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