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