DisplayList.c revision 5ec34c4c
1/*
2 * Copyright (c) 1998 by The XFree86 Project, Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
17 * THE XFREE86 PROJECT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
18 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
19 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20 * SOFTWARE.
21 *
22 * Except as contained in this notice, the name of the XFree86 Project shall
23 * not be used in advertising or otherwise to promote the sale, use or other
24 * dealings in this Software without prior written authorization from the
25 * XFree86 Project.
26 *
27 * Author: Paulo César Pereira de Andrade
28 */
29
30#ifdef HAVE_CONFIG_H
31#include <config.h>
32#endif
33#include <ctype.h>
34#include <string.h>
35#include <stdio.h>
36#include <stdlib.h>
37#include <X11/IntrinsicP.h>
38#include <X11/StringDefs.h>
39#include <X11/CoreP.h>
40#include <X11/Xfuncs.h>
41#include <X11/Xmu/CharSet.h>
42#include "Private.h"
43
44
45#ifndef OLDXAW
46
47/*
48 * Types
49 */
50typedef struct _XawDLProc XawDLProc;
51typedef struct _XawDLData XawDLData;
52typedef struct _XawDLInfo XawDLInfo;
53
54struct _XawDLProc {
55  XrmQuark qname;
56  String *params;
57  Cardinal num_params;
58  XawDisplayListProc proc;
59  XtPointer args;
60  XawDLData *data;
61};
62
63struct _XawDLData {
64  XawDLClass *dlclass;
65  XtPointer data;
66};
67
68struct _XawDLInfo {
69  String name;
70  XrmQuark qname;
71  XawDisplayListProc proc;
72};
73
74struct _XawDL {
75  XawDLProc **procs;
76  Cardinal num_procs;
77  XawDLData **data;
78  Cardinal num_data;
79  Screen *screen;
80  Colormap colormap;
81  int depth;
82  XrmQuark qrep;  /* for cache lookup */
83};
84
85struct _XawDLClass {
86  String name;
87  XawDLInfo **infos;
88  Cardinal num_infos;
89  XawDLArgsInitProc args_init;
90  XawDLArgsDestructor args_destructor;
91  XawDLDataInitProc data_init;
92  XawDLDataDestructor data_destructor;
93};
94
95/*
96 * Private Methods
97 */
98static XawDLClass *_XawFindDLClass(String);
99static int qcmp_dlist_class(_Xconst void*, _Xconst void*);
100static int bcmp_dlist_class(_Xconst void*, _Xconst void*);
101static XawDLInfo *_XawFindDLInfo(XawDLClass*, String);
102static int qcmp_dlist_info(_Xconst void*, _Xconst void*);
103static int bcmp_dlist_info(_Xconst void*, _Xconst void*);
104static void *_Xaw_Xlib_ArgsInitProc(String, String*, Cardinal*,
105				    Screen*, Colormap, int);
106static void _Xaw_Xlib_ArgsDestructor(Display*, String, XtPointer,
107				     String*, Cardinal*);
108static void *_Xaw_Xlib_DataInitProc(String, Screen*, Colormap, int);
109static void _Xaw_Xlib_DataDestructor(Display*, String, XtPointer);
110
111/*
112 * Initialization
113 */
114static XawDLClass **classes;
115static Cardinal num_classes;
116static String xlib = "xlib";
117
118/*
119 * Implementation
120 */
121void
122XawRunDisplayList(Widget w, _XawDisplayList *list,
123		       XEvent *event, Region region)
124{
125  XawDLProc *proc;
126  Cardinal i;
127
128  if (!XtIsRealized(w))
129    return;
130
131  for (i = 0; i < list->num_procs; i++)
132    {
133      proc = list->procs[i];
134      proc->proc(w, proc->args, proc->data->data, event, region);
135    }
136}
137
138#define DLERR  -2
139#define DLEOF  -1
140#define DLEND  1
141#define DLNAME 2
142#define DLARG  3
143static String
144read_token(String src, char *dst, Cardinal size, int *status)
145{
146  int ch;
147  Bool esc, quote;
148  Cardinal i;
149
150  i = 0;
151  esc = quote = False;
152
153  /*CONSTCOND*/
154  while (1)
155    {
156      ch = *src;
157      if (ch != '\n' && isspace(ch))
158	++src;
159      else
160	break;
161    }
162
163  for (; i < size - 1; src++)
164    {
165      ch = *src;
166      if (ch == '"')
167	{
168	  if (quote)
169	    {
170	      quote = False;
171	      continue;
172	    }
173	  quote = True;
174	  continue;
175	}
176      if (ch == '\\')
177	{
178	  if (esc)
179	    {
180	      dst[i++] = (char)ch;
181	      esc = False;
182	      continue;
183	    }
184	  esc = True;
185	  continue;
186	}
187      if (ch == '\0')
188	{
189	  *status = DLEOF;
190	  dst[i] = '\0';
191	  return (src);
192	}
193      else if (!esc)
194	{
195	  if (!quote)
196	    {
197	      if (ch == ',')
198		{
199		  *status = DLARG;
200		  dst[i] = '\0';
201		  return (++src);
202		}
203	      else if (ch == ' ' || ch == '\t')
204		{
205		  *status = DLNAME;
206		  dst[i] = '\0';
207		  return (++src);
208		}
209	      else if (ch == ';' || ch == '\n')
210		{
211		  *status = DLEND;
212		  dst[i] = '\0';
213		  return (++src);
214		}
215	    }
216	}
217      else
218	esc = False;
219      dst[i++] = (char)ch;
220    }
221
222  *status = DLERR;
223  dst[i] = '\0';
224
225  return (src);
226}
227
228_XawDisplayList *XawCreateDisplayList(String string, Screen *screen,
229				     Colormap colormap, int depth)
230{
231  _XawDisplayList *dlist;
232  XawDLClass *lc, *xlibc;
233  XawDLData *data;
234  XawDLInfo *info;
235  XawDLProc *proc;
236  char cname[64], fname[64], aname[1024];
237  Cardinal i;
238  String cp;
239  String fp;
240  String lp;
241  int status;
242
243  xlibc = XawGetDisplayListClass(xlib);
244  if (!xlibc)
245    {
246      XawDisplayListInitialize();
247      xlibc = XawGetDisplayListClass(xlib);
248    }
249
250  dlist = (_XawDisplayList *)XtMalloc(sizeof(_XawDisplayList));
251  dlist->procs = NULL;
252  dlist->num_procs = 0;
253  dlist->data = NULL;
254  dlist->num_data = 0;
255  dlist->screen = screen;
256  dlist->colormap = colormap;
257  dlist->depth = depth;
258  dlist->qrep = NULLQUARK;
259  if (!string || !string[0])
260    return (dlist);
261
262  cp = string;
263
264  status = 0;
265  while (status != DLEOF)
266    {
267      lp = cp;
268      cp = read_token(cp, fname, sizeof(fname), &status);
269
270      if (status != DLNAME && status != DLEND && status != DLEOF)
271	{
272	  char msg[256];
273
274	  snprintf(msg, sizeof(msg),
275		   "Error parsing displayList at \"%s\"", lp);
276	  XtAppWarning(XtDisplayToApplicationContext(DisplayOfScreen(screen)),
277		       msg);
278	  XawDestroyDisplayList(dlist);
279	  return (NULL);
280	}
281      fp = fname;
282      /*CONSTCOND*/
283      while (1)
284	{
285	  fp = strchr(fp, ':');
286	  if (!fp || (fp == cp || fp[-1] != '\\'))
287	    break;
288	  ++fp;
289	}
290      if (fp)
291	{
292	  snprintf(cname, (size_t)(fp - fname + 1), "%s", fname);
293	  memmove(fname, fp + 1, strlen(fp));
294	  lc = cname[0] ? XawGetDisplayListClass(cname) : xlibc;
295	  if (!lc)
296	    {
297	      char msg[256];
298
299	      snprintf(msg, sizeof(msg),
300		       "Cannot find displayList class \"%s\"", cname);
301	      XtAppWarning(XtDisplayToApplicationContext
302			   (DisplayOfScreen(screen)), msg);
303	      XawDestroyDisplayList(dlist);
304	      return (NULL);
305	    }
306	}
307      else
308	lc = xlibc;
309
310      if (status == DLEOF && !fname[0])
311	break;
312
313      if ((info = _XawFindDLInfo(lc, fname)) == NULL)
314	{
315	  char msg[256];
316
317	  snprintf(msg, sizeof(msg),
318		   "Cannot find displayList procedure \"%s\"", fname);
319	  XtAppWarning(XtDisplayToApplicationContext(DisplayOfScreen(screen)),
320		       msg);
321	  XawDestroyDisplayList(dlist);
322	  return (NULL);
323	}
324
325      proc = (XawDLProc *)XtMalloc(sizeof(XawDLProc));
326      proc->qname = info->qname;
327      proc->params = NULL;
328      proc->num_params = 0;
329      proc->proc = info->proc;
330      proc->args = NULL;
331      proc->data = NULL;
332
333      if (!dlist->procs)
334	{
335	  dlist->num_procs = 1;
336	  dlist->procs = (XawDLProc**)XtMalloc(sizeof(XawDLProc*));
337	}
338      else
339	{
340	  ++dlist->num_procs;
341	  dlist->procs = (XawDLProc**)
342	    XtRealloc((char *)dlist->procs, (Cardinal)(sizeof(XawDLProc*) *
343		      dlist->num_procs));
344	}
345      dlist->procs[dlist->num_procs - 1] = proc;
346
347      while (status != DLEND && status != DLEOF)
348	{
349	  lp = cp;
350	  cp = read_token(cp, aname, sizeof(aname), &status);
351
352	  if (status != DLARG && status != DLEND && status != DLEOF)
353	    {
354	      char msg[256];
355
356	      snprintf(msg, sizeof(msg),
357		       "Error parsing displayList at \"%s\"", lp);
358	      XtAppWarning(XtDisplayToApplicationContext
359			   (DisplayOfScreen(screen)), msg);
360	      XawDestroyDisplayList(dlist);
361	      return (NULL);
362	    }
363
364	  if (!proc->num_params)
365	    {
366	      proc->num_params = 1;
367	      proc->params = (String *)XtMalloc(sizeof(String));
368	    }
369	  else
370	    {
371	      ++proc->num_params;
372	      proc->params = (String *)XtRealloc((char *)proc->params,
373						 (Cardinal)(sizeof(String) *
374						 proc->num_params));
375	    }
376	  proc->params[proc->num_params - 1] = XtNewString(aname);
377	}
378
379      /* verify if data is already created for lc */
380      data = NULL;
381      for (i = 0; i < dlist->num_data; i++)
382	if (dlist->data[i]->dlclass == lc)
383	  {
384	    data = dlist->data[i];
385	    break;
386	  }
387
388      if (!data)
389	{
390	  data = (XawDLData *)XtMalloc(sizeof(XawDLData));
391	  data->dlclass = lc;
392	  if (lc->data_init)
393	    data->data = lc->data_init(lc->name, screen, colormap, depth);
394	  else
395	    data->data = NULL;
396
397	  if (!dlist->data)
398	    {
399	      dlist->num_data = 1;
400	      dlist->data = (XawDLData **)XtMalloc(sizeof(XawDLData*));
401	    }
402	  else
403	    {
404	      ++dlist->num_data;
405	      dlist->data = (XawDLData **)
406		XtRealloc((char *)dlist->data, (Cardinal)(sizeof(XawDLData*) *
407			  dlist->num_data));
408	    }
409	  dlist->data[dlist->num_data - 1] = data;
410	}
411
412      if (lc->args_init)
413	{
414	  proc->args = lc->args_init(fname, proc->params, &proc->num_params,
415				    screen, colormap, depth);
416	  if (proc->args == XAWDL_CONVERT_ERROR)
417	    {
418	      char msg[256];
419
420	      proc->args = NULL;
421	      snprintf(msg, sizeof(msg),
422		       "Cannot convert arguments to displayList function \"%s\"",
423		       fname);
424	      XtAppWarning(XtDisplayToApplicationContext
425			   (DisplayOfScreen(screen)), msg);
426	      XawDestroyDisplayList(dlist);
427	      return (NULL);
428	    }
429	}
430      else
431	proc->args = NULL;
432
433      proc->data = data;
434    }
435
436  dlist->qrep = XrmStringToQuark(string);
437  return (dlist);
438}
439
440String
441XawDisplayListString(_XawDisplayList *dlist)
442{
443  if (!dlist || dlist->qrep == NULLQUARK)
444    return ("");
445  return (XrmQuarkToString(dlist->qrep));
446}
447
448void
449XawDestroyDisplayList(_XawDisplayList *dlist)
450{
451  Cardinal i, j;
452  XawDLProc *proc;
453  XawDLData *data;
454
455  if (!dlist)
456    return;
457
458  for (i = 0; i < dlist->num_procs; i++)
459    {
460      proc = dlist->procs[i];
461      data = proc->data;
462
463      if (data)
464	{
465	  if (data->dlclass->args_destructor)
466	    data->dlclass->args_destructor(DisplayOfScreen(dlist->screen),
467					   XrmQuarkToString(proc->qname),
468					   proc->args,
469					   proc->params, &proc->num_params);
470	  if (data->data)
471	    {
472	      if (data->dlclass->data_destructor)
473		{
474		  data->dlclass
475		    ->data_destructor(DisplayOfScreen(dlist->screen),
476				      data->dlclass->name,  data->data);
477		  data->data = NULL;
478		}
479	    }
480	}
481
482      for (j = 0; j < proc->num_params; j++)
483	XtFree((char *)proc->params[j]);
484      if (proc->num_params)
485	XtFree((char *)proc->params);
486      XtFree((char *)proc);
487    }
488
489  if (dlist->num_procs)
490    XtFree((char *)dlist->procs);
491
492  XtFree((char *)dlist);
493}
494
495/**********************************************************************
496 * If you want to implement your own class of procedures, look at
497 * the code bellow.
498 **********************************************************************/
499/* Start of Implementation of class "xlib" */
500typedef struct _XawXlibData {
501  GC gc;
502  unsigned long mask;
503  XGCValues values;
504  int shape;
505  int mode;
506  char *dashes;
507  /* these fields can be used for optimization, to
508   * avoid unnecessary coordinates recalculation.
509   */
510  Position x, y;
511  Dimension width, height;
512} XawXlibData;
513
514typedef struct _XawDLPosition {
515  Position pos;
516  short denom;
517  Boolean high;
518} XawDLPosition;
519
520typedef struct _XawDLPositionPtr {
521  XawDLPosition *pos;
522  Cardinal num_pos;
523} XawDLPositionPtr;
524
525typedef struct _XawDLArcArgs {
526  XawDLPosition pos[4];
527  int angle1;
528  int angle2;
529} XawDLArcArgs;
530
531typedef struct _XawDLStringArgs {
532  XawDLPosition pos[2];
533  char *string;
534  int length;
535} XawDLStringArgs;
536
537typedef struct _XawDLCopyArgs {
538  XawPixmap *pixmap;
539  XawDLPosition pos[6];
540  int plane;
541} XawDLCopyArgs;
542
543typedef struct _XawDLImageArgs {
544  XawPixmap *pixmap;
545  XawDLPosition pos[4];
546  int depth;
547} XawDLImageArgs;
548
549#define X_ARG(x) ((Position)(((x).denom != 0) ?				      \
550		  ((float)XtWidth(w) * ((float)(x).pos / (float)(x).denom)) : \
551		  (float)((x).high ? XtWidth(w) - (x).pos : (x).pos)))
552#define Y_ARG(x) ((Position)(((x).denom != 0) ?				      \
553		  ((float)XtHeight(w) * ((float)(x).pos / (float)(x).denom)): \
554		  (float)((x).high ? XtHeight(w) - (x).pos : (x).pos)))
555#define DRECT		0
556#define FRECT		1
557#define LINE		2
558#define GCFG		3
559#define GCBG		4
560#define FPOLY		5
561#define DARC		6
562#define FARC		7
563#define DLINES		8
564#define MASK		9
565#define UMASK		10
566#define LWIDTH		11
567#define POINT		12
568#define POINTS		13
569#define SEGMENTS	14
570#define ARCMODE		15
571#define COORDMODE	16
572#define SHAPEMODE	17
573#define LINESTYLE	18
574#define CAPSTYLE	19
575#define JOINSTYLE	20
576#define FILLSTYLE	21
577#define FILLRULE	22
578#define	TILE		23
579#define STIPPLE		24
580#define TSORIGIN	25
581#define FUNCTION	26
582#define PLANEMASK	27
583#define DSTRING		28
584#define PSTRING		29
585#define FONT		30
586#define DASHES		31
587#define SUBWMODE	32
588#define EXPOSURES	33
589#define CLIPORIGIN	34
590#define CLIPMASK	35
591#define CLIPRECTS	36
592#define COPYAREA	37
593#define COPYPLANE	38
594#define IMAGE		39
595
596static void
597Dl1Point(Widget w, XtPointer args, XtPointer data, int id)
598{
599  XawDLPosition *pos = (XawDLPosition *)args;
600  XawXlibData *xdata = (XawXlibData *)data;
601  Display *display;
602  Window window;
603  Position x, y;
604
605  x = (Position)(X_ARG(pos[0]));
606  y = (Position)(Y_ARG(pos[1]));
607
608  if (!XtIsWidget(w))
609    {
610      Position xpad, ypad;
611
612      xpad = (Position)(XtX(w) + XtBorderWidth(w));
613      ypad = (Position)(XtY(w) + XtBorderWidth(w));
614      x = (Position)(x + xpad);
615      y = (Position)(y + ypad);
616      display = XtDisplayOfObject(w);
617      window = XtWindowOfObject(w);
618    }
619  else
620    {
621      display = XtDisplay(w);
622      window = XtWindow(w);
623    }
624
625  if (id == POINT)
626    XDrawPoint(display, window, xdata->gc, x, y);
627  else if (id == TSORIGIN)
628    {
629      xdata->values.ts_x_origin = x;
630      xdata->values.ts_y_origin = y;
631      xdata->mask |= GCTileStipXOrigin | GCTileStipYOrigin;
632      XSetTSOrigin(display, xdata->gc, x, y);
633    }
634  else if (id == CLIPORIGIN)
635    {
636      xdata->values.clip_x_origin = x;
637      xdata->values.clip_y_origin = y;
638      xdata->mask |= GCClipXOrigin | GCClipYOrigin;
639      XSetClipOrigin(display, xdata->gc, x, y);
640    }
641}
642
643static void
644Dl2Points(Widget w, XtPointer args, XtPointer data, int id)
645{
646  XawDLPosition *pos = (XawDLPosition *)args;
647  XawXlibData *xdata = (XawXlibData *)data;
648  Display *display;
649  Window window;
650  Position x1, y1, x2, y2;
651
652  x1 = X_ARG(pos[0]);
653  y1 = Y_ARG(pos[1]);
654  x2 = X_ARG(pos[2]);
655  y2 = Y_ARG(pos[3]);
656
657  if (!XtIsWidget(w))
658    {
659      Position xpad, ypad;
660
661      xpad = (Position)(XtX(w) + XtBorderWidth(w));
662      ypad = (Position)(XtY(w) + XtBorderWidth(w));
663      x1 = (Position)(x1 + xpad); y1 = (Position)(y1 + ypad);
664      x2 = (Position)(x2 + xpad); y2 = (Position)(y2 + ypad);
665      display = XtDisplayOfObject(w);
666      window = XtWindowOfObject(w);
667    }
668  else
669    {
670      display = XtDisplay(w);
671      window = XtWindow(w);
672    }
673
674  if (id == DRECT)
675    XDrawRectangle(display, window, xdata->gc, x1, y1, (unsigned)(x2 - x1), (unsigned)(y2 - y1));
676  else if (id == FRECT)
677    XFillRectangle(display, window, xdata->gc, x1, y1, (unsigned)(x2 - x1), (unsigned)(y2 - y1));
678  else if (id == LINE)
679    XDrawLine(display, window, xdata->gc, x1, y1, x2, y2);
680}
681
682/* ARGSUSED */
683static void
684DlLine(Widget w, XtPointer args, XtPointer data, XEvent *event _X_UNUSED, Region region _X_UNUSED)
685{
686  Dl2Points(w, args, data, LINE);
687}
688
689/* ARGSUSED */
690static void
691DlDrawRectangle(Widget w, XtPointer args, XtPointer data,
692		XEvent *event _X_UNUSED, Region region _X_UNUSED)
693{
694  Dl2Points(w, args, data, DRECT);
695}
696
697/* ARGSUSED */
698static void
699DlFillRectangle(Widget w, XtPointer args, XtPointer data,
700		XEvent *event _X_UNUSED, Region region _X_UNUSED)
701{
702  Dl2Points(w, args, data, FRECT);
703}
704
705static void
706DlXPoints(Widget w, XtPointer args, XtPointer data, int id)
707{
708  XawDLPositionPtr *pos_ptr = (XawDLPositionPtr *)args;
709  XawXlibData *xdata = (XawXlibData *)data;
710  XawDLPosition *pos;
711  XPoint points_buf[16];
712  XPoint *points;
713  Display *display;
714  Window window;
715  Cardinal num_points, i, j;
716
717  num_points = pos_ptr->num_pos>>1;
718  points = (XPoint *)XawStackAlloc(sizeof(XPoint) * num_points, points_buf);
719
720  for (i = j = 0; i < num_points; i++, j = i << 1)
721    {
722      pos = &pos_ptr->pos[j];
723      points[i].x = X_ARG(pos[0]);
724      points[i].y = Y_ARG(pos[1]);
725    }
726
727  if (!XtIsWidget(w))
728    {
729      Position xpad, ypad;
730
731      xpad = (Position)(XtX(w) + XtBorderWidth(w));
732      ypad = (Position)(XtY(w) + XtBorderWidth(w));
733      if (xdata->mode != CoordModePrevious)
734	{
735	  for (i = 0; i < num_points; i++)
736	    {
737	      points[i].x = (short)(points[i].x + xpad);
738	      points[i].y = (short)(points[i].y + ypad);
739	    }
740	}
741      else
742	{
743	  points[0].x = (short)(points[0].x + xpad);
744	  points[0].y = (short)(points[0].y + ypad);
745	}
746      display = XtDisplayOfObject(w);
747      window = XtWindowOfObject(w);
748    }
749  else
750    {
751      display = XtDisplay(w);
752      window = XtWindow(w);
753    }
754
755  if (id == FPOLY)
756    XFillPolygon(display, window, xdata->gc, points, (int)num_points,
757		 xdata->shape, xdata->mode);
758  else if (id == DLINES)
759    XDrawLines(display, window, xdata->gc, points, (int)num_points, xdata->mode);
760  else if (id == POINTS)
761    XDrawPoints(display, window, xdata->gc, points, (int)num_points, xdata->mode);
762
763  XawStackFree(points, points_buf);
764}
765
766/* ARGSUSED */
767static void
768DlFillPolygon(Widget w, XtPointer args, XtPointer data,
769	      XEvent *event _X_UNUSED, Region region _X_UNUSED)
770{
771  DlXPoints(w, args, data, FPOLY);
772}
773
774/* ARGSUSED */
775static void
776DlDrawLines(Widget w, XtPointer args, XtPointer data,
777	    XEvent *event _X_UNUSED, Region region _X_UNUSED)
778{
779  DlXPoints(w, args, data, DLINES);
780}
781
782/* ARGSUSED */
783static void
784DlDrawPoints(Widget w, XtPointer args, XtPointer data,
785	    XEvent *event _X_UNUSED, Region region _X_UNUSED)
786{
787  DlXPoints(w, args, data, POINTS);
788}
789
790/* ARGSUSED */
791static void
792DlForeground(Widget w, XtPointer args, XtPointer data,
793	     XEvent *event _X_UNUSED, Region region _X_UNUSED)
794{
795  XawXlibData *xdata = (XawXlibData *)data;
796  Pixel foreground = (Pixel)args;
797
798  if (xdata->values.foreground != foreground)
799    {
800      xdata->mask |= GCForeground;
801      xdata->values.foreground = foreground;
802      XSetForeground(XtDisplayOfObject(w), xdata->gc, foreground);
803    }
804}
805
806/* ARGSUSED */
807static void
808DlBackground(Widget w, XtPointer args, XtPointer data,
809	     XEvent *event _X_UNUSED, Region region _X_UNUSED)
810{
811  XawXlibData *xdata = (XawXlibData *)data;
812  Pixel background = (Pixel)args;
813
814  if (xdata->values.background != background)
815    {
816      xdata->mask |= GCBackground;
817      xdata->values.background = background;
818      XSetBackground(XtDisplayOfObject(w), xdata->gc, background);
819    }
820}
821
822static void
823DlArc(Widget w, XtPointer args, XtPointer data, Bool fill)
824{
825  XawXlibData *xdata = (XawXlibData *)data;
826  XawDLArcArgs *arc = (XawDLArcArgs *)args;
827  Position x1, y1, x2, y2;
828  Display *display;
829  Window window;
830
831  x1 = X_ARG(arc->pos[0]);
832  y1 = Y_ARG(arc->pos[1]);
833  x2 = X_ARG(arc->pos[2]);
834  y2 = Y_ARG(arc->pos[3]);
835
836  if (!XtIsWidget(w))
837    {
838      Position xpad, ypad;
839
840      xpad = (Position)(XtX(w) + XtBorderWidth(w));
841      ypad = (Position)(XtY(w) + XtBorderWidth(w));
842      x1 = (Position)(x1 + xpad);
843      y1 = (Position)(y1 + ypad);
844      x2 = (Position)(x2 + xpad);
845      y2 = (Position)(y2 + ypad);
846      display = XtDisplayOfObject(w);
847      window = XtWindowOfObject(w);
848    }
849  else
850    {
851      display = XtDisplay(w);
852      window = XtWindow(w);
853    }
854
855  if (fill)
856    XFillArc(display, window, xdata->gc, x1, y1, (unsigned)(x2 - x1), (unsigned)(y2 - y1),
857	     arc->angle1, arc->angle2);
858  else
859    XDrawArc(display, window, xdata->gc, x1, y1, (unsigned)(x2 - x1), (unsigned)(y2 - y1),
860	     arc->angle1, arc->angle2);
861}
862
863/* ARGSUSED */
864static void
865DlDrawArc(Widget w, XtPointer args, XtPointer data,
866	  XEvent *event _X_UNUSED, Region region _X_UNUSED)
867{
868  DlArc(w, args, data, False);
869}
870
871/* ARGSUSED */
872static void
873DlFillArc(Widget w, XtPointer args, XtPointer data,
874	  XEvent *event _X_UNUSED, Region region _X_UNUSED)
875{
876  DlArc(w, args, data, True);
877}
878
879/*ARGSUSED*/
880static void
881DlMask(Widget w, XtPointer args _X_UNUSED, XtPointer data,
882       XEvent *event, Region region)
883{
884  XawXlibData *xdata = (XawXlibData *)data;
885  Display *display = XtDisplayOfObject(w);
886
887  if (region)
888    XSetRegion(display, xdata->gc, region);
889  else if (event)
890    {
891      XRectangle rect;
892
893      rect.x = (short)event->xexpose.x;
894      rect.y = (short)event->xexpose.y;
895      rect.width = (unsigned short)event->xexpose.width;
896      rect.height = (unsigned short)event->xexpose.height;
897      XSetClipRectangles(display, xdata->gc, 0, 0, &rect, 1, Unsorted);
898    }
899}
900
901/* ARGSUSED */
902static void
903DlUmask(Widget w, XtPointer args _X_UNUSED, XtPointer data,
904	XEvent *event _X_UNUSED, Region region _X_UNUSED)
905{
906  XawXlibData *xdata = (XawXlibData *)data;
907
908  XSetClipMask(XtDisplayOfObject(w), xdata->gc, None);
909}
910
911/* ARGSUSED */
912static void
913DlLineWidth(Widget w, XtPointer args, XtPointer data,
914	    XEvent *event _X_UNUSED, Region region _X_UNUSED)
915{
916  XawXlibData *xdata = (XawXlibData *)data;
917  unsigned line_width = (unsigned)(unsigned long)args;
918
919  if (xdata->values.line_width != line_width)
920    {
921      xdata->mask |= GCLineWidth;
922      xdata->values.line_width = (int)line_width;
923      XChangeGC(XtDisplayOfObject(w), xdata->gc, GCLineWidth, &xdata->values);
924    }
925}
926
927/* ARGSUSED */
928static void
929DlDrawPoint(Widget w, XtPointer args, XtPointer data, XEvent *event _X_UNUSED, Region region _X_UNUSED)
930{
931  Dl1Point(w, args, data, POINT);
932}
933
934/* ARGSUSED */
935static void
936DlDrawSegments(Widget w, XtPointer args, XtPointer data,
937	       XEvent *event _X_UNUSED, Region region _X_UNUSED)
938{
939  XawDLPositionPtr *pos_ptr = (XawDLPositionPtr *)args;
940  XawXlibData *xdata = (XawXlibData *)data;
941  XawDLPosition *pos;
942  XSegment *segments;
943  XSegment segments_buf[8];
944  Display *display;
945  Window window;
946  Cardinal num_segments, i, j;
947
948  num_segments = pos_ptr->num_pos>>2;
949  segments = (XSegment *)XawStackAlloc(sizeof(XSegment) * num_segments, segments_buf);
950
951  for (i = j = 0; i < num_segments; i++, j = i << 2)
952    {
953      pos = &pos_ptr->pos[j];
954      segments[i].x1 = X_ARG(pos[0]);
955      segments[i].y1 = Y_ARG(pos[1]);
956      segments[i].x2 = X_ARG(pos[2]);
957      segments[i].y2 = Y_ARG(pos[3]);
958    }
959
960  if (!XtIsWidget(w))
961    {
962      Position xpad, ypad;
963
964      xpad = (Position)(XtX(w) + XtBorderWidth(w));
965      ypad = (Position)(XtY(w) + XtBorderWidth(w));
966      for (i = 0; i < num_segments; i++)
967	{
968	  segments[i].x1 = (short)(segments[i].x1 + xpad);
969	  segments[i].y1 = (short)(segments[i].y1 + ypad);
970	  segments[i].x2 = (short)(segments[i].x2 + xpad);
971	  segments[i].y2 = (short)(segments[i].y2 + ypad);
972	}
973      display = XtDisplayOfObject(w);
974      window = XtWindowOfObject(w);
975    }
976  else
977    {
978      display = XtDisplay(w);
979      window = XtWindow(w);
980    }
981
982  XDrawSegments(display, window, xdata->gc, segments, (int)num_segments);
983
984  XawStackFree(segments, segments_buf);
985}
986
987/* ARGSUSED */
988static void
989DlArcMode(Widget w, XtPointer args, XtPointer data,
990	  XEvent *event _X_UNUSED, Region region _X_UNUSED)
991{
992  XawXlibData *xdata = (XawXlibData *)data;
993  int arc_mode  = (int)(long)args;
994
995  if (xdata->values.arc_mode != arc_mode)
996    {
997      xdata->mask |= GCArcMode;
998      xdata->values.arc_mode = arc_mode;
999      XSetArcMode(XtDisplayOfObject(w), xdata->gc, arc_mode);
1000    }
1001}
1002
1003/* ARGSUSED */
1004static void
1005DlCoordMode(Widget w _X_UNUSED, XtPointer args, XtPointer data,
1006	    XEvent *event _X_UNUSED, Region region _X_UNUSED)
1007{
1008  XawXlibData *xdata = (XawXlibData *)data;
1009  int mode  = (int)(long)args;
1010
1011  xdata->mode = mode;
1012}
1013
1014/* ARGSUSED */
1015static void
1016DlShapeMode(Widget w _X_UNUSED, XtPointer args, XtPointer data,
1017	    XEvent *event _X_UNUSED, Region region _X_UNUSED)
1018{
1019  XawXlibData *xdata = (XawXlibData *)data;
1020  int shape  = (int)(long)args;
1021
1022  xdata->shape = shape;
1023}
1024
1025/* ARGSUSED */
1026static void
1027DlLineStyle(Widget w, XtPointer args, XtPointer data,
1028	    XEvent *event _X_UNUSED, Region region _X_UNUSED)
1029{
1030  XawXlibData *xdata = (XawXlibData *)data;
1031  int line_style = (int)(long)args;
1032
1033  if (xdata->values.line_style != line_style)
1034    {
1035      xdata->mask |= GCLineStyle;
1036      xdata->values.line_style = line_style;
1037      XChangeGC(XtDisplayOfObject(w), xdata->gc, GCLineStyle, &xdata->values);
1038    }
1039}
1040
1041/* ARGSUSED */
1042static void
1043DlCapStyle(Widget w, XtPointer args, XtPointer data,
1044	   XEvent *event _X_UNUSED, Region region _X_UNUSED)
1045{
1046  XawXlibData *xdata = (XawXlibData *)data;
1047  int cap_style = (int)(long)args;
1048
1049  if (xdata->values.cap_style != cap_style)
1050    {
1051      xdata->mask |= GCCapStyle;
1052      xdata->values.cap_style = cap_style;
1053      XChangeGC(XtDisplayOfObject(w), xdata->gc, GCCapStyle, &xdata->values);
1054    }
1055}
1056
1057/* ARGSUSED */
1058static void
1059DlJoinStyle(Widget w, XtPointer args, XtPointer data,
1060	    XEvent *event _X_UNUSED, Region region _X_UNUSED)
1061{
1062  XawXlibData *xdata = (XawXlibData *)data;
1063  int join_style = (int)(long)args;
1064
1065  if (xdata->values.join_style != join_style)
1066    {
1067      xdata->mask |= GCJoinStyle;
1068      xdata->values.join_style = join_style;
1069      XChangeGC(XtDisplayOfObject(w), xdata->gc, GCJoinStyle, &xdata->values);
1070    }
1071}
1072
1073/* ARGSUSED */
1074static void
1075DlFillStyle(Widget w, XtPointer args, XtPointer data,
1076	    XEvent *event _X_UNUSED, Region region _X_UNUSED)
1077{
1078  XawXlibData *xdata = (XawXlibData *)data;
1079  int fill_style = (int)(long)args;
1080
1081  if (xdata->values.fill_style != fill_style)
1082    {
1083      xdata->mask |= GCFillStyle;
1084      xdata->values.fill_style = fill_style;
1085      XSetFillStyle(XtDisplayOfObject(w), xdata->gc, fill_style);
1086    }
1087}
1088
1089/* ARGSUSED */
1090static void
1091DlFillRule(Widget w, XtPointer args, XtPointer data,
1092	   XEvent *event _X_UNUSED, Region region _X_UNUSED)
1093{
1094  XawXlibData *xdata = (XawXlibData *)data;
1095  int fill_rule = (int)(long)args;
1096
1097  if (xdata->values.fill_rule != fill_rule)
1098    {
1099      xdata->mask |= GCFillRule;
1100      xdata->values.fill_rule = fill_rule;
1101      XSetFillRule(XtDisplayOfObject(w), xdata->gc, fill_rule);
1102    }
1103}
1104
1105/* ARGSUSED */
1106static void
1107DlTile(Widget w, XtPointer args, XtPointer data,
1108       XEvent *event _X_UNUSED, Region region _X_UNUSED)
1109{
1110  XawXlibData *xdata = (XawXlibData *)data;
1111  XawPixmap *pixmap = (XawPixmap *)args;
1112
1113  if (pixmap && xdata->values.tile != pixmap->pixmap)
1114    {
1115      xdata->mask |= GCTile;
1116      xdata->values.tile = pixmap->pixmap;
1117      XSetTile(XtDisplayOfObject(w), xdata->gc, xdata->values.tile);
1118    }
1119}
1120
1121/* ARGSUSED */
1122static void
1123DlStipple(Widget w, XtPointer args, XtPointer data,
1124	  XEvent *event _X_UNUSED, Region region _X_UNUSED)
1125{
1126  XawXlibData *xdata = (XawXlibData *)data;
1127  XawPixmap *pixmap = (XawPixmap *)args;
1128
1129  if (pixmap && xdata->values.stipple != pixmap->pixmap)
1130    {
1131      xdata->mask |= GCStipple;
1132      xdata->values.stipple = pixmap->pixmap;
1133      XSetStipple(XtDisplayOfObject(w), xdata->gc, xdata->values.stipple);
1134    }
1135}
1136
1137/* ARGSUSED */
1138static void
1139DlTSOrigin(Widget w, XtPointer args, XtPointer data, XEvent *event _X_UNUSED, Region region _X_UNUSED)
1140{
1141  Dl1Point(w, args, data, TSORIGIN);
1142}
1143
1144/* ARGSUSED */
1145static void
1146DlFunction(Widget w, XtPointer args, XtPointer data,
1147	   XEvent *event _X_UNUSED, Region region _X_UNUSED)
1148{
1149  XawXlibData *xdata = (XawXlibData *)data;
1150  int function = (int)(long)args;
1151
1152  if (function != xdata->values.function)
1153    {
1154      xdata->mask |= GCFunction;
1155      xdata->values.function = function;
1156      XSetFunction(XtDisplayOfObject(w), xdata->gc, function);
1157    }
1158}
1159
1160/* ARGSUSED */
1161static void
1162DlPlaneMask(Widget w, XtPointer args, XtPointer data,
1163	    XEvent *event _X_UNUSED, Region region _X_UNUSED)
1164{
1165  XawXlibData *xdata = (XawXlibData *)data;
1166  unsigned long plane_mask = (unsigned long)args;
1167
1168  if (xdata->values.plane_mask != plane_mask)
1169    {
1170      xdata->mask |= GCPlaneMask;
1171      xdata->values.plane_mask = plane_mask;
1172      XSetPlaneMask(XtDisplayOfObject(w), xdata->gc, plane_mask);
1173    }
1174}
1175
1176static void
1177DlString(Widget w, XtPointer args, XtPointer data, Bool image)
1178{
1179  XawDLStringArgs *string = (XawDLStringArgs *)args;
1180  XawXlibData *xdata = (XawXlibData *)data;
1181  Display *display;
1182  Window window;
1183  Position x, y;
1184
1185  x = (Position)(X_ARG(string->pos[0]));
1186  y = (Position)(Y_ARG(string->pos[1]));
1187
1188  if (!XtIsWidget(w))
1189    {
1190      Position xpad, ypad;
1191
1192      xpad = (Position)(XtX(w) + XtBorderWidth(w));
1193      ypad = (Position)(XtY(w) + XtBorderWidth(w));
1194      x = (Position)(x + xpad);
1195      y = (Position)(y + ypad);
1196      display = XtDisplayOfObject(w);
1197      window = XtWindowOfObject(w);
1198    }
1199  else
1200    {
1201      display = XtDisplay(w);
1202      window = XtWindow(w);
1203    }
1204
1205  if (image)
1206    XDrawImageString(display, window, xdata->gc, x, y, string->string, string->length);
1207  else
1208    XDrawString(display, window, xdata->gc, x, y, string->string, string->length);
1209}
1210
1211/* ARGSUSED */
1212static void
1213DlDrawString(Widget w, XtPointer args, XtPointer data,
1214	     XEvent *event _X_UNUSED, Region region _X_UNUSED)
1215{
1216  DlString(w, args, data, False);
1217}
1218
1219/* ARGSUSED */
1220static void
1221DlPaintString(Widget w, XtPointer args, XtPointer data,
1222	      XEvent *event _X_UNUSED, Region region _X_UNUSED)
1223{
1224  DlString(w, args, data, True);
1225}
1226
1227/* ARGSUSED */
1228static void
1229DlFont(Widget w, XtPointer args, XtPointer data,
1230       XEvent *event _X_UNUSED, Region region _X_UNUSED)
1231{
1232  XawXlibData *xdata = (XawXlibData *)data;
1233  Font font = (Font)args;
1234
1235  if (xdata->values.font != font)
1236    {
1237      xdata->mask |= GCFont;
1238      xdata->values.font = font;
1239      XSetFont(XtDisplayOfObject(w), xdata->gc, font);
1240    }
1241}
1242
1243/* ARGSUSED */
1244static void
1245DlDashes(Widget w, XtPointer args, XtPointer data,
1246	 XEvent *event _X_UNUSED, Region region _X_UNUSED)
1247{
1248  XawXlibData *xdata = (XawXlibData *)data;
1249  char *dashes = args;
1250
1251  if (xdata->dashes != dashes)
1252    {
1253      xdata->mask |= GCDashOffset | GCDashList;
1254      xdata->dashes = dashes;
1255      XSetDashes(XtDisplayOfObject(w), xdata->gc, 0, dashes + 1, *dashes);
1256    }
1257}
1258
1259/* ARGSUSED */
1260static void
1261DlSubwindowMode(Widget w, XtPointer args, XtPointer data,
1262		XEvent *event _X_UNUSED, Region region _X_UNUSED)
1263{
1264  XawXlibData *xdata = (XawXlibData *)data;
1265  int subwindow_mode = (int)(long)args;
1266
1267  if (xdata->values.subwindow_mode != subwindow_mode)
1268    {
1269      xdata->mask |= GCSubwindowMode;
1270      xdata->values.subwindow_mode = subwindow_mode;
1271      XSetSubwindowMode(XtDisplayOfObject(w), xdata->gc, subwindow_mode);
1272    }
1273}
1274
1275/* ARGSUSED */
1276static void
1277DlExposures(Widget w, XtPointer args, XtPointer data,
1278	    XEvent *event _X_UNUSED, Region region _X_UNUSED)
1279{
1280  XawXlibData *xdata = (XawXlibData *)data;
1281  Bool graphics_exposures = (Bool)(long)args;
1282
1283  if (xdata->values.graphics_exposures != graphics_exposures)
1284    {
1285      xdata->mask |= GCGraphicsExposures;
1286      xdata->values.graphics_exposures = graphics_exposures;
1287      XSetGraphicsExposures(XtDisplayOfObject(w), xdata->gc, graphics_exposures);
1288    }
1289}
1290
1291/* ARGSUSED */
1292static void
1293DlClipOrigin(Widget w, XtPointer args, XtPointer data, XEvent *event _X_UNUSED, Region region _X_UNUSED)
1294{
1295  Dl1Point(w, args, data, CLIPORIGIN);
1296}
1297
1298/* ARGSUSED */
1299static void
1300DlClipMask(Widget w, XtPointer args, XtPointer data,
1301	   XEvent *event _X_UNUSED, Region region _X_UNUSED)
1302{
1303  XawXlibData *xdata = (XawXlibData *)data;
1304  XawPixmap *pixmap = (XawPixmap *)args;
1305  Pixmap clip_mask;
1306
1307  if (pixmap)
1308    clip_mask = pixmap->mask ? pixmap->mask : pixmap->pixmap;
1309  else
1310    clip_mask = None;
1311
1312  if (xdata->values.clip_mask != clip_mask)
1313    {
1314      xdata->mask |= GCClipMask;
1315      XSetClipMask(XtDisplayOfObject(w), xdata->gc, clip_mask);
1316    }
1317}
1318
1319/* ARGSUSED */
1320static void
1321DlClipRectangles(Widget w, XtPointer args, XtPointer data,
1322		 XEvent *event _X_UNUSED, Region region _X_UNUSED)
1323{
1324  XawDLPositionPtr *pos_ptr = (XawDLPositionPtr *)args;
1325  XawXlibData *xdata = (XawXlibData *)data;
1326  XawDLPosition *pos;
1327  XRectangle *rects;
1328  XRectangle rects_buf[8];
1329  Position x1, y1, x2, y2;
1330  Cardinal num_rects, i, j;
1331
1332  num_rects = pos_ptr->num_pos>>2;
1333  rects = (XRectangle *)XawStackAlloc(sizeof(XRectangle) * num_rects, rects_buf);
1334
1335  for (i = j = 0; i < num_rects; i++, j = i << 2)
1336    {
1337      pos = &pos_ptr->pos[j];
1338      x1 = X_ARG(pos[0]);
1339      y1 = Y_ARG(pos[1]);
1340      x2 = X_ARG(pos[2]);
1341      y2 = Y_ARG(pos[3]);
1342      rects[i].x = XawMin(x1, x2);
1343      rects[i].y = XawMin(y1, y2);
1344      rects[i].width = (unsigned short)(XawMax(x1, x2) - rects[i].x);
1345      rects[i].height = (unsigned short)(XawMax(y1, y2) - rects[i].y);
1346    }
1347
1348  if (!XtIsWidget(w))
1349    {
1350      Position xpad, ypad;
1351
1352      xpad = (Position)(XtX(w) + XtBorderWidth(w));
1353      ypad = (Position)(XtY(w) + XtBorderWidth(w));
1354      for (i = 0; i < num_rects; i++)
1355	{
1356	  rects[i].x = (short)(rects[i].x + xpad);
1357	  rects[i].y = (short)(rects[i].y + ypad);
1358	}
1359    }
1360
1361  XSetClipRectangles(XtDisplayOfObject(w), xdata->gc, 0, 0, rects, (int)num_rects, Unsorted);
1362
1363  XawStackFree(rects, rects_buf);
1364}
1365
1366static void
1367DlCopy(Widget w, XtPointer args, XtPointer data, Bool plane)
1368{
1369  XawDLCopyArgs *copy = (XawDLCopyArgs *)args;
1370  XawXlibData *xdata = (XawXlibData *)data;
1371  int src_x, src_y, dst_x, dst_y, width, height, tmp1, tmp2;
1372
1373  tmp1 = X_ARG(copy->pos[0]);
1374  tmp2 = X_ARG(copy->pos[2]);
1375  dst_x = XawMin(tmp1, tmp2);
1376  width = XawMax(tmp1, tmp2) - dst_x;
1377
1378  tmp1 = Y_ARG(copy->pos[1]);
1379  tmp2 = Y_ARG(copy->pos[3]);
1380  dst_y = XawMin(tmp1, tmp2);
1381  height = XawMax(tmp1, tmp2) - dst_y;
1382
1383  src_x = X_ARG(copy->pos[4]);
1384  src_y = Y_ARG(copy->pos[5]);
1385
1386  if (width <= 0)
1387    {
1388      if (copy->pixmap)
1389	width = copy->pixmap->width;
1390      else
1391	{
1392	  if ((width = XtWidth(w) - src_x) < 0)
1393	    width = 0;
1394	}
1395    }
1396  if (height <= 0)
1397    {
1398      if (copy->pixmap)
1399	height = copy->pixmap->height;
1400      else
1401	{
1402	  if ((height = XtHeight(w) - src_y) < 0)
1403	    height = 0;
1404	}
1405    }
1406
1407  if (!XtIsWidget(w))
1408    {
1409      Position xpad, ypad;
1410
1411      xpad = (Position)(XtX(w) + XtBorderWidth(w));
1412      ypad = (Position)(XtY(w) + XtBorderWidth(w));
1413      src_x += xpad;
1414      src_y += ypad;
1415      dst_x += xpad;
1416      dst_y += ypad;
1417    }
1418
1419  if (plane)
1420    XCopyPlane(XtDisplayOfObject(w), XtWindowOfObject(w),
1421	       copy->pixmap ? copy->pixmap->pixmap : XtWindowOfObject(w),
1422	       xdata->gc, src_x, src_y, (unsigned)width, (unsigned)height, dst_x, dst_y,
1423	       (unsigned long)(copy->plane ? copy->plane : 1));
1424  else
1425    XCopyArea(XtDisplayOfObject(w),
1426	      copy->pixmap ? copy->pixmap->pixmap : XtWindowOfObject(w),
1427	      XtWindowOfObject(w), xdata->gc, src_x, src_y, (unsigned)width, (unsigned)height, dst_x, dst_y);
1428}
1429
1430/* ARGSUSED */
1431static void
1432DlCopyArea(Widget w, XtPointer args, XtPointer data,
1433	   XEvent *event _X_UNUSED, Region region _X_UNUSED)
1434{
1435  DlCopy(w, args, data, False);
1436}
1437
1438/* ARGSUSED */
1439static void
1440DlCopyPlane(Widget w, XtPointer args, XtPointer data,
1441	    XEvent *event _X_UNUSED, Region region _X_UNUSED)
1442{
1443  DlCopy(w, args, data, True);
1444}
1445
1446/*ARGSUSED*/
1447/* Note:
1448 *	  This function is destructive if you set the ts_x_origin, ts_y_origin,
1449 *	and/or clip-mask. It is meant to be the only function used in a display
1450 *	list. If you need to use other functions (and those values), be sure to
1451 *	set them after calling this function.
1452 */
1453static void
1454DlImage(Widget w, XtPointer args, XtPointer data, XEvent *event _X_UNUSED, Region region _X_UNUSED)
1455{
1456  XawDLImageArgs *image = (XawDLImageArgs *)args;
1457  XawXlibData *xdata = (XawXlibData *)data;
1458  int x, y, xs, ys, xe, ye, width, height;
1459  Display *display;
1460  Window window;
1461
1462  width = image->pixmap->width;
1463  height = image->pixmap->height;
1464  xs = X_ARG(image->pos[0]);
1465  ys = Y_ARG(image->pos[1]);
1466  xe = X_ARG(image->pos[2]);
1467  ye = Y_ARG(image->pos[3]);
1468
1469  if (xe <= 0)
1470    xe = xs + width;
1471  if (ye <= 0)
1472    ye = ys + height;
1473
1474  if (!XtIsWidget(w))
1475    {
1476      Position xpad, ypad;
1477
1478      xpad = (Position)(XtX(w) + XtBorderWidth(w));
1479      ypad = (Position)(XtY(w) + XtBorderWidth(w));
1480      xe += xpad;
1481      ye += ypad;
1482      xe += xpad;
1483      ye += ypad;
1484      display = XtDisplayOfObject(w);
1485      window = XtWindowOfObject(w);
1486    }
1487  else
1488    {
1489      display = XtDisplay(w);
1490      window = XtWindow(w);
1491    }
1492
1493  for (y = ys; y < ye; y += height)
1494    for (x = xs; x < xe; x += width)
1495      {
1496	XSetClipOrigin(display, xdata->gc, x, y);
1497	if (image->pixmap->mask)
1498	  XSetClipMask(display, xdata->gc, image->pixmap->mask);
1499	if (image->depth == 1)
1500	  XCopyPlane(display, image->pixmap->pixmap, window, xdata->gc,
1501		     0, 0, (unsigned)XawMin(width, xe - x), (unsigned)XawMin(height, ye - y),
1502		     x, y, 1L);
1503	else
1504	  XCopyArea(display, image->pixmap->pixmap, window, xdata->gc, 0, 0,
1505		     (unsigned)XawMin(width, xe - x), (unsigned)XawMin(height, ye - y), x, y);
1506      }
1507
1508  XSetClipMask(display, xdata->gc, None);
1509}
1510
1511typedef struct _Dl_init Dl_init;
1512struct _Dl_init {
1513  String name;
1514  XawDisplayListProc proc;
1515  Cardinal id;
1516};
1517
1518static Dl_init dl_init[] =
1519{
1520  {"arc-mode",		DlArcMode,		ARCMODE},
1521  {"background",	DlBackground,		GCBG},
1522  {"bg",		DlBackground,		GCBG},
1523  {"cap-style",		DlCapStyle,		CAPSTYLE},
1524  {"clip-mask",		DlClipMask,		CLIPMASK},
1525  {"clip-origin",	DlClipOrigin,		CLIPORIGIN},
1526  {"clip-rectangles",	DlClipRectangles,	CLIPRECTS},
1527  {"clip-rects",	DlClipRectangles,	CLIPRECTS},
1528  {"coord-mode",	DlCoordMode,		COORDMODE},
1529  {"copy-area",		DlCopyArea,		COPYAREA},
1530  {"copy-plane",	DlCopyPlane,		COPYPLANE},
1531  {"dashes",		DlDashes,		DASHES},
1532  {"draw-arc",		DlDrawArc,		DARC},
1533  {"draw-line",		DlLine,			LINE},
1534  {"draw-lines",	DlDrawLines,		DLINES},
1535  {"draw-point",	DlDrawPoint,		POINT},
1536  {"draw-points",	DlDrawPoints,		POINTS},
1537  {"draw-rect",		DlDrawRectangle,	DRECT},
1538  {"draw-rectangle",	DlDrawRectangle,	DRECT},
1539  {"draw-segments",	DlDrawSegments,		SEGMENTS},
1540  {"draw-string",	DlDrawString,		DSTRING},
1541  {"exposures",		DlExposures,		EXPOSURES},
1542  {"fg",		DlForeground,		GCFG},
1543  {"fill-arc",		DlFillArc,		FARC},
1544  {"fill-poly",		DlFillPolygon,		FPOLY},
1545  {"fill-polygon",	DlFillPolygon,		FPOLY},
1546  {"fill-rect",		DlFillRectangle,	FRECT},
1547  {"fill-rectangle",	DlFillRectangle,	FRECT},
1548  {"fill-rule",		DlFillRule,		FILLRULE},
1549  {"fill-style",	DlFillStyle,		FILLSTYLE},
1550  {"font",		DlFont,			FONT},
1551  {"foreground",	DlForeground,		GCFG},
1552  {"function",		DlFunction,		FUNCTION},
1553  {"image",		DlImage,		IMAGE},
1554  {"join-style",	DlJoinStyle,		JOINSTYLE},
1555  {"line",		DlLine,			LINE},
1556  {"line-style",	DlLineStyle,		LINESTYLE},
1557  {"line-width",	DlLineWidth,		LWIDTH},
1558  {"lines",		DlDrawLines,		DLINES},
1559  {"mask",		DlMask,			MASK},
1560  {"paint-string",	DlPaintString,		PSTRING},
1561  {"plane-mask",	DlPlaneMask,		PLANEMASK},
1562  {"point",		DlDrawPoint,		POINT},
1563  {"points",		DlDrawPoints,		POINTS},
1564  {"segments",		DlDrawSegments,		SEGMENTS},
1565  {"shape-mode",	DlShapeMode,		SHAPEMODE},
1566  {"stipple",		DlStipple,		STIPPLE},
1567  {"subwindow-mode",	DlSubwindowMode,	SUBWMODE},
1568  {"tile",		DlTile,			TILE},
1569  {"ts-origin",		DlTSOrigin,		TSORIGIN},
1570  {"umask",		DlUmask,		UMASK},
1571};
1572
1573void
1574XawDisplayListInitialize(void)
1575{
1576  static Bool first_time = True;
1577  XawDLClass *lc;
1578  Cardinal i;
1579
1580  if (first_time == False)
1581    return;
1582
1583  first_time = False;
1584
1585  lc = XawCreateDisplayListClass(xlib,
1586				 _Xaw_Xlib_ArgsInitProc,
1587				 _Xaw_Xlib_ArgsDestructor,
1588				 _Xaw_Xlib_DataInitProc,
1589				 _Xaw_Xlib_DataDestructor);
1590  for (i = 0; i < sizeof(dl_init) / sizeof(dl_init[0]); i++)
1591    (void)XawDeclareDisplayListProc(lc, dl_init[i].name, dl_init[i].proc);
1592}
1593
1594static int
1595bcmp_cvt_proc(register _Xconst void *string,
1596	      register _Xconst void *dlinfo)
1597{
1598  return (strcmp((String)string, ((Dl_init*)dlinfo)->name));
1599}
1600
1601static long
1602read_int(char *cp, char **cpp)
1603{
1604  long value = 0, sign = 1;
1605
1606  if (*cp == '-')
1607    {
1608      sign = -1;
1609      ++cp;
1610    }
1611  else if (*cp == '+')
1612    ++cp;
1613  value = 0;
1614  while (*cp >= '0' && *cp <= '9')
1615    {
1616      value = value * 10 + *cp - '0';
1617      ++cp;
1618    }
1619  if (cpp)
1620    *cpp = cp;
1621  return (value * sign);
1622}
1623
1624static void
1625read_position(char *arg, XawDLPosition *pos)
1626{
1627  int ch;
1628  char *str = arg;
1629
1630  ch = *str;
1631  if (ch == '-' || ch == '+')
1632    {
1633      ++str;
1634      if (ch == '-')
1635	pos->high = True;
1636      pos->pos = (Position)read_int(str, NULL);
1637    }
1638  else if (isdigit(ch))
1639    {
1640      pos->pos = (Position)read_int(str, &str);
1641      ch = *str++;
1642      if (ch == '/')
1643	pos->denom = (Position)read_int(str, NULL);
1644    }
1645}
1646
1647/* ARGSUSED */
1648static void *
1649_Xaw_Xlib_ArgsInitProc(String proc_name, String *params, Cardinal *num_params,
1650		       Screen *screen, Colormap colormap, int depth)
1651{
1652  Cardinal id, i;
1653  Dl_init *init;
1654  void *retval = XAWDL_CONVERT_ERROR;
1655
1656  init = (Dl_init *)bsearch(proc_name, dl_init,
1657			    sizeof(dl_init) / sizeof(dl_init[0]),
1658			    sizeof(dl_init[0]),
1659			    bcmp_cvt_proc);
1660
1661  id = init->id;
1662
1663  switch (id)
1664    {
1665    case LINE:
1666    case DRECT:
1667    case FRECT:
1668      if (*num_params == 4)
1669	{
1670	  XawDLPosition *pos = (XawDLPosition *)XtCalloc(1, sizeof(XawDLPosition) * 4);
1671
1672	  for (i = 0; i < 4; i++)
1673	    read_position((char *)params[i], &pos[i]);
1674	  retval = (void *)pos;
1675	}
1676      break;
1677    case POINT:
1678    case TSORIGIN:
1679    case CLIPORIGIN:
1680      if (*num_params == 2)
1681	{
1682	  XawDLPosition *pos = (XawDLPosition *)XtCalloc(1, sizeof(XawDLPosition) * 2);
1683
1684	  read_position((char *)params[0], &pos[0]);
1685	  read_position((char *)params[1], &pos[1]);
1686	  retval = (void *)pos;
1687	}
1688      break;
1689    case DLINES:
1690    case FPOLY:
1691    case POINTS:
1692      if (*num_params >= 4 && !(*num_params & 1))
1693	{
1694	  XawDLPositionPtr *pos = XtNew(XawDLPositionPtr);
1695
1696	  pos->pos = (XawDLPosition *)XtCalloc(1, (Cardinal)(sizeof(XawDLPosition) *
1697					       (size_t)*num_params));
1698	  pos->num_pos = *num_params;
1699	  for (i = 0; i < *num_params; i++)
1700	    read_position((char *)params[i], &pos->pos[i]);
1701	  retval = (void *)pos;
1702	}
1703      break;
1704    case SEGMENTS:
1705    case CLIPRECTS:
1706      if (*num_params >= 4 && !(*num_params % 4))
1707	{
1708	  XawDLPositionPtr *pos = XtNew(XawDLPositionPtr);
1709
1710	  pos->pos = (XawDLPosition *)XtCalloc(1, (Cardinal)(sizeof(XawDLPosition) *
1711					       (size_t)*num_params));
1712	  pos->num_pos = *num_params;
1713	  for (i = 0; i < *num_params; i++)
1714	    read_position((char *)params[i], &pos->pos[i]);
1715	  retval = (void *)pos;
1716	}
1717      break;
1718    case DARC:
1719    case FARC:
1720      if (*num_params >= 4 && *num_params <= 6)
1721	{
1722	  XawDLArcArgs *args = (XawDLArcArgs *)XtCalloc(1, sizeof(XawDLArcArgs));
1723
1724	  args->angle1 = 0;
1725	  args->angle2 = 360;
1726	  for (i = 0; i < 4; i++)
1727	    read_position((char *)params[i], &args->pos[i]);
1728	  if (*num_params > 4)
1729	    args->angle1 = (int)read_int((char *)params[4], NULL);
1730	  if (*num_params > 5)
1731	    args->angle2 = (int)read_int((char *)params[5], NULL);
1732	  args->angle1 *= 64;
1733	  args->angle2 *= 64;
1734	  retval = (void *)args;
1735	}
1736      break;
1737    case GCFG:
1738    case GCBG:
1739      {
1740	XColor xcolor;
1741
1742	if (*num_params == 1 &&
1743	    XAllocNamedColor(DisplayOfScreen(screen), colormap,
1744			     params[0], &xcolor, &xcolor))
1745	  retval = (void *)xcolor.pixel;
1746      } break;
1747    case MASK:
1748    case UMASK:
1749      if (*num_params == 0)
1750	retval = NULL;
1751      break;
1752    case LWIDTH:
1753      if (*num_params == 1)
1754	retval = (void *)read_int((char *)params[0], NULL);
1755      break;
1756    case ARCMODE:
1757      if (*num_params == 1)
1758	{
1759	  if (XmuCompareISOLatin1(params[0], "pieslice") == 0)
1760	    retval = (void *)ArcPieSlice;
1761	  else if (XmuCompareISOLatin1(params[0], "chord") == 0)
1762	    retval = (void *)ArcChord;
1763	}
1764      break;
1765    case COORDMODE:
1766      if (*num_params == 1)
1767	{
1768	  if (XmuCompareISOLatin1(params[0], "origin") == 0)
1769	    retval = (void *)CoordModeOrigin;
1770	  else if (XmuCompareISOLatin1(params[0], "previous") == 0)
1771	    retval = (void *)CoordModePrevious;
1772	}
1773      break;
1774    case SHAPEMODE:
1775      if (*num_params == 1)
1776	{
1777	  if (XmuCompareISOLatin1(params[0], "complex") == 0)
1778	    retval = (void *)Complex;
1779	  else if (XmuCompareISOLatin1(params[0], "convex") == 0)
1780	    retval = (void *)Convex;
1781	  else if (XmuCompareISOLatin1(params[0], "nonconvex") == 0)
1782	    retval = (void *)Nonconvex;
1783	}
1784      break;
1785    case LINESTYLE:
1786      if (*num_params == 1)
1787	{
1788	  if (XmuCompareISOLatin1(params[0], "solid") == 0)
1789	    retval = (void *)LineSolid;
1790	  else if (XmuCompareISOLatin1(params[0], "onoffdash") == 0)
1791	    retval = (void *)LineOnOffDash;
1792	  else if (XmuCompareISOLatin1(params[0], "doubledash") == 0)
1793	    retval = (void *)LineDoubleDash;
1794	}
1795      break;
1796    case CAPSTYLE:
1797      if (*num_params == 1)
1798	{
1799	  if (XmuCompareISOLatin1(params[0], "notlast") == 0)
1800	    retval = (void *)CapNotLast;
1801	  else if (XmuCompareISOLatin1(params[0], "butt") == 0)
1802	    retval = (void *)CapButt;
1803	  else if (XmuCompareISOLatin1(params[0], "round") == 0)
1804	    retval = (void *)CapRound;
1805	  else if (XmuCompareISOLatin1(params[0], "projecting") == 0)
1806	    retval = (void *)CapProjecting;
1807	}
1808      break;
1809    case JOINSTYLE:
1810      if (*num_params == 1)
1811	{
1812	  if (XmuCompareISOLatin1(params[0], "miter") == 0)
1813	    retval = (void *)JoinMiter;
1814	  else if (XmuCompareISOLatin1(params[0], "round") == 0)
1815	    retval = (void *)JoinRound;
1816	  else if (XmuCompareISOLatin1(params[0], "bevel") == 0)
1817	    retval = (void *)JoinBevel;
1818	}
1819      break;
1820    case FILLSTYLE:
1821      if (*num_params == 1)
1822	{
1823	  if (*num_params && XmuCompareISOLatin1(params[0], "solid") == 0)
1824	    retval = (void *)FillSolid;
1825	  else if (*num_params && XmuCompareISOLatin1(params[0], "tiled") == 0)
1826	    retval = (void *)FillTiled;
1827	  else if (*num_params && XmuCompareISOLatin1(params[0], "stippled") == 0)
1828	    retval = (void *)FillStippled;
1829	  else if (*num_params && XmuCompareISOLatin1(params[0], "opaquestippled") == 0)
1830	    retval = (void *)FillOpaqueStippled;
1831	}
1832      break;
1833    case FILLRULE:
1834      if (*num_params == 1)
1835	{
1836	  if (XmuCompareISOLatin1(params[0], "evenodd") == 0)
1837	    retval = (void *)EvenOddRule;
1838	  else if (XmuCompareISOLatin1(params[0], "winding") == 0)
1839	    retval = (void *)WindingRule;
1840	}
1841      break;
1842    case TILE:
1843      if (*num_params == 1)
1844	retval = (void *)XawLoadPixmap(params[0], screen, colormap, depth);
1845      if (retval == NULL)
1846	{
1847	  XtDisplayStringConversionWarning(DisplayOfScreen(screen), (String)params[0],
1848					   XtRPixmap);
1849	  retval = XAWDL_CONVERT_ERROR;
1850	}
1851      break;
1852    case STIPPLE:
1853      if (*num_params == 1)
1854	retval = (void *)XawLoadPixmap(params[0], screen, colormap, 1);
1855      if (retval == NULL)
1856	{
1857	  XtDisplayStringConversionWarning(DisplayOfScreen(screen), (String)params[0],
1858					   XtRBitmap);
1859	  retval = XAWDL_CONVERT_ERROR;
1860	}
1861      break;
1862    case FUNCTION:
1863      if (*num_params == 1)
1864	{
1865	  if (XmuCompareISOLatin1(params[0], "set") == 0)
1866	    retval = (void *)GXset;
1867	  else if (XmuCompareISOLatin1(params[0], "clear") == 0)
1868	    retval = (void *)GXclear;
1869	  else if (XmuCompareISOLatin1(params[0], "and") == 0)
1870	    retval = (void *)GXand;
1871	  else if (XmuCompareISOLatin1(params[0], "andreverse") == 0)
1872	    retval = (void *)GXandReverse;
1873	  else if (XmuCompareISOLatin1(params[0], "copy") == 0)
1874	    retval = (void *)GXcopy;
1875	  else if (XmuCompareISOLatin1(params[0], "andinverted") == 0)
1876	    retval = (void *)GXandInverted;
1877	  else if (XmuCompareISOLatin1(params[0], "noop") == 0)
1878	    retval = (void *)GXnoop;
1879	  else if (XmuCompareISOLatin1(params[0], "xor") == 0)
1880	    retval = (void *)GXxor;
1881	  else if (XmuCompareISOLatin1(params[0], "or") == 0)
1882	    retval = (void *)GXor;
1883	  else if (XmuCompareISOLatin1(params[0], "nor") == 0)
1884	    retval = (void *)GXnor;
1885	  else if (XmuCompareISOLatin1(params[0], "equiv") == 0)
1886	    retval = (void *)GXequiv;
1887	  else if (XmuCompareISOLatin1(params[0], "invert") == 0)
1888	    retval = (void *)GXinvert;
1889	  else if (XmuCompareISOLatin1(params[0], "orreverse") == 0)
1890	    retval = (void *)GXorReverse;
1891	  else if (XmuCompareISOLatin1(params[0], "copyinverted") == 0)
1892	    retval = (void *)GXcopyInverted;
1893	  else if (XmuCompareISOLatin1(params[0], "nand") == 0)
1894	    retval = (void *)GXnand;
1895	}
1896      break;
1897    case PLANEMASK:
1898      if (*num_params == 1)
1899	retval = (void *)read_int((char *)params[0], NULL);
1900      break;
1901    case DSTRING:
1902    case PSTRING:
1903      if (*num_params == 3)
1904	{
1905	  XawDLStringArgs *string = (XawDLStringArgs *)
1906		XtCalloc(1, sizeof(XawDLStringArgs));
1907
1908	  read_position((char *)params[0], &string->pos[0]);
1909	  read_position((char *)params[1], &string->pos[1]);
1910	  string->string = XtNewString(params[2]);
1911	  string->length = (int)strlen(string->string);
1912	  retval = string;
1913	}
1914      break;
1915    case FONT:
1916      if (*num_params == 1)
1917	retval = (void *)XLoadFont(DisplayOfScreen(screen), params[0]);
1918      break;
1919    case DASHES:
1920      if (*num_params && *num_params < 127)
1921	{
1922	  char *dashes;
1923
1924	  dashes = XtMalloc(*num_params + 1);
1925
1926	  for (i = 0; i < *num_params; i++)
1927	    dashes[i + 1] = (char)read_int((char *)params[i], NULL);
1928	  *dashes = (char)*num_params;
1929	  retval = dashes;
1930	}
1931      break;
1932    case SUBWMODE:
1933      if (*num_params == 1)
1934	{
1935	  if (XmuCompareISOLatin1(params[0], "clipbychildren") == 0)
1936	    retval = (void *)ClipByChildren;
1937	  else if (XmuCompareISOLatin1(params[0], "includeinferiors") == 0)
1938	    retval = (void *)IncludeInferiors;
1939	}
1940      break;
1941    case EXPOSURES:
1942      if (*num_params == 1)
1943	{
1944	  if (isdigit(params[0][0]) || params[0][0] == '+' || params[0][0] == '-')
1945	    retval = (void *)read_int((char *)params[0], NULL);
1946	  else if (XmuCompareISOLatin1(params[0], "true") == 0 ||
1947	    XmuCompareISOLatin1(params[0], "on") == 0)
1948	    retval = (void *)True;
1949	  else if (XmuCompareISOLatin1(params[0], "false") == 0 ||
1950	    XmuCompareISOLatin1(params[0], "off") == 0)
1951	    retval = (void *)False;
1952	}
1953      break;
1954    case CLIPMASK:
1955      if (*num_params == 1)
1956	retval = (void *)XawLoadPixmap(params[0], screen, colormap, 1);
1957      if (retval == NULL)
1958	{
1959	  retval = XAWDL_CONVERT_ERROR;
1960	  XtDisplayStringConversionWarning(DisplayOfScreen(screen), (String)params[0],
1961					   XtRPixmap);
1962	}
1963      break;
1964    case COPYAREA:
1965    case COPYPLANE:
1966      if (*num_params > 2 && *num_params <= 7 + (id == COPYPLANE))
1967	{
1968	  XawDLCopyArgs *args = (XawDLCopyArgs *)
1969		XtCalloc(1, sizeof(XawDLCopyArgs));
1970
1971	  retval = args;
1972	  if (params[0][0] == '\0' || strcmp(params[0], ".") == 0)
1973	    args->pixmap = NULL;
1974	  else
1975	   {
1976	     args->pixmap = XawLoadPixmap(params[0], screen, colormap, id == COPYPLANE ? 1 : depth);
1977	     if (args->pixmap == NULL)
1978	      {
1979		XtDisplayStringConversionWarning(DisplayOfScreen(screen), (String)params[0],
1980						 XtRBitmap);
1981		retval = XAWDL_CONVERT_ERROR;
1982		XtFree((char *)args);
1983	      }
1984	  }
1985	  if (retval != XAWDL_CONVERT_ERROR)
1986	    {
1987	      for (i = 1; i < *num_params && i < 7; i++)
1988		read_position((char *)params[i], &args->pos[i - 1]);
1989	      if (*num_params > 7)
1990		args->plane = (int)read_int((char *)params[7], NULL);
1991	    }
1992	}
1993      break;
1994    case IMAGE:
1995      if (*num_params > 2 && *num_params <= 7)
1996	{
1997	  XawDLImageArgs *args = (XawDLImageArgs *)
1998		XtCalloc(1, sizeof(XawDLImageArgs));
1999
2000	  retval = args;
2001	  args->pixmap = XawLoadPixmap(params[0], screen, colormap, depth);
2002	  if (args->pixmap == NULL)
2003	    {
2004	      XtDisplayStringConversionWarning(DisplayOfScreen(screen),
2005					       (String)params[0], XtRPixmap);
2006	      retval = XAWDL_CONVERT_ERROR;
2007	      XtFree((char *)args);
2008	    }
2009	  else
2010	    {
2011	      args->depth = depth;
2012	      for (i = 1; i < *num_params && i < 5; i++)
2013		read_position((char *)params[i], &args->pos[i - 1]);
2014	    }
2015	}
2016      break;
2017    }
2018
2019  return (retval);
2020}
2021
2022/* ARGSUSED */
2023static void *
2024_Xaw_Xlib_DataInitProc(String class_name _X_UNUSED,
2025		       Screen *screen _X_UNUSED, Colormap colormap _X_UNUSED, int depth)
2026{
2027  XawXlibData *data;
2028  Window tmp_win;
2029
2030  data = (XawXlibData *)XtMalloc(sizeof(XawXlibData));
2031
2032  tmp_win = XCreateWindow(DisplayOfScreen(screen),
2033			  RootWindowOfScreen(screen),
2034			  0, 0, 1, 1, 1, depth,
2035			  InputOutput, (Visual *)CopyFromParent, 0, NULL);
2036  data->mask = 0;
2037  data->gc = XCreateGC(DisplayOfScreen(screen), tmp_win, 0, &data->values);
2038  XDestroyWindow(DisplayOfScreen(screen), tmp_win);
2039  data->shape = Complex;
2040  data->mode = CoordModeOrigin;
2041  data->dashes = NULL;
2042
2043  return ((void *)data);
2044}
2045
2046/* ARGSUSED */
2047static void
2048_Xaw_Xlib_ArgsDestructor(Display *display _X_UNUSED, String proc_name, XtPointer args,
2049			 String *params _X_UNUSED, Cardinal *num_params _X_UNUSED)
2050{
2051  Cardinal id;
2052  Dl_init *init;
2053
2054  init = (Dl_init *)bsearch(proc_name, dl_init,
2055			    sizeof(dl_init) / sizeof(dl_init[0]),
2056			    sizeof(dl_init[0]),
2057			    bcmp_cvt_proc);
2058
2059  id = init->id;
2060
2061  switch (id)
2062    {
2063    case LINE:
2064    case DRECT:
2065    case FRECT:
2066    case DARC:
2067    case FARC:
2068    case POINT:
2069    case TSORIGIN:
2070    case DASHES:
2071    case CLIPORIGIN:
2072    case COPYAREA:
2073    case COPYPLANE:
2074    case IMAGE:
2075      XtFree(args);
2076      break;
2077    case DSTRING:
2078    case PSTRING:
2079      {
2080	XawDLStringArgs *string = (XawDLStringArgs *)args;
2081	XtFree(string->string);
2082	XtFree(args);
2083      } break;
2084    case DLINES:
2085    case FPOLY:
2086    case POINTS:
2087    case SEGMENTS:
2088    case CLIPRECTS:
2089      {
2090	XawDLPositionPtr *ptr = (XawDLPositionPtr *)args;
2091
2092	XtFree((char *)ptr->pos);
2093	XtFree(args);
2094      } break;
2095    }
2096}
2097
2098/* ARGSUSED */
2099static void
2100_Xaw_Xlib_DataDestructor(Display *display, String class_name _X_UNUSED, XtPointer data)
2101{
2102  if (data)
2103    {
2104      XawXlibData *xdata = (XawXlibData *)data;
2105
2106      XFreeGC(display, xdata->gc);
2107      if (xdata->dashes)
2108	XtFree(xdata->dashes);
2109      XtFree((char *)data);
2110    }
2111}
2112
2113/* Start of DLInfo Management Functions */
2114static int
2115qcmp_dlist_info(register _Xconst void *left, register _Xconst void *right)
2116{
2117  return (strcmp((*(XawDLInfo **)left)->name, (*(XawDLInfo **)right)->name));
2118}
2119
2120Bool XawDeclareDisplayListProc(XawDLClass *lc, String name,
2121				  XawDisplayListProc proc)
2122{
2123  XawDLInfo *info;
2124
2125  if (!lc || !proc || !name || name[0] == '\0')
2126    return (False);
2127
2128  if ((info = _XawFindDLInfo(lc, name)) != NULL)
2129    /* Since the data structures to the displayList classes are(should be)
2130     * opaque, it is not a good idea to allow overriding a displayList
2131     * procedure; it's better to choose another name or class name!
2132     */
2133    return (False);
2134
2135  info = (XawDLInfo *)XtMalloc(sizeof(XawDLInfo));
2136  info->name = XtNewString(name);
2137  info->qname = XrmStringToQuark(info->name);
2138  info->proc = proc;
2139
2140  if (!lc->num_infos)
2141    {
2142      lc->num_infos = 1;
2143      lc->infos = (XawDLInfo **)XtMalloc(sizeof(XawDLInfo*));
2144    }
2145  else
2146    {
2147      ++lc->num_infos;
2148      lc->infos = (XawDLInfo **)
2149	XtRealloc((char *)lc->infos, (Cardinal)(sizeof(XawDLInfo*) * (size_t)lc->num_infos));
2150    }
2151  lc->infos[lc->num_infos - 1] = info;
2152
2153  if (lc->num_infos > 1)
2154    qsort(lc->infos, lc->num_infos, sizeof(XawDLInfo*), qcmp_dlist_info);
2155
2156  return (True);
2157}
2158
2159static int
2160bcmp_dlist_info(register _Xconst void *string,
2161		register _Xconst void *dlinfo)
2162{
2163  return (strcmp((String)string, (*(XawDLClass **)dlinfo)->name));
2164}
2165
2166static XawDLInfo *
2167_XawFindDLInfo(XawDLClass *lc, String name)
2168{
2169  XawDLInfo **info;
2170
2171  if (!lc->infos)
2172    return (NULL);
2173
2174  info = (XawDLInfo **)bsearch(name, lc->infos, lc->num_infos,
2175			       sizeof(XawDLInfo*), bcmp_dlist_info);
2176
2177  return (info ? *info : NULL);
2178}
2179
2180/* Start of DLClass Management Functions */
2181XawDLClass *
2182XawGetDisplayListClass(String name)
2183{
2184  return (_XawFindDLClass(name));
2185}
2186
2187static int
2188qcmp_dlist_class(register _Xconst void *left, register _Xconst void *right)
2189{
2190  return (strcmp((*(XawDLClass **)left)->name, (*(XawDLClass **)right)->name));
2191}
2192
2193XawDLClass *
2194XawCreateDisplayListClass(String name,
2195			  XawDLArgsInitProc args_init,
2196			  XawDLArgsDestructor args_destructor,
2197			  XawDLDataInitProc data_init,
2198			  XawDLDataDestructor data_destructor)
2199{
2200  XawDLClass *lc;
2201
2202  if (!name || name[0] == '\0')
2203    return (NULL);
2204
2205  lc = (XawDLClass *)XtMalloc(sizeof(XawDLClass));
2206  lc->name = XtNewString(name);
2207  lc->infos = NULL;
2208  lc->num_infos = 0;
2209  lc->args_init = args_init;
2210  lc->args_destructor = args_destructor;
2211  lc->data_init = data_init;
2212  lc->data_destructor = data_destructor;
2213
2214  if (!classes)
2215    {
2216      num_classes = 1;
2217      classes = (XawDLClass **)XtMalloc(sizeof(XawDLClass));
2218    }
2219  else
2220    {
2221      ++num_classes;
2222      classes = (XawDLClass **)XtRealloc((char *)classes,
2223					 (Cardinal)(sizeof(XawDLClass) * (size_t)num_classes));
2224    }
2225  classes[num_classes - 1] = lc;
2226
2227  if (num_classes > 1)
2228    qsort(&classes[0], num_classes, sizeof(XawDLClass*), qcmp_dlist_class);
2229
2230  return (lc);
2231}
2232
2233static int
2234bcmp_dlist_class(register _Xconst void *string,
2235		 register _Xconst void *dlist)
2236{
2237  return (strcmp((String)string, (*(XawDLClass **)dlist)->name));
2238}
2239
2240static XawDLClass *
2241_XawFindDLClass(String name)
2242{
2243  XawDLClass **lc;
2244
2245  if (!classes)
2246    return (NULL);
2247
2248  lc = (XawDLClass **)bsearch(name, &classes[0], num_classes,
2249			      sizeof(XawDLClass*), bcmp_dlist_class);
2250
2251  return (lc ? *lc : NULL);
2252}
2253
2254#endif /* OLDXAW */
2255