1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * The Original Code is Copyright (C) 2005-2007 Blender Foundation
17  * All rights reserved.
18  */
19 
20 /** \file
21  * \ingroup wm
22  *
23  * Cursor pixmap and cursor utility functions to change the cursor.
24  */
25 
26 #include <stdio.h>
27 #include <string.h>
28 
29 #include "GHOST_C-api.h"
30 
31 #include "BLI_utildefines.h"
32 
33 #include "BLI_sys_types.h"
34 
35 #include "DNA_listBase.h"
36 #include "DNA_userdef_types.h"
37 #include "DNA_workspace_types.h"
38 
39 #include "BKE_context.h"
40 #include "BKE_global.h"
41 #include "BKE_main.h"
42 
43 #include "WM_api.h"
44 #include "WM_types.h"
45 #include "wm_cursors.h"
46 #include "wm_window.h"
47 
48 /* Blender custom cursor. */
49 typedef struct BCursor {
50   char *bitmap;
51   char *mask;
52   char hotx;
53   char hoty;
54   bool can_invert_color;
55 } BCursor;
56 
57 static BCursor *BlenderCursor[WM_CURSOR_NUM] = {0};
58 
59 /* Blender cursor to GHOST standard cursor conversion. */
convert_to_ghost_standard_cursor(WMCursorType curs)60 static GHOST_TStandardCursor convert_to_ghost_standard_cursor(WMCursorType curs)
61 {
62   switch (curs) {
63     case WM_CURSOR_DEFAULT:
64       return GHOST_kStandardCursorDefault;
65     case WM_CURSOR_WAIT:
66       return GHOST_kStandardCursorWait;
67     case WM_CURSOR_EDIT:
68     case WM_CURSOR_CROSS:
69       return GHOST_kStandardCursorCrosshair;
70     case WM_CURSOR_X_MOVE:
71       return GHOST_kStandardCursorLeftRight;
72     case WM_CURSOR_Y_MOVE:
73       return GHOST_kStandardCursorUpDown;
74     case WM_CURSOR_COPY:
75       return GHOST_kStandardCursorCopy;
76     case WM_CURSOR_HAND:
77       return GHOST_kStandardCursorMove;
78     case WM_CURSOR_H_SPLIT:
79       return GHOST_kStandardCursorHorizontalSplit;
80     case WM_CURSOR_V_SPLIT:
81       return GHOST_kStandardCursorVerticalSplit;
82     case WM_CURSOR_STOP:
83       return GHOST_kStandardCursorStop;
84     case WM_CURSOR_KNIFE:
85       return GHOST_kStandardCursorKnife;
86     case WM_CURSOR_NSEW_SCROLL:
87       return GHOST_kStandardCursorNSEWScroll;
88     case WM_CURSOR_NS_SCROLL:
89       return GHOST_kStandardCursorNSScroll;
90     case WM_CURSOR_EW_SCROLL:
91       return GHOST_kStandardCursorEWScroll;
92     case WM_CURSOR_EYEDROPPER:
93       return GHOST_kStandardCursorEyedropper;
94     case WM_CURSOR_N_ARROW:
95       return GHOST_kStandardCursorUpArrow;
96     case WM_CURSOR_S_ARROW:
97       return GHOST_kStandardCursorDownArrow;
98     case WM_CURSOR_PAINT:
99       return GHOST_kStandardCursorCrosshairA;
100     case WM_CURSOR_DOT:
101       return GHOST_kStandardCursorCrosshairB;
102     case WM_CURSOR_CROSSC:
103       return GHOST_kStandardCursorCrosshairC;
104     case WM_CURSOR_ERASER:
105       return GHOST_kStandardCursorEraser;
106     case WM_CURSOR_ZOOM_IN:
107       return GHOST_kStandardCursorZoomIn;
108     case WM_CURSOR_ZOOM_OUT:
109       return GHOST_kStandardCursorZoomOut;
110     case WM_CURSOR_TEXT_EDIT:
111       return GHOST_kStandardCursorText;
112     case WM_CURSOR_PAINT_BRUSH:
113       return GHOST_kStandardCursorPencil;
114     case WM_CURSOR_E_ARROW:
115       return GHOST_kStandardCursorRightArrow;
116     case WM_CURSOR_W_ARROW:
117       return GHOST_kStandardCursorLeftArrow;
118     default:
119       return GHOST_kStandardCursorCustom;
120   }
121 }
122 
window_set_custom_cursor(wmWindow * win,const uchar mask[16][2],const uchar bitmap[16][2],int hotx,int hoty)123 static void window_set_custom_cursor(
124     wmWindow *win, const uchar mask[16][2], const uchar bitmap[16][2], int hotx, int hoty)
125 {
126   GHOST_SetCustomCursorShape(
127       win->ghostwin, (GHOST_TUns8 *)bitmap, (GHOST_TUns8 *)mask, 16, 16, hotx, hoty, true);
128 }
129 
window_set_custom_cursor_ex(wmWindow * win,BCursor * cursor)130 static void window_set_custom_cursor_ex(wmWindow *win, BCursor *cursor)
131 {
132   GHOST_SetCustomCursorShape(win->ghostwin,
133                              (GHOST_TUns8 *)cursor->bitmap,
134                              (GHOST_TUns8 *)cursor->mask,
135                              16,
136                              16,
137                              cursor->hotx,
138                              cursor->hoty,
139                              cursor->can_invert_color);
140 }
141 
WM_cursor_set(wmWindow * win,int curs)142 void WM_cursor_set(wmWindow *win, int curs)
143 {
144   if (win == NULL || G.background) {
145     return; /* Can't set custom cursor before Window init */
146   }
147 
148   if (curs == WM_CURSOR_DEFAULT && win->modalcursor) {
149     curs = win->modalcursor;
150   }
151 
152   if (curs == WM_CURSOR_NONE) {
153     GHOST_SetCursorVisibility(win->ghostwin, 0);
154     return;
155   }
156 
157   GHOST_SetCursorVisibility(win->ghostwin, 1);
158 
159   if (win->cursor == curs) {
160     return; /* Cursor is already set */
161   }
162 
163   win->cursor = curs;
164 
165   if (curs < 0 || curs >= WM_CURSOR_NUM) {
166     BLI_assert(!"Invalid cursor number");
167     return;
168   }
169 
170   GHOST_TStandardCursor ghost_cursor = convert_to_ghost_standard_cursor(curs);
171 
172   if (ghost_cursor != GHOST_kStandardCursorCustom &&
173       GHOST_HasCursorShape(win->ghostwin, ghost_cursor)) {
174     /* Use native GHOST cursor when available. */
175     GHOST_SetCursorShape(win->ghostwin, ghost_cursor);
176   }
177   else {
178     BCursor *bcursor = BlenderCursor[curs];
179     if (bcursor) {
180       /* Use custom bitmap cursor. */
181       window_set_custom_cursor_ex(win, bcursor);
182     }
183     else {
184       /* Fallback to default cursor if no bitmap found. */
185       GHOST_SetCursorShape(win->ghostwin, GHOST_kStandardCursorDefault);
186     }
187   }
188 }
189 
WM_cursor_set_from_tool(struct wmWindow * win,const ScrArea * area,const ARegion * region)190 bool WM_cursor_set_from_tool(struct wmWindow *win, const ScrArea *area, const ARegion *region)
191 {
192   if (region && (region->regiontype != RGN_TYPE_WINDOW)) {
193     return false;
194   }
195 
196   bToolRef_Runtime *tref_rt = (area && area->runtime.tool) ? area->runtime.tool->runtime : NULL;
197   if (tref_rt && tref_rt->cursor != WM_CURSOR_DEFAULT) {
198     if (win->modalcursor == 0) {
199       WM_cursor_set(win, tref_rt->cursor);
200       win->cursor = tref_rt->cursor;
201       return true;
202     }
203   }
204   return false;
205 }
206 
WM_cursor_modal_set(wmWindow * win,int val)207 void WM_cursor_modal_set(wmWindow *win, int val)
208 {
209   if (win->lastcursor == 0) {
210     win->lastcursor = win->cursor;
211   }
212   win->modalcursor = val;
213   WM_cursor_set(win, val);
214 }
215 
WM_cursor_modal_restore(wmWindow * win)216 void WM_cursor_modal_restore(wmWindow *win)
217 {
218   win->modalcursor = 0;
219   if (win->lastcursor) {
220     WM_cursor_set(win, win->lastcursor);
221   }
222   win->lastcursor = 0;
223 }
224 
225 /* to allow usage all over, we do entire WM */
WM_cursor_wait(bool val)226 void WM_cursor_wait(bool val)
227 {
228   if (!G.background) {
229     wmWindowManager *wm = G_MAIN->wm.first;
230     wmWindow *win = wm ? wm->windows.first : NULL;
231 
232     for (; win; win = win->next) {
233       if (val) {
234         WM_cursor_modal_set(win, WM_CURSOR_WAIT);
235       }
236       else {
237         WM_cursor_modal_restore(win);
238       }
239     }
240   }
241 }
242 
243 /**
244  * \param bounds: can be NULL
245  */
WM_cursor_grab_enable(wmWindow * win,int wrap,bool hide,int bounds[4])246 void WM_cursor_grab_enable(wmWindow *win, int wrap, bool hide, int bounds[4])
247 {
248   /* Only grab cursor when not running debug.
249    * It helps not to get a stuck WM when hitting a breakpoint
250    * */
251   GHOST_TGrabCursorMode mode = GHOST_kGrabNormal;
252   GHOST_TAxisFlag mode_axis = GHOST_kAxisX | GHOST_kGrabAxisY;
253 
254   if (bounds) {
255     wm_cursor_position_to_ghost(win, &bounds[0], &bounds[1]);
256     wm_cursor_position_to_ghost(win, &bounds[2], &bounds[3]);
257   }
258 
259   if (hide) {
260     mode = GHOST_kGrabHide;
261   }
262   else if (wrap) {
263     mode = GHOST_kGrabWrap;
264 
265     if (wrap == WM_CURSOR_WRAP_X) {
266       mode_axis = GHOST_kAxisX;
267     }
268     if (wrap == WM_CURSOR_WRAP_Y) {
269       mode_axis = GHOST_kGrabAxisY;
270     }
271   }
272 
273   if ((G.debug & G_DEBUG) == 0) {
274     if (win->ghostwin) {
275       if (win->eventstate->tablet.is_motion_absolute == false) {
276         GHOST_SetCursorGrab(win->ghostwin, mode, mode_axis, bounds, NULL);
277       }
278 
279       win->grabcursor = mode;
280     }
281   }
282 }
283 
WM_cursor_grab_disable(wmWindow * win,const int mouse_ungrab_xy[2])284 void WM_cursor_grab_disable(wmWindow *win, const int mouse_ungrab_xy[2])
285 {
286   if ((G.debug & G_DEBUG) == 0) {
287     if (win && win->ghostwin) {
288       if (mouse_ungrab_xy) {
289         int mouse_xy[2] = {mouse_ungrab_xy[0], mouse_ungrab_xy[1]};
290         wm_cursor_position_to_ghost(win, &mouse_xy[0], &mouse_xy[1]);
291         GHOST_SetCursorGrab(
292             win->ghostwin, GHOST_kGrabDisable, GHOST_kGrabAxisNone, NULL, mouse_xy);
293       }
294       else {
295         GHOST_SetCursorGrab(win->ghostwin, GHOST_kGrabDisable, GHOST_kGrabAxisNone, NULL, NULL);
296       }
297 
298       win->grabcursor = GHOST_kGrabDisable;
299     }
300   }
301 }
302 
wm_cursor_warp_relative(wmWindow * win,int x,int y)303 static void wm_cursor_warp_relative(wmWindow *win, int x, int y)
304 {
305   /* note: don't use wmEvent coords because of continuous grab T36409. */
306   int cx, cy;
307   wm_get_cursor_position(win, &cx, &cy);
308   WM_cursor_warp(win, cx + x, cy + y);
309 }
310 
311 /* give it a modal keymap one day? */
wm_cursor_arrow_move(wmWindow * win,const wmEvent * event)312 bool wm_cursor_arrow_move(wmWindow *win, const wmEvent *event)
313 {
314   if (win && event->val == KM_PRESS) {
315     /* Must move at least this much to avoid rounding in WM_cursor_warp. */
316     float fac = GHOST_GetNativePixelSize(win->ghostwin);
317 
318     if (event->type == EVT_UPARROWKEY) {
319       wm_cursor_warp_relative(win, 0, fac);
320       return 1;
321     }
322     if (event->type == EVT_DOWNARROWKEY) {
323       wm_cursor_warp_relative(win, 0, -fac);
324       return 1;
325     }
326     if (event->type == EVT_LEFTARROWKEY) {
327       wm_cursor_warp_relative(win, -fac, 0);
328       return 1;
329     }
330     if (event->type == EVT_RIGHTARROWKEY) {
331       wm_cursor_warp_relative(win, fac, 0);
332       return 1;
333     }
334   }
335   return 0;
336 }
337 
338 /* after this you can call restore too */
WM_cursor_time(wmWindow * win,int nr)339 void WM_cursor_time(wmWindow *win, int nr)
340 {
341   /* 10 8x8 digits */
342   const char number_bitmaps[10][8] = {
343       {0, 56, 68, 68, 68, 68, 68, 56},
344       {0, 24, 16, 16, 16, 16, 16, 56},
345       {0, 60, 66, 32, 16, 8, 4, 126},
346       {0, 124, 32, 16, 56, 64, 66, 60},
347       {0, 32, 48, 40, 36, 126, 32, 32},
348       {0, 124, 4, 60, 64, 64, 68, 56},
349       {0, 56, 4, 4, 60, 68, 68, 56},
350       {0, 124, 64, 32, 16, 8, 8, 8},
351       {0, 60, 66, 66, 60, 66, 66, 60},
352       {0, 56, 68, 68, 120, 64, 68, 56},
353   };
354   uchar mask[16][2];
355   uchar bitmap[16][2] = {{0}};
356 
357   if (win->lastcursor == 0) {
358     win->lastcursor = win->cursor;
359   }
360 
361   memset(&mask, 0xFF, sizeof(mask));
362 
363   /* print number bottom right justified */
364   for (int idx = 3; nr && idx >= 0; idx--) {
365     const char *digit = number_bitmaps[nr % 10];
366     int x = idx % 2;
367     int y = idx / 2;
368 
369     for (int i = 0; i < 8; i++) {
370       bitmap[i + y * 8][x] = digit[i];
371     }
372     nr /= 10;
373   }
374 
375   window_set_custom_cursor(win, mask, bitmap, 7, 7);
376   /* Unset current cursor value so it's properly reset to wmWindow.lastcursor. */
377   win->cursor = 0;
378 }
379 
380 /**
381  * Custom Cursor Description
382  * =========================
383  *
384  * Each bit represents a pixel, so 1 byte = 8 pixels,
385  * the bytes go Left to Right. Top to bottom
386  * the bits in a byte go right to left
387  * (ie;  0x01, 0x80  represents a line of 16 pix with the first and last pix set.)
388  *
389  * - A 0 in the bitmap = white, a 1 black
390  * - a 0 in the mask   = transparent pix.
391  *
392  * This type of cursor is 16x16 pixels only.
393  *
394  * ----
395  *
396  * There is a nice Python GUI utility that can be used for drawing cursors in
397  * this format in the Blender source distribution, in
398  * `./source/tools/utils/make_cursor_gui.py` .
399  *
400  * Start it with the command `python3 make_cursor_gui.py`
401  * It will copy its output to the console when you press 'Do it'.
402  */
403 
404 /**
405  * Because defining a cursor mixes declarations and executable code
406  * each cursor needs its own scoping block or it would be split up
407  * over several hundred lines of code.  To enforce/document this better
408  * I define 2 pretty brain-dead macros so it's obvious what the extra "[]"
409  * are for */
410 
411 #define BEGIN_CURSOR_BLOCK \
412   { \
413     ((void)0)
414 #define END_CURSOR_BLOCK \
415   } \
416   ((void)0)
417 
wm_init_cursor_data(void)418 void wm_init_cursor_data(void)
419 {
420   /********************** NW_ARROW Cursor **************************/
421   BEGIN_CURSOR_BLOCK;
422   static char nw_bitmap[] = {
423       0x00, 0x00, 0x02, 0x00, 0x06, 0x00, 0x0e, 0x00, 0x1e, 0x00, 0x3e,
424       0x00, 0x7e, 0x00, 0xfe, 0x00, 0xfe, 0x01, 0xfe, 0x03, 0xfe, 0x07,
425       0x7e, 0x00, 0x6e, 0x00, 0xc6, 0x00, 0xc2, 0x00, 0x00, 0x00,
426   };
427 
428   static char nw_mask[] = {
429       0x03, 0x00, 0x07, 0x00, 0x0f, 0x00, 0x1f, 0x00, 0x3f, 0x00, 0x7f,
430       0x00, 0xff, 0x00, 0xff, 0x01, 0xff, 0x03, 0xff, 0x07, 0xff, 0x0f,
431       0xff, 0x0f, 0xff, 0x00, 0xef, 0x01, 0xe7, 0x01, 0xc3, 0x00,
432   };
433 
434   static BCursor NWArrowCursor = {
435       nw_bitmap,
436       nw_mask,
437       0,
438       0,
439       true,
440   };
441 
442   BlenderCursor[WM_CURSOR_DEFAULT] = &NWArrowCursor;
443   BlenderCursor[WM_CURSOR_COPY] = &NWArrowCursor;
444   BlenderCursor[WM_CURSOR_NW_ARROW] = &NWArrowCursor;
445   END_CURSOR_BLOCK;
446 
447   /************************ NS_ARROW Cursor *************************/
448   BEGIN_CURSOR_BLOCK;
449   static char ns_bitmap[] = {
450       0x00, 0x00, 0x80, 0x00, 0xc0, 0x01, 0xe0, 0x03, 0xf0, 0x07, 0x80,
451       0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00,
452       0xf0, 0x07, 0xe0, 0x03, 0xc0, 0x01, 0x80, 0x00, 0x00, 0x00,
453   };
454 
455   static char ns_mask[] = {
456       0x80, 0x00, 0xc0, 0x01, 0xe0, 0x03, 0xf0, 0x07, 0xf8, 0x0f, 0xfc,
457       0x1f, 0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x01, 0xfc, 0x1f,
458       0xf8, 0x0f, 0xf0, 0x07, 0xe0, 0x03, 0xc0, 0x01, 0x80, 0x00,
459   };
460 
461   static BCursor NSArrowCursor = {
462       ns_bitmap,
463       ns_mask,
464       7,
465       7,
466       true,
467   };
468 
469   BlenderCursor[WM_CURSOR_Y_MOVE] = &NSArrowCursor;
470   BlenderCursor[WM_CURSOR_NS_ARROW] = &NSArrowCursor;
471   END_CURSOR_BLOCK;
472 
473   /********************** EW_ARROW Cursor *************************/
474   BEGIN_CURSOR_BLOCK;
475   static char ew_bitmap[] = {
476       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x08, 0x18,
477       0x18, 0x1c, 0x38, 0xfe, 0x7f, 0x1c, 0x38, 0x18, 0x18, 0x10, 0x08,
478       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
479   };
480 
481   static char ew_mask[] = {
482       0x00, 0x00, 0x00, 0x00, 0x20, 0x04, 0x30, 0x0c, 0x38, 0x1c, 0x3c,
483       0x3c, 0xfe, 0x7f, 0xff, 0xff, 0xfe, 0x7f, 0x3c, 0x3c, 0x38, 0x1c,
484       0x30, 0x0c, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
485   };
486 
487   static BCursor EWArrowCursor = {
488       ew_bitmap,
489       ew_mask,
490       7,
491       7,
492       true,
493   };
494 
495   BlenderCursor[WM_CURSOR_X_MOVE] = &EWArrowCursor;
496   BlenderCursor[WM_CURSOR_EW_ARROW] = &EWArrowCursor;
497   END_CURSOR_BLOCK;
498 
499   /********************** Wait Cursor *****************************/
500   BEGIN_CURSOR_BLOCK;
501   static char wait_bitmap[] = {
502       0x00, 0x00, 0x00, 0x00, 0xf0, 0x07, 0xf0, 0x07, 0xb0, 0x06, 0x60,
503       0x03, 0xc0, 0x01, 0x80, 0x00, 0x80, 0x00, 0xc0, 0x01, 0x60, 0x03,
504       0x30, 0x06, 0x10, 0x04, 0xf0, 0x07, 0x00, 0x00, 0x00, 0x00,
505   };
506 
507   static char wait_mask[] = {
508       0xfc, 0x1f, 0xfc, 0x1f, 0xf8, 0x0f, 0xf8, 0x0f, 0xf8, 0x0f, 0xf0,
509       0x07, 0xe0, 0x03, 0xc0, 0x01, 0xc0, 0x01, 0xe0, 0x03, 0xf0, 0x07,
510       0xf8, 0x0f, 0xf8, 0x0f, 0xf8, 0x0f, 0xfc, 0x1f, 0xfc, 0x1f,
511   };
512 
513   static BCursor WaitCursor = {
514       wait_bitmap,
515       wait_mask,
516       7,
517       7,
518       false,
519   };
520 
521   BlenderCursor[WM_CURSOR_WAIT] = &WaitCursor;
522   END_CURSOR_BLOCK;
523 
524   /****************** Normal Cross Cursor ************************/
525   BEGIN_CURSOR_BLOCK;
526   static char cross_bitmap[] = {
527       0x00, 0x00, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80,
528       0x01, 0x00, 0x00, 0x3e, 0x7c, 0x3e, 0x7c, 0x00, 0x00, 0x80, 0x01,
529       0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x00, 0x00,
530 
531   };
532 
533   static char cross_mask[] = {
534       0xc0, 0x03, 0xc0, 0x03, 0xc0, 0x03, 0xc0, 0x03, 0xc0, 0x03, 0xc0,
535       0x03, 0x7f, 0xfe, 0x7f, 0xfe, 0x7f, 0xfe, 0xff, 0xff, 0xc0, 0x03,
536       0xc0, 0x03, 0xc0, 0x03, 0xc0, 0x03, 0xc0, 0x03, 0xc0, 0x03,
537   };
538 
539   static BCursor CrossCursor = {
540       cross_bitmap,
541       cross_mask,
542       7,
543       7,
544       false,
545   };
546 
547   BlenderCursor[WM_CURSOR_EDIT] = &CrossCursor;
548   BlenderCursor[WM_CURSOR_CROSS] = &CrossCursor;
549   END_CURSOR_BLOCK;
550 
551   /****************** Painting Cursor ************************/
552   BEGIN_CURSOR_BLOCK;
553   static char paint_bitmap[] = {
554       0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00,
555       0x00, 0x00, 0x00, 0x8f, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
556       0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x00, 0x00,
557   };
558 
559   static char paint_mask[] = {
560       0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x01, 0x00, 0x00, 0x00,
561       0x00, 0x8f, 0x78, 0xcf, 0x79, 0x8f, 0x78, 0x00, 0x00, 0x00, 0x00,
562       0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x01, 0x00, 0x00,
563   };
564 
565   static BCursor PaintCursor = {
566       paint_bitmap,
567       paint_mask,
568       7,
569       7,
570       false,
571   };
572 
573   BlenderCursor[WM_CURSOR_PAINT] = &PaintCursor;
574   END_CURSOR_BLOCK;
575 
576   /********************** Dot Cursor ***********************/
577   BEGIN_CURSOR_BLOCK;
578   static char dot_bitmap[] = {
579       0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00,
580       0x00, 0x00, 0x00, 0x8f, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
581       0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x00, 0x00,
582   };
583 
584   static char dot_mask[] = {
585       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
586       0x00, 0x80, 0x00, 0xc0, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
587       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
588   };
589 
590   static BCursor DotCursor = {
591       dot_bitmap,
592       dot_mask,
593       7,
594       7,
595       false,
596   };
597 
598   BlenderCursor[WM_CURSOR_DOT] = &DotCursor;
599   END_CURSOR_BLOCK;
600 
601   /************* Minimal Crosshair Cursor ***************/
602   BEGIN_CURSOR_BLOCK;
603   static char crossc_bitmap[] = {
604       0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
605       0x00, 0x80, 0x00, 0x55, 0x55, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00,
606       0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
607   };
608 
609   static char crossc_mask[] = {
610       0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80,
611       0x00, 0x80, 0x00, 0x7f, 0x7f, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00,
612       0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x00, 0x00,
613   };
614 
615   static BCursor CrossCursorC = {
616       crossc_bitmap,
617       crossc_mask,
618       7,
619       7,
620       false,
621   };
622 
623   BlenderCursor[WM_CURSOR_CROSSC] = &CrossCursorC;
624   END_CURSOR_BLOCK;
625 
626   /********************** Knife Cursor ***********************/
627   BEGIN_CURSOR_BLOCK;
628   static char knife_bitmap[] = {
629       0x00, 0x00, 0x00, 0x40, 0x00, 0x60, 0x00, 0x30, 0x00, 0x18, 0x00,
630       0x0c, 0x00, 0x06, 0x00, 0x0f, 0x80, 0x07, 0xc0, 0x03, 0xe0, 0x01,
631       0xf0, 0x00, 0x78, 0x00, 0x3c, 0x00, 0x0e, 0x00, 0x00, 0x00,
632   };
633 
634   static char knife_mask[] = {
635       0x00, 0x40, 0x00, 0xe0, 0x00, 0xf0, 0x00, 0x78, 0x00, 0x3c, 0x00,
636       0x1e, 0x00, 0x0f, 0x80, 0x1f, 0xc0, 0x0f, 0xe0, 0x07, 0xf0, 0x03,
637       0xf8, 0x01, 0xfc, 0x00, 0x7e, 0x00, 0x3f, 0x00, 0x0f, 0x00,
638   };
639 
640   static BCursor KnifeCursor = {
641       knife_bitmap,
642       knife_mask,
643       0,
644       15,
645       false,
646   };
647 
648   BlenderCursor[WM_CURSOR_KNIFE] = &KnifeCursor;
649   END_CURSOR_BLOCK;
650 
651   /********************** Loop Select Cursor ***********************/
652   BEGIN_CURSOR_BLOCK;
653   static char vloop_bitmap[] = {
654       0x00, 0x00, 0x7e, 0x00, 0x3e, 0x00, 0x1e, 0x00, 0xfe, 0xf0, 0x96,
655       0x9f, 0x92, 0x90, 0xf0, 0xf0, 0x20, 0x40, 0x20, 0x40, 0x20, 0x40,
656       0x20, 0x40, 0xf0, 0xf0, 0x90, 0x90, 0x90, 0x9f, 0xf0, 0xf0,
657   };
658 
659   static char vloop_mask[] = {
660       0xff, 0x01, 0xff, 0x00, 0x7f, 0x00, 0x3f, 0x00, 0xff, 0xf0, 0xff,
661       0xff, 0xf7, 0xff, 0xf3, 0xf0, 0x61, 0x60, 0x60, 0x60, 0x60, 0x60,
662       0x60, 0x60, 0xf0, 0xf0, 0xf0, 0xff, 0xf0, 0xff, 0xf0, 0xf0,
663   };
664 
665   static BCursor VLoopCursor = {
666       vloop_bitmap,
667       vloop_mask,
668       0,
669       0,
670       false,
671   };
672 
673   BlenderCursor[WM_CURSOR_VERTEX_LOOP] = &VLoopCursor;
674   END_CURSOR_BLOCK;
675 
676   /********************** TextEdit Cursor ***********************/
677   BEGIN_CURSOR_BLOCK;
678   static char textedit_bitmap[] = {
679       0x00, 0x00, 0x70, 0x07, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80,
680       0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00,
681       0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x70, 0x07, 0x00, 0x00,
682   };
683 
684   static char textedit_mask[] = {
685       0x70, 0x07, 0xf8, 0x0f, 0xf0, 0x07, 0xc0, 0x01, 0xc0, 0x01, 0xc0,
686       0x01, 0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x01,
687       0xc0, 0x01, 0xc0, 0x01, 0xf0, 0x07, 0xf8, 0x0f, 0x70, 0x07,
688   };
689 
690   static BCursor TextEditCursor = {
691       textedit_bitmap,
692       textedit_mask,
693       7,
694       7,
695       false,
696   };
697 
698   BlenderCursor[WM_CURSOR_TEXT_EDIT] = &TextEditCursor;
699   END_CURSOR_BLOCK;
700 
701   /********************** Paintbrush Cursor ***********************/
702   BEGIN_CURSOR_BLOCK;
703   static char paintbrush_bitmap[] = {
704       0x00, 0x00, 0x00, 0x30, 0x00, 0x78, 0x00, 0x74, 0x00, 0x2e, 0x00,
705       0x1f, 0x80, 0x0f, 0xc0, 0x07, 0xe0, 0x03, 0xf0, 0x01, 0xf8, 0x00,
706       0x7c, 0x00, 0x3e, 0x00, 0x1e, 0x00, 0x0e, 0x00, 0x00, 0x00,
707   };
708 
709   static char paintbrush_mask[] = {
710       0x00, 0x30, 0x00, 0x78, 0x00, 0xfc, 0x00, 0xfe, 0x00, 0x7f, 0x80,
711       0x3f, 0xc0, 0x1f, 0xe0, 0x0f, 0xf0, 0x07, 0xf8, 0x03, 0xfc, 0x01,
712       0xfe, 0x00, 0x7f, 0x00, 0x3f, 0x00, 0x1f, 0x00, 0x0f, 0x00,
713   };
714 
715   static BCursor PaintBrushCursor = {
716       paintbrush_bitmap,
717       paintbrush_mask,
718       0,
719       15,
720       false,
721   };
722 
723   BlenderCursor[WM_CURSOR_PAINT_BRUSH] = &PaintBrushCursor;
724   END_CURSOR_BLOCK;
725 
726   /********************** Eraser Cursor ***********************/
727   BEGIN_CURSOR_BLOCK;
728   static char eraser_bitmap[] = {
729       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
730       0x00, 0xc0, 0x01, 0xe0, 0x03, 0xf0, 0x07, 0xf8, 0x0f, 0xfc, 0x07,
731       0xfe, 0x03, 0xfe, 0x01, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00,
732   };
733 
734   static char eraser_mask[] = {
735       0x00, 0x00, 0x00, 0x04, 0x00, 0x0e, 0x00, 0x1f, 0x80, 0x3f, 0xc0,
736       0x7f, 0xe0, 0xff, 0xf0, 0x7f, 0xf8, 0x3f, 0xfc, 0x1f, 0xfe, 0x0f,
737       0xff, 0x07, 0xff, 0x03, 0xff, 0x01, 0xff, 0x00, 0x00, 0x00,
738   };
739 
740   static BCursor EraserCursor = {
741       eraser_bitmap,
742       eraser_mask,
743       0,
744       14,
745       false,
746   };
747 
748   BlenderCursor[WM_CURSOR_ERASER] = &EraserCursor;
749   END_CURSOR_BLOCK;
750 
751   /********************** Hand Cursor ***********************/
752   BEGIN_CURSOR_BLOCK;
753   static char hand_bitmap[] = {
754       0x00, 0x00, 0x80, 0x01, 0x80, 0x0d, 0x98, 0x6d, 0xb8, 0x6d, 0xb0,
755       0x6d, 0xb0, 0x6d, 0xe0, 0x6f, 0xe6, 0x7f, 0xee, 0x7f, 0x7c, 0x35,
756       0x78, 0x35, 0x70, 0x15, 0x60, 0x15, 0xc0, 0x1f, 0xc0, 0x1f,
757   };
758 
759   static char hand_mask[] = {
760       0x80, 0x01, 0xc0, 0x0f, 0xd8, 0x7f, 0xfc, 0xff, 0xfc, 0xff, 0xf8,
761       0xff, 0xf8, 0xff, 0xf6, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x7f,
762       0xfc, 0x7f, 0xf8, 0x3f, 0xf0, 0x3f, 0xe0, 0x3f, 0xe0, 0x3f,
763   };
764 
765   static BCursor HandCursor = {
766       hand_bitmap,
767       hand_mask,
768       8,
769       8,
770       false,
771   };
772 
773   BlenderCursor[WM_CURSOR_HAND] = &HandCursor;
774   END_CURSOR_BLOCK;
775 
776   /********************** NSEW Scroll Cursor ***********************/
777   BEGIN_CURSOR_BLOCK;
778   static char nsewscroll_bitmap[] = {
779       0x00, 0x00, 0x80, 0x01, 0xc0, 0x03, 0x40, 0x02, 0x00, 0x00, 0x00,
780       0x00, 0x0c, 0x30, 0x06, 0x60, 0x06, 0x60, 0x0c, 0x30, 0x00, 0x00,
781       0x00, 0x00, 0x40, 0x02, 0xc0, 0x03, 0x80, 0x01, 0x00, 0x00,
782   };
783 
784   static char nsewscroll_mask[] = {
785       0x80, 0x01, 0xc0, 0x03, 0xe0, 0x07, 0xe0, 0x07, 0x40, 0x02, 0x0c,
786       0x30, 0x1e, 0x78, 0x0f, 0xf0, 0x0f, 0xf8, 0x1e, 0x78, 0x0c, 0x30,
787       0x40, 0x02, 0xe0, 0x07, 0xe0, 0x07, 0xc0, 0x03, 0x80, 0x01,
788   };
789 
790   static BCursor NSEWScrollCursor = {
791       nsewscroll_bitmap,
792       nsewscroll_mask,
793       7,
794       7,
795       true,
796   };
797 
798   BlenderCursor[WM_CURSOR_NSEW_SCROLL] = &NSEWScrollCursor;
799   END_CURSOR_BLOCK;
800 
801   /********************** NS Scroll Cursor ***********************/
802   BEGIN_CURSOR_BLOCK;
803   static char nsscroll_bitmap[] = {
804       0x00, 0x00, 0x80, 0x00, 0xc0, 0x01, 0xe0, 0x03, 0x70, 0x07, 0x20,
805       0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x02,
806       0x70, 0x07, 0xe0, 0x03, 0xc0, 0x01, 0x80, 0x00, 0x00, 0x00,
807   };
808 
809   static char nsscroll_mask[] = {
810       0x80, 0x00, 0xc0, 0x01, 0xe0, 0x03, 0xf0, 0x07, 0xf8, 0x0f, 0x70,
811       0x07, 0x20, 0x02, 0x00, 0x00, 0x00, 0x00, 0x20, 0x02, 0x70, 0x07,
812       0xf8, 0x0f, 0xf0, 0x07, 0xe0, 0x03, 0xc0, 0x01, 0x80, 0x00,
813   };
814 
815   static BCursor NSScrollCursor = {
816       nsscroll_bitmap,
817       nsscroll_mask,
818       7,
819       7,
820       true,
821   };
822 
823   BlenderCursor[WM_CURSOR_NS_SCROLL] = &NSScrollCursor;
824   END_CURSOR_BLOCK;
825 
826   /********************** EW Scroll Cursor ***********************/
827   BEGIN_CURSOR_BLOCK;
828   static char ewscroll_bitmap[] = {
829       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x08, 0x38,
830       0x1c, 0x1c, 0x38, 0x0e, 0x70, 0x1c, 0x38, 0x38, 0x1c, 0x10, 0x08,
831       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
832   };
833 
834   static char ewscroll_mask[] = {
835       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x08, 0x38, 0x1c, 0x7c,
836       0x3e, 0x3e, 0x7c, 0x1f, 0xf8, 0x3e, 0x7c, 0x7c, 0x3e, 0x38, 0x1c,
837       0x10, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
838   };
839 
840   static BCursor EWScrollCursor = {
841       ewscroll_bitmap,
842       ewscroll_mask,
843       7,
844       7,
845       true,
846   };
847 
848   BlenderCursor[WM_CURSOR_EW_SCROLL] = &EWScrollCursor;
849   END_CURSOR_BLOCK;
850 
851   /********************** Eyedropper Cursor ***********************/
852   BEGIN_CURSOR_BLOCK;
853   static char eyedropper_bitmap[] = {
854       0x00, 0x00, 0x00, 0x60, 0x00, 0x70, 0x00, 0x3a, 0x00, 0x17, 0x00,
855       0x0e, 0x00, 0x1d, 0x80, 0x0b, 0xc0, 0x01, 0xe0, 0x00, 0x70, 0x00,
856       0x38, 0x00, 0x1c, 0x00, 0x0c, 0x00, 0x02, 0x00, 0x00, 0x00,
857   };
858 
859   static char eyedropper_mask[] = {
860       0x00, 0x60, 0x00, 0xf0, 0x00, 0xfa, 0x00, 0x7f, 0x80, 0x3f, 0x00,
861       0x1f, 0x80, 0x3f, 0xc0, 0x1f, 0xe0, 0x0b, 0xf0, 0x01, 0xf8, 0x00,
862       0x7c, 0x00, 0x3e, 0x00, 0x1e, 0x00, 0x0f, 0x00, 0x03, 0x00,
863   };
864 
865   static BCursor EyedropperCursor = {
866       eyedropper_bitmap,
867       eyedropper_mask,
868       0,
869       15,
870       false,
871   };
872 
873   BlenderCursor[WM_CURSOR_EYEDROPPER] = &EyedropperCursor;
874   END_CURSOR_BLOCK;
875 
876   /********************** Swap Area Cursor ***********************/
877   BEGIN_CURSOR_BLOCK;
878   static char swap_bitmap[] = {
879       0xc0, 0xff, 0x40, 0x80, 0x40, 0xbc, 0x40, 0xb8, 0x40, 0xb8, 0x40,
880       0xa4, 0x00, 0x82, 0xfe, 0x81, 0x7e, 0x81, 0xbe, 0xfd, 0xda, 0x01,
881       0xe2, 0x01, 0xe2, 0x01, 0xc2, 0x01, 0xfe, 0x01, 0x00, 0x00,
882   };
883 
884   static char swap_mask[] = {
885       0xc0, 0xff, 0xc0, 0xff, 0xc0, 0xff, 0xc0, 0xff, 0xc0, 0xff, 0xc0,
886       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x03,
887       0xff, 0x03, 0xff, 0x03, 0xff, 0x03, 0xff, 0x03, 0xff, 0x03,
888   };
889 
890   static BCursor SwapCursor = {
891       swap_bitmap,
892       swap_mask,
893       7,
894       7,
895       false,
896   };
897 
898   BlenderCursor[WM_CURSOR_SWAP_AREA] = &SwapCursor;
899   END_CURSOR_BLOCK;
900 
901   /********************** Vertical Split Cursor ***********************/
902   BEGIN_CURSOR_BLOCK;
903   static char vsplit_bitmap[] = {
904       0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x88,
905       0x11, 0x8c, 0x31, 0x86, 0x61, 0x86, 0x61, 0x8c, 0x31, 0x88, 0x11,
906       0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01,
907   };
908 
909   static char vsplit_mask[] = {
910       0xe0, 0x07, 0xc0, 0x03, 0xc0, 0x03, 0xc0, 0x03, 0xc8, 0x13, 0xdc,
911       0x3b, 0xde, 0x7b, 0xcf, 0xf3, 0xcf, 0xf3, 0xde, 0x7b, 0xdc, 0x3b,
912       0xc8, 0x13, 0xc0, 0x03, 0xc0, 0x03, 0xc0, 0x03, 0xe0, 0x07,
913   };
914 
915   static BCursor VSplitCursor = {
916       vsplit_bitmap,
917       vsplit_mask,
918       7,
919       7,
920       true,
921   };
922 
923   BlenderCursor[WM_CURSOR_V_SPLIT] = &VSplitCursor;
924   END_CURSOR_BLOCK;
925 
926   /********************** Horizontal Split Cursor ***********************/
927   BEGIN_CURSOR_BLOCK;
928   static char hsplit_bitmap[] = {
929       0x00, 0x00, 0x80, 0x01, 0xc0, 0x03, 0x60, 0x06, 0x00, 0x00, 0x00,
930       0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
931       0x00, 0x00, 0x60, 0x06, 0xc0, 0x03, 0x80, 0x01, 0x00, 0x00,
932   };
933 
934   static char hsplit_mask[] = {
935       0x80, 0x01, 0xc0, 0x03, 0xe0, 0x07, 0xf0, 0x0f, 0x60, 0x06, 0x01,
936       0x80, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0x80,
937       0x60, 0x06, 0xf0, 0x0f, 0xe0, 0x07, 0xc0, 0x03, 0x80, 0x01,
938   };
939 
940   static BCursor HSplitCursor = {
941       hsplit_bitmap,
942       hsplit_mask,
943       7,
944       7,
945       true,
946   };
947 
948   BlenderCursor[WM_CURSOR_H_SPLIT] = &HSplitCursor;
949   END_CURSOR_BLOCK;
950 
951   /********************** North Arrow Cursor ***********************/
952   BEGIN_CURSOR_BLOCK;
953   static char narrow_bitmap[] = {
954       0x00, 0x00, 0x80, 0x00, 0xc0, 0x01, 0xe0, 0x03, 0xf0, 0x07, 0xf8,
955       0x0f, 0x7c, 0x1f, 0x3e, 0x3e, 0x1c, 0x1c, 0x08, 0x08, 0x00, 0x00,
956       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
957   };
958 
959   static char narrow_mask[] = {
960       0x80, 0x00, 0xc0, 0x01, 0xe0, 0x03, 0xf0, 0x07, 0xf8, 0x0f, 0xfc,
961       0x1f, 0xfe, 0x3f, 0x7f, 0x7f, 0x3e, 0x3e, 0x1c, 0x1c, 0x08, 0x08,
962       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
963   };
964 
965   static BCursor NArrowCursor = {
966       narrow_bitmap,
967       narrow_mask,
968       7,
969       5,
970       true,
971   };
972 
973   BlenderCursor[WM_CURSOR_N_ARROW] = &NArrowCursor;
974   END_CURSOR_BLOCK;
975 
976   /********************** South Arrow Cursor ***********************/
977   BEGIN_CURSOR_BLOCK;
978   static char sarrow_bitmap[] = {
979       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
980       0x00, 0x08, 0x08, 0x1c, 0x1c, 0x3e, 0x3e, 0x7c, 0x1f, 0xf8, 0x0f,
981       0xf0, 0x07, 0xe0, 0x03, 0xc0, 0x01, 0x80, 0x00, 0x00, 0x00,
982   };
983 
984   static char sarrow_mask[] = {
985       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
986       0x08, 0x1c, 0x1c, 0x3e, 0x3e, 0x7f, 0x7f, 0xfe, 0x3f, 0xfc, 0x1f,
987       0xf8, 0x0f, 0xf0, 0x07, 0xe0, 0x03, 0xc0, 0x01, 0x80, 0x00,
988   };
989 
990   static BCursor SArrowCursor = {
991       sarrow_bitmap,
992       sarrow_mask,
993       7,
994       10,
995       true,
996   };
997 
998   BlenderCursor[WM_CURSOR_S_ARROW] = &SArrowCursor;
999   END_CURSOR_BLOCK;
1000 
1001   /********************** East Arrow Cursor ***********************/
1002   BEGIN_CURSOR_BLOCK;
1003   static char earrow_bitmap[] = {
1004       0x00, 0x00, 0x00, 0x01, 0x80, 0x03, 0xc0, 0x07, 0x80, 0x0f, 0x00,
1005       0x1f, 0x00, 0x3e, 0x00, 0x7c, 0x00, 0x3e, 0x00, 0x1f, 0x80, 0x0f,
1006       0xc0, 0x07, 0x80, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
1007   };
1008 
1009   static char earrow_mask[] = {
1010       0x00, 0x01, 0x80, 0x03, 0xc0, 0x07, 0xe0, 0x0f, 0xc0, 0x1f, 0x80,
1011       0x3f, 0x00, 0x7f, 0x00, 0xfe, 0x00, 0x7f, 0x80, 0x3f, 0xc0, 0x1f,
1012       0xe0, 0x0f, 0xc0, 0x07, 0x80, 0x03, 0x00, 0x01, 0x00, 0x00,
1013   };
1014 
1015   static BCursor EArrowCursor = {
1016       earrow_bitmap,
1017       earrow_mask,
1018       10,
1019       7,
1020       true,
1021   };
1022 
1023   BlenderCursor[WM_CURSOR_E_ARROW] = &EArrowCursor;
1024   END_CURSOR_BLOCK;
1025 
1026   /********************** West Arrow Cursor ***********************/
1027   BEGIN_CURSOR_BLOCK;
1028   static char warrow_bitmap[] = {
1029       0x00, 0x00, 0x80, 0x00, 0xc0, 0x01, 0xe0, 0x03, 0xf0, 0x01, 0xf8,
1030       0x00, 0x7c, 0x00, 0x3e, 0x00, 0x7c, 0x00, 0xf8, 0x00, 0xf0, 0x01,
1031       0xe0, 0x03, 0xc0, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
1032   };
1033 
1034   static char warrow_mask[] = {
1035       0x80, 0x00, 0xc0, 0x01, 0xe0, 0x03, 0xf0, 0x07, 0xf8, 0x03, 0xfc,
1036       0x01, 0xfe, 0x00, 0x7f, 0x00, 0xfe, 0x00, 0xfc, 0x01, 0xf8, 0x03,
1037       0xf0, 0x07, 0xe0, 0x03, 0xc0, 0x01, 0x80, 0x00, 0x00, 0x00,
1038   };
1039 
1040   static BCursor WArrowCursor = {
1041       warrow_bitmap,
1042       warrow_mask,
1043       5,
1044       7,
1045       true,
1046   };
1047 
1048   BlenderCursor[WM_CURSOR_W_ARROW] = &WArrowCursor;
1049   END_CURSOR_BLOCK;
1050 
1051   /********************** Stop Sign Cursor ***********************/
1052   BEGIN_CURSOR_BLOCK;
1053   static char stop_bitmap[] = {
1054       0x00, 0x00, 0xe0, 0x07, 0xf8, 0x1f, 0x1c, 0x3c, 0x3c, 0x30, 0x76,
1055       0x70, 0xe6, 0x60, 0xc6, 0x61, 0x86, 0x63, 0x06, 0x67, 0x0e, 0x6e,
1056       0x0c, 0x3c, 0x3c, 0x38, 0xf8, 0x1f, 0xe0, 0x07, 0x00, 0x00,
1057   };
1058 
1059   static char stop_mask[] = {
1060       0xe0, 0x07, 0xf8, 0x1f, 0xfc, 0x3f, 0xfe, 0x7f, 0x7e, 0x7c, 0xff,
1061       0xf8, 0xff, 0xf1, 0xef, 0xf3, 0xcf, 0xf7, 0x8f, 0xff, 0x1f, 0xff,
1062       0x3e, 0x7e, 0xfe, 0x7f, 0xfc, 0x3f, 0xf8, 0x1f, 0xe0, 0x07,
1063   };
1064 
1065   static BCursor StopCursor = {
1066       stop_bitmap,
1067       stop_mask,
1068       7,
1069       7,
1070       false,
1071   };
1072 
1073   BlenderCursor[WM_CURSOR_STOP] = &StopCursor;
1074   END_CURSOR_BLOCK;
1075 
1076   /********************** Zoom In Cursor ***********************/
1077   BEGIN_CURSOR_BLOCK;
1078   static char zoomin_bitmap[] = {
1079       0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, 0xf8, 0x03, 0xb8, 0x03, 0xbc,
1080       0x07, 0x0c, 0x06, 0xbc, 0x07, 0xb8, 0x03, 0xf8, 0x0b, 0xe0, 0x14,
1081       0x00, 0x22, 0x00, 0x44, 0x00, 0x88, 0x00, 0x90, 0x00, 0x60,
1082   };
1083 
1084   static char zoomin_mask[] = {
1085       0x00, 0x00, 0xe0, 0x00, 0xf8, 0x03, 0xfc, 0x07, 0xfc, 0x07, 0xfe,
1086       0x0f, 0xfe, 0x0f, 0xfe, 0x0f, 0xfc, 0x07, 0xfc, 0x0f, 0xf8, 0x1f,
1087       0xe0, 0x3e, 0x00, 0x7c, 0x00, 0xf8, 0x00, 0xf0, 0x00, 0x60,
1088   };
1089 
1090   static BCursor ZoomInCursor = {
1091       zoomin_bitmap,
1092       zoomin_mask,
1093       6,
1094       6,
1095       false,
1096   };
1097 
1098   BlenderCursor[WM_CURSOR_ZOOM_IN] = &ZoomInCursor;
1099   END_CURSOR_BLOCK;
1100 
1101   /********************** Zoom Out Cursor ***********************/
1102   BEGIN_CURSOR_BLOCK;
1103   static char zoomout_bitmap[] = {
1104       0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, 0xf8, 0x03, 0xf8, 0x03, 0xfc,
1105       0x07, 0x0c, 0x06, 0xfc, 0x07, 0xf8, 0x03, 0xf8, 0x0b, 0xe0, 0x14,
1106       0x00, 0x22, 0x00, 0x44, 0x00, 0x88, 0x00, 0x90, 0x00, 0x60,
1107   };
1108 
1109   static char zoomout_mask[] = {
1110       0x00, 0x00, 0xe0, 0x00, 0xf8, 0x03, 0xfc, 0x07, 0xfc, 0x07, 0xfe,
1111       0x0f, 0xfe, 0x0f, 0xfe, 0x0f, 0xfc, 0x07, 0xfc, 0x0f, 0xf8, 0x1f,
1112       0xe0, 0x3e, 0x00, 0x7c, 0x00, 0xf8, 0x00, 0xf0, 0x00, 0x60,
1113   };
1114 
1115   static BCursor ZoomOutCursor = {
1116       zoomout_bitmap,
1117       zoomout_mask,
1118       6,
1119       6,
1120       false,
1121   };
1122 
1123   BlenderCursor[WM_CURSOR_ZOOM_OUT] = &ZoomOutCursor;
1124   END_CURSOR_BLOCK;
1125 
1126   /********************** Put the cursors in the array ***********************/
1127 }
1128