planemask.c revision fd7d9bd3
1/*
2** planemask.c
3**
4** How to make a widget to choose a planemask.
5**
6** NOTE: This file uses static variables.  Therefore, trying to use these
7**       functions to create more than one of these planemask choice things
8**       will fail in a big way.
9*/
10/* $XFree86: xc/programs/xgc/planemask.c,v 1.3 2000/02/17 14:00:37 dawes Exp $ */
11
12#include <X11/Xos.h>
13#include <stdio.h>
14#include <stdlib.h>
15#include <X11/Intrinsic.h>
16#include <X11/StringDefs.h>
17#include <X11/Xaw/Form.h>
18#include <X11/Xaw/Label.h>
19#include <X11/Xaw/Toggle.h>
20#include "xgc.h"
21
22static void choose_plane(Widget, caddr_t, caddr_t);
23
24static unsigned long planemask;
25static Widget *pm;
26
27/* create_planemask_choice(w)
28** -------------------------
29** Inside w (a form widget), creates a bunch of little toggle buttons
30** in a row, representing the planemask.  There's also a label so
31** the user knows what it is.
32*/
33
34void
35create_planemask_choice(Widget w)
36{
37  /* callback list for the toggle widgets */
38  static XtCallbackRec callbacklist[] = {
39    {(XtCallbackProc) choose_plane, NULL},
40    {NULL,                          NULL}
41  };
42
43  /* ArgList for the label */
44  static Arg labelargs[] = {
45    {XtNborderWidth,     (XtArgVal) 0},
46    {XtNjustify,         (XtArgVal) XtJustifyRight},
47    {XtNvertDistance,    (XtArgVal) 4}
48  };
49
50  /* ArgList for the toggles */
51  static Arg pmargs[] = {
52    {XtNcallback,          (XtArgVal) NULL},
53    {XtNhorizDistance,     (XtArgVal) NULL},
54    {XtNfromHoriz,         (XtArgVal) NULL},
55    {XtNwidth,             (XtArgVal) 10},
56    {XtNheight,            (XtArgVal) 10},
57    {XtNhighlightThickness,(XtArgVal) 1},
58    {XtNstate,             (XtArgVal) True},
59    {XtNlabel,             (XtArgVal) ""}
60  };
61
62  static Widget label;		/* the label, of course */
63  static int *pminfo;		/* contains integers saying which bit
64				   a particular button is; sent to
65				   choose_plane to tell it which
66				   bit got changed */
67
68  int i, num_planes;
69
70  char buf[40];
71  char name[12];
72
73  num_planes = PlanesOfScreen(X.scr);
74
75  planemask = (1<<num_planes)-1;
76  snprintf(buf, sizeof buf, "planemask %lu",planemask);
77  interpret(buf);
78
79  /* Allocate space for stuff that we don't know the size of yet */
80
81  pm = (Widget *) malloc(num_planes * sizeof(Widget));
82  pminfo = (int *) malloc(num_planes * sizeof(int));
83
84  /* Make the label widget */
85
86  label = XtCreateManagedWidget("planemask",labelWidgetClass,w,
87				labelargs,XtNumber(labelargs));
88
89  pmargs[0].value = (XtArgVal) callbacklist;
90
91  for (i=0;i<num_planes;++i) {	/* go through all the buttons */
92    if (i==0) {			/* offset the first one from the label */
93      pmargs[1].value = (XtArgVal) 10;
94      pmargs[2].value = (XtArgVal) label;
95    }
96    else {			/* put it directly to the right of the
97				   last one, no space in between */
98      pmargs[1].value = (XtArgVal) -1;
99      pmargs[2].value = (XtArgVal) pm[i-1];
100    }
101
102    /* set its original state depending on the state of that bit
103    ** of the planemask */
104
105    if (planemask & 1<<i)
106      pmargs[6].value = (XtArgVal) True;
107    else
108      pmargs[6].value = (XtArgVal) False;
109
110    snprintf(name, sizeof name, "planemask%d",i);
111
112    pminfo[i] = i;		/* which bit we're on; this is needed in
113				   choose_plane (the callback) */
114    callbacklist[0].closure = (caddr_t) &pminfo[i];
115
116    pm[i] = XtCreateManagedWidget(name,toggleWidgetClass,w,
117				  pmargs,XtNumber(pmargs));
118  }
119}
120
121/* choose_plane(w,closure,call_data)
122** ------------------------------------
123** This function is called when the user toggles a toggle widget.  It
124** makes the appropriate change to the planemask and sends it off
125** to interpret().
126** Funny args are because it's a callback.
127*/
128
129/*ARGSUSED*/
130static void
131choose_plane(Widget w, caddr_t closure, caddr_t call_data)
132{
133  int num;			/* what number button it is */
134  Boolean on;			/* is it currently on or off? */
135
136  char buf[80];			/* string to send to interpret() */
137
138  static Arg args[] = {
139    {XtNstate,    (XtArgVal) NULL}
140  };
141
142  /* set up ArgList so that 'on' will contain the state */
143  args[0].value = (XtArgVal) &on;
144
145  num = * (int *) closure;	/* we put it here back in the last function */
146  XtGetValues(w,args,XtNumber(args));
147
148  /* Modify the planemask appropriately */
149
150  if (on)
151    planemask |= 1<<num;
152  else
153    planemask &= ~(1<<num);
154
155  (void) snprintf(buf, sizeof buf, "planemask %lu\n",planemask);
156  interpret(buf);
157}
158
159/* update_planemask(mask)
160** ----------------------
161** Updates the display of the planemask so that it corresponds to mask.
162*/
163
164void
165update_planemask(long mask)
166{
167  int i;			/* counter */
168  static Arg maskargs[] = {	/* ArgList for setting toggle state */
169    {XtNstate,     (XtArgVal) NULL}
170  };
171
172  /* First set the internal representation */
173
174  planemask = mask;
175
176  for (i = 0; i < PlanesOfScreen(X.scr); ++i) {
177    if (planemask & 1<<i) {        /* if it's set, make it look that way */
178      maskargs[0].value = (XtArgVal) True;
179    }
180    else {
181      maskargs[0].value = (XtArgVal) False;
182    }
183
184    XtSetValues(pm[i],maskargs,XtNumber(maskargs));
185  }
186}
187