setting up architecture for plugins. have a render-based drawer that doesn't do...
authorDana Jansens <danakj@orodu.net>
Wed, 5 Mar 2008 00:02:01 +0000 (19:02 -0500)
committerDana Jansens <danakj@orodu.net>
Wed, 5 Mar 2008 00:02:01 +0000 (19:02 -0500)
dcompmgr.c
render.c
render.h
screen.c
screen.h
window.c
window.h

index 40d983a..2145dcb 100644 (file)
@@ -2,6 +2,8 @@
 #include "window.h"
 #include "display.h"
 #include "gettext.h"
+#include "time.h"
+#include "render.h"
 
 #include <glib.h>
 #include <stdio.h>
@@ -56,7 +58,7 @@ event(d_display_t *dpy)
             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;
         }
@@ -73,7 +75,7 @@ event(d_display_t *dpy)
             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;
@@ -88,7 +90,7 @@ event(d_display_t *dpy)
             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:
@@ -101,7 +103,7 @@ event(d_display_t *dpy)
             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:
@@ -115,11 +117,15 @@ static void
 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);
     }
 }
 
@@ -158,6 +164,33 @@ run(d_display_t *dpy)
     }
 }
 
+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)
 {
@@ -205,8 +238,12 @@ main(int argc, char **argv)
         return 0;
     }
 
+    setup_functions(dpy);
+
     run(dpy);
 
+    cleanup_functions(dpy);
+
     display_unref(dpy);
     return 0;
 }
index 9d1ba92..f25ddc0 100644 (file)
--- a/render.c
+++ b/render.c
@@ -1,9 +1,41 @@
 #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);
 }
index 128b8c0..3ea2ad7 100644 (file)
--- a/render.h
+++ b/render.h
@@ -3,6 +3,7 @@
 
 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
index cbaf13a..55ee082 100644 (file)
--- a/screen.c
+++ b/screen.c
@@ -3,7 +3,6 @@
 #include "list.h"
 #include "time.h"
 #include "window.h"
-#include "render.h"
 #include "gettext.h"
 #include <string.h>
 #include <stdlib.h>
@@ -19,6 +18,7 @@
 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)
@@ -87,7 +87,7 @@ static guint
 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)
@@ -133,14 +133,14 @@ 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;
 }
@@ -149,6 +149,7 @@ void screen_free(d_screen_t *sc)
 {
     g_hash_table_unref(sc->winhash);
     list_unref(sc->stacking);
+    g_hash_table_unref(sc->plugin_data);
 }
 
 void
@@ -190,7 +191,7 @@ screen_remove_window(d_screen_t *sc, struct d_window *w)
     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);
 }
 
@@ -249,10 +250,39 @@ screen_stacking_remove(d_screen_t *sc, struct d_window *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);
+}
index 1e442f5..2af3c98 100644 (file)
--- a/screen.h
+++ b/screen.h
@@ -24,8 +24,12 @@ typedef struct d_screen {
 
     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
@@ -42,6 +46,10 @@ struct d_window* screen_find_window(d_screen_t *sc, xcb_window_t id);
 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
index 83efdf3..9ba6bfd 100644 (file)
--- a/window.c
+++ b/window.c
@@ -3,11 +3,6 @@
 #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)
 {
@@ -19,11 +14,7 @@ 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);
 
@@ -47,7 +38,7 @@ window_unref(d_window_t *w)
     }
 }
 
-static void
+void
 window_show(d_window_t *w)
 {
     if (w->mapped) return;
@@ -57,7 +48,7 @@ window_show(d_window_t *w)
     w->mapped = TRUE;
 }
 
-static void
+void
 window_hide(d_window_t *w)
 {
     if (!w->mapped) return;
@@ -67,7 +58,7 @@ window_hide(d_window_t *w)
     w->mapped = FALSE;
 }
 
-static void
+void
 window_become_zombie(d_window_t *w)
 {
     if (w->zombie) return;
index 33542ba..07e80dc 100644 (file)
--- a/window.h
+++ b/window.h
@@ -6,6 +6,9 @@
 
 struct d_screen;
 
+#define WINDOW_OPACITY_MAX 100
+#define WINDOW_OPACITY_MIN 0
+
 typedef struct d_window {
     xcb_window_t     id;
     int              ref;
@@ -14,9 +17,7 @@ typedef struct d_window {
     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);
@@ -24,4 +25,9 @@ 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