X-Git-Url: http://git.mutantstargoat.com/user/nuclear/?a=blobdiff_plain;f=src%2Ffreeglut_spaceball.c;h=7c9d0731066c8877dcdada259cbd16b64a3cf908;hb=42c82aef321e500f4f51115ba3244beabefbc3dc;hp=7816f66e5dc9603fc7b7d731a69415947344e495;hpb=ee81383a1573bc3c4a149919126582ab133c1bc1;p=freeglut diff --git a/src/freeglut_spaceball.c b/src/freeglut_spaceball.c index 7816f66..7c9d073 100644 --- a/src/freeglut_spaceball.c +++ b/src/freeglut_spaceball.c @@ -10,13 +10,15 @@ #include #include "freeglut_internal.h" +/* -- PRIVATE FUNCTIONS --------------------------------------------------- */ + #if TARGET_HOST_POSIX_X11 #include enum { - SPNAV_EVENT_ANY, /* used by spnav_remove_events() */ + SPNAV_EVENT_ANY, /* used by spnav_remove_events() */ SPNAV_EVENT_MOTION, - SPNAV_EVENT_BUTTON /* includes both press and release */ + SPNAV_EVENT_BUTTON /* includes both press and release */ }; struct spnav_event_motion { @@ -62,7 +64,7 @@ void fgInitialiseSpaceball(void) #if TARGET_HOST_POSIX_X11 { Window w; - + if(!fgStructure.CurrentWindow) return; @@ -114,7 +116,7 @@ int fgSpaceballNumButtons(void) } #if TARGET_HOST_POSIX_X11 - return 2; /* TODO implement this properly */ + return 2; /* TODO implement this properly */ #else return 0; #endif @@ -143,11 +145,13 @@ int fgIsSpaceballXEvent(const XEvent *xev) { spnav_event sev; + if(spnav_win != fgStructure.CurrentWindow) { + /* this will also initialize spaceball if needed (first call) */ + fgSpaceballSetWindow(fgStructure.CurrentWindow); + } + if(!sball_initialized) { - fgInitialiseSpaceball(); - if(!sball_initialized) { - return 0; - } + return 0; } return spnav_x11_event(xev, &sev); @@ -171,7 +175,7 @@ void fgSpaceballHandleXEvent(const XEvent *xev) INVOKE_WCB(*spnav_win, SpaceMotion, (sev.motion.x, sev.motion.y, sev.motion.z)); } if(sev.motion.rx | sev.motion.ry | sev.motion.rz) { - INVOKE_WCB(*spnav_win, SpaceRotation, (sev.motion.rx, sev.motion.ry, sev.motion.rz)); + INVOKE_WCB(*spnav_win, SpaceRotation, (sev.motion.rx, sev.motion.ry, sev.motion.rz)); } spnav_remove_events(SPNAV_EVENT_MOTION); break; @@ -215,7 +219,10 @@ OF SUCH DAMAGE. #include #include #include + +#ifdef HAVE_ERRNO_H #include +#endif #include #include @@ -228,227 +235,227 @@ static Window app_win; static Atom motion_event, button_press_event, button_release_event, command_event; enum { - CMD_APP_WINDOW = 27695, - CMD_APP_SENS + CMD_APP_WINDOW = 27695, + CMD_APP_SENS }; -#define IS_OPEN dpy +#define IS_OPEN dpy struct event_node { - spnav_event event; - struct event_node *next; + spnav_event event; + struct event_node *next; }; static int spnav_x11_open(Display *display, Window win) { - if(IS_OPEN) { - return -1; - } + if(IS_OPEN) { + return -1; + } - dpy = display; + dpy = display; - motion_event = XInternAtom(dpy, "MotionEvent", True); - button_press_event = XInternAtom(dpy, "ButtonPressEvent", True); - button_release_event = XInternAtom(dpy, "ButtonReleaseEvent", True); - command_event = XInternAtom(dpy, "CommandEvent", True); + motion_event = XInternAtom(dpy, "MotionEvent", True); + button_press_event = XInternAtom(dpy, "ButtonPressEvent", True); + button_release_event = XInternAtom(dpy, "ButtonReleaseEvent", True); + command_event = XInternAtom(dpy, "CommandEvent", True); - if(!motion_event || !button_press_event || !button_release_event || !command_event) { - dpy = 0; - return -1; /* daemon not started */ - } + if(!motion_event || !button_press_event || !button_release_event || !command_event) { + dpy = 0; + return -1; /* daemon not started */ + } - if(spnav_x11_window(win) == -1) { - dpy = 0; - return -1; /* daemon not started */ - } + if(spnav_x11_window(win) == -1) { + dpy = 0; + return -1; /* daemon not started */ + } - app_win = win; - return 0; + app_win = win; + return 0; } static int spnav_close(void) { - if(dpy) { - spnav_x11_window(DefaultRootWindow(dpy)); - app_win = 0; - dpy = 0; - return 0; - } - return -1; + if(dpy) { + spnav_x11_window(DefaultRootWindow(dpy)); + app_win = 0; + dpy = 0; + return 0; + } + return -1; } static int spnav_x11_window(Window win) { - int (*prev_xerr_handler)(Display*, XErrorEvent*); - XEvent xev; - Window daemon_win; - - if(!IS_OPEN) { - return -1; - } - - if(!(daemon_win = get_daemon_window(dpy))) { - return -1; - } - - prev_xerr_handler = XSetErrorHandler(catch_badwin); - - xev.type = ClientMessage; - xev.xclient.send_event = False; - xev.xclient.display = dpy; - xev.xclient.window = win; - xev.xclient.message_type = command_event; - xev.xclient.format = 16; - xev.xclient.data.s[0] = ((unsigned int)win & 0xffff0000) >> 16; - xev.xclient.data.s[1] = (unsigned int)win & 0xffff; - xev.xclient.data.s[2] = CMD_APP_WINDOW; - - XSendEvent(dpy, daemon_win, False, 0, &xev); - XSync(dpy, False); - - XSetErrorHandler(prev_xerr_handler); - return 0; + int (*prev_xerr_handler)(Display*, XErrorEvent*); + XEvent xev; + Window daemon_win; + + if(!IS_OPEN) { + return -1; + } + + if(!(daemon_win = get_daemon_window(dpy))) { + return -1; + } + + prev_xerr_handler = XSetErrorHandler(catch_badwin); + + xev.type = ClientMessage; + xev.xclient.send_event = False; + xev.xclient.display = dpy; + xev.xclient.window = win; + xev.xclient.message_type = command_event; + xev.xclient.format = 16; + xev.xclient.data.s[0] = ((unsigned int)win & 0xffff0000) >> 16; + xev.xclient.data.s[1] = (unsigned int)win & 0xffff; + xev.xclient.data.s[2] = CMD_APP_WINDOW; + + XSendEvent(dpy, daemon_win, False, 0, &xev); + XSync(dpy, False); + + XSetErrorHandler(prev_xerr_handler); + return 0; } static int spnav_fd(void) { - if(dpy) { - return ConnectionNumber(dpy); - } - return -1; + if(dpy) { + return ConnectionNumber(dpy); + } + return -1; } /*static int spnav_wait_event(spnav_event *event) { - if(dpy) { - for(;;) { - XEvent xev; - XNextEvent(dpy, &xev); - - if(spnav_x11_event(&xev, event) > 0) { - return event->type; - } - } - } - return 0; + if(dpy) { + for(;;) { + XEvent xev; + XNextEvent(dpy, &xev); + + if(spnav_x11_event(&xev, event) > 0) { + return event->type; + } + } + } + return 0; } static int spnav_poll_event(spnav_event *event) { - if(dpy) { - if(XPending(dpy)) { - XEvent xev; - XNextEvent(dpy, &xev); - - return spnav_x11_event(&xev, event); - } - } - return 0; + if(dpy) { + if(XPending(dpy)) { + XEvent xev; + XNextEvent(dpy, &xev); + + return spnav_x11_event(&xev, event); + } + } + return 0; }*/ static Bool match_events(Display *dpy, XEvent *xev, char *arg) { - int evtype = *(int*)arg; - - if(xev->type != ClientMessage) { - return False; - } - - if(xev->xclient.message_type == motion_event) { - return !evtype || evtype == SPNAV_EVENT_MOTION ? True : False; - } - if(xev->xclient.message_type == button_press_event || - xev->xclient.message_type == button_release_event) { - return !evtype || evtype == SPNAV_EVENT_BUTTON ? True : False; - } - return False; + int evtype = *(int*)arg; + + if(xev->type != ClientMessage) { + return False; + } + + if(xev->xclient.message_type == motion_event) { + return !evtype || evtype == SPNAV_EVENT_MOTION ? True : False; + } + if(xev->xclient.message_type == button_press_event || + xev->xclient.message_type == button_release_event) { + return !evtype || evtype == SPNAV_EVENT_BUTTON ? True : False; + } + return False; } static int spnav_remove_events(int type) { - int rm_count = 0; + int rm_count = 0; - if(dpy) { - XEvent xev; + if(dpy) { + XEvent xev; - while(XCheckIfEvent(dpy, &xev, match_events, (char*)&type)) { - rm_count++; - } - return rm_count; - } - return 0; + while(XCheckIfEvent(dpy, &xev, match_events, (char*)&type)) { + rm_count++; + } + return rm_count; + } + return 0; } static int spnav_x11_event(const XEvent *xev, spnav_event *event) { - int i; - int xmsg_type; - - if(xev->type != ClientMessage) { - return 0; - } - - xmsg_type = xev->xclient.message_type; - - if(xmsg_type != motion_event && xmsg_type != button_press_event && - xmsg_type != button_release_event) { - return 0; - } - - if(xmsg_type == motion_event) { - event->type = SPNAV_EVENT_MOTION; - event->motion.data = &event->motion.x; - - for(i=0; i<6; i++) { - event->motion.data[i] = xev->xclient.data.s[i + 2]; - } - event->motion.period = xev->xclient.data.s[8]; - } else { - event->type = SPNAV_EVENT_BUTTON; - event->button.press = xmsg_type == button_press_event ? 1 : 0; - event->button.bnum = xev->xclient.data.s[2]; - } - return event->type; + int i; + int xmsg_type; + + if(xev->type != ClientMessage) { + return 0; + } + + xmsg_type = xev->xclient.message_type; + + if(xmsg_type != motion_event && xmsg_type != button_press_event && + xmsg_type != button_release_event) { + return 0; + } + + if(xmsg_type == motion_event) { + event->type = SPNAV_EVENT_MOTION; + event->motion.data = &event->motion.x; + + for(i=0; i<6; i++) { + event->motion.data[i] = xev->xclient.data.s[i + 2]; + } + event->motion.period = xev->xclient.data.s[8]; + } else { + event->type = SPNAV_EVENT_BUTTON; + event->button.press = xmsg_type == button_press_event ? 1 : 0; + event->button.bnum = xev->xclient.data.s[2]; + } + return event->type; } static Window get_daemon_window(Display *dpy) { - Window win, root_win; - XTextProperty wname; - Atom type; - int fmt; - unsigned long nitems, bytes_after; - unsigned char *prop; + Window win, root_win; + XTextProperty wname; + Atom type; + int fmt; + unsigned long nitems, bytes_after; + unsigned char *prop; - root_win = DefaultRootWindow(dpy); + root_win = DefaultRootWindow(dpy); - XGetWindowProperty(dpy, root_win, command_event, 0, 1, False, AnyPropertyType, &type, &fmt, &nitems, &bytes_after, &prop); - if(!prop) { - return 0; - } + XGetWindowProperty(dpy, root_win, command_event, 0, 1, False, AnyPropertyType, &type, &fmt, &nitems, &bytes_after, &prop); + if(!prop) { + return 0; + } - win = *(Window*)prop; - XFree(prop); + win = *(Window*)prop; + XFree(prop); - if(!XGetWMName(dpy, win, &wname) || strcmp("Magellan Window", (char*)wname.value) != 0) { - return 0; - } + if(!XGetWMName(dpy, win, &wname) || strcmp("Magellan Window", (char*)wname.value) != 0) { + return 0; + } - return win; + return win; } static int catch_badwin(Display *dpy, XErrorEvent *err) { - char buf[256]; - - if(err->error_code == BadWindow) { - /* do nothing? */ - } else { - XGetErrorText(dpy, err->error_code, buf, sizeof buf); - fprintf(stderr, "Caught unexpected X error: %s\n", buf); - } - return 0; + char buf[256]; + + if(err->error_code == BadWindow) { + /* do nothing? */ + } else { + XGetErrorText(dpy, err->error_code, buf, sizeof buf); + fprintf(stderr, "Caught unexpected X error: %s\n", buf); + } + return 0; } -#endif /* TARGET_HOST_POSIX_X11 */ +#endif /* TARGET_HOST_POSIX_X11 */