Mercurial > hgrepos > Python2 > PyMuPDF
diff mupdf-source/thirdparty/freeglut/src/x11/fg_cursor_x11.c @ 2:b50eed0cc0ef upstream
ADD: MuPDF v1.26.7: the MuPDF source as downloaded by a default build of PyMuPDF 1.26.4.
The directory name has changed: no version number in the expanded directory now.
| author | Franz Glasner <fzglas.hg@dom66.de> |
|---|---|
| date | Mon, 15 Sep 2025 11:43:07 +0200 |
| parents | |
| children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mupdf-source/thirdparty/freeglut/src/x11/fg_cursor_x11.c Mon Sep 15 11:43:07 2025 +0200 @@ -0,0 +1,184 @@ +/* + * 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; +}
