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