home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / cons-010.zip / Console / src / common / os2con.c < prev    next >
C/C++ Source or Header  |  1997-09-10  |  11KB  |  441 lines

  1. /******************************************************************************\
  2. |*                                                                            *|
  3. |* OS/2 console control routines                                              *|
  4. |* Copyright (C) 1997 by FRIENDS software                                     *|
  5. |* All Rights Reserved                                                        *|
  6. |* Portability: OS/2                                                          *|
  7. |*                                                                            *|
  8. |* This program is free software; you can redistribute it and/or modify       *|
  9. |* it under the terms of the GNU General Public License as published by       *|
  10. |* the Free Software Foundation; either version 2 of the License, or          *|
  11. |* (at your option) any later version.                                        *|
  12. |*                                                                            *|
  13. |* This program is distributed in the hope that it will be useful,            *|
  14. |* but WITHOUT ANY WARRANTY; without even the implied warranty of             *|
  15. |* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the              *|
  16. |* GNU General Public License for more details.                               *|
  17. |*                                                                            *|
  18. |* You should have received a copy of the GNU General Public License          *|
  19. |* along with this program; if not, write to the Free Software                *|
  20. |* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA  *|
  21. |*                                                                            *|
  22. \******************************************************************************/
  23.  
  24. #define INCL_SUB
  25. #define INCL_DOS
  26. #define INCL_WIN
  27. #define INCL_DOSERRORS
  28. #include <os2.h>
  29. #include <malloc.h>
  30. #include "os2con.h"
  31. #include "CWRP.h"
  32.  
  33. #include <conio.h>
  34. #include <stdio.h>
  35. #include <process.h>
  36. #include <string.h>
  37. #include <stdlib.h>
  38.  
  39. // Enable (1) or disable (0) ANSI output
  40. boolean ANSI = TRUE;
  41.  
  42. // Console font list
  43. PVIOFONTCELLSIZE FontList;
  44. ULONG FontCount;
  45.  
  46. HWND vioHWND = NULLHANDLE;
  47. HWND clientHWND = NULLHANDLE;
  48. HWND listHWND = NULLHANDLE;
  49. HWND dlgHWND = NULLHANDLE;
  50. HSWITCH vioHSW;
  51.  
  52. static int ANSI2VIO[17] =
  53. {-1, 0, 4, 2, 6, 1, 5, 3, 7, 8, 12, 10, 14, 9, 13, 11, 15};
  54.  
  55. /*
  56.  * Note: Since this library is oriented to console programs, we
  57.  *       SHOULD NOT use functions that requires a message queue
  58.  *       to exist (since console program cannot own a message queue),
  59.  *       Most WinXXX functions DO require a msgqueue to exist, so we
  60.  *       should do as much as possible with messages, thanks God
  61.  *       WinPostMsg does not require it (alas, WinSendMsg requires).
  62.  *
  63.  *       For functions that require an message queue to exist we
  64.  *       should use an external PM agent program called CWRP.
  65.  */
  66.  
  67. static tConsoleManagerSharedMem *ShMem;
  68. static HMTX cwrpInUse;
  69. static HEV cwrpReady;
  70.  
  71. HWND GetWindowHWND()
  72. {
  73.  if (!vioHWND)
  74.  {
  75.   PTIB tb;
  76.   PPIB pb;
  77.   SWCNTRL swc;
  78.   if (DosGetInfoBlocks(&tb, &pb))
  79.    return NULLHANDLE;
  80.   if (!(vioHSW = WinQuerySwitchHandle(NULLHANDLE, pb->pib_ulpid)))
  81.    return NULLHANDLE;
  82.   if (WinQuerySwitchEntry(vioHSW, &swc))
  83.    return NULLHANDLE;
  84.   vioHWND = swc.hwnd;
  85.   clientHWND = WinWindowFromID(vioHWND, FID_CLIENT);
  86.  }
  87.  return vioHWND;
  88. }
  89.  
  90. /* Send a request to CWRP */
  91. int CWRQ(ULONG request, void *data)
  92. {
  93.  int Try;
  94.  ULONG Count;
  95.  BOOL rc;
  96.  
  97.  if (!ShMem)
  98.  {
  99.   for (Try = 0; Try < 50; Try++)
  100.    if (DosGetNamedSharedMem(
  101.     (PVOID)&ShMem,                       /* Pointer to pointer of object */
  102.     cwrpSharedMem,                              /* Name of shared memory */
  103.     PAG_READ | PAG_WRITE) != NO_ERROR)              /* Read/write access */
  104.    {
  105.     if (Try == 0)                                   /* CWRP not running? */
  106.     {
  107.      RESULTCODES rc;
  108.      char cwrp[CCHMAXPATH];
  109.  
  110.      _path((char *)&cwrp, "CWRP.exe");
  111.      DosExecPgm(NULL, 0, EXEC_BACKGROUND, arg0_magic"\0\0", NULL, &rc, cwrp);
  112.     }
  113.  
  114.     DosSleep(100);
  115.    } else break;
  116.   if (!ShMem) goto failed;
  117.   for (Try = 0; Try < 100; Try++)
  118.    if (!ShMem->manager) DosSleep(100);
  119.    else break;
  120.   if (!ShMem->manager) goto failed;
  121.   cwrpInUse = ShMem->inuse;
  122.   cwrpReady = ShMem->ready;
  123.   if (DosOpenMutexSem(NULL, &cwrpInUse) != NO_ERROR) goto failed;
  124.   if (DosOpenEventSem(NULL, &cwrpReady) != NO_ERROR) goto failed;
  125.  }
  126.  
  127.  if (DosRequestMutexSem(cwrpInUse, SEM_INDEFINITE_WAIT) != NO_ERROR)
  128.   return -1;
  129.  DosResetEventSem(cwrpReady, &Count);
  130.  
  131.  switch (request)
  132.  {
  133.   case cwrqSetFont:
  134.    ShMem->fNo = (LONG)data;
  135.   case cwrqShow:
  136.    ShMem->Show = (BOOL)data;
  137.    break;
  138.   case cwrqSetPos:
  139.    ShMem->swp = *(PSWP)data;
  140.  }
  141.  
  142.  ShMem->ret = 0;
  143.  WinPostMsg(ShMem->manager, WM_CONREQUEST, (MPARAM)request, (MPARAM)GetWindowHWND());
  144.  rc = DosWaitEventSem(cwrpReady, 10000);
  145.  Try = ShMem->ret;
  146.  DosReleaseMutexSem(cwrpInUse);
  147.  if (rc != NO_ERROR) return -1;
  148.  return Try;
  149.  
  150. failed:
  151.  ShMem = 0;
  152.  return -1;
  153. }
  154.  
  155. void SetColor(int Fore, int Back)
  156. {
  157.  if (!ANSI || (Fore < colSAME) || (Fore > colWHITE) || (Back < colSAME) || (Back > colWHITE))
  158.   return;
  159.  
  160.  Fore = ANSI2VIO[++Fore];
  161.  Back = ANSI2VIO[++Back];
  162.  
  163.  if ((Fore != colSAME) && (Back != colSAME))
  164.   printf("\x1b[%d;3%d;4%dm", Fore/8, Fore%8, Back%8);
  165.  else if (Fore != colSAME)
  166.   printf("\x1b[%d;3%dm", Fore/8, Fore%8);
  167.  else if (Back != colSAME)
  168.   printf("\x1b[4%dm", Back%8);
  169. }
  170.  
  171. void SetConsoleSize(int Width, int Height, int Attr)
  172. {
  173.  VIOMODEINFO vi;
  174.  vi.cb = sizeof(vi);
  175.  VioGetMode(&vi, 0);
  176.  
  177.  vi.col = Width;
  178.  vi.row = Height;
  179.  vi.cb = sizeof(vi.cb) + sizeof(vi.fbType) + sizeof(vi.color) + \
  180.          sizeof(vi.col) + sizeof(vi.row);
  181.  VioSetMode(&vi, 0);
  182.  ClearConsole(Attr);
  183. }
  184.  
  185. void GetConsoleSize(int *Width, int *Height)
  186. {
  187.  VIOMODEINFO vi;
  188.  vi.cb = sizeof(vi);
  189.  VioGetMode(&vi, 0);
  190.  *Width = vi.col;
  191.  *Height = vi.row;
  192. }
  193.  
  194. void SetCursorPos(int X, int Y)
  195. {
  196.  VioSetCurPos(Y, X, 0);
  197. }
  198.  
  199. void ClearConsole(int Attr)
  200. {
  201.  static char clsAttr[2];
  202.  VIOMODEINFO vi;
  203.  
  204.  clsAttr[0] = ' ';
  205.  if (Attr == colSAME)
  206.   clsAttr[1] = 0x07;
  207.  else
  208.   clsAttr[1] = ANSI2VIO[(Attr & 0x0f) + 1] | ANSI2VIO[(Attr >> 4) + 1] << 4;
  209.  vi.cb = sizeof(vi);
  210.  VioGetMode(&vi, 0);
  211.  VioScrollUp(0, 0, vi.row, vi.col, vi.col, (PBYTE)&clsAttr, 0);
  212.  
  213.  SetCursorPos(0, 0);
  214. }
  215.  
  216. BOOL QueryFontList()
  217. {
  218.  HDC hdc;
  219.  ULONG outCount;
  220.  PVIOSIZECOUNT vsc;
  221.  uint i,j,k;
  222.  
  223.  if (FontList && FontCount)
  224.   return TRUE;
  225.  
  226.  if (!GetWindowHWND()) exit(1);
  227.  hdc = WinQueryWindowDC(clientHWND);
  228.  
  229.  outCount = sizeof(FontCount);
  230.  if (DevEscape(hdc, DEVESC_QUERYVIOCELLSIZES, 0, NULL, &outCount, (PBYTE)&FontCount) != DEV_OK)
  231.   return FALSE;
  232.  
  233.  outCount = sizeof(VIOSIZECOUNT) + FontCount * sizeof(VIOFONTCELLSIZE);
  234.  vsc = malloc(outCount);
  235.  if (DevEscape(hdc, DEVESC_QUERYVIOCELLSIZES, 0, NULL, &outCount, (PBYTE)vsc) != DEV_OK)
  236.   return FALSE;
  237.  
  238.  FontList = (PVIOFONTCELLSIZE)&vsc[1];
  239.  
  240.  /* Sort fonts by height as in list box */
  241.  for (i = 0; i < FontCount; i++)
  242.   for (j = i + 1; j < FontCount; j++)
  243.    if ((FontList[i].cy > FontList[j].cy) ||
  244.        ((FontList[i].cy == FontList[j].cy) && (FontList[i].cx > FontList[j].cx)))
  245.    {
  246.     k = FontList[i].cx; FontList[i].cx = FontList[j].cx; FontList[j].cx = k;
  247.     k = FontList[i].cy; FontList[i].cy = FontList[j].cy; FontList[j].cy = k;
  248.    }
  249.  
  250.  return TRUE;
  251. }
  252.  
  253. BOOL SetConsoleFontSize(int H, int W)
  254. {
  255.  int fno;
  256.  
  257.  if ((fno = NearestFont(H, W)) < 0)
  258.   return FALSE;
  259.  
  260.  return (CWRQ(cwrqSetFont, (void *)fno) != -1);
  261. }
  262.  
  263. BOOL GetConsoleFontSize(int *H, int *W)
  264. {
  265.  int i;
  266.  
  267.  if (!QueryFontList())
  268.   return FALSE;
  269.  
  270.  i = CWRQ(cwrqQueryFont, NULL);
  271.  
  272.  if (i < 0)
  273.   return FALSE;
  274.  *W = FontList[i].cx;
  275.  *H = FontList[i].cy;
  276.  return TRUE;
  277. }
  278.  
  279. BOOL MaximizeConsole()
  280. {
  281.  if (!GetWindowHWND()) return FALSE;
  282.  WinPostMsg(vioHWND, WM_SYSCOMMAND, (MPARAM)SC_MAXIMIZE, MPFROM2SHORT(CMDSRC_MENU, FALSE));
  283.  return TRUE;
  284. }
  285.  
  286. BOOL MinimizeConsole()
  287. {
  288.  if (!GetWindowHWND()) return FALSE;
  289.  WinPostMsg(vioHWND, WM_SYSCOMMAND, (MPARAM)SC_MINIMIZE, MPFROM2SHORT(CMDSRC_MENU, FALSE));
  290.  return TRUE;
  291. }
  292.  
  293. BOOL RestoreConsole()
  294. {
  295.  if (!GetWindowHWND()) return FALSE;
  296.  WinPostMsg(vioHWND, WM_SYSCOMMAND, (MPARAM)SC_RESTORE, MPFROM2SHORT(CMDSRC_MENU, FALSE));
  297.  return TRUE;
  298. }
  299.  
  300. BOOL ShowConsole(BOOL Show)
  301. {
  302.  return (CWRQ(cwrqShow, (void *)Show) != -1);
  303. }
  304.  
  305. BOOL SelectConsole()
  306. {
  307.  if (!GetWindowHWND()) return FALSE;
  308.  // Lock window updates so that if Console is minimized it will not pop up
  309.  WinEnableWindow(vioHWND, FALSE);       // Tricky ??? but works.
  310.  WinSwitchToProgram(vioHSW);
  311.  WinEnableWindow(vioHWND, TRUE);
  312.  return TRUE;
  313. }
  314.  
  315. BOOL FlashConsole(BOOL State)
  316. {
  317.  if (!GetWindowHWND()) return FALSE;
  318.  WinPostMsg(vioHWND, WM_FLASHWINDOW, (MPARAM)State, (MPARAM)0);
  319.  return TRUE;
  320. }
  321.  
  322. BOOL SetConsoleBorderSize(int W, int H)
  323. {
  324.  if (!GetWindowHWND()) return FALSE;
  325.  WinPostMsg(vioHWND, WM_SETBORDERSIZE, (MPARAM)W, (MPARAM)H);
  326.  return TRUE;
  327. }
  328.  
  329. BOOL GetConsoleBorderSize(int *W, int *H)
  330. {
  331.  ULONG i = CWRQ(cwrqQueryBorder, NULL);
  332.  if (i < 0)
  333.   return FALSE;
  334.  
  335.  *W = (i & 0xFFFF);
  336.  *H = (i >> 16);
  337.  return TRUE;
  338. }
  339.  
  340. BOOL SetPixelConsoleSize(int X, int Y, int W, int H, ULONG Flags)
  341. {
  342.  SWP swp;
  343.  
  344.  // Fill with old values
  345.  WinQueryWindowPos(vioHWND, &swp);
  346.  swp.fl = Flags;
  347.  if (((Flags & SWP_MOVE) == 0) && ((Flags & SWP_SIZE) != 0))
  348.  {
  349.   swp.y += swp.cy - H;
  350.   swp.fl |= SWP_MOVE;
  351.  }
  352.  if (Flags & SWP_MOVE)
  353.  { swp.x = X;  swp.y = Y; }
  354.  if (Flags & SWP_SIZE)
  355.  { swp.cx = W; swp.cy = H; }
  356.  
  357.  return (CWRQ(cwrqSetPos, (void *)&swp) != -1);
  358. }
  359.  
  360. BOOL GetPixelConsoleSize(int *X, int *Y, int *W, int *H)
  361. {
  362.  SWP swp;
  363.  
  364.  if (!GetWindowHWND()) return FALSE;
  365.  
  366.  WinQueryWindowPos(vioHWND, &swp);
  367.  *X = swp.x;  *Y = swp.y;
  368.  *W = swp.cx; *H = swp.cy;
  369.  return TRUE;
  370. }
  371.  
  372. int NearestFont(int H, int W)
  373. {
  374.  ULONG i,j,fno,dist;
  375.  
  376.  if (!QueryFontList())
  377.   return -1;
  378.  
  379.  dist = 9999; fno = 0;
  380.  for (i = 0; i < FontCount; i++)
  381.  {
  382.   j = (FontList[i].cy - H) * (FontList[i].cy - H) +
  383.       (FontList[i].cx - W) * (FontList[i].cx - W);
  384.   if (j < dist)
  385.   { dist = j; fno = i; }
  386.  }
  387.  return fno;
  388. }
  389.  
  390. USHORT _THUNK_FUNCTION (Win16SetTitle) ();
  391.  
  392. USHORT WinSetTitle (char *title)
  393. {
  394.   return ((USHORT)
  395.           (_THUNK_PROLOG (4);
  396.            _THUNK_FLAT (title);
  397.            _THUNK_CALL (Win16SetTitle)));
  398. }
  399.  
  400. BOOL SetConsoleTitle(char *title)
  401. {
  402.  return (WinSetTitle(title));
  403. }
  404.  
  405. BOOL SetMaxConsoleSize()
  406. {
  407.  int w,h;
  408.  int bw,bh;
  409.  int cw,ch;
  410.  int oldx,oldy,oldw,oldh;
  411.  int th = WinQuerySysValue(HWND_DESKTOP, SV_CYTITLEBAR);
  412.  
  413.  if (!GetConsoleFontSize(&h, &w))
  414.   return FALSE;
  415.  
  416.  if (!GetConsoleBorderSize(&bw, &bh))
  417.   return FALSE;
  418.  
  419.  if (!GetPixelConsoleSize(&oldx, &oldy, &oldw, &oldh))
  420.   return FALSE;
  421.  
  422.  GetConsoleSize(&cw, &ch);
  423.  
  424.  // Compute max window size
  425.  cw = bw * 2 + cw * w;
  426.  ch = th + bh * 2 + ch * h;
  427.  oldy = (oldy + oldh) - ch;
  428.  
  429.  return SetPixelConsoleSize(oldx, oldy, cw, ch, SWP_MOVE | SWP_SIZE);
  430. }
  431.  
  432. BOOL LockConsoleUpdate()
  433. {
  434.  return CWRQ(cwrqLockOutput, NULL);
  435. }
  436.  
  437. BOOL UnlockConsoleUpdate()
  438. {
  439.  return CWRQ(cwrqUnlockOutput, NULL);
  440. }
  441.