Beispiel #1
0
static void uv__timer_cb(EV_P_ ev_timer* w, int revents) {
  uv_timer_t* timer = w->data;

  assert(uv__timer_active(timer));

  if (!uv__timer_repeating(timer)) {
    timer->flags &= ~UV_TIMER_ACTIVE;
    ev_ref(EV_A);
  }

  if (timer->timer_cb) {
    timer->timer_cb(timer, 0);
  }
}
Beispiel #2
0
static void uv__timer_cb(EV_P_ ev_timer* w, int revents) {
  uv_timer_t* timer = container_of(w, uv_timer_t, timer_watcher);

  assert(uv__timer_active(timer));

  if (!uv__timer_repeating(timer)) {
    timer->flags &= ~UV_TIMER_ACTIVE;
    ev_ref(EV_A);
  }

  if (timer->timer_cb) {
    timer->timer_cb(timer, 0);
  }
}
Beispiel #3
0
void uv__handle_init(uv_loop_t* loop, uv_handle_t* handle,
    uv_handle_type type) {
  loop->counters.handle_init++;

  handle->loop = loop;
  handle->type = type;
  handle->flags = 0;

  ev_init(&handle->next_watcher, uv__next);
  handle->next_watcher.data = handle;

  /* Ref the loop until this handle is closed. See uv__finish_close. */
  ev_ref(loop->ev);
}
Beispiel #4
0
/**
 * Increases the watcher-reference count on the EventLoop, this is the reverse
 * of EventLoop::unref()
 * 
 * @see EventLoop::unref()
 * @return boolean
 */
PHP_METHOD(EventLoop, ref)
{
	event_loop_object *obj = (event_loop_object *)zend_object_store_get_object(getThis() TSRMLS_CC);
	
	assert(obj->loop);
	
	if(obj->loop)
	{
		ev_ref(obj->loop);
		
		RETURN_BOOL(1);
	}
	
	RETURN_BOOL(0);
}
Beispiel #5
0
static void event_timer_cb(struct ev_loop *loop, ev_timer *w, int revents) {
	liEventTimer *timer = LI_CONTAINER_OF(w, liEventTimer, libevmess.timer);
	liEventLoop *my_loop = timer->base.link_watchers.data;
	UNUSED(revents);

	LI_FORCE_ASSERT(NULL != my_loop);
	LI_FORCE_ASSERT(loop == my_loop->loop);

	if (ev_is_active(w)) {
		if (!timer->base.keep_loop_alive) ev_ref(loop);
		ev_timer_stop(loop, w);
	}
	timer->base.active = 0;

	timer->base.callback(&timer->base, LI_EV_WAKEUP);
}
Beispiel #6
0
/* The driver's event loop. */
static void *event_loop(void *pcap_drv_loop_) {
    assert(pcap_drv_loop_ != NULL);
    struct pcap_drv_loop *pcap_drv_loop = (struct pcap_drv_loop *)pcap_drv_loop_;

    thread_id_set();

    logger_log(pcap_drv_loop->logger, LOG_INFO, "Thread started for PCAP.");

    ev_ref(pcap_drv_loop->loop); //makes sure an empty loop stays alive
    ev_run(pcap_drv_loop->loop, 0/*flags*/);

    logger_log(pcap_drv_loop->logger, LOG_ERR, "Loop exited.");

    pthread_exit(NULL);
    return NULL;
}
Beispiel #7
0
static void event_child_cb(struct ev_loop *loop, ev_child *w, int revents) {
	liEventChild *child = LI_CONTAINER_OF(w, liEventChild, libevmess.child);
	liEventLoop *my_loop = child->base.link_watchers.data;
	UNUSED(revents);

	LI_FORCE_ASSERT(NULL != my_loop);
	LI_FORCE_ASSERT(loop == my_loop->loop);

	if (ev_is_active(w)) {
		if (!child->base.keep_loop_alive) ev_ref(loop);
		ev_child_stop(loop, w);
	}
	child->base.active = 0;

	child->base.callback(&child->base, LI_EV_WAKEUP);
}
Beispiel #8
0
/* Starts the event loop attached to the controller thread. */
static void *
event_loop(void *ctrl_loop_) {
    assert(ctrl_loop_ != NULL);
    struct ctrl_loop *ctrl_loop = (struct ctrl_loop *)ctrl_loop_;

    thread_id_set();

    logger_log(ctrl_loop->logger, LOG_INFO, "Thread started for DP control.");

    ev_ref(ctrl_loop->loop); //makes sure an empty loop stays alive
    ev_run(ctrl_loop->loop, 0/*flags*/);

    logger_log(ctrl_loop->logger, LOG_ERR, "Loop exited.");

    pthread_exit(NULL);
    return NULL;
}
Beispiel #9
0
void uv__udp_watcher_stop(uv_udp_t* handle, ev_io* w) {
  int flags;

  if (!ev_is_active(w)) {
    return;
  }

  assert(w == &handle->read_watcher
      || w == &handle->write_watcher);

  flags = (w == &handle->read_watcher ? EV_READ : EV_WRITE);

  ev_ref(handle->loop->ev);
  ev_io_stop(handle->loop->ev, w);
  ev_io_set(w, -1, flags);
  ev_set_cb(w, NULL);
  w->data = (void*)0xDEADBABE;
}
Beispiel #10
0
    BlendBaton() :
        quality(0),
        format(BLEND_FORMAT_PNG),
        reencode(false),
        width(0),
        height(0),
        matte(0),
        compression(Z_DEFAULT_COMPRESSION),
        result(NULL),
        resultLength(0),
        max(0)
    {
#if NODE_MAJOR_VERSION == 0 && NODE_MINOR_VERSION <= 4
        ev_ref(EV_DEFAULT_UC);
#else
        this->request.data = this;
#endif
    }
