diff options
Diffstat (limited to 'widgets/misc/e-cursors.c')
-rw-r--r-- | widgets/misc/e-cursors.c | 174 |
1 files changed, 134 insertions, 40 deletions
diff --git a/widgets/misc/e-cursors.c b/widgets/misc/e-cursors.c index 79447247c8..c10e0e6490 100644 --- a/widgets/misc/e-cursors.c +++ b/widgets/misc/e-cursors.c @@ -1,40 +1,134 @@ -#ifndef GNUMERIC_CURSORS_H -#define GNUMERIC_CURSORS_H - -#include <gdk/gdk.h> - -typedef enum { - GNUMERIC_CURSOR_FAT_CROSS, - GNUMERIC_CURSOR_THIN_CROSS, - GNUMERIC_CURSOR_ARROW, - GNUMERIC_CURSOR_MOVE, - GNUMERIC_CURSOR_ZOOM_IN, - GNUMERIC_CURSOR_ZOOM_OUT, - GNUMERIC_CURSOR_SIZE_X, - GNUMERIC_CURSOR_SIZE_Y, - GNUMERIC_CURSOR_SIZE_TL, - GNUMERIC_CURSOR_SIZE_TR, - GNUMERIC_CURSOR_PRESS, - GNUMERIC_CURSOR_HAND_OPEN, - GNUMERIC_CURSOR_HAND_CLOSED, - GNUMERIC_CURSOR_NUM_CURSORS -} CursorType; - -void cursors_init (void); -void cursors_shutdown (void); - -#define cursor_set(win, c) \ -G_STMT_START { \ - if (win) \ - gdk_window_set_cursor (win, cursor_get (c)); \ -} G_STMT_END - -#define cursor_set_widget(w, c) \ -G_STMT_START { \ - if (GTK_WIDGET (w)->window) \ - gdk_window_set_cursor (GTK_WIDGET (w)->window, cursor_get (c)); \ -} G_STMT_END - -GdkCursor *cursor_get (CursorType type); - -#endif /* GNUMERIC_CURSORS_H */ +/* + * cursors.c: cursor handling for Gnumeric + * + * Authors: + * Miguel de Icaza (miguel@gnu.org) + */ +#include <config.h> +#include <gnome.h> +#include "e-colors.h" +#include "e-cursors.h" +#include "pixmaps/cursor_cross.xpm" +#include "pixmaps/cursor_zoom_in.xpm" +#include "pixmaps/cursor_zoom_out.xpm" +#include "pixmaps/cursor_hand_open.xpm" +#include "pixmaps/cursor_hand_closed.xpm" + +#define GDK_INTERNAL_CURSOR -1 + +typedef struct { + GdkCursor *cursor; + int hot_x, hot_y; + char **xpm; +} CursorDef; + +static CursorDef cursors [] = { + { NULL, 17, 17, cursor_cross_xpm }, + { NULL, GDK_INTERNAL_CURSOR, GDK_CROSSHAIR, NULL }, + { NULL, GDK_INTERNAL_CURSOR, GDK_ARROW, NULL }, + { NULL, GDK_INTERNAL_CURSOR, GDK_FLEUR, NULL }, + { NULL, 24, 24, cursor_zoom_in_xpm }, + { NULL, 24, 24, cursor_zoom_out_xpm }, + { NULL, GDK_INTERNAL_CURSOR, GDK_SB_H_DOUBLE_ARROW, NULL }, + { NULL, GDK_INTERNAL_CURSOR, GDK_SB_V_DOUBLE_ARROW, NULL }, + { NULL, GDK_INTERNAL_CURSOR, GDK_SIZING, NULL }, + { NULL, GDK_INTERNAL_CURSOR, GDK_SIZING, NULL }, + { NULL, GDK_INTERNAL_CURSOR, GDK_HAND2, NULL }, + { NULL, 10, 10, cursor_hand_open_xpm }, + { NULL, 10, 10, cursor_hand_closed_xpm }, + { NULL, 0, 0, NULL } +}; + + +static void +create_bitmap_and_mask_from_xpm (GdkBitmap **bitmap, GdkBitmap **mask, gchar **xpm) +{ + int height, width, colors; + char pixmap_buffer [(32 * 32)/8]; + char mask_buffer [(32 * 32)/8]; + int x, y, pix, yofs; + int transparent_color, black_color; + + sscanf (xpm [0], "%d %d %d %d", &height, &width, &colors, &pix); + + g_assert (height == 32); + g_assert (width == 32); + g_assert (colors <= 3); + + transparent_color = ' '; + black_color = '.'; + + yofs = colors + 1; + for (y = 0; y < 32; y++){ + for (x = 0; x < 32;){ + char value = 0, maskv = 0; + + for (pix = 0; pix < 8; pix++, x++){ + if (xpm [y + yofs][x] != transparent_color){ + maskv |= 1 << pix; + + /* + * Invert the colours here because it seems + * to workaround a bug the Matrox G100 Xserver? + * We reverse the foreground & background in the next + * routine to compensate. + */ + if (xpm [y + yofs][x] == black_color){ + value |= 1 << pix; + } + } + } + pixmap_buffer [(y * 4 + x/8)-1] = value; + mask_buffer [(y * 4 + x/8)-1] = maskv; + } + } + *bitmap = gdk_bitmap_create_from_data (NULL, pixmap_buffer, 32, 32); + *mask = gdk_bitmap_create_from_data (NULL, mask_buffer, 32, 32); +} + +void +e_cursors_init (void) +{ + int i; + + for (i = 0; cursors [i].hot_x; i++){ + GdkBitmap *bitmap, *mask; + + if (cursors [i].hot_x < 0) + cursors [i].cursor = gdk_cursor_new (cursors [i].hot_y); + else { + create_bitmap_and_mask_from_xpm (&bitmap, &mask, cursors [i].xpm); + + /* The foreground and background colours are reversed. + * See comment above for explanation. + */ + cursors [i].cursor = + gdk_cursor_new_from_pixmap ( + bitmap, mask, + &e_black, &e_white, + cursors [i].hot_x, + cursors [i].hot_y); + } + } + + g_assert (i == E_CURSOR_NUM_CURSORS); +} + +void +e_cursors_shutdown (void) +{ + int i; + + for (i = 0; cursors [i].hot_x; i++) + gdk_cursor_destroy (cursors [i].cursor); +} + + +/* Returns a cursor given its type */ +GdkCursor * +e_cursor_get (ECursorType type) +{ + g_return_val_if_fail (type >= 0 && type < E_CURSOR_NUM_CURSORS, NULL); + + return cursors [type].cursor; +} |