Ejemplo n.º 1
0
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;
}
Ejemplo n.º 2
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);
}
Ejemplo n.º 3
0
/*
 * 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);
}
Ejemplo n.º 4
0
/* 
   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);
}
Ejemplo n.º 5
0
/*
 * 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);
}
Ejemplo n.º 6
0
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);
}
Ejemplo n.º 7
0
Archivo: monitor.c Proyecto: dj95/bspwm
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);
}
Ejemplo n.º 8
0
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);
}
Ejemplo n.º 9
0
Archivo: bspwm.c Proyecto: sunaku/bspwm
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();
}