[AD] 4.3 graphic drivers

[ Thread Index | Date Index | More lists.liballeg.org/allegro-developers Archives ]


A while back there was a big discussion on allegro.cc on the merits and 
lack thereof for using vtables and miscellaneous other issues (personally 
I think vtables are good and a powerful tool if used properly).
Anyway, Thomas Harte suggested that it would be a good idea to have 
functions for creating drivers and setting vtable functions at run time 
(relevant post: 
http://www.allegro.cc/forums/view_thread.php?_id=531456#target).

Not only will this make it easier for addon writers to write and maintain 
code (because nothing gets broken if the driver struct is never touched 
directly and we change the struct), it's also going to be easier for us.
Right now if we add a function to the vtable all sourcefiles on all 
platforms need to be edited, which is error-prone and can lead to 
oversights.

Attached is a proof-of-concept patch against current new_api_branch. There 
are some things that need to be worked out and rewritten for this to work 
elegantly but so far I already find this useful. I was able to permute the 
vtable entries and recompile without breaking anything (as long as I used 
the X11 driver). I think it would be good to have a system like this.

Thoughts/suggestions?

Evert
Index: include/allegro/base.h
===================================================================
RCS file: /cvsroot/alleg/allegro/include/allegro/base.h,v
retrieving revision 1.26.2.12
diff -u -r1.26.2.12 base.h
--- include/allegro/base.h	7 Nov 2005 04:18:09 -0000	1.26.2.12
+++ include/allegro/base.h	9 Nov 2005 17:30:46 -0000
@@ -49,9 +49,9 @@
 AL_BEGIN_EXTERN_C
 
 #define ALLEGRO_VERSION          4
-#define ALLEGRO_SUB_VERSION      2
+#define ALLEGRO_SUB_VERSION      3
 #define ALLEGRO_WIP_VERSION      0
-#define ALLEGRO_VERSION_STR      "4.2.0 (RC3-CVS)"
+#define ALLEGRO_VERSION_STR      "4.3.0 (CVS)"
 #define ALLEGRO_DATE_STR         "2005"
 #define ALLEGRO_DATE             20050828    /* yyyymmdd */
 
Index: include/allegro/display.h
===================================================================
RCS file: /cvsroot/alleg/allegro/include/allegro/Attic/display.h,v
retrieving revision 1.1.2.2
diff -u -r1.1.2.2 display.h
--- include/allegro/display.h	15 May 2005 13:05:32 -0000	1.1.2.2
+++ include/allegro/display.h	9 Nov 2005 17:30:46 -0000
@@ -53,8 +53,89 @@
    int gfx_capabilities;      /* Driver capabilities */
 } AL_DISPLAY;
 
+/* Do we want a new type for the new display drivers? Or is this overkill? */
+typedef GFX_DRIVER AL_DISPLAY_DRIVER;
+
+/* FIXME: get rid of global variables! */
 AL_VAR(AL_DISPLAY *, al_main_display);
 
