Permalink
Browse files

Add cursor support

  • Loading branch information...
1 parent b7fbeab commit aaacdb7c82f090c0bd25c70db8f5dc8b3ced31c7 Jean-Louis Dupond committed May 29, 2012
Showing with 57 additions and 2 deletions.
  1. +13 −0 remmina-plugins/rdp/rdp_event.c
  2. +38 −1 remmina-plugins/rdp/rdp_graphics.c
  3. +6 −1 remmina-plugins/rdp/rdp_plugin.h
@@ -663,6 +663,15 @@ static void remmina_rdp_event_connected(RemminaProtocolWidget* gp, RemminaPlugin
remmina_rdp_event_update_scale(gp);
}
+static void remmina_rdp_event_update_cursor(RemminaProtocolWidget* gp, RemminaPluginRdpUiObject* ui)
+{
+ rfContext* rfi;
+
+ rfi = GET_DATA(gp);
+
+ gdk_window_set_cursor(gtk_widget_get_window(rfi->drawing_area), ui->cursor.cursor);
+}
+
gboolean remmina_rdp_event_queue_ui(RemminaProtocolWidget* gp)
{
rfContext* rfi;
@@ -684,6 +693,10 @@ gboolean remmina_rdp_event_queue_ui(RemminaProtocolWidget* gp)
remmina_rdp_event_connected(gp, ui);
break;
+ case REMMINA_RDP_UI_UPDATE_CURSOR:
+ remmina_rdp_event_update_cursor(gp, ui);
+ break;
+
default:
break;
}
@@ -167,25 +167,62 @@ void rf_Bitmap_SetSurface(rdpContext* context, rdpBitmap* bitmap, boolean primar
void rf_Pointer_New(rdpContext* context, rdpPointer* pointer)
{
+ rfContext* rfi = (rfContext*) context;
+ GdkPixbuf *pixbuf;
+ guchar* pixbuf_data;
+ pixbuf_data = g_malloc(pointer->width * pointer->height * 4);
+ if ((pointer->andMaskData != 0) && (pointer->xorMaskData != 0))
+ {
+ freerdp_alpha_cursor_convert(pixbuf_data, pointer->xorMaskData, pointer->andMaskData, pointer->width, pointer->height, pointer->xorBpp, rfi->clrconv);
+ }
+ pixbuf = gdk_pixbuf_new_from_data(pixbuf_data, GDK_COLORSPACE_RGB, TRUE, 8, pointer->width, pointer->height, (pointer->width * 4), (GdkPixbufDestroyNotify) g_free, NULL);
+ ((rfPointer*) pointer)->cursor = gdk_cursor_new_from_pixbuf(rfi->display, pixbuf, pointer->xPos, pointer->yPos);
}
void rf_Pointer_Free(rdpContext* context, rdpPointer* pointer)
{
-
+ if (((rfPointer*) pointer)->cursor != 0)
+ g_object_unref(((rfPointer*) pointer)->cursor);
}
void rf_Pointer_Set(rdpContext* context, rdpPointer* pointer)
{
+ rfContext* rfi = (rfContext*) context;
+ RemminaPluginRdpUiObject* ui;
+
+ ui = g_new0(RemminaPluginRdpUiObject, 1);
+ ui->type = REMMINA_RDP_UI_UPDATE_CURSOR;
+ ui->cursor.cursor = ((rfPointer*) pointer)->cursor;
+ rf_queue_ui(rfi->protocol_widget, ui);
}
void rf_Pointer_SetNull(rdpContext* context)
{
+ rfContext* rfi = (rfContext*) context;
+ GdkCursor* nullcursor = NULL;
+ RemminaPluginRdpUiObject* ui;
+
+ nullcursor = gdk_cursor_new(GDK_BLANK_CURSOR);
+
+ ui = g_new0(RemminaPluginRdpUiObject, 1);
+ ui->type = REMMINA_RDP_UI_UPDATE_CURSOR;
+ ui->cursor.cursor = nullcursor;
+
+ rf_queue_ui(rfi->protocol_widget, ui);
}
void rf_Pointer_SetDefault(rdpContext* context)
{
+ rfContext* rfi = (rfContext*) context;
+ RemminaPluginRdpUiObject* ui;
+
+ ui = g_new0(RemminaPluginRdpUiObject, 1);
+ ui->type = REMMINA_RDP_UI_UPDATE_CURSOR;
+ ui->cursor.cursor = NULL;
+
+ rf_queue_ui(rfi->protocol_widget, ui);
}
/* Glyph Class */
@@ -48,7 +48,7 @@ extern RemminaPluginService* remmina_plugin_service;
struct rf_pointer
{
rdpPointer pointer;
- Cursor cursor;
+ GdkCursor* cursor;
};
typedef struct rf_pointer rfPointer;
@@ -160,6 +160,7 @@ typedef enum
{
REMMINA_RDP_UI_UPDATE_REGION = 0,
REMMINA_RDP_UI_CONNECTED,
+ REMMINA_RDP_UI_UPDATE_CURSOR,
REMMINA_RDP_UI_RFX,
REMMINA_RDP_UI_NOCODEC
} RemminaPluginRdpUiType;
@@ -178,6 +179,10 @@ struct remmina_plugin_rdp_ui_object
} region;
struct
{
+ GdkCursor* cursor;
+ } cursor;
+ struct
+ {
gint left;
gint top;
RFX_MESSAGE* message;

2 comments on commit aaacdb7

For me, this commit causes remmina to immediately crash after connecting with the following message:

(remmina:6874): Gdk-WARNING **: The program 'remmina' received an X Window System error.
This probably reflects a bug in the program.
The error was 'BadCursor (invalid Cursor parameter)'.
(Details: serial 4564 error_code 6 request_code 141 minor_code 42)
(Note to programmers: normally, X errors are reported asynchronously;
that is, you will receive the error a while after causing it.
To debug your program, run it with the --sync command line
option to change this behavior. You can then get a meaningful
backtrace from your debugger if you break on the gdk_x_error() function.)

The stack trace is:
#0 0xb7fff424 in __kernel_vsyscall ()
#1 0x4519698f in raise () from /lib/libc.so.6
#2 0x451982d5 in abort () from /lib/libc.so.6
#3 0x4518f6a5 in __assert_fail_base () from /lib/libc.so.6
#4 0x4518f757 in __assert_fail () from /lib/libc.so.6
#5 0x455f68e1 in _XAllocID () from /usr/lib/libX11.so.6
#6 0x455d3368 in XCreatePixmap () from /usr/lib/libX11.so.6
#7 0x45ad1690 in XcursorImageLoadCursor () from /usr/lib/libXcursor.so.1
#8 0x46591f01 in ?? () from /usr/lib/libgdk-3.so.0
#9 0x46572cc5 in gdk_cursor_new_from_pixbuf () from /usr/lib/libgdk-3.so.0
#10 0xb7d652c2 in rf_Pointer_New () from /home/palm/opt/Remmina/lib/remmina/plugins/remmina-plugin-rdp.so
#11 0xb7d502ab in update_pointer_new () from /home/palm/opt/FreeRDP/lib/libfreerdp-cache.so.1.0
#12 0xb73cbefa in fastpath_recv_updates () from /home/palm/opt/FreeRDP/lib/libfreerdp-core.so.1.0
#13 0xb73ca1e9 in rdp_recv_pdu () from /home/palm/opt/FreeRDP/lib/libfreerdp-core.so.1.0
#14 0xb73ca4bf in rdp_recv_callback () from /home/palm/opt/FreeRDP/lib/libfreerdp-core.so.1.0
#15 0xb73cdc0c in transport_check_fds () from /home/palm/opt/FreeRDP/lib/libfreerdp-core.so.1.0
#16 0xb73ca6be in rdp_check_fds () from /home/palm/opt/FreeRDP/lib/libfreerdp-core.so.1.0
#17 0xb73c2903 in freerdp_check_fds () from /home/palm/opt/FreeRDP/lib/libfreerdp-core.so.1.0
#18 0xb7d5fbfa in remmina_rdp_main () from /home/palm/opt/Remmina/lib/remmina/plugins/remmina-plugin-rdp.so
#19 0xb7d5fee6 in remmina_rdp_main_thread () from /home/palm/opt/Remmina/lib/remmina/plugins/remmina-plugin-rdp.so
#20 0x4531dcd3 in start_thread () from /lib/libpthread.so.0
#21 0x4525aa2e in clone () from /lib/libc.so.6

The Gdk docs (http://developer.gnome.org/gdk/stable/gdk-Cursors.html#gdk-cursor-new-from-pixmap) says:
"Both the pixmap and mask must have a depth of 1 (i.e. each pixel has only 2 values - on or off)."

Obviously that isn't the case here, so I'm not sure what's going on here. Maybe a Gdk/Gtk version incompatibility?
Let me know if I can provide more info!

You should probably file a bug instead of commenting here.

Please sign in to comment.