home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / altsrcs / 1 / 1736 / update.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-12-28  |  7.8 KB  |  317 lines

  1. /*
  2.  *    update.c : Handles the bitmaps and runs the update command.
  3.  *           This maintains caches of bitmaps and widgets to
  4.  *           avoid calls to XReadBitmapFromFile() and
  5.  *           XtCreateManagedWidget() on every update.
  6.  *
  7.  *      George Ferguson, ferguson@cs.rochester.edu,  15 Jul 1990.
  8.  *
  9.  *    $Id: update.c,v 1.5 90/08/21 11:36:56 ferguson Exp $
  10.  */
  11. #include <stdio.h>
  12. #include <ctype.h>
  13. #include <sys/param.h>
  14. #include <X11/Intrinsic.h>
  15. #include <X11/StringDefs.h>
  16. #include <X11/Xaw/Toggle.h>
  17. #include <X11/Xaw/Cardinals.h>
  18. #include "app-resources.h"
  19. #include "xmon.h"
  20.  
  21. /*
  22.  * Functions defined
  23.  */
  24. void initMemory(),clearBitmapCache(),updateFaces();
  25. char *getTextFromWidget();
  26. static void openNameCommand(),convertNameToFile(),closeNameCommand();
  27. static Pixmap lookupBitmap();
  28.  
  29. /*
  30.  * The widget cache:
  31.  */
  32. typedef struct _CachedWidgetRec {
  33.     char *text;
  34.     Widget widget;
  35.     struct _CachedWidgetRec *next;
  36. } CachedWidgetRec;
  37. static CachedWidgetRec *widgetRecs;
  38.  
  39. /*
  40.  * The pixmap cache:
  41.  */
  42. typedef struct _CachedBitmapRec {
  43.     char *user;
  44.     Pixmap pixmap;
  45.     struct _CachedBitmapRec *next;
  46. } CachedBitmapRec;
  47. static CachedBitmapRec *bitmapRecs;
  48.  
  49. /*    -    -    -    -    -    -    -    -    */
  50.  
  51. void
  52. initMemory()
  53. {
  54.     widgetRecs = NULL;
  55.     radioGroup = NULL;
  56.     bitmapRecs = NULL;
  57. }
  58.  
  59. void
  60. clearBitmapCache()
  61. {
  62.     CachedBitmapRec *p,*q;
  63.  
  64.     p = bitmapRecs;
  65.     while (p != NULL) {
  66.     q = p->next;
  67.     XFreePixmap(XtDisplay(toplevel),p->pixmap);
  68.     XtFree(p->user);
  69.     XtFree(p);
  70.     p = q;
  71.     }
  72.     bitmapRecs = NULL;
  73. }
  74.  
  75. /*    -    -    -    -    -    -    -    -    */
  76. /*
  77.  *    updateFaces() : Redraw the face widgets.
  78.  */
  79. void
  80. updateFaces()
  81. {
  82.     Arg args[2];
  83.     FILE *fp;
  84.     CachedWidgetRec *p,*q;
  85.     char buf[256],user[256];
  86.     int i;
  87.  
  88.     XDefineCursor(XtDisplay(toplevel),XtWindow(toplevel),
  89.                         appResources.updateCursor);
  90.     XFlush(XtDisplay(toplevel));
  91.     if (appResources.debug)
  92.     printf("updateCommand: \"%s\"\n",appResources.updateCommand);
  93.     fp = popen(appResources.updateCommand,"r");
  94.     if (fp == NULL) {
  95.     fprintf(stderr,"%s: couldn't execute updateCommand \"%s\"\n",
  96.                     program,appResources.updateCommand);
  97.     XUndefineCursor(XtDisplay(toplevel),XtWindow(toplevel));
  98.     return;
  99.     }
  100.     p = widgetRecs;
  101.     q = NULL;
  102.     if (radioGroup != NULL)
  103.     XawToggleUnsetCurrent(radioGroup);
  104.     openNameCommand();
  105.     while (!feof(fp)) {
  106.     if (fgets(buf,256,fp) == 0)
  107.         break;
  108.     if (buf[strlen(buf)-1] == '\n')
  109.         buf[strlen(buf)-1] = '\0';
  110.     else {
  111.         fprintf(stderr,"%s: line too long: %s...\n",program,buf);
  112.         while (!feof(fp) && fgetc(fp) != '\n') ;
  113.     }
  114.     i = 0;
  115.     for (i=0; i < 255 && buf[i] && !isspace(buf[i]); i++)
  116.         user[i] = buf[i];
  117.     user[i] = '\0';
  118.     if (p == NULL) {
  119.         if (q == NULL)
  120.         p = widgetRecs = XtNew(CachedWidgetRec);
  121.         else
  122.         p = q->next = XtNew(CachedWidgetRec);
  123.         p->next = NULL;
  124.         p->text = NULL;
  125.         XtSetArg(args[0],XtNmappedWhenManaged,False);
  126.         p->widget = XtCreateManagedWidget("face",toggleWidgetClass,
  127.                             faceBox,args,ONE);
  128.         if (radioGroup == NULL)
  129.         radioGroup = p->widget;
  130.         XtSetArg(args[0],XtNradioData,p->widget);
  131.         XtSetValues(p->widget,args,ONE);  /* set XawToggleGetCurrent info*/
  132.         XawToggleChangeRadioGroup(p->widget,radioGroup);
  133.     }
  134.     XtSetArg(args[0],XtNbitmap,lookupBitmap(user));
  135.     XtSetValues(p->widget,args,ONE);    /* set bitmap */
  136.     XtFree(p->text);
  137.     p->text = XtNewString(buf);
  138.     XtMapWidget(p->widget);
  139.     q = p;
  140.     p = p->next;
  141.     }
  142.     closeNameCommand();
  143.     pclose(fp);
  144.     while (p != NULL) {            /* unmap leftover widgets */
  145.     XtUnmapWidget(p->widget);
  146.     p = p->next;
  147.     }
  148.     XUndefineCursor(XtDisplay(toplevel),XtWindow(toplevel));
  149.     XFlush(XtDisplay(toplevel));
  150. }
  151.  
  152. /*    -    -    -    -    -    -    -    -    */
  153. /* These functions map "user" names from the updateCommand into icon
  154.  * names using the nameCommand. We ignore the potential deadlock if 4K
  155.  * get into the pipes; it shouldn't happen with newline buffering.
  156.  */
  157.  
  158. static FILE *writeFp,*readFp;
  159.  
  160. static void
  161. openNameCommand()
  162. {
  163.     int fd[4],pid;
  164.  
  165.     if (appResources.nameCommand == NULL) {
  166.     writeFp = readFp = NULL;
  167.     return;
  168.     }
  169.     if (appResources.debug)
  170.     printf("nameCommand: \"%s\"\n",appResources.nameCommand);
  171.     if (pipe(fd) < 0 || pipe(fd+2) < 0) {
  172.     fprintf(stderr,"%s: couldn't create pipes for nameCommand \"%s\"\n",
  173.                     program,appResources.nameCommand);
  174.     writeFp = readFp = NULL;
  175.     return;
  176.     }
  177.     if ((pid=fork()) < 0) {        /* error */
  178.     fprintf(stderr,"%s: couldn't fork nameCommand \"%s\"\n",program,
  179.                         appResources.nameCommand);
  180.     writeFp = readFp = NULL;
  181.     return;
  182.     } else if (pid == 0) {        /* child */
  183.     dup2(fd[0],0);
  184.     close(fd[1]);
  185.     close(fd[2]);
  186.     dup2(fd[3],1);
  187.     execlp(appResources.nameCommand,appResources.nameCommand,NULL);
  188.     fprintf(stderr,"%s: couldn't exec nameCommand \"%s\"\n",program,
  189.                         appResources.nameCommand);
  190.     exit(-1);
  191.     } else {                /* parent */
  192.     close(fd[0]);
  193.     writeFp = fdopen(fd[1],"w");
  194.     readFp = fdopen(fd[2],"r");
  195.     close(fd[3]);
  196.     if (writeFp == NULL || readFp == NULL) {
  197.         fprintf(stderr,"%s: couldn't open pipes for nameCommand \"%s\"\n",
  198.                     program,appResources.nameCommand);
  199.         writeFp = readFp = NULL;
  200.     }
  201.     }
  202. }
  203.  
  204. static void
  205. convertNameToFile(user,icon,len)
  206. char user[],icon[];
  207. int len;
  208. {
  209.     char *strrchr();
  210.  
  211.     if (writeFp == NULL) {
  212.     strncpy(icon,user,len);
  213.     return;
  214.     }
  215.     fputs(user,writeFp);
  216.     fputs("\n",writeFp);
  217.     fflush(writeFp);
  218.     fgets(icon,len,readFp);
  219.     if (strrchr(icon,'\n') != NULL)
  220.     *(strrchr(icon,'\n')) = '\0';    /* eat \n */
  221. }
  222.  
  223. static void
  224. closeNameCommand()
  225. {
  226.     if (writeFp == NULL)
  227.     return;
  228.     fclose(writeFp);
  229.     fclose(readFp);
  230.     wait(NULL);
  231. }
  232.  
  233. /*    -    -    -    -    -    -    -    -    */
  234. /* Bitmap cache to avoid doing "XReadBitmapFromFile" on every update.
  235.  *    Have to read file into a bitmap then copy to pixmap. Blech.
  236.  */
  237.  
  238. static filename[MAXPATHLEN];
  239.  
  240. static Pixmap
  241. lookupBitmap(user)
  242. char user[];
  243. {
  244.     CachedBitmapRec *p,*q;
  245.     char icon[256];
  246.     unsigned int w,h,d;
  247.     int x,y,flag;
  248.     Pixmap bitmap;
  249.     XCharStruct ch;
  250.  
  251.     for (p=bitmapRecs, q=NULL; p != NULL; q=p, p=p->next)/* check the cache */
  252.     if (strcmp(p->user,user) == 0)            /* hit */
  253.         return(p->pixmap);                /* so return it */
  254.     if (q == NULL) {                    /* else new one */
  255.     bitmapRecs = XtNew(CachedBitmapRec);        /* this is first */
  256.     q = bitmapRecs;
  257.     } else {
  258.     q->next = XtNew(CachedBitmapRec);        /* else add to end */
  259.     q = q->next;
  260.     }
  261.     q->next = NULL;
  262.     q->user = XtNewString(user);
  263.     flag = appResources.addNames;        /* definitely add name? */
  264.     convertNameToFile(user,icon,255);        /* map to icon name */
  265.     strcpy(filename,appResources.faceDirectory);
  266.     strcat(filename,"/");
  267.     strncat(filename,icon,255-strlen(filename));
  268.     if (XReadBitmapFile(XtDisplay(toplevel),XtWindow(toplevel),filename,
  269.                     &w,&h,&bitmap,&x,&y) != BitmapSuccess) {
  270.     strcpy(filename,appResources.faceDirectory);
  271.     strcat(filename,"/nobody");
  272.     if (XReadBitmapFile(XtDisplay(toplevel),XtWindow(toplevel),filename,
  273.                     &w,&h,&bitmap,&x,&y) != BitmapSuccess)
  274.         fail("couldn't open default bitmap \"%s\"\n",filename);
  275.     flag = 1;        /* always add name to default icon */
  276.     }
  277.     q->pixmap = XCreatePixmap(XtDisplay(toplevel),XtWindow(toplevel),w,h,
  278.                     PlanesOfScreen(XtScreen(toplevel)));
  279.     XCopyPlane(XtDisplay(toplevel),bitmap,q->pixmap,gc,0,0,w,h,0,0,1);
  280.     XFreePixmap(XtDisplay(toplevel),bitmap);
  281.     if (flag) {
  282.     XTextExtents(XQueryFont(XtDisplay(toplevel),appResources.smallFont),
  283.                     user,strlen(user),&d,&x,&y,&ch);
  284.     x = ((int)w - ch.width)/2;
  285.     if (x < 1) x = 1;
  286.     y = h - 2;
  287.     if (appResources.opaqueNames)
  288.         XDrawImageString(XtDisplay(toplevel),q->pixmap,gc,x,y,user,
  289.                                 strlen(user));
  290.     else
  291.         XDrawString(XtDisplay(toplevel),q->pixmap,gc,x,y,user,strlen(user));
  292.     }
  293.     return(q->pixmap);
  294. }
  295.  
  296. /*    -    -    -    -    -    -    -    -    */
  297. /*
  298.  *    getTextFromWidget() : Return the text stored with the widget.
  299.  */
  300. char *
  301. getTextFromWidget(w)
  302. Widget w;
  303. {
  304.     CachedWidgetRec *p;
  305.  
  306.     if (w == NULL)
  307.     return(NULL);
  308.     p = widgetRecs;
  309.     while (p != NULL) {
  310.     if (p->widget == w)
  311.         return(p->text);
  312.     else
  313.         p = p->next;
  314.     }
  315.     return(NULL);
  316. }
  317.