1 /* # skkinput (Simple Kana-Kanji Input)
2  *
3  * This file is part of skkinput.
4  * Copyright (C) 2002
5  * Takashi SAKAMOTO (PXG01715@nifty.ne.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 "AfxWin.h"
22 #include <stdio.h>
23 #include <X11/Intrinsic.h>
24 #include "TTerminalP.h"
25 #include "dtext.h"
26 
27 #if !defined (DEFAULT_FONTSET)
28 #define	DEFAULT_FONTSET	"-*--12-*"
29 #endif
30 
31 #define	TTERM_NCHAR_PER_MALLOC	(16)
32 
33 #define offset(field)	XtOffsetOf(TTerminalRec, tterminal.field)
34 #define goffset(field)	XtOffsetOf(WidgetRec, core.field )
35 
36 static	XtResource	srTTerminalResource []	= {
37 	{	XtNwidth,		XtCWidth,		XtRDimension,	sizeof (Dimension),
38 		goffset (width),			XtRImmediate,	(XtPointer) 640, },
39 	{	XtNheight,		XtCHeight,		XtRDimension,	sizeof (Dimension),
40 		goffset (height),			XtRImmediate,	(XtPointer) 48, },
41 	{	XtNbackground,	XtCBackground,	XtRPixel,		sizeof (Pixel),
42 		goffset (background_pixel),	XtRString,		XtDefaultBackground, },
43 	{	XtNparentWindow,	XtCParentWindow,	XtRWindow,	sizeof (Window),
44 		offset (m_wndParent),		XtRImmediate,	(XtPointer) None, },
45 	{	XtNreverseVideo,	XtCReverseVideo,	XtRBoolean,	sizeof (Boolean),
46 		offset (m_fReverseVideo),	XtRImmediate,	(XtPointer) False, },
47 	{	XtNforeground,	XtCForeground,	XtRPixel,		sizeof (Pixel),
48 		offset (m_pxlFore),			XtRString,		XtDefaultForeground, },
49 	{	XtNfontSet,		XtCFontSet,		XtRString,		sizeof (String),
50 		offset (m_strFontSet),		XtRString,		DEFAULT_FONTSET, },
51 } ;
52 
53 #undef	offset
54 #undef	goffset
55 
56 static	void	tterminal_onInitialize	(Widget, Widget, ArgList, Cardinal*) ;
57 static	void	tterminal_onRealize		(Widget, XtValueMask*, XSetWindowAttributes*) ;
58 static	void	tterminal_onExpose		(Widget, XEvent*, Region) ;
59 static	Boolean	tterminal_onSetValues	(Widget, Widget, Widget, ArgList, Cardinal*) ;
60 static	void	tterminal_onDestroy		(Widget) ;
61 
62 static	Boolean	tterminal_putcharControl	(Widget, Char) ;
63 static	Boolean	tterminal_putcharPrintable	(Widget, Char) ;
64 
65 
66 /* �����Х��ѿ���
67  */
68 static XtActionsRec		srTTerminalAction [] = {
69 } ;
70 
71 static char				sstrTTerminalTranslation [] = "" ;
72 
73 
74 TTerminalClassRec		tterminalClassRec	= {
75     {	/* core fields */
76 		/* superclass			*/	&widgetClassRec,
77 		/* class_name			*/	"TTerminal",
78 		/* size					*/	sizeof (TTerminalRec),
79 		/* class_initialize		*/	NULL,
80 		/* class_part_initialize*/	NULL,
81 		/* class_inited			*/	FALSE,
82 		/* initialize			*/	tterminal_onInitialize,
83 		/* initialize_hook		*/	NULL,
84 		/* realize				*/	tterminal_onRealize,
85 		/* actions				*/	srTTerminalAction,
86 		/* num_actions			*/	XtNumber (srTTerminalAction),
87 		/* resources			*/	srTTerminalResource,
88 		/* num_resources		*/	XtNumber(srTTerminalResource),
89 		/* xrm_class			*/	NULLQUARK,
90 		/* compress_motion		*/	TRUE,
91 		/* compress_exposure	*/	TRUE,
92 		/* compress_enterleave	*/	TRUE,
93 		/* visible_interest		*/	FALSE,
94 		/* destroy				*/	tterminal_onDestroy,
95 		/* resize				*/	XtInheritResize,
96 		/* expose				*/	tterminal_onExpose,
97 		/* set_values			*/	tterminal_onSetValues,
98 		/* set_values_hook		*/	NULL,
99 		/* set_values_almost	*/	XtInheritSetValuesAlmost,
100 		/* get_values_hook		*/	NULL,
101 		/* accept_focus			*/	NULL,
102 		/* version				*/	XtVersion,
103 		/* callback_private		*/	NULL,
104 		/* tm_table				*/	sstrTTerminalTranslation,
105 		/* query_geometry		*/	XtInheritQueryGeometry,
106     },
107 } ;
108 
109 WidgetClass	tterminalWidgetClass	= (WidgetClass) &tterminalClassRec ;
110 
111 void
tterminal_onInitialize(Widget wgRequest,Widget wgNew,ArgList args,Cardinal * num_args)112 tterminal_onInitialize (
113 	Widget		wgRequest,
114 	Widget		wgNew,
115 	ArgList		args,
116 	Cardinal*	num_args)
117 {
118 	register TTerminalWidget	w 	= (TTerminalWidget) wgNew ;
119 	TTermLineInfo				tli ;
120 
121 	TVarbuffer_Initialize (&w->tterminal.m_vbCurText, sizeof (DChar)) ;
122 	TVarbuffer_Initialize (&w->tterminal.m_vbReqText, sizeof (DChar)) ;
123 	TVarbuffer_Initialize (&w->tterminal.m_vbCurLineInfo, sizeof (TTermLineInfo)) ;
124 	TVarbuffer_Initialize (&w->tterminal.m_vbReqLineInfo, sizeof (TTermLineInfo)) ;
125 
126 	w->tterminal.m_iRow		= 0 ;
127 	w->tterminal.m_iColumn	= 0 ;
128 	w->tterminal.m_fRev		= False ;	/* ���� reverse video �� terminal �Ȥ��ƤΡ�*/
129 
130 	tli.m_nIndex	= 0 ;
131 	tli.m_nLength	= 0 ;
132 	tli.m_nSize		= 0 ;
133 	tli.m_nPrev		= -1 ;
134 	tli.m_nNext		= -1 ;
135 	TVarbuffer_Add (&w->tterminal.m_vbReqLineInfo, &tli, 1) ;
136 	TVarbuffer_Add (&w->tterminal.m_vbCurLineInfo, &tli, 1) ;
137 	w->tterminal.m_nReqTailLineIndex	= 0 ;
138 
139 	/*	�ե���Ȥν��������������� onSetValues ���ƤФ�뤳�Ȥ������
140 	 *	��̿Ū��
141 	 */
142 	TFontSet_Initialize (&w->tterminal.m_FontSet) ;
143 	return ;
144 }
145 
146 void
tterminal_onRealize(register Widget wgThis,register XtValueMask * pValueMask,register XSetWindowAttributes * pXSWA)147 tterminal_onRealize (
148 	register Widget					wgThis,
149 	register XtValueMask*			pValueMask,
150 	register XSetWindowAttributes*	pXSWA)
151 {
152 	register TTerminalWidget	wgTerm		= (TTerminalWidget) wgThis ;
153 	register Display*			pDisplay	= XtDisplay (wgThis) ;
154 	XGCValues	gcvalue ;
155 
156 	if (wgTerm->tterminal.m_wndParent != None) {
157 		register Widget				wgParent ;
158 		register Window				wndRoot ;
159 		XWindowAttributes	xwa ;
160 
161 		XGetWindowAttributes (XtDisplay (wgThis), wgTerm->tterminal.m_wndParent, &xwa) ;
162 		wgParent	= wgThis->core.parent ;
163 		wndRoot		= wgThis->core.screen->root ;
164 		wgThis->core.depth			= xwa.depth ;
165 		wgThis->core.parent			= NULL ;
166 		wgThis->core.screen->root	= wgTerm->tterminal.m_wndParent ;
167 		XtCreateWindow (wgThis, (unsigned int)InputOutput, (Visual *)CopyFromParent, *pValueMask, pXSWA) ;
168 		wgThis->core.parent			= wgParent ;
169 		wgThis->core.screen->root	= wndRoot ;
170 	} else {
171 		XtCreateWindow (wgThis, (unsigned int)InputOutput, (Visual *)CopyFromParent, *pValueMask, pXSWA) ;
172 	}
173 #if 0
174 	gcvalue.foreground	= wgTerm->tterminal.m_pxlFore ;
175 	gcvalue.background	= wgTerm->core.background_pixel ;
176 	wgTerm->tterminal.m_gc	= XtGetGC ((Widget) wgThis, GCForeground | GCBackground, &gcvalue) ;
177 #else
178 	gcvalue.foreground	= BlackPixel (pDisplay, 0) ;
179 	gcvalue.background	= WhitePixel (pDisplay, 0) ;
180 	wgTerm->tterminal.m_gc	= XCreateGC (pDisplay, XtWindow (wgThis), GCForeground | GCBackground, &gcvalue) ;
181 #endif
182 	TFontSet_Load (pDisplay, &wgTerm->tterminal.m_FontSet, wgTerm->tterminal.m_strFontSet, False) ;
183 	return ;
184 }
185 
186 void
tterminal_onExpose(register Widget wgThis,register XEvent * pEvent,register Region region)187 tterminal_onExpose (
188 	register Widget		wgThis,
189 	register XEvent*	pEvent,
190 	register Region		region)
191 {
192 	register	TTerminalWidget	w	= (TTerminalWidget) wgThis ;
193 	register	Display*		pDisplay ;
194 	register	Window			wnd ;
195 	register	GC				gc ;
196 	register	TFontSet*		pFontSet ;
197 	register	DChar*			pCurTextTop ;
198 	register	TTermLineInfo*	pCurLineInfoTop ;
199 	register	TTermLineInfo*	pCurLineInfo ;
200 	register	int				nCurLineInfo ;
201 	register	int				nPoint, y, nHeight ;
202 
203 	pDisplay		= XtDisplay (wgThis) ;
204 	wnd				= XtWindow  (wgThis) ;
205 	gc				= w->tterminal.m_gc ;
206 	pFontSet		= TTerminal_GetFontSet (wgThis) ;
207 
208 	pCurLineInfoTop	= TVarbuffer_GetBuffer (&w->tterminal.m_vbCurLineInfo) ;
209 	nCurLineInfo	= TVarbuffer_GetUsage  (&w->tterminal.m_vbCurLineInfo) ;
210 	pCurTextTop		= TVarbuffer_GetBuffer (&w->tterminal.m_vbCurText) ;
211 	nPoint			= 0 ;
212 	y				= TFontSet_GetAscent (pFontSet) ;
213 	nHeight			= TFontSet_GetHeight (pFontSet) ;
214 
215 	while (nCurLineInfo > 0) {
216 		pCurLineInfo	= pCurLineInfoTop + nPoint ;
217 		if (pCurLineInfo->m_nLength > 0)
218 			TDTextOut (pDisplay, wnd, gc, pFontSet, 0, y, pCurTextTop + pCurLineInfo->m_nIndex, pCurLineInfo->m_nLength, NULL) ;
219 		nPoint			= pCurLineInfo->m_nNext ;
220 		y				+= nHeight ;
221 		nCurLineInfo	-- ;
222 	}
223 	return ;
224 }
225 
226 Boolean
tterminal_onSetValues(register Widget curw,register Widget reqw,register Widget neww,register ArgList args,register Cardinal * num_args)227 tterminal_onSetValues (
228 	register Widget		curw,
229 	register Widget		reqw,
230 	register Widget		neww,
231 	register ArgList	args,
232 	register Cardinal*	num_args)
233 {
234 	register TTerminalWidget	curtw	= (TTerminalWidget) curw ;
235 	register TTerminalWidget	reqtw	= (TTerminalWidget) reqw ;
236 	register TTerminalWidget	newtw	= (TTerminalWidget) neww ;
237 	register Boolean		fRetval	= False ;
238 
239 	/*	FontSet �ޤ뤴�Ȥ������ؤ��ؼ������ä����Υ����å���
240 	 *	���̤��ѹ��� SetValues �ǤϹԤ�ʤ����̤� Method �����Ѥ��롣
241 	 */
242 	if (curtw->tterminal.m_strFontSet != reqtw->tterminal.m_strFontSet &&
243 		strcmp (curtw->tterminal.m_strFontSet, reqtw->tterminal.m_strFontSet) == 0) {
244 		newtw->tterminal.m_strFontSet	= reqtw->tterminal.m_strFontSet ;
245 		/*	�����߻ȤäƤ���ե���ȥ��åȤ�������ơ��������ե���ȥ��åȤ�
246 		 *	�ɤ߹��ࡣ*/
247 		if (XtIsRealized (neww)) {
248 			TFontSet_Load (XtDisplay (neww), &newtw->tterminal.m_FontSet, newtw->tterminal.m_strFontSet, False) ;
249 			fRetval	= True ;
250 		}
251 	}
252 	return	fRetval ;
253 }
254 
255 void
tterminal_onDestroy(register Widget gw)256 tterminal_onDestroy (
257 	register Widget		gw)
258 {
259 	register TTerminalWidget	wgThis	= (TTerminalWidget) gw ;
260 
261 	if (wgThis->tterminal.m_gc != None) {
262 		XtReleaseGC (gw, wgThis->tterminal.m_gc) ;
263 		wgThis->tterminal.m_gc	= None ;
264 	}
265 	TFontSet_Destroy (&wgThis->tterminal.m_FontSet) ;
266 	return ;
267 }
268 
269 Boolean
TTerminal_Putchar(register Widget wgThis,register Char cc)270 TTerminal_Putchar (
271 	register Widget		wgThis,
272 	register Char		cc)
273 {
274 	if (XtClass (wgThis) != tterminalWidgetClass)
275 		return	False ;
276 
277 #if defined (DEBUG)
278 	if (cc != 10)
279 		fprintf (stderr, "TTerminal_Putchar (%p, %ld)\n", wgThis, cc) ;
280 #endif
281 	if (cc < 0x20) {
282 		return	tterminal_putcharControl (wgThis, cc) ;
283 	} else {
284 		return	tterminal_putcharPrintable (wgThis, cc) ;
285 	}
286 }
287 
288 TFontSet*
TTerminal_GetFontSet(register Widget wgThis)289 TTerminal_GetFontSet (
290 	register Widget		wgThis)
291 {
292 	register TTerminalWidget	wgTerm ;
293 
294 	if (XtClass (wgThis) != tterminalWidgetClass)
295 		return	NULL ;
296 
297 	wgTerm			= (TTerminalWidget) wgThis ;
298 	return	&wgTerm->tterminal.m_FontSet ;
299 }
300 
301 Boolean
TTerminal_Clear(register Widget wgThis)302 TTerminal_Clear (
303 	register Widget		wgThis)
304 {
305 	register TTerminalWidget	wgTerm ;
306 	TTermLineInfo	tli ;
307 
308 	if (XtClass (wgThis) != tterminalWidgetClass)
309 		return	False ;
310 
311 	wgTerm			= (TTerminalWidget) wgThis ;
312 
313 	TVarbuffer_Clear (&wgTerm->tterminal.m_vbReqText) ;
314 	TVarbuffer_Clear (&wgTerm->tterminal.m_vbReqLineInfo) ;
315 	tli.m_nIndex	= 0 ;
316 	tli.m_nLength	= 0 ;
317 	tli.m_nSize		= TVarbuffer_GetUsage (&wgTerm->tterminal.m_vbReqText) ;
318 	tli.m_nPrev		= -1 ;
319 	tli.m_nNext		= -1 ;
320 	TVarbuffer_Add (&wgTerm->tterminal.m_vbReqLineInfo, &tli, 1) ;
321 	wgTerm->tterminal.m_nReqTailLineIndex	= 0 ;
322 
323 	/*
324 	 *	�������������˰�ư�����롣
325 	 */
326 	wgTerm->tterminal.m_iRow		= 0 ;
327 	wgTerm->tterminal.m_iColumn	= 0 ;
328 	return	True ;
329 }
330 
331 
332 Boolean
TTerminal_Rev(register Widget wgThis,register Boolean fRev)333 TTerminal_Rev (
334 	register Widget		wgThis,
335 	register Boolean	fRev)
336 {
337 	if (XtClass (wgThis) != tterminalWidgetClass)
338 		return	False ;
339 
340 	((TTerminalWidget) wgThis)->tterminal.m_fRev	= fRev ;
341 	return	True ;
342 }
343 
344 Boolean
TTerminal_MoveCursor(register Widget wgThis,register int nRow,register int nColumn)345 TTerminal_MoveCursor (
346 	register Widget		wgThis,
347 	register int		nRow,
348 	register int		nColumn)
349 {
350 	register TTerminalWidget	wgTerm ;
351 	register TTermLineInfo*	pLineInfo ;
352 	register int			nMaxRow ;
353 
354 	if (XtClass (wgThis) != tterminalWidgetClass)
355 		return	False ;
356 
357 	wgTerm	= (TTerminalWidget) wgThis ;
358 
359 	/*
360 	 *	Row ¦��ɬ��¸�ߤ��ʤ��Ȥ����ʤ���
361 	 */
362 	nMaxRow	= TVarbuffer_GetUsage (&wgTerm->tterminal.m_vbReqLineInfo) ;
363 	assert (nMaxRow > 0) ;
364 	if (nRow >= nMaxRow)
365 		nRow	= nMaxRow - 1 ;
366 	if (nRow < 0)
367 		nRow	= 0 ;
368 
369 	pLineInfo	= TVarbuffer_GetBuffer (&wgTerm->tterminal.m_vbReqLineInfo) ;
370 	pLineInfo	+= nRow ;
371 	if (nColumn > pLineInfo->m_nLength)
372 		nColumn	= pLineInfo->m_nLength ;
373 	if (nColumn < 0)
374 		nColumn	= 0 ;
375 
376 	wgTerm->tterminal.m_iRow		= nRow ;
377 	wgTerm->tterminal.m_iColumn	= nColumn ;
378 	return	True ;
379 }
380 
381 Boolean
TTerminal_Flush(register Widget wgThis)382 TTerminal_Flush (
383 	register Widget		wgThis)
384 {
385 	register TTerminalWidget	wgTerm ;
386 	register DChar*			pReq ;
387 	register DChar*			pCur ;
388 	register int			nReq ;
389 	register int			nCur ;
390 
391 	if (XtClass (wgThis) != tterminalWidgetClass)
392 		return	False ;
393 
394 	wgTerm	= (TTerminalWidget) wgThis ;
395 	pReq	= TVarbuffer_GetBuffer (&wgTerm->tterminal.m_vbReqText) ;
396 	nReq	= TVarbuffer_GetUsage  (&wgTerm->tterminal.m_vbReqText) ;
397 	nCur	= TVarbuffer_GetUsage  (&wgTerm->tterminal.m_vbCurText) ;
398 	if (nReq != nCur)
399 		TVarbuffer_Require (&wgTerm->tterminal.m_vbCurText, nReq - nCur) ;
400 	pCur	= TVarbuffer_GetBuffer (&wgTerm->tterminal.m_vbCurText) ;
401 	memcpy (pCur, pReq, nReq * sizeof (DChar)) ;
402 	return	True ;
403 }
404 
405 Boolean
TTerminal_Update(register Widget wgThis)406 TTerminal_Update (
407 	register Widget		wgThis)
408 {
409 	register	TTerminalWidget	wgTerm ;
410 	register	Display*		pDisplay ;
411 	register	Window			wnd ;
412 	register	GC				gc ;
413 	register	TFontSet*		pFontSet ;
414 	register	DChar*			pCurTextTop ;
415 	register	TTermLineInfo*	pCurLineInfoTop ;
416 	register	TTermLineInfo*	pCurLineInfo ;
417 	register	int				nCurLineInfo ;
418 	register	int				nCurPoint ;
419 	register	DChar*			pReqTextTop ;
420 	register	TTermLineInfo*	pReqLineInfoTop ;
421 	register	TTermLineInfo*	pReqLineInfo ;
422 	register	int				nReqPoint ;
423 	register	Boolean			fRedraw ;
424 	register	int				nReqLineInfo ;
425 	register	int				nReqLine ;
426 	register	int				nReqChar ;
427 	register	int				y, nAscent, nHeight ;
428 	TSize						szWnd ;
429 
430 	wgTerm			= (TTerminalWidget) wgThis ;
431 	pDisplay		= XtDisplay (wgThis) ;
432 	wnd				= XtWindow  (wgThis) ;
433 	gc				= wgTerm->tterminal.m_gc ;
434 	pFontSet		= TTerminal_GetFontSet (wgThis) ;
435 	szWnd.cx		= wgThis->core.width ;
436 	szWnd.cy		= wgThis->core.height ;
437 
438 	pReqLineInfoTop	= TVarbuffer_GetBuffer (&wgTerm->tterminal.m_vbReqLineInfo) ;
439 	nReqLine		= TVarbuffer_GetUsage  (&wgTerm->tterminal.m_vbReqLineInfo) ;
440 	nReqLineInfo	= nReqLine ;
441 	pReqTextTop		= TVarbuffer_GetBuffer (&wgTerm->tterminal.m_vbReqText) ;
442 	nReqChar 		= TVarbuffer_GetUsage (&wgTerm->tterminal.m_vbReqText) ;
443 	nReqPoint		= 0 ;
444 	pCurLineInfoTop	= TVarbuffer_GetBuffer (&wgTerm->tterminal.m_vbCurLineInfo) ;
445 	nCurLineInfo	= TVarbuffer_GetUsage  (&wgTerm->tterminal.m_vbCurLineInfo) ;
446 	pCurTextTop		= TVarbuffer_GetBuffer (&wgTerm->tterminal.m_vbCurText) ;
447 	nCurPoint		= 0 ;
448 	nAscent			= TFontSet_GetAscent (pFontSet) ;
449 	nHeight			= TFontSet_GetHeight (pFontSet) ;
450 	y				= nAscent ;
451 	while (nReqLineInfo > 0) {
452 		pReqLineInfo	= pReqLineInfoTop + nReqPoint ;
453 		if (nCurLineInfo > 0) {
454 			pCurLineInfo	= pCurLineInfoTop + nCurPoint ;
455 			if (pCurLineInfo->m_nLength != pReqLineInfo->m_nLength) {
456 				fRedraw	= True ;
457 			} else if (memcmp (pCurTextTop + pCurLineInfo->m_nIndex,
458 							   pReqTextTop + pReqLineInfo->m_nIndex,
459 							   pCurLineInfo->m_nLength * sizeof (DChar))) {
460 				fRedraw	=	True ;
461 			} else {
462 				fRedraw	=	False ;
463 			}
464 			nCurPoint		= pCurLineInfo->m_nNext ;
465 			nCurLineInfo	-- ;
466 		} else {
467 			fRedraw	= True ;
468 		}
469 		if (fRedraw) {
470 			TSize	sz ;
471 			if (pReqLineInfo->m_nLength > 0) {
472 				TDTextOut (pDisplay, wnd, gc, pFontSet, 0, y, pReqTextTop + pReqLineInfo->m_nIndex, pReqLineInfo->m_nLength, &sz) ;
473 			} else {
474 				sz.cx	= 0 ;
475 			}
476 			XClearArea (pDisplay, wnd, sz.cx, y - nAscent, szWnd.cx - sz.cx, nHeight, False) ;
477 		}
478 		nReqPoint		= pReqLineInfo->m_nNext ;
479 		y				+= nHeight ;
480 		nReqLineInfo	-- ;
481 	}
482 	if (nCurLineInfo > 0) {
483 		XClearArea (pDisplay, wnd, 0, y - nAscent, szWnd.cx, nHeight * nCurLineInfo, False) ;
484 	}
485 	{
486 		register	int	nCharDiff ;
487 		register	int	nLineDiff ;
488 		nCharDiff	= nReqChar - TVarbuffer_GetUsage (&wgTerm->tterminal.m_vbCurText) ;
489 		nLineDiff	= nReqLine - TVarbuffer_GetUsage (&wgTerm->tterminal.m_vbCurLineInfo) ;
490 		if (TFAILED (TVarbuffer_Require (&wgTerm->tterminal.m_vbCurText,     nCharDiff)) ||
491 			TFAILED (TVarbuffer_Require (&wgTerm->tterminal.m_vbCurLineInfo, nLineDiff)))
492 			return	False ;
493 	}
494 
495 	pReqLineInfoTop	= TVarbuffer_GetBuffer (&wgTerm->tterminal.m_vbReqLineInfo) ;
496 	pCurLineInfoTop	= TVarbuffer_GetBuffer (&wgTerm->tterminal.m_vbCurLineInfo) ;
497 	memcpy (pCurLineInfoTop, pReqLineInfoTop, sizeof (TTermLineInfo) * nReqLine) ;
498 	pReqTextTop		= TVarbuffer_GetBuffer (&wgTerm->tterminal.m_vbReqText) ;
499 	pCurTextTop		= TVarbuffer_GetBuffer (&wgTerm->tterminal.m_vbCurText) ;
500 	memcpy (pCurTextTop, pReqTextTop, sizeof (DChar) * nReqChar) ;
501 	return	True ;
502 }
503 
504 /*========================================================================*
505  *	������ؿ���
506  *========================================================================*/
507 Boolean
tterminal_putcharControl(register Widget wgThis,register Char cc)508 tterminal_putcharControl (
509 	register Widget		wgThis,
510 	register Char		cc)
511 {
512 	register TTerminalWidget	wgTerm	= (TTerminalWidget) wgThis ;
513 	register TFontSet*		pFontSet ;
514 	TSize					sz ;
515 	register int			nHeight ;
516 
517 	switch (cc) {
518 	case	'\n':
519 		pFontSet					= TTerminal_GetFontSet (wgThis) ;
520 		nHeight						= TFontSet_GetHeight (pFontSet) ;
521 		wgTerm->tterminal.m_iColumn	= 0 ;
522 		/*	�������뤬���̳��˽Фʤ��褦����ա�*/
523 		sz.cx						= wgThis->core.width ;
524 		sz.cy						= wgThis->core.height ;
525 		if ((wgTerm->tterminal.m_iRow + 1) * nHeight < sz.cy)
526 			wgTerm->tterminal.m_iRow		++ ;
527 		assert (0 <= wgTerm->tterminal.m_iRow) ;
528 		assert (wgTerm->tterminal.m_iRow <= TVarbuffer_GetUsage (&wgTerm->tterminal.m_vbReqLineInfo)) ;
529 		/*	�����˥饤�������ɲä��ʤ���Фʤ�ʤ����� */
530 		if (wgTerm->tterminal.m_iRow == TVarbuffer_GetUsage (&wgTerm->tterminal.m_vbReqLineInfo)) {
531 			TTermLineInfo*	pPrevLineInfo ;
532 			TTermLineInfo	tli ;
533 
534 			tli.m_nIndex	= TVarbuffer_GetUsage (&wgTerm->tterminal.m_vbReqText) ;
535 			tli.m_nLength	= 0 ;
536 			tli.m_nSize		= 0 ;
537 			tli.m_nPrev		= wgTerm->tterminal.m_nReqTailLineIndex ;
538 			tli.m_nNext		= -1 ;
539 			if (TFAILED (TVarbuffer_Add (&wgTerm->tterminal.m_vbReqLineInfo, &tli, 1)))
540 				return	False ;
541 
542 			/*
543 			 *	���ιԤξ������äƤ��롣
544 			 */
545 			pPrevLineInfo			= (TTermLineInfo *)TVarbuffer_GetBuffer (&wgTerm->tterminal.m_vbReqLineInfo) + wgTerm->tterminal.m_nReqTailLineIndex ;
546 			pPrevLineInfo->m_nNext	= wgTerm->tterminal.m_iRow ;
547 			wgTerm->tterminal.m_nReqTailLineIndex	= wgTerm->tterminal.m_iRow ;
548 #if defined (DEBUG)
549 		} else {
550 			fprintf (stderr, "Failure! %d, %d\n",
551 					 wgTerm->tterminal.m_iRow,
552 					 TVarbuffer_GetUsage (&wgTerm->tterminal.m_vbReqLineInfo)) ;
553 #endif
554 		}
555 		break ;
556 	default:
557 		/*	���ΤȤ�����԰ʳ��� control code �������ʤ���*/
558 		break ;
559 	}
560 	return	True ;
561 }
562 
563 Boolean
tterminal_putcharPrintable(register Widget wgThis,register Char cc)564 tterminal_putcharPrintable (
565 	register Widget		wgThis,
566 	register Char		cc)
567 {
568 	register TTerminalWidget	wgTerm	= (TTerminalWidget) wgThis ;
569 	register Pixel			pxlFore ;
570 	register Pixel			pxlBack ;
571 	register DChar*			pTextTop ;
572 	register DChar*			pText ;
573 	register TTermLineInfo*	pLineInfoTop ;
574 	register TTermLineInfo*	pLineInfo ;
575 
576 	assert (0 <= wgTerm->tterminal.m_iRow) ;
577 	assert (wgTerm->tterminal.m_iRow < TVarbuffer_GetUsage (&wgTerm->tterminal.m_vbReqLineInfo)) ;
578 
579 	pLineInfoTop	= TVarbuffer_GetBuffer (&wgTerm->tterminal.m_vbReqLineInfo) ;
580 	pLineInfo		= pLineInfoTop + wgTerm->tterminal.m_iRow ;
581 	assert (0 <= wgTerm->tterminal.m_iColumn) ;
582 	assert (wgTerm->tterminal.m_iColumn <= pLineInfo->m_nLength) ;
583 
584 	if (wgTerm->tterminal.m_fRev) {
585 		pxlFore	= wgTerm->core.background_pixel ;
586 		pxlBack	= wgTerm->tterminal.m_pxlFore ;
587 	} else {
588 		pxlFore	= wgTerm->tterminal.m_pxlFore ;
589 		pxlBack	= wgTerm->core.background_pixel ;
590 	}
591 
592 #if defined (DEBUG_LV99)
593 	fprintf (stderr, "%d\n", wgTerm->tterminal.m_iColumn) ;
594 #endif
595 	pText				= TVarbuffer_GetBuffer (&wgTerm->tterminal.m_vbReqText) ;
596 	pText				= pText + pLineInfo->m_nIndex + wgTerm->tterminal.m_iColumn ;
597 	if (wgTerm->tterminal.m_iColumn < pLineInfo->m_nLength) {
598 		/*	length ��������ѹ����Ƥ��롣��������������ѹ���������Ǥ�
599 		 *	��ü���ޤ��֤����֤��Ѥ���ǽ��������ġ�*/
600 		pText->m_char		= cc ;
601 		pText->m_pxlFore	= pxlFore ;
602 		pText->m_pxlBack	= pxlBack ;
603 		wgTerm->tterminal.m_iColumn	++ ;
604 		return	True ;
605 	}
606 	if (wgTerm->tterminal.m_iColumn < pLineInfo->m_nSize) {
607 		/*	�Хåե���­��Ƥ���Τǡ�length ���� +1 ���롣*/
608 		pText->m_char		= cc ;
609 		pText->m_pxlFore	= pxlFore ;
610 		pText->m_pxlBack	= pxlBack ;
611 		pLineInfo->m_nLength	++ ;
612 		wgTerm->tterminal.m_iColumn	++ ;
613 		return	True ;
614 	}
615 
616 	/*
617 	 *	�Хåե����ĥ���ʤ���Фʤ�ʤ��ʤä����ν�����
618 	 */
619 	if (pLineInfo->m_nNext < 0) {
620 		if (TFAILED (TVarbuffer_Require (&wgTerm->tterminal.m_vbReqText, TTERM_NCHAR_PER_MALLOC)))
621 			return	False ;
622 		pLineInfo->m_nSize	+= TTERM_NCHAR_PER_MALLOC ;
623 		pTextTop	= TVarbuffer_GetBuffer (&wgTerm->tterminal.m_vbReqText) ;
624 	} else {
625 		TTermLineInfo*	pTailLineInfo ;
626 		int				nPos ;
627 
628 		nPos		= TVarbuffer_GetUsage (&wgTerm->tterminal.m_vbReqText) ;
629 		if (TFAILED (TVarbuffer_Require (&wgTerm->tterminal.m_vbReqText, pLineInfo->m_nLength + TTERM_NCHAR_PER_MALLOC)))
630 			return	False ;
631 		pTextTop	= TVarbuffer_GetBuffer (&wgTerm->tterminal.m_vbReqText) ;
632 		memcpy (pTextTop + nPos, pTextTop + pLineInfo->m_nIndex, pLineInfo->m_nLength * sizeof (DChar)) ;
633 		/*	Ϣ³�����¤�Ǥ���Ȥ����ݾڤ��ʤ����Ȥ˵��դ����ġ�*/
634 		if (pLineInfo->m_nPrev >= 0) {
635 			TTermLineInfo*	pPrevLineInfo ;
636 			pPrevLineInfo	= pLineInfoTop + pLineInfo->m_nPrev ;
637 			pPrevLineInfo->m_nSize	+= pLineInfo->m_nSize ;
638 			pPrevLineInfo->m_nNext	=  pLineInfo->m_nNext ;
639 		} else {
640 			TTermLineInfo*	pNextLineInfo ;
641 			pNextLineInfo	= pLineInfoTop + pLineInfo->m_nNext ;
642 			pNextLineInfo->m_nSize	+= pLineInfo->m_nSize ;
643 			pNextLineInfo->m_nPrev	= pLineInfo->m_nPrev ;
644 			memmove (pTextTop + pLineInfo->m_nIndex, pTextTop + pNextLineInfo->m_nIndex, pNextLineInfo->m_nLength * sizeof (DChar)) ;
645 			pNextLineInfo->m_nIndex	= pLineInfo->m_nIndex ;
646 		}
647 		pTailLineInfo		= pLineInfoTop + wgTerm->tterminal.m_nReqTailLineIndex ;
648 		assert (pTailLineInfo->m_nNext < 0) ;
649 		pTailLineInfo->m_nNext			= wgTerm->tterminal.m_iRow ;
650 		wgTerm->tterminal.m_nReqTailLineIndex	= wgTerm->tterminal.m_iRow ;
651 
652 		pLineInfo->m_nSize		+= TTERM_NCHAR_PER_MALLOC ;
653 		pLineInfo->m_nIndex		=  nPos ;
654 		pLineInfo->m_nNext		= -1 ;
655 	}
656 	pText				= pTextTop + pLineInfo->m_nIndex + wgTerm->tterminal.m_iColumn ;
657 	pText->m_char		= cc ;
658 	pText->m_pxlFore	= pxlFore ;
659 	pText->m_pxlBack	= pxlBack ;
660 	pLineInfo->m_nLength	++ ;
661 	wgTerm->tterminal.m_iColumn	++ ;
662 	return	True ;
663 }
664