]> git.karo-electronics.de Git - karo-tx-redboot.git/blob - packages/services/gfx/mw/v2_0/src/demos/mwin/mterm.c
Initial revision
[karo-tx-redboot.git] / packages / services / gfx / mw / v2_0 / src / demos / mwin / mterm.c
1 /*
2  * Copyright (c) 1999 Greg Haerr <greg@censoft.com>
3  *
4  * Microwindows Terminal Emulator for Linux
5  *
6  * Yes, this is just a demo, and doesn't repaint contents on refresh.
7  */
8
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include <fcntl.h>
12 #include <unistd.h>
13 #include <errno.h>
14 #include <signal.h>
15 #define MWINCLUDECOLORS
16 #include "windows.h"
17 #include "wintern.h"            /* for MwRegisterFdInput*/
18 #include "wintools.h"           /* Draw3dInset*/
19
20 #define COLS            80
21 #define ROWS            24
22 #define XMARGIN         2
23 #define YMARGIN         2
24 #define FGCOLOR         GREEN
25 #define BKCOLOR         BLACK
26 #define FONTNAME        SYSTEM_FIXED_FONT
27 /*#define FONTNAME      OEM_FIXED_FONT*/
28 #define APPCLASS        "mterm"
29
30 #if DOS_DJGPP
31 #define killpg          kill
32 #define SIGCHLD         17 /* from Linux, not defined in DJGPP */
33 #endif
34
35 /* forward decls*/
36 LRESULT CALLBACK WndProc(HWND hwnd,UINT uMsg,WPARAM wp,LPARAM lp);
37 void EmOutChar(HWND hwnd, int ch);
38 int  CreatePtyShell(void);
39 int  ReadPtyShell(int fd, char *buf, int count);
40 int  WritePtyShell(int fd, char *buf, int count);
41 void ClosePtyShell(int fd);
42
43 /* local data*/
44 static int ttyfd = -1;
45 static int xpos = XMARGIN;
46 static int ypos = YMARGIN;
47 static int nCharWidth, nCharHeight;
48 static int nScreenWidth, nScreenHeight;
49
50 int
51 RegisterAppClass(void)
52 {
53         WNDCLASS        wc;
54
55         wc.style = CS_DBLCLKS | CS_VREDRAW | CS_HREDRAW;
56         wc.lpfnWndProc = (WNDPROC)WndProc;
57         wc.cbClsExtra = 0;
58         wc.cbWndExtra = 0;
59         wc.hInstance = 0;
60         wc.hIcon = 0; /*LoadIcon(GetHInstance(), MAKEINTRESOURCE( 1));*/
61         wc.hCursor = 0; /*LoadCursor(NULL, IDC_ARROW);*/
62         wc.hbrBackground = CreateSolidBrush(BKCOLOR);
63         wc.lpszMenuName = NULL;
64         wc.lpszClassName =  APPCLASS;
65         RegisterClass( &wc);
66         return 1;
67 }
68
69 HWND
70 CreateAppWindow(void)
71 {
72         HWND    hwnd;
73         HDC     hdc;
74         int     w, h;
75         RECT    rc;
76
77         GetWindowRect(GetDesktopWindow(), &rc);
78         w = rc.right - 40;
79         h = rc.bottom;
80
81         /* determine TE size from font*/
82         hdc = GetDC(NULL);
83         SelectObject(hdc, GetStockObject(FONTNAME));
84         SetRect(&rc, 0, 0, 0, 0);
85         nCharHeight = DrawText(hdc, "m", 1, &rc, DT_CALCRECT);
86         nCharWidth = rc.right;
87         nScreenWidth = min(w, nCharWidth*COLS);
88         nScreenHeight = min(h, nCharHeight*ROWS);
89         ReleaseDC(NULL, hdc);
90
91         hwnd = CreateWindowEx(0L, APPCLASS,
92                 "Microwindows Terminal",
93                 WS_OVERLAPPEDWINDOW | WS_VISIBLE,
94                 CW_USEDEFAULT, CW_USEDEFAULT,
95                 nScreenWidth+4, nScreenHeight+24,
96                 NULL, (HMENU)1, NULL, NULL);
97
98         return hwnd;
99 }
100
101 LRESULT CALLBACK
102 WndProc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp)
103 {
104         unsigned char   ch;
105         HDC             hdc;
106         RECT            rc;
107         PAINTSTRUCT     ps;
108    
109         switch(msg) {
110         case WM_CREATE:
111                 ttyfd = CreatePtyShell();
112                 /*if(ttyfd == -1)
113                         return -1;*/
114                 MwRegisterFdInput(hwnd, ttyfd);
115                 xpos = XMARGIN;
116                 ypos = YMARGIN;
117                 break;
118
119         case WM_DESTROY:
120                 MwUnregisterFdInput(hwnd, ttyfd);
121                 ClosePtyShell(ttyfd);
122                 break;
123
124         case WM_CHAR:
125                 ch = (char)wp;
126                 /* echo half duplex if CreatePtyShell() failed*/
127                 if(ttyfd == -1) {
128                         EmOutChar(hwnd, ch);
129                         if(ch == '\r')
130                                 EmOutChar(hwnd, '\n');
131                 } else
132                         WritePtyShell(ttyfd, &ch, 1);
133                 break;
134
135         case WM_FDINPUT:
136                 if(ReadPtyShell(ttyfd, &ch, 1) == 1)
137                         EmOutChar(hwnd, ch);
138                 break;
139
140         case WM_PAINT:
141                 hdc = BeginPaint(hwnd, &ps);
142                 GetClientRect(hwnd, &rc);
143                 Draw3dInset(hdc, 0, 0, rc.right-rc.left, rc.bottom-rc.top);
144                 EndPaint(hwnd, &ps);
145                 break;
146
147         default:
148                 return DefWindowProc(hwnd, msg, wp, lp);
149         }
150         return 0;
151 }
152
153 int WINAPI 
154 WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine,
155         int nShowCmd)
156 {
157         MSG     msg;
158         extern MWIMAGEHDR image_car8;
159
160         RegisterAppClass();
161         MwSetDesktopWallpaper(&image_car8);
162
163         CreateAppWindow();
164
165         /* type ESC to quit...*/
166         while(GetMessage(&msg, NULL, 0, 0)) {
167                 TranslateMessage(&msg);
168                 DispatchMessage(&msg);
169         }
170         return 0;
171 }
172
173 void
174 EmOutChar(HWND hwnd, int ch)
175 {
176         HDC     hdc;
177         RECT    rc;
178
179         switch(ch) {
180         case '\r':
181                 xpos = XMARGIN;
182                 return;
183         case '\n':
184                 ypos += nCharHeight;
185                 GetClientRect(hwnd, &rc);
186                 if(ypos > (ROWS-1)*nCharHeight + YMARGIN) {
187                         ypos -= nCharHeight;
188
189                         /* scroll window using bitblt ;-)*/
190                         hdc = GetDC(hwnd);
191                         BitBlt(hdc, XMARGIN, YMARGIN, rc.right-XMARGIN*2,
192                                 rc.bottom-nCharHeight-YMARGIN*2,
193                                 hdc, XMARGIN, nCharHeight+YMARGIN, SRCCOPY);
194                         rc.top = ypos;
195                         rc.left += XMARGIN;
196                         rc.right -= XMARGIN;
197                         rc.bottom -= YMARGIN;
198                         FillRect(hdc, &rc,
199                                 (HBRUSH)GetClassLong(hwnd, GCL_HBRBACKGROUND));
200                         ReleaseDC(hwnd, hdc);
201                 }
202                 return;
203         case '\007':                    /* bel*/
204                 write(STDERR_FILENO, "\007", 1);
205                 return;
206         case '\t':
207                 xpos += nCharWidth;
208                 while((xpos/nCharWidth) & 7)
209                         EmOutChar(hwnd, ' ');
210                 return;
211         case '\b':
212                 if(xpos <= XMARGIN)
213                         return;
214                 xpos -= nCharWidth;
215                 EmOutChar(hwnd, ' ');
216                 xpos -= nCharWidth;
217                 return;
218         }
219
220         /* draw some text*/
221         hdc = GetDC(hwnd);
222         SelectObject(hdc, GetStockObject(FONTNAME));
223         SetBkColor(hdc, BKCOLOR);
224         SetTextColor(hdc, FGCOLOR);
225         SetRect(&rc, xpos, ypos, xpos+nCharWidth, ypos+nCharHeight);
226         ExtTextOut(hdc, xpos, ypos, ETO_OPAQUE, &rc, (char *)&ch, 1, NULL);
227         ReleaseDC(hwnd, hdc);
228         xpos += nCharWidth;
229         if(xpos > (COLS-1)*nCharWidth) {
230                 xpos = XMARGIN;
231                 EmOutChar(hwnd, '\n');
232         }
233 }
234
235 #if ELKS
236 #define SHELL   "/bin/sash"
237 #else
238 #if DOS_DJGPP
239 #define SHELL   "bash"
240 #else
241 #define SHELL   "/bin/sh"
242 #endif
243 #endif
244
245 static int pid;
246
247 static void
248 ptysignaled(int signo)
249 {
250         switch(signo) {
251         case SIGINT:    /* interrupt*/
252 #if !ELKS
253                 /* this doesn't work, can anyone fix it?*/
254                 killpg(pid, SIGINT);
255 #endif
256                 return;
257         case SIGCHLD:   /* child status change - child exit*/
258                 DestroyWindow(GetActiveWindow());
259                 CreateAppWindow();
260                 return;
261         }
262         fprintf(stderr, "Uncaught signal %d\n", signo);
263 }
264
265 /*
266  * Create a shell running through a pseudo tty, return the shell fd.
267  */
268 int
269 CreatePtyShell(void)
270 {
271         int     n = 0;
272         int     tfd;
273         char    pty_name[12];
274         char *  argv[2];
275
276 again:
277         sprintf(pty_name, "/dev/ptyp%d", n);
278         if ((tfd = open(pty_name, O_RDWR | O_NONBLOCK)) < 0) {
279                 if ((errno == EBUSY || errno == EIO) && n < 10) {
280                         ++n;
281                         goto again;
282                 }
283                 fprintf(stderr, "Can't create pty %s\n", pty_name);
284                 return -1;
285         }
286         signal(SIGCHLD, ptysignaled);
287         signal(SIGINT, ptysignaled);
288         if ((pid = fork()) == -1) {
289                 fprintf(stderr, "No processes\n");
290                 return -1;
291         }
292         if (!pid) {
293                 close(STDIN_FILENO);
294                 close(STDOUT_FILENO);
295                 close(STDERR_FILENO);
296                 close(tfd);
297                 
298                 setsid();
299                 pty_name[5] = 't';
300                 if ((tfd = open(pty_name, O_RDWR)) < 0) {
301                         fprintf(stderr, "Child: Can't open pty %s\n", pty_name);
302                         exit(1);
303                 }
304                 dup2(tfd, STDIN_FILENO);
305                 dup2(tfd, STDOUT_FILENO);
306                 dup2(tfd, STDERR_FILENO);
307                 /*if(!(argv[0] = getenv("SHELL")))*/
308                         argv[0] = SHELL;
309                 argv[1] = NULL;
310                 execv(argv[0], argv);
311                 exit(1);
312         }
313         return tfd;
314 }
315
316 int
317 ReadPtyShell(int fd, char *buf, int count)
318 {
319         return read(fd, buf, count);
320 }
321
322 int
323 WritePtyShell(int fd, char *buf, int count)
324 {
325         return write(fd, buf, count);
326 }
327
328 void
329 ClosePtyShell(int fd)
330 {
331         if(ttyfd != -1)
332                 close(fd);
333 }