home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / X / mit / clients / xmh / util.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-07-11  |  11.1 KB  |  532 lines

  1. /*
  2.  * $XConsortium: util.c,v 2.40 91/07/05 18:30:00 converse Exp $
  3.  *
  4.  *
  5.  *              COPYRIGHT 1987
  6.  *           DIGITAL EQUIPMENT CORPORATION
  7.  *               MAYNARD, MASSACHUSETTS
  8.  *            ALL RIGHTS RESERVED.
  9.  *
  10.  * THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE WITHOUT NOTICE AND
  11.  * SHOULD NOT BE CONSTRUED AS A COMMITMENT BY DIGITAL EQUIPMENT CORPORATION.
  12.  * DIGITAL MAKES NO REPRESENTATIONS ABOUT THE SUITABILITY OF THIS SOFTWARE FOR
  13.  * ANY PURPOSE.  IT IS SUPPLIED "AS IS" WITHOUT EXPRESS OR IMPLIED WARRANTY.
  14.  *
  15.  * IF THE SOFTWARE IS MODIFIED IN A MANNER CREATING DERIVATIVE COPYRIGHT
  16.  * RIGHTS, APPROPRIATE LEGENDS MAY BE PLACED ON THE DERIVATIVE WORK IN
  17.  * ADDITION TO THAT SET FORTH ABOVE.
  18.  *
  19.  * Permission to use, copy, modify, and distribute this software and its
  20.  * documentation for any purpose and without fee is hereby granted, provided
  21.  * that the above copyright notice appear in all copies and that both that
  22.  * copyright notice and this permission notice appear in supporting
  23.  * documentation, and that the name of Digital Equipment Corporation not be
  24.  * used in advertising or publicity pertaining to distribution of the software
  25.  * without specific, written prior permission.
  26.  */
  27.  
  28. /* util.c -- little miscellaneous utilities. */
  29.  
  30. #include "xmh.h"
  31. #include <sys/stat.h>
  32. #include <errno.h>
  33. #include <ctype.h>
  34. #include <X11/cursorfont.h>
  35.  
  36. #ifndef abs
  37. #define abs(x)        ((x) < 0 ? (-(x)) : (x))
  38. #endif
  39.  
  40. static char *SysErrorMsg (n)
  41.     int n;
  42. {
  43.     extern char *sys_errlist[];
  44.     extern int sys_nerr;
  45.     char *s = ((n >= 0 && n < sys_nerr) ? sys_errlist[n] : "unknown error");
  46.  
  47.     return (s ? s : "no such error");
  48. }
  49.  
  50. /* Something went wrong; panic and quit. */
  51.  
  52. void Punt(str)
  53.   char *str;
  54. {
  55.     (void) fprintf( stderr, "%s: %s\nerrno = %d; %s\007\n",
  56.             progName, str, errno, SysErrorMsg(errno) );
  57.     if (app_resources.debug) {
  58.     (void)fprintf(stderr, "forcing core dump.\n");
  59.     (void) fflush(stderr);
  60.     abort();
  61.     }
  62.     else {
  63.     (void)fprintf(stderr, "exiting.\n");
  64.     (void)fflush(stderr);
  65.     _exit(-1);
  66.     }
  67. }
  68.  
  69.  
  70. int myopen(path, flags, mode)
  71. char *path;
  72. int flags, mode;
  73. {
  74.     int fid;
  75.     fid = open(path, flags, mode);
  76.     if (fid >= 0) DEBUG2("# %d : %s\n", fid, path)
  77.     return fid;
  78. }
  79.  
  80.  
  81. FILE *myfopen(path, mode)
  82. char *path, *mode;
  83. {
  84.     FILE *result;
  85.     result = fopen(path, mode);
  86.     if (result)  DEBUG2("# %d : %s\n", fileno(result), path)
  87.     return result;
  88. }
  89.  
  90.  
  91.  
  92. int myclose(fid)
  93. {
  94.     if (close(fid) < 0) Punt("Error in myclose!");
  95.     DEBUG1( "# %d : <Closed>\n", fid)
  96. }
  97.  
  98.  
  99. int myfclose(file)
  100. FILE *file;
  101. {
  102.     int fid = fileno(file);
  103.     if (fclose(file) < 0) Punt("Error in myfclose!");
  104.     DEBUG1("# %d : <Closed>\n", fid)
  105. }
  106.  
  107.  
  108.  
  109. /* Return a unique file name. */
  110.  
  111. char *MakeNewTempFileName()
  112. {
  113.     static char name[60];
  114.     static int  uniqueid = 0;
  115.     do {
  116.     (void) sprintf(name, "%s/xmh_%ld_%d", app_resources.temp_dir,
  117.                getpid(), uniqueid++);
  118.     } while (FileExists(name));
  119.     return name;
  120. }
  121.  
  122.  
  123. /* Make an array of string pointers big enough to hold n+1 entries. */
  124.  
  125. char **MakeArgv(n)
  126.   int n;
  127. {
  128.     char **result;
  129.     result = ((char **) XtMalloc((unsigned) (n+1) * sizeof(char *)));
  130.     result[n] = 0;
  131.     return result;
  132. }
  133.  
  134.  
  135. char **ResizeArgv(argv, n)
  136.   char **argv;
  137.   int n;
  138. {
  139.     argv = ((char **) XtRealloc((char *) argv, (unsigned) (n+1) * sizeof(char *)));
  140.     argv[n] = 0;
  141.     return argv;
  142. }
  143.  
  144. /* Open a file, and punt if we can't. */
  145.  
  146. FILEPTR FOpenAndCheck(name, mode)
  147.   char *name, *mode;
  148. {
  149.     FILEPTR result;
  150.     result = myfopen(name, mode);
  151.     if (result == NULL) {
  152.     char str[500];
  153.     perror(progName);
  154.     (void)sprintf(str, "Error in FOpenAndCheck(%s, %s)", name, mode);
  155.     Punt(str);
  156.     }
  157.     return result;
  158. }
  159.  
  160.  
  161. /* Read one line from a file. */
  162.  
  163. static char *DoReadLine(fid, lastchar)
  164.   FILEPTR fid;
  165.   char lastchar;
  166. {
  167.     static char *buf;
  168.     static int  maxlength = 0;
  169.     char   *ptr, c;
  170.     int     length = 0;
  171.     ptr = buf;
  172.     c = ' ';
  173.     while (c != '\n' && !feof(fid)) {
  174.     c = getc(fid);
  175.     if (length++ > maxlength - 5) {
  176.         if (maxlength)
  177.         buf = XtRealloc(buf, (unsigned) (maxlength *= 2));
  178.         else
  179.         buf = XtMalloc((unsigned) (maxlength = 512));
  180.         ptr = buf + length - 1;
  181.     }
  182.     *ptr++ = c;
  183.     }
  184.     if (!feof(fid) || length > 1) {
  185.     *ptr = 0;
  186.     *--ptr = lastchar;
  187.     return buf;
  188.     }
  189.     return NULL;
  190. }
  191.  
  192.  
  193. char *ReadLine(fid)
  194.   FILEPTR fid;
  195. {
  196.     return DoReadLine(fid, 0);
  197. }
  198.  
  199.  
  200. /* Read a line, and keep the CR at the end. */
  201.  
  202. char *ReadLineWithCR(fid)
  203.   FILEPTR fid;
  204. {
  205.     return DoReadLine(fid, '\n');
  206. }
  207.  
  208.  
  209.  
  210. /* Delete a file, and Punt if it fails. */
  211.  
  212. void DeleteFileAndCheck(name)
  213.   char *name;
  214. {
  215.     if (strcmp(name, "/dev/null") != 0 && unlink(name) == -1) {
  216.     char str[500];
  217.     perror(progName);
  218.     (void)sprintf(str, "DeleteFileAndCheck(%s) failed!", name);
  219.     Punt(str);
  220.     }
  221. }
  222.  
  223. void CopyFileAndCheck(from, to)
  224.   char *from, *to;
  225. {
  226.     int fromfid, tofid, n;
  227.     char buf[512];
  228.     fromfid = myopen(from, O_RDONLY, 0666);
  229.     tofid = myopen(to, O_WRONLY | O_TRUNC | O_CREAT, 0666);
  230.     if (fromfid < 0 || tofid < 0) {
  231.     perror(progName);
  232.     (void)sprintf(buf, "CopyFileAndCheck(%s->%s) failed!", from, to);
  233.     Punt(buf);
  234.     }
  235.     do {
  236.     n = read(fromfid, buf, 512);
  237.     if (n) (void) write(tofid, buf, n);
  238.     } while (n);
  239.     (void) myclose(fromfid);
  240.     (void) myclose(tofid);
  241. }
  242.  
  243.  
  244. void RenameAndCheck(from, to)
  245.   char *from, *to;
  246. {
  247.     if (rename(from, to) == -1) {
  248.     if (errno != EXDEV) {
  249.         char str[500];
  250.         perror(progName);
  251.         (void)sprintf(str, "RenameAndCheck(%s->%s) failed!", from, to);
  252.         Punt(str);
  253.     }
  254.     CopyFileAndCheck(from, to);
  255.     DeleteFileAndCheck(from);
  256.     }
  257. }
  258.  
  259.  
  260. char *CreateGeometry(gbits, x, y, width, height)
  261.   int gbits;
  262.   int x, y, width, height;
  263. {
  264.     char   *result, str1[10], str2[10], str3[10], str4[10];
  265.     if (gbits & WidthValue)
  266.     (void) sprintf(str1, "=%d", width);
  267.     else
  268.     (void) strcpy(str1, "=");
  269.     if (gbits & HeightValue)
  270.     (void) sprintf(str2, "x%d", height);
  271.     else
  272.     (void) strcpy(str2, "x");
  273.     if (gbits & XValue)
  274.     (void) sprintf(str3, "%c%d", (gbits & XNegative) ? '-' : '+', abs(x));
  275.     else
  276.     (void) strcpy(str3, "");
  277.     if (gbits & YValue)
  278.     (void) sprintf(str4, "%c%d", (gbits & YNegative) ? '-' : '+', abs(y));
  279.     else
  280.     (void) strcpy(str4, "");
  281.     result = XtMalloc((unsigned) 22);
  282.     (void) sprintf(result, "%s%s%s%s", str1, str2, str3, str4);
  283.     return result;
  284. }
  285.  
  286.  
  287. FileExists(file)
  288.   char *file;
  289. {
  290.     return (access(file, F_OK) == 0);
  291. }
  292.  
  293. LastModifyDate(file)
  294.   char *file;
  295. {
  296.     struct stat buf;
  297.     if (stat(file, &buf)) return -1;
  298.     return buf.st_mtime;
  299. }
  300.  
  301. CurrentDate()
  302. {
  303.     struct timeval time;
  304.     struct timezone zone;
  305.     (void) gettimeofday(&time, &zone);
  306.     return time.tv_sec;
  307. }
  308.  
  309. GetFileLength(file)
  310. char *file;
  311. {
  312.     struct stat buf;
  313.     if (stat(file, &buf)) return -1;
  314.     return buf.st_size;
  315. }
  316.  
  317. Boolean    IsSubfolder(foldername)
  318.     char    *foldername;
  319. {
  320.     return (index(foldername, '/')) ? True : False;
  321. }
  322.  
  323. void SetCurrentFolderName(scrn, foldername)
  324.     Scrn    scrn;
  325.     char    *foldername;
  326. {
  327.     scrn->curfolder = foldername;
  328.     ChangeLabel((Widget) scrn->folderlabel, foldername);
  329. }
  330.  
  331.  
  332. void ChangeLabel(widget, str)
  333. Widget widget;
  334. char *str;
  335. {
  336.     static Arg arglist[] = {XtNlabel, (XtArgVal)NULL};
  337.     arglist[0].value = (XtArgVal) str;
  338.     XtSetValues(widget, arglist, XtNumber(arglist));
  339. }
  340.  
  341.  
  342. Widget CreateTextSW(scrn, name, args, num_args)
  343. Scrn scrn;
  344. char *name;
  345. ArgList    args;
  346. Cardinal num_args;
  347. {
  348.     /* most text widget options are set in the application defaults file */
  349.  
  350.     return XtCreateManagedWidget( name, asciiTextWidgetClass, scrn->widget,
  351.                   args, num_args);
  352. }
  353.  
  354.  
  355. Widget CreateTitleBar(scrn, name)
  356. Scrn scrn;
  357. char *name;
  358. {
  359.     Widget result;
  360.     int height;
  361.     static Arg arglist[] = {
  362.     {XtNlabel, (XtArgVal)NULL},
  363.     };
  364.     arglist[0].value = (XtArgVal) app_resources.banner; /* xmh version */
  365.     result = XtCreateManagedWidget( name, labelWidgetClass, scrn->widget,
  366.                     arglist, XtNumber(arglist) );
  367.     height = GetHeight(result);
  368.     XawPanedSetMinMax(result, height, height);
  369.     return result;
  370. }
  371.  
  372.  
  373. void Feep()
  374. {
  375.     XBell(theDisplay, 0);
  376. }
  377.  
  378.  
  379. MsgList CurMsgListOrCurMsg(toc)
  380.   Toc toc;
  381. {
  382.     MsgList result;
  383.     Msg curmsg;
  384.     result = TocCurMsgList(toc);
  385.     if (result->nummsgs == 0 && (curmsg = TocGetCurMsg(toc))) {
  386.     FreeMsgList(result);
  387.     result = MakeSingleMsgList(curmsg);
  388.     }
  389.     return result;
  390. }
  391.  
  392.  
  393. int GetHeight(w)
  394.    Widget w;
  395. {
  396.     Dimension height;
  397.     Arg args[1];
  398.  
  399.     XtSetArg(args[0], XtNheight, &height);
  400.     XtGetValues( w, args, (Cardinal)1 );
  401.     return (int)height;
  402. }
  403.  
  404.  
  405. int GetWidth(w)
  406.    Widget w;
  407. {
  408.     Dimension width;
  409.     Arg args[1];
  410.  
  411.     XtSetArg(args[0], XtNwidth, &width);
  412.     XtGetValues( w, args, (Cardinal)1 );
  413.     return (int)width;
  414. }
  415.  
  416.  
  417. Toc SelectedToc(scrn)
  418. Scrn scrn;
  419. {
  420.     Toc    toc;
  421.  
  422.     /* tocs of subfolders are created upon the first reference */
  423.  
  424.     if ((toc = TocGetNamed(scrn->curfolder)) == NULL) 
  425.         toc = TocCreate(scrn->curfolder);
  426.     return toc;
  427. }
  428.  
  429.  
  430. Toc CurrentToc(scrn)
  431.     Scrn    scrn;
  432. {
  433.     /* return the toc currently being viewed */
  434.  
  435.     return scrn->toc;
  436. }
  437.  
  438.  
  439. int strncmpIgnoringCase(str1, str2, length)
  440. char *str1, *str2;
  441. int length;
  442. {
  443.     int i, diff;
  444.     for (i=0 ; i<length ; i++, str1++, str2++) {
  445.         diff = ((*str1 >= 'A' && *str1 <= 'Z') ? (*str1 + 'a' - 'A') : *str1) -
  446.            ((*str2 >= 'A' && *str2 <= 'Z') ? (*str2 + 'a' - 'A') : *str2);
  447.     if (diff) return diff;
  448.     }
  449.     return 0;
  450. }
  451.  
  452.  
  453. void StoreWindowName(scrn, str)
  454. Scrn scrn;
  455. char *str;
  456. {
  457.     static Arg arglist[] = {
  458.     {XtNiconName,    (XtArgVal) NULL},
  459.     {XtNtitle,    (XtArgVal) NULL},
  460.     };
  461.     arglist[0].value = arglist[1].value = (XtArgVal) str;
  462.     XtSetValues(scrn->parent, arglist, XtNumber(arglist));
  463. }
  464.  
  465.  
  466. /* Create an input-only window with a busy-wait cursor. */
  467.  
  468. void InitBusyCursor(scrn)
  469.     Scrn    scrn;
  470. {
  471.     unsigned long        valuemask;
  472.     XSetWindowAttributes    attributes;
  473.  
  474.     /* the second condition is for the pick scrn */
  475.     if (! app_resources.block_events_on_busy || scrn->wait_window) 
  476.     return;    
  477.  
  478.     /* Ignore device events while the busy cursor is displayed. */
  479.  
  480.     valuemask = CWDontPropagate | CWCursor;
  481.     attributes.do_not_propagate_mask =    (KeyPressMask | KeyReleaseMask |
  482.                      ButtonPressMask | ButtonReleaseMask |
  483.                      PointerMotionMask);
  484.     attributes.cursor = app_resources.busy_cursor;
  485.  
  486.     /* The window will be as big as the display screen, and clipped by
  487.      * it's own parent window, so we never have to worry about resizing.
  488.      */
  489.  
  490.     scrn->wait_window =
  491.     XCreateWindow(XtDisplay(scrn->parent), XtWindow(scrn->parent), 0, 0, 
  492.               rootwidth, rootheight, (unsigned int) 0, CopyFromParent,
  493.               InputOnly, CopyFromParent, valuemask, &attributes);
  494. }
  495.  
  496. void ShowBusyCursor()
  497. {
  498.     register int    i;
  499.  
  500.     for (i=0; i < numScrns; i++)
  501.     if (scrnList[i]->mapped)
  502.         XMapWindow(theDisplay, scrnList[i]->wait_window);
  503. }
  504.  
  505. void UnshowBusyCursor()
  506. {
  507.     register int    i;
  508.     
  509.     for (i=0; i < numScrns; i++)
  510.     if (scrnList[i]->mapped)
  511.         XUnmapWindow(theDisplay, scrnList[i]->wait_window);
  512. }
  513.  
  514.  
  515. void SetCursorColor(widget, cursor, foreground)
  516.     Widget        widget;
  517.     Cursor        cursor;
  518.     unsigned long    foreground;
  519. {
  520.     XColor    colors[2];
  521.     Arg        args[2];
  522.     Colormap    cmap;
  523.  
  524.     colors[0].pixel = foreground;
  525.     XtSetArg(args[0], XtNbackground, &(colors[1].pixel));
  526.     XtSetArg(args[1], XtNcolormap, &cmap);
  527.     XtGetValues(widget, args, (Cardinal) 2);
  528.     XQueryColors(XtDisplay(widget), cmap, colors, 2);
  529.     XRecolorCursor(XtDisplay(widget), cursor, &colors[0], &colors[1]);
  530. }
  531.  
  532.