Beispiel #11
0
void li_event_io_set_events(liEventIO *io, int events) {
	if (events == io->events) return;
	io->events = events;

	if (li_event_attached(io) && li_event_active(io)) {
		liEventLoop *loop = io->base.link_watchers.data;
		LI_FORCE_ASSERT(NULL != loop);

		ev_ref(loop->loop);

		ev_io_stop(loop->loop, &io->libevmess.io);
		ev_io_set(&io->libevmess.io, io->libevmess.io.fd, io_events_to_libev(events));
		ev_io_start(loop->loop, &io->libevmess.io);

		ev_unref(loop->loop);
	} else {
		ev_io_set(&io->libevmess.io, io->libevmess.io.fd, io_events_to_libev(events));
	}
}
Beispiel #12
0
static void se_thread_new(lua_State *L)
{
	struct se_thread *thread;

	luaL_checktype(L, 1, LUA_TFUNCTION);

	thread = se_new(struct se_thread);
	thread->L = lua_newthread(L);
	thread->lref = luaL_ref(L, LUA_REGISTRYINDEX); // prevent gc
	thread->buf = NULL;

	se_thread_wakeup(thread, lua_gettop(L) - 1);
	ev_init(&thread->timer, NULL);
	ev_init(&thread->io, NULL);
	ev_ref(EV_DEFAULT); // keep ev loop running until there is no thread exists

	//lua_pushvalue(L, 1);  /* move function to top */
  	lua_xmove(L, thread->L, lua_gettop(L));  /* move function and args from L to NL */
}
Beispiel #13
0
/* zipfile.read(buffer, pos, len, cb) -> cb(bytesRead, error) */
Handle<Value> ZipFile::Read(const Arguments& args)
{
    ZipFile* zf = ObjectWrap::Unwrap<ZipFile>(args.This());

    if (!Buffer::HasInstance(args[0])) {
      return ThrowException(Exception::Error(
                  String::New("First argument needs to be a buffer")));
    }
    Local<Object> buffer_obj = args[0]->ToObject();
    char *buffer_data = Buffer::Data(buffer_obj);
    size_t buffer_length = Buffer::Length(buffer_obj);

    zip_uint64_t off = args[1]->Int32Value();
    if (off >= buffer_length) {
      return ThrowException(Exception::Error(
            String::New("Offset is out of bounds")));
    }

    zip_uint64_t len = args[2]->Int32Value();
    if (off + len > buffer_length) {
      return ThrowException(Exception::Error(
            String::New("Length is extends beyond buffer")));
    }

    Local<Value> cb = args[3];
    if (!cb->IsFunction())
      return ThrowException(Exception::Error(
            String::New("Fourth argument should be a callback function.")));

    read_closure_t *closure = new read_closure_t();
    closure->zf = zf;
    closure->read = 0;
    closure->data = buffer_data+off;
    closure->len = len;
    closure->cb = Persistent<Function>::New(Handle<Function>::Cast(args[3]));

    eio_custom(EIO_Read, EIO_PRI_DEFAULT, EIO_AfterRead, closure);
    zf->Ref();
    ev_ref(EV_DEFAULT_UC);

    return Undefined();
}
Beispiel #14
0
void li_tasklet_pool_free(liTaskletPool *pool) {
	liTasklet *t;

	if (!pool) return;

	li_tasklet_pool_set_threads(pool, 0);

	while (NULL != (t = g_async_queue_try_pop(pool->finished))) {
		t->finished_cb(t->data);
	}
	g_async_queue_unref(pool->finished);
	pool->finished = NULL;

	ev_ref(pool->loop);
	ev_async_stop(pool->loop, &pool->finished_watcher);

	if (-1 == pool->delete_later) {
		pool->delete_later = 1;
	} else {
		g_slice_free(liTaskletPool, pool);
	}
}
Beispiel #15
0
void li_event_io_set_fd(liEventIO *io, int fd) {
	if (-1 == fd) {
		li_event_stop(io);
		ev_io_set(&io->libevmess.io, fd, io->libevmess.io.events);
		return;
	}

	if (li_event_attached(io) && li_event_active(io)) {
		liEventLoop *loop = io->base.link_watchers.data;
		LI_FORCE_ASSERT(NULL != loop);

		ev_ref(loop->loop);

		ev_io_stop(loop->loop, &io->libevmess.io);
		ev_io_set(&io->libevmess.io, fd, io->libevmess.io.events);
		ev_io_start(loop->loop, &io->libevmess.io);

		ev_unref(loop->loop);
	} else {
		ev_io_set(&io->libevmess.io, fd, io->libevmess.io.events);
	}
}
Beispiel #16
0
Datei: core.c Projekt: ifzz/lem
static int
signal_os_unwatch(lua_State *T, int sig)
{
	struct sigwatcher **prevp;
	struct sigwatcher *s;

	for (prevp = &signal_watchers, s = signal_watchers;
			s != NULL;
			prevp = &s->next, s = s->next) {
		if (s->w.signum == sig)
			break;
	}
	if (s != NULL) {
		ev_ref(LEM);
		ev_signal_stop(LEM_ &s->w);

		sigdelset(&signal_sigset, sig);

		*prevp = s->next;
		free(s);
	}
	lua_pushboolean(T, 1);
	return 1;
}
Beispiel #17
0
void uv_close(uv_handle_t* handle, uv_close_cb close_cb) {
  uv_async_t* async;
  uv_stream_t* stream;
  uv_process_t* process;

  handle->close_cb = close_cb;

  switch (handle->type) {
    case UV_NAMED_PIPE:
      uv_pipe_cleanup((uv_pipe_t*)handle);
      /* Fall through. */

    case UV_TTY:
    case UV_TCP:
      stream = (uv_stream_t*)handle;

      uv_read_stop(stream);
      ev_io_stop(stream->loop->ev, &stream->write_watcher);

      uv__close(stream->fd);
      stream->fd = -1;

      if (stream->accepted_fd >= 0) {
        uv__close(stream->accepted_fd);
        stream->accepted_fd = -1;
      }

      assert(!ev_is_active(&stream->read_watcher));
      assert(!ev_is_active(&stream->write_watcher));
      break;

    case UV_UDP:
      uv__udp_start_close((uv_udp_t*)handle);
      break;

    case UV_PREPARE:
      uv_prepare_stop((uv_prepare_t*) handle);
      break;

    case UV_CHECK:
      uv_check_stop((uv_check_t*) handle);
      break;

    case UV_IDLE:
      uv_idle_stop((uv_idle_t*) handle);
      break;

    case UV_ASYNC:
      async = (uv_async_t*)handle;
      ev_async_stop(async->loop->ev, &async->async_watcher);
      ev_ref(async->loop->ev);
      break;

    case UV_TIMER:
      uv_timer_stop((uv_timer_t*)handle);
      break;

    case UV_PROCESS:
      process = (uv_process_t*)handle;
      ev_child_stop(process->loop->ev, &process->child_watcher);
      break;

    case UV_FS_EVENT:
      uv__fs_event_destroy((uv_fs_event_t*)handle);
      break;

    default:
      assert(0);
  }

  handle->flags |= UV_CLOSING;

  /* This is used to call the on_close callback in the next loop. */
  ev_idle_start(handle->loop->ev, &handle->next_watcher);
  ev_feed_event(handle->loop->ev, &handle->next_watcher, EV_IDLE);
  assert(ev_is_pending(&handle->next_watcher));
}
Beispiel #18
0
void uv_ref(uv_loop_t* loop) {
  ev_ref(loop->ev);
}
Beispiel #19
0
int main(int argc, char** argv) {
    if (argc < 4) {
        printf("Usage: %s ip port path2worker [shmsize]\n", argv[0]);
        return EXIT_FAILURE;
    }


    struct listener_s listener;
    listener.argc = argc;
    listener.argv = argv;
    listener.stop_moniter = 0;
    listener.shm_id = -1;
    listener.shm_size = -1;

    if (argc > 4) {
        listener.shm_size = atoi(argv[4]);
        if (listener.shm_size > 0) {
            listener.shm_id = shm_alloc(0, listener.shm_size);
        }
        if (listener.shm_id != -1) {
            shm_free(listener.shm_id); // lazy free
        }
    }


    // get loop
    struct ev_loop* loop = ev_default_loop(EVBACKEND_EPOLL);
    ev_set_userdata(loop, &listener);


    // setup signal handler
    struct ev_signal quitwatcher;
    struct ev_signal hupwatcher;
    ev_signal_init(&quitwatcher, listener_stop, SIGQUIT);
    ev_signal_init(&hupwatcher, restart_workers, SIGHUP);
    ev_signal_start(loop, &quitwatcher);
    ev_unref(loop); // 将loop中的watchercnt--,保证不停止此watcher的情况下loop也能正常退出
    ev_signal_start(loop, &hupwatcher);
    ev_unref(loop); // 将loop中的watchercnt--,保证不停止此watcher的情况下loop也能正常退出


    // get cpu number
    listener.worker_count = (int)sysconf(_SC_NPROCESSORS_CONF);


    // init workers
    struct worker_s workers[listener.worker_count];
    listener.workers = &workers[0];

    if (0 != setup_workers(loop, &listener)) {
        return EXIT_FAILURE;
    }


    int r = ev_run(loop, 0);


    ev_ref(loop);
    ev_signal_stop(loop, &quitwatcher);
    ev_ref(loop);
    ev_signal_stop(loop, &hupwatcher);


    return r;
}
Beispiel #20
0
static void uv__fs_event_stop(uv_fs_event_t* handle) {
  ev_ref(handle->loop->ev);
  ev_io_stop(handle->loop->ev, &handle->event_watcher);
}
Beispiel #21
0
void uv_ref() {
    ev_ref(EV_DEFAULT_UC);
}
Beispiel #22
0
void uv__async_close(uv_async_t* handle) {
  ev_async_stop(handle->loop->ev, &handle->async_watcher);
  ev_ref(handle->loop->ev);
}
Beispiel #23
0
static inline void ev_start (struct ev_loop *loop, W w, int active)
{
  w->active = active;
  ev_ref (loop);
}
Beispiel #24
0
/** Hello, this is main.
 * \param argc Who knows.
 * \param argv Who knows.
 * \return EXIT_SUCCESS I hope.
 */
