some fixes to accented characters
[tangerine.git] / rom / devs / console / stdconclass.c
blob014b6cf88c6dc7007052135b1bbaec165b93f1f0
1 /*
2 Copyright © 1995-2001, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc: Code for CONU_STANDARD console units.
6 Lang: english
7 */
8 #include <string.h>
10 #include <proto/graphics.h>
11 #include <proto/intuition.h>
12 #include <intuition/intuition.h>
13 #include <graphics/rastport.h>
14 #include <aros/asmcall.h>
16 #define SDEBUG 0
17 #define DEBUG 0
18 #include <aros/debug.h>
20 #include "console_gcc.h"
21 #include "consoleif.h"
24 struct stdcondata
26 struct DrawInfo *dri;
27 WORD rendercursorcount;
28 BOOL cursorvisible;
32 #undef ConsoleDevice
33 #define ConsoleDevice ((struct ConsoleBase *)cl->cl_UserData)
37 /*********** StdCon::New() **********************/
39 static Object *stdcon_new(Class *cl, Object *o, struct opSet *msg)
41 EnterFunc(bug("StdCon::New()\n"));
42 o = (Object *)DoSuperMethodA(cl, o, (Msg)msg);
43 if (o)
45 struct stdcondata *data = INST_DATA(cl, o);
46 ULONG dispmid = OM_DISPOSE;
47 /* Clear for checking inside dispose() whether stuff was allocated.
48 Basically this is bug-prevention.
50 memset(data, 0, sizeof (struct stdcondata));
52 data->dri = GetScreenDrawInfo(CU(o)->cu_Window->WScreen);
53 if (data->dri)
55 CU(o)->cu_BgPen = data->dri->dri_Pens[BACKGROUNDPEN];
56 CU(o)->cu_FgPen = data->dri->dri_Pens[TEXTPEN];
58 data->cursorvisible = TRUE;
59 Console_RenderCursor(o);
61 ReturnPtr("StdCon::New", Object *, o);
63 CoerceMethodA(cl, o, (Msg)&dispmid);
65 ReturnPtr("StdCon::New", Object *, NULL);
69 /*********** StdCon::Dispose() **************************/
71 static VOID stdcon_dispose(Class *cl, Object *o, Msg msg)
73 struct stdcondata *data= INST_DATA(cl, o);
74 if (data->dri)
75 FreeScreenDrawInfo(CU(o)->cu_Window->WScreen, data->dri);
77 /* Let superclass free its allocations */
78 DoSuperMethodA(cl, o, msg);
80 return;
83 /********* StdCon::DoCommand() ****************************/
85 static VOID stdcon_docommand(Class *cl, Object *o, struct P_Console_DoCommand *msg)
89 struct Window *w = CU(o)->cu_Window;
90 struct RastPort *rp = w->RPort;
91 IPTR *params = msg->Params;
92 struct stdcondata *data = INST_DATA(cl, o);
94 EnterFunc(bug("StdCon::DoCommand(o=%p, cmd=%d, params=%p)\n",
95 o, msg->Command, params));
97 switch (msg->Command)
99 case C_ASCII:
101 D(bug("Writing char %c at (%d, %d)\n",
102 params[0], CP_X(o), CP_Y(o) + rp->Font->tf_Baseline));
104 Console_UnRenderCursor(o);
106 SetAPen(rp, CU(o)->cu_FgPen);
107 SetBPen(rp, CU(o)->cu_BgPen);
108 SetDrMd(rp, JAM2);
109 Move(rp, CP_X(o), CP_Y(o) + rp->Font->tf_Baseline);
111 UBYTE c = params[0];
112 Text(rp, &c, 1);
115 Console_Right(o, 1);
117 /* Rerender the cursor */
118 Console_RenderCursor(o);
120 break;
122 case C_ASCII_STRING:
124 D(bug("Writing string %.*s at (%d, %d)\n",
125 (int)params[1], (char *)params[0], CP_X(o), CP_Y(o) + rp->Font->tf_Baseline));
127 Console_UnRenderCursor(o);
129 SetAPen(rp, CU(o)->cu_FgPen);
130 SetBPen(rp, CU(o)->cu_BgPen);
131 SetDrMd(rp, JAM2);
134 ULONG len = params[1];
135 STRPTR str = (STRPTR)params[0];
137 while (len)
139 ULONG remaining_space = CHAR_XMAX(o)+1-XCCP;
140 ULONG line_len = len < remaining_space ? len : remaining_space;
142 Move(rp, CP_X(o), CP_Y(o) + rp->Font->tf_Baseline);
143 Text(rp, str, line_len);
145 Console_Right(o, line_len);
147 len -= line_len;
148 str += line_len;
152 /* Rerender the cursor */
153 Console_RenderCursor(o);
155 break;
156 case C_FORMFEED:
158 /* Clear the console */
160 UBYTE oldpen = rp->FgPen;
161 IPTR newcurpos[2] = {0,0};
163 Console_UnRenderCursor(o);
165 SetAPen( rp, CU(o)->cu_BgPen );
166 RectFill(rp
167 ,CU(o)->cu_XROrigin
168 ,CU(o)->cu_YROrigin
169 ,CU(o)->cu_XRExtant
170 ,CU(o)->cu_YRExtant);
172 SetAPen(rp, oldpen);
174 Console_DoCommand(o, C_CURSOR_POS, 2, newcurpos);
176 Console_RenderCursor(o);
178 break;
181 case C_BELL:
182 /* !!! maybe trouble with LockLayers() here !!! */
183 // DisplayBeep(CU(o)->cu_Window->WScreen);
184 break;
186 case C_BACKSPACE:
187 Console_UnRenderCursor(o);
188 Console_Left(o, 1);
189 Console_RenderCursor(o);
190 break;
192 case C_CURSOR_BACKWARD:
193 Console_UnRenderCursor(o);
194 Console_Left(o, params[0]);
195 Console_RenderCursor(o);
196 break;
198 case C_CURSOR_FORWARD:
199 Console_UnRenderCursor(o);
200 Console_Right(o, params[0]);
201 Console_RenderCursor(o);
202 break;
204 case C_DELETE_CHAR: /* FIXME: can it have params!? */
205 Console_UnRenderCursor(o);
206 Console_ClearCell(o, XCCP, YCCP);
207 Console_RenderCursor(o);
208 break;
210 case C_HTAB:
212 WORD x = XCCP, i = 0;
214 while( (CU(o)->cu_TabStops[i] != (UWORD)-1) &&
215 (CU(o)->cu_TabStops[i] <= x) )
217 i++;
219 if (CU(o)->cu_TabStops[i] != (UWORD)-1)
221 Console_UnRenderCursor(o);
222 Console_Right(o, CU(o)->cu_TabStops[i] - x);
223 Console_RenderCursor(o);
225 break;
228 case C_CURSOR_HTAB:
230 WORD i = params[0];
234 IPTR dummy;
236 Console_DoCommand(o, C_HTAB, 0, &dummy);
238 } while (--i > 0);
239 break;
242 case C_CURSOR_BACKTAB:
244 WORD count = params[0];
246 Console_UnRenderCursor(o);
250 WORD x = XCCP, i = 0;
252 while( (CU(o)->cu_TabStops[i] != (UWORD)-1) &&
253 (CU(o)->cu_TabStops[i] < x) )
255 i++;
258 i--;
260 if (i >= 0) if (CU(o)->cu_TabStops[i] != (UWORD)-1)
262 Console_Left(o, x - CU(o)->cu_TabStops[i]);
265 } while (--count > 0);
267 Console_RenderCursor(o);
269 break;
272 case C_LINEFEED:
273 D(bug("Got linefeed command\n"));
274 /*Console_ClearCell(o, XCCP, YCCP);*/
275 Console_UnRenderCursor(o);
277 Console_Down(o, 1);
279 /* Check for linefeed mode (LF or LF+CR) */
281 D(bug("conflags: %d\n", ICU(o)->conFlags));
283 /* if (ICU(o)->conFlags & CF_LF_MODE_ON) */
284 if (CHECK_MODE(o, M_LNM))
286 CU(o)->cu_XCP = CHAR_XMIN(o);
287 CU(o)->cu_XCCP = CHAR_XMIN(o);
289 Console_RenderCursor(o);
290 break;
293 case C_VTAB:
294 Console_Up(o, 1);
295 break;
297 case C_CARRIAGE_RETURN:
298 /* Goto start of line */
300 Console_UnRenderCursor(o);
301 CU(o)->cu_XCP = CHAR_XMIN(o);
302 CU(o)->cu_XCCP = CHAR_XMIN(o);
303 Console_RenderCursor(o);
304 break;
307 case C_INDEX:
308 Console_Down(o, 1);
309 break;
311 case C_NEXT_LINE:
312 D(bug("Got NEXT LINE cmd\n"));
313 Console_Down(o, 1);
314 Console_Left(o, XCP);
315 break;
317 case C_REVERSE_IDX:
318 Console_Up(o, 1);
319 break;
321 case C_CURSOR_POS:
323 WORD y = ((WORD)params[0]) - 1;
324 WORD x = ((WORD)params[1]) - 1;
326 if (x < CHAR_XMIN(o))
328 x = CHAR_XMIN(o);
330 else if (x > CHAR_XMAX(o))
332 x = CHAR_XMAX(o);
335 if (y < CHAR_YMIN(o))
337 y = CHAR_YMIN(o);
339 else if (y > CHAR_YMAX(o))
341 y = CHAR_YMAX(o);
344 Console_UnRenderCursor(o);
346 XCCP = XCP = x;
347 YCCP = YCP = y;
349 Console_RenderCursor(o);
350 break;
353 case C_ERASE_IN_LINE:
355 /*UBYTE param = 1;*/
356 UBYTE oldpen = rp->FgPen;
358 Console_UnRenderCursor(o);
360 /* Clear till EOL */
362 SetAPen( rp, CU(o)->cu_BgPen );
363 SetDrMd( rp, JAM2);
365 RectFill(rp
366 ,CU(o)->cu_XROrigin + XCP * XRSIZE
367 ,CU(o)->cu_YROrigin + YCP * YRSIZE
368 ,CU(o)->cu_XRExtant
369 ,CU(o)->cu_YROrigin + (YCP + 1) * YRSIZE - 1);
372 SetAPen(rp, oldpen);
374 Console_RenderCursor(o);
376 } break;
378 case C_ERASE_IN_DISPLAY:
380 IPTR param = 1;
381 UBYTE oldpen = rp->FgPen;
383 /* Clear till EOL */
384 Console_DoCommand(o, C_ERASE_IN_LINE, 1, &param);
386 /* Clear rest of area */
388 Console_UnRenderCursor(o);
390 SetAPen( rp, CU(o)->cu_BgPen );
391 SetDrMd( rp, JAM2);
393 RectFill(rp
394 ,CU(o)->cu_XROrigin
395 ,CU(o)->cu_YROrigin + (YCP + 1) * YRSIZE
396 ,CU(o)->cu_XRExtant
397 ,CU(o)->cu_YRExtant);
399 SetAPen(rp, oldpen);
401 Console_RenderCursor(o);
403 break;
406 case C_INSERT_LINE:
408 UBYTE oldpen = rp->FgPen;
410 Console_UnRenderCursor(o);
411 SetAPen(rp, CU(o)->cu_BgPen);
413 ScrollRaster(rp,
415 -YRSIZE,
416 GFX_XMIN(o),
417 GFX_Y(o, YCP),
418 GFX_XMAX(o),
419 GFX_YMAX(o));
421 SetAPen(rp, oldpen);
423 Console_RenderCursor(o);
424 break;
427 case C_DELETE_LINE:
429 UBYTE oldpen = rp->FgPen;
431 Console_UnRenderCursor(o);
432 SetAPen(rp, CU(o)->cu_BgPen);
434 ScrollRaster(rp,
436 YRSIZE,
437 GFX_XMIN(o),
438 GFX_Y(o, YCP),
439 GFX_XMAX(o),
440 GFX_YMAX(o));
442 SetAPen(rp, oldpen);
444 Console_RenderCursor(o);
445 break;
448 case C_SCROLL_UP:
450 UBYTE oldpen = rp->FgPen;
452 D(bug("C_SCROLL_UP area (%d, %d) to (%d, %d), %d\n",
453 GFX_XMIN(o), GFX_YMIN(o), GFX_XMAX(o), GFX_YMAX(o), YRSIZE * params[0]));
455 Console_UnRenderCursor(o);
457 SetAPen( rp, CU(o)->cu_BgPen );
458 #warning LockLayers problem here ?
459 ScrollRaster(rp
461 , YRSIZE * params[0]
462 , GFX_XMIN(o)
463 , GFX_YMIN(o)
464 , GFX_XMAX(o)
465 , GFX_YMAX(o) );
466 SetAPen(rp, oldpen);
468 Console_RenderCursor(o);
470 break;
473 case C_SCROLL_DOWN:
475 UBYTE oldpen = rp->FgPen;
477 D(bug("C_SCROLL_DOWN area (%d, %d) to (%d, %d), %d\n",
478 GFX_XMIN(o), GFX_YMIN(o), GFX_XMAX(o), GFX_YMAX(o), YRSIZE * params[0]));
480 Console_UnRenderCursor(o);
482 SetAPen( rp, CU(o)->cu_BgPen );
483 #warning LockLayers problem here ?
484 ScrollRaster(rp
486 , -YRSIZE * params[0]
487 , GFX_XMIN(o)
488 , GFX_YMIN(o)
489 , GFX_XMAX(o)
490 , GFX_YMAX(o) );
491 SetAPen(rp, oldpen);
493 Console_RenderCursor(o);
495 break;
498 case C_CURSOR_VISIBLE:
499 if (!data->cursorvisible)
501 data->cursorvisible = TRUE;
502 data->rendercursorcount--;
503 Console_RenderCursor(o);
505 break;
507 case C_CURSOR_INVISIBLE:
508 if (data->cursorvisible)
510 Console_UnRenderCursor(o);
511 data->cursorvisible = FALSE;
512 data->rendercursorcount++;
514 break;
516 /* case C_:
517 break;
519 case C_:
520 break;
522 case C_:
523 break;
525 case C_:
526 break;
528 default:
529 DoSuperMethodA(cl, o, (Msg)msg);
530 break;
533 ReturnVoid("StdCon::DoCommand");
536 /********* StdCon::RenderCursor() ****************************/
537 static VOID stdcon_rendercursor(Class *cl, Object *o, struct P_Console_RenderCursor *msg)
539 struct RastPort *rp = RASTPORT(o);
540 struct stdcondata *data = INST_DATA(cl, o);
542 /* SetAPen(rp, data->dri->dri_Pens[FILLPEN]); */
544 data->rendercursorcount++;
546 if (data->cursorvisible && (data->rendercursorcount == 1))
548 SetDrMd(rp, COMPLEMENT);
549 RectFill(rp
550 , CP_X(o)
551 , CP_Y(o)
552 , CP_X(o) + XRSIZE - 1
553 , CP_Y(o) + YRSIZE - 1
555 SetDrMd(rp, JAM2);
559 /********* StdCon::UnRenderCursor() ****************************/
560 static VOID stdcon_unrendercursor(Class *cl, Object *o, struct P_Console_UnRenderCursor *msg)
562 struct RastPort *rp = RASTPORT(o);
563 struct stdcondata *data = INST_DATA(cl, o);
565 data->rendercursorcount--;
567 /* SetAPen(rp, data->dri->dri_Pens[FILLPEN]); */
569 if (data->cursorvisible && (data->rendercursorcount == 0))
571 SetDrMd(rp, COMPLEMENT);
572 RectFill(rp
573 , CP_X(o)
574 , CP_Y(o)
575 , CP_X(o) + XRSIZE - 1
576 , CP_Y(o) + YRSIZE - 1
578 SetDrMd(rp, JAM2);
582 /**************************
583 ** StdCon::ClearCell() **
584 **************************/
585 static VOID stdcon_clearcell(Class *cl, Object *o, struct P_Console_ClearCell *msg)
587 struct RastPort *rp = RASTPORT(o);
588 struct stdcondata *data = INST_DATA(cl, o);
590 SetAPen(rp, data->dri->dri_Pens[BACKGROUNDPEN]);
591 SetDrMd(rp, JAM1);
592 RectFill(rp
593 , GFX_X(o, msg->X)
594 , GFX_Y(o, msg->Y)
595 , GFX_X(o, msg->X) + XRSIZE - 1
596 , GFX_Y(o, msg->Y) + YRSIZE - 1
600 /*******************************
601 ** StdCon::NewWindowSize() **
602 *******************************/
603 static VOID stdcon_newwindowsize(Class *cl, Object *o, struct P_Console_NewWindowSize *msg)
605 struct RastPort *rp = RASTPORT(o);
606 struct stdcondata *data = INST_DATA(cl, o);
607 WORD old_xmax = CHAR_XMAX(o);
608 WORD old_ymax = CHAR_YMAX(o);
609 WORD old_xcp = XCP;
610 WORD old_ycp = YCP;
612 WORD x1, y1, x2, y2;
614 DoSuperMethodA(cl, o, (Msg)msg);
616 if (CHAR_XMAX(o) < old_xmax)
618 x1 = GFX_XMAX(o) + 1;
619 y1 = GFX_YMIN(o);
620 x2 = WINDOW(o)->Width - WINDOW(o)->BorderRight - 1;
621 y2 = WINDOW(o)->Height - WINDOW(o)->BorderBottom - 1;
623 if ((x2 >= x1) && (y2 >= y1))
625 SetAPen(rp, 0);
626 SetDrMd(rp, JAM2),
627 RectFill(rp, x1, y1, x2, y2);
631 if (CHAR_YMAX(o) < old_ymax)
633 x1 = GFX_XMIN(o);
634 y1 = GFX_YMAX(o) + 1;
635 x2 = WINDOW(o)->Width - WINDOW(o)->BorderRight - 1;
636 y2 = WINDOW(o)->Height - WINDOW(o)->BorderBottom - 1;
638 if ((x2 >= x1) && (y2 >= y1))
640 SetAPen(rp, 0);
641 SetDrMd(rp, JAM2),
642 RectFill(rp, x1, y1, x2, y2);
646 if ((old_xcp != XCP) || (old_ycp != YCP))
648 #if 0
649 SetAPen(rp, 0);
650 SetDrMd(rp, JAM2);
651 RectFill(rp, GFX_XMIN(o), GFX_YMIN(o), GFX_XMAX(o), GFX_YMAX(o));
652 #endif
654 if (old_ycp != YCP)
656 /* Scroll up one line */
658 SetAPen(rp, 0);
659 SetDrMd(rp, JAM2);
660 ScrollRaster(rp,
661 0, CU(o)->cu_YRSize,
662 GFX_XMIN(o), GFX_YMIN(o), GFX_XMAX(o), GFX_YMAX(o));
664 /* Move cursor to column 0 */
666 XCP = CHAR_XMIN(o);
667 XCCP = CHAR_XMIN(o);
670 data->rendercursorcount--;
671 Console_RenderCursor(o);
673 return;
678 AROS_UFH3S(IPTR, dispatch_stdconclass,
679 AROS_UFHA(Class *, cl, A0),
680 AROS_UFHA(Object *, o, A2),
681 AROS_UFHA(Msg, msg, A1)
684 AROS_USERFUNC_INIT
686 IPTR retval = 0UL;
688 switch (msg->MethodID)
690 case OM_NEW:
691 retval = (IPTR)stdcon_new(cl, o, (struct opSet *)msg);
692 break;
694 case OM_DISPOSE:
695 stdcon_dispose(cl, o, msg);
696 break;
698 case M_Console_DoCommand:
699 stdcon_docommand(cl, o, (struct P_Console_DoCommand *)msg);
700 break;
702 case M_Console_RenderCursor:
703 stdcon_rendercursor(cl, o, (struct P_Console_RenderCursor *)msg);
704 break;
706 case M_Console_UnRenderCursor:
707 stdcon_unrendercursor(cl, o, (struct P_Console_UnRenderCursor *)msg);
708 break;
710 case M_Console_ClearCell:
711 stdcon_clearcell(cl, o, (struct P_Console_ClearCell *)msg);
712 break;
714 case M_Console_NewWindowSize:
715 stdcon_newwindowsize(cl, o, (struct P_Console_NewWindowSize *)msg);
716 break;
718 default:
719 retval = DoSuperMethodA(cl, o, msg);
720 break;
723 return retval;
725 AROS_USERFUNC_EXIT
728 #undef ConsoleDevice
730 Class *makeStdConClass(struct ConsoleBase *ConsoleDevice)
733 Class *cl;
735 cl = MakeClass(NULL, NULL ,CONSOLECLASSPTR , sizeof(struct stdcondata), 0UL);
736 if (cl)
738 cl->cl_Dispatcher.h_Entry = (APTR)dispatch_stdconclass;
739 cl->cl_Dispatcher.h_SubEntry = NULL;
741 cl->cl_UserData = (IPTR)ConsoleDevice;
743 return (cl);
745 return (NULL);