/* * Attempt to read bytes from the mouse and interpret them. * Returns -1 on error, 0 if either no bytes were read or not enough * was read for a complete state, or 1 if the new state was read. * When a new state is read, the current buttons and x and y deltas * are returned. This routine does not block. */ static int X11_Read(MWCOORD *dx, MWCOORD *dy, MWCOORD *dz, int *bp) { static int noevent_count = 0; XEvent ev; int events = 0; long mask = /* x11_event_mask | */ #ifdef USE_EXPOSURE ButtonPressMask | ButtonReleaseMask | PointerMotionMask | ExposureMask; #else ButtonPressMask | ButtonReleaseMask | PointerMotionMask; #endif while (XCheckMaskEvent(x11_dpy, mask, &ev)) { if (ev.type == MotionNotify) { if (ev.xmotion.window == x11_win) { int button = 0; *dx = ev.xmotion.x; *dy = ev.xmotion.y; *dz = 0; if (ev.xmotion.state & Button1Mask) button |= MWBUTTON_L; if (ev.xmotion.state & Button2Mask) button |= MWBUTTON_M; if (ev.xmotion.state & Button3Mask) button |= MWBUTTON_R; *bp = button; events++; } } else if (ev.type == ButtonPress) { if (ev.xbutton.window == x11_win) { int button = 0; /* Get pressed button */ if(ev.xbutton.button == 1) button = MWBUTTON_L; else if(ev.xbutton.button == 2) button = MWBUTTON_M; else if(ev.xbutton.button == 3) button = MWBUTTON_R; /* Get any other buttons that might be already held */ if (ev.xbutton.state & Button1Mask) button |= MWBUTTON_L; if (ev.xbutton.state & Button2Mask) button |= MWBUTTON_M; if (ev.xbutton.state & Button3Mask) button |= MWBUTTON_R; /* printf("!Pressing button: 0x%x, state: 0x%x, button: 0x%x\n", button,ev.xbutton.state, ev.xbutton.button);*/ *bp = button; *dx = ev.xbutton.x; *dy = ev.xbutton.y; *dz = 0; events++; } } else if (ev.type == ButtonRelease) { if (ev.xbutton.window == x11_win) { int button = 0; int released = 0; /* Get released button */ if(ev.xbutton.button == 1) released = MWBUTTON_L; else if(ev.xbutton.button == 2) released = MWBUTTON_M; else if(ev.xbutton.button == 3) released = MWBUTTON_R; /* Get any other buttons that might be already held */ if (ev.xbutton.state & Button1Mask) button |= MWBUTTON_L; if (ev.xbutton.state & Button2Mask) button |= MWBUTTON_M; if (ev.xbutton.state & Button3Mask) button |= MWBUTTON_R; /* We need to remove the released button from the button mask*/ button &= ~released; /*printf("!Releasing button: 0x%x, state: 0x%x, button: 0x%x\n", button,ev.xbutton.state, ev.xbutton.button);*/ *bp = button; *dx = ev.xbutton.x; *dy = ev.xbutton.y; *dz = 0; events++; } } else { x11_handle_event(&ev); } } if (events == 0) { /* after a bunch of consecutive noevent calls here (meaning select() says there's something to read but nothing is returned......), force an event read (which will most likely terminate the connection) */ if (++noevent_count >= 50) { while(XNextEvent(x11_dpy, &ev)) { /* if we return, then we got an event...put it back so we can properly process it next time through */ XPutBackEvent(x11_dpy, &ev); } noevent_count = 0; } return 0; } noevent_count = 0; return 2; /* absolute position returned*/ }
static void kill_bus_when_session_ends (void) { int tty_fd; int x_fd; fd_set read_set; fd_set err_set; struct sigaction act; sigset_t empty_mask; /* install SIGHUP handler */ got_sighup = FALSE; sigemptyset (&empty_mask); act.sa_handler = signal_handler; act.sa_mask = empty_mask; act.sa_flags = 0; sigaction (SIGHUP, &act, NULL); sigaction (SIGTERM, &act, NULL); sigaction (SIGINT, &act, NULL); #ifdef DBUS_BUILD_X11 x11_init(); if (xdisplay != NULL) { x_fd = ConnectionNumber (xdisplay); } else x_fd = -1; #else x_fd = -1; #endif if (isatty (0)) tty_fd = 0; else tty_fd = -1; if (x_fd >= 0) { verbose ("session lifetime is defined by X, not monitoring stdin\n"); tty_fd = -1; } else if (tty_fd >= 0) { verbose ("stdin isatty(), monitoring it\n"); } else { verbose ("stdin was not a TTY, not monitoring it\n"); } if (tty_fd < 0 && x_fd < 0) { fprintf (stderr, "No terminal on standard input and no X display; cannot attach message bus to session lifetime\n"); kill_bus_and_exit (1); } while (TRUE) { #ifdef DBUS_BUILD_X11 /* Dump events on the floor, and let * IO error handler run if we lose * the X connection. It's important to * run this before going into select() since * we might have queued outgoing messages or * events. */ x11_handle_event (); #endif FD_ZERO (&read_set); FD_ZERO (&err_set); if (tty_fd >= 0) { FD_SET (tty_fd, &read_set); FD_SET (tty_fd, &err_set); } if (x_fd >= 0) { FD_SET (x_fd, &read_set); FD_SET (x_fd, &err_set); } select (MAX (tty_fd, x_fd) + 1, &read_set, NULL, &err_set, NULL); if (got_sighup) { verbose ("Got SIGHUP, exiting\n"); kill_bus_and_exit (0); } #ifdef DBUS_BUILD_X11 /* Events will be processed before we select again */ if (x_fd >= 0) verbose ("X fd condition reading = %d error = %d\n", FD_ISSET (x_fd, &read_set), FD_ISSET (x_fd, &err_set)); #endif if (tty_fd >= 0) { if (FD_ISSET (tty_fd, &read_set)) { int bytes_read; char discard[512]; verbose ("TTY ready for reading\n"); bytes_read = read (tty_fd, discard, sizeof (discard)); verbose ("Read %d bytes from TTY errno = %d\n", bytes_read, errno); if (bytes_read == 0) kill_bus_and_exit (0); /* EOF */ else if (bytes_read < 0 && errno != EINTR) { /* This shouldn't happen I don't think; to avoid * spinning on the fd forever we exit. */ fprintf (stderr, "dbus-launch: error reading from stdin: %s\n", strerror (errno)); kill_bus_and_exit (0); } } else if (FD_ISSET (tty_fd, &err_set)) { verbose ("TTY has error condition\n"); kill_bus_and_exit (0); } } } }