# HG changeset patch # User František Kučera # Date 1552081138 -3600 # Node ID 3ba27504be0eb01c4fdf19cde33caf93e15353b8 # Parent ac5f3768ebb13d292241928082a3de6e1b3f1eae very hackish and… working diff -r ac5f3768ebb1 -r 3ba27504be0e nbproject/project.xml --- a/nbproject/project.xml Fri Mar 08 20:11:23 2019 +0100 +++ b/nbproject/project.xml Fri Mar 08 22:38:58 2019 +0100 @@ -44,7 +44,7 @@ spacenav-lib-hack c - cpp + cpp,cxx h UTF-8 diff -r ac5f3768ebb1 -r 3ba27504be0e src/spacenav-lib-hack.c --- a/src/spacenav-lib-hack.c Fri Mar 08 20:11:23 2019 +0100 +++ b/src/spacenav-lib-hack.c Fri Mar 08 22:38:58 2019 +0100 @@ -21,20 +21,37 @@ #include #include #include -#include +#include #include #include -static Display* spacenav_hack_dpy; -static Window spacenav_hack_win; - -static pthread_t spacenav_hack_thread; - // from proto_x11.c (spacenavd) static Atom xa_event_motion, xa_event_bpress, xa_event_brelease, xa_event_cmd; static float x11_sens = 1.0; +/* X11 error handler */ +static int xerr(Display *dpy, XErrorEvent *err) { + char buf[512]; + + fprintf(stderr, "xerr(%p, %p)\n", (void*) dpy, (void*) err); + if (err->error_code == BadWindow) { + fprintf(stderr, "BadWindow\n"); + } else { + XGetErrorText(dpy, err->error_code, buf, sizeof buf); + fprintf(stderr, "Caught unexpected X error: %s\n", buf); + } + return 0; +} + +/* X11 I/O error handler + * This function must not return or xlib will abort. + */ +static int xioerr(Display *display) { + fprintf(stderr, "Lost the X server!\n"); + return 0; +} + /** * This function is based on proto_x11.c (spacenavd) written by: * Copyright (C) 2007-2019 John Tsiombikas @@ -80,55 +97,115 @@ break; } - XSendEvent(dpy, win, False, 0, &xevent); - XFlush(dpy); + Window xxx; + int zzz; + int yyy = XGetInputFocus(dpy, &xxx, &zzz); + fprintf(stderr, "spnav-lib-hack: XGetInputFocus(%p, %lx, %d) = %d\n", dpy, xxx, zzz, yyy); + Status result = XSendEvent(dpy, win, False, 0, &xevent); + int xflushResult = XFlush(dpy); + fprintf(stderr, "spnav-lib-hack: send_xevent(); XSendEvent() = %d; XFlush() = %d\n", result, xflushResult); } -static void* spacenav_hack_translate_events(void* arg) { - pthread_setname_np(pthread_self(), "spacenav-hack"); // can be found with: ps H -o 'pid tid cmd comm' +static void spacenav_hack_translate_events(Window win) { spnav_event event; + Display* dpy = XOpenDisplay(0); + XSetErrorHandler(xerr); + XSetIOErrorHandler(xioerr); + fprintf(stderr, "Error handlers were set\n"); + + /* + xa_event_motion = XInternAtom(dpy, "MotionEvent", False); + xa_event_bpress = XInternAtom(dpy, "ButtonPressEvent", False); + xa_event_brelease = XInternAtom(dpy, "ButtonReleaseEvent", False); + xa_event_cmd = XInternAtom(dpy, "CommandEvent", False); + */ + + fprintf(stderr, "spnav-lib-hack: xa_event_motion = %ld\n", xa_event_motion); + fprintf(stderr, "spnav-lib-hack: xa_event_bpress = %ld\n", xa_event_bpress); + fprintf(stderr, "spnav-lib-hack: xa_event_brelease = %ld\n", xa_event_brelease); + fprintf(stderr, "spnav-lib-hack: xa_event_cmd = %ld\n", xa_event_cmd); + while (1) { if (spnav_wait_event(&event)) { - //fprintf(stderr, "spnav-lib-hack: got event\n"); - XLockDisplay(spacenav_hack_dpy); - send_xevent(&event, spacenav_hack_dpy, spacenav_hack_win); - XUnlockDisplay(spacenav_hack_dpy); + fprintf(stderr, "spnav-lib-hack: got event: PID=%d dpy=%p win=%lx\n", getpid(), dpy, win); + //XLockDisplay(dpy); + send_xevent(&event, dpy, win); + //XUnlockDisplay(dpy); } } } int spnav_x11_open(Display* dpy, Window win) { - spacenav_hack_dpy = dpy; - spacenav_hack_win = win; - int result = spnav_open(); fprintf(stderr, "spnav-lib-hack: instead of spnav_x11_open(%p, 0x%lx) calling spnav_open() = %d\n", dpy, win, result); + xa_event_motion = XInternAtom(dpy, "MotionEvent", False); + xa_event_bpress = XInternAtom(dpy, "ButtonPressEvent", False); + xa_event_brelease = XInternAtom(dpy, "ButtonReleaseEvent", False); + xa_event_cmd = XInternAtom(dpy, "CommandEvent", False); + if (result == 0) { - xa_event_motion = XInternAtom(dpy, "MotionEvent", False); - xa_event_bpress = XInternAtom(dpy, "ButtonPressEvent", False); - xa_event_brelease = XInternAtom(dpy, "ButtonReleaseEvent", False); - xa_event_cmd = XInternAtom(dpy, "CommandEvent", False); - - XInitThreads(); - pthread_create(&spacenav_hack_thread, NULL, spacenav_hack_translate_events, NULL); + pid_t pid = fork(); + fprintf(stderr, "spnav-lib-hack: fork() = %d; PID=%d\n", pid, getpid()); + if (pid == -1) return 1; + if (pid == 0) spacenav_hack_translate_events(win); } return result; } +/** + * This function is based on proto_x11.c (spacenavd) written by: + * Copyright (C) 2007-2019 John Tsiombikas + * and published under GNU GPLv3+ + * + * @param dpy + * @param win + * @return + */ +int spnav_x11_event(const XEvent* xev, spnav_event* event) { + /* + * Because real spnav_x11_open() was not called, the library has not initialized xa_event_* + * variables and thus will return 0 (= not a spacenav event). + */ + int i; + int xmsg_type; + + if (xev->type != ClientMessage) { + return 0; + } -/* -int spnav_x11_event(const XEvent* xev, spnav_event* event) { - xev. + xmsg_type = xev->xclient.message_type; + + if (xmsg_type != xa_event_motion && xmsg_type != xa_event_bpress && + xmsg_type != xa_event_brelease) { + return 0; + } + + if (xmsg_type == xa_event_motion) { + 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 == xa_event_bpress ? 1 : 0; + event->button.bnum = xev->xclient.data.s[2]; + } + return event->type; + + /* static int (*real_spnav_x11_event)(const XEvent*, spnav_event*) = NULL; if (!real_spnav_x11_event) real_spnav_x11_event = dlsym(RTLD_NEXT, "spnav_x11_event"); int result = real_spnav_x11_event(xev, event); if (result == SPNAV_EVENT_MOTION || result == SPNAV_EVENT_BUTTON) fprintf(stderr, "spnav-lib-hack: spnav_x11_event() = %d\n", result); return result; + */ } - */ /*