From: handa Date: Tue, 6 Jul 2004 11:36:45 +0000 (+0000) Subject: Cancel previous changes X-Git-Tag: REL-1-1-0~125 X-Git-Url: http://git.chise.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=78694746412ff04ee44865fab47793b9ea9d4bf8;p=m17n%2Fm17n-lib.git Cancel previous changes --- diff --git a/src/m17n-X.c b/src/m17n-X.c index 28a6c0e..ef46273 100644 --- a/src/m17n-X.c +++ b/src/m17n-X.c @@ -842,9 +842,9 @@ static void xft_render (MDrawWindow, int, int, MGlyphString *, MGlyph *, MGlyph *, int, MDrawRegion); MFontDriver xft_driver = - { NULL, /* Set to ft_select in mwin__init (). */ + { NULL, /* Set to ft_select in device_init (). */ xft_open, xft_find_metric, - NULL, /* Set to ft_encode_char in mwin__init (). */ + NULL, /* Set to ft_encode_char in device_init (). */ xft_render }; @@ -999,272 +999,6 @@ xft_render (MDrawWindow win, int x, int y, /* Functions for the device driver. */ -static int -mwin__device_init () -{ - M_iso8859_1 = msymbol ("iso8859-1"); - M_iso10646_1 = msymbol ("iso10646-1"); - - display_info_list = mplist (); - device_list = mplist (); - - Mxim = msymbol ("xim"); - msymbol_put (Mxim, Minput_driver, &minput_xim_driver); - - return 0; -} - -static int -mwin__device_fini () -{ - M17N_OBJECT_UNREF (display_info_list); - M17N_OBJECT_UNREF (device_list); - return 0; -} - -/** Return an MWDevice object corresponding to a display specified in - PLIST. - - It searches device_list for a device matching the display. If - found, return the found object. Otherwise, return a newly created - object. */ - -static int -mwin__open_device (MFrame *frame, MPlist *param) -{ - Display *display = NULL; - Screen *screen = NULL; - int screen_num; - Drawable drawable = 0; - Widget widget = NULL; - Colormap cmap = 0; - int auto_display = 0; - MDisplayInfo *disp_info = NULL; - MWDevice *device = NULL; - MSymbol key; - XWindowAttributes attr; - unsigned depth = 0; - MPlist *plist; - AppData app_data; - MFace *face; - - for (plist = param; (key = mplist_key (plist)) != Mnil; - plist = mplist_next (plist)) - { - if (key == Mdisplay) - display = (Display *) mplist_value (plist); - else if (key == Mscreen) - screen = mplist_value (plist); - else if (key == Mdrawable) - drawable = (Drawable) mplist_value (plist); - else if (key == Mdepth) - depth = (unsigned) mplist_value (plist); - else if (key == Mwidget) - widget = (Widget) mplist_value (plist); - else if (key == Mcolormap) - cmap = (Colormap) mplist_value (plist); - } - - if (widget) - { - display = XtDisplay (widget); - screen_num = XScreenNumberOfScreen (XtScreen (widget)); - depth = DefaultDepth (display, screen_num); - } - else if (drawable) - { - Window root_window; - int x, y; - unsigned width, height, border_width; - - if (! display) - MERROR (MERROR_WIN, -1); - XGetGeometry (display, drawable, &root_window, - &x, &y, &width, &height, &border_width, &depth); - XGetWindowAttributes (display, root_window, &attr); - screen_num = XScreenNumberOfScreen (attr.screen); - } - else - { - if (screen) - display = DisplayOfScreen (screen); - else - { - if (! display) - { - display = XOpenDisplay (NULL); - if (! display) - MERROR (MERROR_WIN, -1); - auto_display = 1; - } - screen = DefaultScreenOfDisplay (display); - } - screen_num = XScreenNumberOfScreen (screen); - if (! depth) - depth = DefaultDepth (display, screen_num); - } - - if (! cmap) - cmap = DefaultColormap (display, screen_num); - - for (plist = display_info_list; mplist_key (plist) != Mnil; - plist = mplist_next (plist)) - { - disp_info = (MDisplayInfo *) mplist_value (plist); - if (disp_info->display == display) - break; - } - - if (mplist_key (plist) != Mnil) - M17N_OBJECT_REF (disp_info); - else - { - M17N_OBJECT (disp_info, free_display_info, MERROR_WIN); - disp_info->display = display; - disp_info->auto_display = auto_display; - disp_info->font_registry_list = mplist (); - disp_info->iso8859_1_family_list = mplist (); - disp_info->iso10646_1_family_list = mplist (); - disp_info->realized_font_list = mplist (); - find_modifier_bits (disp_info); - mplist_add (display_info_list, Mt, disp_info); - } - - for (plist = device_list; mplist_key (plist) != Mnil; - plist = mplist_next (plist)) - { - device = (MWDevice *) mplist_value (plist); - if (device->display_info == disp_info - && device->depth == depth - && device->cmap == cmap) - break; - } - - if (mplist_key (plist) != Mnil) - M17N_OBJECT_REF (device); - else - { - unsigned long valuemask = GCForeground; - XGCValues values; - - M17N_OBJECT (device, free_device, MERROR_WIN); - device->display_info = disp_info; - device->screen_num = screen_num; - /* A drawable on which to create GCs. */ - device->drawable = XCreatePixmap (display, - RootWindow (display, screen_num), - 1, 1, depth); - device->depth = depth; - device->cmap = cmap; - device->realized_face_list = mplist (); - device->realized_fontset_list = mplist (); - device->gc_list = mplist (); - values.foreground = BlackPixel (display, screen_num); - device->scratch_gc = XCreateGC (display, device->drawable, - valuemask, &values); -#ifdef HAVE_XFT2 - device->xft_draw = XftDrawCreate (display, device->drawable, - DefaultVisual (display, screen_num), - cmap); -#endif - } - - frame->device = device; - frame->device_type = MDEVICE_SUPPORT_OUTPUT | MDEVICE_SUPPORT_INPUT; - frame->font_driver_list = mplist (); - mplist_add (frame->font_driver_list, Mx, &xfont_driver); -#ifdef HAVE_XFT2 - mplist_add (frame->font_driver_list, Mfreetype, &xft_driver); -#elif HAVE_FREETYPE - mplist_add (frame->font_driver_list, Mfreetype, &mfont__ft_driver); -#endif - frame->realized_font_list = disp_info->realized_font_list; - frame->realized_face_list = device->realized_face_list; - frame->realized_fontset_list = device->realized_fontset_list; - - if (widget) - { - XtResource resources[] = { - { XtNfont, XtCFont, XtRString, sizeof (String), - XtOffset (AppDataPtr, font), XtRString, DEFAULT_FONT }, - { XtNforeground, XtCForeground, XtRString, sizeof (String), - XtOffset (AppDataPtr, foreground), XtRString, "black" }, - { XtNbackground, XtCBackground, XtRString, sizeof (String), - XtOffset (AppDataPtr, background), XtRString, "white" }, - { XtNreverseVideo, XtCReverseVideo, XtRBoolean, sizeof (Boolean), - XtOffset (AppDataPtr, reverse_video), XtRImmediate, (caddr_t) FALSE } - }; - - XtGetApplicationResources (widget, &app_data, - resources, XtNumber (resources), NULL, 0); - frame->foreground = msymbol (app_data.foreground); - frame->background = msymbol (app_data.background); - frame->videomode = app_data.reverse_video == True ? Mreverse : Mnormal; - } - else - { - app_data.font = DEFAULT_FONT; - frame->foreground = msymbol ("black"); - frame->background = msymbol ("white"); - frame->videomode = Mnormal; - } - - { - int nfonts; - char **names = XListFonts (display, app_data.font, 1, &nfonts); - - if (nfonts > 0) - { - if (! (frame->font = mfont_parse_name (names[0], Mx))) - { - /* The font name does not conform to XLFD. Try to open the - font and get XA_FONT property. */ - XFontStruct *xfont = XLoadQueryFont (display, names[0]); - - nfonts = 0; - if (xfont) - { - unsigned long value; - char *name; - - if (XGetFontProperty (xfont, XA_FONT, &value) - && (name = ((char *) - XGetAtomName (display, (Atom) value)))) - { - if ((frame->font = mfont_parse_name (name, Mx))) - nfonts = 1; - } - XFreeFont (display, xfont); - } - } - XFreeFontNames (names); - } - if (! nfonts) - frame->font = mfont_parse_name (FALLBACK_FONT, Mx); - } - - face = mface_from_font (frame->font); - face->property[MFACE_FONTSET] = mfontset (NULL); - face->property[MFACE_FOREGROUND] = frame->foreground; - face->property[MFACE_BACKGROUND] = frame->background; - mface_put_prop (face, Mhline, mface_get_prop (mface__default, Mhline)); - mface_put_prop (face, Mbox, mface_get_prop (mface__default, Mbox)); - face->property[MFACE_VIDEOMODE] = frame->videomode; - mface_put_prop (face, Mhook_func, - mface_get_prop (mface__default, Mhook_func)); - face->property[MFACE_RATIO] = (void *) 100; - mplist_push (param, Mface, face); - M17N_OBJECT_UNREF (face); - -#ifdef X_SET_ERROR_HANDLER - XSetErrorHandler (x_error_handler); - XSetIOErrorHandler (x_io_error_handler); -#endif - - return 0; -} - - static void mwin__close_device (MFrame *frame) { @@ -1822,139 +1556,408 @@ mwin__adjust_window (MFrame *frame, MDrawWindow win, new->width = 1; values.width = current->width = new->width; } - if (current->height != new->height) + if (current->height != new->height) + { + mask |= CWHeight; + if (new->height <= 0) + new->height = 1; + values.height = current->height = new->height; + } + if (current->x != new->x) + { + mask |= CWX; + values.x = current->x = new->x; + } + if (current->y != new->y) + { + mask |= CWY; + current->y = new->y; + values.y = current->y = new->y; + } + if (mask) + XConfigureWindow (display, (Window) win, mask, &values); + XClearWindow (display, (Window) win); +} + +static MSymbol +mwin__parse_event (MFrame *frame, void *arg, int *modifiers) +{ + XEvent *event = (XEvent *) arg; + MDisplayInfo *disp_info = FRAME_DEVICE (frame)->display_info; + int len; + char buf[512]; + KeySym keysym; + MSymbol key; + + *modifiers = 0; + if (event->xany.type != KeyPress + /* && event->xany.type != KeyRelease */ + ) + return Mnil; + len = XLookupString ((XKeyEvent *) event, (char *) buf, 512, &keysym, NULL); + if (len > 1) + return Mnil; + if (len == 1) + { + int c = keysym; + + if (c < XK_space || c > XK_asciitilde) + c = buf[0]; + if ((c == ' ' || c == 127) && ((XKeyEvent *) event)->state & ShiftMask) + *modifiers |= MINPUT_KEY_SHIFT_MODIFIER; + if (((XKeyEvent *) event)->state & ControlMask) + { + if (c >= 'a' && c <= 'z') + c += 'A' - 'a'; + if (c >= ' ' && c < 127) + *modifiers |= MINPUT_KEY_CONTROL_MODIFIER; + } + key = minput__char_to_key (c); + } + else if (keysym >= XK_Shift_L && keysym <= XK_Hyper_R) + return Mnil; + else + { + char *str = XKeysymToString (keysym); + + if (! str) + return Mnil; + key = msymbol (str); + if (((XKeyEvent *) event)->state & ShiftMask) + *modifiers |= MINPUT_KEY_SHIFT_MODIFIER; + if (((XKeyEvent *) event)->state & ControlMask) + *modifiers |= MINPUT_KEY_CONTROL_MODIFIER; + } + if (((XKeyEvent *) event)->state & disp_info->meta_mask) + *modifiers |= MINPUT_KEY_META_MODIFIER; + if (((XKeyEvent *) event)->state & disp_info->alt_mask) + *modifiers |= MINPUT_KEY_ALT_MODIFIER; + if (((XKeyEvent *) event)->state & disp_info->super_mask) + *modifiers |= MINPUT_KEY_SUPER_MODIFIER; + if (((XKeyEvent *) event)->state & disp_info->hyper_mask) + *modifiers |= MINPUT_KEY_HYPER_MODIFIER; + + return key; +} + + +void +mwin__dump_gc (MFrame *frame, MRealizedFace *rface) +{ + unsigned long valuemask = GCForeground | GCBackground | GCClipMask; + XGCValues values; + Display *display = FRAME_DISPLAY (frame); + GCInfo *info = rface->info; + int i; + + for (i = 0; i <= GC_INVERSE; i++) + { + XGetGCValues (display, info->gc[i], valuemask, &values); + fprintf (stderr, "GC%d: fore/#%lX back/#%lX", i, + values.foreground, values.background); + fprintf (stderr, "\n"); + } +} + +static MDeviceDriver x_driver = + { + mwin__close_device, + mwin__device_get_prop, + mwin__realize_face, + mwin__free_realized_face, + mwin__fill_space, + mwin__draw_empty_boxes, + mwin__draw_hline, + mwin__draw_box, + mwin__draw_points, + mwin__region_from_rect, + mwin__union_rect_with_region, + mwin__intersect_region, + mwin__region_add_rect, + mwin__region_to_rect, + mwin__free_region, + mwin__dump_region, + mwin__create_window, + mwin__destroy_window, + mwin__map_window, + mwin__unmap_window, + mwin__window_geometry, + mwin__adjust_window, + mwin__parse_event + }; + +/* Functions to be stored in MDeviceLibraryInterface by dlsym (). */ + +int +device_init () +{ + M_iso8859_1 = msymbol ("iso8859-1"); + M_iso10646_1 = msymbol ("iso10646-1"); + + display_info_list = mplist (); + device_list = mplist (); + +#ifdef HAVE_XFT2 + xft_driver.select = mfont__ft_driver.select; + xft_driver.encode_char = mfont__ft_driver.encode_char; +#endif + + Mxim = msymbol ("xim"); + msymbol_put (Mxim, Minput_driver, &minput_xim_driver); + + return 0; +} + +int +device_fini () +{ + M17N_OBJECT_UNREF (display_info_list); + M17N_OBJECT_UNREF (device_list); + return 0; +} + +/** Return an MWDevice object corresponding to a display specified in + PLIST. + + It searches device_list for a device matching the display. If + found, return the found object. Otherwise, return a newly created + object. */ + +int +device_open (MFrame *frame, MPlist *param) +{ + Display *display = NULL; + Screen *screen = NULL; + int screen_num; + Drawable drawable = 0; + Widget widget = NULL; + Colormap cmap = 0; + int auto_display = 0; + MDisplayInfo *disp_info = NULL; + MWDevice *device = NULL; + MSymbol key; + XWindowAttributes attr; + unsigned depth = 0; + MPlist *plist; + AppData app_data; + MFace *face; + + for (plist = param; (key = mplist_key (plist)) != Mnil; + plist = mplist_next (plist)) + { + if (key == Mdisplay) + display = (Display *) mplist_value (plist); + else if (key == Mscreen) + screen = mplist_value (plist); + else if (key == Mdrawable) + drawable = (Drawable) mplist_value (plist); + else if (key == Mdepth) + depth = (unsigned) mplist_value (plist); + else if (key == Mwidget) + widget = (Widget) mplist_value (plist); + else if (key == Mcolormap) + cmap = (Colormap) mplist_value (plist); + } + + if (widget) + { + display = XtDisplay (widget); + screen_num = XScreenNumberOfScreen (XtScreen (widget)); + depth = DefaultDepth (display, screen_num); + } + else if (drawable) + { + Window root_window; + int x, y; + unsigned width, height, border_width; + + if (! display) + MERROR (MERROR_WIN, -1); + XGetGeometry (display, drawable, &root_window, + &x, &y, &width, &height, &border_width, &depth); + XGetWindowAttributes (display, root_window, &attr); + screen_num = XScreenNumberOfScreen (attr.screen); + } + else + { + if (screen) + display = DisplayOfScreen (screen); + else + { + if (! display) + { + display = XOpenDisplay (NULL); + if (! display) + MERROR (MERROR_WIN, -1); + auto_display = 1; + } + screen = DefaultScreenOfDisplay (display); + } + screen_num = XScreenNumberOfScreen (screen); + if (! depth) + depth = DefaultDepth (display, screen_num); + } + + if (! cmap) + cmap = DefaultColormap (display, screen_num); + + for (plist = display_info_list; mplist_key (plist) != Mnil; + plist = mplist_next (plist)) + { + disp_info = (MDisplayInfo *) mplist_value (plist); + if (disp_info->display == display) + break; + } + + if (mplist_key (plist) != Mnil) + M17N_OBJECT_REF (disp_info); + else { - mask |= CWHeight; - if (new->height <= 0) - new->height = 1; - values.height = current->height = new->height; - } - if (current->x != new->x) + M17N_OBJECT (disp_info, free_display_info, MERROR_WIN); + disp_info->display = display; + disp_info->auto_display = auto_display; + disp_info->font_registry_list = mplist (); + disp_info->iso8859_1_family_list = mplist (); + disp_info->iso10646_1_family_list = mplist (); + disp_info->realized_font_list = mplist (); + find_modifier_bits (disp_info); + mplist_add (display_info_list, Mt, disp_info); + } + + for (plist = device_list; mplist_key (plist) != Mnil; + plist = mplist_next (plist)) { - mask |= CWX; - values.x = current->x = new->x; + device = (MWDevice *) mplist_value (plist); + if (device->display_info == disp_info + && device->depth == depth + && device->cmap == cmap) + break; } - if (current->y != new->y) + + if (mplist_key (plist) != Mnil) + M17N_OBJECT_REF (device); + else { - mask |= CWY; - current->y = new->y; - values.y = current->y = new->y; + unsigned long valuemask = GCForeground; + XGCValues values; + + M17N_OBJECT (device, free_device, MERROR_WIN); + device->display_info = disp_info; + device->screen_num = screen_num; + /* A drawable on which to create GCs. */ + device->drawable = XCreatePixmap (display, + RootWindow (display, screen_num), + 1, 1, depth); + device->depth = depth; + device->cmap = cmap; + device->realized_face_list = mplist (); + device->realized_fontset_list = mplist (); + device->gc_list = mplist (); + values.foreground = BlackPixel (display, screen_num); + device->scratch_gc = XCreateGC (display, device->drawable, + valuemask, &values); +#ifdef HAVE_XFT2 + device->xft_draw = XftDrawCreate (display, device->drawable, + DefaultVisual (display, screen_num), + cmap); +#endif } - if (mask) - XConfigureWindow (display, (Window) win, mask, &values); - XClearWindow (display, (Window) win); -} -static MSymbol -mwin__parse_event (MFrame *frame, void *arg, int *modifiers) -{ - XEvent *event = (XEvent *) arg; - MDisplayInfo *disp_info = FRAME_DEVICE (frame)->display_info; - int len; - char buf[512]; - KeySym keysym; - MSymbol key; + frame->device = device; + frame->device_type = MDEVICE_SUPPORT_OUTPUT | MDEVICE_SUPPORT_INPUT; + frame->driver = &x_driver; + frame->font_driver_list = mplist (); + mplist_add (frame->font_driver_list, Mx, &xfont_driver); +#ifdef HAVE_XFT2 + mplist_add (frame->font_driver_list, Mfreetype, &xft_driver); +#elif HAVE_FREETYPE + mplist_add (frame->font_driver_list, Mfreetype, &mfont__ft_driver); +#endif + frame->realized_font_list = disp_info->realized_font_list; + frame->realized_face_list = device->realized_face_list; + frame->realized_fontset_list = device->realized_fontset_list; - *modifiers = 0; - if (event->xany.type != KeyPress - /* && event->xany.type != KeyRelease */ - ) - return Mnil; - len = XLookupString ((XKeyEvent *) event, (char *) buf, 512, &keysym, NULL); - if (len > 1) - return Mnil; - if (len == 1) + if (widget) { - int c = keysym; + XtResource resources[] = { + { XtNfont, XtCFont, XtRString, sizeof (String), + XtOffset (AppDataPtr, font), XtRString, DEFAULT_FONT }, + { XtNforeground, XtCForeground, XtRString, sizeof (String), + XtOffset (AppDataPtr, foreground), XtRString, "black" }, + { XtNbackground, XtCBackground, XtRString, sizeof (String), + XtOffset (AppDataPtr, background), XtRString, "white" }, + { XtNreverseVideo, XtCReverseVideo, XtRBoolean, sizeof (Boolean), + XtOffset (AppDataPtr, reverse_video), XtRImmediate, (caddr_t) FALSE } + }; - if (c < XK_space || c > XK_asciitilde) - c = buf[0]; - if ((c == ' ' || c == 127) && ((XKeyEvent *) event)->state & ShiftMask) - *modifiers |= MINPUT_KEY_SHIFT_MODIFIER; - if (((XKeyEvent *) event)->state & ControlMask) - { - if (c >= 'a' && c <= 'z') - c += 'A' - 'a'; - if (c >= ' ' && c < 127) - *modifiers |= MINPUT_KEY_CONTROL_MODIFIER; - } - key = minput__char_to_key (c); + XtGetApplicationResources (widget, &app_data, + resources, XtNumber (resources), NULL, 0); + frame->foreground = msymbol (app_data.foreground); + frame->background = msymbol (app_data.background); + frame->videomode = app_data.reverse_video == True ? Mreverse : Mnormal; } - else if (keysym >= XK_Shift_L && keysym <= XK_Hyper_R) - return Mnil; else { - char *str = XKeysymToString (keysym); - - if (! str) - return Mnil; - key = msymbol (str); - if (((XKeyEvent *) event)->state & ShiftMask) - *modifiers |= MINPUT_KEY_SHIFT_MODIFIER; - if (((XKeyEvent *) event)->state & ControlMask) - *modifiers |= MINPUT_KEY_CONTROL_MODIFIER; + app_data.font = DEFAULT_FONT; + frame->foreground = msymbol ("black"); + frame->background = msymbol ("white"); + frame->videomode = Mnormal; } - if (((XKeyEvent *) event)->state & disp_info->meta_mask) - *modifiers |= MINPUT_KEY_META_MODIFIER; - if (((XKeyEvent *) event)->state & disp_info->alt_mask) - *modifiers |= MINPUT_KEY_ALT_MODIFIER; - if (((XKeyEvent *) event)->state & disp_info->super_mask) - *modifiers |= MINPUT_KEY_SUPER_MODIFIER; - if (((XKeyEvent *) event)->state & disp_info->hyper_mask) - *modifiers |= MINPUT_KEY_HYPER_MODIFIER; - return key; -} + { + int nfonts; + char **names = XListFonts (display, app_data.font, 1, &nfonts); + if (nfonts > 0) + { + if (! (frame->font = mfont_parse_name (names[0], Mx))) + { + /* The font name does not conform to XLFD. Try to open the + font and get XA_FONT property. */ + XFontStruct *xfont = XLoadQueryFont (display, names[0]); -void -mwin__dump_gc (MFrame *frame, MRealizedFace *rface) -{ - unsigned long valuemask = GCForeground | GCBackground | GCClipMask; - XGCValues values; - Display *display = FRAME_DISPLAY (frame); - GCInfo *info = rface->info; - int i; + nfonts = 0; + if (xfont) + { + unsigned long value; + char *name; - for (i = 0; i <= GC_INVERSE; i++) - { - XGetGCValues (display, info->gc[i], valuemask, &values); - fprintf (stderr, "GC%d: fore/#%lX back/#%lX", i, - values.foreground, values.background); - fprintf (stderr, "\n"); - } -} + if (XGetFontProperty (xfont, XA_FONT, &value) + && (name = ((char *) + XGetAtomName (display, (Atom) value)))) + { + if ((frame->font = mfont_parse_name (name, Mx))) + nfonts = 1; + } + XFreeFont (display, xfont); + } + } + XFreeFontNames (names); + } + if (! nfonts) + frame->font = mfont_parse_name (FALLBACK_FONT, Mx); + } -static MDeviceDriver x_driver = - { - 0, - mwin__device_init, - mwin__device_fini, - mwin__open_device, - mwin__close_device, - mwin__device_get_prop, - mwin__realize_face, - mwin__free_realized_face, - mwin__fill_space, - mwin__draw_empty_boxes, - mwin__draw_hline, - mwin__draw_box, - mwin__draw_points, - mwin__region_from_rect, - mwin__union_rect_with_region, - mwin__intersect_region, - mwin__region_add_rect, - mwin__region_to_rect, - mwin__free_region, - mwin__dump_region, - mwin__create_window, - mwin__destroy_window, - mwin__map_window, - mwin__unmap_window, - mwin__window_geometry, - mwin__adjust_window, - mwin__parse_event - }; + face = mface_from_font (frame->font); + face->property[MFACE_FONTSET] = mfontset (NULL); + face->property[MFACE_FOREGROUND] = frame->foreground; + face->property[MFACE_BACKGROUND] = frame->background; + mface_put_prop (face, Mhline, mface_get_prop (mface__default, Mhline)); + mface_put_prop (face, Mbox, mface_get_prop (mface__default, Mbox)); + face->property[MFACE_VIDEOMODE] = frame->videomode; + mface_put_prop (face, Mhook_func, + mface_get_prop (mface__default, Mhook_func)); + face->property[MFACE_RATIO] = (void *) 100; + mplist_push (param, Mface, face); + M17N_OBJECT_UNREF (face); + +#ifdef X_SET_ERROR_HANDLER + XSetErrorHandler (x_error_handler); + XSetIOErrorHandler (x_io_error_handler); +#endif + + return 0; +} @@ -2164,26 +2167,13 @@ x_io_error_handler (Display *display) } #endif +/*=*/ + /*** @} */ #endif /* !FOR_DOXYGEN || DOXYGEN_INTERNAL_MODULE */ /* External API */ -int -m17n_init_X () -{ - x_driver.initialized = 0; - mplist_put (m17n__device_library_list, Mx, &x_driver); - -#ifdef HAVE_XFT2 - xft_driver.select = mfont__ft_driver.select; - xft_driver.encode_char = mfont__ft_driver.encode_char; -#endif - - return 0; -} - -/*=*/ /*** @addtogroup m17nInputMethodWin */ /*=*/ /*** @{ */ diff --git a/src/m17n-X.h b/src/m17n-X.h index 4bc4c3e..3dc953b 100644 --- a/src/m17n-X.h +++ b/src/m17n-X.h @@ -27,27 +27,11 @@ #include #include -#ifndef _M17N_GUI_H_ -#include -#endif - #ifdef __cplusplus extern "C" { #endif -extern int m17n_init_X (void); -#undef M17N_INIT_X -#define M17N_INIT_X() m17n_init_X () - -#undef M17N_INIT -#define M17N_INIT() \ - do { \ - if (m17n_init_win () < 0) break; \ - if (M17N_INIT_GD () < 0) break; \ - M17N_INIT_X (); \ - } while (0) - /* For inputting. */ extern MInputDriver minput_xim_driver; diff --git a/src/m17n-gd.c b/src/m17n-gd.c index 9a8bf40..3e1ce7a 100644 --- a/src/m17n-gd.c +++ b/src/m17n-gd.c @@ -319,71 +319,6 @@ gd_render (MDrawWindow win, int x, int y, static MFontDriver gd_font_driver = { NULL, NULL, NULL, NULL, gd_render }; -static int -gd_init () -{ - M_rgb = msymbol (" rgb"); - read_rgb_txt (); - realized_fontset_list = mplist (); - realized_font_list = mplist (); - realized_face_list = mplist (); - scratch_images[0] = scratch_images[1] = NULL; - - gd_font_driver.select = mfont__ft_driver.select; - gd_font_driver.open = mfont__ft_driver.open; - gd_font_driver.find_metric = mfont__ft_driver.find_metric; - gd_font_driver.encode_char = mfont__ft_driver.encode_char; - - return 0; -} - -static int -gd_fini () -{ - MPlist *plist; - int i; - - MPLIST_DO (plist, realized_fontset_list) - mfont__free_realized_fontset ((MRealizedFontset *) MPLIST_VAL (plist)); - M17N_OBJECT_UNREF (realized_fontset_list); - - MPLIST_DO (plist, realized_face_list) - { - MRealizedFace *rface = MPLIST_VAL (plist); - - free (rface->info); - mface__free_realized (rface); - } - M17N_OBJECT_UNREF (realized_face_list); - - MPLIST_DO (plist, realized_font_list) - mfont__free_realized ((MRealizedFont *) MPLIST_VAL (plist)); - M17N_OBJECT_UNREF (realized_font_list); - - for (i = 0; i < 2; i++) - if (scratch_images[i]) - gdImageDestroy (scratch_images[i]); - return 0; -} - -static int -gd_open (MFrame *frame, MPlist *param) -{ - MFace *face; - - frame->device = NULL; - frame->device_type = MDEVICE_SUPPORT_OUTPUT; - frame->font_driver_list = mplist (); - mplist_add (frame->font_driver_list, Mfreetype, &gd_font_driver); - frame->realized_font_list = realized_font_list; - frame->realized_face_list = realized_face_list; - frame->realized_fontset_list = realized_fontset_list; - face = mface_copy (mface__default); - mplist_push (param, Mface, face); - M17N_OBJECT_UNREF (face); - return 0; -} - static void gd_close (MFrame *frame) { @@ -774,10 +709,6 @@ gd_dump_region (MDrawRegion region) static MDeviceDriver gd_driver = { - 0, - gd_init, - gd_fini, - gd_open, gd_close, gd_get_prop, gd_realize_face, @@ -796,22 +727,72 @@ static MDeviceDriver gd_driver = gd_dump_region, }; - -/* External API */ +/* Functions to be stored in MDeviceLibraryInterface by dlsym (). */ + int -m17n_init_gd () +device_init () { - gd_driver.initialized = 0; - mplist_put (m17n__device_library_list, Mgd, &gd_driver); + M_rgb = msymbol (" rgb"); + read_rgb_txt (); + realized_fontset_list = mplist (); + realized_font_list = mplist (); + realized_face_list = mplist (); + scratch_images[0] = scratch_images[1] = NULL; + + gd_font_driver.select = mfont__ft_driver.select; + gd_font_driver.open = mfont__ft_driver.open; + gd_font_driver.find_metric = mfont__ft_driver.find_metric; + gd_font_driver.encode_char = mfont__ft_driver.encode_char; + return 0; } -#else /* not HAVE_GD nor HAVE_FREETYPE */ +int +device_fini () +{ + MPlist *plist; + int i; + + MPLIST_DO (plist, realized_fontset_list) + mfont__free_realized_fontset ((MRealizedFontset *) MPLIST_VAL (plist)); + M17N_OBJECT_UNREF (realized_fontset_list); + + MPLIST_DO (plist, realized_face_list) + { + MRealizedFace *rface = MPLIST_VAL (plist); + + free (rface->info); + mface__free_realized (rface); + } + M17N_OBJECT_UNREF (realized_face_list); + + MPLIST_DO (plist, realized_font_list) + mfont__free_realized ((MRealizedFont *) MPLIST_VAL (plist)); + M17N_OBJECT_UNREF (realized_font_list); + + for (i = 0; i < 2; i++) + if (scratch_images[i]) + gdImageDestroy (scratch_images[i]); + return 0; +} int -m17n_init_gd () +device_open (MFrame *frame, MPlist *param) { - return -1; + MFace *face; + + frame->device = NULL; + frame->device_type = MDEVICE_SUPPORT_OUTPUT; + frame->driver = &gd_driver; + frame->font_driver_list = mplist (); + mplist_add (frame->font_driver_list, Mfreetype, &gd_font_driver); + frame->realized_font_list = realized_font_list; + frame->realized_face_list = realized_face_list; + frame->realized_fontset_list = realized_fontset_list; + face = mface_copy (mface__default); + mplist_push (param, Mface, face); + M17N_OBJECT_UNREF (face); + return 0; } #endif /* not HAVE_GD nor HAVE_FREETYPE */ diff --git a/src/m17n-gui.c b/src/m17n-gui.c index b752f1b..728280a 100644 --- a/src/m17n-gui.c +++ b/src/m17n-gui.c @@ -85,6 +85,27 @@ static int win_initialized; #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. */ + int (*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 @@ -99,6 +120,24 @@ free_frame (void *object) 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. */ @@ -109,6 +148,36 @@ static struct { MPlist *realized_face_list; } null_device; +static void +null_device_close (MFrame *frame) +{ +} + +static void * +null_device_get_prop (MFrame *frame, MSymbol key) +{ + return NULL; +} + +static void +null_device_realize_face (MRealizedFace *rface) +{ + rface->info = NULL; +} + +static 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 () { @@ -144,6 +213,7 @@ null_device_open (MFrame *frame, MPlist *param) frame->device = NULL; frame->device_type = 0; + frame->driver = &null_driver; frame->font_driver_list = mplist (); mplist_add (frame->font_driver_list, Mfreetype, &mfont__ft_driver); frame->realized_font_list = null_device.realized_font_list; @@ -155,39 +225,8 @@ null_device_open (MFrame *frame, MPlist *param) return 0; } -static void -null_device_close (MFrame *frame) -{ -} - -static void * -null_device_get_prop (MFrame *frame, MSymbol key) -{ - return NULL; -} - -static void -null_device_realize_face (MRealizedFace *rface) -{ - rface->info = NULL; -} - -static void -null_device_free_realized_face (MRealizedFace *rface) -{ -} - -static MDeviceDriver null_driver = - { - 0, - null_device_init, - null_device_fini, - null_device_open, - null_device_close, - null_device_get_prop, - null_device_realize_face, - null_device_free_realized_face - }; +static MDeviceLibraryInterface null_interface = + { NULL, NULL, null_device_init, null_device_open, null_device_fini }; #endif @@ -195,11 +234,6 @@ static MDeviceDriver null_driver = MSymbol Mfreetype; -/** Plist of device symbol vs functions to initialized the device - library. */ -MPlist *m17n__device_library_list; - - /*** @} */ #endif /* !FOR_DOXYGEN || DOXYGEN_INTERNAL_MODULE */ @@ -235,6 +269,9 @@ m17n_init_win (void) Mdepth = msymbol ("depth"); Mwidget = msymbol ("widget"); + register_device_library (Mx, "libm17n-X"); + register_device_library (Mgd, "libm17n-gd"); + MDEBUG_PUSH_TIME (); if (mfont__init () < 0) goto err; @@ -252,13 +289,6 @@ m17n_init_win (void) goto err; MDEBUG_PRINT_TIME ("INIT", (stderr, " to initialize input-win module.")); mframe_default = NULL; - - m17n__device_library_list = mplist (); -#ifdef HAVE_FREETYPE - null_driver.initialized = 0; - mplist_put (m17n__device_library_list, Mt, &null_driver); -#endif - return 0; err: @@ -283,17 +313,22 @@ m17n_fini_win (void) MDEBUG_PUSH_TIME (); MDEBUG_PUSH_TIME (); MDEBUG_PRINT_TIME ("FINI", (stderr, " to finalize device modules.")); - MPLIST_DO (plist, m17n__device_library_list) + MPLIST_DO (plist, device_library_list) { - MDeviceDriver *driver = MPLIST_VAL (plist); + MDeviceLibraryInterface *interface = MPLIST_VAL (plist); - if (driver->initialized) + if (interface->handle && interface->fini) { - (*driver->fini) (); - driver->initialized = 0; + (*interface->fini) (); + dlclose (interface->handle); } + free (interface->library); } - M17N_OBJECT_UNREF (m17n__device_library_list); +#ifdef HAVE_FREETYPE + if (null_interface.handle) + (*null_interface.fini) (); +#endif /* not HAVE_FREETYPE */ + M17N_OBJECT_UNREF (device_library_list); MDEBUG_PRINT_TIME ("FINI", (stderr, " to finalize input-gui module.")); minput__win_fini (); MDEBUG_PRINT_TIME ("FINI", (stderr, " to finalize draw module.")); @@ -564,19 +599,13 @@ mframe (MPlist *plist) int plist_created = 0; MPlist *pl; MSymbol device; - MDeviceDriver *driver; + MDeviceLibraryInterface *interface; if (plist) { pl = mplist_find_by_key (plist, Mdevice); if (pl) - { - device = MPLIST_VAL (pl); - if (device == Mt) - MERROR (MERROR_WIN, NULL); - if (device == Mnil) - device = Mt; - } + device = MPLIST_VAL (pl); else device = Mx; } @@ -587,23 +616,47 @@ mframe (MPlist *plist) device = Mx; } - driver = mplist_get (m17n__device_library_list, device); - if (! driver) - MERROR (MERROR_WIN, NULL); - if (! driver->initialized) + if (device == Mnil) { - if ((*driver->init) () < 0) +#ifdef HAVE_FREETYPE + interface = &null_interface; + if (! interface->handle) + { + (*interface->init) (); + interface->handle = (void *) 1; + } +#else /* not HAVE_FREETYPE */ + MERROR (MERROR_WIN, NULL); +#endif /* not HAVE_FREETYPE */ + } + else + { + interface = mplist_get (device_library_list, device); + if (! interface) MERROR (MERROR_WIN, NULL); - driver->initialized = 1; - } + 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); + } + } + } M17N_OBJECT (frame, free_frame, MERROR_FRAME); - if ((*driver->open) (frame, plist) < 0) + if ((*interface->open) (frame, plist) < 0) { free (frame); MERROR (MERROR_WIN, NULL); } - frame->driver = driver; if (! mframe_default) mframe_default = frame; diff --git a/src/m17n-gui.h b/src/m17n-gui.h index ce2f597..48f545b 100644 --- a/src/m17n-gui.h +++ b/src/m17n-gui.h @@ -32,9 +32,6 @@ extern "C" { #endif -#define M17N_INIT_X() 1 -#define M17N_INIT_GD() 1 - extern int m17n_init_win (void); #undef M17N_INIT #define M17N_INIT() m17n_init_win ()