Wrote platform-dependent dispatch code
[projects/chimara/chimara.git] / libchimara / dispatch.c
diff --git a/libchimara/dispatch.c b/libchimara/dispatch.c
new file mode 100644 (file)
index 0000000..b1f84da
--- /dev/null
@@ -0,0 +1,58 @@
+#include <libchimara/glk.h>
+#include "chimara-glk-private.h"
+#include "window.h"
+#include "stream.h"
+#include "fileref.h"
+
+extern GPrivate *glk_data_key;
+
+void 
+gidispatch_set_object_registry(gidispatch_rock_t (*regi)(void *obj, glui32 objclass), void (*unregi)(void *obj, glui32 objclass, gidispatch_rock_t objrock))
+{
+       ChimaraGlkPrivate *glk_data = g_private_get(glk_data_key);
+       winid_t win;
+    strid_t str;
+    frefid_t fref;
+    
+    glk_data->register_obj = regi;
+    glk_data->unregister_obj = unregi;
+    
+    if(glk_data->register_obj) 
+       {
+        /* It's now necessary to go through all existing objects, and register them. */
+        for(win = glk_window_iterate(NULL, NULL); win; win = glk_window_iterate(win, NULL))
+            win->disprock = (*glk_data->register_obj)(win, gidisp_Class_Window);
+        for(str = glk_stream_iterate(NULL, NULL); str; str = glk_stream_iterate(str, NULL))
+            str->disprock = (*glk_data->register_obj)(str, gidisp_Class_Stream);
+        for(fref = glk_fileref_iterate(NULL, NULL); fref; fref = glk_fileref_iterate(fref, NULL))
+            fref->disprock = (*glk_data->register_obj)(fref, gidisp_Class_Fileref);
+    }
+}
+
+gidispatch_rock_t 
+gidispatch_get_objrock(void *obj, glui32 objclass)
+{
+       switch(objclass) 
+       {
+               case gidisp_Class_Window:
+                       return ((winid_t)obj)->disprock;
+               case gidisp_Class_Stream:
+                       return ((strid_t)obj)->disprock;
+               case gidisp_Class_Fileref:
+                       return ((frefid_t)obj)->disprock;
+               default: 
+               {
+                       gidispatch_rock_t dummy;
+                       dummy.num = 0;
+                       return dummy;
+               }
+       }
+}
+
+void 
+gidispatch_set_retained_registry(gidispatch_rock_t (*regi)(void *array, glui32 len, char *typecode), void (*unregi)(void *array, glui32 len, char *typecode, gidispatch_rock_t objrock))
+{
+       ChimaraGlkPrivate *glk_data = g_private_get(glk_data_key);
+       glk_data->register_arr = regi;
+       glk_data->unregister_arr = unregi;
+}