📄 gxid.c
字号:
device = devices[i]; break; } } if (!device) { fprintf(stderr,"%s: Unknown device id %ld\n",program_name,devid); return GXID_RETURN_ERROR; } for (i=0;i<num_windows;i++) { GxidWindow *w = windows[i]; if (w->xwindow == winid) for (j=0;j<w->num_devices;j++) if (w->devices[j]->id == devid) { if (j<w->num_devices-1) w->devices[j] = w->devices[w->num_devices-1]; w->num_devices--; if (w->num_devices == 0) { if (i<num_windows-1) windows[i] = windows[num_windows-1]; num_windows--; free((void *)w); /* FIXME: should we deselect input? But what what if window is already destroyed */ } if (device->exclusive) { device->exclusive = 0; enable_device(device); } return GXID_RETURN_OK; } } /* device/window combination not found */ fprintf(stderr, "%s: Device %ld not claimed for window 0x%lx\n", program_name,devid,winid); return GXID_RETURN_ERROR;}voidhandle_connection (void){ GxidMessage msg; GxidU32 type; GxidU32 length; GxidI32 retval; int conn_fd; struct sockaddr_in sin; int sin_length; int count; sin_length = sizeof(struct sockaddr_in); conn_fd = accept(socket_fd,(struct sockaddr *)&sin,&sin_length); if (conn_fd < 0) { fprintf(stderr,"%s: Error accepting connection\n", program_name); exit(1); } /* read type and length of message */ count = read(conn_fd,(char *)&msg,2*sizeof(GxidU32)); if (count != 2*sizeof(GxidU32)) { fprintf(stderr,"%s: Error reading message header\n", program_name); close(conn_fd); return; } type = ntohl(msg.any.type); length = ntohl(msg.any.length); /* read rest of message */ if ((length > sizeof(GxidMessage)) || (length < 2*sizeof(GxidU32))) { fprintf(stderr,"%s: Bad message length\n", program_name); close(conn_fd); return; } count = read(conn_fd,2*sizeof(GxidU32) + (char *)&msg, length - 2*sizeof(GxidU32)); if (count != length - 2*sizeof(GxidU32)) { fprintf(stderr,"%s: Error reading message body\n", program_name); close(conn_fd); return; } switch (type) { case GXID_CLAIM_DEVICE: retval = handle_claim_device((GxidClaimDevice *)&msg); break; case GXID_RELEASE_DEVICE: retval = handle_release_device((GxidReleaseDevice *)&msg); break; default: fprintf(stderr,"%s: Unknown message type: %ld (ignoring)\n", program_name,type); close(conn_fd); return; } count = write(conn_fd,&retval,sizeof(GxidI32)); if (count != sizeof(GxidI32)) { fprintf(stderr,"%s: Error writing return code\n", program_name); } close(conn_fd);}voidhandle_motion_notify(XDeviceMotionEvent *event){ int i,j; GxidDevice *old_device = NULL; GxidDevice *new_device = NULL; Window w, root, child; int root_x, root_y, x, y, mask; for (j=0;j<num_devices;j++) { if (devices[j]->ispointer) old_device = devices[j]; if (devices[j]->id == event->deviceid) new_device = devices[j]; } if (new_device && !new_device->exclusive && !new_device->ispointer) { /* make sure we aren't stealing the pointer back from a slow client */ child = root_window; do { w = child; /* FIXME: this fails disasterously if child vanishes between calls. (Which is prone to happening since we get events on root just as the client exits) */ XQueryPointer(dpy,w,&root,&child,&root_x,&root_y, &x,&y,&mask); } while (child != None); for (i=0;i<num_windows;i++) if (windows[i]->xwindow == w) for (j=0;j<windows[i]->num_devices;j++) if (windows[i]->devices[j] == new_device) return; /* FIXME: do something smarter with axes */ XChangePointerDevice(dpy,new_device->xdevice, 0, 1); new_device->ispointer = 1; old_device->ispointer = 0; if (!old_device->xdevice) enable_device(old_device); }}voidhandle_change_notify(XChangeDeviceNotifyEvent *event){ int j; GxidDevice *old_device = NULL; GxidDevice *new_device = NULL; for (j=0;j<num_devices;j++) { if (devices[j]->ispointer) old_device = devices[j]; if (devices[j]->id == event->deviceid) new_device = devices[j]; }#ifdef DEBUG_EVENTS fprintf(stderr,"gxid: ChangeNotify event; old = %ld; new = %ld\n", old_device->id, new_device->id);#endif if (old_device != new_device) { new_device->ispointer = 1; old_device->ispointer = 0; if (!old_device->xdevice) enable_device(old_device); }}voidhandle_enter_notify(XEnterWindowEvent *event, GxidWindow *window){ int i; GxidDevice *old_pointer = NULL; for (i=0;i<num_devices;i++) { if (devices[i]->ispointer) { old_pointer = devices[i]; break; } }#ifdef DEBUG_EVENTS fprintf(stderr,"gxid: Enter event; oldpointer = %ld\n", old_pointer->id);#endif if (old_pointer) for (i=0;i<window->num_devices;i++) { if (window->devices[i] == old_pointer) { switch_core_pointer(); break; } }}voidhandle_destroy_notify(XDestroyWindowEvent *event){ int i,j; for (i=0;i<num_windows;i++) if (windows[i]->xwindow == event->window) { GxidWindow *w = windows[i]; for (j=0;j<w->num_devices;j++) {#ifdef DEBUG_CLIENTS fprintf(stderr,"device %ld released on destruction of window 0x%lx.\n", w->devices[j]->id,w->xwindow);#endif if (w->devices[j]->exclusive) { w->devices[j]->exclusive = 0; enable_device(devices[j]); } } if (i<num_windows-1) windows[i] = windows[num_windows-1]; num_windows--; if (w->devices) free((void *)w->devices); free((void *)w); /* FIXME: should we deselect input? But what what if window is already destroyed */ return; }}voidhandle_xevent(void){ int i; XEvent event; XNextEvent (dpy, &event);#ifdef DEBUG_EVENTS fprintf(stderr,"Event - type = %d; window = 0x%lx\n", event.type,event.xany.window);#endif if (event.type == ConfigureNotify) {#ifdef DEBUG_EVENTS XConfigureEvent *xce = (XConfigureEvent *)&event; fprintf(stderr," configureNotify: window = 0x%lx\n",xce->window);#endif } else if (event.type == EnterNotify) { /* pointer entered a claimed window */ for (i=0;i<num_windows;i++) { if (event.xany.window == windows[i]->xwindow) handle_enter_notify((XEnterWindowEvent *)&event,windows[i]); } } else if (event.type == DestroyNotify) { /* A claimed window was destroyed */ for (i=0;i<num_windows;i++) { if (event.xany.window == windows[i]->xwindow) handle_destroy_notify((XDestroyWindowEvent *)&event); } } else for (i=0;i<num_devices;i++) { if (event.type == devices[i]->motionnotify_type) { handle_motion_notify((XDeviceMotionEvent *)&event); break; } else if (event.type == devices[i]->changenotify_type) { handle_change_notify((XChangeDeviceNotifyEvent *)&event); break; } }}void usage(void){ fprintf(stderr,"Usage: %s [-d display] [-p --gxid-port port]\n", program_name); exit(1);}intmain(int argc, char **argv){ int i; char *display_name = NULL; fd_set readfds; program_name = argv[0]; for (i=1;i<argc;i++) { if (!strcmp(argv[i],"-d")) { if (++i >= argc) usage(); display_name = argv[i]; } else if (!strcmp(argv[i],"--gxid-port") || !strcmp(argv[i],"-p")) { if (++i >= argc) usage(); port = atoi(argv[i]); break; } else usage(); } if (!port) { char *t = getenv("GXID_PORT"); if (t) port = atoi(t); else port = 6951; } /* set up a signal handler so we can clean up if killed */ signal(SIGTERM,handler); signal(SIGINT,handler); /* initialize the X connection */ dpy = XOpenDisplay (display_name); if (!dpy) { fprintf (stderr, "%s: unable to open display '%s'\n", program_name, XDisplayName (display_name)); exit (1); } root_window = DefaultRootWindow(dpy); /* We'll want to do this in the future if we are to support gxid monitoring visibility information for clients */#if 0 XSelectInput(dpy,root_window,SubstructureNotifyMask);#endif init_xinput(); /* set up our server connection */ init_socket(); /* main loop */ if (XPending(dpy)) /* this seems necessary to get things in sync */ handle_xevent(); while (1) { FD_ZERO(&readfds); FD_SET(ConnectionNumber(dpy),&readfds); FD_SET(socket_fd,&readfds); if (select(8*sizeof(readfds),&readfds, (fd_set *)0,(fd_set *)0, (struct timeval *)0) < 0) { fprintf(stderr,"Error in select\n"); exit(1); } if (FD_ISSET(socket_fd,&readfds)) handle_connection(); while (XPending(dpy)) handle_xevent(); } XCloseDisplay (dpy); exit (0);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -