source: trunk/src/kernel32/console.cpp @ 22049

Last change on this file since 22049 was 22049, checked in by dmik, 8 years ago

kernel32: Make sure that console subsystem initialization properly redirects standard I/O handles.

File size: 131.7 KB
Line 
1/* $Id: console.cpp,v 1.33 2004-02-19 13:03:06 sandervl Exp $ */
2
3/*
4 * Win32 Console API Translation for OS/2
5 *
6 * 1998/02/10 Patrick Haller (haller@zebra.fh-weingarten.de)
7 *
8 * @(#) console.cpp         1.0.0   1998/02/10 PH Start from scratch
9 *
10 * Project Odin Software License can be found in LICENSE.TXT
11 *
12 */
13
14
15#ifdef DEBUG
16#define DEBUG_LOCAL
17#define DEBUG_LOCAL2
18#endif
19
20//#undef DEBUG_LOCAL
21//#undef DEBUG_LOCAL2
22
23
24/*****************************************************************************
25 * Remark                                                                    *
26 *****************************************************************************
27
28 - DWORD HandlerRoutine (DWORD dwCtrlType)
29   basically an exception handler routine. handles a few signals / excpts.
30   should be somewhere near the exception handling code ... :)
31
32   Hmm, however as PM applications don't really get a ctrl-c signal,
33   I'll have to do this on my own ...
34
35 - supply unicode<->ascii conversions for all the _A and _W function pairs.
36
37 - problem: we can't prevent thread1 from blocking the message queue ?
38            what will happen if a WinTerminate() is issued there ?
39            will the message queue be closed and provide smooth tasking ?
40            how will open32 react on this ?
41
42 - ECHO_LINE_INPUT / ReadFile blocks till CR
43
44 - scrollbars
45 * do some flowchart to exactly determine WHEN to use WHICH setting
46   and perform WHAT action
47
48 - clipboard support
49*/
50
51
52/*******************************************************************************
53*   Header Files                                                               *
54*******************************************************************************/
55
56// Vio/Kbd/Mou declarations conflict in GCC and in real OS2TK headers;
57// force GCC declarations since we link against GCC libs
58#if defined (__EMX__) && defined (USE_OS2_TOOLKIT_HEADERS)
59#undef USE_OS2_TOOLKIT_HEADERS
60#endif
61
62#define  INCL_WIN
63#define  INCL_DOSMEMMGR
64#define  INCL_DOSSEMAPHORES
65#define  INCL_DOSERRORS
66#define  INCL_DOSEXCEPTIONS
67#define  INCL_DOSPROCESS
68#define  INCL_DOSMODULEMGR
69#define  INCL_DOSDEVICES
70#define  INCL_VIO
71#define  INCL_KBD
72#define  INCL_AVIO
73#include <os2wrap.h>         //Odin32 OS/2 api wrappers
74
75#include <process.h>
76#include <stdlib.h>
77#include <string.h>
78
79#include <win32type.h>
80#include <win32api.h>
81#include <misc.h>
82#include <odincrt.h>
83
84#include "conwin.h"          // Windows Header for console only
85#include "HandleManager.h"
86#include "handlenames.h"
87#include "HMDevice.h"
88
89#include "console.h"
90#include "console2.h"
91#include "conin.h"
92#include "conout.h"
93#include "conbuffer.h"
94#include "conbuffervio.h"
95
96#include "conprop.h"
97#include "unicode.h"
98#include "heapstring.h"
99
100#define DBG_LOCALLOG    DBG_console
101#include "dbglocal.h"
102
103#include <os2sel.h>
104
105
106/*******************************************************************************
107*   Process Global Structures                                                  *
108*******************************************************************************/
109static ICONSOLEGLOBALS ConsoleGlobals;
110static ICONSOLEINPUT   ConsoleInput;
111BOOL                   flVioConsole = FALSE;
112
113/*******************************************************************************
114*   Internal Functions                                                         *
115*******************************************************************************/
116static void iConsoleInputQueueLock();
117static void iConsoleInputQueueUnlock();
118
119
120/*****************************************************************************
121 * Name      : iConsoleInputQueueLock
122 * Purpose   : lock the input queue to ensure correct event sequence
123 * Parameters:
124 * Variables :
125 * Result    :
126 * Remark    :
127 * Status    :
128 *
129 * Author    : Patrick Haller [Tue, 1998/02/10 01:55]
130 *****************************************************************************/
131
132static void iConsoleInputQueueLock()
133{
134  APIRET rc;
135
136  rc = DosRequestMutexSem(ConsoleInput.hmtxInputQueue,
137                          SEM_INDEFINITE_WAIT);
138  if (rc != NO_ERROR)
139     dprintf(("KERNEL32: Console:iConsoleInputQueueLock error %08xh\n",
140              rc));
141}
142
143
144/*****************************************************************************
145 * Name      : iConsoleInputQueueUnlock
146 * Purpose   : unlock the input queue
147 * Parameters:
148 * Variables :
149 * Result    :
150 * Remark    :
151 * Status    :
152 *
153 * Author    : Patrick Haller [Tue, 1998/02/10 01:55]
154 *****************************************************************************/
155
156static void iConsoleInputQueueUnlock()
157{
158  APIRET rc;
159
160  rc = DosReleaseMutexSem(ConsoleInput.hmtxInputQueue);
161  if (rc != NO_ERROR)
162     dprintf(("KERNEL32: Console:iConsoleInputQueueUnlock error %08xh\n",
163              rc));
164}
165
166
167/*****************************************************************************
168 * Name      :
169 * Purpose   :
170 * Parameters:
171 * Variables :
172 * Result    :
173 * Remark    :
174 * Status    :
175 *
176 * Author    : Patrick Haller [Tue, 1998/02/10 01:55]
177 *****************************************************************************/
178
179APIRET iConsoleInit(BOOL fVioConsole)              /* creation of the console subsystem */
180{
181  APIRET rc;                                       /* API return code */
182  ULONG  ulPostCount;                              /* semaphore post counter */
183
184
185  flVioConsole = fVioConsole;
186
187  if (ConsoleGlobals.hevConsole != NULLHANDLE) /* we're already initialized ?*/
188    return (NO_ERROR);                             /* then abort immediately */
189
190  rc = DosSetSignalExceptionFocus(SIG_SETFOCUS, &ulPostCount);
191  if(rc) {
192      dprintf(("DosSetSignalExceptionFocus failed with %d", rc));
193  }
194
195  if(flVioConsole == TRUE)
196  {
197    /***************************************************************************
198    * Create pseudo-devices and initialize ConsoleGlobals                     *
199    ***************************************************************************/
200
201    rc = iConsoleDevicesRegister();                /* ensure devices are there */
202    if (rc != NO_ERROR)                                    /* check for errors */
203    {
204        return (rc);                                    /* raise error condition */
205    }
206    rc = DosCreateMutexSem(NULL,
207                             &ConsoleInput.hmtxInputQueue,
208                             0L,
209                             FALSE);
210    if (rc != NO_ERROR)                                       /* other error ? */
211    {
212        return (rc);                                    /* raise error condition */
213    }
214
215    return NO_ERROR;
216  }
217  else {
218    /* create console synchronization semaphore */
219    rc = DosCreateEventSem (NULL,
220                            &ConsoleGlobals.hevConsole,
221                            0L,                        /* semaphore is private */
222                            FALSE);                             /* reset state */
223    if (rc != NO_ERROR)                                       /* other error ? */
224        return (rc);                                    /* raise error condition */
225
226
227                                         /* create console input queue semaphore */
228    rc = DosCreateEventSem (NULL,
229                              &ConsoleInput.hevInputQueue,
230                              0L,                        /* semaphore is private */
231                              FALSE);                             /* reset state */
232    if (rc != NO_ERROR)                                       /* other error ? */
233    {
234        DosCloseEventSem(ConsoleGlobals.hevConsole);    /* close other semaphore */
235        return (rc);                                    /* raise error condition */
236    }
237
238
239    rc = DosCreateMutexSem(NULL,
240                             &ConsoleInput.hmtxInputQueue,
241                             0L,
242                             FALSE);
243    if (rc != NO_ERROR)                                       /* other error ? */
244    {
245        DosCloseEventSem(ConsoleGlobals.hevConsole);    /* close other semaphore */
246        DosCloseEventSem(ConsoleInput.hevInputQueue);   /* close other semaphore */
247        return (rc);                                    /* raise error condition */
248    }
249
250    /***************************************************************************
251    * Create pseudo-devices and initialize ConsoleGlobals                     *
252    ***************************************************************************/
253
254    rc = iConsoleDevicesRegister();                /* ensure devices are there */
255    if (rc != NO_ERROR)                                    /* check for errors */
256    {
257        DosCloseEventSem(ConsoleGlobals.hevConsole);    /* close other semaphore */
258        DosCloseEventSem(ConsoleInput.hevInputQueue);   /* close other semaphore */
259        return (rc);                                    /* raise error condition */
260    }
261
262
263    /***************************************************************************
264    * Presentation Manager Initialization phase                               *
265    ***************************************************************************/
266
267        /* OK, we're about to initialize the console subsystem for this process. */
268                               /* start message thread for console object window */
269    ConsoleGlobals.tidConsole = _beginthread(iConsoleMsgThread,
270                                               NULL,
271                                               12288,
272                                               NULL);
273                                       /* has the thread been created properly ? */
274    if (ConsoleGlobals.tidConsole == -1)
275    {
276        DosCloseEventSem(ConsoleInput.hevInputQueue);   /* close other semaphore */
277        DosCloseEventSem(ConsoleGlobals.hevConsole);    /* close event semaphore */
278        ConsoleGlobals.hevConsole = NULLHANDLE;         /* for ConsoleIsActive() */
279        return (rc);                                    /* raise error condition */
280    }
281    else
282        DosSetPriority(PRTYS_THREAD,                             /* set priority */
283                       ConsoleGlobals.Options.ulConsoleThreadPriorityClass,
284                       ConsoleGlobals.Options.ulConsoleThreadPriorityDelta,
285                       ConsoleGlobals.tidConsole);
286
287
288                          /* wait for the child thread to do it's initialization */
289                                                  /* timeout isn't really useful */
290    rc = DosWaitEventSem(ConsoleGlobals.hevConsole,
291                           SEM_INDEFINITE_WAIT);
292    if (rc != NO_ERROR)                                    /* check for errors */
293    {
294        DosCloseEventSem(ConsoleInput.hevInputQueue);   /* close other semaphore */
295        DosCloseEventSem(ConsoleGlobals.hevConsole);    /* close event semaphore */
296        ConsoleGlobals.hevConsole = NULLHANDLE;         /* for ConsoleIsActive() */
297        return (rc);                                    /* raise error condition */
298    }
299
300    DosResetEventSem(ConsoleGlobals.hevConsole,       /* reset event semaphore */
301                       &ulPostCount);
302
303    rc = ConsoleGlobals.rcConsole;   /* pass thru console thread's return code */
304
305    return (rc);                                                         /* OK */
306  }
307}
308
309
310/*****************************************************************************
311 * Name      : ConsoleDevicesRegister
312 * Purpose   : creates and registers console devices if the standard handles
313 *             are not redirected to a file
314 * Parameters:
315 * Variables :
316 * Result    :
317 * Remark    :
318 * Status    :
319 *
320 * Author    : Patrick Haller [Tue, 1998/03/17 01:55]
321 *****************************************************************************/
322
323APIRET iConsoleDevicesRegister(void)
324{
325  DWORD  dwType;                                       /* device handle type */
326  HANDLE hStandardIn;                              /* stdin handle to CONIN$ */
327  HANDLE hStandardOut;                           /* stdout handle to CONOUT$ */
328  HANDLE hStandardError;                         /* stderr handle to CONOUT$ */
329
330  HMDeviceConsoleInClass     *pHMDeviceConsoleIn;
331  HMDeviceConsoleOutClass    *pHMDeviceConsoleOut;
332  HMDeviceConsoleBufferClass *pHMDeviceConsoleBuffer;
333
334  DWORD rc;
335
336  static BOOL fDevicesInitialized;     /* have we been initialized already ? */
337
338  if (fDevicesInitialized == TRUE)                 /* OK, we're already done */
339    return (NO_ERROR);
340  else
341    fDevicesInitialized = TRUE;
342
343  dprintf(("KERNEL32:ConsoleDevicesRegister\n"));
344
345
346  /*************************************
347   * Initialize Console Window Options *
348   *************************************/
349
350  // load defaults
351  ConsolePropertyDefault(&ConsoleGlobals.Options);
352
353  ConsoleGlobals.ulTimerFrequency = 10;  /* cursor + blitter timer frequency */
354
355  ConsoleGlobals.coordWindowSize.X               = ConsoleGlobals.Options.coordDefaultSize.X;
356  ConsoleGlobals.coordWindowSize.Y               = ConsoleGlobals.Options.coordDefaultSize.Y;
357  ConsoleGlobals.coordWindowPos.X                = 0;
358  ConsoleGlobals.coordWindowPos.Y                = 0;
359  if(flVioConsole == TRUE) {
360        VIOMODEINFO videoinfo;
361
362        videoinfo.cb = sizeof(VIOMODEINFO);
363        rc = VioGetMode(&videoinfo, 0);
364        if(rc == 0) {
365            dprintf(("video mode (%d,%d)", videoinfo.col, videoinfo.row));
366            ConsoleGlobals.coordWindowSize.X = videoinfo.col;
367            ConsoleGlobals.coordWindowSize.Y = videoinfo.row;
368        }
369  }
370
371
372  ConsoleGlobals.flFrameFlags = FCF_SIZEBORDER   |   /* frame creation flags */
373                                FCF_TITLEBAR     |
374                                FCF_SHELLPOSITION|
375                                FCF_SYSMENU      |
376                                FCF_TASKLIST     |
377                                FCF_AUTOICON     |
378                                FCF_HORZSCROLL   |
379                                FCF_VERTSCROLL   |
380                                FCF_MINMAX;
381
382                                                   /* generate copy of title */
383  ConsoleGlobals.pszWindowTitle = strdup(GetCommandLineA());
384
385                                    /* obtain module handle to our resources */
386  rc = DosQueryModuleHandleStrict("KERNEL32",
387                                  &ConsoleGlobals.hmodResource);
388  if (rc != NO_ERROR)
389    dprintf(("KERNEL32/CONSOLE: Can't get handle to KERNEL32 (%u).\n",
390             rc));
391
392                                             /* standard console input modes */
393  ConsoleInput.dwConsoleMode = ENABLE_LINE_INPUT      |
394                               ENABLE_PROCESSED_INPUT;
395  /* @@@PH ENABLE_ECHO_INPUT || ENABLE_MOUSE_INPUT; */
396
397  ConsoleGlobals.hConsoleBufferDefault = INVALID_HANDLE_VALUE;
398  ConsoleGlobals.hConsoleBuffer        = INVALID_HANDLE_VALUE;
399
400
401  if (flVioConsole == FALSE)
402  {
403    // defaults are effective, try to read and apply stored properties
404    if (ConsolePropertyLoad(&ConsoleGlobals.Options) == NO_ERROR)
405        ConsolePropertyApply(&ConsoleGlobals.Options);
406  }
407
408
409  /***************************************************************************
410   * Standard handles     Initialization phase                               *
411   ***************************************************************************/
412
413  /* create devices and register devices with handlemanager */
414  pHMDeviceConsoleIn  = new HMDeviceConsoleInClass("CONIN$",
415                                                   &ConsoleInput,
416                                                   &ConsoleGlobals);
417
418  rc = HMDeviceRegister ("CONIN$",
419                         pHMDeviceConsoleIn);
420  if (rc != NO_ERROR)                                  /* check for errors */
421      dprintf(("KERNEL32:ConsoleDevicesRegister: registering CONIN$ failed with %u.\n",
422               rc));
423
424
425  pHMDeviceConsoleOut = new HMDeviceConsoleOutClass("CONOUT$",
426                                                    &ConsoleInput,
427                                                    &ConsoleGlobals);
428  rc = HMDeviceRegister ("CONOUT$",
429                         pHMDeviceConsoleOut);
430  if (rc != NO_ERROR)                                  /* check for errors */
431      dprintf(("KERNEL32:ConsoleDevicesRegister: registering CONOUT$ failed with %u.\n",
432               rc));
433
434  // add standard symbolic links
435  HandleNamesAddSymbolicLink("CON",        "CONOUT$");
436  HandleNamesAddSymbolicLink("CON:",       "CONOUT$");
437  HandleNamesAddSymbolicLink("\\\\.\\CON", "CONOUT$");
438
439  if(flVioConsole == TRUE)
440  {
441        pHMDeviceConsoleBuffer = (HMDeviceConsoleBufferClass *)new HMDeviceConsoleVioBufferClass("CONBUFFER$",
442                                                                                                 &ConsoleInput,
443                                                                                                 &ConsoleGlobals);
444  }
445  else {
446        pHMDeviceConsoleBuffer = new HMDeviceConsoleBufferClass("CONBUFFER$",
447                                                                &ConsoleInput,
448                                                                &ConsoleGlobals);
449  }
450  rc = HMDeviceRegister ("CONBUFFER$",
451                         pHMDeviceConsoleBuffer);
452  if (rc != NO_ERROR)                                  /* check for errors */
453      dprintf(("KERNEL32:ConsoleDevicesRegister: registering CONBUFFER$ failed with %u.\n",
454               rc));
455
456  /***********************************************************************
457   * initialize stdin handle                                             *
458   ***********************************************************************/
459  hStandardIn = GetStdHandle(STD_INPUT_HANDLE);
460  dwType = GetFileType(hStandardIn);
461  if (dwType == FILE_TYPE_CHAR) {               /* is handle not redirected ? */
462    hStandardIn = HMCreateFile("CONIN$",
463                               GENERIC_READ | GENERIC_WRITE,
464                               FILE_SHARE_READ | FILE_SHARE_WRITE,
465                               NULL,
466                               0,
467                               CONSOLE_TEXTMODE_BUFFER,
468                               0);
469    HMUpdtStdHandle(STD_INPUT_HANDLE,
470                    hStandardIn);
471  }
472
473  /***********************************************************************
474   * initialize stdout handle                                            *
475   ***********************************************************************/
476  hStandardOut = GetStdHandle(STD_OUTPUT_HANDLE);
477  dwType = GetFileType(hStandardOut);
478  if (dwType == FILE_TYPE_CHAR) {               /* is handle redirected ? */
479    hStandardOut = HMCreateFile("CONOUT$",
480                                GENERIC_READ | GENERIC_WRITE,
481                                FILE_SHARE_READ | FILE_SHARE_WRITE,
482                                NULL,
483                                0,
484                                CONSOLE_TEXTMODE_BUFFER,
485                                0);
486    HMUpdtStdHandle(STD_OUTPUT_HANDLE,
487                    hStandardOut);
488  }
489
490  /***********************************************************************
491   * initialize stderr handle                                            *
492   ***********************************************************************/
493  hStandardError = GetStdHandle(STD_ERROR_HANDLE);
494  dwType = GetFileType(hStandardError);
495  if (dwType == FILE_TYPE_CHAR) {               /* is handle redirected ? */
496    hStandardError = HMCreateFile("CONOUT$",
497                                  GENERIC_READ | GENERIC_WRITE,
498                                  FILE_SHARE_READ | FILE_SHARE_WRITE,
499                                  NULL,
500                                  0,
501                                  CONSOLE_TEXTMODE_BUFFER,
502                                  0);
503    HMUpdtStdHandle(STD_ERROR_HANDLE,
504                    hStandardError);
505  }
506
507  return (NO_ERROR);                                                   /* OK */
508}
509
510
511/*****************************************************************************
512 * Name      : static APIRET ConsoleTerminate
513 * Purpose   : Shuts the OS/2 console subsystem down
514 * Parameters: VOID
515 * Variables :
516 * Result    : OS/2 API return code
517 * Remark    : That consolebuffer handle that became allocated as default
518 *             screen buffer is lost here. This would be a serious memory
519 *             leak if an application keeps opening and closing the console
520 *             frequently.
521 * Status    :
522 *
523 * Author    : Patrick Haller [Tue, 1998/02/10 01:55]
524 *****************************************************************************/
525
526ULONG iConsoleTerminate(VOID)
527{
528  APIRET rc = NO_ERROR;
529
530  if(flVioConsole == FALSE)
531  {
532    DosCloseEventSem(ConsoleGlobals.hevConsole);      /* close other semaphore */
533    DosCloseEventSem(ConsoleInput.hevInputQueue);     /* close other semaphore */
534
535
536    WinPostMsg (ConsoleGlobals.hwndFrame,         /* force thread to terminate */
537                WM_CLOSE,
538                (MPARAM)NULL,
539                (MPARAM)NULL);
540
541    rc = DosWaitThread(&ConsoleGlobals.tidConsole,/* wait until thd terminates */
542                       DCWW_WAIT);
543
544  }
545  DosCloseMutexSem(ConsoleInput.hmtxInputQueue);          /* close semaphore */
546
547  /* close the consolebuffer handle */
548  HMCloseHandle(ConsoleGlobals.hConsoleBufferDefault);
549  free(ConsoleGlobals.pszWindowTitle);   /* free previously allocated memory */
550
551  return (rc);                                                         /* OK */
552}
553
554
555/*****************************************************************************
556 * Name      : static void ConsoleWaitClose
557 * Purpose   : Wait for the user to close console window
558 * Parameters: VOID
559 * Variables :
560 * Result    :
561 * Remark    :
562 * Status    :
563 *
564 * Author    : Patrick Haller [Tue, 1998/02/10 01:55]
565 *****************************************************************************/
566
567void iConsoleWaitClose(void)
568{
569  CHAR szBuffer[128];                                /* buffer for the title */
570  BOOL fResult;                /* result from subsequent calls to Win32 APIs */
571
572                                /* check if there is a console window at all */
573  if (iConsoleIsActive() == FALSE)
574    return;                                                          /* nope */
575
576  if(flVioConsole == TRUE)  //no need to wait for VIO session
577    return;
578
579  strcpy (szBuffer,               /* indicate console process has terminated */
580          "Completed: ");
581
582  fResult = GetConsoleTitleA(szBuffer + 11,/* 11 is length of Completed:_ */
583                                sizeof(szBuffer) - 11);
584
585
586                                /* Set new title: Win32 Console - Terminated */
587  fResult = SetConsoleTitleA(szBuffer);
588
589  DosCloseEventSem(ConsoleGlobals.hevConsole);      /* close other semaphore */
590  DosCloseEventSem(ConsoleInput.hevInputQueue);     /* close other semaphore */
591  DosCloseMutexSem(ConsoleInput.hmtxInputQueue);          /* close semaphore */
592
593
594                                          /* terminate console immediately ? */
595  if (ConsoleGlobals.Options.fTerminateAutomatically == FALSE) {
596    if(getenv("ODIN_AUTOEXITCONSOLE") == NULL) {
597        DosWaitThread(&ConsoleGlobals.tidConsole,   /* wait until thd terminates */
598                      DCWW_WAIT);
599    }
600  }
601}
602
603
604/*****************************************************************************
605 * Name      : static BOOL ConsoleIsActive
606 * Purpose   : Check if Console window is opened
607 * Parameters: VOID
608 * Variables :
609 * Result    :
610 * Remark    :
611 * Status    :
612 *
613 * Author    : Patrick Haller [Tue, 1998/02/10 01:55]
614 *****************************************************************************/
615
616BOOL iConsoleIsActive(void)
617{
618  if(flVioConsole == TRUE) //actually, this isn't needed in VIO mode
619     return TRUE;
620
621  return (NULLHANDLE != ConsoleGlobals.hevConsole);
622}
623
624
625/*****************************************************************************
626 * Name      : static VOID ConsoleMsgThread
627 * Purpose   : Message handler thread for the console object window
628 * Parameters: PVOID pDummy
629 * Variables :
630 * Result    : is placed in Globals.rcConsole
631 * Remark    : the main thread has to wait for this thread
632 * Status    :
633 *
634 * Author    : Patrick Haller [Tue, 1998/02/10 02:49]
635 *****************************************************************************/
636
637VOID iConsoleMsgThread(PVOID pParameters)
638{
639  APIRET rc;                                              /* API return code */
640
641
642  ConsoleGlobals.rcConsole = NO_ERROR;                     /* initialization */
643
644  ConsoleGlobals.hab = WinInitialize(0);             /* enable thread for PM */
645  if (ConsoleGlobals.hab == NULLHANDLE) /* if anchor block allocation failed */
646    ConsoleGlobals.rcConsole = ERROR_NOT_ENOUGH_MEMORY;
647  else
648  {
649                                                     /* create message queue */
650    ConsoleGlobals.hmq = WinCreateMsgQueue(ConsoleGlobals.hab,
651                                           0);
652    if (ConsoleGlobals.hmq == NULLHANDLE)  /* if msg queue allocation failed */
653    {
654      WinTerminate(ConsoleGlobals.hab);     /* stop thread from accessing PM */
655      ConsoleGlobals.rcConsole = ERROR_NOT_ENOUGH_MEMORY;
656    }
657    else
658    {
659      if (WinRegisterClass(ConsoleGlobals.hab, /* register our class with PM */
660                           SZ_CONSOLE_CLASS,
661                           iConsoleWindowProc,
662                           CS_SIZEREDRAW,
663                           0)
664          == FALSE)
665      {
666        WinDestroyMsgQueue(ConsoleGlobals.hmq);     /* destroy message queue */
667        WinTerminate(ConsoleGlobals.hab);   /* stop thread from accessing PM */
668        ConsoleGlobals.rcConsole = ERROR_NOT_ENOUGH_MEMORY;
669      }
670      else
671      {
672        ConsoleGlobals.hwndFrame = WinCreateStdWindow(HWND_DESKTOP,
673                                                      WS_VISIBLE,
674                                                      &ConsoleGlobals.flFrameFlags,
675                                                      SZ_CONSOLE_CLASS,
676                                                      ConsoleGlobals.pszWindowTitle,
677                                                      0,
678                                                      ConsoleGlobals.hmodResource,
679                                                      ID_CONSOLE_MAIN,
680                                                      &ConsoleGlobals.hwndClient);
681        if (ConsoleGlobals.hwndFrame == NULLHANDLE) /* check window creation */
682        {
683          WinDestroyMsgQueue(ConsoleGlobals.hmq);   /* destroy message queue */
684          WinTerminate(ConsoleGlobals.hab); /* stop thread from accessing PM */
685          ConsoleGlobals.rcConsole = ERROR_NOT_ENOUGH_MEMORY;
686        } /* WinCreateStdWindow */
687      } /* WinRegisterClass */
688    } /* WinCreateMsgQueue */
689  } /* WinInitialize */
690
691
692  DosPostEventSem(ConsoleGlobals.hevConsole);      /* signal the main thread */
693
694
695  if (ConsoleGlobals.rcConsole != NO_ERROR)      /* if we ran into a problem */
696  {
697    DosCloseEventSem(ConsoleInput.hevInputQueue);   /* close other semaphore */
698    DosCloseEventSem(ConsoleGlobals.hevConsole); /* subsystem not running .. */
699    ConsoleGlobals.hevConsole = NULLHANDLE;         /* for ConsoleIsActive() */
700    return;                    /* abort the message queue thread immediately */
701  }
702
703
704  while( WinGetMsg(ConsoleGlobals.hab,                       /* message loop */
705                   &ConsoleGlobals.qmsg,
706                   NULLHANDLE,
707                   0,
708                   0) )
709    WinDispatchMsg(ConsoleGlobals.hab,               /* dispatch the message */
710                   &ConsoleGlobals.qmsg);
711
712                                    /* do the cleanup, destroy window, queue */
713                                    /* and stop thread from using PM         */
714  WinDestroyWindow  (ConsoleGlobals.hwndFrame);
715  WinDestroyMsgQueue(ConsoleGlobals.hmq);
716  WinTerminate      (ConsoleGlobals.hab);
717
718                   /* destruction of semaphore indicates console is shutdown */
719  DosCloseEventSem(ConsoleInput.hevInputQueue);     /* close other semaphore */
720  DosCloseEventSem(ConsoleGlobals.hevConsole);
721  DosCloseMutexSem(ConsoleInput.hmtxInputQueue);          /* close semaphore */
722
723  ConsoleGlobals.hevConsole   = NULLHANDLE;         /* for ConsoleIsActive() */
724  ConsoleInput.hevInputQueue  = NULLHANDLE;
725  ConsoleInput.hmtxInputQueue = NULLHANDLE;
726
727  /* @@@PH we've got to exit the process here ! */
728  ExitProcess(1);
729}
730
731
732/*****************************************************************************
733 * Name      : static MRESULT EXPENTRY ConsoleWindowProc
734 * Purpose   : Window Procedure for OUR console window
735 * Parameters: HWND   hwnd - window handle
736 *             ULONG  msg  - message identifier
737 *             MPARAM mp1  - message parameter 1
738 *             MPARAM mp2  - message parameter 2
739 * Variables :
740 * Result    : MRESULT for PM
741 * Remark    :
742 * Status    :
743 *
744 * Author    : Patrick Haller [Tue, 1998/02/10 03:24]
745 *****************************************************************************/
746
747MRESULT EXPENTRY iConsoleWindowProc(HWND   hwnd,
748                                    ULONG  msg,
749                                    MPARAM mp1,
750                                    MPARAM mp2)
751{
752  static RECTL rcl;                                      /* window rectangle */
753  static HPS   hps;
754
755  switch(msg)
756  {
757    /*************************************************************************
758     * WM_CREATE window creation                                             *
759     *************************************************************************/
760
761    case WM_CREATE:
762      WinPostMsg(hwnd,                            /* deferred initialization */
763                 UM_CONSOLE_CREATE,
764                 (MPARAM)NULL,
765                 (MPARAM)NULL);
766      break;
767
768
769    case UM_CONSOLE_CREATE:
770    {
771      APIRET    rc;                                       /* API return code */
772      HWND      hwndFrame;                            /* frame window handle */
773
774                                                /* subclass the frame window */
775      hwndFrame = ConsoleGlobals.hwndFrame;
776      ConsoleGlobals.pfnwpFrameOriginal = WinSubclassWindow(hwndFrame,
777                                                            iConsoleFrameWindowProc);
778
779      ConsoleGlobals.hwndMenuConsole
780                      = WinLoadMenu (hwnd,             /* load context menue */
781                                     ConsoleGlobals.hmodResource,
782                                     ID_CONSOLE_MAIN);
783
784                                               /* set an icon for the dialog */
785      ConsoleGlobals.hPtrConsole = WinLoadPointer(HWND_DESKTOP,
786                                                  ConsoleGlobals.hmodResource,
787                                                  ID_CONSOLE_MAIN );
788      WinSendMsg(ConsoleGlobals.hwndFrame,
789                 WM_SETICON,
790                 (MPARAM)ConsoleGlobals.hPtrConsole,
791                 0L );
792
793               /* determine handles of the horizontal / vertical scroll bars */
794      ConsoleGlobals.hwndVertScroll = WinWindowFromID(ConsoleGlobals.hwndFrame,
795                                                      FID_VERTSCROLL);
796
797      ConsoleGlobals.hwndHorzScroll = WinWindowFromID(ConsoleGlobals.hwndFrame,
798                                                      FID_HORZSCROLL);
799
800                            /* the initial state of the controls is DETACHED */
801      WinSetParent(ConsoleGlobals.hwndHorzScroll,          /* detach control */
802                   HWND_OBJECT,
803                   FALSE);
804
805      WinSetParent(ConsoleGlobals.hwndVertScroll,          /* detach control */
806                   HWND_OBJECT,
807                   FALSE);
808
809
810                                           /* create AVIO presentation space */
811      rc = VioCreatePS(&ConsoleGlobals.hvpsConsole,
812                       ConsoleGlobals.coordWindowSize.Y,
813                       ConsoleGlobals.coordWindowSize.X,
814                       0,                               /* format, must be 0 */
815                       FORMAT_CGA,
816                       0);                       /* template hvps, must be 0 */
817      if (rc != NO_ERROR)                                    /* check errors */
818        dprintf(("KERNEL32/CONSOLE:VioCreatePS=%u\n",
819                 rc));
820
821 /* PH 1998/02/12 this seems to be an OS/2 PM bug:
822    when doing a WinOpenWindowDC here, PM hangs. Seems it never gets back into
823    the message loop. To investigate and report to IBM
824  */
825
826                               /* get a device context for the client window */
827      ConsoleGlobals.hdcConsole = WinOpenWindowDC(hwnd);
828                                           /* associate AVIO PS with the HDC */
829      rc = VioAssociate(ConsoleGlobals.hdcConsole,
830                        ConsoleGlobals.hvpsConsole);
831      if (rc != NO_ERROR)                                    /* check errors */
832        dprintf(("KERNEL32/CONSOLE:VioAssociate=%u\n",
833                 rc));
834
835      iConsoleFontQuery();                       /* query current cell sizes */
836
837                                          /* adjust window size and position */
838      HMDeviceRequest(ConsoleGlobals.hConsoleBuffer,
839                      DRQ_INTERNAL_CONSOLEADJUSTWINDOW,
840                      0,
841                      0,
842                      0,
843                      0);
844
845            /* @@@PH if console is maximized - now switched on per default ! */
846      WinSetWindowPos (ConsoleGlobals.hwndFrame,
847                       HWND_DESKTOP,
848                       0,
849                       0,
850                       ConsoleGlobals.Options.coordDefaultSize.X *
851                         ConsoleGlobals.sCellCX +
852                         2 * WinQuerySysValue(HWND_DESKTOP, SV_CXSIZEBORDER),
853                       ConsoleGlobals.Options.coordDefaultSize.Y *
854                         ConsoleGlobals.sCellCY +
855                         WinQuerySysValue(HWND_DESKTOP, SV_CYTITLEBAR) +
856                         2 * WinQuerySysValue(HWND_DESKTOP, SV_CYSIZEBORDER),
857                       SWP_SIZE);
858
859                             /* do we have to set the window position also ? */
860      if (ConsoleGlobals.Options.fSetWindowPosition == TRUE)
861        WinSetWindowPos (ConsoleGlobals.hwndFrame,
862                         HWND_DESKTOP,
863                         ConsoleGlobals.Options.coordDefaultPosition.X,
864                         ConsoleGlobals.Options.coordDefaultPosition.Y,
865                         0,
866                         0,
867                         SWP_MOVE);
868
869                     /* start timer service for blitting and cursor blinking */
870      ConsoleGlobals.idTimer = WinStartTimer (ConsoleGlobals.hab,
871                                              hwnd,
872                                              CONSOLE_TIMER_ID,  /* timer id */
873                                              ConsoleGlobals.ulTimerFrequency);
874
875      WinPostMsg (hwnd,   /* send myself a start message so we get the first */
876                  WM_TIMER,                             /* frame immediately */
877                  (MPARAM)NULL,
878                  (MPARAM)NULL);
879    }
880    break;
881
882
883    /*************************************************************************
884     * WM_DESTROY window destruction                                         *
885     *************************************************************************/
886
887    case WM_DESTROY:
888      WinStopTimer (ConsoleGlobals.hab,                      /* anchor block */
889                    hwnd,
890                    ConsoleGlobals.idTimer);                     /* timer ID */
891
892      VioAssociate(NULL,
893                   ConsoleGlobals.hvpsConsole); /* disassociates the AVIO PS */
894      VioDestroyPS(ConsoleGlobals.hvpsConsole); /* destroys the AVIO PS      */
895
896      WinDestroyWindow(ConsoleGlobals.hwndMenuConsole);
897      WinDestroyPointer(ConsoleGlobals.hPtrConsole);
898      break;
899
900
901    /*************************************************************************
902     * WM_TIMER display cursor and update AVIO PS if required                *
903     *************************************************************************/
904
905    case WM_TIMER:
906                                       /* check if console has to be updated */
907      if (ConsoleGlobals.fUpdateRequired == TRUE)
908      {
909        ConsoleGlobals.fUpdateRequired = FALSE;     /* as soon as possible ! */
910
911                                /* as device to map itself to the VIO buffer */
912        HMDeviceRequest(ConsoleGlobals.hConsoleBuffer,
913                        DRQ_INTERNAL_CONSOLEBUFFERMAP,
914                        0,
915                        0,
916                        0,
917                        0);
918
919        { /* DEBUG */
920          APIRET rc;
921                                           /* and now bring it to the screen */
922        rc = VioShowPS(ConsoleGlobals.coordWindowSize.Y,
923                       ConsoleGlobals.coordWindowSize.X,
924                       0,
925                       ConsoleGlobals.hvpsConsole);
926
927          dprintf(("KERNEL32::Console::1 VioShowPS(%u,%u,%u)=%u\n",
928                   ConsoleGlobals.coordWindowSize.Y,
929                   ConsoleGlobals.coordWindowSize.X,
930                   ConsoleGlobals.hvpsConsole,
931                   rc));
932        }
933
934                                             /* cursor is overwritten here ! */
935        HMDeviceRequest(ConsoleGlobals.hConsoleBuffer,
936                        DRQ_INTERNAL_CONSOLECURSORSHOW,
937                        CONSOLECURSOR_OVERWRITTEN,
938                        0,
939                        0,
940                        0);
941      }
942      else
943      {
944        ConsoleGlobals.ulTimerCursor++;                  /* increase counter */
945        if (ConsoleGlobals.ulTimerCursor > ConsoleGlobals.Options.ucCursorDivisor)
946        {
947          ConsoleGlobals.ulTimerCursor = 0;                 /* reset counter */
948                                                     /* let our cursor blink */
949          HMDeviceRequest(ConsoleGlobals.hConsoleBuffer,
950                          DRQ_INTERNAL_CONSOLECURSORSHOW,
951                          CONSOLECURSOR_BLINK,
952                          0,
953                          0,
954                          0);
955        }
956      }
957      break;
958
959
960    /*************************************************************************
961     * WM_MINMAXFRAME handle window repaint in case of iconized window       *
962     *************************************************************************/
963
964    case WM_MINMAXFRAME :
965    {
966      BOOL  fShow = ! (((PSWP) mp1)->fl & SWP_MINIMIZE);
967      HENUM henum;
968      HWND  hwndChild;
969
970      WinEnableWindowUpdate ( hwnd, FALSE );
971
972      for (henum=WinBeginEnumWindows(hwnd);
973           (hwndChild = WinGetNextWindow (henum)) != 0; )
974      WinShowWindow ( hwndChild, fShow );
975
976      WinEndEnumWindows ( henum );
977      WinEnableWindowUpdate ( hwnd, TRUE );
978    }
979    break;
980
981
982    /*************************************************************************
983     * WM_PAINT repaint the window                                           *
984     *************************************************************************/
985    case WM_PAINT:
986      hps = WinBeginPaint(hwnd,
987                          (HPS)NULL,
988                          &rcl);
989                                   /* blit the whole AVIO presentation space */
990      { /* DEBUG */
991        APIRET rc;
992                                     /* and now bring it to the screen */
993        rc = VioShowPS(ConsoleGlobals.coordWindowSize.Y,
994                       ConsoleGlobals.coordWindowSize.X,
995                       0,
996                       ConsoleGlobals.hvpsConsole);
997
998        dprintf(("KERNEL32::Console::2 VioShowPS(%u,%u,%u)=%u\n",
999                 ConsoleGlobals.coordWindowSize.Y,
1000                 ConsoleGlobals.coordWindowSize.X,
1001                 ConsoleGlobals.hvpsConsole,
1002                 rc));
1003      }
1004
1005      WinEndPaint(hps);
1006      break;
1007
1008
1009    /*************************************************************************
1010     * WM_SIZE resize the window                                             *
1011     *************************************************************************/
1012    case WM_SIZE:
1013    {
1014                                       /* calculate scrollbars if neccessary */
1015      HMDeviceRequest(ConsoleGlobals.hConsoleBuffer,
1016                      DRQ_INTERNAL_CONSOLEADJUSTWINDOW,
1017                      0,
1018                      0,
1019                      0,
1020                      0);
1021
1022      return WinDefAVioWindowProc(hwnd,
1023                                  (USHORT)msg,
1024                                  (ULONG)mp1,
1025                                  (ULONG)mp2);
1026    }
1027
1028
1029    /*************************************************************************
1030     * context menue                                                         *
1031     *************************************************************************/
1032    case WM_CONTEXTMENU:
1033    {
1034      WinPopupMenu (hwnd,
1035                    hwnd,
1036                    ConsoleGlobals.hwndMenuConsole,
1037                    SHORT1FROMMP(mp1),
1038                    SHORT2FROMMP(mp1),
1039                    CM_CONSOLE_PROPERTIES,                        /* item id */
1040                    PU_HCONSTRAIN |
1041                    PU_VCONSTRAIN |
1042                    PU_KEYBOARD   |
1043                    PU_MOUSEBUTTON1 |
1044                    PU_MOUSEBUTTON2 |
1045                    PU_POSITIONONITEM);
1046    }
1047    return (MPARAM)FALSE;
1048
1049
1050    /*************************************************************************
1051     * WM_COMMAND command processing                                         *
1052     *************************************************************************/
1053    case WM_COMMAND:
1054    {
1055      switch(SHORT1FROMMP(mp1))             /* select appropriate identifier */
1056      {
1057        /* close console window, however we can't call ConsoleTerminate here!*/
1058        case CM_CONSOLE_EXIT:
1059          WinPostMsg (ConsoleGlobals.hwndFrame,
1060                      WM_CLOSE,
1061                      (MPARAM)NULL,
1062                      (MPARAM)NULL);
1063
1064          return (MPARAM)FALSE;
1065
1066
1067        case CM_CONSOLE_REPAINT:
1068          WinInvalidateRect(ConsoleGlobals.hwndClient,/* redraw frame window */
1069                            NULL,
1070                            TRUE);
1071          return (MPARAM)FALSE;
1072
1073                                               /* open the properties dialog */
1074        case CM_CONSOLE_PROPERTIES:
1075        {
1076          ULONG ulResult;                              /* response from user */
1077
1078          ConsoleGlobals.Options.hmodResources =       /* save module handle */
1079            ConsoleGlobals.hmodResource;
1080
1081          ulResult = WinDlgBox(HWND_DESKTOP,
1082                               ConsoleGlobals.hwndClient,
1083                               &ConsolePropertyDlgProc,
1084                               ConsoleGlobals.hmodResource,
1085                               DLG_CONSOLE_PROPERTIES,
1086                               (PVOID)&ConsoleGlobals.Options);
1087          switch (ulResult)
1088          {
1089            case ID_BTN_SAVE:
1090              ConsolePropertySave(&ConsoleGlobals.Options);
1091              ConsolePropertyApply(&ConsoleGlobals.Options);
1092              break;
1093
1094            case ID_BTN_APPLY:
1095              ConsolePropertyApply(&ConsoleGlobals.Options);
1096              break;
1097
1098            default:           break;
1099          }
1100
1101          return (MPARAM) FALSE;
1102        }
1103      }
1104    }
1105    break;
1106
1107
1108    /*************************************************************************
1109     * WM_CHAR keyboard char processing                                      *
1110     *************************************************************************/
1111
1112    case WM_CHAR:
1113      iConsoleInputEventPushKey(mp1,                /* push event into queue */
1114                                mp2);
1115      break;                                  /* enable further processing ! */
1116
1117
1118    /*************************************************************************
1119     * WM_SETFOCUS focus changing processing                                 *
1120     *************************************************************************/
1121
1122    case WM_SETFOCUS:
1123      iConsoleInputEventPushFocus((BOOL)mp2);       /* push event into queue */
1124      break;                                  /* enable further processing ! */
1125
1126
1127    /*************************************************************************
1128     * WM_MOUSEMOVE mouse event processing                                   *
1129     *************************************************************************/
1130
1131    case WM_MOUSEMOVE:
1132    case WM_BUTTON1UP:
1133    case WM_BUTTON1DOWN:
1134    case WM_BUTTON2UP:
1135    case WM_BUTTON2DOWN:
1136    case WM_BUTTON3UP:
1137    case WM_BUTTON3DOWN:
1138    case WM_BUTTON1DBLCLK:
1139    case WM_BUTTON2DBLCLK:
1140    case WM_BUTTON3DBLCLK:
1141      iConsoleInputEventPushMouse(msg,
1142                                  mp1,              /* push event into queue */
1143                                  mp2);
1144      break;                                  /* enable further processing ! */
1145  }
1146
1147  return WinDefWindowProc(hwnd,                     /* to default processing */
1148                          msg,
1149                          mp1,
1150                          mp2);
1151}
1152
1153
1154/*****************************************************************************
1155 * Name      : static MRESULT EXPENTRY ConsoleFrameWindowProc
1156 * Purpose   : Window Procedure for OUR console frame window
1157 * Parameters: HWND   hwnd - window handle
1158 *             ULONG  msg  - message identifier
1159 *             MPARAM mp1  - message parameter 1
1160 *             MPARAM mp2  - message parameter 2
1161 * Variables :
1162 * Result    : MRESULT for PM
1163 * Remark    :
1164 * Status    :
1165 *
1166 * Author    : Patrick Haller [Tue, 1998/02/10 03:24]
1167 *****************************************************************************/
1168
1169MRESULT EXPENTRY iConsoleFrameWindowProc(HWND   hwnd,
1170                                         ULONG  msg,
1171                                         MPARAM mp1,
1172                                         MPARAM mp2)
1173{
1174  switch(msg)
1175  {
1176    /*************************************************************************
1177     * WM_QUERYTRACKINFO handling                                            *
1178     *************************************************************************/
1179    case WM_QUERYTRACKINFO:
1180    {
1181       MRESULT    mr;                                      /* message result */
1182       PTRACKINFO pTrackInfo;           /* frame window tracking information */
1183
1184                             /* let the original code do the hard work first */
1185       mr = ConsoleGlobals.pfnwpFrameOriginal(hwnd,
1186                                              msg,
1187                                              mp1,
1188                                              mp2);
1189
1190       pTrackInfo = (PTRACKINFO)mp2;                /* get track information */
1191
1192       /* @@@PH */
1193       pTrackInfo->ptlMinTrackSize.x = max(pTrackInfo->ptlMinTrackSize.x, 200);
1194       pTrackInfo->ptlMinTrackSize.y = max(pTrackInfo->ptlMinTrackSize.y, 100);
1195       pTrackInfo->ptlMaxTrackSize.x = min(pTrackInfo->ptlMaxTrackSize.x, ConsoleGlobals.coordMaxWindowPels.X);
1196       pTrackInfo->ptlMaxTrackSize.y = min(pTrackInfo->ptlMaxTrackSize.y, ConsoleGlobals.coordMaxWindowPels.Y);
1197
1198       return (mr);                                        /* deliver result */
1199    }
1200  }
1201
1202                                /* call original frame window procedure code */
1203  return (ConsoleGlobals.pfnwpFrameOriginal(hwnd,
1204                                            msg,
1205                                            mp1,
1206                                            mp2));
1207}
1208
1209
1210/*****************************************************************************
1211 * Name      : static void ConsoleBufferMap
1212 * Purpose   : draw a whole consolebuffer into the VIO space
1213 * Parameters: PCONSOLEBUFFER pConsoleBuffer
1214 * Variables :
1215 * Result    : none
1216 * Remark    :
1217 * Status    :
1218 *
1219 * Author    : Patrick Haller [Tue, 1998/02/17 12:57]
1220 *****************************************************************************/
1221
1222void iConsoleBufferMap(PCONSOLEBUFFER pConsoleBuffer)
1223{
1224  ULONG ulLine;
1225
1226  ULONG ulSizeX;                               /* blitting length and height */
1227  ULONG ulSizeY;
1228
1229  ulSizeX = 2 * min(ConsoleGlobals.coordWindowSize.X,
1230                    pConsoleBuffer->coordBufferSize.X -
1231                    ConsoleGlobals.coordWindowPos.X);
1232
1233  ulSizeY = min(ConsoleGlobals.coordWindowSize.Y,
1234                pConsoleBuffer->coordBufferSize.Y -
1235                ConsoleGlobals.coordWindowPos.Y);
1236
1237                      /* check if we're called with non-existing line buffer */
1238  if (pConsoleBuffer->ppszLine == NULL)
1239    return;
1240
1241  for (ulLine = ConsoleGlobals.coordWindowPos.Y;
1242       ulLine < ulSizeY;
1243       ulLine++)
1244    VioWrtCellStr(pConsoleBuffer->ppszLine[ulLine] +
1245                    ConsoleGlobals.coordWindowPos.X,
1246                  ulSizeX,
1247                  ulLine,
1248                  0,
1249                  ConsoleGlobals.hvpsConsole);
1250}
1251
1252
1253/*****************************************************************************
1254 * Name      : static void ConsoleBufferFillLine
1255 * Purpose   : fills a line with a certain output pattern
1256 * Parameters: ULONG ulPattern, PUSHORT pusTarget, ULONG ulSize
1257 * Variables :
1258 * Result    : none
1259 * Remark    :
1260 * Status    :
1261 *
1262 * Author    : Patrick Haller [Tue, 1998/02/17 12:57]
1263 *****************************************************************************/
1264
1265void iConsoleBufferFillLine(ULONG   ulPattern,
1266                            PUSHORT pusTarget,
1267                            ULONG   ulSize)
1268{
1269  ULONG  ulCounter;
1270
1271  for (ulCounter = 0;
1272       ulCounter < (ulSize >> 1);
1273       ulCounter++,
1274       pusTarget+=2)
1275    *(PULONG)pusTarget = ulPattern;
1276
1277  if (ulSize & 0x00000001)
1278    *pusTarget = (USHORT)ulPattern;
1279}
1280
1281
1282/*****************************************************************************
1283 * Name      : static void ConsoleBufferScrollUp
1284 * Purpose   : scroll whole buffer n lines up,
1285 *             fill new lines with default attribute
1286 * Parameters: PCONSOLEBUFFER pConsoleBuffer
1287 *             ULONG          ulLines
1288 * Variables :
1289 * Result    : none
1290 * Remark    :
1291 * Status    :
1292 *
1293 * Author    : Patrick Haller [Tue, 1998/02/17 12:57]
1294 *****************************************************************************/
1295
1296void iConsoleBufferScrollUp(PCONSOLEBUFFER pConsoleBuffer,
1297                            ULONG          ulLines)
1298{
1299  ULONG ulLine;
1300  ULONG ulPosition;
1301  ULONG ulScrollLine;
1302
1303  static ULONG ulUpdateCounter;                /* counter for jump-scrolling */
1304
1305                              /* calculate new line offset to the first line */
1306  pConsoleBuffer->ulScrollLineOffset += ulLines;
1307  pConsoleBuffer->ulScrollLineOffset %= pConsoleBuffer->coordBufferSize.Y;
1308
1309                                                   /* do we have to scroll ? */
1310  if (ulLines < pConsoleBuffer->coordBufferSize.Y)
1311  {
1312    for (ulLine = 0;                                     /* do the scrolling */
1313         ulLine < ConsoleGlobals.coordWindowSize.Y;
1314         ulLine++)
1315    {
1316      ulScrollLine = (ulLine + pConsoleBuffer->ulScrollLineOffset)
1317                     % pConsoleBuffer->coordBufferSize.Y;
1318
1319      ulPosition = (ULONG)pConsoleBuffer->ppszLine
1320                   + (pConsoleBuffer->coordBufferSize.Y * sizeof (PSZ) )
1321                   + (pConsoleBuffer->coordBufferSize.X * 2 * ulScrollLine);
1322
1323      pConsoleBuffer->ppszLine[ulLine] = (PSZ)ulPosition;
1324    }
1325  }
1326
1327                                                  /* enforce the upper limit */
1328  if (ulLines > pConsoleBuffer->coordBufferSize.Y)
1329    ulLines = pConsoleBuffer->coordBufferSize.Y;
1330
1331  ulPosition = ( ((ULONG)(pConsoleBuffer->ucDefaultAttribute) << 8) +
1332                 ((ULONG)' ') +
1333                 ((ULONG)(pConsoleBuffer->ucDefaultAttribute) << 24) +
1334                 ((ULONG)' ' << 16) );
1335
1336                                                    /* scroll the line index */
1337  for (ulLine = pConsoleBuffer->coordBufferSize.Y - ulLines;
1338       ulLine < pConsoleBuffer->coordBufferSize.Y;
1339       ulLine++)
1340    iConsoleBufferFillLine(ulPosition,
1341                           (PUSHORT)(pConsoleBuffer->ppszLine[ulLine]),
1342                           pConsoleBuffer->coordBufferSize.X);
1343
1344    /* this code ensures frequent screen updating, even if the timer prooves */
1345                                                            /* to be to slow */
1346  ulUpdateCounter++;
1347  if (ulUpdateCounter > ConsoleGlobals.Options.ulUpdateLimit)
1348  {
1349    ulUpdateCounter = 0;                                /* reset the counter */
1350    iConsoleBufferMap(pConsoleBuffer);
1351    VioShowPS(ConsoleGlobals.coordWindowSize.Y,
1352              ConsoleGlobals.coordWindowSize.X,
1353              0,
1354              ConsoleGlobals.hvpsConsole);
1355
1356    ConsoleGlobals.fUpdateRequired = FALSE;          /* no more required ... */
1357  }
1358}
1359
1360
1361/*****************************************************************************
1362 * Name      : static APIRET ConsoleInputEventPush
1363 * Purpose   : add an element to the console input queue
1364 * Parameters: PINPUT_RECORD pInputRecord
1365 * Variables :
1366 * Result    : API returncode
1367 * Remark    :
1368 * Status    :
1369 *
1370 * Author    : Patrick Haller [Tue, 1998/03/07 16:55]
1371 *****************************************************************************/
1372
1373APIRET iConsoleInputEventPush(PINPUT_RECORD pInputRecord)
1374{
1375  PINPUT_RECORD pirFree;                           /* pointer to free record */
1376  APIRET        rc;                                        /* API-returncode */
1377
1378  dprintf2(("KERNEL32/CONSOLE:ConsoleInputEventPush(%08x).\n",
1379           pInputRecord));
1380
1381  iConsoleInputQueueLock();
1382                                                           /* get free event */
1383  pirFree = &ConsoleInput.arrInputRecord[ConsoleInput.ulIndexFree];
1384  if (pirFree->EventType != 0x0000)
1385  {
1386    iConsoleInputQueueUnlock();
1387    return (ERROR_QUE_NO_MEMORY);                         /* queue is full ! */
1388  }
1389                                                       /* put event in queue */
1390
1391  ConsoleInput.ulIndexFree++;                        /* update index counter */
1392  if (ConsoleInput.ulIndexFree >= CONSOLE_INPUTQUEUESIZE)
1393    ConsoleInput.ulIndexFree = 0;
1394
1395  ConsoleInput.ulEvents++;                   /* increate queue event counter */
1396
1397  iConsoleInputQueueUnlock();
1398
1399  memcpy(pirFree,                                               /* copy data */
1400         pInputRecord,
1401         sizeof (INPUT_RECORD) );
1402
1403  if(flVioConsole == FALSE)
1404  {     /* unblock reading threads */
1405        rc = DosPostEventSem(ConsoleInput.hevInputQueue);
1406  }
1407  else  rc = 0;
1408  return (rc);                                                         /* OK */
1409}
1410
1411
1412/*****************************************************************************
1413 * Name      : static APIRET ConsoleInputEventPop
1414 * Purpose   : read first element from the console input queue
1415 * Parameters: PINPUT_RECORD pInputRecord
1416 * Variables :
1417 * Result    : API returncode
1418 * Remark    :
1419 * Status    :
1420 *
1421 * Author    : Patrick Haller [Tue, 1998/03/07 16:55]
1422 *****************************************************************************/
1423
1424APIRET iConsoleInputEventPop(PINPUT_RECORD pInputRecord)
1425{
1426  PINPUT_RECORD pirEvent;                         /* pointer to event record */
1427  APIRET        rc;                                        /* API-returncode */
1428
1429  dprintf2(("KERNEL32/CONSOLE:ConsoleInputEventPop(%08x).\n",
1430           pInputRecord));
1431
1432  if (ConsoleInput.ulEvents == 0)                         /* empty console ? */
1433    return (ERROR_QUE_EMPTY);                            /* queue is empty ! */
1434
1435  iConsoleInputQueueLock();
1436                                                          /* get first event */
1437  pirEvent = &ConsoleInput.arrInputRecord[ConsoleInput.ulIndexEvent];
1438  if (pirEvent->EventType == 0x0000)
1439  {
1440    iConsoleInputQueueUnlock();
1441    return (ERROR_QUE_EMPTY);                            /* queue is empty ! */
1442  }
1443
1444  if (ConsoleInput.ulEvents >= 0)       /* decrease number of console events */
1445    ConsoleInput.ulEvents--;
1446
1447  ConsoleInput.ulIndexEvent++;                       /* update index counter */
1448  if (ConsoleInput.ulIndexEvent >= CONSOLE_INPUTQUEUESIZE)
1449    ConsoleInput.ulIndexEvent = 0;
1450
1451                                                       /* put event in queue */
1452  memcpy(pInputRecord,                                          /* copy data */
1453         pirEvent,
1454         sizeof (INPUT_RECORD) );
1455
1456  pirEvent->EventType = 0x0000;                 /* mark event as read = free */
1457
1458  iConsoleInputQueueUnlock();
1459
1460  return (NO_ERROR);                                                   /* OK */
1461}
1462
1463
1464/*****************************************************************************
1465 * Name      : static APIRET ConsoleInputEventPushKey
1466 * Purpose   : push key event into the queue
1467 * Parameters: MPARAM mp1, MPARAM mp2 from WM_CHAR processing
1468 * Variables :
1469 * Result    : API returncode
1470 * Remark    : @@@PH: 2nd table that learns codes automatically from "down"
1471 *                    messages from PM. With Alt-a, etc. it is 0 for "up" ?
1472 * Status    :
1473 *
1474 * Author    : Patrick Haller [Tue, 1998/03/07 16:55]
1475 *****************************************************************************/
1476
1477char tabVirtualKeyCodes[TABVIRTUALKEYCODES] =
1478{
1479/* --- PM key -- NT key --- */
1480   /*              0x00 */ 0,
1481   /* VK_BUTTON1   0x01 */ 0x01, /* WIN_VK_LBUTTON ??? */
1482   /* VK_BUTTON2   0x02 */ 0x02, /* WIN_VK_RBUTTON ??? */
1483   /* VK_BUTTON3   0x03 */ 0x04, /* WIN_VK_MBUTTON ??? */
1484   /* VK_BREAK     0x04 */ 0x03, /* WIN_VK_CANCEL  ??? */
1485   /* VK_BACKSPACE 0x05 */ 0x08, /* WIN_VK_BACK    */
1486   /* VK_TAB       0x06 */ 0x09, /* WIN_VK_TAB     */
1487   /* VK_BACKTAB   0x07 */ 0,
1488   /* VK_NEWLINE   0x08 */ 0,
1489   /* VK_SHIFT     0x09 */ 0x10, /* WIN_VK_SHIFT   */
1490   /* VK_CTRL      0x0A */ 0x11, /* WIN_VK_CONTROL */
1491   /* VK_ALT       0x0B */ 0x12, /* WIN_VK_MENU    */
1492   /* VK_ALTGRAF   0x0C */ 0,
1493   /* VK_PAUSE     0x0D */ 0x13, /* WIN_VK_PAUSE   */
1494   /* VK_CAPSLOCK  0x0E */ 0x14, /* WIN_VK_CAPITAL ??? */
1495   /* VK_ESC       0x0F */ 0x1b, /* WIN_VK_ESCAPE  */
1496   /* VK_SPACE     0x10 */ 0x20, /* WIN_VK_SPACE   */
1497   /* VK_PAGEUP    0x11 */ 0x21, /* WIN_VK_PRIOR   ??? */
1498   /* VK_PAGEDOWN  0x12 */ 0x22, /* WIN_VK_NEXT    ??? */
1499   /* VK_END       0x13 */ 0x23, /* WIN_VK_END     */
1500   /* VK_HOME      0x14 */ 0x24, /* WIN_VK_HOME    */
1501   /* VK_LEFT      0x15 */ 0x25, /* WIN_VK_LEFT    */
1502   /* VK_UP        0x16 */ 0x26, /* WIN_VK_UP      */
1503   /* VK_RIGHT     0x17 */ 0x27, /* WIN_VK_RIGHT   */
1504   /* VK_DOWN      0x18 */ 0x28, /* WIN_VK_DOWN    */
1505   /* VK_PRINTSCRN 0x19 */ 0x2A, /* WIN_VK_PRINT   */
1506   /* VK_INSERT    0x1A */ 0x2D, /* WIN_VK_INSERT  */
1507   /* VK_DELETE    0x1B */ 0x2E, /* WIN_VK_DELETE  */
1508   /* VK_SCRLLOCK  0x1C */ 0x91, /* WIN_VK_SCROLL  */
1509   /* VK_NUMLOCK   0x1D */ 0x90, /* WIN_VK_NUMLOCK */
1510   /* VK_ENTER     0x1E */ 0x0D, /* WIN_VK_RETURN  */
1511   /* VK_SYSRQ     0x1F */ 0,
1512   /* VK_F1        0x20 */ 0x70, /* WIN_VK_F1      */
1513   /* VK_F2        0x21 */ 0x71, /* WIN_VK_F2      */
1514   /* VK_F3        0x22 */ 0x72, /* WIN_VK_F3      */
1515   /* VK_F4        0x23 */ 0x73, /* WIN_VK_F4      */
1516   /* VK_F5        0x24 */ 0x74, /* WIN_VK_F5      */
1517   /* VK_F6        0x25 */ 0x75, /* WIN_VK_F6      */
1518   /* VK_F7        0x26 */ 0x76, /* WIN_VK_F7      */
1519   /* VK_F8        0x27 */ 0x77, /* WIN_VK_F8      */
1520   /* VK_F9        0x28 */ 0x78, /* WIN_VK_F9      */
1521   /* VK_F10       0x29 */ 0x79, /* WIN_VK_F10     */
1522   /* VK_F11       0x2A */ 0x7A, /* WIN_VK_F11     */
1523   /* VK_F12       0x2B */ 0x7B, /* WIN_VK_F12     */
1524   /* VK_F13       0x2C */ 0x7C, /* WIN_VK_F13     */
1525   /* VK_F14       0x2D */ 0x7D, /* WIN_VK_F14     */
1526   /* VK_F15       0x2E */ 0x7E, /* WIN_VK_F15     */
1527   /* VK_F16       0x2F */ 0x7F, /* WIN_VK_F16     */
1528   /* VK_F17       0x30 */ 0x80, /* WIN_VK_F17     */
1529   /* VK_F18       0x31 */ 0x81, /* WIN_VK_F18     */
1530   /* VK_F19       0x32 */ 0x82, /* WIN_VK_F19     */
1531   /* VK_F20       0x33 */ 0x83, /* WIN_VK_F20     */
1532   /* VK_F21       0x34 */ 0x84, /* WIN_VK_F21     */
1533   /* VK_F22       0x35 */ 0x85, /* WIN_VK_F22     */
1534   /* VK_F23       0x36 */ 0x86, /* WIN_VK_F23     */
1535   /* VK_F24       0x37 */ 0x87, /* WIN_VK_F24     */
1536   /* VK_ENDDRAG   0x38 */ 0,
1537   /* VK_CLEAR     0x39 */ 0x0C, /* WIN_VK_CLEAR   */
1538   /* VK_EREOF     0x3A */ 0xF9, /* WIN_VK_EREOF   */
1539   /* VK_PA1       0x3B */ 0xFD, /* WIN_VK_PA1     */
1540   /* VK_ATTN      0x3C */ 0xF6, /* WIN_VK_ATTN    */
1541   /* VK_CRSEL     0x3D */ 0xF7, /* WIN_VK_CRSEL   */
1542   /* VK_EXSEL     0x3E */ 0xF8, /* WIN_VK_EXSEL   */
1543   /* VK_COPY      0x3F */ 0,
1544   /* VK_BLK1      0x40 */ 0,
1545   /* VK_BLK2      0x41 */ 0,
1546   /*              0x42 */ 0,
1547   /*              0x43 */ 0,
1548   /*              0x44 */ 0,
1549   /*              0x45 */ 0,
1550   /*              0x46 */ 0,
1551   /*              0x47 */ 0,
1552   /*              0x48 */ 0,
1553   /*              0x49 */ 0,
1554   /*              0x4A */ 0,
1555   /*              0x4B */ 0,
1556   /*              0x4C */ 0,
1557   /*              0x4D */ 0,
1558   /*              0x4E */ 0,
1559   /*              0x4F */ 0,
1560   /* from UNIKBD.H:             */
1561   /* VK_PA2              0x0050 */ 0,
1562   /* VK_PA3              0x0051 */ 0,
1563   /* VK_GROUP            0x0052 */ 0,
1564   /* VK_GROUPLOCK        0x0053 */ 0,
1565   /* VK_APPL             0x0054 */ 0x5D, /* WIN_VK_APPS ??? */
1566   /* VK_WINLEFT          0x0055 */ 0x5B, /* WIN_VK_LWIN */
1567   /* VK_WINRIGHT         0x0056 */ 0x5C, /* WIN_VK_RWIN */
1568   /*                     0x0057 */ 0,
1569   /*                     0x0058 */ 0,
1570   /*                     0x0059 */ 0,
1571   /*                     0x005A */ 0,
1572   /*                     0x005B */ 0,
1573   /*                     0x005C */ 0,
1574   /*                     0x005D */ 0,
1575   /*                     0x005E */ 0,
1576   /*                     0x005F */ 0,
1577   /*                     0x0060 */ 0,
1578   /* VK_M_DOWNLEFT       0x0061 */ 0,
1579   /* VK_M_DOWN           0x0062 */ 0,
1580   /* VK_M_DOWNRIGHT      0x0063 */ 0,
1581   /* VK_M_LEFT           0x0064 */ 0,
1582   /* VK_M_CENTER         0x0065 */ 0,
1583   /* VK_M_RIGHT          0x0066 */ 0,
1584   /* VK_M_UPLEFT         0x0067 */ 0,
1585   /* VK_M_UP             0x0068 */ 0,
1586   /* VK_M_UPRIGHT        0x0069 */ 0,
1587   /* VK_M_BUTTONLOCK     0x006A */ 0,
1588   /* VK_M_BUTTONRELEASE  0x006B */ 0,
1589   /* VK_M_DOUBLECLICK    0x006C */ 0,
1590
1591#if 0
15920xA4, /* WIN_VK_LMENU   ??? */
15930xA5, /* WIN_VK_RMENU   ??? */
1594#define VK_SELECT         0x29
1595#define VK_EXECUTE        0x2B
1596#define VK_SNAPSHOT       0x2C
1597#define VK_HELP           0x2F
1598#define VK_NUMPAD0        0x60
1599#define VK_NUMPAD1        0x61
1600#define VK_NUMPAD2        0x62
1601#define VK_NUMPAD3        0x63
1602#define VK_NUMPAD4        0x64
1603#define VK_NUMPAD5        0x65
1604#define VK_NUMPAD6        0x66
1605#define VK_NUMPAD7        0x67
1606#define VK_NUMPAD8        0x68
1607#define VK_NUMPAD9        0x69
1608#define VK_MULTIPLY       0x6A
1609#define VK_ADD            0x6B
1610#define VK_SEPARATOR      0x6C
1611#define VK_SUBTRACT       0x6D
1612#define VK_DECIMAL        0x6E
1613#define VK_DIVIDE         0x6F
1614#define VK_LSHIFT         0xA0
1615#define VK_RSHIFT         0xA1
1616#define VK_LCONTROL       0xA2
1617#define VK_RCONTROL       0xA3
1618#define VK_PROCESSKEY     0xE5
1619#define VK_PLAY           0xFA
1620#define VK_ZOOM           0xFB
1621#define VK_NONAME         0xFC
1622#define VK_OEM_CLEAR      0xFE
1623#endif
1624
1625};
1626
1627
1628APIRET iConsoleInputEventPushKey(MPARAM mp1,
1629                                 MPARAM mp2)
1630{
1631  INPUT_RECORD InputRecord;                    /* the input record structure */
1632  APIRET       rc;                                         /* API-returncode */
1633  USHORT       fsFlags    = ((ULONG)mp1 & 0x0000ffff);             /* get key flags */
1634  UCHAR        ucRepeat   = ((ULONG)mp1 & 0x00ff0000) >> 16;
1635  UCHAR        ucScanCode = ((ULONG)mp1 & 0xff000000) >> 24;
1636  UCHAR        usCh       = ((ULONG)mp2 & 0x0000ffff);
1637  USHORT       usVk       = ((ULONG)mp2 & 0xffff0000) >> 16;
1638  UCHAR        ucChar     = usCh & 0x00ff;
1639
1640  dprintf2(("KERNEL32/CONSOLE:ConsoleInputEventPushKey(%08x,%08x).\n",
1641           mp1,
1642           mp2));
1643
1644
1645  InputRecord.EventType = KEY_EVENT;                 /* fill event structure */
1646  InputRecord.Event.KeyEvent.dwControlKeyState = 0;
1647
1648  if (fsFlags & KC_SHIFT) InputRecord.Event.KeyEvent.dwControlKeyState |= SHIFT_PRESSED;
1649  if (fsFlags & KC_ALT)   InputRecord.Event.KeyEvent.dwControlKeyState |= LEFT_ALT_PRESSED;
1650  if (fsFlags & KC_CTRL)  InputRecord.Event.KeyEvent.dwControlKeyState |= LEFT_CTRL_PRESSED;
1651
1652  /* @@@PH no support for RIGHT_ALT_PRESSED,
1653                          RIGHT_CTRL_PRESSED,
1654                          NUMLOCK_ON,
1655                          SCROLLLOCK_ON,
1656                          CAPSLOCK_ON,
1657                          ENHANCED_KEY
1658   */
1659
1660  InputRecord.Event.KeyEvent.bKeyDown         = !(fsFlags & KC_KEYUP);
1661  InputRecord.Event.KeyEvent.wRepeatCount     = ucRepeat;
1662  InputRecord.Event.KeyEvent.wVirtualKeyCode  = usVk;
1663  InputRecord.Event.KeyEvent.wVirtualScanCode = ucScanCode;
1664
1665             /* check if ascii is valid, if so then wVirtualKeyCode = ascii, */
1666             /* else go through the table                                    */
1667  if (fsFlags & KC_CHAR) /* usCh valid ? */
1668  {
1669          /* VK_0 thru VK_9 are the same as ASCII '0' thru '9' (0x30 - 0x39) */
1670          /* VK_A thru VK_Z are the same as ASCII 'A' thru 'Z' (0x41 - 0x5A) */
1671    if ( ( (usCh >= 'a') && (usCh <= 'z') ) ||                /* lowercase ? */
1672         ( (usCh >= '0') && (usCh <= '9') )
1673       )
1674      InputRecord.Event.KeyEvent.wVirtualKeyCode = usCh & 0xDF;
1675    else
1676      InputRecord.Event.KeyEvent.wVirtualKeyCode = usCh;
1677  }
1678  else
1679    if (fsFlags & KC_VIRTUALKEY)          /* translate OS/2 virtual key code */
1680    {
1681      if (usVk < TABVIRTUALKEYCODES)                  /* limit to table size */
1682        InputRecord.Event.KeyEvent.wVirtualKeyCode =
1683          tabVirtualKeyCodes[usVk];                     /* translate keycode */
1684    }
1685
1686                /* this is a workaround for empty / invalid wVirtualKeyCodes */
1687  if (InputRecord.Event.KeyEvent.wVirtualKeyCode == 0x0000)
1688  {
1689    if ( ( (usCh >= 'a') && (usCh <= 'z') ) ||                /* lowercase ? */
1690         ( (usCh >= '0') && (usCh <= '9') )
1691       )
1692      InputRecord.Event.KeyEvent.wVirtualKeyCode = usCh & 0xDF;
1693    else
1694      InputRecord.Event.KeyEvent.wVirtualKeyCode = usCh;
1695  }
1696
1697
1698  /* @@@PH handle special keys */
1699  if ( (ucChar != 0xe0) && (ucChar != 0x00) )
1700    InputRecord.Event.KeyEvent.uChar.AsciiChar  = ucChar;
1701  else
1702  {
1703    /* extended key ! */
1704    InputRecord.Event.KeyEvent.dwControlKeyState |= ENHANCED_KEY;
1705    InputRecord.Event.KeyEvent.uChar.AsciiChar  = (ucChar >> 8);
1706  }
1707
1708              /* further processing according the current input console mode */
1709  if (ConsoleInput.dwConsoleMode & ENABLE_PROCESSED_INPUT)
1710  {
1711    /* filter ctrl-c, etc. */
1712  }
1713
1714#if 0
1715  /* DEBUG */
1716  dprintf(("DEBUG: mp1=%08x mp2=%08x\n",
1717           mp1,
1718           mp2));
1719  dprintf(("DEBUG: fsFlags = %04x repeat=%u hwscan=%2x",
1720           fsFlags,
1721           ucRepeat,
1722           ucScanCode ));
1723  dprintf((" uscc=%04x usvk=%04x\n",
1724           SHORT1FROMMP(mp2),
1725           SHORT2FROMMP(mp2)));
1726
1727  dprintf(("DEBUG: ascii=[%c] (%02x)",
1728           InputRecord.Event.KeyEvent.uChar.AsciiChar,
1729           InputRecord.Event.KeyEvent.uChar.AsciiChar));
1730#endif
1731
1732  rc = iConsoleInputEventPush(&InputRecord);          /* add it to the queue */
1733  return (rc);                                                         /* OK */
1734}
1735
1736
1737/*****************************************************************************
1738 * Name      : static APIRET ConsoleInputEventPushMouse
1739 * Purpose   : push mouse event into the queue
1740 * Parameters: MPARAM mp1, MPARAM mp2 from WM_MOUSEMOVE processing
1741 * Variables :
1742 * Result    : API returncode
1743 * Remark    :
1744 * Status    :
1745 *
1746 * Author    : Patrick Haller [Tue, 1998/03/07 16:55]
1747 *****************************************************************************/
1748
1749APIRET iConsoleInputEventPushMouse(ULONG  ulMessage,
1750                                   MPARAM mp1,
1751                                   MPARAM mp2)
1752{
1753  INPUT_RECORD     InputRecord;                /* the input record structure */
1754  APIRET             rc;                                   /* API-returncode */
1755  USHORT             fsFlags = SHORT2FROMMP(mp2);           /* get key flags */
1756  static USHORT      usButtonState;     /* keeps track of mouse button state */
1757
1758                                      /* do we have to process mouse input ? */
1759  if ( !(ConsoleInput.dwConsoleMode & ENABLE_MOUSE_INPUT))
1760    return (NO_ERROR);                                 /* return immediately */
1761
1762  dprintf2(("KERNEL32/CONSOLE:ConsoleInputEventPushMouse(%08x,%08x,%08x).\n",
1763           ulMessage,
1764           mp1,
1765           mp2));
1766
1767  memset(&InputRecord,                                 /* zero the structure */
1768         0,
1769         sizeof (INPUT_RECORD) );
1770
1771  InputRecord.EventType = MOUSE_EVENT;               /* fill event structure */
1772
1773  switch (ulMessage)
1774  {
1775    case WM_MOUSEMOVE:
1776      InputRecord.Event.MouseEvent.dwEventFlags      = MOUSE_MOVED;
1777      InputRecord.Event.MouseEvent.dwMousePosition.X = SHORT1FROMMP(mp1);
1778      InputRecord.Event.MouseEvent.dwMousePosition.Y = SHORT2FROMMP(mp1);
1779
1780      InputRecord.Event.MouseEvent.dwButtonState     = usButtonState;
1781
1782      if (fsFlags & KC_SHIFT) InputRecord.Event.MouseEvent.dwControlKeyState |= SHIFT_PRESSED;
1783      if (fsFlags & KC_ALT)   InputRecord.Event.MouseEvent.dwControlKeyState |= LEFT_ALT_PRESSED;
1784      if (fsFlags & KC_CTRL)  InputRecord.Event.MouseEvent.dwControlKeyState |= LEFT_CTRL_PRESSED;
1785
1786      /* @@@PH no support for RIGHT_ALT_PRESSED,
1787                              RIGHT_CTRL_PRESSED,
1788                              NUMLOCK_ON,
1789                              SCROLLLOCK_ON,
1790                              CAPSLOCK_ON,
1791                              ENHANCED_KEY
1792       */
1793      break;
1794
1795    case WM_BUTTON1UP:
1796      usButtonState            &= ~FROM_LEFT_1ST_BUTTON_PRESSED;
1797      InputRecord.Event.MouseEvent.dwButtonState = usButtonState;
1798      break;
1799
1800    case WM_BUTTON1DOWN:
1801      usButtonState            |=  FROM_LEFT_1ST_BUTTON_PRESSED;
1802      InputRecord.Event.MouseEvent.dwButtonState = usButtonState;
1803      break;
1804
1805    case WM_BUTTON2UP:
1806      usButtonState &= ~FROM_LEFT_2ND_BUTTON_PRESSED;
1807      InputRecord.Event.MouseEvent.dwButtonState = usButtonState;
1808      break;
1809
1810    case WM_BUTTON2DOWN:
1811      usButtonState |= FROM_LEFT_2ND_BUTTON_PRESSED;
1812      InputRecord.Event.MouseEvent.dwButtonState = usButtonState;
1813      break;
1814
1815    case WM_BUTTON3UP:
1816      usButtonState &= ~FROM_LEFT_3RD_BUTTON_PRESSED;
1817      InputRecord.Event.MouseEvent.dwButtonState = usButtonState;
1818      break;
1819
1820    case WM_BUTTON3DOWN:
1821      usButtonState |=  FROM_LEFT_3RD_BUTTON_PRESSED;
1822      InputRecord.Event.MouseEvent.dwButtonState = usButtonState;
1823      break;
1824
1825    case WM_BUTTON1DBLCLK:
1826      InputRecord.Event.MouseEvent.dwEventFlags = DOUBLE_CLICK;
1827      InputRecord.Event.MouseEvent.dwButtonState = FROM_LEFT_1ST_BUTTON_PRESSED;
1828      usButtonState &= ~FROM_LEFT_1ST_BUTTON_PRESSED;
1829      break;
1830
1831    case WM_BUTTON2DBLCLK:
1832      InputRecord.Event.MouseEvent.dwEventFlags = DOUBLE_CLICK;
1833      InputRecord.Event.MouseEvent.dwButtonState = FROM_LEFT_2ND_BUTTON_PRESSED;
1834      usButtonState &= ~FROM_LEFT_2ND_BUTTON_PRESSED;
1835      break;
1836
1837    case WM_BUTTON3DBLCLK:
1838      InputRecord.Event.MouseEvent.dwEventFlags = DOUBLE_CLICK;
1839      InputRecord.Event.MouseEvent.dwButtonState = FROM_LEFT_3RD_BUTTON_PRESSED;
1840      usButtonState &= ~FROM_LEFT_3RD_BUTTON_PRESSED;
1841      break;
1842  }
1843
1844                        /* @@@PH pseudo-support for RIGHTMOST_BUTTON_PRESSED */
1845  if (InputRecord.Event.MouseEvent.dwButtonState & FROM_LEFT_3RD_BUTTON_PRESSED)
1846    InputRecord.Event.MouseEvent.dwButtonState |= RIGHTMOST_BUTTON_PRESSED;
1847
1848  rc = iConsoleInputEventPush(&InputRecord);          /* add it to the queue */
1849  return (rc);                                                         /* OK */
1850}
1851
1852
1853/*****************************************************************************
1854 * Name      : static APIRET ConsoleInputEventPushWindow
1855 * Purpose   : push menu event into the queue
1856 * Parameters: DWORD dwCommandId
1857 * Variables :
1858 * Result    : API returncode
1859 * Remark    :
1860 * Status    :
1861 *
1862 * Author    : Patrick Haller [Tue, 1998/03/07 16:55]
1863 *****************************************************************************/
1864
1865APIRET iConsoleInputEventPushWindow(COORD coordWindowSize)
1866{
1867  INPUT_RECORD     InputRecord;                /* the input record structure */
1868  APIRET           rc;                                     /* API-returncode */
1869
1870                                     /* do we have to process window input ? */
1871  if ( !(ConsoleInput.dwConsoleMode & ENABLE_WINDOW_INPUT))
1872    return (NO_ERROR);                                 /* return immediately */
1873
1874  dprintf2(("KERNEL32/CONSOLE:ConsoleInputEventPushWindow(x = %u, y = %u).\n",
1875           coordWindowSize.X,
1876           coordWindowSize.Y));
1877
1878  InputRecord.EventType = WINDOW_BUFFER_SIZE_EVENT;  /* fill event structure */
1879
1880  InputRecord.Event.WindowBufferSizeEvent.dwSize = coordWindowSize;
1881
1882  rc = iConsoleInputEventPush(&InputRecord);          /* add it to the queue */
1883  return (rc);                                                         /* OK */
1884}
1885
1886
1887/*****************************************************************************
1888 * Name      : static APIRET ConsoleInputEventPushMenu
1889 * Purpose   : push window event into the queue
1890 * Parameters: COORD coordWindowSize
1891 * Variables :
1892 * Result    : API returncode
1893 * Remark    :
1894 * Status    :
1895 *
1896 * Author    : Patrick Haller [Tue, 1998/03/07 16:55]
1897 *****************************************************************************/
1898
1899APIRET iConsoleInputEventPushMenu(DWORD dwCommandId)
1900{
1901  INPUT_RECORD     InputRecord;                /* the input record structure */
1902  APIRET           rc;                                     /* API-returncode */
1903
1904  /* @@@PH this is unknown to me - there's no separate bit for menu events ? */
1905                                     /* do we have to process window input ? */
1906  if ( !(ConsoleInput.dwConsoleMode & ENABLE_WINDOW_INPUT))
1907    return (NO_ERROR);                                 /* return immediately */
1908
1909  dprintf2(("KERNEL32/CONSOLE:ConsoleInputEventPushMenu(%08x).\n",
1910           dwCommandId));
1911
1912  InputRecord.EventType = MENU_EVENT;                /* fill event structure */
1913
1914  InputRecord.Event.MenuEvent.dwCommandId = dwCommandId;
1915
1916  rc = iConsoleInputEventPush(&InputRecord);          /* add it to the queue */
1917  return (rc);                                                         /* OK */
1918}
1919
1920
1921/*****************************************************************************
1922 * Name      : static APIRET ConsoleInputEventPushFocus
1923 * Purpose   : push focus event into the queue
1924 * Parameters: BOOL bSetFocus
1925 * Variables :
1926 * Result    : API returncode
1927 * Remark    :
1928 * Status    :
1929 *
1930 * Author    : Patrick Haller [Tue, 1998/03/07 16:55]
1931 *****************************************************************************/
1932
1933APIRET iConsoleInputEventPushFocus(BOOL bSetFocus)
1934{
1935  INPUT_RECORD     InputRecord;                /* the input record structure */
1936  APIRET           rc;                                     /* API-returncode */
1937
1938  /* @@@PH this is unknown to me - there's no separate bit for menu events ? */
1939                                     /* do we have to process window input ? */
1940  if ( !(ConsoleInput.dwConsoleMode & ENABLE_WINDOW_INPUT))
1941    return (NO_ERROR);                                 /* return immediately */
1942
1943  dprintf2(("KERNEL32/CONSOLE:ConsoleInputEventPushFocus(%08x).\n",
1944           bSetFocus));
1945
1946  InputRecord.EventType = FOCUS_EVENT;               /* fill event structure */
1947
1948  InputRecord.Event.FocusEvent.bSetFocus = bSetFocus;
1949
1950  rc = iConsoleInputEventPush(&InputRecord);          /* add it to the queue */
1951  return (rc);                                                         /* OK */
1952}
1953
1954
1955/*****************************************************************************
1956 * Name      : static ULONG ConsoleInputQueueEvents
1957 * Purpose   : query number of events in the queue
1958 * Parameters:
1959 * Variables :
1960 * Result    : number of events
1961 * Remark    :
1962 * Status    :
1963 *
1964 * Author    : Patrick Haller [Tue, 1998/03/07 16:55]
1965 *****************************************************************************/
1966
1967ULONG iConsoleInputQueryEvents(PICONSOLEINPUT pConsoleInput, int fWait)
1968{
1969 ULONG ulPostCounter;                   /* semaphore post counter - ignored */
1970 APIRET rc;                                               /* API returncode */
1971
1972  if(flVioConsole)
1973  {
1974    KBDKEYINFO keyinfo;
1975
1976        rc = KbdCharIn(&keyinfo, IO_NOWAIT, 0); //grab key if present; don't wait
1977        if((rc || !(keyinfo.fbStatus & 0x40)) && fWait == QUERY_EVENT_WAIT && ConsoleInput.ulEvents == 0) {
1978                rc = KbdCharIn(&keyinfo, IO_WAIT, 0);
1979        }
1980        while(rc == 0 && (keyinfo.fbStatus & 0x40))
1981        {
1982                INPUT_RECORD InputRecord = {0};
1983
1984                InputRecord.EventType = KEY_EVENT;
1985                InputRecord.Event.KeyEvent.wRepeatCount = 1;
1986                InputRecord.Event.KeyEvent.bKeyDown     = 1;
1987                InputRecord.Event.KeyEvent.dwControlKeyState = 0;
1988
1989                if(keyinfo.fbStatus & 2)
1990                        InputRecord.Event.KeyEvent.dwControlKeyState |= ENHANCED_KEY;
1991
1992                if(keyinfo.fsState & (KBDSTF_RIGHTSHIFT|KBDSTF_LEFTSHIFT))
1993                        InputRecord.Event.KeyEvent.dwControlKeyState |= SHIFT_PRESSED;
1994
1995                if(keyinfo.fsState & KBDSTF_LEFTALT)
1996                        InputRecord.Event.KeyEvent.dwControlKeyState |= LEFT_ALT_PRESSED;
1997
1998                if(keyinfo.fsState & KBDSTF_RIGHTALT)
1999                        InputRecord.Event.KeyEvent.dwControlKeyState |= RIGHT_ALT_PRESSED;
2000
2001                if(keyinfo.fsState & KBDSTF_LEFTCONTROL)
2002                    InputRecord.Event.KeyEvent.dwControlKeyState |= LEFT_CTRL_PRESSED;
2003
2004                if(keyinfo.fsState & KBDSTF_RIGHTCONTROL)
2005                    InputRecord.Event.KeyEvent.dwControlKeyState |= RIGHT_CTRL_PRESSED;
2006
2007                if(keyinfo.fsState & KBDSTF_CAPSLOCK_ON)
2008                    InputRecord.Event.KeyEvent.dwControlKeyState |= CAPSLOCK_ON;
2009
2010                if(keyinfo.fsState & KBDSTF_SCROLLLOCK_ON)
2011                    InputRecord.Event.KeyEvent.dwControlKeyState |= SCROLLLOCK_ON;
2012
2013                if(keyinfo.fsState & KBDSTF_NUMLOCK_ON)
2014                    InputRecord.Event.KeyEvent.dwControlKeyState |= NUMLOCK_ON;
2015
2016                InputRecord.Event.KeyEvent.wVirtualKeyCode  = 0;
2017                InputRecord.Event.KeyEvent.wVirtualScanCode = keyinfo.chScan;
2018                InputRecord.Event.KeyEvent.uChar.AsciiChar  = keyinfo.chChar;
2019
2020                rc = iConsoleInputEventPush(&InputRecord);          /* add it to the queue */
2021                if(rc) {
2022                    dprintf(("WARNING: lost key!!"));
2023                    break;
2024                }
2025
2026                rc = KbdCharIn(&keyinfo, IO_NOWAIT, 0); //grab key if present; don't wait
2027        }
2028  }
2029  else
2030  if(fWait == QUERY_EVENT_WAIT && ConsoleInput.ulEvents == 0)
2031  {
2032        rc = DosWaitEventSem(pConsoleInput->hevInputQueue,      /* wait for input */
2033                             SEM_INDEFINITE_WAIT);
2034        DosResetEventSem(pConsoleInput->hevInputQueue,         /* reset semaphore */
2035                         &ulPostCounter);              /* post counter - ignored */
2036  }
2037  return (ConsoleInput.ulEvents);        /* return number of events in queue */
2038}
2039
2040
2041/*****************************************************************************
2042 * Name      : static void ConsoleCursorShow
2043 * Purpose   : query number of events in the queue
2044 * Parameters:
2045 * Variables :
2046 * Result    : number of events
2047 * Remark    :
2048 * Status    :
2049 *
2050 * Author    : Patrick Haller [Tue, 1998/03/07 16:55]
2051 *****************************************************************************/
2052
2053void iConsoleCursorShow (PCONSOLEBUFFER pConsoleBuffer,
2054                         ULONG          ulCursorMode)
2055{
2056  HPS   hps;                                    /* presentation space handle */
2057  RECTL rclCursor;                                   /* the cursor rectangle */
2058  static BOOL fState;                                /* current cursor state */
2059  RECTL rclWindow;                                    /* current window size */
2060
2061  dprintf2(("KERNEL32:Console:ConsoleCursorShow(%u)\n",
2062           ulCursorMode));
2063
2064  if (pConsoleBuffer->CursorInfo.bVisible == FALSE)/* cursor is switched off */
2065    return;                                            /* return immediately */
2066
2067  switch (ulCursorMode)
2068  {
2069    case CONSOLECURSOR_HIDE:
2070      if (fState == FALSE)                       /* cursor currently shown ? */
2071        return;                                     /* no, abort immediately */
2072      else
2073        fState = FALSE;       /* set to invisible and invert our cursor rect */
2074      break;
2075
2076    case CONSOLECURSOR_SHOW:
2077      if (fState == TRUE)                        /* cursor currently shown ? */
2078        return;                                     /* yes,abort immediately */
2079      else
2080        fState = TRUE;          /* set to visible and invert our cursor rect */
2081      break;
2082
2083    case CONSOLECURSOR_BLINK:
2084      fState = !fState;      /* let there be on off on off on off on off ... */
2085      break;
2086
2087    case CONSOLECURSOR_OVERWRITTEN:       /* our cursor has been overwritten */
2088      fState = TRUE;                       /* so show the cursor immediately */
2089      break;
2090  }
2091
2092
2093                                              /* query current window's size */
2094  WinQueryWindowRect(ConsoleGlobals.hwndClient,
2095                     &rclWindow);
2096
2097                                      /* calculate coordinates of the cursor */
2098  rclCursor.xLeft   = ConsoleGlobals.sCellCX * pConsoleBuffer->coordCursorPosition.X;
2099  rclCursor.xRight  = rclCursor.xLeft + ConsoleGlobals.sCellCX;
2100
2101  //@@@PH top calculation is wrong!
2102  rclCursor.yBottom = rclWindow.yTop
2103                      - ConsoleGlobals.sCellCY * (pConsoleBuffer->coordCursorPosition.Y + 1);
2104  rclCursor.yTop    = rclCursor.yBottom +        /* cursor height in percent */
2105                      (ConsoleGlobals.sCellCY *
2106                       pConsoleBuffer->CursorInfo.dwSize /
2107                       100);
2108
2109  hps = WinGetPS(ConsoleGlobals.hwndClient);                      /* get HPS */
2110
2111  /* @@@PH invert coordinates here ... */
2112  WinInvertRect(hps,                  /* our cursor is an inverted rectangle */
2113                &rclCursor);
2114
2115  WinReleasePS(hps);                                /* release the hps again */
2116}
2117
2118
2119/*****************************************************************************
2120 * Name      : static APIRET ConsoleFontQuery
2121 * Purpose   : queries the current font cell sizes
2122 * Parameters:
2123 * Variables :
2124 * Result    : API returncode
2125 * Remark    :
2126 * Status    :
2127 *
2128 * Author    : Patrick Haller [Tue, 1998/03/07 16:55]
2129 *****************************************************************************/
2130
2131APIRET iConsoleFontQuery (void)
2132{
2133  return(VioGetDeviceCellSize(&ConsoleGlobals.sCellCY,  /* query VIO manager */
2134                              &ConsoleGlobals.sCellCX,
2135                              ConsoleGlobals.hvpsConsole));
2136}
2137
2138
2139/*****************************************************************************
2140 * Name      : static void ConsoleCursorShow
2141 * Purpose   : query number of events in the queue
2142 * Parameters:
2143 * Variables :
2144 * Result    : number of events
2145 * Remark    : called during INIT, FONTCHANGE, RESIZE, BUFFERCHANGE
2146 * Status    :
2147 *
2148 * Author    : Patrick Haller [Wed, 1998/04/29 16:55]
2149 *****************************************************************************/
2150
2151void iConsoleAdjustWindow (PCONSOLEBUFFER pConsoleBuffer)
2152{
2153  LONG   lX, lY;                                    /* temporary long values */
2154  RECTL  rcl;
2155  PRECTL pRcl = &rcl;
2156  ULONG  flStyle;                              /* window frame control style */
2157
2158  BOOL fNeedVertScroll;                      /* indicates need of scrollbars */
2159  BOOL fNeedHorzScroll;
2160
2161  LONG lScrollX;                           /* width and height of scrollbars */
2162  LONG lScrollY;
2163
2164                                         /* now calculate actual window size */
2165  lX = ConsoleGlobals.sCellCX * ConsoleGlobals.coordWindowSize.X;
2166  lY = ConsoleGlobals.sCellCY * ConsoleGlobals.coordWindowSize.Y;
2167
2168  if ( (ConsoleGlobals.sCellCX == 0) ||          /* prevent division by zero */
2169       (ConsoleGlobals.sCellCY == 0) )
2170    return;
2171
2172         /* calculate maximum console window size in pixels for the tracking */
2173  ConsoleGlobals.coordMaxWindowPels.X = ConsoleGlobals.sCellCX * pConsoleBuffer->coordWindowSize.X
2174                                        + WinQuerySysValue(HWND_DESKTOP, SV_CXSIZEBORDER) * 2;
2175
2176  ConsoleGlobals.coordMaxWindowPels.Y = ConsoleGlobals.sCellCY * pConsoleBuffer->coordWindowSize.Y
2177                                        + WinQuerySysValue(HWND_DESKTOP, SV_CYSIZEBORDER) * 2
2178                                        + WinQuerySysValue(HWND_DESKTOP, SV_CYTITLEBAR);
2179
2180  /***************************/
2181  /* @@@PH broken code below */
2182  /***************************/
2183  return;
2184
2185                             /* add the window border height and width, etc. */
2186  WinQueryWindowRect (ConsoleGlobals.hwndClient,
2187                      pRcl);
2188
2189                                                   /* calculate visible area */
2190   /* calculate real client window rectangle and take care of the scrollbars */
2191  lScrollX = WinQuerySysValue(HWND_DESKTOP, SV_CXVSCROLL);
2192  lScrollY = WinQuerySysValue(HWND_DESKTOP, SV_CYHSCROLL);
2193  if (ConsoleGlobals.fHasHorzScroll)
2194  {
2195    lY += lScrollY;
2196    ConsoleGlobals.coordMaxWindowPels.Y += lScrollY;
2197  }
2198
2199  if (ConsoleGlobals.fHasVertScroll)
2200  {
2201    lX += lScrollX;
2202    ConsoleGlobals.coordMaxWindowPels.X += lScrollX;
2203  }
2204
2205  /* @@@PH might NOT exceed maximum VioPS size ! */
2206  ConsoleGlobals.coordWindowSize.X = (pRcl->xRight - pRcl->xLeft)
2207                                     / ConsoleGlobals.sCellCX;
2208
2209  ConsoleGlobals.coordWindowSize.Y = (pRcl->yTop   - pRcl->yBottom)
2210                                     / ConsoleGlobals.sCellCY;
2211
2212                                    /* do we have to enable the scrollbars ? */
2213  fNeedHorzScroll = lX < pConsoleBuffer->coordWindowSize.X * ConsoleGlobals.sCellCX;
2214  fNeedVertScroll = lY < pConsoleBuffer->coordWindowSize.Y * ConsoleGlobals.sCellCY;
2215
2216
2217  if ( (ConsoleGlobals.fHasVertScroll != fNeedVertScroll) ||
2218       (ConsoleGlobals.fHasHorzScroll != fNeedHorzScroll) )
2219  {
2220    flStyle = WinQueryWindowULong(ConsoleGlobals.hwndFrame,
2221                                  QWL_STYLE);
2222
2223                                           /* now set or remove the controls */
2224    if (ConsoleGlobals.fHasHorzScroll != fNeedHorzScroll)
2225      if (fNeedHorzScroll)
2226      {
2227        flStyle |= FCF_HORZSCROLL;
2228        WinSetParent(ConsoleGlobals.hwndHorzScroll,        /* attach control */
2229                     ConsoleGlobals.hwndFrame,
2230                     FALSE);
2231      }
2232      else
2233      {
2234        flStyle &= ~FCF_HORZSCROLL;
2235        WinSetParent(ConsoleGlobals.hwndHorzScroll,        /* detach control */
2236                     HWND_OBJECT,
2237                     FALSE);
2238        ConsoleGlobals.coordWindowPos.X = 0;    /* we can see the whole buffer */
2239      }
2240
2241    if (ConsoleGlobals.fHasVertScroll != fNeedVertScroll)
2242      if (fNeedVertScroll)
2243      {
2244        flStyle |= FCF_VERTSCROLL;
2245        WinSetParent(ConsoleGlobals.hwndVertScroll,        /* attach control */
2246                     ConsoleGlobals.hwndFrame,
2247                     FALSE);
2248      }
2249      else
2250      {
2251        flStyle &= ~FCF_VERTSCROLL;
2252        WinSetParent(ConsoleGlobals.hwndVertScroll,        /* detach control */
2253                     HWND_OBJECT,
2254                     FALSE);
2255        ConsoleGlobals.coordWindowPos.Y = 0;  /* we can see the whole buffer */
2256      }
2257
2258
2259    WinSendMsg(ConsoleGlobals.hwndFrame,                     /* update frame */
2260               WM_UPDATEFRAME,
2261               MPFROMLONG(flStyle),
2262               MPVOID);
2263
2264    WinInvalidateRect(ConsoleGlobals.hwndFrame,       /* redraw frame window */
2265                      NULL,
2266                      TRUE);
2267
2268    ConsoleGlobals.fHasVertScroll = fNeedVertScroll;       /* update globals */
2269    ConsoleGlobals.fHasHorzScroll = fNeedHorzScroll;       /* update globals */
2270  }
2271
2272
2273                                    /* setup the scrollbars and scrollranges */
2274  if (ConsoleGlobals.fHasVertScroll)
2275  {
2276    /* setup vertical scrollbar */
2277  }
2278
2279
2280  if (ConsoleGlobals.fHasHorzScroll)
2281  {
2282    /* setup horizonal scrollbar */
2283  }
2284
2285
2286  WinCalcFrameRect(ConsoleGlobals.hwndFrame,    /* calculate frame rectangle */
2287                   pRcl,
2288                   FALSE);
2289
2290  /* @@@PH client may not overlap frame ! */
2291  /* @@@PH write values to TRACKINFO      */
2292
2293#if 0
2294  /* @@@PH this results in recursion */
2295  WinSetWindowPos (ConsoleGlobals.hwndClient,   /* adjust client window size */
2296                   ConsoleGlobals.hwndFrame,
2297                   0,
2298                   0,
2299                   lX,
2300                   lY,
2301                   SWP_SIZE);
2302
2303  WinSetWindowPos (ConsoleGlobals.hwndFrame,    /* adjust client window size */
2304                   HWND_DESKTOP,
2305                   pRcl->xLeft,
2306                   pRcl->yBottom,
2307                   pRcl->xRight,
2308                   pRcl->yTop,
2309                   SWP_SIZE);
2310#endif
2311}
2312
2313extern "C" {
2314
2315/*****************************************************************************
2316 * Name      : BOOL WIN32API AllocConsole
2317 * Purpose   : The AllocConsole function allocates a new console
2318 *             for the calling process
2319 * Parameters: VOID
2320 * Variables :
2321 * Result    : BOOL: TRUE  - function succeeded
2322 *                   FALSE - function failed. Extended error information
2323 *                           obtainable via GetLastError
2324 * Remark    :
2325 * Status    : REWRITTEN UNTESTED
2326 *
2327 * Author    : Patrick Haller [Tue, 1998/02/10 01:55]
2328 *****************************************************************************/
2329
2330BOOL WIN32API AllocConsole(VOID)
2331{
2332  APIRET rc;                                               /* API returncode */
2333
2334  dprintf(("KERNEL32/CONSOLE: OS2AllocConsole() called"));
2335
2336  rc = iConsoleInit(flVioConsole);               /* initialize subsystem if required */
2337  if (rc != NO_ERROR)                            /* check for errors */
2338  {
2339    SetLastError(rc);                            /* pass thru the error code */
2340    return FALSE;                                          /* signal failure */
2341  }
2342  else
2343    return TRUE;                                                /* Fine ! :) */
2344}
2345
2346
2347/*****************************************************************************
2348 * Name      : HANDLE WIN32API CreateConsoleScreenBuffer
2349 * Purpose   : The CreateConsoleScreenBuffer function creates a console
2350 *             screen buffer and returns a handle of it.
2351 * Parameters: DWORD  dwDesiredAccess    - access flag
2352 *             DWORD  dwShareMode        - buffer share more
2353 *             PVOID  pIgnored           - LPSECURITY_ATTRIBUTES -> NT
2354 *             DWORD  dwFlags            - type of buffer to create
2355 *             LPVOID lpScreenBufferData - reserved
2356 * Variables :
2357 * Result    :
2358 * Remark    : a console buffer is a kernel heap object equipped with
2359 *             share modes, access rights, etc.
2360 *             we can't really map this to OS/2 unless we build a
2361 *             console device driver for it ... maybe this turns out to
2362 *             be necessary since we've got to handle CONIN$ and CONOUT$, too.
2363 * Status    :
2364 *
2365 * Author    : Patrick Haller [Tue, 1998/02/10 03:55]
2366 *****************************************************************************/
2367
2368HANDLE WIN32API CreateConsoleScreenBuffer(DWORD  dwDesiredAccess,
2369                                          DWORD  dwShareMode,
2370                                          LPVOID lpSecurityAttributes,
2371                                          DWORD  dwFlags,
2372                                          LPVOID lpScreenBufferData)
2373{
2374  HANDLE hResult;
2375
2376  hResult = HMCreateFile("CONBUFFER$",         /* create a new buffer handle */
2377                         dwDesiredAccess,
2378                         dwShareMode,
2379                         (LPSECURITY_ATTRIBUTES)lpSecurityAttributes,
2380                         0,
2381                         dwFlags,
2382                         INVALID_HANDLE_VALUE);
2383
2384  return hResult;
2385}
2386
2387
2388/*****************************************************************************
2389 * Name      :
2390 * Purpose   :
2391 * Parameters:
2392 * Variables :
2393 * Result    :
2394 * Remark    :
2395 * Status    :
2396 *
2397 * Author    : Patrick Haller [Tue, 1998/02/10 01:55]
2398 *****************************************************************************/
2399
2400BOOL WIN32API FillConsoleOutputAttribute(HANDLE  hConsoleOutput,
2401                                            WORD    wAttribute,
2402                                            DWORD   nLength,
2403                                            COORD   dwWriteCoord,
2404                                            LPDWORD lpNumberOfAttrsWritten)
2405{
2406  BOOL fResult;
2407
2408  fResult = (BOOL)HMDeviceRequest(hConsoleOutput,
2409                                  DRQ_FILLCONSOLEOUTPUTATTRIBUTE,
2410                                  (ULONG)wAttribute,
2411                                  (ULONG)nLength,
2412                                  COORD2ULONG(dwWriteCoord),
2413                                  (ULONG)lpNumberOfAttrsWritten);
2414
2415  return fResult;
2416}
2417
2418
2419/*****************************************************************************
2420 * Name      :
2421 * Purpose   :
2422 * Parameters:
2423 * Variables :
2424 * Result    :
2425 * Remark    :
2426 * Status    :
2427 *
2428 * Author    : Patrick Haller [Tue, 1998/02/10 01:55]
2429 *****************************************************************************/
2430
2431BOOL WIN32API FillConsoleOutputCharacterA(HANDLE  hConsoleOutput,
2432                                             UCHAR   cCharacter,
2433                                             DWORD   nLength,
2434                                             COORD   dwWriteCoord,
2435                                             LPDWORD lpNumberOfCharsWritten )
2436{
2437  BOOL fResult;
2438
2439  fResult = (BOOL)HMDeviceRequest(hConsoleOutput,
2440                                  DRQ_FILLCONSOLEOUTPUTCHARACTERA,
2441                                  (ULONG)cCharacter,
2442                                  (ULONG)nLength,
2443                                  COORD2ULONG(dwWriteCoord),
2444                                  (ULONG)lpNumberOfCharsWritten);
2445
2446  return fResult;
2447}
2448
2449
2450/*****************************************************************************
2451 * Name      :
2452 * Purpose   :
2453 * Parameters:
2454 * Variables :
2455 * Result    :
2456 * Remark    :
2457 * Status    :
2458 *
2459 * Author    : Patrick Haller [Tue, 1998/02/10 01:55]
2460 *****************************************************************************/
2461
2462BOOL WIN32API FillConsoleOutputCharacterW(HANDLE  hConsoleOutput,
2463                                             WCHAR   cCharacter,
2464                                             DWORD   nLength,
2465                                             COORD   dwWriteCoord,
2466                                             LPDWORD lpNumberOfCharsWritten )
2467{
2468  BOOL fResult;
2469
2470  fResult = (BOOL)HMDeviceRequest(hConsoleOutput,
2471                                  DRQ_FILLCONSOLEOUTPUTCHARACTERW,
2472                                  (ULONG)cCharacter,
2473                                  (ULONG)nLength,
2474                                  COORD2ULONG(dwWriteCoord),
2475                                  (ULONG)lpNumberOfCharsWritten);
2476
2477  return fResult;
2478}
2479
2480
2481/*****************************************************************************
2482 * Name      :
2483 * Purpose   :
2484 * Parameters:
2485 * Variables :
2486 * Result    :
2487 * Remark    :
2488 * Status    :
2489 *
2490 * Author    : Patrick Haller [Tue, 1998/02/10 01:55]
2491 *****************************************************************************/
2492
2493BOOL WIN32API FlushConsoleInputBuffer( HANDLE hConsoleInput )
2494{
2495  BOOL fResult;
2496
2497  fResult = (BOOL)HMDeviceRequest(hConsoleInput,
2498                                  DRQ_FLUSHCONSOLEINPUTBUFFER,
2499                                  0,
2500                                  0,
2501                                  0,
2502                                  0);
2503
2504  return fResult;
2505}
2506
2507
2508/*****************************************************************************
2509 * Name      : BOOL WIN32API FreeConsole
2510 * Purpose   : The FreeConsole function detaches the calling process
2511 *             from its console.
2512 * Parameters: VOID
2513 * Variables :
2514 * Result    : BOOL: TRUE  - function succeeded
2515 *                   FALSE - function failed. Extended error information
2516 *                           obtainable via GetLastError
2517 * Remark    :
2518 * Status    : REWRITTEN UNTESTED
2519 *
2520 * Author    : Patrick Haller [Tue, 1998/02/10 03:35]
2521 *****************************************************************************/
2522
2523BOOL WIN32API FreeConsole( VOID )
2524{
2525  APIRET rc;                                               /* API returncode */
2526
2527  rc = iConsoleTerminate();               /* terminate subsystem if required */
2528  if (rc != NO_ERROR)                                    /* check for errors */
2529  {
2530    SetLastError(rc);                            /* pass thru the error code */
2531    return FALSE;                                          /* signal failure */
2532  }
2533  else
2534    return TRUE;                                                /* Fine ! :) */
2535
2536  return TRUE;
2537}
2538
2539
2540/*****************************************************************************
2541 * Name      :
2542 * Purpose   :
2543 * Parameters:
2544 * Variables :
2545 * Result    :
2546 * Remark    :
2547 * Status    :
2548 *
2549 * Author    : Patrick Haller [Tue, 1998/02/10 01:55]
2550 *****************************************************************************/
2551
2552UINT WIN32API GetConsoleCP(VOID)
2553{
2554  dprintf(("KERNEL32/CONSOLE: GetConsoleCP not implemented"));
2555
2556  return 1;
2557}
2558
2559
2560/*****************************************************************************
2561 * Name      :
2562 * Purpose   :
2563 * Parameters:
2564 * Variables :
2565 * Result    :
2566 * Remark    :
2567 * Status    :
2568 *
2569 * Author    : Patrick Haller [Tue, 1998/02/10 01:55]
2570 *****************************************************************************/
2571
2572BOOL WIN32API GetConsoleCursorInfo(HANDLE               hConsoleOutput,
2573                                      PCONSOLE_CURSOR_INFO lpConsoleCursorInfo)
2574{
2575  BOOL fResult;
2576
2577  fResult = (BOOL)HMDeviceRequest(hConsoleOutput,
2578                                  DRQ_GETCONSOLECURSORINFO,
2579                                  (ULONG)lpConsoleCursorInfo,
2580                                  0,
2581                                  0,
2582                                  0);
2583
2584  return fResult;
2585}
2586
2587
2588/*****************************************************************************
2589 * Name      :
2590 * Purpose   :
2591 * Parameters:
2592 * Variables :
2593 * Result    :
2594 * Remark    :
2595 * Status    :
2596 *
2597 * Author    : Patrick Haller [Tue, 1998/02/10 01:55]
2598 *****************************************************************************/
2599
2600BOOL WIN32API GetConsoleMode(HANDLE  hConsole,
2601                                LPDWORD lpMode)
2602{
2603  BOOL fResult;
2604
2605  fResult = (BOOL)HMDeviceRequest(hConsole,
2606                                  DRQ_GETCONSOLEMODE,
2607                                  (ULONG) lpMode,
2608                                  0,
2609                                  0,
2610                                  0);
2611
2612  return fResult;
2613}
2614
2615
2616/*****************************************************************************
2617 * Name      :
2618 * Purpose   :
2619 * Parameters:
2620 * Variables :
2621 * Result    :
2622 * Remark    :
2623 * Status    :
2624 *
2625 * Author    : Patrick Haller [Tue, 1998/02/10 01:55]
2626 *****************************************************************************/
2627
2628UINT WIN32API GetConsoleOutputCP(VOID)
2629{
2630  dprintf(("KERNEL32/CONSOLE: GetConsoleOutputCP not implemented"));
2631
2632  return 1;
2633}
2634
2635
2636/*****************************************************************************
2637 * Name      :
2638 * Purpose   :
2639 * Parameters:
2640 * Variables :
2641 * Result    :
2642 * Remark    :
2643 * Status    :
2644 *
2645 * Author    : Patrick Haller [Tue, 1998/02/10 01:55]
2646 *****************************************************************************/
2647
2648BOOL WIN32API GetConsoleScreenBufferInfo(HANDLE                      hConsoleOutput,
2649                                         PCONSOLE_SCREEN_BUFFER_INFO lpConsoleScreenBufferInfo)
2650{
2651  BOOL fResult;
2652
2653  fResult = (BOOL)HMDeviceRequest(hConsoleOutput,
2654                                  DRQ_GETCONSOLESCREENBUFFERINFO,
2655                                  (ULONG)lpConsoleScreenBufferInfo,
2656                                  0,
2657                                  0,
2658                                  0);
2659
2660  return fResult;
2661}
2662
2663
2664/*****************************************************************************
2665 * Name      : DWORD WIN32API GetConsoleTitle
2666 * Purpose   : Query the current console window title
2667 * Parameters: LPTSTR lpConsoleTitle
2668 *             DWORD  nSize
2669 * Variables :
2670 * Result    : number of copied bytes
2671 * Remark    :
2672 * Status    : REWRITTEN UNTESTED
2673 *
2674 * Author    : Patrick Haller [Thu, 1998/02/12 23:31]
2675 *****************************************************************************/
2676
2677DWORD WIN32API GetConsoleTitleA(LPTSTR lpConsoleTitle,
2678                                DWORD  nSize)
2679{
2680  ULONG ulLength;                                          /* length of text */
2681
2682  if (ConsoleGlobals.pszWindowTitle == NULL)    /* is there a window title ? */
2683    return 0;                                           /* abort immediately */
2684
2685  ulLength = strlen(ConsoleGlobals.pszWindowTitle);        /* length of text */
2686
2687  strncpy(lpConsoleTitle,
2688          ConsoleGlobals.pszWindowTitle,
2689          nSize);
2690  lpConsoleTitle[nSize-1] = 0;
2691
2692  return (nSize < ulLength) ? nSize : ulLength;
2693}
2694
2695
2696/*****************************************************************************
2697 * Name      : DWORD WIN32API GetConsoleTitle
2698 * Purpose   : Query the current console window title
2699 * Parameters: LPTSTR lpConsoleTitle
2700 *             DWORD  nSize
2701 * Variables :
2702 * Result    : number of copied bytes
2703 * Remark    :
2704 * Status    : REWRITTEN UNTESTED
2705 *
2706 * Author    : Patrick Haller [Thu, 1998/02/12 23:31]
2707 *****************************************************************************/
2708
2709
2710DWORD WIN32API GetConsoleTitleW(LPWSTR lpConsoleTitle,
2711                                DWORD  nSize)
2712{
2713  if (ConsoleGlobals.pszWindowTitle == NULL)    /* is there a window title ? */
2714    return 0;                                           /* abort immediately */
2715
2716  MultiByteToWideChar( GetConsoleCP(), 0, ConsoleGlobals.pszWindowTitle, -1,
2717        lpConsoleTitle, nSize );
2718  lpConsoleTitle[ nSize - 1 ] = 0;
2719
2720  return lstrlenW( lpConsoleTitle );
2721}
2722
2723
2724/*****************************************************************************
2725 * Name      : COORD WIN32API GetLargestConsoleWindowSize
2726 * Purpose   : Determine maximum AVIO size
2727 * Parameters:
2728 * Variables :
2729 * Result    :
2730 * Remark    :
2731 * Status    :
2732 *
2733 * Author    : Patrick Haller [Tue, 1998/02/10 01:55]
2734 *****************************************************************************/
2735
2736COORD WIN32API GetLargestConsoleWindowSize(HANDLE hConsoleOutput)
2737{
2738  DWORD dwResult;
2739  COORD coordResult;
2740
2741  dwResult = HMDeviceRequest(hConsoleOutput,
2742                             DRQ_GETLARGESTCONSOLEWINDOWSIZE,
2743                             0,
2744                             0,
2745                             0,
2746                             0);
2747
2748  ULONG2COORD(coordResult,dwResult)
2749  return ( coordResult );
2750}
2751
2752
2753/*****************************************************************************
2754 * Name      :
2755 * Purpose   :
2756 * Parameters:
2757 * Variables :
2758 * Result    :
2759 * Remark    :
2760 * Status    :
2761 *
2762 * Author    : Patrick Haller [Tue, 1998/02/10 01:55]
2763 *****************************************************************************/
2764
2765BOOL WIN32API GetNumberOfConsoleInputEvents(HANDLE  hConsoleInput,
2766                                            LPDWORD lpNumberOfEvents)
2767{
2768  BOOL fResult;
2769
2770  fResult = (BOOL)HMDeviceRequest(hConsoleInput,
2771                                  DRQ_GETNUMBEROFCONSOLEINPUTEVENTS,
2772                                  (ULONG)lpNumberOfEvents,
2773                                  0,
2774                                  0,
2775                                  0);
2776
2777  return fResult;
2778}
2779
2780
2781/*****************************************************************************
2782 * Name      :
2783 * Purpose   :
2784 * Parameters:
2785 * Variables :
2786 * Result    :
2787 * Remark    :
2788 * Status    :
2789 *
2790 * Author    : Patrick Haller [Tue, 1998/02/10 01:55]
2791 *****************************************************************************/
2792
2793BOOL WIN32API GetNumberOfConsoleMouseButtons(LPDWORD lpcNumberOfMouseButtons)
2794{
2795  LONG lMouseButtons;
2796
2797  lMouseButtons = WinQuerySysValue(HWND_DESKTOP,        /* query PM for that */
2798                                   SV_CMOUSEBUTTONS);
2799
2800  *lpcNumberOfMouseButtons = (DWORD)lMouseButtons;
2801
2802  return TRUE;
2803}
2804
2805
2806/*****************************************************************************
2807 * Name      :
2808 * Purpose   :
2809 * Parameters:
2810 * Variables :
2811 * Result    :
2812 * Remark    :
2813 * Status    :
2814 *
2815 * Author    : Patrick Haller [Tue, 1998/02/10 01:55]
2816 *****************************************************************************/
2817
2818BOOL WIN32API PeekConsoleInputW(HANDLE        hConsoleInput,
2819                                   PINPUT_RECORD pirBuffer,
2820                                   DWORD         cInRecords,
2821                                   LPDWORD       lpcRead)
2822{
2823  BOOL fResult;
2824
2825  fResult = (BOOL)HMDeviceRequest(hConsoleInput,
2826                                  DRQ_PEEKCONSOLEINPUTW,
2827                                  (ULONG)pirBuffer,
2828                                  (ULONG)cInRecords,
2829                                  (ULONG)lpcRead,
2830                                  0);
2831
2832  return fResult;
2833}
2834
2835
2836/*****************************************************************************
2837 * Name      :
2838 * Purpose   :
2839 * Parameters:
2840 * Variables :
2841 * Result    :
2842 * Remark    :
2843 * Status    :
2844 *
2845 * Author    : Patrick Haller [Tue, 1998/02/10 01:55]
2846 *****************************************************************************/
2847
2848BOOL WIN32API PeekConsoleInputA(HANDLE        hConsoleInput,
2849                                PINPUT_RECORD pirBuffer,
2850                                DWORD         cInRecords,
2851                                LPDWORD       lpcRead)
2852{
2853  BOOL fResult;
2854
2855  fResult = (BOOL)HMDeviceRequest(hConsoleInput,
2856                                  DRQ_PEEKCONSOLEINPUTA,
2857                                  (ULONG)pirBuffer,
2858                                  (ULONG)cInRecords,
2859                                  (ULONG)lpcRead,
2860                                  0);
2861
2862  return fResult;
2863}
2864
2865
2866/*****************************************************************************
2867 * Name      :
2868 * Purpose   :
2869 * Parameters:
2870 * Variables :
2871 * Result    :
2872 * Remark    :
2873 * Status    :
2874 *
2875 * Author    : Patrick Haller [Tue, 1998/02/10 01:55]
2876 *****************************************************************************/
2877
2878BOOL WIN32API ReadConsoleA(HANDLE  hConsoleInput,
2879                           LPVOID  lpvBuffer,
2880                           DWORD   cchToRead,
2881                           LPDWORD lpcchRead,
2882                           LPVOID  lpvReserved)
2883{
2884  BOOL fResult;
2885
2886  fResult = (BOOL)HMDeviceRequest(hConsoleInput,
2887                                  DRQ_READCONSOLEA,
2888                                  (ULONG)lpvBuffer,
2889                                  (ULONG)cchToRead,
2890                                  (ULONG)lpcchRead,
2891                                  (ULONG)lpvReserved);
2892
2893  return fResult;
2894}
2895
2896
2897/*****************************************************************************
2898 * Name      :
2899 * Purpose   :
2900 * Parameters:
2901 * Variables :
2902 * Result    :
2903 * Remark    :
2904 * Status    :
2905 *
2906 * Author    : Patrick Haller [Tue, 1998/02/10 01:55]
2907 *****************************************************************************/
2908
2909BOOL WIN32API ReadConsoleW(HANDLE  hConsoleInput,
2910                           LPVOID  lpvBuffer,
2911                           DWORD   cchToRead,
2912                           LPDWORD lpcchRead,
2913                           LPVOID  lpvReserved)
2914{
2915  BOOL fResult;
2916
2917  fResult = (BOOL)HMDeviceRequest(hConsoleInput,
2918                                  DRQ_READCONSOLEW,
2919                                  (ULONG)lpvBuffer,
2920                                  (ULONG)cchToRead,
2921                                  (ULONG)lpcchRead,
2922                                  (ULONG)lpvReserved);
2923
2924  return fResult;
2925}
2926
2927
2928/*****************************************************************************
2929 * Name      :
2930 * Purpose   :
2931 * Parameters:
2932 * Variables :
2933 * Result    :
2934 * Remark    :
2935 * Status    :
2936 *
2937 * Author    : Patrick Haller [Tue, 1998/02/10 01:55]
2938 *****************************************************************************/
2939
2940BOOL WIN32API ReadConsoleInputA(HANDLE        hConsoleInput,
2941                                PINPUT_RECORD pirBuffer,
2942                                DWORD         cInRecords,
2943                                LPDWORD       lpcRead)
2944{
2945  BOOL fResult;
2946
2947  fResult = (BOOL)HMDeviceRequest(hConsoleInput,
2948                                  DRQ_READCONSOLEINPUTA,
2949                                  (ULONG)pirBuffer,
2950                                  (ULONG)cInRecords,
2951                                  (ULONG)lpcRead,
2952                                  0);
2953
2954  return fResult;
2955}
2956
2957
2958/*****************************************************************************
2959 * Name      :
2960 * Purpose   :
2961 * Parameters:
2962 * Variables :
2963 * Result    :
2964 * Remark    :
2965 * Status    :
2966 *
2967 * Author    : Patrick Haller [Tue, 1998/02/10 01:55]
2968 *****************************************************************************/
2969
2970BOOL WIN32API ReadConsoleInputW(HANDLE        hConsoleInput,
2971                                PINPUT_RECORD pirBuffer,
2972                                DWORD         cInRecords,
2973                                LPDWORD       lpcRead)
2974{
2975  BOOL fResult;
2976
2977  fResult = (BOOL)HMDeviceRequest(hConsoleInput,
2978                                  DRQ_READCONSOLEINPUTW,
2979                                  (ULONG)pirBuffer,
2980                                  (ULONG)cInRecords,
2981                                  (ULONG)lpcRead,
2982                                  0);
2983
2984  return fResult;
2985}
2986
2987
2988/*****************************************************************************
2989 * Name      :
2990 * Purpose   :
2991 * Parameters:
2992 * Variables :
2993 * Result    :
2994 * Remark    :
2995 * Status    :
2996 *
2997 * Author    : Patrick Haller [Tue, 1998/02/10 01:55]
2998 *****************************************************************************/
2999
3000BOOL WIN32API ReadConsoleOutputA(HANDLE      hConsoleOutput,
3001                                 PCHAR_INFO  pchiDestBuffer,
3002                                 COORD       coordDestBufferSize,
3003                                 COORD       coordDestBufferCoord,
3004                                 PSMALL_RECT psrctSourceRect)
3005{
3006  BOOL fResult;
3007
3008  fResult = (BOOL)HMDeviceRequest(hConsoleOutput,
3009                                  DRQ_READCONSOLEOUTPUTA,
3010                                  (ULONG)pchiDestBuffer,
3011                                  COORD2ULONG(coordDestBufferSize),
3012                                  COORD2ULONG(coordDestBufferCoord),
3013                                  (ULONG)psrctSourceRect);
3014
3015  return fResult;
3016}
3017
3018
3019/*****************************************************************************
3020 * Name      :
3021 * Purpose   :
3022 * Parameters:
3023 * Variables :
3024 * Result    :
3025 * Remark    :
3026 * Status    :
3027 *
3028 * Author    : Patrick Haller [Tue, 1998/02/10 01:55]
3029 *****************************************************************************/
3030
3031BOOL WIN32API ReadConsoleOutputW(HANDLE      hConsoleOutput,
3032                                 PCHAR_INFO  pchiDestBuffer,
3033                                 COORD       coordDestBufferSize,
3034                                 COORD       coordDestBufferCoord,
3035                                 PSMALL_RECT psrctSourceRect)
3036{
3037  BOOL fResult;
3038
3039  fResult = (BOOL)HMDeviceRequest(hConsoleOutput,
3040                                  DRQ_READCONSOLEOUTPUTW,
3041                                  (ULONG)pchiDestBuffer,
3042                                  COORD2ULONG(coordDestBufferSize),
3043                                  COORD2ULONG(coordDestBufferCoord),
3044                                  (ULONG)psrctSourceRect);
3045
3046  return fResult;
3047}
3048
3049
3050/*****************************************************************************
3051 * Name      :
3052 * Purpose   :
3053 * Parameters:
3054 * Variables :
3055 * Result    :
3056 * Remark    :
3057 * Status    :
3058 *
3059 * Author    : Patrick Haller [Tue, 1998/02/10 01:55]
3060 *****************************************************************************/
3061
3062BOOL WIN32API ReadConsoleOutputAttribute(HANDLE  hConsoleOutput,
3063                                         LPWORD  lpwAttribute,
3064                                         DWORD   cReadCells,
3065                                         COORD   coordReadCoord,
3066                                         LPDWORD lpcNumberRead)
3067{
3068  BOOL fResult;
3069
3070  fResult = (BOOL)HMDeviceRequest(hConsoleOutput,
3071                                  DRQ_READCONSOLEOUTPUTATTRIBUTE,
3072                                  (ULONG)lpwAttribute,
3073                                  (ULONG)cReadCells,
3074                                  COORD2ULONG(coordReadCoord),
3075                                  (ULONG)lpcNumberRead);
3076
3077  return fResult;
3078}
3079
3080
3081/*****************************************************************************
3082 * Name      :
3083 * Purpose   :
3084 * Parameters:
3085 * Variables :
3086 * Result    :
3087 * Remark    :
3088 * Status    :
3089 *
3090 * Author    : Patrick Haller [Tue, 1998/02/10 01:55]
3091 *****************************************************************************/
3092
3093BOOL WIN32API ReadConsoleOutputCharacterA(HANDLE  hConsoleOutput,
3094                                          LPTSTR  lpReadBuffer,
3095                                          DWORD   cchRead,
3096                                          COORD   coordReadCoord,
3097                                          LPDWORD lpcNumberRead)
3098{
3099  BOOL fResult;
3100
3101  fResult = (BOOL)HMDeviceRequest(hConsoleOutput,
3102                                  DRQ_READCONSOLEOUTPUTCHARACTERA,
3103                                  (ULONG)lpReadBuffer,
3104                                  (ULONG)cchRead,
3105                                  COORD2ULONG(coordReadCoord),
3106                                  (ULONG)lpcNumberRead);
3107
3108  return fResult;
3109}
3110
3111
3112/*****************************************************************************
3113 * Name      :
3114 * Purpose   :
3115 * Parameters:
3116 * Variables :
3117 * Result    :
3118 * Remark    :
3119 * Status    :
3120 *
3121 * Author    : Patrick Haller [Tue, 1998/02/10 01:55]
3122 *****************************************************************************/
3123
3124BOOL WIN32API ReadConsoleOutputCharacterW(HANDLE  hConsoleOutput,
3125                                          LPTSTR  lpReadBuffer,
3126                                          DWORD   cchRead,
3127                                          COORD   coordReadCoord,
3128                                          LPDWORD lpcNumberRead)
3129{
3130  BOOL fResult;
3131
3132  fResult = (BOOL)HMDeviceRequest(hConsoleOutput,
3133                                  DRQ_READCONSOLEOUTPUTCHARACTERW,
3134                                  (ULONG)lpReadBuffer,
3135                                  (ULONG)cchRead,
3136                                  COORD2ULONG(coordReadCoord),
3137                                  (ULONG)lpcNumberRead);
3138
3139  return fResult;
3140}
3141
3142
3143/*****************************************************************************
3144 * Name      :
3145 * Purpose   :
3146 * Parameters:
3147 * Variables :
3148 * Result    :
3149 * Remark    :
3150 * Status    :
3151 *
3152 * Author    : Patrick Haller [Tue, 1998/02/10 01:55]
3153 *****************************************************************************/
3154
3155BOOL WIN32API ScrollConsoleScreenBufferA(HANDLE      hConsoleOutput,
3156                                         PSMALL_RECT psrctSourceRect,
3157                                         PSMALL_RECT psrctClipRect,
3158                                         COORD       coordDestOrigin,
3159                                         PCHAR_INFO  pchiFill)
3160{
3161  BOOL fResult;
3162
3163  fResult = (BOOL)HMDeviceRequest(hConsoleOutput,
3164                                  DRQ_SCROLLCONSOLESCREENBUFFERA,
3165                                  (ULONG)psrctSourceRect,
3166                                  (ULONG)psrctClipRect,
3167                                  COORD2ULONG(coordDestOrigin),
3168                                  (ULONG)pchiFill);
3169
3170  return fResult;
3171}
3172
3173
3174/*****************************************************************************
3175 * Name      :
3176 * Purpose   :
3177 * Parameters:
3178 * Variables :
3179 * Result    :
3180 * Remark    :
3181 * Status    :
3182 *
3183 * Author    : Patrick Haller [Tue, 1998/02/10 01:55]
3184 *****************************************************************************/
3185
3186BOOL WIN32API ScrollConsoleScreenBufferW(HANDLE      hConsoleOutput,
3187                                         PSMALL_RECT psrctSourceRect,
3188                                         PSMALL_RECT psrctClipRect,
3189                                         COORD       coordDestOrigin,
3190                                         PCHAR_INFO  pchiFill)
3191{
3192  BOOL fResult;
3193
3194  fResult = (BOOL)HMDeviceRequest(hConsoleOutput,
3195                                  DRQ_SCROLLCONSOLESCREENBUFFERW,
3196                                  (ULONG)psrctSourceRect,
3197                                  (ULONG)psrctClipRect,
3198                                  COORD2ULONG(coordDestOrigin),
3199                                  (ULONG)pchiFill);
3200
3201  return fResult;
3202}
3203
3204/*****************************************************************************
3205 * Name      :
3206 * Purpose   :
3207 * Parameters:
3208 * Variables :
3209 * Result    :
3210 * Remark    :
3211 * Status    :
3212 *
3213 * Author    : Patrick Haller [Tue, 1998/02/10 01:55]
3214 *****************************************************************************/
3215
3216BOOL WIN32API SetConsoleActiveScreenBuffer(HANDLE hConsoleOutput)
3217{
3218  BOOL fResult;
3219
3220  fResult = (BOOL)HMDeviceRequest(hConsoleOutput,
3221                                  DRQ_SETCONSOLEACTIVESCREENBUFFER,
3222                                  0,
3223                                  0,
3224                                  0,
3225                                  0);
3226
3227  return fResult;
3228}
3229
3230
3231/*****************************************************************************
3232 * Name      :
3233 * Purpose   :
3234 * Parameters:
3235 * Variables :
3236 * Result    :
3237 * Remark    :
3238 * Status    :
3239 *
3240 * Author    : Patrick Haller [Tue, 1998/02/10 01:55]
3241 *****************************************************************************/
3242
3243BOOL WIN32API SetConsoleCP(UINT IDCodePage)
3244{
3245  dprintf(("KERNEL32/CONSOLE: SetConsoleCP(%08x) not implemented.\n",
3246           IDCodePage));
3247
3248  return TRUE;
3249}
3250
3251
3252/*****************************************************************************
3253 * Name      :
3254 * Purpose   :
3255 * Parameters:
3256 * Variables :
3257 * Result    :
3258 * Remark    :
3259 * Status    :
3260 *
3261 * Author    : Patrick Haller [Tue, 1998/02/10 01:55]
3262 *****************************************************************************/
3263
3264BOOL WIN32API SetConsoleCursorInfo(HANDLE               hConsoleOutput,
3265                                      PCONSOLE_CURSOR_INFO lpConsoleCursorInfo)
3266{
3267  BOOL fResult;
3268
3269  fResult = (BOOL)HMDeviceRequest(hConsoleOutput,
3270                                  DRQ_SETCONSOLECURSORINFO,
3271                                  (ULONG)lpConsoleCursorInfo,
3272                                  0,
3273                                  0,
3274                                  0);
3275
3276  return fResult;
3277}
3278
3279
3280/*****************************************************************************
3281 * Name      :
3282 * Purpose   :
3283 * Parameters:
3284 * Variables :
3285 * Result    :
3286 * Remark    :
3287 * Status    :
3288 *
3289 * Author    : Patrick Haller [Tue, 1998/02/10 01:55]
3290
3291 *****************************************************************************/
3292
3293BOOL WIN32API SetConsoleCursorPosition(HANDLE hConsoleOutput,
3294                                          COORD  coordCursor)
3295{
3296  BOOL fResult;
3297
3298  fResult = (BOOL)HMDeviceRequest(hConsoleOutput,
3299                                  DRQ_SETCONSOLECURSORPOSITION,
3300                                  COORD2ULONG(coordCursor),
3301                                  0,
3302                                  0,
3303                                  0);
3304
3305  return fResult;
3306}
3307
3308
3309/*****************************************************************************
3310 * Name      :
3311 * Purpose   :
3312 * Parameters:
3313 * Variables :
3314 * Result    :
3315 * Remark    :
3316 * Status    :
3317 *
3318 * Author    : Patrick Haller [Tue, 1998/02/10 01:55]
3319 *****************************************************************************/
3320
3321BOOL WIN32API SetConsoleMode(HANDLE hConsole,
3322                                DWORD  fdwMode)
3323{
3324 BOOL fResult;
3325
3326  fResult = (BOOL)HMDeviceRequest(hConsole,
3327                                  DRQ_SETCONSOLEMODE,
3328                                  (ULONG)fdwMode,
3329                                  0,
3330                                  0,
3331                                  0);
3332
3333  return fResult;
3334}
3335
3336
3337/*****************************************************************************
3338 * Name      :
3339 * Purpose   :
3340 * Parameters:
3341 * Variables :
3342 * Result    :
3343 * Remark    :
3344 * Status    :
3345 *
3346 * Author    : Patrick Haller [Tue, 1998/02/10 01:55]
3347 *****************************************************************************/
3348
3349BOOL WIN32API SetConsoleOutputCP(UINT IDCodePage)
3350{
3351  dprintf(("KERNEL32/CONSOLE: OS2SetConsoleOutputCP(%08x) not implemented.\n",
3352           IDCodePage));
3353
3354  return TRUE;
3355}
3356
3357
3358/*****************************************************************************
3359 * Name      :
3360 * Purpose   :
3361 * Parameters:
3362 * Variables :
3363 * Result    :
3364 * Remark    :
3365 * Status    :
3366 *
3367 * Author    : Patrick Haller [Tue, 1998/02/10 01:55]
3368 *****************************************************************************/
3369
3370BOOL WIN32API SetConsoleScreenBufferSize(HANDLE hConsoleOutput,
3371                                            COORD  coordSize)
3372{
3373  BOOL fResult;
3374
3375  fResult = (BOOL)HMDeviceRequest(hConsoleOutput,
3376                                  DRQ_SETCONSOLESCREENBUFFERSIZE,
3377                                  COORD2ULONG(coordSize),
3378                                  0,
3379                                  0,
3380                                  0);
3381
3382  return fResult;
3383}
3384
3385
3386/*****************************************************************************
3387 * Name      :
3388 * Purpose   :
3389 * Parameters:
3390 * Variables :
3391 * Result    :
3392 * Remark    :
3393 * Status    :
3394 *
3395 * Author    : Patrick Haller [Tue, 1998/02/10 01:55]
3396 *****************************************************************************/
3397
3398BOOL WIN32API SetConsoleTextAttribute(HANDLE hConsoleOutput,
3399                                         WORD   wAttr)
3400{
3401  BOOL fResult;
3402
3403  fResult = (BOOL)HMDeviceRequest(hConsoleOutput,
3404                                  DRQ_SETCONSOLETEXTATTRIBUTE,
3405                                  (ULONG)wAttr,
3406                                  0,
3407                                  0,
3408                                  0);
3409
3410  return fResult;
3411}
3412
3413
3414/*****************************************************************************
3415 * Name      : BOOL WIN32API SetConsoleTitleA
3416 * Purpose   : Set new title text for the console window
3417 * Parameters: LPTSTR lpszTitle
3418 * Variables :
3419 * Result    :
3420 * Remark    :
3421 * Status    : REWRITTEN UNTESTED
3422 *
3423 * Author    : Patrick Haller [Tue, 1998/02/12 23:28]
3424 *****************************************************************************/
3425
3426BOOL WIN32API SetConsoleTitleA(LPTSTR lpszTitle)
3427{
3428  if (ConsoleGlobals.pszWindowTitle != NULL)           /* previously set name */
3429    free (ConsoleGlobals.pszWindowTitle);                     /* then free it */
3430
3431  ConsoleGlobals.pszWindowTitle = strdup(lpszTitle);     /* copy the new name */
3432
3433  WinSetWindowText(ConsoleGlobals.hwndFrame,           /* set new title text */
3434                   ConsoleGlobals.pszWindowTitle);
3435
3436  return TRUE;
3437}
3438
3439
3440/*****************************************************************************
3441 * Name      : BOOL WIN32API SetConsoleTitleW
3442 * Purpose   : Set new title text for the console window
3443 * Parameters: LPTSTR lpszTitle
3444 * Variables :
3445 * Result    :
3446 * Remark    :
3447 * Status    : REWRITTEN UNTESTED
3448 *
3449 * Author    : Patrick Haller [Tue, 1998/02/12 23:28]
3450 *****************************************************************************/
3451
3452BOOL WIN32API SetConsoleTitleW(LPWSTR lpszTitle)
3453{
3454  int alen;
3455
3456  if (lpszTitle == NULL)                                 /* check parameters */
3457    return FALSE;
3458
3459  if (ConsoleGlobals.pszWindowTitle != NULL)           /* previously set name */
3460    free (ConsoleGlobals.pszWindowTitle);                     /* then free it */
3461
3462  alen = WideCharToMultiByte( GetConsoleCP(), 0, lpszTitle, -1, 0, 0, 0, 0 );
3463  /* create an ascii copy of the lpszTitle */
3464  ConsoleGlobals.pszWindowTitle = (PSZ)malloc( alen );
3465  WideCharToMultiByte( GetConsoleCP(), 0, lpszTitle, -1,
3466        ConsoleGlobals.pszWindowTitle, alen, 0, 0 );
3467
3468  WinSetWindowText(ConsoleGlobals.hwndFrame,           /* set new title text */
3469                   ConsoleGlobals.pszWindowTitle);
3470
3471  return TRUE;
3472}
3473
3474
3475/*****************************************************************************
3476 * Name      :
3477 * Purpose   :
3478 * Parameters:
3479 * Variables :
3480 * Result    :
3481 * Remark    :
3482 * Status    :
3483 *
3484 * Author    : Patrick Haller [Tue, 1998/02/10 01:55]
3485 *****************************************************************************/
3486
3487BOOL WIN32API SetConsoleWindowInfo(HANDLE      hConsoleOutput,
3488                                   BOOL        fAbsolute,
3489                                   PSMALL_RECT psrctWindowRect)
3490{
3491  BOOL fResult;
3492
3493  fResult = (BOOL)HMDeviceRequest(hConsoleOutput,
3494                                  DRQ_SETCONSOLEWINDOWINFO,
3495                                  (ULONG)fAbsolute,
3496                                  (ULONG)psrctWindowRect,
3497                                  0,
3498                                  0);
3499
3500  return fResult;
3501}
3502
3503
3504/*****************************************************************************
3505 * Name      :
3506 * Purpose   :
3507 * Parameters:
3508 * Variables :
3509 * Result    :
3510 * Remark    :
3511 * Status    :
3512 *
3513 * Author    : Patrick Haller [Tue, 1998/02/10 01:55]
3514 *****************************************************************************/
3515
3516BOOL WIN32API WriteConsoleA(HANDLE      hConsoleOutput,
3517                            CONST VOID* lpvBuffer,
3518                            DWORD       cchToWrite,
3519                            LPDWORD     lpcchWritten,
3520                            LPVOID      lpvReserved)
3521{
3522  BOOL fResult;
3523
3524  fResult = (BOOL)HMDeviceRequest(hConsoleOutput,
3525                                  DRQ_WRITECONSOLEA,
3526                                  (ULONG)lpvBuffer,
3527                                  (ULONG)cchToWrite,
3528                                  (ULONG)lpcchWritten,
3529                                  (ULONG)lpvReserved);
3530
3531  return fResult;
3532}
3533
3534
3535/*****************************************************************************
3536 * Name      :
3537 * Purpose   :
3538 * Parameters:
3539 * Variables :
3540 * Result    :
3541 * Remark    :
3542 * Status    :
3543 *
3544 * Author    : Patrick Haller [Tue, 1998/02/10 01:55]
3545 *****************************************************************************/
3546
3547BOOL WIN32API WriteConsoleW(HANDLE      hConsoleOutput,
3548                            CONST VOID* lpvBuffer,
3549                            DWORD       cchToWrite,
3550                            LPDWORD     lpcchWritten,
3551                            LPVOID      lpvReserved)
3552{
3553  BOOL fResult;
3554
3555  fResult = (BOOL)HMDeviceRequest(hConsoleOutput,
3556                                  DRQ_WRITECONSOLEW,
3557                                  (ULONG)lpvBuffer,
3558                                  (ULONG)cchToWrite,
3559                                  (ULONG)lpcchWritten,
3560                                  (ULONG)lpvReserved);
3561
3562  return fResult;
3563}
3564
3565
3566/*****************************************************************************
3567 * Name      :
3568 * Purpose   :
3569 * Parameters:
3570 * Variables :
3571 * Result    :
3572 * Remark    :
3573 * Status    :
3574 *
3575 * Author    : Patrick Haller [Tue, 1998/02/10 01:55]
3576 *****************************************************************************/
3577
3578BOOL WIN32API WriteConsoleInputA(HANDLE        hConsoleInput,
3579                                 PINPUT_RECORD pirBuffer,
3580                                 DWORD         cInRecords,
3581                                 LPDWORD       lpcWritten)
3582{
3583  BOOL fResult;
3584
3585  fResult = (BOOL)HMDeviceRequest(hConsoleInput,
3586                                  DRQ_WRITECONSOLEINPUTA,
3587                                  (ULONG)pirBuffer,
3588                                  (ULONG)cInRecords,
3589                                  (ULONG)lpcWritten,
3590                                  0);
3591
3592  return fResult;
3593}
3594
3595
3596/*****************************************************************************
3597 * Name      :
3598 * Purpose   :
3599 * Parameters:
3600 * Variables :
3601 * Result    :
3602 * Remark    :
3603 * Status    :
3604 *
3605 * Author    : Patrick Haller [Tue, 1998/02/10 01:55]
3606 *****************************************************************************/
3607
3608BOOL WIN32API WriteConsoleInputW(HANDLE        hConsoleInput,
3609                                 PINPUT_RECORD pirBuffer,
3610                                 DWORD         cInRecords,
3611                                 LPDWORD       lpcWritten)
3612{
3613  BOOL fResult;
3614
3615  fResult = (BOOL)HMDeviceRequest(hConsoleInput,
3616                                  DRQ_WRITECONSOLEINPUTW,
3617                                  (ULONG)pirBuffer,
3618                                  (ULONG)cInRecords,
3619                                  (ULONG)lpcWritten,
3620                                  0);
3621
3622  return fResult;
3623}
3624
3625
3626/*****************************************************************************
3627 * Name      :
3628 * Purpose   :
3629 * Parameters:
3630 * Variables :
3631 * Result    :
3632 * Remark    :
3633 * Status    :
3634 *
3635 * Author    : Patrick Haller [Tue, 1998/02/10 01:55]
3636 *****************************************************************************/
3637
3638BOOL WIN32API WriteConsoleOutputA(HANDLE      hConsoleOutput,
3639                                  PCHAR_INFO  pchiSrcBuffer,
3640                                  COORD       coordSrcBufferSize,
3641                                  COORD       coordSrcBufferCoord,
3642                                  PSMALL_RECT psrctDestRect)
3643{
3644  BOOL fResult;
3645
3646  fResult = (BOOL)HMDeviceRequest(hConsoleOutput,
3647                                  DRQ_WRITECONSOLEOUTPUTA,
3648                                  (ULONG)pchiSrcBuffer,
3649                                  COORD2ULONG(coordSrcBufferSize),
3650                                  COORD2ULONG(coordSrcBufferCoord),
3651                                  (ULONG)psrctDestRect);
3652
3653  return fResult;
3654}
3655
3656
3657/*****************************************************************************
3658 * Name      :
3659 * Purpose   :
3660 * Parameters:
3661 * Variables :
3662 * Result    :
3663 * Remark    :
3664 * Status    :
3665 *
3666 * Author    : Patrick Haller [Tue, 1998/02/10 01:55]
3667 *****************************************************************************/
3668
3669BOOL WIN32API WriteConsoleOutputW(HANDLE      hConsoleOutput,
3670                                  PCHAR_INFO  pchiSrcBuffer,
3671                                  COORD       coordSrcBufferSize,
3672                                  COORD       coordSrcBufferCoord,
3673                                  PSMALL_RECT psrctDestRect)
3674{
3675  BOOL fResult;
3676
3677  fResult = (BOOL)HMDeviceRequest(hConsoleOutput,
3678                                  DRQ_WRITECONSOLEOUTPUTW,
3679                                  (ULONG)pchiSrcBuffer,
3680                                  COORD2ULONG(coordSrcBufferSize),
3681                                  COORD2ULONG(coordSrcBufferCoord),
3682                                  (ULONG)psrctDestRect);
3683
3684  return fResult;
3685}
3686
3687/*****************************************************************************
3688 * Name      :
3689 * Purpose   :
3690 * Parameters:
3691 * Variables :
3692 * Result    :
3693 * Remark    :
3694 * Status    :
3695 *
3696 * Author    : Patrick Haller [Tue, 1998/02/10 01:55]
3697 *****************************************************************************/
3698
3699BOOL WIN32API WriteConsoleOutputAttribute(HANDLE  hConsoleOutput,
3700                                          LPWORD  lpwAttribute,
3701                                          DWORD   cWriteCells,
3702                                          COORD   coordWriteCoord,
3703                                          LPDWORD lpcNumberWritten)
3704{
3705  BOOL fResult;
3706
3707  fResult = (BOOL)HMDeviceRequest(hConsoleOutput,
3708                                  DRQ_WRITECONSOLEOUTPUTATTRIBUTE,
3709                                  (ULONG)lpwAttribute,
3710                                  (ULONG)cWriteCells,
3711                                  COORD2ULONG(coordWriteCoord),
3712                                  (ULONG)lpcNumberWritten);
3713
3714  return fResult;
3715}
3716
3717
3718/*****************************************************************************
3719 * Name      :
3720 * Purpose   :
3721 * Parameters:
3722 * Variables :
3723 * Result    :
3724 * Remark    :
3725 * Status    :
3726 *
3727 * Author    : Patrick Haller [Tue, 1998/02/10 01:55]
3728 *****************************************************************************/
3729
3730BOOL WIN32API WriteConsoleOutputCharacterA(HANDLE  hConsoleOutput,
3731                                           LPTSTR  lpWriteBuffer,
3732                                           DWORD   cchWrite,
3733                                           COORD   coordWriteCoord,
3734                                           LPDWORD lpcWritten)
3735{
3736  BOOL fResult;
3737
3738  fResult = (BOOL)HMDeviceRequest(hConsoleOutput,
3739                                  DRQ_WRITECONSOLEOUTPUTCHARACTERA,
3740                                  (ULONG)lpWriteBuffer,
3741                                  (ULONG)cchWrite,
3742                                  COORD2ULONG(coordWriteCoord),
3743                                  (ULONG)lpcWritten);
3744
3745  return fResult;
3746}
3747
3748
3749/*****************************************************************************
3750 * Name      :
3751 * Purpose   :
3752 * Parameters:
3753 * Variables :
3754 * Result    :
3755 * Remark    :
3756 * Status    :
3757 *
3758 * Author    : Patrick Haller [Tue, 1998/02/10 01:55]
3759 *****************************************************************************/
3760
3761BOOL WIN32API WriteConsoleOutputCharacterW(HANDLE  hConsoleOutput,
3762                                           LPTSTR  lpWriteBuffer,
3763                                           DWORD   cchWrite,
3764                                           COORD   coordWriteCoord,
3765                                           LPDWORD lpcWritten)
3766{
3767  BOOL fResult;
3768
3769  fResult = (BOOL)HMDeviceRequest(hConsoleOutput,
3770                                  DRQ_WRITECONSOLEOUTPUTCHARACTERW,
3771                                  (ULONG)lpWriteBuffer,
3772                                  (ULONG)cchWrite,
3773                                  COORD2ULONG(coordWriteCoord),
3774                                  (ULONG)lpcWritten);
3775
3776  return fResult;
3777}
3778
3779} // extern "C"
Note: See TracBrowser for help on using the repository browser.