int
main(int argc, char **argv)
{
    char *confpath = NULL;
    int xfd, i, screen_nbr, opt, colors_nbr;
    xcolor_init_request_t colors_reqs[2];
    ssize_t cmdlen = 1;
    xdgHandle xdg;
    xcb_generic_event_t *event;
    static struct option long_options[] =
    {
        { "help",    0, NULL, 'h' },
        { "version", 0, NULL, 'v' },
        { "config",  1, NULL, 'c' },
        { "check",   0, NULL, 'k' },
        { NULL,      0, NULL, 0 }
    };

    /* event loop watchers */
    ev_io xio    = { .fd = -1 };
    ev_check xcheck;
    ev_prepare a_refresh;
    ev_signal sigint;
    ev_signal sigterm;
    ev_signal sighup;

    /* clear the globalconf structure */
    p_clear(&globalconf, 1);
    globalconf.keygrabber = LUA_REFNIL;
    globalconf.mousegrabber = LUA_REFNIL;
    buffer_init(&globalconf.startup_errors);

    /* save argv */
    for(i = 0; i < argc; i++)
        cmdlen += a_strlen(argv[i]) + 1;

    globalconf.argv = p_new(char, cmdlen);
    a_strcpy(globalconf.argv, cmdlen, argv[0]);

    for(i = 1; i < argc; i++)
    {
        a_strcat(globalconf.argv, cmdlen, " ");
        a_strcat(globalconf.argv, cmdlen, argv[i]);
    }

    /* Text won't be printed correctly otherwise */
    setlocale(LC_CTYPE, "");

    /* Get XDG basedir data */
    xdgInitHandle(&xdg);

    /* init lua */
    luaA_init(&xdg);

    /* check args */
    while((opt = getopt_long(argc, argv, "vhkc:",
                             long_options, NULL)) != -1)
        switch(opt)
        {
          case 'v':
            eprint_version();
            break;
          case 'h':
            exit_help(EXIT_SUCCESS);
            break;
          case 'k':
            if(!luaA_parserc(&xdg, confpath, false))
            {
                fprintf(stderr, "✘ Configuration file syntax error.\n");
                return EXIT_FAILURE;
            }
            else
            {
                fprintf(stderr, "✔ Configuration file syntax OK.\n");
                return EXIT_SUCCESS;
            }
          case 'c':
            if(a_strlen(optarg))
                confpath = a_strdup(optarg);
            else
                fatal("-c option requires a file name");
            break;
        }

    globalconf.loop = ev_default_loop(0);
    ev_timer_init(&globalconf.timer, &luaA_on_timer, 0., 0.);

    /* register function for signals */
    ev_signal_init(&sigint, exit_on_signal, SIGINT);
    ev_signal_init(&sigterm, exit_on_signal, SIGTERM);
    ev_signal_init(&sighup, restart_on_signal, SIGHUP);
    ev_signal_start(globalconf.loop, &sigint);
    ev_signal_start(globalconf.loop, &sigterm);
    ev_signal_start(globalconf.loop, &sighup);
    ev_unref(globalconf.loop);
    ev_unref(globalconf.loop);
    ev_unref(globalconf.loop);

    struct sigaction sa = { .sa_handler = signal_fatal, .sa_flags = 0 };
    sigemptyset(&sa.sa_mask);
    sigaction(SIGSEGV, &sa, 0);

    /* XLib sucks */
    XkbIgnoreExtension(True);

    /* X stuff */
    globalconf.display = XOpenDisplay(NULL);
    if (globalconf.display == NULL)
        fatal("cannot open display");

    globalconf.default_screen = XDefaultScreen(globalconf.display);

    globalconf.connection = XGetXCBConnection(globalconf.display);

    /* Double checking then everything is OK. */
    if(xcb_connection_has_error(globalconf.connection))
        fatal("cannot open display");

    /* Prefetch all the extensions we might need */
    xcb_prefetch_extension_data(globalconf.connection, &xcb_big_requests_id);
    xcb_prefetch_extension_data(globalconf.connection, &xcb_test_id);
    xcb_prefetch_extension_data(globalconf.connection, &xcb_randr_id);
    xcb_prefetch_extension_data(globalconf.connection, &xcb_shape_id);

    /* initialize dbus */
    a_dbus_init();

    /* Get the file descriptor corresponding to the X connection */
    xfd = xcb_get_file_descriptor(globalconf.connection);
    ev_io_init(&xio, &a_xcb_io_cb, xfd, EV_READ);
    ev_io_start(globalconf.loop, &xio);
    ev_check_init(&xcheck, &a_xcb_check_cb);
    ev_check_start(globalconf.loop, &xcheck);
    ev_unref(globalconf.loop);
    ev_prepare_init(&a_refresh, &a_refresh_cb);
    ev_prepare_start(globalconf.loop, &a_refresh);
    ev_unref(globalconf.loop);

    /* Grab server */
    xcb_grab_server(globalconf.connection);

    /* Make sure there are no pending events. Since we didn't really do anything
     * at all yet, we will just discard all events which we received so far.
     * The above GrabServer should make sure no new events are generated. */
    xcb_aux_sync(globalconf.connection);
    while ((event = xcb_poll_for_event(globalconf.connection)) != NULL)
    {
        /* Make sure errors are printed */
        uint8_t response_type = XCB_EVENT_RESPONSE_TYPE(event);
        if(response_type == 0)
            event_handle(event);
        p_delete(&event);
    }

    for(screen_nbr = 0;
        screen_nbr < xcb_setup_roots_length(xcb_get_setup(globalconf.connection));
        screen_nbr++)
    {
        const uint32_t select_input_val = XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT;

        /* This causes an error if some other window manager is running */
        xcb_change_window_attributes(globalconf.connection,
                                     xutil_screen_get(globalconf.connection, screen_nbr)->root,
                                     XCB_CW_EVENT_MASK, &select_input_val);
    }

    /* Need to xcb_flush to validate error handler */
    xcb_aux_sync(globalconf.connection);

    /* Process all errors in the queue if any. There can be no events yet, so if
     * this function returns something, it must be an error. */
    if (xcb_poll_for_event(globalconf.connection) != NULL)
        fatal("another window manager is already running");

    /* Prefetch the maximum request length */
    xcb_prefetch_maximum_request_length(globalconf.connection);

    /* check for xtest extension */
    const xcb_query_extension_reply_t *xtest_query;
    xtest_query = xcb_get_extension_data(globalconf.connection, &xcb_test_id);
    globalconf.have_xtest = xtest_query->present;

    /* Allocate the key symbols */
    globalconf.keysyms = xcb_key_symbols_alloc(globalconf.connection);
    xcb_get_modifier_mapping_cookie_t xmapping_cookie =
        xcb_get_modifier_mapping_unchecked(globalconf.connection);

    /* init atom cache */
    atoms_init(globalconf.connection);

    /* init screens information */
    screen_scan();

    /* init default font and colors */
    colors_reqs[0] = xcolor_init_unchecked(&globalconf.colors.fg,
                                           "black", sizeof("black") - 1);

    colors_reqs[1] = xcolor_init_unchecked(&globalconf.colors.bg,
                                           "white", sizeof("white") - 1);

    globalconf.font = draw_font_new("sans 8");

    for(colors_nbr = 0; colors_nbr < 2; colors_nbr++)
        xcolor_init_reply(colors_reqs[colors_nbr]);

    xutil_lock_mask_get(globalconf.connection, xmapping_cookie,
                        globalconf.keysyms, &globalconf.numlockmask,
                        &globalconf.shiftlockmask, &globalconf.capslockmask,
                        &globalconf.modeswitchmask);

    /* Get the window tree associated to this screen */
    const int screen_max = xcb_setup_roots_length(xcb_get_setup(globalconf.connection));
    xcb_query_tree_cookie_t tree_c[screen_max];

    /* do this only for real screen */
    for(screen_nbr = 0; screen_nbr < screen_max; screen_nbr++)
    {
        /* select for events */
        const uint32_t change_win_vals[] =
        {
            XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT | XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY
                | XCB_EVENT_MASK_ENTER_WINDOW | XCB_EVENT_MASK_LEAVE_WINDOW
                | XCB_EVENT_MASK_STRUCTURE_NOTIFY
                | XCB_EVENT_MASK_PROPERTY_CHANGE
                | XCB_EVENT_MASK_BUTTON_PRESS
                | XCB_EVENT_MASK_BUTTON_RELEASE
                | XCB_EVENT_MASK_FOCUS_CHANGE
        };

        tree_c[screen_nbr] = xcb_query_tree_unchecked(globalconf.connection,
                                                      xutil_screen_get(globalconf.connection, screen_nbr)->root);

        xcb_change_window_attributes(globalconf.connection,
                                     xutil_screen_get(globalconf.connection, screen_nbr)->root,
                                     XCB_CW_EVENT_MASK,
                                     change_win_vals);
        ewmh_init(screen_nbr);
        systray_init(screen_nbr);
    }

    /* init spawn (sn) */
    spawn_init();

    /* we will receive events, stop grabbing server */
    xcb_ungrab_server(globalconf.connection);

    /* Parse and run configuration file */
    if (!luaA_parserc(&xdg, confpath, true))
        fatal("couldn't find any rc file");

    scan(tree_c);

    xcb_flush(globalconf.connection);

    /* main event loop */
    ev_loop(globalconf.loop, 0);

    /* cleanup event loop */
    ev_ref(globalconf.loop);
    ev_check_stop(globalconf.loop, &xcheck);
    ev_ref(globalconf.loop);
    ev_prepare_stop(globalconf.loop, &a_refresh);
    ev_ref(globalconf.loop);
    ev_io_stop(globalconf.loop, &xio);

    awesome_atexit(false);

    return EXIT_SUCCESS;
}
Beispiel #25
0
static PyObject *
Loop_ref(Loop *self)
{
    ev_ref(self->loop);
    Py_RETURN_NONE;
}
Beispiel #26
0
/** Hello, this is main.
 * \param argc Who knows.
 * \param argv Who knows.
 * \return EXIT_SUCCESS I hope.
 */
