1 /*
2  * $Id: ox11menu.c,v 1.7 2003/02/16 12:43:37 isizaka Exp isizaka $
3  *
4  * This file is part of "Ngraph for X11".
5  *
6  * Copyright (C) 2002, Satoshi ISHIZAKA. isizaka@msa.biglobe.ne.jp
7  *
8  * "Ngraph for X11" is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License
10  * as published by the Free Software Foundation; either version 2
11  * of the License, or (at your option) any later version.
12  *
13  * "Ngraph for X11" is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
21  *
22  */
23 
24 /**
25  *
26  * $Log: ox11menu.c,v $
27  * Revision 1.7  2003/02/16 12:43:37  isizaka
28  * for release 6.13.18
29  *
30  * Revision 1.6  2002/07/06 08:57:25  isizaka
31  * change to GPL.
32  *
33  * Revision 1.5  2001/07/14 17:44:50  isizaka
34  * for 6.03.14
35  *
36  * Revision 1.4  2001/03/23 12:17:43  isizaka
37  * for 6.3.13
38  *
39  * Revision 1.3  1999/04/15 12:14:26  isizaka
40  * for release 6.03.01
41  *
42  * Revision 1.2  1999/03/20 12:32:54  isizaka
43  * minor change
44  *
45  * Revision 1.1  1999/03/17 13:28:18  isizaka
46  * Initial revision
47  *
48  *
49  **/
50 
51 #include <Xm/XmAll.h>
52 #include <stdio.h>
53 #include <string.h>
54 #include <stdlib.h>
55 #include <stdarg.h>
56 #include <limits.h>
57 #include <math.h>
58 #include <time.h>
59 #include <ctype.h>
60 
61 #include "ngraph.h"
62 #include "object.h"
63 #include "ioutil.h"
64 #include "shell.h"
65 #include "nstring.h"
66 #include "jnstring.h"
67 #include "config.h"
68 #include "mathfn.h"
69 #include "gra.h"
70 #include "spline.h"
71 
72 #include "ox11menu.h"
73 #include "x11menu.h"
74 
75 #define NAME "menu"
76 #define ALIAS "winmenu:x11menu"
77 #define PARENT "gra2"
78 #define VERSION  "1.00.00"
79 #define MX11CONF "[x11menu]"
80 #define G2WINCONF "[gra2x11]"
81 #define TRUE  1
82 #define FALSE 0
83 
84 #define ERRNUM 3
85 
86 char *menuerrorlist[ERRNUM]={
87   "already running.",
88   "not enough color cell.",
89   "cannot create font. Check `windowfont' resource.",
90 };
91 
92 extern int OpenApplication();
93 
94 struct menulocal menulocal;
95 struct mxlocal *mxlocal;
96 struct savedstdio x11iosave;
97 
mx11loadconfig()98 int mx11loadconfig()
99 {
100   FILE *fp;
101   char *tok,*str,*s2;
102   char *f1,*f2,*f3,*f4,*f5;
103   int val;
104   char *endptr;
105   int len;
106   struct fontmap *fcur,*fnew;
107   struct extprinter *pcur,*pnew;
108   struct prnprinter *pcur2,*pnew2;
109   struct script *scur,*snew;
110 
111   if ((fp=openconfig(MX11CONF))==NULL) return 0;
112   fcur=mxlocal->fontmaproot;
113   pcur=menulocal.extprinterroot;
114   pcur2=menulocal.prnprinterroot;
115   scur=menulocal.scriptroot;
116   while ((tok=getconfig(fp,&str))!=NULL) {
117     s2=str;
118     if (strcmp(tok,"mouse_click")==0) {
119       f1=getitok2(&s2,&len," \t,");
120       if (f1!=NULL) {
121         val=strtol(f1,&endptr,10);
122         if (endptr[0]=='\0') menulocal.mouseclick=val;
123       }
124       memfree(f1);
125     } else if (strcmp(tok,"script_console")==0) {
126       f1=getitok2(&s2,&len," \t,");
127       if (f1!=NULL) {
128         val=strtol(f1,&endptr,10);
129         if (endptr[0]=='\0') menulocal.scriptconsole=val;
130       }
131       memfree(f1);
132     } else if (strcmp(tok,"addin_console")==0) {
133       f1=getitok2(&s2,&len," \t,");
134       if (f1!=NULL) {
135         val=strtol(f1,&endptr,10);
136         if (endptr[0]=='\0') menulocal.addinconsole=val;
137       }
138       memfree(f1);
139     } else if (strcmp(tok,"change_directory")==0) {
140       f1=getitok2(&s2,&len," \t,");
141       if (f1!=NULL) {
142         val=strtol(f1,&endptr,10);
143         if (endptr[0]=='\0') menulocal.changedirectory=val;
144       }
145       memfree(f1);
146     } else if (strcmp(tok,"save_history")==0) {
147       f1=getitok2(&s2,&len," \t,");
148       if (f1!=NULL) {
149         val=strtol(f1,&endptr,10);
150         if (endptr[0]=='\0') menulocal.savehistory=val;
151       }
152       memfree(f1);
153     } else if (strcmp(tok,"expand_dir")==0) {
154       f1=getitok2(&s2,&len,"");
155       if (f1!=NULL) {
156         memfree(menulocal.expanddir);
157         menulocal.expanddir=f1;
158       }
159     } else if (strcmp(tok,"expand")==0) {
160       f1=getitok2(&s2,&len," \x09,");
161       if (f1!=NULL) {
162         val=strtol(f1,&endptr,10);
163         if (endptr[0]=='\0') menulocal.expand=val;
164       }
165       memfree(f1);
166     } else if (strcmp(tok,"ignore_path")==0) {
167       f1=getitok2(&s2,&len," \x09,");
168       if (f1!=NULL) {
169         val=strtol(f1,&endptr,10);
170         if (endptr[0]=='\0') menulocal.ignorepath=val;
171       }
172       memfree(f1);
173     } else if (strcmp(tok,"expand_to_fullpath")==0) {
174       f1=getitok2(&s2,&len," \t,");
175       if (f1!=NULL) {
176         val=strtol(f1,&endptr,10);
177         if (endptr[0]=='\0') menulocal.expandtofullpath=val;
178       }
179       memfree(f1);
180     } else if (strcmp(tok,"save_path")==0) {
181       f1=getitok2(&s2,&len," \t,");
182       if (f1!=NULL) {
183         val=strtol(f1,&endptr,10);
184         if (endptr[0]=='\0') menulocal.savepath=val;
185       }
186       memfree(f1);
187     } else if (strcmp(tok,"save_with_data")==0) {
188       f1=getitok2(&s2,&len," \t,");
189       if (f1!=NULL) {
190         val=strtol(f1,&endptr,10);
191         if (endptr[0]=='\0') menulocal.savewithdata=val;
192       }
193       memfree(f1);
194     } else if (strcmp(tok,"save_with_merge")==0) {
195       f1=getitok2(&s2,&len," \t,");
196       if (f1!=NULL) {
197         val=strtol(f1,&endptr,10);
198         if (endptr[0]=='\0') menulocal.savewithmerge=val;
199       }
200       memfree(f1);
201     } else if (strcmp(tok,"ngp_history")==0) {
202       for (;(s2[0]!='\0') && (strchr(" \t,",s2[0])!=NULL);s2++);
203       f1=getitok2(&s2,&len,"");
204       if (f1!=NULL) arrayadd(menulocal.ngpfilelist,&f1);
205     } else if (strcmp(tok,"ngp_dir_history")==0) {
206       for (;(s2[0]!='\0') && (strchr(" \t,",s2[0])!=NULL);s2++);
207       f1=getitok2(&s2,&len,"");
208       if (f1!=NULL) arrayadd(menulocal.ngpdirlist,&f1);
209     } else if (strcmp(tok,"data_history")==0) {
210       for (;(s2[0]!='\0') && (strchr(" \t,",s2[0])!=NULL);s2++);
211       f1=getitok2(&s2,&len,"");
212       if (f1!=NULL) arrayadd(menulocal.datafilelist,&f1);
213     } else if (strcmp(tok,"framex")==0) {
214       f1=getitok2(&s2,&len," \t,");
215       val=strtol(f1,&endptr,10);
216       if (endptr[0]=='\0') menulocal.framex=val;
217     } else if (strcmp(tok,"framey")==0) {
218       f1=getitok2(&s2,&len," \t,");
219       val=strtol(f1,&endptr,10);
220       if (endptr[0]=='\0') menulocal.framey=val;
221     } else if (strcmp(tok,"menu_win")==0) {
222       f1=getitok2(&s2,&len," \t,");
223       f2=getitok2(&s2,&len," \t,");
224       f3=getitok2(&s2,&len," \t,");
225       f4=getitok2(&s2,&len," \t,");
226       if ((f1!=NULL) && (f2!=NULL) && (f3!=NULL) && (f4!=NULL)) {
227         val=strtol(f1,&endptr,10);
228         if ((endptr[0]=='\0') && (val!=0)) menulocal.menux=val;
229         val=strtol(f2,&endptr,10);
230         if ((endptr[0]=='\0') && (val!=0)) menulocal.menuy=val;
231         val=strtol(f3,&endptr,10);
232         if ((endptr[0]=='\0') && (val!=0)) menulocal.menuwidth=val;
233         val=strtol(f4,&endptr,10);
234         if ((endptr[0]=='\0') && (val!=0)) menulocal.menuheight=val;
235       }
236       memfree(f1);
237       memfree(f2);
238       memfree(f3);
239       memfree(f4);
240     } else if (strcmp(tok,"file_win")==0) {
241       f1=getitok2(&s2,&len," \t,");
242       f2=getitok2(&s2,&len," \t,");
243       f3=getitok2(&s2,&len," \t,");
244       f4=getitok2(&s2,&len," \t,");
245       f5=getitok2(&s2,&len," \t,");
246       if ((f1!=NULL) && (f2!=NULL) && (f3!=NULL) && (f4!=NULL) && (f5!=NULL)) {
247         val=strtol(f1,&endptr,10);
248         if (endptr[0]=='\0') menulocal.filex=val;
249         val=strtol(f2,&endptr,10);
250         if (endptr[0]=='\0') menulocal.filey=val;
251         val=strtol(f3,&endptr,10);
252         if (endptr[0]=='\0') menulocal.filewidth=val;
253         val=strtol(f4,&endptr,10);
254         if (endptr[0]=='\0') menulocal.fileheight=val;
255         val=strtol(f5,&endptr,10);
256         if (endptr[0]=='\0') menulocal.fileopen=val;
257       }
258       memfree(f1);
259       memfree(f2);
260       memfree(f3);
261       memfree(f4);
262       memfree(f5);
263     } else if (strcmp(tok,"axis_win")==0) {
264       f1=getitok2(&s2,&len," \t,");
265       f2=getitok2(&s2,&len," \t,");
266       f3=getitok2(&s2,&len," \t,");
267       f4=getitok2(&s2,&len," \t,");
268       f5=getitok2(&s2,&len," \t,");
269       if ((f1!=NULL) && (f2!=NULL) && (f3!=NULL) && (f4!=NULL) && (f5!=NULL)) {
270         val=strtol(f1,&endptr,10);
271         if (endptr[0]=='\0') menulocal.axisx=val;
272         val=strtol(f2,&endptr,10);
273         if (endptr[0]=='\0') menulocal.axisy=val;
274         val=strtol(f3,&endptr,10);
275         if (endptr[0]=='\0') menulocal.axiswidth=val;
276         val=strtol(f4,&endptr,10);
277         if (endptr[0]=='\0') menulocal.axisheight=val;
278         val=strtol(f5,&endptr,10);
279         if (endptr[0]=='\0') menulocal.axisopen=val;
280       }
281       memfree(f1);
282       memfree(f2);
283       memfree(f3);
284       memfree(f4);
285       memfree(f5);
286     } else if (strcmp(tok,"legend_win")==0) {
287       f1=getitok2(&s2,&len," \t,");
288       f2=getitok2(&s2,&len," \t,");
289       f3=getitok2(&s2,&len," \t,");
290       f4=getitok2(&s2,&len," \t,");
291       f5=getitok2(&s2,&len," \t,");
292       if ((f1!=NULL) && (f2!=NULL) && (f3!=NULL) && (f4!=NULL) && (f5!=NULL)) {
293         val=strtol(f1,&endptr,10);
294         if (endptr[0]=='\0') menulocal.legendx=val;
295         val=strtol(f2,&endptr,10);
296         if (endptr[0]=='\0') menulocal.legendy=val;
297         val=strtol(f3,&endptr,10);
298         if (endptr[0]=='\0') menulocal.legendwidth=val;
299         val=strtol(f4,&endptr,10);
300         if (endptr[0]=='\0') menulocal.legendheight=val;
301         val=strtol(f5,&endptr,10);
302         if (endptr[0]=='\0') menulocal.legendopen=val;
303       }
304       memfree(f1);
305       memfree(f2);
306       memfree(f3);
307       memfree(f4);
308       memfree(f5);
309     } else if (strcmp(tok,"merge_win")==0) {
310       f1=getitok2(&s2,&len," \t,");
311       f2=getitok2(&s2,&len," \t,");
312       f3=getitok2(&s2,&len," \t,");
313       f4=getitok2(&s2,&len," \t,");
314       f5=getitok2(&s2,&len," \t,");
315       if ((f1!=NULL) && (f2!=NULL) && (f3!=NULL) && (f4!=NULL) && (f5!=NULL)) {
316         val=strtol(f1,&endptr,10);
317         if (endptr[0]=='\0') menulocal.mergex=val;
318         val=strtol(f2,&endptr,10);
319         if (endptr[0]=='\0') menulocal.mergey=val;
320         val=strtol(f3,&endptr,10);
321         if (endptr[0]=='\0') menulocal.mergewidth=val;
322         val=strtol(f4,&endptr,10);
323         if (endptr[0]=='\0') menulocal.mergeheight=val;
324         val=strtol(f5,&endptr,10);
325         if (endptr[0]=='\0') menulocal.mergeopen=val;
326       }
327       memfree(f1);
328       memfree(f2);
329       memfree(f3);
330       memfree(f4);
331       memfree(f5);
332     } else if (strcmp(tok,"information_win")==0) {
333       f1=getitok2(&s2,&len," \t,");
334       f2=getitok2(&s2,&len," \t,");
335       f3=getitok2(&s2,&len," \t,");
336       f4=getitok2(&s2,&len," \t,");
337       f5=getitok2(&s2,&len," \t,");
338       if ((f1!=NULL) && (f2!=NULL) && (f3!=NULL) && (f4!=NULL) && (f5!=NULL)) {
339         val=strtol(f1,&endptr,10);
340         if (endptr[0]=='\0') menulocal.dialogx=val;
341         val=strtol(f2,&endptr,10);
342         if (endptr[0]=='\0') menulocal.dialogy=val;
343         val=strtol(f3,&endptr,10);
344         if (endptr[0]=='\0') menulocal.dialogwidth=val;
345         val=strtol(f4,&endptr,10);
346         if (endptr[0]=='\0') menulocal.dialogheight=val;
347         val=strtol(f5,&endptr,10);
348         if (endptr[0]=='\0') menulocal.dialogopen=val;
349       }
350       memfree(f1);
351       memfree(f2);
352       memfree(f3);
353       memfree(f4);
354       memfree(f5);
355     } else if (strcmp(tok,"coordinate_win")==0) {
356       f1=getitok2(&s2,&len," \t,");
357       f2=getitok2(&s2,&len," \t,");
358       f3=getitok2(&s2,&len," \t,");
359       f4=getitok2(&s2,&len," \t,");
360       f5=getitok2(&s2,&len," \t,");
361       if ((f1!=NULL) && (f2!=NULL) && (f3!=NULL) && (f4!=NULL) && (f5!=NULL)) {
362         val=strtol(f1,&endptr,10);
363         if (endptr[0]=='\0') menulocal.coordx=val;
364         val=strtol(f2,&endptr,10);
365         if (endptr[0]=='\0') menulocal.coordy=val;
366         val=strtol(f3,&endptr,10);
367         if (endptr[0]=='\0') menulocal.coordwidth=val;
368         val=strtol(f4,&endptr,10);
369         if (endptr[0]=='\0') menulocal.coordheight=val;
370         val=strtol(f5,&endptr,10);
371         if (endptr[0]=='\0') menulocal.coordopen=val;
372       }
373       memfree(f1);
374       memfree(f2);
375       memfree(f3);
376       memfree(f4);
377       memfree(f5);
378     } else if (strcmp(tok,"status_bar")==0) {
379       f1=getitok2(&s2,&len," \t,");
380       if (f1!=NULL) {
381         val=strtol(f1,&endptr,10);
382         if (endptr[0]=='\0') menulocal.statusb=val;
383       }
384       memfree(f1);
385     } else if (strcmp(tok,"show_tip")==0) {
386       f1=getitok2(&s2,&len," \t,");
387       if (f1!=NULL) {
388         val=strtol(f1,&endptr,10);
389         if (endptr[0]=='\0') menulocal.showtip=val;
390       }
391       memfree(f1);
392     } else if (strcmp(tok,"move_child_window")==0) {
393       f1=getitok2(&s2,&len," \t,");
394       if (f1!=NULL) {
395         val=strtol(f1,&endptr,10);
396         if (endptr[0]=='\0') menulocal.movechild=val;
397       }
398       memfree(f1);
399     } else if (strcmp(tok,"editor")==0) {
400       memfree(menulocal.editor);
401       f1=getitok2(&s2,&len,"");
402       menulocal.editor=f1;
403     } else if (strcmp(tok,"browser")==0) {
404       memfree(menulocal.browser);
405       f1=getitok2(&s2,&len,"");
406       menulocal.browser=f1;
407     } else if (strcmp(tok,"gpl")==0) {
408       memfree(menulocal.gpl);
409       f1=getitok2(&s2,&len,"");
410       menulocal.gpl=f1;
411     } else if (strcmp(tok,"ext_driver")==0) {
412       f1=getitok2(&s2,&len,",");
413       f2=getitok2(&s2,&len,",");
414       if (s2[1]==',') f3=NULL;
415       else f3=getitok2(&s2,&len,",");
416       for (;(s2[0]!='\0') && (strchr(" \t,",s2[0])!=NULL);s2++);
417       f4=getitok2(&s2,&len,"");
418       if ((f1!=NULL) && (f2!=NULL)) {
419         if ((pnew=(struct extprinter *)memalloc(sizeof(struct extprinter)))
420         ==NULL) {
421           memfree(tok);
422           memfree(f1);
423           memfree(f2);
424           memfree(f3);
425           memfree(f4);
426           closeconfig(fp);
427           return 1;
428         }
429         if (pcur==NULL) menulocal.extprinterroot=pnew;
430         else pcur->next=pnew;
431         pcur=pnew;
432         pcur->next=NULL;
433         pcur->name=f1;
434         pcur->driver=f2;
435         pcur->ext=f3;
436         pcur->option=f4;
437       } else {
438         memfree(f1);
439         memfree(f2);
440         memfree(f3);
441         memfree(f4);
442       }
443     } else if (strcmp(tok,"prn_driver")==0) {
444       f1=getitok2(&s2,&len,",");
445       f2=getitok2(&s2,&len,",");
446       f3=getitok2(&s2,&len,",");
447       for (;(s2[0]!='\0') && (strchr(" \t,",s2[0])!=NULL);s2++);
448       f4=getitok2(&s2,&len,"");
449       if ((f1!=NULL) && (f2!=NULL)) {
450         if ((pnew2=(struct prnprinter *)memalloc(sizeof(struct prnprinter)))
451         ==NULL) {
452           memfree(tok);
453           memfree(f1);
454           memfree(f2);
455           memfree(f3);
456           memfree(f4);
457           closeconfig(fp);
458           return 1;
459         }
460         if (pcur2==NULL) menulocal.prnprinterroot=pnew2;
461         else pcur2->next=pnew2;
462         pcur2=pnew2;
463         pcur2->next=NULL;
464         pcur2->name=f1;
465         pcur2->driver=f2;
466         pcur2->prn=f3;
467         pcur2->option=f4;
468       } else {
469         memfree(f1);
470         memfree(f2);
471         memfree(f3);
472         memfree(f4);
473       }
474     } else if (strcmp(tok,"script")==0) {
475       f1=getitok2(&s2,&len,",");
476       f2=getitok2(&s2,&len,",");
477       for (;(s2[0]!='\0') && (strchr(" \t,",s2[0])!=NULL);s2++);
478       f3=getitok2(&s2,&len,"");
479       if ((f1!=NULL) && (f2!=NULL)) {
480         if ((snew=(struct script *)memalloc(sizeof(struct script)))==NULL) {
481           memfree(tok);
482           memfree(f1);
483           memfree(f2);
484           memfree(f3);
485           closeconfig(fp);
486           return 1;
487         }
488         if (scur==NULL) menulocal.scriptroot=snew;
489         else scur->next=snew;
490         scur=snew;
491         scur->next=NULL;
492         scur->name=f1;
493         scur->script=f2;
494         scur->option=f3;
495       } else {
496         memfree(f1);
497         memfree(f2);
498         memfree(f3);
499       }
500     } else if (strcmp(tok,"font_map")==0) {
501       f1=getitok2(&s2,&len," \t,");
502       f2=getitok2(&s2,&len," \t,");
503       f3=getitok2(&s2,&len," \t,");
504       for (;(s2[0]!='\0') && (strchr(" \x09,",s2[0])!=NULL);s2++);
505       f4=getitok2(&s2,&len,"");
506       if ((f1!=NULL) && (f2!=NULL) && (f3!=NULL) && (f4!=NULL)) {
507         if ((fnew=memalloc(sizeof(struct fontmap)))==NULL) {
508           memfree(tok);
509           memfree(f1);
510           memfree(f2);
511           memfree(f3);
512           memfree(f4);
513           closeconfig(fp);
514           return 1;
515         }
516         if (fcur==NULL) mxlocal->fontmaproot=fnew;
517         else fcur->next=fnew;
518         fcur=fnew;
519         fcur->next=NULL;
520         fcur->fontalias=f1;
521         if (strcmp(f2,"bold")==0) fcur->type=BOLD;
522         else if (strcmp(f2,"italic")==0) fcur->type=ITALIC;
523         else if (strcmp(f2,"bold_italic")==0) fcur->type=BOLDITALIC;
524         else fcur->type=NORMAL;
525         memfree(f2);
526         val=strtol(f3,&endptr,10);
527         memfree(f3);
528         fcur->twobyte=val;
529         fcur->fontname=f4;
530       } else {
531         memfree(f1);
532         memfree(f2);
533         memfree(f3);
534         memfree(f4);
535       }
536     } else if (strcmp(tok,"backing_store")==0) {
537       f1=getitok2(&s2,&len," \t,");
538       if (f1!=NULL) {
539         val=strtol(f1,&endptr,10);
540         if (endptr[0]=='\0') mxlocal->backingstore=val;
541       }
542       memfree(f1);
543     } else if (strcmp(tok,"viewer_dpi")==0) {
544       f1=getitok2(&s2,&len," \t,");
545       val=strtol(f1,&endptr,10);
546       if (endptr[0]=='\0') mxlocal->windpi=val;
547       memfree(f1);
548     } else if (strcmp(tok,"color_depth")==0) {
549       f1=getitok2(&s2,&len," \t,");
550       val=strtol(f1,&endptr,10);
551       if (endptr[0]=='\0') mxlocal->cdepth=val;
552       memfree(f1);
553     } else if (strcmp(tok,"viewer_auto_redraw")==0) {
554       f1=getitok2(&s2,&len," \t,");
555       val=strtol(f1,&endptr,10);
556       if (endptr[0]=='\0') {
557         if (val==0) mxlocal->autoredraw=FALSE;
558         else mxlocal->autoredraw=TRUE;
559       }
560       memfree(f1);
561     } else if (strcmp(tok,"viewer_load_file_on_redraw")==0) {
562       f1=getitok2(&s2,&len," \t,");
563       val=strtol(f1,&endptr,10);
564       if (endptr[0]=='\0') {
565         if (val==0) mxlocal->redrawf=FALSE;
566         else mxlocal->redrawf=TRUE;
567       }
568       memfree(f1);
569     } else if (strcmp(tok,"viewer_show_ruler")==0) {
570       f1=getitok2(&s2,&len," \t,");
571       val=strtol(f1,&endptr,10);
572       if (endptr[0]=='\0') {
573         if (val==0) mxlocal->ruler=FALSE;
574         else mxlocal->ruler=TRUE;
575       }
576       memfree(f1);
577     } else if (strcmp(tok,"viewer_grid")==0) {
578       f1=getitok2(&s2,&len," \t,");
579       val=strtol(f1,&endptr,10);
580       if (endptr[0]=='\0') mxlocal->grid=val;
581       memfree(f1);
582     } else if (strcmp(tok,"minus_hyphen")==0) {
583       f1=getitok2(&s2,&len," \t,");
584       val=strtol(f1,&endptr,10);
585       if (endptr[0]=='\0') mxlocal->minus_hyphen=val;
586       memfree(f1);
587     } else if (strcmp(tok,"font_slant")==0) {
588       f1=getitok2(&s2,&len," \t,");
589       val=strtol(f1,&endptr,10);
590       if ((endptr[0]=='\0') && (0<=val) && (val<=60))
591         mxlocal->font_slant=val;
592       memfree(f1);
593     }
594     memfree(tok);
595     memfree(str);
596   }
597   closeconfig(fp);
598   return 0;
599 }
600 
initwindowconfig()601 void initwindowconfig()
602 {
603   menulocal.fileopen=menulocal.axisopen=menulocal.legendopen
604    =menulocal.mergeopen=menulocal.dialogopen=menulocal.coordopen=FALSE;
605   menulocal.filex=menulocal.filey
606    =menulocal.fileheight=menulocal.filewidth=CW_USEDEFAULT;
607   menulocal.axisx=menulocal.axisy
608    =menulocal.axisheight=menulocal.axiswidth=CW_USEDEFAULT;
609   menulocal.legendx=menulocal.legendy
610    =menulocal.legendheight=menulocal.legendwidth=CW_USEDEFAULT;
611   menulocal.mergex=menulocal.mergey
612    =menulocal.mergeheight=menulocal.mergewidth=CW_USEDEFAULT;
613   menulocal.dialogx=menulocal.dialogy
614    =menulocal.dialogheight=menulocal.dialogwidth=CW_USEDEFAULT;
615   menulocal.coordx=menulocal.coordy
616    =menulocal.coordheight=menulocal.coordwidth=CW_USEDEFAULT;
617 }
618 
mx11windowconfig()619 int mx11windowconfig()
620 {
621   FILE *fp;
622   char *tok,*str,*s2;
623   char *f1,*f2,*f3,*f4,*f5;
624   int val;
625   char *endptr;
626   int len;
627 
628   if ((fp=openconfig(MX11CONF))==NULL) return 0;
629   while ((tok=getconfig(fp,&str))!=NULL) {
630     s2=str;
631     if (strcmp(tok,"file_win")==0) {
632       f1=getitok2(&s2,&len," \t,");
633       f2=getitok2(&s2,&len," \t,");
634       f3=getitok2(&s2,&len," \t,");
635       f4=getitok2(&s2,&len," \t,");
636       f5=getitok2(&s2,&len," \t,");
637       if ((f1!=NULL) && (f2!=NULL) && (f3!=NULL) && (f4!=NULL) && (f5!=NULL)) {
638         val=strtol(f1,&endptr,10);
639         if (endptr[0]=='\0') menulocal.filex=val;
640         val=strtol(f2,&endptr,10);
641         if (endptr[0]=='\0') menulocal.filey=val;
642         val=strtol(f3,&endptr,10);
643         if (endptr[0]=='\0') menulocal.filewidth=val;
644         val=strtol(f4,&endptr,10);
645         if (endptr[0]=='\0') menulocal.fileheight=val;
646         val=strtol(f5,&endptr,10);
647         if (endptr[0]=='\0') menulocal.fileopen=val;
648       }
649       memfree(f1);
650       memfree(f2);
651       memfree(f3);
652       memfree(f4);
653       memfree(f5);
654     } else if (strcmp(tok,"axis_win")==0) {
655       f1=getitok2(&s2,&len," \t,");
656       f2=getitok2(&s2,&len," \t,");
657       f3=getitok2(&s2,&len," \t,");
658       f4=getitok2(&s2,&len," \t,");
659       f5=getitok2(&s2,&len," \t,");
660       if ((f1!=NULL) && (f2!=NULL) && (f3!=NULL) && (f4!=NULL) && (f5!=NULL)) {
661         val=strtol(f1,&endptr,10);
662         if (endptr[0]=='\0') menulocal.axisx=val;
663         val=strtol(f2,&endptr,10);
664         if (endptr[0]=='\0') menulocal.axisy=val;
665         val=strtol(f3,&endptr,10);
666         if (endptr[0]=='\0') menulocal.axiswidth=val;
667         val=strtol(f4,&endptr,10);
668         if (endptr[0]=='\0') menulocal.axisheight=val;
669         val=strtol(f5,&endptr,10);
670         if (endptr[0]=='\0') menulocal.axisopen=val;
671       }
672       memfree(f1);
673       memfree(f2);
674       memfree(f3);
675       memfree(f4);
676       memfree(f5);
677     } else if (strcmp(tok,"legend_win")==0) {
678       f1=getitok2(&s2,&len," \t,");
679       f2=getitok2(&s2,&len," \t,");
680       f3=getitok2(&s2,&len," \t,");
681       f4=getitok2(&s2,&len," \t,");
682       f5=getitok2(&s2,&len," \t,");
683       if ((f1!=NULL) && (f2!=NULL) && (f3!=NULL) && (f4!=NULL) && (f5!=NULL)) {
684         val=strtol(f1,&endptr,10);
685         if (endptr[0]=='\0') menulocal.legendx=val;
686         val=strtol(f2,&endptr,10);
687         if (endptr[0]=='\0') menulocal.legendy=val;
688         val=strtol(f3,&endptr,10);
689         if (endptr[0]=='\0') menulocal.legendwidth=val;
690         val=strtol(f4,&endptr,10);
691         if (endptr[0]=='\0') menulocal.legendheight=val;
692         val=strtol(f5,&endptr,10);
693         if (endptr[0]=='\0') menulocal.legendopen=val;
694       }
695       memfree(f1);
696       memfree(f2);
697       memfree(f3);
698       memfree(f4);
699       memfree(f5);
700     } else if (strcmp(tok,"merge_win")==0) {
701       f1=getitok2(&s2,&len," \t,");
702       f2=getitok2(&s2,&len," \t,");
703       f3=getitok2(&s2,&len," \t,");
704       f4=getitok2(&s2,&len," \t,");
705       f5=getitok2(&s2,&len," \t,");
706       if ((f1!=NULL) && (f2!=NULL) && (f3!=NULL) && (f4!=NULL) && (f5!=NULL)) {
707         val=strtol(f1,&endptr,10);
708         if (endptr[0]=='\0') menulocal.mergex=val;
709         val=strtol(f2,&endptr,10);
710         if (endptr[0]=='\0') menulocal.mergey=val;
711         val=strtol(f3,&endptr,10);
712         if (endptr[0]=='\0') menulocal.mergewidth=val;
713         val=strtol(f4,&endptr,10);
714         if (endptr[0]=='\0') menulocal.mergeheight=val;
715         val=strtol(f5,&endptr,10);
716         if (endptr[0]=='\0') menulocal.mergeopen=val;
717       }
718       memfree(f1);
719       memfree(f2);
720       memfree(f3);
721       memfree(f4);
722       memfree(f5);
723     } else if (strcmp(tok,"information_win")==0) {
724       f1=getitok2(&s2,&len," \t,");
725       f2=getitok2(&s2,&len," \t,");
726       f3=getitok2(&s2,&len," \t,");
727       f4=getitok2(&s2,&len," \t,");
728       f5=getitok2(&s2,&len," \t,");
729       if ((f1!=NULL) && (f2!=NULL) && (f3!=NULL) && (f4!=NULL) && (f5!=NULL)) {
730         val=strtol(f1,&endptr,10);
731         if (endptr[0]=='\0') menulocal.dialogx=val;
732         val=strtol(f2,&endptr,10);
733         if (endptr[0]=='\0') menulocal.dialogy=val;
734         val=strtol(f3,&endptr,10);
735         if (endptr[0]=='\0') menulocal.dialogwidth=val;
736         val=strtol(f4,&endptr,10);
737         if (endptr[0]=='\0') menulocal.dialogheight=val;
738         val=strtol(f5,&endptr,10);
739         if (endptr[0]=='\0') menulocal.dialogopen=val;
740       }
741       memfree(f1);
742       memfree(f2);
743       memfree(f3);
744       memfree(f4);
745       memfree(f5);
746     } else if (strcmp(tok,"coordinate_win")==0) {
747       f1=getitok2(&s2,&len," \t,");
748       f2=getitok2(&s2,&len," \t,");
749       f3=getitok2(&s2,&len," \t,");
750       f4=getitok2(&s2,&len," \t,");
751       f5=getitok2(&s2,&len," \t,");
752       if ((f1!=NULL) && (f2!=NULL) && (f3!=NULL) && (f4!=NULL) && (f5!=NULL)) {
753         val=strtol(f1,&endptr,10);
754         if (endptr[0]=='\0') menulocal.coordx=val;
755         val=strtol(f2,&endptr,10);
756         if (endptr[0]=='\0') menulocal.coordy=val;
757         val=strtol(f3,&endptr,10);
758         if (endptr[0]=='\0') menulocal.coordwidth=val;
759         val=strtol(f4,&endptr,10);
760         if (endptr[0]=='\0') menulocal.coordheight=val;
761         val=strtol(f5,&endptr,10);
762         if (endptr[0]=='\0') menulocal.coordopen=val;
763       }
764       memfree(f1);
765       memfree(f2);
766       memfree(f3);
767       memfree(f4);
768       memfree(f5);
769     }
770     memfree(tok);
771     memfree(str);
772   }
773   closeconfig(fp);
774   return 0;
775 }
776 
exwinloadconfig()777 int exwinloadconfig()
778 {
779   FILE *fp;
780   char *tok,*str,*s2;
781   char *f1;
782   int val;
783   char *endptr;
784   int len;
785 
786   if ((fp=openconfig(G2WINCONF))==NULL) return 0;
787   while ((tok=getconfig(fp,&str))!=NULL) {
788     s2=str;
789     if (strcmp(tok,"win_dpi")==0) {
790       f1=getitok2(&s2,&len," \t,");
791       val=strtol(f1,&endptr,10);
792       if (endptr[0]=='\0') menulocal.exwindpi=val;
793       memfree(f1);
794     } else if (strcmp(tok,"win_width")==0) {
795       f1=getitok2(&s2,&len," \t,");
796       val=strtol(f1,&endptr,10);
797       if (endptr[0]=='\0') menulocal.exwinwidth=val;
798       memfree(f1);
799     } else if (strcmp(tok,"win_height")==0) {
800       f1=getitok2(&s2,&len," \t,");
801       val=strtol(f1,&endptr,10);
802       if (endptr[0]=='\0') menulocal.exwinheight=val;
803       memfree(f1);
804     } else if (strcmp(tok,"backing_store")==0) {
805       f1=getitok2(&s2,&len," \t,");
806       val=strtol(f1,&endptr,10);
807       if (endptr[0]=='\0') menulocal.exwinbackingstore=val;
808       memfree(f1);
809     }
810     memfree(tok);
811     memfree(str);
812   }
813   closeconfig(fp);
814   return 0;
815 }
816 
menuadddrawrable(struct objlist * parent,struct narray * drawrable)817 void menuadddrawrable(struct objlist *parent,struct narray *drawrable)
818 {
819   struct objlist *ocur;
820   char *name;
821 
822   ocur=chkobjroot();
823   while (ocur!=NULL) {
824     if (chkobjparent(ocur)==parent) {
825       name=chkobjectname(ocur);
826       arrayadd2(drawrable,&name);
827       menuadddrawrable(ocur,drawrable);
828     }
829     ocur=ocur->next;
830   }
831 }
832 
menuinit(struct objlist * obj,char * inst,char * rval,int argc,char ** argv)833 int menuinit(struct objlist *obj,char *inst,char *rval,int argc,char **argv)
834 {
835   struct objlist *robj;
836   struct fontmap *fcur,*fdel;
837   struct extprinter *pcur,*pdel;
838   struct prnprinter *pcur2,*pdel2;
839   struct script *scur,*sdel;
840   int i,numf,numd;
841   char *dum;
842 
843   if (_exeparent(obj,(char *)argv[1],inst,rval,argc,argv)) return 1;
844   if ((mxlocal=(struct mxlocal *)memalloc(sizeof(struct mxlocal)))==NULL)
845     return 1;
846   menulocal.framex=menulocal.framey=0;
847   menulocal.menux=menulocal.menuy
848    =menulocal.menuheight=menulocal.menuwidth=CW_USEDEFAULT;
849   initwindowconfig();
850   menulocal.showtip=TRUE;
851   menulocal.statusb=TRUE;
852   menulocal.movechild=FALSE;
853   menulocal.scriptconsole=FALSE;
854   menulocal.addinconsole=TRUE;
855   menulocal.mouseclick=500;
856   menulocal.changedirectory=1;
857   menulocal.editor=NULL;
858   menulocal.browser=NULL;
859   menulocal.gpl=NULL;
860   menulocal.PaperWidth=21000;
861   menulocal.PaperHeight=29700;
862   menulocal.LeftMargin=0;
863   menulocal.TopMargin=0;
864   menulocal.PaperZoom=10000;
865   menulocal.exwindpi=70;
866   menulocal.exwinwidth=0;
867   menulocal.exwinheight=0;
868   menulocal.exwinbackingstore=FALSE;
869   menulocal.fileopendir=NULL;
870   menulocal.graphloaddir=NULL;
871   menulocal.expand=1;
872   menulocal.expanddir=(char *)memalloc(3);
873   strcpy(menulocal.expanddir,"./");
874   menulocal.ignorepath=0;
875   menulocal.expandtofullpath=TRUE;
876   menulocal.savepath=0;
877   menulocal.savewithdata=0;
878   menulocal.savewithmerge=0;
879   menulocal.mathlist=arraynew(sizeof(char *));
880   menulocal.ngpfilelist=arraynew(sizeof(char *));
881   menulocal.ngpdirlist=arraynew(sizeof(char *));
882   menulocal.datafilelist=arraynew(sizeof(char *));
883   menulocal.GRAobj=chkobject("gra");
884   arrayinit(&(menulocal.drawrable),sizeof(char *));
885   menuadddrawrable(chkobject("draw"),&(menulocal.drawrable));
886   menulocal.extprinterroot=NULL;
887   menulocal.prnprinterroot=NULL;
888   menulocal.scriptroot=NULL;
889   mxlocal->fontmaproot=NULL;
890   mxlocal->windpi=70;
891   mxlocal->autoredraw=TRUE;
892   mxlocal->redrawf=TRUE;
893   mxlocal->ruler=TRUE;
894   mxlocal->grid=200;
895   mxlocal->cdepth=X11COLORDEPTH;
896   mxlocal->backingstore=FALSE;
897   mxlocal->minus_hyphen=TRUE;
898   mxlocal->font_slant=15;
899   if (_putobj(obj,"_local",inst,mxlocal)) goto errexit;
900   if (mx11loadconfig()) goto errexit;
901   if (exwinloadconfig()) goto errexit;
902   numf=arraynum(menulocal.ngpfilelist);
903   numd=arraynum(menulocal.ngpdirlist);
904   dum=NULL;
905   if (numd>numf)
906     for (i=numf;i<numd;i++) arrayndel2(menulocal.ngpdirlist,i);
907   else if (numd<numf)
908     for (i=numd;i<numf;i++) arrayadd(menulocal.ngpdirlist,&dum);
909   if (menulocal.exwindpi<1) menulocal.exwindpi=70;
910   if (menulocal.exwindpi>2540) menulocal.exwindpi=2540;
911   if (mxlocal->windpi<1) mxlocal->windpi=70;
912   if (mxlocal->windpi>2540) mxlocal->windpi=2540;
913   if (mxlocal->cdepth<2) mxlocal->cdepth=2;
914   if (_putobj(obj,"dpi",inst,&(mxlocal->windpi))) goto errexit;
915   if (_putobj(obj,"auto_redraw",inst,&(mxlocal->autoredraw))) goto errexit;
916   if (_putobj(obj,"redraw_flag",inst,&(mxlocal->redrawf))) goto errexit;
917   if (!chkobjfield(obj,"_output")) {
918     if ((menulocal.output=getobjtblpos(obj,"_output",&robj))==-1) goto errexit;
919     menulocal.outputobj=robj;
920   } else menulocal.output=-1;
921   menulocal.obj=obj;
922   menulocal.inst=inst;
923   mxlocal->win=0;
924   mxlocal->gc=0;
925   mxlocal->lock=0;
926 
927   if (!OpenApplication()) goto errexit;
928   return 0;
929 
930 errexit:
931   memfree(menulocal.editor);
932   memfree(menulocal.browser);
933   memfree(menulocal.gpl);
934   pcur=menulocal.extprinterroot;
935   while (pcur!=NULL) {
936     pdel=pcur;
937     pcur=pcur->next;
938     memfree(pdel->name);
939     memfree(pdel->driver);
940     memfree(pdel->ext);
941     memfree(pdel->option);
942     memfree(pdel);
943   }
944   pcur2=menulocal.prnprinterroot;
945   while (pcur2!=NULL) {
946     pdel2=pcur2;
947     pcur2=pcur2->next;
948     memfree(pdel2->name);
949     memfree(pdel2->driver);
950     memfree(pdel2->option);
951     memfree(pdel2->prn);
952     memfree(pdel2);
953   }
954   scur=menulocal.scriptroot;
955   while (scur!=NULL) {
956     sdel=scur;
957     scur=scur->next;
958     memfree(sdel->name);
959     memfree(sdel->script);
960     memfree(sdel->option);
961     memfree(sdel);
962   }
963   fcur=mxlocal->fontmaproot;
964   while (fcur!=NULL) {
965     fdel=fcur;
966     fcur=fcur->next;
967     memfree(fdel->fontalias);
968     memfree(fdel->fontname);
969     memfree(fdel);
970   }
971   memfree(mxlocal);
972   return 1;
973 }
974 
menudone(struct objlist * obj,char * inst,char * rval,int argc,char ** argv)975 int menudone(struct objlist *obj,char *inst,char *rval,int argc,char **argv)
976 {
977   struct fontmap *fcur,*fdel;
978   struct extprinter *pcur,*pdel;
979   struct prnprinter *pcur2,*pdel2;
980   struct script *scur,*sdel;
981 
982   if (_exeparent(obj,(char *)argv[1],inst,rval,argc,argv)) return 1;
983   arraydel2(&(menulocal.drawrable));
984   arrayfree2(menulocal.mathlist);
985   arrayfree2(menulocal.ngpfilelist);
986   arrayfree2(menulocal.ngpdirlist);
987   arrayfree2(menulocal.datafilelist);
988   memfree(menulocal.editor);
989   memfree(menulocal.browser);
990   memfree(menulocal.gpl);
991   free(menulocal.fileopendir);
992   free(menulocal.graphloaddir);
993   memfree(menulocal.expanddir);
994   pcur=menulocal.extprinterroot;
995   while (pcur!=NULL) {
996     pdel=pcur;
997     pcur=pcur->next;
998     memfree(pdel->name);
999     memfree(pdel->driver);
1000     memfree(pdel->ext);
1001     memfree(pdel->option);
1002     memfree(pdel);
1003   }
1004   pcur2=menulocal.prnprinterroot;
1005   while (pcur2!=NULL) {
1006     pdel2=pcur2;
1007     pcur2=pcur2->next;
1008     memfree(pdel2->name);
1009     memfree(pdel2->driver);
1010     memfree(pdel2->option);
1011     memfree(pdel2->prn);
1012     memfree(pdel2);
1013   }
1014   scur=menulocal.scriptroot;
1015   while (scur!=NULL) {
1016     sdel=scur;
1017     scur=scur->next;
1018     memfree(sdel->name);
1019     memfree(sdel->script);
1020     memfree(sdel->option);
1021     memfree(sdel);
1022   }
1023   fcur=mxlocal->fontmaproot;
1024   while (fcur!=NULL) {
1025     fdel=fcur;
1026     fcur=fcur->next;
1027     memfree(fdel->fontname);
1028     memfree(fdel->fontalias);
1029     memfree(fdel);
1030   }
1031   return 0;
1032 }
1033 
mx11displaydialog(char * str)1034 void mx11displaydialog(char *str)
1035 {
1036   DisplayDialog(str);
1037 }
1038 
mx11displaystatus(char * str)1039 void mx11displaystatus(char *str)
1040 {
1041   DisplayStatus(str);
1042 }
1043 
mx11putstderr(char * s)1044 int mx11putstderr(char *s)
1045 {
1046   return PutStderr(s);
1047 }
1048 
mx11printfstderr(char * fmt,...)1049 int mx11printfstderr(char *fmt,...)
1050 {
1051   int len;
1052   char buf[1024];
1053   va_list ap;
1054 
1055   va_start(ap,fmt);
1056   len=vsprintf(buf,fmt,ap);
1057   va_end(ap);
1058   PutStderr(buf);
1059   return len;
1060 }
1061 
mx11interrupt()1062 int mx11interrupt()
1063 {
1064   return ChkInterrupt();
1065 }
1066 
mx11inputyn(char * mes)1067 int mx11inputyn(char *mes)
1068 {
1069   return InputYN(mes);
1070 }
1071 
menumenu(struct objlist * obj,char * inst,char * rval,int argc,char ** argv)1072 int menumenu(struct objlist *obj,char *inst,char *rval,int argc,char **argv)
1073 {
1074   char *file;
1075 
1076   if (_exeparent(obj,(char *)argv[1],inst,rval,argc,argv)) return 1;
1077   if (mxlocal->lock) {
1078     error(obj,ERRRUN);
1079     return 1;
1080   }
1081   mxlocal->lock=1;
1082 
1083   savestdio(&x11iosave);
1084 
1085   file=(char *)argv[2];
1086   application(file);
1087 
1088   loadstdio(&x11iosave);
1089   mxlocal->lock=0;
1090   return 0;
1091 }
1092 
mx_evloop(struct objlist * obj,char * inst,char * rval,int argc,char ** argv)1093 int mx_evloop(struct objlist *obj,char *inst,char *rval,int argc,char **argv)
1094 {
1095   ResetEvent();
1096   return 0;
1097 }
1098 
mxredrawflag(struct objlist * obj,char * inst,char * rval,int argc,char ** argv)1099 int mxredrawflag(struct objlist *obj,char *inst,char *rval,int argc,char **argv)
1100 {
1101   mxlocal->redrawf=*(int *)argv[2];
1102   return 0;
1103 }
1104 
mx_redraw(struct objlist * obj,char * inst)1105 void mx_redraw(struct objlist *obj,char *inst)
1106 {
1107   GRAredraw(obj,inst,TRUE,mxlocal->redrawf);
1108   mxflush(obj,inst,NULL,0,NULL);
1109 }
1110 
mx_inslist(struct objlist * obj,char * inst,struct objlist * aobj,char * ainst,char * afield,int addn)1111 void mx_inslist(struct objlist *obj,char *inst,
1112                 struct objlist *aobj,char *ainst,char *afield,int addn)
1113 {
1114   int GC;
1115 
1116   _getobj(obj,"_GC",inst,&GC);
1117   GRAinslist(GC,aobj,ainst,chkobjectname(aobj),afield,addn);
1118 }
1119 
mx_dellist(struct objlist * obj,char * inst,int deln)1120 void mx_dellist(struct objlist *obj,char *inst,int deln)
1121 {
1122   int GC;
1123 
1124   _getobj(obj,"_GC",inst,&GC);
1125   GRAdellist(GC,deln);
1126 }
1127 
mxredraw(struct objlist * obj,char * inst,char * rval,int argc,char ** argv)1128 int mxredraw(struct objlist *obj,char *inst,char *rval,int argc,char **argv)
1129 {
1130   mx_redraw(obj,inst);
1131   return 0;
1132 }
1133 
mxautoredraw(struct objlist * obj,char * inst,char * rval,int argc,char ** argv)1134 int mxautoredraw(struct objlist *obj,char *inst,char *rval,
1135                  int argc,char **argv)
1136 {
1137   if (!(mxlocal->autoredraw) && (*(int *)argv[2]))
1138     mx_redraw(obj,inst);
1139   mxlocal->autoredraw=*(int *)argv[2];
1140   return 0;
1141 }
1142 
mxdpi(struct objlist * obj,char * inst,char * rval,int argc,char ** argv)1143 int mxdpi(struct objlist *obj,char *inst,char *rval,int argc,char **argv)
1144 {
1145   int dpi;
1146 
1147   dpi=abs(*(int *)argv[2]);
1148   if (dpi<1) dpi=1;
1149   if (dpi>2540) dpi=2540;
1150   mxlocal->windpi=dpi;
1151   mxlocal->pixel_dot=dpi/2540.0;
1152   *(int *)argv[2]=dpi;
1153   if (Disp!=NULL)
1154     XClearArea(Disp,mxlocal->win,0,0,0,0,TRUE);
1155   return 0;
1156 }
1157 
mxflush(struct objlist * obj,char * inst,char * rval,int argc,char ** argv)1158 int mxflush(struct objlist *obj,char *inst,char *rval,int argc,char **argv)
1159 {
1160   if (mxlocal->linetonum!=0) {
1161     if (Disp!=NULL) {
1162       XDrawLines(Disp,mxlocal->win,mxlocal->gc,
1163                  mxlocal->points,mxlocal->linetonum,CoordModeOrigin);
1164       mxlocal->linetonum=0;
1165     }
1166   }
1167   if (Disp!=NULL) XFlush(Disp);
1168   return 0;
1169 }
1170 
1171 
mxclear(struct objlist * obj,char * inst,char * rval,int argc,char ** argv)1172 int mxclear(struct objlist *obj,char *inst,char *rval,int argc,char **argv)
1173 {
1174   if (_exeparent(obj,(char *)argv[1],inst,rval,argc,argv)) return 1;
1175   if (mxlocal->linetonum!=0) {
1176     if (Disp!=NULL) {
1177       XDrawLines(Disp,mxlocal->win,mxlocal->gc,
1178                  mxlocal->points,mxlocal->linetonum,CoordModeOrigin);
1179       mxlocal->linetonum=0;
1180     }
1181   }
1182   if (Disp!=NULL) {
1183     XClearArea(Disp,mxlocal->win,0,0,0,0,TRUE);
1184   }
1185   return 0;
1186 }
1187 
mxsaveGC(GC gc,Drawable d,int scrollx,int scrolly,struct mxlocal * mxsave,int dpi,Region region)1188 void mxsaveGC(GC gc,Drawable d,int scrollx,int scrolly,
1189               struct mxlocal *mxsave,int dpi,
1190               Region region)
1191 {
1192   int i;
1193 
1194   memcpy(mxsave,mxlocal,sizeof(struct mxlocal));
1195   mxlocal->win=d;
1196   mxlocal->gc=gc;
1197   mxlocal->scrollx=scrollx;
1198   mxlocal->scrolly=scrolly;
1199   mxlocal->offsetx=0;
1200   mxlocal->offsety=0;
1201   mxlocal->cpx=0;
1202   mxlocal->cpy=0;
1203   mxlocal->fontalias=NULL;
1204   for (i=0;i<X11FONTCASH;i++) (mxlocal->font[i]).fontalias=NULL;
1205   mxlocal->loadfont=0;
1206   mxlocal->loadfontf=-1;
1207   mxlocal->linetonum=0;
1208   if (dpi!=-1) {
1209     mxlocal->windpi=dpi;
1210     mxlocal->pixel_dot=mxlocal->windpi/2540.0;
1211   } else {
1212     mxlocal->windpi=mxsave->windpi;
1213     mxlocal->pixel_dot=mxsave->pixel_dot;
1214   }
1215   mxlocal->region=region;
1216 }
1217 
mxrestoreGC(struct mxlocal * mxsave)1218 void mxrestoreGC(struct mxlocal *mxsave)
1219 {
1220   int i;
1221 
1222   if (mxlocal->linetonum!=0) {
1223     if (Disp!=NULL) {
1224       XDrawLines(Disp,mxlocal->win,mxlocal->gc,
1225                  mxlocal->points,mxlocal->linetonum,CoordModeOrigin);
1226       mxlocal->linetonum=0;
1227       XFlush(Disp);
1228     }
1229   }
1230   memfree(mxlocal->fontalias);
1231   for (i=0;i<X11FONTCASH;i++) memfree((mxlocal->font[i]).fontalias);
1232   memcpy(mxlocal,mxsave,sizeof(struct mxlocal));
1233 }
1234 
mxd2p(int r)1235 int mxd2p(int r)
1236 {
1237   return nround(r*mxlocal->pixel_dot);
1238 }
1239 
mxd2px(int x)1240 int mxd2px(int x)
1241 {
1242   return nround(x*mxlocal->pixel_dot+mxlocal->offsetx-mxlocal->scrollx);
1243 }
1244 
mxd2py(int y)1245 int mxd2py(int y)
1246 {
1247   return nround(y*mxlocal->pixel_dot+mxlocal->offsety-mxlocal->scrolly);
1248 }
1249 
mxp2d(int r)1250 int mxp2d(int r)
1251 {
1252   return nround(r/mxlocal->pixel_dot);
1253 }
1254 
RGB(int R,int G,int B)1255 unsigned long RGB(int R,int G,int B)
1256 {
1257   XColor col;
1258 
1259   R=R*mxlocal->cdepth/256;
1260   if (R>=mxlocal->cdepth) R=mxlocal->cdepth-1;
1261   else if (R<0) R=0;
1262   G=G*mxlocal->cdepth/256;
1263   if (G>=mxlocal->cdepth) G=mxlocal->cdepth-1;
1264   else if (G<0) G=0;
1265   B=B*mxlocal->cdepth/256;
1266   if (B>=mxlocal->cdepth) B=mxlocal->cdepth-1;
1267   else if (B<0) B=0;
1268   col.red=R*65535/(mxlocal->cdepth-1);
1269   col.green=G*65535/(mxlocal->cdepth-1);
1270   col.blue=B*65535/(mxlocal->cdepth-1);
1271   XAllocColor(Disp,mxlocal->cmap,&col);
1272   return col.pixel;
1273 }
1274 
mxloadfont(Display * disp,GC gc,char * fontalias,int size,int dir,double fsin,double fcos,int top)1275 int mxloadfont(Display *disp,GC gc,char *fontalias,int size,int dir,
1276                double fsin,double fcos,int top)
1277 {
1278   int fontcashfind;
1279   int i;
1280   char *fsp;
1281   char *fontname,*fontname2,*fontname3=NULL;
1282   char **fname2,**fname3;
1283   struct fontlocal font;
1284   struct fontmap *fcur;
1285   char fontmatrix[256];
1286   int rcount2,rcount3;
1287   Font newfont;
1288   XFontStruct *newfontstruct;
1289   int store;
1290   int twobyte=FALSE,type;
1291   double ftan;
1292 
1293   fontcashfind=-1;
1294   for (i=0;i<mxlocal->loadfont;i++) {
1295     if ((strcmp((mxlocal->font[i]).fontalias,fontalias)==0)
1296     && ((mxlocal->font[i]).fontsize==size)
1297     && ((mxlocal->font[i]).fontdir==dir)) {
1298       fontcashfind=i;
1299       break;
1300     }
1301   }
1302   if (fontcashfind!=-1) {
1303     if (top) {
1304       font=mxlocal->font[fontcashfind];
1305       for (i=fontcashfind-1;i>=0;i--) mxlocal->font[i+1]=mxlocal->font[i];
1306       mxlocal->font[0]=font;
1307       XSetFont(disp,gc,(mxlocal->font[0]).font);
1308       return 0;
1309     } else return fontcashfind;
1310   }
1311 
1312   fcur=mxlocal->fontmaproot;
1313   fontname=NULL;
1314   while (fcur!=NULL) {
1315     if (strcmp(fontalias,fcur->fontalias)==0) {
1316       fontname=fcur->fontname;
1317       type=fcur->type;
1318       twobyte=fcur->twobyte;
1319       break;
1320     }
1321     fcur=fcur->next;
1322   }
1323   if ((fontname==NULL) || (fontname[0]!='-')) {
1324     return -1;
1325   }
1326   if (((fontname2=memalloc(strlen(fontname)+128))==NULL)
1327   || ((fontname3=memalloc(strlen(fontname)+128))==NULL)) {
1328     memfree(fontname2);
1329     memfree(fontname3);
1330     return -1;
1331   }
1332   fsp=fontname;
1333   for (i=0;i<6;i++) fsp=strchr(fsp+1,'-');
1334   strncpy(fontname2,fontname,fsp-fontname+1);
1335   strncpy(fontname3,fontname,fsp-fontname+1);
1336   fontname2[fsp-fontname+1]='\0';
1337   fontname3[fsp-fontname+1]='\0';
1338   if ((type==ITALIC) || (type==BOLDITALIC)) {
1339     ftan=tan(mxlocal->font_slant*MPI/180.0);
1340     sprintf(fontmatrix,"[%.3e %.3e %.3e %.3e]",
1341             size*fcos,size*fsin,
1342            -size*fsin+size*fcos*ftan,size*fcos+size*fsin*ftan);
1343   } else {
1344     sprintf(fontmatrix,"[%.3e %.3e %.3e %.3e]",
1345             size*fcos,size*fsin,-size*fsin,size*fcos);
1346   }
1347   for (i=0;fontmatrix[i]!='\0';i++)
1348     if (fontmatrix[i]=='-') fontmatrix[i]='~';
1349   strcat(fontname2,fontmatrix);
1350   sprintf(fontmatrix,"%d",size);
1351   strcat(fontname3,fontmatrix);
1352   fsp=strchr(fsp+1,'-');
1353   strcat(fontname2,fsp);
1354   strcat(fontname3,fsp);
1355   fname2=XListFonts(disp,fontname2,1,&rcount2);
1356   if (!twobyte) fname3=XListFonts(disp,fontname3,1,&rcount3);
1357   else fname3=NULL;
1358   memfree(fontname2);
1359   memfree(fontname3);
1360   if ((fname2!=NULL) && (twobyte || (fname3!=NULL))) {
1361     newfont=XLoadFont(disp,fname2[0]);
1362     if (!twobyte) newfontstruct=XLoadQueryFont(disp,fname3[0]);
1363     else newfontstruct=NULL;
1364     if (mxlocal->loadfont==X11FONTCASH) {
1365       XUnloadFont(disp,(mxlocal->font[X11FONTCASH-1]).font);
1366       if (mxlocal->font[X11FONTCASH-1].fontstruct!=NULL)
1367         XFreeFont(disp,(mxlocal->font[X11FONTCASH-1]).fontstruct);
1368       memfree((mxlocal->font[X11FONTCASH-1]).fontalias);
1369       (mxlocal->font[X11FONTCASH-1]).fontalias=NULL;
1370       mxlocal->loadfont--;
1371     }
1372     if (top) {
1373       for (i=mxlocal->loadfont-1;i>=0;i--)
1374         mxlocal->font[i+1]=mxlocal->font[i];
1375       store=0;
1376     } else store=mxlocal->loadfont;
1377     (mxlocal->font[store]).fontalias=memalloc(strlen(fontalias)+1);
1378     if ((mxlocal->font[store]).fontalias==NULL) {
1379       if (fname2!=NULL) XFreeFontNames(fname2);
1380       if (fname3!=NULL) XFreeFontNames(fname3);
1381       return -1;
1382     }
1383     strcpy((mxlocal->font[store]).fontalias,fontalias);
1384     (mxlocal->font[store]).font=newfont;
1385     (mxlocal->font[store]).fontstruct=newfontstruct;
1386     (mxlocal->font[store]).fontsize=size;
1387     (mxlocal->font[store]).fonttype=type;
1388     (mxlocal->font[store]).fontdir=dir;
1389     if (strcmp(fname2[0]+strlen(fname2[0])-9,"iso8859-1")==0)
1390       (mxlocal->font[store]).iso=ISO8859;
1391     else if (strcmp(fname2[0]+strlen(fname2[0])-10,"iso10646-1")==0)
1392       (mxlocal->font[store]).iso=ISO10646;
1393     else
1394       (mxlocal->font[store]).iso=ISOOTHER;
1395     if (top) XSetFont(disp,gc,(mxlocal->font[store]).font);
1396     mxlocal->loadfont++;
1397     if (fname2!=NULL) XFreeFontNames(fname2);
1398     if (fname3!=NULL) XFreeFontNames(fname3);
1399     return store;
1400   }
1401   if (fname2!=NULL) XFreeFontNames(fname2);
1402   if (fname3!=NULL) XFreeFontNames(fname3);
1403   return -1;
1404 }
1405 
mxXDrawString(struct fontlocal font,Display * Disp,Drawable win,GC gc,int x,int y,char * ch)1406 void mxXDrawString(struct fontlocal font,Display *Disp,Drawable win,GC gc,
1407                   int x,int y,char *ch)
1408 {
1409   XChar2b kanji[1];
1410 
1411   if ((font.iso==ISO10646) && (ch[0]=='-')) {
1412     kanji[0].byte1=0x22;
1413     kanji[0].byte2=0x12;
1414     XDrawString16(Disp,win,gc,x,y,kanji,1);
1415   } else {
1416     XDrawString(Disp,win,gc,x,y,ch,1);
1417   }
1418 }
1419 
mxXTextWidth(struct fontlocal font,int minus_hyphen,char * ch)1420 int mxXTextWidth(struct fontlocal font,int minus_hyphen,char *ch)
1421 {
1422   XChar2b kanji[1];
1423 
1424   if (font.fontstruct==NULL) {
1425       return font.fontsize;
1426   } else if ((font.iso==ISO10646) && (ch[0]=='-')) {
1427     kanji[0].byte1=0x22;
1428     kanji[0].byte2=0x12;
1429     return XTextWidth16(font.fontstruct,kanji,1);
1430   } else {
1431     if ((font.iso==ISO8859) && minus_hyphen && (ch[0]=='-')) {
1432       ch[0]='+';
1433     }
1434     return XTextWidth(font.fontstruct,ch,1);
1435   }
1436 }
1437 
mx_output(struct objlist * obj,char * inst,char * rval,int argc,char ** argv)1438 int mx_output(struct objlist *obj,char *inst,char *rval,int argc,char **argv)
1439 {
1440   char code;
1441   int *cpar;
1442   char *cstr,ch[1];
1443   int i,x,y,x1,y1,x2,y2;
1444   double bs;
1445   XRectangle rect;
1446   int width,style,cap,join,dashn=0;
1447   char *dashlist=NULL;
1448   int arcmode;
1449   XPoint *xpoint;
1450   Region region;
1451 
1452   double fontsize,fontspace,fontdir,fontsin,fontcos;
1453   int fontcashsize,fontcashdir;
1454   double x0,y0,x02,y02,fontwidth;
1455   XChar2b kanji[1];
1456   unsigned int jis;
1457 
1458   code=*(char *)(argv[3]);
1459   cpar=(int *)argv[4];
1460   cstr=(char *)argv[5];
1461   if (Disp==NULL) return -1;
1462   if (mxlocal->gc==0) return -1;
1463   if (mxlocal->linetonum!=0) {
1464     if ((code!='T') || (mxlocal->linetonum>=LINETOLIMIT)) {
1465       XDrawLines(Disp,mxlocal->win,mxlocal->gc,
1466                  mxlocal->points,mxlocal->linetonum,CoordModeOrigin);
1467       mxlocal->linetonum=0;
1468     }
1469   }
1470   switch (code) {
1471   case 'I': case '%': case 'X':
1472     break;
1473   case 'E':
1474     XFlush(Disp);
1475     break;
1476   case 'V':
1477     mxlocal->offsetx=mxd2p(cpar[1]);
1478     mxlocal->offsety=mxd2p(cpar[2]);
1479     mxlocal->cpx=0;
1480     mxlocal->cpy=0;
1481     if (cpar[5]) {
1482       rect.x=mxd2p(cpar[1])-mxlocal->scrollx;
1483       rect.y=mxd2p(cpar[2])-mxlocal->scrolly;
1484       rect.width=mxd2p(cpar[3])-mxlocal->scrollx-rect.x;
1485       rect.height=mxd2p(cpar[4])-mxlocal->scrolly-rect.y;
1486       region=XCreateRegion();
1487       XUnionRectWithRegion(&rect,region,region);
1488       if (mxlocal->region!=NULL)
1489         XIntersectRegion(region,mxlocal->region,region);
1490       XSetRegion(Disp,mxlocal->gc,region);
1491       XDestroyRegion(region);
1492     } else {
1493       if (mxlocal->region!=NULL)
1494         XSetRegion(Disp,mxlocal->gc,mxlocal->region);
1495       else {
1496         rect.x=0;
1497         rect.y=0;
1498         rect.width=SHRT_MAX;
1499         rect.height=SHRT_MAX;
1500         region=XCreateRegion();
1501         XUnionRectWithRegion(&rect,region,region);
1502         XSetRegion(Disp,mxlocal->gc,region);
1503         XDestroyRegion(region);
1504       }
1505     }
1506     break;
1507   case 'A':
1508     if (cpar[1]==0) style=LineSolid;
1509     else {
1510       style=LineOnOffDash;
1511       if ((dashlist=memalloc(sizeof(char)*cpar[1]))==NULL) break;
1512       for (i=0;i<cpar[1];i++)
1513         if ((dashlist[i]=mxd2p(cpar[6+i]))<=0) dashlist[i]=1;
1514       dashn=cpar[1];
1515     }
1516     width=mxd2p(cpar[2]);
1517     if (cpar[3]==2) cap=CapProjecting;
1518     else if (cpar[3]==1) cap=CapRound;
1519     else cap=CapButt;
1520     if (cpar[4]==2) join=JoinBevel;
1521     else if (cpar[4]==1) join=JoinRound;
1522     else join=JoinMiter;
1523     XSetLineAttributes(Disp,mxlocal->gc,width,style,cap,join);
1524     if (style!=LineSolid)
1525       XSetDashes(Disp,mxlocal->gc,0,dashlist,dashn);
1526     if (cpar[1]!=0) memfree(dashlist);
1527     break;
1528   case 'G':
1529     XSetForeground(Disp,mxlocal->gc,RGB(cpar[1],cpar[2],cpar[3]));
1530     break;
1531   case 'M':
1532     mxlocal->cpx=cpar[1];
1533     mxlocal->cpy=cpar[2];
1534     break;
1535   case 'N':
1536     mxlocal->cpx+=cpar[1];
1537     mxlocal->cpy+=cpar[2];
1538     break;
1539   case 'L':
1540     XDrawLine(Disp,mxlocal->win,mxlocal->gc,
1541               mxd2px(cpar[1]),mxd2py(cpar[2]),
1542               mxd2px(cpar[3]),mxd2py(cpar[4]));
1543     break;
1544   case 'T':
1545     x=mxd2px(cpar[1]);
1546     y=mxd2py(cpar[2]);
1547     if (mxlocal->linetonum==0) {
1548       mxlocal->points[0].x=mxd2px(mxlocal->cpx);
1549       mxlocal->points[0].y=mxd2py(mxlocal->cpy);;
1550       mxlocal->linetonum++;
1551     }
1552     mxlocal->points[mxlocal->linetonum].x=x;
1553     mxlocal->points[mxlocal->linetonum].y=y;
1554     mxlocal->linetonum++;
1555     mxlocal->cpx=cpar[1];
1556     mxlocal->cpy=cpar[2];
1557     break;
1558   case 'C':
1559     if (cpar[7]==0) {
1560       XDrawArc(Disp,mxlocal->win,mxlocal->gc,
1561                mxd2px(cpar[1]-cpar[3]),
1562                mxd2py(cpar[2]-cpar[4]),
1563                mxd2p(2*cpar[3]),mxd2p(2*cpar[4]),
1564                (int )cpar[5]*64/100,(int )cpar[6]*64/100);
1565     } else {
1566       if ((mxd2p(cpar[3])<2) && (mxd2p(cpar[4])<2)) {
1567         XDrawPoint(Disp,mxlocal->win,mxlocal->gc,
1568                    mxd2px(cpar[1]),mxd2py(cpar[2]));
1569       } else {
1570         if (cpar[7]==1) arcmode=ArcPieSlice;
1571         else arcmode=ArcChord;
1572         XSetArcMode(Disp,mxlocal->gc,arcmode);
1573         XFillArc(Disp,mxlocal->win,mxlocal->gc,
1574                mxd2px(cpar[1]-cpar[3]),
1575                mxd2py(cpar[2]-cpar[4]),
1576                mxd2p(2*cpar[3]),mxd2p(2*cpar[4]),
1577                (int )cpar[5]*64/100,(int )cpar[6]*64/100);
1578       }
1579     }
1580     break;
1581   case 'B':
1582     if (cpar[1]<=cpar[3]) {
1583       x1=mxd2px(cpar[1]);
1584       x2=mxd2p(cpar[3]-cpar[1]);
1585     } else {
1586       x1=mxd2px(cpar[3]);
1587       x2=mxd2p(cpar[1]-cpar[3]);
1588     }
1589     if (cpar[2]<=cpar[4]) {
1590       y1=mxd2py(cpar[2]);
1591       y2=mxd2p(cpar[4]-cpar[2]);
1592     } else {
1593       y1=mxd2py(cpar[4]);
1594       y2=mxd2p(cpar[2]-cpar[4]);
1595     }
1596     if (cpar[5]==0) {
1597       XDrawRectangle(Disp,mxlocal->win,mxlocal->gc,
1598               x1,y1,x2+1,y2+1);
1599     } else {
1600       XFillRectangle(Disp,mxlocal->win,mxlocal->gc,
1601               x1,y1,x2+1,y2+1);
1602     }
1603     break;
1604   case 'P':
1605     XDrawPoint(Disp,mxlocal->win,mxlocal->gc,
1606                mxd2px(cpar[1]),mxd2py(cpar[2]));
1607     break;
1608   case 'R':
1609     if (cpar[1]==0) break;
1610     if ((xpoint=memalloc(sizeof(XPoint)*cpar[1]))==NULL) break;
1611     for (i=0;i<cpar[1];i++) {
1612       xpoint[i].x=mxd2px(cpar[i*2+2]);
1613       xpoint[i].y=mxd2py(cpar[i*2+3]);
1614     }
1615     XDrawLines(Disp,mxlocal->win,mxlocal->gc,
1616                xpoint,cpar[1],CoordModeOrigin);
1617     memfree(xpoint);
1618     break;
1619   case 'D':
1620     if (cpar[1]==0) break;
1621     if ((xpoint=memalloc(sizeof(XPoint)*cpar[1]))==NULL) break;
1622     for (i=0;i<cpar[1];i++) {
1623       xpoint[i].x=mxd2px(cpar[i*2+3]);
1624       xpoint[i].y=mxd2py(cpar[i*2+4]);
1625     }
1626     if (cpar[2]==0) {
1627       XDrawLines(Disp,mxlocal->win,mxlocal->gc,
1628                  xpoint,cpar[1],CoordModeOrigin);
1629     } else if (cpar[2]==1) {
1630       XSetFillRule(Disp,mxlocal->gc,EvenOddRule);
1631       XFillPolygon(Disp,mxlocal->win,mxlocal->gc,
1632                    xpoint,cpar[1],Complex,CoordModeOrigin);
1633     } else {
1634       XSetFillRule(Disp,mxlocal->gc,WindingRule);
1635       XFillPolygon(Disp,mxlocal->win,mxlocal->gc,
1636                    xpoint,cpar[1],Complex,CoordModeOrigin);
1637     }
1638     memfree(xpoint);
1639     break;
1640   case 'F':
1641     memfree(mxlocal->fontalias);
1642     if ((mxlocal->fontalias=memalloc(strlen(cstr)+1))==NULL) break;
1643     strcpy(mxlocal->fontalias,cstr);
1644     break;
1645   case 'H':
1646     fontspace=cpar[2]/72.0*25.4;
1647     mxlocal->fontspace=fontspace;
1648     fontsize=cpar[1]/72.0*25.4;
1649     mxlocal->fontsize=fontsize;
1650     fontcashsize=mxd2p(fontsize);
1651     fontcashdir=cpar[3];
1652     fontdir=cpar[3]*MPI/18000.0;
1653     fontsin=sin(fontdir);
1654     fontcos=cos(fontdir);
1655     mxlocal->fontsin=fontsin;
1656     mxlocal->fontcos=fontcos;
1657     mxlocal->loadfontf=mxloadfont(Disp,mxlocal->gc,
1658                                   mxlocal->fontalias,fontcashsize,fontcashdir,
1659                                   fontsin,fontcos,TRUE);
1660     break;
1661   case 'S':
1662     if (mxlocal->loadfontf==-1) break;
1663     x0=mxlocal->cpx;
1664     y0=mxlocal->cpy;
1665     i=0;
1666     while (i<strlen(cstr)) {
1667       if (cstr[i]=='\\') {
1668         if (cstr[i+1]=='x') {
1669           if (toupper(cstr[i+2])>='A') ch[0]=toupper(cstr[i+2])-'A'+10;
1670           else ch[0]=cstr[i+2]-'0';
1671           if (toupper(cstr[i+3])>='A') ch[0]=ch[0]*16+toupper(cstr[i+3])-'A'+10;
1672           else ch[0]=ch[0]*16+cstr[i+3]-'0';
1673           i+=4;
1674         } else if (cstr[i+1]!='\0') {
1675           ch[0]=cstr[i];
1676           i+=2;
1677         }
1678       } else {
1679         ch[0]=cstr[i];
1680         i++;
1681       }
1682       mxXDrawString(mxlocal->font[0],Disp,mxlocal->win,mxlocal->gc,
1683                     mxd2px(nround(x0)),
1684                     mxd2py(nround(y0)),ch);
1685       if ((mxlocal->font[0].fonttype==BOLD)
1686        || (mxlocal->font[0].fonttype==BOLDITALIC)) {
1687         bs=mxlocal->fontsize*0.018;
1688         mxXDrawString(mxlocal->font[0],Disp,mxlocal->win,mxlocal->gc,
1689           mxd2px(nround(x0+bs)),
1690           mxd2py(nround(y0)),ch);
1691         mxXDrawString(mxlocal->font[0],Disp,mxlocal->win,mxlocal->gc,
1692           mxd2px(nround(x0)),
1693           mxd2py(nround(y0-bs)),ch);
1694         mxXDrawString(mxlocal->font[0],Disp,mxlocal->win,mxlocal->gc,
1695           mxd2px(nround(x0+bs)),
1696           mxd2py(nround(y0-bs)),ch);
1697       }
1698       fontwidth=mxp2d(mxXTextWidth(mxlocal->font[0],mxlocal->minus_hyphen,ch));
1699       x0+=(fontwidth+mxlocal->fontspace)*mxlocal->fontcos;
1700       y0-=(fontwidth+mxlocal->fontspace)*mxlocal->fontsin;
1701     }
1702     mxlocal->cpx=nround(x0);
1703     mxlocal->cpy=nround(y0);
1704     break;
1705   case 'K':
1706     if (mxlocal->loadfontf==-1) break;
1707     i=0;
1708     x0=mxlocal->cpx;
1709     y0=mxlocal->cpy;
1710     while (i<strlen(cstr)) {
1711       if (niskanji((unsigned char)cstr[i]) && (cstr[i+1]!='\0')) {
1712         jis=njms2jis(((unsigned char)cstr[i] << 8)+(unsigned char)cstr[i+1]);
1713         kanji[0].byte1=jis >> 8;
1714         kanji[0].byte2=jis & 0xff;
1715         XDrawString16(Disp,mxlocal->win,mxlocal->gc,
1716                   mxd2px(nround(x0)),
1717                   mxd2py(nround(y0)),kanji,1);
1718         if ((mxlocal->font[0].fonttype==BOLD)
1719          || (mxlocal->font[0].fonttype==BOLDITALIC)) {
1720           bs=mxlocal->fontsize*0.018;
1721           XDrawString16(Disp,mxlocal->win,mxlocal->gc,
1722             mxd2px(nround(x0+bs)),
1723             mxd2py(nround(y0)),kanji,1);
1724           XDrawString16(Disp,mxlocal->win,mxlocal->gc,
1725             mxd2px(nround(x0)),
1726             mxd2py(nround(y0-bs)),kanji,1);
1727           XDrawString16(Disp,mxlocal->win,mxlocal->gc,
1728             mxd2px(nround(x0+bs)),
1729             mxd2py(nround(y0-bs)),kanji,1);
1730         }
1731         if ((mxlocal->font[0]).fontstruct==NULL) {
1732           fontwidth=mxp2d((mxlocal->font[0]).fontsize);
1733         } else {
1734           fontwidth=mxp2d(XTextWidth16((mxlocal->font[0]).fontstruct,kanji,1));
1735         }
1736         x0+=(fontwidth+mxlocal->fontspace)*mxlocal->fontcos;
1737         y0-=(fontwidth+mxlocal->fontspace)*mxlocal->fontsin;
1738         i+=2;
1739       } else i++;
1740     }
1741     mxlocal->cpx=nround(x0);
1742     mxlocal->cpy=nround(y0);
1743     break;
1744   default: break;
1745   }
1746   return 0;
1747 }
1748 
mx_charwidth(struct objlist * obj,char * inst,char * rval,int argc,char ** argv)1749 int mx_charwidth(struct objlist *obj,char *inst,char *rval,
1750                     int argc,char **argv)
1751 {
1752   struct mxlocal *mxlocal;
1753   char ch[3];
1754   char *font;
1755   double size;
1756   int fontcashsize;
1757   XChar2b kanji[1];
1758   unsigned int jis;
1759   int cashpos;
1760   XFontStruct *fontstruct;
1761 
1762   ch[0]=(*(unsigned int *)(argv[3]) & 0xff);
1763   ch[1]=(*(unsigned int *)(argv[3]) & 0xff00) >> 8;
1764   ch[2]='\0';
1765   size=(*(int *)(argv[4]))/72.0*25.4;
1766   font=(char *)(argv[5]);
1767   if (_getobj(obj,"_local",inst,&mxlocal)) return 1;
1768   fontcashsize=mxd2p(size);
1769   if ((cashpos=mxloadfont(Disp,NULL,font,fontcashsize,0,0.0,1.0,FALSE))!=-1) {
1770     fontstruct=(mxlocal->font[cashpos]).fontstruct;
1771     if (fontstruct==NULL) {
1772       if (ch[1]!=0) *(int *)rval=size;
1773       else *(int *)rval=nround(size*0.600);
1774     } else {
1775       if (ch[1]!=0) {
1776         jis=njms2jis(*(unsigned int *)(argv[3]));
1777         kanji[0].byte1=jis >> 8;
1778         kanji[0].byte2=jis & 0xff;
1779         *(int *)rval=mxp2d(XTextWidth16(fontstruct,kanji,1));
1780       } else {
1781         *(int *)rval=mxp2d(mxXTextWidth(mxlocal->font[cashpos],
1782                                         mxlocal->minus_hyphen,ch));
1783       }
1784     }
1785   } else *(int *)rval=nround(size*0.600);
1786   return 0;
1787 }
1788 
mx_charheight(struct objlist * obj,char * inst,char * rval,int argc,char ** argv)1789 int mx_charheight(struct objlist *obj,char *inst,char *rval,
1790                   int argc,char **argv)
1791 {
1792   struct mxlocal *mxlocal;
1793   char *font;
1794   double size;
1795   int fontcashsize;
1796   char *func;
1797   int height;
1798   int cashpos;
1799   XFontStruct *fontstruct;
1800   struct fontmap *fcur;
1801   int twobyte;
1802 
1803   func=(char *)argv[1];
1804   if (strcmp0(func,"_charascent")==0) height=TRUE;
1805   else height=FALSE;
1806   size=(*(int *)(argv[3]))/72.0*25.4;
1807   font=(char *)(argv[4]);
1808   if (_getobj(obj,"_local",inst,&mxlocal)) return 1;
1809   fcur=mxlocal->fontmaproot;
1810   twobyte=FALSE;
1811   while (fcur!=NULL) {
1812     if (strcmp(font,fcur->fontalias)==0) {
1813       twobyte=fcur->twobyte;
1814       break;
1815     }
1816     fcur=fcur->next;
1817   }
1818   fontcashsize=mxd2p(size);
1819   if ((cashpos=mxloadfont(Disp,NULL,font,fontcashsize,0,0.0,1.0,FALSE))!=-1) {
1820     fontstruct=(mxlocal->font[cashpos]).fontstruct;
1821     if (fontstruct==NULL) {
1822       if (twobyte) {
1823         if (height) *(int *)rval=nround(size*0.791);
1824         else *(int *)rval=nround(size*0.250);
1825       } else {
1826         if (height) *(int *)rval=nround(size*0.562);
1827         else *(int *)rval=nround(size*0.250);
1828       }
1829     } else {
1830       if (height) *(int *)rval=mxp2d(fontstruct->ascent);
1831       else *(int *)rval=mxp2d(fontstruct->descent);
1832     }
1833   } else {
1834     if (height) *(int *)rval=nround(size*0.562);
1835     else *(int *)rval=nround(size*0.250);
1836   }
1837   return 0;
1838 }
1839 
mxfullpathngp(struct objlist * obj,char * inst,char * rval,int argc,char ** argv)1840 int mxfullpathngp(struct objlist *obj,char *inst,char *rval,int argc,char **argv)
1841 {
1842   char *name,*ngp2;
1843 
1844   name=(char *)argv[2];
1845   if (name==NULL) ngp2=NULL;
1846   else ngp2=getbasename(name);
1847   putobj(menulocal.obj,"ngp",0,ngp2);
1848   return 0;
1849 }
1850 
1851 #define TBLNUM 17
1852 
1853 struct objtable x11menu[TBLNUM] = {
1854   {"init",NVFUNC,NEXEC,menuinit,NULL,0},
1855   {"done",NVFUNC,NEXEC,menudone,NULL,0},
1856   {"menu",NVFUNC,NREAD|NEXEC,menumenu,NULL,0},
1857   {"ngp",NSTR,NREAD|NWRITE,NULL,NULL,0},
1858   {"fullpath_ngp",NSTR,NREAD|NWRITE,mxfullpathngp,NULL,0},
1859   {"dpi",NINT,NREAD|NWRITE,mxdpi,NULL,0},
1860   {"auto_redraw",NBOOL,NREAD|NWRITE,mxautoredraw,NULL,0},
1861   {"redraw_flag",NBOOL,NREAD|NWRITE,mxredrawflag,NULL,0},
1862   {"redraw",NVFUNC,NREAD|NEXEC,mxredraw,"",0},
1863   {"flush",NVFUNC,NREAD|NEXEC,mxflush,"",0},
1864   {"clear",NVFUNC,NREAD|NEXEC,mxclear,"",0},
1865   {"_output",NVFUNC,0,mx_output,NULL,0},
1866   {"_charwidth",NIFUNC,0,mx_charwidth,NULL,0},
1867   {"_charascent",NIFUNC,0,mx_charheight,NULL,0},
1868   {"_chardescent",NIFUNC,0,mx_charheight,NULL,0},
1869   {"_evloop",NVFUNC,0,mx_evloop,NULL,0},
1870   {"_local",NPOINTER,0,NULL,NULL,0},
1871 };
1872 
addmenu()1873 void *addmenu()
1874 {
1875   return addobject(NAME,ALIAS,PARENT,VERSION,TBLNUM,x11menu,ERRNUM,
1876                    menuerrorlist,NULL,NULL);
1877 }
1878