And migrate the rest of the loop to the libev.

Signed-off-by: Pierre Habouzit <madcoder@debian.org>
This commit is contained in:
Pierre Habouzit 2008-06-17 00:30:53 +02:00
parent 476c851510
commit 9ea15fd224
5 changed files with 88 additions and 80 deletions

147
awesome.c
View File

@ -22,20 +22,12 @@
#define _GNU_SOURCE #define _GNU_SOURCE
#include <getopt.h> #include <getopt.h>
#include <errno.h>
#include <locale.h> #include <locale.h>
#include <stdio.h> #include <stdio.h>
#include <unistd.h> #include <unistd.h>
#include <sys/select.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <fcntl.h>
#include <signal.h> #include <signal.h>
#include <glib.h>
#include <ev.h> #include <ev.h>
#include <xcb/xcb.h> #include <xcb/xcb.h>
#include <xcb/shape.h> #include <xcb/shape.h>
#include <xcb/randr.h> #include <xcb/randr.h>
@ -61,8 +53,6 @@
#include "common/xutil.h" #include "common/xutil.h"
#include "config.h" #include "config.h"
bool running = true;
awesome_t globalconf; awesome_t globalconf;
typedef struct typedef struct
@ -168,6 +158,45 @@ scan(void)
p_delete(&root_wins); p_delete(&root_wins);
} }
static void
a_xcb_check_cb(EV_P_ ev_check *w, int revents)
{
xcb_generic_event_t *ev;
while((ev = xcb_poll_for_event(globalconf.connection)))
{
do
{
xcb_handle_event(globalconf.evenths, ev);
/* need to resync */
xcb_aux_sync(globalconf.connection);
p_delete(&ev);
} while((ev = xcb_poll_for_event(globalconf.connection)));
layout_refresh();
statusbar_refresh();
/* need to resync */
xcb_aux_sync(globalconf.connection);
}
layout_refresh();
statusbar_refresh();
xcb_aux_sync(globalconf.connection);
}
static void
a_xcb_io_cb(EV_P_ ev_io *w, int revents)
{
/* Two level polling:
* We need to first check we have an event to handle
* and if so, we handle them all in a round.
* Then when we have refresh()'ed stuff so maybe new XEvent
* are available and select() won't tell us, so let's check
* with xcb_poll_for_event() again.
*/
/* empty */
}
/** Startup Error handler to check if another window manager /** Startup Error handler to check if another window manager
* is already running. * is already running.
* \param data Additional optional parameters data * \param data Additional optional parameters data
@ -186,9 +215,9 @@ xerrorstart(void * data __attribute__ ((unused)),
* \param sig the signal received, unused * \param sig the signal received, unused
*/ */
static void static void
exit_on_signal(int sig __attribute__ ((unused))) exit_on_signal(EV_P_ ev_signal *w, int revents)
{ {
running = false; ev_unloop(EV_A_ 1);
} }
/** \brief awesome xerror function /** \brief awesome xerror function
@ -262,10 +291,7 @@ main(int argc, char **argv)
int xfd, i, screen_nbr, opt; int xfd, i, screen_nbr, opt;
ssize_t cmdlen = 1; ssize_t cmdlen = 1;
const xcb_query_extension_reply_t *shape_query, *randr_query; const xcb_query_extension_reply_t *shape_query, *randr_query;
fd_set rd;
xcb_generic_event_t *ev;
client_t *c; client_t *c;
struct timeval select_timeout, hook_lastrun = { 0, 0 }, now, hook_nextrun;
static struct option long_options[] = static struct option long_options[] =
{ {
{"help", 0, NULL, 'h'}, {"help", 0, NULL, 'h'},
@ -274,6 +300,13 @@ main(int argc, char **argv)
{NULL, 0, NULL, 0} {NULL, 0, NULL, 0}
}; };
/* event loop watchers */
ev_io xio = { .fd = -1 };
ev_check xcheck;
ev_signal sigint;
ev_signal sigterm;
ev_signal sighup;
/* clear the globalconf structure */ /* clear the globalconf structure */
p_clear(&globalconf, 1); p_clear(&globalconf, 1);
globalconf.keygrabber = LUA_REFNIL; globalconf.keygrabber = LUA_REFNIL;
@ -312,6 +345,19 @@ main(int argc, char **argv)
/* Text won't be printed correctly otherwise */ /* Text won't be printed correctly otherwise */
setlocale(LC_CTYPE, ""); setlocale(LC_CTYPE, "");
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, &exit_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);
/* X stuff */ /* X stuff */
globalconf.connection = xcb_connect(NULL, &globalconf.default_screen); globalconf.connection = xcb_connect(NULL, &globalconf.default_screen);
@ -320,6 +366,12 @@ main(int argc, char **argv)
/* Get the file descriptor corresponding to the X connection */ /* Get the file descriptor corresponding to the X connection */
xfd = xcb_get_file_descriptor(globalconf.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_unref(globalconf.loop);
ev_check_init(&xcheck, &a_xcb_check_cb);
ev_check_start(globalconf.loop, &xcheck);
ev_unref(globalconf.loop);
/* Allocate a handler which will holds all errors and events */ /* Allocate a handler which will holds all errors and events */
globalconf.evenths = xcb_alloc_event_handlers(globalconf.connection); globalconf.evenths = xcb_alloc_event_handlers(globalconf.connection);
@ -457,71 +509,18 @@ main(int argc, char **argv)
luaA_cs_init(); luaA_cs_init();
a_dbus_init(); a_dbus_init();
/* register function for signals */
signal(SIGINT, &exit_on_signal);
signal(SIGTERM, &exit_on_signal);
signal(SIGHUP, &exit_on_signal);
/* refresh everything before waiting events */ /* refresh everything before waiting events */
layout_refresh(); layout_refresh();
statusbar_refresh(); statusbar_refresh();
/* main event loop */ /* main event loop */
while(running) ev_loop(globalconf.loop, 0);
{
FD_ZERO(&rd);
FD_SET(xfd, &rd);
if(timerisset(&globalconf.timer))
{
gettimeofday(&now, NULL);
timeradd(&hook_lastrun, &globalconf.timer, &hook_nextrun);
/* Need to do 2 tests, <= does not work with timercmp() */
if(timercmp(&hook_nextrun, &now, <) || (timercmp(&hook_nextrun, &now, ==)))
{
gettimeofday(&hook_lastrun, NULL);
luaA_dofunction(globalconf.L, globalconf.hooks.timer, 0);
select_timeout = globalconf.timer;
}
else
timersub(&hook_nextrun, &now, &select_timeout);
}
if(select(xfd + 1, &rd,
NULL, NULL,
timerisset(&globalconf.timer) ? &select_timeout : NULL) == -1)
{
if(errno == EINTR)
continue;
eprint("select failed");
}
/* Two level polling:
* We need to first check we have an event to handle
* and if so, we handle them all in a round.
* Then when we have refresh()'ed stuff so maybe new XEvent
* are available and select() won't tell us, so let's check
* with xcb_poll_for_event() again.
*/
while((ev = xcb_poll_for_event(globalconf.connection)))
{
do
{
xcb_handle_event(globalconf.evenths, ev);
/* need to resync */
xcb_aux_sync(globalconf.connection);
p_delete(&ev);
} while((ev = xcb_poll_for_event(globalconf.connection)));
layout_refresh();
statusbar_refresh();
/* need to resync */
xcb_aux_sync(globalconf.connection);
}
layout_refresh();
statusbar_refresh();
xcb_aux_sync(globalconf.connection);
}
/* cleanup event loop */
ev_ref(globalconf.loop);
ev_check_stop(globalconf.loop, &xcheck);
ev_ref(globalconf.loop);
ev_io_stop(globalconf.loop, &xio);
a_dbus_cleanup(); a_dbus_cleanup();
luaA_cs_cleanup(); luaA_cs_cleanup();

13
lua.c
View File

@ -46,7 +46,6 @@
extern awesome_t globalconf; extern awesome_t globalconf;
extern bool running;
extern const name_func_link_t FloatingPlacementList[]; extern const name_func_link_t FloatingPlacementList[];
extern const struct luaL_reg awesome_keygrabber_lib[]; extern const struct luaL_reg awesome_keygrabber_lib[];
@ -108,7 +107,7 @@ luaA_floating_placement_set(lua_State *L)
static int static int
luaA_quit(lua_State *L __attribute__ ((unused))) luaA_quit(lua_State *L __attribute__ ((unused)))
{ {
running = false; ev_unloop(globalconf.loop, 1);
return 0; return 0;
} }
@ -378,8 +377,7 @@ luaA_hooks_urgent(lua_State *L)
static int static int
luaA_hooks_timer(lua_State *L) luaA_hooks_timer(lua_State *L)
{ {
globalconf.timer.tv_usec = 0; globalconf.timer.repeat = luaL_checknumber(L, 1);
globalconf.timer.tv_sec = luaL_checknumber(L, 1);
if(lua_gettop(L) == 2 && !lua_isnil(L, 2)) if(lua_gettop(L) == 2 && !lua_isnil(L, 2))
{ {
@ -389,6 +387,7 @@ luaA_hooks_timer(lua_State *L)
globalconf.hooks.timer = luaL_ref(L, LUA_REGISTRYINDEX); globalconf.hooks.timer = luaL_ref(L, LUA_REGISTRYINDEX);
} }
ev_timer_again(globalconf.loop, &globalconf.timer);
return 0; return 0;
} }
@ -649,3 +648,9 @@ luaA_cs_cleanup(void)
p_delete(&addr); p_delete(&addr);
csio.fd = -1; csio.fd = -1;
} }
void
luaA_on_timer(EV_P_ ev_timer *w, int revents)
{
luaA_dofunction(globalconf.L, globalconf.hooks.timer, 0);
}