int
main(int argc, char **argv)
{
    char *confpath = NULL;
    int xfd, i, opt;
    ssize_t cmdlen = 1;
    xdgHandle xdg;
    bool no_argb = false;
    xcb_generic_event_t *event;
    xcb_query_tree_cookie_t tree_c;
    static struct option long_options[] =
    {
        { "help",    0, NULL, 'h' },
        { "version", 0, NULL, 'v' },
        { "config",  1, NULL, 'c' },
        { "check",   0, NULL, 'k' },
        { "no-argb", 0, NULL, 'a' },
        { NULL,      0, NULL, 0 }
    };

    /* event loop watchers */
    ev_io xio    = { .fd = -1 };
    ev_check xcheck;
    ev_prepare a_refresh;
    ev_signal sigint;
    ev_signal sigterm;
    ev_signal sighup;

    /* clear the globalconf structure */
    p_clear(&globalconf, 1);
    globalconf.keygrabber = LUA_REFNIL;
    globalconf.mousegrabber = LUA_REFNIL;
    buffer_init(&globalconf.startup_errors);

    /* save argv */
    for(i = 0; i < argc; i++)
        cmdlen += a_strlen(argv[i]) + 1;

    awesome_argv = p_new(char, cmdlen);
    a_strcpy(awesome_argv, cmdlen, argv[0]);

    for(i = 1; i < argc; i++)
    {
        a_strcat(awesome_argv, cmdlen, " ");
        a_strcat(awesome_argv, cmdlen, argv[i]);
    }

    /* Text won't be printed correctly otherwise */
    setlocale(LC_CTYPE, "");

    /* Get XDG basedir data */
    xdgInitHandle(&xdg);

    /* init lua */
    luaA_init(&xdg);

    /* check args */
    while((opt = getopt_long(argc, argv, "vhkc:a",
                             long_options, NULL)) != -1)
        switch(opt)
        {
        case 'v':
            eprint_version();
            break;
        case 'h':
            exit_help(EXIT_SUCCESS);
            break;
        case 'k':
            if(!luaA_parserc(&xdg, confpath, false))
            {
                fprintf(stderr, "✘ Configuration file syntax error.\n");
                return EXIT_FAILURE;
            }
            else
            {
                fprintf(stderr, "✔ Configuration file syntax OK.\n");
                return EXIT_SUCCESS;
            }
        case 'c':
            if(a_strlen(optarg))
                confpath = a_strdup(optarg);
            else
                fatal("-c option requires a file name");
            break;
        case 'a':
            no_argb = true;
            break;
        }

    globalconf.loop = ev_default_loop(EVFLAG_NOSIGFD);

    /* register function for signals */
    ev_signal_init(&sigint, exit_on_signal, SIGINT);
    ev_signal_init(&sigterm, exit_on_signal, SIGTERM);
    ev_signal_init(&sighup, restart_on_signal, SIGHUP);
    ev_signal_start(globalconf.loop, &sigint);
    ev_signal_start(globalconf.loop, &sigterm);
    ev_signal_start(globalconf.loop, &sighup);
    ev_unref(globalconf.loop);
    ev_unref(globalconf.loop);
    ev_unref(globalconf.loop);

    struct sigaction sa = { .sa_handler = signal_fatal, .sa_flags = 0 };
    sigemptyset(&sa.sa_mask);
    sigaction(SIGSEGV, &sa, 0);

    /* X stuff */
    globalconf.connection = xcb_connect(NULL, &globalconf.default_screen);
    if(xcb_connection_has_error(globalconf.connection))
        fatal("cannot open display");

    globalconf.screen = xcb_aux_get_screen(globalconf.connection, globalconf.default_screen);
    /* FIXME The following two assignments were swapped on purpose */
    if(!no_argb)
        globalconf.visual = a_default_visual(globalconf.screen);
    if(!globalconf.visual)
        globalconf.visual = a_argb_visual(globalconf.screen);
    globalconf.default_depth = a_visual_depth(globalconf.screen, globalconf.visual->visual_id);
    globalconf.default_cmap = globalconf.screen->default_colormap;
    if(globalconf.default_depth != globalconf.screen->root_depth)
    {
        // We need our own color map if we aren't using the default depth
        globalconf.default_cmap = xcb_generate_id(globalconf.connection);
        xcb_create_colormap(globalconf.connection, XCB_COLORMAP_ALLOC_NONE,
                            globalconf.default_cmap, globalconf.screen->root,
                            globalconf.visual->visual_id);
    }

    /* Prefetch all the extensions we might need */
    xcb_prefetch_extension_data(globalconf.connection, &xcb_big_requests_id);
    xcb_prefetch_extension_data(globalconf.connection, &xcb_test_id);
    xcb_prefetch_extension_data(globalconf.connection, &xcb_randr_id);
    xcb_prefetch_extension_data(globalconf.connection, &xcb_xinerama_id);

    /* initialize dbus */
    a_dbus_init();

    /* Get the file descriptor corresponding to the X connection */
    xfd = xcb_get_file_descriptor(globalconf.connection);
    ev_io_init(&xio, &a_xcb_io_cb, xfd, EV_READ);
    ev_io_start(globalconf.loop, &xio);
    ev_check_init(&xcheck, &a_xcb_check_cb);
    ev_check_start(globalconf.loop, &xcheck);
    ev_unref(globalconf.loop);
    ev_prepare_init(&a_refresh, &a_refresh_cb);
    ev_prepare_start(globalconf.loop, &a_refresh);
    ev_unref(globalconf.loop);

    /* Grab server */
    xcb_grab_server(globalconf.connection);

    /* Make sure there are no pending events. Since we didn't really do anything
     * at all yet, we will just discard all events which we received so far.
     * The above GrabServer should make sure no new events are generated. */
    xcb_aux_sync(globalconf.connection);
    while ((event = xcb_poll_for_event(globalconf.connection)) != NULL)
    {
        /* Make sure errors are printed */
        uint8_t response_type = XCB_EVENT_RESPONSE_TYPE(event);
        if(response_type == 0)
            event_handle(event);
        p_delete(&event);
    }

    {
        const uint32_t select_input_val = XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT;

        /* This causes an error if some other window manager is running */
        xcb_change_window_attributes(globalconf.connection,
                                     globalconf.screen->root,
                                     XCB_CW_EVENT_MASK, &select_input_val);
    }

    /* Need to xcb_flush to validate error handler */
    xcb_aux_sync(globalconf.connection);

    /* Process all errors in the queue if any. There can be no events yet, so if
     * this function returns something, it must be an error. */
    if (xcb_poll_for_event(globalconf.connection) != NULL)
        fatal("another window manager is already running");

    /* Prefetch the maximum request length */
    xcb_prefetch_maximum_request_length(globalconf.connection);

    /* check for xtest extension */
    const xcb_query_extension_reply_t *xtest_query;
    xtest_query = xcb_get_extension_data(globalconf.connection, &xcb_test_id);
    globalconf.have_xtest = xtest_query->present;

    /* Allocate the key symbols */
    globalconf.keysyms = xcb_key_symbols_alloc(globalconf.connection);
    xcb_get_modifier_mapping_cookie_t xmapping_cookie =
        xcb_get_modifier_mapping_unchecked(globalconf.connection);

    /* init atom cache */
    atoms_init(globalconf.connection);

    /* init screens information */
    screen_scan();

    xutil_lock_mask_get(globalconf.connection, xmapping_cookie,
                        globalconf.keysyms, &globalconf.numlockmask,
                        &globalconf.shiftlockmask, &globalconf.capslockmask,
                        &globalconf.modeswitchmask);

    /* do this only for real screen */
    ewmh_init();
    systray_init();

    /* init spawn (sn) */
    spawn_init();

    /* The default GC is just a newly created associated with a window with
     * depth globalconf.default_depth */
    xcb_window_t tmp_win = xcb_generate_id(globalconf.connection);
    globalconf.gc = xcb_generate_id(globalconf.connection);
    xcb_create_window(globalconf.connection, globalconf.default_depth,
                      tmp_win, globalconf.screen->root,
                      -1, -1, 1, 1, 0,
                      XCB_COPY_FROM_PARENT, globalconf.visual->visual_id,
                      XCB_CW_BACK_PIXEL | XCB_CW_BORDER_PIXEL | XCB_CW_COLORMAP,
                      (const uint32_t [])
    {
        globalconf.screen->black_pixel,
                          globalconf.screen->black_pixel,
                          globalconf.default_cmap
    });
    xcb_create_gc(globalconf.connection, globalconf.gc, tmp_win, XCB_GC_FOREGROUND | XCB_GC_BACKGROUND,
    (const uint32_t[]) {
        globalconf.screen->black_pixel, globalconf.screen->white_pixel
    });
    xcb_destroy_window(globalconf.connection, tmp_win);

    /* Get the window tree associated to this screen */
    tree_c = xcb_query_tree_unchecked(globalconf.connection,
                                      globalconf.screen->root);

    xcb_change_window_attributes(globalconf.connection,
                                 globalconf.screen->root,
                                 XCB_CW_EVENT_MASK,
                                 ROOT_WINDOW_EVENT_MASK);

    /* we will receive events, stop grabbing server */
    xcb_ungrab_server(globalconf.connection);

    /* Parse and run configuration file */
    if (!luaA_parserc(&xdg, confpath, true))
        fatal("couldn't find any rc file");

    p_delete(&confpath);

    xdgWipeHandle(&xdg);

    /* scan existing windows */
    scan(tree_c);

    xcb_flush(globalconf.connection);

    /* main event loop */
    ev_loop(globalconf.loop, 0);

    /* cleanup event loop */
    ev_ref(globalconf.loop);
    ev_check_stop(globalconf.loop, &xcheck);
    ev_ref(globalconf.loop);
    ev_prepare_stop(globalconf.loop, &a_refresh);
    ev_ref(globalconf.loop);
    ev_io_stop(globalconf.loop, &xio);

    awesome_atexit(false);

    return EXIT_SUCCESS;
}