earlybrowserreborn - Blame information for rev 1

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 roytam 1 #include <Mrm/MrmAppl.h>                        /* Motif Toolkit and MRM */
2 #include "midaslist.h"
3 #include "midaserrors.h"
4 #include "midasoperand.h"
5 #include "midasconvert.h"
6 #include <X11/cursorfont.h>
7 #include <X11/CoreP.h>
8 #include <stdlib.h>
9  
10 typedef Boolean (*cr)();
11  
12 static List ConverterList;
13 static List MidasClassList;
14 Widget MidasGetActiveWidget();
15  
16 ConvertBlock *MidasFindStringConverter(Type)
17 MidasType Type;
18 {
19     ListItem *item;
20     char buffer[256];
21     strcpy(buffer,MString);
22     strcat(buffer,".");
23     strcat(buffer,Type);
24     item = MidasFindItemInList(&ConverterList,buffer);
25     if (item == 0) MidasError("Could not find converter for %s to %s",MString,Type);
26     return item->Pointer;
27 }
28 static Boolean MidasConversionConverter(display,args,nargs,from,to,converter_data)
29     Display    *display;
30     XrmValue   *args;
31     Cardinal   *nargs;
32     XrmValue   *from;
33     XrmValue   *to;
34     XtPointer  *converter_data;
35 {
36     cr ConvertRtn = (cr) args[0].addr;
37     MidasOperand FromOp, ToOp;
38     XtPointer new;
39     int size;
40  
41     FromOp.Value.P = from->addr;
42     FromOp.Type = args[1].addr;
43     FromOp.Dynamic = FALSE;
44  
45     ToOp.Dynamic = FALSE;
46     ToOp.Type = args[2].addr;
47  
48     printf("Converting %s to %s rtn=%x\n",FromOp.Type,ToOp.Type,ConvertRtn);
49     if (!ConvertRtn(&FromOp,&ToOp)) return FALSE;
50  
51     new = ToOp.Value.P;
52     if (strcmp(ToOp.Type,"String")) size = sizeof(new);
53     else size = strlen((char *) new) + 1;
54  
55     if (to->addr == 0)
56       {
57          to->addr = new;
58          to->size = size;
59          return TRUE;
60       }
61     else if  (to->size >= size)
62       {
63          strcpy(to->addr,new);
64          to->size = size;
65          return TRUE;
66       }
67     else
68       {
69          to->size = size;
70          return FALSE;
71       }
72  
73 }
74 void MidasDeclareConverter(FromType,ToType,ConvertRtn)
75      MidasType FromType;
76      MidasType ToType;
77      cr        ConvertRtn;
78 {
79      char *name = XtMalloc(strlen(FromType)+strlen(ToType)+2);
80      ListItem *item;
81  
82      strcpy(name,FromType);
83      strcat(name,".");
84      strcat(name,ToType);
85      item = MidasFindItemInList(&ConverterList,name);
86      if (item != 0)
87        {
88          XtFree(name);
89          MidasError("Duplicate converter for %s to %s ignored",FromType,ToType);
90        }
91      else
92        {
93          ConvertBlock *ab = XtNew(ConvertBlock);
94 /*
95          XtConvertArgRec  ConvertArgs[] = {{XtAddress  ,(XtPointer)ConvertRtn ,sizeof(XtPointer)},
96                                            {XtAddress  ,(XtPointer)FromType   ,strlen(FromType)+1} ,
97                                            {XtAddress  ,(XtPointer)ToType     ,strlen(ToType)+1}};
98 */
99          item = MidasAddItemToList(&ConverterList,name);
100          item->Pointer = ab;
101          ab->ConvertRtn = ConvertRtn;
102          ab->FromType = FromType;
103          ab->ToType = ToType;
104 /*
105          printf("Convert %s to %s rtn=%x\n",FromType ,ToType,ConvertRtn);
106          XtSetTypeConverter(FromType,ToType,MidasConversionConverter,
107                             &ConvertArgs,XtNumber(ConvertArgs),XtCacheNone);
108 */
109        }
110      XtFree(name);
111 }
112 void MidasDeclareStringConverter(ToType,ConvertRtn)
113      MidasType ToType;
114      Boolean (*ConvertRtn)();
115 {
116      MidasDeclareConverter(MString,ToType,ConvertRtn);
117 }
118 Boolean MidasConvertOperandInternal(Operand,Type)
119 MidasOperand *Operand;
120 MidasType Type;
121 {
122   MidasOperand Temp;
123   char name[256];
124   ListItem *item;
125   ConvertBlock *cb;
126   Boolean ok;
127  
128   if (strcmp(Operand->Type,Type) == 0) return TRUE;
129  
130   if (strcmp(Type,"any") == 0)
131     {
132       MidasOperand *new = XtNew(MidasOperand);
133       *new = *Operand;
134       Operand->Type = "any";
135       Operand->Dynamic = TRUE;
136       Operand->Value.P = (XtPointer) new;
137       return TRUE;
138     }
139  
140   strcpy(name,Operand->Type);
141   strcat(name,".");
142   strcat(name,Type);
143   item = MidasFindItemInList(&ConverterList,name);
144  
145   if (item == 0)
146     {
147       /*
148        * Maybe the intrinsics can do the job for us?
149        *
150        */
151  
152       XrmValue from, to;
153       Widget ActiveWidget = MidasGetActiveWidget();
154       int result;
155  
156       if (strcmp(Operand->Type,MString) == 0)
157         {
158           from.size = strlen(Operand->Value.P) + 1;
159           from.addr = Operand->Value.P;
160         }
161       else
162         {
163           from.size = sizeof(Operand->Value.P);
164           from.addr = Operand->Value.P;
165         }
166       to.addr = (XtPointer) &result;
167       to.size = sizeof(result);
168  
169       MidasSuppressXtWarningMessages();
170  
171       ok = XtConvertAndStore(ActiveWidget,Operand->Type,&from,Type,&to);
172  
173       MidasReenableXtWarningMessages();
174  
175       if (ok)
176         {
177           if (to.size == sizeof(result)) Operand->Value.I = result;
178           else
179             {
180               short s;
181               memcpy(&s,to.addr,to.size);
182               Operand->Value.I = s;
183             }
184         }
185       else if (to.size>sizeof(result))
186         {
187           to.addr = XtMalloc(to.size);
188           ok = XtConvertAndStore(ActiveWidget,Operand->Type,&from,Type,&to);
189  
190           Operand->Value.P = to.addr;
191           Operand->Dynamic = TRUE;
192         }
193       if (ok)
194         {
195           Operand->Type = Type;
196           return ok;
197         }
198  
199       if (strcmp(Type,MString) == 0)
200         {
201           char *p = XtMalloc(12);
202           sprintf(p,"%d",Operand->Value.I);
203  
204           if (Operand->Dynamic) XtFree(Operand->Value.P);
205           Operand->Value.P = p;
206           Operand->Dynamic = TRUE;
207           Operand->Type = MString;
208           return TRUE;
209         }
210       MidasError("No converter declared for %s to %s",Operand->Type,Type);
211     }
212  
213   cb = item->Pointer;
214  
215   Temp.Dynamic = FALSE;
216   Temp.Type = Type;
217  
218   ok = cb->ConvertRtn(Operand,&Temp);
219  
220   if (ok)
221     {
222       if (Operand->Dynamic) XtFree(Operand->Value.P);
223       *Operand = Temp;
224     }
225  
226   return ok;
227 }
228 void MidasConvertOperand(Operand,Type)
229 MidasOperand *Operand;
230 MidasType Type;
231 {
232   Boolean ok = MidasConvertOperandInternal(Operand, Type);
233   if (ok) return;
234  
235   /* Try to report error as best we can */
236  
237   if (strcmp(Operand->Type,MString) == 0)
238     MidasError("Can not convert %s from %s to %s",Operand->Value.P,Operand->Type,Type);
239  
240   else if (strcmp(Type,MString) == 0)
241     MidasError("Can not convert operand from %s to %s",Operand->Type,Type);
242  
243   else
244     {
245       ok = MidasConvertOperandInternal(Operand, MString);
246       if (ok)
247         MidasError("Can not convert %s from %s to %s",Operand->Value.P,Operand->Type,Type);
248       else
249         MidasError("Can not convert operand from %s to %s",Operand->Type,Type);
250     }
251 }
252 static MidasOperand MidasConvertForce(Operand,Type)
253 MidasOperand *Operand;
254 char *Type;
255 {
256    MidasOperand Temp;
257    Temp = *Operand;
258    MidasConvertOperand(&Temp,XtNewString(Type)); /* bug ... never freed */
259    return Temp;
260 }
261 static Boolean MidasConvertBooleanString(In,Out)
262 MidasOperand *In;
263 MidasOperand *Out;
264 {
265    if (In->Value.I) Out->Value.P = "True";
266    else             Out->Value.P = "False";
267    return TRUE;
268 }
269 static Boolean MidasConvertIntString(In,Out)
270 MidasOperand *In;
271 MidasOperand *Out;
272 {
273    char *new = XtMalloc(12);
274    sprintf(new,"%d",In->Value.P);
275    Out->Value.P = new;
276    return TRUE;
277 }
278 static Boolean MidasConvertFloatString(In,Out)
279 MidasOperand *In;
280 MidasOperand *Out;
281 {
282    char *new = XtMalloc(20);
283    sprintf(new,"%f",In->Value.F);
284    Out->Value.P = new;
285    return TRUE;
286 }
287 static Boolean MidasConvertStringBoolean(In,Out)
288 MidasOperand *In;
289 MidasOperand *Out;
290 {
291   if      (strcmp(In->Value.P,"True" ) == 0) Out->Value.I = TRUE;
292   else if (strcmp(In->Value.P,"true" ) == 0) Out->Value.I = TRUE;
293   else if (strcmp(In->Value.P,"TRUE" ) == 0) Out->Value.I = TRUE;
294   else if (strcmp(In->Value.P,"False") == 0) Out->Value.I = FALSE;
295   else if (strcmp(In->Value.P,"false") == 0) Out->Value.I = FALSE;
296   else if (strcmp(In->Value.P,"FALSE") == 0) Out->Value.I = FALSE;
297   else return FALSE;
298  
299   return TRUE;
300 }
301 static Boolean MidasConvertStringXmString(In,Out)
302 MidasOperand *In;
303 MidasOperand *Out;
304 {
305    Out->Value.P = (XtPointer) MidasCharToString(In->Value.P);
306    Out->Dynamic = TRUE; /* Need special destructor for this ??? */
307    return TRUE;
308 }
309 static Boolean MidasConvertStringUpperName(In,Out)
310 MidasOperand *In;
311 MidasOperand *Out;
312 {
313    char *p = In->Value.P;
314  
315    for (; *p != '\0'; p++) *p = toupper(*p);
316  
317    Out->Value.P = In->Value.P;
318    Out->Dynamic = In->Dynamic;
319    In->Dynamic = FALSE;
320    return TRUE;
321 }
322 static Boolean MidasConvertStringName(In,Out)
323 MidasOperand *In;
324 MidasOperand *Out;
325 {
326    Out->Value.P = In->Value.P;
327    Out->Dynamic = In->Dynamic;
328    In->Dynamic = FALSE;
329    return TRUE;
330 }
331 static Boolean MidasConvertStringInt(In,Out)
332 MidasOperand *In;
333 MidasOperand *Out;
334 {
335    char *End;
336  
337    Out->Value.P = (XtPointer) strtol((char *)In->Value.P,&End,10);
338    return (*End == '\0');
339 }    
340 static Boolean MidasConvertStringFloat(In,Out)
341 MidasOperand *In;
342 MidasOperand *Out;
343 {
344    char *End;
345  
346    Out->Value.F = strtod(In->Value.P,&End);
347    return (*End == '\0');
348 }
349 static Boolean MidasConvertStringWidget(In,Out)
350 MidasOperand *In;
351 MidasOperand *Out;
352 {
353    Out->Value.P = (XtPointer) MidasFindWidget(In->Value.P);
354    return TRUE;
355 }
356 static Boolean MidasConvertStringIcon(In,Out)
357 MidasOperand *In;
358 MidasOperand *Out;
359 {
360    Out->Value.P = (XtPointer) MidasFetchIcon(In->Value.P,NULL);
361    return TRUE;
362 }
363 static Boolean MidasConvertStringClass(In,Out)
364 MidasOperand *In;
365 MidasOperand *Out;
366 {
367    ListItem *i = MidasFindItemInList(&MidasClassList,In->Value.P);
368    if (i == 0) return FALSE;
369    Out->Value.P = i->Pointer;
370    return TRUE;
371 }
372 void MidasDeclareClass(Class)
373 CoreClassPart *Class;
374 {
375     ListItem *i = MidasFindItemInList(&MidasClassList,Class->class_name);
376     if (i==0)
377       {
378         i = MidasAddItemToList(&MidasClassList,Class->class_name);
379         i->Pointer = Class;
380       }
381 }
382 static Boolean MidasConvertStringAny(In,Out)
383 MidasOperand *In;
384 MidasOperand *Out;
385 {
386    return FALSE;
387 }
388 static Boolean MidasConvertIntNumber(In,Out)
389 MidasOperand *In;
390 MidasOperand *Out;
391 {
392    *Out = *In;
393    return TRUE;
394 }
395 static Boolean MidasConvertFloatNumber(In,Out)
396 MidasOperand *In;
397 MidasOperand *Out;
398 {
399    *Out = *In;
400    return TRUE;
401 }
402 static Boolean MidasConvertIntFloat(In,Out)
403 MidasOperand *In;
404 MidasOperand *Out;
405 {
406    Out->Value.F = (float) In->Value.I;
407    return TRUE;
408 }
409 /*
410  *
411  *  Converting shorts to Ints in a portable way is not trivial
412  *
413  */
414 static Boolean MidasConvertIntShort(In,Out)
415 MidasOperand *In;
416 MidasOperand *Out;
417 {
418    if (In->Value.I > 32767 || In->Value.I < -32768) return FALSE;
419    Out->Value.I = In->Value.I;
420    return TRUE;
421 }
422 static Boolean MidasConvertShortInt(In,Out)
423 MidasOperand *In;
424 MidasOperand *Out;
425 {
426    printf("%x\n",In->Value.I);
427    printf("%x\n",In->Value.S);
428    Out->Value.I = (int) In->Value.S;
429    printf("%x\n",Out->Value.I);
430    return TRUE;
431 }
432 static Boolean MidasConvertStringNumber(In,Out)
433 MidasOperand *In;
434 MidasOperand *Out;
435 {
436    Boolean ok;
437  
438    ok = MidasConvertStringInt(In,Out);
439    if (ok) { Out->Type = MInt;  return ok; }
440  
441    ok = MidasConvertStringFloat(In,Out);
442    if (ok) { Out->Type = MFloat;  return ok; }
443  
444    return ok;
445 }
446 static Boolean MidasConvertStringCursor(In,Out)
447 MidasOperand *In;
448 MidasOperand *Out;
449 {
450    int r;
451    if      (strcmp(In->Value.P,""     ) == 0) r = 0;
452    else if (strcmp(In->Value.P,"watch") == 0) r = XC_watch;
453    else if (strcmp(In->Value.P,"trek" ) == 0) r = XC_trek;
454    else return False;
455  
456    Out->Value.I = r;
457    return True;
458 }
459 static Boolean MidasConvertStringAtom(In,Out)
460 MidasOperand *In;
461 MidasOperand *Out;
462 {
463    XrmValue source, dest;
464    Atom result;
465    Widget ActiveWidget = MidasGetActiveWidget();
466  
467    source.size = strlen(In->Value.P) + 1;
468    source.addr = In->Value.P;
469  
470    dest.size = sizeof(Atom);
471    dest.addr = (XtPointer) &result;  
472  
473    XtConvertAndStore(ActiveWidget,XtRString,&source,XtRAtom,&dest);
474  
475    Out->Value.P = (XtPointer) result;
476    return True;
477 }
478 void MidasConvertInit()
479 {
480     ConverterList = NullList;
481     MidasClassList = NullList;
482  
483     MidasDeclareStringConverter("name",       MidasConvertStringName);
484     MidasDeclareStringConverter("upname",     MidasConvertStringUpperName);
485     MidasDeclareStringConverter("Widget",     MidasConvertStringWidget);  
486     MidasDeclareStringConverter("list",       MidasConvertStringList);
487     MidasDeclareStringConverter("Int",        MidasConvertStringInt);    
488     MidasDeclareStringConverter("Float",      MidasConvertStringFloat);
489     MidasDeclareStringConverter("Icon",       MidasConvertStringIcon);
490     MidasDeclareStringConverter("Boolean",    MidasConvertStringBoolean);  
491     MidasDeclareStringConverter("any",        MidasConvertStringAny);
492     MidasDeclareStringConverter("XmString",   MidasConvertStringXmString);
493     MidasDeclareStringConverter("MenuWidget", MidasConvertStringWidget);
494     MidasDeclareStringConverter("Pixmap",     MidasConvertStringIcon);
495     MidasDeclareStringConverter("Cursor",     MidasConvertStringCursor);  
496     MidasDeclareStringConverter("Class",      MidasConvertStringClass);
497     MidasDeclareStringConverter("Atom",       MidasConvertStringAtom);
498  
499     /*
500      * Although the intrinsics have converters for Shell*Dim they rely
501      * an ACTUALLY getting a shell widget. Thus we need these two extra  
502      * lines here (otherwise MidasWWW show source can bomb).
503      */
504  
505     MidasDeclareStringConverter("ShellVertDim",  MidasConvertStringInt);    
506     MidasDeclareStringConverter("ShellHorizDim", MidasConvertStringInt);    
507  
508     MidasDeclareConverter("Boolean","String", MidasConvertBooleanString);
509     MidasDeclareConverter("Boolean","name",   MidasConvertBooleanString);
510     MidasDeclareConverter("Int","String",     MidasConvertIntString);
511     MidasDeclareConverter("Int","name",       MidasConvertIntString);
512     MidasDeclareConverter("Float","String",   MidasConvertFloatString);
513     MidasDeclareConverter("String","Number",  MidasConvertStringNumber);
514     MidasDeclareConverter("Int","Number",     MidasConvertIntNumber);
515     MidasDeclareConverter("Float","Number",   MidasConvertFloatNumber);
516     MidasDeclareConverter("Int","Float",      MidasConvertIntFloat);
517     MidasDeclareConverter("Int","Short",      MidasConvertIntShort);
518     MidasDeclareConverter("Int","HorizontalDimension",MidasConvertIntShort);
519     MidasDeclareConverter("Int","VerticalDimension"  ,MidasConvertIntShort);
520     MidasDeclareConverter("Int","ShellHorizPos"      ,MidasConvertIntShort);
521     MidasDeclareConverter("Int","ShellVertPos"       ,MidasConvertIntShort);
522     MidasDeclareConverter("HorizontalDimension","Int",MidasConvertShortInt);
523     MidasDeclareConverter("VerticalDimension","Int"  ,MidasConvertShortInt);
524     MidasDeclareConverter("HorizontalDimension","Number",MidasConvertShortInt);
525     MidasDeclareConverter("VerticalDimension","Number"  ,MidasConvertShortInt);
526  
527     MidasDeclareFunction("CONVERT(any,name)",MidasConvertForce);
528  
529     MidasClassInit();
530 }