revert between 56095 -> 55830 in arch
[AROS.git] / rom / devs / console / stdconclass.c
blob9f80bb2442006afdd9232db547fb0fb2e2414de5
1 /*
2 Copyright © 1995-2014, 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 <exec/rawfmt.h>
15 #include <aros/asmcall.h>
17 #define SDEBUG 0
18 #define DEBUG 0
19 #include <aros/debug.h>
21 #include "console_gcc.h"
22 #include "consoleif.h"
25 struct stdcondata
27 struct DrawInfo *dri;
28 WORD rendercursorcount;
29 BOOL cursorvisible;
31 /* Libraries */
32 struct Library *scd_GfxBase;
36 #undef ConsoleDevice
37 #define ConsoleDevice ((struct ConsoleBase *)cl->cl_UserData)
39 /*********** StdCon::New() **********************/
41 static Object *stdcon_new(Class *cl, Object *o, struct opSet *msg)
43 EnterFunc(bug("StdCon::New()\n"));
44 o = (Object *) DoSuperMethodA(cl, o, (Msg) msg);
45 if (o)
47 struct stdcondata *data = INST_DATA(cl, o);
48 ULONG dispmid = OM_DISPOSE;
49 /* Clear for checking inside dispose() whether stuff was allocated.
50 Basically this is bug-prevention.
52 memset(data, 0, sizeof(struct stdcondata));
54 data->scd_GfxBase = TaggedOpenLibrary(TAGGEDOPEN_GRAPHICS);
55 if (data->scd_GfxBase)
57 data->dri = GetScreenDrawInfo(CU(o)->cu_Window->WScreen);
58 if (data->dri)
60 CU(o)->cu_BgPen = data->dri->dri_Pens[BACKGROUNDPEN];
61 CU(o)->cu_FgPen = data->dri->dri_Pens[TEXTPEN];
63 data->cursorvisible = TRUE;
64 Console_RenderCursor(o);
66 ReturnPtr("StdCon::New", Object *, o);
69 CoerceMethodA(cl, o, (Msg) &dispmid);
71 ReturnPtr("StdCon::New", Object *, NULL);
75 /*********** StdCon::Dispose() **************************/
77 static VOID stdcon_dispose(Class *cl, Object *o, Msg msg)
79 struct stdcondata *data = INST_DATA(cl, o);
81 if (data->scd_GfxBase)
82 CloseLibrary(data->scd_GfxBase);
84 if (data->dri)
85 FreeScreenDrawInfo(CU(o)->cu_Window->WScreen, data->dri);
87 /* Let superclass free its allocations */
88 DoSuperMethodA(cl, o, msg);
90 return;
93 VOID setabpen(struct Library *GfxBase, struct RastPort *rp, UBYTE tflags,
94 UBYTE FgPen, UBYTE BgPen)
96 UBYTE fg = FgPen, bg = BgPen;
97 UBYTE style = JAM2;
99 if (tflags & CON_TXTFLAGS_CONCEALED)
100 fg = bg;
101 else if (tflags & CON_TXTFLAGS_REVERSED)
102 style |= INVERSVID;
103 SetABPenDrMd(rp, fg, bg, style);
106 static void setstyle(struct Library *GfxBase, struct RastPort *rp,
107 Object *o)
109 UBYTE tflags = CU(o)->cu_TxFlags;
110 setabpen(GfxBase, rp, tflags, CU(o)->cu_FgPen, CU(o)->cu_BgPen);
111 SetSoftStyle(rp, tflags, CON_TXTFLAGS_MASK);
114 /********* StdCon::DoCommand() ****************************/
116 static VOID stdcon_docommand(Class *cl, Object *o,
117 struct P_Console_DoCommand *msg)
119 struct Window *w = CU(o)->cu_Window;
120 struct RastPort *rp = w->RPort;
121 IPTR *params = msg->Params;
122 struct stdcondata *data = INST_DATA(cl, o);
123 struct Library *GfxBase = data->scd_GfxBase;
125 EnterFunc(bug("StdCon::DoCommand(o=%p, cmd=%d, params=%p)\n",
126 o, msg->Command, params));
128 switch (msg->Command)
130 case C_NIL:
131 /* do nothing */
132 break;
134 case C_ASCII:
136 D(bug("Writing char %c at (%d, %d)\n",
137 params[0], CP_X(o), CP_Y(o) + rp->Font->tf_Baseline));
139 Console_UnRenderCursor(o);
141 setstyle(GfxBase, rp, o);
142 Move(rp, CP_X(o), CP_Y(o) + rp->Font->tf_Baseline);
144 UBYTE c = params[0];
145 Text(rp, &c, 1);
148 Console_Right(o, 1);
150 /* Rerender the cursor */
151 Console_RenderCursor(o);
153 break;
155 case C_ASCII_STRING:
156 D(bug("Writing string %.*s at (%d, %d)\n",
157 (int)params[1], (char *)params[0], CP_X(o),
158 CP_Y(o) + rp->Font->tf_Baseline));
160 Console_UnRenderCursor(o);
162 setstyle(GfxBase, rp, o);
165 ULONG len = params[1];
166 STRPTR str = (STRPTR) params[0];
168 while (len)
170 ULONG remaining_space = CHAR_XMAX(o) + 1 - XCCP;
171 ULONG line_len =
172 len < remaining_space ? len : remaining_space;
174 Move(rp, CP_X(o), CP_Y(o) + rp->Font->tf_Baseline);
175 Text(rp, str, line_len);
177 Console_Right(o, line_len);
179 len -= line_len;
180 str += line_len;
184 /* Rerender the cursor */
185 Console_RenderCursor(o);
187 break;
189 case C_FORMFEED:
191 /* Clear the console */
193 UBYTE oldpen = rp->FgPen;
194 IPTR newcurpos[2] = { 0, 0 };
196 Console_UnRenderCursor(o);
198 SetAPen(rp, CU(o)->cu_BgPen);
199 RectFill(rp, CU(o)->cu_XROrigin, CU(o)->cu_YROrigin,
200 CU(o)->cu_XRExtant, CU(o)->cu_YRExtant);
202 SetAPen(rp, oldpen);
204 Console_DoCommand(o, C_CURSOR_POS, 2, newcurpos);
206 Console_RenderCursor(o);
208 break;
211 case C_BELL:
212 /* !!! maybe trouble with LockLayers() here !!! */
213 // DisplayBeep(CU(o)->cu_Window->WScreen);
214 break;
216 case C_BACKSPACE:
217 Console_UnRenderCursor(o);
218 Console_Left(o, 1);
219 Console_RenderCursor(o);
220 break;
222 case C_CURSOR_BACKWARD:
223 Console_UnRenderCursor(o);
224 Console_Left(o, params[0]);
225 Console_RenderCursor(o);
226 break;
228 case C_CURSOR_FORWARD:
229 Console_UnRenderCursor(o);
230 Console_Right(o, params[0]);
231 Console_RenderCursor(o);
232 break;
234 case C_DELETE_CHAR: /* FIXME: can it have params!? */
236 UBYTE oldpen = rp->FgPen;
237 Console_UnRenderCursor(o);
238 SetAPen(rp, CU(o)->cu_BgPen);
239 ScrollRaster(rp,
240 XRSIZE,
242 GFX_X(o, XCP),
243 GFX_Y(o, YCP), GFX_XMAX(o), GFX_Y(o, YCP + 1));
244 SetAPen(rp, oldpen);
245 Console_RenderCursor(o);
247 break;
248 Console_RenderCursor(o);
249 break;
251 case C_HTAB:
253 WORD x = XCCP, i = 0;
255 while ((CU(o)->cu_TabStops[i] != (UWORD) - 1) &&
256 (CU(o)->cu_TabStops[i] <= x))
258 i++;
260 if (CU(o)->cu_TabStops[i] != (UWORD) - 1)
262 Console_UnRenderCursor(o);
263 Console_Right(o, CU(o)->cu_TabStops[i] - x);
264 Console_RenderCursor(o);
266 break;
269 case C_CURSOR_HTAB:
271 WORD i = params[0];
275 IPTR dummy;
277 Console_DoCommand(o, C_HTAB, 0, &dummy);
280 while (--i > 0);
281 break;
284 case C_CURSOR_BACKTAB:
286 WORD count = params[0];
288 Console_UnRenderCursor(o);
292 WORD x = XCCP, i = 0;
294 while ((CU(o)->cu_TabStops[i] != (UWORD) - 1) &&
295 (CU(o)->cu_TabStops[i] < x))
297 i++;
300 i--;
302 if (i >= 0)
303 if (CU(o)->cu_TabStops[i] != (UWORD) - 1)
305 Console_Left(o, x - CU(o)->cu_TabStops[i]);
309 while (--count > 0);
311 Console_RenderCursor(o);
313 break;
316 case C_LINEFEED:
317 D(bug("Got linefeed command\n"));
318 /*Console_ClearCell(o, XCCP, YCCP); */
319 Console_UnRenderCursor(o);
321 Console_Down(o, 1);
323 /* Check for linefeed mode (LF or LF+CR) */
325 D(bug("conflags: %d\n", ICU(o)->conFlags));
327 /* if (ICU(o)->conFlags & CF_LF_MODE_ON) */
328 if (CHECK_MODE(o, M_LNM))
330 CU(o)->cu_XCP = CHAR_XMIN(o);
331 CU(o)->cu_XCCP = CHAR_XMIN(o);
333 Console_RenderCursor(o);
334 break;
336 case C_CURSOR_PREV_LINE:
337 Console_UnRenderCursor(o);
338 CU(o)->cu_XCP = CHAR_XMIN(o);
339 CU(o)->cu_XCCP = CHAR_XMIN(o);
340 Console_Up(o, 1);
341 Console_RenderCursor(o);
342 break;
344 case C_CURSOR_UP:
345 case C_VTAB:
346 Console_UnRenderCursor(o);
347 Console_Up(o, 1);
348 Console_RenderCursor(o);
349 break;
351 case C_CURSOR_NEXT_LINE:
352 Console_UnRenderCursor(o);
353 CU(o)->cu_XCP = CHAR_XMIN(o);
354 CU(o)->cu_XCCP = CHAR_XMIN(o);
355 Console_Down(o, 1);
356 Console_RenderCursor(o);
357 break;
359 case C_CURSOR_DOWN:
360 Console_UnRenderCursor(o);
361 Console_Down(o, 1);
362 Console_RenderCursor(o);
363 break;
365 case C_CARRIAGE_RETURN:
366 /* Goto start of line */
368 Console_UnRenderCursor(o);
369 CU(o)->cu_XCP = CHAR_XMIN(o);
370 CU(o)->cu_XCCP = CHAR_XMIN(o);
371 Console_RenderCursor(o);
372 break;
374 case C_INDEX:
375 Console_Down(o, 1);
376 break;
378 case C_NEXT_LINE:
379 D(bug("Got NEXT LINE cmd\n"));
380 Console_Down(o, 1);
381 Console_Left(o, XCP);
382 break;
384 case C_REVERSE_IDX:
385 Console_Up(o, 1);
386 break;
388 case C_CURSOR_POS:
390 WORD y = ((WORD) params[0]) - 1;
391 WORD x = ((WORD) params[1]) - 1;
393 if (x < CHAR_XMIN(o))
395 x = CHAR_XMIN(o);
397 else if (x > CHAR_XMAX(o))
399 x = CHAR_XMAX(o);
402 if (y < CHAR_YMIN(o))
404 y = CHAR_YMIN(o);
406 else if (y > CHAR_YMAX(o))
408 y = CHAR_YMAX(o);
411 Console_UnRenderCursor(o);
413 XCCP = XCP = x;
414 YCCP = YCP = y;
416 Console_RenderCursor(o);
417 break;
420 case C_ERASE_IN_LINE:
422 /*UBYTE param = 1; */
423 UBYTE oldpen = rp->FgPen;
425 Console_UnRenderCursor(o);
427 /* Clear till EOL */
429 SetAPen(rp, CU(o)->cu_BgPen);
430 SetDrMd(rp, JAM2);
432 RectFill(rp, CU(o)->cu_XROrigin + XCP * XRSIZE,
433 CU(o)->cu_YROrigin + YCP * YRSIZE, CU(o)->cu_XRExtant,
434 CU(o)->cu_YROrigin + (YCP + 1) * YRSIZE - 1);
437 SetAPen(rp, oldpen);
439 Console_RenderCursor(o);
442 break;
444 case C_ERASE_IN_DISPLAY:
446 IPTR param = 1;
447 UBYTE oldpen = rp->FgPen;
449 /* Clear till EOL */
450 Console_DoCommand(o, C_ERASE_IN_LINE, 1, &param);
452 /* Clear rest of area */
454 Console_UnRenderCursor(o);
456 SetAPen(rp, CU(o)->cu_BgPen);
457 SetDrMd(rp, JAM2);
459 RectFill(rp, CU(o)->cu_XROrigin,
460 CU(o)->cu_YROrigin + (YCP + 1) * YRSIZE, CU(o)->cu_XRExtant,
461 CU(o)->cu_YRExtant);
463 SetAPen(rp, oldpen);
465 Console_RenderCursor(o);
467 break;
470 case C_INSERT_CHAR:
472 UBYTE oldpen = rp->FgPen;
473 Console_UnRenderCursor(o);
474 SetAPen(rp, CU(o)->cu_BgPen);
475 ScrollRaster(rp,
476 -XRSIZE,
478 GFX_X(o, XCP),
479 GFX_Y(o, YCP), GFX_XMAX(o), GFX_Y(o, YCP + 1));
480 SetAPen(rp, oldpen);
481 Console_RenderCursor(o);
483 break;
485 case C_INSERT_LINE:
487 UBYTE oldpen = rp->FgPen;
489 Console_UnRenderCursor(o);
490 SetAPen(rp, CU(o)->cu_BgPen);
492 ScrollRaster(rp,
494 -YRSIZE,
495 GFX_XMIN(o), GFX_Y(o, YCP), GFX_XMAX(o), GFX_YMAX(o));
497 SetAPen(rp, oldpen);
499 Console_RenderCursor(o);
500 break;
503 case C_DELETE_LINE:
505 UBYTE oldpen = rp->FgPen;
507 Console_UnRenderCursor(o);
508 SetAPen(rp, CU(o)->cu_BgPen);
510 ScrollRaster(rp,
512 YRSIZE,
513 GFX_XMIN(o), GFX_Y(o, YCP), GFX_XMAX(o), GFX_YMAX(o));
515 SetAPen(rp, oldpen);
517 Console_RenderCursor(o);
518 break;
521 case C_SCROLL_UP:
523 UBYTE oldpen = rp->FgPen;
525 D(bug("C_SCROLL_UP area (%d, %d) to (%d, %d), %d\n",
526 GFX_XMIN(o), GFX_YMIN(o), GFX_XMAX(o), GFX_YMAX(o),
527 YRSIZE * params[0]));
529 Console_UnRenderCursor(o);
531 SetAPen(rp, CU(o)->cu_BgPen);
532 /* FIXME: LockLayers problem here ? */
533 ScrollRaster(rp, 0, YRSIZE * params[0], GFX_XMIN(o),
534 GFX_YMIN(o), GFX_XMAX(o), GFX_YMAX(o));
535 SetAPen(rp, oldpen);
537 Console_RenderCursor(o);
539 break;
542 case C_SCROLL_DOWN:
544 UBYTE oldpen = rp->FgPen;
546 D(bug("C_SCROLL_DOWN area (%d, %d) to (%d, %d), %d\n",
547 GFX_XMIN(o), GFX_YMIN(o), GFX_XMAX(o), GFX_YMAX(o),
548 YRSIZE * params[0]));
550 Console_UnRenderCursor(o);
552 SetAPen(rp, CU(o)->cu_BgPen);
553 /* FIXME: LockLayers problem here? */
554 ScrollRaster(rp, 0, -YRSIZE * params[0], GFX_XMIN(o),
555 GFX_YMIN(o), GFX_XMAX(o), GFX_YMAX(o));
556 SetAPen(rp, oldpen);
558 Console_RenderCursor(o);
560 break;
563 case C_CURSOR_VISIBLE:
564 if (!data->cursorvisible)
566 data->cursorvisible = TRUE;
567 data->rendercursorcount--;
568 Console_RenderCursor(o);
570 break;
572 case C_CURSOR_INVISIBLE:
573 if (data->cursorvisible)
575 Console_UnRenderCursor(o);
576 data->cursorvisible = FALSE;
577 data->rendercursorcount++;
579 break;
581 case C_SET_TOP_OFFSET:
582 Console_UnRenderCursor(o);
583 CU(o)->cu_YROrigin = params[0];
584 CU(o)->cu_YMax =
585 (w->Height - (CU(o)->cu_YROrigin +
586 w->BorderBottom)) / CU(o)->cu_YRSize - 1;
587 Console_RenderCursor(o);
588 Console_NewWindowSize(o);
589 break;
591 case C_SET_PAGE_LENGTH:
592 Console_UnRenderCursor(o);
593 CU(o)->cu_YMax = params[0];
594 // FIXME: Need to set something that prevents NewWindowSize to
595 // change YMax
596 Console_RenderCursor(o);
597 Console_NewWindowSize(o);
598 break;
600 case C_WINDOW_STATUS_REQUEST:
602 UBYTE reply[32];
603 NewRawDoFmt("\x9b" "1;1;%d;%d r", RAWFMTFUNC_STRING, reply,
604 CU(o)->cu_YMax, CU(o)->cu_XMax);
605 con_inject((struct ConsoleBase *)cl->cl_UserData, CU(o), reply,
606 -1);
607 break;
610 case C_DEVICE_STATUS_REPORT:
612 UBYTE reply[32];
613 NewRawDoFmt("\x9b" "%d;%dR", RAWFMTFUNC_STRING, reply,
614 CU(o)->cu_YCP, CU(o)->cu_XCP);
615 con_inject((struct ConsoleBase *)cl->cl_UserData, CU(o), reply,
616 -1);
617 break;
620 default:
621 DoSuperMethodA(cl, o, (Msg) msg);
622 break;
625 ReturnVoid("StdCon::DoCommand");
628 /********* StdCon::RenderCursor() ****************************/
629 static VOID stdcon_rendercursor(Class *cl, Object *o,
630 struct P_Console_RenderCursor *msg)
632 struct RastPort *rp = RASTPORT(o);
633 struct stdcondata *data = INST_DATA(cl, o);
634 struct Library *GfxBase = data->scd_GfxBase;
636 /* SetAPen(rp, data->dri->dri_Pens[FILLPEN]); */
638 data->rendercursorcount++;
640 if (data->cursorvisible && (data->rendercursorcount == 1))
642 SetDrMd(rp, COMPLEMENT);
643 RectFill(rp, CP_X(o), CP_Y(o), CP_X(o) + XRSIZE - 1,
644 CP_Y(o) + YRSIZE - 1);
645 SetDrMd(rp, JAM2);
649 /********* StdCon::UnRenderCursor() ****************************/
650 static VOID stdcon_unrendercursor(Class *cl, Object *o,
651 struct P_Console_UnRenderCursor *msg)
653 struct RastPort *rp = RASTPORT(o);
654 struct stdcondata *data = INST_DATA(cl, o);
655 struct Library *GfxBase = data->scd_GfxBase;
657 data->rendercursorcount--;
659 /* SetAPen(rp, data->dri->dri_Pens[FILLPEN]); */
661 if (data->cursorvisible && (data->rendercursorcount == 0))
663 SetDrMd(rp, COMPLEMENT);
664 RectFill(rp, CP_X(o), CP_Y(o), CP_X(o) + XRSIZE - 1,
665 CP_Y(o) + YRSIZE - 1);
666 SetDrMd(rp, JAM2);
670 /**************************
671 ** StdCon::ClearCell() **
672 **************************/
673 static VOID stdcon_clearcell(Class *cl, Object *o,
674 struct P_Console_ClearCell *msg)
676 struct RastPort *rp = RASTPORT(o);
677 struct stdcondata *data = INST_DATA(cl, o);
678 struct Library *GfxBase = data->scd_GfxBase;
680 SetAPen(rp, data->dri->dri_Pens[BACKGROUNDPEN]);
681 SetDrMd(rp, JAM1);
682 RectFill(rp, GFX_X(o, msg->X), GFX_Y(o, msg->Y), GFX_X(o,
683 msg->X) + XRSIZE - 1, GFX_Y(o, msg->Y) + YRSIZE - 1);
686 /*******************************
687 ** StdCon::NewWindowSize() **
688 *******************************/
689 static VOID stdcon_newwindowsize(Class *cl, Object *o,
690 struct P_Console_NewWindowSize *msg)
692 struct RastPort *rp = RASTPORT(o);
693 struct stdcondata *data = INST_DATA(cl, o);
694 struct Library *GfxBase = data->scd_GfxBase;
695 WORD old_xmax = CHAR_XMAX(o);
696 WORD old_ymax = CHAR_YMAX(o);
697 WORD old_xcp = XCP;
698 WORD old_ycp = YCP;
700 WORD x1, y1, x2, y2;
702 DoSuperMethodA(cl, o, (Msg) msg);
704 if (CHAR_XMAX(o) < old_xmax)
706 x1 = GFX_XMAX(o) + 1;
707 y1 = GFX_YMIN(o);
708 x2 = GFX_XMAX(o);
709 y2 = GFX_YMAX(o) - 1;
711 if ((x2 >= x1) && (y2 >= y1))
713 SetAPen(rp, 0);
714 SetDrMd(rp, JAM2), RectFill(rp, x1, y1, x2, y2);
718 if (CHAR_YMAX(o) < old_ymax)
720 x1 = GFX_XMIN(o);
721 y1 = GFX_YMAX(o) + 1;
722 x2 = WINDOW(o)->Width - WINDOW(o)->BorderRight - 1;
723 y2 = WINDOW(o)->Height - WINDOW(o)->BorderBottom - 1;
725 if ((x2 >= x1) && (y2 >= y1))
727 SetAPen(rp, 0);
728 SetDrMd(rp, JAM2), RectFill(rp, x1, y1, x2, y2);
732 if ((old_xcp != XCP) || (old_ycp != YCP))
734 SetAPen(rp, 0);
735 SetDrMd(rp, JAM2);
736 RectFill(rp, GFX_XMIN(o), GFX_YMIN(o), GFX_XMAX(o), GFX_YMAX(o));
737 data->rendercursorcount--;
738 Console_RenderCursor(o);
740 return;
745 AROS_UFH3S(IPTR, dispatch_stdconclass,
746 AROS_UFHA(Class *, cl, A0),
747 AROS_UFHA(Object *, o, A2), AROS_UFHA(Msg, msg, A1))
749 AROS_USERFUNC_INIT
751 IPTR retval = 0UL;
753 switch (msg->MethodID)
755 case OM_NEW:
756 retval = (IPTR) stdcon_new(cl, o, (struct opSet *)msg);
757 break;
759 case OM_DISPOSE:
760 stdcon_dispose(cl, o, msg);
761 break;
763 case M_Console_DoCommand:
764 stdcon_docommand(cl, o, (struct P_Console_DoCommand *)msg);
765 break;
767 case M_Console_RenderCursor:
768 stdcon_rendercursor(cl, o, (struct P_Console_RenderCursor *)msg);
769 break;
771 case M_Console_UnRenderCursor:
772 stdcon_unrendercursor(cl, o,
773 (struct P_Console_UnRenderCursor *)msg);
774 break;
776 case M_Console_ClearCell:
777 stdcon_clearcell(cl, o, (struct P_Console_ClearCell *)msg);
778 break;
780 case M_Console_NewWindowSize:
781 stdcon_newwindowsize(cl, o, (struct P_Console_NewWindowSize *)msg);
782 break;
784 default:
785 retval = DoSuperMethodA(cl, o, msg);
786 break;
789 return retval;
791 AROS_USERFUNC_EXIT
794 #undef ConsoleDevice
796 Class *makeStdConClass(struct ConsoleBase *ConsoleDevice)
798 Class *cl;
800 cl = MakeClass(NULL, NULL, CONSOLECLASSPTR, sizeof(struct stdcondata),
801 0UL);
802 if (cl)
804 cl->cl_Dispatcher.h_Entry = (APTR) dispatch_stdconclass;
805 cl->cl_Dispatcher.h_SubEntry = NULL;
807 cl->cl_UserData = (IPTR) ConsoleDevice;
809 return (cl);
811 return NULL;