1 #define __SP_CURSOR_C__
3 /*
4 * Some convenience stuff
5 *
6 * Authors:
7 * Lauris Kaplinski <lauris@kaplinski.com>
8 *
9 * Copyright (C) 1999-2002 authors
10 * Copyright (C) 2001-2002 Ximian, Inc.
11 *
12 * Released under GNU GPL, read the file 'COPYING' for more information
13 */
15 #include <string.h>
16 #include <ctype.h>
17 #include "sp-cursor.h"
19 void sp_cursor_bitmap_and_mask_from_xpm (GdkBitmap **bitmap, GdkBitmap **mask, gchar **xpm)
20 {
21 int height;
22 int width;
23 int colors;
24 int pix;
25 sscanf(xpm[0], "%d %d %d %d", &height, &width, &colors, &pix);
27 g_return_if_fail (height == 32);
28 g_return_if_fail (width == 32);
29 g_return_if_fail (colors >= 3);
31 int transparent_color = ' ';
32 int black_color = '.';
34 char pixmap_buffer[(32 * 32)/8];
35 char mask_buffer[(32 * 32)/8];
37 for (int i = 0; i < colors; i++) {
39 char const *p = xpm[1 + i];
40 char const ccode = *p;
42 p++;
43 while (isspace(*p)) {
44 p++;
45 }
46 p++;
47 while (isspace(*p)) {
48 p++;
49 }
51 if (strcmp(p, "None") == 0) {
52 transparent_color = ccode;
53 }
55 if (strcmp(p, "#000000") == 0) {
56 black_color = ccode;
57 }
58 }
60 for (int y = 0; y < 32; y++) {
61 for (int x = 0; x < 32; ) {
63 char value = 0;
64 char maskv = 0;
66 for (int pix = 0; pix < 8; pix++, x++){
67 if (xpm [4+y][x] != transparent_color) {
68 maskv |= 1 << pix;
70 if (xpm [4+y][x] == black_color) {
71 value |= 1 << pix;
72 }
73 }
74 }
76 pixmap_buffer[(y * 4 + x/8)-1] = value;
77 mask_buffer[(y * 4 + x/8)-1] = maskv;
78 }
79 }
81 *bitmap = gdk_bitmap_create_from_data(NULL, pixmap_buffer, 32, 32);
82 *mask = gdk_bitmap_create_from_data(NULL, mask_buffer, 32, 32);
83 }
85 GdkCursor *sp_cursor_new_from_xpm (gchar **xpm, gint hot_x, gint hot_y)
86 {
87 GdkDisplay *display=gdk_display_get_default();
88 if (
89 gdk_display_supports_cursor_alpha(display) &
90 gdk_display_supports_cursor_color(display)
91 )
92 {
93 GdkPixbuf *pixbuf=NULL;
94 GdkCursor *new_cursor=NULL;
95 pixbuf=gdk_pixbuf_new_from_xpm_data((const char**)xpm);
96 if (pixbuf != NULL){
97 new_cursor = gdk_cursor_new_from_pixbuf(display,pixbuf,hot_x,hot_y);
98 }
99 return new_cursor;
100 }
101 else
102 {
103 GdkColor const fg = { 0, 0, 0, 0 };
104 GdkColor const bg = { 0, 65535, 65535, 65535 };
106 GdkBitmap *bitmap = NULL;
107 GdkBitmap *mask = NULL;
109 sp_cursor_bitmap_and_mask_from_xpm (&bitmap, &mask, xpm);
110 if ( bitmap != NULL && mask != NULL ) {
111 GdkCursor *new_cursor = gdk_cursor_new_from_pixmap (bitmap, mask,
112 &fg, &bg,
113 hot_x, hot_y);
114 g_object_unref (bitmap);
115 g_object_unref (mask);
116 return new_cursor;
117 }
118 }
119 return NULL;
120 }
122 /*
123 Local Variables:
124 mode:c++
125 c-file-style:"stroustrup"
126 c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
127 indent-tabs-mode:nil
128 fill-column:99
129 End:
130 */
131 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :