1 /* # skkinput (Simple Kana-Kanji Input)
2  * skkwin.c --- Draw skkinput window.
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 
22 enum {
23   MODELINE_NOTHING = 0, MODELINE_HANKAKU, MODELINE_ZENKAKU,
24   MODELINE_KATAKANA, MODELINE_KANA,
25 } ;
26 
27 static void skkwin_jdiffputstring
28 ( Widget gw, int x, int y, int width, char *text, char *ptext,
29   int roman_width, int kana_width ) ;
30 static void skkinput_FullDrawWindow
31 ( Widget gw, struct SKKInputNode *node, char *text,
32   int start_pos, int x, int y, int end_x, int end_y ) ;
33 
34 /*
35  * skkinput ����λ��ꤵ�줿���˥���饯����ɽ������ؿ���
36  *----
37  * flag �ϽŤ͹�碌������Ԥ����ɤ��������������ɽ���˴ط����롣
38  * rf ��ȿžɽ�����뤫�ɤ����Ǥ��롣
39  */
skkwin_jputchar(Widget gw,int x,int y,int chara,int flag,int rf)40 static void skkwin_jputchar
41 ( Widget gw, int x, int y, int chara, int flag, int rf )
42 {
43   char buffer[ 3 ] ;
44   SkkInputWidget w = ( SkkInputWidget )gw ;
45 
46   if( chara > 0x100 ){
47     buffer[ 0 ] = ( chara & 0x07F00 ) >> 8 ;
48     buffer[ 1 ] = ( chara & 0x0007F ) ;
49     buffer[ 2 ] = '\0' ;
50     /* ʸ�����ɽ����*/
51     if( flag ){
52       if( rf ){
53 	XDrawString16
54 	  ( XtDisplay( gw ), XtWindow( gw ), w->skkinput.kanji_rgc,
55 	    x, y, ( XChar2b *)buffer, 1 ) ;
56       } else {
57 	XDrawString16
58 	  ( XtDisplay( gw ), XtWindow( gw ), w->skkinput.kanji_ngc,
59 	    x, y, ( XChar2b *)buffer, 1 ) ;
60       }
61     } else {
62       if( rf ){
63 	XDrawImageString16
64 	  ( XtDisplay( gw ), XtWindow( gw ), w->skkinput.kanji_rgc,
65 	    x, y, ( XChar2b *)buffer, 1 ) ;
66       } else {
67 	XDrawImageString16
68 	  ( XtDisplay( gw ), XtWindow( gw ), w->skkinput.kanji_ngc,
69 	    x, y, ( XChar2b *)buffer, 1 ) ;
70       }
71     }
72   } else {
73     buffer[ 0 ] = chara ;
74     buffer[ 1 ] = '\0' ;
75     if( flag ){
76       if( rf ){
77 	XDrawString
78 	  ( XtDisplay( gw ), XtWindow( gw ), w->skkinput.roman_rgc,
79 	    x, y, buffer, 1 ) ;
80       } else {
81 	XDrawString
82 	  ( XtDisplay( gw ), XtWindow( gw ), w->skkinput.roman_ngc,
83 	    x, y, buffer, 1 ) ;
84       }
85     } else {
86       if( rf ){
87 	XDrawImageString
88 	  ( XtDisplay( gw ), XtWindow( gw ), w->skkinput.roman_rgc,
89 	    x, y, buffer, 1 ) ;
90       } else {
91 	XDrawImageString
92 	  ( XtDisplay( gw ), XtWindow( gw ), w->skkinput.roman_ngc,
93 	    x, y, buffer, 1 ) ;
94       }
95     }
96   }
97   return ;
98 }
99 
100 /*
101  * ���������ɽ������ؿ���
102  *----
103  * int kf : �����ե饰��EUC ���������ɤʤ� True �ˤʤ롣
104  */
skkinputDrawCursor(Widget gw,int x,int y,int kf)105 static void skkinputDrawCursor
106 ( Widget gw, int x, int y, int kf )
107 {
108   SkkInputWidget w = ( SkkInputWidget )gw ;
109 
110   /* ���������ɽ�����롣*/
111   if( kf ){
112     if( w->skkinput.is_focus ){
113       XFillRectangle
114 	( XtDisplay( gw ), XtWindow( gw ), w->skkinput.kanji_ngc,
115 	  x, y - w->skkinput.font_ascent,
116 	  w->skkinput.kanji_width - 1, w->skkinput.font_height ) ;
117     } else {
118       XFillRectangle
119 	( XtDisplay( gw ), XtWindow( gw ), w->skkinput.kanji_rgc,
120 	  x, y - w->skkinput.font_ascent,
121 	  w->skkinput.kanji_width - 1, w->skkinput.font_height ) ;
122       XDrawRectangle
123 	( XtDisplay( gw ), XtWindow( gw ), w->skkinput.kanji_ngc,
124 	  x, y - w->skkinput.font_ascent,
125 	  w->skkinput.kanji_width - 1, w->skkinput.font_height - 1 ) ;
126     }
127   } else {
128     if( w->skkinput.is_focus ){
129       XFillRectangle
130 	( XtDisplay( gw ), XtWindow( gw ), w->skkinput.roman_ngc,
131 	  x, y - w->skkinput.font_ascent,
132 	  w->skkinput.roman_width - 1, w->skkinput.font_height ) ;
133     } else {
134       XFillRectangle
135 	( XtDisplay( gw ), XtWindow( gw ), w->skkinput.roman_rgc,
136 	  x, y - w->skkinput.font_ascent,
137 	  w->skkinput.roman_width - 1, w->skkinput.font_height ) ;
138       XDrawRectangle
139 	( XtDisplay( gw ), XtWindow( gw ), w->skkinput.roman_ngc,
140 	  x, y - w->skkinput.font_ascent,
141 	  w->skkinput.roman_width - 1, w->skkinput.font_height - 1 ) ;
142     }
143   }
144   return ;
145 }
146 
147 /*
148  * skk window �����ʸ����õ��ؿ���
149  *----
150  * x, y �Ϻ�ɸ��kf �ϴ���������ե��٥åȤ��ɤ�����Ƚ�̤����Ѥ��롣
151  */
skkwin_jerase(Widget gw,int x,int y,int kf)152 void skkwin_jerase( Widget gw, int x, int y, int kf )
153 {
154   SkkInputWidget w = ( SkkInputWidget )gw ;
155   if( kf ){
156     XFillRectangle
157       ( XtDisplay( gw ), XtWindow( gw ), w->skkinput.roman_rgc,
158        x, y - w->skkinput.font_ascent,
159        w->skkinput.kanji_width, w->skkinput.font_height ) ;
160   } else {
161     XFillRectangle
162       ( XtDisplay( gw ), XtWindow( gw ), w->skkinput.roman_rgc,
163        x, y - w->skkinput.font_ascent,
164        w->skkinput.roman_width, w->skkinput.font_height ) ;
165   }
166   return ;
167 }
168 
169 /*
170  * skkinput ����λ��ꤵ�줿���˥���饯����ɽ������ؿ���
171  *----
172  * flag �ϽŤ͹�碌������Ԥ����ɤ��������������ɽ���˴ط����롣
173  */
skkwin_jputchar2(Widget gw,int x,int y,int chara,int flag,int wflag)174 static void skkwin_jputchar2
175 ( Widget gw, int x, int y, int chara, int flag, int wflag )
176 {
177   SkkInputWidget w = ( SkkInputWidget )gw ;
178   char buffer[ 3 ] ;
179   int kanji_flag ;
180 
181   if( chara > 0x100 ){
182     buffer[ 0 ] = ( chara & 0x07F00 ) >> 8 ;
183     buffer[ 1 ] = ( chara & 0x0007F ) ;
184     buffer[ 2 ] = '\0' ;
185     kanji_flag  = True ;
186   } else {
187     buffer[ 0 ] = chara ;
188     buffer[ 1 ] = '\0' ;
189     kanji_flag  = False ;
190   }
191   if( flag ){
192     if( kanji_flag ){
193       XDrawString16
194 	( XtDisplay( gw ), XtWindow( gw ), w->skkinput.kanji_rgc,
195 	  x, y, ( XChar2b *)buffer, 1 ) ;
196     } else {
197       XDrawString
198 	( XtDisplay( gw ), XtWindow( gw ), w->skkinput.roman_rgc,
199 	  x, y, buffer, 1 ) ;
200     }
201   } else {
202     /* ʸ�����ɽ����*/
203     skkwin_jerase( gw, x, y, kanji_flag ) ;
204     if( wflag )
205       return ;
206     if( kanji_flag ){
207       XDrawImageString16
208 	( XtDisplay( gw ), XtWindow( gw ), w->skkinput.kanji_ngc,
209 	  x, y, ( XChar2b *)buffer, 1 ) ;
210     } else {
211       XDrawImageString
212 	( XtDisplay( gw ), XtWindow( gw ), w->skkinput.roman_ngc,
213 	  x, y, buffer, 1 ) ;
214     }
215   }
216   return ;
217 }
218 
skkinput_WinGetNextLineTop(char * ptr,int win_width,int roman_width,int kana_width)219 static char *skkinput_WinGetNextLineTop
220 ( char *ptr, int win_width, int roman_width, int kana_width )
221 {
222   int kana_flag = 0, x = 0 ;
223 
224   while( *ptr != '\0' ){
225     if( 0x80 & *ptr ){
226       kana_flag = kana_flag % 2 + 1 ;
227     } else {
228       kana_flag = 0 ;
229     }
230     switch( kana_flag ){
231       /* �������������ɤν�����*/
232     case 0 :
233       x += roman_width ;
234       if( x >= win_width )
235 	return ptr ;
236       break ;
237       /* ���������ɤΰ�Х����ܤν�����*/
238     case 1 :
239       x += kana_width ;
240       if( x >= win_width )
241 	return ptr ;
242       break ;
243       /* ���������ɤ���Х����ܤν�����*/
244     case 2 :
245     default :
246       break ;
247     }
248     ptr ++ ;
249   }
250   return ptr ;
251 }
252 
253 /*
254  * ��ʬ�����ԤäƤ�����ʬ�Υᥤ�����������ʬ�Ĥδؿ���
255  *---------------
256  * ������ɽ�����줿ʸ����Ⱥ���ɽ�����ʤ��Ȥ����ʤ�ʸ������äȸ���٤�
257  * �ɤ����ʡ� ������ʸ����Ʊ��������ɽ�����ʤ��ǺѤ�͡� �Ȥ����Ԥ������
258  * �ä����顢�ѹ��Ϥ����͡� �Ȥ�����ġ�
259  */
skkinput_DiffDrawWindowSub1(Widget gw,struct SKKInputNode * node,char * text,char * ptext,int start_pos,int * retx,int * rety,int end_x,int end_y,int * rcx,int * rcy,int * retpos)260 static char *skkinput_DiffDrawWindowSub1
261 ( Widget gw, struct SKKInputNode *node, char *text, char *ptext,
262   int start_pos, int *retx, int *rety, int end_x, int end_y,
263   int *rcx, int *rcy, int *retpos )
264 {
265   SkkInputWidget w = ( SkkInputWidget )gw ;
266   int x, y, pos, cx, cy, chara ;
267   int charas_are_different, dkana_flag, skana_flag, diff_flag ;
268   char *dptr, *sptr, *linetop ;
269 
270   /* �ե饰�ν������*/
271   diff_flag = skana_flag = dkana_flag = False ;
272 
273   /* ���ɽ�����֤����ꡣ*/
274   pos = start_pos ;
275   x = *retx ;
276   y = *rety ;
277   chara = 0 ;
278   cx = cy = -1 ;
279 
280   /* ʸ��������ꡣ*/
281   linetop = sptr = ptext ;
282   dptr = text ;
283 
284   /* ��Ĥ�ʸ�������Ӥ��롣*/
285   while( *dptr != '\0' ){
286     /* ���������ɤ��������������ɤ������������ɤʤ餽�β��Х����ܤ���*/
287     if( 0x80 & *dptr ){
288       dkana_flag = dkana_flag % 2 + 1 ;
289     } else {
290       dkana_flag = 0 ;
291     }
292     /* ���Ԥ��뤫�ɤ�����Ƚ�ꡣ*/
293     switch( dkana_flag ){
294       /* �������������ɤν�����*/
295     case 0 :
296       /* �Ԥ��ޤ��֤��Υ����å���*/
297       if( ( x + w->skkinput.roman_width ) >= end_x ){
298 	/* �����������뤬ɽ������Ƥ����顢��äѤ�õ*/
299 	if( x == node->prev_cx && y == node->prev_cy )
300 	  skkwin_jerase( gw, x, y, True ) ;
301 	/* �ޤ��֤����� backslash ��ɽ�����롣*/
302 	skkwin_jputchar( gw, x, y, '\\', False, False ) ;
303 	x = 0 ;
304 	y += w->skkinput.font_height ;
305 	linetop = sptr = skkinput_WinGetNextLineTop
306 	  ( linetop, end_x, w->skkinput.roman_width,
307 	    w->skkinput.kanji_width ) ;
308 	/* ����������Dz��Ԥ��뤳�ȤϤʤ��Τǡ�������Ǥ��롣*/
309 	skana_flag = 0 ;
310 	/* ����ιԿ���Ķ���Ƥ��ޤä��ʤ顢ȴ���롣*/
311 	if( y >= end_y )
312 	  goto exit_loop ;
313       }
314       break ;
315       /* ���������ɤΰ�Х����ܤν�����*/
316     case 1 :
317       if( ( x + w->skkinput.kanji_width ) >= end_x ){
318 	/* �����������뤬ɽ������Ƥ����顢��äѤ�õ*/
319 	if( x >= node->prev_cx &&
320 	    ( node->prev_cx <= ( x + w->skkinput.kanji_width ) ) &&
321 	    y == node->prev_cy )
322 	  skkwin_jerase( gw, x, y, True ) ;
323 	skkwin_jputchar
324 	  ( gw, x, y, '\\', False, False ) ;
325 	skkwin_jputchar
326 	  ( gw, x + w->skkinput.roman_width, y, '\\', False, False ) ;
327 #if 0
328 	skkwin_jerase( gw, x, y, True ) ;
329 #endif
330 	x = 0 ;
331 	y += w->skkinput.font_height ;
332 	/* ��Ӥ��Ƥ�������ɽ�����줿ʸ���������Ԥ��줿���֤�õ���ơ�*
333 	 * �����إݥ������ư�����롣*/
334 	linetop = sptr = skkinput_WinGetNextLineTop
335 	  ( linetop, end_x, w->skkinput.roman_width,
336 	    w->skkinput.kanji_width ) ;
337 	/* ����������Dz��Ԥ��뤳�ȤϤʤ��Τǡ�������Ǥ��롣*/
338 	skana_flag = 0 ;
339 	/* ����ιԿ���Ķ���Ƥ��ޤä��ʤ顢ȴ���롣*/
340 	if( y >= end_y )
341 	  goto exit_loop ;
342       }
343       break ;
344       /* ���������ɤ���Х����ܤν�����*/
345     case 2 :
346     default :
347       break ;
348     }
349     /* ����ɽ�����줿����Ƚ���Ԥ���*/
350     if( 0x80 & *sptr ){
351       skana_flag = skana_flag % 2 + 1 ;
352     } else {
353       skana_flag = 0 ;
354     }
355     /* ���ơ�����饯���ϰۤʤ�ΤǤ��礦���� */
356     if( *sptr != *dptr || pos == node->cur_pos ||
357 	( x == node->prev_cx && y == node->prev_cy ) ||
358 	skana_flag != dkana_flag ){
359       /* �����ࡣ����������֤ϥǥե���Ȥǰۤʤ�Τ��ʡ� */
360       charas_are_different = True ;
361     } else {
362       charas_are_different = False ;
363     }
364     switch( dkana_flag ){
365       /* �������������ɤν�����*/
366     case 0 :
367       /* ��꤬��˲��Ԥ��Ƥ��ޤäƤ�����ˤ��̾��ɽ����*/
368       /* �����ǤϤʤ��ơ�����饯������Ӥ��ưۤʤ����ɽ����*/
369       if( charas_are_different ){
370 	if( pos == node->cur_pos ){
371 	  if( node->cur_exist ){
372 	    skkinputDrawCursor( gw, x, y, False ) ;
373 	    skkwin_jputchar
374 	      ( gw, x, y, *dptr, True, w->skkinput.is_focus ) ;
375 	  } else {
376 	    skkwin_jputchar2( gw, x, y, *dptr, False, False ) ;
377 	  }
378 	  cx = x ; cy = y ;
379 	} else {
380 	  skkwin_jputchar2( gw, x, y, *dptr, False, False ) ;
381 	}
382       }
383       /* ɽ�����֤ΰ�ư��*/
384       x += w->skkinput.roman_width ;
385       break ;
386       /* ���������ɤΰ�Х����ܤν�����*/
387     case 1 :
388       chara = ( unsigned char )*dptr ;
389       /* ���ä�����˲��Ԥ��Ƥ��ޤäƤ�����ˤ��Ԥġ�*/
390       /* ���������ɤΰ�Х����ܤ�ʸ�����ۤʤäƤ����硣*/
391       if( charas_are_different )
392 	diff_flag = True ;
393       break ;
394       /* ���������ɤ����Х����ܤν�����*/
395     case 2 :
396       chara = ( chara << 8 ) | ( ( unsigned char )*dptr ) ;
397       /* ���������ɤ����Х����ܤ�ʸ�����ۤʤäƤ�����ڤӡ���Х��� *
398        * �ܤǰۤʤäƤ�����ˤϽ�ľ���κ�Ȥ����롣                 */
399       if( charas_are_different || diff_flag ){
400 	if( pos == ( node->cur_pos + 1 ) ){
401 	  if( node->cur_exist ){
402 	    skkinputDrawCursor( gw, x, y, True ) ;
403 	    skkwin_jputchar
404 	      ( gw, x, y, chara, True, w->skkinput.is_focus ) ;
405 	  } else {
406 	    skkwin_jputchar2( gw, x, y, chara, False, False ) ;
407 	  }
408 	  cx = x ; cy = y ;
409 	} else {
410 	  skkwin_jputchar2( gw, x, y, chara, False, False ) ;
411 	}
412 	diff_flag = False ;
413       }
414       /* ɽ�����֤ΰ�ư��*/
415       x += w->skkinput.kanji_width ;
416       break ;
417     default :
418       dkana_flag = 0 ;
419       break ;
420     }
421     dptr ++ ;
422     if( *sptr != '\0' )
423       sptr ++ ;
424     pos  ++ ;
425   }
426 exit_loop:
427   /* ����ɽ���η�̥������뤬����ޤǰ�ư�����Τ����֤���*/
428   *retx   = x ;
429   *rety   = y ;
430   *rcx    = cx ;
431   *rcy    = cy ;
432   *retpos = pos ;
433   return sptr ;
434 }
435 
436 /*
437  * ��ʬɽ����Ԥ��ؿ���
438  *----
439  * �ޤ����ޤ�ư���ʤ��Ǥ����ɤ����Ƥ��ϡ��档
440  */
skkinput_DiffDrawWindow(Widget gw,struct SKKInputNode * node,char * text,char * ptext,int start_pos,int x,int y,int end_x,int end_y)441 static void skkinput_DiffDrawWindow
442 ( Widget gw, struct SKKInputNode *node, char *text, char *ptext,
443   int start_pos, int x, int y, int end_x, int end_y )
444 {
445   SkkInputWidget w = ( SkkInputWidget )gw ;
446   int pos, cx, cy, kx, ky ;
447   char *sptr ;
448 
449   /* ξ�Ԥ�����ɽ������Ƥ�����ʬ�ˤĤ��ƺ�ʬ�����Ԥ���*/
450   sptr = skkinput_DiffDrawWindowSub1
451     ( gw, node, text, ptext, start_pos, &x, &y, end_x, end_y,
452       &cx, &cy, &pos ) ;
453 
454   /* �ޤ����̰��դˤϽ��Ƥʤ��Τǡ��õ��Ȥ��ĤäƤ��뤫�⤷��ʤ���*/
455   if( y < end_y ){
456     /* �õ��Ԥ����˸��ߤΥ�������ΰ��֤�Ф��Ƥ�����*/
457     kx = x ;
458     ky = y ;
459     while( *sptr != '\0' ){
460       if( ( ( x + w->skkinput.kanji_width ) >= end_x &&
461 	    ( 0x80 & *sptr ) ) ||
462 	  ( x + w->skkinput.roman_width ) >= end_x ){
463 	skkwin_jerase( gw, x, y, True ) ;
464 	x = 0 ;
465 	y += w->skkinput.font_height ;
466       }
467       if( y >= end_y )
468 	break ;
469       skkwin_jerase( gw, x, y, False ) ;
470       x += w->skkinput.roman_width ;
471       sptr ++ ;
472     }
473 
474     /* �����������뤬ɽ������Ƥ������֤ޤ���ã���Ƥ��ޤ���...������ *
475      * ���ˤϡ����������õ�ޤ���*/
476     if( y < node->prev_cy ||
477 	( x <= node->prev_cx && y == node->prev_cy ) ){
478       skkwin_jerase( gw, node->prev_cx, node->prev_cy, True ) ;
479     }
480     x = kx ;
481     y = ky ;
482 
483     /* �ޤ��������뤬ɽ������Ƥ��ʤ��Ȥ������Ȥϡ��Ǹ�ΰ��֤ˤ��� *
484      * �Τ��ʤ���*/
485     if( cy < 0 ){
486       if( ( x + w->skkinput.roman_width ) > end_x ){
487 	x = 0 ;
488 	y += w->skkinput.font_height ;
489       }
490       if( node->cur_exist )
491 	skkinputDrawCursor( gw, x, y, False ) ;
492       cx = x ; cy = y ;
493     }
494   }
495   /* �����������ɽ���������֤������Ƥ�����*/
496   node->prev_cx = cx ;
497   node->prev_cy = cy ;
498   /* ����ɽ������ʸ����������Ƥ�����*/
499   return ;
500 }
501 
502 /*
503  * cur_line != NULL �ʤ�С���������Τ��ä���꤬�����ܤǤ��뤫���֤���
504  */
skkinput_GetLineNum(SkkInputWidget w,unsigned char * text,unsigned int width,int cur_pos,int * cur_line)505 static int skkinput_GetLineNum
506 ( SkkInputWidget w, unsigned char *text, unsigned int width,
507   int cur_pos, int *cur_line )
508 {
509   int num, cur_num, x, y, pos, kana_flag ;
510   char *ptr ;
511 
512   /* �ɽ��ѿ��ν������*/
513   x = y = pos = kana_flag = cur_num = num = 0 ;
514   /* �롼�ס�*/
515   for( ptr = text ; *ptr != '\0' ; ptr ++, pos ++ ){
516     /* ���������ɤ��롣*/
517     if( 0x80 & *ptr ){
518       kana_flag = kana_flag % 2 + 1 ;
519     } else {
520       kana_flag = 0 ;
521     }
522     /* ���������ɤν�����*/
523     switch( kana_flag ){
524       /* �������������ɤξ��ν�����*/
525     case 0 :
526       x += w->skkinput.roman_width ;
527       if( x >= width ){
528 	x = w->skkinput.roman_width ;
529 	num ++ ;
530       }
531       break ;
532       /* ���������ɤΰ�Х����ܤν�����*/
533     case 1 :
534       x += w->skkinput.kanji_width ;
535       if( x >= width ){
536 	x = w->skkinput.kanji_width ;
537 	num ++ ;
538       }
539       break ;
540       /* ���������ɤ���Х����ܤν�����*/
541     case 2 :
542       break ;
543       /* ����ʳ��Υ����ɤʤ�̵�롣*/
544     default :
545       break ;
546     }
547     /* ����������֤������롣*/
548     if( pos == cur_pos )
549       cur_num = num ;
550   }
551 
552   /* ̤���˥��������ȯ������Ƥ��ʤ���硣*/
553   if( pos <= cur_pos ){
554     if( ( x + w->skkinput.kanji_width ) > width )
555       num ++ ;
556     cur_num = num ;
557   }
558 
559   /* ��������ΰ��֤��֤��Τ��ʡ� */
560   if( cur_line != NULL )
561     *cur_line = cur_num ;
562   return num ;
563 }
564 
skkinput_FindStartLine(SkkInputWidget w,unsigned char * text,int startline,unsigned int width)565 static int skkinput_FindStartLine
566 ( SkkInputWidget w, unsigned char *text, int startline, unsigned int width )
567 {
568   int x, kana_flag, pos ;
569   char *ptr ;
570 
571   /* �ɽ��ѿ��ν������*/
572   x = pos = kana_flag = 0 ;
573   /* �롼�ס�*/
574   for( ptr = text ; *ptr != '\0' ; ptr ++, pos ++ ){
575     /* ���������ɤ��롣*/
576     if( 0x80 & *ptr ){
577       kana_flag = kana_flag % 2 + 1 ;
578     } else {
579       kana_flag = 0 ;
580     }
581     /* ���������ɤν�����*/
582     switch( kana_flag ){
583       /* �������������ɤξ��ν�����*/
584     case 0 :
585       x += w->skkinput.roman_width ;
586       if( x >= width ){
587 	x = w->skkinput.roman_width ;
588 	startline -- ;
589 	if( startline <= 0 )
590 	  goto exit_loop ;
591       }
592       break ;
593       /* ���������ɤΰ�Х����ܤν�����*/
594     case 1 :
595       x += w->skkinput.kanji_width ;
596       if( x >= width ){
597 	x = w->skkinput.kanji_width ;
598 	startline -- ;
599 	if( startline <= 0 )
600 	  goto exit_loop ;
601       }
602       break ;
603       /* ���������ɤ���Х����ܤν�����*/
604     case 2 :
605       break ;
606       /* ����ʳ��Υ����ɤʤ�̵�롣*/
607     default :
608       break ;
609     }
610   }
611 exit_loop:
612   return pos ;
613 }
614 
skkwin_jputstring(Widget gw,int x,int y,char * text,int roman_width,int kana_width,int rf)615 static void skkwin_jputstring
616 ( Widget gw, int x, int y, char *text,
617   int roman_width, int kana_width, int rf )
618 {
619   SkkInputWidget w = ( SkkInputWidget )gw ;
620   int kanji_flag = False ;
621   char buffer[ 3 ] ;
622 
623   buffer[ 2 ] = '\0' ;
624 
625   for( ; *text != '\0' ; text ++ ){
626     if( ( 0x80 & *text ) && !kanji_flag ){
627       kanji_flag = True ;
628       buffer[ 0 ] = ( *text ) & 0x7F ;
629     } else {
630       if( 0x80 & *text ){
631 	buffer[ 1 ] = 0x7F & ( *text ) ;
632 	if( rf ){
633 	  XDrawString16( XtDisplay( gw ), XtWindow( gw ),
634 			 w->skkinput.kanji_rgc,
635 			 x, y, ( XChar2b *)buffer, 1 ) ;
636 	} else {
637 	  XDrawString16( XtDisplay( gw ), XtWindow( gw ),
638 			 w->skkinput.kanji_ngc,
639 			 x, y, ( XChar2b *)buffer, 1 ) ;
640 	}
641 	x += w->skkinput.kanji_width ;
642 	kanji_flag = False ;
643       } else {
644 	buffer[ 0 ] = *text ;
645 	buffer[ 1 ] = '\0' ;
646 	if( rf ){
647 	  XDrawString( XtDisplay( gw ), XtWindow( gw ), w->skkinput.roman_rgc,
648 		     x, y, buffer, 1 ) ;
649 	} else {
650 	  XDrawString( XtDisplay( gw ), XtWindow( gw ), w->skkinput.roman_ngc,
651 		     x, y, buffer, 1 ) ;
652 	}
653 	x += w->skkinput.roman_width ;
654 #if 0
655 	kanji_flag = False ;
656 #endif
657       }
658     }
659   }
660   return ;
661 }
662 
663 /*
664  * �Ϥ��줿 skkinput �Υ⡼�ɥ饤�����Ǥ���Τ���Ĵ�٤�ؿ���
665  */
skkinput_GetModelineNumber(struct SKKInputNode * node)666 static int skkinput_GetModelineNumber( struct SKKInputNode *node )
667 {
668   int modeline ;
669   /* ��̾���ϥ⡼�ɤʤΡ� �����ǤϤʤ��Ρ� */
670   if( !node->j_mode ){
671     /* �������ϥ⡼�ɤʤΡ� Ⱦ�����ϥ⡼�ɤʤΡ� */
672     if( node->j_zenkaku ){
673       modeline = MODELINE_ZENKAKU ;
674     } else {
675       modeline = MODELINE_HANKAKU ;
676     }
677   } else {
678     /* �Ҳ�̾���ϥ⡼�ɤʤΡ� ʿ��̾���ϥ⡼�ɤʤΡ� */
679     if( node->j_katakana_mode ){
680       modeline = MODELINE_KATAKANA ;
681     } else {
682       modeline = MODELINE_KANA ;
683     }
684   }
685   return modeline ;
686 }
687 
688 /*
689  * skkinput �Υ⡼�ɥ饤���ʬ���褹��ؿ���
690  */
skkinput_DiffDrawModeLine(Widget gw,struct SKKInputNode * node,int x,int y,unsigned int width)691 static void skkinput_DiffDrawModeLine
692 ( Widget gw, struct SKKInputNode *node, int x, int y, unsigned int width )
693 {
694   SkkInputWidget w = ( SkkInputWidget )gw ;
695   static char *modelineStrings[] = {
696     "SKK:", "����", "����", "����",
697   } ;
698   static char *modelineStrings2[] = {
699     "--", "**",
700   } ;
701   static char *chatAdapterStrings[] = {
702     "(Fundamental",
703     "(ChatAdapter",
704   } ;
705   int modeline = skkinput_GetModelineNumber( node ) ;
706 
707   /* �⡼�ɥ饤�������ɽ�����줿��Τ�Ʊ���Ǥ��뤫��������ɬ�פ� *
708    * �ʤ���*/
709   if( w->skkinput.prev_modeline != modeline ){
710     /* �ѹ����оݤȤʤ���ʬ��õ�롣*/
711     XFillRectangle
712       ( XtDisplay( gw ), XtWindow( gw ), w->skkinput.roman_ngc,
713 	x + w->skkinput.roman_width * 2,
714 	y - w->skkinput.font_ascent,
715 	w->skkinput.kanji_width * 2,
716 	w->skkinput.font_height ) ;
717     /* �⡼�ɥ饤���ʬ���褹�롣*/
718     skkwin_jputstring
719       ( gw, x + w->skkinput.roman_width * 2, y,
720 	modelineStrings[ modeline - 1 ],
721 	w->skkinput.roman_width,
722 	w->skkinput.kanji_width, True ) ;
723     /* �����ɽ����Ф��롣*/
724     w->skkinput.prev_modeline = modeline ;
725   }
726   if( w->skkinput.prev_jisyo_dirty != w->skkinput.jisyo_dirty ){
727     /* �ѹ����оݤȤʤ���ʬ��õ�롣*/
728     XFillRectangle
729       ( XtDisplay( gw ), XtWindow( gw ), w->skkinput.roman_ngc,
730        x + w->skkinput.roman_width * 11,
731        y - w->skkinput.font_ascent,
732        w->skkinput.roman_width * 2,
733        w->skkinput.font_height ) ;
734     /* �⡼�ɥ饤���ʬ���褹�롣*/
735     skkwin_jputstring
736       ( gw, x + w->skkinput.roman_width * 11, y,
737        modelineStrings2[ w->skkinput.jisyo_dirty ],
738        w->skkinput.roman_width,
739        w->skkinput.kanji_width, True ) ;
740     w->skkinput.prev_jisyo_dirty = w->skkinput.jisyo_dirty ;
741   }
742   if( w->skkinput.prev_chat_adapter != w->skkinput.chat_adapter ){
743     /* �ѹ����оݤȤʤ���ʬ��õ�롣*/
744     XFillRectangle
745       ( XtDisplay( gw ), XtWindow( gw ),
746        w->skkinput.roman_ngc,
747        x + w->skkinput.roman_width * 35,
748        y - w->skkinput.font_ascent,
749        w->skkinput.roman_width * 12,
750        w->skkinput.font_height ) ;
751     /* �⡼�ɥ饤���ʬ���褹�롣*/
752     skkwin_jputstring
753       ( gw, x + w->skkinput.roman_width * 35, y,
754        chatAdapterStrings[ w->skkinput.chat_adapter ],
755        w->skkinput.roman_width,
756        w->skkinput.kanji_width, True ) ;
757     w->skkinput.prev_chat_adapter = w->skkinput.chat_adapter ;
758   }
759   if( w->skkinput.prev_eggnl != w->skkinput.egg_like_newline ){
760     /* �ѹ����оݤȤʤ���ʬ��õ�롣*/
761     XFillRectangle
762       ( XtDisplay( gw ), XtWindow( gw ),
763        w->skkinput.roman_ngc,
764        x + w->skkinput.roman_width * 47,
765        y - w->skkinput.font_ascent,
766        w->skkinput.roman_width * 13,
767        w->skkinput.font_height ) ;
768     /* �⡼�ɥ饤���ʬ���褹�롣*/
769     if( w->skkinput.egg_like_newline ){
770       skkwin_jputstring
771 	( gw, x + w->skkinput.roman_width * 47, y,
772 	 " egg-nl)--All",
773 	 w->skkinput.roman_width,
774 	 w->skkinput.kanji_width, True ) ;
775     } else {
776       skkwin_jputstring
777 	( gw, x + w->skkinput.roman_width * 47, y,
778 	 ")--All-------",
779 	 w->skkinput.roman_width,
780 	 w->skkinput.kanji_width, True ) ;
781     }
782     w->skkinput.prev_eggnl = w->skkinput.egg_like_newline ;
783   }
784   return ;
785 }
786 
787 /*
788  * skkinput �β��̤�ʬɽ�����Ѥ���ɽ������ؿ���
789  *-----
790  * �̾�β��̤ν���(�ѹ�)�Ϥ�����δؿ��ˤ�äƹԤ��롣
791  */
skkinput_DrawScreen(Widget gw)792 static void skkinput_DrawScreen( Widget gw )
793 {
794   SkkInputWidget w = ( SkkInputWidget )gw ;
795   int x, y, cur_line, linenum, maxline, spos, sty, edy ;
796   Window root ;
797   unsigned int width, height, border, depth ;
798   char *sptr, *dptr ;
799   struct SKKInputNode *node = w->skkinput.topbuffer, *mNode ;
800 
801   /* �����������뤬¸�ߤ��Ƥ�����ꡣ*/
802 
803   /* Window �� size ��������롣*/
804   XGetGeometry( XtDisplay( gw ), XtWindow( gw ),
805 	        &root, &x, &y, &width, &height, &border, &depth ) ;
806 
807   /* ����ɽ����ǽ�Կ�����롣*/
808   maxline = height / w->skkinput.font_height ;
809   /* ���ߡ��ƥ����Ȥϲ��Ԥޤ�ɽ�����ʤ���Фʤ�ʤ��Τ����Ф��롣*/
810   linenum = skkinput_GetLineNum
811     ( w, node->textbuffer, width, node->cur_pos, &cur_line ) ;
812 
813   /* �⡼�ɥ饤��� minibuffer �Τ�������ɬ�פǤ��뤫���롣*/
814   maxline = ( maxline < 3 )? 1 : maxline - 2 ;
815 
816 #ifdef DEBUG_LV1
817   fprintf( stderr, "cursor_line = %d\n", cur_line ) ;
818 #endif
819   /* ɽ����ǽ�Կ���Ķ���Ƥ������ν���������������֤������ϰϤ��� *
820    * �ǰ��ֺǽ�ιԤ��ֹ椬�Ǥ⾮�������ʤ�褦�����ꤹ�롣*/
821   if( linenum >= maxline && cur_line >= maxline ){
822     int startline = cur_line - maxline + 1 ;
823     /* ���ꤵ�줿��꤫��ɽ�����ʤ�Фʤ�ʤ��Τǡ����ΰ��֤��Ф��롣*/
824     spos = skkinput_FindStartLine( w, node->textbuffer, startline,
825 				   width ) ;
826     dptr = node->textbuffer + spos ;
827     sptr = w->skkinput.pwrite_string + node->prev_start_pos ;
828   }  else {
829     spos = 0 ;
830     /* ���˰��ֺǽ��ʸ������ɽ����ǽ�Ǥ��롣*/
831     dptr = node->textbuffer ;
832     sptr = w->skkinput.pwrite_string + node->prev_start_pos ;
833   }
834   sty = w->skkinput.font_ascent ;
835   edy = sty + maxline * w->skkinput.font_height ;
836   /* Window �� buffer ��ʸ�����ɽ�����롣*/
837   skkinput_DiffDrawWindow( gw, node,
838 			   dptr, sptr, spos, 0, sty, width, edy ) ;
839   strcpy( w->skkinput.pwrite_string, node->textbuffer ) ;
840   node->prev_start_pos = spos ;
841 
842   /* �⡼�ɥ饤���ɽ�����롣��ʬɽ����ľ���б�����ͽ��ǤϤ��롣*/
843   sty = edy ;
844   edy = sty + w->skkinput.font_height ;
845   skkinput_DiffDrawModeLine( gw, node, 0, sty, width ) ;
846 
847   /* mini-buffer ��ɽ�����롣*/
848   mNode = w->skkinput.lastbuffer ;
849 
850   sty = edy ;
851   edy = sty + w->skkinput.font_height ;
852 
853   /* for debugging */
854   if( mNode == node ){
855     skkwin_jdiffputstring
856       ( gw, 0, sty, width, node->mtextbuffer,
857 	w->skkinput.pmtextbuffer, w->skkinput.roman_width,
858 	w->skkinput.kanji_width ) ;
859     strcpy( w->skkinput.pmtextbuffer, node->mtextbuffer ) ;
860   } else {
861     if( mNode->mtextbuffer[ 0 ] != '\0' ){
862       skkwin_jdiffputstring
863 	( gw, 0, sty, width, mNode->mtextbuffer,
864 	  w->skkinput.pmtextbuffer, w->skkinput.roman_width,
865 	  w->skkinput.kanji_width ) ;
866       strcpy( w->skkinput.pmtextbuffer, mNode->mtextbuffer ) ;
867     } else {
868       /* Window �� buffer ��ʸ�����ɽ�����롣*/
869       skkinput_DiffDrawWindow
870 	( gw, mNode, mNode->textbuffer, w->skkinput.pmtextbuffer,
871 	  0, 0, sty, width, edy ) ;
872       strcpy( w->skkinput.pmtextbuffer, mNode->textbuffer ) ;
873     }
874   }
875   return ;
876 }
877 
878 /*
879  * skkinput �����ɽ������ؿ���
880  *-----
881  * ������Ϻ�ʬ�����Ԥ�ʤ���
882  */
skkinput_FullDrawWindow(Widget gw,struct SKKInputNode * node,char * text,int start_pos,int x,int y,int end_x,int end_y)883 static void skkinput_FullDrawWindow
884 ( Widget gw, struct SKKInputNode *node, char *text,
885   int start_pos, int x, int y, int end_x, int end_y )
886 {
887   SkkInputWidget w = ( SkkInputWidget )gw ;
888   int pos, chara, kana_flag, kanji_check, cursor_flag ;
889   int cx, cy ;
890 
891   pos         = start_pos ;
892   kana_flag   = False ;
893   cursor_flag = False ;
894 
895   chara = cx = cy = 0 ;
896 
897   while( *text != '\0' ){
898     /* �������ɤ�����Ƚ���Ԥ���*/
899     kanji_check = 0x80 & *text ;
900     /* ���������ɽ��������ʤΤ��ɤ�����Ƚ�ꤹ�롣*/
901     if( pos == node->cur_pos ){
902       if( node->cur_exist ){
903 	skkinputDrawCursor( gw, x, y, kanji_check ) ;
904 	cursor_flag = True ;
905       }
906       cx = x ;
907       cy = y ;
908     }
909     /* ���������ɤΰ�Х����ܤʤΤǤ��礦���� */
910     if( kanji_check && kana_flag == False ){
911       kana_flag = True ;
912       chara = ( unsigned char )*text ;
913       /* ���̤α�ü�ޤ����褷���Τ��ɤ�����Ƚ�Ǥ��롣*/
914       if( ( x + w->skkinput.kanji_width ) >= end_x ){
915 	skkwin_jputchar
916 	  ( gw, x, y, '\\', False, False ) ;
917 	skkwin_jputchar
918 	  ( gw, x + w->skkinput.roman_width, y, '\\', False, False ) ;
919 	x = 0 ;
920 	y += w->skkinput.font_height ;
921 	/* ���̤β��ޤǽ��ڤä��Τ��ɤ�����Ƚ�Ǥ��롣*/
922 	if( y >= end_y )
923 	  goto exit_loop ;
924       }
925     } else {
926       /* ���������ɤ���Х����ܤʤΤǤ��礦���� */
927       if( kana_flag ){
928 	chara = ( chara << 8 ) | ( ( unsigned char )*text ) ;
929 	/* ���ξ��˥��������ɽ������Ƥ���ΤǤ����� */
930 	if( cursor_flag ){
931 	  skkwin_jputchar( gw, x, y, chara, False, True ) ;
932 	  cursor_flag = False ;
933 	} else {
934 	  skkwin_jputchar( gw, x, y, chara, True, False ) ;
935 	}
936 	x += w->skkinput.kanji_width ;
937 	kana_flag = False ;
938       } else {
939 	/* �������������ɤ��ä����ν����Ǥ���*/
940 	if( ( x + w->skkinput.roman_width ) >= end_x ){
941 	  skkwin_jputchar
942 	    ( gw, x, y, '\\', False, False ) ;
943 	  x =  0 ;
944 	  y += w->skkinput.font_height ;
945 	  /* ���̤β��ޤǽ��ڤä��Τ��ɤ�����Ƚ�Ǥ��롣*/
946 	  if( y >= end_y )
947 	    goto exit_loop ;
948 	}
949 	/* ���ΰ��֤˥������뤬ɽ������Ƥ����ΤǤ���С�ʸ����ȿž *
950 	 * �����롣*/
951 	if( cursor_flag ){
952 	  skkwin_jputchar( gw, x, y, *text, False, True ) ;
953 	  cursor_flag = False ;
954 	} else {
955 	  skkwin_jputchar( gw, x, y, *text, True, False ) ;
956 	}
957 	x += w->skkinput.roman_width ;
958       }
959     }
960     text ++ ;
961     pos ++ ;
962   }
963   /* �Ǹ�ޤǥ������뤬ɽ������Ƥ��ʤ��ä��Τʤ顢�Ǹ�ιԤ˥����� *
964    * ���ɽ�����롣*/
965   if( pos == node->cur_pos && node->cur_exist ){
966     /* ����������Ԥ�ɬ�פ��ꡩ */
967     if( ( x + w->skkinput.roman_width ) > end_x ){
968       skkwin_jputchar
969 	( gw, x, y, '\\', False, False ) ;
970       x  = 0 ;
971       y += w->skkinput.font_height ;
972     }
973     skkinputDrawCursor( gw, x, y, False ) ;
974     cx = x ;
975     cy = y ;
976   }
977 
978 exit_loop:
979   node->prev_cx = cx ;
980   node->prev_cy = cy ;
981 }
982 
skkinput_FullDrawModeLine(Widget gw,struct SKKInputNode * node,int x,int y,unsigned int width)983 static void skkinput_FullDrawModeLine
984 ( Widget gw, struct SKKInputNode *node, int x, int y, unsigned int width )
985 {
986   SkkInputWidget w = ( SkkInputWidget )gw ;
987   int modeline = skkinput_GetModelineNumber( node ) ;
988   static char *modelineStrings[] = {
989     "--SKK:E.:--", "--����E.:--", "--����E.:--", "--����E.:--",
990   } ;
991   /* ����ν����ˤ�äư㤦�⡼�ɥ饤��*/
992   static char *modelineStrings2[] = {
993     "---Skkinput:", "**-Skkinput:",
994   } ;
995   static char *chatadapterString[] = {
996     "(Fundamental", "(ChatAdapter",
997   } ;
998   /* �ޤ����⡼�ɥ饤���ɽ�����Ƥ������õ�롣*/
999   XFillRectangle
1000     ( XtDisplay( gw ), XtWindow( gw ), w->skkinput.roman_ngc,
1001      x, y - w->skkinput.font_ascent,
1002      width, w->skkinput.font_height ) ;
1003   /* �⡼�ɥ饤���ɽ������( SKK�Υ⡼��ɽ�� )��*/
1004   skkwin_jputstring
1005     ( gw, x, y, modelineStrings[ modeline - 1 ],
1006      w->skkinput.roman_width, w->skkinput.kanji_width, True ) ;
1007   /* ����������֤ι�����*/
1008   x += w->skkinput.roman_width * 11 ;
1009   /* �⡼�ɥ饤���ɽ������( ����ξ����ɽ�� )��*/
1010   skkwin_jputstring
1011     ( gw, x, y, modelineStrings2[ w->skkinput.jisyo_dirty ],
1012      w->skkinput.roman_width,
1013      w->skkinput.kanji_width, True ) ;
1014   /* ����������֤ι�����*/
1015   x += w->skkinput.roman_width * 24 ;
1016   /* �᡼����⡼�ɤ�ɽ����*/
1017   XDrawString
1018     ( XtDisplay( gw ), XtWindow( gw ), w->skkinput.roman_rgc,
1019      x, y, chatadapterString[ w->skkinput.chat_adapter % 2 ], 12 ) ;
1020   /* ����������֤ι�����*/
1021   x += w->skkinput.roman_width * 12 ;
1022   /* �ޥ��ʡ��⡼�ɤ�ɽ��(...ʣ�����ä��餳����դ��ƿϤ�ʥ����ɤ��� *
1023    * ���줽���Ǥ���) *
1024    * ����    �֤����ʤ�Ǥ�������
1025    * �ե��꡼�֤�������ʬ���äƤ�Ρ���
1026    * ����    �ֿ������������ޤ����ʿ��˸��Ȥ�Ƥ����äˤĤ��Ƥ��ä�
1027    *           �ޤ���Ǥ�������*/
1028   if( w->skkinput.egg_like_newline ){
1029     XDrawString
1030       ( XtDisplay( gw ), XtWindow( gw ), w->skkinput.roman_rgc,
1031        x, y, " egg-nl", 7 ) ;
1032     x += w->skkinput.roman_width * 7 ;
1033   } ;
1034   XDrawString
1035     ( XtDisplay( gw ), XtWindow( gw ), w->skkinput.roman_rgc,
1036      x, y, ")", 1 ) ;
1037   x += w->skkinput.roman_width ;
1038   /* �����³����*/
1039   XDrawString( XtDisplay( gw ), XtWindow( gw ), w->skkinput.roman_rgc,
1040 	       x, y, "--All", 5 ) ;
1041   x += w->skkinput.roman_width * 5 ;
1042   for( ; x < width ; x += w->skkinput.roman_width )
1043     XDrawString( XtDisplay( gw ), XtWindow( gw ), w->skkinput.roman_rgc,
1044 		 x, y, "-", 1 ) ;
1045   /* ����ɽ�������⡼�ɥ饤��������Ƥ�����*/
1046   w->skkinput.prev_modeline     = modeline ;
1047   w->skkinput.prev_jisyo_dirty  = w->skkinput.jisyo_dirty ;
1048   w->skkinput.prev_eggnl        = w->skkinput.egg_like_newline ;
1049   w->skkinput.prev_chat_adapter = w->skkinput.chat_adapter ;
1050   return ;
1051 }
1052 
1053 /*
1054  * skkinput �β��̤�������������ľ���ؿ���
1055  *-----
1056  * ���̤��礭�����ѹ��ʤɤ��Ԥ�줿���ˤϤ�����δؿ����ƤФ�뤳�Ȥ�
1057  * �ʤ롣
1058  */
skkinput_RedrawScreen(Widget gw)1059 static void skkinput_RedrawScreen( Widget gw )
1060 {
1061   SkkInputWidget w = ( SkkInputWidget )gw ;
1062   int x, y, cur_line, linenum, maxline, spos, sty, edy ;
1063   Window root ;
1064   unsigned int width, height, border, depth ;
1065   char *ptr ;
1066   struct SKKInputNode *mNode, *node = w->skkinput.topbuffer ;
1067 
1068   /* Window ����Ȥ�õ�롣*/
1069   XClearWindow( XtDisplay( gw ), XtWindow( gw ) ) ;
1070 
1071   /* Window �� size ��������롣*/
1072   XGetGeometry( XtDisplay( gw ), XtWindow( gw ),
1073 	        &root, &x, &y, &width, &height, &border, &depth ) ;
1074 
1075   /* ����ɽ����ǽ�Կ�����롣*/
1076   maxline = height / w->skkinput.font_height ;
1077   /* ���ߡ��ƥ����Ȥϲ��Ԥޤ�ɽ�����ʤ���Фʤ�ʤ��Τ����Ф��롣*/
1078   linenum = skkinput_GetLineNum( w, node->textbuffer, width,
1079 				 node->cur_pos, &cur_line ) ;
1080   /* �⡼�ɥ饤��� minibuffer �Τ�������ɬ�פǤ��뤫���롣*/
1081   maxline = ( maxline < 3 )? 1 : maxline - 2 ;
1082   /* ɽ����ǽ�Կ���Ķ���Ƥ������ν���������������֤������ϰϤ��� *
1083    * �ǰ��ֺǽ�ιԤ��ֹ椬�Ǥ⾮�������ʤ�褦�����ꤹ�롣*/
1084   if( linenum >= maxline && cur_line >= maxline ){
1085     int startline = cur_line - maxline + 1 ;
1086     /* ���ꤵ�줿��꤫��ɽ�����ʤ�Фʤ�ʤ��Τǡ����ΰ��֤��Ф��롣*/
1087     spos = skkinput_FindStartLine( w, node->textbuffer, startline,
1088 				   width ) ;
1089     ptr = node->textbuffer + spos ;
1090   }  else {
1091     spos = 0 ;
1092     /* ���˰��ֺǽ��ʸ������ɽ����ǽ�Ǥ��롣*/
1093     ptr = node->textbuffer ;
1094   }
1095   sty = w->skkinput.font_ascent ;
1096   edy = sty + maxline * w->skkinput.font_height ;
1097   /* Window �� buffer ��ʸ�����ɽ�����롣*/
1098   skkinput_FullDrawWindow( gw, node, ptr, spos, 0, sty, width, edy ) ;
1099   strcpy( w->skkinput.pwrite_string, node->textbuffer ) ;
1100 
1101   /* �⡼�ɥ饤���ɽ�����롣��ʬɽ����ľ���б�����ͽ��ǤϤ��롣*/
1102   sty = edy ;
1103   edy = sty + w->skkinput.font_height ;
1104   skkinput_FullDrawModeLine( gw, node, 0, sty, width ) ;
1105 
1106   /* mini-buffer ��ɽ�����롣*/
1107   mNode = w->skkinput.lastbuffer ;
1108   sty = edy ;
1109   edy = sty + w->skkinput.font_height ;
1110 
1111   if( mNode == node ){
1112     skkwin_jputstring( gw, 0, sty, node->mtextbuffer,
1113 		       w->skkinput.roman_width,
1114 		       w->skkinput.kanji_width, False ) ;
1115     strcpy( w->skkinput.pmtextbuffer, node->mtextbuffer ) ;
1116   } else {
1117     if( mNode->mtextbuffer[ 0 ] != '\0' ){
1118       skkwin_jputstring( gw, 0, sty, mNode->mtextbuffer,
1119 			 w->skkinput.roman_width,
1120 			 w->skkinput.kanji_width, False ) ;
1121       strcpy( w->skkinput.pmtextbuffer, mNode->mtextbuffer ) ;
1122     } else {
1123       /* Window �� buffer ��ʸ�����ɽ�����롣*/
1124       skkinput_FullDrawWindow( gw, mNode,
1125 			       mNode->textbuffer, 0, 0, sty,
1126 			       width, edy ) ;
1127       w->skkinput.pmtextbuffer[ 0 ] = '\0' ;
1128     }
1129   }
1130   return ;
1131 }
1132 
1133 /*
1134  * ��ʬ����ؿ�����������ɽ���ط��ν����ʤ������Ե�ǽ̵����
1135  *-----
1136  * ��Ϥ� minibuffer ���������ѤȤ��ä���������ޤ���
1137  */
skkwin_jdiffputstring(Widget gw,int x,int y,int width,char * text,char * ptext,int roman_width,int kana_width)1138 static void skkwin_jdiffputstring( Widget gw,
1139 				   int x, int y, int width,
1140 				   char *text, char *ptext,
1141 				   int roman_width, int kana_width )
1142 {
1143   SkkInputWidget w = ( SkkInputWidget )gw ;
1144   int dkana_flag, skana_flag, charas_are_different, diff_flag, chara ;
1145 
1146   charas_are_different = diff_flag = dkana_flag = skana_flag = False ;
1147   chara = 0 ;
1148 
1149   /* ��Ĥ�ʸ�������Ӥ��롣*/
1150   while( *text != '\0' && x < width ){
1151     /* ���������ɤ��������������ɤ������������ɤʤ餽�β��Х����ܤ���*/
1152     if( 0x80 & *text ){
1153       dkana_flag = dkana_flag % 2 + 1 ;
1154     } else {
1155       dkana_flag = 0 ;
1156     }
1157     /* ����ɽ�����줿����Ƚ���Ԥ���*/
1158     if( 0x80 & *ptext ){
1159       skana_flag = skana_flag % 2 + 1 ;
1160     } else {
1161       skana_flag = 0 ;
1162     }
1163     /* ���ơ�����饯���ϰۤʤ�ΤǤ��礦���� */
1164     if( *ptext != *text || skana_flag != dkana_flag || *ptext == '\0' ){
1165       charas_are_different = True ;
1166     } else {
1167       charas_are_different = False ;
1168     }
1169     switch( dkana_flag ){
1170       /* �������������ɤν�����*/
1171     case 0 :
1172       /* ��꤬��˲��Ԥ��Ƥ��ޤäƤ�����ˤ��̾��ɽ����*/
1173       /* �����ǤϤʤ��ơ�����饯������Ӥ��ưۤʤ����ɽ����*/
1174       if( charas_are_different )
1175 	skkwin_jputchar2( gw, x, y, *text, False, False ) ;
1176       /* ɽ�����֤ΰ�ư��*/
1177       x += w->skkinput.roman_width ;
1178       break ;
1179       /* ���������ɤΰ�Х����ܤν�����*/
1180     case 1 :
1181       chara = ( unsigned char )*text ;
1182       /* ���ä�����˲��Ԥ��Ƥ��ޤäƤ�����ˤ��Ԥġ�*/
1183       /* ���������ɤΰ�Х����ܤ�ʸ�����ۤʤäƤ����硣*/
1184       if( charas_are_different )
1185 	diff_flag = True ;
1186       break ;
1187       /* ���������ɤ����Х����ܤν�����*/
1188     case 2 :
1189       chara = ( chara << 8 ) | ( ( unsigned char )*text ) ;
1190       /* ���������ɤ����Х����ܤ�ʸ�����ۤʤäƤ�����ڤӡ���Х��� *
1191        * �ܤǰۤʤäƤ�����ˤϽ�ľ���κ�Ȥ����롣                 */
1192       if( charas_are_different || diff_flag ){
1193 	skkwin_jputchar2( gw, x, y, chara, False, False ) ;
1194 	diff_flag = False ;
1195       }
1196       /* ɽ�����֤ΰ�ư��*/
1197       x += w->skkinput.kanji_width ;
1198       break ;
1199     default :
1200       dkana_flag = 0 ;
1201       break ;
1202     }
1203     text ++ ;
1204     if( *ptext != '\0' )
1205       ptext ++ ;
1206   }
1207   /* ���̰��դޤ�ɽ������Ƥ���ΤǾõ��Ȥ�ɬ��̵����*/
1208   /* �⤷��������ɽ���˻Ȥä�ʬ��Ķ����ɽ�����Ƥ���Τǡ�*/
1209   if( x >= width || *ptext == '\0' )
1210     return ;
1211   /* �������Ƥ��ʤ���ʬ��õľ����*/
1212   while( *ptext != '\0' ){
1213     skkwin_jerase( gw, x, y, False ) ;
1214     x += roman_width ;
1215     ptext ++ ;
1216   }
1217   return ;
1218 }
1219 
1220 /*
1221  * �ߥ˥Хåե���ɽ������Ƥ�����Τ�õ��ؿ���
1222  */
skkinput_ClearMinibuffer(Widget gw)1223 static void skkinput_ClearMinibuffer( Widget gw )
1224 {
1225   SkkInputWidget w = ( SkkInputWidget )gw ;
1226   Window root ;
1227   int x, y, maxline ;
1228   unsigned int width, height, border, depth ;
1229 
1230   /* Window �� size ��������롣*/
1231   XGetGeometry( XtDisplay( gw ), XtWindow( gw ),
1232 	        &root, &x, &y, &width, &height, &border, &depth ) ;
1233 
1234   /* ����ɽ����ǽ�Կ�����롣*/
1235   maxline = height / w->skkinput.font_height ;
1236   if( maxline < 3 ){
1237     y = 2 * w->skkinput.font_height ;
1238   } else {
1239     y = ( maxline - 1 ) * w->skkinput.font_height ;
1240   }
1241   w->skkinput.pmtextbuffer[ 0 ] = '\0' ;
1242   XFillRectangle( XtDisplay( gw ), XtWindow( gw ), w->skkinput.roman_rgc,
1243 		  0, y, width, w->skkinput.font_height ) ;
1244   return ;
1245 }
1246