1 /* # skkinput (Simple Kana-Kanji Input)
2  * SkkInput.c --- Making SkkInputWidget.
3  * This file is part of skkinput.
4  * Copyright (C) 1997
5  * Takashi SAKAMOTO (sakamoto@yajima.kuis.kyoto-u.ac.jp)
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2, or (at your option)
10  * any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with skkinput; see the file COPYING.  If not, write to
19  * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
20  */
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <stdarg.h>
24 #include <string.h>
25 #include <X11/Xos.h>
26 #include <X11/Xlib.h>
27 #include <X11/Xutil.h>
28 #include <X11/Xatom.h>
29 #include <X11/keysym.h>
30 #include <X11/IntrinsicP.h>
31 #include <X11/StringDefs.h>
32 
33 #include "SkkInputP.h"
34 #include "config.h"
35 
36 #define XtNgeometry		"geometry"
37 #define XtCGeometry		"Geometry"
38 
39 #define offset(field) XtOffsetOf(SkkInputRec, skkinput.field)
40 #define goffset(field) XtOffsetOf(WidgetRec, core.field)
41 
42 static XtResource resources[] = {
43   /* ��Ȥ��餢��꥽������*/
44   { XtNwidth, XtCWidth, XtRDimension, sizeof(Dimension),
45     goffset(width), XtRImmediate, (XtPointer) 400},
46   { XtNheight, XtCHeight, XtRDimension, sizeof(Dimension),
47     goffset(height), XtRImmediate, (XtPointer) 400},
48   { XtNbackground, XtCBackground, XtRPixel, sizeof(Pixel),
49     goffset(background_pixel), XtRString, XtDefaultBackground },
50   /* ��ʬ�Ȥ��Ǻ�ä��꥽������*/
51   { XtNforeground, XtCForeground, XtRPixel, sizeof(Pixel),
52     offset(puppixel), XtRString, XtDefaultForeground },
53   { XtNreverseVideo, XtCReverseVideo, XtRBoolean, sizeof (Boolean),
54     offset(reverse_video), XtRImmediate, (XtPointer) FALSE},
55   { XtNfont, XtCFont, XtRFontStruct, sizeof(XFontStruct *),
56     offset(fs_roman), XtRString, DEFAULT_ROMANFONT },
57   { XtNkanjiFont, XtCFont, XtRFontStruct, sizeof(XFontStruct *),
58     offset(fs_kanji), XtRString, DEFAULT_KANJIFONT },
59   /* skkinput �뤬�Ĥ���������Ѥ���� callback */
60   { XtNendNotify, XtCCallback, XtRCallback, sizeof(caddr_t),
61     offset(endcallback), XtRCallback, (caddr_t)NULL },
62   /* skkinput ���� client ��ʸ�������������������Ѥ���� callback */
63   { XtNfixNotify, XtCCallback, XtRCallback, sizeof(caddr_t),
64     offset(fixcallback), XtRCallback, (caddr_t)NULL },
65   /* key event �� client �������֤��������Ѥ���� callback */
66   { XtNkeybackNotify, XtCCallback, XtRCallback, sizeof(caddr_t),
67     offset(keybackcallback), XtRCallback, (caddr_t)NULL },
68   /* �Ѵ����ϻ������Ѥ���� callback */
69   { XtNjhenkanNotify, XtCCallback, XtRCallback, sizeof(caddr_t),
70     offset(jhenkancallback), XtRCallback, (caddr_t)NULL },
71   /* �Ѵ���λ�������Ѥ���� callback */
72   { XtNjhenkanendNotify, XtCCallback, XtRCallback, sizeof(caddr_t),
73     offset(jhenkanendcallback), XtRCallback, (caddr_t)NULL },
74   /* ��������֤���������Ѥ���� callback */
75   { XtNjsavejisyoNotify, XtCCallback, XtRCallback, sizeof(caddr_t),
76     offset(jsavejisyocallback), XtRCallback, (caddr_t)NULL },
77   /* �����ñ�����Ͽ����������Ѥ���� callback */
78   { XtNjtangotourokuNotify, XtCCallback, XtRCallback, sizeof(caddr_t),
79     offset(jtangotourokucallback), XtRCallback, (caddr_t)NULL },
80   /* ������ñ�����(purge)����������Ѥ���� callback */
81   { XtNjtangosakujoNotify, XtCCallback, XtRCallback, sizeof(caddr_t),
82     offset(jtangosakujocallback), XtRCallback, (caddr_t)NULL },
83   /* completion ���Ϥ������ hit �����ꥹ�Ȥ���Τ��Ѥ����� *
84    * callback */
85   { XtNjcompletionNotify, XtCCallback, XtRCallback, sizeof(caddr_t),
86     offset(jcompletioncallback), XtRCallback, (caddr_t)NULL },
87   /* completion �ˤ�äƽ��褿�ꥹ�Ȥ�ä��Τ��Ѥ����� callback */
88   { XtNjcompletioncloseNotify, XtCCallback, XtRCallback, sizeof(caddr_t),
89     offset(jcompletionclosecallback), XtRCallback, (caddr_t)NULL },
90   /* ����ν����ե饰��õ����˻Ȥ��� callback */
91   { XtNnotmodifiedNotify, XtCCallback, XtRCallback, sizeof(caddr_t),
92     offset(notmodifiedcallback), XtRCallback, (caddr_t)NULL },
93   /* Shift-Space �� skkinput ����Ĥ����褦�ˤ��뤫�ݤ���*/
94   { XtNcompatibleCloseSkkinputKey, XtCCompatibleCloseSkkinputKey,
95     XtRBoolean, sizeof ( Boolean ),
96     offset(compatible_close_skkinputkey), XtRImmediate, (XtPointer)TRUE },
97   /* egg �ߴ��� j-newline ��������ݤ���*/
98   { XtNeggLikeNewline, XtCEggLikeNewline, XtRImmediate, sizeof (int),
99     offset(egg_like_newline), XtRImmediate, (XtPointer) FALSE},
100   /* chat-adapter-mode ���ݤ���*/
101   { XtNchatAdapter, XtCChatAdapter, XtRImmediate, sizeof (int),
102     offset(chat_adapter), XtRImmediate, (XtPointer) FALSE},
103   /* �Ĥ���Ρ� */
104   { XtNwillBeDestroyed, XtCWillBeDestroyed, XtRImmediate, sizeof (int),
105     offset(will_be_destroyed), XtRImmediate, (XtPointer) FALSE},
106   /* date-ad */
107   { XtNdateAd, XtCDateAd, XtRImmediate, sizeof (int),
108     offset(date_ad), XtRImmediate, (XtPointer) FALSE},
109   /* number-style */
110   { XtNnumberStyle, XtCNumberStyle, XtRImmediate, sizeof (int),
111     offset(number_style), XtRImmediate, (XtPointer) FALSE },
112   /* delte_implies_kautei */
113   { XtNdeleteImpliesKakutei, XtCDeleteImpliesKakutei,
114     XtRImmediate, sizeof (int),
115     offset(delete_implies_kakutei), XtRImmediate, (XtPointer) TRUE },
116   { XtNuseNumericConversion, XtCUseNumericConversion,
117     XtRImmediate, sizeof (int),
118     offset(use_numeric_conversion), XtRImmediate, (XtPointer) TRUE },
119   { XtNgeometry, XtCGeometry, XtRString, sizeof(char *),
120     offset(geo_metry), 	XtRString, (XtPointer) NULL },
121   { XtNjisyoDirty, XtCJisyoDirty, XtRImmediate, sizeof (int),
122     offset(jisyo_dirty), XtRImmediate, (XtPointer) FALSE },
123   { XtNkeySkkMap, XtCKeySkkMap, XtRImmediate, sizeof( int * ),
124     offset(skkmap), XtRImmediate, ( XtPointer )NULL },
125   { XtNkeyAbbrevMap, XtCKeyAbbrevMap, XtRImmediate, sizeof( int * ),
126     offset(abbrevmap), XtRImmediate, ( XtPointer )NULL },
127   { XtNkeyTwoMap, XtCKeyTwoMap, XtRImmediate,
128     sizeof( struct skkinputTwokeys * ),
129     offset( twokeymap ), XtRImmediate, ( XtPointer )NULL },
130   { XtNinputVector, XtCInputVector, XtRImmediate,
131     sizeof( unsigned char **),
132     offset( skk_input_vector ), XtRImmediate, ( XtPointer )NULL },
133   { XtNzenkakuVector, XtCZenkakuVector, XtRImmediate,
134     sizeof( unsigned char **),
135     offset( skk_zenkaku_vector ), XtRImmediate, ( XtPointer )NULL },
136   { XtNromKanaRuleList, XtCRomKanaRuleList, XtRImmediate,
137     sizeof( struct skk_rom_kana_rule * ),
138     offset( rom_kana_rule_list ), XtRImmediate, ( XtPointer )NULL },
139   { XtNtabWidth,     XtCTabWidth, XtRImmediate, sizeof (int),
140     offset( tab_width ), XtRImmediate, (XtPointer) 8 },
141   { XtNinitPosition, XtCInitPosition, XtRImmediate, sizeof (int),
142     offset( iposflag ), XtRImmediate, (XtPointer) TRUE },
143 } ;
144 
145 #undef offset
146 #undef goffset
147 
148 static void Initialize
149 ( Widget greq, Widget gnew, ArgList args, Cardinal *num_args ) ;
150 static void Realize
151 ( Widget gw, XtValueMask *valueMask, XSetWindowAttributes *attrs ) ;
152 static void Redisplay
153 ( Widget gw, XEvent *event, Region region ) ;
154 static void Destroy( Widget gw ) ;
155 static Boolean SetValues
156 ( Widget current, Widget request, Widget new,
157   ArgList args, Cardinal *num_args ) ;
158 static void KeyDownEventHandler
159 ( Widget w, XEvent *event, String *params, Cardinal *num_params ) ;
160 static void ShiftSpaceKeyEventHandler
161 ( Widget w, XEvent *event, String *params, Cardinal *num_params ) ;
162 static void ControlSpaceKeyEventHandler
163 ( Widget gw, XEvent *xevent, String *params, Cardinal *num_params ) ;
164 static void FocusInEventHandler
165 ( Widget gw, XEvent *xevent, String *params, Cardinal *num_params ) ;
166 static void FocusOutEventHandler
167 ( Widget gw, XEvent *xevent, String *params, Cardinal *num_params ) ;
168 static void WMMessageHandler
169 ( Widget w, XEvent *event, String *params, Cardinal *num_params ) ;
170 
171 /*
172  * �������Ȥ��Ƥ���ؿ��Υץ�ȥ����������
173  *-----
174  * �����δؿ������� SkkInputP.h �� include ���Ƥ��륽��������ˤ��롣
175  */
176 /* skkkeymap.c */
177 static int do_function_by_reading_character
178 ( Widget gw, struct SKKInputNode *node ) ;
179 /* skkwin.c */
180 static void skkinput_RedrawScreen( Widget gw ) ;
181 static void skkinput_DrawScreen( Widget gw ) ;
182 static void skkinput_ClearMinibuffer( Widget gw ) ;
183 /* skkmbuf.c */
184 static struct SKKInputNode *skkinput_AllocateMinibuffer( void ) ;
185 static void free_Minibuffer
186 ( Widget gw, struct SKKInputNode *node ) ;
187 
188 /*
189  * �����Х��ѿ���
190  */
191 XtActionsRec skkinputActionsTable [] = {
192   { "ShiftSpaceKeyEventHandler",   ShiftSpaceKeyEventHandler },
193   { "ControlSpaceKeyEventHandler", ControlSpaceKeyEventHandler },
194   { "KeyDownEventHandler",	   KeyDownEventHandler },
195   { "FocusInEventHandler",	   FocusInEventHandler },
196   { "FocusOutEventHandler",	   FocusOutEventHandler },
197   { "WMMessageHandler",		   WMMessageHandler },
198 };
199 
200 char defaultSkkinputTranslations[] =
201 "Shift<Key>space:         ShiftSpaceKeyEventHandler()\n\
202  Ctrl<Key>space:	  ControlSpaceKeyEventHandler()\n\
203  <Key>:                   KeyDownEventHandler()\n\
204  <FocusIn>:               FocusInEventHandler()\n\
205  <FocusOut>:              FocusOutEventHandler()\n\
206  <Message>WM_PROTOCOLS:   WMMessageHandler()\n" ;
207 
208 SkkInputClassRec skkinputClassRec = {
209     { /* core fields */
210     /* superclass		*/	&widgetClassRec,
211     /* class_name		*/	"SkkInput",
212     /* size			*/	sizeof(SkkInputRec),
213     /* class_initialize		*/	NULL,
214     /* class_part_initialize	*/	NULL,
215     /* class_inited		*/	FALSE,
216     /* initialize		*/	Initialize,
217     /* initialize_hook		*/	NULL,
218     /* realize			*/	Realize,
219     /* actions			*/	skkinputActionsTable,
220     /* num_actions		*/	XtNumber( skkinputActionsTable ),
221     /* resources		*/	resources,
222     /* num_resources		*/	XtNumber( resources ),
223     /* xrm_class		*/	NULLQUARK,
224     /* compress_motion		*/	TRUE,
225     /* compress_exposure	*/	TRUE,
226     /* compress_enterleave	*/	TRUE,
227     /* visible_interest		*/	FALSE,
228     /* destroy			*/	Destroy,
229     /* resize			*/	NULL,
230     /* expose			*/	Redisplay,
231     /* set_values		*/	SetValues,
232     /* set_values_hook		*/	NULL,
233     /* set_values_almost	*/	XtInheritSetValuesAlmost,
234     /* get_values_hook		*/	NULL,
235     /* accept_focus		*/	NULL,
236     /* version			*/	XtVersion,
237     /* callback_private		*/	NULL,
238     /* tm_table			*/	defaultSkkinputTranslations,
239     /* query_geometry		*/	XtInheritQueryGeometry,
240     }
241 };
242 
243 WidgetClass skkinputWidgetClass = ( WidgetClass )&skkinputClassRec ;
244 
Initialize(Widget greq,Widget gnew,ArgList args,Cardinal * num_args)245 static void Initialize
246 ( Widget greq, Widget gnew, ArgList args, Cardinal *num_args )
247 {
248   SkkInputWidget w = ( SkkInputWidget )gnew ;
249   struct SKKInputNode *node ;
250   XtGCMask	valuemask ;
251   XGCValues	myXGCV ;
252   int roman_width, roman_ascent, roman_height ;
253   int kanji_width, kanji_ascent, kanji_height ;
254   int fontwidth_sub1, fontwidth_sub2 ;
255 
256 #if 0
257   if( w->skkinput.reverse_video ){
258     Pixel fg = w->skkinput.puppixel ;
259     Pixel bg = w->core.background_pixel ;
260 
261     w->skkinput.puppixel = bg ;
262     w->core.background_pixel = fg ;
263   }
264 #endif
265 
266   /* �ե���Ȥξ�����ɤ߽Ф��Ƥ�����*/
267   roman_width  = w->skkinput.fs_roman->max_bounds.width ;
268   roman_ascent = w->skkinput.fs_roman->max_bounds.ascent ;
269   roman_height = roman_ascent + w->skkinput.fs_roman->max_bounds.descent ;
270   kanji_width  = w->skkinput.fs_kanji->max_bounds.width ;
271   kanji_ascent = w->skkinput.fs_kanji->max_bounds.ascent ;
272   kanji_height = kanji_ascent + w->skkinput.fs_kanji->max_bounds.descent ;
273 
274   fontwidth_sub1 = ( roman_width << 1 ) ;
275   fontwidth_sub2 = ( kanji_width >> 1 ) ;
276   /* �ߤ��Υե���Ȥ��礭���δط����ѤʤΤ��⤷��ʤ���*/
277   if( fontwidth_sub1 != kanji_width ){
278     /* �ѿ��������ܤ�����Τ��������������礭������ */
279     if( fontwidth_sub1 > kanji_width ){
280       kanji_width = fontwidth_sub1 ;
281     } else {
282       /* �ѿ��������ܤ�����Τϴ����������Ͼ������餷����*/
283       roman_width = fontwidth_sub2 ;
284     }
285   }
286   w->skkinput.roman_width = roman_width ;
287   w->skkinput.kanji_width = kanji_width ;
288 
289   w->skkinput.font_height = ( ( kanji_height > roman_height )?
290     kanji_height : roman_height ) + 1 ;
291   w->skkinput.font_ascent = ( ( kanji_ascent > roman_ascent )?
292     kanji_ascent : roman_ascent ) + 1 ;
293 
294   /* ����ե��٥å�ɽ���Τ���� GC ���롣*/
295   myXGCV.foreground = w->skkinput.puppixel ;
296   myXGCV.background = w->core.background_pixel ;
297   myXGCV.font       = w->skkinput.fs_roman->fid ;
298   valuemask = GCForeground | GCBackground | GCFont ;
299   w->skkinput.roman_ngc = XtGetGC( gnew, valuemask, &myXGCV ) ;
300 
301   myXGCV.foreground = w->core.background_pixel ;
302   myXGCV.background = w->skkinput.puppixel ;
303   myXGCV.font       = w->skkinput.fs_roman->fid ;
304   valuemask = GCForeground | GCBackground | GCFont ;
305   w->skkinput.roman_rgc = XtGetGC( gnew, valuemask, &myXGCV ) ;
306 
307   /* ʸ����(�����Ҳ�̾ʿ��̾)����Τ���� GC ��������롣*/
308   myXGCV.foreground = w->skkinput.puppixel ;
309   myXGCV.background = w->core.background_pixel ;
310   myXGCV.font       = w->skkinput.fs_kanji->fid ;
311   valuemask = GCForeground | GCBackground | GCFont ;
312   w->skkinput.kanji_ngc = XtGetGC( gnew, valuemask, &myXGCV ) ;
313 
314   myXGCV.foreground = w->core.background_pixel ;
315   myXGCV.background = w->skkinput.puppixel ;
316   myXGCV.font       = w->skkinput.fs_kanji->fid ;
317   valuemask = GCForeground | GCBackground | GCFont ;
318   w->skkinput.kanji_rgc = XtGetGC( gnew, valuemask, &myXGCV ) ;
319 
320   /* ����¾�ν������*/
321   w->skkinput.pwrite_string[ 0 ] = '\0' ;
322   w->skkinput.pmtextbuffer[ 0 ]  = '\0' ;
323   w->skkinput.cutbuffer[ 0 ]  = '\0' ;
324   w->skkinput.keybuf_use    = 0 ;
325   w->skkinput.keybuf[ 0 ]   = '\0' ;
326   w->skkinput.prev_modeline = 0 ;
327 
328   /* �ҥ��ȥ�ϥ��ꥢ���Ƥ�������ɸ�ν������ɬ�פǤ����Ĥޤ�ϰ�� */
329   /* �ⵯ�����줿���Ȥʤ�Ƥʤ��ΤǴ��Ǥ��롣*/
330   if( w->skkinput.iposflag ){
331     w->skkinput.historybuffer[ 0 ] = '\0' ;
332     w->skkinput.hist_start = w->skkinput.hist_end = 0 ;
333     w->skkinput.hist_cur   = -1 ;
334   } else {
335     w->skkinput.hist_cur   = -1 ;
336   }
337   /* �Խ��ѤΥХåե��γ��ݡ�*/
338   node = skkinput_AllocateMinibuffer() ;
339   node->cur_exist = True ;
340   w->skkinput.topbuffer  = node ;
341   w->skkinput.lastbuffer = node ;
342 
343   w->skkinput.prev_jisyo_dirty  = w->skkinput.jisyo_dirty = 0 ;
344   w->skkinput.prev_chat_adapter = w->skkinput.chat_adapter ;
345   w->skkinput.prev_eggnl        = w->skkinput.egg_like_newline ;
346   w->skkinput.will_be_destroyed = False ;
347 
348   /* �ޤ���Focus �Ϻǽ�ϳ���Ƥ���Ȼפ��衣*/
349   w->skkinput.is_focus = False ;
350   return ;
351 }
352 
Realize(Widget gw,XtValueMask * valueMask,XSetWindowAttributes * attrs)353 static void Realize
354 ( Widget gw, XtValueMask *valueMask, XSetWindowAttributes *attrs )
355 {
356   SkkInputWidget w = ( SkkInputWidget )gw ;
357   unsigned int winwidth, winheight, pr ;
358   int xpos, ypos, cols, rows ;
359   XSizeHints sizehints ;
360   Display *display = XtDisplay( gw ) ;
361 
362   xpos = 1 ;
363   ypos = 1 ;
364   winwidth = 80 ;
365   winheight = 3 ;
366   /* ������ȥ�β��ϡ�*/
367   pr = XParseGeometry ( w->skkinput.geo_metry,
368 			&xpos, &ypos, &winwidth, &winheight ) ;
369   /* ������ȥ꤫����֤�ȴ���Ф���*/
370   if( ( pr & XValue ) && ( XNegative & pr ) ) {
371     xpos += DisplayWidth
372       ( display, DefaultScreen( display ) )
373       - ( w->core.parent->core.border_width * 2 ) ;
374   }
375   if( ( pr & YValue ) && ( YNegative & pr ) ){
376     ypos += DisplayHeight
377       ( display, DefaultScreen( display ) )
378       - ( w->core.parent->core.border_width * 2 ) ;
379   }
380   /* �IJ���ʸ���ޤ�ɽ������Ρ� */
381   cols = ( ( WidthValue & pr  ) && winwidth > 0 )? winwidth : 80 ;
382   rows = ( ( HeightValue & pr ) && winheight > 0 )? winheight : 3 ;
383   /* ������ɥ��Υꥵ��������¾�����ꡣ*/
384   sizehints.base_width = w->core.border_width * 2 ;
385   sizehints.base_height= w->core.border_width * 2 ;
386   sizehints.width_inc  = w->skkinput.roman_width ;
387   sizehints.height_inc = w->skkinput.font_height ;
388   sizehints.min_width  = w->skkinput.roman_width * 2 ;
389   sizehints.min_height = w->skkinput.font_height * 3 ;
390   sizehints.flags      = ( PBaseSize | PMinSize | PResizeInc ) ;
391 
392   /* ��ɸ�ν����ġ�*/
393   if( w->skkinput.iposflag ){
394     /* ������ɥ����礭���λ��ꡣ*/
395     sizehints.width  = winwidth ;
396     sizehints.height = winheight ;
397     if( ( WidthValue & pr ) || ( HeightValue & pr ) ) {
398       sizehints.flags |= USSize ;
399     } else {
400       sizehints.flags |= PSize ;
401     }
402     /* Window ���礭������롣*/
403     winwidth  = w->core.border_width * 2 + cols * w->skkinput.roman_width ;
404     winheight = w->core.border_width * 2 + rows * w->skkinput.font_height ;
405 
406     if( ( pr & XValue ) || ( pr & YValue ) ){
407       sizehints.flags |= USSize | USPosition ;
408       sizehints.flags |= PWinGravity ;
409     }
410     switch( pr & ( XNegative | YNegative ) ){
411     case 0 :
412       /*sizehints.win_gravity = NorthWestGravity ;*/
413       sizehints.x = xpos ;
414       sizehints.y = ypos ;
415       break ;
416     case XNegative :
417       /*sizehints.win_gravity = NorthEastGravity ;*/
418       sizehints.x = xpos - winwidth ;
419       sizehints.y = ypos ;
420       break ;
421     case YNegative :
422       /*sizehints.win_gravity = SouthWestGravity ;*/
423       sizehints.x = xpos ;
424       sizehints.y = ypos - winheight ;
425       break ;
426     default:
427       /*sizehints.win_gravity = SouthEastGravity ;*/
428       sizehints.x = xpos - winwidth ;
429       sizehints.y = ypos - winheight ;
430       break ;
431     }
432   }
433   if( w->skkinput.iposflag ){
434     /* �Ƥ˥ꥵ�������äƤ��롩 */
435     (void) XtMakeResizeRequest
436       ( (Widget)w->core.parent,
437 	(Dimension)winwidth, (Dimension)winheight,
438 	&w->core.parent->core.width,
439 	&w->core.parent->core.height ) ;
440     /* ������֤����ꤹ�롣*/
441     if( sizehints.flags & USPosition ){
442       XtMoveWidget( w->core.parent, sizehints.x, sizehints.y ) ;
443       sizehints.flags &= ~USPosition ;
444     }
445     /* Window Manager �˥ҥ�Ȥ����äƤ��롣*/
446     XSetWMNormalHints
447       ( XtDisplay( gw ), w->core.parent->core.window, &sizehints ) ;
448   }
449   XSync( display, False ) ;
450   /* Window ��������롣*/
451   *valueMask |= CWBitGravity ;
452   attrs->bit_gravity = ForgetGravity ;
453   XtCreateWindow
454     ( gw, (unsigned)InputOutput, (Visual *)CopyFromParent,
455       *valueMask, attrs ) ;
456   w->skkinput.iposflag = False ;
457   return ;
458 }
459 
460 /*
461  * SIW �� XtDestroyWidget ���������˸ƤӽФ����ؿ���
462  *-----
463  * SIW �ν�λ������·�������äƤ��롣GC ��������Ƥ��顢malloc ���Ƥ�
464  * �������������Ƥ��롣
465  */
Destroy(Widget gw)466 static void Destroy( Widget gw )
467 {
468   SkkInputWidget w = ( SkkInputWidget )gw ;
469   struct SKKInputNode *node, *pNode ;
470   /*
471    * XFreeFont( XtDisplay( gw ), w->skkinput.fs_kanji ) ;
472    * XFreeFont( XtDisplay( gw ), w->skkinput.fs_roman ) ;
473    * �ɤ���顢Widget ��˳��ݤ��Ƥ���櫓����ʤ��ߤ����ʤΤǡ�������
474    * ��������ȤϤޤ�ߤ�������
475    */
476   /* Event �����������ʤ����֤ˤ��Ƥ����Ƥ���ġ�*/
477   XSelectInput( XtDisplay( gw ), XtWindow( gw ), NoEventMask ) ;
478   /* Event Queue ��ե�å��夷�Ƥ�����*/
479   XSync( XtDisplay( gw ), True ) ;
480 
481   XtReleaseGC(gw, w->skkinput.roman_ngc ) ;
482   XtReleaseGC(gw, w->skkinput.roman_rgc ) ;
483   XtReleaseGC(gw, w->skkinput.kanji_ngc ) ;
484   XtReleaseGC(gw, w->skkinput.kanji_rgc ) ;
485 
486   node = w->skkinput.lastbuffer ;
487   while( node != NULL ){
488     pNode = node->parentbuffer ;
489     free_Minibuffer( gw, node ) ;
490     node  = pNode ;
491   }
492   XtCallCallbacks( gw, XtNendNotify, NULL ) ;
493   return ;
494 }
495 
496 /*
497  * ���̤�����褹��ؿ���
498  */
Redisplay(Widget gw,XEvent * event,Region region)499 static void Redisplay( Widget gw, XEvent *event, Region region )
500 {
501   SkkInputWidget w = ( SkkInputWidget )gw ;
502   /* ����ϲ����Υ����ߥ��Ǵְ�ä� Widget �κ����褬�����Ƥ��롣*/
503   if( w->skkinput.topbuffer == NULL || w->core.being_destroyed ){
504 #if 1
505     fprintf( stderr, "Illegal Widget Exposure Event.\n" ) ;
506 #endif
507     return ;
508   }
509   skkinput_RedrawScreen( gw ) ;
510   XFlush( XtDisplay( gw ) ) ;
511   return ;
512 }
513 
SetValues(Widget current,Widget request,Widget new,ArgList args,Cardinal * num_args)514 static Boolean SetValues
515 ( Widget current, Widget request, Widget new,
516   ArgList args, Cardinal *num_args )
517 {
518   SkkInputWidget curw = ( SkkInputWidget )current ;
519   SkkInputWidget neww = ( SkkInputWidget )new ;
520 
521   /* ������������Ƥ����顢��ľ����¹Ԥ��롣*/
522   if( curw->skkinput.jisyo_dirty != neww->skkinput.jisyo_dirty ){
523     curw->skkinput.jisyo_dirty = neww->skkinput.jisyo_dirty ;
524     return TRUE ;
525   }
526   return( FALSE ) ;
527 }
528 
529 enum {
530   SIW_DESTROYED = -1, SIW_PROCESSING = 0,
531 } ;
532 
533 /*
534  * �����������줿�Ȥ������٥�Ȥν�����Ԥ��ؿ���
535  *----
536  * ������Υ���줿�Ȥ�������������Բ�ǽ�ʾ�礬����Τǡ������줿�Ȥ�
537  * ����������Ǿ�꤯ư���褦�˺��ʤ���Фʤ�ʤ���
538  */
KeyDownEventHandler(Widget gw,XEvent * xevent,String * params,Cardinal * num_params)539 static void KeyDownEventHandler
540 ( Widget gw, XEvent *xevent, String *params, Cardinal *num_params )
541 {
542   SkkInputWidget w = ( SkkInputWidget )gw ;
543   char inpstr[ STRBUFSIZE ] ;
544   KeySym key ;
545   struct SKKInputNode *node ;
546 
547   /* ���٥�Ȥ������Ƥ�����*/
548   w->skkinput.xevent = *xevent ;
549 
550   /* �ߥ˥Хåե���¸�ߤ��Ƥ���Τʤ�С����ΰ��ֺǸ�Τ�Τ������롣*/
551   node = w->skkinput.lastbuffer ;
552   if( !node->cur_exist )
553     node = w->skkinput.topbuffer ;
554 
555   /* ʸ��������Хåե��ν������*/
556   inpstr[ 0 ] = '\0' ;
557   /* ʸ����������*/
558   XLookupString( &( xevent->xkey ), inpstr, STRBUFSIZE, &key, NULL ) ;
559 
560   /* ���Ϥ��줿ʸ���ϰ�̣����ʸ���ʤΤǤ����� */
561   if( inpstr[ 0 ] != '\0' ){
562     w->skkinput.keybuf[ w->skkinput.keybuf_use ++ ] = inpstr[ 0 ] ;
563     /* �ߥ˥Хåե���¸�ߤ������������Ѥ���Ƥ�����ν�����*/
564     if( do_function_by_reading_character( gw, node ) )
565       return ;
566   }
567   skkinput_DrawScreen( gw ) ;
568   XFlush( XtDisplay( gw ) ) ;
569   return ;
570 }
571 
572 /*
573  * C-@ �Ȥ�����̤� 0 �ˤʤäƤ��ޤ��褦���ᤷ���������Ϥ�虜�虜���ؿ���
574  */
ControlSpaceKeyEventHandler(Widget gw,XEvent * xevent,String * params,Cardinal * num_params)575 static void ControlSpaceKeyEventHandler
576 ( Widget gw, XEvent *xevent, String *params, Cardinal *num_params )
577 {
578   SkkInputWidget w = ( SkkInputWidget )gw ;
579   struct SKKInputNode *node ;
580 
581   /* ���٥�Ȥ������Ƥ�����*/
582   w->skkinput.xevent = *xevent ;
583 
584   /* �ߥ˥Хåե���¸�ߤ��Ƥ���Τʤ�С����ΰ��ֺǸ�Τ�Τ������롣*/
585   node = w->skkinput.lastbuffer ;
586   if( !node->cur_exist )
587     node = w->skkinput.topbuffer ;
588 
589   /* ���Ϥ��줿ʸ���ϰ�̣����ʸ���ʤΤǤ����� */
590   w->skkinput.keybuf[ w->skkinput.keybuf_use ++ ] = 0x00 ;
591   /* �ߥ˥Хåե���¸�ߤ������������Ѥ���Ƥ�����ν�����*/
592   if( do_function_by_reading_character( gw, node ) )
593     return ;
594   skkinput_DrawScreen( gw ) ;
595   XFlush( XtDisplay( gw ) ) ;
596   return ;
597 }
598 
ShiftSpaceKeyEventHandler(Widget gw,XEvent * xevent,String * params,Cardinal * num_params)599 static void ShiftSpaceKeyEventHandler
600 ( Widget gw, XEvent *xevent, String *params, Cardinal *num_params )
601 {
602   SkkInputWidget w = ( SkkInputWidget )gw ;
603   if( w->skkinput.compatible_close_skkinputkey ){
604     /* Widget ���˲�����Ĥ����ƽ�λ���롣*/
605     w->skkinput.will_be_destroyed = True ;
606   } else {
607     /* �����Ǥʤ���С��̾�ν����롼�����Ƥ֡�*/
608     KeyDownEventHandler( gw, xevent, params, num_params ) ;
609   }
610   return ;
611 }
612 
613 /*
614  * �ե��������������줿���ν�����Ԥ��ؿ���
615  */
FocusOutEventHandler(Widget gw,XEvent * xevent,String * params,Cardinal * num_params)616 static void FocusOutEventHandler
617 ( Widget gw, XEvent *xevent, String *params, Cardinal *num_params )
618 {
619   SkkInputWidget w = ( SkkInputWidget )gw ;
620   /* �ե������������줿���Ȥ���ã���줿�Τǡ�����������Ƥ�����*/
621   w->skkinput.is_focus = False ;
622   /* ���̤ν����ĥ�������η������Ѳ�����Τǡ�*/
623   skkinput_DrawScreen( gw ) ;
624   return ;
625 }
626 
627 /*
628  * �ե�����������蘆�줿���ν�����Ԥ��ؿ���
629  */
FocusInEventHandler(Widget gw,XEvent * xevent,String * params,Cardinal * num_params)630 static void FocusInEventHandler
631 ( Widget gw, XEvent *xevent, String *params, Cardinal *num_params )
632 {
633   SkkInputWidget w = ( SkkInputWidget )gw ;
634   /* �ե������������줿���Ȥ���ã���줿�Τǡ�����������Ƥ�����*/
635   w->skkinput.is_focus = True ;
636   /* ���̤ν����ĥ�������η������Ѳ�����Τǡ�*/
637   skkinput_DrawScreen( gw ) ;
638   return ;
639 }
640 
641 /*
642  * Window Manager ���齪λ��[x]�ܥ�������줿�Ȥ�����å�������ή��
643  * ����褿���ν�����Ԥ��ؿ���
644  */
WMMessageHandler(Widget gw,XEvent * event,String * params,Cardinal * num_params)645 static void WMMessageHandler
646 ( Widget gw, XEvent *event, String *params, Cardinal *num_params )
647 {
648   SkkInputWidget w = ( SkkInputWidget )gw ;
649   /* Widget ���˲����ƽ��������롣*/
650   w->skkinput.will_be_destroyed = True ;
651   return ;
652 }
653 
654 /*
655  * ���������᤹�Τ����Ѥ����ؿ���
656  */
SKIW_SendbackKeyPress(Widget gw)657 static void SKIW_SendbackKeyPress( Widget gw )
658 {
659   SkkInputWidget w = ( SkkInputWidget )gw ;
660   /* ������Хå������������Ͽ����Ƥ���ʤ�н�����Ԥ���*/
661   if( w->skkinput.keybackcallback != NULL ){
662     Window to_window, subwindow ;
663     /* �����ࡩ ���Τ����Ф��Ƥ����ġ�*/
664     to_window = w->skkinput.xevent.xkey.window ;
665     subwindow = w->skkinput.xevent.xkey.subwindow ;
666     /* ���٥�Ȥ��äĤ����Ϥ���*/
667     XtCallCallbacks( gw, XtNkeybackNotify, &w->skkinput.xevent ) ;
668     /* �����ᤷ�Ƥ��롣*/
669     w->skkinput.xevent.xkey.window    = to_window ;
670     w->skkinput.xevent.xkey.subwindow = subwindow ;
671   }
672   return ;
673 }
674 
675 /*
676  * �ʲ��Υե�����ϡ�SkkInputWidget �Υ������ΰ����Ǥ��롣
677  */
678 #include "skkmarker.c"
679 #include "skkel.c"
680 #include "skkkeymap.c"
681 #include "skkmbuf.c"
682 #include "skkwin.c"
683