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