OpenCores
URL https://opencores.org/ocsvn/or1k_old/or1k_old/trunk

Subversion Repositories or1k_old

[/] [or1k_old/] [trunk/] [mw/] [src/] [demos/] [mwin/] [mterm.c] - Blame information for rev 1782

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 673 markom
/*
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
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.