ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/crossedit/App.c
Revision: 1.4
Committed: Sun Aug 13 17:16:01 2006 UTC (17 years, 9 months ago) by elmex
Content type: text/plain
Branch: MAIN
CVS Tags: HEAD
Changes since 1.3: +0 -0 lines
State: FILE REMOVED
Log Message:
Made server compile with C++.
Removed cfanim plugin and crossedit.
C++ here we come.

File Contents

# Content
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
40 #include <proto.h>
41
42 Pixmap *pixmaps; /* list of pixmaps */
43 Pixmap *masks; /* list of masks */
44 int FontSize; /* Size of font (really images) */
45 #define E_EDITABLE (E_MONSTER | E_EXIT | E_TREASURE | E_BACKGROUND | \
46 E_DOOR | E_SPECIAL | E_SHOP | E_NORMAL | E_FALSE_WALL)
47
48 static ArchFlagsRec archFlags[] = {
49 { 0, "toggle", E_EDITABLE },
50 { 0, "monster", E_MONSTER },
51 { 0, "exit", E_EXIT },
52 { 0, "treasure", E_TREASURE },
53 { 0, "background", E_BACKGROUND },
54 { 0, "door", E_DOOR },
55 { 0, "special", E_SPECIAL },
56 { 0, "shop", E_SHOP },
57 { 0, "normal", E_NORMAL },
58 { 0, "false wall", E_FALSE_WALL },
59 { 0, "wall", E_WALL },
60 { 0, "equipment", E_EQUIPMENT },
61 { 0, "other", E_OTHER },
62 { 0, "artifact", E_ARTIFACT },
63 { 0, NULL, 0 },
64 };
65
66 /*
67 * plaah: where to put these ???
68 * 0.91.9 - moved to start of file - needed for ReadPixmaps function.
69 */
70 XColor discolor[13];
71 Colormap colormap=(Colormap)NULL;
72
73
74 /**********************************************************************
75 * private
76 **********************************************************************/
77
78 void AppDestroy(App self);
79 Edit AppEditInsert(App self,String path,EditType type);
80 void AppEditAttach(App self,Edit edit);
81
82 #if 0
83 static void AbsToCr(App self,String abs)
84 {
85 char mapdir[PATH_MAX+1],path[PATH_MAX+1],*current,*filename;
86
87 strcpy(path,abs);
88
89 current = strlen(mapdir) + path;
90 filename = strrchr(path,'/');
91 *filename = 0;
92 filename++;
93 strcpy(self->path->current,current);
94 strcpy(self->path->filename,filename);
95 }
96 #endif
97
98 static void Picks(XtPointer client,String entryPath)
99 {
100 App self = (App)client;
101 String path;
102 char mapdir[PATH_MAX+1];
103 int i=0;
104
105 sprintf(mapdir,"%s/%s",settings.datadir,settings.mapdir);
106 for(path = entryPath; mapdir[i++] == *path++;);
107
108 debug1("Picks() %s\n",path);
109 AppEditInsert(self,path,Pick);
110 }
111
112 static void Walls(XtPointer client,String entryPath)
113 {
114 App self = (App)client;
115 String path;
116 char mapdir[PATH_MAX+1];
117 int i = 0;
118
119 sprintf(mapdir,"%s/%s",settings.datadir,settings.mapdir);
120 for(path = entryPath; mapdir[i++] == *path++;);
121
122 debug1("Walls() %s\n",path);
123 AppEditInsert(self,path,Wall);
124 }
125
126 static void Info(XtPointer client,String entryPath)
127 {
128 App self = (App)client;
129
130 CnvBrowseShowFile(self->info,entryPath);
131 }
132
133
134 /**********************************************************************
135 * select
136 **********************************************************************/
137
138 /*
139 * member: filter archetype list
140 * at : requested archetype
141 * return: True, if show out
142 */
143 static Boolean AppArchFilter (App self,archetype * at)
144 {
145 if(self->arch.all) return True;
146 if (!at->editable) return False;
147 return (self->arch.flags & at->editable) ? True : False;
148 }
149
150 /*
151 * function: give widget head of list
152 */
153 static CrListNode Next(XtPointer client,XtPointer call)
154 {
155 App self = (App)client;
156 CrListNode retNode = (CrListNode)call;
157 static struct _CrListNode node;
158 archetype *at;
159
160
161 if(retNode) {
162 at = ((archetype *)retNode->ptr)->next;
163 } else { /* begin */
164 at = first_archetype;
165 }
166
167 while (at && !AppArchFilter(self,at))
168 at = at->next;
169
170 if(at) {
171 node.face = at->clone.face;
172 node.name = at->name;
173 node.ptr = (XtPointer)at;
174 return &node;
175 }
176 return (CrListNode)NULL;
177 }
178
179 /*
180 * create attributes from inventory
181 */
182 static void SelectCb(Widget w,XtPointer client,XtPointer call)
183 {
184 CrListCall ret = (CrListCall)call;
185 App self = (App)client;
186
187 debug0 ("SelectCb\n");
188 /* self->item.wall_map = NULL; */
189 AppItemSet (self,NULL,& ((archetype *) ret->node)->clone,0);
190 /*
191 if(self->attr.isup) {
192 AttrSetArch(&self->attr,self->item.at);
193 }
194 */
195 return;
196 }
197
198 /**********************************************************************
199 * look
200 **********************************************************************/
201
202 /*
203 * function: give widget head of list
204 */
205 static CrListNode lookNext(XtPointer client,XtPointer call)
206 {
207 App self = (App)client;
208 CrListNode retNode = (CrListNode)call;
209 static struct _CrListNode node;
210 object *op = NULL;
211
212 if(self->look.edit == NULL) return NULL;
213
214 if(retNode) { /* next */
215 op = ((object *)retNode->ptr)->below;
216 } else {
217 /* begin */
218 op = MapGetObjectZ(self->look.edit->emap,
219 self->look.rect.x,
220 self->look.rect.y,0);
221 }
222 if(op) {
223 node.face = op->face;
224 node.name = op->name;
225 node.ptr = (XtPointer)op;
226 return &node;
227 }
228 return (CrListNode)NULL;
229 }
230
231 /*
232 *
233 */
234 static void lookSelectCb(Widget w,XtPointer client,XtPointer call)
235 {
236 App self = (App)client;
237 CrListCall ret = (CrListCall)call;
238 object *ob;
239
240 ob = ret->node;
241 if (ob->head)
242 ob = ob->head;
243 if(!self->attr) {
244 self->attr = AttrCreate
245 ("attr", self, ob, AttrDescription, GetType(ob), self->look.edit);
246 } else {
247 AttrChange(self->attr,ob, GetType(ob), self->look.edit);
248 }
249 return;
250 }
251
252 /*
253 * callback: insert object to look window
254 */
255 static void lookInsertCb(Widget w,XtPointer client,XtPointer call)
256 {
257 App self = (App)client;
258 CrListCall ret = (CrListCall)call;
259
260 EditInsert (self->look.edit,
261 self->look.rect.x, self->look.rect.y, ret->index);
262 return;
263 }
264
265 /*
266 * callback: delete object from look window
267 */
268 static void lookDeleteCb(Widget w,XtPointer client,XtPointer call)
269 {
270 App self = (App)client;
271 CrListCall ret = (CrListCall)call;
272 EditDelete (self->look.edit, self->look.rect.x, self->look.rect.y,
273 ret->index);
274 return;
275 }
276 /**********************************************************************
277 * File-menu
278 * New
279 * Open
280 * CrossFire
281 * Quit
282 **********************************************************************/
283
284 static void AppNewCb(Widget w,XtPointer client,XtPointer call)
285 {
286 App self = (App)client;
287 AppEditInsert(self,NULL,Regular);
288 }
289
290 #if 0
291 static void AppClipCb(Widget w,XtPointer client,XtPointer call)
292 {
293 App self = (App)client;
294 AppEditInsert(self,NULL,ClipBoard);
295 }
296 #endif
297
298
299 static void AppOpenCb (Widget w, XtPointer client, XtPointer call)
300 {
301 App self = (App)client;
302 char path[PATH_MAX+1];
303 if(CnvPathSelect(self->path) != CnvPathOk) return;
304 sprintf(path,"%s/%s",self->path->current,self->path->filename);
305 AppEditInsert(self,path,Regular);
306 }
307
308 static void AppCrossfireCb (Widget w, XtPointer client, XtPointer call)
309 {
310 App self = (App)client;
311 int pid;
312 char *prog,*arg1;
313
314 if(!self->res.cmdCrossfire) {
315 CnvNotify("No command defined to *cmdCrossfire:","Continue",NULL);
316 return;
317 }
318 prog = strtok(self->res.cmdCrossfire," \t");
319 arg1 = strtok(NULL," \t"); /* kludge for -pix */
320 switch(pid = fork()) {
321 case -1:
322 CnvNotify("Cannot open new process","OK",NULL);
323 return;
324 case 0: /* child */
325 if(execlp(prog,prog,arg1,NULL) == -1) {
326 char buf[BUFSIZ];
327 sprintf(buf,"cannot execute \"%s\"",self->res.cmdCrossfire);
328 CnvWarn(self->shell,buf);
329 exit(0);
330 }
331 default: /* parent */
332 debug2("CbMainCrossfire() %d %s started\n",pid,self->res.cmdCrossfire);
333 return;
334 }
335 }
336
337 /*
338 *
339 */
340 static void AppQuitCb (Widget w, XtPointer client, XtPointer call)
341 {
342 App self = (App)client;
343
344 AppDestroy(self);
345 XtDestroyApplicationContext (XtWidgetToApplicationContext (w));
346 exit (0);
347 }
348
349 /*
350 * file-menu definition
351 */
352 static CnvMenuRec fileMenu[] = {
353 {"new" ,AppNewCb},
354 {"open" ,AppOpenCb},
355 #if 0
356 {"clipboard",AppClipCb},
357 #endif
358 {"-----" ,NULL},
359 {"crossfire",AppCrossfireCb},
360 {"-----" ,NULL},
361 {"quit" ,AppQuitCb},
362 {"" ,NULL}
363 };
364
365 /**********************************************************************
366 * toggle-menu
367 **********************************************************************/
368
369 static void dirtyfixscrollbar (Widget w) {
370 Widget s = XtParent (w);
371 XawViewportSetCoordinates (s, 0, 0);
372 /* undocumented function */
373 }
374
375
376 static void ToggleFlagCb(Widget w, XtPointer client, XtPointer call)
377 {
378 App self = (App)client;
379 int i;
380
381 for (i = 0; archFlags[i].name; i++) {
382 if (archFlags[i].w == w) {
383 self->arch.flags ^= archFlags[i].flags;
384 break;
385 }
386 }
387 dirtyfixscrollbar (self->arch.w);
388 XtVaSetValues (self->arch.w, XtNpackage, self, NULL);
389 for (i = 0; archFlags[i].name; i++) {
390 XtVaSetValues
391 (archFlags[i].w,
392 XtNleftBitmap,
393 (self->arch.flags & archFlags[i].flags) ? bitmaps.mark : None,
394 NULL);
395 }
396 return;
397 }
398
399
400 static void ToggleAllCb(Widget w, XtPointer client, XtPointer call)
401 {
402 App self = (App)client;
403
404 self->arch.all = !self->arch.all;
405 dirtyfixscrollbar (self->arch.w);
406
407 XtVaSetValues (self->arch.w, XtNpackage, self, NULL);
408 XtVaSetValues(w,
409 XtNleftBitmap,
410 self->arch.all ? bitmaps.mark : None,
411 NULL);
412 }
413
414 static void ToggleClipCb(Widget w, XtPointer client, XtPointer call)
415 {
416 App self = (App)client;
417
418 self->clipon = !self->clipon;
419 XtVaSetValues(w,
420 XtNleftBitmap,
421 self->clipon ? bitmaps.mark : None,
422 NULL);
423 if(self->clipon)
424 XtPopup(self->clip->shell,XtGrabNone);
425 else
426 XtPopdown(self->clip->shell);
427 }
428
429 static void AppToggleMenu(App self,String name,Widget parent)
430 {
431 Widget shell,entry;
432 int i;
433
434 shell = XtVaCreatePopupShell
435 (name,simpleMenuWidgetClass,parent,
436 NULL);
437
438 entry = XtVaCreateManagedWidget
439 ("all",smeBSBObjectClass,shell,
440 XtNleftBitmap,
441 self->arch.all ? bitmaps.mark : None,
442 NULL);
443 XtAddCallback(entry,XtNcallback,ToggleAllCb,(XtPointer)self);
444
445 for (i = 0; archFlags[i].name; i++) {
446 archFlags[i].w = XtVaCreateManagedWidget
447 (archFlags[i].name, smeBSBObjectClass,shell,
448 XtNleftBitmap,
449 (self->arch.flags & archFlags[i].flags) ?
450 bitmaps.mark : None,
451 NULL);
452 XtAddCallback
453 (archFlags[i].w,XtNcallback,ToggleFlagCb,(XtPointer)self);
454 }
455
456 XtVaCreateManagedWidget ("line", smeLineObjectClass, shell, NULL);
457 entry = XtVaCreateManagedWidget
458 ("clipboard",smeBSBObjectClass,shell,
459 XtNleftBitmap,
460 self->clipon ? bitmaps.mark : None,
461 NULL);
462 XtAddCallback(entry,XtNcallback,ToggleClipCb,(XtPointer)self);
463 }
464
465 /**********************************************************************
466 * editMenu callbacks (cut,copy,paste,...)
467 **********************************************************************/
468
469 /*
470 * callback: Cut
471 */
472 static void CutCb (Widget w, XtPointer client, XtPointer call)
473 {
474 App self = (App)client;
475 XRectangle rect;
476
477 debug0 ("AppCutCb()\n");
478 if(!self->look.edit) {
479 CnvNotify("Select area to Cut","Continue",NULL);
480 return;
481 }
482 EditResizeScroll(self->clip,self->look.rect.width,
483 self->look.rect.height,0,0);
484 /*
485 EditCopyRectangle(self->look.edit,self->clip,EditRectAll,
486 self->look.rect.x,self->look.rect.y);
487 */
488 rect.x = rect.y = 0;
489 rect.width = self->look.rect.width;
490 rect.height = self->look.rect.height;
491 EditWipeRectangle(self->clip,rect);
492 EditCopyRectangle(self->clip,self->look.edit,self->look.rect,0,0);
493 EditWipeRectangle(self->look.edit,self->look.rect);
494
495 EditModified(self->look.edit);
496 CrEditRefresh(self->look.edit->w,self->look.rect);
497 AppSelectUnset(self);
498 }
499
500 /*
501 * callback: Copy
502 */
503 static void CopyCb (Widget w, XtPointer client, XtPointer call)
504 {
505 App self = (App)client;
506 XRectangle rect;
507
508 debug0 ("AppCopyCb()\n");
509 if(!self->look.edit) {
510 CnvNotify("Select area to Copy","Continue",NULL);
511 return;
512 }
513 EditResizeScroll(self->clip,self->look.rect.width,
514 self->look.rect.height,0,0);
515 rect.x = rect.y = 0;
516 rect.width = self->look.rect.width;
517 rect.height = self->look.rect.height;
518 EditWipeRectangle(self->clip,rect);
519 EditCopyRectangle(self->clip,self->look.edit,self->look.rect,0,0);
520
521 AppSelectUnset(self);
522 }
523
524 /*
525 * callback: Paste
526 */
527 static void PasteCb (Widget w, XtPointer client, XtPointer call)
528 {
529 App self = (App)client;
530
531 debug0 ("AppPasteCb()\n");
532
533 if(!self->look.edit) {
534 CnvNotify("Select point to Paste","Continue",NULL);
535 return;
536 }
537 EditCopyRectangle(self->look.edit,self->clip,EditRectAll,
538 self->look.rect.x,self->look.rect.y);
539
540 EditModified(self->look.edit);
541
542 AppSelectUnset(self);
543 }
544
545 /*
546 * callback: Fill
547 */
548 static void FillCb (Widget w, XtPointer client, XtPointer call)
549 {
550 App self = (App)client;
551
552 debug0 ("AppFillCb()\n");
553 if(!self->look.edit) {
554 CnvNotify("Select point to Fill","Continue",NULL);
555 return;
556 }
557 EditPerformFill(self->look.edit,self->look.rect.x,self->look.rect.y);
558 EditModified(self->look.edit);
559 AppSelectUnset(self);
560 }
561
562 /*
563 * callback: FillBelow
564 */
565 static void FillBelowCb (Widget w, XtPointer client, XtPointer call)
566 {
567 App self = (App)client;
568
569 debug0 ("AppFillCb()\n");
570 if(!self->look.edit) {
571 CnvNotify("Select point to Fill","Continue",NULL);
572 return;
573 }
574 EditPerformFillBelow(self->look.edit,self->look.rect.x,self->look.rect.y);
575 EditModified(self->look.edit);
576 AppSelectUnset(self);
577 }
578
579 /*
580 * callback: Box
581 */
582 static void BoxCb (Widget w, XtPointer client, XtPointer call)
583 {
584 App self = (App)client;
585
586 debug0 ("AppBoxCb()\n");
587 if(!self->look.edit) {
588 CnvNotify("Select area to fill","Continue",NULL);
589 return;
590 }
591 EditFillRectangle(self->look.edit, self->look.rect);
592 EditModified(self->look.edit);
593 AppSelectUnset(self);
594 }
595
596 /*
597 * callback: Wipe
598 */
599 static void WipeCb (Widget w, XtPointer client, XtPointer call)
600 {
601 App self = (App)client;
602
603 debug0 ("AppWipeCb()\n");
604 if(!self->look.edit) {
605 CnvNotify("Select area to Wipe","Continue",NULL);
606 return;
607 }
608
609 EditShaveRectangle(self->look.edit, self->look.rect);
610 EditModified(self->look.edit);
611 AppSelectUnset(self);
612 }
613
614 /*
615 * callback: WipeBelow
616 */
617 static void WipeBelowCb (Widget w, XtPointer client, XtPointer call)
618 {
619 App self = (App)client;
620
621 debug0 ("AppWipeBelowCb()\n");
622 if(!self->look.edit) {
623 CnvNotify("Select area to Wipe","Continue",NULL);
624 return;
625 }
626
627 EditShaveRectangleBelow(self->look.edit, self->look.rect);
628 EditModified(self->look.edit);
629 AppSelectUnset(self);
630 }
631
632 /*
633 * menu definition
634 */
635 static CnvMenuRec editMenu[] = {
636 {"cut" ,CutCb},
637 {"copy" ,CopyCb},
638 {"paste",PasteCb},
639 {"-----",NULL},
640 {"fill" ,FillCb},
641 {"fillbelow" ,FillBelowCb},
642 {"box" ,BoxCb},
643 {"wipe" ,WipeCb},
644 {"wipebelow" ,WipeBelowCb},
645 {"", NULL}
646 };
647
648 /**********************************************************************
649 * layout
650 **********************************************************************/
651
652 /*
653 * member: create application window layout
654 */
655 static void Layout(App self)
656 {
657 Widget pane, box,use,view;
658 char path[PATH_MAX+1];
659
660 /*** vertical Pane of widgets ***/
661 pane = XtCreateManagedWidget
662 ("pane", panedWidgetClass, self->shell,
663 NULL, 0);
664
665 /*** menubar ***/
666 box = XtVaCreateManagedWidget
667 ("box", boxWidgetClass, pane,
668 XtNorientation, XtorientHorizontal,
669 NULL);
670 use = XtVaCreateManagedWidget
671 ("fileButton",menuButtonWidgetClass, box,
672 XtNmenuName,"appFileMenu",
673 NULL);
674 CnvMenu("appFileMenu",use,fileMenu,(XtPointer)self);
675
676 use = XtVaCreateManagedWidget
677 ("infoButton",menuButtonWidgetClass, box,
678 XtNmenuName,"info",
679 NULL);
680 sprintf(path,"%s/%s",settings.datadir,"doc");
681 self->infof = CnvFilesCreate("info",use,Info,(XtPointer)self,path);
682
683 /*** look ***/
684 self->look.info = XtVaCreateManagedWidget
685 ("info",labelWidgetClass,pane,
686 NULL);
687
688 view = XtVaCreateManagedWidget
689 ("view", viewportWidgetClass,pane,
690 NULL);
691 self->look.w = XtVaCreateManagedWidget
692 ("cross",crListWidgetClass,view,
693 XtNpackage, self,
694 XtNnext, lookNext,
695 NULL);
696 XtAddCallback(self->look.w,XtNinsertCallback,lookInsertCb,
697 (XtPointer)self);
698 XtAddCallback(self->look.w,XtNselectCallback,lookSelectCb,
699 (XtPointer)self);
700 XtAddCallback(self->look.w,XtNdeleteCallback,lookDeleteCb,
701 (XtPointer)self);
702
703 /*** arch ***/
704 box = XtVaCreateManagedWidget
705 ("box", boxWidgetClass, pane,
706 XtNorientation, XtorientHorizontal,
707 NULL);
708 use = XtVaCreateManagedWidget
709 ("archButton",menuButtonWidgetClass, box,
710 XtNmenuName,"toggle",
711 NULL);
712 AppToggleMenu(self,"toggle",use);
713 use = XtVaCreateManagedWidget
714 ("pickButton",menuButtonWidgetClass, box,
715 XtNmenuName,"picks",
716 NULL);
717 sprintf(path,"%s/%s/%s",settings.datadir,settings.mapdir,"editor/picks");
718 self->picks = CnvFilesCreate("picks",use,Picks,(XtPointer)self,path);
719 use = XtVaCreateManagedWidget
720 ("wallButton",menuButtonWidgetClass, box,
721 NULL);
722 sprintf(path,"%s/%s/%s",settings.datadir,settings.mapdir,"editor/walls");
723 self->walls = CnvFilesCreate("menu",use,Walls,(XtPointer)self,path);
724
725 use = XtVaCreateManagedWidget
726 ("arch", viewportWidgetClass, pane,
727 NULL);
728 self->arch.w = XtVaCreateManagedWidget
729 ("cross",crListWidgetClass,use,
730 XtNpackage, self,
731 XtNnext, Next,
732 NULL);
733 XtAddCallback(self->arch.w,XtNselectCallback,SelectCb,(XtPointer)self);
734 #if 0
735 XtAddCallback(self->arch.w,XtNdeleteCallback,SelectCb,(XtPointer)self);
736 XtAddCallback(self->arch.w,XtNinsertCallback,SelectCb,(XtPointer)self);
737 #endif
738
739 /*** item ***/
740 box = XtVaCreateManagedWidget
741 ("item", formWidgetClass, pane,
742 XtNorientation, XtorientVertical,
743 NULL);
744 self->item.name = XtVaCreateManagedWidget
745 ("name",labelWidgetClass,box,
746 NULL);
747 self->item.face = XtVaCreateManagedWidget
748 ("face",crFaceWidgetClass,box,
749 XtNfromVert, self->item.name,
750 NULL);
751
752 /*** used on other places ***/
753 self->look.menu = CnvMenu /* cut,copy,paste-menu on editors */
754 ("mapEdit",self->shell,editMenu,(XtPointer)self);
755 self->info = CnvBrowseCreate("infoFile",self->shell, NULL);
756 /* browsing text */
757 }
758
759 /**********************************************************************
760 * public
761 **********************************************************************/
762
763 /*
764 * member : create one application main window
765 * appCon : on self Xt application context
766 * displayString: on self display
767 * argc : number of command line params
768 * argv : list of command line params
769 */
770 App AppCreate(XtAppContext appCon,
771 String displayString,
772 XtResource resources[],
773 Cardinal resourcesNum,
774 XrmOptionDescRec *options,
775 Cardinal optionsNum,
776 int *argc,
777 char *argv[])
778 {
779 char buf[BUFSIZ];
780 char path[PATH_MAX+1];
781 App self;
782
783
784 /*** initialize ***/
785 self = (App)XtMalloc(sizeof(struct _App));
786 memset(self,0,sizeof(struct _App));
787 self->display = XtOpenDisplay
788 (appCon,
789 NULL,NULL,AppClass,
790 options,optionsNum,
791 argc,argv);
792 if(!self->display) {
793 sprintf(buf,"Cannot open display %s",displayString);
794 XtAppError(appCon,buf);
795 exit(EXIT_FAILURE);
796 }
797
798 BitmapsCreate(self->display);
799 self->shell = XtVaAppCreateShell
800 (NULL,AppClass,
801 applicationShellWidgetClass,
802 self->display,
803 XtNtitle,AppClass,
804 XtNiconName,AppClass,
805 XtNiconPixmap,bitmaps.edit,
806 NULL);
807 self->attr = NULL;
808 self->edit = NULL;
809 self->clip = NULL;
810 self->clipon = 0;
811 self->path = NULL;
812 self->look.edit = NULL;
813 self->arch.flags= E_EDITABLE;
814 self->arch.all = 0;
815 self->item.clone = NULL;
816 self->item.wall_map = NULL;
817 self->item.edit = NULL;
818
819 /*** ***/
820 XtGetApplicationResources
821 (self->shell,
822 (XtPointer) & self->res,
823 resources, resourcesNum,
824 NULL, 0);
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 /*
1013 * member: add editor
1014 */
1015 Edit AppEditInsert(App self,String path,EditType type)
1016 {
1017 Edit edit;
1018 Edit editor;
1019
1020 /*** check if exist ***/
1021 /* Dragon Master */
1022 for(editor = self->edit; editor; editor = editor->next)
1023 if(path != NULL && !strcmp(editor->emap->path, path)) {
1024 /*** save, if modified ***/
1025 if (editor->modified) {
1026 switch (CnvNotify ("Map modified, discard changes?",
1027 "OK","Save Changes","Cancel",NULL)) {
1028 case 1:
1029 EditLoad(editor);
1030 break;
1031 case 2:
1032 EditSave(editor);
1033 break;
1034 default:
1035 break;
1036 }
1037 }
1038 XRaiseWindow(editor->app->display, XtWindow(editor->shell));
1039 return editor;
1040 }
1041
1042 /*** create new one ***/
1043 if((edit = EditCreate(self,type,path)) == NULL) {
1044 return NULL;
1045 }
1046 AppEditAttach(self,edit);
1047 return edit;
1048 }
1049
1050 /*
1051 * attach Edit to App environment
1052 */
1053 void AppEditAttach(App self,Edit edit)
1054 {
1055 debug1("AppEditAttach() %s\n",EditGetPath(edit));
1056 /*** attach edit to list ***/
1057 edit->next = self->edit;
1058 self->edit = edit;
1059
1060 edit->app = self;
1061 }
1062
1063 /*
1064 * deattach edit from list
1065 */
1066 void AppEditDeattach(App self,Edit edit)
1067 {
1068 Edit oldPrev,old;
1069 debug1("AppEditdeattach() %s\n",EditGetPath(edit));
1070
1071 oldPrev = old = NULL;
1072 for(old = self->edit;
1073 old && old != edit;
1074 oldPrev = old, old = old->next)
1075 debug1("AppEditDeattach() %s\n",EditGetPath(old));
1076
1077 if(!old) {
1078 CnvWarn(self->shell,"Trying delete unlinked edit");
1079 } else {
1080 if(!oldPrev) { /* first */
1081 self->edit = old->next;
1082 } else {
1083 oldPrev->next = old->next;
1084 }
1085 }
1086 /* edit->app = NULL; */
1087 }
1088
1089 /*** end of App.c ***/