+/* Display driver access, for addon libraries. Should probably not be in a 
+ *  public header file but in an internal header.
+ *
+ * These functions allow the creation and modification of graphic drivers
+ *  on the fly (eg, for extension libraries but they also make the code
+ *  easier to maintain).
+ *
+ * AL_DISPLAY_DRIVER *al_new_display_driver(void)
+ *    Allocates a new (dummy) display driver that does nothing
+ *
+ * void al_set_driver_name(AL_DISPLAY_DRIVER *drv, const char *name)
+ *    Sets the (display) name (ID?) of the driver
+ *
+ * void al_set_driver_info(AL_DISPLAY_DRIVER *drv, int w, int h, int linear, long vid_mem, int windowed)
+ * void al_get_driver_info(const AL_DISPLAY_DRIVER *drv, int *w, int *h, int *linear, long *vid_mem, int *windowed)
+ *    Get or set information about the driver: width/height of the display,
+ *    is the video memory is linear or not, if the driver is a window or a 
+ *    fullscreen driver and the amount of video memory.
+ *
+ * int al_set_driver_function(AL_DISPLAY_DRIVER *drv, int function_id, const void *function)
+ *    Sets a vtable function entry. Returns 0 on succes and non-zero codes
+ *    on failure.
+ *
+ * Function IDs and prototypes:
+ *
+ * AL_DPYDRV_INIT  - BITMAP *init(int w, int h, int v_w, int v_h, int color_depth)
+ * AL_DPYDRV_EXIT  - void exit(struct BITMAP *b)
+ * AL_DPYDRV_SCROLL  - int scroll(int x, int y)
+ * AL_DPYDRV_VSYNC - void vsync(void)
+ * AL_DPYDRV_SET_PALETTE  - void set_palette(AL_CONST struct RGB *p, int from, int to, int retracesync)
+ * AL_DPYDRV_ENABLE_TRIPLE_BUFFER - void enable_triple_buffer(void)
+ * AL_DPYDRV_CREATE_VIDEO_BITMAP - BITMAP *create_video_bitmap(int width, int height)
+ * AL_DPYDRV_DESTROY_VIDEO_BITMAP - void destroy_video_bitmap(struct BITMAP *bitmap)
+ * AL_DPYDRV_SHOW_VIDEO_BITMAP - int show_video_bitmap(struct BITMAP *bitmap)
+ * AL_DPYDRV_REQUEST_VIDEO_BITMAP - int request_video_bitmap(struct BITMAP *bitmap)
+ * AL_DPYDRV_CREATE_SYSTEM_BITMAP - BITMAP *create_system_bitmap(int width, int height)
+ * AL_DPYDRV_DESTROY_SYSTEM_BITMAP - void destroy_system_bitmap(struct BITMAP *bitmap)
+ * AL_DPYDRV_SET_MOUSE_SPRITE - int set_mouse_sprite(struct BITMAP *sprite, int xfocus, int yfocus)
+ * AL_DPYDRV_SHOW_MOUSE - int show_mouse(struct BITMAP *bmp, int x, int y)
+ * AL_DPYDRV_HIDE_MOUSE - void hide_mouse(void)
+ * AL_DPYDRV_MOVE_MOUSE - void move_mouse(int x, int y)
+ * AL_DPYDRV_DRAWING_MODE - void drawing_mode(void)
+ * AL_DPYDRV_SAVE_VIDEO_STATE - void save_video_state(void)
+ * AL_DPYDRV_RESTORE_VIDEO_STATE - void restore_video_state(void)
+ * AL_DPYDRV_SET_BLENDER_MODE - void set_blender_mode(int mode, int r, int g, int b, int a)
+ * AL_DPYDRV_FETCH_MODE_LIST - GFX_MODE_LIST *fetch_mode_list(void)
+ *
+ */  
+AL_FUNC(AL_DISPLAY_DRIVER *, al_new_display_driver, (void));
+AL_FUNC(void, al_set_driver_name, (AL_DISPLAY_DRIVER *drv, const char *name));
+AL_FUNC(void, al_set_driver_info, (AL_DISPLAY_DRIVER *drv, int w, int h, int linear, long vid_mem, int windowed));
+AL_FUNC(void, al_get_driver_info, (const AL_DISPLAY_DRIVER *drv, int *w, int *h, int *linear, long *vid_mem, int *windowed));
+AL_FUNC(int, al_set_driver_function, (AL_DISPLAY_DRIVER *drv, int function_id, const void *function));
+
+#define AL_DPYDRV_INIT                       0
+#define AL_DPYDRV_EXIT                       1
+#define AL_DPYDRV_SCROLL                     2
+#define AL_DPYDRV_VSYNC                      3
+#define AL_DPYDRV_SET_PALETTE                4
+#define AL_DPYDRV_ENABLE_TRIPLE_BUFFER       5
+#define AL_DPYDRV_CREATE_VIDEO_BITMAP        6
+#define AL_DPYDRV_DESTROY_VIDEO_BITMAP       7
+#define AL_DPYDRV_SHOW_VIDEO_BITMAP          8
+#define AL_DPYDRV_REQUEST_VIDEO_BITMAP       9
+#define AL_DPYDRV_CREATE_SYSTEM_BITMAP       10
+#define AL_DPYDRV_DESTROY_SYSTEM_BITMAP      11
+#define AL_DPYDRV_SET_MOUSE_SPRITE           12
+#define AL_DPYDRV_SHOW_MOUSE                 13
+#define AL_DPYDRV_HIDE_MOUSE                 14
+#define AL_DPYDRV_MOVE_MOUSE                 15
+#define AL_DPYDRV_DRAWING_MODE               16
+#define AL_DPYDRV_SAVE_VIDEO_STATE           17
+#define AL_DPYDRV_RESTORE_VIDEO_STATE        18
+#define AL_DPYDRV_SET_BLENDER_MODE           19
+#define AL_DPYDRV_FETCH_MODE_LIST            20
+
+
 AL_FUNC(BITMAP *, al_create_video_bitmap, (AL_DISPLAY *display, int width, int height));
 AL_FUNC(BITMAP *, al_create_system_bitmap, (AL_DISPLAY *display, int width, int height));
 
