1 /* con32s - emulates Windows console.
2 Copyright (C) 1997, 1998 Free Software Foundation, Inc.
3 Written by Ben Pfaff <blp@gnu.org>.
5 This program is free software; you can redistribute it and/or
6 modify it under the terms of the GNU General Public License as
7 published by the Free Software Foundation; either version 2 of the
8 License, or (at your option) any later version.
10 This program is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
28 typedef struct line_struct line;
31 line *next, *prev; /* next and previous lines */
32 char *text; /* text */
33 int len; /* number of characters in text */
34 int size; /* maximum allocated size for text */
37 /* Pointer to tail end of text lines. */
40 /* Console window created. */
41 static int inited = 0;
43 /* Console window title. */
44 static const char *title = _("Con32s Console Emulator by Ben Pfaff");
46 /* Important variables. */
55 /* Width, height of a single character in the console font. */
58 /* Width, height of console window in characters. */
61 /* Keyboard buffer. */
62 #define MAX_KBD_BUF 80 /* Maximum number of characters to buffer. */
63 char kbd[MAX_KBD_BUF];
64 char *hp, *tp; /* Keyboard buffer head, tail. */
67 outmsg (char *format,...)
72 va_start (args, format);
73 vsprintf (s, format, args);
75 MessageBox (_hInstance, s, "Con32s",
76 MB_OK | MB_ICONHAND | MB_SYSTEMMODAL);
88 MessageBox (NULL, _("xmalloc(): out of memory"), NULL, MB_OK);
95 xrealloc (void *ptr, size_t size)
105 vp = realloc (ptr, size);
110 MessageBox (NULL, _("xrealloc(): out of memory"), NULL, MB_OK);
116 void _blp_console_init (void);
117 void _blp_console_yield (void);
118 void _blp_console_paint (void);
119 void find_console_top (line ** top);
120 void find_console_bottom (int *x, int *y, line ** bottom);
142 tail = xmalloc (sizeof (line));
143 tail->next = tail->prev = NULL;
145 tail->len = tail->size = 0;
152 tail->next = xmalloc (sizeof (line));
153 tail->next->prev = tail;
157 tail->len = tail->size = 0;
164 find_console_bottom (&x, &y, &bottom);
179 SelectObject (dc, GetStockObject (ANSI_FIXED_FONT));
182 TextOut (dc, x * cw, y * ch, " ", 1);
189 if (tail->len + 1 > tail->size)
192 tail->text = xrealloc (tail->text, tail->size);
195 find_console_bottom (&x, &y, &bottom);
196 tail->text[tail->len++] = c;
202 SelectObject (dc, GetStockObject (ANSI_FIXED_FONT));
205 TextOut (dc, x * cw, y * ch, &tail->text[tail->len - 1], 1);
211 InvalidateRect (wnd, NULL, TRUE);
214 /* Writes LEN bytes from BUF to the fake console window. */
216 _blp_console_write (const void *buf, unsigned len)
221 _blp_console_init ();
222 for (i = 0; i < len; i++)
223 writechar (((char *) buf)[i]);
228 /* Reads one character from the fake console window. A whole line
229 is read at once, then spoon-fed to the runtime library. */
234 _blp_console_read (const void *t1, unsigned t2)
236 static char buf[1024];
245 _blp_console_init ();
248 *(char *) t1 = buf[n];
255 while (GetMessage ((LPMSG) & msg, NULL, 0, 0))
257 TranslateMessage ((LPMSG) & msg);
258 DispatchMessage ((LPMSG) & msg);
262 c = *(unsigned char *) tp;
263 if (++tp >= &kbd[MAX_KBD_BUF])
265 if ((c >= 32 && c < 128) || c == '\b' || c == '\r')
281 *(char *) t1 = buf[n];
295 LRESULT CALLBACK _export _blp_console_wndproc (HWND, UINT, WPARAM, LPARAM);
298 _blp_console_init (void)
305 wc.style = CS_HREDRAW | CS_VREDRAW;
306 wc.lpfnWndProc = _blp_console_wndproc;
309 wc.hInstance = (HINSTANCE) _hInstance;
310 wc.hIcon = LoadIcon (NULL, IDI_APPLICATION);
311 wc.hCursor = LoadCursor (NULL, IDC_ARROW);
312 wc.hbrBackground = CreateSolidBrush (RGB (255, 255, 255));
313 wc.lpszMenuName = NULL;
314 wc.lpszClassName = "blp_console";
315 if (!RegisterClass (&wc))
317 MessageBox ((HWND) 0, _("RegisterClass(): returned 0."),
318 "_blp_console_init()", MB_APPLMODAL | MB_OK);
322 wnd = CreateWindow ("blp_console", title, WS_OVERLAPPEDWINDOW,
323 CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
324 CW_USEDEFAULT, NULL, (HMENU) 0, (HINSTANCE) _hInstance,
328 MessageBox ((HWND) 0, _("CreateWindow(): returned 0."),
329 "_blp_console_init()", MB_APPLMODAL | MB_OK);
333 ShowWindow (wnd, _nCmdShow);
338 LRESULT CALLBACK _export
339 _blp_console_wndproc (HWND hwnd, UINT msg, WPARAM wp, LPARAM lp)
347 HDC dc = GetDC (hwnd);
351 SelectObject (dc, GetStockObject (ANSI_FIXED_FONT));
352 success = GetTextMetrics (dc, &tm);
354 cw = tm.tmMaxCharWidth;
356 success = ReleaseDC (hwnd, dc);
361 _blp_console_paint ();
365 if (hp + 1 != tp && (hp != &kbd[MAX_KBD_BUF - 1] || tp != kbd))
368 if (hp >= &kbd[MAX_KBD_BUF])
374 return DefWindowProc (hwnd, msg, wp, lp);
378 find_console_top (line ** top)
391 /* Client rectangle. */
394 success = GetClientRect (wnd, &r);
403 /* Find the beginning of the text to display. */
404 for (lc = 0, iter = tail; iter; iter = iter->prev)
409 lc += (iter->len / nw) + (iter->len % nw > 0);
410 if (lc >= nh || !iter->prev)
416 temp.text += nw * (lc - nh);
417 temp.len -= nw * (lc - nh);
425 find_console_bottom (int *x, int *y, line ** bottom)
427 find_console_top (bottom);
433 if ((*bottom)->len == 0)
436 (*y) += ((*bottom)->len / nw) + ((*bottom)->len % nw > 0);
437 if (!(*bottom)->next)
439 *bottom = (*bottom)->next;
441 *x = (*bottom)->len % nw;
446 _blp_console_paint (void)
451 /* Current screen location. */
457 dc = BeginPaint (wnd, &ps);
460 find_console_top (&iter);
462 /* Display the text. */
463 SelectObject (dc, GetStockObject (ANSI_FIXED_FONT));
464 SetTextColor (dc, RGB (0, 0, 0));
465 for (y = 0; iter; iter = iter->next)
472 for (x = 0; x < iter->len; x += nw)
474 TextOut (dc, 0, y, &iter->text[x],
475 iter->len - x > nw ? nw : iter->len - x);
483 int main (int argc, char *argv[], char *env[]);
489 WinMain (HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int nCmdShow)
494 char *pgmname = "PSPP";
499 _nCmdShow = nCmdShow;
501 result = main (1, &pgmname, NULL);