ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/crossedit/App.c
Revision: 1.1.1.1 (vendor branch)
Committed: Fri Feb 3 07:11:42 2006 UTC (18 years, 3 months ago) by root
Content type: text/plain
Branch: UPSTREAM
CVS Tags: UPSTREAM_2006_03_15, UPSTREAM_2006_02_22, UPSTREAM_2006_02_03
Changes since 1.1: +0 -0 lines
Log Message:
initial import

File Contents

# User Rev Content
1 root 1.1 /*
2     * CrossEdit - game world editor
3     * Copyright (C) 1993 Jarkko Sonninen & Petri Heinila
4     *
5     * This program is free software; you can redistribute it and/or modify
6     * it under the terms of the GNU General Public License as published by
7     * the Free Software Foundation; either version 2 of the License, or
8     * (at your option) any later version.
9     *
10     * This program is distributed in the hope that it will be useful,
11     * but WITHOUT ANY WARRANTY; without even the implied warranty of
12     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13     * GNU General Public License for more details.
14     *
15     * You should have received a copy of the GNU General Public License
16     * along with this program; if not, write to the Free Software
17     * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18     *
19     * The authors can be reached via e-mail to Jarkko.Sonninen@lut.fi
20     * or Petri.Heinila@lut.fi .
21     */
22    
23     #include "Defines.h"
24     #include "global.h"
25    
26     #include "Ansi.h"
27     #include "X11.h"
28    
29     #include "CrList.h"
30     #include "CrFace.h"
31     #include "CrEdit.h"
32    
33     #include "Edit.h"
34     #include "Attr.h"
35     #include "Cnv.h"
36     #include "Bitmaps.h"
37     #include "App.h"
38     #include "debug.h"
39     #include "util.h"
40    
41     #include <proto.h>
42    
43     Pixmap *pixmaps; /* list of pixmaps */
44     Pixmap *masks; /* list of masks */
45     int FontSize; /* Size of font (really images) */
46     #define E_EDITABLE (E_MONSTER | E_EXIT | E_TREASURE | E_BACKGROUND | \
47     E_DOOR | E_SPECIAL | E_SHOP | E_NORMAL | E_FALSE_WALL)
48    
49     ArchFlagsRec archFlags[] = {
50     { 0, "toggle", E_EDITABLE },
51     { 0, "monster", E_MONSTER },
52     { 0, "exit", E_EXIT },
53     { 0, "treasure", E_TREASURE },
54     { 0, "background", E_BACKGROUND },
55     { 0, "door", E_DOOR },
56     { 0, "special", E_SPECIAL },
57     { 0, "shop", E_SHOP },
58     { 0, "normal", E_NORMAL },
59     { 0, "false wall", E_FALSE_WALL },
60     { 0, "wall", E_WALL },
61     { 0, "equipment", E_EQUIPMENT },
62     { 0, "other", E_OTHER },
63     { 0, "artifact", E_ARTIFACT },
64     { 0, NULL, 0 },
65     };
66    
67     /*
68     * plaah: where to put these ???
69     * 0.91.9 - moved to start of file - needed for ReadPixmaps function.
70     */
71     XColor exactcolor, discolor[13];
72     Colormap colormap=(Colormap)NULL;
73    
74    
75     /**********************************************************************
76     * private
77     **********************************************************************/
78    
79     #if 0
80     static void AbsToCr(App self,String abs)
81     {
82     char mapdir[PATH_MAX+1],path[PATH_MAX+1],*current,*filename;
83    
84     strcpy(path,abs);
85    
86     current = strlen(mapdir) + path;
87     filename = strrchr(path,'/');
88     *filename = 0;
89     filename++;
90     strcpy(self->path->current,current);
91     strcpy(self->path->filename,filename);
92     }
93     #endif
94    
95     static void Picks(XtPointer client,String entryPath)
96     {
97     App self = (App)client;
98     String path;
99     char mapdir[PATH_MAX+1];
100     int i=0;
101    
102     sprintf(mapdir,"%s/%s",settings.datadir,settings.mapdir);
103     for(path = entryPath; mapdir[i++] == *path++;);
104    
105     debug1("Picks() %s\n",path);
106     AppEditInsert(self,path,Pick);
107     }
108    
109     static void Walls(XtPointer client,String entryPath)
110     {
111     App self = (App)client;
112     String path;
113     char mapdir[PATH_MAX+1];
114     int i = 0;
115    
116     sprintf(mapdir,"%s/%s",settings.datadir,settings.mapdir);
117     for(path = entryPath; mapdir[i++] == *path++;);
118    
119     debug1("Walls() %s\n",path);
120     AppEditInsert(self,path,Wall);
121     }
122    
123     static void Info(XtPointer client,String entryPath)
124     {
125     App self = (App)client;
126    
127     CnvBrowseShowFile(self->info,entryPath);
128     }
129    
130    
131     /**********************************************************************
132     * select
133     **********************************************************************/
134    
135     /*
136     * member: filter archetype list
137     * at : requested archetype
138     * return: True, if show out
139     */
140     static Boolean AppArchFilter (App self,archetype * at)
141     {
142     if(self->arch.all) return True;
143     if (!at->editable) return False;
144     return (self->arch.flags & at->editable) ? True : False;
145     }
146    
147     /*
148     * function: give widget head of list
149     */
150     static CrListNode Next(XtPointer client,XtPointer call)
151     {
152     App self = (App)client;
153     CrListNode retNode = (CrListNode)call;
154     static struct _CrListNode node;
155     archetype *at;
156    
157    
158     if(retNode) {
159     at = ((archetype *)retNode->ptr)->next;
160     } else { /* begin */
161     at = first_archetype;
162     }
163    
164     while (at && !AppArchFilter(self,at))
165     at = at->next;
166    
167     if(at) {
168     node.face = at->clone.face;
169     node.name = at->name;
170     node.ptr = (XtPointer)at;
171     return &node;
172     }
173     return (CrListNode)NULL;
174     }
175    
176     /*
177     * create attributes from inventory
178     */
179     static void SelectCb(Widget w,XtPointer client,XtPointer call)
180     {
181     CrListCall ret = (CrListCall)call;
182     App self = (App)client;
183    
184     debug0 ("SelectCb\n");
185     /* self->item.wall_map = NULL; */
186     AppItemSet (self,NULL,& ((archetype *) ret->node)->clone,0);
187     /*
188     if(self->attr.isup) {
189     AttrSetArch(&self->attr,self->item.at);
190     }
191     */
192     return;
193     }
194    
195     /**********************************************************************
196     * look
197     **********************************************************************/
198    
199     /*
200     * function: give widget head of list
201     */
202     static CrListNode lookNext(XtPointer client,XtPointer call)
203     {
204     App self = (App)client;
205     CrListNode retNode = (CrListNode)call;
206     static struct _CrListNode node;
207     object *op = NULL;
208    
209     if(self->look.edit == NULL) return NULL;
210    
211     if(retNode) { /* next */
212     op = ((object *)retNode->ptr)->below;
213     } else {
214     /* begin */
215     op = MapGetObjectZ(self->look.edit->emap,
216     self->look.rect.x,
217     self->look.rect.y,0);
218     }
219     if(op) {
220     node.face = op->face;
221     node.name = op->name;
222     node.ptr = (XtPointer)op;
223     return &node;
224     }
225     return (CrListNode)NULL;
226     }
227    
228     /*
229     *
230     */
231     static void lookSelectCb(Widget w,XtPointer client,XtPointer call)
232     {
233     App self = (App)client;
234     CrListCall ret = (CrListCall)call;
235     object *ob;
236    
237     ob = ret->node;
238     if (ob->head)
239     ob = ob->head;
240     if(!self->attr) {
241     self->attr = AttrCreate
242     ("attr", self, ob, AttrDescription, GetType(ob), self->look.edit);
243     } else {
244     AttrChange(self->attr,ob, GetType(ob), self->look.edit);
245     }
246     return;
247     }
248    
249     /*
250     * callback: insert object to look window
251     */
252     static void lookInsertCb(Widget w,XtPointer client,XtPointer call)
253     {
254     App self = (App)client;
255     CrListCall ret = (CrListCall)call;
256    
257     EditInsert (self->look.edit,
258     self->look.rect.x, self->look.rect.y, ret->index);
259     return;
260     }
261    
262     /*
263     * callback: delete object from look window
264     */
265     static void lookDeleteCb(Widget w,XtPointer client,XtPointer call)
266     {
267     App self = (App)client;
268     CrListCall ret = (CrListCall)call;
269     EditDelete (self->look.edit, self->look.rect.x, self->look.rect.y,
270     ret->index);
271     return;
272     }
273     /**********************************************************************
274     * File-menu
275     * New
276     * Open
277     * CrossFire
278     * Quit
279     **********************************************************************/
280    
281     static void AppNewCb(Widget w,XtPointer client,XtPointer call)
282     {
283     App self = (App)client;
284     AppEditInsert(self,NULL,Regular);
285     }
286    
287     #if 0
288     static void AppClipCb(Widget w,XtPointer client,XtPointer call)
289     {
290     App self = (App)client;
291     AppEditInsert(self,NULL,ClipBoard);
292     }
293     #endif
294    
295    
296     static void AppOpenCb (Widget w, XtPointer client, XtPointer call)
297     {
298     App self = (App)client;
299     char path[PATH_MAX+1];
300     if(CnvPathSelect(self->path) != CnvPathOk) return;
301     sprintf(path,"%s/%s",self->path->current,self->path->filename);
302     AppEditInsert(self,path,Regular);
303     }
304    
305     static void AppCrossfireCb (Widget w, XtPointer client, XtPointer call)
306     {
307     App self = (App)client;
308     int pid;
309     char *prog,*arg1;
310    
311     if(!self->res.cmdCrossfire) {
312     CnvNotify("No command defined to *cmdCrossfire:","Continue",NULL);
313     return;
314     }
315     prog = strtok(self->res.cmdCrossfire," \t");
316     arg1 = strtok(NULL," \t"); /* kludge for -pix */
317     switch(pid = fork()) {
318     case -1:
319     CnvNotify("Cannot open new process","OK",NULL);
320     return;
321     case 0: /* child */
322     if(execlp(prog,prog,arg1,NULL) == -1) {
323     char buf[BUFSIZ];
324     sprintf(buf,"cannot execute \"%s\"",self->res.cmdCrossfire);
325     CnvWarn(self->shell,buf);
326     exit(0);
327     }
328     default: /* parent */
329     debug2("CbMainCrossfire() %d %s started\n",pid,self->res.cmdCrossfire);
330     return;
331     }
332     }
333    
334     /*
335     *
336     */
337     static void AppQuitCb (Widget w, XtPointer client, XtPointer call)
338     {
339     App self = (App)client;
340    
341     AppDestroy(self);
342     XtDestroyApplicationContext (XtWidgetToApplicationContext (w));
343     exit (0);
344     }
345    
346     /*
347     * file-menu definition
348     */
349     static CnvMenuRec fileMenu[] = {
350     {"new" ,AppNewCb},
351     {"open" ,AppOpenCb},
352     #if 0
353     {"clipboard",AppClipCb},
354     #endif
355     {"-----" ,NULL},
356     {"crossfire",AppCrossfireCb},
357     {"-----" ,NULL},
358     {"quit" ,AppQuitCb},
359     {"" ,NULL}
360     };
361    
362     /**********************************************************************
363     * toggle-menu
364     **********************************************************************/
365    
366     static void dirtyfixscrollbar (Widget w) {
367     Widget s = XtParent (w);
368     XawViewportSetCoordinates (s, 0, 0);
369     /* undocumented function */
370     }
371    
372    
373     static void ToggleFlagCb(Widget w, XtPointer client, XtPointer call)
374     {
375     App self = (App)client;
376     int i;
377    
378     for (i = 0; archFlags[i].name; i++) {
379     if (archFlags[i].w == w) {
380     self->arch.flags ^= archFlags[i].flags;
381     break;
382     }
383     }
384     dirtyfixscrollbar (self->arch.w);
385     XtVaSetValues (self->arch.w, XtNpackage, self, NULL);
386     for (i = 0; archFlags[i].name; i++) {
387     XtVaSetValues
388     (archFlags[i].w,
389     XtNleftBitmap,
390     (self->arch.flags & archFlags[i].flags) ? bitmaps.mark : None,
391     NULL);
392     }
393     return;
394     }
395    
396    
397     static void ToggleAllCb(Widget w, XtPointer client, XtPointer call)
398     {
399     App self = (App)client;
400    
401     self->arch.all = !self->arch.all;
402     dirtyfixscrollbar (self->arch.w);
403    
404     XtVaSetValues (self->arch.w, XtNpackage, self, NULL);
405     XtVaSetValues(w,
406     XtNleftBitmap,
407     self->arch.all ? bitmaps.mark : None,
408     NULL);
409     }
410    
411     static void ToggleClipCb(Widget w, XtPointer client, XtPointer call)
412     {
413     App self = (App)client;
414    
415     self->clipon = !self->clipon;
416     XtVaSetValues(w,
417     XtNleftBitmap,
418     self->clipon ? bitmaps.mark : None,
419     NULL);
420     if(self->clipon)
421     XtPopup(self->clip->shell,XtGrabNone);
422     else
423     XtPopdown(self->clip->shell);
424     }
425    
426     static void AppToggleMenu(App self,String name,Widget parent)
427     {
428     Widget shell,entry;
429     int i;
430    
431     shell = XtVaCreatePopupShell
432     (name,simpleMenuWidgetClass,parent,
433     NULL);
434    
435     entry = XtVaCreateManagedWidget
436     ("all",smeBSBObjectClass,shell,
437     XtNleftBitmap,
438     self->arch.all ? bitmaps.mark : None,
439     NULL);
440     XtAddCallback(entry,XtNcallback,ToggleAllCb,(XtPointer)self);
441    
442     for (i = 0; archFlags[i].name; i++) {
443     archFlags[i].w = XtVaCreateManagedWidget
444     (archFlags[i].name, smeBSBObjectClass,shell,
445     XtNleftBitmap,
446     (self->arch.flags & archFlags[i].flags) ?
447     bitmaps.mark : None,
448     NULL);
449     XtAddCallback
450     (archFlags[i].w,XtNcallback,ToggleFlagCb,(XtPointer)self);
451     }
452    
453     XtVaCreateManagedWidget ("line", smeLineObjectClass, shell, NULL);
454     entry = XtVaCreateManagedWidget
455     ("clipboard",smeBSBObjectClass,shell,
456     XtNleftBitmap,
457     self->clipon ? bitmaps.mark : None,
458     NULL);
459     XtAddCallback(entry,XtNcallback,ToggleClipCb,(XtPointer)self);
460     }
461    
462     /**********************************************************************
463     * editMenu callbacks (cut,copy,paste,...)
464     **********************************************************************/
465    
466     /*
467     * callback: Cut
468     */
469     static void CutCb (Widget w, XtPointer client, XtPointer call)
470     {
471     App self = (App)client;
472     XRectangle rect;
473    
474     debug0 ("AppCutCb()\n");
475     if(!self->look.edit) {
476     CnvNotify("Select area to Cut","Continue",NULL);
477     return;
478     }
479     EditResizeScroll(self->clip,self->look.rect.width,
480     self->look.rect.height,0,0);
481     /*
482     EditCopyRectangle(self->look.edit,self->clip,EditRectAll,
483     self->look.rect.x,self->look.rect.y);
484     */
485     rect.x = rect.y = 0;
486     rect.width = self->look.rect.width;
487     rect.height = self->look.rect.height;
488     EditWipeRectangle(self->clip,rect);
489     EditCopyRectangle(self->clip,self->look.edit,self->look.rect,0,0);
490     EditWipeRectangle(self->look.edit,self->look.rect);
491    
492     EditModified(self->look.edit);
493     CrEditRefresh(self->look.edit->w,self->look.rect);
494     AppSelectUnset(self);
495     }
496    
497     /*
498     * callback: Copy
499     */
500     static void CopyCb (Widget w, XtPointer client, XtPointer call)
501     {
502     App self = (App)client;
503     XRectangle rect;
504    
505     debug0 ("AppCopyCb()\n");
506     if(!self->look.edit) {
507     CnvNotify("Select area to Copy","Continue",NULL);
508     return;
509     }
510     EditResizeScroll(self->clip,self->look.rect.width,
511     self->look.rect.height,0,0);
512     rect.x = rect.y = 0;
513     rect.width = self->look.rect.width;
514     rect.height = self->look.rect.height;
515     EditWipeRectangle(self->clip,rect);
516     EditCopyRectangle(self->clip,self->look.edit,self->look.rect,0,0);
517    
518     AppSelectUnset(self);
519     }
520    
521     /*
522     * callback: Paste
523     */
524     static void PasteCb (Widget w, XtPointer client, XtPointer call)
525     {
526     App self = (App)client;
527    
528     debug0 ("AppPasteCb()\n");
529    
530     if(!self->look.edit) {
531     CnvNotify("Select point to Paste","Continue",NULL);
532     return;
533     }
534     EditCopyRectangle(self->look.edit,self->clip,EditRectAll,
535     self->look.rect.x,self->look.rect.y);
536    
537     EditModified(self->look.edit);
538    
539     AppSelectUnset(self);
540     }
541    
542     /*
543     * callback: Fill
544     */
545     static void FillCb (Widget w, XtPointer client, XtPointer call)
546     {
547     App self = (App)client;
548    
549     debug0 ("AppFillCb()\n");
550     if(!self->look.edit) {
551     CnvNotify("Select point to Fill","Continue",NULL);
552     return;
553     }
554     EditPerformFill(self->look.edit,self->look.rect.x,self->look.rect.y);
555     EditModified(self->look.edit);
556     AppSelectUnset(self);
557     }
558    
559     /*
560     * callback: FillBelow
561     */
562     static void FillBelowCb (Widget w, XtPointer client, XtPointer call)
563     {
564     App self = (App)client;
565    
566     debug0 ("AppFillCb()\n");
567     if(!self->look.edit) {
568     CnvNotify("Select point to Fill","Continue",NULL);
569     return;
570     }
571     EditPerformFillBelow(self->look.edit,self->look.rect.x,self->look.rect.y);
572     EditModified(self->look.edit);
573     AppSelectUnset(self);
574     }
575    
576     /*
577     * callback: Box
578     */
579     static void BoxCb (Widget w, XtPointer client, XtPointer call)
580     {
581     App self = (App)client;
582    
583     debug0 ("AppBoxCb()\n");
584     if(!self->look.edit) {
585     CnvNotify("Select area to fill","Continue",NULL);
586     return;
587     }
588     EditFillRectangle(self->look.edit, self->look.rect);
589     EditModified(self->look.edit);
590     AppSelectUnset(self);
591     }
592    
593     /*
594     * callback: Wipe
595     */
596     static void WipeCb (Widget w, XtPointer client, XtPointer call)
597     {
598     App self = (App)client;
599    
600     debug0 ("AppWipeCb()\n");
601     if(!self->look.edit) {
602     CnvNotify("Select area to Wipe","Continue",NULL);
603     return;
604     }
605    
606     EditShaveRectangle(self->look.edit, self->look.rect);
607     EditModified(self->look.edit);
608     AppSelectUnset(self);
609     }
610    
611     /*
612     * callback: WipeBelow
613     */
614     static void WipeBelowCb (Widget w, XtPointer client, XtPointer call)
615     {
616     App self = (App)client;
617    
618     debug0 ("AppWipeBelowCb()\n");
619     if(!self->look.edit) {
620     CnvNotify("Select area to Wipe","Continue",NULL);
621     return;
622     }
623    
624     EditShaveRectangleBelow(self->look.edit, self->look.rect);
625     EditModified(self->look.edit);
626     AppSelectUnset(self);
627     }
628    
629     /*
630     * menu definition
631     */
632     static CnvMenuRec editMenu[] = {
633     {"cut" ,CutCb},
634     {"copy" ,CopyCb},
635     {"paste",PasteCb},
636     {"-----",NULL},
637     {"fill" ,FillCb},
638     {"fillbelow" ,FillBelowCb},
639     {"box" ,BoxCb},
640     {"wipe" ,WipeCb},
641     {"wipebelow" ,WipeBelowCb},
642     {"", NULL}
643     };
644    
645     /**********************************************************************
646     * layout
647     **********************************************************************/
648    
649     /*
650     * member: create application window layout
651     */
652     static void Layout(App self)
653     {
654     Widget pane, box,use,view;
655     char path[PATH_MAX+1];
656    
657     /*** vertical Pane of widgets ***/
658     pane = XtCreateManagedWidget
659     ("pane", panedWidgetClass, self->shell,
660     NULL, 0);
661    
662     /*** menubar ***/
663     box = XtVaCreateManagedWidget
664     ("box", boxWidgetClass, pane,
665     XtNorientation, XtorientHorizontal,
666     NULL);
667     use = XtVaCreateManagedWidget
668     ("fileButton",menuButtonWidgetClass, box,
669     XtNmenuName,"appFileMenu",
670     NULL);
671     CnvMenu("appFileMenu",use,fileMenu,(XtPointer)self);
672    
673     use = XtVaCreateManagedWidget
674     ("infoButton",menuButtonWidgetClass, box,
675     XtNmenuName,"info",
676     NULL);
677     sprintf(path,"%s/%s",settings.datadir,"doc");
678     self->infof = CnvFilesCreate("info",use,Info,(XtPointer)self,path);
679    
680     /*** look ***/
681     self->look.info = XtVaCreateManagedWidget
682     ("info",labelWidgetClass,pane,
683     NULL);
684    
685     view = XtVaCreateManagedWidget
686     ("view", viewportWidgetClass,pane,
687     NULL);
688     self->look.w = XtVaCreateManagedWidget
689     ("cross",crListWidgetClass,view,
690     XtNpackage, self,
691     XtNnext, lookNext,
692     NULL);
693     XtAddCallback(self->look.w,XtNinsertCallback,lookInsertCb,
694     (XtPointer)self);
695     XtAddCallback(self->look.w,XtNselectCallback,lookSelectCb,
696     (XtPointer)self);
697     XtAddCallback(self->look.w,XtNdeleteCallback,lookDeleteCb,
698     (XtPointer)self);
699    
700     /*** arch ***/
701     box = XtVaCreateManagedWidget
702     ("box", boxWidgetClass, pane,
703     XtNorientation, XtorientHorizontal,
704     NULL);
705     use = XtVaCreateManagedWidget
706     ("archButton",menuButtonWidgetClass, box,
707     XtNmenuName,"toggle",
708     NULL);
709     AppToggleMenu(self,"toggle",use);
710     use = XtVaCreateManagedWidget
711     ("pickButton",menuButtonWidgetClass, box,
712     XtNmenuName,"picks",
713     NULL);
714     sprintf(path,"%s/%s/%s",settings.datadir,settings.mapdir,"editor/picks");
715     self->picks = CnvFilesCreate("picks",use,Picks,(XtPointer)self,path);
716     use = XtVaCreateManagedWidget
717     ("wallButton",menuButtonWidgetClass, box,
718     NULL);
719     sprintf(path,"%s/%s/%s",settings.datadir,settings.mapdir,"editor/walls");
720     self->walls = CnvFilesCreate("menu",use,Walls,(XtPointer)self,path);
721    
722     use = XtVaCreateManagedWidget
723     ("arch", viewportWidgetClass, pane,
724     NULL);
725     self->arch.w = XtVaCreateManagedWidget
726     ("cross",crListWidgetClass,use,
727     XtNpackage, self,
728     XtNnext, Next,
729     NULL);
730     XtAddCallback(self->arch.w,XtNselectCallback,SelectCb,(XtPointer)self);
731     #if 0
732     XtAddCallback(self->arch.w,XtNdeleteCallback,SelectCb,(XtPointer)self);
733     XtAddCallback(self->arch.w,XtNinsertCallback,SelectCb,(XtPointer)self);
734     #endif
735    
736     /*** item ***/
737     box = XtVaCreateManagedWidget
738     ("item", formWidgetClass, pane,
739     XtNorientation, XtorientVertical,
740     NULL);
741     self->item.name = XtVaCreateManagedWidget
742     ("name",labelWidgetClass,box,
743     NULL);
744     self->item.face = XtVaCreateManagedWidget
745     ("face",crFaceWidgetClass,box,
746     XtNfromVert, self->item.name,
747     NULL);
748    
749     /*** used on other places ***/
750     self->look.menu = CnvMenu /* cut,copy,paste-menu on editors */
751     ("mapEdit",self->shell,editMenu,(XtPointer)self);
752     self->info = CnvBrowseCreate("infoFile",self->shell, NULL);
753     /* browsing text */
754     }
755    
756     /**********************************************************************
757     * public
758     **********************************************************************/
759    
760     /*
761     * member : create one application main window
762     * appCon : on self Xt application context
763     * displayString: on self display
764     * argc : number of command line params
765     * argv : list of command line params
766     */
767     App AppCreate(XtAppContext appCon,
768     String displayString,
769     XtResource resources[],
770     Cardinal resourcesNum,
771     XrmOptionDescRec *options,
772     Cardinal optionsNum,
773     int *argc,
774     char *argv[])
775     {
776     char buf[BUFSIZ];
777     char path[PATH_MAX+1];
778     App self;
779    
780    
781     /*** initialize ***/
782     self = (App)XtMalloc(sizeof(struct _App));
783     memset(self,0,sizeof(struct _App));
784     self->display = XtOpenDisplay
785     (appCon,
786     NULL,NULL,AppClass,
787     options,optionsNum,
788     argc,argv);
789     if(!self->display) {
790     sprintf(buf,"Cannot open display %s",displayString);
791     XtAppError(appCon,buf);
792     exit(EXIT_FAILURE);
793     }
794    
795     BitmapsCreate(self->display);
796     self->shell = XtVaAppCreateShell
797     (NULL,AppClass,
798     applicationShellWidgetClass,
799     self->display,
800     XtNtitle,AppClass,
801     XtNiconName,AppClass,
802     XtNiconPixmap,bitmaps.edit,
803     NULL);
804     self->attr = NULL;
805     self->edit = NULL;
806     self->clip = NULL;
807     self->clipon = 0;
808     self->path = NULL;
809     self->look.edit = NULL;
810     self->arch.flags= E_EDITABLE;
811     self->arch.all = 0;
812     self->item.clone = NULL;
813     self->item.wall_map = NULL;
814     self->item.edit = NULL;
815    
816     /*** ***/
817     XtGetApplicationResources
818     (self->shell,
819     (XtPointer) & self->res,
820     resources, resourcesNum,
821     NULL, 0);
822    
823     /*** images & colors ***/
824     InitializeColors(XtDisplay(self->shell));
825    
826     /* Default */
827     displaymode=Dm_Png;
828     FontSize=32;
829    
830     CnvInitialize(self->shell);
831    
832    
833     /*** creating ***/
834     sprintf(path,"%s/%s",settings.datadir,settings.mapdir);
835     self->path = CnvPathCreate("fileSelect",path, "");
836     self->clip = EditCreate(self,ClipBoard,"/Clipboard"); /* separate from */
837     Layout(self);
838     XtRealizeWidget (self->shell);
839     XtRealizeWidget(self->clip->shell);
840     /* I move this down here because I want all the widgets to get their
841     * colors before the images hog all of them.
842     */
843     colormap = DefaultColormap(self->display, DefaultScreen(self->display));
844     if (ReadImages(self->display, &pixmaps, &masks, &colormap, displaymode)) {
845     /* We really should do something better than this */
846     fprintf(stderr,"Not enough space in colormap - switch colormap.\n");
847     /* exit(1);*/
848     }
849     if (colormap)
850     XtVaSetValues(self->shell, XtNcolormap, colormap, NULL);
851     AppUpdate(self);
852     return self;
853     }
854    
855     /*
856     * member: vanish application
857     */
858     void AppDestroy(App self)
859     {
860     Edit edit;
861     Edit temp;
862    
863     debug0("AppDestroy()");
864     /*
865     XUnloadFont (XtDisplay (self->shell), self->font);
866     XtReleaseGC (self->shell, self->gc);
867     XtReleaseGC (self->shell, self->text_gc);
868     */
869    
870     if(self->attr) {
871     AttrDestroy(self->attr);
872     }
873     self->attr = NULL;
874     edit = self->edit;
875     while(edit) {
876     temp = edit->next;
877     EditDestroy(edit);
878     edit = temp;
879     }
880     }
881    
882     /*
883     *
884     *Description:
885     * update all things
886     */
887     void AppUpdate(App self)
888     {
889     char buf[BUFSIZ];
890     object *obj;
891    
892     debug0 ("AppUpdate()\n");
893     /*** look ***/
894     XtVaSetValues (self->look.w, XtNpackage, self, NULL); /*** pseudo ***/
895     if(self->look.edit) {
896     sprintf(buf,"Look: %dx%d+%d+%d",
897     self->look.rect.width,
898     self->look.rect.height,
899     self->look.rect.x,
900     self->look.rect.y);
901    
902     #if 0
903     if (self->attr) {
904     object *ob = MapGetObjectZ (self->look.edit->emap,
905     self->look.rect.x,
906     self->look.rect.y,0);
907     AttrChange(self->attr, ob, GetType(ob));
908     }
909     #endif
910     } else {
911     sprintf(buf,"Look: (no map)");
912     }
913     XtVaSetValues(self->look.info,
914     XtNlabel,buf,
915     NULL);
916    
917     /*** item ***/
918     if((obj = AppItemGetObject(self)) && obj->arch) {
919     if(AppItemGetMap(self)) {
920     XtVaSetValues(self->item.name,
921     XtNlabel,"(auto-joining)",
922     NULL);
923     if((obj = get_map_ob(AppItemGetMap(self),0,
924     AppItemGetWall(self)))) {
925     XtVaSetValues(self->item.face,
926     XtNobject,
927     obj,
928     NULL);
929     } else {
930     debug0("App-No object to show\n");
931     }
932     } else {
933     XtVaSetValues(self->item.name,
934     XtNlabel,AppItemGetObject(self)->arch->name,
935     NULL);
936     XtVaSetValues(self->item.face,
937     XtNobject, AppItemGetObject(self),
938     NULL);
939     }
940     } else {
941     XtVaSetValues(self->item.name,
942     XtNlabel, "Not Selected",
943     NULL);
944     XtVaSetValues(self->item.face,
945     XtNobject,NULL,
946     NULL);
947     }
948     }
949    
950     /*
951     *
952     */
953     void AppSelectSet(App self,Edit edit,XRectangle rect)
954     {
955     if(edit == NULL) {
956     debug0("AppSelectSet() WARN try set NULL Edit\n");
957     return;
958     }
959     if(self->look.edit && self->look.edit != edit)
960     CrEditBorderOff(self->look.edit->w);
961     self->look.edit = edit;
962     self->look.rect = rect;
963     AppUpdate(self);
964     }
965    
966     /*
967     *
968     */
969     void AppSelectUnset(App self)
970     {
971     if (self->look.edit == NULL) return;
972     CrEditBorderOff(self->look.edit->w);
973     CrEditRefresh(self->look.edit->w,self->look.rect);
974     self->look.edit = NULL;
975     AppUpdate(self);
976     }
977    
978     /*
979     * member : item - window to show inserted archetype
980     * edit : object is selectted from self map, NULL if from
981     * main window or no selection
982     * obj : self object is selected to cloning
983     * wallSet:
984     */
985     void AppItemSet (App self, Edit edit,object *obj,int wallSet)
986     {
987     self->item.edit = NULL;
988     self->item.wall_map = NULL;
989     self->item.clone = NULL;
990     self->item.wall_set = AppItemNoWall;
991    
992     if(edit) { /* from map */
993     self->item.edit = edit;
994     if(wallSet > AppItemNoWall) { /* wall map */
995     self->item.wall_map = edit->emap;
996     self->item.wall_set = wallSet;
997     self->item.clone = get_map_ob(edit->emap,0,wallSet);
998     } else { /* other */
999     self->item.clone = obj;
1000     }
1001     } else if(obj) { /* from main window */
1002     self->item.clone = obj;
1003     } else {
1004     /* debug("AppItemSet() strange selection\n"); */
1005     /* return;*/
1006     }
1007     AppUpdate(self);
1008     }
1009    
1010    
1011    
1012     void InitializeColors (Display *dpy)
1013     {
1014     return; /* this function does nothing anymore */
1015     }
1016    
1017     /*
1018     * member: add editor
1019     */
1020     Edit AppEditInsert(App self,String path,EditType type)
1021     {
1022     Edit edit;
1023     Edit editor;
1024    
1025     /*** check if exist ***/
1026     /* Dragon Master */
1027     for(editor = self->edit; editor; editor = editor->next)
1028     if(path != NULL && !strcmp(editor->emap->path, path)) {
1029     /*** save, if modified ***/
1030     if (editor->modified) {
1031     switch (CnvNotify ("Map modified, discard changes?",
1032     "OK","Save Changes","Cancel",NULL)) {
1033     case 1:
1034     EditLoad(editor);
1035     break;
1036     case 2:
1037     EditSave(editor);
1038     break;
1039     default:
1040     break;
1041     }
1042     }
1043     XRaiseWindow(editor->app->display, XtWindow(editor->shell));
1044     return editor;
1045     }
1046    
1047     /*** create new one ***/
1048     if((edit = EditCreate(self,type,path)) == NULL) {
1049     return NULL;
1050     }
1051     AppEditAttach(self,edit);
1052     return edit;
1053     }
1054    
1055     /*
1056     * attach Edit to App environment
1057     */
1058     void AppEditAttach(App self,Edit edit)
1059     {
1060     debug1("AppEditAttach() %s\n",EditGetPath(edit));
1061     /*** attach edit to list ***/
1062     edit->next = self->edit;
1063     self->edit = edit;
1064    
1065     edit->app = self;
1066     }
1067    
1068     /*
1069     * deattach edit from list
1070     */
1071     void AppEditDeattach(App self,Edit edit)
1072     {
1073     Edit oldPrev,old;
1074     debug1("AppEditdeattach() %s\n",EditGetPath(edit));
1075    
1076     oldPrev = old = NULL;
1077     for(old = self->edit;
1078     old && old != edit;
1079     oldPrev = old, old = old->next)
1080     debug1("AppEditDeattach() %s\n",EditGetPath(old));
1081    
1082     if(!old) {
1083     CnvWarn(self->shell,"Trying delete unlinked edit");
1084     } else {
1085     if(!oldPrev) { /* first */
1086     self->edit = old->next;
1087     } else {
1088     oldPrev->next = old->next;
1089     }
1090     }
1091     /* edit->app = NULL; */
1092     }
1093    
1094     /*** end of App.c ***/