int main() { create_resolvconf(); int fd = inotify_init(), wd = add_monitor(fd); void* buff = malloc(2048); struct inotify_event event; while (1) { /* TODO: get all events, not just one */ int n = read(fd, &event, sizeof(struct inotify_event)); event = *(struct inotify_event*)buff; printf("\nevent\n"); rm_monitor(fd, wd); create_resolvconf(); wd = add_monitor(fd); usleep(999999); } //int f_resolv_conf = open("/etc/resolv.conf", O_CREAT | ) return 0; }
static Eterm notify_when_unloaded(Process *p, Eterm name_term, char *name, ErtsProcLocks plocks, Uint flag) { Eterm r = NIL; Eterm immediate_tag = NIL; Eterm immediate_type = NIL; erts_driver_t *drv; ERTS_LC_ASSERT(ERTS_PROC_LOCK_MAIN & plocks); lock_drv_list(); if ((drv = lookup_driver(name)) == NULL) { immediate_tag = am_unloaded; immediate_type = am_DOWN; goto immediate; } if (drv->handle == NULL || drv->handle->status == ERL_DE_PERMANENT) { immediate_tag = am_permanent; immediate_type = am_UP; goto immediate; } p->flags |= F_USING_DDLL; r = add_monitor(p, drv->handle, flag); unlock_drv_list(); BIF_RET(r); immediate: r = erts_make_ref(p); erts_proc_unlock(p, plocks); notify_proc(p, r, name_term, immediate_type, immediate_tag, 0); unlock_drv_list(); erts_proc_lock(p, plocks); BIF_RET(r); }
/* * Utilities */ static Eterm notify_when_loaded(Process *p, Eterm name_term, char *name, ErtsProcLocks plocks) { Eterm r = NIL; Eterm immediate_tag = NIL; Eterm immediate_type = NIL; erts_driver_t *drv; ERTS_LC_ASSERT(ERTS_PROC_LOCK_MAIN & plocks); lock_drv_list(); if ((drv = lookup_driver(name)) == NULL) { immediate_tag = am_unloaded; immediate_type = am_DOWN; goto immediate; } if (drv->handle == NULL || drv->handle->status == ERL_DE_PERMANENT) { immediate_tag = am_permanent; immediate_type = am_UP; goto immediate; } switch (drv->handle->status) { case ERL_DE_OK: immediate_tag = am_loaded; immediate_type = am_UP; goto immediate; case ERL_DE_UNLOAD: case ERL_DE_FORCE_UNLOAD: immediate_tag = am_load_cancelled; immediate_type = am_DOWN; goto immediate; case ERL_DE_RELOAD: case ERL_DE_FORCE_RELOAD: break; default: erts_exit(ERTS_ERROR_EXIT,"Internal error, unknown state %u in dynamic driver.", drv->handle->status); } p->flags |= F_USING_DDLL; r = add_monitor(p, drv->handle, ERL_DE_PROC_AWAIT_LOAD); unlock_drv_list(); BIF_RET(r); immediate: r = erts_make_ref(p); erts_proc_unlock(p, plocks); notify_proc(p, r, name_term, immediate_type, immediate_tag, 0); unlock_drv_list(); erts_proc_lock(p, plocks); BIF_RET(r); }
/* You have to have loaded the driver and the pid state is LOADED or AWAIT_LOAD. You will be removed from the list regardless of driver state. If the driver is loaded by someone else to, return is {ok, pending_process} If the driver is loaded but locked by a port, return is {ok, pending_driver} If the driver is loaded and free to unload (you're the last holding it) {ok, unloaded} If it's not loaded or not loaded by you {error, not_loaded} or {error, not_loaded_by_you} Internally, if its in state UNLOADING, just return {ok, pending_driver} and remove/decrement this pid (which should be an LOADED tagged one). If the state is RELOADING, this pid should be in list as LOADED tagged, only AWAIT_LOAD would be possible but not allowed for unloading, remove it and, if the last LOADED tagged, change from RELOAD to UNLOAD and notify any AWAIT_LOAD-waiters with {'DOWN', ref(), driver, name(), load_cancelled} If the driver made itself permanent, {'UP', ref(), driver, name(), permanent} */ Eterm erl_ddll_try_unload_2(BIF_ALIST_2) { Eterm name_term = BIF_ARG_1; Eterm options = BIF_ARG_2; char *name = NULL; Eterm ok_term = NIL; Eterm soft_error_term = NIL; erts_driver_t *drv; DE_Handle *dh; DE_ProcEntry *pe; Eterm *hp; Eterm t; int monitor = 0; Eterm l; int kill_ports = 0; erts_proc_unlock(BIF_P, ERTS_PROC_LOCK_MAIN); for(l = options; is_list(l); l = CDR(list_val(l))) { Eterm opt = CAR(list_val(l)); Eterm *tp; if (is_not_tuple(opt)) { if (opt == am_kill_ports) { kill_ports = 1; continue; } else { goto error; } } tp = tuple_val(opt); if (*tp != make_arityval(2) || tp[1] != am_monitor) { goto error; } if (tp[2] == am_pending_driver) { monitor = 1; } else if (tp[2] == am_pending) { monitor = 2; } else { goto error; } } if (is_not_nil(l)) { goto error; } if ((name = pick_list_or_atom(name_term)) == NULL) { goto error; } lock_drv_list(); if ((drv = lookup_driver(name)) == NULL) { soft_error_term = am_not_loaded; goto soft_error; } if (drv->handle == NULL) { soft_error_term = am_linked_in_driver; goto soft_error; } else if (drv->handle->status == ERL_DE_PERMANENT) { soft_error_term = am_permanent; goto soft_error; } dh = drv->handle; if (dh->flags & ERL_DE_FL_KILL_PORTS) { kill_ports = 1; } if ((pe = find_proc_entry(dh, BIF_P, ERL_DE_PROC_LOADED)) == NULL) { if (num_procs(dh, ERL_DE_PROC_LOADED) > 0) { soft_error_term = am_not_loaded_by_this_process; goto soft_error; } } else { remove_proc_entry(dh, pe); if (!(pe->flags & ERL_DE_FL_DEREFERENCED)) { erts_ddll_dereference_driver(dh); } erts_free(ERTS_ALC_T_DDLL_PROCESS, pe); } if (num_procs(dh, ERL_DE_PROC_LOADED) > 0) { ok_term = am_pending_process; --monitor; goto done; } if (dh->status == ERL_DE_RELOAD || dh->status == ERL_DE_FORCE_RELOAD) { notify_all(dh, drv->name, ERL_DE_PROC_AWAIT_LOAD, am_DOWN, am_load_cancelled); erts_free(ERTS_ALC_T_DDLL_HANDLE,dh->reload_full_path); erts_free(ERTS_ALC_T_DDLL_HANDLE,dh->reload_driver_name); dh->reload_full_path = dh->reload_driver_name = NULL; dh->reload_flags = 0; } if (erts_atomic32_read_nob(&dh->port_count) > 0) { ++kill_ports; } dh->status = ERL_DE_UNLOAD; ok_term = am_pending_driver; done: assert_drv_list_rwlocked(); if (kill_ports > 1) { /* Avoid closing the driver by referencing it */ erts_ddll_reference_driver(dh); dh->status = ERL_DE_FORCE_UNLOAD; unlock_drv_list(); kill_ports_driver_unloaded(dh); lock_drv_list(); erts_ddll_dereference_driver(dh); } erts_ddll_reference_driver(dh); unlock_drv_list(); erts_proc_lock(BIF_P, ERTS_PROC_LOCK_MAIN); lock_drv_list(); erts_ddll_dereference_driver(dh); erts_free(ERTS_ALC_T_DDLL_TMP_BUF, (void *) name); BIF_P->flags |= F_USING_DDLL; if (monitor > 0) { Eterm mref = add_monitor(BIF_P, dh, ERL_DE_PROC_AWAIT_UNLOAD); hp = HAlloc(BIF_P, 4); t = TUPLE3(hp, am_ok, ok_term, mref); } else { hp = HAlloc(BIF_P, 3); t = TUPLE2(hp, am_ok, ok_term); } if (kill_ports > 1) { ERTS_BIF_CHK_EXITED(BIF_P); /* May be exited by port killing */ } unlock_drv_list(); BIF_RET(t); soft_error: unlock_drv_list(); erts_free(ERTS_ALC_T_DDLL_TMP_BUF, (void *) name); erts_proc_lock(BIF_P, ERTS_PROC_LOCK_MAIN); hp = HAlloc(BIF_P, 3); t = TUPLE2(hp, am_error, soft_error_term); BIF_RET(t); error: /* No lock fiddling before going here */ assert_drv_list_not_locked(); if (name != NULL) { erts_free(ERTS_ALC_T_DDLL_TMP_BUF, (void *) name); } erts_proc_lock(BIF_P, ERTS_PROC_LOCK_MAIN); BIF_ERROR(BIF_P, BADARG); }
/* * Try to load. If the driver is OK, add as LOADED. If the driver is * UNLOAD, possibly change to reload and add as LOADED, * there should be no other * LOADED tagged pid's. If the driver is RELOAD then add/increment as * LOADED (should be some LOADED pid). If the driver is not present, * really load and add as LOADED {ok,loaded} {ok,pending_driver} * {error, permanent} {error,load_error()} */ BIF_RETTYPE erl_ddll_try_load_3(BIF_ALIST_3) { Eterm path_term = BIF_ARG_1; Eterm name_term = BIF_ARG_2; Eterm options = BIF_ARG_3; char *path = NULL; Sint path_len; char *name = NULL; DE_Handle *dh; erts_driver_t *drv; int res; Eterm soft_error_term = NIL; Eterm ok_term = NIL; Eterm *hp; Eterm t; int monitor = 0; int reload = 0; Eterm l; Uint flags = 0; int kill_ports = 0; int do_build_load_error = 0; int build_this_load_error = 0; int encoding; for(l = options; is_list(l); l = CDR(list_val(l))) { Eterm opt = CAR(list_val(l)); Eterm *tp; if (is_not_tuple(opt)) { goto error; } tp = tuple_val(opt); if (*tp != make_arityval(2) || is_not_atom(tp[1])) { goto error; } switch (tp[1]) { case am_driver_options: { Eterm ll; for(ll = tp[2]; is_list(ll); ll = CDR(list_val(ll))) { Eterm dopt = CAR(list_val(ll)); if (dopt == am_kill_ports) { flags |= ERL_DE_FL_KILL_PORTS; } else { goto error; } } if (is_not_nil(ll)) { goto error; } } break; case am_monitor: if (tp[2] == am_pending_driver) { monitor = 1; } else if (tp[2] == am_pending ) { monitor = 2; } else { goto error; } break; case am_reload: if (tp[2] == am_pending_driver) { reload = 1; } else if (tp[2] == am_pending ) { reload = 2; } else { goto error; } break; default: goto error; } } if (is_not_nil(l)) { goto error; } if ((name = pick_list_or_atom(name_term)) == NULL) { goto error; } encoding = erts_get_native_filename_encoding(); if (encoding == ERL_FILENAME_WIN_WCHAR) { /* Do not convert the lib name to utf-16le yet, do that in win32 specific code */ /* since lib_name is used in error messages */ encoding = ERL_FILENAME_UTF8; } path = erts_convert_filename_to_encoding(path_term, NULL, 0, ERTS_ALC_T_DDLL_TMP_BUF, 1, 0, encoding, &path_len, sys_strlen(name) + 2); /* might need path separator */ if (!path) { goto error; } ASSERT(path_len > 0 && path[path_len-1] == 0); while (--path_len > 0 && (path[path_len-1] == '\\' || path[path_len-1] == '/')) ; path[path_len++] = '/'; sys_strcpy(path+path_len,name); erts_proc_unlock(BIF_P, ERTS_PROC_LOCK_MAIN); lock_drv_list(); if ((drv = lookup_driver(name)) != NULL) { if (drv->handle == NULL) { /* static_driver */ soft_error_term = am_linked_in_driver; goto soft_error; } else { dh = drv->handle; if (dh->status == ERL_DE_OK) { int is_last = is_last_user(dh, BIF_P); if (reload == 1 && !is_last) { /*Want reload if no other users, but there are others...*/ soft_error_term = am_pending_process; goto soft_error; } if (reload != 0) { DE_ProcEntry *old; if ((dh->flags & ERL_FL_CONSISTENT_MASK) != (flags & ERL_FL_CONSISTENT_MASK)) { soft_error_term = am_inconsistent; goto soft_error; } if ((old = find_proc_entry(dh, BIF_P, ERL_DE_PROC_LOADED)) == NULL) { soft_error_term = am_not_loaded_by_this_process; goto soft_error; } else { remove_proc_entry(dh, old); erts_ddll_dereference_driver(dh); erts_free(ERTS_ALC_T_DDLL_PROCESS, old); } /* Reload requested and granted */ dereference_all_processes(dh); set_driver_reloading(dh, BIF_P, path, name, flags); if (dh->flags & ERL_DE_FL_KILL_PORTS) { kill_ports = 1; } ok_term = (reload == 1) ? am_pending_driver : am_pending_process; } else { /* Already loaded and healthy (might be by me) */ if (sys_strcmp(dh->full_path, path) || (dh->flags & ERL_FL_CONSISTENT_MASK) != (flags & ERL_FL_CONSISTENT_MASK)) { soft_error_term = am_inconsistent; goto soft_error; } add_proc_loaded(dh, BIF_P); erts_ddll_reference_driver(dh); monitor = 0; ok_term = mkatom("already_loaded"); } } else if (dh->status == ERL_DE_UNLOAD || dh->status == ERL_DE_FORCE_UNLOAD) { /* pending driver */ if (reload != 0) { soft_error_term = am_not_loaded_by_this_process; goto soft_error; } if (sys_strcmp(dh->full_path, path) || (dh->flags & ERL_FL_CONSISTENT_MASK) != (flags & ERL_FL_CONSISTENT_MASK)) { soft_error_term = am_inconsistent; goto soft_error; } dh->status = ERL_DE_OK; notify_all(dh, drv->name, ERL_DE_PROC_AWAIT_UNLOAD, am_UP, am_unload_cancelled); add_proc_loaded(dh, BIF_P); erts_ddll_reference_driver(dh); monitor = 0; ok_term = mkatom("already_loaded"); } else if (dh->status == ERL_DE_RELOAD || dh->status == ERL_DE_FORCE_RELOAD) { if (reload != 0) { soft_error_term = am_pending_reload; goto soft_error; } if (sys_strcmp(dh->reload_full_path, path) || (dh->reload_flags & ERL_FL_CONSISTENT_MASK) != (flags & ERL_FL_CONSISTENT_MASK)) { soft_error_term = am_inconsistent; goto soft_error; } /* Load of granted unload... */ /* Don't reference, will happen after reload */ add_proc_loaded_deref(dh, BIF_P); ++monitor; ok_term = am_pending_driver; } else { /* ERL_DE_PERMANENT */ soft_error_term = am_permanent; goto soft_error; } } } else { /* driver non-existing */ if (reload != 0) { soft_error_term = am_not_loaded; goto soft_error; } if ((res = load_driver_entry(&dh, path, name)) != ERL_DE_NO_ERROR) { build_this_load_error = res; do_build_load_error = 1; soft_error_term = am_undefined; goto soft_error; } else { dh->flags = flags; add_proc_loaded(dh, BIF_P); first_ddll_reference(dh); monitor = 0; ok_term = mkatom("loaded"); } } assert_drv_list_rwlocked(); if (kill_ports) { /* Avoid closing the driver by referencing it */ erts_ddll_reference_driver(dh); ASSERT(dh->status == ERL_DE_RELOAD); dh->status = ERL_DE_FORCE_RELOAD; unlock_drv_list(); kill_ports_driver_unloaded(dh); /* Dereference, eventually causing driver destruction */ lock_drv_list(); erts_ddll_dereference_driver(dh); } erts_ddll_reference_driver(dh); unlock_drv_list(); erts_proc_lock(BIF_P, ERTS_PROC_LOCK_MAIN); lock_drv_list(); erts_ddll_dereference_driver(dh); BIF_P->flags |= F_USING_DDLL; if (monitor) { Eterm mref = add_monitor(BIF_P, dh, ERL_DE_PROC_AWAIT_LOAD); hp = HAlloc(BIF_P, 4); t = TUPLE3(hp, am_ok, ok_term, mref); } else { hp = HAlloc(BIF_P, 3); t = TUPLE2(hp, am_ok, ok_term); } unlock_drv_list(); erts_free(ERTS_ALC_T_DDLL_TMP_BUF, (void *) path); erts_free(ERTS_ALC_T_DDLL_TMP_BUF, (void *) name); ERTS_LC_ASSERT(ERTS_PROC_LOCK_MAIN & erts_proc_lc_my_proc_locks(BIF_P)); BIF_RET(t); soft_error: unlock_drv_list(); erts_proc_lock(BIF_P, ERTS_PROC_LOCK_MAIN); if (do_build_load_error) { soft_error_term = build_load_error(BIF_P, build_this_load_error); } hp = HAlloc(BIF_P, 3); t = TUPLE2(hp, am_error, soft_error_term); erts_free(ERTS_ALC_T_DDLL_TMP_BUF, (void *) path); erts_free(ERTS_ALC_T_DDLL_TMP_BUF, (void *) name); ERTS_LC_ASSERT(ERTS_PROC_LOCK_MAIN & erts_proc_lc_my_proc_locks(BIF_P)); BIF_RET(t); error: assert_drv_list_not_locked(); ERTS_LC_ASSERT(ERTS_PROC_LOCK_MAIN & erts_proc_lc_my_proc_locks(BIF_P)); if (path != NULL) { erts_free(ERTS_ALC_T_DDLL_TMP_BUF, (void *) path); } if (name != NULL) { erts_free(ERTS_ALC_T_DDLL_TMP_BUF, (void *) name); } BIF_ERROR(BIF_P, BADARG); }
bool import_monitors(void) { PUTS("import monitors"); xcb_randr_get_screen_resources_current_reply_t *sres = xcb_randr_get_screen_resources_current_reply(dpy, xcb_randr_get_screen_resources_current(dpy, root), NULL); if (sres == NULL) return false; monitor_t *m, *mm = NULL; int len = xcb_randr_get_screen_resources_current_outputs_length(sres); xcb_randr_output_t *outputs = xcb_randr_get_screen_resources_current_outputs(sres); xcb_randr_get_output_info_cookie_t cookies[len]; for (int i = 0; i < len; i++) cookies[i] = xcb_randr_get_output_info(dpy, outputs[i], XCB_CURRENT_TIME); for (m = mon_head; m != NULL; m = m->next) m->wired = false; for (int i = 0; i < len; i++) { xcb_randr_get_output_info_reply_t *info = xcb_randr_get_output_info_reply(dpy, cookies[i], NULL); if (info != NULL) { if (info->crtc != XCB_NONE) { xcb_randr_get_crtc_info_reply_t *cir = xcb_randr_get_crtc_info_reply(dpy, xcb_randr_get_crtc_info(dpy, info->crtc, XCB_CURRENT_TIME), NULL); if (cir != NULL) { xcb_rectangle_t rect = (xcb_rectangle_t) {cir->x, cir->y, cir->width, cir->height}; mm = get_monitor_by_id(outputs[i]); if (mm != NULL) { mm->rectangle = rect; update_root(mm); for (desktop_t *d = mm->desk_head; d != NULL; d = d->next) for (node_t *n = first_extrema(d->root); n != NULL; n = next_leaf(n, d->root)) translate_client(mm, mm, n->client); arrange(mm, mm->desk); mm->wired = true; PRINTF("update monitor %s (0x%X)\n", mm->name, mm->id); } else { mm = add_monitor(rect); char *name = (char *)xcb_randr_get_output_info_name(info); size_t name_len = MIN(sizeof(mm->name), (size_t)xcb_randr_get_output_info_name_length(info) + 1); snprintf(mm->name, name_len, "%s", name); mm->id = outputs[i]; PRINTF("add monitor %s (0x%X)\n", mm->name, mm->id); } } free(cir); } else if (!remove_disabled_monitor && info->connection != XCB_RANDR_CONNECTION_DISCONNECTED) { m = get_monitor_by_id(outputs[i]); if (m != NULL) m->wired = true; } } free(info); } /* initially focus the primary monitor and add the first desktop to it */ xcb_randr_get_output_primary_reply_t *gpo = xcb_randr_get_output_primary_reply(dpy, xcb_randr_get_output_primary(dpy, root), NULL); if (gpo != NULL) { pri_mon = get_monitor_by_id(gpo->output); if (!running && pri_mon != NULL) { if (mon != pri_mon) mon = pri_mon; add_desktop(pri_mon, make_desktop(NULL)); ewmh_update_current_desktop(); } } free(gpo); /* handle overlapping monitors */ m = mon_head; while (m != NULL) { monitor_t *next = m->next; if (m->wired) { for (monitor_t *mb = mon_head; mb != NULL; mb = mb->next) if (mb != m && mb->wired && (m->desk == NULL || mb->desk == NULL) && contains(mb->rectangle, m->rectangle)) { if (mm == m) mm = mb; merge_monitors(m, mb); remove_monitor(m); break; } } m = next; } /* merge and remove disconnected monitors */ m = mon_head; while (m != NULL) { monitor_t *next = m->next; if (!m->wired) { merge_monitors(m, mm); remove_monitor(m); } m = next; } /* add one desktop to each new monitor */ for (m = mon_head; m != NULL; m = m->next) if (m->desk == NULL && (running || pri_mon == NULL || m != pri_mon)) add_desktop(m, make_desktop(NULL)); free(sres); update_motion_recorder(); return (num_monitors > 0); }
bool update_monitors(void) { xcb_randr_get_screen_resources_reply_t *sres = xcb_randr_get_screen_resources_reply(dpy, xcb_randr_get_screen_resources(dpy, root), NULL); if (sres == NULL) { return false; } monitor_t *m, *mm = NULL; int len = xcb_randr_get_screen_resources_outputs_length(sres); xcb_randr_output_t *outputs = xcb_randr_get_screen_resources_outputs(sres); xcb_randr_get_output_info_cookie_t cookies[len]; for (int i = 0; i < len; i++) { cookies[i] = xcb_randr_get_output_info(dpy, outputs[i], XCB_CURRENT_TIME); } for (m = mon_head; m != NULL; m = m->next) { m->wired = false; } for (int i = 0; i < len; i++) { xcb_randr_get_output_info_reply_t *info = xcb_randr_get_output_info_reply(dpy, cookies[i], NULL); if (info != NULL) { if (info->crtc != XCB_NONE) { xcb_randr_get_crtc_info_reply_t *cir = xcb_randr_get_crtc_info_reply(dpy, xcb_randr_get_crtc_info(dpy, info->crtc, XCB_CURRENT_TIME), NULL); if (cir != NULL) { xcb_rectangle_t rect = (xcb_rectangle_t) {cir->x, cir->y, cir->width, cir->height}; mm = get_monitor_by_randr_id(outputs[i]); if (mm != NULL) { update_root(mm, &rect); mm->wired = true; } else { mm = make_monitor(&rect, XCB_NONE); char *name = (char *)xcb_randr_get_output_info_name(info); int len = xcb_randr_get_output_info_name_length(info); size_t name_size = MIN(sizeof(mm->name), (size_t) len + 1); snprintf(mm->name, name_size, "%s", name); mm->randr_id = outputs[i]; add_monitor(mm); } } free(cir); } else if (!remove_disabled_monitors && info->connection != XCB_RANDR_CONNECTION_DISCONNECTED) { m = get_monitor_by_randr_id(outputs[i]); if (m != NULL) { m->wired = true; } } } free(info); } xcb_randr_get_output_primary_reply_t *gpo = xcb_randr_get_output_primary_reply(dpy, xcb_randr_get_output_primary(dpy, root), NULL); if (gpo != NULL) { pri_mon = get_monitor_by_randr_id(gpo->output); } free(gpo); /* handle overlapping monitors */ if (merge_overlapping_monitors) { m = mon_head; while (m != NULL) { monitor_t *next = m->next; if (m->wired) { monitor_t *mb = mon_head; while (mb != NULL) { monitor_t *mb_next = mb->next; if (m != mb && mb->wired && contains(m->rectangle, mb->rectangle)) { if (mm == mb) { mm = m; } if (next == mb) { next = mb_next; } merge_monitors(mb, m); remove_monitor(mb); } mb = mb_next; } } m = next; } } /* merge and remove disconnected monitors */ if (remove_unplugged_monitors) { m = mon_head; while (m != NULL) { monitor_t *next = m->next; if (!m->wired) { merge_monitors(m, mm); remove_monitor(m); } m = next; } } /* add one desktop to each new monitor */ for (m = mon_head; m != NULL; m = m->next) { if (m->desk == NULL) { add_desktop(m, make_desktop(NULL, XCB_NONE)); } } if (!running && mon != NULL) { if (pri_mon != NULL) { mon = pri_mon; } center_pointer(mon->rectangle); ewmh_update_current_desktop(); } free(sres); return (mon != NULL); }
void handle_command(zmsg_t * request, zmsg_t * reply, rulepackage_t * rpkg, channeldb_t * db ) { char * command = zmsg_popstr(request); zclock_log("%s worker servicing request %s", rpkg->servicename,command); if (strcmp(command, "AddTrigger") == 0) { triggerconfig_t * tconf = add_trigger(rpkg, request, reply); if(tconf) db_store_trigger(db, tconf); } else if (strcmp(command, "AddAction") == 0) { zclock_log("actions not implemented yet"); //TODO } else if (strcmp(command,"RemoveRule") == 0) { char * rule_id = zmsg_popstr(request); // we always evaluate both, hence | usage rather than || int found = remove_rule(rpkg->context, rpkg->triggers, rule_id) | remove_rule(rpkg->context, rpkg->actions, rule_id); if(found) { // must also delete from local db. db_delete_action(db, rule_id); db_delete_trigger(db, rule_id); zmsg_pushstr(reply, "200"); } else { // not there! zclock_log("Received delete trigger request for nonexistent rule %s, ignoring", rule_id); zmsg_pushstr(reply, "404"); zmsg_pushstr(reply, "rule not found"); } } else if (strcmp(command, "AddMonitor")==0) { add_monitor(rpkg, reply); } else if (strcmp(command, "Service") == 0) { assert(zmsg_size(request) == 1); // TODO this is incomplete // services also have names char * name = zmsg_popstr(request); // char * service_pipe; // we _could_ just throw the request out into the ether, but // really, we want this to be a reply-request sort of deal. // otherwise, we have to contend with the same problem we have // with monitors: that they need to stay active. // let's set up a hash of pipes, and just have a worker for each // possible service. // problems: this _is_ synchronous for the channel involved. // this means we can't subsume monitors into it. probably ok for // now. //service_function * service_func; // if ((service_func=zhash_lookup(config->services, name))) { // found it, let's execute // problem here is that we don't particularly want to wait for // the next update, even though it's probably within the next // 60th of a second. // what are our options? // 1. listen to line000X, wait, return // 2. spin off a thread with a reference to the request, let // it reply on our behalf... i think this probably doesn't // work, majordomo expects a response before it gives you more // work. // 3. cache current value somewhere. this is fast, but pretty // sketchy in synchronisation terms. it migh tbe ok, given // that it's explicitly just sampling. // char * result = service_func(); //zmsg_pushstr(reply, result); // } else { zclock_log("bad service %s", name); zmsg_pushstr(reply, "no such service"); } else { zclock_log("Can't handle command %s: ignoring", command); zmsg_pushstr(reply, "bad command"); } zmsg_destroy(&request); }
void setup(void) { ewmh_init(); screen = xcb_setup_roots_iterator(xcb_get_setup(dpy)).data; if (!screen) err("error: cannot aquire screen\n"); screen_width = screen->width_in_pixels; screen_height = screen->height_in_pixels; root_depth = screen->root_depth; xcb_atom_t net_atoms[] = {ewmh->_NET_SUPPORTED, ewmh->_NET_DESKTOP_NAMES, ewmh->_NET_NUMBER_OF_DESKTOPS, ewmh->_NET_CURRENT_DESKTOP, ewmh->_NET_CLIENT_LIST, ewmh->_NET_ACTIVE_WINDOW, ewmh->_NET_WM_DESKTOP, ewmh->_NET_WM_STATE, ewmh->_NET_WM_STATE_FULLSCREEN, ewmh->_NET_WM_WINDOW_TYPE, ewmh->_NET_WM_WINDOW_TYPE_DOCK, ewmh->_NET_WM_WINDOW_TYPE_NOTIFICATION, ewmh->_NET_WM_WINDOW_TYPE_DIALOG, ewmh->_NET_WM_WINDOW_TYPE_UTILITY, ewmh->_NET_WM_WINDOW_TYPE_TOOLBAR}; xcb_ewmh_set_supported(ewmh, default_screen, LENGTH(net_atoms), net_atoms); monitor_uid = desktop_uid = client_uid = 0; mon = last_mon = mon_head = mon_tail = NULL; bool xinerama_is_active = false; if (xcb_get_extension_data(dpy, &xcb_xinerama_id)->present) { xcb_xinerama_is_active_reply_t *xia = xcb_xinerama_is_active_reply(dpy, xcb_xinerama_is_active(dpy), NULL); if (xia != NULL) { xinerama_is_active = xia->state; free(xia); } } if (xinerama_is_active) { xcb_xinerama_query_screens_reply_t *xsq = xcb_xinerama_query_screens_reply(dpy, xcb_xinerama_query_screens(dpy), NULL); xcb_xinerama_screen_info_t *xsi = xcb_xinerama_query_screens_screen_info(xsq); int n = xcb_xinerama_query_screens_screen_info_length(xsq); PRINTF("number of monitors: %d\n", n); for (int i = 0; i < n; i++) { xcb_xinerama_screen_info_t info = xsi[i]; xcb_rectangle_t rect = (xcb_rectangle_t) {info.x_org, info.y_org, info.width, info.height}; add_monitor(&rect); } free(xsq); } else { warn("Xinerama is inactive"); xcb_rectangle_t rect = (xcb_rectangle_t) {0, 0, screen_width, screen_height}; add_monitor(&rect); } for (monitor_t *m = mon_head; m != NULL; m = m->next) add_desktop(m, NULL); ewmh_update_number_of_desktops(); ewmh_update_desktop_names(); rule_head = make_rule(); frozen_pointer = make_pointer_state(); get_pointer_position(&pointer_position); split_mode = MODE_AUTOMATIC; }
Plugin::Plugin(XfcePanelPlugin *xfce_plugin_) : xfce_plugin(xfce_plugin_), // Setting defaults icon_path("/usr/share/pixmaps/xfce4-hardware-monitor-plugin.png"), viewer_type("curve"), viewer_font(""), viewer_size(96), // Arbitrary default, see later in this function for notes background_color(0x000000FF), // Black as the night - note that the // transparency bits need to be set to max to // ensure the colour is visible use_background_color(false), next_color(0), viewer_text_overlay_enabled(false), viewer_text_overlay_format_string("%a %m"), viewer_text_overlay_separator(" "), viewer_text_overlay_font(""), viewer_text_overlay_use_font(false), viewer_text_overlay_color(0x000000FF), viewer_text_overlay_position(CanvasView::top_left), viewer_monitor_type_sync_enabled(true) { // Search for settings file XfceRc* settings_ro = NULL; gchar* file = xfce_panel_plugin_lookup_rc_file(xfce_plugin); if (file) { // One exists - loading settings settings_ro = xfce_rc_simple_open(file, true); g_free(file); // Ensuring default group is in focus xfce_rc_set_group(settings_ro, NULL); icon_path = xfce_rc_read_entry(settings_ro, "icon-path", icon_path.c_str()); viewer_type = xfce_rc_read_entry(settings_ro, "viewer_type", viewer_type.c_str()); viewer_size = xfce_rc_read_int_entry(settings_ro, "viewer_size", viewer_size); viewer_font = xfce_rc_read_entry(settings_ro, "viewer_font", viewer_font.c_str()); background_color = xfce_rc_read_int_entry(settings_ro, "background_color", background_color); use_background_color = xfce_rc_read_bool_entry(settings_ro, "use_background_color", use_background_color); next_color = xfce_rc_read_int_entry(settings_ro, "next_color", next_color); viewer_text_overlay_enabled = xfce_rc_read_bool_entry(settings_ro, "viewer_text_overlay_enabled", viewer_text_overlay_enabled); viewer_text_overlay_format_string = xfce_rc_read_entry(settings_ro, "viewer_text_overlay_format_string", viewer_text_overlay_format_string.c_str()); viewer_text_overlay_separator = xfce_rc_read_entry(settings_ro, "viewer_text_overlay_separator", viewer_text_overlay_separator.c_str()); viewer_text_overlay_font = xfce_rc_read_entry(settings_ro, "viewer_text_overlay_font", viewer_text_overlay_font.c_str()); viewer_text_overlay_color = xfce_rc_read_int_entry(settings_ro, "viewer_text_overlay_color", viewer_text_overlay_color); viewer_monitor_type_sync_enabled = xfce_rc_read_bool_entry(settings_ro, "viewer_monitor_type_sync_enabled", viewer_monitor_type_sync_enabled); // Enum is validated in set_viewer_text_overlay_position CanvasView::TextOverlayPosition text_overlay_position = static_cast<CanvasView::TextOverlayPosition>( xfce_rc_read_int_entry(settings_ro, "viewer_text_overlay_position", CanvasView::top_left)); set_viewer_text_overlay_position(text_overlay_position); } // Loading icon try { icon = Gdk::Pixbuf::create_from_file(icon_path); } catch (...) { std::cerr << String::ucompose(_("Hardware Monitor: cannot load the icon '%1'.\n"), icon_path); // It's a minor problem if we can't find the icon icon = Glib::RefPtr<Gdk::Pixbuf>(); } // Configuring viewer type viewer_type_listener(viewer_type); /* Actually setting the viewer size has no effect in this function - * seems that it needs to be done in or after the mainloop kicks off */ // Loading up monitors /* Plugin& is initialised from non-transient address of this ('this' itself * is an rvalue so not allowed for a reference) */ monitor_seq mon = load_monitors(settings_ro, *this); for (monitor_iter i = mon.begin(), end = mon.end(); i != end; ++i) add_monitor(*i); // All settings loaded if (settings_ro) xfce_rc_close(settings_ro); /* Connect plugin signals to functions - since I'm not really interested * in the plugin but the plugin pointer, swapped results in the signal * handler getting the plugin reference first - the plugin pointer is * passed next, but since the handler only takes one parameter this is * discarded * Providing About option */ g_signal_connect_swapped(xfce_plugin, "about", G_CALLBACK(display_about), this); // Hooking into Properties option g_signal_connect_swapped(xfce_plugin, "configure-plugin", G_CALLBACK(display_preferences), this); // Hooking into plugin destruction signal g_signal_connect_swapped(xfce_plugin, "free-data", G_CALLBACK(plugin_free), this); // Hooking into save signal g_signal_connect_swapped(xfce_plugin, "save", G_CALLBACK(save_monitors), this); /* Not needed as the canvas resizes on the fly // Hooking into size changed signal g_signal_connect(xfce_plugin, "size-changed", G_CALLBACK(size_changed), this); */ // Adding configure and about to the plugin's right-click menu xfce_panel_plugin_menu_show_configure(xfce_plugin); xfce_panel_plugin_menu_show_about(xfce_plugin); /* Add plugin to panel - I need to turn the Plugin (which inherits from * Gtk::EventBox) into a GtkWidget* - to do this I get at the GObject * pointer underneath the gtkmm layer */ gtk_container_add(GTK_CONTAINER(xfce_plugin), GTK_WIDGET(this->gobj())); // Initialising timer to run every second (by default) to trigger main_loop timer = Glib::signal_timeout().connect(sigc::mem_fun(*this, &Plugin::main_loop), update_interval); // Initial main_loop run main_loop(); }