1 /* $Header: /home/yav/xpx/RCS/edit.c,v 1.32 1996/04/26 17:22:47 yav Exp $
2 * xpx image edit
3 * written by yav (UHD98984@pcvan.or.jp)
4 */
5
6 #include <X11/Xlib.h>
7 #include <X11/Xutil.h>
8 #include <X11/keysym.h>
9
10 #include "headers.h"
11 #ifdef HAVE_MATH_H
12 #include <math.h>
13 #endif
14 #include "xpx.h"
15 #include "work.h"
16 #include "editdef.h"
17 #include "menudef.h"
18 #include "cursdef.h"
19 #define PUBLIC_EDIT_C
20 #include "extern.h"
21
22
23 #define AUTOSAVETIME 30
24
25 #define EDMW 64
26 #define EDMH 24
27
28 #define EDITWINW 214
29 #define EDITWINH (EDITWINH2+8+(BDW+EDMH+BDW)+2+(BDW+EDMH+BDW)+4)
30 #define EDITWINH2 ((EDMH+BDW)*EDIT_PEN+BDW+8+(BDW+EDMH+BDW))
31
32 char rcsid_edit[] = "$Id: edit.c,v 1.32 1996/04/26 17:22:47 yav Exp $";
33
34
35 /* work */
36 static Window editfuncwin[3];
37 static int edit_mode[3] = {EDIT_PLOT, EDIT_GETCOLOR, EDIT_GETCOLOR};
38 static int area_mode = 0;
39 static int circle_mode = 0;
40 static int line_mode = 0;
41 static POS copypos0, copysrc0, copysrc1;
42 static AREA copydst;
43 static int penno[3] = {0, 0, 0};
44 static int penwidthtbl[] = {1, 2, 3, 5, 7, 0};
45
46
47 int edev();
48 int edev2();
49
edevpenstr(p)50 char *edevpenstr(p)
51 MENU *p;
52 {
53 sprintf(p->str, "width %d", penwidthtbl[penno[get_top_menu(p)->cursor]]);
54 return p->str;
55 }
56
edevpen(p,ev)57 int edevpen(p, ev)
58 MENU *p;
59 XEvent *ev;
60 {
61 int i;
62
63 switch (ev->type) {
64 case ButtonPress:
65 i = get_top_menu(p)->cursor;
66 ++penno[i];
67 if (!penwidthtbl[penno[i]])
68 penno[i] = 0;
69 redraw_window(p->win);
70 return 1;
71 }
72 return 0;
73 }
74
75 #define IMASK (ExposureMask|EnterWindowMask|LeaveWindowMask|ButtonPressMask)
76 #define EMSTRUC(num,name) \
77 { (num), MenuModeMaskBorder,\
78 0, (EDMH+BDW)*(num), EDMW, EDMH,\
79 0, IMASK, 0,\
80 edev, NULL, 0, 0, name}
81
82 static MENU menutbl[] = {
83 {
84 EDIT_dummy, 0,
85 0, 0, EDMW, EDMH,
86 0, ExposureMask, 0,
87 NULL, NULL, 0, 0, "Button?"},
88 EMSTRUC(EDIT_PLOT, "plot"),
89 EMSTRUC(EDIT_COPY, "copy"),
90 EMSTRUC(EDIT_FILL, "boxfull"),
91 EMSTRUC(EDIT_LINE, "line"),
92 EMSTRUC(EDIT_CIRCLE, "circle"),
93 EMSTRUC(EDIT_ELLIPSE, "ellipse"),
94 EMSTRUC(EDIT_PAINT, "paint"),
95 EMSTRUC(EDIT_GETCOLOR,"get"),
96 EMSTRUC(EDIT_SCROLL, "scroll"),
97 EMSTRUC(EDIT_HOTSPOT, "hotspot"),
98 EMSTRUC(EDIT_GRID, "grid"),
99 EMSTRUC(EDIT_CANCEL, "cancel"),
100 {
101 EDIT_ONGRID, MenuModeMaskBorder,
102 0, (EDMH+BDW)*EDIT_ONGRID+BDW+4, EDMW, EDMH,
103 0, IMASK, 0,
104 NULL, NULL, 0, 0, "on grid"},
105 {
106 EDIT_PEN, MenuModeMaskBorder,
107 0, (EDMH+BDW)*EDIT_PEN+BDW+4, EDMW, EDMH,
108 0, IMASK, 0,
109 edevpen, edevpenstr, 0, 16, NULL},
110 {
111 -1, 0,
112 0, 0, 0, 0,
113 0, 0, 0,
114 NULL, NULL, 0, 0, NULL}};
115
116 char *edev2str();
117 MENU editmenu2[] = {
118 {
119 EDIT2_UNDO, MenuModeMaskBorder,
120 4, 6+ BDW*2+4 + EDMH+BDW*2, 70, EDMH,
121 0, IMASK, SouthWestGravity,
122 edev2, edev2str, 0, 16, NULL},
123 {
124 EDIT2_IGNPIX, 0,
125 4 + 70+BDW*2 + 8, 6+ BDW*2+4 + EDMH+BDW*2, 78, EDMH,
126 0, ExposureMask, SouthWestGravity,
127 NULL, NULL, 0, 0, "nocopypix:"},
128 {
129 EDIT2_IGNPIXN, MenuModeMaskBorder,
130 4 + 70+BDW*2 + 8 + 78, 6+ BDW*2+4 + EDMH+BDW*2, 40, EDMH,
131 0, IMASK|KeyPressMask, SouthWestGravity,
132 edev2, NULL, 0, 8, NULL},
133 {
134 EDIT2_AREA, MenuModeMaskBorder,
135 4, BDW*2+4, EDMW, EDMH,
136 0, IMASK, SouthWestGravity,
137 edev2, NULL, 0, 0, "Area"},
138 {
139 EDIT2_OK, MenuModeMaskBorder,
140 BDW*2+4, BDW*2+4, EDMW, EDMH,
141 0, IMASK, SouthEastGravity,
142 edev2, NULL, 0, 0, "OK"},
143 {
144 -1, 0,
145 0, 0, 0, 0,
146 0, 0, 0,
147 NULL, NULL, 0, 0, NULL}};
148 MENU *menutblp[3];
149
150 static int *ptsbuf = NULL;
151
152
create_edit_window()153 int create_edit_window()
154 {
155 int i;
156 MENU *p;
157 static char *titles[3] = {"Button1", "Button2", "Button3"};
158
159 ptsbuf = (int*)malloc(sizeof(int)*8*(imgmaxw+imgmaxh));
160
161 create_toplevel_window(&editwin, "edit", str_edit_geom, EDITWINW, EDITWINH);
162 XSelectInput(dsp, editwin, ExposureMask);
163 for (i = 0; i < 3; i++) {
164 editfuncwin[i] =
165 XCreateSimpleWindow(dsp, editwin,
166 4+(EDMW+BDW*2+4)*i, 0, EDMW+BDW*2, EDITWINH2,
167 0, fg, bg);
168 XSelectInput(dsp, editfuncwin[i], ExposureMask);
169 XMapWindow(dsp, editfuncwin[i]);
170 p = (MENU *)malloc(sizeof(menutbl));
171 memcpy(p, menutbl, sizeof(menutbl));
172 p->str = titles[i];
173 p->cursor = i;
174 if (i == 0) {
175 /* short cut key initial */
176 (p+EDIT_PLOT)->str = "plOt";
177 (p+EDIT_COPY)->str = "Copy";
178 (p+EDIT_FILL)->str = "Boxfull";
179 (p+EDIT_LINE)->str = "liNe";
180 (p+EDIT_PAINT)->str = "Paint";
181 }
182 (p+edit_mode[i])->mode |= MenuModeMaskOn;
183 menuwin_create(p, editfuncwin[i], 0, 0);
184 menutblp[i] = p;
185 }
186 menuwin_create(editmenu2, editwin, 0, 0);
187 /* Area edit menu */
188 create_area_menu();
189 return 0;
190 }
191
map_edit_window()192 void map_edit_window()
193 {
194 XMapRaised(dsp, editwin);
195 }
196
unmap_edit_window()197 void unmap_edit_window()
198 {
199 XUnmapWindow(dsp, editwin);
200 }
201
close_edit_window()202 void close_edit_window()
203 {
204 XDestroyWindow(dsp, editwin);
205 }
206
area_mode_reset()207 void area_mode_reset()
208 {
209 area_flag = False;
210 area_mode = line_mode = circle_mode = 0;
211 copy_area_expose();
212 }
213
edit_mode_change2(btn,mode)214 void edit_mode_change2(btn, mode)
215 int btn; /* 0:Button1 1:Button2 2:Button3 */
216 int mode;
217 {
218 MENU *p;
219
220 area_mode_reset();
221 p = menutblp[btn]+edit_mode[btn];
222 if (mode != edit_mode[btn]) {
223 p->mode &= ~MenuModeMaskOn;
224 redraw_window(p->win);
225 edit_mode[btn] = mode;
226 p = menutblp[btn]+mode;
227 p->mode |= MenuModeMaskOn;
228 redraw_window(p->win);
229 }
230 }
231
edit_mode_change(n)232 void edit_mode_change(n)
233 int n;
234 {
235 edit_mode_change2(0, n);
236 }
237
edev(p,ev)238 int edev(p, ev)
239 MENU *p;
240 XEvent *ev;
241 {
242 switch(ev->type) {
243 case ButtonPress:
244 edit_mode_change2(get_top_menu(p)->cursor, p->n);
245 return 1;
246 }
247 return 0;
248 }
249
edit_undo()250 void edit_undo()
251 {
252 cursor_busy();
253 undo_pull();
254 }
255
edev2(p,ev)256 int edev2(p, ev)
257 MENU *p;
258 XEvent *ev;
259 {
260 int i;
261 KeySym key;
262 char buf[16];
263
264 switch(ev->type) {
265 case ButtonPress:
266 switch(p->n) {
267 case EDIT2_UNDO:
268 edit_undo();
269 p->mode &= ~MenuModeMaskOn;
270 redraw_window(p->win);
271 return 1;
272 case EDIT2_AREA:
273 p->mode ^= MenuModeMaskOn;
274 if (p->mode & MenuModeMaskOn)
275 map_area_window();
276 else
277 unmap_area_window();
278 redraw_window(p->win);
279 return 1;
280 case EDIT2_OK:
281 p->mode &= ~MenuModeMaskOn;
282 menu_stat_change(MENU_EDIT, 0);
283 return 1;
284 case EDIT2_IGNPIXN:
285 p->mode ^= MenuModeMaskOn;
286 nocopypixel_mode = p->mode & MenuModeMaskOn ? True : False;
287 redraw_window(p->win);
288 return 1;
289 }
290 case KeyPress:
291 i = XLookupString((XKeyEvent *)ev, buf, sizeof(buf)-1, &key, NULL);
292 buf[i] = '\0';
293 switch(key) {
294 case XK_KP_Enter:
295 case XK_Return:
296 i = strtol(p->str, NULL, 0);
297 if (i >= 0 && i < 256) {
298 nocopypixel = i;
299 sprintf(p->str, "%d", i);
300 p->mode |= MenuModeMaskOn;
301 nocopypixel_mode = True;
302 } else {
303 p->mode &= ~MenuModeMaskOn;
304 nocopypixel_mode = False;
305 }
306 redraw_window(p->win);
307 return 1;
308 }
309 break;
310 }
311 return 0;
312 }
313
edev2str(p)314 char *edev2str(p)
315 MENU *p;
316 {
317 switch(p->n) {
318 case EDIT2_UNDO:
319 if (undo_cnt >= MAXUNDO)
320 strcpy(p->str, "Undo MAX");
321 else
322 sprintf(p->str, "Undo %d", undo_cnt);
323 break;
324 }
325 return p->str;
326 }
327
edit_undo_update()328 void edit_undo_update()
329 {
330 static int last_undo_cnt = -1;
331
332 if (undo_cnt != last_undo_cnt) {
333 redraw_window(editmenu2[EDIT2_UNDO].win);
334 last_undo_cnt = undo_cnt;
335 }
336 }
337
338 /*********************************
339 * image edit function
340 */
341
area_img_expose(x,y,w,h)342 void area_img_expose(x, y, w, h)
343 int x;
344 int y;
345 int w;
346 int h;
347 {
348 calc_img_area(&x, &y, &w, &h);
349 img_expose(x, y, w, h);
350 }
351
plot(x,y,c)352 void plot(x, y, c)
353 int x;
354 int y;
355 int c;
356 {
357 setpixelcolor(x, y, c);
358 if (vimg != NULL)
359 XClearArea(dsp, viewwin, x, y, 1, 1, True);
360 img_expose(x*zoomfactor-imgofsx, y*zoomfactor-imgofsy,
361 zoomfactor, zoomfactor);
362 }
363
364 /* Window update */
area_update(x,y,w,h)365 void area_update(x, y, w, h)
366 int x;
367 int y;
368 int w;
369 int h;
370 {
371 if (vimg != NULL)
372 XClearArea(dsp, viewwin, x, y, w, h, True);
373 area_img_expose(x, y, w, h);
374 copy_area_expose();
375 }
376
copy(dstx,dsty,srcx,srcy,w,h)377 void copy(dstx, dsty, srcx, srcy, w, h)
378 int dstx;
379 int dsty;
380 int srcx;
381 int srcy;
382 int w;
383 int h;
384 {
385 if (w > 0 && h > 0) {
386 undo_push_area(dstx, dsty, w, h);
387 copy_area(dstx, dsty, srcx, srcy, w, h);
388 area_update(dstx, dsty, w, h);
389 }
390 }
391
392
fill(x,y,w,h,c)393 void fill(x, y, w, h, c)
394 int x;
395 int y;
396 int w;
397 int h;
398 int c;
399 {
400 if (w > 0 && h > 0) {
401 undo_push_area(x, y, w, h);
402 fill_area(x, y, w, h, c);
403 area_update(x, y, w, h);
404 }
405 }
406
edit_plot(x,y,pen)407 void edit_plot(x, y, pen)
408 int x;
409 int y;
410 int pen; /* pen width (pixel) */
411 {
412 static int lastpen = -1;
413 static int lastcol = -1;
414
415 switch (pen) {
416 case 1:
417 if (current_col >= 0 && *(imgdata+y*imgmaxw+x) != current_col) {
418 undo_push_plot(x, y, *(imgdata+y*imgmaxw+x), current_col);
419 plot(x, y, current_col);
420 }
421 break;
422 default:
423 if (pen != lastpen || current_col != lastcol) {
424 cursor_busy();
425 undo_push_area(0, 0, imgfilew, imgfileh);
426 lastpen = pen;
427 lastcol = current_col;
428 }
429 fill_area(x-(pen-1)/2, y-(pen-1)/2, pen, pen, current_col);
430 area_update(x-(pen-1)/2, y-(pen-1)/2, pen, pen);
431 break;
432 }
433 }
434
edit_copy_and_fill(x,y,type,btn)435 void edit_copy_and_fill(x, y, type, btn)
436 int x;
437 int y;
438 int type; /* event type */
439 int btn; /* 0:Button1 1:Button2 2:Button3 */
440 {
441 switch (type) {
442 case ButtonPress:
443 switch(area_mode) {
444 case 2:
445 if (inarea(x, 1, copysrc0.x, copysrc1.x)&&
446 inarea(y, 1, copysrc0.y, copysrc1.y)) {
447 /* area catch */
448 copydst.x = x - copysrc0.x;
449 copydst.y = y - copysrc0.y;
450 copydst.w = copysrc1.x - copysrc0.x;
451 copydst.h = copysrc1.y - copysrc0.y;
452 area_mode = 3;
453 break;
454 }
455 /* FALL THROUGH */
456 case 0:
457 /* area mark start */
458 copypos0.x = x;
459 copypos0.y = y;
460 area_mode = 1;
461 break;
462 }
463 break;
464 case ButtonRelease:
465 switch(area_mode) {
466 case 3:
467 /* paste */
468 copy(area0.x, area0.y, copysrc0.x, copysrc0.y,
469 copysrc1.x - copysrc0.x, copysrc1.y - copysrc0.y);
470 /* FALL THROUGH */
471 case 1:
472 /* area mark end */
473 copysrc0.x = area0.x;
474 copysrc0.y = area0.y;
475 copysrc1.x = area0.w;
476 copysrc1.y = area0.h;
477 little_big(©src0.x, ©src1.x);
478 little_big(©src0.y, ©src1.y);
479 switch(edit_mode[btn]) {
480 case EDIT_FILL:
481 erase_last_area();
482 area_flag = False;
483 area_mode = 0;
484 fill(copysrc0.x, copysrc0.y,
485 copysrc1.x-copysrc0.x, copysrc1.y-copysrc0.y, current_col);
486 break;
487 case EDIT_COPY:
488 area_mode = 2;
489 break;
490 }
491 break;
492 }
493 break;
494 case MotionNotify:
495 switch(area_mode) {
496 case 1:
497 /* area size update */
498 if (x != area0.w || y != area0.h) {
499 area0.w = x;
500 area0.h = y;
501 area0.x = copypos0.x;
502 area0.y = copypos0.y;
503 area_flag = True;
504 copy_area_expose();
505 }
506 break;
507 case 3:
508 /* drug area */
509 x -= copydst.x;
510 if (x < 0)
511 x = 0;
512 if (x + copydst.w > imgfilew)
513 x = imgfilew - copydst.w;
514 y -= copydst.y;
515 if (y < 0)
516 y = 0;
517 if (y + copydst.h > imgfileh)
518 y = imgfileh - copydst.h;
519 if (x != area0.x || y != area0.y) {
520 area0.x = x;
521 area0.y = y;
522 area0.w = x + copydst.w;
523 area0.h = y + copydst.h;
524 copy_area_expose();
525 }
526 break;
527 }
528 break;
529 }
530 }
531
532 #ifndef abs
533 #define abs(x) ((x)<0?-(x):(x))
534 #endif
535
plots(p,n,pen)536 void plots(p, n, pen)
537 int *p;
538 int n;
539 int pen; /* pen width (pixel) */
540 {
541 int x, y, x0, y0, x1, y1;
542 int xs, ys, xe, ye;
543 int d0, d1;
544
545 if (current_col < 0 || n <= 0)
546 return;
547 /* check update area */
548 max_area(&x0, &y0, &x1, &y1, n, p);
549 d0 = (pen-1) / 2;
550 if ((x0 -= d0) < 0)
551 x0 = 0;
552 if ((y0 -= d0) < 0)
553 y0 = 0;
554 d1 = pen / 2;
555 if ((x1 += d1) >= imgmaxw)
556 x1 = imgmaxw - 1;
557 if ((y1 += d1) >= imgmaxh)
558 y1 = imgmaxh - 1;
559 undo_push_area(x0, y0, x1-x0+1, y1-y0+1);
560 while (n--) {
561 xs = xe = *p++;
562 ys = ye = *p++;
563 if ((xs -= d0) < 0)
564 xs = 0;
565 if ((xe += d1) >= imgmaxw)
566 xe = imgmaxw - 1;
567 if ((ys -= d0) < 0)
568 ys = 0;
569 if ((ye += d1) >= imgmaxh)
570 ye = imgmaxh - 1;
571 for (y = ys; y <= ye; y++) {
572 for (x = xs; x <= xe; x++) {
573 setpixelcolor(x, y, current_col);
574 }
575 }
576 }
577 if (vimg != NULL)
578 XClearArea(dsp, viewwin, x0, y0, x1-x0+1, y1-y0+1, True);
579 img_expose(x0*zoomfactor-imgofsx, y0*zoomfactor-imgofsy,
580 (x1-x0+1)*zoomfactor, (y1-y0+1)*zoomfactor);
581 }
582
edit_line(x,y,ev,btn)583 void edit_line(x, y, ev, btn)
584 int x;
585 int y;
586 int ev; /* event type */
587 int btn; /* 0:Button1 1:Button2 2:Button3 */
588 {
589 int i;
590 static int x0, y0, x1, y1;
591
592 switch(ev) {
593 case ButtonPress:
594 x0 = x;
595 y0 = y;
596 x1 = y1 = -1;
597 line_mode = 1;
598 break;
599 case ButtonRelease:
600 if (line_mode == 1) {
601 i = line(ptsbuf, x0, y0, x, y);
602 mark_flag = False;
603 mark_pts_expose();
604 plots(ptsbuf, i, penwidthtbl[penno[btn]]);
605 line_mode = 0;
606 }
607 break;
608 case MotionNotify:
609 if (line_mode == 1 && (x != x1 || y != y1)) {
610 mark_flag = False;
611 mark_pts_expose();
612 i = line(ptsbuf, x0, y0, x, y);
613 mark_pts_set(i, ptsbuf);
614 mark_flag = True;
615 mark_pts_expose();
616 x1 = x;
617 y1 = y;
618 }
619 break;
620 }
621 }
622
edit_circle_and_ellipse(x,y,ev,btn)623 void edit_circle_and_ellipse(x, y, ev, btn)
624 int x;
625 int y;
626 int ev; /* event type */
627 int btn; /* 0:Button1 1:Button2 2:Button3 */
628 {
629 int i, rx, ry;
630 static int x0, y0, x1, y1;
631
632 switch(ev) {
633 case ButtonPress:
634 x0 = x;
635 y0 = y;
636 x1 = y1 = -1;
637 circle_mode = 1;
638 break;
639 case ButtonRelease:
640 if (circle_mode == 1) {
641 rx = abs(x-x0);
642 ry = abs(y-y0);
643 if (edit_mode[btn] == EDIT_CIRCLE)
644 ry = rx = ry>rx?ry:rx;
645 if (rx > 0 && ry > 0) {
646 if (edit_mode[btn] == EDIT_CIRCLE)
647 i = circle(ptsbuf, x0, y0, rx);
648 else
649 i = ellipse(ptsbuf, x0, y0, rx, ry);
650 mark_flag = False;
651 mark_pts_expose();
652 plots(ptsbuf, i, penwidthtbl[penno[btn]]);
653 }
654 area_flag = False;
655 copy_area_expose();
656 circle_mode = 0;
657 }
658 break;
659 case MotionNotify:
660 if (circle_mode == 1 && (x != x1 || y != y1)) {
661 rx = abs(x-x0);
662 ry = abs(y-y0);
663 if (edit_mode[btn] == EDIT_CIRCLE)
664 ry = rx = ry>rx?ry:rx;
665 if (rx > 0 && ry > 0) {
666 mark_flag = False;
667 mark_pts_expose();
668 if (edit_mode[btn] == EDIT_CIRCLE)
669 i = circle(ptsbuf, x0, y0, rx);
670 else
671 i = ellipse(ptsbuf, x0, y0, rx, ry);
672 mark_pts_set(i, ptsbuf);
673 mark_flag = True;
674 mark_pts_expose();
675 }
676 x1 = x;
677 y1 = y;
678 }
679 break;
680 }
681 }
682
683
edit_paint(x,y,type)684 void edit_paint(x, y, type)
685 int x;
686 int y;
687 int type;
688 {
689 switch(type) {
690 case ButtonPress:
691 cursor_busy();
692 painted_pixel = *(imgdata+y*imgmaxw+x);
693 if (painted_pixel != current_col) {
694 undo_push_area(0, 0, imgfilew, imgfileh);
695 paint(x, y);
696 area_update(0, 0, imgfilew, imgfileh);
697 }
698 break;
699 case ButtonRelease:
700 break;
701 }
702 }
703
img_button_sub(x,y,type,btn,ox,oy)704 void img_button_sub(x, y, type, btn, ox, oy)
705 int x;
706 int y;
707 int type;
708 int btn; /* 0:Button1 1:Button2 2:Button3 */
709 int ox;
710 int oy;
711 {
712 switch (edit_mode[btn]) {
713 case EDIT_GETCOLOR:
714 set_current_color(*(imgdata+y*imgmaxw+x));
715 break;
716 case EDIT_PLOT:
717 edit_plot(x, y, penwidthtbl[penno[btn]]);
718 break;
719 case EDIT_COPY:
720 case EDIT_FILL:
721 edit_copy_and_fill(x, y, type, btn);
722 break;
723 case EDIT_LINE:
724 edit_line(x, y, type, btn);
725 break;
726 case EDIT_CIRCLE:
727 case EDIT_ELLIPSE:
728 edit_circle_and_ellipse(x, y, type, btn);
729 break;
730 case EDIT_PAINT:
731 edit_paint(x, y, type);
732 break;
733 case EDIT_SCROLL:
734 switch(type) {
735 case ButtonPress:
736 /* set background scroll */
737 if (ox < imgwinwidth/3)
738 scroll_ax = -1;
739 if (ox >= imgwinwidth*2/3)
740 scroll_ax = 1;
741 if (oy < imgwinheight/3)
742 scroll_ay = -1;
743 if (oy >= imgwinheight*2/3)
744 scroll_ay = 1;
745 break;
746 case ButtonRelease:
747 /* reset background scroll */
748 scroll_dx = scroll_dy = 0;
749 scroll_ax = scroll_ay = 0;
750 break;
751 }
752 break;
753 case EDIT_GRID:
754 if (type == ButtonPress) {
755 grid_ofsx = x % grid_size;
756 grid_ofsy = y % grid_size;
757 set_image_size(-1, -1);
758 area_mode_reset();
759 }
760 break;
761 case EDIT_HOTSPOT:
762 if (type == ButtonPress) {
763 if (x == hotspotx && y == hotspoty)
764 x = y = -1;
765 hotspotx = x;
766 hotspoty = y;
767 set_image_size(-1, -1);
768 }
769 /* continue to next case */
770 case EDIT_CANCEL:
771 default:
772 if (type == ButtonPress)
773 area_mode_reset();
774 mark_pts_expose();
775 return;
776 }
777 }
778
img_button(type,ox,oy,button,st)779 void img_button(type, ox, oy, button, st)
780 int type;
781 int ox;
782 int oy;
783 int button;
784 unsigned int st;
785 {
786 int x, y, dx, dy, btn;
787
788 x = (ox + imgofsx) / zoomfactor;
789 y = (oy + imgofsy) / zoomfactor;
790 switch(button) {
791 case Button1:
792 btn = 0;
793 break;
794 case Button2:
795 btn = 1;
796 break;
797 case Button3:
798 btn = 2;
799 break;
800 }
801 if ((menutblp[btn]+EDIT_ONGRID)->mode & MenuModeMaskOn) {
802 dx = (x - grid_ofsx) % grid_size;
803 x -= dx;
804 if (dx > grid_size/2)
805 x += grid_size;
806 dy = (y - grid_ofsy) % grid_size;
807 y -= dy;
808 if (dy > grid_size/2)
809 y += grid_size;
810 }
811 if (x < 0)
812 x = 0;
813 if (x >= imgfilew)
814 x = imgfilew;
815 if (y < 0)
816 y = 0;
817 if (y >= imgfileh)
818 y = imgfileh;
819 if (x != curx) {
820 curx = x;
821 redraw_window(cursmenu[CURS_CURX].win);
822 }
823 if (y != cury) {
824 cury = y;
825 redraw_window(cursmenu[CURS_CURY].win);
826 }
827 img_button_sub(x, y, type, btn, ox, oy);
828 }
829
edit_event(ev)830 void edit_event(ev)
831 XEvent *ev;
832 {
833 int x, y, button;
834 static int savecnt = 0;
835
836 if (get_event_window(ev) != imgwin)
837 return;
838 switch (ev->type) {
839 case MotionNotify:
840 x = ev->xmotion.x;
841 y = ev->xmotion.y;
842 if (ev->xmotion.state & Button1Mask)
843 img_button(ev->type, x, y, Button1);
844 if (ev->xmotion.state & Button2Mask)
845 img_button(ev->type, x, y, Button2);
846 if (ev->xmotion.state & Button3Mask)
847 img_button(ev->type, x, y, Button3);
848 break;
849 case ButtonRelease:
850 if (++savecnt >= AUTOSAVETIME) {
851 autosave();
852 savecnt = 0;
853 }
854 case ButtonPress:
855 button = ev->xbutton.button;
856 img_button(ev->type, ev->xbutton.x, ev->xbutton.y, ev->xbutton.button);
857 break;
858 }
859 }
860
861 /* End of file */
862