From 949a87877d267db3226e998eb4cfaecb77180292 Mon Sep 17 00:00:00 2001 From: handa Date: Thu, 27 May 2004 09:15:37 +0000 Subject: [PATCH] Include and "config.h". (free_frame): Call frame->driver->close instead of mwin__close_device. (DLOPEN_SHLIB_EXT): New macro. (MDeviceLibraryInterface): New type. (device_library_list): New variable. (register_device_library): New function. (null_device): New variable. (null_device_close, null_device_get_prop) (null_device_realize_face, null_device_free_realized_face): New function. (null_driver): New variable. (null_device_init, null_device_fini, null_device_open): New functions. (null_interface): New variable. (Mfreetype, Mdevice): Declare them. (m17n_init_win): Increment win_initialized. Initialize Mx, Mgd, Mfreetype, Mdevice, Mdisplay, Mscreen, Mdrawable, Mdevice, and Mwin__Close_Device. Register drivers for Mx and Mgd. (m17n_fini_win): Decremented win_initialized. Call "fini" function of all opened devices. Don't call mwin__fini. (Mdisplay, Mscreen, Mdrawable, Mdepth, Mwidget, Mcolormap): Declare them here. (mframe): Handle Mdevice key of PLIST. (mframe_get_prop): Call frame->device->get_prop instead of mwin__device_get_prop. --- src/m17n-gui.c | 260 ++++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 243 insertions(+), 17 deletions(-) diff --git a/src/m17n-gui.c b/src/m17n-gui.c index d81b891..a3f5620 100644 --- a/src/m17n-gui.c +++ b/src/m17n-gui.c @@ -64,7 +64,9 @@ #include #include #include +#include +#include "config.h" #include "m17n-gui.h" #include "m17n-misc.h" #include "internal.h" @@ -76,49 +78,194 @@ static int win_initialized; +#ifndef DLOPEN_SHLIB_EXT +#define DLOPEN_SHLIB_EXT ".so" +#endif + +/** Information about a dynamic library supporting a specific graphic + device. */ +typedef struct +{ + /** Name of the dynamic library (e.g. "libm17n-X.so"). */ + char *library; + /** Handle fo the dynamic library. */ + void *handle; + /** Function to call just after loading the library. */ + int (*init) (); + /** Function to call to open a frame on the graphic device. */ + void *(*open) (MFrame *frame, MPlist *param); + /** Function to call just before unloading the library. */ + int (*fini) (); +} MDeviceLibraryInterface; + + +/** Plist of device symbol vs MDeviceLibraryInterface. */ + +static MPlist *device_library_list; + + +/** Close MFrame and free it. */ + static void free_frame (void *object) { MFrame *frame = (MFrame *) object; + (*frame->driver->close) (frame); M17N_OBJECT_UNREF (frame->face); - mwin__close_device ((MFrame *) object); free (frame->font); free (object); } + +/** Register a dynamic library of name LIB by a key NAME. */ + +static int +register_device_library (MSymbol name, char *lib) +{ + MDeviceLibraryInterface *interface; + + MSTRUCT_CALLOC (interface, MERROR_WIN); + interface->library = malloc (strlen (lib) + + strlen (DLOPEN_SHLIB_EXT) + 1); + sprintf (interface->library, "%s%s", lib, DLOPEN_SHLIB_EXT); + if (! device_library_list) + device_library_list = mplist (); + mplist_add (device_library_list, name, interface); + return 0; +} + + +#ifdef HAVE_FREETYPE +/** Null device support. */ + +static struct { + MPlist *realized_fontset_list; + MPlist *realized_font_list; + MPlist *realized_face_list; +} null_device; + +static void +null_device_close (MFrame *frame) +{ +} + +void * +null_device_get_prop (MFrame *frame, MSymbol key) +{ + return NULL; +} + +void +null_device_realize_face (MRealizedFace *rface) +{ + rface->info = NULL; +} + +void +null_device_free_realized_face (MRealizedFace *rface) +{ +} + +static MDeviceDriver null_driver = + { + null_device_close, + null_device_get_prop, + null_device_realize_face, + null_device_free_realized_face + }; + +static int +null_device_init () +{ + null_device.realized_fontset_list = mplist (); + null_device.realized_font_list = mplist (); + null_device.realized_face_list = mplist (); + return 0; +} + +static int +null_device_fini () +{ + MPlist *plist; + + MPLIST_DO (plist, null_device.realized_fontset_list) + mfont__free_realized_fontset ((MRealizedFontset *) MPLIST_VAL (plist)); + M17N_OBJECT_UNREF (null_device.realized_fontset_list); + + MPLIST_DO (plist, null_device.realized_face_list) + mface__free_realized ((MRealizedFace *) MPLIST_VAL (plist)); + M17N_OBJECT_UNREF (null_device.realized_face_list); + + MPLIST_DO (plist, null_device.realized_font_list) + mfont__free_realized ((MRealizedFont *) MPLIST_VAL (plist)); + M17N_OBJECT_UNREF (null_device.realized_font_list); + return 0; +} + +static void * +null_device_open (MFrame *frame, MPlist *param) +{ + frame->device_type = 0; + frame->driver = &null_driver; + frame->font_driver_list = mplist (); + mplist_add (frame->font_driver_list, Mfreetype, &mfont__ft_driver); + return &null_device; +} + +static MDeviceLibraryInterface null_interface = + { NULL, NULL, null_device_init, null_device_open, null_device_fini }; + +#endif /* Internal API */ +MSymbol Mfreetype; + /*** @} */ #endif /* !FOR_DOXYGEN || DOXYGEN_INTERNAL_MODULE */ /* External API */ +MSymbol Mdevice; + void m17n_init_win (void) { int mdebug_mask = MDEBUG_INIT; - if (win_initialized) + if (win_initialized++) return; m17n_init (); if (merror_code != MERROR_NONE) return; + MDEBUG_PUSH_TIME (); + + Mx = msymbol ("x"); + Mgd = msymbol ("gd"); + + Mfreetype = msymbol ("freetype"); Mfont = msymbol ("font"); Mfont_width = msymbol ("font-width"); Mfont_ascent = msymbol ("font-ascent"); Mfont_descent = msymbol ("font-descent"); + Mdevice = msymbol ("device"); + + Mdisplay = msymbol ("display"); + Mscreen = msymbol ("screen"); + Mdrawable = msymbol ("drawable"); + Mdepth = msymbol ("depth"); + Mwidget = msymbol ("widget"); + + register_device_library (Mx, "libm17n-X"); + register_device_library (Mgd, "libm17n-gd"); - MDEBUG_PUSH_TIME (); MDEBUG_PUSH_TIME (); if (mfont__init () < 0) goto err; MDEBUG_PRINT_TIME ("INIT", (stderr, " to initialize font module.")); - if (mwin__init () < 0) - goto err; MDEBUG_PRINT_TIME ("INIT", (stderr, " to initialize win module.")); if (mfont__fontset_init () < 0) goto err; @@ -133,7 +280,6 @@ m17n_init_win (void) goto err; MDEBUG_PRINT_TIME ("INIT", (stderr, " to initialize input-win module.")); mframe_default = NULL; - win_initialized = 1; err: MDEBUG_POP_TIME (); @@ -147,10 +293,31 @@ m17n_fini_win (void) { int mdebug_mask = MDEBUG_FINI; - if (win_initialized) + if (win_initialized > 1) + win_initialized--; + else { + MPlist *plist; + + win_initialized = 0; MDEBUG_PUSH_TIME (); MDEBUG_PUSH_TIME (); + MDEBUG_PRINT_TIME ("FINI", (stderr, " to finalize device modules.")); + MPLIST_DO (plist, device_library_list) + { + MDeviceLibraryInterface *interface = MPLIST_VAL (plist); + + if (interface->handle && interface->fini) + { + (*interface->fini) (); + dlclose (interface->handle); + } + free (interface->library); + free (interface); + } + M17N_OBJECT_UNREF (device_library_list); + if (null_interface.handle) + (*null_interface.fini) (); MDEBUG_PRINT_TIME ("FINI", (stderr, " to finalize input-gui module.")); minput__win_fini (); MDEBUG_PRINT_TIME ("FINI", (stderr, " to finalize draw module.")); @@ -159,15 +326,12 @@ m17n_fini_win (void) mface__fini (); MDEBUG_PRINT_TIME ("FINI", (stderr, " to finalize fontset module.")); mfont__fontset_fini (); - MDEBUG_PRINT_TIME ("FINI", (stderr, " to finalize window module.")); - mwin__fini (); MDEBUG_PRINT_TIME ("FINI", (stderr, " to finalize font module.")); mfont__fini (); mframe_default = NULL; MDEBUG_POP_TIME (); MDEBUG_PRINT_TIME ("FINI", (stderr, " to finalize the gui modules.")); MDEBUG_POP_TIME (); - win_initialized = 0; } m17n_fini (); } @@ -203,6 +367,28 @@ MSymbol Mfont_ascent; MSymbol Mfont_descent; /*=*/ + +/***en + @name Variables: Keys of frame parameter (X specific). + + These are the symbols to use as parameter keys for the function + mframe () (which see). They are also keys of a frame property + except for #Mwidget. */ +/***ja + @name ÊÑ¿ô¡§ ¥Õ¥ì¡¼¥à¥Ñ¥é¥á¡¼¥¿ÍÑ¥­¡¼ (X ¸ÇÍ­). + + ´Ø¿ô mframe () ¤Î¥Ñ¥é¥á¡¼¥¿¥­¡¼¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¥·¥ó¥Ü¥ë¡£( mframe + () ¤ÎÀâÌÀ»²¾È¡£) #Mwidget ¤ò½ü¤¤¤Æ¤Ï¥Õ¥ì¡¼¥à¥×¥í¥Ñ¥Æ¥£¤Î¥­¡¼¤Ç¤â¤¢ + ¤ë¡£ + */ + +/*=*/ + +MSymbol Mdisplay, Mscreen, Mdrawable, Mdepth, Mwidget, Mcolormap; + +MSymbol Mx, Mgd; + +/*=*/ /*** @} */ /*=*/ @@ -356,15 +542,57 @@ mframe (MPlist *plist) MFrame *frame; int plist_created = 0; MPlist *pl; + MSymbol device; + MDeviceLibraryInterface *interface; - M17N_OBJECT (frame, free_frame, MERROR_FRAME); - if (! plist) + if (plist) + { + pl = mplist_find_by_key (plist, Mdevice); + if (pl) + device = MPLIST_VAL (pl); + else + device = Mx; + } + else { plist = mplist (); plist_created = 1; + device = Mx; + } + + if (device == Mnil) + { + interface = &null_interface; + if (! interface->handle) + { + (*interface->init) (); + interface->handle = Mt; + } + } + else + { + interface = mplist_get (device_library_list, device); + if (! interface) + MERROR (MERROR_WIN, NULL); + if (! interface->handle) + { + interface->handle = dlopen (interface->library, RTLD_NOW); + if (! interface->handle) + MERROR (MERROR_WIN, NULL); + interface->init = dlsym (interface->handle, "device_init"); + interface->open = dlsym (interface->handle, "device_open"); + interface->fini = dlsym (interface->handle, "device_fini"); + if (! interface->init || ! interface->open || ! interface->fini + || (*interface->init) () < 0) + { + dlclose (interface->handle); + MERROR (MERROR_WIN, NULL); + } + } } - frame->device = mwin__open_device (frame, plist); - if (! frame->device) + + M17N_OBJECT (frame, free_frame, MERROR_FRAME); + if (! (frame->device = (*interface->open) (frame, plist))) { free (frame); MERROR (MERROR_WIN, NULL); @@ -375,8 +603,6 @@ mframe (MPlist *plist) if (MPLIST_KEY (pl) == Mface) mface_merge (frame->face, (MFace *) MPLIST_VAL (pl)); mface__update_frame_face (frame); - if (! frame->rface->rfont) - MERROR (MERROR_WIN, NULL); if (! mframe_default) mframe_default = frame; @@ -481,7 +707,7 @@ mframe_get_prop (MFrame *frame, MSymbol key) return (void *) (frame->ascent); if (key == Mfont_descent) return (void *) (frame->descent); - return mwin__device_get_prop (frame->device, key); + return (*frame->driver->get_prop) (frame, key); } /*=*/ -- 1.7.10.4