Index: src/display.c
===================================================================
RCS file: /cvsroot/alleg/allegro/src/Attic/display.c,v
retrieving revision 1.1.2.9
diff -u -r1.1.2.9 display.c
--- src/display.c	15 May 2005 20:31:34 -0000	1.1.2.9
+++ src/display.c	9 Nov 2005 17:30:51 -0000
@@ -1485,3 +1485,159 @@
    
    return (display->flags&AL_DISABLE_VSYNC) == 0;
 }
+
+
+
+/* Display driver accesor and run-time modification functions. */
+
+/* AL_DISPLAY_DRIVER *al_new_display_driver(void)
+ *    Allocates a new (dummy) display driver that does nothing
+ */
+AL_DISPLAY_DRIVER *al_new_display_driver(void)
+{
+   AL_DISPLAY_DRIVER *drv;
+   
+   drv = calloc(1, sizeof *drv);
+   
+   if (drv) {
+      drv->name = drv->ascii_name = "Dummy driver";
+      drv->desc = "Dummy NOP driver";
+   }
+   
+   return drv;
+}
+
+
+
+/*
+ * void al_set_driver_name(AL_DISPLAY_DRIVER *drv, const char *name)
+ *    Sets the (display) name (ID?) of the driver
+ *
+ */
+void al_set_driver_name(AL_DISPLAY_DRIVER *drv, const char *name)
+{
+   ASSERT(drv);
+   
+   /* FIXME: need proper Unicode version for the full name */
+   drv->name = name;
+   drv->ascii_name = name;
+   
+   /* Better description can't hurt either (but do we need it?) */
+   drv->desc = name;
+} 
+
+
+
+/* void al_set_driver_info(AL_DISPLAY_DRIVER *drv, int w, int h, int linear, long vid_mem, int windowed)
+ * Sets some information about the driver.
+ */
+void al_set_driver_info(AL_DISPLAY_DRIVER *drv, int w, int h, int linear, long vid_mem, int windowed)
+{
+   ASSERT(drv);
+   drv->w = w;
+   drv->h = h;
+   drv->linear = linear;
+   drv->vid_mem = vid_mem;
+   drv->windowed = windowed;
+}
+
+
+
+/* void al_get_driver_info(AL_DISPLAY_DRIVER *drv, int w, int h, int linear, long vid_mem, int windowed)
+ * Retrieve some information about the driver.
+ */
+void al_get_driver_info(const AL_DISPLAY_DRIVER *drv, int *w, int *h, int *linear, long *vid_mem, int *windowed)
+{
+   ASSERT(drv);
+   ASSERT(w);
+   ASSERT(h);
+   ASSERT(linear);
+   ASSERT(vid_mem);
+   ASSERT(windowed);
+
+   *w = drv->w;
+   *h = drv->h;
+   *linear = drv->linear;
+   *vid_mem = drv->vid_mem;
+   *windowed = drv->windowed;
+}
+
+
+
+/* int al_set_driver_function(AL_DISPLAY_DRIVER *drv, int function_id, const void *function)
+ *    Sets a vtable function entry. Returns 0 on succes and non-zero codes
+ *    on failure.
+ */
+int al_set_driver_function(AL_DISPLAY_DRIVER *drv, int function_id, const void *function)
+{
+   ASSERT(drv);
+   
+   switch (function_id) {
+      case AL_DPYDRV_INIT:
+         drv->init = function;
+         return 0;
+      case AL_DPYDRV_EXIT:
+         drv->exit = function;
+         return 0;
+      case AL_DPYDRV_SCROLL:
+         drv->scroll = function;
+         return 0;
+      case AL_DPYDRV_VSYNC:
+         drv->vsync = function;
+         return 0;
+      case AL_DPYDRV_SET_PALETTE:
+         drv->set_palette = function;
+         return 0;
+      case AL_DPYDRV_ENABLE_TRIPLE_BUFFER:
+         drv->enable_triple_buffer = function;
+         return 0;
+      case AL_DPYDRV_CREATE_VIDEO_BITMAP:
+         drv->create_video_bitmap = function;
+         return 0;
+      case AL_DPYDRV_DESTROY_VIDEO_BITMAP:
+         drv->destroy_video_bitmap = function;
+         return 0;
+      case AL_DPYDRV_SHOW_VIDEO_BITMAP:
+         drv->show_video_bitmap = function;
+         return 0;
+      case AL_DPYDRV_REQUEST_VIDEO_BITMAP:
+         drv->request_video_bitmap = function;
+         return 0;
+      case AL_DPYDRV_CREATE_SYSTEM_BITMAP:
+         drv->create_system_bitmap = function;
+         return 0;
+      case AL_DPYDRV_DESTROY_SYSTEM_BITMAP:
+         drv->destroy_system_bitmap = function;
+         return 0;
+      case AL_DPYDRV_SET_MOUSE_SPRITE:
+         drv->set_mouse_sprite = function;
+         return 0;
+      case AL_DPYDRV_SHOW_MOUSE:
+         drv->show_mouse = function;
+         return 0;
+      case AL_DPYDRV_HIDE_MOUSE:
+         drv->hide_mouse = function;
+         return 0;
+      case AL_DPYDRV_MOVE_MOUSE:
+         drv->move_mouse = function;
+         return 0;
+      case AL_DPYDRV_DRAWING_MODE:
+         drv->drawing_mode = function;
+         return 0;
+      case AL_DPYDRV_SAVE_VIDEO_STATE:
+         drv->save_video_state = function;
+         return 0;
+      case AL_DPYDRV_RESTORE_VIDEO_STATE:
+         drv->restore_video_state = function;
+         return 0;
+      case AL_DPYDRV_SET_BLENDER_MODE:
+         drv->set_blender_mode = function;
+         return 0;
+      case AL_DPYDRV_FETCH_MODE_LIST:
+         drv->fetch_mode_list = function;
+         return 0;
+   } /* switch (function_id) */
+   
+   /* Function not found */
+   return -1;
+}
Index: src/x/xgfxdrv.c
===================================================================
RCS file: /cvsroot/alleg/allegro/src/x/xgfxdrv.c,v
retrieving revision 1.14.2.3
diff -u -r1.14.2.3 xgfxdrv.c
--- src/x/xgfxdrv.c	7 Nov 2005 04:18:11 -0000	1.14.2.3
+++ src/x/xgfxdrv.c	9 Nov 2005 17:30:53 -0000
@@ -25,39 +25,7 @@
 static void _xwin_gfxdrv_exit(BITMAP *bmp);
 
 
