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.disable_caching = 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;
126 win_ic_info->candidates.win = mwin__create_window (frame, win_info->client);
127 win_ic_info->candidates.control.as_image = 1;
129 ic->info = win_ic_info;
135 win_destroy_ic (MInputContext *ic)
137 MInputGUIContextInfo *win_ic_info = (MInputGUIContextInfo *) ic->info;
138 MInputContextInfo *ic_info = (MInputContextInfo *) win_ic_info->ic_info;
140 mwin__destroy_window (win_ic_info->frame, win_ic_info->preedit.win);
141 mwin__destroy_window (win_ic_info->frame, win_ic_info->status.win);
142 mwin__destroy_window (win_ic_info->frame, win_ic_info->candidates.win);
144 (*minput_default_driver.destroy_ic) (ic);
149 win_filter (MInputContext *ic, MSymbol key, void *arg)
151 MInputGUIContextInfo *win_ic_info = (MInputGUIContextInfo *) ic->info;
152 MInputContextInfo *ic_info = (MInputContextInfo *) win_ic_info->ic_info;
163 key = minput_event_to_key (win_ic_info->frame, arg);
168 ret = (*minput_default_driver.filter) (ic, key, arg);
169 ic->info = win_ic_info;
174 adjust_window_and_draw (MFrame *frame, MInputContext *ic, MText *mt, int type)
176 MInputGUIContextInfo *win_ic_info = (MInputGUIContextInfo *) ic->info;
177 MDrawControl *control;
179 MDrawMetric *geometry, physical, logical;
180 int xoff = win_ic_info->focus.geometry.x;
181 int yoff = win_ic_info->focus.geometry.y;
183 int len = mtext_nchars (mt);
187 win = win_ic_info->preedit.win;
188 control = &win_ic_info->preedit.control;
189 geometry = &win_ic_info->preedit.geometry;
194 win = win_ic_info->status.win;
195 control = &win_ic_info->status.control;
196 geometry = &win_ic_info->status.geometry;
200 win = win_ic_info->candidates.win;
201 control = &win_ic_info->candidates.control;
202 geometry = &win_ic_info->candidates.geometry;
205 mdraw_text_extents (frame, mt, 0, len, control, &physical, &logical, NULL);
206 x0 = physical.x, x1 = x0 + physical.width;
207 y0 = physical.y, y1 = y0 + physical.height;
210 if (x1 < logical.x + logical.width)
211 x1 = logical.x + logical.width;
214 if (y1 < logical.y + logical.height)
215 y1 = logical.y + logical.height;
216 physical.width = x1 - x0;
217 physical.height = y1 - y0;
218 physical.x = xoff + ic->spot.x;
219 if (physical.x + physical.width > win_ic_info->client.geometry.width)
220 physical.x = win_ic_info->client.geometry.width - physical.width;
223 if (y0 > - ic->spot.ascent)
225 physical.height += y0 + ic->spot.ascent;
226 y0 = - ic->spot.ascent;
228 if (y1 < ic->spot.descent)
230 physical.height += ic->spot.descent - y1;
232 physical.y = yoff + ic->spot.y + y0;
236 physical.y = yoff + ic->spot.y + ic->spot.descent + 2;
237 if (physical.y + physical.height > win_ic_info->client.geometry.height
238 && yoff + ic->spot.y - ic->spot.ascent - 2 - physical.height >= 0)
239 physical.y = yoff + ic->spot.y - ic->spot.ascent - 2 - physical.height;
243 if (win_ic_info->status.mapped)
245 /* We assume that status is already drawn. */
246 if (win_ic_info->status.geometry.y < yoff + ic->spot.y)
247 /* As there was no lower room for status, candidates must also
249 physical.y = win_ic_info->status.geometry.y - 1 - physical.height;
252 /* There was a lower room for status. */
253 physical.y = (win_ic_info->status.geometry.y
254 + win_ic_info->status.geometry.height
256 if (physical.y + physical.height
257 > win_ic_info->client.geometry.height)
258 /* But not for candidates. */
259 physical.y = (yoff + ic->spot.y - ic->spot.ascent - 1
265 physical.y = yoff + ic->spot.y + ic->spot.descent + 2;
266 if ((physical.y + physical.height
267 > win_ic_info->client.geometry.height)
268 && (yoff + ic->spot.y - ic->spot.ascent - 2 - physical.height
270 physical.y = (yoff + ic->spot.y - ic->spot.ascent - 2
275 mwin__adjust_window (frame, win, geometry, &physical);
276 mdraw_text_with_control (frame, win, -x0, -y0, mt, 0, len, control);
280 win_callback (MInputContext *ic, MSymbol command)
282 MInputGUIContextInfo *win_ic_info = (MInputGUIContextInfo *) ic->info;
283 MFrame *frame = win_ic_info->frame;
285 if (command == Minput_preedit_draw)
288 MFace *face = mface ();
290 if (! win_ic_info->preedit.mapped)
292 mwin__map_window (frame, win_ic_info->preedit.win);
293 win_ic_info->preedit.mapped = 1;
295 win_ic_info->preedit.control.cursor_pos = ic->cursor_pos;
296 if (ic->spot.fontsize)
297 mface_put_prop (face, Msize, (void *) ic->spot.fontsize);
298 mface_merge (face, mface_underline);
299 mtext_push_prop (ic->preedit, 0, mtext_nchars (ic->preedit),
301 M17N_OBJECT_UNREF (face);
302 if (ic->im->language != Mnil)
303 mtext_put_prop (ic->preedit, 0, mtext_nchars (ic->preedit), Mlanguage,
305 if (ic->candidate_list)
306 mtext_push_prop (ic->preedit, ic->candidate_from, ic->candidate_to,
307 Mface, mface_reverse_video);
308 if (mtext_nchars (ic->produced) == 0)
312 mt = mtext_dup (ic->produced);
313 mtext_cat (mt, ic->preedit);
314 win_ic_info->preedit.control.cursor_pos
315 += mtext_nchars (ic->produced);
317 adjust_window_and_draw (frame, ic, mt, 0);
318 if (ic->candidate_list)
319 mtext_pop_prop (ic->preedit, 0, mtext_nchars (ic->preedit), Mface);
320 mtext_pop_prop (ic->preedit, 0, mtext_nchars (ic->preedit), Mface);
321 if (mtext_nchars (ic->produced) != 0)
322 M17N_OBJECT_UNREF (mt);
324 else if (command == Minput_status_draw)
326 if (! win_ic_info->client.win)
328 mtext_put_prop (ic->status, 0, mtext_nchars (ic->status), Mface,
330 if (ic->im->language != Mnil)
331 mtext_put_prop (ic->status, 0, mtext_nchars (ic->status), Mlanguage,
333 adjust_window_and_draw (frame, ic, ic->status, 1);
335 else if (command == Minput_candidates_draw)
342 if (! ic->candidate_list || ! ic->candidate_show)
344 if (win_ic_info->candidates.mapped)
346 mwin__unmap_window (frame, win_ic_info->candidates.win);
347 win_ic_info->candidates.mapped = 0;
352 if (! win_ic_info->candidates.mapped)
354 mwin__map_window (frame, win_ic_info->candidates.win);
355 win_ic_info->candidates.mapped = 1;
359 group = ic->candidate_list;
362 if (mplist_key (group) == Mtext)
363 len = mtext_len (mplist_value (group));
365 len = mplist_length (mplist_value (group));
366 if (i + len > ic->candidate_index)
369 group = mplist_next (group);
373 if (mplist_key (group) == Mtext)
375 MText *candidates = (MText *) mplist_value (group);
377 from = (ic->candidate_index - i) * 2 + 1;
379 for (i = 0; i < len; i++)
381 mtext_cat_char (mt, ' ');
382 mtext_cat_char (mt, mtext_ref_char (candidates, i));
389 for (pl = (MPlist *) mplist_value (group);
390 i < ic->candidate_index && mplist_key (pl) != Mnil;
391 i++, pl = mplist_next (pl))
393 mtext_cat_char (mt, ' ');
394 mtext_cat (mt, (MText *) mplist_value (pl));
396 from = mtext_nchars (mt) + 1;
397 to = from + mtext_nchars ((MText *) mplist_value (pl));
398 for (; mplist_key (pl) != Mnil; pl = mplist_next (pl))
400 mtext_cat_char (mt, ' ');
401 mtext_cat (mt, (MText *) mplist_value (pl));
404 mtext_cat_char (mt, ' ');
405 mtext_push_prop (mt, 0, mtext_nchars (mt), Mface, status_face);
406 mtext_push_prop (mt, from, to, Mface, mface_reverse_video);
407 if (ic->im->language != Mnil)
408 mtext_put_prop (mt, 0, mtext_nchars (mt), Mlanguage, ic->im->language);
409 adjust_window_and_draw (frame, ic, mt, 2);
410 M17N_OBJECT_UNREF (mt);
412 else if (command == Minput_set_spot)
414 minput__callback (ic, Minput_preedit_draw);
415 minput__callback (ic, Minput_status_draw);
416 minput__callback (ic, Minput_candidates_draw);
418 else if (command == Minput_toggle)
422 minput__callback (ic, Minput_preedit_done);
423 minput__callback (ic, Minput_status_done);
424 minput__callback (ic, Minput_candidates_done);
428 minput__callback (ic, Minput_preedit_start);
429 minput__callback (ic, Minput_status_start);
430 minput__callback (ic, Minput_candidates_start);
433 else if (command == Minput_preedit_start)
436 else if (command == Minput_preedit_done)
438 if (win_ic_info->preedit.mapped)
440 mwin__unmap_window (frame, win_ic_info->preedit.win);
441 win_ic_info->preedit.mapped = 0;
444 else if (command == Minput_status_start)
446 if (! win_ic_info->status.mapped)
448 mwin__map_window (frame, win_ic_info->status.win);
449 win_ic_info->status.mapped = 1;
452 else if (command == Minput_status_done)
454 if (win_ic_info->status.mapped)
456 mwin__unmap_window (frame, win_ic_info->status.win);
457 win_ic_info->status.mapped = 0;
460 else if (command == Minput_candidates_start)
462 if (! win_ic_info->candidates.mapped)
464 mwin__map_window (frame, win_ic_info->candidates.win);
465 win_ic_info->candidates.mapped = 1;
468 else if (command == Minput_candidates_done)
470 if (win_ic_info->candidates.mapped)
472 mwin__unmap_window (frame, win_ic_info->candidates.win);
473 win_ic_info->candidates.mapped = 0;
479 win_lookup (MInputContext *ic, MSymbol key, void *arg, MText *mt)
481 MInputGUIContextInfo *win_ic_info = (MInputGUIContextInfo *) ic->info;
482 MInputContextInfo *ic_info = (MInputContextInfo *) win_ic_info->ic_info;
486 ret = (*minput_default_driver.lookup) (ic, key, arg, mt);
487 ic->info = win_ic_info;
496 minput_gui_driver = minput_default_driver;
498 minput_gui_driver.create_ic = win_create_ic;
499 minput_gui_driver.destroy_ic = win_destroy_ic;
500 minput_gui_driver.filter = win_filter;
501 minput_gui_driver.lookup = win_lookup;
503 MPlist *plist = mplist ();
505 minput_gui_driver.callback_list = plist;
506 plist = mplist_add (plist, Minput_preedit_start, (void *) win_callback);
507 plist = mplist_add (plist, Minput_preedit_draw, (void *) win_callback);
508 plist = mplist_add (plist, Minput_preedit_done, (void *) win_callback);
509 plist = mplist_add (plist, Minput_status_start, (void *) win_callback);
510 plist = mplist_add (plist, Minput_status_draw, (void *) win_callback);
511 plist = mplist_add (plist, Minput_status_done, (void *) win_callback);
512 plist = mplist_add (plist, Minput_candidates_start, (void *) win_callback);
513 plist = mplist_add (plist, Minput_candidates_draw, (void *) win_callback);
514 plist = mplist_add (plist, Minput_candidates_done, (void *) win_callback);
515 plist = mplist_add (plist, Minput_set_spot, (void *) win_callback);
516 plist = mplist_add (plist, Minput_toggle, (void *) win_callback);
518 minput_driver = &minput_gui_driver;
520 face_box_prop.width = 1;
521 face_box_prop.color_top = face_box_prop.color_left
522 = face_box_prop.color_bottom = face_box_prop.color_right
524 face_box_prop.inner_hmargin = face_box_prop.inner_vmargin = 2;
525 face_box_prop.outer_hmargin = face_box_prop.outer_vmargin = 1;
526 status_face = mface ();
527 mface_put_prop (status_face, Mbox, &face_box_prop);
535 M17N_OBJECT_UNREF (status_face);
536 if (minput_gui_driver.callback_list)
538 M17N_OBJECT_UNREF (minput_gui_driver.callback_list);
539 minput_gui_driver.callback_list = NULL;
544 #endif /* !FOR_DOXYGEN || DOXYGEN_INTERNAL_MODULE */
549 /*** @addtogroup m17nInputMethodWin */
554 @brief Input driver for internal input methods on window systems.
556 The input driver @c minput_gui_driver is for internal input
557 methods to be used on window systems.
559 It creates sub-windows for a preedit text and a status text, and
560 displays them at the input spot set by the function
563 The function m17n_initialize_win () set the variable @c
564 minput_driver to the pointer to this driver so that all internal
565 input methods use it.
567 Therefore, unless @c minput_driver is changed from the default,
568 the driver dependent arguments to the functions whose name begin
569 with minput_ must are treated as follows.
571 The argument $ARG of the function minput_open_im () is ignored.
573 The argument $ARG of the function minput_create_ic () must be a
574 pointer to the structure @c MInputGUIArgIC. See the documentation
575 of @c MInputGUIArgIC for more detail.
577 If the argument $KEY is @c Mnil, the argument $ARG of the
578 function minput_filter () must be a pointer to the object of type
579 @c XEvent. In that case, $KEY is generated from $ARG.
581 The argument $ARG of the function minput_lookup () must be the
582 same one as that of the function minput_filter (). */
585 @brief ¥¦¥£¥ó¥É¥¦¥·¥¹¥Æ¥à¤ÎÆâÉôÆþÎϥ᥽¥Ã¥ÉÍÑÆþÎϥɥ饤¥Ð
587 ÆþÎϥɥ饤¥Ð @c minput_gui_driver ¤Ï¡¢¥¦¥£¥ó¥É¥¦¥·¥¹¥Æ¥à¾å¤ÇÍѤ¤¤é
588 ¤ì¤ëÆþÎϥ᥽¥Ã¥ÉÍѤΤâ¤Î¤Ç¤¢¤ë¡£
590 ¤³¤Î¥É¥é¥¤¥Ð¤Ï¡¢´Ø¿ô minput_set_spot () ¤Ë¤è¤Ã¤ÆÀßÄꤵ¤ì¤¿ÆþÎÏ¥¹¥Ý¥Ã
591 ¥È¤Ë preedit ¥Æ¥¥¹¥ÈÍѤΥµ¥Ö¥¦¥£¥ó¥É¥¦¤È status ¥Æ¥¥¹¥ÈÍѤΥµ¥Ö
592 ¥¦¥£¥ó¥É¥¦¤òºî¤ê¡¢¤½¤ì¤¾¤ì¤òɽ¼¨¤¹¤ë¡£
594 ´Ø¿ô m17n_initialize_win () ¤ÏÊÑ¿ô @c minput_driver ¤ò¤³¤Î¥É¥é¥¤¥Ð
595 ¤Ø¤Î¥Ý¥¤¥ó¥¿¤ËÀßÄꤷ¡¢Á´¤Æ¤ÎÆâÉôÆþÎϥ᥽¥Ã¥É¤¬¤³¤Î¥É¥é¥¤¥Ð¤ò»È¤¦¤è
598 ¤·¤¿¤¬¤Ã¤Æ¡¢@c minput_driver ¤¬¥Ç¥Õ¥©¥ë¥ÈÃͤΤޤޤǤ¢¤ì¤Ð¡¢minput_
599 ¤Ç»Ï¤Þ¤ë̾Á°¤ò»ý¤Ä°Ê²¼¤Î´Ø¿ô·²¤Î¥É¥é¥¤¥Ð¤Ë°Í¸¤¹¤ë°ú¿ô¤Ï¼¡¤Î¤è¤¦¤Ë
602 ´Ø¿ô minput_open_im () ¤Î°ú¿ô $ARG ¤Ï̵»ë¤µ¤ì¤ë¡£
604 ´Ø¿ô minput_create_ic () ¤Î°ú¿ô $ARG ¤Ï¹½Â¤ÂÎ @c MInputGUIArgIC ¤Ø
605 ¤Î¥Ý¥¤¥ó¥¿¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£¾ÜºÙ¤Ë¤Ä¤¤¤Æ¤Ï @c MInputGUIArgIC ¤Î
606 ¥É¥¥å¥á¥ó¥È¤ò»²¾È¤Î¤³¤È¡£
608 ´Ø¿ô minput_filter () ¤Î°ú¿ô $ARG ¤¬ @c Mnil ¤Î¾ì¹ç¡¢ $ARG ¤Ï
609 XEvent ·¿¤Î¥ª¥Ö¥¸¥§¥¯¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£¤³¤Î¾ì¹ç $KEY
610 ¤Ï $ARG ¤«¤éÀ¸À®¤µ¤ì¤ë¡£
612 ´Ø¿ô minput_lookup () ¤Î°ú¿ô $ARG ¤Ï´Ø¿ô minput_filter () °ú¿ô
613 $ARG ¤ÈƱ¤¸¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ */
615 MInputDriver minput_gui_driver;
620 @brief Convert an event to an input key.
622 The minput_event_to_key () function returns the input key
623 corresponding to event $EVENT on $FRAME by a window system
626 In the m17n-X library, $EVENT must be a pointer to the struct @c
627 XKeyEvent, and it is handled as below.
629 At first, the keysym name of $EVENT is acquired by the function @c
632 Then, the name is modified as below.
634 If the name is one of "a" .. "z" and $EVENT has a Shift modifier,
635 the name is converted to "A" .. "Z" respectively, and the Shift
638 If the name is one byte length and $EVENT has a Control modifier,
639 the byte is bitwise anded by 0x1F and the Control modifier is
642 If $EVENT still has Shift, Control, Meta, Alt, Super, and/or Hyper
643 modifiers, the name is prepended by "S-", "C-", "M-", "A-", "s-",
644 and/or "H-" respectively in this order.
646 For instance, if the keysym name is "a" and the event has Shift,
647 Meta, and Hyper modifiers, the resulting name is "H-M-A".
649 At last, a symbol who has the name is returned. */
652 @brief ¥¡¼Ì¾¾Î¤òÆþÎÏ¥¡¼¤ËÊÑ´¹¤¹¤ë
654 ´Ø¿ô minput_name_to_key () ¤Ï¡¢Ì¾Á° $NAME ¤ËÂбþ¤¹¤ëÆþÎÏ¥¡¼¤òÊÖ¤¹¡£
656 $NAME ¤Ï¼¡¤Î·Á¤ò¤È¤ë¡£
658 [ MODIFIER-MNEMONIC '-' ] * KEY-NAME
660 ¤³¤³¤Ç MODIFIER-MNEMONIC ¤Ï 'S', 'C', 'M', 'A', 's', 'H' ¤Î¤¤¤º¤ì
661 ¤«¤Ç¤¢¤ê¡¢¤½¤ì¤¾¤ì Shift, Control, Meta, Alt, Super, Hyper ¤Î³Æ¥â
662 ¥Ç¥£¥Õ¥¡¥¤¥¢¤ò¼¨¤¹¡£KEY-NAME ¤ÏÆþÎÏ¥¡¼¤Î¥·¥ó¥Ü¥ê¥Ã¥¯¤Ê̾Á°¤òɽ¤¹Ê¸»úÎó¡£
664 ÆþÎÏ¥¡¼¤Î²¼ 16 ¥Ó¥Ã¥È¤Ï "keysym bits" ¤È¤è¤Ð¤ì¡¢KEY-NAME ¤ËÂбþ¤¹
665 ¤ë¥³¡¼¥É¤òɽ¤¹¡£¾å7 bits (¤Ä¤Þ¤ê 17 ¥Ó¥Ã¥ÈÌܤ«¤é 23 ¥Ó¥Ã¥ÈÌܤޤÇ)
666 ¤Ï"modifier bits" ¤È¸Æ¤Ð¤ì¡¢MODIFIER-MNEMONIC ¤òɽ¸½¤·¤Æ¤¤¤ë¡£
668 KEY-NAME ¤¬ 1 ¥Ð¥¤¥ÈŤǤ¢¤ë¾ì¹ç¡¢ÆþÎÏ¥¡¼¤Ï¼¡¤Î¤è¤¦¤Ë¹½À®¤µ¤ì¤ë¡£
670 ¤Þ¤º¡¢keysym bits ¤Ë¤Ï¤½¤Î¥Ð¥¤¥È¥³¡¼¥É¤½¤Î¤â¤Î¤¬ÀßÄꤵ¤ì¤ë¡£
672 ¼¡¤¤¤Ç¡¢Shift, Control, Meta ¤Î³Æ¥â¥Ç¥£¥Õ¥¡¥¤¥¢¤Ï°Ê²¼¤Î¼ê³¤¤Ç
673 keysym bits ¤ËÈ¿±Ç¤µ¤ì¤ë¡£
675 (1) Shift ¥â¥Ç¥£¥Õ¥¡¥¤¥¢¤¬¤¢¤ê¡¢keysym bits ¤¬¾®Ê¸»ú¤Ç¤¢¤ì¤Ð(¤Ä¤Þ
676 ¤ê 'a' ¤«¤é 'z' ¤Ç¤¢¤ì¤Ð), Âçʸ»ú (¤Ä¤Þ¤ê 'A' through 'Z') ¤ËÊÑ´¹
677 ¤µ¤ì¤ë¡£Shift ¥â¥Ç¥£¥Õ¥¡¥¤¥¢¤Ï modifier bits ¤«¤é¼è¤ê½ü¤«¤ì¤ë¡£
679 (2) Control ¥â¥Ç¥£¥Õ¥¡¥¤¥¢¤¬¤¢¤ì¤Ð, keysym bits ¤Ï¥Ó¥Ã¥Èñ°Ì¤Ç
680 0x1F ¤È and ±é»»¤ò¹Ô¤¦¡£Control ¥â¥Ç¥£¥Õ¥¡¥¤¥¢¤Ï modifier bits
683 (3) Meta ¥â¥Ç¥£¥Õ¥¡¥¤¥¢¤¬¤¢¤ì¤Ð, keysym bits ¤Ï¥Ó¥Ã¥Èñ°Ì¤Ç 0x80
684 ¤È or ±é»»¤ò¹Ô¤¦¡£ Meta ¥â¥Ç¥£¥Õ¥¡¥¤¥¢¤Ï modifier bits ¤«¤é¼è¤ê½ü
687 ¤¿¤È¤¨¤Ð¡¢"S-a" ¤È "A" ¤Ï¤É¤Á¤é¤â 65 ¤ò¡¢"C-a" ¤È "C-A" ¤Ï¤É¤Á¤é¤â
688 1 ¤òÊÖ¤·¡¢"M-a" ¤Ï 225 ¤ò, "C-M-a" ¤Ï 129 ¤òÊÖ¤¹¡£
690 KEY-NAME ¤¬ 2 ¥Ð¥¤¥È°Ê¾å¤Ç¤¢¤ë»þ¤Ë¤Ï¡¢Âбþ¤¹¤ëkeysym bits ¤Ï@c
691 m17n @c ¥é¥¤¥Ö¥é¥ê ÆâÉô¤Î¥Æ¡¼¥Ö¥ë¤Ë¤è¤Ã¤ÆÆÀ¤ë»ö¤¬¤Ç¤¤ë¡£¤³¤Î¤È¤
692 ¥Æ¡¼¥Ö¥ë¤Ë KEY-NAME ¤¬¤Ê¤±¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ï -1 ¤òÊÖ¤¹¡£ */
695 minput_event_to_key (MFrame *frame, void *event)
698 MSymbol key = mwin__parse_event (frame, event, &modifiers);
704 name = msymbol_name (key);
705 str = alloca (strlen (name) + 2 * 6 + 1);
707 if (modifiers & MINPUT_KEY_SHIFT_MODIFIER)
709 if (modifiers & MINPUT_KEY_CONTROL_MODIFIER)
711 if (modifiers & MINPUT_KEY_META_MODIFIER)
713 if (modifiers & MINPUT_KEY_ALT_MODIFIER)
715 if (modifiers & MINPUT_KEY_SUPER_MODIFIER)
717 if (modifiers & MINPUT_KEY_HYPER_MODIFIER)
721 return msymbol (str);