1 /* Dia -- an diagram creation/manipulation program
2  * Copyright (C) 1998 Alexander Larsson
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17  */
18 
19 #include <config.h>
20 
21 #include <gdk/gdk.h>
22 
23 #define DIA_CURSOR GDK_LAST_CURSOR
24 
25 #include "display.h"
26 #include "cursor.h"
27 
28 #include "pixmaps/hand-open-data.xbm"
29 #include "pixmaps/hand-open-mask.xbm"
30 #include "pixmaps/hand-closed-data.xbm"
31 #include "pixmaps/hand-closed-mask.xbm"
32 #include "pixmaps/magnify-plus-data.xbm"
33 #include "pixmaps/magnify-plus-mask.xbm"
34 #include "pixmaps/magnify-minus-data.xbm"
35 #include "pixmaps/magnify-minus-mask.xbm"
36 
37 static struct {
38   /* Can't use a union because it can't be statically initialized
39      (except for the first element) */
40   int gdk_cursor_number;
41   gchar *data;
42   int width;
43   int height;
44   gchar *mask;
45   int hot_x;
46   int hot_y;
47   GdkCursor *cursor;
48 } cursors[MAX_CURSORS] = {
49   { GDK_LEFT_PTR },
50   { GDK_FLEUR },
51   { DIA_CURSOR,
52     hand_open_data_bits,
53     hand_open_data_width, hand_open_data_height,
54     hand_open_mask_bits,
55     hand_open_data_width/2, hand_open_data_height/2},
56   { DIA_CURSOR,
57     hand_closed_data_bits,
58     hand_closed_data_width, hand_closed_data_height,
59     hand_closed_mask_bits,
60     hand_closed_data_width/2, hand_closed_data_height/2},
61   { DIA_CURSOR,
62     magnify_minus_data_bits,
63     magnify_minus_data_width, magnify_minus_data_height,
64     magnify_minus_mask_bits,
65     magnify_minus_data_x_hot, magnify_minus_data_y_hot},
66   { DIA_CURSOR,
67     magnify_plus_data_bits,
68     magnify_plus_data_width, magnify_plus_data_height,
69     magnify_plus_mask_bits,
70     magnify_plus_data_x_hot, magnify_plus_data_y_hot},
71   { GDK_CROSS_REVERSE },
72   { GDK_XTERM },
73 };
74 
75 GdkCursor *
get_cursor(DiaCursorType ctype)76 get_cursor(DiaCursorType ctype) {
77   if (ctype >= MAX_CURSORS || ctype < 0) {
78     return NULL;
79   }
80   if (cursors[ctype].cursor == NULL) {
81     GdkCursor *new_cursor = NULL;
82 
83     if (cursors[ctype].gdk_cursor_number != DIA_CURSOR) {
84       new_cursor = gdk_cursor_new(cursors[ctype].gdk_cursor_number);
85     } else {
86       DDisplay *active_display = ddisplay_active ();
87       if (active_display != NULL)
88 	new_cursor = create_cursor(active_display->canvas->window,
89 				   cursors[ctype].data,
90 				   cursors[ctype].width,
91 				   cursors[ctype].height,
92 				   cursors[ctype].mask,
93 				   cursors[ctype].hot_x,
94 				   cursors[ctype].hot_y);
95     }
96     cursors[ctype].cursor = new_cursor;
97   }
98 
99   return cursors[ctype].cursor;
100 }
101 
102 GdkCursor *
create_cursor(GdkWindow * window,const gchar * data,int width,int height,const gchar * mask,int hot_x,int hot_y)103 create_cursor(GdkWindow *window,
104 	      const gchar *data, int width, int height,
105 	      const gchar *mask, int hot_x, int hot_y)
106 {
107   GdkBitmap *dbit, *mbit;
108   GdkColor black, white;
109   GdkCursor *cursor;
110 
111   g_return_val_if_fail(window != NULL, NULL);
112 
113   dbit = gdk_bitmap_create_from_data(window, data, width, height);
114   mbit = gdk_bitmap_create_from_data(window, mask, width, height);
115   g_assert(dbit != NULL && mbit != NULL);
116 
117   /* For some odd reason, black and white is inverted */
118   gdk_color_black(gdk_window_get_colormap(window), &white);
119   gdk_color_white(gdk_window_get_colormap(window), &black);
120 
121   cursor = gdk_cursor_new_from_pixmap(dbit, mbit, &white, &black, hot_x,hot_y);
122   g_assert(cursor != NULL);
123 
124   gdk_bitmap_unref(dbit);
125   gdk_bitmap_unref(mbit);
126 
127   return cursor;
128 }
129