ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/crossedit/Attr.c
Revision: 1.3
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.2: +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 Copyright (C) 1993 Jarkko Sonninen & Petri Heinila
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17
18 The authors can be reached via e-mail to Jarkko.Sonninen@lut.fi
19 or Petri.Heinila@lut.fi .
20 */
21
22
23
24 #include "Posix.h"
25 #include "Attr.h"
26 #include "X11.h"
27 #include "CrList.h"
28 #include "CrFace.h"
29 #include "CrEdit.h"
30 #include "Cnv.h"
31 #include "Edit.h"
32 #include "App.h"
33 #include "loader.h"
34 #include "debug.h"
35
36 static void AttrReset(Attr self);
37
38 /* variables, combination bit */
39 #define T_Path (1<<I_Path)
40 #define T_X (1<<I_X)
41 #define T_Y (1<<I_Y)
42 #define T_Weight (1<<I_Weight)
43 #define T_Connect (1<<I_Connect)
44 #define T_Hp (1<<I_Hp)
45 #define T_Trigger (1<<I_Trigger)
46 #define T_Sacrifice (1<<I_Sacrifice)
47 #define T_Count (1<<I_Count)
48 #define T_Lockcode (1<<I_Lockcode) /* slaying - field */
49 #define T_Direction (1<<I_Direction)
50 #define T_Rotation (1<<I_Rotation)
51 #define T_NoPick (1<<I_NoPick)
52 #define T_Unique (1<<I_Unique)
53 #define T_WeightL (1<<I_WeightL)
54 #define T_Brand (1<<I_Brand)
55 #define T_Maker (1<<I_Maker)
56
57 /*** types ar Combinations ***/
58 #define T_Exit (T_Path | T_X | T_Y )
59 #define T_Trapdoor (T_Weight | T_X | T_Y )
60 #define T_Connected (T_Connect )
61 #define T_Pit (T_Connect | T_X | T_Y )
62 #define T_Monster (T_Hp )
63 #define T_Pedestal (T_Connected | T_Trigger )
64 #define T_Altar (T_Connected | T_Sacrifice | T_Count )
65 #define T_Button (T_Weight | T_Connected)
66 #define T_Director (T_Connected | T_Direction | T_Rotation)
67 #define T_Lockdoor (T_Lockcode)
68 #define T_Key (T_Lockcode | T_Unique)
69 #define T_Container (T_Lockcode | T_WeightL | T_Brand | T_Unique | T_NoPick)
70 #define T_Sign 0
71 #define T_Map (T_X | T_Y | T_Path)
72
73 #define T_Default 0
74
75 /*
76 * transfer type from game to editor, return negative on error
77 *
78 * Basically, for certain things, we want to have default values set up.
79 */
80 int GetType (object *tmp)
81 {
82 if (!tmp)
83 return (-1);
84
85 if (tmp->head)
86 tmp = tmp->head;
87
88 switch (tmp->type) {
89 case TELEPORTER:
90 return T_Connected|T_Exit;
91 case PLAYER_CHANGER:
92 case EXIT:
93 return T_Exit;
94 case TRAPDOOR:
95 return T_Trapdoor;
96 case HOLE:
97 return T_Pit;
98 case BUTTON:
99 case TRIGGER_BUTTON:
100 return T_Button;
101 case CREATOR:
102 return T_Connected|T_Maker;
103 case CONVERTER:
104 return T_Maker|T_Lockcode;
105 case GATE:
106 case CF_HANDLE:
107 case TIMED_GATE:
108 case MAGIC_EAR:
109 case TRIGGER:
110 return T_Connected;
111 case CHECK_INV:
112 return T_Connected | T_Lockcode;
113 case ALTAR:
114 case TRIGGER_ALTAR:
115 return T_Altar;
116 case PEDESTAL:
117 case TRIGGER_PEDESTAL:
118 return T_Pedestal;
119 case BOOK:
120 case SIGN:
121 return T_Sign;
122 case MARKER:
123 case LOCKED_DOOR:
124 return T_Lockdoor;
125 case SPECIAL_KEY:
126 return T_Key;
127 case MAP: /* shouldn't happen ... */
128 return T_Map;
129 case DIRECTOR:
130 case FIREWALL:
131 return (NUM_ANIMATIONS(tmp) > 0)
132 ? T_Director : T_Connected;
133 case CONTAINER:
134 return T_Container;
135 default:
136 if (QUERY_FLAG(tmp, FLAG_MONSTER))
137 return T_Monster;
138 else
139 return T_Default;
140 }
141 /* return -1; */
142 }
143
144 /**********************************************************************
145 *Section: get value from object for displying
146 *Commentary:
147 * Remeber, the strings from obejct may be NULL's
148 **********************************************************************/
149
150 static void getX (object *ob, char *str, XtPointer c) {
151 sprintf(str,"%d",EXIT_X(ob));
152 }
153
154 static void getY (object *ob, char *str, XtPointer c) {
155 sprintf(str,"%d",EXIT_Y(ob));
156 }
157
158 static void getPath (object *ob, char *str, XtPointer c) {
159 strcpy (str, EXIT_PATH(ob) ? EXIT_PATH(ob) : "");
160 }
161
162 static void getWeight (object *ob, char *str, XtPointer c) {
163 sprintf(str,"%d",ob->weight);
164 }
165
166 /*** connected ***/
167 static void getConnect (object *ob, char *str, XtPointer c) {
168 sprintf(str,"%d",get_button_value(ob));
169 }
170
171 static void getHp (object *ob, char *str, XtPointer c) {
172 sprintf(str,"%d",ob->stats.hp);
173 }
174
175 #define NotUsed "(not-used)"
176
177 static void getTrigger (object *ob, char *str, XtPointer c) {
178 if(!ob->slaying || !*ob->slaying)
179 sprintf(str,NotUsed);
180 else
181 strcpy (str, ob->slaying);
182 }
183
184 /*** sacrifice ***/
185 static void getSacrifice (object *ob, char *str, XtPointer c) {
186 if(!ob->slaying || !*ob->slaying) {
187 if(!ob->arch->clone.slaying)
188 LOG(llevError,"missing sacrifice for altar\n");
189 strcpy (str, ob->arch->clone.slaying);
190 } else
191 strcpy (str, ob->slaying);
192 }
193
194 static void getCount (object *ob, char *str, XtPointer c) {
195 sprintf(str,"%d",ob->stats.food);
196 }
197
198 /*** lockcode ***/
199 static void getLockcode (object *ob, char *str, XtPointer c) {
200 if(!ob->slaying || !*ob->slaying) {
201 sprintf(str,NotUsed);
202 } else
203 strcpy (str, ob->slaying);
204 }
205
206 /*** direction ***/
207 static void getDirection (object *ob, char *str, XtPointer c) {
208 sprintf(str,"%d",ob->stats.maxsp);
209 }
210
211 /*** rotation ***/
212 static void getRotation (object *ob, char *str, XtPointer c) {
213 sprintf(str,"%d",ob->stats.sp);
214 }
215
216 /*** unique ***/
217 static void getUnique (object *ob, char *str, XtPointer c) {
218 *str = QUERY_FLAG(ob, FLAG_UNIQUE) ? ~0 : 0;
219 }
220
221 /*** no pick ***/
222 static void getNoPick (object *ob, char *str, XtPointer c) {
223 *str = QUERY_FLAG(ob, FLAG_NO_PICK) ? ~0 : 0;
224 }
225
226 /*** weight limit ***/
227 static void getWeightL (object *ob, char *str, XtPointer c) {
228 sprintf(str,"%d",ob->weight_limit);
229 }
230
231 /*** brand ***/
232 static void getBrand (object *ob, char *str, XtPointer c) {
233 if(!ob->race || !*ob->race)
234 sprintf(str,NotUsed);
235 else
236 sprintf(str,"%s",ob->race);
237 }
238
239 /*** brand ***/
240 static void getMakes (object *ob, char *str, XtPointer c) {
241 if(!ob->other_arch)
242 sprintf(str,NotUsed);
243 else
244 sprintf(str,"%s",ob->other_arch->name);
245 }
246
247 /*
248 * putValue functions
249 *
250 */
251
252 /*** coord ***/
253 static void putX (object *ob, char *str, XtPointer c) {
254 EXIT_X(ob) = atoi(str);
255 }
256
257 static void putY (object *ob, char *str, XtPointer c) {
258 EXIT_Y(ob) = atoi(str);
259 }
260
261 /*** path ***/
262 static void putPath (object *ob, char *str, XtPointer c) {
263 if(EXIT_PATH(ob)) free_string(EXIT_PATH(ob));
264 EXIT_PATH(ob) = NULL;
265 if(strlen(str)) EXIT_PATH(ob) = add_string(str);
266 }
267
268 /*** sacrifice ***/
269 static void putSacrifice (object *ob, char *str, XtPointer c) {
270 if(ob->slaying) free_string(ob->slaying);
271 ob->slaying = add_string(str);
272 }
273
274 /*** trigger ***/
275 static void putTrigger (object *ob, char *str, XtPointer c) {
276 if(!strcmp(str,NotUsed))
277 ob->slaying = NULL;
278 else {
279 if(ob->slaying) free_string(ob->slaying);
280 ob->slaying = add_string(str);
281 }
282 }
283
284 /*** weight ***/
285 static void putWeight (object *ob, char *str, XtPointer c) {
286 ob->weight = atoi(str);
287 }
288
289 /*** connect ***/
290 static void putConnect (object *ob, char *str, XtPointer c) {
291 if (QUERY_FLAG(ob, FLAG_IS_LINKED))
292 remove_button_link(ob);
293 add_button_link(ob, ob->map, atoi(str));
294 }
295
296 /*** hp ***/
297 static void putHp (object *ob, char *str, XtPointer c) {
298 ob->stats.hp = atoi(str);
299 }
300
301 /*** count ***/
302 static void putCount (object *ob, char *str, XtPointer c) {
303 ob->stats.food = atoi(str);
304 }
305
306 /*** lockcode ***/
307 static void putLockcode (object *ob, char *str, XtPointer c) {
308 if(!strcmp(str,NotUsed))
309 ob->slaying = NULL;
310 else {
311 if(ob->slaying) free_string(ob->slaying);
312 ob->slaying = add_string(str);
313 }
314 }
315
316 /*** direction ***/
317 static void putDirection (object *ob, char *str, XtPointer c) {
318 ob->stats.maxsp = atoi(str);
319 animate_object (ob, ob->direction);
320 }
321
322 /*** rotation ***/
323 static void putRotation (object *ob, char *str, XtPointer c) {
324 ob->stats.sp = atoi(str);
325 animate_object (ob, ob->direction);
326 }
327
328 /*** unique ***/
329 static void putUnique (object *ob, char *str, XtPointer c) {
330 *str ? SET_FLAG(ob, FLAG_UNIQUE) : CLEAR_FLAG(ob, FLAG_UNIQUE);
331 }
332
333 /*** no pick ***/
334 static void putNoPick (object *ob, char *str, XtPointer c) {
335 *str ? SET_FLAG(ob, FLAG_NO_PICK) : CLEAR_FLAG(ob, FLAG_NO_PICK);
336 }
337
338 /*** weight limit ***/
339 static void putWeightL (object *ob, char *str, XtPointer c) {
340 debug0("NO putWeightL\n");
341 }
342
343 /*** brand ***/
344 static void putBrand (object *ob, char *str, XtPointer c) {
345 if(!strcmp(str,NotUsed))
346 ob->race = NULL;
347 else {
348 if(ob->race) free_string(ob->race);
349 ob->race = add_string(str);
350 }
351 }
352
353 static void putMakes (object *ob, char *str, XtPointer c) {
354 if(!strcmp(str,NotUsed))
355 ob->other_arch = NULL;
356 else {
357 ob->other_arch = find_archetype(str);
358 }
359 }
360
361
362 /**********************************************************************
363 * tags
364 **********************************************************************/
365
366 AttrDef AttrDescription[] = {
367 {"Path", TypeString, getPath, putPath},
368 {"X", TypeString, getX, putX},
369 {"Y", TypeString, getY, putY},
370 {"Weight", TypeString, getWeight, putWeight},
371 {"Connect", TypeString, getConnect, putConnect},
372 {"Hp", TypeString, getHp, putHp},
373 {"Trigger", TypeString, getTrigger, putTrigger},
374 {"Sacrifice", TypeString, getSacrifice, putSacrifice},
375 {"Count", TypeString, getCount, putCount},
376 {"Lockcode", TypeString, getLockcode, putLockcode},
377 {"Direction", TypeString, getDirection, putDirection},
378 {"Rotation", TypeString, getRotation, putRotation},
379 {"No Pick", TypeToggle, getNoPick, putNoPick},
380 {"Unique", TypeToggle, getUnique, putUnique},
381 {"WeightL", TypeString, getWeightL, putWeightL},
382 {"Brand", TypeString, getBrand, putBrand},
383 {"Makes", TypeString, getMakes, putMakes}, /* other_arch */
384 {NULL, 0, 0, NULL}
385 };
386
387 char *allowed_variables[] = {
388
389 "name", "race", "slaying", "other_arch", "last_heal", "last_sp",
390 "last_eat", "speed", "speed_left", "slow_move", "face", "Str", "Dex",
391 "Con", "Wis", "Cha", "Int", "Pow", "hp", "maxhp", "sp", "maxsp", "exp",
392 "food", "dam", "wc", "ac", "nrof", "level", "direction", "type",
393 "material", "value", "weight", "carrying", "immune", "protected",
394 "attacktype", "vulnerable", "path_attuned", "path_repelled",
395 "path_denied", "invisible", "magic", "state", "alive", "applied",
396 "unpaid", "need_an", "need_ie", "no_pick", "no_pass", "walk_on",
397 "walk_off", "fly_on", "fly_off", "flying", "monster",
398 "neutral", "no_attack", "no_damage", "friendly",
399 "generator", "is_thrown", "auto_apply", "treasure", "apply_once",
400 "see_invisible", "can_roll", "is_turning", "is_turnable", "is_used_up",
401 "identified", "reflecting", "changing", "splitting", "hitback",
402 "startequip", "blocksview", "undead", "scared", "unaggressive",
403 "reflect_missile", "reflect_spell", "no_magic", "wiz", "was_wiz",
404 "tear_down", "luck", "run_away", "pass_thru", "can_pass_thru",
405 "pick_up", "anim_speed", "container", "no_drop", "no_pretext",
406 "will_apply", "random_movement", "can_apply", "can_cast_spell",
407 "can_use_scroll", "can_use_wand", "can_use_bow", "can_use_armour",
408 "can_use_weapon", "can_use_ring", "has_ready_wand", "has_ready_bow",
409 "xrays", "is_floor", "lifesave", "no_strength", "sleep", "stand_still",
410 "random_move", "only_attack", "armour", "attack_movement", "move_state",
411 "confused", "stealth", "connected", "cursed", "damned", "see_anywhere",
412 "known_magical", "known_cursed", "can_use_skill", "been_applied",
413 "title", "has_ready_rod", "can_use_rod", "has_ready_horn",
414 "can_use_horn", "expmul", "unique", "make_invisible", "is_wooded",
415 "is_hilly", "has_ready_skill", "has_ready_weapon", "no_skill_ident",
416 "glow_radius", "is_blind", "can_see_in_dark", "is_cauldron",
417 "randomitems", "is_dust", "no_steal", "one_hit","berserk",
418 "sub_type", "sub_type2","casting_speed", "elevation",
419 "save_on_overlay",
420 /* GROS - These are hooks for script events */
421 "script_load","script_apply","script_say","script_trigger", "script_time",
422 "script_attack","script_drop", "script_throw", "script_stop", "script_death", "current_weapon_script",
423 "start_script_load", "start_script_apply","start_script_say","start_script_trigger","start_script_time",
424 "start_script_attack","start_script_drop","start_script_throw","start_script_stop", "start_script_death",
425 "end_script_load", "end_script_apply","end_script_say","end_script_trigger","end_script_time",
426 "end_script_attack","end_script_drop","end_script_throw","end_script_stop", "end_script_death",
427
428 #ifdef NPC_PROG
429 "npc_status", "npc_program",
430 #endif
431
432 /* Resistances */ "resist_physical", "resist_magic", "resist_fire",
433 "resist_electricity", "resist_cold", "resist_confusion", "resist_acid",
434 "resist_drain", "resist_weaponmagic", "resist_ghosthit", "resist_poison",
435 "resist_slow", "resist_paralyze", "resist_turn_undead", "resist_fear",
436 "resist_cancellation", "resist_deplete", "resist_death", "resist_chaos",
437 "resist_counterspell", "resist_godpower", "resist_holyword",
438 "resist_blind", "elevation"
439
440 };
441
442 #define ALLOWED_VARIABLES (sizeof(allowed_variables) / sizeof (char *))
443
444 /**********************************************************************
445 * widgets
446 **********************************************************************/
447
448 /*
449 * member: create tag widgets
450 * parent: parent container
451 */
452 static void AttrTagsCreate(Attr self,Widget parent)
453 {
454 int i;
455 self->attrnumber = 0;
456 while (self->desc[self->attrnumber].label)
457 self->attrnumber++;
458
459 self->tags = (AttrTags*)XtCalloc(self->attrnumber,sizeof(AttrTags));
460 for(i=0; i < self->attrnumber; i++) {
461 if (self->desc[i].type == TypeString) {
462 self->tags[i].cont = XtVaCreateWidget
463 ("box",boxWidgetClass,parent,
464 XtNorientation,XtorientHorizontal,
465 NULL);
466 XtVaCreateManagedWidget
467 ("label",labelWidgetClass,self->tags[i].cont,
468 XtNlabel,self->desc[i].label,
469 NULL);
470 self->tags[i].value = XtVaCreateManagedWidget
471 ("value",asciiTextWidgetClass,self->tags[i].cont,
472 XtNtype,XawAsciiString,
473 XtNeditType,XawtextEdit,
474 NULL);
475 }
476 }
477 for(i=0; i < self->attrnumber; i++) {
478 if (self->desc[i].type == TypeToggle) {
479 self->tags[i].cont = XtVaCreateWidget
480 ("box",boxWidgetClass,parent,
481 XtNorientation,XtorientHorizontal,
482 NULL);
483
484 self->tags[i].value = XtVaCreateManagedWidget
485 ("toggle",toggleWidgetClass, self->tags[i].cont,
486 XtNlabel,self->desc[i].label,
487 NULL);
488 }
489 }
490 }
491
492
493 /*
494 * callback: receive ok
495 */
496 static void AttrOkCb(Widget w,XtPointer client,XtPointer call)
497 {
498 Attr self = (Attr)client;
499
500 AttrApply(self);
501 AttrDestroy (self);
502 }
503
504 /*
505 * receive apply
506 */
507 static void AttrApplyCb(Widget w,XtPointer client,XtPointer call)
508 {
509 Attr self = (Attr)client;
510 AttrApply(self);
511 }
512
513 /*
514 * receive cancel
515 */
516 static void AttrCancelCb(Widget w,XtPointer client,XtPointer call)
517 {
518 Attr self = (Attr)client;
519
520 AttrDestroy(self);
521 }
522
523 /*
524 * receive dump
525 */
526 static void AttrDumpCb(Widget w,XtPointer client,XtPointer call)
527 {
528 Attr self = (Attr)client;
529
530 dump_object(self->op);
531 CnvBrowseShowString(self->dump,errmsg);
532 }
533
534 /**********************************************************************
535 * widget-message
536 **********************************************************************/
537
538
539 static CrListNode AttrInventoryNext(XtPointer client,XtPointer call)
540 {
541 Attr self = (Attr)client;
542 CrListNode retNode = (CrListNode)call;
543 static struct _CrListNode node;
544 object *op = NULL;
545
546 if (!self->op)
547 return (CrListNode)NULL;
548
549 if(retNode) { /* next */
550 op = ((object *)retNode->ptr)->below;
551 } else { /* begin */
552 op = self->op->inv;
553 }
554
555 if(op) {
556 node.face = op->face;
557 node.name = op->name;
558 node.ptr = (XtPointer)op;
559 return &node;
560 }
561 return (CrListNode)NULL;
562 }
563
564 /*
565 * callback: insert object
566 */
567 static void InsertCb(Widget w,XtPointer client,XtPointer call)
568 {
569 Attr self = (Attr)client;
570 /* CrListCall ret = (CrListCall)call; */
571 object *obj;
572
573 if((obj = AppItemGetObject(self->app)) && AttrGetObject(self)) {
574 debug1("Attr-InsertCb() %s\n",obj->name);
575 (void) insert_ob_in_ob(object_create_clone(obj),AttrGetObject(self));
576 }
577 }
578
579 /*
580 * create recursively attributes from inventory
581 */
582 static void AttrInventorySelectCb(Widget w,XtPointer client,XtPointer call)
583 {
584 Attr self = (Attr)client;
585 CrListCall p = (CrListCall)call;
586 object *ob = (object *)p->node;
587
588 if (self->attr) {
589 AttrDestroy (self->attr);
590 }
591
592 self->attr = AttrCreate("attr",self->app, ob,
593 AttrDescription, GetType(ob), self->client);
594 }
595
596 /*
597 * callback: delete object from look window
598 */
599 static void DeleteCb(Widget w,XtPointer client,XtPointer call)
600 {
601 Attr self = (Attr)client;
602 CrListCall ret = (CrListCall)call;
603 object *obj = ret->node;
604
605 debug1("Attr-DeleteCb() %s\n",obj->name);
606 if (self->attr && self->attr->op == obj)
607 AttrDestroy (self->attr);
608 remove_ob(obj);
609 free_object(obj);
610 }
611
612 /**********************************************************************
613 * widget - variables
614 **********************************************************************/
615
616 /*
617 *
618 */
619 static void AttrVarSelectCb(Widget w,XtPointer client,XtPointer call)
620 {
621 Attr self = (Attr)client;
622 XawListReturnStruct *ret = (XawListReturnStruct*)call;
623 XtVaSetValues(self->iw.var,
624 XtNstring,ret->string,
625 NULL);
626 XtPopdown(self->vars.shell);
627 }
628
629 /*
630 *
631 */
632 static void AttrVarCancelCb(Widget w,XtPointer client,XtPointer call)
633 {
634 Attr self = (Attr)client;
635 XtPopdown(self->vars.shell);
636 }
637
638 /*
639 * compare funtion for sorting in PathListGet()
640 */
641 static int StrCmp (const void **s1, const void **s2)
642 {
643 return strcmp (*s1, *s2);
644 }
645
646 /*
647 * create widget layout for selectin variable from list
648 */
649 static void AttrVarLayout(Attr self,Widget parent)
650 {
651 Widget form,cancel,view;
652
653 self->vars.shell = XtVaCreatePopupShell
654 ("vars",transientShellWidgetClass,parent,
655 NULL);
656 form = XtVaCreateManagedWidget
657 ("form",formWidgetClass,self->vars.shell,
658 NULL);
659 view = XtVaCreateManagedWidget
660 ("view",viewportWidgetClass,form,
661 NULL);
662 self->vars.list = XtVaCreateManagedWidget
663 ("list",listWidgetClass,view,
664 NULL);
665 XtAddCallback(self->vars.list,XtNcallback,AttrVarSelectCb,(XtPointer)self);
666 /*** sort varibales ***/
667
668 qsort(allowed_variables, ALLOWED_VARIABLES,
669 sizeof(char *),(int (*)())StrCmp);
670
671 XawListChange(self->vars.list,allowed_variables,
672 ALLOWED_VARIABLES, 0, True);
673 cancel = XtVaCreateManagedWidget
674 ("cancel",commandWidgetClass,form,
675 XtNfromVert,view,
676 NULL);
677 XtAddCallback(cancel,XtNcallback,AttrVarCancelCb,(XtPointer)self);
678 CnvCenterWidget(self->vars.shell);
679 }
680
681 /*
682 *
683 */
684 static void AttrVarGetCb(Widget w,XtPointer client,XtPointer call)
685 {
686 Attr self = (Attr)client;
687 XtPopup(self->vars.shell,XtGrabExclusive);
688 }
689
690 /**********************************************************************
691 * members
692 **********************************************************************/
693
694 static void AppLayout(Attr self,Widget parent, char *name)
695 {
696 Widget form,view1,pane;
697 Widget ok,apply,cancel;
698 Widget view;
699
700 self->shell = XtVaCreatePopupShell
701 (name, topLevelShellWidgetClass, parent, NULL);
702 form = XtVaCreateManagedWidget("form",formWidgetClass,self->shell,NULL);
703
704 self->iw.name = XtVaCreateManagedWidget
705 ("name",asciiTextWidgetClass,form,
706 XtNtype,XawAsciiString,
707 XtNeditType,XawtextEdit,
708 XtNresize,False,
709 XtNadjust,False,
710 NULL);
711
712 self->iw.face = XtVaCreateManagedWidget
713 ("face",crFaceWidgetClass,form,
714 XtNfromVert,self->iw.name,
715 XtNresize,True,
716 XtNadjust,False,
717 XtNobject,self->op,
718 NULL);
719
720 /*** dump ***/
721 self->iw.exact = XtVaCreateManagedWidget
722 ("exact",commandWidgetClass,form,
723 XtNfromVert,self->iw.face,
724 XtNresize,True,
725 XtNadjust,False,
726 NULL);
727 XtAddCallback(self->iw.exact,XtNcallback,AttrDumpCb,(XtPointer)self);
728
729 /*** inventory ***/
730 view = XtVaCreateManagedWidget
731 ("inventory",viewportWidgetClass,form,
732 XtNfromVert,self->iw.name,
733 XtNfromHoriz,self->iw.face,
734 NULL);
735
736 self->iw.inv = XtVaCreateManagedWidget
737 ("list",crListWidgetClass,view,
738 XtNpackage, self,
739 XtNnext, AttrInventoryNext,
740 NULL);
741 XtAddCallback(self->iw.inv,XtNselectCallback,AttrInventorySelectCb,
742 (XtPointer)self);
743 XtAddCallback(self->iw.inv,XtNinsertCallback,InsertCb,
744 (XtPointer)self);
745 XtAddCallback(self->iw.inv,XtNdeleteCallback,DeleteCb,
746 (XtPointer)self);
747
748 /*** multi ***/
749 view1 = XtVaCreateManagedWidget
750 ("view",viewportWidgetClass,form,
751 /*XtNallowVert,True,*/
752 XtNforceBars,True,
753 XtNfromVert,self->iw.exact,
754 NULL);
755 pane = XtVaCreateManagedWidget
756 ("pane",boxWidgetClass,view1,
757 XtNorientation,XtorientVertical,
758 NULL);
759
760 /*** variable setting ***/
761 AttrVarLayout(self,parent);
762
763 self->iw.msg = XtVaCreateManagedWidget
764 ("msg",asciiTextWidgetClass,form,
765 XtNtype,XawAsciiString,
766 XtNeditType,XawtextEdit,
767 XtNfromHoriz,NULL,
768 XtNfromVert,view1,
769 NULL);
770
771
772 self->iw.vars = XtVaCreateManagedWidget
773 ("vars",commandWidgetClass,form,
774 XtNfromVert,self->iw.msg,
775 NULL);
776 XtAddCallback(self->iw.vars,XtNcallback,AttrVarGetCb,(XtPointer)self);
777 self->iw.var = XtVaCreateManagedWidget
778 ("var",asciiTextWidgetClass,form,
779 XtNfromHoriz,self->iw.vars,
780 XtNfromVert,self->iw.msg,
781 XtNtype,XawAsciiString,
782 XtNeditType,XawtextEdit,
783 NULL);
784
785 /*** reponses ***/
786 ok = XtVaCreateManagedWidget
787 ("ok",commandWidgetClass,form,
788 XtNfromVert,self->iw.vars,
789 NULL);
790 XtAddCallback(ok,XtNcallback,AttrOkCb,(XtPointer)self);
791 apply = XtVaCreateManagedWidget
792 ("apply",commandWidgetClass,form,
793 XtNfromVert,self->iw.vars,
794 XtNfromHoriz,ok,
795 NULL);
796 XtAddCallback(apply,XtNcallback,AttrApplyCb,(XtPointer)self);
797 cancel = XtVaCreateManagedWidget
798 ("cancel",commandWidgetClass,form,
799 XtNfromVert,self->iw.vars,
800 XtNfromHoriz,apply,
801 NULL);
802 XtAddCallback(cancel,XtNcallback,AttrCancelCb,(XtPointer)self);
803
804 AttrTagsCreate(self,pane);
805 }
806
807 /*
808 * - create object attribute editor from given object
809 * - change values in future of given object
810 * - struct Attr don't have to be initialized, but have to be
811 * allocated anyway.
812 * - create widgets & popup window
813 */
814 Attr AttrCreate(char *name, App app, object *ob,
815 AttrDef *desc, unsigned long flags, Edit edit)
816 {
817 Attr self = (Attr) XtMalloc (sizeof(struct _Attr));
818
819 if (ob->head)
820 ob = ob->head;
821 self->op = ob;
822 self->app = app;
823 self->client = edit;
824 self->attr = NULL;
825
826 self->desc = desc;
827 AppLayout (self, self->app->shell, name);
828 AttrChange(self,self->op, flags, self->client);
829
830 self->dump = CnvBrowseCreate("dump", self->app->shell, NULL);
831 XtPopup(self->shell,XtGrabNone);
832 self->isup = True;
833 return self;
834 }
835
836 /*
837 * change object to another
838 */
839 void AttrChange(Attr self,object *ob, unsigned long flags, Edit edit)
840 {
841 char buf[BUFSIZ];
842 int i, mask = 1;
843
844 if (!self)
845 return;
846
847 if (self->attr)
848 AttrDestroy (self->attr);
849
850 if (ob && ob->head)
851 ob = ob->head;
852 self->op = ob;
853
854 if(!ob) {
855 AttrReset(self);
856 XtVaSetValues(self->shell,
857 XtNtitle,"",
858 NULL);
859 return;
860 }
861
862 self->flags = flags;
863
864 /*** name ***/
865 XtVaSetValues(self->iw.name,
866 XtNstring,self->op->name,
867 NULL);
868
869 /*** object ***/
870 XtVaSetValues(self->iw.face,
871 XtNobject,self->op,
872 NULL);
873
874 /*** message ***/
875 XtVaSetValues(self->iw.msg,
876 XtNstring,self->op->msg,
877 NULL);
878
879 /*** inventory ***/
880 XtVaSetValues(self->iw.inv,
881 XtNpackage,self,
882 NULL);
883
884 /* get attribute value */
885 for (i = 0; self->desc[i].label; i++, mask <<= 1)
886 if(self->flags & mask) {
887 self->desc[i].getValue (ob, buf, (XtPointer) self->client);
888 if (self->desc[i].type == TypeString) {
889 XtVaSetValues(self->tags[i].value,
890 XtNstring, buf,
891 NULL);
892 } else if (self->desc[i].type == TypeToggle) {
893 XtVaSetValues(self->tags[i].value,
894 XtNstate, *buf ? TRUE : FALSE,
895 NULL);
896 }
897 }
898
899 /*** update ***/
900 for(i=0; self->desc[i].label; i++) {
901 XtUnmanageChild(self->tags[i].cont);
902 }
903 for(i=0; self->desc[i].label; i++) {
904 if(self->flags & (1 << i)) {
905 XtManageChild(self->tags[i].cont);
906 }
907 }
908 sprintf(buf,"Attr: %s",self->op->name);
909 XtVaSetValues(self->shell,
910 XtNtitle,buf,
911 XtNiconName,buf,
912 NULL);
913 self->modified = False;
914 }
915
916 static void AttrReset(Attr self)
917 {
918 int i;
919 debug0("Attr-Reset()\n");
920 /*** name ***/
921 XtVaSetValues(self->iw.name,
922 XtNstring,NULL,
923 NULL);
924 /*** object ***/
925 XtVaSetValues(self->iw.face,
926 XtNobject,NULL,
927 NULL);
928 /*** message ***/
929 XtVaSetValues(self->iw.msg,
930 XtNstring,NULL,
931 NULL);
932 /*** inventory ***/
933 XtVaSetValues(self->iw.inv,
934 XtNpackage,self,
935 NULL);
936
937 for(i=0; self->desc[i].label; i++) {
938 XtUnmanageChild(self->tags[i].cont);
939 }
940 }
941
942 /*
943 * popdown window & destroy widgets
944 */
945 void AttrDestroy(Attr self)
946 {
947 Attr tmp2;
948
949 if (self->attr)
950 AttrDestroy (self->attr);
951 XtDestroyWidget(self->shell);
952 XtFree((char*)self->tags);
953 self->isup = False;
954 CnvBrowseDestroy(self->dump);
955
956 /*
957 * dirty part:
958 * here we find out to what part this window belongs to.
959 * it may be:
960 * - Attr of Look in App
961 * - Attr of other Attr (inventory)
962 */
963
964 if (self == self->app->attr)
965 self->app->attr = NULL;
966 else {
967 for (tmp2 = self->app->attr; tmp2; tmp2 = tmp2->attr)
968 if (self == tmp2->attr) {
969 tmp2->attr = NULL;
970 break;
971 }
972 #ifdef DEBUG
973 if (!tmp2)
974 debug0 ("Cannot find origin of Attr!!\n");
975 #endif
976 }
977 XtFree((char*)self);
978 }
979
980 /*
981 * member: store information from edited widget structure
982 * to object structure
983 */
984 void AttrApply(Attr self)
985 {
986 String str,var;
987 object *ob;
988 char buf[BUFSIZ];
989 int len, mask,set_all=1;
990 size_t i;
991
992 /* check out, that object exist */
993 if(!self->op) {
994 return;
995 }
996
997 for(ob = self->op; ob && set_all; ob = ob->more) {
998 /*** variable ***/
999 XtVaGetValues(self->iw.var,
1000 XtNstring,&var,
1001 NULL);
1002 if(var && *var) {
1003 debug1("AttrApply(), %s\n",var);
1004
1005 /* This is a pretty gross hack, but somewhat necessary. Otherwise,
1006 * all pieces of a multisquare monster will get the treasure, which
1007 * is really not what we want.
1008 */
1009 if (!strncmp(var, "randomitems", 11)) set_all=0;
1010 for (i = 0; i < ALLOWED_VARIABLES; i++)
1011 if (!strncmp (allowed_variables[i], var,
1012 strlen(allowed_variables[i]))) {
1013 if (set_variable(ob,var) == -1) {
1014 sprintf(buf,"%s: no such variable",var);
1015 CnvNotify(buf,"Continue",NULL);
1016 }
1017 break;
1018 }
1019 if (i >= ALLOWED_VARIABLES) {
1020 sprintf(buf,"%s: cannot set variable",var);
1021 CnvNotify(buf,"Continue",NULL);
1022 }
1023 }
1024 /*** name ***/
1025 XtVaGetValues(self->iw.name,
1026 XtNstring,&str,
1027 NULL);
1028 if(ob->name) free_string(ob->name);
1029 ob->name = add_string(str);
1030
1031 /*** message ***/
1032 XtVaGetValues(self->iw.msg,
1033 XtNstring,&str,
1034 NULL);
1035
1036 if(self->op->msg) free_string(self->op->msg);
1037 if((len = strlen(str))) {
1038 if(str[len-1] != '\n') str[len-1] = '\n'; /*** kludge ***/
1039 self->op->msg = add_string(str);
1040 } else {
1041 self->op->msg = NULL;
1042 }
1043
1044 /* set individual attribute value */
1045 for (i = 0, mask = 1; self->desc[i].label; i++, mask <<= 1) {
1046 if(self->flags & mask) {
1047 if (self->desc[i].type == TypeString) {
1048 XtVaGetValues(self->tags[i].value, XtNstring, &str, NULL);
1049 self->desc[i].putValue (ob, str, (XtPointer)self->client);
1050 } else if (self->desc[i].type == TypeToggle) {
1051 Boolean tmp;
1052 XtVaGetValues(self->tags[i].value, XtNstate, &tmp, NULL);
1053 *str = tmp ? ~0 : 0;
1054 self->desc[i].putValue (ob, str, (XtPointer)self->client);
1055 }
1056 }
1057 }
1058 } /* for all parts of the object */
1059
1060 /*** clear variables ***/
1061 XtVaSetValues(self->iw.var,XtNstring,NULL,NULL);
1062
1063 /*** update ***/
1064 AppUpdate (self->app);
1065
1066 self->modified = True;
1067 /*self->client->modified = True;*/
1068 EditModified(self->client);
1069 }
1070
1071
1072 /*** end of Attr.c ***/