static gboolean on_read_bytes (GPollableInputStream * stream, Client * client) { gssize r; gchar data[4096]; GError *err = NULL; do { r = g_pollable_input_stream_read_nonblocking (G_POLLABLE_INPUT_STREAM (client->istream), data, sizeof (data), NULL, &err); if (r > 0) g_byte_array_append (client->current_message, (guint8 *) data, r); } while (r > 0); if (r == 0) { remove_client (client); return FALSE; } else if (g_error_matches (err, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK)) { guint8 *tmp = client->current_message->data; g_clear_error (&err); while (client->current_message->len > 3) { if (tmp[0] == 0x0d && tmp[1] == 0x0a && tmp[2] == 0x0d && tmp[3] == 0x0a) { guint len; g_byte_array_append (client->current_message, (const guint8 *) "\0", 1); len = tmp - client->current_message->data + 5; client_message (client, (gchar *) client->current_message->data, len); g_byte_array_remove_range (client->current_message, 0, len); tmp = client->current_message->data; } else { tmp++; } } if (client->current_message->len >= 1024 * 1024) { g_print ("No complete request after 1MB of data\n"); remove_client (client); return FALSE; } return TRUE; } else { g_print ("Read error %s\n", err->message); g_clear_error (&err); remove_client (client); return FALSE; } return FALSE; }
void handle_event(xcb_generic_event_t *evt) { uint8_t resp_type = XCB_EVENT_RESPONSE_TYPE(evt); switch (resp_type) { case XCB_MAP_REQUEST: map_request(evt); break; case XCB_DESTROY_NOTIFY: destroy_notify(evt); break; case XCB_UNMAP_NOTIFY: unmap_notify(evt); break; case XCB_CLIENT_MESSAGE: client_message(evt); break; case XCB_CONFIGURE_REQUEST: configure_request(evt); break; case XCB_PROPERTY_NOTIFY: property_notify(evt); break; case XCB_ENTER_NOTIFY: enter_notify(evt); break; case XCB_MOTION_NOTIFY: motion_notify(evt); break; case XCB_FOCUS_IN: focus_in(evt); break; case 0: process_error(evt); break; default: if (randr && resp_type == randr_base + XCB_RANDR_SCREEN_CHANGE_NOTIFY) { update_monitors(); } break; } }
/* -------------------------------------------------------------------------- * * 'event handling' des [settings] Dialoges * * -------------------------------------------------------------------------- */ int ui_settings_proc(sgWidget *widget, sgEvent event) { ui_generic_proc(widget, event); if(event == SG_EVENT_CLICK) { if(widget == ui_settings_team1) { net_send("TEAM 1"); sgDisableWidget(widget); sgEnableWidget(ui_settings_team2); } else if(widget == ui_settings_team2) { net_send("TEAM 2"); sgDisableWidget(widget); sgEnableWidget(ui_settings_team1); } else if(widget == ui_settings_accept) { net_send("ACCEPT"); sgDisableWidget(widget); } else if(widget == ui_settings_start) { net_send("START"); } else if(widget == ui_settings_kick) { sgListboxItem *item = NULL; char msg[30] = "KICK \0"; item = sgSelectedListboxItem(ui_settings_players); if(item) { strcat(msg, item->caption); net_send(msg); } } else if(widget == ui_settings_ban) { sgListboxItem *item = NULL; char msg[30] = "BAN \0"; item = sgSelectedListboxItem(ui_settings_players); if(item) { strcat(msg, item->caption); net_send(msg); } } else if(widget == ui_settings_back) { net_send("LEAVE"); sgClearWidgetStatus(ui_settings_dialog, SG_RUNNING); client_status = CLIENT_CHAT; return 1; } } /* Return taste wurde gedrückt */ else if(event == SG_RETURN) { if(widget == ui_settings_input && strcmp(ui_settings_input->caption, "")) { client_message(ui_settings_input->caption); } } if(event == SG_EVENT_QUIT) sgClearWidgetStatus(ui_settings_dialog, SG_RUNNING); return 0; }
/* main() for usual operation */ int tray_main(int argc, char **argv) { XEvent ev; /* Interpret those settings that need an open display */ interpret_settings(); #ifdef DEBUG ewmh_list_supported_atoms(tray_data.dpy); #endif /* Create and show tray window */ tray_create_window(argc, argv); tray_acquire_selection(); tray_show_window(); #ifndef NO_NATIVE_KDE kde_tray_init(tray_data.dpy); #endif xembed_init(); #ifndef NO_NATIVE_KDE kde_icons_update(); #endif /* Main event loop */ while ("my guitar gently wheeps") { /* This is ugly and extra dependency. But who cares? * Rationale: we want to block unless absolutely needed. * This way we ensure that stalonetray does not show up * in powertop (i.e. does not eat unnecessary power and * CPU cycles) * Drawback: handling of signals is very limited. XNextEvent() * does not if signal occurs. This means that graceful * exit on e.g. Ctrl-C cannot be implemented without hacks. */ while (XPending(tray_data.dpy) || tray_data.scrollbars_data.scrollbar_down == -1) { XNextEvent(tray_data.dpy, &ev); xembed_handle_event(ev); scrollbars_handle_event(ev); switch (ev.type) { case VisibilityNotify: LOG_TRACE(("VisibilityNotify (0x%x, state=%d)\n", ev.xvisibility.window, ev.xvisibility.state)); visibility_notify(ev.xvisibility); break; case Expose: LOG_TRACE(("Expose (0x%x)\n", ev.xexpose.window)); expose(ev.xexpose); break; case PropertyNotify: LOG_TRACE(("PropertyNotify(0x%x)\n", ev.xproperty.window)); property_notify(ev.xproperty); break; case DestroyNotify: LOG_TRACE(("DestroyNotify(0x%x)\n", ev.xdestroywindow.window)); destroy_notify(ev.xdestroywindow); break; case ClientMessage: LOG_TRACE(("ClientMessage(from 0x%x?)\n", ev.xclient.window)); client_message(ev.xclient); break; case ConfigureNotify: LOG_TRACE(("ConfigureNotify(0x%x)\n", ev.xconfigure.window)); configure_notify(ev.xconfigure); break; case MapNotify: LOG_TRACE(("MapNotify(0x%x)\n", ev.xmap.window)); map_notify(ev.xmap); break; case ReparentNotify: LOG_TRACE(("ReparentNotify(0x%x to 0x%x)\n", ev.xreparent.window, ev.xreparent.parent)); reparent_notify(ev.xreparent); break; case SelectionClear: LOG_TRACE(("SelectionClear (0x%x has lost selection)\n", ev.xselectionclear.window)); selection_clear(ev.xselectionclear); break; case SelectionNotify: LOG_TRACE(("SelectionNotify\n")); break; case SelectionRequest: LOG_TRACE(("SelectionRequest (from 0x%x to 0x%x)\n", ev.xselectionrequest.requestor, ev.xselectionrequest.owner)); break; case UnmapNotify: LOG_TRACE(("UnmapNotify(0x%x)\n", ev.xunmap.window)); unmap_notify(ev.xunmap); break; default: #if defined(DEBUG) && defined(TRACE_EVENTS) LOG_TRACE(("Unhandled event: %s, serial: %d, window: 0x%x\n", x11_event_names[ev.type], ev.xany.serial, ev.xany.window)); #endif break; } if (tray_data.terminated) goto bailout; /* Perform all periodic tasks but for scrollbars */ perform_periodic_tasks(PT_MASK_ALL & (~PT_MASK_SB)); } perform_periodic_tasks(PT_MASK_ALL); my_usleep(500000L); } bailout: LOG_TRACE(("Clean exit\n")); return 0; }
/* The main function */ int main(int argc, char const *argv[]) { Display *dpy; GString *line; unsigned xeventmask; int error_base, shape_event, damage_event; struct { Bool children, creation, mapping, configure, shape; Bool properties, clientmsg; Bool visibility, exposure, damages; Bool pointer, keyboard; } track; dpy = XOpenDisplay(NULL); XSetErrorHandler(xerror_handler); XA_utf8_string = XInternAtom(dpy, "UTF8_STRING", False); XA_wm_state = XInternAtom(dpy, "WM_STATE", False); if (argv[1] && !strcmp(argv[1], "-t")) { Opt_timestamp = 1; optind++; } /* Choose which events we're interested in. */ memset(&track, 0, sizeof(track)); track.children = True; track.creation = True; track.mapping = True; track.configure = True; track.shape = True; track.properties = True; track.clientmsg = True; track.visibility = True; track.keyboard = True; for (; argv[optind]; optind++) { char const *opt; Bool add, del, *which; opt = argv[optind]; add = opt[0] == '+'; del = opt[0] == '-'; if (add || del) opt++; if (!strcmp(opt, "children")) which = &track.children; else if (!strcmp(opt, "create")) which = &track.creation; else if (!strcmp(opt, "map")) which = &track.mapping; else if (!strcmp(opt, "config")) which = &track.configure; else if (!strcmp(opt, "shape")) which = &track.shape; else if (!strcmp(opt, "prop")) which = &track.properties; else if (!strcmp(opt, "ipc")) which = &track.clientmsg; else if (!strcmp(opt, "visibility")) which = &track.visibility; else if (!strcmp(opt, "expose")) which = &track.exposure; else if (!strcmp(opt, "damage")) which = &track.damages; else if (!strcmp(opt, "ptr")) which = &track.pointer; else if (!strcmp(opt, "kbd")) which = &track.keyboard; else break; if (!add && !del) memset(&track, 0, sizeof(track)); *which = !del; } /* for */ xeventmask = 0; if (track.creation || track.mapping || track.configure || track.clientmsg) xeventmask |= track.children ? SubstructureNotifyMask : StructureNotifyMask; if (track.shape) XShapeQueryExtension(dpy, &shape_event, &error_base); if (track.properties) xeventmask |= PropertyChangeMask; if (track.visibility) xeventmask |= VisibilityChangeMask; if (track.exposure) xeventmask |= ExposureMask; if (track.damages) XDamageQueryExtension(dpy, &damage_event, &error_base); if (track.pointer); xeventmask |= EnterWindowMask|LeaveWindowMask; if (track.keyboard) xeventmask |= KeyPressMask|KeyReleaseMask; /* XSelectInput() the windows we're interested in * or the root window. */ if (argv[optind]) do { Window win; char const *errp; win = strtoul(argv[optind], (char **)&errp, 0); if (errp == argv[optind] || *errp) { fprintf(stderr, "%s: what is `%s'?\n", argv[0], argv[optind]); exit(1); } XSelectInput(dpy, win, xeventmask); if (track.shape) XShapeSelectInput(dpy, win, ShapeNotifyMask); if (track.damages) XDamageCreate(dpy, win, XDamageReportRawRectangles); } while (argv[++optind]); else XSelectInput(dpy, DefaultRootWindow(dpy), xeventmask); /* The main loop */ line = g_string_new(""); for (;;) { XEvent ev; /* Wait for, get and process the next event. */ XNextEvent(dpy, &ev); if (ev.type == CreateNotify) { XCreateWindowEvent const *create = &ev.xcreatewindow; if (!track.creation) continue; fmtxid(line, create->parent); g_string_append_printf(line, "Create(0x%lx)", create->window); output(line, ev.xany.send_event); } else if (ev.type == DestroyNotify) { XDestroyWindowEvent const *destroy = &ev.xdestroywindow; if (!track.creation) continue; fmtxid(line, destroy->event); g_string_append_printf(line, "Destroy(0x%lx)", destroy->window); output(line, ev.xany.send_event); } else if (ev.type == MapNotify) { XMapEvent const *map = &ev.xmap; if (!track.mapping) continue; fmtxid(line, map->event); g_string_append_printf(line, "Map(0x%lx%s)", map->window, map->override_redirect ? ", override_redirected" : ""); output(line, ev.xany.send_event); } else if (ev.type == UnmapNotify) { XUnmapEvent const *unmap = &ev.xunmap; if (!track.mapping) continue; fmtxid(line, unmap->event); g_string_append_printf(line, "Unmap(0x%lx%s)", unmap->window, unmap->from_configure ? ", from_configure" : ""); output(line, ev.xany.send_event); } else if (ev.type == ReparentNotify) { XReparentEvent const *reparent = &ev.xreparent; if (!track.configure) continue; fmtxid(line, reparent->event); g_string_append_printf(line, "Reparent(0x%lx => 0x%lx)", reparent->window, reparent->parent); output(line, ev.xany.send_event); } else if (ev.type == ConfigureNotify) { XConfigureEvent const *cfg = &ev.xconfigure; if (!track.configure) continue; fmtxid(line, cfg->event); g_string_append_printf(line, "Configure(0x%lx => %dx%d%+d%+d, " "above=0x%lx%s)", cfg->window, cfg->width, cfg->height, cfg->x, cfg->y, cfg->above, cfg->override_redirect ? ", override_redirected" : ""); output(line, ev.xany.send_event); } else if (track.shape && ev.type == shape_event + ShapeNotify) { static char const *shapes[] = { "Bounding", "Clip", "Input" }; XShapeEvent sev; memcpy(&sev, &ev, sizeof(sev)); fmtxid(line, sev.window); g_string_append_printf(line, "Shape(%s => %dx%d%+d%+d)", shapes[sev.kind], sev.width, sev.height, sev.x, sev.y); output(line, ev.xany.send_event); } else if (ev.type == PropertyNotify) { assert(track.properties); property_event(dpy, &ev.xproperty, line); } else if (ev.type == ClientMessage) { if (!track.clientmsg) continue; client_message(dpy, &ev.xclient, line); } else if (ev.type == VisibilityNotify) { static char const *visibilities[] = { "unobscured", "partially obscured", "fully obscured", }; XVisibilityEvent const *vis = &ev.xvisibility; assert(track.visibility); fmtxid(line, vis->window); g_string_append_printf(line, "Visibility=%s", visibilities[vis->state]); output(line, ev.xany.send_event); } else if (ev.type == Expose) { XExposeEvent const *ex = &ev.xexpose; assert(track.exposure); fmtxid(line, ex->window); g_string_append_printf(line, "Expose(%dx%d%+d%+d)", ex->width, ex->height, ex->x, ex->y); output(line, ev.xany.send_event); } else if (track.damages && ev.type == damage_event) { XDamageNotifyEvent dev; memcpy(&dev, &ev, sizeof(dev)); fmtxid(line, dev.drawable); g_string_append_printf(line, "Damage(%dx%d%+d%+d)", dev.area.width, dev.area.height, dev.area.x, dev.area.y); output(line, ev.xany.send_event); XDamageSubtract(dpy, dev.damage, None, None); } else if (ev.type == EnterNotify || ev.type == LeaveNotify) { XCrossingEvent const *cross = &ev.xcrossing; if (!track.pointer) continue; fmtxid(line, cross->window); g_string_append_printf(line, "%s(%dx%d", cross->type == EnterNotify ? "Enter" : "Leave", cross->x, cross->y); if (cross->mode == NotifyGrab) g_string_append(line, ", grab"); else if (cross->mode == NotifyUngrab) g_string_append(line, ", ungrab"); g_string_append_c(line, ')'); output(line, ev.xany.send_event); } else if (ev.type == KeyPress || ev.type == KeyRelease) { static struct { int mask; char const *name; } states[] = { { ShiftMask, "Shift" }, { LockMask, "Lock" }, { ControlMask, "Ctrl" }, { Mod1Mask, "Mod1" }, { Mod2Mask, "Mod2" }, { Mod3Mask, "Mod3" }, { Mod4Mask, "Mod4" }, { Mod5Mask, "Mod5" }, }; unsigned i; int has_modifiers; XKeyEvent const *key; assert(track.keyboard); key = &ev.xkey; fmtxid(line, key->window); /* Prepend with the list of modifiers. */ has_modifiers = 0; for (i = 0; i < G_N_ELEMENTS(states); i++) if (key->state & states[i].mask) { if (!has_modifiers) { g_string_append_c(line, ' '); has_modifiers = 1; } else g_string_append_c(line, '-'); g_string_append(line, states[i].name); } if (has_modifiers) g_string_append_c(line, '-'); g_string_append_printf(line, "%s %s", XKeysymToString(XKeycodeToKeysym(dpy, key->keycode, 0)), ev.type == KeyPress ? "pressed" : "released"); output(line, ev.xany.send_event); } /* if */ } /* for ever */ return 0; } /* main */
void SYSTRAY_event_filter(XEvent *e) { XEvent ev; if (!tray_data.dpy) return; ev = *e; xembed_handle_event(ev); //scrollbars_handle_event(ev); switch (ev.type) { case VisibilityNotify: LOG_TRACE(("VisibilityNotify (0x%x, state=%d)\n", ev.xvisibility.window, ev.xvisibility.state)); visibility_notify(ev.xvisibility); break; case Expose: LOG_TRACE(("Expose (0x%x)\n", ev.xexpose.window)); expose(ev.xexpose); break; case PropertyNotify: LOG_TRACE(("PropertyNotify(0x%x)\n", ev.xproperty.window)); property_notify(ev.xproperty); break; case DestroyNotify: LOG_TRACE(("DestroyNotify(0x%x)\n", ev.xdestroywindow.window)); destroy_notify(ev.xdestroywindow); break; case ClientMessage: LOG_TRACE(("ClientMessage(from 0x%x?)\n", ev.xclient.window)); client_message(ev.xclient); break; case ConfigureNotify: LOG_TRACE(("ConfigureNotify(0x%x)\n", ev.xconfigure.window)); configure_notify(ev.xconfigure); break; case MapNotify: LOG_TRACE(("MapNotify(0x%x)\n", ev.xmap.window)); map_notify(ev.xmap); break; case ReparentNotify: LOG_TRACE(("ReparentNotify(0x%x to 0x%x)\n", ev.xreparent.window, ev.xreparent.parent)); reparent_notify(ev.xreparent); break; case SelectionClear: LOG_TRACE(("SelectionClear (0x%x has lost selection)\n", ev.xselectionclear.window)); selection_clear(ev.xselectionclear); break; case SelectionNotify: LOG_TRACE(("SelectionNotify\n")); break; case SelectionRequest: LOG_TRACE(("SelectionRequest (from 0x%x to 0x%x)\n", ev.xselectionrequest.requestor, ev.xselectionrequest.owner)); break; case UnmapNotify: LOG_TRACE(("UnmapNotify(0x%x)\n", ev.xunmap.window)); unmap_notify(ev.xunmap); break; default: #if defined(DEBUG) && defined(TRACE_EVENTS) LOG_TRACE(("Unhandled event: %s, serial: %d, window: 0x%x\n", x11_event_names[ev.type], ev.xany.serial, ev.xany.window)); #endif break; } // TODO: perform_periodic_tasks(PT_MASK_ALL); #if 0 if (tray_data.terminated) goto bailout; /* Perform all periodic tasks but for scrollbars */ perform_periodic_tasks(PT_MASK_ALL & (~PT_MASK_SB)); }