summaryrefslogtreecommitdiffstats
path: root/src/glut/glx/glut_cursor.c
diff options
context:
space:
mode:
authorBrian Paul <[email protected]>1999-08-19 13:57:42 +0000
committerBrian Paul <[email protected]>1999-08-19 13:57:42 +0000
commita4dcdcf0ffae4c6cf52354fbd63c95d7d7815fd9 (patch)
treef4c57aa74226a59913cb650b87f7083eee5e34b6 /src/glut/glx/glut_cursor.c
parent2d550f6ff1afa3189874c99cfe4125362ee76797 (diff)
initial check-in (post crash)
Diffstat (limited to 'src/glut/glx/glut_cursor.c')
-rw-r--r--src/glut/glx/glut_cursor.c201
1 files changed, 201 insertions, 0 deletions
diff --git a/src/glut/glx/glut_cursor.c b/src/glut/glx/glut_cursor.c
new file mode 100644
index 00000000000..74ecb9cd667
--- /dev/null
+++ b/src/glut/glx/glut_cursor.c
@@ -0,0 +1,201 @@
+
+/* Copyright (c) Mark J. Kilgard, 1995, 1998. */
+
+/* This program is freely distributable without licensing fees
+ and is provided without guarantee or warrantee expressed or
+ implied. This program is -not- in the public domain. */
+
+#include "glutint.h"
+
+#if !defined(_WIN32)
+#include <X11/Xatom.h> /* For XA_CURSOR */
+#include <X11/cursorfont.h>
+#endif
+
+typedef struct _CursorTable {
+#if defined(_WIN32)
+ char* glyph;
+#else
+ int glyph;
+#endif
+ Cursor cursor;
+} CursorTable;
+/* *INDENT-OFF* */
+
+static CursorTable cursorTable[] = {
+ {XC_arrow, None}, /* GLUT_CURSOR_RIGHT_ARROW */
+ {XC_top_left_arrow, None}, /* GLUT_CURSOR_LEFT_ARROW */
+ {XC_hand1, None}, /* GLUT_CURSOR_INFO */
+ {XC_pirate, None}, /* GLUT_CURSOR_DESTROY */
+ {XC_question_arrow, None}, /* GLUT_CURSOR_HELP */
+ {XC_exchange, None}, /* GLUT_CURSOR_CYCLE */
+ {XC_spraycan, None}, /* GLUT_CURSOR_SPRAY */
+ {XC_watch, None}, /* GLUT_CURSOR_WAIT */
+ {XC_xterm, None}, /* GLUT_CURSOR_TEXT */
+ {XC_crosshair, None}, /* GLUT_CURSOR_CROSSHAIR */
+ {XC_sb_v_double_arrow, None}, /* GLUT_CURSOR_UP_DOWN */
+ {XC_sb_h_double_arrow, None}, /* GLUT_CURSOR_LEFT_RIGHT */
+ {XC_top_side, None}, /* GLUT_CURSOR_TOP_SIDE */
+ {XC_bottom_side, None}, /* GLUT_CURSOR_BOTTOM_SIDE */
+ {XC_left_side, None}, /* GLUT_CURSOR_LEFT_SIDE */
+ {XC_right_side, None}, /* GLUT_CURSOR_RIGHT_SIDE */
+ {XC_top_left_corner, None}, /* GLUT_CURSOR_TOP_LEFT_CORNER */
+ {XC_top_right_corner, None}, /* GLUT_CURSOR_TOP_RIGHT_CORNER */
+ {XC_bottom_right_corner, None}, /* GLUT_CURSOR_BOTTOM_RIGHT_CORNER */
+ {XC_bottom_left_corner, None}, /* GLUT_CURSOR_BOTTOM_LEFT_CORNER */
+};
+/* *INDENT-ON* */
+
+#if !defined(_WIN32)
+static Cursor blankCursor = None;
+static Cursor fullCrosshairCusor = None;
+
+/* SGI X server's support a special property called the
+ _SGI_CROSSHAIR_CURSOR that when installed as a window's
+ cursor, becomes a full screen crosshair cursor. SGI
+ has special cursor generation hardware for this case. */
+static Cursor
+getFullCrosshairCursor(void)
+{
+ Cursor cursor;
+ Atom crosshairAtom, actualType;
+ int rc, actualFormat;
+ unsigned long n, left;
+ unsigned long *value;
+
+ if (fullCrosshairCusor == None) {
+ crosshairAtom = XInternAtom(__glutDisplay,
+ "_SGI_CROSSHAIR_CURSOR", True);
+ if (crosshairAtom != None) {
+ value = 0; /* Make compiler happy. */
+ rc = XGetWindowProperty(__glutDisplay, __glutRoot,
+ crosshairAtom, 0, 1, False, XA_CURSOR, &actualType,
+ &actualFormat, &n, &left, (unsigned char **) &value);
+ if (rc == Success && actualFormat == 32 && n >= 1) {
+ cursor = value[0];
+ XFree(value);
+ return cursor;
+ }
+ }
+ }
+ return XCreateFontCursor(__glutDisplay, XC_crosshair);
+}
+
+/* X11 forces you to create a blank cursor if you want
+ to disable the cursor. */
+static Cursor
+makeBlankCursor(void)
+{
+ static char data[1] =
+ {0};
+ Cursor cursor;
+ Pixmap blank;
+ XColor dummy;
+
+ blank = XCreateBitmapFromData(__glutDisplay, __glutRoot,
+ data, 1, 1);
+ if (blank == None)
+ __glutFatalError("out of memory.");
+ cursor = XCreatePixmapCursor(__glutDisplay, blank, blank,
+ &dummy, &dummy, 0, 0);
+ XFreePixmap(__glutDisplay, blank);
+
+ return cursor;
+}
+#endif /* !_WIN32 */
+
+/* Win32 and X11 use this same function to accomplish
+ fairly different tasks. X11 lets you just define the
+ cursor for a window and the window system takes care
+ of making sure that the window's cursor is installed
+ when the mouse is in the window. Win32 requires the
+ application to handle a WM_SETCURSOR message to install
+ the right cursor when windows are entered. Think of
+ the Win32 __glutSetCursor (called from __glutWindowProc)
+ as "install cursor". Think of the X11 __glutSetCursor
+ (called from glutSetCursor) as "define cursor". */
+void
+__glutSetCursor(GLUTwindow *window)
+{
+ int cursor = window->cursor;
+ Cursor xcursor;
+
+ if (cursor >= 0 &&
+ cursor < sizeof(cursorTable) / sizeof(cursorTable[0])) {
+ if (cursorTable[cursor].cursor == None) {
+ cursorTable[cursor].cursor = XCreateFontCursor(__glutDisplay,
+ cursorTable[cursor].glyph);
+ }
+ xcursor = cursorTable[cursor].cursor;
+ } else {
+ /* Special cases. */
+ switch (cursor) {
+ case GLUT_CURSOR_INHERIT:
+#if defined(_WIN32)
+ while (window->parent) {
+ window = window->parent;
+ if (window->cursor != GLUT_CURSOR_INHERIT) {
+ __glutSetCursor(window);
+ return;
+ }
+ }
+ /* XXX Default to an arrow cursor. Is this
+ right or should we be letting the default
+ window proc be installing some system cursor? */
+ xcursor = cursorTable[0].cursor;
+ if (xcursor == NULL) {
+ xcursor =
+ cursorTable[0].cursor =
+ LoadCursor(NULL, cursorTable[0].glyph);
+ }
+#else
+ xcursor = None;
+#endif
+ break;
+ case GLUT_CURSOR_NONE:
+#if defined(_WIN32)
+ xcursor = NULL;
+#else
+ if (blankCursor == None) {
+ blankCursor = makeBlankCursor();
+ }
+ xcursor = blankCursor;
+#endif
+ break;
+ case GLUT_CURSOR_FULL_CROSSHAIR:
+#if defined(_WIN32)
+ xcursor = IDC_CROSS;
+#else
+ if (fullCrosshairCusor == None) {
+ fullCrosshairCusor = getFullCrosshairCursor();
+ }
+ xcursor = fullCrosshairCusor;
+#endif
+ break;
+ }
+ }
+ XDefineCursor(__glutDisplay,
+ window->win, xcursor);
+ XFlush(__glutDisplay);
+}
+
+/* CENTRY */
+void APIENTRY
+glutSetCursor(int cursor)
+{
+#ifdef _WIN32
+ POINT point;
+
+ __glutCurrentWindow->cursor = cursor;
+ /* Are we in the window right now? If so,
+ install the cursor. */
+ GetCursorPos(&point);
+ if (__glutCurrentWindow->win == WindowFromPoint(point)) {
+ __glutSetCursor(__glutCurrentWindow);
+ }
+#else
+ __glutCurrentWindow->cursor = cursor;
+ __glutSetCursor(__glutCurrentWindow);
+#endif
+}
+/* ENDCENTRY */