4 * Revision 1.1 2001/04/04 05:43:36 wang
5 * First commit: compiles on Linux, Amiga, Windows, Windows CE, generic gcc
7 * Revision 1.1 1999/09/13 15:06:41 bnv
17 * These are dummy variables that are used because this module is
22 HINSTANCE _hPrevInstance
;
24 POINT _WindowOrg
= { CW_USEDEFAULT
, CW_USEDEFAULT
};
25 POINT _WindowSize
= { CW_USEDEFAULT
, CW_USEDEFAULT
};
27 POINT _ScreenSize
= { 80, 25 }; // Screen buffer dimensions
28 POINT _Cursor
= { 0, 0 }; // Cursor location
29 POINT _Origin
= { 0, 0 }; // Client area origin
30 LPSTR _InactiveTitle
= "(Inactive %s)"; // Inactive window title
31 BOOL _AutoTracking
= TRUE
; // Track cursor on Write?
32 BOOL _CheckEOF
= TRUE
; // Allow Ctrl-Z for EOF?
33 BOOL _CheckBreak
= TRUE
; // Allow Ctrl-C for break?
34 HFONT _hFont
; // Current working font
36 char _WindowTitle
[80]; // Window title
38 void _DoneWinIO(void);
40 BOOL
_KeyPressed(void);
42 WORD
_ReadBuf(char *Buffer
, WORD Count
);
44 void gotoxy(int X
, int Y
);
50 void _CursorTo(int X
, int Y
);
51 void _ScrollTo(int X
, int Y
);
52 void _TrackCursor(void);
54 void _InitWinIO(HINSTANCE
,HINSTANCE
,int);
58 typedef POINT TMinMaxInfo
[5];
60 // Scroll key definition record
70 // Window I/O procedure
72 long PASCAL
_WinIOProc(HWND Window
, UINT Message
,
73 WPARAM WParam
, LONG LParam
);
77 static WNDCLASS CrtClass
=
79 CS_HREDRAW
| CS_VREDRAW
, _WinIOProc
, 0, 0, 0, 0, 0, 0,
83 static int FirstLine
= 0; // First line in circular buffer
84 static int KeyCount
= 0; // Count of keys in KeyBuffer
85 static BOOL Created
= FALSE
; // Window created?
86 static BOOL Focused
= FALSE
; // Window focused?
87 static BOOL Reading
= FALSE
; // Reading from window?
88 static BOOL Painting
= FALSE
; // Handling wm_Paint?
90 static HWND CrtWindow
= 0; // CRT window handle
91 static char *ScreenBuffer
; // Screen buffer pointer
92 static POINT ClientSize
; // Client area dimensions
93 static POINT Range
; // Scroll bar ranges
94 static POINT CharSize
; // Character cell size
95 static int CharAscent
; // Character ascent
96 static HDC DC
; // Global device context
97 static PAINTSTRUCT PS
; // Global paint structure
98 static HFONT SaveFont
; // Saved device context font
99 static char KeyBuffer
[64]; // Keyboard type-ahead buffer
102 #define SCROLLKEYCOUNT 12
103 static TScrollKey ScrollKeys
[SCROLLKEYCOUNT
] =
105 { VK_LEFT
, FALSE
, SB_HORZ
, SB_LINEUP
},
106 { VK_RIGHT
, FALSE
, SB_HORZ
, SB_LINEDOWN
},
107 { VK_LEFT
, TRUE
, SB_HORZ
, SB_PAGEUP
},
108 { VK_RIGHT
, TRUE
, SB_HORZ
, SB_PAGEDOWN
},
109 { VK_HOME
, FALSE
, SB_HORZ
, SB_TOP
},
110 { VK_END
, FALSE
, SB_HORZ
, SB_BOTTOM
},
111 { VK_UP
, FALSE
, SB_VERT
, SB_LINEUP
},
112 { VK_DOWN
, FALSE
, SB_VERT
, SB_LINEDOWN
},
113 { VK_PRIOR
, FALSE
, SB_VERT
, SB_PAGEUP
},
114 { VK_NEXT
, FALSE
, SB_VERT
, SB_PAGEDOWN
},
115 { VK_HOME
, TRUE
, SB_VERT
, SB_TOP
},
116 { VK_END
, TRUE
, SB_VERT
, SB_BOTTOM
}
119 /* ------------ Allocate device context ----------- */
121 InitDeviceContext(void)
124 DC
= BeginPaint(CrtWindow
, &PS
);
126 DC
= GetDC(CrtWindow
);
127 // SaveFont = (HFONT) SelectObject( DC, GetStockObject(SYSTEM_FIXED_FONT));
128 SaveFont
= (HFONT
)SelectObject (DC
, _hFont
);
129 } /* InitDeviceContext */
131 /* ------------ Release device context ------------ */
133 DoneDeviceContext(void)
135 SelectObject(DC
, SaveFont
);
137 EndPaint(CrtWindow
, &PS
);
139 ReleaseDC(CrtWindow
, DC
);
140 } /* DoneDeviceContext */
142 /* ---------- Show caret --------- */
146 CreateCaret(CrtWindow
, 0, CharSize
.x
, 2);
147 SetCaretPos((_Cursor
.x
- _Origin
.x
) * CharSize
.x
,
148 (_Cursor
.y
- _Origin
.y
) * CharSize
.y
+ CharAscent
);
149 ShowCaret(CrtWindow
);
152 /* ----------- Hide caret ------------ */
159 /* ---------- Update scroll bars --------- */
163 SetScrollRange(CrtWindow
, SB_HORZ
, 0, max(1, Range
.x
), FALSE
);
164 SetScrollPos(CrtWindow
, SB_HORZ
, _Origin
.x
, TRUE
);
165 SetScrollRange(CrtWindow
, SB_VERT
, 0, max(1, Range
.y
), FALSE
);
166 SetScrollPos(CrtWindow
, SB_VERT
, _Origin
.y
, TRUE
);
167 } /* SetScrollBars */
169 /* --------- Terminate window ----------- */
173 if (Focused
&& Reading
)
178 /* --------- Set cursor position ---------- */
180 _CursorTo(int X
, int Y
)
182 _Cursor
.x
= max(0, min(X
, _ScreenSize
.x
- 1));
183 _Cursor
.y
= max(0, min(Y
, _ScreenSize
.y
- 1));
186 /* ------- Scroll window to given origin -------- */
188 _ScrollTo(int X
, int Y
)
191 X
= max(0, min(X
, Range
.x
));
192 Y
= max(0, min(Y
, Range
.y
));
193 if ((X
!= _Origin
.x
) || (Y
!= _Origin
.y
)) {
195 SetScrollPos(CrtWindow
, SB_HORZ
, X
, TRUE
);
197 SetScrollPos(CrtWindow
, SB_VERT
, Y
, TRUE
);
198 ScrollWindow(CrtWindow
,
199 (_Origin
.x
- X
) * CharSize
.x
,
200 (_Origin
.y
- Y
) * CharSize
.y
, NULL
, NULL
);
203 UpdateWindow(CrtWindow
);
208 /* ------ Scroll to make cursor visible --------- */
212 _ScrollTo(max(_Cursor
.x
- ClientSize
.x
+ 1,
213 min(_Origin
.x
, _Cursor
.x
)),
214 max(_Cursor
.y
- ClientSize
.y
+ 1,
215 min(_Origin
.y
, _Cursor
.y
)));
218 /* ------ Return pointer to location in screen buffer ----------- */
220 ScreenPtr(int X
, int Y
)
223 if (Y
>= _ScreenSize
.y
)
225 return (ScreenBuffer
+ (Y
* _ScreenSize
.x
+ X
));
228 /* ------ Update text on cursor line -------- */
230 ShowText(int L
, int R
)
234 ExtTextOut(DC
, (L
- _Origin
.x
) * CharSize
.x
,
235 (_Cursor
.y
- _Origin
.y
) * CharSize
.y
,
237 ScreenPtr(L
, _Cursor
.y
), R
- L
);
238 //? TextOut(DC, (L - _Origin.x) * CharSize.x,
239 //? (_Cursor.y - _Origin.y) * CharSize.y,
240 //? ScreenPtr(L, _Cursor.y), R - L);
245 /* ------ Write text buffer to window -------- */
247 NewLine(int *L
, int *R
)
254 if (_Cursor
.y
== _ScreenSize
.y
) {
257 if (FirstLine
== _ScreenSize
.y
)
259 memset(ScreenPtr(0, _Cursor
.y
), ' ', _ScreenSize
.x
);
260 ScrollWindow(CrtWindow
, 0, -CharSize
.y
, NULL
, NULL
);
261 UpdateWindow(CrtWindow
);
265 /* --------- Write the contents of Buffer ----------- */
267 _WriteBuf(char *Buffer
, WORD Count
)
284 *(ScreenPtr(_Cursor
.x
,_Cursor
.y
))=' ';
288 if (_Cursor
.x
== _ScreenSize
.x
) {
292 } while (_Cursor
.x
% 8);
297 *(ScreenPtr(_Cursor
.x
,_Cursor
.y
))=' ';
306 *(ScreenPtr(_Cursor
.x
, _Cursor
.y
)) = Buffer
[0];
310 if (_Cursor
.x
== _ScreenSize
.x
)
322 /* ------- Write character to window ---------- */
329 /* ------ Return keyboard status -------- */
335 while (PeekMessage(&M
, 0, 0, 0, PM_REMOVE
)) {
336 if (M
.message
== WM_QUIT
)
338 TranslateMessage(&M
);
341 return (BOOL
)( KeyCount
> 0 );
344 /* ------- Read key from window ---------- */
351 if (!_KeyPressed()) {
355 do { } while (!_KeyPressed());
360 readkey
= KeyBuffer
[0];
362 memmove(KeyBuffer
, KeyBuffer
+1, KeyCount
);
366 /* ------ Read text buffer from window --------- */
368 _ReadBuf(char *Buffer
, WORD Count
)
388 } while (!((Ch
== 13) || (_CheckEOF
&& (Ch
== 26))));
400 /* -------- Set cursor position ------------- */
404 _CursorTo(X
- 1, Y
- 1);
407 /* ------- Return cursor X position --------- */
411 return (_Cursor
.x
+ 1);
414 /* ------- Return cursor Y position ------- */
418 return(_Cursor
.y
+ 1);
421 /* ------ Clear screen ------ */
425 memset(ScreenBuffer
, ' ', _ScreenSize
.x
* _ScreenSize
.y
);
431 InvalidateRect(CrtWindow
, NULL
, TRUE
);
432 UpdateWindow(CrtWindow
);
435 /* ------ Clear to end of line --------- */
439 memset(ScreenPtr(_Cursor
.x
,_Cursor
.y
),' ',_ScreenSize
.x
-_Cursor
.x
);
440 ShowText(_Cursor
.x
, _ScreenSize
.x
);
443 /* ---- WM_CREATE message handler ---- */
448 ScreenBuffer
= (char *) malloc(_ScreenSize
.x
* _ScreenSize
.y
);
449 memset(ScreenBuffer
, ' ', _ScreenSize
.x
* _ScreenSize
.y
);
451 EnableMenuItem(GetSystemMenu(CrtWindow
, FALSE
), SC_CLOSE
,
452 MF_DISABLED
| MF_GRAYED
);
455 /* ---- WM_PAINT message handler ----- */
463 X1
= max(0, PS
.rcPaint
.left
/ CharSize
.x
+ _Origin
.x
);
464 X2
= min(_ScreenSize
.x
,
465 (PS
.rcPaint
.right
+ CharSize
.x
- 1) / CharSize
.x
+ _Origin
.x
);
466 Y1
= max(0, PS
.rcPaint
.top
/ CharSize
.y
+ _Origin
.y
);
467 Y2
= min(_ScreenSize
.y
,
468 (PS
.rcPaint
.bottom
+ CharSize
.y
- 1) / CharSize
.y
+ _Origin
.y
);
470 TextOut(DC
, (X1
- _Origin
.x
) * CharSize
.x
, (Y1
- _Origin
.y
) * CharSize
.y
,
471 ScreenPtr(X1
, Y1
), X2
- X1
);
478 /* ---- WM_VSCROLL and WM_HSCROLL message handler ----- */
480 GetNewPos(int Pos
, int Page
, int Range
, int Action
, int Thumb
)
495 case SB_THUMBPOSITION
:
502 /* ------ WindowScroll ------- */
504 WindowScroll(int Which
, int Action
, int Thumb
)
512 X
= GetNewPos(X
, ClientSize
.x
/ 2, Range
.x
, Action
, Thumb
);
515 Y
= GetNewPos(Y
, ClientSize
.y
, Range
.y
, Action
, Thumb
);
520 /* ------ WM_SIZE message handler -------- */
522 WindowResize(int X
, int Y
)
524 if (Focused
&& Reading
)
526 ClientSize
.x
= X
/ CharSize
.x
;
527 ClientSize
.y
= Y
/ CharSize
.y
;
528 Range
.x
= max(0, _ScreenSize
.x
- ClientSize
.x
);
529 Range
.y
= max(0, _ScreenSize
.y
- ClientSize
.y
);
530 _Origin
.x
= min(_Origin
.x
, Range
.x
);
531 _Origin
.y
= min(_Origin
.y
, Range
.y
);
533 if (Focused
&& Reading
)
537 /* ------ WM_GETMINMAXINFO message handler ------ */
539 WindowMinMaxInfo(TMinMaxInfo
* MinMaxInfo
)
545 GetTextMetrics(DC
, &Metrics
);
546 CharSize
.x
= Metrics
.tmMaxCharWidth
;
547 CharSize
.y
= Metrics
.tmHeight
+ Metrics
.tmExternalLeading
;
548 CharAscent
= Metrics
.tmAscent
;
549 X
= min(_ScreenSize
.x
* CharSize
.x
+ GetSystemMetrics(SM_CXVSCROLL
),
550 GetSystemMetrics(SM_CXSCREEN
)) + GetSystemMetrics(SM_CXFRAME
) * 2;
551 Y
= min(_ScreenSize
.y
* CharSize
.y
+ GetSystemMetrics(SM_CYHSCROLL
) +
552 GetSystemMetrics(SM_CYCAPTION
), GetSystemMetrics(SM_CYSCREEN
)) +
553 GetSystemMetrics(SM_CYFRAME
) * 2;
554 (*MinMaxInfo
)[1].x
= X
;
555 (*MinMaxInfo
)[1].y
= Y
;
556 (*MinMaxInfo
)[3].x
= CharSize
.x
* 16 + GetSystemMetrics(SM_CXVSCROLL
) +
557 GetSystemMetrics(SM_CXFRAME
) * 2;
558 (*MinMaxInfo
)[3].y
= CharSize
.y
* 4 + GetSystemMetrics(SM_CYHSCROLL
) +
559 GetSystemMetrics(SM_CYFRAME
) * 2 + GetSystemMetrics(SM_CYCAPTION
);
560 (*MinMaxInfo
)[4].x
= X
;
561 (*MinMaxInfo
)[4].y
= Y
;
563 } /* WindowMinMaxInfo */
565 /* ----- WM_CHAR message handler ----- */
569 if (_CheckBreak
&& (Ch
== 3))
571 if (KeyCount
< sizeof(KeyBuffer
)) {
572 KeyBuffer
[KeyCount
] = Ch
;
577 /* ------ WM_KEYDOWN message handler ------ */
579 WindowKeyDown(BYTE KeyDown
)
584 if (_CheckBreak
&& (KeyDown
== VK_CANCEL
))
586 CtrlDown
= (BOOL
) (GetKeyState(VK_CONTROL
< 0));
587 for (I
= 0; I
< SCROLLKEYCOUNT
; ++I
) {
588 if (ScrollKeys
[I
].Key
== KeyDown
&& ScrollKeys
[I
].Ctrl
== CtrlDown
) {
589 WindowScroll(ScrollKeys
[I
].SBar
, ScrollKeys
[I
].Action
, 0);
593 } /* WindowKeyDown */
595 /* ----- WM_SETFOCUS message handler ------ */
602 } /* WindowSetFocus */
604 /* ----- WM_KILLFOCUS message handler ----- */
606 WindowKillFocus(void)
611 } /* WindowKillFocus */
613 /* ----- WM_DESTROY message handler ------ */
624 } /* WindowDestroy */
626 /* --------- LoVal --------- */
630 return (((unsigned *)&LVal
)[0]);
633 /* -------- HiVal ------- */
637 return (((unsigned *)&LVal
)[1]);
640 /* ------ WindowIO window procedure ------ */
643 _WinIOProc(HWND Window
, UINT Message
, WPARAM WParam
, LONG LParam
)
654 WindowScroll(SB_VERT
, WParam
, LoVal(LParam
));
657 WindowScroll(SB_HORZ
, WParam
, LoVal(LParam
));
660 WindowResize(LoVal(LParam
), HiVal(LParam
));
662 case WM_GETMINMAXINFO
:
663 WindowMinMaxInfo((TMinMaxInfo
*) LParam
);
666 WindowChar((char)WParam
);
669 WindowKeyDown((BYTE
)WParam
);
681 return DefWindowProc(Window
, Message
, WParam
, LParam
);
686 /* ------- _CreateWinIO ------- */
690 if (_hPrevInstance
== 0) {
691 CrtClass
.hInstance
= _hInstance
;
692 CrtClass
.hIcon
= LoadIcon(NULL
, IDI_APPLICATION
);
693 CrtClass
.hCursor
= LoadCursor(NULL
, IDC_ARROW
);
694 CrtClass
.hbrBackground
= GetStockObject(WHITE_BRUSH
);
695 RegisterClass(&CrtClass
);
697 GetModuleFileName(_hInstance
, _WindowTitle
, sizeof(_WindowTitle
));
698 OemToAnsi(_WindowTitle
, _WindowTitle
);
701 /* ----- Create window if required ----- */
703 _InitWinIO(HINSTANCE hInst
, HINSTANCE hPrev
, int cmdShow
)
708 _hPrevInstance
= hPrev
;
712 CrtWindow
= CreateWindow(
713 CrtClass
.lpszClassName
,
715 WS_OVERLAPPEDWINDOW
| WS_HSCROLL
| WS_VSCROLL
,
716 _WindowOrg
.x
, _WindowOrg
.y
,
717 _WindowSize
.x
, _WindowSize
.y
,
722 ShowWindow(CrtWindow
, cmdShow
);
723 UpdateWindow(CrtWindow
);
725 // For the first time create the font (WCE)
726 memset ((char *)&lf
, 0, sizeof(lf
));
727 lf
.lfPitchAndFamily
= FIXED_PITCH
| FF_MODERN
;
729 _hFont
= CreateFontIndirect (&lf
);
733 /* ----- Destroy window if required ----- */
738 DestroyWindow(CrtWindow
);
742 /* ------ WinIO unit exit procedure ----- */
752 wsprintf(Title
, _InactiveTitle
, (char *) P
);
753 SetWindowText(CrtWindow
, Title
);
754 GetSystemMenu(CrtWindow
, TRUE
);
756 while (GetMessage(&Message
, 0, 0, 0)) {
757 TranslateMessage(&Message
);
758 DispatchMessage(&Message
);