home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / x / volume8 / chaos / part01 / widgets / Label.c < prev   
Encoding:
C/C++ Source or Header  |  1990-08-20  |  6.3 KB  |  242 lines

  1. /*
  2.  * Copyright (c) Ken W. Marks 1989, 1990.
  3.  */
  4.  
  5. #include <stdio.h>
  6. #include <ctype.h>
  7. #include <X11/IntrinsicP.h>
  8. #include <X11/StringDefs.h>
  9. #include <Chaos.h>
  10. #include <LocalDefs.h>
  11. #include <LabelP.h>
  12.  
  13. #define LABEL_ALLOC_COUNT    10
  14.  
  15. static void LabelInitialize();
  16. static void LabelRedisplay();
  17. static void LabelDestroy();
  18.  
  19. #define offset(field) XtOffset(LabelWidget, field)
  20.  
  21. static XtResource resources[] = {
  22.     {XtNforeground, XtCForeground, XtRPixel, sizeof(Pixel),
  23.     offset(label.foreground), XtRString, "XtDefaultForeground"},
  24.     {XtNfont, XtCFont, XtRFontStruct, sizeof(XFontStruct *),
  25.     offset(label.font), XtRString, "chaos-bold"},
  26.     {XtNlabel, XtCLabel, XtRString, sizeof(String),
  27.     offset(label.label), XtRString, NULL},
  28.     {XtNinternalWidth, XtCWidth, XtRDimension, sizeof(Dimension),
  29.     offset(label.internal_width), XtRImmediate, (caddr_t) 4},
  30.     {XtNinternalHeight, XtCHeight, XtRDimension, sizeof(Dimension),
  31.     offset(label.internal_height), XtRImmediate, (caddr_t) 2},
  32. };
  33.  
  34. #define superclass        (&simpleClassRec)
  35.  
  36. LabelClassRec labelClassRec = {
  37.     {
  38.     /* core_class fields */
  39.      /* superclass           */ (WidgetClass) superclass,
  40.      /* class_name           */ "Label",
  41.      /* widget_size           */ sizeof(LabelRec),
  42.      /* class_initialize        */ NULL,
  43.      /* class_part_initialize */ NULL,
  44.      /* class_inited            */ FALSE,
  45.      /* initialize           */ LabelInitialize,
  46.      /* initialize_hoo     */ NULL,
  47.      /* realize           */ XtInheritRealize,
  48.      /* actions           */ NULL,
  49.      /* num_actions           */ 0,
  50.      /* resources           */ resources,
  51.      /* num_resources     */ XtNumber(resources),
  52.      /* xrm_class           */ NULLQUARK,
  53.      /* compress_motion     */ TRUE,
  54.      /* compress_exposure       */ TRUE,
  55.      /* compress_enterleave     */ TRUE,
  56.      /* visible_interest     */ FALSE,
  57.      /* destroy         */ LabelDestroy,
  58.      /* resize         */ NULL,
  59.      /* expose         */ LabelRedisplay,
  60.      /* set_values           */ NULL,
  61.      /* set_values_hook     */ NULL,
  62.      /* set_values_almost     */ XtInheritSetValuesAlmost,
  63.      /* get_values_hook     */ NULL,
  64.      /* accept_focus     */ NULL,
  65.      /* version         */ XtVersion,
  66.      /* callback_private        */ NULL,
  67.      /* tm_table         */ NULL,
  68.      /* query_geometry     */ NULL,
  69.      /* display_accelerator     */ XtInheritDisplayAccelerator,
  70.      /* extension         */ NULL
  71.     },
  72.     {
  73.     /* Simple class fields initialization */
  74.      /* change_sensitive     */ XtInheritChangeSensitive
  75.     }
  76. };
  77.  
  78. WidgetClass labelWidgetClass = (WidgetClass) & labelClassRec;
  79.  
  80.  
  81. /************************************************************/
  82. /******************** Private Procedures ********************/
  83. /************************************************************/
  84.  
  85.  
  86. static void LabelGetGC(w)
  87. LabelWidget w;
  88. {
  89.     XGCValues values;
  90.  
  91.     values.foreground = w->label.foreground;
  92.     values.background = w->core.background_pixel;
  93.     values.font = w->label.font->fid;
  94.  
  95.     w->label.normal_gc = XtGetGC((Widget) w, (unsigned) GCForeground |
  96.       GCBackground | GCFont, &values);
  97. }
  98.  
  99.  
  100. static void LabelSetSize(w)
  101. LabelWidget w;
  102. {
  103.     XtWidgetGeometry my_request;
  104.     char *label = w->label.label;
  105.     char *start = label;
  106.     char *end = label;
  107.     int line_width;
  108.  
  109.     w->label.label_len = strlen(label);
  110.     w->label.num_lines = 0;
  111.     w->label.label_width = 0;
  112.  
  113.     while (1)
  114.     {
  115.     if (*end == '\0' || *end == '\n' || (*end == '\\' && end[1] == 'n'))
  116.     {
  117.         if (w->label.num_lines >= w->label.num_lines_alloced)
  118.         {
  119.         w->label.num_lines_alloced += LABEL_ALLOC_COUNT;
  120.         w->label.line_start =
  121.           (int *) realloc((char *) w->label.line_start,
  122.           w->label.num_lines_alloced * sizeof(int));
  123.         w->label.line_len = (int *) realloc((char *) w->label.line_len,
  124.           w->label.num_lines_alloced * sizeof(int));
  125.         }
  126.         w->label.line_start[w->label.num_lines] = (int) (start - label);
  127.         w->label.line_len[w->label.num_lines] = (int) (end - start);
  128.  
  129.         line_width = (end - start) * w->label.char_width;
  130.         if (line_width > w->label.label_width)
  131.         w->label.label_width = line_width;
  132.         w->label.num_lines++;
  133.         if (*end == '\0')
  134.         break;
  135.         if (*end != '\n')
  136.         ++end;
  137.         start = end + 1;
  138.     }
  139.     ++end;
  140.     }
  141.  
  142.     w->label.label_height = w->label.num_lines * w->label.char_height;
  143.  
  144.     my_request.request_mode = CWWidth | CWHeight;
  145.     my_request.width = w->label.label_width + 2 * w->label.internal_width;
  146.     my_request.height = w->label.label_height + 2 * w->label.internal_height;
  147.  
  148.     XtMakeGeometryRequest((Widget) w, &my_request, NULL);
  149. }
  150.  
  151.  
  152. /* ARGSUSED */
  153. static void LabelInitialize(request, new)
  154. Widget request, new;
  155. {
  156.     LabelWidget w = (LabelWidget) new;
  157.     XFontStruct *fs = w->label.font;
  158.  
  159.     if (w->label.label == NULL)
  160.     {
  161.     eprintf("XtNLabel not set\n");
  162.     abort();
  163.     }
  164.  
  165.     w->label.label = STRCOPY(w->label.label);
  166.     w->label.num_lines_alloced = LABEL_ALLOC_COUNT;
  167.     w->label.line_start = (int *) malloc(LABEL_ALLOC_COUNT * sizeof(int));
  168.     w->label.line_len = (int *) malloc(LABEL_ALLOC_COUNT * sizeof(int));
  169.     w->label.char_height = fs->max_bounds.ascent + fs->max_bounds.descent;
  170.     w->label.char_width = fs->max_bounds.width;
  171.     w->label.label_x = w->label.internal_width;
  172.     w->label.label_y = w->label.internal_height + fs->max_bounds.ascent;
  173.  
  174.     LabelGetGC(w);
  175.     LabelSetSize(w);
  176. }
  177.  
  178.  
  179. /* ARGSUSED */
  180. static void LabelRedisplay(widget, event, region)
  181. Widget widget;
  182. XEvent *event;
  183. Region region;
  184. {
  185.     LabelWidget w = (LabelWidget) widget;
  186.     Display *dpy = XtDisplay(w);
  187.     Window window = XtWindow(w);
  188.     Position line_y = w->label.label_y;
  189.     int *line_start = w->label.line_start;
  190.     int *line_len = w->label.line_len;
  191.     char *label;
  192.     int ii;
  193.  
  194.     if (XtIsRealized(widget) == False)
  195.     return;
  196.  
  197.     for (ii = 0; ii < w->label.num_lines; ++ii)
  198.     {
  199.     label = &(w->label.label[*line_start]);
  200.  
  201.     XDrawImageString(dpy, window, w->label.normal_gc, w->label.label_x,
  202.       line_y, label, *line_len);
  203.  
  204.     line_y += w->label.char_height;
  205.     ++line_start;
  206.     ++line_len;
  207.     }
  208. }
  209.  
  210.  
  211. static void LabelDestroy(widget)
  212. Widget widget;
  213. {
  214.     LabelWidget w = (LabelWidget) widget;
  215.  
  216.     XtReleaseGC(widget, w->label.normal_gc);
  217. }
  218.  
  219.  
  220. /***********************************************************/
  221. /******************** Public Procedures ********************/
  222. /***********************************************************/
  223.  
  224.  
  225. void LabelChangeLabel(widget, label)
  226. Widget widget;
  227. char *label;
  228. {
  229.     LabelWidget w = (LabelWidget) widget;
  230.  
  231.     if (label == NULL)
  232.     {
  233.     eprintf("Label may not be NULL\n");
  234.     abort();
  235.     }
  236.  
  237.     free(w->label.label);
  238.     w->label.label = STRCOPY(label);
  239.     LabelSetSize(w);
  240.     LabelRedisplay(widget, (XEvent *) NULL, (Region) NULL);
  241. }
  242.