42 #include "magick/studio.h"
43 #include "magick/artifact.h"
44 #include "magick/attribute.h"
45 #include "magick/blob.h"
46 #include "magick/cache.h"
47 #include "magick/channel.h"
48 #include "magick/client.h"
49 #include "magick/color.h"
50 #include "magick/colorspace.h"
51 #include "magick/composite.h"
52 #include "magick/constitute.h"
53 #include "magick/decorate.h"
54 #include "magick/delegate.h"
55 #include "magick/display.h"
56 #include "magick/display-private.h"
57 #include "magick/distort.h"
58 #include "magick/draw.h"
59 #include "magick/effect.h"
60 #include "magick/enhance.h"
61 #include "magick/exception.h"
62 #include "magick/exception-private.h"
63 #include "magick/fx.h"
64 #include "magick/geometry.h"
65 #include "magick/image.h"
66 #include "magick/image-private.h"
67 #include "magick/list.h"
68 #include "magick/locale-private.h"
69 #include "magick/log.h"
70 #include "magick/magick.h"
71 #include "magick/memory_.h"
72 #include "magick/monitor.h"
73 #include "magick/monitor-private.h"
74 #include "magick/montage.h"
75 #include "magick/nt-base-private.h"
76 #include "magick/option.h"
77 #include "magick/paint.h"
78 #include "magick/pixel.h"
79 #include "magick/pixel-private.h"
80 #include "magick/property.h"
81 #include "magick/quantum.h"
82 #include "magick/resize.h"
83 #include "magick/resource_.h"
84 #include "magick/shear.h"
85 #include "magick/segment.h"
86 #include "magick/statistic.h"
87 #include "magick/string_.h"
88 #include "magick/string-private.h"
89 #include "magick/timer-private.h"
90 #include "magick/transform.h"
91 #include "magick/threshold.h"
92 #include "magick/utility.h"
93 #include "magick/utility-private.h"
94 #include "magick/version.h"
95 #include "magick/visual-effects.h"
96 #include "magick/widget.h"
97 #include "magick/xwindow-private.h"
99 #if defined(MAGICKCORE_X11_DELEGATE)
103 #define MaxColors MagickMin((ssize_t) windows->visual_info->colormap_size,256L)
108 static const unsigned char
111 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55
115 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
119 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
126 ImageAnnotateHelp[] =
128 "In annotate mode, the Command widget has these options:\n"
178 "Choose a font name from the Font Name sub-menu. Additional\n"
179 "font names can be specified with the font browser. You can\n"
180 "change the menu names by setting the X resources font1\n"
183 "Choose a font color from the Font Color sub-menu.\n"
184 "Additional font colors can be specified with the color\n"
185 "browser. You can change the menu colors by setting the X\n"
186 "resources pen1 through pen9.\n"
188 "If you select the color browser and press Grab, you can\n"
189 "choose the font color by moving the pointer to the desired\n"
190 "color on the screen and press any button.\n"
192 "If you choose to rotate the text, choose Rotate Text from the\n"
193 "menu and select an angle. Typically you will only want to\n"
194 "rotate one line of text at a time. Depending on the angle you\n"
195 "choose, subsequent lines may end up overwriting each other.\n"
197 "Choosing a font and its color is optional. The default font\n"
198 "is fixed and the default color is black. However, you must\n"
199 "choose a location to begin entering text and press button 1.\n"
200 "An underscore character will appear at the location of the\n"
201 "pointer. The cursor changes to a pencil to indicate you are\n"
202 "in text mode. To exit immediately, press Dismiss.\n"
204 "In text mode, any key presses will display the character at\n"
205 "the location of the underscore and advance the underscore\n"
206 "cursor. Enter your text and once completed press Apply to\n"
207 "finish your image annotation. To correct errors press BACK\n"
208 "SPACE. To delete an entire line of text, press DELETE. Any\n"
209 "text that exceeds the boundaries of the image window is\n"
210 "automagically continued onto the next line.\n"
212 "The actual color you request for the font is saved in the\n"
213 "image. However, the color that appears in your image window\n"
214 "may be different. For example, on a monochrome screen the\n"
215 "text will appear black or white even if you choose the color\n"
216 "red as the font color. However, the image saved to a file\n"
217 "with -write is written with red lettering. To assure the\n"
218 "correct color text in the final image, any PseudoClass image\n"
219 "is promoted to DirectClass (see miff(5)). To force a\n"
220 "PseudoClass image to remain PseudoClass, use -colors.\n"
224 "In chop mode, the Command widget has these options:\n"
232 "If the you choose the horizontal direction (this the\n"
233 "default), the area of the image between the two horizontal\n"
234 "endpoints of the chop line is removed. Otherwise, the area\n"
235 "of the image between the two vertical endpoints of the chop\n"
238 "Select a location within the image window to begin your chop,\n"
239 "press and hold any button. Next, move the pointer to\n"
240 "another location in the image. As you move a line will\n"
241 "connect the initial location and the pointer. When you\n"
242 "release the button, the area within the image to chop is\n"
243 "determined by which direction you choose from the Command\n"
246 "To cancel the image chopping, move the pointer back to the\n"
247 "starting point of the line and release the button.\n"
249 ImageColorEditHelp[] =
251 "In color edit mode, the Command widget has these options:\n"
292 "Choose a color editing method from the Method sub-menu\n"
293 "of the Command widget. The point method recolors any pixel\n"
294 "selected with the pointer until the button is released. The\n"
295 "replace method recolors any pixel that matches the color of\n"
296 "the pixel you select with a button press. Floodfill recolors\n"
297 "any pixel that matches the color of the pixel you select with\n"
298 "a button press and is a neighbor. Whereas filltoborder recolors\n"
299 "any neighbor pixel that is not the border color. Finally reset\n"
300 "changes the entire image to the designated color.\n"
302 "Next, choose a pixel color from the Pixel Color sub-menu.\n"
303 "Additional pixel colors can be specified with the color\n"
304 "browser. You can change the menu colors by setting the X\n"
305 "resources pen1 through pen9.\n"
307 "Now press button 1 to select a pixel within the image window\n"
308 "to change its color. Additional pixels may be recolored as\n"
309 "prescribed by the method you choose.\n"
311 "If the Magnify widget is mapped, it can be helpful in positioning\n"
312 "your pointer within the image (refer to button 2).\n"
314 "The actual color you request for the pixels is saved in the\n"
315 "image. However, the color that appears in your image window\n"
316 "may be different. For example, on a monochrome screen the\n"
317 "pixel will appear black or white even if you choose the\n"
318 "color red as the pixel color. However, the image saved to a\n"
319 "file with -write is written with red pixels. To assure the\n"
320 "correct color text in the final image, any PseudoClass image\n"
321 "is promoted to DirectClass (see miff(5)). To force a\n"
322 "PseudoClass image to remain PseudoClass, use -colors.\n"
324 ImageCompositeHelp[] =
326 "First a widget window is displayed requesting you to enter an\n"
327 "image name. Press Composite, Grab or type a file name.\n"
328 "Press Cancel if you choose not to create a composite image.\n"
329 "When you choose Grab, move the pointer to the desired window\n"
330 "and press any button.\n"
332 "If the Composite image does not have any matte information,\n"
333 "you are informed and the file browser is displayed again.\n"
334 "Enter the name of a mask image. The image is typically\n"
335 "grayscale and the same size as the composite image. If the\n"
336 "image is not grayscale, it is converted to grayscale and the\n"
337 "resulting intensities are used as matte information.\n"
339 "A small window appears showing the location of the cursor in\n"
340 "the image window. You are now in composite mode. To exit\n"
341 "immediately, press Dismiss. In composite mode, the Command\n"
342 "widget has these options:\n"
368 "Choose a composite operation from the Operators sub-menu of\n"
369 "the Command widget. How each operator behaves is described\n"
370 "below. Image window is the image currently displayed on\n"
371 "your X server and image is the image obtained with the File\n"
374 "Over The result is the union of the two image shapes,\n"
375 " with image obscuring image window in the region of\n"
378 "In The result is simply image cut by the shape of\n"
379 " image window. None of the image data of image\n"
380 " window is in the result.\n"
382 "Out The resulting image is image with the shape of\n"
383 " image window cut out.\n"
385 "Atop The result is the same shape as image 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 Transarent. 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 image image window,\n"
1099 " with image obscuring image window where the image\n"
1100 " shapes overlap. Note this differs from over\n"
1101 " because the portion of image outside image window's\n"
1102 " shape does not appear in the result.\n"
1104 "Xor The result is the image data from both image and\n"
1105 " image window that is outside the overlap region.\n"
1106 " The overlap region is blank.\n"
1108 "Plus The result is just the sum of the image data.\n"
1109 " Output values are cropped to QuantumRange (no overflow).\n"
1110 " This operation is independent of the matte\n"
1113 "Minus The result of image - image window, with underflow\n"
1114 " cropped to zero.\n"
1116 "Add The result of image + image window, with overflow\n"
1117 " wrapping around (mod 256).\n"
1119 "Subtract The result of image - image window, with underflow\n"
1120 " wrapping around (mod 256). The add and subtract\n"
1121 " operators can be used to perform reversible\n"
1122 " transformations.\n"
1125 " The result of abs(image - image window). This\n"
1126 " useful for comparing two very similar images.\n"
1128 "Copy The resulting image is image window replaced with\n"
1129 " image. Here the matte information is ignored.\n"
1131 "CopyRed The red layer of the image window is replace with\n"
1132 " the red layer of the image. The other layers are\n"
1136 " The green layer of the image window is replace with\n"
1137 " the green layer of the image. The other layers are\n"
1140 "CopyBlue The blue layer of the image window is replace with\n"
1141 " the blue layer of the image. The other layers are\n"
1145 " The matte layer of the image window is replace with\n"
1146 " the matte layer of the image. The other layers are\n"
1149 "The image compositor requires a matte, or alpha channel in\n"
1150 "the image for some operations. This extra channel usually\n"
1151 "defines a mask which represents a sort of a cookie-cutter\n"
1152 "for the image. This the case when matte is opaque (full\n"
1153 "coverage) for pixels inside the shape, zero outside, and\n"
1154 "between 0 and QuantumRange on the boundary. If image does not\n"
1155 "have a matte channel, it is initialized with 0 for any pixel\n"
1156 "matching in color to pixel location (0,0), otherwise QuantumRange.\n"
1158 "Note that matte information for image window is not retained\n"
1159 "for colormapped X server visuals (e.g. StaticColor,\n"
1160 "StaticColor, GrayScale, PseudoColor). Correct compositing\n"
1161 "behavior may require a TrueColor or DirectColor visual or a\n"
1162 "Standard Colormap.\n"
1164 "Choosing a composite operator is optional. The default\n"
1165 "operator is replace. However, you must choose a location to\n"
1166 "paste your image and press button 1. Press and hold the\n"
1167 "button before releasing and an outline of the image will\n"
1168 "appear to help you identify your location.\n"
1170 "The actual colors of the pasted image is saved. However,\n"
1171 "the color that appears in image window may be different.\n"
1172 "For example, on a monochrome screen image window will appear\n"
1173 "black or white even though your pasted image may have\n"
1174 "many colors. If the image is saved to a file it is written\n"
1175 "with the correct colors. To assure the correct colors are\n"
1176 "saved in the final image, any PseudoClass image is promoted\n"
1177 "to DirectClass (see miff(5)). To force a PseudoClass image\n"
1178 "to remain PseudoClass, use -colors.\n"
1182 "In region of interest mode, the Command widget has these\n"
1188 "To define a region of interest, press button 1 and drag.\n"
1189 "The region of interest is defined by a highlighted rectangle\n"
1190 "that expands or contracts as it follows the pointer. Once\n"
1191 "you are satisfied with the region of interest, release the\n"
1192 "button. You are now in apply mode. In apply mode the\n"
1193 "Command widget has these options:\n"
1213 " Contrast Stretch\n"
1214 " Sigmoidal Contrast...\n"
1240 " Oil Painting...\n"
1241 " Charcoal Drawing...\n"
1245 " Show Preview...\n"
1251 "You can make adjustments to the region of interest by moving\n"
1252 "the pointer to one of the rectangle corners, pressing a\n"
1253 "button, and dragging. Finally, choose an image processing\n"
1254 "technique from the Command widget. You can choose more than\n"
1255 "one image processing technique to apply to an area.\n"
1256 "Alternatively, you can move the region of interest before\n"
1257 "applying another image processing technique. To exit, press\n"
1262 "In rotate mode, the Command widget has these options:\n"
1281 "Choose a background color from the Pixel Color sub-menu.\n"
1282 "Additional background colors can be specified with the color\n"
1283 "browser. You can change the menu colors by setting the X\n"
1284 "resources pen1 through pen9.\n"
1286 "If you choose the color browser and press Grab, you can\n"
1287 "select the background color by moving the pointer to the\n"
1288 "desired color on the screen and press any button.\n"
1290 "Choose a point in the image window and press this button and\n"
1291 "hold. Next, move the pointer to another location in the\n"
1292 "image. As you move a line connects the initial location and\n"
1293 "the pointer. When you release the button, the degree of\n"
1294 "image rotation is determined by the slope of the line you\n"
1295 "just drew. The slope is relative to the direction you\n"
1296 "choose from the Direction sub-menu of the Command widget.\n"
1298 "To cancel the image rotation, move the pointer back to the\n"
1299 "starting point of the line and release the button.\n"
1322 VisualDirectoryCommand,
1330 OriginalSizeCommand,
1352 ContrastStretchCommand,
1353 SigmoidalContrastCommand,
1379 CharcoalDrawCommand,
1389 RegionofInterestCommand,
1395 ShowHistogramCommand,
1401 BrowseDocumentationCommand,
1403 SaveToUndoBufferCommand,
1410 AnnotateNameCommand,
1411 AnnotateFontColorCommand,
1412 AnnotateBackgroundColorCommand,
1413 AnnotateRotateCommand,
1414 AnnotateHelpCommand,
1415 AnnotateDismissCommand,
1418 ChopDirectionCommand,
1421 HorizontalChopCommand,
1422 VerticalChopCommand,
1423 ColorEditMethodCommand,
1424 ColorEditColorCommand,
1425 ColorEditBorderCommand,
1426 ColorEditFuzzCommand,
1427 ColorEditUndoCommand,
1428 ColorEditHelpCommand,
1429 ColorEditDismissCommand,
1430 CompositeOperatorsCommand,
1431 CompositeDissolveCommand,
1432 CompositeDisplaceCommand,
1433 CompositeHelpCommand,
1434 CompositeDismissCommand,
1439 RectifyDismissCommand,
1448 MatteEditBorderCommand,
1449 MatteEditFuzzCommand,
1450 MatteEditValueCommand,
1451 MatteEditUndoCommand,
1452 MatteEditHelpCommand,
1453 MatteEditDismissCommand,
1454 PasteOperatorsCommand,
1456 PasteDismissCommand,
1458 RotateDirectionCommand,
1460 RotateSharpenCommand,
1462 RotateDismissCommand,
1463 HorizontalRotateCommand,
1464 VerticalRotateCommand,
1475 #define BricksWidth 20
1476 #define BricksHeight 20
1477 #define DiagonalWidth 16
1478 #define DiagonalHeight 16
1479 #define HighlightWidth 8
1480 #define HighlightHeight 8
1481 #define OpaqueWidth 8
1482 #define OpaqueHeight 8
1483 #define ScalesWidth 16
1484 #define ScalesHeight 16
1485 #define ShadowWidth 8
1486 #define ShadowHeight 8
1487 #define VerticalWidth 16
1488 #define VerticalHeight 16
1489 #define WavyWidth 16
1490 #define WavyHeight 16
1498 static const unsigned char
1501 0xff, 0xff, 0x0f, 0x03, 0x0c, 0x00, 0x03, 0x0c, 0x00, 0x03, 0x0c, 0x00,
1502 0x03, 0x0c, 0x00, 0xff, 0xff, 0x0f, 0x60, 0x80, 0x01, 0x60, 0x80, 0x01,
1503 0x60, 0x80, 0x01, 0x60, 0x80, 0x01, 0xff, 0xff, 0x0f, 0x03, 0x0c, 0x00,
1504 0x03, 0x0c, 0x00, 0x03, 0x0c, 0x00, 0x03, 0x0c, 0x00, 0xff, 0xff, 0x0f,
1505 0x60, 0x80, 0x01, 0x60, 0x80, 0x01, 0x60, 0x80, 0x01, 0x60, 0x80, 0x01
1509 0x44, 0x44, 0x88, 0x88, 0x11, 0x11, 0x22, 0x22, 0x44, 0x44, 0x88, 0x88,
1510 0x11, 0x11, 0x22, 0x22, 0x44, 0x44, 0x88, 0x88, 0x11, 0x11, 0x22, 0x22,
1511 0x44, 0x44, 0x88, 0x88, 0x11, 0x11, 0x22, 0x22
1515 0x08, 0x08, 0x08, 0x08, 0x14, 0x14, 0xe3, 0xe3, 0x80, 0x80, 0x80, 0x80,
1516 0x41, 0x41, 0x3e, 0x3e, 0x08, 0x08, 0x08, 0x08, 0x14, 0x14, 0xe3, 0xe3,
1517 0x80, 0x80, 0x80, 0x80, 0x41, 0x41, 0x3e, 0x3e
1521 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1522 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1523 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11
1527 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfd, 0xff, 0xfd, 0xff, 0xfb, 0xff,
1528 0xe7, 0xff, 0x1f, 0xff, 0xff, 0xf8, 0xff, 0xe7, 0xff, 0xdf, 0xff, 0xbf,
1529 0xff, 0xbf, 0xff, 0x7f, 0xff, 0x7f, 0xff, 0x7f
1536 XImageWindowCommand(Display *,XResourceInfo *,XWindows *,
1537 const MagickStatusType,KeySym,
Image **);
1540 *XMagickCommand(Display *,XResourceInfo *,XWindows *,
const CommandType,
1542 *XOpenImage(Display *,XResourceInfo *,XWindows *,
const MagickBooleanType),
1543 *XTileImage(Display *,XResourceInfo *,XWindows *,
Image *,XEvent *),
1544 *XVisualDirectoryImage(Display *,XResourceInfo *,XWindows *);
1546 static MagickBooleanType
1547 XAnnotateEditImage(Display *,XResourceInfo *,XWindows *,
Image *),
1548 XDrawEditImage(Display *,XResourceInfo *,XWindows *,
Image **),
1549 XChopImage(Display *,XResourceInfo *,XWindows *,
Image **),
1550 XCropImage(Display *,XResourceInfo *,XWindows *,
Image *,
const ClipboardMode),
1551 XBackgroundImage(Display *,XResourceInfo *,XWindows *,
Image **),
1552 XColorEditImage(Display *,XResourceInfo *,XWindows *,
Image **),
1553 XCompositeImage(Display *,XResourceInfo *,XWindows *,
Image *),
1554 XConfigureImage(Display *,XResourceInfo *,XWindows *,
Image *),
1555 XMatteEditImage(Display *,XResourceInfo *,XWindows *,
Image **),
1556 XPasteImage(Display *,XResourceInfo *,XWindows *,
Image *),
1557 XPrintImage(Display *,XResourceInfo *,XWindows *,
Image *),
1558 XRotateImage(Display *,XResourceInfo *,XWindows *,
double,
Image **),
1559 XROIImage(Display *,XResourceInfo *,XWindows *,
Image **),
1560 XSaveImage(Display *,XResourceInfo *,XWindows *,
Image *),
1561 XTrimImage(Display *,XResourceInfo *,XWindows *,
Image *);
1564 XDrawPanRectangle(Display *,XWindows *),
1565 XImageCache(Display *,XResourceInfo *,XWindows *,
const CommandType,
Image **),
1566 XMagnifyImage(Display *,XWindows *,XEvent *),
1567 XMakePanImage(Display *,XResourceInfo *,XWindows *,
Image *),
1568 XPanImage(Display *,XWindows *,XEvent *),
1569 XMagnifyWindowCommand(Display *,XWindows *,
const MagickStatusType,
1572 XScreenEvent(Display *,XWindows *,XEvent *),
1573 XTranslateImage(Display *,XWindows *,
Image *,
const KeySym);
1602 MagickExport MagickBooleanType DisplayImages(
const ImageInfo *image_info,
1626 assert(image_info != (
const ImageInfo *) NULL);
1627 assert(image_info->signature == MagickCoreSignature);
1628 assert(images != (
Image *) NULL);
1629 assert(images->signature == MagickCoreSignature);
1630 if (IsEventLogging() != MagickFalse)
1631 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",images->filename);
1632 display=XOpenDisplay(image_info->server_name);
1633 if (display == (Display *) NULL)
1635 (void) ThrowMagickException(&images->exception,GetMagickModule(),
1636 XServerError,
"UnableToOpenXServer",
"`%s'",XDisplayName(
1637 image_info->server_name));
1638 return(MagickFalse);
1640 if (images->exception.severity != UndefinedException)
1641 CatchException(&images->exception);
1642 (void) XSetErrorHandler(XError);
1643 resource_database=XGetResourceDatabase(display,GetClientName());
1644 (void) memset(&resource_info,0,
sizeof(resource_info));
1645 XGetResourceInfo(image_info,resource_database,GetClientName(),&resource_info);
1646 if (image_info->page != (
char *) NULL)
1647 resource_info.image_geometry=AcquireString(image_info->page);
1648 resource_info.immutable=MagickTrue;
1649 argv[0]=AcquireString(GetClientName());
1651 for (i=0; (state & ExitState) == 0; i++)
1653 if ((images->iterations != 0) && (i >= (ssize_t) images->iterations))
1655 image=GetImageFromList(images,i % GetImageListLength(images));
1656 (void) XDisplayImage(display,&resource_info,argv,1,&image,&state);
1658 (void) SetErrorHandler((ErrorHandler) NULL);
1659 (void) SetWarningHandler((WarningHandler) NULL);
1660 argv[0]=DestroyString(argv[0]);
1661 XDestroyResourceInfo(&resource_info);
1662 if (images->exception.severity != UndefinedException)
1663 return(MagickFalse);
1697 MagickExport MagickBooleanType RemoteDisplayCommand(
const ImageInfo *image_info,
1698 const char *window,
const char *filename,
ExceptionInfo *exception)
1706 assert(image_info != (
const ImageInfo *) NULL);
1707 assert(image_info->signature == MagickCoreSignature);
1708 assert(filename != (
char *) NULL);
1709 if (IsEventLogging() != MagickFalse)
1710 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",filename);
1711 display=XOpenDisplay(image_info->server_name);
1712 if (display == (Display *) NULL)
1714 (void) ThrowMagickException(exception,GetMagickModule(),XServerError,
1715 "UnableToOpenXServer",
"`%s'",XDisplayName(image_info->server_name));
1716 return(MagickFalse);
1718 (void) XSetErrorHandler(XError);
1719 status=XRemoteCommand(display,window,filename);
1720 (void) XCloseDisplay(display);
1721 return(status != 0 ? MagickTrue : MagickFalse);
1755 static MagickBooleanType XAnnotateEditImage(Display *display,
1756 XResourceInfo *resource_info,XWindows *windows,
Image *image)
1759 *
const AnnotateMenu[] =
1776 static const ModeType
1777 AnnotateCommands[] =
1779 AnnotateNameCommand,
1780 AnnotateFontColorCommand,
1781 AnnotateBackgroundColorCommand,
1782 AnnotateRotateCommand,
1783 AnnotateHelpCommand,
1784 AnnotateDismissCommand
1792 static MagickBooleanType
1793 transparent_box = MagickTrue,
1794 transparent_pen = MagickFalse;
1796 static MagickRealType
1800 box_id = MaxNumberPens-2,
1805 command[MaxTextExtent],
1806 text[MaxTextExtent];
1809 *ColorMenu[MaxNumberPens+1];
1857 (void) CloneString(&windows->command.name,
"Annotate");
1858 windows->command.data=4;
1859 (void) XCommandWidget(display,windows,AnnotateMenu,(XEvent *) NULL);
1860 (void) XMapRaised(display,windows->command.id);
1861 XClientMessage(display,windows->image.id,windows->im_protocols,
1862 windows->im_update_widget,CurrentTime);
1866 XQueryPosition(display,windows->image.id,&x,&y);
1867 (void) XSelectInput(display,windows->image.id,
1868 windows->image.attributes.event_mask | PointerMotionMask);
1869 cursor=XCreateFontCursor(display,XC_left_side);
1870 (void) XCheckDefineCursor(display,windows->image.id,cursor);
1874 if (windows->info.mapped != MagickFalse)
1879 (void) FormatLocaleString(text,MaxTextExtent,
" %+d%+d ",
1880 x+windows->image.x,y+windows->image.y);
1881 XInfoWidget(display,windows,text);
1886 XScreenEvent(display,windows,&event);
1887 if (event.xany.window == windows->command.id)
1892 id=XCommandWidget(display,windows,AnnotateMenu,&event);
1893 (void) XCheckDefineCursor(display,windows->image.id,cursor);
1896 switch (AnnotateCommands[
id])
1898 case AnnotateNameCommand:
1901 *FontMenu[MaxNumberFonts];
1909 for (i=0; i < MaxNumberFonts; i++)
1910 FontMenu[i]=resource_info->font_name[i];
1911 FontMenu[MaxNumberFonts-2]=
"Browser...";
1912 FontMenu[MaxNumberFonts-1]=(
const char *) NULL;
1916 font_number=XMenuWidget(display,windows,AnnotateMenu[
id],
1917 (
const char **) FontMenu,command);
1918 if (font_number < 0)
1920 if (font_number == (MaxNumberFonts-2))
1923 font_name[MaxTextExtent] =
"fixed";
1928 resource_info->font_name[font_number]=font_name;
1929 XFontBrowserWidget(display,windows,
"Select",font_name);
1930 if (*font_name ==
'\0')
1936 font_info=XLoadQueryFont(display,resource_info->font_name[
1938 if (font_info == (XFontStruct *) NULL)
1940 XNoticeWidget(display,windows,
"Unable to load font:",
1941 resource_info->font_name[font_number]);
1944 font_id=(
unsigned int) font_number;
1945 (void) XFreeFont(display,font_info);
1948 case AnnotateFontColorCommand:
1953 for (i=0; i < (int) (MaxNumberPens-2); i++)
1954 ColorMenu[i]=resource_info->pen_colors[i];
1955 ColorMenu[MaxNumberPens-2]=
"transparent";
1956 ColorMenu[MaxNumberPens-1]=
"Browser...";
1957 ColorMenu[MaxNumberPens]=(
const char *) NULL;
1961 pen_number=XMenuWidget(display,windows,AnnotateMenu[
id],
1962 (
const char **) ColorMenu,command);
1965 transparent_pen=pen_number == (MaxNumberPens-2) ? MagickTrue :
1967 if (transparent_pen != MagickFalse)
1969 if (pen_number == (MaxNumberPens-1))
1972 color_name[MaxTextExtent] =
"gray";
1977 resource_info->pen_colors[pen_number]=color_name;
1978 XColorBrowserWidget(display,windows,
"Select",color_name);
1979 if (*color_name ==
'\0')
1985 (void) XParseColor(display,windows->map_info->colormap,
1986 resource_info->pen_colors[pen_number],&color);
1987 XBestPixel(display,windows->map_info->colormap,(XColor *) NULL,
1988 (
unsigned int) MaxColors,&color);
1989 windows->pixel_info->pen_colors[pen_number]=color;
1990 pen_id=(
unsigned int) pen_number;
1993 case AnnotateBackgroundColorCommand:
1998 for (i=0; i < (int) (MaxNumberPens-2); i++)
1999 ColorMenu[i]=resource_info->pen_colors[i];
2000 ColorMenu[MaxNumberPens-2]=
"transparent";
2001 ColorMenu[MaxNumberPens-1]=
"Browser...";
2002 ColorMenu[MaxNumberPens]=(
const char *) NULL;
2006 pen_number=XMenuWidget(display,windows,AnnotateMenu[
id],
2007 (
const char **) ColorMenu,command);
2010 transparent_box=pen_number == (MaxNumberPens-2) ? MagickTrue :
2012 if (transparent_box != MagickFalse)
2014 if (pen_number == (MaxNumberPens-1))
2017 color_name[MaxTextExtent] =
"gray";
2022 resource_info->pen_colors[pen_number]=color_name;
2023 XColorBrowserWidget(display,windows,
"Select",color_name);
2024 if (*color_name ==
'\0')
2030 (void) XParseColor(display,windows->map_info->colormap,
2031 resource_info->pen_colors[pen_number],&color);
2032 XBestPixel(display,windows->map_info->colormap,(XColor *) NULL,
2033 (
unsigned int) MaxColors,&color);
2034 windows->pixel_info->pen_colors[pen_number]=color;
2035 box_id=(
unsigned int) pen_number;
2038 case AnnotateRotateCommand:
2044 *
const RotateMenu[] =
2059 angle[MaxTextExtent] =
"30.0";
2064 entry=XMenuWidget(display,windows,AnnotateMenu[
id],RotateMenu,
2070 degrees=StringToDouble(RotateMenu[entry],(
char **) NULL);
2073 (void) XDialogWidget(display,windows,
"OK",
"Enter rotation angle:",
2077 degrees=StringToDouble(angle,(
char **) NULL);
2080 case AnnotateHelpCommand:
2082 XTextViewHelp(display,resource_info,windows,MagickFalse,
2083 "Help Viewer - Image Annotation",ImageAnnotateHelp);
2086 case AnnotateDismissCommand:
2104 if (event.xbutton.button != Button1)
2106 if (event.xbutton.window != windows->image.id)
2122 if (event.xkey.window != windows->image.id)
2127 (void) XLookupString((XKeyEvent *) &
event.xkey,command,(int)
2128 sizeof(command),&key_symbol,(XComposeStatus *) NULL);
2129 switch ((
int) key_symbol)
2144 XTextViewHelp(display,resource_info,windows,MagickFalse,
2145 "Help Viewer - Image Annotation",ImageAnnotateHelp);
2150 (void) XBell(display,0);
2163 if (windows->info.mapped != MagickFalse)
2165 if ((x < (
int) (windows->info.x+windows->info.width)) &&
2166 (y < (int) (windows->info.y+windows->info.height)))
2167 (void) XWithdrawWindow(display,windows->info.id,
2168 windows->info.screen);
2171 if ((x > (
int) (windows->info.x+windows->info.width)) ||
2172 (y > (int) (windows->info.y+windows->info.height)))
2173 (void) XMapWindow(display,windows->info.id);
2179 }
while ((state & ExitState) == 0);
2180 (void) XSelectInput(display,windows->image.id,
2181 windows->image.attributes.event_mask);
2182 (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
2183 if ((state & EscapeState) != 0)
2188 font_info=XLoadQueryFont(display,resource_info->font_name[font_id]);
2189 if (font_info == (XFontStruct *) NULL)
2191 XNoticeWidget(display,windows,
"Unable to load font:",
2192 resource_info->font_name[font_id]);
2193 font_info=windows->font_info;
2195 if ((x+font_info->max_bounds.width) >= (
int) windows->image.width)
2196 x=(int) windows->image.width-font_info->max_bounds.width;
2197 if (y < (
int) (font_info->ascent+font_info->descent))
2198 y=(int) font_info->ascent+font_info->descent;
2199 if (((
int) font_info->max_bounds.width > (int) windows->image.width) ||
2200 ((font_info->ascent+font_info->descent) >= (
int) windows->image.height))
2201 return(MagickFalse);
2205 annotate_info=(XAnnotateInfo *) AcquireMagickMemory(
sizeof(*annotate_info));
2206 if (annotate_info == (XAnnotateInfo *) NULL)
2207 return(MagickFalse);
2208 XGetAnnotateInfo(annotate_info);
2211 if ((transparent_box == MagickFalse) && (transparent_pen == MagickFalse))
2212 annotate_info->stencil=OpaqueStencil;
2214 if (transparent_box == MagickFalse)
2215 annotate_info->stencil=BackgroundStencil;
2217 annotate_info->stencil=ForegroundStencil;
2218 annotate_info->height=(
unsigned int) font_info->ascent+font_info->descent;
2219 annotate_info->degrees=degrees;
2220 annotate_info->font_info=font_info;
2221 annotate_info->text=(
char *) AcquireQuantumMemory((
size_t)
2222 windows->image.width/MagickMax((ssize_t) font_info->min_bounds.width,1)+2UL,
2223 sizeof(*annotate_info->text));
2224 if (annotate_info->text == (
char *) NULL)
2225 return(MagickFalse);
2229 cursor=XCreateFontCursor(display,XC_pencil);
2230 (void) XCheckDefineCursor(display,windows->image.id,cursor);
2231 annotate_context=windows->image.annotate_context;
2232 (void) XSetFont(display,annotate_context,font_info->fid);
2233 (void) XSetBackground(display,annotate_context,
2234 windows->pixel_info->pen_colors[box_id].pixel);
2235 (void) XSetForeground(display,annotate_context,
2236 windows->pixel_info->pen_colors[pen_id].pixel);
2240 (void) CloneString(&windows->command.name,
"Text");
2241 windows->command.data=0;
2242 (void) XCommandWidget(display,windows,TextMenu,(XEvent *) NULL);
2244 (void) XDrawString(display,windows->image.id,annotate_context,x,y,
"_",1);
2245 text_event.xexpose.width=(int) font_info->max_bounds.width;
2246 text_event.xexpose.height=font_info->max_bounds.ascent+
2247 font_info->max_bounds.descent;
2248 p=annotate_info->text;
2255 (
void) XDrawString(display,windows->image.id,annotate_context,x,y,
"_",1);
2259 XScreenEvent(display,windows,&event);
2260 if (event.xany.window == windows->command.id)
2265 (void) XSetBackground(display,annotate_context,
2266 windows->pixel_info->background_color.pixel);
2267 (void) XSetForeground(display,annotate_context,
2268 windows->pixel_info->foreground_color.pixel);
2269 id=XCommandWidget(display,windows,AnnotateMenu,&event);
2270 (void) XSetBackground(display,annotate_context,
2271 windows->pixel_info->pen_colors[box_id].pixel);
2272 (void) XSetForeground(display,annotate_context,
2273 windows->pixel_info->pen_colors[pen_id].pixel);
2276 switch (TextCommands[
id])
2278 case TextHelpCommand:
2280 XTextViewHelp(display,resource_info,windows,MagickFalse,
2281 "Help Viewer - Image Annotation",ImageAnnotateHelp);
2282 (void) XCheckDefineCursor(display,windows->image.id,cursor);
2285 case TextApplyCommand:
2290 annotate_info->width=(
unsigned int) XTextWidth(font_info,
2291 annotate_info->text,(
int) strlen(annotate_info->text));
2292 XRefreshWindow(display,&windows->image,&text_event);
2304 text_event.xexpose.x=x;
2305 text_event.xexpose.y=y-font_info->max_bounds.ascent;
2306 (void) XClearArea(display,windows->image.id,x,text_event.xexpose.y,
2307 (
unsigned int) text_event.xexpose.width,(
unsigned int)
2308 text_event.xexpose.height,MagickFalse);
2309 XRefreshWindow(display,&windows->image,&text_event);
2314 if (event.xbutton.window != windows->image.id)
2316 if (event.xbutton.button == Button2)
2321 (void) XConvertSelection(display,XA_PRIMARY,XA_STRING,XA_STRING,
2322 windows->image.id,CurrentTime);
2329 if (event.xexpose.count == 0)
2337 XRefreshWindow(display,&windows->image,(XEvent *) NULL);
2338 text_info=annotate_info;
2339 while (text_info != (XAnnotateInfo *) NULL)
2341 if (annotate_info->stencil == ForegroundStencil)
2342 (void) XDrawString(display,windows->image.id,annotate_context,
2343 text_info->x,text_info->y,text_info->text,
2344 (
int) strlen(text_info->text));
2346 (
void) XDrawImageString(display,windows->image.id,
2347 annotate_context,text_info->x,text_info->y,text_info->text,
2348 (
int) strlen(text_info->text));
2349 text_info=text_info->previous;
2351 (void) XDrawString(display,windows->image.id,annotate_context,
2361 if (event.xkey.window != windows->image.id)
2366 length=XLookupString((XKeyEvent *) &event.xkey,command,(
int)
2367 sizeof(command),&key_symbol,(XComposeStatus *) NULL);
2368 *(command+length)=
'\0';
2369 if (((event.xkey.state & ControlMask) != 0) ||
2370 ((
event.xkey.state & Mod1Mask) != 0))
2371 state|=ModifierState;
2372 if ((state & ModifierState) != 0)
2373 switch ((
int) key_symbol)
2378 key_symbol=DeleteCommand;
2384 switch ((
int) key_symbol)
2391 if (p == annotate_info->text)
2393 if (annotate_info->previous == (XAnnotateInfo *) NULL)
2400 annotate_info=annotate_info->previous;
2401 p=annotate_info->text;
2402 x=annotate_info->x+annotate_info->width;
2404 if (annotate_info->width != 0)
2405 p+=strlen(annotate_info->text);
2410 x-=XTextWidth(font_info,p,1);
2411 text_event.xexpose.x=x;
2412 text_event.xexpose.y=y-font_info->max_bounds.ascent;
2413 XRefreshWindow(display,&windows->image,&text_event);
2416 case XK_bracketleft:
2418 key_symbol=XK_Escape;
2426 while (p != annotate_info->text)
2429 x-=XTextWidth(font_info,p,1);
2430 text_event.xexpose.x=x;
2431 XRefreshWindow(display,&windows->image,&text_event);
2441 annotate_info->width=(
unsigned int) XTextWidth(font_info,
2442 annotate_info->text,(
int) strlen(annotate_info->text));
2443 XRefreshWindow(display,&windows->image,&text_event);
2452 if ((state & ModifierState) != 0)
2454 if (*command ==
'\0')
2457 if (annotate_info->stencil == ForegroundStencil)
2458 (void) XDrawString(display,windows->image.id,annotate_context,
2461 (
void) XDrawImageString(display,windows->image.id,
2462 annotate_context,x,y,p,1);
2463 x+=XTextWidth(font_info,p,1);
2465 if ((x+font_info->max_bounds.width) < (
int) windows->image.width)
2475 annotate_info->width=(
unsigned int) XTextWidth(font_info,
2476 annotate_info->text,(
int) strlen(annotate_info->text));
2477 if (annotate_info->next != (XAnnotateInfo *) NULL)
2482 annotate_info=annotate_info->next;
2485 p=annotate_info->text;
2488 annotate_info->next=(XAnnotateInfo *) AcquireQuantumMemory(1,
2489 sizeof(*annotate_info->next));
2490 if (annotate_info->next == (XAnnotateInfo *) NULL)
2491 return(MagickFalse);
2492 *annotate_info->next=(*annotate_info);
2493 annotate_info->next->previous=annotate_info;
2494 annotate_info=annotate_info->next;
2495 annotate_info->text=(
char *) AcquireQuantumMemory((
size_t)
2496 windows->image.width/MagickMax((ssize_t)
2497 font_info->min_bounds.width,1)+2UL,
sizeof(*annotate_info->text));
2498 if (annotate_info->text == (
char *) NULL)
2499 return(MagickFalse);
2500 annotate_info->y+=annotate_info->height;
2501 if (annotate_info->y > (
int) windows->image.height)
2502 annotate_info->y=(
int) annotate_info->height;
2503 annotate_info->next=(XAnnotateInfo *) NULL;
2506 p=annotate_info->text;
2517 (void) XLookupString((XKeyEvent *) &
event.xkey,command,(int)
2518 sizeof(command),&key_symbol,(XComposeStatus *) NULL);
2519 state&=(~ModifierState);
2522 case SelectionNotify:
2540 if (event.xselection.property == (Atom) None)
2542 status=XGetWindowProperty(display,event.xselection.requestor,
2543 event.xselection.property,0L,(
long) MaxTextExtent,True,XA_STRING,
2544 &type,&format,&length,&after,&data);
2545 if ((status != Success) || (type != XA_STRING) || (format == 32) ||
2551 for (i=0; i < (ssize_t) length; i++)
2553 if ((
char) data[i] !=
'\n')
2559 (void) XDrawString(display,windows->image.id,annotate_context,
2561 x+=XTextWidth(font_info,p,1);
2563 if ((x+font_info->max_bounds.width) < (
int) windows->image.width)
2570 annotate_info->width=(
unsigned int) XTextWidth(font_info,
2571 annotate_info->text,(
int) strlen(annotate_info->text));
2572 if (annotate_info->next != (XAnnotateInfo *) NULL)
2577 annotate_info=annotate_info->next;
2580 p=annotate_info->text;
2583 annotate_info->next=(XAnnotateInfo *) AcquireQuantumMemory(1,
2584 sizeof(*annotate_info->next));
2585 if (annotate_info->next == (XAnnotateInfo *) NULL)
2586 return(MagickFalse);
2587 *annotate_info->next=(*annotate_info);
2588 annotate_info->next->previous=annotate_info;
2589 annotate_info=annotate_info->next;
2590 annotate_info->text=(
char *) AcquireQuantumMemory((
size_t)
2591 windows->image.width/MagickMax((ssize_t)
2592 font_info->min_bounds.width,1)+2UL,
sizeof(*annotate_info->text));
2593 if (annotate_info->text == (
char *) NULL)
2594 return(MagickFalse);
2595 annotate_info->y+=annotate_info->height;
2596 if (annotate_info->y > (
int) windows->image.height)
2597 annotate_info->y=(
int) annotate_info->height;
2598 annotate_info->next=(XAnnotateInfo *) NULL;
2601 p=annotate_info->text;
2603 (void) XFree((
void *) data);
2609 }
while ((state & ExitState) == 0);
2610 (void) XFreeCursor(display,cursor);
2614 width=(
unsigned int) image->columns;
2615 height=(
unsigned int) image->rows;
2618 if (windows->image.crop_geometry != (
char *) NULL)
2619 (
void) XParseGeometry(windows->image.crop_geometry,&x,&y,&width,&height);
2623 XSetCursorState(display,windows,MagickTrue);
2624 XCheckRefreshWindows(display,windows);
2625 while (annotate_info != (XAnnotateInfo *) NULL)
2627 if (annotate_info->width == 0)
2632 previous_info=annotate_info->previous;
2633 annotate_info->text=(
char *)
2634 RelinquishMagickMemory(annotate_info->text);
2635 annotate_info=(XAnnotateInfo *) RelinquishMagickMemory(annotate_info);
2636 annotate_info=previous_info;
2642 windows->pixel_info->box_color=windows->pixel_info->pen_colors[box_id];
2643 if (windows->pixel_info->colors != 0)
2644 for (i=0; i < (ssize_t) windows->pixel_info->colors; i++)
2645 if (windows->pixel_info->pixels[i] ==
2646 windows->pixel_info->pen_colors[box_id].pixel)
2648 windows->pixel_info->box_index=(
unsigned short) i;
2651 windows->pixel_info->pen_color=windows->pixel_info->pen_colors[pen_id];
2652 if (windows->pixel_info->colors != 0)
2653 for (i=0; i < (ssize_t) windows->pixel_info->colors; i++)
2654 if (windows->pixel_info->pixels[i] ==
2655 windows->pixel_info->pen_colors[pen_id].pixel)
2657 windows->pixel_info->pen_index=(
unsigned short) i;
2663 annotate_info->x=(int)
2664 width*(annotate_info->x+windows->image.x)/windows->image.ximage->width;
2665 annotate_info->y=(int) height*(annotate_info->y-font_info->ascent+
2666 windows->image.y)/windows->image.ximage->height;
2667 (void) FormatLocaleString(annotate_info->geometry,MaxTextExtent,
2668 "%ux%u%+d%+d",width*annotate_info->width/windows->image.ximage->width,
2669 height*annotate_info->height/windows->image.ximage->height,
2670 annotate_info->x+x,annotate_info->y+y);
2674 status=XAnnotateImage(display,windows->pixel_info,annotate_info,image);
2676 return(MagickFalse);
2680 previous_info=annotate_info->previous;
2681 annotate_info->text=DestroyString(annotate_info->text);
2682 annotate_info=(XAnnotateInfo *) RelinquishMagickMemory(annotate_info);
2683 annotate_info=previous_info;
2685 (void) XSetForeground(display,annotate_context,
2686 windows->pixel_info->foreground_color.pixel);
2687 (void) XSetBackground(display,annotate_context,
2688 windows->pixel_info->background_color.pixel);
2689 (void) XSetFont(display,annotate_context,windows->font_info->fid);
2690 XSetCursorState(display,windows,MagickFalse);
2691 (void) XFreeFont(display,font_info);
2695 XConfigureImageColormap(display,resource_info,windows,image);
2696 (void) XConfigureImage(display,resource_info,windows,image);
2730 static MagickBooleanType XBackgroundImage(Display *display,
2731 XResourceInfo *resource_info,XWindows *windows,
Image **image)
2733 #define BackgroundImageTag "Background/Image"
2739 window_id[MaxTextExtent] =
"root";
2742 background_resources;
2747 status=XDialogWidget(display,windows,
"Background",
2748 "Enter window id (id 0x00 selects window with pointer):",window_id);
2749 if (*window_id ==
'\0')
2750 return(MagickFalse);
2751 (void) XMagickCommand(display,resource_info,windows,ApplyCommand,image);
2752 XInfoWidget(display,windows,BackgroundImageTag);
2753 XSetCursorState(display,windows,MagickTrue);
2754 XCheckRefreshWindows(display,windows);
2755 background_resources=(*resource_info);
2756 background_resources.window_id=window_id;
2757 background_resources.backdrop=status != 0 ? MagickTrue : MagickFalse;
2758 status=XDisplayBackgroundImage(display,&background_resources,*image);
2759 if (status != MagickFalse)
2760 XClientMessage(display,windows->image.id,windows->im_protocols,
2761 windows->im_retain_colors,CurrentTime);
2762 XSetCursorState(display,windows,MagickFalse);
2763 (void) XMagickCommand(display,resource_info,windows,UndoCommand,image);
2797 static MagickBooleanType XChopImage(Display *display,
2798 XResourceInfo *resource_info,XWindows *windows,
Image **image)
2810 direction = HorizontalChopCommand;
2812 static const ModeType
2815 ChopDirectionCommand,
2819 DirectionCommands[] =
2821 HorizontalChopCommand,
2826 text[MaxTextExtent];
2859 (void) CloneString(&windows->command.name,
"Chop");
2860 windows->command.data=1;
2861 (void) XCommandWidget(display,windows,ChopMenu,(XEvent *) NULL);
2862 (void) XMapRaised(display,windows->command.id);
2863 XClientMessage(display,windows->image.id,windows->im_protocols,
2864 windows->im_update_widget,CurrentTime);
2868 XQueryPosition(display,windows->image.id,&x,&y);
2869 (void) XSelectInput(display,windows->image.id,
2870 windows->image.attributes.event_mask | PointerMotionMask);
2872 (void) memset(&segment_info,0,
sizeof(segment_info));
2875 if (windows->info.mapped != MagickFalse)
2880 (void) FormatLocaleString(text,MaxTextExtent,
" %+d%+d ",
2881 x+windows->image.x,y+windows->image.y);
2882 XInfoWidget(display,windows,text);
2887 XScreenEvent(display,windows,&event);
2888 if (event.xany.window == windows->command.id)
2893 id=XCommandWidget(display,windows,ChopMenu,&event);
2896 switch (ChopCommands[
id])
2898 case ChopDirectionCommand:
2901 command[MaxTextExtent];
2904 *
const Directions[] =
2914 id=XMenuWidget(display,windows,ChopMenu[
id],Directions,command);
2916 direction=DirectionCommands[id];
2919 case ChopHelpCommand:
2921 XTextViewHelp(display,resource_info,windows,MagickFalse,
2922 "Help Viewer - Image Chop",ImageChopHelp);
2925 case ChopDismissCommand:
2943 if (event.xbutton.button != Button1)
2945 if (event.xbutton.window != windows->image.id)
2950 segment_info.x1=(
short int) event.xbutton.x;
2951 segment_info.x2=(
short int)
event.xbutton.x;
2952 segment_info.y1=(
short int) event.xbutton.y;
2953 segment_info.y2=(
short int)
event.xbutton.y;
2964 command[MaxTextExtent];
2969 if (event.xkey.window != windows->image.id)
2974 (void) XLookupString((XKeyEvent *) &
event.xkey,command,(int)
2975 sizeof(command),&key_symbol,(XComposeStatus *) NULL);
2976 switch ((
int) key_symbol)
2991 (void) XSetFunction(display,windows->image.highlight_context,
2993 XTextViewHelp(display,resource_info,windows,MagickFalse,
2994 "Help Viewer - Image Chop",ImageChopHelp);
2995 (void) XSetFunction(display,windows->image.highlight_context,
3001 (void) XBell(display,0);
3014 if (windows->info.mapped != MagickFalse)
3016 if ((x < (
int) (windows->info.x+windows->info.width)) &&
3017 (y < (int) (windows->info.y+windows->info.height)))
3018 (void) XWithdrawWindow(display,windows->info.id,
3019 windows->info.screen);
3022 if ((x > (
int) (windows->info.x+windows->info.width)) ||
3023 (y > (int) (windows->info.y+windows->info.height)))
3024 (void) XMapWindow(display,windows->info.id);
3027 }
while ((state & ExitState) == 0);
3028 (void) XSelectInput(display,windows->image.id,
3029 windows->image.attributes.event_mask);
3030 (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
3031 if ((state & EscapeState) != 0)
3041 (void) XSetFunction(display,windows->image.highlight_context,GXinvert);
3050 if (windows->info.mapped == MagickFalse)
3051 (void) XMapWindow(display,windows->info.id);
3052 (void) FormatLocaleString(text,MaxTextExtent,
3053 " %.20gx%.20g%+.20g%+.20g",(
double) chop_info.width,(double)
3054 chop_info.height,(
double) chop_info.x,(double) chop_info.y);
3055 XInfoWidget(display,windows,text);
3056 XHighlightLine(display,windows->image.id,
3057 windows->image.highlight_context,&segment_info);
3060 if (windows->info.mapped != MagickFalse)
3061 (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
3065 XScreenEvent(display,windows,&event);
3067 XHighlightLine(display,windows->image.id,
3068 windows->image.highlight_context,&segment_info);
3073 segment_info.x2=(
short int) event.xmotion.x;
3074 segment_info.y2=(
short int)
event.xmotion.y;
3082 segment_info.x2=(
short int) event.xbutton.x;
3083 segment_info.y2=(
short int)
event.xbutton.y;
3091 segment_info.x2=(
short int) event.xmotion.x;
3092 segment_info.y2=(
short int)
event.xmotion.y;
3100 if (segment_info.x2 < 0)
3103 if (segment_info.x2 > windows->image.ximage->width)
3104 segment_info.x2=windows->image.ximage->width;
3105 if (segment_info.y2 < 0)
3108 if (segment_info.y2 > windows->image.ximage->height)
3109 segment_info.y2=windows->image.ximage->height;
3110 distance=(
unsigned int)
3111 (((segment_info.x2-segment_info.x1)*(segment_info.x2-segment_info.x1))+
3112 ((segment_info.y2-segment_info.y1)*(segment_info.y2-segment_info.y1)));
3116 if (direction == HorizontalChopCommand)
3118 chop_info.width=(size_t) (segment_info.x2-segment_info.x1+1);
3119 chop_info.x=(ssize_t) windows->image.x+segment_info.x1;
3122 if (segment_info.x1 > (
int) segment_info.x2)
3124 chop_info.width=(size_t) (segment_info.x1-segment_info.x2+1);
3125 chop_info.x=(ssize_t) windows->image.x+segment_info.x2;
3131 chop_info.height=(size_t) (segment_info.y2-segment_info.y1+1);
3133 chop_info.y=(ssize_t) windows->image.y+segment_info.y1;
3134 if (segment_info.y1 > segment_info.y2)
3136 chop_info.height=(size_t) (segment_info.y1-segment_info.y2+1);
3137 chop_info.y=(ssize_t) windows->image.y+segment_info.y2;
3140 }
while ((state & ExitState) == 0);
3141 (void) XSetFunction(display,windows->image.highlight_context,GXcopy);
3142 (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
3148 (void) XMagickCommand(display,resource_info,windows,ApplyCommand,image);
3149 XSetCursorState(display,windows,MagickTrue);
3150 XCheckRefreshWindows(display,windows);
3151 windows->image.window_changes.width=windows->image.ximage->width-
3152 (
unsigned int) chop_info.width;
3153 windows->image.window_changes.height=windows->image.ximage->height-
3154 (
unsigned int) chop_info.height;
3155 width=(
unsigned int) (*image)->columns;
3156 height=(
unsigned int) (*image)->rows;
3159 if (windows->image.crop_geometry != (
char *) NULL)
3160 (
void) XParseGeometry(windows->image.crop_geometry,&x,&y,&width,&height);
3161 scale_factor=(MagickRealType) width/windows->image.ximage->width;
3163 chop_info.x=(ssize_t) (scale_factor*chop_info.x+0.5);
3164 chop_info.width=(
unsigned int) (scale_factor*chop_info.width+0.5);
3165 scale_factor=(MagickRealType) height/windows->image.ximage->height;
3167 chop_info.y=(ssize_t) (scale_factor*chop_info.y+0.5);
3168 chop_info.height=(
unsigned int) (scale_factor*chop_info.height+0.5);
3172 chop_image=ChopImage(*image,&chop_info,&(*image)->exception);
3173 XSetCursorState(display,windows,MagickFalse);
3174 if (chop_image == (
Image *) NULL)
3175 return(MagickFalse);
3176 *image=DestroyImage(*image);
3181 XConfigureImageColormap(display,resource_info,windows,*image);
3182 (void) XConfigureImage(display,resource_info,windows,*image);
3219 static MagickBooleanType XColorEditImage(Display *display,
3220 XResourceInfo *resource_info,XWindows *windows,
Image **image)
3223 *
const ColorEditMenu[] =
3235 static const ModeType
3236 ColorEditCommands[] =
3238 ColorEditMethodCommand,
3239 ColorEditColorCommand,
3240 ColorEditBorderCommand,
3241 ColorEditFuzzCommand,
3242 ColorEditUndoCommand,
3243 ColorEditHelpCommand,
3244 ColorEditDismissCommand
3248 method = PointMethod;
3254 border_color = { 0, 0, 0, 0, 0, 0 };
3257 command[MaxTextExtent] =
"",
3258 text[MaxTextExtent] =
"";
3296 (void) CloneString(&windows->command.name,
"Color Edit");
3297 windows->command.data=4;
3298 (void) XCommandWidget(display,windows,ColorEditMenu,(XEvent *) NULL);
3299 (void) XMapRaised(display,windows->command.id);
3300 XClientMessage(display,windows->image.id,windows->im_protocols,
3301 windows->im_update_widget,CurrentTime);
3305 cursor=XMakeCursor(display,windows->image.id,windows->map_info->colormap,
3306 resource_info->background_color,resource_info->foreground_color);
3307 (void) XCheckDefineCursor(display,windows->image.id,cursor);
3311 XQueryPosition(display,windows->image.id,&x,&y);
3312 (void) XSelectInput(display,windows->image.id,
3313 windows->image.attributes.event_mask | PointerMotionMask);
3317 if (windows->info.mapped != MagickFalse)
3322 (void) FormatLocaleString(text,MaxTextExtent,
" %+d%+d ",
3323 x+windows->image.x,y+windows->image.y);
3324 XInfoWidget(display,windows,text);
3329 XScreenEvent(display,windows,&event);
3330 if (event.xany.window == windows->command.id)
3335 id=XCommandWidget(display,windows,ColorEditMenu,&event);
3338 (void) XCheckDefineCursor(display,windows->image.id,cursor);
3341 switch (ColorEditCommands[
id])
3343 case ColorEditMethodCommand:
3351 methods=(
char **) GetCommandOptions(MagickMethodOptions);
3352 if (methods == (
char **) NULL)
3354 entry=XMenuWidget(display,windows,ColorEditMenu[
id],
3355 (
const char **) methods,command);
3357 method=(PaintMethod) ParseCommandOption(MagickMethodOptions,
3358 MagickFalse,methods[entry]);
3359 methods=DestroyStringList(methods);
3362 case ColorEditColorCommand:
3365 *ColorMenu[MaxNumberPens];
3373 for (i=0; i < (int) (MaxNumberPens-2); i++)
3374 ColorMenu[i]=resource_info->pen_colors[i];
3375 ColorMenu[MaxNumberPens-2]=
"Browser...";
3376 ColorMenu[MaxNumberPens-1]=(
const char *) NULL;
3380 pen_number=XMenuWidget(display,windows,ColorEditMenu[
id],
3381 (
const char **) ColorMenu,command);
3384 if (pen_number == (MaxNumberPens-2))
3387 color_name[MaxTextExtent] =
"gray";
3392 resource_info->pen_colors[pen_number]=color_name;
3393 XColorBrowserWidget(display,windows,
"Select",color_name);
3394 if (*color_name ==
'\0')
3400 (void) XParseColor(display,windows->map_info->colormap,
3401 resource_info->pen_colors[pen_number],&color);
3402 XBestPixel(display,windows->map_info->colormap,(XColor *) NULL,
3403 (
unsigned int) MaxColors,&color);
3404 windows->pixel_info->pen_colors[pen_number]=color;
3405 pen_id=(
unsigned int) pen_number;
3408 case ColorEditBorderCommand:
3411 *ColorMenu[MaxNumberPens];
3419 for (i=0; i < (int) (MaxNumberPens-2); i++)
3420 ColorMenu[i]=resource_info->pen_colors[i];
3421 ColorMenu[MaxNumberPens-2]=
"Browser...";
3422 ColorMenu[MaxNumberPens-1]=(
const char *) NULL;
3426 pen_number=XMenuWidget(display,windows,ColorEditMenu[
id],
3427 (
const char **) ColorMenu,command);
3430 if (pen_number == (MaxNumberPens-2))
3433 color_name[MaxTextExtent] =
"gray";
3438 resource_info->pen_colors[pen_number]=color_name;
3439 XColorBrowserWidget(display,windows,
"Select",color_name);
3440 if (*color_name ==
'\0')
3446 (void) XParseColor(display,windows->map_info->colormap,
3447 resource_info->pen_colors[pen_number],&border_color);
3450 case ColorEditFuzzCommand:
3453 fuzz[MaxTextExtent];
3470 entry=XMenuWidget(display,windows,ColorEditMenu[
id],FuzzMenu,
3476 (*image)->fuzz=StringToDoubleInterval(FuzzMenu[entry],(
double)
3480 (void) (
void) CopyMagickString(fuzz,
"20%",MaxTextExtent);
3481 (void) XDialogWidget(display,windows,
"Ok",
3482 "Enter fuzz factor (0.0 - 99.9%):",fuzz);
3485 (void) ConcatenateMagickString(fuzz,
"%",MaxTextExtent);
3486 (*image)->fuzz=StringToDoubleInterval(fuzz,(
double) QuantumRange+
3490 case ColorEditUndoCommand:
3492 (void) XMagickCommand(display,resource_info,windows,UndoCommand,
3496 case ColorEditHelpCommand:
3499 XTextViewHelp(display,resource_info,windows,MagickFalse,
3500 "Help Viewer - Image Annotation",ImageColorEditHelp);
3503 case ColorEditDismissCommand:
3513 (void) XCheckDefineCursor(display,windows->image.id,cursor);
3520 if (event.xbutton.button != Button1)
3522 if ((event.xbutton.window != windows->image.id) &&
3523 (
event.xbutton.window != windows->magnify.id))
3530 (void) XMagickCommand(display,resource_info,windows,
3531 SaveToUndoBufferCommand,image);
3532 state|=UpdateConfigurationState;
3537 if (event.xbutton.button != Button1)
3539 if ((event.xbutton.window != windows->image.id) &&
3540 (
event.xbutton.window != windows->magnify.id))
3547 XConfigureImageColormap(display,resource_info,windows,*image);
3548 (void) XConfigureImage(display,resource_info,windows,*image);
3549 XInfoWidget(display,windows,text);
3550 (void) XCheckDefineCursor(display,windows->image.id,cursor);
3551 state&=(~UpdateConfigurationState);
3561 if (event.xkey.window == windows->magnify.id)
3566 window=windows->magnify.id;
3567 while (XCheckWindowEvent(display,window,KeyPressMask,&event)) ;
3569 if (event.xkey.window != windows->image.id)
3574 (void) XLookupString((XKeyEvent *) &
event.xkey,command,(int)
3575 sizeof(command),&key_symbol,(XComposeStatus *) NULL);
3576 switch ((
int) key_symbol)
3590 XTextViewHelp(display,resource_info,windows,MagickFalse,
3591 "Help Viewer - Image Annotation",ImageColorEditHelp);
3596 (void) XBell(display,0);
3609 if (windows->info.mapped != MagickFalse)
3611 if ((x < (
int) (windows->info.x+windows->info.width)) &&
3612 (y < (int) (windows->info.y+windows->info.height)))
3613 (void) XWithdrawWindow(display,windows->info.id,
3614 windows->info.screen);
3617 if ((x > (
int) (windows->info.x+windows->info.width)) ||
3618 (y > (int) (windows->info.y+windows->info.height)))
3619 (void) XMapWindow(display,windows->info.id);
3625 if (event.xany.window == windows->magnify.id)
3627 x=windows->magnify.x-windows->image.x;
3628 y=windows->magnify.y-windows->image.y;
3632 if ((state & UpdateConfigurationState) != 0)
3644 (void) XClearArea(display,windows->image.id,x_offset,y_offset,1,1,
3646 color=windows->pixel_info->pen_colors[pen_id];
3647 XPutPixel(windows->image.ximage,x_offset,y_offset,color.pixel);
3648 width=(
unsigned int) (*image)->columns;
3649 height=(
unsigned int) (*image)->rows;
3652 if (windows->image.crop_geometry != (
char *) NULL)
3653 (
void) XParseGeometry(windows->image.crop_geometry,&x,&y,
3656 (width*(windows->image.x+x_offset)/windows->image.ximage->width+x);
3658 (height*(windows->image.y+y_offset)/windows->image.ximage->height+y);
3659 if ((x_offset < 0) || (y_offset < 0))
3661 if ((x_offset >= (
int) (*image)->columns) ||
3662 (y_offset >= (
int) (*image)->rows))
3664 exception=(&(*image)->exception);
3665 image_view=AcquireAuthenticCacheView(*image,exception);
3674 if (SetImageStorageClass(*image,DirectClass) == MagickFalse)
3675 return(MagickFalse);
3676 q=GetCacheViewAuthenticPixels(image_view,(ssize_t)x_offset,
3677 (ssize_t)y_offset,1,1,exception);
3680 q->red=ScaleShortToQuantum(color.red);
3681 q->green=ScaleShortToQuantum(color.green);
3682 q->blue=ScaleShortToQuantum(color.blue);
3683 (void) SyncCacheViewAuthenticPixels(image_view,
3684 &(*image)->exception);
3695 (void) GetOneCacheViewVirtualPixel(image_view,(ssize_t) x_offset,
3696 (ssize_t) y_offset,&target,&(*image)->exception);
3697 if ((*image)->storage_class == DirectClass)
3699 for (y=0; y < (int) (*image)->rows; y++)
3701 q=GetCacheViewAuthenticPixels(image_view,0,(ssize_t) y,
3702 (*image)->columns,1,exception);
3705 for (x=0; x < (int) (*image)->columns; x++)
3707 if (IsColorSimilar(*image,q,&target) != MagickFalse)
3709 q->red=ScaleShortToQuantum(color.red);
3710 q->green=ScaleShortToQuantum(color.green);
3711 q->blue=ScaleShortToQuantum(color.blue);
3715 if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
3721 for (i=0; i < (ssize_t) (*image)->colors; i++)
3722 if (IsColorSimilar(*image,(*image)->colormap+i,&target) != MagickFalse)
3724 (*image)->colormap[i].red=ScaleShortToQuantum(color.red);
3725 (*image)->colormap[i].green=ScaleShortToQuantum(
3727 (*image)->colormap[i].blue=ScaleShortToQuantum(
3730 (void) SyncImage(*image);
3734 case FloodfillMethod:
3735 case FillToBorderMethod:
3746 (void) GetOneVirtualMagickPixel(*image,(ssize_t) x_offset,
3747 (ssize_t) y_offset,&target,exception);
3748 if (method == FillToBorderMethod)
3750 target.red=(MagickRealType)
3751 ScaleShortToQuantum(border_color.red);
3752 target.green=(MagickRealType)
3753 ScaleShortToQuantum(border_color.green);
3754 target.blue=(MagickRealType)
3755 ScaleShortToQuantum(border_color.blue);
3757 draw_info=CloneDrawInfo(resource_info->image_info,
3759 (void) QueryColorDatabase(resource_info->pen_colors[pen_id],
3760 &draw_info->fill,exception);
3761 (void) FloodfillPaintImage(*image,DefaultChannels,draw_info,&target,
3762 (ssize_t) x_offset,(ssize_t) y_offset,
3763 method == FloodfillMethod ? MagickFalse : MagickTrue);
3764 draw_info=DestroyDrawInfo(draw_info);
3772 if (SetImageStorageClass(*image,DirectClass) == MagickFalse)
3773 return(MagickFalse);
3774 for (y=0; y < (int) (*image)->rows; y++)
3776 q=QueueCacheViewAuthenticPixels(image_view,0,(ssize_t) y,
3777 (*image)->columns,1,exception);
3780 for (x=0; x < (int) (*image)->columns; x++)
3782 q->red=ScaleShortToQuantum(color.red);
3783 q->green=ScaleShortToQuantum(color.green);
3784 q->blue=ScaleShortToQuantum(color.blue);
3787 if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
3793 image_view=DestroyCacheView(image_view);
3794 state&=(~UpdateConfigurationState);
3796 }
while ((state & ExitState) == 0);
3797 (void) XSelectInput(display,windows->image.id,
3798 windows->image.attributes.event_mask);
3799 XSetCursorState(display,windows,MagickFalse);
3800 (void) XFreeCursor(display,cursor);
3836 static MagickBooleanType XCompositeImage(Display *display,
3837 XResourceInfo *resource_info,XWindows *windows,
Image *image)
3840 *
const CompositeMenu[] =
3851 displacement_geometry[MaxTextExtent] =
"30x30",
3852 filename[MaxTextExtent] =
"\0";
3854 static CompositeOperator
3855 compose = CopyCompositeOp;
3857 static const ModeType
3858 CompositeCommands[] =
3860 CompositeOperatorsCommand,
3861 CompositeDissolveCommand,
3862 CompositeDisplaceCommand,
3863 CompositeHelpCommand,
3864 CompositeDismissCommand
3868 text[MaxTextExtent];
3903 XFileBrowserWidget(display,windows,
"Composite",filename);
3904 if (*filename ==
'\0')
3909 XSetCursorState(display,windows,MagickTrue);
3910 XCheckRefreshWindows(display,windows);
3911 (void) CopyMagickString(resource_info->image_info->filename,filename,
3913 composite_image=ReadImage(resource_info->image_info,&image->exception);
3914 CatchException(&image->exception);
3915 XSetCursorState(display,windows,MagickFalse);
3916 if (composite_image == (
Image *) NULL)
3917 return(MagickFalse);
3921 (void) CloneString(&windows->command.name,
"Composite");
3922 windows->command.data=1;
3923 (void) XCommandWidget(display,windows,CompositeMenu,(XEvent *) NULL);
3924 (void) XMapRaised(display,windows->command.id);
3925 XClientMessage(display,windows->image.id,windows->im_protocols,
3926 windows->im_update_widget,CurrentTime);
3930 XQueryPosition(display,windows->image.id,&x,&y);
3931 (void) XSelectInput(display,windows->image.id,
3932 windows->image.attributes.event_mask | PointerMotionMask);
3933 composite_info.x=(ssize_t) windows->image.x+x;
3934 composite_info.y=(ssize_t) windows->image.y+y;
3935 composite_info.width=0;
3936 composite_info.height=0;
3937 cursor=XCreateFontCursor(display,XC_ul_angle);
3938 (void) XSetFunction(display,windows->image.highlight_context,GXinvert);
3943 if (windows->info.mapped != MagickFalse)
3948 (void) FormatLocaleString(text,MaxTextExtent,
" %+ld%+ld ",
3949 (
long) composite_info.x,(long) composite_info.y);
3950 XInfoWidget(display,windows,text);
3952 highlight_info=composite_info;
3953 highlight_info.x=composite_info.x-windows->image.x;
3954 highlight_info.y=composite_info.y-windows->image.y;
3955 XHighlightRectangle(display,windows->image.id,
3956 windows->image.highlight_context,&highlight_info);
3960 XScreenEvent(display,windows,&event);
3961 XHighlightRectangle(display,windows->image.id,
3962 windows->image.highlight_context,&highlight_info);
3963 if (event.xany.window == windows->command.id)
3968 id=XCommandWidget(display,windows,CompositeMenu,&event);
3971 switch (CompositeCommands[
id])
3973 case CompositeOperatorsCommand:
3976 command[MaxTextExtent],
3982 operators=GetCommandOptions(MagickComposeOptions);
3983 if (operators == (
char **) NULL)
3985 entry=XMenuWidget(display,windows,CompositeMenu[
id],
3986 (
const char **) operators,command);
3988 compose=(CompositeOperator) ParseCommandOption(
3989 MagickComposeOptions,MagickFalse,operators[entry]);
3990 operators=DestroyStringList(operators);
3993 case CompositeDissolveCommand:
3996 factor[MaxTextExtent] =
"20.0";
4001 (void) XSetFunction(display,windows->image.highlight_context,
4003 (void) XDialogWidget(display,windows,
"Dissolve",
4004 "Enter the blend factor (0.0 - 99.9%):",factor);
4005 (void) XSetFunction(display,windows->image.highlight_context,
4007 if (*factor ==
'\0')
4009 blend=StringToDouble(factor,(
char **) NULL);
4010 compose=DissolveCompositeOp;
4013 case CompositeDisplaceCommand:
4018 (void) XSetFunction(display,windows->image.highlight_context,
4020 (void) XDialogWidget(display,windows,
"Displace",
4021 "Enter the horizontal and vertical scale:",displacement_geometry);
4022 (void) XSetFunction(display,windows->image.highlight_context,
4024 if (*displacement_geometry ==
'\0')
4026 compose=DisplaceCompositeOp;
4029 case CompositeHelpCommand:
4031 (void) XSetFunction(display,windows->image.highlight_context,
4033 XTextViewHelp(display,resource_info,windows,MagickFalse,
4034 "Help Viewer - Image Composite",ImageCompositeHelp);
4035 (void) XSetFunction(display,windows->image.highlight_context,
4039 case CompositeDismissCommand:
4057 if (resource_info->debug != MagickFalse)
4058 (void) LogMagickEvent(X11Event,GetMagickModule(),
4059 "Button Press: 0x%lx %u +%d+%d",
event.xbutton.window,
4060 event.xbutton.button,
event.xbutton.x,
event.xbutton.y);
4061 if (event.xbutton.button != Button1)
4063 if (event.xbutton.window != windows->image.id)
4068 composite_info.width=composite_image->columns;
4069 composite_info.height=composite_image->rows;
4070 (void) XCheckDefineCursor(display,windows->image.id,cursor);
4071 composite_info.x=(ssize_t) windows->image.x+event.xbutton.x;
4072 composite_info.y=(ssize_t) windows->image.y+
event.xbutton.y;
4077 if (resource_info->debug != MagickFalse)
4078 (void) LogMagickEvent(X11Event,GetMagickModule(),
4079 "Button Release: 0x%lx %u +%d+%d",
event.xbutton.window,
4080 event.xbutton.button,
event.xbutton.x,
event.xbutton.y);
4081 if (event.xbutton.button != Button1)
4083 if (event.xbutton.window != windows->image.id)
4085 if ((composite_info.width != 0) && (composite_info.height != 0))
4090 composite_info.x=(ssize_t) windows->image.x+event.xbutton.x;
4091 composite_info.y=(ssize_t) windows->image.y+
event.xbutton.y;
4101 command[MaxTextExtent];
4109 if (event.xkey.window != windows->image.id)
4114 length=XLookupString((XKeyEvent *) &event.xkey,command,(
int)
4115 sizeof(command),&key_symbol,(XComposeStatus *) NULL);
4116 *(command+length)=
'\0';
4117 if (resource_info->debug != MagickFalse)
4118 (void) LogMagickEvent(X11Event,GetMagickModule(),
4119 "Key press: 0x%lx (%s)",(
unsigned long) key_symbol,command);
4120 switch ((
int) key_symbol)
4128 composite_image=DestroyImage(composite_image);
4136 (void) XSetFunction(display,windows->image.highlight_context,
4138 XTextViewHelp(display,resource_info,windows,MagickFalse,
4139 "Help Viewer - Image Composite",ImageCompositeHelp);
4140 (void) XSetFunction(display,windows->image.highlight_context,
4146 (void) XBell(display,0);
4159 if (windows->info.mapped != MagickFalse)
4161 if ((x < (
int) (windows->info.x+windows->info.width)) &&
4162 (y < (int) (windows->info.y+windows->info.height)))
4163 (void) XWithdrawWindow(display,windows->info.id,
4164 windows->info.screen);
4167 if ((x > (
int) (windows->info.x+windows->info.width)) ||
4168 (y > (int) (windows->info.y+windows->info.height)))
4169 (void) XMapWindow(display,windows->info.id);
4170 composite_info.x=(ssize_t) windows->image.x+x;
4171 composite_info.y=(ssize_t) windows->image.y+y;
4176 if (resource_info->debug != MagickFalse)
4177 (void) LogMagickEvent(X11Event,GetMagickModule(),
"Event type: %d",
4182 }
while ((state & ExitState) == 0);
4183 (void) XSelectInput(display,windows->image.id,
4184 windows->image.attributes.event_mask);
4185 (void) XSetFunction(display,windows->image.highlight_context,GXcopy);
4186 XSetCursorState(display,windows,MagickFalse);
4187 (void) XFreeCursor(display,cursor);
4188 if ((state & EscapeState) != 0)
4193 XSetCursorState(display,windows,MagickTrue);
4194 XCheckRefreshWindows(display,windows);
4195 width=(
unsigned int) image->columns;
4196 height=(
unsigned int) image->rows;
4199 if (windows->image.crop_geometry != (
char *) NULL)
4200 (
void) XParseGeometry(windows->image.crop_geometry,&x,&y,&width,&height);
4201 scale_factor=(MagickRealType) width/windows->image.ximage->width;
4202 composite_info.x+=x;
4203 composite_info.x=(ssize_t) (scale_factor*composite_info.x+0.5);
4204 composite_info.width=(
unsigned int) (scale_factor*composite_info.width+0.5);
4205 scale_factor=(MagickRealType) height/windows->image.ximage->height;
4206 composite_info.y+=y;
4207 composite_info.y=(ssize_t) (scale_factor*composite_info.y+0.5);
4208 composite_info.height=(
unsigned int) (scale_factor*composite_info.height+0.5);
4209 if ((composite_info.width != composite_image->columns) ||
4210 (composite_info.height != composite_image->rows))
4218 resize_image=ResizeImage(composite_image,composite_info.width,
4219 composite_info.height,composite_image->filter,composite_image->blur,
4221 composite_image=DestroyImage(composite_image);
4222 if (resize_image == (
Image *) NULL)
4224 XSetCursorState(display,windows,MagickFalse);
4225 return(MagickFalse);
4227 composite_image=resize_image;
4229 if (compose == DisplaceCompositeOp)
4230 (void) SetImageArtifact(composite_image,
"compose:args",
4231 displacement_geometry);
4255 (void) SetImageAlphaChannel(composite_image,OpaqueAlphaChannel);
4256 opacity=(Quantum) (ScaleQuantumToChar(QuantumRange)-
4257 ((ssize_t) ScaleQuantumToChar(QuantumRange)*blend)/100);
4258 if (SetImageStorageClass(image,DirectClass) == MagickFalse)
4259 return(MagickFalse);
4260 image->matte=MagickTrue;
4261 exception=(&image->exception);
4262 image_view=AcquireAuthenticCacheView(image,exception);
4263 for (y=0; y < (int) image->rows; y++)
4265 q=GetCacheViewAuthenticPixels(image_view,0,(ssize_t) y,image->columns,1,
4269 for (x=0; x < (int) image->columns; x++)
4274 if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
4277 image_view=DestroyCacheView(image_view);
4282 (void) CompositeImage(image,compose,composite_image,composite_info.x,
4284 composite_image=DestroyImage(composite_image);
4285 XSetCursorState(display,windows,MagickFalse);
4289 XConfigureImageColormap(display,resource_info,windows,image);
4290 (void) XConfigureImage(display,resource_info,windows,image);
4326 static MagickBooleanType XConfigureImage(Display *display,
4327 XResourceInfo *resource_info,XWindows *windows,
Image *image)
4330 geometry[MaxTextExtent];
4353 width=(
unsigned int) windows->image.window_changes.width;
4354 height=(
unsigned int) windows->image.window_changes.height;
4355 if (resource_info->debug != MagickFalse)
4356 (void) LogMagickEvent(X11Event,GetMagickModule(),
4357 "Configure Image: %dx%d=>%.20gx%.20g",windows->image.ximage->width,
4358 windows->image.ximage->height,(double) width,(
double) height);
4359 if ((width*height) == 0)
4366 XSetCursorState(display,windows,MagickTrue);
4367 (void) XFlush(display);
4368 if (((
int) width != windows->image.ximage->width) ||
4369 ((int) height != windows->image.ximage->height))
4370 image->taint=MagickTrue;
4371 windows->magnify.x=(
int)
4372 width*windows->magnify.x/windows->image.ximage->width;
4373 windows->magnify.y=(int)
4374 height*windows->magnify.y/windows->image.ximage->height;
4375 windows->image.x=(
int) (width*windows->image.x/windows->image.ximage->width);
4376 windows->image.y=(int)
4377 (height*windows->image.y/windows->image.ximage->height);
4378 status=XMakeImage(display,resource_info,&windows->image,image,
4379 (
unsigned int) width,(
unsigned int) height);
4380 if (status == MagickFalse)
4381 XNoticeWidget(display,windows,
"Unable to configure X image:",
4382 windows->image.name);
4386 if (resource_info->image_geometry != (
char *) NULL)
4387 (void) FormatLocaleString(geometry,MaxTextExtent,
"%s>!",
4388 resource_info->image_geometry);
4390 (
void) FormatLocaleString(geometry,MaxTextExtent,
"%ux%u+0+0>!",
4391 XDisplayWidth(display,windows->image.screen),
4392 XDisplayHeight(display,windows->image.screen));
4393 (void) ParseMetaGeometry(geometry,&x,&y,&width,&height);
4394 window_changes.width=(int) width;
4395 if (window_changes.width > XDisplayWidth(display,windows->image.screen))
4396 window_changes.width=XDisplayWidth(display,windows->image.screen);
4397 window_changes.height=(int) height;
4398 if (window_changes.height > XDisplayHeight(display,windows->image.screen))
4399 window_changes.height=XDisplayHeight(display,windows->image.screen);
4400 mask=(size_t) (CWWidth | CWHeight);
4401 if (resource_info->backdrop)
4404 window_changes.x=(int)
4405 ((XDisplayWidth(display,windows->image.screen)/2)-(width/2));
4406 window_changes.y=(int)
4407 ((XDisplayHeight(display,windows->image.screen)/2)-(height/2));
4409 (void) XReconfigureWMWindow(display,windows->image.id,windows->image.screen,
4410 (
unsigned int) mask,&window_changes);
4411 (void) XClearWindow(display,windows->image.id);
4412 XRefreshWindow(display,&windows->image,(XEvent *) NULL);
4416 if (windows->magnify.mapped != MagickFalse)
4417 XMakeMagnifyImage(display,windows);
4418 windows->pan.crop_geometry=windows->image.crop_geometry;
4419 XBestIconSize(display,&windows->pan,image);
4420 while (((windows->pan.width << 1) < MaxIconSize) &&
4421 ((windows->pan.height << 1) < MaxIconSize))
4423 windows->pan.width<<=1;
4424 windows->pan.height<<=1;
4426 if (windows->pan.geometry != (
char *) NULL)
4427 (void) XParseGeometry(windows->pan.geometry,&windows->pan.x,&windows->pan.y,
4428 &windows->pan.width,&windows->pan.height);
4429 window_changes.width=(int) windows->pan.width;
4430 window_changes.height=(
int) windows->pan.height;
4431 size_hints=XAllocSizeHints();
4432 if (size_hints != (XSizeHints *) NULL)
4437 size_hints->flags=PSize | PMinSize | PMaxSize;
4438 size_hints->width=window_changes.width;
4439 size_hints->height=window_changes.height;
4440 size_hints->min_width=size_hints->width;
4441 size_hints->min_height=size_hints->height;
4442 size_hints->max_width=size_hints->width;
4443 size_hints->max_height=size_hints->height;
4444 (void) XSetNormalHints(display,windows->pan.id,size_hints);
4445 (void) XFree((
void *) size_hints);
4447 (void) XReconfigureWMWindow(display,windows->pan.id,windows->pan.screen,
4448 (
unsigned int) (CWWidth | CWHeight),&window_changes);
4452 windows->icon.crop_geometry=windows->image.crop_geometry;
4453 XBestIconSize(display,&windows->icon,image);
4454 window_changes.width=(int) windows->icon.width;
4455 window_changes.height=(
int) windows->icon.height;
4456 (void) XReconfigureWMWindow(display,windows->icon.id,windows->icon.screen,
4457 (
unsigned int) (CWWidth | CWHeight),&window_changes);
4458 XSetCursorState(display,windows,MagickFalse);
4459 return(status != 0 ? MagickTrue : MagickFalse);
4498 static MagickBooleanType XCropImage(Display *display,
4499 XResourceInfo *resource_info,XWindows *windows,
Image *image,
4500 const ClipboardMode mode)
4509 *RectifyModeMenu[] =
4517 static const ModeType
4527 RectifyDismissCommand
4534 command[MaxTextExtent],
4535 text[MaxTextExtent];
4581 (void) CloneString(&windows->command.name,
"Copy");
4586 (void) CloneString(&windows->command.name,
"Crop");
4591 (void) CloneString(&windows->command.name,
"Cut");
4595 RectifyModeMenu[0]=windows->command.name;
4596 windows->command.data=0;
4597 (void) XCommandWidget(display,windows,CropModeMenu,(XEvent *) NULL);
4598 (void) XMapRaised(display,windows->command.id);
4599 XClientMessage(display,windows->image.id,windows->im_protocols,
4600 windows->im_update_widget,CurrentTime);
4604 XQueryPosition(display,windows->image.id,&x,&y);
4605 (void) XSelectInput(display,windows->image.id,
4606 windows->image.attributes.event_mask | PointerMotionMask);
4607 crop_info.x=(ssize_t) windows->image.x+x;
4608 crop_info.y=(ssize_t) windows->image.y+y;
4611 cursor=XCreateFontCursor(display,XC_fleur);
4615 if (windows->info.mapped != MagickFalse)
4620 (void) FormatLocaleString(text,MaxTextExtent,
" %+ld%+ld ",
4621 (
long) crop_info.x,(long) crop_info.y);
4622 XInfoWidget(display,windows,text);
4627 XScreenEvent(display,windows,&event);
4628 if (event.xany.window == windows->command.id)
4633 id=XCommandWidget(display,windows,CropModeMenu,&event);
4636 switch (CropCommands[
id])
4638 case CropHelpCommand:
4644 XTextViewHelp(display,resource_info,windows,MagickFalse,
4645 "Help Viewer - Image Copy",ImageCopyHelp);
4650 XTextViewHelp(display,resource_info,windows,MagickFalse,
4651 "Help Viewer - Image Crop",ImageCropHelp);
4656 XTextViewHelp(display,resource_info,windows,MagickFalse,
4657 "Help Viewer - Image Cut",ImageCutHelp);
4663 case CropDismissCommand:
4681 if (event.xbutton.button != Button1)
4683 if (event.xbutton.window != windows->image.id)
4688 (void) XCheckDefineCursor(display,windows->image.id,cursor);
4689 crop_info.x=(ssize_t) windows->image.x+event.xbutton.x;
4690 crop_info.y=(ssize_t) windows->image.y+
event.xbutton.y;
4700 if (event.xkey.window != windows->image.id)
4705 (void) XLookupString((XKeyEvent *) &
event.xkey,command,(int)
4706 sizeof(command),&key_symbol,(XComposeStatus *) NULL);
4707 switch ((
int) key_symbol)
4726 XTextViewHelp(display,resource_info,windows,MagickFalse,
4727 "Help Viewer - Image Copy",ImageCopyHelp);
4732 XTextViewHelp(display,resource_info,windows,MagickFalse,
4733 "Help Viewer - Image Crop",ImageCropHelp);
4738 XTextViewHelp(display,resource_info,windows,MagickFalse,
4739 "Help Viewer - Image Cut",ImageCutHelp);
4747 (void) XBell(display,0);
4755 if (event.xmotion.window != windows->image.id)
4762 if (windows->info.mapped != MagickFalse)
4764 if ((x < (
int) (windows->info.x+windows->info.width)) &&
4765 (y < (int) (windows->info.y+windows->info.height)))
4766 (void) XWithdrawWindow(display,windows->info.id,
4767 windows->info.screen);
4770 if ((x > (
int) (windows->info.x+windows->info.width)) ||
4771 (y > (int) (windows->info.y+windows->info.height)))
4772 (void) XMapWindow(display,windows->info.id);
4773 crop_info.x=(ssize_t) windows->image.x+x;
4774 crop_info.y=(ssize_t) windows->image.y+y;
4780 }
while ((state & ExitState) == 0);
4781 (void) XSelectInput(display,windows->image.id,
4782 windows->image.attributes.event_mask);
4783 if ((state & EscapeState) != 0)
4788 (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
4789 (void) XFreeCursor(display,cursor);
4792 (void) XSetFunction(display,windows->image.highlight_context,GXinvert);
4798 x=(int) crop_info.x;
4799 y=(
int) crop_info.y;
4805 highlight_info=crop_info;
4806 highlight_info.x=crop_info.x-windows->image.x;
4807 highlight_info.y=crop_info.y-windows->image.y;
4808 if ((highlight_info.width > 3) && (highlight_info.height > 3))
4813 if (windows->info.mapped == MagickFalse)
4814 (void) XMapWindow(display,windows->info.id);
4815 (void) FormatLocaleString(text,MaxTextExtent,
4816 " %.20gx%.20g%+.20g%+.20g",(
double) crop_info.width,(double)
4817 crop_info.height,(
double) crop_info.x,(double) crop_info.y);
4818 XInfoWidget(display,windows,text);
4819 XHighlightRectangle(display,windows->image.id,
4820 windows->image.highlight_context,&highlight_info);
4823 if (windows->info.mapped != MagickFalse)
4824 (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
4828 XScreenEvent(display,windows,&event);
4829 if ((highlight_info.width > 3) && (highlight_info.height > 3))
4830 XHighlightRectangle(display,windows->image.id,
4831 windows->image.highlight_context,&highlight_info);
4836 crop_info.x=(ssize_t) windows->image.x+event.xbutton.x;
4837 crop_info.y=(ssize_t) windows->image.y+
event.xbutton.y;
4845 crop_info.x=(ssize_t) windows->image.x+event.xbutton.x;
4846 crop_info.y=(ssize_t) windows->image.y+
event.xbutton.y;
4847 XSetCursorState(display,windows,MagickFalse);
4849 windows->command.data=0;
4850 (void) XCommandWidget(display,windows,RectifyModeMenu,
4858 crop_info.x=(ssize_t) windows->image.x+event.xmotion.x;
4859 crop_info.y=(ssize_t) windows->image.y+
event.xmotion.y;
4864 if ((((
int) crop_info.x != x) && ((int) crop_info.y != y)) ||
4865 ((state & ExitState) != 0))
4870 if (crop_info.x < 0)
4873 if (crop_info.x > (ssize_t) windows->image.ximage->width)
4874 crop_info.x=(ssize_t) windows->image.ximage->width;
4875 if ((
int) crop_info.x < x)
4876 crop_info.width=(
unsigned int) (x-crop_info.x);
4879 crop_info.width=(
unsigned int) (crop_info.x-x);
4880 crop_info.x=(ssize_t) x;
4882 if (crop_info.y < 0)
4885 if (crop_info.y > (ssize_t) windows->image.ximage->height)
4886 crop_info.y=(ssize_t) windows->image.ximage->height;
4887 if ((
int) crop_info.y < y)
4888 crop_info.height=(
unsigned int) (y-crop_info.y);
4891 crop_info.height=(
unsigned int) (crop_info.y-y);
4892 crop_info.y=(ssize_t) y;
4895 }
while ((state & ExitState) == 0);
4900 (void) XMapWindow(display,windows->info.id);
4903 if (windows->info.mapped != MagickFalse)
4908 (void) FormatLocaleString(text,MaxTextExtent,
4909 " %.20gx%.20g%+.20g%+.20g",(
double) crop_info.width,(double)
4910 crop_info.height,(
double) crop_info.x,(double) crop_info.y);
4911 XInfoWidget(display,windows,text);
4913 highlight_info=crop_info;
4914 highlight_info.x=crop_info.x-windows->image.x;
4915 highlight_info.y=crop_info.y-windows->image.y;
4916 if ((highlight_info.width <= 3) || (highlight_info.height <= 3))
4922 XHighlightRectangle(display,windows->image.id,
4923 windows->image.highlight_context,&highlight_info);
4924 XScreenEvent(display,windows,&event);
4925 if (event.xany.window == windows->command.id)
4930 (void) XSetFunction(display,windows->image.highlight_context,GXcopy);
4931 id=XCommandWidget(display,windows,RectifyModeMenu,&event);
4932 (void) XSetFunction(display,windows->image.highlight_context,
4934 XHighlightRectangle(display,windows->image.id,
4935 windows->image.highlight_context,&highlight_info);
4937 switch (RectifyCommands[
id])
4939 case RectifyCopyCommand:
4944 case RectifyHelpCommand:
4946 (void) XSetFunction(display,windows->image.highlight_context,
4952 XTextViewHelp(display,resource_info,windows,MagickFalse,
4953 "Help Viewer - Image Copy",ImageCopyHelp);
4958 XTextViewHelp(display,resource_info,windows,MagickFalse,
4959 "Help Viewer - Image Crop",ImageCropHelp);
4964 XTextViewHelp(display,resource_info,windows,MagickFalse,
4965 "Help Viewer - Image Cut",ImageCutHelp);
4969 (void) XSetFunction(display,windows->image.highlight_context,
4973 case RectifyDismissCommand:
4987 XHighlightRectangle(display,windows->image.id,
4988 windows->image.highlight_context,&highlight_info);
4993 if (event.xbutton.button != Button1)
4995 if (event.xbutton.window != windows->image.id)
4997 x=windows->image.x+
event.xbutton.x;
4998 y=windows->image.y+
event.xbutton.y;
4999 if ((x < (
int) (crop_info.x+RoiDelta)) &&
5000 (x > (
int) (crop_info.x-RoiDelta)) &&
5001 (y < (
int) (crop_info.y+RoiDelta)) &&
5002 (y > (
int) (crop_info.y-RoiDelta)))
5004 crop_info.x=(ssize_t) (crop_info.x+crop_info.width);
5005 crop_info.y=(ssize_t) (crop_info.y+crop_info.height);
5006 state|=UpdateConfigurationState;
5009 if ((x < (
int) (crop_info.x+RoiDelta)) &&
5010 (x > (int) (crop_info.x-RoiDelta)) &&
5011 (y < (
int) (crop_info.y+crop_info.height+RoiDelta)) &&
5012 (y > (int) (crop_info.y+crop_info.height-RoiDelta)))
5014 crop_info.x=(ssize_t) (crop_info.x+crop_info.width);
5015 state|=UpdateConfigurationState;
5018 if ((x < (
int) (crop_info.x+crop_info.width+RoiDelta)) &&
5019 (x > (int) (crop_info.x+crop_info.width-RoiDelta)) &&
5020 (y < (
int) (crop_info.y+RoiDelta)) &&
5021 (y > (int) (crop_info.y-RoiDelta)))
5023 crop_info.y=(ssize_t) (crop_info.y+crop_info.height);
5024 state|=UpdateConfigurationState;
5027 if ((x < (
int) (crop_info.x+crop_info.width+RoiDelta)) &&
5028 (x > (int) (crop_info.x+crop_info.width-RoiDelta)) &&
5029 (y < (
int) (crop_info.y+crop_info.height+RoiDelta)) &&
5030 (y > (int) (crop_info.y+crop_info.height-RoiDelta)))
5032 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)
5085 crop_info.x=(ssize_t) (windows->image.width/2L-crop_info.width/
5087 crop_info.y=(ssize_t) (windows->image.height/2L-crop_info.height/
5120 (void) XSetFunction(display,windows->image.highlight_context,
5126 XTextViewHelp(display,resource_info,windows,MagickFalse,
5127 "Help Viewer - Image Copy",ImageCopyHelp);
5132 XTextViewHelp(display,resource_info,windows,MagickFalse,
5133 "Help Viewer - Image Cropg",ImageCropHelp);
5138 XTextViewHelp(display,resource_info,windows,MagickFalse,
5139 "Help Viewer - Image Cutg",ImageCutHelp);
5143 (void) XSetFunction(display,windows->image.highlight_context,
5149 (void) XBell(display,0);
5153 (void) XSetSelectionOwner(display,XA_PRIMARY,windows->image.id,
5161 if (event.xmotion.window != windows->image.id)
5168 if (windows->info.mapped != MagickFalse)
5170 if ((x < (
int) (windows->info.x+windows->info.width)) &&
5171 (y < (int) (windows->info.y+windows->info.height)))
5172 (void) XWithdrawWindow(display,windows->info.id,
5173 windows->info.screen);
5176 if ((x > (
int) (windows->info.x+windows->info.width)) ||
5177 (y > (int) (windows->info.y+windows->info.height)))
5178 (void) XMapWindow(display,windows->info.id);
5179 crop_info.x=(ssize_t) windows->image.x+event.xmotion.x;
5180 crop_info.y=(ssize_t) windows->image.y+
event.xmotion.y;
5183 case SelectionRequest:
5188 XSelectionRequestEvent
5194 (void) FormatLocaleString(text,MaxTextExtent,
5195 "%.20gx%.20g%+.20g%+.20g",(
double) crop_info.width,(double)
5196 crop_info.height,(
double) crop_info.x,(double) crop_info.y);
5197 request=(&(
event.xselectionrequest));
5198 (void) XChangeProperty(request->display,request->requestor,
5199 request->property,request->target,8,PropModeReplace,
5200 (
unsigned char *) text,(int) strlen(text));
5201 notify.type=SelectionNotify;
5202 notify.display=request->display;
5203 notify.requestor=request->requestor;
5204 notify.selection=request->selection;
5205 notify.target=request->target;
5206 notify.time=request->time;
5207 if (request->property == None)
5208 notify.property=request->target;
5210 notify.property=request->property;
5211 (void) XSendEvent(request->display,request->requestor,False,0,
5212 (XEvent *) ¬ify);
5217 if ((state & UpdateConfigurationState) != 0)
5219 (void) XPutBackEvent(display,&event);
5220 (void) XCheckDefineCursor(display,windows->image.id,cursor);
5223 }
while ((state & ExitState) == 0);
5224 }
while ((state & ExitState) == 0);
5225 (void) XSetFunction(display,windows->image.highlight_context,GXcopy);
5226 XSetCursorState(display,windows,MagickFalse);
5227 if ((state & EscapeState) != 0)
5229 if (mode == CropMode)
5230 if (((
int) crop_info.width != windows->image.ximage->width) ||
5231 ((
int) crop_info.height != windows->image.ximage->height))
5236 XSetCropGeometry(display,windows,&crop_info,image);
5237 windows->image.window_changes.width=(int) crop_info.width;
5238 windows->image.window_changes.height=(
int) crop_info.height;
5239 (void) XConfigureImage(display,resource_info,windows,image);
5245 XSetCursorState(display,windows,MagickTrue);
5246 XCheckRefreshWindows(display,windows);
5247 width=(
unsigned int) image->columns;
5248 height=(
unsigned int) image->rows;
5251 if (windows->image.crop_geometry != (
char *) NULL)
5252 (
void) XParseGeometry(windows->image.crop_geometry,&x,&y,&width,&height);
5253 scale_factor=(MagickRealType) width/windows->image.ximage->width;
5255 crop_info.x=(ssize_t) (scale_factor*crop_info.x+0.5);
5256 crop_info.x+=image->page.x;
5257 crop_info.width=(
unsigned int) (scale_factor*crop_info.width+0.5);
5258 scale_factor=(MagickRealType) height/windows->image.ximage->height;
5260 crop_info.y=(ssize_t) (scale_factor*crop_info.y+0.5);
5261 crop_info.y+=image->page.y;
5262 crop_info.height=(
unsigned int) (scale_factor*crop_info.height+0.5);
5263 crop_image=CropImage(image,&crop_info,&image->exception);
5264 XSetCursorState(display,windows,MagickFalse);
5265 if (crop_image == (
Image *) NULL)
5266 return(MagickFalse);
5267 if (resource_info->copy_image != (
Image *) NULL)
5268 resource_info->copy_image=DestroyImage(resource_info->copy_image);
5269 resource_info->copy_image=crop_image;
5270 if (mode == CopyMode)
5272 (void) XConfigureImage(display,resource_info,windows,image);
5278 if (SetImageStorageClass(image,DirectClass) == MagickFalse)
5279 return(MagickFalse);
5280 image->matte=MagickTrue;
5281 exception=(&image->exception);
5282 image_view=AcquireAuthenticCacheView(image,exception);
5283 for (y=0; y < (int) crop_info.height; y++)
5285 q=GetCacheViewAuthenticPixels(image_view,crop_info.x,y+crop_info.y,
5286 crop_info.width,1,exception);
5289 for (x=0; x < (int) crop_info.width; x++)
5291 q->opacity=(Quantum) TransparentOpacity;
5294 if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
5297 image_view=DestroyCacheView(image_view);
5301 XConfigureImageColormap(display,resource_info,windows,image);
5302 (void) XConfigureImage(display,resource_info,windows,image);
5337 static MagickBooleanType XDrawEditImage(Display *display,
5338 XResourceInfo *resource_info,XWindows *windows,
Image **image)
5354 element = PointElement;
5356 static const ModeType
5369 stipple = (Pixmap) NULL;
5376 command[MaxTextExtent],
5377 text[MaxTextExtent];
5428 max_coordinates=2048;
5429 coordinate_info=(XPoint *) AcquireQuantumMemory((
size_t) max_coordinates,
5430 sizeof(*coordinate_info));
5431 if (coordinate_info == (XPoint *) NULL)
5433 (void) ThrowMagickException(&(*image)->exception,GetMagickModule(),
5434 ResourceLimitError,
"MemoryAllocationFailed",
"`%s'",
"...");
5435 return(MagickFalse);
5440 (void) CloneString(&windows->command.name,
"Draw");
5441 windows->command.data=4;
5442 (void) XCommandWidget(display,windows,DrawMenu,(XEvent *) NULL);
5443 (void) XMapRaised(display,windows->command.id);
5444 XClientMessage(display,windows->image.id,windows->im_protocols,
5445 windows->im_update_widget,CurrentTime);
5449 root_window=XRootWindow(display,XDefaultScreen(display));
5450 draw_info.stencil=OpaqueStencil;
5452 cursor=XCreateFontCursor(display,XC_tcross);
5455 XQueryPosition(display,windows->image.id,&x,&y);
5456 (void) XSelectInput(display,windows->image.id,
5457 windows->image.attributes.event_mask | PointerMotionMask);
5458 (void) XCheckDefineCursor(display,windows->image.id,cursor);
5462 if (windows->info.mapped != MagickFalse)
5467 (void) FormatLocaleString(text,MaxTextExtent,
" %+d%+d ",
5468 x+windows->image.x,y+windows->image.y);
5469 XInfoWidget(display,windows,text);
5474 XScreenEvent(display,windows,&event);
5475 if (event.xany.window == windows->command.id)
5480 id=XCommandWidget(display,windows,DrawMenu,&event);
5483 switch (DrawCommands[
id])
5485 case DrawElementCommand:
5506 element=(ElementType) (XMenuWidget(display,windows,
5507 DrawMenu[
id],Elements,command)+1);
5510 case DrawColorCommand:
5513 *ColorMenu[MaxNumberPens+1];
5527 for (i=0; i < (int) (MaxNumberPens-2); i++)
5528 ColorMenu[i]=resource_info->pen_colors[i];
5529 ColorMenu[MaxNumberPens-2]=
"transparent";
5530 ColorMenu[MaxNumberPens-1]=
"Browser...";
5531 ColorMenu[MaxNumberPens]=(
char *) NULL;
5535 pen_number=XMenuWidget(display,windows,DrawMenu[
id],
5536 (
const char **) ColorMenu,command);
5539 transparent=pen_number == (MaxNumberPens-2) ? MagickTrue :
5541 if (transparent != MagickFalse)
5543 draw_info.stencil=TransparentStencil;
5546 if (pen_number == (MaxNumberPens-1))
5549 color_name[MaxTextExtent] =
"gray";
5554 resource_info->pen_colors[pen_number]=color_name;
5555 XColorBrowserWidget(display,windows,
"Select",color_name);
5556 if (*color_name ==
'\0')
5562 (void) XParseColor(display,windows->map_info->colormap,
5563 resource_info->pen_colors[pen_number],&color);
5564 XBestPixel(display,windows->map_info->colormap,(XColor *) NULL,
5565 (
unsigned int) MaxColors,&color);
5566 windows->pixel_info->pen_colors[pen_number]=color;
5567 pen_id=(
unsigned int) pen_number;
5568 draw_info.stencil=OpaqueStencil;
5571 case DrawStippleCommand:
5597 filename[MaxTextExtent] =
"\0";
5602 StipplesMenu[7]=
"Open...";
5603 entry=XMenuWidget(display,windows,DrawMenu[
id],StipplesMenu,
5607 if (stipple != (Pixmap) NULL)
5608 (void) XFreePixmap(display,stipple);
5609 stipple=(Pixmap) NULL;
5616 stipple=XCreateBitmapFromData(display,root_window,
5617 (
char *) BricksBitmap,BricksWidth,BricksHeight);
5622 stipple=XCreateBitmapFromData(display,root_window,
5623 (
char *) DiagonalBitmap,DiagonalWidth,DiagonalHeight);
5628 stipple=XCreateBitmapFromData(display,root_window,
5629 (
char *) ScalesBitmap,ScalesWidth,ScalesHeight);
5634 stipple=XCreateBitmapFromData(display,root_window,
5635 (
char *) VerticalBitmap,VerticalWidth,VerticalHeight);
5640 stipple=XCreateBitmapFromData(display,root_window,
5641 (
char *) WavyBitmap,WavyWidth,WavyHeight);
5646 stipple=XCreateBitmapFromData(display,root_window,
5647 (
char *) HighlightBitmap,HighlightWidth,
5654 stipple=XCreateBitmapFromData(display,root_window,
5655 (
char *) OpaqueBitmap,OpaqueWidth,OpaqueHeight);
5661 XFileBrowserWidget(display,windows,
"Stipple",filename);
5662 if (*filename ==
'\0')
5667 XSetCursorState(display,windows,MagickTrue);
5668 XCheckRefreshWindows(display,windows);
5669 image_info=AcquireImageInfo();
5670 (void) CopyMagickString(image_info->filename,filename,
5672 stipple_image=ReadImage(image_info,&(*image)->exception);
5673 CatchException(&(*image)->exception);
5674 XSetCursorState(display,windows,MagickFalse);
5675 if (stipple_image == (
Image *) NULL)
5677 (void) AcquireUniqueFileResource(filename);
5678 (void) FormatLocaleString(stipple_image->filename,MaxTextExtent,
5680 (void) WriteImage(image_info,stipple_image);
5681 stipple_image=DestroyImage(stipple_image);
5682 image_info=DestroyImageInfo(image_info);
5683 status=XReadBitmapFile(display,root_window,filename,&width,
5684 &height,&stipple,&x,&y);
5685 (void) RelinquishUniqueFileResource(filename);
5686 if ((status != BitmapSuccess) != 0)
5687 XNoticeWidget(display,windows,
"Unable to read X bitmap image:",
5691 case DrawWidthCommand:
5694 *
const WidthsMenu[] =
5706 width[MaxTextExtent] =
"0";
5711 entry=XMenuWidget(display,windows,DrawMenu[
id],WidthsMenu,
5717 line_width=(
unsigned int) StringToUnsignedLong(
5721 (void) XDialogWidget(display,windows,
"Ok",
"Enter line width:",
5725 line_width=(
unsigned int) StringToUnsignedLong(width);
5728 case DrawUndoCommand:
5730 (void) XMagickCommand(display,resource_info,windows,UndoCommand,
5734 case DrawHelpCommand:
5736 XTextViewHelp(display,resource_info,windows,MagickFalse,
5737 "Help Viewer - Image Rotation",ImageDrawHelp);
5738 (void) XCheckDefineCursor(display,windows->image.id,cursor);
5741 case DrawDismissCommand:
5753 (void) XCheckDefineCursor(display,windows->image.id,cursor);
5760 if (event.xbutton.button != Button1)
5762 if (event.xbutton.window != windows->image.id)
5781 if (event.xkey.window != windows->image.id)
5786 (void) XLookupString((XKeyEvent *) &
event.xkey,command,(int)
5787 sizeof(command),&key_symbol,(XComposeStatus *) NULL);
5788 switch ((
int) key_symbol)
5803 XTextViewHelp(display,resource_info,windows,MagickFalse,
5804 "Help Viewer - Image Rotation",ImageDrawHelp);
5809 (void) XBell(display,0);
5822 if (windows->info.mapped != MagickFalse)
5824 if ((x < (
int) (windows->info.x+windows->info.width)) &&
5825 (y < (int) (windows->info.y+windows->info.height)))
5826 (void) XWithdrawWindow(display,windows->info.id,
5827 windows->info.screen);
5830 if ((x > (
int) (windows->info.x+windows->info.width)) ||
5831 (y > (int) (windows->info.y+windows->info.height)))
5832 (void) XMapWindow(display,windows->info.id);
5836 }
while ((state & ExitState) == 0);
5837 (void) XSelectInput(display,windows->image.id,
5838 windows->image.attributes.event_mask);
5839 (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
5840 if ((state & EscapeState) != 0)
5851 rectangle_info.x=(ssize_t) x;
5852 rectangle_info.y=(ssize_t) y;
5853 rectangle_info.width=0;
5854 rectangle_info.height=0;
5855 number_coordinates=1;
5856 coordinate_info->x=x;
5857 coordinate_info->y=y;
5858 (void) XSetFunction(display,windows->image.highlight_context,GXinvert);
5867 if (number_coordinates > 1)
5869 (void) XDrawLines(display,windows->image.id,
5870 windows->image.highlight_context,coordinate_info,
5871 number_coordinates,CoordModeOrigin);
5872 (void) FormatLocaleString(text,MaxTextExtent,
" %+d%+d",
5873 coordinate_info[number_coordinates-1].x,
5874 coordinate_info[number_coordinates-1].y);
5875 XInfoWidget(display,windows,text);
5886 degrees=RadiansToDegrees(-atan2((
double) (line_info.y2-
5887 line_info.y1),(
double) (line_info.x2-line_info.x1)));
5888 (void) FormatLocaleString(text,MaxTextExtent,
" %g",
5890 XInfoWidget(display,windows,text);
5891 XHighlightLine(display,windows->image.id,
5892 windows->image.highlight_context,&line_info);
5895 if (windows->info.mapped != MagickFalse)
5896 (void) XWithdrawWindow(display,windows->info.id,
5897 windows->info.screen);
5900 case RectangleElement:
5901 case FillRectangleElement:
5903 if ((rectangle_info.width > 3) && (rectangle_info.height > 3))
5908 (void) FormatLocaleString(text,MaxTextExtent,
5909 " %.20gx%.20g%+.20g%+.20g",(
double) rectangle_info.width,
5910 (double) rectangle_info.height,(
double) rectangle_info.x,
5911 (double) rectangle_info.y);
5912 XInfoWidget(display,windows,text);
5913 XHighlightRectangle(display,windows->image.id,
5914 windows->image.highlight_context,&rectangle_info);
5917 if (windows->info.mapped != MagickFalse)
5918 (void) XWithdrawWindow(display,windows->info.id,
5919 windows->info.screen);
5923 case FillCircleElement:
5924 case EllipseElement:
5925 case FillEllipseElement:
5927 if ((rectangle_info.width > 3) && (rectangle_info.height > 3))
5932 (void) FormatLocaleString(text,MaxTextExtent,
5933 " %.20gx%.20g%+.20g%+.20g",(
double) rectangle_info.width,
5934 (double) rectangle_info.height,(
double) rectangle_info.x,
5935 (double) rectangle_info.y);
5936 XInfoWidget(display,windows,text);
5937 XHighlightEllipse(display,windows->image.id,
5938 windows->image.highlight_context,&rectangle_info);
5941 if (windows->info.mapped != MagickFalse)
5942 (void) XWithdrawWindow(display,windows->info.id,
5943 windows->info.screen);
5946 case PolygonElement:
5947 case FillPolygonElement:
5949 if (number_coordinates > 1)
5950 (void) XDrawLines(display,windows->image.id,
5951 windows->image.highlight_context,coordinate_info,
5952 number_coordinates,CoordModeOrigin);
5958 degrees=RadiansToDegrees(-atan2((
double) (line_info.y2-
5959 line_info.y1),(
double) (line_info.x2-line_info.x1)));
5960 (void) FormatLocaleString(text,MaxTextExtent,
" %g",
5962 XInfoWidget(display,windows,text);
5963 XHighlightLine(display,windows->image.id,
5964 windows->image.highlight_context,&line_info);
5967 if (windows->info.mapped != MagickFalse)
5968 (void) XWithdrawWindow(display,windows->info.id,
5969 windows->info.screen);
5976 XScreenEvent(display,windows,&event);
5982 if (number_coordinates > 1)
5983 (void) XDrawLines(display,windows->image.id,
5984 windows->image.highlight_context,coordinate_info,
5985 number_coordinates,CoordModeOrigin);
5991 XHighlightLine(display,windows->image.id,
5992 windows->image.highlight_context,&line_info);
5995 case RectangleElement:
5996 case FillRectangleElement:
5998 if ((rectangle_info.width > 3) && (rectangle_info.height > 3))
5999 XHighlightRectangle(display,windows->image.id,
6000 windows->image.highlight_context,&rectangle_info);
6004 case FillCircleElement:
6005 case EllipseElement:
6006 case FillEllipseElement:
6008 if ((rectangle_info.width > 3) && (rectangle_info.height > 3))
6009 XHighlightEllipse(display,windows->image.id,
6010 windows->image.highlight_context,&rectangle_info);
6013 case PolygonElement:
6014 case FillPolygonElement:
6016 if (number_coordinates > 1)
6017 (void) XDrawLines(display,windows->image.id,
6018 windows->image.highlight_context,coordinate_info,
6019 number_coordinates,CoordModeOrigin);
6021 XHighlightLine(display,windows->image.id,
6022 windows->image.highlight_context,&line_info);
6035 line_info.x2=
event.xbutton.x;
6036 line_info.y2=
event.xbutton.y;
6037 rectangle_info.x=(ssize_t) event.xbutton.x;
6038 rectangle_info.y=(ssize_t)
event.xbutton.y;
6039 coordinate_info[number_coordinates].x=
event.xbutton.x;
6040 coordinate_info[number_coordinates].y=
event.xbutton.y;
6041 if (((element != PolygonElement) &&
6042 (element != FillPolygonElement)) || (distance <= 9))
6047 number_coordinates++;
6048 if (number_coordinates < (
int) max_coordinates)
6050 line_info.x1=
event.xbutton.x;
6051 line_info.y1=
event.xbutton.y;
6054 max_coordinates<<=1;
6055 coordinate_info=(XPoint *) ResizeQuantumMemory(coordinate_info,
6056 max_coordinates,
sizeof(*coordinate_info));
6057 if (coordinate_info == (XPoint *) NULL)
6058 (
void) ThrowMagickException(&(*image)->exception,GetMagickModule(),
6059 ResourceLimitError,
"MemoryAllocationFailed",
"`%s'",
"...");
6066 if (event.xmotion.window != windows->image.id)
6068 if (element != PointElement)
6070 line_info.x2=
event.xmotion.x;
6071 line_info.y2=
event.xmotion.y;
6072 rectangle_info.x=(ssize_t) event.xmotion.x;
6073 rectangle_info.y=(ssize_t)
event.xmotion.y;
6076 coordinate_info[number_coordinates].x=
event.xbutton.x;
6077 coordinate_info[number_coordinates].y=
event.xbutton.y;
6078 number_coordinates++;
6079 if (number_coordinates < (
int) max_coordinates)
6081 max_coordinates<<=1;
6082 coordinate_info=(XPoint *) ResizeQuantumMemory(coordinate_info,
6083 max_coordinates,
sizeof(*coordinate_info));
6084 if (coordinate_info == (XPoint *) NULL)
6085 (
void) ThrowMagickException(&(*image)->exception,GetMagickModule(),
6086 ResourceLimitError,
"MemoryAllocationFailed",
"`%s'",
"...");
6095 if (line_info.x2 < 0)
6098 if (line_info.x2 > (
int) windows->image.width)
6099 line_info.x2=(short) windows->image.width;
6100 if (line_info.y2 < 0)
6103 if (line_info.y2 > (
int) windows->image.height)
6104 line_info.y2=(
short) windows->image.height;
6105 distance=(
unsigned int)
6106 (((line_info.x2-line_info.x1+1)*(line_info.x2-line_info.x1+1))+
6107 ((line_info.y2-line_info.y1+1)*(line_info.y2-line_info.y1+1)));
6108 if ((((
int) rectangle_info.x != x) && ((
int) rectangle_info.y != y)) ||
6109 ((state & ExitState) != 0))
6111 if (rectangle_info.x < 0)
6114 if (rectangle_info.x > (ssize_t) windows->image.width)
6115 rectangle_info.x=(ssize_t) windows->image.width;
6116 if ((
int) rectangle_info.x < x)
6117 rectangle_info.width=(
unsigned int) (x-rectangle_info.x);
6120 rectangle_info.width=(
unsigned int) (rectangle_info.x-x);
6121 rectangle_info.x=(ssize_t) x;
6123 if (rectangle_info.y < 0)
6126 if (rectangle_info.y > (ssize_t) windows->image.height)
6127 rectangle_info.y=(ssize_t) windows->image.height;
6128 if ((
int) rectangle_info.y < y)
6129 rectangle_info.height=(
unsigned int) (y-rectangle_info.y);
6132 rectangle_info.height=(
unsigned int) (rectangle_info.y-y);
6133 rectangle_info.y=(ssize_t) y;
6136 }
while ((state & ExitState) == 0);
6137 (void) XSetFunction(display,windows->image.highlight_context,GXcopy);
6138 if ((element == PointElement) || (element == PolygonElement) ||
6139 (element == FillPolygonElement))
6144 rectangle_info.x=(ssize_t) coordinate_info->x;
6145 rectangle_info.y=(ssize_t) coordinate_info->y;
6146 x=coordinate_info->x;
6147 y=coordinate_info->y;
6148 for (i=1; i < number_coordinates; i++)
6150 if (coordinate_info[i].x > x)
6151 x=coordinate_info[i].x;
6152 if (coordinate_info[i].y > y)
6153 y=coordinate_info[i].y;
6154 if ((ssize_t) coordinate_info[i].x < rectangle_info.x)
6155 rectangle_info.x=MagickMax((ssize_t) coordinate_info[i].x,0);
6156 if ((ssize_t) coordinate_info[i].y < rectangle_info.y)
6157 rectangle_info.y=MagickMax((ssize_t) coordinate_info[i].y,0);
6159 rectangle_info.width=(size_t) (x-rectangle_info.x);
6160 rectangle_info.height=(size_t) (y-rectangle_info.y);
6161 for (i=0; i < number_coordinates; i++)
6163 coordinate_info[i].x-=rectangle_info.x;
6164 coordinate_info[i].y-=rectangle_info.y;
6171 if ((element == RectangleElement) ||
6172 (element == CircleElement) || (element == EllipseElement))
6174 rectangle_info.width--;
6175 rectangle_info.height--;
6180 draw_info.x=(int) rectangle_info.x;
6181 draw_info.y=(
int) rectangle_info.y;
6182 (void) XMagickCommand(display,resource_info,windows,SaveToUndoBufferCommand,
6184 width=(
unsigned int) (*image)->columns;
6185 height=(
unsigned int) (*image)->rows;
6188 if (windows->image.crop_geometry != (
char *) NULL)
6189 (
void) XParseGeometry(windows->image.crop_geometry,&x,&y,&width,&height);
6190 draw_info.x+=windows->image.x-(line_width/2);
6191 if (draw_info.x < 0)
6193 draw_info.x=(int) (width*draw_info.x/windows->image.ximage->width);
6194 draw_info.y+=windows->image.y-(line_width/2);
6195 if (draw_info.y < 0)
6197 draw_info.y=(int) height*draw_info.y/windows->image.ximage->height;
6198 draw_info.width=(
unsigned int) rectangle_info.width+(line_width << 1);
6199 if (draw_info.width > (
unsigned int) (*image)->columns)
6200 draw_info.width=(
unsigned int) (*image)->columns;
6201 draw_info.height=(
unsigned int) rectangle_info.height+(line_width << 1);
6202 if (draw_info.height > (
unsigned int) (*image)->rows)
6203 draw_info.height=(
unsigned int) (*image)->rows;
6204 (void) FormatLocaleString(draw_info.geometry,MaxTextExtent,
"%ux%u%+d%+d",
6205 width*draw_info.width/windows->image.ximage->width,
6206 height*draw_info.height/windows->image.ximage->height,
6207 draw_info.x+x,draw_info.y+y);
6211 draw_info.degrees=0.0;
6212 draw_info.element=element;
6213 draw_info.stipple=stipple;
6214 draw_info.line_width=line_width;
6215 draw_info.line_info=line_info;
6216 if (line_info.x1 > (
int) (line_width/2))
6217 draw_info.line_info.x1=(short) line_width/2;
6218 if (line_info.y1 > (
int) (line_width/2))
6219 draw_info.line_info.y1=(short) line_width/2;
6220 draw_info.line_info.x2=(short) (line_info.x2-line_info.x1+(line_width/2));
6221 draw_info.line_info.y2=(short) (line_info.y2-line_info.y1+(line_width/2));
6222 if ((draw_info.line_info.x2 < 0) && (draw_info.line_info.y2 < 0))
6224 draw_info.line_info.x2=(-draw_info.line_info.x2);
6225 draw_info.line_info.y2=(-draw_info.line_info.y2);
6227 if (draw_info.line_info.x2 < 0)
6229 draw_info.line_info.x2=(-draw_info.line_info.x2);
6230 Swap(draw_info.line_info.x1,draw_info.line_info.x2);
6232 if (draw_info.line_info.y2 < 0)
6234 draw_info.line_info.y2=(-draw_info.line_info.y2);
6235 Swap(draw_info.line_info.y1,draw_info.line_info.y2);
6237 draw_info.rectangle_info=rectangle_info;
6238 if (draw_info.rectangle_info.x > (ssize_t) (line_width/2))
6239 draw_info.rectangle_info.x=(ssize_t) line_width/2;
6240 if (draw_info.rectangle_info.y > (ssize_t) (line_width/2))
6241 draw_info.rectangle_info.y=(ssize_t) line_width/2;
6242 draw_info.number_coordinates=(
unsigned int) number_coordinates;
6243 draw_info.coordinate_info=coordinate_info;
6244 windows->pixel_info->pen_color=windows->pixel_info->pen_colors[pen_id];
6248 XSetCursorState(display,windows,MagickTrue);
6249 XCheckRefreshWindows(display,windows);
6250 status=XDrawImage(display,windows->pixel_info,&draw_info,*image);
6251 XSetCursorState(display,windows,MagickFalse);
6255 XConfigureImageColormap(display,resource_info,windows,*image);
6256 (void) XConfigureImage(display,resource_info,windows,*image);
6258 XSetCursorState(display,windows,MagickFalse);
6259 coordinate_info=(XPoint *) RelinquishMagickMemory(coordinate_info);
6260 return(status != 0 ? MagickTrue : MagickFalse);
6290 static void XDrawPanRectangle(Display *display,XWindows *windows)
6301 scale_factor=(MagickRealType) windows->pan.width/windows->image.ximage->width;
6302 highlight_info.x=(ssize_t) (scale_factor*windows->image.x+0.5);
6303 highlight_info.width=(
unsigned int) (scale_factor*windows->image.width+0.5);
6304 scale_factor=(MagickRealType)
6305 windows->pan.height/windows->image.ximage->height;
6306 highlight_info.y=(ssize_t) (scale_factor*windows->image.y+0.5);
6307 highlight_info.height=(
unsigned int) (scale_factor*windows->image.height+0.5);
6311 (void) XClearWindow(display,windows->pan.id);
6312 XHighlightRectangle(display,windows->pan.id,windows->pan.annotate_context,
6350 static void XImageCache(Display *display,XResourceInfo *resource_info,
6351 XWindows *windows,
const CommandType command,
Image **image)
6357 *redo_image = (
Image *) NULL,
6358 *undo_image = (
Image *) NULL;
6362 case FreeBuffersCommand:
6367 while (undo_image != (
Image *) NULL)
6369 cache_image=undo_image;
6370 undo_image=GetPreviousImageInList(undo_image);
6371 cache_image->list=DestroyImage(cache_image->list);
6372 cache_image=DestroyImage(cache_image);
6374 undo_image=NewImageList();
6375 if (redo_image != (
Image *) NULL)
6376 redo_image=DestroyImage(redo_image);
6377 redo_image=NewImageList();
6383 image_geometry[MaxTextExtent];
6388 if (undo_image == (
Image *) NULL)
6390 (void) XBell(display,0);
6393 cache_image=undo_image;
6394 undo_image=GetPreviousImageInList(undo_image);
6395 windows->image.window_changes.width=(int) cache_image->columns;
6396 windows->image.window_changes.height=(
int) cache_image->rows;
6397 (void) FormatLocaleString(image_geometry,MaxTextExtent,
"%dx%d!",
6398 windows->image.ximage->width,windows->image.ximage->height);
6399 (void) TransformImage(image,windows->image.crop_geometry,image_geometry);
6400 if (windows->image.crop_geometry != (
char *) NULL)
6401 windows->image.crop_geometry=(
char *)
6402 RelinquishMagickMemory(windows->image.crop_geometry);
6403 windows->image.crop_geometry=cache_image->geometry;
6404 if (redo_image != (
Image *) NULL)
6405 redo_image=DestroyImage(redo_image);
6406 redo_image=(*image);
6407 *image=cache_image->list;
6408 cache_image=DestroyImage(cache_image);
6409 if (windows->image.orphan != MagickFalse)
6411 XConfigureImageColormap(display,resource_info,windows,*image);
6412 (void) XConfigureImage(display,resource_info,windows,*image);
6418 case HalfSizeCommand:
6419 case OriginalSizeCommand:
6420 case DoubleSizeCommand:
6427 case RotateRightCommand:
6428 case RotateLeftCommand:
6433 case ContrastStretchCommand:
6434 case SigmoidalContrastCommand:
6435 case NormalizeCommand:
6436 case EqualizeCommand:
6438 case SaturationCommand:
6439 case BrightnessCommand:
6443 case GrayscaleCommand:
6445 case QuantizeCommand:
6446 case DespeckleCommand:
6448 case ReduceNoiseCommand:
6449 case AddNoiseCommand:
6450 case SharpenCommand:
6452 case ThresholdCommand:
6453 case EdgeDetectCommand:
6457 case SegmentCommand:
6458 case SolarizeCommand:
6459 case SepiaToneCommand:
6461 case ImplodeCommand:
6462 case VignetteCommand:
6464 case OilPaintCommand:
6465 case CharcoalDrawCommand:
6466 case AnnotateCommand:
6467 case AddBorderCommand:
6468 case AddFrameCommand:
6469 case CompositeCommand:
6470 case CommentCommand:
6472 case RegionofInterestCommand:
6473 case SaveToUndoBufferCommand:
6482 bytes=(ssize_t) ((*image)->columns*(*image)->rows*
sizeof(
PixelPacket));
6483 if (undo_image != (
Image *) NULL)
6488 previous_image=undo_image;
6489 while (previous_image != (
Image *) NULL)
6491 bytes+=previous_image->list->columns*previous_image->list->rows*
6493 if (bytes <= (ssize_t) (resource_info->undo_cache << 20))
6495 previous_image=GetPreviousImageInList(previous_image);
6498 bytes-=previous_image->list->columns*previous_image->list->rows*
6500 if (previous_image == undo_image)
6501 undo_image=NewImageList();
6503 previous_image->next->previous=NewImageList();
6506 while (previous_image != (
Image *) NULL)
6511 cache_image=previous_image;
6512 previous_image=GetPreviousImageInList(previous_image);
6513 cache_image->list=DestroyImage(cache_image->list);
6514 cache_image=DestroyImage(cache_image);
6517 if (bytes > (ssize_t) (resource_info->undo_cache << 20))
6522 cache_image=AcquireImage((
ImageInfo *) NULL);
6523 if (cache_image == (
Image *) NULL)
6525 XSetCursorState(display,windows,MagickTrue);
6526 XCheckRefreshWindows(display,windows);
6527 cache_image->list=CloneImage(*image,0,0,MagickTrue,&(*image)->exception);
6528 XSetCursorState(display,windows,MagickFalse);
6529 if (cache_image->list == (
Image *) NULL)
6531 cache_image=DestroyImage(cache_image);
6534 cache_image->columns=(size_t) windows->image.ximage->width;
6535 cache_image->rows=(
size_t) windows->image.ximage->height;
6536 cache_image->geometry=windows->image.crop_geometry;
6537 if (windows->image.crop_geometry != (
char *) NULL)
6539 cache_image->geometry=AcquireString((
char *) NULL);
6540 (void) CopyMagickString(cache_image->geometry,
6541 windows->image.crop_geometry,MaxTextExtent);
6543 if (undo_image == (
Image *) NULL)
6545 undo_image=cache_image;
6548 undo_image->next=cache_image;
6549 undo_image->next->previous=undo_image;
6550 undo_image=undo_image->next;
6556 if (command == RedoCommand)
6561 if (redo_image == (
Image *) NULL)
6563 (void) XBell(display,0);
6566 windows->image.window_changes.width=(int) redo_image->columns;
6567 windows->image.window_changes.height=(
int) redo_image->rows;
6568 if (windows->image.crop_geometry != (
char *) NULL)
6569 windows->image.crop_geometry=(
char *)
6570 RelinquishMagickMemory(windows->image.crop_geometry);
6571 windows->image.crop_geometry=redo_image->geometry;
6572 *image=DestroyImage(*image);
6574 redo_image=NewImageList();
6575 if (windows->image.orphan != MagickFalse)
6577 XConfigureImageColormap(display,resource_info,windows,*image);
6578 (void) XConfigureImage(display,resource_info,windows,*image);
6581 if (command != InfoCommand)
6586 XSetCursorState(display,windows,MagickTrue);
6587 XCheckRefreshWindows(display,windows);
6588 XDisplayImageInfo(display,resource_info,windows,undo_image,*image);
6589 XSetCursorState(display,windows,MagickFalse);
6633 static CommandType XImageWindowCommand(Display *display,
6634 XResourceInfo *resource_info,XWindows *windows,
const MagickStatusType state,
6635 KeySym key_symbol,
Image **image)
6638 delta[MaxTextExtent] =
"";
6641 Digits[] =
"01234567890";
6646 if ((key_symbol >= XK_0) && (key_symbol <= XK_9))
6648 if (((last_symbol < XK_0) || (last_symbol > XK_9)))
6651 resource_info->quantum=1;
6653 last_symbol=key_symbol;
6654 delta[strlen(delta)+1]=
'\0';
6655 delta[strlen(delta)]=Digits[key_symbol-XK_0];
6656 resource_info->quantum=StringToLong(delta);
6657 return(NullCommand);
6659 last_symbol=key_symbol;
6660 if (resource_info->immutable)
6668 return(InfoCommand);
6671 return(PrintCommand);
6673 return(NextCommand);
6676 return(QuitCommand);
6680 return(NullCommand);
6682 switch ((
int) key_symbol)
6686 if ((state & ControlMask) == 0)
6688 return(OpenCommand);
6691 return(NextCommand);
6693 return(FormerCommand);
6696 if ((state & Mod1Mask) != 0)
6697 return(SwirlCommand);
6698 if ((state & ControlMask) == 0)
6699 return(ShearCommand);
6700 return(SaveCommand);
6705 if ((state & Mod1Mask) != 0)
6706 return(OilPaintCommand);
6707 if ((state & Mod4Mask) != 0)
6708 return(ColorCommand);
6709 if ((state & ControlMask) == 0)
6710 return(NullCommand);
6711 return(PrintCommand);
6715 if ((state & Mod4Mask) != 0)
6716 return(DrawCommand);
6717 if ((state & ControlMask) == 0)
6718 return(NullCommand);
6719 return(DeleteCommand);
6723 if ((state & ControlMask) == 0)
6724 return(NullCommand);
6725 return(SelectCommand);
6729 if ((state & ControlMask) == 0)
6730 return(NullCommand);
6735 return(QuitCommand);
6739 if ((state & ControlMask) == 0)
6740 return(NullCommand);
6741 return(UndoCommand);
6746 if ((state & ControlMask) == 0)
6747 return(RollCommand);
6748 return(RedoCommand);
6752 if ((state & ControlMask) == 0)
6753 return(NullCommand);
6758 if ((state & Mod1Mask) != 0)
6759 return(CharcoalDrawCommand);
6760 if ((state & ControlMask) == 0)
6761 return(CropCommand);
6762 return(CopyCommand);
6767 if ((state & Mod4Mask) != 0)
6768 return(CompositeCommand);
6769 if ((state & ControlMask) == 0)
6770 return(FlipCommand);
6771 return(PasteCommand);
6774 return(HalfSizeCommand);
6776 return(OriginalSizeCommand);
6778 return(DoubleSizeCommand);
6780 return(ResizeCommand);
6782 return(RefreshCommand);
6783 case XK_bracketleft:
6784 return(ChopCommand);
6786 return(FlopCommand);
6788 return(RotateRightCommand);
6790 return(RotateLeftCommand);
6792 return(RotateCommand);
6794 return(TrimCommand);
6798 return(SaturationCommand);
6800 return(BrightnessCommand);
6802 return(GammaCommand);
6804 return(SpiffCommand);
6806 return(DullCommand);
6808 return(NormalizeCommand);
6810 return(EqualizeCommand);
6812 return(NegateCommand);
6814 return(GrayscaleCommand);
6816 return(QuantizeCommand);
6818 return(DespeckleCommand);
6820 return(EmbossCommand);
6822 return(ReduceNoiseCommand);
6824 return(AddNoiseCommand);
6826 return(SharpenCommand);
6828 return(BlurCommand);
6830 return(ThresholdCommand);
6832 return(EdgeDetectCommand);
6834 return(SpreadCommand);
6836 return(ShadeCommand);
6838 return(RaiseCommand);
6840 return(SegmentCommand);
6843 if ((state & Mod1Mask) == 0)
6844 return(NullCommand);
6845 return(ImplodeCommand);
6849 if ((state & Mod1Mask) == 0)
6850 return(NullCommand);
6851 return(WaveCommand);
6855 if ((state & Mod4Mask) == 0)
6856 return(NullCommand);
6857 return(MatteCommand);
6861 if ((state & Mod4Mask) == 0)
6862 return(NullCommand);
6863 return(AddBorderCommand);
6867 if ((state & Mod4Mask) == 0)
6868 return(NullCommand);
6869 return(AddFrameCommand);
6873 if ((state & Mod4Mask) == 0)
6874 return(NullCommand);
6875 return(CommentCommand);
6879 if ((state & Mod1Mask) != 0)
6880 return(ApplyCommand);
6881 if ((state & Mod4Mask) != 0)
6882 return(AnnotateCommand);
6883 if ((state & ControlMask) == 0)
6884 return(NullCommand);
6885 return(RegionofInterestCommand);
6888 return(InfoCommand);
6890 return(ZoomCommand);
6893 if ((state & ShiftMask) == 0)
6894 return(NullCommand);
6895 return(ShowPreviewCommand);
6898 return(LaunchCommand);
6900 return(HelpCommand);
6902 return(BrowseDocumentationCommand);
6905 (void) XMapRaised(display,windows->command.id);
6906 return(NullCommand);
6913 XTranslateImage(display,windows,*image,key_symbol);
6914 return(NullCommand);
6925 if ((state & Mod1Mask) != 0)
6935 crop_info.width=(size_t) windows->image.ximage->width;
6936 crop_info.height=(
size_t) windows->image.ximage->height;
6937 if ((key_symbol == XK_Up) || (key_symbol == XK_KP_Up))
6939 if (resource_info->quantum >= (
int) crop_info.height)
6940 resource_info->quantum=(
int) crop_info.height-1;
6941 crop_info.height-=resource_info->quantum;
6943 if ((key_symbol == XK_Down) || (key_symbol == XK_KP_Down))
6945 if (resource_info->quantum >= (
int) (crop_info.height-crop_info.y))
6946 resource_info->quantum=(int) (crop_info.height-crop_info.y-1);
6947 crop_info.y+=resource_info->quantum;
6948 crop_info.height-=resource_info->quantum;
6950 if ((key_symbol == XK_Left) || (key_symbol == XK_KP_Left))
6952 if (resource_info->quantum >= (
int) crop_info.width)
6953 resource_info->quantum=(
int) crop_info.width-1;
6954 crop_info.width-=resource_info->quantum;
6956 if ((key_symbol == XK_Right) || (key_symbol == XK_KP_Right))
6958 if (resource_info->quantum >= (
int) (crop_info.width-crop_info.x))
6959 resource_info->quantum=(int) (crop_info.width-crop_info.x-1);
6960 crop_info.x+=resource_info->quantum;
6961 crop_info.width-=resource_info->quantum;
6963 if ((
int) (windows->image.x+windows->image.width) >
6964 (
int) crop_info.width)
6965 windows->image.x=(
int) (crop_info.width-windows->image.width);
6966 if ((
int) (windows->image.y+windows->image.height) >
6967 (
int) crop_info.height)
6968 windows->image.y=(
int) (crop_info.height-windows->image.height);
6969 XSetCropGeometry(display,windows,&crop_info,*image);
6970 windows->image.window_changes.width=(int) crop_info.width;
6971 windows->image.window_changes.height=(
int) crop_info.height;
6972 (void) XSetWindowBackgroundPixmap(display,windows->image.id,None);
6973 (void) XConfigureImage(display,resource_info,windows,*image);
6974 return(NullCommand);
6976 XTranslateImage(display,windows,*image,key_symbol);
6977 return(NullCommand);
6980 return(NullCommand);
6982 return(NullCommand);
7023 static Image *XMagickCommand(Display *display,XResourceInfo *resource_info,
7024 XWindows *windows,
const CommandType command,
Image **image)
7027 filename[MaxTextExtent],
7028 geometry[MaxTextExtent],
7029 modulate_factors[MaxTextExtent];
7058 color[MaxTextExtent] =
"gray";
7067 XCheckRefreshWindows(display,windows);
7068 XImageCache(display,resource_info,windows,command,image);
7069 nexus=NewImageList();
7070 windows->image.window_changes.width=windows->image.ximage->width;
7071 windows->image.window_changes.height=windows->image.ximage->height;
7072 image_info=CloneImageInfo(resource_info->image_info);
7073 SetGeometryInfo(&geometry_info);
7074 GetQuantizeInfo(&quantize_info);
7082 nexus=XOpenImage(display,resource_info,windows,MagickFalse);
7090 for (i=0; i < resource_info->quantum; i++)
7091 XClientMessage(display,windows->image.id,windows->im_protocols,
7092 windows->im_next_image,CurrentTime);
7100 for (i=0; i < resource_info->quantum; i++)
7101 XClientMessage(display,windows->image.id,windows->im_protocols,
7102 windows->im_former_image,CurrentTime);
7113 if (*resource_info->home_directory ==
'\0')
7114 (void) CopyMagickString(resource_info->home_directory,
".",
7116 status=chdir(resource_info->home_directory);
7118 (void) ThrowMagickException(&(*image)->exception,GetMagickModule(),
7119 FileOpenError,
"UnableToOpenFile",
"%s",resource_info->home_directory);
7120 nexus=XOpenImage(display,resource_info,windows,MagickTrue);
7128 status=XSaveImage(display,resource_info,windows,*image);
7129 if (status == MagickFalse)
7132 message[MaxTextExtent];
7134 (void) FormatLocaleString(message,MaxTextExtent,
"%s:%s",
7135 (*image)->exception.reason != (
char *) NULL ?
7136 (*image)->exception.reason :
"",
7137 (*image)->exception.description != (
char *) NULL ?
7138 (*image)->exception.description :
"");
7139 XNoticeWidget(display,windows,
"Unable to save file:",message);
7149 status=XPrintImage(display,resource_info,windows,*image);
7150 if (status == MagickFalse)
7153 message[MaxTextExtent];
7155 (void) FormatLocaleString(message,MaxTextExtent,
"%s:%s",
7156 (*image)->exception.reason != (
char *) NULL ?
7157 (*image)->exception.reason :
"",
7158 (*image)->exception.description != (
char *) NULL ?
7159 (*image)->exception.description :
"");
7160 XNoticeWidget(display,windows,
"Unable to print file:",message);
7168 filename[MaxTextExtent] =
"\0";
7173 XFileBrowserWidget(display,windows,
"Delete",filename);
7174 if (*filename ==
'\0')
7176 status=ShredFile(filename);
7177 status|=remove_utf8(filename);
7178 if (status != MagickFalse)
7179 XNoticeWidget(display,windows,
"Unable to delete image file:",filename);
7188 color[MaxTextExtent] =
"gray",
7189 geometry[MaxTextExtent] =
"640x480";
7192 *format =
"gradient";
7197 status=XDialogWidget(display,windows,
"New",
"Enter image geometry:",
7199 if (*geometry ==
'\0')
7203 XColorBrowserWidget(display,windows,
"Select",color);
7209 (void) FormatLocaleString(image_info->filename,MaxTextExtent,
7210 "%s:%s",format,color);
7211 (void) CloneString(&image_info->size,geometry);
7212 nexus=ReadImage(image_info,&(*image)->exception);
7213 CatchException(&(*image)->exception);
7214 XClientMessage(display,windows->image.id,windows->im_protocols,
7215 windows->im_next_image,CurrentTime);
7218 case VisualDirectoryCommand:
7223 nexus=XVisualDirectoryImage(display,resource_info,windows);
7231 if (resource_info->confirm_exit == MagickFalse)
7232 XClientMessage(display,windows->image.id,windows->im_protocols,
7233 windows->im_exit,CurrentTime);
7242 status=XConfirmWidget(display,windows,
"Do you really want to exit",
7243 resource_info->client_name);
7245 XClientMessage(display,windows->image.id,windows->im_protocols,
7246 windows->im_exit,CurrentTime);
7255 (void) XCropImage(display,resource_info,windows,*image,CutMode);
7263 (void) XCropImage(display,resource_info,windows,*image,CopyMode);
7271 status=XPasteImage(display,resource_info,windows,*image);
7272 if (status == MagickFalse)
7274 XNoticeWidget(display,windows,
"Unable to paste X image",
7275 (*image)->filename);
7280 case HalfSizeCommand:
7285 windows->image.window_changes.width=windows->image.ximage->width/2;
7286 windows->image.window_changes.height=windows->image.ximage->height/2;
7287 (void) XConfigureImage(display,resource_info,windows,*image);
7290 case OriginalSizeCommand:
7295 windows->image.window_changes.width=(int) (*image)->columns;
7296 windows->image.window_changes.height=(
int) (*image)->rows;
7297 (void) XConfigureImage(display,resource_info,windows,*image);
7300 case DoubleSizeCommand:
7305 windows->image.window_changes.width=windows->image.ximage->width << 1;
7306 windows->image.window_changes.height=windows->image.ximage->height << 1;
7307 (void) XConfigureImage(display,resource_info,windows,*image);
7326 width=(size_t) windows->image.ximage->width;
7327 height=(
size_t) windows->image.ximage->height;
7330 (void) FormatLocaleString(geometry,MaxTextExtent,
"%.20gx%.20g+0+0",
7331 (
double) width,(double) height);
7332 status=XDialogWidget(display,windows,
"Resize",
7333 "Enter resize geometry (e.g. 640x480, 200%):",geometry);
7334 if (*geometry ==
'\0')
7337 (void) ConcatenateMagickString(geometry,
"!",MaxTextExtent);
7338 (void) ParseMetaGeometry(geometry,&x,&y,&width,&height);
7339 windows->image.window_changes.width=(int) width;
7340 windows->image.window_changes.height=(int) height;
7341 (void) XConfigureImage(display,resource_info,windows,*image);
7347 image_geometry[MaxTextExtent];
7349 if ((windows->image.crop_geometry == (
char *) NULL) &&
7350 ((
int) (*image)->columns == windows->image.ximage->width) &&
7351 ((
int) (*image)->rows == windows->image.ximage->height))
7356 XSetCursorState(display,windows,MagickTrue);
7357 XCheckRefreshWindows(display,windows);
7361 (void) FormatLocaleString(image_geometry,MaxTextExtent,
"%dx%d!",
7362 windows->image.ximage->width,windows->image.ximage->height);
7363 (void) TransformImage(image,windows->image.crop_geometry,image_geometry);
7364 if (windows->image.crop_geometry != (
char *) NULL)
7365 windows->image.crop_geometry=(
char *)
7366 RelinquishMagickMemory(windows->image.crop_geometry);
7369 XConfigureImageColormap(display,resource_info,windows,*image);
7370 (void) XConfigureImage(display,resource_info,windows,*image);
7373 case RefreshCommand:
7375 (void) XConfigureImage(display,resource_info,windows,*image);
7378 case RestoreCommand:
7383 if ((windows->image.width == (
unsigned int) (*image)->columns) &&
7384 (windows->image.height == (
unsigned int) (*image)->rows) &&
7385 (windows->image.crop_geometry == (
char *) NULL))
7387 (void) XBell(display,0);
7390 windows->image.window_changes.width=(int) (*image)->columns;
7391 windows->image.window_changes.height=(
int) (*image)->rows;
7392 if (windows->image.crop_geometry != (
char *) NULL)
7394 windows->image.crop_geometry=(
char *)
7395 RelinquishMagickMemory(windows->image.crop_geometry);
7396 windows->image.crop_geometry=(
char *) NULL;
7400 XConfigureImageColormap(display,resource_info,windows,*image);
7401 (void) XConfigureImage(display,resource_info,windows,*image);
7409 (void) XCropImage(display,resource_info,windows,*image,CropMode);
7417 status=XChopImage(display,resource_info,windows,image);
7418 if (status == MagickFalse)
7420 XNoticeWidget(display,windows,
"Unable to cut X image",
7421 (*image)->filename);
7434 XSetCursorState(display,windows,MagickTrue);
7435 XCheckRefreshWindows(display,windows);
7436 flop_image=FlopImage(*image,&(*image)->exception);
7437 if (flop_image != (
Image *) NULL)
7439 *image=DestroyImage(*image);
7442 CatchException(&(*image)->exception);
7443 XSetCursorState(display,windows,MagickFalse);
7444 if (windows->image.crop_geometry != (
char *) NULL)
7449 width=(
unsigned int) (*image)->columns;
7450 height=(
unsigned int) (*image)->rows;
7451 (void) XParseGeometry(windows->image.crop_geometry,&x,&y,
7453 (void) FormatLocaleString(windows->image.crop_geometry,MaxTextExtent,
7454 "%ux%u%+d%+d",width,height,(
int) (*image)->columns-(int) width-x,y);
7456 if (windows->image.orphan != MagickFalse)
7458 (void) XConfigureImage(display,resource_info,windows,*image);
7469 XSetCursorState(display,windows,MagickTrue);
7470 XCheckRefreshWindows(display,windows);
7471 flip_image=FlipImage(*image,&(*image)->exception);
7472 if (flip_image != (
Image *) NULL)
7474 *image=DestroyImage(*image);
7477 CatchException(&(*image)->exception);
7478 XSetCursorState(display,windows,MagickFalse);
7479 if (windows->image.crop_geometry != (
char *) NULL)
7484 width=(
unsigned int) (*image)->columns;
7485 height=(
unsigned int) (*image)->rows;
7486 (void) XParseGeometry(windows->image.crop_geometry,&x,&y,
7488 (void) FormatLocaleString(windows->image.crop_geometry,MaxTextExtent,
7489 "%ux%u%+d%+d",width,height,x,(
int) (*image)->rows-(int) height-y);
7491 if (windows->image.orphan != MagickFalse)
7493 (void) XConfigureImage(display,resource_info,windows,*image);
7496 case RotateRightCommand:
7501 status=XRotateImage(display,resource_info,windows,90.0,image);
7502 if (status == MagickFalse)
7504 XNoticeWidget(display,windows,
"Unable to rotate X image",
7505 (*image)->filename);
7510 case RotateLeftCommand:
7515 status=XRotateImage(display,resource_info,windows,-90.0,image);
7516 if (status == MagickFalse)
7518 XNoticeWidget(display,windows,
"Unable to rotate X image",
7519 (*image)->filename);
7529 status=XRotateImage(display,resource_info,windows,0.0,image);
7530 if (status == MagickFalse)
7532 XNoticeWidget(display,windows,
"Unable to rotate X image",
7533 (*image)->filename);
7544 geometry[MaxTextExtent] =
"45.0x45.0";
7549 XColorBrowserWidget(display,windows,
"Select",color);
7552 (void) XDialogWidget(display,windows,
"Shear",
"Enter shear geometry:",
7554 if (*geometry ==
'\0')
7559 (void) XMagickCommand(display,resource_info,windows,ApplyCommand,image);
7560 XSetCursorState(display,windows,MagickTrue);
7561 XCheckRefreshWindows(display,windows);
7562 (void) QueryColorDatabase(color,&(*image)->background_color,
7563 &(*image)->exception);
7564 flags=ParseGeometry(geometry,&geometry_info);
7565 if ((flags & SigmaValue) == 0)
7566 geometry_info.sigma=geometry_info.rho;
7567 shear_image=ShearImage(*image,geometry_info.rho,geometry_info.sigma,
7568 &(*image)->exception);
7569 if (shear_image != (
Image *) NULL)
7571 *image=DestroyImage(*image);
7574 CatchException(&(*image)->exception);
7575 XSetCursorState(display,windows,MagickFalse);
7576 if (windows->image.orphan != MagickFalse)
7578 windows->image.window_changes.width=(int) (*image)->columns;
7579 windows->image.window_changes.height=(
int) (*image)->rows;
7580 XConfigureImageColormap(display,resource_info,windows,*image);
7581 (void) XConfigureImage(display,resource_info,windows,*image);
7590 geometry[MaxTextExtent] =
"+2+2";
7595 (void) XDialogWidget(display,windows,
"Roll",
"Enter roll geometry:",
7597 if (*geometry ==
'\0')
7602 (void) XMagickCommand(display,resource_info,windows,ApplyCommand,image);
7603 XSetCursorState(display,windows,MagickTrue);
7604 XCheckRefreshWindows(display,windows);
7605 (void) ParsePageGeometry(*image,geometry,&page_geometry,
7606 &(*image)->exception);
7607 roll_image=RollImage(*image,page_geometry.x,page_geometry.y,
7608 &(*image)->exception);
7609 if (roll_image != (
Image *) NULL)
7611 *image=DestroyImage(*image);
7614 CatchException(&(*image)->exception);
7615 XSetCursorState(display,windows,MagickFalse);
7616 if (windows->image.orphan != MagickFalse)
7618 windows->image.window_changes.width=(int) (*image)->columns;
7619 windows->image.window_changes.height=(
int) (*image)->rows;
7620 XConfigureImageColormap(display,resource_info,windows,*image);
7621 (void) XConfigureImage(display,resource_info,windows,*image);
7627 fuzz[MaxTextExtent];
7632 (void) FormatLocaleString(fuzz,MaxTextExtent,
"%g%%",100.0*
7633 (*image)->fuzz/(QuantumRange+1.0));
7634 (void) XDialogWidget(display,windows,
"Trim",
"Enter fuzz factor:",fuzz);
7637 (*image)->fuzz=StringToDoubleInterval(fuzz,(
double) QuantumRange+1.0);
7641 status=XTrimImage(display,resource_info,windows,*image);
7642 if (status == MagickFalse)
7644 XNoticeWidget(display,windows,
"Unable to trim X image",
7645 (*image)->filename);
7653 hue_percent[MaxTextExtent] =
"110";
7658 (void) XDialogWidget(display,windows,
"Apply",
7659 "Enter percent change in image hue (0-200):",hue_percent);
7660 if (*hue_percent ==
'\0')
7665 XSetCursorState(display,windows,MagickTrue);
7666 XCheckRefreshWindows(display,windows);
7667 (void) CopyMagickString(modulate_factors,
"100.0/100.0/",MaxTextExtent);
7668 (void) ConcatenateMagickString(modulate_factors,hue_percent,
7670 (void) ModulateImage(*image,modulate_factors);
7671 XSetCursorState(display,windows,MagickFalse);
7672 if (windows->image.orphan != MagickFalse)
7674 XConfigureImageColormap(display,resource_info,windows,*image);
7675 (void) XConfigureImage(display,resource_info,windows,*image);
7678 case SaturationCommand:
7681 saturation_percent[MaxTextExtent] =
"110";
7686 (void) XDialogWidget(display,windows,
"Apply",
7687 "Enter percent change in color saturation (0-200):",saturation_percent);
7688 if (*saturation_percent ==
'\0')
7693 XSetCursorState(display,windows,MagickTrue);
7694 XCheckRefreshWindows(display,windows);
7695 (void) CopyMagickString(modulate_factors,
"100.0/",MaxTextExtent);
7696 (void) ConcatenateMagickString(modulate_factors,saturation_percent,
7698 (void) ModulateImage(*image,modulate_factors);
7699 XSetCursorState(display,windows,MagickFalse);
7700 if (windows->image.orphan != MagickFalse)
7702 XConfigureImageColormap(display,resource_info,windows,*image);
7703 (void) XConfigureImage(display,resource_info,windows,*image);
7706 case BrightnessCommand:
7709 brightness_percent[MaxTextExtent] =
"110";
7714 (void) XDialogWidget(display,windows,
"Apply",
7715 "Enter percent change in color brightness (0-200):",brightness_percent);
7716 if (*brightness_percent ==
'\0')
7721 XSetCursorState(display,windows,MagickTrue);
7722 XCheckRefreshWindows(display,windows);
7723 (void) CopyMagickString(modulate_factors,brightness_percent,
7725 (void) ModulateImage(*image,modulate_factors);
7726 XSetCursorState(display,windows,MagickFalse);
7727 if (windows->image.orphan != MagickFalse)
7729 XConfigureImageColormap(display,resource_info,windows,*image);
7730 (void) XConfigureImage(display,resource_info,windows,*image);
7736 factor[MaxTextExtent] =
"1.6";
7741 (void) XDialogWidget(display,windows,
"Gamma",
7742 "Enter gamma value (e.g. 1.0,1.0,1.6):",factor);
7743 if (*factor ==
'\0')
7748 XSetCursorState(display,windows,MagickTrue);
7749 XCheckRefreshWindows(display,windows);
7750 (void) GammaImage(*image,factor);
7751 XSetCursorState(display,windows,MagickFalse);
7752 if (windows->image.orphan != MagickFalse)
7754 XConfigureImageColormap(display,resource_info,windows,*image);
7755 (void) XConfigureImage(display,resource_info,windows,*image);
7763 XSetCursorState(display,windows,MagickTrue);
7764 XCheckRefreshWindows(display,windows);
7765 (void) ContrastImage(*image,MagickTrue);
7766 XSetCursorState(display,windows,MagickFalse);
7767 if (windows->image.orphan != MagickFalse)
7769 XConfigureImageColormap(display,resource_info,windows,*image);
7770 (void) XConfigureImage(display,resource_info,windows,*image);
7778 XSetCursorState(display,windows,MagickTrue);
7779 XCheckRefreshWindows(display,windows);
7780 (void) ContrastImage(*image,MagickFalse);
7781 XSetCursorState(display,windows,MagickFalse);
7782 if (windows->image.orphan != MagickFalse)
7784 XConfigureImageColormap(display,resource_info,windows,*image);
7785 (void) XConfigureImage(display,resource_info,windows,*image);
7788 case ContrastStretchCommand:
7795 levels[MaxTextExtent] =
"1%";
7800 (void) XDialogWidget(display,windows,
"Contrast Stretch",
7801 "Enter black and white points:",levels);
7802 if (*levels ==
'\0')
7807 XSetCursorState(display,windows,MagickTrue);
7808 XCheckRefreshWindows(display,windows);
7809 flags=ParseGeometry(levels,&geometry_info);
7810 black_point=geometry_info.rho;
7811 white_point=(flags & SigmaValue) != 0 ? geometry_info.sigma : black_point;
7812 if ((flags & PercentValue) != 0)
7814 black_point*=(double) (*image)->columns*(*image)->rows/100.0;
7815 white_point*=(
double) (*image)->columns*(*image)->rows/100.0;
7817 white_point=(MagickRealType) (*image)->columns*(*image)->rows-white_point;
7818 (
void) ContrastStretchImageChannel(*image,DefaultChannels,black_point,
7820 XSetCursorState(display,windows,MagickFalse);
7821 if (windows->image.orphan != MagickFalse)
7823 XConfigureImageColormap(display,resource_info,windows,*image);
7824 (void) XConfigureImage(display,resource_info,windows,*image);
7827 case SigmoidalContrastCommand:
7830 levels[MaxTextExtent] =
"3x50%";
7835 (void) XDialogWidget(display,windows,
"Sigmoidal Contrast",
7836 "Enter contrast and midpoint:",levels);
7837 if (*levels ==
'\0')
7842 XSetCursorState(display,windows,MagickTrue);
7843 XCheckRefreshWindows(display,windows);
7844 (void) SigmoidalContrastImage(*image,MagickTrue,levels);
7845 XSetCursorState(display,windows,MagickFalse);
7846 if (windows->image.orphan != MagickFalse)
7848 XConfigureImageColormap(display,resource_info,windows,*image);
7849 (void) XConfigureImage(display,resource_info,windows,*image);
7852 case NormalizeCommand:
7857 XSetCursorState(display,windows,MagickTrue);
7858 XCheckRefreshWindows(display,windows);
7859 (void) NormalizeImage(*image);
7860 XSetCursorState(display,windows,MagickFalse);
7861 if (windows->image.orphan != MagickFalse)
7863 XConfigureImageColormap(display,resource_info,windows,*image);
7864 (void) XConfigureImage(display,resource_info,windows,*image);
7867 case EqualizeCommand:
7872 XSetCursorState(display,windows,MagickTrue);
7873 XCheckRefreshWindows(display,windows);
7874 (void) EqualizeImage(*image);
7875 XSetCursorState(display,windows,MagickFalse);
7876 if (windows->image.orphan != MagickFalse)
7878 XConfigureImageColormap(display,resource_info,windows,*image);
7879 (void) XConfigureImage(display,resource_info,windows,*image);
7887 XSetCursorState(display,windows,MagickTrue);
7888 XCheckRefreshWindows(display,windows);
7889 (void) NegateImage(*image,MagickFalse);
7890 XSetCursorState(display,windows,MagickFalse);
7891 if (windows->image.orphan != MagickFalse)
7893 XConfigureImageColormap(display,resource_info,windows,*image);
7894 (void) XConfigureImage(display,resource_info,windows,*image);
7897 case GrayscaleCommand:
7902 XSetCursorState(display,windows,MagickTrue);
7903 XCheckRefreshWindows(display,windows);
7904 (void) SetImageType(*image,(*image)->matte == MagickFalse ?
7905 GrayscaleType : GrayscaleMatteType);
7906 XSetCursorState(display,windows,MagickFalse);
7907 if (windows->image.orphan != MagickFalse)
7909 XConfigureImageColormap(display,resource_info,windows,*image);
7910 (void) XConfigureImage(display,resource_info,windows,*image);
7919 filename[MaxTextExtent] =
"\0";
7924 XFileBrowserWidget(display,windows,
"Map",filename);
7925 if (*filename ==
'\0')
7930 XSetCursorState(display,windows,MagickTrue);
7931 XCheckRefreshWindows(display,windows);
7932 (void) CopyMagickString(image_info->filename,filename,MaxTextExtent);
7933 affinity_image=ReadImage(image_info,&(*image)->exception);
7934 if (affinity_image != (
Image *) NULL)
7936 (void) RemapImage(&quantize_info,*image,affinity_image);
7937 affinity_image=DestroyImage(affinity_image);
7939 CatchException(&(*image)->exception);
7940 XSetCursorState(display,windows,MagickFalse);
7941 if (windows->image.orphan != MagickFalse)
7943 XConfigureImageColormap(display,resource_info,windows,*image);
7944 (void) XConfigureImage(display,resource_info,windows,*image);
7947 case QuantizeCommand:
7953 colors[MaxTextExtent] =
"256";
7958 status=XDialogWidget(display,windows,
"Quantize",
7959 "Maximum number of colors:",colors);
7960 if (*colors ==
'\0')
7965 XSetCursorState(display,windows,MagickTrue);
7966 XCheckRefreshWindows(display,windows);
7967 quantize_info.number_colors=StringToUnsignedLong(colors);
7968 quantize_info.dither=status != 0 ? MagickTrue : MagickFalse;
7969 (void) QuantizeImage(&quantize_info,*image);
7970 XSetCursorState(display,windows,MagickFalse);
7971 if (windows->image.orphan != MagickFalse)
7973 XConfigureImageColormap(display,resource_info,windows,*image);
7974 (void) XConfigureImage(display,resource_info,windows,*image);
7977 case DespeckleCommand:
7985 XSetCursorState(display,windows,MagickTrue);
7986 XCheckRefreshWindows(display,windows);
7987 despeckle_image=DespeckleImage(*image,&(*image)->exception);
7988 if (despeckle_image != (
Image *) NULL)
7990 *image=DestroyImage(*image);
7991 *image=despeckle_image;
7993 CatchException(&(*image)->exception);
7994 XSetCursorState(display,windows,MagickFalse);
7995 if (windows->image.orphan != MagickFalse)
7997 XConfigureImageColormap(display,resource_info,windows,*image);
7998 (void) XConfigureImage(display,resource_info,windows,*image);
8007 radius[MaxTextExtent] =
"0.0x1.0";
8012 (void) XDialogWidget(display,windows,
"Emboss",
8013 "Enter the emboss radius and standard deviation:",radius);
8014 if (*radius ==
'\0')
8019 XSetCursorState(display,windows,MagickTrue);
8020 XCheckRefreshWindows(display,windows);
8021 flags=ParseGeometry(radius,&geometry_info);
8022 if ((flags & SigmaValue) == 0)
8023 geometry_info.sigma=1.0;
8024 emboss_image=EmbossImage(*image,geometry_info.rho,geometry_info.sigma,
8025 &(*image)->exception);
8026 if (emboss_image != (
Image *) NULL)
8028 *image=DestroyImage(*image);
8029 *image=emboss_image;
8031 CatchException(&(*image)->exception);
8032 XSetCursorState(display,windows,MagickFalse);
8033 if (windows->image.orphan != MagickFalse)
8035 XConfigureImageColormap(display,resource_info,windows,*image);
8036 (void) XConfigureImage(display,resource_info,windows,*image);
8039 case ReduceNoiseCommand:
8045 radius[MaxTextExtent] =
"0";
8050 (void) XDialogWidget(display,windows,
"Reduce Noise",
8051 "Enter the noise radius:",radius);
8052 if (*radius ==
'\0')
8057 XSetCursorState(display,windows,MagickTrue);
8058 XCheckRefreshWindows(display,windows);
8059 flags=ParseGeometry(radius,&geometry_info);
8060 noise_image=StatisticImage(*image,NonpeakStatistic,(
size_t)
8061 geometry_info.rho,(
size_t) geometry_info.rho,&(*image)->exception);
8062 if (noise_image != (
Image *) NULL)
8064 *image=DestroyImage(*image);
8067 CatchException(&(*image)->exception);
8068 XSetCursorState(display,windows,MagickFalse);
8069 if (windows->image.orphan != MagickFalse)
8071 XConfigureImageColormap(display,resource_info,windows,*image);
8072 (void) XConfigureImage(display,resource_info,windows,*image);
8075 case AddNoiseCommand:
8084 noise_type[MaxTextExtent] =
"Gaussian";
8089 noises=GetCommandOptions(MagickNoiseOptions);
8090 if (noises == (
char **) NULL)
8092 XListBrowserWidget(display,windows,&windows->widget,
8093 (
const char **) noises,
"Add Noise",
8094 "Select a type of noise to add to your image:",noise_type);
8095 noises=DestroyStringList(noises);
8096 if (*noise_type ==
'\0')
8098 XSetCursorState(display,windows,MagickTrue);
8099 XCheckRefreshWindows(display,windows);
8100 noise_image=AddNoiseImage(*image,(NoiseType) ParseCommandOption(
8101 MagickNoiseOptions,MagickFalse,noise_type),&(*image)->exception);
8102 if (noise_image != (
Image *) NULL)
8104 *image=DestroyImage(*image);
8107 CatchException(&(*image)->exception);
8108 XSetCursorState(display,windows,MagickFalse);
8109 if (windows->image.orphan != MagickFalse)
8111 XConfigureImageColormap(display,resource_info,windows,*image);
8112 (void) XConfigureImage(display,resource_info,windows,*image);
8115 case SharpenCommand:
8121 radius[MaxTextExtent] =
"0.0x1.0";
8126 (void) XDialogWidget(display,windows,
"Sharpen",
8127 "Enter the sharpen radius and standard deviation:",radius);
8128 if (*radius ==
'\0')
8133 XSetCursorState(display,windows,MagickTrue);
8134 XCheckRefreshWindows(display,windows);
8135 flags=ParseGeometry(radius,&geometry_info);
8136 sharp_image=SharpenImage(*image,geometry_info.rho,geometry_info.sigma,
8137 &(*image)->exception);
8138 if (sharp_image != (
Image *) NULL)
8140 *image=DestroyImage(*image);
8143 CatchException(&(*image)->exception);
8144 XSetCursorState(display,windows,MagickFalse);
8145 if (windows->image.orphan != MagickFalse)
8147 XConfigureImageColormap(display,resource_info,windows,*image);
8148 (void) XConfigureImage(display,resource_info,windows,*image);
8157 radius[MaxTextExtent] =
"0.0x1.0";
8162 (void) XDialogWidget(display,windows,
"Blur",
8163 "Enter the blur radius and standard deviation:",radius);
8164 if (*radius ==
'\0')
8169 XSetCursorState(display,windows,MagickTrue);
8170 XCheckRefreshWindows(display,windows);
8171 flags=ParseGeometry(radius,&geometry_info);
8172 blur_image=BlurImage(*image,geometry_info.rho,geometry_info.sigma,
8173 &(*image)->exception);
8174 if (blur_image != (
Image *) NULL)
8176 *image=DestroyImage(*image);
8179 CatchException(&(*image)->exception);
8180 XSetCursorState(display,windows,MagickFalse);
8181 if (windows->image.orphan != MagickFalse)
8183 XConfigureImageColormap(display,resource_info,windows,*image);
8184 (void) XConfigureImage(display,resource_info,windows,*image);
8187 case ThresholdCommand:
8193 factor[MaxTextExtent] =
"128";
8198 (void) XDialogWidget(display,windows,
"Threshold",
8199 "Enter threshold value:",factor);
8200 if (*factor ==
'\0')
8205 XSetCursorState(display,windows,MagickTrue);
8206 XCheckRefreshWindows(display,windows);
8207 threshold=StringToDoubleInterval(factor,(
double) QuantumRange+1.0);
8208 (void) BilevelImage(*image,threshold);
8209 XSetCursorState(display,windows,MagickFalse);
8210 if (windows->image.orphan != MagickFalse)
8212 XConfigureImageColormap(display,resource_info,windows,*image);
8213 (void) XConfigureImage(display,resource_info,windows,*image);
8216 case EdgeDetectCommand:
8222 radius[MaxTextExtent] =
"0";
8227 (void) XDialogWidget(display,windows,
"Detect Edges",
8228 "Enter the edge detect radius:",radius);
8229 if (*radius ==
'\0')
8234 XSetCursorState(display,windows,MagickTrue);
8235 XCheckRefreshWindows(display,windows);
8236 flags=ParseGeometry(radius,&geometry_info);
8237 edge_image=EdgeImage(*image,geometry_info.rho,&(*image)->exception);
8238 if (edge_image != (
Image *) NULL)
8240 *image=DestroyImage(*image);
8243 CatchException(&(*image)->exception);
8244 XSetCursorState(display,windows,MagickFalse);
8245 if (windows->image.orphan != MagickFalse)
8247 XConfigureImageColormap(display,resource_info,windows,*image);
8248 (void) XConfigureImage(display,resource_info,windows,*image);
8257 amount[MaxTextExtent] =
"2";
8262 (void) XDialogWidget(display,windows,
"Spread",
8263 "Enter the displacement amount:",amount);
8264 if (*amount ==
'\0')
8269 XSetCursorState(display,windows,MagickTrue);
8270 XCheckRefreshWindows(display,windows);
8271 flags=ParseGeometry(amount,&geometry_info);
8272 spread_image=EdgeImage(*image,geometry_info.rho,&(*image)->exception);
8273 if (spread_image != (
Image *) NULL)
8275 *image=DestroyImage(*image);
8276 *image=spread_image;
8278 CatchException(&(*image)->exception);
8279 XSetCursorState(display,windows,MagickFalse);
8280 if (windows->image.orphan != MagickFalse)
8282 XConfigureImageColormap(display,resource_info,windows,*image);
8283 (void) XConfigureImage(display,resource_info,windows,*image);
8295 geometry[MaxTextExtent] =
"30x30";
8300 status=XDialogWidget(display,windows,
"Shade",
8301 "Enter the azimuth and elevation of the light source:",geometry);
8302 if (*geometry ==
'\0')
8307 XSetCursorState(display,windows,MagickTrue);
8308 XCheckRefreshWindows(display,windows);
8309 flags=ParseGeometry(geometry,&geometry_info);
8310 if ((flags & SigmaValue) == 0)
8311 geometry_info.sigma=1.0;
8312 shade_image=ShadeImage(*image,status != 0 ? MagickFalse : MagickTrue,
8313 geometry_info.rho,geometry_info.sigma,&(*image)->exception);
8314 if (shade_image != (
Image *) NULL)
8316 *image=DestroyImage(*image);
8319 CatchException(&(*image)->exception);
8320 XSetCursorState(display,windows,MagickFalse);
8321 if (windows->image.orphan != MagickFalse)
8323 XConfigureImageColormap(display,resource_info,windows,*image);
8324 (void) XConfigureImage(display,resource_info,windows,*image);
8330 bevel_width[MaxTextExtent] =
"10";
8335 (void) XDialogWidget(display,windows,
"Raise",
"Bevel width:",bevel_width);
8336 if (*bevel_width ==
'\0')
8341 (void) XMagickCommand(display,resource_info,windows,ApplyCommand,image);
8342 XSetCursorState(display,windows,MagickTrue);
8343 XCheckRefreshWindows(display,windows);
8344 (void) ParsePageGeometry(*image,bevel_width,&page_geometry,
8345 &(*image)->exception);
8346 (void) RaiseImage(*image,&page_geometry,MagickTrue);
8347 XSetCursorState(display,windows,MagickFalse);
8348 if (windows->image.orphan != MagickFalse)
8350 XConfigureImageColormap(display,resource_info,windows,*image);
8351 (void) XConfigureImage(display,resource_info,windows,*image);
8354 case SegmentCommand:
8357 threshold[MaxTextExtent] =
"1.0x1.5";
8362 (void) XDialogWidget(display,windows,
"Segment",
"Smooth threshold:",
8364 if (*threshold ==
'\0')
8369 XSetCursorState(display,windows,MagickTrue);
8370 XCheckRefreshWindows(display,windows);
8371 flags=ParseGeometry(threshold,&geometry_info);
8372 if ((flags & SigmaValue) == 0)
8373 geometry_info.sigma=1.0;
8374 (void) SegmentImage(*image,sRGBColorspace,MagickFalse,geometry_info.rho,
8375 geometry_info.sigma);
8376 XSetCursorState(display,windows,MagickFalse);
8377 if (windows->image.orphan != MagickFalse)
8379 XConfigureImageColormap(display,resource_info,windows,*image);
8380 (void) XConfigureImage(display,resource_info,windows,*image);
8383 case SepiaToneCommand:
8392 factor[MaxTextExtent] =
"80%";
8397 (void) XDialogWidget(display,windows,
"Sepia Tone",
8398 "Enter the sepia tone factor (0 - 99.9%):",factor);
8399 if (*factor ==
'\0')
8404 XSetCursorState(display,windows,MagickTrue);
8405 XCheckRefreshWindows(display,windows);
8406 threshold=StringToDoubleInterval(factor,(
double) QuantumRange+1.0);
8407 sepia_image=SepiaToneImage(*image,threshold,&(*image)->exception);
8408 if (sepia_image != (
Image *) NULL)
8410 *image=DestroyImage(*image);
8413 CatchException(&(*image)->exception);
8414 XSetCursorState(display,windows,MagickFalse);
8415 if (windows->image.orphan != MagickFalse)
8417 XConfigureImageColormap(display,resource_info,windows,*image);
8418 (void) XConfigureImage(display,resource_info,windows,*image);
8421 case SolarizeCommand:
8427 factor[MaxTextExtent] =
"60%";
8432 (void) XDialogWidget(display,windows,
"Solarize",
8433 "Enter the solarize factor (0 - 99.9%):",factor);
8434 if (*factor ==
'\0')
8439 XSetCursorState(display,windows,MagickTrue);
8440 XCheckRefreshWindows(display,windows);
8441 threshold=StringToDoubleInterval(factor,(
double) QuantumRange+1.0);
8442 (void) SolarizeImage(*image,threshold);
8443 XSetCursorState(display,windows,MagickFalse);
8444 if (windows->image.orphan != MagickFalse)
8446 XConfigureImageColormap(display,resource_info,windows,*image);
8447 (void) XConfigureImage(display,resource_info,windows,*image);
8456 degrees[MaxTextExtent] =
"60";
8461 (void) XDialogWidget(display,windows,
"Swirl",
"Enter the swirl angle:",
8463 if (*degrees ==
'\0')
8468 XSetCursorState(display,windows,MagickTrue);
8469 XCheckRefreshWindows(display,windows);
8470 flags=ParseGeometry(degrees,&geometry_info);
8471 swirl_image=SwirlImage(*image,geometry_info.rho,&(*image)->exception);
8472 if (swirl_image != (
Image *) NULL)
8474 *image=DestroyImage(*image);
8477 CatchException(&(*image)->exception);
8478 XSetCursorState(display,windows,MagickFalse);
8479 if (windows->image.orphan != MagickFalse)
8481 XConfigureImageColormap(display,resource_info,windows,*image);
8482 (void) XConfigureImage(display,resource_info,windows,*image);
8485 case ImplodeCommand:
8491 factor[MaxTextExtent] =
"0.3";
8496 (void) XDialogWidget(display,windows,
"Implode",
8497 "Enter the implosion/explosion factor (-1.0 - 1.0):",factor);
8498 if (*factor ==
'\0')
8503 XSetCursorState(display,windows,MagickTrue);
8504 XCheckRefreshWindows(display,windows);
8505 flags=ParseGeometry(factor,&geometry_info);
8506 implode_image=ImplodeImage(*image,geometry_info.rho,&(*image)->exception);
8507 if (implode_image != (
Image *) NULL)
8509 *image=DestroyImage(*image);
8510 *image=implode_image;
8512 CatchException(&(*image)->exception);
8513 XSetCursorState(display,windows,MagickFalse);
8514 if (windows->image.orphan != MagickFalse)
8516 XConfigureImageColormap(display,resource_info,windows,*image);
8517 (void) XConfigureImage(display,resource_info,windows,*image);
8520 case VignetteCommand:
8526 geometry[MaxTextExtent] =
"0x20";
8531 (void) XDialogWidget(display,windows,
"Vignette",
8532 "Enter the radius, sigma, and x and y offsets:",geometry);
8533 if (*geometry ==
'\0')
8538 XSetCursorState(display,windows,MagickTrue);
8539 XCheckRefreshWindows(display,windows);
8540 flags=ParseGeometry(geometry,&geometry_info);
8541 if ((flags & SigmaValue) == 0)
8542 geometry_info.sigma=1.0;
8543 if ((flags & XiValue) == 0)
8544 geometry_info.xi=0.1*(*image)->columns;
8545 if ((flags & PsiValue) == 0)
8546 geometry_info.psi=0.1*(*image)->rows;
8547 vignette_image=VignetteImage(*image,geometry_info.rho,geometry_info.sigma,
8548 (ssize_t) ceil(geometry_info.xi-0.5),(ssize_t) ceil(geometry_info.psi-
8549 0.5),&(*image)->exception);
8550 if (vignette_image != (
Image *) NULL)
8552 *image=DestroyImage(*image);
8553 *image=vignette_image;
8555 CatchException(&(*image)->exception);
8556 XSetCursorState(display,windows,MagickFalse);
8557 if (windows->image.orphan != MagickFalse)
8559 XConfigureImageColormap(display,resource_info,windows,*image);
8560 (void) XConfigureImage(display,resource_info,windows,*image);
8569 geometry[MaxTextExtent] =
"25x150";
8574 (void) XDialogWidget(display,windows,
"Wave",
8575 "Enter the amplitude and length of the wave:",geometry);
8576 if (*geometry ==
'\0')
8581 XSetCursorState(display,windows,MagickTrue);
8582 XCheckRefreshWindows(display,windows);
8583 flags=ParseGeometry(geometry,&geometry_info);
8584 if ((flags & SigmaValue) == 0)
8585 geometry_info.sigma=1.0;
8586 wave_image=WaveImage(*image,geometry_info.rho,geometry_info.sigma,
8587 &(*image)->exception);
8588 if (wave_image != (
Image *) NULL)
8590 *image=DestroyImage(*image);
8593 CatchException(&(*image)->exception);
8594 XSetCursorState(display,windows,MagickFalse);
8595 if (windows->image.orphan != MagickFalse)
8597 XConfigureImageColormap(display,resource_info,windows,*image);
8598 (void) XConfigureImage(display,resource_info,windows,*image);
8601 case OilPaintCommand:
8607 radius[MaxTextExtent] =
"0";
8612 (void) XDialogWidget(display,windows,
"Oil Paint",
8613 "Enter the mask radius:",radius);
8614 if (*radius ==
'\0')
8619 XSetCursorState(display,windows,MagickTrue);
8620 XCheckRefreshWindows(display,windows);
8621 flags=ParseGeometry(radius,&geometry_info);
8622 paint_image=OilPaintImage(*image,geometry_info.rho,&(*image)->exception);
8623 if (paint_image != (
Image *) NULL)
8625 *image=DestroyImage(*image);
8628 CatchException(&(*image)->exception);
8629 XSetCursorState(display,windows,MagickFalse);
8630 if (windows->image.orphan != MagickFalse)
8632 XConfigureImageColormap(display,resource_info,windows,*image);
8633 (void) XConfigureImage(display,resource_info,windows,*image);
8636 case CharcoalDrawCommand:
8642 radius[MaxTextExtent] =
"0x1";
8647 (void) XDialogWidget(display,windows,
"Charcoal Draw",
8648 "Enter the charcoal radius and sigma:",radius);
8649 if (*radius ==
'\0')
8654 (void) XMagickCommand(display,resource_info,windows,ApplyCommand,image);
8655 XSetCursorState(display,windows,MagickTrue);
8656 XCheckRefreshWindows(display,windows);
8657 flags=ParseGeometry(radius,&geometry_info);
8658 if ((flags & SigmaValue) == 0)
8659 geometry_info.sigma=geometry_info.rho;
8660 charcoal_image=CharcoalImage(*image,geometry_info.rho,geometry_info.sigma,
8661 &(*image)->exception);
8662 if (charcoal_image != (
Image *) NULL)
8664 *image=DestroyImage(*image);
8665 *image=charcoal_image;
8667 CatchException(&(*image)->exception);
8668 XSetCursorState(display,windows,MagickFalse);
8669 if (windows->image.orphan != MagickFalse)
8671 XConfigureImageColormap(display,resource_info,windows,*image);
8672 (void) XConfigureImage(display,resource_info,windows,*image);
8675 case AnnotateCommand:
8680 status=XAnnotateEditImage(display,resource_info,windows,*image);
8681 if (status == MagickFalse)
8683 XNoticeWidget(display,windows,
"Unable to annotate X image",
8684 (*image)->filename);
8694 status=XDrawEditImage(display,resource_info,windows,image);
8695 if (status == MagickFalse)
8697 XNoticeWidget(display,windows,
"Unable to draw on the X image",
8698 (*image)->filename);
8708 status=XColorEditImage(display,resource_info,windows,image);
8709 if (status == MagickFalse)
8711 XNoticeWidget(display,windows,
"Unable to pixel edit X image",
8712 (*image)->filename);
8722 status=XMatteEditImage(display,resource_info,windows,image);
8723 if (status == MagickFalse)
8725 XNoticeWidget(display,windows,
"Unable to matte edit X image",
8726 (*image)->filename);
8731 case CompositeCommand:
8736 status=XCompositeImage(display,resource_info,windows,*image);
8737 if (status == MagickFalse)
8739 XNoticeWidget(display,windows,
"Unable to composite X image",
8740 (*image)->filename);
8745 case AddBorderCommand:
8751 geometry[MaxTextExtent] =
"6x6";
8756 XColorBrowserWidget(display,windows,
"Select",color);
8759 (void) XDialogWidget(display,windows,
"Add Border",
8760 "Enter border geometry:",geometry);
8761 if (*geometry ==
'\0')
8766 (void) XMagickCommand(display,resource_info,windows,ApplyCommand,image);
8767 XSetCursorState(display,windows,MagickTrue);
8768 XCheckRefreshWindows(display,windows);
8769 (void) QueryColorDatabase(color,&(*image)->border_color,
8770 &(*image)->exception);
8771 (void) ParsePageGeometry(*image,geometry,&page_geometry,
8772 &(*image)->exception);
8773 border_image=BorderImage(*image,&page_geometry,&(*image)->exception);
8774 if (border_image != (
Image *) NULL)
8776 *image=DestroyImage(*image);
8777 *image=border_image;
8779 CatchException(&(*image)->exception);
8780 XSetCursorState(display,windows,MagickFalse);
8781 if (windows->image.orphan != MagickFalse)
8783 windows->image.window_changes.width=(int) (*image)->columns;
8784 windows->image.window_changes.height=(
int) (*image)->rows;
8785 XConfigureImageColormap(display,resource_info,windows,*image);
8786 (void) XConfigureImage(display,resource_info,windows,*image);
8789 case AddFrameCommand:
8798 geometry[MaxTextExtent] =
"6x6";
8803 XColorBrowserWidget(display,windows,
"Select",color);
8806 (void) XDialogWidget(display,windows,
"Add Frame",
"Enter frame geometry:",
8808 if (*geometry ==
'\0')
8813 (void) XMagickCommand(display,resource_info,windows,ApplyCommand,image);
8814 XSetCursorState(display,windows,MagickTrue);
8815 XCheckRefreshWindows(display,windows);
8816 (void) QueryColorDatabase(color,&(*image)->matte_color,
8817 &(*image)->exception);
8818 (void) ParsePageGeometry(*image,geometry,&page_geometry,
8819 &(*image)->exception);
8820 frame_info.width=page_geometry.width;
8821 frame_info.height=page_geometry.height;
8822 frame_info.outer_bevel=page_geometry.x;
8823 frame_info.inner_bevel=page_geometry.y;
8824 frame_info.x=(ssize_t) frame_info.width;
8825 frame_info.y=(ssize_t) frame_info.height;
8826 frame_info.width=(*image)->columns+2*frame_info.width;
8827 frame_info.height=(*image)->rows+2*frame_info.height;
8828 frame_image=FrameImage(*image,&frame_info,&(*image)->exception);
8829 if (frame_image != (
Image *) NULL)
8831 *image=DestroyImage(*image);
8834 CatchException(&(*image)->exception);
8835 XSetCursorState(display,windows,MagickFalse);
8836 if (windows->image.orphan != MagickFalse)
8838 windows->image.window_changes.width=(int) (*image)->columns;
8839 windows->image.window_changes.height=(
int) (*image)->rows;
8840 XConfigureImageColormap(display,resource_info,windows,*image);
8841 (void) XConfigureImage(display,resource_info,windows,*image);
8844 case CommentCommand:
8858 unique_file=AcquireUniqueFileResource(image_info->filename);
8859 if (unique_file == -1)
8861 XNoticeWidget(display,windows,
"Unable to edit image comment",
8862 image_info->filename);
8865 value=GetImageProperty(*image,
"comment");
8866 if (value == (
char *) NULL)
8867 unique_file=close(unique_file)-1;
8873 file=fdopen(unique_file,
"w");
8874 if (file == (FILE *) NULL)
8876 XNoticeWidget(display,windows,
"Unable to edit image comment",
8877 image_info->filename);
8880 for (p=value; *p !=
'\0'; p++)
8881 (
void) fputc((
int) *p,file);
8882 (void) fputc(
'\n',file);
8883 (void) fclose(file);
8885 XSetCursorState(display,windows,MagickTrue);
8886 XCheckRefreshWindows(display,windows);
8887 status=InvokeDelegate(image_info,*image,
"edit",(
char *) NULL,
8888 &(*image)->exception);
8889 if (status == MagickFalse)
8890 XNoticeWidget(display,windows,
"Unable to edit image comment",
8897 comment=FileToString(image_info->filename,~0UL,&(*image)->exception);
8898 if (comment != (
char *) NULL)
8900 (void) SetImageProperty(*image,
"comment",comment);
8901 (*image)->taint=MagickTrue;
8904 (void) RelinquishUniqueFileResource(image_info->filename);
8905 XSetCursorState(display,windows,MagickFalse);
8913 XSetCursorState(display,windows,MagickTrue);
8914 XCheckRefreshWindows(display,windows);
8915 (void) AcquireUniqueFilename(filename);
8916 (void) FormatLocaleString((*image)->filename,MaxTextExtent,
"launch:%s",
8918 status=WriteImage(image_info,*image);
8919 if (status == MagickFalse)
8920 XNoticeWidget(display,windows,
"Unable to launch image editor",
8924 nexus=ReadImage(resource_info->image_info,&(*image)->exception);
8925 CatchException(&(*image)->exception);
8926 XClientMessage(display,windows->image.id,windows->im_protocols,
8927 windows->im_next_image,CurrentTime);
8929 (void) RelinquishUniqueFileResource(filename);
8930 XSetCursorState(display,windows,MagickFalse);
8933 case RegionofInterestCommand:
8938 (void) XROIImage(display,resource_info,windows,image);
8948 if (windows->magnify.mapped != MagickFalse)
8949 (void) XRaiseWindow(display,windows->magnify.id);
8955 XSetCursorState(display,windows,MagickTrue);
8956 (void) XMapRaised(display,windows->magnify.id);
8957 XSetCursorState(display,windows,MagickFalse);
8961 case ShowPreviewCommand:
8970 preview_type[MaxTextExtent] =
"Gamma";
8975 previews=GetCommandOptions(MagickPreviewOptions);
8976 if (previews == (
char **) NULL)
8978 XListBrowserWidget(display,windows,&windows->widget,
8979 (
const char **) previews,
"Preview",
8980 "Select an enhancement, effect, or F/X:",preview_type);
8981 previews=DestroyStringList(previews);
8982 if (*preview_type ==
'\0')
8987 XSetCursorState(display,windows,MagickTrue);
8988 XCheckRefreshWindows(display,windows);
8989 image_info->preview_type=(PreviewType)
8990 ParseCommandOption(MagickPreviewOptions,MagickFalse,preview_type);
8991 image_info->group=(ssize_t) windows->image.id;
8992 (
void) DeleteImageProperty(*image,
"label");
8993 (void) SetImageProperty(*image,
"label",
"Preview");
8994 (void) AcquireUniqueFilename(filename);
8995 (void) FormatLocaleString((*image)->filename,MaxTextExtent,
"preview:%s",
8997 status=WriteImage(image_info,*image);
8998 (void) CopyMagickString(image_info->filename,filename,MaxTextExtent);
8999 preview_image=ReadImage(image_info,&(*image)->exception);
9000 (void) RelinquishUniqueFileResource(filename);
9001 if (preview_image == (
Image *) NULL)
9003 (void) FormatLocaleString(preview_image->filename,MaxTextExtent,
"show:%s",
9005 status=WriteImage(image_info,preview_image);
9006 preview_image=DestroyImage(preview_image);
9007 if (status == MagickFalse)
9008 XNoticeWidget(display,windows,
"Unable to show image preview",
9009 (*image)->filename);
9010 XDelay(display,1500);
9011 XSetCursorState(display,windows,MagickFalse);
9014 case ShowHistogramCommand:
9022 XSetCursorState(display,windows,MagickTrue);
9023 XCheckRefreshWindows(display,windows);
9024 image_info->group=(ssize_t) windows->image.id;
9025 (
void) DeleteImageProperty(*image,
"label");
9026 (void) SetImageProperty(*image,
"label",
"Histogram");
9027 (void) AcquireUniqueFilename(filename);
9028 (void) FormatLocaleString((*image)->filename,MaxTextExtent,
"histogram:%s",
9030 status=WriteImage(image_info,*image);
9031 (void) CopyMagickString(image_info->filename,filename,MaxTextExtent);
9032 histogram_image=ReadImage(image_info,&(*image)->exception);
9033 (void) RelinquishUniqueFileResource(filename);
9034 if (histogram_image == (
Image *) NULL)
9036 (void) FormatLocaleString(histogram_image->filename,MaxTextExtent,
9037 "show:%s",filename);
9038 status=WriteImage(image_info,histogram_image);
9039 histogram_image=DestroyImage(histogram_image);
9040 if (status == MagickFalse)
9041 XNoticeWidget(display,windows,
"Unable to show histogram",
9042 (*image)->filename);
9043 XDelay(display,1500);
9044 XSetCursorState(display,windows,MagickFalse);
9047 case ShowMatteCommand:
9052 if ((*image)->matte == MagickFalse)
9054 XNoticeWidget(display,windows,
9055 "Image does not have any matte information",(*image)->filename);
9061 XSetCursorState(display,windows,MagickTrue);
9062 XCheckRefreshWindows(display,windows);
9063 image_info->group=(ssize_t) windows->image.id;
9064 (
void) DeleteImageProperty(*image,
"label");
9065 (void) SetImageProperty(*image,
"label",
"Matte");
9066 (void) AcquireUniqueFilename(filename);
9067 (void) FormatLocaleString((*image)->filename,MaxTextExtent,
"matte:%s",
9069 status=WriteImage(image_info,*image);
9070 (void) CopyMagickString(image_info->filename,filename,MaxTextExtent);
9071 matte_image=ReadImage(image_info,&(*image)->exception);
9072 (void) RelinquishUniqueFileResource(filename);
9073 if (matte_image == (
Image *) NULL)
9075 (void) FormatLocaleString(matte_image->filename,MaxTextExtent,
"show:%s",
9077 status=WriteImage(image_info,matte_image);
9078 matte_image=DestroyImage(matte_image);
9079 if (status == MagickFalse)
9080 XNoticeWidget(display,windows,
"Unable to show matte",
9081 (*image)->filename);
9082 XDelay(display,1500);
9083 XSetCursorState(display,windows,MagickFalse);
9086 case BackgroundCommand:
9091 status=XBackgroundImage(display,resource_info,windows,image);
9092 if (status == MagickFalse)
9094 nexus=CloneImage(*image,0,0,MagickTrue,&(*image)->exception);
9095 if (nexus != (
Image *) NULL)
9096 XClientMessage(display,windows->image.id,windows->im_protocols,
9097 windows->im_next_image,CurrentTime);
9100 case SlideShowCommand:
9103 delay[MaxTextExtent] =
"5";
9108 (void) XDialogWidget(display,windows,
"Slide Show",
9109 "Pause how many 1/100ths of a second between images:",delay);
9112 resource_info->delay=StringToUnsignedLong(delay);
9113 XClientMessage(display,windows->image.id,windows->im_protocols,
9114 windows->im_next_image,CurrentTime);
9117 case PreferencesCommand:
9122 status=XPreferencesWidget(display,resource_info,windows);
9123 if (status == MagickFalse)
9125 nexus=CloneImage(*image,0,0,MagickTrue,&(*image)->exception);
9126 if (nexus != (
Image *) NULL)
9127 XClientMessage(display,windows->image.id,windows->im_protocols,
9128 windows->im_next_image,CurrentTime);
9136 XTextViewHelp(display,resource_info,windows,MagickFalse,
9137 "Help Viewer - Display",DisplayHelp);
9140 case BrowseDocumentationCommand:
9152 root_window=XRootWindow(display,XDefaultScreen(display));
9153 mozilla_atom=XInternAtom(display,
"_MOZILLA_VERSION",MagickFalse);
9154 mozilla_window=XWindowByProperty(display,root_window,mozilla_atom);
9155 if (mozilla_window != (Window) NULL)
9158 command[MaxTextExtent];
9163 (void) FormatLocaleString(command,MaxTextExtent,
9164 "openurl(%s,new-tab)",MagickAuthoritativeURL);
9165 mozilla_atom=XInternAtom(display,
"_MOZILLA_COMMAND",MagickFalse);
9166 (void) XChangeProperty(display,mozilla_window,mozilla_atom,XA_STRING,
9167 8,PropModeReplace,(
unsigned char *) command,(int) strlen(command));
9168 XSetCursorState(display,windows,MagickFalse);
9171 XSetCursorState(display,windows,MagickTrue);
9172 XCheckRefreshWindows(display,windows);
9173 status=InvokeDelegate(image_info,*image,
"browse",(
char *) NULL,
9174 &(*image)->exception);
9175 if (status == MagickFalse)
9176 XNoticeWidget(display,windows,
"Unable to browse documentation",
9178 XDelay(display,1500);
9179 XSetCursorState(display,windows,MagickFalse);
9182 case VersionCommand:
9184 XNoticeWidget(display,windows,GetMagickVersion((
size_t *) NULL),
9185 GetMagickCopyright());
9188 case SaveToUndoBufferCommand:
9192 (void) XBell(display,0);
9196 image_info=DestroyImageInfo(image_info);
9229 static void XMagnifyImage(Display *display,XWindows *windows,XEvent *event)
9232 text[MaxTextExtent];
9244 (void) XCheckDefineCursor(display,windows->image.id,windows->magnify.cursor);
9248 windows->magnify.x=(int) windows->image.x+x;
9249 windows->magnify.y=(
int) windows->image.y+y;
9255 if (windows->info.mapped != MagickFalse)
9257 if ((x < (
int) (windows->info.x+windows->info.width)) &&
9258 (y < (int) (windows->info.y+windows->info.height)))
9259 (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
9262 if ((x > (
int) (windows->info.x+windows->info.width)) ||
9263 (y > (int) (windows->info.y+windows->info.height)))
9264 (void) XMapWindow(display,windows->info.id);
9265 if (windows->info.mapped != MagickFalse)
9270 (void) FormatLocaleString(text,MaxTextExtent,
" %+d%+d ",
9271 windows->magnify.x,windows->magnify.y);
9272 XInfoWidget(display,windows,text);
9277 XScreenEvent(display,windows,event);
9278 switch (event->type)
9309 if (x >= (
int) windows->image.width)
9310 x=(int) windows->image.width-1;
9314 if (y >= (
int) windows->image.height)
9315 y=(
int) windows->image.height-1;
9316 }
while ((state & ExitState) == 0);
9320 XSetCursorState(display,windows,MagickFalse);
9355 static void XMagnifyWindowCommand(Display *display,XWindows *windows,
9356 const MagickStatusType state,
const KeySym key_symbol)
9365 if ((state & Mod1Mask) != 0)
9367 switch ((
int) key_symbol)
9371 (void) XWithdrawWindow(display,windows->magnify.id,
9372 windows->magnify.screen);
9378 windows->magnify.x=(int) windows->image.width/2;
9379 windows->magnify.y=(
int) windows->image.height/2;
9385 if (windows->magnify.x > 0)
9386 windows->magnify.x-=quantum;
9392 if (windows->magnify.y > 0)
9393 windows->magnify.y-=quantum;
9399 if (windows->magnify.x < (
int) (windows->image.ximage->width-1))
9400 windows->magnify.x+=quantum;
9406 if (windows->magnify.y < (
int) (windows->image.ximage->height-1))
9407 windows->magnify.y+=quantum;
9421 windows->magnify.data=(key_symbol-XK_0);
9435 windows->magnify.data=(key_symbol-XK_KP_0);
9441 XMakeMagnifyImage(display,windows);
9475 static void XMakePanImage(Display *display,XResourceInfo *resource_info,
9476 XWindows *windows,
Image *image)
9484 XSetCursorState(display,windows,MagickTrue);
9485 XCheckRefreshWindows(display,windows);
9486 windows->pan.x=(int) windows->image.x;
9487 windows->pan.y=(
int) windows->image.y;
9488 status=XMakeImage(display,resource_info,&windows->pan,image,
9489 windows->pan.width,windows->pan.height);
9490 if (status == MagickFalse)
9491 ThrowXWindowFatalException(XServerFatalError,image->exception.reason,
9492 image->exception.description);
9493 (void) XSetWindowBackgroundPixmap(display,windows->pan.id,
9494 windows->pan.pixmap);
9495 (void) XClearWindow(display,windows->pan.id);
9496 XDrawPanRectangle(display,windows);
9497 XSetCursorState(display,windows,MagickFalse);
9532 static MagickBooleanType XMatteEditImage(Display *display,
9533 XResourceInfo *resource_info,XWindows *windows,
Image **image)
9536 *
const MatteEditMenu[] =
9549 matte[MaxTextExtent] =
"0";
9551 static const ModeType
9552 MatteEditCommands[] =
9555 MatteEditBorderCommand,
9556 MatteEditFuzzCommand,
9557 MatteEditValueCommand,
9558 MatteEditUndoCommand,
9559 MatteEditHelpCommand,
9560 MatteEditDismissCommand
9564 method = PointMethod;
9567 border_color = { 0, 0, 0, 0, 0, 0 };
9570 command[MaxTextExtent],
9571 text[MaxTextExtent] =
"";
9603 (void) CloneString(&windows->command.name,
"Matte Edit");
9604 windows->command.data=4;
9605 (void) XCommandWidget(display,windows,MatteEditMenu,(XEvent *) NULL);
9606 (void) XMapRaised(display,windows->command.id);
9607 XClientMessage(display,windows->image.id,windows->im_protocols,
9608 windows->im_update_widget,CurrentTime);
9612 cursor=XMakeCursor(display,windows->image.id,windows->map_info->colormap,
9613 resource_info->background_color,resource_info->foreground_color);
9614 (void) XCheckDefineCursor(display,windows->image.id,cursor);
9618 XQueryPosition(display,windows->image.id,&x,&y);
9619 (void) XSelectInput(display,windows->image.id,
9620 windows->image.attributes.event_mask | PointerMotionMask);
9624 if (windows->info.mapped != MagickFalse)
9629 (void) FormatLocaleString(text,MaxTextExtent,
" %+d%+d ",
9630 x+windows->image.x,y+windows->image.y);
9631 XInfoWidget(display,windows,text);
9636 XScreenEvent(display,windows,&event);
9637 if (event.xany.window == windows->command.id)
9642 id=XCommandWidget(display,windows,MatteEditMenu,&event);
9645 (void) XCheckDefineCursor(display,windows->image.id,cursor);
9648 switch (MatteEditCommands[
id])
9650 case MatteEditMethod:
9658 methods=GetCommandOptions(MagickMethodOptions);
9659 if (methods == (
char **) NULL)
9661 entry=XMenuWidget(display,windows,MatteEditMenu[
id],
9662 (
const char **) methods,command);
9664 method=(PaintMethod) ParseCommandOption(MagickMethodOptions,
9665 MagickFalse,methods[entry]);
9666 methods=DestroyStringList(methods);
9669 case MatteEditBorderCommand:
9672 *ColorMenu[MaxNumberPens];
9680 for (i=0; i < (int) (MaxNumberPens-2); i++)
9681 ColorMenu[i]=resource_info->pen_colors[i];
9682 ColorMenu[MaxNumberPens-2]=
"Browser...";
9683 ColorMenu[MaxNumberPens-1]=(
const char *) NULL;
9687 pen_number=XMenuWidget(display,windows,MatteEditMenu[
id],
9688 (
const char **) ColorMenu,command);
9691 if (pen_number == (MaxNumberPens-2))
9694 color_name[MaxTextExtent] =
"gray";
9699 resource_info->pen_colors[pen_number]=color_name;
9700 XColorBrowserWidget(display,windows,
"Select",color_name);
9701 if (*color_name ==
'\0')
9707 (void) XParseColor(display,windows->map_info->colormap,
9708 resource_info->pen_colors[pen_number],&border_color);
9711 case MatteEditFuzzCommand:
9726 fuzz[MaxTextExtent];
9731 entry=XMenuWidget(display,windows,MatteEditMenu[
id],FuzzMenu,
9737 (*image)->fuzz=StringToDoubleInterval(FuzzMenu[entry],(
double)
9741 (void) CopyMagickString(fuzz,
"20%",MaxTextExtent);
9742 (void) XDialogWidget(display,windows,
"Ok",
9743 "Enter fuzz factor (0.0 - 99.9%):",fuzz);
9746 (void) ConcatenateMagickString(fuzz,
"%",MaxTextExtent);
9747 (*image)->fuzz=StringToDoubleInterval(fuzz,(
double) QuantumRange+
9751 case MatteEditValueCommand:
9754 *
const MatteMenu[] =
9763 message[MaxTextExtent];
9768 entry=XMenuWidget(display,windows,MatteEditMenu[
id],MatteMenu,
9774 (void) FormatLocaleString(matte,MaxTextExtent,QuantumFormat,
9776 if (LocaleCompare(MatteMenu[entry],
"Transparent") == 0)
9777 (
void) FormatLocaleString(matte,MaxTextExtent,QuantumFormat,
9778 (Quantum) TransparentOpacity);
9781 (void) FormatLocaleString(message,MaxTextExtent,
9782 "Enter matte value (0 - " QuantumFormat
"):",(Quantum)
9784 (void) XDialogWidget(display,windows,
"Matte",message,matte);
9789 case MatteEditUndoCommand:
9791 (void) XMagickCommand(display,resource_info,windows,UndoCommand,
9795 case MatteEditHelpCommand:
9797 XTextViewHelp(display,resource_info,windows,MagickFalse,
9798 "Help Viewer - Matte Edit",ImageMatteEditHelp);
9801 case MatteEditDismissCommand:
9813 (void) XCheckDefineCursor(display,windows->image.id,cursor);
9820 if (event.xbutton.button != Button1)
9822 if ((event.xbutton.window != windows->image.id) &&
9823 (
event.xbutton.window != windows->magnify.id))
9830 (void) XMagickCommand(display,resource_info,windows,
9831 SaveToUndoBufferCommand,image);
9832 state|=UpdateConfigurationState;
9837 if (event.xbutton.button != Button1)
9839 if ((event.xbutton.window != windows->image.id) &&
9840 (
event.xbutton.window != windows->magnify.id))
9847 XConfigureImageColormap(display,resource_info,windows,*image);
9848 (void) XConfigureImage(display,resource_info,windows,*image);
9849 XInfoWidget(display,windows,text);
9850 (void) XCheckDefineCursor(display,windows->image.id,cursor);
9851 state&=(~UpdateConfigurationState);
9859 command[MaxTextExtent];
9864 if (event.xkey.window == windows->magnify.id)
9869 window=windows->magnify.id;
9870 while (XCheckWindowEvent(display,window,KeyPressMask,&event)) ;
9872 if (event.xkey.window != windows->image.id)
9877 (void) XLookupString((XKeyEvent *) &
event.xkey,command,(int)
9878 sizeof(command),&key_symbol,(XComposeStatus *) NULL);
9879 switch ((
int) key_symbol)
9893 XTextViewHelp(display,resource_info,windows,MagickFalse,
9894 "Help Viewer - Matte Edit",ImageMatteEditHelp);
9899 (void) XBell(display,0);
9912 if (windows->info.mapped != MagickFalse)
9914 if ((x < (
int) (windows->info.x+windows->info.width)) &&
9915 (y < (int) (windows->info.y+windows->info.height)))
9916 (void) XWithdrawWindow(display,windows->info.id,
9917 windows->info.screen);
9920 if ((x > (
int) (windows->info.x+windows->info.width)) ||
9921 (y > (int) (windows->info.y+windows->info.height)))
9922 (void) XMapWindow(display,windows->info.id);
9928 if (event.xany.window == windows->magnify.id)
9930 x=windows->magnify.x-windows->image.x;
9931 y=windows->magnify.y-windows->image.y;
9935 if ((state & UpdateConfigurationState) != 0)
9950 (void) XClearArea(display,windows->image.id,x_offset,y_offset,1,1,
9952 XPutPixel(windows->image.ximage,x_offset,y_offset,
9953 windows->pixel_info->background_color.pixel);
9954 width=(
unsigned int) (*image)->columns;
9955 height=(
unsigned int) (*image)->rows;
9958 if (windows->image.crop_geometry != (
char *) NULL)
9959 (
void) XParseGeometry(windows->image.crop_geometry,&x,&y,
9962 (width*(windows->image.x+x_offset)/windows->image.ximage->width+x);
9964 (height*(windows->image.y+y_offset)/windows->image.ximage->height+y);
9965 if ((x_offset < 0) || (y_offset < 0))
9967 if ((x_offset >= (
int) (*image)->columns) ||
9968 (y_offset >= (
int) (*image)->rows))
9970 if (SetImageStorageClass(*image,DirectClass) == MagickFalse)
9971 return(MagickFalse);
9972 (*image)->matte=MagickTrue;
9973 exception=(&(*image)->exception);
9974 image_view=AcquireAuthenticCacheView(*image,exception);
9983 q=GetCacheViewAuthenticPixels(image_view,(ssize_t) x_offset,
9984 (ssize_t) y_offset,1,1,exception);
9987 q->opacity=(Quantum) StringToLong(matte);
9988 (void) SyncCacheViewAuthenticPixels(image_view,exception);
9999 (void) GetOneCacheViewVirtualPixel(image_view,(ssize_t) x_offset,
10000 (ssize_t) y_offset,&target,exception);
10001 for (y=0; y < (int) (*image)->rows; y++)
10003 q=GetCacheViewAuthenticPixels(image_view,0,(ssize_t) y,
10004 (*image)->columns,1,&(*image)->exception);
10007 for (x=0; x < (int) (*image)->columns; x++)
10009 if (IsColorSimilar(*image,q,&target))
10010 q->opacity=(Quantum) StringToLong(matte);
10013 if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
10018 case FloodfillMethod:
10019 case FillToBorderMethod:
10030 (void) GetOneVirtualMagickPixel(*image,(ssize_t) x_offset,
10031 (ssize_t) y_offset,&target,exception);
10032 if (method == FillToBorderMethod)
10034 target.red=(MagickRealType)
10035 ScaleShortToQuantum(border_color.red);
10036 target.green=(MagickRealType)
10037 ScaleShortToQuantum(border_color.green);
10038 target.blue=(MagickRealType)
10039 ScaleShortToQuantum(border_color.blue);
10041 draw_info=CloneDrawInfo(resource_info->image_info,
10043 draw_info->fill.opacity=ClampToQuantum(StringToDouble(matte,
10045 (void) FloodfillPaintImage(*image,OpacityChannel,draw_info,&target,
10046 (ssize_t) x_offset,(ssize_t) y_offset,
10047 method == FloodfillMethod ? MagickFalse : MagickTrue);
10048 draw_info=DestroyDrawInfo(draw_info);
10056 if (SetImageStorageClass(*image,DirectClass) == MagickFalse)
10057 return(MagickFalse);
10058 for (y=0; y < (int) (*image)->rows; y++)
10060 q=QueueCacheViewAuthenticPixels(image_view,0,(ssize_t) y,
10061 (*image)->columns,1,exception);
10064 for (x=0; x < (int) (*image)->columns; x++)
10066 q->opacity=(Quantum) StringToLong(matte);
10069 if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
10072 if (StringToLong(matte) == OpaqueOpacity)
10073 (*image)->matte=MagickFalse;
10077 image_view=DestroyCacheView(image_view);
10078 state&=(~UpdateConfigurationState);
10080 }
while ((state & ExitState) == 0);
10081 (void) XSelectInput(display,windows->image.id,
10082 windows->image.attributes.event_mask);
10083 XSetCursorState(display,windows,MagickFalse);
10084 (void) XFreeCursor(display,cursor);
10085 return(MagickTrue);
10119 static Image *XOpenImage(Display *display,XResourceInfo *resource_info,
10120 XWindows *windows,
const MagickBooleanType command)
10135 filename[MaxTextExtent] =
"\0";
10140 if (command == MagickFalse)
10141 XFileBrowserWidget(display,windows,
"Open",filename);
10159 status=XGetCommand(display,windows->image.id,&files,&count);
10161 ThrowXWindowException(XServerError,
"UnableToGetProperty",
"...");
10162 filelist=(
char **) AcquireQuantumMemory((
size_t) count,
sizeof(*filelist));
10163 if (filelist == (
char **) NULL)
10165 (void) XFreeStringList(files);
10166 ThrowXWindowException(ResourceLimitError,
10167 "MemoryAllocationFailed",
"...");
10168 return((
Image *) NULL);
10171 for (i=1; i < count; i++)
10172 if (*files[i] !=
'-')
10173 filelist[j++]=files[i];
10174 filelist[j]=(
char *) NULL;
10175 XListBrowserWidget(display,windows,&windows->widget,
10176 (
const char **) filelist,
"Load",
"Select Image to Load:",filename);
10177 filelist=(
char **) RelinquishMagickMemory(filelist);
10178 (void) XFreeStringList(files);
10180 if (*filename ==
'\0')
10181 return((
Image *) NULL);
10182 image_info=CloneImageInfo(resource_info->image_info);
10183 (void) SetImageInfoProgressMonitor(image_info,(MagickProgressMonitor) NULL,
10185 (void) CopyMagickString(image_info->filename,filename,MaxTextExtent);
10186 exception=AcquireExceptionInfo();
10187 (void) SetImageInfo(image_info,0,exception);
10188 if (LocaleCompare(image_info->magick,
"X") == 0)
10191 seconds[MaxTextExtent];
10196 (void) CopyMagickString(seconds,
"0",MaxTextExtent);
10197 (void) XDialogWidget(display,windows,
"Grab",
"Enter any delay in seconds:",
10199 if (*seconds ==
'\0')
10200 return((
Image *) NULL);
10201 XDelay(display,(
size_t) (1000*StringToLong(seconds)));
10203 magick_info=GetMagickInfo(image_info->magick,exception);
10204 if ((magick_info != (
const MagickInfo *) NULL) &&
10205 (magick_info->raw != MagickFalse))
10208 geometry[MaxTextExtent];
10213 (void) CopyMagickString(geometry,
"512x512",MaxTextExtent);
10214 if (image_info->size != (
char *) NULL)
10215 (
void) CopyMagickString(geometry,image_info->size,MaxTextExtent);
10216 (void) XDialogWidget(display,windows,
"Load",
"Enter the image geometry:",
10218 (void) CloneString(&image_info->size,geometry);
10223 XSetCursorState(display,windows,MagickTrue);
10224 XCheckRefreshWindows(display,windows);
10225 (void) CopyMagickString(image_info->filename,filename,MaxTextExtent);
10226 nexus=ReadImage(image_info,exception);
10227 CatchException(exception);
10228 XSetCursorState(display,windows,MagickFalse);
10229 if (nexus != (
Image *) NULL)
10230 XClientMessage(display,windows->image.id,windows->im_protocols,
10231 windows->im_next_image,CurrentTime);
10241 text=FileToString(filename,~0UL,exception);
10242 if (text == (
char *) NULL)
10243 return((
Image *) NULL);
10244 textlist=StringToList(text);
10245 if (textlist != (
char **) NULL)
10248 title[MaxTextExtent];
10253 (void) FormatLocaleString(title,MaxTextExtent,
10254 "Unknown format: %s",filename);
10255 XTextViewWidget(display,resource_info,windows,MagickTrue,title,
10256 (
const char **) textlist);
10257 for (i=0; textlist[i] != (
char *) NULL; i++)
10258 textlist[i]=DestroyString(textlist[i]);
10259 textlist=(
char **) RelinquishMagickMemory(textlist);
10261 text=DestroyString(text);
10263 exception=DestroyExceptionInfo(exception);
10264 image_info=DestroyImageInfo(image_info);
10296 static void XPanImage(Display *display,XWindows *windows,XEvent *event)
10299 text[MaxTextExtent];
10317 if ((windows->image.ximage->width > (
int) windows->image.width) &&
10318 (windows->image.ximage->height > (
int) windows->image.height))
10319 cursor=XCreateFontCursor(display,XC_fleur);
10321 if (windows->image.ximage->width > (
int) windows->image.width)
10322 cursor=XCreateFontCursor(display,XC_sb_h_double_arrow);
10324 if (windows->image.ximage->height > (
int) windows->image.height)
10325 cursor=XCreateFontCursor(display,XC_sb_v_double_arrow);
10327 cursor=XCreateFontCursor(display,XC_arrow);
10328 (void) XCheckDefineCursor(display,windows->pan.id,cursor);
10332 x_factor=(MagickRealType) windows->image.ximage->width/windows->pan.width;
10333 y_factor=(MagickRealType) windows->image.ximage->height/windows->pan.height;
10334 pan_info.width=windows->pan.width*windows->image.width/
10335 windows->image.ximage->width;
10336 pan_info.height=windows->pan.height*windows->image.height/
10337 windows->image.ximage->height;
10340 state=UpdateConfigurationState;
10343 switch (event->type)
10350 pan_info.x=(ssize_t) event->xbutton.x;
10351 pan_info.y=(ssize_t)
event->xbutton.y;
10352 state|=UpdateConfigurationState;
10355 case ButtonRelease:
10360 pan_info.x=(ssize_t) event->xbutton.x;
10361 pan_info.y=(ssize_t)
event->xbutton.y;
10362 state|=UpdateConfigurationState | ExitState;
10367 pan_info.x=(ssize_t) event->xmotion.x;
10368 pan_info.y=(ssize_t)
event->xmotion.y;
10369 state|=UpdateConfigurationState;
10374 if ((state & UpdateConfigurationState) != 0)
10379 if (pan_info.x < (ssize_t) (pan_info.width/2))
10382 pan_info.x=(ssize_t) (x_factor*(pan_info.x-(pan_info.width/2)));
10383 if (pan_info.x < 0)
10386 if ((
int) (pan_info.x+windows->image.width) >
10387 windows->image.ximage->width)
10388 pan_info.x=(ssize_t)
10389 (windows->image.ximage->width-windows->image.width);
10390 if (pan_info.y < (ssize_t) (pan_info.height/2))
10393 pan_info.y=(ssize_t) (y_factor*(pan_info.y-(pan_info.height/2)));
10394 if (pan_info.y < 0)
10397 if ((
int) (pan_info.y+windows->image.height) >
10398 windows->image.ximage->height)
10399 pan_info.y=(ssize_t)
10400 (windows->image.ximage->height-windows->image.height);
10401 if ((windows->image.x != (
int) pan_info.x) ||
10402 (windows->image.y != (
int) pan_info.y))
10407 windows->image.x=(int) pan_info.x;
10408 windows->image.y=(
int) pan_info.y;
10409 (void) FormatLocaleString(text,MaxTextExtent,
" %ux%u%+d%+d ",
10410 windows->image.width,windows->image.height,windows->image.x,
10412 XInfoWidget(display,windows,text);
10416 XDrawPanRectangle(display,windows);
10417 XRefreshWindow(display,&windows->image,(XEvent *) NULL);
10419 state&=(~UpdateConfigurationState);
10424 if ((state & ExitState) == 0)
10425 XScreenEvent(display,windows,event);
10426 }
while ((state & ExitState) == 0);
10430 (void) XCheckDefineCursor(display,windows->pan.id,windows->pan.cursor);
10431 (void) XFreeCursor(display,cursor);
10432 (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
10466 static MagickBooleanType XPasteImage(Display *display,
10467 XResourceInfo *resource_info,XWindows *windows,
Image *image)
10470 *
const PasteMenu[] =
10478 static const ModeType
10481 PasteOperatorsCommand,
10483 PasteDismissCommand
10486 static CompositeOperator
10487 compose = CopyCompositeOp;
10490 text[MaxTextExtent];
10524 if (resource_info->copy_image == (
Image *) NULL)
10525 return(MagickFalse);
10526 paste_image=CloneImage(resource_info->copy_image,0,0,MagickTrue,
10527 &image->exception);
10528 if (paste_image == (
Image *) NULL)
10529 return(MagickFalse);
10533 (void) CloneString(&windows->command.name,
"Paste");
10534 windows->command.data=1;
10535 (void) XCommandWidget(display,windows,PasteMenu,(XEvent *) NULL);
10536 (void) XMapRaised(display,windows->command.id);
10537 XClientMessage(display,windows->image.id,windows->im_protocols,
10538 windows->im_update_widget,CurrentTime);
10542 XSetCursorState(display,windows,MagickFalse);
10543 XQueryPosition(display,windows->image.id,&x,&y);
10544 (void) XSelectInput(display,windows->image.id,
10545 windows->image.attributes.event_mask | PointerMotionMask);
10546 paste_info.x=(ssize_t) windows->image.x+x;
10547 paste_info.y=(ssize_t) windows->image.y+y;
10548 paste_info.width=0;
10549 paste_info.height=0;
10550 cursor=XCreateFontCursor(display,XC_ul_angle);
10551 (void) XSetFunction(display,windows->image.highlight_context,GXinvert);
10552 state=DefaultState;
10555 if (windows->info.mapped != MagickFalse)
10560 (void) FormatLocaleString(text,MaxTextExtent,
" %+ld%+ld ",
10561 (
long) paste_info.x,(long) paste_info.y);
10562 XInfoWidget(display,windows,text);
10564 highlight_info=paste_info;
10565 highlight_info.x=paste_info.x-windows->image.x;
10566 highlight_info.y=paste_info.y-windows->image.y;
10567 XHighlightRectangle(display,windows->image.id,
10568 windows->image.highlight_context,&highlight_info);
10572 XScreenEvent(display,windows,&event);
10573 XHighlightRectangle(display,windows->image.id,
10574 windows->image.highlight_context,&highlight_info);
10575 if (event.xany.window == windows->command.id)
10580 id=XCommandWidget(display,windows,PasteMenu,&event);
10583 switch (PasteCommands[
id])
10585 case PasteOperatorsCommand:
10588 command[MaxTextExtent],
10594 operators=GetCommandOptions(MagickComposeOptions);
10595 if (operators == (
char **) NULL)
10597 entry=XMenuWidget(display,windows,PasteMenu[
id],
10598 (
const char **) operators,command);
10600 compose=(CompositeOperator) ParseCommandOption(
10601 MagickComposeOptions,MagickFalse,operators[entry]);
10602 operators=DestroyStringList(operators);
10605 case PasteHelpCommand:
10607 XTextViewHelp(display,resource_info,windows,MagickFalse,
10608 "Help Viewer - Image Composite",ImagePasteHelp);
10611 case PasteDismissCommand:
10616 state|=EscapeState;
10625 switch (event.type)
10629 if (resource_info->debug != MagickFalse)
10630 (void) LogMagickEvent(X11Event,GetMagickModule(),
10631 "Button Press: 0x%lx %u +%d+%d",
event.xbutton.window,
10632 event.xbutton.button,
event.xbutton.x,
event.xbutton.y);
10633 if (event.xbutton.button != Button1)
10635 if (event.xbutton.window != windows->image.id)
10640 width=(
unsigned int) image->columns;
10641 height=(
unsigned int) image->rows;
10644 if (windows->image.crop_geometry != (
char *) NULL)
10645 (
void) XParseGeometry(windows->image.crop_geometry,&x,&y,
10647 scale_factor=(MagickRealType) windows->image.ximage->width/width;
10648 paste_info.width=(
unsigned int) (scale_factor*paste_image->columns+0.5);
10649 scale_factor=(MagickRealType) windows->image.ximage->height/height;
10650 paste_info.height=(
unsigned int) (scale_factor*paste_image->rows+0.5);
10651 (void) XCheckDefineCursor(display,windows->image.id,cursor);
10652 paste_info.x=(ssize_t) windows->image.x+event.xbutton.x;
10653 paste_info.y=(ssize_t) windows->image.y+
event.xbutton.y;
10656 case ButtonRelease:
10658 if (resource_info->debug != MagickFalse)
10659 (void) LogMagickEvent(X11Event,GetMagickModule(),
10660 "Button Release: 0x%lx %u +%d+%d",
event.xbutton.window,
10661 event.xbutton.button,
event.xbutton.x,
event.xbutton.y);
10662 if (event.xbutton.button != Button1)
10664 if (event.xbutton.window != windows->image.id)
10666 if ((paste_info.width != 0) && (paste_info.height != 0))
10671 paste_info.x=(ssize_t) windows->image.x+event.xbutton.x;
10672 paste_info.y=(ssize_t) windows->image.y+
event.xbutton.y;
10682 command[MaxTextExtent];
10690 if (event.xkey.window != windows->image.id)
10695 length=XLookupString((XKeyEvent *) &event.xkey,command,(
int)
10696 sizeof(command),&key_symbol,(XComposeStatus *) NULL);
10697 *(command+length)=
'\0';
10698 if (resource_info->debug != MagickFalse)
10699 (void) LogMagickEvent(X11Event,GetMagickModule(),
10700 "Key press: 0x%lx (%s)",(long) key_symbol,command);
10701 switch ((
int) key_symbol)
10709 paste_image=DestroyImage(paste_image);
10710 state|=EscapeState;
10717 (void) XSetFunction(display,windows->image.highlight_context,
10719 XTextViewHelp(display,resource_info,windows,MagickFalse,
10720 "Help Viewer - Image Composite",ImagePasteHelp);
10721 (void) XSetFunction(display,windows->image.highlight_context,
10727 (void) XBell(display,0);
10740 if (windows->info.mapped != MagickFalse)
10742 if ((x < (
int) (windows->info.x+windows->info.width)) &&
10743 (y < (int) (windows->info.y+windows->info.height)))
10744 (void) XWithdrawWindow(display,windows->info.id,
10745 windows->info.screen);
10748 if ((x > (
int) (windows->info.x+windows->info.width)) ||
10749 (y > (int) (windows->info.y+windows->info.height)))
10750 (void) XMapWindow(display,windows->info.id);
10751 paste_info.x=(ssize_t) windows->image.x+x;
10752 paste_info.y=(ssize_t) windows->image.y+y;
10757 if (resource_info->debug != MagickFalse)
10758 (void) LogMagickEvent(X11Event,GetMagickModule(),
"Event type: %d",
10763 }
while ((state & ExitState) == 0);
10764 (void) XSelectInput(display,windows->image.id,
10765 windows->image.attributes.event_mask);
10766 (void) XSetFunction(display,windows->image.highlight_context,GXcopy);
10767 XSetCursorState(display,windows,MagickFalse);
10768 (void) XFreeCursor(display,cursor);
10769 if ((state & EscapeState) != 0)
10770 return(MagickTrue);
10774 XSetCursorState(display,windows,MagickTrue);
10775 XCheckRefreshWindows(display,windows);
10776 width=(
unsigned int) image->columns;
10777 height=(
unsigned int) image->rows;
10780 if (windows->image.crop_geometry != (
char *) NULL)
10781 (
void) XParseGeometry(windows->image.crop_geometry,&x,&y,&width,&height);
10782 scale_factor=(MagickRealType) width/windows->image.ximage->width;
10784 paste_info.x=(ssize_t) (scale_factor*paste_info.x+0.5);
10785 paste_info.width=(
unsigned int) (scale_factor*paste_info.width+0.5);
10786 scale_factor=(MagickRealType) height/windows->image.ximage->height;
10788 paste_info.y=(ssize_t) (scale_factor*paste_info.y*scale_factor+0.5);
10789 paste_info.height=(
unsigned int) (scale_factor*paste_info.height+0.5);
10793 (void) CompositeImage(image,compose,paste_image,paste_info.x,paste_info.y);
10794 paste_image=DestroyImage(paste_image);
10795 XSetCursorState(display,windows,MagickFalse);
10799 XConfigureImageColormap(display,resource_info,windows,image);
10800 (void) XConfigureImage(display,resource_info,windows,image);
10801 return(MagickTrue);
10834 static MagickBooleanType XPrintImage(Display *display,
10835 XResourceInfo *resource_info,XWindows *windows,
Image *image)
10838 filename[MaxTextExtent],
10839 geometry[MaxTextExtent];
10842 *
const PageSizes[] =
10873 image_info=CloneImageInfo(resource_info->image_info);
10874 (void) FormatLocaleString(geometry,MaxTextExtent,
"Letter");
10875 if (image_info->page != (
char *) NULL)
10876 (
void) CopyMagickString(geometry,image_info->page,MaxTextExtent);
10877 XListBrowserWidget(display,windows,&windows->widget,PageSizes,
"Select",
10878 "Select Postscript Page Geometry:",geometry);
10879 if (*geometry ==
'\0')
10880 return(MagickTrue);
10881 image_info->page=GetPageGeometry(geometry);
10885 XSetCursorState(display,windows,MagickTrue);
10886 XCheckRefreshWindows(display,windows);
10887 print_image=CloneImage(image,0,0,MagickTrue,&image->exception);
10888 if (print_image == (
Image *) NULL)
10889 return(MagickFalse);
10890 (void) FormatLocaleString(geometry,MaxTextExtent,
"%dx%d!",
10891 windows->image.ximage->width,windows->image.ximage->height);
10892 (void) TransformImage(&print_image,windows->image.crop_geometry,geometry);
10896 (void) AcquireUniqueFilename(filename);
10897 (void) FormatLocaleString(print_image->filename,MaxTextExtent,
"print:%s",
10899 status=WriteImage(image_info,print_image);
10900 (void) RelinquishUniqueFileResource(filename);
10901 print_image=DestroyImage(print_image);
10902 image_info=DestroyImageInfo(image_info);
10903 XSetCursorState(display,windows,MagickFalse);
10904 return(status != 0 ? MagickTrue : MagickFalse);
10937 static MagickBooleanType XROIImage(Display *display,
10938 XResourceInfo *resource_info,XWindows *windows,
Image **image)
10940 #define ApplyMenus 7
10949 *
const ApplyMenu[] =
10962 *
const FileMenu[] =
10968 *
const EditMenu[] =
10974 *
const TransformMenu[] =
10982 *
const EnhanceMenu[] =
10990 "Contrast Stretch...",
10991 "Sigmoidal Contrast...",
11000 *
const EffectsMenu[] =
11025 "Charcoal Draw...",
11028 *
const MiscellanyMenu[] =
11039 *
const *Menus[ApplyMenus] =
11050 static const CommandType
11073 TransformCommands[] =
11077 RotateRightCommand,
11080 EnhanceCommands[] =
11088 ContrastStretchCommand,
11089 SigmoidalContrastCommand,
11097 EffectsCommands[] =
11101 ReduceNoiseCommand,
11120 CharcoalDrawCommand
11122 MiscellanyCommands[] =
11126 ShowPreviewCommand,
11127 ShowHistogramCommand,
11136 static const CommandType
11137 *Commands[ApplyMenus] =
11149 command[MaxTextExtent],
11150 text[MaxTextExtent];
11170 MagickProgressMonitor
11191 (void) CloneString(&windows->command.name,
"ROI");
11192 windows->command.data=0;
11193 (void) XCommandWidget(display,windows,ROIMenu,(XEvent *) NULL);
11194 (void) XMapRaised(display,windows->command.id);
11195 XClientMessage(display,windows->image.id,windows->im_protocols,
11196 windows->im_update_widget,CurrentTime);
11200 XQueryPosition(display,windows->image.id,&x,&y);
11201 (void) XSelectInput(display,windows->image.id,
11202 windows->image.attributes.event_mask | PointerMotionMask);
11204 crop_info.height=0;
11207 roi_info.x=(ssize_t) windows->image.x+x;
11208 roi_info.y=(ssize_t) windows->image.y+y;
11211 cursor=XCreateFontCursor(display,XC_fleur);
11212 state=DefaultState;
11215 if (windows->info.mapped != MagickFalse)
11220 (void) FormatLocaleString(text,MaxTextExtent,
" %+ld%+ld ",
11221 (
long) roi_info.x,(long) roi_info.y);
11222 XInfoWidget(display,windows,text);
11227 XScreenEvent(display,windows,&event);
11228 if (event.xany.window == windows->command.id)
11233 id=XCommandWidget(display,windows,ROIMenu,&event);
11236 switch (ROICommands[
id])
11238 case ROIHelpCommand:
11240 XTextViewHelp(display,resource_info,windows,MagickFalse,
11241 "Help Viewer - Region of Interest",ImageROIHelp);
11244 case ROIDismissCommand:
11249 state|=EscapeState;
11258 switch (event.type)
11262 if (event.xbutton.button != Button1)
11264 if (event.xbutton.window != windows->image.id)
11269 (void) XCheckDefineCursor(display,windows->image.id,cursor);
11270 roi_info.x=(ssize_t) windows->image.x+event.xbutton.x;
11271 roi_info.y=(ssize_t) windows->image.y+
event.xbutton.y;
11275 case ButtonRelease:
11284 if (event.xkey.window != windows->image.id)
11289 (void) XLookupString((XKeyEvent *) &
event.xkey,command,(int)
11290 sizeof(command),&key_symbol,(XComposeStatus *) NULL);
11291 switch ((
int) key_symbol)
11299 state|=EscapeState;
11306 XTextViewHelp(display,resource_info,windows,MagickFalse,
11307 "Help Viewer - Region of Interest",ImageROIHelp);
11312 (void) XBell(display,0);
11325 if (windows->info.mapped != MagickFalse)
11327 if ((x < (
int) (windows->info.x+windows->info.width)) &&
11328 (y < (int) (windows->info.y+windows->info.height)))
11329 (void) XWithdrawWindow(display,windows->info.id,
11330 windows->info.screen);
11333 if ((x > (
int) (windows->info.x+windows->info.width)) ||
11334 (y > (int) (windows->info.y+windows->info.height)))
11335 (void) XMapWindow(display,windows->info.id);
11336 roi_info.x=(ssize_t) windows->image.x+x;
11337 roi_info.y=(ssize_t) windows->image.y+y;
11343 }
while ((state & ExitState) == 0);
11344 (void) XSelectInput(display,windows->image.id,
11345 windows->image.attributes.event_mask);
11346 if ((state & EscapeState) != 0)
11351 (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
11352 (void) XFreeCursor(display,cursor);
11353 return(MagickTrue);
11355 (void) XSetFunction(display,windows->image.highlight_context,GXinvert);
11361 x=(int) roi_info.x;
11362 y=(
int) roi_info.y;
11365 state=DefaultState;
11368 highlight_info=roi_info;
11369 highlight_info.x=roi_info.x-windows->image.x;
11370 highlight_info.y=roi_info.y-windows->image.y;
11371 if ((highlight_info.width > 3) && (highlight_info.height > 3))
11376 if (windows->info.mapped == MagickFalse)
11377 (void) XMapWindow(display,windows->info.id);
11378 (void) FormatLocaleString(text,MaxTextExtent,
11379 " %.20gx%.20g%+.20g%+.20g",(
double) roi_info.width,(double)
11380 roi_info.height,(
double) roi_info.x,(double) roi_info.y);
11381 XInfoWidget(display,windows,text);
11382 XHighlightRectangle(display,windows->image.id,
11383 windows->image.highlight_context,&highlight_info);
11386 if (windows->info.mapped != MagickFalse)
11387 (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
11391 XScreenEvent(display,windows,&event);
11392 if ((highlight_info.width > 3) && (highlight_info.height > 3))
11393 XHighlightRectangle(display,windows->image.id,
11394 windows->image.highlight_context,&highlight_info);
11395 switch (event.type)
11399 roi_info.x=(ssize_t) windows->image.x+event.xbutton.x;
11400 roi_info.y=(ssize_t) windows->image.y+
event.xbutton.y;
11403 case ButtonRelease:
11408 roi_info.x=(ssize_t) windows->image.x+event.xbutton.x;
11409 roi_info.y=(ssize_t) windows->image.y+
event.xbutton.y;
11410 XSetCursorState(display,windows,MagickFalse);
11412 if (LocaleCompare(windows->command.name,
"Apply") == 0)
11414 (void) CloneString(&windows->command.name,
"Apply");
11415 windows->command.data=ApplyMenus;
11416 (void) XCommandWidget(display,windows,ApplyMenu,(XEvent *) NULL);
11423 roi_info.x=(ssize_t) windows->image.x+event.xmotion.x;
11424 roi_info.y=(ssize_t) windows->image.y+
event.xmotion.y;
11429 if ((((
int) roi_info.x != x) && ((
int) roi_info.y != y)) ||
11430 ((state & ExitState) != 0))
11435 if (roi_info.x < 0)
11438 if (roi_info.x > (ssize_t) windows->image.ximage->width)
11439 roi_info.x=(ssize_t) windows->image.ximage->width;
11440 if ((
int) roi_info.x < x)
11441 roi_info.width=(
unsigned int) (x-roi_info.x);
11444 roi_info.width=(
unsigned int) (roi_info.x-x);
11445 roi_info.x=(ssize_t) x;
11447 if (roi_info.y < 0)
11450 if (roi_info.y > (ssize_t) windows->image.ximage->height)
11451 roi_info.y=(ssize_t) windows->image.ximage->height;
11452 if ((
int) roi_info.y < y)
11453 roi_info.height=(
unsigned int) (y-roi_info.y);
11456 roi_info.height=(
unsigned int) (roi_info.y-y);
11457 roi_info.y=(ssize_t) y;
11460 }
while ((state & ExitState) == 0);
11464 state=DefaultState;
11465 command_type=NullCommand;
11466 (void) XMapWindow(display,windows->info.id);
11469 if (windows->info.mapped != MagickFalse)
11474 (void) FormatLocaleString(text,MaxTextExtent,
11475 " %.20gx%.20g%+.20g%+.20g",(
double) roi_info.width,(double)
11476 roi_info.height,(
double) roi_info.x,(double) roi_info.y);
11477 XInfoWidget(display,windows,text);
11479 highlight_info=roi_info;
11480 highlight_info.x=roi_info.x-windows->image.x;
11481 highlight_info.y=roi_info.y-windows->image.y;
11482 if ((highlight_info.width <= 3) || (highlight_info.height <= 3))
11484 state|=EscapeState;
11488 if ((state & UpdateRegionState) != 0)
11490 (void) XSetFunction(display,windows->image.highlight_context,GXcopy);
11491 switch (command_type)
11496 (void) XMagickCommand(display,resource_info,windows,command_type,
11505 progress_monitor=SetImageProgressMonitor(*image,
11506 (MagickProgressMonitor) NULL,(*image)->client_data);
11507 crop_info=roi_info;
11508 width=(
unsigned int) (*image)->columns;
11509 height=(
unsigned int) (*image)->rows;
11512 if (windows->image.crop_geometry != (
char *) NULL)
11513 (
void) XParseGeometry(windows->image.crop_geometry,&x,&y,
11515 scale_factor=(MagickRealType) width/windows->image.ximage->width;
11517 crop_info.x=(ssize_t) (scale_factor*crop_info.x+0.5);
11518 crop_info.width=(
unsigned int) (scale_factor*crop_info.width+0.5);
11519 scale_factor=(MagickRealType)
11520 height/windows->image.ximage->height;
11522 crop_info.y=(ssize_t) (scale_factor*crop_info.y+0.5);
11523 crop_info.height=(
unsigned int)
11524 (scale_factor*crop_info.height+0.5);
11525 roi_image=CropImage(*image,&crop_info,&(*image)->exception);
11526 (void) SetImageProgressMonitor(*image,progress_monitor,
11527 (*image)->client_data);
11528 if (roi_image == (
Image *) NULL)
11533 windows->image.orphan=MagickTrue;
11534 (void) XMagickCommand(display,resource_info,windows,command_type,
11536 progress_monitor=SetImageProgressMonitor(*image,
11537 (MagickProgressMonitor) NULL,(*image)->client_data);
11538 (void) XMagickCommand(display,resource_info,windows,
11539 SaveToUndoBufferCommand,image);
11540 windows->image.orphan=MagickFalse;
11541 (void) CompositeImage(*image,CopyCompositeOp,roi_image,
11542 crop_info.x,crop_info.y);
11543 roi_image=DestroyImage(roi_image);
11544 (void) SetImageProgressMonitor(*image,progress_monitor,
11545 (*image)->client_data);
11549 if (command_type != InfoCommand)
11551 XConfigureImageColormap(display,resource_info,windows,*image);
11552 (void) XConfigureImage(display,resource_info,windows,*image);
11554 XCheckRefreshWindows(display,windows);
11555 XInfoWidget(display,windows,text);
11556 (void) XSetFunction(display,windows->image.highlight_context,
11558 state&=(~UpdateRegionState);
11560 XHighlightRectangle(display,windows->image.id,
11561 windows->image.highlight_context,&highlight_info);
11562 XScreenEvent(display,windows,&event);
11563 if (event.xany.window == windows->command.id)
11568 (void) XSetFunction(display,windows->image.highlight_context,GXcopy);
11569 command_type=NullCommand;
11570 id=XCommandWidget(display,windows,ApplyMenu,&event);
11573 (void) CopyMagickString(command,ApplyMenu[
id],MaxTextExtent);
11574 command_type=ApplyCommands[id];
11575 if (
id < ApplyMenus)
11580 entry=XMenuWidget(display,windows,ApplyMenu[
id],
11581 (
const char **) Menus[
id],command);
11584 (void) CopyMagickString(command,Menus[
id][entry],
11586 command_type=Commands[id][entry];
11590 (void) XSetFunction(display,windows->image.highlight_context,
11592 XHighlightRectangle(display,windows->image.id,
11593 windows->image.highlight_context,&highlight_info);
11594 if (command_type == HelpCommand)
11596 (void) XSetFunction(display,windows->image.highlight_context,
11598 XTextViewHelp(display,resource_info,windows,MagickFalse,
11599 "Help Viewer - Region of Interest",ImageROIHelp);
11600 (void) XSetFunction(display,windows->image.highlight_context,
11604 if (command_type == QuitCommand)
11609 state|=EscapeState;
11613 if (command_type != NullCommand)
11614 state|=UpdateRegionState;
11617 XHighlightRectangle(display,windows->image.id,
11618 windows->image.highlight_context,&highlight_info);
11619 switch (event.type)
11623 x=windows->image.x;
11624 y=windows->image.y;
11625 if (event.xbutton.button != Button1)
11627 if (event.xbutton.window != windows->image.id)
11629 x=windows->image.x+
event.xbutton.x;
11630 y=windows->image.y+
event.xbutton.y;
11631 if ((x < (
int) (roi_info.x+RoiDelta)) &&
11632 (x > (
int) (roi_info.x-RoiDelta)) &&
11633 (y < (
int) (roi_info.y+RoiDelta)) &&
11634 (y > (
int) (roi_info.y-RoiDelta)))
11636 roi_info.x=(ssize_t) (roi_info.x+roi_info.width);
11637 roi_info.y=(ssize_t) (roi_info.y+roi_info.height);
11638 state|=UpdateConfigurationState;
11641 if ((x < (
int) (roi_info.x+RoiDelta)) &&
11642 (x > (int) (roi_info.x-RoiDelta)) &&
11643 (y < (
int) (roi_info.y+roi_info.height+RoiDelta)) &&
11644 (y > (int) (roi_info.y+roi_info.height-RoiDelta)))
11646 roi_info.x=(ssize_t) (roi_info.x+roi_info.width);
11647 state|=UpdateConfigurationState;
11650 if ((x < (
int) (roi_info.x+roi_info.width+RoiDelta)) &&
11651 (x > (int) (roi_info.x+roi_info.width-RoiDelta)) &&
11652 (y < (
int) (roi_info.y+RoiDelta)) &&
11653 (y > (int) (roi_info.y-RoiDelta)))
11655 roi_info.y=(ssize_t) (roi_info.y+roi_info.height);
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+roi_info.height+RoiDelta)) &&
11662 (y > (int) (roi_info.y+roi_info.height-RoiDelta)))
11664 state|=UpdateConfigurationState;
11668 case ButtonRelease:
11670 if (event.xbutton.window == windows->pan.id)
11671 if ((highlight_info.x != crop_info.x-windows->image.x) ||
11672 (highlight_info.y != crop_info.y-windows->image.y))
11673 XHighlightRectangle(display,windows->image.id,
11674 windows->image.highlight_context,&highlight_info);
11675 (void) XSetSelectionOwner(display,XA_PRIMARY,windows->image.id,
11676 event.xbutton.time);
11681 if (event.xexpose.window == windows->image.id)
11682 if (event.xexpose.count == 0)
11684 event.xexpose.x=(int) highlight_info.x;
11685 event.xexpose.y=(
int) highlight_info.y;
11686 event.xexpose.width=(int) highlight_info.width;
11687 event.xexpose.height=(
int) highlight_info.height;
11688 XRefreshWindow(display,&windows->image,&event);
11690 if (event.xexpose.window == windows->info.id)
11691 if (event.xexpose.count == 0)
11692 XInfoWidget(display,windows,text);
11700 if (event.xkey.window != windows->image.id)
11705 (void) XLookupString((XKeyEvent *) &
event.xkey,command,(int)
11706 sizeof(command),&key_symbol,(XComposeStatus *) NULL);
11707 switch ((
int) key_symbol)
11714 state|=EscapeState;
11723 roi_info.x=(ssize_t) (windows->image.width/2L-roi_info.width/2L);
11724 roi_info.y=(ssize_t) (windows->image.height/2L-
11725 roi_info.height/2L);
11757 (void) XSetFunction(display,windows->image.highlight_context,
11759 XTextViewHelp(display,resource_info,windows,MagickFalse,
11760 "Help Viewer - Region of Interest",ImageROIHelp);
11761 (void) XSetFunction(display,windows->image.highlight_context,
11767 command_type=XImageWindowCommand(display,resource_info,windows,
11768 event.xkey.state,key_symbol,image);
11769 if (command_type != NullCommand)
11770 state|=UpdateRegionState;
11774 (void) XSetSelectionOwner(display,XA_PRIMARY,windows->image.id,
11782 if (event.xbutton.window != windows->image.id)
11789 if (windows->info.mapped != MagickFalse)
11791 if ((x < (
int) (windows->info.x+windows->info.width)) &&
11792 (y < (int) (windows->info.y+windows->info.height)))
11793 (void) XWithdrawWindow(display,windows->info.id,
11794 windows->info.screen);
11797 if ((x > (
int) (windows->info.x+windows->info.width)) ||
11798 (y > (int) (windows->info.y+windows->info.height)))
11799 (void) XMapWindow(display,windows->info.id);
11800 roi_info.x=(ssize_t) windows->image.x+event.xmotion.x;
11801 roi_info.y=(ssize_t) windows->image.y+
event.xmotion.y;
11804 case SelectionRequest:
11809 XSelectionRequestEvent
11815 (void) FormatLocaleString(text,MaxTextExtent,
11816 "%.20gx%.20g%+.20g%+.20g",(
double) roi_info.width,(double)
11817 roi_info.height,(
double) roi_info.x,(double) roi_info.y);
11818 request=(&(
event.xselectionrequest));
11819 (void) XChangeProperty(request->display,request->requestor,
11820 request->property,request->target,8,PropModeReplace,
11821 (
unsigned char *) text,(int) strlen(text));
11822 notify.type=SelectionNotify;
11823 notify.display=request->display;
11824 notify.requestor=request->requestor;
11825 notify.selection=request->selection;
11826 notify.target=request->target;
11827 notify.time=request->time;
11828 if (request->property == None)
11829 notify.property=request->target;
11831 notify.property=request->property;
11832 (void) XSendEvent(request->display,request->requestor,False,0,
11833 (XEvent *) ¬ify);
11838 if ((state & UpdateConfigurationState) != 0)
11840 (void) XPutBackEvent(display,&event);
11841 (void) XCheckDefineCursor(display,windows->image.id,cursor);
11844 }
while ((state & ExitState) == 0);
11845 }
while ((state & ExitState) == 0);
11846 (void) XSetFunction(display,windows->image.highlight_context,GXcopy);
11847 XSetCursorState(display,windows,MagickFalse);
11848 if ((state & EscapeState) != 0)
11849 return(MagickTrue);
11850 return(MagickTrue);
11887 static MagickBooleanType XRotateImage(Display *display,
11888 XResourceInfo *resource_info,XWindows *windows,
double degrees,
Image **image)
11891 *
const RotateMenu[] =
11901 direction = HorizontalRotateCommand;
11903 static const ModeType
11904 DirectionCommands[] =
11906 HorizontalRotateCommand,
11907 VerticalRotateCommand
11911 RotateColorCommand,
11912 RotateDirectionCommand,
11914 RotateDismissCommand
11917 static unsigned int
11921 command[MaxTextExtent],
11922 text[MaxTextExtent];
11933 normalized_degrees;
11943 if (degrees == 0.0)
11960 (void) CloneString(&windows->command.name,
"Rotate");
11961 windows->command.data=2;
11962 (void) XCommandWidget(display,windows,RotateMenu,(XEvent *) NULL);
11963 (void) XMapRaised(display,windows->command.id);
11964 XClientMessage(display,windows->image.id,windows->im_protocols,
11965 windows->im_update_widget,CurrentTime);
11969 (void) XSetFunction(display,windows->image.highlight_context,GXinvert);
11970 XQueryPosition(display,windows->image.id,&x,&y);
11975 state=DefaultState;
11978 XHighlightLine(display,windows->image.id,
11979 windows->image.highlight_context,&rotate_info);
11983 XScreenEvent(display,windows,&event);
11984 XHighlightLine(display,windows->image.id,
11985 windows->image.highlight_context,&rotate_info);
11986 if (event.xany.window == windows->command.id)
11991 id=XCommandWidget(display,windows,RotateMenu,&event);
11994 (void) XSetFunction(display,windows->image.highlight_context,
11996 switch (RotateCommands[
id])
11998 case RotateColorCommand:
12001 *ColorMenu[MaxNumberPens];
12012 for (i=0; i < (int) (MaxNumberPens-2); i++)
12013 ColorMenu[i]=resource_info->pen_colors[i];
12014 ColorMenu[MaxNumberPens-2]=
"Browser...";
12015 ColorMenu[MaxNumberPens-1]=(
const char *) NULL;
12019 pen_number=XMenuWidget(display,windows,RotateMenu[
id],
12020 (
const char **) ColorMenu,command);
12021 if (pen_number < 0)
12023 if (pen_number == (MaxNumberPens-2))
12026 color_name[MaxTextExtent] =
"gray";
12031 resource_info->pen_colors[pen_number]=color_name;
12032 XColorBrowserWidget(display,windows,
"Select",color_name);
12033 if (*color_name ==
'\0')
12039 (void) XParseColor(display,windows->map_info->colormap,
12040 resource_info->pen_colors[pen_number],&color);
12041 XBestPixel(display,windows->map_info->colormap,(XColor *) NULL,
12042 (
unsigned int) MaxColors,&color);
12043 windows->pixel_info->pen_colors[pen_number]=color;
12044 pen_id=(
unsigned int) pen_number;
12047 case RotateDirectionCommand:
12050 *
const Directions[] =
12060 id=XMenuWidget(display,windows,RotateMenu[
id],
12061 Directions,command);
12063 direction=DirectionCommands[id];
12066 case RotateHelpCommand:
12068 XTextViewHelp(display,resource_info,windows,MagickFalse,
12069 "Help Viewer - Image Rotation",ImageRotateHelp);
12072 case RotateDismissCommand:
12077 state|=EscapeState;
12084 (void) XSetFunction(display,windows->image.highlight_context,
12088 switch (event.type)
12092 if (event.xbutton.button != Button1)
12094 if (event.xbutton.window != windows->image.id)
12099 (void) XSetFunction(display,windows->image.highlight_context,
12101 rotate_info.x1=
event.xbutton.x;
12102 rotate_info.y1=
event.xbutton.y;
12106 case ButtonRelease:
12113 command[MaxTextExtent];
12118 if (event.xkey.window != windows->image.id)
12123 (void) XLookupString((XKeyEvent *) &
event.xkey,command,(int)
12124 sizeof(command),&key_symbol,(XComposeStatus *) NULL);
12125 switch ((
int) key_symbol)
12133 state|=EscapeState;
12140 (void) XSetFunction(display,windows->image.highlight_context,
12142 XTextViewHelp(display,resource_info,windows,MagickFalse,
12143 "Help Viewer - Image Rotation",ImageRotateHelp);
12144 (void) XSetFunction(display,windows->image.highlight_context,
12150 (void) XBell(display,0);
12158 rotate_info.x1=
event.xmotion.x;
12159 rotate_info.y1=
event.xmotion.y;
12162 rotate_info.x2=rotate_info.x1;
12163 rotate_info.y2=rotate_info.y1;
12164 if (direction == HorizontalRotateCommand)
12165 rotate_info.x2+=32;
12167 rotate_info.y2-=32;
12168 }
while ((state & ExitState) == 0);
12169 (void) XSetFunction(display,windows->image.highlight_context,GXcopy);
12170 (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
12171 if ((state & EscapeState) != 0)
12172 return(MagickTrue);
12177 (void) XSetFunction(display,windows->image.highlight_context,GXinvert);
12178 state=DefaultState;
12186 if (windows->info.mapped == MagickFalse)
12187 (void) XMapWindow(display,windows->info.id);
12188 (void) FormatLocaleString(text,MaxTextExtent,
" %g",
12189 direction == VerticalRotateCommand ? degrees-90.0 : degrees);
12190 XInfoWidget(display,windows,text);
12191 XHighlightLine(display,windows->image.id,
12192 windows->image.highlight_context,&rotate_info);
12195 if (windows->info.mapped != MagickFalse)
12196 (void) XWithdrawWindow(display,windows->info.id,
12197 windows->info.screen);
12201 XScreenEvent(display,windows,&event);
12203 XHighlightLine(display,windows->image.id,
12204 windows->image.highlight_context,&rotate_info);
12205 switch (event.type)
12209 case ButtonRelease:
12214 rotate_info.x2=
event.xbutton.x;
12215 rotate_info.y2=
event.xbutton.y;
12223 rotate_info.x2=
event.xmotion.x;
12224 rotate_info.y2=
event.xmotion.y;
12232 if (rotate_info.x2 < 0)
12235 if (rotate_info.x2 > (
int) windows->image.width)
12236 rotate_info.x2=(short) windows->image.width;
12237 if (rotate_info.y2 < 0)
12240 if (rotate_info.y2 > (
int) windows->image.height)
12241 rotate_info.y2=(
short) windows->image.height;
12246 distance=(
unsigned int)
12247 ((rotate_info.x2-rotate_info.x1+1)*(rotate_info.x2-rotate_info.x1+1))+
12248 ((rotate_info.y2-rotate_info.y1+1)*(rotate_info.y2-rotate_info.y1+1));
12250 degrees=RadiansToDegrees(-atan2((
double) (rotate_info.y2-
12251 rotate_info.y1),(
double) (rotate_info.x2-rotate_info.x1)));
12252 }
while ((state & ExitState) == 0);
12253 (void) XSetFunction(display,windows->image.highlight_context,GXcopy);
12254 (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
12256 return(MagickTrue);
12258 if (direction == VerticalRotateCommand)
12260 if (degrees == 0.0)
12261 return(MagickTrue);
12265 normalized_degrees=degrees;
12266 while (normalized_degrees < -45.0)
12267 normalized_degrees+=360.0;
12268 for (rotations=0; normalized_degrees > 45.0; rotations++)
12269 normalized_degrees-=90.0;
12270 if (normalized_degrees != 0.0)
12271 (void) XMagickCommand(display,resource_info,windows,ApplyCommand,image);
12272 XSetCursorState(display,windows,MagickTrue);
12273 XCheckRefreshWindows(display,windows);
12274 (*image)->background_color.red=ScaleShortToQuantum(
12275 windows->pixel_info->pen_colors[pen_id].red);
12276 (*image)->background_color.green=ScaleShortToQuantum(
12277 windows->pixel_info->pen_colors[pen_id].green);
12278 (*image)->background_color.blue=ScaleShortToQuantum(
12279 windows->pixel_info->pen_colors[pen_id].blue);
12280 rotate_image=RotateImage(*image,degrees,&(*image)->exception);
12281 XSetCursorState(display,windows,MagickFalse);
12282 if (rotate_image == (
Image *) NULL)
12283 return(MagickFalse);
12284 *image=DestroyImage(*image);
12285 *image=rotate_image;
12286 if (windows->image.crop_geometry != (
char *) NULL)
12291 width=(
unsigned int) (*image)->columns;
12292 height=(
unsigned int) (*image)->rows;
12293 (void) XParseGeometry(windows->image.crop_geometry,&x,&y,&width,&height);
12294 switch (rotations % 4)
12304 (void) FormatLocaleString(windows->image.crop_geometry,MaxTextExtent,
12305 "%ux%u%+d%+d",height,width,(
int) (*image)->columns-
12314 (void) FormatLocaleString(windows->image.crop_geometry,MaxTextExtent,
12315 "%ux%u%+d%+d",width,height,(
int) width-x,(int) height-y);
12323 (void) FormatLocaleString(windows->image.crop_geometry,MaxTextExtent,
12324 "%ux%u%+d%+d",height,width,y,(
int) (*image)->rows-(int) width-x);
12329 if (windows->image.orphan != MagickFalse)
12330 return(MagickTrue);
12331 if (normalized_degrees != 0.0)
12336 windows->image.window_changes.width=(int) (*image)->columns;
12337 windows->image.window_changes.height=(
int) (*image)->rows;
12338 if (windows->image.crop_geometry != (
char *) NULL)
12343 (void) XParseGeometry(windows->image.crop_geometry,&x,&y,
12345 windows->image.window_changes.width=(int) width;
12346 windows->image.window_changes.height=(int) height;
12348 XConfigureImageColormap(display,resource_info,windows,*image);
12351 if (((rotations % 4) == 1) || ((rotations % 4) == 3))
12353 windows->image.window_changes.width=windows->image.ximage->height;
12354 windows->image.window_changes.height=windows->image.ximage->width;
12359 (void) XConfigureImage(display,resource_info,windows,*image);
12360 return(MagickTrue);
12393 static MagickBooleanType XSaveImage(Display *display,
12394 XResourceInfo *resource_info,XWindows *windows,
Image *image)
12397 filename[MaxTextExtent],
12398 geometry[MaxTextExtent];
12412 if (resource_info->write_filename != (
char *) NULL)
12413 (void) CopyMagickString(filename,resource_info->write_filename,
12418 path[MaxTextExtent];
12423 GetPathComponent(image->filename,HeadPath,path);
12424 GetPathComponent(image->filename,TailPath,filename);
12427 status=chdir(path);
12429 (void) ThrowMagickException(&image->exception,GetMagickModule(),
12430 FileOpenError,
"UnableToOpenFile",
"%s",path);
12433 XFileBrowserWidget(display,windows,
"Save",filename);
12434 if (*filename ==
'\0')
12435 return(MagickTrue);
12436 if (IsPathAccessible(filename) != MagickFalse)
12444 status=XConfirmWidget(display,windows,
"Overwrite",filename);
12446 return(MagickTrue);
12448 image_info=CloneImageInfo(resource_info->image_info);
12449 (void) CopyMagickString(image_info->filename,filename,MaxTextExtent);
12450 (void) SetImageInfo(image_info,1,&image->exception);
12451 if ((LocaleCompare(image_info->magick,
"JPEG") == 0) ||
12452 (LocaleCompare(image_info->magick,
"JPG") == 0))
12455 quality[MaxTextExtent];
12463 (void) FormatLocaleString(quality,MaxTextExtent,
"%.20g",(
double)
12465 status=XDialogWidget(display,windows,
"Save",
"Enter JPEG quality:",
12467 if (*quality ==
'\0')
12468 return(MagickTrue);
12469 image->quality=StringToUnsignedLong(quality);
12470 image_info->interlace=status != 0 ? NoInterlace : PlaneInterlace;
12472 if ((LocaleCompare(image_info->magick,
"EPS") == 0) ||
12473 (LocaleCompare(image_info->magick,
"PDF") == 0) ||
12474 (LocaleCompare(image_info->magick,
"PS") == 0) ||
12475 (LocaleCompare(image_info->magick,
"PS2") == 0))
12478 geometry[MaxTextExtent];
12481 *
const PageSizes[] =
12503 (void) CopyMagickString(geometry,PSPageGeometry,MaxTextExtent);
12504 if (LocaleCompare(image_info->magick,
"PDF") == 0)
12505 (
void) CopyMagickString(geometry,PSPageGeometry,MaxTextExtent);
12506 if (image_info->page != (
char *) NULL)
12507 (void) CopyMagickString(geometry,image_info->page,MaxTextExtent);
12508 XListBrowserWidget(display,windows,&windows->widget,PageSizes,
"Select",
12509 "Select page geometry:",geometry);
12510 if (*geometry !=
'\0')
12511 image_info->page=GetPageGeometry(geometry);
12516 XSetCursorState(display,windows,MagickTrue);
12517 XCheckRefreshWindows(display,windows);
12518 save_image=CloneImage(image,0,0,MagickTrue,&image->exception);
12519 if (save_image == (
Image *) NULL)
12520 return(MagickFalse);
12521 (void) FormatLocaleString(geometry,MaxTextExtent,
"%dx%d!",
12522 windows->image.ximage->width,windows->image.ximage->height);
12523 (void) TransformImage(&save_image,windows->image.crop_geometry,geometry);
12527 (void) CopyMagickString(save_image->filename,filename,MaxTextExtent);
12528 status=WriteImage(image_info,save_image);
12529 if (status != MagickFalse)
12530 image->taint=MagickFalse;
12531 save_image=DestroyImage(save_image);
12532 image_info=DestroyImageInfo(image_info);
12533 XSetCursorState(display,windows,MagickFalse);
12534 return(status != 0 ? MagickTrue : MagickFalse);
12567 #if defined(__cplusplus) || defined(c_plusplus)
12571 static int XPredicate(Display *magick_unused(display),XEvent *event,
char *data)
12576 magick_unreferenced(display);
12578 windows=(XWindows *) data;
12579 if ((event->type == ClientMessage) &&
12580 (
event->xclient.window == windows->image.id))
12581 return(MagickFalse);
12582 return(MagickTrue);
12585 #if defined(__cplusplus) || defined(c_plusplus)
12589 static void XScreenEvent(Display *display,XWindows *windows,XEvent *event)
12595 (void) XIfEvent(display,event,XPredicate,(
char *) windows);
12596 if (event->xany.window == windows->command.id)
12598 switch (event->type)
12601 case ButtonRelease:
12603 if ((event->xbutton.button == Button3) &&
12604 (
event->xbutton.state & Mod1Mask))
12609 event->xbutton.button=Button2;
12610 event->xbutton.state&=(~Mod1Mask);
12612 if (event->xbutton.window == windows->backdrop.id)
12614 (void) XSetInputFocus(display,event->xbutton.window,RevertToParent,
12615 event->xbutton.time);
12618 if (event->xbutton.window == windows->pan.id)
12620 XPanImage(display,windows,event);
12623 if (event->xbutton.window == windows->image.id)
12624 if (event->xbutton.button == Button2)
12629 x=
event->xbutton.x;
12630 y=
event->xbutton.y;
12634 if (x >= (
int) windows->image.width)
12635 x=(int) (windows->image.width-1);
12636 windows->magnify.x=(int) windows->image.x+x;
12640 if (y >= (
int) windows->image.height)
12641 y=(
int) (windows->image.height-1);
12642 windows->magnify.y=windows->image.y+y;
12643 if (windows->magnify.mapped == MagickFalse)
12644 (void) XMapRaised(display,windows->magnify.id);
12645 XMakeMagnifyImage(display,windows);
12646 if (event->type == ButtonRelease)
12647 (void) XWithdrawWindow(display,windows->info.id,
12648 windows->info.screen);
12653 case ClientMessage:
12658 if (event->xclient.message_type != windows->wm_protocols)
12660 if (*event->xclient.data.l != (
long) windows->wm_delete_window)
12662 if (event->xclient.window == windows->magnify.id)
12664 (void) XWithdrawWindow(display,windows->magnify.id,
12665 windows->magnify.screen);
12670 case ConfigureNotify:
12672 if (event->xconfigure.window == windows->magnify.id)
12680 windows->magnify.width=(
unsigned int) event->xconfigure.width;
12681 windows->magnify.height=(
unsigned int)
event->xconfigure.height;
12682 if (windows->magnify.mapped == MagickFalse)
12685 while ((
int) magnify <=
event->xconfigure.width)
12687 while ((
int) magnify <=
event->xconfigure.height)
12690 if (((
int) magnify !=
event->xconfigure.width) ||
12691 ((
int) magnify !=
event->xconfigure.height))
12696 window_changes.width=(int) magnify;
12697 window_changes.height=(int) magnify;
12698 (void) XReconfigureWMWindow(display,windows->magnify.id,
12699 windows->magnify.screen,(
unsigned int) (CWWidth | CWHeight),
12703 XMakeMagnifyImage(display,windows);
12710 if (event->xexpose.window == windows->image.id)
12712 XRefreshWindow(display,&windows->image,event);
12715 if (event->xexpose.window == windows->pan.id)
12716 if (event->xexpose.count == 0)
12718 XDrawPanRectangle(display,windows);
12721 if (event->xexpose.window == windows->magnify.id)
12722 if (event->xexpose.count == 0)
12724 XMakeMagnifyImage(display,windows);
12732 command[MaxTextExtent];
12737 if (event->xkey.window != windows->magnify.id)
12742 (void) XLookupString((XKeyEvent *) &
event->xkey,command,(int)
12743 sizeof(command),&key_symbol,(XComposeStatus *) NULL);
12744 XMagnifyWindowCommand(display,windows,event->xkey.state,key_symbol);
12749 if (event->xmap.window == windows->magnify.id)
12751 windows->magnify.mapped=MagickTrue;
12752 (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
12755 if (event->xmap.window == windows->info.id)
12757 windows->info.mapped=MagickTrue;
12764 while (XCheckMaskEvent(display,ButtonMotionMask,event)) ;
12765 if (event->xmotion.window == windows->image.id)
12766 if (windows->magnify.mapped != MagickFalse)
12771 x=
event->xmotion.x;
12772 y=
event->xmotion.y;
12776 if (x >= (
int) windows->image.width)
12777 x=(
int) (windows->image.width-1);
12778 windows->magnify.x=(int) windows->image.x+x;
12782 if (y >= (
int) windows->image.height)
12783 y=(
int) (windows->image.height-1);
12784 windows->magnify.y=windows->image.y+y;
12785 XMakeMagnifyImage(display,windows);
12791 if (event->xunmap.window == windows->magnify.id)
12793 windows->magnify.mapped=MagickFalse;
12796 if (event->xunmap.window == windows->info.id)
12798 windows->info.mapped=MagickFalse;
12840 static void XSetCropGeometry(Display *display,XWindows *windows,
12844 text[MaxTextExtent];
12857 if (windows->info.mapped != MagickFalse)
12862 (void) FormatLocaleString(text,MaxTextExtent,
" %.20gx%.20g%+.20g%+.20g",
12863 (
double) crop_info->width,(double) crop_info->height,(
double)
12864 crop_info->x,(double) crop_info->y);
12865 XInfoWidget(display,windows,text);
12872 width=(
unsigned int) image->columns;
12873 height=(
unsigned int) image->rows;
12874 if (windows->image.crop_geometry != (
char *) NULL)
12875 (
void) XParseGeometry(windows->image.crop_geometry,&x,&y,&width,&height);
12877 windows->image.crop_geometry=AcquireString((
char *) NULL);
12881 scale_factor=(MagickRealType) width/windows->image.ximage->width;
12882 if (crop_info->x > 0)
12883 x+=(int) (scale_factor*crop_info->x+0.5);
12884 width=(
unsigned int) (scale_factor*crop_info->width+0.5);
12887 scale_factor=(MagickRealType) height/windows->image.ximage->height;
12888 if (crop_info->y > 0)
12889 y+=(int) (scale_factor*crop_info->y+0.5);
12890 height=(
unsigned int) (scale_factor*crop_info->height+0.5);
12893 (void) FormatLocaleString(windows->image.crop_geometry,MaxTextExtent,
12894 "%ux%u%+d%+d",width,height,x,y);
12934 static Image *XTileImage(Display *display,XResourceInfo *resource_info,
12935 XWindows *windows,
Image *image,XEvent *event)
12938 *
const VerbMenu[] =
12948 static const ModeType
12959 command[MaxTextExtent],
12960 filename[MaxTextExtent];
12991 width=(
unsigned int) image->columns;
12992 height=(
unsigned int) image->rows;
12993 if (windows->image.crop_geometry != (
char *) NULL)
12994 (
void) XParseGeometry(windows->image.crop_geometry,&x,&y,&width,&height);
12995 scale_factor=(MagickRealType) width/windows->image.ximage->width;
12996 event->xbutton.x+=windows->image.x;
12997 event->xbutton.x=(
int) (scale_factor*
event->xbutton.x+x+0.5);
12998 scale_factor=(MagickRealType) height/windows->image.ximage->height;
12999 event->xbutton.y+=windows->image.y;
13000 event->xbutton.y=(
int) (scale_factor*
event->xbutton.y+y+0.5);
13004 width=(
unsigned int) image->columns;
13005 height=(
unsigned int) image->rows;
13008 (void) XParseGeometry(image->montage,&x,&y,&width,&height);
13009 tile=((
event->xbutton.y-y)/height)*(((int) image->columns-x)/width)+
13010 (event->xbutton.x-x)/width;
13016 (void) XBell(display,0);
13017 return((
Image *) NULL);
13022 p=image->directory;
13023 for (i=tile; (i != 0) && (*p !=
'\0'); )
13034 (void) XBell(display,0);
13035 return((
Image *) NULL);
13040 id=XMenuWidget(display,windows,
"Tile Verb",VerbMenu,command);
13042 return((
Image *) NULL);
13044 while ((*q !=
'\xff') && (*q !=
'\0'))
13046 (void) CopyMagickString(filename,p,(
size_t) (q-p+1));
13050 XSetCursorState(display,windows,MagickTrue);
13051 XCheckRefreshWindows(display,windows);
13052 tile_image=NewImageList();
13053 switch (TileCommands[
id])
13055 case TileLoadCommand:
13060 XCheckRefreshWindows(display,windows);
13061 (void) CopyMagickString(resource_info->image_info->magick,
"MIFF",
13063 (void) CopyMagickString(resource_info->image_info->filename,filename,
13065 tile_image=ReadImage(resource_info->image_info,&image->exception);
13066 CatchException(&image->exception);
13067 (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
13070 case TileNextCommand:
13075 XClientMessage(display,windows->image.id,windows->im_protocols,
13076 windows->im_next_image,CurrentTime);
13079 case TileFormerCommand:
13084 XClientMessage(display,windows->image.id,windows->im_protocols,
13085 windows->im_former_image,CurrentTime);
13088 case TileDeleteCommand:
13093 if (IsPathAccessible(filename) == MagickFalse)
13095 XNoticeWidget(display,windows,
"Image file does not exist:",filename);
13098 status=XConfirmWidget(display,windows,
"Really delete tile",filename);
13101 status=ShredFile(filename);
13102 status|=remove_utf8(filename);
13103 if (status != MagickFalse)
13105 XNoticeWidget(display,windows,
"Unable to delete image file:",
13110 case TileUpdateCommand:
13132 for (p=image->directory; *p !=
'\0'; p++)
13138 while ((*q !=
'\xff') && (*q !=
'\0'))
13140 (void) CopyMagickString(filename,p,(
size_t) (q-p+1));
13142 if (IsPathAccessible(filename) != MagickFalse)
13150 x_offset=(int) (width*(tile % (((
int) image->columns-x)/width))+x);
13151 y_offset=(int) (height*(tile/(((
int) image->columns-x)/width))+y);
13152 exception=(&image->exception);
13153 image_view=AcquireAuthenticCacheView(image,exception);
13154 (void) GetOneCacheViewVirtualPixel(image_view,0,0,&pixel,exception);
13155 for (i=0; i < (int) height; i++)
13157 s=GetCacheViewAuthenticPixels(image_view,(ssize_t) x_offset,(ssize_t)
13158 y_offset+i,width,1,exception);
13161 for (j=0; j < (int) width; j++)
13163 if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
13166 image_view=DestroyCacheView(image_view);
13169 windows->image.window_changes.width=(int) image->columns;
13170 windows->image.window_changes.height=(
int) image->rows;
13171 XConfigureImageColormap(display,resource_info,windows,image);
13172 (void) XConfigureImage(display,resource_info,windows,image);
13178 XSetCursorState(display,windows,MagickFalse);
13179 return(tile_image);
13215 static void XTranslateImage(Display *display,XWindows *windows,
13216 Image *image,
const KeySym key_symbol)
13219 text[MaxTextExtent];
13232 x_offset=windows->image.width;
13233 y_offset=windows->image.height;
13234 if (image->montage != (
char *) NULL)
13235 (void) XParseGeometry(image->montage,&x,&y,&x_offset,&y_offset);
13236 switch ((
int) key_symbol)
13241 windows->image.x=(int) windows->image.width/2;
13242 windows->image.y=(
int) windows->image.height/2;
13248 windows->image.x-=x_offset;
13255 windows->image.y-=y_offset;
13261 windows->image.x+=x_offset;
13268 windows->image.y+=y_offset;
13277 if (windows->image.x < 0)
13278 windows->image.x=0;
13280 if ((
int) (windows->image.x+windows->image.width) >
13281 windows->image.ximage->width)
13282 windows->image.x=(int) windows->image.ximage->width-windows->image.width;
13283 if (windows->image.y < 0)
13284 windows->image.y=0;
13286 if ((
int) (windows->image.y+windows->image.height) >
13287 windows->image.ximage->height)
13288 windows->image.y=(int) windows->image.ximage->height-windows->image.height;
13292 (
void) FormatLocaleString(text,MaxTextExtent,
" %ux%u%+d%+d ",
13293 windows->image.width,windows->image.height,windows->image.x,
13295 XInfoWidget(display,windows,text);
13296 XCheckRefreshWindows(display,windows);
13297 XDrawPanRectangle(display,windows);
13298 XRefreshWindow(display,&windows->image,(XEvent *) NULL);
13299 (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
13332 static MagickBooleanType XTrimImage(Display *display,
13333 XResourceInfo *resource_info,XWindows *windows,
Image *image)
13349 XSetCursorState(display,windows,MagickTrue);
13350 XCheckRefreshWindows(display,windows);
13354 background=XGetPixel(windows->image.ximage,0,0);
13355 trim_info.width=(size_t) windows->image.ximage->width;
13356 for (x=0; x < windows->image.ximage->width; x++)
13358 for (y=0; y < windows->image.ximage->height; y++)
13360 pixel=XGetPixel(windows->image.ximage,x,y);
13361 if (pixel != background)
13364 if (y < windows->image.ximage->height)
13367 trim_info.x=(ssize_t) x;
13368 if (trim_info.x == (ssize_t) windows->image.ximage->width)
13370 XSetCursorState(display,windows,MagickFalse);
13371 return(MagickFalse);
13376 background=XGetPixel(windows->image.ximage,windows->image.ximage->width-1,0);
13377 for (x=windows->image.ximage->width-1; x != 0; x--)
13379 for (y=0; y < windows->image.ximage->height; y++)
13381 pixel=XGetPixel(windows->image.ximage,x,y);
13382 if (pixel != background)
13385 if (y < windows->image.ximage->height)
13388 trim_info.width=(size_t) (x-trim_info.x+1);
13392 background=XGetPixel(windows->image.ximage,0,0);
13393 trim_info.height=(size_t) windows->image.ximage->height;
13394 for (y=0; y < windows->image.ximage->height; y++)
13396 for (x=0; x < windows->image.ximage->width; x++)
13398 pixel=XGetPixel(windows->image.ximage,x,y);
13399 if (pixel != background)
13402 if (x < windows->image.ximage->width)
13405 trim_info.y=(ssize_t) y;
13409 background=XGetPixel(windows->image.ximage,0,windows->image.ximage->height-1);
13410 for (y=windows->image.ximage->height-1; y != 0; y--)
13412 for (x=0; x < windows->image.ximage->width; x++)
13414 pixel=XGetPixel(windows->image.ximage,x,y);
13415 if (pixel != background)
13418 if (x < windows->image.ximage->width)
13421 trim_info.height=(size_t) y-trim_info.y+1;
13422 if (((
unsigned int) trim_info.width != windows->image.width) ||
13423 ((
unsigned int) trim_info.height != windows->image.height))
13428 XSetCropGeometry(display,windows,&trim_info,image);
13429 windows->image.window_changes.width=(int) trim_info.width;
13430 windows->image.window_changes.height=(
int) trim_info.height;
13431 (void) XConfigureImage(display,resource_info,windows,image);
13433 XSetCursorState(display,windows,MagickFalse);
13434 return(MagickTrue);
13469 static Image *XVisualDirectoryImage(Display *display,
13470 XResourceInfo *resource_info,XWindows *windows)
13472 #define TileImageTag "Scale/Image"
13473 #define XClientName "montage"
13509 filename[MaxTextExtent] =
"\0",
13510 filenames[MaxTextExtent] =
"*";
13513 background_resources;
13518 XFileBrowserWidget(display,windows,
"Directory",filenames);
13519 if (*filenames ==
'\0')
13520 return((
Image *) NULL);
13524 filelist=(
char **) AcquireMagickMemory(
sizeof(*filelist));
13525 if (filelist == (
char **) NULL)
13527 ThrowXWindowException(ResourceLimitError,
"MemoryAllocationFailed",
13529 return((
Image *) NULL);
13532 filelist[0]=filenames;
13533 status=ExpandFilenames(&number_files,&filelist);
13534 if ((status == MagickFalse) || (number_files == 0))
13536 if (number_files == 0)
13537 ThrowXWindowException(ImageError,
"NoImagesWereFound",filenames)
13539 ThrowXWindowException(ResourceLimitError,"MemoryAllocationFailed",
13541 return((
Image *) NULL);
13546 background_resources=(*resource_info);
13547 background_resources.window_id=AcquireString("");
13548 (
void) FormatLocaleString(background_resources.window_id,MaxTextExtent,
13549 "0x%lx",windows->image.
id);
13550 background_resources.backdrop=MagickTrue;
13554 backdrop=(windows->visual_info->klass == TrueColor) ||
13555 (windows->visual_info->klass == DirectColor) ? MagickTrue : MagickFalse;
13556 read_info=CloneImageInfo(resource_info->image_info);
13557 (
void) SetImageOption(read_info,"jpeg:size","120x120");
13558 (
void) CloneString(&read_info->size,DefaultTileGeometry);
13559 (
void) SetImageInfoProgressMonitor(read_info,(MagickProgressMonitor) NULL,
13561 images=NewImageList();
13562 exception=AcquireExceptionInfo();
13563 XSetCursorState(display,windows,MagickTrue);
13564 XCheckRefreshWindows(display,windows);
13565 for (i=0; i < (
int) number_files; i++)
13567 (void) CopyMagickString(read_info->filename,filelist[i],MaxTextExtent);
13568 filelist[i]=DestroyString(filelist[i]);
13569 *read_info->magick=
'\0';
13570 next_image=ReadImage(read_info,exception);
13571 CatchException(exception);
13572 if (next_image != (
Image *) NULL)
13574 (void) DeleteImageProperty(next_image,
"label");
13575 (void) SetImageProperty(next_image,
"label",InterpretImageProperties(
13576 read_info,next_image,DefaultTileLabel));
13577 (void) ParseRegionGeometry(next_image,read_info->size,&geometry,
13579 thumbnail_image=ThumbnailImage(next_image,geometry.width,
13580 geometry.height,exception);
13581 if (thumbnail_image != (
Image *) NULL)
13583 next_image=DestroyImage(next_image);
13584 next_image=thumbnail_image;
13588 (void) XDisplayBackgroundImage(display,&background_resources,
13590 XSetCursorState(display,windows,MagickTrue);
13592 AppendImageToList(&images,next_image);
13593 if (images->progress_monitor != (MagickProgressMonitor) NULL)
13598 proceed=SetImageProgress(images,LoadImageTag,(MagickOffsetType) i,
13599 (MagickSizeType) number_files);
13600 if (proceed == MagickFalse)
13605 exception=DestroyExceptionInfo(exception);
13606 filelist=(
char **) RelinquishMagickMemory(filelist);
13607 if (images == (
Image *) NULL)
13609 read_info=DestroyImageInfo(read_info);
13610 XSetCursorState(display,windows,MagickFalse);
13611 ThrowXWindowException(ImageError,
"NoImagesWereLoaded",filenames);
13612 return((
Image *) NULL);
13617 montage_info=CloneMontageInfo(read_info,(
MontageInfo *) NULL);
13618 montage_info->pointsize=10;
13619 if (resource_info->font != (
char *) NULL)
13620 (void) CloneString(&montage_info->font,resource_info->font);
13621 (void) CopyMagickString(montage_info->filename,filename,MaxTextExtent);
13622 montage_image=MontageImageList(read_info,montage_info,GetFirstImageInList(
13623 images),&images->exception);
13624 images=DestroyImageList(images);
13625 montage_info=DestroyMontageInfo(montage_info);
13626 read_info=DestroyImageInfo(read_info);
13627 XSetCursorState(display,windows,MagickFalse);
13628 if (montage_image == (
Image *) NULL)
13629 return(montage_image);
13630 XClientMessage(display,windows->image.id,windows->im_protocols,
13631 windows->im_next_image,CurrentTime);
13632 return(montage_image);
13663 MagickExport MagickBooleanType XDisplayBackgroundImage(Display *display,
13664 XResourceInfo *resource_info,
Image *image)
13667 geometry[MaxTextExtent],
13668 visual_type[MaxTextExtent];
13681 static XStandardColormap
13685 *visual_info = (XVisualInfo *) NULL;
13708 assert(image != (
Image *) NULL);
13709 assert(image->signature == MagickCoreSignature);
13710 if (IsEventLogging() != MagickFalse)
13711 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
13712 resources=(*resource_info);
13713 window_info.id=(Window) NULL;
13714 root_window=XRootWindow(display,XDefaultScreen(display));
13715 if (LocaleCompare(resources.window_id,
"root") == 0)
13716 window_info.id=root_window;
13719 if (isdigit((
int) ((
unsigned char) *resources.window_id)) != 0)
13720 window_info.id=XWindowByID(display,root_window,
13721 (Window) strtol((
char *) resources.window_id,(
char **) NULL,0));
13722 if (window_info.id == (Window) NULL)
13723 window_info.id=XWindowByName(display,root_window,resources.window_id);
13725 if (window_info.id == (Window) NULL)
13727 ThrowXWindowException(XServerError,
"NoWindowWithSpecifiedIDExists",
13728 resources.window_id);
13733 window_attributes.width=XDisplayWidth(display,XDefaultScreen(display));
13734 window_attributes.height=XDisplayHeight(display,XDefaultScreen(display));
13735 (void) CopyMagickString(visual_type,
"default",MaxTextExtent);
13736 status=XGetWindowAttributes(display,window_info.id,&window_attributes);
13738 (void) FormatLocaleString(visual_type,MaxTextExtent,
"0x%lx",
13739 XVisualIDFromVisual(window_attributes.visual));
13740 if (visual_info == (XVisualInfo *) NULL)
13745 map_info=XAllocStandardColormap();
13746 if (map_info == (XStandardColormap *) NULL)
13747 ThrowXWindowFatalException(XServerFatalError,
"MemoryAllocationFailed",
13749 map_info->colormap=(Colormap) NULL;
13750 pixel.pixels=(
unsigned long *) NULL;
13754 resources.map_type=(
char *) NULL;
13755 resources.visual_type=visual_type;
13756 visual_info=XBestVisualInfo(display,map_info,&resources);
13757 if (visual_info == (XVisualInfo *) NULL)
13758 ThrowXWindowFatalException(XServerFatalError,
"UnableToGetVisual",
13759 resources.visual_type);
13763 window_info.ximage=(XImage *) NULL;
13764 window_info.matte_image=(XImage *) NULL;
13765 window_info.pixmap=(Pixmap) NULL;
13766 window_info.matte_pixmap=(Pixmap) NULL;
13771 if (window_info.id == root_window)
13772 (void) XDestroyWindowColors(display,root_window);
13776 resources.colormap=SharedColormap;
13777 XMakeStandardColormap(display,visual_info,&resources,image,map_info,&pixel);
13781 context_values.background=pixel.foreground_color.pixel;
13782 context_values.foreground=pixel.background_color.pixel;
13783 pixel.annotate_context=XCreateGC(display,window_info.id,
13784 (
size_t) (GCBackground | GCForeground),&context_values);
13785 if (pixel.annotate_context == (GC) NULL)
13786 ThrowXWindowFatalException(XServerFatalError,
"UnableToCreateGraphicContext",
13791 window_info.name=AcquireString(
"\0");
13792 window_info.icon_name=AcquireString(
"\0");
13793 XGetWindowInfo(display,visual_info,map_info,&pixel,(XFontStruct *) NULL,
13794 &resources,&window_info);
13798 window_info.width=(
unsigned int) image->columns;
13799 window_info.height=(
unsigned int) image->rows;
13800 if ((image->columns != window_info.width) ||
13801 (image->rows != window_info.height))
13802 ThrowXWindowFatalException(XServerFatalError,
"UnableToCreateXImage",
13804 (void) FormatLocaleString(geometry,MaxTextExtent,
"%ux%u+0+0>",
13805 window_attributes.width,window_attributes.height);
13806 geometry_info.width=window_info.width;
13807 geometry_info.height=window_info.height;
13808 geometry_info.x=(ssize_t) window_info.x;
13809 geometry_info.y=(ssize_t) window_info.y;
13810 (void) ParseMetaGeometry(geometry,&geometry_info.x,&geometry_info.y,
13811 &geometry_info.width,&geometry_info.height);
13812 window_info.width=(
unsigned int) geometry_info.width;
13813 window_info.height=(
unsigned int) geometry_info.height;
13814 window_info.x=(int) geometry_info.x;
13815 window_info.y=(
int) geometry_info.y;
13816 status=XMakeImage(display,&resources,&window_info,image,window_info.width,
13817 window_info.height);
13818 if (status == MagickFalse)
13819 ThrowXWindowFatalException(XServerFatalError,
"UnableToCreateXImage",
13823 if (resource_info->debug != MagickFalse)
13825 (void) LogMagickEvent(X11Event,GetMagickModule(),
13826 "Image: %s[%.20g] %.20gx%.20g ",image->filename,(double) image->scene,
13827 (
double) image->columns,(double) image->rows);
13828 if (image->colors != 0)
13829 (void) LogMagickEvent(X11Event,GetMagickModule(),
"%.20gc ",(double)
13831 (void) LogMagickEvent(X11Event,GetMagickModule(),
"%s",image->magick);
13836 width=(int) window_info.width;
13837 height=(
int) window_info.height;
13838 if (resources.backdrop != MagickFalse)
13843 window_info.x=(window_attributes.width/2)-(window_info.ximage->width/2);
13844 window_info.y=(window_attributes.height/2)-(window_info.ximage->height/2);
13845 width=window_attributes.width;
13846 height=window_attributes.height;
13848 if ((resources.image_geometry != (
char *) NULL) &&
13849 (*resources.image_geometry !=
'\0'))
13852 default_geometry[MaxTextExtent];
13864 size_hints=XAllocSizeHints();
13865 if (size_hints == (XSizeHints *) NULL)
13866 ThrowXWindowFatalException(ResourceLimitFatalError,
13867 "MemoryAllocationFailed",image->filename);
13868 size_hints->flags=0L;
13869 (void) FormatLocaleString(default_geometry,MaxTextExtent,
"%dx%d",
13871 flags=XWMGeometry(display,visual_info->screen,resources.image_geometry,
13872 default_geometry,window_info.border_width,size_hints,&window_info.x,
13873 &window_info.y,&width,&height,&gravity);
13874 if (flags & (XValue | YValue))
13876 width=window_attributes.width;
13877 height=window_attributes.height;
13879 (void) XFree((
void *) size_hints);
13884 window_info.pixmap=XCreatePixmap(display,window_info.id,(
unsigned int) width,
13885 (
unsigned int) height,window_info.depth);
13886 if (window_info.pixmap == (Pixmap) NULL)
13887 ThrowXWindowFatalException(XServerFatalError,
"UnableToCreateXPixmap",
13892 if (((
unsigned int) width > window_info.width) ||
13893 ((
unsigned int) height > window_info.height))
13894 (void) XFillRectangle(display,window_info.pixmap,
13895 window_info.annotate_context,0,0,(
unsigned int) width,
13896 (
unsigned int) height);
13897 (void) XPutImage(display,window_info.pixmap,window_info.annotate_context,
13898 window_info.ximage,0,0,window_info.x,window_info.y,(
unsigned int)
13899 window_info.width,(
unsigned int) window_info.height);
13900 (void) XSetWindowBackgroundPixmap(display,window_info.id,window_info.pixmap);
13901 (void) XClearWindow(display,window_info.id);
13902 delay=1000*image->delay/MagickMax(image->ticks_per_second,1L);
13903 XDelay(display,delay == 0UL ? 10UL : delay);
13904 (void) XSync(display,MagickFalse);
13905 return(window_info.id == root_window ? MagickTrue : MagickFalse);
13945 MagickExport
Image *XDisplayImage(Display *display,XResourceInfo *resource_info,
13946 char **argv,
int argc,
Image **image,
size_t *state)
13948 #define MagnifySize 256
13949 #define MagickMenus 10
13950 #define MagickTitle "Commands"
13953 *
const CommandMenu[] =
13967 *
const FileMenu[] =
13977 "Visual Directory...",
13981 *
const EditMenu[] =
13990 *
const ViewMenu[] =
14001 *
const TransformMenu[] =
14015 *
const EnhanceMenu[] =
14023 "Contrast Stretch...",
14024 "Sigmoidal Contrast...",
14033 *
const EffectsMenu[] =
14058 "Charcoal Draw...",
14061 *
const ImageEditMenu[] =
14072 "Region of Interest...",
14075 *
const MiscellanyMenu[] =
14087 *
const HelpMenu[] =
14090 "Browse Documentation",
14094 *
const ShortCutsMenu[] =
14107 *
const VirtualMenu[] =
14117 *
const *Menus[MagickMenus] =
14155 VisualDirectoryCommand,
14169 OriginalSizeCommand,
14176 TransformCommands[] =
14182 RotateRightCommand,
14189 EnhanceCommands[] =
14197 ContrastStretchCommand,
14198 SigmoidalContrastCommand,
14206 EffectsCommands[] =
14210 ReduceNoiseCommand,
14230 CharcoalDrawCommand
14232 ImageEditCommands[] =
14243 RegionofInterestCommand
14245 MiscellanyCommands[] =
14249 ShowPreviewCommand,
14250 ShowHistogramCommand,
14259 BrowseDocumentationCommand,
14262 ShortCutsCommands[] =
14274 VirtualCommands[] =
14283 *Commands[MagickMenus] =
14293 MiscellanyCommands,
14298 command[MaxTextExtent],
14300 geometry[MaxTextExtent],
14301 resource_name[MaxTextExtent];
14328 working_directory[MaxTextExtent];
14334 *magick_windows[MaxXWindows];
14336 static unsigned int
14396 assert(image != (
Image **) NULL);
14397 assert((*image)->signature == MagickCoreSignature);
14398 if (IsEventLogging() != MagickFalse)
14399 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",(*image)->filename);
14400 display_image=(*image);
14401 warning_handler=(WarningHandler) NULL;
14402 windows=XSetWindows((XWindows *) ~0);
14403 if (windows != (XWindows *) NULL)
14408 if (*working_directory ==
'\0')
14409 (void) CopyMagickString(working_directory,
".",MaxTextExtent);
14410 status=chdir(working_directory);
14412 (void) ThrowMagickException(&(*image)->exception,GetMagickModule(),
14413 FileOpenError,
"UnableToOpenFile",
"%s",working_directory);
14414 warning_handler=resource_info->display_warnings ?
14415 SetErrorHandler(XWarning) : SetErrorHandler((ErrorHandler) NULL);
14416 warning_handler=resource_info->display_warnings ?
14417 SetWarningHandler(XWarning) : SetWarningHandler((WarningHandler) NULL);
14424 resource_info->colors=display_image->colors;
14425 windows=XSetWindows(XInitializeWindows(display,resource_info));
14426 if (windows == (XWindows *) NULL)
14427 ThrowXWindowFatalException(XServerFatalError,
"UnableToCreateWindow",
14428 (*image)->filename);
14433 magick_windows[number_windows++]=(&windows->icon);
14434 magick_windows[number_windows++]=(&windows->backdrop);
14435 magick_windows[number_windows++]=(&windows->image);
14436 magick_windows[number_windows++]=(&windows->info);
14437 magick_windows[number_windows++]=(&windows->command);
14438 magick_windows[number_windows++]=(&windows->widget);
14439 magick_windows[number_windows++]=(&windows->popup);
14440 magick_windows[number_windows++]=(&windows->magnify);
14441 magick_windows[number_windows++]=(&windows->pan);
14442 for (i=0; i < (int) number_windows; i++)
14443 magick_windows[i]->
id=(Window) NULL;
14450 if (windows->font_info != (XFontStruct *) NULL)
14451 (
void) XFreeFont(display,windows->font_info);
14452 windows->font_info=XBestFont(display,resource_info,MagickFalse);
14453 if (windows->font_info == (XFontStruct *) NULL)
14454 ThrowXWindowFatalException(XServerFatalError,
"UnableToLoadFont",
14455 resource_info->font);
14459 map_info=windows->map_info;
14460 icon_map=windows->icon_map;
14461 visual_info=windows->visual_info;
14462 icon_visual=windows->icon_visual;
14463 pixel=windows->pixel_info;
14464 icon_pixel=windows->icon_pixel;
14465 font_info=windows->font_info;
14466 icon_resources=windows->icon_resources;
14467 class_hints=windows->class_hints;
14468 manager_hints=windows->manager_hints;
14469 root_window=XRootWindow(display,visual_info->screen);
14470 nexus=NewImageList();
14471 if (resource_info->debug != MagickFalse)
14473 (void) LogMagickEvent(X11Event,GetMagickModule(),
14474 "Image: %s[%.20g] %.20gx%.20g ",display_image->filename,
14475 (double) display_image->scene,(
double) display_image->columns,
14476 (double) display_image->rows);
14477 if (display_image->colors != 0)
14478 (void) LogMagickEvent(X11Event,GetMagickModule(),
"%.20gc ",(double)
14479 display_image->colors);
14480 (void) LogMagickEvent(X11Event,GetMagickModule(),
"%s",
14481 display_image->magick);
14483 XMakeStandardColormap(display,visual_info,resource_info,display_image,
14485 display_image->taint=MagickFalse;
14489 windows->context.id=(Window) NULL;
14490 XGetWindowInfo(display,visual_info,map_info,pixel,font_info,
14491 resource_info,&windows->context);
14492 (void) CloneString(&class_hints->res_name,resource_info->client_name);
14493 (void) CloneString(&class_hints->res_class,resource_info->client_name);
14494 class_hints->res_class[0]=(char) LocaleToUppercase((
int)
14495 class_hints->res_class[0]);
14496 manager_hints->flags=InputHint | StateHint;
14497 manager_hints->input=MagickFalse;
14498 manager_hints->initial_state=WithdrawnState;
14499 XMakeWindow(display,root_window,argv,argc,class_hints,manager_hints,
14500 &windows->context);
14501 if (resource_info->debug != MagickFalse)
14502 (void) LogMagickEvent(X11Event,GetMagickModule(),
14503 "Window id: 0x%lx (context)",windows->context.id);
14504 context_values.background=pixel->background_color.pixel;
14505 context_values.font=font_info->fid;
14506 context_values.foreground=pixel->foreground_color.pixel;
14507 context_values.graphics_exposures=MagickFalse;
14508 context_mask=(MagickStatusType)
14509 (GCBackground | GCFont | GCForeground | GCGraphicsExposures);
14510 if (pixel->annotate_context != (GC) NULL)
14511 (
void) XFreeGC(display,pixel->annotate_context);
14512 pixel->annotate_context=XCreateGC(display,windows->context.id,
14513 context_mask,&context_values);
14514 if (pixel->annotate_context == (GC) NULL)
14515 ThrowXWindowFatalException(XServerFatalError,
"UnableToCreateGraphicContext",
14516 display_image->filename);
14517 context_values.background=pixel->depth_color.pixel;
14518 if (pixel->widget_context != (GC) NULL)
14519 (void) XFreeGC(display,pixel->widget_context);
14520 pixel->widget_context=XCreateGC(display,windows->context.id,context_mask,
14522 if (pixel->widget_context == (GC) NULL)
14523 ThrowXWindowFatalException(XServerFatalError,
"UnableToCreateGraphicContext",
14524 display_image->filename);
14525 context_values.background=pixel->foreground_color.pixel;
14526 context_values.foreground=pixel->background_color.pixel;
14527 context_values.plane_mask=context_values.background ^
14528 context_values.foreground;
14529 if (pixel->highlight_context != (GC) NULL)
14530 (void) XFreeGC(display,pixel->highlight_context);
14531 pixel->highlight_context=XCreateGC(display,windows->context.id,
14532 (
size_t) (context_mask | GCPlaneMask),&context_values);
14533 if (pixel->highlight_context == (GC) NULL)
14534 ThrowXWindowFatalException(XServerFatalError,
"UnableToCreateGraphicContext",
14535 display_image->filename);
14536 (void) XDestroyWindow(display,windows->context.id);
14540 XGetWindowInfo(display,icon_visual,icon_map,icon_pixel,(XFontStruct *) NULL,
14541 icon_resources,&windows->icon);
14542 windows->icon.geometry=resource_info->icon_geometry;
14543 XBestIconSize(display,&windows->icon,display_image);
14544 windows->icon.attributes.colormap=XDefaultColormap(display,
14545 icon_visual->screen);
14546 windows->icon.attributes.event_mask=ExposureMask | StructureNotifyMask;
14547 manager_hints->flags=InputHint | StateHint;
14548 manager_hints->input=MagickFalse;
14549 manager_hints->initial_state=IconicState;
14550 XMakeWindow(display,root_window,argv,argc,class_hints,manager_hints,
14552 if (resource_info->debug != MagickFalse)
14553 (void) LogMagickEvent(X11Event,GetMagickModule(),
"Window id: 0x%lx (icon)",
14558 if (icon_pixel->annotate_context != (GC) NULL)
14559 (
void) XFreeGC(display,icon_pixel->annotate_context);
14560 context_values.background=icon_pixel->background_color.pixel;
14561 context_values.foreground=icon_pixel->foreground_color.pixel;
14562 icon_pixel->annotate_context=XCreateGC(display,windows->icon.id,
14563 (
size_t) (GCBackground | GCForeground),&context_values);
14564 if (icon_pixel->annotate_context == (GC) NULL)
14565 ThrowXWindowFatalException(XServerFatalError,
"UnableToCreateGraphicContext",
14566 display_image->filename);
14567 windows->icon.annotate_context=icon_pixel->annotate_context;
14571 XGetWindowInfo(display,visual_info,map_info,pixel,font_info,resource_info,
14573 windows->image.shape=MagickTrue;
14574 if (resource_info->use_shared_memory == MagickFalse)
14575 windows->image.shared_memory=MagickFalse;
14576 if ((resource_info->title != (
char *) NULL) && !(*state & MontageImageState))
14581 title=InterpretImageProperties(resource_info->image_info,display_image,
14582 resource_info->title);
14583 (void) CloneString(&windows->image.name,title);
14584 (void) CloneString(&windows->image.icon_name,title);
14585 title=DestroyString(title);
14590 filename[MaxTextExtent],
14591 window_name[MaxTextExtent];
14596 GetPathComponent(display_image->magick_filename,TailPath,filename);
14597 if (display_image->scene == 0)
14598 (void) FormatLocaleString(window_name,MaxTextExtent,
"%s: %s",
14599 MagickPackageName,filename);
14601 (
void) FormatLocaleString(window_name,MaxTextExtent,
14602 "%s: %s[scene: %.20g frames: %.20g]",MagickPackageName,filename,
14603 (
double) display_image->scene,(
double) GetImageListLength(
14605 (void) CloneString(&windows->image.name,window_name);
14606 (void) CloneString(&windows->image.icon_name,filename);
14608 if (resource_info->immutable)
14609 windows->image.immutable=MagickTrue;
14610 windows->image.use_pixmap=resource_info->use_pixmap;
14611 windows->image.geometry=resource_info->image_geometry;
14612 (void) FormatLocaleString(geometry,MaxTextExtent,
"%ux%u+0+0>!",
14613 XDisplayWidth(display,visual_info->screen),
14614 XDisplayHeight(display,visual_info->screen));
14615 geometry_info.width=display_image->columns;
14616 geometry_info.height=display_image->rows;
14619 (void) ParseMetaGeometry(geometry,&geometry_info.x,&geometry_info.y,
14620 &geometry_info.width,&geometry_info.height);
14621 windows->image.width=(
unsigned int) geometry_info.width;
14622 windows->image.height=(
unsigned int) geometry_info.height;
14623 windows->image.attributes.event_mask=ButtonMotionMask | ButtonPressMask |
14624 ButtonReleaseMask | EnterWindowMask | ExposureMask | KeyPressMask |
14625 KeyReleaseMask | LeaveWindowMask | OwnerGrabButtonMask |
14626 PropertyChangeMask | StructureNotifyMask | SubstructureNotifyMask;
14627 XGetWindowInfo(display,visual_info,map_info,pixel,font_info,
14628 resource_info,&windows->backdrop);
14629 if ((resource_info->backdrop) || (windows->backdrop.id != (Window) NULL))
14634 windows->backdrop.x=0;
14635 windows->backdrop.y=0;
14636 (void) CloneString(&windows->backdrop.name,
"Backdrop");
14637 windows->backdrop.flags=(size_t) (USSize | USPosition);
14638 windows->backdrop.width=(
unsigned int)
14639 XDisplayWidth(display,visual_info->screen);
14640 windows->backdrop.height=(
unsigned int)
14641 XDisplayHeight(display,visual_info->screen);
14642 windows->backdrop.border_width=0;
14643 windows->backdrop.immutable=MagickTrue;
14644 windows->backdrop.attributes.do_not_propagate_mask=ButtonPressMask |
14646 windows->backdrop.attributes.event_mask=ButtonPressMask | KeyPressMask |
14647 StructureNotifyMask;
14648 manager_hints->flags=IconWindowHint | InputHint | StateHint;
14649 manager_hints->icon_window=windows->icon.id;
14650 manager_hints->input=MagickTrue;
14651 manager_hints->initial_state=resource_info->iconic ? IconicState :
14653 XMakeWindow(display,root_window,argv,argc,class_hints,manager_hints,
14654 &windows->backdrop);
14655 if (resource_info->debug != MagickFalse)
14656 (void) LogMagickEvent(X11Event,GetMagickModule(),
14657 "Window id: 0x%lx (backdrop)",windows->backdrop.id);
14658 (void) XMapWindow(display,windows->backdrop.id);
14659 (void) XClearWindow(display,windows->backdrop.id);
14660 if (windows->image.id != (Window) NULL)
14662 (void) XDestroyWindow(display,windows->image.id);
14663 windows->image.id=(Window) NULL;
14668 windows->image.flags|=USPosition;
14669 windows->image.x=(XDisplayWidth(display,visual_info->screen)/2)-
14670 (windows->image.width/2);
14671 windows->image.y=(XDisplayHeight(display,visual_info->screen)/2)-
14672 (windows->image.height/2);
14674 manager_hints->flags=IconWindowHint | InputHint | StateHint;
14675 manager_hints->icon_window=windows->icon.id;
14676 manager_hints->input=MagickTrue;
14677 manager_hints->initial_state=resource_info->iconic ? IconicState :
14679 if (windows->group_leader.id != (Window) NULL)
14684 manager_hints->flags|=WindowGroupHint;
14685 manager_hints->window_group=windows->group_leader.id;
14686 (void) XSelectInput(display,windows->group_leader.id,StructureNotifyMask);
14687 if (resource_info->debug != MagickFalse)
14688 (void) LogMagickEvent(X11Event,GetMagickModule(),
14689 "Window id: 0x%lx (group leader)",windows->group_leader.id);
14691 XMakeWindow(display,
14692 (Window) (resource_info->backdrop ? windows->backdrop.id : root_window),
14693 argv,argc,class_hints,manager_hints,&windows->image);
14694 (void) XChangeProperty(display,windows->image.id,windows->im_protocols,
14695 XA_STRING,8,PropModeReplace,(
unsigned char *) NULL,0);
14696 if (windows->group_leader.id != (Window) NULL)
14697 (
void) XSetTransientForHint(display,windows->image.id,
14698 windows->group_leader.id);
14699 if (resource_info->debug != MagickFalse)
14700 (void) LogMagickEvent(X11Event,GetMagickModule(),
"Window id: 0x%lx (image)",
14701 windows->image.id);
14705 XGetWindowInfo(display,visual_info,map_info,pixel,font_info,resource_info,
14707 (void) CloneString(&windows->info.name,
"Info");
14708 (void) CloneString(&windows->info.icon_name,
"Info");
14709 windows->info.border_width=1;
14712 windows->info.flags|=PPosition;
14713 windows->info.attributes.win_gravity=UnmapGravity;
14714 windows->info.attributes.event_mask=ButtonPressMask | ExposureMask |
14715 StructureNotifyMask;
14716 manager_hints->flags=InputHint | StateHint | WindowGroupHint;
14717 manager_hints->input=MagickFalse;
14718 manager_hints->initial_state=NormalState;
14719 manager_hints->window_group=windows->image.id;
14720 XMakeWindow(display,windows->image.id,argv,argc,class_hints,manager_hints,
14722 windows->info.highlight_stipple=XCreateBitmapFromData(display,
14723 windows->info.id,(
char *) HighlightBitmap,HighlightWidth,HighlightHeight);
14724 windows->info.shadow_stipple=XCreateBitmapFromData(display,
14725 windows->info.id,(
char *) ShadowBitmap,ShadowWidth,ShadowHeight);
14726 (void) XSetTransientForHint(display,windows->info.id,windows->image.id);
14727 if (windows->image.mapped != MagickFalse)
14728 (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
14729 if (resource_info->debug != MagickFalse)
14730 (void) LogMagickEvent(X11Event,GetMagickModule(),
"Window id: 0x%lx (info)",
14735 XGetWindowInfo(display,visual_info,map_info,pixel,font_info,
14736 resource_info,&windows->command);
14737 windows->command.data=MagickMenus;
14738 (void) XCommandWidget(display,windows,CommandMenu,(XEvent *) NULL);
14739 (void) FormatLocaleString(resource_name,MaxTextExtent,
"%s.command",
14740 resource_info->client_name);
14741 windows->command.geometry=XGetResourceClass(resource_info->resource_database,
14742 resource_name,
"geometry",(
char *) NULL);
14743 (void) CloneString(&windows->command.name,MagickTitle);
14744 windows->command.border_width=0;
14745 windows->command.flags|=PPosition;
14746 windows->command.attributes.event_mask=ButtonMotionMask | ButtonPressMask |
14747 ButtonReleaseMask | EnterWindowMask | ExposureMask | LeaveWindowMask |
14748 OwnerGrabButtonMask | StructureNotifyMask;
14749 manager_hints->flags=InputHint | StateHint | WindowGroupHint;
14750 manager_hints->input=MagickTrue;
14751 manager_hints->initial_state=NormalState;
14752 manager_hints->window_group=windows->image.id;
14753 XMakeWindow(display,root_window,argv,argc,class_hints,manager_hints,
14754 &windows->command);
14755 windows->command.highlight_stipple=XCreateBitmapFromData(display,
14756 windows->command.id,(
char *) HighlightBitmap,HighlightWidth,
14758 windows->command.shadow_stipple=XCreateBitmapFromData(display,
14759 windows->command.id,(
char *) ShadowBitmap,ShadowWidth,ShadowHeight);
14760 (void) XSetTransientForHint(display,windows->command.id,windows->image.id);
14761 if (windows->command.mapped != MagickFalse)
14762 (void) XMapRaised(display,windows->command.id);
14763 if (resource_info->debug != MagickFalse)
14764 (void) LogMagickEvent(X11Event,GetMagickModule(),
14765 "Window id: 0x%lx (command)",windows->command.id);
14769 XGetWindowInfo(display,visual_info,map_info,pixel,font_info,
14770 resource_info,&windows->widget);
14771 (void) FormatLocaleString(resource_name,MaxTextExtent,
"%s.widget",
14772 resource_info->client_name);
14773 windows->widget.geometry=XGetResourceClass(resource_info->resource_database,
14774 resource_name,
"geometry",(
char *) NULL);
14775 windows->widget.border_width=0;
14776 windows->widget.flags|=PPosition;
14777 windows->widget.attributes.event_mask=ButtonMotionMask | ButtonPressMask |
14778 ButtonReleaseMask | EnterWindowMask | ExposureMask | KeyPressMask |
14779 KeyReleaseMask | LeaveWindowMask | OwnerGrabButtonMask |
14780 StructureNotifyMask;
14781 manager_hints->flags=InputHint | StateHint | WindowGroupHint;
14782 manager_hints->input=MagickTrue;
14783 manager_hints->initial_state=NormalState;
14784 manager_hints->window_group=windows->image.id;
14785 XMakeWindow(display,root_window,argv,argc,class_hints,manager_hints,
14787 windows->widget.highlight_stipple=XCreateBitmapFromData(display,
14788 windows->widget.id,(
char *) HighlightBitmap,HighlightWidth,HighlightHeight);
14789 windows->widget.shadow_stipple=XCreateBitmapFromData(display,
14790 windows->widget.id,(
char *) ShadowBitmap,ShadowWidth,ShadowHeight);
14791 (void) XSetTransientForHint(display,windows->widget.id,windows->image.id);
14792 if (resource_info->debug != MagickFalse)
14793 (void) LogMagickEvent(X11Event,GetMagickModule(),
14794 "Window id: 0x%lx (widget)",windows->widget.id);
14798 XGetWindowInfo(display,visual_info,map_info,pixel,font_info,
14799 resource_info,&windows->popup);
14800 windows->popup.border_width=0;
14801 windows->popup.flags|=PPosition;
14802 windows->popup.attributes.event_mask=ButtonMotionMask | ButtonPressMask |
14803 ButtonReleaseMask | EnterWindowMask | ExposureMask | KeyPressMask |
14804 KeyReleaseMask | LeaveWindowMask | StructureNotifyMask;
14805 manager_hints->flags=InputHint | StateHint | WindowGroupHint;
14806 manager_hints->input=MagickTrue;
14807 manager_hints->initial_state=NormalState;
14808 manager_hints->window_group=windows->image.id;
14809 XMakeWindow(display,root_window,argv,argc,class_hints,manager_hints,
14811 windows->popup.highlight_stipple=XCreateBitmapFromData(display,
14812 windows->popup.id,(
char *) HighlightBitmap,HighlightWidth,HighlightHeight);
14813 windows->popup.shadow_stipple=XCreateBitmapFromData(display,
14814 windows->popup.id,(
char *) ShadowBitmap,ShadowWidth,ShadowHeight);
14815 (void) XSetTransientForHint(display,windows->popup.id,windows->image.id);
14816 if (resource_info->debug != MagickFalse)
14817 (void) LogMagickEvent(X11Event,GetMagickModule(),
14818 "Window id: 0x%lx (pop up)",windows->popup.id);
14822 XGetWindowInfo(display,visual_info,map_info,pixel,font_info,
14823 resource_info,&windows->magnify);
14824 if (resource_info->use_shared_memory == MagickFalse)
14825 windows->magnify.shared_memory=MagickFalse;
14826 (void) FormatLocaleString(resource_name,MaxTextExtent,
"%s.magnify",
14827 resource_info->client_name);
14828 windows->magnify.geometry=XGetResourceClass(resource_info->resource_database,
14829 resource_name,
"geometry",(
char *) NULL);
14830 (void) FormatLocaleString(windows->magnify.name,MaxTextExtent,
"Magnify %uX",
14831 resource_info->magnify);
14832 if (windows->magnify.cursor != (Cursor) NULL)
14833 (
void) XFreeCursor(display,windows->magnify.cursor);
14834 windows->magnify.cursor=XMakeCursor(display,windows->image.id,
14835 map_info->colormap,resource_info->background_color,
14836 resource_info->foreground_color);
14837 if (windows->magnify.cursor == (Cursor) NULL)
14838 ThrowXWindowFatalException(XServerFatalError,
"UnableToCreateCursor",
14839 display_image->filename);
14840 windows->magnify.width=MagnifySize;
14841 windows->magnify.height=MagnifySize;
14842 windows->magnify.flags|=PPosition;
14843 windows->magnify.min_width=MagnifySize;
14844 windows->magnify.min_height=MagnifySize;
14845 windows->magnify.width_inc=MagnifySize;
14846 windows->magnify.height_inc=MagnifySize;
14847 windows->magnify.data=resource_info->magnify;
14848 windows->magnify.attributes.cursor=windows->magnify.cursor;
14849 windows->magnify.attributes.event_mask=ButtonPressMask | ButtonReleaseMask |
14850 ExposureMask | KeyPressMask | KeyReleaseMask | OwnerGrabButtonMask |
14851 StructureNotifyMask;
14852 manager_hints->flags=InputHint | StateHint | WindowGroupHint;
14853 manager_hints->input=MagickTrue;
14854 manager_hints->initial_state=NormalState;
14855 manager_hints->window_group=windows->image.id;
14856 XMakeWindow(display,root_window,argv,argc,class_hints,manager_hints,
14857 &windows->magnify);
14858 if (resource_info->debug != MagickFalse)
14859 (void) LogMagickEvent(X11Event,GetMagickModule(),
14860 "Window id: 0x%lx (magnify)",windows->magnify.id);
14861 (void) XSetTransientForHint(display,windows->magnify.id,windows->image.id);
14865 XGetWindowInfo(display,visual_info,map_info,pixel,font_info,
14866 resource_info,&windows->pan);
14867 (void) CloneString(&windows->pan.name,
"Pan Icon");
14868 windows->pan.width=windows->icon.width;
14869 windows->pan.height=windows->icon.height;
14870 (void) FormatLocaleString(resource_name,MaxTextExtent,
"%s.pan",
14871 resource_info->client_name);
14872 windows->pan.geometry=XGetResourceClass(resource_info->resource_database,
14873 resource_name,
"geometry",(
char *) NULL);
14874 (void) XParseGeometry(windows->pan.geometry,&windows->pan.x,&windows->pan.y,
14875 &windows->pan.width,&windows->pan.height);
14876 windows->pan.flags|=PPosition;
14877 windows->pan.immutable=MagickTrue;
14878 windows->pan.attributes.event_mask=ButtonMotionMask | ButtonPressMask |
14879 ButtonReleaseMask | ExposureMask | KeyPressMask | KeyReleaseMask |
14880 StructureNotifyMask;
14881 manager_hints->flags=InputHint | StateHint | WindowGroupHint;
14882 manager_hints->input=MagickFalse;
14883 manager_hints->initial_state=NormalState;
14884 manager_hints->window_group=windows->image.id;
14885 XMakeWindow(display,root_window,argv,argc,class_hints,manager_hints,
14887 if (resource_info->debug != MagickFalse)
14888 (void) LogMagickEvent(X11Event,GetMagickModule(),
"Window id: 0x%lx (pan)",
14890 (void) XSetTransientForHint(display,windows->pan.id,windows->image.id);
14891 if (windows->info.mapped != MagickFalse)
14892 (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
14893 if ((windows->image.mapped == MagickFalse) ||
14894 (windows->backdrop.id != (Window) NULL))
14895 (
void) XMapWindow(display,windows->image.id);
14899 if (warning_handler == (WarningHandler) NULL)
14901 warning_handler=resource_info->display_warnings ?
14902 SetErrorHandler(XWarning) : SetErrorHandler((ErrorHandler) NULL);
14903 warning_handler=resource_info->display_warnings ?
14904 SetWarningHandler(XWarning) : SetWarningHandler((WarningHandler) NULL);
14909 windows->image.x=0;
14910 windows->image.y=0;
14911 windows->magnify.shape=MagickFalse;
14912 width=(
unsigned int) display_image->columns;
14913 height=(
unsigned int) display_image->rows;
14914 if ((display_image->columns != width) || (display_image->rows != height))
14915 ThrowXWindowFatalException(XServerFatalError,
"UnableToCreateXImage",
14916 display_image->filename);
14917 status=XMakeImage(display,resource_info,&windows->image,display_image,
14919 if (status == MagickFalse)
14920 ThrowXWindowFatalException(XServerFatalError,
"UnableToCreateXImage",
14921 display_image->filename);
14922 status=XMakeImage(display,resource_info,&windows->magnify,(
Image *) NULL,
14923 windows->magnify.width,windows->magnify.height);
14924 if (status == MagickFalse)
14925 ThrowXWindowFatalException(XServerFatalError,
"UnableToCreateXImage",
14926 display_image->filename);
14927 if (windows->magnify.mapped != MagickFalse)
14928 (void) XMapRaised(display,windows->magnify.id);
14929 if (windows->pan.mapped != MagickFalse)
14930 (void) XMapRaised(display,windows->pan.id);
14931 windows->image.window_changes.width=(int) display_image->columns;
14932 windows->image.window_changes.height=(
int) display_image->rows;
14933 (void) XConfigureImage(display,resource_info,windows,display_image);
14934 (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
14935 (void) XSync(display,MagickFalse);
14939 delay=display_image->delay/MagickMax(display_image->ticks_per_second,1L);
14940 timer=GetMagickTime()+(delay == 0 ? 1 : delay)+1;
14942 if (resource_info->update != MagickFalse)
14950 status=GetPathAttributes(display_image->filename,&attributes);
14951 if (status != MagickFalse)
14952 update_time=attributes.st_mtime;
14954 *state&=(~FormerImageState);
14955 *state&=(~MontageImageState);
14956 *state&=(~NextImageState);
14962 if (windows->image.mapped != MagickFalse)
14963 if ((display_image->delay != 0) || (resource_info->update != 0))
14965 if (timer < GetMagickTime())
14967 if (resource_info->update == MagickFalse)
14968 *state|=NextImageState | ExitState;
14977 status=GetPathAttributes(display_image->filename,&attributes);
14978 if (status != MagickFalse)
14979 if (update_time != attributes.st_mtime)
14984 (void) FormatLocaleString(
14985 resource_info->image_info->filename,MaxTextExtent,
14986 "%s:%s",display_image->magick,
14987 display_image->filename);
14988 nexus=ReadImage(resource_info->image_info,
14989 &display_image->exception);
14990 if (nexus != (
Image *) NULL)
14991 *state|=NextImageState | ExitState;
14993 delay=display_image->delay/MagickMax(
14994 display_image->ticks_per_second,1L);
14995 timer=GetMagickTime()+(delay == 0 ? 1 : delay)+1;
14998 if (XEventsQueued(display,QueuedAfterFlush) == 0)
15003 XDelay(display,SuspendTime << 2);
15007 timestamp=GetMagickTime();
15008 (void) XNextEvent(display,&event);
15009 if (windows->image.stasis == MagickFalse)
15010 windows->image.stasis=(GetMagickTime()-timestamp) > 0 ?
15011 MagickTrue : MagickFalse;
15012 if (windows->magnify.stasis == MagickFalse)
15013 windows->magnify.stasis=(GetMagickTime()-timestamp) > 0 ?
15014 MagickTrue : MagickFalse;
15015 if (event.xany.window == windows->command.id)
15020 id=XCommandWidget(display,windows,CommandMenu,&event);
15023 (void) CopyMagickString(command,CommandMenu[
id],MaxTextExtent);
15024 command_type=CommandMenus[id];
15025 if (
id < MagickMenus)
15030 entry=XMenuWidget(display,windows,CommandMenu[
id],Menus[
id],
15034 (void) CopyMagickString(command,Menus[
id][entry],MaxTextExtent);
15035 command_type=Commands[id][entry];
15037 if (command_type != NullCommand)
15038 nexus=XMagickCommand(display,resource_info,windows,command_type,
15042 switch (event.type)
15046 if (resource_info->debug != MagickFalse)
15047 (void) LogMagickEvent(X11Event,GetMagickModule(),
15048 "Button Press: 0x%lx %u +%d+%d",
event.xbutton.window,
15049 event.xbutton.button,
event.xbutton.x,
event.xbutton.y);
15050 if ((event.xbutton.button == Button3) &&
15051 (
event.xbutton.state & Mod1Mask))
15056 event.xbutton.button=Button2;
15057 event.xbutton.state&=(~Mod1Mask);
15059 if (event.xbutton.window == windows->backdrop.id)
15061 (void) XSetInputFocus(display,event.xbutton.window,RevertToParent,
15062 event.xbutton.time);
15065 if (event.xbutton.window == windows->image.id)
15067 switch (event.xbutton.button)
15071 if (resource_info->immutable)
15076 entry=XMenuWidget(display,windows,
"Commands",VirtualMenu,
15079 nexus=XMagickCommand(display,resource_info,windows,
15080 VirtualCommands[entry],&display_image);
15086 if (windows->command.mapped != MagickFalse)
15087 (void) XWithdrawWindow(display,windows->command.id,
15088 windows->command.screen);
15091 (void) XCommandWidget(display,windows,CommandMenu,
15093 (void) XMapRaised(display,windows->command.id);
15102 (void) XMagickCommand(display,resource_info,windows,ZoomCommand,
15104 XMagnifyImage(display,windows,&event);
15109 if (resource_info->immutable)
15114 entry=XMenuWidget(display,windows,
"Commands",VirtualMenu,
15117 nexus=XMagickCommand(display,resource_info,windows,
15118 VirtualCommands[entry],&display_image);
15121 if (display_image->montage != (
char *) NULL)
15126 nexus=XTileImage(display,resource_info,windows,
15127 display_image,&event);
15128 if (nexus != (
Image *) NULL)
15129 *state|=MontageImageState | NextImageState | ExitState;
15130 vid_info.x=(
short int) windows->image.x;
15131 vid_info.y=(
short int) windows->image.y;
15137 entry=XMenuWidget(display,windows,
"Short Cuts",ShortCutsMenu,
15140 nexus=XMagickCommand(display,resource_info,windows,
15141 ShortCutsCommands[entry],&display_image);
15149 XTranslateImage(display,windows,*image,XK_Up);
15157 XTranslateImage(display,windows,*image,XK_Down);
15165 if (event.xbutton.window == windows->magnify.id)
15168 *
const MagnifyMenu[] =
15185 MagnifyCommands[] =
15200 factor=XMenuWidget(display,windows,
"Magnify",MagnifyMenu,command);
15202 XMagnifyWindowCommand(display,windows,0,MagnifyCommands[factor]);
15205 if (event.xbutton.window == windows->pan.id)
15207 switch (event.xbutton.button)
15214 XTranslateImage(display,windows,*image,XK_Up);
15222 XTranslateImage(display,windows,*image,XK_Down);
15227 XPanImage(display,windows,&event);
15233 delay=display_image->delay/MagickMax(display_image->ticks_per_second,
15235 timer=GetMagickTime()+(delay == 0 ? 1 : delay)+1;
15238 case ButtonRelease:
15240 if (resource_info->debug != MagickFalse)
15241 (void) LogMagickEvent(X11Event,GetMagickModule(),
15242 "Button Release: 0x%lx %u +%d+%d",
event.xbutton.window,
15243 event.xbutton.button,
event.xbutton.x,
event.xbutton.y);
15246 case ClientMessage:
15248 if (resource_info->debug != MagickFalse)
15249 (void) LogMagickEvent(X11Event,GetMagickModule(),
15250 "Client Message: 0x%lx 0x%lx %d 0x%lx",
event.xclient.window,
15251 event.xclient.message_type,
event.xclient.format,(
unsigned long)
15252 event.xclient.data.l[0]);
15253 if (event.xclient.message_type == windows->im_protocols)
15255 if (*event.xclient.data.l == (
long) windows->im_update_widget)
15257 (void) CloneString(&windows->command.name,MagickTitle);
15258 windows->command.data=MagickMenus;
15259 (void) XCommandWidget(display,windows,CommandMenu,
15263 if (*event.xclient.data.l == (
long) windows->im_update_colormap)
15268 for (i=0; i < (int) number_windows; i++)
15270 if (magick_windows[i]->
id == windows->icon.id)
15272 context_values.background=pixel->background_color.pixel;
15273 context_values.foreground=pixel->foreground_color.pixel;
15274 (void) XChangeGC(display,magick_windows[i]->annotate_context,
15275 context_mask,&context_values);
15276 (void) XChangeGC(display,magick_windows[i]->widget_context,
15277 context_mask,&context_values);
15278 context_values.background=pixel->foreground_color.pixel;
15279 context_values.foreground=pixel->background_color.pixel;
15280 context_values.plane_mask=context_values.background ^
15281 context_values.foreground;
15282 (void) XChangeGC(display,magick_windows[i]->highlight_context,
15283 (
size_t) (context_mask | GCPlaneMask),
15285 magick_windows[i]->attributes.background_pixel=
15286 pixel->background_color.pixel;
15287 magick_windows[i]->attributes.border_pixel=
15288 pixel->border_color.pixel;
15289 magick_windows[i]->attributes.colormap=map_info->colormap;
15290 (void) XChangeWindowAttributes(display,magick_windows[i]->
id,
15291 (
unsigned long) magick_windows[i]->mask,
15292 &magick_windows[i]->attributes);
15294 if (windows->pan.mapped != MagickFalse)
15296 (void) XSetWindowBackgroundPixmap(display,windows->pan.id,
15297 windows->pan.pixmap);
15298 (void) XClearWindow(display,windows->pan.id);
15299 XDrawPanRectangle(display,windows);
15301 if (windows->backdrop.id != (Window) NULL)
15302 (void) XInstallColormap(display,map_info->colormap);
15305 if (*event.xclient.data.l == (
long) windows->im_former_image)
15307 *state|=FormerImageState | ExitState;
15310 if (*event.xclient.data.l == (
long) windows->im_next_image)
15312 *state|=NextImageState | ExitState;
15315 if (*event.xclient.data.l == (
long) windows->im_retain_colors)
15317 *state|=RetainColorsState;
15320 if (*event.xclient.data.l == (
long) windows->im_exit)
15327 if (event.xclient.message_type == windows->dnd_protocols)
15347 if ((*event.xclient.data.l != 2) && (*
event.xclient.data.l != 128))
15349 selection=XInternAtom(display,
"DndSelection",MagickFalse);
15350 status=XGetWindowProperty(display,root_window,selection,0L,(
long)
15351 MaxTextExtent,MagickFalse,(Atom) AnyPropertyType,&type,&format,
15352 &length,&after,&data);
15353 if ((status != Success) || (length == 0))
15355 if (*event.xclient.data.l == 2)
15360 (void) CopyMagickString(resource_info->image_info->filename,
15361 (
char *) data,MaxTextExtent);
15368 if (strncmp((
char *) data,
"file:", 5) != 0)
15370 (void) XFree((
void *) data);
15373 (void) CopyMagickString(resource_info->image_info->filename,
15374 ((
char *) data)+5,MaxTextExtent);
15376 nexus=ReadImage(resource_info->image_info,
15377 &display_image->exception);
15378 CatchException(&display_image->exception);
15379 if (nexus != (
Image *) NULL)
15380 *state|=NextImageState | ExitState;
15381 (void) XFree((
void *) data);
15387 if (event.xclient.message_type != windows->wm_protocols)
15389 if (*event.xclient.data.l != (
long) windows->wm_delete_window)
15391 (void) XWithdrawWindow(display,event.xclient.window,
15392 visual_info->screen);
15393 if (event.xclient.window == windows->image.id)
15398 if (event.xclient.window == windows->pan.id)
15403 windows->image.window_changes.width=windows->image.ximage->width;
15404 windows->image.window_changes.height=windows->image.ximage->height;
15405 (void) XConfigureImage(display,resource_info,windows,
15410 case ConfigureNotify:
15412 if (resource_info->debug != MagickFalse)
15413 (void) LogMagickEvent(X11Event,GetMagickModule(),
15414 "Configure Notify: 0x%lx %dx%d+%d+%d %d",
event.xconfigure.window,
15415 event.xconfigure.width,
event.xconfigure.height,
event.xconfigure.x,
15416 event.xconfigure.y,
event.xconfigure.send_event);
15417 if (event.xconfigure.window == windows->image.id)
15422 if (event.xconfigure.send_event != 0)
15430 if (windows->command.geometry == (
char *) NULL)
15431 if (windows->command.mapped == MagickFalse)
15433 windows->command.x=
event.xconfigure.x-
15434 windows->command.width-25;
15435 windows->command.y=
event.xconfigure.y;
15436 XConstrainWindowPosition(display,&windows->command);
15437 window_changes.x=windows->command.x;
15438 window_changes.y=windows->command.y;
15439 (void) XReconfigureWMWindow(display,windows->command.id,
15440 windows->command.screen,(
unsigned int) (CWX | CWY),
15443 if (windows->widget.geometry == (
char *) NULL)
15444 if (windows->widget.mapped == MagickFalse)
15446 windows->widget.x=
event.xconfigure.x+
15447 event.xconfigure.width/10;
15448 windows->widget.y=
event.xconfigure.y+
15449 event.xconfigure.height/10;
15450 XConstrainWindowPosition(display,&windows->widget);
15451 window_changes.x=windows->widget.x;
15452 window_changes.y=windows->widget.y;
15453 (void) XReconfigureWMWindow(display,windows->widget.id,
15454 windows->widget.screen,(
unsigned int) (CWX | CWY),
15457 if (windows->magnify.geometry == (
char *) NULL)
15458 if (windows->magnify.mapped == MagickFalse)
15460 windows->magnify.x=
event.xconfigure.x+
15461 event.xconfigure.width+25;
15462 windows->magnify.y=
event.xconfigure.y;
15463 XConstrainWindowPosition(display,&windows->magnify);
15464 window_changes.x=windows->magnify.x;
15465 window_changes.y=windows->magnify.y;
15466 (void) XReconfigureWMWindow(display,windows->magnify.id,
15467 windows->magnify.screen,(
unsigned int) (CWX | CWY),
15470 if (windows->pan.geometry == (
char *) NULL)
15471 if (windows->pan.mapped == MagickFalse)
15473 windows->pan.x=
event.xconfigure.x+
15474 event.xconfigure.width+25;
15475 windows->pan.y=
event.xconfigure.y+
15476 windows->magnify.height+50;
15477 XConstrainWindowPosition(display,&windows->pan);
15478 window_changes.x=windows->pan.x;
15479 window_changes.y=windows->pan.y;
15480 (void) XReconfigureWMWindow(display,windows->pan.id,
15481 windows->pan.screen,(
unsigned int) (CWX | CWY),
15485 if ((event.xconfigure.width == (
int) windows->image.width) &&
15486 (event.xconfigure.height == (
int) windows->image.height))
15488 windows->image.width=(
unsigned int) event.xconfigure.width;
15489 windows->image.height=(
unsigned int)
event.xconfigure.height;
15490 windows->image.x=0;
15491 windows->image.y=0;
15492 if (display_image->montage != (
char *) NULL)
15494 windows->image.x=vid_info.x;
15495 windows->image.y=vid_info.y;
15497 if ((windows->image.mapped != MagickFalse) &&
15498 (windows->image.stasis != MagickFalse))
15503 windows->image.window_changes.width=
event.xconfigure.width;
15504 windows->image.window_changes.height=
event.xconfigure.height;
15505 (void) XConfigureImage(display,resource_info,windows,
15511 if ((event.xconfigure.width < windows->image.ximage->width) ||
15512 (
event.xconfigure.height < windows->image.ximage->height))
15514 (void) XMapRaised(display,windows->pan.id);
15515 XDrawPanRectangle(display,windows);
15518 if (windows->pan.mapped != MagickFalse)
15519 (void) XWithdrawWindow(display,windows->pan.id,
15520 windows->pan.screen);
15523 if (event.xconfigure.window == windows->magnify.id)
15531 windows->magnify.width=(
unsigned int) event.xconfigure.width;
15532 windows->magnify.height=(
unsigned int)
event.xconfigure.height;
15533 if (windows->magnify.mapped == MagickFalse)
15536 while ((
int) magnify <=
event.xconfigure.width)
15538 while ((
int) magnify <=
event.xconfigure.height)
15541 if (((
int) magnify !=
event.xconfigure.width) ||
15542 ((
int) magnify !=
event.xconfigure.height))
15544 window_changes.width=(int) magnify;
15545 window_changes.height=(int) magnify;
15546 (void) XReconfigureWMWindow(display,windows->magnify.id,
15547 windows->magnify.screen,(
unsigned int) (CWWidth | CWHeight),
15551 if ((windows->magnify.mapped != MagickFalse) &&
15552 (windows->magnify.stasis != MagickFalse))
15554 status=XMakeImage(display,resource_info,&windows->magnify,
15555 display_image,windows->magnify.width,windows->magnify.height);
15556 XMakeMagnifyImage(display,windows);
15560 if ((windows->magnify.mapped != MagickFalse) &&
15561 (event.xconfigure.window == windows->pan.id))
15566 if (event.xconfigure.send_event != 0)
15568 windows->pan.x=
event.xconfigure.x;
15569 windows->pan.y=
event.xconfigure.y;
15571 windows->pan.width=(
unsigned int) event.xconfigure.width;
15572 windows->pan.height=(
unsigned int)
event.xconfigure.height;
15575 if (event.xconfigure.window == windows->icon.id)
15580 windows->icon.width=(
unsigned int) event.xconfigure.width;
15581 windows->icon.height=(
unsigned int)
event.xconfigure.height;
15586 case DestroyNotify:
15591 if (resource_info->debug != MagickFalse)
15592 (void) LogMagickEvent(X11Event,GetMagickModule(),
15593 "Destroy Notify: 0x%lx",
event.xdestroywindow.window);
15594 if (event.xdestroywindow.window == windows->group_leader.id)
15606 if (map_info->colormap != XDefaultColormap(display,visual_info->screen))
15607 if (event.xcrossing.mode != NotifyUngrab)
15608 XInstallColormap(display,map_info->colormap);
15613 if (resource_info->debug != MagickFalse)
15614 (void) LogMagickEvent(X11Event,GetMagickModule(),
15615 "Expose: 0x%lx %dx%d+%d+%d",
event.xexpose.window,
15616 event.xexpose.width,
event.xexpose.height,
event.xexpose.x,
15621 if ((event.xexpose.window == windows->image.id) &&
15622 (windows->image.mapped != MagickFalse))
15624 XRefreshWindow(display,&windows->image,&event);
15625 delay=display_image->delay/MagickMax(
15626 display_image->ticks_per_second,1L);
15627 timer=GetMagickTime()+(delay == 0 ? 1 : delay)+1;
15630 if ((event.xexpose.window == windows->magnify.id) &&
15631 (windows->magnify.mapped != MagickFalse))
15633 XMakeMagnifyImage(display,windows);
15636 if (event.xexpose.window == windows->pan.id)
15638 XDrawPanRectangle(display,windows);
15641 if (event.xexpose.window == windows->icon.id)
15643 XRefreshWindow(display,&windows->icon,&event);
15656 length=XLookupString((XKeyEvent *) &event.xkey,command,(
int)
15657 sizeof(command),&key_symbol,(XComposeStatus *) NULL);
15658 *(command+length)=
'\0';
15659 if (resource_info->debug != MagickFalse)
15660 (void) LogMagickEvent(X11Event,GetMagickModule(),
15661 "Key press: %d 0x%lx (%s)",
event.xkey.state,(
unsigned long)
15662 key_symbol,command);
15663 if (event.xkey.window == windows->image.id)
15665 command_type=XImageWindowCommand(display,resource_info,windows,
15666 event.xkey.state,key_symbol,&display_image);
15667 if (command_type != NullCommand)
15668 nexus=XMagickCommand(display,resource_info,windows,command_type,
15671 if (event.xkey.window == windows->magnify.id)
15672 XMagnifyWindowCommand(display,windows,event.xkey.state,key_symbol);
15673 if (event.xkey.window == windows->pan.id)
15675 if ((key_symbol == XK_q) || (key_symbol == XK_Escape))
15676 (void) XWithdrawWindow(display,windows->pan.id,
15677 windows->pan.screen);
15679 if ((key_symbol == XK_F1) || (key_symbol == XK_Help))
15680 XTextViewHelp(display,resource_info,windows,MagickFalse,
15681 "Help Viewer - Image Pan",ImagePanHelp);
15683 XTranslateImage(display,windows,*image,key_symbol);
15685 delay=display_image->delay/MagickMax(
15686 display_image->ticks_per_second,1L);
15687 timer=GetMagickTime()+(delay == 0 ? 1 : delay)+1;
15695 (void) XLookupString((XKeyEvent *) &
event.xkey,command,(int)
15696 sizeof(command),&key_symbol,(XComposeStatus *) NULL);
15697 if (resource_info->debug != MagickFalse)
15698 (void) LogMagickEvent(X11Event,GetMagickModule(),
15699 "Key release: 0x%lx (%c)",(
unsigned long) key_symbol,*command);
15707 if (map_info->colormap != XDefaultColormap(display,visual_info->screen))
15708 if (event.xcrossing.mode != NotifyUngrab)
15709 XUninstallColormap(display,map_info->colormap);
15714 if (resource_info->debug != MagickFalse)
15715 (void) LogMagickEvent(X11Event,GetMagickModule(),
"Map Notify: 0x%lx",
15716 event.xmap.window);
15717 if (event.xmap.window == windows->backdrop.id)
15719 (void) XSetInputFocus(display,event.xmap.window,RevertToParent,
15721 windows->backdrop.mapped=MagickTrue;
15724 if (event.xmap.window == windows->image.id)
15726 if (windows->backdrop.id != (Window) NULL)
15727 (
void) XInstallColormap(display,map_info->colormap);
15728 if (LocaleCompare(display_image->magick,
"LOGO") == 0)
15730 if (LocaleCompare(display_image->filename,
"LOGO") == 0)
15731 nexus=XOpenImage(display,resource_info,windows,MagickFalse);
15733 if (((
int) windows->image.width < windows->image.ximage->width) ||
15734 ((
int) windows->image.height < windows->image.ximage->height))
15735 (void) XMapRaised(display,windows->pan.id);
15736 windows->image.mapped=MagickTrue;
15739 if (event.xmap.window == windows->magnify.id)
15741 XMakeMagnifyImage(display,windows);
15742 windows->magnify.mapped=MagickTrue;
15743 (void) XWithdrawWindow(display,windows->info.id,
15744 windows->info.screen);
15747 if (event.xmap.window == windows->pan.id)
15749 XMakePanImage(display,resource_info,windows,display_image);
15750 windows->pan.mapped=MagickTrue;
15753 if (event.xmap.window == windows->info.id)
15755 windows->info.mapped=MagickTrue;
15758 if (event.xmap.window == windows->icon.id)
15766 taint=display_image->taint;
15767 XMakeStandardColormap(display,icon_visual,icon_resources,
15768 display_image,icon_map,icon_pixel);
15769 (void) XMakeImage(display,icon_resources,&windows->icon,
15770 display_image,windows->icon.width,windows->icon.height);
15771 display_image->taint=taint;
15772 (void) XSetWindowBackgroundPixmap(display,windows->icon.id,
15773 windows->icon.pixmap);
15774 (void) XClearWindow(display,windows->icon.id);
15775 (void) XWithdrawWindow(display,windows->info.id,
15776 windows->info.screen);
15777 windows->icon.mapped=MagickTrue;
15780 if (event.xmap.window == windows->command.id)
15782 windows->command.mapped=MagickTrue;
15785 if (event.xmap.window == windows->popup.id)
15787 windows->popup.mapped=MagickTrue;
15790 if (event.xmap.window == windows->widget.id)
15792 windows->widget.mapped=MagickTrue;
15797 case MappingNotify:
15799 (void) XRefreshKeyboardMapping(&event.xmapping);
15804 case PropertyNotify:
15820 if (resource_info->debug != MagickFalse)
15821 (void) LogMagickEvent(X11Event,GetMagickModule(),
15822 "Property Notify: 0x%lx 0x%lx %d",
event.xproperty.window,
15823 event.xproperty.atom,
event.xproperty.state);
15824 if (event.xproperty.atom != windows->im_remote_command)
15829 status=XGetWindowProperty(display,event.xproperty.window,
15830 event.xproperty.atom,0L,(
long) MaxTextExtent,MagickFalse,(Atom)
15831 AnyPropertyType,&type,&format,&length,&after,&data);
15832 if ((status != Success) || (length == 0))
15834 if (LocaleCompare((
char *) data,
"-quit") == 0)
15836 XClientMessage(display,windows->image.id,windows->im_protocols,
15837 windows->im_exit,CurrentTime);
15838 (void) XFree((
void *) data);
15841 (void) CopyMagickString(resource_info->image_info->filename,
15842 (
char *) data,MaxTextExtent);
15843 (void) XFree((
void *) data);
15844 nexus=ReadImage(resource_info->image_info,&display_image->exception);
15845 CatchException(&display_image->exception);
15846 if (nexus != (
Image *) NULL)
15847 *state|=NextImageState | ExitState;
15850 case ReparentNotify:
15852 if (resource_info->debug != MagickFalse)
15853 (void) LogMagickEvent(X11Event,GetMagickModule(),
15854 "Reparent Notify: 0x%lx=>0x%lx",
event.xreparent.parent,
15855 event.xreparent.window);
15860 if (resource_info->debug != MagickFalse)
15861 (void) LogMagickEvent(X11Event,GetMagickModule(),
15862 "Unmap Notify: 0x%lx",
event.xunmap.window);
15863 if (event.xunmap.window == windows->backdrop.id)
15865 windows->backdrop.mapped=MagickFalse;
15868 if (event.xunmap.window == windows->image.id)
15870 windows->image.mapped=MagickFalse;
15873 if (event.xunmap.window == windows->magnify.id)
15875 windows->magnify.mapped=MagickFalse;
15878 if (event.xunmap.window == windows->pan.id)
15880 windows->pan.mapped=MagickFalse;
15883 if (event.xunmap.window == windows->info.id)
15885 windows->info.mapped=MagickFalse;
15888 if (event.xunmap.window == windows->icon.id)
15890 if (map_info->colormap == icon_map->colormap)
15891 XConfigureImageColormap(display,resource_info,windows,
15893 (void) XFreeStandardColormap(display,icon_visual,icon_map,
15895 windows->icon.mapped=MagickFalse;
15898 if (event.xunmap.window == windows->command.id)
15900 windows->command.mapped=MagickFalse;
15903 if (event.xunmap.window == windows->popup.id)
15905 if (windows->backdrop.id != (Window) NULL)
15906 (
void) XSetInputFocus(display,windows->image.id,RevertToParent,
15908 windows->popup.mapped=MagickFalse;
15911 if (event.xunmap.window == windows->widget.id)
15913 if (windows->backdrop.id != (Window) NULL)
15914 (void) XSetInputFocus(display,windows->image.id,RevertToParent,
15916 windows->widget.mapped=MagickFalse;
15923 if (resource_info->debug != MagickFalse)
15924 (void) LogMagickEvent(X11Event,GetMagickModule(),
"Event type: %d",
15929 }
while (!(*state & ExitState));
15930 if ((*state & ExitState) == 0)
15931 (
void) XMagickCommand(display,resource_info,windows,FreeBuffersCommand,
15934 if (resource_info->confirm_edit != MagickFalse)
15939 if ((resource_info->immutable == MagickFalse) &&
15940 (display_image->taint != MagickFalse))
15945 status=XConfirmWidget(display,windows,
"Your image changed.",
15946 "Do you want to save it");
15948 *state&=(~ExitState);
15951 (void) XMagickCommand(display,resource_info,windows,SaveCommand,
15955 if ((windows->visual_info->klass == GrayScale) ||
15956 (windows->visual_info->klass == PseudoColor) ||
15957 (windows->visual_info->klass == DirectColor))
15962 if (windows->info.mapped != MagickFalse)
15963 (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
15964 if (windows->magnify.mapped != MagickFalse)
15965 (void) XWithdrawWindow(display,windows->magnify.id,
15966 windows->magnify.screen);
15967 if (windows->command.mapped != MagickFalse)
15968 (void) XWithdrawWindow(display,windows->command.id,
15969 windows->command.screen);
15971 if (windows->pan.mapped != MagickFalse)
15972 (void) XWithdrawWindow(display,windows->pan.id,windows->pan.screen);
15973 if (resource_info->backdrop == MagickFalse)
15974 if (windows->backdrop.mapped)
15976 (void) XWithdrawWindow(display,windows->backdrop.id,
15977 windows->backdrop.screen);
15978 (void) XDestroyWindow(display,windows->backdrop.id);
15979 windows->backdrop.id=(Window) NULL;
15980 (void) XWithdrawWindow(display,windows->image.id,
15981 windows->image.screen);
15982 (void) XDestroyWindow(display,windows->image.id);
15983 windows->image.id=(Window) NULL;
15985 XSetCursorState(display,windows,MagickTrue);
15986 XCheckRefreshWindows(display,windows);
15987 if (((*state & FormerImageState) != 0) || ((*state & NextImageState) != 0))
15988 *state&=(~ExitState);
15989 if (*state & ExitState)
15994 (void) XFreeStandardColormap(display,icon_visual,icon_map,icon_pixel);
15995 if (resource_info->map_type == (
char *) NULL)
15996 (
void) XFreeStandardColormap(display,visual_info,map_info,pixel);
16000 if (resource_info->copy_image != (
Image *) NULL)
16001 resource_info->copy_image=DestroyImage(resource_info->copy_image);
16002 DestroyXResources();
16004 (void) XSync(display,MagickFalse);
16008 (void) SetErrorHandler(warning_handler);
16009 (void) SetWarningHandler(warning_handler);
16013 directory=getcwd(working_directory,MaxTextExtent);
16019 if (*resource_info->home_directory ==
'\0')
16020 (void) CopyMagickString(resource_info->home_directory,
".",MaxTextExtent);
16021 status=chdir(resource_info->home_directory);
16023 (void) ThrowMagickException(&display_image->exception,GetMagickModule(),
16024 FileOpenError,
"UnableToOpenFile",
"%s",resource_info->home_directory);
16026 *image=display_image;
16058 MagickExport MagickBooleanType DisplayImages(
const ImageInfo *image_info,
16061 assert(image_info != (
const ImageInfo *) NULL);
16062 assert(image_info->signature == MagickCoreSignature);
16063 assert(image != (
Image *) NULL);
16064 assert(image->signature == MagickCoreSignature);
16065 if (IsEventLogging() != MagickFalse)
16066 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
16068 (void) ThrowMagickException(&image->exception,GetMagickModule(),
16069 MissingDelegateError,
"DelegateLibrarySupportNotBuiltIn",
"`%s' (X11)",
16071 return(MagickFalse);
16104 MagickExport MagickBooleanType RemoteDisplayCommand(
const ImageInfo *image_info,
16105 const char *window,
const char *filename,
ExceptionInfo *exception)
16107 assert(image_info != (
const ImageInfo *) NULL);
16108 assert(image_info->signature == MagickCoreSignature);
16109 assert(filename != (
char *) NULL);
16110 if (IsEventLogging() != MagickFalse)
16111 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",filename);
16113 (void) ThrowMagickException(exception,GetMagickModule(),MissingDelegateError,
16114 "DelegateLibrarySupportNotBuiltIn",
"`%s' (X11)",image_info->filename);
16115 return(MagickFalse);