Convert uses of XKeycodeToKeysym (deprecated) to XkbKeycodeToKeysym
[oweals/cde.git] / cde / programs / dtwm / WmResCvt.c
1 /*
2  * CDE - Common Desktop Environment
3  *
4  * Copyright (c) 1993-2012, The Open Group. All rights reserved.
5  *
6  * These libraries and programs are free software; you can
7  * redistribute them and/or modify them under the terms of the GNU
8  * Lesser General Public License as published by the Free Software
9  * Foundation; either version 2 of the License, or (at your option)
10  * any later version.
11  *
12  * These libraries and programs are distributed in the hope that
13  * they will be useful, but WITHOUT ANY WARRANTY; without even the
14  * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15  * PURPOSE. See the GNU Lesser General Public License for more
16  * details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with these libraries and programs; if not, write
20  * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21  * Floor, Boston, MA 02110-1301 USA
22  */
23 /* 
24  * (c) Copyright 1989, 1990, 1991, 1992, 1993, 1994 OPEN SOFTWARE FOUNDATION, INC. 
25  * ALL RIGHTS RESERVED 
26 */ 
27 /* 
28  * Motif Release 1.2.4
29 */ 
30 /*
31  * (c) Copyright 1987, 1988, 1989, 1990 HEWLETT-PACKARD COMPANY */
32
33 /*
34  * Included Files:
35  */
36
37 #include "WmGlobal.h"
38 #include "WmResNames.h"
39 #include <ctype.h>
40 #include <stdio.h>
41
42 #include <stdlib.h>
43
44 #include <Xm/XmosP.h>
45
46 /*
47  * include extern functions
48  */
49
50 #include "WmResParse.h"
51
52 /*
53  * Function Declarations:
54  */
55
56 unsigned char *NextToken ();
57 long           DecStrToL ();
58
59 #include "WmResCvt.h"
60
61
62
63 \f
64 /*************************************<->*************************************
65  *
66  *  AddWmResourceConverters (args)
67  *
68  *
69  *  Description:
70  *  -----------
71  *  This function adds resource type converters for mwm specific resource
72  *  types to the X Toolkit collection.
73  *
74  *
75  *  Inputs:
76  *  ------
77  *  XXinput = ...
78  *
79  *  XXinput = ...
80  *
81  * 
82  *  Outputs:
83  *  -------
84  *  XXOutput = ...
85  *
86  *
87  *  Comments:
88  *  --------
89  *  XXComments ...
90  * 
91  *************************************<->***********************************/
92
93 void AddWmResourceConverters (void)
94 {
95     XtAppAddConverter (wmGD.mwmAppContext, XtRString, WmRAbsentMapBehavior, 
96         (XtConverter)WmCvtStringToAMBehavior, NULL, 0);
97     XtAppAddConverter (wmGD.mwmAppContext, XtRString, WmRCFocusPolicy, 
98         (XtConverter)WmCvtStringToCFocus, NULL, 0);
99     XtAppAddConverter (wmGD.mwmAppContext, XtRString, WmRClientDecor, 
100         (XtConverter)WmCvtStringToCDecor, NULL, 0);
101     XtAppAddConverter (wmGD.mwmAppContext, XtRString, WmRClientFunction, 
102         (XtConverter)WmCvtStringToCFunc, NULL, 0);
103     XtAppAddConverter (wmGD.mwmAppContext, XtRString, WmRFrameStyle, 
104         (XtConverter)WmCvtStringToFrameStyle, NULL, 0);
105     XtAppAddConverter (wmGD.mwmAppContext, XtRString, WmRIconDecor, 
106         (XtConverter)WmCvtStringToIDecor, NULL, 0);
107     XtAppAddConverter (wmGD.mwmAppContext, XtRString, WmRIconPlacement, 
108         (XtConverter)WmCvtStringToIPlace, NULL, 0);
109     XtAppAddConverter (wmGD.mwmAppContext, XtRString, WmRKFocusPolicy, 
110         (XtConverter)WmCvtStringToKFocus, NULL, 0);
111     XtAppAddConverter (wmGD.mwmAppContext, XtRString, WmRSize, 
112         (XtConverter)WmCvtStringToSize, NULL, 0);
113     XtAppAddConverter (wmGD.mwmAppContext, XtRString, WmRShowFeedback, 
114         (XtConverter)WmCvtStringToShowFeedback, NULL, 0);
115     XtAppAddConverter (wmGD.mwmAppContext, XtRString, WmRUsePPosition, 
116         (XtConverter)WmCvtStringToUsePPosition, NULL, 0);
117
118 } /* END OF FUNCTION AddWmResourceConverters */
119
120 /*************************************<->*************************************
121  *
122  *  WmCvtStringToAMBehavior (args, numArgs, fromVal, toVal)
123  *
124  *
125  *  Description:
126  *  -----------
127  *  This function converts a string to an absent map behavior description.
128  *
129  *
130  *  Inputs:
131  *  ------
132  *  args = additional XrmValue arguments to the converter - NULL here
133  *
134  *  numArgs = number of XrmValue arguments - 0 here
135  *
136  *  fromVal = resource value to convert
137  *
138  * 
139  *  Outputs:
140  *  -------
141  *  toVal = descriptor to use to return converted value
142  *
143  *************************************<->***********************************/
144
145 void WmCvtStringToAMBehavior (XrmValue *args, Cardinal numArgs, XrmValue *fromVal, XrmValue *toVal)
146 {
147     unsigned char      *pch = (unsigned char *) (fromVal->addr);
148     unsigned char      *pchNext;
149     int        len;
150     static int cval;
151     Boolean    fHit = False;
152
153 /*
154  * Absent map behavior policies:
155  */
156 #define AMAP_BEHAVIOR_ADD_STR           (unsigned char *)"add"
157 #define AMAP_BEHAVIOR_MOVE_STR          (unsigned char *)"move"
158 #define AMAP_BEHAVIOR_IGNORE_STR        (unsigned char *)"ignore"
159
160     /*
161      * Convert the absent map behavior policy resource value:
162      */
163
164     if (*pch && NextToken (pch, &len, &pchNext))
165     {
166         if ((*pch == 'A') || (*pch == 'a'))
167         {
168             if (StringsAreEqual (pch, AMAP_BEHAVIOR_ADD_STR, len))
169             {
170                 cval = AMAP_BEHAVIOR_ADD;
171                 fHit = True;
172             }
173         }
174
175         else if ((*pch == 'M') || (*pch == 'm'))
176         {
177             if (StringsAreEqual (pch, AMAP_BEHAVIOR_MOVE_STR, len))
178             {
179                 cval = AMAP_BEHAVIOR_MOVE;
180                 fHit = True;
181             }
182         }
183
184         else if ((*pch == 'I') || (*pch == 'i'))
185         {
186             if (StringsAreEqual (pch, AMAP_BEHAVIOR_IGNORE_STR, len))
187             {
188                 cval = AMAP_BEHAVIOR_IGNORE;
189                 fHit = True;
190             }
191         }
192     }
193
194     if (!fHit)
195     {
196         cval =  AMAP_BEHAVIOR_ADD;
197     }
198
199
200     (*toVal).size = sizeof (int);
201     (*toVal).addr = (caddr_t)&cval;
202
203
204 } /* END OF FUNCTION WmCvtStringToAMBehavior */
205
206 \f
207 /*************************************<->*************************************
208  *
209  *  WmCvtStringToCFocus (args, numArgs, fromVal, toVal)
210  *
211  *
212  *  Description:
213  *  -----------
214  *  This function converts a string to a colormap focus policy description.
215  *
216  *
217  *  Inputs:
218  *  ------
219  *  args = additional XrmValue arguments to the converter - NULL here
220  *
221  *  numArgs = number of XrmValue arguments - 0 here
222  *
223  *  fromVal = resource value to convert
224  *
225  * 
226  *  Outputs:
227  *  -------
228  *  toVal = descriptor to use to return converted value
229  *
230  *************************************<->***********************************/
231
232 void WmCvtStringToCFocus (XrmValue *args, Cardinal numArgs, XrmValue *fromVal, XrmValue *toVal)
233 {
234     unsigned char      *pch = (unsigned char *) (fromVal->addr);
235     unsigned char      *pchNext;
236     int        len;
237     static int cval;
238     Boolean    fHit = False;
239
240 /*
241  * Colormap focus policies:
242  */
243
244 #define CMAP_FOCUS_EXPLICIT_STR         (unsigned char *)"explicit"
245 #define CMAP_FOCUS_KEYBOARD_STR         (unsigned char *)"keyboard"
246 #define CMAP_FOCUS_POINTER_STR          (unsigned char *)"pointer"
247
248
249     /*
250      * Convert the colormap focus policy resource value:
251      */
252
253     if (*pch && NextToken (pch, &len, &pchNext))
254     {
255         if ((*pch == 'E') || (*pch == 'e'))
256         {
257             if (StringsAreEqual (pch, CMAP_FOCUS_EXPLICIT_STR, len))
258             {
259                 cval = CMAP_FOCUS_EXPLICIT;
260                 fHit = True;
261             }
262         }
263
264         else if ((*pch == 'K') || (*pch == 'k'))
265         {
266             if (StringsAreEqual (pch, CMAP_FOCUS_KEYBOARD_STR, len))
267             {
268                 cval = CMAP_FOCUS_KEYBOARD;
269                 fHit = True;
270             }
271         }
272
273         else if ((*pch == 'P') || (*pch == 'p'))
274         {
275             if (StringsAreEqual (pch, CMAP_FOCUS_POINTER_STR, len))
276             {
277                 cval = CMAP_FOCUS_POINTER;
278                 fHit = True;
279             }
280         }
281     }
282
283     if (!fHit)
284     {
285         cval =  CMAP_FOCUS_KEYBOARD;
286     }
287
288
289     (*toVal).size = sizeof (int);
290     (*toVal).addr = (caddr_t)&cval;
291
292
293 } /* END OF FUNCTION WmCvtStringToCFocus */
294
295
296 \f
297 /*************************************<->*************************************
298  *
299  *  WmCvtStringToCDecor (args, numArgs, fromVal, toVal)
300  *
301  *
302  *  Description:
303  *  -----------
304  *  This function converts a string to a mwm client window frame decoration
305  *  description.
306  *
307  *
308  *  Inputs:
309  *  ------
310  *  args = NULL (don't care)
311  *
312  *  numArgs = 0 (don't care)
313  *
314  *  fromVal = resource value to convert
315  *
316  * 
317  *  Outputs:
318  *  -------
319  *  toVal = descriptor to use to return converted value
320  *
321  *
322  *  Comments:
323  *  --------
324  *  o Accepts the following syntax:
325  *
326  *    CDecor ::= [sign] decor_spec [decor_spec ...]
327  *
328  *    sign ::= ['+' | '-']
329  *
330  *    decor_spec ::= [sign] decor_name
331  *
332  *    decor_name ::=  "all" | "none" | "title" | "titlebar" |
333  *                     "menu" | "minimize" | "maximize" | "resize" 
334  * 
335  *************************************<->***********************************/
336
337 void WmCvtStringToCDecor (XrmValue *args, Cardinal numArgs, XrmValue *fromVal, XrmValue *toVal)
338 {
339     unsigned char      *pch = (unsigned char *) (fromVal->addr);
340     unsigned char      *pchNext;
341     int        len;
342     static int cval;
343     Boolean    fHit = False;
344     Boolean    fAddNext = True;
345 /*
346  * Client decoration parts:
347  */
348
349 #define WM_DECOR_ALL_STR                (unsigned char *)"all"
350 #define WM_DECOR_NONE_STR               (unsigned char *)"none"
351 #define WM_DECOR_BORDER_STR             (unsigned char *)"border"
352 #define WM_DECOR_RESIZEH_STR            (unsigned char *)"resizeh"
353 #define WM_DECOR_TITLE_STR              (unsigned char *)"title"
354 #define WM_DECOR_TITLEBAR_STR           (unsigned char *)"titlebar"
355 #define WM_DECOR_MINIMIZE_STR           (unsigned char *)"minimize"
356 #define WM_DECOR_MAXIMIZE_STR           (unsigned char *)"maximize"
357 #define WM_DECOR_MENU_STR               (unsigned char *)"menu"
358 #define WM_DECOR_RESIZE_STR             (unsigned char *)"resize"
359
360     /*
361      * Check first token. If '-' we subtract from all decoration.
362      * Otherwise, we start with no decoration and add things in.
363      */
364     if (*pch && 
365         (NextToken (pch, &len, &pchNext)) && 
366         (*pch == '-'))
367     {
368         cval = WM_DECOR_ALL;   
369         fHit = True;
370     }
371     else
372     {
373         cval = WM_DECOR_NONE;
374     }
375
376
377     while (*pch && NextToken(pch, &len, &pchNext)) 
378     {
379            /*
380             * Strip off "sign" if prepended to another token, and process
381             * that token the next time through.
382             */
383
384         if (*pch == '+')
385         {
386             if (len != 1)
387             {
388                 pchNext = pch + 1;
389             }
390             fAddNext = TRUE;
391         }
392
393         else if (*pch == '-')
394         {
395             if (len != 1) 
396             {
397                 pchNext = pch + 1;
398             }
399             fAddNext = FALSE;
400         }
401
402         else if ((*pch == 'A') || (*pch == 'a'))
403         {
404             if (StringsAreEqual(pch, WM_DECOR_ALL_STR,len))  
405             {
406                 cval = fAddNext ? (cval | WM_DECOR_ALL) : 
407                                  (cval & ~WM_DECOR_ALL);
408                 fHit = True;
409             }
410         }
411                
412         else if ((*pch == 'N') || (*pch == 'n'))
413         {
414             if (StringsAreEqual(pch, WM_DECOR_NONE_STR,len))
415             {
416                 /* don't bother adding or subtracting nothing */
417                 fHit = True;
418             }
419         }
420
421         else if ((*pch == 'T') || (*pch == 't'))
422         {
423             if (StringsAreEqual(pch, WM_DECOR_TITLE_STR,len))
424             {
425                 cval = fAddNext ? (cval | WM_DECOR_TITLE) : 
426                                   (cval & ~WM_DECOR_TITLEBAR);
427                 fHit = True;
428             }
429             else if (StringsAreEqual(pch, WM_DECOR_TITLEBAR_STR,len))  
430             {
431                 cval = fAddNext ? (cval | WM_DECOR_TITLEBAR) : 
432                                   (cval & ~WM_DECOR_TITLEBAR);
433                 fHit = True;
434             }
435         }
436                
437         else if ((*pch == 'M') || (*pch == 'm'))
438         {
439             if (StringsAreEqual(pch, WM_DECOR_MINIMIZE_STR,len)) 
440             {
441                 cval = fAddNext ? (cval | WM_DECOR_MINIMIZE) : 
442                                   (cval & ~MWM_DECOR_MINIMIZE);
443                 fHit = True;
444             }
445             else if (StringsAreEqual(pch, WM_DECOR_MAXIMIZE_STR,len))  
446             {
447                 cval = fAddNext ? (cval | WM_DECOR_MAXIMIZE) : 
448                                   (cval & ~MWM_DECOR_MAXIMIZE);
449                 fHit = True;
450             }
451             else if (StringsAreEqual(pch, WM_DECOR_MENU_STR,len))
452             {
453                 cval = fAddNext ? (cval | WM_DECOR_SYSTEM) : 
454                                   (cval & ~MWM_DECOR_MENU);
455                 fHit = True;
456             }
457         }
458
459         else if ((*pch == 'R') || (*pch == 'r'))
460         {
461             if (StringsAreEqual(pch, WM_DECOR_RESIZE_STR,len) ||
462                 StringsAreEqual(pch, WM_DECOR_RESIZEH_STR,len)) 
463             {
464                 cval = fAddNext ? (cval | WM_DECOR_RESIZEH) : 
465                                   (cval & ~MWM_DECOR_RESIZEH);
466                 fHit = True;
467             }
468         }
469                
470         else if ((*pch == 'B') || (*pch == 'b'))
471         {
472             if (StringsAreEqual(pch, WM_DECOR_BORDER_STR,len))
473             {
474                 cval = fAddNext ? (cval | WM_DECOR_BORDER) : 
475                                   (cval & ~WM_DECOR_BORDER);
476                 fHit = True;
477             }
478         }
479
480         pch = pchNext;
481     }
482
483     if (!fHit) cval =  WM_DECOR_ALL;
484
485     (*toVal).size = sizeof (int);
486     (*toVal).addr = (caddr_t) &cval;
487
488 } /* END OF FUNCTION WmCvtStringToCDecor */
489
490
491 \f
492 /*************************************<->*************************************
493  *
494  *  WmCvtStringToCFunc (args, numArgs, fromVal, toVal)
495  *
496  *
497  *  Description:
498  *  -----------
499  *  This function converts a string to a mwm client-applicable function
500  *  description.
501  *
502  *
503  *  Inputs:
504  *  ------
505  *  args = NULL (don't care)
506  *
507  *  numArgs = 0 (don't care)
508  *
509  *  fromVal = resource value to convert
510  *
511  * 
512  *  Outputs:
513  *  -------
514  *  toVal = descriptor to use to return converted value
515  *
516  *
517  *  Comments:
518  *  --------
519  *  o Accepts the following syntax:
520  *
521  *    CFunc ::= [sign] func_spec [func_spec ...]
522  *
523  *    sign ::= ['+' | '-']
524  *
525  *    func_spec ::= [sign] func_name
526  *
527  *    func_name ::=  "all" | "none" | "resize" | "move" | "minimize" |
528  *                   "maximize" | "close" 
529  * 
530  *************************************<->***********************************/
531
532 void WmCvtStringToCFunc (XrmValue *args, Cardinal numArgs, XrmValue *fromVal, XrmValue *toVal)
533 {
534     unsigned char      *pch = (unsigned char *) (fromVal->addr);
535     unsigned char      *pchNext;
536     int        len;
537     static int cval;
538     Boolean    fHit = False;
539     Boolean    fAddNext = True;
540
541 /*
542  * Client-applicable functions:
543  */
544
545 #define WM_FUNC_ALL_STR                 (unsigned char *)"all"
546 #define WM_FUNC_NONE_STR                (unsigned char *)"none"
547 #define WM_FUNC_RESIZE_STR              (unsigned char *)"resize"
548 #define WM_FUNC_MOVE_STR                (unsigned char *)"move"
549 #define WM_FUNC_MINIMIZE_STR            (unsigned char *)"minimize"
550 #define WM_FUNC_MAXIMIZE_STR            (unsigned char *)"maximize"
551 #define WM_FUNC_CLOSE_STR               (unsigned char *)"close"
552
553     /*
554      * Check first token. If '-' we subtract from all functions.
555      * Otherwise, we start with no functions and add things in.
556      */
557
558     if (*pch && 
559         (NextToken (pch, &len, &pchNext)) && 
560         (*pch == '-'))
561     {
562         cval = WM_FUNC_ALL;   
563         fHit = True;
564     }
565     else
566     {
567         cval = WM_FUNC_NONE;
568     }
569
570
571     while (*pch && NextToken(pch, &len, &pchNext)) 
572     {
573            /*
574             * Strip off "sign" if prepended to another token, and process
575             * that token the next time through.
576             */
577
578         if (*pch == '+')
579         {
580             if (len != 1)
581             {
582                 pchNext = pch + 1;
583             }
584             fAddNext = TRUE;
585         }
586
587         else if (*pch == '-')
588         {
589             if (len != 1) 
590             {
591                 pchNext = pch + 1;
592             }
593             fAddNext = FALSE;
594         }
595
596         else if ((*pch == 'A') || (*pch == 'a'))
597         {
598             if (StringsAreEqual(pch, WM_FUNC_ALL_STR,len))  
599             {
600                 cval = fAddNext ? (cval | WM_FUNC_ALL) : 
601                                   (cval & ~WM_FUNC_ALL);
602                 fHit = True;
603             }
604         }
605                
606         else if ((*pch == 'N') || (*pch == 'n'))
607         {
608             if (StringsAreEqual(pch, WM_FUNC_NONE_STR,len))
609             {
610                 /* don't bother adding or subtracting nothing */
611                 fHit = True;
612             }
613         }
614
615         else if ((*pch == 'R') || (*pch == 'r'))
616         {
617             if (StringsAreEqual(pch, WM_FUNC_RESIZE_STR,len))
618             {
619                 cval = fAddNext ? (cval | MWM_FUNC_RESIZE) : 
620                                   (cval & ~MWM_FUNC_RESIZE);
621                 fHit = True;
622             }
623         }
624                
625         else if ((*pch == 'M') || (*pch == 'm'))
626         {
627             if (StringsAreEqual(pch, WM_FUNC_MINIMIZE_STR,len)) 
628             {
629                 cval = fAddNext ? (cval | MWM_FUNC_MINIMIZE) : 
630                                   (cval & ~MWM_FUNC_MINIMIZE);
631                 fHit = True;
632             }
633             else if (StringsAreEqual(pch, WM_FUNC_MAXIMIZE_STR,len))  
634             {
635                 cval = fAddNext ? (cval | MWM_FUNC_MAXIMIZE) : 
636                                   (cval & ~MWM_FUNC_MAXIMIZE);
637                 fHit = True;
638             }
639             else if (StringsAreEqual(pch, WM_FUNC_MOVE_STR,len))  
640             {
641                 cval = fAddNext ? (cval | MWM_FUNC_MOVE) : 
642                                   (cval & ~MWM_FUNC_MOVE);
643                 fHit = True;
644             }
645         }
646                
647         else if ((*pch == 'C') || (*pch == 'c'))
648         {
649             if (StringsAreEqual(pch, WM_FUNC_CLOSE_STR,len))
650             {
651                 cval = fAddNext ? (cval | MWM_FUNC_CLOSE) : 
652                                   (cval & ~MWM_FUNC_CLOSE);
653                 fHit = True;
654             }
655         }
656
657         pch = pchNext;
658     }
659
660     if (!fHit) cval =  WM_FUNC_ALL;
661
662     (*toVal).size = sizeof (int);
663     (*toVal).addr = (caddr_t) &cval;
664
665 } /* END OF FUNCTION WmCvtStringToCFunc */
666
667 \f
668 /*************************************<->*************************************
669  *
670  *  WmCvtStringToFrameStyle (args, numArgs, fromVal, toVal)
671  *
672  *
673  *  Description:
674  *  -----------
675  *  This function converts a string to a frame style description.
676  *
677  *
678  *  Inputs:
679  *  ------
680  *  args = NULL (don't care)
681  *
682  *  numArgs = 0 (don't care)
683  *
684  *  fromVal = resource value to convert
685  *
686  * 
687  *  Outputs:
688  *  -------
689  *  toVal = descriptor to use to return converted value
690  *
691  *************************************<->***********************************/
692
693 void WmCvtStringToFrameStyle (XrmValue *args, Cardinal numArgs, XrmValue *fromVal, XrmValue *toVal)
694 {
695     unsigned char      *pch = (unsigned char *) (fromVal->addr);
696     unsigned char      *pchNext;
697     int        len;
698     static FrameStyle frameStyle;
699     Boolean    fHit = False;
700
701
702 #define FRAME_STYLE_RECESSED_STR        (unsigned char *)"recessed"
703 #define FRAME_STYLE_SLAB_STR            (unsigned char *)"slab"
704
705     /*
706      * Convert the resource value:
707      */
708
709     if (*pch && NextToken (pch, &len, &pchNext))
710     {
711         if ((*pch == 'R') || (*pch == 'r'))
712         {
713             if (StringsAreEqual (pch, FRAME_STYLE_RECESSED_STR, len))
714             {
715                 frameStyle = WmRECESSED;
716                 fHit = True;
717             }
718         }
719         else if (StringsAreEqual (pch, FRAME_STYLE_SLAB_STR, len))
720         {
721             frameStyle = WmSLAB;
722             fHit = True;
723         }
724     }
725
726     if (!fHit)
727     {
728         frameStyle = WmRECESSED;
729     }
730
731     (*toVal).size = sizeof (FrameStyle);
732     (*toVal).addr = (caddr_t)&frameStyle;
733
734
735 } /* END OF FUNCTION WmCvtStringToFrameStyle */
736
737
738 \f
739 /*************************************<->*************************************
740  *
741  *  WmCvtStringToIDecor (args, numArgs, fromVal, toVal)
742  *
743  *
744  *  Description:
745  *  -----------
746  *  This function converts a string to an icon decoration description.
747  *
748  *
749  *  Inputs:
750  *  ------
751  *  args = NULL (don't care)
752  *
753  *  numArgs = 0 (don't care)
754  *
755  *  fromVal = resource value to convert
756  *
757  * 
758  *  Outputs:
759  *  -------
760  *  toVal = descriptor to use to return converted value
761  *
762  *************************************<->***********************************/
763
764 void WmCvtStringToIDecor (XrmValue *args, Cardinal numArgs, XrmValue *fromVal, XrmValue *toVal)
765 {
766     unsigned char       *pch = (unsigned char *) (fromVal->addr);
767     unsigned char       *pchNext;
768     int         len;
769     static int cval;
770     Boolean     fHit = False;
771
772 /*
773  * Icon decoration parts:
774  */
775
776 #define ICON_DECOR_IMAGE_STR            (unsigned char *)"image"
777 #define ICON_DECOR_LABEL_STR            (unsigned char *)"label"
778 #define ICON_DECOR_ACTIVE_LABEL_STR     (unsigned char *)"activelabel"
779
780
781     /*
782      * Convert the icon decoration resource value:
783      */
784
785     cval = 0;
786
787     while (*pch && NextToken (pch, &len, &pchNext))
788     {
789         if ((*pch == 'A') || (*pch == 'a'))
790         {
791             if (StringsAreEqual (pch, ICON_DECOR_ACTIVE_LABEL_STR, len))
792             {
793                 cval |= ICON_ACTIVE_LABEL_PART;
794                 fHit = True;
795             }
796         }
797
798         else if ((*pch == 'I') || (*pch == 'i'))
799         {
800             if (StringsAreEqual (pch, ICON_DECOR_IMAGE_STR, len))
801             {
802                 cval |= ICON_IMAGE_PART;
803                 fHit = True;
804             }
805         }
806
807         else if ((*pch == 'L') || (*pch == 'l'))
808         {
809             if (StringsAreEqual (pch, ICON_DECOR_LABEL_STR, len))
810             {
811                 cval |= ICON_LABEL_PART;
812                 fHit = True;
813             }
814         }
815
816         pch = pchNext;
817     }
818
819     /*
820      * If we didn't match anything or only have the active label
821      * (which is just a modifier) then give 'em the whole ball of wax.
822      */
823     if (!fHit || cval == ICON_ACTIVE_LABEL_PART)
824     {
825         cval =  ICON_LABEL_PART | ICON_IMAGE_PART | ICON_ACTIVE_LABEL_PART;
826     }
827
828
829     (*toVal).size = sizeof (int);
830     (*toVal).addr = (caddr_t) &cval;
831
832 } /* END OF FUNCTION WmCvtStringToIDecor */
833
834
835 \f
836 /*************************************<->*************************************
837  *
838  *  WmCvtStringToIPlace (args, numArgs, fromVal, toVal)
839  *
840  *
841  *  Description:
842  *  -----------
843  *  This function converts a string to an icon placement scheme description.
844  *
845  *
846  *  Inputs:
847  *  ------
848  *  args = NULL (don't care)
849  *
850  *  numArgs = 0 (don't care)
851  *
852  *  fromVal = resource value to convert
853  *
854  * 
855  *  Outputs:
856  *  -------
857  *  toVal = descriptor to use to return converted value
858  *
859  *************************************<->***********************************/
860
861 void WmCvtStringToIPlace (XrmValue *args, Cardinal numArgs, XrmValue *fromVal, XrmValue *toVal)
862 {
863     unsigned char       *pch = (unsigned char *) (fromVal->addr);
864     unsigned char       *pchNext;
865     int         len;
866     static int cval;
867     Boolean     fPrimarySet = False;
868     Boolean     fSecondarySet = False;
869
870 /*
871  * Icon placement layout values:
872  */
873
874 #define ICON_PLACE_BOTTOM_STR           (unsigned char *)"bottom"
875 #define ICON_PLACE_LEFT_STR             (unsigned char *)"left"
876 #define ICON_PLACE_RIGHT_STR            (unsigned char *)"right"
877 #define ICON_PLACE_TOP_STR              (unsigned char *)"top"
878 #define ICON_PLACE_TIGHT_STR            (unsigned char *)"tight"
879
880
881     /*
882      * Convert the icon placement resource value:
883      */
884
885     cval = 0;
886
887     while (*pch && NextToken (pch, &len, &pchNext))
888     {
889         if ((*pch == 'B') || (*pch == 'b'))
890         {
891             if (StringsAreEqual (pch, ICON_PLACE_BOTTOM_STR, len))
892             {
893                 if (!fPrimarySet)
894                 {
895                     cval |= ICON_PLACE_BOTTOM_PRIMARY;
896                     fPrimarySet = True;
897                 }
898                 else if (!fSecondarySet)
899                 {
900                     if (!(cval &
901                       (ICON_PLACE_BOTTOM_PRIMARY | ICON_PLACE_TOP_PRIMARY)))
902                     {
903                         cval |= ICON_PLACE_BOTTOM_SECONDARY;
904                         fSecondarySet = True;
905                     }
906                 }
907             }
908         }
909         else if ((*pch == 'L') || (*pch == 'l'))
910         {
911             if (StringsAreEqual (pch, ICON_PLACE_LEFT_STR, len))
912             {
913                 if (!fPrimarySet)
914                 {
915                     cval |= ICON_PLACE_LEFT_PRIMARY;
916                     fPrimarySet = True;
917                 }
918                 else if (!fSecondarySet)
919                 {
920                     if (!(cval &
921                         (ICON_PLACE_LEFT_PRIMARY | ICON_PLACE_RIGHT_PRIMARY)))
922                     {
923                         cval |= ICON_PLACE_LEFT_SECONDARY;
924                         fSecondarySet = True;
925                     }
926                 }
927             }
928         }
929
930         else if ((*pch == 'R') || (*pch == 'r'))
931         {
932             if (StringsAreEqual (pch, ICON_PLACE_RIGHT_STR, len))
933             {
934                 if (!fPrimarySet)
935                 {
936                     cval |= ICON_PLACE_RIGHT_PRIMARY;
937                     fPrimarySet = True;
938                 }
939                 else if (!fSecondarySet)
940                 {
941                     if (!(cval &
942                         (ICON_PLACE_RIGHT_PRIMARY | ICON_PLACE_LEFT_PRIMARY)))
943                     {
944                         cval |= ICON_PLACE_RIGHT_SECONDARY;
945                         fSecondarySet = True;
946                     }
947                 }
948             }
949         }
950
951         else if ((*pch == 'T') || (*pch == 't'))
952         {
953             if (StringsAreEqual (pch, ICON_PLACE_TOP_STR, len))
954             {
955                 if (!fPrimarySet)
956                 {
957                     cval |= ICON_PLACE_TOP_PRIMARY;
958                     fPrimarySet = True;
959                 }
960                 else if (!fSecondarySet)
961                 {
962                     if (!(cval &
963                         (ICON_PLACE_TOP_PRIMARY | ICON_PLACE_BOTTOM_PRIMARY)))
964                     {
965                         cval |= ICON_PLACE_TOP_SECONDARY;
966                         fSecondarySet = True;
967                     }
968                 }
969             }
970
971             else if (StringsAreEqual (pch, ICON_PLACE_TIGHT_STR, len))
972             {
973                 cval |= ICON_PLACE_TIGHT;
974             }
975         }
976
977         pch = pchNext;
978     }
979
980     if (!fPrimarySet)
981     {
982         cval =  ICON_PLACE_LEFT_PRIMARY;
983     }
984     if (!fSecondarySet)
985     {
986         if (cval & (ICON_PLACE_LEFT_PRIMARY | ICON_PLACE_RIGHT_PRIMARY))
987         {
988             cval |= ICON_PLACE_BOTTOM_SECONDARY;
989         }
990         else
991         {
992             cval |= ICON_PLACE_LEFT_SECONDARY;
993         }
994     }
995
996
997     (*toVal).size = sizeof (int);
998     (*toVal).addr = (caddr_t) &cval;
999
1000 } /* END OF FUNCTION WmCvtStringToIPlace */
1001
1002
1003 \f
1004 /*************************************<->*************************************
1005  *
1006  *  WmCvtStringToKFocus (args, numArgs, fromVal, toVal)
1007  *
1008  *
1009  *  Description:
1010  *  -----------
1011  *  This function converts a string to a keyboard focus policy description.
1012  *
1013  *
1014  *  Inputs:
1015  *  ------
1016  *  args = NULL (don't care)
1017  *
1018  *  numArgs = 0 (don't care)
1019  *
1020  *  fromVal = resource value to convert
1021  *
1022  * 
1023  *  Outputs:
1024  *  -------
1025  *  toVal = descriptor to use to return converted value
1026  *
1027  *************************************<->***********************************/
1028
1029 void WmCvtStringToKFocus (XrmValue *args, Cardinal numArgs, XrmValue *fromVal, XrmValue *toVal)
1030 {
1031     unsigned char      *pch = (unsigned char *) (fromVal->addr);
1032     unsigned char      *pchNext;
1033     int        len;
1034     static int cval;
1035     Boolean    fHit = False;
1036
1037 /*
1038  * Keyboard focus policies:
1039  */
1040
1041 #define KEYBOARD_FOCUS_EXPLICIT_STR             (unsigned char *)"explicit"
1042 #define KEYBOARD_FOCUS_POINTER_STR              (unsigned char *)"pointer"
1043
1044
1045     /*
1046      * Convert the keyboard focus policy resource value:
1047      */
1048
1049     if (*pch && NextToken (pch, &len, &pchNext))
1050     {
1051         if ((*pch == 'E') || (*pch == 'e'))
1052         {
1053             if (StringsAreEqual (pch, KEYBOARD_FOCUS_EXPLICIT_STR, len))
1054             {
1055                 cval = KEYBOARD_FOCUS_EXPLICIT;
1056                 fHit = True;
1057             }
1058         }
1059
1060         else if ((*pch == 'P') || (*pch == 'p'))
1061         {
1062             if (StringsAreEqual (pch, KEYBOARD_FOCUS_POINTER_STR, len))
1063             {
1064                 cval = KEYBOARD_FOCUS_POINTER;
1065                 fHit = True;
1066             }
1067         }
1068     }
1069
1070     if (!fHit)
1071     {
1072 #if defined(sun)
1073         cval =  KEYBOARD_FOCUS_POINTER;
1074 #else
1075         cval =  KEYBOARD_FOCUS_EXPLICIT;
1076 #endif
1077     }
1078
1079
1080     (*toVal).size = sizeof (int);
1081     (*toVal).addr = (caddr_t)&cval;
1082
1083
1084 } /* END OF FUNCTION WmCvtStringToKFocus */
1085
1086
1087 \f
1088 /*************************************<->*************************************
1089  *
1090  *  WmCvtStringToSize (args, numArgs, fromVal, toVal)
1091  *
1092  *
1093  *  Description:
1094  *  -----------
1095  *  This function converts a string to a size description (<width>x<height>).
1096  *
1097  *
1098  *  Inputs:
1099  *  ------
1100  *  args = NULL (don't care)
1101  *
1102  *  numArgs = 0 (don't care)
1103  *
1104  *  fromVal = resource value to convert
1105  *
1106  * 
1107  *  Outputs:
1108  *  -------
1109  *  toVal = descriptor to use to return converted value
1110  *
1111  *************************************<->***********************************/
1112
1113 void WmCvtStringToSize (XrmValue *args, Cardinal numArgs, XrmValue *fromVal, XrmValue *toVal)
1114 {
1115     unsigned char  *pch = (unsigned char *) (fromVal->addr);
1116     unsigned char  *pchNext;
1117     static WHSize cval;
1118     int        len;
1119
1120 /*
1121  * Convenience values for WmSize:
1122  */
1123
1124 #define VERTICAL_STR    (unsigned char *)"vertical"
1125 #define HORIZONTAL_STR  (unsigned char *)"horizontal"
1126
1127
1128     /*
1129      * Convert the size resource value.  The syntax is "<width>[xX]<height>"
1130      * OR it is the string 'vertical' or 'horizontal'.  It's kinda neat that
1131      * BIGSIZE is a legal Dimension so that we get vertical and horizontal
1132      * for free.
1133      */
1134
1135     cval.width = 0;
1136     cval.height = 0;
1137
1138     if (*pch)
1139     {
1140         cval.width = (int) DecStrToL (pch, &pchNext);
1141         if (!((cval.width == 0) && (pchNext == pch)))
1142         {
1143             /*
1144              * Width was converted.
1145              * Check for a delimiter (must be 'x' or 'X'):
1146              */
1147
1148             pch = pchNext;
1149             if (*pch && ((*pch == 'x') || (*pch == 'X')))
1150             {
1151                 /*
1152                  * Delimiter found now get the height:
1153                  */
1154
1155                 pch++;
1156                 cval.height = (int) DecStrToL (pch, &pchNext);
1157             }
1158         }
1159         else
1160         {
1161             if (*pch && NextToken (pch, &len, &pchNext))
1162             {
1163                 if ((*pch == 'V') || (*pch == 'v'))
1164                 {
1165                     if (StringsAreEqual (pch, VERTICAL_STR, len))
1166                     {
1167                         cval.height = BIGSIZE;
1168                     }
1169                 }
1170                 else if ((*pch == 'H') || (*pch == 'h'))
1171                 {
1172                     if (StringsAreEqual (pch, HORIZONTAL_STR, len))
1173                     {
1174                         cval.width = BIGSIZE;
1175                     }
1176                 }
1177             }
1178         }
1179     }
1180
1181     /* !!! check for the maximum maximum sizes !!! */
1182
1183     (*toVal).size = sizeof (WHSize);
1184     (*toVal).addr = (caddr_t)&cval;
1185
1186
1187 } /* END OF FUNCTION WmCvtStringToSize */
1188
1189 \f
1190 /*************************************<->*************************************
1191  *
1192  *  WmCvtStringToShowFeedback (args, numArgs, fromVal, toVal)
1193  *
1194  *
1195  *  Description:
1196  *  -----------
1197  *  This function converts a string to a value for the showFeedback flag set.
1198  *
1199  *
1200  *  Inputs:
1201  *  ------
1202  *  args = NULL (don't care)
1203  *
1204  *  numArgs = 0 (don't care)
1205  *
1206  *  fromVal = resource value to convert
1207  *
1208  * 
1209  *  Outputs:
1210  *  -------
1211  *  toVal = descriptor to use to return converted value
1212  *
1213  *************************************<->***********************************/
1214
1215 void WmCvtStringToShowFeedback (XrmValue *args, Cardinal numArgs, XrmValue *fromVal, XrmValue *toVal)
1216 {
1217     unsigned char       *pch = (unsigned char *) (fromVal->addr);
1218     unsigned char       *pchNext;
1219     int         len;
1220     static int cval;
1221     Boolean     fHit = False;
1222     Boolean    fAddNext = True;
1223
1224 /*
1225  * Names of feedback options
1226  */
1227
1228 #define SHOW_FB_ALL_STR         (unsigned char *)"all"
1229 #define SHOW_FB_BEHAVIOR_STR    (unsigned char *)"behavior"
1230 #define SHOW_FB_KILL_STR        (unsigned char *)"kill"
1231 #define SHOW_FB_MOVE_STR        (unsigned char *)"move"
1232 #define SHOW_FB_NONE_STR        (unsigned char *)"none"
1233 #define SHOW_FB_PLACEMENT_STR   (unsigned char *)"placement"
1234 #define SHOW_FB_QUIT_STR        (unsigned char *)"quit"
1235 #define SHOW_FB_RESIZE_STR      (unsigned char *)"resize"
1236 #define SHOW_FB_RESTART_STR     (unsigned char *)"restart"
1237
1238     /*
1239      * Check first token. If '-' we subtract from all functions.
1240      * Otherwise, we start with no functions and add things in.
1241      */
1242
1243     if (*pch &&
1244         (NextToken (pch, &len, &pchNext)) &&
1245         (*pch == '-'))
1246     {
1247         cval = WM_SHOW_FB_DEFAULT;
1248         fHit = True;
1249     }
1250     else
1251     {
1252         cval = WM_SHOW_FB_NONE;
1253     }
1254
1255
1256     /*
1257      * Convert the feedback option resource value:
1258      */
1259
1260
1261     while (*pch && NextToken (pch, &len, &pchNext))
1262     {
1263            /*
1264             * Strip off "sign" if prepended to another token, and process
1265             * that token the next time through.
1266             */
1267
1268         if (*pch == '+')
1269         {
1270             if (len != 1)
1271             {
1272                 pchNext = pch + 1;
1273             }
1274             fAddNext = TRUE;
1275         }
1276
1277         else if (*pch == '-')
1278         {
1279             if (len != 1)
1280             {
1281                 pchNext = pch + 1;
1282             }
1283             fAddNext = FALSE;
1284         }
1285
1286         if ((*pch == 'A') || (*pch == 'a'))
1287         {
1288             if (StringsAreEqual (pch, SHOW_FB_ALL_STR, len))
1289             {
1290                 cval = fAddNext ? (cval | WM_SHOW_FB_ALL) :
1291                                   (cval & ~WM_SHOW_FB_ALL);
1292                 fHit = True;
1293             }
1294         }
1295
1296         else if ((*pch == 'B') || (*pch == 'b'))
1297         {
1298             if (StringsAreEqual (pch, SHOW_FB_BEHAVIOR_STR, len))
1299             {
1300                 cval = fAddNext ? (cval | WM_SHOW_FB_BEHAVIOR) :
1301                                   (cval & ~WM_SHOW_FB_BEHAVIOR);
1302                 fHit = True;
1303             }
1304         }
1305
1306         else if ((*pch == 'K') || (*pch == 'k'))
1307         {
1308             if (StringsAreEqual (pch, SHOW_FB_KILL_STR, len))
1309             {
1310                 cval = fAddNext ? (cval | WM_SHOW_FB_KILL) :
1311                                   (cval & ~WM_SHOW_FB_KILL);
1312                 fHit = True;
1313             }
1314         }
1315
1316         else if ((*pch == 'M') || (*pch == 'm'))
1317         {
1318             if (StringsAreEqual (pch, SHOW_FB_MOVE_STR, len))
1319             {
1320                 cval = fAddNext ? (cval | WM_SHOW_FB_MOVE) :
1321                                   (cval & ~WM_SHOW_FB_MOVE);
1322                 fHit = True;
1323             }
1324         }
1325
1326         else if ((*pch == 'N') || (*pch == 'n'))
1327         {
1328             if (StringsAreEqual (pch, SHOW_FB_NONE_STR, len))
1329             {
1330                 /* don't bother adding or subtracting nothing */
1331                 fHit = True;
1332             }
1333         }
1334
1335         else if ((*pch == 'P') || (*pch == 'p'))
1336         {
1337             if (StringsAreEqual (pch, SHOW_FB_PLACEMENT_STR, len))
1338             {
1339                 cval = fAddNext ? (cval | WM_SHOW_FB_PLACEMENT) :
1340                                   (cval & ~WM_SHOW_FB_PLACEMENT);
1341                 fHit = True;
1342             }
1343         }
1344
1345         else if ((*pch == 'Q') || (*pch == 'q'))
1346         {
1347             if (StringsAreEqual (pch, SHOW_FB_QUIT_STR, len))
1348             {
1349                 cval = fAddNext ? (cval | WM_SHOW_FB_QUIT) :
1350                                   (cval & ~WM_SHOW_FB_QUIT);
1351                 fHit = True;
1352             }
1353         }
1354
1355         else if ((*pch == 'R') || (*pch == 'r'))
1356         {
1357             if (StringsAreEqual (pch, SHOW_FB_RESIZE_STR, len))
1358             {
1359                 cval = fAddNext ? (cval | WM_SHOW_FB_RESIZE) :
1360                                   (cval & ~WM_SHOW_FB_RESIZE);
1361                 fHit = True;
1362             }
1363             else if (StringsAreEqual (pch, SHOW_FB_RESTART_STR, len))
1364             {
1365                 cval = fAddNext ? (cval | WM_SHOW_FB_RESTART) :
1366                                   (cval & ~WM_SHOW_FB_RESTART);
1367                 fHit = True;
1368             }
1369         }
1370         pch = pchNext;
1371     }
1372
1373
1374
1375     /*
1376      * If we didn't match anything then set to default.
1377      */
1378     if (!fHit)
1379     {
1380         cval =  WM_SHOW_FB_DEFAULT;
1381     }
1382
1383
1384     (*toVal).size = sizeof (int);
1385     (*toVal).addr = (caddr_t) &cval;
1386
1387 } /* END OF FUNCTION WmCvtStringToShowFeedback */
1388
1389
1390 \f
1391 /*************************************<->*************************************
1392  *
1393  *  WmCvtStringToUsePPosition (args, numArgs, fromVal, toVal)
1394  *
1395  *
1396  *  Description:
1397  *  -----------
1398  *  This function converts a string to a keyboard focus policy description.
1399  *
1400  *
1401  *  Inputs:
1402  *  ------
1403  *  args = NULL (don't care)
1404  *
1405  *  numArgs = 0 (don't care)
1406  *
1407  *  fromVal = resource value to convert
1408  *
1409  * 
1410  *  Outputs:
1411  *  -------
1412  *  toVal = descriptor to use to return converted value
1413  *
1414  *************************************<->***********************************/
1415
1416 void WmCvtStringToUsePPosition (XrmValue *args, Cardinal numArgs, XrmValue *fromVal, XrmValue *toVal)
1417 {
1418     unsigned char      *pch = (unsigned char *) (fromVal->addr);
1419     unsigned char      *pchNext;
1420     int        len;
1421     static int cval;
1422     Boolean    fHit = False;
1423
1424
1425 #define USE_PPOSITION_NONZERO_STR       (unsigned char *)"nonzero"
1426 #define USE_PPOSITION_ON_STR            (unsigned char *)"on"
1427 #define USE_PPOSITION_OFF_STR           (unsigned char *)"off"
1428
1429     /*
1430      * Convert the use PPosition resource value:
1431      */
1432
1433     if (*pch && NextToken (pch, &len, &pchNext))
1434     {
1435         if ((*pch == 'N') || (*pch == 'n'))
1436         {
1437             if (StringsAreEqual (pch, USE_PPOSITION_NONZERO_STR, len))
1438             {
1439                 cval = USE_PPOSITION_NONZERO;
1440                 fHit = True;
1441             }
1442         }
1443         else if (StringsAreEqual (pch, USE_PPOSITION_OFF_STR, len))
1444         {
1445             cval = USE_PPOSITION_OFF;
1446             fHit = True;
1447         }
1448         else if (StringsAreEqual (pch, USE_PPOSITION_ON_STR, len))
1449         {
1450             cval = USE_PPOSITION_ON;
1451             fHit = True;
1452         }
1453     }
1454
1455     if (!fHit)
1456     {
1457         cval =  USE_PPOSITION_NONZERO;
1458     }
1459
1460     (*toVal).size = sizeof (int);
1461     (*toVal).addr = (caddr_t)&cval;
1462
1463
1464 } /* END OF FUNCTION WmCvtStringToUsePPosition */
1465
1466 \f
1467 /*************************************<->*************************************
1468  *
1469  *  NextToken (pchIn, pLen, ppchNext)
1470  *
1471  *
1472  *  Description:
1473  *  -----------
1474  *  XXDescription ...
1475  *
1476  *
1477  *  Inputs:
1478  *  ------
1479  *  pchIn = pointer to start of next token
1480  *
1481  * 
1482  *  Outputs:
1483  *  -------
1484  *  pLen  =    pointer to integer containing number of characters in next token
1485  *  ppchNext = address of pointer to following token
1486  *
1487  *  Return =   next token or NULL
1488  *
1489  *
1490  *  Comments:
1491  *  --------
1492  *  None.
1493  * 
1494  *************************************<->***********************************/
1495
1496 unsigned char *NextToken (unsigned char *pchIn, int *pLen, 
1497         unsigned char **ppchNext)
1498 {
1499     unsigned char *pchR = pchIn;
1500     int   i;
1501
1502     int   chlen;
1503
1504     for (i = 0;
1505          ((chlen = mblen((char *)pchIn, MB_CUR_MAX)) > 0) && (pchIn[0] != '\0');
1506          i++)
1507     /* find end of word: requires singlebyte whitespace terminator */
1508     {
1509         if ((chlen == 1) && isspace (*pchIn))
1510         {
1511             break;
1512         }
1513         pchIn += chlen;
1514     }
1515
1516     /* skip to next word */
1517     ScanWhitespace (&pchIn);
1518
1519     *ppchNext = pchIn;
1520     *pLen = i;
1521     if (i)
1522     {
1523         return(pchR);
1524     }
1525     else
1526     {
1527        return(NULL);
1528     }
1529
1530 } /* END OF FUNCTION NextToken */   
1531
1532
1533 \f
1534 /*************************************<->*************************************
1535  *
1536  *  StringsAreEqual (pch1, pch2, len)
1537  *
1538  *
1539  *  Description:
1540  *  -----------
1541  *  XXDescription ...
1542  *
1543  *
1544  *  Inputs:
1545  *  ------
1546  *  pch1 =
1547  *  pch2 =
1548  *  len  =
1549  *
1550  * 
1551  *  Outputs:
1552  *  -------
1553  *  Return = (Boolean) True iff strings match (case insensitive)
1554  *
1555  *
1556  *  Comments:
1557  *  --------
1558  *  None.
1559  * 
1560  *************************************<->***********************************/
1561
1562 Boolean StringsAreEqual (unsigned char *pch1, unsigned char *pch2, int len)
1563 {
1564     int       chlen1;
1565     int       chlen2;
1566     wchar_t   wch1;
1567     wchar_t   wch2;
1568
1569     while (len  && 
1570            ((chlen1 = mbtowc (&wch1, (char *) pch1, MB_CUR_MAX)) > 0) &&
1571            ((chlen2 = mbtowc (&wch2, (char *) pch2, MB_CUR_MAX)) == chlen1) )
1572     {
1573         if (chlen1 == 1)
1574         /* singlebyte characters -- make case insensitive */
1575         {
1576             if ((isupper (*pch1) ? tolower(*pch1) : *pch1) !=
1577                 (isupper (*pch2) ? tolower(*pch2) : *pch2))
1578             {
1579                 break;
1580             }
1581         }
1582         else
1583         /* multibyte characters */
1584         {
1585             if (wch1 != wch2)
1586             {
1587                 break;
1588             }
1589         }
1590         pch1 += chlen1;
1591         pch2 += chlen2;
1592         len--;
1593     }
1594
1595     return (len == 0);
1596
1597 } /* END OF StringsAreEqual */   
1598
1599 \f
1600 /*************************************<->*************************************
1601  *
1602  *  long
1603  *  DecStrToL (str, ptr)
1604  *
1605  *
1606  *  Description:
1607  *  -----------
1608  *  Converts a decimal string to a long.
1609  *
1610  *
1611  *  Inputs:
1612  *  ------
1613  *  str = character string
1614  *
1615  * 
1616  *  Outputs:
1617  *  -------
1618  *  *ptr = pointer to character terminating str or str
1619  *  Return = long value
1620  *
1621  *
1622  *  Comments:
1623  *  --------
1624  *  Leading whitespace is ignored.
1625  *  Returns long value with *ptr pointing at character terminating the decimal
1626  *    string.
1627  *  Returns 0 with *ptr == str if no integer can be formed.
1628  * 
1629  *************************************<->***********************************/
1630
1631 long DecStrToL (unsigned char *str, unsigned char **ptr)
1632 {
1633     long  val = 0;
1634
1635     *ptr = str;
1636     while ((mblen ((char *)str, MB_CUR_MAX) == 1) && isspace (*str))
1637     /* Ignore leading whitespace */
1638     {
1639         str++;
1640     }
1641
1642     /* If we can start, we will reset *ptr */
1643     if ((mblen ((char *)str, MB_CUR_MAX) == 1) && isdigit (*str))
1644     {
1645         while ((mblen ((char *)str, MB_CUR_MAX) == 1) && isdigit (*str))
1646         {
1647             val = val * 10 + (*str - '0');
1648             str++;
1649         }
1650
1651         *ptr = str;
1652     }
1653
1654     return (val);
1655
1656 } /* END OF FUNCTION DecStrToL */
1657