source: trunk/athena/etc/xdm/xlogin/StringToPixel.c @ 10939

Revision 10939, 7.0 KB checked in by ghudson, 27 years ago (diff)
Assume X11R5 or higher on all platforms.
Line 
1#include <X11/StringDefs.h>
2#include <stdio.h>
3#include <string.h>
4#include <X11/cursorfont.h>
5#include <X11/keysym.h>
6#include <X11/IntrinsicP.h>
7#include <X11/Xresource.h>
8#include <ctype.h>
9
10#define MONO 0
11#define GRAY 1
12#define COLOR 2
13
14
15/*
16 * a few things taken from Xt/Converters.c, with a few mods...
17 */
18#ifdef __STDC__
19#define Const const
20#else
21#define Const /**/
22#endif
23
24static Const String XtNwrongParameters = "wrongParameters";
25
26#define done(type, value) \
27        {                                                       \
28            if (toVal->addr != NULL) {                          \
29                if (toVal->size < sizeof(type)) {               \
30                    toVal->size = sizeof(type);                 \
31                    return False;                               \
32                }                                               \
33                *(type*)(toVal->addr) = (value);                \
34            }                                                   \
35            else {                                              \
36                static type static_val;                         \
37                static_val = (value);                           \
38                toVal->addr = (XtPointer)&static_val;           \
39            }                                                   \
40            toVal->size = sizeof(type);                         \
41            return True;                                        \
42        }
43
44static XtConvertArgRec Const multiColorConvertArgs[] = {
45    {XtWidgetBaseOffset,
46       (XtPointer)XtOffset(Widget, core.screen),
47       sizeof(Screen *)},
48    {XtWidgetBaseOffset,
49       (XtPointer)XtOffset(Widget, core.colormap),
50       sizeof(Colormap)}
51};
52
53
54
55/*
56 *  CvtStringToPixel taken from Xt/Converters.c, and modified to suit
57 *  our needs...
58 */
59
60static Boolean CvtMultiStrToPxl(dpy, args, num_args, fromVal, toVal, closure_ret)
61    Display*    dpy;
62    XrmValuePtr args;
63    Cardinal    *num_args;
64    XrmValuePtr fromVal;
65    XrmValuePtr toVal;
66    XtPointer   *closure_ret;
67{
68    String          str = (String)fromVal->addr;
69    XColor          screenColor;
70    XColor          exactColor;
71    Screen          *screen;
72    /*
73     *  XtPerDisplay    pd = _XtGetPerDisplay(dpy);
74     *  we don't want to use private functions, however, that means we
75     *  can't deal with reverseVideo.  See below...
76     */
77    Colormap        colormap;
78    Status          status;
79    String          params[1];
80    Cardinal        num_params=1;
81
82    static int      init=0;
83    static int      type;
84    char            sep = ',';
85    String          copy, address2, address3, color;
86    XtAppContext    appContext = XtDisplayToApplicationContext(dpy);
87    char            *ptr;
88
89
90    if (*num_args != 2)
91      XtAppErrorMsg(appContext, XtNwrongParameters, "CvtMultiStrToPxl",
92                    "XtToolkitError",
93        "String to pixel conversion needs screen and colormap arguments",
94        (String *)NULL, (Cardinal *)NULL);
95
96    screen = *((Screen **) args[0].addr);
97    colormap = *((Colormap *) args[1].addr);
98
99
100
101    copy = XtNewString(str);
102
103    /*
104     * figure out the display type -- MONO, GRAY or COLOR
105     */
106    if (!init)
107      {
108        init = 1;
109        if (DisplayPlanes(dpy, XScreenNumberOfScreen(screen)) > 1)
110          {
111            Visual *visual;
112            visual =
113              DefaultVisualOfScreen(screen);
114            switch(visual->class)
115              {
116              case StaticGray:
117              case GrayScale:
118                type = GRAY;
119                break;
120              case StaticColor:
121              case PseudoColor:
122              case TrueColor:
123              case DirectColor:
124                type = COLOR;
125                break;
126              default:
127                type = MONO;
128                break;
129              }
130          }
131      }
132
133    /*
134     * parse the resource -- if there are 2 or 3 "words", then
135     * assign them to the other addresses.
136     */
137    if ((ptr = address2 = strchr(copy, sep))  !=  NULL)
138      {
139        ptr--;                          /* strip trailing spaces off word */
140        while (isspace(*ptr))           /*   before comma */
141          ptr--;
142        *++ptr = '\0';                  /* terminate string */
143
144        address2++;                     /* strip leading spaces off word */
145        while (isspace(*address2))      /*   after comma */
146          address2++;
147
148        if ((ptr = address3 = strchr(address2, sep))  !=  NULL)
149          {
150            ptr--;                      /* strip trailing spaces off word */
151            while (isspace(*ptr))       /*   before comma */
152              ptr--;
153            *++ptr = '\0';              /* terminate string */
154
155            address3++;                 /* strip leading spaces off word */
156            while (isspace(*address3))  /*   after comma */
157              address3++;
158
159            ptr = address3 + strlen(address3) - 1;      /* strip trailing */
160            while (isspace(*ptr))       /*   spaces off last word... */
161              ptr--;
162            *++ptr = '\0';              /* terminate string */
163          }
164        else
165          {                             /* if there are only 2 words, then */
166            address3 = address2;        /* set the "color address" to the */
167            address2 = copy;            /* 2nd one, and the "grayscale */
168          }                             /* address" to the 1st one... */
169      }
170    else                                /* if there is only 1 word, then */
171      address3 = address2 = copy;       /* set all addresses to it... */
172
173    /*
174     * figure out which address to use based on the display type.
175     */
176    switch(type)
177      {
178      case COLOR:
179        color = address3;
180        break;
181      case GRAY:
182        color = address2;
183        break;
184      default:
185        color = copy;
186        break;
187      }
188
189    if (strcasecmp(color, XtDefaultBackground) == 0) {
190        *closure_ret = False;
191        XtFree(copy);
192        /* if (pd->rv) done(Pixel, BlackPixelOfScreen(screen)) */
193        /* else */
194/*
195 *  Since we don't want to have to depend on header files in the Xt
196 *  sources, we can't deal with reverseVideo...  oh well...
197 */
198        done(Pixel, WhitePixelOfScreen(screen));
199    }
200    if (strcasecmp(color, XtDefaultForeground) == 0) {
201        *closure_ret = False;
202        XtFree(copy);
203        /* if (pd->rv) done(Pixel, WhitePixelOfScreen(screen)) */
204        /* else */
205/*
206 *  Since we don't want to have to depend on header files in the Xt
207 *  sources, we can't deal with reverseVideo...  oh well...
208 */
209        done(Pixel, BlackPixelOfScreen(screen));
210    }
211
212/*
213 *  From here on down, this is almost identical to the old
214 *  CvtStringToPixel, except that "str" was replaced by "color", and we
215 *  also have to free "copy" before returning, to avoid memory leaks...
216 */
217
218    if (*color == '#') {  /* some color rgb definition */
219
220        status = XParseColor(DisplayOfScreen(screen), colormap,
221                             (char*)color, &screenColor);
222
223        if (status == 0) {
224            params[0] = color;
225            XtAppWarningMsg(appContext, "badFormat", "CvtMultiStrToPxl",
226                            "XtToolkitError",
227                  "RGB color specification \"%s\" has invalid format",
228                  params, &num_params);
229            *closure_ret = False;
230            XtFree(copy);
231            return False;
232        }
233        else
234           status = XAllocColor(DisplayOfScreen(screen), colormap,
235                                &screenColor);
236    } else  /* some color name */
237
238        status = XAllocNamedColor(DisplayOfScreen(screen), colormap,
239                                  (char*)color, &screenColor, &exactColor);
240    if (status == 0) {
241        String msg, type;
242        params[0] = color;
243        /* Server returns a specific error code but Xlib discards it.  Ugh */
244        if (*color == '#' ||
245            XLookupColor(DisplayOfScreen(screen), colormap, (char*)color,
246                         &exactColor, &screenColor)) {
247            type = "noColormap";
248            msg = "Cannot allocate colormap entry for \"%s\"";
249        }
250        else {
251            type = "badValue";
252            msg = "Color name \"%s\" is not defined in server database";
253        }
254
255        XtAppWarningMsg(appContext, type, "CvtMultiStrToPxl",
256                        "XtToolkitError", msg, params, &num_params);
257        *closure_ret = False;
258        XtFree(copy);
259        return False;
260    } else {
261        *closure_ret = (char*)True;
262        XtFree(copy);
263        done(Pixel, screenColor.pixel);
264    }
265}
266
267
268
269void add_converter ()
270{
271  XtSetTypeConverter(XtRString, XtRPixel, CvtMultiStrToPxl,
272                     multiColorConvertArgs,
273                     XtNumber(multiColorConvertArgs),
274                     XtCacheNone, NULL);
275}
Note: See TracBrowser for help on using the repository browser.