2
lua.h
View File

@ -22,6 +22,7 @@
#ifndef AWESOME_LUA_H #ifndef AWESOME_LUA_H
#define AWESOME_LUA_H #define AWESOME_LUA_H
#include <ev.h>
#include <lua.h> #include <lua.h>
#include <lauxlib.h> #include <lauxlib.h>
@ -173,6 +174,7 @@ bool luaA_parserc(const char *);
void luaA_pushpointer(void *, awesome_type_t); void luaA_pushpointer(void *, awesome_type_t);
void luaA_cs_init(void); void luaA_cs_init(void);
void luaA_cs_cleanup(void); void luaA_cs_cleanup(void);
void luaA_on_timer(EV_P_ ev_timer *w, int revents);
#endif #endif
// vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80 // vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80

View File

@ -29,7 +29,6 @@
#include "window.h" #include "window.h"
extern awesome_t globalconf; extern awesome_t globalconf;
extern bool running;
/** Draw a statusbar. /** Draw a statusbar.
* \param statusbar The statusbar to draw. * \param statusbar The statusbar to draw.

View File

@ -23,6 +23,7 @@
#define AWESOME_STRUCTS_H #define AWESOME_STRUCTS_H
#include <xcb/xcb_event.h> #include <xcb/xcb_event.h>
#include <ev.h>
#include "lua.h" #include "lua.h"
#include "layout.h" #include "layout.h"
@ -461,8 +462,10 @@ struct awesome_t
/** Command to run on time */ /** Command to run on time */
luaA_function timer; luaA_function timer;
} hooks; } hooks;
/** The event loop */
struct ev_loop *loop;
/** The timeout after which we need to stop select() */ /** The timeout after which we need to stop select() */
struct timeval timer; struct ev_timer timer;
/** The key grabber function */ /** The key grabber function */
luaA_function keygrabber; luaA_function keygrabber;
}; };