42 #include "magick/studio.h"
43 #include "magick/artifact.h"
44 #include "magick/attribute.h"
45 #include "magick/blob.h"
46 #include "magick/cache.h"
47 #include "magick/channel.h"
48 #include "magick/client.h"
49 #include "magick/color.h"
50 #include "magick/colorspace.h"
51 #include "magick/composite.h"
52 #include "magick/constitute.h"
53 #include "magick/decorate.h"
54 #include "magick/delegate.h"
55 #include "magick/display.h"
56 #include "magick/display-private.h"
57 #include "magick/distort.h"
58 #include "magick/draw.h"
59 #include "magick/effect.h"
60 #include "magick/enhance.h"
61 #include "magick/exception.h"
62 #include "magick/exception-private.h"
63 #include "magick/fx.h"
64 #include "magick/geometry.h"
65 #include "magick/image.h"
66 #include "magick/image-private.h"
67 #include "magick/list.h"
68 #include "magick/locale-private.h"
69 #include "magick/log.h"
70 #include "magick/magick.h"
71 #include "magick/memory_.h"
72 #include "magick/monitor.h"
73 #include "magick/monitor-private.h"
74 #include "magick/montage.h"
75 #include "magick/nt-base-private.h"
76 #include "magick/option.h"
77 #include "magick/paint.h"
78 #include "magick/pixel.h"
79 #include "magick/pixel-private.h"
80 #include "magick/property.h"
81 #include "magick/quantum.h"
82 #include "magick/resize.h"
83 #include "magick/resource_.h"
84 #include "magick/shear.h"
85 #include "magick/segment.h"
86 #include "magick/statistic.h"
87 #include "magick/string_.h"
88 #include "magick/string-private.h"
89 #include "magick/timer-private.h"
90 #include "magick/transform.h"
91 #include "magick/threshold.h"
92 #include "magick/utility.h"
93 #include "magick/utility-private.h"
94 #include "magick/version.h"
95 #include "magick/visual-effects.h"
96 #include "magick/widget.h"
97 #include "magick/xwindow-private.h"
99 #if defined(MAGICKCORE_X11_DELEGATE)
103 #define MaxColors MagickMin((ssize_t) windows->visual_info->colormap_size,256L)
108 static const unsigned char
111 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55
115 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
119 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
126 ImageAnnotateHelp[] =
128 "In annotate mode, the Command widget has these options:\n"
178 "Choose a font name from the Font Name sub-menu. Additional\n"
179 "font names can be specified with the font browser. You can\n"
180 "change the menu names by setting the X resources font1\n"
183 "Choose a font color from the Font Color sub-menu.\n"
184 "Additional font colors can be specified with the color\n"
185 "browser. You can change the menu colors by setting the X\n"
186 "resources pen1 through pen9.\n"
188 "If you select the color browser and press Grab, you can\n"
189 "choose the font color by moving the pointer to the desired\n"
190 "color on the screen and press any button.\n"
192 "If you choose to rotate the text, choose Rotate Text from the\n"
193 "menu and select an angle. Typically you will only want to\n"
194 "rotate one line of text at a time. Depending on the angle you\n"
195 "choose, subsequent lines may end up overwriting each other.\n"
197 "Choosing a font and its color is optional. The default font\n"
198 "is fixed and the default color is black. However, you must\n"
199 "choose a location to begin entering text and press button 1.\n"
200 "An underscore character will appear at the location of the\n"
201 "pointer. The cursor changes to a pencil to indicate you are\n"
202 "in text mode. To exit immediately, press Dismiss.\n"
204 "In text mode, any key presses will display the character at\n"
205 "the location of the underscore and advance the underscore\n"
206 "cursor. Enter your text and once completed press Apply to\n"
207 "finish your image annotation. To correct errors press BACK\n"
208 "SPACE. To delete an entire line of text, press DELETE. Any\n"
209 "text that exceeds the boundaries of the image window is\n"
210 "automagically continued onto the next line.\n"
212 "The actual color you request for the font is saved in the\n"
213 "image. However, the color that appears in your image window\n"
214 "may be different. For example, on a monochrome screen the\n"
215 "text will appear black or white even if you choose the color\n"
216 "red as the font color. However, the image saved to a file\n"
217 "with -write is written with red lettering. To assure the\n"
218 "correct color text in the final image, any PseudoClass image\n"
219 "is promoted to DirectClass (see miff(5)). To force a\n"
220 "PseudoClass image to remain PseudoClass, use -colors.\n"
224 "In chop mode, the Command widget has these options:\n"
232 "If the you choose the horizontal direction (this the\n"
233 "default), the area of the image between the two horizontal\n"
234 "endpoints of the chop line is removed. Otherwise, the area\n"
235 "of the image between the two vertical endpoints of the chop\n"
238 "Select a location within the image window to begin your chop,\n"
239 "press and hold any button. Next, move the pointer to\n"
240 "another location in the image. As you move a line will\n"
241 "connect the initial location and the pointer. When you\n"
242 "release the button, the area within the image to chop is\n"
243 "determined by which direction you choose from the Command\n"
246 "To cancel the image chopping, move the pointer back to the\n"
247 "starting point of the line and release the button.\n"
249 ImageColorEditHelp[] =
251 "In color edit mode, the Command widget has these options:\n"
292 "Choose a color editing method from the Method sub-menu\n"
293 "of the Command widget. The point method recolors any pixel\n"
294 "selected with the pointer until the button is released. The\n"
295 "replace method recolors any pixel that matches the color of\n"
296 "the pixel you select with a button press. Floodfill recolors\n"
297 "any pixel that matches the color of the pixel you select with\n"
298 "a button press and is a neighbor. Whereas filltoborder recolors\n"
299 "any neighbor pixel that is not the border color. Finally reset\n"
300 "changes the entire image to the designated color.\n"
302 "Next, choose a pixel color from the Pixel Color sub-menu.\n"
303 "Additional pixel colors can be specified with the color\n"
304 "browser. You can change the menu colors by setting the X\n"
305 "resources pen1 through pen9.\n"
307 "Now press button 1 to select a pixel within the image window\n"
308 "to change its color. Additional pixels may be recolored as\n"
309 "prescribed by the method you choose.\n"
311 "If the Magnify widget is mapped, it can be helpful in positioning\n"
312 "your pointer within the image (refer to button 2).\n"
314 "The actual color you request for the pixels is saved in the\n"
315 "image. However, the color that appears in your image window\n"
316 "may be different. For example, on a monochrome screen the\n"
317 "pixel will appear black or white even if you choose the\n"
318 "color red as the pixel color. However, the image saved to a\n"
319 "file with -write is written with red pixels. To assure the\n"
320 "correct color text in the final image, any PseudoClass image\n"
321 "is promoted to DirectClass (see miff(5)). To force a\n"
322 "PseudoClass image to remain PseudoClass, use -colors.\n"
324 ImageCompositeHelp[] =
326 "First a widget window is displayed requesting you to enter an\n"
327 "image name. Press Composite, Grab or type a file name.\n"
328 "Press Cancel if you choose not to create a composite image.\n"
329 "When you choose Grab, move the pointer to the desired window\n"
330 "and press any button.\n"
332 "If the Composite image does not have any matte information,\n"
333 "you are informed and the file browser is displayed again.\n"
334 "Enter the name of a mask image. The image is typically\n"
335 "grayscale and the same size as the composite image. If the\n"
336 "image is not grayscale, it is converted to grayscale and the\n"
337 "resulting intensities are used as matte information.\n"
339 "A small window appears showing the location of the cursor in\n"
340 "the image window. You are now in composite mode. To exit\n"
341 "immediately, press Dismiss. In composite mode, the Command\n"
342 "widget has these options:\n"
368 "Choose a composite operation from the Operators sub-menu of\n"
369 "the Command widget. How each operator behaves is described\n"
370 "below. Image window is the image currently displayed on\n"
371 "your X server and image is the image obtained with the File\n"
374 "Over The result is the union of the two image shapes,\n"
375 " with image obscuring image window in the region of\n"
378 "In The result is simply image cut by the shape of\n"
379 " image window. None of the image data of image\n"
380 " window is in the result.\n"
382 "Out The resulting image is image with the shape of\n"
383 " image window cut out.\n"
385 "Atop The result is the same shape as the image window,\n"
386 " with image obscuring image window where the image\n"
387 " shapes overlap. Note this differs from over\n"
388 " because the portion of image outside image window's\n"
389 " shape does not appear in the result.\n"
391 "Xor The result is the image data from both image and\n"
392 " image window that is outside the overlap region.\n"
393 " The overlap region is blank.\n"
395 "Plus The result is just the sum of the image data.\n"
396 " Output values are cropped to QuantumRange (no overflow).\n"
398 "Minus The result of image - image window, with underflow\n"
399 " cropped to zero.\n"
401 "Add The result of image + image window, with overflow\n"
402 " wrapping around (mod 256).\n"
404 "Subtract The result of image - image window, with underflow\n"
405 " wrapping around (mod 256). The add and subtract\n"
406 " operators can be used to perform reversible\n"
407 " transformations.\n"
410 " The result of abs(image - image window). This\n"
411 " useful for comparing two very similar images.\n"
414 " The result of image * image window. This\n"
415 " useful for the creation of drop-shadows.\n"
417 "Bumpmap The result of surface normals from image * image\n"
420 "Copy The resulting image is image window replaced with\n"
421 " image. Here the matte information is ignored.\n"
423 "CopyRed The red layer of the image window is replace with\n"
424 " the red layer of the image. The other layers are\n"
428 " The green layer of the image window is replace with\n"
429 " the green layer of the image. The other layers are\n"
432 "CopyBlue The blue layer of the image window is replace with\n"
433 " the blue layer of the image. The other layers are\n"
437 " The matte layer of the image window is replace with\n"
438 " the matte layer of the image. The other layers are\n"
441 "The image compositor requires a matte, or alpha channel in\n"
442 "the image for some operations. This extra channel usually\n"
443 "defines a mask which represents a sort of a cookie-cutter\n"
444 "for the image. This the case when matte is opaque (full\n"
445 "coverage) for pixels inside the shape, zero outside, and\n"
446 "between 0 and QuantumRange on the boundary. If image does not\n"
447 "have a matte channel, it is initialized with 0 for any pixel\n"
448 "matching in color to pixel location (0,0), otherwise QuantumRange.\n"
450 "If you choose Dissolve, the composite operator becomes Over. The\n"
451 "image matte channel percent transparency is initialized to factor.\n"
452 "The image window is initialized to (100-factor). Where factor is the\n"
453 "value you specify in the Dialog widget.\n"
455 "Displace shifts the image pixels as defined by a displacement\n"
456 "map. With this option, image is used as a displacement map.\n"
457 "Black, within the displacement map, is a maximum positive\n"
458 "displacement. White is a maximum negative displacement and\n"
459 "middle gray is neutral. The displacement is scaled to determine\n"
460 "the pixel shift. By default, the displacement applies in both the\n"
461 "horizontal and vertical directions. However, if you specify a mask,\n"
462 "image is the horizontal X displacement and mask the vertical Y\n"
465 "Note that matte information for image window is not retained\n"
466 "for colormapped X server visuals (e.g. StaticColor,\n"
467 "StaticColor, GrayScale, PseudoColor). Correct compositing\n"
468 "behavior may require a TrueColor or DirectColor visual or a\n"
469 "Standard Colormap.\n"
471 "Choosing a composite operator is optional. The default\n"
472 "operator is replace. However, you must choose a location to\n"
473 "composite your image and press button 1. Press and hold the\n"
474 "button before releasing and an outline of the image will\n"
475 "appear to help you identify your location.\n"
477 "The actual colors of the composite image is saved. However,\n"
478 "the color that appears in image window may be different.\n"
479 "For example, on a monochrome screen image window will appear\n"
480 "black or white even though your composited image may have\n"
481 "many colors. If the image is saved to a file it is written\n"
482 "with the correct colors. To assure the correct colors are\n"
483 "saved in the final image, any PseudoClass image is promoted\n"
484 "to DirectClass (see miff(5)). To force a PseudoClass image\n"
485 "to remain PseudoClass, use -colors.\n"
489 "In cut mode, the Command widget has these options:\n"
494 "To define a cut region, press button 1 and drag. The\n"
495 "cut region is defined by a highlighted rectangle that\n"
496 "expands or contracts as it follows the pointer. Once you\n"
497 "are satisfied with the cut region, release the button.\n"
498 "You are now in rectify mode. In rectify mode, the Command\n"
499 "widget has these options:\n"
505 "You can make adjustments by moving the pointer to one of the\n"
506 "cut rectangle corners, pressing a button, and dragging.\n"
507 "Finally, press Cut to commit your copy region. To\n"
508 "exit without cutting the image, press Dismiss.\n"
512 "In copy mode, the Command widget has these options:\n"
517 "To define a copy region, press button 1 and drag. The\n"
518 "copy region is defined by a highlighted rectangle that\n"
519 "expands or contracts as it follows the pointer. Once you\n"
520 "are satisfied with the copy region, release the button.\n"
521 "You are now in rectify mode. In rectify mode, the Command\n"
522 "widget has these options:\n"
528 "You can make adjustments by moving the pointer to one of the\n"
529 "copy rectangle corners, pressing a button, and dragging.\n"
530 "Finally, press Copy to commit your copy region. To\n"
531 "exit without copying the image, press Dismiss.\n"
535 "In crop mode, the Command widget has these options:\n"
540 "To define a cropping region, press button 1 and drag. The\n"
541 "cropping region is defined by a highlighted rectangle that\n"
542 "expands or contracts as it follows the pointer. Once you\n"
543 "are satisfied with the cropping region, release the button.\n"
544 "You are now in rectify mode. In rectify mode, the Command\n"
545 "widget has these options:\n"
551 "You can make adjustments by moving the pointer to one of the\n"
552 "cropping rectangle corners, pressing a button, and dragging.\n"
553 "Finally, press Crop to commit your cropping region. To\n"
554 "exit without cropping the image, press Dismiss.\n"
558 "The cursor changes to a crosshair to indicate you are in\n"
559 "draw mode. To exit immediately, press Dismiss. In draw mode,\n"
560 "the Command widget has these options:\n"
605 "Choose a drawing primitive from the Element sub-menu.\n"
607 "Choose a color from the Color sub-menu. Additional\n"
608 "colors can be specified with the color browser.\n"
610 "If you choose the color browser and press Grab, you can\n"
611 "select the color by moving the pointer to the desired\n"
612 "color on the screen and press any button. The transparent\n"
613 "color updates the image matte channel and is useful for\n"
614 "image compositing.\n"
616 "Choose a stipple, if appropriate, from the Stipple sub-menu.\n"
617 "Additional stipples can be specified with the file browser.\n"
618 "Stipples obtained from the file browser must be on disk in the\n"
619 "X11 bitmap format.\n"
621 "Choose a width, if appropriate, from the Width sub-menu. To\n"
622 "choose a specific width select the Dialog widget.\n"
624 "Choose a point in the Image window and press button 1 and\n"
625 "hold. Next, move the pointer to another location in the\n"
626 "image. As you move, a line connects the initial location and\n"
627 "the pointer. When you release the button, the image is\n"
628 "updated with the primitive you just drew. For polygons, the\n"
629 "image is updated when you press and release the button without\n"
630 "moving the pointer.\n"
632 "To cancel image drawing, move the pointer back to the\n"
633 "starting point of the line and release the button.\n"
638 " The effects of each button press is described below. Three\n"
639 " buttons are required. If you have a two button mouse,\n"
640 " button 1 and 3 are returned. Press ALT and button 3 to\n"
641 " simulate button 2.\n"
643 " 1 Press this button to map or unmap the Command widget.\n"
645 " 2 Press and drag to define a region of the image to\n"
648 " 3 Press and drag to choose from a select set of commands.\n"
649 " This button behaves differently if the image being\n"
650 " displayed is a visual image directory. Here, choose a\n"
651 " particular tile of the directory and press this button and\n"
652 " drag to select a command from a pop-up menu. Choose from\n"
653 " these menu items:\n"
661 " If you choose Open, the image represented by the tile is\n"
662 " displayed. To return to the visual image directory, choose\n"
663 " Next from the Command widget. Next and Former moves to the\n"
664 " next or former image respectively. Choose Delete to delete\n"
665 " a particular image tile. Finally, choose Update to\n"
666 " synchronize all the image tiles with their respective\n"
670 " The Command widget lists a number of sub-menus and commands.\n"
682 " Visual Directory...\n"
716 " Contrast Stretch...\n"
717 " Sigmoidal Contrast...\n"
745 " Charcoal Drawing...\n"
756 " Region of Interest...\n"
768 " Browse Documentation\n"
771 " Menu items with a indented triangle have a sub-menu. They\n"
772 " are represented above as the indented items. To access a\n"
773 " sub-menu item, move the pointer to the appropriate menu and\n"
774 " press a button and drag. When you find the desired sub-menu\n"
775 " item, release the button and the command is executed. Move\n"
776 " the pointer away from the sub-menu if you decide not to\n"
777 " execute a particular command.\n"
779 "KEYBOARD ACCELERATORS\n"
780 " Accelerators are one or two key presses that effect a\n"
781 " particular command. The keyboard accelerators that\n"
782 " display(1) understands is:\n"
784 " Ctl+O Press to open an image from a file.\n"
786 " space Press to display the next image.\n"
788 " If the image is a multi-paged document such as a Postscript\n"
789 " document, you can skip ahead several pages by preceding\n"
790 " this command with a number. For example to display the\n"
791 " third page beyond the current page, press 3<space>.\n"
793 " backspace Press to display the former image.\n"
795 " If the image is a multi-paged document such as a Postscript\n"
796 " document, you can skip behind several pages by preceding\n"
797 " this command with a number. For example to display the\n"
798 " third page preceding the current page, press 3<backspace>.\n"
800 " Ctl+S Press to write the image to a file.\n"
802 " Ctl+P Press to print the image to a Postscript printer.\n"
804 " Ctl+D Press to delete an image file.\n"
806 " Ctl+N Press to create a blank canvas.\n"
808 " Ctl+Q Press to discard all images and exit program.\n"
810 " Ctl+Z Press to undo last image transformation.\n"
812 " Ctl+R Press to redo last image transformation.\n"
814 " Ctl+X Press to cut a region of the image.\n"
816 " Ctl+C Press to copy a region of the image.\n"
818 " Ctl+V Press to paste a region to the image.\n"
820 " < Press to half the image size.\n"
822 " - Press to return to the original image size.\n"
824 " > Press to double the image size.\n"
826 " % Press to resize the image to a width and height you\n"
829 "Cmd-A Press to make any image transformations permanent."
831 " By default, any image size transformations are applied\n"
832 " to the original image to create the image displayed on\n"
833 " the X server. However, the transformations are not\n"
834 " permanent (i.e. the original image does not change\n"
835 " size only the X image does). For example, if you\n"
836 " press > the X image will appear to double in size,\n"
837 " but the original image will in fact remain the same size.\n"
838 " To force the original image to double in size, press >\n"
839 " followed by Cmd-A.\n"
841 " @ Press to refresh the image window.\n"
843 " C Press to cut out a rectangular region of the image.\n"
845 " [ Press to chop the image.\n"
847 " H Press to flop image in the horizontal direction.\n"
849 " V Press to flip image in the vertical direction.\n"
851 " / Press to rotate the image 90 degrees clockwise.\n"
853 " \\ Press to rotate the image 90 degrees counter-clockwise.\n"
855 " * Press to rotate the image the number of degrees you\n"
858 " S Press to shear the image the number of degrees you\n"
861 " R Press to roll the image.\n"
863 " T Press to trim the image edges.\n"
865 " Shft-H Press to vary the image hue.\n"
867 " Shft-S Press to vary the color saturation.\n"
869 " Shft-L Press to vary the color brightness.\n"
871 " Shft-G Press to gamma correct the image.\n"
873 " Shft-C Press to sharpen the image contrast.\n"
875 " Shft-Z Press to dull the image contrast.\n"
877 " = Press to perform histogram equalization on the image.\n"
879 " Shft-N Press to perform histogram normalization on the image.\n"
881 " Shft-~ Press to negate the colors of the image.\n"
883 " . Press to convert the image colors to gray.\n"
885 " Shft-# Press to set the maximum number of unique colors in the\n"
888 " F2 Press to reduce the speckles in an image.\n"
890 " F3 Press to eliminate peak noise from an image.\n"
892 " F4 Press to add noise to an image.\n"
894 " F5 Press to sharpen an image.\n"
896 " F6 Press to delete an image file.\n"
898 " F7 Press to threshold the image.\n"
900 " F8 Press to detect edges within an image.\n"
902 " F9 Press to emboss an image.\n"
904 " F10 Press to displace pixels by a random amount.\n"
906 " F11 Press to negate all pixels above the threshold level.\n"
908 " F12 Press to shade the image using a distant light source.\n"
910 " F13 Press to lighten or darken image edges to create a 3-D effect.\n"
912 " F14 Press to segment the image by color.\n"
914 " Meta-S Press to swirl image pixels about the center.\n"
916 " Meta-I Press to implode image pixels about the center.\n"
918 " Meta-W Press to alter an image along a sine wave.\n"
920 " Meta-P Press to simulate an oil painting.\n"
922 " Meta-C Press to simulate a charcoal drawing.\n"
924 " Alt-A Press to annotate the image with text.\n"
926 " Alt-D Press to draw on an image.\n"
928 " Alt-P Press to edit an image pixel color.\n"
930 " Alt-M Press to edit the image matte information.\n"
932 " Alt-V Press to composite the image with another.\n"
934 " Alt-B Press to add a border to the image.\n"
936 " Alt-F Press to add an ornamental border to the image.\n"
939 " Press to add an image comment.\n"
941 " Ctl-A Press to apply image processing techniques to a region\n"
944 " Shft-? Press to display information about the image.\n"
946 " Shft-+ Press to map the zoom image window.\n"
948 " Shft-P Press to preview an image enhancement, effect, or f/x.\n"
950 " F1 Press to display helpful information about display(1).\n"
952 " Find Press to browse documentation about ImageMagick.\n"
954 " 1-9 Press to change the level of magnification.\n"
956 " Use the arrow keys to move the image one pixel up, down,\n"
957 " left, or right within the magnify window. Be sure to first\n"
958 " map the magnify window by pressing button 2.\n"
960 " Press ALT and one of the arrow keys to trim off one pixel\n"
961 " from any side of the image.\n"
963 ImageMatteEditHelp[] =
965 "Matte information within an image is useful for some\n"
966 "operations such as image compositing (See IMAGE\n"
967 "COMPOSITING). This extra channel usually defines a mask\n"
968 "which represents a sort of a cookie-cutter for the image.\n"
969 "This the case when matte is opaque (full coverage) for\n"
970 "pixels inside the shape, zero outside, and between 0 and\n"
971 "QuantumRange on the boundary.\n"
973 "A small window appears showing the location of the cursor in\n"
974 "the image window. You are now in matte edit mode. To exit\n"
975 "immediately, press Dismiss. In matte edit mode, the Command\n"
976 "widget has these options:\n"
1010 "Choose a matte editing method from the Method sub-menu of\n"
1011 "the Command widget. The point method changes the matte value\n"
1012 "of any pixel selected with the pointer until the button is\n"
1013 "is released. The replace method changes the matte value of\n"
1014 "any pixel that matches the color of the pixel you select with\n"
1015 "a button press. Floodfill changes the matte value of any pixel\n"
1016 "that matches the color of the pixel you select with a button\n"
1017 "press and is a neighbor. Whereas filltoborder changes the matte\n"
1018 "value any neighbor pixel that is not the border color. Finally\n"
1019 "reset changes the entire image to the designated matte value.\n"
1021 "Choose Matte Value and pick Opaque or Transparent. For other values\n"
1022 "select the Dialog entry. Here a dialog appears requesting a matte\n"
1023 "value. The value you select is assigned as the opacity value of the\n"
1024 "selected pixel or pixels.\n"
1026 "Now, press any button to select a pixel within the image\n"
1027 "window to change its matte value.\n"
1029 "If the Magnify widget is mapped, it can be helpful in positioning\n"
1030 "your pointer within the image (refer to button 2).\n"
1032 "Matte information is only valid in a DirectClass image.\n"
1033 "Therefore, any PseudoClass image is promoted to DirectClass\n"
1034 "(see miff(5)). Note that matte information for PseudoClass\n"
1035 "is not retained for colormapped X server visuals (e.g.\n"
1036 "StaticColor, StaticColor, GrayScale, PseudoColor) unless you\n"
1037 "immediately save your image to a file (refer to Write).\n"
1038 "Correct matte editing behavior may require a TrueColor or\n"
1039 "DirectColor visual or a Standard Colormap.\n"
1043 "When an image exceeds the width or height of the X server\n"
1044 "screen, display maps a small panning icon. The rectangle\n"
1045 "within the panning icon shows the area that is currently\n"
1046 "displayed in the image window. To pan about the image,\n"
1047 "press any button and drag the pointer within the panning\n"
1048 "icon. The pan rectangle moves with the pointer and the\n"
1049 "image window is updated to reflect the location of the\n"
1050 "rectangle within the panning icon. When you have selected\n"
1051 "the area of the image you wish to view, release the button.\n"
1053 "Use the arrow keys to pan the image one pixel up, down,\n"
1054 "left, or right within the image window.\n"
1056 "The panning icon is withdrawn if the image becomes smaller\n"
1057 "than the dimensions of the X server screen.\n"
1061 "A small window appears showing the location of the cursor in\n"
1062 "the image window. You are now in paste mode. To exit\n"
1063 "immediately, press Dismiss. In paste mode, the Command\n"
1064 "widget has these options:\n"
1081 "Choose a composite operation from the Operators sub-menu of\n"
1082 "the Command widget. How each operator behaves is described\n"
1083 "below. Image window is the image currently displayed on\n"
1084 "your X server and image is the image obtained with the File\n"
1087 "Over The result is the union of the two image shapes,\n"
1088 " with image obscuring image window in the region of\n"
1091 "In The result is simply image cut by the shape of\n"
1092 " image window. None of the image data of image\n"
1093 " window is in the result.\n"
1095 "Out The resulting image is image with the shape of\n"
1096 " image window cut out.\n"
1098 "Atop The result is the same shape as the image window,\n"
1099 " with image obscuring image window where the image\n"
1100 " shapes overlap. Note this differs from over\n"
1101 " because the portion of image outside image window's\n"
1102 " shape does not appear in the result.\n"
1104 "Xor The result is the image data from both image and\n"
1105 " image window that is outside the overlap region.\n"
1106 " The overlap region is blank.\n"
1108 "Plus The result is just the sum of the image data.\n"
1109 " Output values are cropped to QuantumRange (no overflow).\n"
1110 " This operation is independent of the matte\n"
1113 "Minus The result of image - image window, with underflow\n"
1114 " cropped to zero.\n"
1116 "Add The result of image + image window, with overflow\n"
1117 " wrapping around (mod 256).\n"
1119 "Subtract The result of image - image window, with underflow\n"
1120 " wrapping around (mod 256). The add and subtract\n"
1121 " operators can be used to perform reversible\n"
1122 " transformations.\n"
1125 " The result of abs(image - image window). This\n"
1126 " useful for comparing two very similar images.\n"
1128 "Copy The resulting image is image window replaced with\n"
1129 " image. Here the matte information is ignored.\n"
1131 "CopyRed The red layer of the image window is replace with\n"
1132 " the red layer of the image. The other layers are\n"
1136 " The green layer of the image window is replace with\n"
1137 " the green layer of the image. The other layers are\n"
1140 "CopyBlue The blue layer of the image window is replace with\n"
1141 " the blue layer of the image. The other layers are\n"
1145 " The matte layer of the image window is replace with\n"
1146 " the matte layer of the image. The other layers are\n"
1149 "The image compositor requires a matte, or alpha channel in\n"
1150 "the image for some operations. This extra channel usually\n"
1151 "defines a mask which represents a sort of a cookie-cutter\n"
1152 "for the image. This the case when matte is opaque (full\n"
1153 "coverage) for pixels inside the shape, zero outside, and\n"
1154 "between 0 and QuantumRange on the boundary. If image does not\n"
1155 "have a matte channel, it is initialized with 0 for any pixel\n"
1156 "matching in color to pixel location (0,0), otherwise QuantumRange.\n"
1158 "Note that matte information for image window is not retained\n"
1159 "for colormapped X server visuals (e.g. StaticColor,\n"
1160 "StaticColor, GrayScale, PseudoColor). Correct compositing\n"
1161 "behavior may require a TrueColor or DirectColor visual or a\n"
1162 "Standard Colormap.\n"
1164 "Choosing a composite operator is optional. The default\n"
1165 "operator is replace. However, you must choose a location to\n"
1166 "paste your image and press button 1. Press and hold the\n"
1167 "button before releasing and an outline of the image will\n"
1168 "appear to help you identify your location.\n"
1170 "The actual colors of the pasted image is saved. However,\n"
1171 "the color that appears in image window may be different.\n"
1172 "For example, on a monochrome screen image window will appear\n"
1173 "black or white even though your pasted image may have\n"
1174 "many colors. If the image is saved to a file it is written\n"
1175 "with the correct colors. To assure the correct colors are\n"
1176 "saved in the final image, any PseudoClass image is promoted\n"
1177 "to DirectClass (see miff(5)). To force a PseudoClass image\n"
1178 "to remain PseudoClass, use -colors.\n"
1182 "In region of interest mode, the Command widget has these\n"
1188 "To define a region of interest, press button 1 and drag.\n"
1189 "The region of interest is defined by a highlighted rectangle\n"
1190 "that expands or contracts as it follows the pointer. Once\n"
1191 "you are satisfied with the region of interest, release the\n"
1192 "button. You are now in apply mode. In apply mode the\n"
1193 "Command widget has these options:\n"
1213 " Contrast Stretch\n"
1214 " Sigmoidal Contrast...\n"
1240 " Oil Painting...\n"
1241 " Charcoal Drawing...\n"
1245 " Show Preview...\n"
1251 "You can make adjustments to the region of interest by moving\n"
1252 "the pointer to one of the rectangle corners, pressing a\n"
1253 "button, and dragging. Finally, choose an image processing\n"
1254 "technique from the Command widget. You can choose more than\n"
1255 "one image processing technique to apply to an area.\n"
1256 "Alternatively, you can move the region of interest before\n"
1257 "applying another image processing technique. To exit, press\n"
1262 "In rotate mode, the Command widget has these options:\n"
1281 "Choose a background color from the Pixel Color sub-menu.\n"
1282 "Additional background colors can be specified with the color\n"
1283 "browser. You can change the menu colors by setting the X\n"
1284 "resources pen1 through pen9.\n"
1286 "If you choose the color browser and press Grab, you can\n"
1287 "select the background color by moving the pointer to the\n"
1288 "desired color on the screen and press any button.\n"
1290 "Choose a point in the image window and press this button and\n"
1291 "hold. Next, move the pointer to another location in the\n"
1292 "image. As you move a line connects the initial location and\n"
1293 "the pointer. When you release the button, the degree of\n"
1294 "image rotation is determined by the slope of the line you\n"
1295 "just drew. The slope is relative to the direction you\n"
1296 "choose from the Direction sub-menu of the Command widget.\n"
1298 "To cancel the image rotation, move the pointer back to the\n"
1299 "starting point of the line and release the button.\n"
1322 VisualDirectoryCommand,
1330 OriginalSizeCommand,
1352 ContrastStretchCommand,
1353 SigmoidalContrastCommand,
1379 CharcoalDrawCommand,
1389 RegionOfInterestCommand,
1395 ShowHistogramCommand,
1401 BrowseDocumentationCommand,
1403 SaveToUndoBufferCommand,
1410 AnnotateNameCommand,
1411 AnnotateFontColorCommand,
1412 AnnotateBackgroundColorCommand,
1413 AnnotateRotateCommand,
1414 AnnotateHelpCommand,
1415 AnnotateDismissCommand,
1418 ChopDirectionCommand,
1421 HorizontalChopCommand,
1422 VerticalChopCommand,
1423 ColorEditMethodCommand,
1424 ColorEditColorCommand,
1425 ColorEditBorderCommand,
1426 ColorEditFuzzCommand,
1427 ColorEditUndoCommand,
1428 ColorEditHelpCommand,
1429 ColorEditDismissCommand,
1430 CompositeOperatorsCommand,
1431 CompositeDissolveCommand,
1432 CompositeDisplaceCommand,
1433 CompositeHelpCommand,
1434 CompositeDismissCommand,
1439 RectifyDismissCommand,
1448 MatteEditBorderCommand,
1449 MatteEditFuzzCommand,
1450 MatteEditValueCommand,
1451 MatteEditUndoCommand,
1452 MatteEditHelpCommand,
1453 MatteEditDismissCommand,
1454 PasteOperatorsCommand,
1456 PasteDismissCommand,
1458 RotateDirectionCommand,
1460 RotateSharpenCommand,
1462 RotateDismissCommand,
1463 HorizontalRotateCommand,
1464 VerticalRotateCommand,
1475 #define BricksWidth 20
1476 #define BricksHeight 20
1477 #define DiagonalWidth 16
1478 #define DiagonalHeight 16
1479 #define HighlightWidth 8
1480 #define HighlightHeight 8
1481 #define OpaqueWidth 8
1482 #define OpaqueHeight 8
1483 #define ScalesWidth 16
1484 #define ScalesHeight 16
1485 #define ShadowWidth 8
1486 #define ShadowHeight 8
1487 #define VerticalWidth 16
1488 #define VerticalHeight 16
1489 #define WavyWidth 16
1490 #define WavyHeight 16
1498 static const unsigned char
1501 0xff, 0xff, 0x0f, 0x03, 0x0c, 0x00, 0x03, 0x0c, 0x00, 0x03, 0x0c, 0x00,
1502 0x03, 0x0c, 0x00, 0xff, 0xff, 0x0f, 0x60, 0x80, 0x01, 0x60, 0x80, 0x01,
1503 0x60, 0x80, 0x01, 0x60, 0x80, 0x01, 0xff, 0xff, 0x0f, 0x03, 0x0c, 0x00,
1504 0x03, 0x0c, 0x00, 0x03, 0x0c, 0x00, 0x03, 0x0c, 0x00, 0xff, 0xff, 0x0f,
1505 0x60, 0x80, 0x01, 0x60, 0x80, 0x01, 0x60, 0x80, 0x01, 0x60, 0x80, 0x01
1509 0x44, 0x44, 0x88, 0x88, 0x11, 0x11, 0x22, 0x22, 0x44, 0x44, 0x88, 0x88,
1510 0x11, 0x11, 0x22, 0x22, 0x44, 0x44, 0x88, 0x88, 0x11, 0x11, 0x22, 0x22,
1511 0x44, 0x44, 0x88, 0x88, 0x11, 0x11, 0x22, 0x22
1515 0x08, 0x08, 0x08, 0x08, 0x14, 0x14, 0xe3, 0xe3, 0x80, 0x80, 0x80, 0x80,
1516 0x41, 0x41, 0x3e, 0x3e, 0x08, 0x08, 0x08, 0x08, 0x14, 0x14, 0xe3, 0xe3,
1517 0x80, 0x80, 0x80, 0x80, 0x41, 0x41, 0x3e, 0x3e
1521 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1522 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1523 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11
1527 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfd, 0xff, 0xfd, 0xff, 0xfb, 0xff,
1528 0xe7, 0xff, 0x1f, 0xff, 0xff, 0xf8, 0xff, 0xe7, 0xff, 0xdf, 0xff, 0xbf,
1529 0xff, 0xbf, 0xff, 0x7f, 0xff, 0x7f, 0xff, 0x7f
1536 XImageWindowCommand(Display *,XResourceInfo *,XWindows *,
1537 const MagickStatusType,KeySym,
Image **);
1540 *XMagickCommand(Display *,XResourceInfo *,XWindows *,
const CommandType,
1542 *XOpenImage(Display *,XResourceInfo *,XWindows *,
const MagickBooleanType),
1543 *XTileImage(Display *,XResourceInfo *,XWindows *,
Image *,XEvent *),
1544 *XVisualDirectoryImage(Display *,XResourceInfo *,XWindows *);
1546 static MagickBooleanType
1547 XAnnotateEditImage(Display *,XResourceInfo *,XWindows *,
Image *),
1548 XDrawEditImage(Display *,XResourceInfo *,XWindows *,
Image **),
1549 XChopImage(Display *,XResourceInfo *,XWindows *,
Image **),
1550 XCropImage(Display *,XResourceInfo *,XWindows *,
Image *,
const ClipboardMode),
1551 XBackgroundImage(Display *,XResourceInfo *,XWindows *,
Image **),
1552 XColorEditImage(Display *,XResourceInfo *,XWindows *,
Image **),
1553 XCompositeImage(Display *,XResourceInfo *,XWindows *,
Image *),
1554 XConfigureImage(Display *,XResourceInfo *,XWindows *,
Image *),
1555 XMatteEditImage(Display *,XResourceInfo *,XWindows *,
Image **),
1556 XPasteImage(Display *,XResourceInfo *,XWindows *,
Image *),
1557 XPrintImage(Display *,XResourceInfo *,XWindows *,
Image *),
1558 XRotateImage(Display *,XResourceInfo *,XWindows *,
double,
Image **),
1559 XROIImage(Display *,XResourceInfo *,XWindows *,
Image **),
1560 XSaveImage(Display *,XResourceInfo *,XWindows *,
Image *),
1561 XTrimImage(Display *,XResourceInfo *,XWindows *,
Image *);
1564 XDrawPanRectangle(Display *,XWindows *),
1565 XImageCache(Display *,XResourceInfo *,XWindows *,
const CommandType,
Image **),
1566 XMagnifyImage(Display *,XWindows *,XEvent *),
1567 XMakePanImage(Display *,XResourceInfo *,XWindows *,
Image *),
1568 XPanImage(Display *,XWindows *,XEvent *),
1569 XMagnifyWindowCommand(Display *,XWindows *,
const MagickStatusType,
1572 XScreenEvent(Display *,XWindows *,XEvent *),
1573 XTranslateImage(Display *,XWindows *,
Image *,
const KeySym);
1602 MagickExport MagickBooleanType DisplayImages(
const ImageInfo *image_info,
1626 assert(image_info != (
const ImageInfo *) NULL);
1627 assert(image_info->signature == MagickCoreSignature);
1628 assert(images != (
Image *) NULL);
1629 assert(images->signature == MagickCoreSignature);
1630 if (IsEventLogging() != MagickFalse)
1631 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",images->filename);
1632 display=XOpenDisplay(image_info->server_name);
1633 if (display == (Display *) NULL)
1635 (void) ThrowMagickException(&images->exception,GetMagickModule(),
1636 XServerError,
"UnableToOpenXServer",
"`%s'",XDisplayName(
1637 image_info->server_name));
1638 return(MagickFalse);
1640 if (images->exception.severity != UndefinedException)
1641 CatchException(&images->exception);
1642 (void) XSetErrorHandler(XError);
1643 resource_database=XGetResourceDatabase(display,GetClientName());
1644 (void) memset(&resource_info,0,
sizeof(resource_info));
1645 XGetResourceInfo(image_info,resource_database,GetClientName(),&resource_info);
1646 if (image_info->page != (
char *) NULL)
1647 resource_info.image_geometry=AcquireString(image_info->page);
1648 resource_info.immutable=MagickTrue;
1649 argv[0]=AcquireString(GetClientName());
1651 for (i=0; (state & ExitState) == 0; i++)
1653 if ((images->iterations != 0) && (i >= (ssize_t) images->iterations))
1655 image=GetImageFromList(images,i % GetImageListLength(images));
1656 (void) XDisplayImage(display,&resource_info,argv,1,&image,&state);
1658 (void) SetErrorHandler((ErrorHandler) NULL);
1659 (void) SetWarningHandler((WarningHandler) NULL);
1660 argv[0]=DestroyString(argv[0]);
1661 XDestroyResourceInfo(&resource_info);
1662 if (images->exception.severity != UndefinedException)
1663 return(MagickFalse);
1697 MagickExport MagickBooleanType RemoteDisplayCommand(
const ImageInfo *image_info,
1698 const char *window,
const char *filename,
ExceptionInfo *exception)
1706 assert(image_info != (
const ImageInfo *) NULL);
1707 assert(image_info->signature == MagickCoreSignature);
1708 assert(filename != (
char *) NULL);
1709 if (IsEventLogging() != MagickFalse)
1710 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",filename);
1711 display=XOpenDisplay(image_info->server_name);
1712 if (display == (Display *) NULL)
1714 (void) ThrowMagickException(exception,GetMagickModule(),XServerError,
1715 "UnableToOpenXServer",
"`%s'",XDisplayName(image_info->server_name));
1716 return(MagickFalse);
1718 (void) XSetErrorHandler(XError);
1719 status=XRemoteCommand(display,window,filename);
1720 (void) XCloseDisplay(display);
1721 return(status != 0 ? MagickTrue : MagickFalse);
1755 static MagickBooleanType XAnnotateEditImage(Display *display,
1756 XResourceInfo *resource_info,XWindows *windows,
Image *image)
1759 *
const AnnotateMenu[] =
1776 static const ModeType
1777 AnnotateCommands[] =
1779 AnnotateNameCommand,
1780 AnnotateFontColorCommand,
1781 AnnotateBackgroundColorCommand,
1782 AnnotateRotateCommand,
1783 AnnotateHelpCommand,
1784 AnnotateDismissCommand
1792 static MagickBooleanType
1793 transparent_box = MagickTrue,
1794 transparent_pen = MagickFalse;
1796 static MagickRealType
1800 box_id = MaxNumberPens-2,
1805 command[MaxTextExtent],
1806 text[MaxTextExtent];
1809 *ColorMenu[MaxNumberPens+1];
1857 (void) CloneString(&windows->command.name,
"Annotate");
1858 windows->command.data=4;
1859 (void) XCommandWidget(display,windows,AnnotateMenu,(XEvent *) NULL);
1860 (void) XMapRaised(display,windows->command.id);
1861 XClientMessage(display,windows->image.id,windows->im_protocols,
1862 windows->im_update_widget,CurrentTime);
1866 XQueryPosition(display,windows->image.id,&x,&y);
1867 (void) XSelectInput(display,windows->image.id,
1868 windows->image.attributes.event_mask | PointerMotionMask);
1869 cursor=XCreateFontCursor(display,XC_left_side);
1870 (void) XCheckDefineCursor(display,windows->image.id,cursor);
1874 if (windows->info.mapped != MagickFalse)
1879 (void) FormatLocaleString(text,MaxTextExtent,
" %+d%+d ",
1880 x+windows->image.x,y+windows->image.y);
1881 XInfoWidget(display,windows,text);
1886 XScreenEvent(display,windows,&event);
1887 if (event.xany.window == windows->command.id)
1892 id=XCommandWidget(display,windows,AnnotateMenu,&event);
1893 (void) XCheckDefineCursor(display,windows->image.id,cursor);
1896 switch (AnnotateCommands[
id])
1898 case AnnotateNameCommand:
1901 *FontMenu[MaxNumberFonts];
1909 for (i=0; i < MaxNumberFonts; i++)
1910 FontMenu[i]=resource_info->font_name[i];
1911 FontMenu[MaxNumberFonts-2]=
"Browser...";
1912 FontMenu[MaxNumberFonts-1]=(
const char *) NULL;
1916 font_number=XMenuWidget(display,windows,AnnotateMenu[
id],
1917 (
const char **) FontMenu,command);
1918 if (font_number < 0)
1920 if (font_number == (MaxNumberFonts-2))
1923 font_name[MaxTextExtent] =
"fixed";
1928 resource_info->font_name[font_number]=font_name;
1929 XFontBrowserWidget(display,windows,
"Select",font_name);
1930 if (*font_name ==
'\0')
1936 font_info=XLoadQueryFont(display,resource_info->font_name[
1938 if (font_info == (XFontStruct *) NULL)
1940 XNoticeWidget(display,windows,
"Unable to load font:",
1941 resource_info->font_name[font_number]);
1944 font_id=(
unsigned int) font_number;
1945 (void) XFreeFont(display,font_info);
1948 case AnnotateFontColorCommand:
1953 for (i=0; i < (int) (MaxNumberPens-2); i++)
1954 ColorMenu[i]=resource_info->pen_colors[i];
1955 ColorMenu[MaxNumberPens-2]=
"transparent";
1956 ColorMenu[MaxNumberPens-1]=
"Browser...";
1957 ColorMenu[MaxNumberPens]=(
const char *) NULL;
1961 pen_number=XMenuWidget(display,windows,AnnotateMenu[
id],
1962 (
const char **) ColorMenu,command);
1965 transparent_pen=pen_number == (MaxNumberPens-2) ? MagickTrue :
1967 if (transparent_pen != MagickFalse)
1969 if (pen_number == (MaxNumberPens-1))
1972 color_name[MaxTextExtent] =
"gray";
1977 resource_info->pen_colors[pen_number]=color_name;
1978 XColorBrowserWidget(display,windows,
"Select",color_name);
1979 if (*color_name ==
'\0')
1985 (void) XParseColor(display,windows->map_info->colormap,
1986 resource_info->pen_colors[pen_number],&color);
1987 XBestPixel(display,windows->map_info->colormap,(XColor *) NULL,
1988 (
unsigned int) MaxColors,&color);
1989 windows->pixel_info->pen_colors[pen_number]=color;
1990 pen_id=(
unsigned int) pen_number;
1993 case AnnotateBackgroundColorCommand:
1998 for (i=0; i < (int) (MaxNumberPens-2); i++)
1999 ColorMenu[i]=resource_info->pen_colors[i];
2000 ColorMenu[MaxNumberPens-2]=
"transparent";
2001 ColorMenu[MaxNumberPens-1]=
"Browser...";
2002 ColorMenu[MaxNumberPens]=(
const char *) NULL;
2006 pen_number=XMenuWidget(display,windows,AnnotateMenu[
id],
2007 (
const char **) ColorMenu,command);
2010 transparent_box=pen_number == (MaxNumberPens-2) ? MagickTrue :
2012 if (transparent_box != MagickFalse)
2014 if (pen_number == (MaxNumberPens-1))
2017 color_name[MaxTextExtent] =
"gray";
2022 resource_info->pen_colors[pen_number]=color_name;
2023 XColorBrowserWidget(display,windows,
"Select",color_name);
2024 if (*color_name ==
'\0')
2030 (void) XParseColor(display,windows->map_info->colormap,
2031 resource_info->pen_colors[pen_number],&color);
2032 XBestPixel(display,windows->map_info->colormap,(XColor *) NULL,
2033 (
unsigned int) MaxColors,&color);
2034 windows->pixel_info->pen_colors[pen_number]=color;
2035 box_id=(
unsigned int) pen_number;
2038 case AnnotateRotateCommand:
2044 *
const RotateMenu[] =
2059 angle[MaxTextExtent] =
"30.0";
2064 entry=XMenuWidget(display,windows,AnnotateMenu[
id],RotateMenu,
2070 degrees=StringToDouble(RotateMenu[entry],(
char **) NULL);
2073 (void) XDialogWidget(display,windows,
"OK",
"Enter rotation angle:",
2077 degrees=StringToDouble(angle,(
char **) NULL);
2080 case AnnotateHelpCommand:
2082 XTextViewHelp(display,resource_info,windows,MagickFalse,
2083 "Help Viewer - Image Annotation",ImageAnnotateHelp);
2086 case AnnotateDismissCommand:
2104 if (event.xbutton.button != Button1)
2106 if (event.xbutton.window != windows->image.id)
2122 if (event.xkey.window != windows->image.id)
2127 (void) XLookupString((XKeyEvent *) &
event.xkey,command,(int)
2128 sizeof(command),&key_symbol,(XComposeStatus *) NULL);
2129 switch ((
int) key_symbol)
2144 XTextViewHelp(display,resource_info,windows,MagickFalse,
2145 "Help Viewer - Image Annotation",ImageAnnotateHelp);
2150 (void) XBell(display,0);
2163 if (windows->info.mapped != MagickFalse)
2165 if ((x < (
int) (windows->info.x+windows->info.width)) &&
2166 (y < (int) (windows->info.y+windows->info.height)))
2167 (void) XWithdrawWindow(display,windows->info.id,
2168 windows->info.screen);
2171 if ((x > (
int) (windows->info.x+windows->info.width)) ||
2172 (y > (int) (windows->info.y+windows->info.height)))
2173 (void) XMapWindow(display,windows->info.id);
2179 }
while ((state & ExitState) == 0);
2180 (void) XSelectInput(display,windows->image.id,
2181 windows->image.attributes.event_mask);
2182 (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
2183 if ((state & EscapeState) != 0)
2188 font_info=XLoadQueryFont(display,resource_info->font_name[font_id]);
2189 if (font_info == (XFontStruct *) NULL)
2191 XNoticeWidget(display,windows,
"Unable to load font:",
2192 resource_info->font_name[font_id]);
2193 font_info=windows->font_info;
2195 if ((x+font_info->max_bounds.width) >= (
int) windows->image.width)
2196 x=(int) windows->image.width-font_info->max_bounds.width;
2197 if (y < (
int) (font_info->ascent+font_info->descent))
2198 y=(int) font_info->ascent+font_info->descent;
2199 if (((
int) font_info->max_bounds.width > (int) windows->image.width) ||
2200 ((font_info->ascent+font_info->descent) >= (
int) windows->image.height))
2201 return(MagickFalse);
2205 annotate_info=(XAnnotateInfo *) AcquireMagickMemory(
sizeof(*annotate_info));
2206 if (annotate_info == (XAnnotateInfo *) NULL)
2207 return(MagickFalse);
2208 XGetAnnotateInfo(annotate_info);
2211 if ((transparent_box == MagickFalse) && (transparent_pen == MagickFalse))
2212 annotate_info->stencil=OpaqueStencil;
2214 if (transparent_box == MagickFalse)
2215 annotate_info->stencil=BackgroundStencil;
2217 annotate_info->stencil=ForegroundStencil;
2218 annotate_info->height=(
unsigned int) font_info->ascent+font_info->descent;
2219 annotate_info->degrees=degrees;
2220 annotate_info->font_info=font_info;
2221 annotate_info->text=(
char *) AcquireQuantumMemory((
size_t)
2222 windows->image.width/MagickMax((ssize_t) font_info->min_bounds.width,1)+2UL,
2223 sizeof(*annotate_info->text));
2224 if (annotate_info->text == (
char *) NULL)
2225 return(MagickFalse);
2229 cursor=XCreateFontCursor(display,XC_pencil);
2230 (void) XCheckDefineCursor(display,windows->image.id,cursor);
2231 annotate_context=windows->image.annotate_context;
2232 (void) XSetFont(display,annotate_context,font_info->fid);
2233 (void) XSetBackground(display,annotate_context,
2234 windows->pixel_info->pen_colors[box_id].pixel);
2235 (void) XSetForeground(display,annotate_context,
2236 windows->pixel_info->pen_colors[pen_id].pixel);
2240 (void) CloneString(&windows->command.name,
"Text");
2241 windows->command.data=0;
2242 (void) XCommandWidget(display,windows,TextMenu,(XEvent *) NULL);
2244 (void) XDrawString(display,windows->image.id,annotate_context,x,y,
"_",1);
2245 text_event.xexpose.width=(int) font_info->max_bounds.width;
2246 text_event.xexpose.height=font_info->max_bounds.ascent+
2247 font_info->max_bounds.descent;
2248 p=annotate_info->text;
2255 (
void) XDrawString(display,windows->image.id,annotate_context,x,y,
"_",1);
2259 XScreenEvent(display,windows,&event);
2260 if (event.xany.window == windows->command.id)
2265 (void) XSetBackground(display,annotate_context,
2266 windows->pixel_info->background_color.pixel);
2267 (void) XSetForeground(display,annotate_context,
2268 windows->pixel_info->foreground_color.pixel);
2269 id=XCommandWidget(display,windows,AnnotateMenu,&event);
2270 (void) XSetBackground(display,annotate_context,
2271 windows->pixel_info->pen_colors[box_id].pixel);
2272 (void) XSetForeground(display,annotate_context,
2273 windows->pixel_info->pen_colors[pen_id].pixel);
2276 switch (TextCommands[
id])
2278 case TextHelpCommand:
2280 XTextViewHelp(display,resource_info,windows,MagickFalse,
2281 "Help Viewer - Image Annotation",ImageAnnotateHelp);
2282 (void) XCheckDefineCursor(display,windows->image.id,cursor);
2285 case TextApplyCommand:
2290 annotate_info->width=(
unsigned int) XTextWidth(font_info,
2291 annotate_info->text,(
int) strlen(annotate_info->text));
2292 XRefreshWindow(display,&windows->image,&text_event);
2304 text_event.xexpose.x=x;
2305 text_event.xexpose.y=y-font_info->max_bounds.ascent;
2306 (void) XClearArea(display,windows->image.id,x,text_event.xexpose.y,
2307 (
unsigned int) text_event.xexpose.width,(
unsigned int)
2308 text_event.xexpose.height,MagickFalse);
2309 XRefreshWindow(display,&windows->image,&text_event);
2314 if (event.xbutton.window != windows->image.id)
2316 if (event.xbutton.button == Button2)
2321 (void) XConvertSelection(display,XA_PRIMARY,XA_STRING,XA_STRING,
2322 windows->image.id,CurrentTime);
2329 if (event.xexpose.count == 0)
2337 XRefreshWindow(display,&windows->image,(XEvent *) NULL);
2338 text_info=annotate_info;
2339 while (text_info != (XAnnotateInfo *) NULL)
2341 if (annotate_info->stencil == ForegroundStencil)
2342 (void) XDrawString(display,windows->image.id,annotate_context,
2343 text_info->x,text_info->y,text_info->text,
2344 (
int) strlen(text_info->text));
2346 (
void) XDrawImageString(display,windows->image.id,
2347 annotate_context,text_info->x,text_info->y,text_info->text,
2348 (
int) strlen(text_info->text));
2349 text_info=text_info->previous;
2351 (void) XDrawString(display,windows->image.id,annotate_context,
2361 if (event.xkey.window != windows->image.id)
2366 length=XLookupString((XKeyEvent *) &event.xkey,command,(
int)
2367 sizeof(command),&key_symbol,(XComposeStatus *) NULL);
2368 *(command+length)=
'\0';
2369 if (((event.xkey.state & ControlMask) != 0) ||
2370 ((
event.xkey.state & Mod1Mask) != 0))
2371 state|=ModifierState;
2372 if ((state & ModifierState) != 0)
2373 switch ((
int) key_symbol)
2378 key_symbol=DeleteCommand;
2384 switch ((
int) key_symbol)
2391 if (p == annotate_info->text)
2393 if (annotate_info->previous == (XAnnotateInfo *) NULL)
2400 annotate_info=annotate_info->previous;
2401 p=annotate_info->text;
2402 x=annotate_info->x+annotate_info->width;
2404 if (annotate_info->width != 0)
2405 p+=strlen(annotate_info->text);
2410 x-=XTextWidth(font_info,p,1);
2411 text_event.xexpose.x=x;
2412 text_event.xexpose.y=y-font_info->max_bounds.ascent;
2413 XRefreshWindow(display,&windows->image,&text_event);
2416 case XK_bracketleft:
2418 key_symbol=XK_Escape;
2426 while (p != annotate_info->text)
2429 x-=XTextWidth(font_info,p,1);
2430 text_event.xexpose.x=x;
2431 XRefreshWindow(display,&windows->image,&text_event);
2441 annotate_info->width=(
unsigned int) XTextWidth(font_info,
2442 annotate_info->text,(
int) strlen(annotate_info->text));
2443 XRefreshWindow(display,&windows->image,&text_event);
2452 if ((state & ModifierState) != 0)
2454 if (*command ==
'\0')
2457 if (annotate_info->stencil == ForegroundStencil)
2458 (void) XDrawString(display,windows->image.id,annotate_context,
2461 (
void) XDrawImageString(display,windows->image.id,
2462 annotate_context,x,y,p,1);
2463 x+=XTextWidth(font_info,p,1);
2465 if ((x+font_info->max_bounds.width) < (
int) windows->image.width)
2476 annotate_info->width=(
unsigned int) XTextWidth(font_info,
2477 annotate_info->text,(
int) strlen(annotate_info->text));
2478 if (annotate_info->next != (XAnnotateInfo *) NULL)
2483 annotate_info=annotate_info->next;
2486 p=annotate_info->text;
2489 annotate_info->next=(XAnnotateInfo *) AcquireQuantumMemory(1,
2490 sizeof(*annotate_info->next));
2491 if (annotate_info->next == (XAnnotateInfo *) NULL)
2492 return(MagickFalse);
2493 *annotate_info->next=(*annotate_info);
2494 annotate_info->next->previous=annotate_info;
2495 annotate_info=annotate_info->next;
2496 annotate_info->text=(
char *) AcquireQuantumMemory((
size_t)
2497 windows->image.width/MagickMax((ssize_t)
2498 font_info->min_bounds.width,1)+2UL,
sizeof(*annotate_info->text));
2499 if (annotate_info->text == (
char *) NULL)
2500 return(MagickFalse);
2501 annotate_info->y+=annotate_info->height;
2502 if (annotate_info->y > (
int) windows->image.height)
2503 annotate_info->y=(
int) annotate_info->height;
2504 annotate_info->next=(XAnnotateInfo *) NULL;
2507 p=annotate_info->text;
2518 (void) XLookupString((XKeyEvent *) &
event.xkey,command,(int)
2519 sizeof(command),&key_symbol,(XComposeStatus *) NULL);
2520 state&=(~ModifierState);
2523 case SelectionNotify:
2541 if (event.xselection.property == (Atom) None)
2543 status=XGetWindowProperty(display,event.xselection.requestor,
2544 event.xselection.property,0L,(
long) MaxTextExtent,True,XA_STRING,
2545 &type,&format,&length,&after,&data);
2546 if ((status != Success) || (type != XA_STRING) || (format == 32) ||
2552 for (i=0; i < (ssize_t) length; i++)
2554 if ((
char) data[i] !=
'\n')
2560 (void) XDrawString(display,windows->image.id,annotate_context,
2562 x+=XTextWidth(font_info,p,1);
2564 if ((x+font_info->max_bounds.width) < (
int) windows->image.width)
2571 annotate_info->width=(
unsigned int) XTextWidth(font_info,
2572 annotate_info->text,(
int) strlen(annotate_info->text));
2573 if (annotate_info->next != (XAnnotateInfo *) NULL)
2578 annotate_info=annotate_info->next;
2581 p=annotate_info->text;
2584 annotate_info->next=(XAnnotateInfo *) AcquireQuantumMemory(1,
2585 sizeof(*annotate_info->next));
2586 if (annotate_info->next == (XAnnotateInfo *) NULL)
2587 return(MagickFalse);
2588 *annotate_info->next=(*annotate_info);
2589 annotate_info->next->previous=annotate_info;
2590 annotate_info=annotate_info->next;
2591 annotate_info->text=(
char *) AcquireQuantumMemory((
size_t)
2592 windows->image.width/MagickMax((ssize_t)
2593 font_info->min_bounds.width,1)+2UL,
sizeof(*annotate_info->text));
2594 if (annotate_info->text == (
char *) NULL)
2595 return(MagickFalse);
2596 annotate_info->y+=annotate_info->height;
2597 if (annotate_info->y > (
int) windows->image.height)
2598 annotate_info->y=(
int) annotate_info->height;
2599 annotate_info->next=(XAnnotateInfo *) NULL;
2602 p=annotate_info->text;
2604 (void) XFree((
void *) data);
2610 }
while ((state & ExitState) == 0);
2611 (void) XFreeCursor(display,cursor);
2615 width=(
unsigned int) image->columns;
2616 height=(
unsigned int) image->rows;
2619 if (windows->image.crop_geometry != (
char *) NULL)
2620 (
void) XParseGeometry(windows->image.crop_geometry,&x,&y,&width,&height);
2624 XSetCursorState(display,windows,MagickTrue);
2625 XCheckRefreshWindows(display,windows);
2626 while (annotate_info != (XAnnotateInfo *) NULL)
2628 if (annotate_info->width == 0)
2633 previous_info=annotate_info->previous;
2634 annotate_info->text=(
char *)
2635 RelinquishMagickMemory(annotate_info->text);
2636 annotate_info=(XAnnotateInfo *) RelinquishMagickMemory(annotate_info);
2637 annotate_info=previous_info;
2643 windows->pixel_info->box_color=windows->pixel_info->pen_colors[box_id];
2644 if (windows->pixel_info->colors != 0)
2645 for (i=0; i < (ssize_t) windows->pixel_info->colors; i++)
2646 if (windows->pixel_info->pixels[i] ==
2647 windows->pixel_info->pen_colors[box_id].pixel)
2649 windows->pixel_info->box_index=(
unsigned short) i;
2652 windows->pixel_info->pen_color=windows->pixel_info->pen_colors[pen_id];
2653 if (windows->pixel_info->colors != 0)
2654 for (i=0; i < (ssize_t) windows->pixel_info->colors; i++)
2655 if (windows->pixel_info->pixels[i] ==
2656 windows->pixel_info->pen_colors[pen_id].pixel)
2658 windows->pixel_info->pen_index=(
unsigned short) i;
2664 annotate_info->x=(int)
2665 width*(annotate_info->x+windows->image.x)/windows->image.ximage->width;
2666 annotate_info->y=(int) height*(annotate_info->y-font_info->ascent+
2667 windows->image.y)/windows->image.ximage->height;
2668 (void) FormatLocaleString(annotate_info->geometry,MaxTextExtent,
2669 "%ux%u%+d%+d",width*annotate_info->width/windows->image.ximage->width,
2670 height*annotate_info->height/windows->image.ximage->height,
2671 annotate_info->x+x,annotate_info->y+y);
2675 status=XAnnotateImage(display,windows->pixel_info,annotate_info,image);
2677 return(MagickFalse);
2681 previous_info=annotate_info->previous;
2682 annotate_info->text=DestroyString(annotate_info->text);
2683 annotate_info=(XAnnotateInfo *) RelinquishMagickMemory(annotate_info);
2684 annotate_info=previous_info;
2686 (void) XSetForeground(display,annotate_context,
2687 windows->pixel_info->foreground_color.pixel);
2688 (void) XSetBackground(display,annotate_context,
2689 windows->pixel_info->background_color.pixel);
2690 (void) XSetFont(display,annotate_context,windows->font_info->fid);
2691 XSetCursorState(display,windows,MagickFalse);
2692 (void) XFreeFont(display,font_info);
2696 XConfigureImageColormap(display,resource_info,windows,image);
2697 (void) XConfigureImage(display,resource_info,windows,image);
2731 static MagickBooleanType XBackgroundImage(Display *display,
2732 XResourceInfo *resource_info,XWindows *windows,
Image **image)
2734 #define BackgroundImageTag "Background/Image"
2740 window_id[MaxTextExtent] =
"root";
2743 background_resources;
2748 status=XDialogWidget(display,windows,
"Background",
2749 "Enter window id (id 0x00 selects window with pointer):",window_id);
2750 if (*window_id ==
'\0')
2751 return(MagickFalse);
2752 (void) XMagickCommand(display,resource_info,windows,ApplyCommand,image);
2753 XInfoWidget(display,windows,BackgroundImageTag);
2754 XSetCursorState(display,windows,MagickTrue);
2755 XCheckRefreshWindows(display,windows);
2756 background_resources=(*resource_info);
2757 background_resources.window_id=window_id;
2758 background_resources.backdrop=status != 0 ? MagickTrue : MagickFalse;
2759 status=XDisplayBackgroundImage(display,&background_resources,*image);
2760 if (status != MagickFalse)
2761 XClientMessage(display,windows->image.id,windows->im_protocols,
2762 windows->im_retain_colors,CurrentTime);
2763 XSetCursorState(display,windows,MagickFalse);
2764 (void) XMagickCommand(display,resource_info,windows,UndoCommand,image);
2798 static MagickBooleanType XChopImage(Display *display,
2799 XResourceInfo *resource_info,XWindows *windows,
Image **image)
2811 direction = HorizontalChopCommand;
2813 static const ModeType
2816 ChopDirectionCommand,
2820 DirectionCommands[] =
2822 HorizontalChopCommand,
2827 text[MaxTextExtent];
2860 (void) CloneString(&windows->command.name,
"Chop");
2861 windows->command.data=1;
2862 (void) XCommandWidget(display,windows,ChopMenu,(XEvent *) NULL);
2863 (void) XMapRaised(display,windows->command.id);
2864 XClientMessage(display,windows->image.id,windows->im_protocols,
2865 windows->im_update_widget,CurrentTime);
2869 XQueryPosition(display,windows->image.id,&x,&y);
2870 (void) XSelectInput(display,windows->image.id,
2871 windows->image.attributes.event_mask | PointerMotionMask);
2873 (void) memset(&segment_info,0,
sizeof(segment_info));
2876 if (windows->info.mapped != MagickFalse)
2881 (void) FormatLocaleString(text,MaxTextExtent,
" %+d%+d ",
2882 x+windows->image.x,y+windows->image.y);
2883 XInfoWidget(display,windows,text);
2888 XScreenEvent(display,windows,&event);
2889 if (event.xany.window == windows->command.id)
2894 id=XCommandWidget(display,windows,ChopMenu,&event);
2897 switch (ChopCommands[
id])
2899 case ChopDirectionCommand:
2902 command[MaxTextExtent];
2905 *
const Directions[] =
2915 id=XMenuWidget(display,windows,ChopMenu[
id],Directions,command);
2917 direction=DirectionCommands[id];
2920 case ChopHelpCommand:
2922 XTextViewHelp(display,resource_info,windows,MagickFalse,
2923 "Help Viewer - Image Chop",ImageChopHelp);
2926 case ChopDismissCommand:
2944 if (event.xbutton.button != Button1)
2946 if (event.xbutton.window != windows->image.id)
2951 segment_info.x1=(
short int) event.xbutton.x;
2952 segment_info.x2=(
short int)
event.xbutton.x;
2953 segment_info.y1=(
short int) event.xbutton.y;
2954 segment_info.y2=(
short int)
event.xbutton.y;
2965 command[MaxTextExtent];
2970 if (event.xkey.window != windows->image.id)
2975 (void) XLookupString((XKeyEvent *) &
event.xkey,command,(int)
2976 sizeof(command),&key_symbol,(XComposeStatus *) NULL);
2977 switch ((
int) key_symbol)
2992 (void) XSetFunction(display,windows->image.highlight_context,
2994 XTextViewHelp(display,resource_info,windows,MagickFalse,
2995 "Help Viewer - Image Chop",ImageChopHelp);
2996 (void) XSetFunction(display,windows->image.highlight_context,
3002 (void) XBell(display,0);
3015 if (windows->info.mapped != MagickFalse)
3017 if ((x < (
int) (windows->info.x+windows->info.width)) &&
3018 (y < (int) (windows->info.y+windows->info.height)))
3019 (void) XWithdrawWindow(display,windows->info.id,
3020 windows->info.screen);
3023 if ((x > (
int) (windows->info.x+windows->info.width)) ||
3024 (y > (int) (windows->info.y+windows->info.height)))
3025 (void) XMapWindow(display,windows->info.id);
3028 }
while ((state & ExitState) == 0);
3029 (void) XSelectInput(display,windows->image.id,
3030 windows->image.attributes.event_mask);
3031 (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
3032 if ((state & EscapeState) != 0)
3042 (void) XSetFunction(display,windows->image.highlight_context,GXinvert);
3051 if (windows->info.mapped == MagickFalse)
3052 (void) XMapWindow(display,windows->info.id);
3053 (void) FormatLocaleString(text,MaxTextExtent,
3054 " %.20gx%.20g%+.20g%+.20g",(
double) chop_info.width,(double)
3055 chop_info.height,(
double) chop_info.x,(double) chop_info.y);
3056 XInfoWidget(display,windows,text);
3057 XHighlightLine(display,windows->image.id,
3058 windows->image.highlight_context,&segment_info);
3061 if (windows->info.mapped != MagickFalse)
3062 (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
3066 XScreenEvent(display,windows,&event);
3068 XHighlightLine(display,windows->image.id,
3069 windows->image.highlight_context,&segment_info);
3074 segment_info.x2=(
short int) event.xmotion.x;
3075 segment_info.y2=(
short int)
event.xmotion.y;
3083 segment_info.x2=(
short int) event.xbutton.x;
3084 segment_info.y2=(
short int)
event.xbutton.y;
3092 segment_info.x2=(
short int) event.xmotion.x;
3093 segment_info.y2=(
short int)
event.xmotion.y;
3101 if (segment_info.x2 < 0)
3104 if (segment_info.x2 > windows->image.ximage->width)
3105 segment_info.x2=windows->image.ximage->width;
3106 if (segment_info.y2 < 0)
3109 if (segment_info.y2 > windows->image.ximage->height)
3110 segment_info.y2=windows->image.ximage->height;
3111 distance=(
unsigned int)
3112 (((segment_info.x2-segment_info.x1)*(segment_info.x2-segment_info.x1))+
3113 ((segment_info.y2-segment_info.y1)*(segment_info.y2-segment_info.y1)));
3117 if (direction == HorizontalChopCommand)
3119 chop_info.width=(size_t) (segment_info.x2-segment_info.x1+1);
3120 chop_info.x=(ssize_t) windows->image.x+segment_info.x1;
3123 if (segment_info.x1 > (
int) segment_info.x2)
3125 chop_info.width=(size_t) (segment_info.x1-segment_info.x2+1);
3126 chop_info.x=(ssize_t) windows->image.x+segment_info.x2;
3132 chop_info.height=(size_t) (segment_info.y2-segment_info.y1+1);
3134 chop_info.y=(ssize_t) windows->image.y+segment_info.y1;
3135 if (segment_info.y1 > segment_info.y2)
3137 chop_info.height=(size_t) (segment_info.y1-segment_info.y2+1);
3138 chop_info.y=(ssize_t) windows->image.y+segment_info.y2;
3141 }
while ((state & ExitState) == 0);
3142 (void) XSetFunction(display,windows->image.highlight_context,GXcopy);
3143 (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
3149 (void) XMagickCommand(display,resource_info,windows,ApplyCommand,image);
3150 XSetCursorState(display,windows,MagickTrue);
3151 XCheckRefreshWindows(display,windows);
3152 windows->image.window_changes.width=windows->image.ximage->width-
3153 (
unsigned int) chop_info.width;
3154 windows->image.window_changes.height=windows->image.ximage->height-
3155 (
unsigned int) chop_info.height;
3156 width=(
unsigned int) (*image)->columns;
3157 height=(
unsigned int) (*image)->rows;
3160 if (windows->image.crop_geometry != (
char *) NULL)
3161 (
void) XParseGeometry(windows->image.crop_geometry,&x,&y,&width,&height);
3162 scale_factor=(MagickRealType) width/windows->image.ximage->width;
3164 chop_info.x=(ssize_t) (scale_factor*chop_info.x+0.5);
3165 chop_info.width=(
unsigned int) (scale_factor*chop_info.width+0.5);
3166 scale_factor=(MagickRealType) height/windows->image.ximage->height;
3168 chop_info.y=(ssize_t) (scale_factor*chop_info.y+0.5);
3169 chop_info.height=(
unsigned int) (scale_factor*chop_info.height+0.5);
3173 chop_image=ChopImage(*image,&chop_info,&(*image)->exception);
3174 XSetCursorState(display,windows,MagickFalse);
3175 if (chop_image == (
Image *) NULL)
3176 return(MagickFalse);
3177 *image=DestroyImage(*image);
3182 XConfigureImageColormap(display,resource_info,windows,*image);
3183 (void) XConfigureImage(display,resource_info,windows,*image);
3220 static MagickBooleanType XColorEditImage(Display *display,
3221 XResourceInfo *resource_info,XWindows *windows,
Image **image)
3224 *
const ColorEditMenu[] =
3236 static const ModeType
3237 ColorEditCommands[] =
3239 ColorEditMethodCommand,
3240 ColorEditColorCommand,
3241 ColorEditBorderCommand,
3242 ColorEditFuzzCommand,
3243 ColorEditUndoCommand,
3244 ColorEditHelpCommand,
3245 ColorEditDismissCommand
3249 method = PointMethod;
3255 border_color = { 0, 0, 0, 0, 0, 0 };
3258 command[MaxTextExtent] =
"",
3259 text[MaxTextExtent] =
"";
3297 (void) CloneString(&windows->command.name,
"Color Edit");
3298 windows->command.data=4;
3299 (void) XCommandWidget(display,windows,ColorEditMenu,(XEvent *) NULL);
3300 (void) XMapRaised(display,windows->command.id);
3301 XClientMessage(display,windows->image.id,windows->im_protocols,
3302 windows->im_update_widget,CurrentTime);
3306 cursor=XMakeCursor(display,windows->image.id,windows->map_info->colormap,
3307 resource_info->background_color,resource_info->foreground_color);
3308 (void) XCheckDefineCursor(display,windows->image.id,cursor);
3312 XQueryPosition(display,windows->image.id,&x,&y);
3313 (void) XSelectInput(display,windows->image.id,
3314 windows->image.attributes.event_mask | PointerMotionMask);
3318 if (windows->info.mapped != MagickFalse)
3323 (void) FormatLocaleString(text,MaxTextExtent,
" %+d%+d ",
3324 x+windows->image.x,y+windows->image.y);
3325 XInfoWidget(display,windows,text);
3330 XScreenEvent(display,windows,&event);
3331 if (event.xany.window == windows->command.id)
3336 id=XCommandWidget(display,windows,ColorEditMenu,&event);
3339 (void) XCheckDefineCursor(display,windows->image.id,cursor);
3342 switch (ColorEditCommands[
id])
3344 case ColorEditMethodCommand:
3352 methods=(
char **) GetCommandOptions(MagickMethodOptions);
3353 if (methods == (
char **) NULL)
3355 entry=XMenuWidget(display,windows,ColorEditMenu[
id],
3356 (
const char **) methods,command);
3358 method=(PaintMethod) ParseCommandOption(MagickMethodOptions,
3359 MagickFalse,methods[entry]);
3360 methods=DestroyStringList(methods);
3363 case ColorEditColorCommand:
3366 *ColorMenu[MaxNumberPens];
3374 for (i=0; i < (int) (MaxNumberPens-2); i++)
3375 ColorMenu[i]=resource_info->pen_colors[i];
3376 ColorMenu[MaxNumberPens-2]=
"Browser...";
3377 ColorMenu[MaxNumberPens-1]=(
const char *) NULL;
3381 pen_number=XMenuWidget(display,windows,ColorEditMenu[
id],
3382 (
const char **) ColorMenu,command);
3385 if (pen_number == (MaxNumberPens-2))
3388 color_name[MaxTextExtent] =
"gray";
3393 resource_info->pen_colors[pen_number]=color_name;
3394 XColorBrowserWidget(display,windows,
"Select",color_name);
3395 if (*color_name ==
'\0')
3401 (void) XParseColor(display,windows->map_info->colormap,
3402 resource_info->pen_colors[pen_number],&color);
3403 XBestPixel(display,windows->map_info->colormap,(XColor *) NULL,
3404 (
unsigned int) MaxColors,&color);
3405 windows->pixel_info->pen_colors[pen_number]=color;
3406 pen_id=(
unsigned int) pen_number;
3409 case ColorEditBorderCommand:
3412 *ColorMenu[MaxNumberPens];
3420 for (i=0; i < (int) (MaxNumberPens-2); i++)
3421 ColorMenu[i]=resource_info->pen_colors[i];
3422 ColorMenu[MaxNumberPens-2]=
"Browser...";
3423 ColorMenu[MaxNumberPens-1]=(
const char *) NULL;
3427 pen_number=XMenuWidget(display,windows,ColorEditMenu[
id],
3428 (
const char **) ColorMenu,command);
3431 if (pen_number == (MaxNumberPens-2))
3434 color_name[MaxTextExtent] =
"gray";
3439 resource_info->pen_colors[pen_number]=color_name;
3440 XColorBrowserWidget(display,windows,
"Select",color_name);
3441 if (*color_name ==
'\0')
3447 (void) XParseColor(display,windows->map_info->colormap,
3448 resource_info->pen_colors[pen_number],&border_color);
3451 case ColorEditFuzzCommand:
3454 fuzz[MaxTextExtent];
3471 entry=XMenuWidget(display,windows,ColorEditMenu[
id],FuzzMenu,
3477 (*image)->fuzz=StringToDoubleInterval(FuzzMenu[entry],(
double)
3481 (void) (
void) CopyMagickString(fuzz,
"20%",MaxTextExtent);
3482 (void) XDialogWidget(display,windows,
"Ok",
3483 "Enter fuzz factor (0.0 - 99.9%):",fuzz);
3486 (void) ConcatenateMagickString(fuzz,
"%",MaxTextExtent);
3487 (*image)->fuzz=StringToDoubleInterval(fuzz,(
double) QuantumRange+
3491 case ColorEditUndoCommand:
3493 (void) XMagickCommand(display,resource_info,windows,UndoCommand,
3497 case ColorEditHelpCommand:
3500 XTextViewHelp(display,resource_info,windows,MagickFalse,
3501 "Help Viewer - Image Annotation",ImageColorEditHelp);
3504 case ColorEditDismissCommand:
3514 (void) XCheckDefineCursor(display,windows->image.id,cursor);
3521 if (event.xbutton.button != Button1)
3523 if ((event.xbutton.window != windows->image.id) &&
3524 (
event.xbutton.window != windows->magnify.id))
3531 (void) XMagickCommand(display,resource_info,windows,
3532 SaveToUndoBufferCommand,image);
3533 state|=UpdateConfigurationState;
3538 if (event.xbutton.button != Button1)
3540 if ((event.xbutton.window != windows->image.id) &&
3541 (
event.xbutton.window != windows->magnify.id))
3548 XConfigureImageColormap(display,resource_info,windows,*image);
3549 (void) XConfigureImage(display,resource_info,windows,*image);
3550 XInfoWidget(display,windows,text);
3551 (void) XCheckDefineCursor(display,windows->image.id,cursor);
3552 state&=(~UpdateConfigurationState);
3562 if (event.xkey.window == windows->magnify.id)
3567 window=windows->magnify.id;
3568 while (XCheckWindowEvent(display,window,KeyPressMask,&event)) ;
3570 if (event.xkey.window != windows->image.id)
3575 (void) XLookupString((XKeyEvent *) &
event.xkey,command,(int)
3576 sizeof(command),&key_symbol,(XComposeStatus *) NULL);
3577 switch ((
int) key_symbol)
3591 XTextViewHelp(display,resource_info,windows,MagickFalse,
3592 "Help Viewer - Image Annotation",ImageColorEditHelp);
3597 (void) XBell(display,0);
3610 if (windows->info.mapped != MagickFalse)
3612 if ((x < (
int) (windows->info.x+windows->info.width)) &&
3613 (y < (int) (windows->info.y+windows->info.height)))
3614 (void) XWithdrawWindow(display,windows->info.id,
3615 windows->info.screen);
3618 if ((x > (
int) (windows->info.x+windows->info.width)) ||
3619 (y > (int) (windows->info.y+windows->info.height)))
3620 (void) XMapWindow(display,windows->info.id);
3626 if (event.xany.window == windows->magnify.id)
3628 x=windows->magnify.x-windows->image.x;
3629 y=windows->magnify.y-windows->image.y;
3633 if ((state & UpdateConfigurationState) != 0)
3645 (void) XClearArea(display,windows->image.id,x_offset,y_offset,1,1,
3647 color=windows->pixel_info->pen_colors[pen_id];
3648 XPutPixel(windows->image.ximage,x_offset,y_offset,color.pixel);
3649 width=(
unsigned int) (*image)->columns;
3650 height=(
unsigned int) (*image)->rows;
3653 if (windows->image.crop_geometry != (
char *) NULL)
3654 (
void) XParseGeometry(windows->image.crop_geometry,&x,&y,
3657 (width*(windows->image.x+x_offset)/windows->image.ximage->width+x);
3659 (height*(windows->image.y+y_offset)/windows->image.ximage->height+y);
3660 if ((x_offset < 0) || (y_offset < 0))
3662 if ((x_offset >= (
int) (*image)->columns) ||
3663 (y_offset >= (
int) (*image)->rows))
3665 exception=(&(*image)->exception);
3666 image_view=AcquireAuthenticCacheView(*image,exception);
3675 if (SetImageStorageClass(*image,DirectClass) == MagickFalse)
3676 return(MagickFalse);
3677 q=GetCacheViewAuthenticPixels(image_view,(ssize_t)x_offset,
3678 (ssize_t)y_offset,1,1,exception);
3681 q->red=ScaleShortToQuantum(color.red);
3682 q->green=ScaleShortToQuantum(color.green);
3683 q->blue=ScaleShortToQuantum(color.blue);
3684 (void) SyncCacheViewAuthenticPixels(image_view,
3685 &(*image)->exception);
3696 (void) GetOneCacheViewVirtualPixel(image_view,(ssize_t) x_offset,
3697 (ssize_t) y_offset,&target,&(*image)->exception);
3698 if ((*image)->storage_class == DirectClass)
3700 for (y=0; y < (int) (*image)->rows; y++)
3702 q=GetCacheViewAuthenticPixels(image_view,0,(ssize_t) y,
3703 (*image)->columns,1,exception);
3706 for (x=0; x < (int) (*image)->columns; x++)
3708 if (IsColorSimilar(*image,q,&target) != MagickFalse)
3710 q->red=ScaleShortToQuantum(color.red);
3711 q->green=ScaleShortToQuantum(color.green);
3712 q->blue=ScaleShortToQuantum(color.blue);
3716 if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
3722 for (i=0; i < (ssize_t) (*image)->colors; i++)
3723 if (IsColorSimilar(*image,(*image)->colormap+i,&target) != MagickFalse)
3725 (*image)->colormap[i].red=ScaleShortToQuantum(color.red);
3726 (*image)->colormap[i].green=ScaleShortToQuantum(
3728 (*image)->colormap[i].blue=ScaleShortToQuantum(
3731 (void) SyncImage(*image);
3735 case FloodfillMethod:
3736 case FillToBorderMethod:
3747 (void) GetOneVirtualMagickPixel(*image,(ssize_t) x_offset,
3748 (ssize_t) y_offset,&target,exception);
3749 if (method == FillToBorderMethod)
3751 target.red=(MagickRealType)
3752 ScaleShortToQuantum(border_color.red);
3753 target.green=(MagickRealType)
3754 ScaleShortToQuantum(border_color.green);
3755 target.blue=(MagickRealType)
3756 ScaleShortToQuantum(border_color.blue);
3758 draw_info=CloneDrawInfo(resource_info->image_info,
3760 (void) QueryColorDatabase(resource_info->pen_colors[pen_id],
3761 &draw_info->fill,exception);
3762 (void) FloodfillPaintImage(*image,DefaultChannels,draw_info,&target,
3763 (ssize_t) x_offset,(ssize_t) y_offset,
3764 method == FloodfillMethod ? MagickFalse : MagickTrue);
3765 draw_info=DestroyDrawInfo(draw_info);
3773 if (SetImageStorageClass(*image,DirectClass) == MagickFalse)
3774 return(MagickFalse);
3775 for (y=0; y < (int) (*image)->rows; y++)
3777 q=QueueCacheViewAuthenticPixels(image_view,0,(ssize_t) y,
3778 (*image)->columns,1,exception);
3781 for (x=0; x < (int) (*image)->columns; x++)
3783 q->red=ScaleShortToQuantum(color.red);
3784 q->green=ScaleShortToQuantum(color.green);
3785 q->blue=ScaleShortToQuantum(color.blue);
3788 if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
3794 image_view=DestroyCacheView(image_view);
3795 state&=(~UpdateConfigurationState);
3797 }
while ((state & ExitState) == 0);
3798 (void) XSelectInput(display,windows->image.id,
3799 windows->image.attributes.event_mask);
3800 XSetCursorState(display,windows,MagickFalse);
3801 (void) XFreeCursor(display,cursor);
3837 static MagickBooleanType XCompositeImage(Display *display,
3838 XResourceInfo *resource_info,XWindows *windows,
Image *image)
3841 *
const CompositeMenu[] =
3852 displacement_geometry[MaxTextExtent] =
"30x30",
3853 filename[MaxTextExtent] =
"\0";
3855 static CompositeOperator
3856 compose = CopyCompositeOp;
3858 static const ModeType
3859 CompositeCommands[] =
3861 CompositeOperatorsCommand,
3862 CompositeDissolveCommand,
3863 CompositeDisplaceCommand,
3864 CompositeHelpCommand,
3865 CompositeDismissCommand
3869 text[MaxTextExtent];
3904 XFileBrowserWidget(display,windows,
"Composite",filename);
3905 if (*filename ==
'\0')
3910 XSetCursorState(display,windows,MagickTrue);
3911 XCheckRefreshWindows(display,windows);
3912 (void) CopyMagickString(resource_info->image_info->filename,filename,
3914 composite_image=ReadImage(resource_info->image_info,&image->exception);
3915 CatchException(&image->exception);
3916 XSetCursorState(display,windows,MagickFalse);
3917 if (composite_image == (
Image *) NULL)
3918 return(MagickFalse);
3922 (void) CloneString(&windows->command.name,
"Composite");
3923 windows->command.data=1;
3924 (void) XCommandWidget(display,windows,CompositeMenu,(XEvent *) NULL);
3925 (void) XMapRaised(display,windows->command.id);
3926 XClientMessage(display,windows->image.id,windows->im_protocols,
3927 windows->im_update_widget,CurrentTime);
3931 XQueryPosition(display,windows->image.id,&x,&y);
3932 (void) XSelectInput(display,windows->image.id,
3933 windows->image.attributes.event_mask | PointerMotionMask);
3934 composite_info.x=(ssize_t) windows->image.x+x;
3935 composite_info.y=(ssize_t) windows->image.y+y;
3936 composite_info.width=0;
3937 composite_info.height=0;
3938 cursor=XCreateFontCursor(display,XC_ul_angle);
3939 (void) XSetFunction(display,windows->image.highlight_context,GXinvert);
3944 if (windows->info.mapped != MagickFalse)
3949 (void) FormatLocaleString(text,MaxTextExtent,
" %+ld%+ld ",
3950 (
long) composite_info.x,(long) composite_info.y);
3951 XInfoWidget(display,windows,text);
3953 highlight_info=composite_info;
3954 highlight_info.x=composite_info.x-windows->image.x;
3955 highlight_info.y=composite_info.y-windows->image.y;
3956 XHighlightRectangle(display,windows->image.id,
3957 windows->image.highlight_context,&highlight_info);
3961 XScreenEvent(display,windows,&event);
3962 XHighlightRectangle(display,windows->image.id,
3963 windows->image.highlight_context,&highlight_info);
3964 if (event.xany.window == windows->command.id)
3969 id=XCommandWidget(display,windows,CompositeMenu,&event);
3972 switch (CompositeCommands[
id])
3974 case CompositeOperatorsCommand:
3977 command[MaxTextExtent],
3983 operators=GetCommandOptions(MagickComposeOptions);
3984 if (operators == (
char **) NULL)
3986 entry=XMenuWidget(display,windows,CompositeMenu[
id],
3987 (
const char **) operators,command);
3989 compose=(CompositeOperator) ParseCommandOption(
3990 MagickComposeOptions,MagickFalse,operators[entry]);
3991 operators=DestroyStringList(operators);
3994 case CompositeDissolveCommand:
3997 factor[MaxTextExtent] =
"20.0";
4002 (void) XSetFunction(display,windows->image.highlight_context,
4004 (void) XDialogWidget(display,windows,
"Dissolve",
4005 "Enter the blend factor (0.0 - 99.9%):",factor);
4006 (void) XSetFunction(display,windows->image.highlight_context,
4008 if (*factor ==
'\0')
4010 blend=StringToDouble(factor,(
char **) NULL);
4011 compose=DissolveCompositeOp;
4014 case CompositeDisplaceCommand:
4019 (void) XSetFunction(display,windows->image.highlight_context,
4021 (void) XDialogWidget(display,windows,
"Displace",
4022 "Enter the horizontal and vertical scale:",displacement_geometry);
4023 (void) XSetFunction(display,windows->image.highlight_context,
4025 if (*displacement_geometry ==
'\0')
4027 compose=DisplaceCompositeOp;
4030 case CompositeHelpCommand:
4032 (void) XSetFunction(display,windows->image.highlight_context,
4034 XTextViewHelp(display,resource_info,windows,MagickFalse,
4035 "Help Viewer - Image Composite",ImageCompositeHelp);
4036 (void) XSetFunction(display,windows->image.highlight_context,
4040 case CompositeDismissCommand:
4058 if (resource_info->debug != MagickFalse)
4059 (void) LogMagickEvent(X11Event,GetMagickModule(),
4060 "Button Press: 0x%lx %u +%d+%d",
event.xbutton.window,
4061 event.xbutton.button,
event.xbutton.x,
event.xbutton.y);
4062 if (event.xbutton.button != Button1)
4064 if (event.xbutton.window != windows->image.id)
4069 composite_info.width=composite_image->columns;
4070 composite_info.height=composite_image->rows;
4071 (void) XCheckDefineCursor(display,windows->image.id,cursor);
4072 composite_info.x=(ssize_t) windows->image.x+event.xbutton.x;
4073 composite_info.y=(ssize_t) windows->image.y+
event.xbutton.y;
4078 if (resource_info->debug != MagickFalse)
4079 (void) LogMagickEvent(X11Event,GetMagickModule(),
4080 "Button Release: 0x%lx %u +%d+%d",
event.xbutton.window,
4081 event.xbutton.button,
event.xbutton.x,
event.xbutton.y);
4082 if (event.xbutton.button != Button1)
4084 if (event.xbutton.window != windows->image.id)
4086 if ((composite_info.width != 0) && (composite_info.height != 0))
4091 composite_info.x=(ssize_t) windows->image.x+event.xbutton.x;
4092 composite_info.y=(ssize_t) windows->image.y+
event.xbutton.y;
4102 command[MaxTextExtent];
4110 if (event.xkey.window != windows->image.id)
4115 length=XLookupString((XKeyEvent *) &event.xkey,command,(
int)
4116 sizeof(command),&key_symbol,(XComposeStatus *) NULL);
4117 *(command+length)=
'\0';
4118 if (resource_info->debug != MagickFalse)
4119 (void) LogMagickEvent(X11Event,GetMagickModule(),
4120 "Key press: 0x%lx (%s)",(
unsigned long) key_symbol,command);
4121 switch ((
int) key_symbol)
4129 composite_image=DestroyImage(composite_image);
4137 (void) XSetFunction(display,windows->image.highlight_context,
4139 XTextViewHelp(display,resource_info,windows,MagickFalse,
4140 "Help Viewer - Image Composite",ImageCompositeHelp);
4141 (void) XSetFunction(display,windows->image.highlight_context,
4147 (void) XBell(display,0);
4160 if (windows->info.mapped != MagickFalse)
4162 if ((x < (
int) (windows->info.x+windows->info.width)) &&
4163 (y < (int) (windows->info.y+windows->info.height)))
4164 (void) XWithdrawWindow(display,windows->info.id,
4165 windows->info.screen);
4168 if ((x > (
int) (windows->info.x+windows->info.width)) ||
4169 (y > (int) (windows->info.y+windows->info.height)))
4170 (void) XMapWindow(display,windows->info.id);
4171 composite_info.x=(ssize_t) windows->image.x+x;
4172 composite_info.y=(ssize_t) windows->image.y+y;
4177 if (resource_info->debug != MagickFalse)
4178 (void) LogMagickEvent(X11Event,GetMagickModule(),
"Event type: %d",
4183 }
while ((state & ExitState) == 0);
4184 (void) XSelectInput(display,windows->image.id,
4185 windows->image.attributes.event_mask);
4186 (void) XSetFunction(display,windows->image.highlight_context,GXcopy);
4187 XSetCursorState(display,windows,MagickFalse);
4188 (void) XFreeCursor(display,cursor);
4189 if ((state & EscapeState) != 0)
4194 XSetCursorState(display,windows,MagickTrue);
4195 XCheckRefreshWindows(display,windows);
4196 width=(
unsigned int) image->columns;
4197 height=(
unsigned int) image->rows;
4200 if (windows->image.crop_geometry != (
char *) NULL)
4201 (
void) XParseGeometry(windows->image.crop_geometry,&x,&y,&width,&height);
4202 scale_factor=(MagickRealType) width/windows->image.ximage->width;
4203 composite_info.x+=x;
4204 composite_info.x=(ssize_t) (scale_factor*composite_info.x+0.5);
4205 composite_info.width=(
unsigned int) (scale_factor*composite_info.width+0.5);
4206 scale_factor=(MagickRealType) height/windows->image.ximage->height;
4207 composite_info.y+=y;
4208 composite_info.y=(ssize_t) (scale_factor*composite_info.y+0.5);
4209 composite_info.height=(
unsigned int) (scale_factor*composite_info.height+0.5);
4210 if ((composite_info.width != composite_image->columns) ||
4211 (composite_info.height != composite_image->rows))
4219 resize_image=ResizeImage(composite_image,composite_info.width,
4220 composite_info.height,composite_image->filter,composite_image->blur,
4222 composite_image=DestroyImage(composite_image);
4223 if (resize_image == (
Image *) NULL)
4225 XSetCursorState(display,windows,MagickFalse);
4226 return(MagickFalse);
4228 composite_image=resize_image;
4230 if (compose == DisplaceCompositeOp)
4231 (void) SetImageArtifact(composite_image,
"compose:args",
4232 displacement_geometry);
4256 (void) SetImageAlphaChannel(composite_image,OpaqueAlphaChannel);
4257 opacity=(Quantum) (ScaleQuantumToChar(QuantumRange)-
4258 ((ssize_t) ScaleQuantumToChar(QuantumRange)*blend)/100);
4259 if (SetImageStorageClass(image,DirectClass) == MagickFalse)
4260 return(MagickFalse);
4261 image->matte=MagickTrue;
4262 exception=(&image->exception);
4263 image_view=AcquireAuthenticCacheView(image,exception);
4264 for (y=0; y < (int) image->rows; y++)
4266 q=GetCacheViewAuthenticPixels(image_view,0,(ssize_t) y,image->columns,1,
4270 for (x=0; x < (int) image->columns; x++)
4275 if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
4278 image_view=DestroyCacheView(image_view);
4283 (void) CompositeImage(image,compose,composite_image,composite_info.x,
4285 composite_image=DestroyImage(composite_image);
4286 XSetCursorState(display,windows,MagickFalse);
4290 XConfigureImageColormap(display,resource_info,windows,image);
4291 (void) XConfigureImage(display,resource_info,windows,image);
4327 static MagickBooleanType XConfigureImage(Display *display,
4328 XResourceInfo *resource_info,XWindows *windows,
Image *image)
4331 geometry[MaxTextExtent];
4354 width=(
unsigned int) windows->image.window_changes.width;
4355 height=(
unsigned int) windows->image.window_changes.height;
4356 if (resource_info->debug != MagickFalse)
4357 (void) LogMagickEvent(X11Event,GetMagickModule(),
4358 "Configure Image: %dx%d=>%.20gx%.20g",windows->image.ximage->width,
4359 windows->image.ximage->height,(double) width,(
double) height);
4360 if ((width*height) == 0)
4367 XSetCursorState(display,windows,MagickTrue);
4368 (void) XFlush(display);
4369 if (((
int) width != windows->image.ximage->width) ||
4370 ((int) height != windows->image.ximage->height))
4371 image->taint=MagickTrue;
4372 windows->magnify.x=(
int)
4373 width*windows->magnify.x/windows->image.ximage->width;
4374 windows->magnify.y=(int)
4375 height*windows->magnify.y/windows->image.ximage->height;
4376 windows->image.x=(
int) (width*windows->image.x/windows->image.ximage->width);
4377 windows->image.y=(int)
4378 (height*windows->image.y/windows->image.ximage->height);
4379 status=XMakeImage(display,resource_info,&windows->image,image,
4380 (
unsigned int) width,(
unsigned int) height);
4381 if (status == MagickFalse)
4382 XNoticeWidget(display,windows,
"Unable to configure X image:",
4383 windows->image.name);
4387 if (resource_info->image_geometry != (
char *) NULL)
4388 (void) FormatLocaleString(geometry,MaxTextExtent,
"%s>!",
4389 resource_info->image_geometry);
4391 (
void) FormatLocaleString(geometry,MaxTextExtent,
"%ux%u+0+0>!",
4392 XDisplayWidth(display,windows->image.screen),
4393 XDisplayHeight(display,windows->image.screen));
4394 (void) ParseMetaGeometry(geometry,&x,&y,&width,&height);
4395 window_changes.width=(int) width;
4396 if (window_changes.width > XDisplayWidth(display,windows->image.screen))
4397 window_changes.width=XDisplayWidth(display,windows->image.screen);
4398 window_changes.height=(int) height;
4399 if (window_changes.height > XDisplayHeight(display,windows->image.screen))
4400 window_changes.height=XDisplayHeight(display,windows->image.screen);
4401 mask=(size_t) (CWWidth | CWHeight);
4402 if (resource_info->backdrop)
4405 window_changes.x=(int)
4406 ((XDisplayWidth(display,windows->image.screen)/2)-(width/2));
4407 window_changes.y=(int)
4408 ((XDisplayHeight(display,windows->image.screen)/2)-(height/2));
4410 (void) XReconfigureWMWindow(display,windows->image.id,windows->image.screen,
4411 (
unsigned int) mask,&window_changes);
4412 (void) XClearWindow(display,windows->image.id);
4413 XRefreshWindow(display,&windows->image,(XEvent *) NULL);
4417 if (windows->magnify.mapped != MagickFalse)
4418 XMakeMagnifyImage(display,windows);
4419 windows->pan.crop_geometry=windows->image.crop_geometry;
4420 XBestIconSize(display,&windows->pan,image);
4421 while (((windows->pan.width << 1) < MaxIconSize) &&
4422 ((windows->pan.height << 1) < MaxIconSize))
4424 windows->pan.width<<=1;
4425 windows->pan.height<<=1;
4427 if (windows->pan.geometry != (
char *) NULL)
4428 (void) XParseGeometry(windows->pan.geometry,&windows->pan.x,&windows->pan.y,
4429 &windows->pan.width,&windows->pan.height);
4430 window_changes.width=(int) windows->pan.width;
4431 window_changes.height=(
int) windows->pan.height;
4432 size_hints=XAllocSizeHints();
4433 if (size_hints != (XSizeHints *) NULL)
4438 size_hints->flags=PSize | PMinSize | PMaxSize;
4439 size_hints->width=window_changes.width;
4440 size_hints->height=window_changes.height;
4441 size_hints->min_width=size_hints->width;
4442 size_hints->min_height=size_hints->height;
4443 size_hints->max_width=size_hints->width;
4444 size_hints->max_height=size_hints->height;
4445 (void) XSetNormalHints(display,windows->pan.id,size_hints);
4446 (void) XFree((
void *) size_hints);
4448 (void) XReconfigureWMWindow(display,windows->pan.id,windows->pan.screen,
4449 (
unsigned int) (CWWidth | CWHeight),&window_changes);
4453 windows->icon.crop_geometry=windows->image.crop_geometry;
4454 XBestIconSize(display,&windows->icon,image);
4455 window_changes.width=(int) windows->icon.width;
4456 window_changes.height=(
int) windows->icon.height;
4457 (void) XReconfigureWMWindow(display,windows->icon.id,windows->icon.screen,
4458 (
unsigned int) (CWWidth | CWHeight),&window_changes);
4459 XSetCursorState(display,windows,MagickFalse);
4460 return(status != 0 ? MagickTrue : MagickFalse);
4499 static MagickBooleanType XCropImage(Display *display,
4500 XResourceInfo *resource_info,XWindows *windows,
Image *image,
4501 const ClipboardMode mode)
4510 *RectifyModeMenu[] =
4518 static const ModeType
4528 RectifyDismissCommand
4535 command[MaxTextExtent],
4536 text[MaxTextExtent];
4582 (void) CloneString(&windows->command.name,
"Copy");
4587 (void) CloneString(&windows->command.name,
"Crop");
4592 (void) CloneString(&windows->command.name,
"Cut");
4596 RectifyModeMenu[0]=windows->command.name;
4597 windows->command.data=0;
4598 (void) XCommandWidget(display,windows,CropModeMenu,(XEvent *) NULL);
4599 (void) XMapRaised(display,windows->command.id);
4600 XClientMessage(display,windows->image.id,windows->im_protocols,
4601 windows->im_update_widget,CurrentTime);
4605 XQueryPosition(display,windows->image.id,&x,&y);
4606 (void) XSelectInput(display,windows->image.id,
4607 windows->image.attributes.event_mask | PointerMotionMask);
4608 crop_info.x=(ssize_t) windows->image.x+x;
4609 crop_info.y=(ssize_t) windows->image.y+y;
4612 cursor=XCreateFontCursor(display,XC_fleur);
4616 if (windows->info.mapped != MagickFalse)
4621 (void) FormatLocaleString(text,MaxTextExtent,
" %+ld%+ld ",
4622 (
long) crop_info.x,(long) crop_info.y);
4623 XInfoWidget(display,windows,text);
4628 XScreenEvent(display,windows,&event);
4629 if (event.xany.window == windows->command.id)
4634 id=XCommandWidget(display,windows,CropModeMenu,&event);
4637 switch (CropCommands[
id])
4639 case CropHelpCommand:
4645 XTextViewHelp(display,resource_info,windows,MagickFalse,
4646 "Help Viewer - Image Copy",ImageCopyHelp);
4651 XTextViewHelp(display,resource_info,windows,MagickFalse,
4652 "Help Viewer - Image Crop",ImageCropHelp);
4657 XTextViewHelp(display,resource_info,windows,MagickFalse,
4658 "Help Viewer - Image Cut",ImageCutHelp);
4664 case CropDismissCommand:
4682 if (event.xbutton.button != Button1)
4684 if (event.xbutton.window != windows->image.id)
4689 (void) XCheckDefineCursor(display,windows->image.id,cursor);
4690 crop_info.x=(ssize_t) windows->image.x+event.xbutton.x;
4691 crop_info.y=(ssize_t) windows->image.y+
event.xbutton.y;
4701 if (event.xkey.window != windows->image.id)
4706 (void) XLookupString((XKeyEvent *) &
event.xkey,command,(int)
4707 sizeof(command),&key_symbol,(XComposeStatus *) NULL);
4708 switch ((
int) key_symbol)
4727 XTextViewHelp(display,resource_info,windows,MagickFalse,
4728 "Help Viewer - Image Copy",ImageCopyHelp);
4733 XTextViewHelp(display,resource_info,windows,MagickFalse,
4734 "Help Viewer - Image Crop",ImageCropHelp);
4739 XTextViewHelp(display,resource_info,windows,MagickFalse,
4740 "Help Viewer - Image Cut",ImageCutHelp);
4748 (void) XBell(display,0);
4756 if (event.xmotion.window != windows->image.id)
4763 if (windows->info.mapped != MagickFalse)
4765 if ((x < (
int) (windows->info.x+windows->info.width)) &&
4766 (y < (int) (windows->info.y+windows->info.height)))
4767 (void) XWithdrawWindow(display,windows->info.id,
4768 windows->info.screen);
4771 if ((x > (
int) (windows->info.x+windows->info.width)) ||
4772 (y > (int) (windows->info.y+windows->info.height)))
4773 (void) XMapWindow(display,windows->info.id);
4774 crop_info.x=(ssize_t) windows->image.x+x;
4775 crop_info.y=(ssize_t) windows->image.y+y;
4781 }
while ((state & ExitState) == 0);
4782 (void) XSelectInput(display,windows->image.id,
4783 windows->image.attributes.event_mask);
4784 if ((state & EscapeState) != 0)
4789 (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
4790 (void) XFreeCursor(display,cursor);
4793 (void) XSetFunction(display,windows->image.highlight_context,GXinvert);
4799 x=(int) crop_info.x;
4800 y=(
int) crop_info.y;
4806 highlight_info=crop_info;
4807 highlight_info.x=crop_info.x-windows->image.x;
4808 highlight_info.y=crop_info.y-windows->image.y;
4809 if ((highlight_info.width > 3) && (highlight_info.height > 3))
4814 if (windows->info.mapped == MagickFalse)
4815 (void) XMapWindow(display,windows->info.id);
4816 (void) FormatLocaleString(text,MaxTextExtent,
4817 " %.20gx%.20g%+.20g%+.20g",(
double) crop_info.width,(double)
4818 crop_info.height,(
double) crop_info.x,(double) crop_info.y);
4819 XInfoWidget(display,windows,text);
4820 XHighlightRectangle(display,windows->image.id,
4821 windows->image.highlight_context,&highlight_info);
4824 if (windows->info.mapped != MagickFalse)
4825 (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
4829 XScreenEvent(display,windows,&event);
4830 if ((highlight_info.width > 3) && (highlight_info.height > 3))
4831 XHighlightRectangle(display,windows->image.id,
4832 windows->image.highlight_context,&highlight_info);
4837 crop_info.x=(ssize_t) windows->image.x+event.xbutton.x;
4838 crop_info.y=(ssize_t) windows->image.y+
event.xbutton.y;
4846 crop_info.x=(ssize_t) windows->image.x+event.xbutton.x;
4847 crop_info.y=(ssize_t) windows->image.y+
event.xbutton.y;
4848 XSetCursorState(display,windows,MagickFalse);
4850 windows->command.data=0;
4851 (void) XCommandWidget(display,windows,RectifyModeMenu,
4859 crop_info.x=(ssize_t) windows->image.x+event.xmotion.x;
4860 crop_info.y=(ssize_t) windows->image.y+
event.xmotion.y;
4865 if ((((
int) crop_info.x != x) && ((int) crop_info.y != y)) ||
4866 ((state & ExitState) != 0))
4871 if (crop_info.x < 0)
4874 if (crop_info.x > (ssize_t) windows->image.ximage->width)
4875 crop_info.x=(ssize_t) windows->image.ximage->width;
4876 if ((
int) crop_info.x < x)
4877 crop_info.width=(
unsigned int) (x-crop_info.x);
4880 crop_info.width=(
unsigned int) (crop_info.x-x);
4881 crop_info.x=(ssize_t) x;
4883 if (crop_info.y < 0)
4886 if (crop_info.y > (ssize_t) windows->image.ximage->height)
4887 crop_info.y=(ssize_t) windows->image.ximage->height;
4888 if ((
int) crop_info.y < y)
4889 crop_info.height=(
unsigned int) (y-crop_info.y);
4892 crop_info.height=(
unsigned int) (crop_info.y-y);
4893 crop_info.y=(ssize_t) y;
4896 }
while ((state & ExitState) == 0);
4901 (void) XMapWindow(display,windows->info.id);
4904 if (windows->info.mapped != MagickFalse)
4909 (void) FormatLocaleString(text,MaxTextExtent,
4910 " %.20gx%.20g%+.20g%+.20g",(
double) crop_info.width,(double)
4911 crop_info.height,(
double) crop_info.x,(double) crop_info.y);
4912 XInfoWidget(display,windows,text);
4914 highlight_info=crop_info;
4915 highlight_info.x=crop_info.x-windows->image.x;
4916 highlight_info.y=crop_info.y-windows->image.y;
4917 if ((highlight_info.width <= 3) || (highlight_info.height <= 3))
4923 XHighlightRectangle(display,windows->image.id,
4924 windows->image.highlight_context,&highlight_info);
4925 XScreenEvent(display,windows,&event);
4926 if (event.xany.window == windows->command.id)
4931 (void) XSetFunction(display,windows->image.highlight_context,GXcopy);
4932 id=XCommandWidget(display,windows,RectifyModeMenu,&event);
4933 (void) XSetFunction(display,windows->image.highlight_context,
4935 XHighlightRectangle(display,windows->image.id,
4936 windows->image.highlight_context,&highlight_info);
4938 switch (RectifyCommands[
id])
4940 case RectifyCopyCommand:
4945 case RectifyHelpCommand:
4947 (void) XSetFunction(display,windows->image.highlight_context,
4953 XTextViewHelp(display,resource_info,windows,MagickFalse,
4954 "Help Viewer - Image Copy",ImageCopyHelp);
4959 XTextViewHelp(display,resource_info,windows,MagickFalse,
4960 "Help Viewer - Image Crop",ImageCropHelp);
4965 XTextViewHelp(display,resource_info,windows,MagickFalse,
4966 "Help Viewer - Image Cut",ImageCutHelp);
4970 (void) XSetFunction(display,windows->image.highlight_context,
4974 case RectifyDismissCommand:
4988 XHighlightRectangle(display,windows->image.id,
4989 windows->image.highlight_context,&highlight_info);
4994 if (event.xbutton.button != Button1)
4996 if (event.xbutton.window != windows->image.id)
4998 x=windows->image.x+
event.xbutton.x;
4999 y=windows->image.y+
event.xbutton.y;
5000 if ((x < (
int) (crop_info.x+RoiDelta)) &&
5001 (x > (
int) (crop_info.x-RoiDelta)) &&
5002 (y < (
int) (crop_info.y+RoiDelta)) &&
5003 (y > (
int) (crop_info.y-RoiDelta)))
5005 crop_info.x=(ssize_t) (crop_info.x+crop_info.width);
5006 crop_info.y=(ssize_t) (crop_info.y+crop_info.height);
5007 state|=UpdateConfigurationState;
5010 if ((x < (
int) (crop_info.x+RoiDelta)) &&
5011 (x > (int) (crop_info.x-RoiDelta)) &&
5012 (y < (
int) (crop_info.y+crop_info.height+RoiDelta)) &&
5013 (y > (int) (crop_info.y+crop_info.height-RoiDelta)))
5015 crop_info.x=(ssize_t) (crop_info.x+crop_info.width);
5016 state|=UpdateConfigurationState;
5019 if ((x < (
int) (crop_info.x+crop_info.width+RoiDelta)) &&
5020 (x > (int) (crop_info.x+crop_info.width-RoiDelta)) &&
5021 (y < (
int) (crop_info.y+RoiDelta)) &&
5022 (y > (int) (crop_info.y-RoiDelta)))
5024 crop_info.y=(ssize_t) (crop_info.y+crop_info.height);
5025 state|=UpdateConfigurationState;
5028 if ((x < (
int) (crop_info.x+crop_info.width+RoiDelta)) &&
5029 (x > (int) (crop_info.x+crop_info.width-RoiDelta)) &&
5030 (y < (
int) (crop_info.y+crop_info.height+RoiDelta)) &&
5031 (y > (int) (crop_info.y+crop_info.height-RoiDelta)))
5033 state|=UpdateConfigurationState;
5040 if (event.xbutton.window == windows->pan.id)
5041 if ((highlight_info.x != crop_info.x-windows->image.x) ||
5042 (highlight_info.y != crop_info.y-windows->image.y))
5043 XHighlightRectangle(display,windows->image.id,
5044 windows->image.highlight_context,&highlight_info);
5045 (void) XSetSelectionOwner(display,XA_PRIMARY,windows->image.id,
5046 event.xbutton.time);
5051 if (event.xexpose.window == windows->image.id)
5052 if (event.xexpose.count == 0)
5054 event.xexpose.x=(int) highlight_info.x;
5055 event.xexpose.y=(
int) highlight_info.y;
5056 event.xexpose.width=(int) highlight_info.width;
5057 event.xexpose.height=(
int) highlight_info.height;
5058 XRefreshWindow(display,&windows->image,&event);
5060 if (event.xexpose.window == windows->info.id)
5061 if (event.xexpose.count == 0)
5062 XInfoWidget(display,windows,text);
5067 if (event.xkey.window != windows->image.id)
5072 (void) XLookupString((XKeyEvent *) &
event.xkey,command,(int)
5073 sizeof(command),&key_symbol,(XComposeStatus *) NULL);
5074 switch ((
int) key_symbol)
5090 crop_info.x=(ssize_t) (windows->image.width/2L-crop_info.width/
5092 crop_info.y=(ssize_t) (windows->image.height/2L-crop_info.height/
5125 (void) XSetFunction(display,windows->image.highlight_context,
5131 XTextViewHelp(display,resource_info,windows,MagickFalse,
5132 "Help Viewer - Image Copy",ImageCopyHelp);
5137 XTextViewHelp(display,resource_info,windows,MagickFalse,
5138 "Help Viewer - Image Cropg",ImageCropHelp);
5143 XTextViewHelp(display,resource_info,windows,MagickFalse,
5144 "Help Viewer - Image Cutg",ImageCutHelp);
5148 (void) XSetFunction(display,windows->image.highlight_context,
5154 (void) XBell(display,0);
5158 (void) XSetSelectionOwner(display,XA_PRIMARY,windows->image.id,
5166 if (event.xmotion.window != windows->image.id)
5173 if (windows->info.mapped != MagickFalse)
5175 if ((x < (
int) (windows->info.x+windows->info.width)) &&
5176 (y < (int) (windows->info.y+windows->info.height)))
5177 (void) XWithdrawWindow(display,windows->info.id,
5178 windows->info.screen);
5181 if ((x > (
int) (windows->info.x+windows->info.width)) ||
5182 (y > (int) (windows->info.y+windows->info.height)))
5183 (void) XMapWindow(display,windows->info.id);
5184 crop_info.x=(ssize_t) windows->image.x+event.xmotion.x;
5185 crop_info.y=(ssize_t) windows->image.y+
event.xmotion.y;
5188 case SelectionRequest:
5193 XSelectionRequestEvent
5199 (void) FormatLocaleString(text,MaxTextExtent,
5200 "%.20gx%.20g%+.20g%+.20g",(
double) crop_info.width,(double)
5201 crop_info.height,(
double) crop_info.x,(double) crop_info.y);
5202 request=(&(
event.xselectionrequest));
5203 (void) XChangeProperty(request->display,request->requestor,
5204 request->property,request->target,8,PropModeReplace,
5205 (
unsigned char *) text,(int) strlen(text));
5206 notify.type=SelectionNotify;
5207 notify.display=request->display;
5208 notify.requestor=request->requestor;
5209 notify.selection=request->selection;
5210 notify.target=request->target;
5211 notify.time=request->time;
5212 if (request->property == None)
5213 notify.property=request->target;
5215 notify.property=request->property;
5216 (void) XSendEvent(request->display,request->requestor,False,0,
5217 (XEvent *) ¬ify);
5222 if ((state & UpdateConfigurationState) != 0)
5224 (void) XPutBackEvent(display,&event);
5225 (void) XCheckDefineCursor(display,windows->image.id,cursor);
5228 }
while ((state & ExitState) == 0);
5229 }
while ((state & ExitState) == 0);
5230 (void) XSetFunction(display,windows->image.highlight_context,GXcopy);
5231 XSetCursorState(display,windows,MagickFalse);
5232 if ((state & EscapeState) != 0)
5234 if (mode == CropMode)
5235 if (((
int) crop_info.width != windows->image.ximage->width) ||
5236 ((
int) crop_info.height != windows->image.ximage->height))
5241 XSetCropGeometry(display,windows,&crop_info,image);
5242 windows->image.window_changes.width=(int) crop_info.width;
5243 windows->image.window_changes.height=(
int) crop_info.height;
5244 (void) XConfigureImage(display,resource_info,windows,image);
5250 XSetCursorState(display,windows,MagickTrue);
5251 XCheckRefreshWindows(display,windows);
5252 width=(
unsigned int) image->columns;
5253 height=(
unsigned int) image->rows;
5256 if (windows->image.crop_geometry != (
char *) NULL)
5257 (
void) XParseGeometry(windows->image.crop_geometry,&x,&y,&width,&height);
5258 scale_factor=(MagickRealType) width/windows->image.ximage->width;
5260 crop_info.x=(ssize_t) (scale_factor*crop_info.x+0.5);
5261 crop_info.x+=image->page.x;
5262 crop_info.width=(
unsigned int) (scale_factor*crop_info.width+0.5);
5263 scale_factor=(MagickRealType) height/windows->image.ximage->height;
5265 crop_info.y=(ssize_t) (scale_factor*crop_info.y+0.5);
5266 crop_info.y+=image->page.y;
5267 crop_info.height=(
unsigned int) (scale_factor*crop_info.height+0.5);
5268 crop_image=CropImage(image,&crop_info,&image->exception);
5269 XSetCursorState(display,windows,MagickFalse);
5270 if (crop_image == (
Image *) NULL)
5271 return(MagickFalse);
5272 if (resource_info->copy_image != (
Image *) NULL)
5273 resource_info->copy_image=DestroyImage(resource_info->copy_image);
5274 resource_info->copy_image=crop_image;
5275 if (mode == CopyMode)
5277 (void) XConfigureImage(display,resource_info,windows,image);
5283 if (SetImageStorageClass(image,DirectClass) == MagickFalse)
5284 return(MagickFalse);
5285 image->matte=MagickTrue;
5286 exception=(&image->exception);
5287 image_view=AcquireAuthenticCacheView(image,exception);
5288 for (y=0; y < (int) crop_info.height; y++)
5290 q=GetCacheViewAuthenticPixels(image_view,crop_info.x,y+crop_info.y,
5291 crop_info.width,1,exception);
5294 for (x=0; x < (int) crop_info.width; x++)
5296 q->opacity=(Quantum) TransparentOpacity;
5299 if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
5302 image_view=DestroyCacheView(image_view);
5306 XConfigureImageColormap(display,resource_info,windows,image);
5307 (void) XConfigureImage(display,resource_info,windows,image);
5342 static MagickBooleanType XDrawEditImage(Display *display,
5343 XResourceInfo *resource_info,XWindows *windows,
Image **image)
5359 element = PointElement;
5361 static const ModeType
5374 stipple = (Pixmap) NULL;
5381 command[MaxTextExtent],
5382 text[MaxTextExtent];
5433 max_coordinates=2048;
5434 coordinate_info=(XPoint *) AcquireQuantumMemory((
size_t) max_coordinates,
5435 sizeof(*coordinate_info));
5436 if (coordinate_info == (XPoint *) NULL)
5438 (void) ThrowMagickException(&(*image)->exception,GetMagickModule(),
5439 ResourceLimitError,
"MemoryAllocationFailed",
"`%s'",
"...");
5440 return(MagickFalse);
5445 (void) CloneString(&windows->command.name,
"Draw");
5446 windows->command.data=4;
5447 (void) XCommandWidget(display,windows,DrawMenu,(XEvent *) NULL);
5448 (void) XMapRaised(display,windows->command.id);
5449 XClientMessage(display,windows->image.id,windows->im_protocols,
5450 windows->im_update_widget,CurrentTime);
5454 root_window=XRootWindow(display,XDefaultScreen(display));
5455 draw_info.stencil=OpaqueStencil;
5457 cursor=XCreateFontCursor(display,XC_tcross);
5460 XQueryPosition(display,windows->image.id,&x,&y);
5461 (void) XSelectInput(display,windows->image.id,
5462 windows->image.attributes.event_mask | PointerMotionMask);
5463 (void) XCheckDefineCursor(display,windows->image.id,cursor);
5467 if (windows->info.mapped != MagickFalse)
5472 (void) FormatLocaleString(text,MaxTextExtent,
" %+d%+d ",
5473 x+windows->image.x,y+windows->image.y);
5474 XInfoWidget(display,windows,text);
5479 XScreenEvent(display,windows,&event);
5480 if (event.xany.window == windows->command.id)
5485 id=XCommandWidget(display,windows,DrawMenu,&event);
5488 switch (DrawCommands[
id])
5490 case DrawElementCommand:
5511 element=(ElementType) (XMenuWidget(display,windows,
5512 DrawMenu[
id],Elements,command)+1);
5515 case DrawColorCommand:
5518 *ColorMenu[MaxNumberPens+1];
5532 for (i=0; i < (int) (MaxNumberPens-2); i++)
5533 ColorMenu[i]=resource_info->pen_colors[i];
5534 ColorMenu[MaxNumberPens-2]=
"transparent";
5535 ColorMenu[MaxNumberPens-1]=
"Browser...";
5536 ColorMenu[MaxNumberPens]=(
char *) NULL;
5540 pen_number=XMenuWidget(display,windows,DrawMenu[
id],
5541 (
const char **) ColorMenu,command);
5544 transparent=pen_number == (MaxNumberPens-2) ? MagickTrue :
5546 if (transparent != MagickFalse)
5548 draw_info.stencil=TransparentStencil;
5551 if (pen_number == (MaxNumberPens-1))
5554 color_name[MaxTextExtent] =
"gray";
5559 resource_info->pen_colors[pen_number]=color_name;
5560 XColorBrowserWidget(display,windows,
"Select",color_name);
5561 if (*color_name ==
'\0')
5567 (void) XParseColor(display,windows->map_info->colormap,
5568 resource_info->pen_colors[pen_number],&color);
5569 XBestPixel(display,windows->map_info->colormap,(XColor *) NULL,
5570 (
unsigned int) MaxColors,&color);
5571 windows->pixel_info->pen_colors[pen_number]=color;
5572 pen_id=(
unsigned int) pen_number;
5573 draw_info.stencil=OpaqueStencil;
5576 case DrawStippleCommand:
5602 filename[MaxTextExtent] =
"\0";
5607 StipplesMenu[7]=
"Open...";
5608 entry=XMenuWidget(display,windows,DrawMenu[
id],StipplesMenu,
5612 if (stipple != (Pixmap) NULL)
5613 (void) XFreePixmap(display,stipple);
5614 stipple=(Pixmap) NULL;
5621 stipple=XCreateBitmapFromData(display,root_window,
5622 (
char *) BricksBitmap,BricksWidth,BricksHeight);
5627 stipple=XCreateBitmapFromData(display,root_window,
5628 (
char *) DiagonalBitmap,DiagonalWidth,DiagonalHeight);
5633 stipple=XCreateBitmapFromData(display,root_window,
5634 (
char *) ScalesBitmap,ScalesWidth,ScalesHeight);
5639 stipple=XCreateBitmapFromData(display,root_window,
5640 (
char *) VerticalBitmap,VerticalWidth,VerticalHeight);
5645 stipple=XCreateBitmapFromData(display,root_window,
5646 (
char *) WavyBitmap,WavyWidth,WavyHeight);
5651 stipple=XCreateBitmapFromData(display,root_window,
5652 (
char *) HighlightBitmap,HighlightWidth,
5659 stipple=XCreateBitmapFromData(display,root_window,
5660 (
char *) OpaqueBitmap,OpaqueWidth,OpaqueHeight);
5666 XFileBrowserWidget(display,windows,
"Stipple",filename);
5667 if (*filename ==
'\0')
5672 XSetCursorState(display,windows,MagickTrue);
5673 XCheckRefreshWindows(display,windows);
5674 image_info=AcquireImageInfo();
5675 (void) CopyMagickString(image_info->filename,filename,
5677 stipple_image=ReadImage(image_info,&(*image)->exception);
5678 CatchException(&(*image)->exception);
5679 XSetCursorState(display,windows,MagickFalse);
5680 if (stipple_image == (
Image *) NULL)
5682 (void) AcquireUniqueFileResource(filename);
5683 (void) FormatLocaleString(stipple_image->filename,MaxTextExtent,
5685 (void) WriteImage(image_info,stipple_image);
5686 stipple_image=DestroyImage(stipple_image);
5687 image_info=DestroyImageInfo(image_info);
5688 status=XReadBitmapFile(display,root_window,filename,&width,
5689 &height,&stipple,&x,&y);
5690 (void) RelinquishUniqueFileResource(filename);
5691 if ((status != BitmapSuccess) != 0)
5692 XNoticeWidget(display,windows,
"Unable to read X bitmap image:",
5696 case DrawWidthCommand:
5699 *
const WidthsMenu[] =
5711 width[MaxTextExtent] =
"0";
5716 entry=XMenuWidget(display,windows,DrawMenu[
id],WidthsMenu,
5722 line_width=(
unsigned int) StringToUnsignedLong(
5726 (void) XDialogWidget(display,windows,
"Ok",
"Enter line width:",
5730 line_width=(
unsigned int) StringToUnsignedLong(width);
5733 case DrawUndoCommand:
5735 (void) XMagickCommand(display,resource_info,windows,UndoCommand,
5739 case DrawHelpCommand:
5741 XTextViewHelp(display,resource_info,windows,MagickFalse,
5742 "Help Viewer - Image Rotation",ImageDrawHelp);
5743 (void) XCheckDefineCursor(display,windows->image.id,cursor);
5746 case DrawDismissCommand:
5758 (void) XCheckDefineCursor(display,windows->image.id,cursor);
5765 if (event.xbutton.button != Button1)
5767 if (event.xbutton.window != windows->image.id)
5786 if (event.xkey.window != windows->image.id)
5791 (void) XLookupString((XKeyEvent *) &
event.xkey,command,(int)
5792 sizeof(command),&key_symbol,(XComposeStatus *) NULL);
5793 switch ((
int) key_symbol)
5808 XTextViewHelp(display,resource_info,windows,MagickFalse,
5809 "Help Viewer - Image Rotation",ImageDrawHelp);
5814 (void) XBell(display,0);
5827 if (windows->info.mapped != MagickFalse)
5829 if ((x < (
int) (windows->info.x+windows->info.width)) &&
5830 (y < (int) (windows->info.y+windows->info.height)))
5831 (void) XWithdrawWindow(display,windows->info.id,
5832 windows->info.screen);
5835 if ((x > (
int) (windows->info.x+windows->info.width)) ||
5836 (y > (int) (windows->info.y+windows->info.height)))
5837 (void) XMapWindow(display,windows->info.id);
5841 }
while ((state & ExitState) == 0);
5842 (void) XSelectInput(display,windows->image.id,
5843 windows->image.attributes.event_mask);
5844 (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
5845 if ((state & EscapeState) != 0)
5856 rectangle_info.x=(ssize_t) x;
5857 rectangle_info.y=(ssize_t) y;
5858 rectangle_info.width=0;
5859 rectangle_info.height=0;
5860 number_coordinates=1;
5861 coordinate_info->x=x;
5862 coordinate_info->y=y;
5863 (void) XSetFunction(display,windows->image.highlight_context,GXinvert);
5872 if (number_coordinates > 1)
5874 (void) XDrawLines(display,windows->image.id,
5875 windows->image.highlight_context,coordinate_info,
5876 number_coordinates,CoordModeOrigin);
5877 (void) FormatLocaleString(text,MaxTextExtent,
" %+d%+d",
5878 coordinate_info[number_coordinates-1].x,
5879 coordinate_info[number_coordinates-1].y);
5880 XInfoWidget(display,windows,text);
5891 degrees=RadiansToDegrees(-atan2((
double) (line_info.y2-
5892 line_info.y1),(
double) (line_info.x2-line_info.x1)));
5893 (void) FormatLocaleString(text,MaxTextExtent,
" %g",
5895 XInfoWidget(display,windows,text);
5896 XHighlightLine(display,windows->image.id,
5897 windows->image.highlight_context,&line_info);
5900 if (windows->info.mapped != MagickFalse)
5901 (void) XWithdrawWindow(display,windows->info.id,
5902 windows->info.screen);
5905 case RectangleElement:
5906 case FillRectangleElement:
5908 if ((rectangle_info.width > 3) && (rectangle_info.height > 3))
5913 (void) FormatLocaleString(text,MaxTextExtent,
5914 " %.20gx%.20g%+.20g%+.20g",(
double) rectangle_info.width,
5915 (double) rectangle_info.height,(
double) rectangle_info.x,
5916 (double) rectangle_info.y);
5917 XInfoWidget(display,windows,text);
5918 XHighlightRectangle(display,windows->image.id,
5919 windows->image.highlight_context,&rectangle_info);
5922 if (windows->info.mapped != MagickFalse)
5923 (void) XWithdrawWindow(display,windows->info.id,
5924 windows->info.screen);
5928 case FillCircleElement:
5929 case EllipseElement:
5930 case FillEllipseElement:
5932 if ((rectangle_info.width > 3) && (rectangle_info.height > 3))
5937 (void) FormatLocaleString(text,MaxTextExtent,
5938 " %.20gx%.20g%+.20g%+.20g",(
double) rectangle_info.width,
5939 (double) rectangle_info.height,(
double) rectangle_info.x,
5940 (double) rectangle_info.y);
5941 XInfoWidget(display,windows,text);
5942 XHighlightEllipse(display,windows->image.id,
5943 windows->image.highlight_context,&rectangle_info);
5946 if (windows->info.mapped != MagickFalse)
5947 (void) XWithdrawWindow(display,windows->info.id,
5948 windows->info.screen);
5951 case PolygonElement:
5952 case FillPolygonElement:
5954 if (number_coordinates > 1)
5955 (void) XDrawLines(display,windows->image.id,
5956 windows->image.highlight_context,coordinate_info,
5957 number_coordinates,CoordModeOrigin);
5963 degrees=RadiansToDegrees(-atan2((
double) (line_info.y2-
5964 line_info.y1),(
double) (line_info.x2-line_info.x1)));
5965 (void) FormatLocaleString(text,MaxTextExtent,
" %g",
5967 XInfoWidget(display,windows,text);
5968 XHighlightLine(display,windows->image.id,
5969 windows->image.highlight_context,&line_info);
5972 if (windows->info.mapped != MagickFalse)
5973 (void) XWithdrawWindow(display,windows->info.id,
5974 windows->info.screen);
5981 XScreenEvent(display,windows,&event);
5987 if (number_coordinates > 1)
5988 (void) XDrawLines(display,windows->image.id,
5989 windows->image.highlight_context,coordinate_info,
5990 number_coordinates,CoordModeOrigin);
5996 XHighlightLine(display,windows->image.id,
5997 windows->image.highlight_context,&line_info);
6000 case RectangleElement:
6001 case FillRectangleElement:
6003 if ((rectangle_info.width > 3) && (rectangle_info.height > 3))
6004 XHighlightRectangle(display,windows->image.id,
6005 windows->image.highlight_context,&rectangle_info);
6009 case FillCircleElement:
6010 case EllipseElement:
6011 case FillEllipseElement:
6013 if ((rectangle_info.width > 3) && (rectangle_info.height > 3))
6014 XHighlightEllipse(display,windows->image.id,
6015 windows->image.highlight_context,&rectangle_info);
6018 case PolygonElement:
6019 case FillPolygonElement:
6021 if (number_coordinates > 1)
6022 (void) XDrawLines(display,windows->image.id,
6023 windows->image.highlight_context,coordinate_info,
6024 number_coordinates,CoordModeOrigin);
6026 XHighlightLine(display,windows->image.id,
6027 windows->image.highlight_context,&line_info);
6040 line_info.x2=
event.xbutton.x;
6041 line_info.y2=
event.xbutton.y;
6042 rectangle_info.x=(ssize_t) event.xbutton.x;
6043 rectangle_info.y=(ssize_t)
event.xbutton.y;
6044 coordinate_info[number_coordinates].x=
event.xbutton.x;
6045 coordinate_info[number_coordinates].y=
event.xbutton.y;
6046 if (((element != PolygonElement) &&
6047 (element != FillPolygonElement)) || (distance <= 9))
6052 number_coordinates++;
6053 if (number_coordinates < (
int) max_coordinates)
6055 line_info.x1=
event.xbutton.x;
6056 line_info.y1=
event.xbutton.y;
6059 max_coordinates<<=1;
6060 coordinate_info=(XPoint *) ResizeQuantumMemory(coordinate_info,
6061 max_coordinates,
sizeof(*coordinate_info));
6062 if (coordinate_info == (XPoint *) NULL)
6063 (
void) ThrowMagickException(&(*image)->exception,GetMagickModule(),
6064 ResourceLimitError,
"MemoryAllocationFailed",
"`%s'",
"...");
6071 if (event.xmotion.window != windows->image.id)
6073 if (element != PointElement)
6075 line_info.x2=
event.xmotion.x;
6076 line_info.y2=
event.xmotion.y;
6077 rectangle_info.x=(ssize_t) event.xmotion.x;
6078 rectangle_info.y=(ssize_t)
event.xmotion.y;
6081 coordinate_info[number_coordinates].x=
event.xbutton.x;
6082 coordinate_info[number_coordinates].y=
event.xbutton.y;
6083 number_coordinates++;
6084 if (number_coordinates < (
int) max_coordinates)
6086 max_coordinates<<=1;
6087 coordinate_info=(XPoint *) ResizeQuantumMemory(coordinate_info,
6088 max_coordinates,
sizeof(*coordinate_info));
6089 if (coordinate_info == (XPoint *) NULL)
6090 (
void) ThrowMagickException(&(*image)->exception,GetMagickModule(),
6091 ResourceLimitError,
"MemoryAllocationFailed",
"`%s'",
"...");
6100 if (line_info.x2 < 0)
6103 if (line_info.x2 > (
int) windows->image.width)
6104 line_info.x2=(short) windows->image.width;
6105 if (line_info.y2 < 0)
6108 if (line_info.y2 > (
int) windows->image.height)
6109 line_info.y2=(
short) windows->image.height;
6110 distance=(
unsigned int)
6111 (((line_info.x2-line_info.x1+1)*(line_info.x2-line_info.x1+1))+
6112 ((line_info.y2-line_info.y1+1)*(line_info.y2-line_info.y1+1)));
6113 if ((((
int) rectangle_info.x != x) && ((
int) rectangle_info.y != y)) ||
6114 ((state & ExitState) != 0))
6116 if (rectangle_info.x < 0)
6119 if (rectangle_info.x > (ssize_t) windows->image.width)
6120 rectangle_info.x=(ssize_t) windows->image.width;
6121 if ((
int) rectangle_info.x < x)
6122 rectangle_info.width=(
unsigned int) (x-rectangle_info.x);
6125 rectangle_info.width=(
unsigned int) (rectangle_info.x-x);
6126 rectangle_info.x=(ssize_t) x;
6128 if (rectangle_info.y < 0)
6131 if (rectangle_info.y > (ssize_t) windows->image.height)
6132 rectangle_info.y=(ssize_t) windows->image.height;
6133 if ((
int) rectangle_info.y < y)
6134 rectangle_info.height=(
unsigned int) (y-rectangle_info.y);
6137 rectangle_info.height=(
unsigned int) (rectangle_info.y-y);
6138 rectangle_info.y=(ssize_t) y;
6141 }
while ((state & ExitState) == 0);
6142 (void) XSetFunction(display,windows->image.highlight_context,GXcopy);
6143 if ((element == PointElement) || (element == PolygonElement) ||
6144 (element == FillPolygonElement))
6149 rectangle_info.x=(ssize_t) coordinate_info->x;
6150 rectangle_info.y=(ssize_t) coordinate_info->y;
6151 x=coordinate_info->x;
6152 y=coordinate_info->y;
6153 for (i=1; i < number_coordinates; i++)
6155 if (coordinate_info[i].x > x)
6156 x=coordinate_info[i].x;
6157 if (coordinate_info[i].y > y)
6158 y=coordinate_info[i].y;
6159 if ((ssize_t) coordinate_info[i].x < rectangle_info.x)
6160 rectangle_info.x=MagickMax((ssize_t) coordinate_info[i].x,0);
6161 if ((ssize_t) coordinate_info[i].y < rectangle_info.y)
6162 rectangle_info.y=MagickMax((ssize_t) coordinate_info[i].y,0);
6164 rectangle_info.width=(size_t) (x-rectangle_info.x);
6165 rectangle_info.height=(size_t) (y-rectangle_info.y);
6166 for (i=0; i < number_coordinates; i++)
6168 coordinate_info[i].x-=rectangle_info.x;
6169 coordinate_info[i].y-=rectangle_info.y;
6176 if ((element == RectangleElement) ||
6177 (element == CircleElement) || (element == EllipseElement))
6179 rectangle_info.width--;
6180 rectangle_info.height--;
6185 draw_info.x=(int) rectangle_info.x;
6186 draw_info.y=(
int) rectangle_info.y;
6187 (void) XMagickCommand(display,resource_info,windows,SaveToUndoBufferCommand,
6189 width=(
unsigned int) (*image)->columns;
6190 height=(
unsigned int) (*image)->rows;
6193 if (windows->image.crop_geometry != (
char *) NULL)
6194 (
void) XParseGeometry(windows->image.crop_geometry,&x,&y,&width,&height);
6195 draw_info.x+=windows->image.x-(line_width/2);
6196 if (draw_info.x < 0)
6198 draw_info.x=(int) (width*draw_info.x/windows->image.ximage->width);
6199 draw_info.y+=windows->image.y-(line_width/2);
6200 if (draw_info.y < 0)
6202 draw_info.y=(int) height*draw_info.y/windows->image.ximage->height;
6203 draw_info.width=(
unsigned int) rectangle_info.width+(line_width << 1);
6204 if (draw_info.width > (
unsigned int) (*image)->columns)
6205 draw_info.width=(
unsigned int) (*image)->columns;
6206 draw_info.height=(
unsigned int) rectangle_info.height+(line_width << 1);
6207 if (draw_info.height > (
unsigned int) (*image)->rows)
6208 draw_info.height=(
unsigned int) (*image)->rows;
6209 (void) FormatLocaleString(draw_info.geometry,MaxTextExtent,
"%ux%u%+d%+d",
6210 width*draw_info.width/windows->image.ximage->width,
6211 height*draw_info.height/windows->image.ximage->height,
6212 draw_info.x+x,draw_info.y+y);
6216 draw_info.degrees=0.0;
6217 draw_info.element=element;
6218 draw_info.stipple=stipple;
6219 draw_info.line_width=line_width;
6220 draw_info.line_info=line_info;
6221 if (line_info.x1 > (
int) (line_width/2))
6222 draw_info.line_info.x1=(short) line_width/2;
6223 if (line_info.y1 > (
int) (line_width/2))
6224 draw_info.line_info.y1=(short) line_width/2;
6225 draw_info.line_info.x2=(short) (line_info.x2-line_info.x1+(line_width/2));
6226 draw_info.line_info.y2=(short) (line_info.y2-line_info.y1+(line_width/2));
6227 if ((draw_info.line_info.x2 < 0) && (draw_info.line_info.y2 < 0))
6229 draw_info.line_info.x2=(-draw_info.line_info.x2);
6230 draw_info.line_info.y2=(-draw_info.line_info.y2);
6232 if (draw_info.line_info.x2 < 0)
6234 draw_info.line_info.x2=(-draw_info.line_info.x2);
6235 Swap(draw_info.line_info.x1,draw_info.line_info.x2);
6237 if (draw_info.line_info.y2 < 0)
6239 draw_info.line_info.y2=(-draw_info.line_info.y2);
6240 Swap(draw_info.line_info.y1,draw_info.line_info.y2);
6242 draw_info.rectangle_info=rectangle_info;
6243 if (draw_info.rectangle_info.x > (ssize_t) (line_width/2))
6244 draw_info.rectangle_info.x=(ssize_t) line_width/2;
6245 if (draw_info.rectangle_info.y > (ssize_t) (line_width/2))
6246 draw_info.rectangle_info.y=(ssize_t) line_width/2;
6247 draw_info.number_coordinates=(
unsigned int) number_coordinates;
6248 draw_info.coordinate_info=coordinate_info;
6249 windows->pixel_info->pen_color=windows->pixel_info->pen_colors[pen_id];
6253 XSetCursorState(display,windows,MagickTrue);
6254 XCheckRefreshWindows(display,windows);
6255 status=XDrawImage(display,windows->pixel_info,&draw_info,*image);
6256 XSetCursorState(display,windows,MagickFalse);
6260 XConfigureImageColormap(display,resource_info,windows,*image);
6261 (void) XConfigureImage(display,resource_info,windows,*image);
6263 XSetCursorState(display,windows,MagickFalse);
6264 coordinate_info=(XPoint *) RelinquishMagickMemory(coordinate_info);
6265 return(status != 0 ? MagickTrue : MagickFalse);
6295 static void XDrawPanRectangle(Display *display,XWindows *windows)
6306 scale_factor=(MagickRealType) windows->pan.width/windows->image.ximage->width;
6307 highlight_info.x=(ssize_t) (scale_factor*windows->image.x+0.5);
6308 highlight_info.width=(
unsigned int) (scale_factor*windows->image.width+0.5);
6309 scale_factor=(MagickRealType)
6310 windows->pan.height/windows->image.ximage->height;
6311 highlight_info.y=(ssize_t) (scale_factor*windows->image.y+0.5);
6312 highlight_info.height=(
unsigned int) (scale_factor*windows->image.height+0.5);
6316 (void) XClearWindow(display,windows->pan.id);
6317 XHighlightRectangle(display,windows->pan.id,windows->pan.annotate_context,
6355 static void XImageCache(Display *display,XResourceInfo *resource_info,
6356 XWindows *windows,
const CommandType command,
Image **image)
6362 *redo_image = (
Image *) NULL,
6363 *undo_image = (
Image *) NULL;
6367 case FreeBuffersCommand:
6372 while (undo_image != (
Image *) NULL)
6374 cache_image=undo_image;
6375 undo_image=GetPreviousImageInList(undo_image);
6376 cache_image->list=DestroyImage(cache_image->list);
6377 cache_image=DestroyImage(cache_image);
6379 undo_image=NewImageList();
6380 if (redo_image != (
Image *) NULL)
6381 redo_image=DestroyImage(redo_image);
6382 redo_image=NewImageList();
6388 image_geometry[MaxTextExtent];
6393 if (undo_image == (
Image *) NULL)
6395 (void) XBell(display,0);
6398 cache_image=undo_image;
6399 undo_image=GetPreviousImageInList(undo_image);
6400 windows->image.window_changes.width=(int) cache_image->columns;
6401 windows->image.window_changes.height=(
int) cache_image->rows;
6402 (void) FormatLocaleString(image_geometry,MaxTextExtent,
"%dx%d!",
6403 windows->image.ximage->width,windows->image.ximage->height);
6404 (void) TransformImage(image,windows->image.crop_geometry,image_geometry);
6405 if (windows->image.crop_geometry != (
char *) NULL)
6406 windows->image.crop_geometry=(
char *)
6407 RelinquishMagickMemory(windows->image.crop_geometry);
6408 windows->image.crop_geometry=cache_image->geometry;
6409 if (redo_image != (
Image *) NULL)
6410 redo_image=DestroyImage(redo_image);
6411 redo_image=(*image);
6412 *image=cache_image->list;
6413 cache_image=DestroyImage(cache_image);
6414 if (windows->image.orphan != MagickFalse)
6416 XConfigureImageColormap(display,resource_info,windows,*image);
6417 (void) XConfigureImage(display,resource_info,windows,*image);
6423 case HalfSizeCommand:
6424 case OriginalSizeCommand:
6425 case DoubleSizeCommand:
6432 case RotateRightCommand:
6433 case RotateLeftCommand:
6438 case ContrastStretchCommand:
6439 case SigmoidalContrastCommand:
6440 case NormalizeCommand:
6441 case EqualizeCommand:
6443 case SaturationCommand:
6444 case BrightnessCommand:
6448 case GrayscaleCommand:
6450 case QuantizeCommand:
6451 case DespeckleCommand:
6453 case ReduceNoiseCommand:
6454 case AddNoiseCommand:
6455 case SharpenCommand:
6457 case ThresholdCommand:
6458 case EdgeDetectCommand:
6462 case SegmentCommand:
6463 case SolarizeCommand:
6464 case SepiaToneCommand:
6466 case ImplodeCommand:
6467 case VignetteCommand:
6469 case OilPaintCommand:
6470 case CharcoalDrawCommand:
6471 case AnnotateCommand:
6472 case AddBorderCommand:
6473 case AddFrameCommand:
6474 case CompositeCommand:
6475 case CommentCommand:
6477 case RegionOfInterestCommand:
6478 case SaveToUndoBufferCommand:
6487 bytes=(ssize_t) ((*image)->columns*(*image)->rows*
sizeof(
PixelPacket));
6488 if (undo_image != (
Image *) NULL)
6493 previous_image=undo_image;
6494 while (previous_image != (
Image *) NULL)
6496 bytes+=previous_image->list->columns*previous_image->list->rows*
6498 if (bytes <= (ssize_t) (resource_info->undo_cache << 20))
6500 previous_image=GetPreviousImageInList(previous_image);
6503 bytes-=previous_image->list->columns*previous_image->list->rows*
6505 if (previous_image == undo_image)
6506 undo_image=NewImageList();
6508 previous_image->next->previous=NewImageList();
6511 while (previous_image != (
Image *) NULL)
6516 cache_image=previous_image;
6517 previous_image=GetPreviousImageInList(previous_image);
6518 cache_image->list=DestroyImage(cache_image->list);
6519 cache_image=DestroyImage(cache_image);
6522 if (bytes > (ssize_t) (resource_info->undo_cache << 20))
6527 cache_image=AcquireImage((
ImageInfo *) NULL);
6528 if (cache_image == (
Image *) NULL)
6530 XSetCursorState(display,windows,MagickTrue);
6531 XCheckRefreshWindows(display,windows);
6532 cache_image->list=CloneImage(*image,0,0,MagickTrue,&(*image)->exception);
6533 XSetCursorState(display,windows,MagickFalse);
6534 if (cache_image->list == (
Image *) NULL)
6536 cache_image=DestroyImage(cache_image);
6539 cache_image->columns=(size_t) windows->image.ximage->width;
6540 cache_image->rows=(
size_t) windows->image.ximage->height;
6541 cache_image->geometry=windows->image.crop_geometry;
6542 if (windows->image.crop_geometry != (
char *) NULL)
6544 cache_image->geometry=AcquireString((
char *) NULL);
6545 (void) CopyMagickString(cache_image->geometry,
6546 windows->image.crop_geometry,MaxTextExtent);
6548 if (undo_image == (
Image *) NULL)
6550 undo_image=cache_image;
6553 undo_image->next=cache_image;
6554 undo_image->next->previous=undo_image;
6555 undo_image=undo_image->next;
6561 if (command == RedoCommand)
6566 if (redo_image == (
Image *) NULL)
6568 (void) XBell(display,0);
6571 windows->image.window_changes.width=(int) redo_image->columns;
6572 windows->image.window_changes.height=(
int) redo_image->rows;
6573 if (windows->image.crop_geometry != (
char *) NULL)
6574 windows->image.crop_geometry=(
char *)
6575 RelinquishMagickMemory(windows->image.crop_geometry);
6576 windows->image.crop_geometry=redo_image->geometry;
6577 *image=DestroyImage(*image);
6579 redo_image=NewImageList();
6580 if (windows->image.orphan != MagickFalse)
6582 XConfigureImageColormap(display,resource_info,windows,*image);
6583 (void) XConfigureImage(display,resource_info,windows,*image);
6586 if (command != InfoCommand)
6591 XSetCursorState(display,windows,MagickTrue);
6592 XCheckRefreshWindows(display,windows);
6593 XDisplayImageInfo(display,resource_info,windows,undo_image,*image);
6594 XSetCursorState(display,windows,MagickFalse);
6638 static CommandType XImageWindowCommand(Display *display,
6639 XResourceInfo *resource_info,XWindows *windows,
const MagickStatusType state,
6640 KeySym key_symbol,
Image **image)
6643 delta[MaxTextExtent] =
"";
6646 Digits[] =
"01234567890";
6651 if ((key_symbol >= XK_0) && (key_symbol <= XK_9))
6653 if (((last_symbol < XK_0) || (last_symbol > XK_9)))
6656 resource_info->quantum=1;
6658 last_symbol=key_symbol;
6659 delta[strlen(delta)+1]=
'\0';
6660 delta[strlen(delta)]=Digits[key_symbol-XK_0];
6661 resource_info->quantum=StringToLong(delta);
6662 return(NullCommand);
6664 last_symbol=key_symbol;
6665 if (resource_info->immutable)
6673 return(InfoCommand);
6676 return(PrintCommand);
6678 return(NextCommand);
6681 return(QuitCommand);
6685 return(NullCommand);
6687 switch ((
int) key_symbol)
6691 if ((state & ControlMask) == 0)
6693 return(OpenCommand);
6696 return(NextCommand);
6698 return(FormerCommand);
6701 if ((state & Mod1Mask) != 0)
6702 return(SwirlCommand);
6703 if ((state & ControlMask) == 0)
6704 return(ShearCommand);
6705 return(SaveCommand);
6710 if ((state & Mod1Mask) != 0)
6711 return(OilPaintCommand);
6712 if ((state & Mod4Mask) != 0)
6713 return(ColorCommand);
6714 if ((state & ControlMask) == 0)
6715 return(NullCommand);
6716 return(PrintCommand);
6720 if ((state & Mod4Mask) != 0)
6721 return(DrawCommand);
6722 if ((state & ControlMask) == 0)
6723 return(NullCommand);
6724 return(DeleteCommand);
6728 if ((state & ControlMask) == 0)
6729 return(NullCommand);
6730 return(SelectCommand);
6734 if ((state & ControlMask) == 0)
6735 return(NullCommand);
6740 return(QuitCommand);
6744 if ((state & ControlMask) == 0)
6745 return(NullCommand);
6746 return(UndoCommand);
6751 if ((state & ControlMask) == 0)
6752 return(RollCommand);
6753 return(RedoCommand);
6757 if ((state & ControlMask) == 0)
6758 return(NullCommand);
6763 if ((state & Mod1Mask) != 0)
6764 return(CharcoalDrawCommand);
6765 if ((state & ControlMask) == 0)
6766 return(CropCommand);
6767 return(CopyCommand);
6772 if ((state & Mod4Mask) != 0)
6773 return(CompositeCommand);
6774 if ((state & ControlMask) == 0)
6775 return(FlipCommand);
6776 return(PasteCommand);
6779 return(HalfSizeCommand);
6781 return(OriginalSizeCommand);
6783 return(DoubleSizeCommand);
6785 return(ResizeCommand);
6787 return(RefreshCommand);
6788 case XK_bracketleft:
6789 return(ChopCommand);
6791 return(FlopCommand);
6793 return(RotateRightCommand);
6795 return(RotateLeftCommand);
6797 return(RotateCommand);
6799 return(TrimCommand);
6803 return(SaturationCommand);
6805 return(BrightnessCommand);
6807 return(GammaCommand);
6809 return(SpiffCommand);
6811 return(DullCommand);
6813 return(NormalizeCommand);
6815 return(EqualizeCommand);
6817 return(NegateCommand);
6819 return(GrayscaleCommand);
6821 return(QuantizeCommand);
6823 return(DespeckleCommand);
6825 return(EmbossCommand);
6827 return(ReduceNoiseCommand);
6829 return(AddNoiseCommand);
6831 return(SharpenCommand);
6833 return(BlurCommand);
6835 return(ThresholdCommand);
6837 return(EdgeDetectCommand);
6839 return(SpreadCommand);
6841 return(ShadeCommand);
6843 return(RaiseCommand);
6845 return(SegmentCommand);
6848 if ((state & Mod1Mask) == 0)
6849 return(NullCommand);
6850 return(ImplodeCommand);
6854 if ((state & Mod1Mask) == 0)
6855 return(NullCommand);
6856 return(WaveCommand);
6860 if ((state & Mod4Mask) == 0)
6861 return(NullCommand);
6862 return(MatteCommand);
6866 if ((state & Mod4Mask) == 0)
6867 return(NullCommand);
6868 return(AddBorderCommand);
6872 if ((state & Mod4Mask) == 0)
6873 return(NullCommand);
6874 return(AddFrameCommand);
6878 if ((state & Mod4Mask) == 0)
6879 return(NullCommand);
6880 return(CommentCommand);
6884 if ((state & Mod1Mask) != 0)
6885 return(ApplyCommand);
6886 if ((state & Mod4Mask) != 0)
6887 return(AnnotateCommand);
6888 if ((state & ControlMask) == 0)
6889 return(NullCommand);
6890 return(RegionOfInterestCommand);
6893 return(InfoCommand);
6895 return(ZoomCommand);
6898 if ((state & ShiftMask) == 0)
6899 return(NullCommand);
6900 return(ShowPreviewCommand);
6903 return(LaunchCommand);
6905 return(HelpCommand);
6907 return(BrowseDocumentationCommand);
6910 (void) XMapRaised(display,windows->command.id);
6911 return(NullCommand);
6918 XTranslateImage(display,windows,*image,key_symbol);
6919 return(NullCommand);
6930 if ((state & Mod1Mask) != 0)
6940 crop_info.width=(size_t) windows->image.ximage->width;
6941 crop_info.height=(
size_t) windows->image.ximage->height;
6942 if ((key_symbol == XK_Up) || (key_symbol == XK_KP_Up))
6944 if (resource_info->quantum >= (
int) crop_info.height)
6945 resource_info->quantum=(
int) crop_info.height-1;
6946 crop_info.height-=resource_info->quantum;
6948 if ((key_symbol == XK_Down) || (key_symbol == XK_KP_Down))
6950 if (resource_info->quantum >= (
int) (crop_info.height-crop_info.y))
6951 resource_info->quantum=(int) (crop_info.height-crop_info.y-1);
6952 crop_info.y+=resource_info->quantum;
6953 crop_info.height-=resource_info->quantum;
6955 if ((key_symbol == XK_Left) || (key_symbol == XK_KP_Left))
6957 if (resource_info->quantum >= (
int) crop_info.width)
6958 resource_info->quantum=(
int) crop_info.width-1;
6959 crop_info.width-=resource_info->quantum;
6961 if ((key_symbol == XK_Right) || (key_symbol == XK_KP_Right))
6963 if (resource_info->quantum >= (
int) (crop_info.width-crop_info.x))
6964 resource_info->quantum=(int) (crop_info.width-crop_info.x-1);
6965 crop_info.x+=resource_info->quantum;
6966 crop_info.width-=resource_info->quantum;
6968 if ((
int) (windows->image.x+windows->image.width) >
6969 (
int) crop_info.width)
6970 windows->image.x=(
int) (crop_info.width-windows->image.width);
6971 if ((
int) (windows->image.y+windows->image.height) >
6972 (
int) crop_info.height)
6973 windows->image.y=(
int) (crop_info.height-windows->image.height);
6974 XSetCropGeometry(display,windows,&crop_info,*image);
6975 windows->image.window_changes.width=(int) crop_info.width;
6976 windows->image.window_changes.height=(
int) crop_info.height;
6977 (void) XSetWindowBackgroundPixmap(display,windows->image.id,None);
6978 (void) XConfigureImage(display,resource_info,windows,*image);
6979 return(NullCommand);
6981 XTranslateImage(display,windows,*image,key_symbol);
6982 return(NullCommand);
6985 return(NullCommand);
6987 return(NullCommand);
7028 static Image *XMagickCommand(Display *display,XResourceInfo *resource_info,
7029 XWindows *windows,
const CommandType command,
Image **image)
7032 filename[MaxTextExtent],
7033 geometry[MaxTextExtent],
7034 modulate_factors[MaxTextExtent];
7063 color[MaxTextExtent] =
"gray";
7072 XCheckRefreshWindows(display,windows);
7073 XImageCache(display,resource_info,windows,command,image);
7074 nexus=NewImageList();
7075 windows->image.window_changes.width=windows->image.ximage->width;
7076 windows->image.window_changes.height=windows->image.ximage->height;
7077 image_info=CloneImageInfo(resource_info->image_info);
7078 SetGeometryInfo(&geometry_info);
7079 GetQuantizeInfo(&quantize_info);
7087 nexus=XOpenImage(display,resource_info,windows,MagickFalse);
7095 for (i=0; i < resource_info->quantum; i++)
7096 XClientMessage(display,windows->image.id,windows->im_protocols,
7097 windows->im_next_image,CurrentTime);
7105 for (i=0; i < resource_info->quantum; i++)
7106 XClientMessage(display,windows->image.id,windows->im_protocols,
7107 windows->im_former_image,CurrentTime);
7118 if (*resource_info->home_directory ==
'\0')
7119 (void) CopyMagickString(resource_info->home_directory,
".",
7121 status=chdir(resource_info->home_directory);
7123 (void) ThrowMagickException(&(*image)->exception,GetMagickModule(),
7124 FileOpenError,
"UnableToOpenFile",
"%s",resource_info->home_directory);
7125 nexus=XOpenImage(display,resource_info,windows,MagickTrue);
7133 status=XSaveImage(display,resource_info,windows,*image);
7134 if (status == MagickFalse)
7137 message[MaxTextExtent];
7139 (void) FormatLocaleString(message,MaxTextExtent,
"%s:%s",
7140 (*image)->exception.reason != (
char *) NULL ?
7141 (*image)->exception.reason :
"",
7142 (*image)->exception.description != (
char *) NULL ?
7143 (*image)->exception.description :
"");
7144 XNoticeWidget(display,windows,
"Unable to save file:",message);
7154 status=XPrintImage(display,resource_info,windows,*image);
7155 if (status == MagickFalse)
7158 message[MaxTextExtent];
7160 (void) FormatLocaleString(message,MaxTextExtent,
"%s:%s",
7161 (*image)->exception.reason != (
char *) NULL ?
7162 (*image)->exception.reason :
"",
7163 (*image)->exception.description != (
char *) NULL ?
7164 (*image)->exception.description :
"");
7165 XNoticeWidget(display,windows,
"Unable to print file:",message);
7173 filename[MaxTextExtent] =
"\0";
7178 XFileBrowserWidget(display,windows,
"Delete",filename);
7179 if (*filename ==
'\0')
7181 status=ShredFile(filename);
7182 status|=remove_utf8(filename);
7183 if (status != MagickFalse)
7184 XNoticeWidget(display,windows,
"Unable to delete image file:",filename);
7193 color[MaxTextExtent] =
"gray",
7194 geometry[MaxTextExtent] =
"640x480";
7197 *format =
"gradient";
7202 status=XDialogWidget(display,windows,
"New",
"Enter image geometry:",
7204 if (*geometry ==
'\0')
7208 XColorBrowserWidget(display,windows,
"Select",color);
7214 (void) FormatLocaleString(image_info->filename,MaxTextExtent,
7215 "%s:%s",format,color);
7216 (void) CloneString(&image_info->size,geometry);
7217 nexus=ReadImage(image_info,&(*image)->exception);
7218 CatchException(&(*image)->exception);
7219 XClientMessage(display,windows->image.id,windows->im_protocols,
7220 windows->im_next_image,CurrentTime);
7223 case VisualDirectoryCommand:
7228 nexus=XVisualDirectoryImage(display,resource_info,windows);
7236 if (resource_info->confirm_exit == MagickFalse)
7237 XClientMessage(display,windows->image.id,windows->im_protocols,
7238 windows->im_exit,CurrentTime);
7247 status=XConfirmWidget(display,windows,
"Do you really want to exit",
7248 resource_info->client_name);
7250 XClientMessage(display,windows->image.id,windows->im_protocols,
7251 windows->im_exit,CurrentTime);
7260 (void) XCropImage(display,resource_info,windows,*image,CutMode);
7268 (void) XCropImage(display,resource_info,windows,*image,CopyMode);
7276 status=XPasteImage(display,resource_info,windows,*image);
7277 if (status == MagickFalse)
7279 XNoticeWidget(display,windows,
"Unable to paste X image",
7280 (*image)->filename);
7285 case HalfSizeCommand:
7290 windows->image.window_changes.width=windows->image.ximage->width/2;
7291 windows->image.window_changes.height=windows->image.ximage->height/2;
7292 (void) XConfigureImage(display,resource_info,windows,*image);
7295 case OriginalSizeCommand:
7300 windows->image.window_changes.width=(int) (*image)->columns;
7301 windows->image.window_changes.height=(
int) (*image)->rows;
7302 (void) XConfigureImage(display,resource_info,windows,*image);
7305 case DoubleSizeCommand:
7310 windows->image.window_changes.width=windows->image.ximage->width << 1;
7311 windows->image.window_changes.height=windows->image.ximage->height << 1;
7312 (void) XConfigureImage(display,resource_info,windows,*image);
7331 width=(size_t) windows->image.ximage->width;
7332 height=(
size_t) windows->image.ximage->height;
7335 (void) FormatLocaleString(geometry,MaxTextExtent,
"%.20gx%.20g+0+0",
7336 (
double) width,(double) height);
7337 status=XDialogWidget(display,windows,
"Resize",
7338 "Enter resize geometry (e.g. 640x480, 200%):",geometry);
7339 if (*geometry ==
'\0')
7342 (void) ConcatenateMagickString(geometry,
"!",MaxTextExtent);
7343 (void) ParseMetaGeometry(geometry,&x,&y,&width,&height);
7344 windows->image.window_changes.width=(int) width;
7345 windows->image.window_changes.height=(int) height;
7346 (void) XConfigureImage(display,resource_info,windows,*image);
7352 image_geometry[MaxTextExtent];
7354 if ((windows->image.crop_geometry == (
char *) NULL) &&
7355 ((
int) (*image)->columns == windows->image.ximage->width) &&
7356 ((
int) (*image)->rows == windows->image.ximage->height))
7361 XSetCursorState(display,windows,MagickTrue);
7362 XCheckRefreshWindows(display,windows);
7366 (void) FormatLocaleString(image_geometry,MaxTextExtent,
"%dx%d!",
7367 windows->image.ximage->width,windows->image.ximage->height);
7368 (void) TransformImage(image,windows->image.crop_geometry,image_geometry);
7369 if (windows->image.crop_geometry != (
char *) NULL)
7370 windows->image.crop_geometry=(
char *)
7371 RelinquishMagickMemory(windows->image.crop_geometry);
7374 XConfigureImageColormap(display,resource_info,windows,*image);
7375 (void) XConfigureImage(display,resource_info,windows,*image);
7378 case RefreshCommand:
7380 (void) XConfigureImage(display,resource_info,windows,*image);
7383 case RestoreCommand:
7388 if ((windows->image.width == (
unsigned int) (*image)->columns) &&
7389 (windows->image.height == (
unsigned int) (*image)->rows) &&
7390 (windows->image.crop_geometry == (
char *) NULL))
7392 (void) XBell(display,0);
7395 windows->image.window_changes.width=(int) (*image)->columns;
7396 windows->image.window_changes.height=(
int) (*image)->rows;
7397 if (windows->image.crop_geometry != (
char *) NULL)
7399 windows->image.crop_geometry=(
char *)
7400 RelinquishMagickMemory(windows->image.crop_geometry);
7401 windows->image.crop_geometry=(
char *) NULL;
7405 XConfigureImageColormap(display,resource_info,windows,*image);
7406 (void) XConfigureImage(display,resource_info,windows,*image);
7414 (void) XCropImage(display,resource_info,windows,*image,CropMode);
7422 status=XChopImage(display,resource_info,windows,image);
7423 if (status == MagickFalse)
7425 XNoticeWidget(display,windows,
"Unable to cut X image",
7426 (*image)->filename);
7439 XSetCursorState(display,windows,MagickTrue);
7440 XCheckRefreshWindows(display,windows);
7441 flop_image=FlopImage(*image,&(*image)->exception);
7442 if (flop_image != (
Image *) NULL)
7444 *image=DestroyImage(*image);
7447 CatchException(&(*image)->exception);
7448 XSetCursorState(display,windows,MagickFalse);
7449 if (windows->image.crop_geometry != (
char *) NULL)
7454 width=(
unsigned int) (*image)->columns;
7455 height=(
unsigned int) (*image)->rows;
7456 (void) XParseGeometry(windows->image.crop_geometry,&x,&y,
7458 (void) FormatLocaleString(windows->image.crop_geometry,MaxTextExtent,
7459 "%ux%u%+d%+d",width,height,(
int) (*image)->columns-(int) width-x,y);
7461 if (windows->image.orphan != MagickFalse)
7463 (void) XConfigureImage(display,resource_info,windows,*image);
7474 XSetCursorState(display,windows,MagickTrue);
7475 XCheckRefreshWindows(display,windows);
7476 flip_image=FlipImage(*image,&(*image)->exception);
7477 if (flip_image != (
Image *) NULL)
7479 *image=DestroyImage(*image);
7482 CatchException(&(*image)->exception);
7483 XSetCursorState(display,windows,MagickFalse);
7484 if (windows->image.crop_geometry != (
char *) NULL)
7489 width=(
unsigned int) (*image)->columns;
7490 height=(
unsigned int) (*image)->rows;
7491 (void) XParseGeometry(windows->image.crop_geometry,&x,&y,
7493 (void) FormatLocaleString(windows->image.crop_geometry,MaxTextExtent,
7494 "%ux%u%+d%+d",width,height,x,(
int) (*image)->rows-(int) height-y);
7496 if (windows->image.orphan != MagickFalse)
7498 (void) XConfigureImage(display,resource_info,windows,*image);
7501 case RotateRightCommand:
7506 status=XRotateImage(display,resource_info,windows,90.0,image);
7507 if (status == MagickFalse)
7509 XNoticeWidget(display,windows,
"Unable to rotate X image",
7510 (*image)->filename);
7515 case RotateLeftCommand:
7520 status=XRotateImage(display,resource_info,windows,-90.0,image);
7521 if (status == MagickFalse)
7523 XNoticeWidget(display,windows,
"Unable to rotate X image",
7524 (*image)->filename);
7534 status=XRotateImage(display,resource_info,windows,0.0,image);
7535 if (status == MagickFalse)
7537 XNoticeWidget(display,windows,
"Unable to rotate X image",
7538 (*image)->filename);
7549 geometry[MaxTextExtent] =
"45.0x45.0";
7554 XColorBrowserWidget(display,windows,
"Select",color);
7557 (void) XDialogWidget(display,windows,
"Shear",
"Enter shear geometry:",
7559 if (*geometry ==
'\0')
7564 (void) XMagickCommand(display,resource_info,windows,ApplyCommand,image);
7565 XSetCursorState(display,windows,MagickTrue);
7566 XCheckRefreshWindows(display,windows);
7567 (void) QueryColorDatabase(color,&(*image)->background_color,
7568 &(*image)->exception);
7569 flags=ParseGeometry(geometry,&geometry_info);
7570 if ((flags & SigmaValue) == 0)
7571 geometry_info.sigma=geometry_info.rho;
7572 shear_image=ShearImage(*image,geometry_info.rho,geometry_info.sigma,
7573 &(*image)->exception);
7574 if (shear_image != (
Image *) NULL)
7576 *image=DestroyImage(*image);
7579 CatchException(&(*image)->exception);
7580 XSetCursorState(display,windows,MagickFalse);
7581 if (windows->image.orphan != MagickFalse)
7583 windows->image.window_changes.width=(int) (*image)->columns;
7584 windows->image.window_changes.height=(
int) (*image)->rows;
7585 XConfigureImageColormap(display,resource_info,windows,*image);
7586 (void) XConfigureImage(display,resource_info,windows,*image);
7595 geometry[MaxTextExtent] =
"+2+2";
7600 (void) XDialogWidget(display,windows,
"Roll",
"Enter roll geometry:",
7602 if (*geometry ==
'\0')
7607 (void) XMagickCommand(display,resource_info,windows,ApplyCommand,image);
7608 XSetCursorState(display,windows,MagickTrue);
7609 XCheckRefreshWindows(display,windows);
7610 (void) ParsePageGeometry(*image,geometry,&page_geometry,
7611 &(*image)->exception);
7612 roll_image=RollImage(*image,page_geometry.x,page_geometry.y,
7613 &(*image)->exception);
7614 if (roll_image != (
Image *) NULL)
7616 *image=DestroyImage(*image);
7619 CatchException(&(*image)->exception);
7620 XSetCursorState(display,windows,MagickFalse);
7621 if (windows->image.orphan != MagickFalse)
7623 windows->image.window_changes.width=(int) (*image)->columns;
7624 windows->image.window_changes.height=(
int) (*image)->rows;
7625 XConfigureImageColormap(display,resource_info,windows,*image);
7626 (void) XConfigureImage(display,resource_info,windows,*image);
7632 fuzz[MaxTextExtent];
7637 (void) FormatLocaleString(fuzz,MaxTextExtent,
"%g%%",100.0*
7638 (*image)->fuzz/(QuantumRange+1.0));
7639 (void) XDialogWidget(display,windows,
"Trim",
"Enter fuzz factor:",fuzz);
7642 (*image)->fuzz=StringToDoubleInterval(fuzz,(
double) QuantumRange+1.0);
7646 status=XTrimImage(display,resource_info,windows,*image);
7647 if (status == MagickFalse)
7649 XNoticeWidget(display,windows,
"Unable to trim X image",
7650 (*image)->filename);
7658 hue_percent[MaxTextExtent] =
"110";
7663 (void) XDialogWidget(display,windows,
"Apply",
7664 "Enter percent change in image hue (0-200):",hue_percent);
7665 if (*hue_percent ==
'\0')
7670 XSetCursorState(display,windows,MagickTrue);
7671 XCheckRefreshWindows(display,windows);
7672 (void) CopyMagickString(modulate_factors,
"100.0/100.0/",MaxTextExtent);
7673 (void) ConcatenateMagickString(modulate_factors,hue_percent,
7675 (void) ModulateImage(*image,modulate_factors);
7676 XSetCursorState(display,windows,MagickFalse);
7677 if (windows->image.orphan != MagickFalse)
7679 XConfigureImageColormap(display,resource_info,windows,*image);
7680 (void) XConfigureImage(display,resource_info,windows,*image);
7683 case SaturationCommand:
7686 saturation_percent[MaxTextExtent] =
"110";
7691 (void) XDialogWidget(display,windows,
"Apply",
7692 "Enter percent change in color saturation (0-200):",saturation_percent);
7693 if (*saturation_percent ==
'\0')
7698 XSetCursorState(display,windows,MagickTrue);
7699 XCheckRefreshWindows(display,windows);
7700 (void) CopyMagickString(modulate_factors,
"100.0/",MaxTextExtent);
7701 (void) ConcatenateMagickString(modulate_factors,saturation_percent,
7703 (void) ModulateImage(*image,modulate_factors);
7704 XSetCursorState(display,windows,MagickFalse);
7705 if (windows->image.orphan != MagickFalse)
7707 XConfigureImageColormap(display,resource_info,windows,*image);
7708 (void) XConfigureImage(display,resource_info,windows,*image);
7711 case BrightnessCommand:
7714 brightness_percent[MaxTextExtent] =
"110";
7719 (void) XDialogWidget(display,windows,
"Apply",
7720 "Enter percent change in color brightness (0-200):",brightness_percent);
7721 if (*brightness_percent ==
'\0')
7726 XSetCursorState(display,windows,MagickTrue);
7727 XCheckRefreshWindows(display,windows);
7728 (void) CopyMagickString(modulate_factors,brightness_percent,
7730 (void) ModulateImage(*image,modulate_factors);
7731 XSetCursorState(display,windows,MagickFalse);
7732 if (windows->image.orphan != MagickFalse)
7734 XConfigureImageColormap(display,resource_info,windows,*image);
7735 (void) XConfigureImage(display,resource_info,windows,*image);
7741 factor[MaxTextExtent] =
"1.6";
7746 (void) XDialogWidget(display,windows,
"Gamma",
7747 "Enter gamma value (e.g. 1.0,1.0,1.6):",factor);
7748 if (*factor ==
'\0')
7753 XSetCursorState(display,windows,MagickTrue);
7754 XCheckRefreshWindows(display,windows);
7755 (void) GammaImage(*image,factor);
7756 XSetCursorState(display,windows,MagickFalse);
7757 if (windows->image.orphan != MagickFalse)
7759 XConfigureImageColormap(display,resource_info,windows,*image);
7760 (void) XConfigureImage(display,resource_info,windows,*image);
7768 XSetCursorState(display,windows,MagickTrue);
7769 XCheckRefreshWindows(display,windows);
7770 (void) ContrastImage(*image,MagickTrue);
7771 XSetCursorState(display,windows,MagickFalse);
7772 if (windows->image.orphan != MagickFalse)
7774 XConfigureImageColormap(display,resource_info,windows,*image);
7775 (void) XConfigureImage(display,resource_info,windows,*image);
7783 XSetCursorState(display,windows,MagickTrue);
7784 XCheckRefreshWindows(display,windows);
7785 (void) ContrastImage(*image,MagickFalse);
7786 XSetCursorState(display,windows,MagickFalse);
7787 if (windows->image.orphan != MagickFalse)
7789 XConfigureImageColormap(display,resource_info,windows,*image);
7790 (void) XConfigureImage(display,resource_info,windows,*image);
7793 case ContrastStretchCommand:
7800 levels[MaxTextExtent] =
"1%";
7805 (void) XDialogWidget(display,windows,
"Contrast Stretch",
7806 "Enter black and white points:",levels);
7807 if (*levels ==
'\0')
7812 XSetCursorState(display,windows,MagickTrue);
7813 XCheckRefreshWindows(display,windows);
7814 flags=ParseGeometry(levels,&geometry_info);
7815 black_point=geometry_info.rho;
7816 white_point=(flags & SigmaValue) != 0 ? geometry_info.sigma : black_point;
7817 if ((flags & PercentValue) != 0)
7819 black_point*=(double) (*image)->columns*(*image)->rows/100.0;
7820 white_point*=(
double) (*image)->columns*(*image)->rows/100.0;
7822 white_point=(MagickRealType) (*image)->columns*(*image)->rows-white_point;
7823 (
void) ContrastStretchImageChannel(*image,DefaultChannels,black_point,
7825 XSetCursorState(display,windows,MagickFalse);
7826 if (windows->image.orphan != MagickFalse)
7828 XConfigureImageColormap(display,resource_info,windows,*image);
7829 (void) XConfigureImage(display,resource_info,windows,*image);
7832 case SigmoidalContrastCommand:
7835 levels[MaxTextExtent] =
"3x50%";
7840 (void) XDialogWidget(display,windows,
"Sigmoidal Contrast",
7841 "Enter contrast and midpoint:",levels);
7842 if (*levels ==
'\0')
7847 XSetCursorState(display,windows,MagickTrue);
7848 XCheckRefreshWindows(display,windows);
7849 (void) SigmoidalContrastImage(*image,MagickTrue,levels);
7850 XSetCursorState(display,windows,MagickFalse);
7851 if (windows->image.orphan != MagickFalse)
7853 XConfigureImageColormap(display,resource_info,windows,*image);
7854 (void) XConfigureImage(display,resource_info,windows,*image);
7857 case NormalizeCommand:
7862 XSetCursorState(display,windows,MagickTrue);
7863 XCheckRefreshWindows(display,windows);
7864 (void) NormalizeImage(*image);
7865 XSetCursorState(display,windows,MagickFalse);
7866 if (windows->image.orphan != MagickFalse)
7868 XConfigureImageColormap(display,resource_info,windows,*image);
7869 (void) XConfigureImage(display,resource_info,windows,*image);
7872 case EqualizeCommand:
7877 XSetCursorState(display,windows,MagickTrue);
7878 XCheckRefreshWindows(display,windows);
7879 (void) EqualizeImage(*image);
7880 XSetCursorState(display,windows,MagickFalse);
7881 if (windows->image.orphan != MagickFalse)
7883 XConfigureImageColormap(display,resource_info,windows,*image);
7884 (void) XConfigureImage(display,resource_info,windows,*image);
7892 XSetCursorState(display,windows,MagickTrue);
7893 XCheckRefreshWindows(display,windows);
7894 (void) NegateImage(*image,MagickFalse);
7895 XSetCursorState(display,windows,MagickFalse);
7896 if (windows->image.orphan != MagickFalse)
7898 XConfigureImageColormap(display,resource_info,windows,*image);
7899 (void) XConfigureImage(display,resource_info,windows,*image);
7902 case GrayscaleCommand:
7907 XSetCursorState(display,windows,MagickTrue);
7908 XCheckRefreshWindows(display,windows);
7909 (void) SetImageType(*image,(*image)->matte == MagickFalse ?
7910 GrayscaleType : GrayscaleMatteType);
7911 XSetCursorState(display,windows,MagickFalse);
7912 if (windows->image.orphan != MagickFalse)
7914 XConfigureImageColormap(display,resource_info,windows,*image);
7915 (void) XConfigureImage(display,resource_info,windows,*image);
7924 filename[MaxTextExtent] =
"\0";
7929 XFileBrowserWidget(display,windows,
"Map",filename);
7930 if (*filename ==
'\0')
7935 XSetCursorState(display,windows,MagickTrue);
7936 XCheckRefreshWindows(display,windows);
7937 (void) CopyMagickString(image_info->filename,filename,MaxTextExtent);
7938 affinity_image=ReadImage(image_info,&(*image)->exception);
7939 if (affinity_image != (
Image *) NULL)
7941 (void) RemapImage(&quantize_info,*image,affinity_image);
7942 affinity_image=DestroyImage(affinity_image);
7944 CatchException(&(*image)->exception);
7945 XSetCursorState(display,windows,MagickFalse);
7946 if (windows->image.orphan != MagickFalse)
7948 XConfigureImageColormap(display,resource_info,windows,*image);
7949 (void) XConfigureImage(display,resource_info,windows,*image);
7952 case QuantizeCommand:
7958 colors[MaxTextExtent] =
"256";
7963 status=XDialogWidget(display,windows,
"Quantize",
7964 "Maximum number of colors:",colors);
7965 if (*colors ==
'\0')
7970 XSetCursorState(display,windows,MagickTrue);
7971 XCheckRefreshWindows(display,windows);
7972 quantize_info.number_colors=StringToUnsignedLong(colors);
7973 quantize_info.dither=status != 0 ? MagickTrue : MagickFalse;
7974 (void) QuantizeImage(&quantize_info,*image);
7975 XSetCursorState(display,windows,MagickFalse);
7976 if (windows->image.orphan != MagickFalse)
7978 XConfigureImageColormap(display,resource_info,windows,*image);
7979 (void) XConfigureImage(display,resource_info,windows,*image);
7982 case DespeckleCommand:
7990 XSetCursorState(display,windows,MagickTrue);
7991 XCheckRefreshWindows(display,windows);
7992 despeckle_image=DespeckleImage(*image,&(*image)->exception);
7993 if (despeckle_image != (
Image *) NULL)
7995 *image=DestroyImage(*image);
7996 *image=despeckle_image;
7998 CatchException(&(*image)->exception);
7999 XSetCursorState(display,windows,MagickFalse);
8000 if (windows->image.orphan != MagickFalse)
8002 XConfigureImageColormap(display,resource_info,windows,*image);
8003 (void) XConfigureImage(display,resource_info,windows,*image);
8012 radius[MaxTextExtent] =
"0.0x1.0";
8017 (void) XDialogWidget(display,windows,
"Emboss",
8018 "Enter the emboss radius and standard deviation:",radius);
8019 if (*radius ==
'\0')
8024 XSetCursorState(display,windows,MagickTrue);
8025 XCheckRefreshWindows(display,windows);
8026 flags=ParseGeometry(radius,&geometry_info);
8027 if ((flags & SigmaValue) == 0)
8028 geometry_info.sigma=1.0;
8029 emboss_image=EmbossImage(*image,geometry_info.rho,geometry_info.sigma,
8030 &(*image)->exception);
8031 if (emboss_image != (
Image *) NULL)
8033 *image=DestroyImage(*image);
8034 *image=emboss_image;
8036 CatchException(&(*image)->exception);
8037 XSetCursorState(display,windows,MagickFalse);
8038 if (windows->image.orphan != MagickFalse)
8040 XConfigureImageColormap(display,resource_info,windows,*image);
8041 (void) XConfigureImage(display,resource_info,windows,*image);
8044 case ReduceNoiseCommand:
8050 radius[MaxTextExtent] =
"0";
8055 (void) XDialogWidget(display,windows,
"Reduce Noise",
8056 "Enter the noise radius:",radius);
8057 if (*radius ==
'\0')
8062 XSetCursorState(display,windows,MagickTrue);
8063 XCheckRefreshWindows(display,windows);
8064 flags=ParseGeometry(radius,&geometry_info);
8065 noise_image=StatisticImage(*image,NonpeakStatistic,(
size_t)
8066 geometry_info.rho,(
size_t) geometry_info.rho,&(*image)->exception);
8067 if (noise_image != (
Image *) NULL)
8069 *image=DestroyImage(*image);
8072 CatchException(&(*image)->exception);
8073 XSetCursorState(display,windows,MagickFalse);
8074 if (windows->image.orphan != MagickFalse)
8076 XConfigureImageColormap(display,resource_info,windows,*image);
8077 (void) XConfigureImage(display,resource_info,windows,*image);
8080 case AddNoiseCommand:
8089 noise_type[MaxTextExtent] =
"Gaussian";
8094 noises=GetCommandOptions(MagickNoiseOptions);
8095 if (noises == (
char **) NULL)
8097 XListBrowserWidget(display,windows,&windows->widget,
8098 (
const char **) noises,
"Add Noise",
8099 "Select a type of noise to add to your image:",noise_type);
8100 noises=DestroyStringList(noises);
8101 if (*noise_type ==
'\0')
8103 XSetCursorState(display,windows,MagickTrue);
8104 XCheckRefreshWindows(display,windows);
8105 noise_image=AddNoiseImage(*image,(NoiseType) ParseCommandOption(
8106 MagickNoiseOptions,MagickFalse,noise_type),&(*image)->exception);
8107 if (noise_image != (
Image *) NULL)
8109 *image=DestroyImage(*image);
8112 CatchException(&(*image)->exception);
8113 XSetCursorState(display,windows,MagickFalse);
8114 if (windows->image.orphan != MagickFalse)
8116 XConfigureImageColormap(display,resource_info,windows,*image);
8117 (void) XConfigureImage(display,resource_info,windows,*image);
8120 case SharpenCommand:
8126 radius[MaxTextExtent] =
"0.0x1.0";
8131 (void) XDialogWidget(display,windows,
"Sharpen",
8132 "Enter the sharpen radius and standard deviation:",radius);
8133 if (*radius ==
'\0')
8138 XSetCursorState(display,windows,MagickTrue);
8139 XCheckRefreshWindows(display,windows);
8140 flags=ParseGeometry(radius,&geometry_info);
8141 sharp_image=SharpenImage(*image,geometry_info.rho,geometry_info.sigma,
8142 &(*image)->exception);
8143 if (sharp_image != (
Image *) NULL)
8145 *image=DestroyImage(*image);
8148 CatchException(&(*image)->exception);
8149 XSetCursorState(display,windows,MagickFalse);
8150 if (windows->image.orphan != MagickFalse)
8152 XConfigureImageColormap(display,resource_info,windows,*image);
8153 (void) XConfigureImage(display,resource_info,windows,*image);
8162 radius[MaxTextExtent] =
"0.0x1.0";
8167 (void) XDialogWidget(display,windows,
"Blur",
8168 "Enter the blur radius and standard deviation:",radius);
8169 if (*radius ==
'\0')
8174 XSetCursorState(display,windows,MagickTrue);
8175 XCheckRefreshWindows(display,windows);
8176 flags=ParseGeometry(radius,&geometry_info);
8177 blur_image=BlurImage(*image,geometry_info.rho,geometry_info.sigma,
8178 &(*image)->exception);
8179 if (blur_image != (
Image *) NULL)
8181 *image=DestroyImage(*image);
8184 CatchException(&(*image)->exception);
8185 XSetCursorState(display,windows,MagickFalse);
8186 if (windows->image.orphan != MagickFalse)
8188 XConfigureImageColormap(display,resource_info,windows,*image);
8189 (void) XConfigureImage(display,resource_info,windows,*image);
8192 case ThresholdCommand:
8198 factor[MaxTextExtent] =
"128";
8203 (void) XDialogWidget(display,windows,
"Threshold",
8204 "Enter threshold value:",factor);
8205 if (*factor ==
'\0')
8210 XSetCursorState(display,windows,MagickTrue);
8211 XCheckRefreshWindows(display,windows);
8212 threshold=StringToDoubleInterval(factor,(
double) QuantumRange+1.0);
8213 (void) BilevelImage(*image,threshold);
8214 XSetCursorState(display,windows,MagickFalse);
8215 if (windows->image.orphan != MagickFalse)
8217 XConfigureImageColormap(display,resource_info,windows,*image);
8218 (void) XConfigureImage(display,resource_info,windows,*image);
8221 case EdgeDetectCommand:
8227 radius[MaxTextExtent] =
"0";
8232 (void) XDialogWidget(display,windows,
"Detect Edges",
8233 "Enter the edge detect radius:",radius);
8234 if (*radius ==
'\0')
8239 XSetCursorState(display,windows,MagickTrue);
8240 XCheckRefreshWindows(display,windows);
8241 flags=ParseGeometry(radius,&geometry_info);
8242 edge_image=EdgeImage(*image,geometry_info.rho,&(*image)->exception);
8243 if (edge_image != (
Image *) NULL)
8245 *image=DestroyImage(*image);
8248 CatchException(&(*image)->exception);
8249 XSetCursorState(display,windows,MagickFalse);
8250 if (windows->image.orphan != MagickFalse)
8252 XConfigureImageColormap(display,resource_info,windows,*image);
8253 (void) XConfigureImage(display,resource_info,windows,*image);
8262 amount[MaxTextExtent] =
"2";
8267 (void) XDialogWidget(display,windows,
"Spread",
8268 "Enter the displacement amount:",amount);
8269 if (*amount ==
'\0')
8274 XSetCursorState(display,windows,MagickTrue);
8275 XCheckRefreshWindows(display,windows);
8276 flags=ParseGeometry(amount,&geometry_info);
8277 spread_image=EdgeImage(*image,geometry_info.rho,&(*image)->exception);
8278 if (spread_image != (
Image *) NULL)
8280 *image=DestroyImage(*image);
8281 *image=spread_image;
8283 CatchException(&(*image)->exception);
8284 XSetCursorState(display,windows,MagickFalse);
8285 if (windows->image.orphan != MagickFalse)
8287 XConfigureImageColormap(display,resource_info,windows,*image);
8288 (void) XConfigureImage(display,resource_info,windows,*image);
8300 geometry[MaxTextExtent] =
"30x30";
8305 status=XDialogWidget(display,windows,
"Shade",
8306 "Enter the azimuth and elevation of the light source:",geometry);
8307 if (*geometry ==
'\0')
8312 XSetCursorState(display,windows,MagickTrue);
8313 XCheckRefreshWindows(display,windows);
8314 flags=ParseGeometry(geometry,&geometry_info);
8315 if ((flags & SigmaValue) == 0)
8316 geometry_info.sigma=1.0;
8317 shade_image=ShadeImage(*image,status != 0 ? MagickFalse : MagickTrue,
8318 geometry_info.rho,geometry_info.sigma,&(*image)->exception);
8319 if (shade_image != (
Image *) NULL)
8321 *image=DestroyImage(*image);
8324 CatchException(&(*image)->exception);
8325 XSetCursorState(display,windows,MagickFalse);
8326 if (windows->image.orphan != MagickFalse)
8328 XConfigureImageColormap(display,resource_info,windows,*image);
8329 (void) XConfigureImage(display,resource_info,windows,*image);
8335 bevel_width[MaxTextExtent] =
"10";
8340 (void) XDialogWidget(display,windows,
"Raise",
"Bevel width:",bevel_width);
8341 if (*bevel_width ==
'\0')
8346 (void) XMagickCommand(display,resource_info,windows,ApplyCommand,image);
8347 XSetCursorState(display,windows,MagickTrue);
8348 XCheckRefreshWindows(display,windows);
8349 (void) ParsePageGeometry(*image,bevel_width,&page_geometry,
8350 &(*image)->exception);
8351 (void) RaiseImage(*image,&page_geometry,MagickTrue);
8352 XSetCursorState(display,windows,MagickFalse);
8353 if (windows->image.orphan != MagickFalse)
8355 XConfigureImageColormap(display,resource_info,windows,*image);
8356 (void) XConfigureImage(display,resource_info,windows,*image);
8359 case SegmentCommand:
8362 threshold[MaxTextExtent] =
"1.0x1.5";
8367 (void) XDialogWidget(display,windows,
"Segment",
"Smooth threshold:",
8369 if (*threshold ==
'\0')
8374 XSetCursorState(display,windows,MagickTrue);
8375 XCheckRefreshWindows(display,windows);
8376 flags=ParseGeometry(threshold,&geometry_info);
8377 if ((flags & SigmaValue) == 0)
8378 geometry_info.sigma=1.0;
8379 (void) SegmentImage(*image,sRGBColorspace,MagickFalse,geometry_info.rho,
8380 geometry_info.sigma);
8381 XSetCursorState(display,windows,MagickFalse);
8382 if (windows->image.orphan != MagickFalse)
8384 XConfigureImageColormap(display,resource_info,windows,*image);
8385 (void) XConfigureImage(display,resource_info,windows,*image);
8388 case SepiaToneCommand:
8397 factor[MaxTextExtent] =
"80%";
8402 (void) XDialogWidget(display,windows,
"Sepia Tone",
8403 "Enter the sepia tone factor (0 - 99.9%):",factor);
8404 if (*factor ==
'\0')
8409 XSetCursorState(display,windows,MagickTrue);
8410 XCheckRefreshWindows(display,windows);
8411 threshold=StringToDoubleInterval(factor,(
double) QuantumRange+1.0);
8412 sepia_image=SepiaToneImage(*image,threshold,&(*image)->exception);
8413 if (sepia_image != (
Image *) NULL)
8415 *image=DestroyImage(*image);
8418 CatchException(&(*image)->exception);
8419 XSetCursorState(display,windows,MagickFalse);
8420 if (windows->image.orphan != MagickFalse)
8422 XConfigureImageColormap(display,resource_info,windows,*image);
8423 (void) XConfigureImage(display,resource_info,windows,*image);
8426 case SolarizeCommand:
8432 factor[MaxTextExtent] =
"60%";
8437 (void) XDialogWidget(display,windows,
"Solarize",
8438 "Enter the solarize factor (0 - 99.9%):",factor);
8439 if (*factor ==
'\0')
8444 XSetCursorState(display,windows,MagickTrue);
8445 XCheckRefreshWindows(display,windows);
8446 threshold=StringToDoubleInterval(factor,(
double) QuantumRange+1.0);
8447 (void) SolarizeImage(*image,threshold);
8448 XSetCursorState(display,windows,MagickFalse);
8449 if (windows->image.orphan != MagickFalse)
8451 XConfigureImageColormap(display,resource_info,windows,*image);
8452 (void) XConfigureImage(display,resource_info,windows,*image);
8461 degrees[MaxTextExtent] =
"60";
8466 (void) XDialogWidget(display,windows,
"Swirl",
"Enter the swirl angle:",
8468 if (*degrees ==
'\0')
8473 XSetCursorState(display,windows,MagickTrue);
8474 XCheckRefreshWindows(display,windows);
8475 flags=ParseGeometry(degrees,&geometry_info);
8476 swirl_image=SwirlImage(*image,geometry_info.rho,&(*image)->exception);
8477 if (swirl_image != (
Image *) NULL)
8479 *image=DestroyImage(*image);
8482 CatchException(&(*image)->exception);
8483 XSetCursorState(display,windows,MagickFalse);
8484 if (windows->image.orphan != MagickFalse)
8486 XConfigureImageColormap(display,resource_info,windows,*image);
8487 (void) XConfigureImage(display,resource_info,windows,*image);
8490 case ImplodeCommand:
8496 factor[MaxTextExtent] =
"0.3";
8501 (void) XDialogWidget(display,windows,
"Implode",
8502 "Enter the implosion/explosion factor (-1.0 - 1.0):",factor);
8503 if (*factor ==
'\0')
8508 XSetCursorState(display,windows,MagickTrue);
8509 XCheckRefreshWindows(display,windows);
8510 flags=ParseGeometry(factor,&geometry_info);
8511 implode_image=ImplodeImage(*image,geometry_info.rho,&(*image)->exception);
8512 if (implode_image != (
Image *) NULL)
8514 *image=DestroyImage(*image);
8515 *image=implode_image;
8517 CatchException(&(*image)->exception);
8518 XSetCursorState(display,windows,MagickFalse);
8519 if (windows->image.orphan != MagickFalse)
8521 XConfigureImageColormap(display,resource_info,windows,*image);
8522 (void) XConfigureImage(display,resource_info,windows,*image);
8525 case VignetteCommand:
8531 geometry[MaxTextExtent] =
"0x20";
8536 (void) XDialogWidget(display,windows,
"Vignette",
8537 "Enter the radius, sigma, and x and y offsets:",geometry);
8538 if (*geometry ==
'\0')
8543 XSetCursorState(display,windows,MagickTrue);
8544 XCheckRefreshWindows(display,windows);
8545 flags=ParseGeometry(geometry,&geometry_info);
8546 if ((flags & SigmaValue) == 0)
8547 geometry_info.sigma=1.0;
8548 if ((flags & XiValue) == 0)
8549 geometry_info.xi=0.1*(*image)->columns;
8550 if ((flags & PsiValue) == 0)
8551 geometry_info.psi=0.1*(*image)->rows;
8552 vignette_image=VignetteImage(*image,geometry_info.rho,geometry_info.sigma,
8553 (ssize_t) ceil(geometry_info.xi-0.5),(ssize_t) ceil(geometry_info.psi-
8554 0.5),&(*image)->exception);
8555 if (vignette_image != (
Image *) NULL)
8557 *image=DestroyImage(*image);
8558 *image=vignette_image;
8560 CatchException(&(*image)->exception);
8561 XSetCursorState(display,windows,MagickFalse);
8562 if (windows->image.orphan != MagickFalse)
8564 XConfigureImageColormap(display,resource_info,windows,*image);
8565 (void) XConfigureImage(display,resource_info,windows,*image);
8574 geometry[MaxTextExtent] =
"25x150";
8579 (void) XDialogWidget(display,windows,
"Wave",
8580 "Enter the amplitude and length of the wave:",geometry);
8581 if (*geometry ==
'\0')
8586 XSetCursorState(display,windows,MagickTrue);
8587 XCheckRefreshWindows(display,windows);
8588 flags=ParseGeometry(geometry,&geometry_info);
8589 if ((flags & SigmaValue) == 0)
8590 geometry_info.sigma=1.0;
8591 wave_image=WaveImage(*image,geometry_info.rho,geometry_info.sigma,
8592 &(*image)->exception);
8593 if (wave_image != (
Image *) NULL)
8595 *image=DestroyImage(*image);
8598 CatchException(&(*image)->exception);
8599 XSetCursorState(display,windows,MagickFalse);
8600 if (windows->image.orphan != MagickFalse)
8602 XConfigureImageColormap(display,resource_info,windows,*image);
8603 (void) XConfigureImage(display,resource_info,windows,*image);
8606 case OilPaintCommand:
8612 radius[MaxTextExtent] =
"0";
8617 (void) XDialogWidget(display,windows,
"Oil Paint",
8618 "Enter the mask radius:",radius);
8619 if (*radius ==
'\0')
8624 XSetCursorState(display,windows,MagickTrue);
8625 XCheckRefreshWindows(display,windows);
8626 flags=ParseGeometry(radius,&geometry_info);
8627 paint_image=OilPaintImage(*image,geometry_info.rho,&(*image)->exception);
8628 if (paint_image != (
Image *) NULL)
8630 *image=DestroyImage(*image);
8633 CatchException(&(*image)->exception);
8634 XSetCursorState(display,windows,MagickFalse);
8635 if (windows->image.orphan != MagickFalse)
8637 XConfigureImageColormap(display,resource_info,windows,*image);
8638 (void) XConfigureImage(display,resource_info,windows,*image);
8641 case CharcoalDrawCommand:
8647 radius[MaxTextExtent] =
"0x1";
8652 (void) XDialogWidget(display,windows,
"Charcoal Draw",
8653 "Enter the charcoal radius and sigma:",radius);
8654 if (*radius ==
'\0')
8659 (void) XMagickCommand(display,resource_info,windows,ApplyCommand,image);
8660 XSetCursorState(display,windows,MagickTrue);
8661 XCheckRefreshWindows(display,windows);
8662 flags=ParseGeometry(radius,&geometry_info);
8663 if ((flags & SigmaValue) == 0)
8664 geometry_info.sigma=geometry_info.rho;
8665 charcoal_image=CharcoalImage(*image,geometry_info.rho,geometry_info.sigma,
8666 &(*image)->exception);
8667 if (charcoal_image != (
Image *) NULL)
8669 *image=DestroyImage(*image);
8670 *image=charcoal_image;
8672 CatchException(&(*image)->exception);
8673 XSetCursorState(display,windows,MagickFalse);
8674 if (windows->image.orphan != MagickFalse)
8676 XConfigureImageColormap(display,resource_info,windows,*image);
8677 (void) XConfigureImage(display,resource_info,windows,*image);
8680 case AnnotateCommand:
8685 status=XAnnotateEditImage(display,resource_info,windows,*image);
8686 if (status == MagickFalse)
8688 XNoticeWidget(display,windows,
"Unable to annotate X image",
8689 (*image)->filename);
8699 status=XDrawEditImage(display,resource_info,windows,image);
8700 if (status == MagickFalse)
8702 XNoticeWidget(display,windows,
"Unable to draw on the X image",
8703 (*image)->filename);
8713 status=XColorEditImage(display,resource_info,windows,image);
8714 if (status == MagickFalse)
8716 XNoticeWidget(display,windows,
"Unable to pixel edit X image",
8717 (*image)->filename);
8727 status=XMatteEditImage(display,resource_info,windows,image);
8728 if (status == MagickFalse)
8730 XNoticeWidget(display,windows,
"Unable to matte edit X image",
8731 (*image)->filename);
8736 case CompositeCommand:
8741 status=XCompositeImage(display,resource_info,windows,*image);
8742 if (status == MagickFalse)
8744 XNoticeWidget(display,windows,
"Unable to composite X image",
8745 (*image)->filename);
8750 case AddBorderCommand:
8756 geometry[MaxTextExtent] =
"6x6";
8761 XColorBrowserWidget(display,windows,
"Select",color);
8764 (void) XDialogWidget(display,windows,
"Add Border",
8765 "Enter border geometry:",geometry);
8766 if (*geometry ==
'\0')
8771 (void) XMagickCommand(display,resource_info,windows,ApplyCommand,image);
8772 XSetCursorState(display,windows,MagickTrue);
8773 XCheckRefreshWindows(display,windows);
8774 (void) QueryColorDatabase(color,&(*image)->border_color,
8775 &(*image)->exception);
8776 (void) ParsePageGeometry(*image,geometry,&page_geometry,
8777 &(*image)->exception);
8778 border_image=BorderImage(*image,&page_geometry,&(*image)->exception);
8779 if (border_image != (
Image *) NULL)
8781 *image=DestroyImage(*image);
8782 *image=border_image;
8784 CatchException(&(*image)->exception);
8785 XSetCursorState(display,windows,MagickFalse);
8786 if (windows->image.orphan != MagickFalse)
8788 windows->image.window_changes.width=(int) (*image)->columns;
8789 windows->image.window_changes.height=(
int) (*image)->rows;
8790 XConfigureImageColormap(display,resource_info,windows,*image);
8791 (void) XConfigureImage(display,resource_info,windows,*image);
8794 case AddFrameCommand:
8803 geometry[MaxTextExtent] =
"6x6";
8808 XColorBrowserWidget(display,windows,
"Select",color);
8811 (void) XDialogWidget(display,windows,
"Add Frame",
"Enter frame geometry:",
8813 if (*geometry ==
'\0')
8818 (void) XMagickCommand(display,resource_info,windows,ApplyCommand,image);
8819 XSetCursorState(display,windows,MagickTrue);
8820 XCheckRefreshWindows(display,windows);
8821 (void) QueryColorDatabase(color,&(*image)->matte_color,
8822 &(*image)->exception);
8823 (void) ParsePageGeometry(*image,geometry,&page_geometry,
8824 &(*image)->exception);
8825 frame_info.width=page_geometry.width;
8826 frame_info.height=page_geometry.height;
8827 frame_info.outer_bevel=page_geometry.x;
8828 frame_info.inner_bevel=page_geometry.y;
8829 frame_info.x=(ssize_t) frame_info.width;
8830 frame_info.y=(ssize_t) frame_info.height;
8831 frame_info.width=(*image)->columns+2*frame_info.width;
8832 frame_info.height=(*image)->rows+2*frame_info.height;
8833 frame_image=FrameImage(*image,&frame_info,&(*image)->exception);
8834 if (frame_image != (
Image *) NULL)
8836 *image=DestroyImage(*image);
8839 CatchException(&(*image)->exception);
8840 XSetCursorState(display,windows,MagickFalse);
8841 if (windows->image.orphan != MagickFalse)
8843 windows->image.window_changes.width=(int) (*image)->columns;
8844 windows->image.window_changes.height=(
int) (*image)->rows;
8845 XConfigureImageColormap(display,resource_info,windows,*image);
8846 (void) XConfigureImage(display,resource_info,windows,*image);
8849 case CommentCommand:
8863 unique_file=AcquireUniqueFileResource(image_info->filename);
8864 if (unique_file == -1)
8866 XNoticeWidget(display,windows,
"Unable to edit image comment",
8867 image_info->filename);
8870 value=GetImageProperty(*image,
"comment");
8871 if (value == (
char *) NULL)
8872 unique_file=close(unique_file)-1;
8878 file=fdopen(unique_file,
"w");
8879 if (file == (FILE *) NULL)
8881 XNoticeWidget(display,windows,
"Unable to edit image comment",
8882 image_info->filename);
8885 for (p=value; *p !=
'\0'; p++)
8886 (
void) fputc((
int) *p,file);
8887 (void) fputc(
'\n',file);
8888 (void) fclose(file);
8890 XSetCursorState(display,windows,MagickTrue);
8891 XCheckRefreshWindows(display,windows);
8892 status=InvokeDelegate(image_info,*image,
"edit",(
char *) NULL,
8893 &(*image)->exception);
8894 if (status == MagickFalse)
8895 XNoticeWidget(display,windows,
"Unable to edit image comment",
8902 comment=FileToString(image_info->filename,~0UL,&(*image)->exception);
8903 if (comment != (
char *) NULL)
8905 (void) SetImageProperty(*image,
"comment",comment);
8906 (*image)->taint=MagickTrue;
8909 (void) RelinquishUniqueFileResource(image_info->filename);
8910 XSetCursorState(display,windows,MagickFalse);
8918 XSetCursorState(display,windows,MagickTrue);
8919 XCheckRefreshWindows(display,windows);
8920 (void) AcquireUniqueFilename(filename);
8921 (void) FormatLocaleString((*image)->filename,MaxTextExtent,
"launch:%s",
8923 status=WriteImage(image_info,*image);
8924 if (status == MagickFalse)
8925 XNoticeWidget(display,windows,
"Unable to launch image editor",
8929 nexus=ReadImage(resource_info->image_info,&(*image)->exception);
8930 CatchException(&(*image)->exception);
8931 XClientMessage(display,windows->image.id,windows->im_protocols,
8932 windows->im_next_image,CurrentTime);
8934 (void) RelinquishUniqueFileResource(filename);
8935 XSetCursorState(display,windows,MagickFalse);
8938 case RegionOfInterestCommand:
8943 (void) XROIImage(display,resource_info,windows,image);
8953 if (windows->magnify.mapped != MagickFalse)
8954 (void) XRaiseWindow(display,windows->magnify.id);
8960 XSetCursorState(display,windows,MagickTrue);
8961 (void) XMapRaised(display,windows->magnify.id);
8962 XSetCursorState(display,windows,MagickFalse);
8966 case ShowPreviewCommand:
8975 preview_type[MaxTextExtent] =
"Gamma";
8980 previews=GetCommandOptions(MagickPreviewOptions);
8981 if (previews == (
char **) NULL)
8983 XListBrowserWidget(display,windows,&windows->widget,
8984 (
const char **) previews,
"Preview",
8985 "Select an enhancement, effect, or F/X:",preview_type);
8986 previews=DestroyStringList(previews);
8987 if (*preview_type ==
'\0')
8992 XSetCursorState(display,windows,MagickTrue);
8993 XCheckRefreshWindows(display,windows);
8994 image_info->preview_type=(PreviewType)
8995 ParseCommandOption(MagickPreviewOptions,MagickFalse,preview_type);
8996 image_info->group=(ssize_t) windows->image.id;
8997 (
void) DeleteImageProperty(*image,
"label");
8998 (void) SetImageProperty(*image,
"label",
"Preview");
8999 (void) AcquireUniqueFilename(filename);
9000 (void) FormatLocaleString((*image)->filename,MaxTextExtent,
"preview:%s",
9002 status=WriteImage(image_info,*image);
9003 (void) CopyMagickString(image_info->filename,filename,MaxTextExtent);
9004 preview_image=ReadImage(image_info,&(*image)->exception);
9005 (void) RelinquishUniqueFileResource(filename);
9006 if (preview_image == (
Image *) NULL)
9008 (void) FormatLocaleString(preview_image->filename,MaxTextExtent,
"show:%s",
9010 status=WriteImage(image_info,preview_image);
9011 preview_image=DestroyImage(preview_image);
9012 if (status == MagickFalse)
9013 XNoticeWidget(display,windows,
"Unable to show image preview",
9014 (*image)->filename);
9015 XDelay(display,1500);
9016 XSetCursorState(display,windows,MagickFalse);
9019 case ShowHistogramCommand:
9027 XSetCursorState(display,windows,MagickTrue);
9028 XCheckRefreshWindows(display,windows);
9029 image_info->group=(ssize_t) windows->image.id;
9030 (
void) DeleteImageProperty(*image,
"label");
9031 (void) SetImageProperty(*image,
"label",
"Histogram");
9032 (void) AcquireUniqueFilename(filename);
9033 (void) FormatLocaleString((*image)->filename,MaxTextExtent,
"histogram:%s",
9035 status=WriteImage(image_info,*image);
9036 (void) CopyMagickString(image_info->filename,filename,MaxTextExtent);
9037 histogram_image=ReadImage(image_info,&(*image)->exception);
9038 (void) RelinquishUniqueFileResource(filename);
9039 if (histogram_image == (
Image *) NULL)
9041 (void) FormatLocaleString(histogram_image->filename,MaxTextExtent,
9042 "show:%s",filename);
9043 status=WriteImage(image_info,histogram_image);
9044 histogram_image=DestroyImage(histogram_image);
9045 if (status == MagickFalse)
9046 XNoticeWidget(display,windows,
"Unable to show histogram",
9047 (*image)->filename);
9048 XDelay(display,1500);
9049 XSetCursorState(display,windows,MagickFalse);
9052 case ShowMatteCommand:
9057 if ((*image)->matte == MagickFalse)
9059 XNoticeWidget(display,windows,
9060 "Image does not have any matte information",(*image)->filename);
9066 XSetCursorState(display,windows,MagickTrue);
9067 XCheckRefreshWindows(display,windows);
9068 image_info->group=(ssize_t) windows->image.id;
9069 (
void) DeleteImageProperty(*image,
"label");
9070 (void) SetImageProperty(*image,
"label",
"Matte");
9071 (void) AcquireUniqueFilename(filename);
9072 (void) FormatLocaleString((*image)->filename,MaxTextExtent,
"matte:%s",
9074 status=WriteImage(image_info,*image);
9075 (void) CopyMagickString(image_info->filename,filename,MaxTextExtent);
9076 matte_image=ReadImage(image_info,&(*image)->exception);
9077 (void) RelinquishUniqueFileResource(filename);
9078 if (matte_image == (
Image *) NULL)
9080 (void) FormatLocaleString(matte_image->filename,MaxTextExtent,
"show:%s",
9082 status=WriteImage(image_info,matte_image);
9083 matte_image=DestroyImage(matte_image);
9084 if (status == MagickFalse)
9085 XNoticeWidget(display,windows,
"Unable to show matte",
9086 (*image)->filename);
9087 XDelay(display,1500);
9088 XSetCursorState(display,windows,MagickFalse);
9091 case BackgroundCommand:
9096 status=XBackgroundImage(display,resource_info,windows,image);
9097 if (status == MagickFalse)
9099 nexus=CloneImage(*image,0,0,MagickTrue,&(*image)->exception);
9100 if (nexus != (
Image *) NULL)
9101 XClientMessage(display,windows->image.id,windows->im_protocols,
9102 windows->im_next_image,CurrentTime);
9105 case SlideShowCommand:
9108 delay[MaxTextExtent] =
"5";
9113 (void) XDialogWidget(display,windows,
"Slide Show",
9114 "Pause how many 1/100ths of a second between images:",delay);
9117 resource_info->delay=StringToUnsignedLong(delay);
9118 XClientMessage(display,windows->image.id,windows->im_protocols,
9119 windows->im_next_image,CurrentTime);
9122 case PreferencesCommand:
9127 status=XPreferencesWidget(display,resource_info,windows);
9128 if (status == MagickFalse)
9130 nexus=CloneImage(*image,0,0,MagickTrue,&(*image)->exception);
9131 if (nexus != (
Image *) NULL)
9132 XClientMessage(display,windows->image.id,windows->im_protocols,
9133 windows->im_next_image,CurrentTime);
9141 XTextViewHelp(display,resource_info,windows,MagickFalse,
9142 "Help Viewer - Display",DisplayHelp);
9145 case BrowseDocumentationCommand:
9157 root_window=XRootWindow(display,XDefaultScreen(display));
9158 mozilla_atom=XInternAtom(display,
"_MOZILLA_VERSION",MagickFalse);
9159 mozilla_window=XWindowByProperty(display,root_window,mozilla_atom);
9160 if (mozilla_window != (Window) NULL)
9163 command[MaxTextExtent];
9168 (void) FormatLocaleString(command,MaxTextExtent,
9169 "openurl(%s,new-tab)",MagickAuthoritativeURL);
9170 mozilla_atom=XInternAtom(display,
"_MOZILLA_COMMAND",MagickFalse);
9171 (void) XChangeProperty(display,mozilla_window,mozilla_atom,XA_STRING,
9172 8,PropModeReplace,(
unsigned char *) command,(int) strlen(command));
9173 XSetCursorState(display,windows,MagickFalse);
9176 XSetCursorState(display,windows,MagickTrue);
9177 XCheckRefreshWindows(display,windows);
9178 status=InvokeDelegate(image_info,*image,
"browse",(
char *) NULL,
9179 &(*image)->exception);
9180 if (status == MagickFalse)
9181 XNoticeWidget(display,windows,
"Unable to browse documentation",
9183 XDelay(display,1500);
9184 XSetCursorState(display,windows,MagickFalse);
9187 case VersionCommand:
9189 XNoticeWidget(display,windows,GetMagickVersion((
size_t *) NULL),
9190 GetMagickCopyright());
9193 case SaveToUndoBufferCommand:
9197 (void) XBell(display,0);
9201 image_info=DestroyImageInfo(image_info);
9234 static void XMagnifyImage(Display *display,XWindows *windows,XEvent *event)
9237 text[MaxTextExtent];
9249 (void) XCheckDefineCursor(display,windows->image.id,windows->magnify.cursor);
9253 windows->magnify.x=(int) windows->image.x+x;
9254 windows->magnify.y=(
int) windows->image.y+y;
9260 if (windows->info.mapped != MagickFalse)
9262 if ((x < (
int) (windows->info.x+windows->info.width)) &&
9263 (y < (int) (windows->info.y+windows->info.height)))
9264 (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
9267 if ((x > (
int) (windows->info.x+windows->info.width)) ||
9268 (y > (int) (windows->info.y+windows->info.height)))
9269 (void) XMapWindow(display,windows->info.id);
9270 if (windows->info.mapped != MagickFalse)
9275 (void) FormatLocaleString(text,MaxTextExtent,
" %+d%+d ",
9276 windows->magnify.x,windows->magnify.y);
9277 XInfoWidget(display,windows,text);
9282 XScreenEvent(display,windows,event);
9283 switch (event->type)
9314 if (x >= (
int) windows->image.width)
9315 x=(int) windows->image.width-1;
9319 if (y >= (
int) windows->image.height)
9320 y=(
int) windows->image.height-1;
9321 }
while ((state & ExitState) == 0);
9325 XSetCursorState(display,windows,MagickFalse);
9360 static void XMagnifyWindowCommand(Display *display,XWindows *windows,
9361 const MagickStatusType state,
const KeySym key_symbol)
9370 if ((state & Mod1Mask) != 0)
9372 switch ((
int) key_symbol)
9376 (void) XWithdrawWindow(display,windows->magnify.id,
9377 windows->magnify.screen);
9383 windows->magnify.x=(int) windows->image.width/2;
9384 windows->magnify.y=(
int) windows->image.height/2;
9390 if (windows->magnify.x > 0)
9391 windows->magnify.x-=quantum;
9397 if (windows->magnify.y > 0)
9398 windows->magnify.y-=quantum;
9404 if (windows->magnify.x < (
int) (windows->image.ximage->width-1))
9405 windows->magnify.x+=quantum;
9411 if (windows->magnify.y < (
int) (windows->image.ximage->height-1))
9412 windows->magnify.y+=quantum;
9426 windows->magnify.data=(key_symbol-XK_0);
9440 windows->magnify.data=(key_symbol-XK_KP_0);
9446 XMakeMagnifyImage(display,windows);
9480 static void XMakePanImage(Display *display,XResourceInfo *resource_info,
9481 XWindows *windows,
Image *image)
9489 XSetCursorState(display,windows,MagickTrue);
9490 XCheckRefreshWindows(display,windows);
9491 windows->pan.x=(int) windows->image.x;
9492 windows->pan.y=(
int) windows->image.y;
9493 status=XMakeImage(display,resource_info,&windows->pan,image,
9494 windows->pan.width,windows->pan.height);
9495 if (status == MagickFalse)
9496 ThrowXWindowFatalException(XServerFatalError,image->exception.reason,
9497 image->exception.description);
9498 (void) XSetWindowBackgroundPixmap(display,windows->pan.id,
9499 windows->pan.pixmap);
9500 (void) XClearWindow(display,windows->pan.id);
9501 XDrawPanRectangle(display,windows);
9502 XSetCursorState(display,windows,MagickFalse);
9537 static MagickBooleanType XMatteEditImage(Display *display,
9538 XResourceInfo *resource_info,XWindows *windows,
Image **image)
9541 *
const MatteEditMenu[] =
9554 matte[MaxTextExtent] =
"0";
9556 static const ModeType
9557 MatteEditCommands[] =
9560 MatteEditBorderCommand,
9561 MatteEditFuzzCommand,
9562 MatteEditValueCommand,
9563 MatteEditUndoCommand,
9564 MatteEditHelpCommand,
9565 MatteEditDismissCommand
9569 method = PointMethod;
9572 border_color = { 0, 0, 0, 0, 0, 0 };
9575 command[MaxTextExtent],
9576 text[MaxTextExtent] =
"";
9608 (void) CloneString(&windows->command.name,
"Matte Edit");
9609 windows->command.data=4;
9610 (void) XCommandWidget(display,windows,MatteEditMenu,(XEvent *) NULL);
9611 (void) XMapRaised(display,windows->command.id);
9612 XClientMessage(display,windows->image.id,windows->im_protocols,
9613 windows->im_update_widget,CurrentTime);
9617 cursor=XMakeCursor(display,windows->image.id,windows->map_info->colormap,
9618 resource_info->background_color,resource_info->foreground_color);
9619 (void) XCheckDefineCursor(display,windows->image.id,cursor);
9623 XQueryPosition(display,windows->image.id,&x,&y);
9624 (void) XSelectInput(display,windows->image.id,
9625 windows->image.attributes.event_mask | PointerMotionMask);
9629 if (windows->info.mapped != MagickFalse)
9634 (void) FormatLocaleString(text,MaxTextExtent,
" %+d%+d ",
9635 x+windows->image.x,y+windows->image.y);
9636 XInfoWidget(display,windows,text);
9641 XScreenEvent(display,windows,&event);
9642 if (event.xany.window == windows->command.id)
9647 id=XCommandWidget(display,windows,MatteEditMenu,&event);
9650 (void) XCheckDefineCursor(display,windows->image.id,cursor);
9653 switch (MatteEditCommands[
id])
9655 case MatteEditMethod:
9663 methods=GetCommandOptions(MagickMethodOptions);
9664 if (methods == (
char **) NULL)
9666 entry=XMenuWidget(display,windows,MatteEditMenu[
id],
9667 (
const char **) methods,command);
9669 method=(PaintMethod) ParseCommandOption(MagickMethodOptions,
9670 MagickFalse,methods[entry]);
9671 methods=DestroyStringList(methods);
9674 case MatteEditBorderCommand:
9677 *ColorMenu[MaxNumberPens];
9685 for (i=0; i < (int) (MaxNumberPens-2); i++)
9686 ColorMenu[i]=resource_info->pen_colors[i];
9687 ColorMenu[MaxNumberPens-2]=
"Browser...";
9688 ColorMenu[MaxNumberPens-1]=(
const char *) NULL;
9692 pen_number=XMenuWidget(display,windows,MatteEditMenu[
id],
9693 (
const char **) ColorMenu,command);
9696 if (pen_number == (MaxNumberPens-2))
9699 color_name[MaxTextExtent] =
"gray";
9704 resource_info->pen_colors[pen_number]=color_name;
9705 XColorBrowserWidget(display,windows,
"Select",color_name);
9706 if (*color_name ==
'\0')
9712 (void) XParseColor(display,windows->map_info->colormap,
9713 resource_info->pen_colors[pen_number],&border_color);
9716 case MatteEditFuzzCommand:
9731 fuzz[MaxTextExtent];
9736 entry=XMenuWidget(display,windows,MatteEditMenu[
id],FuzzMenu,
9742 (*image)->fuzz=StringToDoubleInterval(FuzzMenu[entry],(
double)
9746 (void) CopyMagickString(fuzz,
"20%",MaxTextExtent);
9747 (void) XDialogWidget(display,windows,
"Ok",
9748 "Enter fuzz factor (0.0 - 99.9%):",fuzz);
9751 (void) ConcatenateMagickString(fuzz,
"%",MaxTextExtent);
9752 (*image)->fuzz=StringToDoubleInterval(fuzz,(
double) QuantumRange+
9756 case MatteEditValueCommand:
9759 *
const MatteMenu[] =
9768 message[MaxTextExtent];
9773 entry=XMenuWidget(display,windows,MatteEditMenu[
id],MatteMenu,
9779 (void) FormatLocaleString(matte,MaxTextExtent,QuantumFormat,
9781 if (LocaleCompare(MatteMenu[entry],
"Transparent") == 0)
9782 (
void) FormatLocaleString(matte,MaxTextExtent,QuantumFormat,
9783 (Quantum) TransparentOpacity);
9786 (void) FormatLocaleString(message,MaxTextExtent,
9787 "Enter matte value (0 - " QuantumFormat
"):",(Quantum)
9789 (void) XDialogWidget(display,windows,
"Matte",message,matte);
9794 case MatteEditUndoCommand:
9796 (void) XMagickCommand(display,resource_info,windows,UndoCommand,
9800 case MatteEditHelpCommand:
9802 XTextViewHelp(display,resource_info,windows,MagickFalse,
9803 "Help Viewer - Matte Edit",ImageMatteEditHelp);
9806 case MatteEditDismissCommand:
9818 (void) XCheckDefineCursor(display,windows->image.id,cursor);
9825 if (event.xbutton.button != Button1)
9827 if ((event.xbutton.window != windows->image.id) &&
9828 (
event.xbutton.window != windows->magnify.id))
9835 (void) XMagickCommand(display,resource_info,windows,
9836 SaveToUndoBufferCommand,image);
9837 state|=UpdateConfigurationState;
9842 if (event.xbutton.button != Button1)
9844 if ((event.xbutton.window != windows->image.id) &&
9845 (
event.xbutton.window != windows->magnify.id))
9852 XConfigureImageColormap(display,resource_info,windows,*image);
9853 (void) XConfigureImage(display,resource_info,windows,*image);
9854 XInfoWidget(display,windows,text);
9855 (void) XCheckDefineCursor(display,windows->image.id,cursor);
9856 state&=(~UpdateConfigurationState);
9864 command[MaxTextExtent];
9869 if (event.xkey.window == windows->magnify.id)
9874 window=windows->magnify.id;
9875 while (XCheckWindowEvent(display,window,KeyPressMask,&event)) ;
9877 if (event.xkey.window != windows->image.id)
9882 (void) XLookupString((XKeyEvent *) &
event.xkey,command,(int)
9883 sizeof(command),&key_symbol,(XComposeStatus *) NULL);
9884 switch ((
int) key_symbol)
9898 XTextViewHelp(display,resource_info,windows,MagickFalse,
9899 "Help Viewer - Matte Edit",ImageMatteEditHelp);
9904 (void) XBell(display,0);
9917 if (windows->info.mapped != MagickFalse)
9919 if ((x < (
int) (windows->info.x+windows->info.width)) &&
9920 (y < (int) (windows->info.y+windows->info.height)))
9921 (void) XWithdrawWindow(display,windows->info.id,
9922 windows->info.screen);
9925 if ((x > (
int) (windows->info.x+windows->info.width)) ||
9926 (y > (int) (windows->info.y+windows->info.height)))
9927 (void) XMapWindow(display,windows->info.id);
9933 if (event.xany.window == windows->magnify.id)
9935 x=windows->magnify.x-windows->image.x;
9936 y=windows->magnify.y-windows->image.y;
9940 if ((state & UpdateConfigurationState) != 0)
9955 (void) XClearArea(display,windows->image.id,x_offset,y_offset,1,1,
9957 XPutPixel(windows->image.ximage,x_offset,y_offset,
9958 windows->pixel_info->background_color.pixel);
9959 width=(
unsigned int) (*image)->columns;
9960 height=(
unsigned int) (*image)->rows;
9963 if (windows->image.crop_geometry != (
char *) NULL)
9964 (
void) XParseGeometry(windows->image.crop_geometry,&x,&y,
9967 (width*(windows->image.x+x_offset)/windows->image.ximage->width+x);
9969 (height*(windows->image.y+y_offset)/windows->image.ximage->height+y);
9970 if ((x_offset < 0) || (y_offset < 0))
9972 if ((x_offset >= (
int) (*image)->columns) ||
9973 (y_offset >= (
int) (*image)->rows))
9975 if (SetImageStorageClass(*image,DirectClass) == MagickFalse)
9976 return(MagickFalse);
9977 (*image)->matte=MagickTrue;
9978 exception=(&(*image)->exception);
9979 image_view=AcquireAuthenticCacheView(*image,exception);
9988 q=GetCacheViewAuthenticPixels(image_view,(ssize_t) x_offset,
9989 (ssize_t) y_offset,1,1,exception);
9992 q->opacity=(Quantum) StringToLong(matte);
9993 (void) SyncCacheViewAuthenticPixels(image_view,exception);
10004 (void) GetOneCacheViewVirtualPixel(image_view,(ssize_t) x_offset,
10005 (ssize_t) y_offset,&target,exception);
10006 for (y=0; y < (int) (*image)->rows; y++)
10008 q=GetCacheViewAuthenticPixels(image_view,0,(ssize_t) y,
10009 (*image)->columns,1,&(*image)->exception);
10012 for (x=0; x < (int) (*image)->columns; x++)
10014 if (IsColorSimilar(*image,q,&target))
10015 q->opacity=(Quantum) StringToLong(matte);
10018 if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
10023 case FloodfillMethod:
10024 case FillToBorderMethod:
10035 (void) GetOneVirtualMagickPixel(*image,(ssize_t) x_offset,
10036 (ssize_t) y_offset,&target,exception);
10037 if (method == FillToBorderMethod)
10039 target.red=(MagickRealType)
10040 ScaleShortToQuantum(border_color.red);
10041 target.green=(MagickRealType)
10042 ScaleShortToQuantum(border_color.green);
10043 target.blue=(MagickRealType)
10044 ScaleShortToQuantum(border_color.blue);
10046 draw_info=CloneDrawInfo(resource_info->image_info,
10048 draw_info->fill.opacity=ClampToQuantum(StringToDouble(matte,
10050 (void) FloodfillPaintImage(*image,OpacityChannel,draw_info,&target,
10051 (ssize_t) x_offset,(ssize_t) y_offset,
10052 method == FloodfillMethod ? MagickFalse : MagickTrue);
10053 draw_info=DestroyDrawInfo(draw_info);
10061 if (SetImageStorageClass(*image,DirectClass) == MagickFalse)
10062 return(MagickFalse);
10063 for (y=0; y < (int) (*image)->rows; y++)
10065 q=QueueCacheViewAuthenticPixels(image_view,0,(ssize_t) y,
10066 (*image)->columns,1,exception);
10069 for (x=0; x < (int) (*image)->columns; x++)
10071 q->opacity=(Quantum) StringToLong(matte);
10074 if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
10077 if (StringToLong(matte) == OpaqueOpacity)
10078 (*image)->matte=MagickFalse;
10082 image_view=DestroyCacheView(image_view);
10083 state&=(~UpdateConfigurationState);
10085 }
while ((state & ExitState) == 0);
10086 (void) XSelectInput(display,windows->image.id,
10087 windows->image.attributes.event_mask);
10088 XSetCursorState(display,windows,MagickFalse);
10089 (void) XFreeCursor(display,cursor);
10090 return(MagickTrue);
10124 static Image *XOpenImage(Display *display,XResourceInfo *resource_info,
10125 XWindows *windows,
const MagickBooleanType command)
10140 filename[MaxTextExtent] =
"\0";
10145 if (command == MagickFalse)
10146 XFileBrowserWidget(display,windows,
"Open",filename);
10164 status=XGetCommand(display,windows->image.id,&files,&count);
10166 ThrowXWindowException(XServerError,
"UnableToGetProperty",
"...");
10167 filelist=(
char **) AcquireQuantumMemory((
size_t) count,
sizeof(*filelist));
10168 if (filelist == (
char **) NULL)
10170 (void) XFreeStringList(files);
10171 ThrowXWindowException(ResourceLimitError,
10172 "MemoryAllocationFailed",
"...");
10173 return((
Image *) NULL);
10176 for (i=1; i < count; i++)
10177 if (*files[i] !=
'-')
10178 filelist[j++]=files[i];
10179 filelist[j]=(
char *) NULL;
10180 XListBrowserWidget(display,windows,&windows->widget,
10181 (
const char **) filelist,
"Load",
"Select Image to Load:",filename);
10182 filelist=(
char **) RelinquishMagickMemory(filelist);
10183 (void) XFreeStringList(files);
10185 if (*filename ==
'\0')
10186 return((
Image *) NULL);
10187 image_info=CloneImageInfo(resource_info->image_info);
10188 (void) SetImageInfoProgressMonitor(image_info,(MagickProgressMonitor) NULL,
10190 (void) CopyMagickString(image_info->filename,filename,MaxTextExtent);
10191 exception=AcquireExceptionInfo();
10192 (void) SetImageInfo(image_info,0,exception);
10193 if (LocaleCompare(image_info->magick,
"X") == 0)
10196 seconds[MaxTextExtent];
10201 (void) CopyMagickString(seconds,
"0",MaxTextExtent);
10202 (void) XDialogWidget(display,windows,
"Grab",
"Enter any delay in seconds:",
10204 if (*seconds ==
'\0')
10205 return((
Image *) NULL);
10206 XDelay(display,(
size_t) (1000*StringToLong(seconds)));
10208 magick_info=GetMagickInfo(image_info->magick,exception);
10209 if ((magick_info != (
const MagickInfo *) NULL) &&
10210 (magick_info->raw != MagickFalse))
10213 geometry[MaxTextExtent];
10218 (void) CopyMagickString(geometry,
"512x512",MaxTextExtent);
10219 if (image_info->size != (
char *) NULL)
10220 (
void) CopyMagickString(geometry,image_info->size,MaxTextExtent);
10221 (void) XDialogWidget(display,windows,
"Load",
"Enter the image geometry:",
10223 (void) CloneString(&image_info->size,geometry);
10228 XSetCursorState(display,windows,MagickTrue);
10229 XCheckRefreshWindows(display,windows);
10230 (void) CopyMagickString(image_info->filename,filename,MaxTextExtent);
10231 nexus=ReadImage(image_info,exception);
10232 CatchException(exception);
10233 XSetCursorState(display,windows,MagickFalse);
10234 if (nexus != (
Image *) NULL)
10235 XClientMessage(display,windows->image.id,windows->im_protocols,
10236 windows->im_next_image,CurrentTime);
10246 text=FileToString(filename,~0UL,exception);
10247 if (text == (
char *) NULL)
10248 return((
Image *) NULL);
10249 textlist=StringToList(text);
10250 if (textlist != (
char **) NULL)
10253 title[MaxTextExtent];
10258 (void) FormatLocaleString(title,MaxTextExtent,
10259 "Unknown format: %s",filename);
10260 XTextViewWidget(display,resource_info,windows,MagickTrue,title,
10261 (
const char **) textlist);
10262 for (i=0; textlist[i] != (
char *) NULL; i++)
10263 textlist[i]=DestroyString(textlist[i]);
10264 textlist=(
char **) RelinquishMagickMemory(textlist);
10266 text=DestroyString(text);
10268 exception=DestroyExceptionInfo(exception);
10269 image_info=DestroyImageInfo(image_info);
10301 static void XPanImage(Display *display,XWindows *windows,XEvent *event)
10304 text[MaxTextExtent];
10322 if ((windows->image.ximage->width > (
int) windows->image.width) &&
10323 (windows->image.ximage->height > (
int) windows->image.height))
10324 cursor=XCreateFontCursor(display,XC_fleur);
10326 if (windows->image.ximage->width > (
int) windows->image.width)
10327 cursor=XCreateFontCursor(display,XC_sb_h_double_arrow);
10329 if (windows->image.ximage->height > (
int) windows->image.height)
10330 cursor=XCreateFontCursor(display,XC_sb_v_double_arrow);
10332 cursor=XCreateFontCursor(display,XC_arrow);
10333 (void) XCheckDefineCursor(display,windows->pan.id,cursor);
10337 x_factor=(MagickRealType) windows->image.ximage->width/windows->pan.width;
10338 y_factor=(MagickRealType) windows->image.ximage->height/windows->pan.height;
10339 pan_info.width=windows->pan.width*windows->image.width/
10340 windows->image.ximage->width;
10341 pan_info.height=windows->pan.height*windows->image.height/
10342 windows->image.ximage->height;
10345 state=UpdateConfigurationState;
10348 switch (event->type)
10355 pan_info.x=(ssize_t) event->xbutton.x;
10356 pan_info.y=(ssize_t)
event->xbutton.y;
10357 state|=UpdateConfigurationState;
10360 case ButtonRelease:
10365 pan_info.x=(ssize_t) event->xbutton.x;
10366 pan_info.y=(ssize_t)
event->xbutton.y;
10367 state|=UpdateConfigurationState | ExitState;
10372 pan_info.x=(ssize_t) event->xmotion.x;
10373 pan_info.y=(ssize_t)
event->xmotion.y;
10374 state|=UpdateConfigurationState;
10379 if ((state & UpdateConfigurationState) != 0)
10384 if (pan_info.x < (ssize_t) (pan_info.width/2))
10387 pan_info.x=(ssize_t) (x_factor*(pan_info.x-(pan_info.width/2)));
10388 if (pan_info.x < 0)
10391 if ((
int) (pan_info.x+windows->image.width) >
10392 windows->image.ximage->width)
10393 pan_info.x=(ssize_t)
10394 (windows->image.ximage->width-windows->image.width);
10395 if (pan_info.y < (ssize_t) (pan_info.height/2))
10398 pan_info.y=(ssize_t) (y_factor*(pan_info.y-(pan_info.height/2)));
10399 if (pan_info.y < 0)
10402 if ((
int) (pan_info.y+windows->image.height) >
10403 windows->image.ximage->height)
10404 pan_info.y=(ssize_t)
10405 (windows->image.ximage->height-windows->image.height);
10406 if ((windows->image.x != (
int) pan_info.x) ||
10407 (windows->image.y != (
int) pan_info.y))
10412 windows->image.x=(int) pan_info.x;
10413 windows->image.y=(
int) pan_info.y;
10414 (void) FormatLocaleString(text,MaxTextExtent,
" %ux%u%+d%+d ",
10415 windows->image.width,windows->image.height,windows->image.x,
10417 XInfoWidget(display,windows,text);
10421 XDrawPanRectangle(display,windows);
10422 XRefreshWindow(display,&windows->image,(XEvent *) NULL);
10424 state&=(~UpdateConfigurationState);
10429 if ((state & ExitState) == 0)
10430 XScreenEvent(display,windows,event);
10431 }
while ((state & ExitState) == 0);
10435 (void) XCheckDefineCursor(display,windows->pan.id,windows->pan.cursor);
10436 (void) XFreeCursor(display,cursor);
10437 (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
10471 static MagickBooleanType XPasteImage(Display *display,
10472 XResourceInfo *resource_info,XWindows *windows,
Image *image)
10475 *
const PasteMenu[] =
10483 static const ModeType
10486 PasteOperatorsCommand,
10488 PasteDismissCommand
10491 static CompositeOperator
10492 compose = CopyCompositeOp;
10495 text[MaxTextExtent];
10529 if (resource_info->copy_image == (
Image *) NULL)
10530 return(MagickFalse);
10531 paste_image=CloneImage(resource_info->copy_image,0,0,MagickTrue,
10532 &image->exception);
10533 if (paste_image == (
Image *) NULL)
10534 return(MagickFalse);
10538 (void) CloneString(&windows->command.name,
"Paste");
10539 windows->command.data=1;
10540 (void) XCommandWidget(display,windows,PasteMenu,(XEvent *) NULL);
10541 (void) XMapRaised(display,windows->command.id);
10542 XClientMessage(display,windows->image.id,windows->im_protocols,
10543 windows->im_update_widget,CurrentTime);
10547 XSetCursorState(display,windows,MagickFalse);
10548 XQueryPosition(display,windows->image.id,&x,&y);
10549 (void) XSelectInput(display,windows->image.id,
10550 windows->image.attributes.event_mask | PointerMotionMask);
10551 paste_info.x=(ssize_t) windows->image.x+x;
10552 paste_info.y=(ssize_t) windows->image.y+y;
10553 paste_info.width=0;
10554 paste_info.height=0;
10555 cursor=XCreateFontCursor(display,XC_ul_angle);
10556 (void) XSetFunction(display,windows->image.highlight_context,GXinvert);
10557 state=DefaultState;
10560 if (windows->info.mapped != MagickFalse)
10565 (void) FormatLocaleString(text,MaxTextExtent,
" %+ld%+ld ",
10566 (
long) paste_info.x,(long) paste_info.y);
10567 XInfoWidget(display,windows,text);
10569 highlight_info=paste_info;
10570 highlight_info.x=paste_info.x-windows->image.x;
10571 highlight_info.y=paste_info.y-windows->image.y;
10572 XHighlightRectangle(display,windows->image.id,
10573 windows->image.highlight_context,&highlight_info);
10577 XScreenEvent(display,windows,&event);
10578 XHighlightRectangle(display,windows->image.id,
10579 windows->image.highlight_context,&highlight_info);
10580 if (event.xany.window == windows->command.id)
10585 id=XCommandWidget(display,windows,PasteMenu,&event);
10588 switch (PasteCommands[
id])
10590 case PasteOperatorsCommand:
10593 command[MaxTextExtent],
10599 operators=GetCommandOptions(MagickComposeOptions);
10600 if (operators == (
char **) NULL)
10602 entry=XMenuWidget(display,windows,PasteMenu[
id],
10603 (
const char **) operators,command);
10605 compose=(CompositeOperator) ParseCommandOption(
10606 MagickComposeOptions,MagickFalse,operators[entry]);
10607 operators=DestroyStringList(operators);
10610 case PasteHelpCommand:
10612 XTextViewHelp(display,resource_info,windows,MagickFalse,
10613 "Help Viewer - Image Composite",ImagePasteHelp);
10616 case PasteDismissCommand:
10621 state|=EscapeState;
10630 switch (event.type)
10634 if (resource_info->debug != MagickFalse)
10635 (void) LogMagickEvent(X11Event,GetMagickModule(),
10636 "Button Press: 0x%lx %u +%d+%d",
event.xbutton.window,
10637 event.xbutton.button,
event.xbutton.x,
event.xbutton.y);
10638 if (event.xbutton.button != Button1)
10640 if (event.xbutton.window != windows->image.id)
10645 width=(
unsigned int) image->columns;
10646 height=(
unsigned int) image->rows;
10649 if (windows->image.crop_geometry != (
char *) NULL)
10650 (
void) XParseGeometry(windows->image.crop_geometry,&x,&y,
10652 scale_factor=(MagickRealType) windows->image.ximage->width/width;
10653 paste_info.width=(
unsigned int) (scale_factor*paste_image->columns+0.5);
10654 scale_factor=(MagickRealType) windows->image.ximage->height/height;
10655 paste_info.height=(
unsigned int) (scale_factor*paste_image->rows+0.5);
10656 (void) XCheckDefineCursor(display,windows->image.id,cursor);
10657 paste_info.x=(ssize_t) windows->image.x+event.xbutton.x;
10658 paste_info.y=(ssize_t) windows->image.y+
event.xbutton.y;
10661 case ButtonRelease:
10663 if (resource_info->debug != MagickFalse)
10664 (void) LogMagickEvent(X11Event,GetMagickModule(),
10665 "Button Release: 0x%lx %u +%d+%d",
event.xbutton.window,
10666 event.xbutton.button,
event.xbutton.x,
event.xbutton.y);
10667 if (event.xbutton.button != Button1)
10669 if (event.xbutton.window != windows->image.id)
10671 if ((paste_info.width != 0) && (paste_info.height != 0))
10676 paste_info.x=(ssize_t) windows->image.x+event.xbutton.x;
10677 paste_info.y=(ssize_t) windows->image.y+
event.xbutton.y;
10687 command[MaxTextExtent];
10695 if (event.xkey.window != windows->image.id)
10700 length=XLookupString((XKeyEvent *) &event.xkey,command,(
int)
10701 sizeof(command),&key_symbol,(XComposeStatus *) NULL);
10702 *(command+length)=
'\0';
10703 if (resource_info->debug != MagickFalse)
10704 (void) LogMagickEvent(X11Event,GetMagickModule(),
10705 "Key press: 0x%lx (%s)",(long) key_symbol,command);
10706 switch ((
int) key_symbol)
10714 paste_image=DestroyImage(paste_image);
10715 state|=EscapeState;
10722 (void) XSetFunction(display,windows->image.highlight_context,
10724 XTextViewHelp(display,resource_info,windows,MagickFalse,
10725 "Help Viewer - Image Composite",ImagePasteHelp);
10726 (void) XSetFunction(display,windows->image.highlight_context,
10732 (void) XBell(display,0);
10745 if (windows->info.mapped != MagickFalse)
10747 if ((x < (
int) (windows->info.x+windows->info.width)) &&
10748 (y < (int) (windows->info.y+windows->info.height)))
10749 (void) XWithdrawWindow(display,windows->info.id,
10750 windows->info.screen);
10753 if ((x > (
int) (windows->info.x+windows->info.width)) ||
10754 (y > (int) (windows->info.y+windows->info.height)))
10755 (void) XMapWindow(display,windows->info.id);
10756 paste_info.x=(ssize_t) windows->image.x+x;
10757 paste_info.y=(ssize_t) windows->image.y+y;
10762 if (resource_info->debug != MagickFalse)
10763 (void) LogMagickEvent(X11Event,GetMagickModule(),
"Event type: %d",
10768 }
while ((state & ExitState) == 0);
10769 (void) XSelectInput(display,windows->image.id,
10770 windows->image.attributes.event_mask);
10771 (void) XSetFunction(display,windows->image.highlight_context,GXcopy);
10772 XSetCursorState(display,windows,MagickFalse);
10773 (void) XFreeCursor(display,cursor);
10774 if ((state & EscapeState) != 0)
10775 return(MagickTrue);
10779 XSetCursorState(display,windows,MagickTrue);
10780 XCheckRefreshWindows(display,windows);
10781 width=(
unsigned int) image->columns;
10782 height=(
unsigned int) image->rows;
10785 if (windows->image.crop_geometry != (
char *) NULL)
10786 (
void) XParseGeometry(windows->image.crop_geometry,&x,&y,&width,&height);
10787 scale_factor=(MagickRealType) width/windows->image.ximage->width;
10789 paste_info.x=(ssize_t) (scale_factor*paste_info.x+0.5);
10790 paste_info.width=(
unsigned int) (scale_factor*paste_info.width+0.5);
10791 scale_factor=(MagickRealType) height/windows->image.ximage->height;
10793 paste_info.y=(ssize_t) (scale_factor*paste_info.y*scale_factor+0.5);
10794 paste_info.height=(
unsigned int) (scale_factor*paste_info.height+0.5);
10798 (void) CompositeImage(image,compose,paste_image,paste_info.x,paste_info.y);
10799 paste_image=DestroyImage(paste_image);
10800 XSetCursorState(display,windows,MagickFalse);
10804 XConfigureImageColormap(display,resource_info,windows,image);
10805 (void) XConfigureImage(display,resource_info,windows,image);
10806 return(MagickTrue);
10839 static MagickBooleanType XPrintImage(Display *display,
10840 XResourceInfo *resource_info,XWindows *windows,
Image *image)
10843 filename[MaxTextExtent],
10844 geometry[MaxTextExtent];
10847 *
const PageSizes[] =
10878 image_info=CloneImageInfo(resource_info->image_info);
10879 (void) FormatLocaleString(geometry,MaxTextExtent,
"Letter");
10880 if (image_info->page != (
char *) NULL)
10881 (
void) CopyMagickString(geometry,image_info->page,MaxTextExtent);
10882 XListBrowserWidget(display,windows,&windows->widget,PageSizes,
"Select",
10883 "Select Postscript Page Geometry:",geometry);
10884 if (*geometry ==
'\0')
10885 return(MagickTrue);
10886 image_info->page=GetPageGeometry(geometry);
10890 XSetCursorState(display,windows,MagickTrue);
10891 XCheckRefreshWindows(display,windows);
10892 print_image=CloneImage(image,0,0,MagickTrue,&image->exception);
10893 if (print_image == (
Image *) NULL)
10894 return(MagickFalse);
10895 (void) FormatLocaleString(geometry,MaxTextExtent,
"%dx%d!",
10896 windows->image.ximage->width,windows->image.ximage->height);
10897 (void) TransformImage(&print_image,windows->image.crop_geometry,geometry);
10901 (void) AcquireUniqueFilename(filename);
10902 (void) FormatLocaleString(print_image->filename,MaxTextExtent,
"print:%s",
10904 status=WriteImage(image_info,print_image);
10905 (void) RelinquishUniqueFileResource(filename);
10906 print_image=DestroyImage(print_image);
10907 image_info=DestroyImageInfo(image_info);
10908 XSetCursorState(display,windows,MagickFalse);
10909 return(status != 0 ? MagickTrue : MagickFalse);
10942 static MagickBooleanType XROIImage(Display *display,
10943 XResourceInfo *resource_info,XWindows *windows,
Image **image)
10945 #define ApplyMenus 7
10954 *
const ApplyMenu[] =
10967 *
const FileMenu[] =
10973 *
const EditMenu[] =
10979 *
const TransformMenu[] =
10987 *
const EnhanceMenu[] =
10995 "Contrast Stretch...",
10996 "Sigmoidal Contrast...",
11005 *
const EffectsMenu[] =
11030 "Charcoal Draw...",
11033 *
const MiscellanyMenu[] =
11044 *
const *Menus[ApplyMenus] =
11055 static const CommandType
11078 TransformCommands[] =
11082 RotateRightCommand,
11085 EnhanceCommands[] =
11093 ContrastStretchCommand,
11094 SigmoidalContrastCommand,
11102 EffectsCommands[] =
11106 ReduceNoiseCommand,
11125 CharcoalDrawCommand
11127 MiscellanyCommands[] =
11131 ShowPreviewCommand,
11132 ShowHistogramCommand,
11141 static const CommandType
11142 *Commands[ApplyMenus] =
11154 command[MaxTextExtent],
11155 text[MaxTextExtent];
11175 MagickProgressMonitor
11196 (void) CloneString(&windows->command.name,
"ROI");
11197 windows->command.data=0;
11198 (void) XCommandWidget(display,windows,ROIMenu,(XEvent *) NULL);
11199 (void) XMapRaised(display,windows->command.id);
11200 XClientMessage(display,windows->image.id,windows->im_protocols,
11201 windows->im_update_widget,CurrentTime);
11205 XQueryPosition(display,windows->image.id,&x,&y);
11206 (void) XSelectInput(display,windows->image.id,
11207 windows->image.attributes.event_mask | PointerMotionMask);
11209 crop_info.height=0;
11212 roi_info.x=(ssize_t) windows->image.x+x;
11213 roi_info.y=(ssize_t) windows->image.y+y;
11216 cursor=XCreateFontCursor(display,XC_fleur);
11217 state=DefaultState;
11220 if (windows->info.mapped != MagickFalse)
11225 (void) FormatLocaleString(text,MaxTextExtent,
" %+ld%+ld ",
11226 (
long) roi_info.x,(long) roi_info.y);
11227 XInfoWidget(display,windows,text);
11232 XScreenEvent(display,windows,&event);
11233 if (event.xany.window == windows->command.id)
11238 id=XCommandWidget(display,windows,ROIMenu,&event);
11241 switch (ROICommands[
id])
11243 case ROIHelpCommand:
11245 XTextViewHelp(display,resource_info,windows,MagickFalse,
11246 "Help Viewer - Region of Interest",ImageROIHelp);
11249 case ROIDismissCommand:
11254 state|=EscapeState;
11263 switch (event.type)
11267 if (event.xbutton.button != Button1)
11269 if (event.xbutton.window != windows->image.id)
11274 (void) XCheckDefineCursor(display,windows->image.id,cursor);
11275 roi_info.x=(ssize_t) windows->image.x+event.xbutton.x;
11276 roi_info.y=(ssize_t) windows->image.y+
event.xbutton.y;
11280 case ButtonRelease:
11289 if (event.xkey.window != windows->image.id)
11294 (void) XLookupString((XKeyEvent *) &
event.xkey,command,(int)
11295 sizeof(command),&key_symbol,(XComposeStatus *) NULL);
11296 switch ((
int) key_symbol)
11304 state|=EscapeState;
11311 XTextViewHelp(display,resource_info,windows,MagickFalse,
11312 "Help Viewer - Region of Interest",ImageROIHelp);
11317 (void) XBell(display,0);
11330 if (windows->info.mapped != MagickFalse)
11332 if ((x < (
int) (windows->info.x+windows->info.width)) &&
11333 (y < (int) (windows->info.y+windows->info.height)))
11334 (void) XWithdrawWindow(display,windows->info.id,
11335 windows->info.screen);
11338 if ((x > (
int) (windows->info.x+windows->info.width)) ||
11339 (y > (int) (windows->info.y+windows->info.height)))
11340 (void) XMapWindow(display,windows->info.id);
11341 roi_info.x=(ssize_t) windows->image.x+x;
11342 roi_info.y=(ssize_t) windows->image.y+y;
11348 }
while ((state & ExitState) == 0);
11349 (void) XSelectInput(display,windows->image.id,
11350 windows->image.attributes.event_mask);
11351 if ((state & EscapeState) != 0)
11356 (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
11357 (void) XFreeCursor(display,cursor);
11358 return(MagickTrue);
11360 (void) XSetFunction(display,windows->image.highlight_context,GXinvert);
11366 x=(int) roi_info.x;
11367 y=(
int) roi_info.y;
11370 state=DefaultState;
11373 highlight_info=roi_info;
11374 highlight_info.x=roi_info.x-windows->image.x;
11375 highlight_info.y=roi_info.y-windows->image.y;
11376 if ((highlight_info.width > 3) && (highlight_info.height > 3))
11381 if (windows->info.mapped == MagickFalse)
11382 (void) XMapWindow(display,windows->info.id);
11383 (void) FormatLocaleString(text,MaxTextExtent,
11384 " %.20gx%.20g%+.20g%+.20g",(
double) roi_info.width,(double)
11385 roi_info.height,(
double) roi_info.x,(double) roi_info.y);
11386 XInfoWidget(display,windows,text);
11387 XHighlightRectangle(display,windows->image.id,
11388 windows->image.highlight_context,&highlight_info);
11391 if (windows->info.mapped != MagickFalse)
11392 (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
11396 XScreenEvent(display,windows,&event);
11397 if ((highlight_info.width > 3) && (highlight_info.height > 3))
11398 XHighlightRectangle(display,windows->image.id,
11399 windows->image.highlight_context,&highlight_info);
11400 switch (event.type)
11404 roi_info.x=(ssize_t) windows->image.x+event.xbutton.x;
11405 roi_info.y=(ssize_t) windows->image.y+
event.xbutton.y;
11408 case ButtonRelease:
11413 roi_info.x=(ssize_t) windows->image.x+event.xbutton.x;
11414 roi_info.y=(ssize_t) windows->image.y+
event.xbutton.y;
11415 XSetCursorState(display,windows,MagickFalse);
11417 if (LocaleCompare(windows->command.name,
"Apply") == 0)
11419 (void) CloneString(&windows->command.name,
"Apply");
11420 windows->command.data=ApplyMenus;
11421 (void) XCommandWidget(display,windows,ApplyMenu,(XEvent *) NULL);
11428 roi_info.x=(ssize_t) windows->image.x+event.xmotion.x;
11429 roi_info.y=(ssize_t) windows->image.y+
event.xmotion.y;
11434 if ((((
int) roi_info.x != x) && ((
int) roi_info.y != y)) ||
11435 ((state & ExitState) != 0))
11440 if (roi_info.x < 0)
11443 if (roi_info.x > (ssize_t) windows->image.ximage->width)
11444 roi_info.x=(ssize_t) windows->image.ximage->width;
11445 if ((
int) roi_info.x < x)
11446 roi_info.width=(
unsigned int) (x-roi_info.x);
11449 roi_info.width=(
unsigned int) (roi_info.x-x);
11450 roi_info.x=(ssize_t) x;
11452 if (roi_info.y < 0)
11455 if (roi_info.y > (ssize_t) windows->image.ximage->height)
11456 roi_info.y=(ssize_t) windows->image.ximage->height;
11457 if ((
int) roi_info.y < y)
11458 roi_info.height=(
unsigned int) (y-roi_info.y);
11461 roi_info.height=(
unsigned int) (roi_info.y-y);
11462 roi_info.y=(ssize_t) y;
11465 }
while ((state & ExitState) == 0);
11469 state=DefaultState;
11470 command_type=NullCommand;
11471 (void) XMapWindow(display,windows->info.id);
11474 if (windows->info.mapped != MagickFalse)
11479 (void) FormatLocaleString(text,MaxTextExtent,
11480 " %.20gx%.20g%+.20g%+.20g",(
double) roi_info.width,(double)
11481 roi_info.height,(
double) roi_info.x,(double) roi_info.y);
11482 XInfoWidget(display,windows,text);
11484 highlight_info=roi_info;
11485 highlight_info.x=roi_info.x-windows->image.x;
11486 highlight_info.y=roi_info.y-windows->image.y;
11487 if ((highlight_info.width <= 3) || (highlight_info.height <= 3))
11489 state|=EscapeState;
11493 if ((state & UpdateRegionState) != 0)
11495 (void) XSetFunction(display,windows->image.highlight_context,GXcopy);
11496 switch (command_type)
11501 (void) XMagickCommand(display,resource_info,windows,command_type,
11510 progress_monitor=SetImageProgressMonitor(*image,
11511 (MagickProgressMonitor) NULL,(*image)->client_data);
11512 crop_info=roi_info;
11513 width=(
unsigned int) (*image)->columns;
11514 height=(
unsigned int) (*image)->rows;
11517 if (windows->image.crop_geometry != (
char *) NULL)
11518 (
void) XParseGeometry(windows->image.crop_geometry,&x,&y,
11520 scale_factor=(MagickRealType) width/windows->image.ximage->width;
11522 crop_info.x=(ssize_t) (scale_factor*crop_info.x+0.5);
11523 crop_info.width=(
unsigned int) (scale_factor*crop_info.width+0.5);
11524 scale_factor=(MagickRealType)
11525 height/windows->image.ximage->height;
11527 crop_info.y=(ssize_t) (scale_factor*crop_info.y+0.5);
11528 crop_info.height=(
unsigned int)
11529 (scale_factor*crop_info.height+0.5);
11530 roi_image=CropImage(*image,&crop_info,&(*image)->exception);
11531 (void) SetImageProgressMonitor(*image,progress_monitor,
11532 (*image)->client_data);
11533 if (roi_image == (
Image *) NULL)
11538 windows->image.orphan=MagickTrue;
11539 (void) XMagickCommand(display,resource_info,windows,command_type,
11541 progress_monitor=SetImageProgressMonitor(*image,
11542 (MagickProgressMonitor) NULL,(*image)->client_data);
11543 (void) XMagickCommand(display,resource_info,windows,
11544 SaveToUndoBufferCommand,image);
11545 windows->image.orphan=MagickFalse;
11546 (void) CompositeImage(*image,CopyCompositeOp,roi_image,
11547 crop_info.x,crop_info.y);
11548 roi_image=DestroyImage(roi_image);
11549 (void) SetImageProgressMonitor(*image,progress_monitor,
11550 (*image)->client_data);
11554 if (command_type != InfoCommand)
11556 XConfigureImageColormap(display,resource_info,windows,*image);
11557 (void) XConfigureImage(display,resource_info,windows,*image);
11559 XCheckRefreshWindows(display,windows);
11560 XInfoWidget(display,windows,text);
11561 (void) XSetFunction(display,windows->image.highlight_context,
11563 state&=(~UpdateRegionState);
11565 XHighlightRectangle(display,windows->image.id,
11566 windows->image.highlight_context,&highlight_info);
11567 XScreenEvent(display,windows,&event);
11568 if (event.xany.window == windows->command.id)
11573 (void) XSetFunction(display,windows->image.highlight_context,GXcopy);
11574 command_type=NullCommand;
11575 id=XCommandWidget(display,windows,ApplyMenu,&event);
11578 (void) CopyMagickString(command,ApplyMenu[
id],MaxTextExtent);
11579 command_type=ApplyCommands[id];
11580 if (
id < ApplyMenus)
11585 entry=XMenuWidget(display,windows,ApplyMenu[
id],
11586 (
const char **) Menus[
id],command);
11589 (void) CopyMagickString(command,Menus[
id][entry],
11591 command_type=Commands[id][entry];
11595 (void) XSetFunction(display,windows->image.highlight_context,
11597 XHighlightRectangle(display,windows->image.id,
11598 windows->image.highlight_context,&highlight_info);
11599 if (command_type == HelpCommand)
11601 (void) XSetFunction(display,windows->image.highlight_context,
11603 XTextViewHelp(display,resource_info,windows,MagickFalse,
11604 "Help Viewer - Region of Interest",ImageROIHelp);
11605 (void) XSetFunction(display,windows->image.highlight_context,
11609 if (command_type == QuitCommand)
11614 state|=EscapeState;
11618 if (command_type != NullCommand)
11619 state|=UpdateRegionState;
11622 XHighlightRectangle(display,windows->image.id,
11623 windows->image.highlight_context,&highlight_info);
11624 switch (event.type)
11628 x=windows->image.x;
11629 y=windows->image.y;
11630 if (event.xbutton.button != Button1)
11632 if (event.xbutton.window != windows->image.id)
11634 x=windows->image.x+
event.xbutton.x;
11635 y=windows->image.y+
event.xbutton.y;
11636 if ((x < (
int) (roi_info.x+RoiDelta)) &&
11637 (x > (
int) (roi_info.x-RoiDelta)) &&
11638 (y < (
int) (roi_info.y+RoiDelta)) &&
11639 (y > (
int) (roi_info.y-RoiDelta)))
11641 roi_info.x=(ssize_t) (roi_info.x+roi_info.width);
11642 roi_info.y=(ssize_t) (roi_info.y+roi_info.height);
11643 state|=UpdateConfigurationState;
11646 if ((x < (
int) (roi_info.x+RoiDelta)) &&
11647 (x > (int) (roi_info.x-RoiDelta)) &&
11648 (y < (
int) (roi_info.y+roi_info.height+RoiDelta)) &&
11649 (y > (int) (roi_info.y+roi_info.height-RoiDelta)))
11651 roi_info.x=(ssize_t) (roi_info.x+roi_info.width);
11652 state|=UpdateConfigurationState;
11655 if ((x < (
int) (roi_info.x+roi_info.width+RoiDelta)) &&
11656 (x > (int) (roi_info.x+roi_info.width-RoiDelta)) &&
11657 (y < (
int) (roi_info.y+RoiDelta)) &&
11658 (y > (int) (roi_info.y-RoiDelta)))
11660 roi_info.y=(ssize_t) (roi_info.y+roi_info.height);
11661 state|=UpdateConfigurationState;
11664 if ((x < (
int) (roi_info.x+roi_info.width+RoiDelta)) &&
11665 (x > (int) (roi_info.x+roi_info.width-RoiDelta)) &&
11666 (y < (
int) (roi_info.y+roi_info.height+RoiDelta)) &&
11667 (y > (int) (roi_info.y+roi_info.height-RoiDelta)))
11669 state|=UpdateConfigurationState;
11672 magick_fallthrough;
11674 case ButtonRelease:
11676 if (event.xbutton.window == windows->pan.id)
11677 if ((highlight_info.x != crop_info.x-windows->image.x) ||
11678 (highlight_info.y != crop_info.y-windows->image.y))
11679 XHighlightRectangle(display,windows->image.id,
11680 windows->image.highlight_context,&highlight_info);
11681 (void) XSetSelectionOwner(display,XA_PRIMARY,windows->image.id,
11682 event.xbutton.time);
11687 if (event.xexpose.window == windows->image.id)
11688 if (event.xexpose.count == 0)
11690 event.xexpose.x=(int) highlight_info.x;
11691 event.xexpose.y=(
int) highlight_info.y;
11692 event.xexpose.width=(int) highlight_info.width;
11693 event.xexpose.height=(
int) highlight_info.height;
11694 XRefreshWindow(display,&windows->image,&event);
11696 if (event.xexpose.window == windows->info.id)
11697 if (event.xexpose.count == 0)
11698 XInfoWidget(display,windows,text);
11706 if (event.xkey.window != windows->image.id)
11711 (void) XLookupString((XKeyEvent *) &
event.xkey,command,(int)
11712 sizeof(command),&key_symbol,(XComposeStatus *) NULL);
11713 switch ((
int) key_symbol)
11721 state|=EscapeState;
11722 magick_fallthrough;
11732 roi_info.x=(ssize_t) (windows->image.width/2L-roi_info.width/2L);
11733 roi_info.y=(ssize_t) (windows->image.height/2L-
11734 roi_info.height/2L);
11766 (void) XSetFunction(display,windows->image.highlight_context,
11768 XTextViewHelp(display,resource_info,windows,MagickFalse,
11769 "Help Viewer - Region of Interest",ImageROIHelp);
11770 (void) XSetFunction(display,windows->image.highlight_context,
11776 command_type=XImageWindowCommand(display,resource_info,windows,
11777 event.xkey.state,key_symbol,image);
11778 if (command_type != NullCommand)
11779 state|=UpdateRegionState;
11783 (void) XSetSelectionOwner(display,XA_PRIMARY,windows->image.id,
11791 if (event.xbutton.window != windows->image.id)
11798 if (windows->info.mapped != MagickFalse)
11800 if ((x < (
int) (windows->info.x+windows->info.width)) &&
11801 (y < (int) (windows->info.y+windows->info.height)))
11802 (void) XWithdrawWindow(display,windows->info.id,
11803 windows->info.screen);
11806 if ((x > (
int) (windows->info.x+windows->info.width)) ||
11807 (y > (int) (windows->info.y+windows->info.height)))
11808 (void) XMapWindow(display,windows->info.id);
11809 roi_info.x=(ssize_t) windows->image.x+event.xmotion.x;
11810 roi_info.y=(ssize_t) windows->image.y+
event.xmotion.y;
11813 case SelectionRequest:
11818 XSelectionRequestEvent
11824 (void) FormatLocaleString(text,MaxTextExtent,
11825 "%.20gx%.20g%+.20g%+.20g",(
double) roi_info.width,(double)
11826 roi_info.height,(
double) roi_info.x,(double) roi_info.y);
11827 request=(&(
event.xselectionrequest));
11828 (void) XChangeProperty(request->display,request->requestor,
11829 request->property,request->target,8,PropModeReplace,
11830 (
unsigned char *) text,(int) strlen(text));
11831 notify.type=SelectionNotify;
11832 notify.display=request->display;
11833 notify.requestor=request->requestor;
11834 notify.selection=request->selection;
11835 notify.target=request->target;
11836 notify.time=request->time;
11837 if (request->property == None)
11838 notify.property=request->target;
11840 notify.property=request->property;
11841 (void) XSendEvent(request->display,request->requestor,False,0,
11842 (XEvent *) ¬ify);
11847 if ((state & UpdateConfigurationState) != 0)
11849 (void) XPutBackEvent(display,&event);
11850 (void) XCheckDefineCursor(display,windows->image.id,cursor);
11853 }
while ((state & ExitState) == 0);
11854 }
while ((state & ExitState) == 0);
11855 (void) XSetFunction(display,windows->image.highlight_context,GXcopy);
11856 XSetCursorState(display,windows,MagickFalse);
11857 if ((state & EscapeState) != 0)
11858 return(MagickTrue);
11859 return(MagickTrue);
11896 static MagickBooleanType XRotateImage(Display *display,
11897 XResourceInfo *resource_info,XWindows *windows,
double degrees,
Image **image)
11900 *
const RotateMenu[] =
11910 direction = HorizontalRotateCommand;
11912 static const ModeType
11913 DirectionCommands[] =
11915 HorizontalRotateCommand,
11916 VerticalRotateCommand
11920 RotateColorCommand,
11921 RotateDirectionCommand,
11923 RotateDismissCommand
11926 static unsigned int
11930 command[MaxTextExtent],
11931 text[MaxTextExtent];
11942 normalized_degrees;
11952 if (degrees == 0.0)
11969 (void) CloneString(&windows->command.name,
"Rotate");
11970 windows->command.data=2;
11971 (void) XCommandWidget(display,windows,RotateMenu,(XEvent *) NULL);
11972 (void) XMapRaised(display,windows->command.id);
11973 XClientMessage(display,windows->image.id,windows->im_protocols,
11974 windows->im_update_widget,CurrentTime);
11978 (void) XSetFunction(display,windows->image.highlight_context,GXinvert);
11979 XQueryPosition(display,windows->image.id,&x,&y);
11984 state=DefaultState;
11987 XHighlightLine(display,windows->image.id,
11988 windows->image.highlight_context,&rotate_info);
11992 XScreenEvent(display,windows,&event);
11993 XHighlightLine(display,windows->image.id,
11994 windows->image.highlight_context,&rotate_info);
11995 if (event.xany.window == windows->command.id)
12000 id=XCommandWidget(display,windows,RotateMenu,&event);
12003 (void) XSetFunction(display,windows->image.highlight_context,
12005 switch (RotateCommands[
id])
12007 case RotateColorCommand:
12010 *ColorMenu[MaxNumberPens];
12021 for (i=0; i < (int) (MaxNumberPens-2); i++)
12022 ColorMenu[i]=resource_info->pen_colors[i];
12023 ColorMenu[MaxNumberPens-2]=
"Browser...";
12024 ColorMenu[MaxNumberPens-1]=(
const char *) NULL;
12028 pen_number=XMenuWidget(display,windows,RotateMenu[
id],
12029 (
const char **) ColorMenu,command);
12030 if (pen_number < 0)
12032 if (pen_number == (MaxNumberPens-2))
12035 color_name[MaxTextExtent] =
"gray";
12040 resource_info->pen_colors[pen_number]=color_name;
12041 XColorBrowserWidget(display,windows,
"Select",color_name);
12042 if (*color_name ==
'\0')
12048 (void) XParseColor(display,windows->map_info->colormap,
12049 resource_info->pen_colors[pen_number],&color);
12050 XBestPixel(display,windows->map_info->colormap,(XColor *) NULL,
12051 (
unsigned int) MaxColors,&color);
12052 windows->pixel_info->pen_colors[pen_number]=color;
12053 pen_id=(
unsigned int) pen_number;
12056 case RotateDirectionCommand:
12059 *
const Directions[] =
12069 id=XMenuWidget(display,windows,RotateMenu[
id],
12070 Directions,command);
12072 direction=DirectionCommands[id];
12075 case RotateHelpCommand:
12077 XTextViewHelp(display,resource_info,windows,MagickFalse,
12078 "Help Viewer - Image Rotation",ImageRotateHelp);
12081 case RotateDismissCommand:
12086 state|=EscapeState;
12093 (void) XSetFunction(display,windows->image.highlight_context,
12097 switch (event.type)
12101 if (event.xbutton.button != Button1)
12103 if (event.xbutton.window != windows->image.id)
12108 (void) XSetFunction(display,windows->image.highlight_context,
12110 rotate_info.x1=
event.xbutton.x;
12111 rotate_info.y1=
event.xbutton.y;
12115 case ButtonRelease:
12122 command[MaxTextExtent];
12127 if (event.xkey.window != windows->image.id)
12132 (void) XLookupString((XKeyEvent *) &
event.xkey,command,(int)
12133 sizeof(command),&key_symbol,(XComposeStatus *) NULL);
12134 switch ((
int) key_symbol)
12142 state|=EscapeState;
12149 (void) XSetFunction(display,windows->image.highlight_context,
12151 XTextViewHelp(display,resource_info,windows,MagickFalse,
12152 "Help Viewer - Image Rotation",ImageRotateHelp);
12153 (void) XSetFunction(display,windows->image.highlight_context,
12159 (void) XBell(display,0);
12167 rotate_info.x1=
event.xmotion.x;
12168 rotate_info.y1=
event.xmotion.y;
12171 rotate_info.x2=rotate_info.x1;
12172 rotate_info.y2=rotate_info.y1;
12173 if (direction == HorizontalRotateCommand)
12174 rotate_info.x2+=32;
12176 rotate_info.y2-=32;
12177 }
while ((state & ExitState) == 0);
12178 (void) XSetFunction(display,windows->image.highlight_context,GXcopy);
12179 (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
12180 if ((state & EscapeState) != 0)
12181 return(MagickTrue);
12186 (void) XSetFunction(display,windows->image.highlight_context,GXinvert);
12187 state=DefaultState;
12195 if (windows->info.mapped == MagickFalse)
12196 (void) XMapWindow(display,windows->info.id);
12197 (void) FormatLocaleString(text,MaxTextExtent,
" %g",
12198 direction == VerticalRotateCommand ? degrees-90.0 : degrees);
12199 XInfoWidget(display,windows,text);
12200 XHighlightLine(display,windows->image.id,
12201 windows->image.highlight_context,&rotate_info);
12204 if (windows->info.mapped != MagickFalse)
12205 (void) XWithdrawWindow(display,windows->info.id,
12206 windows->info.screen);
12210 XScreenEvent(display,windows,&event);
12212 XHighlightLine(display,windows->image.id,
12213 windows->image.highlight_context,&rotate_info);
12214 switch (event.type)
12218 case ButtonRelease:
12223 rotate_info.x2=
event.xbutton.x;
12224 rotate_info.y2=
event.xbutton.y;
12232 rotate_info.x2=
event.xmotion.x;
12233 rotate_info.y2=
event.xmotion.y;
12241 if (rotate_info.x2 < 0)
12244 if (rotate_info.x2 > (
int) windows->image.width)
12245 rotate_info.x2=(short) windows->image.width;
12246 if (rotate_info.y2 < 0)
12249 if (rotate_info.y2 > (
int) windows->image.height)
12250 rotate_info.y2=(
short) windows->image.height;
12255 distance=(
unsigned int)
12256 ((rotate_info.x2-rotate_info.x1+1)*(rotate_info.x2-rotate_info.x1+1))+
12257 ((rotate_info.y2-rotate_info.y1+1)*(rotate_info.y2-rotate_info.y1+1));
12259 degrees=RadiansToDegrees(-atan2((
double) (rotate_info.y2-
12260 rotate_info.y1),(
double) (rotate_info.x2-rotate_info.x1)));
12261 }
while ((state & ExitState) == 0);
12262 (void) XSetFunction(display,windows->image.highlight_context,GXcopy);
12263 (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
12265 return(MagickTrue);
12267 if (direction == VerticalRotateCommand)
12269 if (degrees == 0.0)
12270 return(MagickTrue);
12274 normalized_degrees=degrees;
12275 while (normalized_degrees < -45.0)
12276 normalized_degrees+=360.0;
12277 for (rotations=0; normalized_degrees > 45.0; rotations++)
12278 normalized_degrees-=90.0;
12279 if (normalized_degrees != 0.0)
12280 (void) XMagickCommand(display,resource_info,windows,ApplyCommand,image);
12281 XSetCursorState(display,windows,MagickTrue);
12282 XCheckRefreshWindows(display,windows);
12283 (*image)->background_color.red=ScaleShortToQuantum(
12284 windows->pixel_info->pen_colors[pen_id].red);
12285 (*image)->background_color.green=ScaleShortToQuantum(
12286 windows->pixel_info->pen_colors[pen_id].green);
12287 (*image)->background_color.blue=ScaleShortToQuantum(
12288 windows->pixel_info->pen_colors[pen_id].blue);
12289 rotate_image=RotateImage(*image,degrees,&(*image)->exception);
12290 XSetCursorState(display,windows,MagickFalse);
12291 if (rotate_image == (
Image *) NULL)
12292 return(MagickFalse);
12293 *image=DestroyImage(*image);
12294 *image=rotate_image;
12295 if (windows->image.crop_geometry != (
char *) NULL)
12300 width=(
unsigned int) (*image)->columns;
12301 height=(
unsigned int) (*image)->rows;
12302 (void) XParseGeometry(windows->image.crop_geometry,&x,&y,&width,&height);
12303 switch (rotations % 4)
12313 (void) FormatLocaleString(windows->image.crop_geometry,MaxTextExtent,
12314 "%ux%u%+d%+d",height,width,(
int) (*image)->columns-
12323 (void) FormatLocaleString(windows->image.crop_geometry,MaxTextExtent,
12324 "%ux%u%+d%+d",width,height,(
int) width-x,(int) height-y);
12332 (void) FormatLocaleString(windows->image.crop_geometry,MaxTextExtent,
12333 "%ux%u%+d%+d",height,width,y,(
int) (*image)->rows-(int) width-x);
12338 if (windows->image.orphan != MagickFalse)
12339 return(MagickTrue);
12340 if (normalized_degrees != 0.0)
12345 windows->image.window_changes.width=(int) (*image)->columns;
12346 windows->image.window_changes.height=(
int) (*image)->rows;
12347 if (windows->image.crop_geometry != (
char *) NULL)
12352 (void) XParseGeometry(windows->image.crop_geometry,&x,&y,
12354 windows->image.window_changes.width=(int) width;
12355 windows->image.window_changes.height=(int) height;
12357 XConfigureImageColormap(display,resource_info,windows,*image);
12360 if (((rotations % 4) == 1) || ((rotations % 4) == 3))
12362 windows->image.window_changes.width=windows->image.ximage->height;
12363 windows->image.window_changes.height=windows->image.ximage->width;
12368 (void) XConfigureImage(display,resource_info,windows,*image);
12369 return(MagickTrue);
12402 static MagickBooleanType XSaveImage(Display *display,
12403 XResourceInfo *resource_info,XWindows *windows,
Image *image)
12406 filename[MaxTextExtent],
12407 geometry[MaxTextExtent];
12421 if (resource_info->write_filename != (
char *) NULL)
12422 (void) CopyMagickString(filename,resource_info->write_filename,
12427 path[MaxTextExtent];
12432 GetPathComponent(image->filename,HeadPath,path);
12433 GetPathComponent(image->filename,TailPath,filename);
12436 status=chdir(path);
12438 (void) ThrowMagickException(&image->exception,GetMagickModule(),
12439 FileOpenError,
"UnableToOpenFile",
"%s",path);
12442 XFileBrowserWidget(display,windows,
"Save",filename);
12443 if (*filename ==
'\0')
12444 return(MagickTrue);
12445 if (IsPathAccessible(filename) != MagickFalse)
12453 status=XConfirmWidget(display,windows,
"Overwrite",filename);
12455 return(MagickTrue);
12457 image_info=CloneImageInfo(resource_info->image_info);
12458 (void) CopyMagickString(image_info->filename,filename,MaxTextExtent);
12459 (void) SetImageInfo(image_info,1,&image->exception);
12460 if ((LocaleCompare(image_info->magick,
"JPEG") == 0) ||
12461 (LocaleCompare(image_info->magick,
"JPG") == 0))
12464 quality[MaxTextExtent];
12472 (void) FormatLocaleString(quality,MaxTextExtent,
"%.20g",(
double)
12474 status=XDialogWidget(display,windows,
"Save",
"Enter JPEG quality:",
12476 if (*quality ==
'\0')
12477 return(MagickTrue);
12478 image->quality=StringToUnsignedLong(quality);
12479 image_info->interlace=status != 0 ? NoInterlace : PlaneInterlace;
12481 if ((LocaleCompare(image_info->magick,
"EPS") == 0) ||
12482 (LocaleCompare(image_info->magick,
"PDF") == 0) ||
12483 (LocaleCompare(image_info->magick,
"PS") == 0) ||
12484 (LocaleCompare(image_info->magick,
"PS2") == 0))
12487 geometry[MaxTextExtent];
12490 *
const PageSizes[] =
12512 (void) CopyMagickString(geometry,PSPageGeometry,MaxTextExtent);
12513 if (LocaleCompare(image_info->magick,
"PDF") == 0)
12514 (
void) CopyMagickString(geometry,PSPageGeometry,MaxTextExtent);
12515 if (image_info->page != (
char *) NULL)
12516 (void) CopyMagickString(geometry,image_info->page,MaxTextExtent);
12517 XListBrowserWidget(display,windows,&windows->widget,PageSizes,
"Select",
12518 "Select page geometry:",geometry);
12519 if (*geometry !=
'\0')
12520 image_info->page=GetPageGeometry(geometry);
12525 XSetCursorState(display,windows,MagickTrue);
12526 XCheckRefreshWindows(display,windows);
12527 save_image=CloneImage(image,0,0,MagickTrue,&image->exception);
12528 if (save_image == (
Image *) NULL)
12529 return(MagickFalse);
12530 (void) FormatLocaleString(geometry,MaxTextExtent,
"%dx%d!",
12531 windows->image.ximage->width,windows->image.ximage->height);
12532 (void) TransformImage(&save_image,windows->image.crop_geometry,geometry);
12536 (void) CopyMagickString(save_image->filename,filename,MaxTextExtent);
12537 status=WriteImage(image_info,save_image);
12538 if (status != MagickFalse)
12539 image->taint=MagickFalse;
12540 save_image=DestroyImage(save_image);
12541 image_info=DestroyImageInfo(image_info);
12542 XSetCursorState(display,windows,MagickFalse);
12543 return(status != 0 ? MagickTrue : MagickFalse);
12576 #if defined(__cplusplus) || defined(c_plusplus)
12580 static int XPredicate(Display *magick_unused(display),XEvent *event,
char *data)
12585 magick_unreferenced(display);
12587 windows=(XWindows *) data;
12588 if ((event->type == ClientMessage) &&
12589 (
event->xclient.window == windows->image.id))
12590 return(MagickFalse);
12591 return(MagickTrue);
12594 #if defined(__cplusplus) || defined(c_plusplus)
12598 static void XScreenEvent(Display *display,XWindows *windows,XEvent *event)
12604 (void) XIfEvent(display,event,XPredicate,(
char *) windows);
12605 if (event->xany.window == windows->command.id)
12607 switch (event->type)
12610 case ButtonRelease:
12612 if ((event->xbutton.button == Button3) &&
12613 (
event->xbutton.state & Mod1Mask))
12618 event->xbutton.button=Button2;
12619 event->xbutton.state&=(~Mod1Mask);
12621 if (event->xbutton.window == windows->backdrop.id)
12623 (void) XSetInputFocus(display,event->xbutton.window,RevertToParent,
12624 event->xbutton.time);
12627 if (event->xbutton.window == windows->pan.id)
12629 XPanImage(display,windows,event);
12632 if (event->xbutton.window == windows->image.id)
12633 if (event->xbutton.button == Button2)
12638 x=
event->xbutton.x;
12639 y=
event->xbutton.y;
12643 if (x >= (
int) windows->image.width)
12644 x=(int) (windows->image.width-1);
12645 windows->magnify.x=(int) windows->image.x+x;
12649 if (y >= (
int) windows->image.height)
12650 y=(
int) (windows->image.height-1);
12651 windows->magnify.y=windows->image.y+y;
12652 if (windows->magnify.mapped == MagickFalse)
12653 (void) XMapRaised(display,windows->magnify.id);
12654 XMakeMagnifyImage(display,windows);
12655 if (event->type == ButtonRelease)
12656 (void) XWithdrawWindow(display,windows->info.id,
12657 windows->info.screen);
12662 case ClientMessage:
12667 if (event->xclient.message_type != windows->wm_protocols)
12669 if (*event->xclient.data.l != (
long) windows->wm_delete_window)
12671 if (event->xclient.window == windows->magnify.id)
12673 (void) XWithdrawWindow(display,windows->magnify.id,
12674 windows->magnify.screen);
12679 case ConfigureNotify:
12681 if (event->xconfigure.window == windows->magnify.id)
12689 windows->magnify.width=(
unsigned int) event->xconfigure.width;
12690 windows->magnify.height=(
unsigned int)
event->xconfigure.height;
12691 if (windows->magnify.mapped == MagickFalse)
12694 while ((
int) magnify <=
event->xconfigure.width)
12696 while ((
int) magnify <=
event->xconfigure.height)
12699 if (((
int) magnify !=
event->xconfigure.width) ||
12700 ((
int) magnify !=
event->xconfigure.height))
12705 window_changes.width=(int) magnify;
12706 window_changes.height=(int) magnify;
12707 (void) XReconfigureWMWindow(display,windows->magnify.id,
12708 windows->magnify.screen,(
unsigned int) (CWWidth | CWHeight),
12712 XMakeMagnifyImage(display,windows);
12719 if (event->xexpose.window == windows->image.id)
12721 XRefreshWindow(display,&windows->image,event);
12724 if (event->xexpose.window == windows->pan.id)
12725 if (event->xexpose.count == 0)
12727 XDrawPanRectangle(display,windows);
12730 if (event->xexpose.window == windows->magnify.id)
12731 if (event->xexpose.count == 0)
12733 XMakeMagnifyImage(display,windows);
12741 command[MaxTextExtent];
12746 if (event->xkey.window != windows->magnify.id)
12751 (void) XLookupString((XKeyEvent *) &
event->xkey,command,(int)
12752 sizeof(command),&key_symbol,(XComposeStatus *) NULL);
12753 XMagnifyWindowCommand(display,windows,event->xkey.state,key_symbol);
12758 if (event->xmap.window == windows->magnify.id)
12760 windows->magnify.mapped=MagickTrue;
12761 (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
12764 if (event->xmap.window == windows->info.id)
12766 windows->info.mapped=MagickTrue;
12773 while (XCheckMaskEvent(display,ButtonMotionMask,event)) ;
12774 if (event->xmotion.window == windows->image.id)
12775 if (windows->magnify.mapped != MagickFalse)
12780 x=
event->xmotion.x;
12781 y=
event->xmotion.y;
12785 if (x >= (
int) windows->image.width)
12786 x=(
int) (windows->image.width-1);
12787 windows->magnify.x=(int) windows->image.x+x;
12791 if (y >= (
int) windows->image.height)
12792 y=(
int) (windows->image.height-1);
12793 windows->magnify.y=windows->image.y+y;
12794 XMakeMagnifyImage(display,windows);
12800 if (event->xunmap.window == windows->magnify.id)
12802 windows->magnify.mapped=MagickFalse;
12805 if (event->xunmap.window == windows->info.id)
12807 windows->info.mapped=MagickFalse;
12849 static void XSetCropGeometry(Display *display,XWindows *windows,
12853 text[MaxTextExtent];
12866 if (windows->info.mapped != MagickFalse)
12871 (void) FormatLocaleString(text,MaxTextExtent,
" %.20gx%.20g%+.20g%+.20g",
12872 (
double) crop_info->width,(double) crop_info->height,(
double)
12873 crop_info->x,(double) crop_info->y);
12874 XInfoWidget(display,windows,text);
12881 width=(
unsigned int) image->columns;
12882 height=(
unsigned int) image->rows;
12883 if (windows->image.crop_geometry != (
char *) NULL)
12884 (
void) XParseGeometry(windows->image.crop_geometry,&x,&y,&width,&height);
12886 windows->image.crop_geometry=AcquireString((
char *) NULL);
12890 scale_factor=(MagickRealType) width/windows->image.ximage->width;
12891 if (crop_info->x > 0)
12892 x+=(int) (scale_factor*crop_info->x+0.5);
12893 width=(
unsigned int) (scale_factor*crop_info->width+0.5);
12896 scale_factor=(MagickRealType) height/windows->image.ximage->height;
12897 if (crop_info->y > 0)
12898 y+=(int) (scale_factor*crop_info->y+0.5);
12899 height=(
unsigned int) (scale_factor*crop_info->height+0.5);
12902 (void) FormatLocaleString(windows->image.crop_geometry,MaxTextExtent,
12903 "%ux%u%+d%+d",width,height,x,y);
12943 static Image *XTileImage(Display *display,XResourceInfo *resource_info,
12944 XWindows *windows,
Image *image,XEvent *event)
12947 *
const VerbMenu[] =
12957 static const ModeType
12968 command[MaxTextExtent],
12969 filename[MaxTextExtent];
13000 width=(
unsigned int) image->columns;
13001 height=(
unsigned int) image->rows;
13002 if (windows->image.crop_geometry != (
char *) NULL)
13003 (
void) XParseGeometry(windows->image.crop_geometry,&x,&y,&width,&height);
13004 scale_factor=(MagickRealType) width/windows->image.ximage->width;
13005 event->xbutton.x+=windows->image.x;
13006 event->xbutton.x=(
int) (scale_factor*
event->xbutton.x+x+0.5);
13007 scale_factor=(MagickRealType) height/windows->image.ximage->height;
13008 event->xbutton.y+=windows->image.y;
13009 event->xbutton.y=(
int) (scale_factor*
event->xbutton.y+y+0.5);
13013 width=(
unsigned int) image->columns;
13014 height=(
unsigned int) image->rows;
13017 (void) XParseGeometry(image->montage,&x,&y,&width,&height);
13018 tile=((
event->xbutton.y-y)/height)*(((int) image->columns-x)/width)+
13019 (event->xbutton.x-x)/width;
13025 (void) XBell(display,0);
13026 return((
Image *) NULL);
13031 p=image->directory;
13032 for (i=tile; (i != 0) && (*p !=
'\0'); )
13043 (void) XBell(display,0);
13044 return((
Image *) NULL);
13049 id=XMenuWidget(display,windows,
"Tile Verb",VerbMenu,command);
13051 return((
Image *) NULL);
13053 while ((*q !=
'\xff') && (*q !=
'\0'))
13055 (void) CopyMagickString(filename,p,(
size_t) (q-p+1));
13059 XSetCursorState(display,windows,MagickTrue);
13060 XCheckRefreshWindows(display,windows);
13061 tile_image=NewImageList();
13062 switch (TileCommands[
id])
13064 case TileLoadCommand:
13069 XCheckRefreshWindows(display,windows);
13070 (void) CopyMagickString(resource_info->image_info->magick,
"MIFF",
13072 (void) CopyMagickString(resource_info->image_info->filename,filename,
13074 tile_image=ReadImage(resource_info->image_info,&image->exception);
13075 CatchException(&image->exception);
13076 (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
13079 case TileNextCommand:
13084 XClientMessage(display,windows->image.id,windows->im_protocols,
13085 windows->im_next_image,CurrentTime);
13088 case TileFormerCommand:
13093 XClientMessage(display,windows->image.id,windows->im_protocols,
13094 windows->im_former_image,CurrentTime);
13097 case TileDeleteCommand:
13102 if (IsPathAccessible(filename) == MagickFalse)
13104 XNoticeWidget(display,windows,
"Image file does not exist:",filename);
13107 status=XConfirmWidget(display,windows,
"Really delete tile",filename);
13110 status=ShredFile(filename);
13111 status|=remove_utf8(filename);
13112 if (status != MagickFalse)
13114 XNoticeWidget(display,windows,
"Unable to delete image file:",
13118 magick_fallthrough;
13120 case TileUpdateCommand:
13142 for (p=image->directory; *p !=
'\0'; p++)
13148 while ((*q !=
'\xff') && (*q !=
'\0'))
13150 (void) CopyMagickString(filename,p,(
size_t) (q-p+1));
13152 if (IsPathAccessible(filename) != MagickFalse)
13160 x_offset=(int) (width*(tile % (((
int) image->columns-x)/width))+x);
13161 y_offset=(int) (height*(tile/(((
int) image->columns-x)/width))+y);
13162 exception=(&image->exception);
13163 image_view=AcquireAuthenticCacheView(image,exception);
13164 (void) GetOneCacheViewVirtualPixel(image_view,0,0,&pixel,exception);
13165 for (i=0; i < (int) height; i++)
13167 s=GetCacheViewAuthenticPixels(image_view,(ssize_t) x_offset,(ssize_t)
13168 y_offset+i,width,1,exception);
13171 for (j=0; j < (int) width; j++)
13173 if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
13176 image_view=DestroyCacheView(image_view);
13179 windows->image.window_changes.width=(int) image->columns;
13180 windows->image.window_changes.height=(
int) image->rows;
13181 XConfigureImageColormap(display,resource_info,windows,image);
13182 (void) XConfigureImage(display,resource_info,windows,image);
13188 XSetCursorState(display,windows,MagickFalse);
13189 return(tile_image);
13225 static void XTranslateImage(Display *display,XWindows *windows,
13226 Image *image,
const KeySym key_symbol)
13229 text[MaxTextExtent];
13242 x_offset=windows->image.width;
13243 y_offset=windows->image.height;
13244 if (image->montage != (
char *) NULL)
13245 (void) XParseGeometry(image->montage,&x,&y,&x_offset,&y_offset);
13246 switch ((
int) key_symbol)
13251 windows->image.x=(int) windows->image.width/2;
13252 windows->image.y=(
int) windows->image.height/2;
13258 windows->image.x-=x_offset;
13265 windows->image.y-=y_offset;
13271 windows->image.x+=x_offset;
13278 windows->image.y+=y_offset;
13287 if (windows->image.x < 0)
13288 windows->image.x=0;
13290 if ((
int) (windows->image.x+windows->image.width) >
13291 windows->image.ximage->width)
13292 windows->image.x=(int) windows->image.ximage->width-windows->image.width;
13293 if (windows->image.y < 0)
13294 windows->image.y=0;
13296 if ((
int) (windows->image.y+windows->image.height) >
13297 windows->image.ximage->height)
13298 windows->image.y=(int) windows->image.ximage->height-windows->image.height;
13302 (
void) FormatLocaleString(text,MaxTextExtent,
" %ux%u%+d%+d ",
13303 windows->image.width,windows->image.height,windows->image.x,
13305 XInfoWidget(display,windows,text);
13306 XCheckRefreshWindows(display,windows);
13307 XDrawPanRectangle(display,windows);
13308 XRefreshWindow(display,&windows->image,(XEvent *) NULL);
13309 (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
13342 static MagickBooleanType XTrimImage(Display *display,
13343 XResourceInfo *resource_info,XWindows *windows,
Image *image)
13359 XSetCursorState(display,windows,MagickTrue);
13360 XCheckRefreshWindows(display,windows);
13364 background=XGetPixel(windows->image.ximage,0,0);
13365 trim_info.width=(size_t) windows->image.ximage->width;
13366 for (x=0; x < windows->image.ximage->width; x++)
13368 for (y=0; y < windows->image.ximage->height; y++)
13370 pixel=XGetPixel(windows->image.ximage,x,y);
13371 if (pixel != background)
13374 if (y < windows->image.ximage->height)
13377 trim_info.x=(ssize_t) x;
13378 if (trim_info.x == (ssize_t) windows->image.ximage->width)
13380 XSetCursorState(display,windows,MagickFalse);
13381 return(MagickFalse);
13386 background=XGetPixel(windows->image.ximage,windows->image.ximage->width-1,0);
13387 for (x=windows->image.ximage->width-1; x != 0; x--)
13389 for (y=0; y < windows->image.ximage->height; y++)
13391 pixel=XGetPixel(windows->image.ximage,x,y);
13392 if (pixel != background)
13395 if (y < windows->image.ximage->height)
13398 trim_info.width=(size_t) (x-trim_info.x+1);
13402 background=XGetPixel(windows->image.ximage,0,0);
13403 trim_info.height=(size_t) windows->image.ximage->height;
13404 for (y=0; y < windows->image.ximage->height; y++)
13406 for (x=0; x < windows->image.ximage->width; x++)
13408 pixel=XGetPixel(windows->image.ximage,x,y);
13409 if (pixel != background)
13412 if (x < windows->image.ximage->width)
13415 trim_info.y=(ssize_t) y;
13419 background=XGetPixel(windows->image.ximage,0,windows->image.ximage->height-1);
13420 for (y=windows->image.ximage->height-1; y != 0; y--)
13422 for (x=0; x < windows->image.ximage->width; x++)
13424 pixel=XGetPixel(windows->image.ximage,x,y);
13425 if (pixel != background)
13428 if (x < windows->image.ximage->width)
13431 trim_info.height=(size_t) y-trim_info.y+1;
13432 if (((
unsigned int) trim_info.width != windows->image.width) ||
13433 ((
unsigned int) trim_info.height != windows->image.height))
13438 XSetCropGeometry(display,windows,&trim_info,image);
13439 windows->image.window_changes.width=(int) trim_info.width;
13440 windows->image.window_changes.height=(
int) trim_info.height;
13441 (void) XConfigureImage(display,resource_info,windows,image);
13443 XSetCursorState(display,windows,MagickFalse);
13444 return(MagickTrue);
13479 static Image *XVisualDirectoryImage(Display *display,
13480 XResourceInfo *resource_info,XWindows *windows)
13482 #define TileImageTag "Scale/Image"
13483 #define XClientName "montage"
13519 filename[MaxTextExtent] =
"\0",
13520 filenames[MaxTextExtent] =
"*";
13523 background_resources;
13528 XFileBrowserWidget(display,windows,
"Directory",filenames);
13529 if (*filenames ==
'\0')
13530 return((
Image *) NULL);
13534 filelist=(
char **) AcquireMagickMemory(
sizeof(*filelist));
13535 if (filelist == (
char **) NULL)
13537 ThrowXWindowException(ResourceLimitError,
"MemoryAllocationFailed",
13539 return((
Image *) NULL);
13542 filelist[0]=filenames;
13543 status=ExpandFilenames(&number_files,&filelist);
13544 if ((status == MagickFalse) || (number_files == 0))
13546 if (number_files == 0)
13547 ThrowXWindowException(ImageError,
"NoImagesWereFound",filenames)
13549 ThrowXWindowException(ResourceLimitError,
"MemoryAllocationFailed",
13551 return((
Image *) NULL);
13556 background_resources=(*resource_info);
13557 background_resources.window_id=AcquireString(
"");
13558 (void) FormatLocaleString(background_resources.window_id,MaxTextExtent,
13559 "0x%lx",windows->image.id);
13560 background_resources.backdrop=MagickTrue;
13564 backdrop=(windows->visual_info->klass == TrueColor) ||
13565 (windows->visual_info->klass == DirectColor) ? MagickTrue : MagickFalse;
13566 read_info=CloneImageInfo(resource_info->image_info);
13567 (void) SetImageOption(read_info,
"jpeg:size",
"120x120");
13568 (void) CloneString(&read_info->size,DefaultTileGeometry);
13569 (void) SetImageInfoProgressMonitor(read_info,(MagickProgressMonitor) NULL,
13571 images=NewImageList();
13572 exception=AcquireExceptionInfo();
13573 XSetCursorState(display,windows,MagickTrue);
13574 XCheckRefreshWindows(display,windows);
13575 for (i=0; i < (int) number_files; i++)
13577 (void) CopyMagickString(read_info->filename,filelist[i],MaxTextExtent);
13578 filelist[i]=DestroyString(filelist[i]);
13579 *read_info->magick=
'\0';
13580 next_image=ReadImage(read_info,exception);
13581 CatchException(exception);
13582 if (next_image != (
Image *) NULL)
13584 (void) DeleteImageProperty(next_image,
"label");
13585 (void) SetImageProperty(next_image,
"label",InterpretImageProperties(
13586 read_info,next_image,DefaultTileLabel));
13587 (void) ParseRegionGeometry(next_image,read_info->size,&geometry,
13589 thumbnail_image=ThumbnailImage(next_image,geometry.width,
13590 geometry.height,exception);
13591 if (thumbnail_image != (
Image *) NULL)
13593 next_image=DestroyImage(next_image);
13594 next_image=thumbnail_image;
13598 (void) XDisplayBackgroundImage(display,&background_resources,
13600 XSetCursorState(display,windows,MagickTrue);
13602 AppendImageToList(&images,next_image);
13603 if (images->progress_monitor != (MagickProgressMonitor) NULL)
13608 proceed=SetImageProgress(images,LoadImageTag,(MagickOffsetType) i,
13609 (MagickSizeType) number_files);
13610 if (proceed == MagickFalse)
13615 exception=DestroyExceptionInfo(exception);
13616 filelist=(
char **) RelinquishMagickMemory(filelist);
13617 if (images == (
Image *) NULL)
13619 read_info=DestroyImageInfo(read_info);
13620 XSetCursorState(display,windows,MagickFalse);
13621 ThrowXWindowException(ImageError,
"NoImagesWereLoaded",filenames);
13622 return((
Image *) NULL);
13627 montage_info=CloneMontageInfo(read_info,(
MontageInfo *) NULL);
13628 montage_info->pointsize=10;
13629 if (resource_info->font != (
char *) NULL)
13630 (void) CloneString(&montage_info->font,resource_info->font);
13631 (void) CopyMagickString(montage_info->filename,filename,MaxTextExtent);
13632 montage_image=MontageImageList(read_info,montage_info,GetFirstImageInList(
13633 images),&images->exception);
13634 images=DestroyImageList(images);
13635 montage_info=DestroyMontageInfo(montage_info);
13636 read_info=DestroyImageInfo(read_info);
13637 XSetCursorState(display,windows,MagickFalse);
13638 if (montage_image == (
Image *) NULL)
13639 return(montage_image);
13640 XClientMessage(display,windows->image.id,windows->im_protocols,
13641 windows->im_next_image,CurrentTime);
13642 return(montage_image);
13673 MagickExport MagickBooleanType XDisplayBackgroundImage(Display *display,
13674 XResourceInfo *resource_info,
Image *image)
13677 geometry[MaxTextExtent],
13678 visual_type[MaxTextExtent];
13691 static XStandardColormap
13695 *visual_info = (XVisualInfo *) NULL;
13718 assert(image != (
Image *) NULL);
13719 assert(image->signature == MagickCoreSignature);
13720 if (IsEventLogging() != MagickFalse)
13721 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
13722 resources=(*resource_info);
13723 window_info.id=(Window) NULL;
13724 root_window=XRootWindow(display,XDefaultScreen(display));
13725 if (LocaleCompare(resources.window_id,
"root") == 0)
13726 window_info.id=root_window;
13729 if (isdigit((
int) ((
unsigned char) *resources.window_id)) != 0)
13730 window_info.id=XWindowByID(display,root_window,
13731 (Window) strtol((
char *) resources.window_id,(
char **) NULL,0));
13732 if (window_info.id == (Window) NULL)
13733 window_info.id=XWindowByName(display,root_window,resources.window_id);
13735 if (window_info.id == (Window) NULL)
13737 ThrowXWindowException(XServerError,
"NoWindowWithSpecifiedIDExists",
13738 resources.window_id);
13743 window_attributes.width=XDisplayWidth(display,XDefaultScreen(display));
13744 window_attributes.height=XDisplayHeight(display,XDefaultScreen(display));
13745 (void) CopyMagickString(visual_type,
"default",MaxTextExtent);
13746 status=XGetWindowAttributes(display,window_info.id,&window_attributes);
13748 (void) FormatLocaleString(visual_type,MaxTextExtent,
"0x%lx",
13749 XVisualIDFromVisual(window_attributes.visual));
13750 if (visual_info == (XVisualInfo *) NULL)
13755 map_info=XAllocStandardColormap();
13756 if (map_info == (XStandardColormap *) NULL)
13757 ThrowXWindowFatalException(XServerFatalError,
"MemoryAllocationFailed",
13759 map_info->colormap=(Colormap) NULL;
13760 pixel.pixels=(
unsigned long *) NULL;
13764 resources.map_type=(
char *) NULL;
13765 resources.visual_type=visual_type;
13766 visual_info=XBestVisualInfo(display,map_info,&resources);
13767 if (visual_info == (XVisualInfo *) NULL)
13768 ThrowXWindowFatalException(XServerFatalError,
"UnableToGetVisual",
13769 resources.visual_type);
13773 window_info.ximage=(XImage *) NULL;
13774 window_info.matte_image=(XImage *) NULL;
13775 window_info.pixmap=(Pixmap) NULL;
13776 window_info.matte_pixmap=(Pixmap) NULL;
13781 if (window_info.id == root_window)
13782 (void) XDestroyWindowColors(display,root_window);
13786 resources.colormap=SharedColormap;
13787 XMakeStandardColormap(display,visual_info,&resources,image,map_info,&pixel);
13791 context_values.background=pixel.foreground_color.pixel;
13792 context_values.foreground=pixel.background_color.pixel;
13793 pixel.annotate_context=XCreateGC(display,window_info.id,
13794 (
size_t) (GCBackground | GCForeground),&context_values);
13795 if (pixel.annotate_context == (GC) NULL)
13796 ThrowXWindowFatalException(XServerFatalError,
"UnableToCreateGraphicContext",
13801 window_info.name=AcquireString(
"\0");
13802 window_info.icon_name=AcquireString(
"\0");
13803 XGetWindowInfo(display,visual_info,map_info,&pixel,(XFontStruct *) NULL,
13804 &resources,&window_info);
13808 window_info.width=(
unsigned int) image->columns;
13809 window_info.height=(
unsigned int) image->rows;
13810 if ((image->columns != window_info.width) ||
13811 (image->rows != window_info.height))
13812 ThrowXWindowFatalException(XServerFatalError,
"UnableToCreateXImage",
13814 (void) FormatLocaleString(geometry,MaxTextExtent,
"%ux%u+0+0>",
13815 window_attributes.width,window_attributes.height);
13816 geometry_info.width=window_info.width;
13817 geometry_info.height=window_info.height;
13818 geometry_info.x=(ssize_t) window_info.x;
13819 geometry_info.y=(ssize_t) window_info.y;
13820 (void) ParseMetaGeometry(geometry,&geometry_info.x,&geometry_info.y,
13821 &geometry_info.width,&geometry_info.height);
13822 window_info.width=(
unsigned int) geometry_info.width;
13823 window_info.height=(
unsigned int) geometry_info.height;
13824 window_info.x=(int) geometry_info.x;
13825 window_info.y=(
int) geometry_info.y;
13826 status=XMakeImage(display,&resources,&window_info,image,window_info.width,
13827 window_info.height);
13828 if (status == MagickFalse)
13829 ThrowXWindowFatalException(XServerFatalError,
"UnableToCreateXImage",
13833 if (resource_info->debug != MagickFalse)
13835 (void) LogMagickEvent(X11Event,GetMagickModule(),
13836 "Image: %s[%.20g] %.20gx%.20g ",image->filename,(double) image->scene,
13837 (
double) image->columns,(double) image->rows);
13838 if (image->colors != 0)
13839 (void) LogMagickEvent(X11Event,GetMagickModule(),
"%.20gc ",(double)
13841 (void) LogMagickEvent(X11Event,GetMagickModule(),
"%s",image->magick);
13846 width=(int) window_info.width;
13847 height=(
int) window_info.height;
13848 if (resources.backdrop != MagickFalse)
13853 window_info.x=(window_attributes.width/2)-(window_info.ximage->width/2);
13854 window_info.y=(window_attributes.height/2)-(window_info.ximage->height/2);
13855 width=window_attributes.width;
13856 height=window_attributes.height;
13858 if ((resources.image_geometry != (
char *) NULL) &&
13859 (*resources.image_geometry !=
'\0'))
13862 default_geometry[MaxTextExtent];
13874 size_hints=XAllocSizeHints();
13875 if (size_hints == (XSizeHints *) NULL)
13876 ThrowXWindowFatalException(ResourceLimitFatalError,
13877 "MemoryAllocationFailed",image->filename);
13878 size_hints->flags=0L;
13879 (void) FormatLocaleString(default_geometry,MaxTextExtent,
"%dx%d",
13881 flags=XWMGeometry(display,visual_info->screen,resources.image_geometry,
13882 default_geometry,window_info.border_width,size_hints,&window_info.x,
13883 &window_info.y,&width,&height,&gravity);
13884 if (flags & (XValue | YValue))
13886 width=window_attributes.width;
13887 height=window_attributes.height;
13889 (void) XFree((
void *) size_hints);
13894 window_info.pixmap=XCreatePixmap(display,window_info.id,(
unsigned int) width,
13895 (
unsigned int) height,window_info.depth);
13896 if (window_info.pixmap == (Pixmap) NULL)
13897 ThrowXWindowFatalException(XServerFatalError,
"UnableToCreateXPixmap",
13902 if (((
unsigned int) width > window_info.width) ||
13903 ((
unsigned int) height > window_info.height))
13904 (void) XFillRectangle(display,window_info.pixmap,
13905 window_info.annotate_context,0,0,(
unsigned int) width,
13906 (
unsigned int) height);
13907 (void) XPutImage(display,window_info.pixmap,window_info.annotate_context,
13908 window_info.ximage,0,0,window_info.x,window_info.y,(
unsigned int)
13909 window_info.width,(
unsigned int) window_info.height);
13910 (void) XSetWindowBackgroundPixmap(display,window_info.id,window_info.pixmap);
13911 (void) XClearWindow(display,window_info.id);
13912 delay=1000*image->delay/MagickMax(image->ticks_per_second,1L);
13913 XDelay(display,delay == 0UL ? 10UL : delay);
13914 (void) XSync(display,MagickFalse);
13915 return(window_info.id == root_window ? MagickTrue : MagickFalse);
13955 MagickExport
Image *XDisplayImage(Display *display,XResourceInfo *resource_info,
13956 char **argv,
int argc,
Image **image,
size_t *state)
13958 #define MagnifySize 256
13959 #define MagickMenus 10
13960 #define MagickTitle "Commands"
13963 *
const CommandMenu[] =
13977 *
const FileMenu[] =
13987 "Visual Directory...",
13991 *
const EditMenu[] =
14000 *
const ViewMenu[] =
14011 *
const TransformMenu[] =
14025 *
const EnhanceMenu[] =
14033 "Contrast Stretch...",
14034 "Sigmoidal Contrast...",
14043 *
const EffectsMenu[] =
14068 "Charcoal Draw...",
14071 *
const ImageEditMenu[] =
14082 "Region of Interest...",
14085 *
const MiscellanyMenu[] =
14097 *
const HelpMenu[] =
14100 "Browse Documentation",
14104 *
const ShortCutsMenu[] =
14117 *
const VirtualMenu[] =
14127 *
const *Menus[MagickMenus] =
14165 VisualDirectoryCommand,
14179 OriginalSizeCommand,
14186 TransformCommands[] =
14192 RotateRightCommand,
14199 EnhanceCommands[] =
14207 ContrastStretchCommand,
14208 SigmoidalContrastCommand,
14216 EffectsCommands[] =
14220 ReduceNoiseCommand,
14240 CharcoalDrawCommand
14242 ImageEditCommands[] =
14253 RegionOfInterestCommand
14255 MiscellanyCommands[] =
14259 ShowPreviewCommand,
14260 ShowHistogramCommand,
14269 BrowseDocumentationCommand,
14272 ShortCutsCommands[] =
14284 VirtualCommands[] =
14293 *Commands[MagickMenus] =
14303 MiscellanyCommands,
14308 command[MaxTextExtent],
14310 geometry[MaxTextExtent],
14311 resource_name[MaxTextExtent];
14338 working_directory[MaxTextExtent];
14344 *magick_windows[MaxXWindows];
14346 static unsigned int
14406 assert(image != (
Image **) NULL);
14407 assert((*image)->signature == MagickCoreSignature);
14408 if (IsEventLogging() != MagickFalse)
14409 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",(*image)->filename);
14410 display_image=(*image);
14411 warning_handler=(WarningHandler) NULL;
14412 windows=XSetWindows((XWindows *) ~0);
14413 if (windows != (XWindows *) NULL)
14418 if (*working_directory ==
'\0')
14419 (void) CopyMagickString(working_directory,
".",MaxTextExtent);
14420 status=chdir(working_directory);
14422 (void) ThrowMagickException(&(*image)->exception,GetMagickModule(),
14423 FileOpenError,
"UnableToOpenFile",
"%s",working_directory);
14424 warning_handler=resource_info->display_warnings ?
14425 SetErrorHandler(XWarning) : SetErrorHandler((ErrorHandler) NULL);
14426 warning_handler=resource_info->display_warnings ?
14427 SetWarningHandler(XWarning) : SetWarningHandler((WarningHandler) NULL);
14434 resource_info->colors=display_image->colors;
14435 windows=XSetWindows(XInitializeWindows(display,resource_info));
14436 if (windows == (XWindows *) NULL)
14437 ThrowXWindowFatalException(XServerFatalError,
"UnableToCreateWindow",
14438 (*image)->filename);
14443 magick_windows[number_windows++]=(&windows->icon);
14444 magick_windows[number_windows++]=(&windows->backdrop);
14445 magick_windows[number_windows++]=(&windows->image);
14446 magick_windows[number_windows++]=(&windows->info);
14447 magick_windows[number_windows++]=(&windows->command);
14448 magick_windows[number_windows++]=(&windows->widget);
14449 magick_windows[number_windows++]=(&windows->popup);
14450 magick_windows[number_windows++]=(&windows->magnify);
14451 magick_windows[number_windows++]=(&windows->pan);
14452 for (i=0; i < (int) number_windows; i++)
14453 magick_windows[i]->
id=(Window) NULL;
14460 if (windows->font_info != (XFontStruct *) NULL)
14461 (
void) XFreeFont(display,windows->font_info);
14462 windows->font_info=XBestFont(display,resource_info,MagickFalse);
14463 if (windows->font_info == (XFontStruct *) NULL)
14464 ThrowXWindowFatalException(XServerFatalError,
"UnableToLoadFont",
14465 resource_info->font);
14469 map_info=windows->map_info;
14470 icon_map=windows->icon_map;
14471 visual_info=windows->visual_info;
14472 icon_visual=windows->icon_visual;
14473 pixel=windows->pixel_info;
14474 icon_pixel=windows->icon_pixel;
14475 font_info=windows->font_info;
14476 icon_resources=windows->icon_resources;
14477 class_hints=windows->class_hints;
14478 manager_hints=windows->manager_hints;
14479 root_window=XRootWindow(display,visual_info->screen);
14480 nexus=NewImageList();
14481 if (resource_info->debug != MagickFalse)
14483 (void) LogMagickEvent(X11Event,GetMagickModule(),
14484 "Image: %s[%.20g] %.20gx%.20g ",display_image->filename,
14485 (double) display_image->scene,(
double) display_image->columns,
14486 (double) display_image->rows);
14487 if (display_image->colors != 0)
14488 (void) LogMagickEvent(X11Event,GetMagickModule(),
"%.20gc ",(double)
14489 display_image->colors);
14490 (void) LogMagickEvent(X11Event,GetMagickModule(),
"%s",
14491 display_image->magick);
14493 XMakeStandardColormap(display,visual_info,resource_info,display_image,
14495 display_image->taint=MagickFalse;
14499 windows->context.id=(Window) NULL;
14500 XGetWindowInfo(display,visual_info,map_info,pixel,font_info,
14501 resource_info,&windows->context);
14502 (void) CloneString(&class_hints->res_name,resource_info->client_name);
14503 (void) CloneString(&class_hints->res_class,resource_info->client_name);
14504 class_hints->res_class[0]=(char) LocaleToUppercase((
int)
14505 class_hints->res_class[0]);
14506 manager_hints->flags=InputHint | StateHint;
14507 manager_hints->input=MagickFalse;
14508 manager_hints->initial_state=WithdrawnState;
14509 XMakeWindow(display,root_window,argv,argc,class_hints,manager_hints,
14510 &windows->context);
14511 if (resource_info->debug != MagickFalse)
14512 (void) LogMagickEvent(X11Event,GetMagickModule(),
14513 "Window id: 0x%lx (context)",windows->context.id);
14514 context_values.background=pixel->background_color.pixel;
14515 context_values.font=font_info->fid;
14516 context_values.foreground=pixel->foreground_color.pixel;
14517 context_values.graphics_exposures=MagickFalse;
14518 context_mask=(MagickStatusType)
14519 (GCBackground | GCFont | GCForeground | GCGraphicsExposures);
14520 if (pixel->annotate_context != (GC) NULL)
14521 (
void) XFreeGC(display,pixel->annotate_context);
14522 pixel->annotate_context=XCreateGC(display,windows->context.id,
14523 context_mask,&context_values);
14524 if (pixel->annotate_context == (GC) NULL)
14525 ThrowXWindowFatalException(XServerFatalError,
"UnableToCreateGraphicContext",
14526 display_image->filename);
14527 context_values.background=pixel->depth_color.pixel;
14528 if (pixel->widget_context != (GC) NULL)
14529 (void) XFreeGC(display,pixel->widget_context);
14530 pixel->widget_context=XCreateGC(display,windows->context.id,context_mask,
14532 if (pixel->widget_context == (GC) NULL)
14533 ThrowXWindowFatalException(XServerFatalError,
"UnableToCreateGraphicContext",
14534 display_image->filename);
14535 context_values.background=pixel->foreground_color.pixel;
14536 context_values.foreground=pixel->background_color.pixel;
14537 context_values.plane_mask=context_values.background ^
14538 context_values.foreground;
14539 if (pixel->highlight_context != (GC) NULL)
14540 (void) XFreeGC(display,pixel->highlight_context);
14541 pixel->highlight_context=XCreateGC(display,windows->context.id,
14542 (
size_t) (context_mask | GCPlaneMask),&context_values);
14543 if (pixel->highlight_context == (GC) NULL)
14544 ThrowXWindowFatalException(XServerFatalError,
"UnableToCreateGraphicContext",
14545 display_image->filename);
14546 (void) XDestroyWindow(display,windows->context.id);
14550 XGetWindowInfo(display,icon_visual,icon_map,icon_pixel,(XFontStruct *) NULL,
14551 icon_resources,&windows->icon);
14552 windows->icon.geometry=resource_info->icon_geometry;
14553 XBestIconSize(display,&windows->icon,display_image);
14554 windows->icon.attributes.colormap=XDefaultColormap(display,
14555 icon_visual->screen);
14556 windows->icon.attributes.event_mask=ExposureMask | StructureNotifyMask;
14557 manager_hints->flags=InputHint | StateHint;
14558 manager_hints->input=MagickFalse;
14559 manager_hints->initial_state=IconicState;
14560 XMakeWindow(display,root_window,argv,argc,class_hints,manager_hints,
14562 if (resource_info->debug != MagickFalse)
14563 (void) LogMagickEvent(X11Event,GetMagickModule(),
"Window id: 0x%lx (icon)",
14568 if (icon_pixel->annotate_context != (GC) NULL)
14569 (
void) XFreeGC(display,icon_pixel->annotate_context);
14570 context_values.background=icon_pixel->background_color.pixel;
14571 context_values.foreground=icon_pixel->foreground_color.pixel;
14572 icon_pixel->annotate_context=XCreateGC(display,windows->icon.id,
14573 (
size_t) (GCBackground | GCForeground),&context_values);
14574 if (icon_pixel->annotate_context == (GC) NULL)
14575 ThrowXWindowFatalException(XServerFatalError,
"UnableToCreateGraphicContext",
14576 display_image->filename);
14577 windows->icon.annotate_context=icon_pixel->annotate_context;
14581 XGetWindowInfo(display,visual_info,map_info,pixel,font_info,resource_info,
14583 windows->image.shape=MagickTrue;
14584 if (resource_info->use_shared_memory == MagickFalse)
14585 windows->image.shared_memory=MagickFalse;
14586 if ((resource_info->title != (
char *) NULL) && !(*state & MontageImageState))
14591 title=InterpretImageProperties(resource_info->image_info,display_image,
14592 resource_info->title);
14593 (void) CloneString(&windows->image.name,title);
14594 (void) CloneString(&windows->image.icon_name,title);
14595 title=DestroyString(title);
14600 filename[MaxTextExtent],
14601 window_name[MaxTextExtent];
14606 GetPathComponent(display_image->magick_filename,TailPath,filename);
14607 if (display_image->scene == 0)
14608 (void) FormatLocaleString(window_name,MaxTextExtent,
"%s: %s",
14609 MagickPackageName,filename);
14611 (
void) FormatLocaleString(window_name,MaxTextExtent,
14612 "%s: %s[scene: %.20g frames: %.20g]",MagickPackageName,filename,
14613 (
double) display_image->scene,(
double) GetImageListLength(
14615 (void) CloneString(&windows->image.name,window_name);
14616 (void) CloneString(&windows->image.icon_name,filename);
14618 if (resource_info->immutable)
14619 windows->image.immutable=MagickTrue;
14620 windows->image.use_pixmap=resource_info->use_pixmap;
14621 windows->image.geometry=resource_info->image_geometry;
14622 (void) FormatLocaleString(geometry,MaxTextExtent,
"%ux%u+0+0>!",
14623 XDisplayWidth(display,visual_info->screen),
14624 XDisplayHeight(display,visual_info->screen));
14625 geometry_info.width=display_image->columns;
14626 geometry_info.height=display_image->rows;
14629 (void) ParseMetaGeometry(geometry,&geometry_info.x,&geometry_info.y,
14630 &geometry_info.width,&geometry_info.height);
14631 windows->image.width=(
unsigned int) geometry_info.width;
14632 windows->image.height=(
unsigned int) geometry_info.height;
14633 windows->image.attributes.event_mask=ButtonMotionMask | ButtonPressMask |
14634 ButtonReleaseMask | EnterWindowMask | ExposureMask | KeyPressMask |
14635 KeyReleaseMask | LeaveWindowMask | OwnerGrabButtonMask |
14636 PropertyChangeMask | StructureNotifyMask | SubstructureNotifyMask;
14637 XGetWindowInfo(display,visual_info,map_info,pixel,font_info,
14638 resource_info,&windows->backdrop);
14639 if ((resource_info->backdrop) || (windows->backdrop.id != (Window) NULL))
14644 windows->backdrop.x=0;
14645 windows->backdrop.y=0;
14646 (void) CloneString(&windows->backdrop.name,
"Backdrop");
14647 windows->backdrop.flags=(size_t) (USSize | USPosition);
14648 windows->backdrop.width=(
unsigned int)
14649 XDisplayWidth(display,visual_info->screen);
14650 windows->backdrop.height=(
unsigned int)
14651 XDisplayHeight(display,visual_info->screen);
14652 windows->backdrop.border_width=0;
14653 windows->backdrop.immutable=MagickTrue;
14654 windows->backdrop.attributes.do_not_propagate_mask=ButtonPressMask |
14656 windows->backdrop.attributes.event_mask=ButtonPressMask | KeyPressMask |
14657 StructureNotifyMask;
14658 manager_hints->flags=IconWindowHint | InputHint | StateHint;
14659 manager_hints->icon_window=windows->icon.id;
14660 manager_hints->input=MagickTrue;
14661 manager_hints->initial_state=resource_info->iconic ? IconicState :
14663 XMakeWindow(display,root_window,argv,argc,class_hints,manager_hints,
14664 &windows->backdrop);
14665 if (resource_info->debug != MagickFalse)
14666 (void) LogMagickEvent(X11Event,GetMagickModule(),
14667 "Window id: 0x%lx (backdrop)",windows->backdrop.id);
14668 (void) XMapWindow(display,windows->backdrop.id);
14669 (void) XClearWindow(display,windows->backdrop.id);
14670 if (windows->image.id != (Window) NULL)
14672 (void) XDestroyWindow(display,windows->image.id);
14673 windows->image.id=(Window) NULL;
14678 windows->image.flags|=USPosition;
14679 windows->image.x=(XDisplayWidth(display,visual_info->screen)/2)-
14680 (windows->image.width/2);
14681 windows->image.y=(XDisplayHeight(display,visual_info->screen)/2)-
14682 (windows->image.height/2);
14684 manager_hints->flags=IconWindowHint | InputHint | StateHint;
14685 manager_hints->icon_window=windows->icon.id;
14686 manager_hints->input=MagickTrue;
14687 manager_hints->initial_state=resource_info->iconic ? IconicState :
14689 if (windows->group_leader.id != (Window) NULL)
14694 manager_hints->flags|=WindowGroupHint;
14695 manager_hints->window_group=windows->group_leader.id;
14696 (void) XSelectInput(display,windows->group_leader.id,StructureNotifyMask);
14697 if (resource_info->debug != MagickFalse)
14698 (void) LogMagickEvent(X11Event,GetMagickModule(),
14699 "Window id: 0x%lx (group leader)",windows->group_leader.id);
14701 XMakeWindow(display,
14702 (Window) (resource_info->backdrop ? windows->backdrop.id : root_window),
14703 argv,argc,class_hints,manager_hints,&windows->image);
14704 (void) XChangeProperty(display,windows->image.id,windows->im_protocols,
14705 XA_STRING,8,PropModeReplace,(
unsigned char *) NULL,0);
14706 if (windows->group_leader.id != (Window) NULL)
14707 (
void) XSetTransientForHint(display,windows->image.id,
14708 windows->group_leader.id);
14709 if (resource_info->debug != MagickFalse)
14710 (void) LogMagickEvent(X11Event,GetMagickModule(),
"Window id: 0x%lx (image)",
14711 windows->image.id);
14715 XGetWindowInfo(display,visual_info,map_info,pixel,font_info,resource_info,
14717 (void) CloneString(&windows->info.name,
"Info");
14718 (void) CloneString(&windows->info.icon_name,
"Info");
14719 windows->info.border_width=1;
14722 windows->info.flags|=PPosition;
14723 windows->info.attributes.win_gravity=UnmapGravity;
14724 windows->info.attributes.event_mask=ButtonPressMask | ExposureMask |
14725 StructureNotifyMask;
14726 manager_hints->flags=InputHint | StateHint | WindowGroupHint;
14727 manager_hints->input=MagickFalse;
14728 manager_hints->initial_state=NormalState;
14729 manager_hints->window_group=windows->image.id;
14730 XMakeWindow(display,windows->image.id,argv,argc,class_hints,manager_hints,
14732 windows->info.highlight_stipple=XCreateBitmapFromData(display,
14733 windows->info.id,(
char *) HighlightBitmap,HighlightWidth,HighlightHeight);
14734 windows->info.shadow_stipple=XCreateBitmapFromData(display,
14735 windows->info.id,(
char *) ShadowBitmap,ShadowWidth,ShadowHeight);
14736 (void) XSetTransientForHint(display,windows->info.id,windows->image.id);
14737 if (windows->image.mapped != MagickFalse)
14738 (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
14739 if (resource_info->debug != MagickFalse)
14740 (void) LogMagickEvent(X11Event,GetMagickModule(),
"Window id: 0x%lx (info)",
14745 XGetWindowInfo(display,visual_info,map_info,pixel,font_info,
14746 resource_info,&windows->command);
14747 windows->command.data=MagickMenus;
14748 (void) XCommandWidget(display,windows,CommandMenu,(XEvent *) NULL);
14749 (void) FormatLocaleString(resource_name,MaxTextExtent,
"%s.command",
14750 resource_info->client_name);
14751 windows->command.geometry=XGetResourceClass(resource_info->resource_database,
14752 resource_name,
"geometry",(
char *) NULL);
14753 (void) CloneString(&windows->command.name,MagickTitle);
14754 windows->command.border_width=0;
14755 windows->command.flags|=PPosition;
14756 windows->command.attributes.event_mask=ButtonMotionMask | ButtonPressMask |
14757 ButtonReleaseMask | EnterWindowMask | ExposureMask | LeaveWindowMask |
14758 OwnerGrabButtonMask | StructureNotifyMask;
14759 manager_hints->flags=InputHint | StateHint | WindowGroupHint;
14760 manager_hints->input=MagickTrue;
14761 manager_hints->initial_state=NormalState;
14762 manager_hints->window_group=windows->image.id;
14763 XMakeWindow(display,root_window,argv,argc,class_hints,manager_hints,
14764 &windows->command);
14765 windows->command.highlight_stipple=XCreateBitmapFromData(display,
14766 windows->command.id,(
char *) HighlightBitmap,HighlightWidth,
14768 windows->command.shadow_stipple=XCreateBitmapFromData(display,
14769 windows->command.id,(
char *) ShadowBitmap,ShadowWidth,ShadowHeight);
14770 (void) XSetTransientForHint(display,windows->command.id,windows->image.id);
14771 if (windows->command.mapped != MagickFalse)
14772 (void) XMapRaised(display,windows->command.id);
14773 if (resource_info->debug != MagickFalse)
14774 (void) LogMagickEvent(X11Event,GetMagickModule(),
14775 "Window id: 0x%lx (command)",windows->command.id);
14779 XGetWindowInfo(display,visual_info,map_info,pixel,font_info,
14780 resource_info,&windows->widget);
14781 (void) FormatLocaleString(resource_name,MaxTextExtent,
"%s.widget",
14782 resource_info->client_name);
14783 windows->widget.geometry=XGetResourceClass(resource_info->resource_database,
14784 resource_name,
"geometry",(
char *) NULL);
14785 windows->widget.border_width=0;
14786 windows->widget.flags|=PPosition;
14787 windows->widget.attributes.event_mask=ButtonMotionMask | ButtonPressMask |
14788 ButtonReleaseMask | EnterWindowMask | ExposureMask | KeyPressMask |
14789 KeyReleaseMask | LeaveWindowMask | OwnerGrabButtonMask |
14790 StructureNotifyMask;
14791 manager_hints->flags=InputHint | StateHint | WindowGroupHint;
14792 manager_hints->input=MagickTrue;
14793 manager_hints->initial_state=NormalState;
14794 manager_hints->window_group=windows->image.id;
14795 XMakeWindow(display,root_window,argv,argc,class_hints,manager_hints,
14797 windows->widget.highlight_stipple=XCreateBitmapFromData(display,
14798 windows->widget.id,(
char *) HighlightBitmap,HighlightWidth,HighlightHeight);
14799 windows->widget.shadow_stipple=XCreateBitmapFromData(display,
14800 windows->widget.id,(
char *) ShadowBitmap,ShadowWidth,ShadowHeight);
14801 (void) XSetTransientForHint(display,windows->widget.id,windows->image.id);
14802 if (resource_info->debug != MagickFalse)
14803 (void) LogMagickEvent(X11Event,GetMagickModule(),
14804 "Window id: 0x%lx (widget)",windows->widget.id);
14808 XGetWindowInfo(display,visual_info,map_info,pixel,font_info,
14809 resource_info,&windows->popup);
14810 windows->popup.border_width=0;
14811 windows->popup.flags|=PPosition;
14812 windows->popup.attributes.event_mask=ButtonMotionMask | ButtonPressMask |
14813 ButtonReleaseMask | EnterWindowMask | ExposureMask | KeyPressMask |
14814 KeyReleaseMask | LeaveWindowMask | StructureNotifyMask;
14815 manager_hints->flags=InputHint | StateHint | WindowGroupHint;
14816 manager_hints->input=MagickTrue;
14817 manager_hints->initial_state=NormalState;
14818 manager_hints->window_group=windows->image.id;
14819 XMakeWindow(display,root_window,argv,argc,class_hints,manager_hints,
14821 windows->popup.highlight_stipple=XCreateBitmapFromData(display,
14822 windows->popup.id,(
char *) HighlightBitmap,HighlightWidth,HighlightHeight);
14823 windows->popup.shadow_stipple=XCreateBitmapFromData(display,
14824 windows->popup.id,(
char *) ShadowBitmap,ShadowWidth,ShadowHeight);
14825 (void) XSetTransientForHint(display,windows->popup.id,windows->image.id);
14826 if (resource_info->debug != MagickFalse)
14827 (void) LogMagickEvent(X11Event,GetMagickModule(),
14828 "Window id: 0x%lx (pop up)",windows->popup.id);
14832 XGetWindowInfo(display,visual_info,map_info,pixel,font_info,
14833 resource_info,&windows->magnify);
14834 if (resource_info->use_shared_memory == MagickFalse)
14835 windows->magnify.shared_memory=MagickFalse;
14836 (void) FormatLocaleString(resource_name,MaxTextExtent,
"%s.magnify",
14837 resource_info->client_name);
14838 windows->magnify.geometry=XGetResourceClass(resource_info->resource_database,
14839 resource_name,
"geometry",(
char *) NULL);
14840 (void) FormatLocaleString(windows->magnify.name,MaxTextExtent,
"Magnify %uX",
14841 resource_info->magnify);
14842 if (windows->magnify.cursor != (Cursor) NULL)
14843 (
void) XFreeCursor(display,windows->magnify.cursor);
14844 windows->magnify.cursor=XMakeCursor(display,windows->image.id,
14845 map_info->colormap,resource_info->background_color,
14846 resource_info->foreground_color);
14847 if (windows->magnify.cursor == (Cursor) NULL)
14848 ThrowXWindowFatalException(XServerFatalError,
"UnableToCreateCursor",
14849 display_image->filename);
14850 windows->magnify.width=MagnifySize;
14851 windows->magnify.height=MagnifySize;
14852 windows->magnify.flags|=PPosition;
14853 windows->magnify.min_width=MagnifySize;
14854 windows->magnify.min_height=MagnifySize;
14855 windows->magnify.width_inc=MagnifySize;
14856 windows->magnify.height_inc=MagnifySize;
14857 windows->magnify.data=resource_info->magnify;
14858 windows->magnify.attributes.cursor=windows->magnify.cursor;
14859 windows->magnify.attributes.event_mask=ButtonPressMask | ButtonReleaseMask |
14860 ExposureMask | KeyPressMask | KeyReleaseMask | OwnerGrabButtonMask |
14861 StructureNotifyMask;
14862 manager_hints->flags=InputHint | StateHint | WindowGroupHint;
14863 manager_hints->input=MagickTrue;
14864 manager_hints->initial_state=NormalState;
14865 manager_hints->window_group=windows->image.id;
14866 XMakeWindow(display,root_window,argv,argc,class_hints,manager_hints,
14867 &windows->magnify);
14868 if (resource_info->debug != MagickFalse)
14869 (void) LogMagickEvent(X11Event,GetMagickModule(),
14870 "Window id: 0x%lx (magnify)",windows->magnify.id);
14871 (void) XSetTransientForHint(display,windows->magnify.id,windows->image.id);
14875 XGetWindowInfo(display,visual_info,map_info,pixel,font_info,
14876 resource_info,&windows->pan);
14877 (void) CloneString(&windows->pan.name,
"Pan Icon");
14878 windows->pan.width=windows->icon.width;
14879 windows->pan.height=windows->icon.height;
14880 (void) FormatLocaleString(resource_name,MaxTextExtent,
"%s.pan",
14881 resource_info->client_name);
14882 windows->pan.geometry=XGetResourceClass(resource_info->resource_database,
14883 resource_name,
"geometry",(
char *) NULL);
14884 (void) XParseGeometry(windows->pan.geometry,&windows->pan.x,&windows->pan.y,
14885 &windows->pan.width,&windows->pan.height);
14886 windows->pan.flags|=PPosition;
14887 windows->pan.immutable=MagickTrue;
14888 windows->pan.attributes.event_mask=ButtonMotionMask | ButtonPressMask |
14889 ButtonReleaseMask | ExposureMask | KeyPressMask | KeyReleaseMask |
14890 StructureNotifyMask;
14891 manager_hints->flags=InputHint | StateHint | WindowGroupHint;
14892 manager_hints->input=MagickFalse;
14893 manager_hints->initial_state=NormalState;
14894 manager_hints->window_group=windows->image.id;
14895 XMakeWindow(display,root_window,argv,argc,class_hints,manager_hints,
14897 if (resource_info->debug != MagickFalse)
14898 (void) LogMagickEvent(X11Event,GetMagickModule(),
"Window id: 0x%lx (pan)",
14900 (void) XSetTransientForHint(display,windows->pan.id,windows->image.id);
14901 if (windows->info.mapped != MagickFalse)
14902 (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
14903 if ((windows->image.mapped == MagickFalse) ||
14904 (windows->backdrop.id != (Window) NULL))
14905 (
void) XMapWindow(display,windows->image.id);
14909 if (warning_handler == (WarningHandler) NULL)
14911 warning_handler=resource_info->display_warnings ?
14912 SetErrorHandler(XWarning) : SetErrorHandler((ErrorHandler) NULL);
14913 warning_handler=resource_info->display_warnings ?
14914 SetWarningHandler(XWarning) : SetWarningHandler((WarningHandler) NULL);
14919 windows->image.x=0;
14920 windows->image.y=0;
14921 windows->magnify.shape=MagickFalse;
14922 width=(
unsigned int) display_image->columns;
14923 height=(
unsigned int) display_image->rows;
14924 if ((display_image->columns != width) || (display_image->rows != height))
14925 ThrowXWindowFatalException(XServerFatalError,
"UnableToCreateXImage",
14926 display_image->filename);
14927 status=XMakeImage(display,resource_info,&windows->image,display_image,
14929 if (status == MagickFalse)
14930 ThrowXWindowFatalException(XServerFatalError,
"UnableToCreateXImage",
14931 display_image->filename);
14932 status=XMakeImage(display,resource_info,&windows->magnify,(
Image *) NULL,
14933 windows->magnify.width,windows->magnify.height);
14934 if (status == MagickFalse)
14935 ThrowXWindowFatalException(XServerFatalError,
"UnableToCreateXImage",
14936 display_image->filename);
14937 if (windows->magnify.mapped != MagickFalse)
14938 (void) XMapRaised(display,windows->magnify.id);
14939 if (windows->pan.mapped != MagickFalse)
14940 (void) XMapRaised(display,windows->pan.id);
14941 windows->image.window_changes.width=(int) display_image->columns;
14942 windows->image.window_changes.height=(
int) display_image->rows;
14943 (void) XConfigureImage(display,resource_info,windows,display_image);
14944 (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
14945 (void) XSync(display,MagickFalse);
14949 delay=display_image->delay/MagickMax(display_image->ticks_per_second,1L);
14950 timer=GetMagickTime()+(delay == 0 ? 1 : delay)+1;
14952 if (resource_info->update != MagickFalse)
14960 status=GetPathAttributes(display_image->filename,&attributes);
14961 if (status != MagickFalse)
14962 update_time=attributes.st_mtime;
14964 *state&=(~FormerImageState);
14965 *state&=(~MontageImageState);
14966 *state&=(~NextImageState);
14972 if (windows->image.mapped != MagickFalse)
14973 if ((display_image->delay != 0) || (resource_info->update != 0))
14975 if (timer < GetMagickTime())
14977 if (resource_info->update == MagickFalse)
14978 *state|=NextImageState | ExitState;
14987 status=GetPathAttributes(display_image->filename,&attributes);
14988 if (status != MagickFalse)
14989 if (update_time != attributes.st_mtime)
14994 (void) FormatLocaleString(
14995 resource_info->image_info->filename,MaxTextExtent,
14996 "%s:%s",display_image->magick,
14997 display_image->filename);
14998 nexus=ReadImage(resource_info->image_info,
14999 &display_image->exception);
15000 if (nexus != (
Image *) NULL)
15001 *state|=NextImageState | ExitState;
15003 delay=display_image->delay/MagickMax(
15004 display_image->ticks_per_second,1L);
15005 timer=GetMagickTime()+(delay == 0 ? 1 : delay)+1;
15008 if (XEventsQueued(display,QueuedAfterFlush) == 0)
15013 XDelay(display,SuspendTime << 2);
15017 timestamp=GetMagickTime();
15018 (void) XNextEvent(display,&event);
15019 if (windows->image.stasis == MagickFalse)
15020 windows->image.stasis=(GetMagickTime()-timestamp) > 0 ?
15021 MagickTrue : MagickFalse;
15022 if (windows->magnify.stasis == MagickFalse)
15023 windows->magnify.stasis=(GetMagickTime()-timestamp) > 0 ?
15024 MagickTrue : MagickFalse;
15025 if (event.xany.window == windows->command.id)
15030 id=XCommandWidget(display,windows,CommandMenu,&event);
15033 (void) CopyMagickString(command,CommandMenu[
id],MaxTextExtent);
15034 command_type=CommandMenus[id];
15035 if (
id < MagickMenus)
15040 entry=XMenuWidget(display,windows,CommandMenu[
id],Menus[
id],
15044 (void) CopyMagickString(command,Menus[
id][entry],MaxTextExtent);
15045 command_type=Commands[id][entry];
15047 if (command_type != NullCommand)
15048 nexus=XMagickCommand(display,resource_info,windows,command_type,
15052 switch (event.type)
15056 if (resource_info->debug != MagickFalse)
15057 (void) LogMagickEvent(X11Event,GetMagickModule(),
15058 "Button Press: 0x%lx %u +%d+%d",
event.xbutton.window,
15059 event.xbutton.button,
event.xbutton.x,
event.xbutton.y);
15060 if ((event.xbutton.button == Button3) &&
15061 (
event.xbutton.state & Mod1Mask))
15066 event.xbutton.button=Button2;
15067 event.xbutton.state&=(~Mod1Mask);
15069 if (event.xbutton.window == windows->backdrop.id)
15071 (void) XSetInputFocus(display,event.xbutton.window,RevertToParent,
15072 event.xbutton.time);
15075 if (event.xbutton.window == windows->image.id)
15077 switch (event.xbutton.button)
15081 if (resource_info->immutable)
15086 entry=XMenuWidget(display,windows,
"Commands",VirtualMenu,
15089 nexus=XMagickCommand(display,resource_info,windows,
15090 VirtualCommands[entry],&display_image);
15096 if (windows->command.mapped != MagickFalse)
15097 (void) XWithdrawWindow(display,windows->command.id,
15098 windows->command.screen);
15101 (void) XCommandWidget(display,windows,CommandMenu,
15103 (void) XMapRaised(display,windows->command.id);
15112 (void) XMagickCommand(display,resource_info,windows,ZoomCommand,
15114 XMagnifyImage(display,windows,&event);
15119 if (resource_info->immutable)
15124 entry=XMenuWidget(display,windows,
"Commands",VirtualMenu,
15127 nexus=XMagickCommand(display,resource_info,windows,
15128 VirtualCommands[entry],&display_image);
15131 if (display_image->montage != (
char *) NULL)
15136 nexus=XTileImage(display,resource_info,windows,
15137 display_image,&event);
15138 if (nexus != (
Image *) NULL)
15139 *state|=MontageImageState | NextImageState | ExitState;
15140 vid_info.x=(
short int) windows->image.x;
15141 vid_info.y=(
short int) windows->image.y;
15147 entry=XMenuWidget(display,windows,
"Short Cuts",ShortCutsMenu,
15150 nexus=XMagickCommand(display,resource_info,windows,
15151 ShortCutsCommands[entry],&display_image);
15159 XTranslateImage(display,windows,*image,XK_Up);
15167 XTranslateImage(display,windows,*image,XK_Down);
15175 if (event.xbutton.window == windows->magnify.id)
15178 *
const MagnifyMenu[] =
15195 MagnifyCommands[] =
15210 factor=XMenuWidget(display,windows,
"Magnify",MagnifyMenu,command);
15212 XMagnifyWindowCommand(display,windows,0,MagnifyCommands[factor]);
15215 if (event.xbutton.window == windows->pan.id)
15217 switch (event.xbutton.button)
15224 XTranslateImage(display,windows,*image,XK_Up);
15232 XTranslateImage(display,windows,*image,XK_Down);
15237 XPanImage(display,windows,&event);
15243 delay=display_image->delay/MagickMax(display_image->ticks_per_second,
15245 timer=GetMagickTime()+(delay == 0 ? 1 : delay)+1;
15248 case ButtonRelease:
15250 if (resource_info->debug != MagickFalse)
15251 (void) LogMagickEvent(X11Event,GetMagickModule(),
15252 "Button Release: 0x%lx %u +%d+%d",
event.xbutton.window,
15253 event.xbutton.button,
event.xbutton.x,
event.xbutton.y);
15256 case ClientMessage:
15258 if (resource_info->debug != MagickFalse)
15259 (void) LogMagickEvent(X11Event,GetMagickModule(),
15260 "Client Message: 0x%lx 0x%lx %d 0x%lx",
event.xclient.window,
15261 event.xclient.message_type,
event.xclient.format,(
unsigned long)
15262 event.xclient.data.l[0]);
15263 if (event.xclient.message_type == windows->im_protocols)
15265 if (*event.xclient.data.l == (
long) windows->im_update_widget)
15267 (void) CloneString(&windows->command.name,MagickTitle);
15268 windows->command.data=MagickMenus;
15269 (void) XCommandWidget(display,windows,CommandMenu,
15273 if (*event.xclient.data.l == (
long) windows->im_update_colormap)
15278 for (i=0; i < (int) number_windows; i++)
15280 if (magick_windows[i]->
id == windows->icon.id)
15282 context_values.background=pixel->background_color.pixel;
15283 context_values.foreground=pixel->foreground_color.pixel;
15284 (void) XChangeGC(display,magick_windows[i]->annotate_context,
15285 context_mask,&context_values);
15286 (void) XChangeGC(display,magick_windows[i]->widget_context,
15287 context_mask,&context_values);
15288 context_values.background=pixel->foreground_color.pixel;
15289 context_values.foreground=pixel->background_color.pixel;
15290 context_values.plane_mask=context_values.background ^
15291 context_values.foreground;
15292 (void) XChangeGC(display,magick_windows[i]->highlight_context,
15293 (
size_t) (context_mask | GCPlaneMask),
15295 magick_windows[i]->attributes.background_pixel=
15296 pixel->background_color.pixel;
15297 magick_windows[i]->attributes.border_pixel=
15298 pixel->border_color.pixel;
15299 magick_windows[i]->attributes.colormap=map_info->colormap;
15300 (void) XChangeWindowAttributes(display,magick_windows[i]->
id,
15301 (
unsigned long) magick_windows[i]->mask,
15302 &magick_windows[i]->attributes);
15304 if (windows->pan.mapped != MagickFalse)
15306 (void) XSetWindowBackgroundPixmap(display,windows->pan.id,
15307 windows->pan.pixmap);
15308 (void) XClearWindow(display,windows->pan.id);
15309 XDrawPanRectangle(display,windows);
15311 if (windows->backdrop.id != (Window) NULL)
15312 (void) XInstallColormap(display,map_info->colormap);
15315 if (*event.xclient.data.l == (
long) windows->im_former_image)
15317 *state|=FormerImageState | ExitState;
15320 if (*event.xclient.data.l == (
long) windows->im_next_image)
15322 *state|=NextImageState | ExitState;
15325 if (*event.xclient.data.l == (
long) windows->im_retain_colors)
15327 *state|=RetainColorsState;
15330 if (*event.xclient.data.l == (
long) windows->im_exit)
15337 if (event.xclient.message_type == windows->dnd_protocols)
15357 if ((*event.xclient.data.l != 2) && (*
event.xclient.data.l != 128))
15359 selection=XInternAtom(display,
"DndSelection",MagickFalse);
15360 status=XGetWindowProperty(display,root_window,selection,0L,(
long)
15361 MaxTextExtent,MagickFalse,(Atom) AnyPropertyType,&type,&format,
15362 &length,&after,&data);
15363 if ((status != Success) || (length == 0))
15365 if (*event.xclient.data.l == 2)
15370 (void) CopyMagickString(resource_info->image_info->filename,
15371 (
char *) data,MaxTextExtent);
15378 if (strncmp((
char *) data,
"file:", 5) != 0)
15380 (void) XFree((
void *) data);
15383 (void) CopyMagickString(resource_info->image_info->filename,
15384 ((
char *) data)+5,MaxTextExtent);
15386 nexus=ReadImage(resource_info->image_info,
15387 &display_image->exception);
15388 CatchException(&display_image->exception);
15389 if (nexus != (
Image *) NULL)
15390 *state|=NextImageState | ExitState;
15391 (void) XFree((
void *) data);
15397 if (event.xclient.message_type != windows->wm_protocols)
15399 if (*event.xclient.data.l != (
long) windows->wm_delete_window)
15401 (void) XWithdrawWindow(display,event.xclient.window,
15402 visual_info->screen);
15403 if (event.xclient.window == windows->image.id)
15408 if (event.xclient.window == windows->pan.id)
15413 windows->image.window_changes.width=windows->image.ximage->width;
15414 windows->image.window_changes.height=windows->image.ximage->height;
15415 (void) XConfigureImage(display,resource_info,windows,
15420 case ConfigureNotify:
15422 if (resource_info->debug != MagickFalse)
15423 (void) LogMagickEvent(X11Event,GetMagickModule(),
15424 "Configure Notify: 0x%lx %dx%d+%d+%d %d",
event.xconfigure.window,
15425 event.xconfigure.width,
event.xconfigure.height,
event.xconfigure.x,
15426 event.xconfigure.y,
event.xconfigure.send_event);
15427 if (event.xconfigure.window == windows->image.id)
15432 if (event.xconfigure.send_event != 0)
15440 if (windows->command.geometry == (
char *) NULL)
15441 if (windows->command.mapped == MagickFalse)
15443 windows->command.x=
event.xconfigure.x-
15444 windows->command.width-25;
15445 windows->command.y=
event.xconfigure.y;
15446 XConstrainWindowPosition(display,&windows->command);
15447 window_changes.x=windows->command.x;
15448 window_changes.y=windows->command.y;
15449 (void) XReconfigureWMWindow(display,windows->command.id,
15450 windows->command.screen,(
unsigned int) (CWX | CWY),
15453 if (windows->widget.geometry == (
char *) NULL)
15454 if (windows->widget.mapped == MagickFalse)
15456 windows->widget.x=
event.xconfigure.x+
15457 event.xconfigure.width/10;
15458 windows->widget.y=
event.xconfigure.y+
15459 event.xconfigure.height/10;
15460 XConstrainWindowPosition(display,&windows->widget);
15461 window_changes.x=windows->widget.x;
15462 window_changes.y=windows->widget.y;
15463 (void) XReconfigureWMWindow(display,windows->widget.id,
15464 windows->widget.screen,(
unsigned int) (CWX | CWY),
15467 if (windows->magnify.geometry == (
char *) NULL)
15468 if (windows->magnify.mapped == MagickFalse)
15470 windows->magnify.x=
event.xconfigure.x+
15471 event.xconfigure.width+25;
15472 windows->magnify.y=
event.xconfigure.y;
15473 XConstrainWindowPosition(display,&windows->magnify);
15474 window_changes.x=windows->magnify.x;
15475 window_changes.y=windows->magnify.y;
15476 (void) XReconfigureWMWindow(display,windows->magnify.id,
15477 windows->magnify.screen,(
unsigned int) (CWX | CWY),
15480 if (windows->pan.geometry == (
char *) NULL)
15481 if (windows->pan.mapped == MagickFalse)
15483 windows->pan.x=
event.xconfigure.x+
15484 event.xconfigure.width+25;
15485 windows->pan.y=
event.xconfigure.y+
15486 windows->magnify.height+50;
15487 XConstrainWindowPosition(display,&windows->pan);
15488 window_changes.x=windows->pan.x;
15489 window_changes.y=windows->pan.y;
15490 (void) XReconfigureWMWindow(display,windows->pan.id,
15491 windows->pan.screen,(
unsigned int) (CWX | CWY),
15495 if ((event.xconfigure.width == (
int) windows->image.width) &&
15496 (event.xconfigure.height == (
int) windows->image.height))
15498 windows->image.width=(
unsigned int) event.xconfigure.width;
15499 windows->image.height=(
unsigned int)
event.xconfigure.height;
15500 windows->image.x=0;
15501 windows->image.y=0;
15502 if (display_image->montage != (
char *) NULL)
15504 windows->image.x=vid_info.x;
15505 windows->image.y=vid_info.y;
15507 if ((windows->image.mapped != MagickFalse) &&
15508 (windows->image.stasis != MagickFalse))
15513 windows->image.window_changes.width=
event.xconfigure.width;
15514 windows->image.window_changes.height=
event.xconfigure.height;
15515 (void) XConfigureImage(display,resource_info,windows,
15521 if ((event.xconfigure.width < windows->image.ximage->width) ||
15522 (
event.xconfigure.height < windows->image.ximage->height))
15524 (void) XMapRaised(display,windows->pan.id);
15525 XDrawPanRectangle(display,windows);
15528 if (windows->pan.mapped != MagickFalse)
15529 (void) XWithdrawWindow(display,windows->pan.id,
15530 windows->pan.screen);
15533 if (event.xconfigure.window == windows->magnify.id)
15541 windows->magnify.width=(
unsigned int) event.xconfigure.width;
15542 windows->magnify.height=(
unsigned int)
event.xconfigure.height;
15543 if (windows->magnify.mapped == MagickFalse)
15546 while ((
int) magnify <=
event.xconfigure.width)
15548 while ((
int) magnify <=
event.xconfigure.height)
15551 if (((
int) magnify !=
event.xconfigure.width) ||
15552 ((
int) magnify !=
event.xconfigure.height))
15554 window_changes.width=(int) magnify;
15555 window_changes.height=(int) magnify;
15556 (void) XReconfigureWMWindow(display,windows->magnify.id,
15557 windows->magnify.screen,(
unsigned int) (CWWidth | CWHeight),
15561 if ((windows->magnify.mapped != MagickFalse) &&
15562 (windows->magnify.stasis != MagickFalse))
15564 status=XMakeImage(display,resource_info,&windows->magnify,
15565 display_image,windows->magnify.width,windows->magnify.height);
15566 XMakeMagnifyImage(display,windows);
15570 if ((windows->magnify.mapped != MagickFalse) &&
15571 (event.xconfigure.window == windows->pan.id))
15576 if (event.xconfigure.send_event != 0)
15578 windows->pan.x=
event.xconfigure.x;
15579 windows->pan.y=
event.xconfigure.y;
15581 windows->pan.width=(
unsigned int) event.xconfigure.width;
15582 windows->pan.height=(
unsigned int)
event.xconfigure.height;
15585 if (event.xconfigure.window == windows->icon.id)
15590 windows->icon.width=(
unsigned int) event.xconfigure.width;
15591 windows->icon.height=(
unsigned int)
event.xconfigure.height;
15596 case DestroyNotify:
15601 if (resource_info->debug != MagickFalse)
15602 (void) LogMagickEvent(X11Event,GetMagickModule(),
15603 "Destroy Notify: 0x%lx",
event.xdestroywindow.window);
15604 if (event.xdestroywindow.window == windows->group_leader.id)
15616 if (map_info->colormap != XDefaultColormap(display,visual_info->screen))
15617 if (event.xcrossing.mode != NotifyUngrab)
15618 XInstallColormap(display,map_info->colormap);
15623 if (resource_info->debug != MagickFalse)
15624 (void) LogMagickEvent(X11Event,GetMagickModule(),
15625 "Expose: 0x%lx %dx%d+%d+%d",
event.xexpose.window,
15626 event.xexpose.width,
event.xexpose.height,
event.xexpose.x,
15631 if ((event.xexpose.window == windows->image.id) &&
15632 (windows->image.mapped != MagickFalse))
15634 XRefreshWindow(display,&windows->image,&event);
15635 delay=display_image->delay/MagickMax(
15636 display_image->ticks_per_second,1L);
15637 timer=GetMagickTime()+(delay == 0 ? 1 : delay)+1;
15640 if ((event.xexpose.window == windows->magnify.id) &&
15641 (windows->magnify.mapped != MagickFalse))
15643 XMakeMagnifyImage(display,windows);
15646 if (event.xexpose.window == windows->pan.id)
15648 XDrawPanRectangle(display,windows);
15651 if (event.xexpose.window == windows->icon.id)
15653 XRefreshWindow(display,&windows->icon,&event);
15666 length=XLookupString((XKeyEvent *) &event.xkey,command,(
int)
15667 sizeof(command),&key_symbol,(XComposeStatus *) NULL);
15668 *(command+length)=
'\0';
15669 if (resource_info->debug != MagickFalse)
15670 (void) LogMagickEvent(X11Event,GetMagickModule(),
15671 "Key press: %d 0x%lx (%s)",
event.xkey.state,(
unsigned long)
15672 key_symbol,command);
15673 if (event.xkey.window == windows->image.id)
15675 command_type=XImageWindowCommand(display,resource_info,windows,
15676 event.xkey.state,key_symbol,&display_image);
15677 if (command_type != NullCommand)
15678 nexus=XMagickCommand(display,resource_info,windows,command_type,
15681 if (event.xkey.window == windows->magnify.id)
15682 XMagnifyWindowCommand(display,windows,event.xkey.state,key_symbol);
15683 if (event.xkey.window == windows->pan.id)
15685 if ((key_symbol == XK_q) || (key_symbol == XK_Escape))
15686 (void) XWithdrawWindow(display,windows->pan.id,
15687 windows->pan.screen);
15689 if ((key_symbol == XK_F1) || (key_symbol == XK_Help))
15690 XTextViewHelp(display,resource_info,windows,MagickFalse,
15691 "Help Viewer - Image Pan",ImagePanHelp);
15693 XTranslateImage(display,windows,*image,key_symbol);
15695 delay=display_image->delay/MagickMax(
15696 display_image->ticks_per_second,1L);
15697 timer=GetMagickTime()+(delay == 0 ? 1 : delay)+1;
15705 (void) XLookupString((XKeyEvent *) &
event.xkey,command,(int)
15706 sizeof(command),&key_symbol,(XComposeStatus *) NULL);
15707 if (resource_info->debug != MagickFalse)
15708 (void) LogMagickEvent(X11Event,GetMagickModule(),
15709 "Key release: 0x%lx (%c)",(
unsigned long) key_symbol,*command);
15717 if (map_info->colormap != XDefaultColormap(display,visual_info->screen))
15718 if (event.xcrossing.mode != NotifyUngrab)
15719 XUninstallColormap(display,map_info->colormap);
15724 if (resource_info->debug != MagickFalse)
15725 (void) LogMagickEvent(X11Event,GetMagickModule(),
"Map Notify: 0x%lx",
15726 event.xmap.window);
15727 if (event.xmap.window == windows->backdrop.id)
15729 (void) XSetInputFocus(display,event.xmap.window,RevertToParent,
15731 windows->backdrop.mapped=MagickTrue;
15734 if (event.xmap.window == windows->image.id)
15736 if (windows->backdrop.id != (Window) NULL)
15737 (
void) XInstallColormap(display,map_info->colormap);
15738 if (LocaleCompare(display_image->magick,
"LOGO") == 0)
15740 if (LocaleCompare(display_image->filename,
"LOGO") == 0)
15741 nexus=XOpenImage(display,resource_info,windows,MagickFalse);
15743 if (((
int) windows->image.width < windows->image.ximage->width) ||
15744 ((
int) windows->image.height < windows->image.ximage->height))
15745 (void) XMapRaised(display,windows->pan.id);
15746 windows->image.mapped=MagickTrue;
15749 if (event.xmap.window == windows->magnify.id)
15751 XMakeMagnifyImage(display,windows);
15752 windows->magnify.mapped=MagickTrue;
15753 (void) XWithdrawWindow(display,windows->info.id,
15754 windows->info.screen);
15757 if (event.xmap.window == windows->pan.id)
15759 XMakePanImage(display,resource_info,windows,display_image);
15760 windows->pan.mapped=MagickTrue;
15763 if (event.xmap.window == windows->info.id)
15765 windows->info.mapped=MagickTrue;
15768 if (event.xmap.window == windows->icon.id)
15776 taint=display_image->taint;
15777 XMakeStandardColormap(display,icon_visual,icon_resources,
15778 display_image,icon_map,icon_pixel);
15779 (void) XMakeImage(display,icon_resources,&windows->icon,
15780 display_image,windows->icon.width,windows->icon.height);
15781 display_image->taint=taint;
15782 (void) XSetWindowBackgroundPixmap(display,windows->icon.id,
15783 windows->icon.pixmap);
15784 (void) XClearWindow(display,windows->icon.id);
15785 (void) XWithdrawWindow(display,windows->info.id,
15786 windows->info.screen);
15787 windows->icon.mapped=MagickTrue;
15790 if (event.xmap.window == windows->command.id)
15792 windows->command.mapped=MagickTrue;
15795 if (event.xmap.window == windows->popup.id)
15797 windows->popup.mapped=MagickTrue;
15800 if (event.xmap.window == windows->widget.id)
15802 windows->widget.mapped=MagickTrue;
15807 case MappingNotify:
15809 (void) XRefreshKeyboardMapping(&event.xmapping);
15814 case PropertyNotify:
15830 if (resource_info->debug != MagickFalse)
15831 (void) LogMagickEvent(X11Event,GetMagickModule(),
15832 "Property Notify: 0x%lx 0x%lx %d",
event.xproperty.window,
15833 event.xproperty.atom,
event.xproperty.state);
15834 if (event.xproperty.atom != windows->im_remote_command)
15839 status=XGetWindowProperty(display,event.xproperty.window,
15840 event.xproperty.atom,0L,(
long) MaxTextExtent,MagickFalse,(Atom)
15841 AnyPropertyType,&type,&format,&length,&after,&data);
15842 if ((status != Success) || (length == 0))
15844 if (LocaleCompare((
char *) data,
"-quit") == 0)
15846 XClientMessage(display,windows->image.id,windows->im_protocols,
15847 windows->im_exit,CurrentTime);
15848 (void) XFree((
void *) data);
15851 (void) CopyMagickString(resource_info->image_info->filename,
15852 (
char *) data,MaxTextExtent);
15853 (void) XFree((
void *) data);
15854 nexus=ReadImage(resource_info->image_info,&display_image->exception);
15855 CatchException(&display_image->exception);
15856 if (nexus != (
Image *) NULL)
15857 *state|=NextImageState | ExitState;
15860 case ReparentNotify:
15862 if (resource_info->debug != MagickFalse)
15863 (void) LogMagickEvent(X11Event,GetMagickModule(),
15864 "Reparent Notify: 0x%lx=>0x%lx",
event.xreparent.parent,
15865 event.xreparent.window);
15870 if (resource_info->debug != MagickFalse)
15871 (void) LogMagickEvent(X11Event,GetMagickModule(),
15872 "Unmap Notify: 0x%lx",
event.xunmap.window);
15873 if (event.xunmap.window == windows->backdrop.id)
15875 windows->backdrop.mapped=MagickFalse;
15878 if (event.xunmap.window == windows->image.id)
15880 windows->image.mapped=MagickFalse;
15883 if (event.xunmap.window == windows->magnify.id)
15885 windows->magnify.mapped=MagickFalse;
15888 if (event.xunmap.window == windows->pan.id)
15890 windows->pan.mapped=MagickFalse;
15893 if (event.xunmap.window == windows->info.id)
15895 windows->info.mapped=MagickFalse;
15898 if (event.xunmap.window == windows->icon.id)
15900 if (map_info->colormap == icon_map->colormap)
15901 XConfigureImageColormap(display,resource_info,windows,
15903 (void) XFreeStandardColormap(display,icon_visual,icon_map,
15905 windows->icon.mapped=MagickFalse;
15908 if (event.xunmap.window == windows->command.id)
15910 windows->command.mapped=MagickFalse;
15913 if (event.xunmap.window == windows->popup.id)
15915 if (windows->backdrop.id != (Window) NULL)
15916 (
void) XSetInputFocus(display,windows->image.id,RevertToParent,
15918 windows->popup.mapped=MagickFalse;
15921 if (event.xunmap.window == windows->widget.id)
15923 if (windows->backdrop.id != (Window) NULL)
15924 (void) XSetInputFocus(display,windows->image.id,RevertToParent,
15926 windows->widget.mapped=MagickFalse;
15933 if (resource_info->debug != MagickFalse)
15934 (void) LogMagickEvent(X11Event,GetMagickModule(),
"Event type: %d",
15939 }
while (!(*state & ExitState));
15940 if ((*state & ExitState) == 0)
15941 (
void) XMagickCommand(display,resource_info,windows,FreeBuffersCommand,
15944 if (resource_info->confirm_edit != MagickFalse)
15949 if ((resource_info->immutable == MagickFalse) &&
15950 (display_image->taint != MagickFalse))
15955 status=XConfirmWidget(display,windows,
"Your image changed.",
15956 "Do you want to save it");
15958 *state&=(~ExitState);
15961 (void) XMagickCommand(display,resource_info,windows,SaveCommand,
15965 if ((windows->visual_info->klass == GrayScale) ||
15966 (windows->visual_info->klass == PseudoColor) ||
15967 (windows->visual_info->klass == DirectColor))
15972 if (windows->info.mapped != MagickFalse)
15973 (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
15974 if (windows->magnify.mapped != MagickFalse)
15975 (void) XWithdrawWindow(display,windows->magnify.id,
15976 windows->magnify.screen);
15977 if (windows->command.mapped != MagickFalse)
15978 (void) XWithdrawWindow(display,windows->command.id,
15979 windows->command.screen);
15981 if (windows->pan.mapped != MagickFalse)
15982 (void) XWithdrawWindow(display,windows->pan.id,windows->pan.screen);
15983 if (resource_info->backdrop == MagickFalse)
15984 if (windows->backdrop.mapped)
15986 (void) XWithdrawWindow(display,windows->backdrop.id,
15987 windows->backdrop.screen);
15988 (void) XDestroyWindow(display,windows->backdrop.id);
15989 windows->backdrop.id=(Window) NULL;
15990 (void) XWithdrawWindow(display,windows->image.id,
15991 windows->image.screen);
15992 (void) XDestroyWindow(display,windows->image.id);
15993 windows->image.id=(Window) NULL;
15995 XSetCursorState(display,windows,MagickTrue);
15996 XCheckRefreshWindows(display,windows);
15997 if (((*state & FormerImageState) != 0) || ((*state & NextImageState) != 0))
15998 *state&=(~ExitState);
15999 if (*state & ExitState)
16004 (void) XFreeStandardColormap(display,icon_visual,icon_map,icon_pixel);
16005 if (resource_info->map_type == (
char *) NULL)
16006 (
void) XFreeStandardColormap(display,visual_info,map_info,pixel);
16010 if (resource_info->copy_image != (
Image *) NULL)
16011 resource_info->copy_image=DestroyImage(resource_info->copy_image);
16012 DestroyXResources();
16014 (void) XSync(display,MagickFalse);
16018 (void) SetErrorHandler(warning_handler);
16019 (void) SetWarningHandler(warning_handler);
16023 directory=getcwd(working_directory,MaxTextExtent);
16029 if (*resource_info->home_directory ==
'\0')
16030 (void) CopyMagickString(resource_info->home_directory,
".",MaxTextExtent);
16031 status=chdir(resource_info->home_directory);
16033 (void) ThrowMagickException(&display_image->exception,GetMagickModule(),
16034 FileOpenError,
"UnableToOpenFile",
"%s",resource_info->home_directory);
16036 *image=display_image;
16068 MagickExport MagickBooleanType DisplayImages(
const ImageInfo *image_info,
16071 assert(image_info != (
const ImageInfo *) NULL);
16072 assert(image_info->signature == MagickCoreSignature);
16073 assert(image != (
Image *) NULL);
16074 assert(image->signature == MagickCoreSignature);
16075 if (IsEventLogging() != MagickFalse)
16076 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
16078 (void) ThrowMagickException(&image->exception,GetMagickModule(),
16079 MissingDelegateError,
"DelegateLibrarySupportNotBuiltIn",
"`%s' (X11)",
16081 return(MagickFalse);
16114 MagickExport MagickBooleanType RemoteDisplayCommand(
const ImageInfo *image_info,
16115 const char *window,
const char *filename,
ExceptionInfo *exception)
16117 assert(image_info != (
const ImageInfo *) NULL);
16118 assert(image_info->signature == MagickCoreSignature);
16119 assert(filename != (
char *) NULL);
16120 if (IsEventLogging() != MagickFalse)
16121 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",filename);
16123 (void) ThrowMagickException(exception,GetMagickModule(),MissingDelegateError,
16124 "DelegateLibrarySupportNotBuiltIn",
"`%s' (X11)",image_info->filename);
16125 return(MagickFalse);