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