ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/crossedit/CrEdit.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 * static char *rcsid_map_c =
3 * "$Id$";
4 */
5
6 /*
7 CrossFire, A Multiplayer game for X-windows
8
9 Copyright (C) 2001 Mark Wedel & Crossfire Development Team
10 Copyright (C) 1992 Frank Tore Johansen
11
12 This program is free software; you can redistribute it and/or modify
13 it under the terms of the GNU General Public License as published by
14 the Free Software Foundation; either version 2 of the License, or
15 (at your option) any later version.
16
17 This program is distributed in the hope that it will be useful,
18 but WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 GNU General Public License for more details.
21
22 You should have received a copy of the GNU General Public License
23 along with this program; if not, write to the Free Software
24 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25
26 The authors can be reached via e-mail at crossfire-devel@real-time.com
27 */
28
29 #include "Defines.h"
30 #include "Ansi.h"
31 #include "Xaw.h"
32 #include <X11/IntrinsicP.h>
33 #include <X11/StringDefs.h>
34
35 #include "global.h"
36 #include "debug.h"
37
38 #include "Cnv.h"
39 #include "CrEditP.h"
40 #include "CrUtil.h"
41
42 extern Pixmap *pixmaps; /* list of pixmaps */
43
44 /**********************************************************************
45 * resources
46 **********************************************************************/
47
48 static XtResource resources[] = {
49 #define Offset(field) XtOffsetOf(CrEditRec, crEdit.field)
50 {
51 XtNinsertCallback,
52 XtCInsertCallback,
53 XtRCallback,
54 sizeof(XtCallbackList),
55 Offset(insertCallbacks),
56 XtRCallback,
57 NULL
58 },{
59 XtNselectCallback,
60 XtCSelectCallback,
61 XtRCallback,
62 sizeof(XtCallbackList),
63 Offset(selectCallbacks),
64 XtRCallback,
65 NULL
66 },{
67 XtNpropsCallback,
68 XtCPropsCallback,
69 XtRCallback,
70 sizeof(XtCallbackList),
71 Offset(propsCallbacks),
72 XtRCallback,
73 NULL
74 },{
75 XtNdeleteCallback,
76 XtCDeleteCallback,
77 XtRCallback,
78 sizeof(XtCallbackList),
79 Offset(deleteCallbacks),
80 XtRCallback,
81 NULL
82 },{
83 XtNalignCallback,
84 XtCAlignCallback,
85 XtRCallback,
86 sizeof(XtCallbackList),
87 Offset(alignCallbacks),
88 XtRCallback,
89 NULL
90 },{
91 XtNfeedCallback,
92 XtCFeedCallback,
93 XtRCallback,
94 sizeof(XtCallbackList),
95 Offset(feedCallbacks),
96 XtRCallback,
97 NULL
98 },{
99 XtNmap,
100 XtCMap,
101 XtRPointer,
102 sizeof(XtPointer),
103 Offset(map),
104 XtRPointer,
105 NULL
106 },{
107 XtNstacking,
108 XtCStacking,
109 XtRInt,
110 sizeof(int),
111 Offset(stacking),
112 XtRImmediate,
113 (XtPointer)0
114 },{
115 XtNshow_weak_walls,
116 XtCShow_weak_walls,
117 XtRInt,
118 sizeof(int),
119 Offset(show_weak_walls),
120 XtRImmediate,
121 (XtPointer)0
122 },{
123 XtNselectArea,
124 XtCSelectArea,
125 XtRBoolean,
126 sizeof(Boolean),
127 Offset(selectArea),
128 XtRBoolean,
129 (XtPointer)NULL,
130 }
131 #undef offset
132 };
133
134 /**********************************************************************
135 * declarations
136 **********************************************************************/
137
138 static void UpdatePosition (Widget w, int x, int y,Boolean inv);
139 static void ClassInitialize(void);
140 static void Initialize(Widget req,Widget new,Arg args[],Cardinal *num);
141 static void Destroy(Widget w);
142 static void Resize(Widget w);
143 static void Redisplay(Widget w,XEvent *event,Region region);
144 static Boolean SetValues(Widget cur,Widget req,Widget new,
145 Arg args[],Cardinal *num);
146
147 #define EmptyObject "editor_archetype"
148
149 /**********************************************************************
150 * actions & translations
151 **********************************************************************/
152
153 static void InsertAc ( Widget w, XEvent * event,
154 String * argv, Cardinal * argc );
155 static void DeleteAc ( Widget w, XEvent * event,
156 String * argv, Cardinal * argc );
157 static void PropsAc ( Widget w, XEvent * event,
158 String * argv, Cardinal * argc );
159 static void MoveAc ( Widget w, XEvent * e,
160 String * argv, Cardinal * argc );
161 static void ResizeAc ( Widget w, XEvent * e,
162 String * argv, Cardinal * argc );
163 static void ScrollAc ( Widget w, XEvent * e,
164 String * argv, Cardinal * argc );
165 static void SelectBeginAc ( Widget w, XEvent * e,
166 String * argv, Cardinal * argc );
167 static void SelectExpandAc ( Widget w, XEvent * e,
168 String * argv, Cardinal * argc );
169 static void SelectEndAc ( Widget w, XEvent * e,
170 String * argv, Cardinal * argc );
171 static void FeedAc ( Widget w, XEvent * e,
172 String * argv, Cardinal * argc );
173
174 XtActionsRec actions[] = {
175 {"Insert", InsertAc},
176 {"SelectBegin", SelectBeginAc},
177 {"SelectExpand", SelectExpandAc},
178 {"SelectEnd", SelectEndAc},
179 {"Props", PropsAc},
180 {"Delete", DeleteAc},
181 {"Feed", FeedAc},
182 {"Move", MoveAc},
183 {"Resize", ResizeAc},
184 {"Scroll", ScrollAc},
185 };
186
187 static char translations[] = "\
188 <Btn1Up>: Insert(archetype) \n\
189 <Btn1Motion>: Insert(archetype) \n\
190 Ctrl<Btn2Up>: Feed(coordinate) \n\
191 Ctrl<Btn2Motion>: Feed(coordinate) \n\
192 Shift<Btn2Up>: Props() \n\
193 None<Btn2Down>: SelectBegin() \n\
194 None<Btn2Motion>: SelectExpand() \n\
195 None<Btn2Up>: SelectEnd() \n\
196 <Btn3Down>: Delete(archetype) \n\
197 <Btn3Motion>: Delete(archetype) \n\
198 Ctrl<Key>Right: Resize(right) \n\
199 Ctrl<Key>Left: Resize(left) \n\
200 Ctrl<Key>Down: Resize(down) \n\
201 Ctrl<Key>Up: Resize(up) \n\
202 Shift<Key>Right: Scroll(right) \n\
203 Shift<Key>Left: Scroll(left) \n\
204 Shift<Key>Down: Scroll(down) \n\
205 Shift<Key>Up: Scroll(up) \n\
206 <Key>Right: Move(right) \n\
207 <Key>Left: Move(left) \n\
208 <Key>Down: Move(down) \n\
209 <Key>Up: Move(up) \n\
210 ";
211
212 /**********************************************************************
213 * class record
214 **********************************************************************/
215
216 CrEditClassRec crEditClassRec = {
217 { /* core fields */
218 /* superclass */ (WidgetClass)&widgetClassRec,
219 /* class_name */ "CrEdit",
220 /* widget_size */ sizeof(CrEditRec),
221 /* class_initialize */ ClassInitialize,
222 /* class_part_initialize */ NULL,
223 /* class_inited */ FALSE,
224 /* initialize */ Initialize,
225 /* initialize_hook */ NULL,
226 /* realize */ XtInheritRealize,
227 /* actions */ actions,
228 /* num_actions */ XtNumber(actions),
229 /* resources */ resources,
230 /* num_resources */ XtNumber(resources),
231 /* xrm_class */ NULLQUARK,
232 /* compress_motion */ TRUE,
233 /* compress_exposure */ TRUE,
234 /* compress_enterleave */ TRUE,
235 /* visible_interest */ FALSE,
236 /* destroy */ Destroy,
237 /* resize */ Resize,
238 /* expose */ Redisplay,
239 /* set_values */ SetValues,
240 /* set_values_hook */ NULL,
241 /* set_values_almost */ XtInheritSetValuesAlmost,
242 /* get_values_hook */ NULL,
243 /* accept_focus */ NULL,
244 /* version */ XtVersion,
245 /* callback_private */ NULL,
246 /* tm_table */ translations,
247 /* query_geometry */ XtInheritQueryGeometry,
248 /* display_accelerator */ XtInheritDisplayAccelerator,
249 /* extension */ NULL
250 },
251 { /* crEdit fields */
252 /* empty */ 0
253 }
254 };
255
256 WidgetClass crEditWidgetClass = (WidgetClass)&crEditClassRec;
257
258 /**********************************************************************
259 * inner functions
260 **********************************************************************/
261
262 /*
263 *
264 */
265 static void SegToRec(XSegment *seg,XRectangle *rec)
266 {
267 /*** calculate rectangle ***/
268 rec->x = seg->x1 < seg->x2 ? seg->x1 : seg->x2;
269 rec->y = seg->y1 < seg->y2 ? seg->y1 : seg->y2;
270 rec->width = abs(seg->x1 - seg->x2) + 1;
271 rec->height = abs(seg->y1 - seg->y2) + 1;
272 }
273
274 static void SetSize(Widget w)
275 {
276 CrEditWidget self = (CrEditWidget)w;
277 XtWidgetGeometry request,reply;
278 /*Dimension width,height,rWidth,rHeight;*/
279
280 /*** determine size to ask for ***/
281 if(self->crEdit.map) {
282 request.width = MAP_WIDTH(self->crEdit.map) * self->crEdit.fontSize;
283 request.height = MAP_HEIGHT(self->crEdit.map) * self->crEdit.fontSize;
284 } else {
285 request.width = self->crEdit.fontSize;
286 request.height = self->crEdit.fontSize;
287 }
288 request.x = request.y = 0;
289 request.request_mode = CWWidth | CWHeight;
290
291 /*** ask it ***/
292 switch(XtMakeGeometryRequest(w,&request,&reply)) {
293 case XtGeometryYes:
294 break;
295 case XtGeometryNo:
296 debug1 ("%s: May not change my geometry\n",XtName(w));
297 break;
298 case XtGeometryAlmost:
299 XtMakeGeometryRequest(w,&reply,&reply);
300 break;
301 default:
302 CnvDie(w,"Unknown geometry request return");
303 break;
304 };
305 /*
306 XSendEvent(XtDisplay(w),XtWindow(w),False,ResizeRequest,NULL);
307 */
308 debug3("%s: setting widget size to %dx%d\n",XtName(w),self->core.width,
309 self->core.height);
310 }
311
312 /**********************************************************************
313 **********************************************************************/
314
315
316 static void AnimateCursor (Widget w, int x, int y) {
317 /* Currently, this was only supported with bitmap mode.
318 * I'm sure soething clever could be done in other modes.
319 */
320
321 }
322
323
324
325 /**********************************************************************
326 * drawing functions
327 * hierarchy:
328 * DrawRectangle DrawBorder
329 * UpdatePosition
330 * DrawObject
331 **********************************************************************/
332
333 /*
334 * inv : draw inverse colored object if True
335 */
336
337
338 /*
339 * member: update object stack at point in map
340 * x,y : point
341 * inv : draw inverse
342 */
343 static void UpdatePosition (Widget w, int x, int y,Boolean inv)
344 {
345 CrEditWidget self = (CrEditWidget)w;
346 object *op;
347 int i;
348
349 if(out_of_map(self->crEdit.map,x,y)) return;
350
351 if (self->crEdit.stacking) {
352 /* stacking mode */
353 float xb, yb;
354 XClearArea (XtDisplay(w), XtWindow(w),
355 x * self->crEdit.fontSize,
356 y * self->crEdit.fontSize,
357 self->crEdit.fontSize,
358 self->crEdit.fontSize, False);
359 for (i = 0, op = get_map_ob (self->crEdit.map, x, y);
360 op;
361 i++, op = op->above);
362 if (i > 0) {
363 int diff = self->crEdit.fontSize - FontSize;
364 int depth = diff / STACK_MIN + 1;
365 float dist = 0;
366
367 if (depth < 1)
368 depth = 1;
369 for (op = get_map_ob (self->crEdit.map, x, y); i > depth; i--)
370 op = op->above;
371
372 i--;
373 if (i) {
374 dist = (diff - 1) / (float)i;
375 if (dist > STACK_MAX)
376 dist = STACK_MAX;
377 }
378
379 xb = diff + x * self->crEdit.fontSize - 1;
380 yb = diff + y * self->crEdit.fontSize - 1;
381
382 while (op) {
383 if (QUERY_FLAG(op, FLAG_TEAR_DOWN) && self->crEdit.show_weak_walls) {
384 New_Face * f;
385 f = &new_faces[GET_ANIMATION(op,NUM_ANIMATIONS(op)/2)];
386 DrawFacePart(w, self->crEdit.gc, f, xb, yb, 0, 0);
387 } else {
388 DrawPartObject(w, self->crEdit.gc, op, xb, yb);
389 }
390
391 if (HAS_COLOUR(w)) {
392 XSetForeground(XtDisplay(w), self->crEdit.gc,
393 BlackPixelOfScreen(XtScreen(w)));
394 }
395 XDrawRectangle (XtDisplay(w),
396 XtWindow(w), self->crEdit.gc,
397 (int) xb, (int) yb, FontSize -1, FontSize -1);
398 xb -= dist;
399 yb -= dist;
400 op = op->above;
401 }
402 }
403 } else { /* Normal map drawing routine */
404 New_Face *f;
405
406 if (GET_MAP_FLAGS(self->crEdit.map, x, y) & P_NEED_UPDATE) {
407 update_position(self->crEdit.map, x, y);
408 }
409
410 if (displaymode==Dm_Png) {
411 op = GET_MAP_FACE_OBJ(self->crEdit.map, x, y, 2);
412 if (op != NULL)
413 DrawPartObject(w, self->crEdit.gc, op,
414 x * self->crEdit.fontSize,
415 y * self->crEdit.fontSize);
416 op = GET_MAP_FACE_OBJ(self->crEdit.map, x, y, 1);
417 if (op != NULL && op->face->number != blank_face->number)
418 DrawPartObject(w, self->crEdit.gc, op,
419 x * self->crEdit.fontSize,
420 y * self->crEdit.fontSize);
421 op = GET_MAP_FACE_OBJ(self->crEdit.map, x, y, 0);
422 if (op != NULL && op->face->number != blank_face->number)
423 DrawPartObject(w, self->crEdit.gc, op,
424 x * self->crEdit.fontSize,
425 y * self->crEdit.fontSize);
426 }
427 op=get_map_ob(self->crEdit.map, x, y);
428 while (op && op->above) op=op->above;
429 if (op == NULL) {
430 ; /* Paint nothing */
431 } else if (QUERY_FLAG(op, FLAG_TEAR_DOWN) && self->crEdit.show_weak_walls) {
432 f = &new_faces[GET_ANIMATION(op, NUM_ANIMATIONS(op)/2)];
433
434 if (displaymode == Dm_Png || f->number != blank_face->number)
435 DrawFacePart (w, self->crEdit.gc, f,
436 x * self->crEdit.fontSize,
437 y * self->crEdit.fontSize,
438 0, 0);
439 } else {
440 if (displaymode == Dm_Png || op->face->number != blank_face->number)
441 DrawPartObject (w, self->crEdit.gc, op,
442 x * self->crEdit.fontSize,
443 y * self->crEdit.fontSize);
444 }
445 }
446 return;
447 }
448
449 /*
450 * member: draw filled rectangle
451 * rec : rectangle
452 * inv : True = inverse
453 */
454 static void DrawRectangle(Widget w,XRectangle area,Boolean inv)
455 {
456 CrEditWidget self = (CrEditWidget)w;
457 int i, j;
458
459 if (!self->crEdit.map) return;
460 for (j = area.x;
461 j < area.x + area.width && j < MAP_WIDTH(self->crEdit.map);
462 j++) {
463 for (i = area.y;
464 i < area.y + area.height && i < MAP_HEIGHT(self->crEdit.map);
465 i++) {
466 UpdatePosition (w,j,i,inv);
467 }
468 }
469 }
470
471 /*
472 * member: draw open square
473 * seg : start and end points of square
474 * inv : border of square are inversed
475 */
476 static void DrawBorder(Widget w,XSegment seg,Boolean inv)
477 {
478 CrEditWidget self = (CrEditWidget)w;
479 int i,x1,x2,y1,y2;
480
481 if (!self->crEdit.map) return;
482 x1 = seg.x1 < seg.x2 ? seg.x1 : seg.x2;
483 y1 = seg.y1 < seg.y2 ? seg.y1 : seg.y2;
484 x2 = abs(seg.x1 - seg.x2) + x1;
485 y2 = abs(seg.y1 - seg.y2) + y1;
486
487 if(x1 > MAP_WIDTH(self->crEdit.map) ||
488 x2 > MAP_WIDTH(self->crEdit.map) ||
489 y1 > MAP_HEIGHT(self->crEdit.map) ||
490 y2 > MAP_HEIGHT(self->crEdit.map)) return;
491
492 if (inv) {
493 XDrawRectangle (XtDisplay(w), XtWindow(w),
494 DefaultGC(XtDisplay(w), XScreenNumberOfScreen(XtScreen(w))),
495 x1 * self->crEdit.fontSize,
496 y1 * self->crEdit.fontSize,
497 (x2 - x1 + 1) * self->crEdit.fontSize - 1,
498 (y2 - y1 + 1) * self->crEdit.fontSize - 1);
499 XDrawRectangle (XtDisplay(w), XtWindow(w),
500 DefaultGC(XtDisplay(w), XScreenNumberOfScreen(XtScreen(w))),
501 x1 * self->crEdit.fontSize + 1,
502 y1 * self->crEdit.fontSize + 1,
503 (x2 - x1 + 1) * self->crEdit.fontSize - 3,
504 (y2 - y1 + 1) * self->crEdit.fontSize - 3);
505 } else {
506
507 for(i=x1;
508 i <= x2;
509 i++) {
510 UpdatePosition(w,i,seg.y1,inv);
511 if (y1 != y2)
512 UpdatePosition(w,i,seg.y2,inv);
513 }
514 for(i=y1 + 1;
515 i <= (y2 - 1);
516 i++) {
517 UpdatePosition(w,seg.x1,i,inv);
518 if (x1 != x2)
519 UpdatePosition(w,seg.x2,i,inv);
520 }
521 }
522 }
523
524 /*
525 * member:
526 * x,y :
527 * return:
528 */
529 static int CalcIndex (Widget w, int x, int y) {
530 CrEditWidget self = (CrEditWidget)w;
531 object *op;
532 int i, j = 0;
533 int xp, yp;
534 float xb, yb;
535
536 xp = x / self->crEdit.fontSize;
537 yp = y / self->crEdit.fontSize;
538
539 if (out_of_map (self->crEdit.map, xp, yp))
540 return 0;
541
542 for (i = 0, op = get_map_ob (self->crEdit.map, xp, yp);
543 op;
544 i++, op = op->above);
545
546 if (i > 0) {
547 int diff = self->crEdit.fontSize - FontSize;
548 int depth = diff / STACK_MIN;
549 float dist = 0;
550
551 if (depth == 0)
552 depth = 1;
553 if (i > depth)
554 i = depth;
555
556 i--;
557 if (i) {
558 dist = (diff - 1) / (float)i;
559 if (dist > STACK_MAX)
560 dist = STACK_MAX;
561 }
562
563 xb = self->crEdit.fontSize - i * dist;
564 yb = self->crEdit.fontSize - i * dist;
565
566 x %= self->crEdit.fontSize;
567 y %= self->crEdit.fontSize;
568
569 debug4 ("%dx%d %d %f\n", x, y, i, dist);
570 for (j = 0; j <= i; j++) {
571 if (x < xb && y < yb)
572 break;
573 xb += dist;
574 yb += dist;
575 }
576 }
577 return (j);
578 }
579
580 /*
581 * no borders drawing set
582 */
583 static void BorderOff(Widget w)
584 {
585 CrEditWidget self = (CrEditWidget)w;
586 self->crEdit.seg.x1 = 0;
587 self->crEdit.seg.y1 = 0;
588 self->crEdit.seg.x2 = 10000;
589 self->crEdit.seg.y2 = 10000;
590 }
591
592 /**********************************************************************
593 * actions
594 **********************************************************************/
595
596 /*
597 * action: insert object to map
598 */
599 static void InsertAc (Widget w, XEvent * event,
600 String * argv, Cardinal * argc)
601 {
602 CrEditWidget self = (CrEditWidget)w;
603 int x, y;
604 static int oldx, oldy;
605 struct CrEditCall call;
606
607 AnimateCursor (w, event->xbutton.x, event->xbutton.y);
608 x = event->xbutton.x / self->crEdit.fontSize;
609 y = event->xbutton.y / self->crEdit.fontSize;
610
611 if(XtHasCallbacks(w,XtNinsertCallback) == XtCallbackHasNone) return;
612 /*** fill the call strcture ***/
613 call.rect.x = x;
614 call.rect.y = y;
615 call.rect.width = 0;
616 call.rect.height = 0;
617 call.map = self->crEdit.map;
618 call.z = self->crEdit.stacking ?
619 CalcIndex (w,event->xbutton.x,event->xbutton.y) : 0;
620
621 if (!(event->type == MotionNotify && x == oldx && y == oldy)) {
622 XtCallCallbackList(w,self->crEdit.insertCallbacks,(XtPointer)&call);
623 }
624 oldx = x;
625 oldy = y;
626 }
627
628 /*
629 * action: set begin of selection
630 */
631 static void SelectBeginAc(Widget w, XEvent * event,
632 String * argv, Cardinal * argc)
633 {
634 CrEditWidget self = (CrEditWidget)w;
635 int x,y;
636
637 AnimateCursor (w, event->xbutton.x, event->xbutton.y);
638 if(!self->crEdit.selectArea) return;
639 DrawBorder(w,self->crEdit.seg,False);
640
641 x = event->xbutton.x / self->crEdit.fontSize;
642 y = event->xbutton.y / self->crEdit.fontSize;
643
644 debug2("SelectBeginAc() %dx%d\n",x,y);
645
646 if(out_of_map(self->crEdit.map,x,y)) return;
647
648 self->crEdit.seg.x1 = self->crEdit.seg.x2 = x;
649 self->crEdit.seg.y1 = self->crEdit.seg.y2 = y;
650 DrawBorder(w,self->crEdit.seg,True);
651 }
652
653 /*
654 * action: expand selection
655 */
656 static void SelectExpandAc(Widget w, XEvent * event,
657 String * argv, Cardinal * argc)
658 {
659 CrEditWidget self = (CrEditWidget)w;
660 int x,y;
661 static int oldx, oldy;
662
663 AnimateCursor (w, event->xbutton.x, event->xbutton.y);
664 if(!self->crEdit.selectArea) return;
665
666 x = event->xbutton.x / self->crEdit.fontSize;
667 y = event->xbutton.y / self->crEdit.fontSize;
668
669 if (x >= MAP_WIDTH(self->crEdit.map) )
670 x = MAP_WIDTH(self->crEdit.map) - 1;
671 if (x < 0)
672 x = 0;
673
674 if (y >= MAP_HEIGHT(self->crEdit.map) )
675 y = MAP_HEIGHT(self->crEdit.map) - 1;
676 if (y < 0)
677 y = 0;
678
679 if (!(event->type == MotionNotify && x == oldx && y == oldy)) {
680 DrawBorder(w,self->crEdit.seg,False);
681 self->crEdit.seg.x2 = x;
682 self->crEdit.seg.y2 = y;
683 DrawBorder(w,self->crEdit.seg,True);
684 }
685 oldx = x;
686 oldy = y;
687 }
688
689 /*
690 * action: get end of selection
691 */
692 static void SelectEndAc(Widget w, XEvent * event,
693 String * argv, Cardinal * argc)
694 {
695 CrEditWidget self = (CrEditWidget)w;
696 int x,y;
697 struct CrEditCall call;
698
699 x = event->xbutton.x / self->crEdit.fontSize;
700 y = event->xbutton.y / self->crEdit.fontSize;
701
702 debug2("SelectEndAc() %dx%d\n",x,y);
703
704 if (x >= MAP_WIDTH(self->crEdit.map) )
705 x = MAP_WIDTH(self->crEdit.map) - 1;
706 if (x < 0)
707 x = 0;
708
709 if (y >= MAP_HEIGHT(self->crEdit.map) )
710 y = MAP_HEIGHT(self->crEdit.map) - 1;
711 if (y < 0)
712 y = 0;
713
714 /*** fill the call strcture ***/
715 if(self->crEdit.selectArea) {
716 SegToRec(&self->crEdit.seg,&call.rect);
717 } else {
718 call.rect.x = x;
719 call.rect.y = y;
720 call.rect.width = 0;
721 call.rect.height = 0;
722 }
723 call.map = self->crEdit.map;
724 call.z = 0;
725
726 XtCallCallbackList(w,self->crEdit.selectCallbacks,(XtPointer)&call);
727 }
728
729 /*
730 * action:
731 */
732 static void PropsAc(Widget w, XEvent * event,
733 String * argv, Cardinal * argc)
734 {
735 CrEditWidget self = (CrEditWidget)w;
736 int x, y;
737 struct CrEditCall call;
738
739 AnimateCursor (w, event->xbutton.x, event->xbutton.y);
740 x = event->xbutton.x / self->crEdit.fontSize;
741 y = event->xbutton.y / self->crEdit.fontSize;
742
743 /*** fill the call strcture ***/
744 call.rect.x = x;
745 call.rect.y = y;
746 call.rect.width = 0;
747 call.rect.height = 0;
748 call.map = self->crEdit.map;
749 call.z = self->crEdit.stacking ? CalcIndex
750 (w,event->xbutton.x, event->xbutton.y) : 0;
751
752 XtCallCallbackList(w,self->crEdit.propsCallbacks,(XtPointer)&call);
753 }
754
755 /*
756 * action: delete object from map
757 */
758 static void DeleteAc(Widget w, XEvent * event,
759 String * argv, Cardinal * argc)
760 {
761 CrEditWidget self = (CrEditWidget)w;
762 int x, y;
763 static int oldx, oldy;
764 struct CrEditCall call;
765
766 AnimateCursor (w, event->xbutton.x, event->xbutton.y);
767 x = event->xbutton.x / self->crEdit.fontSize;
768 y = event->xbutton.y / self->crEdit.fontSize;
769
770 if (!(event->type == MotionNotify && x == oldx && y == oldy)) {
771 /*** fill the call strcture ***/
772 call.rect.x = x;
773 call.rect.y = y;
774 call.rect.width = 0;
775 call.rect.height = 0;
776 call.map = self->crEdit.map;
777 call.z = self->crEdit.stacking ? CalcIndex
778 (w,event->xbutton.x, event->xbutton.y) : 0;
779
780 XtCallCallbackList(w,self->crEdit.deleteCallbacks,(XtPointer)&call);
781 UpdatePosition(w,x,y,False);
782 }
783 oldx = x;
784 oldy = y;
785 }
786
787 /*
788 * action: feed point
789 */
790 static void FeedAc (Widget w, XEvent * event, String * argv, Cardinal * argc)
791 {
792 CrEditWidget self = (CrEditWidget)w;
793 int x, y;
794 static int oldx, oldy;
795 struct CrEditCall call;
796
797 x = event->xbutton.x / self->crEdit.fontSize;
798 y = event->xbutton.y / self->crEdit.fontSize;
799
800 if (!(event->type == MotionNotify && x == oldx && y == oldy)) {
801 /*** fill the call strcture ***/
802 call.rect.x = x;
803 call.rect.y = y;
804 call.rect.width = 0;
805 call.rect.height = 0;
806 call.map = self->crEdit.map;
807 call.z = self->crEdit.stacking ? CalcIndex
808 (w,event->xbutton.x, event->xbutton.y) : 0;
809
810 XtCallCallbackList(w,self->crEdit.feedCallbacks,(XtPointer)&call);
811 }
812
813 oldx = x;
814 oldy = y;
815 }
816
817 /*
818 * action: resize to directions
819 */
820 static void ResizeAc (Widget w, XEvent * e, String * argv, Cardinal * argc)
821 {
822 CrEditWidget self = (CrEditWidget)w;
823 struct CrEditCall call;
824 char buf[BUFSIZ];
825
826 call.map = self->crEdit.map;
827 call.rect.x = 0;
828 call.rect.y = 0;
829 call.rect.width = MAP_WIDTH(self->crEdit.map);
830 call.rect.height = MAP_HEIGHT(self->crEdit.map);
831 call.z = 0;
832 if (argv) {
833 if (!strcmp (argv[0], "right")) {
834 call.rect.width++;
835 } else if (!strcmp (argv[0], "left")) {
836 call.rect.width--;
837 } else if (!strcmp (argv[0], "down")) {
838 call.rect.height++;
839 } else if (!strcmp (argv[0], "up")) {
840 call.rect.height--;
841 } else {
842 sprintf(buf,"bad argument %s",argv[0]);
843 CnvWarn(w,buf);
844 }
845 }
846 XtCallCallbackList(w,self->crEdit.alignCallbacks,(XtPointer)&call);
847 }
848
849 /*
850 * action: scroll around to directions
851 */
852 static void ScrollAc (Widget w, XEvent * e, String * argv, Cardinal * argc)
853 {
854 CrEditWidget self = (CrEditWidget)w;
855 struct CrEditCall call;
856 char buf[BUFSIZ];
857
858 call.map = self->crEdit.map;
859 call.rect.x = 0;
860 call.rect.y = 0;
861 call.rect.width = MAP_WIDTH(self->crEdit.map);
862 call.rect.height = MAP_HEIGHT(self->crEdit.map);
863 call.z = 0;
864
865 /*
866 debug4("CrEdit::ScrollAc() by %dx%d+%d+%d",call->rect.width,
867 call->rect.height,call->rect.x,call->rect.y); */
868
869 if (argv) {
870 if (!strcmp (argv[0], "right")) {
871 call.rect.x++;
872 } else if (!strcmp (argv[0], "left")) {
873 call.rect.x--;
874 } else if (!strcmp (argv[0], "down")) {
875 call.rect.y++;
876 } else if (!strcmp (argv[0], "up")) {
877 call.rect.y--;
878 } else {
879 sprintf(buf,"bad argument %s",argv[0]);
880 CnvWarn(w,buf);
881 }
882 XtCallCallbackList(w,self->crEdit.alignCallbacks,(XtPointer)&call);
883 }
884 }
885
886 /*
887 * action: move clipped window in viewport
888 */
889 static void MoveAc (Widget w, XEvent * e, String * argv, Cardinal * argc)
890 {
891 /* CrEditWidget self = (CrEditWidget)w; */
892 Widget horizontal, vertical;
893
894 if (argv) {
895 horizontal = XtNameToWidget (XtParent (w), "horizontal");
896 vertical = XtNameToWidget (XtParent (w), "vertical");
897
898 if (!strcmp (argv[0], "right")) {
899 String argv[1];
900 argv[0] = XtNewString ("Forward");
901 XtCallActionProc (horizontal, "StartScroll", e, argv, 1);
902 XtFree (argv[0]);
903 argv[0] = XtNewString ("Proportional");
904 XtCallActionProc (horizontal, "NotifyScroll", e, argv, 1);
905 XtFree (argv[0]);
906 XtCallActionProc (horizontal, "EndScroll", e, NULL, 0);
907 } else if (!strcmp (argv[0], "left")) {
908 String argv[1];
909 argv[0] = XtNewString ("Backward");
910 XtCallActionProc (horizontal, "StartScroll", e, argv, 1);
911 XtFree (argv[0]);
912 argv[0] = XtNewString ("Proportional");
913 XtCallActionProc (horizontal, "NotifyScroll", e, argv, 1);
914 XtFree (argv[0]);
915 XtCallActionProc (horizontal, "EndScroll", e, NULL, 0);
916 } else if (!strcmp (argv[0], "down")) {
917 String argv[1];
918 argv[0] = XtNewString ("Forward");
919 XtCallActionProc (vertical, "StartScroll", e, argv, 1);
920 XtFree (argv[0]);
921 argv[0] = XtNewString ("Proportional");
922 XtCallActionProc (vertical, "NotifyScroll", e, argv, 1);
923 XtFree (argv[0]);
924 XtCallActionProc (vertical, "EndScroll", e, NULL, 0);
925 } else if (!strcmp (argv[0], "up")) {
926 String argv[1];
927 argv[0] = XtNewString ("Backward");
928 XtCallActionProc (vertical, "StartScroll", e, argv, 1);
929 XtFree (argv[0]);
930 argv[0] = XtNewString ("Proportional");
931 XtCallActionProc (vertical, "NotifyScroll", e, argv, 1);
932 XtFree (argv[0]);
933 XtCallActionProc (vertical, "EndScroll", e, NULL, 0);
934 }
935 }
936 }
937
938 /**********************************************************************
939 * members
940 **********************************************************************/
941
942 static void ClassInitialize(void)
943 {
944 debug0("CrEdit-ClassInitialize()\n");
945
946 }
947
948 static void Initialize(Widget req,Widget new,Arg args[],Cardinal *num)
949 {
950 CrEditWidget self = (CrEditWidget)new;
951
952 debug1("CrEdit-%s-Initialize()\n",XtName(new));
953
954 /*** allocate gc ***/
955 self->crEdit.gc = GCCreate (new);
956 self->crEdit.fontSize = FontSize;
957 SetSize(new);
958 BorderOff(new);
959 }
960
961 static void Destroy(Widget w)
962 {
963 CrEditWidget self = (CrEditWidget)w;
964 debug1("CrEdit-%s-Destroy()\n",XtName(w));
965 XtReleaseGC(w,self->crEdit.gc);
966 }
967
968 static void Resize(Widget w)
969 {
970 /* CrEditWidget self = (CrEditWidget)w; */
971 debug1("CrEdit-%s-Resize()\n",XtName(w));
972 SetSize(w);
973 }
974
975 static void Redisplay(Widget w,XEvent *event,Region region)
976 {
977 CrEditWidget self = (CrEditWidget)w;
978 XRectangle rect, new;
979
980 if(!region) return;
981 XClipBox(region,&rect);
982 new.x = rect.x / self->crEdit.fontSize;
983 new.y = rect.y / self->crEdit.fontSize;
984 new.width = (rect.x + rect.width) / self->crEdit.fontSize - new.x + 1;
985 new.height = (rect.y + rect.height) / self->crEdit.fontSize - new.y + 1;
986
987 debug5("CrEdit-%s-Expose() %dx%d+%d+%d\n",XtName(w),
988 new.width, new.height, new.x, new.y);
989
990 DrawRectangle(w,new,False);
991 if (self->crEdit.selectArea)
992 DrawBorder(w, self->crEdit.seg, True);
993 }
994
995 static Boolean SetValues(Widget cur,Widget req,Widget new,
996 Arg args[],Cardinal *num)
997 {
998 Boolean redpy = False;
999
1000 CrEditWidget self = (CrEditWidget)new;
1001 CrEditWidget old = (CrEditWidget)cur;
1002 debug1("CrEdit-%s-SetValues()\n",XtName(new));
1003
1004 /*** stacking change ***/
1005 if(self->crEdit.stacking != old->crEdit.stacking) {
1006 self->crEdit.fontSize = FontSize + self->crEdit.stacking;
1007 SetSize(new);
1008 redpy = True;
1009 }
1010 /*** map change ***/
1011 if(self->crEdit.map != old->crEdit.map) {
1012 SetSize(new);
1013 redpy = True;
1014 }
1015 /*** weak wall change ***/
1016 if(self->crEdit.show_weak_walls != old->crEdit.show_weak_walls) {
1017 SetSize(new);
1018 redpy = True;
1019 }
1020 return redpy; /* redisplay */
1021 }
1022
1023 /**********************************************************************
1024 * public
1025 **********************************************************************/
1026
1027 /*
1028 * member: draw rectangle part of w
1029 * rect : rectangle, width = height = 10000 to draw all
1030 */
1031 void CrEditRefresh(Widget w,XRectangle rect)
1032 {
1033 CrEditWidget self = (CrEditWidget)w;
1034 if(!w) return;
1035
1036
1037 debug4("CrEditRefresh() %dx%d+%d+%d\n",
1038 rect.width,
1039 rect.height,
1040 rect.x,
1041 rect.y
1042 );
1043 /* for all */
1044 if(rect.width == 10000 && rect.height == 10000) {
1045 XClearWindow(XtDisplay(w),XtWindow(w));
1046 SetSize(w); /* for partially fix to sizing probem */
1047 }
1048 DrawRectangle(w,rect,False);
1049
1050 if (self->crEdit.selectArea)
1051 DrawBorder(w, self->crEdit.seg, True);
1052 }
1053
1054 /*
1055 * atc: True: selection-border drawing active, other no draw
1056 */
1057 void CrEditBorderOff(Widget w)
1058 {
1059 CrEditWidget self = (CrEditWidget)w;
1060
1061 debug1("%s-CrEditBorderOff()\n",XtName(w));
1062 DrawBorder(w,self->crEdit.seg,False);
1063 BorderOff(w);
1064 }
1065
1066 /*
1067 * member:
1068 * rect :
1069 */
1070 void CrEditSelect(Widget w,XRectangle rect)
1071 {
1072 CrEditWidget self = (CrEditWidget)w;
1073 if(!w) return;
1074
1075
1076 debug4("CrEditRefresh() %dx%d+%d+%d\n",
1077 rect.width,
1078 rect.height,
1079 rect.x,
1080 rect.y
1081 );
1082 /* for all */
1083 if(rect.width == 10000 && rect.height == 10000) {
1084 XClearWindow(XtDisplay(w),XtWindow(w));
1085 SetSize(w); /* for partially fix to sizing probem */
1086 }
1087
1088 if (self->crEdit.selectArea) {
1089 DrawBorder(w, self->crEdit.seg, False);
1090 self->crEdit.seg.x1 = rect.x;
1091 self->crEdit.seg.y1 = rect.y;
1092 self->crEdit.seg.x2 = rect.x + rect.width;
1093 self->crEdit.seg.y2 = rect.y + rect.height;
1094 DrawBorder(w, self->crEdit.seg, True);
1095 }
1096 }
1097
1098 /*** end of CrEdit.c ***/