C   176
XPanel
Guest on 26th June 2022 03:57:59 AM


  1. #define VERSION_ID  "15-nov-95"
  2. /*= XPANEL - X-window control panel program */
  3. /*& jm */
  4. /*: tools */
  5. /*+
  6. XPanel is a TCP/IP server based on X-windows, which listens for
  7. connections from the Miriad "ctrl" routines, constructs a control
  8. panel according to commands from the Ctrl routines, and allows the
  9. user and programmer to communicate through the control panel.
  10.  
  11. See the Miriad Programmers manual for documentation of the Ctrl
  12. routines.
  13.  
  14. For X users familiar with application resources, the user may
  15. set up characteristics for individual panel items.  The Widget
  16. tree layout used by Xpanel is shown below:
  17.         Level 1:
  18.         Top level shell:        "Xpanel"
  19.  
  20.         Level 2:
  21.         Child of "Xpanel":      "Miriad Control Panel" (PopupShell)
  22.  
  23.         Level 3:
  24.         Child of "Miriad Control Panel":        "panel"      (formWidget)
  25.  
  26.         Level 4:
  27.         Children of "panel":    "button"     (commandWidget)
  28.                                 "list"       (commandWidget)
  29.                                 "status"     (labelWidget)
  30.                                 "slider"     (formWidget)
  31.                                 "cursor"     (coreWidget)
  32.  
  33.         Level 5:
  34.         Child of "list":        "ButtonList" (transientWidget)
  35.  
  36.         Children of "slider":   "Slab"       (labelWidget)
  37.                                 "Sval"       (labelWidget)
  38.                                 "Smin"       (labelWidget)
  39.                                 "Scroll"     (scrollbarWidget)
  40.                                 "Smax"       (labelWidget)
  41.  
  42.         Level 6:
  43.         Child of "ButtonList":  "MenuBox"    (boxWidget)
  44.  
  45.         Level 7:
  46.         Child of "MenuBox":     list entry  (commandWidget)
  47.  
  48. In addition to the above widget items, there are application
  49. resources that the user may set in their application file or
  50. on the command line.  In addition to the usual X-window resources,
  51. Xpanel provides the following resources, along with their defaults:
  52.  
  53.    *cursorForeground:   "XtDefaultForeground" (Fore/Background color of)
  54.    *cursorBackground:   "XtDefaultBackground" (... cursor in coreWidget)
  55.    *noIconic:           False             (Start application non-iconic)
  56.    *Font:               "9x15"                   (Font used for strings)
  57.    *portNumber:         5001       (Port number used for communications)
  58.  */
  59. /*--
  60.  
  61.   History:
  62.     jm  16sep91 Original based on SunView panel routine.
  63.     mjs 21sep93 #define bzero -> memset on sun; make in-code docs
  64.                 compatible with miriad docs; make icon "unsigned char".
  65.     jm  31oct94 Fixed problem that would not let port number be
  66.                 reassigned (also added a message).  Also, cleaned
  67.                 socket code section and removed some global
  68.                 variables they depended on.
  69.     rjs 15feb95 Added htons/ntohs to buffer exchange.
  70.     rjs 16aug95 Do not expect a full read to always work (added readit).
  71.     jm  01sep95 Finally found the bug causing this to bomb under Solaris
  72.                 (I was releasing memory that was not allocated for the
  73.                 buttonlist array and was also freeing the Nth member
  74.                 instead of the pointer to the array itself).
  75.     jm  15nov95 Corrected some routine declarations.  Also corrected
  76.                 the initial iconic state setting.
  77.     jm  16may97 Fixed options table so it properly calls the resources.
  78. *************************************************************************/
  79. #include <stdlib.h>
  80. #include <stdio.h>
  81. #include <sys/time.h>
  82. #include <sys/types.h>
  83. #include <sys/socket.h>
  84. #include <X11/Intrinsic.h>
  85. #include <X11/StringDefs.h>
  86. #include <X11/Shell.h>
  87. #include <X11/cursorfont.h>
  88. #include <X11/Xmu/Misc.h>
  89. #include <X11/Xaw/Box.h>
  90. #include <X11/Xaw/Command.h>
  91. #include <X11/Xaw/Form.h>
  92. #include <X11/Xaw/Label.h>
  93. #include <X11/Xaw/List.h>
  94. #include <X11/Xaw/Scrollbar.h>
  95. #include <netdb.h>
  96. #include <netinet/in.h>
  97. #include "xpanel.icon"
  98.  
  99. #ifdef sun
  100. #define bzero(a,b) memset((a),0,(b))
  101. #endif
  102.  
  103. #define CTRL_DEFINE     1
  104. #define CTRL_DISPLAY    2
  105. #define CTRL_CLEAR      3
  106. #define CTRL_CHECK      4
  107. #define CTRL_WAIT       5
  108. #define CTRL_SET        6
  109. #define CTRL_DONE       7
  110.  
  111. #define PORT 5001
  112. #define PANEL_WIDTH 13
  113. #define MAXBUF 1024
  114. #define CHECKTIME 100   /* Number of milli-s to wait before */
  115.                         /* looking for new connections. */
  116.  
  117. static int ioSocket;
  118. static int connected, visible, waiting, changes;
  119. static int cursorx, cursory, cursor_changes, ncursors;
  120.  
  121. static Widget top_level;
  122. static Widget subframe;
  123. static GC gc;
  124.  
  125. static XtAppContext context;
  126.  
  127. typedef struct items {  char *values;
  128.                         int type,nvalues,changes,itno;
  129.                         int sval;        /* used by scrollbars and lists.*/
  130.                         int smin,smax,slen; /* used only with scrollbars.*/
  131.                         Widget main;
  132.                         String *buttonlist; /* List of item values in a popup.*/
  133.                         struct items *fwd; } ITEMS;
  134. static ITEMS *items_head = (ITEMS *)NULL;
  135.  
  136. #define ITEM_BUTTONS 1
  137. #define ITEM_SLIDERS 2
  138. #define ITEM_CURSORS 3
  139. #define ITEM_STATUSES 4
  140.  
  141. #if NeedFunctionPrototypes
  142. #define ARGS(args)  args
  143. #else
  144. #define ARGS(args) ()
  145. #endif /* NeedFunctionPrototypes */
  146.  
  147. static void initializeSocket ARGS(( unsigned int ));
  148. static void checkSocket ARGS(( XtPointer, XtIntervalId * ));
  149. static void readSocket ARGS(( XtPointer, int *, XtInputId * ));
  150. static void clear_control_panel ARGS(( void ));
  151. static void check_control_panel ARGS(( int ));
  152. static void wait_control_panel ARGS(( void ));
  153. static void define_control_panel ARGS(( short int message[] ));
  154. static void set_control_panel ARGS(( short int message[] ));
  155. static void destroy_control_panel ARGS(( void ));
  156. static void create_control_panel ARGS(( void ));
  157. static void CursorPaint ARGS(( Widget, XEvent *, String *, Cardinal * ));
  158. static void CursorEvents ARGS(( Widget, XEvent *, String *, Cardinal * ));
  159. static void SetUpListMenu ARGS(( ITEMS *, int ));
  160. static void SetUpSlider ARGS(( ITEMS *, Cursor, int, int, int ));
  161. static void LabelScrollBarValue ARGS(( Widget, int ));
  162. static void LabelScrollBarMinMax ARGS(( Widget, int, int ));
  163. static void PlaceMenu ARGS(( Widget, XtPointer, XtPointer ));
  164. static void ListButtonPushed ARGS(( Widget, XtPointer, XtPointer ));
  165. static void button_next ARGS(( Widget, XtPointer, XtPointer ));
  166. static void button_changed ARGS(( Widget, XtPointer, XtPointer ));
  167. static void SliderScrollProc ARGS(( Widget, XtPointer, XtPointer ));
  168. static void SliderJumpProc ARGS(( Widget, XtPointer, XtPointer ));
  169. static void UpdateScroll ARGS(( Widget, XEvent *, String *, Cardinal * ));
  170. static void QuitPanel ARGS(( Widget, XEvent *, String *, Cardinal * ));
  171.  
  172. typedef struct {
  173.   Pixel       cursor_foreground;
  174.   Pixel       cursor_background;
  175.   Boolean     no_iconic;
  176.   int         port_number;
  177.   XFontStruct *font;
  178. } ApplicationData;
  179.  
  180. static ApplicationData App_Data;
  181.  
  182. #define Offset(field) XtOffsetOf(ApplicationData, field)
  183. static XtResource resources[] = {
  184.   {"cursorForeground", "CursorForeground", XtRPixel,      sizeof(Pixel),
  185.       Offset(cursor_foreground), XtRString,    (XtPointer)XtDefaultForeground},
  186.   {"cursorBackground", "CursorBackground", XtRPixel,      sizeof(Pixel),
  187.       Offset(cursor_background), XtRString,    (XtPointer)XtDefaultBackground},
  188.   {"noIconic",         "NoIconic",         XtRBoolean,    sizeof(Boolean),
  189.       Offset(no_iconic),         XtRImmediate, (XtPointer)False},
  190.   {"portNumber",       "PortNumber",       XtRInt,        sizeof(int),
  191.       Offset(port_number),       XtRImmediate, (XtPointer)PORT},
  192.   {XtNfont,             XtCFont,           XtRFontStruct, sizeof(XFontStruct *),
  193.       Offset(font),              XtRString,    (XtPointer)"9x15"},
  194. };
  195. #undef Offset
  196.  
  197. static XtActionsRec actionTable[] = {
  198.   {"quitpanel",    QuitPanel},
  199.   {"cursorpaint",  CursorPaint},
  200.   {"cursorevents", CursorEvents},
  201.   {"updatescroll", UpdateScroll},
  202.   {NULL, NULL}
  203. };
  204.  
  205. static XrmOptionDescRec options[] = {
  206.   {"-cursorforeground", "cursorForeground", XrmoptionSepArg, (XtPointer)NULL},
  207.   {"-cfg",              "cursorForeground", XrmoptionSepArg, (XtPointer)NULL},
  208.   {"-cursorbackground", "cursorBackground", XrmoptionSepArg, (XtPointer)NULL},
  209.   {"-cbg",              "cursorBackground", XrmoptionSepArg, (XtPointer)NULL},
  210.   {"-port",             "portNumber",       XrmoptionSepArg, (XtPointer)NULL},
  211.   {"-noiconic",         "noIconic",         XrmoptionNoArg,  "TRUE"},
  212. };
  213.  
  214. static String fallback_resources[] = {
  215.   NULL,
  216. };
  217.  
  218. /************************************************************************/
  219. #if NeedFunctionPrototypes
  220. static void bug(char *string)
  221. #else
  222. static void bug(string)
  223. char *string;
  224. #endif /* NeedFunctionPrototypes */
  225. {
  226.     perror(string);
  227.     exit(-1);
  228. }
  229.  
  230. /************************************************************************/
  231. #if NeedFunctionPrototypes
  232. static int readit(int fd, char *buff, int size)
  233. #else
  234. static int readit(fd, buff, size)
  235. int fd, size;
  236. char *buff;
  237. #endif /* NeedFunctionPrototypes */
  238. {
  239.   int nread, n;
  240.   unsigned int amount;
  241.  
  242.   nread = 0;
  243.   while (nread < size) {
  244.     amount = size - nread;
  245.     n = read(fd, buff+nread, amount);
  246.     if (n == 0) return(nread);
  247.     nread += n;
  248.   }
  249.  
  250.   return(nread);
  251. }
  252.  
  253. /************************************************************************/
  254. #if NeedFunctionPrototypes
  255. int main(int argc, char *argv[])
  256. #else
  257. int main(argc, argv)
  258. int argc;
  259. char *argv[];
  260. #endif /* NeedFunctionPrototypes */
  261. {
  262.   int i;
  263.   unsigned int Port; /* Used to identify the communications socket number. */
  264.   Arg args[10];
  265.   Pixmap iconPixmap;
  266.   XGCValues gcv;
  267.   static String QuitTrans = "#override \n\
  268.                        !<Key>Escape: quitpanel()";
  269.  
  270. /* Create the base level frame. */
  271.  
  272.   (void)fprintf(stderr,"PANEL: %s\n",VERSION_ID);
  273.  
  274.   top_level = XtAppInitialize(&context, "Xpanel", options, XtNumber(options),
  275.        &argc, argv, fallback_resources, NULL, (Cardinal)0);
  276.  
  277.   XtGetApplicationResources(top_level, (XtPointer)&App_Data,
  278.        resources, XtNumber(resources), NULL, (Cardinal)0);
  279.  
  280.   XtAppAddActions(context, actionTable, XtNumber(actionTable));
  281.  
  282.   i = 0;
  283.   if (App_Data.no_iconic == False) {
  284.     XtSetArg(args[i], XtNinitialState,   (XtArgVal)IconicState); i++;
  285.   }
  286.   XtSetArg(args[i], XtNheight,                    (XtArgVal)64); i++;
  287.   XtSetArg(args[i], XtNwidth,                    (XtArgVal)200); i++;
  288.   XtSetArg(args[i], XtNtitle, (XtArgVal)"Miriad Control Panel"); i++;
  289.   XtSetValues(top_level, args, i);
  290.  
  291.   XtOverrideTranslations(top_level, XtParseTranslationTable(QuitTrans));
  292.  
  293.   XtRealizeWidget(top_level);
  294.  
  295.   iconPixmap = XCreateBitmapFromData(XtDisplay(top_level),
  296.        XtWindow(top_level), (char *)xpanel_bits, xpanel_width, xpanel_height);
  297.  
  298.   i = 0;
  299.   XtSetArg(args[i], XtNiconPixmap, iconPixmap); i++;
  300.   XtSetValues(top_level, args, i);
  301.  
  302.   gcv.foreground = App_Data.cursor_foreground;
  303.   gcv.background = App_Data.cursor_background;
  304.   gc = XCreateGC(XtDisplay(top_level), XtWindow(top_level),
  305.          (GCForeground | GCBackground), &gcv);
  306.  
  307.   waiting = False;
  308.   changes = 0;
  309.   connected = False;
  310.   visible = False;
  311.  
  312. /* Get a socket for accepting connections and then start the timer. */
  313.   Port = App_Data.port_number;
  314.   if (Port != PORT)
  315.     (void)fprintf(stderr,
  316.       "PANEL: Re-assigning the I/O Port number from %d to %d\n", PORT, Port);
  317.   initializeSocket(Port);
  318.  
  319. /* Wait for connections, and go into the main loop. */
  320.  
  321.   XtAppMainLoop(context);
  322.   return(0);
  323. }
  324.  
  325. /************************************************************************/
  326. #if NeedFunctionPrototypes
  327. static void startTimer(int socketID)
  328. #else
  329. static void startTimer(socketID)
  330. int socketID;
  331. #endif /* NeedFunctionPrototypes */
  332. {
  333.   unsigned long interval = CHECKTIME; /* in milli-seconds */
  334.  
  335.   (void)XtAppAddTimeOut(context, interval, checkSocket, (XtPointer)socketID);
  336.  
  337.   return;
  338. }
  339.  
  340. /************************************************************************/
  341. #if NeedFunctionPrototypes
  342. static void initializeSocket(unsigned int portnumber)
  343. #else
  344. static void initializeSocket(portnumber)
  345. unsigned int portnumber;
  346. #endif /* NeedFunctionPrototypes */
  347. {
  348.   int listenSocket;
  349.   struct sockaddr_in sin;
  350.  
  351. /* Get a socket to the outside world, and bind to it. */
  352.  
  353.   bzero((char *)&sin, sizeof(sin));
  354.   sin.sin_family = AF_INET;
  355.   sin.sin_port = htons(portnumber);
  356.   sin.sin_addr.s_addr = htonl(INADDR_ANY);
  357.  
  358.   if ((listenSocket = socket(AF_INET, SOCK_STREAM, 0)) < 0)
  359.     bug("initializeSocket:socket");
  360.   if (bind(listenSocket, (struct sockaddr *)&sin, sizeof(sin)) < 0)
  361.     bug("initializeSocket:bind");
  362.   listen(listenSocket, 5);
  363.   startTimer(listenSocket);
  364.  
  365.   return;
  366. }
  367.  
  368. /************************************************************************/
  369. /* ARGSUSED */
  370. #if NeedFunctionPrototypes
  371. static void checkSocket(XtPointer clientData, XtIntervalId *ptrTimer)
  372. #else
  373. static void checkSocket(clientData, ptrTimer)
  374. XtPointer clientData;
  375. XtIntervalId *ptrTimer;
  376. #endif /* NeedFunctionPrototypes */
  377. {
  378.   int len;
  379.   int listenSocket;
  380.   fd_set read_mask;
  381.   struct timeval time_0;
  382.   struct sockaddr_in addr;
  383.   XtInputMask condition = XtInputReadMask;
  384.  
  385.   time_0.tv_sec = 0;
  386.   time_0.tv_usec = 0;
  387.  
  388.   listenSocket = (int)clientData;
  389.   startTimer(listenSocket);
  390.  
  391.   if (connected == False) {
  392.     FD_ZERO(&read_mask);
  393.     FD_SET(listenSocket, &read_mask);
  394.     if (select(listenSocket+1, &read_mask, (fd_set *)NULL,
  395.       (fd_set *)NULL, &time_0) > 0) {
  396.       len = sizeof(addr);
  397.       if ((ioSocket = accept(listenSocket, (struct sockaddr *)&addr, &len)) < 0)
  398.         bug("checkSocket:accept");
  399.       (void)XtAppAddInput(context, ioSocket, (XtPointer)condition,
  400.         readSocket, (XtPointer)NULL);
  401.       connected = True;
  402.     }
  403.   }
  404.  
  405.   return;
  406. }
  407.  
  408. /************************************************************************/
  409. /* ARGSUSED */
  410. #if NeedFunctionPrototypes
  411. static void readSocket(XtPointer dummy, int *iosocket, XtInputId *fdid)
  412. #else
  413. static void readSocket(dummy, iosocket, fdid)
  414. XtPointer dummy;  /* Unused */
  415. int *iosocket;
  416. XtInputId *fdid;
  417. #endif /* NeedFunctionPrototypes */
  418. {
  419.   int fd,nread,size,i;
  420.   short int buffer[MAXBUF];
  421.  
  422.   fd = *iosocket;
  423.   size=2;
  424.   nread = readit(fd,(char *)buffer,2*size);
  425.   buffer[0] = ntohs(buffer[0]);
  426.   buffer[1] = ntohs(buffer[1]);
  427.   if(nread != 2*size){
  428.     (void)close(fd);
  429.     XtRemoveInput(*fdid);
  430.     destroy_control_panel();
  431.   }else if(buffer[0] == CTRL_DEFINE){
  432.     size = buffer[1] + 2;
  433.     nread = readit(fd,(char *)&buffer[2],2*size);
  434.     if(nread < 2*size) bug("Unexpected End-of-Data");
  435.     size+=2;
  436.     for(i=2; i < size; i++)buffer[i] = ntohs(buffer[i]);
  437.     define_control_panel(buffer);
  438.   }else if(buffer[0] == CTRL_DISPLAY){
  439.     create_control_panel();
  440.   }else if(buffer[0] == CTRL_CLEAR){
  441.     clear_control_panel();
  442.   }else if(buffer[0] == CTRL_CHECK){
  443.     check_control_panel(buffer[1]);
  444.   }else if(buffer[0] == CTRL_WAIT){
  445.     wait_control_panel();
  446.   }else if(buffer[0] == CTRL_SET){
  447.     size = buffer[1] + 1;
  448.     nread = readit(fd,(char *)&buffer[2],2*size);
  449.     if(nread < 2*size) bug("Unexpected End-of-Data");
  450.     size+=2;
  451.     for(i=2; i < size; i++)buffer[i] = ntohs(buffer[i]);
  452.     set_control_panel(buffer);
  453.   }else if(buffer[0] == CTRL_DONE){
  454.     (void)close(fd);
  455.     XtRemoveInput(*fdid);
  456.     destroy_control_panel();
  457.   }else bug("readSocket:I should never get here");
  458.  
  459.   return;
  460. }
  461.  
  462. /************************************************************************/
  463. #if NeedFunctionPrototypes
  464. static void clear_control_panel(void)
  465. #else
  466. static void clear_control_panel()
  467. #endif /* NeedFunctionPrototypes */
  468. /*
  469.   Clear all the flags that say something has changed.
  470. ------------------------------------------------------------------------*/
  471. {
  472.   ITEMS *ip;
  473.  
  474.   changes = 0;
  475.   for(ip = items_head; ip != (ITEMS *)NULL; ip = ip->fwd) ip->changes = 0;
  476.   cursor_changes = 0;
  477.  
  478.   return;
  479. }
  480.  
  481. /************************************************************************/
  482. #if NeedFunctionPrototypes
  483. static void check_control_panel(int itno)
  484. #else
  485. static void check_control_panel(itno)
  486. int itno;
  487. #endif /* NeedFunctionPrototypes */
  488. /*
  489.   Check the current state of a particular item.
  490. ------------------------------------------------------------------------*/
  491. {
  492.   ITEMS *ip;
  493.   short int buf[4];
  494.  
  495.   for(ip = items_head; ip != (ITEMS *)NULL && ip->itno != itno; ip = ip->fwd);
  496.   if(ip == (ITEMS *)NULL) bug("check_control_panel: Did not find the item");
  497.  
  498.   buf[2] = 0;
  499.   buf[3] = 0;
  500.   if(ip->type == ITEM_SLIDERS){
  501.     buf[2] = ip->smin + ((ip->smax - ip->smin) * ip->sval / ip->slen);
  502.   }else if(ip->type == ITEM_BUTTONS && ip->nvalues > 1){
  503.     buf[2] = ip->sval;
  504.   }else if(ip->type == ITEM_CURSORS){
  505.     buf[2] = cursorx;
  506.     buf[3] = 99 - cursory;
  507.     ip->changes = cursor_changes;
  508.     cursor_changes = 0;
  509.   }
  510.   buf[0] = ip->itno;
  511.   buf[1] = ip->changes;
  512.   changes -= ip->changes;
  513.   ip->changes = 0;
  514.   buf[0] = htons(buf[0]);
  515.   buf[1] = htons(buf[1]);
  516.   buf[2] = htons(buf[2]);
  517.   buf[3] = htons(buf[3]);
  518.   (void)write(ioSocket,(char *)buf,8);
  519.  
  520.   return;
  521. }
  522.  
  523. /************************************************************************/
  524. #if NeedFunctionPrototypes
  525. static void wait_control_panel(void)
  526. #else
  527. static void wait_control_panel()
  528. #endif /* NeedFunctionPrototypes */
  529. /*
  530.   Wait for something to happen. When something has happened, send a message
  531.   to the client to say so.
  532. ------------------------------------------------------------------------*/
  533. {
  534.   ITEMS *ip;
  535.  
  536.   if(changes != 0){
  537.     for(ip = items_head;
  538.         ip->changes == 0 && (ip->type != ITEM_CURSORS || cursor_changes == 0);
  539.         ip = ip->fwd)
  540.       /* NULL */ ;
  541.     check_control_panel(ip->itno);
  542.     waiting = False;
  543.   }else{
  544.     waiting = True;
  545.   }
  546.  
  547.   return;
  548. }
  549.  
  550. /************************************************************************/
  551. #if NeedFunctionPrototypes
  552. static void define_control_panel(short int message[])
  553. #else
  554. static void define_control_panel(message)
  555. short int message[];
  556. #endif /* NeedFunctionPrototypes */
  557. /*
  558.   This client has requested that an additional item be added to our list
  559.   of items. Add in the description.
  560.  
  561.   Inputs:
  562.     message     An array containing:
  563.                 CTRL_DEFINE,size,itno,item_type,values
  564. ------------------------------------------------------------------------*/
  565. {
  566.   ITEMS *ip;
  567.   int l,size;
  568.   short int *in;
  569.   char *out;
  570.  
  571.   ip = items_head;
  572.   if(ip == (ITEMS *)NULL){
  573.     items_head = (ITEMS *)malloc(sizeof(ITEMS));
  574.     ip = items_head;
  575.   }else{
  576.     while(ip->fwd != (ITEMS *)NULL) ip = ip->fwd;
  577.     ip->fwd = (ITEMS *)malloc(sizeof(ITEMS));
  578.     ip = ip->fwd;
  579.   }
  580.  
  581.   ip->itno = message[2];
  582.   ip->type = message[3];
  583.   ip->fwd = (ITEMS *)NULL;
  584.   size = message[1];
  585.   ip->values = malloc(size);
  586.   ip->changes = 0;
  587.   ip->nvalues = 0;
  588.   ip->buttonlist = NULL;
  589.  
  590.   in = &message[4];
  591.   out = ip->values;
  592.   for(l=0; l < size; l++){
  593.     if(*in == 0) ip->nvalues++;
  594.     *out++ = *in++;
  595.   }
  596.  
  597.   return;
  598. }
  599.  
  600. /************************************************************************/
  601. #if NeedFunctionPrototypes
  602. static void set_control_panel(short int message[])
  603. #else
  604. static void set_control_panel(message)
  605. short int message[];
  606. #endif /* NeedFunctionPrototypes */
  607. /*
  608.   This client has requested that a change be made to one of our items.
  609.   Currently, only either one or two values are permitted.
  610.  
  611.   Note that this routine is ONLY useful AFTER the panel is visible!
  612.  
  613.   Inputs:
  614.     message     An array containing:
  615.                 CTRL_SET,size,itno,values
  616. ------------------------------------------------------------------------*/
  617. {
  618.   int j,k,itno,size,val[2];
  619.   short int *in;
  620.   char *cval,*out;
  621.   float top;
  622.   Widget w;
  623.   Arg args[10];
  624.   ITEMS *ip;
  625.  
  626.   if(!visible) return;
  627.  
  628.   size = message[1];
  629.   itno = message[2];
  630.   for(ip = items_head; ip != (ITEMS *)NULL && ip->itno != itno; ip = ip->fwd);
  631.   if(ip == (ITEMS *)NULL) bug("set_control_panel: Did not find the item.");
  632.   cval = malloc(size);
  633.   in = &message[3];
  634.   out = cval;
  635.   for(j=0,k=0; j < size; j++){
  636.     if(!(*out++ = *in++)){
  637.       if(k > 1) break; /* No more than two parameters for now. */
  638.       if(ip->type != ITEM_STATUSES)val[k] = atoi(cval);
  639.       k++;
  640.       out = cval;
  641.     }
  642.   }
  643.   if(k == 0) bug("set_control_panel: Did not find any values.");
  644.  
  645.   if((ip->type == ITEM_BUTTONS) && (ip->nvalues > 1)){
  646.     if((val[0] >= 0) && (val[0] < ip->nvalues) && (val[0] != ip->sval)){
  647.       ip->sval = val[0] - 1;
  648.       button_next(ip->main, (XtPointer)ip, (XtPointer)NULL);
  649.     }
  650.   }else if(ip->type == ITEM_BUTTONS){
  651.     ; /* NULL command for one valued buttons */
  652.   }else if(ip->type == ITEM_STATUSES){
  653.     XtSetArg(args[0], XtNlabel, cval);
  654.     XtSetValues(ip->main, args, 1);
  655.   }else if(ip->type == ITEM_SLIDERS){
  656.     if(k == 1){
  657.       top = (float)(val[0] - ip->smin)/(float)(ip->smax - ip->smin);
  658.       ip->sval = top * ip->slen;
  659.       w = XtNameToWidget(ip->main, "Scroll");
  660.       XawScrollbarSetThumb(w, top, (float)(-1.0)); /* -1 means unchanged. */
  661.       LabelScrollBarValue(ip->main, val[0]);
  662.     }else if(k == 2){
  663.       ip->smin = val[0];
  664.       ip->smax = val[1];
  665.       LabelScrollBarMinMax(ip->main, ip->smin, ip->smax);
  666.     }else {
  667.       bug("set_control_panel: Too many slider values!");
  668.     }
  669.   }else if(ip->type == ITEM_CURSORS){
  670.     if(k == 1){
  671.       cursorx = val[0];
  672.       cursory = 99 - cursorx;
  673.     }else if(k == 2){
  674.       cursorx = val[0];
  675.       cursory = 99 - val[1];
  676.     }else {
  677.       bug("set_control_panel: Too many cursor values!");
  678.     }
  679.     CursorPaint(ip->main, (XEvent *)NULL, (String *)NULL, (Cardinal *)NULL);
  680.   }else{
  681.     bug("set_control_panel: I cannot get here!");
  682.   }
  683.   (void)free(cval);
  684.  
  685.   return;
  686. }
  687.  
  688. /************************************************************************/
  689. #if NeedFunctionPrototypes
  690. static void destroy_control_panel(void)
  691. #else
  692. static void destroy_control_panel()
  693. #endif /* NeedFunctionPrototypes */
  694. /*
  695.   Delete the structures created to handle this control panel.
  696. ------------------------------------------------------------------------*/
  697. {
  698.   ITEMS *ip, *next;
  699.  
  700.   next = items_head;
  701.   while(next != (ITEMS *)NULL){
  702.     ip = next;
  703.     next = ip->fwd;
  704.  
  705.     if (ip->buttonlist) XtFree((char *)ip->buttonlist);
  706.  
  707.     (void)free(ip->values);
  708.     (void)free((char *)ip);
  709.  
  710.   }
  711.   if(visible) XtDestroyWidget(subframe);
  712.   items_head = (ITEMS *)NULL;
  713.   visible = False;
  714.   connected = False;
  715.  
  716.   return;
  717. }
  718.  
  719. /************************************************************************/
  720. #if NeedFunctionPrototypes
  721. static void create_control_panel(void)
  722. #else
  723. static void create_control_panel()
  724. #endif /* NeedFunctionPrototypes */
  725. /*
  726.   It is now time to create the control panel that the user wants.
  727. ------------------------------------------------------------------------*/
  728. {
  729.   ITEMS *ip;
  730.   int i,panel_width,char_width,char_height;
  731.   int max_width,max_height,item_width;
  732.   int Cursor_Shape;
  733.   Cursor cursor, nocursor;
  734.   XFontStruct *font;
  735.   Arg args[20];
  736.   Widget panel;  /* Just about all items sit in this widget. */
  737.   Widget canvas; /* Used for the cursor. */
  738.   Widget Lasthoriz, Lastvert, SaveFirst;
  739.  
  740.   static String Trans = "#override \n\
  741.                        <Btn3Down>: XtMenuPopup(ButtonList)";
  742.   static String CoreTrans = "#override \n\
  743.                             <Expose>: cursorpaint() \n\
  744.                             <Btn1Down>: cursorevents() \n\
  745.                             <Btn2Down>: cursorevents() \n\
  746.                             <Btn1Motion>: cursorevents() \n\
  747.                             <Btn2Motion>: cursorevents()";
  748.  
  749.   font = App_Data.font;
  750.   char_width  = font->max_bounds.width;
  751.   char_height = font->max_bounds.descent + font->max_bounds.ascent;
  752.   panel_width = PANEL_WIDTH * char_width + 30;
  753.   clear_control_panel();
  754.   if(visible) XtDestroyWidget(subframe);
  755.   Lasthoriz = NULL;
  756.   Lastvert = NULL;
  757.   SaveFirst = NULL;
  758.   max_width = 0;
  759.   max_height = 0;
  760.  
  761. /* Create a cursor for button items and a null cursor for all other items. */
  762.  
  763.   Cursor_Shape = XC_X_cursor;
  764.   nocursor = XCreateFontCursor(XtDisplay(top_level), Cursor_Shape);
  765.   Cursor_Shape = XC_arrow;
  766.   cursor = XCreateFontCursor(XtDisplay(top_level), Cursor_Shape);
  767.  
  768. /* Create the subframe, and its panel. */
  769.  
  770.   i = 0;
  771.   subframe = XtCreatePopupShell("Miriad Control Panel",
  772.     applicationShellWidgetClass, top_level, args, i);
  773.   XtAddCallback(subframe, XtNpopupCallback, PlaceMenu, (XtPointer)NULL);
  774.  
  775.   i = 0;
  776.   panel = XtCreateManagedWidget("panel", formWidgetClass, subframe, args, i);
  777.  
  778.   ncursors = 0;
  779.   for(ip = items_head; ip != (ITEMS *)NULL; ip = ip->fwd){
  780.     if(ip->type == ITEM_CURSORS){
  781.       ncursors++;
  782.     }else if(ip->type == ITEM_BUTTONS){
  783.       if(Lasthoriz == NULL) max_height++;
  784.       item_width = panel_width / 2;
  785.       if(ip->nvalues == 1){
  786.         i = 0;
  787.         XtSetArg(args[i], XtNfromHoriz, (XtArgVal) Lasthoriz); i++;
  788.         XtSetArg(args[i], XtNfromVert,   (XtArgVal) Lastvert); i++;
  789.         XtSetArg(args[i], XtNlabel,    (XtArgVal) ip->values); i++;
  790.         XtSetArg(args[i], XtNresize,        (XtArgVal) False); i++;
  791.         XtSetArg(args[i], XtNwidth,    (XtArgVal) item_width); i++;
  792.         XtSetArg(args[i], XtNcursor,       (XtArgVal) cursor); i++;
  793.         ip->main = XtCreateManagedWidget("button", commandWidgetClass,
  794.                      panel, args, i);
  795.         XtAddCallback(ip->main, XtNcallback, button_changed, (XtPointer)ip);
  796.         if (Lasthoriz) {
  797.           Lastvert = Lasthoriz;
  798.           Lasthoriz = NULL;
  799.         } else {
  800.           Lasthoriz = ip->main;
  801.         }
  802.         if (Lastvert && (item_width > max_width) && (max_height < 8)){
  803.           max_width = item_width;
  804.           SaveFirst = ip->main;
  805.         }
  806.       }else{
  807.         i = 0;
  808.         XtSetArg(args[i], XtNfromHoriz, (XtArgVal) Lasthoriz); i++;
  809.         XtSetArg(args[i], XtNfromVert,   (XtArgVal) Lastvert); i++;
  810.         XtSetArg(args[i], XtNlabel,    (XtArgVal) ip->values); i++;
  811.         XtSetArg(args[i], XtNresize,        (XtArgVal) False); i++;
  812.         XtSetArg(args[i], XtNwidth,    (XtArgVal) item_width); i++;
  813.         XtSetArg(args[i], XtNcursor,       (XtArgVal) cursor); i++;
  814.         ip->main = XtCreateManagedWidget("list", commandWidgetClass,
  815.                      panel, args, i);
  816.         XtAddCallback(ip->main, XtNcallback, button_next, (XtPointer)ip);
  817.         XtOverrideTranslations(ip->main, XtParseTranslationTable(Trans));
  818.         SetUpListMenu(ip, item_width);
  819.         if (Lasthoriz) {
  820.           Lastvert = Lasthoriz;
  821.           Lasthoriz = NULL;
  822.         } else {
  823.           Lasthoriz = ip->main;
  824.         }
  825.         if (Lastvert && (item_width > max_width) && (max_height < 8)){
  826.           max_width = item_width;
  827.           SaveFirst = ip->main;
  828.         }
  829.       }
  830.     }else if(ip->type == ITEM_STATUSES){
  831.       max_height++;
  832.       if (Lasthoriz) { /* Give this its own line. */
  833.         Lastvert = Lasthoriz;
  834.         Lasthoriz = NULL;
  835.       }
  836.       item_width = strlen(ip->values);
  837.       if (panel_width > item_width) item_width = (2 * panel_width);
  838.       i = 0;
  839.       XtSetArg(args[i], XtNfromHoriz, (XtArgVal) Lasthoriz); i++;
  840.       XtSetArg(args[i], XtNfromVert,   (XtArgVal) Lastvert); i++;
  841.       XtSetArg(args[i], XtNlabel,    (XtArgVal) ip->values); i++;
  842.       XtSetArg(args[i], XtNwidth,    (XtArgVal) item_width); i++;
  843.       XtSetArg(args[i], XtNcursor,     (XtArgVal) nocursor); i++;
  844.       ip->main = XtCreateManagedWidget("status", labelWidgetClass,
  845.                    panel, args, i);
  846.       Lastvert = ip->main;
  847.       if ((item_width > max_width) && (max_height < 8)){
  848.         max_width = item_width;
  849.         SaveFirst = ip->main;
  850.       }
  851.     }else if(ip->type == ITEM_SLIDERS){
  852.       max_height++;
  853.       if (Lasthoriz) { /* Give this its own line. */
  854.         Lastvert = Lasthoriz;
  855.         Lasthoriz = NULL;
  856.       }
  857.       item_width = (2 * panel_width);
  858.       i = 0;
  859.       XtSetArg(args[i], XtNfromHoriz, (XtArgVal) Lasthoriz); i++;
  860.       XtSetArg(args[i], XtNfromVert,   (XtArgVal) Lastvert); i++;
  861.       XtSetArg(args[i], XtNwidth,    (XtArgVal) item_width); i++;
  862.       XtSetArg(args[i], XtNcursor,     (XtArgVal) nocursor); i++;
  863.       ip->main = XtCreateManagedWidget("slider", formWidgetClass,
  864.                    panel, args, i);
  865.       SetUpSlider(ip, nocursor, panel_width/2, panel_width*2/3, char_height);
  866.       Lastvert = ip->main;
  867.       if ((item_width > max_width) && (max_height < 8)){
  868.         max_width = item_width;
  869.         SaveFirst = ip->main;
  870.       }
  871.     }else bug("create_control_panel: I cannot get here!");
  872.   }
  873.  
  874. /* Check if the user requested cursors. This implementation only allows
  875.    one cursor. This maps as follows:
  876.     wait_control_panel:  It maps to the first cursor defined.
  877.     check_control_panel: It maps to the requested cursor. */
  878.  
  879.   if(ncursors != 0){
  880.     cursorx = 50;
  881.     cursory = 50;
  882.     i = 0;
  883.     XtSetArg(args[i], XtNtop,      (XtArgVal)XtChainTop); i++;
  884.     XtSetArg(args[i], XtNright,  (XtArgVal)XtChainRight); i++;
  885.     XtSetArg(args[i], XtNresize,        (XtArgVal)False); i++;
  886.     XtSetArg(args[i], XtNwidth,   (XtArgVal)panel_width); i++;
  887.     XtSetArg(args[i], XtNheight,  (XtArgVal)panel_width); i++;
  888.     XtSetArg(args[i], XtNfromVert,       (XtArgVal)NULL); i++;
  889.     XtSetArg(args[i], XtNfromHoriz, (XtArgVal)SaveFirst); i++;
  890.     canvas = XtCreateManagedWidget("cursor", coreWidgetClass,
  891.                    panel, args, i);
  892.     XtOverrideTranslations(canvas, XtParseTranslationTable(CoreTrans));
  893.     for(ip = items_head; ip != (ITEMS *)NULL; ip = ip->fwd)
  894.       if(ip->type == ITEM_CURSORS)
  895.         ip->main = canvas;
  896.   }
  897.  
  898. /*  Push the subframe onto the screen. */
  899.  
  900.   XtPopup(subframe, XtGrabNone);
  901.   visible = True;
  902.  
  903. /*  Only after it has been realized can one assign a cursor to the canvas. */
  904.  
  905.   if(ncursors != 0) {
  906.     Cursor_Shape = XC_hand2;
  907.     cursor = XCreateFontCursor(XtDisplay(top_level), Cursor_Shape);
  908.     XDefineCursor(XtDisplay(canvas), XtWindow(canvas), cursor);
  909.   }
  910.  
  911.   return;
  912. }
  913.  
  914. /************************************************************************/
  915. /* ARGSUSED */
  916. #if NeedFunctionPrototypes
  917. static void CursorPaint(Widget w, XEvent *event, String *params,
  918.    Cardinal *nparams)
  919. #else
  920. static void CursorPaint(w, event, params, nparams)
  921. Widget w;
  922. XEvent *event;     /* Unused */
  923. String *params;    /* Unused */
  924. Cardinal *nparams; /* Unused */
  925. #endif /* NeedFunctionPrototypes */
  926. /*
  927.   Draw a cross at the cursor position.
  928. ------------------------------------------------------------------------*/
  929. {
  930.   int width,height,left,right,top,bottom;
  931.   XWindowAttributes wattr;
  932.  
  933.   if(XGetWindowAttributes(XtDisplay(w), XtWindow(w), &wattr)){
  934.     width = (int)wattr.width;
  935.     height = (int)wattr.height;
  936.     left = width*cursorx/100 - 10;
  937.     right = left + 21;
  938.     top = height*cursory/100 - 10;
  939.     bottom = top + 21;
  940.     XClearWindow(XtDisplay(w), XtWindow(w));
  941.     XDrawLine(XtDisplay(w), XtWindow(w), gc, left, top, right, bottom);
  942.     XDrawLine(XtDisplay(w), XtWindow(w), gc, left, bottom, right, top);
  943.   }
  944.  
  945.   return;
  946. }
  947.  
  948. /************************************************************************/
  949. #if NeedFunctionPrototypes
  950. static void CursorEvents(Widget w, XEvent *event, String *params,
  951.    Cardinal *nparams)
  952. #else
  953. static void CursorEvents(w, event, params, nparams)
  954. Widget w;
  955. XEvent *event;
  956. String *params;
  957. Cardinal *nparams;
  958. #endif /* NeedFunctionPrototypes */
  959. /*
  960.   This receives events when the cursor is moved or pushed.
  961. ------------------------------------------------------------------------*/
  962. {
  963.   int x, y;
  964.   int width, height;
  965.   XWindowAttributes wattr;
  966.  
  967.   switch (event->type) {
  968.     case ButtonPress:  x = event->xbutton.x; y = event->xbutton.y; break;
  969.     case MotionNotify: x = event->xmotion.x; y = event->xmotion.y; break;
  970.     default: /* ?? */  x = event->xbutton.x; y = event->xbutton.y; break;
  971.   }
  972.  
  973.   if(XGetWindowAttributes(XtDisplay(w), XtWindow(w), &wattr)){
  974.     width = (int)wattr.width;
  975.     height = (int)wattr.height;
  976.     if((x >= 0) && (x < width) && (y >= 0) && (y < height)){
  977.       cursor_changes++;
  978.       changes++;
  979.       cursorx = 100 * x / width;
  980.       cursory = 100 * y / height;
  981.       (void)CursorPaint(w, event, params, nparams);
  982.       if (waiting) wait_control_panel();
  983.       waiting = False;
  984.     }
  985.   }
  986.  
  987.   return;
  988. }
  989.  
  990. /************************************************************************/
  991. #if NeedFunctionPrototypes
  992. static void SetUpListMenu(ITEMS *item, int width)
  993. #else
  994. static void SetUpListMenu(item, width)
  995. ITEMS *item;
  996. int width;
  997. #endif /* NeedFunctionPrototypes */
  998. {
  999.     char *s;
  1000.     int i;
  1001.     ITEMS *ip;
  1002.     Arg args[10];
  1003.     Widget popupshell, popbox, wlist;
  1004.     static String PopTrans = "#override \n\
  1005.                              <Btn3Up>: XtMenuPopdown(ButtonList)";
  1006.     static String LisTrans = "#override \n\
  1007.                              <EnterWindow>: highlight() \n\
  1008.                              <LeaveWindow>: reset() \n\
  1009.                              <Btn3Up>: set() notify() unset() ";
  1010.  
  1011.     ip = item;
  1012.     if (ip == (ITEMS *)NULL) bug("SetUpListMenu: Did not find the item");
  1013.     if (ip->type != ITEM_BUTTONS) bug("SetUpListMenu: item not a button");
  1014.  
  1015.     i = 0;
  1016.     popupshell = XtCreatePopupShell("ButtonList", transientShellWidgetClass,
  1017.                                       ip->main, args, i);
  1018.     XtAddCallback(popupshell, XtNpopupCallback, PlaceMenu, (XtPointer)NULL);
  1019.     XtOverrideTranslations(popupshell, XtParseTranslationTable(PopTrans));
  1020.  
  1021.     i = 0;
  1022.     XtSetArg(args[i], XtNhSpace, (XtArgVal) 1); i++;
  1023.     XtSetArg(args[i], XtNvSpace, (XtArgVal) 1); i++;
  1024.     popbox = XtCreateManagedWidget("MenuBox", boxWidgetClass,
  1025.                                       popupshell, args, i);
  1026.  
  1027.     XtSetArg(args[0], XtNwidth, (XtArgVal) width);
  1028.     ip->buttonlist = (String *)XtMalloc((ip->nvalues + 1) * sizeof(String));
  1029.     s = ip->values;
  1030.     for (i = 0; i < ip->nvalues; i++) {
  1031.       ip->buttonlist[i] = (String) s;
  1032.       wlist = XtCreateManagedWidget(ip->buttonlist[i], commandWidgetClass,
  1033.                                      popbox, args, 1);
  1034.       XtAddCallback(wlist, XtNcallback, ListButtonPushed, (XtPointer)ip);
  1035.       XtOverrideTranslations(wlist, XtParseTranslationTable(LisTrans));
  1036.       s += strlen(s) + 1;
  1037.     }
  1038.     ip->buttonlist[i] = NULL;
  1039.     ip->sval = 0; /* SVAL points to the current hightlighted entry. */
  1040.  
  1041.     return;
  1042. }
  1043.  
  1044. /************************************************************************/
  1045. #if NeedFunctionPrototypes
  1046. static void SetUpSlider(ITEMS *item, Cursor nocursor, int labelwidth,
  1047.    int width, int height)
  1048. #else
  1049. static void SetUpSlider(item, nocursor, labelwidth, width, height)
  1050. ITEMS *item;
  1051. Cursor nocursor;
  1052. int labelwidth, width, height;
  1053. #endif /* NeedFunctionPrototypes */
  1054. {
  1055.     int i;
  1056.     float top, shown;
  1057.     ITEMS *ip;
  1058.     Arg args[20];
  1059.     Widget wlab, wval, wmin;
  1060.     Widget wscroll;
  1061.     char ScrollTrans[300];
  1062.     static String SprintfTrans = "#override \n\
  1063.      <Btn2Up>: NotifyScroll(Proportional) EndScroll() updatescroll(%d) \n\
  1064.      <BtnUp>:  NotifyScroll(Proportional) EndScroll() ";
  1065.  
  1066.     ip = item;
  1067.     if (ip == (ITEMS *)NULL) bug("SetUpSlider: Did not find the item");
  1068.     if(ip->type != ITEM_SLIDERS) bug("SetUpSlider: item is not a Slider");
  1069.  
  1070.     ip->smin = 0;
  1071.     ip->smax = 100;
  1072.     ip->slen = width;
  1073.     ip->sval = width / 2;
  1074.     top = (float)ip->sval;
  1075.     shown = (float)ip->sval / (float)ip->slen;
  1076.  
  1077.     i = 0;
  1078.     XtSetArg(args[i], XtNlabel,            ip->values); i++;
  1079.     XtSetArg(args[i], XtNwidth, (XtArgVal) labelwidth); i++;
  1080.     XtSetArg(args[i], XtNborderWidth,    (XtArgVal) 0); i++;
  1081.     XtSetArg(args[i], XtNfromVert,    (XtArgVal) NULL); i++;
  1082.     XtSetArg(args[i], XtNfromHoriz,   (XtArgVal) NULL); i++;
  1083.     XtSetArg(args[i], XtNcursor,  (XtArgVal) nocursor); i++;
  1084.     wlab = XtCreateManagedWidget("Slab", labelWidgetClass, ip->main, args, i);
  1085.  
  1086.     i = 0;
  1087.     XtSetArg(args[i], XtNlabel,              "[100]"); i++;
  1088.     XtSetArg(args[i], XtNborderWidth,   (XtArgVal) 0); i++;
  1089.     XtSetArg(args[i], XtNfromHoriz,  (XtArgVal) wlab); i++;
  1090.     XtSetArg(args[i], XtNhorizDistance, (XtArgVal) 5); i++;
  1091.     XtSetArg(args[i], XtNcursor, (XtArgVal) nocursor); i++;
  1092.     wval = XtCreateManagedWidget("Sval", labelWidgetClass, ip->main, args, i);
  1093.  
  1094.     i = 0;
  1095.     XtSetArg(args[i], XtNlabel,                "100"); i++;
  1096.     XtSetArg(args[i], XtNborderWidth,   (XtArgVal) 0); i++;
  1097.     XtSetArg(args[i], XtNfromHoriz,  (XtArgVal) wval); i++;
  1098.     XtSetArg(args[i], XtNhorizDistance, (XtArgVal) 5); i++;
  1099.     XtSetArg(args[i], XtNcursor, (XtArgVal) nocursor); i++;
  1100.     wmin = XtCreateManagedWidget("Smin", labelWidgetClass, ip->main, args, i);
  1101.  
  1102.     i = 0;
  1103.     XtSetArg(args[i], XtNfromHoriz,      (XtArgVal) wmin); i++;
  1104.     XtSetArg(args[i], XtNhorizDistance,     (XtArgVal) 0); i++;
  1105.     XtSetArg(args[i], XtNorientation, XtorientHorizontal); i++;
  1106.     XtSetArg(args[i], XtNlength,     (XtArgVal) ip->slen); i++;
  1107.     XtSetArg(args[i], XtNthickness,    (XtArgVal) height); i++;
  1108.     XtSetArg(args[i], XtNtop,             (XtArgVal) top); i++;
  1109.     XtSetArg(args[i], XtNshown,         (XtArgVal) shown); i++;
  1110.     wscroll = XtCreateManagedWidget("Scroll", scrollbarWidgetClass,
  1111.                  ip->main, args, i);
  1112.     XtAddCallback(wscroll, XtNscrollProc, SliderScrollProc, (XtPointer)ip);
  1113.     XtAddCallback(wscroll, XtNjumpProc, SliderJumpProc, (XtPointer)ip);
  1114.     (void)sprintf(ScrollTrans, SprintfTrans, ip->itno);
  1115.     XtOverrideTranslations(wscroll, XtParseTranslationTable(ScrollTrans));
  1116.  
  1117.     i = 0;
  1118.     XtSetArg(args[i], XtNlabel,                  "100"); i++;
  1119.     XtSetArg(args[i], XtNborderWidth,     (XtArgVal) 0); i++;
  1120.     XtSetArg(args[i], XtNfromHoriz, (XtArgVal) wscroll); i++;
  1121.     XtSetArg(args[i], XtNhorizDistance,   (XtArgVal) 0); i++;
  1122.     XtSetArg(args[i], XtNcursor,   (XtArgVal) nocursor); i++;
  1123.     (void)XtCreateManagedWidget("Smax", labelWidgetClass, ip->main, args, i);
  1124.  
  1125.     LabelScrollBarMinMax(ip->main, ip->smin, ip->smax);
  1126.     LabelScrollBarValue(ip->main, (int)50);
  1127.     XawScrollbarSetThumb(wscroll, (float)(0.5), (float)(-1.0));
  1128.         /* -1 for the last two arguments means unchanged. */
  1129.  
  1130.     return;
  1131. }
  1132.  
  1133. /************************************************************************/
  1134. #if NeedFunctionPrototypes
  1135. static void LabelScrollBarValue(Widget parent, int value)
  1136. #else
  1137. static void LabelScrollBarValue(parent, value)
  1138. Widget parent;
  1139. int value;
  1140. #endif /* NeedFunctionPrototypes */
  1141. {
  1142.     Arg args[2];
  1143.     char string[20];
  1144.     Dimension width;
  1145.     Widget widget;
  1146.  
  1147.     widget = XtNameToWidget(parent, "Sval");
  1148.     (void)sprintf(string, "[%d]", value);
  1149.     XtSetArg(args[0], XtNwidth, &width);
  1150.     XtGetValues(widget, args, 1);
  1151.     XtSetArg(args[0], XtNwidth, width);
  1152.     XtSetArg(args[1], XtNlabel, string);
  1153.     XtSetValues(widget, args, 2);
  1154.  
  1155.     return;
  1156. }
  1157.  
  1158. /************************************************************************/
  1159. #if NeedFunctionPrototypes
  1160. static void LabelScrollBarMinMax(Widget parent, int min, int max)
  1161. #else
  1162. static void LabelScrollBarMinMax(parent, min, max)
  1163. Widget parent;
  1164. int min, max;
  1165. #endif /* NeedFunctionPrototypes */
  1166. {
  1167.     char string[20];
  1168.     Arg args[1];
  1169.     Widget widget;
  1170.  
  1171.     widget = XtNameToWidget(parent, "Smin");
  1172.     (void)sprintf(string, "%d", min);
  1173.     XtSetArg(args[0], XtNlabel, string);
  1174.     XtSetValues(widget, args, 1);
  1175.  
  1176.     widget = XtNameToWidget(parent, "Smax");
  1177.     (void)sprintf(string, "%d", max);
  1178.     XtSetArg(args[0], XtNlabel, string);
  1179.     XtSetValues(widget, args, 1);
  1180.  
  1181.     return;
  1182. }
  1183.  
  1184. /************************************************************************/
  1185. /* ARGSUSED */
  1186. #if NeedFunctionPrototypes
  1187. static void PlaceMenu(Widget w, XtPointer clientData, XtPointer callData)
  1188. #else
  1189. static void PlaceMenu(w, clientData, callData)
  1190. Widget w;
  1191. XtPointer clientData; /* Unused */
  1192. XtPointer callData;   /* Unused */
  1193. #endif /* NeedFunctionPrototypes */
  1194. {
  1195.     Arg args[2];
  1196.     Cardinal i;
  1197.     Dimension height; /* Height of parent;  menu is placed below parent. */
  1198.     Position x, y;    /* Coords of the parent widget on the root window. */
  1199.     Widget button;    /* Widget of parent of popup widget. */
  1200. /*
  1201.  *  Translate the position of the popup window to the coordinates of
  1202.  *  the button window origin.
  1203.  */
  1204.     button = XtParent(w);
  1205.     i = 0;
  1206.     XtSetArg(args[i], XtNheight, &height); i++;
  1207.     XtGetValues(button, args, i);
  1208.     XtTranslateCoords(button, (Position)0, (Position)0, &x, &y);
  1209.     x += height;
  1210.     y += (height / 2);
  1211.  
  1212. /*  Move the popup shell height pixels below and right of this position. */
  1213. /*  (The popup widget is not visible yet.) */
  1214.     i = 0;
  1215.     XtSetArg(args[i], XtNx, x); i++;
  1216.     XtSetArg(args[i], XtNy, y); i++;
  1217.     XtSetValues(w, args, i);
  1218.  
  1219.     return;
  1220. }
  1221.  
  1222. /************************************************************************/
  1223. /* ARGSUSED */
  1224. #if NeedFunctionPrototypes
  1225. static void ListButtonPushed(Widget w, XtPointer clientData, XtPointer callData)
  1226. #else
  1227. static void ListButtonPushed(w, clientData, callData)
  1228. Widget w;
  1229. XtPointer clientData;
  1230. XtPointer callData;   /* Unused */
  1231. #endif /* NeedFunctionPrototypes */
  1232. {
  1233.     int listindex;
  1234.     Arg args[1];
  1235.     String listitem;
  1236.     Widget button;
  1237.     ITEMS *ip;
  1238.  
  1239.     ip = (ITEMS *)clientData;
  1240.     if(ip == (ITEMS *)NULL) bug("ListButtonPushed: Did not find the item");
  1241.     if (ip->type != ITEM_BUTTONS) bug("ListButtonPushed: item not a button");
  1242.  
  1243.     XtSetArg(args[0], XtNlabel, &listitem);
  1244.     XtGetValues(w, args, 1);
  1245.  
  1246.     button = XtParent(XtParent(w)); /* ButtonList<-MenuBox<-buttonlist[i] */
  1247.     XtPopdown(button);
  1248.  
  1249.     button = XtParent(button);  /* list<-ButtonList<-MenuBox<-buttonlist[i] */
  1250.  
  1251.     if(strlen(listitem) > (size_t)0) {
  1252.       for (listindex = 0; listindex < ip->nvalues; listindex++)
  1253.         if(strcmp(listitem, ip->buttonlist[listindex]) == 0) break;
  1254.  
  1255.       if((listindex != ip->sval) && (listindex < ip->nvalues)) {
  1256.         XtSetArg(args[0], XtNlabel, ip->buttonlist[listindex]);
  1257.         XtSetValues(button, args, 1);
  1258.         ip->sval = listindex;
  1259.  
  1260.         button_changed(w, (XtPointer)ip, (XtPointer)NULL);
  1261.       }
  1262.     }
  1263.  
  1264.     return;
  1265. }
  1266.  
  1267. /************************************************************************/
  1268. /* ARGSUSED */
  1269. #if NeedFunctionPrototypes
  1270. static void button_next(Widget w, XtPointer clientData, XtPointer callData)
  1271. #else
  1272. static void button_next(w, clientData, callData)
  1273. Widget w;
  1274. XtPointer clientData;
  1275. XtPointer callData;   /* Unused */
  1276. #endif /* NeedFunctionPrototypes */
  1277. {
  1278.     int listindex;
  1279.     Arg args[1];
  1280.     ITEMS *ip;
  1281.  
  1282.     ip = (ITEMS *)clientData;
  1283.     if(ip == (ITEMS *)NULL) bug("button_next: Did not find the item");
  1284.     if (ip->type != ITEM_BUTTONS) bug("button_next: item not a button");
  1285.  
  1286.     listindex = (ip->sval + 1) % ip->nvalues;
  1287.  
  1288.     XtSetArg(args[0], XtNlabel, ip->buttonlist[listindex]);
  1289.     XtSetValues(w, args, 1);
  1290.  
  1291.     ip->sval = listindex;
  1292.  
  1293.     button_changed(w, (XtPointer)ip, (XtPointer)NULL);
  1294.  
  1295.     return;
  1296. }
  1297.  
  1298. /************************************************************************/
  1299. /* ARGSUSED */
  1300. #if NeedFunctionPrototypes
  1301. static void button_changed(Widget w, XtPointer clientData, XtPointer callData)
  1302. #else
  1303. static void button_changed(w, clientData, callData)
  1304. Widget w;
  1305. XtPointer clientData;
  1306. XtPointer callData;   /* Unused */
  1307. #endif /* NeedFunctionPrototypes */
  1308. {
  1309.     ITEMS *ip;
  1310.  
  1311.     ip = (ITEMS *)clientData;
  1312.     if(ip == (ITEMS *)NULL) bug("button_changed: Did not find the item");
  1313.  
  1314.     ip->changes++;
  1315.     changes++;
  1316.     if (waiting) check_control_panel(ip->itno);
  1317.     waiting = False;
  1318.  
  1319.     return;
  1320. }
  1321.  
  1322. /************************************************************************/
  1323. #if NeedFunctionPrototypes
  1324. static void SliderScrollProc(Widget w, XtPointer clientData, XtPointer callData)
  1325. #else
  1326. static void SliderScrollProc(w, clientData, callData)
  1327. Widget w;
  1328. XtPointer clientData;
  1329. XtPointer callData;
  1330. #endif /* NeedFunctionPrototypes */
  1331. {
  1332.     int value;
  1333.     float fraction;
  1334.     ITEMS *ip;
  1335.  
  1336.     ip = (ITEMS *)clientData;
  1337.     if(ip == (ITEMS *)NULL) bug("SliderScrollProc: Did not find the item");
  1338.     if(ip->type != ITEM_SLIDERS) bug("SliderScrollProc: item is not a Slider");
  1339.  
  1340.     ip->sval -= (int)callData / 10;
  1341.     if (ip->sval < 0) ip->sval = 0;
  1342.     if (ip->sval > ip->slen) ip->sval = ip->slen;
  1343.     fraction = (float)ip->sval / (float)ip->slen;
  1344.     value = ip->smin + (fraction * (ip->smax - ip->smin));
  1345.     XawScrollbarSetThumb(w, fraction, (float)(-1.0)); /* -1 means unchanged. */
  1346.     LabelScrollBarValue(ip->main, value);
  1347.     button_changed(w, (XtPointer)ip, (XtPointer)NULL);
  1348.  
  1349.     return;
  1350. }
  1351.  
  1352. /************************************************************************/
  1353. /* ARGSUSED */
  1354. #if NeedFunctionPrototypes
  1355. static void SliderJumpProc(Widget w, XtPointer clientData, XtPointer callData)
  1356. #else
  1357. static void SliderJumpProc(w, clientData, callData)
  1358. Widget w;            /* Unused */
  1359. XtPointer clientData;
  1360. XtPointer callData;
  1361. #endif /* NeedFunctionPrototypes */
  1362. {
  1363.     int value;
  1364.     float fraction;
  1365.     ITEMS *ip;
  1366.  
  1367.     ip = (ITEMS *)clientData;
  1368.     if(ip == (ITEMS *)NULL) bug("SliderJumpProc: Did not find the item");
  1369.     if(ip->type != ITEM_SLIDERS) bug("SliderJumpProc: item is not a Slider");
  1370.  
  1371.     fraction = *(float *)callData;
  1372.     ip->sval = fraction * ip->slen;
  1373.     value = ip->smin + (fraction * (ip->smax - ip->smin));
  1374.     LabelScrollBarValue(ip->main, value);
  1375. /*  Only notify when the scrolling is finished....   */
  1376. /*  button_changed(w, (XtPointer)ip, (XtPointer)NULL); */
  1377.  
  1378.     return;
  1379. }
  1380.  
  1381. /************************************************************************/
  1382. /* ARGSUSED */
  1383. #if NeedFunctionPrototypes
  1384. static void UpdateScroll(Widget w, XEvent *event, String *params,
  1385.     Cardinal *nparams)
  1386. #else
  1387. static void UpdateScroll(w, event, params, nparams)
  1388. Widget w;
  1389. XEvent *event;     /* Unused */
  1390. String *params;    /* ITEMS* ip->itno */
  1391. Cardinal *nparams; /* Only 1 */
  1392. #endif /* NeedFunctionPrototypes */
  1393. {
  1394.     int itno;
  1395.     ITEMS *ip;
  1396.  
  1397.     if (*nparams != 1) return;
  1398.     itno = atoi(*params);
  1399.  
  1400.     for (ip = items_head; ip != (ITEMS *)NULL && ip->itno != itno; ip = ip->fwd)
  1401.       /* NULL */ ;
  1402.     if (ip == (ITEMS *)NULL) bug("UpdateScroll: Did not find the item");
  1403.  
  1404.     button_changed(w, (XtPointer)ip, (XtPointer)NULL);
  1405.  
  1406.     return;
  1407. }
  1408.  
  1409. /************************************************************************/
  1410. /* ARGSUSED */
  1411. #if NeedFunctionPrototypes
  1412. static void QuitPanel(Widget w, XEvent *event, String *params,
  1413.     Cardinal *nparams)
  1414. #else
  1415. static void QuitPanel(w, event, params, nparams)
  1416. Widget w;          /* Unused */
  1417. XEvent *event;     /* Unused */
  1418. String *params;    /* Unused */
  1419. Cardinal *nparams; /* Unused */
  1420. #endif /* NeedFunctionPrototypes */
  1421. {
  1422.     destroy_control_panel();
  1423.     XtCloseDisplay(XtDisplay(top_level));
  1424.     exit(0);
  1425. }

Raw Paste

Login or Register to edit or fork this paste. It's free.