Index: src_plugins/lib_gtk_common/bu_icons.c =================================================================== --- src_plugins/lib_gtk_common/bu_icons.c (revision 8018) +++ src_plugins/lib_gtk_common/bu_icons.c (revision 8019) @@ -4,6 +4,7 @@ * PCB, interactive printed circuit board design * Copyright (C) 1994,1995,1996 Thomas Nau * pcb-rnd Copyright (C) 2017 Tibor 'Igor2' Palinkas + * pcb-rnd Copyright (C) 2017 Alain Vigne * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -32,10 +33,65 @@ /* It's enough to load these once, globally - shared data among all callers */ static int inited = 0; -GdkPixmap *XC_clock_source, *XC_clock_mask, *XC_hand_source, *XC_hand_mask, *XC_lock_source, *XC_lock_mask; +GdkPixbuf *XC_clock_source, *XC_hand_source, *XC_lock_source; -void pcb_gtk_icons_init(GdkWindow *top_window) +/** Returns an RGBA 24x24 GdkPixbuf from \p data, using \p mask. + + \param width should be smaller than 24 + \param height should be smaller than 24 + + \returns A newly-created GdkPixbuf with a reference count of 1. Use g_object_unref() to free the structure. + */ +static GdkPixbuf *pcb_gtk_cursor_from_xbm_data(unsigned char *data, unsigned char *mask, + unsigned int width, unsigned int height) { + GdkPixbuf *dest; + unsigned char *src_data, *mask_data, *dest_data; + int dest_stride; + unsigned char reg, reg_m; + unsigned char data_b, mask_b; + int bits; + int x, y; + + g_return_val_if_fail((width < 25 && height < 25), NULL); + + /* Creates a new suitable GdkPixbuf structure for cursor. */ + dest = gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE, 8, 24, 24); + dest_data = gdk_pixbuf_get_pixels(dest); + dest_stride = gdk_pixbuf_get_rowstride(dest); + + src_data = data; + mask_data = mask; + + /* Copy data + mask into GdkPixbuf RGBA pixels. */ + for (y = 0; y < height; y++) { + bits = 0; + for (x = 0; x < width; x++) { + if (bits == 0) { + reg = *src_data++; + reg_m = *mask_data++; + bits = 8; + } + data_b = (reg & 0x01) ? 255 : 0; + reg >>= 1; + mask_b = (reg_m & 0x01) ? 255 : 0; + reg_m >>= 1; + bits--; + + dest_data[x * 4 + 0] = data_b; + dest_data[x * 4 + 1] = data_b; + dest_data[x * 4 + 2] = data_b; + dest_data[x * 4 + 3] = mask_b; + } + + dest_data += dest_stride; + } + + return dest; +} + +void pcb_gtk_icons_init(GdkWindow * top_window) +{ GdkPixbuf *icon; if (inited) @@ -44,15 +100,11 @@ icon = gdk_pixbuf_new_from_xpm_data((const gchar **) icon_bits); gtk_window_set_default_icon(icon); - XC_clock_source = gdk_bitmap_create_from_data(top_window, (char *) rotateIcon_bits, rotateIcon_width, rotateIcon_height); - XC_clock_mask = gdk_bitmap_create_from_data(top_window, (char *) rotateMask_bits, rotateMask_width, rotateMask_height); + XC_clock_source = pcb_gtk_cursor_from_xbm_data(rotateIcon_bits, rotateMask_bits, rotateIcon_width, rotateIcon_height); - XC_hand_source = gdk_bitmap_create_from_data(top_window, (char *) handIcon_bits, handIcon_width, handIcon_height); - XC_hand_mask = gdk_bitmap_create_from_data(top_window, (char *) handMask_bits, handMask_width, handMask_height); + XC_hand_source = pcb_gtk_cursor_from_xbm_data(handIcon_bits, handMask_bits, handIcon_width, handIcon_height); - XC_lock_source = gdk_bitmap_create_from_data(top_window, (char *) lockIcon_bits, lockIcon_width, lockIcon_height); - XC_lock_mask = gdk_bitmap_create_from_data(top_window, (char *) lockMask_bits, lockMask_width, lockMask_height); + XC_lock_source = pcb_gtk_cursor_from_xbm_data(lockIcon_bits, lockMask_bits, lockIcon_width, lockIcon_height); inited = 1; } - Index: src_plugins/lib_gtk_common/bu_icons.h =================================================================== --- src_plugins/lib_gtk_common/bu_icons.h (revision 8018) +++ src_plugins/lib_gtk_common/bu_icons.h (revision 8019) @@ -1,8 +1,6 @@ #include -/* initializes icon pixmap (cursor bits, pcb-rnd logo) */ +/** Initializes icon pixbufs (cursor bits, pcb-rnd logo). */ void pcb_gtk_icons_init(GdkWindow *top_window); -extern GdkPixmap *XC_hand_source, *XC_hand_mask; -extern GdkPixmap *XC_lock_source, *XC_lock_mask; -extern GdkPixmap *XC_clock_source, *XC_clock_mask; +extern GdkPixbuf *XC_clock_source, *XC_hand_source, *XC_lock_source; Index: src_plugins/lib_gtk_common/in_mouse.c =================================================================== --- src_plugins/lib_gtk_common/in_mouse.c (revision 8018) +++ src_plugins/lib_gtk_common/in_mouse.c (revision 8019) @@ -65,8 +65,6 @@ static GdkCursorType gport_set_cursor(pcb_gtk_mouse_t *ctx, GdkCursorType shape) { GdkWindow *window; - GdkColor fg = { 0, 65535, 65535, 65535 }; /* white */ - GdkColor bg = { 0, 0, 0, 0 }; /* black */ GdkCursorType old_shape = ctx->X_cursor_shape; if (ctx->drawing_area == NULL) @@ -84,11 +82,11 @@ ctx->X_cursor_shape = shape; if (shape > GDK_LAST_CURSOR) { if (shape == CUSTOM_CURSOR_CLOCKWISE) - ctx->X_cursor = gdk_cursor_new_from_pixmap(XC_clock_source, XC_clock_mask, &fg, &bg, ICON_X_HOT, ICON_Y_HOT); + ctx->X_cursor = gdk_cursor_new_from_pixbuf(gtk_widget_get_display(ctx->drawing_area), XC_clock_source, ICON_X_HOT, ICON_Y_HOT); else if (shape == CUSTOM_CURSOR_DRAG) - ctx->X_cursor = gdk_cursor_new_from_pixmap(XC_hand_source, XC_hand_mask, &fg, &bg, ICON_X_HOT, ICON_Y_HOT); + ctx->X_cursor = gdk_cursor_new_from_pixbuf(gtk_widget_get_display(ctx->drawing_area), XC_hand_source, ICON_X_HOT, ICON_Y_HOT); else if (shape == CUSTOM_CURSOR_LOCK) - ctx->X_cursor = gdk_cursor_new_from_pixmap(XC_lock_source, XC_lock_mask, &fg, &bg, ICON_X_HOT, ICON_Y_HOT); + ctx->X_cursor = gdk_cursor_new_from_pixbuf(gtk_widget_get_display(ctx->drawing_area), XC_lock_source, ICON_X_HOT, ICON_Y_HOT); } else ctx->X_cursor = gdk_cursor_new(shape);