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"
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)
108static 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
1490#define WavyHeight 16
1498static 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
1535static DisplayCommand
1536 XImageWindowCommand(Display *,XResourceInfo *,XWindows *,
1537 const MagickStatusType,KeySym,
Image **);
1540 *XMagickCommand(Display *,XResourceInfo *,XWindows *,
const DisplayCommand,
1542 *XOpenImage(Display *,XResourceInfo *,XWindows *,
const MagickBooleanType),
1543 *XTileImage(Display *,XResourceInfo *,XWindows *,
Image *,XEvent *),
1544 *XVisualDirectoryImage(Display *,XResourceInfo *,XWindows *);
1546static 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 DisplayCommand,
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);
1602MagickExport 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);
1697MagickExport 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);
1755static 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],
1807 text[MaxTextExtent];
1810 *ColorMenu[MaxNumberPens+1];
1855 (void) CloneString(&windows->command.name,
"Annotate");
1856 windows->command.data=4;
1857 (void) XCommandWidget(display,windows,AnnotateMenu,(XEvent *) NULL);
1858 (void) XMapRaised(display,windows->command.id);
1859 XClientMessage(display,windows->image.id,windows->im_protocols,
1860 windows->im_update_widget,CurrentTime);
1864 XQueryPosition(display,windows->image.id,&x,&y);
1865 (void) XSelectInput(display,windows->image.id,
1866 windows->image.attributes.event_mask | PointerMotionMask);
1867 cursor=XCreateFontCursor(display,XC_left_side);
1868 (void) XCheckDefineCursor(display,windows->image.id,cursor);
1872 if (windows->info.mapped != MagickFalse)
1877 (void) FormatLocaleString(text,MaxTextExtent,
" %+d%+d ",
1878 x+windows->image.x,y+windows->image.y);
1879 XInfoWidget(display,windows,text);
1884 XScreenEvent(display,windows,&event);
1885 if (event.xany.window == windows->command.id)
1890 id=XCommandWidget(display,windows,AnnotateMenu,&event);
1891 (void) XCheckDefineCursor(display,windows->image.id,cursor);
1894 switch (AnnotateCommands[
id])
1896 case AnnotateNameCommand:
1899 *FontMenu[MaxNumberFonts];
1907 for (i=0; i < MaxNumberFonts; i++)
1908 FontMenu[i]=resource_info->font_name[i];
1909 FontMenu[MaxNumberFonts-2]=
"Browser...";
1910 FontMenu[MaxNumberFonts-1]=(
const char *) NULL;
1914 font_number=XMenuWidget(display,windows,AnnotateMenu[
id],
1915 (
const char **) FontMenu,command);
1916 if (font_number < 0)
1918 if (font_number == (MaxNumberFonts-2))
1921 font_name[MaxTextExtent] =
"fixed";
1926 resource_info->font_name[font_number]=font_name;
1927 XFontBrowserWidget(display,windows,
"Select",font_name);
1928 if (*font_name ==
'\0')
1934 font_info=XLoadQueryFont(display,resource_info->font_name[
1936 if (font_info == (XFontStruct *) NULL)
1938 XNoticeWidget(display,windows,
"Unable to load font:",
1939 resource_info->font_name[font_number]);
1942 font_id=(
unsigned int) font_number;
1943 (void) XFreeFont(display,font_info);
1946 case AnnotateFontColorCommand:
1951 for (i=0; i < (int) (MaxNumberPens-2); i++)
1952 ColorMenu[i]=resource_info->pen_colors[i];
1953 ColorMenu[MaxNumberPens-2]=
"transparent";
1954 ColorMenu[MaxNumberPens-1]=
"Browser...";
1955 ColorMenu[MaxNumberPens]=(
const char *) NULL;
1959 pen_number=XMenuWidget(display,windows,AnnotateMenu[
id],
1960 (
const char **) ColorMenu,command);
1963 transparent_pen=pen_number == (MaxNumberPens-2) ? MagickTrue :
1965 if (transparent_pen != MagickFalse)
1967 if (pen_number == (MaxNumberPens-1))
1970 color_name[MaxTextExtent] =
"gray";
1975 resource_info->pen_colors[pen_number]=color_name;
1976 XColorBrowserWidget(display,windows,
"Select",color_name);
1977 if (*color_name ==
'\0')
1983 (void) XParseColor(display,windows->map_info->colormap,
1984 resource_info->pen_colors[pen_number],&color);
1985 XBestPixel(display,windows->map_info->colormap,(XColor *) NULL,
1986 (
unsigned int) MaxColors,&color);
1987 windows->pixel_info->pen_colors[pen_number]=color;
1988 pen_id=(
unsigned int) pen_number;
1991 case AnnotateBackgroundColorCommand:
1996 for (i=0; i < (int) (MaxNumberPens-2); i++)
1997 ColorMenu[i]=resource_info->pen_colors[i];
1998 ColorMenu[MaxNumberPens-2]=
"transparent";
1999 ColorMenu[MaxNumberPens-1]=
"Browser...";
2000 ColorMenu[MaxNumberPens]=(
const char *) NULL;
2004 pen_number=XMenuWidget(display,windows,AnnotateMenu[
id],
2005 (
const char **) ColorMenu,command);
2008 transparent_box=pen_number == (MaxNumberPens-2) ? MagickTrue :
2010 if (transparent_box != MagickFalse)
2012 if (pen_number == (MaxNumberPens-1))
2015 color_name[MaxTextExtent] =
"gray";
2020 resource_info->pen_colors[pen_number]=color_name;
2021 XColorBrowserWidget(display,windows,
"Select",color_name);
2022 if (*color_name ==
'\0')
2028 (void) XParseColor(display,windows->map_info->colormap,
2029 resource_info->pen_colors[pen_number],&color);
2030 XBestPixel(display,windows->map_info->colormap,(XColor *) NULL,
2031 (
unsigned int) MaxColors,&color);
2032 windows->pixel_info->pen_colors[pen_number]=color;
2033 box_id=(
unsigned int) pen_number;
2036 case AnnotateRotateCommand:
2042 *
const RotateMenu[] =
2057 angle[MaxTextExtent] =
"30.0";
2062 entry=XMenuWidget(display,windows,AnnotateMenu[
id],RotateMenu,
2068 degrees=StringToDouble(RotateMenu[entry],(
char **) NULL);
2071 (void) XDialogWidget(display,windows,
"OK",
"Enter rotation angle:",
2075 degrees=StringToDouble(angle,(
char **) NULL);
2078 case AnnotateHelpCommand:
2080 XTextViewHelp(display,resource_info,windows,MagickFalse,
2081 "Help Viewer - Image Annotation",ImageAnnotateHelp);
2084 case AnnotateDismissCommand:
2102 if (event.xbutton.button != Button1)
2104 if (event.xbutton.window != windows->image.id)
2120 if (event.xkey.window != windows->image.id)
2125 (void) XLookupString((XKeyEvent *) &
event.xkey,command,(int)
2126 sizeof(command),&key_symbol,(XComposeStatus *) NULL);
2127 switch ((
int) key_symbol)
2142 XTextViewHelp(display,resource_info,windows,MagickFalse,
2143 "Help Viewer - Image Annotation",ImageAnnotateHelp);
2148 (void) XBell(display,0);
2161 if (windows->info.mapped != MagickFalse)
2163 if ((x < (
int) (windows->info.x+windows->info.width)) &&
2164 (y < (int) (windows->info.y+windows->info.height)))
2165 (void) XWithdrawWindow(display,windows->info.id,
2166 windows->info.screen);
2169 if ((x > (
int) (windows->info.x+windows->info.width)) ||
2170 (y > (int) (windows->info.y+windows->info.height)))
2171 (void) XMapWindow(display,windows->info.id);
2177 }
while ((state & ExitState) == 0);
2178 (void) XSelectInput(display,windows->image.id,
2179 windows->image.attributes.event_mask);
2180 (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
2181 if ((state & EscapeState) != 0)
2186 font_info=XLoadQueryFont(display,resource_info->font_name[font_id]);
2187 if (font_info == (XFontStruct *) NULL)
2189 XNoticeWidget(display,windows,
"Unable to load font:",
2190 resource_info->font_name[font_id]);
2191 font_info=windows->font_info;
2193 if ((x+font_info->max_bounds.width) >= (
int) windows->image.width)
2194 x=(int) windows->image.width-font_info->max_bounds.width;
2195 if (y < (
int) (font_info->ascent+font_info->descent))
2196 y=(int) font_info->ascent+font_info->descent;
2197 if (((
int) font_info->max_bounds.width > (int) windows->image.width) ||
2198 ((font_info->ascent+font_info->descent) >= (
int) windows->image.height))
2199 return(MagickFalse);
2203 annotate_info=(XAnnotateInfo *) AcquireMagickMemory(
sizeof(*annotate_info));
2204 if (annotate_info == (XAnnotateInfo *) NULL)
2205 return(MagickFalse);
2206 XGetAnnotateInfo(annotate_info);
2209 if ((transparent_box == MagickFalse) && (transparent_pen == MagickFalse))
2210 annotate_info->stencil=OpaqueStencil;
2212 if (transparent_box == MagickFalse)
2213 annotate_info->stencil=BackgroundStencil;
2215 annotate_info->stencil=ForegroundStencil;
2216 annotate_info->height=(
unsigned int) font_info->ascent+font_info->descent;
2217 annotate_info->degrees=degrees;
2218 annotate_info->font_info=font_info;
2219 annotate_info->text=(
char *) AcquireQuantumMemory((
size_t)
2220 windows->image.width/MagickMax((ssize_t) font_info->min_bounds.width,1)+2UL,
2221 sizeof(*annotate_info->text));
2222 if (annotate_info->text == (
char *) NULL)
2223 return(MagickFalse);
2227 cursor=XCreateFontCursor(display,XC_pencil);
2228 (void) XCheckDefineCursor(display,windows->image.id,cursor);
2229 annotate_context=windows->image.annotate_context;
2230 (void) XSetFont(display,annotate_context,font_info->fid);
2231 (void) XSetBackground(display,annotate_context,
2232 windows->pixel_info->pen_colors[box_id].pixel);
2233 (void) XSetForeground(display,annotate_context,
2234 windows->pixel_info->pen_colors[pen_id].pixel);
2238 (void) CloneString(&windows->command.name,
"Text");
2239 windows->command.data=0;
2240 (void) XCommandWidget(display,windows,TextMenu,(XEvent *) NULL);
2242 (void) XDrawString(display,windows->image.id,annotate_context,x,y,
"_",1);
2243 text_event.xexpose.width=(int) font_info->max_bounds.width;
2244 text_event.xexpose.height=font_info->max_bounds.ascent+
2245 font_info->max_bounds.descent;
2246 p=annotate_info->text;
2253 (
void) XDrawString(display,windows->image.id,annotate_context,x,y,
"_",1);
2257 XScreenEvent(display,windows,&event);
2258 if (event.xany.window == windows->command.id)
2263 (void) XSetBackground(display,annotate_context,
2264 windows->pixel_info->background_color.pixel);
2265 (void) XSetForeground(display,annotate_context,
2266 windows->pixel_info->foreground_color.pixel);
2267 id=XCommandWidget(display,windows,AnnotateMenu,&event);
2268 (void) XSetBackground(display,annotate_context,
2269 windows->pixel_info->pen_colors[box_id].pixel);
2270 (void) XSetForeground(display,annotate_context,
2271 windows->pixel_info->pen_colors[pen_id].pixel);
2274 switch (TextCommands[
id])
2276 case TextHelpCommand:
2278 XTextViewHelp(display,resource_info,windows,MagickFalse,
2279 "Help Viewer - Image Annotation",ImageAnnotateHelp);
2280 (void) XCheckDefineCursor(display,windows->image.id,cursor);
2283 case TextApplyCommand:
2288 annotate_info->width=(
unsigned int) XTextWidth(font_info,
2289 annotate_info->text,(
int) strlen(annotate_info->text));
2290 XRefreshWindow(display,&windows->image,&text_event);
2302 text_event.xexpose.x=x;
2303 text_event.xexpose.y=y-font_info->max_bounds.ascent;
2304 (void) XClearArea(display,windows->image.id,x,text_event.xexpose.y,
2305 (
unsigned int) text_event.xexpose.width,(
unsigned int)
2306 text_event.xexpose.height,MagickFalse);
2307 XRefreshWindow(display,&windows->image,&text_event);
2312 if (event.xbutton.window != windows->image.id)
2314 if (event.xbutton.button == Button2)
2319 (void) XConvertSelection(display,XA_PRIMARY,XA_STRING,XA_STRING,
2320 windows->image.id,CurrentTime);
2327 if (event.xexpose.count == 0)
2335 XRefreshWindow(display,&windows->image,(XEvent *) NULL);
2336 text_info=annotate_info;
2337 while (text_info != (XAnnotateInfo *) NULL)
2339 if (annotate_info->stencil == ForegroundStencil)
2340 (void) XDrawString(display,windows->image.id,annotate_context,
2341 text_info->x,text_info->y,text_info->text,
2342 (
int) strlen(text_info->text));
2344 (
void) XDrawImageString(display,windows->image.id,
2345 annotate_context,text_info->x,text_info->y,text_info->text,
2346 (
int) strlen(text_info->text));
2347 text_info=text_info->previous;
2349 (void) XDrawString(display,windows->image.id,annotate_context,
2359 if (event.xkey.window != windows->image.id)
2364 length=XLookupString((XKeyEvent *) &event.xkey,command,(
int)
2365 sizeof(command),&key_symbol,(XComposeStatus *) NULL);
2366 *(command+length)=
'\0';
2367 if (((event.xkey.state & ControlMask) != 0) ||
2368 ((
event.xkey.state & Mod1Mask) != 0))
2369 state|=ModifierState;
2370 if ((state & ModifierState) != 0)
2371 switch ((
int) key_symbol)
2376 key_symbol=DeleteCommand;
2382 switch ((
int) key_symbol)
2389 if (p == annotate_info->text)
2391 if (annotate_info->previous == (XAnnotateInfo *) NULL)
2398 annotate_info=annotate_info->previous;
2399 p=annotate_info->text;
2400 x=annotate_info->x+annotate_info->width;
2402 if (annotate_info->width != 0)
2403 p+=strlen(annotate_info->text);
2408 x-=XTextWidth(font_info,p,1);
2409 text_event.xexpose.x=x;
2410 text_event.xexpose.y=y-font_info->max_bounds.ascent;
2411 XRefreshWindow(display,&windows->image,&text_event);
2414 case XK_bracketleft:
2416 key_symbol=XK_Escape;
2424 while (p != annotate_info->text)
2427 x-=XTextWidth(font_info,p,1);
2428 text_event.xexpose.x=x;
2429 XRefreshWindow(display,&windows->image,&text_event);
2439 annotate_info->width=(
unsigned int) XTextWidth(font_info,
2440 annotate_info->text,(
int) strlen(annotate_info->text));
2441 XRefreshWindow(display,&windows->image,&text_event);
2450 if ((state & ModifierState) != 0)
2452 if (*command ==
'\0')
2455 if (annotate_info->stencil == ForegroundStencil)
2456 (void) XDrawString(display,windows->image.id,annotate_context,
2459 (
void) XDrawImageString(display,windows->image.id,
2460 annotate_context,x,y,p,1);
2461 x+=XTextWidth(font_info,p,1);
2463 if ((x+font_info->max_bounds.width) < (
int) windows->image.width)
2474 annotate_info->width=(
unsigned int) XTextWidth(font_info,
2475 annotate_info->text,(
int) strlen(annotate_info->text));
2476 if (annotate_info->next != (XAnnotateInfo *) NULL)
2481 annotate_info=annotate_info->next;
2484 p=annotate_info->text;
2487 annotate_info->next=(XAnnotateInfo *) AcquireQuantumMemory(1,
2488 sizeof(*annotate_info->next));
2489 if (annotate_info->next == (XAnnotateInfo *) NULL)
2490 return(MagickFalse);
2491 *annotate_info->next=(*annotate_info);
2492 annotate_info->next->previous=annotate_info;
2493 annotate_info=annotate_info->next;
2494 annotate_info->text=(
char *) AcquireQuantumMemory((
size_t)
2495 windows->image.width/MagickMax((ssize_t)
2496 font_info->min_bounds.width,1)+2UL,
sizeof(*annotate_info->text));
2497 if (annotate_info->text == (
char *) NULL)
2498 return(MagickFalse);
2499 annotate_info->y+=annotate_info->height;
2500 if (annotate_info->y > (
int) windows->image.height)
2501 annotate_info->y=(
int) annotate_info->height;
2502 annotate_info->next=(XAnnotateInfo *) NULL;
2505 p=annotate_info->text;
2516 (void) XLookupString((XKeyEvent *) &
event.xkey,command,(int)
2517 sizeof(command),&key_symbol,(XComposeStatus *) NULL);
2518 state&=(~ModifierState);
2521 case SelectionNotify:
2539 if (event.xselection.property == (Atom) None)
2541 status=XGetWindowProperty(display,event.xselection.requestor,
2542 event.xselection.property,0L,(
long) MaxTextExtent,True,XA_STRING,
2543 &type,&format,&length,&after,&data);
2544 if ((status != Success) || (type != XA_STRING) || (format == 32) ||
2550 for (i=0; i < (ssize_t) length; i++)
2552 if ((
char) data[i] !=
'\n')
2558 (void) XDrawString(display,windows->image.id,annotate_context,
2560 x+=XTextWidth(font_info,p,1);
2562 if ((x+font_info->max_bounds.width) < (
int) windows->image.width)
2569 annotate_info->width=(
unsigned int) XTextWidth(font_info,
2570 annotate_info->text,(
int) strlen(annotate_info->text));
2571 if (annotate_info->next != (XAnnotateInfo *) NULL)
2576 annotate_info=annotate_info->next;
2579 p=annotate_info->text;
2582 annotate_info->next=(XAnnotateInfo *) AcquireQuantumMemory(1,
2583 sizeof(*annotate_info->next));
2584 if (annotate_info->next == (XAnnotateInfo *) NULL)
2585 return(MagickFalse);
2586 *annotate_info->next=(*annotate_info);
2587 annotate_info->next->previous=annotate_info;
2588 annotate_info=annotate_info->next;
2589 annotate_info->text=(
char *) AcquireQuantumMemory((
size_t)
2590 windows->image.width/MagickMax((ssize_t)
2591 font_info->min_bounds.width,1)+2UL,
sizeof(*annotate_info->text));
2592 if (annotate_info->text == (
char *) NULL)
2593 return(MagickFalse);
2594 annotate_info->y+=annotate_info->height;
2595 if (annotate_info->y > (
int) windows->image.height)
2596 annotate_info->y=(
int) annotate_info->height;
2597 annotate_info->next=(XAnnotateInfo *) NULL;
2600 p=annotate_info->text;
2602 (void) XFree((
void *) data);
2608 }
while ((state & ExitState) == 0);
2609 (void) XFreeCursor(display,cursor);
2613 width=(
unsigned int) image->columns;
2614 height=(
unsigned int) image->rows;
2617 if (windows->image.crop_geometry != (
char *) NULL)
2618 (
void) XParseGeometry(windows->image.crop_geometry,&x,&y,&width,&height);
2622 XSetCursorState(display,windows,MagickTrue);
2623 XCheckRefreshWindows(display,windows);
2624 while (annotate_info != (XAnnotateInfo *) NULL)
2626 if (annotate_info->width == 0)
2631 previous_info=annotate_info->previous;
2632 annotate_info->text=(
char *)
2633 RelinquishMagickMemory(annotate_info->text);
2634 annotate_info=(XAnnotateInfo *) RelinquishMagickMemory(annotate_info);
2635 annotate_info=previous_info;
2641 windows->pixel_info->box_color=windows->pixel_info->pen_colors[box_id];
2642 if (windows->pixel_info->colors != 0)
2643 for (i=0; i < (ssize_t) windows->pixel_info->colors; i++)
2644 if (windows->pixel_info->pixels[i] ==
2645 windows->pixel_info->pen_colors[box_id].pixel)
2647 windows->pixel_info->box_index=(
unsigned short) i;
2650 windows->pixel_info->pen_color=windows->pixel_info->pen_colors[pen_id];
2651 if (windows->pixel_info->colors != 0)
2652 for (i=0; i < (ssize_t) windows->pixel_info->colors; i++)
2653 if (windows->pixel_info->pixels[i] ==
2654 windows->pixel_info->pen_colors[pen_id].pixel)
2656 windows->pixel_info->pen_index=(
unsigned short) i;
2662 annotate_info->x=(int)
2663 width*(annotate_info->x+windows->image.x)/windows->image.ximage->width;
2664 annotate_info->y=(int) height*(annotate_info->y-font_info->ascent+
2665 windows->image.y)/windows->image.ximage->height;
2666 (void) FormatLocaleString(annotate_info->geometry,MaxTextExtent,
2667 "%ux%u%+d%+d",width*annotate_info->width/windows->image.ximage->width,
2668 height*annotate_info->height/windows->image.ximage->height,
2669 annotate_info->x+x,annotate_info->y+y);
2673 status=XAnnotateImage(display,windows->pixel_info,annotate_info,image);
2675 return(MagickFalse);
2679 previous_info=annotate_info->previous;
2680 annotate_info->text=DestroyString(annotate_info->text);
2681 annotate_info=(XAnnotateInfo *) RelinquishMagickMemory(annotate_info);
2682 annotate_info=previous_info;
2684 (void) XSetForeground(display,annotate_context,
2685 windows->pixel_info->foreground_color.pixel);
2686 (void) XSetBackground(display,annotate_context,
2687 windows->pixel_info->background_color.pixel);
2688 (void) XSetFont(display,annotate_context,windows->font_info->fid);
2689 XSetCursorState(display,windows,MagickFalse);
2690 (void) XFreeFont(display,font_info);
2694 XConfigureImageColormap(display,resource_info,windows,image);
2695 (void) XConfigureImage(display,resource_info,windows,image);
2729static MagickBooleanType XBackgroundImage(Display *display,
2730 XResourceInfo *resource_info,XWindows *windows,
Image **image)
2732#define BackgroundImageTag "Background/Image"
2738 window_id[MaxTextExtent] =
"root";
2741 background_resources;
2746 status=XDialogWidget(display,windows,
"Background",
2747 "Enter window id (id 0x00 selects window with pointer):",window_id);
2748 if (*window_id ==
'\0')
2749 return(MagickFalse);
2750 (void) XMagickCommand(display,resource_info,windows,ApplyCommand,image);
2751 XInfoWidget(display,windows,BackgroundImageTag);
2752 XSetCursorState(display,windows,MagickTrue);
2753 XCheckRefreshWindows(display,windows);
2754 background_resources=(*resource_info);
2755 background_resources.window_id=window_id;
2756 background_resources.backdrop=status != 0 ? MagickTrue : MagickFalse;
2757 status=XDisplayBackgroundImage(display,&background_resources,*image);
2758 if (status != MagickFalse)
2759 XClientMessage(display,windows->image.id,windows->im_protocols,
2760 windows->im_retain_colors,CurrentTime);
2761 XSetCursorState(display,windows,MagickFalse);
2762 (void) XMagickCommand(display,resource_info,windows,UndoCommand,image);
2796static MagickBooleanType XChopImage(Display *display,
2797 XResourceInfo *resource_info,XWindows *windows,
Image **image)
2809 direction = HorizontalChopCommand;
2811 static const ModeType
2814 ChopDirectionCommand,
2818 DirectionCommands[] =
2820 HorizontalChopCommand,
2825 text[MaxTextExtent];
2858 (void) CloneString(&windows->command.name,
"Chop");
2859 windows->command.data=1;
2860 (void) XCommandWidget(display,windows,ChopMenu,(XEvent *) NULL);
2861 (void) XMapRaised(display,windows->command.id);
2862 XClientMessage(display,windows->image.id,windows->im_protocols,
2863 windows->im_update_widget,CurrentTime);
2867 XQueryPosition(display,windows->image.id,&x,&y);
2868 (void) XSelectInput(display,windows->image.id,
2869 windows->image.attributes.event_mask | PointerMotionMask);
2871 (void) memset(&segment_info,0,
sizeof(segment_info));
2874 if (windows->info.mapped != MagickFalse)
2879 (void) FormatLocaleString(text,MaxTextExtent,
" %+d%+d ",
2880 x+windows->image.x,y+windows->image.y);
2881 XInfoWidget(display,windows,text);
2886 XScreenEvent(display,windows,&event);
2887 if (event.xany.window == windows->command.id)
2892 id=XCommandWidget(display,windows,ChopMenu,&event);
2895 switch (ChopCommands[
id])
2897 case ChopDirectionCommand:
2900 command[MaxTextExtent];
2903 *
const Directions[] =
2913 id=XMenuWidget(display,windows,ChopMenu[
id],Directions,command);
2915 direction=DirectionCommands[id];
2918 case ChopHelpCommand:
2920 XTextViewHelp(display,resource_info,windows,MagickFalse,
2921 "Help Viewer - Image Chop",ImageChopHelp);
2924 case ChopDismissCommand:
2942 if (event.xbutton.button != Button1)
2944 if (event.xbutton.window != windows->image.id)
2949 segment_info.x1=(
short int) event.xbutton.x;
2950 segment_info.x2=(
short int)
event.xbutton.x;
2951 segment_info.y1=(
short int) event.xbutton.y;
2952 segment_info.y2=(
short int)
event.xbutton.y;
2963 command[MaxTextExtent];
2968 if (event.xkey.window != windows->image.id)
2973 (void) XLookupString((XKeyEvent *) &
event.xkey,command,(int)
2974 sizeof(command),&key_symbol,(XComposeStatus *) NULL);
2975 switch ((
int) key_symbol)
2990 (void) XSetFunction(display,windows->image.highlight_context,
2992 XTextViewHelp(display,resource_info,windows,MagickFalse,
2993 "Help Viewer - Image Chop",ImageChopHelp);
2994 (void) XSetFunction(display,windows->image.highlight_context,
3000 (void) XBell(display,0);
3013 if (windows->info.mapped != MagickFalse)
3015 if ((x < (
int) (windows->info.x+windows->info.width)) &&
3016 (y < (int) (windows->info.y+windows->info.height)))
3017 (void) XWithdrawWindow(display,windows->info.id,
3018 windows->info.screen);
3021 if ((x > (
int) (windows->info.x+windows->info.width)) ||
3022 (y > (int) (windows->info.y+windows->info.height)))
3023 (void) XMapWindow(display,windows->info.id);
3026 }
while ((state & ExitState) == 0);
3027 (void) XSelectInput(display,windows->image.id,
3028 windows->image.attributes.event_mask);
3029 (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
3030 if ((state & EscapeState) != 0)
3040 (void) XSetFunction(display,windows->image.highlight_context,GXinvert);
3049 if (windows->info.mapped == MagickFalse)
3050 (void) XMapWindow(display,windows->info.id);
3051 (void) FormatLocaleString(text,MaxTextExtent,
3052 " %.20gx%.20g%+.20g%+.20g",(
double) chop_info.width,(double)
3053 chop_info.height,(
double) chop_info.x,(double) chop_info.y);
3054 XInfoWidget(display,windows,text);
3055 XHighlightLine(display,windows->image.id,
3056 windows->image.highlight_context,&segment_info);
3059 if (windows->info.mapped != MagickFalse)
3060 (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
3064 XScreenEvent(display,windows,&event);
3066 XHighlightLine(display,windows->image.id,
3067 windows->image.highlight_context,&segment_info);
3072 segment_info.x2=(
short int) event.xmotion.x;
3073 segment_info.y2=(
short int)
event.xmotion.y;
3081 segment_info.x2=(
short int) event.xbutton.x;
3082 segment_info.y2=(
short int)
event.xbutton.y;
3090 segment_info.x2=(
short int) event.xmotion.x;
3091 segment_info.y2=(
short int)
event.xmotion.y;
3099 if (segment_info.x2 < 0)
3102 if (segment_info.x2 > windows->image.ximage->width)
3103 segment_info.x2=windows->image.ximage->width;
3104 if (segment_info.y2 < 0)
3107 if (segment_info.y2 > windows->image.ximage->height)
3108 segment_info.y2=windows->image.ximage->height;
3109 distance=(
unsigned int)
3110 (((segment_info.x2-segment_info.x1)*(segment_info.x2-segment_info.x1))+
3111 ((segment_info.y2-segment_info.y1)*(segment_info.y2-segment_info.y1)));
3115 if (direction == HorizontalChopCommand)
3117 chop_info.width=(size_t) (segment_info.x2-segment_info.x1+1);
3118 chop_info.x=(ssize_t) windows->image.x+segment_info.x1;
3121 if (segment_info.x1 > (
int) segment_info.x2)
3123 chop_info.width=(size_t) (segment_info.x1-segment_info.x2+1);
3124 chop_info.x=(ssize_t) windows->image.x+segment_info.x2;
3130 chop_info.height=(size_t) (segment_info.y2-segment_info.y1+1);
3132 chop_info.y=(ssize_t) windows->image.y+segment_info.y1;
3133 if (segment_info.y1 > segment_info.y2)
3135 chop_info.height=(size_t) (segment_info.y1-segment_info.y2+1);
3136 chop_info.y=(ssize_t) windows->image.y+segment_info.y2;
3139 }
while ((state & ExitState) == 0);
3140 (void) XSetFunction(display,windows->image.highlight_context,GXcopy);
3141 (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
3147 (void) XMagickCommand(display,resource_info,windows,ApplyCommand,image);
3148 XSetCursorState(display,windows,MagickTrue);
3149 XCheckRefreshWindows(display,windows);
3150 windows->image.window_changes.width=windows->image.ximage->width-
3151 (
unsigned int) chop_info.width;
3152 windows->image.window_changes.height=windows->image.ximage->height-
3153 (
unsigned int) chop_info.height;
3154 width=(
unsigned int) (*image)->columns;
3155 height=(
unsigned int) (*image)->rows;
3158 if (windows->image.crop_geometry != (
char *) NULL)
3159 (
void) XParseGeometry(windows->image.crop_geometry,&x,&y,&width,&height);
3160 scale_factor=(MagickRealType) width/windows->image.ximage->width;
3162 chop_info.x=(ssize_t) (scale_factor*chop_info.x+0.5);
3163 chop_info.width=(
unsigned int) (scale_factor*chop_info.width+0.5);
3164 scale_factor=(MagickRealType) height/windows->image.ximage->height;
3166 chop_info.y=(ssize_t) (scale_factor*chop_info.y+0.5);
3167 chop_info.height=(
unsigned int) (scale_factor*chop_info.height+0.5);
3171 chop_image=ChopImage(*image,&chop_info,&(*image)->exception);
3172 XSetCursorState(display,windows,MagickFalse);
3173 if (chop_image == (
Image *) NULL)
3174 return(MagickFalse);
3175 *image=DestroyImage(*image);
3180 XConfigureImageColormap(display,resource_info,windows,*image);
3181 (void) XConfigureImage(display,resource_info,windows,*image);
3218static MagickBooleanType XColorEditImage(Display *display,
3219 XResourceInfo *resource_info,XWindows *windows,
Image **image)
3222 *
const ColorEditMenu[] =
3234 static const ModeType
3235 ColorEditCommands[] =
3237 ColorEditMethodCommand,
3238 ColorEditColorCommand,
3239 ColorEditBorderCommand,
3240 ColorEditFuzzCommand,
3241 ColorEditUndoCommand,
3242 ColorEditHelpCommand,
3243 ColorEditDismissCommand
3247 method = PointMethod;
3253 border_color = { 0, 0, 0, 0, 0, 0 };
3256 command[MaxTextExtent] =
"",
3257 text[MaxTextExtent] =
"";
3295 (void) CloneString(&windows->command.name,
"Color Edit");
3296 windows->command.data=4;
3297 (void) XCommandWidget(display,windows,ColorEditMenu,(XEvent *) NULL);
3298 (void) XMapRaised(display,windows->command.id);
3299 XClientMessage(display,windows->image.id,windows->im_protocols,
3300 windows->im_update_widget,CurrentTime);
3304 cursor=XMakeCursor(display,windows->image.id,windows->map_info->colormap,
3305 resource_info->background_color,resource_info->foreground_color);
3306 (void) XCheckDefineCursor(display,windows->image.id,cursor);
3310 XQueryPosition(display,windows->image.id,&x,&y);
3311 (void) XSelectInput(display,windows->image.id,
3312 windows->image.attributes.event_mask | PointerMotionMask);
3316 if (windows->info.mapped != MagickFalse)
3321 (void) FormatLocaleString(text,MaxTextExtent,
" %+d%+d ",
3322 x+windows->image.x,y+windows->image.y);
3323 XInfoWidget(display,windows,text);
3328 XScreenEvent(display,windows,&event);
3329 if (event.xany.window == windows->command.id)
3334 id=XCommandWidget(display,windows,ColorEditMenu,&event);
3337 (void) XCheckDefineCursor(display,windows->image.id,cursor);
3340 switch (ColorEditCommands[
id])
3342 case ColorEditMethodCommand:
3350 methods=(
char **) GetCommandOptions(MagickMethodOptions);
3351 if (methods == (
char **) NULL)
3353 entry=XMenuWidget(display,windows,ColorEditMenu[
id],
3354 (
const char **) methods,command);
3356 method=(PaintMethod) ParseCommandOption(MagickMethodOptions,
3357 MagickFalse,methods[entry]);
3358 methods=DestroyStringList(methods);
3361 case ColorEditColorCommand:
3364 *ColorMenu[MaxNumberPens];
3372 for (i=0; i < (int) (MaxNumberPens-2); i++)
3373 ColorMenu[i]=resource_info->pen_colors[i];
3374 ColorMenu[MaxNumberPens-2]=
"Browser...";
3375 ColorMenu[MaxNumberPens-1]=(
const char *) NULL;
3379 pen_number=XMenuWidget(display,windows,ColorEditMenu[
id],
3380 (
const char **) ColorMenu,command);
3383 if (pen_number == (MaxNumberPens-2))
3386 color_name[MaxTextExtent] =
"gray";
3391 resource_info->pen_colors[pen_number]=color_name;
3392 XColorBrowserWidget(display,windows,
"Select",color_name);
3393 if (*color_name ==
'\0')
3399 (void) XParseColor(display,windows->map_info->colormap,
3400 resource_info->pen_colors[pen_number],&color);
3401 XBestPixel(display,windows->map_info->colormap,(XColor *) NULL,
3402 (
unsigned int) MaxColors,&color);
3403 windows->pixel_info->pen_colors[pen_number]=color;
3404 pen_id=(
unsigned int) pen_number;
3407 case ColorEditBorderCommand:
3410 *ColorMenu[MaxNumberPens];
3418 for (i=0; i < (int) (MaxNumberPens-2); i++)
3419 ColorMenu[i]=resource_info->pen_colors[i];
3420 ColorMenu[MaxNumberPens-2]=
"Browser...";
3421 ColorMenu[MaxNumberPens-1]=(
const char *) NULL;
3425 pen_number=XMenuWidget(display,windows,ColorEditMenu[
id],
3426 (
const char **) ColorMenu,command);
3429 if (pen_number == (MaxNumberPens-2))
3432 color_name[MaxTextExtent] =
"gray";
3437 resource_info->pen_colors[pen_number]=color_name;
3438 XColorBrowserWidget(display,windows,
"Select",color_name);
3439 if (*color_name ==
'\0')
3445 (void) XParseColor(display,windows->map_info->colormap,
3446 resource_info->pen_colors[pen_number],&border_color);
3449 case ColorEditFuzzCommand:
3452 fuzz[MaxTextExtent];
3469 entry=XMenuWidget(display,windows,ColorEditMenu[
id],FuzzMenu,
3475 (*image)->fuzz=StringToDoubleInterval(FuzzMenu[entry],(
double)
3479 (void) (
void) CopyMagickString(fuzz,
"20%",MaxTextExtent);
3480 (void) XDialogWidget(display,windows,
"Ok",
3481 "Enter fuzz factor (0.0 - 99.9%):",fuzz);
3484 (void) ConcatenateMagickString(fuzz,
"%",MaxTextExtent);
3485 (*image)->fuzz=StringToDoubleInterval(fuzz,(
double) QuantumRange+
3489 case ColorEditUndoCommand:
3491 (void) XMagickCommand(display,resource_info,windows,UndoCommand,
3495 case ColorEditHelpCommand:
3498 XTextViewHelp(display,resource_info,windows,MagickFalse,
3499 "Help Viewer - Image Annotation",ImageColorEditHelp);
3502 case ColorEditDismissCommand:
3512 (void) XCheckDefineCursor(display,windows->image.id,cursor);
3519 if (event.xbutton.button != Button1)
3521 if ((event.xbutton.window != windows->image.id) &&
3522 (
event.xbutton.window != windows->magnify.id))
3529 (void) XMagickCommand(display,resource_info,windows,
3530 SaveToUndoBufferCommand,image);
3531 state|=UpdateConfigurationState;
3536 if (event.xbutton.button != Button1)
3538 if ((event.xbutton.window != windows->image.id) &&
3539 (
event.xbutton.window != windows->magnify.id))
3546 XConfigureImageColormap(display,resource_info,windows,*image);
3547 (void) XConfigureImage(display,resource_info,windows,*image);
3548 XInfoWidget(display,windows,text);
3549 (void) XCheckDefineCursor(display,windows->image.id,cursor);
3550 state&=(~UpdateConfigurationState);
3560 if (event.xkey.window == windows->magnify.id)
3565 window=windows->magnify.id;
3566 while (XCheckWindowEvent(display,window,KeyPressMask,&event)) ;
3568 if (event.xkey.window != windows->image.id)
3573 (void) XLookupString((XKeyEvent *) &
event.xkey,command,(int)
3574 sizeof(command),&key_symbol,(XComposeStatus *) NULL);
3575 switch ((
int) key_symbol)
3589 XTextViewHelp(display,resource_info,windows,MagickFalse,
3590 "Help Viewer - Image Annotation",ImageColorEditHelp);
3595 (void) XBell(display,0);
3608 if (windows->info.mapped != MagickFalse)
3610 if ((x < (
int) (windows->info.x+windows->info.width)) &&
3611 (y < (int) (windows->info.y+windows->info.height)))
3612 (void) XWithdrawWindow(display,windows->info.id,
3613 windows->info.screen);
3616 if ((x > (
int) (windows->info.x+windows->info.width)) ||
3617 (y > (int) (windows->info.y+windows->info.height)))
3618 (void) XMapWindow(display,windows->info.id);
3624 if (event.xany.window == windows->magnify.id)
3626 x=windows->magnify.x-windows->image.x;
3627 y=windows->magnify.y-windows->image.y;
3631 if ((state & UpdateConfigurationState) != 0)
3643 (void) XClearArea(display,windows->image.id,x_offset,y_offset,1,1,
3645 color=windows->pixel_info->pen_colors[pen_id];
3646 XPutPixel(windows->image.ximage,x_offset,y_offset,color.pixel);
3647 width=(
unsigned int) (*image)->columns;
3648 height=(
unsigned int) (*image)->rows;
3651 if (windows->image.crop_geometry != (
char *) NULL)
3652 (
void) XParseGeometry(windows->image.crop_geometry,&x,&y,
3655 (width*(windows->image.x+x_offset)/windows->image.ximage->width+x);
3657 (height*(windows->image.y+y_offset)/windows->image.ximage->height+y);
3658 if ((x_offset < 0) || (y_offset < 0))
3660 if ((x_offset >= (
int) (*image)->columns) ||
3661 (y_offset >= (
int) (*image)->rows))
3663 exception=(&(*image)->exception);
3664 image_view=AcquireAuthenticCacheView(*image,exception);
3673 if (SetImageStorageClass(*image,DirectClass) == MagickFalse)
3674 return(MagickFalse);
3675 q=GetCacheViewAuthenticPixels(image_view,(ssize_t)x_offset,
3676 (ssize_t)y_offset,1,1,exception);
3679 q->red=ScaleShortToQuantum(color.red);
3680 q->green=ScaleShortToQuantum(color.green);
3681 q->blue=ScaleShortToQuantum(color.blue);
3682 (void) SyncCacheViewAuthenticPixels(image_view,
3683 &(*image)->exception);
3694 (void) GetOneCacheViewVirtualPixel(image_view,(ssize_t) x_offset,
3695 (ssize_t) y_offset,&target,&(*image)->exception);
3696 if ((*image)->storage_class == DirectClass)
3698 for (y=0; y < (int) (*image)->rows; y++)
3700 q=GetCacheViewAuthenticPixels(image_view,0,(ssize_t) y,
3701 (*image)->columns,1,exception);
3704 for (x=0; x < (int) (*image)->columns; x++)
3706 if (IsColorSimilar(*image,q,&target) != MagickFalse)
3708 q->red=ScaleShortToQuantum(color.red);
3709 q->green=ScaleShortToQuantum(color.green);
3710 q->blue=ScaleShortToQuantum(color.blue);
3714 if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
3720 for (i=0; i < (ssize_t) (*image)->colors; i++)
3721 if (IsColorSimilar(*image,(*image)->colormap+i,&target) != MagickFalse)
3723 (*image)->colormap[i].red=ScaleShortToQuantum(color.red);
3724 (*image)->colormap[i].green=ScaleShortToQuantum(
3726 (*image)->colormap[i].blue=ScaleShortToQuantum(
3729 (void) SyncImage(*image);
3733 case FloodfillMethod:
3734 case FillToBorderMethod:
3745 (void) GetOneVirtualMagickPixel(*image,(ssize_t) x_offset,
3746 (ssize_t) y_offset,&target,exception);
3747 if (method == FillToBorderMethod)
3749 target.red=(MagickRealType)
3750 ScaleShortToQuantum(border_color.red);
3751 target.green=(MagickRealType)
3752 ScaleShortToQuantum(border_color.green);
3753 target.blue=(MagickRealType)
3754 ScaleShortToQuantum(border_color.blue);
3756 draw_info=CloneDrawInfo(resource_info->image_info,
3758 (void) QueryColorDatabase(resource_info->pen_colors[pen_id],
3759 &draw_info->fill,exception);
3760 (void) FloodfillPaintImage(*image,DefaultChannels,draw_info,&target,
3761 (ssize_t) x_offset,(ssize_t) y_offset,
3762 method == FloodfillMethod ? MagickFalse : MagickTrue);
3763 draw_info=DestroyDrawInfo(draw_info);
3771 if (SetImageStorageClass(*image,DirectClass) == MagickFalse)
3772 return(MagickFalse);
3773 for (y=0; y < (int) (*image)->rows; y++)
3775 q=QueueCacheViewAuthenticPixels(image_view,0,(ssize_t) y,
3776 (*image)->columns,1,exception);
3779 for (x=0; x < (int) (*image)->columns; x++)
3781 q->red=ScaleShortToQuantum(color.red);
3782 q->green=ScaleShortToQuantum(color.green);
3783 q->blue=ScaleShortToQuantum(color.blue);
3786 if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
3792 image_view=DestroyCacheView(image_view);
3793 state&=(~UpdateConfigurationState);
3795 }
while ((state & ExitState) == 0);
3796 (void) XSelectInput(display,windows->image.id,
3797 windows->image.attributes.event_mask);
3798 XSetCursorState(display,windows,MagickFalse);
3799 (void) XFreeCursor(display,cursor);
3835static MagickBooleanType XCompositeImage(Display *display,
3836 XResourceInfo *resource_info,XWindows *windows,
Image *image)
3839 *
const CompositeMenu[] =
3850 displacement_geometry[MaxTextExtent] =
"30x30",
3851 filename[MaxTextExtent] =
"\0";
3853 static CompositeOperator
3854 compose = CopyCompositeOp;
3856 static const ModeType
3857 CompositeCommands[] =
3859 CompositeOperatorsCommand,
3860 CompositeDissolveCommand,
3861 CompositeDisplaceCommand,
3862 CompositeHelpCommand,
3863 CompositeDismissCommand
3867 text[MaxTextExtent];
3902 XFileBrowserWidget(display,windows,
"Composite",filename);
3903 if (*filename ==
'\0')
3908 XSetCursorState(display,windows,MagickTrue);
3909 XCheckRefreshWindows(display,windows);
3910 (void) CopyMagickString(resource_info->image_info->filename,filename,
3912 composite_image=ReadImage(resource_info->image_info,&image->exception);
3913 CatchException(&image->exception);
3914 XSetCursorState(display,windows,MagickFalse);
3915 if (composite_image == (
Image *) NULL)
3916 return(MagickFalse);
3920 (void) CloneString(&windows->command.name,
"Composite");
3921 windows->command.data=1;
3922 (void) XCommandWidget(display,windows,CompositeMenu,(XEvent *) NULL);
3923 (void) XMapRaised(display,windows->command.id);
3924 XClientMessage(display,windows->image.id,windows->im_protocols,
3925 windows->im_update_widget,CurrentTime);
3929 XQueryPosition(display,windows->image.id,&x,&y);
3930 (void) XSelectInput(display,windows->image.id,
3931 windows->image.attributes.event_mask | PointerMotionMask);
3932 composite_info.x=(ssize_t) windows->image.x+x;
3933 composite_info.y=(ssize_t) windows->image.y+y;
3934 composite_info.width=0;
3935 composite_info.height=0;
3936 cursor=XCreateFontCursor(display,XC_ul_angle);
3937 (void) XSetFunction(display,windows->image.highlight_context,GXinvert);
3942 if (windows->info.mapped != MagickFalse)
3947 (void) FormatLocaleString(text,MaxTextExtent,
" %+ld%+ld ",
3948 (
long) composite_info.x,(long) composite_info.y);
3949 XInfoWidget(display,windows,text);
3951 highlight_info=composite_info;
3952 highlight_info.x=composite_info.x-windows->image.x;
3953 highlight_info.y=composite_info.y-windows->image.y;
3954 XHighlightRectangle(display,windows->image.id,
3955 windows->image.highlight_context,&highlight_info);
3959 XScreenEvent(display,windows,&event);
3960 XHighlightRectangle(display,windows->image.id,
3961 windows->image.highlight_context,&highlight_info);
3962 if (event.xany.window == windows->command.id)
3967 id=XCommandWidget(display,windows,CompositeMenu,&event);
3970 switch (CompositeCommands[
id])
3972 case CompositeOperatorsCommand:
3975 command[MaxTextExtent],
3981 operators=GetCommandOptions(MagickComposeOptions);
3982 if (operators == (
char **) NULL)
3984 entry=XMenuWidget(display,windows,CompositeMenu[
id],
3985 (
const char **) operators,command);
3987 compose=(CompositeOperator) ParseCommandOption(
3988 MagickComposeOptions,MagickFalse,operators[entry]);
3989 operators=DestroyStringList(operators);
3992 case CompositeDissolveCommand:
3995 factor[MaxTextExtent] =
"20.0";
4000 (void) XSetFunction(display,windows->image.highlight_context,
4002 (void) XDialogWidget(display,windows,
"Dissolve",
4003 "Enter the blend factor (0.0 - 99.9%):",factor);
4004 (void) XSetFunction(display,windows->image.highlight_context,
4006 if (*factor ==
'\0')
4008 blend=StringToDouble(factor,(
char **) NULL);
4009 compose=DissolveCompositeOp;
4012 case CompositeDisplaceCommand:
4017 (void) XSetFunction(display,windows->image.highlight_context,
4019 (void) XDialogWidget(display,windows,
"Displace",
4020 "Enter the horizontal and vertical scale:",displacement_geometry);
4021 (void) XSetFunction(display,windows->image.highlight_context,
4023 if (*displacement_geometry ==
'\0')
4025 compose=DisplaceCompositeOp;
4028 case CompositeHelpCommand:
4030 (void) XSetFunction(display,windows->image.highlight_context,
4032 XTextViewHelp(display,resource_info,windows,MagickFalse,
4033 "Help Viewer - Image Composite",ImageCompositeHelp);
4034 (void) XSetFunction(display,windows->image.highlight_context,
4038 case CompositeDismissCommand:
4056 if (resource_info->debug != MagickFalse)
4057 (void) LogMagickEvent(X11Event,GetMagickModule(),
4058 "Button Press: 0x%lx %u +%d+%d",
event.xbutton.window,
4059 event.xbutton.button,
event.xbutton.x,
event.xbutton.y);
4060 if (event.xbutton.button != Button1)
4062 if (event.xbutton.window != windows->image.id)
4067 composite_info.width=composite_image->columns;
4068 composite_info.height=composite_image->rows;
4069 (void) XCheckDefineCursor(display,windows->image.id,cursor);
4070 composite_info.x=(ssize_t) windows->image.x+event.xbutton.x;
4071 composite_info.y=(ssize_t) windows->image.y+
event.xbutton.y;
4076 if (resource_info->debug != MagickFalse)
4077 (void) LogMagickEvent(X11Event,GetMagickModule(),
4078 "Button Release: 0x%lx %u +%d+%d",
event.xbutton.window,
4079 event.xbutton.button,
event.xbutton.x,
event.xbutton.y);
4080 if (event.xbutton.button != Button1)
4082 if (event.xbutton.window != windows->image.id)
4084 if ((composite_info.width != 0) && (composite_info.height != 0))
4089 composite_info.x=(ssize_t) windows->image.x+event.xbutton.x;
4090 composite_info.y=(ssize_t) windows->image.y+
event.xbutton.y;
4100 command[MaxTextExtent];
4108 if (event.xkey.window != windows->image.id)
4113 length=XLookupString((XKeyEvent *) &event.xkey,command,(
int)
4114 sizeof(command),&key_symbol,(XComposeStatus *) NULL);
4115 *(command+length)=
'\0';
4116 if (resource_info->debug != MagickFalse)
4117 (void) LogMagickEvent(X11Event,GetMagickModule(),
4118 "Key press: 0x%lx (%s)",(
unsigned long) key_symbol,command);
4119 switch ((
int) key_symbol)
4127 composite_image=DestroyImage(composite_image);
4135 (void) XSetFunction(display,windows->image.highlight_context,
4137 XTextViewHelp(display,resource_info,windows,MagickFalse,
4138 "Help Viewer - Image Composite",ImageCompositeHelp);
4139 (void) XSetFunction(display,windows->image.highlight_context,
4145 (void) XBell(display,0);
4158 if (windows->info.mapped != MagickFalse)
4160 if ((x < (
int) (windows->info.x+windows->info.width)) &&
4161 (y < (int) (windows->info.y+windows->info.height)))
4162 (void) XWithdrawWindow(display,windows->info.id,
4163 windows->info.screen);
4166 if ((x > (
int) (windows->info.x+windows->info.width)) ||
4167 (y > (int) (windows->info.y+windows->info.height)))
4168 (void) XMapWindow(display,windows->info.id);
4169 composite_info.x=(ssize_t) windows->image.x+x;
4170 composite_info.y=(ssize_t) windows->image.y+y;
4175 if (resource_info->debug != MagickFalse)
4176 (void) LogMagickEvent(X11Event,GetMagickModule(),
"Event type: %d",
4181 }
while ((state & ExitState) == 0);
4182 (void) XSelectInput(display,windows->image.id,
4183 windows->image.attributes.event_mask);
4184 (void) XSetFunction(display,windows->image.highlight_context,GXcopy);
4185 XSetCursorState(display,windows,MagickFalse);
4186 (void) XFreeCursor(display,cursor);
4187 if ((state & EscapeState) != 0)
4192 XSetCursorState(display,windows,MagickTrue);
4193 XCheckRefreshWindows(display,windows);
4194 width=(
unsigned int) image->columns;
4195 height=(
unsigned int) image->rows;
4198 if (windows->image.crop_geometry != (
char *) NULL)
4199 (
void) XParseGeometry(windows->image.crop_geometry,&x,&y,&width,&height);
4200 scale_factor=(MagickRealType) width/windows->image.ximage->width;
4201 composite_info.x+=x;
4202 composite_info.x=(ssize_t) (scale_factor*composite_info.x+0.5);
4203 composite_info.width=(
unsigned int) (scale_factor*composite_info.width+0.5);
4204 scale_factor=(MagickRealType) height/windows->image.ximage->height;
4205 composite_info.y+=y;
4206 composite_info.y=(ssize_t) (scale_factor*composite_info.y+0.5);
4207 composite_info.height=(
unsigned int) (scale_factor*composite_info.height+0.5);
4208 if ((composite_info.width != composite_image->columns) ||
4209 (composite_info.height != composite_image->rows))
4217 resize_image=ResizeImage(composite_image,composite_info.width,
4218 composite_info.height,composite_image->filter,composite_image->blur,
4220 composite_image=DestroyImage(composite_image);
4221 if (resize_image == (
Image *) NULL)
4223 XSetCursorState(display,windows,MagickFalse);
4224 return(MagickFalse);
4226 composite_image=resize_image;
4228 if (compose == DisplaceCompositeOp)
4229 (void) SetImageArtifact(composite_image,
"compose:args",
4230 displacement_geometry);
4254 (void) SetImageAlphaChannel(composite_image,OpaqueAlphaChannel);
4255 opacity=(Quantum) (ScaleQuantumToChar(QuantumRange)-
4256 ((ssize_t) ScaleQuantumToChar(QuantumRange)*blend)/100);
4257 if (SetImageStorageClass(image,DirectClass) == MagickFalse)
4258 return(MagickFalse);
4259 image->matte=MagickTrue;
4260 exception=(&image->exception);
4261 image_view=AcquireAuthenticCacheView(image,exception);
4262 for (y=0; y < (int) image->rows; y++)
4264 q=GetCacheViewAuthenticPixels(image_view,0,(ssize_t) y,image->columns,1,
4268 for (x=0; x < (int) image->columns; x++)
4273 if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
4276 image_view=DestroyCacheView(image_view);
4281 (void) CompositeImage(image,compose,composite_image,composite_info.x,
4283 composite_image=DestroyImage(composite_image);
4284 XSetCursorState(display,windows,MagickFalse);
4288 XConfigureImageColormap(display,resource_info,windows,image);
4289 (void) XConfigureImage(display,resource_info,windows,image);
4325static MagickBooleanType XConfigureImage(Display *display,
4326 XResourceInfo *resource_info,XWindows *windows,
Image *image)
4329 geometry[MaxTextExtent];
4352 width=(
unsigned int) windows->image.window_changes.width;
4353 height=(
unsigned int) windows->image.window_changes.height;
4354 if (resource_info->debug != MagickFalse)
4355 (void) LogMagickEvent(X11Event,GetMagickModule(),
4356 "Configure Image: %dx%d=>%.20gx%.20g",windows->image.ximage->width,
4357 windows->image.ximage->height,(double) width,(
double) height);
4358 if ((width*height) == 0)
4365 XSetCursorState(display,windows,MagickTrue);
4366 (void) XFlush(display);
4367 if (((
int) width != windows->image.ximage->width) ||
4368 ((int) height != windows->image.ximage->height))
4369 image->taint=MagickTrue;
4370 windows->magnify.x=(
int)
4371 width*windows->magnify.x/windows->image.ximage->width;
4372 windows->magnify.y=(int)
4373 height*windows->magnify.y/windows->image.ximage->height;
4374 windows->image.x=(
int) (width*windows->image.x/windows->image.ximage->width);
4375 windows->image.y=(int)
4376 (height*windows->image.y/windows->image.ximage->height);
4377 status=XMakeImage(display,resource_info,&windows->image,image,
4378 (
unsigned int) width,(
unsigned int) height);
4379 if (status == MagickFalse)
4380 XNoticeWidget(display,windows,
"Unable to configure X image:",
4381 windows->image.name);
4385 if (resource_info->image_geometry != (
char *) NULL)
4386 (void) FormatLocaleString(geometry,MaxTextExtent,
"%s>!",
4387 resource_info->image_geometry);
4389 (
void) FormatLocaleString(geometry,MaxTextExtent,
"%ux%u+0+0>!",
4390 XDisplayWidth(display,windows->image.screen),
4391 XDisplayHeight(display,windows->image.screen));
4392 (void) ParseMetaGeometry(geometry,&x,&y,&width,&height);
4393 window_changes.width=(int) width;
4394 if (window_changes.width > XDisplayWidth(display,windows->image.screen))
4395 window_changes.width=XDisplayWidth(display,windows->image.screen);
4396 window_changes.height=(int) height;
4397 if (window_changes.height > XDisplayHeight(display,windows->image.screen))
4398 window_changes.height=XDisplayHeight(display,windows->image.screen);
4399 mask=(size_t) (CWWidth | CWHeight);
4400 if (resource_info->backdrop)
4403 window_changes.x=(int)
4404 ((XDisplayWidth(display,windows->image.screen)/2)-(width/2));
4405 window_changes.y=(int)
4406 ((XDisplayHeight(display,windows->image.screen)/2)-(height/2));
4408 (void) XReconfigureWMWindow(display,windows->image.id,windows->image.screen,
4409 (
unsigned int) mask,&window_changes);
4410 (void) XClearWindow(display,windows->image.id);
4411 XRefreshWindow(display,&windows->image,(XEvent *) NULL);
4415 if (windows->magnify.mapped != MagickFalse)
4416 XMakeMagnifyImage(display,windows);
4417 windows->pan.crop_geometry=windows->image.crop_geometry;
4418 XBestIconSize(display,&windows->pan,image);
4419 while (((windows->pan.width << 1) < MaxIconSize) &&
4420 ((windows->pan.height << 1) < MaxIconSize))
4422 windows->pan.width<<=1;
4423 windows->pan.height<<=1;
4425 if (windows->pan.geometry != (
char *) NULL)
4426 (void) XParseGeometry(windows->pan.geometry,&windows->pan.x,&windows->pan.y,
4427 &windows->pan.width,&windows->pan.height);
4428 window_changes.width=(int) windows->pan.width;
4429 window_changes.height=(
int) windows->pan.height;
4430 size_hints=XAllocSizeHints();
4431 if (size_hints != (XSizeHints *) NULL)
4436 size_hints->flags=PSize | PMinSize | PMaxSize;
4437 size_hints->width=window_changes.width;
4438 size_hints->height=window_changes.height;
4439 size_hints->min_width=size_hints->width;
4440 size_hints->min_height=size_hints->height;
4441 size_hints->max_width=size_hints->width;
4442 size_hints->max_height=size_hints->height;
4443 (void) XSetNormalHints(display,windows->pan.id,size_hints);
4444 (void) XFree((
void *) size_hints);
4446 (void) XReconfigureWMWindow(display,windows->pan.id,windows->pan.screen,
4447 (
unsigned int) (CWWidth | CWHeight),&window_changes);
4451 windows->icon.crop_geometry=windows->image.crop_geometry;
4452 XBestIconSize(display,&windows->icon,image);
4453 window_changes.width=(int) windows->icon.width;
4454 window_changes.height=(
int) windows->icon.height;
4455 (void) XReconfigureWMWindow(display,windows->icon.id,windows->icon.screen,
4456 (
unsigned int) (CWWidth | CWHeight),&window_changes);
4457 XSetCursorState(display,windows,MagickFalse);
4458 return(status != 0 ? MagickTrue : MagickFalse);
4497static MagickBooleanType XCropImage(Display *display,
4498 XResourceInfo *resource_info,XWindows *windows,
Image *image,
4499 const ClipboardMode mode)
4508 *RectifyModeMenu[] =
4516 static const ModeType
4526 RectifyDismissCommand
4533 command[MaxTextExtent],
4534 text[MaxTextExtent];
4580 (void) CloneString(&windows->command.name,
"Copy");
4585 (void) CloneString(&windows->command.name,
"Crop");
4590 (void) CloneString(&windows->command.name,
"Cut");
4594 RectifyModeMenu[0]=windows->command.name;
4595 windows->command.data=0;
4596 (void) XCommandWidget(display,windows,CropModeMenu,(XEvent *) NULL);
4597 (void) XMapRaised(display,windows->command.id);
4598 XClientMessage(display,windows->image.id,windows->im_protocols,
4599 windows->im_update_widget,CurrentTime);
4603 XQueryPosition(display,windows->image.id,&x,&y);
4604 (void) XSelectInput(display,windows->image.id,
4605 windows->image.attributes.event_mask | PointerMotionMask);
4606 crop_info.x=(ssize_t) windows->image.x+x;
4607 crop_info.y=(ssize_t) windows->image.y+y;
4610 cursor=XCreateFontCursor(display,XC_fleur);
4614 if (windows->info.mapped != MagickFalse)
4619 (void) FormatLocaleString(text,MaxTextExtent,
" %+ld%+ld ",
4620 (
long) crop_info.x,(long) crop_info.y);
4621 XInfoWidget(display,windows,text);
4626 XScreenEvent(display,windows,&event);
4627 if (event.xany.window == windows->command.id)
4632 id=XCommandWidget(display,windows,CropModeMenu,&event);
4635 switch (CropCommands[
id])
4637 case CropHelpCommand:
4643 XTextViewHelp(display,resource_info,windows,MagickFalse,
4644 "Help Viewer - Image Copy",ImageCopyHelp);
4649 XTextViewHelp(display,resource_info,windows,MagickFalse,
4650 "Help Viewer - Image Crop",ImageCropHelp);
4655 XTextViewHelp(display,resource_info,windows,MagickFalse,
4656 "Help Viewer - Image Cut",ImageCutHelp);
4662 case CropDismissCommand:
4680 if (event.xbutton.button != Button1)
4682 if (event.xbutton.window != windows->image.id)
4687 (void) XCheckDefineCursor(display,windows->image.id,cursor);
4688 crop_info.x=(ssize_t) windows->image.x+event.xbutton.x;
4689 crop_info.y=(ssize_t) windows->image.y+
event.xbutton.y;
4699 if (event.xkey.window != windows->image.id)
4704 (void) XLookupString((XKeyEvent *) &
event.xkey,command,(int)
4705 sizeof(command),&key_symbol,(XComposeStatus *) NULL);
4706 switch ((
int) key_symbol)
4725 XTextViewHelp(display,resource_info,windows,MagickFalse,
4726 "Help Viewer - Image Copy",ImageCopyHelp);
4731 XTextViewHelp(display,resource_info,windows,MagickFalse,
4732 "Help Viewer - Image Crop",ImageCropHelp);
4737 XTextViewHelp(display,resource_info,windows,MagickFalse,
4738 "Help Viewer - Image Cut",ImageCutHelp);
4746 (void) XBell(display,0);
4754 if (event.xmotion.window != windows->image.id)
4761 if (windows->info.mapped != MagickFalse)
4763 if ((x < (
int) (windows->info.x+windows->info.width)) &&
4764 (y < (int) (windows->info.y+windows->info.height)))
4765 (void) XWithdrawWindow(display,windows->info.id,
4766 windows->info.screen);
4769 if ((x > (
int) (windows->info.x+windows->info.width)) ||
4770 (y > (int) (windows->info.y+windows->info.height)))
4771 (void) XMapWindow(display,windows->info.id);
4772 crop_info.x=(ssize_t) windows->image.x+x;
4773 crop_info.y=(ssize_t) windows->image.y+y;
4779 }
while ((state & ExitState) == 0);
4780 (void) XSelectInput(display,windows->image.id,
4781 windows->image.attributes.event_mask);
4782 if ((state & EscapeState) != 0)
4787 (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
4788 (void) XFreeCursor(display,cursor);
4791 (void) XSetFunction(display,windows->image.highlight_context,GXinvert);
4797 x=(int) crop_info.x;
4798 y=(
int) crop_info.y;
4804 highlight_info=crop_info;
4805 highlight_info.x=crop_info.x-windows->image.x;
4806 highlight_info.y=crop_info.y-windows->image.y;
4807 if ((highlight_info.width > 3) && (highlight_info.height > 3))
4812 if (windows->info.mapped == MagickFalse)
4813 (void) XMapWindow(display,windows->info.id);
4814 (void) FormatLocaleString(text,MaxTextExtent,
4815 " %.20gx%.20g%+.20g%+.20g",(
double) crop_info.width,(double)
4816 crop_info.height,(
double) crop_info.x,(double) crop_info.y);
4817 XInfoWidget(display,windows,text);
4818 XHighlightRectangle(display,windows->image.id,
4819 windows->image.highlight_context,&highlight_info);
4822 if (windows->info.mapped != MagickFalse)
4823 (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
4827 XScreenEvent(display,windows,&event);
4828 if ((highlight_info.width > 3) && (highlight_info.height > 3))
4829 XHighlightRectangle(display,windows->image.id,
4830 windows->image.highlight_context,&highlight_info);
4835 crop_info.x=(ssize_t) windows->image.x+event.xbutton.x;
4836 crop_info.y=(ssize_t) windows->image.y+
event.xbutton.y;
4844 crop_info.x=(ssize_t) windows->image.x+event.xbutton.x;
4845 crop_info.y=(ssize_t) windows->image.y+
event.xbutton.y;
4846 XSetCursorState(display,windows,MagickFalse);
4848 windows->command.data=0;
4849 (void) XCommandWidget(display,windows,RectifyModeMenu,
4857 crop_info.x=(ssize_t) windows->image.x+event.xmotion.x;
4858 crop_info.y=(ssize_t) windows->image.y+
event.xmotion.y;
4863 if ((((
int) crop_info.x != x) && ((int) crop_info.y != y)) ||
4864 ((state & ExitState) != 0))
4869 if (crop_info.x < 0)
4872 if (crop_info.x > (ssize_t) windows->image.ximage->width)
4873 crop_info.x=(ssize_t) windows->image.ximage->width;
4874 if ((
int) crop_info.x < x)
4875 crop_info.width=(
unsigned int) (x-crop_info.x);
4878 crop_info.width=(
unsigned int) (crop_info.x-x);
4879 crop_info.x=(ssize_t) x;
4881 if (crop_info.y < 0)
4884 if (crop_info.y > (ssize_t) windows->image.ximage->height)
4885 crop_info.y=(ssize_t) windows->image.ximage->height;
4886 if ((
int) crop_info.y < y)
4887 crop_info.height=(
unsigned int) (y-crop_info.y);
4890 crop_info.height=(
unsigned int) (crop_info.y-y);
4891 crop_info.y=(ssize_t) y;
4894 }
while ((state & ExitState) == 0);
4899 (void) XMapWindow(display,windows->info.id);
4902 if (windows->info.mapped != MagickFalse)
4907 (void) FormatLocaleString(text,MaxTextExtent,
4908 " %.20gx%.20g%+.20g%+.20g",(
double) crop_info.width,(double)
4909 crop_info.height,(
double) crop_info.x,(double) crop_info.y);
4910 XInfoWidget(display,windows,text);
4912 highlight_info=crop_info;
4913 highlight_info.x=crop_info.x-windows->image.x;
4914 highlight_info.y=crop_info.y-windows->image.y;
4915 if ((highlight_info.width <= 3) || (highlight_info.height <= 3))
4921 XHighlightRectangle(display,windows->image.id,
4922 windows->image.highlight_context,&highlight_info);
4923 XScreenEvent(display,windows,&event);
4924 if (event.xany.window == windows->command.id)
4929 (void) XSetFunction(display,windows->image.highlight_context,GXcopy);
4930 id=XCommandWidget(display,windows,RectifyModeMenu,&event);
4931 (void) XSetFunction(display,windows->image.highlight_context,
4933 XHighlightRectangle(display,windows->image.id,
4934 windows->image.highlight_context,&highlight_info);
4936 switch (RectifyCommands[
id])
4938 case RectifyCopyCommand:
4943 case RectifyHelpCommand:
4945 (void) XSetFunction(display,windows->image.highlight_context,
4951 XTextViewHelp(display,resource_info,windows,MagickFalse,
4952 "Help Viewer - Image Copy",ImageCopyHelp);
4957 XTextViewHelp(display,resource_info,windows,MagickFalse,
4958 "Help Viewer - Image Crop",ImageCropHelp);
4963 XTextViewHelp(display,resource_info,windows,MagickFalse,
4964 "Help Viewer - Image Cut",ImageCutHelp);
4968 (void) XSetFunction(display,windows->image.highlight_context,
4972 case RectifyDismissCommand:
4986 XHighlightRectangle(display,windows->image.id,
4987 windows->image.highlight_context,&highlight_info);
4992 if (event.xbutton.button != Button1)
4994 if (event.xbutton.window != windows->image.id)
4996 x=windows->image.x+
event.xbutton.x;
4997 y=windows->image.y+
event.xbutton.y;
4998 if ((x < (
int) (crop_info.x+RoiDelta)) &&
4999 (x > (
int) (crop_info.x-RoiDelta)) &&
5000 (y < (
int) (crop_info.y+RoiDelta)) &&
5001 (y > (
int) (crop_info.y-RoiDelta)))
5003 crop_info.x=(ssize_t) (crop_info.x+crop_info.width);
5004 crop_info.y=(ssize_t) (crop_info.y+crop_info.height);
5005 state|=UpdateConfigurationState;
5008 if ((x < (
int) (crop_info.x+RoiDelta)) &&
5009 (x > (int) (crop_info.x-RoiDelta)) &&
5010 (y < (
int) (crop_info.y+crop_info.height+RoiDelta)) &&
5011 (y > (int) (crop_info.y+crop_info.height-RoiDelta)))
5013 crop_info.x=(ssize_t) (crop_info.x+crop_info.width);
5014 state|=UpdateConfigurationState;
5017 if ((x < (
int) (crop_info.x+crop_info.width+RoiDelta)) &&
5018 (x > (int) (crop_info.x+crop_info.width-RoiDelta)) &&
5019 (y < (
int) (crop_info.y+RoiDelta)) &&
5020 (y > (int) (crop_info.y-RoiDelta)))
5022 crop_info.y=(ssize_t) (crop_info.y+crop_info.height);
5023 state|=UpdateConfigurationState;
5026 if ((x < (
int) (crop_info.x+crop_info.width+RoiDelta)) &&
5027 (x > (int) (crop_info.x+crop_info.width-RoiDelta)) &&
5028 (y < (
int) (crop_info.y+crop_info.height+RoiDelta)) &&
5029 (y > (int) (crop_info.y+crop_info.height-RoiDelta)))
5031 state|=UpdateConfigurationState;
5038 if (event.xbutton.window == windows->pan.id)
5039 if ((highlight_info.x != crop_info.x-windows->image.x) ||
5040 (highlight_info.y != crop_info.y-windows->image.y))
5041 XHighlightRectangle(display,windows->image.id,
5042 windows->image.highlight_context,&highlight_info);
5043 (void) XSetSelectionOwner(display,XA_PRIMARY,windows->image.id,
5044 event.xbutton.time);
5049 if (event.xexpose.window == windows->image.id)
5050 if (event.xexpose.count == 0)
5052 event.xexpose.x=(int) highlight_info.x;
5053 event.xexpose.y=(
int) highlight_info.y;
5054 event.xexpose.width=(int) highlight_info.width;
5055 event.xexpose.height=(
int) highlight_info.height;
5056 XRefreshWindow(display,&windows->image,&event);
5058 if (event.xexpose.window == windows->info.id)
5059 if (event.xexpose.count == 0)
5060 XInfoWidget(display,windows,text);
5065 if (event.xkey.window != windows->image.id)
5070 (void) XLookupString((XKeyEvent *) &
event.xkey,command,(int)
5071 sizeof(command),&key_symbol,(XComposeStatus *) NULL);
5072 switch ((
int) key_symbol)
5088 crop_info.x=(ssize_t) (windows->image.width/2L-crop_info.width/
5090 crop_info.y=(ssize_t) (windows->image.height/2L-crop_info.height/
5123 (void) XSetFunction(display,windows->image.highlight_context,
5129 XTextViewHelp(display,resource_info,windows,MagickFalse,
5130 "Help Viewer - Image Copy",ImageCopyHelp);
5135 XTextViewHelp(display,resource_info,windows,MagickFalse,
5136 "Help Viewer - Image Cropg",ImageCropHelp);
5141 XTextViewHelp(display,resource_info,windows,MagickFalse,
5142 "Help Viewer - Image Cutg",ImageCutHelp);
5146 (void) XSetFunction(display,windows->image.highlight_context,
5152 (void) XBell(display,0);
5156 (void) XSetSelectionOwner(display,XA_PRIMARY,windows->image.id,
5164 if (event.xmotion.window != windows->image.id)
5171 if (windows->info.mapped != MagickFalse)
5173 if ((x < (
int) (windows->info.x+windows->info.width)) &&
5174 (y < (int) (windows->info.y+windows->info.height)))
5175 (void) XWithdrawWindow(display,windows->info.id,
5176 windows->info.screen);
5179 if ((x > (
int) (windows->info.x+windows->info.width)) ||
5180 (y > (int) (windows->info.y+windows->info.height)))
5181 (void) XMapWindow(display,windows->info.id);
5182 crop_info.x=(ssize_t) windows->image.x+event.xmotion.x;
5183 crop_info.y=(ssize_t) windows->image.y+
event.xmotion.y;
5186 case SelectionRequest:
5191 XSelectionRequestEvent
5197 (void) FormatLocaleString(text,MaxTextExtent,
5198 "%.20gx%.20g%+.20g%+.20g",(
double) crop_info.width,(double)
5199 crop_info.height,(
double) crop_info.x,(double) crop_info.y);
5200 request=(&(
event.xselectionrequest));
5201 (void) XChangeProperty(request->display,request->requestor,
5202 request->property,request->target,8,PropModeReplace,
5203 (
unsigned char *) text,(int) strlen(text));
5204 notify.type=SelectionNotify;
5205 notify.display=request->display;
5206 notify.requestor=request->requestor;
5207 notify.selection=request->selection;
5208 notify.target=request->target;
5209 notify.time=request->time;
5210 if (request->property == None)
5211 notify.property=request->target;
5213 notify.property=request->property;
5214 (void) XSendEvent(request->display,request->requestor,False,0,
5215 (XEvent *) ¬ify);
5220 if ((state & UpdateConfigurationState) != 0)
5222 (void) XPutBackEvent(display,&event);
5223 (void) XCheckDefineCursor(display,windows->image.id,cursor);
5226 }
while ((state & ExitState) == 0);
5227 }
while ((state & ExitState) == 0);
5228 (void) XSetFunction(display,windows->image.highlight_context,GXcopy);
5229 XSetCursorState(display,windows,MagickFalse);
5230 if ((state & EscapeState) != 0)
5232 if (mode == CropMode)
5233 if (((
int) crop_info.width != windows->image.ximage->width) ||
5234 ((
int) crop_info.height != windows->image.ximage->height))
5239 XSetCropGeometry(display,windows,&crop_info,image);
5240 windows->image.window_changes.width=(int) crop_info.width;
5241 windows->image.window_changes.height=(
int) crop_info.height;
5242 (void) XConfigureImage(display,resource_info,windows,image);
5248 XSetCursorState(display,windows,MagickTrue);
5249 XCheckRefreshWindows(display,windows);
5250 width=(
unsigned int) image->columns;
5251 height=(
unsigned int) image->rows;
5254 if (windows->image.crop_geometry != (
char *) NULL)
5255 (
void) XParseGeometry(windows->image.crop_geometry,&x,&y,&width,&height);
5256 scale_factor=(MagickRealType) width/windows->image.ximage->width;
5258 crop_info.x=(ssize_t) (scale_factor*crop_info.x+0.5);
5259 crop_info.x+=image->page.x;
5260 crop_info.width=(
unsigned int) (scale_factor*crop_info.width+0.5);
5261 scale_factor=(MagickRealType) height/windows->image.ximage->height;
5263 crop_info.y=(ssize_t) (scale_factor*crop_info.y+0.5);
5264 crop_info.y+=image->page.y;
5265 crop_info.height=(
unsigned int) (scale_factor*crop_info.height+0.5);
5266 crop_image=CropImage(image,&crop_info,&image->exception);
5267 XSetCursorState(display,windows,MagickFalse);
5268 if (crop_image == (
Image *) NULL)
5269 return(MagickFalse);
5270 if (resource_info->copy_image != (
Image *) NULL)
5271 resource_info->copy_image=DestroyImage(resource_info->copy_image);
5272 resource_info->copy_image=crop_image;
5273 if (mode == CopyMode)
5275 (void) XConfigureImage(display,resource_info,windows,image);
5281 if (SetImageStorageClass(image,DirectClass) == MagickFalse)
5282 return(MagickFalse);
5283 image->matte=MagickTrue;
5284 exception=(&image->exception);
5285 image_view=AcquireAuthenticCacheView(image,exception);
5286 for (y=0; y < (int) crop_info.height; y++)
5288 q=GetCacheViewAuthenticPixels(image_view,crop_info.x,y+crop_info.y,
5289 crop_info.width,1,exception);
5292 for (x=0; x < (int) crop_info.width; x++)
5294 q->opacity=(Quantum) TransparentOpacity;
5297 if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
5300 image_view=DestroyCacheView(image_view);
5304 XConfigureImageColormap(display,resource_info,windows,image);
5305 (void) XConfigureImage(display,resource_info,windows,image);
5340static MagickBooleanType XDrawEditImage(Display *display,
5341 XResourceInfo *resource_info,XWindows *windows,
Image **image)
5357 element = PointElement;
5359 static const ModeType
5372 stipple = (Pixmap) NULL;
5379 command[MaxTextExtent],
5380 text[MaxTextExtent];
5431 max_coordinates=2048;
5432 coordinate_info=(XPoint *) AcquireQuantumMemory((
size_t) max_coordinates,
5433 sizeof(*coordinate_info));
5434 if (coordinate_info == (XPoint *) NULL)
5436 (void) ThrowMagickException(&(*image)->exception,GetMagickModule(),
5437 ResourceLimitError,
"MemoryAllocationFailed",
"`%s'",
"...");
5438 return(MagickFalse);
5443 (void) CloneString(&windows->command.name,
"Draw");
5444 windows->command.data=4;
5445 (void) XCommandWidget(display,windows,DrawMenu,(XEvent *) NULL);
5446 (void) XMapRaised(display,windows->command.id);
5447 XClientMessage(display,windows->image.id,windows->im_protocols,
5448 windows->im_update_widget,CurrentTime);
5452 root_window=XRootWindow(display,XDefaultScreen(display));
5453 draw_info.stencil=OpaqueStencil;
5455 cursor=XCreateFontCursor(display,XC_tcross);
5458 XQueryPosition(display,windows->image.id,&x,&y);
5459 (void) XSelectInput(display,windows->image.id,
5460 windows->image.attributes.event_mask | PointerMotionMask);
5461 (void) XCheckDefineCursor(display,windows->image.id,cursor);
5465 if (windows->info.mapped != MagickFalse)
5470 (void) FormatLocaleString(text,MaxTextExtent,
" %+d%+d ",
5471 x+windows->image.x,y+windows->image.y);
5472 XInfoWidget(display,windows,text);
5477 XScreenEvent(display,windows,&event);
5478 if (event.xany.window == windows->command.id)
5483 id=XCommandWidget(display,windows,DrawMenu,&event);
5486 switch (DrawCommands[
id])
5488 case DrawElementCommand:
5509 element=(ElementType) (XMenuWidget(display,windows,
5510 DrawMenu[
id],Elements,command)+1);
5513 case DrawColorCommand:
5516 *ColorMenu[MaxNumberPens+1];
5530 for (i=0; i < (int) (MaxNumberPens-2); i++)
5531 ColorMenu[i]=resource_info->pen_colors[i];
5532 ColorMenu[MaxNumberPens-2]=
"transparent";
5533 ColorMenu[MaxNumberPens-1]=
"Browser...";
5534 ColorMenu[MaxNumberPens]=(
char *) NULL;
5538 pen_number=XMenuWidget(display,windows,DrawMenu[
id],
5539 (
const char **) ColorMenu,command);
5542 transparent=pen_number == (MaxNumberPens-2) ? MagickTrue :
5544 if (transparent != MagickFalse)
5546 draw_info.stencil=TransparentStencil;
5549 if (pen_number == (MaxNumberPens-1))
5552 color_name[MaxTextExtent] =
"gray";
5557 resource_info->pen_colors[pen_number]=color_name;
5558 XColorBrowserWidget(display,windows,
"Select",color_name);
5559 if (*color_name ==
'\0')
5565 (void) XParseColor(display,windows->map_info->colormap,
5566 resource_info->pen_colors[pen_number],&color);
5567 XBestPixel(display,windows->map_info->colormap,(XColor *) NULL,
5568 (
unsigned int) MaxColors,&color);
5569 windows->pixel_info->pen_colors[pen_number]=color;
5570 pen_id=(
unsigned int) pen_number;
5571 draw_info.stencil=OpaqueStencil;
5574 case DrawStippleCommand:
5600 filename[MaxTextExtent] =
"\0";
5605 StipplesMenu[7]=
"Open...";
5606 entry=XMenuWidget(display,windows,DrawMenu[
id],StipplesMenu,
5610 if (stipple != (Pixmap) NULL)
5611 (void) XFreePixmap(display,stipple);
5612 stipple=(Pixmap) NULL;
5619 stipple=XCreateBitmapFromData(display,root_window,
5620 (
char *) BricksBitmap,BricksWidth,BricksHeight);
5625 stipple=XCreateBitmapFromData(display,root_window,
5626 (
char *) DiagonalBitmap,DiagonalWidth,DiagonalHeight);
5631 stipple=XCreateBitmapFromData(display,root_window,
5632 (
char *) ScalesBitmap,ScalesWidth,ScalesHeight);
5637 stipple=XCreateBitmapFromData(display,root_window,
5638 (
char *) VerticalBitmap,VerticalWidth,VerticalHeight);
5643 stipple=XCreateBitmapFromData(display,root_window,
5644 (
char *) WavyBitmap,WavyWidth,WavyHeight);
5649 stipple=XCreateBitmapFromData(display,root_window,
5650 (
char *) HighlightBitmap,HighlightWidth,
5657 stipple=XCreateBitmapFromData(display,root_window,
5658 (
char *) OpaqueBitmap,OpaqueWidth,OpaqueHeight);
5664 XFileBrowserWidget(display,windows,
"Stipple",filename);
5665 if (*filename ==
'\0')
5670 XSetCursorState(display,windows,MagickTrue);
5671 XCheckRefreshWindows(display,windows);
5672 image_info=AcquireImageInfo();
5673 (void) CopyMagickString(image_info->filename,filename,
5675 stipple_image=ReadImage(image_info,&(*image)->exception);
5676 CatchException(&(*image)->exception);
5677 XSetCursorState(display,windows,MagickFalse);
5678 if (stipple_image == (
Image *) NULL)
5680 (void) AcquireUniqueFileResource(filename);
5681 (void) FormatLocaleString(stipple_image->filename,MaxTextExtent,
5683 (void) WriteImage(image_info,stipple_image);
5684 stipple_image=DestroyImage(stipple_image);
5685 image_info=DestroyImageInfo(image_info);
5686 status=XReadBitmapFile(display,root_window,filename,&width,
5687 &height,&stipple,&x,&y);
5688 (void) RelinquishUniqueFileResource(filename);
5689 if ((status != BitmapSuccess) != 0)
5690 XNoticeWidget(display,windows,
"Unable to read X bitmap image:",
5694 case DrawWidthCommand:
5697 *
const WidthsMenu[] =
5709 width[MaxTextExtent] =
"0";
5714 entry=XMenuWidget(display,windows,DrawMenu[
id],WidthsMenu,
5720 line_width=(
unsigned int) StringToUnsignedLong(
5724 (void) XDialogWidget(display,windows,
"Ok",
"Enter line width:",
5728 line_width=(
unsigned int) StringToUnsignedLong(width);
5731 case DrawUndoCommand:
5733 (void) XMagickCommand(display,resource_info,windows,UndoCommand,
5737 case DrawHelpCommand:
5739 XTextViewHelp(display,resource_info,windows,MagickFalse,
5740 "Help Viewer - Image Rotation",ImageDrawHelp);
5741 (void) XCheckDefineCursor(display,windows->image.id,cursor);
5744 case DrawDismissCommand:
5756 (void) XCheckDefineCursor(display,windows->image.id,cursor);
5763 if (event.xbutton.button != Button1)
5765 if (event.xbutton.window != windows->image.id)
5784 if (event.xkey.window != windows->image.id)
5789 (void) XLookupString((XKeyEvent *) &
event.xkey,command,(int)
5790 sizeof(command),&key_symbol,(XComposeStatus *) NULL);
5791 switch ((
int) key_symbol)
5806 XTextViewHelp(display,resource_info,windows,MagickFalse,
5807 "Help Viewer - Image Rotation",ImageDrawHelp);
5812 (void) XBell(display,0);
5825 if (windows->info.mapped != MagickFalse)
5827 if ((x < (
int) (windows->info.x+windows->info.width)) &&
5828 (y < (int) (windows->info.y+windows->info.height)))
5829 (void) XWithdrawWindow(display,windows->info.id,
5830 windows->info.screen);
5833 if ((x > (
int) (windows->info.x+windows->info.width)) ||
5834 (y > (int) (windows->info.y+windows->info.height)))
5835 (void) XMapWindow(display,windows->info.id);
5839 }
while ((state & ExitState) == 0);
5840 (void) XSelectInput(display,windows->image.id,
5841 windows->image.attributes.event_mask);
5842 (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
5843 if ((state & EscapeState) != 0)
5854 rectangle_info.x=(ssize_t) x;
5855 rectangle_info.y=(ssize_t) y;
5856 rectangle_info.width=0;
5857 rectangle_info.height=0;
5858 number_coordinates=1;
5859 coordinate_info->x=x;
5860 coordinate_info->y=y;
5861 (void) XSetFunction(display,windows->image.highlight_context,GXinvert);
5870 if (number_coordinates > 1)
5872 (void) XDrawLines(display,windows->image.id,
5873 windows->image.highlight_context,coordinate_info,
5874 number_coordinates,CoordModeOrigin);
5875 (void) FormatLocaleString(text,MaxTextExtent,
" %+d%+d",
5876 coordinate_info[number_coordinates-1].x,
5877 coordinate_info[number_coordinates-1].y);
5878 XInfoWidget(display,windows,text);
5889 degrees=RadiansToDegrees(-atan2((
double) (line_info.y2-
5890 line_info.y1),(
double) (line_info.x2-line_info.x1)));
5891 (void) FormatLocaleString(text,MaxTextExtent,
" %g",
5893 XInfoWidget(display,windows,text);
5894 XHighlightLine(display,windows->image.id,
5895 windows->image.highlight_context,&line_info);
5898 if (windows->info.mapped != MagickFalse)
5899 (void) XWithdrawWindow(display,windows->info.id,
5900 windows->info.screen);
5903 case RectangleElement:
5904 case FillRectangleElement:
5906 if ((rectangle_info.width > 3) && (rectangle_info.height > 3))
5911 (void) FormatLocaleString(text,MaxTextExtent,
5912 " %.20gx%.20g%+.20g%+.20g",(
double) rectangle_info.width,
5913 (double) rectangle_info.height,(
double) rectangle_info.x,
5914 (double) rectangle_info.y);
5915 XInfoWidget(display,windows,text);
5916 XHighlightRectangle(display,windows->image.id,
5917 windows->image.highlight_context,&rectangle_info);
5920 if (windows->info.mapped != MagickFalse)
5921 (void) XWithdrawWindow(display,windows->info.id,
5922 windows->info.screen);
5926 case FillCircleElement:
5927 case EllipseElement:
5928 case FillEllipseElement:
5930 if ((rectangle_info.width > 3) && (rectangle_info.height > 3))
5935 (void) FormatLocaleString(text,MaxTextExtent,
5936 " %.20gx%.20g%+.20g%+.20g",(
double) rectangle_info.width,
5937 (double) rectangle_info.height,(
double) rectangle_info.x,
5938 (double) rectangle_info.y);
5939 XInfoWidget(display,windows,text);
5940 XHighlightEllipse(display,windows->image.id,
5941 windows->image.highlight_context,&rectangle_info);
5944 if (windows->info.mapped != MagickFalse)
5945 (void) XWithdrawWindow(display,windows->info.id,
5946 windows->info.screen);
5949 case PolygonElement:
5950 case FillPolygonElement:
5952 if (number_coordinates > 1)
5953 (void) XDrawLines(display,windows->image.id,
5954 windows->image.highlight_context,coordinate_info,
5955 number_coordinates,CoordModeOrigin);
5961 degrees=RadiansToDegrees(-atan2((
double) (line_info.y2-
5962 line_info.y1),(
double) (line_info.x2-line_info.x1)));
5963 (void) FormatLocaleString(text,MaxTextExtent,
" %g",
5965 XInfoWidget(display,windows,text);
5966 XHighlightLine(display,windows->image.id,
5967 windows->image.highlight_context,&line_info);
5970 if (windows->info.mapped != MagickFalse)
5971 (void) XWithdrawWindow(display,windows->info.id,
5972 windows->info.screen);
5979 XScreenEvent(display,windows,&event);
5985 if (number_coordinates > 1)
5986 (void) XDrawLines(display,windows->image.id,
5987 windows->image.highlight_context,coordinate_info,
5988 number_coordinates,CoordModeOrigin);
5994 XHighlightLine(display,windows->image.id,
5995 windows->image.highlight_context,&line_info);
5998 case RectangleElement:
5999 case FillRectangleElement:
6001 if ((rectangle_info.width > 3) && (rectangle_info.height > 3))
6002 XHighlightRectangle(display,windows->image.id,
6003 windows->image.highlight_context,&rectangle_info);
6007 case FillCircleElement:
6008 case EllipseElement:
6009 case FillEllipseElement:
6011 if ((rectangle_info.width > 3) && (rectangle_info.height > 3))
6012 XHighlightEllipse(display,windows->image.id,
6013 windows->image.highlight_context,&rectangle_info);
6016 case PolygonElement:
6017 case FillPolygonElement:
6019 if (number_coordinates > 1)
6020 (void) XDrawLines(display,windows->image.id,
6021 windows->image.highlight_context,coordinate_info,
6022 number_coordinates,CoordModeOrigin);
6024 XHighlightLine(display,windows->image.id,
6025 windows->image.highlight_context,&line_info);
6038 line_info.x2=
event.xbutton.x;
6039 line_info.y2=
event.xbutton.y;
6040 rectangle_info.x=(ssize_t) event.xbutton.x;
6041 rectangle_info.y=(ssize_t)
event.xbutton.y;
6042 coordinate_info[number_coordinates].x=
event.xbutton.x;
6043 coordinate_info[number_coordinates].y=
event.xbutton.y;
6044 if (((element != PolygonElement) &&
6045 (element != FillPolygonElement)) || (distance <= 9))
6050 number_coordinates++;
6051 if (number_coordinates < (
int) max_coordinates)
6053 line_info.x1=
event.xbutton.x;
6054 line_info.y1=
event.xbutton.y;
6057 max_coordinates<<=1;
6058 coordinate_info=(XPoint *) ResizeQuantumMemory(coordinate_info,
6059 max_coordinates,
sizeof(*coordinate_info));
6060 if (coordinate_info == (XPoint *) NULL)
6061 (
void) ThrowMagickException(&(*image)->exception,GetMagickModule(),
6062 ResourceLimitError,
"MemoryAllocationFailed",
"`%s'",
"...");
6069 if (event.xmotion.window != windows->image.id)
6071 if (element != PointElement)
6073 line_info.x2=
event.xmotion.x;
6074 line_info.y2=
event.xmotion.y;
6075 rectangle_info.x=(ssize_t) event.xmotion.x;
6076 rectangle_info.y=(ssize_t)
event.xmotion.y;
6079 coordinate_info[number_coordinates].x=
event.xbutton.x;
6080 coordinate_info[number_coordinates].y=
event.xbutton.y;
6081 number_coordinates++;
6082 if (number_coordinates < (
int) max_coordinates)
6084 max_coordinates<<=1;
6085 coordinate_info=(XPoint *) ResizeQuantumMemory(coordinate_info,
6086 max_coordinates,
sizeof(*coordinate_info));
6087 if (coordinate_info == (XPoint *) NULL)
6088 (
void) ThrowMagickException(&(*image)->exception,GetMagickModule(),
6089 ResourceLimitError,
"MemoryAllocationFailed",
"`%s'",
"...");
6098 if (line_info.x2 < 0)
6101 if (line_info.x2 > (
int) windows->image.width)
6102 line_info.x2=(short) windows->image.width;
6103 if (line_info.y2 < 0)
6106 if (line_info.y2 > (
int) windows->image.height)
6107 line_info.y2=(
short) windows->image.height;
6108 distance=(
unsigned int)
6109 (((line_info.x2-line_info.x1+1)*(line_info.x2-line_info.x1+1))+
6110 ((line_info.y2-line_info.y1+1)*(line_info.y2-line_info.y1+1)));
6111 if ((((
int) rectangle_info.x != x) && ((
int) rectangle_info.y != y)) ||
6112 ((state & ExitState) != 0))
6114 if (rectangle_info.x < 0)
6117 if (rectangle_info.x > (ssize_t) windows->image.width)
6118 rectangle_info.x=(ssize_t) windows->image.width;
6119 if ((
int) rectangle_info.x < x)
6120 rectangle_info.width=(
unsigned int) (x-rectangle_info.x);
6123 rectangle_info.width=(
unsigned int) (rectangle_info.x-x);
6124 rectangle_info.x=(ssize_t) x;
6126 if (rectangle_info.y < 0)
6129 if (rectangle_info.y > (ssize_t) windows->image.height)
6130 rectangle_info.y=(ssize_t) windows->image.height;
6131 if ((
int) rectangle_info.y < y)
6132 rectangle_info.height=(
unsigned int) (y-rectangle_info.y);
6135 rectangle_info.height=(
unsigned int) (rectangle_info.y-y);
6136 rectangle_info.y=(ssize_t) y;
6139 }
while ((state & ExitState) == 0);
6140 (void) XSetFunction(display,windows->image.highlight_context,GXcopy);
6141 if ((element == PointElement) || (element == PolygonElement) ||
6142 (element == FillPolygonElement))
6147 rectangle_info.x=(ssize_t) coordinate_info->x;
6148 rectangle_info.y=(ssize_t) coordinate_info->y;
6149 x=coordinate_info->x;
6150 y=coordinate_info->y;
6151 for (i=1; i < number_coordinates; i++)
6153 if (coordinate_info[i].x > x)
6154 x=coordinate_info[i].x;
6155 if (coordinate_info[i].y > y)
6156 y=coordinate_info[i].y;
6157 if ((ssize_t) coordinate_info[i].x < rectangle_info.x)
6158 rectangle_info.x=MagickMax((ssize_t) coordinate_info[i].x,0);
6159 if ((ssize_t) coordinate_info[i].y < rectangle_info.y)
6160 rectangle_info.y=MagickMax((ssize_t) coordinate_info[i].y,0);
6162 rectangle_info.width=(size_t) (x-rectangle_info.x);
6163 rectangle_info.height=(size_t) (y-rectangle_info.y);
6164 for (i=0; i < number_coordinates; i++)
6166 coordinate_info[i].x-=rectangle_info.x;
6167 coordinate_info[i].y-=rectangle_info.y;
6174 if ((element == RectangleElement) ||
6175 (element == CircleElement) || (element == EllipseElement))
6177 rectangle_info.width--;
6178 rectangle_info.height--;
6183 draw_info.x=(int) rectangle_info.x;
6184 draw_info.y=(
int) rectangle_info.y;
6185 (void) XMagickCommand(display,resource_info,windows,SaveToUndoBufferCommand,
6187 width=(
unsigned int) (*image)->columns;
6188 height=(
unsigned int) (*image)->rows;
6191 if (windows->image.crop_geometry != (
char *) NULL)
6192 (
void) XParseGeometry(windows->image.crop_geometry,&x,&y,&width,&height);
6193 draw_info.x+=windows->image.x-(line_width/2);
6194 if (draw_info.x < 0)
6196 draw_info.x=(int) (width*draw_info.x/windows->image.ximage->width);
6197 draw_info.y+=windows->image.y-(line_width/2);
6198 if (draw_info.y < 0)
6200 draw_info.y=(int) height*draw_info.y/windows->image.ximage->height;
6201 draw_info.width=(
unsigned int) rectangle_info.width+(line_width << 1);
6202 if (draw_info.width > (
unsigned int) (*image)->columns)
6203 draw_info.width=(
unsigned int) (*image)->columns;
6204 draw_info.height=(
unsigned int) rectangle_info.height+(line_width << 1);
6205 if (draw_info.height > (
unsigned int) (*image)->rows)
6206 draw_info.height=(
unsigned int) (*image)->rows;
6207 (void) FormatLocaleString(draw_info.geometry,MaxTextExtent,
"%ux%u%+d%+d",
6208 width*draw_info.width/windows->image.ximage->width,
6209 height*draw_info.height/windows->image.ximage->height,
6210 draw_info.x+x,draw_info.y+y);
6214 draw_info.degrees=0.0;
6215 draw_info.element=element;
6216 draw_info.stipple=stipple;
6217 draw_info.line_width=line_width;
6218 draw_info.line_info=line_info;
6219 if (line_info.x1 > (
int) (line_width/2))
6220 draw_info.line_info.x1=(short) line_width/2;
6221 if (line_info.y1 > (
int) (line_width/2))
6222 draw_info.line_info.y1=(short) line_width/2;
6223 draw_info.line_info.x2=(short) (line_info.x2-line_info.x1+(line_width/2));
6224 draw_info.line_info.y2=(short) (line_info.y2-line_info.y1+(line_width/2));
6225 if ((draw_info.line_info.x2 < 0) && (draw_info.line_info.y2 < 0))
6227 draw_info.line_info.x2=(-draw_info.line_info.x2);
6228 draw_info.line_info.y2=(-draw_info.line_info.y2);
6230 if (draw_info.line_info.x2 < 0)
6232 draw_info.line_info.x2=(-draw_info.line_info.x2);
6233 Swap(draw_info.line_info.x1,draw_info.line_info.x2);
6235 if (draw_info.line_info.y2 < 0)
6237 draw_info.line_info.y2=(-draw_info.line_info.y2);
6238 Swap(draw_info.line_info.y1,draw_info.line_info.y2);
6240 draw_info.rectangle_info=rectangle_info;
6241 if (draw_info.rectangle_info.x > (ssize_t) (line_width/2))
6242 draw_info.rectangle_info.x=(ssize_t) line_width/2;
6243 if (draw_info.rectangle_info.y > (ssize_t) (line_width/2))
6244 draw_info.rectangle_info.y=(ssize_t) line_width/2;
6245 draw_info.number_coordinates=(
unsigned int) number_coordinates;
6246 draw_info.coordinate_info=coordinate_info;
6247 windows->pixel_info->pen_color=windows->pixel_info->pen_colors[pen_id];
6251 XSetCursorState(display,windows,MagickTrue);
6252 XCheckRefreshWindows(display,windows);
6253 status=XDrawImage(display,windows->pixel_info,&draw_info,*image);
6254 XSetCursorState(display,windows,MagickFalse);
6258 XConfigureImageColormap(display,resource_info,windows,*image);
6259 (void) XConfigureImage(display,resource_info,windows,*image);
6261 XSetCursorState(display,windows,MagickFalse);
6262 coordinate_info=(XPoint *) RelinquishMagickMemory(coordinate_info);
6263 return(status != 0 ? MagickTrue : MagickFalse);
6293static void XDrawPanRectangle(Display *display,XWindows *windows)
6304 scale_factor=(MagickRealType) windows->pan.width/windows->image.ximage->width;
6305 highlight_info.x=(ssize_t) (scale_factor*windows->image.x+0.5);
6306 highlight_info.width=(
unsigned int) (scale_factor*windows->image.width+0.5);
6307 scale_factor=(MagickRealType)
6308 windows->pan.height/windows->image.ximage->height;
6309 highlight_info.y=(ssize_t) (scale_factor*windows->image.y+0.5);
6310 highlight_info.height=(
unsigned int) (scale_factor*windows->image.height+0.5);
6314 (void) XClearWindow(display,windows->pan.id);
6315 XHighlightRectangle(display,windows->pan.id,windows->pan.annotate_context,
6353static void XImageCache(Display *display,XResourceInfo *resource_info,
6354 XWindows *windows,
const DisplayCommand command,
Image **image)
6360 *redo_image = (
Image *) NULL,
6361 *undo_image = (
Image *) NULL;
6365 case FreeBuffersCommand:
6370 while (undo_image != (
Image *) NULL)
6372 cache_image=undo_image;
6373 undo_image=GetPreviousImageInList(undo_image);
6374 cache_image->list=DestroyImage(cache_image->list);
6375 cache_image=DestroyImage(cache_image);
6377 undo_image=NewImageList();
6378 if (redo_image != (
Image *) NULL)
6379 redo_image=DestroyImage(redo_image);
6380 redo_image=NewImageList();
6386 image_geometry[MaxTextExtent];
6391 if (undo_image == (
Image *) NULL)
6393 (void) XBell(display,0);
6396 cache_image=undo_image;
6397 undo_image=GetPreviousImageInList(undo_image);
6398 windows->image.window_changes.width=(int) cache_image->columns;
6399 windows->image.window_changes.height=(
int) cache_image->rows;
6400 (void) FormatLocaleString(image_geometry,MaxTextExtent,
"%dx%d!",
6401 windows->image.ximage->width,windows->image.ximage->height);
6402 (void) TransformImage(image,windows->image.crop_geometry,image_geometry);
6403 if (windows->image.crop_geometry != (
char *) NULL)
6404 windows->image.crop_geometry=(
char *)
6405 RelinquishMagickMemory(windows->image.crop_geometry);
6406 windows->image.crop_geometry=cache_image->geometry;
6407 if (redo_image != (
Image *) NULL)
6408 redo_image=DestroyImage(redo_image);
6409 redo_image=(*image);
6410 *image=cache_image->list;
6411 cache_image=DestroyImage(cache_image);
6412 if (windows->image.orphan != MagickFalse)
6414 XConfigureImageColormap(display,resource_info,windows,*image);
6415 (void) XConfigureImage(display,resource_info,windows,*image);
6421 case HalfSizeCommand:
6422 case OriginalSizeCommand:
6423 case DoubleSizeCommand:
6430 case RotateRightCommand:
6431 case RotateLeftCommand:
6436 case ContrastStretchCommand:
6437 case SigmoidalContrastCommand:
6438 case NormalizeCommand:
6439 case EqualizeCommand:
6441 case SaturationCommand:
6442 case BrightnessCommand:
6446 case GrayscaleCommand:
6448 case QuantizeCommand:
6449 case DespeckleCommand:
6451 case ReduceNoiseCommand:
6452 case AddNoiseCommand:
6453 case SharpenCommand:
6455 case ThresholdCommand:
6456 case EdgeDetectCommand:
6460 case SegmentCommand:
6461 case SolarizeCommand:
6462 case SepiaToneCommand:
6464 case ImplodeCommand:
6465 case VignetteCommand:
6467 case OilPaintCommand:
6468 case CharcoalDrawCommand:
6469 case AnnotateCommand:
6470 case AddBorderCommand:
6471 case AddFrameCommand:
6472 case CompositeCommand:
6473 case CommentCommand:
6475 case RegionOfInterestCommand:
6476 case SaveToUndoBufferCommand:
6485 bytes=(ssize_t) ((*image)->columns*(*image)->rows*
sizeof(
PixelPacket));
6486 if (undo_image != (
Image *) NULL)
6491 previous_image=undo_image;
6492 while (previous_image != (
Image *) NULL)
6494 bytes+=previous_image->list->columns*previous_image->list->rows*
6496 if (bytes <= (ssize_t) (resource_info->undo_cache << 20))
6498 previous_image=GetPreviousImageInList(previous_image);
6501 bytes-=previous_image->list->columns*previous_image->list->rows*
6503 if (previous_image == undo_image)
6504 undo_image=NewImageList();
6506 previous_image->next->previous=NewImageList();
6509 while (previous_image != (
Image *) NULL)
6514 cache_image=previous_image;
6515 previous_image=GetPreviousImageInList(previous_image);
6516 cache_image->list=DestroyImage(cache_image->list);
6517 cache_image=DestroyImage(cache_image);
6520 if (bytes > (ssize_t) (resource_info->undo_cache << 20))
6525 cache_image=AcquireImage((
ImageInfo *) NULL);
6526 if (cache_image == (
Image *) NULL)
6528 XSetCursorState(display,windows,MagickTrue);
6529 XCheckRefreshWindows(display,windows);
6530 cache_image->list=CloneImage(*image,0,0,MagickTrue,&(*image)->exception);
6531 XSetCursorState(display,windows,MagickFalse);
6532 if (cache_image->list == (
Image *) NULL)
6534 cache_image=DestroyImage(cache_image);
6537 cache_image->columns=(size_t) windows->image.ximage->width;
6538 cache_image->rows=(
size_t) windows->image.ximage->height;
6539 cache_image->geometry=windows->image.crop_geometry;
6540 if (windows->image.crop_geometry != (
char *) NULL)
6542 cache_image->geometry=AcquireString((
char *) NULL);
6543 (void) CopyMagickString(cache_image->geometry,
6544 windows->image.crop_geometry,MaxTextExtent);
6546 if (undo_image == (
Image *) NULL)
6548 undo_image=cache_image;
6551 undo_image->next=cache_image;
6552 undo_image->next->previous=undo_image;
6553 undo_image=undo_image->next;
6559 if (command == RedoCommand)
6564 if (redo_image == (
Image *) NULL)
6566 (void) XBell(display,0);
6569 windows->image.window_changes.width=(int) redo_image->columns;
6570 windows->image.window_changes.height=(
int) redo_image->rows;
6571 if (windows->image.crop_geometry != (
char *) NULL)
6572 windows->image.crop_geometry=(
char *)
6573 RelinquishMagickMemory(windows->image.crop_geometry);
6574 windows->image.crop_geometry=redo_image->geometry;
6575 *image=DestroyImage(*image);
6577 redo_image=NewImageList();
6578 if (windows->image.orphan != MagickFalse)
6580 XConfigureImageColormap(display,resource_info,windows,*image);
6581 (void) XConfigureImage(display,resource_info,windows,*image);
6584 if (command != InfoCommand)
6589 XSetCursorState(display,windows,MagickTrue);
6590 XCheckRefreshWindows(display,windows);
6591 XDisplayImageInfo(display,resource_info,windows,undo_image,*image);
6592 XSetCursorState(display,windows,MagickFalse);
6636static DisplayCommand XImageWindowCommand(Display *display,
6637 XResourceInfo *resource_info,XWindows *windows,
const MagickStatusType state,
6638 KeySym key_symbol,
Image **image)
6641 delta[MaxTextExtent] =
"";
6644 Digits[] =
"01234567890";
6649 if ((key_symbol >= XK_0) && (key_symbol <= XK_9))
6651 if (((last_symbol < XK_0) || (last_symbol > XK_9)))
6654 resource_info->quantum=1;
6656 last_symbol=key_symbol;
6657 delta[strlen(delta)+1]=
'\0';
6658 delta[strlen(delta)]=Digits[key_symbol-XK_0];
6659 resource_info->quantum=StringToLong(delta);
6660 return(NullCommand);
6662 last_symbol=key_symbol;
6663 if (resource_info->immutable)
6671 return(InfoCommand);
6674 return(PrintCommand);
6676 return(NextCommand);
6679 return(QuitCommand);
6683 return(NullCommand);
6685 switch ((
int) key_symbol)
6689 if ((state & ControlMask) == 0)
6691 return(OpenCommand);
6694 return(NextCommand);
6696 return(FormerCommand);
6699 if ((state & Mod1Mask) != 0)
6700 return(SwirlCommand);
6701 if ((state & ControlMask) == 0)
6702 return(ShearCommand);
6703 return(SaveCommand);
6708 if ((state & Mod1Mask) != 0)
6709 return(OilPaintCommand);
6710 if ((state & Mod4Mask) != 0)
6711 return(ColorCommand);
6712 if ((state & ControlMask) == 0)
6713 return(NullCommand);
6714 return(PrintCommand);
6718 if ((state & Mod4Mask) != 0)
6719 return(DrawCommand);
6720 if ((state & ControlMask) == 0)
6721 return(NullCommand);
6722 return(DeleteCommand);
6726 if ((state & ControlMask) == 0)
6727 return(NullCommand);
6728 return(SelectCommand);
6732 if ((state & ControlMask) == 0)
6733 return(NullCommand);
6738 return(QuitCommand);
6742 if ((state & ControlMask) == 0)
6743 return(NullCommand);
6744 return(UndoCommand);
6749 if ((state & ControlMask) == 0)
6750 return(RollCommand);
6751 return(RedoCommand);
6755 if ((state & ControlMask) == 0)
6756 return(NullCommand);
6761 if ((state & Mod1Mask) != 0)
6762 return(CharcoalDrawCommand);
6763 if ((state & ControlMask) == 0)
6764 return(CropCommand);
6765 return(CopyCommand);
6770 if ((state & Mod4Mask) != 0)
6771 return(CompositeCommand);
6772 if ((state & ControlMask) == 0)
6773 return(FlipCommand);
6774 return(PasteCommand);
6777 return(HalfSizeCommand);
6779 return(OriginalSizeCommand);
6781 return(DoubleSizeCommand);
6783 return(ResizeCommand);
6785 return(RefreshCommand);
6786 case XK_bracketleft:
6787 return(ChopCommand);
6789 return(FlopCommand);
6791 return(RotateRightCommand);
6793 return(RotateLeftCommand);
6795 return(RotateCommand);
6797 return(TrimCommand);
6801 return(SaturationCommand);
6803 return(BrightnessCommand);
6805 return(GammaCommand);
6807 return(SpiffCommand);
6809 return(DullCommand);
6811 return(NormalizeCommand);
6813 return(EqualizeCommand);
6815 return(NegateCommand);
6817 return(GrayscaleCommand);
6819 return(QuantizeCommand);
6821 return(DespeckleCommand);
6823 return(EmbossCommand);
6825 return(ReduceNoiseCommand);
6827 return(AddNoiseCommand);
6829 return(SharpenCommand);
6831 return(BlurCommand);
6833 return(ThresholdCommand);
6835 return(EdgeDetectCommand);
6837 return(SpreadCommand);
6839 return(ShadeCommand);
6841 return(RaiseCommand);
6843 return(SegmentCommand);
6846 if ((state & Mod1Mask) == 0)
6847 return(NullCommand);
6848 return(ImplodeCommand);
6852 if ((state & Mod1Mask) == 0)
6853 return(NullCommand);
6854 return(WaveCommand);
6858 if ((state & Mod4Mask) == 0)
6859 return(NullCommand);
6860 return(MatteCommand);
6864 if ((state & Mod4Mask) == 0)
6865 return(NullCommand);
6866 return(AddBorderCommand);
6870 if ((state & Mod4Mask) == 0)
6871 return(NullCommand);
6872 return(AddFrameCommand);
6876 if ((state & Mod4Mask) == 0)
6877 return(NullCommand);
6878 return(CommentCommand);
6882 if ((state & Mod1Mask) != 0)
6883 return(ApplyCommand);
6884 if ((state & Mod4Mask) != 0)
6885 return(AnnotateCommand);
6886 if ((state & ControlMask) == 0)
6887 return(NullCommand);
6888 return(RegionOfInterestCommand);
6891 return(InfoCommand);
6893 return(ZoomCommand);
6896 if ((state & ShiftMask) == 0)
6897 return(NullCommand);
6898 return(ShowPreviewCommand);
6901 return(LaunchCommand);
6903 return(HelpCommand);
6905 return(BrowseDocumentationCommand);
6908 (void) XMapRaised(display,windows->command.id);
6909 return(NullCommand);
6916 XTranslateImage(display,windows,*image,key_symbol);
6917 return(NullCommand);
6928 if ((state & Mod1Mask) != 0)
6938 crop_info.width=(size_t) windows->image.ximage->width;
6939 crop_info.height=(
size_t) windows->image.ximage->height;
6940 if ((key_symbol == XK_Up) || (key_symbol == XK_KP_Up))
6942 if (resource_info->quantum >= (
int) crop_info.height)
6943 resource_info->quantum=(
int) crop_info.height-1;
6944 crop_info.height-=resource_info->quantum;
6946 if ((key_symbol == XK_Down) || (key_symbol == XK_KP_Down))
6948 if (resource_info->quantum >= (
int) (crop_info.height-crop_info.y))
6949 resource_info->quantum=(int) (crop_info.height-crop_info.y-1);
6950 crop_info.y+=resource_info->quantum;
6951 crop_info.height-=resource_info->quantum;
6953 if ((key_symbol == XK_Left) || (key_symbol == XK_KP_Left))
6955 if (resource_info->quantum >= (
int) crop_info.width)
6956 resource_info->quantum=(
int) crop_info.width-1;
6957 crop_info.width-=resource_info->quantum;
6959 if ((key_symbol == XK_Right) || (key_symbol == XK_KP_Right))
6961 if (resource_info->quantum >= (
int) (crop_info.width-crop_info.x))
6962 resource_info->quantum=(int) (crop_info.width-crop_info.x-1);
6963 crop_info.x+=resource_info->quantum;
6964 crop_info.width-=resource_info->quantum;
6966 if ((
int) (windows->image.x+windows->image.width) >
6967 (
int) crop_info.width)
6968 windows->image.x=(
int) (crop_info.width-windows->image.width);
6969 if ((
int) (windows->image.y+windows->image.height) >
6970 (
int) crop_info.height)
6971 windows->image.y=(
int) (crop_info.height-windows->image.height);
6972 XSetCropGeometry(display,windows,&crop_info,*image);
6973 windows->image.window_changes.width=(int) crop_info.width;
6974 windows->image.window_changes.height=(
int) crop_info.height;
6975 (void) XSetWindowBackgroundPixmap(display,windows->image.id,None);
6976 (void) XConfigureImage(display,resource_info,windows,*image);
6977 return(NullCommand);
6979 XTranslateImage(display,windows,*image,key_symbol);
6980 return(NullCommand);
6983 return(NullCommand);
6985 return(NullCommand);
7026static Image *XMagickCommand(Display *display,XResourceInfo *resource_info,
7027 XWindows *windows,
const DisplayCommand command,
Image **image)
7030 filename[MaxTextExtent],
7031 geometry[MaxTextExtent],
7032 modulate_factors[MaxTextExtent];
7061 color[MaxTextExtent] =
"gray";
7070 XCheckRefreshWindows(display,windows);
7071 XImageCache(display,resource_info,windows,command,image);
7072 nexus=NewImageList();
7073 windows->image.window_changes.width=windows->image.ximage->width;
7074 windows->image.window_changes.height=windows->image.ximage->height;
7075 image_info=CloneImageInfo(resource_info->image_info);
7076 SetGeometryInfo(&geometry_info);
7077 GetQuantizeInfo(&quantize_info);
7085 nexus=XOpenImage(display,resource_info,windows,MagickFalse);
7093 for (i=0; i < resource_info->quantum; i++)
7094 XClientMessage(display,windows->image.id,windows->im_protocols,
7095 windows->im_next_image,CurrentTime);
7103 for (i=0; i < resource_info->quantum; i++)
7104 XClientMessage(display,windows->image.id,windows->im_protocols,
7105 windows->im_former_image,CurrentTime);
7116 if (*resource_info->home_directory ==
'\0')
7117 (void) CopyMagickString(resource_info->home_directory,
".",
7119 status=chdir(resource_info->home_directory);
7121 (void) ThrowMagickException(&(*image)->exception,GetMagickModule(),
7122 FileOpenError,
"UnableToOpenFile",
"%s",resource_info->home_directory);
7123 nexus=XOpenImage(display,resource_info,windows,MagickTrue);
7131 status=XSaveImage(display,resource_info,windows,*image);
7132 if (status == MagickFalse)
7135 message[MaxTextExtent];
7137 (void) FormatLocaleString(message,MaxTextExtent,
"%s:%s",
7138 (*image)->exception.reason != (
char *) NULL ?
7139 (*image)->exception.reason :
"",
7140 (*image)->exception.description != (
char *) NULL ?
7141 (*image)->exception.description :
"");
7142 XNoticeWidget(display,windows,
"Unable to save file:",message);
7152 status=XPrintImage(display,resource_info,windows,*image);
7153 if (status == MagickFalse)
7156 message[MaxTextExtent];
7158 (void) FormatLocaleString(message,MaxTextExtent,
"%s:%s",
7159 (*image)->exception.reason != (
char *) NULL ?
7160 (*image)->exception.reason :
"",
7161 (*image)->exception.description != (
char *) NULL ?
7162 (*image)->exception.description :
"");
7163 XNoticeWidget(display,windows,
"Unable to print file:",message);
7171 filename[MaxTextExtent] =
"\0";
7176 XFileBrowserWidget(display,windows,
"Delete",filename);
7177 if (*filename ==
'\0')
7179 status=ShredFile(filename);
7180 status|=remove_utf8(filename);
7181 if (status != MagickFalse)
7182 XNoticeWidget(display,windows,
"Unable to delete image file:",filename);
7191 color[MaxTextExtent] =
"gray",
7192 geometry[MaxTextExtent] =
"640x480";
7195 *format =
"gradient";
7200 status=XDialogWidget(display,windows,
"New",
"Enter image geometry:",
7202 if (*geometry ==
'\0')
7206 XColorBrowserWidget(display,windows,
"Select",color);
7212 (void) FormatLocaleString(image_info->filename,MaxTextExtent,
7213 "%s:%s",format,color);
7214 (void) CloneString(&image_info->size,geometry);
7215 nexus=ReadImage(image_info,&(*image)->exception);
7216 CatchException(&(*image)->exception);
7217 XClientMessage(display,windows->image.id,windows->im_protocols,
7218 windows->im_next_image,CurrentTime);
7221 case VisualDirectoryCommand:
7226 nexus=XVisualDirectoryImage(display,resource_info,windows);
7234 if (resource_info->confirm_exit == MagickFalse)
7235 XClientMessage(display,windows->image.id,windows->im_protocols,
7236 windows->im_exit,CurrentTime);
7245 status=XConfirmWidget(display,windows,
"Do you really want to exit",
7246 resource_info->client_name);
7248 XClientMessage(display,windows->image.id,windows->im_protocols,
7249 windows->im_exit,CurrentTime);
7258 (void) XCropImage(display,resource_info,windows,*image,CutMode);
7266 (void) XCropImage(display,resource_info,windows,*image,CopyMode);
7274 status=XPasteImage(display,resource_info,windows,*image);
7275 if (status == MagickFalse)
7277 XNoticeWidget(display,windows,
"Unable to paste X image",
7278 (*image)->filename);
7283 case HalfSizeCommand:
7288 windows->image.window_changes.width=windows->image.ximage->width/2;
7289 windows->image.window_changes.height=windows->image.ximage->height/2;
7290 (void) XConfigureImage(display,resource_info,windows,*image);
7293 case OriginalSizeCommand:
7298 windows->image.window_changes.width=(int) (*image)->columns;
7299 windows->image.window_changes.height=(
int) (*image)->rows;
7300 (void) XConfigureImage(display,resource_info,windows,*image);
7303 case DoubleSizeCommand:
7308 windows->image.window_changes.width=windows->image.ximage->width << 1;
7309 windows->image.window_changes.height=windows->image.ximage->height << 1;
7310 (void) XConfigureImage(display,resource_info,windows,*image);
7329 width=(size_t) windows->image.ximage->width;
7330 height=(
size_t) windows->image.ximage->height;
7333 (void) FormatLocaleString(geometry,MaxTextExtent,
"%.20gx%.20g+0+0",
7334 (
double) width,(double) height);
7335 status=XDialogWidget(display,windows,
"Resize",
7336 "Enter resize geometry (e.g. 640x480, 200%):",geometry);
7337 if (*geometry ==
'\0')
7340 (void) ConcatenateMagickString(geometry,
"!",MaxTextExtent);
7341 (void) ParseMetaGeometry(geometry,&x,&y,&width,&height);
7342 windows->image.window_changes.width=(int) width;
7343 windows->image.window_changes.height=(int) height;
7344 (void) XConfigureImage(display,resource_info,windows,*image);
7350 image_geometry[MaxTextExtent];
7352 if ((windows->image.crop_geometry == (
char *) NULL) &&
7353 ((
int) (*image)->columns == windows->image.ximage->width) &&
7354 ((
int) (*image)->rows == windows->image.ximage->height))
7359 XSetCursorState(display,windows,MagickTrue);
7360 XCheckRefreshWindows(display,windows);
7364 (void) FormatLocaleString(image_geometry,MaxTextExtent,
"%dx%d!",
7365 windows->image.ximage->width,windows->image.ximage->height);
7366 (void) TransformImage(image,windows->image.crop_geometry,image_geometry);
7367 if (windows->image.crop_geometry != (
char *) NULL)
7368 windows->image.crop_geometry=(
char *)
7369 RelinquishMagickMemory(windows->image.crop_geometry);
7372 XConfigureImageColormap(display,resource_info,windows,*image);
7373 (void) XConfigureImage(display,resource_info,windows,*image);
7376 case RefreshCommand:
7378 (void) XConfigureImage(display,resource_info,windows,*image);
7381 case RestoreCommand:
7386 if ((windows->image.width == (
unsigned int) (*image)->columns) &&
7387 (windows->image.height == (
unsigned int) (*image)->rows) &&
7388 (windows->image.crop_geometry == (
char *) NULL))
7390 (void) XBell(display,0);
7393 windows->image.window_changes.width=(int) (*image)->columns;
7394 windows->image.window_changes.height=(
int) (*image)->rows;
7395 if (windows->image.crop_geometry != (
char *) NULL)
7397 windows->image.crop_geometry=(
char *)
7398 RelinquishMagickMemory(windows->image.crop_geometry);
7399 windows->image.crop_geometry=(
char *) NULL;
7403 XConfigureImageColormap(display,resource_info,windows,*image);
7404 (void) XConfigureImage(display,resource_info,windows,*image);
7412 (void) XCropImage(display,resource_info,windows,*image,CropMode);
7420 status=XChopImage(display,resource_info,windows,image);
7421 if (status == MagickFalse)
7423 XNoticeWidget(display,windows,
"Unable to cut X image",
7424 (*image)->filename);
7437 XSetCursorState(display,windows,MagickTrue);
7438 XCheckRefreshWindows(display,windows);
7439 flop_image=FlopImage(*image,&(*image)->exception);
7440 if (flop_image != (
Image *) NULL)
7442 *image=DestroyImage(*image);
7445 CatchException(&(*image)->exception);
7446 XSetCursorState(display,windows,MagickFalse);
7447 if (windows->image.crop_geometry != (
char *) NULL)
7452 width=(
unsigned int) (*image)->columns;
7453 height=(
unsigned int) (*image)->rows;
7454 (void) XParseGeometry(windows->image.crop_geometry,&x,&y,
7456 (void) FormatLocaleString(windows->image.crop_geometry,MaxTextExtent,
7457 "%ux%u%+d%+d",width,height,(
int) (*image)->columns-(int) width-x,y);
7459 if (windows->image.orphan != MagickFalse)
7461 (void) XConfigureImage(display,resource_info,windows,*image);
7472 XSetCursorState(display,windows,MagickTrue);
7473 XCheckRefreshWindows(display,windows);
7474 flip_image=FlipImage(*image,&(*image)->exception);
7475 if (flip_image != (
Image *) NULL)
7477 *image=DestroyImage(*image);
7480 CatchException(&(*image)->exception);
7481 XSetCursorState(display,windows,MagickFalse);
7482 if (windows->image.crop_geometry != (
char *) NULL)
7487 width=(
unsigned int) (*image)->columns;
7488 height=(
unsigned int) (*image)->rows;
7489 (void) XParseGeometry(windows->image.crop_geometry,&x,&y,
7491 (void) FormatLocaleString(windows->image.crop_geometry,MaxTextExtent,
7492 "%ux%u%+d%+d",width,height,x,(
int) (*image)->rows-(int) height-y);
7494 if (windows->image.orphan != MagickFalse)
7496 (void) XConfigureImage(display,resource_info,windows,*image);
7499 case RotateRightCommand:
7504 status=XRotateImage(display,resource_info,windows,90.0,image);
7505 if (status == MagickFalse)
7507 XNoticeWidget(display,windows,
"Unable to rotate X image",
7508 (*image)->filename);
7513 case RotateLeftCommand:
7518 status=XRotateImage(display,resource_info,windows,-90.0,image);
7519 if (status == MagickFalse)
7521 XNoticeWidget(display,windows,
"Unable to rotate X image",
7522 (*image)->filename);
7532 status=XRotateImage(display,resource_info,windows,0.0,image);
7533 if (status == MagickFalse)
7535 XNoticeWidget(display,windows,
"Unable to rotate X image",
7536 (*image)->filename);
7547 geometry[MaxTextExtent] =
"45.0x45.0";
7552 XColorBrowserWidget(display,windows,
"Select",color);
7555 (void) XDialogWidget(display,windows,
"Shear",
"Enter shear geometry:",
7557 if (*geometry ==
'\0')
7562 (void) XMagickCommand(display,resource_info,windows,ApplyCommand,image);
7563 XSetCursorState(display,windows,MagickTrue);
7564 XCheckRefreshWindows(display,windows);
7565 (void) QueryColorDatabase(color,&(*image)->background_color,
7566 &(*image)->exception);
7567 flags=ParseGeometry(geometry,&geometry_info);
7568 if ((flags & SigmaValue) == 0)
7569 geometry_info.sigma=geometry_info.rho;
7570 shear_image=ShearImage(*image,geometry_info.rho,geometry_info.sigma,
7571 &(*image)->exception);
7572 if (shear_image != (
Image *) NULL)
7574 *image=DestroyImage(*image);
7577 CatchException(&(*image)->exception);
7578 XSetCursorState(display,windows,MagickFalse);
7579 if (windows->image.orphan != MagickFalse)
7581 windows->image.window_changes.width=(int) (*image)->columns;
7582 windows->image.window_changes.height=(
int) (*image)->rows;
7583 XConfigureImageColormap(display,resource_info,windows,*image);
7584 (void) XConfigureImage(display,resource_info,windows,*image);
7593 geometry[MaxTextExtent] =
"+2+2";
7598 (void) XDialogWidget(display,windows,
"Roll",
"Enter roll geometry:",
7600 if (*geometry ==
'\0')
7605 (void) XMagickCommand(display,resource_info,windows,ApplyCommand,image);
7606 XSetCursorState(display,windows,MagickTrue);
7607 XCheckRefreshWindows(display,windows);
7608 (void) ParsePageGeometry(*image,geometry,&page_geometry,
7609 &(*image)->exception);
7610 roll_image=RollImage(*image,page_geometry.x,page_geometry.y,
7611 &(*image)->exception);
7612 if (roll_image != (
Image *) NULL)
7614 *image=DestroyImage(*image);
7617 CatchException(&(*image)->exception);
7618 XSetCursorState(display,windows,MagickFalse);
7619 if (windows->image.orphan != MagickFalse)
7621 windows->image.window_changes.width=(int) (*image)->columns;
7622 windows->image.window_changes.height=(
int) (*image)->rows;
7623 XConfigureImageColormap(display,resource_info,windows,*image);
7624 (void) XConfigureImage(display,resource_info,windows,*image);
7630 fuzz[MaxTextExtent];
7635 (void) FormatLocaleString(fuzz,MaxTextExtent,
"%g%%",100.0*
7636 (*image)->fuzz/((
double) QuantumRange+1.0));
7637 (void) XDialogWidget(display,windows,
"Trim",
"Enter fuzz factor:",fuzz);
7640 (*image)->fuzz=StringToDoubleInterval(fuzz,(
double) QuantumRange+1.0);
7644 status=XTrimImage(display,resource_info,windows,*image);
7645 if (status == MagickFalse)
7647 XNoticeWidget(display,windows,
"Unable to trim X image",
7648 (*image)->filename);
7656 hue_percent[MaxTextExtent] =
"110";
7661 (void) XDialogWidget(display,windows,
"Apply",
7662 "Enter percent change in image hue (0-200):",hue_percent);
7663 if (*hue_percent ==
'\0')
7668 XSetCursorState(display,windows,MagickTrue);
7669 XCheckRefreshWindows(display,windows);
7670 (void) CopyMagickString(modulate_factors,
"100.0/100.0/",MaxTextExtent);
7671 (void) ConcatenateMagickString(modulate_factors,hue_percent,
7673 (void) ModulateImage(*image,modulate_factors);
7674 XSetCursorState(display,windows,MagickFalse);
7675 if (windows->image.orphan != MagickFalse)
7677 XConfigureImageColormap(display,resource_info,windows,*image);
7678 (void) XConfigureImage(display,resource_info,windows,*image);
7681 case SaturationCommand:
7684 saturation_percent[MaxTextExtent] =
"110";
7689 (void) XDialogWidget(display,windows,
"Apply",
7690 "Enter percent change in color saturation (0-200):",saturation_percent);
7691 if (*saturation_percent ==
'\0')
7696 XSetCursorState(display,windows,MagickTrue);
7697 XCheckRefreshWindows(display,windows);
7698 (void) CopyMagickString(modulate_factors,
"100.0/",MaxTextExtent);
7699 (void) ConcatenateMagickString(modulate_factors,saturation_percent,
7701 (void) ModulateImage(*image,modulate_factors);
7702 XSetCursorState(display,windows,MagickFalse);
7703 if (windows->image.orphan != MagickFalse)
7705 XConfigureImageColormap(display,resource_info,windows,*image);
7706 (void) XConfigureImage(display,resource_info,windows,*image);
7709 case BrightnessCommand:
7712 brightness_percent[MaxTextExtent] =
"110";
7717 (void) XDialogWidget(display,windows,
"Apply",
7718 "Enter percent change in color brightness (0-200):",brightness_percent);
7719 if (*brightness_percent ==
'\0')
7724 XSetCursorState(display,windows,MagickTrue);
7725 XCheckRefreshWindows(display,windows);
7726 (void) CopyMagickString(modulate_factors,brightness_percent,
7728 (void) ModulateImage(*image,modulate_factors);
7729 XSetCursorState(display,windows,MagickFalse);
7730 if (windows->image.orphan != MagickFalse)
7732 XConfigureImageColormap(display,resource_info,windows,*image);
7733 (void) XConfigureImage(display,resource_info,windows,*image);
7739 factor[MaxTextExtent] =
"1.6";
7744 (void) XDialogWidget(display,windows,
"Gamma",
7745 "Enter gamma value (e.g. 1.0,1.0,1.6):",factor);
7746 if (*factor ==
'\0')
7751 XSetCursorState(display,windows,MagickTrue);
7752 XCheckRefreshWindows(display,windows);
7753 (void) GammaImage(*image,factor);
7754 XSetCursorState(display,windows,MagickFalse);
7755 if (windows->image.orphan != MagickFalse)
7757 XConfigureImageColormap(display,resource_info,windows,*image);
7758 (void) XConfigureImage(display,resource_info,windows,*image);
7766 XSetCursorState(display,windows,MagickTrue);
7767 XCheckRefreshWindows(display,windows);
7768 (void) ContrastImage(*image,MagickTrue);
7769 XSetCursorState(display,windows,MagickFalse);
7770 if (windows->image.orphan != MagickFalse)
7772 XConfigureImageColormap(display,resource_info,windows,*image);
7773 (void) XConfigureImage(display,resource_info,windows,*image);
7781 XSetCursorState(display,windows,MagickTrue);
7782 XCheckRefreshWindows(display,windows);
7783 (void) ContrastImage(*image,MagickFalse);
7784 XSetCursorState(display,windows,MagickFalse);
7785 if (windows->image.orphan != MagickFalse)
7787 XConfigureImageColormap(display,resource_info,windows,*image);
7788 (void) XConfigureImage(display,resource_info,windows,*image);
7791 case ContrastStretchCommand:
7798 levels[MaxTextExtent] =
"1%";
7803 (void) XDialogWidget(display,windows,
"Contrast Stretch",
7804 "Enter black and white points:",levels);
7805 if (*levels ==
'\0')
7810 XSetCursorState(display,windows,MagickTrue);
7811 XCheckRefreshWindows(display,windows);
7812 flags=ParseGeometry(levels,&geometry_info);
7813 black_point=geometry_info.rho;
7814 white_point=(flags & SigmaValue) != 0 ? geometry_info.sigma : black_point;
7815 if ((flags & PercentValue) != 0)
7817 black_point*=(double) (*image)->columns*(*image)->rows/100.0;
7818 white_point*=(
double) (*image)->columns*(*image)->rows/100.0;
7820 white_point=(MagickRealType) (*image)->columns*(*image)->rows-white_point;
7821 (
void) ContrastStretchImageChannel(*image,DefaultChannels,black_point,
7823 XSetCursorState(display,windows,MagickFalse);
7824 if (windows->image.orphan != MagickFalse)
7826 XConfigureImageColormap(display,resource_info,windows,*image);
7827 (void) XConfigureImage(display,resource_info,windows,*image);
7830 case SigmoidalContrastCommand:
7833 levels[MaxTextExtent] =
"3x50%";
7838 (void) XDialogWidget(display,windows,
"Sigmoidal Contrast",
7839 "Enter contrast and midpoint:",levels);
7840 if (*levels ==
'\0')
7845 XSetCursorState(display,windows,MagickTrue);
7846 XCheckRefreshWindows(display,windows);
7847 (void) SigmoidalContrastImage(*image,MagickTrue,levels);
7848 XSetCursorState(display,windows,MagickFalse);
7849 if (windows->image.orphan != MagickFalse)
7851 XConfigureImageColormap(display,resource_info,windows,*image);
7852 (void) XConfigureImage(display,resource_info,windows,*image);
7855 case NormalizeCommand:
7860 XSetCursorState(display,windows,MagickTrue);
7861 XCheckRefreshWindows(display,windows);
7862 (void) NormalizeImage(*image);
7863 XSetCursorState(display,windows,MagickFalse);
7864 if (windows->image.orphan != MagickFalse)
7866 XConfigureImageColormap(display,resource_info,windows,*image);
7867 (void) XConfigureImage(display,resource_info,windows,*image);
7870 case EqualizeCommand:
7875 XSetCursorState(display,windows,MagickTrue);
7876 XCheckRefreshWindows(display,windows);
7877 (void) EqualizeImage(*image);
7878 XSetCursorState(display,windows,MagickFalse);
7879 if (windows->image.orphan != MagickFalse)
7881 XConfigureImageColormap(display,resource_info,windows,*image);
7882 (void) XConfigureImage(display,resource_info,windows,*image);
7890 XSetCursorState(display,windows,MagickTrue);
7891 XCheckRefreshWindows(display,windows);
7892 (void) NegateImage(*image,MagickFalse);
7893 XSetCursorState(display,windows,MagickFalse);
7894 if (windows->image.orphan != MagickFalse)
7896 XConfigureImageColormap(display,resource_info,windows,*image);
7897 (void) XConfigureImage(display,resource_info,windows,*image);
7900 case GrayscaleCommand:
7905 XSetCursorState(display,windows,MagickTrue);
7906 XCheckRefreshWindows(display,windows);
7907 (void) SetImageType(*image,(*image)->matte == MagickFalse ?
7908 GrayscaleType : GrayscaleMatteType);
7909 XSetCursorState(display,windows,MagickFalse);
7910 if (windows->image.orphan != MagickFalse)
7912 XConfigureImageColormap(display,resource_info,windows,*image);
7913 (void) XConfigureImage(display,resource_info,windows,*image);
7922 filename[MaxTextExtent] =
"\0";
7927 XFileBrowserWidget(display,windows,
"Map",filename);
7928 if (*filename ==
'\0')
7933 XSetCursorState(display,windows,MagickTrue);
7934 XCheckRefreshWindows(display,windows);
7935 (void) CopyMagickString(image_info->filename,filename,MaxTextExtent);
7936 affinity_image=ReadImage(image_info,&(*image)->exception);
7937 if (affinity_image != (
Image *) NULL)
7939 (void) RemapImage(&quantize_info,*image,affinity_image);
7940 affinity_image=DestroyImage(affinity_image);
7942 CatchException(&(*image)->exception);
7943 XSetCursorState(display,windows,MagickFalse);
7944 if (windows->image.orphan != MagickFalse)
7946 XConfigureImageColormap(display,resource_info,windows,*image);
7947 (void) XConfigureImage(display,resource_info,windows,*image);
7950 case QuantizeCommand:
7956 colors[MaxTextExtent] =
"256";
7961 status=XDialogWidget(display,windows,
"Quantize",
7962 "Maximum number of colors:",colors);
7963 if (*colors ==
'\0')
7968 XSetCursorState(display,windows,MagickTrue);
7969 XCheckRefreshWindows(display,windows);
7970 quantize_info.number_colors=StringToUnsignedLong(colors);
7971 quantize_info.dither=status != 0 ? MagickTrue : MagickFalse;
7972 (void) QuantizeImage(&quantize_info,*image);
7973 XSetCursorState(display,windows,MagickFalse);
7974 if (windows->image.orphan != MagickFalse)
7976 XConfigureImageColormap(display,resource_info,windows,*image);
7977 (void) XConfigureImage(display,resource_info,windows,*image);
7980 case DespeckleCommand:
7988 XSetCursorState(display,windows,MagickTrue);
7989 XCheckRefreshWindows(display,windows);
7990 despeckle_image=DespeckleImage(*image,&(*image)->exception);
7991 if (despeckle_image != (
Image *) NULL)
7993 *image=DestroyImage(*image);
7994 *image=despeckle_image;
7996 CatchException(&(*image)->exception);
7997 XSetCursorState(display,windows,MagickFalse);
7998 if (windows->image.orphan != MagickFalse)
8000 XConfigureImageColormap(display,resource_info,windows,*image);
8001 (void) XConfigureImage(display,resource_info,windows,*image);
8010 radius[MaxTextExtent] =
"0.0x1.0";
8015 (void) XDialogWidget(display,windows,
"Emboss",
8016 "Enter the emboss radius and standard deviation:",radius);
8017 if (*radius ==
'\0')
8022 XSetCursorState(display,windows,MagickTrue);
8023 XCheckRefreshWindows(display,windows);
8024 flags=ParseGeometry(radius,&geometry_info);
8025 if ((flags & SigmaValue) == 0)
8026 geometry_info.sigma=1.0;
8027 emboss_image=EmbossImage(*image,geometry_info.rho,geometry_info.sigma,
8028 &(*image)->exception);
8029 if (emboss_image != (
Image *) NULL)
8031 *image=DestroyImage(*image);
8032 *image=emboss_image;
8034 CatchException(&(*image)->exception);
8035 XSetCursorState(display,windows,MagickFalse);
8036 if (windows->image.orphan != MagickFalse)
8038 XConfigureImageColormap(display,resource_info,windows,*image);
8039 (void) XConfigureImage(display,resource_info,windows,*image);
8042 case ReduceNoiseCommand:
8048 radius[MaxTextExtent] =
"0";
8053 (void) XDialogWidget(display,windows,
"Reduce Noise",
8054 "Enter the noise radius:",radius);
8055 if (*radius ==
'\0')
8060 XSetCursorState(display,windows,MagickTrue);
8061 XCheckRefreshWindows(display,windows);
8062 flags=ParseGeometry(radius,&geometry_info);
8063 noise_image=StatisticImage(*image,NonpeakStatistic,(
size_t)
8064 geometry_info.rho,(
size_t) geometry_info.rho,&(*image)->exception);
8065 if (noise_image != (
Image *) NULL)
8067 *image=DestroyImage(*image);
8070 CatchException(&(*image)->exception);
8071 XSetCursorState(display,windows,MagickFalse);
8072 if (windows->image.orphan != MagickFalse)
8074 XConfigureImageColormap(display,resource_info,windows,*image);
8075 (void) XConfigureImage(display,resource_info,windows,*image);
8078 case AddNoiseCommand:
8087 noise_type[MaxTextExtent] =
"Gaussian";
8092 noises=GetCommandOptions(MagickNoiseOptions);
8093 if (noises == (
char **) NULL)
8095 XListBrowserWidget(display,windows,&windows->widget,
8096 (
const char **) noises,
"Add Noise",
8097 "Select a type of noise to add to your image:",noise_type);
8098 noises=DestroyStringList(noises);
8099 if (*noise_type ==
'\0')
8101 XSetCursorState(display,windows,MagickTrue);
8102 XCheckRefreshWindows(display,windows);
8103 noise_image=AddNoiseImage(*image,(NoiseType) ParseCommandOption(
8104 MagickNoiseOptions,MagickFalse,noise_type),&(*image)->exception);
8105 if (noise_image != (
Image *) NULL)
8107 *image=DestroyImage(*image);
8110 CatchException(&(*image)->exception);
8111 XSetCursorState(display,windows,MagickFalse);
8112 if (windows->image.orphan != MagickFalse)
8114 XConfigureImageColormap(display,resource_info,windows,*image);
8115 (void) XConfigureImage(display,resource_info,windows,*image);
8118 case SharpenCommand:
8124 radius[MaxTextExtent] =
"0.0x1.0";
8129 (void) XDialogWidget(display,windows,
"Sharpen",
8130 "Enter the sharpen radius and standard deviation:",radius);
8131 if (*radius ==
'\0')
8136 XSetCursorState(display,windows,MagickTrue);
8137 XCheckRefreshWindows(display,windows);
8138 flags=ParseGeometry(radius,&geometry_info);
8139 sharp_image=SharpenImage(*image,geometry_info.rho,geometry_info.sigma,
8140 &(*image)->exception);
8141 if (sharp_image != (
Image *) NULL)
8143 *image=DestroyImage(*image);
8146 CatchException(&(*image)->exception);
8147 XSetCursorState(display,windows,MagickFalse);
8148 if (windows->image.orphan != MagickFalse)
8150 XConfigureImageColormap(display,resource_info,windows,*image);
8151 (void) XConfigureImage(display,resource_info,windows,*image);
8160 radius[MaxTextExtent] =
"0.0x1.0";
8165 (void) XDialogWidget(display,windows,
"Blur",
8166 "Enter the blur radius and standard deviation:",radius);
8167 if (*radius ==
'\0')
8172 XSetCursorState(display,windows,MagickTrue);
8173 XCheckRefreshWindows(display,windows);
8174 flags=ParseGeometry(radius,&geometry_info);
8175 blur_image=BlurImage(*image,geometry_info.rho,geometry_info.sigma,
8176 &(*image)->exception);
8177 if (blur_image != (
Image *) NULL)
8179 *image=DestroyImage(*image);
8182 CatchException(&(*image)->exception);
8183 XSetCursorState(display,windows,MagickFalse);
8184 if (windows->image.orphan != MagickFalse)
8186 XConfigureImageColormap(display,resource_info,windows,*image);
8187 (void) XConfigureImage(display,resource_info,windows,*image);
8190 case ThresholdCommand:
8196 factor[MaxTextExtent] =
"128";
8201 (void) XDialogWidget(display,windows,
"Threshold",
8202 "Enter threshold value:",factor);
8203 if (*factor ==
'\0')
8208 XSetCursorState(display,windows,MagickTrue);
8209 XCheckRefreshWindows(display,windows);
8210 threshold=StringToDoubleInterval(factor,(
double) QuantumRange+1.0);
8211 (void) BilevelImage(*image,threshold);
8212 XSetCursorState(display,windows,MagickFalse);
8213 if (windows->image.orphan != MagickFalse)
8215 XConfigureImageColormap(display,resource_info,windows,*image);
8216 (void) XConfigureImage(display,resource_info,windows,*image);
8219 case EdgeDetectCommand:
8225 radius[MaxTextExtent] =
"0";
8230 (void) XDialogWidget(display,windows,
"Detect Edges",
8231 "Enter the edge detect radius:",radius);
8232 if (*radius ==
'\0')
8237 XSetCursorState(display,windows,MagickTrue);
8238 XCheckRefreshWindows(display,windows);
8239 flags=ParseGeometry(radius,&geometry_info);
8240 edge_image=EdgeImage(*image,geometry_info.rho,&(*image)->exception);
8241 if (edge_image != (
Image *) NULL)
8243 *image=DestroyImage(*image);
8246 CatchException(&(*image)->exception);
8247 XSetCursorState(display,windows,MagickFalse);
8248 if (windows->image.orphan != MagickFalse)
8250 XConfigureImageColormap(display,resource_info,windows,*image);
8251 (void) XConfigureImage(display,resource_info,windows,*image);
8260 amount[MaxTextExtent] =
"2";
8265 (void) XDialogWidget(display,windows,
"Spread",
8266 "Enter the displacement amount:",amount);
8267 if (*amount ==
'\0')
8272 XSetCursorState(display,windows,MagickTrue);
8273 XCheckRefreshWindows(display,windows);
8274 flags=ParseGeometry(amount,&geometry_info);
8275 spread_image=EdgeImage(*image,geometry_info.rho,&(*image)->exception);
8276 if (spread_image != (
Image *) NULL)
8278 *image=DestroyImage(*image);
8279 *image=spread_image;
8281 CatchException(&(*image)->exception);
8282 XSetCursorState(display,windows,MagickFalse);
8283 if (windows->image.orphan != MagickFalse)
8285 XConfigureImageColormap(display,resource_info,windows,*image);
8286 (void) XConfigureImage(display,resource_info,windows,*image);
8298 geometry[MaxTextExtent] =
"30x30";
8303 status=XDialogWidget(display,windows,
"Shade",
8304 "Enter the azimuth and elevation of the light source:",geometry);
8305 if (*geometry ==
'\0')
8310 XSetCursorState(display,windows,MagickTrue);
8311 XCheckRefreshWindows(display,windows);
8312 flags=ParseGeometry(geometry,&geometry_info);
8313 if ((flags & SigmaValue) == 0)
8314 geometry_info.sigma=1.0;
8315 shade_image=ShadeImage(*image,status != 0 ? MagickFalse : MagickTrue,
8316 geometry_info.rho,geometry_info.sigma,&(*image)->exception);
8317 if (shade_image != (
Image *) NULL)
8319 *image=DestroyImage(*image);
8322 CatchException(&(*image)->exception);
8323 XSetCursorState(display,windows,MagickFalse);
8324 if (windows->image.orphan != MagickFalse)
8326 XConfigureImageColormap(display,resource_info,windows,*image);
8327 (void) XConfigureImage(display,resource_info,windows,*image);
8333 bevel_width[MaxTextExtent] =
"10";
8338 (void) XDialogWidget(display,windows,
"Raise",
"Bevel width:",bevel_width);
8339 if (*bevel_width ==
'\0')
8344 (void) XMagickCommand(display,resource_info,windows,ApplyCommand,image);
8345 XSetCursorState(display,windows,MagickTrue);
8346 XCheckRefreshWindows(display,windows);
8347 (void) ParsePageGeometry(*image,bevel_width,&page_geometry,
8348 &(*image)->exception);
8349 (void) RaiseImage(*image,&page_geometry,MagickTrue);
8350 XSetCursorState(display,windows,MagickFalse);
8351 if (windows->image.orphan != MagickFalse)
8353 XConfigureImageColormap(display,resource_info,windows,*image);
8354 (void) XConfigureImage(display,resource_info,windows,*image);
8357 case SegmentCommand:
8360 threshold[MaxTextExtent] =
"1.0x1.5";
8365 (void) XDialogWidget(display,windows,
"Segment",
"Smooth threshold:",
8367 if (*threshold ==
'\0')
8372 XSetCursorState(display,windows,MagickTrue);
8373 XCheckRefreshWindows(display,windows);
8374 flags=ParseGeometry(threshold,&geometry_info);
8375 if ((flags & SigmaValue) == 0)
8376 geometry_info.sigma=1.0;
8377 (void) SegmentImage(*image,sRGBColorspace,MagickFalse,geometry_info.rho,
8378 geometry_info.sigma);
8379 XSetCursorState(display,windows,MagickFalse);
8380 if (windows->image.orphan != MagickFalse)
8382 XConfigureImageColormap(display,resource_info,windows,*image);
8383 (void) XConfigureImage(display,resource_info,windows,*image);
8386 case SepiaToneCommand:
8395 factor[MaxTextExtent] =
"80%";
8400 (void) XDialogWidget(display,windows,
"Sepia Tone",
8401 "Enter the sepia tone factor (0 - 99.9%):",factor);
8402 if (*factor ==
'\0')
8407 XSetCursorState(display,windows,MagickTrue);
8408 XCheckRefreshWindows(display,windows);
8409 threshold=StringToDoubleInterval(factor,(
double) QuantumRange+1.0);
8410 sepia_image=SepiaToneImage(*image,threshold,&(*image)->exception);
8411 if (sepia_image != (
Image *) NULL)
8413 *image=DestroyImage(*image);
8416 CatchException(&(*image)->exception);
8417 XSetCursorState(display,windows,MagickFalse);
8418 if (windows->image.orphan != MagickFalse)
8420 XConfigureImageColormap(display,resource_info,windows,*image);
8421 (void) XConfigureImage(display,resource_info,windows,*image);
8424 case SolarizeCommand:
8430 factor[MaxTextExtent] =
"60%";
8435 (void) XDialogWidget(display,windows,
"Solarize",
8436 "Enter the solarize factor (0 - 99.9%):",factor);
8437 if (*factor ==
'\0')
8442 XSetCursorState(display,windows,MagickTrue);
8443 XCheckRefreshWindows(display,windows);
8444 threshold=StringToDoubleInterval(factor,(
double) QuantumRange+1.0);
8445 (void) SolarizeImage(*image,threshold);
8446 XSetCursorState(display,windows,MagickFalse);
8447 if (windows->image.orphan != MagickFalse)
8449 XConfigureImageColormap(display,resource_info,windows,*image);
8450 (void) XConfigureImage(display,resource_info,windows,*image);
8459 degrees[MaxTextExtent] =
"60";
8464 (void) XDialogWidget(display,windows,
"Swirl",
"Enter the swirl angle:",
8466 if (*degrees ==
'\0')
8471 XSetCursorState(display,windows,MagickTrue);
8472 XCheckRefreshWindows(display,windows);
8473 flags=ParseGeometry(degrees,&geometry_info);
8474 swirl_image=SwirlImage(*image,geometry_info.rho,&(*image)->exception);
8475 if (swirl_image != (
Image *) NULL)
8477 *image=DestroyImage(*image);
8480 CatchException(&(*image)->exception);
8481 XSetCursorState(display,windows,MagickFalse);
8482 if (windows->image.orphan != MagickFalse)
8484 XConfigureImageColormap(display,resource_info,windows,*image);
8485 (void) XConfigureImage(display,resource_info,windows,*image);
8488 case ImplodeCommand:
8494 factor[MaxTextExtent] =
"0.3";
8499 (void) XDialogWidget(display,windows,
"Implode",
8500 "Enter the implosion/explosion factor (-1.0 - 1.0):",factor);
8501 if (*factor ==
'\0')
8506 XSetCursorState(display,windows,MagickTrue);
8507 XCheckRefreshWindows(display,windows);
8508 flags=ParseGeometry(factor,&geometry_info);
8509 implode_image=ImplodeImage(*image,geometry_info.rho,&(*image)->exception);
8510 if (implode_image != (
Image *) NULL)
8512 *image=DestroyImage(*image);
8513 *image=implode_image;
8515 CatchException(&(*image)->exception);
8516 XSetCursorState(display,windows,MagickFalse);
8517 if (windows->image.orphan != MagickFalse)
8519 XConfigureImageColormap(display,resource_info,windows,*image);
8520 (void) XConfigureImage(display,resource_info,windows,*image);
8523 case VignetteCommand:
8529 geometry[MaxTextExtent] =
"0x20";
8534 (void) XDialogWidget(display,windows,
"Vignette",
8535 "Enter the radius, sigma, and x and y offsets:",geometry);
8536 if (*geometry ==
'\0')
8541 XSetCursorState(display,windows,MagickTrue);
8542 XCheckRefreshWindows(display,windows);
8543 flags=ParseGeometry(geometry,&geometry_info);
8544 if ((flags & SigmaValue) == 0)
8545 geometry_info.sigma=1.0;
8546 if ((flags & XiValue) == 0)
8547 geometry_info.xi=0.1*(*image)->columns;
8548 if ((flags & PsiValue) == 0)
8549 geometry_info.psi=0.1*(*image)->rows;
8550 vignette_image=VignetteImage(*image,geometry_info.rho,geometry_info.sigma,
8551 (ssize_t) ceil(geometry_info.xi-0.5),(ssize_t) ceil(geometry_info.psi-
8552 0.5),&(*image)->exception);
8553 if (vignette_image != (
Image *) NULL)
8555 *image=DestroyImage(*image);
8556 *image=vignette_image;
8558 CatchException(&(*image)->exception);
8559 XSetCursorState(display,windows,MagickFalse);
8560 if (windows->image.orphan != MagickFalse)
8562 XConfigureImageColormap(display,resource_info,windows,*image);
8563 (void) XConfigureImage(display,resource_info,windows,*image);
8572 geometry[MaxTextExtent] =
"25x150";
8577 (void) XDialogWidget(display,windows,
"Wave",
8578 "Enter the amplitude and length of the wave:",geometry);
8579 if (*geometry ==
'\0')
8584 XSetCursorState(display,windows,MagickTrue);
8585 XCheckRefreshWindows(display,windows);
8586 flags=ParseGeometry(geometry,&geometry_info);
8587 if ((flags & SigmaValue) == 0)
8588 geometry_info.sigma=1.0;
8589 wave_image=WaveImage(*image,geometry_info.rho,geometry_info.sigma,
8590 &(*image)->exception);
8591 if (wave_image != (
Image *) NULL)
8593 *image=DestroyImage(*image);
8596 CatchException(&(*image)->exception);
8597 XSetCursorState(display,windows,MagickFalse);
8598 if (windows->image.orphan != MagickFalse)
8600 XConfigureImageColormap(display,resource_info,windows,*image);
8601 (void) XConfigureImage(display,resource_info,windows,*image);
8604 case OilPaintCommand:
8610 radius[MaxTextExtent] =
"0";
8615 (void) XDialogWidget(display,windows,
"Oil Paint",
8616 "Enter the mask radius:",radius);
8617 if (*radius ==
'\0')
8622 XSetCursorState(display,windows,MagickTrue);
8623 XCheckRefreshWindows(display,windows);
8624 flags=ParseGeometry(radius,&geometry_info);
8625 paint_image=OilPaintImage(*image,geometry_info.rho,&(*image)->exception);
8626 if (paint_image != (
Image *) NULL)
8628 *image=DestroyImage(*image);
8631 CatchException(&(*image)->exception);
8632 XSetCursorState(display,windows,MagickFalse);
8633 if (windows->image.orphan != MagickFalse)
8635 XConfigureImageColormap(display,resource_info,windows,*image);
8636 (void) XConfigureImage(display,resource_info,windows,*image);
8639 case CharcoalDrawCommand:
8645 radius[MaxTextExtent] =
"0x1";
8650 (void) XDialogWidget(display,windows,
"Charcoal Draw",
8651 "Enter the charcoal radius and sigma:",radius);
8652 if (*radius ==
'\0')
8657 (void) XMagickCommand(display,resource_info,windows,ApplyCommand,image);
8658 XSetCursorState(display,windows,MagickTrue);
8659 XCheckRefreshWindows(display,windows);
8660 flags=ParseGeometry(radius,&geometry_info);
8661 if ((flags & SigmaValue) == 0)
8662 geometry_info.sigma=geometry_info.rho;
8663 charcoal_image=CharcoalImage(*image,geometry_info.rho,geometry_info.sigma,
8664 &(*image)->exception);
8665 if (charcoal_image != (
Image *) NULL)
8667 *image=DestroyImage(*image);
8668 *image=charcoal_image;
8670 CatchException(&(*image)->exception);
8671 XSetCursorState(display,windows,MagickFalse);
8672 if (windows->image.orphan != MagickFalse)
8674 XConfigureImageColormap(display,resource_info,windows,*image);
8675 (void) XConfigureImage(display,resource_info,windows,*image);
8678 case AnnotateCommand:
8683 status=XAnnotateEditImage(display,resource_info,windows,*image);
8684 if (status == MagickFalse)
8686 XNoticeWidget(display,windows,
"Unable to annotate X image",
8687 (*image)->filename);
8697 status=XDrawEditImage(display,resource_info,windows,image);
8698 if (status == MagickFalse)
8700 XNoticeWidget(display,windows,
"Unable to draw on the X image",
8701 (*image)->filename);
8711 status=XColorEditImage(display,resource_info,windows,image);
8712 if (status == MagickFalse)
8714 XNoticeWidget(display,windows,
"Unable to pixel edit X image",
8715 (*image)->filename);
8725 status=XMatteEditImage(display,resource_info,windows,image);
8726 if (status == MagickFalse)
8728 XNoticeWidget(display,windows,
"Unable to matte edit X image",
8729 (*image)->filename);
8734 case CompositeCommand:
8739 status=XCompositeImage(display,resource_info,windows,*image);
8740 if (status == MagickFalse)
8742 XNoticeWidget(display,windows,
"Unable to composite X image",
8743 (*image)->filename);
8748 case AddBorderCommand:
8754 geometry[MaxTextExtent] =
"6x6";
8759 XColorBrowserWidget(display,windows,
"Select",color);
8762 (void) XDialogWidget(display,windows,
"Add Border",
8763 "Enter border geometry:",geometry);
8764 if (*geometry ==
'\0')
8769 (void) XMagickCommand(display,resource_info,windows,ApplyCommand,image);
8770 XSetCursorState(display,windows,MagickTrue);
8771 XCheckRefreshWindows(display,windows);
8772 (void) QueryColorDatabase(color,&(*image)->border_color,
8773 &(*image)->exception);
8774 (void) ParsePageGeometry(*image,geometry,&page_geometry,
8775 &(*image)->exception);
8776 border_image=BorderImage(*image,&page_geometry,&(*image)->exception);
8777 if (border_image != (
Image *) NULL)
8779 *image=DestroyImage(*image);
8780 *image=border_image;
8782 CatchException(&(*image)->exception);
8783 XSetCursorState(display,windows,MagickFalse);
8784 if (windows->image.orphan != MagickFalse)
8786 windows->image.window_changes.width=(int) (*image)->columns;
8787 windows->image.window_changes.height=(
int) (*image)->rows;
8788 XConfigureImageColormap(display,resource_info,windows,*image);
8789 (void) XConfigureImage(display,resource_info,windows,*image);
8792 case AddFrameCommand:
8801 geometry[MaxTextExtent] =
"6x6";
8806 XColorBrowserWidget(display,windows,
"Select",color);
8809 (void) XDialogWidget(display,windows,
"Add Frame",
"Enter frame geometry:",
8811 if (*geometry ==
'\0')
8816 (void) XMagickCommand(display,resource_info,windows,ApplyCommand,image);
8817 XSetCursorState(display,windows,MagickTrue);
8818 XCheckRefreshWindows(display,windows);
8819 (void) QueryColorDatabase(color,&(*image)->matte_color,
8820 &(*image)->exception);
8821 (void) ParsePageGeometry(*image,geometry,&page_geometry,
8822 &(*image)->exception);
8823 frame_info.width=page_geometry.width;
8824 frame_info.height=page_geometry.height;
8825 frame_info.outer_bevel=page_geometry.x;
8826 frame_info.inner_bevel=page_geometry.y;
8827 frame_info.x=(ssize_t) frame_info.width;
8828 frame_info.y=(ssize_t) frame_info.height;
8829 frame_info.width=(*image)->columns+2*frame_info.width;
8830 frame_info.height=(*image)->rows+2*frame_info.height;
8831 frame_image=FrameImage(*image,&frame_info,&(*image)->exception);
8832 if (frame_image != (
Image *) NULL)
8834 *image=DestroyImage(*image);
8837 CatchException(&(*image)->exception);
8838 XSetCursorState(display,windows,MagickFalse);
8839 if (windows->image.orphan != MagickFalse)
8841 windows->image.window_changes.width=(int) (*image)->columns;
8842 windows->image.window_changes.height=(
int) (*image)->rows;
8843 XConfigureImageColormap(display,resource_info,windows,*image);
8844 (void) XConfigureImage(display,resource_info,windows,*image);
8847 case CommentCommand:
8861 unique_file=AcquireUniqueFileResource(image_info->filename);
8862 if (unique_file == -1)
8864 XNoticeWidget(display,windows,
"Unable to edit image comment",
8865 image_info->filename);
8868 value=GetImageProperty(*image,
"comment");
8869 if (value == (
char *) NULL)
8870 unique_file=close(unique_file)-1;
8876 file=fdopen(unique_file,
"w");
8877 if (file == (FILE *) NULL)
8879 XNoticeWidget(display,windows,
"Unable to edit image comment",
8880 image_info->filename);
8883 for (p=value; *p !=
'\0'; p++)
8884 (
void) fputc((
int) *p,file);
8885 (void) fputc(
'\n',file);
8886 (void) fclose(file);
8888 XSetCursorState(display,windows,MagickTrue);
8889 XCheckRefreshWindows(display,windows);
8890 status=InvokeDelegate(image_info,*image,
"edit",(
char *) NULL,
8891 &(*image)->exception);
8892 if (status == MagickFalse)
8893 XNoticeWidget(display,windows,
"Unable to edit image comment",
8900 comment=FileToString(image_info->filename,~0UL,&(*image)->exception);
8901 if (comment != (
char *) NULL)
8903 (void) SetImageProperty(*image,
"comment",comment);
8904 (*image)->taint=MagickTrue;
8907 (void) RelinquishUniqueFileResource(image_info->filename);
8908 XSetCursorState(display,windows,MagickFalse);
8916 XSetCursorState(display,windows,MagickTrue);
8917 XCheckRefreshWindows(display,windows);
8918 (void) AcquireUniqueFilename(filename);
8919 (void) FormatLocaleString((*image)->filename,MaxTextExtent,
"launch:%s",
8921 status=WriteImage(image_info,*image);
8922 if (status == MagickFalse)
8923 XNoticeWidget(display,windows,
"Unable to launch image editor",
8927 nexus=ReadImage(resource_info->image_info,&(*image)->exception);
8928 CatchException(&(*image)->exception);
8929 XClientMessage(display,windows->image.id,windows->im_protocols,
8930 windows->im_next_image,CurrentTime);
8932 (void) RelinquishUniqueFileResource(filename);
8933 XSetCursorState(display,windows,MagickFalse);
8936 case RegionOfInterestCommand:
8941 (void) XROIImage(display,resource_info,windows,image);
8951 if (windows->magnify.mapped != MagickFalse)
8952 (void) XRaiseWindow(display,windows->magnify.id);
8958 XSetCursorState(display,windows,MagickTrue);
8959 (void) XMapRaised(display,windows->magnify.id);
8960 XSetCursorState(display,windows,MagickFalse);
8964 case ShowPreviewCommand:
8973 preview_type[MaxTextExtent] =
"Gamma";
8978 previews=GetCommandOptions(MagickPreviewOptions);
8979 if (previews == (
char **) NULL)
8981 XListBrowserWidget(display,windows,&windows->widget,
8982 (
const char **) previews,
"Preview",
8983 "Select an enhancement, effect, or F/X:",preview_type);
8984 previews=DestroyStringList(previews);
8985 if (*preview_type ==
'\0')
8990 XSetCursorState(display,windows,MagickTrue);
8991 XCheckRefreshWindows(display,windows);
8992 image_info->preview_type=(PreviewType)
8993 ParseCommandOption(MagickPreviewOptions,MagickFalse,preview_type);
8994 image_info->group=(ssize_t) windows->image.id;
8995 (
void) DeleteImageProperty(*image,
"label");
8996 (void) SetImageProperty(*image,
"label",
"Preview");
8997 (void) AcquireUniqueFilename(filename);
8998 (void) FormatLocaleString((*image)->filename,MaxTextExtent,
"preview:%s",
9000 status=WriteImage(image_info,*image);
9001 (void) CopyMagickString(image_info->filename,filename,MaxTextExtent);
9002 preview_image=ReadImage(image_info,&(*image)->exception);
9003 (void) RelinquishUniqueFileResource(filename);
9004 if (preview_image == (
Image *) NULL)
9006 (void) FormatLocaleString(preview_image->filename,MaxTextExtent,
"show:%s",
9008 status=WriteImage(image_info,preview_image);
9009 preview_image=DestroyImage(preview_image);
9010 if (status == MagickFalse)
9011 XNoticeWidget(display,windows,
"Unable to show image preview",
9012 (*image)->filename);
9013 XDelay(display,1500);
9014 XSetCursorState(display,windows,MagickFalse);
9017 case ShowHistogramCommand:
9025 XSetCursorState(display,windows,MagickTrue);
9026 XCheckRefreshWindows(display,windows);
9027 image_info->group=(ssize_t) windows->image.id;
9028 (
void) DeleteImageProperty(*image,
"label");
9029 (void) SetImageProperty(*image,
"label",
"Histogram");
9030 (void) AcquireUniqueFilename(filename);
9031 (void) FormatLocaleString((*image)->filename,MaxTextExtent,
"histogram:%s",
9033 status=WriteImage(image_info,*image);
9034 (void) CopyMagickString(image_info->filename,filename,MaxTextExtent);
9035 histogram_image=ReadImage(image_info,&(*image)->exception);
9036 (void) RelinquishUniqueFileResource(filename);
9037 if (histogram_image == (
Image *) NULL)
9039 (void) FormatLocaleString(histogram_image->filename,MaxTextExtent,
9040 "show:%s",filename);
9041 status=WriteImage(image_info,histogram_image);
9042 histogram_image=DestroyImage(histogram_image);
9043 if (status == MagickFalse)
9044 XNoticeWidget(display,windows,
"Unable to show histogram",
9045 (*image)->filename);
9046 XDelay(display,1500);
9047 XSetCursorState(display,windows,MagickFalse);
9050 case ShowMatteCommand:
9055 if ((*image)->matte == MagickFalse)
9057 XNoticeWidget(display,windows,
9058 "Image does not have any matte information",(*image)->filename);
9064 XSetCursorState(display,windows,MagickTrue);
9065 XCheckRefreshWindows(display,windows);
9066 image_info->group=(ssize_t) windows->image.id;
9067 (
void) DeleteImageProperty(*image,
"label");
9068 (void) SetImageProperty(*image,
"label",
"Matte");
9069 (void) AcquireUniqueFilename(filename);
9070 (void) FormatLocaleString((*image)->filename,MaxTextExtent,
"matte:%s",
9072 status=WriteImage(image_info,*image);
9073 (void) CopyMagickString(image_info->filename,filename,MaxTextExtent);
9074 matte_image=ReadImage(image_info,&(*image)->exception);
9075 (void) RelinquishUniqueFileResource(filename);
9076 if (matte_image == (
Image *) NULL)
9078 (void) FormatLocaleString(matte_image->filename,MaxTextExtent,
"show:%s",
9080 status=WriteImage(image_info,matte_image);
9081 matte_image=DestroyImage(matte_image);
9082 if (status == MagickFalse)
9083 XNoticeWidget(display,windows,
"Unable to show matte",
9084 (*image)->filename);
9085 XDelay(display,1500);
9086 XSetCursorState(display,windows,MagickFalse);
9089 case BackgroundCommand:
9094 status=XBackgroundImage(display,resource_info,windows,image);
9095 if (status == MagickFalse)
9097 nexus=CloneImage(*image,0,0,MagickTrue,&(*image)->exception);
9098 if (nexus != (
Image *) NULL)
9099 XClientMessage(display,windows->image.id,windows->im_protocols,
9100 windows->im_next_image,CurrentTime);
9103 case SlideShowCommand:
9106 delay[MaxTextExtent] =
"5";
9111 (void) XDialogWidget(display,windows,
"Slide Show",
9112 "Pause how many 1/100ths of a second between images:",delay);
9115 resource_info->delay=StringToUnsignedLong(delay);
9116 XClientMessage(display,windows->image.id,windows->im_protocols,
9117 windows->im_next_image,CurrentTime);
9120 case PreferencesCommand:
9125 status=XPreferencesWidget(display,resource_info,windows);
9126 if (status == MagickFalse)
9128 nexus=CloneImage(*image,0,0,MagickTrue,&(*image)->exception);
9129 if (nexus != (
Image *) NULL)
9130 XClientMessage(display,windows->image.id,windows->im_protocols,
9131 windows->im_next_image,CurrentTime);
9139 XTextViewHelp(display,resource_info,windows,MagickFalse,
9140 "Help Viewer - Display",DisplayHelp);
9143 case BrowseDocumentationCommand:
9155 root_window=XRootWindow(display,XDefaultScreen(display));
9156 mozilla_atom=XInternAtom(display,
"_MOZILLA_VERSION",MagickFalse);
9157 mozilla_window=XWindowByProperty(display,root_window,mozilla_atom);
9158 if (mozilla_window != (Window) NULL)
9161 command[MaxTextExtent];
9166 (void) FormatLocaleString(command,MaxTextExtent,
9167 "openurl(%s,new-tab)",MagickAuthoritativeURL);
9168 mozilla_atom=XInternAtom(display,
"_MOZILLA_COMMAND",MagickFalse);
9169 (void) XChangeProperty(display,mozilla_window,mozilla_atom,XA_STRING,
9170 8,PropModeReplace,(
unsigned char *) command,(int) strlen(command));
9171 XSetCursorState(display,windows,MagickFalse);
9174 XSetCursorState(display,windows,MagickTrue);
9175 XCheckRefreshWindows(display,windows);
9176 status=InvokeDelegate(image_info,*image,
"browse",(
char *) NULL,
9177 &(*image)->exception);
9178 if (status == MagickFalse)
9179 XNoticeWidget(display,windows,
"Unable to browse documentation",
9181 XDelay(display,1500);
9182 XSetCursorState(display,windows,MagickFalse);
9185 case VersionCommand:
9187 XNoticeWidget(display,windows,GetMagickVersion((
size_t *) NULL),
9188 GetMagickCopyright());
9191 case SaveToUndoBufferCommand:
9195 (void) XBell(display,0);
9199 image_info=DestroyImageInfo(image_info);
9232static void XMagnifyImage(Display *display,XWindows *windows,XEvent *event)
9235 text[MaxTextExtent];
9247 (void) XCheckDefineCursor(display,windows->image.id,windows->magnify.cursor);
9251 windows->magnify.x=(int) windows->image.x+x;
9252 windows->magnify.y=(
int) windows->image.y+y;
9258 if (windows->info.mapped != MagickFalse)
9260 if ((x < (
int) (windows->info.x+windows->info.width)) &&
9261 (y < (int) (windows->info.y+windows->info.height)))
9262 (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
9265 if ((x > (
int) (windows->info.x+windows->info.width)) ||
9266 (y > (int) (windows->info.y+windows->info.height)))
9267 (void) XMapWindow(display,windows->info.id);
9268 if (windows->info.mapped != MagickFalse)
9273 (void) FormatLocaleString(text,MaxTextExtent,
" %+d%+d ",
9274 windows->magnify.x,windows->magnify.y);
9275 XInfoWidget(display,windows,text);
9280 XScreenEvent(display,windows,event);
9281 switch (event->type)
9312 if (x >= (
int) windows->image.width)
9313 x=(int) windows->image.width-1;
9317 if (y >= (
int) windows->image.height)
9318 y=(
int) windows->image.height-1;
9319 }
while ((state & ExitState) == 0);
9323 XSetCursorState(display,windows,MagickFalse);
9358static void XMagnifyWindowCommand(Display *display,XWindows *windows,
9359 const MagickStatusType state,
const KeySym key_symbol)
9368 if ((state & Mod1Mask) != 0)
9370 switch ((
int) key_symbol)
9374 (void) XWithdrawWindow(display,windows->magnify.id,
9375 windows->magnify.screen);
9381 windows->magnify.x=(int) windows->image.width/2;
9382 windows->magnify.y=(
int) windows->image.height/2;
9388 if (windows->magnify.x > 0)
9389 windows->magnify.x-=quantum;
9395 if (windows->magnify.y > 0)
9396 windows->magnify.y-=quantum;
9402 if (windows->magnify.x < (
int) (windows->image.ximage->width-1))
9403 windows->magnify.x+=quantum;
9409 if (windows->magnify.y < (
int) (windows->image.ximage->height-1))
9410 windows->magnify.y+=quantum;
9424 windows->magnify.data=(key_symbol-XK_0);
9438 windows->magnify.data=(key_symbol-XK_KP_0);
9444 XMakeMagnifyImage(display,windows);
9478static void XMakePanImage(Display *display,XResourceInfo *resource_info,
9479 XWindows *windows,
Image *image)
9487 XSetCursorState(display,windows,MagickTrue);
9488 XCheckRefreshWindows(display,windows);
9489 windows->pan.x=(int) windows->image.x;
9490 windows->pan.y=(
int) windows->image.y;
9491 status=XMakeImage(display,resource_info,&windows->pan,image,
9492 windows->pan.width,windows->pan.height);
9493 if (status == MagickFalse)
9494 ThrowXWindowFatalException(XServerFatalError,image->exception.reason,
9495 image->exception.description);
9496 (void) XSetWindowBackgroundPixmap(display,windows->pan.id,
9497 windows->pan.pixmap);
9498 (void) XClearWindow(display,windows->pan.id);
9499 XDrawPanRectangle(display,windows);
9500 XSetCursorState(display,windows,MagickFalse);
9535static MagickBooleanType XMatteEditImage(Display *display,
9536 XResourceInfo *resource_info,XWindows *windows,
Image **image)
9539 *
const MatteEditMenu[] =
9552 matte[MaxTextExtent] =
"0";
9554 static const ModeType
9555 MatteEditCommands[] =
9558 MatteEditBorderCommand,
9559 MatteEditFuzzCommand,
9560 MatteEditValueCommand,
9561 MatteEditUndoCommand,
9562 MatteEditHelpCommand,
9563 MatteEditDismissCommand
9567 method = PointMethod;
9570 border_color = { 0, 0, 0, 0, 0, 0 };
9573 command[MaxTextExtent],
9574 text[MaxTextExtent] =
"";
9606 (void) CloneString(&windows->command.name,
"Matte Edit");
9607 windows->command.data=4;
9608 (void) XCommandWidget(display,windows,MatteEditMenu,(XEvent *) NULL);
9609 (void) XMapRaised(display,windows->command.id);
9610 XClientMessage(display,windows->image.id,windows->im_protocols,
9611 windows->im_update_widget,CurrentTime);
9615 cursor=XMakeCursor(display,windows->image.id,windows->map_info->colormap,
9616 resource_info->background_color,resource_info->foreground_color);
9617 (void) XCheckDefineCursor(display,windows->image.id,cursor);
9621 XQueryPosition(display,windows->image.id,&x,&y);
9622 (void) XSelectInput(display,windows->image.id,
9623 windows->image.attributes.event_mask | PointerMotionMask);
9627 if (windows->info.mapped != MagickFalse)
9632 (void) FormatLocaleString(text,MaxTextExtent,
" %+d%+d ",
9633 x+windows->image.x,y+windows->image.y);
9634 XInfoWidget(display,windows,text);
9639 XScreenEvent(display,windows,&event);
9640 if (event.xany.window == windows->command.id)
9645 id=XCommandWidget(display,windows,MatteEditMenu,&event);
9648 (void) XCheckDefineCursor(display,windows->image.id,cursor);
9651 switch (MatteEditCommands[
id])
9653 case MatteEditMethod:
9661 methods=GetCommandOptions(MagickMethodOptions);
9662 if (methods == (
char **) NULL)
9664 entry=XMenuWidget(display,windows,MatteEditMenu[
id],
9665 (
const char **) methods,command);
9667 method=(PaintMethod) ParseCommandOption(MagickMethodOptions,
9668 MagickFalse,methods[entry]);
9669 methods=DestroyStringList(methods);
9672 case MatteEditBorderCommand:
9675 *ColorMenu[MaxNumberPens];
9683 for (i=0; i < (int) (MaxNumberPens-2); i++)
9684 ColorMenu[i]=resource_info->pen_colors[i];
9685 ColorMenu[MaxNumberPens-2]=
"Browser...";
9686 ColorMenu[MaxNumberPens-1]=(
const char *) NULL;
9690 pen_number=XMenuWidget(display,windows,MatteEditMenu[
id],
9691 (
const char **) ColorMenu,command);
9694 if (pen_number == (MaxNumberPens-2))
9697 color_name[MaxTextExtent] =
"gray";
9702 resource_info->pen_colors[pen_number]=color_name;
9703 XColorBrowserWidget(display,windows,
"Select",color_name);
9704 if (*color_name ==
'\0')
9710 (void) XParseColor(display,windows->map_info->colormap,
9711 resource_info->pen_colors[pen_number],&border_color);
9714 case MatteEditFuzzCommand:
9729 fuzz[MaxTextExtent];
9734 entry=XMenuWidget(display,windows,MatteEditMenu[
id],FuzzMenu,
9740 (*image)->fuzz=StringToDoubleInterval(FuzzMenu[entry],(
double)
9744 (void) CopyMagickString(fuzz,
"20%",MaxTextExtent);
9745 (void) XDialogWidget(display,windows,
"Ok",
9746 "Enter fuzz factor (0.0 - 99.9%):",fuzz);
9749 (void) ConcatenateMagickString(fuzz,
"%",MaxTextExtent);
9750 (*image)->fuzz=StringToDoubleInterval(fuzz,(
double) QuantumRange+
9754 case MatteEditValueCommand:
9757 *
const MatteMenu[] =
9766 message[MaxTextExtent];
9771 entry=XMenuWidget(display,windows,MatteEditMenu[
id],MatteMenu,
9777 (void) FormatLocaleString(matte,MaxTextExtent,
"%g",
9778 (
double) OpaqueOpacity);
9779 if (LocaleCompare(MatteMenu[entry],
"Transparent") == 0)
9780 (
void) FormatLocaleString(matte,MaxTextExtent,
"%g",
9781 (
double) TransparentOpacity);
9784 (void) FormatLocaleString(message,MaxTextExtent,
9785 "Enter matte value (0 - " "%g" "):",(
double) QuantumRange);
9786 (void) XDialogWidget(display,windows,
"Matte",message,matte);
9791 case MatteEditUndoCommand:
9793 (void) XMagickCommand(display,resource_info,windows,UndoCommand,
9797 case MatteEditHelpCommand:
9799 XTextViewHelp(display,resource_info,windows,MagickFalse,
9800 "Help Viewer - Matte Edit",ImageMatteEditHelp);
9803 case MatteEditDismissCommand:
9815 (void) XCheckDefineCursor(display,windows->image.id,cursor);
9822 if (event.xbutton.button != Button1)
9824 if ((event.xbutton.window != windows->image.id) &&
9825 (
event.xbutton.window != windows->magnify.id))
9832 (void) XMagickCommand(display,resource_info,windows,
9833 SaveToUndoBufferCommand,image);
9834 state|=UpdateConfigurationState;
9839 if (event.xbutton.button != Button1)
9841 if ((event.xbutton.window != windows->image.id) &&
9842 (
event.xbutton.window != windows->magnify.id))
9849 XConfigureImageColormap(display,resource_info,windows,*image);
9850 (void) XConfigureImage(display,resource_info,windows,*image);
9851 XInfoWidget(display,windows,text);
9852 (void) XCheckDefineCursor(display,windows->image.id,cursor);
9853 state&=(~UpdateConfigurationState);
9861 command[MaxTextExtent];
9866 if (event.xkey.window == windows->magnify.id)
9871 window=windows->magnify.id;
9872 while (XCheckWindowEvent(display,window,KeyPressMask,&event)) ;
9874 if (event.xkey.window != windows->image.id)
9879 (void) XLookupString((XKeyEvent *) &
event.xkey,command,(int)
9880 sizeof(command),&key_symbol,(XComposeStatus *) NULL);
9881 switch ((
int) key_symbol)
9895 XTextViewHelp(display,resource_info,windows,MagickFalse,
9896 "Help Viewer - Matte Edit",ImageMatteEditHelp);
9901 (void) XBell(display,0);
9914 if (windows->info.mapped != MagickFalse)
9916 if ((x < (
int) (windows->info.x+windows->info.width)) &&
9917 (y < (int) (windows->info.y+windows->info.height)))
9918 (void) XWithdrawWindow(display,windows->info.id,
9919 windows->info.screen);
9922 if ((x > (
int) (windows->info.x+windows->info.width)) ||
9923 (y > (int) (windows->info.y+windows->info.height)))
9924 (void) XMapWindow(display,windows->info.id);
9930 if (event.xany.window == windows->magnify.id)
9932 x=windows->magnify.x-windows->image.x;
9933 y=windows->magnify.y-windows->image.y;
9937 if ((state & UpdateConfigurationState) != 0)
9952 (void) XClearArea(display,windows->image.id,x_offset,y_offset,1,1,
9954 XPutPixel(windows->image.ximage,x_offset,y_offset,
9955 windows->pixel_info->background_color.pixel);
9956 width=(
unsigned int) (*image)->columns;
9957 height=(
unsigned int) (*image)->rows;
9960 if (windows->image.crop_geometry != (
char *) NULL)
9961 (
void) XParseGeometry(windows->image.crop_geometry,&x,&y,
9964 (width*(windows->image.x+x_offset)/windows->image.ximage->width+x);
9966 (height*(windows->image.y+y_offset)/windows->image.ximage->height+y);
9967 if ((x_offset < 0) || (y_offset < 0))
9969 if ((x_offset >= (
int) (*image)->columns) ||
9970 (y_offset >= (
int) (*image)->rows))
9972 if (SetImageStorageClass(*image,DirectClass) == MagickFalse)
9973 return(MagickFalse);
9974 (*image)->matte=MagickTrue;
9975 exception=(&(*image)->exception);
9976 image_view=AcquireAuthenticCacheView(*image,exception);
9985 q=GetCacheViewAuthenticPixels(image_view,(ssize_t) x_offset,
9986 (ssize_t) y_offset,1,1,exception);
9989 q->opacity=(Quantum) StringToLong(matte);
9990 (void) SyncCacheViewAuthenticPixels(image_view,exception);
10001 (void) GetOneCacheViewVirtualPixel(image_view,(ssize_t) x_offset,
10002 (ssize_t) y_offset,&target,exception);
10003 for (y=0; y < (int) (*image)->rows; y++)
10005 q=GetCacheViewAuthenticPixels(image_view,0,(ssize_t) y,
10006 (*image)->columns,1,&(*image)->exception);
10009 for (x=0; x < (int) (*image)->columns; x++)
10011 if (IsColorSimilar(*image,q,&target))
10012 q->opacity=(Quantum) StringToLong(matte);
10015 if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
10020 case FloodfillMethod:
10021 case FillToBorderMethod:
10032 (void) GetOneVirtualMagickPixel(*image,(ssize_t) x_offset,
10033 (ssize_t) y_offset,&target,exception);
10034 if (method == FillToBorderMethod)
10036 target.red=(MagickRealType)
10037 ScaleShortToQuantum(border_color.red);
10038 target.green=(MagickRealType)
10039 ScaleShortToQuantum(border_color.green);
10040 target.blue=(MagickRealType)
10041 ScaleShortToQuantum(border_color.blue);
10043 draw_info=CloneDrawInfo(resource_info->image_info,
10045 draw_info->fill.opacity=ClampToQuantum(StringToDouble(matte,
10047 (void) FloodfillPaintImage(*image,OpacityChannel,draw_info,&target,
10048 (ssize_t) x_offset,(ssize_t) y_offset,
10049 method == FloodfillMethod ? MagickFalse : MagickTrue);
10050 draw_info=DestroyDrawInfo(draw_info);
10058 if (SetImageStorageClass(*image,DirectClass) == MagickFalse)
10059 return(MagickFalse);
10060 for (y=0; y < (int) (*image)->rows; y++)
10062 q=QueueCacheViewAuthenticPixels(image_view,0,(ssize_t) y,
10063 (*image)->columns,1,exception);
10066 for (x=0; x < (int) (*image)->columns; x++)
10068 q->opacity=(Quantum) StringToLong(matte);
10071 if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
10074 if (StringToLong(matte) == OpaqueOpacity)
10075 (*image)->matte=MagickFalse;
10079 image_view=DestroyCacheView(image_view);
10080 state&=(~UpdateConfigurationState);
10082 }
while ((state & ExitState) == 0);
10083 (void) XSelectInput(display,windows->image.id,
10084 windows->image.attributes.event_mask);
10085 XSetCursorState(display,windows,MagickFalse);
10086 (void) XFreeCursor(display,cursor);
10087 return(MagickTrue);
10121static Image *XOpenImage(Display *display,XResourceInfo *resource_info,
10122 XWindows *windows,
const MagickBooleanType command)
10137 filename[MaxTextExtent] =
"\0";
10142 if (command == MagickFalse)
10143 XFileBrowserWidget(display,windows,
"Open",filename);
10161 status=XGetCommand(display,windows->image.id,&files,&count);
10163 ThrowXWindowException(XServerError,
"UnableToGetProperty",
"...");
10164 filelist=(
char **) AcquireQuantumMemory((
size_t) count,
sizeof(*filelist));
10165 if (filelist == (
char **) NULL)
10167 (void) XFreeStringList(files);
10168 ThrowXWindowException(ResourceLimitError,
10169 "MemoryAllocationFailed",
"...");
10170 return((
Image *) NULL);
10173 for (i=1; i < count; i++)
10174 if (*files[i] !=
'-')
10175 filelist[j++]=files[i];
10176 filelist[j]=(
char *) NULL;
10177 XListBrowserWidget(display,windows,&windows->widget,
10178 (
const char **) filelist,
"Load",
"Select Image to Load:",filename);
10179 filelist=(
char **) RelinquishMagickMemory(filelist);
10180 (void) XFreeStringList(files);
10182 if (*filename ==
'\0')
10183 return((
Image *) NULL);
10184 image_info=CloneImageInfo(resource_info->image_info);
10185 (void) SetImageInfoProgressMonitor(image_info,(MagickProgressMonitor) NULL,
10187 (void) CopyMagickString(image_info->filename,filename,MaxTextExtent);
10188 exception=AcquireExceptionInfo();
10189 (void) SetImageInfo(image_info,0,exception);
10190 if (LocaleCompare(image_info->magick,
"X") == 0)
10193 seconds[MaxTextExtent];
10198 (void) CopyMagickString(seconds,
"0",MaxTextExtent);
10199 (void) XDialogWidget(display,windows,
"Grab",
"Enter any delay in seconds:",
10201 if (*seconds ==
'\0')
10202 return((
Image *) NULL);
10203 XDelay(display,(
size_t) (1000*StringToLong(seconds)));
10205 magick_info=GetMagickInfo(image_info->magick,exception);
10206 if ((magick_info != (
const MagickInfo *) NULL) &&
10207 (magick_info->raw != MagickFalse))
10210 geometry[MaxTextExtent];
10215 (void) CopyMagickString(geometry,
"512x512",MaxTextExtent);
10216 if (image_info->size != (
char *) NULL)
10217 (
void) CopyMagickString(geometry,image_info->size,MaxTextExtent);
10218 (void) XDialogWidget(display,windows,
"Load",
"Enter the image geometry:",
10220 (void) CloneString(&image_info->size,geometry);
10225 XSetCursorState(display,windows,MagickTrue);
10226 XCheckRefreshWindows(display,windows);
10227 (void) CopyMagickString(image_info->filename,filename,MaxTextExtent);
10228 nexus=ReadImage(image_info,exception);
10229 CatchException(exception);
10230 XSetCursorState(display,windows,MagickFalse);
10231 if (nexus != (
Image *) NULL)
10232 XClientMessage(display,windows->image.id,windows->im_protocols,
10233 windows->im_next_image,CurrentTime);
10243 text=FileToString(filename,~0UL,exception);
10244 if (text == (
char *) NULL)
10245 return((
Image *) NULL);
10246 textlist=StringToList(text);
10247 if (textlist != (
char **) NULL)
10250 title[MaxTextExtent];
10255 (void) FormatLocaleString(title,MaxTextExtent,
10256 "Unknown format: %s",filename);
10257 XTextViewWidget(display,resource_info,windows,MagickTrue,title,
10258 (
const char **) textlist);
10259 for (i=0; textlist[i] != (
char *) NULL; i++)
10260 textlist[i]=DestroyString(textlist[i]);
10261 textlist=(
char **) RelinquishMagickMemory(textlist);
10263 text=DestroyString(text);
10265 exception=DestroyExceptionInfo(exception);
10266 image_info=DestroyImageInfo(image_info);
10298static void XPanImage(Display *display,XWindows *windows,XEvent *event)
10301 text[MaxTextExtent];
10319 if ((windows->image.ximage->width > (
int) windows->image.width) &&
10320 (windows->image.ximage->height > (
int) windows->image.height))
10321 cursor=XCreateFontCursor(display,XC_fleur);
10323 if (windows->image.ximage->width > (
int) windows->image.width)
10324 cursor=XCreateFontCursor(display,XC_sb_h_double_arrow);
10326 if (windows->image.ximage->height > (
int) windows->image.height)
10327 cursor=XCreateFontCursor(display,XC_sb_v_double_arrow);
10329 cursor=XCreateFontCursor(display,XC_arrow);
10330 (void) XCheckDefineCursor(display,windows->pan.id,cursor);
10334 x_factor=(MagickRealType) windows->image.ximage->width/windows->pan.width;
10335 y_factor=(MagickRealType) windows->image.ximage->height/windows->pan.height;
10336 pan_info.width=windows->pan.width*windows->image.width/
10337 windows->image.ximage->width;
10338 pan_info.height=windows->pan.height*windows->image.height/
10339 windows->image.ximage->height;
10342 state=UpdateConfigurationState;
10345 switch (event->type)
10352 pan_info.x=(ssize_t) event->xbutton.x;
10353 pan_info.y=(ssize_t)
event->xbutton.y;
10354 state|=UpdateConfigurationState;
10357 case ButtonRelease:
10362 pan_info.x=(ssize_t) event->xbutton.x;
10363 pan_info.y=(ssize_t)
event->xbutton.y;
10364 state|=UpdateConfigurationState | ExitState;
10369 pan_info.x=(ssize_t) event->xmotion.x;
10370 pan_info.y=(ssize_t)
event->xmotion.y;
10371 state|=UpdateConfigurationState;
10376 if ((state & UpdateConfigurationState) != 0)
10381 if (pan_info.x < (ssize_t) (pan_info.width/2))
10384 pan_info.x=(ssize_t) (x_factor*(pan_info.x-(pan_info.width/2)));
10385 if (pan_info.x < 0)
10388 if ((
int) (pan_info.x+windows->image.width) >
10389 windows->image.ximage->width)
10390 pan_info.x=(ssize_t)
10391 (windows->image.ximage->width-windows->image.width);
10392 if (pan_info.y < (ssize_t) (pan_info.height/2))
10395 pan_info.y=(ssize_t) (y_factor*(pan_info.y-(pan_info.height/2)));
10396 if (pan_info.y < 0)
10399 if ((
int) (pan_info.y+windows->image.height) >
10400 windows->image.ximage->height)
10401 pan_info.y=(ssize_t)
10402 (windows->image.ximage->height-windows->image.height);
10403 if ((windows->image.x != (
int) pan_info.x) ||
10404 (windows->image.y != (
int) pan_info.y))
10409 windows->image.x=(int) pan_info.x;
10410 windows->image.y=(
int) pan_info.y;
10411 (void) FormatLocaleString(text,MaxTextExtent,
" %ux%u%+d%+d ",
10412 windows->image.width,windows->image.height,windows->image.x,
10414 XInfoWidget(display,windows,text);
10418 XDrawPanRectangle(display,windows);
10419 XRefreshWindow(display,&windows->image,(XEvent *) NULL);
10421 state&=(~UpdateConfigurationState);
10426 if ((state & ExitState) == 0)
10427 XScreenEvent(display,windows,event);
10428 }
while ((state & ExitState) == 0);
10432 (void) XCheckDefineCursor(display,windows->pan.id,windows->pan.cursor);
10433 (void) XFreeCursor(display,cursor);
10434 (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
10468static MagickBooleanType XPasteImage(Display *display,
10469 XResourceInfo *resource_info,XWindows *windows,
Image *image)
10472 *
const PasteMenu[] =
10480 static const ModeType
10483 PasteOperatorsCommand,
10485 PasteDismissCommand
10488 static CompositeOperator
10489 compose = CopyCompositeOp;
10492 text[MaxTextExtent];
10526 if (resource_info->copy_image == (
Image *) NULL)
10527 return(MagickFalse);
10528 paste_image=CloneImage(resource_info->copy_image,0,0,MagickTrue,
10529 &image->exception);
10530 if (paste_image == (
Image *) NULL)
10531 return(MagickFalse);
10535 (void) CloneString(&windows->command.name,
"Paste");
10536 windows->command.data=1;
10537 (void) XCommandWidget(display,windows,PasteMenu,(XEvent *) NULL);
10538 (void) XMapRaised(display,windows->command.id);
10539 XClientMessage(display,windows->image.id,windows->im_protocols,
10540 windows->im_update_widget,CurrentTime);
10544 XSetCursorState(display,windows,MagickFalse);
10545 XQueryPosition(display,windows->image.id,&x,&y);
10546 (void) XSelectInput(display,windows->image.id,
10547 windows->image.attributes.event_mask | PointerMotionMask);
10548 paste_info.x=(ssize_t) windows->image.x+x;
10549 paste_info.y=(ssize_t) windows->image.y+y;
10550 paste_info.width=0;
10551 paste_info.height=0;
10552 cursor=XCreateFontCursor(display,XC_ul_angle);
10553 (void) XSetFunction(display,windows->image.highlight_context,GXinvert);
10554 state=DefaultState;
10557 if (windows->info.mapped != MagickFalse)
10562 (void) FormatLocaleString(text,MaxTextExtent,
" %+ld%+ld ",
10563 (
long) paste_info.x,(long) paste_info.y);
10564 XInfoWidget(display,windows,text);
10566 highlight_info=paste_info;
10567 highlight_info.x=paste_info.x-windows->image.x;
10568 highlight_info.y=paste_info.y-windows->image.y;
10569 XHighlightRectangle(display,windows->image.id,
10570 windows->image.highlight_context,&highlight_info);
10574 XScreenEvent(display,windows,&event);
10575 XHighlightRectangle(display,windows->image.id,
10576 windows->image.highlight_context,&highlight_info);
10577 if (event.xany.window == windows->command.id)
10582 id=XCommandWidget(display,windows,PasteMenu,&event);
10585 switch (PasteCommands[
id])
10587 case PasteOperatorsCommand:
10590 command[MaxTextExtent],
10596 operators=GetCommandOptions(MagickComposeOptions);
10597 if (operators == (
char **) NULL)
10599 entry=XMenuWidget(display,windows,PasteMenu[
id],
10600 (
const char **) operators,command);
10602 compose=(CompositeOperator) ParseCommandOption(
10603 MagickComposeOptions,MagickFalse,operators[entry]);
10604 operators=DestroyStringList(operators);
10607 case PasteHelpCommand:
10609 XTextViewHelp(display,resource_info,windows,MagickFalse,
10610 "Help Viewer - Image Composite",ImagePasteHelp);
10613 case PasteDismissCommand:
10618 state|=EscapeState;
10627 switch (event.type)
10631 if (resource_info->debug != MagickFalse)
10632 (void) LogMagickEvent(X11Event,GetMagickModule(),
10633 "Button Press: 0x%lx %u +%d+%d",
event.xbutton.window,
10634 event.xbutton.button,
event.xbutton.x,
event.xbutton.y);
10635 if (event.xbutton.button != Button1)
10637 if (event.xbutton.window != windows->image.id)
10642 width=(
unsigned int) image->columns;
10643 height=(
unsigned int) image->rows;
10646 if (windows->image.crop_geometry != (
char *) NULL)
10647 (
void) XParseGeometry(windows->image.crop_geometry,&x,&y,
10649 scale_factor=(MagickRealType) windows->image.ximage->width/width;
10650 paste_info.width=(
unsigned int) (scale_factor*paste_image->columns+0.5);
10651 scale_factor=(MagickRealType) windows->image.ximage->height/height;
10652 paste_info.height=(
unsigned int) (scale_factor*paste_image->rows+0.5);
10653 (void) XCheckDefineCursor(display,windows->image.id,cursor);
10654 paste_info.x=(ssize_t) windows->image.x+event.xbutton.x;
10655 paste_info.y=(ssize_t) windows->image.y+
event.xbutton.y;
10658 case ButtonRelease:
10660 if (resource_info->debug != MagickFalse)
10661 (void) LogMagickEvent(X11Event,GetMagickModule(),
10662 "Button Release: 0x%lx %u +%d+%d",
event.xbutton.window,
10663 event.xbutton.button,
event.xbutton.x,
event.xbutton.y);
10664 if (event.xbutton.button != Button1)
10666 if (event.xbutton.window != windows->image.id)
10668 if ((paste_info.width != 0) && (paste_info.height != 0))
10673 paste_info.x=(ssize_t) windows->image.x+event.xbutton.x;
10674 paste_info.y=(ssize_t) windows->image.y+
event.xbutton.y;
10684 command[MaxTextExtent];
10692 if (event.xkey.window != windows->image.id)
10697 length=XLookupString((XKeyEvent *) &event.xkey,command,(
int)
10698 sizeof(command),&key_symbol,(XComposeStatus *) NULL);
10699 *(command+length)=
'\0';
10700 if (resource_info->debug != MagickFalse)
10701 (void) LogMagickEvent(X11Event,GetMagickModule(),
10702 "Key press: 0x%lx (%s)",(long) key_symbol,command);
10703 switch ((
int) key_symbol)
10711 paste_image=DestroyImage(paste_image);
10712 state|=EscapeState;
10719 (void) XSetFunction(display,windows->image.highlight_context,
10721 XTextViewHelp(display,resource_info,windows,MagickFalse,
10722 "Help Viewer - Image Composite",ImagePasteHelp);
10723 (void) XSetFunction(display,windows->image.highlight_context,
10729 (void) XBell(display,0);
10742 if (windows->info.mapped != MagickFalse)
10744 if ((x < (
int) (windows->info.x+windows->info.width)) &&
10745 (y < (int) (windows->info.y+windows->info.height)))
10746 (void) XWithdrawWindow(display,windows->info.id,
10747 windows->info.screen);
10750 if ((x > (
int) (windows->info.x+windows->info.width)) ||
10751 (y > (int) (windows->info.y+windows->info.height)))
10752 (void) XMapWindow(display,windows->info.id);
10753 paste_info.x=(ssize_t) windows->image.x+x;
10754 paste_info.y=(ssize_t) windows->image.y+y;
10759 if (resource_info->debug != MagickFalse)
10760 (void) LogMagickEvent(X11Event,GetMagickModule(),
"Event type: %d",
10765 }
while ((state & ExitState) == 0);
10766 (void) XSelectInput(display,windows->image.id,
10767 windows->image.attributes.event_mask);
10768 (void) XSetFunction(display,windows->image.highlight_context,GXcopy);
10769 XSetCursorState(display,windows,MagickFalse);
10770 (void) XFreeCursor(display,cursor);
10771 if ((state & EscapeState) != 0)
10772 return(MagickTrue);
10776 XSetCursorState(display,windows,MagickTrue);
10777 XCheckRefreshWindows(display,windows);
10778 width=(
unsigned int) image->columns;
10779 height=(
unsigned int) image->rows;
10782 if (windows->image.crop_geometry != (
char *) NULL)
10783 (
void) XParseGeometry(windows->image.crop_geometry,&x,&y,&width,&height);
10784 scale_factor=(MagickRealType) width/windows->image.ximage->width;
10786 paste_info.x=(ssize_t) (scale_factor*paste_info.x+0.5);
10787 paste_info.width=(
unsigned int) (scale_factor*paste_info.width+0.5);
10788 scale_factor=(MagickRealType) height/windows->image.ximage->height;
10790 paste_info.y=(ssize_t) (scale_factor*paste_info.y*scale_factor+0.5);
10791 paste_info.height=(
unsigned int) (scale_factor*paste_info.height+0.5);
10795 (void) CompositeImage(image,compose,paste_image,paste_info.x,paste_info.y);
10796 paste_image=DestroyImage(paste_image);
10797 XSetCursorState(display,windows,MagickFalse);
10801 XConfigureImageColormap(display,resource_info,windows,image);
10802 (void) XConfigureImage(display,resource_info,windows,image);
10803 return(MagickTrue);
10836static MagickBooleanType XPrintImage(Display *display,
10837 XResourceInfo *resource_info,XWindows *windows,
Image *image)
10840 filename[MaxTextExtent],
10841 geometry[MaxTextExtent];
10844 *
const PageSizes[] =
10875 image_info=CloneImageInfo(resource_info->image_info);
10876 (void) FormatLocaleString(geometry,MaxTextExtent,
"Letter");
10877 if (image_info->page != (
char *) NULL)
10878 (
void) CopyMagickString(geometry,image_info->page,MaxTextExtent);
10879 XListBrowserWidget(display,windows,&windows->widget,PageSizes,
"Select",
10880 "Select Postscript Page Geometry:",geometry);
10881 if (*geometry ==
'\0')
10882 return(MagickTrue);
10883 image_info->page=GetPageGeometry(geometry);
10887 XSetCursorState(display,windows,MagickTrue);
10888 XCheckRefreshWindows(display,windows);
10889 print_image=CloneImage(image,0,0,MagickTrue,&image->exception);
10890 if (print_image == (
Image *) NULL)
10891 return(MagickFalse);
10892 (void) FormatLocaleString(geometry,MaxTextExtent,
"%dx%d!",
10893 windows->image.ximage->width,windows->image.ximage->height);
10894 (void) TransformImage(&print_image,windows->image.crop_geometry,geometry);
10898 (void) AcquireUniqueFilename(filename);
10899 (void) FormatLocaleString(print_image->filename,MaxTextExtent,
"print:%s",
10901 status=WriteImage(image_info,print_image);
10902 (void) RelinquishUniqueFileResource(filename);
10903 print_image=DestroyImage(print_image);
10904 image_info=DestroyImageInfo(image_info);
10905 XSetCursorState(display,windows,MagickFalse);
10906 return(status != 0 ? MagickTrue : MagickFalse);
10939static MagickBooleanType XROIImage(Display *display,
10940 XResourceInfo *resource_info,XWindows *windows,
Image **image)
10942#define ApplyMenus 7
10951 *
const ApplyMenu[] =
10964 *
const FileMenu[] =
10970 *
const EditMenu[] =
10976 *
const TransformMenu[] =
10984 *
const EnhanceMenu[] =
10992 "Contrast Stretch...",
10993 "Sigmoidal Contrast...",
11002 *
const EffectsMenu[] =
11027 "Charcoal Draw...",
11030 *
const MiscellanyMenu[] =
11041 *
const *Menus[ApplyMenus] =
11052 static const DisplayCommand
11075 TransformCommands[] =
11079 RotateRightCommand,
11082 EnhanceCommands[] =
11090 ContrastStretchCommand,
11091 SigmoidalContrastCommand,
11099 EffectsCommands[] =
11103 ReduceNoiseCommand,
11122 CharcoalDrawCommand
11124 MiscellanyCommands[] =
11128 ShowPreviewCommand,
11129 ShowHistogramCommand,
11138 static const DisplayCommand
11139 *Commands[ApplyMenus] =
11151 command[MaxTextExtent],
11152 text[MaxTextExtent];
11172 MagickProgressMonitor
11193 (void) CloneString(&windows->command.name,
"ROI");
11194 windows->command.data=0;
11195 (void) XCommandWidget(display,windows,ROIMenu,(XEvent *) NULL);
11196 (void) XMapRaised(display,windows->command.id);
11197 XClientMessage(display,windows->image.id,windows->im_protocols,
11198 windows->im_update_widget,CurrentTime);
11202 XQueryPosition(display,windows->image.id,&x,&y);
11203 (void) XSelectInput(display,windows->image.id,
11204 windows->image.attributes.event_mask | PointerMotionMask);
11206 crop_info.height=0;
11209 roi_info.x=(ssize_t) windows->image.x+x;
11210 roi_info.y=(ssize_t) windows->image.y+y;
11213 cursor=XCreateFontCursor(display,XC_fleur);
11214 state=DefaultState;
11217 if (windows->info.mapped != MagickFalse)
11222 (void) FormatLocaleString(text,MaxTextExtent,
" %+ld%+ld ",
11223 (
long) roi_info.x,(long) roi_info.y);
11224 XInfoWidget(display,windows,text);
11229 XScreenEvent(display,windows,&event);
11230 if (event.xany.window == windows->command.id)
11235 id=XCommandWidget(display,windows,ROIMenu,&event);
11238 switch (ROICommands[
id])
11240 case ROIHelpCommand:
11242 XTextViewHelp(display,resource_info,windows,MagickFalse,
11243 "Help Viewer - Region of Interest",ImageROIHelp);
11246 case ROIDismissCommand:
11251 state|=EscapeState;
11260 switch (event.type)
11264 if (event.xbutton.button != Button1)
11266 if (event.xbutton.window != windows->image.id)
11271 (void) XCheckDefineCursor(display,windows->image.id,cursor);
11272 roi_info.x=(ssize_t) windows->image.x+event.xbutton.x;
11273 roi_info.y=(ssize_t) windows->image.y+
event.xbutton.y;
11277 case ButtonRelease:
11286 if (event.xkey.window != windows->image.id)
11291 (void) XLookupString((XKeyEvent *) &
event.xkey,command,(int)
11292 sizeof(command),&key_symbol,(XComposeStatus *) NULL);
11293 switch ((
int) key_symbol)
11301 state|=EscapeState;
11308 XTextViewHelp(display,resource_info,windows,MagickFalse,
11309 "Help Viewer - Region of Interest",ImageROIHelp);
11314 (void) XBell(display,0);
11327 if (windows->info.mapped != MagickFalse)
11329 if ((x < (
int) (windows->info.x+windows->info.width)) &&
11330 (y < (int) (windows->info.y+windows->info.height)))
11331 (void) XWithdrawWindow(display,windows->info.id,
11332 windows->info.screen);
11335 if ((x > (
int) (windows->info.x+windows->info.width)) ||
11336 (y > (int) (windows->info.y+windows->info.height)))
11337 (void) XMapWindow(display,windows->info.id);
11338 roi_info.x=(ssize_t) windows->image.x+x;
11339 roi_info.y=(ssize_t) windows->image.y+y;
11345 }
while ((state & ExitState) == 0);
11346 (void) XSelectInput(display,windows->image.id,
11347 windows->image.attributes.event_mask);
11348 if ((state & EscapeState) != 0)
11353 (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
11354 (void) XFreeCursor(display,cursor);
11355 return(MagickTrue);
11357 (void) XSetFunction(display,windows->image.highlight_context,GXinvert);
11363 x=(int) roi_info.x;
11364 y=(
int) roi_info.y;
11367 state=DefaultState;
11370 highlight_info=roi_info;
11371 highlight_info.x=roi_info.x-windows->image.x;
11372 highlight_info.y=roi_info.y-windows->image.y;
11373 if ((highlight_info.width > 3) && (highlight_info.height > 3))
11378 if (windows->info.mapped == MagickFalse)
11379 (void) XMapWindow(display,windows->info.id);
11380 (void) FormatLocaleString(text,MaxTextExtent,
11381 " %.20gx%.20g%+.20g%+.20g",(
double) roi_info.width,(double)
11382 roi_info.height,(
double) roi_info.x,(double) roi_info.y);
11383 XInfoWidget(display,windows,text);
11384 XHighlightRectangle(display,windows->image.id,
11385 windows->image.highlight_context,&highlight_info);
11388 if (windows->info.mapped != MagickFalse)
11389 (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
11393 XScreenEvent(display,windows,&event);
11394 if ((highlight_info.width > 3) && (highlight_info.height > 3))
11395 XHighlightRectangle(display,windows->image.id,
11396 windows->image.highlight_context,&highlight_info);
11397 switch (event.type)
11401 roi_info.x=(ssize_t) windows->image.x+event.xbutton.x;
11402 roi_info.y=(ssize_t) windows->image.y+
event.xbutton.y;
11405 case ButtonRelease:
11410 roi_info.x=(ssize_t) windows->image.x+event.xbutton.x;
11411 roi_info.y=(ssize_t) windows->image.y+
event.xbutton.y;
11412 XSetCursorState(display,windows,MagickFalse);
11414 if (LocaleCompare(windows->command.name,
"Apply") == 0)
11416 (void) CloneString(&windows->command.name,
"Apply");
11417 windows->command.data=ApplyMenus;
11418 (void) XCommandWidget(display,windows,ApplyMenu,(XEvent *) NULL);
11425 roi_info.x=(ssize_t) windows->image.x+event.xmotion.x;
11426 roi_info.y=(ssize_t) windows->image.y+
event.xmotion.y;
11431 if ((((
int) roi_info.x != x) && ((
int) roi_info.y != y)) ||
11432 ((state & ExitState) != 0))
11437 if (roi_info.x < 0)
11440 if (roi_info.x > (ssize_t) windows->image.ximage->width)
11441 roi_info.x=(ssize_t) windows->image.ximage->width;
11442 if ((
int) roi_info.x < x)
11443 roi_info.width=(
unsigned int) (x-roi_info.x);
11446 roi_info.width=(
unsigned int) (roi_info.x-x);
11447 roi_info.x=(ssize_t) x;
11449 if (roi_info.y < 0)
11452 if (roi_info.y > (ssize_t) windows->image.ximage->height)
11453 roi_info.y=(ssize_t) windows->image.ximage->height;
11454 if ((
int) roi_info.y < y)
11455 roi_info.height=(
unsigned int) (y-roi_info.y);
11458 roi_info.height=(
unsigned int) (roi_info.y-y);
11459 roi_info.y=(ssize_t) y;
11462 }
while ((state & ExitState) == 0);
11466 state=DefaultState;
11467 display_command=NullCommand;
11468 (void) XMapWindow(display,windows->info.id);
11471 if (windows->info.mapped != MagickFalse)
11476 (void) FormatLocaleString(text,MaxTextExtent,
11477 " %.20gx%.20g%+.20g%+.20g",(
double) roi_info.width,(double)
11478 roi_info.height,(
double) roi_info.x,(double) roi_info.y);
11479 XInfoWidget(display,windows,text);
11481 highlight_info=roi_info;
11482 highlight_info.x=roi_info.x-windows->image.x;
11483 highlight_info.y=roi_info.y-windows->image.y;
11484 if ((highlight_info.width <= 3) || (highlight_info.height <= 3))
11486 state|=EscapeState;
11490 if ((state & UpdateRegionState) != 0)
11492 (void) XSetFunction(display,windows->image.highlight_context,GXcopy);
11493 switch (display_command)
11498 (void) XMagickCommand(display,resource_info,windows,
11499 display_command,image);
11507 progress_monitor=SetImageProgressMonitor(*image,
11508 (MagickProgressMonitor) NULL,(*image)->client_data);
11509 crop_info=roi_info;
11510 width=(
unsigned int) (*image)->columns;
11511 height=(
unsigned int) (*image)->rows;
11514 if (windows->image.crop_geometry != (
char *) NULL)
11515 (
void) XParseGeometry(windows->image.crop_geometry,&x,&y,
11517 scale_factor=(MagickRealType) width/windows->image.ximage->width;
11519 crop_info.x=(ssize_t) (scale_factor*crop_info.x+0.5);
11520 crop_info.width=(
unsigned int) (scale_factor*crop_info.width+0.5);
11521 scale_factor=(MagickRealType)
11522 height/windows->image.ximage->height;
11524 crop_info.y=(ssize_t) (scale_factor*crop_info.y+0.5);
11525 crop_info.height=(
unsigned int)
11526 (scale_factor*crop_info.height+0.5);
11527 roi_image=CropImage(*image,&crop_info,&(*image)->exception);
11528 (void) SetImageProgressMonitor(*image,progress_monitor,
11529 (*image)->client_data);
11530 if (roi_image == (
Image *) NULL)
11535 windows->image.orphan=MagickTrue;
11536 (void) XMagickCommand(display,resource_info,windows,
11537 display_command,&roi_image);
11538 progress_monitor=SetImageProgressMonitor(*image,
11539 (MagickProgressMonitor) NULL,(*image)->client_data);
11540 (void) XMagickCommand(display,resource_info,windows,
11541 SaveToUndoBufferCommand,image);
11542 windows->image.orphan=MagickFalse;
11543 (void) CompositeImage(*image,CopyCompositeOp,roi_image,
11544 crop_info.x,crop_info.y);
11545 roi_image=DestroyImage(roi_image);
11546 (void) SetImageProgressMonitor(*image,progress_monitor,
11547 (*image)->client_data);
11551 if (display_command != InfoCommand)
11553 XConfigureImageColormap(display,resource_info,windows,*image);
11554 (void) XConfigureImage(display,resource_info,windows,*image);
11556 XCheckRefreshWindows(display,windows);
11557 XInfoWidget(display,windows,text);
11558 (void) XSetFunction(display,windows->image.highlight_context,
11560 state&=(~UpdateRegionState);
11562 XHighlightRectangle(display,windows->image.id,
11563 windows->image.highlight_context,&highlight_info);
11564 XScreenEvent(display,windows,&event);
11565 if (event.xany.window == windows->command.id)
11570 (void) XSetFunction(display,windows->image.highlight_context,GXcopy);
11571 display_command=NullCommand;
11572 id=XCommandWidget(display,windows,ApplyMenu,&event);
11575 (void) CopyMagickString(command,ApplyMenu[
id],MaxTextExtent);
11576 display_command=ApplyCommands[id];
11577 if (
id < ApplyMenus)
11582 entry=XMenuWidget(display,windows,ApplyMenu[
id],
11583 (
const char **) Menus[
id],command);
11586 (void) CopyMagickString(command,Menus[
id][entry],
11588 display_command=Commands[id][entry];
11592 (void) XSetFunction(display,windows->image.highlight_context,
11594 XHighlightRectangle(display,windows->image.id,
11595 windows->image.highlight_context,&highlight_info);
11596 if (display_command == HelpCommand)
11598 (void) XSetFunction(display,windows->image.highlight_context,
11600 XTextViewHelp(display,resource_info,windows,MagickFalse,
11601 "Help Viewer - Region of Interest",ImageROIHelp);
11602 (void) XSetFunction(display,windows->image.highlight_context,
11606 if (display_command == QuitCommand)
11611 state|=EscapeState;
11615 if (display_command != NullCommand)
11616 state|=UpdateRegionState;
11619 XHighlightRectangle(display,windows->image.id,
11620 windows->image.highlight_context,&highlight_info);
11621 switch (event.type)
11625 x=windows->image.x;
11626 y=windows->image.y;
11627 if (event.xbutton.button != Button1)
11629 if (event.xbutton.window != windows->image.id)
11631 x=windows->image.x+
event.xbutton.x;
11632 y=windows->image.y+
event.xbutton.y;
11633 if ((x < (
int) (roi_info.x+RoiDelta)) &&
11634 (x > (
int) (roi_info.x-RoiDelta)) &&
11635 (y < (
int) (roi_info.y+RoiDelta)) &&
11636 (y > (
int) (roi_info.y-RoiDelta)))
11638 roi_info.x=(ssize_t) (roi_info.x+roi_info.width);
11639 roi_info.y=(ssize_t) (roi_info.y+roi_info.height);
11640 state|=UpdateConfigurationState;
11643 if ((x < (
int) (roi_info.x+RoiDelta)) &&
11644 (x > (int) (roi_info.x-RoiDelta)) &&
11645 (y < (
int) (roi_info.y+roi_info.height+RoiDelta)) &&
11646 (y > (int) (roi_info.y+roi_info.height-RoiDelta)))
11648 roi_info.x=(ssize_t) (roi_info.x+roi_info.width);
11649 state|=UpdateConfigurationState;
11652 if ((x < (
int) (roi_info.x+roi_info.width+RoiDelta)) &&
11653 (x > (int) (roi_info.x+roi_info.width-RoiDelta)) &&
11654 (y < (
int) (roi_info.y+RoiDelta)) &&
11655 (y > (int) (roi_info.y-RoiDelta)))
11657 roi_info.y=(ssize_t) (roi_info.y+roi_info.height);
11658 state|=UpdateConfigurationState;
11661 if ((x < (
int) (roi_info.x+roi_info.width+RoiDelta)) &&
11662 (x > (int) (roi_info.x+roi_info.width-RoiDelta)) &&
11663 (y < (
int) (roi_info.y+roi_info.height+RoiDelta)) &&
11664 (y > (int) (roi_info.y+roi_info.height-RoiDelta)))
11666 state|=UpdateConfigurationState;
11669 magick_fallthrough;
11671 case ButtonRelease:
11673 if (event.xbutton.window == windows->pan.id)
11674 if ((highlight_info.x != crop_info.x-windows->image.x) ||
11675 (highlight_info.y != crop_info.y-windows->image.y))
11676 XHighlightRectangle(display,windows->image.id,
11677 windows->image.highlight_context,&highlight_info);
11678 (void) XSetSelectionOwner(display,XA_PRIMARY,windows->image.id,
11679 event.xbutton.time);
11684 if (event.xexpose.window == windows->image.id)
11685 if (event.xexpose.count == 0)
11687 event.xexpose.x=(int) highlight_info.x;
11688 event.xexpose.y=(
int) highlight_info.y;
11689 event.xexpose.width=(int) highlight_info.width;
11690 event.xexpose.height=(
int) highlight_info.height;
11691 XRefreshWindow(display,&windows->image,&event);
11693 if (event.xexpose.window == windows->info.id)
11694 if (event.xexpose.count == 0)
11695 XInfoWidget(display,windows,text);
11703 if (event.xkey.window != windows->image.id)
11708 (void) XLookupString((XKeyEvent *) &
event.xkey,command,(int)
11709 sizeof(command),&key_symbol,(XComposeStatus *) NULL);
11710 switch ((
int) key_symbol)
11718 state|=EscapeState;
11719 magick_fallthrough;
11729 roi_info.x=(ssize_t) (windows->image.width/2L-roi_info.width/2L);
11730 roi_info.y=(ssize_t) (windows->image.height/2L-
11731 roi_info.height/2L);
11763 (void) XSetFunction(display,windows->image.highlight_context,
11765 XTextViewHelp(display,resource_info,windows,MagickFalse,
11766 "Help Viewer - Region of Interest",ImageROIHelp);
11767 (void) XSetFunction(display,windows->image.highlight_context,
11773 display_command=XImageWindowCommand(display,resource_info,windows,
11774 event.xkey.state,key_symbol,image);
11775 if (display_command != NullCommand)
11776 state|=UpdateRegionState;
11780 (void) XSetSelectionOwner(display,XA_PRIMARY,windows->image.id,
11788 if (event.xbutton.window != windows->image.id)
11795 if (windows->info.mapped != MagickFalse)
11797 if ((x < (
int) (windows->info.x+windows->info.width)) &&
11798 (y < (int) (windows->info.y+windows->info.height)))
11799 (void) XWithdrawWindow(display,windows->info.id,
11800 windows->info.screen);
11803 if ((x > (
int) (windows->info.x+windows->info.width)) ||
11804 (y > (int) (windows->info.y+windows->info.height)))
11805 (void) XMapWindow(display,windows->info.id);
11806 roi_info.x=(ssize_t) windows->image.x+event.xmotion.x;
11807 roi_info.y=(ssize_t) windows->image.y+
event.xmotion.y;
11810 case SelectionRequest:
11815 XSelectionRequestEvent
11821 (void) FormatLocaleString(text,MaxTextExtent,
11822 "%.20gx%.20g%+.20g%+.20g",(
double) roi_info.width,(double)
11823 roi_info.height,(
double) roi_info.x,(double) roi_info.y);
11824 request=(&(
event.xselectionrequest));
11825 (void) XChangeProperty(request->display,request->requestor,
11826 request->property,request->target,8,PropModeReplace,
11827 (
unsigned char *) text,(int) strlen(text));
11828 notify.type=SelectionNotify;
11829 notify.display=request->display;
11830 notify.requestor=request->requestor;
11831 notify.selection=request->selection;
11832 notify.target=request->target;
11833 notify.time=request->time;
11834 if (request->property == None)
11835 notify.property=request->target;
11837 notify.property=request->property;
11838 (void) XSendEvent(request->display,request->requestor,False,0,
11839 (XEvent *) ¬ify);
11844 if ((state & UpdateConfigurationState) != 0)
11846 (void) XPutBackEvent(display,&event);
11847 (void) XCheckDefineCursor(display,windows->image.id,cursor);
11850 }
while ((state & ExitState) == 0);
11851 }
while ((state & ExitState) == 0);
11852 (void) XSetFunction(display,windows->image.highlight_context,GXcopy);
11853 XSetCursorState(display,windows,MagickFalse);
11854 if ((state & EscapeState) != 0)
11855 return(MagickTrue);
11856 return(MagickTrue);
11893static MagickBooleanType XRotateImage(Display *display,
11894 XResourceInfo *resource_info,XWindows *windows,
double degrees,
Image **image)
11897 *
const RotateMenu[] =
11907 direction = HorizontalRotateCommand;
11909 static const ModeType
11910 DirectionCommands[] =
11912 HorizontalRotateCommand,
11913 VerticalRotateCommand
11917 RotateColorCommand,
11918 RotateDirectionCommand,
11920 RotateDismissCommand
11923 static unsigned int
11927 command[MaxTextExtent],
11928 text[MaxTextExtent];
11939 normalized_degrees;
11949 if (degrees == 0.0)
11966 (void) CloneString(&windows->command.name,
"Rotate");
11967 windows->command.data=2;
11968 (void) XCommandWidget(display,windows,RotateMenu,(XEvent *) NULL);
11969 (void) XMapRaised(display,windows->command.id);
11970 XClientMessage(display,windows->image.id,windows->im_protocols,
11971 windows->im_update_widget,CurrentTime);
11975 (void) XSetFunction(display,windows->image.highlight_context,GXinvert);
11976 XQueryPosition(display,windows->image.id,&x,&y);
11981 state=DefaultState;
11984 XHighlightLine(display,windows->image.id,
11985 windows->image.highlight_context,&rotate_info);
11989 XScreenEvent(display,windows,&event);
11990 XHighlightLine(display,windows->image.id,
11991 windows->image.highlight_context,&rotate_info);
11992 if (event.xany.window == windows->command.id)
11997 id=XCommandWidget(display,windows,RotateMenu,&event);
12000 (void) XSetFunction(display,windows->image.highlight_context,
12002 switch (RotateCommands[
id])
12004 case RotateColorCommand:
12007 *ColorMenu[MaxNumberPens];
12018 for (i=0; i < (int) (MaxNumberPens-2); i++)
12019 ColorMenu[i]=resource_info->pen_colors[i];
12020 ColorMenu[MaxNumberPens-2]=
"Browser...";
12021 ColorMenu[MaxNumberPens-1]=(
const char *) NULL;
12025 pen_number=XMenuWidget(display,windows,RotateMenu[
id],
12026 (
const char **) ColorMenu,command);
12027 if (pen_number < 0)
12029 if (pen_number == (MaxNumberPens-2))
12032 color_name[MaxTextExtent] =
"gray";
12037 resource_info->pen_colors[pen_number]=color_name;
12038 XColorBrowserWidget(display,windows,
"Select",color_name);
12039 if (*color_name ==
'\0')
12045 (void) XParseColor(display,windows->map_info->colormap,
12046 resource_info->pen_colors[pen_number],&color);
12047 XBestPixel(display,windows->map_info->colormap,(XColor *) NULL,
12048 (
unsigned int) MaxColors,&color);
12049 windows->pixel_info->pen_colors[pen_number]=color;
12050 pen_id=(
unsigned int) pen_number;
12053 case RotateDirectionCommand:
12056 *
const Directions[] =
12066 id=XMenuWidget(display,windows,RotateMenu[
id],
12067 Directions,command);
12069 direction=DirectionCommands[id];
12072 case RotateHelpCommand:
12074 XTextViewHelp(display,resource_info,windows,MagickFalse,
12075 "Help Viewer - Image Rotation",ImageRotateHelp);
12078 case RotateDismissCommand:
12083 state|=EscapeState;
12090 (void) XSetFunction(display,windows->image.highlight_context,
12094 switch (event.type)
12098 if (event.xbutton.button != Button1)
12100 if (event.xbutton.window != windows->image.id)
12105 (void) XSetFunction(display,windows->image.highlight_context,
12107 rotate_info.x1=
event.xbutton.x;
12108 rotate_info.y1=
event.xbutton.y;
12112 case ButtonRelease:
12119 command[MaxTextExtent];
12124 if (event.xkey.window != windows->image.id)
12129 (void) XLookupString((XKeyEvent *) &
event.xkey,command,(int)
12130 sizeof(command),&key_symbol,(XComposeStatus *) NULL);
12131 switch ((
int) key_symbol)
12139 state|=EscapeState;
12146 (void) XSetFunction(display,windows->image.highlight_context,
12148 XTextViewHelp(display,resource_info,windows,MagickFalse,
12149 "Help Viewer - Image Rotation",ImageRotateHelp);
12150 (void) XSetFunction(display,windows->image.highlight_context,
12156 (void) XBell(display,0);
12164 rotate_info.x1=
event.xmotion.x;
12165 rotate_info.y1=
event.xmotion.y;
12168 rotate_info.x2=rotate_info.x1;
12169 rotate_info.y2=rotate_info.y1;
12170 if (direction == HorizontalRotateCommand)
12171 rotate_info.x2+=32;
12173 rotate_info.y2-=32;
12174 }
while ((state & ExitState) == 0);
12175 (void) XSetFunction(display,windows->image.highlight_context,GXcopy);
12176 (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
12177 if ((state & EscapeState) != 0)
12178 return(MagickTrue);
12183 (void) XSetFunction(display,windows->image.highlight_context,GXinvert);
12184 state=DefaultState;
12192 if (windows->info.mapped == MagickFalse)
12193 (void) XMapWindow(display,windows->info.id);
12194 (void) FormatLocaleString(text,MaxTextExtent,
" %g",
12195 direction == VerticalRotateCommand ? degrees-90.0 : degrees);
12196 XInfoWidget(display,windows,text);
12197 XHighlightLine(display,windows->image.id,
12198 windows->image.highlight_context,&rotate_info);
12201 if (windows->info.mapped != MagickFalse)
12202 (void) XWithdrawWindow(display,windows->info.id,
12203 windows->info.screen);
12207 XScreenEvent(display,windows,&event);
12209 XHighlightLine(display,windows->image.id,
12210 windows->image.highlight_context,&rotate_info);
12211 switch (event.type)
12215 case ButtonRelease:
12220 rotate_info.x2=
event.xbutton.x;
12221 rotate_info.y2=
event.xbutton.y;
12229 rotate_info.x2=
event.xmotion.x;
12230 rotate_info.y2=
event.xmotion.y;
12238 if (rotate_info.x2 < 0)
12241 if (rotate_info.x2 > (
int) windows->image.width)
12242 rotate_info.x2=(short) windows->image.width;
12243 if (rotate_info.y2 < 0)
12246 if (rotate_info.y2 > (
int) windows->image.height)
12247 rotate_info.y2=(
short) windows->image.height;
12252 distance=(
unsigned int)
12253 ((rotate_info.x2-rotate_info.x1+1)*(rotate_info.x2-rotate_info.x1+1))+
12254 ((rotate_info.y2-rotate_info.y1+1)*(rotate_info.y2-rotate_info.y1+1));
12256 degrees=RadiansToDegrees(-atan2((
double) (rotate_info.y2-
12257 rotate_info.y1),(
double) (rotate_info.x2-rotate_info.x1)));
12258 }
while ((state & ExitState) == 0);
12259 (void) XSetFunction(display,windows->image.highlight_context,GXcopy);
12260 (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
12262 return(MagickTrue);
12264 if (direction == VerticalRotateCommand)
12266 if (degrees == 0.0)
12267 return(MagickTrue);
12271 normalized_degrees=degrees;
12272 while (normalized_degrees < -45.0)
12273 normalized_degrees+=360.0;
12274 for (rotations=0; normalized_degrees > 45.0; rotations++)
12275 normalized_degrees-=90.0;
12276 if (normalized_degrees != 0.0)
12277 (void) XMagickCommand(display,resource_info,windows,ApplyCommand,image);
12278 XSetCursorState(display,windows,MagickTrue);
12279 XCheckRefreshWindows(display,windows);
12280 (*image)->background_color.red=ScaleShortToQuantum(
12281 windows->pixel_info->pen_colors[pen_id].red);
12282 (*image)->background_color.green=ScaleShortToQuantum(
12283 windows->pixel_info->pen_colors[pen_id].green);
12284 (*image)->background_color.blue=ScaleShortToQuantum(
12285 windows->pixel_info->pen_colors[pen_id].blue);
12286 rotate_image=RotateImage(*image,degrees,&(*image)->exception);
12287 XSetCursorState(display,windows,MagickFalse);
12288 if (rotate_image == (
Image *) NULL)
12289 return(MagickFalse);
12290 *image=DestroyImage(*image);
12291 *image=rotate_image;
12292 if (windows->image.crop_geometry != (
char *) NULL)
12297 width=(
unsigned int) (*image)->columns;
12298 height=(
unsigned int) (*image)->rows;
12299 (void) XParseGeometry(windows->image.crop_geometry,&x,&y,&width,&height);
12300 switch (rotations % 4)
12310 (void) FormatLocaleString(windows->image.crop_geometry,MaxTextExtent,
12311 "%ux%u%+d%+d",height,width,(
int) (*image)->columns-
12320 (void) FormatLocaleString(windows->image.crop_geometry,MaxTextExtent,
12321 "%ux%u%+d%+d",width,height,(
int) width-x,(int) height-y);
12329 (void) FormatLocaleString(windows->image.crop_geometry,MaxTextExtent,
12330 "%ux%u%+d%+d",height,width,y,(
int) (*image)->rows-(int) width-x);
12335 if (windows->image.orphan != MagickFalse)
12336 return(MagickTrue);
12337 if (normalized_degrees != 0.0)
12342 windows->image.window_changes.width=(int) (*image)->columns;
12343 windows->image.window_changes.height=(
int) (*image)->rows;
12344 if (windows->image.crop_geometry != (
char *) NULL)
12349 (void) XParseGeometry(windows->image.crop_geometry,&x,&y,
12351 windows->image.window_changes.width=(int) width;
12352 windows->image.window_changes.height=(int) height;
12354 XConfigureImageColormap(display,resource_info,windows,*image);
12357 if (((rotations % 4) == 1) || ((rotations % 4) == 3))
12359 windows->image.window_changes.width=windows->image.ximage->height;
12360 windows->image.window_changes.height=windows->image.ximage->width;
12365 (void) XConfigureImage(display,resource_info,windows,*image);
12366 return(MagickTrue);
12399static MagickBooleanType XSaveImage(Display *display,
12400 XResourceInfo *resource_info,XWindows *windows,
Image *image)
12403 filename[MaxTextExtent],
12404 geometry[MaxTextExtent];
12418 if (resource_info->write_filename != (
char *) NULL)
12419 (void) CopyMagickString(filename,resource_info->write_filename,
12424 path[MaxTextExtent];
12429 GetPathComponent(image->filename,HeadPath,path);
12430 GetPathComponent(image->filename,TailPath,filename);
12433 status=chdir(path);
12435 (void) ThrowMagickException(&image->exception,GetMagickModule(),
12436 FileOpenError,
"UnableToOpenFile",
"%s",path);
12439 XFileBrowserWidget(display,windows,
"Save",filename);
12440 if (*filename ==
'\0')
12441 return(MagickTrue);
12442 if (IsPathAccessible(filename) != MagickFalse)
12450 status=XConfirmWidget(display,windows,
"Overwrite",filename);
12452 return(MagickTrue);
12454 image_info=CloneImageInfo(resource_info->image_info);
12455 (void) CopyMagickString(image_info->filename,filename,MaxTextExtent);
12456 (void) SetImageInfo(image_info,1,&image->exception);
12457 if ((LocaleCompare(image_info->magick,
"JPEG") == 0) ||
12458 (LocaleCompare(image_info->magick,
"JPG") == 0))
12461 quality[MaxTextExtent];
12469 (void) FormatLocaleString(quality,MaxTextExtent,
"%.20g",(
double)
12471 status=XDialogWidget(display,windows,
"Save",
"Enter JPEG quality:",
12473 if (*quality ==
'\0')
12474 return(MagickTrue);
12475 image->quality=StringToUnsignedLong(quality);
12476 image_info->interlace=status != 0 ? NoInterlace : PlaneInterlace;
12478 if ((LocaleCompare(image_info->magick,
"EPS") == 0) ||
12479 (LocaleCompare(image_info->magick,
"PDF") == 0) ||
12480 (LocaleCompare(image_info->magick,
"PS") == 0) ||
12481 (LocaleCompare(image_info->magick,
"PS2") == 0))
12484 geometry[MaxTextExtent];
12487 *
const PageSizes[] =
12509 (void) CopyMagickString(geometry,PSPageGeometry,MaxTextExtent);
12510 if (LocaleCompare(image_info->magick,
"PDF") == 0)
12511 (
void) CopyMagickString(geometry,PSPageGeometry,MaxTextExtent);
12512 if (image_info->page != (
char *) NULL)
12513 (void) CopyMagickString(geometry,image_info->page,MaxTextExtent);
12514 XListBrowserWidget(display,windows,&windows->widget,PageSizes,
"Select",
12515 "Select page geometry:",geometry);
12516 if (*geometry !=
'\0')
12517 image_info->page=GetPageGeometry(geometry);
12522 XSetCursorState(display,windows,MagickTrue);
12523 XCheckRefreshWindows(display,windows);
12524 save_image=CloneImage(image,0,0,MagickTrue,&image->exception);
12525 if (save_image == (
Image *) NULL)
12526 return(MagickFalse);
12527 (void) FormatLocaleString(geometry,MaxTextExtent,
"%dx%d!",
12528 windows->image.ximage->width,windows->image.ximage->height);
12529 (void) TransformImage(&save_image,windows->image.crop_geometry,geometry);
12533 (void) CopyMagickString(save_image->filename,filename,MaxTextExtent);
12534 status=WriteImage(image_info,save_image);
12535 if (status != MagickFalse)
12536 image->taint=MagickFalse;
12537 save_image=DestroyImage(save_image);
12538 image_info=DestroyImageInfo(image_info);
12539 XSetCursorState(display,windows,MagickFalse);
12540 return(status != 0 ? MagickTrue : MagickFalse);
12573#if defined(__cplusplus) || defined(c_plusplus)
12577static int XPredicate(Display *magick_unused(display),XEvent *event,
char *data)
12582 magick_unreferenced(display);
12584 windows=(XWindows *) data;
12585 if ((event->type == ClientMessage) &&
12586 (
event->xclient.window == windows->image.id))
12587 return(MagickFalse);
12588 return(MagickTrue);
12591#if defined(__cplusplus) || defined(c_plusplus)
12595static void XScreenEvent(Display *display,XWindows *windows,XEvent *event)
12601 (void) XIfEvent(display,event,XPredicate,(
char *) windows);
12602 if (event->xany.window == windows->command.id)
12604 switch (event->type)
12607 case ButtonRelease:
12609 if ((event->xbutton.button == Button3) &&
12610 (
event->xbutton.state & Mod1Mask))
12615 event->xbutton.button=Button2;
12616 event->xbutton.state&=(~Mod1Mask);
12618 if (event->xbutton.window == windows->backdrop.id)
12620 (void) XSetInputFocus(display,event->xbutton.window,RevertToParent,
12621 event->xbutton.time);
12624 if (event->xbutton.window == windows->pan.id)
12626 XPanImage(display,windows,event);
12629 if (event->xbutton.window == windows->image.id)
12630 if (event->xbutton.button == Button2)
12635 x=
event->xbutton.x;
12636 y=
event->xbutton.y;
12640 if (x >= (
int) windows->image.width)
12641 x=(int) (windows->image.width-1);
12642 windows->magnify.x=(int) windows->image.x+x;
12646 if (y >= (
int) windows->image.height)
12647 y=(
int) (windows->image.height-1);
12648 windows->magnify.y=windows->image.y+y;
12649 if (windows->magnify.mapped == MagickFalse)
12650 (void) XMapRaised(display,windows->magnify.id);
12651 XMakeMagnifyImage(display,windows);
12652 if (event->type == ButtonRelease)
12653 (void) XWithdrawWindow(display,windows->info.id,
12654 windows->info.screen);
12659 case ClientMessage:
12664 if (event->xclient.message_type != windows->wm_protocols)
12666 if (*event->xclient.data.l != (
long) windows->wm_delete_window)
12668 if (event->xclient.window == windows->magnify.id)
12670 (void) XWithdrawWindow(display,windows->magnify.id,
12671 windows->magnify.screen);
12676 case ConfigureNotify:
12678 if (event->xconfigure.window == windows->magnify.id)
12686 windows->magnify.width=(
unsigned int) event->xconfigure.width;
12687 windows->magnify.height=(
unsigned int)
event->xconfigure.height;
12688 if (windows->magnify.mapped == MagickFalse)
12691 while ((
int) magnify <=
event->xconfigure.width)
12693 while ((
int) magnify <=
event->xconfigure.height)
12696 if (((
int) magnify !=
event->xconfigure.width) ||
12697 ((
int) magnify !=
event->xconfigure.height))
12702 window_changes.width=(int) magnify;
12703 window_changes.height=(int) magnify;
12704 (void) XReconfigureWMWindow(display,windows->magnify.id,
12705 windows->magnify.screen,(
unsigned int) (CWWidth | CWHeight),
12709 XMakeMagnifyImage(display,windows);
12716 if (event->xexpose.window == windows->image.id)
12718 XRefreshWindow(display,&windows->image,event);
12721 if (event->xexpose.window == windows->pan.id)
12722 if (event->xexpose.count == 0)
12724 XDrawPanRectangle(display,windows);
12727 if (event->xexpose.window == windows->magnify.id)
12728 if (event->xexpose.count == 0)
12730 XMakeMagnifyImage(display,windows);
12738 command[MaxTextExtent];
12743 if (event->xkey.window != windows->magnify.id)
12748 (void) XLookupString((XKeyEvent *) &
event->xkey,command,(int)
12749 sizeof(command),&key_symbol,(XComposeStatus *) NULL);
12750 XMagnifyWindowCommand(display,windows,event->xkey.state,key_symbol);
12755 if (event->xmap.window == windows->magnify.id)
12757 windows->magnify.mapped=MagickTrue;
12758 (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
12761 if (event->xmap.window == windows->info.id)
12763 windows->info.mapped=MagickTrue;
12770 while (XCheckMaskEvent(display,ButtonMotionMask,event)) ;
12771 if (event->xmotion.window == windows->image.id)
12772 if (windows->magnify.mapped != MagickFalse)
12777 x=
event->xmotion.x;
12778 y=
event->xmotion.y;
12782 if (x >= (
int) windows->image.width)
12783 x=(
int) (windows->image.width-1);
12784 windows->magnify.x=(int) windows->image.x+x;
12788 if (y >= (
int) windows->image.height)
12789 y=(
int) (windows->image.height-1);
12790 windows->magnify.y=windows->image.y+y;
12791 XMakeMagnifyImage(display,windows);
12797 if (event->xunmap.window == windows->magnify.id)
12799 windows->magnify.mapped=MagickFalse;
12802 if (event->xunmap.window == windows->info.id)
12804 windows->info.mapped=MagickFalse;
12846static void XSetCropGeometry(Display *display,XWindows *windows,
12850 text[MaxTextExtent];
12863 if (windows->info.mapped != MagickFalse)
12868 (void) FormatLocaleString(text,MaxTextExtent,
" %.20gx%.20g%+.20g%+.20g",
12869 (
double) crop_info->width,(double) crop_info->height,(
double)
12870 crop_info->x,(double) crop_info->y);
12871 XInfoWidget(display,windows,text);
12878 width=(
unsigned int) image->columns;
12879 height=(
unsigned int) image->rows;
12880 if (windows->image.crop_geometry != (
char *) NULL)
12881 (
void) XParseGeometry(windows->image.crop_geometry,&x,&y,&width,&height);
12883 windows->image.crop_geometry=AcquireString((
char *) NULL);
12887 scale_factor=(MagickRealType) width/windows->image.ximage->width;
12888 if (crop_info->x > 0)
12889 x+=(int) (scale_factor*crop_info->x+0.5);
12890 width=(
unsigned int) (scale_factor*crop_info->width+0.5);
12893 scale_factor=(MagickRealType) height/windows->image.ximage->height;
12894 if (crop_info->y > 0)
12895 y+=(int) (scale_factor*crop_info->y+0.5);
12896 height=(
unsigned int) (scale_factor*crop_info->height+0.5);
12899 (void) FormatLocaleString(windows->image.crop_geometry,MaxTextExtent,
12900 "%ux%u%+d%+d",width,height,x,y);
12940static Image *XTileImage(Display *display,XResourceInfo *resource_info,
12941 XWindows *windows,
Image *image,XEvent *event)
12944 *
const VerbMenu[] =
12954 static const ModeType
12965 command[MaxTextExtent],
12966 filename[MaxTextExtent];
12997 width=(
unsigned int) image->columns;
12998 height=(
unsigned int) image->rows;
12999 if (windows->image.crop_geometry != (
char *) NULL)
13000 (
void) XParseGeometry(windows->image.crop_geometry,&x,&y,&width,&height);
13001 scale_factor=(MagickRealType) width/windows->image.ximage->width;
13002 event->xbutton.x+=windows->image.x;
13003 event->xbutton.x=(
int) (scale_factor*
event->xbutton.x+x+0.5);
13004 scale_factor=(MagickRealType) height/windows->image.ximage->height;
13005 event->xbutton.y+=windows->image.y;
13006 event->xbutton.y=(
int) (scale_factor*
event->xbutton.y+y+0.5);
13010 width=(
unsigned int) image->columns;
13011 height=(
unsigned int) image->rows;
13014 (void) XParseGeometry(image->montage,&x,&y,&width,&height);
13015 tile=((
event->xbutton.y-y)/height)*(((int) image->columns-x)/width)+
13016 (event->xbutton.x-x)/width;
13022 (void) XBell(display,0);
13023 return((
Image *) NULL);
13028 p=image->directory;
13029 for (i=tile; (i != 0) && (*p !=
'\0'); )
13040 (void) XBell(display,0);
13041 return((
Image *) NULL);
13046 id=XMenuWidget(display,windows,
"Tile Verb",VerbMenu,command);
13048 return((
Image *) NULL);
13050 while ((*q !=
'\xff') && (*q !=
'\0'))
13052 (void) CopyMagickString(filename,p,(
size_t) (q-p+1));
13056 XSetCursorState(display,windows,MagickTrue);
13057 XCheckRefreshWindows(display,windows);
13058 tile_image=NewImageList();
13059 switch (TileCommands[
id])
13061 case TileLoadCommand:
13066 XCheckRefreshWindows(display,windows);
13067 (void) CopyMagickString(resource_info->image_info->magick,
"MIFF",
13069 (void) CopyMagickString(resource_info->image_info->filename,filename,
13071 tile_image=ReadImage(resource_info->image_info,&image->exception);
13072 CatchException(&image->exception);
13073 (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
13076 case TileNextCommand:
13081 XClientMessage(display,windows->image.id,windows->im_protocols,
13082 windows->im_next_image,CurrentTime);
13085 case TileFormerCommand:
13090 XClientMessage(display,windows->image.id,windows->im_protocols,
13091 windows->im_former_image,CurrentTime);
13094 case TileDeleteCommand:
13099 if (IsPathAccessible(filename) == MagickFalse)
13101 XNoticeWidget(display,windows,
"Image file does not exist:",filename);
13104 status=XConfirmWidget(display,windows,
"Really delete tile",filename);
13107 status=ShredFile(filename);
13108 status|=remove_utf8(filename);
13109 if (status != MagickFalse)
13111 XNoticeWidget(display,windows,
"Unable to delete image file:",
13115 magick_fallthrough;
13117 case TileUpdateCommand:
13139 for (p=image->directory; *p !=
'\0'; p++)
13145 while ((*q !=
'\xff') && (*q !=
'\0'))
13147 (void) CopyMagickString(filename,p,(
size_t) (q-p+1));
13149 if (IsPathAccessible(filename) != MagickFalse)
13157 x_offset=(int) (width*(tile % (((
int) image->columns-x)/width))+x);
13158 y_offset=(int) (height*(tile/(((
int) image->columns-x)/width))+y);
13159 exception=(&image->exception);
13160 image_view=AcquireAuthenticCacheView(image,exception);
13161 (void) GetOneCacheViewVirtualPixel(image_view,0,0,&pixel,exception);
13162 for (i=0; i < (int) height; i++)
13164 s=GetCacheViewAuthenticPixels(image_view,(ssize_t) x_offset,(ssize_t)
13165 y_offset+i,width,1,exception);
13168 for (j=0; j < (int) width; j++)
13170 if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
13173 image_view=DestroyCacheView(image_view);
13176 windows->image.window_changes.width=(int) image->columns;
13177 windows->image.window_changes.height=(
int) image->rows;
13178 XConfigureImageColormap(display,resource_info,windows,image);
13179 (void) XConfigureImage(display,resource_info,windows,image);
13185 XSetCursorState(display,windows,MagickFalse);
13186 return(tile_image);
13222static void XTranslateImage(Display *display,XWindows *windows,
13223 Image *image,
const KeySym key_symbol)
13226 text[MaxTextExtent];
13239 x_offset=windows->image.width;
13240 y_offset=windows->image.height;
13241 if (image->montage != (
char *) NULL)
13242 (void) XParseGeometry(image->montage,&x,&y,&x_offset,&y_offset);
13243 switch ((
int) key_symbol)
13248 windows->image.x=(int) windows->image.width/2;
13249 windows->image.y=(
int) windows->image.height/2;
13255 windows->image.x-=x_offset;
13262 windows->image.y-=y_offset;
13268 windows->image.x+=x_offset;
13275 windows->image.y+=y_offset;
13284 if (windows->image.x < 0)
13285 windows->image.x=0;
13287 if ((
int) (windows->image.x+windows->image.width) >
13288 windows->image.ximage->width)
13289 windows->image.x=(int) windows->image.ximage->width-windows->image.width;
13290 if (windows->image.y < 0)
13291 windows->image.y=0;
13293 if ((
int) (windows->image.y+windows->image.height) >
13294 windows->image.ximage->height)
13295 windows->image.y=(int) windows->image.ximage->height-windows->image.height;
13299 (
void) FormatLocaleString(text,MaxTextExtent,
" %ux%u%+d%+d ",
13300 windows->image.width,windows->image.height,windows->image.x,
13302 XInfoWidget(display,windows,text);
13303 XCheckRefreshWindows(display,windows);
13304 XDrawPanRectangle(display,windows);
13305 XRefreshWindow(display,&windows->image,(XEvent *) NULL);
13306 (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
13339static MagickBooleanType XTrimImage(Display *display,
13340 XResourceInfo *resource_info,XWindows *windows,
Image *image)
13356 XSetCursorState(display,windows,MagickTrue);
13357 XCheckRefreshWindows(display,windows);
13361 background=XGetPixel(windows->image.ximage,0,0);
13362 trim_info.width=(size_t) windows->image.ximage->width;
13363 for (x=0; x < windows->image.ximage->width; x++)
13365 for (y=0; y < windows->image.ximage->height; y++)
13367 pixel=XGetPixel(windows->image.ximage,x,y);
13368 if (pixel != background)
13371 if (y < windows->image.ximage->height)
13374 trim_info.x=(ssize_t) x;
13375 if (trim_info.x == (ssize_t) windows->image.ximage->width)
13377 XSetCursorState(display,windows,MagickFalse);
13378 return(MagickFalse);
13383 background=XGetPixel(windows->image.ximage,windows->image.ximage->width-1,0);
13384 for (x=windows->image.ximage->width-1; x != 0; x--)
13386 for (y=0; y < windows->image.ximage->height; y++)
13388 pixel=XGetPixel(windows->image.ximage,x,y);
13389 if (pixel != background)
13392 if (y < windows->image.ximage->height)
13395 trim_info.width=(size_t) (x-trim_info.x+1);
13399 background=XGetPixel(windows->image.ximage,0,0);
13400 trim_info.height=(size_t) windows->image.ximage->height;
13401 for (y=0; y < windows->image.ximage->height; y++)
13403 for (x=0; x < windows->image.ximage->width; x++)
13405 pixel=XGetPixel(windows->image.ximage,x,y);
13406 if (pixel != background)
13409 if (x < windows->image.ximage->width)
13412 trim_info.y=(ssize_t) y;
13416 background=XGetPixel(windows->image.ximage,0,windows->image.ximage->height-1);
13417 for (y=windows->image.ximage->height-1; y != 0; y--)
13419 for (x=0; x < windows->image.ximage->width; x++)
13421 pixel=XGetPixel(windows->image.ximage,x,y);
13422 if (pixel != background)
13425 if (x < windows->image.ximage->width)
13428 trim_info.height=(size_t) y-trim_info.y+1;
13429 if (((
unsigned int) trim_info.width != windows->image.width) ||
13430 ((
unsigned int) trim_info.height != windows->image.height))
13435 XSetCropGeometry(display,windows,&trim_info,image);
13436 windows->image.window_changes.width=(int) trim_info.width;
13437 windows->image.window_changes.height=(
int) trim_info.height;
13438 (void) XConfigureImage(display,resource_info,windows,image);
13440 XSetCursorState(display,windows,MagickFalse);
13441 return(MagickTrue);
13476static Image *XVisualDirectoryImage(Display *display,
13477 XResourceInfo *resource_info,XWindows *windows)
13479#define TileImageTag "Scale/Image"
13480#define XClientName "montage"
13516 filename[MaxTextExtent] =
"\0",
13517 filenames[MaxTextExtent] =
"*";
13520 background_resources;
13525 XFileBrowserWidget(display,windows,
"Directory",filenames);
13526 if (*filenames ==
'\0')
13527 return((
Image *) NULL);
13531 filelist=(
char **) AcquireMagickMemory(
sizeof(*filelist));
13532 if (filelist == (
char **) NULL)
13534 ThrowXWindowException(ResourceLimitError,
"MemoryAllocationFailed",
13536 return((
Image *) NULL);
13539 filelist[0]=filenames;
13540 status=ExpandFilenames(&number_files,&filelist);
13541 if ((status == MagickFalse) || (number_files == 0))
13543 if (number_files == 0)
13544 ThrowXWindowException(ImageError,
"NoImagesWereFound",filenames)
13546 ThrowXWindowException(ResourceLimitError,
"MemoryAllocationFailed",
13548 return((
Image *) NULL);
13553 background_resources=(*resource_info);
13554 background_resources.window_id=AcquireString(
"");
13555 (void) FormatLocaleString(background_resources.window_id,MaxTextExtent,
13556 "0x%lx",windows->image.id);
13557 background_resources.backdrop=MagickTrue;
13561 backdrop=(windows->visual_info->klass == TrueColor) ||
13562 (windows->visual_info->klass == DirectColor) ? MagickTrue : MagickFalse;
13563 read_info=CloneImageInfo(resource_info->image_info);
13564 (void) SetImageOption(read_info,
"jpeg:size",
"120x120");
13565 (void) CloneString(&read_info->size,DefaultTileGeometry);
13566 (void) SetImageInfoProgressMonitor(read_info,(MagickProgressMonitor) NULL,
13568 images=NewImageList();
13569 exception=AcquireExceptionInfo();
13570 XSetCursorState(display,windows,MagickTrue);
13571 XCheckRefreshWindows(display,windows);
13572 for (i=0; i < (int) number_files; i++)
13574 (void) CopyMagickString(read_info->filename,filelist[i],MaxTextExtent);
13575 filelist[i]=DestroyString(filelist[i]);
13576 *read_info->magick=
'\0';
13577 next_image=ReadImage(read_info,exception);
13578 CatchException(exception);
13579 if (next_image != (
Image *) NULL)
13581 (void) DeleteImageProperty(next_image,
"label");
13582 (void) SetImageProperty(next_image,
"label",InterpretImageProperties(
13583 read_info,next_image,DefaultTileLabel));
13584 (void) ParseRegionGeometry(next_image,read_info->size,&geometry,
13586 thumbnail_image=ThumbnailImage(next_image,geometry.width,
13587 geometry.height,exception);
13588 if (thumbnail_image != (
Image *) NULL)
13590 next_image=DestroyImage(next_image);
13591 next_image=thumbnail_image;
13595 (void) XDisplayBackgroundImage(display,&background_resources,
13597 XSetCursorState(display,windows,MagickTrue);
13599 AppendImageToList(&images,next_image);
13600 if (images->progress_monitor != (MagickProgressMonitor) NULL)
13605 proceed=SetImageProgress(images,LoadImageTag,(MagickOffsetType) i,
13606 (MagickSizeType) number_files);
13607 if (proceed == MagickFalse)
13612 exception=DestroyExceptionInfo(exception);
13613 filelist=(
char **) RelinquishMagickMemory(filelist);
13614 if (images == (
Image *) NULL)
13616 read_info=DestroyImageInfo(read_info);
13617 XSetCursorState(display,windows,MagickFalse);
13618 ThrowXWindowException(ImageError,
"NoImagesWereLoaded",filenames);
13619 return((
Image *) NULL);
13624 montage_info=CloneMontageInfo(read_info,(
MontageInfo *) NULL);
13625 montage_info->pointsize=10;
13626 if (resource_info->font != (
char *) NULL)
13627 (void) CloneString(&montage_info->font,resource_info->font);
13628 (void) CopyMagickString(montage_info->filename,filename,MaxTextExtent);
13629 montage_image=MontageImageList(read_info,montage_info,GetFirstImageInList(
13630 images),&images->exception);
13631 images=DestroyImageList(images);
13632 montage_info=DestroyMontageInfo(montage_info);
13633 read_info=DestroyImageInfo(read_info);
13634 XSetCursorState(display,windows,MagickFalse);
13635 if (montage_image == (
Image *) NULL)
13636 return(montage_image);
13637 XClientMessage(display,windows->image.id,windows->im_protocols,
13638 windows->im_next_image,CurrentTime);
13639 return(montage_image);
13670MagickExport MagickBooleanType XDisplayBackgroundImage(Display *display,
13671 XResourceInfo *resource_info,
Image *image)
13674 geometry[MaxTextExtent],
13675 visual_type[MaxTextExtent];
13688 static XStandardColormap
13692 *visual_info = (XVisualInfo *) NULL;
13715 assert(image != (
Image *) NULL);
13716 assert(image->signature == MagickCoreSignature);
13717 if (IsEventLogging() != MagickFalse)
13718 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
13719 resources=(*resource_info);
13720 window_info.id=(Window) NULL;
13721 root_window=XRootWindow(display,XDefaultScreen(display));
13722 if (LocaleCompare(resources.window_id,
"root") == 0)
13723 window_info.id=root_window;
13726 if (isdigit((
int) ((
unsigned char) *resources.window_id)) != 0)
13727 window_info.id=XWindowByID(display,root_window,
13728 (Window) strtol((
char *) resources.window_id,(
char **) NULL,0));
13729 if (window_info.id == (Window) NULL)
13730 window_info.id=XWindowByName(display,root_window,resources.window_id);
13732 if (window_info.id == (Window) NULL)
13734 ThrowXWindowException(XServerError,
"NoWindowWithSpecifiedIDExists",
13735 resources.window_id);
13740 window_attributes.width=XDisplayWidth(display,XDefaultScreen(display));
13741 window_attributes.height=XDisplayHeight(display,XDefaultScreen(display));
13742 (void) CopyMagickString(visual_type,
"default",MaxTextExtent);
13743 status=XGetWindowAttributes(display,window_info.id,&window_attributes);
13745 (void) FormatLocaleString(visual_type,MaxTextExtent,
"0x%lx",
13746 XVisualIDFromVisual(window_attributes.visual));
13747 if (visual_info == (XVisualInfo *) NULL)
13752 map_info=XAllocStandardColormap();
13753 if (map_info == (XStandardColormap *) NULL)
13754 ThrowXWindowFatalException(XServerFatalError,
"MemoryAllocationFailed",
13756 map_info->colormap=(Colormap) NULL;
13757 pixel.pixels=(
unsigned long *) NULL;
13761 resources.map_type=(
char *) NULL;
13762 resources.visual_type=visual_type;
13763 visual_info=XBestVisualInfo(display,map_info,&resources);
13764 if (visual_info == (XVisualInfo *) NULL)
13765 ThrowXWindowFatalException(XServerFatalError,
"UnableToGetVisual",
13766 resources.visual_type);
13770 window_info.ximage=(XImage *) NULL;
13771 window_info.matte_image=(XImage *) NULL;
13772 window_info.pixmap=(Pixmap) NULL;
13773 window_info.matte_pixmap=(Pixmap) NULL;
13778 if (window_info.id == root_window)
13779 (void) XDestroyWindowColors(display,root_window);
13783 resources.colormap=SharedColormap;
13784 XMakeStandardColormap(display,visual_info,&resources,image,map_info,&pixel);
13788 context_values.background=pixel.foreground_color.pixel;
13789 context_values.foreground=pixel.background_color.pixel;
13790 pixel.annotate_context=XCreateGC(display,window_info.id,
13791 (
size_t) (GCBackground | GCForeground),&context_values);
13792 if (pixel.annotate_context == (GC) NULL)
13793 ThrowXWindowFatalException(XServerFatalError,
"UnableToCreateGraphicContext",
13798 window_info.name=AcquireString(
"\0");
13799 window_info.icon_name=AcquireString(
"\0");
13800 XGetWindowInfo(display,visual_info,map_info,&pixel,(XFontStruct *) NULL,
13801 &resources,&window_info);
13805 window_info.width=(
unsigned int) image->columns;
13806 window_info.height=(
unsigned int) image->rows;
13807 if ((image->columns != window_info.width) ||
13808 (image->rows != window_info.height))
13809 ThrowXWindowFatalException(XServerFatalError,
"UnableToCreateXImage",
13811 (void) FormatLocaleString(geometry,MaxTextExtent,
"%ux%u+0+0>",
13812 window_attributes.width,window_attributes.height);
13813 geometry_info.width=window_info.width;
13814 geometry_info.height=window_info.height;
13815 geometry_info.x=(ssize_t) window_info.x;
13816 geometry_info.y=(ssize_t) window_info.y;
13817 (void) ParseMetaGeometry(geometry,&geometry_info.x,&geometry_info.y,
13818 &geometry_info.width,&geometry_info.height);
13819 window_info.width=(
unsigned int) geometry_info.width;
13820 window_info.height=(
unsigned int) geometry_info.height;
13821 window_info.x=(int) geometry_info.x;
13822 window_info.y=(
int) geometry_info.y;
13823 status=XMakeImage(display,&resources,&window_info,image,window_info.width,
13824 window_info.height);
13825 if (status == MagickFalse)
13826 ThrowXWindowFatalException(XServerFatalError,
"UnableToCreateXImage",
13830 if (resource_info->debug != MagickFalse)
13832 (void) LogMagickEvent(X11Event,GetMagickModule(),
13833 "Image: %s[%.20g] %.20gx%.20g ",image->filename,(double) image->scene,
13834 (
double) image->columns,(double) image->rows);
13835 if (image->colors != 0)
13836 (void) LogMagickEvent(X11Event,GetMagickModule(),
"%.20gc ",(double)
13838 (void) LogMagickEvent(X11Event,GetMagickModule(),
"%s",image->magick);
13843 width=(int) window_info.width;
13844 height=(
int) window_info.height;
13845 if (resources.backdrop != MagickFalse)
13850 window_info.x=(window_attributes.width/2)-(window_info.ximage->width/2);
13851 window_info.y=(window_attributes.height/2)-(window_info.ximage->height/2);
13852 width=window_attributes.width;
13853 height=window_attributes.height;
13855 if ((resources.image_geometry != (
char *) NULL) &&
13856 (*resources.image_geometry !=
'\0'))
13859 default_geometry[MaxTextExtent];
13871 size_hints=XAllocSizeHints();
13872 if (size_hints == (XSizeHints *) NULL)
13873 ThrowXWindowFatalException(ResourceLimitFatalError,
13874 "MemoryAllocationFailed",image->filename);
13875 size_hints->flags=0L;
13876 (void) FormatLocaleString(default_geometry,MaxTextExtent,
"%dx%d",
13878 flags=XWMGeometry(display,visual_info->screen,resources.image_geometry,
13879 default_geometry,window_info.border_width,size_hints,&window_info.x,
13880 &window_info.y,&width,&height,&gravity);
13881 if (flags & (XValue | YValue))
13883 width=window_attributes.width;
13884 height=window_attributes.height;
13886 (void) XFree((
void *) size_hints);
13891 window_info.pixmap=XCreatePixmap(display,window_info.id,(
unsigned int) width,
13892 (
unsigned int) height,window_info.depth);
13893 if (window_info.pixmap == (Pixmap) NULL)
13894 ThrowXWindowFatalException(XServerFatalError,
"UnableToCreateXPixmap",
13899 if (((
unsigned int) width > window_info.width) ||
13900 ((
unsigned int) height > window_info.height))
13901 (void) XFillRectangle(display,window_info.pixmap,
13902 window_info.annotate_context,0,0,(
unsigned int) width,
13903 (
unsigned int) height);
13904 (void) XPutImage(display,window_info.pixmap,window_info.annotate_context,
13905 window_info.ximage,0,0,window_info.x,window_info.y,(
unsigned int)
13906 window_info.width,(
unsigned int) window_info.height);
13907 (void) XSetWindowBackgroundPixmap(display,window_info.id,window_info.pixmap);
13908 (void) XClearWindow(display,window_info.id);
13909 delay=1000*image->delay/MagickMax(image->ticks_per_second,1L);
13910 XDelay(display,delay == 0UL ? 10UL : delay);
13911 (void) XSync(display,MagickFalse);
13912 return(window_info.id == root_window ? MagickTrue : MagickFalse);
13952MagickExport
Image *XDisplayImage(Display *display,XResourceInfo *resource_info,
13953 char **argv,
int argc,
Image **image,
size_t *state)
13955#define MagnifySize 256
13956#define MagickMenus 10
13957#define MagickTitle "Commands"
13960 *
const CommandMenu[] =
13974 *
const FileMenu[] =
13984 "Visual Directory...",
13988 *
const EditMenu[] =
13997 *
const ViewMenu[] =
14008 *
const TransformMenu[] =
14022 *
const EnhanceMenu[] =
14030 "Contrast Stretch...",
14031 "Sigmoidal Contrast...",
14040 *
const EffectsMenu[] =
14065 "Charcoal Draw...",
14068 *
const ImageEditMenu[] =
14079 "Region of Interest...",
14082 *
const MiscellanyMenu[] =
14094 *
const HelpMenu[] =
14097 "Browse Documentation",
14101 *
const ShortCutsMenu[] =
14114 *
const VirtualMenu[] =
14124 *
const *Menus[MagickMenus] =
14138 static DisplayCommand
14162 VisualDirectoryCommand,
14176 OriginalSizeCommand,
14183 TransformCommands[] =
14189 RotateRightCommand,
14196 EnhanceCommands[] =
14204 ContrastStretchCommand,
14205 SigmoidalContrastCommand,
14213 EffectsCommands[] =
14217 ReduceNoiseCommand,
14237 CharcoalDrawCommand
14239 ImageEditCommands[] =
14250 RegionOfInterestCommand
14252 MiscellanyCommands[] =
14256 ShowPreviewCommand,
14257 ShowHistogramCommand,
14266 BrowseDocumentationCommand,
14269 ShortCutsCommands[] =
14281 VirtualCommands[] =
14289 static DisplayCommand
14290 *Commands[MagickMenus] =
14300 MiscellanyCommands,
14305 command[MaxTextExtent],
14307 geometry[MaxTextExtent],
14308 resource_name[MaxTextExtent];
14335 working_directory[MaxTextExtent];
14341 *magick_windows[MaxXWindows];
14343 static unsigned int
14403 assert(image != (
Image **) NULL);
14404 assert((*image)->signature == MagickCoreSignature);
14405 if (IsEventLogging() != MagickFalse)
14406 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",(*image)->filename);
14407 display_image=(*image);
14408 warning_handler=(WarningHandler) NULL;
14409 windows=XSetWindows((XWindows *) ~0);
14410 if (windows != (XWindows *) NULL)
14415 if (*working_directory ==
'\0')
14416 (void) CopyMagickString(working_directory,
".",MaxTextExtent);
14417 status=chdir(working_directory);
14419 (void) ThrowMagickException(&(*image)->exception,GetMagickModule(),
14420 FileOpenError,
"UnableToOpenFile",
"%s",working_directory);
14421 warning_handler=resource_info->display_warnings ?
14422 SetErrorHandler(XWarning) : SetErrorHandler((ErrorHandler) NULL);
14423 warning_handler=resource_info->display_warnings ?
14424 SetWarningHandler(XWarning) : SetWarningHandler((WarningHandler) NULL);
14431 resource_info->colors=display_image->colors;
14432 windows=XSetWindows(XInitializeWindows(display,resource_info));
14433 if (windows == (XWindows *) NULL)
14434 ThrowXWindowFatalException(XServerFatalError,
"UnableToCreateWindow",
14435 (*image)->filename);
14440 magick_windows[number_windows++]=(&windows->icon);
14441 magick_windows[number_windows++]=(&windows->backdrop);
14442 magick_windows[number_windows++]=(&windows->image);
14443 magick_windows[number_windows++]=(&windows->info);
14444 magick_windows[number_windows++]=(&windows->command);
14445 magick_windows[number_windows++]=(&windows->widget);
14446 magick_windows[number_windows++]=(&windows->popup);
14447 magick_windows[number_windows++]=(&windows->magnify);
14448 magick_windows[number_windows++]=(&windows->pan);
14449 for (i=0; i < (int) number_windows; i++)
14450 magick_windows[i]->
id=(Window) NULL;
14457 if (windows->font_info != (XFontStruct *) NULL)
14458 (
void) XFreeFont(display,windows->font_info);
14459 windows->font_info=XBestFont(display,resource_info,MagickFalse);
14460 if (windows->font_info == (XFontStruct *) NULL)
14461 ThrowXWindowFatalException(XServerFatalError,
"UnableToLoadFont",
14462 resource_info->font);
14466 map_info=windows->map_info;
14467 icon_map=windows->icon_map;
14468 visual_info=windows->visual_info;
14469 icon_visual=windows->icon_visual;
14470 pixel=windows->pixel_info;
14471 icon_pixel=windows->icon_pixel;
14472 font_info=windows->font_info;
14473 icon_resources=windows->icon_resources;
14474 class_hints=windows->class_hints;
14475 manager_hints=windows->manager_hints;
14476 root_window=XRootWindow(display,visual_info->screen);
14477 nexus=NewImageList();
14478 if (resource_info->debug != MagickFalse)
14480 (void) LogMagickEvent(X11Event,GetMagickModule(),
14481 "Image: %s[%.20g] %.20gx%.20g ",display_image->filename,
14482 (double) display_image->scene,(
double) display_image->columns,
14483 (double) display_image->rows);
14484 if (display_image->colors != 0)
14485 (void) LogMagickEvent(X11Event,GetMagickModule(),
"%.20gc ",(double)
14486 display_image->colors);
14487 (void) LogMagickEvent(X11Event,GetMagickModule(),
"%s",
14488 display_image->magick);
14490 XMakeStandardColormap(display,visual_info,resource_info,display_image,
14492 display_image->taint=MagickFalse;
14496 windows->context.id=(Window) NULL;
14497 XGetWindowInfo(display,visual_info,map_info,pixel,font_info,
14498 resource_info,&windows->context);
14499 (void) CloneString(&class_hints->res_name,resource_info->client_name);
14500 (void) CloneString(&class_hints->res_class,resource_info->client_name);
14501 class_hints->res_class[0]=(char) LocaleToUppercase((
int)
14502 class_hints->res_class[0]);
14503 manager_hints->flags=InputHint | StateHint;
14504 manager_hints->input=MagickFalse;
14505 manager_hints->initial_state=WithdrawnState;
14506 XMakeWindow(display,root_window,argv,argc,class_hints,manager_hints,
14507 &windows->context);
14508 if (resource_info->debug != MagickFalse)
14509 (void) LogMagickEvent(X11Event,GetMagickModule(),
14510 "Window id: 0x%lx (context)",windows->context.id);
14511 context_values.background=pixel->background_color.pixel;
14512 context_values.font=font_info->fid;
14513 context_values.foreground=pixel->foreground_color.pixel;
14514 context_values.graphics_exposures=MagickFalse;
14515 context_mask=(MagickStatusType)
14516 (GCBackground | GCFont | GCForeground | GCGraphicsExposures);
14517 if (pixel->annotate_context != (GC) NULL)
14518 (
void) XFreeGC(display,pixel->annotate_context);
14519 pixel->annotate_context=XCreateGC(display,windows->context.id,
14520 context_mask,&context_values);
14521 if (pixel->annotate_context == (GC) NULL)
14522 ThrowXWindowFatalException(XServerFatalError,
"UnableToCreateGraphicContext",
14523 display_image->filename);
14524 context_values.background=pixel->depth_color.pixel;
14525 if (pixel->widget_context != (GC) NULL)
14526 (void) XFreeGC(display,pixel->widget_context);
14527 pixel->widget_context=XCreateGC(display,windows->context.id,context_mask,
14529 if (pixel->widget_context == (GC) NULL)
14530 ThrowXWindowFatalException(XServerFatalError,
"UnableToCreateGraphicContext",
14531 display_image->filename);
14532 context_values.background=pixel->foreground_color.pixel;
14533 context_values.foreground=pixel->background_color.pixel;
14534 context_values.plane_mask=context_values.background ^
14535 context_values.foreground;
14536 if (pixel->highlight_context != (GC) NULL)
14537 (void) XFreeGC(display,pixel->highlight_context);
14538 pixel->highlight_context=XCreateGC(display,windows->context.id,
14539 (
size_t) (context_mask | GCPlaneMask),&context_values);
14540 if (pixel->highlight_context == (GC) NULL)
14541 ThrowXWindowFatalException(XServerFatalError,
"UnableToCreateGraphicContext",
14542 display_image->filename);
14543 (void) XDestroyWindow(display,windows->context.id);
14547 XGetWindowInfo(display,icon_visual,icon_map,icon_pixel,(XFontStruct *) NULL,
14548 icon_resources,&windows->icon);
14549 windows->icon.geometry=resource_info->icon_geometry;
14550 XBestIconSize(display,&windows->icon,display_image);
14551 windows->icon.attributes.colormap=XDefaultColormap(display,
14552 icon_visual->screen);
14553 windows->icon.attributes.event_mask=ExposureMask | StructureNotifyMask;
14554 manager_hints->flags=InputHint | StateHint;
14555 manager_hints->input=MagickFalse;
14556 manager_hints->initial_state=IconicState;
14557 XMakeWindow(display,root_window,argv,argc,class_hints,manager_hints,
14559 if (resource_info->debug != MagickFalse)
14560 (void) LogMagickEvent(X11Event,GetMagickModule(),
"Window id: 0x%lx (icon)",
14565 if (icon_pixel->annotate_context != (GC) NULL)
14566 (
void) XFreeGC(display,icon_pixel->annotate_context);
14567 context_values.background=icon_pixel->background_color.pixel;
14568 context_values.foreground=icon_pixel->foreground_color.pixel;
14569 icon_pixel->annotate_context=XCreateGC(display,windows->icon.id,
14570 (
size_t) (GCBackground | GCForeground),&context_values);
14571 if (icon_pixel->annotate_context == (GC) NULL)
14572 ThrowXWindowFatalException(XServerFatalError,
"UnableToCreateGraphicContext",
14573 display_image->filename);
14574 windows->icon.annotate_context=icon_pixel->annotate_context;
14578 XGetWindowInfo(display,visual_info,map_info,pixel,font_info,resource_info,
14580 windows->image.shape=MagickTrue;
14581 if (resource_info->use_shared_memory == MagickFalse)
14582 windows->image.shared_memory=MagickFalse;
14583 if ((resource_info->title != (
char *) NULL) && !(*state & MontageImageState))
14588 title=InterpretImageProperties(resource_info->image_info,display_image,
14589 resource_info->title);
14590 (void) CloneString(&windows->image.name,title);
14591 (void) CloneString(&windows->image.icon_name,title);
14592 title=DestroyString(title);
14597 filename[MaxTextExtent],
14598 window_name[MaxTextExtent];
14603 GetPathComponent(display_image->magick_filename,TailPath,filename);
14604 if (display_image->scene == 0)
14605 (void) FormatLocaleString(window_name,MaxTextExtent,
"%s: %s",
14606 MagickPackageName,filename);
14608 (
void) FormatLocaleString(window_name,MaxTextExtent,
14609 "%s: %s[scene: %.20g frames: %.20g]",MagickPackageName,filename,
14610 (
double) display_image->scene,(
double) GetImageListLength(
14612 (void) CloneString(&windows->image.name,window_name);
14613 (void) CloneString(&windows->image.icon_name,filename);
14615 if (resource_info->immutable)
14616 windows->image.immutable=MagickTrue;
14617 windows->image.use_pixmap=resource_info->use_pixmap;
14618 windows->image.geometry=resource_info->image_geometry;
14619 (void) FormatLocaleString(geometry,MaxTextExtent,
"%ux%u+0+0>!",
14620 XDisplayWidth(display,visual_info->screen),
14621 XDisplayHeight(display,visual_info->screen));
14622 geometry_info.width=display_image->columns;
14623 geometry_info.height=display_image->rows;
14626 (void) ParseMetaGeometry(geometry,&geometry_info.x,&geometry_info.y,
14627 &geometry_info.width,&geometry_info.height);
14628 windows->image.width=(
unsigned int) geometry_info.width;
14629 windows->image.height=(
unsigned int) geometry_info.height;
14630 windows->image.attributes.event_mask=ButtonMotionMask | ButtonPressMask |
14631 ButtonReleaseMask | EnterWindowMask | ExposureMask | KeyPressMask |
14632 KeyReleaseMask | LeaveWindowMask | OwnerGrabButtonMask |
14633 PropertyChangeMask | StructureNotifyMask | SubstructureNotifyMask;
14634 XGetWindowInfo(display,visual_info,map_info,pixel,font_info,
14635 resource_info,&windows->backdrop);
14636 if ((resource_info->backdrop) || (windows->backdrop.id != (Window) NULL))
14641 windows->backdrop.x=0;
14642 windows->backdrop.y=0;
14643 (void) CloneString(&windows->backdrop.name,
"Backdrop");
14644 windows->backdrop.flags=(size_t) (USSize | USPosition);
14645 windows->backdrop.width=(
unsigned int)
14646 XDisplayWidth(display,visual_info->screen);
14647 windows->backdrop.height=(
unsigned int)
14648 XDisplayHeight(display,visual_info->screen);
14649 windows->backdrop.border_width=0;
14650 windows->backdrop.immutable=MagickTrue;
14651 windows->backdrop.attributes.do_not_propagate_mask=ButtonPressMask |
14653 windows->backdrop.attributes.event_mask=ButtonPressMask | KeyPressMask |
14654 StructureNotifyMask;
14655 manager_hints->flags=IconWindowHint | InputHint | StateHint;
14656 manager_hints->icon_window=windows->icon.id;
14657 manager_hints->input=MagickTrue;
14658 manager_hints->initial_state=resource_info->iconic ? IconicState :
14660 XMakeWindow(display,root_window,argv,argc,class_hints,manager_hints,
14661 &windows->backdrop);
14662 if (resource_info->debug != MagickFalse)
14663 (void) LogMagickEvent(X11Event,GetMagickModule(),
14664 "Window id: 0x%lx (backdrop)",windows->backdrop.id);
14665 (void) XMapWindow(display,windows->backdrop.id);
14666 (void) XClearWindow(display,windows->backdrop.id);
14667 if (windows->image.id != (Window) NULL)
14669 (void) XDestroyWindow(display,windows->image.id);
14670 windows->image.id=(Window) NULL;
14675 windows->image.flags|=USPosition;
14676 windows->image.x=(XDisplayWidth(display,visual_info->screen)/2)-
14677 (windows->image.width/2);
14678 windows->image.y=(XDisplayHeight(display,visual_info->screen)/2)-
14679 (windows->image.height/2);
14681 manager_hints->flags=IconWindowHint | InputHint | StateHint;
14682 manager_hints->icon_window=windows->icon.id;
14683 manager_hints->input=MagickTrue;
14684 manager_hints->initial_state=resource_info->iconic ? IconicState :
14686 if (windows->group_leader.id != (Window) NULL)
14691 manager_hints->flags|=WindowGroupHint;
14692 manager_hints->window_group=windows->group_leader.id;
14693 (void) XSelectInput(display,windows->group_leader.id,StructureNotifyMask);
14694 if (resource_info->debug != MagickFalse)
14695 (void) LogMagickEvent(X11Event,GetMagickModule(),
14696 "Window id: 0x%lx (group leader)",windows->group_leader.id);
14698 XMakeWindow(display,
14699 (Window) (resource_info->backdrop ? windows->backdrop.id : root_window),
14700 argv,argc,class_hints,manager_hints,&windows->image);
14701 (void) XChangeProperty(display,windows->image.id,windows->im_protocols,
14702 XA_STRING,8,PropModeReplace,(
unsigned char *) NULL,0);
14703 if (windows->group_leader.id != (Window) NULL)
14704 (
void) XSetTransientForHint(display,windows->image.id,
14705 windows->group_leader.id);
14706 if (resource_info->debug != MagickFalse)
14707 (void) LogMagickEvent(X11Event,GetMagickModule(),
"Window id: 0x%lx (image)",
14708 windows->image.id);
14712 XGetWindowInfo(display,visual_info,map_info,pixel,font_info,resource_info,
14714 (void) CloneString(&windows->info.name,
"Info");
14715 (void) CloneString(&windows->info.icon_name,
"Info");
14716 windows->info.border_width=1;
14719 windows->info.flags|=PPosition;
14720 windows->info.attributes.win_gravity=UnmapGravity;
14721 windows->info.attributes.event_mask=ButtonPressMask | ExposureMask |
14722 StructureNotifyMask;
14723 manager_hints->flags=InputHint | StateHint | WindowGroupHint;
14724 manager_hints->input=MagickFalse;
14725 manager_hints->initial_state=NormalState;
14726 manager_hints->window_group=windows->image.id;
14727 XMakeWindow(display,windows->image.id,argv,argc,class_hints,manager_hints,
14729 windows->info.highlight_stipple=XCreateBitmapFromData(display,
14730 windows->info.id,(
char *) HighlightBitmap,HighlightWidth,HighlightHeight);
14731 windows->info.shadow_stipple=XCreateBitmapFromData(display,
14732 windows->info.id,(
char *) ShadowBitmap,ShadowWidth,ShadowHeight);
14733 (void) XSetTransientForHint(display,windows->info.id,windows->image.id);
14734 if (windows->image.mapped != MagickFalse)
14735 (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
14736 if (resource_info->debug != MagickFalse)
14737 (void) LogMagickEvent(X11Event,GetMagickModule(),
"Window id: 0x%lx (info)",
14742 XGetWindowInfo(display,visual_info,map_info,pixel,font_info,
14743 resource_info,&windows->command);
14744 windows->command.data=MagickMenus;
14745 (void) XCommandWidget(display,windows,CommandMenu,(XEvent *) NULL);
14746 (void) FormatLocaleString(resource_name,MaxTextExtent,
"%s.command",
14747 resource_info->client_name);
14748 windows->command.geometry=XGetResourceClass(resource_info->resource_database,
14749 resource_name,
"geometry",(
char *) NULL);
14750 (void) CloneString(&windows->command.name,MagickTitle);
14751 windows->command.border_width=0;
14752 windows->command.flags|=PPosition;
14753 windows->command.attributes.event_mask=ButtonMotionMask | ButtonPressMask |
14754 ButtonReleaseMask | EnterWindowMask | ExposureMask | LeaveWindowMask |
14755 OwnerGrabButtonMask | StructureNotifyMask;
14756 manager_hints->flags=InputHint | StateHint | WindowGroupHint;
14757 manager_hints->input=MagickTrue;
14758 manager_hints->initial_state=NormalState;
14759 manager_hints->window_group=windows->image.id;
14760 XMakeWindow(display,root_window,argv,argc,class_hints,manager_hints,
14761 &windows->command);
14762 windows->command.highlight_stipple=XCreateBitmapFromData(display,
14763 windows->command.id,(
char *) HighlightBitmap,HighlightWidth,
14765 windows->command.shadow_stipple=XCreateBitmapFromData(display,
14766 windows->command.id,(
char *) ShadowBitmap,ShadowWidth,ShadowHeight);
14767 (void) XSetTransientForHint(display,windows->command.id,windows->image.id);
14768 if (windows->command.mapped != MagickFalse)
14769 (void) XMapRaised(display,windows->command.id);
14770 if (resource_info->debug != MagickFalse)
14771 (void) LogMagickEvent(X11Event,GetMagickModule(),
14772 "Window id: 0x%lx (command)",windows->command.id);
14776 XGetWindowInfo(display,visual_info,map_info,pixel,font_info,
14777 resource_info,&windows->widget);
14778 (void) FormatLocaleString(resource_name,MaxTextExtent,
"%s.widget",
14779 resource_info->client_name);
14780 windows->widget.geometry=XGetResourceClass(resource_info->resource_database,
14781 resource_name,
"geometry",(
char *) NULL);
14782 windows->widget.border_width=0;
14783 windows->widget.flags|=PPosition;
14784 windows->widget.attributes.event_mask=ButtonMotionMask | ButtonPressMask |
14785 ButtonReleaseMask | EnterWindowMask | ExposureMask | KeyPressMask |
14786 KeyReleaseMask | LeaveWindowMask | OwnerGrabButtonMask |
14787 StructureNotifyMask;
14788 manager_hints->flags=InputHint | StateHint | WindowGroupHint;
14789 manager_hints->input=MagickTrue;
14790 manager_hints->initial_state=NormalState;
14791 manager_hints->window_group=windows->image.id;
14792 XMakeWindow(display,root_window,argv,argc,class_hints,manager_hints,
14794 windows->widget.highlight_stipple=XCreateBitmapFromData(display,
14795 windows->widget.id,(
char *) HighlightBitmap,HighlightWidth,HighlightHeight);
14796 windows->widget.shadow_stipple=XCreateBitmapFromData(display,
14797 windows->widget.id,(
char *) ShadowBitmap,ShadowWidth,ShadowHeight);
14798 (void) XSetTransientForHint(display,windows->widget.id,windows->image.id);
14799 if (resource_info->debug != MagickFalse)
14800 (void) LogMagickEvent(X11Event,GetMagickModule(),
14801 "Window id: 0x%lx (widget)",windows->widget.id);
14805 XGetWindowInfo(display,visual_info,map_info,pixel,font_info,
14806 resource_info,&windows->popup);
14807 windows->popup.border_width=0;
14808 windows->popup.flags|=PPosition;
14809 windows->popup.attributes.event_mask=ButtonMotionMask | ButtonPressMask |
14810 ButtonReleaseMask | EnterWindowMask | ExposureMask | KeyPressMask |
14811 KeyReleaseMask | LeaveWindowMask | StructureNotifyMask;
14812 manager_hints->flags=InputHint | StateHint | WindowGroupHint;
14813 manager_hints->input=MagickTrue;
14814 manager_hints->initial_state=NormalState;
14815 manager_hints->window_group=windows->image.id;
14816 XMakeWindow(display,root_window,argv,argc,class_hints,manager_hints,
14818 windows->popup.highlight_stipple=XCreateBitmapFromData(display,
14819 windows->popup.id,(
char *) HighlightBitmap,HighlightWidth,HighlightHeight);
14820 windows->popup.shadow_stipple=XCreateBitmapFromData(display,
14821 windows->popup.id,(
char *) ShadowBitmap,ShadowWidth,ShadowHeight);
14822 (void) XSetTransientForHint(display,windows->popup.id,windows->image.id);
14823 if (resource_info->debug != MagickFalse)
14824 (void) LogMagickEvent(X11Event,GetMagickModule(),
14825 "Window id: 0x%lx (pop up)",windows->popup.id);
14829 XGetWindowInfo(display,visual_info,map_info,pixel,font_info,
14830 resource_info,&windows->magnify);
14831 if (resource_info->use_shared_memory == MagickFalse)
14832 windows->magnify.shared_memory=MagickFalse;
14833 (void) FormatLocaleString(resource_name,MaxTextExtent,
"%s.magnify",
14834 resource_info->client_name);
14835 windows->magnify.geometry=XGetResourceClass(resource_info->resource_database,
14836 resource_name,
"geometry",(
char *) NULL);
14837 (void) FormatLocaleString(windows->magnify.name,MaxTextExtent,
"Magnify %uX",
14838 resource_info->magnify);
14839 if (windows->magnify.cursor != (Cursor) NULL)
14840 (
void) XFreeCursor(display,windows->magnify.cursor);
14841 windows->magnify.cursor=XMakeCursor(display,windows->image.id,
14842 map_info->colormap,resource_info->background_color,
14843 resource_info->foreground_color);
14844 if (windows->magnify.cursor == (Cursor) NULL)
14845 ThrowXWindowFatalException(XServerFatalError,
"UnableToCreateCursor",
14846 display_image->filename);
14847 windows->magnify.width=MagnifySize;
14848 windows->magnify.height=MagnifySize;
14849 windows->magnify.flags|=PPosition;
14850 windows->magnify.min_width=MagnifySize;
14851 windows->magnify.min_height=MagnifySize;
14852 windows->magnify.width_inc=MagnifySize;
14853 windows->magnify.height_inc=MagnifySize;
14854 windows->magnify.data=resource_info->magnify;
14855 windows->magnify.attributes.cursor=windows->magnify.cursor;
14856 windows->magnify.attributes.event_mask=ButtonPressMask | ButtonReleaseMask |
14857 ExposureMask | KeyPressMask | KeyReleaseMask | OwnerGrabButtonMask |
14858 StructureNotifyMask;
14859 manager_hints->flags=InputHint | StateHint | WindowGroupHint;
14860 manager_hints->input=MagickTrue;
14861 manager_hints->initial_state=NormalState;
14862 manager_hints->window_group=windows->image.id;
14863 XMakeWindow(display,root_window,argv,argc,class_hints,manager_hints,
14864 &windows->magnify);
14865 if (resource_info->debug != MagickFalse)
14866 (void) LogMagickEvent(X11Event,GetMagickModule(),
14867 "Window id: 0x%lx (magnify)",windows->magnify.id);
14868 (void) XSetTransientForHint(display,windows->magnify.id,windows->image.id);
14872 XGetWindowInfo(display,visual_info,map_info,pixel,font_info,
14873 resource_info,&windows->pan);
14874 (void) CloneString(&windows->pan.name,
"Pan Icon");
14875 windows->pan.width=windows->icon.width;
14876 windows->pan.height=windows->icon.height;
14877 (void) FormatLocaleString(resource_name,MaxTextExtent,
"%s.pan",
14878 resource_info->client_name);
14879 windows->pan.geometry=XGetResourceClass(resource_info->resource_database,
14880 resource_name,
"geometry",(
char *) NULL);
14881 (void) XParseGeometry(windows->pan.geometry,&windows->pan.x,&windows->pan.y,
14882 &windows->pan.width,&windows->pan.height);
14883 windows->pan.flags|=PPosition;
14884 windows->pan.immutable=MagickTrue;
14885 windows->pan.attributes.event_mask=ButtonMotionMask | ButtonPressMask |
14886 ButtonReleaseMask | ExposureMask | KeyPressMask | KeyReleaseMask |
14887 StructureNotifyMask;
14888 manager_hints->flags=InputHint | StateHint | WindowGroupHint;
14889 manager_hints->input=MagickFalse;
14890 manager_hints->initial_state=NormalState;
14891 manager_hints->window_group=windows->image.id;
14892 XMakeWindow(display,root_window,argv,argc,class_hints,manager_hints,
14894 if (resource_info->debug != MagickFalse)
14895 (void) LogMagickEvent(X11Event,GetMagickModule(),
"Window id: 0x%lx (pan)",
14897 (void) XSetTransientForHint(display,windows->pan.id,windows->image.id);
14898 if (windows->info.mapped != MagickFalse)
14899 (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
14900 if ((windows->image.mapped == MagickFalse) ||
14901 (windows->backdrop.id != (Window) NULL))
14902 (
void) XMapWindow(display,windows->image.id);
14906 if (warning_handler == (WarningHandler) NULL)
14908 warning_handler=resource_info->display_warnings ?
14909 SetErrorHandler(XWarning) : SetErrorHandler((ErrorHandler) NULL);
14910 warning_handler=resource_info->display_warnings ?
14911 SetWarningHandler(XWarning) : SetWarningHandler((WarningHandler) NULL);
14916 windows->image.x=0;
14917 windows->image.y=0;
14918 windows->magnify.shape=MagickFalse;
14919 width=(
unsigned int) display_image->columns;
14920 height=(
unsigned int) display_image->rows;
14921 if ((display_image->columns != width) || (display_image->rows != height))
14922 ThrowXWindowFatalException(XServerFatalError,
"UnableToCreateXImage",
14923 display_image->filename);
14924 status=XMakeImage(display,resource_info,&windows->image,display_image,
14926 if (status == MagickFalse)
14927 ThrowXWindowFatalException(XServerFatalError,
"UnableToCreateXImage",
14928 display_image->filename);
14929 status=XMakeImage(display,resource_info,&windows->magnify,(
Image *) NULL,
14930 windows->magnify.width,windows->magnify.height);
14931 if (status == MagickFalse)
14932 ThrowXWindowFatalException(XServerFatalError,
"UnableToCreateXImage",
14933 display_image->filename);
14934 if (windows->magnify.mapped != MagickFalse)
14935 (void) XMapRaised(display,windows->magnify.id);
14936 if (windows->pan.mapped != MagickFalse)
14937 (void) XMapRaised(display,windows->pan.id);
14938 windows->image.window_changes.width=(int) display_image->columns;
14939 windows->image.window_changes.height=(
int) display_image->rows;
14940 (void) XConfigureImage(display,resource_info,windows,display_image);
14941 (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
14942 (void) XSync(display,MagickFalse);
14946 delay=display_image->delay/MagickMax(display_image->ticks_per_second,1L);
14947 timer=GetMagickTime()+(delay == 0 ? 1 : delay)+1;
14949 if (resource_info->update != MagickFalse)
14957 status=GetPathAttributes(display_image->filename,&attributes);
14958 if (status != MagickFalse)
14959 update_time=attributes.st_mtime;
14961 *state&=(~FormerImageState);
14962 *state&=(~MontageImageState);
14963 *state&=(~NextImageState);
14969 if (windows->image.mapped != MagickFalse)
14970 if ((display_image->delay != 0) || (resource_info->update != 0))
14972 if (timer < GetMagickTime())
14974 if (resource_info->update == MagickFalse)
14975 *state|=NextImageState | ExitState;
14984 status=GetPathAttributes(display_image->filename,&attributes);
14985 if (status != MagickFalse)
14986 if (update_time != attributes.st_mtime)
14991 (void) FormatLocaleString(
14992 resource_info->image_info->filename,MaxTextExtent,
14993 "%s:%s",display_image->magick,
14994 display_image->filename);
14995 nexus=ReadImage(resource_info->image_info,
14996 &display_image->exception);
14997 if (nexus != (
Image *) NULL)
14998 *state|=NextImageState | ExitState;
15000 delay=display_image->delay/MagickMax(
15001 display_image->ticks_per_second,1L);
15002 timer=GetMagickTime()+(delay == 0 ? 1 : delay)+1;
15005 if (XEventsQueued(display,QueuedAfterFlush) == 0)
15010 XDelay(display,SuspendTime << 2);
15014 timestamp=GetMagickTime();
15015 (void) XNextEvent(display,&event);
15016 if (windows->image.stasis == MagickFalse)
15017 windows->image.stasis=(GetMagickTime()-timestamp) > 0 ?
15018 MagickTrue : MagickFalse;
15019 if (windows->magnify.stasis == MagickFalse)
15020 windows->magnify.stasis=(GetMagickTime()-timestamp) > 0 ?
15021 MagickTrue : MagickFalse;
15022 if (event.xany.window == windows->command.id)
15027 id=XCommandWidget(display,windows,CommandMenu,&event);
15030 (void) CopyMagickString(command,CommandMenu[
id],MaxTextExtent);
15031 display_command=CommandMenus[id];
15032 if (
id < MagickMenus)
15037 entry=XMenuWidget(display,windows,CommandMenu[
id],Menus[
id],
15041 (void) CopyMagickString(command,Menus[
id][entry],MaxTextExtent);
15042 display_command=Commands[id][entry];
15044 if (display_command != NullCommand)
15045 nexus=XMagickCommand(display,resource_info,windows,display_command,
15049 switch (event.type)
15053 if (resource_info->debug != MagickFalse)
15054 (void) LogMagickEvent(X11Event,GetMagickModule(),
15055 "Button Press: 0x%lx %u +%d+%d",
event.xbutton.window,
15056 event.xbutton.button,
event.xbutton.x,
event.xbutton.y);
15057 if ((event.xbutton.button == Button3) &&
15058 (
event.xbutton.state & Mod1Mask))
15063 event.xbutton.button=Button2;
15064 event.xbutton.state&=(~Mod1Mask);
15066 if (event.xbutton.window == windows->backdrop.id)
15068 (void) XSetInputFocus(display,event.xbutton.window,RevertToParent,
15069 event.xbutton.time);
15072 if (event.xbutton.window == windows->image.id)
15074 switch (event.xbutton.button)
15078 if (resource_info->immutable)
15083 entry=XMenuWidget(display,windows,
"Commands",VirtualMenu,
15086 nexus=XMagickCommand(display,resource_info,windows,
15087 VirtualCommands[entry],&display_image);
15093 if (windows->command.mapped != MagickFalse)
15094 (void) XWithdrawWindow(display,windows->command.id,
15095 windows->command.screen);
15098 (void) XCommandWidget(display,windows,CommandMenu,
15100 (void) XMapRaised(display,windows->command.id);
15109 (void) XMagickCommand(display,resource_info,windows,ZoomCommand,
15111 XMagnifyImage(display,windows,&event);
15116 if (resource_info->immutable)
15121 entry=XMenuWidget(display,windows,
"Commands",VirtualMenu,
15124 nexus=XMagickCommand(display,resource_info,windows,
15125 VirtualCommands[entry],&display_image);
15128 if (display_image->montage != (
char *) NULL)
15133 nexus=XTileImage(display,resource_info,windows,
15134 display_image,&event);
15135 if (nexus != (
Image *) NULL)
15136 *state|=MontageImageState | NextImageState | ExitState;
15137 vid_info.x=(
short int) windows->image.x;
15138 vid_info.y=(
short int) windows->image.y;
15144 entry=XMenuWidget(display,windows,
"Short Cuts",ShortCutsMenu,
15147 nexus=XMagickCommand(display,resource_info,windows,
15148 ShortCutsCommands[entry],&display_image);
15156 XTranslateImage(display,windows,*image,XK_Up);
15164 XTranslateImage(display,windows,*image,XK_Down);
15172 if (event.xbutton.window == windows->magnify.id)
15175 *
const MagnifyMenu[] =
15192 MagnifyCommands[] =
15207 factor=XMenuWidget(display,windows,
"Magnify",MagnifyMenu,command);
15209 XMagnifyWindowCommand(display,windows,0,MagnifyCommands[factor]);
15212 if (event.xbutton.window == windows->pan.id)
15214 switch (event.xbutton.button)
15221 XTranslateImage(display,windows,*image,XK_Up);
15229 XTranslateImage(display,windows,*image,XK_Down);
15234 XPanImage(display,windows,&event);
15240 delay=display_image->delay/MagickMax(display_image->ticks_per_second,
15242 timer=GetMagickTime()+(delay == 0 ? 1 : delay)+1;
15245 case ButtonRelease:
15247 if (resource_info->debug != MagickFalse)
15248 (void) LogMagickEvent(X11Event,GetMagickModule(),
15249 "Button Release: 0x%lx %u +%d+%d",
event.xbutton.window,
15250 event.xbutton.button,
event.xbutton.x,
event.xbutton.y);
15253 case ClientMessage:
15255 if (resource_info->debug != MagickFalse)
15256 (void) LogMagickEvent(X11Event,GetMagickModule(),
15257 "Client Message: 0x%lx 0x%lx %d 0x%lx",
event.xclient.window,
15258 event.xclient.message_type,
event.xclient.format,(
unsigned long)
15259 event.xclient.data.l[0]);
15260 if (event.xclient.message_type == windows->im_protocols)
15262 if (*event.xclient.data.l == (
long) windows->im_update_widget)
15264 (void) CloneString(&windows->command.name,MagickTitle);
15265 windows->command.data=MagickMenus;
15266 (void) XCommandWidget(display,windows,CommandMenu,
15270 if (*event.xclient.data.l == (
long) windows->im_update_colormap)
15275 for (i=0; i < (int) number_windows; i++)
15277 if (magick_windows[i]->
id == windows->icon.id)
15279 context_values.background=pixel->background_color.pixel;
15280 context_values.foreground=pixel->foreground_color.pixel;
15281 (void) XChangeGC(display,magick_windows[i]->annotate_context,
15282 context_mask,&context_values);
15283 (void) XChangeGC(display,magick_windows[i]->widget_context,
15284 context_mask,&context_values);
15285 context_values.background=pixel->foreground_color.pixel;
15286 context_values.foreground=pixel->background_color.pixel;
15287 context_values.plane_mask=context_values.background ^
15288 context_values.foreground;
15289 (void) XChangeGC(display,magick_windows[i]->highlight_context,
15290 (
size_t) (context_mask | GCPlaneMask),
15292 magick_windows[i]->attributes.background_pixel=
15293 pixel->background_color.pixel;
15294 magick_windows[i]->attributes.border_pixel=
15295 pixel->border_color.pixel;
15296 magick_windows[i]->attributes.colormap=map_info->colormap;
15297 (void) XChangeWindowAttributes(display,magick_windows[i]->
id,
15298 (
unsigned long) magick_windows[i]->mask,
15299 &magick_windows[i]->attributes);
15301 if (windows->pan.mapped != MagickFalse)
15303 (void) XSetWindowBackgroundPixmap(display,windows->pan.id,
15304 windows->pan.pixmap);
15305 (void) XClearWindow(display,windows->pan.id);
15306 XDrawPanRectangle(display,windows);
15308 if (windows->backdrop.id != (Window) NULL)
15309 (void) XInstallColormap(display,map_info->colormap);
15312 if (*event.xclient.data.l == (
long) windows->im_former_image)
15314 *state|=FormerImageState | ExitState;
15317 if (*event.xclient.data.l == (
long) windows->im_next_image)
15319 *state|=NextImageState | ExitState;
15322 if (*event.xclient.data.l == (
long) windows->im_retain_colors)
15324 *state|=RetainColorsState;
15327 if (*event.xclient.data.l == (
long) windows->im_exit)
15334 if (event.xclient.message_type == windows->dnd_protocols)
15354 if ((*event.xclient.data.l != 2) && (*
event.xclient.data.l != 128))
15356 selection=XInternAtom(display,
"DndSelection",MagickFalse);
15357 status=XGetWindowProperty(display,root_window,selection,0L,(
long)
15358 MaxTextExtent,MagickFalse,(Atom) AnyPropertyType,&type,&format,
15359 &length,&after,&data);
15360 if ((status != Success) || (length == 0))
15362 if (*event.xclient.data.l == 2)
15367 (void) CopyMagickString(resource_info->image_info->filename,
15368 (
char *) data,MaxTextExtent);
15375 if (strncmp((
char *) data,
"file:", 5) != 0)
15377 (void) XFree((
void *) data);
15380 (void) CopyMagickString(resource_info->image_info->filename,
15381 ((
char *) data)+5,MaxTextExtent);
15383 nexus=ReadImage(resource_info->image_info,
15384 &display_image->exception);
15385 CatchException(&display_image->exception);
15386 if (nexus != (
Image *) NULL)
15387 *state|=NextImageState | ExitState;
15388 (void) XFree((
void *) data);
15394 if (event.xclient.message_type != windows->wm_protocols)
15396 if (*event.xclient.data.l != (
long) windows->wm_delete_window)
15398 (void) XWithdrawWindow(display,event.xclient.window,
15399 visual_info->screen);
15400 if (event.xclient.window == windows->image.id)
15405 if (event.xclient.window == windows->pan.id)
15410 windows->image.window_changes.width=windows->image.ximage->width;
15411 windows->image.window_changes.height=windows->image.ximage->height;
15412 (void) XConfigureImage(display,resource_info,windows,
15417 case ConfigureNotify:
15419 if (resource_info->debug != MagickFalse)
15420 (void) LogMagickEvent(X11Event,GetMagickModule(),
15421 "Configure Notify: 0x%lx %dx%d+%d+%d %d",
event.xconfigure.window,
15422 event.xconfigure.width,
event.xconfigure.height,
event.xconfigure.x,
15423 event.xconfigure.y,
event.xconfigure.send_event);
15424 if (event.xconfigure.window == windows->image.id)
15429 if (event.xconfigure.send_event != 0)
15437 if (windows->command.geometry == (
char *) NULL)
15438 if (windows->command.mapped == MagickFalse)
15440 windows->command.x=
event.xconfigure.x-
15441 windows->command.width-25;
15442 windows->command.y=
event.xconfigure.y;
15443 XConstrainWindowPosition(display,&windows->command);
15444 window_changes.x=windows->command.x;
15445 window_changes.y=windows->command.y;
15446 (void) XReconfigureWMWindow(display,windows->command.id,
15447 windows->command.screen,(
unsigned int) (CWX | CWY),
15450 if (windows->widget.geometry == (
char *) NULL)
15451 if (windows->widget.mapped == MagickFalse)
15453 windows->widget.x=
event.xconfigure.x+
15454 event.xconfigure.width/10;
15455 windows->widget.y=
event.xconfigure.y+
15456 event.xconfigure.height/10;
15457 XConstrainWindowPosition(display,&windows->widget);
15458 window_changes.x=windows->widget.x;
15459 window_changes.y=windows->widget.y;
15460 (void) XReconfigureWMWindow(display,windows->widget.id,
15461 windows->widget.screen,(
unsigned int) (CWX | CWY),
15464 if (windows->magnify.geometry == (
char *) NULL)
15465 if (windows->magnify.mapped == MagickFalse)
15467 windows->magnify.x=
event.xconfigure.x+
15468 event.xconfigure.width+25;
15469 windows->magnify.y=
event.xconfigure.y;
15470 XConstrainWindowPosition(display,&windows->magnify);
15471 window_changes.x=windows->magnify.x;
15472 window_changes.y=windows->magnify.y;
15473 (void) XReconfigureWMWindow(display,windows->magnify.id,
15474 windows->magnify.screen,(
unsigned int) (CWX | CWY),
15477 if (windows->pan.geometry == (
char *) NULL)
15478 if (windows->pan.mapped == MagickFalse)
15480 windows->pan.x=
event.xconfigure.x+
15481 event.xconfigure.width+25;
15482 windows->pan.y=
event.xconfigure.y+
15483 windows->magnify.height+50;
15484 XConstrainWindowPosition(display,&windows->pan);
15485 window_changes.x=windows->pan.x;
15486 window_changes.y=windows->pan.y;
15487 (void) XReconfigureWMWindow(display,windows->pan.id,
15488 windows->pan.screen,(
unsigned int) (CWX | CWY),
15492 if ((event.xconfigure.width == (
int) windows->image.width) &&
15493 (event.xconfigure.height == (
int) windows->image.height))
15495 windows->image.width=(
unsigned int) event.xconfigure.width;
15496 windows->image.height=(
unsigned int)
event.xconfigure.height;
15497 windows->image.x=0;
15498 windows->image.y=0;
15499 if (display_image->montage != (
char *) NULL)
15501 windows->image.x=vid_info.x;
15502 windows->image.y=vid_info.y;
15504 if ((windows->image.mapped != MagickFalse) &&
15505 (windows->image.stasis != MagickFalse))
15510 windows->image.window_changes.width=
event.xconfigure.width;
15511 windows->image.window_changes.height=
event.xconfigure.height;
15512 (void) XConfigureImage(display,resource_info,windows,
15518 if ((event.xconfigure.width < windows->image.ximage->width) ||
15519 (
event.xconfigure.height < windows->image.ximage->height))
15521 (void) XMapRaised(display,windows->pan.id);
15522 XDrawPanRectangle(display,windows);
15525 if (windows->pan.mapped != MagickFalse)
15526 (void) XWithdrawWindow(display,windows->pan.id,
15527 windows->pan.screen);
15530 if (event.xconfigure.window == windows->magnify.id)
15538 windows->magnify.width=(
unsigned int) event.xconfigure.width;
15539 windows->magnify.height=(
unsigned int)
event.xconfigure.height;
15540 if (windows->magnify.mapped == MagickFalse)
15543 while ((
int) magnify <=
event.xconfigure.width)
15545 while ((
int) magnify <=
event.xconfigure.height)
15548 if (((
int) magnify !=
event.xconfigure.width) ||
15549 ((
int) magnify !=
event.xconfigure.height))
15551 window_changes.width=(int) magnify;
15552 window_changes.height=(int) magnify;
15553 (void) XReconfigureWMWindow(display,windows->magnify.id,
15554 windows->magnify.screen,(
unsigned int) (CWWidth | CWHeight),
15558 if ((windows->magnify.mapped != MagickFalse) &&
15559 (windows->magnify.stasis != MagickFalse))
15561 status=XMakeImage(display,resource_info,&windows->magnify,
15562 display_image,windows->magnify.width,windows->magnify.height);
15563 XMakeMagnifyImage(display,windows);
15567 if ((windows->magnify.mapped != MagickFalse) &&
15568 (event.xconfigure.window == windows->pan.id))
15573 if (event.xconfigure.send_event != 0)
15575 windows->pan.x=
event.xconfigure.x;
15576 windows->pan.y=
event.xconfigure.y;
15578 windows->pan.width=(
unsigned int) event.xconfigure.width;
15579 windows->pan.height=(
unsigned int)
event.xconfigure.height;
15582 if (event.xconfigure.window == windows->icon.id)
15587 windows->icon.width=(
unsigned int) event.xconfigure.width;
15588 windows->icon.height=(
unsigned int)
event.xconfigure.height;
15593 case DestroyNotify:
15598 if (resource_info->debug != MagickFalse)
15599 (void) LogMagickEvent(X11Event,GetMagickModule(),
15600 "Destroy Notify: 0x%lx",
event.xdestroywindow.window);
15601 if (event.xdestroywindow.window == windows->group_leader.id)
15613 if (map_info->colormap != XDefaultColormap(display,visual_info->screen))
15614 if (event.xcrossing.mode != NotifyUngrab)
15615 XInstallColormap(display,map_info->colormap);
15620 if (resource_info->debug != MagickFalse)
15621 (void) LogMagickEvent(X11Event,GetMagickModule(),
15622 "Expose: 0x%lx %dx%d+%d+%d",
event.xexpose.window,
15623 event.xexpose.width,
event.xexpose.height,
event.xexpose.x,
15628 if ((event.xexpose.window == windows->image.id) &&
15629 (windows->image.mapped != MagickFalse))
15631 XRefreshWindow(display,&windows->image,&event);
15632 delay=display_image->delay/MagickMax(
15633 display_image->ticks_per_second,1L);
15634 timer=GetMagickTime()+(delay == 0 ? 1 : delay)+1;
15637 if ((event.xexpose.window == windows->magnify.id) &&
15638 (windows->magnify.mapped != MagickFalse))
15640 XMakeMagnifyImage(display,windows);
15643 if (event.xexpose.window == windows->pan.id)
15645 XDrawPanRectangle(display,windows);
15648 if (event.xexpose.window == windows->icon.id)
15650 XRefreshWindow(display,&windows->icon,&event);
15663 length=XLookupString((XKeyEvent *) &event.xkey,command,(
int)
15664 sizeof(command),&key_symbol,(XComposeStatus *) NULL);
15665 *(command+length)=
'\0';
15666 if (resource_info->debug != MagickFalse)
15667 (void) LogMagickEvent(X11Event,GetMagickModule(),
15668 "Key press: %d 0x%lx (%s)",
event.xkey.state,(
unsigned long)
15669 key_symbol,command);
15670 if (event.xkey.window == windows->image.id)
15672 display_command=XImageWindowCommand(display,resource_info,windows,
15673 event.xkey.state,key_symbol,&display_image);
15674 if (display_command != NullCommand)
15675 nexus=XMagickCommand(display,resource_info,windows,display_command,
15678 if (event.xkey.window == windows->magnify.id)
15679 XMagnifyWindowCommand(display,windows,event.xkey.state,key_symbol);
15680 if (event.xkey.window == windows->pan.id)
15682 if ((key_symbol == XK_q) || (key_symbol == XK_Escape))
15683 (void) XWithdrawWindow(display,windows->pan.id,
15684 windows->pan.screen);
15686 if ((key_symbol == XK_F1) || (key_symbol == XK_Help))
15687 XTextViewHelp(display,resource_info,windows,MagickFalse,
15688 "Help Viewer - Image Pan",ImagePanHelp);
15690 XTranslateImage(display,windows,*image,key_symbol);
15692 delay=display_image->delay/MagickMax(
15693 display_image->ticks_per_second,1L);
15694 timer=GetMagickTime()+(delay == 0 ? 1 : delay)+1;
15702 (void) XLookupString((XKeyEvent *) &
event.xkey,command,(int)
15703 sizeof(command),&key_symbol,(XComposeStatus *) NULL);
15704 if (resource_info->debug != MagickFalse)
15705 (void) LogMagickEvent(X11Event,GetMagickModule(),
15706 "Key release: 0x%lx (%c)",(
unsigned long) key_symbol,*command);
15714 if (map_info->colormap != XDefaultColormap(display,visual_info->screen))
15715 if (event.xcrossing.mode != NotifyUngrab)
15716 XUninstallColormap(display,map_info->colormap);
15721 if (resource_info->debug != MagickFalse)
15722 (void) LogMagickEvent(X11Event,GetMagickModule(),
"Map Notify: 0x%lx",
15723 event.xmap.window);
15724 if (event.xmap.window == windows->backdrop.id)
15726 (void) XSetInputFocus(display,event.xmap.window,RevertToParent,
15728 windows->backdrop.mapped=MagickTrue;
15731 if (event.xmap.window == windows->image.id)
15733 if (windows->backdrop.id != (Window) NULL)
15734 (
void) XInstallColormap(display,map_info->colormap);
15735 if (LocaleCompare(display_image->magick,
"LOGO") == 0)
15737 if (LocaleCompare(display_image->filename,
"LOGO") == 0)
15738 nexus=XOpenImage(display,resource_info,windows,MagickFalse);
15740 if (((
int) windows->image.width < windows->image.ximage->width) ||
15741 ((
int) windows->image.height < windows->image.ximage->height))
15742 (void) XMapRaised(display,windows->pan.id);
15743 windows->image.mapped=MagickTrue;
15746 if (event.xmap.window == windows->magnify.id)
15748 XMakeMagnifyImage(display,windows);
15749 windows->magnify.mapped=MagickTrue;
15750 (void) XWithdrawWindow(display,windows->info.id,
15751 windows->info.screen);
15754 if (event.xmap.window == windows->pan.id)
15756 XMakePanImage(display,resource_info,windows,display_image);
15757 windows->pan.mapped=MagickTrue;
15760 if (event.xmap.window == windows->info.id)
15762 windows->info.mapped=MagickTrue;
15765 if (event.xmap.window == windows->icon.id)
15773 taint=display_image->taint;
15774 XMakeStandardColormap(display,icon_visual,icon_resources,
15775 display_image,icon_map,icon_pixel);
15776 (void) XMakeImage(display,icon_resources,&windows->icon,
15777 display_image,windows->icon.width,windows->icon.height);
15778 display_image->taint=taint;
15779 (void) XSetWindowBackgroundPixmap(display,windows->icon.id,
15780 windows->icon.pixmap);
15781 (void) XClearWindow(display,windows->icon.id);
15782 (void) XWithdrawWindow(display,windows->info.id,
15783 windows->info.screen);
15784 windows->icon.mapped=MagickTrue;
15787 if (event.xmap.window == windows->command.id)
15789 windows->command.mapped=MagickTrue;
15792 if (event.xmap.window == windows->popup.id)
15794 windows->popup.mapped=MagickTrue;
15797 if (event.xmap.window == windows->widget.id)
15799 windows->widget.mapped=MagickTrue;
15804 case MappingNotify:
15806 (void) XRefreshKeyboardMapping(&event.xmapping);
15811 case PropertyNotify:
15827 if (resource_info->debug != MagickFalse)
15828 (void) LogMagickEvent(X11Event,GetMagickModule(),
15829 "Property Notify: 0x%lx 0x%lx %d",
event.xproperty.window,
15830 event.xproperty.atom,
event.xproperty.state);
15831 if (event.xproperty.atom != windows->im_remote_command)
15836 status=XGetWindowProperty(display,event.xproperty.window,
15837 event.xproperty.atom,0L,(
long) MaxTextExtent,MagickFalse,(Atom)
15838 AnyPropertyType,&type,&format,&length,&after,&data);
15839 if ((status != Success) || (length == 0))
15841 if (LocaleCompare((
char *) data,
"-quit") == 0)
15843 XClientMessage(display,windows->image.id,windows->im_protocols,
15844 windows->im_exit,CurrentTime);
15845 (void) XFree((
void *) data);
15848 (void) CopyMagickString(resource_info->image_info->filename,
15849 (
char *) data,MaxTextExtent);
15850 (void) XFree((
void *) data);
15851 nexus=ReadImage(resource_info->image_info,&display_image->exception);
15852 CatchException(&display_image->exception);
15853 if (nexus != (
Image *) NULL)
15854 *state|=NextImageState | ExitState;
15857 case ReparentNotify:
15859 if (resource_info->debug != MagickFalse)
15860 (void) LogMagickEvent(X11Event,GetMagickModule(),
15861 "Reparent Notify: 0x%lx=>0x%lx",
event.xreparent.parent,
15862 event.xreparent.window);
15867 if (resource_info->debug != MagickFalse)
15868 (void) LogMagickEvent(X11Event,GetMagickModule(),
15869 "Unmap Notify: 0x%lx",
event.xunmap.window);
15870 if (event.xunmap.window == windows->backdrop.id)
15872 windows->backdrop.mapped=MagickFalse;
15875 if (event.xunmap.window == windows->image.id)
15877 windows->image.mapped=MagickFalse;
15880 if (event.xunmap.window == windows->magnify.id)
15882 windows->magnify.mapped=MagickFalse;
15885 if (event.xunmap.window == windows->pan.id)
15887 windows->pan.mapped=MagickFalse;
15890 if (event.xunmap.window == windows->info.id)
15892 windows->info.mapped=MagickFalse;
15895 if (event.xunmap.window == windows->icon.id)
15897 if (map_info->colormap == icon_map->colormap)
15898 XConfigureImageColormap(display,resource_info,windows,
15900 (void) XFreeStandardColormap(display,icon_visual,icon_map,
15902 windows->icon.mapped=MagickFalse;
15905 if (event.xunmap.window == windows->command.id)
15907 windows->command.mapped=MagickFalse;
15910 if (event.xunmap.window == windows->popup.id)
15912 if (windows->backdrop.id != (Window) NULL)
15913 (
void) XSetInputFocus(display,windows->image.id,RevertToParent,
15915 windows->popup.mapped=MagickFalse;
15918 if (event.xunmap.window == windows->widget.id)
15920 if (windows->backdrop.id != (Window) NULL)
15921 (void) XSetInputFocus(display,windows->image.id,RevertToParent,
15923 windows->widget.mapped=MagickFalse;
15930 if (resource_info->debug != MagickFalse)
15931 (void) LogMagickEvent(X11Event,GetMagickModule(),
"Event type: %d",
15936 }
while (!(*state & ExitState));
15937 if ((*state & ExitState) == 0)
15938 (
void) XMagickCommand(display,resource_info,windows,FreeBuffersCommand,
15941 if (resource_info->confirm_edit != MagickFalse)
15946 if ((resource_info->immutable == MagickFalse) &&
15947 (display_image->taint != MagickFalse))
15952 status=XConfirmWidget(display,windows,
"Your image changed.",
15953 "Do you want to save it");
15955 *state&=(~ExitState);
15958 (void) XMagickCommand(display,resource_info,windows,SaveCommand,
15962 if ((windows->visual_info->klass == GrayScale) ||
15963 (windows->visual_info->klass == PseudoColor) ||
15964 (windows->visual_info->klass == DirectColor))
15969 if (windows->info.mapped != MagickFalse)
15970 (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
15971 if (windows->magnify.mapped != MagickFalse)
15972 (void) XWithdrawWindow(display,windows->magnify.id,
15973 windows->magnify.screen);
15974 if (windows->command.mapped != MagickFalse)
15975 (void) XWithdrawWindow(display,windows->command.id,
15976 windows->command.screen);
15978 if (windows->pan.mapped != MagickFalse)
15979 (void) XWithdrawWindow(display,windows->pan.id,windows->pan.screen);
15980 if (resource_info->backdrop == MagickFalse)
15981 if (windows->backdrop.mapped)
15983 (void) XWithdrawWindow(display,windows->backdrop.id,
15984 windows->backdrop.screen);
15985 (void) XDestroyWindow(display,windows->backdrop.id);
15986 windows->backdrop.id=(Window) NULL;
15987 (void) XWithdrawWindow(display,windows->image.id,
15988 windows->image.screen);
15989 (void) XDestroyWindow(display,windows->image.id);
15990 windows->image.id=(Window) NULL;
15992 XSetCursorState(display,windows,MagickTrue);
15993 XCheckRefreshWindows(display,windows);
15994 if (((*state & FormerImageState) != 0) || ((*state & NextImageState) != 0))
15995 *state&=(~ExitState);
15996 if (*state & ExitState)
16001 (void) XFreeStandardColormap(display,icon_visual,icon_map,icon_pixel);
16002 if (resource_info->map_type == (
char *) NULL)
16003 (
void) XFreeStandardColormap(display,visual_info,map_info,pixel);
16007 if (resource_info->copy_image != (
Image *) NULL)
16008 resource_info->copy_image=DestroyImage(resource_info->copy_image);
16009 DestroyXResources();
16011 (void) XSync(display,MagickFalse);
16015 (void) SetErrorHandler(warning_handler);
16016 (void) SetWarningHandler(warning_handler);
16020 directory=getcwd(working_directory,MaxTextExtent);
16026 if (*resource_info->home_directory ==
'\0')
16027 (void) CopyMagickString(resource_info->home_directory,
".",MaxTextExtent);
16028 status=chdir(resource_info->home_directory);
16030 (void) ThrowMagickException(&display_image->exception,GetMagickModule(),
16031 FileOpenError,
"UnableToOpenFile",
"%s",resource_info->home_directory);
16033 *image=display_image;
16065MagickExport MagickBooleanType DisplayImages(
const ImageInfo *image_info,
16068 assert(image_info != (
const ImageInfo *) NULL);
16069 assert(image_info->signature == MagickCoreSignature);
16070 assert(image != (
Image *) NULL);
16071 assert(image->signature == MagickCoreSignature);
16072 if (IsEventLogging() != MagickFalse)
16073 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
16075 (void) ThrowMagickException(&image->exception,GetMagickModule(),
16076 MissingDelegateError,
"DelegateLibrarySupportNotBuiltIn",
"`%s' (X11)",
16078 return(MagickFalse);
16111MagickExport MagickBooleanType RemoteDisplayCommand(
const ImageInfo *image_info,
16112 const char *window,
const char *filename,
ExceptionInfo *exception)
16114 assert(image_info != (
const ImageInfo *) NULL);
16115 assert(image_info->signature == MagickCoreSignature);
16116 assert(filename != (
char *) NULL);
16117 if (IsEventLogging() != MagickFalse)
16118 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",filename);
16120 (void) ThrowMagickException(exception,GetMagickModule(),MissingDelegateError,
16121 "DelegateLibrarySupportNotBuiltIn",
"`%s' (X11)",image_info->filename);
16122 return(MagickFalse);