#include "window.h"
#include "display.h"
#include "gettext.h"
+#include "time.h"
+#include "render.h"
#include <glib.h>
#include <stdio.h>
sc = display_screen_from_root(dpy, dev->event);
if (!sc) break;
w = screen_find_window(sc, dev->window);
- w->hide(w);
+ sc->window_hide(w);
screen_remove_window(sc, w);
break;
}
if (rev->parent == sc->super.root)
screen_add_window(sc, rev->window);
else {
- w->hide(w);
+ sc->window_hide(w);
screen_remove_window(sc, w);
}
break;
sc = display_screen_from_root(dpy, mev->event);
if (!sc) break;
w = screen_find_window(sc, mev->window);
- w->show(w);
+ sc->window_show(w);
break;
}
case XCB_UNMAP_NOTIFY:
sc = display_screen_from_root(dpy, mev->event);
if (!sc) break;
w = screen_find_window(sc, mev->window);
- w->hide(w);
+ sc->window_hide(w);
break;
}
default:
paint(d_display_t *dpy)
{
int i;
+ struct timeval now;
+ gettimeofday(&now, NULL);
+
for (i = 0; i < dpy->nscreens; ++i) {
d_screen_t *sc = display_screen_n(dpy, i);
- sc->paint(sc);
+ if (time_compare(&sc->next_repaint, &now) <= 0)
+ sc->screen_paint(sc);
}
}
}
}
+static void
+setup_functions(d_display_t *dpy)
+{
+ int i;
+
+ for (i = 0; i < dpy->nscreens; ++i) {
+ d_screen_t *sc = display_screen_n(dpy, i);
+ screen_setup_default_functions(sc);
+
+ /* these can be plugins.. */
+ render_init(sc);
+ }
+}
+
+static void
+cleanup_functions(d_display_t *dpy)
+{
+ int i;
+
+ for (i = 0; i < dpy->nscreens; ++i) {
+ d_screen_t *sc = display_screen_n(dpy, i);
+
+ /* these can be plugins.. */
+ render_free(sc);
+ }
+}
+
int
main(int argc, char **argv)
{
return 0;
}
+ setup_functions(dpy);
+
run(dpy);
+ cleanup_functions(dpy);
+
display_unref(dpy);
return 0;
}
#include "render.h"
+#include "screen.h"
#include <stdio.h>
+#include <stdlib.h>
#include <xcb/render.h>
-void render_paint_screen(struct d_screen *sc)
+#define PLUGIN_NAME "render"
+
+typedef struct {
+ void (*screen_paint)(d_screen_t *sc);
+} data_t;
+
+static void render_paint_screen(d_screen_t *sc);
+
+void
+render_init(d_screen_t *sc)
+{
+ data_t *d = malloc(sizeof(data_t));
+ d->screen_paint = sc->screen_paint;
+ screen_add_plugin_data(sc, PLUGIN_NAME, d);
+
+ sc->screen_paint = render_paint_screen;
+}
+
+void
+render_free(d_screen_t *sc)
+{
+ data_t *d = screen_find_plugin_data(sc, PLUGIN_NAME);
+ free(d);
+}
+
+static void
+render_paint_screen(d_screen_t *sc)
{
- (void)sc;
+ data_t *d = screen_find_plugin_data(sc, PLUGIN_NAME);
+
printf("painting\n");
+
+ /* call the function we replaced in the chain */
+ d->screen_paint(sc);
}
struct d_screen;
-void render_paint_screen(struct d_screen *sc);
+void render_init(struct d_screen *sc);
+void render_free(struct d_screen *sc);
#endif
#include "list.h"
#include "time.h"
#include "window.h"
-#include "render.h"
#include "gettext.h"
#include <string.h>
#include <stdlib.h>
static gboolean screen_init(d_screen_t *sc);
static xcb_timestamp_t screen_timestamp(d_screen_t *sc);
static void screen_add_existing_windows(d_screen_t *sc);
+static void screen_set_next_repaint(d_screen_t *sc);
gboolean
screen_register(struct d_display *dpy, int num, d_screen_t *sc)
xcb_window_hash(xcb_window_t *w) { return *w; }
static gboolean
-xcb_window_compare(xcb_window_t *w1, xcb_window_t *w2) { return *w1 == *w2; }
+xcb_window_equal(xcb_window_t *w1, xcb_window_t *w2) { return *w1 == *w2; }
static gboolean
screen_init(d_screen_t *sc)
xcb_change_window_attributes(sc->dpy->conn, sc->super.root,
XCB_CW_EVENT_MASK, &mask);
- /* use the render backend */
- sc->paint = render_paint_screen;
-
gettimeofday(&sc->next_repaint, NULL);
sc->winhash = g_hash_table_new((GHashFunc)xcb_window_hash,
- (GCompareFunc)xcb_window_compare);
+ (GEqualFunc)xcb_window_equal);
sc->stacking = list_new();
+ sc->plugin_data = g_hash_table_new_full((GHashFunc)g_str_hash,
+ (GEqualFunc)g_str_equal,
+ g_free, NULL);
return TRUE;
}
{
g_hash_table_unref(sc->winhash);
list_unref(sc->stacking);
+ g_hash_table_unref(sc->plugin_data);
}
void
printf("screen removed window 0x%x\n", w->id);
g_hash_table_remove(sc->winhash, &w->id);
- w->become_zombie(w);
+ sc->window_become_zombie(w);
window_unref(w);
}
list_remove(sc->stacking, w);
}
-void
+static void
screen_set_next_repaint(d_screen_t *sc)
{
gettimeofday(&sc->next_repaint, NULL);
/* add time for the refresh rate (60 hz) */
time_add(&sc->next_repaint, 1000000/60);
}
+
+void
+screen_setup_default_functions(d_screen_t *sc)
+{
+ sc->screen_paint = screen_set_next_repaint;
+ sc->window_show = window_show;
+ sc->window_hide = window_hide;
+ sc->window_become_zombie = window_become_zombie;
+
+}
+
+void
+screen_add_plugin_data(d_screen_t *sc, const char *key, void *data)
+{
+ char *skey = g_strdup(key);
+ g_hash_table_insert(sc->plugin_data, skey, data);
+}
+
+void*
+screen_find_plugin_data(d_screen_t *sc, const char *key)
+{
+ return g_hash_table_lookup(sc->plugin_data, key);
+}
+
+void
+screen_remove_plugin_data(d_screen_t *sc, const char *key)
+{
+ g_hash_table_remove(sc->plugin_data, key);
+}
GHashTable *winhash;
struct d_list *stacking;
+ GHashTable *plugin_data;
- void (*paint)(struct d_screen *sc);
+ void (*screen_paint)(struct d_screen *sc);
+ void (*window_show)(struct d_window *w);
+ void (*window_hide)(struct d_window *w);
+ void (*window_become_zombie)(struct d_window *w);
} d_screen_t;
/*! Tries to register on the screen given by @sc. If it succeeds, it fills
void screen_stacking_add(d_screen_t *sc, struct d_window *w);
void screen_stacking_remove(d_screen_t *sc, struct d_window *w);
-void screen_set_next_repaint(d_screen_t *sc);
+void screen_setup_default_functions(d_screen_t *sc);
+
+void screen_add_plugin_data(d_screen_t *sc, const char *key, void *data);
+void* screen_find_plugin_data(d_screen_t *sc, const char *key);
+void screen_remove_plugin_data(d_screen_t *sc, const char *key);
#endif
#include <stdlib.h>
#include <stdio.h>
-static void window_show(d_window_t *w);
-static void window_hide(d_window_t *w);
-
-static void window_become_zombie(d_window_t *w);
-
d_window_t*
window_new(xcb_window_t id, struct d_screen *sc)
{
w->sc = sc;
w->mapped = FALSE;
w->zombie = FALSE;
-
- /* default functions */
- w->show = window_show;
- w->hide = window_hide;
- w->become_zombie = window_become_zombie;
+ w->opacity = WINDOW_OPACITY_MAX;
screen_stacking_add(sc, w);
}
}
-static void
+void
window_show(d_window_t *w)
{
if (w->mapped) return;
w->mapped = TRUE;
}
-static void
+void
window_hide(d_window_t *w)
{
if (!w->mapped) return;
w->mapped = FALSE;
}
-static void
+void
window_become_zombie(d_window_t *w)
{
if (w->zombie) return;
struct d_screen;
+#define WINDOW_OPACITY_MAX 100
+#define WINDOW_OPACITY_MIN 0
+
typedef struct d_window {
xcb_window_t id;
int ref;
gboolean mapped;
gboolean zombie;
- void (*show)(struct d_window *w);
- void (*hide)(struct d_window *w);
- void (*become_zombie)(struct d_window *w);
+ int opacity;
} d_window_t;
d_window_t* window_new(xcb_window_t id, struct d_screen *sc);
void window_ref(d_window_t *w);
void window_unref(d_window_t *w);
+void window_show(d_window_t *w);
+void window_hide(d_window_t *w);
+
+void window_become_zombie(d_window_t *w);
+
#endif