home *** CD-ROM | disk | FTP | other *** search
/ Magazyn Amiga 5 / MA_Cover_5.iso / ppc / mesa / src-glut / glut_cursor.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-01-31  |  4.9 KB  |  168 lines

  1. /* Copyright (c) Mark J. Kilgard, 1995. */
  2.  
  3. /* This program is freely distributable without licensing fees 
  4.    and is provided without guarantee or warrantee expressed or 
  5.    implied. This program is -not- in the public domain. */
  6.  
  7. #include <GL/glut.h>
  8. #include "glutint.h"
  9.  
  10. #if !defined(WIN32)
  11. #include <X11/Xatom.h>  /* For XA_CURSOR */
  12. #include <X11/cursorfont.h>
  13. #endif
  14.  
  15. typedef struct _CursorTable {
  16. #if defined(WIN32)
  17.   char* glyph;
  18. #else
  19.   int glyph;
  20. #endif
  21.   Cursor cursor;
  22. } CursorTable;
  23. /* *INDENT-OFF* */
  24.  
  25. static CursorTable cursorTable[] = {
  26.   {XC_arrow, None},          /* GLUT_CURSOR_RIGHT_ARROW */
  27.   {XC_top_left_arrow, None},      /* GLUT_CURSOR_LEFT_ARROW */
  28.   {XC_hand1, None},          /* GLUT_CURSOR_INFO */
  29.   {XC_pirate, None},          /* GLUT_CURSOR_DESTROY */
  30.   {XC_question_arrow, None},      /* GLUT_CURSOR_HELP */
  31.   {XC_exchange, None},          /* GLUT_CURSOR_CYCLE */
  32.   {XC_spraycan, None},          /* GLUT_CURSOR_SPRAY */
  33.   {XC_watch, None},          /* GLUT_CURSOR_WAIT */
  34.   {XC_xterm, None},          /* GLUT_CURSOR_TEXT */
  35.   {XC_crosshair, None},          /* GLUT_CURSOR_CROSSHAIR */
  36.   {XC_sb_v_double_arrow, None},      /* GLUT_CURSOR_UP_DOWN */
  37.   {XC_sb_h_double_arrow, None},      /* GLUT_CURSOR_LEFT_RIGHT */
  38.   {XC_top_side, None},          /* GLUT_CURSOR_TOP_SIDE */
  39.   {XC_bottom_side, None},      /* GLUT_CURSOR_BOTTOM_SIDE */
  40.   {XC_left_side, None},          /* GLUT_CURSOR_LEFT_SIDE */
  41.   {XC_right_side, None},      /* GLUT_CURSOR_RIGHT_SIDE */
  42.   {XC_top_left_corner, None},      /* GLUT_CURSOR_TOP_LEFT_CORNER */
  43.   {XC_top_right_corner, None},      /* GLUT_CURSOR_TOP_RIGHT_CORNER */
  44.   {XC_bottom_right_corner, None}, /* GLUT_CURSOR_BOTTOM_RIGHT_CORNER */
  45.   {XC_bottom_left_corner, None},  /* GLUT_CURSOR_BOTTOM_LEFT_CORNER */
  46. };
  47. /* *INDENT-ON* */
  48.  
  49. static Cursor blankCursor = None;
  50. static Cursor fullCrosshairCusor = None;
  51.  
  52. static Cursor
  53. getFullCrosshairCursor(void)
  54. {
  55. #if !defined(WIN32)
  56.   Cursor cursor;
  57.   Atom crosshairAtom, actualType;
  58.   int rc, actualFormat;
  59.   unsigned long n, left;
  60.   unsigned long *value;
  61.  
  62.   if (fullCrosshairCusor == None) {
  63.     crosshairAtom = XInternAtom(__glutDisplay,
  64.       "_SGI_CROSSHAIR_CURSOR", True);
  65.     if (crosshairAtom != None) {
  66.       value = 0;        /* Make compiler happy. */
  67.       rc = XGetWindowProperty(__glutDisplay, __glutRoot,
  68.         crosshairAtom, 0, 1, False, XA_CURSOR, &actualType,
  69.         &actualFormat, &n, &left, (unsigned char **) &value);
  70.       if (rc == Success && actualFormat == 32 && n >= 1) {
  71.         cursor = value[0];
  72.         XFree(value);
  73.         return cursor;
  74.       }
  75.     }
  76.   }
  77.   return XCreateFontCursor(__glutDisplay, XC_crosshair);
  78. #else
  79.   /* we could kludge up an XGetWindowProperty, XInterAtom and
  80.      XCreateFontCursor that worked for just this case, but I dunno if
  81.      it is worth it, hence the #ifdefs instead. */
  82.   return IDC_CROSS;
  83. #endif /* !WIN32 */
  84. }
  85.  
  86. static Cursor
  87. makeBlankCursor(void)
  88. {
  89. #if !defined(WIN32)
  90.   static char data[1] =
  91.   {0};
  92.   Cursor cursor;
  93.   Pixmap blank;
  94.   XColor dummy;
  95.  
  96.   blank = XCreateBitmapFromData(__glutDisplay, __glutRoot,
  97.     data, 1, 1);
  98.   if (blank == None)
  99.     __glutFatalError("out of memory.");
  100.   cursor = XCreatePixmapCursor(__glutDisplay, blank, blank,
  101.     &dummy, &dummy, 0, 0);
  102.   XFreePixmap(__glutDisplay, blank);
  103.  
  104.   return cursor;
  105. #else
  106.   /* we could kludge up an XCreateBitmapFromData, XCreatePixmapCursor
  107.      and XFreePixmap that worked for just this case, but I dunno if it
  108.      is worth it, hence the #ifdefs instead. */
  109.   return NULL;
  110. #endif /* !WIN32 */
  111. }
  112.  
  113. /* CENTRY */
  114. void APIENTRY 
  115. glutSetCursor(int cursor)
  116. {
  117.   Cursor xcursor;
  118.  
  119.   if (cursor >= 0 &&
  120.     cursor < sizeof(cursorTable) / sizeof(cursorTable[0])) {
  121.     if (cursorTable[cursor].cursor == None)
  122.       cursorTable[cursor].cursor = XCreateFontCursor(__glutDisplay,
  123.         cursorTable[cursor].glyph);
  124.     xcursor = cursorTable[cursor].cursor;
  125.   } else {
  126.     /* Special cases. */
  127.     switch (cursor) {
  128.     case GLUT_CURSOR_INHERIT:
  129. #if defined(WIN32)
  130.       /* must be a parent - this bit of voodoo is brought to you by
  131.      your friendly neighborhood Win32 API.  It allows the parent
  132.      to override the setting of the child windows cursor (ACK!).
  133.      Therefore, if this parent has children (and the cursor is in
  134.      one), DON'T SET THE CURSOR.  */
  135.       if (__glutCurrentWindow->parent)
  136.         return;
  137.       else {
  138.         if (__glutCurrentWindow->win != GetFocus())
  139.           return;
  140.         xcursor = cursorTable[0].cursor;
  141.         if (xcursor == NULL)
  142.           xcursor =
  143.             cursorTable[0].cursor =
  144.             LoadCursor(NULL, cursorTable[0].glyph);
  145.       }
  146. #else
  147.       xcursor = None;
  148. #endif
  149.       break;
  150.     case GLUT_CURSOR_NONE:
  151.       if (blankCursor == None)
  152.         blankCursor = makeBlankCursor();
  153.       xcursor = blankCursor;
  154.       break;
  155.     case GLUT_CURSOR_FULL_CROSSHAIR:
  156.       if (fullCrosshairCusor == None)
  157.         fullCrosshairCusor = getFullCrosshairCursor();
  158.       xcursor = fullCrosshairCusor;
  159.       break;
  160.     }
  161.   }
  162.   __glutCurrentWindow->cursor = cursor;
  163.   XDefineCursor(__glutDisplay,
  164.     __glutCurrentWindow->win, xcursor);
  165.   XFlush(__glutDisplay);
  166. }
  167. /* ENDCENTRY */
  168.