-static GFX_DRIVER gfx_xwin =
-{
-   GFX_XWINDOWS,
-   empty_string,
-   empty_string,
-   "X11 window",
-   _xwin_gfxdrv_init,
-   _xwin_gfxdrv_exit,
-   _xwin_scroll_screen,
-   _xwin_vsync,
-   _xwin_set_palette_range,
-   NULL, NULL, NULL,
-   NULL, NULL, NULL, NULL,
-   NULL, NULL,
-#ifdef ALLEGRO_XWINDOWS_WITH_XCURSOR
-   _xwin_set_mouse_sprite,
-   _xwin_show_mouse,
-   _xwin_hide_mouse,
-   _xwin_move_mouse,
-#else
-   NULL, NULL, NULL, NULL,
-#endif
-   _xwin_drawing_mode,
-   NULL, NULL,
-   NULL,    // AL_METHOD(void, set_blender_mode, (int mode, int r, int g, int b, int a));
-   NULL,
-   320, 200,
-   TRUE,
-   0, 0,
-   0x10000,
-   0,
-   TRUE
-};
+static GFX_DRIVER gfx_xwin;
 
 
 
@@ -147,3 +115,24 @@
    return _xwin_create_screen(&gfx_xwin_fullscreen, w, h, vw, vh, color_depth, TRUE);
 }
 #endif
