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

  1. /******************************************************************************\
  2. |*                                                                            *|
  3. |* Console window manager                                                     *|
  4. |* Copyright (C) 1997 by FRIENDS software                                     *|
  5. |* All Rights Reserved                                                        *|
  6. |*                                                                            *|
  7. |* This program is free software; you can redistribute it and/or modify       *|
  8. |* it under the terms of the GNU General Public License as published by       *|
  9. |* the Free Software Foundation; either version 2 of the License, or          *|
  10. |* (at your option) any later version.                                        *|
  11. |*                                                                            *|
  12. |* This program is distributed in the hope that it will be useful,            *|
  13. |* but WITHOUT ANY WARRANTY; without even the implied warranty of             *|
  14. |* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the              *|
  15. |* GNU General Public License for more details.                               *|
  16. |*                                                                            *|
  17. |* You should have received a copy of the GNU General Public License          *|
  18. |* along with this program; if not, write to the Free Software                *|
  19. |* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA  *|
  20. |*                                                                            *|
  21. \******************************************************************************/
  22. #define INCL_DOS
  23. #define INCL_DOSERRORS
  24. #define INCL_WIN
  25. #include <os2.h>
  26. #include <conio.h>
  27. #include <stdio.h>
  28. #include <stdlib.h>
  29. #include <getopt.h>
  30. #include <malloc.h>
  31. #include <process.h>
  32. #include <string.h>
  33. #include <alloca.h>
  34. #include <io.h>
  35. #include "syslib.h"
  36. #include "cmdline.h"
  37. #include "strop.h"
  38. #include "os2con.h"
  39.  
  40. char *version = "0.1.0";
  41.  
  42. char *os2iniMaximize = "fMaximize";    // Entry with "maximize window" flag
  43. char *os2iniShape = "sInitialShape";    // Entry with window initial shape
  44. char *os2iniFontSize;            // Entry with VIO font size
  45.  
  46. // Shield:sInitialShape structure
  47. // Does somebody know what those fields means?
  48. struct
  49. {
  50.  USHORT unknown1;
  51.  USHORT WindowH;
  52.  USHORT WindowW;
  53.  USHORT WindowY;
  54.  USHORT WindowX;
  55.  USHORT unknown2;
  56.  USHORT unknown3;
  57.  USHORT unknown4;
  58.  USHORT unknown5;
  59. } DefShape;
  60.  
  61. struct
  62. {
  63.  signed char W;
  64.  signed char H;
  65. } Font, DefFont;
  66.  
  67. struct
  68. {
  69.  int W;
  70.  int H;
  71. } Console, Border;
  72.  
  73. struct
  74. {
  75.  int X,Y,W,H;
  76. } ConsolePos;
  77.  
  78. // Command-line driven flags
  79. boolean fAutoSize = TRUE;
  80. boolean fConsoleSize = FALSE;
  81. boolean fQueryCommand = FALSE;
  82. boolean fDelay = FALSE;
  83. boolean fExplicitPos = FALSE;
  84. boolean fExplicitSize = FALSE;
  85. boolean fFontSet = FALSE;
  86. boolean fNewSession = FALSE;
  87. boolean fQuiet = FALSE;
  88. boolean fResizeWindowToMax = FALSE;
  89. boolean fMaximizeConsole = FALSE;
  90. boolean fRestoreConsole = FALSE;
  91. boolean fMinimizeConsole = FALSE;
  92. boolean fShowConsole = FALSE;
  93. boolean fHideConsole = FALSE;
  94. boolean fForegroundConsole = FALSE;
  95. boolean fSetBorder = FALSE;
  96. boolean fFlashWindow = FALSE;
  97. boolean fSetFlash = FALSE;
  98.  
  99. USHORT fMaximize;
  100. STARTDATA sd;
  101. char *cmdLine;
  102. char *progname = NULL;
  103. char *progargs = NULL;
  104. char *progtitle = NULL;
  105. int optCount;
  106.  
  107. HMTX ConsoleSem;
  108.  
  109. static long INIpresent = 0;
  110. #define iniShape    0x00000001
  111. #define iniMaximize 0x00000002
  112. #define iniFontsize 0x00000004
  113.  
  114. static void ReleaseINI(void)
  115. {
  116.  DosReleaseMutexSem(ConsoleSem);
  117.  DosCloseMutexSem(ConsoleSem);
  118. }
  119.  
  120. void doHeader()
  121. {
  122.  static char AlreadyPrinted = 0;
  123.  
  124.  if (fQuiet || AlreadyPrinted) return;
  125.  AlreadyPrinted = 1;
  126.  SetColor(colWHITE, colSAME);
  127.  printf("┌[ Console ]──────────────────────────────────[ Version %s ]┐\n", version);
  128.  printf("├ Copyright (C) 1997 by FRIENDS software ─ All Rights Reserved ┘\n");
  129. }
  130.  
  131. void doHelp()
  132. {
  133.  char *HelpText[] =
  134.  {
  135.   "│ This utility will start a windowed session (DOS or OS/2) optionaly",
  136.   "│ placing window at a specific location, changing its font and resizing",
  137.   "│ You can place legal switches in the CONSOLE environment variable",
  138.   "├ Usage: Console {options} {program} {...program options...}",
  139.   "│  Some options works only when starting a new session (these options are",
  140.   "│  marked with a /N/ sign), some applies to current window, these are marked",
  141.   "│  with /C/. Those which applies to both cases are marked with /CN/.",
  142.   "├ Available options:",
  143.   "├ -b{w,h} /CN/",
  144.   "│  Set window border [W]idth and [H]eight",
  145.   "├ -f{h,w} /CN/",
  146.   "│  Set window font [H]eight and [W]idth (enables -or+)",
  147.   "├ -o{a|b|c|d|f|m|n|r|s|v|x}{+|-}",
  148.   "│  Enable (+) or disable (-) one of following [O]ptions:",
  149.   "│  a /CN/ - Turn on (+)/off (-) [A]NSI colored output",
  150.   "│  b /CN/ - Start a [B]ackground session (+) or foreground (-)",
  151.   "│  c /N/  - auto[C]lose on termination (+) or leave window until user closes it",
  152.   "│  d /N/  - Enable (+) or disable (-) a small [D]elay after running command",
  153.   "│           Use this if you experience problems with -p starting a new session",
  154.   "│  f /CN/ - Start window title [F]lashing (+) or stop flashing (-)",
  155.   "│  m /CN/ - Start session [M]inimized (+) or non-minimized (-)",
  156.   "│  n /N/  - Start a [N]ew session (+) or change same window (-)",
  157.   "│  r /C/  - [R]esize window to max possible size (+) or leave as-is (-)",
  158.   "│  s /N/  - auto[S]ize window: compute the size of new window based on known",
  159.   "│           console window size and console font size (overriden by -p,,#,#)",
  160.   "│  v /CN/ - Start a [V]isible console window (+) or invisible (-)",
  161.   "│  x /CN/ - Start session ma[X]imized (+) or non-maximized (-)",
  162.   "├ -p{{x}{,{y}{,{w}{,h}}}} /CN/",
  163.   "│  Set window position (X, Y) and size (W, H) (in pixels)",
  164.   "│  Defining width and height implies -or-",
  165.   "├ -s{w,h} /CN/",
  166.   "│  re[S]ize window using \"MODE W,H\" command. (enables -or+ and -wo)",
  167.   "├ -q /CN/",
  168.   "│  Display a sample command line to start a window with current",
  169.   "│  size/shape (possibly modified by command-line options)",
  170.   "├ -t\"...\" /CN/",
  171.   "│  Set console [T]itle",
  172.   "├ -w{a|d|o} /N/",
  173.   "│  [W]indow type: [D]OS/[O]S2/[A]utodetect; default = OS/2",
  174.   "├┤ Default: -oa+ -oc+ -od- -of- -om- -on- -or- -os+ -ov+ -ox- -wo",
  175.   "├┤ Example: Console -wo -f18,10 -p200,100 -on t-mail.exe",
  176.   "├┤          Console -s40,25 -p,,300,100 -f8,8",
  177.   "├┤          Console -s60,20 -p10,10,488,186 -f8,8 -on -oc- -ob",
  178.   NULL
  179.  };
  180.  
  181.  int i, linecnt, consoleH;
  182.  
  183.  GetConsoleSize(&i, &consoleH);
  184.  linecnt = consoleH - 2;
  185.  
  186.  ReleaseINI();
  187.  doHeader();
  188.  for (i = 0; i < 999; i++)
  189.  {
  190.   char *Line = HelpText[i];
  191.   if (Line == NULL) break;
  192.   switch (Line[0])
  193.   {
  194.    case '│':
  195.     if (Line[2] == ' ') SetColor(colLBLUE, colSAME); else SetColor(colYELLOW, colSAME);
  196.     break;
  197.    case '├':
  198.     if (Line[1] == ' ') SetColor(colLCYAN, colSAME); else SetColor(colBLUE, colSAME);
  199.     break;
  200.   }
  201.   printf("%s\n", Line);
  202.   if ((--linecnt <= 1) && (_isterm(1)) && (_isterm(0)))
  203.   {
  204.    SetColor(colWHITE, colSAME);
  205.    printf("-- [press any key] --");
  206.    fflush(stdout);
  207.    getch();
  208.    printf("\r                     \r");
  209.    linecnt = consoleH;
  210.   }
  211.  }
  212.  fflush(stdout);
  213. }
  214.  
  215. void Stop(int code, char *msg)
  216. {
  217.  int cl;
  218.  int mcl;
  219.  
  220.  doHeader();
  221.  switch (code)
  222.  {
  223.   case 1:
  224.    doHelp();
  225.    break;
  226.   case 2:
  227.    cl = strlen(cmdLine);
  228.    mcl = strlen(msg);
  229.    cmdLine[cl - mcl] = 0;
  230.    SetColor(colYELLOW, colSAME); printf("├ Error in command-line option:\n├ %s", cmdLine);
  231.    SetColor(colLRED, colSAME); printf("%s\n", msg);
  232.    break;
  233.   case 3:
  234.    SetColor(colLRED, colSAME); 
  235.    printf("Cannot open mutex semaphore \\SEM32\\CONSOLE");
  236.    break;
  237.  }
  238.  SetColor(colBLUE, colSAME);
  239.  printf("└┤ Done\n");
  240.  SetColor(colCYAN, colSAME);
  241.  exit(code);
  242. }
  243.  
  244. int isdigit(char c)
  245. {
  246.  return (((c >= '0') && (c <= '9')) || (c == '+') || (c == '-'));
  247. }
  248.  
  249. void doInitialize()
  250. {
  251.  ULONG Sz;
  252.  ULONG bsz = 0;
  253.  
  254.  // Initialize variables
  255.  memset(&sd, 0, sizeof(sd));
  256.  Font.W = -1;
  257.  Console.W = -1;
  258.  sd.PgmControl = SSF_CONTROL_SETPOS;
  259.  sd.Related = SSF_RELATED_INDEPENDENT;
  260.  sd.SessionType = SSF_TYPE_WINDOWABLEVIO;
  261.  
  262.  // Look inside OS2.INI and find the appropiate "~Font Size..." entry
  263.  if (PrfQueryProfileSize(HINI_USERPROFILE, "Shield", NULL, &bsz))
  264.  {
  265.   PSZ buff = alloca(bsz);
  266.   if (PrfQueryProfileData(HINI_USERPROFILE, "Shield", NULL, buff, &bsz))
  267.   {
  268.    char *name = buff;
  269.    int len;
  270.    while (*name)
  271.    {
  272.     len = strlen(name) + 1;
  273.     if (strstr(name, "..."))
  274.      if ((os2iniFontSize = malloc(len)))
  275.       strcpy(os2iniFontSize, name);
  276.     name += len;
  277.    }
  278.   }
  279.  }
  280.  if (os2iniFontSize == NULL)
  281.   os2iniFontSize = "~Font Size...";
  282.  
  283.  // Query default window creation attributes
  284.  Sz = sizeof(DefShape);
  285.  if (PrfQueryProfileData(HINI_USERPROFILE, "Shield", os2iniShape,
  286.      (PVOID)&DefShape, &Sz))
  287.  {
  288.   INIpresent |= iniShape;
  289.   ConsolePos.X = DefShape.WindowX;
  290.   ConsolePos.Y = DefShape.WindowY;
  291.   ConsolePos.W = DefShape.WindowW;
  292.   ConsolePos.H = DefShape.WindowH;
  293.  }
  294.  
  295.  Sz = sizeof(fMaximize);
  296.  if (PrfQueryProfileData(HINI_USERPROFILE, "Shield", os2iniMaximize,
  297.      (PVOID)&fMaximize, &Sz))
  298.  {
  299.   INIpresent |= iniMaximize;
  300.   if (fMaximize)
  301.    sd.PgmControl |= SSF_CONTROL_MAXIMIZE;
  302.  }
  303.  
  304.  Sz = sizeof(DefFont);
  305.  if (PrfQueryProfileData(HINI_USERPROFILE, "Shield", os2iniFontSize,
  306.      (PVOID)&DefFont, &Sz))
  307.  {
  308.   INIpresent |= iniFontsize;
  309.   Font = DefFont;
  310.  }
  311.  
  312.  // Query console size, console border size
  313.  GetConsoleSize(&Console.W, &Console.H);
  314.  GetConsoleBorderSize(&Border.W, &Border.H);
  315. }
  316.  
  317. int OptH(char *Opt)
  318. {
  319.  int optLen = 2;
  320.  boolean State;
  321.  
  322.  optCount++;
  323.  switch (Opt[1])
  324.  {
  325.   case 'b':
  326.    fSetBorder = TRUE;
  327.    strdel(Opt, 0, 2); Border.W = decVal(Opt);
  328.    if (Opt[0] != ',') Stop(2, Opt);
  329.    strdel(Opt, 0, 1); Border.H = decVal(Opt);
  330.    optLen = 0;
  331.    break;
  332.   case 'f':
  333.    fFontSet = TRUE;
  334.    fResizeWindowToMax = TRUE;
  335.    strdel(Opt, 0, 2);
  336.    if (isdigit(Opt[0]))
  337.    {
  338.     Font.H = decVal(Opt);
  339.     if (Opt[0] != ',') Stop(2, Opt);
  340.     strdel(Opt, 0, 1);
  341.     Font.W = decVal(Opt);
  342.    }
  343.    else
  344.    {
  345.     int fw,fh;
  346.     if (GetConsoleFontSize(&fh, &fw))
  347.     { Font.H = fh; Font.W = fw; }
  348.    }
  349.    optLen = 0;
  350.    break;
  351.   case 'o':
  352.    optLen += OptState(Opt[3], &State) + 1;
  353.    switch (Opt[2])
  354.    {
  355.     case 'a': ANSI = State;
  356.               break;
  357.     case 'd': fDelay = State;
  358.               break;
  359.     case 'r': fResizeWindowToMax = State;
  360.               break;
  361.     case 'f': if (State)
  362.               {
  363.                fFlashWindow = TRUE;
  364.                fSetFlash = TRUE;
  365.               }
  366.               else
  367.               {
  368.                fFlashWindow = FALSE;
  369.                fSetFlash = TRUE;
  370.               }
  371.               break;
  372.     case 'b': if (State)
  373.               {
  374.                sd.FgBg = SSF_FGBG_BACK;
  375.                fForegroundConsole = FALSE;
  376.               }
  377.               else
  378.               {
  379.                sd.FgBg = SSF_FGBG_FORE;
  380.                fForegroundConsole = TRUE;
  381.               }
  382.               break;
  383.     case 'c': if (State)
  384.                sd.PgmControl &= ~SSF_CONTROL_NOAUTOCLOSE;
  385.               else
  386.                sd.PgmControl |= SSF_CONTROL_NOAUTOCLOSE;
  387.               break;
  388.     case 'v': if (State)
  389.               {
  390.                sd.PgmControl &= ~SSF_CONTROL_INVISIBLE;
  391.                fHideConsole = FALSE;
  392.                fShowConsole = TRUE;
  393.               }
  394.               else
  395.               {
  396.                sd.PgmControl |= SSF_CONTROL_INVISIBLE;
  397.                fHideConsole = TRUE;
  398.                fShowConsole = FALSE;
  399.               }
  400.               break;
  401.     case 'x': if (State)
  402.               {
  403.                sd.PgmControl |= SSF_CONTROL_MAXIMIZE;
  404.                sd.PgmControl &= ~SSF_CONTROL_MINIMIZE;
  405.                fAutoSize = FALSE;
  406.                fMaximizeConsole = TRUE;
  407.                fRestoreConsole = FALSE;
  408.               }
  409.               else
  410.               {
  411.                sd.PgmControl &= ~SSF_CONTROL_MAXIMIZE;
  412.                fMaximizeConsole = FALSE;
  413.                fRestoreConsole = TRUE;
  414.               }
  415.               break;
  416.     case 'm': if (State)
  417.               {
  418.                sd.PgmControl |= SSF_CONTROL_MINIMIZE;
  419.                sd.PgmControl &= ~SSF_CONTROL_MAXIMIZE;
  420.                fMinimizeConsole = TRUE;
  421.                fRestoreConsole = FALSE;
  422.               }
  423.               else
  424.               {
  425.                sd.PgmControl &= ~SSF_CONTROL_MINIMIZE;
  426.                fMinimizeConsole = FALSE;
  427.                fRestoreConsole = TRUE;
  428.               }
  429.               break;
  430.     case 'n': fNewSession = State;
  431.               break;
  432.     case 's': fAutoSize = State;
  433.               break;
  434.      default: Stop(2, Opt);
  435.    }
  436.    break;
  437.   case 'p':
  438.    strdel(Opt, 0, 2);
  439.    if (isdigit(Opt[0]))
  440.    { ConsolePos.X = decVal(Opt); fExplicitPos = TRUE; }
  441.    else if (Opt[0] != ',')
  442.          GetPixelConsoleSize(&ConsolePos.X, &ConsolePos.Y, &ConsolePos.W, &ConsolePos.H);
  443.    if (Opt[0] == ',')
  444.    {
  445.     strdel(Opt, 0, 1);
  446.     if (isdigit(Opt[0]))
  447.     { ConsolePos.Y = decVal(Opt); fExplicitPos = TRUE; }
  448.     if (Opt[0] == ',')
  449.     {
  450.      strdel(Opt, 0, 1);
  451.      if (isdigit(Opt[0]))
  452.      { ConsolePos.W = decVal(Opt); fExplicitSize = TRUE; }
  453.      if (Opt[0] == ',')
  454.      {
  455.       strdel(Opt, 0, 1);
  456.       if (isdigit(Opt[0]))
  457.       { ConsolePos.H = decVal(Opt); fExplicitSize = TRUE; }
  458.      }
  459.     }
  460.    }
  461.    optLen = 0;
  462.    break;
  463.   case 's':
  464.    fConsoleSize = TRUE;
  465.    fResizeWindowToMax = TRUE;
  466.    strdel(Opt, 0, 2); Console.W = decVal(Opt);
  467.    if (Opt[0] != ',') Stop(2, Opt);
  468.    strdel(Opt, 0, 1); Console.H = decVal(Opt);
  469.    optLen = 0;
  470.    break;
  471.   case 't':
  472.   {
  473.    int i = 3;
  474.    int l = strlen(Opt);
  475.    if (Opt[2] != '"') Stop(2, Opt);
  476.    while (i < l && Opt[i] != '"') i++;
  477.    if (Opt[i] != '"') Stop(2, Opt);
  478.    progtitle = malloc(i - 2);
  479.    strncpy(progtitle, &Opt[3], i - 3);
  480.    progtitle[i - 2] = 0;
  481.    optLen = i + 1;
  482.    break;
  483.   }
  484.   case 'q':
  485.    fQueryCommand = TRUE;
  486.    break;
  487.   case 'w':
  488.    switch (Opt[2])
  489.    {
  490.     case 'a':
  491.      sd.SessionType = SSF_TYPE_DEFAULT;
  492.      break;
  493.     case 'd':
  494.      sd.SessionType = SSF_TYPE_WINDOWEDVDM;
  495.      break;
  496.     case 'o':
  497.      sd.SessionType = SSF_TYPE_WINDOWABLEVIO;
  498.      break;
  499.     default:
  500.      Stop(2, Opt);
  501.    }
  502.    optLen++;
  503.    break;
  504.   case '?':
  505.   case 'h':
  506.    Stop(1, NULL);
  507.   default:
  508.    Stop(2, Opt);
  509.  }
  510.  if ((Opt[optLen] != 0) && (Opt[optLen] != SPACE) && (Opt[optLen] != TAB))
  511.   Stop(2, Opt);
  512.  return optLen;
  513. }
  514.  
  515. int StrH(char *Str)
  516. {
  517.  int len;
  518.  int sz;
  519.  
  520.  optCount++;
  521.  len = firstwordlen(Str);
  522.  sz = strlen(Str) - len;
  523.  progname = malloc(len + 1);
  524.  Str[len] = 0;
  525.  strcpy(progname, Str);
  526.  if (!strcmp("*", progname)) progname[0] = 0;
  527.  if (sz > 0)
  528.  {
  529.   progargs = malloc(sz + 1);
  530.   strcpy(progargs, (char *)&Str[len + 1]);
  531.  }
  532.  return 99999;
  533. }
  534.  
  535. void doShowCommand()
  536. {
  537.  char ch;
  538.  
  539.  SetColor(colLCYAN, colSAME);
  540.  printf("├ Effective command line:\n├┤ ");
  541.  SetColor(colWHITE, colSAME);
  542.  printf("Console -p%d,%d,%d,%d -b%d,%d -f%d,%d -s%d,%d",
  543.         ConsolePos.X, ConsolePos.Y, ConsolePos.W, ConsolePos.H,
  544.         Border.W, Border.H, Font.H, Font.W, Console.W, Console.H);
  545.  
  546.  if (fNewSession)
  547.  {
  548.   switch (sd.SessionType)
  549.   {
  550.    case SSF_TYPE_DEFAULT:       ch = 'a'; break;
  551.    case SSF_TYPE_WINDOWEDVDM:   ch = 'd'; break;
  552.    case SSF_TYPE_WINDOWABLEVIO: ch = 'o'; break;
  553.    default: ch = '*';
  554.   }
  555.   printf("-t%c ", ch);
  556.  
  557.   (sd.PgmControl & SSF_CONTROL_NOAUTOCLOSE) ? (ch = '-') : (ch = '+');
  558.   printf(" -oc%c", ch);
  559.  }
  560.  
  561.  if (fShowConsole || fHideConsole)
  562.  {
  563.   (fShowConsole) ? (ch = '-') : (ch = '+');
  564.   printf(" -ov%c", ch);
  565.  }
  566.  if (fMaximizeConsole)
  567.   printf(" -ox");
  568.  if (fMinimizeConsole)
  569.   printf(" -om");
  570.  if (fRestoreConsole)
  571.   printf(" -ox-");
  572.  if (fForegroundConsole)
  573.   printf(" -of");
  574.  else if (sd.FgBg == SSF_FGBG_BACK)
  575.   printf(" -ob");
  576.  if (fDelay)
  577.   printf(" -od");
  578.  
  579.  printf("\n");
  580. }
  581.  
  582. void doAutoSize()
  583. {
  584.  int i;
  585.  
  586.  i = NearestFont(Font.H, Font.W);
  587.  if (i >= 0)
  588.  {
  589.   Font.W = FontList[i].cx;
  590.   Font.H = FontList[i].cy;
  591.  }
  592.  
  593.  // If position is explicitely defined and size is not, auto compute window size
  594.  if ((!fExplicitSize) && (Font.W > 0) && (Font.H > 0) && fAutoSize)
  595.  {
  596.   int bw = WinQuerySysValue(HWND_DESKTOP, SV_CXSIZEBORDER);
  597.   int bh = WinQuerySysValue(HWND_DESKTOP, SV_CYSIZEBORDER);
  598.   int th = WinQuerySysValue(HWND_DESKTOP, SV_CYTITLEBAR);
  599.  
  600.   if (Console.W == -1)
  601.   { Console.W = 80; Console.H = 25; }
  602.   ConsolePos.W = bw * 2 + Console.W * Font.W;
  603.   ConsolePos.H = th + bh * 2 + Console.H * Font.H;
  604.  }
  605. }
  606.  
  607. void doNewSession()
  608. {
  609.  char objbuff[255];
  610.  ULONG sid;
  611.  PID pid;
  612.  USHORT fMax;
  613.  long Sz;
  614.  PVOID p;
  615.  
  616.  doAutoSize();
  617.  if (fExplicitSize || fAutoSize) sd.PgmControl &= ~SSF_CONTROL_MAXIMIZE;
  618.  
  619.  // Activate our window if sd.FgBg = SSF_FGBG_FORE;
  620.  if (sd.FgBg == SSF_FGBG_FORE)
  621.   SelectConsole();
  622.  
  623.  // Fill in the STARTDATA structure
  624.  sd.Length = sizeof(sd);
  625.  sd.PgmName = progname;
  626.  sd.PgmInputs = progargs;
  627.  sd.PgmTitle = progtitle;
  628.  sd.InheritOpt = SSF_INHERTOPT_PARENT;
  629.  sd.ObjectBuffer = (PVOID)&objbuff;
  630.  sd.ObjectBuffLen = sizeof(objbuff);
  631.  sd.InitXPos = ConsolePos.X;
  632.  sd.InitYPos = ConsolePos.Y;
  633.  sd.InitXSize = ConsolePos.W;
  634.  sd.InitYSize = ConsolePos.H;
  635.  
  636.  // Delete the shitty sInitialShape since it has a messy structure
  637.  PrfWriteProfileData(HINI_USERPROFILE, "Shield", os2iniShape,
  638.      NULL, 0);
  639.  if (sd.PgmControl & SSF_CONTROL_MAXIMIZE) fMax = 1; else fMax = 0;
  640.  PrfWriteProfileData(HINI_USERPROFILE, "Shield", os2iniMaximize,
  641.      (PVOID)&fMax, sizeof(fMax));
  642.  PrfWriteProfileData(HINI_USERPROFILE, "Shield", os2iniFontSize,
  643.      (PVOID)&Font, sizeof(Font));
  644.  
  645.  switch (DosStartSession(&sd, &sid, &pid))
  646.  {
  647.   case NO_ERROR:
  648.    SetColor(colLBLUE, colSAME);
  649.    printf("├ Session successfully started\n");
  650.    break;
  651.   case ERROR_SMG_START_IN_BACKGROUND:
  652.   {
  653.    SetColor(colLRED, colSAME);
  654.    printf("├ Session started in background\n");
  655.    break;
  656.   }
  657.   default:
  658.    SetColor(colLRED, colSAME);
  659.    printf("├ Failed because of \"%s\"\n", (char *)&objbuff);
  660.  };
  661.  if (fDelay) DosSleep(500);
  662.  
  663.  
  664.  // Restore INI state
  665.  Sz = sizeof(DefShape);
  666.  if (INIpresent & iniShape) p = (PVOID)&DefShape; else p = NULL;
  667.  PrfWriteProfileData(HINI_USERPROFILE, "Shield", os2iniShape, p, Sz);
  668.  Sz = sizeof(fMaximize);
  669.  if (INIpresent & iniMaximize) p = (PVOID)&fMaximize; else p = NULL;
  670.  PrfWriteProfileData(HINI_USERPROFILE, "Shield", os2iniMaximize, p, Sz);
  671.  Sz = sizeof(DefFont);
  672.  if (INIpresent & iniFontsize) p = (PVOID)&DefFont; else p = NULL;
  673.  PrfWriteProfileData(HINI_USERPROFILE, "Shield", os2iniFontSize, p, Sz);
  674. }
  675.  
  676. void doSameSession()
  677. {
  678.  char *arg;
  679.  RESULTCODES rc;
  680.  int i,j;
  681.  
  682.  if (progtitle)
  683.   SetConsoleTitle(progtitle);
  684.  
  685.  if (fForegroundConsole)
  686.   SelectConsole();
  687.  
  688.  if (fConsoleSize)
  689.   SetConsoleSize(Console.W, Console.H, colSAME);
  690.  
  691.  if (fFontSet)
  692.  {
  693.   RECTL r;
  694.   LockConsoleUpdate();
  695.   SetConsoleFontSize(Font.H, Font.W);
  696.   if (fResizeWindowToMax && !fExplicitSize)
  697.    SetMaxConsoleSize();
  698.  
  699.   // Workaround: NPS WPS does not redraw window shadow when window grows :-(
  700.   GetPixelConsoleSize((int *)&r.xLeft, (int *)&r.yBottom, (int *)&r.xRight, (int *)&r.yTop);
  701.   r.xRight += r.xLeft + 8; r.yTop += r.yBottom + 8;
  702.   r.xLeft -= 8; r.yBottom -= 8;
  703.   WinInvalidateRect(HWND_DESKTOP, &r, FALSE);
  704.  
  705.   UnlockConsoleUpdate();
  706.  } else
  707.  if (fResizeWindowToMax && !fExplicitSize)
  708.   SetMaxConsoleSize();
  709.  
  710.  if (fSetBorder)
  711.   SetConsoleBorderSize(Border.W, Border.H);
  712.  if (fSetFlash)
  713.   FlashConsole(fFlashWindow);
  714.  
  715.  if (fMinimizeConsole)
  716.   MinimizeConsole();
  717.  else if (fMaximizeConsole)
  718.   MaximizeConsole();
  719.  
  720.  if (GetWindowHWND())
  721.  {
  722.   if ((fExplicitPos || fExplicitSize))
  723.    SetPixelConsoleSize(ConsolePos.X, ConsolePos.Y, ConsolePos.W, ConsolePos.H,
  724.     (fExplicitPos ? SWP_MOVE : 0) | (fExplicitSize ? SWP_SIZE : 0));
  725.   else if (fMaximizeConsole)
  726.    SetPixelConsoleSize(ConsolePos.X, ConsolePos.Y, 0, 0, SWP_MOVE);
  727.  }
  728.  
  729.  if (fHideConsole)
  730.   ShowConsole(FALSE);
  731.  else if (fShowConsole)
  732.   ShowConsole(TRUE);
  733.  
  734.  if (fRestoreConsole)
  735.   RestoreConsole();
  736.  
  737.  if (!progname) return;
  738.  if (!progname[0]) progname = getenv("COMSPEC");
  739.  if (progname) i = strlen(progname); else i = 0;
  740.  j = i; i++;
  741.  if (progargs) i+= strlen(progargs);
  742.  arg = malloc(i);
  743.  
  744.  if (progname) strcpy(arg, progname); else arg[0] = 0;
  745.  strcat(arg, "*");
  746.  if (progargs) strcat(arg, progargs);
  747.  arg[j] = 0;
  748.  
  749.  ReleaseINI();
  750.  if (DosExecPgm(NULL, 0, EXEC_SYNC, arg, NULL, &rc, progname))
  751.  {
  752.   SetColor(colLRED, colSAME);
  753.   printf("Error running command %s\n", progname);
  754.   if (_isterm(1)) getch();
  755.   return;
  756.  }
  757. }
  758.  
  759. int main (int argc, char *argv[])
  760. {
  761.  if (!_isterm(1)) ANSI = 0;
  762.  
  763.  if (DosCreateMutexSem("\\SEM32\\CONSOLE.RUN", &ConsoleSem, DC_SEM_SHARED, TRUE) != NO_ERROR)
  764.  {
  765.   if (DosOpenMutexSem("\\SEM32\\CONSOLE.RUN", &ConsoleSem) != NO_ERROR)
  766.    Stop(3, NULL);
  767.   if (DosRequestMutexSem(ConsoleSem, SEM_INDEFINITE_WAIT) != NO_ERROR)
  768.    Stop(3, NULL);
  769.  }
  770.  atexit(ReleaseINI);
  771.  
  772.  doInitialize();
  773.  
  774.  ParseCmdLine(getenv("CONSOLE"), OptH, StrH);
  775.  optCount = 0;
  776.  cmdLine = CmdLine(argc, argv);
  777.  ParseCmdLine(cmdLine, OptH, StrH);
  778.  free(cmdLine);
  779.  
  780.  if (!fNewSession && (optCount > 0) && !fQueryCommand)
  781.   fQuiet = TRUE;
  782.  
  783.  doHeader();
  784.  
  785.  if (fQueryCommand)
  786.   doShowCommand();
  787.  
  788.  if ((fConsoleSize || fSetBorder || (fSetFlash && fFlashWindow)) &&
  789.      fNewSession && (sd.SessionType == SSF_TYPE_WINDOWABLEVIO))
  790.  {
  791.   char *p,*n;
  792.   int nl = 64;
  793.   if (progname) nl += strlen(progname);
  794.   if (progargs) nl += strlen(progargs);
  795.   p = malloc(nl);
  796.   sprintf(p, "-s%d,%d ", Console.W, Console.H);
  797.   if (fSetBorder)
  798.    sprintf(&p[strlen(p)], "-b%d,%d ", Border.W, Border.H);
  799.   if (fSetFlash && fFlashWindow)
  800.    strcat(&p[strlen(p)], "-of ");
  801.   if (fExplicitSize)
  802.    sprintf(&p[strlen(p)], "-p,,%d,%d ", ConsolePos.W, ConsolePos.H);
  803.   if ((sd.PgmControl & SSF_CONTROL_INVISIBLE) == 0)
  804.   {
  805.    strcat(&p[strlen(p)], "-ov ");
  806.    sd.PgmControl |= SSF_CONTROL_INVISIBLE;
  807.   }
  808.   if (!progname || !progname[0]) n = getenv("COMSPEC"); else n = progname;
  809.   sprintf(&p[strlen(p)], "%s ", n);
  810.   if (progargs) strcat(p, progargs);
  811.   if (progname) free(progname);
  812.   progname = SourceName();
  813.   progargs = p;
  814.  }
  815.  
  816.  if (!optCount)
  817.   doHelp();
  818.  else
  819.  {
  820.   if (fNewSession)
  821.    doNewSession();
  822.   else
  823.    doSameSession();
  824.  }
  825.  
  826.  if (!fQuiet)
  827.  {
  828.   SetColor(colBLUE, colSAME);
  829.   printf("└┤ Done\n");
  830.   SetColor(colCYAN, colSAME);
  831.  }
  832.  return 0;
  833. }
  834.