src/spacenav-lib-hack.c
branchv_0
changeset 5 26e9fb705faf
parent 4 650e0a578dab
child 8 1dab2b99f51d
equal deleted inserted replaced
4:650e0a578dab 5:26e9fb705faf
    20 #include <stdio.h>
    20 #include <stdio.h>
    21 #include <stdint.h>
    21 #include <stdint.h>
    22 #include <dlfcn.h>
    22 #include <dlfcn.h>
    23 #include <stdlib.h>
    23 #include <stdlib.h>
    24 #include <unistd.h>
    24 #include <unistd.h>
       
    25 #include <pthread.h>
    25 
    26 
    26 #include <X11/Xlib.h>
    27 #include <X11/Xlib.h>
    27 #include <spnav.h>
    28 #include <spnav.h>
    28 
    29 
    29 /**
    30 /**
    39  *    and translates spacenav events to X11 events and sends them to the application window.
    40  *    and translates spacenav events to X11 events and sends them to the application window.
    40  * 3) reimplements spnav_x11_event() which is needed, because Atom variables in original library
    41  * 3) reimplements spnav_x11_event() which is needed, because Atom variables in original library
    41  *    were not initialized spnav_x11_open() and thus the library funcion is not working.
    42  *    were not initialized spnav_x11_open() and thus the library funcion is not working.
    42  * 
    43  * 
    43  * This solution works and allows using e.g. FreeCAD with domain socket instead of X11, but:
    44  * This solution works and allows using e.g. FreeCAD with domain socket instead of X11, but:
    44  *	- the background process never ends and must be terminated by: killall freecad
       
    45  *  - is very hackish and should be reimplemented as a separate process which will work partly
    45  *  - is very hackish and should be reimplemented as a separate process which will work partly
    46  *    as a libspnav client and partly emulate spacenavd daemon and will bridge the domain socket
    46  *    as a libspnav client and partly emulate spacenavd daemon and will bridge the domain socket
    47  *    and th X11. Other solution is to emulate the hardware and keep spacenavd and libspnav untouched.
    47  *    and th X11. Other solution is to emulate the hardware and keep spacenavd and libspnav untouched.
    48  */
    48  */
       
    49 
       
    50 static pthread_t spacenav_hack_thread;
       
    51 static Window spacenav_hack_win;
    49 
    52 
    50 // from proto_x11.c (spacenavd)
    53 // from proto_x11.c (spacenavd)
    51 static Atom xa_event_motion, xa_event_bpress, xa_event_brelease, xa_event_cmd;
    54 static Atom xa_event_motion, xa_event_bpress, xa_event_brelease, xa_event_cmd;
    52 static float x11_sens = 1.0;
    55 static float x11_sens = 1.0;
    53 
    56 
    98 
   101 
    99 	XSendEvent(dpy, win, False, 0, &xevent);
   102 	XSendEvent(dpy, win, False, 0, &xevent);
   100 	XFlush(dpy);
   103 	XFlush(dpy);
   101 }
   104 }
   102 
   105 
   103 static void spacenav_hack_translate_events(Window win) {
   106 static void* spacenav_hack_translate_events(void* arg) {
       
   107 	fprintf(stderr, "spnav-lib-hack: pthread running, PID=%d\n", getpid());
   104 	spnav_event event;
   108 	spnav_event event;
   105 	Display* dpy = XOpenDisplay(0);
   109 	Display* dpy = XOpenDisplay(0);
   106 
   110 
   107 	while (1) {
   111 	while (1) {
   108 		if (spnav_wait_event(&event)) {
   112 		if (spnav_wait_event(&event)) {
   109 			send_xevent(&event, dpy, win);
   113 			send_xevent(&event, dpy, spacenav_hack_win);
   110 		}
   114 		}
   111 	}
   115 	}
   112 	// FIXME: this process never ends and must be killed manually
       
   113 }
   116 }
   114 
   117 
   115 int spnav_x11_open(Display* dpy, Window win) {
   118 int spnav_x11_open(Display* dpy, Window win) {
   116 	int result = spnav_open();
   119 	int result = spnav_open();
   117 	fprintf(stderr, "spnav-lib-hack: instead of spnav_x11_open(%p, 0x%lx) calling spnav_open() = %d\n", dpy, win, result);
   120 	fprintf(stderr, "spnav-lib-hack: instead of spnav_x11_open(%p, 0x%lx) calling spnav_open() = %d\n", dpy, win, result);
   120 	xa_event_bpress = XInternAtom(dpy, "ButtonPressEvent", False);
   123 	xa_event_bpress = XInternAtom(dpy, "ButtonPressEvent", False);
   121 	xa_event_brelease = XInternAtom(dpy, "ButtonReleaseEvent", False);
   124 	xa_event_brelease = XInternAtom(dpy, "ButtonReleaseEvent", False);
   122 	xa_event_cmd = XInternAtom(dpy, "CommandEvent", False);
   125 	xa_event_cmd = XInternAtom(dpy, "CommandEvent", False);
   123 
   126 
   124 	if (result == 0) {
   127 	if (result == 0) {
   125 		pid_t pid = fork();
   128 		spacenav_hack_win = win;
   126 		fprintf(stderr, "spnav-lib-hack: fork() = %d; PID=%d\n", pid, getpid());
   129 		pthread_create(&spacenav_hack_thread, NULL, spacenav_hack_translate_events, NULL);
   127 		if (pid == -1) return 1; // error
       
   128 		if (pid == 0) spacenav_hack_translate_events(win); // child
       
   129 		else; // parent
       
   130 	}
   130 	}
   131 
   131 
   132 	return result;
   132 	return result;
   133 }
   133 }
   134 
   134