2 Copyright © 1995-2014, The AROS Development Team. All rights reserved.
5 Desc: Code for CONU_STANDARD console units.
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>
19 #include <aros/debug.h>
21 #include "console_gcc.h"
22 #include "consoleif.h"
28 WORD rendercursorcount
;
32 struct Library
*scd_GfxBase
;
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
);
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
);
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
);
85 FreeScreenDrawInfo(CU(o
)->cu_Window
->WScreen
, data
->dri
);
87 /* Let superclass free its allocations */
88 DoSuperMethodA(cl
, o
, msg
);
93 VOID
setabpen(struct Library
*GfxBase
, struct RastPort
*rp
, UBYTE tflags
,
94 UBYTE FgPen
, UBYTE BgPen
)
96 UBYTE fg
= FgPen
, bg
= BgPen
;
99 if (tflags
& CON_TXTFLAGS_CONCEALED
)
101 else if (tflags
& CON_TXTFLAGS_REVERSED
)
103 SetABPenDrMd(rp
, fg
, bg
, style
);
106 static void setstyle(struct Library
*GfxBase
, struct RastPort
*rp
,
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
)
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
);
150 /* Rerender the cursor */
151 Console_RenderCursor(o
);
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];
170 ULONG remaining_space
= CHAR_XMAX(o
) + 1 - XCCP
;
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
);
184 /* Rerender the cursor */
185 Console_RenderCursor(o
);
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
);
204 Console_DoCommand(o
, C_CURSOR_POS
, 2, newcurpos
);
206 Console_RenderCursor(o
);
212 /* !!! maybe trouble with LockLayers() here !!! */
213 // DisplayBeep(CU(o)->cu_Window->WScreen);
217 Console_UnRenderCursor(o
);
219 Console_RenderCursor(o
);
222 case C_CURSOR_BACKWARD
:
223 Console_UnRenderCursor(o
);
224 Console_Left(o
, params
[0]);
225 Console_RenderCursor(o
);
228 case C_CURSOR_FORWARD
:
229 Console_UnRenderCursor(o
);
230 Console_Right(o
, params
[0]);
231 Console_RenderCursor(o
);
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
);
243 GFX_Y(o
, YCP
), GFX_XMAX(o
), GFX_Y(o
, YCP
+ 1));
245 Console_RenderCursor(o
);
248 Console_RenderCursor(o
);
253 WORD x
= XCCP
, i
= 0;
255 while ((CU(o
)->cu_TabStops
[i
] != (UWORD
) - 1) &&
256 (CU(o
)->cu_TabStops
[i
] <= x
))
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
);
277 Console_DoCommand(o
, C_HTAB
, 0, &dummy
);
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
))
303 if (CU(o
)->cu_TabStops
[i
] != (UWORD
) - 1)
305 Console_Left(o
, x
- CU(o
)->cu_TabStops
[i
]);
311 Console_RenderCursor(o
);
317 D(bug("Got linefeed command\n"));
318 /*Console_ClearCell(o, XCCP, YCCP); */
319 Console_UnRenderCursor(o
);
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
);
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
);
341 Console_RenderCursor(o
);
346 Console_UnRenderCursor(o
);
348 Console_RenderCursor(o
);
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
);
356 Console_RenderCursor(o
);
360 Console_UnRenderCursor(o
);
362 Console_RenderCursor(o
);
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
);
379 D(bug("Got NEXT LINE cmd\n"));
381 Console_Left(o
, XCP
);
390 WORD y
= ((WORD
) params
[0]) - 1;
391 WORD x
= ((WORD
) params
[1]) - 1;
393 if (x
< CHAR_XMIN(o
))
397 else if (x
> CHAR_XMAX(o
))
402 if (y
< CHAR_YMIN(o
))
406 else if (y
> CHAR_YMAX(o
))
411 Console_UnRenderCursor(o
);
416 Console_RenderCursor(o
);
420 case C_ERASE_IN_LINE
:
422 /*UBYTE param = 1; */
423 UBYTE oldpen
= rp
->FgPen
;
425 Console_UnRenderCursor(o
);
429 SetAPen(rp
, CU(o
)->cu_BgPen
);
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);
439 Console_RenderCursor(o
);
444 case C_ERASE_IN_DISPLAY
:
447 UBYTE oldpen
= rp
->FgPen
;
450 Console_DoCommand(o
, C_ERASE_IN_LINE
, 1, ¶m
);
452 /* Clear rest of area */
454 Console_UnRenderCursor(o
);
456 SetAPen(rp
, CU(o
)->cu_BgPen
);
459 RectFill(rp
, CU(o
)->cu_XROrigin
,
460 CU(o
)->cu_YROrigin
+ (YCP
+ 1) * YRSIZE
, CU(o
)->cu_XRExtant
,
465 Console_RenderCursor(o
);
472 UBYTE oldpen
= rp
->FgPen
;
473 Console_UnRenderCursor(o
);
474 SetAPen(rp
, CU(o
)->cu_BgPen
);
479 GFX_Y(o
, YCP
), GFX_XMAX(o
), GFX_Y(o
, YCP
+ 1));
481 Console_RenderCursor(o
);
487 UBYTE oldpen
= rp
->FgPen
;
489 Console_UnRenderCursor(o
);
490 SetAPen(rp
, CU(o
)->cu_BgPen
);
495 GFX_XMIN(o
), GFX_Y(o
, YCP
), GFX_XMAX(o
), GFX_YMAX(o
));
499 Console_RenderCursor(o
);
505 UBYTE oldpen
= rp
->FgPen
;
507 Console_UnRenderCursor(o
);
508 SetAPen(rp
, CU(o
)->cu_BgPen
);
513 GFX_XMIN(o
), GFX_Y(o
, YCP
), GFX_XMAX(o
), GFX_YMAX(o
));
517 Console_RenderCursor(o
);
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
));
537 Console_RenderCursor(o
);
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
));
558 Console_RenderCursor(o
);
563 case C_CURSOR_VISIBLE
:
564 if (!data
->cursorvisible
)
566 data
->cursorvisible
= TRUE
;
567 data
->rendercursorcount
--;
568 Console_RenderCursor(o
);
572 case C_CURSOR_INVISIBLE
:
573 if (data
->cursorvisible
)
575 Console_UnRenderCursor(o
);
576 data
->cursorvisible
= FALSE
;
577 data
->rendercursorcount
++;
581 case C_SET_TOP_OFFSET
:
582 Console_UnRenderCursor(o
);
583 CU(o
)->cu_YROrigin
= params
[0];
585 (w
->Height
- (CU(o
)->cu_YROrigin
+
586 w
->BorderBottom
)) / CU(o
)->cu_YRSize
- 1;
587 Console_RenderCursor(o
);
588 Console_NewWindowSize(o
);
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
596 Console_RenderCursor(o
);
597 Console_NewWindowSize(o
);
600 case C_WINDOW_STATUS_REQUEST
:
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
,
610 case C_DEVICE_STATUS_REPORT
:
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
,
621 DoSuperMethodA(cl
, o
, (Msg
) msg
);
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);
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);
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
]);
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
);
702 DoSuperMethodA(cl
, o
, (Msg
) msg
);
704 if (CHAR_XMAX(o
) < old_xmax
)
706 x1
= GFX_XMAX(o
) + 1;
709 y2
= GFX_YMAX(o
) - 1;
711 if ((x2
>= x1
) && (y2
>= y1
))
714 SetDrMd(rp
, JAM2
), RectFill(rp
, x1
, y1
, x2
, y2
);
718 if (CHAR_YMAX(o
) < old_ymax
)
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
))
728 SetDrMd(rp
, JAM2
), RectFill(rp
, x1
, y1
, x2
, y2
);
732 if ((old_xcp
!= XCP
) || (old_ycp
!= YCP
))
736 RectFill(rp
, GFX_XMIN(o
), GFX_YMIN(o
), GFX_XMAX(o
), GFX_YMAX(o
));
737 data
->rendercursorcount
--;
738 Console_RenderCursor(o
);
745 AROS_UFH3S(IPTR
, dispatch_stdconclass
,
746 AROS_UFHA(Class
*, cl
, A0
),
747 AROS_UFHA(Object
*, o
, A2
), AROS_UFHA(Msg
, msg
, A1
))
753 switch (msg
->MethodID
)
756 retval
= (IPTR
) stdcon_new(cl
, o
, (struct opSet
*)msg
);
760 stdcon_dispose(cl
, o
, msg
);
763 case M_Console_DoCommand
:
764 stdcon_docommand(cl
, o
, (struct P_Console_DoCommand
*)msg
);
767 case M_Console_RenderCursor
:
768 stdcon_rendercursor(cl
, o
, (struct P_Console_RenderCursor
*)msg
);
771 case M_Console_UnRenderCursor
:
772 stdcon_unrendercursor(cl
, o
,
773 (struct P_Console_UnRenderCursor
*)msg
);
776 case M_Console_ClearCell
:
777 stdcon_clearcell(cl
, o
, (struct P_Console_ClearCell
*)msg
);
780 case M_Console_NewWindowSize
:
781 stdcon_newwindowsize(cl
, o
, (struct P_Console_NewWindowSize
*)msg
);
785 retval
= DoSuperMethodA(cl
, o
, msg
);
796 Class
*makeStdConClass(struct ConsoleBase
*ConsoleDevice
)
800 cl
= MakeClass(NULL
, NULL
, CONSOLECLASSPTR
, sizeof(struct stdcondata
),
804 cl
->cl_Dispatcher
.h_Entry
= (APTR
) dispatch_stdconclass
;
805 cl
->cl_Dispatcher
.h_SubEntry
= NULL
;
807 cl
->cl_UserData
= (IPTR
) ConsoleDevice
;