2 Copyright © 1995-2001, 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
) {
56 data
->dri
= GetScreenDrawInfo(CU(o
)->cu_Window
->WScreen
);
59 CU(o
)->cu_BgPen
= data
->dri
->dri_Pens
[BACKGROUNDPEN
];
60 CU(o
)->cu_FgPen
= data
->dri
->dri_Pens
[TEXTPEN
];
62 data
->cursorvisible
= TRUE
;
63 Console_RenderCursor(o
);
65 ReturnPtr("StdCon::New", Object
*, o
);
68 CoerceMethodA(cl
, o
, (Msg
)&dispmid
);
70 ReturnPtr("StdCon::New", Object
*, NULL
);
74 /*********** StdCon::Dispose() **************************/
76 static VOID
stdcon_dispose(Class
*cl
, Object
*o
, Msg msg
)
78 struct stdcondata
*data
= INST_DATA(cl
, o
);
80 if (data
->scd_GfxBase
)
81 CloseLibrary(data
->scd_GfxBase
);
84 FreeScreenDrawInfo(CU(o
)->cu_Window
->WScreen
, data
->dri
);
86 /* Let superclass free its allocations */
87 DoSuperMethodA(cl
, o
, msg
);
92 VOID
setabpen(struct Library
*GfxBase
, struct RastPort
*rp
, UBYTE tflags
, UBYTE FgPen
, UBYTE BgPen
)
94 UBYTE fg
= FgPen
, bg
= BgPen
;
97 if (tflags
& CON_TXTFLAGS_CONCEALED
)
99 else if (tflags
& CON_TXTFLAGS_REVERSED
)
101 SetABPenDrMd(rp
, fg
, bg
, style
);
104 static void setstyle(struct Library
*GfxBase
, struct RastPort
*rp
, Object
*o
)
106 UBYTE tflags
= CU(o
)->cu_TxFlags
;
107 setabpen(GfxBase
, rp
, tflags
, CU(o
)->cu_FgPen
, CU(o
)->cu_BgPen
);
108 SetSoftStyle(rp
, tflags
, CON_TXTFLAGS_MASK
);
111 /********* StdCon::DoCommand() ****************************/
113 static VOID
stdcon_docommand(Class
*cl
, Object
*o
, struct P_Console_DoCommand
*msg
)
116 struct Window
*w
= CU(o
)->cu_Window
;
117 struct RastPort
*rp
= w
->RPort
;
118 IPTR
*params
= msg
->Params
;
119 struct stdcondata
*data
= INST_DATA(cl
, o
);
120 struct Library
*GfxBase
= data
->scd_GfxBase
;
122 EnterFunc(bug("StdCon::DoCommand(o=%p, cmd=%d, params=%p)\n",
123 o
, msg
->Command
, params
));
125 switch (msg
->Command
)
133 D(bug("Writing char %c at (%d, %d)\n",
134 params
[0], CP_X(o
), CP_Y(o
) + rp
->Font
->tf_Baseline
));
136 Console_UnRenderCursor(o
);
138 setstyle(GfxBase
, rp
, o
);
139 Move(rp
,CP_X(o
),CP_Y(o
)+rp
->Font
->tf_Baseline
);
147 /* Rerender the cursor */
148 Console_RenderCursor(o
);
154 D(bug("Writing string %.*s at (%d, %d)\n",
155 (int)params
[1], (char *)params
[0], CP_X(o
), CP_Y(o
) + rp
->Font
->tf_Baseline
));
157 Console_UnRenderCursor(o
);
159 setstyle(GfxBase
, rp
, o
);
162 ULONG len
= params
[1];
163 STRPTR str
= (STRPTR
)params
[0];
167 ULONG remaining_space
= CHAR_XMAX(o
)+1-XCCP
;
168 ULONG line_len
= len
< remaining_space
? len
: remaining_space
;
170 Move(rp
, CP_X(o
), CP_Y(o
) + rp
->Font
->tf_Baseline
);
171 Text(rp
, str
, line_len
);
173 Console_Right(o
, line_len
);
180 /* Rerender the cursor */
181 Console_RenderCursor(o
);
186 /* Clear the console */
188 UBYTE oldpen
= rp
->FgPen
;
189 IPTR newcurpos
[2] = {0,0};
191 Console_UnRenderCursor(o
);
193 SetAPen( rp
, CU(o
)->cu_BgPen
);
198 ,CU(o
)->cu_YRExtant
);
202 Console_DoCommand(o
, C_CURSOR_POS
, 2, newcurpos
);
204 Console_RenderCursor(o
);
210 /* !!! maybe trouble with LockLayers() here !!! */
211 // DisplayBeep(CU(o)->cu_Window->WScreen);
215 Console_UnRenderCursor(o
);
217 Console_RenderCursor(o
);
220 case C_CURSOR_BACKWARD
:
221 Console_UnRenderCursor(o
);
222 Console_Left(o
, params
[0]);
223 Console_RenderCursor(o
);
226 case C_CURSOR_FORWARD
:
227 Console_UnRenderCursor(o
);
228 Console_Right(o
, params
[0]);
229 Console_RenderCursor(o
);
232 case C_DELETE_CHAR
: /* FIXME: can it have params!? */
234 UBYTE oldpen
= rp
->FgPen
;
235 Console_UnRenderCursor(o
);
236 SetAPen(rp
, CU(o
)->cu_BgPen
);
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
);
283 case C_CURSOR_BACKTAB
:
285 WORD count
= params
[0];
287 Console_UnRenderCursor(o
);
291 WORD x
= XCCP
, i
= 0;
293 while( (CU(o
)->cu_TabStops
[i
] != (UWORD
)-1) &&
294 (CU(o
)->cu_TabStops
[i
] < x
) )
301 if (i
>= 0) if (CU(o
)->cu_TabStops
[i
] != (UWORD
)-1)
303 Console_Left(o
, x
- CU(o
)->cu_TabStops
[i
]);
306 } while (--count
> 0);
308 Console_RenderCursor(o
);
314 D(bug("Got linefeed command\n"));
315 /*Console_ClearCell(o, XCCP, YCCP);*/
316 Console_UnRenderCursor(o
);
320 /* Check for linefeed mode (LF or LF+CR) */
322 D(bug("conflags: %d\n", ICU(o
)->conFlags
));
324 /* if (ICU(o)->conFlags & CF_LF_MODE_ON) */
325 if (CHECK_MODE(o
, M_LNM
))
327 CU(o
)->cu_XCP
= CHAR_XMIN(o
);
328 CU(o
)->cu_XCCP
= CHAR_XMIN(o
);
330 Console_RenderCursor(o
);
333 case C_CURSOR_PREV_LINE
:
334 Console_UnRenderCursor(o
);
335 CU(o
)->cu_XCP
= CHAR_XMIN(o
);
336 CU(o
)->cu_XCCP
= CHAR_XMIN(o
);
338 Console_RenderCursor(o
);
343 Console_UnRenderCursor(o
);
345 Console_RenderCursor(o
);
348 case C_CURSOR_NEXT_LINE
:
349 Console_UnRenderCursor(o
);
350 CU(o
)->cu_XCP
= CHAR_XMIN(o
);
351 CU(o
)->cu_XCCP
= CHAR_XMIN(o
);
353 Console_RenderCursor(o
);
357 Console_UnRenderCursor(o
);
359 Console_RenderCursor(o
);
362 case C_CARRIAGE_RETURN
:
363 /* Goto start of line */
365 Console_UnRenderCursor(o
);
366 CU(o
)->cu_XCP
= CHAR_XMIN(o
);
367 CU(o
)->cu_XCCP
= CHAR_XMIN(o
);
368 Console_RenderCursor(o
);
377 D(bug("Got NEXT LINE cmd\n"));
379 Console_Left(o
, XCP
);
388 WORD y
= ((WORD
)params
[0]) - 1;
389 WORD x
= ((WORD
)params
[1]) - 1;
391 if (x
< CHAR_XMIN(o
))
395 else if (x
> CHAR_XMAX(o
))
400 if (y
< CHAR_YMIN(o
))
404 else if (y
> CHAR_YMAX(o
))
409 Console_UnRenderCursor(o
);
414 Console_RenderCursor(o
);
418 case C_ERASE_IN_LINE
:
421 UBYTE oldpen
= rp
->FgPen
;
423 Console_UnRenderCursor(o
);
427 SetAPen( rp
, CU(o
)->cu_BgPen
);
431 ,CU(o
)->cu_XROrigin
+ XCP
* XRSIZE
432 ,CU(o
)->cu_YROrigin
+ YCP
* YRSIZE
434 ,CU(o
)->cu_YROrigin
+ (YCP
+ 1) * YRSIZE
- 1);
439 Console_RenderCursor(o
);
443 case C_ERASE_IN_DISPLAY
:
446 UBYTE oldpen
= rp
->FgPen
;
449 Console_DoCommand(o
, C_ERASE_IN_LINE
, 1, ¶m
);
451 /* Clear rest of area */
453 Console_UnRenderCursor(o
);
455 SetAPen( rp
, CU(o
)->cu_BgPen
);
460 ,CU(o
)->cu_YROrigin
+ (YCP
+ 1) * YRSIZE
462 ,CU(o
)->cu_YRExtant
);
466 Console_RenderCursor(o
);
473 UBYTE oldpen
= rp
->FgPen
;
474 Console_UnRenderCursor(o
);
475 SetAPen(rp
, CU(o
)->cu_BgPen
);
484 Console_RenderCursor(o
);
489 UBYTE oldpen
= rp
->FgPen
;
491 Console_UnRenderCursor(o
);
492 SetAPen(rp
, CU(o
)->cu_BgPen
);
504 Console_RenderCursor(o
);
510 UBYTE oldpen
= rp
->FgPen
;
512 Console_UnRenderCursor(o
);
513 SetAPen(rp
, CU(o
)->cu_BgPen
);
525 Console_RenderCursor(o
);
531 UBYTE oldpen
= rp
->FgPen
;
533 D(bug("C_SCROLL_UP area (%d, %d) to (%d, %d), %d\n",
534 GFX_XMIN(o
), GFX_YMIN(o
), GFX_XMAX(o
), GFX_YMAX(o
), YRSIZE
* params
[0]));
536 Console_UnRenderCursor(o
);
538 SetAPen( rp
, CU(o
)->cu_BgPen
);
539 /* FIXME: LockLayers problem here ? */
549 Console_RenderCursor(o
);
556 UBYTE oldpen
= rp
->FgPen
;
558 D(bug("C_SCROLL_DOWN area (%d, %d) to (%d, %d), %d\n",
559 GFX_XMIN(o
), GFX_YMIN(o
), GFX_XMAX(o
), GFX_YMAX(o
), YRSIZE
* params
[0]));
561 Console_UnRenderCursor(o
);
563 SetAPen( rp
, CU(o
)->cu_BgPen
);
564 /* FIXME: LockLayers problem here ? */
567 , -YRSIZE
* params
[0]
574 Console_RenderCursor(o
);
579 case C_CURSOR_VISIBLE
:
580 if (!data
->cursorvisible
)
582 data
->cursorvisible
= TRUE
;
583 data
->rendercursorcount
--;
584 Console_RenderCursor(o
);
588 case C_CURSOR_INVISIBLE
:
589 if (data
->cursorvisible
)
591 Console_UnRenderCursor(o
);
592 data
->cursorvisible
= FALSE
;
593 data
->rendercursorcount
++;
597 case C_SET_TOP_OFFSET
:
598 Console_UnRenderCursor(o
);
599 CU(o
)->cu_YROrigin
= params
[0];
600 CU(o
)->cu_YMax
= (w
->Height
- (CU(o
)->cu_YROrigin
+ w
->BorderBottom
)) / CU(o
)->cu_YRSize
- 1;
601 Console_RenderCursor(o
);
602 Console_NewWindowSize(o
);
605 case C_SET_PAGE_LENGTH
:
606 Console_UnRenderCursor(o
);
607 CU(o
)->cu_YMax
= params
[0];
608 // FIXME: Need to set something that prevents NewWindowSize to change YMax
609 Console_RenderCursor(o
);
610 Console_NewWindowSize(o
);
613 case C_WINDOW_STATUS_REQUEST
:
616 NewRawDoFmt("\x9b""1;1;%d;%d r", RAWFMTFUNC_STRING
, reply
, CU(o
)->cu_YMax
, CU(o
)->cu_XMax
);
617 con_inject((struct ConsoleBase
*)cl
->cl_UserData
, CU(o
), reply
, -1);
621 case C_DEVICE_STATUS_REPORT
:
624 NewRawDoFmt("\x9b""%d;%dR", RAWFMTFUNC_STRING
, reply
, CU(o
)->cu_YCP
, CU(o
)->cu_XCP
);
625 con_inject((struct ConsoleBase
*)cl
->cl_UserData
, CU(o
), reply
, -1);
630 DoSuperMethodA(cl
, o
, (Msg
)msg
);
634 ReturnVoid("StdCon::DoCommand");
637 /********* StdCon::RenderCursor() ****************************/
638 static VOID
stdcon_rendercursor(Class
*cl
, Object
*o
, struct P_Console_RenderCursor
*msg
)
640 struct RastPort
*rp
= RASTPORT(o
);
641 struct stdcondata
*data
= INST_DATA(cl
, o
);
642 struct Library
*GfxBase
= data
->scd_GfxBase
;
644 /* SetAPen(rp, data->dri->dri_Pens[FILLPEN]); */
646 data
->rendercursorcount
++;
648 if (data
->cursorvisible
&& (data
->rendercursorcount
== 1))
650 SetDrMd(rp
, COMPLEMENT
);
654 , CP_X(o
) + XRSIZE
- 1
655 , CP_Y(o
) + YRSIZE
- 1
661 /********* StdCon::UnRenderCursor() ****************************/
662 static VOID
stdcon_unrendercursor(Class
*cl
, Object
*o
, struct P_Console_UnRenderCursor
*msg
)
664 struct RastPort
*rp
= RASTPORT(o
);
665 struct stdcondata
*data
= INST_DATA(cl
, o
);
666 struct Library
*GfxBase
= data
->scd_GfxBase
;
668 data
->rendercursorcount
--;
670 /* SetAPen(rp, data->dri->dri_Pens[FILLPEN]); */
672 if (data
->cursorvisible
&& (data
->rendercursorcount
== 0))
674 SetDrMd(rp
, COMPLEMENT
);
678 , CP_X(o
) + XRSIZE
- 1
679 , CP_Y(o
) + YRSIZE
- 1
685 /**************************
686 ** StdCon::ClearCell() **
687 **************************/
688 static VOID
stdcon_clearcell(Class
*cl
, Object
*o
, struct P_Console_ClearCell
*msg
)
690 struct RastPort
*rp
= RASTPORT(o
);
691 struct stdcondata
*data
= INST_DATA(cl
, o
);
692 struct Library
*GfxBase
= data
->scd_GfxBase
;
694 SetAPen(rp
, data
->dri
->dri_Pens
[BACKGROUNDPEN
]);
699 , GFX_X(o
, msg
->X
) + XRSIZE
- 1
700 , GFX_Y(o
, msg
->Y
) + YRSIZE
- 1
704 /*******************************
705 ** StdCon::NewWindowSize() **
706 *******************************/
707 static VOID
stdcon_newwindowsize(Class
*cl
, Object
*o
, struct P_Console_NewWindowSize
*msg
)
709 struct RastPort
*rp
= RASTPORT(o
);
710 struct stdcondata
*data
= INST_DATA(cl
, o
);
711 struct Library
*GfxBase
= data
->scd_GfxBase
;
712 WORD old_xmax
= CHAR_XMAX(o
);
713 WORD old_ymax
= CHAR_YMAX(o
);
719 DoSuperMethodA(cl
, o
, (Msg
)msg
);
721 if (CHAR_XMAX(o
) < old_xmax
)
723 x1
= GFX_XMAX(o
) + 1;
728 if ((x2
>= x1
) && (y2
>= y1
))
732 RectFill(rp
, x1
, y1
, x2
, y2
);
736 if (CHAR_YMAX(o
) < old_ymax
)
739 y1
= GFX_YMAX(o
) + 1;
740 x2
= WINDOW(o
)->Width
- WINDOW(o
)->BorderRight
- 1;
741 y2
= WINDOW(o
)->Height
- WINDOW(o
)->BorderBottom
- 1;
743 if ((x2
>= x1
) && (y2
>= y1
))
747 RectFill(rp
, x1
, y1
, x2
, y2
);
751 if ((old_xcp
!= XCP
) || (old_ycp
!= YCP
))
755 RectFill(rp
, GFX_XMIN(o
), GFX_YMIN(o
), GFX_XMAX(o
), GFX_YMAX(o
));
756 data
->rendercursorcount
--;
757 Console_RenderCursor(o
);
764 AROS_UFH3S(IPTR
, dispatch_stdconclass
,
765 AROS_UFHA(Class
*, cl
, A0
),
766 AROS_UFHA(Object
*, o
, A2
),
767 AROS_UFHA(Msg
, msg
, A1
)
774 switch (msg
->MethodID
)
777 retval
= (IPTR
)stdcon_new(cl
, o
, (struct opSet
*)msg
);
781 stdcon_dispose(cl
, o
, msg
);
784 case M_Console_DoCommand
:
785 stdcon_docommand(cl
, o
, (struct P_Console_DoCommand
*)msg
);
788 case M_Console_RenderCursor
:
789 stdcon_rendercursor(cl
, o
, (struct P_Console_RenderCursor
*)msg
);
792 case M_Console_UnRenderCursor
:
793 stdcon_unrendercursor(cl
, o
, (struct P_Console_UnRenderCursor
*)msg
);
796 case M_Console_ClearCell
:
797 stdcon_clearcell(cl
, o
, (struct P_Console_ClearCell
*)msg
);
800 case M_Console_NewWindowSize
:
801 stdcon_newwindowsize(cl
, o
, (struct P_Console_NewWindowSize
*)msg
);
805 retval
= DoSuperMethodA(cl
, o
, msg
);
816 Class
*makeStdConClass(struct ConsoleBase
*ConsoleDevice
)
821 cl
= MakeClass(NULL
, NULL
,CONSOLECLASSPTR
, sizeof(struct stdcondata
), 0UL);
824 cl
->cl_Dispatcher
.h_Entry
= (APTR
)dispatch_stdconclass
;
825 cl
->cl_Dispatcher
.h_SubEntry
= NULL
;
827 cl
->cl_UserData
= (IPTR
)ConsoleDevice
;