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 detail.
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 detail. */
39 @addtogroup m17nInputMethodWin
40 @brief ¥¦¥£¥ó¥É¥¦¥·¥¹¥Æ¥à¾å¤ÎÆþÎϥ᥽¥Ã¥É¤Î¥µ¥Ý¡¼¥È
42 ÆþÎϥɥ饤¥Ð @c minput_gui_driver ¤Ï¡¢¥¦¥£¥ó¥É¥¦¥·¥¹¥Æ¥à¾å¤ÇÊØÍø¤Ë
43 ÍѤ¤¤é¤ì¤ëÆâÉôÆþÎϥ᥽¥Ã¥É¤Î¤¿¤á¤Î¤â¤Î¤Ç¤¢¤ë¡£¤³¤Î¥É¥é¥¤¥Ð¤ÏÆþÎÏ¥¹
44 ¥Ý¥Ã¥È¤Ë preedit ¥Æ¥¥¹¥È¤È status ¥Æ¥¥¹¥È¤òɽ¼¨¤¹¤ë¡£¾ÜºÙ¤Ë¤Ä¤¤
45 ¤Æ¤Ï @c 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 ¤Î¥É¥¥å
52 ¥á¥ó¥È¤ò»²¾È¤Î¤³¤È¡£ */
56 #if !defined (FOR_DOXYGEN) || defined (DOXYGEN_INTERNAL_MODULE)
57 /*** @addtogroup m17nInternal
64 #include "m17n-misc.h"
66 #include "internal-gui.h"
79 MInputContextInfo *ic_info;
82 /* <geometry>.x and <geometry>.y are not used. */
83 MInputGUIWinInfo client;
84 /* In the following members, <geometry> is relative to <client>. */
85 MInputGUIWinInfo focus;
86 MInputGUIWinInfo preedit;
87 MInputGUIWinInfo status;
88 MInputGUIWinInfo candidates;
89 } MInputGUIContextInfo;
91 static MFace *status_face;
92 static MFaceBoxProp face_box_prop;
95 win_create_ic (MInputContext *ic)
97 MInputGUIContextInfo *win_ic_info;
98 MInputGUIArgIC *win_info = (MInputGUIArgIC *) ic->arg;
99 MFrame *frame = win_info->frame;
101 if ((*minput_default_driver.create_ic) (ic) < 0)
104 MSTRUCT_CALLOC (win_ic_info, MERROR_IM);
105 win_ic_info->ic_info = (MInputContextInfo *) ic->info;
106 win_ic_info->frame = frame;
107 win_ic_info->client.win = win_info->client;
108 mwin__window_geometry (frame, win_info->client, win_info->client,
109 &win_ic_info->client.geometry);
110 win_ic_info->focus.win = win_info->focus;
111 mwin__window_geometry (frame, win_info->focus, win_info->client,
112 &win_ic_info->focus.geometry);
114 win_ic_info->preedit.win = mwin__create_window (frame, win_info->client);
115 win_ic_info->preedit.control.two_dimensional = 1;
116 win_ic_info->preedit.control.as_image = 1;
117 win_ic_info->preedit.control.with_cursor = 1;
118 win_ic_info->preedit.control.cursor_width = 1;
119 win_ic_info->preedit.control.enable_bidi = 1;
120 win_ic_info->preedit.geometry.x = -1;
121 win_ic_info->preedit.geometry.y = -1;
123 win_ic_info->status.win = mwin__create_window (frame, win_info->client);
124 win_ic_info->status.control.as_image = 1;
125 win_ic_info->status.control.enable_bidi = 1;
127 win_ic_info->candidates.win = mwin__create_window (frame, win_info->client);
128 win_ic_info->candidates.control.as_image = 1;
130 ic->info = win_ic_info;
136 win_destroy_ic (MInputContext *ic)
138 MInputGUIContextInfo *win_ic_info = (MInputGUIContextInfo *) ic->info;
139 MInputContextInfo *ic_info = (MInputContextInfo *) win_ic_info->ic_info;
141 mwin__destroy_window (win_ic_info->frame, win_ic_info->preedit.win);
142 mwin__destroy_window (win_ic_info->frame, win_ic_info->status.win);
143 mwin__destroy_window (win_ic_info->frame, win_ic_info->candidates.win);
145 (*minput_default_driver.destroy_ic) (ic);
150 win_filter (MInputContext *ic, MSymbol key, void *arg)
152 MInputGUIContextInfo *win_ic_info = (MInputGUIContextInfo *) ic->info;
153 MInputContextInfo *ic_info = (MInputContextInfo *) win_ic_info->ic_info;
164 key = minput_event_to_key (win_ic_info->frame, arg);
169 ret = (*minput_default_driver.filter) (ic, key, arg);
170 ic->info = win_ic_info;
175 adjust_window_and_draw (MFrame *frame, MInputContext *ic, MText *mt, int type)
177 MInputGUIContextInfo *win_ic_info = (MInputGUIContextInfo *) ic->info;
178 MDrawControl *control;
180 MDrawMetric *geometry, physical, logical;
181 int xoff = win_ic_info->focus.geometry.x;
182 int yoff = win_ic_info->focus.geometry.y;
184 int len = mtext_nchars (mt);
188 win = win_ic_info->preedit.win;
189 control = &win_ic_info->preedit.control;
190 geometry = &win_ic_info->preedit.geometry;
195 win = win_ic_info->status.win;
196 control = &win_ic_info->status.control;
197 geometry = &win_ic_info->status.geometry;
201 win = win_ic_info->candidates.win;
202 control = &win_ic_info->candidates.control;
203 geometry = &win_ic_info->candidates.geometry;
206 mdraw_text_extents (frame, mt, 0, len, control, &physical, &logical, NULL);
207 x0 = physical.x, x1 = x0 + physical.width;
208 y0 = physical.y, y1 = y0 + physical.height;
211 if (x1 < logical.x + logical.width)
212 x1 = logical.x + logical.width;
215 if (y1 < logical.y + logical.height)
216 y1 = logical.y + logical.height;
217 physical.width = x1 - x0;
218 physical.height = y1 - y0;
219 physical.x = xoff + ic->spot.x;
220 if (physical.x + physical.width > win_ic_info->client.geometry.width)
221 physical.x = win_ic_info->client.geometry.width - physical.width;
224 if (y0 > - ic->spot.ascent)
226 physical.height += y0 + ic->spot.ascent;
227 y0 = - ic->spot.ascent;
229 if (y1 < ic->spot.descent)
231 physical.height += ic->spot.descent - y1;
233 physical.y = yoff + ic->spot.y + y0;
237 physical.y = yoff + ic->spot.y + ic->spot.descent + 2;
238 if (physical.y + physical.height > win_ic_info->client.geometry.height
239 && yoff + ic->spot.y - ic->spot.ascent - 2 - physical.height >= 0)
240 physical.y = yoff + ic->spot.y - ic->spot.ascent - 2 - physical.height;
244 if (win_ic_info->status.mapped)
246 /* We assume that status is already drawn. */
247 if (win_ic_info->status.geometry.y < yoff + ic->spot.y)
248 /* As there was no lower room for status, candidates must also
250 physical.y = win_ic_info->status.geometry.y - 1 - physical.height;
253 /* There was a lower room for status. */
254 physical.y = (win_ic_info->status.geometry.y
255 + win_ic_info->status.geometry.height
257 if (physical.y + physical.height
258 > win_ic_info->client.geometry.height)
259 /* But not for candidates. */
260 physical.y = (yoff + ic->spot.y - ic->spot.ascent - 1
266 physical.y = yoff + ic->spot.y + ic->spot.descent + 2;
267 if ((physical.y + physical.height
268 > win_ic_info->client.geometry.height)
269 && (yoff + ic->spot.y - ic->spot.ascent - 2 - physical.height
271 physical.y = (yoff + ic->spot.y - ic->spot.ascent - 2
276 mwin__adjust_window (frame, win, geometry, &physical);
277 mdraw_text_with_control (frame, win, -x0, -y0, mt, 0, len, control);
281 win_callback (MInputContext *ic, MSymbol command)
283 MInputGUIContextInfo *win_ic_info = (MInputGUIContextInfo *) ic->info;
284 MFrame *frame = win_ic_info->frame;
286 if (command == Minput_preedit_draw)
289 MFace *face = mface ();
291 if (! win_ic_info->preedit.mapped)
293 mwin__map_window (frame, win_ic_info->preedit.win);
294 win_ic_info->preedit.mapped = 1;
296 win_ic_info->preedit.control.cursor_pos = ic->cursor_pos;
297 if (ic->spot.fontsize)
298 mface_put_prop (face, Msize, (void *) ic->spot.fontsize);
299 mface_merge (face, mface_underline);
300 mtext_push_prop (ic->preedit, 0, mtext_nchars (ic->preedit),
302 M17N_OBJECT_UNREF (face);
303 if (ic->im->language != Mnil)
304 mtext_put_prop (ic->preedit, 0, mtext_nchars (ic->preedit), Mlanguage,
306 if (ic->candidate_list)
307 mtext_push_prop (ic->preedit, ic->candidate_from, ic->candidate_to,
308 Mface, mface_reverse_video);
309 if (mtext_nchars (ic->produced) == 0)
313 mt = mtext_dup (ic->produced);
314 mtext_cat (mt, ic->preedit);
315 win_ic_info->preedit.control.cursor_pos
316 += mtext_nchars (ic->produced);
318 adjust_window_and_draw (frame, ic, mt, 0);
319 if (ic->candidate_list)
320 mtext_pop_prop (ic->preedit, 0, mtext_nchars (ic->preedit), Mface);
321 mtext_pop_prop (ic->preedit, 0, mtext_nchars (ic->preedit), Mface);
322 if (mtext_nchars (ic->produced) != 0)
323 M17N_OBJECT_UNREF (mt);
325 else if (command == Minput_status_draw)
327 if (! win_ic_info->client.win)
329 mtext_put_prop (ic->status, 0, mtext_nchars (ic->status), Mface,
331 if (ic->im->language != Mnil)
332 mtext_put_prop (ic->status, 0, mtext_nchars (ic->status), Mlanguage,
334 adjust_window_and_draw (frame, ic, ic->status, 1);
336 else if (command == Minput_candidates_draw)
343 if (! ic->candidate_list || ! ic->candidate_show)
345 if (win_ic_info->candidates.mapped)
347 mwin__unmap_window (frame, win_ic_info->candidates.win);
348 win_ic_info->candidates.mapped = 0;
353 if (! win_ic_info->candidates.mapped)
355 mwin__map_window (frame, win_ic_info->candidates.win);
356 win_ic_info->candidates.mapped = 1;
360 group = ic->candidate_list;
363 if (mplist_key (group) == Mtext)
364 len = mtext_len (mplist_value (group));
366 len = mplist_length (mplist_value (group));
367 if (i + len > ic->candidate_index)
370 group = mplist_next (group);
374 if (mplist_key (group) == Mtext)
376 MText *candidates = (MText *) mplist_value (group);
378 from = (ic->candidate_index - i) * 2 + 1;
380 for (i = 0; i < len; i++)
382 mtext_cat_char (mt, ' ');
383 mtext_cat_char (mt, mtext_ref_char (candidates, i));
390 for (pl = (MPlist *) mplist_value (group);
391 i < ic->candidate_index && mplist_key (pl) != Mnil;
392 i++, pl = mplist_next (pl))
394 mtext_cat_char (mt, ' ');
395 mtext_cat (mt, (MText *) mplist_value (pl));
397 from = mtext_nchars (mt) + 1;
398 to = from + mtext_nchars ((MText *) mplist_value (pl));
399 for (; mplist_key (pl) != Mnil; pl = mplist_next (pl))
401 mtext_cat_char (mt, ' ');
402 mtext_cat (mt, (MText *) mplist_value (pl));
405 mtext_cat_char (mt, ' ');
406 mtext_push_prop (mt, 0, mtext_nchars (mt), Mface, status_face);
407 mtext_push_prop (mt, from, to, Mface, mface_reverse_video);
408 if (ic->im->language != Mnil)
409 mtext_put_prop (mt, 0, mtext_nchars (mt), Mlanguage, ic->im->language);
410 adjust_window_and_draw (frame, ic, mt, 2);
411 M17N_OBJECT_UNREF (mt);
413 else if (command == Minput_set_spot)
415 minput__callback (ic, Minput_preedit_draw);
416 minput__callback (ic, Minput_status_draw);
417 minput__callback (ic, Minput_candidates_draw);
419 else if (command == Minput_toggle)
423 minput__callback (ic, Minput_preedit_done);
424 minput__callback (ic, Minput_status_done);
425 minput__callback (ic, Minput_candidates_done);
429 minput__callback (ic, Minput_preedit_start);
430 minput__callback (ic, Minput_status_start);
431 minput__callback (ic, Minput_candidates_start);
434 else if (command == Minput_preedit_start)
437 else if (command == Minput_preedit_done)
439 if (win_ic_info->preedit.mapped)
441 mwin__unmap_window (frame, win_ic_info->preedit.win);
442 win_ic_info->preedit.mapped = 0;
445 else if (command == Minput_status_start)
447 if (! win_ic_info->status.mapped)
449 mwin__map_window (frame, win_ic_info->status.win);
450 win_ic_info->status.mapped = 1;
453 else if (command == Minput_status_done)
455 if (win_ic_info->status.mapped)
457 mwin__unmap_window (frame, win_ic_info->status.win);
458 win_ic_info->status.mapped = 0;
461 else if (command == Minput_candidates_start)
463 if (! win_ic_info->candidates.mapped)
465 mwin__map_window (frame, win_ic_info->candidates.win);
466 win_ic_info->candidates.mapped = 1;
469 else if (command == Minput_candidates_done)
471 if (win_ic_info->candidates.mapped)
473 mwin__unmap_window (frame, win_ic_info->candidates.win);
474 win_ic_info->candidates.mapped = 0;
480 win_lookup (MInputContext *ic, MSymbol key, void *arg, MText *mt)
482 MInputGUIContextInfo *win_ic_info = (MInputGUIContextInfo *) ic->info;
483 MInputContextInfo *ic_info = (MInputContextInfo *) win_ic_info->ic_info;
487 ret = (*minput_default_driver.lookup) (ic, key, arg, mt);
488 ic->info = win_ic_info;
497 minput_gui_driver = minput_default_driver;
499 minput_gui_driver.create_ic = win_create_ic;
500 minput_gui_driver.destroy_ic = win_destroy_ic;
501 minput_gui_driver.filter = win_filter;
502 minput_gui_driver.lookup = win_lookup;
504 MPlist *plist = mplist ();
506 minput_gui_driver.callback_list = plist;
507 plist = mplist_add (plist, Minput_preedit_start, (void *) win_callback);
508 plist = mplist_add (plist, Minput_preedit_draw, (void *) win_callback);
509 plist = mplist_add (plist, Minput_preedit_done, (void *) win_callback);
510 plist = mplist_add (plist, Minput_status_start, (void *) win_callback);
511 plist = mplist_add (plist, Minput_status_draw, (void *) win_callback);
512 plist = mplist_add (plist, Minput_status_done, (void *) win_callback);
513 plist = mplist_add (plist, Minput_candidates_start, (void *) win_callback);
514 plist = mplist_add (plist, Minput_candidates_draw, (void *) win_callback);
515 plist = mplist_add (plist, Minput_candidates_done, (void *) win_callback);
516 plist = mplist_add (plist, Minput_set_spot, (void *) win_callback);
517 plist = mplist_add (plist, Minput_toggle, (void *) win_callback);
519 minput_driver = &minput_gui_driver;
521 face_box_prop.width = 1;
522 face_box_prop.color_top = face_box_prop.color_left
523 = face_box_prop.color_bottom = face_box_prop.color_right
525 face_box_prop.inner_hmargin = face_box_prop.inner_vmargin = 2;
526 face_box_prop.outer_hmargin = face_box_prop.outer_vmargin = 1;
527 status_face = mface ();
528 mface_put_prop (status_face, Mbox, &face_box_prop);
536 M17N_OBJECT_UNREF (status_face);
537 if (minput_gui_driver.callback_list)
539 M17N_OBJECT_UNREF (minput_gui_driver.callback_list);
540 minput_gui_driver.callback_list = NULL;
545 #endif /* !FOR_DOXYGEN || DOXYGEN_INTERNAL_MODULE */
550 /*** @addtogroup m17nInputMethodWin */
555 @brief Input driver for internal input methods on window systems.
557 The input driver @c minput_gui_driver is for internal input
558 methods to be used on window systems.
560 It creates sub-windows for a preedit text and a status text, and
561 displays them at the input spot set by the function
564 The function m17n_initialize_win () set the variable @c
565 minput_driver to the pointer to this driver so that all internal
566 input methods use it.
568 Therefore, unless @c minput_driver is changed from the default,
569 the driver dependent arguments to the functions whose name begin
570 with minput_ must are treated as follows.
572 The argument $ARG of the function minput_open_im () is ignored.
574 The argument $ARG of the function minput_create_ic () must be a
575 pointer to the structure @c MInputGUIArgIC. See the documentation
576 of @c MInputGUIArgIC for more detail.
578 If the argument $KEY is @c Mnil, the argument $ARG of the
579 function minput_filter () must be a pointer to the object of type
580 @c XEvent. In that case, $KEY is generated from $ARG.
582 The argument $ARG of the function minput_lookup () must be the
583 same one as that of the function minput_filter (). */
586 @brief ¥¦¥£¥ó¥É¥¦¥·¥¹¥Æ¥à¤ÎÆâÉôÆþÎϥ᥽¥Ã¥ÉÍÑÆþÎϥɥ饤¥Ð
588 ÆþÎϥɥ饤¥Ð @c minput_gui_driver ¤Ï¡¢¥¦¥£¥ó¥É¥¦¥·¥¹¥Æ¥à¾å¤ÇÍѤ¤¤é
589 ¤ì¤ëÆþÎϥ᥽¥Ã¥ÉÍѤΤâ¤Î¤Ç¤¢¤ë¡£
591 ¤³¤Î¥É¥é¥¤¥Ð¤Ï¡¢´Ø¿ô minput_set_spot () ¤Ë¤è¤Ã¤ÆÀßÄꤵ¤ì¤¿ÆþÎÏ¥¹¥Ý¥Ã
592 ¥È¤Ë preedit ¥Æ¥¥¹¥ÈÍѤΥµ¥Ö¥¦¥£¥ó¥É¥¦¤È status ¥Æ¥¥¹¥ÈÍѤΥµ¥Ö
593 ¥¦¥£¥ó¥É¥¦¤òºî¤ê¡¢¤½¤ì¤¾¤ì¤òɽ¼¨¤¹¤ë¡£
595 ´Ø¿ô m17n_initialize_win () ¤ÏÊÑ¿ô @c minput_driver ¤ò¤³¤Î¥É¥é¥¤¥Ð
596 ¤Ø¤Î¥Ý¥¤¥ó¥¿¤ËÀßÄꤷ¡¢Á´¤Æ¤ÎÆâÉôÆþÎϥ᥽¥Ã¥É¤¬¤³¤Î¥É¥é¥¤¥Ð¤ò»È¤¦¤è
599 ¤·¤¿¤¬¤Ã¤Æ¡¢@c minput_driver ¤¬¥Ç¥Õ¥©¥ë¥ÈÃͤΤޤޤǤ¢¤ì¤Ð¡¢minput_
600 ¤Ç»Ï¤Þ¤ë̾Á°¤ò»ý¤Ä°Ê²¼¤Î´Ø¿ô·²¤Î¥É¥é¥¤¥Ð¤Ë°Í¸¤¹¤ë°ú¿ô¤Ï¼¡¤Î¤è¤¦¤Ë
603 ´Ø¿ô minput_open_im () ¤Î°ú¿ô $ARG ¤Ï̵»ë¤µ¤ì¤ë¡£
605 ´Ø¿ô minput_create_ic () ¤Î°ú¿ô $ARG ¤Ï¹½Â¤ÂÎ @c MInputGUIArgIC ¤Ø
606 ¤Î¥Ý¥¤¥ó¥¿¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£¾ÜºÙ¤Ë¤Ä¤¤¤Æ¤Ï @c MInputGUIArgIC ¤Î
607 ¥É¥¥å¥á¥ó¥È¤ò»²¾È¤Î¤³¤È¡£
609 ´Ø¿ô minput_filter () ¤Î°ú¿ô $ARG ¤¬ @c Mnil ¤Î¾ì¹ç¡¢ $ARG ¤Ï
610 XEvent ·¿¤Î¥ª¥Ö¥¸¥§¥¯¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£¤³¤Î¾ì¹ç $KEY
611 ¤Ï $ARG ¤«¤éÀ¸À®¤µ¤ì¤ë¡£
613 ´Ø¿ô minput_lookup () ¤Î°ú¿ô $ARG ¤Ï´Ø¿ô minput_filter () °ú¿ô
614 $ARG ¤ÈƱ¤¸¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ */
616 MInputDriver minput_gui_driver;
621 @brief Convert an event to an input key.
623 The minput_event_to_key () function returns the input key
624 corresponding to event $EVENT on $FRAME by a window system
627 In the m17n-X library, $EVENT must be a pointer to the struct @c
628 XKeyEvent, and it is handled as below.
630 At first, the keysym name of $EVENT is acquired by the function @c
633 Then, the name is modified as below.
635 If the name is one of "a" .. "z" and $EVENT has a Shift modifier,
636 the name is converted to "A" .. "Z" respectively, and the Shift
639 If the name is one byte length and $EVENT has a Control modifier,
640 the byte is bitwise anded by 0x1F and the Control modifier is
643 If $EVENT still has Shift, Control, Meta, Alt, Super, and/or Hyper
644 modifiers, the name is prepended by "S-", "C-", "M-", "A-", "s-",
645 and/or "H-" respectively in this order.
647 For instance, if the keysym name is "a" and the event has Shift,
648 Meta, and Hyper modifiers, the resulting name is "H-M-A".
650 At last, a symbol who has the name is returned. */
653 @brief ¥¡¼Ì¾¾Î¤òÆþÎÏ¥¡¼¤ËÊÑ´¹¤¹¤ë
655 ´Ø¿ô minput_name_to_key () ¤Ï¡¢Ì¾Á° $NAME ¤ËÂбþ¤¹¤ëÆþÎÏ¥¡¼¤òÊÖ¤¹¡£
657 $NAME ¤Ï¼¡¤Î·Á¤ò¤È¤ë¡£
659 [ MODIFIER-MNEMONIC '-' ] * KEY-NAME
661 ¤³¤³¤Ç MODIFIER-MNEMONIC ¤Ï 'S', 'C', 'M', 'A', 's', 'H' ¤Î¤¤¤º¤ì
662 ¤«¤Ç¤¢¤ê¡¢¤½¤ì¤¾¤ì Shift, Control, Meta, Alt, Super, Hyper ¤Î³Æ¥â
663 ¥Ç¥£¥Õ¥¡¥¤¥¢¤ò¼¨¤¹¡£KEY-NAME ¤ÏÆþÎÏ¥¡¼¤Î¥·¥ó¥Ü¥ê¥Ã¥¯¤Ê̾Á°¤òɽ¤¹Ê¸»úÎó¡£
665 ÆþÎÏ¥¡¼¤Î²¼ 16 ¥Ó¥Ã¥È¤Ï "keysym bits" ¤È¤è¤Ð¤ì¡¢KEY-NAME ¤ËÂбþ¤¹
666 ¤ë¥³¡¼¥É¤òɽ¤¹¡£¾å7 bits (¤Ä¤Þ¤ê 17 ¥Ó¥Ã¥ÈÌܤ«¤é 23 ¥Ó¥Ã¥ÈÌܤޤÇ)
667 ¤Ï"modifier bits" ¤È¸Æ¤Ð¤ì¡¢MODIFIER-MNEMONIC ¤òɽ¸½¤·¤Æ¤¤¤ë¡£
669 KEY-NAME ¤¬ 1 ¥Ð¥¤¥ÈŤǤ¢¤ë¾ì¹ç¡¢ÆþÎÏ¥¡¼¤Ï¼¡¤Î¤è¤¦¤Ë¹½À®¤µ¤ì¤ë¡£
671 ¤Þ¤º¡¢keysym bits ¤Ë¤Ï¤½¤Î¥Ð¥¤¥È¥³¡¼¥É¤½¤Î¤â¤Î¤¬ÀßÄꤵ¤ì¤ë¡£
673 ¼¡¤¤¤Ç¡¢Shift, Control, Meta ¤Î³Æ¥â¥Ç¥£¥Õ¥¡¥¤¥¢¤Ï°Ê²¼¤Î¼ê³¤¤Ç
674 keysym bits ¤ËÈ¿±Ç¤µ¤ì¤ë¡£
676 (1) Shift ¥â¥Ç¥£¥Õ¥¡¥¤¥¢¤¬¤¢¤ê¡¢keysym bits ¤¬¾®Ê¸»ú¤Ç¤¢¤ì¤Ð(¤Ä¤Þ
677 ¤ê 'a' ¤«¤é 'z' ¤Ç¤¢¤ì¤Ð), Âçʸ»ú (¤Ä¤Þ¤ê 'A' through 'Z') ¤ËÊÑ´¹
678 ¤µ¤ì¤ë¡£Shift ¥â¥Ç¥£¥Õ¥¡¥¤¥¢¤Ï modifier bits ¤«¤é¼è¤ê½ü¤«¤ì¤ë¡£
680 (2) Control ¥â¥Ç¥£¥Õ¥¡¥¤¥¢¤¬¤¢¤ì¤Ð, keysym bits ¤Ï¥Ó¥Ã¥Èñ°Ì¤Ç
681 0x1F ¤È and ±é»»¤ò¹Ô¤¦¡£Control ¥â¥Ç¥£¥Õ¥¡¥¤¥¢¤Ï modifier bits
684 (3) Meta ¥â¥Ç¥£¥Õ¥¡¥¤¥¢¤¬¤¢¤ì¤Ð, keysym bits ¤Ï¥Ó¥Ã¥Èñ°Ì¤Ç 0x80
685 ¤È or ±é»»¤ò¹Ô¤¦¡£ Meta ¥â¥Ç¥£¥Õ¥¡¥¤¥¢¤Ï modifier bits ¤«¤é¼è¤ê½ü
688 ¤¿¤È¤¨¤Ð¡¢"S-a" ¤È "A" ¤Ï¤É¤Á¤é¤â 65 ¤ò¡¢"C-a" ¤È "C-A" ¤Ï¤É¤Á¤é¤â
689 1 ¤òÊÖ¤·¡¢"M-a" ¤Ï 225 ¤ò, "C-M-a" ¤Ï 129 ¤òÊÖ¤¹¡£
691 KEY-NAME ¤¬ 2 ¥Ð¥¤¥È°Ê¾å¤Ç¤¢¤ë»þ¤Ë¤Ï¡¢Âбþ¤¹¤ëkeysym bits ¤Ï@c
692 m17n @c ¥é¥¤¥Ö¥é¥ê ÆâÉô¤Î¥Æ¡¼¥Ö¥ë¤Ë¤è¤Ã¤ÆÆÀ¤ë»ö¤¬¤Ç¤¤ë¡£¤³¤Î¤È¤
693 ¥Æ¡¼¥Ö¥ë¤Ë KEY-NAME ¤¬¤Ê¤±¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï -1 ¤òÊÖ¤¹¡£ */
696 minput_event_to_key (MFrame *frame, void *event)
699 MSymbol key = mwin__parse_event (frame, event, &modifiers);
705 name = msymbol_name (key);
706 str = alloca (strlen (name) + 2 * 6 + 1);
708 if (modifiers & MINPUT_KEY_SHIFT_MODIFIER)
710 if (modifiers & MINPUT_KEY_CONTROL_MODIFIER)
712 if (modifiers & MINPUT_KEY_META_MODIFIER)
714 if (modifiers & MINPUT_KEY_ALT_MODIFIER)
716 if (modifiers & MINPUT_KEY_SUPER_MODIFIER)
718 if (modifiers & MINPUT_KEY_HYPER_MODIFIER)
722 return msymbol (str);