1 /* 2 3 Copyright 1989, 1998 The Open Group 4 5 Permission to use, copy, modify, distribute, and sell this software and its 6 documentation for any purpose is hereby granted without fee, provided that 7 the above copyright notice appear in all copies and that both that 8 copyright notice and this permission notice appear in supporting 9 documentation. 10 11 The above copyright notice and this permission notice shall be included 12 in all copies or substantial portions of the Software. 13 14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 15 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 17 IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR 18 OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 19 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 20 OTHER DEALINGS IN THE SOFTWARE. 21 22 Except as contained in this notice, the name of The Open Group shall 23 not be used in advertising or otherwise to promote the sale, use or 24 other dealings in this Software without prior written authorization 25 from The Open Group. 26 27 */ 28 29 /* 30 * Author: Davor Matic, MIT X Consortium 31 */ 32 33 #ifdef HAVE_CONFIG_H 34 # include "config.h" 35 #endif 36 37 #include <stdio.h> 38 #include <stdlib.h> 39 #include <X11/Intrinsic.h> 40 #include <X11/StringDefs.h> 41 #include <X11/Xaw/Paned.h> 42 #include <X11/Xaw/Form.h> 43 #include <X11/Xaw/Box.h> 44 #include <X11/Xaw/Command.h> 45 #include <X11/Xaw/Toggle.h> 46 #include <X11/Xaw/MenuButton.h> 47 #include <X11/Xaw/SimpleMenu.h> 48 #include <X11/Xaw/SmeLine.h> 49 #include <X11/Xaw/SmeBSB.h> 50 #include "Bitmap.h" 51 52 #include <X11/bitmaps/xlogo16> 53 54 static const char *usage = "[-options ...] filename\n\ 55 \n\ 56 where options include all standard toolkit options plus:\n\ 57 -size WIDTHxHEIGHT\n\ 58 -sw dimension\n\ 59 -sh dimension\n\ 60 -gt dimension\n\ 61 -grid, +grid\n\ 62 -axes, +axes\n\ 63 -dashed, +dashed\n\ 64 -stippled, +stippled\n\ 65 -proportional, +proportional\n\ 66 -basename basename\n\ 67 -dashes filename\n\ 68 -stipple filename\n\ 69 -hl color\n\ 70 -fr color\n\ 71 -help\n\ 72 -version\n\ 73 \n\ 74 The default WIDTHxHEIGHT is 16x16.\n"; 75 76 #define __C(A,B,C,D) {(char *)A,(char *)B,C,(XPointer)D} 77 78 static XrmOptionDescRec options[] = { 79 __C( "-axes", "*bitmap.axes", XrmoptionNoArg, "True"), 80 __C( "+axes", "*bitmap.axes", XrmoptionNoArg, "False"), 81 __C( "-basename", "*bitmap.basename", XrmoptionSepArg, NULL), 82 __C( "-dashed", "*bitmap.dashed", XrmoptionNoArg, "True"), 83 __C( "+dashed", "*bitmap.dashed", XrmoptionNoArg, "False"), 84 __C( "-dashes", "*bitmap.dashes", XrmoptionSepArg, NULL), 85 __C( "-fr", "*bitmap.frame", XrmoptionSepArg, NULL), 86 __C( "-gt", "*bitmap.gridTolerance",XrmoptionSepArg, NULL), 87 __C( "-grid", "*bitmap.grid", XrmoptionNoArg, "True"), 88 __C( "+grid", "*bitmap.grid", XrmoptionNoArg, "False"), 89 __C( "-hl", "*bitmap.highlight", XrmoptionSepArg, NULL), 90 __C( "-proportional","*bitmap.proportional", XrmoptionNoArg, "True"), 91 __C( "+proportional","*bitmap.proportional", XrmoptionNoArg, "False"), 92 __C( "-size", "*bitmap.size", XrmoptionSepArg, NULL), 93 __C( "-sh", "*bitmap.squareHeight", XrmoptionSepArg, NULL), 94 __C( "-sw", "*bitmap.squareWidth", XrmoptionSepArg, NULL), 95 __C( "-stipple", "*bitmap.stipple", XrmoptionSepArg, NULL), 96 __C( "-stippled", "*bitmap.stippled", XrmoptionNoArg, "True"), 97 __C( "+stippled", "*bitmap.stippled", XrmoptionNoArg, "False"), 98 }; 99 100 #undef __C 101 102 typedef struct { 103 int id; 104 String name; 105 Boolean trap; 106 Widget widget; 107 } ButtonRec; 108 109 static ButtonRec file_menu[] = { 110 #define New 101 111 {New, "new", True}, 112 #define Load 102 113 {Load, "load", True}, 114 #define Insert 103 115 {Insert, "insert", True}, 116 #define Save 104 117 {Save, "save", True}, 118 #define SaveAs 105 119 {SaveAs, "saveAs", True}, 120 #define Resize 106 121 {Resize, "resize", True}, 122 #define Rescale 107 123 {Rescale, "rescale", True}, 124 #define Filename 108 125 {Filename, "filename", True}, 126 #define Basename 109 127 {Basename, "basename", True}, 128 #define Dummy -1 129 {Dummy, "line", False}, 130 #define Quit 110 131 {Quit, "quit", True}, 132 }; 133 134 static ButtonRec edit_menu[] = { 135 #define Image 201 136 {Image, "image", True}, 137 #define Grid 203 138 {Grid, "grid", True}, 139 #define Dashed 204 140 {Dashed, "dashed", True}, 141 #define Axes 205 142 {Axes, "axes", True}, 143 #define Stippled 206 144 {Stippled, "stippled", True}, 145 #define Proportional 207 146 {Proportional, "proportional", True}, 147 #define Zoom 208 148 {Zoom, "zoom", True}, 149 /* Dummy */ 150 {Dummy, "line", False}, 151 #define Cut 209 152 {Cut, "cut", True}, 153 #define Copy 210 154 {Copy, "copy", True}, 155 #define Paste 211 156 {Paste, "paste", True}, 157 }; 158 159 static ButtonRec buttons[] = { 160 /*#define Clear 1*/ 161 {Clear, "clear", False}, 162 /*#define Set 2*/ 163 {Set, "set", False}, 164 /*#define Invert 3*/ 165 {Invert, "invert", False}, 166 #define Mark 26 167 {Mark, "mark", True}, 168 #define Unmark 27 169 {Unmark, "unmark", False}, 170 #define CopyImm 4 171 {CopyImm, "copy", True}, 172 #define MoveImm 5 173 {MoveImm, "move", True}, 174 #define FlipHoriz 6 175 {FlipHoriz, "flipHoriz", False}, 176 #define Up 7 177 {Up, "up", False}, 178 #define FlipVert 8 179 {FlipVert, "flipVert", False}, 180 #define Left 9 181 {Left, "left", False}, 182 #define Fold 10 183 {Fold, "fold", False}, 184 #define Right 11 185 {Right, "right", False}, 186 #define RotateLeft 12 187 {RotateLeft, "rotateLeft", False}, 188 #define Down 13 189 {Down, "down", False}, 190 #define RotateRight 14 191 {RotateRight, "rotateRight", False}, 192 #define Point 15 193 {Point, "point", True}, 194 #define Curve 16 195 {Curve, "curve", True}, 196 #define Line 17 197 {Line, "line", True}, 198 #define Rectangle 18 199 {Rectangle, "rectangle", True}, 200 #define FilledRectangle 19 201 {FilledRectangle, "filledRectangle", True}, 202 #define Circle 20 203 {Circle, "circle", True}, 204 #define FilledCircle 21 205 {FilledCircle, "filledCircle", True}, 206 #define FloodFill 22 207 {FloodFill, "floodFill", True}, 208 #define SetHotSpot 23 209 {SetHotSpot, "setHotSpot", True}, 210 #define ClearHotSpot 24 211 {ClearHotSpot, "clearHotSpot", False}, 212 #define Undo 25 213 {Undo, "undo", False}, 214 }; 215 216 #include "Dialog.h" 217 218 static Widget 219 top_widget, 220 parent_widget, 221 formy_widget, 222 fileMenu_widget, 223 editMenu_widget, 224 status_widget, 225 pane_widget, 226 form_widget, 227 bitmap_widget, 228 image_shell, 229 box_widget, 230 normal_image_widget, 231 inverted_image_widget; 232 static Boolean image_visible = False; 233 static Pixmap check_mark; 234 static Dialog input_dialog, error_dialog, qsave_dialog; 235 static Time btime; 236 static char *filename = NULL, *base_name = NULL; 237 static char *format; 238 static char message[80]; 239 240 241 void FixMenu ( Widget w, XEvent *event, String *params, Cardinal *num_params ); 242 void SwitchImage ( void ); 243 void SwitchGrid( void ); 244 void SwitchDashed( void ); 245 void SwitchAxes( void ); 246 void SwitchStippled( void ); 247 void SwitchProportional( void ); 248 void SwitchZoom( void ); 249 void DoCut( void ); 250 void DoCopy( void ); 251 void DoPaste( void ); 252 void DoNew( void ); 253 void DoLoad( void ); 254 void DoInsert( void ); 255 void DoSave( void ); 256 void DoSaveAs( void ); 257 void DoResize( void ); 258 void DoRescale( void ); 259 void DoFilename( void ); 260 void DoBasename( void ); 261 void DoQuit ( Widget w, XEvent *event, String *params, Cardinal *num_params ); 262 263 static XtActionsRec actions_table[] = { 264 {"fix-menu", FixMenu}, 265 {"switch-image", (XtActionProc)SwitchImage}, 266 {"switch-grid", (XtActionProc)SwitchGrid}, 267 {"switch-dashed", (XtActionProc)SwitchDashed}, 268 {"switch-axes", (XtActionProc)SwitchAxes}, 269 {"switch-stippled", (XtActionProc)SwitchStippled}, 270 {"switch-proportional", (XtActionProc)SwitchProportional}, 271 {"switch-zoom", (XtActionProc)SwitchZoom}, 272 {"do-cut", (XtActionProc)DoCut}, 273 {"do-copy", (XtActionProc)DoCopy}, 274 {"do-paste", (XtActionProc)DoPaste}, 275 {"do-new", (XtActionProc)DoNew}, 276 {"do-load", (XtActionProc)DoLoad}, 277 {"do-insert", (XtActionProc)DoInsert}, 278 {"do-save", (XtActionProc)DoSave}, 279 {"do-save-as", (XtActionProc)DoSaveAs}, 280 {"do-resize", (XtActionProc)DoResize}, 281 {"do-rescale", (XtActionProc)DoRescale}, 282 {"do-filename", (XtActionProc)DoFilename}, 283 {"do-basename", (XtActionProc)DoBasename}, 284 {"do-quit", DoQuit} 285 }; 286 287 static Atom wm_delete_window; 288 289 static void 290 FixImage(void) 291 { 292 Pixmap old_image, image; 293 int n; 294 Arg wargs[2]; 295 296 if (!image_visible) return; 297 298 n=0; 299 XtSetArg(wargs[n], XtNbitmap, &old_image); n++; 300 XtGetValues(normal_image_widget, wargs, n); 301 302 303 image = BWGetUnzoomedPixmap(bitmap_widget); 304 305 n=0; 306 XtSetArg(wargs[n], XtNbitmap, image); n++; 307 XtSetValues(normal_image_widget, wargs, n); 308 XtSetValues(inverted_image_widget, wargs, n); 309 310 if (old_image != XtUnspecifiedPixmap) 311 XFreePixmap(XtDisplay(bitmap_widget), old_image); 312 } 313 314 static void 315 FixStatus(void) 316 { 317 int n; 318 Arg wargs[2]; 319 String str, label; 320 321 str = BWUnparseStatus(bitmap_widget); 322 323 n=0; 324 XtSetArg(wargs[n], XtNlabel, &label); n++; 325 XtGetValues(status_widget, wargs, n); 326 327 if (strcmp(str, label)) { 328 n = 0; 329 XtSetArg(wargs[n], XtNlabel, str); n++; 330 XtSetValues(status_widget, wargs, n); 331 } 332 333 /*XtFree(str); */ 334 } 335 336 static void 337 FixUp(void) 338 { 339 FixImage(); 340 FixStatus(); 341 } 342 343 static void 344 FixEntry(Widget w, int *id) 345 { 346 Time dummy = 0; 347 348 switch (*id) { 349 350 case Image: 351 XtVaSetValues(w, XtNleftBitmap, 352 image_visible ? check_mark : None,NULL); 353 return; 354 355 case Grid: 356 XtVaSetValues(w, XtNleftBitmap, 357 BWQueryGrid(bitmap_widget) ? check_mark : None,NULL); 358 return; 359 360 case Dashed: 361 XtVaSetValues(w, XtNleftBitmap, 362 BWQueryDashed(bitmap_widget) ? check_mark : None,NULL); 363 return; 364 365 case Axes: 366 XtVaSetValues(w, XtNleftBitmap, 367 BWQueryAxes(bitmap_widget) ? check_mark : None,NULL); 368 return; 369 370 case Stippled: 371 XtVaSetValues(w, XtNleftBitmap, 372 BWQueryStippled(bitmap_widget) ? check_mark : None,NULL); 373 return; 374 375 case Proportional: 376 XtVaSetValues(w, XtNleftBitmap, 377 BWQueryProportional(bitmap_widget) ? check_mark : None,NULL); 378 return; 379 380 case Zoom: 381 XtVaSetValues(w, XtNleftBitmap, 382 BWQueryZooming(bitmap_widget) ? check_mark : None,NULL); 383 return; 384 385 case Copy: 386 case Cut: 387 XtVaSetValues(w, XtNsensitive, BWQueryMarked(bitmap_widget),NULL ); 388 return; 389 390 case Paste: 391 XtVaSetValues(w, XtNsensitive, BWQuerySelection(bitmap_widget, dummy),NULL ); 392 return; 393 394 default: 395 return; 396 } 397 } 398 399 /* ARGSUSED */ 400 void FixMenu(Widget w, 401 XEvent *event, 402 String *params, 403 Cardinal *num_params) 404 { 405 btime = event->xbutton.time; 406 407 for (Cardinal i = 0; i < XtNumber(edit_menu); i++) 408 FixEntry(edit_menu[i].widget, &edit_menu[i].id); 409 } 410 411 static int zero = 0; 412 #define Plain (char *)&zero,sizeof(int) 413 /* ARGSUSED */ 414 static void 415 TheCallback(Widget w, /* not used */ 416 XtPointer clientData, 417 XtPointer callData) 418 { 419 int *id = (int *)clientData; 420 switch (*id) { 421 422 case New: 423 DoNew(); 424 break; 425 426 case Load: 427 DoLoad(); 428 break; 429 430 case Insert: 431 DoInsert(); 432 break; 433 434 case Save: 435 DoSave(); 436 break; 437 438 case SaveAs: 439 DoSaveAs(); 440 break; 441 442 case Resize: 443 DoResize(); 444 break; 445 446 case Rescale: 447 DoRescale(); 448 break; 449 450 case Filename: 451 DoFilename(); 452 break; 453 454 case Basename: 455 DoBasename(); 456 break; 457 458 case Image: 459 SwitchImage(); 460 break; 461 462 case Grid: 463 SwitchGrid(); 464 break; 465 466 case Dashed: 467 SwitchDashed(); 468 break; 469 470 case Axes: 471 SwitchAxes(); 472 break; 473 474 case Stippled: 475 SwitchStippled(); 476 break; 477 478 case Proportional: 479 SwitchProportional(); 480 break; 481 482 case Zoom: 483 SwitchZoom(); 484 break; 485 486 case Cut: 487 DoCut(); 488 break; 489 490 case Copy: 491 DoCopy(); 492 break; 493 494 case Paste: 495 DoPaste(); 496 break; 497 498 case Clear: 499 BWStoreToBuffer(bitmap_widget); 500 BWClear(bitmap_widget); 501 BWChangeNotify(bitmap_widget); 502 BWSetChanged(bitmap_widget); 503 break; 504 505 case Set: 506 BWStoreToBuffer(bitmap_widget); 507 BWSet(bitmap_widget); 508 BWChangeNotify(bitmap_widget); 509 BWSetChanged(bitmap_widget); 510 break; 511 512 case Invert: 513 BWStoreToBuffer(bitmap_widget); 514 BWInvert(bitmap_widget); 515 BWChangeNotify(bitmap_widget); 516 BWSetChanged(bitmap_widget); 517 break; 518 519 case Mark: 520 BWRemoveAllRequests(bitmap_widget); 521 BWEngageRequest(bitmap_widget, MarkRequest, True, Plain); 522 break; 523 524 case Unmark: 525 BWUnmark(bitmap_widget); 526 break; 527 528 case CopyImm: 529 BWRemoveAllRequests(bitmap_widget); 530 if (BWQueryMarked(bitmap_widget)) { 531 BWAddRequest(bitmap_widget, MarkRequest, False, Plain); 532 BWEngageRequest(bitmap_widget, CopyRequest, True, Plain); 533 } 534 else { 535 BWEngageRequest(bitmap_widget, MarkRequest, False, Plain); 536 BWAddRequest(bitmap_widget, CopyRequest, True, Plain); 537 } 538 break; 539 540 case MoveImm: 541 BWRemoveAllRequests(bitmap_widget); 542 if (BWQueryMarked(bitmap_widget)) { 543 BWAddRequest(bitmap_widget, MarkRequest, False, Plain); 544 BWEngageRequest(bitmap_widget, MoveRequest, True, Plain); 545 } 546 else { 547 BWEngageRequest(bitmap_widget, MarkRequest, False, Plain); 548 BWAddRequest(bitmap_widget, MoveRequest, True, Plain); 549 } 550 break; 551 552 case Up: 553 BWStoreToBuffer(bitmap_widget); 554 BWUp(bitmap_widget); 555 BWChangeNotify(bitmap_widget); 556 BWSetChanged(bitmap_widget); 557 break; 558 559 case Down: 560 BWStoreToBuffer(bitmap_widget); 561 BWDown(bitmap_widget); 562 BWChangeNotify(bitmap_widget); 563 BWSetChanged(bitmap_widget); 564 break; 565 566 case Left: 567 BWStoreToBuffer(bitmap_widget); 568 BWLeft(bitmap_widget); 569 BWChangeNotify(bitmap_widget); 570 BWSetChanged(bitmap_widget); 571 break; 572 573 case Right: 574 BWStoreToBuffer(bitmap_widget); 575 BWRight(bitmap_widget); 576 BWChangeNotify(bitmap_widget); 577 BWSetChanged(bitmap_widget); 578 break; 579 580 case Fold: 581 BWStoreToBuffer(bitmap_widget); 582 BWFold(bitmap_widget); 583 BWChangeNotify(bitmap_widget); 584 BWSetChanged(bitmap_widget); 585 break; 586 587 case FlipHoriz: 588 BWStoreToBuffer(bitmap_widget); 589 BWFlipHoriz(bitmap_widget); 590 BWChangeNotify(bitmap_widget); 591 BWSetChanged(bitmap_widget); 592 break; 593 594 case FlipVert: 595 BWStoreToBuffer(bitmap_widget); 596 BWFlipVert(bitmap_widget); 597 BWChangeNotify(bitmap_widget); 598 BWSetChanged(bitmap_widget); 599 break; 600 601 case RotateRight: 602 BWStoreToBuffer(bitmap_widget); 603 BWRotateRight(bitmap_widget); 604 BWChangeNotify(bitmap_widget); 605 BWSetChanged(bitmap_widget); 606 break; 607 608 case RotateLeft: 609 BWStoreToBuffer(bitmap_widget); 610 BWRotateLeft(bitmap_widget); 611 BWChangeNotify(bitmap_widget); 612 BWSetChanged(bitmap_widget); 613 break; 614 615 case Point: 616 BWRemoveAllRequests(bitmap_widget); 617 BWEngageRequest(bitmap_widget, PointRequest, True, Plain); 618 break; 619 620 case Curve: 621 BWRemoveAllRequests(bitmap_widget); 622 BWEngageRequest(bitmap_widget, CurveRequest, True, Plain); 623 break; 624 625 case Line: 626 BWRemoveAllRequests(bitmap_widget); 627 BWEngageRequest(bitmap_widget, LineRequest, True, Plain); 628 break; 629 630 case Rectangle: 631 BWRemoveAllRequests(bitmap_widget); 632 BWEngageRequest(bitmap_widget, RectangleRequest, True, Plain); 633 break; 634 635 case FilledRectangle: 636 BWRemoveAllRequests(bitmap_widget); 637 BWEngageRequest(bitmap_widget, FilledRectangleRequest, True, Plain); 638 break; 639 640 case Circle: 641 BWRemoveAllRequests(bitmap_widget); 642 BWEngageRequest(bitmap_widget, CircleRequest, True, Plain); 643 break; 644 645 case FilledCircle: 646 BWRemoveAllRequests(bitmap_widget); 647 BWEngageRequest(bitmap_widget, FilledCircleRequest, True, Plain); 648 break; 649 650 case FloodFill: 651 BWRemoveAllRequests(bitmap_widget); 652 BWEngageRequest(bitmap_widget, FloodFillRequest, True, Plain); 653 break; 654 655 case SetHotSpot: 656 BWRemoveAllRequests(bitmap_widget); 657 BWEngageRequest(bitmap_widget, HotSpotRequest, True, Plain); 658 break; 659 660 case ClearHotSpot: 661 BWStoreToBuffer(bitmap_widget); 662 BWClearHotSpot(bitmap_widget); 663 BWChangeNotify(bitmap_widget); 664 BWSetChanged(bitmap_widget); 665 break; 666 667 case Undo: 668 BWUndo(bitmap_widget); 669 BWChangeNotify(bitmap_widget); 670 BWSetChanged(bitmap_widget); 671 break; 672 673 case Quit: 674 DoQuit(bitmap_widget, NULL, NULL, NULL); 675 break; 676 } /* don't add anything below this line */ 677 } 678 679 /* ARGSUSED */ 680 681 void SwitchImage(void) 682 { 683 if (image_visible) { 684 XtPopdown(image_shell); 685 image_visible = False; 686 } 687 else { 688 Position image_x, image_y; 689 int n; 690 Arg wargs[3]; 691 692 XtTranslateCoords(bitmap_widget, 693 10, 10, &image_x, &image_y); 694 695 n = 0; 696 XtSetArg(wargs[n], XtNx, image_x); n++; 697 XtSetArg(wargs[n], XtNy, image_y); n++; 698 XtSetValues(image_shell, wargs, n); 699 700 image_visible = True; 701 702 FixImage(); 703 XtPopup(image_shell, XtGrabNone); 704 FixImage(); 705 } 706 } 707 708 void SwitchGrid(void) 709 { 710 BWSwitchGrid(bitmap_widget); 711 } 712 713 void SwitchDashed(void) 714 { 715 BWSwitchDashed(bitmap_widget); 716 } 717 718 void SwitchAxes(void) 719 { 720 BWSwitchAxes(bitmap_widget); 721 } 722 723 void SwitchStippled(void) 724 { 725 BWSwitchStippled(bitmap_widget); 726 } 727 728 void SwitchProportional(void) 729 { 730 BWSwitchProportional(bitmap_widget); 731 } 732 733 void SwitchZoom(void) 734 { 735 if (BWQueryZooming(bitmap_widget)) { 736 BWZoomOut(bitmap_widget); 737 BWChangeNotify(bitmap_widget); 738 } 739 else { 740 if (BWQueryMarked(bitmap_widget)) { 741 BWStoreToBuffer(bitmap_widget); 742 BWZoomMarked(bitmap_widget); 743 BWChangeNotify(bitmap_widget); 744 } 745 else { 746 BWEngageRequest(bitmap_widget, ZoomInRequest, False, Plain); 747 } 748 } 749 } 750 751 void DoCut(void) 752 { 753 BWStore(bitmap_widget); 754 BWStoreToBuffer(bitmap_widget); 755 BWClearMarked(bitmap_widget); 756 BWUnmark(bitmap_widget); 757 BWChangeNotify(bitmap_widget); 758 BWSetChanged(bitmap_widget); 759 } 760 761 void DoCopy(void) 762 { 763 BWStore(bitmap_widget); 764 BWUnmark(bitmap_widget); 765 } 766 767 void DoPaste(void) 768 { 769 BWRequestSelection(bitmap_widget, btime, TRUE); 770 BWEngageRequest(bitmap_widget, RestoreRequest, False, Plain); 771 } 772 773 void DoNew(void) 774 { 775 BWGetFilename(bitmap_widget, &filename); 776 if (PopupDialog(input_dialog, "New file:", 777 filename, &filename, XtGrabExclusive) == Okay) { 778 BWChangeFilename(bitmap_widget, filename); 779 BWChangeBasename(bitmap_widget, filename); 780 BWStoreToBuffer(bitmap_widget); 781 BWClear(bitmap_widget); 782 BWClearHotSpot(bitmap_widget); 783 BWChangeNotify(bitmap_widget); 784 BWClearChanged(bitmap_widget); 785 BWUnmark(bitmap_widget); 786 FixStatus(); 787 } 788 } 789 790 void DoLoad(void) 791 { 792 if (BWQueryChanged(bitmap_widget)) { 793 BWGetFilename(bitmap_widget, &filename); 794 RetryLoadSave: 795 switch (PopupDialog(qsave_dialog, "Save file before loading?", 796 filename, &filename, XtGrabExclusive)) { 797 case Yes: 798 if (BWWriteFile(bitmap_widget, filename, NULL) 799 != BitmapSuccess) { 800 snprintf(message, sizeof(message), "Can't write file: %s", filename); 801 if (PopupDialog(error_dialog, message, 802 NULL, NULL, XtGrabExclusive) == Retry) 803 goto RetryLoadSave; 804 } 805 break; 806 807 case Cancel: 808 return; 809 } 810 } 811 BWGetFilepath(bitmap_widget, &filename); 812 RetryLoad: 813 if (PopupDialog(input_dialog, "Load file:", 814 filename, &filename, XtGrabExclusive) == Okay) { 815 if (BWReadFile(bitmap_widget, filename, NULL) != BitmapSuccess) { 816 snprintf(message, sizeof(message), "Can't read file: %s", filename); 817 if (PopupDialog(error_dialog, message, 818 NULL, NULL, XtGrabExclusive) == Retry) 819 goto RetryLoad; 820 } 821 else { 822 BWChangeNotify(bitmap_widget); 823 BWClearChanged(bitmap_widget); 824 FixStatus(); 825 } 826 } 827 } 828 829 void DoInsert(void) 830 { 831 BWGetFilepath(bitmap_widget, &filename); 832 RetryInsert: 833 if (PopupDialog(input_dialog, "Insert file:", 834 filename, &filename, XtGrabExclusive) == Okay) { 835 if (BWStoreFile(bitmap_widget, filename, NULL) != BitmapSuccess) { 836 snprintf(message, sizeof(message), "Can't read file: %s", filename); 837 if (PopupDialog(error_dialog, message, 838 NULL, NULL, XtGrabExclusive) == Retry) 839 goto RetryInsert; 840 } 841 else { 842 BWEngageRequest(bitmap_widget, RestoreRequest, False, Plain); 843 } 844 } 845 } 846 847 void DoSave(void) 848 { 849 BWGetFilename(bitmap_widget, &filename); 850 if (!strcmp(filename, "")) 851 DoSaveAs(); 852 else if (BWWriteFile(bitmap_widget, NULL, NULL) != BitmapSuccess) { 853 snprintf(message, sizeof(message), "Can't write file: %s", filename); 854 if (PopupDialog(error_dialog, message, 855 NULL, NULL, XtGrabExclusive) == Retry) 856 DoSaveAs(); 857 } 858 else { 859 BWClearChanged(bitmap_widget); 860 } 861 } 862 863 void DoSaveAs(void) 864 { 865 BWGetFilename(bitmap_widget, &filename); 866 RetrySave: 867 if (PopupDialog(input_dialog, "Save file:", 868 filename, &filename, XtGrabExclusive) == Okay) { 869 if (BWWriteFile(bitmap_widget, filename, NULL) != BitmapSuccess) { 870 snprintf(message, sizeof(message), "Can't write file: %s", filename); 871 if (PopupDialog(error_dialog, message, 872 NULL, NULL, XtGrabExclusive) == Retry) 873 goto RetrySave; 874 } 875 else { 876 BWClearChanged(bitmap_widget); 877 FixStatus(); 878 } 879 } 880 } 881 882 void DoResize(void) 883 { 884 Dimension width, height; 885 format = (char *)""; 886 RetryResize: 887 if (PopupDialog(input_dialog, "Resize to WIDTHxHEIGHT:", 888 format, &format, XtGrabExclusive) == Okay) { 889 if (BWParseSize(format, &width, &height)) { 890 BWResize(bitmap_widget, width, height); 891 BWChangeNotify(bitmap_widget); 892 BWSetChanged(bitmap_widget); 893 FixStatus(); 894 } 895 else { 896 snprintf(message, sizeof(message), "Wrong format: %s", format); 897 if (PopupDialog(error_dialog, message, 898 NULL, NULL, XtGrabExclusive) == Retry) 899 goto RetryResize; 900 } 901 } 902 } 903 904 void DoRescale(void) 905 { 906 Dimension width, height; 907 908 format = (char *)""; 909 RetryRescale: 910 if (PopupDialog(input_dialog, "Rescale to WIDTHxHEIGHT:", 911 format, &format, XtGrabExclusive) == Okay) { 912 if (BWParseSize(format, &width, &height)) { 913 BWRescale(bitmap_widget, width, height); 914 BWChangeNotify(bitmap_widget); 915 BWSetChanged(bitmap_widget); 916 FixStatus(); 917 } 918 else { 919 snprintf(message, sizeof(message), "Wrong format: %s", format); 920 if (PopupDialog(error_dialog, message, 921 NULL, NULL, XtGrabExclusive) == Retry) 922 goto RetryRescale; 923 } 924 } 925 } 926 927 void DoFilename(void) 928 { 929 BWGetFilename(bitmap_widget, &filename); 930 if (PopupDialog(input_dialog, "Change filename:", 931 filename, &filename, XtGrabExclusive) == Okay) { 932 BWChangeFilename(bitmap_widget, filename); 933 FixStatus(); 934 } 935 } 936 937 void DoBasename(void) 938 { 939 BWGetBasename(bitmap_widget, &base_name); 940 if (PopupDialog(input_dialog, "Change basename:", 941 base_name, &base_name, XtGrabExclusive) == Okay) { 942 BWChangeBasename(bitmap_widget, base_name); 943 FixStatus(); 944 } 945 } 946 947 void DoQuit(Widget w, XEvent *event, String *params, Cardinal *num_params) 948 { 949 if (BWQueryChanged(bitmap_widget)) { 950 BWGetFilename(bitmap_widget, &filename); 951 RetryQuit: 952 switch (PopupDialog(qsave_dialog, "Save file before quitting?", 953 filename, &filename, XtGrabExclusive)) { 954 case Yes: 955 if (BWWriteFile(bitmap_widget, filename, NULL) 956 != BitmapSuccess) { 957 snprintf(message, sizeof(message), "Can't write file: %s", filename); 958 if (PopupDialog(error_dialog, message, 959 NULL, NULL, XtGrabExclusive) == Retry) 960 goto RetryQuit; 961 else return; 962 } 963 break; 964 965 case Cancel: 966 return; 967 } 968 } 969 exit(0); 970 } 971 972 int main(int argc, char *argv[]) 973 { 974 Cardinal i, n; 975 Arg wargs[2]; 976 Widget w; 977 Widget radio_group = NULL; 978 XtPointer radio_data = NULL; 979 const char *myfilename = NULL; 980 981 /* Handle args that don't require opening a display */ 982 for (int a = 1; a < argc; a++) { 983 const char *argn = argv[a]; 984 /* accept single or double dash for -help & -version */ 985 if (argn[0] == '-' && argn[1] == '-') { 986 argn++; 987 } 988 if (strcmp(argn, "-help") == 0) { 989 fprintf(stderr, "usage: %s %s", argv[0], usage); 990 exit(0); 991 } 992 if (strcmp(argn, "-version") == 0) { 993 puts(PACKAGE_STRING); 994 exit(0); 995 } 996 } 997 998 top_widget = XtInitialize(NULL, "Bitmap", 999 options, XtNumber(options), &argc, argv); 1000 1001 if (argc > 1) { 1002 if ((argv[argc - 1][0] != '-') && (argv[argc - 1][0] != '+')) { 1003 myfilename = argv[--argc]; 1004 } 1005 if (argc > 1) { 1006 fputs("Unknown argument(s):", stderr); 1007 for (int a = 1; a < argc; a++) { 1008 fprintf(stderr, " %s", argv[a]); 1009 } 1010 fputs("\n\n", stderr); 1011 fprintf(stderr, "usage: %s %s", argv[0], usage); 1012 exit (1); 1013 } 1014 } 1015 1016 check_mark = XCreateBitmapFromData(XtDisplay(top_widget), 1017 RootWindowOfScreen(XtScreen(top_widget)), 1018 (char *) xlogo16_bits, 1019 xlogo16_width, 1020 xlogo16_height); 1021 1022 XtAddActions(actions_table, XtNumber(actions_table)); 1023 XtOverrideTranslations 1024 (top_widget, 1025 XtParseTranslationTable("<Message>WM_PROTOCOLS: do-quit()")); 1026 1027 parent_widget = XtCreateManagedWidget("parent", panedWidgetClass, 1028 top_widget, NULL, 0); 1029 1030 formy_widget = XtCreateManagedWidget("formy", formWidgetClass, 1031 parent_widget, NULL, 0); 1032 1033 fileMenu_widget = XtCreatePopupShell("fileMenu", 1034 simpleMenuWidgetClass, 1035 formy_widget, NULL, 0); 1036 1037 (void) XtCreateManagedWidget("fileButton", 1038 menuButtonWidgetClass, 1039 formy_widget, NULL, 0); 1040 1041 for (i = 0; i < XtNumber(file_menu); i++) { 1042 w = XtCreateManagedWidget(file_menu[i].name, 1043 (file_menu[i].trap ? 1044 smeBSBObjectClass : smeLineObjectClass), 1045 fileMenu_widget, NULL, 0), 1046 XtAddCallback(w, 1047 XtNcallback, 1048 TheCallback, 1049 (XtPointer)&file_menu[i].id); 1050 1051 file_menu[i].widget = w; 1052 } 1053 1054 editMenu_widget = XtCreatePopupShell("editMenu", 1055 simpleMenuWidgetClass, 1056 formy_widget, NULL, 0); 1057 1058 (void) XtCreateManagedWidget("editButton", 1059 menuButtonWidgetClass, 1060 formy_widget, NULL, 0); 1061 1062 for (i = 0; i < XtNumber(edit_menu); i++) { 1063 w = XtCreateManagedWidget(edit_menu[i].name, 1064 (edit_menu[i].trap ? 1065 smeBSBObjectClass : smeLineObjectClass), 1066 editMenu_widget, NULL, 0), 1067 XtAddCallback(w, 1068 XtNcallback, 1069 TheCallback, 1070 (XtPointer)&edit_menu[i].id); 1071 1072 edit_menu[i].widget = w; 1073 } 1074 1075 status_widget = XtCreateManagedWidget("status", labelWidgetClass, 1076 formy_widget, NULL, 0); 1077 1078 pane_widget = XtCreateManagedWidget("pane", panedWidgetClass, 1079 parent_widget, NULL, 0); 1080 1081 form_widget = XtCreateManagedWidget("form", formWidgetClass, 1082 pane_widget, NULL, 0); 1083 1084 for (i = 0; i < XtNumber(buttons); i++) { 1085 w = XtCreateManagedWidget(buttons[i].name, 1086 (buttons[i].trap ? 1087 toggleWidgetClass : commandWidgetClass), 1088 form_widget, NULL, 0); 1089 1090 XtAddCallback(w, 1091 XtNcallback, 1092 TheCallback, 1093 (XtPointer)&buttons[i].id); 1094 1095 buttons[i].widget = w; 1096 1097 if (buttons[i].id == Point) { 1098 radio_group = buttons[i].widget; 1099 radio_data = (char *)buttons[i].name; 1100 } 1101 } 1102 bitmap_widget = XtCreateManagedWidget("bitmap", bitmapWidgetClass, 1103 pane_widget, NULL, 0); 1104 XtRealizeWidget(top_widget); 1105 if (myfilename != NULL) 1106 BWReadFile(bitmap_widget, myfilename, NULL); 1107 1108 wm_delete_window = XInternAtom(XtDisplay(top_widget), "WM_DELETE_WINDOW", 1109 False); 1110 (void) XSetWMProtocols (XtDisplay(top_widget), XtWindow(top_widget), 1111 &wm_delete_window, 1); 1112 1113 1114 image_shell = XtCreatePopupShell("image", transientShellWidgetClass, 1115 top_widget, NULL, 0); 1116 1117 box_widget = XtCreateManagedWidget("box", boxWidgetClass, 1118 image_shell, NULL, 0); 1119 1120 normal_image_widget = XtCreateManagedWidget("normalImage", 1121 labelWidgetClass, 1122 box_widget, NULL, 0); 1123 1124 inverted_image_widget = XtCreateManagedWidget("invertedImage", 1125 labelWidgetClass, 1126 box_widget, NULL, 0); 1127 1128 n=0; 1129 XtSetArg(wargs[n], XtNbitmap, BWGetUnzoomedPixmap(bitmap_widget)); n++; 1130 XtSetValues(normal_image_widget, wargs, n); 1131 XtSetValues(inverted_image_widget, wargs, n); 1132 1133 XtRealizeWidget(image_shell); 1134 1135 BWNotify(bitmap_widget, (XtActionProc)FixUp); 1136 1137 FixStatus(); 1138 1139 input_dialog = CreateDialog(top_widget, "input", Okay | Cancel); 1140 error_dialog = CreateDialog(top_widget, "error", Abort | Retry); 1141 qsave_dialog = CreateDialog(top_widget, "qsave", Yes | No | Cancel); 1142 1143 XawToggleSetCurrent(radio_group, radio_data); 1144 BWEngageRequest(bitmap_widget, PointRequest, True, Plain); 1145 1146 XtMainLoop(); 1147 exit(0); 1148 } 1149