1 /* input-gui.c -- gui-based input method module.
2 Copyright (C) 2003, 2004
3 National Institute of Advanced Industrial Science and Technology (AIST)
4 Registration Number H15PRO112
6 This file is part of the m17n library.
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.
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.
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., 59 Temple Place, Suite 330, Boston, MA
24 @addtogroup m17nInputMethodWin
25 @brief Input method support on window systems.
27 The input driver @c minput_gui_driver is provided for internal
28 input methods that is useful on window systems. It displays
29 preedit text and status text at the inputting spot. See the
30 documentation of @c minput_gui_driver for more details.
32 In the m17n-X library, the foreign input method of name @c Mxim is
33 provided. It uses XIM (X Input Method) as a background input
34 engine. The symbol @c Mxim has a property @c Minput_driver whose
35 value is a pointer to the input driver @c minput_xim_driver. See
36 the documentation of @c minput_xim_driver for more details. */
39 @addtogroup m17nInputMethodWin
40 @brief ¥¦¥£¥ó¥É¥¦¥·¥¹¥Æ¥à¾å¤ÎÆþÎϥ᥽¥Ã¥É¤Î¥µ¥Ý¡¼¥È.
42 ÆþÎϥɥ饤¥Ð @c minput_gui_driver ¤Ï¡¢¥¦¥£¥ó¥É¥¦¥·¥¹¥Æ¥à¾å¤ÇÍѤ¤¤é
43 ¤ì¤ëÆâÉôÆþÎϥ᥽¥Ã¥ÉÍѤǤ¢¤ë¡£¤³¤Î¥É¥é¥¤¥Ð¤ÏÆþÎÏ¥¹¥Ý¥Ã¥È¤Ë preedit
44 ¥Æ¥¥¹¥È¤È status ¥Æ¥¥¹¥È¤òɽ¼¨¤¹¤ë¡£¾ÜºÙ¤Ë¤Ä¤¤¤Æ¤Ï @c
45 minput_gui_driver ¤ÎÀâÌÀ¤ò»²¾È¤Î¤³¤È¡£
47 m17n-X ¥é¥¤¥Ö¥é¥ê¤Ï¡¢@c Mxim ¤È¸À¤¦Ì¾Á°¤ò»ý¤Ä³°ÉôÆþÎϥ᥽¥Ã¥É¤òÄó
48 ¶¡¤·¤Æ¤¤¤ë¡£¤³¤ì¤Ï XIM (X Input Method) ¤ò¥Ð¥Ã¥¯¥°¥é¥¦¥ó¥É¤ÎÆþÎÏ¥¨
49 ¥ó¥¸¥ó¤È¤·¤ÆÍøÍѤ¹¤ë¡£¥·¥ó¥Ü¥ë @c Mxim ¤Ï @c Minput_driver ¤È¤¤¤¦
50 ¥×¥í¥Ñ¥Æ¥£¤ò»ý¤Ã¤Æ¤ª¤ê¡¢¤½¤ÎÃͤÏÆþÎϥɥ饤¥Ð @c minput_xim_driver
51 ¤Ø¤Î¥Ý¥¤¥ó¥¿¤Ç¤¢¤ë¡£ ¾ÜºÙ¤Ë¤Ä¤¤¤Æ¤Ï @c minput_xim_driver ¤ÎÀâÌÀ¤ò
56 #if !defined (FOR_DOXYGEN) || defined (DOXYGEN_INTERNAL_MODULE)
57 /*** @addtogroup m17nInternal
65 #include "m17n-misc.h"
67 #include "internal-gui.h"
80 MInputContextInfo *ic_info;
83 /* <geometry>.x and <geometry>.y are not used. */
84 MInputGUIWinInfo client;
85 /* In the following members, <geometry> is relative to <client>. */
86 MInputGUIWinInfo focus;
87 MInputGUIWinInfo preedit;
88 MInputGUIWinInfo status;
89 MInputGUIWinInfo candidates;
90 } MInputGUIContextInfo;
92 static MFace *status_face;
93 static MFaceBoxProp face_box_prop;
96 win_create_ic (MInputContext *ic)
98 MInputGUIContextInfo *win_ic_info;
99 MInputGUIArgIC *win_info = (MInputGUIArgIC *) ic->arg;
100 MFrame *frame = win_info->frame;
102 if ((*minput_default_driver.create_ic) (ic) < 0)
105 MSTRUCT_CALLOC (win_ic_info, MERROR_IM);
106 win_ic_info->ic_info = (MInputContextInfo *) ic->info;
107 win_ic_info->frame = frame;
108 win_ic_info->client.win = win_info->client;
109 (*frame->driver->window_geometry) (frame, win_info->client, win_info->client,
110 &win_ic_info->client.geometry);
111 win_ic_info->focus.win = win_info->focus;
112 (*frame->driver->window_geometry) (frame, win_info->focus, win_info->client,
113 &win_ic_info->focus.geometry);
115 win_ic_info->preedit.win = (*frame->driver->create_window) (frame, win_info->client);
116 win_ic_info->preedit.control.two_dimensional = 1;
117 win_ic_info->preedit.control.as_image = 0;
118 win_ic_info->preedit.control.with_cursor = 1;
119 win_ic_info->preedit.control.cursor_width = 1;
120 win_ic_info->preedit.control.enable_bidi = 1;
121 win_ic_info->preedit.geometry.x = -1;
122 win_ic_info->preedit.geometry.y = -1;
124 win_ic_info->status.win = (*frame->driver->create_window) (frame, win_info->client);
125 win_ic_info->status.control.as_image = 1;
126 win_ic_info->status.control.enable_bidi = 1;
128 win_ic_info->candidates.win = (*frame->driver->create_window) (frame, win_info->client);
129 win_ic_info->candidates.control.as_image = 1;
131 ic->info = win_ic_info;
137 win_destroy_ic (MInputContext *ic)
139 MInputGUIContextInfo *win_ic_info = (MInputGUIContextInfo *) ic->info;
140 MInputContextInfo *ic_info = (MInputContextInfo *) win_ic_info->ic_info;
141 MFrame *frame = win_ic_info->frame;
143 (*frame->driver->destroy_window) (frame, win_ic_info->preedit.win);
144 (*frame->driver->destroy_window) (frame, win_ic_info->status.win);
145 (*frame->driver->destroy_window) (frame, win_ic_info->candidates.win);
147 (*minput_default_driver.destroy_ic) (ic);
152 win_filter (MInputContext *ic, MSymbol key, void *arg)
154 MInputGUIContextInfo *win_ic_info = (MInputGUIContextInfo *) ic->info;
155 MInputContextInfo *ic_info = (MInputContextInfo *) win_ic_info->ic_info;
166 key = minput_event_to_key (win_ic_info->frame, arg);
171 ret = (*minput_default_driver.filter) (ic, key, arg);
172 ic->info = win_ic_info;
177 adjust_window_and_draw (MFrame *frame, MInputContext *ic, MText *mt, int type)
179 MInputGUIContextInfo *win_ic_info = (MInputGUIContextInfo *) ic->info;
180 MDrawControl *control;
182 MDrawMetric *geometry, physical, logical;
183 int xoff = win_ic_info->focus.geometry.x;
184 int yoff = win_ic_info->focus.geometry.y;
186 int len = mtext_nchars (mt);
190 win = win_ic_info->preedit.win;
191 control = &win_ic_info->preedit.control;
192 geometry = &win_ic_info->preedit.geometry;
197 win = win_ic_info->status.win;
198 control = &win_ic_info->status.control;
199 geometry = &win_ic_info->status.geometry;
203 win = win_ic_info->candidates.win;
204 control = &win_ic_info->candidates.control;
205 geometry = &win_ic_info->candidates.geometry;
208 mdraw_text_extents (frame, mt, 0, len, control, &physical, &logical, NULL);
209 x0 = physical.x, x1 = x0 + physical.width;
210 y0 = physical.y, y1 = y0 + physical.height;
213 if (x1 < logical.x + logical.width)
214 x1 = logical.x + logical.width;
217 if (y1 < logical.y + logical.height)
218 y1 = logical.y + logical.height;
219 physical.width = x1 - x0;
220 physical.height = y1 - y0;
221 physical.x = xoff + ic->spot.x;
222 if (physical.x + physical.width > win_ic_info->client.geometry.width)
223 physical.x = win_ic_info->client.geometry.width - physical.width;
228 physical.height = physical.width = 1;
229 physical.x = physical.y = -1;
233 if (y0 > - ic->spot.ascent)
235 physical.height += y0 + ic->spot.ascent;
236 y0 = - ic->spot.ascent;
238 if (y1 < ic->spot.descent)
240 physical.height += ic->spot.descent - y1;
242 physical.y = yoff + ic->spot.y + y0;
247 physical.y = yoff + ic->spot.y + ic->spot.descent + 2;
248 if (physical.y + physical.height > win_ic_info->client.geometry.height
249 && yoff + ic->spot.y - ic->spot.ascent - 2 - physical.height >= 0)
250 physical.y = yoff + ic->spot.y - ic->spot.ascent - 2 - physical.height;
254 if (win_ic_info->status.mapped)
256 /* We assume that status is already drawn. */
257 if (win_ic_info->status.geometry.y < yoff + ic->spot.y)
258 /* As there was no lower room for status, candidates must also
260 physical.y = win_ic_info->status.geometry.y - 1 - physical.height;
263 /* There was a lower room for status. */
264 physical.y = (win_ic_info->status.geometry.y
265 + win_ic_info->status.geometry.height
267 if (physical.y + physical.height
268 > win_ic_info->client.geometry.height)
269 /* But not for candidates. */
270 physical.y = (yoff + ic->spot.y - ic->spot.ascent - 1
276 physical.y = yoff + ic->spot.y + ic->spot.descent + 2;
277 if ((physical.y + physical.height
278 > win_ic_info->client.geometry.height)
279 && (yoff + ic->spot.y - ic->spot.ascent - 2 - physical.height
281 physical.y = (yoff + ic->spot.y - ic->spot.ascent - 2
286 (*frame->driver->adjust_window) (frame, win, geometry, &physical);
287 mdraw_text_with_control (frame, win, -x0, -y0, mt, 0, len, control);
291 win_callback (MInputContext *ic, MSymbol command)
293 MInputGUIContextInfo *win_ic_info = (MInputGUIContextInfo *) ic->info;
294 MFrame *frame = win_ic_info->frame;
296 if (command == Minput_preedit_draw)
299 MFace *face = mface ();
301 if (! win_ic_info->preedit.mapped)
303 (*frame->driver->map_window) (frame, win_ic_info->preedit.win);
304 win_ic_info->preedit.mapped = 1;
306 win_ic_info->preedit.control.cursor_pos = ic->cursor_pos;
307 if (ic->spot.fontsize)
308 mface_put_prop (face, Msize, (void *) ic->spot.fontsize);
309 mface_merge (face, mface_underline);
310 mtext_push_prop (ic->preedit, 0, mtext_nchars (ic->preedit),
312 M17N_OBJECT_UNREF (face);
313 if (ic->im->language != Mnil)
314 mtext_put_prop (ic->preedit, 0, mtext_nchars (ic->preedit), Mlanguage,
316 if (ic->candidate_list)
317 mtext_push_prop (ic->preedit, ic->candidate_from, ic->candidate_to,
318 Mface, mface_reverse_video);
319 if (mtext_nchars (ic->produced) == 0)
323 mt = mtext_dup (ic->produced);
324 mtext_cat (mt, ic->preedit);
325 win_ic_info->preedit.control.cursor_pos
326 += mtext_nchars (ic->produced);
328 adjust_window_and_draw (frame, ic, mt, 0);
329 if (ic->candidate_list)
330 mtext_pop_prop (ic->preedit, 0, mtext_nchars (ic->preedit), Mface);
331 mtext_pop_prop (ic->preedit, 0, mtext_nchars (ic->preedit), Mface);
332 if (mtext_nchars (ic->produced) != 0)
333 M17N_OBJECT_UNREF (mt);
335 else if (command == Minput_status_draw)
337 if (! win_ic_info->client.win)
339 mtext_put_prop (ic->status, 0, mtext_nchars (ic->status), Mface,
341 if (ic->im->language != Mnil)
342 mtext_put_prop (ic->status, 0, mtext_nchars (ic->status), Mlanguage,
344 adjust_window_and_draw (frame, ic, ic->status, 1);
346 else if (command == Minput_candidates_draw)
353 if (! ic->candidate_list || ! ic->candidate_show)
355 if (win_ic_info->candidates.mapped)
357 (*frame->driver->unmap_window) (frame, win_ic_info->candidates.win);
358 win_ic_info->candidates.mapped = 0;
363 if (! win_ic_info->candidates.mapped)
365 (*frame->driver->map_window) (frame, win_ic_info->candidates.win);
366 win_ic_info->candidates.mapped = 1;
370 group = ic->candidate_list;
373 if (mplist_key (group) == Mtext)
374 len = mtext_len (mplist_value (group));
376 len = mplist_length (mplist_value (group));
377 if (i + len > ic->candidate_index)
380 group = mplist_next (group);
384 if (mplist_key (group) == Mtext)
386 MText *candidates = (MText *) mplist_value (group);
388 from = (ic->candidate_index - i) * 2 + 1;
390 for (i = 0; i < len; i++)
392 mtext_cat_char (mt, ' ');
393 mtext_cat_char (mt, mtext_ref_char (candidates, i));
400 for (pl = (MPlist *) mplist_value (group);
401 i < ic->candidate_index && mplist_key (pl) != Mnil;
402 i++, pl = mplist_next (pl))
404 mtext_cat_char (mt, ' ');
405 mtext_cat (mt, (MText *) mplist_value (pl));
407 from = mtext_nchars (mt) + 1;
408 to = from + mtext_nchars ((MText *) mplist_value (pl));
409 for (; mplist_key (pl) != Mnil; pl = mplist_next (pl))
411 mtext_cat_char (mt, ' ');
412 mtext_cat (mt, (MText *) mplist_value (pl));
415 mtext_cat_char (mt, ' ');
416 mtext_push_prop (mt, 0, mtext_nchars (mt), Mface, status_face);
417 mtext_push_prop (mt, from, to, Mface, mface_reverse_video);
418 if (ic->im->language != Mnil)
419 mtext_put_prop (mt, 0, mtext_nchars (mt), Mlanguage, ic->im->language);
420 adjust_window_and_draw (frame, ic, mt, 2);
421 M17N_OBJECT_UNREF (mt);
423 else if (command == Minput_set_spot)
425 minput__callback (ic, Minput_preedit_draw);
426 minput__callback (ic, Minput_status_draw);
427 minput__callback (ic, Minput_candidates_draw);
429 else if (command == Minput_toggle)
433 minput__callback (ic, Minput_preedit_done);
434 minput__callback (ic, Minput_status_done);
435 minput__callback (ic, Minput_candidates_done);
439 minput__callback (ic, Minput_preedit_start);
440 minput__callback (ic, Minput_status_start);
441 minput__callback (ic, Minput_candidates_start);
444 else if (command == Minput_preedit_start)
447 else if (command == Minput_preedit_done)
449 if (win_ic_info->preedit.mapped)
451 (*frame->driver->unmap_window) (frame, win_ic_info->preedit.win);
452 win_ic_info->preedit.mapped = 0;
455 else if (command == Minput_status_start)
457 if (! win_ic_info->status.mapped)
459 (*frame->driver->map_window) (frame, win_ic_info->status.win);
460 win_ic_info->status.mapped = 1;
463 else if (command == Minput_status_done)
465 if (win_ic_info->status.mapped)
467 (*frame->driver->unmap_window) (frame, win_ic_info->status.win);
468 win_ic_info->status.mapped = 0;
471 else if (command == Minput_candidates_start)
473 if (! win_ic_info->candidates.mapped)
475 (*frame->driver->map_window) (frame, win_ic_info->candidates.win);
476 win_ic_info->candidates.mapped = 1;
479 else if (command == Minput_candidates_done)
481 if (win_ic_info->candidates.mapped)
483 (*frame->driver->unmap_window) (frame, win_ic_info->candidates.win);
484 win_ic_info->candidates.mapped = 0;
490 win_lookup (MInputContext *ic, MSymbol key, void *arg, MText *mt)
492 MInputGUIContextInfo *win_ic_info = (MInputGUIContextInfo *) ic->info;
493 MInputContextInfo *ic_info = (MInputContextInfo *) win_ic_info->ic_info;
497 ret = (*minput_default_driver.lookup) (ic, key, arg, mt);
498 ic->info = win_ic_info;
507 minput_gui_driver = minput_default_driver;
509 minput_gui_driver.create_ic = win_create_ic;
510 minput_gui_driver.destroy_ic = win_destroy_ic;
511 minput_gui_driver.filter = win_filter;
512 minput_gui_driver.lookup = win_lookup;
514 MPlist *plist = mplist ();
516 minput_gui_driver.callback_list = plist;
517 plist = mplist_add (plist, Minput_preedit_start, (void *) win_callback);
518 plist = mplist_add (plist, Minput_preedit_draw, (void *) win_callback);
519 plist = mplist_add (plist, Minput_preedit_done, (void *) win_callback);
520 plist = mplist_add (plist, Minput_status_start, (void *) win_callback);
521 plist = mplist_add (plist, Minput_status_draw, (void *) win_callback);
522 plist = mplist_add (plist, Minput_status_done, (void *) win_callback);
523 plist = mplist_add (plist, Minput_candidates_start, (void *) win_callback);
524 plist = mplist_add (plist, Minput_candidates_draw, (void *) win_callback);
525 plist = mplist_add (plist, Minput_candidates_done, (void *) win_callback);
526 plist = mplist_add (plist, Minput_set_spot, (void *) win_callback);
527 plist = mplist_add (plist, Minput_toggle, (void *) win_callback);
529 minput_driver = &minput_gui_driver;
531 face_box_prop.width = 1;
532 face_box_prop.color_top = face_box_prop.color_left
533 = face_box_prop.color_bottom = face_box_prop.color_right
535 face_box_prop.inner_hmargin = face_box_prop.inner_vmargin = 2;
536 face_box_prop.outer_hmargin = face_box_prop.outer_vmargin = 1;
537 status_face = mface ();
538 mface_put_prop (status_face, Mbox, &face_box_prop);
546 M17N_OBJECT_UNREF (status_face);
547 if (minput_gui_driver.callback_list)
549 M17N_OBJECT_UNREF (minput_gui_driver.callback_list);
550 minput_gui_driver.callback_list = NULL;
555 #endif /* !FOR_DOXYGEN || DOXYGEN_INTERNAL_MODULE */
560 /*** @addtogroup m17nInputMethodWin */
565 @brief Input driver for internal input methods on window systems.
567 The input driver @c minput_gui_driver is for internal input
568 methods to be used on window systems.
570 It creates sub-windows for a preedit text and a status text, and
571 displays them at the input spot set by the function
574 The macro M17N_INIT () set the variable @c minput_driver to the
575 pointer to this driver so that all internal input methods use it.
577 Therefore, unless @c minput_driver is changed from the default,
578 the driver dependent arguments to the functions whose name begin
579 with minput_ must are treated as follows.
581 The argument $ARG of the function minput_open_im () is ignored.
583 The argument $ARG of the function minput_create_ic () must be a
584 pointer to the structure @c MInputGUIArgIC. See the documentation
585 of @c MInputGUIArgIC for more details.
587 If the argument $KEY is @c Mnil, the argument $ARG of the
588 function minput_filter () must be a pointer to the object of type
589 @c XEvent. In that case, $KEY is generated from $ARG.
591 The argument $ARG of the function minput_lookup () must be the
592 same one as that of the function minput_filter (). */
595 @brief ¥¦¥£¥ó¥É¥¦¥·¥¹¥Æ¥à¤ÎÆâÉôÆþÎϥ᥽¥Ã¥ÉÍÑÆþÎϥɥ饤¥Ð.
597 ÆþÎϥɥ饤¥Ð @c minput_gui_driver ¤Ï¡¢¥¦¥£¥ó¥É¥¦¥·¥¹¥Æ¥à¾å¤ÇÍѤ¤¤é
598 ¤ì¤ëÆþÎϥ᥽¥Ã¥ÉÍѤǤ¢¤ë¡£
600 ¤³¤Î¥É¥é¥¤¥Ð¤Ï¡¢´Ø¿ô minput_set_spot () ¤Ë¤è¤Ã¤ÆÀßÄꤵ¤ì¤¿ÆþÎÏ¥¹¥Ý¥Ã
601 ¥È¤Ë preedit ¥Æ¥¥¹¥ÈÍѤΥµ¥Ö¥¦¥£¥ó¥É¥¦¤È status ¥Æ¥¥¹¥ÈÍѤΥµ¥Ö
602 ¥¦¥£¥ó¥É¥¦¤òºî¤ê¡¢¤½¤ì¤¾¤ì¤òɽ¼¨¤¹¤ë¡£
604 ¥Þ¥¯¥í M17N_INIT () ¤ÏÊÑ¿ô @c minput_driver ¤ò¤³¤Î¥É¥é¥¤¥Ð
605 ¤Ø¤Î¥Ý¥¤¥ó¥¿¤ËÀßÄꤷ¡¢Á´¤Æ¤ÎÆâÉôÆþÎϥ᥽¥Ã¥É¤¬¤³¤Î¥É¥é¥¤¥Ð¤ò»È¤¦¤è
608 ¤·¤¿¤¬¤Ã¤Æ¡¢@c minput_driver ¤¬¥Ç¥Õ¥©¥ë¥ÈÃͤΤޤޤǤ¢¤ì¤Ð¡¢minput_
609 ¤Ç»Ï¤Þ¤ë̾Á°¤ò»ý¤Ä´Ø¿ô¤Î°ú¿ô¤Î¤¦¤Á¥É¥é¥¤¥Ð°Í¸¤Î¤â¤Î¤Ï°Ê²¼¤Î¤è¤¦¤Ë
612 ´Ø¿ô minput_open_im () ¤Î°ú¿ô $ARG ¤Ï̵»ë¤µ¤ì¤ë¡£
614 ´Ø¿ô minput_create_ic () ¤Î°ú¿ô $ARG ¤Ï¹½Â¤ÂÎ @c MInputGUIArgIC ¤Ø
615 ¤Î¥Ý¥¤¥ó¥¿¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£¾ÜºÙ¤Ë¤Ä¤¤¤Æ¤Ï @c MInputGUIArgIC ¤Î
618 ´Ø¿ô minput_filter () ¤Î°ú¿ô $ARG ¤¬ @c Mnil ¤Î¾ì¹ç¡¢ $ARG ¤Ï @c
619 XEvent ·¿¤Î¥ª¥Ö¥¸¥§¥¯¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£¤³¤Î¾ì¹ç
620 $KEY ¤Ï $ARG ¤«¤éÀ¸À®¤µ¤ì¤ë¡£
622 ´Ø¿ô minput_lookup () ¤Î°ú¿ô $ARG ¤Ï´Ø¿ô minput_filter () ¤Î°ú¿ô
623 $ARG ¤ÈƱ¤¸¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ */
625 MInputDriver minput_gui_driver;
630 @brief Symbol of the name "xim".
632 The variable Mxim is a symbol of name "xim". It is a name of the
633 input method driver #minput_xim_driver. */
635 @brief "xim"¤ò̾Á°¤È¤·¤Æ»ý¤Ä¥·¥ó¥Ü¥ë .
637 ÊÑ¿ô Mxim ¤Ï"xim"¤ò̾Á°¤È¤·¤Æ»ý¤Ä¥·¥ó¥Ü¥ë¤Ç¤¢¤ë¡£"xim" ¤ÏÆþÎϥ᥽¥Ã
638 ¥É¥É¥é¥¤¥Ð #minput_xim_driver ¤Î̾Á°¤Ç¤¢¤ë¡£ */
645 @brief Convert an event to an input key.
647 The minput_event_to_key () function returns the input key
648 corresponding to event $EVENT on $FRAME by a window system
651 In the m17n-X library, $EVENT must be a pointer to the structure
652 @c XKeyEvent, and it is handled as below.
654 At first, the keysym name of $EVENT is acquired by the function @c
655 XKeysymToString. Then, the name is modified as below.
657 If the name is one of "a" .. "z" and $EVENT has a Shift modifier,
658 the name is converted to "A" .. "Z" respectively, and the Shift
661 If the name is one byte length and $EVENT has a Control modifier,
662 the byte is bitwise anded by 0x1F and the Control modifier is
665 If $EVENT still has Shift, Control, Meta, Alt, Super, and/or Hyper
666 modifiers, the name is preceded by "S-", "C-", "M-", "A-", "s-",
667 and/or "H-" respectively in this order.
669 For instance, if the keysym name is "a" and the event has Shift,
670 Meta, and Hyper modifiers, the resulting name is "H-M-A".
672 At last, a symbol who has the name is returned. */
675 @brief ¥¤¥Ù¥ó¥È¤òÆþÎÏ¥¡¼¤ËÊÑ´¹¤¹¤ë.
677 ´Ø¿ô minput_name_to_key () ¤Ï¡¢$FRAME ¤Î¥¤¥Ù¥ó¥È $EVENT ¤ËÂбþ¤¹¤ë
678 ÆþÎÏ¥¡¼¤òÊÖ¤¹¡£¤³¤³¤Ç¤Î¡ÖÂбþ¡×¤Ï¥¦¥£¥ó¥É¥¦¥·¥¹¥Æ¥à°Í¸¤Ç¤¢¤ë¡£
680 m17n-X ¥é¥¤¥Ö¥é¥ê¤Î¾ì¹ç¤Ë¤Ï¡¢$EVENT ¤Ï ¹½Â¤ÂÎ @c XKeyEvent ¤Ø¤Î¥Ý
681 ¥¤¥ó¥¿¤Ç¤¢¤ê¡¢¼¡¤Î¤è¤¦¤Ë½èÍý¤µ¤ì¤ë¡£
683 ¤Þ¤º¡¢´Ø¿ô @c XKeysymToString ¤Ë¤è¤Ã¤Æ¡¢$EVENT ¤Î keysym ̾¤ò¼èÆÀ
684 ¤·¡¢¼¡¤¤¤Ç°Ê²¼¤ÎÊѹ¹¤ò²Ã¤¨¤ë¡£
686 ̾Á°¤¬ "a" .. "z" ¤Î¤¤¤º¤ì¤«¤Ç¤¢¤Ã¤Æ $EVENT ¤Ë Shift ¥â¥Ç¥£¥Õ¥¡¥¤
687 ¥¢¤¬¤¢¤ì¤Ð¡¢Ì¾Á°¤Ï¤½¤ì¤¾¤ì "A" .. "Z" ¤ËÊÑ´¹¤µ¤ì¡¢Shift ¥â¥Ç¥£¥Õ¥¡
690 ̾Á°¤¬£±¥Ð¥¤¥ÈĹ¤Ç $EVENT ¤Ë Control ¥â¥Ç¥£¥Õ¥¡¥¤¥¢¤¬¤¢¤ì¤Ð¡¢Ì¾Á°
691 ¤È 0x1F ¤ò¥Ó¥Ã¥Èñ°Ì and ±é»»¤¹¤ë¡£Control ¥â¥Ç¥£¥Õ¥¡¥¤¥¢¤Ï¼è¤ê½ü
694 $EVENT ¤Ë¤Þ¤À Shift, Control, Meta, Alt, Super, Hyper ¤Ê¤É¤Î¥â¥Ç¥£
695 ¥Õ¥¡¥¤¥¢¤¬¤¢¤ì¤Ð¡¢Ì¾Á°¤ÎÁ°¤Ë¤½¤ì¤¾¤ì"S-", "C-", "M-", "A-", "s-",
698 ¤¿¤È¤¨¤Ð¡¢keysym ̾¤¬ "a" ¤Ç¥¤¥Ù¥ó¥È¤¬ Shift, Meta, and Hyper ¥â¥Ç¥£
699 ¥Õ¥¡¥¤¥¢¤ò»ý¤Æ¤Ð¡¢ÆÀ¤é¤ì¤ë̾Á°¤Ï "H-M-A" ¤Ç¤¢¤ë¡£
701 ºÇ¸å¤Ë¤½¤Î̾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤òÊÖ¤¹¡£*/
705 minput_event_to_key (MFrame *frame, void *event)
711 M_CHECK_READABLE (frame, MERROR_IM, Mnil);
712 key = (*frame->driver->parse_event) (frame, event, &modifiers);
716 name = msymbol_name (key);
717 str = alloca (strlen (name) + 2 * 6 + 1);
719 if (modifiers & MINPUT_KEY_SHIFT_MODIFIER)
721 if (modifiers & MINPUT_KEY_CONTROL_MODIFIER)
723 if (modifiers & MINPUT_KEY_META_MODIFIER)
725 if (modifiers & MINPUT_KEY_ALT_MODIFIER)
727 if (modifiers & MINPUT_KEY_SUPER_MODIFIER)
729 if (modifiers & MINPUT_KEY_HYPER_MODIFIER)
733 return msymbol (str);