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

  1. /*
  2.  * $XConsortium: xfd.c,v 1.31 91/07/18 14:13:24 rws Exp $
  3.  *
  4.  * Copyright 1989 Massachusetts Institute of Technology
  5.  *
  6.  * Permission to use, copy, modify, and distribute this software and its
  7.  * documentation for any purpose and without fee is hereby granted, provided
  8.  * that the above copyright notice appear in all copies and that both that
  9.  * copyright notice and this permission notice appear in supporting
  10.  * documentation, and that the name of M.I.T. not be used in advertising
  11.  * or publicity pertaining to distribution of the software without specific,
  12.  * written prior permission.  M.I.T. makes no representations about the
  13.  * suitability of this software for any purpose.  It is provided "as is"
  14.  * without express or implied warranty.
  15.  *
  16.  * M.I.T. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
  17.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL M.I.T.
  18.  * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  19.  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
  20.  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 
  21.  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  22.  *
  23.  * Author:  Jim Fulton, MIT X Consortium
  24.  */
  25.  
  26. #include <X11/Intrinsic.h>
  27. #include <X11/StringDefs.h>
  28. #include <X11/Xos.h>
  29. #include <X11/Xatom.h>
  30. #include <X11/Shell.h>
  31. #include <X11/Xaw/Cardinals.h>
  32. #include <X11/Xaw/Paned.h>
  33. #include <X11/Xaw/Box.h>
  34. #include <X11/Xaw/Form.h>
  35. #include <X11/Xaw/Command.h>
  36. #include <stdio.h>
  37. #include "fontgrid.h"
  38.  
  39. char *ProgramName;
  40.  
  41. static XrmOptionDescRec xfd_options[] = {
  42. {"-fn",        "*grid.font",    XrmoptionSepArg,    (caddr_t) NULL },
  43. {"-start",    "*startChar",    XrmoptionSepArg,     (caddr_t) NULL },
  44. {"-box",    "*grid.boxChars", XrmoptionNoArg,    (caddr_t) "on" },
  45. {"-bc",        "*grid.boxColor", XrmoptionSepArg,     (caddr_t) NULL },
  46. {"-center",    "*grid.centerChars", XrmoptionNoArg,    (caddr_t) "on" },
  47. {"-rows",    "*grid.cellRows", XrmoptionSepArg,    (caddr_t) NULL },
  48. {"-columns",    "*grid.cellColumns", XrmoptionSepArg,    (caddr_t) NULL },
  49. };
  50.  
  51. static void do_quit(), do_next(), do_prev();
  52. static void change_page (), set_button_state ();
  53. static char *get_font_name();
  54. static void SelectChar();
  55.  
  56. static XtActionsRec xfd_actions[] = {
  57.   { "Quit", do_quit },
  58.   { "Prev", do_prev },
  59.   { "Next", do_next },
  60. };
  61.  
  62. static Atom wm_delete_window;
  63.  
  64. Widget quitButton, prevButton, nextButton;
  65.  
  66.  
  67. #define DEF_SELECT_FORMAT "character 0x%02x%02x (%u,%u) (%#o,%#o)"
  68. #define DEF_METRICS_FORMAT "width %d; left %d, right %d; ascent %d, descent %d (font %d, %d)"
  69. #define DEF_RANGE_FORMAT "range:  0x%02x%02x (%u,%u) thru 0x%02x%02x (%u,%u)"
  70. #define DEF_START_FORMAT "upper left:  0x%04x (%d,%d)"
  71. #define DEF_NOCHAR_FORMAT "no such character 0x%02x%02x (%u,%u) (%#o,%#o)"
  72.  
  73. static struct _xfd_resources {
  74.   char *select_format;
  75.   char *metrics_format;
  76.   char *range_format;
  77.   char *start_format;
  78.   char *nochar_format;
  79. } xfd_resources;
  80.  
  81. #define Offset(field) XtOffsetOf(struct _xfd_resources, field)
  82.  
  83. static XtResource Resources[] = {
  84.   { "selectFormat", "SelectFormat", XtRString, sizeof(char *), 
  85.       Offset(select_format), XtRString, DEF_SELECT_FORMAT },
  86.   { "metricsFormat", "MetricsFormat", XtRString, sizeof(char *), 
  87.       Offset(metrics_format), XtRString, DEF_METRICS_FORMAT },
  88.   { "rangeFormat", "RangeFormat", XtRString, sizeof(char *), 
  89.       Offset(range_format), XtRString, DEF_RANGE_FORMAT },
  90.   { "startFormat", "StartFormat", XtRString, sizeof(char *), 
  91.       Offset(start_format), XtRString, DEF_START_FORMAT },
  92.   { "nocharFormat", "NocharFormat", XtRString, sizeof(char *), 
  93.       Offset(nochar_format), XtRString, DEF_NOCHAR_FORMAT },
  94. };
  95.  
  96. #undef Offset
  97.  
  98. usage()
  99. {
  100.     fprintf (stderr, "usage:  %s [-options ...] -fn font\n\n", ProgramName);
  101.     fprintf (stderr, "where options include:\n");
  102.     fprintf (stderr,
  103.     "    -display dpy           X server to contact\n");
  104.     fprintf (stderr, 
  105.     "    -geometry geom         size and location of window\n");
  106.     fprintf (stderr, 
  107.     "    -start num             first character to show\n");
  108.     fprintf (stderr, 
  109.     "    -box                   show a box around each character\n");
  110.     fprintf (stderr, 
  111.     "    -center                center each character inside its grid\n");
  112.     fprintf (stderr, 
  113.     "    -rows number           number of rows in grid\n");
  114.     fprintf (stderr, 
  115.     "    -columns number        number of columns in grid\n");
  116.     fprintf (stderr, "\n");
  117.     exit (1);
  118. }
  119.  
  120.  
  121. static Widget selectLabel, metricsLabel, rangeLabel, startLabel, fontGrid;
  122.  
  123. static Boolean fontConversionFailed = False;
  124. static void (*oldWarningHandler)();
  125. static void CatchFontConversionWarning();
  126.  
  127. main (argc, argv) 
  128.     int argc;
  129.     char **argv;
  130. {
  131.     XtAppContext xtcontext;
  132.     Widget toplevel, pane, toplabel, box, form;
  133.     char buf[256];
  134.     Arg av[10];
  135.     Cardinal i;
  136.     static XtCallbackRec cb[2] = { { SelectChar, NULL }, { NULL, NULL } };
  137.     XFontStruct *fs;
  138.     char *fontname;
  139.  
  140.     ProgramName = argv[0];
  141.  
  142.     toplevel = XtAppInitialize (&xtcontext, "Xfd",
  143.                 xfd_options, XtNumber(xfd_options),
  144.                 &argc, argv, NULL, NULL, 0);
  145.     if (argc != 1) usage ();
  146.     XtAppAddActions (xtcontext, xfd_actions, XtNumber (xfd_actions));
  147.     XtOverrideTranslations
  148.         (toplevel, XtParseTranslationTable ("<Message>WM_PROTOCOLS: Quit()"));
  149.  
  150.     XtGetApplicationResources (toplevel, (XtPointer) &xfd_resources, Resources,
  151.                    XtNumber (Resources), NULL, ZERO);
  152.  
  153.  
  154.     /* pane wrapping everything */
  155.     pane = XtCreateManagedWidget ("pane", panedWidgetClass, toplevel,
  156.                   NULL, ZERO);
  157.  
  158.     /* font name */
  159.     toplabel = XtCreateManagedWidget ("fontname", labelWidgetClass, pane, 
  160.                       NULL, ZERO);
  161.  
  162.     /* button box */
  163.     box = XtCreateManagedWidget ("box", boxWidgetClass, pane, NULL, ZERO);
  164.     quitButton = XtCreateManagedWidget ("quit", commandWidgetClass, box,
  165.                     NULL, ZERO);
  166.     prevButton = XtCreateManagedWidget ("prev", commandWidgetClass, box,
  167.                     NULL, ZERO);
  168.     nextButton = XtCreateManagedWidget ("next", commandWidgetClass, box,
  169.                     NULL, ZERO);
  170.  
  171.  
  172.     /* and labels in which to put information */
  173.     selectLabel = XtCreateManagedWidget ("select", labelWidgetClass,
  174.                      pane, NULL, ZERO);
  175.  
  176.     metricsLabel = XtCreateManagedWidget ("metrics", labelWidgetClass,
  177.                       pane, NULL, ZERO);
  178.  
  179.     rangeLabel = XtCreateManagedWidget ("range", labelWidgetClass, pane, 
  180.                     NULL, ZERO);
  181.  
  182.     startLabel = XtCreateManagedWidget ("start", labelWidgetClass, pane, 
  183.                     NULL, ZERO);
  184.  
  185.     /* form in which to draw */
  186.     form = XtCreateManagedWidget ("form", formWidgetClass, pane, NULL, ZERO);
  187.     
  188.     i = 0;
  189.     XtSetArg (av[i], XtNtop, XtChainTop); i++;
  190.     XtSetArg (av[i], XtNbottom, XtChainBottom); i++;
  191.     XtSetArg (av[i], XtNleft, XtChainLeft); i++;
  192.     XtSetArg (av[i], XtNright, XtChainRight); i++;
  193.     XtSetArg (av[i], XtNcallback, cb); i++;
  194.  
  195.     oldWarningHandler = XtAppSetWarningMsgHandler(xtcontext, 
  196.                           CatchFontConversionWarning);
  197.  
  198.     fontGrid = XtCreateManagedWidget ("grid", fontgridWidgetClass, form,
  199.                       av, i);
  200.  
  201.     XtAppSetWarningMsgHandler(xtcontext, oldWarningHandler);
  202.  
  203.     /* set the label at the top to tell us which font this is */
  204.     i = 0;
  205.     XtSetArg (av[i], XtNfont, &fs); i++;
  206.     XtGetValues (fontGrid, av, i);
  207.     if (!fs || fontConversionFailed) {
  208.     fprintf (stderr, "%s:  no font to display\n", ProgramName);
  209.     exit (1);
  210.     }
  211.     fontname = get_font_name (XtDisplay(toplevel), fs);
  212.     if (!fontname) fontname = "unknown font!";
  213.     i = 0;
  214.     XtSetArg (av[i], XtNlabel, fontname); i++;
  215.     XtSetValues (toplabel, av, i);
  216.  
  217.     i = 0;
  218.     XtSetArg (av[i], XtNlabel, buf); i++;
  219.     sprintf (buf, xfd_resources.range_format, 
  220.          fs->min_byte1, fs->min_char_or_byte2,
  221.          fs->min_byte1, fs->min_char_or_byte2,
  222.          fs->max_byte1, fs->max_char_or_byte2,
  223.          fs->max_byte1, fs->max_char_or_byte2);
  224.     XtSetValues (rangeLabel, av, i);
  225.  
  226.     XtRealizeWidget (toplevel);
  227.  
  228.     wm_delete_window = XInternAtom(XtDisplay(toplevel), "WM_DELETE_WINDOW",
  229.                                    False);
  230.     (void) XSetWMProtocols (XtDisplay(toplevel), XtWindow(toplevel),
  231.                             &wm_delete_window, 1);
  232.  
  233.     change_page (0);
  234.     XtAppMainLoop (xtcontext);
  235. }
  236.  
  237. /*ARGSUSED*/
  238. static void SelectChar (w, closure, data)
  239.     Widget w;
  240.     XtPointer closure, data;
  241. {
  242.     FontGridCharRec *p = (FontGridCharRec *) data;
  243.     XFontStruct *fs = p->thefont;
  244.     unsigned n = ((((unsigned) p->thechar.byte1) << 8) |
  245.           ((unsigned) p->thechar.byte2));
  246.     int direction, fontascent, fontdescent;
  247.     XCharStruct metrics;
  248.     char buf[256];
  249.     Arg arg;
  250.  
  251.     XtSetArg (arg, XtNlabel, buf);
  252.  
  253.     if ((!fs->min_byte1 && !fs->max_byte1) ?
  254.     (n < fs->min_char_or_byte2 || n > fs->max_char_or_byte2) :
  255.     (p->thechar.byte1 < fs->min_byte1 || p->thechar.byte1 > fs->max_byte1 ||
  256.      p->thechar.byte2 < fs->min_char_or_byte2 ||
  257.      p->thechar.byte2 > fs->max_char_or_byte2)) {
  258.     sprintf (buf, xfd_resources.nochar_format,
  259.          (unsigned) p->thechar.byte1, (unsigned) p->thechar.byte2,
  260.          (unsigned) p->thechar.byte1, (unsigned) p->thechar.byte2,
  261.          (unsigned) p->thechar.byte1, (unsigned) p->thechar.byte2);
  262.     XtSetValues (selectLabel, &arg, ONE);
  263.     buf[0] = '\0';
  264.     XtSetValues (metricsLabel, &arg, ONE);
  265.     return;
  266.     }
  267.  
  268.     XTextExtents16 (fs, &p->thechar, 1, &direction, &fontascent, &fontdescent,
  269.             &metrics);
  270.     sprintf (buf, xfd_resources.select_format,
  271.          (unsigned) p->thechar.byte1, (unsigned) p->thechar.byte2,
  272.          (unsigned) p->thechar.byte1, (unsigned) p->thechar.byte2,
  273.          (unsigned) p->thechar.byte1, (unsigned) p->thechar.byte2);
  274.     XtSetValues (selectLabel, &arg, ONE);
  275.  
  276.     sprintf (buf, xfd_resources.metrics_format,
  277.          metrics.width, metrics.lbearing, metrics.rbearing,
  278.          metrics.ascent, metrics.descent, fontascent, fontdescent);
  279.     XtSetValues (metricsLabel, &arg, ONE);
  280.  
  281.     return;
  282. }
  283.  
  284.  
  285. /*ARGSUSED*/
  286. static void do_quit (w, event, params, num_params)
  287.     Widget w;
  288.     XEvent *event;
  289.     String *params;
  290.     Cardinal *num_params;
  291. {
  292.     exit (0);
  293. }
  294.  
  295. static void change_page (page)
  296.     int page;
  297. {
  298.     Dimension oldstart, newstart;
  299.     int ncols, nrows;
  300.     char buf[256];
  301.     Arg arg;
  302.  
  303.     arg.name = XtNstartChar;
  304.     GetFontGridCellDimensions (fontGrid, &oldstart, &ncols, &nrows);
  305.  
  306.     if (page) {
  307.     Dimension start = (oldstart + 
  308.                ((long) ncols) * ((long) nrows) * ((long) page));
  309.  
  310.     arg.value = (XtArgVal) start;
  311.     XtSetValues (fontGrid, &arg, ONE);
  312.     }
  313.  
  314.     /* find out what it got set to */
  315.     arg.value = (XtArgVal) &newstart;
  316.     XtGetValues (fontGrid, &arg, ONE);
  317.  
  318.     /* if not paging, then initialize it, else only do it actually changed */
  319.     if (!page || newstart != oldstart) {
  320.     unsigned int row = (unsigned int) ((newstart >> 8) & 0xff);
  321.     unsigned int col = (unsigned int) (newstart & 0xff);
  322.  
  323.     XtSetArg (arg, XtNlabel, buf);
  324.     sprintf (buf, xfd_resources.start_format, newstart, row, col);
  325.     XtSetValues (startLabel, &arg, ONE);
  326.     }
  327.  
  328.     set_button_state ();
  329.  
  330.     return;
  331. }
  332.  
  333.  
  334. static void set_button_state ()
  335. {
  336.     Bool prevvalid, nextvalid;
  337.     Arg arg;
  338.  
  339.     GetPrevNextStates (fontGrid, &prevvalid, &nextvalid);
  340.     arg.name = XtNsensitive;
  341.     arg.value = (XtArgVal) (prevvalid ? TRUE : FALSE);
  342.     XtSetValues (prevButton, &arg, ONE);
  343.     arg.value = (XtArgVal) (nextvalid ? TRUE : FALSE);
  344.     XtSetValues (nextButton, &arg, ONE);
  345. }
  346.  
  347.  
  348. /* ARGSUSED */
  349. static void do_prev (w, event, params, num_params)
  350.     Widget w;
  351.     XEvent *event;
  352.     String *params;
  353.     Cardinal *num_params;
  354. {
  355.     change_page (-1);
  356. }
  357.  
  358.  
  359. /* ARGSUSED */
  360. static void do_next (w, event, params, num_params)
  361.     Widget w;
  362.     XEvent *event;
  363.     String *params;
  364.     Cardinal *num_params;
  365. {
  366.     change_page (1);
  367. }
  368.  
  369.  
  370. static char *get_font_name (dpy, fs)
  371.     Display *dpy;
  372.     XFontStruct *fs;
  373. {
  374.     register XFontProp *fp;
  375.     register int i;
  376.     Atom fontatom = XInternAtom (dpy, "FONT", False);
  377.  
  378.     for (i = 0, fp = fs->properties; i < fs->n_properties; i++, fp++) {
  379.     if (fp->name == fontatom) {
  380.         return (XGetAtomName (dpy, fp->card32));
  381.     }
  382.     }
  383.     return NULL;
  384. }
  385.  
  386.  
  387. static void CatchFontConversionWarning(name, type, class, defaultp, params, np)
  388.     String name, type, class, defaultp, *params;
  389.     Cardinal *np;
  390. {
  391.     if (np && *np > 1 &
  392.     strcmp(name, "conversionError") == 0 &&
  393.     strcmp(type, "string") == 0 &&
  394.     strcmp(class, "XtToolkitError") == 0 &&
  395.     strcmp(params[1], "FontStruct") == 0) fontConversionFailed = True;
  396.  
  397.     (*oldWarningHandler)(name, type, class, defaultp, params, np);
  398. }
  399.