Doxygen Source Code Documentation
        
Main Page   Alphabetical List   Data Structures   File List   Data Fields   Globals   Search   
glut_cursor.c
Go to the documentation of this file.00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 #include <GL/glut.h>
00009 #include "glutint.h"
00010 #include <X11/Xatom.h>  
00011 #include <X11/cursorfont.h>
00012 
00013 typedef struct _CursorTable {
00014   int glyph;
00015   Cursor cursor;
00016 } CursorTable;
00017 
00018 static CursorTable cursorTable[] = {
00019   {XC_arrow, None},               
00020   {XC_top_left_arrow, None},      
00021   {XC_hand1, None},               
00022   {XC_pirate, None},              
00023   {XC_question_arrow, None},      
00024   {XC_exchange, None},            
00025   {XC_spraycan, None},            
00026   {XC_watch, None},               
00027   {XC_xterm, None},               
00028   {XC_crosshair, None},           
00029   {XC_sb_v_double_arrow, None},   
00030   {XC_sb_h_double_arrow, None},   
00031   {XC_top_side, None},            
00032   {XC_bottom_side, None},         
00033   {XC_left_side, None},           
00034   {XC_right_side, None},          
00035   {XC_top_left_corner, None},     
00036   {XC_top_right_corner, None},    
00037   {XC_bottom_right_corner, None}, 
00038   {XC_bottom_left_corner, None},  
00039 };
00040 
00041 static Cursor blankCursor = None;
00042 static Cursor fullCrosshairCusor = None;
00043 
00044 static Cursor
00045 getFullCrosshairCursor(void)
00046 {
00047   Cursor cursor;
00048   Atom crosshairAtom, actualType;
00049   int rc, actualFormat;
00050   unsigned long n, left;
00051   unsigned long *value;
00052 
00053   if (fullCrosshairCusor == None) {
00054     crosshairAtom = XInternAtom(__glutDisplay,
00055       "_SGI_CROSSHAIR_CURSOR", True);
00056     if (crosshairAtom != None) {
00057       value = 0;        
00058       rc = XGetWindowProperty(__glutDisplay, __glutRoot,
00059         crosshairAtom, 0, 1, False, XA_CURSOR, &actualType,
00060         &actualFormat, &n, &left, (unsigned char **) &value);
00061       if (rc == Success && actualFormat == 32 && n >= 1) {
00062         cursor = value[0];
00063         XFree(value);
00064         return cursor;
00065       }
00066     }
00067   }
00068   return XCreateFontCursor(__glutDisplay, XC_crosshair);
00069 }
00070 
00071 static Cursor
00072 makeBlankCursor(void)
00073 {
00074   static char data[1] =
00075   {0};
00076   Cursor cursor;
00077   Pixmap blank;
00078   XColor dummy;
00079 
00080   blank = XCreateBitmapFromData(__glutDisplay, __glutRoot,
00081     data, 1, 1);
00082   if (blank == None)
00083     __glutFatalError("out of memory.");
00084   cursor = XCreatePixmapCursor(__glutDisplay, blank, blank,
00085     &dummy, &dummy, 0, 0);
00086   XFreePixmap(__glutDisplay, blank);
00087 
00088   return cursor;
00089 }
00090 
00091 void
00092 glutSetCursor(int cursor)
00093 {
00094   Cursor xcursor;
00095 
00096   if (cursor >= 0 &&
00097     cursor < sizeof(cursorTable) / sizeof(cursorTable[0])) {
00098     if (cursorTable[cursor].cursor == None)
00099       cursorTable[cursor].cursor = XCreateFontCursor(__glutDisplay,
00100         cursorTable[cursor].glyph);
00101     xcursor = cursorTable[cursor].cursor;
00102   } else {
00103     
00104     switch (cursor) {
00105     case GLUT_CURSOR_INHERIT:
00106       xcursor = None;
00107       break;
00108     case GLUT_CURSOR_NONE:
00109       if (blankCursor == None)
00110         blankCursor = makeBlankCursor();
00111       xcursor = blankCursor;
00112       break;
00113     case GLUT_CURSOR_FULL_CROSSHAIR:
00114       if (fullCrosshairCusor == None)
00115         fullCrosshairCusor = getFullCrosshairCursor();
00116       xcursor = fullCrosshairCusor;
00117       break;
00118     }
00119   }
00120   __glutCurrentWindow->cursor = cursor;
00121   XDefineCursor(__glutDisplay,
00122     __glutCurrentWindow->win, xcursor);
00123   XFlush(__glutDisplay);
00124 }