1 /* m17n-gui.c -- body of the GUI API.
2    Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
3      National Institute of Advanced Industrial Science and Technology (AIST)
4      Registration Number H15PRO112
5 
6    This file is part of the m17n library.
7 
8    The m17n library is free software; you can redistribute it and/or
9    modify it under the terms of the GNU Lesser General Public License
10    as published by the Free Software Foundation; either version 2.1 of
11    the License, or (at your option) any later version.
12 
13    The m17n library is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16    Lesser General Public License for more details.
17 
18    You should have received a copy of the GNU Lesser General Public
19    License along with the m17n library; if not, write to the Free
20    Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21    Boston, MA 02110-1301 USA.  */
22 
23 /***en
24     @addtogroup m17nGUI
25     @brief GUI support for a window system.
26 
27     This section defines the m17n GUI API concerning M-text drawing
28     and inputting under a window system.
29 
30     All the definitions here are independent of window systems.  An
31     actual library file, however, can depend on a specific window
32     system.  For instance, the library file m17n-X.so is an example of
33     implementation of the m17n GUI API for the X Window System.
34 
35     Actually the GUI API is mainly for toolkit libraries or to
36     implement XOM, not for direct use from application programs.
37 */
38 
39 /***ja
40     @addtogroup m17nGUI
41     @brief ������ɥ������ƥ��� GUI ���ݡ���.
42 
43     ���Υ��������ϥ�����ɥ������ƥ�Τ�ȤǤ� M-text ��ɽ�������Ϥˤ������
44     m17n GUI API ��������롣
45 
46     �����ǤΤ��٤Ƥ�����ϥ�����ɥ������ƥ�Ȥ���Ω�Ǥ��롣
47     ���������ºݤΥ饤�֥��ե�����ϸ��̤Υ�����ɥ������ƥ�˰�¸�����礬���롣
48     ���Ȥ��Х饤�֥��ե����� m17n-X.so �ϡ�m17n GUI API �� X
49     ������ɥ��Ѥμ�����Ǥ��롣
50 
51     ���¤ˤϡ�GUI API �ϼ�˥ġ��륭�åȥ饤�֥������Ǥ��뤫���ޤ���
52     XOM ��������뤿����Ѥ����Ƥ��ꡢ���ץꥱ�������ץ���फ���ľ�ܤ����Ѥ�ǰƬ�ˤ�������ΤǤϤʤ���
53 */
54 
55 /*=*/
56 
57 #if !defined (FOR_DOXYGEN) || defined (DOXYGEN_INTERNAL_MODULE)
58 /*** @addtogroup m17nInternal
59      @{ */
60 
61 #include "config.h"
62 
63 #include <stdio.h>
64 #include <string.h>
65 #include <stdlib.h>
66 
67 #include "config.h"
68 #ifdef HAVE_DLFCN_H
69 #include <dlfcn.h>
70 #endif
71 
72 #include "m17n-gui.h"
73 #include "m17n-misc.h"
74 #include "internal.h"
75 #include "plist.h"
76 #include "internal-gui.h"
77 #include "font.h"
78 #include "fontset.h"
79 #include "face.h"
80 
81 #ifndef DLOPEN_SHLIB_EXT
82 #define DLOPEN_SHLIB_EXT ".so"
83 #endif
84 
85 /** Information about a dynamic library supporting a specific graphic
86     device.  */
87 typedef struct
88 {
89   /** Name of the dynamic library (e.g. "libm17n-X.so").  */
90   char *library;
91   /** Handle of the dynamic library.  */
92   void *handle;
93   /** Function to call just after loading the library.  */
94   int (*init) ();
95   /** Function to call to open a frame on the graphic device.  */
96   int (*open) (MFrame *frame, MPlist *param);
97   /** Function to call just before unloading the library.  */
98   int (*fini) ();
99 } MDeviceLibraryInterface;
100 
101 
102 /** Plist of device symbol vs MDeviceLibraryInterface.  */
103 
104 static MPlist *device_library_list;
105 
106 /** Close MFrame and free it.  */
107 
108 static void
free_frame(void * object)109 free_frame (void *object)
110 {
111   MFrame *frame = (MFrame *) object;
112 
113   (*frame->driver->close) (frame);
114   M17N_OBJECT_UNREF (frame->face);
115   M17N_OBJECT_UNREF (frame->font_driver_list);
116   free (object);
117 }
118 
119 
120 /** Register a dynamic library of name LIB by a key NAME.  */
121 
122 static int
register_device_library(MSymbol name,char * lib)123 register_device_library (MSymbol name, char *lib)
124 {
125   MDeviceLibraryInterface *interface;
126 
127   MSTRUCT_CALLOC (interface, MERROR_WIN);
128   interface->library = malloc (strlen (M17N_MODULE_DIR) + 1
129 			       + strlen (lib)
130 			       + strlen (DLOPEN_SHLIB_EXT) + 1);
131   sprintf (interface->library, "%s/%s%s", M17N_MODULE_DIR, lib,
132 	   DLOPEN_SHLIB_EXT);
133   if (! device_library_list)
134     device_library_list = mplist ();
135   mplist_add (device_library_list, name, interface);
136   return 0;
137 }
138 
139 
140 #ifdef HAVE_FREETYPE
141 /** Null device support.  */
142 
143 static struct {
144   MPlist *realized_fontset_list;
145   MPlist *realized_font_list;
146   MPlist *realized_face_list;
147 } null_device;
148 
149 static void
null_device_close(MFrame * frame)150 null_device_close (MFrame *frame)
151 {
152 }
153 
154 static void *
null_device_get_prop(MFrame * frame,MSymbol key)155 null_device_get_prop (MFrame *frame, MSymbol key)
156 {
157   return NULL;
158 }
159 
160 static void
null_device_realize_face(MRealizedFace * rface)161 null_device_realize_face (MRealizedFace *rface)
162 {
163   rface->info = NULL;
164 }
165 
166 static void
null_device_free_realized_face(MRealizedFace * rface)167 null_device_free_realized_face (MRealizedFace *rface)
168 {
169 }
170 
171 static MDeviceDriver null_driver =
172   {
173     null_device_close,
174     null_device_get_prop,
175     null_device_realize_face,
176     null_device_free_realized_face
177   };
178 
179 static int
null_device_init()180 null_device_init ()
181 {
182   null_device.realized_fontset_list = mplist ();
183   null_device.realized_font_list = mplist ();
184   null_device.realized_face_list = mplist ();
185   return 0;
186 }
187 
188 static int
null_device_fini()189 null_device_fini ()
190 {
191   MPlist *plist;
192 
193   MPLIST_DO (plist, null_device.realized_fontset_list)
194     mfont__free_realized_fontset ((MRealizedFontset *) MPLIST_VAL (plist));
195   M17N_OBJECT_UNREF (null_device.realized_fontset_list);
196 
197   MPLIST_DO (plist, null_device.realized_face_list)
198     mface__free_realized ((MRealizedFace *) MPLIST_VAL (plist));
199   M17N_OBJECT_UNREF (null_device.realized_face_list);
200 
201   if (MPLIST_VAL (null_device.realized_font_list))
202     mfont__free_realized (MPLIST_VAL (null_device.realized_font_list));
203   M17N_OBJECT_UNREF (null_device.realized_font_list);
204   return 0;
205 }
206 
207 static int
null_device_open(MFrame * frame,MPlist * param)208 null_device_open (MFrame *frame, MPlist *param)
209 {
210   MFace *face;
211 
212   frame->device = NULL;
213   frame->device_type = 0;
214   frame->dpi = (int) mplist_get (param, Mresolution);
215   if (frame->dpi == 0)
216     frame->dpi = 100;
217   frame->driver = &null_driver;
218   frame->font_driver_list = mplist ();
219   mplist_add (frame->font_driver_list, Mfreetype, &mfont__ft_driver);
220   frame->realized_font_list = null_device.realized_font_list;
221   frame->realized_face_list = null_device.realized_face_list;
222   frame->realized_fontset_list = null_device.realized_fontset_list;
223   face = mface_copy (mface__default);
224   mplist_push (param, Mface, face);
225   M17N_OBJECT_UNREF (face);
226   return 0;
227 }
228 
229 static MDeviceLibraryInterface null_interface =
230   { NULL, NULL, null_device_init, null_device_open, null_device_fini };
231 
232 #endif
233 
234 /* Internal API */
235 
236 
237 /* External API */
238 
239 void
m17n_init_win(void)240 m17n_init_win (void)
241 {
242   int mdebug_flag = MDEBUG_INIT;
243 
244   merror_code = MERROR_NONE;
245   if (m17n__gui_initialized++)
246     return;
247   m17n_init ();
248   m17n_init_flt ();
249   if (merror_code != MERROR_NONE)
250     {
251       m17n__gui_initialized--;
252       return;
253     }
254 
255   MDEBUG_PUSH_TIME ();
256 
257   Mgd = msymbol ("gd");
258 
259   Mfont = msymbol ("font");
260   Mfont_width = msymbol ("font-width");
261   Mfont_ascent = msymbol ("font-ascent");
262   Mfont_descent = msymbol ("font-descent");
263   Mdevice = msymbol ("device");
264 
265   Mdisplay = msymbol ("display");
266   Mscreen = msymbol ("screen");
267   Mdrawable = msymbol ("drawable");
268   Mdepth = msymbol ("depth");
269   Mwidget = msymbol ("widget");
270   Mcolormap = msymbol ("colormap");
271 
272   MDEBUG_PUSH_TIME ();
273   if (mfont__init () < 0)
274     goto err;
275   MDEBUG_PRINT_TIME ("INIT", (mdebug__output, " to initialize font module."));
276   if (mfont__fontset_init () < 0)
277     goto err;
278   MDEBUG_PRINT_TIME ("INIT", (mdebug__output, " to initialize fontset module."));
279   if (mface__init () < 0)
280     goto err;
281   MDEBUG_PRINT_TIME ("INIT", (mdebug__output, " to initialize face module."));
282   if (mdraw__init () < 0)
283     goto err;
284   MDEBUG_PRINT_TIME ("INIT", (mdebug__output, " to initialize draw module."));
285   if (minput__win_init () < 0)
286     goto err;
287   MDEBUG_PRINT_TIME ("INIT",
288 		     (mdebug__output, " to initialize input-win module."));
289   mframe_default = NULL;
290 
291   register_device_library (Mx, "libm17n-X");
292   register_device_library (Mgd, "libm17n-gd");
293   return;
294 
295  err:
296   MDEBUG_POP_TIME ();
297   MDEBUG_PRINT_TIME ("INIT",
298 		     (mdebug__output, " to initialize the m17n GUI module."));
299   MDEBUG_POP_TIME ();
300 }
301 
302 void
m17n_fini_win(void)303 m17n_fini_win (void)
304 {
305   int mdebug_flag = MDEBUG_FINI;
306   MPlist *plist;
307 
308   if (m17n__gui_initialized == 0
309       || --m17n__gui_initialized > 0)
310     return;
311 
312   MDEBUG_PUSH_TIME ();
313   MDEBUG_PUSH_TIME ();
314   MDEBUG_PRINT_TIME ("FINI", (mdebug__output, " to finalize device modules."));
315   MPLIST_DO (plist, device_library_list)
316     {
317       MDeviceLibraryInterface *interface = MPLIST_VAL (plist);
318 
319       if (interface->handle && interface->fini)
320 	{
321 	  (*interface->fini) ();
322 	  dlclose (interface->handle);
323 	}
324       free (interface->library);
325       free (interface);
326     }
327 #ifdef HAVE_FREETYPE
328   if (null_interface.handle)
329     {
330       (*null_interface.fini) ();
331       null_interface.handle = NULL;
332     }
333 #endif	/* not HAVE_FREETYPE */
334   M17N_OBJECT_UNREF (device_library_list);
335   minput__win_fini ();
336   MDEBUG_PRINT_TIME ("FINI",
337 		     (mdebug__output, " to finalize input-gui module."));
338   mdraw__fini ();
339   MDEBUG_PRINT_TIME ("FINI", (mdebug__output, " to finalize draw module."));
340   mface__fini ();
341   MDEBUG_PRINT_TIME ("FINI", (mdebug__output, " to finalize face module."));
342   mfont__fontset_fini ();
343   MDEBUG_PRINT_TIME ("FINI", (mdebug__output, " to finalize fontset module."));
344   mfont__fini ();
345   MDEBUG_PRINT_TIME ("FINI", (mdebug__output, " to finalize font module."));
346   mframe_default = NULL;
347   MDEBUG_POP_TIME ();
348   MDEBUG_PRINT_TIME ("FINI", (mdebug__output, " to finalize the gui modules."));
349   MDEBUG_POP_TIME ();
350   m17n_fini_flt ();
351   m17n_fini ();
352 }
353 
354 /*** @} */
355 #endif /* !FOR_DOXYGEN || DOXYGEN_INTERNAL_MODULE */
356 
357 /*** @addtogroup m17nFrame */
358 /***en
359     @brief A @e frame is an object corresponding to the graphic device.
360 
361     A @e frame is an object of the type #MFrame to hold various
362     information about each display/input device.  Almost all m17n GUI
363     functions require a pointer to a frame as an argument.  */
364 /***ja
365     @brief @e �ե졼�� �Ȥϥ���ե��å��ǥХ������б����륪�֥������ȤǤ���.
366 
367     @e �ե졼�� �Ȥ� #MFrame
368     ���Υ��֥������ȤǤ��ꡢ�ġ���ɽ�������ϥǥХ����ξ�����Ǽ���뤿����Ѥ����롣
369     �ۤȤ�ɤ��٤Ƥ� m17n GUI�ؿ��ϡ������Ȥ��ƥե졼��ؤΥݥ������׵᤹�롣  */
370 
371 /*** @{ */
372 /*=*/
373 
374 /***en
375     @name Variables: Keys of frame parameter
376 
377     These are the symbols to use in a parameter to create a frame.  See
378     the function mframe () for details.
379 
380     @b Mdevice, @b Mdisplay, @b Mscreen, @b Mdrawable, @b Mdepth, and
381     @b Mcolormap are also keys of a frame property.  */
382 
383 /***ja
384     @name �ѿ��� �ե졼��ѥ�᡼���ѥ���
385 
386     �ե졼�����������ݤΥѥ�᡼�����Ѥ��륷��ܥ롣�ܤ����ϴؿ�
387     mframe () ���������ȡ�
388 
389     @b Mdevice�� @b Mdisplay�� @b Mscreen�� @b Mdrawable�� @b Mdepth��
390     @b Mcolormap �ϥե졼��ץ�ѥƥ��Υ����Ǥ⤢�롣  */
391 
392 /*=*/
393 
394 MSymbol Mdevice, Mdisplay, Mscreen, Mdrawable, Mdepth, Mcolormap, Mwidget;
395 
396 MSymbol Mgd;
397 
398 /*=*/
399 
400 /***en
401     @name Variables: Keys of frame property
402 
403     These are the symbols to use as an argument to the function
404     mframe_get_prop ().  */
405 /***ja
406     @name �ѿ��� �ե졼��ץ�ѥƥ��Υ���
407 
408     �ؿ� mframe_get_prop () �ΰ������Ѥ����륷��ܥ롣  */
409 /*** @{ */
410 /*=*/
411 MSymbol Mfont;
412 MSymbol Mfont_width;
413 MSymbol Mfont_ascent;
414 MSymbol Mfont_descent;
415 
416 /*=*/
417 
418 /*** @} */
419 /*=*/
420 
421 /***en
422     @brief Create a new frame.
423 
424     The mframe () function creates a new frame with parameters listed
425     in $PLIST which may be @c NULL.
426 
427     The recognized keys in $PLIST are window system dependent.
428 
429     The following key is always recognized.
430 
431     <ul>
432 
433     <li> @b Mdevice, the value must be one of #Mx, @b Mgd, and #Mnil.
434 
435     If the value is #Mx, the frame is for X Window System.  The
436     argument #MDrawWindow specified together with the frame must be of
437     type @c Window.  The frame is both readable and writable, thus all
438     GUI functions can be used.
439 
440     If the value is @b Mgd, the frame is for an image object of GD
441     library.  The argument #MDrawWindow specified together with the
442     frame must be of type @c gdImagePtr.  The frame is writable
443     only, thus functions minput_XXX can't be used for the frame.
444 
445     If the value is #Mnil, the frame is for a null device.  The frame
446     is not writable nor readable, thus functions mdraw_XXX that
447     require the argument #MDrawWindow and functions minput_XXX can't
448     be used for the frame.
449 
450     <li> #Mface, the value must be a pointer to #MFace.
451 
452     The value is used as the default face of the frame.
453 
454     </ul>
455 
456     In addition, if the value of the key @b Mdevice is #Mx, the
457     following keys are recognized.  They are to specify the root
458     window and the depth of drawables that can be used with the frame.
459 
460     <ul>
461 
462     <li> @b Mdrawable, the value type must be <tt>Drawable</tt>.
463 
464     A parameter of key @b Mdisplay must also be specified.  The
465     created frame can be used for drawables whose root window and
466     depth are the same as those of the specified drawable on the
467     specified display.
468 
469     When this parameter is specified, the parameter of key @b Mscreen
470     is ignored.
471 
472     <li> @b Mwidget, the value type must be <tt>Widget</tt>.
473 
474     The created frame can be used for drawables whose root window and
475     depth are the same as those of the specified widget.
476 
477     If a parameter of key #Mface is not specified, the default face
478     is created from the resources of the widget.
479 
480     When this parameter is specified, the parameters of key @b Mdisplay,
481     @b Mscreen, @b Mdrawable, @b Mdepth are ignored.
482 
483     <li> @b Mdepth, the value type must be <tt>unsigned</tt>.
484 
485     The created frame can be used for drawables of the specified
486     depth.
487 
488     <li> @b Mscreen, the value type must be <tt>(Screen *)</tt>.
489 
490     The created frame can be used for drawables whose root window is
491     the same as the root window of the specified screen, and depth is
492     the same at the default depth of the screen.
493 
494     When this parameter is specified, parameter of key @b Mdisplay is
495     ignored.
496 
497     <li> @b Mdisplay, the value type must be <tt>(Display *)</tt>.
498 
499     The created frame can be used for drawables whose root window is
500     the same as the root window for the default screen of the display,
501     and depth is the same as the default depth of the screen.
502 
503     <li> @b Mcolormap, the value type must be <tt>(Colormap)</tt>.
504 
505     The created frame uses the specified colormap.
506 
507     <li> @b Mfont, the value must be #Mx, #Mfreetype, or #Mxft.
508 
509     The created frame uses the specified font backend.  The value #Mx
510     instructs to use X core fonts, #Mfreetype to use local fonts
511     supported by FreeType fonts, and #Mxft to use local fonts via Xft
512     library.  You can specify this parameter more than once with
513     different values if you want to use multiple font backends.  This
514     is ignored if the specified font backend is not supported on the
515     device.
516 
517     When this parameter is not specified, all font backend supported
518     on the device are used.
519 
520     </ul>
521 
522     @return
523     If the operation was successful, mframe () returns a pointer to a
524     newly created frame.  Otherwise, it returns @c NULL.  */
525 
526 /***ja
527     @brief �������ե졼�����.
528 
529     �ؿ� mframe () �� $PLIST ��Υѥ�᡼������Ŀ������ե졼����롣
530     $PLIST �� @c NULL �Ǥ��ɤ���
531 
532     $PLIST �˸����륭���Τ����ɤ줬ǧ������뤫�ϥ�����ɥ������ƥ�˰�¸���롣
533 
534     �ʲ��Υ����Ͼ��ǧ������롣
535 
536     <ul>
537 
538     <li> @b Mdevice. �ͤ� #Mx, @b Mgd, #Mnil �Τ����줫�Ǥʤ��ƤϤʤ�ʤ���
539 
540     �ͤ� #Mx �ʤ�С��������ե졼��� X ������ɥ������ƥ��ѤǤ��롣
541     ���Υե졼��ȶ��˻��ꤵ�줿���� #MDrawWindow �ϡ� @c Window
542     ���Ǥʤ��ƤϤʤ�ʤ����ե졼����ɤ߽��Ȥ�˲�ǽ�Ǥ��ꡢ���٤Ƥ�GUI
543     �ؿ������ѤǤ��롣
544 
545     �ͤ� @b Mgd �ʤ�С��������ե졼��� GD
546     �饤�֥��Υ��᡼�����֥��������ѤǤ��롣���Υե졼��ȶ��˻��ꤵ�줿����
547     #MDrawWindow �ϡ� @c gdImagePtr ���Ǥʤ��ƤϤʤ�ʤ����ե졼��Ͻ��Ф����ѤǤ��ꡢ
548     minput_ �ǻϤޤ�̾���δؿ��ϻ��ѤǤ��ʤ���
549 
550     �ͤ� #Mnil �ʤ�С��������ե졼���, null
551     �ǥХ����ѤǤ��롣���Υե졼����ɤ߽��Ǥ��ʤ��Τǡ����� #MDrawWindow
552     ��ɬ�פȤ���mdraw_ �ǻϤޤ�̾���δؿ��䡢minput_ �ǻϤޤ�̾���δؿ��ϻ��ѤǤ��ʤ���
553 
554     <li> #Mface. �ͤ� #MFace �ؤΥݥ����Ǥʤ��ƤϤʤ�ʤ���
555 
556     �����ͤϥե졼��Υǥե���ȤΥե������Ȥ����Ѥ����롣
557 
558     </ul>
559 
560     �����Υ����˲ä���@b Mdevice �Υ����� #Mx
561     �Ǥ�����˸¤�ʲ��Υ�����ǧ������롣�ʲ��Υ����ϥ롼�ȥ�����ɥ��ȡ��ե졼������ѤǤ���
562     drawable �ο�������ꤹ�롣
563 
564     <ul>
565 
566     <li> @b Mdrawable. �ͤ� <tt>Drawable</tt> ���Ǥʤ��ƤϤʤ�ʤ���
567 
568     ���� @b Mdisplay ����ĥѥ�᡼������ꤵ��Ƥ���ɬ�פ����롣
569     �������줿�ե졼��ϡ����ꤵ�줿�ǥ����ץ쥤��λ��ꤵ�줿 drawable
570     ��Ʊ���롼�ȥ�����ɥ��ȿ�������� drawable ���Ѥ����롣
571 
572     ���Υѥ�᡼����������ˤϡ�@b Mscreen �����Ȥ���ѥ�᡼����̵�뤵��롣
573 
574     <li> @b Mwidget. �ͤ� <tt>Widget</tt> ���Ǥʤ��ƤϤʤ�ʤ���
575 
576     �������줿�ե졼��ϡ����ꤷ�����������åȤ�Ʊ���롼�ȥ�����ɥ��ȿ��������
577     drawable ���Ѥ����롣
578 
579     ���� #Mface ����ĥѥ�᡼�����ʤ���С��ǥե���ȤΥե������Ϥ���
580     ���������åȤΥ꥽�����������롣
581 
582     ���Υѥ�᡼����������ˤϡ�@b Mdisplay, @b Mscreen, @b Mdrawable,
583     @b Mdepth �����Ȥ���ѥ�᡼����̵�뤵��롣
584 
585     <li> @b Mdepth. �ͤ� <tt>unsigned</tt>  ���Ǥʤ��ƤϤʤ�ʤ���
586 
587     �������줿�ե졼��ϡ����ꤷ�������� drawable ���Ѥ����롣
588 
589     <li> @b Mscreen. �ͤ� <tt>(Screen *)</tt> ���Ǥʤ��ƤϤʤ�ʤ���
590 
591     ���������ե졼��ϡ����ꤷ�������꡼���Ʊ���롼�ȥ�����ɥ�������������꡼��Υǥե���Ȥο�����Ʊ����������� drawable ���Ѥ����롣
592 
593     ���Υѥ�᡼����������ˤϡ�@b Mdisplay �����Ȥ���ѥ�᡼����̵�뤵��롣
594 
595     <li> @b Mdisplay. �ͤ� <tt>(Display *)</tt> ���Ǥʤ��ƤϤʤ�ʤ���
596 
597     �������줿�ե졼��ϡ����ꤷ���ǥ����ץ쥤�Υǥե���ȥ����꡼���Ʊ���롼�ȥ�����ɥ���Ʊ�����������drawables ���Ѥ����롣
598 
599     <li> @b Mcolormap. �ͤ� <tt>(Colormap)</tt> ���Ǥʤ��ƤϤʤ�ʤ���
600 
601     �������줿�ե졼��ϡ����ꤷ�����顼�ޥåפ���Ѥ��롣
602 
603     <li> #Mfont. �ͤϡ�#Mx, #Mfreetype, #Mxft �Τ����줫��
604 
605     �������줿�ե졼��ϻ��ꤷ���ե���ȥХå�����ɤ���Ѥ��롣�ͤ�
606     #Mx �Ǥ���� X �Υ����ե���ȡ�#Mfreetype �Ǥ���� FreeType
607     �ǥ��ݡ��Ȥ���Ƥ��������ե���ȡ�#Mxft �Ǥ���� Xft
608     �饤�֥���ͳ���Ѥ��������ե���Ȥ���Ѥ��롣
609     ʣ���Υե���ȥХå�����ɤ���Ѥ��������ˤϡ����Υѥ�᡼����ʣ�����ۤʤ��ͤǻ��ꤹ�뤳�Ȥ��Ǥ��롣
610     ���ꤷ���Хå�����ɤ����ݡ��Ȥ���Ƥ��ʤ��ǥХ����Ǥϡ����Υѥ�᡼����̵�뤵��롣
611 
612     ���Υѥ�᡼����̵�����ˤϡ��ǥХ����ǥ��ݡ��Ȥ���Ƥ��뤹�٤ƤΥե���ȥХå�����ɤ����Ѥ��롣
613 
614     </ul>
615 
616     @return
617     ��������� mframe() �Ͽ������ե졼��ؤΥݥ������֤��������Ǥʤ����
618     @c NULL ���֤���  */
619 
620 MFrame *
mframe(MPlist * plist)621 mframe (MPlist *plist)
622 {
623   MFrame *frame;
624   int plist_created = 0;
625   MPlist *pl;
626   MSymbol device;
627   MDeviceLibraryInterface *interface;
628 
629   if (plist)
630     {
631       pl = mplist_find_by_key (plist, Mdevice);
632       if (pl)
633 	device = MPLIST_VAL (pl);
634       else
635 	device = Mx;
636     }
637   else
638     {
639       plist = mplist ();
640       plist_created = 1;
641       device = Mx;
642     }
643 
644   if (device == Mnil)
645     {
646 #ifdef HAVE_FREETYPE
647       interface = &null_interface;
648       if (! interface->handle)
649 	{
650 	  (*interface->init) ();
651 	  interface->handle = (void *) 1;
652 	}
653 #else  /* not HAVE_FREETYPE */
654       MERROR (MERROR_WIN, NULL);
655 #endif	/* not HAVE_FREETYPE */
656     }
657   else
658     {
659       interface = mplist_get (device_library_list, device);
660       if (! interface)
661 	MERROR (MERROR_WIN, NULL);
662       if (! interface->handle)
663 	{
664 	  if (! (interface->handle = dlopen (interface->library, RTLD_NOW))
665 	      || ! (interface->init
666 		    = (int (*) ()) dlsym (interface->handle, "device_init"))
667 	      || ! (interface->open
668 		    = (int (*) (MFrame *, MPlist *)) dlsym (interface->handle,
669 							    "device_open"))
670 	      || ! (interface->fini
671 		    = (int (*) ()) dlsym (interface->handle, "device_fini"))
672 	      || (*interface->init) () < 0)
673 	    {
674 	      fprintf (stderr, "%s\n", (char *) dlerror ());
675 	      if (interface->handle)
676 		dlclose (interface->handle);
677 	      MERROR (MERROR_WIN, NULL);
678 	    }
679 	}
680     }
681 
682   M17N_OBJECT (frame, free_frame, MERROR_FRAME);
683   if ((*interface->open) (frame, plist) < 0)
684     {
685       free (frame);
686       MERROR (MERROR_WIN, NULL);
687     }
688 
689   if (! mframe_default)
690     mframe_default = frame;
691 
692   frame->face = mface ();
693   MPLIST_DO (pl, plist)
694     if (MPLIST_KEY (pl) == Mface)
695       mface_merge (frame->face, (MFace *) MPLIST_VAL (pl));
696   mface__update_frame_face (frame);
697   frame->font
698     = frame->rface->rfont ? (MFont *) frame->rface->rfont : NULL;
699   if (plist_created)
700     M17N_OBJECT_UNREF (plist);
701   return frame;
702 }
703 
704 /*=*/
705 
706 /***en
707     @brief Return property value of frame.
708 
709     The mframe_get_prop () function returns a value of property $KEY
710     of frame $FRAME.  The valid keys and the corresponding return
711     values are as follows.
712 
713 @verbatim
714 
715         key             type of value   meaning of value
716         ---             -------------   ----------------
717         Mface           MFace *         The default face.
718 
719         Mfont           MFont *         The default font.
720 
721         Mfont_width     int             Width of the default font.
722 
723         Mfont_ascent    int             Ascent of the default font.
724 
725         Mfont_descent   int             Descent of the default font.
726 
727 @endverbatim
728 
729     In the m17n-X library, the followings are also accepted.
730 
731 @verbatim
732 
733         key             type of value   meaning of value
734         ---             -------------   ----------------
735         Mdisplay        Display *       Display associated with the frame.
736 
737         Mscreen         int             Screen number of a screen associated
738                                         with the frame.
739 
740         Mcolormap       Colormap        Colormap of the frame.
741 
742         Mdepth          unsigned        Depth of the frame.
743 @endverbatim
744 */
745 
746 /***ja
747     @brief �ե졼��Υץ�ѥƥ����ͤ��֤�.
748 
749     �ؿ� mframe_get_prop () �ϥե졼�� $FRAME �Υ��� $KEY
750     ����ĥץ�ѥƥ����ͤ��֤���ͭ���ʥ����Ȥ����ͤϰʲ����̤ꡣ
751 
752 @verbatim
753 
754         ����            �ͤη�          �ͤΰ�̣
755         ---             -------------   ----------------
756         Mface           MFace *         �ǥե���ȤΥե�����
757 
758         Mfont           MFont *         �ǥե���ȤΥե����
759 
760         Mfont_width     int             �ǥե���ȤΥե���Ȥ���
761 
762         Mfont_ascent    int             �ǥե���ȤΥե���Ȥ� ascent
763 
764         Mfont_descent   int             �ǥե���ȤΥե���Ȥ� descent
765 
766 @endverbatim
767 
768      m17n-X �饤�֥��Ǥϡ��ʲ��Υ�������ѤǤ��롣
769 
770 @verbatim
771 
772         ����            �ͤη�          �ͤΰ�̣
773         ---             -------------   ----------------
774         Mdisplay        Display *       �ե졼��ȴ�Ϣ�դ���줿�ǥ����ץ쥤
775 
776         Mscreen         int             �ե졼��ȴ�Ϣ�դ���줿�����꡼��
777                                         �Υ����꡼��ʥ��
778 
779         Mcolormap       Colormap        �ե졼��Υ��顼�ޥå�
780 
781         Mdepth          unsigned        �ե졼��ο���
782 @endverbatim
783 
784 */
785 
786 void *
mframe_get_prop(MFrame * frame,MSymbol key)787 mframe_get_prop (MFrame *frame, MSymbol key)
788 {
789   if (key == Mface)
790     return frame->face;
791   if (key == Mfont)
792     return frame->font;
793   if (key == Mfont_width)
794     return (void *) (frame->average_width);
795   if (key == Mfont_ascent)
796     return (void *) (frame->ascent);
797   if (key == Mfont_descent)
798     return (void *) (frame->descent);
799   return (*frame->driver->get_prop) (frame, key);
800 }
801 
802 /*=*/
803 
804 /***en
805     @brief The default frame.
806 
807     The external variable #mframe_default contains a pointer to the
808     default frame that is created by the first call of mframe ().  */
809 
810 /***ja
811     @brief �ǥե���ȤΥե졼��.
812 
813     �����ѿ� #mframe_default �ϡ��ǥե���ȤΥե졼��ؤΥݥ�������ġ�
814     �ǥե���ȤΥե졼��ϡ��ǽ�� mframe () ���ƤӽФ��줿�Ȥ��˺���롣  */
815 
816 MFrame *mframe_default;
817 
818 /*** @} */
819 
820 /*
821   Local Variables:
822   coding: euc-japan
823   End:
824 */
825