/* Handler for "active-window" event from root window listener. */ static void pager_net_active_window(FbEv * ev, PagerPlugin * pg) { Window * focused_window = get_xaproperty(GDK_ROOT_WINDOW(), a_NET_ACTIVE_WINDOW, XA_WINDOW, 0); if (focused_window != NULL) { PagerTask * tk = task_lookup(pg, *focused_window); if (tk != pg->focused_task) { /* Focused task changed. Redraw both old and new. */ if (pg->focused_task != NULL) desk_set_dirty_by_win(pg, pg->focused_task); pg->focused_task = tk; if (tk != NULL) desk_set_dirty_by_win(pg, tk); } XFree(focused_window); } else { /* Focused task disappeared. Redraw old. */ if (pg->focused_task != NULL) { desk_set_dirty_by_win(pg, pg->focused_task); pg->focused_task = NULL; } } }
int task_flash(int argc, char *argv[]) { int (*function)(int argc, char *argv[]); if (argc < 3) { int i; TASK_FLASH_USAGE: warning("usage: %s %s <task> [<task parameters>]\n", argv[0], argv[1]); warning("supported tasks are:\n", argv[0]); for (i = 0; tasks_flash[i].name != NULL; ++i) warning("\t%s\n", tasks_flash[i].name); return EXIT_FAILURE; } function = task_lookup(tasks_flash, 2, argc, argv); if (function) { int result; radio = NULL; result = function(argc, argv); if (radio) task_radio_done(radio); return result; } goto TASK_FLASH_USAGE; return EXIT_SUCCESS; }
/* Handle ConfigureNotify event. */ static void pager_configure_notify_event(PagerPlugin * pg, XEvent * ev) { Window win = ev->xconfigure.window; PagerTask * tk = task_lookup(pg, win); if (tk != NULL) { task_get_geometry(tk); desk_set_dirty_by_win(pg, tk); } }
/* Handle PropertyNotify event. * http://tronche.com/gui/x/icccm/ * http://standards.freedesktop.org/wm-spec/wm-spec-1.4.html */ static void pager_property_notify_event(PagerPlugin * pg, XEvent * ev) { /* State may be PropertyNewValue, PropertyDeleted. */ if (((XPropertyEvent*) ev)->state == PropertyNewValue) { Atom at = ev->xproperty.atom; Window win = ev->xproperty.window; if (win != GDK_ROOT_WINDOW()) { /* Look up task structure by X window handle. */ PagerTask * tk = task_lookup(pg, win); if (tk != NULL) { /* Install an error handler that ignores BadWindow. * We frequently get a PropertyNotify event on deleted windows. */ XErrorHandler previous_error_handler = XSetErrorHandler(panel_handle_x_error_swallow_BadWindow_BadDrawable); /* Dispatch on atom. */ if (at == a_WM_STATE) { /* Window changed state. */ tk->ws = get_wm_state(tk->win); desk_set_dirty_by_win(pg, tk); } else if (at == a_NET_WM_STATE) { /* Window changed EWMH state. */ get_net_wm_state(tk->win, &tk->nws); desk_set_dirty_by_win(pg, tk); } else if (at == a_NET_WM_DESKTOP) { /* Window changed desktop. * Mark both old and new desktops for redraw. */ desk_set_dirty_by_win(pg, tk); tk->desktop = get_net_wm_desktop(tk->win); desk_set_dirty_by_win(pg, tk); XSetErrorHandler(previous_error_handler); } } } } }
/* * Allocate new task */ int task_alloc(task_t task, struct task **pt) { struct task *t; /* Check if specified task already exists. */ if (task_lookup(task) != NULL) return EINVAL; if (!(t = malloc(sizeof(struct task)))) return ENOMEM; memset(t, 0, sizeof(struct task)); t->task = task; strcpy(t->cwd, "/"); mutex_init(&t->lock); TASK_LOCK(); list_insert(&task_table[TASKHASH(task)], &t->link); TASK_UNLOCK(); *pt = t; return 0; }