+
+void _xwin_create_display_drivers(void)
+{
+   /* This perhaps shouldn't be nescessary later on */
+   gfx_xwin.id = GFX_XWINDOWS;
+
+   al_set_driver_name(&gfx_xwin, empty_string);
+   al_set_driver_function(&gfx_xwin, AL_DPYDRV_INIT, _xwin_gfxdrv_init);
+   al_set_driver_function(&gfx_xwin, AL_DPYDRV_EXIT, _xwin_gfxdrv_exit);
+   al_set_driver_function(&gfx_xwin, AL_DPYDRV_VSYNC, _xwin_vsync);
+   al_set_driver_function(&gfx_xwin, AL_DPYDRV_SET_PALETTE, _xwin_set_palette_range);
+#ifdef ALLEGRO_XWINDOWS_WITH_XCURSOR
+   al_set_driver_function(&gfx_xwin, AL_DPYDRV_SET_MOUSE_SPRITE, _xwin_set_mouse_sprite);
+   al_set_driver_function(&gfx_xwin, AL_DPYDRV_SHOW_MOUSE, _xwin_show_mouse);
+   al_set_driver_function(&gfx_xwin, AL_DPYDRV_HIDE_MOUSE, _xwin_hide_mouse);
+   al_set_driver_function(&gfx_xwin, AL_DPYDRV_MOVE_MOUSE, _xwin_move_mouse);
+#endif
+   al_set_driver_function(&gfx_xwin, AL_DPYDRV_DRAWING_MODE, _xwin_drawing_mode);
+
+   al_set_driver_info(&gfx_xwin, 320, 200, TRUE, 0x10000, TRUE);
+}
Index: src/x/xsystem.c
===================================================================
RCS file: /cvsroot/alleg/allegro/src/x/xsystem.c,v
retrieving revision 1.27.2.9
diff -u -r1.27.2.9 xsystem.c
--- src/x/xsystem.c	14 Oct 2005 08:59:19 -0000	1.27.2.9
+++ src/x/xsystem.c	9 Nov 2005 17:30:53 -0000
@@ -151,7 +151,12 @@
    char tmp[256];
 
    _unix_read_os_type();
-
+   
+   /* Initialise the X11 display driver */
+   /* FIXME! */
+   extern void _xwin_create_display_drivers(void);
+   _xwin_create_display_drivers();
+   
    /* install emergency-exit signal handlers */
    old_sig_abrt = signal(SIGABRT, _xwin_signal_handler);
    old_sig_fpe  = signal(SIGFPE,  _xwin_signal_handler);


Mail converted by MHonArc 2.6.19+ http://listengine.tuxfamily.org/