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
1536 XImageWindowCommand(Display *,XResourceInfo *,XWindows *,
1537 const MagickStatusType,KeySym,
Image **);
1540 *XMagickCommand(Display *,XResourceInfo *,XWindows *,
const CommandType,
1542 *XOpenImage(Display *,XResourceInfo *,XWindows *,
const MagickBooleanType),
1543 *XTileImage(Display *,XResourceInfo *,XWindows *,
Image *,XEvent *),
1544 *XVisualDirectoryImage(Display *,XResourceInfo *,XWindows *);
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 CommandType,
Image **),
1566 XMagnifyImage(Display *,XWindows *,XEvent *),
1567 XMakePanImage(Display *,XResourceInfo *,XWindows *,
Image *),
1568 XPanImage(Display *,XWindows *,XEvent *),
1569 XMagnifyWindowCommand(Display *,XWindows *,
const MagickStatusType,
1572 XScreenEvent(Display *,XWindows *,XEvent *),
1573 XTranslateImage(Display *,XWindows *,
Image *,
const KeySym);
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 CommandType 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 CommandType 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))
6654 if (((last_symbol < XK_0) || (last_symbol > XK_9)))
6657 resource_info->quantum=1;
6659 last_symbol=key_symbol;
6660 length=strlen(delta);
6661 if (length < MagickPathExtent)
6663 delta[length]=Digits[key_symbol-XK_0];
6664 delta[length+1]=
'\0';
6666 resource_info->quantum=StringToLong(delta);
6667 return(NullCommand);
6669 last_symbol=key_symbol;
6670 if (resource_info->immutable)
6678 return(InfoCommand);
6681 return(PrintCommand);
6683 return(NextCommand);
6686 return(QuitCommand);
6690 return(NullCommand);
6692 switch ((
int) key_symbol)
6696 if ((state & ControlMask) == 0)
6698 return(OpenCommand);
6701 return(NextCommand);
6703 return(FormerCommand);
6706 if ((state & Mod1Mask) != 0)
6707 return(SwirlCommand);
6708 if ((state & ControlMask) == 0)
6709 return(ShearCommand);
6710 return(SaveCommand);
6715 if ((state & Mod1Mask) != 0)
6716 return(OilPaintCommand);
6717 if ((state & Mod4Mask) != 0)
6718 return(ColorCommand);
6719 if ((state & ControlMask) == 0)
6720 return(NullCommand);
6721 return(PrintCommand);
6725 if ((state & Mod4Mask) != 0)
6726 return(DrawCommand);
6727 if ((state & ControlMask) == 0)
6728 return(NullCommand);
6729 return(DeleteCommand);
6733 if ((state & ControlMask) == 0)
6734 return(NullCommand);
6735 return(SelectCommand);
6739 if ((state & ControlMask) == 0)
6740 return(NullCommand);
6745 return(QuitCommand);
6749 if ((state & ControlMask) == 0)
6750 return(NullCommand);
6751 return(UndoCommand);
6756 if ((state & ControlMask) == 0)
6757 return(RollCommand);
6758 return(RedoCommand);
6762 if ((state & ControlMask) == 0)
6763 return(NullCommand);
6768 if ((state & Mod1Mask) != 0)
6769 return(CharcoalDrawCommand);
6770 if ((state & ControlMask) == 0)
6771 return(CropCommand);
6772 return(CopyCommand);
6777 if ((state & Mod4Mask) != 0)
6778 return(CompositeCommand);
6779 if ((state & ControlMask) == 0)
6780 return(FlipCommand);
6781 return(PasteCommand);
6784 return(HalfSizeCommand);
6786 return(OriginalSizeCommand);
6788 return(DoubleSizeCommand);
6790 return(ResizeCommand);
6792 return(RefreshCommand);
6793 case XK_bracketleft:
6794 return(ChopCommand);
6796 return(FlopCommand);
6798 return(RotateRightCommand);
6800 return(RotateLeftCommand);
6802 return(RotateCommand);
6804 return(TrimCommand);
6808 return(SaturationCommand);
6810 return(BrightnessCommand);
6812 return(GammaCommand);
6814 return(SpiffCommand);
6816 return(DullCommand);
6818 return(NormalizeCommand);
6820 return(EqualizeCommand);
6822 return(NegateCommand);
6824 return(GrayscaleCommand);
6826 return(QuantizeCommand);
6828 return(DespeckleCommand);
6830 return(EmbossCommand);
6832 return(ReduceNoiseCommand);
6834 return(AddNoiseCommand);
6836 return(SharpenCommand);
6838 return(BlurCommand);
6840 return(ThresholdCommand);
6842 return(EdgeDetectCommand);
6844 return(SpreadCommand);
6846 return(ShadeCommand);
6848 return(RaiseCommand);
6850 return(SegmentCommand);
6853 if ((state & Mod1Mask) == 0)
6854 return(NullCommand);
6855 return(ImplodeCommand);
6859 if ((state & Mod1Mask) == 0)
6860 return(NullCommand);
6861 return(WaveCommand);
6865 if ((state & Mod4Mask) == 0)
6866 return(NullCommand);
6867 return(MatteCommand);
6871 if ((state & Mod4Mask) == 0)
6872 return(NullCommand);
6873 return(AddBorderCommand);
6877 if ((state & Mod4Mask) == 0)
6878 return(NullCommand);
6879 return(AddFrameCommand);
6883 if ((state & Mod4Mask) == 0)
6884 return(NullCommand);
6885 return(CommentCommand);
6889 if ((state & Mod1Mask) != 0)
6890 return(ApplyCommand);
6891 if ((state & Mod4Mask) != 0)
6892 return(AnnotateCommand);
6893 if ((state & ControlMask) == 0)
6894 return(NullCommand);
6895 return(RegionOfInterestCommand);
6898 return(InfoCommand);
6900 return(ZoomCommand);
6903 if ((state & ShiftMask) == 0)
6904 return(NullCommand);
6905 return(ShowPreviewCommand);
6908 return(LaunchCommand);
6910 return(HelpCommand);
6912 return(BrowseDocumentationCommand);
6915 (void) XMapRaised(display,windows->command.id);
6916 return(NullCommand);
6923 XTranslateImage(display,windows,*image,key_symbol);
6924 return(NullCommand);
6935 if ((state & Mod1Mask) != 0)
6945 crop_info.width=(size_t) windows->image.ximage->width;
6946 crop_info.height=(size_t) windows->image.ximage->height;
6947 if ((key_symbol == XK_Up) || (key_symbol == XK_KP_Up))
6949 if (resource_info->quantum >= (
int) crop_info.height)
6950 resource_info->quantum=(int) crop_info.height-1;
6951 crop_info.height-=resource_info->quantum;
6953 if ((key_symbol == XK_Down) || (key_symbol == XK_KP_Down))
6955 if (resource_info->quantum >= (
int) (crop_info.height-crop_info.y))
6956 resource_info->quantum=(int) (crop_info.height-crop_info.y-1);
6957 crop_info.y+=resource_info->quantum;
6958 crop_info.height-=resource_info->quantum;
6960 if ((key_symbol == XK_Left) || (key_symbol == XK_KP_Left))
6962 if (resource_info->quantum >= (
int) crop_info.width)
6963 resource_info->quantum=(
int) crop_info.width-1;
6964 crop_info.width-=resource_info->quantum;
6966 if ((key_symbol == XK_Right) || (key_symbol == XK_KP_Right))
6968 if (resource_info->quantum >= (
int) (crop_info.width-crop_info.x))
6969 resource_info->quantum=(int) (crop_info.width-crop_info.x-1);
6970 crop_info.x+=resource_info->quantum;
6971 crop_info.width-=resource_info->quantum;
6973 if ((
int) (windows->image.x+windows->image.width) >
6974 (
int) crop_info.width)
6975 windows->image.x=(
int) (crop_info.width-windows->image.width);
6976 if ((
int) (windows->image.y+windows->image.height) >
6977 (
int) crop_info.height)
6978 windows->image.y=(
int) (crop_info.height-windows->image.height);
6979 XSetCropGeometry(display,windows,&crop_info,*image);
6980 windows->image.window_changes.width=(int) crop_info.width;
6981 windows->image.window_changes.height=(int) crop_info.height;
6982 (void) XSetWindowBackgroundPixmap(display,windows->image.id,None);
6983 (void) XConfigureImage(display,resource_info,windows,*image);
6984 return(NullCommand);
6986 XTranslateImage(display,windows,*image,key_symbol);
6987 return(NullCommand);
6990 return(NullCommand);
6992 return(NullCommand);
7033static Image *XMagickCommand(Display *display,XResourceInfo *resource_info,
7034 XWindows *windows,
const CommandType command,
Image **image)
7037 filename[MaxTextExtent],
7038 geometry[MaxTextExtent],
7039 modulate_factors[MaxTextExtent];
7068 color[MaxTextExtent] =
"gray";
7077 XCheckRefreshWindows(display,windows);
7078 XImageCache(display,resource_info,windows,command,image);
7079 nexus=NewImageList();
7080 windows->image.window_changes.width=windows->image.ximage->width;
7081 windows->image.window_changes.height=windows->image.ximage->height;
7082 image_info=CloneImageInfo(resource_info->image_info);
7083 SetGeometryInfo(&geometry_info);
7084 GetQuantizeInfo(&quantize_info);
7092 nexus=XOpenImage(display,resource_info,windows,MagickFalse);
7100 for (i=0; i < resource_info->quantum; i++)
7101 XClientMessage(display,windows->image.id,windows->im_protocols,
7102 windows->im_next_image,CurrentTime);
7110 for (i=0; i < resource_info->quantum; i++)
7111 XClientMessage(display,windows->image.id,windows->im_protocols,
7112 windows->im_former_image,CurrentTime);
7123 if (*resource_info->home_directory ==
'\0')
7124 (void) CopyMagickString(resource_info->home_directory,
".",
7126 status=chdir(resource_info->home_directory);
7128 (void) ThrowMagickException(&(*image)->exception,GetMagickModule(),
7129 FileOpenError,
"UnableToOpenFile",
"%s",resource_info->home_directory);
7130 nexus=XOpenImage(display,resource_info,windows,MagickTrue);
7138 status=XSaveImage(display,resource_info,windows,*image);
7139 if (status == MagickFalse)
7142 message[MaxTextExtent];
7144 (void) FormatLocaleString(message,MaxTextExtent,
"%s:%s",
7145 (*image)->exception.reason != (
char *) NULL ?
7146 (*image)->exception.reason :
"",
7147 (*image)->exception.description != (
char *) NULL ?
7148 (*image)->exception.description :
"");
7149 XNoticeWidget(display,windows,
"Unable to save file:",message);
7159 status=XPrintImage(display,resource_info,windows,*image);
7160 if (status == MagickFalse)
7163 message[MaxTextExtent];
7165 (void) FormatLocaleString(message,MaxTextExtent,
"%s:%s",
7166 (*image)->exception.reason != (
char *) NULL ?
7167 (*image)->exception.reason :
"",
7168 (*image)->exception.description != (
char *) NULL ?
7169 (*image)->exception.description :
"");
7170 XNoticeWidget(display,windows,
"Unable to print file:",message);
7178 filename[MaxTextExtent] =
"\0";
7183 XFileBrowserWidget(display,windows,
"Delete",filename);
7184 if (*filename ==
'\0')
7186 status=ShredFile(filename);
7187 status|=remove_utf8(filename);
7188 if (status != MagickFalse)
7189 XNoticeWidget(display,windows,
"Unable to delete image file:",filename);
7198 color[MaxTextExtent] =
"gray",
7199 geometry[MaxTextExtent] =
"640x480";
7202 *format =
"gradient";
7207 status=XDialogWidget(display,windows,
"New",
"Enter image geometry:",
7209 if (*geometry ==
'\0')
7213 XColorBrowserWidget(display,windows,
"Select",color);
7219 (void) FormatLocaleString(image_info->filename,MaxTextExtent,
7220 "%s:%s",format,color);
7221 (void) CloneString(&image_info->size,geometry);
7222 nexus=ReadImage(image_info,&(*image)->exception);
7223 CatchException(&(*image)->exception);
7224 XClientMessage(display,windows->image.id,windows->im_protocols,
7225 windows->im_next_image,CurrentTime);
7228 case VisualDirectoryCommand:
7233 nexus=XVisualDirectoryImage(display,resource_info,windows);
7241 if (resource_info->confirm_exit == MagickFalse)
7242 XClientMessage(display,windows->image.id,windows->im_protocols,
7243 windows->im_exit,CurrentTime);
7252 status=XConfirmWidget(display,windows,
"Do you really want to exit",
7253 resource_info->client_name);
7255 XClientMessage(display,windows->image.id,windows->im_protocols,
7256 windows->im_exit,CurrentTime);
7265 (void) XCropImage(display,resource_info,windows,*image,CutMode);
7273 (void) XCropImage(display,resource_info,windows,*image,CopyMode);
7281 status=XPasteImage(display,resource_info,windows,*image);
7282 if (status == MagickFalse)
7284 XNoticeWidget(display,windows,
"Unable to paste X image",
7285 (*image)->filename);
7290 case HalfSizeCommand:
7295 windows->image.window_changes.width=windows->image.ximage->width/2;
7296 windows->image.window_changes.height=windows->image.ximage->height/2;
7297 (void) XConfigureImage(display,resource_info,windows,*image);
7300 case OriginalSizeCommand:
7305 windows->image.window_changes.width=(int) (*image)->columns;
7306 windows->image.window_changes.height=(int) (*image)->rows;
7307 (void) XConfigureImage(display,resource_info,windows,*image);
7310 case DoubleSizeCommand:
7315 windows->image.window_changes.width=windows->image.ximage->width << 1;
7316 windows->image.window_changes.height=windows->image.ximage->height << 1;
7317 (void) XConfigureImage(display,resource_info,windows,*image);
7336 width=(size_t) windows->image.ximage->width;
7337 height=(size_t) windows->image.ximage->height;
7340 (void) FormatLocaleString(geometry,MaxTextExtent,
"%.20gx%.20g+0+0",
7341 (
double) width,(double) height);
7342 status=XDialogWidget(display,windows,
"Resize",
7343 "Enter resize geometry (e.g. 640x480, 200%):",geometry);
7344 if (*geometry ==
'\0')
7347 (void) ConcatenateMagickString(geometry,
"!",MaxTextExtent);
7348 (void) ParseMetaGeometry(geometry,&x,&y,&width,&height);
7349 windows->image.window_changes.width=(int) width;
7350 windows->image.window_changes.height=(int) height;
7351 (void) XConfigureImage(display,resource_info,windows,*image);
7357 image_geometry[MaxTextExtent];
7359 if ((windows->image.crop_geometry == (
char *) NULL) &&
7360 ((
int) (*image)->columns == windows->image.ximage->width) &&
7361 ((
int) (*image)->rows == windows->image.ximage->height))
7366 XSetCursorState(display,windows,MagickTrue);
7367 XCheckRefreshWindows(display,windows);
7371 (void) FormatLocaleString(image_geometry,MaxTextExtent,
"%dx%d!",
7372 windows->image.ximage->width,windows->image.ximage->height);
7373 (void) TransformImage(image,windows->image.crop_geometry,image_geometry);
7374 if (windows->image.crop_geometry != (
char *) NULL)
7375 windows->image.crop_geometry=(
char *)
7376 RelinquishMagickMemory(windows->image.crop_geometry);
7379 XConfigureImageColormap(display,resource_info,windows,*image);
7380 (void) XConfigureImage(display,resource_info,windows,*image);
7383 case RefreshCommand:
7385 (void) XConfigureImage(display,resource_info,windows,*image);
7388 case RestoreCommand:
7393 if ((windows->image.width == (
unsigned int) (*image)->columns) &&
7394 (windows->image.height == (
unsigned int) (*image)->rows) &&
7395 (windows->image.crop_geometry == (
char *) NULL))
7397 (void) XBell(display,0);
7400 windows->image.window_changes.width=(int) (*image)->columns;
7401 windows->image.window_changes.height=(int) (*image)->rows;
7402 if (windows->image.crop_geometry != (
char *) NULL)
7404 windows->image.crop_geometry=(
char *)
7405 RelinquishMagickMemory(windows->image.crop_geometry);
7406 windows->image.crop_geometry=(
char *) NULL;
7410 XConfigureImageColormap(display,resource_info,windows,*image);
7411 (void) XConfigureImage(display,resource_info,windows,*image);
7419 (void) XCropImage(display,resource_info,windows,*image,CropMode);
7427 status=XChopImage(display,resource_info,windows,image);
7428 if (status == MagickFalse)
7430 XNoticeWidget(display,windows,
"Unable to cut X image",
7431 (*image)->filename);
7444 XSetCursorState(display,windows,MagickTrue);
7445 XCheckRefreshWindows(display,windows);
7446 flop_image=FlopImage(*image,&(*image)->exception);
7447 if (flop_image != (
Image *) NULL)
7449 *image=DestroyImage(*image);
7452 CatchException(&(*image)->exception);
7453 XSetCursorState(display,windows,MagickFalse);
7454 if (windows->image.crop_geometry != (
char *) NULL)
7459 width=(
unsigned int) (*image)->columns;
7460 height=(
unsigned int) (*image)->rows;
7461 (void) XParseGeometry(windows->image.crop_geometry,&x,&y,
7463 (void) FormatLocaleString(windows->image.crop_geometry,MaxTextExtent,
7464 "%ux%u%+d%+d",width,height,(
int) (*image)->columns-(int) width-x,y);
7466 if (windows->image.orphan != MagickFalse)
7468 (void) XConfigureImage(display,resource_info,windows,*image);
7479 XSetCursorState(display,windows,MagickTrue);
7480 XCheckRefreshWindows(display,windows);
7481 flip_image=FlipImage(*image,&(*image)->exception);
7482 if (flip_image != (
Image *) NULL)
7484 *image=DestroyImage(*image);
7487 CatchException(&(*image)->exception);
7488 XSetCursorState(display,windows,MagickFalse);
7489 if (windows->image.crop_geometry != (
char *) NULL)
7494 width=(
unsigned int) (*image)->columns;
7495 height=(
unsigned int) (*image)->rows;
7496 (void) XParseGeometry(windows->image.crop_geometry,&x,&y,
7498 (void) FormatLocaleString(windows->image.crop_geometry,MaxTextExtent,
7499 "%ux%u%+d%+d",width,height,x,(
int) (*image)->rows-(int) height-y);
7501 if (windows->image.orphan != MagickFalse)
7503 (void) XConfigureImage(display,resource_info,windows,*image);
7506 case RotateRightCommand:
7511 status=XRotateImage(display,resource_info,windows,90.0,image);
7512 if (status == MagickFalse)
7514 XNoticeWidget(display,windows,
"Unable to rotate X image",
7515 (*image)->filename);
7520 case RotateLeftCommand:
7525 status=XRotateImage(display,resource_info,windows,-90.0,image);
7526 if (status == MagickFalse)
7528 XNoticeWidget(display,windows,
"Unable to rotate X image",
7529 (*image)->filename);
7539 status=XRotateImage(display,resource_info,windows,0.0,image);
7540 if (status == MagickFalse)
7542 XNoticeWidget(display,windows,
"Unable to rotate X image",
7543 (*image)->filename);
7554 geometry[MaxTextExtent] =
"45.0x45.0";
7559 XColorBrowserWidget(display,windows,
"Select",color);
7562 (void) XDialogWidget(display,windows,
"Shear",
"Enter shear geometry:",
7564 if (*geometry ==
'\0')
7569 (void) XMagickCommand(display,resource_info,windows,ApplyCommand,image);
7570 XSetCursorState(display,windows,MagickTrue);
7571 XCheckRefreshWindows(display,windows);
7572 (void) QueryColorDatabase(color,&(*image)->background_color,
7573 &(*image)->exception);
7574 flags=ParseGeometry(geometry,&geometry_info);
7575 if ((flags & SigmaValue) == 0)
7576 geometry_info.sigma=geometry_info.rho;
7577 shear_image=ShearImage(*image,geometry_info.rho,geometry_info.sigma,
7578 &(*image)->exception);
7579 if (shear_image != (
Image *) NULL)
7581 *image=DestroyImage(*image);
7584 CatchException(&(*image)->exception);
7585 XSetCursorState(display,windows,MagickFalse);
7586 if (windows->image.orphan != MagickFalse)
7588 windows->image.window_changes.width=(int) (*image)->columns;
7589 windows->image.window_changes.height=(int) (*image)->rows;
7590 XConfigureImageColormap(display,resource_info,windows,*image);
7591 (void) XConfigureImage(display,resource_info,windows,*image);
7600 geometry[MaxTextExtent] =
"+2+2";
7605 (void) XDialogWidget(display,windows,
"Roll",
"Enter roll geometry:",
7607 if (*geometry ==
'\0')
7612 (void) XMagickCommand(display,resource_info,windows,ApplyCommand,image);
7613 XSetCursorState(display,windows,MagickTrue);
7614 XCheckRefreshWindows(display,windows);
7615 (void) ParsePageGeometry(*image,geometry,&page_geometry,
7616 &(*image)->exception);
7617 roll_image=RollImage(*image,page_geometry.x,page_geometry.y,
7618 &(*image)->exception);
7619 if (roll_image != (
Image *) NULL)
7621 *image=DestroyImage(*image);
7624 CatchException(&(*image)->exception);
7625 XSetCursorState(display,windows,MagickFalse);
7626 if (windows->image.orphan != MagickFalse)
7628 windows->image.window_changes.width=(int) (*image)->columns;
7629 windows->image.window_changes.height=(int) (*image)->rows;
7630 XConfigureImageColormap(display,resource_info,windows,*image);
7631 (void) XConfigureImage(display,resource_info,windows,*image);
7637 fuzz[MaxTextExtent];
7642 (void) FormatLocaleString(fuzz,MaxTextExtent,
"%g%%",100.0*
7643 (*image)->fuzz/((
double) QuantumRange+1.0));
7644 (void) XDialogWidget(display,windows,
"Trim",
"Enter fuzz factor:",fuzz);
7647 (*image)->fuzz=StringToDoubleInterval(fuzz,(
double) QuantumRange+1.0);
7651 status=XTrimImage(display,resource_info,windows,*image);
7652 if (status == MagickFalse)
7654 XNoticeWidget(display,windows,
"Unable to trim X image",
7655 (*image)->filename);
7663 hue_percent[MaxTextExtent] =
"110";
7668 (void) XDialogWidget(display,windows,
"Apply",
7669 "Enter percent change in image hue (0-200):",hue_percent);
7670 if (*hue_percent ==
'\0')
7675 XSetCursorState(display,windows,MagickTrue);
7676 XCheckRefreshWindows(display,windows);
7677 (void) CopyMagickString(modulate_factors,
"100.0/100.0/",MaxTextExtent);
7678 (void) ConcatenateMagickString(modulate_factors,hue_percent,
7680 (void) ModulateImage(*image,modulate_factors);
7681 XSetCursorState(display,windows,MagickFalse);
7682 if (windows->image.orphan != MagickFalse)
7684 XConfigureImageColormap(display,resource_info,windows,*image);
7685 (void) XConfigureImage(display,resource_info,windows,*image);
7688 case SaturationCommand:
7691 saturation_percent[MaxTextExtent] =
"110";
7696 (void) XDialogWidget(display,windows,
"Apply",
7697 "Enter percent change in color saturation (0-200):",saturation_percent);
7698 if (*saturation_percent ==
'\0')
7703 XSetCursorState(display,windows,MagickTrue);
7704 XCheckRefreshWindows(display,windows);
7705 (void) CopyMagickString(modulate_factors,
"100.0/",MaxTextExtent);
7706 (void) ConcatenateMagickString(modulate_factors,saturation_percent,
7708 (void) ModulateImage(*image,modulate_factors);
7709 XSetCursorState(display,windows,MagickFalse);
7710 if (windows->image.orphan != MagickFalse)
7712 XConfigureImageColormap(display,resource_info,windows,*image);
7713 (void) XConfigureImage(display,resource_info,windows,*image);
7716 case BrightnessCommand:
7719 brightness_percent[MaxTextExtent] =
"110";
7724 (void) XDialogWidget(display,windows,
"Apply",
7725 "Enter percent change in color brightness (0-200):",brightness_percent);
7726 if (*brightness_percent ==
'\0')
7731 XSetCursorState(display,windows,MagickTrue);
7732 XCheckRefreshWindows(display,windows);
7733 (void) CopyMagickString(modulate_factors,brightness_percent,
7735 (void) ModulateImage(*image,modulate_factors);
7736 XSetCursorState(display,windows,MagickFalse);
7737 if (windows->image.orphan != MagickFalse)
7739 XConfigureImageColormap(display,resource_info,windows,*image);
7740 (void) XConfigureImage(display,resource_info,windows,*image);
7746 factor[MaxTextExtent] =
"1.6";
7751 (void) XDialogWidget(display,windows,
"Gamma",
7752 "Enter gamma value (e.g. 1.0,1.0,1.6):",factor);
7753 if (*factor ==
'\0')
7758 XSetCursorState(display,windows,MagickTrue);
7759 XCheckRefreshWindows(display,windows);
7760 (void) GammaImage(*image,factor);
7761 XSetCursorState(display,windows,MagickFalse);
7762 if (windows->image.orphan != MagickFalse)
7764 XConfigureImageColormap(display,resource_info,windows,*image);
7765 (void) XConfigureImage(display,resource_info,windows,*image);
7773 XSetCursorState(display,windows,MagickTrue);
7774 XCheckRefreshWindows(display,windows);
7775 (void) ContrastImage(*image,MagickTrue);
7776 XSetCursorState(display,windows,MagickFalse);
7777 if (windows->image.orphan != MagickFalse)
7779 XConfigureImageColormap(display,resource_info,windows,*image);
7780 (void) XConfigureImage(display,resource_info,windows,*image);
7788 XSetCursorState(display,windows,MagickTrue);
7789 XCheckRefreshWindows(display,windows);
7790 (void) ContrastImage(*image,MagickFalse);
7791 XSetCursorState(display,windows,MagickFalse);
7792 if (windows->image.orphan != MagickFalse)
7794 XConfigureImageColormap(display,resource_info,windows,*image);
7795 (void) XConfigureImage(display,resource_info,windows,*image);
7798 case ContrastStretchCommand:
7805 levels[MaxTextExtent] =
"1%";
7810 (void) XDialogWidget(display,windows,
"Contrast Stretch",
7811 "Enter black and white points:",levels);
7812 if (*levels ==
'\0')
7817 XSetCursorState(display,windows,MagickTrue);
7818 XCheckRefreshWindows(display,windows);
7819 flags=ParseGeometry(levels,&geometry_info);
7820 black_point=geometry_info.rho;
7821 white_point=(flags & SigmaValue) != 0 ? geometry_info.sigma : black_point;
7822 if ((flags & PercentValue) != 0)
7824 black_point*=(double) (*image)->columns*(*image)->rows/100.0;
7825 white_point*=(double) (*image)->columns*(*image)->rows/100.0;
7827 white_point=(MagickRealType) (*image)->columns*(*image)->rows-white_point;
7828 (void) ContrastStretchImageChannel(*image,DefaultChannels,black_point,
7830 XSetCursorState(display,windows,MagickFalse);
7831 if (windows->image.orphan != MagickFalse)
7833 XConfigureImageColormap(display,resource_info,windows,*image);
7834 (void) XConfigureImage(display,resource_info,windows,*image);
7837 case SigmoidalContrastCommand:
7840 levels[MaxTextExtent] =
"3x50%";
7845 (void) XDialogWidget(display,windows,
"Sigmoidal Contrast",
7846 "Enter contrast and midpoint:",levels);
7847 if (*levels ==
'\0')
7852 XSetCursorState(display,windows,MagickTrue);
7853 XCheckRefreshWindows(display,windows);
7854 (void) SigmoidalContrastImage(*image,MagickTrue,levels);
7855 XSetCursorState(display,windows,MagickFalse);
7856 if (windows->image.orphan != MagickFalse)
7858 XConfigureImageColormap(display,resource_info,windows,*image);
7859 (void) XConfigureImage(display,resource_info,windows,*image);
7862 case NormalizeCommand:
7867 XSetCursorState(display,windows,MagickTrue);
7868 XCheckRefreshWindows(display,windows);
7869 (void) NormalizeImage(*image);
7870 XSetCursorState(display,windows,MagickFalse);
7871 if (windows->image.orphan != MagickFalse)
7873 XConfigureImageColormap(display,resource_info,windows,*image);
7874 (void) XConfigureImage(display,resource_info,windows,*image);
7877 case EqualizeCommand:
7882 XSetCursorState(display,windows,MagickTrue);
7883 XCheckRefreshWindows(display,windows);
7884 (void) EqualizeImage(*image);
7885 XSetCursorState(display,windows,MagickFalse);
7886 if (windows->image.orphan != MagickFalse)
7888 XConfigureImageColormap(display,resource_info,windows,*image);
7889 (void) XConfigureImage(display,resource_info,windows,*image);
7897 XSetCursorState(display,windows,MagickTrue);
7898 XCheckRefreshWindows(display,windows);
7899 (void) NegateImage(*image,MagickFalse);
7900 XSetCursorState(display,windows,MagickFalse);
7901 if (windows->image.orphan != MagickFalse)
7903 XConfigureImageColormap(display,resource_info,windows,*image);
7904 (void) XConfigureImage(display,resource_info,windows,*image);
7907 case GrayscaleCommand:
7912 XSetCursorState(display,windows,MagickTrue);
7913 XCheckRefreshWindows(display,windows);
7914 (void) SetImageType(*image,(*image)->matte == MagickFalse ?
7915 GrayscaleType : GrayscaleMatteType);
7916 XSetCursorState(display,windows,MagickFalse);
7917 if (windows->image.orphan != MagickFalse)
7919 XConfigureImageColormap(display,resource_info,windows,*image);
7920 (void) XConfigureImage(display,resource_info,windows,*image);
7929 filename[MaxTextExtent] =
"\0";
7934 XFileBrowserWidget(display,windows,
"Map",filename);
7935 if (*filename ==
'\0')
7940 XSetCursorState(display,windows,MagickTrue);
7941 XCheckRefreshWindows(display,windows);
7942 (void) CopyMagickString(image_info->filename,filename,MaxTextExtent);
7943 affinity_image=ReadImage(image_info,&(*image)->exception);
7944 if (affinity_image != (
Image *) NULL)
7946 (void) RemapImage(&quantize_info,*image,affinity_image);
7947 affinity_image=DestroyImage(affinity_image);
7949 CatchException(&(*image)->exception);
7950 XSetCursorState(display,windows,MagickFalse);
7951 if (windows->image.orphan != MagickFalse)
7953 XConfigureImageColormap(display,resource_info,windows,*image);
7954 (void) XConfigureImage(display,resource_info,windows,*image);
7957 case QuantizeCommand:
7963 colors[MaxTextExtent] =
"256";
7968 status=XDialogWidget(display,windows,
"Quantize",
7969 "Maximum number of colors:",colors);
7970 if (*colors ==
'\0')
7975 XSetCursorState(display,windows,MagickTrue);
7976 XCheckRefreshWindows(display,windows);
7977 quantize_info.number_colors=StringToUnsignedLong(colors);
7978 quantize_info.dither=status != 0 ? MagickTrue : MagickFalse;
7979 (void) QuantizeImage(&quantize_info,*image);
7980 XSetCursorState(display,windows,MagickFalse);
7981 if (windows->image.orphan != MagickFalse)
7983 XConfigureImageColormap(display,resource_info,windows,*image);
7984 (void) XConfigureImage(display,resource_info,windows,*image);
7987 case DespeckleCommand:
7995 XSetCursorState(display,windows,MagickTrue);
7996 XCheckRefreshWindows(display,windows);
7997 despeckle_image=DespeckleImage(*image,&(*image)->exception);
7998 if (despeckle_image != (
Image *) NULL)
8000 *image=DestroyImage(*image);
8001 *image=despeckle_image;
8003 CatchException(&(*image)->exception);
8004 XSetCursorState(display,windows,MagickFalse);
8005 if (windows->image.orphan != MagickFalse)
8007 XConfigureImageColormap(display,resource_info,windows,*image);
8008 (void) XConfigureImage(display,resource_info,windows,*image);
8017 radius[MaxTextExtent] =
"0.0x1.0";
8022 (void) XDialogWidget(display,windows,
"Emboss",
8023 "Enter the emboss radius and standard deviation:",radius);
8024 if (*radius ==
'\0')
8029 XSetCursorState(display,windows,MagickTrue);
8030 XCheckRefreshWindows(display,windows);
8031 flags=ParseGeometry(radius,&geometry_info);
8032 if ((flags & SigmaValue) == 0)
8033 geometry_info.sigma=1.0;
8034 emboss_image=EmbossImage(*image,geometry_info.rho,geometry_info.sigma,
8035 &(*image)->exception);
8036 if (emboss_image != (
Image *) NULL)
8038 *image=DestroyImage(*image);
8039 *image=emboss_image;
8041 CatchException(&(*image)->exception);
8042 XSetCursorState(display,windows,MagickFalse);
8043 if (windows->image.orphan != MagickFalse)
8045 XConfigureImageColormap(display,resource_info,windows,*image);
8046 (void) XConfigureImage(display,resource_info,windows,*image);
8049 case ReduceNoiseCommand:
8055 radius[MaxTextExtent] =
"0";
8060 (void) XDialogWidget(display,windows,
"Reduce Noise",
8061 "Enter the noise radius:",radius);
8062 if (*radius ==
'\0')
8067 XSetCursorState(display,windows,MagickTrue);
8068 XCheckRefreshWindows(display,windows);
8069 flags=ParseGeometry(radius,&geometry_info);
8070 noise_image=StatisticImage(*image,NonpeakStatistic,(
size_t)
8071 geometry_info.rho,(
size_t) geometry_info.rho,&(*image)->exception);
8072 if (noise_image != (
Image *) NULL)
8074 *image=DestroyImage(*image);
8077 CatchException(&(*image)->exception);
8078 XSetCursorState(display,windows,MagickFalse);
8079 if (windows->image.orphan != MagickFalse)
8081 XConfigureImageColormap(display,resource_info,windows,*image);
8082 (void) XConfigureImage(display,resource_info,windows,*image);
8085 case AddNoiseCommand:
8094 noise_type[MaxTextExtent] =
"Gaussian";
8099 noises=GetCommandOptions(MagickNoiseOptions);
8100 if (noises == (
char **) NULL)
8102 XListBrowserWidget(display,windows,&windows->widget,
8103 (
const char **) noises,
"Add Noise",
8104 "Select a type of noise to add to your image:",noise_type);
8105 noises=DestroyStringList(noises);
8106 if (*noise_type ==
'\0')
8108 XSetCursorState(display,windows,MagickTrue);
8109 XCheckRefreshWindows(display,windows);
8110 noise_image=AddNoiseImage(*image,(NoiseType) ParseCommandOption(
8111 MagickNoiseOptions,MagickFalse,noise_type),&(*image)->exception);
8112 if (noise_image != (
Image *) NULL)
8114 *image=DestroyImage(*image);
8117 CatchException(&(*image)->exception);
8118 XSetCursorState(display,windows,MagickFalse);
8119 if (windows->image.orphan != MagickFalse)
8121 XConfigureImageColormap(display,resource_info,windows,*image);
8122 (void) XConfigureImage(display,resource_info,windows,*image);
8125 case SharpenCommand:
8131 radius[MaxTextExtent] =
"0.0x1.0";
8136 (void) XDialogWidget(display,windows,
"Sharpen",
8137 "Enter the sharpen radius and standard deviation:",radius);
8138 if (*radius ==
'\0')
8143 XSetCursorState(display,windows,MagickTrue);
8144 XCheckRefreshWindows(display,windows);
8145 flags=ParseGeometry(radius,&geometry_info);
8146 sharp_image=SharpenImage(*image,geometry_info.rho,geometry_info.sigma,
8147 &(*image)->exception);
8148 if (sharp_image != (
Image *) NULL)
8150 *image=DestroyImage(*image);
8153 CatchException(&(*image)->exception);
8154 XSetCursorState(display,windows,MagickFalse);
8155 if (windows->image.orphan != MagickFalse)
8157 XConfigureImageColormap(display,resource_info,windows,*image);
8158 (void) XConfigureImage(display,resource_info,windows,*image);
8167 radius[MaxTextExtent] =
"0.0x1.0";
8172 (void) XDialogWidget(display,windows,
"Blur",
8173 "Enter the blur radius and standard deviation:",radius);
8174 if (*radius ==
'\0')
8179 XSetCursorState(display,windows,MagickTrue);
8180 XCheckRefreshWindows(display,windows);
8181 flags=ParseGeometry(radius,&geometry_info);
8182 blur_image=BlurImage(*image,geometry_info.rho,geometry_info.sigma,
8183 &(*image)->exception);
8184 if (blur_image != (
Image *) NULL)
8186 *image=DestroyImage(*image);
8189 CatchException(&(*image)->exception);
8190 XSetCursorState(display,windows,MagickFalse);
8191 if (windows->image.orphan != MagickFalse)
8193 XConfigureImageColormap(display,resource_info,windows,*image);
8194 (void) XConfigureImage(display,resource_info,windows,*image);
8197 case ThresholdCommand:
8203 factor[MaxTextExtent] =
"128";
8208 (void) XDialogWidget(display,windows,
"Threshold",
8209 "Enter threshold value:",factor);
8210 if (*factor ==
'\0')
8215 XSetCursorState(display,windows,MagickTrue);
8216 XCheckRefreshWindows(display,windows);
8217 threshold=StringToDoubleInterval(factor,(
double) QuantumRange+1.0);
8218 (void) BilevelImage(*image,threshold);
8219 XSetCursorState(display,windows,MagickFalse);
8220 if (windows->image.orphan != MagickFalse)
8222 XConfigureImageColormap(display,resource_info,windows,*image);
8223 (void) XConfigureImage(display,resource_info,windows,*image);
8226 case EdgeDetectCommand:
8232 radius[MaxTextExtent] =
"0";
8237 (void) XDialogWidget(display,windows,
"Detect Edges",
8238 "Enter the edge detect radius:",radius);
8239 if (*radius ==
'\0')
8244 XSetCursorState(display,windows,MagickTrue);
8245 XCheckRefreshWindows(display,windows);
8246 flags=ParseGeometry(radius,&geometry_info);
8247 edge_image=EdgeImage(*image,geometry_info.rho,&(*image)->exception);
8248 if (edge_image != (
Image *) NULL)
8250 *image=DestroyImage(*image);
8253 CatchException(&(*image)->exception);
8254 XSetCursorState(display,windows,MagickFalse);
8255 if (windows->image.orphan != MagickFalse)
8257 XConfigureImageColormap(display,resource_info,windows,*image);
8258 (void) XConfigureImage(display,resource_info,windows,*image);
8267 amount[MaxTextExtent] =
"2";
8272 (void) XDialogWidget(display,windows,
"Spread",
8273 "Enter the displacement amount:",amount);
8274 if (*amount ==
'\0')
8279 XSetCursorState(display,windows,MagickTrue);
8280 XCheckRefreshWindows(display,windows);
8281 flags=ParseGeometry(amount,&geometry_info);
8282 spread_image=EdgeImage(*image,geometry_info.rho,&(*image)->exception);
8283 if (spread_image != (
Image *) NULL)
8285 *image=DestroyImage(*image);
8286 *image=spread_image;
8288 CatchException(&(*image)->exception);
8289 XSetCursorState(display,windows,MagickFalse);
8290 if (windows->image.orphan != MagickFalse)
8292 XConfigureImageColormap(display,resource_info,windows,*image);
8293 (void) XConfigureImage(display,resource_info,windows,*image);
8305 geometry[MaxTextExtent] =
"30x30";
8310 status=XDialogWidget(display,windows,
"Shade",
8311 "Enter the azimuth and elevation of the light source:",geometry);
8312 if (*geometry ==
'\0')
8317 XSetCursorState(display,windows,MagickTrue);
8318 XCheckRefreshWindows(display,windows);
8319 flags=ParseGeometry(geometry,&geometry_info);
8320 if ((flags & SigmaValue) == 0)
8321 geometry_info.sigma=1.0;
8322 shade_image=ShadeImage(*image,status != 0 ? MagickFalse : MagickTrue,
8323 geometry_info.rho,geometry_info.sigma,&(*image)->exception);
8324 if (shade_image != (
Image *) NULL)
8326 *image=DestroyImage(*image);
8329 CatchException(&(*image)->exception);
8330 XSetCursorState(display,windows,MagickFalse);
8331 if (windows->image.orphan != MagickFalse)
8333 XConfigureImageColormap(display,resource_info,windows,*image);
8334 (void) XConfigureImage(display,resource_info,windows,*image);
8340 bevel_width[MaxTextExtent] =
"10";
8345 (void) XDialogWidget(display,windows,
"Raise",
"Bevel width:",bevel_width);
8346 if (*bevel_width ==
'\0')
8351 (void) XMagickCommand(display,resource_info,windows,ApplyCommand,image);
8352 XSetCursorState(display,windows,MagickTrue);
8353 XCheckRefreshWindows(display,windows);
8354 (void) ParsePageGeometry(*image,bevel_width,&page_geometry,
8355 &(*image)->exception);
8356 (void) RaiseImage(*image,&page_geometry,MagickTrue);
8357 XSetCursorState(display,windows,MagickFalse);
8358 if (windows->image.orphan != MagickFalse)
8360 XConfigureImageColormap(display,resource_info,windows,*image);
8361 (void) XConfigureImage(display,resource_info,windows,*image);
8364 case SegmentCommand:
8367 threshold[MaxTextExtent] =
"1.0x1.5";
8372 (void) XDialogWidget(display,windows,
"Segment",
"Smooth threshold:",
8374 if (*threshold ==
'\0')
8379 XSetCursorState(display,windows,MagickTrue);
8380 XCheckRefreshWindows(display,windows);
8381 flags=ParseGeometry(threshold,&geometry_info);
8382 if ((flags & SigmaValue) == 0)
8383 geometry_info.sigma=1.0;
8384 (void) SegmentImage(*image,sRGBColorspace,MagickFalse,geometry_info.rho,
8385 geometry_info.sigma);
8386 XSetCursorState(display,windows,MagickFalse);
8387 if (windows->image.orphan != MagickFalse)
8389 XConfigureImageColormap(display,resource_info,windows,*image);
8390 (void) XConfigureImage(display,resource_info,windows,*image);
8393 case SepiaToneCommand:
8402 factor[MaxTextExtent] =
"80%";
8407 (void) XDialogWidget(display,windows,
"Sepia Tone",
8408 "Enter the sepia tone factor (0 - 99.9%):",factor);
8409 if (*factor ==
'\0')
8414 XSetCursorState(display,windows,MagickTrue);
8415 XCheckRefreshWindows(display,windows);
8416 threshold=StringToDoubleInterval(factor,(
double) QuantumRange+1.0);
8417 sepia_image=SepiaToneImage(*image,threshold,&(*image)->exception);
8418 if (sepia_image != (
Image *) NULL)
8420 *image=DestroyImage(*image);
8423 CatchException(&(*image)->exception);
8424 XSetCursorState(display,windows,MagickFalse);
8425 if (windows->image.orphan != MagickFalse)
8427 XConfigureImageColormap(display,resource_info,windows,*image);
8428 (void) XConfigureImage(display,resource_info,windows,*image);
8431 case SolarizeCommand:
8437 factor[MaxTextExtent] =
"60%";
8442 (void) XDialogWidget(display,windows,
"Solarize",
8443 "Enter the solarize factor (0 - 99.9%):",factor);
8444 if (*factor ==
'\0')
8449 XSetCursorState(display,windows,MagickTrue);
8450 XCheckRefreshWindows(display,windows);
8451 threshold=StringToDoubleInterval(factor,(
double) QuantumRange+1.0);
8452 (void) SolarizeImage(*image,threshold);
8453 XSetCursorState(display,windows,MagickFalse);
8454 if (windows->image.orphan != MagickFalse)
8456 XConfigureImageColormap(display,resource_info,windows,*image);
8457 (void) XConfigureImage(display,resource_info,windows,*image);
8466 degrees[MaxTextExtent] =
"60";
8471 (void) XDialogWidget(display,windows,
"Swirl",
"Enter the swirl angle:",
8473 if (*degrees ==
'\0')
8478 XSetCursorState(display,windows,MagickTrue);
8479 XCheckRefreshWindows(display,windows);
8480 flags=ParseGeometry(degrees,&geometry_info);
8481 swirl_image=SwirlImage(*image,geometry_info.rho,&(*image)->exception);
8482 if (swirl_image != (
Image *) NULL)
8484 *image=DestroyImage(*image);
8487 CatchException(&(*image)->exception);
8488 XSetCursorState(display,windows,MagickFalse);
8489 if (windows->image.orphan != MagickFalse)
8491 XConfigureImageColormap(display,resource_info,windows,*image);
8492 (void) XConfigureImage(display,resource_info,windows,*image);
8495 case ImplodeCommand:
8501 factor[MaxTextExtent] =
"0.3";
8506 (void) XDialogWidget(display,windows,
"Implode",
8507 "Enter the implosion/explosion factor (-1.0 - 1.0):",factor);
8508 if (*factor ==
'\0')
8513 XSetCursorState(display,windows,MagickTrue);
8514 XCheckRefreshWindows(display,windows);
8515 flags=ParseGeometry(factor,&geometry_info);
8516 implode_image=ImplodeImage(*image,geometry_info.rho,&(*image)->exception);
8517 if (implode_image != (
Image *) NULL)
8519 *image=DestroyImage(*image);
8520 *image=implode_image;
8522 CatchException(&(*image)->exception);
8523 XSetCursorState(display,windows,MagickFalse);
8524 if (windows->image.orphan != MagickFalse)
8526 XConfigureImageColormap(display,resource_info,windows,*image);
8527 (void) XConfigureImage(display,resource_info,windows,*image);
8530 case VignetteCommand:
8536 geometry[MaxTextExtent] =
"0x20";
8541 (void) XDialogWidget(display,windows,
"Vignette",
8542 "Enter the radius, sigma, and x and y offsets:",geometry);
8543 if (*geometry ==
'\0')
8548 XSetCursorState(display,windows,MagickTrue);
8549 XCheckRefreshWindows(display,windows);
8550 flags=ParseGeometry(geometry,&geometry_info);
8551 if ((flags & SigmaValue) == 0)
8552 geometry_info.sigma=1.0;
8553 if ((flags & XiValue) == 0)
8554 geometry_info.xi=0.1*(*image)->columns;
8555 if ((flags & PsiValue) == 0)
8556 geometry_info.psi=0.1*(*image)->rows;
8557 vignette_image=VignetteImage(*image,geometry_info.rho,geometry_info.sigma,
8558 (ssize_t) ceil(geometry_info.xi-0.5),(ssize_t) ceil(geometry_info.psi-
8559 0.5),&(*image)->exception);
8560 if (vignette_image != (
Image *) NULL)
8562 *image=DestroyImage(*image);
8563 *image=vignette_image;
8565 CatchException(&(*image)->exception);
8566 XSetCursorState(display,windows,MagickFalse);
8567 if (windows->image.orphan != MagickFalse)
8569 XConfigureImageColormap(display,resource_info,windows,*image);
8570 (void) XConfigureImage(display,resource_info,windows,*image);
8579 geometry[MaxTextExtent] =
"25x150";
8584 (void) XDialogWidget(display,windows,
"Wave",
8585 "Enter the amplitude and length of the wave:",geometry);
8586 if (*geometry ==
'\0')
8591 XSetCursorState(display,windows,MagickTrue);
8592 XCheckRefreshWindows(display,windows);
8593 flags=ParseGeometry(geometry,&geometry_info);
8594 if ((flags & SigmaValue) == 0)
8595 geometry_info.sigma=1.0;
8596 wave_image=WaveImage(*image,geometry_info.rho,geometry_info.sigma,
8597 &(*image)->exception);
8598 if (wave_image != (
Image *) NULL)
8600 *image=DestroyImage(*image);
8603 CatchException(&(*image)->exception);
8604 XSetCursorState(display,windows,MagickFalse);
8605 if (windows->image.orphan != MagickFalse)
8607 XConfigureImageColormap(display,resource_info,windows,*image);
8608 (void) XConfigureImage(display,resource_info,windows,*image);
8611 case OilPaintCommand:
8617 radius[MaxTextExtent] =
"0";
8622 (void) XDialogWidget(display,windows,
"Oil Paint",
8623 "Enter the mask radius:",radius);
8624 if (*radius ==
'\0')
8629 XSetCursorState(display,windows,MagickTrue);
8630 XCheckRefreshWindows(display,windows);
8631 flags=ParseGeometry(radius,&geometry_info);
8632 paint_image=OilPaintImage(*image,geometry_info.rho,&(*image)->exception);
8633 if (paint_image != (
Image *) NULL)
8635 *image=DestroyImage(*image);
8638 CatchException(&(*image)->exception);
8639 XSetCursorState(display,windows,MagickFalse);
8640 if (windows->image.orphan != MagickFalse)
8642 XConfigureImageColormap(display,resource_info,windows,*image);
8643 (void) XConfigureImage(display,resource_info,windows,*image);
8646 case CharcoalDrawCommand:
8652 radius[MaxTextExtent] =
"0x1";
8657 (void) XDialogWidget(display,windows,
"Charcoal Draw",
8658 "Enter the charcoal radius and sigma:",radius);
8659 if (*radius ==
'\0')
8664 (void) XMagickCommand(display,resource_info,windows,ApplyCommand,image);
8665 XSetCursorState(display,windows,MagickTrue);
8666 XCheckRefreshWindows(display,windows);
8667 flags=ParseGeometry(radius,&geometry_info);
8668 if ((flags & SigmaValue) == 0)
8669 geometry_info.sigma=geometry_info.rho;
8670 charcoal_image=CharcoalImage(*image,geometry_info.rho,geometry_info.sigma,
8671 &(*image)->exception);
8672 if (charcoal_image != (
Image *) NULL)
8674 *image=DestroyImage(*image);
8675 *image=charcoal_image;
8677 CatchException(&(*image)->exception);
8678 XSetCursorState(display,windows,MagickFalse);
8679 if (windows->image.orphan != MagickFalse)
8681 XConfigureImageColormap(display,resource_info,windows,*image);
8682 (void) XConfigureImage(display,resource_info,windows,*image);
8685 case AnnotateCommand:
8690 status=XAnnotateEditImage(display,resource_info,windows,*image);
8691 if (status == MagickFalse)
8693 XNoticeWidget(display,windows,
"Unable to annotate X image",
8694 (*image)->filename);
8704 status=XDrawEditImage(display,resource_info,windows,image);
8705 if (status == MagickFalse)
8707 XNoticeWidget(display,windows,
"Unable to draw on the X image",
8708 (*image)->filename);
8718 status=XColorEditImage(display,resource_info,windows,image);
8719 if (status == MagickFalse)
8721 XNoticeWidget(display,windows,
"Unable to pixel edit X image",
8722 (*image)->filename);
8732 status=XMatteEditImage(display,resource_info,windows,image);
8733 if (status == MagickFalse)
8735 XNoticeWidget(display,windows,
"Unable to matte edit X image",
8736 (*image)->filename);
8741 case CompositeCommand:
8746 status=XCompositeImage(display,resource_info,windows,*image);
8747 if (status == MagickFalse)
8749 XNoticeWidget(display,windows,
"Unable to composite X image",
8750 (*image)->filename);
8755 case AddBorderCommand:
8761 geometry[MaxTextExtent] =
"6x6";
8766 XColorBrowserWidget(display,windows,
"Select",color);
8769 (void) XDialogWidget(display,windows,
"Add Border",
8770 "Enter border geometry:",geometry);
8771 if (*geometry ==
'\0')
8776 (void) XMagickCommand(display,resource_info,windows,ApplyCommand,image);
8777 XSetCursorState(display,windows,MagickTrue);
8778 XCheckRefreshWindows(display,windows);
8779 (void) QueryColorDatabase(color,&(*image)->border_color,
8780 &(*image)->exception);
8781 (void) ParsePageGeometry(*image,geometry,&page_geometry,
8782 &(*image)->exception);
8783 border_image=BorderImage(*image,&page_geometry,&(*image)->exception);
8784 if (border_image != (
Image *) NULL)
8786 *image=DestroyImage(*image);
8787 *image=border_image;
8789 CatchException(&(*image)->exception);
8790 XSetCursorState(display,windows,MagickFalse);
8791 if (windows->image.orphan != MagickFalse)
8793 windows->image.window_changes.width=(int) (*image)->columns;
8794 windows->image.window_changes.height=(int) (*image)->rows;
8795 XConfigureImageColormap(display,resource_info,windows,*image);
8796 (void) XConfigureImage(display,resource_info,windows,*image);
8799 case AddFrameCommand:
8808 geometry[MaxTextExtent] =
"6x6";
8813 XColorBrowserWidget(display,windows,
"Select",color);
8816 (void) XDialogWidget(display,windows,
"Add Frame",
"Enter frame geometry:",
8818 if (*geometry ==
'\0')
8823 (void) XMagickCommand(display,resource_info,windows,ApplyCommand,image);
8824 XSetCursorState(display,windows,MagickTrue);
8825 XCheckRefreshWindows(display,windows);
8826 (void) QueryColorDatabase(color,&(*image)->matte_color,
8827 &(*image)->exception);
8828 (void) ParsePageGeometry(*image,geometry,&page_geometry,
8829 &(*image)->exception);
8830 frame_info.width=page_geometry.width;
8831 frame_info.height=page_geometry.height;
8832 frame_info.outer_bevel=page_geometry.x;
8833 frame_info.inner_bevel=page_geometry.y;
8834 frame_info.x=(ssize_t) frame_info.width;
8835 frame_info.y=(ssize_t) frame_info.height;
8836 frame_info.width=(*image)->columns+2*frame_info.width;
8837 frame_info.height=(*image)->rows+2*frame_info.height;
8838 frame_image=FrameImage(*image,&frame_info,&(*image)->exception);
8839 if (frame_image != (
Image *) NULL)
8841 *image=DestroyImage(*image);
8844 CatchException(&(*image)->exception);
8845 XSetCursorState(display,windows,MagickFalse);
8846 if (windows->image.orphan != MagickFalse)
8848 windows->image.window_changes.width=(int) (*image)->columns;
8849 windows->image.window_changes.height=(int) (*image)->rows;
8850 XConfigureImageColormap(display,resource_info,windows,*image);
8851 (void) XConfigureImage(display,resource_info,windows,*image);
8854 case CommentCommand:
8868 unique_file=AcquireUniqueFileResource(image_info->filename);
8869 if (unique_file == -1)
8871 XNoticeWidget(display,windows,
"Unable to edit image comment",
8872 image_info->filename);
8875 value=GetImageProperty(*image,
"comment");
8876 if (value == (
char *) NULL)
8877 unique_file=close(unique_file)-1;
8883 file=fdopen(unique_file,
"w");
8884 if (file == (FILE *) NULL)
8886 XNoticeWidget(display,windows,
"Unable to edit image comment",
8887 image_info->filename);
8890 for (p=value; *p !=
'\0'; p++)
8891 (
void) fputc((
int) *p,file);
8892 (void) fputc(
'\n',file);
8893 (void) fclose(file);
8895 XSetCursorState(display,windows,MagickTrue);
8896 XCheckRefreshWindows(display,windows);
8897 status=InvokeDelegate(image_info,*image,
"edit",(
char *) NULL,
8898 &(*image)->exception);
8899 if (status == MagickFalse)
8900 XNoticeWidget(display,windows,
"Unable to edit image comment",
8907 comment=FileToString(image_info->filename,~0UL,&(*image)->exception);
8908 if (comment != (
char *) NULL)
8910 (void) SetImageProperty(*image,
"comment",comment);
8911 (*image)->taint=MagickTrue;
8914 (void) RelinquishUniqueFileResource(image_info->filename);
8915 XSetCursorState(display,windows,MagickFalse);
8923 XSetCursorState(display,windows,MagickTrue);
8924 XCheckRefreshWindows(display,windows);
8925 (void) AcquireUniqueFilename(filename);
8926 (void) FormatLocaleString((*image)->filename,MaxTextExtent,
"launch:%s",
8928 status=WriteImage(image_info,*image);
8929 if (status == MagickFalse)
8930 XNoticeWidget(display,windows,
"Unable to launch image editor",
8934 nexus=ReadImage(resource_info->image_info,&(*image)->exception);
8935 CatchException(&(*image)->exception);
8936 XClientMessage(display,windows->image.id,windows->im_protocols,
8937 windows->im_next_image,CurrentTime);
8939 (void) RelinquishUniqueFileResource(filename);
8940 XSetCursorState(display,windows,MagickFalse);
8943 case RegionOfInterestCommand:
8948 (void) XROIImage(display,resource_info,windows,image);
8958 if (windows->magnify.mapped != MagickFalse)
8959 (void) XRaiseWindow(display,windows->magnify.id);
8965 XSetCursorState(display,windows,MagickTrue);
8966 (void) XMapRaised(display,windows->magnify.id);
8967 XSetCursorState(display,windows,MagickFalse);
8971 case ShowPreviewCommand:
8980 preview_type[MaxTextExtent] =
"Gamma";
8985 previews=GetCommandOptions(MagickPreviewOptions);
8986 if (previews == (
char **) NULL)
8988 XListBrowserWidget(display,windows,&windows->widget,
8989 (
const char **) previews,
"Preview",
8990 "Select an enhancement, effect, or F/X:",preview_type);
8991 previews=DestroyStringList(previews);
8992 if (*preview_type ==
'\0')
8997 XSetCursorState(display,windows,MagickTrue);
8998 XCheckRefreshWindows(display,windows);
8999 image_info->preview_type=(PreviewType)
9000 ParseCommandOption(MagickPreviewOptions,MagickFalse,preview_type);
9001 image_info->group=(ssize_t) windows->image.id;
9002 (void) DeleteImageProperty(*image,
"label");
9003 (void) SetImageProperty(*image,
"label",
"Preview");
9004 (void) AcquireUniqueFilename(filename);
9005 (void) FormatLocaleString((*image)->filename,MaxTextExtent,
"preview:%s",
9007 status=WriteImage(image_info,*image);
9008 (void) CopyMagickString(image_info->filename,filename,MaxTextExtent);
9009 preview_image=ReadImage(image_info,&(*image)->exception);
9010 (void) RelinquishUniqueFileResource(filename);
9011 if (preview_image == (
Image *) NULL)
9013 (void) FormatLocaleString(preview_image->filename,MaxTextExtent,
"show:%s",
9015 status=WriteImage(image_info,preview_image);
9016 preview_image=DestroyImage(preview_image);
9017 if (status == MagickFalse)
9018 XNoticeWidget(display,windows,
"Unable to show image preview",
9019 (*image)->filename);
9020 XDelay(display,1500);
9021 XSetCursorState(display,windows,MagickFalse);
9024 case ShowHistogramCommand:
9032 XSetCursorState(display,windows,MagickTrue);
9033 XCheckRefreshWindows(display,windows);
9034 image_info->group=(ssize_t) windows->image.id;
9035 (void) DeleteImageProperty(*image,
"label");
9036 (void) SetImageProperty(*image,
"label",
"Histogram");
9037 (void) AcquireUniqueFilename(filename);
9038 (void) FormatLocaleString((*image)->filename,MaxTextExtent,
"histogram:%s",
9040 status=WriteImage(image_info,*image);
9041 (void) CopyMagickString(image_info->filename,filename,MaxTextExtent);
9042 histogram_image=ReadImage(image_info,&(*image)->exception);
9043 (void) RelinquishUniqueFileResource(filename);
9044 if (histogram_image == (
Image *) NULL)
9046 (void) FormatLocaleString(histogram_image->filename,MaxTextExtent,
9047 "show:%s",filename);
9048 status=WriteImage(image_info,histogram_image);
9049 histogram_image=DestroyImage(histogram_image);
9050 if (status == MagickFalse)
9051 XNoticeWidget(display,windows,
"Unable to show histogram",
9052 (*image)->filename);
9053 XDelay(display,1500);
9054 XSetCursorState(display,windows,MagickFalse);
9057 case ShowMatteCommand:
9062 if ((*image)->matte == MagickFalse)
9064 XNoticeWidget(display,windows,
9065 "Image does not have any matte information",(*image)->filename);
9071 XSetCursorState(display,windows,MagickTrue);
9072 XCheckRefreshWindows(display,windows);
9073 image_info->group=(ssize_t) windows->image.id;
9074 (void) DeleteImageProperty(*image,
"label");
9075 (void) SetImageProperty(*image,
"label",
"Matte");
9076 (void) AcquireUniqueFilename(filename);
9077 (void) FormatLocaleString((*image)->filename,MaxTextExtent,
"matte:%s",
9079 status=WriteImage(image_info,*image);
9080 (void) CopyMagickString(image_info->filename,filename,MaxTextExtent);
9081 matte_image=ReadImage(image_info,&(*image)->exception);
9082 (void) RelinquishUniqueFileResource(filename);
9083 if (matte_image == (
Image *) NULL)
9085 (void) FormatLocaleString(matte_image->filename,MaxTextExtent,
"show:%s",
9087 status=WriteImage(image_info,matte_image);
9088 matte_image=DestroyImage(matte_image);
9089 if (status == MagickFalse)
9090 XNoticeWidget(display,windows,
"Unable to show matte",
9091 (*image)->filename);
9092 XDelay(display,1500);
9093 XSetCursorState(display,windows,MagickFalse);
9096 case BackgroundCommand:
9101 status=XBackgroundImage(display,resource_info,windows,image);
9102 if (status == MagickFalse)
9104 nexus=CloneImage(*image,0,0,MagickTrue,&(*image)->exception);
9105 if (nexus != (
Image *) NULL)
9106 XClientMessage(display,windows->image.id,windows->im_protocols,
9107 windows->im_next_image,CurrentTime);
9110 case SlideShowCommand:
9113 delay[MaxTextExtent] =
"5";
9118 (void) XDialogWidget(display,windows,
"Slide Show",
9119 "Pause how many 1/100ths of a second between images:",delay);
9122 resource_info->delay=StringToUnsignedLong(delay);
9123 XClientMessage(display,windows->image.id,windows->im_protocols,
9124 windows->im_next_image,CurrentTime);
9127 case PreferencesCommand:
9132 status=XPreferencesWidget(display,resource_info,windows);
9133 if (status == MagickFalse)
9135 nexus=CloneImage(*image,0,0,MagickTrue,&(*image)->exception);
9136 if (nexus != (
Image *) NULL)
9137 XClientMessage(display,windows->image.id,windows->im_protocols,
9138 windows->im_next_image,CurrentTime);
9146 XTextViewHelp(display,resource_info,windows,MagickFalse,
9147 "Help Viewer - Display",DisplayHelp);
9150 case BrowseDocumentationCommand:
9162 root_window=XRootWindow(display,XDefaultScreen(display));
9163 mozilla_atom=XInternAtom(display,
"_MOZILLA_VERSION",MagickFalse);
9164 mozilla_window=XWindowByProperty(display,root_window,mozilla_atom);
9165 if (mozilla_window != (Window) NULL)
9168 command[MaxTextExtent];
9173 (void) FormatLocaleString(command,MaxTextExtent,
9174 "openurl(%s,new-tab)",MagickAuthoritativeURL);
9175 mozilla_atom=XInternAtom(display,
"_MOZILLA_COMMAND",MagickFalse);
9176 (void) XChangeProperty(display,mozilla_window,mozilla_atom,XA_STRING,
9177 8,PropModeReplace,(
unsigned char *) command,(int) strlen(command));
9178 XSetCursorState(display,windows,MagickFalse);
9181 XSetCursorState(display,windows,MagickTrue);
9182 XCheckRefreshWindows(display,windows);
9183 status=InvokeDelegate(image_info,*image,
"browse",(
char *) NULL,
9184 &(*image)->exception);
9185 if (status == MagickFalse)
9186 XNoticeWidget(display,windows,
"Unable to browse documentation",
9188 XDelay(display,1500);
9189 XSetCursorState(display,windows,MagickFalse);
9192 case VersionCommand:
9194 XNoticeWidget(display,windows,GetMagickVersion((
size_t *) NULL),
9195 GetMagickCopyright());
9198 case SaveToUndoBufferCommand:
9202 (void) XBell(display,0);
9206 image_info=DestroyImageInfo(image_info);
9239static void XMagnifyImage(Display *display,XWindows *windows,XEvent *event)
9242 text[MaxTextExtent];
9254 (void) XCheckDefineCursor(display,windows->image.id,windows->magnify.cursor);
9258 windows->magnify.x=(int) windows->image.x+x;
9259 windows->magnify.y=(int) windows->image.y+y;
9265 if (windows->info.mapped != MagickFalse)
9267 if ((x < (
int) (windows->info.x+windows->info.width)) &&
9268 (y < (
int) (windows->info.y+windows->info.height)))
9269 (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
9272 if ((x > (
int) (windows->info.x+windows->info.width)) ||
9273 (y > (int) (windows->info.y+windows->info.height)))
9274 (void) XMapWindow(display,windows->info.id);
9275 if (windows->info.mapped != MagickFalse)
9280 (void) FormatLocaleString(text,MaxTextExtent,
" %+d%+d ",
9281 windows->magnify.x,windows->magnify.y);
9282 XInfoWidget(display,windows,text);
9287 XScreenEvent(display,windows,event);
9288 switch (event->type)
9319 if (x >= (
int) windows->image.width)
9320 x=(int) windows->image.width-1;
9324 if (y >= (
int) windows->image.height)
9325 y=(int) windows->image.height-1;
9326 }
while ((state & ExitState) == 0);
9330 XSetCursorState(display,windows,MagickFalse);
9365static void XMagnifyWindowCommand(Display *display,XWindows *windows,
9366 const MagickStatusType state,
const KeySym key_symbol)
9375 if ((state & Mod1Mask) != 0)
9377 switch ((
int) key_symbol)
9381 (void) XWithdrawWindow(display,windows->magnify.id,
9382 windows->magnify.screen);
9388 windows->magnify.x=(int) windows->image.width/2;
9389 windows->magnify.y=(int) windows->image.height/2;
9395 if (windows->magnify.x > 0)
9396 windows->magnify.x-=quantum;
9402 if (windows->magnify.y > 0)
9403 windows->magnify.y-=quantum;
9409 if (windows->magnify.x < (
int) (windows->image.ximage->width-1))
9410 windows->magnify.x+=quantum;
9416 if (windows->magnify.y < (
int) (windows->image.ximage->height-1))
9417 windows->magnify.y+=quantum;
9431 windows->magnify.data=(key_symbol-XK_0);
9445 windows->magnify.data=(key_symbol-XK_KP_0);
9451 XMakeMagnifyImage(display,windows);
9485static void XMakePanImage(Display *display,XResourceInfo *resource_info,
9486 XWindows *windows,
Image *image)
9494 XSetCursorState(display,windows,MagickTrue);
9495 XCheckRefreshWindows(display,windows);
9496 windows->pan.x=(int) windows->image.x;
9497 windows->pan.y=(int) windows->image.y;
9498 status=XMakeImage(display,resource_info,&windows->pan,image,
9499 windows->pan.width,windows->pan.height);
9500 if (status == MagickFalse)
9501 ThrowXWindowFatalException(XServerFatalError,image->exception.reason,
9502 image->exception.description);
9503 (void) XSetWindowBackgroundPixmap(display,windows->pan.id,
9504 windows->pan.pixmap);
9505 (void) XClearWindow(display,windows->pan.id);
9506 XDrawPanRectangle(display,windows);
9507 XSetCursorState(display,windows,MagickFalse);
9542static MagickBooleanType XMatteEditImage(Display *display,
9543 XResourceInfo *resource_info,XWindows *windows,
Image **image)
9546 *
const MatteEditMenu[] =
9559 matte[MaxTextExtent] =
"0";
9561 static const ModeType
9562 MatteEditCommands[] =
9565 MatteEditBorderCommand,
9566 MatteEditFuzzCommand,
9567 MatteEditValueCommand,
9568 MatteEditUndoCommand,
9569 MatteEditHelpCommand,
9570 MatteEditDismissCommand
9574 method = PointMethod;
9577 border_color = { 0, 0, 0, 0, 0, 0 };
9580 command[MaxTextExtent],
9581 text[MaxTextExtent] =
"";
9613 (void) CloneString(&windows->command.name,
"Matte Edit");
9614 windows->command.data=4;
9615 (void) XCommandWidget(display,windows,MatteEditMenu,(XEvent *) NULL);
9616 (void) XMapRaised(display,windows->command.id);
9617 XClientMessage(display,windows->image.id,windows->im_protocols,
9618 windows->im_update_widget,CurrentTime);
9622 cursor=XMakeCursor(display,windows->image.id,windows->map_info->colormap,
9623 resource_info->background_color,resource_info->foreground_color);
9624 (void) XCheckDefineCursor(display,windows->image.id,cursor);
9628 XQueryPosition(display,windows->image.id,&x,&y);
9629 (void) XSelectInput(display,windows->image.id,
9630 windows->image.attributes.event_mask | PointerMotionMask);
9634 if (windows->info.mapped != MagickFalse)
9639 (void) FormatLocaleString(text,MaxTextExtent,
" %+d%+d ",
9640 x+windows->image.x,y+windows->image.y);
9641 XInfoWidget(display,windows,text);
9646 XScreenEvent(display,windows,&event);
9647 if (event.xany.window == windows->command.id)
9652 id=XCommandWidget(display,windows,MatteEditMenu,&event);
9655 (void) XCheckDefineCursor(display,windows->image.id,cursor);
9658 switch (MatteEditCommands[
id])
9660 case MatteEditMethod:
9668 methods=GetCommandOptions(MagickMethodOptions);
9669 if (methods == (
char **) NULL)
9671 entry=XMenuWidget(display,windows,MatteEditMenu[
id],
9672 (
const char **) methods,command);
9674 method=(PaintMethod) ParseCommandOption(MagickMethodOptions,
9675 MagickFalse,methods[entry]);
9676 methods=DestroyStringList(methods);
9679 case MatteEditBorderCommand:
9682 *ColorMenu[MaxNumberPens];
9690 for (i=0; i < (int) (MaxNumberPens-2); i++)
9691 ColorMenu[i]=resource_info->pen_colors[i];
9692 ColorMenu[MaxNumberPens-2]=
"Browser...";
9693 ColorMenu[MaxNumberPens-1]=(
const char *) NULL;
9697 pen_number=XMenuWidget(display,windows,MatteEditMenu[
id],
9698 (
const char **) ColorMenu,command);
9701 if (pen_number == (MaxNumberPens-2))
9704 color_name[MaxTextExtent] =
"gray";
9709 resource_info->pen_colors[pen_number]=color_name;
9710 XColorBrowserWidget(display,windows,
"Select",color_name);
9711 if (*color_name ==
'\0')
9717 (void) XParseColor(display,windows->map_info->colormap,
9718 resource_info->pen_colors[pen_number],&border_color);
9721 case MatteEditFuzzCommand:
9736 fuzz[MaxTextExtent];
9741 entry=XMenuWidget(display,windows,MatteEditMenu[
id],FuzzMenu,
9747 (*image)->fuzz=StringToDoubleInterval(FuzzMenu[entry],(
double)
9751 (void) CopyMagickString(fuzz,
"20%",MaxTextExtent);
9752 (void) XDialogWidget(display,windows,
"Ok",
9753 "Enter fuzz factor (0.0 - 99.9%):",fuzz);
9756 (void) ConcatenateMagickString(fuzz,
"%",MaxTextExtent);
9757 (*image)->fuzz=StringToDoubleInterval(fuzz,(
double) QuantumRange+
9761 case MatteEditValueCommand:
9764 *
const MatteMenu[] =
9773 message[MaxTextExtent];
9778 entry=XMenuWidget(display,windows,MatteEditMenu[
id],MatteMenu,
9784 (void) FormatLocaleString(matte,MaxTextExtent,
"%g",
9785 (
double) OpaqueOpacity);
9786 if (LocaleCompare(MatteMenu[entry],
"Transparent") == 0)
9787 (
void) FormatLocaleString(matte,MaxTextExtent,
"%g",
9788 (
double) TransparentOpacity);
9791 (void) FormatLocaleString(message,MaxTextExtent,
9792 "Enter matte value (0 - " "%g" "):",(
double) QuantumRange);
9793 (void) XDialogWidget(display,windows,
"Matte",message,matte);
9798 case MatteEditUndoCommand:
9800 (void) XMagickCommand(display,resource_info,windows,UndoCommand,
9804 case MatteEditHelpCommand:
9806 XTextViewHelp(display,resource_info,windows,MagickFalse,
9807 "Help Viewer - Matte Edit",ImageMatteEditHelp);
9810 case MatteEditDismissCommand:
9822 (void) XCheckDefineCursor(display,windows->image.id,cursor);
9829 if (event.xbutton.button != Button1)
9831 if ((event.xbutton.window != windows->image.id) &&
9832 (
event.xbutton.window != windows->magnify.id))
9839 (void) XMagickCommand(display,resource_info,windows,
9840 SaveToUndoBufferCommand,image);
9841 state|=UpdateConfigurationState;
9846 if (event.xbutton.button != Button1)
9848 if ((event.xbutton.window != windows->image.id) &&
9849 (
event.xbutton.window != windows->magnify.id))
9856 XConfigureImageColormap(display,resource_info,windows,*image);
9857 (void) XConfigureImage(display,resource_info,windows,*image);
9858 XInfoWidget(display,windows,text);
9859 (void) XCheckDefineCursor(display,windows->image.id,cursor);
9860 state&=(~UpdateConfigurationState);
9868 command[MaxTextExtent];
9873 if (event.xkey.window == windows->magnify.id)
9878 window=windows->magnify.id;
9879 while (XCheckWindowEvent(display,window,KeyPressMask,&event)) ;
9881 if (event.xkey.window != windows->image.id)
9886 (void) XLookupString((XKeyEvent *) &
event.xkey,command,(int)
9887 sizeof(command),&key_symbol,(XComposeStatus *) NULL);
9888 switch ((
int) key_symbol)
9902 XTextViewHelp(display,resource_info,windows,MagickFalse,
9903 "Help Viewer - Matte Edit",ImageMatteEditHelp);
9908 (void) XBell(display,0);
9921 if (windows->info.mapped != MagickFalse)
9923 if ((x < (
int) (windows->info.x+windows->info.width)) &&
9924 (y < (int) (windows->info.y+windows->info.height)))
9925 (void) XWithdrawWindow(display,windows->info.id,
9926 windows->info.screen);
9929 if ((x > (
int) (windows->info.x+windows->info.width)) ||
9930 (y > (int) (windows->info.y+windows->info.height)))
9931 (void) XMapWindow(display,windows->info.id);
9937 if (event.xany.window == windows->magnify.id)
9939 x=windows->magnify.x-windows->image.x;
9940 y=windows->magnify.y-windows->image.y;
9944 if ((state & UpdateConfigurationState) != 0)
9959 (void) XClearArea(display,windows->image.id,x_offset,y_offset,1,1,
9961 XPutPixel(windows->image.ximage,x_offset,y_offset,
9962 windows->pixel_info->background_color.pixel);
9963 width=(
unsigned int) (*image)->columns;
9964 height=(
unsigned int) (*image)->rows;
9967 if (windows->image.crop_geometry != (
char *) NULL)
9968 (void) XParseGeometry(windows->image.crop_geometry,&x,&y,
9971 (width*(windows->image.x+x_offset)/windows->image.ximage->width+x);
9973 (height*(windows->image.y+y_offset)/windows->image.ximage->height+y);
9974 if ((x_offset < 0) || (y_offset < 0))
9976 if ((x_offset >= (
int) (*image)->columns) ||
9977 (y_offset >= (
int) (*image)->rows))
9979 if (SetImageStorageClass(*image,DirectClass) == MagickFalse)
9980 return(MagickFalse);
9981 (*image)->matte=MagickTrue;
9982 exception=(&(*image)->exception);
9983 image_view=AcquireAuthenticCacheView(*image,exception);
9992 q=GetCacheViewAuthenticPixels(image_view,(ssize_t) x_offset,
9993 (ssize_t) y_offset,1,1,exception);
9996 q->opacity=(Quantum) StringToLong(matte);
9997 (void) SyncCacheViewAuthenticPixels(image_view,exception);
10000 case ReplaceMethod:
10008 (void) GetOneCacheViewVirtualPixel(image_view,(ssize_t) x_offset,
10009 (ssize_t) y_offset,&target,exception);
10010 for (y=0; y < (int) (*image)->rows; y++)
10012 q=GetCacheViewAuthenticPixels(image_view,0,(ssize_t) y,
10013 (*image)->columns,1,&(*image)->exception);
10016 for (x=0; x < (int) (*image)->columns; x++)
10018 if (IsColorSimilar(*image,q,&target))
10019 q->opacity=(Quantum) StringToLong(matte);
10022 if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
10027 case FloodfillMethod:
10028 case FillToBorderMethod:
10039 (void) GetOneVirtualMagickPixel(*image,(ssize_t) x_offset,
10040 (ssize_t) y_offset,&target,exception);
10041 if (method == FillToBorderMethod)
10043 target.red=(MagickRealType)
10044 ScaleShortToQuantum(border_color.red);
10045 target.green=(MagickRealType)
10046 ScaleShortToQuantum(border_color.green);
10047 target.blue=(MagickRealType)
10048 ScaleShortToQuantum(border_color.blue);
10050 draw_info=CloneDrawInfo(resource_info->image_info,
10052 draw_info->fill.opacity=ClampToQuantum(StringToDouble(matte,
10054 (void) FloodfillPaintImage(*image,OpacityChannel,draw_info,&target,
10055 (ssize_t) x_offset,(ssize_t) y_offset,
10056 method == FloodfillMethod ? MagickFalse : MagickTrue);
10057 draw_info=DestroyDrawInfo(draw_info);
10065 if (SetImageStorageClass(*image,DirectClass) == MagickFalse)
10066 return(MagickFalse);
10067 for (y=0; y < (int) (*image)->rows; y++)
10069 q=QueueCacheViewAuthenticPixels(image_view,0,(ssize_t) y,
10070 (*image)->columns,1,exception);
10073 for (x=0; x < (int) (*image)->columns; x++)
10075 q->opacity=(Quantum) StringToLong(matte);
10078 if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
10081 if (StringToLong(matte) == OpaqueOpacity)
10082 (*image)->matte=MagickFalse;
10086 image_view=DestroyCacheView(image_view);
10087 state&=(~UpdateConfigurationState);
10089 }
while ((state & ExitState) == 0);
10090 (void) XSelectInput(display,windows->image.id,
10091 windows->image.attributes.event_mask);
10092 XSetCursorState(display,windows,MagickFalse);
10093 (void) XFreeCursor(display,cursor);
10094 return(MagickTrue);
10128static Image *XOpenImage(Display *display,XResourceInfo *resource_info,
10129 XWindows *windows,
const MagickBooleanType command)
10144 filename[MaxTextExtent] =
"\0";
10149 if (command == MagickFalse)
10150 XFileBrowserWidget(display,windows,
"Open",filename);
10168 status=XGetCommand(display,windows->image.id,&files,&count);
10170 ThrowXWindowException(XServerError,
"UnableToGetProperty",
"...");
10171 filelist=(
char **) AcquireQuantumMemory((
size_t) count,
sizeof(*filelist));
10172 if (filelist == (
char **) NULL)
10174 (void) XFreeStringList(files);
10175 ThrowXWindowException(ResourceLimitError,
10176 "MemoryAllocationFailed",
"...");
10177 return((
Image *) NULL);
10180 for (i=1; i < count; i++)
10181 if (*files[i] !=
'-')
10182 filelist[j++]=files[i];
10183 filelist[j]=(
char *) NULL;
10184 XListBrowserWidget(display,windows,&windows->widget,
10185 (
const char **) filelist,
"Load",
"Select Image to Load:",filename);
10186 filelist=(
char **) RelinquishMagickMemory(filelist);
10187 (void) XFreeStringList(files);
10189 if (*filename ==
'\0')
10190 return((
Image *) NULL);
10191 image_info=CloneImageInfo(resource_info->image_info);
10192 (void) SetImageInfoProgressMonitor(image_info,(MagickProgressMonitor) NULL,
10194 (void) CopyMagickString(image_info->filename,filename,MaxTextExtent);
10195 exception=AcquireExceptionInfo();
10196 (void) SetImageInfo(image_info,0,exception);
10197 if (LocaleCompare(image_info->magick,
"X") == 0)
10200 seconds[MaxTextExtent];
10205 (void) CopyMagickString(seconds,
"0",MaxTextExtent);
10206 (void) XDialogWidget(display,windows,
"Grab",
"Enter any delay in seconds:",
10208 if (*seconds ==
'\0')
10209 return((
Image *) NULL);
10210 XDelay(display,(
size_t) (1000*StringToLong(seconds)));
10212 magick_info=GetMagickInfo(image_info->magick,exception);
10213 if ((magick_info != (
const MagickInfo *) NULL) &&
10214 (magick_info->raw != MagickFalse))
10217 geometry[MaxTextExtent];
10222 (void) CopyMagickString(geometry,
"512x512",MaxTextExtent);
10223 if (image_info->size != (
char *) NULL)
10224 (
void) CopyMagickString(geometry,image_info->size,MaxTextExtent);
10225 (void) XDialogWidget(display,windows,
"Load",
"Enter the image geometry:",
10227 (void) CloneString(&image_info->size,geometry);
10232 XSetCursorState(display,windows,MagickTrue);
10233 XCheckRefreshWindows(display,windows);
10234 (void) CopyMagickString(image_info->filename,filename,MaxTextExtent);
10235 nexus=ReadImage(image_info,exception);
10236 CatchException(exception);
10237 XSetCursorState(display,windows,MagickFalse);
10238 if (nexus != (
Image *) NULL)
10239 XClientMessage(display,windows->image.id,windows->im_protocols,
10240 windows->im_next_image,CurrentTime);
10250 text=FileToString(filename,~0UL,exception);
10251 if (text == (
char *) NULL)
10252 return((
Image *) NULL);
10253 textlist=StringToList(text);
10254 if (textlist != (
char **) NULL)
10257 title[MaxTextExtent];
10262 (void) FormatLocaleString(title,MaxTextExtent,
10263 "Unknown format: %s",filename);
10264 XTextViewWidget(display,resource_info,windows,MagickTrue,title,
10265 (
const char **) textlist);
10266 for (i=0; textlist[i] != (
char *) NULL; i++)
10267 textlist[i]=DestroyString(textlist[i]);
10268 textlist=(
char **) RelinquishMagickMemory(textlist);
10270 text=DestroyString(text);
10272 exception=DestroyExceptionInfo(exception);
10273 image_info=DestroyImageInfo(image_info);
10305static void XPanImage(Display *display,XWindows *windows,XEvent *event)
10308 text[MaxTextExtent];
10326 if ((windows->image.ximage->width > (
int) windows->image.width) &&
10327 (windows->image.ximage->height > (
int) windows->image.height))
10328 cursor=XCreateFontCursor(display,XC_fleur);
10330 if (windows->image.ximage->width > (
int) windows->image.width)
10331 cursor=XCreateFontCursor(display,XC_sb_h_double_arrow);
10333 if (windows->image.ximage->height > (
int) windows->image.height)
10334 cursor=XCreateFontCursor(display,XC_sb_v_double_arrow);
10336 cursor=XCreateFontCursor(display,XC_arrow);
10337 (void) XCheckDefineCursor(display,windows->pan.id,cursor);
10341 x_factor=(MagickRealType) windows->image.ximage->width/windows->pan.width;
10342 y_factor=(MagickRealType) windows->image.ximage->height/windows->pan.height;
10343 pan_info.width=windows->pan.width*windows->image.width/
10344 windows->image.ximage->width;
10345 pan_info.height=windows->pan.height*windows->image.height/
10346 windows->image.ximage->height;
10349 state=UpdateConfigurationState;
10352 switch (event->type)
10359 pan_info.x=(ssize_t) event->xbutton.x;
10360 pan_info.y=(ssize_t) event->xbutton.y;
10361 state|=UpdateConfigurationState;
10364 case ButtonRelease:
10369 pan_info.x=(ssize_t) event->xbutton.x;
10370 pan_info.y=(ssize_t) event->xbutton.y;
10371 state|=UpdateConfigurationState | ExitState;
10376 pan_info.x=(ssize_t) event->xmotion.x;
10377 pan_info.y=(ssize_t) event->xmotion.y;
10378 state|=UpdateConfigurationState;
10383 if ((state & UpdateConfigurationState) != 0)
10388 if (pan_info.x < (ssize_t) (pan_info.width/2))
10391 pan_info.x=(ssize_t) (x_factor*(pan_info.x-(pan_info.width/2)));
10392 if (pan_info.x < 0)
10395 if ((
int) (pan_info.x+windows->image.width) >
10396 windows->image.ximage->width)
10397 pan_info.x=(ssize_t)
10398 (windows->image.ximage->width-windows->image.width);
10399 if (pan_info.y < (ssize_t) (pan_info.height/2))
10402 pan_info.y=(ssize_t) (y_factor*(pan_info.y-(pan_info.height/2)));
10403 if (pan_info.y < 0)
10406 if ((
int) (pan_info.y+windows->image.height) >
10407 windows->image.ximage->height)
10408 pan_info.y=(ssize_t)
10409 (windows->image.ximage->height-windows->image.height);
10410 if ((windows->image.x != (
int) pan_info.x) ||
10411 (windows->image.y != (
int) pan_info.y))
10416 windows->image.x=(int) pan_info.x;
10417 windows->image.y=(int) pan_info.y;
10418 (void) FormatLocaleString(text,MaxTextExtent,
" %ux%u%+d%+d ",
10419 windows->image.width,windows->image.height,windows->image.x,
10421 XInfoWidget(display,windows,text);
10425 XDrawPanRectangle(display,windows);
10426 XRefreshWindow(display,&windows->image,(XEvent *) NULL);
10428 state&=(~UpdateConfigurationState);
10433 if ((state & ExitState) == 0)
10434 XScreenEvent(display,windows,event);
10435 }
while ((state & ExitState) == 0);
10439 (void) XCheckDefineCursor(display,windows->pan.id,windows->pan.cursor);
10440 (void) XFreeCursor(display,cursor);
10441 (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
10475static MagickBooleanType XPasteImage(Display *display,
10476 XResourceInfo *resource_info,XWindows *windows,
Image *image)
10479 *
const PasteMenu[] =
10487 static const ModeType
10490 PasteOperatorsCommand,
10492 PasteDismissCommand
10495 static CompositeOperator
10496 compose = CopyCompositeOp;
10499 text[MaxTextExtent];
10533 if (resource_info->copy_image == (
Image *) NULL)
10534 return(MagickFalse);
10535 paste_image=CloneImage(resource_info->copy_image,0,0,MagickTrue,
10536 &image->exception);
10537 if (paste_image == (
Image *) NULL)
10538 return(MagickFalse);
10542 (void) CloneString(&windows->command.name,
"Paste");
10543 windows->command.data=1;
10544 (void) XCommandWidget(display,windows,PasteMenu,(XEvent *) NULL);
10545 (void) XMapRaised(display,windows->command.id);
10546 XClientMessage(display,windows->image.id,windows->im_protocols,
10547 windows->im_update_widget,CurrentTime);
10551 XSetCursorState(display,windows,MagickFalse);
10552 XQueryPosition(display,windows->image.id,&x,&y);
10553 (void) XSelectInput(display,windows->image.id,
10554 windows->image.attributes.event_mask | PointerMotionMask);
10555 paste_info.x=(ssize_t) windows->image.x+x;
10556 paste_info.y=(ssize_t) windows->image.y+y;
10557 paste_info.width=0;
10558 paste_info.height=0;
10559 cursor=XCreateFontCursor(display,XC_ul_angle);
10560 (void) XSetFunction(display,windows->image.highlight_context,GXinvert);
10561 state=DefaultState;
10564 if (windows->info.mapped != MagickFalse)
10569 (void) FormatLocaleString(text,MaxTextExtent,
" %+ld%+ld ",
10570 (
long) paste_info.x,(long) paste_info.y);
10571 XInfoWidget(display,windows,text);
10573 highlight_info=paste_info;
10574 highlight_info.x=paste_info.x-windows->image.x;
10575 highlight_info.y=paste_info.y-windows->image.y;
10576 XHighlightRectangle(display,windows->image.id,
10577 windows->image.highlight_context,&highlight_info);
10581 XScreenEvent(display,windows,&event);
10582 XHighlightRectangle(display,windows->image.id,
10583 windows->image.highlight_context,&highlight_info);
10584 if (event.xany.window == windows->command.id)
10589 id=XCommandWidget(display,windows,PasteMenu,&event);
10592 switch (PasteCommands[
id])
10594 case PasteOperatorsCommand:
10597 command[MaxTextExtent],
10603 operators=GetCommandOptions(MagickComposeOptions);
10604 if (operators == (
char **) NULL)
10606 entry=XMenuWidget(display,windows,PasteMenu[
id],
10607 (
const char **) operators,command);
10609 compose=(CompositeOperator) ParseCommandOption(
10610 MagickComposeOptions,MagickFalse,operators[entry]);
10611 operators=DestroyStringList(operators);
10614 case PasteHelpCommand:
10616 XTextViewHelp(display,resource_info,windows,MagickFalse,
10617 "Help Viewer - Image Composite",ImagePasteHelp);
10620 case PasteDismissCommand:
10625 state|=EscapeState;
10634 switch (event.type)
10638 if (resource_info->debug != MagickFalse)
10639 (void) LogMagickEvent(X11Event,GetMagickModule(),
10640 "Button Press: 0x%lx %u +%d+%d",
event.xbutton.window,
10641 event.xbutton.button,
event.xbutton.x,
event.xbutton.y);
10642 if (event.xbutton.button != Button1)
10644 if (event.xbutton.window != windows->image.id)
10649 width=(
unsigned int) image->columns;
10650 height=(
unsigned int) image->rows;
10653 if (windows->image.crop_geometry != (
char *) NULL)
10654 (void) XParseGeometry(windows->image.crop_geometry,&x,&y,
10656 scale_factor=(MagickRealType) windows->image.ximage->width/width;
10657 paste_info.width=(
unsigned int) (scale_factor*paste_image->columns+0.5);
10658 scale_factor=(MagickRealType) windows->image.ximage->height/height;
10659 paste_info.height=(
unsigned int) (scale_factor*paste_image->rows+0.5);
10660 (void) XCheckDefineCursor(display,windows->image.id,cursor);
10661 paste_info.x=(ssize_t) windows->image.x+event.xbutton.x;
10662 paste_info.y=(ssize_t) windows->image.y+event.xbutton.y;
10665 case ButtonRelease:
10667 if (resource_info->debug != MagickFalse)
10668 (void) LogMagickEvent(X11Event,GetMagickModule(),
10669 "Button Release: 0x%lx %u +%d+%d",
event.xbutton.window,
10670 event.xbutton.button,
event.xbutton.x,
event.xbutton.y);
10671 if (event.xbutton.button != Button1)
10673 if (event.xbutton.window != windows->image.id)
10675 if ((paste_info.width != 0) && (paste_info.height != 0))
10680 paste_info.x=(ssize_t) windows->image.x+event.xbutton.x;
10681 paste_info.y=(ssize_t) windows->image.y+event.xbutton.y;
10691 command[MaxTextExtent];
10699 if (event.xkey.window != windows->image.id)
10704 length=XLookupString((XKeyEvent *) &event.xkey,command,(
int)
10705 sizeof(command),&key_symbol,(XComposeStatus *) NULL);
10706 *(command+length)=
'\0';
10707 if (resource_info->debug != MagickFalse)
10708 (void) LogMagickEvent(X11Event,GetMagickModule(),
10709 "Key press: 0x%lx (%s)",(long) key_symbol,command);
10710 switch ((
int) key_symbol)
10718 paste_image=DestroyImage(paste_image);
10719 state|=EscapeState;
10726 (void) XSetFunction(display,windows->image.highlight_context,
10728 XTextViewHelp(display,resource_info,windows,MagickFalse,
10729 "Help Viewer - Image Composite",ImagePasteHelp);
10730 (void) XSetFunction(display,windows->image.highlight_context,
10736 (void) XBell(display,0);
10749 if (windows->info.mapped != MagickFalse)
10751 if ((x < (
int) (windows->info.x+windows->info.width)) &&
10752 (y < (int) (windows->info.y+windows->info.height)))
10753 (void) XWithdrawWindow(display,windows->info.id,
10754 windows->info.screen);
10757 if ((x > (
int) (windows->info.x+windows->info.width)) ||
10758 (y > (int) (windows->info.y+windows->info.height)))
10759 (void) XMapWindow(display,windows->info.id);
10760 paste_info.x=(ssize_t) windows->image.x+x;
10761 paste_info.y=(ssize_t) windows->image.y+y;
10766 if (resource_info->debug != MagickFalse)
10767 (void) LogMagickEvent(X11Event,GetMagickModule(),
"Event type: %d",
10772 }
while ((state & ExitState) == 0);
10773 (void) XSelectInput(display,windows->image.id,
10774 windows->image.attributes.event_mask);
10775 (void) XSetFunction(display,windows->image.highlight_context,GXcopy);
10776 XSetCursorState(display,windows,MagickFalse);
10777 (void) XFreeCursor(display,cursor);
10778 if ((state & EscapeState) != 0)
10779 return(MagickTrue);
10783 XSetCursorState(display,windows,MagickTrue);
10784 XCheckRefreshWindows(display,windows);
10785 width=(
unsigned int) image->columns;
10786 height=(
unsigned int) image->rows;
10789 if (windows->image.crop_geometry != (
char *) NULL)
10790 (void) XParseGeometry(windows->image.crop_geometry,&x,&y,&width,&height);
10791 scale_factor=(MagickRealType) width/windows->image.ximage->width;
10793 paste_info.x=(ssize_t) (scale_factor*paste_info.x+0.5);
10794 paste_info.width=(
unsigned int) (scale_factor*paste_info.width+0.5);
10795 scale_factor=(MagickRealType) height/windows->image.ximage->height;
10797 paste_info.y=(ssize_t) (scale_factor*paste_info.y*scale_factor+0.5);
10798 paste_info.height=(
unsigned int) (scale_factor*paste_info.height+0.5);
10802 (void) CompositeImage(image,compose,paste_image,paste_info.x,paste_info.y);
10803 paste_image=DestroyImage(paste_image);
10804 XSetCursorState(display,windows,MagickFalse);
10808 XConfigureImageColormap(display,resource_info,windows,image);
10809 (void) XConfigureImage(display,resource_info,windows,image);
10810 return(MagickTrue);
10843static MagickBooleanType XPrintImage(Display *display,
10844 XResourceInfo *resource_info,XWindows *windows,
Image *image)
10847 filename[MaxTextExtent],
10848 geometry[MaxTextExtent];
10851 *
const PageSizes[] =
10882 image_info=CloneImageInfo(resource_info->image_info);
10883 (void) FormatLocaleString(geometry,MaxTextExtent,
"Letter");
10884 if (image_info->page != (
char *) NULL)
10885 (
void) CopyMagickString(geometry,image_info->page,MaxTextExtent);
10886 XListBrowserWidget(display,windows,&windows->widget,PageSizes,
"Select",
10887 "Select Postscript Page Geometry:",geometry);
10888 if (*geometry ==
'\0')
10889 return(MagickTrue);
10890 image_info->page=GetPageGeometry(geometry);
10894 XSetCursorState(display,windows,MagickTrue);
10895 XCheckRefreshWindows(display,windows);
10896 print_image=CloneImage(image,0,0,MagickTrue,&image->exception);
10897 if (print_image == (
Image *) NULL)
10898 return(MagickFalse);
10899 (void) FormatLocaleString(geometry,MaxTextExtent,
"%dx%d!",
10900 windows->image.ximage->width,windows->image.ximage->height);
10901 (void) TransformImage(&print_image,windows->image.crop_geometry,geometry);
10905 (void) AcquireUniqueFilename(filename);
10906 (void) FormatLocaleString(print_image->filename,MaxTextExtent,
"print:%s",
10908 status=WriteImage(image_info,print_image);
10909 (void) RelinquishUniqueFileResource(filename);
10910 print_image=DestroyImage(print_image);
10911 image_info=DestroyImageInfo(image_info);
10912 XSetCursorState(display,windows,MagickFalse);
10913 return(status != 0 ? MagickTrue : MagickFalse);
10946static MagickBooleanType XROIImage(Display *display,
10947 XResourceInfo *resource_info,XWindows *windows,
Image **image)
10949#define ApplyMenus 7
10958 *
const ApplyMenu[] =
10971 *
const FileMenu[] =
10977 *
const EditMenu[] =
10983 *
const TransformMenu[] =
10991 *
const EnhanceMenu[] =
10999 "Contrast Stretch...",
11000 "Sigmoidal Contrast...",
11009 *
const EffectsMenu[] =
11034 "Charcoal Draw...",
11037 *
const MiscellanyMenu[] =
11048 *
const *Menus[ApplyMenus] =
11059 static const CommandType
11082 TransformCommands[] =
11086 RotateRightCommand,
11089 EnhanceCommands[] =
11097 ContrastStretchCommand,
11098 SigmoidalContrastCommand,
11106 EffectsCommands[] =
11110 ReduceNoiseCommand,
11129 CharcoalDrawCommand
11131 MiscellanyCommands[] =
11135 ShowPreviewCommand,
11136 ShowHistogramCommand,
11145 static const CommandType
11146 *Commands[ApplyMenus] =
11158 command[MaxTextExtent],
11159 text[MaxTextExtent];
11179 MagickProgressMonitor
11200 (void) CloneString(&windows->command.name,
"ROI");
11201 windows->command.data=0;
11202 (void) XCommandWidget(display,windows,ROIMenu,(XEvent *) NULL);
11203 (void) XMapRaised(display,windows->command.id);
11204 XClientMessage(display,windows->image.id,windows->im_protocols,
11205 windows->im_update_widget,CurrentTime);
11209 XQueryPosition(display,windows->image.id,&x,&y);
11210 (void) XSelectInput(display,windows->image.id,
11211 windows->image.attributes.event_mask | PointerMotionMask);
11213 crop_info.height=0;
11216 roi_info.x=(ssize_t) windows->image.x+x;
11217 roi_info.y=(ssize_t) windows->image.y+y;
11220 cursor=XCreateFontCursor(display,XC_fleur);
11221 state=DefaultState;
11224 if (windows->info.mapped != MagickFalse)
11229 (void) FormatLocaleString(text,MaxTextExtent,
" %+ld%+ld ",
11230 (
long) roi_info.x,(long) roi_info.y);
11231 XInfoWidget(display,windows,text);
11236 XScreenEvent(display,windows,&event);
11237 if (event.xany.window == windows->command.id)
11242 id=XCommandWidget(display,windows,ROIMenu,&event);
11245 switch (ROICommands[
id])
11247 case ROIHelpCommand:
11249 XTextViewHelp(display,resource_info,windows,MagickFalse,
11250 "Help Viewer - Region of Interest",ImageROIHelp);
11253 case ROIDismissCommand:
11258 state|=EscapeState;
11267 switch (event.type)
11271 if (event.xbutton.button != Button1)
11273 if (event.xbutton.window != windows->image.id)
11278 (void) XCheckDefineCursor(display,windows->image.id,cursor);
11279 roi_info.x=(ssize_t) windows->image.x+event.xbutton.x;
11280 roi_info.y=(ssize_t) windows->image.y+event.xbutton.y;
11284 case ButtonRelease:
11293 if (event.xkey.window != windows->image.id)
11298 (void) XLookupString((XKeyEvent *) &
event.xkey,command,(int)
11299 sizeof(command),&key_symbol,(XComposeStatus *) NULL);
11300 switch ((
int) key_symbol)
11308 state|=EscapeState;
11315 XTextViewHelp(display,resource_info,windows,MagickFalse,
11316 "Help Viewer - Region of Interest",ImageROIHelp);
11321 (void) XBell(display,0);
11334 if (windows->info.mapped != MagickFalse)
11336 if ((x < (
int) (windows->info.x+windows->info.width)) &&
11337 (y < (int) (windows->info.y+windows->info.height)))
11338 (void) XWithdrawWindow(display,windows->info.id,
11339 windows->info.screen);
11342 if ((x > (
int) (windows->info.x+windows->info.width)) ||
11343 (y > (int) (windows->info.y+windows->info.height)))
11344 (void) XMapWindow(display,windows->info.id);
11345 roi_info.x=(ssize_t) windows->image.x+x;
11346 roi_info.y=(ssize_t) windows->image.y+y;
11352 }
while ((state & ExitState) == 0);
11353 (void) XSelectInput(display,windows->image.id,
11354 windows->image.attributes.event_mask);
11355 if ((state & EscapeState) != 0)
11360 (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
11361 (void) XFreeCursor(display,cursor);
11362 return(MagickTrue);
11364 (void) XSetFunction(display,windows->image.highlight_context,GXinvert);
11370 x=(int) roi_info.x;
11371 y=(int) roi_info.y;
11374 state=DefaultState;
11377 highlight_info=roi_info;
11378 highlight_info.x=roi_info.x-windows->image.x;
11379 highlight_info.y=roi_info.y-windows->image.y;
11380 if ((highlight_info.width > 3) && (highlight_info.height > 3))
11385 if (windows->info.mapped == MagickFalse)
11386 (void) XMapWindow(display,windows->info.id);
11387 (void) FormatLocaleString(text,MaxTextExtent,
11388 " %.20gx%.20g%+.20g%+.20g",(
double) roi_info.width,(double)
11389 roi_info.height,(
double) roi_info.x,(double) roi_info.y);
11390 XInfoWidget(display,windows,text);
11391 XHighlightRectangle(display,windows->image.id,
11392 windows->image.highlight_context,&highlight_info);
11395 if (windows->info.mapped != MagickFalse)
11396 (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
11400 XScreenEvent(display,windows,&event);
11401 if ((highlight_info.width > 3) && (highlight_info.height > 3))
11402 XHighlightRectangle(display,windows->image.id,
11403 windows->image.highlight_context,&highlight_info);
11404 switch (event.type)
11408 roi_info.x=(ssize_t) windows->image.x+event.xbutton.x;
11409 roi_info.y=(ssize_t) windows->image.y+event.xbutton.y;
11412 case ButtonRelease:
11417 roi_info.x=(ssize_t) windows->image.x+event.xbutton.x;
11418 roi_info.y=(ssize_t) windows->image.y+event.xbutton.y;
11419 XSetCursorState(display,windows,MagickFalse);
11421 if (LocaleCompare(windows->command.name,
"Apply") == 0)
11423 (void) CloneString(&windows->command.name,
"Apply");
11424 windows->command.data=ApplyMenus;
11425 (void) XCommandWidget(display,windows,ApplyMenu,(XEvent *) NULL);
11432 roi_info.x=(ssize_t) windows->image.x+event.xmotion.x;
11433 roi_info.y=(ssize_t) windows->image.y+event.xmotion.y;
11438 if ((((
int) roi_info.x != x) && ((
int) roi_info.y != y)) ||
11439 ((state & ExitState) != 0))
11444 if (roi_info.x < 0)
11447 if (roi_info.x > (ssize_t) windows->image.ximage->width)
11448 roi_info.x=(ssize_t) windows->image.ximage->width;
11449 if ((
int) roi_info.x < x)
11450 roi_info.width=(
unsigned int) (x-roi_info.x);
11453 roi_info.width=(
unsigned int) (roi_info.x-x);
11454 roi_info.x=(ssize_t) x;
11456 if (roi_info.y < 0)
11459 if (roi_info.y > (ssize_t) windows->image.ximage->height)
11460 roi_info.y=(ssize_t) windows->image.ximage->height;
11461 if ((
int) roi_info.y < y)
11462 roi_info.height=(
unsigned int) (y-roi_info.y);
11465 roi_info.height=(
unsigned int) (roi_info.y-y);
11466 roi_info.y=(ssize_t) y;
11469 }
while ((state & ExitState) == 0);
11473 state=DefaultState;
11474 command_type=NullCommand;
11475 (void) XMapWindow(display,windows->info.id);
11478 if (windows->info.mapped != MagickFalse)
11483 (void) FormatLocaleString(text,MaxTextExtent,
11484 " %.20gx%.20g%+.20g%+.20g",(
double) roi_info.width,(double)
11485 roi_info.height,(
double) roi_info.x,(double) roi_info.y);
11486 XInfoWidget(display,windows,text);
11488 highlight_info=roi_info;
11489 highlight_info.x=roi_info.x-windows->image.x;
11490 highlight_info.y=roi_info.y-windows->image.y;
11491 if ((highlight_info.width <= 3) || (highlight_info.height <= 3))
11493 state|=EscapeState;
11497 if ((state & UpdateRegionState) != 0)
11499 (void) XSetFunction(display,windows->image.highlight_context,GXcopy);
11500 switch (command_type)
11505 (void) XMagickCommand(display,resource_info,windows,command_type,
11514 progress_monitor=SetImageProgressMonitor(*image,
11515 (MagickProgressMonitor) NULL,(*image)->client_data);
11516 crop_info=roi_info;
11517 width=(
unsigned int) (*image)->columns;
11518 height=(
unsigned int) (*image)->rows;
11521 if (windows->image.crop_geometry != (
char *) NULL)
11522 (void) XParseGeometry(windows->image.crop_geometry,&x,&y,
11524 scale_factor=(MagickRealType) width/windows->image.ximage->width;
11526 crop_info.x=(ssize_t) (scale_factor*crop_info.x+0.5);
11527 crop_info.width=(
unsigned int) (scale_factor*crop_info.width+0.5);
11528 scale_factor=(MagickRealType)
11529 height/windows->image.ximage->height;
11531 crop_info.y=(ssize_t) (scale_factor*crop_info.y+0.5);
11532 crop_info.height=(
unsigned int)
11533 (scale_factor*crop_info.height+0.5);
11534 roi_image=CropImage(*image,&crop_info,&(*image)->exception);
11535 (void) SetImageProgressMonitor(*image,progress_monitor,
11536 (*image)->client_data);
11537 if (roi_image == (
Image *) NULL)
11542 windows->image.orphan=MagickTrue;
11543 (void) XMagickCommand(display,resource_info,windows,command_type,
11545 progress_monitor=SetImageProgressMonitor(*image,
11546 (MagickProgressMonitor) NULL,(*image)->client_data);
11547 (void) XMagickCommand(display,resource_info,windows,
11548 SaveToUndoBufferCommand,image);
11549 windows->image.orphan=MagickFalse;
11550 (void) CompositeImage(*image,CopyCompositeOp,roi_image,
11551 crop_info.x,crop_info.y);
11552 roi_image=DestroyImage(roi_image);
11553 (void) SetImageProgressMonitor(*image,progress_monitor,
11554 (*image)->client_data);
11558 if (command_type != InfoCommand)
11560 XConfigureImageColormap(display,resource_info,windows,*image);
11561 (void) XConfigureImage(display,resource_info,windows,*image);
11563 XCheckRefreshWindows(display,windows);
11564 XInfoWidget(display,windows,text);
11565 (void) XSetFunction(display,windows->image.highlight_context,
11567 state&=(~UpdateRegionState);
11569 XHighlightRectangle(display,windows->image.id,
11570 windows->image.highlight_context,&highlight_info);
11571 XScreenEvent(display,windows,&event);
11572 if (event.xany.window == windows->command.id)
11577 (void) XSetFunction(display,windows->image.highlight_context,GXcopy);
11578 command_type=NullCommand;
11579 id=XCommandWidget(display,windows,ApplyMenu,&event);
11582 (void) CopyMagickString(command,ApplyMenu[
id],MaxTextExtent);
11583 command_type=ApplyCommands[id];
11584 if (
id < ApplyMenus)
11589 entry=XMenuWidget(display,windows,ApplyMenu[
id],
11590 (
const char **) Menus[
id],command);
11593 (void) CopyMagickString(command,Menus[
id][entry],
11595 command_type=Commands[id][entry];
11599 (void) XSetFunction(display,windows->image.highlight_context,
11601 XHighlightRectangle(display,windows->image.id,
11602 windows->image.highlight_context,&highlight_info);
11603 if (command_type == HelpCommand)
11605 (void) XSetFunction(display,windows->image.highlight_context,
11607 XTextViewHelp(display,resource_info,windows,MagickFalse,
11608 "Help Viewer - Region of Interest",ImageROIHelp);
11609 (void) XSetFunction(display,windows->image.highlight_context,
11613 if (command_type == QuitCommand)
11618 state|=EscapeState;
11622 if (command_type != NullCommand)
11623 state|=UpdateRegionState;
11626 XHighlightRectangle(display,windows->image.id,
11627 windows->image.highlight_context,&highlight_info);
11628 switch (event.type)
11632 x=windows->image.x;
11633 y=windows->image.y;
11634 if (event.xbutton.button != Button1)
11636 if (event.xbutton.window != windows->image.id)
11638 x=windows->image.x+
event.xbutton.x;
11639 y=windows->image.y+
event.xbutton.y;
11640 if ((x < (
int) (roi_info.x+RoiDelta)) &&
11641 (x > (
int) (roi_info.x-RoiDelta)) &&
11642 (y < (
int) (roi_info.y+RoiDelta)) &&
11643 (y > (
int) (roi_info.y-RoiDelta)))
11645 roi_info.x=(ssize_t) (roi_info.x+roi_info.width);
11646 roi_info.y=(ssize_t) (roi_info.y+roi_info.height);
11647 state|=UpdateConfigurationState;
11650 if ((x < (
int) (roi_info.x+RoiDelta)) &&
11651 (x > (int) (roi_info.x-RoiDelta)) &&
11652 (y < (
int) (roi_info.y+roi_info.height+RoiDelta)) &&
11653 (y > (int) (roi_info.y+roi_info.height-RoiDelta)))
11655 roi_info.x=(ssize_t) (roi_info.x+roi_info.width);
11656 state|=UpdateConfigurationState;
11659 if ((x < (
int) (roi_info.x+roi_info.width+RoiDelta)) &&
11660 (x > (int) (roi_info.x+roi_info.width-RoiDelta)) &&
11661 (y < (
int) (roi_info.y+RoiDelta)) &&
11662 (y > (int) (roi_info.y-RoiDelta)))
11664 roi_info.y=(ssize_t) (roi_info.y+roi_info.height);
11665 state|=UpdateConfigurationState;
11668 if ((x < (
int) (roi_info.x+roi_info.width+RoiDelta)) &&
11669 (x > (int) (roi_info.x+roi_info.width-RoiDelta)) &&
11670 (y < (
int) (roi_info.y+roi_info.height+RoiDelta)) &&
11671 (y > (int) (roi_info.y+roi_info.height-RoiDelta)))
11673 state|=UpdateConfigurationState;
11676 magick_fallthrough;
11678 case ButtonRelease:
11680 if (event.xbutton.window == windows->pan.id)
11681 if ((highlight_info.x != crop_info.x-windows->image.x) ||
11682 (highlight_info.y != crop_info.y-windows->image.y))
11683 XHighlightRectangle(display,windows->image.id,
11684 windows->image.highlight_context,&highlight_info);
11685 (void) XSetSelectionOwner(display,XA_PRIMARY,windows->image.id,
11686 event.xbutton.time);
11691 if (event.xexpose.window == windows->image.id)
11692 if (event.xexpose.count == 0)
11694 event.xexpose.x=(int) highlight_info.x;
11695 event.xexpose.y=(int) highlight_info.y;
11696 event.xexpose.width=(int) highlight_info.width;
11697 event.xexpose.height=(int) highlight_info.height;
11698 XRefreshWindow(display,&windows->image,&event);
11700 if (event.xexpose.window == windows->info.id)
11701 if (event.xexpose.count == 0)
11702 XInfoWidget(display,windows,text);
11710 if (event.xkey.window != windows->image.id)
11715 (void) XLookupString((XKeyEvent *) &
event.xkey,command,(int)
11716 sizeof(command),&key_symbol,(XComposeStatus *) NULL);
11717 switch ((
int) key_symbol)
11725 state|=EscapeState;
11726 magick_fallthrough;
11736 roi_info.x=(ssize_t) (windows->image.width/2L-roi_info.width/2L);
11737 roi_info.y=(ssize_t) (windows->image.height/2L-
11738 roi_info.height/2L);
11770 (void) XSetFunction(display,windows->image.highlight_context,
11772 XTextViewHelp(display,resource_info,windows,MagickFalse,
11773 "Help Viewer - Region of Interest",ImageROIHelp);
11774 (void) XSetFunction(display,windows->image.highlight_context,
11780 command_type=XImageWindowCommand(display,resource_info,windows,
11781 event.xkey.state,key_symbol,image);
11782 if (command_type != NullCommand)
11783 state|=UpdateRegionState;
11787 (void) XSetSelectionOwner(display,XA_PRIMARY,windows->image.id,
11795 if (event.xbutton.window != windows->image.id)
11802 if (windows->info.mapped != MagickFalse)
11804 if ((x < (
int) (windows->info.x+windows->info.width)) &&
11805 (y < (int) (windows->info.y+windows->info.height)))
11806 (void) XWithdrawWindow(display,windows->info.id,
11807 windows->info.screen);
11810 if ((x > (
int) (windows->info.x+windows->info.width)) ||
11811 (y > (int) (windows->info.y+windows->info.height)))
11812 (void) XMapWindow(display,windows->info.id);
11813 roi_info.x=(ssize_t) windows->image.x+event.xmotion.x;
11814 roi_info.y=(ssize_t) windows->image.y+event.xmotion.y;
11817 case SelectionRequest:
11822 XSelectionRequestEvent
11828 (void) FormatLocaleString(text,MaxTextExtent,
11829 "%.20gx%.20g%+.20g%+.20g",(
double) roi_info.width,(double)
11830 roi_info.height,(
double) roi_info.x,(double) roi_info.y);
11831 request=(&(
event.xselectionrequest));
11832 (void) XChangeProperty(request->display,request->requestor,
11833 request->property,request->target,8,PropModeReplace,
11834 (
unsigned char *) text,(int) strlen(text));
11835 notify.type=SelectionNotify;
11836 notify.display=request->display;
11837 notify.requestor=request->requestor;
11838 notify.selection=request->selection;
11839 notify.target=request->target;
11840 notify.time=request->time;
11841 if (request->property == None)
11842 notify.property=request->target;
11844 notify.property=request->property;
11845 (void) XSendEvent(request->display,request->requestor,False,0,
11846 (XEvent *) ¬ify);
11851 if ((state & UpdateConfigurationState) != 0)
11853 (void) XPutBackEvent(display,&event);
11854 (void) XCheckDefineCursor(display,windows->image.id,cursor);
11857 }
while ((state & ExitState) == 0);
11858 }
while ((state & ExitState) == 0);
11859 (void) XSetFunction(display,windows->image.highlight_context,GXcopy);
11860 XSetCursorState(display,windows,MagickFalse);
11861 if ((state & EscapeState) != 0)
11862 return(MagickTrue);
11863 return(MagickTrue);
11900static MagickBooleanType XRotateImage(Display *display,
11901 XResourceInfo *resource_info,XWindows *windows,
double degrees,
Image **image)
11904 *
const RotateMenu[] =
11914 direction = HorizontalRotateCommand;
11916 static const ModeType
11917 DirectionCommands[] =
11919 HorizontalRotateCommand,
11920 VerticalRotateCommand
11924 RotateColorCommand,
11925 RotateDirectionCommand,
11927 RotateDismissCommand
11930 static unsigned int
11934 command[MaxTextExtent],
11935 text[MaxTextExtent];
11946 normalized_degrees;
11956 if (degrees == 0.0)
11973 (void) CloneString(&windows->command.name,
"Rotate");
11974 windows->command.data=2;
11975 (void) XCommandWidget(display,windows,RotateMenu,(XEvent *) NULL);
11976 (void) XMapRaised(display,windows->command.id);
11977 XClientMessage(display,windows->image.id,windows->im_protocols,
11978 windows->im_update_widget,CurrentTime);
11982 (void) XSetFunction(display,windows->image.highlight_context,GXinvert);
11983 XQueryPosition(display,windows->image.id,&x,&y);
11988 state=DefaultState;
11991 XHighlightLine(display,windows->image.id,
11992 windows->image.highlight_context,&rotate_info);
11996 XScreenEvent(display,windows,&event);
11997 XHighlightLine(display,windows->image.id,
11998 windows->image.highlight_context,&rotate_info);
11999 if (event.xany.window == windows->command.id)
12004 id=XCommandWidget(display,windows,RotateMenu,&event);
12007 (void) XSetFunction(display,windows->image.highlight_context,
12009 switch (RotateCommands[
id])
12011 case RotateColorCommand:
12014 *ColorMenu[MaxNumberPens];
12025 for (i=0; i < (int) (MaxNumberPens-2); i++)
12026 ColorMenu[i]=resource_info->pen_colors[i];
12027 ColorMenu[MaxNumberPens-2]=
"Browser...";
12028 ColorMenu[MaxNumberPens-1]=(
const char *) NULL;
12032 pen_number=XMenuWidget(display,windows,RotateMenu[
id],
12033 (
const char **) ColorMenu,command);
12034 if (pen_number < 0)
12036 if (pen_number == (MaxNumberPens-2))
12039 color_name[MaxTextExtent] =
"gray";
12044 resource_info->pen_colors[pen_number]=color_name;
12045 XColorBrowserWidget(display,windows,
"Select",color_name);
12046 if (*color_name ==
'\0')
12052 (void) XParseColor(display,windows->map_info->colormap,
12053 resource_info->pen_colors[pen_number],&color);
12054 XBestPixel(display,windows->map_info->colormap,(XColor *) NULL,
12055 (
unsigned int) MaxColors,&color);
12056 windows->pixel_info->pen_colors[pen_number]=color;
12057 pen_id=(
unsigned int) pen_number;
12060 case RotateDirectionCommand:
12063 *
const Directions[] =
12073 id=XMenuWidget(display,windows,RotateMenu[
id],
12074 Directions,command);
12076 direction=DirectionCommands[id];
12079 case RotateHelpCommand:
12081 XTextViewHelp(display,resource_info,windows,MagickFalse,
12082 "Help Viewer - Image Rotation",ImageRotateHelp);
12085 case RotateDismissCommand:
12090 state|=EscapeState;
12097 (void) XSetFunction(display,windows->image.highlight_context,
12101 switch (event.type)
12105 if (event.xbutton.button != Button1)
12107 if (event.xbutton.window != windows->image.id)
12112 (void) XSetFunction(display,windows->image.highlight_context,
12114 rotate_info.x1=
event.xbutton.x;
12115 rotate_info.y1=
event.xbutton.y;
12119 case ButtonRelease:
12126 command[MaxTextExtent];
12131 if (event.xkey.window != windows->image.id)
12136 (void) XLookupString((XKeyEvent *) &
event.xkey,command,(int)
12137 sizeof(command),&key_symbol,(XComposeStatus *) NULL);
12138 switch ((
int) key_symbol)
12146 state|=EscapeState;
12153 (void) XSetFunction(display,windows->image.highlight_context,
12155 XTextViewHelp(display,resource_info,windows,MagickFalse,
12156 "Help Viewer - Image Rotation",ImageRotateHelp);
12157 (void) XSetFunction(display,windows->image.highlight_context,
12163 (void) XBell(display,0);
12171 rotate_info.x1=
event.xmotion.x;
12172 rotate_info.y1=
event.xmotion.y;
12175 rotate_info.x2=rotate_info.x1;
12176 rotate_info.y2=rotate_info.y1;
12177 if (direction == HorizontalRotateCommand)
12178 rotate_info.x2+=32;
12180 rotate_info.y2-=32;
12181 }
while ((state & ExitState) == 0);
12182 (void) XSetFunction(display,windows->image.highlight_context,GXcopy);
12183 (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
12184 if ((state & EscapeState) != 0)
12185 return(MagickTrue);
12190 (void) XSetFunction(display,windows->image.highlight_context,GXinvert);
12191 state=DefaultState;
12199 if (windows->info.mapped == MagickFalse)
12200 (void) XMapWindow(display,windows->info.id);
12201 (void) FormatLocaleString(text,MaxTextExtent,
" %g",
12202 direction == VerticalRotateCommand ? degrees-90.0 : degrees);
12203 XInfoWidget(display,windows,text);
12204 XHighlightLine(display,windows->image.id,
12205 windows->image.highlight_context,&rotate_info);
12208 if (windows->info.mapped != MagickFalse)
12209 (void) XWithdrawWindow(display,windows->info.id,
12210 windows->info.screen);
12214 XScreenEvent(display,windows,&event);
12216 XHighlightLine(display,windows->image.id,
12217 windows->image.highlight_context,&rotate_info);
12218 switch (event.type)
12222 case ButtonRelease:
12227 rotate_info.x2=
event.xbutton.x;
12228 rotate_info.y2=
event.xbutton.y;
12236 rotate_info.x2=
event.xmotion.x;
12237 rotate_info.y2=
event.xmotion.y;
12245 if (rotate_info.x2 < 0)
12248 if (rotate_info.x2 > (
int) windows->image.width)
12249 rotate_info.x2=(short) windows->image.width;
12250 if (rotate_info.y2 < 0)
12253 if (rotate_info.y2 > (
int) windows->image.height)
12254 rotate_info.y2=(short) windows->image.height;
12259 distance=(
unsigned int)
12260 ((rotate_info.x2-rotate_info.x1+1)*(rotate_info.x2-rotate_info.x1+1))+
12261 ((rotate_info.y2-rotate_info.y1+1)*(rotate_info.y2-rotate_info.y1+1));
12263 degrees=RadiansToDegrees(-atan2((
double) (rotate_info.y2-
12264 rotate_info.y1),(
double) (rotate_info.x2-rotate_info.x1)));
12265 }
while ((state & ExitState) == 0);
12266 (void) XSetFunction(display,windows->image.highlight_context,GXcopy);
12267 (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
12269 return(MagickTrue);
12271 if (direction == VerticalRotateCommand)
12273 if (degrees == 0.0)
12274 return(MagickTrue);
12278 normalized_degrees=degrees;
12279 while (normalized_degrees < -45.0)
12280 normalized_degrees+=360.0;
12281 for (rotations=0; normalized_degrees > 45.0; rotations++)
12282 normalized_degrees-=90.0;
12283 if (normalized_degrees != 0.0)
12284 (void) XMagickCommand(display,resource_info,windows,ApplyCommand,image);
12285 XSetCursorState(display,windows,MagickTrue);
12286 XCheckRefreshWindows(display,windows);
12287 (*image)->background_color.red=ScaleShortToQuantum(
12288 windows->pixel_info->pen_colors[pen_id].red);
12289 (*image)->background_color.green=ScaleShortToQuantum(
12290 windows->pixel_info->pen_colors[pen_id].green);
12291 (*image)->background_color.blue=ScaleShortToQuantum(
12292 windows->pixel_info->pen_colors[pen_id].blue);
12293 rotate_image=RotateImage(*image,degrees,&(*image)->exception);
12294 XSetCursorState(display,windows,MagickFalse);
12295 if (rotate_image == (
Image *) NULL)
12296 return(MagickFalse);
12297 *image=DestroyImage(*image);
12298 *image=rotate_image;
12299 if (windows->image.crop_geometry != (
char *) NULL)
12304 width=(
unsigned int) (*image)->columns;
12305 height=(
unsigned int) (*image)->rows;
12306 (void) XParseGeometry(windows->image.crop_geometry,&x,&y,&width,&height);
12307 switch (rotations % 4)
12317 (void) FormatLocaleString(windows->image.crop_geometry,MaxTextExtent,
12318 "%ux%u%+d%+d",height,width,(
int) (*image)->columns-
12327 (void) FormatLocaleString(windows->image.crop_geometry,MaxTextExtent,
12328 "%ux%u%+d%+d",width,height,(
int) width-x,(int) height-y);
12336 (void) FormatLocaleString(windows->image.crop_geometry,MaxTextExtent,
12337 "%ux%u%+d%+d",height,width,y,(
int) (*image)->rows-(int) width-x);
12342 if (windows->image.orphan != MagickFalse)
12343 return(MagickTrue);
12344 if (normalized_degrees != 0.0)
12349 windows->image.window_changes.width=(int) (*image)->columns;
12350 windows->image.window_changes.height=(int) (*image)->rows;
12351 if (windows->image.crop_geometry != (
char *) NULL)
12356 (void) XParseGeometry(windows->image.crop_geometry,&x,&y,
12358 windows->image.window_changes.width=(int) width;
12359 windows->image.window_changes.height=(int) height;
12361 XConfigureImageColormap(display,resource_info,windows,*image);
12364 if (((rotations % 4) == 1) || ((rotations % 4) == 3))
12366 windows->image.window_changes.width=windows->image.ximage->height;
12367 windows->image.window_changes.height=windows->image.ximage->width;
12372 (void) XConfigureImage(display,resource_info,windows,*image);
12373 return(MagickTrue);
12406static MagickBooleanType XSaveImage(Display *display,
12407 XResourceInfo *resource_info,XWindows *windows,
Image *image)
12410 filename[MaxTextExtent],
12411 geometry[MaxTextExtent];
12425 if (resource_info->write_filename != (
char *) NULL)
12426 (void) CopyMagickString(filename,resource_info->write_filename,
12431 path[MaxTextExtent];
12436 GetPathComponent(image->filename,HeadPath,path);
12437 GetPathComponent(image->filename,TailPath,filename);
12440 status=chdir(path);
12442 (void) ThrowMagickException(&image->exception,GetMagickModule(),
12443 FileOpenError,
"UnableToOpenFile",
"%s",path);
12446 XFileBrowserWidget(display,windows,
"Save",filename);
12447 if (*filename ==
'\0')
12448 return(MagickTrue);
12449 if (IsPathAccessible(filename) != MagickFalse)
12457 status=XConfirmWidget(display,windows,
"Overwrite",filename);
12459 return(MagickTrue);
12461 image_info=CloneImageInfo(resource_info->image_info);
12462 (void) CopyMagickString(image_info->filename,filename,MaxTextExtent);
12463 (void) SetImageInfo(image_info,1,&image->exception);
12464 if ((LocaleCompare(image_info->magick,
"JPEG") == 0) ||
12465 (LocaleCompare(image_info->magick,
"JPG") == 0))
12468 quality[MaxTextExtent];
12476 (void) FormatLocaleString(quality,MaxTextExtent,
"%.20g",(
double)
12478 status=XDialogWidget(display,windows,
"Save",
"Enter JPEG quality:",
12480 if (*quality ==
'\0')
12481 return(MagickTrue);
12482 image->quality=StringToUnsignedLong(quality);
12483 image_info->interlace=status != 0 ? NoInterlace : PlaneInterlace;
12485 if ((LocaleCompare(image_info->magick,
"EPS") == 0) ||
12486 (LocaleCompare(image_info->magick,
"PDF") == 0) ||
12487 (LocaleCompare(image_info->magick,
"PS") == 0) ||
12488 (LocaleCompare(image_info->magick,
"PS2") == 0))
12491 geometry[MaxTextExtent];
12494 *
const PageSizes[] =
12516 (void) CopyMagickString(geometry,PSPageGeometry,MaxTextExtent);
12517 if (LocaleCompare(image_info->magick,
"PDF") == 0)
12518 (
void) CopyMagickString(geometry,PSPageGeometry,MaxTextExtent);
12519 if (image_info->page != (
char *) NULL)
12520 (void) CopyMagickString(geometry,image_info->page,MaxTextExtent);
12521 XListBrowserWidget(display,windows,&windows->widget,PageSizes,
"Select",
12522 "Select page geometry:",geometry);
12523 if (*geometry !=
'\0')
12524 image_info->page=GetPageGeometry(geometry);
12529 XSetCursorState(display,windows,MagickTrue);
12530 XCheckRefreshWindows(display,windows);
12531 save_image=CloneImage(image,0,0,MagickTrue,&image->exception);
12532 if (save_image == (
Image *) NULL)
12533 return(MagickFalse);
12534 (void) FormatLocaleString(geometry,MaxTextExtent,
"%dx%d!",
12535 windows->image.ximage->width,windows->image.ximage->height);
12536 (void) TransformImage(&save_image,windows->image.crop_geometry,geometry);
12540 (void) CopyMagickString(save_image->filename,filename,MaxTextExtent);
12541 status=WriteImage(image_info,save_image);
12542 if (status != MagickFalse)
12543 image->taint=MagickFalse;
12544 save_image=DestroyImage(save_image);
12545 image_info=DestroyImageInfo(image_info);
12546 XSetCursorState(display,windows,MagickFalse);
12547 return(status != 0 ? MagickTrue : MagickFalse);
12580#if defined(__cplusplus) || defined(c_plusplus)
12584static int XPredicate(Display *magick_unused(display),XEvent *event,
char *data)
12589 magick_unreferenced(display);
12591 windows=(XWindows *) data;
12592 if ((event->type == ClientMessage) &&
12593 (
event->xclient.window == windows->image.id))
12594 return(MagickFalse);
12595 return(MagickTrue);
12598#if defined(__cplusplus) || defined(c_plusplus)
12602static void XScreenEvent(Display *display,XWindows *windows,XEvent *event)
12608 (void) XIfEvent(display,event,XPredicate,(
char *) windows);
12609 if (event->xany.window == windows->command.id)
12611 switch (event->type)
12614 case ButtonRelease:
12616 if ((event->xbutton.button == Button3) &&
12617 (
event->xbutton.state & Mod1Mask))
12622 event->xbutton.button=Button2;
12623 event->xbutton.state&=(~Mod1Mask);
12625 if (event->xbutton.window == windows->backdrop.id)
12627 (void) XSetInputFocus(display,event->xbutton.window,RevertToParent,
12628 event->xbutton.time);
12631 if (event->xbutton.window == windows->pan.id)
12633 XPanImage(display,windows,event);
12636 if (event->xbutton.window == windows->image.id)
12637 if (event->xbutton.button == Button2)
12642 x=
event->xbutton.x;
12643 y=
event->xbutton.y;
12647 if (x >= (
int) windows->image.width)
12648 x=(int) (windows->image.width-1);
12649 windows->magnify.x=(int) windows->image.x+x;
12653 if (y >= (
int) windows->image.height)
12654 y=(int) (windows->image.height-1);
12655 windows->magnify.y=windows->image.y+y;
12656 if (windows->magnify.mapped == MagickFalse)
12657 (void) XMapRaised(display,windows->magnify.id);
12658 XMakeMagnifyImage(display,windows);
12659 if (event->type == ButtonRelease)
12660 (void) XWithdrawWindow(display,windows->info.id,
12661 windows->info.screen);
12666 case ClientMessage:
12671 if (event->xclient.message_type != windows->wm_protocols)
12673 if (*event->xclient.data.l != (
long) windows->wm_delete_window)
12675 if (event->xclient.window == windows->magnify.id)
12677 (void) XWithdrawWindow(display,windows->magnify.id,
12678 windows->magnify.screen);
12683 case ConfigureNotify:
12685 if (event->xconfigure.window == windows->magnify.id)
12693 windows->magnify.width=(
unsigned int) event->xconfigure.width;
12694 windows->magnify.height=(
unsigned int) event->xconfigure.height;
12695 if (windows->magnify.mapped == MagickFalse)
12698 while ((
int) magnify <= event->xconfigure.width)
12700 while ((
int) magnify <= event->xconfigure.height)
12703 if (((
int) magnify != event->xconfigure.width) ||
12704 ((
int) magnify != event->xconfigure.height))
12709 window_changes.width=(int) magnify;
12710 window_changes.height=(int) magnify;
12711 (void) XReconfigureWMWindow(display,windows->magnify.id,
12712 windows->magnify.screen,(
unsigned int) (CWWidth | CWHeight),
12716 XMakeMagnifyImage(display,windows);
12723 if (event->xexpose.window == windows->image.id)
12725 XRefreshWindow(display,&windows->image,event);
12728 if (event->xexpose.window == windows->pan.id)
12729 if (event->xexpose.count == 0)
12731 XDrawPanRectangle(display,windows);
12734 if (event->xexpose.window == windows->magnify.id)
12735 if (event->xexpose.count == 0)
12737 XMakeMagnifyImage(display,windows);
12745 command[MaxTextExtent];
12750 if (event->xkey.window != windows->magnify.id)
12755 (void) XLookupString((XKeyEvent *) &
event->xkey,command,(int)
12756 sizeof(command),&key_symbol,(XComposeStatus *) NULL);
12757 XMagnifyWindowCommand(display,windows,event->xkey.state,key_symbol);
12762 if (event->xmap.window == windows->magnify.id)
12764 windows->magnify.mapped=MagickTrue;
12765 (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
12768 if (event->xmap.window == windows->info.id)
12770 windows->info.mapped=MagickTrue;
12777 while (XCheckMaskEvent(display,ButtonMotionMask,event)) ;
12778 if (event->xmotion.window == windows->image.id)
12779 if (windows->magnify.mapped != MagickFalse)
12784 x=
event->xmotion.x;
12785 y=
event->xmotion.y;
12789 if (x >= (
int) windows->image.width)
12790 x=(
int) (windows->image.width-1);
12791 windows->magnify.x=(int) windows->image.x+x;
12795 if (y >= (
int) windows->image.height)
12796 y=(int) (windows->image.height-1);
12797 windows->magnify.y=windows->image.y+y;
12798 XMakeMagnifyImage(display,windows);
12804 if (event->xunmap.window == windows->magnify.id)
12806 windows->magnify.mapped=MagickFalse;
12809 if (event->xunmap.window == windows->info.id)
12811 windows->info.mapped=MagickFalse;
12853static void XSetCropGeometry(Display *display,XWindows *windows,
12857 text[MaxTextExtent];
12870 if (windows->info.mapped != MagickFalse)
12875 (void) FormatLocaleString(text,MaxTextExtent,
" %.20gx%.20g%+.20g%+.20g",
12876 (
double) crop_info->width,(double) crop_info->height,(
double)
12877 crop_info->x,(double) crop_info->y);
12878 XInfoWidget(display,windows,text);
12885 width=(
unsigned int) image->columns;
12886 height=(
unsigned int) image->rows;
12887 if (windows->image.crop_geometry != (
char *) NULL)
12888 (void) XParseGeometry(windows->image.crop_geometry,&x,&y,&width,&height);
12890 windows->image.crop_geometry=AcquireString((
char *) NULL);
12894 scale_factor=(MagickRealType) width/windows->image.ximage->width;
12895 if (crop_info->x > 0)
12896 x+=(int) (scale_factor*crop_info->x+0.5);
12897 width=(
unsigned int) (scale_factor*crop_info->width+0.5);
12900 scale_factor=(MagickRealType) height/windows->image.ximage->height;
12901 if (crop_info->y > 0)
12902 y+=(int) (scale_factor*crop_info->y+0.5);
12903 height=(
unsigned int) (scale_factor*crop_info->height+0.5);
12906 (void) FormatLocaleString(windows->image.crop_geometry,MaxTextExtent,
12907 "%ux%u%+d%+d",width,height,x,y);
12947static Image *XTileImage(Display *display,XResourceInfo *resource_info,
12948 XWindows *windows,
Image *image,XEvent *event)
12951 *
const VerbMenu[] =
12961 static const ModeType
12972 command[MaxTextExtent],
12973 filename[MaxTextExtent];
13004 width=(
unsigned int) image->columns;
13005 height=(
unsigned int) image->rows;
13006 if (windows->image.crop_geometry != (
char *) NULL)
13007 (void) XParseGeometry(windows->image.crop_geometry,&x,&y,&width,&height);
13008 scale_factor=(MagickRealType) width/windows->image.ximage->width;
13009 event->xbutton.x+=windows->image.x;
13010 event->xbutton.x=(int) (scale_factor*event->xbutton.x+x+0.5);
13011 scale_factor=(MagickRealType) height/windows->image.ximage->height;
13012 event->xbutton.y+=windows->image.y;
13013 event->xbutton.y=(int) (scale_factor*event->xbutton.y+y+0.5);
13017 width=(
unsigned int) image->columns;
13018 height=(
unsigned int) image->rows;
13021 (void) XParseGeometry(image->montage,&x,&y,&width,&height);
13022 tile=((
event->xbutton.y-y)/height)*(((int) image->columns-x)/width)+
13023 (event->xbutton.x-x)/width;
13029 (void) XBell(display,0);
13030 return((
Image *) NULL);
13035 p=image->directory;
13036 for (i=tile; (i != 0) && (*p !=
'\0'); )
13047 (void) XBell(display,0);
13048 return((
Image *) NULL);
13053 id=XMenuWidget(display,windows,
"Tile Verb",VerbMenu,command);
13055 return((
Image *) NULL);
13057 while ((*q !=
'\xff') && (*q !=
'\0'))
13059 (void) CopyMagickString(filename,p,(
size_t) (q-p+1));
13063 XSetCursorState(display,windows,MagickTrue);
13064 XCheckRefreshWindows(display,windows);
13065 tile_image=NewImageList();
13066 switch (TileCommands[
id])
13068 case TileLoadCommand:
13073 XCheckRefreshWindows(display,windows);
13074 (void) CopyMagickString(resource_info->image_info->magick,
"MIFF",
13076 (void) CopyMagickString(resource_info->image_info->filename,filename,
13078 tile_image=ReadImage(resource_info->image_info,&image->exception);
13079 CatchException(&image->exception);
13080 (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
13083 case TileNextCommand:
13088 XClientMessage(display,windows->image.id,windows->im_protocols,
13089 windows->im_next_image,CurrentTime);
13092 case TileFormerCommand:
13097 XClientMessage(display,windows->image.id,windows->im_protocols,
13098 windows->im_former_image,CurrentTime);
13101 case TileDeleteCommand:
13106 if (IsPathAccessible(filename) == MagickFalse)
13108 XNoticeWidget(display,windows,
"Image file does not exist:",filename);
13111 status=XConfirmWidget(display,windows,
"Really delete tile",filename);
13114 status=ShredFile(filename);
13115 status|=remove_utf8(filename);
13116 if (status != MagickFalse)
13118 XNoticeWidget(display,windows,
"Unable to delete image file:",
13122 magick_fallthrough;
13124 case TileUpdateCommand:
13146 for (p=image->directory; *p !=
'\0'; p++)
13152 while ((*q !=
'\xff') && (*q !=
'\0'))
13154 (void) CopyMagickString(filename,p,(
size_t) (q-p+1));
13156 if (IsPathAccessible(filename) != MagickFalse)
13164 x_offset=(int) (width*(tile % (((
int) image->columns-x)/width))+x);
13165 y_offset=(int) (height*(tile/(((
int) image->columns-x)/width))+y);
13166 exception=(&image->exception);
13167 image_view=AcquireAuthenticCacheView(image,exception);
13168 (void) GetOneCacheViewVirtualPixel(image_view,0,0,&pixel,exception);
13169 for (i=0; i < (int) height; i++)
13171 s=GetCacheViewAuthenticPixels(image_view,(ssize_t) x_offset,(ssize_t)
13172 y_offset+i,width,1,exception);
13175 for (j=0; j < (int) width; j++)
13177 if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
13180 image_view=DestroyCacheView(image_view);
13183 windows->image.window_changes.width=(int) image->columns;
13184 windows->image.window_changes.height=(int) image->rows;
13185 XConfigureImageColormap(display,resource_info,windows,image);
13186 (void) XConfigureImage(display,resource_info,windows,image);
13192 XSetCursorState(display,windows,MagickFalse);
13193 return(tile_image);
13229static void XTranslateImage(Display *display,XWindows *windows,
13230 Image *image,
const KeySym key_symbol)
13233 text[MaxTextExtent];
13246 x_offset=windows->image.width;
13247 y_offset=windows->image.height;
13248 if (image->montage != (
char *) NULL)
13249 (void) XParseGeometry(image->montage,&x,&y,&x_offset,&y_offset);
13250 switch ((
int) key_symbol)
13255 windows->image.x=(int) windows->image.width/2;
13256 windows->image.y=(int) windows->image.height/2;
13262 windows->image.x-=x_offset;
13269 windows->image.y-=y_offset;
13275 windows->image.x+=x_offset;
13282 windows->image.y+=y_offset;
13291 if (windows->image.x < 0)
13292 windows->image.x=0;
13294 if ((
int) (windows->image.x+windows->image.width) >
13295 windows->image.ximage->width)
13296 windows->image.x=(int) windows->image.ximage->width-windows->image.width;
13297 if (windows->image.y < 0)
13298 windows->image.y=0;
13300 if ((
int) (windows->image.y+windows->image.height) >
13301 windows->image.ximage->height)
13302 windows->image.y=(int) windows->image.ximage->height-windows->image.height;
13306 (void) FormatLocaleString(text,MaxTextExtent,
" %ux%u%+d%+d ",
13307 windows->image.width,windows->image.height,windows->image.x,
13309 XInfoWidget(display,windows,text);
13310 XCheckRefreshWindows(display,windows);
13311 XDrawPanRectangle(display,windows);
13312 XRefreshWindow(display,&windows->image,(XEvent *) NULL);
13313 (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
13346static MagickBooleanType XTrimImage(Display *display,
13347 XResourceInfo *resource_info,XWindows *windows,
Image *image)
13363 XSetCursorState(display,windows,MagickTrue);
13364 XCheckRefreshWindows(display,windows);
13368 background=XGetPixel(windows->image.ximage,0,0);
13369 trim_info.width=(size_t) windows->image.ximage->width;
13370 for (x=0; x < windows->image.ximage->width; x++)
13372 for (y=0; y < windows->image.ximage->height; y++)
13374 pixel=XGetPixel(windows->image.ximage,x,y);
13375 if (pixel != background)
13378 if (y < windows->image.ximage->height)
13381 trim_info.x=(ssize_t) x;
13382 if (trim_info.x == (ssize_t) windows->image.ximage->width)
13384 XSetCursorState(display,windows,MagickFalse);
13385 return(MagickFalse);
13390 background=XGetPixel(windows->image.ximage,windows->image.ximage->width-1,0);
13391 for (x=windows->image.ximage->width-1; x != 0; x--)
13393 for (y=0; y < windows->image.ximage->height; y++)
13395 pixel=XGetPixel(windows->image.ximage,x,y);
13396 if (pixel != background)
13399 if (y < windows->image.ximage->height)
13402 trim_info.width=(size_t) (x-trim_info.x+1);
13406 background=XGetPixel(windows->image.ximage,0,0);
13407 trim_info.height=(size_t) windows->image.ximage->height;
13408 for (y=0; y < windows->image.ximage->height; y++)
13410 for (x=0; x < windows->image.ximage->width; x++)
13412 pixel=XGetPixel(windows->image.ximage,x,y);
13413 if (pixel != background)
13416 if (x < windows->image.ximage->width)
13419 trim_info.y=(ssize_t) y;
13423 background=XGetPixel(windows->image.ximage,0,windows->image.ximage->height-1);
13424 for (y=windows->image.ximage->height-1; y != 0; y--)
13426 for (x=0; x < windows->image.ximage->width; x++)
13428 pixel=XGetPixel(windows->image.ximage,x,y);
13429 if (pixel != background)
13432 if (x < windows->image.ximage->width)
13435 trim_info.height=(size_t) y-trim_info.y+1;
13436 if (((
unsigned int) trim_info.width != windows->image.width) ||
13437 ((
unsigned int) trim_info.height != windows->image.height))
13442 XSetCropGeometry(display,windows,&trim_info,image);
13443 windows->image.window_changes.width=(int) trim_info.width;
13444 windows->image.window_changes.height=(int) trim_info.height;
13445 (void) XConfigureImage(display,resource_info,windows,image);
13447 XSetCursorState(display,windows,MagickFalse);
13448 return(MagickTrue);
13483static Image *XVisualDirectoryImage(Display *display,
13484 XResourceInfo *resource_info,XWindows *windows)
13486#define TileImageTag "Scale/Image"
13487#define XClientName "montage"
13523 filename[MaxTextExtent] =
"\0",
13524 filenames[MaxTextExtent] =
"*";
13527 background_resources;
13532 XFileBrowserWidget(display,windows,
"Directory",filenames);
13533 if (*filenames ==
'\0')
13534 return((
Image *) NULL);
13538 filelist=(
char **) AcquireMagickMemory(
sizeof(*filelist));
13539 if (filelist == (
char **) NULL)
13541 ThrowXWindowException(ResourceLimitError,
"MemoryAllocationFailed",
13543 return((
Image *) NULL);
13546 filelist[0]=filenames;
13547 status=ExpandFilenames(&number_files,&filelist);
13548 if ((status == MagickFalse) || (number_files == 0))
13550 if (number_files == 0)
13551 ThrowXWindowException(ImageError,
"NoImagesWereFound",filenames)
13553 ThrowXWindowException(ResourceLimitError,
"MemoryAllocationFailed",
13555 return((
Image *) NULL);
13560 background_resources=(*resource_info);
13561 background_resources.window_id=AcquireString(
"");
13562 (void) FormatLocaleString(background_resources.window_id,MaxTextExtent,
13563 "0x%lx",windows->image.id);
13564 background_resources.backdrop=MagickTrue;
13568 backdrop=(windows->visual_info->klass == TrueColor) ||
13569 (windows->visual_info->klass == DirectColor) ? MagickTrue : MagickFalse;
13570 read_info=CloneImageInfo(resource_info->image_info);
13571 (void) SetImageOption(read_info,
"jpeg:size",
"120x120");
13572 (void) CloneString(&read_info->size,DefaultTileGeometry);
13573 (void) SetImageInfoProgressMonitor(read_info,(MagickProgressMonitor) NULL,
13575 images=NewImageList();
13576 exception=AcquireExceptionInfo();
13577 XSetCursorState(display,windows,MagickTrue);
13578 XCheckRefreshWindows(display,windows);
13579 for (i=0; i < (int) number_files; i++)
13581 (void) CopyMagickString(read_info->filename,filelist[i],MaxTextExtent);
13582 filelist[i]=DestroyString(filelist[i]);
13583 *read_info->magick=
'\0';
13584 next_image=ReadImage(read_info,exception);
13585 CatchException(exception);
13586 if (next_image != (
Image *) NULL)
13588 (void) DeleteImageProperty(next_image,
"label");
13589 (void) SetImageProperty(next_image,
"label",InterpretImageProperties(
13590 read_info,next_image,DefaultTileLabel));
13591 (void) ParseRegionGeometry(next_image,read_info->size,&geometry,
13593 thumbnail_image=ThumbnailImage(next_image,geometry.width,
13594 geometry.height,exception);
13595 if (thumbnail_image != (
Image *) NULL)
13597 next_image=DestroyImage(next_image);
13598 next_image=thumbnail_image;
13602 (void) XDisplayBackgroundImage(display,&background_resources,
13604 XSetCursorState(display,windows,MagickTrue);
13606 AppendImageToList(&images,next_image);
13607 if (images->progress_monitor != (MagickProgressMonitor) NULL)
13612 proceed=SetImageProgress(images,LoadImageTag,(MagickOffsetType) i,
13613 (MagickSizeType) number_files);
13614 if (proceed == MagickFalse)
13619 exception=DestroyExceptionInfo(exception);
13620 filelist=(
char **) RelinquishMagickMemory(filelist);
13621 if (images == (
Image *) NULL)
13623 read_info=DestroyImageInfo(read_info);
13624 XSetCursorState(display,windows,MagickFalse);
13625 ThrowXWindowException(ImageError,
"NoImagesWereLoaded",filenames);
13626 return((
Image *) NULL);
13631 montage_info=CloneMontageInfo(read_info,(
MontageInfo *) NULL);
13632 montage_info->pointsize=10;
13633 if (resource_info->font != (
char *) NULL)
13634 (void) CloneString(&montage_info->font,resource_info->font);
13635 (void) CopyMagickString(montage_info->filename,filename,MaxTextExtent);
13636 montage_image=MontageImageList(read_info,montage_info,GetFirstImageInList(
13637 images),&images->exception);
13638 images=DestroyImageList(images);
13639 montage_info=DestroyMontageInfo(montage_info);
13640 read_info=DestroyImageInfo(read_info);
13641 XSetCursorState(display,windows,MagickFalse);
13642 if (montage_image == (
Image *) NULL)
13643 return(montage_image);
13644 XClientMessage(display,windows->image.id,windows->im_protocols,
13645 windows->im_next_image,CurrentTime);
13646 return(montage_image);
13677MagickExport MagickBooleanType XDisplayBackgroundImage(Display *display,
13678 XResourceInfo *resource_info,
Image *image)
13681 geometry[MaxTextExtent],
13682 visual_type[MaxTextExtent];
13695 static XStandardColormap
13699 *visual_info = (XVisualInfo *) NULL;
13722 assert(image != (
Image *) NULL);
13723 assert(image->signature == MagickCoreSignature);
13724 if (IsEventLogging() != MagickFalse)
13725 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
13726 resources=(*resource_info);
13727 window_info.id=(Window) NULL;
13728 root_window=XRootWindow(display,XDefaultScreen(display));
13729 if (LocaleCompare(resources.window_id,
"root") == 0)
13730 window_info.id=root_window;
13733 if (isdigit((
int) ((
unsigned char) *resources.window_id)) != 0)
13734 window_info.id=XWindowByID(display,root_window,
13735 (Window) strtol((
char *) resources.window_id,(
char **) NULL,0));
13736 if (window_info.id == (Window) NULL)
13737 window_info.id=XWindowByName(display,root_window,resources.window_id);
13739 if (window_info.id == (Window) NULL)
13741 ThrowXWindowException(XServerError,
"NoWindowWithSpecifiedIDExists",
13742 resources.window_id);
13747 window_attributes.width=XDisplayWidth(display,XDefaultScreen(display));
13748 window_attributes.height=XDisplayHeight(display,XDefaultScreen(display));
13749 (void) CopyMagickString(visual_type,
"default",MaxTextExtent);
13750 status=XGetWindowAttributes(display,window_info.id,&window_attributes);
13752 (void) FormatLocaleString(visual_type,MaxTextExtent,
"0x%lx",
13753 XVisualIDFromVisual(window_attributes.visual));
13754 if (visual_info == (XVisualInfo *) NULL)
13759 map_info=XAllocStandardColormap();
13760 if (map_info == (XStandardColormap *) NULL)
13761 ThrowXWindowFatalException(XServerFatalError,
"MemoryAllocationFailed",
13763 map_info->colormap=(Colormap) NULL;
13764 pixel.pixels=(
unsigned long *) NULL;
13768 resources.map_type=(
char *) NULL;
13769 resources.visual_type=visual_type;
13770 visual_info=XBestVisualInfo(display,map_info,&resources);
13771 if (visual_info == (XVisualInfo *) NULL)
13772 ThrowXWindowFatalException(XServerFatalError,
"UnableToGetVisual",
13773 resources.visual_type);
13777 window_info.ximage=(XImage *) NULL;
13778 window_info.matte_image=(XImage *) NULL;
13779 window_info.pixmap=(Pixmap) NULL;
13780 window_info.matte_pixmap=(Pixmap) NULL;
13785 if (window_info.id == root_window)
13786 (void) XDestroyWindowColors(display,root_window);
13790 resources.colormap=SharedColormap;
13791 XMakeStandardColormap(display,visual_info,&resources,image,map_info,&pixel);
13795 context_values.background=pixel.foreground_color.pixel;
13796 context_values.foreground=pixel.background_color.pixel;
13797 pixel.annotate_context=XCreateGC(display,window_info.id,
13798 (
size_t) (GCBackground | GCForeground),&context_values);
13799 if (pixel.annotate_context == (GC) NULL)
13800 ThrowXWindowFatalException(XServerFatalError,
"UnableToCreateGraphicContext",
13805 window_info.name=AcquireString(
"\0");
13806 window_info.icon_name=AcquireString(
"\0");
13807 XGetWindowInfo(display,visual_info,map_info,&pixel,(XFontStruct *) NULL,
13808 &resources,&window_info);
13812 window_info.width=(
unsigned int) image->columns;
13813 window_info.height=(
unsigned int) image->rows;
13814 if ((image->columns != window_info.width) ||
13815 (image->rows != window_info.height))
13816 ThrowXWindowFatalException(XServerFatalError,
"UnableToCreateXImage",
13818 (void) FormatLocaleString(geometry,MaxTextExtent,
"%ux%u+0+0>",
13819 window_attributes.width,window_attributes.height);
13820 geometry_info.width=window_info.width;
13821 geometry_info.height=window_info.height;
13822 geometry_info.x=(ssize_t) window_info.x;
13823 geometry_info.y=(ssize_t) window_info.y;
13824 (void) ParseMetaGeometry(geometry,&geometry_info.x,&geometry_info.y,
13825 &geometry_info.width,&geometry_info.height);
13826 window_info.width=(
unsigned int) geometry_info.width;
13827 window_info.height=(
unsigned int) geometry_info.height;
13828 window_info.x=(int) geometry_info.x;
13829 window_info.y=(int) geometry_info.y;
13830 status=XMakeImage(display,&resources,&window_info,image,window_info.width,
13831 window_info.height);
13832 if (status == MagickFalse)
13833 ThrowXWindowFatalException(XServerFatalError,
"UnableToCreateXImage",
13837 if (resource_info->debug != MagickFalse)
13839 (void) LogMagickEvent(X11Event,GetMagickModule(),
13840 "Image: %s[%.20g] %.20gx%.20g ",image->filename,(double) image->scene,
13841 (
double) image->columns,(double) image->rows);
13842 if (image->colors != 0)
13843 (void) LogMagickEvent(X11Event,GetMagickModule(),
"%.20gc ",(double)
13845 (void) LogMagickEvent(X11Event,GetMagickModule(),
"%s",image->magick);
13850 width=(int) window_info.width;
13851 height=(int) window_info.height;
13852 if (resources.backdrop != MagickFalse)
13857 window_info.x=(window_attributes.width/2)-(window_info.ximage->width/2);
13858 window_info.y=(window_attributes.height/2)-(window_info.ximage->height/2);
13859 width=window_attributes.width;
13860 height=window_attributes.height;
13862 if ((resources.image_geometry != (
char *) NULL) &&
13863 (*resources.image_geometry !=
'\0'))
13866 default_geometry[MaxTextExtent];
13878 size_hints=XAllocSizeHints();
13879 if (size_hints == (XSizeHints *) NULL)
13880 ThrowXWindowFatalException(ResourceLimitFatalError,
13881 "MemoryAllocationFailed",image->filename);
13882 size_hints->flags=0L;
13883 (void) FormatLocaleString(default_geometry,MaxTextExtent,
"%dx%d",
13885 flags=XWMGeometry(display,visual_info->screen,resources.image_geometry,
13886 default_geometry,window_info.border_width,size_hints,&window_info.x,
13887 &window_info.y,&width,&height,&gravity);
13888 if (flags & (XValue | YValue))
13890 width=window_attributes.width;
13891 height=window_attributes.height;
13893 (void) XFree((
void *) size_hints);
13898 window_info.pixmap=XCreatePixmap(display,window_info.id,(
unsigned int) width,
13899 (
unsigned int) height,window_info.depth);
13900 if (window_info.pixmap == (Pixmap) NULL)
13901 ThrowXWindowFatalException(XServerFatalError,
"UnableToCreateXPixmap",
13906 if (((
unsigned int) width > window_info.width) ||
13907 ((
unsigned int) height > window_info.height))
13908 (void) XFillRectangle(display,window_info.pixmap,
13909 window_info.annotate_context,0,0,(
unsigned int) width,
13910 (
unsigned int) height);
13911 (void) XPutImage(display,window_info.pixmap,window_info.annotate_context,
13912 window_info.ximage,0,0,window_info.x,window_info.y,(
unsigned int)
13913 window_info.width,(
unsigned int) window_info.height);
13914 (void) XSetWindowBackgroundPixmap(display,window_info.id,window_info.pixmap);
13915 (void) XClearWindow(display,window_info.id);
13916 delay=1000*image->delay/MagickMax(image->ticks_per_second,1L);
13917 XDelay(display,delay == 0UL ? 10UL : delay);
13918 (void) XSync(display,MagickFalse);
13919 return(window_info.id == root_window ? MagickTrue : MagickFalse);
13959MagickExport
Image *XDisplayImage(Display *display,XResourceInfo *resource_info,
13960 char **argv,
int argc,
Image **image,
size_t *state)
13962#define MagnifySize 256
13963#define MagickMenus 10
13964#define MagickTitle "Commands"
13967 *
const CommandMenu[] =
13981 *
const FileMenu[] =
13991 "Visual Directory...",
13995 *
const EditMenu[] =
14004 *
const ViewMenu[] =
14015 *
const TransformMenu[] =
14029 *
const EnhanceMenu[] =
14037 "Contrast Stretch...",
14038 "Sigmoidal Contrast...",
14047 *
const EffectsMenu[] =
14072 "Charcoal Draw...",
14075 *
const ImageEditMenu[] =
14086 "Region of Interest...",
14089 *
const MiscellanyMenu[] =
14101 *
const HelpMenu[] =
14104 "Browse Documentation",
14108 *
const ShortCutsMenu[] =
14121 *
const VirtualMenu[] =
14131 *
const *Menus[MagickMenus] =
14169 VisualDirectoryCommand,
14183 OriginalSizeCommand,
14190 TransformCommands[] =
14196 RotateRightCommand,
14203 EnhanceCommands[] =
14211 ContrastStretchCommand,
14212 SigmoidalContrastCommand,
14220 EffectsCommands[] =
14224 ReduceNoiseCommand,
14244 CharcoalDrawCommand
14246 ImageEditCommands[] =
14257 RegionOfInterestCommand
14259 MiscellanyCommands[] =
14263 ShowPreviewCommand,
14264 ShowHistogramCommand,
14273 BrowseDocumentationCommand,
14276 ShortCutsCommands[] =
14288 VirtualCommands[] =
14297 *Commands[MagickMenus] =
14307 MiscellanyCommands,
14312 command[MaxTextExtent],
14314 geometry[MaxTextExtent],
14315 resource_name[MaxTextExtent];
14342 working_directory[MaxTextExtent];
14348 *magick_windows[MaxXWindows];
14350 static unsigned int
14410 assert(image != (
Image **) NULL);
14411 assert((*image)->signature == MagickCoreSignature);
14412 if (IsEventLogging() != MagickFalse)
14413 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",(*image)->filename);
14414 display_image=(*image);
14415 warning_handler=(WarningHandler) NULL;
14416 windows=XSetWindows((XWindows *) ~0);
14417 if (windows != (XWindows *) NULL)
14422 if (*working_directory ==
'\0')
14423 (void) CopyMagickString(working_directory,
".",MaxTextExtent);
14424 status=chdir(working_directory);
14426 (void) ThrowMagickException(&(*image)->exception,GetMagickModule(),
14427 FileOpenError,
"UnableToOpenFile",
"%s",working_directory);
14428 warning_handler=resource_info->display_warnings ?
14429 SetErrorHandler(XWarning) : SetErrorHandler((ErrorHandler) NULL);
14430 warning_handler=resource_info->display_warnings ?
14431 SetWarningHandler(XWarning) : SetWarningHandler((WarningHandler) NULL);
14438 resource_info->colors=display_image->colors;
14439 windows=XSetWindows(XInitializeWindows(display,resource_info));
14440 if (windows == (XWindows *) NULL)
14441 ThrowXWindowFatalException(XServerFatalError,
"UnableToCreateWindow",
14442 (*image)->filename);
14447 magick_windows[number_windows++]=(&windows->icon);
14448 magick_windows[number_windows++]=(&windows->backdrop);
14449 magick_windows[number_windows++]=(&windows->image);
14450 magick_windows[number_windows++]=(&windows->info);
14451 magick_windows[number_windows++]=(&windows->command);
14452 magick_windows[number_windows++]=(&windows->widget);
14453 magick_windows[number_windows++]=(&windows->popup);
14454 magick_windows[number_windows++]=(&windows->magnify);
14455 magick_windows[number_windows++]=(&windows->pan);
14456 for (i=0; i < (int) number_windows; i++)
14457 magick_windows[i]->
id=(Window) NULL;
14464 if (windows->font_info != (XFontStruct *) NULL)
14465 (
void) XFreeFont(display,windows->font_info);
14466 windows->font_info=XBestFont(display,resource_info,MagickFalse);
14467 if (windows->font_info == (XFontStruct *) NULL)
14468 ThrowXWindowFatalException(XServerFatalError,
"UnableToLoadFont",
14469 resource_info->font);
14473 map_info=windows->map_info;
14474 icon_map=windows->icon_map;
14475 visual_info=windows->visual_info;
14476 icon_visual=windows->icon_visual;
14477 pixel=windows->pixel_info;
14478 icon_pixel=windows->icon_pixel;
14479 font_info=windows->font_info;
14480 icon_resources=windows->icon_resources;
14481 class_hints=windows->class_hints;
14482 manager_hints=windows->manager_hints;
14483 root_window=XRootWindow(display,visual_info->screen);
14484 nexus=NewImageList();
14485 if (resource_info->debug != MagickFalse)
14487 (void) LogMagickEvent(X11Event,GetMagickModule(),
14488 "Image: %s[%.20g] %.20gx%.20g ",display_image->filename,
14489 (double) display_image->scene,(
double) display_image->columns,
14490 (double) display_image->rows);
14491 if (display_image->colors != 0)
14492 (void) LogMagickEvent(X11Event,GetMagickModule(),
"%.20gc ",(double)
14493 display_image->colors);
14494 (void) LogMagickEvent(X11Event,GetMagickModule(),
"%s",
14495 display_image->magick);
14497 XMakeStandardColormap(display,visual_info,resource_info,display_image,
14499 display_image->taint=MagickFalse;
14503 windows->context.id=(Window) NULL;
14504 XGetWindowInfo(display,visual_info,map_info,pixel,font_info,
14505 resource_info,&windows->context);
14506 (void) CloneString(&class_hints->res_name,resource_info->client_name);
14507 (void) CloneString(&class_hints->res_class,resource_info->client_name);
14508 class_hints->res_class[0]=(char) LocaleToUppercase((
int)
14509 class_hints->res_class[0]);
14510 manager_hints->flags=InputHint | StateHint;
14511 manager_hints->input=MagickFalse;
14512 manager_hints->initial_state=WithdrawnState;
14513 XMakeWindow(display,root_window,argv,argc,class_hints,manager_hints,
14514 &windows->context);
14515 if (resource_info->debug != MagickFalse)
14516 (void) LogMagickEvent(X11Event,GetMagickModule(),
14517 "Window id: 0x%lx (context)",windows->context.id);
14518 context_values.background=pixel->background_color.pixel;
14519 context_values.font=font_info->fid;
14520 context_values.foreground=pixel->foreground_color.pixel;
14521 context_values.graphics_exposures=MagickFalse;
14522 context_mask=(MagickStatusType)
14523 (GCBackground | GCFont | GCForeground | GCGraphicsExposures);
14524 if (pixel->annotate_context != (GC) NULL)
14525 (
void) XFreeGC(display,pixel->annotate_context);
14526 pixel->annotate_context=XCreateGC(display,windows->context.id,
14527 context_mask,&context_values);
14528 if (pixel->annotate_context == (GC) NULL)
14529 ThrowXWindowFatalException(XServerFatalError,
"UnableToCreateGraphicContext",
14530 display_image->filename);
14531 context_values.background=pixel->depth_color.pixel;
14532 if (pixel->widget_context != (GC) NULL)
14533 (void) XFreeGC(display,pixel->widget_context);
14534 pixel->widget_context=XCreateGC(display,windows->context.id,context_mask,
14536 if (pixel->widget_context == (GC) NULL)
14537 ThrowXWindowFatalException(XServerFatalError,
"UnableToCreateGraphicContext",
14538 display_image->filename);
14539 context_values.background=pixel->foreground_color.pixel;
14540 context_values.foreground=pixel->background_color.pixel;
14541 context_values.plane_mask=context_values.background ^
14542 context_values.foreground;
14543 if (pixel->highlight_context != (GC) NULL)
14544 (void) XFreeGC(display,pixel->highlight_context);
14545 pixel->highlight_context=XCreateGC(display,windows->context.id,
14546 (
size_t) (context_mask | GCPlaneMask),&context_values);
14547 if (pixel->highlight_context == (GC) NULL)
14548 ThrowXWindowFatalException(XServerFatalError,
"UnableToCreateGraphicContext",
14549 display_image->filename);
14550 (void) XDestroyWindow(display,windows->context.id);
14554 XGetWindowInfo(display,icon_visual,icon_map,icon_pixel,(XFontStruct *) NULL,
14555 icon_resources,&windows->icon);
14556 windows->icon.geometry=resource_info->icon_geometry;
14557 XBestIconSize(display,&windows->icon,display_image);
14558 windows->icon.attributes.colormap=XDefaultColormap(display,
14559 icon_visual->screen);
14560 windows->icon.attributes.event_mask=ExposureMask | StructureNotifyMask;
14561 manager_hints->flags=InputHint | StateHint;
14562 manager_hints->input=MagickFalse;
14563 manager_hints->initial_state=IconicState;
14564 XMakeWindow(display,root_window,argv,argc,class_hints,manager_hints,
14566 if (resource_info->debug != MagickFalse)
14567 (void) LogMagickEvent(X11Event,GetMagickModule(),
"Window id: 0x%lx (icon)",
14572 if (icon_pixel->annotate_context != (GC) NULL)
14573 (
void) XFreeGC(display,icon_pixel->annotate_context);
14574 context_values.background=icon_pixel->background_color.pixel;
14575 context_values.foreground=icon_pixel->foreground_color.pixel;
14576 icon_pixel->annotate_context=XCreateGC(display,windows->icon.id,
14577 (
size_t) (GCBackground | GCForeground),&context_values);
14578 if (icon_pixel->annotate_context == (GC) NULL)
14579 ThrowXWindowFatalException(XServerFatalError,
"UnableToCreateGraphicContext",
14580 display_image->filename);
14581 windows->icon.annotate_context=icon_pixel->annotate_context;
14585 XGetWindowInfo(display,visual_info,map_info,pixel,font_info,resource_info,
14587 windows->image.shape=MagickTrue;
14588 if (resource_info->use_shared_memory == MagickFalse)
14589 windows->image.shared_memory=MagickFalse;
14590 if ((resource_info->title != (
char *) NULL) && !(*state & MontageImageState))
14595 title=InterpretImageProperties(resource_info->image_info,display_image,
14596 resource_info->title);
14597 (void) CloneString(&windows->image.name,title);
14598 (void) CloneString(&windows->image.icon_name,title);
14599 title=DestroyString(title);
14604 filename[MaxTextExtent],
14605 window_name[MaxTextExtent];
14610 GetPathComponent(display_image->magick_filename,TailPath,filename);
14611 if (display_image->scene == 0)
14612 (void) FormatLocaleString(window_name,MaxTextExtent,
"%s: %s",
14613 MagickPackageName,filename);
14615 (
void) FormatLocaleString(window_name,MaxTextExtent,
14616 "%s: %s[scene: %.20g frames: %.20g]",MagickPackageName,filename,
14617 (
double) display_image->scene,(
double) GetImageListLength(
14619 (void) CloneString(&windows->image.name,window_name);
14620 (void) CloneString(&windows->image.icon_name,filename);
14622 if (resource_info->immutable)
14623 windows->image.immutable=MagickTrue;
14624 windows->image.use_pixmap=resource_info->use_pixmap;
14625 windows->image.geometry=resource_info->image_geometry;
14626 (void) FormatLocaleString(geometry,MaxTextExtent,
"%ux%u+0+0>!",
14627 XDisplayWidth(display,visual_info->screen),
14628 XDisplayHeight(display,visual_info->screen));
14629 geometry_info.width=display_image->columns;
14630 geometry_info.height=display_image->rows;
14633 (void) ParseMetaGeometry(geometry,&geometry_info.x,&geometry_info.y,
14634 &geometry_info.width,&geometry_info.height);
14635 windows->image.width=(
unsigned int) geometry_info.width;
14636 windows->image.height=(
unsigned int) geometry_info.height;
14637 windows->image.attributes.event_mask=ButtonMotionMask | ButtonPressMask |
14638 ButtonReleaseMask | EnterWindowMask | ExposureMask | KeyPressMask |
14639 KeyReleaseMask | LeaveWindowMask | OwnerGrabButtonMask |
14640 PropertyChangeMask | StructureNotifyMask | SubstructureNotifyMask;
14641 XGetWindowInfo(display,visual_info,map_info,pixel,font_info,
14642 resource_info,&windows->backdrop);
14643 if ((resource_info->backdrop) || (windows->backdrop.id != (Window) NULL))
14648 windows->backdrop.x=0;
14649 windows->backdrop.y=0;
14650 (void) CloneString(&windows->backdrop.name,
"Backdrop");
14651 windows->backdrop.flags=(size_t) (USSize | USPosition);
14652 windows->backdrop.width=(
unsigned int)
14653 XDisplayWidth(display,visual_info->screen);
14654 windows->backdrop.height=(
unsigned int)
14655 XDisplayHeight(display,visual_info->screen);
14656 windows->backdrop.border_width=0;
14657 windows->backdrop.immutable=MagickTrue;
14658 windows->backdrop.attributes.do_not_propagate_mask=ButtonPressMask |
14660 windows->backdrop.attributes.event_mask=ButtonPressMask | KeyPressMask |
14661 StructureNotifyMask;
14662 manager_hints->flags=IconWindowHint | InputHint | StateHint;
14663 manager_hints->icon_window=windows->icon.id;
14664 manager_hints->input=MagickTrue;
14665 manager_hints->initial_state=resource_info->iconic ? IconicState :
14667 XMakeWindow(display,root_window,argv,argc,class_hints,manager_hints,
14668 &windows->backdrop);
14669 if (resource_info->debug != MagickFalse)
14670 (void) LogMagickEvent(X11Event,GetMagickModule(),
14671 "Window id: 0x%lx (backdrop)",windows->backdrop.id);
14672 (void) XMapWindow(display,windows->backdrop.id);
14673 (void) XClearWindow(display,windows->backdrop.id);
14674 if (windows->image.id != (Window) NULL)
14676 (void) XDestroyWindow(display,windows->image.id);
14677 windows->image.id=(Window) NULL;
14682 windows->image.flags|=USPosition;
14683 windows->image.x=(XDisplayWidth(display,visual_info->screen)/2)-
14684 (windows->image.width/2);
14685 windows->image.y=(XDisplayHeight(display,visual_info->screen)/2)-
14686 (windows->image.height/2);
14688 manager_hints->flags=IconWindowHint | InputHint | StateHint;
14689 manager_hints->icon_window=windows->icon.id;
14690 manager_hints->input=MagickTrue;
14691 manager_hints->initial_state=resource_info->iconic ? IconicState :
14693 if (windows->group_leader.id != (Window) NULL)
14698 manager_hints->flags|=WindowGroupHint;
14699 manager_hints->window_group=windows->group_leader.id;
14700 (void) XSelectInput(display,windows->group_leader.id,StructureNotifyMask);
14701 if (resource_info->debug != MagickFalse)
14702 (void) LogMagickEvent(X11Event,GetMagickModule(),
14703 "Window id: 0x%lx (group leader)",windows->group_leader.id);
14705 XMakeWindow(display,
14706 (Window) (resource_info->backdrop ? windows->backdrop.id : root_window),
14707 argv,argc,class_hints,manager_hints,&windows->image);
14708 (void) XChangeProperty(display,windows->image.id,windows->im_protocols,
14709 XA_STRING,8,PropModeReplace,(
unsigned char *) NULL,0);
14710 if (windows->group_leader.id != (Window) NULL)
14711 (
void) XSetTransientForHint(display,windows->image.id,
14712 windows->group_leader.id);
14713 if (resource_info->debug != MagickFalse)
14714 (void) LogMagickEvent(X11Event,GetMagickModule(),
"Window id: 0x%lx (image)",
14715 windows->image.id);
14719 XGetWindowInfo(display,visual_info,map_info,pixel,font_info,resource_info,
14721 (void) CloneString(&windows->info.name,
"Info");
14722 (void) CloneString(&windows->info.icon_name,
"Info");
14723 windows->info.border_width=1;
14726 windows->info.flags|=PPosition;
14727 windows->info.attributes.win_gravity=UnmapGravity;
14728 windows->info.attributes.event_mask=ButtonPressMask | ExposureMask |
14729 StructureNotifyMask;
14730 manager_hints->flags=InputHint | StateHint | WindowGroupHint;
14731 manager_hints->input=MagickFalse;
14732 manager_hints->initial_state=NormalState;
14733 manager_hints->window_group=windows->image.id;
14734 XMakeWindow(display,windows->image.id,argv,argc,class_hints,manager_hints,
14736 windows->info.highlight_stipple=XCreateBitmapFromData(display,
14737 windows->info.id,(
char *) HighlightBitmap,HighlightWidth,HighlightHeight);
14738 windows->info.shadow_stipple=XCreateBitmapFromData(display,
14739 windows->info.id,(
char *) ShadowBitmap,ShadowWidth,ShadowHeight);
14740 (void) XSetTransientForHint(display,windows->info.id,windows->image.id);
14741 if (windows->image.mapped != MagickFalse)
14742 (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
14743 if (resource_info->debug != MagickFalse)
14744 (void) LogMagickEvent(X11Event,GetMagickModule(),
"Window id: 0x%lx (info)",
14749 XGetWindowInfo(display,visual_info,map_info,pixel,font_info,
14750 resource_info,&windows->command);
14751 windows->command.data=MagickMenus;
14752 (void) XCommandWidget(display,windows,CommandMenu,(XEvent *) NULL);
14753 (void) FormatLocaleString(resource_name,MaxTextExtent,
"%s.command",
14754 resource_info->client_name);
14755 windows->command.geometry=XGetResourceClass(resource_info->resource_database,
14756 resource_name,
"geometry",(
char *) NULL);
14757 (void) CloneString(&windows->command.name,MagickTitle);
14758 windows->command.border_width=0;
14759 windows->command.flags|=PPosition;
14760 windows->command.attributes.event_mask=ButtonMotionMask | ButtonPressMask |
14761 ButtonReleaseMask | EnterWindowMask | ExposureMask | LeaveWindowMask |
14762 OwnerGrabButtonMask | StructureNotifyMask;
14763 manager_hints->flags=InputHint | StateHint | WindowGroupHint;
14764 manager_hints->input=MagickTrue;
14765 manager_hints->initial_state=NormalState;
14766 manager_hints->window_group=windows->image.id;
14767 XMakeWindow(display,root_window,argv,argc,class_hints,manager_hints,
14768 &windows->command);
14769 windows->command.highlight_stipple=XCreateBitmapFromData(display,
14770 windows->command.id,(
char *) HighlightBitmap,HighlightWidth,
14772 windows->command.shadow_stipple=XCreateBitmapFromData(display,
14773 windows->command.id,(
char *) ShadowBitmap,ShadowWidth,ShadowHeight);
14774 (void) XSetTransientForHint(display,windows->command.id,windows->image.id);
14775 if (windows->command.mapped != MagickFalse)
14776 (void) XMapRaised(display,windows->command.id);
14777 if (resource_info->debug != MagickFalse)
14778 (void) LogMagickEvent(X11Event,GetMagickModule(),
14779 "Window id: 0x%lx (command)",windows->command.id);
14783 XGetWindowInfo(display,visual_info,map_info,pixel,font_info,
14784 resource_info,&windows->widget);
14785 (void) FormatLocaleString(resource_name,MaxTextExtent,
"%s.widget",
14786 resource_info->client_name);
14787 windows->widget.geometry=XGetResourceClass(resource_info->resource_database,
14788 resource_name,
"geometry",(
char *) NULL);
14789 windows->widget.border_width=0;
14790 windows->widget.flags|=PPosition;
14791 windows->widget.attributes.event_mask=ButtonMotionMask | ButtonPressMask |
14792 ButtonReleaseMask | EnterWindowMask | ExposureMask | KeyPressMask |
14793 KeyReleaseMask | LeaveWindowMask | OwnerGrabButtonMask |
14794 StructureNotifyMask;
14795 manager_hints->flags=InputHint | StateHint | WindowGroupHint;
14796 manager_hints->input=MagickTrue;
14797 manager_hints->initial_state=NormalState;
14798 manager_hints->window_group=windows->image.id;
14799 XMakeWindow(display,root_window,argv,argc,class_hints,manager_hints,
14801 windows->widget.highlight_stipple=XCreateBitmapFromData(display,
14802 windows->widget.id,(
char *) HighlightBitmap,HighlightWidth,HighlightHeight);
14803 windows->widget.shadow_stipple=XCreateBitmapFromData(display,
14804 windows->widget.id,(
char *) ShadowBitmap,ShadowWidth,ShadowHeight);
14805 (void) XSetTransientForHint(display,windows->widget.id,windows->image.id);
14806 if (resource_info->debug != MagickFalse)
14807 (void) LogMagickEvent(X11Event,GetMagickModule(),
14808 "Window id: 0x%lx (widget)",windows->widget.id);
14812 XGetWindowInfo(display,visual_info,map_info,pixel,font_info,
14813 resource_info,&windows->popup);
14814 windows->popup.border_width=0;
14815 windows->popup.flags|=PPosition;
14816 windows->popup.attributes.event_mask=ButtonMotionMask | ButtonPressMask |
14817 ButtonReleaseMask | EnterWindowMask | ExposureMask | KeyPressMask |
14818 KeyReleaseMask | LeaveWindowMask | StructureNotifyMask;
14819 manager_hints->flags=InputHint | StateHint | WindowGroupHint;
14820 manager_hints->input=MagickTrue;
14821 manager_hints->initial_state=NormalState;
14822 manager_hints->window_group=windows->image.id;
14823 XMakeWindow(display,root_window,argv,argc,class_hints,manager_hints,
14825 windows->popup.highlight_stipple=XCreateBitmapFromData(display,
14826 windows->popup.id,(
char *) HighlightBitmap,HighlightWidth,HighlightHeight);
14827 windows->popup.shadow_stipple=XCreateBitmapFromData(display,
14828 windows->popup.id,(
char *) ShadowBitmap,ShadowWidth,ShadowHeight);
14829 (void) XSetTransientForHint(display,windows->popup.id,windows->image.id);
14830 if (resource_info->debug != MagickFalse)
14831 (void) LogMagickEvent(X11Event,GetMagickModule(),
14832 "Window id: 0x%lx (pop up)",windows->popup.id);
14836 XGetWindowInfo(display,visual_info,map_info,pixel,font_info,
14837 resource_info,&windows->magnify);
14838 if (resource_info->use_shared_memory == MagickFalse)
14839 windows->magnify.shared_memory=MagickFalse;
14840 (void) FormatLocaleString(resource_name,MaxTextExtent,
"%s.magnify",
14841 resource_info->client_name);
14842 windows->magnify.geometry=XGetResourceClass(resource_info->resource_database,
14843 resource_name,
"geometry",(
char *) NULL);
14844 (void) FormatLocaleString(windows->magnify.name,MaxTextExtent,
"Magnify %uX",
14845 resource_info->magnify);
14846 if (windows->magnify.cursor != (Cursor) NULL)
14847 (
void) XFreeCursor(display,windows->magnify.cursor);
14848 windows->magnify.cursor=XMakeCursor(display,windows->image.id,
14849 map_info->colormap,resource_info->background_color,
14850 resource_info->foreground_color);
14851 if (windows->magnify.cursor == (Cursor) NULL)
14852 ThrowXWindowFatalException(XServerFatalError,
"UnableToCreateCursor",
14853 display_image->filename);
14854 windows->magnify.width=MagnifySize;
14855 windows->magnify.height=MagnifySize;
14856 windows->magnify.flags|=PPosition;
14857 windows->magnify.min_width=MagnifySize;
14858 windows->magnify.min_height=MagnifySize;
14859 windows->magnify.width_inc=MagnifySize;
14860 windows->magnify.height_inc=MagnifySize;
14861 windows->magnify.data=resource_info->magnify;
14862 windows->magnify.attributes.cursor=windows->magnify.cursor;
14863 windows->magnify.attributes.event_mask=ButtonPressMask | ButtonReleaseMask |
14864 ExposureMask | KeyPressMask | KeyReleaseMask | OwnerGrabButtonMask |
14865 StructureNotifyMask;
14866 manager_hints->flags=InputHint | StateHint | WindowGroupHint;
14867 manager_hints->input=MagickTrue;
14868 manager_hints->initial_state=NormalState;
14869 manager_hints->window_group=windows->image.id;
14870 XMakeWindow(display,root_window,argv,argc,class_hints,manager_hints,
14871 &windows->magnify);
14872 if (resource_info->debug != MagickFalse)
14873 (void) LogMagickEvent(X11Event,GetMagickModule(),
14874 "Window id: 0x%lx (magnify)",windows->magnify.id);
14875 (void) XSetTransientForHint(display,windows->magnify.id,windows->image.id);
14879 XGetWindowInfo(display,visual_info,map_info,pixel,font_info,
14880 resource_info,&windows->pan);
14881 (void) CloneString(&windows->pan.name,
"Pan Icon");
14882 windows->pan.width=windows->icon.width;
14883 windows->pan.height=windows->icon.height;
14884 (void) FormatLocaleString(resource_name,MaxTextExtent,
"%s.pan",
14885 resource_info->client_name);
14886 windows->pan.geometry=XGetResourceClass(resource_info->resource_database,
14887 resource_name,
"geometry",(
char *) NULL);
14888 (void) XParseGeometry(windows->pan.geometry,&windows->pan.x,&windows->pan.y,
14889 &windows->pan.width,&windows->pan.height);
14890 windows->pan.flags|=PPosition;
14891 windows->pan.immutable=MagickTrue;
14892 windows->pan.attributes.event_mask=ButtonMotionMask | ButtonPressMask |
14893 ButtonReleaseMask | ExposureMask | KeyPressMask | KeyReleaseMask |
14894 StructureNotifyMask;
14895 manager_hints->flags=InputHint | StateHint | WindowGroupHint;
14896 manager_hints->input=MagickFalse;
14897 manager_hints->initial_state=NormalState;
14898 manager_hints->window_group=windows->image.id;
14899 XMakeWindow(display,root_window,argv,argc,class_hints,manager_hints,
14901 if (resource_info->debug != MagickFalse)
14902 (void) LogMagickEvent(X11Event,GetMagickModule(),
"Window id: 0x%lx (pan)",
14904 (void) XSetTransientForHint(display,windows->pan.id,windows->image.id);
14905 if (windows->info.mapped != MagickFalse)
14906 (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
14907 if ((windows->image.mapped == MagickFalse) ||
14908 (windows->backdrop.id != (Window) NULL))
14909 (
void) XMapWindow(display,windows->image.id);
14913 if (warning_handler == (WarningHandler) NULL)
14915 warning_handler=resource_info->display_warnings ?
14916 SetErrorHandler(XWarning) : SetErrorHandler((ErrorHandler) NULL);
14917 warning_handler=resource_info->display_warnings ?
14918 SetWarningHandler(XWarning) : SetWarningHandler((WarningHandler) NULL);
14923 windows->image.x=0;
14924 windows->image.y=0;
14925 windows->magnify.shape=MagickFalse;
14926 width=(
unsigned int) display_image->columns;
14927 height=(
unsigned int) display_image->rows;
14928 if ((display_image->columns != width) || (display_image->rows != height))
14929 ThrowXWindowFatalException(XServerFatalError,
"UnableToCreateXImage",
14930 display_image->filename);
14931 status=XMakeImage(display,resource_info,&windows->image,display_image,
14933 if (status == MagickFalse)
14934 ThrowXWindowFatalException(XServerFatalError,
"UnableToCreateXImage",
14935 display_image->filename);
14936 status=XMakeImage(display,resource_info,&windows->magnify,(
Image *) NULL,
14937 windows->magnify.width,windows->magnify.height);
14938 if (status == MagickFalse)
14939 ThrowXWindowFatalException(XServerFatalError,
"UnableToCreateXImage",
14940 display_image->filename);
14941 if (windows->magnify.mapped != MagickFalse)
14942 (void) XMapRaised(display,windows->magnify.id);
14943 if (windows->pan.mapped != MagickFalse)
14944 (void) XMapRaised(display,windows->pan.id);
14945 windows->image.window_changes.width=(int) display_image->columns;
14946 windows->image.window_changes.height=(int) display_image->rows;
14947 (void) XConfigureImage(display,resource_info,windows,display_image);
14948 (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
14949 (void) XSync(display,MagickFalse);
14953 delay=display_image->delay/MagickMax(display_image->ticks_per_second,1L);
14954 timer=GetMagickTime()+(delay == 0 ? 1 : delay)+1;
14956 if (resource_info->update != MagickFalse)
14964 status=GetPathAttributes(display_image->filename,&attributes);
14965 if (status != MagickFalse)
14966 update_time=attributes.st_mtime;
14968 *state&=(~FormerImageState);
14969 *state&=(~MontageImageState);
14970 *state&=(~NextImageState);
14976 if (windows->image.mapped != MagickFalse)
14977 if ((display_image->delay != 0) || (resource_info->update != 0))
14979 if (timer < GetMagickTime())
14981 if (resource_info->update == MagickFalse)
14982 *state|=NextImageState | ExitState;
14991 status=GetPathAttributes(display_image->filename,&attributes);
14992 if (status != MagickFalse)
14993 if (update_time != attributes.st_mtime)
14998 (void) FormatLocaleString(
14999 resource_info->image_info->filename,MaxTextExtent,
15000 "%s:%s",display_image->magick,
15001 display_image->filename);
15002 nexus=ReadImage(resource_info->image_info,
15003 &display_image->exception);
15004 if (nexus != (
Image *) NULL)
15005 *state|=NextImageState | ExitState;
15007 delay=display_image->delay/MagickMax(
15008 display_image->ticks_per_second,1L);
15009 timer=GetMagickTime()+(delay == 0 ? 1 : delay)+1;
15012 if (XEventsQueued(display,QueuedAfterFlush) == 0)
15017 XDelay(display,SuspendTime << 2);
15021 timestamp=GetMagickTime();
15022 (void) XNextEvent(display,&event);
15023 if (windows->image.stasis == MagickFalse)
15024 windows->image.stasis=(GetMagickTime()-timestamp) > 0 ?
15025 MagickTrue : MagickFalse;
15026 if (windows->magnify.stasis == MagickFalse)
15027 windows->magnify.stasis=(GetMagickTime()-timestamp) > 0 ?
15028 MagickTrue : MagickFalse;
15029 if (event.xany.window == windows->command.id)
15034 id=XCommandWidget(display,windows,CommandMenu,&event);
15037 (void) CopyMagickString(command,CommandMenu[
id],MaxTextExtent);
15038 command_type=CommandMenus[id];
15039 if (
id < MagickMenus)
15044 entry=XMenuWidget(display,windows,CommandMenu[
id],Menus[
id],
15048 (void) CopyMagickString(command,Menus[
id][entry],MaxTextExtent);
15049 command_type=Commands[id][entry];
15051 if (command_type != NullCommand)
15052 nexus=XMagickCommand(display,resource_info,windows,command_type,
15056 switch (event.type)
15060 if (resource_info->debug != MagickFalse)
15061 (void) LogMagickEvent(X11Event,GetMagickModule(),
15062 "Button Press: 0x%lx %u +%d+%d",
event.xbutton.window,
15063 event.xbutton.button,
event.xbutton.x,
event.xbutton.y);
15064 if ((event.xbutton.button == Button3) &&
15065 (
event.xbutton.state & Mod1Mask))
15070 event.xbutton.button=Button2;
15071 event.xbutton.state&=(~Mod1Mask);
15073 if (event.xbutton.window == windows->backdrop.id)
15075 (void) XSetInputFocus(display,event.xbutton.window,RevertToParent,
15076 event.xbutton.time);
15079 if (event.xbutton.window == windows->image.id)
15081 switch (event.xbutton.button)
15085 if (resource_info->immutable)
15090 entry=XMenuWidget(display,windows,
"Commands",VirtualMenu,
15093 nexus=XMagickCommand(display,resource_info,windows,
15094 VirtualCommands[entry],&display_image);
15100 if (windows->command.mapped != MagickFalse)
15101 (void) XWithdrawWindow(display,windows->command.id,
15102 windows->command.screen);
15105 (void) XCommandWidget(display,windows,CommandMenu,
15107 (void) XMapRaised(display,windows->command.id);
15116 (void) XMagickCommand(display,resource_info,windows,ZoomCommand,
15118 XMagnifyImage(display,windows,&event);
15123 if (resource_info->immutable)
15128 entry=XMenuWidget(display,windows,
"Commands",VirtualMenu,
15131 nexus=XMagickCommand(display,resource_info,windows,
15132 VirtualCommands[entry],&display_image);
15135 if (display_image->montage != (
char *) NULL)
15140 nexus=XTileImage(display,resource_info,windows,
15141 display_image,&event);
15142 if (nexus != (
Image *) NULL)
15143 *state|=MontageImageState | NextImageState | ExitState;
15144 vid_info.x=(
short int) windows->image.x;
15145 vid_info.y=(
short int) windows->image.y;
15151 entry=XMenuWidget(display,windows,
"Short Cuts",ShortCutsMenu,
15154 nexus=XMagickCommand(display,resource_info,windows,
15155 ShortCutsCommands[entry],&display_image);
15163 XTranslateImage(display,windows,*image,XK_Up);
15171 XTranslateImage(display,windows,*image,XK_Down);
15179 if (event.xbutton.window == windows->magnify.id)
15182 *
const MagnifyMenu[] =
15199 MagnifyCommands[] =
15214 factor=XMenuWidget(display,windows,
"Magnify",MagnifyMenu,command);
15216 XMagnifyWindowCommand(display,windows,0,MagnifyCommands[factor]);
15219 if (event.xbutton.window == windows->pan.id)
15221 switch (event.xbutton.button)
15228 XTranslateImage(display,windows,*image,XK_Up);
15236 XTranslateImage(display,windows,*image,XK_Down);
15241 XPanImage(display,windows,&event);
15247 delay=display_image->delay/MagickMax(display_image->ticks_per_second,
15249 timer=GetMagickTime()+(delay == 0 ? 1 : delay)+1;
15252 case ButtonRelease:
15254 if (resource_info->debug != MagickFalse)
15255 (void) LogMagickEvent(X11Event,GetMagickModule(),
15256 "Button Release: 0x%lx %u +%d+%d",
event.xbutton.window,
15257 event.xbutton.button,
event.xbutton.x,
event.xbutton.y);
15260 case ClientMessage:
15262 if (resource_info->debug != MagickFalse)
15263 (void) LogMagickEvent(X11Event,GetMagickModule(),
15264 "Client Message: 0x%lx 0x%lx %d 0x%lx",
event.xclient.window,
15265 event.xclient.message_type,
event.xclient.format,(
unsigned long)
15266 event.xclient.data.l[0]);
15267 if (event.xclient.message_type == windows->im_protocols)
15269 if (*event.xclient.data.l == (
long) windows->im_update_widget)
15271 (void) CloneString(&windows->command.name,MagickTitle);
15272 windows->command.data=MagickMenus;
15273 (void) XCommandWidget(display,windows,CommandMenu,
15277 if (*event.xclient.data.l == (
long) windows->im_update_colormap)
15282 for (i=0; i < (int) number_windows; i++)
15284 if (magick_windows[i]->
id == windows->icon.id)
15286 context_values.background=pixel->background_color.pixel;
15287 context_values.foreground=pixel->foreground_color.pixel;
15288 (void) XChangeGC(display,magick_windows[i]->annotate_context,
15289 context_mask,&context_values);
15290 (void) XChangeGC(display,magick_windows[i]->widget_context,
15291 context_mask,&context_values);
15292 context_values.background=pixel->foreground_color.pixel;
15293 context_values.foreground=pixel->background_color.pixel;
15294 context_values.plane_mask=context_values.background ^
15295 context_values.foreground;
15296 (void) XChangeGC(display,magick_windows[i]->highlight_context,
15297 (
size_t) (context_mask | GCPlaneMask),
15299 magick_windows[i]->attributes.background_pixel=
15300 pixel->background_color.pixel;
15301 magick_windows[i]->attributes.border_pixel=
15302 pixel->border_color.pixel;
15303 magick_windows[i]->attributes.colormap=map_info->colormap;
15304 (void) XChangeWindowAttributes(display,magick_windows[i]->
id,
15305 (
unsigned long) magick_windows[i]->mask,
15306 &magick_windows[i]->attributes);
15308 if (windows->pan.mapped != MagickFalse)
15310 (void) XSetWindowBackgroundPixmap(display,windows->pan.id,
15311 windows->pan.pixmap);
15312 (void) XClearWindow(display,windows->pan.id);
15313 XDrawPanRectangle(display,windows);
15315 if (windows->backdrop.id != (Window) NULL)
15316 (void) XInstallColormap(display,map_info->colormap);
15319 if (*event.xclient.data.l == (
long) windows->im_former_image)
15321 *state|=FormerImageState | ExitState;
15324 if (*event.xclient.data.l == (
long) windows->im_next_image)
15326 *state|=NextImageState | ExitState;
15329 if (*event.xclient.data.l == (
long) windows->im_retain_colors)
15331 *state|=RetainColorsState;
15334 if (*event.xclient.data.l == (
long) windows->im_exit)
15341 if (event.xclient.message_type == windows->dnd_protocols)
15361 if ((*event.xclient.data.l != 2) && (*
event.xclient.data.l != 128))
15363 selection=XInternAtom(display,
"DndSelection",MagickFalse);
15364 status=XGetWindowProperty(display,root_window,selection,0L,(
long)
15365 MaxTextExtent,MagickFalse,(Atom) AnyPropertyType,&type,&format,
15366 &length,&after,&data);
15367 if ((status != Success) || (length == 0))
15369 if (*event.xclient.data.l == 2)
15374 (void) CopyMagickString(resource_info->image_info->filename,
15375 (
char *) data,MaxTextExtent);
15382 if (strncmp((
char *) data,
"file:", 5) != 0)
15384 (void) XFree((
void *) data);
15387 (void) CopyMagickString(resource_info->image_info->filename,
15388 ((
char *) data)+5,MaxTextExtent);
15390 nexus=ReadImage(resource_info->image_info,
15391 &display_image->exception);
15392 CatchException(&display_image->exception);
15393 if (nexus != (
Image *) NULL)
15394 *state|=NextImageState | ExitState;
15395 (void) XFree((
void *) data);
15401 if (event.xclient.message_type != windows->wm_protocols)
15403 if (*event.xclient.data.l != (
long) windows->wm_delete_window)
15405 (void) XWithdrawWindow(display,event.xclient.window,
15406 visual_info->screen);
15407 if (event.xclient.window == windows->image.id)
15412 if (event.xclient.window == windows->pan.id)
15417 windows->image.window_changes.width=windows->image.ximage->width;
15418 windows->image.window_changes.height=windows->image.ximage->height;
15419 (void) XConfigureImage(display,resource_info,windows,
15424 case ConfigureNotify:
15426 if (resource_info->debug != MagickFalse)
15427 (void) LogMagickEvent(X11Event,GetMagickModule(),
15428 "Configure Notify: 0x%lx %dx%d+%d+%d %d",
event.xconfigure.window,
15429 event.xconfigure.width,
event.xconfigure.height,
event.xconfigure.x,
15430 event.xconfigure.y,
event.xconfigure.send_event);
15431 if (event.xconfigure.window == windows->image.id)
15436 if (event.xconfigure.send_event != 0)
15444 if (windows->command.geometry == (
char *) NULL)
15445 if (windows->command.mapped == MagickFalse)
15447 windows->command.x=
event.xconfigure.x-
15448 windows->command.width-25;
15449 windows->command.y=
event.xconfigure.y;
15450 XConstrainWindowPosition(display,&windows->command);
15451 window_changes.x=windows->command.x;
15452 window_changes.y=windows->command.y;
15453 (void) XReconfigureWMWindow(display,windows->command.id,
15454 windows->command.screen,(
unsigned int) (CWX | CWY),
15457 if (windows->widget.geometry == (
char *) NULL)
15458 if (windows->widget.mapped == MagickFalse)
15460 windows->widget.x=
event.xconfigure.x+
15461 event.xconfigure.width/10;
15462 windows->widget.y=
event.xconfigure.y+
15463 event.xconfigure.height/10;
15464 XConstrainWindowPosition(display,&windows->widget);
15465 window_changes.x=windows->widget.x;
15466 window_changes.y=windows->widget.y;
15467 (void) XReconfigureWMWindow(display,windows->widget.id,
15468 windows->widget.screen,(
unsigned int) (CWX | CWY),
15471 if (windows->magnify.geometry == (
char *) NULL)
15472 if (windows->magnify.mapped == MagickFalse)
15474 windows->magnify.x=
event.xconfigure.x+
15475 event.xconfigure.width+25;
15476 windows->magnify.y=
event.xconfigure.y;
15477 XConstrainWindowPosition(display,&windows->magnify);
15478 window_changes.x=windows->magnify.x;
15479 window_changes.y=windows->magnify.y;
15480 (void) XReconfigureWMWindow(display,windows->magnify.id,
15481 windows->magnify.screen,(
unsigned int) (CWX | CWY),
15484 if (windows->pan.geometry == (
char *) NULL)
15485 if (windows->pan.mapped == MagickFalse)
15487 windows->pan.x=
event.xconfigure.x+
15488 event.xconfigure.width+25;
15489 windows->pan.y=
event.xconfigure.y+
15490 windows->magnify.height+50;
15491 XConstrainWindowPosition(display,&windows->pan);
15492 window_changes.x=windows->pan.x;
15493 window_changes.y=windows->pan.y;
15494 (void) XReconfigureWMWindow(display,windows->pan.id,
15495 windows->pan.screen,(
unsigned int) (CWX | CWY),
15499 if ((event.xconfigure.width == (
int) windows->image.width) &&
15500 (event.xconfigure.height == (
int) windows->image.height))
15502 windows->image.width=(
unsigned int) event.xconfigure.width;
15503 windows->image.height=(
unsigned int) event.xconfigure.height;
15504 windows->image.x=0;
15505 windows->image.y=0;
15506 if (display_image->montage != (
char *) NULL)
15508 windows->image.x=vid_info.x;
15509 windows->image.y=vid_info.y;
15511 if ((windows->image.mapped != MagickFalse) &&
15512 (windows->image.stasis != MagickFalse))
15517 windows->image.window_changes.width=
event.xconfigure.width;
15518 windows->image.window_changes.height=
event.xconfigure.height;
15519 (void) XConfigureImage(display,resource_info,windows,
15525 if ((event.xconfigure.width < windows->image.ximage->width) ||
15526 (
event.xconfigure.height < windows->image.ximage->height))
15528 (void) XMapRaised(display,windows->pan.id);
15529 XDrawPanRectangle(display,windows);
15532 if (windows->pan.mapped != MagickFalse)
15533 (void) XWithdrawWindow(display,windows->pan.id,
15534 windows->pan.screen);
15537 if (event.xconfigure.window == windows->magnify.id)
15545 windows->magnify.width=(
unsigned int) event.xconfigure.width;
15546 windows->magnify.height=(
unsigned int) event.xconfigure.height;
15547 if (windows->magnify.mapped == MagickFalse)
15550 while ((
int) magnify <= event.xconfigure.width)
15552 while ((
int) magnify <= event.xconfigure.height)
15555 if (((
int) magnify != event.xconfigure.width) ||
15556 ((
int) magnify != event.xconfigure.height))
15558 window_changes.width=(int) magnify;
15559 window_changes.height=(int) magnify;
15560 (void) XReconfigureWMWindow(display,windows->magnify.id,
15561 windows->magnify.screen,(
unsigned int) (CWWidth | CWHeight),
15565 if ((windows->magnify.mapped != MagickFalse) &&
15566 (windows->magnify.stasis != MagickFalse))
15568 status=XMakeImage(display,resource_info,&windows->magnify,
15569 display_image,windows->magnify.width,windows->magnify.height);
15570 XMakeMagnifyImage(display,windows);
15574 if ((windows->magnify.mapped != MagickFalse) &&
15575 (event.xconfigure.window == windows->pan.id))
15580 if (event.xconfigure.send_event != 0)
15582 windows->pan.x=
event.xconfigure.x;
15583 windows->pan.y=
event.xconfigure.y;
15585 windows->pan.width=(
unsigned int) event.xconfigure.width;
15586 windows->pan.height=(
unsigned int) event.xconfigure.height;
15589 if (event.xconfigure.window == windows->icon.id)
15594 windows->icon.width=(
unsigned int) event.xconfigure.width;
15595 windows->icon.height=(
unsigned int) event.xconfigure.height;
15600 case DestroyNotify:
15605 if (resource_info->debug != MagickFalse)
15606 (void) LogMagickEvent(X11Event,GetMagickModule(),
15607 "Destroy Notify: 0x%lx",
event.xdestroywindow.window);
15608 if (event.xdestroywindow.window == windows->group_leader.id)
15620 if (map_info->colormap != XDefaultColormap(display,visual_info->screen))
15621 if (event.xcrossing.mode != NotifyUngrab)
15622 XInstallColormap(display,map_info->colormap);
15627 if (resource_info->debug != MagickFalse)
15628 (void) LogMagickEvent(X11Event,GetMagickModule(),
15629 "Expose: 0x%lx %dx%d+%d+%d",
event.xexpose.window,
15630 event.xexpose.width,
event.xexpose.height,
event.xexpose.x,
15635 if ((event.xexpose.window == windows->image.id) &&
15636 (windows->image.mapped != MagickFalse))
15638 XRefreshWindow(display,&windows->image,&event);
15639 delay=display_image->delay/MagickMax(
15640 display_image->ticks_per_second,1L);
15641 timer=GetMagickTime()+(delay == 0 ? 1 : delay)+1;
15644 if ((event.xexpose.window == windows->magnify.id) &&
15645 (windows->magnify.mapped != MagickFalse))
15647 XMakeMagnifyImage(display,windows);
15650 if (event.xexpose.window == windows->pan.id)
15652 XDrawPanRectangle(display,windows);
15655 if (event.xexpose.window == windows->icon.id)
15657 XRefreshWindow(display,&windows->icon,&event);
15670 length=XLookupString((XKeyEvent *) &event.xkey,command,(
int)
15671 sizeof(command),&key_symbol,(XComposeStatus *) NULL);
15672 *(command+length)=
'\0';
15673 if (resource_info->debug != MagickFalse)
15674 (void) LogMagickEvent(X11Event,GetMagickModule(),
15675 "Key press: %d 0x%lx (%s)",
event.xkey.state,(
unsigned long)
15676 key_symbol,command);
15677 if (event.xkey.window == windows->image.id)
15679 command_type=XImageWindowCommand(display,resource_info,windows,
15680 event.xkey.state,key_symbol,&display_image);
15681 if (command_type != NullCommand)
15682 nexus=XMagickCommand(display,resource_info,windows,command_type,
15685 if (event.xkey.window == windows->magnify.id)
15686 XMagnifyWindowCommand(display,windows,event.xkey.state,key_symbol);
15687 if (event.xkey.window == windows->pan.id)
15689 if ((key_symbol == XK_q) || (key_symbol == XK_Escape))
15690 (void) XWithdrawWindow(display,windows->pan.id,
15691 windows->pan.screen);
15693 if ((key_symbol == XK_F1) || (key_symbol == XK_Help))
15694 XTextViewHelp(display,resource_info,windows,MagickFalse,
15695 "Help Viewer - Image Pan",ImagePanHelp);
15697 XTranslateImage(display,windows,*image,key_symbol);
15699 delay=display_image->delay/MagickMax(
15700 display_image->ticks_per_second,1L);
15701 timer=GetMagickTime()+(delay == 0 ? 1 : delay)+1;
15709 (void) XLookupString((XKeyEvent *) &
event.xkey,command,(int)
15710 sizeof(command),&key_symbol,(XComposeStatus *) NULL);
15711 if (resource_info->debug != MagickFalse)
15712 (void) LogMagickEvent(X11Event,GetMagickModule(),
15713 "Key release: 0x%lx (%c)",(
unsigned long) key_symbol,*command);
15721 if (map_info->colormap != XDefaultColormap(display,visual_info->screen))
15722 if (event.xcrossing.mode != NotifyUngrab)
15723 XUninstallColormap(display,map_info->colormap);
15728 if (resource_info->debug != MagickFalse)
15729 (void) LogMagickEvent(X11Event,GetMagickModule(),
"Map Notify: 0x%lx",
15730 event.xmap.window);
15731 if (event.xmap.window == windows->backdrop.id)
15733 (void) XSetInputFocus(display,event.xmap.window,RevertToParent,
15735 windows->backdrop.mapped=MagickTrue;
15738 if (event.xmap.window == windows->image.id)
15740 if (windows->backdrop.id != (Window) NULL)
15741 (
void) XInstallColormap(display,map_info->colormap);
15742 if (LocaleCompare(display_image->magick,
"LOGO") == 0)
15744 if (LocaleCompare(display_image->filename,
"LOGO") == 0)
15745 nexus=XOpenImage(display,resource_info,windows,MagickFalse);
15747 if (((
int) windows->image.width < windows->image.ximage->width) ||
15748 ((
int) windows->image.height < windows->image.ximage->height))
15749 (void) XMapRaised(display,windows->pan.id);
15750 windows->image.mapped=MagickTrue;
15753 if (event.xmap.window == windows->magnify.id)
15755 XMakeMagnifyImage(display,windows);
15756 windows->magnify.mapped=MagickTrue;
15757 (void) XWithdrawWindow(display,windows->info.id,
15758 windows->info.screen);
15761 if (event.xmap.window == windows->pan.id)
15763 XMakePanImage(display,resource_info,windows,display_image);
15764 windows->pan.mapped=MagickTrue;
15767 if (event.xmap.window == windows->info.id)
15769 windows->info.mapped=MagickTrue;
15772 if (event.xmap.window == windows->icon.id)
15780 taint=display_image->taint;
15781 XMakeStandardColormap(display,icon_visual,icon_resources,
15782 display_image,icon_map,icon_pixel);
15783 (void) XMakeImage(display,icon_resources,&windows->icon,
15784 display_image,windows->icon.width,windows->icon.height);
15785 display_image->taint=taint;
15786 (void) XSetWindowBackgroundPixmap(display,windows->icon.id,
15787 windows->icon.pixmap);
15788 (void) XClearWindow(display,windows->icon.id);
15789 (void) XWithdrawWindow(display,windows->info.id,
15790 windows->info.screen);
15791 windows->icon.mapped=MagickTrue;
15794 if (event.xmap.window == windows->command.id)
15796 windows->command.mapped=MagickTrue;
15799 if (event.xmap.window == windows->popup.id)
15801 windows->popup.mapped=MagickTrue;
15804 if (event.xmap.window == windows->widget.id)
15806 windows->widget.mapped=MagickTrue;
15811 case MappingNotify:
15813 (void) XRefreshKeyboardMapping(&event.xmapping);
15818 case PropertyNotify:
15834 if (resource_info->debug != MagickFalse)
15835 (void) LogMagickEvent(X11Event,GetMagickModule(),
15836 "Property Notify: 0x%lx 0x%lx %d",
event.xproperty.window,
15837 event.xproperty.atom,
event.xproperty.state);
15838 if (event.xproperty.atom != windows->im_remote_command)
15843 status=XGetWindowProperty(display,event.xproperty.window,
15844 event.xproperty.atom,0L,(
long) MaxTextExtent,MagickFalse,(Atom)
15845 AnyPropertyType,&type,&format,&length,&after,&data);
15846 if ((status != Success) || (length == 0))
15848 if (LocaleCompare((
char *) data,
"-quit") == 0)
15850 XClientMessage(display,windows->image.id,windows->im_protocols,
15851 windows->im_exit,CurrentTime);
15852 (void) XFree((
void *) data);
15855 (void) CopyMagickString(resource_info->image_info->filename,
15856 (
char *) data,MaxTextExtent);
15857 (void) XFree((
void *) data);
15858 nexus=ReadImage(resource_info->image_info,&display_image->exception);
15859 CatchException(&display_image->exception);
15860 if (nexus != (
Image *) NULL)
15861 *state|=NextImageState | ExitState;
15864 case ReparentNotify:
15866 if (resource_info->debug != MagickFalse)
15867 (void) LogMagickEvent(X11Event,GetMagickModule(),
15868 "Reparent Notify: 0x%lx=>0x%lx",
event.xreparent.parent,
15869 event.xreparent.window);
15874 if (resource_info->debug != MagickFalse)
15875 (void) LogMagickEvent(X11Event,GetMagickModule(),
15876 "Unmap Notify: 0x%lx",
event.xunmap.window);
15877 if (event.xunmap.window == windows->backdrop.id)
15879 windows->backdrop.mapped=MagickFalse;
15882 if (event.xunmap.window == windows->image.id)
15884 windows->image.mapped=MagickFalse;
15887 if (event.xunmap.window == windows->magnify.id)
15889 windows->magnify.mapped=MagickFalse;
15892 if (event.xunmap.window == windows->pan.id)
15894 windows->pan.mapped=MagickFalse;
15897 if (event.xunmap.window == windows->info.id)
15899 windows->info.mapped=MagickFalse;
15902 if (event.xunmap.window == windows->icon.id)
15904 if (map_info->colormap == icon_map->colormap)
15905 XConfigureImageColormap(display,resource_info,windows,
15907 (void) XFreeStandardColormap(display,icon_visual,icon_map,
15909 windows->icon.mapped=MagickFalse;
15912 if (event.xunmap.window == windows->command.id)
15914 windows->command.mapped=MagickFalse;
15917 if (event.xunmap.window == windows->popup.id)
15919 if (windows->backdrop.id != (Window) NULL)
15920 (
void) XSetInputFocus(display,windows->image.id,RevertToParent,
15922 windows->popup.mapped=MagickFalse;
15925 if (event.xunmap.window == windows->widget.id)
15927 if (windows->backdrop.id != (Window) NULL)
15928 (void) XSetInputFocus(display,windows->image.id,RevertToParent,
15930 windows->widget.mapped=MagickFalse;
15937 if (resource_info->debug != MagickFalse)
15938 (void) LogMagickEvent(X11Event,GetMagickModule(),
"Event type: %d",
15943 }
while (!(*state & ExitState));
15944 if ((*state & ExitState) == 0)
15945 (
void) XMagickCommand(display,resource_info,windows,FreeBuffersCommand,
15948 if (resource_info->confirm_edit != MagickFalse)
15953 if ((resource_info->immutable == MagickFalse) &&
15954 (display_image->taint != MagickFalse))
15959 status=XConfirmWidget(display,windows,
"Your image changed.",
15960 "Do you want to save it");
15962 *state&=(~ExitState);
15965 (void) XMagickCommand(display,resource_info,windows,SaveCommand,
15969 if ((windows->visual_info->klass == GrayScale) ||
15970 (windows->visual_info->klass == PseudoColor) ||
15971 (windows->visual_info->klass == DirectColor))
15976 if (windows->info.mapped != MagickFalse)
15977 (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
15978 if (windows->magnify.mapped != MagickFalse)
15979 (void) XWithdrawWindow(display,windows->magnify.id,
15980 windows->magnify.screen);
15981 if (windows->command.mapped != MagickFalse)
15982 (void) XWithdrawWindow(display,windows->command.id,
15983 windows->command.screen);
15985 if (windows->pan.mapped != MagickFalse)
15986 (void) XWithdrawWindow(display,windows->pan.id,windows->pan.screen);
15987 if (resource_info->backdrop == MagickFalse)
15988 if (windows->backdrop.mapped)
15990 (void) XWithdrawWindow(display,windows->backdrop.id,
15991 windows->backdrop.screen);
15992 (void) XDestroyWindow(display,windows->backdrop.id);
15993 windows->backdrop.id=(Window) NULL;
15994 (void) XWithdrawWindow(display,windows->image.id,
15995 windows->image.screen);
15996 (void) XDestroyWindow(display,windows->image.id);
15997 windows->image.id=(Window) NULL;
15999 XSetCursorState(display,windows,MagickTrue);
16000 XCheckRefreshWindows(display,windows);
16001 if (((*state & FormerImageState) != 0) || ((*state & NextImageState) != 0))
16002 *state&=(~ExitState);
16003 if (*state & ExitState)
16008 (void) XFreeStandardColormap(display,icon_visual,icon_map,icon_pixel);
16009 if (resource_info->map_type == (
char *) NULL)
16010 (
void) XFreeStandardColormap(display,visual_info,map_info,pixel);
16014 if (resource_info->copy_image != (
Image *) NULL)
16015 resource_info->copy_image=DestroyImage(resource_info->copy_image);
16016 DestroyXResources();
16018 (void) XSync(display,MagickFalse);
16022 (void) SetErrorHandler(warning_handler);
16023 (void) SetWarningHandler(warning_handler);
16027 directory=getcwd(working_directory,MaxTextExtent);
16033 if (*resource_info->home_directory ==
'\0')
16034 (void) CopyMagickString(resource_info->home_directory,
".",MaxTextExtent);
16035 status=chdir(resource_info->home_directory);
16037 (void) ThrowMagickException(&display_image->exception,GetMagickModule(),
16038 FileOpenError,
"UnableToOpenFile",
"%s",resource_info->home_directory);
16040 *image=display_image;
16072MagickExport MagickBooleanType DisplayImages(
const ImageInfo *image_info,
16075 assert(image_info != (
const ImageInfo *) NULL);
16076 assert(image_info->signature == MagickCoreSignature);
16077 assert(image != (
Image *) NULL);
16078 assert(image->signature == MagickCoreSignature);
16079 if (IsEventLogging() != MagickFalse)
16080 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
16082 (void) ThrowMagickException(&image->exception,GetMagickModule(),
16083 MissingDelegateError,
"DelegateLibrarySupportNotBuiltIn",
"`%s' (X11)",
16085 return(MagickFalse);
16118MagickExport MagickBooleanType RemoteDisplayCommand(
const ImageInfo *image_info,
16119 const char *window,
const char *filename,
ExceptionInfo *exception)
16121 assert(image_info != (
const ImageInfo *) NULL);
16122 assert(image_info->signature == MagickCoreSignature);
16123 assert(filename != (
char *) NULL);
16124 if (IsEventLogging() != MagickFalse)
16125 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",filename);
16127 (void) ThrowMagickException(exception,GetMagickModule(),MissingDelegateError,
16128 "DelegateLibrarySupportNotBuiltIn",
"`%s' (X11)",image_info->filename);
16129 return(MagickFalse);