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); } }
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); } }
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); }
/** * 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); }
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); }
/* 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; }
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); }
/* 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; }
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; }
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 }
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)); } }
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 */ }
/* 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(); }
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); } }
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); } }
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; }
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)); }
void uv_ref(uv_loop_t* loop) { ev_ref(loop->ev); }
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; }
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); }
void uv_ref() { ev_ref(EV_DEFAULT_UC); }
void uv__async_close(uv_async_t* handle) { ev_async_stop(handle->loop->ev, &handle->async_watcher); ev_ref(handle->loop->ev); }
static inline void ev_start (struct ev_loop *loop, W w, int active) { w->active = active; ev_ref (loop); }
/** 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; }
static PyObject * Loop_ref(Loop *self) { ev_ref(self->loop); Py_RETURN_NONE; }
/** 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; }