home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 563.lha / NewShellCX_v1.07 / NewShellCX.c < prev    next >
C/C++ Source or Header  |  1991-09-05  |  17KB  |  540 lines

  1. /*
  2.  *  NewShellCX.c
  3.  *
  4.  *  Commodity
  5.  *
  6.  *  Author: Stefan Sticht
  7.  *
  8.  *  Copyright: source is public domain, no copyright
  9.  *
  10.  *  Version history:
  11.  *
  12.  *  V1.01   initial release
  13.  *  V1.03   recompiled with main.c V1.02
  14.  *  V1.04   completly rewritten; shared commodity code thrown away; smaller, uses less CPU time
  15.  *  V1.05   some really minor changes
  16.  *  V1.06   added PUBLICSCREEN option; suggested by Albert-Jan Brouwer
  17.  *  V1.07   added moveing the screen; suggested by Albert-Jan Brouwer
  18.  */
  19.  
  20. #define VERSION "V1.07"
  21.  
  22. /********************************************************************
  23.  *                             interfacing                          *
  24.  ********************************************************************/
  25.  
  26. /*
  27.  *  include files
  28.  */
  29.  
  30. #include <stdarg.h>
  31. #include <stdlib.h>
  32. #include <string.h>
  33. #include <dos/dos.h>
  34. #include <dos/dostags.h>
  35. #include <intuition/intuitionbase.h>
  36. #include <intuition/screens.h>
  37. #include <libraries/commodities.h>
  38.  
  39. #include <clib/alib_protos.h>
  40. #include <clib/commodities_protos.h>
  41. #include <pragmas/commodities_pragmas.h>
  42. #include <clib/dos_protos.h>
  43. #include <pragmas/dos_pragmas.h>
  44. #include <clib/exec_protos.h>
  45. #include <pragmas/exec_pragmas.h>
  46. #include <clib/intuition_protos.h>
  47. #include <pragmas/intuition_pragmas.h>
  48. #include <clib/utility_protos.h>
  49. #include <pragmas/utility_pragmas.h>
  50.  
  51. #ifdef DEBUG
  52. #define printf KPrintF
  53. #include <clib/dlib_protos.h>
  54. #endif
  55.  
  56. /*
  57.  *  prototypes
  58.  */
  59. long request(char *title, char *gadgets, char *text, ...);
  60. struct Library *myopenlibrary(char *name, unsigned long version);
  61. void processmessages(void);
  62.  
  63. /*
  64.  *  global data defined in other moduls
  65.  *
  66.  *  libraries opened by startup code; basepointers needed by function pragmas
  67.  */
  68. extern struct Library *DOSBase;
  69. extern struct Library *SysBase;
  70.  
  71. /*
  72.  *  Disable SAS/C CTRL/C handling
  73.  */
  74. void chkabort(void) {}
  75.  
  76. /********************************************************************
  77.  *                             global data                          *
  78.  ********************************************************************/
  79.  
  80. /*
  81.  *  definition of all messages (multi language support not completed yet)
  82.  */
  83. #ifdef GERMAN
  84.  
  85. #define RETRY_GADGETS           "Wiederholen|Abbrechen"
  86. #define RESUME_GADGETS          "Weiter"
  87. #define MSG_LIBRARY_OPENERR     "Die %s (V%ld+) kann nicht geöffnet werden!"
  88. #define COM_NAME                "NewShellCX"
  89. #define COM_DESCR               "Öffnet eine neue Shell mit "
  90. #define TT_HOTKEY               "TASTE"
  91. #define TT_COMMAND              "KOMMANDO"
  92. #define TT_PUBSCR               "PUBLICSCREEN"
  93. #define TT_MOVEX                "XBEWEGUNG"
  94. #define TT_MOVEY                "YBEWEGUNG"
  95. #define TT_MOVEABS              "ABSOLUTBEWEGUNG"
  96. #define NO                      "NEIN"
  97. #define YES                     "JA"
  98.  
  99. #else
  100.  
  101. #define RETRY_GADGETS           "Retry|Cancel"
  102. #define RESUME_GADGETS          "Resume"
  103. #define MSG_LIBRARY_OPENERR     "%s (V%ld+) can't be opened!"
  104. #define COM_NAME                "NewShellCX"
  105. #define COM_DESCR               "Open new shell on "
  106. #define TT_HOTKEY               "HOTKEY"
  107. #define TT_COMMAND              "COMMAND"
  108. #define TT_PUBSCR               "PUBLICSCREEN"
  109. #define TT_MOVEX                "MOVEX"
  110. #define TT_MOVEY                "MOVEY"
  111. #define TT_MOVEABS              "MOVEABSOLUTE"
  112. #define YES                     "YES"
  113. #define NO                      "NO"
  114.  
  115. #endif
  116.  
  117. #define COM_TITLE           COM_NAME " " VERSION
  118. #define CX_PRIORITY         "CX_PRIORITY"
  119. #define DEF_CX_PRIORITY     0
  120.  
  121. #define DEF_TT_HOTKEY       "lcommand esc"
  122. #define DEF_TT_COMMAND      "NewShell"
  123. #define DEF_TT_PUBSCR       ""
  124. #define DEF_TT_MOVEX        0
  125. #define DEF_TT_MOVEY        0
  126. #define DEF_TT_MOVEABS      NO
  127.  
  128. /*
  129.  *  library base pointers
  130.  */
  131. struct IntuitionBase *IntuitionBase;
  132. struct Library *CxBase;
  133. struct Library *IconBase;
  134. struct Library *UtilityBase;
  135.  
  136. /*
  137.  *  message port
  138.  */
  139. struct MsgPort *cxport = NULL;
  140.  
  141. /*
  142.  *  signal flag
  143.  */
  144. unsigned long cxsigflag = 0l;
  145.  
  146. /*
  147.  *  programtitle and version for Version command
  148.  */
  149. char versionstring[] ="\0$VER: " COM_NAME " " VERSION;
  150.  
  151. /*
  152.  *  helpstring
  153.  */
  154. #ifdef GERMAN
  155. char helpstring[] = "\033[1m" COM_NAME "\033[0m " VERSION " (Public Domain) von Stefan Sticht\n"\
  156.                     "Aufruf: " COM_NAME " [" CX_PRIORITY "=<Zahl>] [" TT_HOTKEY "=<Zeichenkette>] ["\
  157.                     TT_COMMAND "=<Zeichenkette>] [" TT_PUBSCR "=<Zeichenkette>] ["\
  158.                     TT_MOVEX "=<Zahl>] [" TT_MOVEY "=<Zahl>] [" TT_MOVEABS "=" YES "|" NO "]\n";
  159. #else
  160. char helpstring[] = "\033[1m" COM_NAME "\033[0m " VERSION " (Public Domain) by Stefan Sticht\n"
  161.                     "Usage: " COM_NAME " [" CX_PRIORITY "=<number>] [" TT_HOTKEY "=<string>] ["\
  162.                     TT_COMMAND "=<string>] [" TT_PUBSCR "=<string>] ["\
  163.                     TT_MOVEX "=<number>] [" TT_MOVEY "=<number>] [" TT_MOVEABS "=" YES "|" NO "]\n";
  164. #endif
  165.  
  166. /*
  167.  *  the tooltypearray
  168.  */
  169. char **tooltypes;
  170.  
  171. /*
  172.  *  our broker
  173.  */
  174. CxObj *broker = NULL;
  175.  
  176. /*
  177.  *  our commodity description
  178.  */
  179. char descr[CBD_DESCRLEN + 1] = COM_DESCR;
  180.  
  181. /*
  182.  *  the command
  183.  */
  184. char *command;
  185. /*
  186.  *  name of publicscreen to pop to front
  187.  */
  188. char *pubscr;
  189. /*
  190.  *  variables for the screen movements
  191.  */
  192. short move = FALSE;
  193. short movex;
  194. short movey;
  195. short moveabs = FALSE;
  196. /*
  197.  *  or defaultpubscr = TRUE, if the default one should go to front
  198.  */
  199. defaultpubscr = FALSE;
  200.  
  201. struct NewBroker newbroker = {
  202.     NB_VERSION,                         /* BYTE nb_Version               */
  203.     COM_NAME,                           /* BYTE *nb_Name                 */
  204.     COM_TITLE,                          /* BYTE *nb_Title                */
  205.     descr,                              /* BYTE *nb_Descr                */
  206.     NBU_NOTIFY | NBU_UNIQUE,            /* SHORT nb_Unique               */
  207.     0,                                  /* SHORT nb_Flags                */
  208.     0,                                  /* BYTE nb_Pri                   */
  209.     NULL,                               /* struct MsgPort nb_Port        */
  210.     0                                   /* WORD nb_ReservedChannel       */
  211. };
  212.  
  213. #define NEWSHELL 1
  214.  
  215. /*
  216.  *  TagItem structure for System()
  217.  */
  218. #define P_SYS_Input     0
  219. #define P_SYS_Output    1
  220. struct TagItem systemtags[] = {
  221.     SYS_Input, 0l,
  222.     SYS_Output, 0l,
  223.     SYS_Asynch, TRUE,
  224.     SYS_UserShell, TRUE,
  225.     TAG_DONE
  226.     };
  227.  
  228. /********************************************************************
  229.  *                             functions                            *
  230.  ********************************************************************/
  231.  
  232. /*
  233.  *  request(): a glue routine to EasyRequest as simple as printf plus
  234.  *             titlestring, gadgettexts
  235.  *
  236.  *  Input: char *title:         pointer to the title of the requester
  237.  *         char *gadgets:       pointer to gadgettext
  238.  *         char *text:          text displayed in requester
  239.  *
  240.  *  Result: same as EasyrequestArgs()
  241.  *
  242.  * !!! for more info see EasyRequestArgs() in Autodocs/intuition.doc !!!
  243.  */
  244. long request(char *title, char *gadgets, char *text, ...)
  245. {
  246.     /*
  247.      *  structure textreq only needed in this function, so hide it here
  248.      *  must be static, in order to be initialized only once
  249.      */
  250.     static struct EasyStruct textreq = {
  251.         sizeof (struct EasyStruct), /* ULONG es_StructSize      */
  252.         0l,                         /* ULONG es_Flags           */
  253.         NULL,                       /* UBYTE *es_Title          */
  254.         NULL,                       /* UBYTE *es_TextFormat     */
  255.         NULL,                       /* UBYTE *es_GadgetFormat   */
  256.         };
  257.     va_list ap;
  258.     long rc;
  259.  
  260.     /*
  261.      *  get start of variable arguments
  262.      */
  263.     va_start(ap, text);
  264.  
  265.     /*
  266.      *  update textreq
  267.      */
  268.     textreq.es_Title = (UBYTE *)title;
  269.     textreq.es_TextFormat = (UBYTE *)text;
  270.     textreq.es_GadgetFormat = (UBYTE *)gadgets;
  271.  
  272.     /*
  273.      *  win may be NULL
  274.      */
  275.     rc = EasyRequestArgs(NULL, &textreq, NULL, ap);
  276.  
  277.     va_end(ap);
  278.  
  279.     return(rc);
  280. }
  281.  
  282. /*
  283.  *  myopenlibrary(): same as OpenLibrary(), but opens a retry-requester
  284.  *                   if OpenLibrary() fails, to give the user a chance to
  285.  *                   copy the library to libs: and retry
  286.  *                   requires request(), see above
  287.  */
  288. struct Library *myopenlibrary(char *name, unsigned long version)
  289. {
  290.     static char errortext[] = MSG_LIBRARY_OPENERR;
  291.     struct Library *libptr;
  292.     long ok = TRUE;
  293.  
  294.     do {
  295.         if (!(libptr = OpenLibrary((UBYTE *)name, version))) {
  296.             if (IntuitionBase) ok = request(COM_NAME ":", RETRY_GADGETS, errortext, name, version);
  297.             else ok = FALSE;
  298.             }
  299.         } while (!libptr && ok);
  300.  
  301.     return(libptr);
  302. }
  303.  
  304. void main(int argc, char *argv[])
  305. {
  306.     CxObj *filter;
  307.     char *hotkey;
  308.     char *absolutemove;
  309.     struct Message *msg;
  310.     unsigned long len;
  311.  
  312.     if ((argc > 1) && (*argv[1] == '?')) {
  313.         /*
  314.          *  display help string
  315.          */
  316.         Write(Output(), helpstring, sizeof(helpstring) - 1l);
  317.         return;
  318.         }
  319.  
  320.     /*
  321.      *  open required libraries first
  322.      */
  323.     if (IntuitionBase = (struct IntuitionBase *)myopenlibrary("intuition.library", 37l)) {
  324.  
  325.         if (CxBase = myopenlibrary("commodities.library", 37l)) {
  326.  
  327.             if (IconBase = myopenlibrary("icon.library", 37l)) {
  328.                 /*
  329.                  * create tooltypes array (requires icon.library open!!!)
  330.                  */
  331.                 tooltypes = (char **)ArgArrayInit(argc, argv);
  332.                 /*
  333.                  *  create our message port
  334.                  */
  335.                 if (cxport = CreateMsgPort()) {
  336.  
  337.                     cxsigflag = 1l << cxport->mp_SigBit;
  338.                     /*
  339.                      * set up some broker data
  340.                      */
  341.                     newbroker.nb_Pri = ArgInt(tooltypes, CX_PRIORITY, DEF_CX_PRIORITY);
  342.                     newbroker.nb_Port = cxport;
  343.  
  344.                     command = ArgString(tooltypes, TT_COMMAND, DEF_TT_COMMAND);
  345.  
  346.                     movex = (short)ArgInt(tooltypes, TT_MOVEX, DEF_TT_MOVEX);
  347.                     movey = (short)ArgInt(tooltypes, TT_MOVEY, DEF_TT_MOVEY);
  348.  
  349.                     /*
  350.                      *  shall we pop a public screen to front ?
  351.                      */
  352.                     pubscr = ArgString(tooltypes, TT_PUBSCR, DEF_TT_PUBSCR);
  353.                     absolutemove = ArgString(tooltypes, TT_MOVEABS, DEF_TT_MOVEABS);
  354.                     if ((pubscr || absolutemove) && (UtilityBase = myopenlibrary("utility.library", 37l))) {
  355.                         if (pubscr && !Stricmp(pubscr, "DEFAULT")) {
  356.                             /*
  357.                              *  user wants default public screen to front
  358.                              */
  359.                             defaultpubscr = TRUE;
  360.                             pubscr = NULL;
  361.                             }
  362.                         /*
  363.                          *  absolute screen movement?
  364.                          */
  365.                         #ifdef DEBUG
  366.                         printf("main(): absolutemove = %s\n", absolutemove);
  367.                         #endif
  368.                         if (absolutemove && !Stricmp(absolutemove, YES)) moveabs = TRUE;
  369.                         CloseLibrary(UtilityBase);
  370.                         }
  371.  
  372.                     /*
  373.                      *  check if a screen shall be moved
  374.                      */
  375.                     if (((pubscr && *pubscr) || defaultpubscr) && (movex || movey || moveabs)) move = TRUE;
  376.  
  377.                     if ((hotkey = ArgString(tooltypes, TT_HOTKEY, DEF_TT_HOTKEY)) &&
  378.                         *hotkey && command && *command) {
  379.  
  380.                         len = strlen(descr);
  381.                         strncpy(descr + len, hotkey, sizeof(descr) - len - 2l);
  382.  
  383.                         if (broker = CxBroker(&newbroker, NULL)) {
  384.  
  385.                             if (filter = HotKey(hotkey, cxport, NEWSHELL)) {
  386.  
  387.                                 AttachCxObj(broker, filter);
  388.  
  389.                                 if (!CxObjError(filter)) {
  390.  
  391.                                     /*
  392.                                      *  activate our commodity
  393.                                      */
  394.                                     ActivateCxObj(broker, 1l);
  395.                                     /*
  396.                                      *  now watch our numerous ports
  397.                                      */
  398.                                     processmessages();
  399.  
  400.                                     } /* if !CxObjError() */
  401.  
  402.                                 } /* if centerfilter */
  403.  
  404.                             DeleteCxObjAll(broker);
  405.  
  406.                             } /* if broker */
  407.  
  408.                         #ifdef DEBUG
  409.                         else printf("main(): CxBroker() failed!\n");
  410.                         #endif
  411.  
  412.                         } /* if hotkey */
  413.  
  414.                     /*
  415.                      *  delete our message port after replying all pending messages
  416.                      */
  417.                     while (msg = GetMsg(cxport)) ReplyMsg(msg);
  418.                     DeleteMsgPort(cxport);
  419.  
  420.                     } /* if cxport */
  421.  
  422.                 #ifdef DEBUG
  423.                 else printf("main(): CraeteMsgPort() failed!\n");
  424.                 #endif
  425.  
  426.                 ArgArrayDone();
  427.  
  428.                 CloseLibrary(IconBase);
  429.                 } /* if IconBase */
  430.  
  431.             CloseLibrary(CxBase);
  432.             } /* if CxBase */
  433.  
  434.     CloseLibrary((struct Library *)IntuitionBase);
  435.     } /* if IntuitionBase */
  436.  
  437. } /* main() */
  438.  
  439. void processmessages(void)
  440. {
  441.     BPTR fh;
  442.     struct Screen *scr;
  443.     struct Message *msg;
  444.     unsigned long msgid;
  445.     unsigned long msgtype;
  446.     unsigned long sigreceived;
  447.     unsigned short quit = FALSE;
  448.  
  449.     while (!quit) {
  450.  
  451.         sigreceived = Wait(SIGBREAKF_CTRL_C | cxsigflag);
  452.  
  453.         #ifdef DEBUG
  454.         printf("processmessages(): signal received\n");
  455.         #endif
  456.  
  457.         if (sigreceived & SIGBREAKF_CTRL_C) quit = TRUE;
  458.  
  459.         if (sigreceived & cxsigflag) {
  460.  
  461.             while (msg = (struct Message *)GetMsg(cxport)) {
  462.  
  463.                 msgid = CxMsgID((CxMsg *)msg);
  464.                 msgtype = CxMsgType((CxMsg *)msg);
  465.  
  466.                 ReplyMsg(msg);
  467.  
  468.                 switch (msgtype) {
  469.  
  470.                     case CXM_IEVENT:
  471.                         switch (msgid) {
  472.  
  473.                             case NEWSHELL:
  474.  
  475.                                 fh = Open("NIL:", MODE_NEWFILE);
  476.                                 systemtags[P_SYS_Input].ti_Data = (ULONG)fh;
  477.                                 fh = Open("NIL:", MODE_NEWFILE);
  478.                                 systemtags[P_SYS_Output].ti_Data = (ULONG)fh;
  479.                                 System(command, systemtags);
  480.  
  481.                                 if ((pubscr && *pubscr) || defaultpubscr) {
  482.                                     /*
  483.                                      *  try to lock public screen with name in pubscr
  484.                                      */
  485.                                     if (scr = LockPubScreen(pubscr)) {
  486.  
  487.                                         if (move) {
  488.                                             #ifdef DEBUG
  489.                                             printf("processmessages(): moving screen; x = %ld, y = %ld, abs = %ld\n", movex, movey, moveabs);
  490.                                             #endif
  491.                                             if (!moveabs) MoveScreen(scr, movex, movey);
  492.                                             else if ((scr->LeftEdge != movex) || (scr->TopEdge != movey)) {
  493.                                                 short x, y;
  494.                                                 x = movex - scr->LeftEdge;
  495.                                                 y = movey - scr->TopEdge;
  496.                                                 MoveScreen(scr, x, y);
  497.                                                 }
  498.                                             }
  499.                                         if (scr != IntuitionBase->FirstScreen) ScreenToFront(scr);
  500.  
  501.                                         UnlockPubScreen(NULL, scr);
  502.  
  503.                                         }
  504.                                     }
  505.                                 break;
  506.  
  507.                             } /* switch msgid */
  508.  
  509.                         break;
  510.  
  511.                     case CXM_COMMAND:
  512.                         switch (msgid) {
  513.  
  514.                             case CXCMD_UNIQUE:
  515.                             case CXCMD_KILL:
  516.                                 quit = TRUE;
  517.                                 break;
  518.  
  519.                             case CXCMD_DISABLE:
  520.                                 ActivateCxObj(broker, 0l);
  521.                                 break;
  522.  
  523.                             case CXCMD_ENABLE:
  524.                                 ActivateCxObj(broker, 1l);
  525.                                 break;
  526.  
  527.                             }
  528.                         break;
  529.  
  530.                     } /* switch msgtype */
  531.  
  532.                 } /* while CxMsg */
  533.  
  534.             } /* if (sigreceived & cxsigflag) */
  535.  
  536.         } /* while !quit */
  537.  
  538.     ActivateCxObj(broker, 0l);
  539. }
  540.