Mercurial > hgrepos > Python2 > PyMuPDF
view mupdf-source/thirdparty/freeglut/src/x11/fg_cursor_x11.c @ 40:aa33339d6b8a upstream
ADD: MuPDF v1.26.10: the MuPDF source as downloaded by a default build of PyMuPDF 1.26.5.
| author | Franz Glasner <fzglas.hg@dom66.de> |
|---|---|
| date | Sat, 11 Oct 2025 11:31:38 +0200 |
| parents | b50eed0cc0ef |
| children |
line wrap: on
line source
/* * fg_cursor_x11.c * * The Windows-specific mouse cursor related stuff. * * Copyright (c) 2012 Stephen J. Baker. All Rights Reserved. * Written by John F. Fay, <fayjf@sourceforge.net> * Creation date: Sun Feb 5, 2012 * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * PAWEL W. OLSZTA BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include <GL/freeglut.h> #include "../fg_internal.h" /* This code is for Posix/X11, Solaris, and OSX */ #include <X11/cursorfont.h> /* * A factory method for an empty cursor */ static Cursor getEmptyCursor( void ) { static Cursor cursorNone = None; if( cursorNone == None ) { char cursorNoneBits[ 32 ]; XColor dontCare; Pixmap cursorNonePixmap; memset( cursorNoneBits, 0, sizeof( cursorNoneBits ) ); memset( &dontCare, 0, sizeof( dontCare ) ); cursorNonePixmap = XCreateBitmapFromData ( fgDisplay.pDisplay.Display, fgDisplay.pDisplay.RootWindow, cursorNoneBits, 16, 16 ); if( cursorNonePixmap != None ) { cursorNone = XCreatePixmapCursor( fgDisplay.pDisplay.Display, cursorNonePixmap, cursorNonePixmap, &dontCare, &dontCare, 0, 0 ); XFreePixmap( fgDisplay.pDisplay.Display, cursorNonePixmap ); } } return cursorNone; } typedef struct tag_cursorCacheEntry cursorCacheEntry; struct tag_cursorCacheEntry { unsigned int cursorShape; /* an XC_foo value */ Cursor cachedCursor; /* None if the corresponding cursor has not been created yet */ Display *dpy; /* display used to allocate this cursor */ }; /* * Note: The arrangement of the table below depends on the fact that * the "normal" GLUT_CURSOR_* values start a 0 and are consecutive. */ static cursorCacheEntry cursorCache[] = { { XC_arrow, None, 0 }, /* GLUT_CURSOR_RIGHT_ARROW */ { XC_top_left_arrow, None, 0 }, /* GLUT_CURSOR_LEFT_ARROW */ { XC_hand1, None, 0 }, /* GLUT_CURSOR_INFO */ { XC_pirate, None, 0 }, /* GLUT_CURSOR_DESTROY */ { XC_question_arrow, None, 0 }, /* GLUT_CURSOR_HELP */ { XC_exchange, None, 0 }, /* GLUT_CURSOR_CYCLE */ { XC_spraycan, None, 0 }, /* GLUT_CURSOR_SPRAY */ { XC_watch, None, 0 }, /* GLUT_CURSOR_WAIT */ { XC_xterm, None, 0 }, /* GLUT_CURSOR_TEXT */ { XC_crosshair, None, 0 }, /* GLUT_CURSOR_CROSSHAIR */ { XC_sb_v_double_arrow, None, 0 }, /* GLUT_CURSOR_UP_DOWN */ { XC_sb_h_double_arrow, None, 0 }, /* GLUT_CURSOR_LEFT_RIGHT */ { XC_top_side, None, 0 }, /* GLUT_CURSOR_TOP_SIDE */ { XC_bottom_side, None, 0 }, /* GLUT_CURSOR_BOTTOM_SIDE */ { XC_left_side, None, 0 }, /* GLUT_CURSOR_LEFT_SIDE */ { XC_right_side, None, 0 }, /* GLUT_CURSOR_RIGHT_SIDE */ { XC_top_left_corner, None, 0 }, /* GLUT_CURSOR_TOP_LEFT_CORNER */ { XC_top_right_corner, None, 0 }, /* GLUT_CURSOR_TOP_RIGHT_CORNER */ { XC_bottom_right_corner, None, 0 }, /* GLUT_CURSOR_BOTTOM_RIGHT_CORNER */ { XC_bottom_left_corner, None, 0 } /* GLUT_CURSOR_BOTTOM_LEFT_CORNER */ }; void fgPlatformSetCursor ( SFG_Window *window, int cursorID ) { Cursor cursor; /* * XXX FULL_CROSSHAIR demotes to plain CROSSHAIR. Old GLUT allows * for this, but if there is a system that easily supports a full- * window (or full-screen) crosshair, we might consider it. */ int cursorIDToUse = ( cursorID == GLUT_CURSOR_FULL_CROSSHAIR ) ? GLUT_CURSOR_CROSSHAIR : cursorID; if( ( cursorIDToUse >= 0 ) && ( cursorIDToUse < sizeof( cursorCache ) / sizeof( cursorCache[0] ) ) ) { cursorCacheEntry *entry = &cursorCache[ cursorIDToUse ]; /* 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 = XCreateFontCursor( fgDisplay.pDisplay.Display, entry->cursorShape ); entry->dpy = fgDisplay.pDisplay.Display; } cursor = entry->cachedCursor; } else { switch( cursorIDToUse ) { case GLUT_CURSOR_NONE: cursor = getEmptyCursor( ); break; case GLUT_CURSOR_INHERIT: cursor = None; break; default: fgError( "Unknown cursor type: %d", cursorIDToUse ); return; } } if ( cursorIDToUse == GLUT_CURSOR_INHERIT ) { XUndefineCursor( fgDisplay.pDisplay.Display, window->Window.Handle ); } else if ( cursor != None ) { XDefineCursor( fgDisplay.pDisplay.Display, window->Window.Handle, cursor ); } else if ( cursorIDToUse != GLUT_CURSOR_NONE ) { fgError( "Failed to create cursor" ); } } void fgPlatformWarpPointer ( int x, int y ) { XWarpPointer( fgDisplay.pDisplay.Display, None, fgStructure.CurrentWindow->Window.Handle, 0, 0, 0, 0, x, y ); /* Make the warp visible immediately. */ XFlush( fgDisplay.pDisplay.Display ); } void fghPlatformGetCursorPos(const SFG_Window *window, GLboolean client, SFG_XYUse *mouse_pos) { /* Get current pointer location in screen coordinates (if client is false or window is NULL), else * Get current pointer location relative to top-left of client area of window (if client is true and window is not NULL) */ Window w = (client && window && window->Window.Handle)? window->Window.Handle: fgDisplay.pDisplay.RootWindow; Window junk_window; unsigned int junk_mask; int clientX, clientY; XQueryPointer(fgDisplay.pDisplay.Display, w, &junk_window, &junk_window, &mouse_pos->X, &mouse_pos->Y, /* Screen coords relative to root window's top-left */ &clientX, &clientY, /* Client coords relative to window's top-left */ &junk_mask); if (client && window && window->Window.Handle) { mouse_pos->X = clientX; mouse_pos->Y = clientY; } mouse_pos->Use = GL_TRUE; }
