- fixed a minor bug in the UNIX/X11 cursor code, causing an X error and abort

due to a stale cursor cache, when the application (which calls glutSetCursor),
  uses glutLeaveMainLoop to close the connection to the X server, and then
  re-initializes freeglut and starts over with a new connection.


git-svn-id: https://svn.code.sf.net/p/freeglut/code/trunk@1749 7f0cb862-5218-0410-a997-914c9d46530a
This commit is contained in:
jtsiomb 2015-02-28 04:15:13 +00:00
parent 3be8dc8380
commit 3f95e542fa

View File

@ -61,6 +61,7 @@ struct tag_cursorCacheEntry {
unsigned int cursorShape; /* an XC_foo value */ unsigned int cursorShape; /* an XC_foo value */
Cursor cachedCursor; /* None if the corresponding cursor has Cursor cachedCursor; /* None if the corresponding cursor has
not been created yet */ not been created yet */
Display *dpy; /* display used to allocate this cursor */
}; };
/* /*
@ -68,26 +69,26 @@ struct tag_cursorCacheEntry {
* the "normal" GLUT_CURSOR_* values start a 0 and are consecutive. * the "normal" GLUT_CURSOR_* values start a 0 and are consecutive.
*/ */
static cursorCacheEntry cursorCache[] = { static cursorCacheEntry cursorCache[] = {
{ XC_arrow, None }, /* GLUT_CURSOR_RIGHT_ARROW */ { XC_arrow, None, 0 }, /* GLUT_CURSOR_RIGHT_ARROW */
{ XC_top_left_arrow, None }, /* GLUT_CURSOR_LEFT_ARROW */ { XC_top_left_arrow, None, 0 }, /* GLUT_CURSOR_LEFT_ARROW */
{ XC_hand1, None }, /* GLUT_CURSOR_INFO */ { XC_hand1, None, 0 }, /* GLUT_CURSOR_INFO */
{ XC_pirate, None }, /* GLUT_CURSOR_DESTROY */ { XC_pirate, None, 0 }, /* GLUT_CURSOR_DESTROY */
{ XC_question_arrow, None }, /* GLUT_CURSOR_HELP */ { XC_question_arrow, None, 0 }, /* GLUT_CURSOR_HELP */
{ XC_exchange, None }, /* GLUT_CURSOR_CYCLE */ { XC_exchange, None, 0 }, /* GLUT_CURSOR_CYCLE */
{ XC_spraycan, None }, /* GLUT_CURSOR_SPRAY */ { XC_spraycan, None, 0 }, /* GLUT_CURSOR_SPRAY */
{ XC_watch, None }, /* GLUT_CURSOR_WAIT */ { XC_watch, None, 0 }, /* GLUT_CURSOR_WAIT */
{ XC_xterm, None }, /* GLUT_CURSOR_TEXT */ { XC_xterm, None, 0 }, /* GLUT_CURSOR_TEXT */
{ XC_crosshair, None }, /* GLUT_CURSOR_CROSSHAIR */ { XC_crosshair, None, 0 }, /* GLUT_CURSOR_CROSSHAIR */
{ XC_sb_v_double_arrow, None }, /* GLUT_CURSOR_UP_DOWN */ { XC_sb_v_double_arrow, None, 0 }, /* GLUT_CURSOR_UP_DOWN */
{ XC_sb_h_double_arrow, None }, /* GLUT_CURSOR_LEFT_RIGHT */ { XC_sb_h_double_arrow, None, 0 }, /* GLUT_CURSOR_LEFT_RIGHT */
{ XC_top_side, None }, /* GLUT_CURSOR_TOP_SIDE */ { XC_top_side, None, 0 }, /* GLUT_CURSOR_TOP_SIDE */
{ XC_bottom_side, None }, /* GLUT_CURSOR_BOTTOM_SIDE */ { XC_bottom_side, None, 0 }, /* GLUT_CURSOR_BOTTOM_SIDE */
{ XC_left_side, None }, /* GLUT_CURSOR_LEFT_SIDE */ { XC_left_side, None, 0 }, /* GLUT_CURSOR_LEFT_SIDE */
{ XC_right_side, None }, /* GLUT_CURSOR_RIGHT_SIDE */ { XC_right_side, None, 0 }, /* GLUT_CURSOR_RIGHT_SIDE */
{ XC_top_left_corner, None }, /* GLUT_CURSOR_TOP_LEFT_CORNER */ { XC_top_left_corner, None, 0 }, /* GLUT_CURSOR_TOP_LEFT_CORNER */
{ XC_top_right_corner, None }, /* GLUT_CURSOR_TOP_RIGHT_CORNER */ { XC_top_right_corner, None, 0 }, /* GLUT_CURSOR_TOP_RIGHT_CORNER */
{ XC_bottom_right_corner, None }, /* GLUT_CURSOR_BOTTOM_RIGHT_CORNER */ { XC_bottom_right_corner, None, 0 }, /* GLUT_CURSOR_BOTTOM_RIGHT_CORNER */
{ XC_bottom_left_corner, None } /* GLUT_CURSOR_BOTTOM_LEFT_CORNER */ { XC_bottom_left_corner, None, 0 } /* GLUT_CURSOR_BOTTOM_LEFT_CORNER */
}; };
void fgPlatformSetCursor ( SFG_Window *window, int cursorID ) void fgPlatformSetCursor ( SFG_Window *window, int cursorID )
@ -104,10 +105,18 @@ void fgPlatformSetCursor ( SFG_Window *window, int cursorID )
if( ( cursorIDToUse >= 0 ) && if( ( cursorIDToUse >= 0 ) &&
( cursorIDToUse < sizeof( cursorCache ) / sizeof( cursorCache[0] ) ) ) { ( cursorIDToUse < sizeof( cursorCache ) / sizeof( cursorCache[0] ) ) ) {
cursorCacheEntry *entry = &cursorCache[ cursorIDToUse ]; cursorCacheEntry *entry = &cursorCache[ cursorIDToUse ];
if( entry->cachedCursor == None ) {
/* the second clause forces an invalidation of the cached cursor, if it was
* created through a different display connection.
* This can only happen, in the extremely rare case where the user program calls the
* freeglut extension glutLeaveMainLoop, and then re-initializes freeglut and
* starts over.
*/
if( entry->cachedCursor == None || entry->dpy != fgDisplay.pDisplay.Display ) {
entry->cachedCursor = entry->cachedCursor =
XCreateFontCursor( fgDisplay.pDisplay.Display, entry->cursorShape ); XCreateFontCursor( fgDisplay.pDisplay.Display, entry->cursorShape );
} entry->dpy = fgDisplay.pDisplay.Display;
}
cursor = entry->cachedCursor; cursor = entry->cachedCursor;
} else { } else {
switch( cursorIDToUse ) switch( cursorIDToUse )