home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / pmtclsh.zip / src.zip / pmtclsh.c next >
C/C++ Source or Header  |  1996-10-09  |  11KB  |  409 lines

  1. /* TclSh for OS/2 ver 1.0 -- tcl shell for OS/2
  2.  * Copyright (C) 1996 Fornari Stefano
  3.  *
  4.  * Permission to use, copy, modify, and distribute this software for any
  5.  * purpose is granted without fee, provided that the above copyright notice
  6.  * and the following paragraph appear in all copies of this software
  7.  * and supporting documentation.
  8.  *
  9.  * This software is distributed in the hope that it will be useful,
  10.  * but WITHOUT ANY WARRANTY, even the implied warranty of MERCHANTABILITY
  11.  * or FITNESS FOR A PARTICULAR PURPOSE.  In no event shall the author be
  12.  * liable to any party for direct, indirect, special, incidental, or
  13.  * consequential damages arising out of the use of this software and its
  14.  * documentation.
  15.  */
  16.  
  17. /*-----------------------------------------------------
  18.    tclsh.c -- tcl 7.4 Interpreter for OS/2
  19.   -----------------------------------------------------*/
  20.  
  21. /*
  22.     Compiler command:      gcc -Zomf -Zcrtdll tclsh.c tclsh.res tclsh.def
  23. */
  24.  
  25. #define INCL_WIN
  26. #define INCL_DOS
  27.  
  28. #include <stdlib.h>
  29. #include <string.h>
  30. #include <fcntl.h>
  31. #include <stdio.h>
  32. #include <io.h>
  33. #include <os2.h>
  34.  
  35. #include "pmtclsh.h"
  36.  
  37. #ifdef WISH
  38.     #include "tkint.h"
  39. #else
  40.     #include "tcl.h"
  41. #endif
  42.  
  43. /* constants */
  44. #define ENTRYHEIGHT 15
  45.  
  46. static HAB           hab;
  47.        HMQ           hmq;
  48. static HWND        hwndFrame = NULLHANDLE,
  49.                    hwndEFInput = NULLHANDLE,
  50.                    hwndMLEOutput = NULLHANDLE;
  51. static LONG        cxBorder, cyBorder, cyTitle, cyMenu;
  52. static HFILE       hOutPipe[2], hInPipe[2];
  53.  
  54. int    majorVersion = 1,
  55.        minorVersion = 0;
  56.  
  57. #ifdef WISH
  58.     char szAppName [] = "Wish/2" ;
  59. #else
  60.     char szAppName [] = "PMTclSh/2" ;
  61. #endif
  62.  
  63.  
  64. /* function prototypes */
  65. MRESULT EXPENTRY WndProc(HWND, ULONG, MPARAM, MPARAM);
  66. MRESULT EXPENTRY EntryProc(HWND, ULONG, MPARAM, MPARAM);
  67. MRESULT EXPENTRY AboutProc(HWND, ULONG, MPARAM, MPARAM);
  68.  
  69.  
  70. /* iscArg : looking for the presence of -c argument */
  71. int iscArg(int argc, char **argv)
  72. {
  73.      int i;
  74.  
  75.      for(i = 1; i < argc; i++)
  76.        if(strcmp(argv[i], "-c") == 0) return 1;
  77.  
  78.      return 0;
  79. }
  80.  
  81.  
  82. void ResizeControls(HWND hwndFrame, USHORT cx, USHORT cy)
  83. {
  84.     if ((cx == 0) && (cy == 0)) return;
  85.  
  86.     WinSetWindowPos(hwndEFInput, HWND_TOP, cxBorder, cyBorder,
  87.                     cx-2*cxBorder, ENTRYHEIGHT,
  88.                     SWP_SIZE | SWP_MOVE);
  89.     WinSetWindowPos(hwndMLEOutput, HWND_TOP, cxBorder+3, ENTRYHEIGHT+cyBorder+5,
  90.                     cx-2*cxBorder-6, cy-ENTRYHEIGHT-2*cyBorder-cyTitle-cyMenu-9,
  91.                     SWP_SIZE | SWP_MOVE);
  92. }
  93.  
  94.  
  95. int AskConfirmation (HWND hwnd)
  96. {
  97. #ifdef WISH
  98.     return WinMessageBox(HWND_DESKTOP, hwnd, "Really want to close Wish ?",
  99.                          szAppName, 0, MB_YESNO | MB_ICONQUESTION);
  100. #else
  101.     return WinMessageBox(HWND_DESKTOP, hwnd, "Really want to close PMTclShell ?",
  102.                          szAppName, 0, MB_YESNO | MB_ICONQUESTION);
  103. #endif
  104. }
  105.  
  106.  
  107. /* CreateControls
  108.  * --------------
  109.  *
  110.  * DESCRIPTION: create controls for commands input/output
  111.  *
  112.  * INPUT:
  113.  *          hwndFrame    frame window handle
  114.  *
  115.  * OUTPUT: TRUE if controls are correctly created, FALSE otherwise.
  116.  *
  117.  * SIDE EFFECTS: the globals variables hwndEFInput and hwndMLEOutput
  118.  * assume rispectively the windows handles for the input entry field
  119.  * and output MLE
  120.  */
  121. BOOL CreateControls(HWND hwndFrame)
  122. {
  123.     SWP   swp;
  124.  
  125.     WinQueryWindowPos(hwndFrame, &swp);
  126.  
  127.     hwndEFInput = WinCreateWindow(hwndFrame, WC_ENTRYFIELD, "",
  128.                       WS_VISIBLE |WS_PARENTCLIP | ES_AUTOSCROLL | ES_MARGIN,
  129.                       0, 0, 10, 10,
  130.                       hwndFrame, HWND_TOP, WID_EFCOMMAND, NULL, NULL);
  131.     hwndMLEOutput = WinCreateWindow(hwndFrame, WC_MLE, "",
  132.                     WS_VISIBLE | WS_PARENTCLIP | MLS_BORDER | MLS_VSCROLL |
  133.                     MLS_HSCROLL | MLS_READONLY,
  134.                     0, 0, 10,10,
  135.                     hwndFrame, HWND_TOP, WID_EFCOMMAND, NULL, NULL);
  136.  
  137.     if (hwndEFInput == NULLHANDLE || hwndMLEOutput == NULLHANDLE) return FALSE;
  138.  
  139.     /* set the max input length  from entry field */
  140.     WinSendMsg(hwndEFInput, EM_SETTEXTLIMIT, (MPARAM)MAXLENINPUT, 0);
  141.  
  142.     return TRUE;
  143. }
  144.  
  145.  
  146.  
  147. /* SourceFile
  148.  * --------------
  149.  *
  150.  * DESCRIPTION: query filname of a file that must be executed
  151.  *
  152.  * INPUT:
  153.  *          hPipe    pipe write handle (used to write the source command)
  154.  *
  155.  * OUTPUT:
  156.  */
  157. void SourceFile(HWND hwndParent, HFILE hPipe)
  158. {
  159.     FILEDLG fdlg;
  160.  
  161.     memset(&fdlg, 0, sizeof(fdlg));
  162.     fdlg.cbSize=sizeof(fdlg);
  163.     fdlg.fl = FDS_OPEN_DIALOG;
  164.     fdlg.pszTitle = "Source file";
  165.     fdlg.pszOKButton = "~Source";
  166.     strcpy(fdlg.szFullFile, "*.tcl");
  167.  
  168.     if (WinFileDlg(HWND_DESKTOP, hwndParent, &fdlg))
  169.     {
  170.         char cmd[CCHMAXPATH+10];  /* it will contain 'source <filename>' */
  171.         char *p;
  172.  
  173.         /* conversion \ -> / */
  174.         p = fdlg.szFullFile;
  175.         while (*p)
  176.         {
  177.             if (*p == '\\') *p = '/';
  178.             p++;
  179.         }
  180.         sprintf(cmd, "source %s\r\n", fdlg.szFullFile);
  181.         write(hPipe, cmd, strlen(cmd));
  182.     }
  183. }
  184.  
  185.  
  186. void ExitInterp(HWND hwnd, int result) {
  187.     char st[100];
  188.  
  189.     sprintf(st, "Tcl interpreter exited: %d", result);
  190.     
  191. }
  192.  
  193.  
  194. MRESULT EXPENTRY WndProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
  195. {
  196.     static PFNWP       pfnwp = NULL;
  197.  
  198.     switch (msg)
  199.     {
  200.         case TCLSHM_PASSPARAM:
  201.             pfnwp = (PFNWP)mp1;
  202.  
  203.             CreateControls(hwnd);
  204.             return (MRESULT)0;
  205.  
  206.                 case TCLSHM_EXITINTERP:
  207.                         WinMessageBox(hwnd, HWND_DESKTOP, 
  208.                             "Tcl interpreter exited", szAppName, 
  209.                             0, MB_OK | MB_INFORMATION);
  210.                         WinPostMsg(hwnd, WM_QUIT, 0, 0);
  211.                         return (MRESULT)0;
  212.  
  213.         case WM_WINDOWPOSCHANGED:
  214.         {
  215.             PSWP pswp = (PSWP)mp1;
  216.             ResizeControls(hwnd, pswp->cx, pswp->cy);
  217.         }; break;
  218.  
  219.         case WM_INITMENU:
  220.             if (HWNDFROMMP(mp2))
  221.             {
  222.                 ULONG ul;
  223.                 BOOL  f;
  224.  
  225.                 f = WinQueryClipbrdFmtInfo(hab, CF_TEXT, &ul);
  226.                 WinEnableMenuItem(HWNDFROMMP(mp2), IDM_PASTE, f);
  227.  
  228.                 ul = (ULONG)WinSendMsg(hwndEFInput, EM_QUERYSEL, 0, 0);
  229.                 f = (HIUSHORT (ul) == LOUSHORT (ul)) ? FALSE : TRUE;
  230.                 WinEnableMenuItem(HWNDFROMMP(mp2), IDM_CUT, f);
  231.                 WinEnableMenuItem(HWNDFROMMP(mp2), IDM_COPY, f);
  232.                 WinEnableMenuItem(HWNDFROMMP(mp2), IDM_DEL, f);
  233.  
  234.                 return (MRESULT)0;
  235.             }
  236.  
  237.         case WM_CHAR:
  238.         {
  239.             HWND hwndFocus;
  240.  
  241.             hwndFocus = WinQueryFocus(HWND_DESKTOP);
  242.             if (hwndFocus == hwndEFInput || hwndFocus == hwndMLEOutput)
  243.             {
  244.                 if ((CHARMSG(&msg)->fs & KC_VIRTUALKEY) &&
  245.                     (CHARMSG(&msg)->fs & KC_KEYUP) &&
  246.                     (CHARMSG(&msg)->vkey == VK_ENTER || CHARMSG(&msg)->vkey == VK_NEWLINE))
  247.                 {
  248.                     char  cmdBuf[MAXLENINPUT];         /* Line buffer for commands */
  249.                     LONG  nLen;
  250.  
  251.                     nLen = WinQueryWindowText(hwndEFInput, sizeof(cmdBuf)-1, cmdBuf);
  252.                     strcat(cmdBuf, "\r\n");
  253.                     /* write (part of) command in the output window */
  254.                     nLen = (LONG)WinSendMsg(hwndMLEOutput, MLM_QUERYTEXTLENGTH, 0, 0);
  255.                     WinSendMsg(hwndMLEOutput, MLM_SETSEL, (MPARAM)nLen, (MPARAM)nLen);
  256.                     WinSendMsg(hwndMLEOutput, MLM_INSERT, (MPARAM)cmdBuf, 0);
  257.  
  258.                     /* send the command to the interpreter */
  259.                     write(hInPipe[1], cmdBuf, strlen(cmdBuf));
  260.  
  261.                     WinSetWindowText(hwndEFInput, "");
  262.         }
  263.             }
  264.         }; break;
  265.  
  266.         case WM_COMMAND:
  267.             switch (COMMANDMSG(&msg)->cmd)
  268.             {
  269.                 case IDM_EXIT:
  270.                     WinSendMsg(hwnd, WM_CLOSE, 0, 0);
  271.                     break;
  272.                 case IDM_CUT:
  273.                 {
  274.                     HWND hwndFocus;
  275.  
  276.                     hwndFocus = WinQueryFocus(HWND_DESKTOP);
  277.                     if (hwndFocus == hwndEFInput)
  278.                         WinSendMsg(hwndEFInput, EM_CUT, 0, 0);
  279.                     else if (hwndFocus == hwndMLEOutput)
  280.                              WinSendMsg(hwndMLEOutput, MLM_CUT, 0, 0);
  281.                 }; break;
  282.                 case IDM_COPY:
  283.                 {
  284.                     HWND hwndFocus;
  285.  
  286.                     hwndFocus = WinQueryFocus(HWND_DESKTOP);
  287.                     if (hwndFocus == hwndEFInput)
  288.                         WinSendMsg(hwndEFInput, EM_COPY, 0, 0);
  289.                     else if (hwndFocus == hwndMLEOutput)
  290.                              WinSendMsg(hwndMLEOutput, MLM_COPY, 0, 0);
  291.                 }; break;
  292.                 case IDM_PASTE:
  293.                 {
  294.                     HWND hwndFocus;
  295.  
  296.                     hwndFocus = WinQueryFocus(HWND_DESKTOP);
  297.                     if (hwndFocus == hwndEFInput)
  298.                         WinSendMsg(hwndEFInput, EM_PASTE, 0, 0);
  299.                     else if (hwndFocus == hwndMLEOutput)
  300.                              WinSendMsg(hwndMLEOutput, MLM_PASTE, 0, 0);
  301.                 }; break;
  302.                 case IDM_DEL:
  303.                 {
  304.                     HWND hwndFocus;
  305.  
  306.                     hwndFocus = WinQueryFocus(HWND_DESKTOP);
  307.                     if (hwndFocus == hwndEFInput)
  308.                         WinSendMsg(hwndEFInput, EM_CLEAR, 0, 0);
  309.                     else if (hwndFocus == hwndMLEOutput)
  310.                              WinSendMsg(hwndMLEOutput, MLM_CLEAR, 0, 0);
  311.                 }; break;
  312.                 case IDM_SOURCE:
  313.                     SourceFile(hwnd, hInPipe[1]);
  314.                     break;
  315.                 case IDM_HELP:
  316.                     WinMessageBox(HWND_DESKTOP, hwnd, "Help not yet implemented!",
  317.                                   szAppName, 0, MB_OK | MB_ICONEXCLAMATION);
  318.                     break;
  319.                 case IDM_ABOUT: 
  320.                     if (WinDlgBox(HWND_DESKTOP, hwnd, AboutProc, NULLHANDLE, ID_ABOUTDLG, NULL)
  321.                                             == DID_ERROR) {
  322.                                             puts("Errore!"); fflush(stdout);
  323.                                         }; break;
  324.             }
  325.             return (MPARAM)0;
  326.  
  327.         case WM_CLOSE:
  328.             if (AskConfirmation(hwnd) != MBID_YES)
  329.                 return 0;
  330.  
  331.         case WM_DESTROY:
  332.             DestroyInterp();
  333.             break;
  334.     }
  335.  
  336.     return (*pfnwp)(hwnd, msg, mp1, mp2);
  337. }
  338.  
  339.  
  340. MRESULT EXPENTRY AboutProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
  341. {
  342.     return (MRESULT)WinDefDlgProc(hwnd, msg, mp1, mp2);
  343. }
  344.  
  345.  
  346. void main(int argc, char **argv)
  347. {
  348.     int    consoleFlag;
  349.     QMSG   qmsg;
  350.     ULONG  ulf = FCF_STANDARD;
  351.     PFNWP  pfnwp;
  352.     HFILE  hFile;
  353.     APIRET rc;
  354.         char   stTitle[100];
  355. #ifdef WISH
  356.     int    ret;
  357. #endif
  358.     char st[500];
  359.  
  360.     consoleFlag = iscArg(argc, argv);
  361.  
  362.     hab = WinInitialize(0);
  363.     hmq = WinCreateMsgQueue(hab, 0);
  364.  
  365.     cxBorder = WinQuerySysValue(HWND_DESKTOP, SV_CXSIZEBORDER);
  366.     cyBorder = WinQuerySysValue(HWND_DESKTOP, SV_CYSIZEBORDER);
  367.     cyTitle = WinQuerySysValue(HWND_DESKTOP, SV_CYTITLEBAR);
  368.     cyMenu = WinQuerySysValue(HWND_DESKTOP, SV_CYMENU);
  369.  
  370.         sprintf(stTitle, "%s %d.%d", szAppName, majorVersion, minorVersion);
  371.     hwndFrame = WinCreateStdWindow(HWND_DESKTOP, WS_PARENTCLIP | WS_CLIPSIBLINGS | WS_CLIPCHILDREN,
  372.                                    &ulf, NULL, stTitle, 0, NULLHANDLE, TCLSHRC, NULL);
  373.     if (hwndFrame == NULLHANDLE)
  374.     {
  375.         WinMessageBox(HWND_DESKTOP, HWND_DESKTOP, "Window creation error...", szAppName,
  376.                       0, MB_OK | MB_ERROR);
  377.         exit(-1);
  378.     }
  379.  
  380.     /* frame subclassing */
  381.     pfnwp = WinSubclassWindow(hwndFrame, (PFNWP)WndProc);
  382.     WinSendMsg(hwndFrame, TCLSHM_PASSPARAM, (MPARAM)pfnwp, 0);
  383.  
  384.     WinSetWindowPos(hwndFrame, NULLHANDLE, 0, 0, 0, 0,
  385.                     (consoleFlag) ? SWP_MINIMIZE : SWP_SHOW);
  386.  
  387.     /* create pipes for input/output and redirict stdin, stdout, stderr */
  388.  
  389.     DosCreatePipe(&hInPipe[0], &hInPipe[1], 4096);
  390.     dup2(hInPipe[0], 0);    /* read stdin = read input pipe     */
  391.     DosCreatePipe(&hOutPipe[0], &hOutPipe[1], 4096);
  392.     dup2(hOutPipe[1], 1);    /* write stdout = write output pipe */
  393.     dup2(hOutPipe[1], 2);    /* write stderr = write output pipe */
  394.  
  395.     if (!CreateInterp(hwndFrame, hwndMLEOutput, hOutPipe[0]))
  396.     {
  397.         WinMessageBox(HWND_DESKTOP, HWND_DESKTOP, "Interpreter creation error...", szAppName,
  398.                       0, MB_OK | MB_ERROR);
  399.         exit(-3);
  400.     }
  401.  
  402.     while (WinGetMsg(hab, &qmsg, NULLHANDLE, 0, 0))
  403.         WinDispatchMsg(hab, &qmsg);
  404.  
  405.     WinDestroyWindow(hwndFrame);
  406.     WinDestroyMsgQueue(hmq);
  407.     WinTerminate(hab);
  408. }
  409.