1 /*
2  * $Id: display.c,v 1.2 2001/06/14 18:16:12 ura Exp $
3  */
4 
5 /*
6  * FreeWnn is a network-extensible Kana-to-Kanji conversion system.
7  * This file is part of FreeWnn.
8  *
9  * Copyright OMRON Corporation. 1987, 1988, 1989, 1990, 1991, 1992, 1999
10  * Copyright 1991, 1992 by Massachusetts Institute of Technology
11  *
12  * Author: OMRON SOFTWARE Co., Ltd. <freewnn@rd.kyoto.omronsoft.co.jp>
13  *
14  * This program is free software; you can redistribute it and/or modify
15  * it under the terms of the GNU General Public License as published by
16  * the Free Software Foundation; either version 2, or (at your option)
17  * any later version.
18  *
19  * This program is distributed in the hope that it will be useful,
20  * but WITHOUT ANY WARRANTY; without even the implied warranty of
21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22  * GNU General Public License for more details.
23  *
24  * You should have received a copy of the GNU General Public License
25  * along with GNU Emacs; see the file COPYING.  If not, write to the
26  * Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27  *
28  * Commentary:
29  *
30  * Change log:
31  *
32  * Last modified date: 8,Feb.1999
33  *
34  * Code:
35  *
36  */
37 
38 /*      Version 4.0
39  */
40 #include <stdio.h>
41 #include "commonhd.h"
42 #include "sdefine.h"
43 #include "xjutil.h"
44 #include "sxheader.h"
45 #include "xext.h"
46 
47 extern wchar_t dol_wchar_t;
48 
49 wchar cursor_wchar = 0x20202020;
50 GC currentGC;
51 
52 static void
JWwindow_move(text)53 JWwindow_move (text)
54      register JutilTextRec *text;
55 {
56 
57   if ((check_mb (text->buf, text->vst)) == 2)
58     text->vst++;
59   XMoveWindow (dpy, text->w, -(text->vst * FontWidth), 0);
60   XFlush (dpy);
61 }
62 
63 static void
JWM_note(which)64 JWM_note (which)
65      int which;
66 {
67   if (!cur_text->note[which])
68     {
69       XMapWindow (dpy, cur_text->wn[which]);
70       XRaiseWindow (dpy, cur_text->wn[which]);
71       XwcDrawImageString (dpy, cur_text->wn[which], cur_fs->fs, cur_root->gc, 0, FontAscent, &dol_wchar_t, 1);
72       XFlush (dpy);
73     }
74 }
75 
76 static void
invisual_note(which)77 invisual_note (which)
78      int which;
79 {
80   if (cur_text->note[which])
81     {
82       XUnmapWindow (dpy, cur_text->wn[which]);
83       XFlush (dpy);
84     }
85 }
86 
87 static void
check_move(text,mb)88 check_move (text, mb)
89      register JutilTextRec *text;
90      int mb;
91 {
92   if ((text->currentcol - text->vst + mb) >= text->max_columns)
93     {
94       text->vst = text->currentcol - text->max_columns + mb + 1;
95       JWwindow_move (text);
96     }
97   else if (text->currentcol < text->vst)
98     {
99       text->vst = text->currentcol;
100       JWwindow_move (text);
101     }
102   if (text->vst)
103     {
104       JWM_note (0);
105       text->note[0] = 1;
106     }
107   else
108     {
109       invisual_note (0);
110       text->note[0] = 0;
111     }
112   if (text->max_pos > (text->vst + text->max_columns))
113     {
114       JWM_note (1);
115       text->note[1] = 1;
116       if ((check_mb (text->buf, text->vst + text->max_columns - 1)) == 1)
117         XMapWindow (dpy, text->wn[2]);
118       else
119         XUnmapWindow (dpy, text->wn[2]);
120     }
121   else
122     {
123       invisual_note (1);
124       text->note[1] = 0;
125       XUnmapWindow (dpy, text->wn[2]);
126     }
127 }
128 
129 static void
visual_window()130 visual_window ()
131 {
132   XMapWindow (dpy, cur_text->wp);
133   XMapWindow (dpy, cur_text->w);
134   XFlush (dpy);
135 }
136 
137 void
JWmark_cursor(on)138 JWmark_cursor (on)
139      int on;
140 {
141   register JutilTextRec *text;
142   wchar *JW_buf;
143   unsigned char *JW_att;
144   int mb_len;
145   char flg;
146   XCharStruct cs;
147 
148   text = cur_text;
149   JW_buf = text->buf + text->currentcol;
150   JW_att = text->att + text->currentcol;
151   visual_window ();
152   cs.width = FontWidth;
153   cs.ascent = FontAscent;
154   cs.descent = FontDescent;
155 
156   if (text->cursor_flag != 1 || text->mark_flag == on)
157     return;
158   text->mark_flag = on;
159 
160   if ((*JW_att & REV_FLAG) != 0)
161     return;
162 
163   if (*JW_buf)
164     {
165       if (*JW_buf == PENDING_WCHAR)
166         {
167           JW_buf++;
168           JW_att++;
169         }
170       mb_len = XwcGetColumn (*JW_buf);
171       flg = *JW_att;
172     }
173   else
174     {
175       JW_buf = &cursor_wchar;
176       JW_att = 0;
177       mb_len = 1;
178       flg = 0;
179     }
180   if (on)
181     {
182       if (mb_len > 1)
183         {
184           check_move (text, 1);
185         }
186       else
187         {
188           check_move (text, 0);
189         }
190       currentGC = cur_root->reversegc;
191       flg |= REV_FLAG;
192     }
193   else
194     {
195       currentGC = cur_root->gc;
196     }
197   JWOutput (text->w, cur_fs->fs, currentGC, text->currentcol, mb_len, flg, 0, 0, &cs, JW_buf, 1);
198   XFlush (dpy);
199 }
200 
201 void
JW1Mputwc(wc,wc_len)202 JW1Mputwc (wc, wc_len)
203      register wchar *wc;
204      int wc_len;
205 {
206   register int cnt = wc_len;
207   register JutilTextRec *text;
208   register wchar *JW_buf, *p = wc;
209   unsigned char *JW_att;
210   int mb_len;
211   short col = 0;
212   register int flg = 0;
213   XCharStruct cs;
214 
215   if (wc_len <= 0)
216     return;
217   text = cur_text;
218   visual_window ();
219   if (text->currentcol >= text->maxcolumns)
220     return;
221   JW_buf = text->buf + text->currentcol;
222   JW_att = text->att + text->currentcol;
223   if (text->r_flag)
224     flg |= REV_FLAG;
225   if (text->b_flag)
226     flg |= BOLD_FLAG;
227   if (text->u_line_flag)
228     flg |= UNDER_FLAG;
229 
230   cs.width = FontWidth;
231   cs.ascent = FontAscent;
232   cs.descent = FontDescent;
233 
234   for (; cnt > 0; cnt--, JW_buf++, JW_att++)
235     {
236       mb_len = XwcGetColumn (*p);
237       if (mb_len > 1)
238         {
239           *(JW_buf++) = PENDING_WCHAR;
240           *(JW_att++) = flg;
241         }
242       *JW_buf = *p++;
243       *JW_att = flg;
244       col += mb_len;
245       if (flg & REV_FLAG)
246         {
247           if (mb_len)
248             {
249               check_move (text, 1);
250             }
251           else
252             {
253               check_move (text, 0);
254             }
255         }
256     }
257   JWOutput (text->w, cur_fs->fs, ((flg & REV_FLAG) ? cur_root->reversegc : cur_root->gc), text->currentcol, col, flg, 0, 0, &cs, wc, wc_len);
258   text->currentcol += col;
259 }
260 
261 void
JWMflushw_buf(w_buf,len)262 JWMflushw_buf (w_buf, len)
263      w_char *w_buf;
264      int len;
265 {
266   int wc_len;
267 
268   if (len <= 0)
269     return;
270   while (1)
271     {
272       wc_len = w_char_to_wchar (xjutil->xlc, w_buf, wc_buf, len, wc_buf_max);
273       if (wc_len < -1)
274         {
275           return;
276         }
277       else if (wc_len == -1)
278         {
279           if (realloc_wc_buf () < 0)
280             return;
281         }
282       else
283         {
284           break;
285         }
286     }
287   JW1Mputwc (wc_buf, wc_len);
288   if (cur_text->currentcol > cur_text->max_pos)
289     {
290       cur_text->max_pos = cur_text->currentcol;
291     }
292   XFlush (dpy);
293 }
294 
295 void
jw_disp_mode(mode)296 jw_disp_mode (mode)
297      unsigned char *mode;
298 {
299   if (xjutil->mode & JUTIL_MODE)
300     {
301       cur_root->jutil->rk_mode->string = mode;
302       redraw_box (cur_root->jutil->rk_mode);
303     }
304   return;
305 }
306 
307 void
JWMline_clear(x)308 JWMline_clear (x)
309      register int x;
310 {
311   register JutilTextRec *text;
312   register int cnt;
313   register wchar *JW_buf;
314   unsigned char *JW_att;
315 
316   text = cur_text;
317   JW_buf = text->buf + x;
318   JW_att = text->att + x;
319   XClearArea (dpy, text->w, x * FontWidth, 0, (text->max_pos - x) * FontWidth + 1, 0, False);
320   if (x <= (text->vst + text->max_columns))
321     {
322       invisual_note (1);
323       text->note[1] = 0;
324       XUnmapWindow (dpy, text->wn[2]);
325     }
326   for (cnt = x; cnt < text->max_pos; cnt++)
327     {
328       *JW_buf++ = 0;
329       *JW_att++ = 0;
330     }
331   text->currentcol = x;
332   text->max_pos = x;
333   XFlush (dpy);
334 }
335 
336 void
JWcursor_visible()337 JWcursor_visible ()
338 {
339   cur_text->cursor_flag = 1;
340   JWmark_cursor (1);
341 }
342 
343 void
JWcursor_invisible()344 JWcursor_invisible ()
345 {
346   JWmark_cursor (0);
347   cur_text->cursor_flag = 0;
348 }
349 
350 void
JWcursor_move(x)351 JWcursor_move (x)
352      int x;
353 {
354   visual_window ();
355   JWmark_cursor (0);
356   cur_text->currentcol = x;
357   if (x >= 0)
358     JWmark_cursor (1);
359 }
360 
361 void
redraw_text(tx,x,width)362 redraw_text (tx, x, width)
363      register JutilTextRec *tx;
364      int x, width;
365 {
366   register wchar *JW_buf, *old_JW_buf, *wc;
367   unsigned char *JW_att;
368   unsigned char old_JW_att;
369   int currentcol_tmp = 0;
370   int start, end, startcol;
371   int wc_len, mb_len;
372   int col;
373   XCharStruct cs;
374 
375   currentcol_tmp = tx->currentcol;
376   start = x / FontWidth;
377   end = start + width / FontWidth + ((width % FontWidth) ? 1 : 0);
378   if (end > tx->max_pos)
379     end = tx->max_pos;
380   if (check_mb (tx->buf, start) == 2)
381     start--;
382   if (check_mb (tx->buf, (end - 1)) == 1)
383     end++;
384 
385   old_JW_buf = JW_buf = tx->buf + start;
386   JW_att = tx->att + start;
387   old_JW_att = *JW_att;
388   while (wc_buf_max < (end - start))
389     {
390       if (realloc_wc_buf () < 0)
391         return;
392     }
393   wc = wc_buf;
394   skip_pending_wchar (wc, JW_buf);
395   wc_len = 0;
396   col = 0;
397   startcol = start;
398   cs.width = FontWidth;
399   cs.ascent = FontAscent;
400   cs.descent = FontDescent;
401 
402   for (tx->currentcol = start; tx->currentcol < end;)
403     {
404       JW_buf = tx->buf + tx->currentcol;
405       JW_att = tx->att + tx->currentcol;
406       if (*JW_buf == PENDING_WCHAR)
407         {
408           JW_buf++;
409           JW_att++;
410         }
411       mb_len = XwcGetColumn (*JW_buf);
412       if ((*JW_att != old_JW_att) && (wc_len > 0))
413         {
414           if (old_JW_att & REV_FLAG)
415             {
416               currentGC = cur_root->reversegc;
417             }
418           else
419             {
420               currentGC = cur_root->gc;
421             }
422           JWOutput (tx->w, cur_fs->fs, currentGC, startcol, col, old_JW_att, 0, 0, &cs, wc, wc_len);
423           old_JW_buf = JW_buf;
424           old_JW_att = *JW_att;
425           wc += wc_len;
426           wc_len = 0;
427           col = 0;
428           startcol = tx->currentcol;
429         }
430       if (*JW_att & REV_FLAG)
431         {
432           if (mb_len)
433             {
434               check_move (tx, 1);
435             }
436           else
437             {
438               check_move (tx, 0);
439             }
440         }
441       wc_len++;
442       col += mb_len;
443       tx->currentcol += mb_len;
444     }
445   if (wc_len > 0)
446     {
447       if (old_JW_att & REV_FLAG)
448         {
449           currentGC = cur_root->reversegc;
450         }
451       else
452         {
453           currentGC = cur_root->gc;
454         }
455       JWOutput (tx->w, cur_fs->fs, currentGC, startcol, col, old_JW_att, 0, 0, &cs, wc, wc_len);
456     }
457   tx->currentcol = currentcol_tmp;
458   if (tx->cursor_flag == 1 && tx->mark_flag == 1)
459     {
460       tx->mark_flag = 0;
461       JWmark_cursor (1);
462     }
463 }
464 
465 void
redraw_note(tx,which)466 redraw_note (tx, which)
467      register JutilTextRec *tx;
468      int which;
469 {
470   XwcDrawImageString (dpy, tx->wn[which], cur_fs->fs, cur_root->gc, 0, FontAscent, &dol_wchar_t, 1);
471   XFlush (dpy);
472 }
473 
474 void
check_scroll()475 check_scroll ()
476 {
477   int mb;
478 
479   mb = check_mb (cur_text->buf, cur_text->currentcol);
480   if ((cur_text->currentcol < cur_text->vst) || ((cur_text->currentcol - cur_text->vst - mb) >= cur_text->max_columns))
481     {
482       if (mb == 1)
483         check_move (cur_text, 1);
484       else
485         check_move (cur_text, 0);
486     }
487 }
488