summaryrefslogtreecommitdiff
path: root/app/xgc/planemask.c
blob: b55cf6b4903071e96fccdeebd352ee8296e7a316 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
/*
** planemask.c
**
** How to make a widget to choose a planemask.
**
** NOTE: This file uses static variables.  Therefore, trying to use these
**       functions to create more than one of these planemask choice things
**       will fail in a big way.
*/

#include <X11/Xos.h>
#include <stdio.h>
#include <stdlib.h>
#include <X11/Intrinsic.h>
#include <X11/StringDefs.h>
#include <X11/Xaw/Form.h>
#include <X11/Xaw/Label.h>
#include <X11/Xaw/Toggle.h>
#include "xgc.h"

static void choose_plane(Widget, caddr_t, caddr_t);

static unsigned long planemask;	
static Widget *pm;

/* create_planemask_choice(w)
** -------------------------
** Inside w (a form widget), creates a bunch of little toggle buttons
** in a row, representing the planemask.  There's also a label so
** the user knows what it is.
*/

void
create_planemask_choice(Widget w)
{
  /* callback list for the toggle widgets */
  static XtCallbackRec callbacklist[] = {
    {(XtCallbackProc) choose_plane, NULL},
    {NULL,                          NULL}
  };

  /* ArgList for the label */
  static Arg labelargs[] = {
    {XtNborderWidth,     (XtArgVal) 0},
    {XtNjustify,         (XtArgVal) XtJustifyRight},
    {XtNvertDistance,    (XtArgVal) 4}
  };

  /* ArgList for the toggles */
  static Arg pmargs[] = {
    {XtNcallback,          (XtArgVal) NULL},
    {XtNhorizDistance,     (XtArgVal) NULL},
    {XtNfromHoriz,         (XtArgVal) NULL},
    {XtNwidth,             (XtArgVal) 10},
    {XtNheight,            (XtArgVal) 10},
    {XtNhighlightThickness,(XtArgVal) 1},
    {XtNstate,             (XtArgVal) True},
    {XtNlabel,             (XtArgVal) ""}
  };

  static Widget label;		/* the label, of course */
  static int *pminfo;		/* contains integers saying which bit
				   a particular button is; sent to
				   choose_plane to tell it which
				   bit got changed */

  int i, num_planes;

  char buf[40];
  char name[12];

  num_planes = PlanesOfScreen(X.scr);

  planemask = (1<<num_planes)-1;
  snprintf(buf, sizeof buf, "planemask %lu",planemask);
  interpret(buf);

  /* Allocate space for stuff that we don't know the size of yet */

  pm = (Widget *) malloc(num_planes * sizeof(Widget));
  pminfo = (int *) malloc(num_planes * sizeof(int));

  /* Make the label widget */

  label = XtCreateManagedWidget("planemask",labelWidgetClass,w,
				labelargs,XtNumber(labelargs));

  pmargs[0].value = (XtArgVal) callbacklist;

  for (i=0;i<num_planes;++i) {	/* go through all the buttons */
    if (i==0) {			/* offset the first one from the label */
      pmargs[1].value = (XtArgVal) 10;
      pmargs[2].value = (XtArgVal) label;
    }
    else {			/* put it directly to the right of the
				   last one, no space in between */
      pmargs[1].value = (XtArgVal) -1;
      pmargs[2].value = (XtArgVal) pm[i-1];
    }

    /* set its original state depending on the state of that bit
    ** of the planemask */

    if (planemask & 1<<i)
      pmargs[6].value = (XtArgVal) True;
    else
      pmargs[6].value = (XtArgVal) False;

    snprintf(name, sizeof name, "planemask%d",i);

    pminfo[i] = i;		/* which bit we're on; this is needed in
				   choose_plane (the callback) */
    callbacklist[0].closure = (caddr_t) &pminfo[i];

    pm[i] = XtCreateManagedWidget(name,toggleWidgetClass,w,
				  pmargs,XtNumber(pmargs));
  }
}

/* choose_plane(w,closure,call_data)
** ------------------------------------
** This function is called when the user toggles a toggle widget.  It
** makes the appropriate change to the planemask and sends it off
** to interpret().
** Funny args are because it's a callback.
*/

/*ARGSUSED*/
static void
choose_plane(Widget w, caddr_t closure, caddr_t call_data)
{
  int num;			/* what number button it is */
  Boolean on;			/* is it currently on or off? */

  char buf[80];			/* string to send to interpret() */

  static Arg args[] = {
    {XtNstate,    (XtArgVal) NULL}
  };

  /* set up ArgList so that 'on' will contain the state */
  args[0].value = (XtArgVal) &on;

  num = * (int *) closure;	/* we put it here back in the last function */
  XtGetValues(w,args,XtNumber(args));

  /* Modify the planemask appropriately */

  if (on)
    planemask |= 1<<num;
  else
    planemask &= ~(1<<num);

  (void) snprintf(buf, sizeof buf, "planemask %lu\n",planemask);
  interpret(buf);
}

/* update_planemask(mask)
** ----------------------
** Updates the display of the planemask so that it corresponds to mask.
*/

void
update_planemask(long mask)
{
  int i;			/* counter */
  static Arg maskargs[] = {	/* ArgList for setting toggle state */
    {XtNstate,     (XtArgVal) NULL}
  };

  /* First set the internal representation */

  planemask = mask;

  for (i = 0; i < PlanesOfScreen(X.scr); ++i) {
    if (planemask & 1<<i) {        /* if it's set, make it look that way */
      maskargs[0].value = (XtArgVal) True;
    }
    else {
      maskargs[0].value = (XtArgVal) False;
    }

    XtSetValues(pm[i],maskargs,XtNumber(maskargs));
  }
}