2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7 % W W IIIII DDDD GGGG EEEEE TTTTT %
9 % W W W I D D G GG EEE T %
10 % WW WW I D D G G E T %
11 % W W IIIII DDDD GGGG EEEEE T %
14 % MagickCore X11 User Interface Methods %
21 % Copyright 1999-2010 ImageMagick Studio LLC, a non-profit organization %
22 % dedicated to making software imaging solutions freely available. %
24 % You may not use this file except in compliance with the License. You may %
25 % obtain a copy of the License at %
27 % http://www.imagemagick.org/script/license.php %
29 % Unless required by applicable law or agreed to in writing, software %
30 % distributed under the License is distributed on an "AS IS" BASIS, %
31 % WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %
32 % See the License for the specific language governing permissions and %
33 % limitations under the License. %
35 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
43 #include "magick/studio.h"
44 #include "magick/color.h"
45 #include "magick/color-private.h"
46 #include "magick/exception.h"
47 #include "magick/exception-private.h"
48 #include "magick/image.h"
49 #include "magick/magick.h"
50 #include "magick/memory_.h"
51 #include "magick/PreRvIcccm.h"
52 #include "magick/string_.h"
53 #include "magick/token.h"
54 #include "magick/utility.h"
55 #include "magick/xwindow-private.h"
56 #include "magick/widget.h"
58 #if defined(MAGICKCORE_X11_DELEGATE)
63 #define AreaIsActive(matte_info,position) ( \
64 ((position.y >= (int) (matte_info.y-matte_info.bevel_width)) && \
65 (position.y < (int) (matte_info.y+matte_info.height+matte_info.bevel_width))) \
66 ? MagickTrue : MagickFalse)
67 #define Extent(s) ((int) strlen(s))
68 #define MatteIsActive(matte_info,position) ( \
69 ((position.x >= (int) (matte_info.x-matte_info.bevel_width)) && \
70 (position.y >= (int) (matte_info.y-matte_info.bevel_width)) && \
71 (position.x < (int) (matte_info.x+matte_info.width+matte_info.bevel_width)) && \
72 (position.y < (int) (matte_info.y+matte_info.height+matte_info.bevel_width))) \
73 ? MagickTrue : MagickFalse)
74 #define MaxTextWidth ((unsigned int) (255*XTextWidth(font_info,"_",1)))
75 #define MinTextWidth (26*XTextWidth(font_info,"_",1))
76 #define QuantumMargin MagickMax(font_info->max_bounds.width,12)
77 #define WidgetTextWidth(font_info,text) \
78 ((unsigned int) XTextWidth(font_info,text,Extent(text)))
79 #define WindowIsActive(window_info,position) ( \
80 ((position.x >= 0) && (position.y >= 0) && \
81 (position.x < (int) window_info.width) && \
82 (position.y < (int) window_info.height)) ? MagickTrue : MagickFalse)
89 ControlState = 0x0001,
90 InactiveWidgetState = 0x0004,
91 JumpListState = 0x0008,
92 RedrawActionState = 0x0010,
93 RedrawListState = 0x0020,
94 RedrawWidgetState = 0x0040,
95 UpdateListState = 0x0100
101 typedef struct _XWidgetInfo
131 Variable declarations.
136 (char *) NULL, (char *) NULL, (char *) NULL, 0, 0, 0, 0, 0, 0, 0, 0,
137 MagickFalse, MagickFalse, MagickFalse, MagickFalse, MagickFalse
141 (char *) NULL, (char *) NULL, (char *) NULL, 0, 0, 0, 0, 0, 0, 0, 0,
142 MagickFalse, MagickFalse, MagickFalse, MagickFalse, MagickFalse
144 *selection_info = (XWidgetInfo *) NULL,
147 (char *) NULL, (char *) NULL, (char *) NULL, 0, 0, 0, 0, 0, 0, 0, 0,
148 MagickFalse, MagickFalse, MagickFalse, MagickFalse, MagickFalse
152 Constant declarations.
162 XDrawMatte(Display *,const XWindowInfo *,const XWidgetInfo *),
163 XSetBevelColor(Display *,const XWindowInfo *,const MagickStatusType),
164 XSetMatteColor(Display *,const XWindowInfo *,const MagickStatusType),
165 XSetTextColor(Display *,const XWindowInfo *,const MagickStatusType);
168 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
172 % D e s t r o y X W i d g e t %
176 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
178 % DestroyXWidget() destroys resources associated with the X widget.
180 % The format of the DestroyXWidget method is:
182 % void DestroyXWidget()
184 % A description of each parameter follows:
187 MagickExport void DestroyXWidget(void)
189 if (selection_info != (XWidgetInfo *) NULL)
190 selection_info=(XWidgetInfo *) RelinquishMagickMemory(selection_info);
194 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
198 + X D r a w B e v e l %
202 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
204 % XDrawBevel() "sets off" an area with a highlighted upper and left bevel and
205 % a shadowed lower and right bevel. The highlighted and shadowed bevels
206 % create a 3-D effect.
208 % The format of the XDrawBevel function is:
210 % XDrawBevel(display,window_info,bevel_info)
212 % A description of each parameter follows:
214 % o display: Specifies a pointer to the Display structure; returned from
217 % o window_info: Specifies a pointer to a X11 XWindowInfo structure.
219 % o bevel_info: Specifies a pointer to a XWidgetInfo structure. It
220 % contains the extents of the bevel.
223 static void XDrawBevel(Display *display,const XWindowInfo *window_info,
224 const XWidgetInfo *bevel_info)
239 Draw upper and left beveled border.
242 y1=bevel_info->y+bevel_info->height;
243 x2=bevel_info->x+bevel_info->width;
245 bevel_width=bevel_info->bevel_width;
252 points[3].x=x2+bevel_width;
253 points[3].y=y2-bevel_width;
254 points[4].x=x1-bevel_width;
255 points[4].y=y2-bevel_width;
256 points[5].x=x1-bevel_width;
257 points[5].y=y1+bevel_width;
258 XSetBevelColor(display,window_info,bevel_info->raised);
259 (void) XFillPolygon(display,window_info->id,window_info->widget_context,
260 points,6,Complex,CoordModeOrigin);
262 Draw lower and right beveled border.
270 points[3].x=x2+bevel_width;
271 points[3].y=y2-bevel_width;
272 points[4].x=x2+bevel_width;
273 points[4].y=y1+bevel_width;
274 points[5].x=x1-bevel_width;
275 points[5].y=y1+bevel_width;
276 XSetBevelColor(display,window_info,!bevel_info->raised);
277 (void) XFillPolygon(display,window_info->id,window_info->widget_context,
278 points,6,Complex,CoordModeOrigin);
279 (void) XSetFillStyle(display,window_info->widget_context,FillSolid);
283 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
287 + X D r a w B e v e l e d B u t t o n %
291 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
293 % XDrawBeveledButton() draws a button with a highlighted upper and left bevel
294 % and a shadowed lower and right bevel. The highlighted and shadowed bevels
295 % create a 3-D effect.
297 % The format of the XDrawBeveledButton function is:
299 % XDrawBeveledButton(display,window_info,button_info)
301 % A description of each parameter follows:
303 % o display: Specifies a pointer to the Display structure; returned from
306 % o window_info: Specifies a pointer to a X11 XWindowInfo structure.
308 % o button_info: Specifies a pointer to a XWidgetInfo structure. It
309 % contains the extents of the button.
313 static inline int MagickAbsoluteValue(const int x)
320 static inline int MagickMax(const int x,const int y)
327 static inline int MagickMin(const int x,const int y)
334 static void XDrawBeveledButton(Display *display,const XWindowInfo *window_info,
335 const XWidgetInfo *button_info)
353 XDrawBevel(display,window_info,button_info);
354 XSetMatteColor(display,window_info,button_info->raised);
355 (void) XFillRectangle(display,window_info->id,window_info->widget_context,
356 button_info->x,button_info->y,button_info->width,button_info->height);
357 x=button_info->x-button_info->bevel_width-1;
358 y=button_info->y-button_info->bevel_width-1;
359 (void) XSetForeground(display,window_info->widget_context,
360 window_info->pixel_info->trough_color.pixel);
361 if (button_info->raised || (window_info->depth == 1))
362 (void) XDrawRectangle(display,window_info->id,window_info->widget_context,
363 x,y,button_info->width+(button_info->bevel_width << 1)+1,
364 button_info->height+(button_info->bevel_width << 1)+1);
365 if (button_info->text == (char *) NULL)
370 crop_info.width=(unsigned short) button_info->width;
371 crop_info.height=(unsigned short) button_info->height;
372 crop_info.x=button_info->x;
373 crop_info.y=button_info->y;
377 font_info=window_info->font_info;
378 width=WidgetTextWidth(font_info,button_info->text);
379 x=button_info->x+(QuantumMargin >> 1);
380 if (button_info->center)
381 x=button_info->x+(button_info->width >> 1)-(width >> 1);
382 y=button_info->y+((button_info->height-
383 (font_info->ascent+font_info->descent)) >> 1)+font_info->ascent;
384 if ((int) button_info->width == (QuantumMargin >> 1))
387 Option button-- write label to right of button.
389 XSetTextColor(display,window_info,MagickTrue);
390 x=button_info->x+button_info->width+button_info->bevel_width+
391 (QuantumMargin >> 1);
392 (void) XDrawString(display,window_info->id,window_info->widget_context,
393 x,y,button_info->text,Extent(button_info->text));
396 (void) XSetClipRectangles(display,window_info->widget_context,0,0,&crop_info,
398 XSetTextColor(display,window_info,button_info->raised);
399 (void) XDrawString(display,window_info->id,window_info->widget_context,x,y,
400 button_info->text,Extent(button_info->text));
401 (void) XSetClipMask(display,window_info->widget_context,None);
402 if (button_info->raised == MagickFalse)
403 XDelay(display,SuspendTime << 2);
407 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
411 + X D r a w B e v e l e d M a t t e %
415 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
417 % XDrawBeveledMatte() draws a matte with a shadowed upper and left bevel and
418 % a highlighted lower and right bevel. The highlighted and shadowed bevels
419 % create a 3-D effect.
421 % The format of the XDrawBeveledMatte function is:
423 % XDrawBeveledMatte(display,window_info,matte_info)
425 % A description of each parameter follows:
427 % o display: Specifies a pointer to the Display structure; returned from
430 % o window_info: Specifies a pointer to a X11 XWindowInfo structure.
432 % o matte_info: Specifies a pointer to a XWidgetInfo structure. It
433 % contains the extents of the matte.
436 static void XDrawBeveledMatte(Display *display,const XWindowInfo *window_info,
437 const XWidgetInfo *matte_info)
442 XDrawBevel(display,window_info,matte_info);
443 XDrawMatte(display,window_info,matte_info);
447 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
451 + X D r a w M a t t e %
455 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
457 % XDrawMatte() fills a rectangular area with the matte color.
459 % The format of the XDrawMatte function is:
461 % XDrawMatte(display,window_info,matte_info)
463 % A description of each parameter follows:
465 % o display: Specifies a pointer to the Display structure; returned from
468 % o window_info: Specifies a pointer to a X11 XWindowInfo structure.
470 % o matte_info: Specifies a pointer to a XWidgetInfo structure. It
471 % contains the extents of the matte.
474 static void XDrawMatte(Display *display,const XWindowInfo *window_info,
475 const XWidgetInfo *matte_info)
480 if ((matte_info->trough == MagickFalse) || (window_info->depth == 1))
481 (void) XFillRectangle(display,window_info->id,
482 window_info->highlight_context,matte_info->x,matte_info->y,
483 matte_info->width,matte_info->height);
486 (void) XSetForeground(display,window_info->widget_context,
487 window_info->pixel_info->trough_color.pixel);
488 (void) XFillRectangle(display,window_info->id,window_info->widget_context,
489 matte_info->x,matte_info->y,matte_info->width,matte_info->height);
494 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
498 + X D r a w M a t t e T e x t %
502 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
504 % XDrawMatteText() draws a matte with text. If the text exceeds the extents
505 % of the text, a portion of the text relative to the cursor is displayed.
507 % The format of the XDrawMatteText function is:
509 % XDrawMatteText(display,window_info,text_info)
511 % A description of each parameter follows:
513 % o display: Specifies a pointer to the Display structure; returned from
516 % o window_info: Specifies a pointer to a X11 XWindowInfo structure.
518 % o text_info: Specifies a pointer to a XWidgetInfo structure. It
519 % contains the extents of the text.
522 static void XDrawMatteText(Display *display,const XWindowInfo *window_info,
523 XWidgetInfo *text_info)
549 XSetMatteColor(display,window_info,MagickFalse);
550 (void) XFillRectangle(display,window_info->id,window_info->widget_context,
551 text_info->x,text_info->y,text_info->width,text_info->height);
552 if (text_info->text == (char *) NULL)
554 XSetTextColor(display,window_info,text_info->highlight);
555 font_info=window_info->font_info;
556 x=text_info->x+(QuantumMargin >> 2);
557 y=text_info->y+font_info->ascent+(text_info->height >> 2);
558 width=text_info->width-(QuantumMargin >> 1);
559 height=(unsigned int) (font_info->ascent+font_info->descent);
560 if (*text_info->text == '\0')
563 No text-- just draw cursor.
565 (void) XDrawLine(display,window_info->id,window_info->annotate_context,
572 crop_info.width=(unsigned short) text_info->width;
573 crop_info.height=(unsigned short) text_info->height;
574 crop_info.x=text_info->x;
575 crop_info.y=text_info->y;
577 Determine beginning of the visible text.
579 if (text_info->cursor < text_info->marker)
580 text_info->marker=text_info->cursor;
583 text=text_info->marker;
584 if (XTextWidth(font_info,(char *) text,(int) (text_info->cursor-text)) >
587 text=text_info->text;
588 for (i=0; i < Extent(text); i++)
590 n=XTextWidth(font_info,(char *) text+i,(int)
591 (text_info->cursor-text-i));
592 if (n <= (int) width)
595 text_info->marker=(char *) text+i;
599 Draw text and cursor.
601 if (text_info->highlight == MagickFalse)
603 (void) XSetClipRectangles(display,window_info->widget_context,0,0,
604 &crop_info,1,Unsorted);
605 (void) XDrawString(display,window_info->id,window_info->widget_context,
606 x,y,text_info->marker,Extent(text_info->marker));
607 (void) XSetClipMask(display,window_info->widget_context,None);
611 (void) XSetClipRectangles(display,window_info->annotate_context,0,0,
612 &crop_info,1,Unsorted);
613 width=WidgetTextWidth(font_info,text_info->marker);
614 (void) XFillRectangle(display,window_info->id,
615 window_info->annotate_context,x,y-font_info->ascent,width,height);
616 (void) XSetClipMask(display,window_info->annotate_context,None);
617 (void) XSetClipRectangles(display,window_info->highlight_context,0,0,
618 &crop_info,1,Unsorted);
619 (void) XDrawString(display,window_info->id,
620 window_info->highlight_context,x,y,text_info->marker,
621 Extent(text_info->marker));
622 (void) XSetClipMask(display,window_info->highlight_context,None);
624 x+=XTextWidth(font_info,text_info->marker,(int)
625 (text_info->cursor-text_info->marker));
626 (void) XDrawLine(display,window_info->id,window_info->annotate_context,x,y+3,
631 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
635 + X D r a w T r i a n g l e E a s t %
639 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
641 % XDrawTriangleEast() draws a triangle with a highlighted left bevel and a
642 % shadowed right and lower bevel. The highlighted and shadowed bevels create
645 % The format of the XDrawTriangleEast function is:
647 % XDrawTriangleEast(display,window_info,triangle_info)
649 % A description of each parameter follows:
651 % o display: Specifies a pointer to the Display structure; returned from
654 % o window_info: Specifies a pointer to a X11 XWindowInfo structure.
656 % o triangle_info: Specifies a pointer to a XWidgetInfo structure. It
657 % contains the extents of the triangle.
660 static void XDrawTriangleEast(Display *display,const XWindowInfo *window_info,
661 const XWidgetInfo *triangle_info)
685 x2=triangle_info->x+triangle_info->width;
686 y2=triangle_info->y+(triangle_info->height >> 1);
688 y3=triangle_info->y+triangle_info->height;
689 bevel_width=triangle_info->bevel_width;
696 XSetMatteColor(display,window_info,triangle_info->raised);
697 (void) XFillPolygon(display,window_info->id,window_info->widget_context,
698 points,3,Complex,CoordModeOrigin);
706 points[2].x=x3-bevel_width;
707 points[2].y=y3+bevel_width;
708 points[3].x=x2+bevel_width;
710 XSetBevelColor(display,window_info,!triangle_info->raised);
711 (void) XFillPolygon(display,window_info->id,window_info->widget_context,
712 points,4,Complex,CoordModeOrigin);
720 points[2].x=x1-bevel_width+1;
721 points[2].y=y1-bevel_width;
722 points[3].x=x3-bevel_width+1;
723 points[3].y=y3+bevel_width;
724 XSetBevelColor(display,window_info,triangle_info->raised);
725 (void) XFillPolygon(display,window_info->id,window_info->widget_context,
726 points,4,Complex,CoordModeOrigin);
734 points[2].x=x2+bevel_width;
736 points[3].x=x1-bevel_width;
737 points[3].y=y1-bevel_width;
738 (void) XFillPolygon(display,window_info->id,window_info->widget_context,
739 points,4,Complex,CoordModeOrigin);
740 (void) XSetFillStyle(display,window_info->widget_context,FillSolid);
741 if (triangle_info->text == (char *) NULL)
744 Write label to right of triangle.
746 font_info=window_info->font_info;
747 XSetTextColor(display,window_info,MagickTrue);
748 x1=triangle_info->x+triangle_info->width+triangle_info->bevel_width+
749 (QuantumMargin >> 1);
750 y1=triangle_info->y+((triangle_info->height-
751 (font_info->ascent+font_info->descent)) >> 1)+font_info->ascent;
752 (void) XDrawString(display,window_info->id,window_info->widget_context,x1,y1,
753 triangle_info->text,Extent(triangle_info->text));
757 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
761 + X D r a w T r i a n g l e N o r t h %
765 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
767 % XDrawTriangleNorth() draws a triangle with a highlighted left bevel and a
768 % shadowed right and lower bevel. The highlighted and shadowed bevels create
771 % The format of the XDrawTriangleNorth function is:
773 % XDrawTriangleNorth(display,window_info,triangle_info)
775 % A description of each parameter follows:
777 % o display: Specifies a pointer to the Display structure; returned from
780 % o window_info: Specifies a pointer to a X11 XWindowInfo structure.
782 % o triangle_info: Specifies a pointer to a XWidgetInfo structure. It
783 % contains the extents of the triangle.
786 static void XDrawTriangleNorth(Display *display,const XWindowInfo *window_info,
787 const XWidgetInfo *triangle_info)
807 y1=triangle_info->y+triangle_info->height;
808 x2=triangle_info->x+(triangle_info->width >> 1);
810 x3=triangle_info->x+triangle_info->width;
811 y3=triangle_info->y+triangle_info->height;
812 bevel_width=triangle_info->bevel_width;
819 XSetMatteColor(display,window_info,triangle_info->raised);
820 (void) XFillPolygon(display,window_info->id,window_info->widget_context,
821 points,3,Complex,CoordModeOrigin);
830 points[2].y=y2-bevel_width-2;
831 points[3].x=x1-bevel_width-1;
832 points[3].y=y1+bevel_width;
833 XSetBevelColor(display,window_info,triangle_info->raised);
834 (void) XFillPolygon(display,window_info->id,window_info->widget_context,
835 points,4,Complex,CoordModeOrigin);
843 points[2].x=x3+bevel_width;
844 points[2].y=y3+bevel_width;
846 points[3].y=y2-bevel_width;
847 XSetBevelColor(display,window_info,!triangle_info->raised);
848 (void) XFillPolygon(display,window_info->id,window_info->widget_context,
849 points,4,Complex,CoordModeOrigin);
857 points[2].x=x1-bevel_width;
858 points[2].y=y1+bevel_width;
859 points[3].x=x3+bevel_width;
860 points[3].y=y3+bevel_width;
861 (void) XFillPolygon(display,window_info->id,window_info->widget_context,
862 points,4,Complex,CoordModeOrigin);
863 (void) XSetFillStyle(display,window_info->widget_context,FillSolid);
867 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
871 + X D r a w T r i a n g l e S o u t h %
875 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
877 % XDrawTriangleSouth() draws a border with a highlighted left and right bevel
878 % and a shadowed lower bevel. The highlighted and shadowed bevels create a
881 % The format of the XDrawTriangleSouth function is:
883 % XDrawTriangleSouth(display,window_info,triangle_info)
885 % A description of each parameter follows:
887 % o display: Specifies a pointer to the Display structure; returned from
890 % o window_info: Specifies a pointer to a X11 XWindowInfo structure.
892 % o triangle_info: Specifies a pointer to a XWidgetInfo structure. It
893 % contains the extents of the triangle.
896 static void XDrawTriangleSouth(Display *display,const XWindowInfo *window_info,
897 const XWidgetInfo *triangle_info)
918 x2=triangle_info->x+(triangle_info->width >> 1);
919 y2=triangle_info->y+triangle_info->height;
920 x3=triangle_info->x+triangle_info->width;
922 bevel_width=triangle_info->bevel_width;
929 XSetMatteColor(display,window_info,triangle_info->raised);
930 (void) XFillPolygon(display,window_info->id,window_info->widget_context,
931 points,3,Complex,CoordModeOrigin);
939 points[2].x=x1-bevel_width;
940 points[2].y=y1-bevel_width;
941 points[3].x=x3+bevel_width;
942 points[3].y=y3-bevel_width;
943 XSetBevelColor(display,window_info,triangle_info->raised);
944 (void) XFillPolygon(display,window_info->id,window_info->widget_context,
945 points,4,Complex,CoordModeOrigin);
952 points[1].y=y3-bevel_width;
953 points[2].x=x3+bevel_width;
954 points[2].y=y3-bevel_width;
956 points[3].y=y2+bevel_width;
957 XSetBevelColor(display,window_info,!triangle_info->raised);
958 (void) XFillPolygon(display,window_info->id,window_info->widget_context,
959 points,4,Complex,CoordModeOrigin);
968 points[2].y=y2+bevel_width;
969 points[3].x=x1-bevel_width;
970 points[3].y=y1-bevel_width;
971 XSetBevelColor(display,window_info,triangle_info->raised);
972 (void) XFillPolygon(display,window_info->id,window_info->widget_context,
973 points,4,Complex,CoordModeOrigin);
974 (void) XSetFillStyle(display,window_info->widget_context,FillSolid);
978 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
982 + X D r a w W i d g e t T e x t %
986 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
988 % XDrawWidgetText() first clears the widget and draws a text string justifed
989 % left (or center) in the x-direction and centered within the y-direction.
991 % The format of the XDrawWidgetText function is:
993 % XDrawWidgetText(display,window_info,text_info)
995 % A description of each parameter follows:
997 % o display: Specifies a pointer to the Display structure; returned from
1000 % o window_info: Specifies a pointer to a XWindowText structure.
1002 % o text_info: Specifies a pointer to XWidgetInfo structure.
1005 static void XDrawWidgetText(Display *display,const XWindowInfo *window_info,
1006 XWidgetInfo *text_info)
1026 Clear the text area.
1028 widget_context=window_info->annotate_context;
1029 if (text_info->raised)
1030 (void) XClearArea(display,window_info->id,text_info->x,text_info->y,
1031 text_info->width,text_info->height,MagickFalse);
1034 (void) XFillRectangle(display,window_info->id,widget_context,text_info->x,
1035 text_info->y,text_info->width,text_info->height);
1036 widget_context=window_info->highlight_context;
1038 if (text_info->text == (char *) NULL)
1040 if (*text_info->text == '\0')
1043 Set cropping region.
1045 font_info=window_info->font_info;
1046 crop_info.width=(unsigned short) text_info->width;
1047 crop_info.height=(unsigned short) text_info->height;
1048 crop_info.x=text_info->x;
1049 crop_info.y=text_info->y;
1053 width=WidgetTextWidth(font_info,text_info->text);
1054 x=text_info->x+(QuantumMargin >> 1);
1055 if (text_info->center)
1056 x=text_info->x+(text_info->width >> 1)-(width >> 1);
1057 if (text_info->raised)
1058 if (width > (text_info->width-QuantumMargin))
1059 x+=(text_info->width-QuantumMargin-width);
1060 height=(unsigned int) (font_info->ascent+font_info->descent);
1061 y=text_info->y+((text_info->height-height) >> 1)+font_info->ascent;
1062 (void) XSetClipRectangles(display,widget_context,0,0,&crop_info,1,Unsorted);
1063 (void) XDrawString(display,window_info->id,widget_context,x,y,text_info->text,
1064 Extent(text_info->text));
1065 (void) XSetClipMask(display,widget_context,None);
1066 if (x < text_info->x)
1067 (void) XDrawLine(display,window_info->id,window_info->annotate_context,
1068 text_info->x,text_info->y,text_info->x,text_info->y+text_info->height-1);
1072 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1076 + X E d i t T e x t %
1080 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1082 % XEditText() edits a text string as indicated by the key symbol.
1084 % The format of the XEditText function is:
1086 % XEditText(display,text_info,key_symbol,text,state)
1088 % A description of each parameter follows:
1090 % o display: Specifies a connection to an X server; returned from
1093 % o text_info: Specifies a pointer to a XWidgetInfo structure. It
1094 % contains the extents of the text.
1096 % o key_symbol: A X11 KeySym that indicates what editing function to
1097 % perform to the text.
1099 % o text: A character string to insert into the text.
1101 % o state: An size_t that indicates whether the key symbol is a
1102 % control character or not.
1105 static void XEditText(Display *display,XWidgetInfo *text_info,
1106 const KeySym key_symbol,char *text,const size_t state)
1108 switch ((int) key_symbol)
1113 if (text_info->highlight)
1116 Erase the entire line of text.
1118 *text_info->text='\0';
1119 text_info->cursor=text_info->text;
1120 text_info->marker=text_info->text;
1121 text_info->highlight=MagickFalse;
1124 Erase one character.
1126 if (text_info->cursor != text_info->text)
1128 text_info->cursor--;
1129 (void) CopyMagickString(text_info->cursor,text_info->cursor+1,
1131 text_info->highlight=MagickFalse;
1139 Move cursor one position left.
1141 if (text_info->cursor == text_info->text)
1143 text_info->cursor--;
1150 Move cursor one position right.
1152 if (text_info->cursor == (text_info->text+Extent(text_info->text)))
1154 text_info->cursor++;
1166 if (state & ControlState)
1170 if ((Extent(text_info->text)+1) >= (ssize_t) MaxTextExtent)
1171 (void) XBell(display,0);
1174 if (text_info->highlight)
1177 Erase the entire line of text.
1179 *text_info->text='\0';
1180 text_info->cursor=text_info->text;
1181 text_info->marker=text_info->text;
1182 text_info->highlight=MagickFalse;
1185 Insert a string into the text.
1187 q=text_info->text+Extent(text_info->text)+strlen(text);
1188 for (i=0; i <= Extent(text_info->cursor); i++)
1190 *q=(*(q-Extent(text)));
1194 for (i=0; i < Extent(text); i++)
1195 *text_info->cursor++=(*p++);
1203 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1207 + X G e t W i d g e t I n f o %
1211 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1213 % XGetWidgetInfo() initializes the XWidgetInfo structure.
1215 % The format of the XGetWidgetInfo function is:
1217 % XGetWidgetInfo(text,widget_info)
1219 % A description of each parameter follows:
1221 % o text: A string of characters associated with the widget.
1223 % o widget_info: Specifies a pointer to a X11 XWidgetInfo structure.
1226 static void XGetWidgetInfo(const char *text,XWidgetInfo *widget_info)
1229 Initialize widget info.
1231 widget_info->id=(~0);
1232 widget_info->bevel_width=3;
1233 widget_info->width=1;
1234 widget_info->height=1;
1237 widget_info->min_y=0;
1238 widget_info->max_y=0;
1239 widget_info->raised=MagickTrue;
1240 widget_info->active=MagickFalse;
1241 widget_info->center=MagickTrue;
1242 widget_info->trough=MagickFalse;
1243 widget_info->highlight=MagickFalse;
1244 widget_info->text=(char *) text;
1245 widget_info->cursor=(char *) text;
1246 if (text != (char *) NULL)
1247 widget_info->cursor+=Extent(text);
1248 widget_info->marker=(char *) text;
1252 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1256 + X H i g h l i g h t W i d g e t %
1260 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1262 % XHighlightWidget() draws a highlighted border around a window.
1264 % The format of the XHighlightWidget function is:
1266 % XHighlightWidget(display,window_info,x,y)
1268 % A description of each parameter follows:
1270 % o display: Specifies a pointer to the Display structure; returned from
1273 % o window_info: Specifies a pointer to a X11 XWindowInfo structure.
1275 % o x: Specifies an integer representing the rectangle offset in the
1278 % o y: Specifies an integer representing the rectangle offset in the
1282 static void XHighlightWidget(Display *display,const XWindowInfo *window_info,
1283 const int x,const int y)
1286 Draw the widget highlighting rectangle.
1288 XSetBevelColor(display,window_info,MagickTrue);
1289 (void) XDrawRectangle(display,window_info->id,window_info->widget_context,x,y,
1290 window_info->width-(x << 1),window_info->height-(y << 1));
1291 (void) XDrawRectangle(display,window_info->id,window_info->widget_context,
1292 x-1,y-1,window_info->width-(x << 1)+1,window_info->height-(y << 1)+1);
1293 XSetBevelColor(display,window_info,MagickFalse);
1294 (void) XDrawRectangle(display,window_info->id,window_info->widget_context,
1295 x-1,y-1,window_info->width-(x << 1),window_info->height-(y << 1));
1296 (void) XSetFillStyle(display,window_info->widget_context,FillSolid);
1300 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1304 + X S c r e e n E v e n t %
1308 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1310 % XScreenEvent() returns MagickTrue if the any event on the X server queue is
1311 % associated with the widget window.
1313 % The format of the XScreenEvent function is:
1315 % int XScreenEvent(Display *display,XEvent *event,char *data)
1317 % A description of each parameter follows:
1319 % o display: Specifies a pointer to the Display structure; returned from
1322 % o event: Specifies a pointer to a X11 XEvent structure.
1324 % o data: Specifies a pointer to a XWindows structure.
1328 #if defined(__cplusplus) || defined(c_plusplus)
1332 static int XScreenEvent(Display *display,XEvent *event,char *data)
1337 windows=(XWindows *) data;
1338 if (event->xany.window == windows->popup.id)
1340 if (event->type == MapNotify)
1341 windows->popup.mapped=MagickTrue;
1342 if (event->type == UnmapNotify)
1343 windows->popup.mapped=MagickFalse;
1346 if (event->xany.window == windows->widget.id)
1348 if (event->type == MapNotify)
1349 windows->widget.mapped=MagickTrue;
1350 if (event->type == UnmapNotify)
1351 windows->widget.mapped=MagickFalse;
1354 switch (event->type)
1358 if ((event->xbutton.button == Button3) &&
1359 (event->xbutton.state & Mod1Mask))
1362 Convert Alt-Button3 to Button2.
1364 event->xbutton.button=Button2;
1365 event->xbutton.state&=(~Mod1Mask);
1371 if (event->xexpose.window == windows->image.id)
1373 XRefreshWindow(display,&windows->image,event);
1376 if (event->xexpose.window == windows->magnify.id)
1377 if (event->xexpose.count == 0)
1378 if (windows->magnify.mapped)
1380 XMakeMagnifyImage(display,windows);
1383 if (event->xexpose.window == windows->command.id)
1384 if (event->xexpose.count == 0)
1386 (void) XCommandWidget(display,windows,(const char **) NULL,event);
1394 Set input focus for backdrop window.
1396 if (event->xfocus.window == windows->image.id)
1397 (void) XSetInputFocus(display,windows->image.id,RevertToNone,
1405 case SelectionNotify:
1410 return(MagickFalse);
1413 #if defined(__cplusplus) || defined(c_plusplus)
1418 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1422 + X S e t B e v e l C o l o r %
1426 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1428 % XSetBevelColor() sets the graphic context for drawing a beveled border.
1430 % The format of the XSetBevelColor function is:
1432 % XSetBevelColor(display,window_info,raised)
1434 % A description of each parameter follows:
1436 % o display: Specifies a pointer to the Display structure; returned from
1439 % o window_info: Specifies a pointer to a X11 XWindowInfo structure.
1441 % o raised: A value other than zero indicates the color show be a
1442 % "highlight" color, otherwise the "shadow" color is set.
1445 static void XSetBevelColor(Display *display,const XWindowInfo *window_info,
1446 const MagickStatusType raised)
1448 if (window_info->depth == 1)
1456 (void) XSetBackground(display,window_info->widget_context,
1457 XBlackPixel(display,window_info->screen));
1458 (void) XSetForeground(display,window_info->widget_context,
1459 XWhitePixel(display,window_info->screen));
1460 (void) XSetFillStyle(display,window_info->widget_context,
1461 FillOpaqueStippled);
1462 stipple=window_info->highlight_stipple;
1463 if (raised == MagickFalse)
1464 stipple=window_info->shadow_stipple;
1465 (void) XSetStipple(display,window_info->widget_context,stipple);
1469 (void) XSetForeground(display,window_info->widget_context,
1470 window_info->pixel_info->highlight_color.pixel);
1472 (void) XSetForeground(display,window_info->widget_context,
1473 window_info->pixel_info->shadow_color.pixel);
1477 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1481 + X S e t M a t t e C o l o r %
1485 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1487 % XSetMatteColor() sets the graphic context for drawing the matte.
1489 % The format of the XSetMatteColor function is:
1491 % XSetMatteColor(display,window_info,raised)
1493 % A description of each parameter follows:
1495 % o display: Specifies a pointer to the Display structure; returned from
1498 % o window_info: Specifies a pointer to a X11 XWindowInfo structure.
1500 % o raised: A value other than zero indicates the matte is active.
1503 static void XSetMatteColor(Display *display,const XWindowInfo *window_info,
1504 const MagickStatusType raised)
1506 if (window_info->depth == 1)
1512 (void) XSetForeground(display,window_info->widget_context,
1513 XWhitePixel(display,window_info->screen));
1515 (void) XSetForeground(display,window_info->widget_context,
1516 XBlackPixel(display,window_info->screen));
1520 (void) XSetForeground(display,window_info->widget_context,
1521 window_info->pixel_info->matte_color.pixel);
1523 (void) XSetForeground(display,window_info->widget_context,
1524 window_info->pixel_info->depth_color.pixel);
1528 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1532 + X S e t T e x t C o l o r %
1536 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1538 % XSetTextColor() sets the graphic context for drawing text on a matte.
1540 % The format of the XSetTextColor function is:
1542 % XSetTextColor(display,window_info,raised)
1544 % A description of each parameter follows:
1546 % o display: Specifies a pointer to the Display structure; returned from
1549 % o window_info: Specifies a pointer to a X11 XWindowInfo structure.
1551 % o raised: A value other than zero indicates the color show be a
1552 % "highlight" color, otherwise the "shadow" color is set.
1555 static void XSetTextColor(Display *display,const XWindowInfo *window_info,
1556 const MagickStatusType raised)
1562 if (window_info->depth == 1)
1568 (void) XSetForeground(display,window_info->widget_context,
1569 XBlackPixel(display,window_info->screen));
1571 (void) XSetForeground(display,window_info->widget_context,
1572 XWhitePixel(display,window_info->screen));
1575 foreground=(ssize_t) XPixelIntensity(&window_info->pixel_info->foreground_color);
1576 matte=(ssize_t) XPixelIntensity(&window_info->pixel_info->matte_color);
1577 if (MagickAbsoluteValue(foreground-matte) > (65535L >> 3))
1578 (void) XSetForeground(display,window_info->widget_context,
1579 window_info->pixel_info->foreground_color.pixel);
1581 (void) XSetForeground(display,window_info->widget_context,
1582 window_info->pixel_info->background_color.pixel);
1586 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1590 % X C o l o r B r o w s e r W i d g e t %
1594 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1596 % XColorBrowserWidget() displays a Color Browser widget with a color query
1597 % to the user. The user keys a reply and presses the Action or Cancel button
1598 % to exit. The typed text is returned as the reply function parameter.
1600 % The format of the XColorBrowserWidget method is:
1602 % void XColorBrowserWidget(Display *display,XWindows *windows,
1603 % const char *action,char *reply)
1605 % A description of each parameter follows:
1607 % o display: Specifies a connection to an X server; returned from
1610 % o window: Specifies a pointer to a XWindows structure.
1612 % o action: Specifies a pointer to the action of this widget.
1614 % o reply: the response from the user is returned in this parameter.
1617 MagickExport void XColorBrowserWidget(Display *display,XWindows *windows,
1618 const char *action,char *reply)
1620 #define CancelButtonText "Cancel"
1621 #define ColornameText "Name:"
1622 #define ColorPatternText "Pattern:"
1623 #define GrabButtonText "Grab"
1624 #define ResetButtonText "Reset"
1628 primary_selection[MaxTextExtent],
1629 reset_pattern[MaxTextExtent],
1630 text[MaxTextExtent];
1643 glob_pattern[MaxTextExtent] = "*";
1645 static MagickStatusType
1646 mask = (MagickStatusType) (CWWidth | CWHeight | CWX | CWY);
1694 Get color list and sort in ascending order.
1696 assert(display != (Display *) NULL);
1697 assert(windows != (XWindows *) NULL);
1698 assert(action != (char *) NULL);
1699 assert(reply != (char *) NULL);
1700 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",action);
1701 XSetCursorState(display,windows,MagickTrue);
1702 XCheckRefreshWindows(display,windows);
1703 (void) CopyMagickString(reset_pattern,"*",MaxTextExtent);
1704 exception=AcquireExceptionInfo();
1705 colorlist=GetColorList(glob_pattern,&colors,exception);
1706 if (colorlist == (char **) NULL)
1709 Pattern failed, obtain all the colors.
1711 (void) CopyMagickString(glob_pattern,"*",MaxTextExtent);
1712 colorlist=GetColorList(glob_pattern,&colors,exception);
1713 if (colorlist == (char **) NULL)
1715 XNoticeWidget(display,windows,"Unable to obtain colors names:",
1717 (void) XDialogWidget(display,windows,action,"Enter color name:",
1723 Determine Color Browser widget attributes.
1725 font_info=windows->widget.font_info;
1727 for (i=0; i < (ssize_t) colors; i++)
1728 if (WidgetTextWidth(font_info,colorlist[i]) > text_width)
1729 text_width=WidgetTextWidth(font_info,colorlist[i]);
1730 width=WidgetTextWidth(font_info,(char *) action);
1731 if (WidgetTextWidth(font_info,CancelButtonText) > width)
1732 width=WidgetTextWidth(font_info,CancelButtonText);
1733 if (WidgetTextWidth(font_info,ResetButtonText) > width)
1734 width=WidgetTextWidth(font_info,ResetButtonText);
1735 if (WidgetTextWidth(font_info,GrabButtonText) > width)
1736 width=WidgetTextWidth(font_info,GrabButtonText);
1737 width+=QuantumMargin;
1738 if (WidgetTextWidth(font_info,ColorPatternText) > width)
1739 width=WidgetTextWidth(font_info,ColorPatternText);
1740 if (WidgetTextWidth(font_info,ColornameText) > width)
1741 width=WidgetTextWidth(font_info,ColornameText);
1742 height=(unsigned int) (font_info->ascent+font_info->descent);
1744 Position Color Browser widget.
1746 windows->widget.width=(unsigned int)
1747 (width+MagickMin((int) text_width,(int) MaxTextWidth)+6*QuantumMargin);
1748 windows->widget.min_width=(unsigned int)
1749 (width+MinTextWidth+4*QuantumMargin);
1750 if (windows->widget.width < windows->widget.min_width)
1751 windows->widget.width=windows->widget.min_width;
1752 windows->widget.height=(unsigned int)
1753 ((81*height) >> 2)+((13*QuantumMargin) >> 1)+4;
1754 windows->widget.min_height=(unsigned int)
1755 (((23*height) >> 1)+((13*QuantumMargin) >> 1)+4);
1756 if (windows->widget.height < windows->widget.min_height)
1757 windows->widget.height=windows->widget.min_height;
1758 XConstrainWindowPosition(display,&windows->widget);
1760 Map Color Browser widget.
1762 (void) CopyMagickString(windows->widget.name,"Browse and Select a Color",
1764 status=XStringListToTextProperty(&windows->widget.name,1,&window_name);
1765 if (status != False)
1767 XSetWMName(display,windows->widget.id,&window_name);
1768 XSetWMIconName(display,windows->widget.id,&window_name);
1769 (void) XFree((void *) window_name.value);
1771 window_changes.width=(int) windows->widget.width;
1772 window_changes.height=(int) windows->widget.height;
1773 window_changes.x=windows->widget.x;
1774 window_changes.y=windows->widget.y;
1775 (void) XReconfigureWMWindow(display,windows->widget.id,windows->widget.screen,
1776 mask,&window_changes);
1777 (void) XMapRaised(display,windows->widget.id);
1778 windows->widget.mapped=MagickFalse;
1780 Respond to X events.
1782 XGetWidgetInfo((char *) NULL,&slider_info);
1783 XGetWidgetInfo((char *) NULL,&north_info);
1784 XGetWidgetInfo((char *) NULL,&south_info);
1785 XGetWidgetInfo((char *) NULL,&expose_info);
1787 delay=SuspendTime << 2;
1788 state=UpdateConfigurationState;
1791 if (state & UpdateConfigurationState)
1797 Initialize button information.
1799 XGetWidgetInfo(CancelButtonText,&cancel_info);
1800 cancel_info.width=width;
1801 cancel_info.height=(unsigned int) ((3*height) >> 1);
1803 (windows->widget.width-cancel_info.width-QuantumMargin-2);
1805 (windows->widget.height-cancel_info.height-QuantumMargin);
1806 XGetWidgetInfo(action,&action_info);
1807 action_info.width=width;
1808 action_info.height=(unsigned int) ((3*height) >> 1);
1809 action_info.x=cancel_info.x-(cancel_info.width+(QuantumMargin >> 1)+
1810 (action_info.bevel_width << 1));
1811 action_info.y=cancel_info.y;
1812 XGetWidgetInfo(GrabButtonText,&grab_info);
1813 grab_info.width=width;
1814 grab_info.height=(unsigned int) ((3*height) >> 1);
1815 grab_info.x=QuantumMargin;
1816 grab_info.y=((5*QuantumMargin) >> 1)+height;
1817 XGetWidgetInfo(ResetButtonText,&reset_info);
1818 reset_info.width=width;
1819 reset_info.height=(unsigned int) ((3*height) >> 1);
1820 reset_info.x=QuantumMargin;
1821 reset_info.y=grab_info.y+grab_info.height+QuantumMargin;
1823 Initialize reply information.
1825 XGetWidgetInfo(reply,&reply_info);
1826 reply_info.raised=MagickFalse;
1827 reply_info.bevel_width--;
1828 reply_info.width=windows->widget.width-width-((6*QuantumMargin) >> 1);
1829 reply_info.height=height << 1;
1830 reply_info.x=(int) (width+(QuantumMargin << 1));
1831 reply_info.y=action_info.y-reply_info.height-QuantumMargin;
1833 Initialize mode information.
1835 XGetWidgetInfo((char *) NULL,&mode_info);
1836 mode_info.active=MagickTrue;
1837 mode_info.bevel_width=0;
1838 mode_info.width=(unsigned int) (action_info.x-(QuantumMargin << 1));
1839 mode_info.height=action_info.height;
1840 mode_info.x=QuantumMargin;
1841 mode_info.y=action_info.y;
1843 Initialize scroll information.
1845 XGetWidgetInfo((char *) NULL,&scroll_info);
1846 scroll_info.bevel_width--;
1847 scroll_info.width=height;
1848 scroll_info.height=(unsigned int) (reply_info.y-grab_info.y-
1849 (QuantumMargin >> 1));
1850 scroll_info.x=reply_info.x+(reply_info.width-scroll_info.width);
1851 scroll_info.y=grab_info.y-reply_info.bevel_width;
1852 scroll_info.raised=MagickFalse;
1853 scroll_info.trough=MagickTrue;
1854 north_info=scroll_info;
1855 north_info.raised=MagickTrue;
1856 north_info.width-=(north_info.bevel_width << 1);
1857 north_info.height=north_info.width-1;
1858 north_info.x+=north_info.bevel_width;
1859 north_info.y+=north_info.bevel_width;
1860 south_info=north_info;
1861 south_info.y=scroll_info.y+scroll_info.height-scroll_info.bevel_width-
1864 slider_info=north_info;
1866 slider_info.width-=2;
1867 slider_info.min_y=north_info.y+north_info.height+north_info.bevel_width+
1868 slider_info.bevel_width+2;
1869 slider_info.height=scroll_info.height-((slider_info.min_y-
1870 scroll_info.y+1) << 1)+4;
1871 visible_colors=scroll_info.height/(height+(height >> 3));
1872 if (colors > visible_colors)
1873 slider_info.height=(unsigned int)
1874 ((visible_colors*slider_info.height)/colors);
1875 slider_info.max_y=south_info.y-south_info.bevel_width-
1876 slider_info.bevel_width-2;
1877 slider_info.x=scroll_info.x+slider_info.bevel_width+1;
1878 slider_info.y=slider_info.min_y;
1879 expose_info=scroll_info;
1880 expose_info.y=slider_info.y;
1882 Initialize list information.
1884 XGetWidgetInfo((char *) NULL,&list_info);
1885 list_info.raised=MagickFalse;
1886 list_info.bevel_width--;
1887 list_info.width=(unsigned int)
1888 (scroll_info.x-reply_info.x-(QuantumMargin >> 1));
1889 list_info.height=scroll_info.height;
1890 list_info.x=reply_info.x;
1891 list_info.y=scroll_info.y;
1892 if (windows->widget.mapped == MagickFalse)
1893 state|=JumpListState;
1895 Initialize text information.
1898 XGetWidgetInfo(text,&text_info);
1899 text_info.center=MagickFalse;
1900 text_info.width=reply_info.width;
1901 text_info.height=height;
1902 text_info.x=list_info.x-(QuantumMargin >> 1);
1903 text_info.y=QuantumMargin;
1905 Initialize selection information.
1907 XGetWidgetInfo((char *) NULL,&selection_info);
1908 selection_info.center=MagickFalse;
1909 selection_info.width=list_info.width;
1910 selection_info.height=(unsigned int) ((9*height) >> 3);
1911 selection_info.x=list_info.x;
1912 state&=(~UpdateConfigurationState);
1914 if (state & RedrawWidgetState)
1917 Redraw Color Browser window.
1920 y=text_info.y+((text_info.height-height) >> 1)+font_info->ascent;
1921 (void) XDrawString(display,windows->widget.id,
1922 windows->widget.annotate_context,x,y,ColorPatternText,
1923 Extent(ColorPatternText));
1924 (void) CopyMagickString(text_info.text,glob_pattern,MaxTextExtent);
1925 XDrawWidgetText(display,&windows->widget,&text_info);
1926 XDrawBeveledButton(display,&windows->widget,&grab_info);
1927 XDrawBeveledButton(display,&windows->widget,&reset_info);
1928 XDrawBeveledMatte(display,&windows->widget,&list_info);
1929 XDrawBeveledMatte(display,&windows->widget,&scroll_info);
1930 XDrawTriangleNorth(display,&windows->widget,&north_info);
1931 XDrawBeveledButton(display,&windows->widget,&slider_info);
1932 XDrawTriangleSouth(display,&windows->widget,&south_info);
1934 y=reply_info.y+((reply_info.height-height) >> 1)+font_info->ascent;
1935 (void) XDrawString(display,windows->widget.id,
1936 windows->widget.annotate_context,x,y,ColornameText,
1937 Extent(ColornameText));
1938 XDrawBeveledMatte(display,&windows->widget,&reply_info);
1939 XDrawMatteText(display,&windows->widget,&reply_info);
1940 XDrawBeveledButton(display,&windows->widget,&action_info);
1941 XDrawBeveledButton(display,&windows->widget,&cancel_info);
1942 XHighlightWidget(display,&windows->widget,BorderOffset,BorderOffset);
1943 selection_info.id=(~0);
1944 state|=RedrawActionState;
1945 state|=RedrawListState;
1946 state&=(~RedrawWidgetState);
1948 if (state & UpdateListState)
1956 status=XParseColor(display,windows->widget.map_info->colormap,
1957 glob_pattern,&color);
1958 if ((status != False) || (strchr(glob_pattern,'-') != (char *) NULL))
1961 Reply is a single color name-- exit.
1963 (void) CopyMagickString(reply,glob_pattern,MaxTextExtent);
1964 (void) CopyMagickString(glob_pattern,reset_pattern,MaxTextExtent);
1965 action_info.raised=MagickFalse;
1966 XDrawBeveledButton(display,&windows->widget,&action_info);
1972 checklist=GetColorList(glob_pattern,&number_colors,exception);
1973 if (number_colors == 0)
1975 (void) CopyMagickString(glob_pattern,reset_pattern,MaxTextExtent);
1976 (void) XBell(display,0);
1980 for (i=0; i < (ssize_t) colors; i++)
1981 colorlist[i]=DestroyString(colorlist[i]);
1982 if (colorlist != (char **) NULL)
1983 colorlist=(char **) RelinquishMagickMemory(colorlist);
1984 colorlist=checklist;
1985 colors=number_colors;
1988 Sort color list in ascending order.
1991 scroll_info.height-((slider_info.min_y-scroll_info.y+1) << 1)+1;
1992 if (colors > visible_colors)
1993 slider_info.height=(unsigned int)
1994 ((visible_colors*slider_info.height)/colors);
1995 slider_info.max_y=south_info.y-south_info.bevel_width-
1996 slider_info.bevel_width-2;
1998 slider_info.y=slider_info.min_y;
1999 expose_info.y=slider_info.y;
2000 selection_info.id=(~0);
2002 state|=RedrawListState;
2004 Redraw color name & reply.
2006 *reply_info.text='\0';
2007 reply_info.cursor=reply_info.text;
2008 (void) CopyMagickString(text_info.text,glob_pattern,MaxTextExtent);
2009 XDrawWidgetText(display,&windows->widget,&text_info);
2010 XDrawMatteText(display,&windows->widget,&reply_info);
2011 XDrawBeveledMatte(display,&windows->widget,&scroll_info);
2012 XDrawTriangleNorth(display,&windows->widget,&north_info);
2013 XDrawBeveledButton(display,&windows->widget,&slider_info);
2014 XDrawTriangleSouth(display,&windows->widget,&south_info);
2015 XHighlightWidget(display,&windows->widget,BorderOffset,BorderOffset);
2016 state&=(~UpdateListState);
2018 if (state & JumpListState)
2021 Jump scroll to match user color.
2024 for (i=0; i < (ssize_t) colors; i++)
2025 if (LocaleCompare(colorlist[i],reply) >= 0)
2027 list_info.id=LocaleCompare(colorlist[i],reply) == 0 ? i : ~0;
2030 if ((i < slider_info.id) ||
2031 (i >= (int) (slider_info.id+visible_colors)))
2032 slider_info.id=i-(visible_colors >> 1);
2033 selection_info.id=(~0);
2034 state|=RedrawListState;
2035 state&=(~JumpListState);
2037 if (state & RedrawListState)
2040 Determine slider id and position.
2042 if (slider_info.id >= (int) (colors-visible_colors))
2043 slider_info.id=(int) (colors-visible_colors);
2044 if ((slider_info.id < 0) || (colors <= visible_colors))
2046 slider_info.y=slider_info.min_y;
2048 slider_info.y+=(int) (slider_info.id*(slider_info.max_y-
2049 slider_info.min_y+1)/colors);
2050 if (slider_info.id != selection_info.id)
2053 Redraw scroll bar and file names.
2055 selection_info.id=slider_info.id;
2056 selection_info.y=list_info.y+(height >> 3)+2;
2057 for (i=0; i < (int) visible_colors; i++)
2059 selection_info.raised=(slider_info.id+i) != list_info.id ?
2060 MagickTrue : MagickFalse;
2061 selection_info.text=(char *) NULL;
2062 if ((slider_info.id+i) < (ssize_t) colors)
2063 selection_info.text=colorlist[slider_info.id+i];
2064 XDrawWidgetText(display,&windows->widget,&selection_info);
2065 selection_info.y+=(int) selection_info.height;
2070 if (slider_info.y > expose_info.y)
2072 expose_info.height=(unsigned int) slider_info.y-expose_info.y;
2073 expose_info.y=slider_info.y-expose_info.height-
2074 slider_info.bevel_width-1;
2078 expose_info.height=(unsigned int) expose_info.y-slider_info.y;
2079 expose_info.y=slider_info.y+slider_info.height+
2080 slider_info.bevel_width+1;
2082 XDrawTriangleNorth(display,&windows->widget,&north_info);
2083 XDrawMatte(display,&windows->widget,&expose_info);
2084 XDrawBeveledButton(display,&windows->widget,&slider_info);
2085 XDrawTriangleSouth(display,&windows->widget,&south_info);
2086 expose_info.y=slider_info.y;
2088 state&=(~RedrawListState);
2090 if (state & RedrawActionState)
2093 colorname[MaxTextExtent];
2096 Display the selected color in a drawing area.
2098 color=windows->widget.pixel_info->matte_color;
2099 (void) XParseColor(display,windows->widget.map_info->colormap,
2100 reply_info.text,&windows->widget.pixel_info->matte_color);
2101 XBestPixel(display,windows->widget.map_info->colormap,(XColor *) NULL,
2102 (unsigned int) windows->widget.visual_info->colormap_size,
2103 &windows->widget.pixel_info->matte_color);
2104 mode_info.text=colorname;
2105 (void) FormatMagickString(mode_info.text,MaxTextExtent,"#%02x%02x%02x",
2106 windows->widget.pixel_info->matte_color.red,
2107 windows->widget.pixel_info->matte_color.green,
2108 windows->widget.pixel_info->matte_color.blue);
2109 XDrawBeveledButton(display,&windows->widget,&mode_info);
2110 windows->widget.pixel_info->matte_color=color;
2111 state&=(~RedrawActionState);
2114 Wait for next event.
2116 if (north_info.raised && south_info.raised)
2117 (void) XIfEvent(display,&event,XScreenEvent,(char *) windows);
2121 Brief delay before advancing scroll bar.
2123 XDelay(display,delay);
2125 (void) XCheckIfEvent(display,&event,XScreenEvent,(char *) windows);
2126 if (north_info.raised == MagickFalse)
2127 if (slider_info.id > 0)
2133 state|=RedrawListState;
2135 if (south_info.raised == MagickFalse)
2136 if (slider_info.id < (ssize_t) colors)
2142 state|=RedrawListState;
2144 if (event.type != ButtonRelease)
2151 if (MatteIsActive(slider_info,event.xbutton))
2156 slider_info.active=MagickTrue;
2159 if (MatteIsActive(north_info,event.xbutton))
2160 if (slider_info.id > 0)
2165 north_info.raised=MagickFalse;
2167 state|=RedrawListState;
2170 if (MatteIsActive(south_info,event.xbutton))
2171 if (slider_info.id < (ssize_t) colors)
2176 south_info.raised=MagickFalse;
2178 state|=RedrawListState;
2181 if (MatteIsActive(scroll_info,event.xbutton))
2186 if (event.xbutton.y < slider_info.y)
2187 slider_info.id-=(visible_colors-1);
2189 slider_info.id+=(visible_colors-1);
2190 state|=RedrawListState;
2193 if (MatteIsActive(list_info,event.xbutton))
2199 User pressed list matte.
2201 id=slider_info.id+(event.xbutton.y-(list_info.y+(height >> 1))+1)/
2202 selection_info.height;
2203 if (id >= (int) colors)
2205 (void) CopyMagickString(reply_info.text,colorlist[id],
2207 reply_info.highlight=MagickFalse;
2208 reply_info.marker=reply_info.text;
2209 reply_info.cursor=reply_info.text+Extent(reply_info.text);
2210 XDrawMatteText(display,&windows->widget,&reply_info);
2211 state|=RedrawActionState;
2212 if (id == list_info.id)
2214 (void) CopyMagickString(glob_pattern,reply_info.text,
2216 state|=UpdateListState;
2218 selection_info.id=(~0);
2220 state|=RedrawListState;
2223 if (MatteIsActive(grab_info,event.xbutton))
2226 User pressed Grab button.
2228 grab_info.raised=MagickFalse;
2229 XDrawBeveledButton(display,&windows->widget,&grab_info);
2232 if (MatteIsActive(reset_info,event.xbutton))
2235 User pressed Reset button.
2237 reset_info.raised=MagickFalse;
2238 XDrawBeveledButton(display,&windows->widget,&reset_info);
2241 if (MatteIsActive(mode_info,event.xbutton))
2244 User pressed mode button.
2246 (void) CopyMagickString(reply_info.text,mode_info.text,
2248 (void) CopyMagickString(primary_selection,reply_info.text,
2250 (void) XSetSelectionOwner(display,XA_PRIMARY,windows->widget.id,
2251 event.xbutton.time);
2252 reply_info.highlight=XGetSelectionOwner(display,XA_PRIMARY) ==
2253 windows->widget.id ? MagickTrue : MagickFalse;
2254 reply_info.marker=reply_info.text;
2255 reply_info.cursor=reply_info.text+Extent(reply_info.text);
2256 XDrawMatteText(display,&windows->widget,&reply_info);
2259 if (MatteIsActive(action_info,event.xbutton))
2262 User pressed action button.
2264 action_info.raised=MagickFalse;
2265 XDrawBeveledButton(display,&windows->widget,&action_info);
2268 if (MatteIsActive(cancel_info,event.xbutton))
2271 User pressed Cancel button.
2273 cancel_info.raised=MagickFalse;
2274 XDrawBeveledButton(display,&windows->widget,&cancel_info);
2277 if (MatteIsActive(reply_info,event.xbutton) == MagickFalse)
2279 if (event.xbutton.button != Button2)
2285 Move text cursor to position of button press.
2287 x=event.xbutton.x-reply_info.x-(QuantumMargin >> 2);
2288 for (i=1; i <= Extent(reply_info.marker); i++)
2289 if (XTextWidth(font_info,reply_info.marker,i) > x)
2291 reply_info.cursor=reply_info.marker+i-1;
2292 if (event.xbutton.time > (click_time+DoubleClick))
2293 reply_info.highlight=MagickFalse;
2297 Become the XA_PRIMARY selection owner.
2299 (void) CopyMagickString(primary_selection,reply_info.text,
2301 (void) XSetSelectionOwner(display,XA_PRIMARY,windows->widget.id,
2302 event.xbutton.time);
2303 reply_info.highlight=XGetSelectionOwner(display,XA_PRIMARY) ==
2304 windows->widget.id ? MagickTrue : MagickFalse;
2306 XDrawMatteText(display,&windows->widget,&reply_info);
2307 click_time=event.xbutton.time;
2311 Request primary selection.
2313 (void) XConvertSelection(display,XA_PRIMARY,XA_STRING,XA_STRING,
2314 windows->widget.id,event.xbutton.time);
2319 if (windows->widget.mapped == MagickFalse)
2321 if (north_info.raised == MagickFalse)
2324 User released up button.
2326 delay=SuspendTime << 2;
2327 north_info.raised=MagickTrue;
2328 XDrawTriangleNorth(display,&windows->widget,&north_info);
2330 if (south_info.raised == MagickFalse)
2333 User released down button.
2335 delay=SuspendTime << 2;
2336 south_info.raised=MagickTrue;
2337 XDrawTriangleSouth(display,&windows->widget,&south_info);
2339 if (slider_info.active)
2342 Stop tracking slider.
2344 slider_info.active=MagickFalse;
2347 if (grab_info.raised == MagickFalse)
2349 if (event.xbutton.window == windows->widget.id)
2350 if (MatteIsActive(grab_info,event.xbutton))
2353 Select a pen color from the X server.
2355 (void) XGetWindowColor(display,windows,reply_info.text);
2356 reply_info.marker=reply_info.text;
2357 reply_info.cursor=reply_info.text+Extent(reply_info.text);
2358 XDrawMatteText(display,&windows->widget,&reply_info);
2359 state|=RedrawActionState;
2361 grab_info.raised=MagickTrue;
2362 XDrawBeveledButton(display,&windows->widget,&grab_info);
2364 if (reset_info.raised == MagickFalse)
2366 if (event.xbutton.window == windows->widget.id)
2367 if (MatteIsActive(reset_info,event.xbutton))
2369 (void) CopyMagickString(glob_pattern,reset_pattern,
2371 state|=UpdateListState;
2373 reset_info.raised=MagickTrue;
2374 XDrawBeveledButton(display,&windows->widget,&reset_info);
2376 if (action_info.raised == MagickFalse)
2378 if (event.xbutton.window == windows->widget.id)
2380 if (MatteIsActive(action_info,event.xbutton))
2382 if (*reply_info.text == '\0')
2383 (void) XBell(display,0);
2388 action_info.raised=MagickTrue;
2389 XDrawBeveledButton(display,&windows->widget,&action_info);
2391 if (cancel_info.raised == MagickFalse)
2393 if (event.xbutton.window == windows->widget.id)
2394 if (MatteIsActive(cancel_info,event.xbutton))
2396 *reply_info.text='\0';
2399 cancel_info.raised=MagickTrue;
2400 XDrawBeveledButton(display,&windows->widget,&cancel_info);
2402 if (MatteIsActive(reply_info,event.xbutton) == MagickFalse)
2409 If client window delete message, exit.
2411 if (event.xclient.message_type != windows->wm_protocols)
2413 if (*event.xclient.data.l == (int) windows->wm_take_focus)
2415 (void) XSetInputFocus(display,event.xclient.window,RevertToParent,
2416 (Time) event.xclient.data.l[1]);
2419 if (*event.xclient.data.l != (int) windows->wm_delete_window)
2421 if (event.xclient.window == windows->widget.id)
2423 *reply_info.text='\0';
2429 case ConfigureNotify:
2432 Update widget configuration.
2434 if (event.xconfigure.window != windows->widget.id)
2436 if ((event.xconfigure.width == (int) windows->widget.width) &&
2437 (event.xconfigure.height == (int) windows->widget.height))
2439 windows->widget.width=(unsigned int)
2440 MagickMax(event.xconfigure.width,(int) windows->widget.min_width);
2441 windows->widget.height=(unsigned int)
2442 MagickMax(event.xconfigure.height,(int) windows->widget.min_height);
2443 state|=UpdateConfigurationState;
2448 if (event.xcrossing.window != windows->widget.id)
2450 state&=(~InactiveWidgetState);
2455 if (event.xexpose.window != windows->widget.id)
2457 if (event.xexpose.count != 0)
2459 state|=RedrawWidgetState;
2465 command[MaxTextExtent];
2474 Respond to a user key press.
2476 if (event.xkey.window != windows->widget.id)
2478 length=XLookupString((XKeyEvent *) &event.xkey,command,
2479 (int) sizeof(command),&key_symbol,(XComposeStatus *) NULL);
2480 *(command+length)='\0';
2481 if (AreaIsActive(scroll_info,event.xkey))
2486 switch ((int) key_symbol)
2509 slider_info.id-=visible_colors;
2515 slider_info.id+=visible_colors;
2521 slider_info.id=(int) colors;
2525 state|=RedrawListState;
2528 if ((key_symbol == XK_Return) || (key_symbol == XK_KP_Enter))
2531 Read new color or glob patterm.
2533 if (*reply_info.text == '\0')
2535 (void) CopyMagickString(glob_pattern,reply_info.text,MaxTextExtent);
2536 state|=UpdateListState;
2539 if (key_symbol == XK_Control_L)
2541 state|=ControlState;
2544 if (state & ControlState)
2545 switch ((int) key_symbol)
2551 Erase the entire line of text.
2553 *reply_info.text='\0';
2554 reply_info.cursor=reply_info.text;
2555 reply_info.marker=reply_info.text;
2556 reply_info.highlight=MagickFalse;
2562 XEditText(display,&reply_info,key_symbol,command,state);
2563 XDrawMatteText(display,&windows->widget,&reply_info);
2564 state|=JumpListState;
2565 status=XParseColor(display,windows->widget.map_info->colormap,
2566 reply_info.text,&color);
2567 if (status != False)
2568 state|=RedrawActionState;
2574 command[MaxTextExtent];
2580 Respond to a user key release.
2582 if (event.xkey.window != windows->widget.id)
2584 (void) XLookupString((XKeyEvent *) &event.xkey,command,
2585 (int) sizeof(command),&key_symbol,(XComposeStatus *) NULL);
2586 if (key_symbol == XK_Control_L)
2587 state&=(~ControlState);
2592 if (event.xcrossing.window != windows->widget.id)
2594 state|=InactiveWidgetState;
2606 Discard pending button motion events.
2608 while (XCheckMaskEvent(display,ButtonMotionMask,&event)) ;
2609 if (slider_info.active)
2614 slider_info.y=event.xmotion.y-
2615 ((slider_info.height+slider_info.bevel_width) >> 1)+1;
2616 if (slider_info.y < slider_info.min_y)
2617 slider_info.y=slider_info.min_y;
2618 if (slider_info.y > slider_info.max_y)
2619 slider_info.y=slider_info.max_y;
2621 if (slider_info.y != slider_info.min_y)
2622 slider_info.id=(int) ((colors*(slider_info.y-
2623 slider_info.min_y+1))/(slider_info.max_y-slider_info.min_y+1));
2624 state|=RedrawListState;
2627 if (state & InactiveWidgetState)
2629 if (grab_info.raised == MatteIsActive(grab_info,event.xmotion))
2632 Grab button status changed.
2634 grab_info.raised=!grab_info.raised;
2635 XDrawBeveledButton(display,&windows->widget,&grab_info);
2638 if (reset_info.raised == MatteIsActive(reset_info,event.xmotion))
2641 Reset button status changed.
2643 reset_info.raised=!reset_info.raised;
2644 XDrawBeveledButton(display,&windows->widget,&reset_info);
2647 if (action_info.raised == MatteIsActive(action_info,event.xmotion))
2650 Action button status changed.
2652 action_info.raised=action_info.raised == MagickFalse ?
2653 MagickTrue : MagickFalse;
2654 XDrawBeveledButton(display,&windows->widget,&action_info);
2657 if (cancel_info.raised == MatteIsActive(cancel_info,event.xmotion))
2660 Cancel button status changed.
2662 cancel_info.raised=cancel_info.raised == MagickFalse ?
2663 MagickTrue : MagickFalse;
2664 XDrawBeveledButton(display,&windows->widget,&cancel_info);
2669 case SelectionClear:
2671 reply_info.highlight=MagickFalse;
2672 XDrawMatteText(display,&windows->widget,&reply_info);
2675 case SelectionNotify:
2691 Obtain response from primary selection.
2693 if (event.xselection.property == (Atom) None)
2695 status=XGetWindowProperty(display,event.xselection.requestor,
2696 event.xselection.property,0L,2047L,MagickTrue,XA_STRING,&type,
2697 &format,&length,&after,&data);
2698 if ((status != Success) || (type != XA_STRING) || (format == 32) ||
2701 if ((Extent(reply_info.text)+length) >= MaxTextExtent)
2702 (void) XBell(display,0);
2706 Insert primary selection in reply text.
2708 *(data+length)='\0';
2709 XEditText(display,&reply_info,(KeySym) XK_Insert,(char *) data,
2711 XDrawMatteText(display,&windows->widget,&reply_info);
2712 state|=JumpListState;
2713 state|=RedrawActionState;
2715 (void) XFree((void *) data);
2718 case SelectionRequest:
2723 XSelectionRequestEvent
2726 if (reply_info.highlight == MagickFalse)
2729 Set primary selection.
2731 request=(&(event.xselectionrequest));
2732 (void) XChangeProperty(request->display,request->requestor,
2733 request->property,request->target,8,PropModeReplace,
2734 (unsigned char *) primary_selection,Extent(primary_selection));
2735 notify.type=SelectionNotify;
2736 notify.send_event=MagickTrue;
2737 notify.display=request->display;
2738 notify.requestor=request->requestor;
2739 notify.selection=request->selection;
2740 notify.target=request->target;
2741 notify.time=request->time;
2742 if (request->property == None)
2743 notify.property=request->target;
2745 notify.property=request->property;
2746 (void) XSendEvent(request->display,request->requestor,False,
2747 NoEventMask,(XEvent *) ¬ify);
2752 } while ((state & ExitState) == 0);
2753 XSetCursorState(display,windows,MagickFalse);
2754 (void) XWithdrawWindow(display,windows->widget.id,windows->widget.screen);
2755 XCheckRefreshWindows(display,windows);
2759 for (i=0; i < (ssize_t) colors; i++)
2760 colorlist[i]=DestroyString(colorlist[i]);
2761 if (colorlist != (char **) NULL)
2762 colorlist=(char **) RelinquishMagickMemory(colorlist);
2763 exception=DestroyExceptionInfo(exception);
2764 if ((*reply == '\0') || (strchr(reply,'-') != (char *) NULL))
2766 status=XParseColor(display,windows->widget.map_info->colormap,reply,&color);
2767 if (status != False)
2769 XNoticeWidget(display,windows,"Color is unknown to X server:",reply);
2770 (void) CopyMagickString(reply,"gray",MaxTextExtent);
2774 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2778 % X C o m m a n d W i d g e t %
2782 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2784 % XCommandWidget() maps a menu and returns the command pointed to by the user
2785 % when the button is released.
2787 % The format of the XCommandWidget method is:
2789 % int XCommandWidget(Display *display,XWindows *windows,
2790 % const char **selections,XEvent *event)
2792 % A description of each parameter follows:
2794 % o selection_number: Specifies the number of the selection that the
2797 % o display: Specifies a connection to an X server; returned from
2800 % o window: Specifies a pointer to a XWindows structure.
2802 % o selections: Specifies a pointer to one or more strings that comprise
2803 % the choices in the menu.
2805 % o event: Specifies a pointer to a X11 XEvent structure.
2808 MagickExport int XCommandWidget(Display *display,XWindows *windows,
2809 const char **selections,XEvent *event)
2811 #define tile_width 112
2812 #define tile_height 70
2814 static const unsigned char
2817 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2818 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2819 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2820 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00,
2821 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00,
2822 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x00,
2823 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2824 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2825 0x00, 0x00, 0x1e, 0x38, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2826 0x00, 0x00, 0x00, 0x00, 0x1e, 0xbc, 0x9f, 0x03, 0x00, 0x3e, 0x00, 0xc0,
2827 0x1f, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x1e, 0xfc, 0xff, 0x0f, 0x80, 0x3f,
2828 0x00, 0xf0, 0x1f, 0xc0, 0x0f, 0x00, 0x00, 0x00, 0x1e, 0xfc, 0xff, 0x1f,
2829 0xe0, 0x3f, 0x00, 0xfc, 0x1f, 0xf0, 0x0f, 0x00, 0x00, 0x00, 0x1e, 0xfc,
2830 0xff, 0x1f, 0xf0, 0x3f, 0x00, 0xfe, 0x1f, 0xf8, 0x0f, 0x00, 0x00, 0x00,
2831 0x1e, 0xfc, 0xfc, 0x3f, 0xf8, 0x3f, 0x00, 0xff, 0x1e, 0xfc, 0x0f, 0x00,
2832 0x00, 0x00, 0x1e, 0x7c, 0xfc, 0x3e, 0xf8, 0x3c, 0x80, 0x1f, 0x1e, 0x7c,
2833 0x0f, 0x00, 0x00, 0x00, 0x1e, 0x78, 0x78, 0x3c, 0x7c, 0x3c, 0xc0, 0x0f,
2834 0x1e, 0x3e, 0x0f, 0x00, 0x00, 0x00, 0x1e, 0x78, 0x78, 0x3c, 0x7c, 0x3c,
2835 0xc0, 0x07, 0x1e, 0x3e, 0x0f, 0x00, 0x00, 0x00, 0x1e, 0x78, 0x78, 0x3c,
2836 0x7c, 0x7c, 0xc0, 0x0f, 0x1e, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x78,
2837 0x78, 0x3c, 0xfc, 0x7c, 0x80, 0x7f, 0x1e, 0x7c, 0x00, 0x00, 0x00, 0x00,
2838 0x1e, 0xf8, 0x78, 0x7c, 0xf8, 0xff, 0x00, 0xff, 0x1f, 0xf8, 0xff, 0x00,
2839 0x00, 0x00, 0x1e, 0xf8, 0x78, 0x7c, 0xf0, 0xff, 0x07, 0xfe, 0x1f, 0xf8,
2840 0xff, 0x00, 0x00, 0x00, 0x1e, 0xf8, 0x78, 0x7c, 0xf0, 0xff, 0x07, 0xf8,
2841 0x1f, 0xf0, 0xff, 0x01, 0x00, 0x00, 0x1e, 0xf8, 0x78, 0x7c, 0xc0, 0xef,
2842 0x07, 0xe0, 0x1f, 0xc0, 0xff, 0x01, 0x00, 0x00, 0x1e, 0x70, 0x40, 0x78,
2843 0x00, 0xc7, 0x07, 0x00, 0x1e, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x1e, 0x00,
2844 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00,
2845 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00,
2846 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00,
2847 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
2848 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2849 0x00, 0xc0, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2850 0x00, 0x00, 0x00, 0xe0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2851 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
2852 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x01, 0x00, 0x00, 0x00,
2853 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00,
2854 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78,
2855 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2856 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x02, 0x00,
2857 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x07,
2858 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2859 0xc0, 0x0f, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2860 0x60, 0x00, 0xc0, 0x0f, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2861 0x00, 0x00, 0x78, 0x00, 0xc0, 0x8f, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00,
2862 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0xc0, 0x8f, 0x3f, 0x00, 0x00, 0x00,
2863 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0xe0, 0x9f, 0x7f, 0x00,
2864 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0xe0, 0xdf,
2865 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x78, 0x00,
2866 0xe0, 0xdf, 0x7b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x0c,
2867 0x78, 0x30, 0xf0, 0xff, 0x7b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e,
2868 0x00, 0x0f, 0xf8, 0x70, 0xf0, 0xff, 0x7b, 0x00, 0x00, 0x1f, 0x00, 0xe0,
2869 0x0f, 0x1e, 0x80, 0x0f, 0xf8, 0x78, 0xf0, 0xfd, 0xf9, 0x00, 0xc0, 0x1f,
2870 0x00, 0xf8, 0x0f, 0x00, 0xe0, 0x1f, 0xf8, 0x7c, 0xf0, 0xfc, 0xf9, 0x00,
2871 0xf0, 0x1f, 0x00, 0xfe, 0x0f, 0x00, 0xf0, 0x07, 0xf8, 0x3e, 0xf8, 0xfc,
2872 0xf0, 0x01, 0xf8, 0x1f, 0x00, 0xff, 0x0f, 0x1e, 0xf0, 0x03, 0xf8, 0x3f,
2873 0xf8, 0xf8, 0xf0, 0x01, 0xfc, 0x1f, 0x80, 0x7f, 0x0f, 0x1e, 0xf8, 0x00,
2874 0xf8, 0x1f, 0x78, 0x18, 0xf0, 0x01, 0x7c, 0x1e, 0xc0, 0x0f, 0x0f, 0x1e,
2875 0x7c, 0x00, 0xf0, 0x0f, 0x78, 0x00, 0xf0, 0x01, 0x3e, 0x1e, 0xe0, 0x07,
2876 0x0f, 0x1e, 0x7c, 0x00, 0xf0, 0x07, 0x7c, 0x00, 0xe0, 0x01, 0x3e, 0x1e,
2877 0xe0, 0x03, 0x0f, 0x1e, 0x3e, 0x00, 0xf0, 0x0f, 0x7c, 0x00, 0xe0, 0x03,
2878 0x3e, 0x3e, 0xe0, 0x07, 0x0f, 0x1e, 0x1e, 0x00, 0xf0, 0x1f, 0x3c, 0x00,
2879 0xe0, 0x03, 0x7e, 0x3e, 0xc0, 0x3f, 0x0f, 0x1e, 0x3e, 0x00, 0xf0, 0x1f,
2880 0x3e, 0x00, 0xe0, 0x03, 0xfc, 0x7f, 0x80, 0xff, 0x0f, 0x1e, 0xfc, 0x00,
2881 0xf0, 0x3e, 0x3e, 0x00, 0xc0, 0x03, 0xf8, 0xff, 0x03, 0xff, 0x0f, 0x1e,
2882 0xfc, 0x07, 0xf0, 0x7c, 0x1e, 0x00, 0xc0, 0x03, 0xf8, 0xff, 0x03, 0xfc,
2883 0x0f, 0x1e, 0xf8, 0x1f, 0xf0, 0xf8, 0x1e, 0x00, 0xc0, 0x03, 0xe0, 0xf7,
2884 0x03, 0xf0, 0x0f, 0x1e, 0xe0, 0x3f, 0xf0, 0x78, 0x1c, 0x00, 0x80, 0x03,
2885 0x80, 0xe3, 0x03, 0x00, 0x0f, 0x1e, 0xc0, 0x3f, 0xf0, 0x30, 0x00, 0x00,
2886 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x0e, 0x00, 0x3e, 0x00, 0x00,
2887 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x0f, 0x00, 0x00, 0x10,
2888 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x0f, 0x00,
2889 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
2890 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2891 0x00, 0xe0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2892 0x00, 0x00, 0x00, 0xf0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2893 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
2894 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00,
2895 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00,
2896 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c,
2897 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2898 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
2920 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
2921 assert(display != (Display *) NULL);
2922 assert(windows != (XWindows *) NULL);
2923 font_info=windows->command.font_info;
2924 height=(unsigned int) (font_info->ascent+font_info->descent);
2927 if (event == (XEvent *) NULL)
2939 Determine command window attributes.
2941 assert(selections != (const char **) NULL);
2942 windows->command.width=0;
2943 for (i=0; selections[i] != (char *) NULL; i++)
2945 width=WidgetTextWidth(font_info,(char *) selections[i]);
2946 if (width > windows->command.width)
2947 windows->command.width=width;
2949 number_selections=(unsigned int) i;
2950 windows->command.width+=3*QuantumMargin+10;
2951 if ((int) windows->command.width < (tile_width+QuantumMargin+10))
2952 windows->command.width=(unsigned int) (tile_width+QuantumMargin+10);
2953 windows->command.height=(unsigned int) (number_selections*
2954 (((3*height) >> 1)+10)+tile_height+20);
2955 windows->command.min_width=windows->command.width;
2956 windows->command.min_height=windows->command.height;
2957 XConstrainWindowPosition(display,&windows->command);
2958 if (windows->command.id != (Window) NULL)
2964 Reconfigure command window.
2966 status=XStringListToTextProperty(&windows->command.name,1,
2968 if (status != False)
2970 XSetWMName(display,windows->command.id,&window_name);
2971 XSetWMIconName(display,windows->command.id,&window_name);
2972 (void) XFree((void *) window_name.value);
2974 window_changes.width=(int) windows->command.width;
2975 window_changes.height=(int) windows->command.height;
2976 (void) XReconfigureWMWindow(display,windows->command.id,
2977 windows->command.screen,(unsigned int) (CWWidth | CWHeight),
2981 Allocate selection info memory.
2983 if (selection_info != (XWidgetInfo *) NULL)
2984 selection_info=(XWidgetInfo *) RelinquishMagickMemory(selection_info);
2985 selection_info=(XWidgetInfo *) AcquireQuantumMemory(number_selections,
2986 sizeof(*selection_info));
2987 if (selection_info == (XWidgetInfo *) NULL)
2989 ThrowXWindowFatalException(ResourceLimitError,
2990 "MemoryAllocationFailed","...");
2993 state|=UpdateConfigurationState | RedrawWidgetState;
2996 Wait for next event.
2998 if (event != (XEvent *) NULL)
2999 switch (event->type)
3003 for (i=0; i < (int) number_selections; i++)
3005 if (MatteIsActive(selection_info[i],event->xbutton) == MagickFalse)
3007 if (i >= (int) windows->command.data)
3009 selection_info[i].raised=MagickFalse;
3010 XDrawBeveledButton(display,&windows->command,&selection_info[i]);
3013 submenu_info=selection_info[i];
3014 submenu_info.active=MagickTrue;
3016 submenu_info.y+(submenu_info.height >> 1)-(toggle_info.height >> 1);
3018 (void) XCheckWindowEvent(display,windows->widget.id,LeaveWindowMask,
3026 for (i=0; i < (int) number_selections; i++)
3028 if (MatteIsActive(selection_info[i],event->xbutton) == MagickFalse)
3031 if (id >= (int) windows->command.data)
3033 selection_info[id].raised=MagickTrue;
3034 XDrawBeveledButton(display,&windows->command,&selection_info[id]);
3044 If client window delete message, withdraw command widget.
3046 if (event->xclient.message_type != windows->wm_protocols)
3048 if (*event->xclient.data.l != (int) windows->wm_delete_window)
3050 (void) XWithdrawWindow(display,windows->command.id,
3051 windows->command.screen);
3054 case ConfigureNotify:
3057 Update widget configuration.
3059 if (event->xconfigure.window != windows->command.id)
3061 if (event->xconfigure.send_event != 0)
3063 windows->command.x=event->xconfigure.x;
3064 windows->command.y=event->xconfigure.y;
3066 if ((event->xconfigure.width == (int) windows->command.width) &&
3067 (event->xconfigure.height == (int) windows->command.height))
3069 windows->command.width=(unsigned int)
3070 MagickMax(event->xconfigure.width,(int) windows->command.min_width);
3071 windows->command.height=(unsigned int)
3072 MagickMax(event->xconfigure.height,(int) windows->command.min_height);
3073 state|=UpdateConfigurationState;
3078 if (event->xexpose.window != windows->command.id)
3080 if (event->xexpose.count != 0)
3082 state|=RedrawWidgetState;
3088 Return the ID of the highlighted menu entry.
3092 for (i=0; i < (int) number_selections; i++)
3094 if (i >= (int) windows->command.data)
3096 if (selection_info[i].raised ==
3097 MatteIsActive(selection_info[i],event->xmotion))
3100 Button status changed.
3102 selection_info[i].raised=!selection_info[i].raised;
3103 XDrawBeveledButton(display,&windows->command,
3104 &selection_info[i]);
3108 if (MatteIsActive(selection_info[i],event->xmotion) == MagickFalse)
3110 submenu_info=selection_info[i];
3111 submenu_info.active=MagickTrue;
3112 toggle_info.raised=MagickTrue;
3113 toggle_info.y=submenu_info.y+(submenu_info.height >> 1)-
3114 (toggle_info.height >> 1);
3115 XDrawTriangleEast(display,&windows->command,&toggle_info);
3118 XDelay(display,SuspendTime);
3119 if (XCheckMaskEvent(display,ButtonMotionMask,event) == MagickFalse)
3121 while (XCheckMaskEvent(display,ButtonMotionMask,event)) ;
3122 toggle_info.raised=MagickFalse;
3123 if (windows->command.data != 0)
3124 XDrawTriangleEast(display,&windows->command,&toggle_info);
3130 windows->command.mapped=MagickTrue;
3135 windows->command.mapped=MagickFalse;
3141 if (state & UpdateConfigurationState)
3144 Initialize button information.
3146 assert(selections != (const char **) NULL);
3148 for (i=0; i < (int) number_selections; i++)
3150 XGetWidgetInfo(selections[i],&selection_info[i]);
3151 selection_info[i].center=MagickFalse;
3152 selection_info[i].bevel_width--;
3153 selection_info[i].height=(unsigned int) ((3*height) >> 1);
3154 selection_info[i].x=(QuantumMargin >> 1)+4;
3155 selection_info[i].width=(unsigned int)
3156 (windows->command.width-(selection_info[i].x << 1));
3157 selection_info[i].y=y;
3158 y+=selection_info[i].height+(selection_info[i].bevel_width << 1)+6;
3160 XGetWidgetInfo((char *) NULL,&toggle_info);
3161 toggle_info.bevel_width--;
3162 toggle_info.width=(unsigned int)
3163 (((5*height) >> 3)-(toggle_info.bevel_width << 1));
3164 toggle_info.height=toggle_info.width;
3165 toggle_info.x=selection_info[0].x+selection_info[0].width-
3166 toggle_info.width-(QuantumMargin >> 1);
3167 if (windows->command.mapped)
3168 (void) XClearWindow(display,windows->command.id);
3170 if (state & RedrawWidgetState)
3176 Draw command buttons.
3178 tile_pixmap=XCreatePixmapFromBitmapData(display,windows->command.id,
3179 (char *) tile_bits,tile_width,tile_height,1L,0L,1);
3180 if (tile_pixmap != (Pixmap) NULL)
3182 (void) XCopyPlane(display,tile_pixmap,windows->command.id,
3183 windows->command.annotate_context,0,0,tile_width,tile_height,
3184 (int) ((windows->command.width-tile_width) >> 1),10,1L);
3185 (void) XFreePixmap(display,tile_pixmap);
3187 for (i=0; i < (int) number_selections; i++)
3189 XDrawBeveledButton(display,&windows->command,&selection_info[i]);
3190 if (i >= (int) windows->command.data)
3192 toggle_info.raised=i == id ? MagickTrue : MagickFalse;
3193 toggle_info.y=selection_info[i].y+
3194 (selection_info[i].height >> 1)-(toggle_info.height >> 1);
3195 XDrawTriangleEast(display,&windows->command,&toggle_info);
3197 XHighlightWidget(display,&windows->command,BorderOffset,BorderOffset);
3203 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3207 % X C o n f i r m W i d g e t %
3211 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3213 % XConfirmWidget() displays a Confirm widget with a notice to the user. The
3214 % function returns -1 if Dismiss is pressed, 0 for Cancel, and 1 for Yes.
3216 % The format of the XConfirmWidget method is:
3218 % int XConfirmWidget(Display *display,XWindows *windows,
3219 % const char *reason,const char *description)
3221 % A description of each parameter follows:
3223 % o display: Specifies a connection to an X server; returned from
3226 % o window: Specifies a pointer to a XWindows structure.
3228 % o reason: Specifies the message to display before terminating the
3231 % o description: Specifies any description to the message.
3234 MagickExport int XConfirmWidget(Display *display,XWindows *windows,
3235 const char *reason,const char *description)
3237 #define CancelButtonText "Cancel"
3238 #define DismissButtonText "Dismiss"
3239 #define YesButtonText "Yes"
3274 Determine Confirm widget attributes.
3276 assert(display != (Display *) NULL);
3277 assert(windows != (XWindows *) NULL);
3278 assert(reason != (char *) NULL);
3279 assert(description != (char *) NULL);
3280 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",reason);
3281 XCheckRefreshWindows(display,windows);
3282 font_info=windows->widget.font_info;
3283 width=WidgetTextWidth(font_info,CancelButtonText);
3284 if (WidgetTextWidth(font_info,DismissButtonText) > width)
3285 width=WidgetTextWidth(font_info,DismissButtonText);
3286 if (WidgetTextWidth(font_info,YesButtonText) > width)
3287 width=WidgetTextWidth(font_info,YesButtonText);
3289 if (description != (char *) NULL)
3290 if (WidgetTextWidth(font_info,(char *) description) > width)
3291 width=WidgetTextWidth(font_info,(char *) description);
3292 height=(unsigned int) (font_info->ascent+font_info->descent);
3294 Position Confirm widget.
3296 windows->widget.width=(unsigned int) (width+9*QuantumMargin);
3297 windows->widget.min_width=(unsigned int) (9*QuantumMargin+
3298 WidgetTextWidth(font_info,CancelButtonText)+
3299 WidgetTextWidth(font_info,DismissButtonText)+
3300 WidgetTextWidth(font_info,YesButtonText));
3301 if (windows->widget.width < windows->widget.min_width)
3302 windows->widget.width=windows->widget.min_width;
3303 windows->widget.height=(unsigned int) (12*height);
3304 windows->widget.min_height=(unsigned int) (7*height);
3305 if (windows->widget.height < windows->widget.min_height)
3306 windows->widget.height=windows->widget.min_height;
3307 XConstrainWindowPosition(display,&windows->widget);
3311 (void) CopyMagickString(windows->widget.name,"Confirm",MaxTextExtent);
3312 status=XStringListToTextProperty(&windows->widget.name,1,&window_name);
3313 if (status != False)
3315 XSetWMName(display,windows->widget.id,&window_name);
3316 XSetWMIconName(display,windows->widget.id,&window_name);
3317 (void) XFree((void *) window_name.value);
3319 window_changes.width=(int) windows->widget.width;
3320 window_changes.height=(int) windows->widget.height;
3321 window_changes.x=windows->widget.x;
3322 window_changes.y=windows->widget.y;
3323 (void) XReconfigureWMWindow(display,windows->widget.id,windows->widget.screen,
3324 (unsigned int) (CWWidth | CWHeight | CWX | CWY),&window_changes);
3325 (void) XMapRaised(display,windows->widget.id);
3326 windows->widget.mapped=MagickFalse;
3328 Respond to X events.
3331 state=UpdateConfigurationState;
3332 XSetCursorState(display,windows,MagickTrue);
3335 if (state & UpdateConfigurationState)
3338 Initialize button information.
3340 XGetWidgetInfo(CancelButtonText,&cancel_info);
3341 cancel_info.width=(unsigned int) QuantumMargin+
3342 WidgetTextWidth(font_info,CancelButtonText);
3343 cancel_info.height=(unsigned int) ((3*height) >> 1);
3344 cancel_info.x=(int) (windows->widget.width-cancel_info.width-
3346 cancel_info.y=(int) (windows->widget.height-(cancel_info.height << 1));
3347 dismiss_info=cancel_info;
3348 dismiss_info.text=(char *) DismissButtonText;
3349 if (LocaleCompare(description,"Do you want to save it") == 0)
3350 dismiss_info.text=(char *) "Don't Save";
3351 dismiss_info.width=(unsigned int) QuantumMargin+
3352 WidgetTextWidth(font_info,dismiss_info.text);
3353 dismiss_info.x=(int)
3354 ((windows->widget.width >> 1)-(dismiss_info.width >> 1));
3355 yes_info=cancel_info;
3356 yes_info.text=(char *) YesButtonText;
3357 if (LocaleCompare(description,"Do you want to save it") == 0)
3358 yes_info.text=(char *) "Save";
3359 yes_info.width=(unsigned int) QuantumMargin+
3360 WidgetTextWidth(font_info,yes_info.text);
3361 if (yes_info.width < cancel_info.width)
3362 yes_info.width=cancel_info.width;
3363 yes_info.x=QuantumMargin;
3364 state&=(~UpdateConfigurationState);
3366 if (state & RedrawWidgetState)
3369 Redraw Confirm widget.
3371 width=WidgetTextWidth(font_info,(char *) reason);
3372 x=(int) ((windows->widget.width >> 1)-(width >> 1));
3373 y=(int) ((windows->widget.height >> 1)-(height << 1));
3374 (void) XDrawString(display,windows->widget.id,
3375 windows->widget.annotate_context,x,y,(char *) reason,Extent(reason));
3376 if (description != (char *) NULL)
3379 question[MaxTextExtent];
3381 (void) CopyMagickString(question,description,MaxTextExtent);
3382 (void) ConcatenateMagickString(question,"?",MaxTextExtent);
3383 width=WidgetTextWidth(font_info,question);
3384 x=(int) ((windows->widget.width >> 1)-(width >> 1));
3386 (void) XDrawString(display,windows->widget.id,
3387 windows->widget.annotate_context,x,y,question,Extent(question));
3389 XDrawBeveledButton(display,&windows->widget,&cancel_info);
3390 XDrawBeveledButton(display,&windows->widget,&dismiss_info);
3391 XDrawBeveledButton(display,&windows->widget,&yes_info);
3392 XHighlightWidget(display,&windows->widget,BorderOffset,BorderOffset);
3393 state&=(~RedrawWidgetState);
3396 Wait for next event.
3398 (void) XIfEvent(display,&event,XScreenEvent,(char *) windows);
3403 if (MatteIsActive(cancel_info,event.xbutton))
3406 User pressed No button.
3408 cancel_info.raised=MagickFalse;
3409 XDrawBeveledButton(display,&windows->widget,&cancel_info);
3412 if (MatteIsActive(dismiss_info,event.xbutton))
3415 User pressed Dismiss button.
3417 dismiss_info.raised=MagickFalse;
3418 XDrawBeveledButton(display,&windows->widget,&dismiss_info);
3421 if (MatteIsActive(yes_info,event.xbutton))
3424 User pressed Yes button.
3426 yes_info.raised=MagickFalse;
3427 XDrawBeveledButton(display,&windows->widget,&yes_info);
3434 if (windows->widget.mapped == MagickFalse)
3436 if (cancel_info.raised == MagickFalse)
3438 if (event.xbutton.window == windows->widget.id)
3439 if (MatteIsActive(cancel_info,event.xbutton))
3444 cancel_info.raised=MagickTrue;
3445 XDrawBeveledButton(display,&windows->widget,&cancel_info);
3447 if (dismiss_info.raised == MagickFalse)
3449 if (event.xbutton.window == windows->widget.id)
3450 if (MatteIsActive(dismiss_info,event.xbutton))
3455 dismiss_info.raised=MagickTrue;
3456 XDrawBeveledButton(display,&windows->widget,&dismiss_info);
3458 if (yes_info.raised == MagickFalse)
3460 if (event.xbutton.window == windows->widget.id)
3461 if (MatteIsActive(yes_info,event.xbutton))
3466 yes_info.raised=MagickTrue;
3467 XDrawBeveledButton(display,&windows->widget,&yes_info);
3474 If client window delete message, exit.
3476 if (event.xclient.message_type != windows->wm_protocols)
3478 if (*event.xclient.data.l == (int) windows->wm_take_focus)
3480 (void) XSetInputFocus(display,event.xclient.window,RevertToParent,
3481 (Time) event.xclient.data.l[1]);
3484 if (*event.xclient.data.l != (int) windows->wm_delete_window)
3486 if (event.xclient.window == windows->widget.id)
3493 case ConfigureNotify:
3496 Update widget configuration.
3498 if (event.xconfigure.window != windows->widget.id)
3500 if ((event.xconfigure.width == (int) windows->widget.width) &&
3501 (event.xconfigure.height == (int) windows->widget.height))
3503 windows->widget.width=(unsigned int)
3504 MagickMax(event.xconfigure.width,(int) windows->widget.min_width);
3505 windows->widget.height=(unsigned int)
3506 MagickMax(event.xconfigure.height,(int) windows->widget.min_height);
3507 state|=UpdateConfigurationState;
3512 if (event.xcrossing.window != windows->widget.id)
3514 state&=(~InactiveWidgetState);
3519 if (event.xexpose.window != windows->widget.id)
3521 if (event.xexpose.count != 0)
3523 state|=RedrawWidgetState;
3529 command[MaxTextExtent];
3535 Respond to a user key press.
3537 if (event.xkey.window != windows->widget.id)
3539 (void) XLookupString((XKeyEvent *) &event.xkey,command,
3540 (int) sizeof(command),&key_symbol,(XComposeStatus *) NULL);
3541 if ((key_symbol == XK_Return) || (key_symbol == XK_KP_Enter))
3543 yes_info.raised=MagickFalse;
3544 XDrawBeveledButton(display,&windows->widget,&yes_info);
3553 if (event.xcrossing.window != windows->widget.id)
3555 state|=InactiveWidgetState;
3561 Discard pending button motion events.
3563 while (XCheckMaskEvent(display,ButtonMotionMask,&event)) ;
3564 if (state & InactiveWidgetState)
3566 if (cancel_info.raised == MatteIsActive(cancel_info,event.xmotion))
3569 Cancel button status changed.
3571 cancel_info.raised=cancel_info.raised == MagickFalse ?
3572 MagickTrue : MagickFalse;
3573 XDrawBeveledButton(display,&windows->widget,&cancel_info);
3576 if (dismiss_info.raised == MatteIsActive(dismiss_info,event.xmotion))
3579 Dismiss button status changed.
3581 dismiss_info.raised=cancel_info.raised == MagickFalse ?
3582 MagickTrue : MagickFalse;
3583 XDrawBeveledButton(display,&windows->widget,&dismiss_info);
3586 if (yes_info.raised == MatteIsActive(yes_info,event.xmotion))
3589 Yes button status changed.
3591 yes_info.raised=yes_info.raised == MagickFalse ?
3592 MagickTrue : MagickFalse;
3593 XDrawBeveledButton(display,&windows->widget,&yes_info);
3601 } while ((state & ExitState) == 0);
3602 XSetCursorState(display,windows,MagickFalse);
3603 (void) XWithdrawWindow(display,windows->widget.id,windows->widget.screen);
3604 XCheckRefreshWindows(display,windows);
3609 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3613 % X D i a l o g W i d g e t %
3617 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3619 % XDialogWidget() displays a Dialog widget with a query to the user. The user
3620 % keys a reply and presses the Ok or Cancel button to exit. The typed text is
3621 % returned as the reply function parameter.
3623 % The format of the XDialogWidget method is:
3625 % int XDialogWidget(Display *display,XWindows *windows,const char *action,
3626 % const char *query,char *reply)
3628 % A description of each parameter follows:
3630 % o display: Specifies a connection to an X server; returned from
3633 % o window: Specifies a pointer to a XWindows structure.
3635 % o action: Specifies a pointer to the action of this widget.
3637 % o query: Specifies a pointer to the query to present to the user.
3639 % o reply: the response from the user is returned in this parameter.
3642 MagickExport int XDialogWidget(Display *display,XWindows *windows,
3643 const char *action,const char *query,char *reply)
3645 #define CancelButtonText "Cancel"
3648 primary_selection[MaxTextExtent];
3656 static MagickBooleanType
3657 raised = MagickFalse;
3690 Determine Dialog widget attributes.
3692 assert(display != (Display *) NULL);
3693 assert(windows != (XWindows *) NULL);
3694 assert(action != (char *) NULL);
3695 assert(query != (char *) NULL);
3696 assert(reply != (char *) NULL);
3697 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",action);
3698 XCheckRefreshWindows(display,windows);
3699 font_info=windows->widget.font_info;
3700 width=WidgetTextWidth(font_info,(char *) action);
3701 if (WidgetTextWidth(font_info,CancelButtonText) > width)
3702 width=WidgetTextWidth(font_info,CancelButtonText);
3703 width+=(3*QuantumMargin) >> 1;
3704 height=(unsigned int) (font_info->ascent+font_info->descent);
3706 Position Dialog widget.
3708 windows->widget.width=(unsigned int) MagickMax(2*width,(int) WidgetTextWidth(
3709 font_info,(char *) query));
3710 if (windows->widget.width < WidgetTextWidth(font_info,reply))
3711 windows->widget.width=WidgetTextWidth(font_info,reply);
3712 windows->widget.width+=6*QuantumMargin;
3713 windows->widget.min_width=(unsigned int)
3714 (width+28*XTextWidth(font_info,"#",1)+4*QuantumMargin);
3715 if (windows->widget.width < windows->widget.min_width)
3716 windows->widget.width=windows->widget.min_width;
3717 windows->widget.height=(unsigned int) (7*height+(QuantumMargin << 1));
3718 windows->widget.min_height=windows->widget.height;
3719 if (windows->widget.height < windows->widget.min_height)
3720 windows->widget.height=windows->widget.min_height;
3721 XConstrainWindowPosition(display,&windows->widget);
3725 (void) CopyMagickString(windows->widget.name,"Dialog",MaxTextExtent);
3726 status=XStringListToTextProperty(&windows->widget.name,1,&window_name);
3727 if (status != False)
3729 XSetWMName(display,windows->widget.id,&window_name);
3730 XSetWMIconName(display,windows->widget.id,&window_name);
3731 (void) XFree((void *) window_name.value);
3733 window_changes.width=(int) windows->widget.width;
3734 window_changes.height=(int) windows->widget.height;
3735 window_changes.x=windows->widget.x;
3736 window_changes.y=windows->widget.y;
3737 (void) XReconfigureWMWindow(display,windows->widget.id,windows->widget.screen,
3738 (unsigned int) (CWWidth | CWHeight | CWX | CWY),&window_changes);
3739 (void) XMapRaised(display,windows->widget.id);
3740 windows->widget.mapped=MagickFalse;
3742 Respond to X events.
3744 anomaly=(LocaleCompare(action,"Background") == 0) ||
3745 (LocaleCompare(action,"New") == 0) ||
3746 (LocaleCompare(action,"Quantize") == 0) ||
3747 (LocaleCompare(action,"Resize") == 0) ||
3748 (LocaleCompare(action,"Save") == 0) ||
3749 (LocaleCompare(action,"Shade") == 0);
3750 state=UpdateConfigurationState;
3751 XSetCursorState(display,windows,MagickTrue);
3754 if (state & UpdateConfigurationState)
3757 Initialize button information.
3759 XGetWidgetInfo(CancelButtonText,&cancel_info);
3760 cancel_info.width=width;
3761 cancel_info.height=(unsigned int) ((3*height) >> 1);
3763 (windows->widget.width-cancel_info.width-((3*QuantumMargin) >> 1));
3765 (windows->widget.height-cancel_info.height-((3*QuantumMargin) >> 1));
3766 XGetWidgetInfo(action,&action_info);
3767 action_info.width=width;
3768 action_info.height=(unsigned int) ((3*height) >> 1);
3769 action_info.x=cancel_info.x-(cancel_info.width+QuantumMargin+
3770 (action_info.bevel_width << 1));
3771 action_info.y=cancel_info.y;
3773 Initialize reply information.
3775 XGetWidgetInfo(reply,&reply_info);
3776 reply_info.raised=MagickFalse;
3777 reply_info.bevel_width--;
3778 reply_info.width=windows->widget.width-(3*QuantumMargin);
3779 reply_info.height=height << 1;
3780 reply_info.x=(3*QuantumMargin) >> 1;
3781 reply_info.y=action_info.y-reply_info.height-QuantumMargin;
3783 Initialize option information.
3785 XGetWidgetInfo("Dither",&special_info);
3786 special_info.raised=raised;
3787 special_info.bevel_width--;
3788 special_info.width=(unsigned int) QuantumMargin >> 1;
3789 special_info.height=(unsigned int) QuantumMargin >> 1;
3790 special_info.x=reply_info.x;
3791 special_info.y=action_info.y+action_info.height-special_info.height;
3792 if (LocaleCompare(action,"Background") == 0)
3793 special_info.text=(char *) "Backdrop";
3794 if (LocaleCompare(action,"New") == 0)
3795 special_info.text=(char *) "Gradation";
3796 if (LocaleCompare(action,"Resize") == 0)
3797 special_info.text=(char *) "Constrain ratio";
3798 if (LocaleCompare(action,"Save") == 0)
3799 special_info.text=(char *) "Non-progressive";
3800 if (LocaleCompare(action,"Shade") == 0)
3801 special_info.text=(char *) "Color shading";
3803 Initialize text information.
3805 XGetWidgetInfo(query,&text_info);
3806 text_info.width=reply_info.width;
3807 text_info.height=height;
3808 text_info.x=reply_info.x-(QuantumMargin >> 1);
3809 text_info.y=QuantumMargin;
3810 text_info.center=MagickFalse;
3811 state&=(~UpdateConfigurationState);
3813 if (state & RedrawWidgetState)
3816 Redraw Dialog widget.
3818 XDrawWidgetText(display,&windows->widget,&text_info);
3819 XDrawBeveledMatte(display,&windows->widget,&reply_info);
3820 XDrawMatteText(display,&windows->widget,&reply_info);
3822 XDrawBeveledButton(display,&windows->widget,&special_info);
3823 XDrawBeveledButton(display,&windows->widget,&action_info);
3824 XDrawBeveledButton(display,&windows->widget,&cancel_info);
3825 XHighlightWidget(display,&windows->widget,BorderOffset,BorderOffset);
3826 state&=(~RedrawWidgetState);
3829 Wait for next event.
3831 (void) XIfEvent(display,&event,XScreenEvent,(char *) windows);
3837 if (MatteIsActive(special_info,event.xbutton))
3840 Option button status changed.
3842 special_info.raised=!special_info.raised;
3843 XDrawBeveledButton(display,&windows->widget,&special_info);
3846 if (MatteIsActive(action_info,event.xbutton))
3849 User pressed Action button.
3851 action_info.raised=MagickFalse;
3852 XDrawBeveledButton(display,&windows->widget,&action_info);
3855 if (MatteIsActive(cancel_info,event.xbutton))
3858 User pressed Cancel button.
3860 cancel_info.raised=MagickFalse;
3861 XDrawBeveledButton(display,&windows->widget,&cancel_info);
3864 if (MatteIsActive(reply_info,event.xbutton) == MagickFalse)
3866 if (event.xbutton.button != Button2)
3872 Move text cursor to position of button press.
3874 x=event.xbutton.x-reply_info.x-(QuantumMargin >> 2);
3875 for (i=1; i <= Extent(reply_info.marker); i++)
3876 if (XTextWidth(font_info,reply_info.marker,i) > x)
3878 reply_info.cursor=reply_info.marker+i-1;
3879 if (event.xbutton.time > (click_time+DoubleClick))
3880 reply_info.highlight=MagickFalse;
3884 Become the XA_PRIMARY selection owner.
3886 (void) CopyMagickString(primary_selection,reply_info.text,
3888 (void) XSetSelectionOwner(display,XA_PRIMARY,windows->widget.id,
3889 event.xbutton.time);
3890 reply_info.highlight=XGetSelectionOwner(display,XA_PRIMARY) ==
3891 windows->widget.id ? MagickTrue : MagickFalse;
3893 XDrawMatteText(display,&windows->widget,&reply_info);
3894 click_time=event.xbutton.time;
3898 Request primary selection.
3900 (void) XConvertSelection(display,XA_PRIMARY,XA_STRING,XA_STRING,
3901 windows->widget.id,event.xbutton.time);
3906 if (windows->widget.mapped == MagickFalse)
3908 if (action_info.raised == MagickFalse)
3910 if (event.xbutton.window == windows->widget.id)
3911 if (MatteIsActive(action_info,event.xbutton))
3913 action_info.raised=MagickTrue;
3914 XDrawBeveledButton(display,&windows->widget,&action_info);
3916 if (cancel_info.raised == MagickFalse)
3918 if (event.xbutton.window == windows->widget.id)
3919 if (MatteIsActive(cancel_info,event.xbutton))
3921 *reply_info.text='\0';
3924 cancel_info.raised=MagickTrue;
3925 XDrawBeveledButton(display,&windows->widget,&cancel_info);
3932 If client window delete message, exit.
3934 if (event.xclient.message_type != windows->wm_protocols)
3936 if (*event.xclient.data.l == (int) windows->wm_take_focus)
3938 (void) XSetInputFocus(display,event.xclient.window,RevertToParent,
3939 (Time) event.xclient.data.l[1]);
3942 if (*event.xclient.data.l != (int) windows->wm_delete_window)
3944 if (event.xclient.window == windows->widget.id)
3946 *reply_info.text='\0';
3952 case ConfigureNotify:
3955 Update widget configuration.
3957 if (event.xconfigure.window != windows->widget.id)
3959 if ((event.xconfigure.width == (int) windows->widget.width) &&
3960 (event.xconfigure.height == (int) windows->widget.height))
3962 windows->widget.width=(unsigned int)
3963 MagickMax(event.xconfigure.width,(int) windows->widget.min_width);
3964 windows->widget.height=(unsigned int)
3965 MagickMax(event.xconfigure.height,(int) windows->widget.min_height);
3966 state|=UpdateConfigurationState;
3971 if (event.xcrossing.window != windows->widget.id)
3973 state&=(~InactiveWidgetState);
3978 if (event.xexpose.window != windows->widget.id)
3980 if (event.xexpose.count != 0)
3982 state|=RedrawWidgetState;
3988 command[MaxTextExtent];
3997 Respond to a user key press.
3999 if (event.xkey.window != windows->widget.id)
4001 length=XLookupString((XKeyEvent *) &event.xkey,command,
4002 (int) sizeof(command),&key_symbol,(XComposeStatus *) NULL);
4003 *(command+length)='\0';
4004 if ((key_symbol == XK_Return) || (key_symbol == XK_KP_Enter))
4006 action_info.raised=MagickFalse;
4007 XDrawBeveledButton(display,&windows->widget,&action_info);
4011 if (key_symbol == XK_Control_L)
4013 state|=ControlState;
4016 if (state & ControlState)
4017 switch ((int) key_symbol)
4023 Erase the entire line of text.
4025 *reply_info.text='\0';
4026 reply_info.cursor=reply_info.text;
4027 reply_info.marker=reply_info.text;
4028 reply_info.highlight=MagickFalse;
4034 XEditText(display,&reply_info,key_symbol,command,state);
4035 XDrawMatteText(display,&windows->widget,&reply_info);
4041 command[MaxTextExtent];
4047 Respond to a user key release.
4049 if (event.xkey.window != windows->widget.id)
4051 (void) XLookupString((XKeyEvent *) &event.xkey,command,
4052 (int) sizeof(command),&key_symbol,(XComposeStatus *) NULL);
4053 if (key_symbol == XK_Control_L)
4054 state&=(~ControlState);
4059 if (event.xcrossing.window != windows->widget.id)
4061 state|=InactiveWidgetState;
4067 Discard pending button motion events.
4069 while (XCheckMaskEvent(display,ButtonMotionMask,&event)) ;
4070 if (state & InactiveWidgetState)
4072 if (action_info.raised == MatteIsActive(action_info,event.xmotion))
4075 Action button status changed.
4077 action_info.raised=action_info.raised == MagickFalse ?
4078 MagickTrue : MagickFalse;
4079 XDrawBeveledButton(display,&windows->widget,&action_info);
4082 if (cancel_info.raised == MatteIsActive(cancel_info,event.xmotion))
4085 Cancel button status changed.
4087 cancel_info.raised=cancel_info.raised == MagickFalse ?
4088 MagickTrue : MagickFalse;
4089 XDrawBeveledButton(display,&windows->widget,&cancel_info);
4094 case SelectionClear:
4096 reply_info.highlight=MagickFalse;
4097 XDrawMatteText(display,&windows->widget,&reply_info);
4100 case SelectionNotify:
4116 Obtain response from primary selection.
4118 if (event.xselection.property == (Atom) None)
4120 status=XGetWindowProperty(display,event.xselection.requestor,
4121 event.xselection.property,0L,2047L,MagickTrue,XA_STRING,&type,
4122 &format,&length,&after,&data);
4123 if ((status != Success) || (type != XA_STRING) || (format == 32) ||
4126 if ((Extent(reply_info.text)+length) >= MaxTextExtent)
4127 (void) XBell(display,0);
4131 Insert primary selection in reply text.
4133 *(data+length)='\0';
4134 XEditText(display,&reply_info,(KeySym) XK_Insert,(char *) data,
4136 XDrawMatteText(display,&windows->widget,&reply_info);
4138 (void) XFree((void *) data);
4141 case SelectionRequest:
4146 XSelectionRequestEvent
4149 if (reply_info.highlight == MagickFalse)
4152 Set primary selection.
4154 request=(&(event.xselectionrequest));
4155 (void) XChangeProperty(request->display,request->requestor,
4156 request->property,request->target,8,PropModeReplace,
4157 (unsigned char *) primary_selection,Extent(primary_selection));
4158 notify.type=SelectionNotify;
4159 notify.display=request->display;
4160 notify.requestor=request->requestor;
4161 notify.selection=request->selection;
4162 notify.target=request->target;
4163 notify.time=request->time;
4164 if (request->property == None)
4165 notify.property=request->target;
4167 notify.property=request->property;
4168 (void) XSendEvent(request->display,request->requestor,False,0,
4169 (XEvent *) ¬ify);
4174 } while ((state & ExitState) == 0);
4175 XSetCursorState(display,windows,MagickFalse);
4176 (void) XWithdrawWindow(display,windows->widget.id,windows->widget.screen);
4177 XCheckRefreshWindows(display,windows);
4179 if (special_info.raised)
4182 return(raised == MagickFalse);
4186 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4190 % X F i l e B r o w s e r W i d g e t %
4194 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4196 % XFileBrowserWidget() displays a File Browser widget with a file query to the
4197 % user. The user keys a reply and presses the Action or Cancel button to
4198 % exit. The typed text is returned as the reply function parameter.
4200 % The format of the XFileBrowserWidget method is:
4202 % void XFileBrowserWidget(Display *display,XWindows *windows,
4203 % const char *action,char *reply)
4205 % A description of each parameter follows:
4207 % o display: Specifies a connection to an X server; returned from
4210 % o window: Specifies a pointer to a XWindows structure.
4212 % o action: Specifies a pointer to the action of this widget.
4214 % o reply: the response from the user is returned in this parameter.
4217 MagickExport void XFileBrowserWidget(Display *display,XWindows *windows,
4218 const char *action,char *reply)
4220 #define CancelButtonText "Cancel"
4221 #define DirectoryText "Directory:"
4222 #define FilenameText "File name:"
4223 #define GrabButtonText "Grab"
4224 #define FormatButtonText "Format"
4225 #define HomeButtonText "Home"
4226 #define UpButtonText "Up"
4231 home_directory[MaxTextExtent],
4232 primary_selection[MaxTextExtent],
4233 text[MaxTextExtent],
4234 working_path[MaxTextExtent];
4244 glob_pattern[MaxTextExtent] = "*",
4245 format[MaxTextExtent] = "miff";
4247 static MagickStatusType
4248 mask = (MagickStatusType) (CWWidth | CWHeight | CWX | CWY);
4294 Read filelist from current directory.
4296 assert(display != (Display *) NULL);
4297 assert(windows != (XWindows *) NULL);
4298 assert(action != (char *) NULL);
4299 assert(reply != (char *) NULL);
4300 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",action);
4301 XSetCursorState(display,windows,MagickTrue);
4302 XCheckRefreshWindows(display,windows);
4303 cwd=getcwd(home_directory,MaxTextExtent);
4304 (void) CopyMagickString(working_path,home_directory,MaxTextExtent);
4305 filelist=ListFiles(working_path,glob_pattern,&files);
4306 if (filelist == (char **) NULL)
4309 Directory read failed.
4311 XNoticeWidget(display,windows,"Unable to read directory:",working_path);
4312 (void) XDialogWidget(display,windows,action,"Enter filename:",reply);
4316 Determine File Browser widget attributes.
4318 font_info=windows->widget.font_info;
4320 for (i=0; i < (ssize_t) files; i++)
4321 if (WidgetTextWidth(font_info,filelist[i]) > text_width)
4322 text_width=WidgetTextWidth(font_info,filelist[i]);
4323 width=WidgetTextWidth(font_info,(char *) action);
4324 if (WidgetTextWidth(font_info,GrabButtonText) > width)
4325 width=WidgetTextWidth(font_info,GrabButtonText);
4326 if (WidgetTextWidth(font_info,FormatButtonText) > width)
4327 width=WidgetTextWidth(font_info,FormatButtonText);
4328 if (WidgetTextWidth(font_info,CancelButtonText) > width)
4329 width=WidgetTextWidth(font_info,CancelButtonText);
4330 if (WidgetTextWidth(font_info,HomeButtonText) > width)
4331 width=WidgetTextWidth(font_info,HomeButtonText);
4332 if (WidgetTextWidth(font_info,UpButtonText) > width)
4333 width=WidgetTextWidth(font_info,UpButtonText);
4334 width+=QuantumMargin;
4335 if (WidgetTextWidth(font_info,DirectoryText) > width)
4336 width=WidgetTextWidth(font_info,DirectoryText);
4337 if (WidgetTextWidth(font_info,FilenameText) > width)
4338 width=WidgetTextWidth(font_info,FilenameText);
4339 height=(unsigned int) (font_info->ascent+font_info->descent);
4341 Position File Browser widget.
4343 windows->widget.width=width+MagickMin((int) text_width,(int) MaxTextWidth)+
4345 windows->widget.min_width=width+MinTextWidth+4*QuantumMargin;
4346 if (windows->widget.width < windows->widget.min_width)
4347 windows->widget.width=windows->widget.min_width;
4348 windows->widget.height=(unsigned int)
4349 (((81*height) >> 2)+((13*QuantumMargin) >> 1)+4);
4350 windows->widget.min_height=(unsigned int)
4351 (((23*height) >> 1)+((13*QuantumMargin) >> 1)+4);
4352 if (windows->widget.height < windows->widget.min_height)
4353 windows->widget.height=windows->widget.min_height;
4354 XConstrainWindowPosition(display,&windows->widget);
4356 Map File Browser widget.
4358 (void) CopyMagickString(windows->widget.name,"Browse and Select a File",
4360 status=XStringListToTextProperty(&windows->widget.name,1,&window_name);
4361 if (status != False)
4363 XSetWMName(display,windows->widget.id,&window_name);
4364 XSetWMIconName(display,windows->widget.id,&window_name);
4365 (void) XFree((void *) window_name.value);
4367 window_changes.width=(int) windows->widget.width;
4368 window_changes.height=(int) windows->widget.height;
4369 window_changes.x=windows->widget.x;
4370 window_changes.y=windows->widget.y;
4371 (void) XReconfigureWMWindow(display,windows->widget.id,
4372 windows->widget.screen,mask,&window_changes);
4373 (void) XMapRaised(display,windows->widget.id);
4374 windows->widget.mapped=MagickFalse;
4376 Respond to X events.
4378 XGetWidgetInfo((char *) NULL,&slider_info);
4379 XGetWidgetInfo((char *) NULL,&north_info);
4380 XGetWidgetInfo((char *) NULL,&south_info);
4381 XGetWidgetInfo((char *) NULL,&expose_info);
4383 anomaly=(LocaleCompare(action,"Composite") == 0) ||
4384 (LocaleCompare(action,"Open") == 0) || (LocaleCompare(action,"Map") == 0);
4386 delay=SuspendTime << 2;
4387 state=UpdateConfigurationState;
4390 if (state & UpdateConfigurationState)
4396 Initialize button information.
4398 XGetWidgetInfo(CancelButtonText,&cancel_info);
4399 cancel_info.width=width;
4400 cancel_info.height=(unsigned int) ((3*height) >> 1);
4402 (windows->widget.width-cancel_info.width-QuantumMargin-2);
4404 (windows->widget.height-cancel_info.height-QuantumMargin);
4405 XGetWidgetInfo(action,&action_info);
4406 action_info.width=width;
4407 action_info.height=(unsigned int) ((3*height) >> 1);
4408 action_info.x=cancel_info.x-(cancel_info.width+(QuantumMargin >> 1)+
4409 (action_info.bevel_width << 1));
4410 action_info.y=cancel_info.y;
4411 XGetWidgetInfo(GrabButtonText,&special_info);
4412 special_info.width=width;
4413 special_info.height=(unsigned int) ((3*height) >> 1);
4414 special_info.x=action_info.x-(action_info.width+(QuantumMargin >> 1)+
4415 (special_info.bevel_width << 1));
4416 special_info.y=action_info.y;
4417 if (anomaly == MagickFalse)
4422 special_info.text=(char *) FormatButtonText;
4423 p=reply+Extent(reply)-1;
4424 while ((p > (reply+1)) && (*(p-1) != '.'))
4426 if ((p > (reply+1)) && (*(p-1) == '.'))
4427 (void) CopyMagickString(format,p,MaxTextExtent);
4429 XGetWidgetInfo(UpButtonText,&up_info);
4430 up_info.width=width;
4431 up_info.height=(unsigned int) ((3*height) >> 1);
4432 up_info.x=QuantumMargin;
4433 up_info.y=((5*QuantumMargin) >> 1)+height;
4434 XGetWidgetInfo(HomeButtonText,&home_info);
4435 home_info.width=width;
4436 home_info.height=(unsigned int) ((3*height) >> 1);
4437 home_info.x=QuantumMargin;
4438 home_info.y=up_info.y+up_info.height+QuantumMargin;
4440 Initialize reply information.
4442 XGetWidgetInfo(reply,&reply_info);
4443 reply_info.raised=MagickFalse;
4444 reply_info.bevel_width--;
4445 reply_info.width=windows->widget.width-width-((6*QuantumMargin) >> 1);
4446 reply_info.height=height << 1;
4447 reply_info.x=(int) (width+(QuantumMargin << 1));
4448 reply_info.y=action_info.y-reply_info.height-QuantumMargin;
4450 Initialize scroll information.
4452 XGetWidgetInfo((char *) NULL,&scroll_info);
4453 scroll_info.bevel_width--;
4454 scroll_info.width=height;
4455 scroll_info.height=(unsigned int)
4456 (reply_info.y-up_info.y-(QuantumMargin >> 1));
4457 scroll_info.x=reply_info.x+(reply_info.width-scroll_info.width);
4458 scroll_info.y=up_info.y-reply_info.bevel_width;
4459 scroll_info.raised=MagickFalse;
4460 scroll_info.trough=MagickTrue;
4461 north_info=scroll_info;
4462 north_info.raised=MagickTrue;
4463 north_info.width-=(north_info.bevel_width << 1);
4464 north_info.height=north_info.width-1;
4465 north_info.x+=north_info.bevel_width;
4466 north_info.y+=north_info.bevel_width;
4467 south_info=north_info;
4468 south_info.y=scroll_info.y+scroll_info.height-scroll_info.bevel_width-
4471 slider_info=north_info;
4473 slider_info.width-=2;
4474 slider_info.min_y=north_info.y+north_info.height+north_info.bevel_width+
4475 slider_info.bevel_width+2;
4476 slider_info.height=scroll_info.height-((slider_info.min_y-
4477 scroll_info.y+1) << 1)+4;
4478 visible_files=scroll_info.height/(height+(height >> 3));
4479 if (files > visible_files)
4480 slider_info.height=(unsigned int)
4481 ((visible_files*slider_info.height)/files);
4482 slider_info.max_y=south_info.y-south_info.bevel_width-
4483 slider_info.bevel_width-2;
4484 slider_info.x=scroll_info.x+slider_info.bevel_width+1;
4485 slider_info.y=slider_info.min_y;
4486 expose_info=scroll_info;
4487 expose_info.y=slider_info.y;
4489 Initialize list information.
4491 XGetWidgetInfo((char *) NULL,&list_info);
4492 list_info.raised=MagickFalse;
4493 list_info.bevel_width--;
4494 list_info.width=(unsigned int)
4495 (scroll_info.x-reply_info.x-(QuantumMargin >> 1));
4496 list_info.height=scroll_info.height;
4497 list_info.x=reply_info.x;
4498 list_info.y=scroll_info.y;
4499 if (windows->widget.mapped == MagickFalse)
4500 state|=JumpListState;
4502 Initialize text information.
4505 XGetWidgetInfo(text,&text_info);
4506 text_info.center=MagickFalse;
4507 text_info.width=reply_info.width;
4508 text_info.height=height;
4509 text_info.x=list_info.x-(QuantumMargin >> 1);
4510 text_info.y=QuantumMargin;
4512 Initialize selection information.
4514 XGetWidgetInfo((char *) NULL,&selection_info);
4515 selection_info.center=MagickFalse;
4516 selection_info.width=list_info.width;
4517 selection_info.height=(unsigned int) ((9*height) >> 3);
4518 selection_info.x=list_info.x;
4519 state&=(~UpdateConfigurationState);
4521 if (state & RedrawWidgetState)
4524 Redraw File Browser window.
4527 y=text_info.y+((text_info.height-height) >> 1)+font_info->ascent;
4528 (void) XDrawString(display,windows->widget.id,
4529 windows->widget.annotate_context,x,y,DirectoryText,
4530 Extent(DirectoryText));
4531 (void) CopyMagickString(text_info.text,working_path,MaxTextExtent);
4532 (void) ConcatenateMagickString(text_info.text,DirectorySeparator,
4534 (void) ConcatenateMagickString(text_info.text,glob_pattern,
4536 XDrawWidgetText(display,&windows->widget,&text_info);
4537 XDrawBeveledButton(display,&windows->widget,&up_info);
4538 XDrawBeveledButton(display,&windows->widget,&home_info);
4539 XDrawBeveledMatte(display,&windows->widget,&list_info);
4540 XDrawBeveledMatte(display,&windows->widget,&scroll_info);
4541 XDrawTriangleNorth(display,&windows->widget,&north_info);
4542 XDrawBeveledButton(display,&windows->widget,&slider_info);
4543 XDrawTriangleSouth(display,&windows->widget,&south_info);
4545 y=reply_info.y+((reply_info.height-height) >> 1)+font_info->ascent;
4546 (void) XDrawString(display,windows->widget.id,
4547 windows->widget.annotate_context,x,y,FilenameText,
4548 Extent(FilenameText));
4549 XDrawBeveledMatte(display,&windows->widget,&reply_info);
4550 XDrawMatteText(display,&windows->widget,&reply_info);
4551 XDrawBeveledButton(display,&windows->widget,&special_info);
4552 XDrawBeveledButton(display,&windows->widget,&action_info);
4553 XDrawBeveledButton(display,&windows->widget,&cancel_info);
4554 XHighlightWidget(display,&windows->widget,BorderOffset,BorderOffset);
4555 selection_info.id=(~0);
4556 state|=RedrawListState;
4557 state&=(~RedrawWidgetState);
4559 if (state & UpdateListState)
4570 checklist=ListFiles(working_path,glob_pattern,&number_files);
4571 if (checklist == (char **) NULL)
4574 Reply is a filename, exit.
4576 action_info.raised=MagickFalse;
4577 XDrawBeveledButton(display,&windows->widget,&action_info);
4580 for (i=0; i < (ssize_t) files; i++)
4581 filelist[i]=DestroyString(filelist[i]);
4582 if (filelist != (char **) NULL)
4583 filelist=(char **) RelinquishMagickMemory(filelist);
4590 scroll_info.height-((slider_info.min_y-scroll_info.y+1) << 1)+1;
4591 if (files > visible_files)
4592 slider_info.height=(unsigned int)
4593 ((visible_files*slider_info.height)/files);
4594 slider_info.max_y=south_info.y-south_info.bevel_width-
4595 slider_info.bevel_width-2;
4597 slider_info.y=slider_info.min_y;
4598 expose_info.y=slider_info.y;
4599 selection_info.id=(~0);
4601 state|=RedrawListState;
4603 Redraw directory name & reply.
4605 if (IsGlob(reply_info.text) == MagickFalse)
4607 *reply_info.text='\0';
4608 reply_info.cursor=reply_info.text;
4610 (void) CopyMagickString(text_info.text,working_path,MaxTextExtent);
4611 (void) ConcatenateMagickString(text_info.text,DirectorySeparator,
4613 (void) ConcatenateMagickString(text_info.text,glob_pattern,
4615 XDrawWidgetText(display,&windows->widget,&text_info);
4616 XDrawMatteText(display,&windows->widget,&reply_info);
4617 XDrawBeveledMatte(display,&windows->widget,&scroll_info);
4618 XDrawTriangleNorth(display,&windows->widget,&north_info);
4619 XDrawBeveledButton(display,&windows->widget,&slider_info);
4620 XDrawTriangleSouth(display,&windows->widget,&south_info);
4621 XHighlightWidget(display,&windows->widget,BorderOffset,BorderOffset);
4622 state&=(~UpdateListState);
4624 if (state & JumpListState)
4627 Jump scroll to match user filename.
4630 for (i=0; i < (ssize_t) files; i++)
4631 if (LocaleCompare(filelist[i],reply) >= 0)
4633 list_info.id=LocaleCompare(filelist[i],reply) == 0 ? i : ~0;
4636 if ((i < slider_info.id) || (i >= (int) (slider_info.id+visible_files)))
4637 slider_info.id=i-(visible_files >> 1);
4638 selection_info.id=(~0);
4639 state|=RedrawListState;
4640 state&=(~JumpListState);
4642 if (state & RedrawListState)
4645 Determine slider id and position.
4647 if (slider_info.id >= (int) (files-visible_files))
4648 slider_info.id=(int) (files-visible_files);
4649 if ((slider_info.id < 0) || (files <= visible_files))
4651 slider_info.y=slider_info.min_y;
4653 slider_info.y+=(int) (slider_info.id*(slider_info.max_y-
4654 slider_info.min_y+1)/files);
4655 if (slider_info.id != selection_info.id)
4658 Redraw scroll bar and file names.
4660 selection_info.id=slider_info.id;
4661 selection_info.y=list_info.y+(height >> 3)+2;
4662 for (i=0; i < (int) visible_files; i++)
4664 selection_info.raised=(slider_info.id+i) != list_info.id ?
4665 MagickTrue : MagickFalse;
4666 selection_info.text=(char *) NULL;
4667 if ((slider_info.id+i) < (ssize_t) files)
4668 selection_info.text=filelist[slider_info.id+i];
4669 XDrawWidgetText(display,&windows->widget,&selection_info);
4670 selection_info.y+=(int) selection_info.height;
4675 if (slider_info.y > expose_info.y)
4677 expose_info.height=(unsigned int) slider_info.y-expose_info.y;
4678 expose_info.y=slider_info.y-expose_info.height-
4679 slider_info.bevel_width-1;
4683 expose_info.height=(unsigned int) expose_info.y-slider_info.y;
4684 expose_info.y=slider_info.y+slider_info.height+
4685 slider_info.bevel_width+1;
4687 XDrawTriangleNorth(display,&windows->widget,&north_info);
4688 XDrawMatte(display,&windows->widget,&expose_info);
4689 XDrawBeveledButton(display,&windows->widget,&slider_info);
4690 XDrawTriangleSouth(display,&windows->widget,&south_info);
4691 expose_info.y=slider_info.y;
4693 state&=(~RedrawListState);
4696 Wait for next event.
4698 if (north_info.raised && south_info.raised)
4699 (void) XIfEvent(display,&event,XScreenEvent,(char *) windows);
4703 Brief delay before advancing scroll bar.
4705 XDelay(display,delay);
4707 (void) XCheckIfEvent(display,&event,XScreenEvent,(char *) windows);
4708 if (north_info.raised == MagickFalse)
4709 if (slider_info.id > 0)
4715 state|=RedrawListState;
4717 if (south_info.raised == MagickFalse)
4718 if (slider_info.id < (ssize_t) files)
4724 state|=RedrawListState;
4726 if (event.type != ButtonRelease)
4733 if (MatteIsActive(slider_info,event.xbutton))
4738 slider_info.active=MagickTrue;
4741 if (MatteIsActive(north_info,event.xbutton))
4742 if (slider_info.id > 0)
4747 north_info.raised=MagickFalse;
4749 state|=RedrawListState;
4752 if (MatteIsActive(south_info,event.xbutton))
4753 if (slider_info.id < (ssize_t) files)
4758 south_info.raised=MagickFalse;
4760 state|=RedrawListState;
4763 if (MatteIsActive(scroll_info,event.xbutton))
4768 if (event.xbutton.y < slider_info.y)
4769 slider_info.id-=(visible_files-1);
4771 slider_info.id+=(visible_files-1);
4772 state|=RedrawListState;
4775 if (MatteIsActive(list_info,event.xbutton))
4781 User pressed file matte.
4783 id=slider_info.id+(event.xbutton.y-(list_info.y+(height >> 1))+1)/
4784 selection_info.height;
4785 if (id >= (ssize_t) files)
4787 (void) CopyMagickString(reply_info.text,filelist[id],MaxTextExtent);
4788 reply_info.highlight=MagickFalse;
4789 reply_info.marker=reply_info.text;
4790 reply_info.cursor=reply_info.text+Extent(reply_info.text);
4791 XDrawMatteText(display,&windows->widget,&reply_info);
4792 if (id == list_info.id)
4798 p=reply_info.text+strlen(reply_info.text)-1;
4799 if (*p == *DirectorySeparator)
4800 ChopPathComponents(reply_info.text,1);
4801 (void) ConcatenateMagickString(working_path,DirectorySeparator,
4803 (void) ConcatenateMagickString(working_path,reply_info.text,
4806 state|=UpdateListState;
4808 selection_info.id=(~0);
4810 state|=RedrawListState;
4813 if (MatteIsActive(up_info,event.xbutton))
4816 User pressed Up button.
4818 up_info.raised=MagickFalse;
4819 XDrawBeveledButton(display,&windows->widget,&up_info);
4822 if (MatteIsActive(home_info,event.xbutton))
4825 User pressed Home button.
4827 home_info.raised=MagickFalse;
4828 XDrawBeveledButton(display,&windows->widget,&home_info);
4831 if (MatteIsActive(special_info,event.xbutton))
4834 User pressed Special button.
4836 special_info.raised=MagickFalse;
4837 XDrawBeveledButton(display,&windows->widget,&special_info);
4840 if (MatteIsActive(action_info,event.xbutton))
4843 User pressed action button.
4845 action_info.raised=MagickFalse;
4846 XDrawBeveledButton(display,&windows->widget,&action_info);
4849 if (MatteIsActive(cancel_info,event.xbutton))
4852 User pressed Cancel button.
4854 cancel_info.raised=MagickFalse;
4855 XDrawBeveledButton(display,&windows->widget,&cancel_info);
4858 if (MatteIsActive(reply_info,event.xbutton) == MagickFalse)
4860 if (event.xbutton.button != Button2)
4866 Move text cursor to position of button press.
4868 x=event.xbutton.x-reply_info.x-(QuantumMargin >> 2);
4869 for (i=1; i <= Extent(reply_info.marker); i++)
4870 if (XTextWidth(font_info,reply_info.marker,i) > x)
4872 reply_info.cursor=reply_info.marker+i-1;
4873 if (event.xbutton.time > (click_time+DoubleClick))
4874 reply_info.highlight=MagickFalse;
4878 Become the XA_PRIMARY selection owner.
4880 (void) CopyMagickString(primary_selection,reply_info.text,
4882 (void) XSetSelectionOwner(display,XA_PRIMARY,windows->widget.id,
4883 event.xbutton.time);
4884 reply_info.highlight=XGetSelectionOwner(display,XA_PRIMARY) ==
4885 windows->widget.id ? MagickTrue : MagickFalse;
4887 XDrawMatteText(display,&windows->widget,&reply_info);
4888 click_time=event.xbutton.time;
4892 Request primary selection.
4894 (void) XConvertSelection(display,XA_PRIMARY,XA_STRING,XA_STRING,
4895 windows->widget.id,event.xbutton.time);
4900 if (windows->widget.mapped == MagickFalse)
4902 if (north_info.raised == MagickFalse)
4905 User released up button.
4907 delay=SuspendTime << 2;
4908 north_info.raised=MagickTrue;
4909 XDrawTriangleNorth(display,&windows->widget,&north_info);
4911 if (south_info.raised == MagickFalse)
4914 User released down button.
4916 delay=SuspendTime << 2;
4917 south_info.raised=MagickTrue;
4918 XDrawTriangleSouth(display,&windows->widget,&south_info);
4920 if (slider_info.active)
4923 Stop tracking slider.
4925 slider_info.active=MagickFalse;
4928 if (up_info.raised == MagickFalse)
4930 if (event.xbutton.window == windows->widget.id)
4931 if (MatteIsActive(up_info,event.xbutton))
4933 ChopPathComponents(working_path,1);
4934 if (*working_path == '\0')
4935 (void) CopyMagickString(working_path,DirectorySeparator,
4937 state|=UpdateListState;
4939 up_info.raised=MagickTrue;
4940 XDrawBeveledButton(display,&windows->widget,&up_info);
4942 if (home_info.raised == MagickFalse)
4944 if (event.xbutton.window == windows->widget.id)
4945 if (MatteIsActive(home_info,event.xbutton))
4947 (void) CopyMagickString(working_path,home_directory,
4949 state|=UpdateListState;
4951 home_info.raised=MagickTrue;
4952 XDrawBeveledButton(display,&windows->widget,&home_info);
4954 if (special_info.raised == MagickFalse)
4956 if (anomaly == MagickFalse)
4968 Let user select image format.
4970 exception=AcquireExceptionInfo();
4971 formats=GetMagickList("*",&number_formats,exception);
4972 exception=DestroyExceptionInfo(exception);
4973 (void) XCheckDefineCursor(display,windows->widget.id,
4974 windows->widget.busy_cursor);
4975 windows->popup.x=windows->widget.x+60;
4976 windows->popup.y=windows->widget.y+60;
4977 XListBrowserWidget(display,windows,&windows->popup,
4978 (const char **) formats,"Select","Select image format type:",
4980 XSetCursorState(display,windows,MagickTrue);
4981 (void) XCheckDefineCursor(display,windows->widget.id,
4982 windows->widget.cursor);
4983 LocaleLower(format);
4984 AppendImageFormat(format,reply_info.text);
4985 reply_info.cursor=reply_info.text+Extent(reply_info.text);
4986 XDrawMatteText(display,&windows->widget,&reply_info);
4987 special_info.raised=MagickTrue;
4988 XDrawBeveledButton(display,&windows->widget,&special_info);
4989 for (i=0; i < (int) number_formats; i++)
4990 formats[i]=DestroyString(formats[i]);
4991 formats=(char **) RelinquishMagickMemory(formats);
4994 if (event.xbutton.window == windows->widget.id)
4995 if (MatteIsActive(special_info,event.xbutton))
4997 (void) CopyMagickString(working_path,"x:",MaxTextExtent);
5000 special_info.raised=MagickTrue;
5001 XDrawBeveledButton(display,&windows->widget,&special_info);
5003 if (action_info.raised == MagickFalse)
5005 if (event.xbutton.window == windows->widget.id)
5007 if (MatteIsActive(action_info,event.xbutton))
5009 if (*reply_info.text == '\0')
5010 (void) XBell(display,0);
5015 action_info.raised=MagickTrue;
5016 XDrawBeveledButton(display,&windows->widget,&action_info);
5018 if (cancel_info.raised == MagickFalse)
5020 if (event.xbutton.window == windows->widget.id)
5021 if (MatteIsActive(cancel_info,event.xbutton))
5023 *reply_info.text='\0';
5027 cancel_info.raised=MagickTrue;
5028 XDrawBeveledButton(display,&windows->widget,&cancel_info);
5035 If client window delete message, exit.
5037 if (event.xclient.message_type != windows->wm_protocols)
5039 if (*event.xclient.data.l == (int) windows->wm_take_focus)
5041 (void) XSetInputFocus(display,event.xclient.window,RevertToParent,
5042 (Time) event.xclient.data.l[1]);
5045 if (*event.xclient.data.l != (int) windows->wm_delete_window)
5047 if (event.xclient.window == windows->widget.id)
5049 *reply_info.text='\0';
5055 case ConfigureNotify:
5058 Update widget configuration.
5060 if (event.xconfigure.window != windows->widget.id)
5062 if ((event.xconfigure.width == (int) windows->widget.width) &&
5063 (event.xconfigure.height == (int) windows->widget.height))
5065 windows->widget.width=(unsigned int)
5066 MagickMax(event.xconfigure.width,(int) windows->widget.min_width);
5067 windows->widget.height=(unsigned int)
5068 MagickMax(event.xconfigure.height,(int) windows->widget.min_height);
5069 state|=UpdateConfigurationState;
5074 if (event.xcrossing.window != windows->widget.id)
5076 state&=(~InactiveWidgetState);
5081 if (event.xexpose.window != windows->widget.id)
5083 if (event.xexpose.count != 0)
5085 state|=RedrawWidgetState;
5091 command[MaxTextExtent];
5100 Respond to a user key press.
5102 if (event.xkey.window != windows->widget.id)
5104 length=XLookupString((XKeyEvent *) &event.xkey,command,
5105 (int) sizeof(command),&key_symbol,(XComposeStatus *) NULL);
5106 *(command+length)='\0';
5107 if (AreaIsActive(scroll_info,event.xkey))
5112 switch ((int) key_symbol)
5135 slider_info.id-=visible_files;
5141 slider_info.id+=visible_files;
5147 slider_info.id=(int) files;
5151 state|=RedrawListState;
5154 if ((key_symbol == XK_Return) || (key_symbol == XK_KP_Enter))
5157 Read new directory or glob patterm.
5159 if (*reply_info.text == '\0')
5161 if (IsGlob(reply_info.text))
5162 (void) CopyMagickString(glob_pattern,reply_info.text,
5166 (void) ConcatenateMagickString(working_path,DirectorySeparator,
5168 (void) ConcatenateMagickString(working_path,reply_info.text,
5170 if (*working_path == '~')
5171 ExpandFilename(working_path);
5174 state|=UpdateListState;
5177 if (key_symbol == XK_Control_L)
5179 state|=ControlState;
5182 if (state & ControlState)
5183 switch ((int) key_symbol)
5189 Erase the entire line of text.
5191 *reply_info.text='\0';
5192 reply_info.cursor=reply_info.text;
5193 reply_info.marker=reply_info.text;
5194 reply_info.highlight=MagickFalse;
5200 XEditText(display,&reply_info,key_symbol,command,state);
5201 XDrawMatteText(display,&windows->widget,&reply_info);
5202 state|=JumpListState;
5208 command[MaxTextExtent];
5214 Respond to a user key release.
5216 if (event.xkey.window != windows->widget.id)
5218 (void) XLookupString((XKeyEvent *) &event.xkey,command,
5219 (int) sizeof(command),&key_symbol,(XComposeStatus *) NULL);
5220 if (key_symbol == XK_Control_L)
5221 state&=(~ControlState);
5226 if (event.xcrossing.window != windows->widget.id)
5228 state|=InactiveWidgetState;
5240 Discard pending button motion events.
5242 while (XCheckMaskEvent(display,ButtonMotionMask,&event)) ;
5243 if (slider_info.active)
5248 slider_info.y=event.xmotion.y-
5249 ((slider_info.height+slider_info.bevel_width) >> 1)+1;
5250 if (slider_info.y < slider_info.min_y)
5251 slider_info.y=slider_info.min_y;
5252 if (slider_info.y > slider_info.max_y)
5253 slider_info.y=slider_info.max_y;
5255 if (slider_info.y != slider_info.min_y)
5256 slider_info.id=(int) ((files*(slider_info.y-slider_info.min_y+1))/
5257 (slider_info.max_y-slider_info.min_y+1));
5258 state|=RedrawListState;
5261 if (state & InactiveWidgetState)
5263 if (up_info.raised == MatteIsActive(up_info,event.xmotion))
5266 Up button status changed.
5268 up_info.raised=!up_info.raised;
5269 XDrawBeveledButton(display,&windows->widget,&up_info);
5272 if (home_info.raised == MatteIsActive(home_info,event.xmotion))
5275 Home button status changed.
5277 home_info.raised=!home_info.raised;
5278 XDrawBeveledButton(display,&windows->widget,&home_info);
5281 if (special_info.raised == MatteIsActive(special_info,event.xmotion))
5284 Grab button status changed.
5286 special_info.raised=!special_info.raised;
5287 XDrawBeveledButton(display,&windows->widget,&special_info);
5290 if (action_info.raised == MatteIsActive(action_info,event.xmotion))
5293 Action button status changed.
5295 action_info.raised=action_info.raised == MagickFalse ?
5296 MagickTrue : MagickFalse;
5297 XDrawBeveledButton(display,&windows->widget,&action_info);
5300 if (cancel_info.raised == MatteIsActive(cancel_info,event.xmotion))
5303 Cancel button status changed.
5305 cancel_info.raised=cancel_info.raised == MagickFalse ?
5306 MagickTrue : MagickFalse;
5307 XDrawBeveledButton(display,&windows->widget,&cancel_info);
5312 case SelectionClear:
5314 reply_info.highlight=MagickFalse;
5315 XDrawMatteText(display,&windows->widget,&reply_info);
5318 case SelectionNotify:
5334 Obtain response from primary selection.
5336 if (event.xselection.property == (Atom) None)
5338 status=XGetWindowProperty(display,event.xselection.requestor,
5339 event.xselection.property,0L,2047L,MagickTrue,XA_STRING,&type,
5340 &format,&length,&after,&data);
5341 if ((status != Success) || (type != XA_STRING) || (format == 32) ||
5344 if ((Extent(reply_info.text)+length) >= MaxTextExtent)
5345 (void) XBell(display,0);
5349 Insert primary selection in reply text.
5351 *(data+length)='\0';
5352 XEditText(display,&reply_info,(KeySym) XK_Insert,(char *) data,
5354 XDrawMatteText(display,&windows->widget,&reply_info);
5355 state|=JumpListState;
5356 state|=RedrawActionState;
5358 (void) XFree((void *) data);
5361 case SelectionRequest:
5366 XSelectionRequestEvent
5369 if (reply_info.highlight == MagickFalse)
5372 Set primary selection.
5374 request=(&(event.xselectionrequest));
5375 (void) XChangeProperty(request->display,request->requestor,
5376 request->property,request->target,8,PropModeReplace,
5377 (unsigned char *) primary_selection,Extent(primary_selection));
5378 notify.type=SelectionNotify;
5379 notify.display=request->display;
5380 notify.requestor=request->requestor;
5381 notify.selection=request->selection;
5382 notify.target=request->target;
5383 notify.time=request->time;
5384 if (request->property == None)
5385 notify.property=request->target;
5387 notify.property=request->property;
5388 (void) XSendEvent(request->display,request->requestor,False,0,
5389 (XEvent *) ¬ify);
5394 } while ((state & ExitState) == 0);
5395 XSetCursorState(display,windows,MagickFalse);
5396 (void) XWithdrawWindow(display,windows->widget.id,windows->widget.screen);
5397 XCheckRefreshWindows(display,windows);
5401 for (i=0; i < (ssize_t) files; i++)
5402 filelist[i]=DestroyString(filelist[i]);
5403 if (filelist != (char **) NULL)
5404 filelist=(char **) RelinquishMagickMemory(filelist);
5407 (void) ConcatenateMagickString(working_path,DirectorySeparator,
5409 (void) ConcatenateMagickString(working_path,reply,MaxTextExtent);
5411 (void) CopyMagickString(reply,working_path,MaxTextExtent);
5413 ExpandFilename(reply);
5417 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5421 % X F o n t B r o w s e r W i d g e t %
5425 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5427 % XFontBrowserWidget() displays a Font Browser widget with a font query to the
5428 % user. The user keys a reply and presses the Action or Cancel button to
5429 % exit. The typed text is returned as the reply function parameter.
5431 % The format of the XFontBrowserWidget method is:
5433 % void XFontBrowserWidget(Display *display,XWindows *windows,
5434 % const char *action,char *reply)
5436 % A description of each parameter follows:
5438 % o display: Specifies a connection to an X server; returned from
5441 % o window: Specifies a pointer to a XWindows structure.
5443 % o action: Specifies a pointer to the action of this widget.
5445 % o reply: the response from the user is returned in this parameter.
5450 #if defined(__cplusplus) || defined(c_plusplus)
5454 static int FontCompare(const void *x,const void *y)
5460 p=(char *) *((char **) x);
5461 q=(char *) *((char **) y);
5462 while ((*p != '\0') && (*q != '\0') && (*p == *q))
5470 #if defined(__cplusplus) || defined(c_plusplus)
5474 MagickExport void XFontBrowserWidget(Display *display,XWindows *windows,
5475 const char *action,char *reply)
5477 #define BackButtonText "Back"
5478 #define CancelButtonText "Cancel"
5479 #define FontnameText "Name:"
5480 #define FontPatternText "Pattern:"
5481 #define ResetButtonText "Reset"
5484 back_pattern[MaxTextExtent],
5487 primary_selection[MaxTextExtent],
5488 reset_pattern[MaxTextExtent],
5489 text[MaxTextExtent];
5500 glob_pattern[MaxTextExtent] = "*";
5502 static MagickStatusType
5503 mask = (MagickStatusType) (CWWidth | CWHeight | CWX | CWY);
5547 Get font list and sort in ascending order.
5549 assert(display != (Display *) NULL);
5550 assert(windows != (XWindows *) NULL);
5551 assert(action != (char *) NULL);
5552 assert(reply != (char *) NULL);
5553 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",action);
5554 XSetCursorState(display,windows,MagickTrue);
5555 XCheckRefreshWindows(display,windows);
5556 (void) CopyMagickString(back_pattern,glob_pattern,MaxTextExtent);
5557 (void) CopyMagickString(reset_pattern,"*",MaxTextExtent);
5558 fontlist=XListFonts(display,glob_pattern,32767,&fonts);
5562 Pattern failed, obtain all the fonts.
5564 XNoticeWidget(display,windows,"Unable to obtain fonts names:",
5566 (void) CopyMagickString(glob_pattern,"*",MaxTextExtent);
5567 fontlist=XListFonts(display,glob_pattern,32767,&fonts);
5568 if (fontlist == (char **) NULL)
5570 XNoticeWidget(display,windows,"Unable to obtain fonts names:",
5576 Sort font list in ascending order.
5579 fontlist=(char **) AcquireQuantumMemory((size_t) fonts,sizeof(*fontlist));
5580 if (fontlist == (char **) NULL)
5582 XNoticeWidget(display,windows,"MemoryAllocationFailed",
5583 "UnableToViewFonts");
5586 for (i=0; i < fonts; i++)
5587 fontlist[i]=listhead[i];
5588 qsort((void *) fontlist,(size_t) fonts,sizeof(*fontlist),FontCompare);
5590 Determine Font Browser widget attributes.
5592 font_info=windows->widget.font_info;
5594 for (i=0; i < fonts; i++)
5595 if (WidgetTextWidth(font_info,fontlist[i]) > text_width)
5596 text_width=WidgetTextWidth(font_info,fontlist[i]);
5597 width=WidgetTextWidth(font_info,(char *) action);
5598 if (WidgetTextWidth(font_info,CancelButtonText) > width)
5599 width=WidgetTextWidth(font_info,CancelButtonText);
5600 if (WidgetTextWidth(font_info,ResetButtonText) > width)
5601 width=WidgetTextWidth(font_info,ResetButtonText);
5602 if (WidgetTextWidth(font_info,BackButtonText) > width)
5603 width=WidgetTextWidth(font_info,BackButtonText);
5604 width+=QuantumMargin;
5605 if (WidgetTextWidth(font_info,FontPatternText) > width)
5606 width=WidgetTextWidth(font_info,FontPatternText);
5607 if (WidgetTextWidth(font_info,FontnameText) > width)
5608 width=WidgetTextWidth(font_info,FontnameText);
5609 height=(unsigned int) (font_info->ascent+font_info->descent);
5611 Position Font Browser widget.
5613 windows->widget.width=width+MagickMin((int) text_width,(int) MaxTextWidth)+
5615 windows->widget.min_width=width+MinTextWidth+4*QuantumMargin;
5616 if (windows->widget.width < windows->widget.min_width)
5617 windows->widget.width=windows->widget.min_width;
5618 windows->widget.height=(unsigned int)
5619 (((85*height) >> 2)+((13*QuantumMargin) >> 1)+4);
5620 windows->widget.min_height=(unsigned int)
5621 (((27*height) >> 1)+((13*QuantumMargin) >> 1)+4);
5622 if (windows->widget.height < windows->widget.min_height)
5623 windows->widget.height=windows->widget.min_height;
5624 XConstrainWindowPosition(display,&windows->widget);
5626 Map Font Browser widget.
5628 (void) CopyMagickString(windows->widget.name,"Browse and Select a Font",
5630 status=XStringListToTextProperty(&windows->widget.name,1,&window_name);
5631 if (status != False)
5633 XSetWMName(display,windows->widget.id,&window_name);
5634 XSetWMIconName(display,windows->widget.id,&window_name);
5635 (void) XFree((void *) window_name.value);
5637 window_changes.width=(int) windows->widget.width;
5638 window_changes.height=(int) windows->widget.height;
5639 window_changes.x=windows->widget.x;
5640 window_changes.y=windows->widget.y;
5641 (void) XReconfigureWMWindow(display,windows->widget.id,
5642 windows->widget.screen,mask,&window_changes);
5643 (void) XMapRaised(display,windows->widget.id);
5644 windows->widget.mapped=MagickFalse;
5646 Respond to X events.
5648 XGetWidgetInfo((char *) NULL,&slider_info);
5649 XGetWidgetInfo((char *) NULL,&north_info);
5650 XGetWidgetInfo((char *) NULL,&south_info);
5651 XGetWidgetInfo((char *) NULL,&expose_info);
5653 delay=SuspendTime << 2;
5654 state=UpdateConfigurationState;
5657 if (state & UpdateConfigurationState)
5663 Initialize button information.
5665 XGetWidgetInfo(CancelButtonText,&cancel_info);
5666 cancel_info.width=width;
5667 cancel_info.height=(unsigned int) ((3*height) >> 1);
5669 (windows->widget.width-cancel_info.width-QuantumMargin-2);
5671 (windows->widget.height-cancel_info.height-QuantumMargin);
5672 XGetWidgetInfo(action,&action_info);
5673 action_info.width=width;
5674 action_info.height=(unsigned int) ((3*height) >> 1);
5675 action_info.x=cancel_info.x-(cancel_info.width+(QuantumMargin >> 1)+
5676 (action_info.bevel_width << 1));
5677 action_info.y=cancel_info.y;
5678 XGetWidgetInfo(BackButtonText,&back_info);
5679 back_info.width=width;
5680 back_info.height=(unsigned int) ((3*height) >> 1);
5681 back_info.x=QuantumMargin;
5682 back_info.y=((5*QuantumMargin) >> 1)+height;
5683 XGetWidgetInfo(ResetButtonText,&reset_info);
5684 reset_info.width=width;
5685 reset_info.height=(unsigned int) ((3*height) >> 1);
5686 reset_info.x=QuantumMargin;
5687 reset_info.y=back_info.y+back_info.height+QuantumMargin;
5689 Initialize reply information.
5691 XGetWidgetInfo(reply,&reply_info);
5692 reply_info.raised=MagickFalse;
5693 reply_info.bevel_width--;
5694 reply_info.width=windows->widget.width-width-((6*QuantumMargin) >> 1);
5695 reply_info.height=height << 1;
5696 reply_info.x=(int) (width+(QuantumMargin << 1));
5697 reply_info.y=action_info.y-(action_info.height << 1)-QuantumMargin;
5699 Initialize mode information.
5701 XGetWidgetInfo(reply,&mode_info);
5702 mode_info.bevel_width=0;
5703 mode_info.width=(unsigned int)
5704 (action_info.x-reply_info.x-QuantumMargin);
5705 mode_info.height=action_info.height << 1;
5706 mode_info.x=reply_info.x;
5707 mode_info.y=action_info.y-action_info.height+action_info.bevel_width;
5709 Initialize scroll information.
5711 XGetWidgetInfo((char *) NULL,&scroll_info);
5712 scroll_info.bevel_width--;
5713 scroll_info.width=height;
5714 scroll_info.height=(unsigned int)
5715 (reply_info.y-back_info.y-(QuantumMargin >> 1));
5716 scroll_info.x=reply_info.x+(reply_info.width-scroll_info.width);
5717 scroll_info.y=back_info.y-reply_info.bevel_width;
5718 scroll_info.raised=MagickFalse;
5719 scroll_info.trough=MagickTrue;
5720 north_info=scroll_info;
5721 north_info.raised=MagickTrue;
5722 north_info.width-=(north_info.bevel_width << 1);
5723 north_info.height=north_info.width-1;
5724 north_info.x+=north_info.bevel_width;
5725 north_info.y+=north_info.bevel_width;
5726 south_info=north_info;
5727 south_info.y=scroll_info.y+scroll_info.height-scroll_info.bevel_width-
5730 slider_info=north_info;
5732 slider_info.width-=2;
5733 slider_info.min_y=north_info.y+north_info.height+north_info.bevel_width+
5734 slider_info.bevel_width+2;
5735 slider_info.height=scroll_info.height-((slider_info.min_y-
5736 scroll_info.y+1) << 1)+4;
5737 visible_fonts=scroll_info.height/(height+(height >> 3));
5738 if (fonts > (int) visible_fonts)
5739 slider_info.height=(visible_fonts*slider_info.height)/fonts;
5740 slider_info.max_y=south_info.y-south_info.bevel_width-
5741 slider_info.bevel_width-2;
5742 slider_info.x=scroll_info.x+slider_info.bevel_width+1;
5743 slider_info.y=slider_info.min_y;
5744 expose_info=scroll_info;
5745 expose_info.y=slider_info.y;
5747 Initialize list information.
5749 XGetWidgetInfo((char *) NULL,&list_info);
5750 list_info.raised=MagickFalse;
5751 list_info.bevel_width--;
5752 list_info.width=(unsigned int)
5753 (scroll_info.x-reply_info.x-(QuantumMargin >> 1));
5754 list_info.height=scroll_info.height;
5755 list_info.x=reply_info.x;
5756 list_info.y=scroll_info.y;
5757 if (windows->widget.mapped == MagickFalse)
5758 state|=JumpListState;
5760 Initialize text information.
5763 XGetWidgetInfo(text,&text_info);
5764 text_info.center=MagickFalse;
5765 text_info.width=reply_info.width;
5766 text_info.height=height;
5767 text_info.x=list_info.x-(QuantumMargin >> 1);
5768 text_info.y=QuantumMargin;
5770 Initialize selection information.
5772 XGetWidgetInfo((char *) NULL,&selection_info);
5773 selection_info.center=MagickFalse;
5774 selection_info.width=list_info.width;
5775 selection_info.height=(unsigned int) ((9*height) >> 3);
5776 selection_info.x=list_info.x;
5777 state&=(~UpdateConfigurationState);
5779 if (state & RedrawWidgetState)
5782 Redraw Font Browser window.
5785 y=text_info.y+((text_info.height-height) >> 1)+font_info->ascent;
5786 (void) XDrawString(display,windows->widget.id,
5787 windows->widget.annotate_context,x,y,FontPatternText,
5788 Extent(FontPatternText));
5789 (void) CopyMagickString(text_info.text,glob_pattern,MaxTextExtent);
5790 XDrawWidgetText(display,&windows->widget,&text_info);
5791 XDrawBeveledButton(display,&windows->widget,&back_info);
5792 XDrawBeveledButton(display,&windows->widget,&reset_info);
5793 XDrawBeveledMatte(display,&windows->widget,&list_info);
5794 XDrawBeveledMatte(display,&windows->widget,&scroll_info);
5795 XDrawTriangleNorth(display,&windows->widget,&north_info);
5796 XDrawBeveledButton(display,&windows->widget,&slider_info);
5797 XDrawTriangleSouth(display,&windows->widget,&south_info);
5799 y=reply_info.y+((reply_info.height-height) >> 1)+font_info->ascent;
5800 (void) XDrawString(display,windows->widget.id,
5801 windows->widget.annotate_context,x,y,FontnameText,
5802 Extent(FontnameText));
5803 XDrawBeveledMatte(display,&windows->widget,&reply_info);
5804 XDrawMatteText(display,&windows->widget,&reply_info);
5805 XDrawBeveledButton(display,&windows->widget,&action_info);
5806 XDrawBeveledButton(display,&windows->widget,&cancel_info);
5807 XHighlightWidget(display,&windows->widget,BorderOffset,BorderOffset);
5808 selection_info.id=(~0);
5809 state|=RedrawActionState;
5810 state|=RedrawListState;
5811 state&=(~RedrawWidgetState);
5813 if (state & UpdateListState)
5824 checklist=XListFonts(display,glob_pattern,32767,&number_fonts);
5825 if (checklist == (char **) NULL)
5827 if ((strchr(glob_pattern,'*') == (char *) NULL) &&
5828 (strchr(glob_pattern,'?') == (char *) NULL))
5831 Might be a scaleable font-- exit.
5833 (void) CopyMagickString(reply,glob_pattern,MaxTextExtent);
5834 (void) CopyMagickString(glob_pattern,back_pattern,MaxTextExtent);
5835 action_info.raised=MagickFalse;
5836 XDrawBeveledButton(display,&windows->widget,&action_info);
5839 (void) CopyMagickString(glob_pattern,back_pattern,MaxTextExtent);
5840 (void) XBell(display,0);
5843 if (number_fonts == 1)
5846 Reply is a single font name-- exit.
5848 (void) CopyMagickString(reply,checklist[0],MaxTextExtent);
5849 (void) CopyMagickString(glob_pattern,back_pattern,MaxTextExtent);
5850 (void) XFreeFontNames(checklist);
5851 action_info.raised=MagickFalse;
5852 XDrawBeveledButton(display,&windows->widget,&action_info);
5857 (void) XFreeFontNames(listhead);
5858 fontlist=(char **) RelinquishMagickMemory(fontlist);
5863 Sort font list in ascending order.
5866 fontlist=(char **) AcquireQuantumMemory((size_t) fonts,
5868 if (fontlist == (char **) NULL)
5870 XNoticeWidget(display,windows,"MemoryAllocationFailed",
5871 "UnableToViewFonts");
5874 for (i=0; i < fonts; i++)
5875 fontlist[i]=listhead[i];
5876 qsort((void *) fontlist,(size_t) fonts,sizeof(*fontlist),FontCompare);
5878 scroll_info.height-((slider_info.min_y-scroll_info.y+1) << 1)+1;
5879 if (fonts > (int) visible_fonts)
5880 slider_info.height=(visible_fonts*slider_info.height)/fonts;
5881 slider_info.max_y=south_info.y-south_info.bevel_width-
5882 slider_info.bevel_width-2;
5884 slider_info.y=slider_info.min_y;
5885 expose_info.y=slider_info.y;
5886 selection_info.id=(~0);
5888 state|=RedrawListState;
5890 Redraw font name & reply.
5892 *reply_info.text='\0';
5893 reply_info.cursor=reply_info.text;
5894 (void) CopyMagickString(text_info.text,glob_pattern,MaxTextExtent);
5895 XDrawWidgetText(display,&windows->widget,&text_info);
5896 XDrawMatteText(display,&windows->widget,&reply_info);
5897 XDrawBeveledMatte(display,&windows->widget,&scroll_info);
5898 XDrawTriangleNorth(display,&windows->widget,&north_info);
5899 XDrawBeveledButton(display,&windows->widget,&slider_info);
5900 XDrawTriangleSouth(display,&windows->widget,&south_info);
5901 XHighlightWidget(display,&windows->widget,BorderOffset,BorderOffset);
5902 state&=(~UpdateListState);
5904 if (state & JumpListState)
5907 Jump scroll to match user font.
5910 for (i=0; i < fonts; i++)
5911 if (LocaleCompare(fontlist[i],reply) >= 0)
5913 list_info.id=LocaleCompare(fontlist[i],reply) == 0 ? i : ~0;
5916 if ((i < slider_info.id) || (i >= (int) (slider_info.id+visible_fonts)))
5917 slider_info.id=i-(visible_fonts >> 1);
5918 selection_info.id=(~0);
5919 state|=RedrawListState;
5920 state&=(~JumpListState);
5922 if (state & RedrawListState)
5925 Determine slider id and position.
5927 if (slider_info.id >= (int) (fonts-visible_fonts))
5928 slider_info.id=fonts-visible_fonts;
5929 if ((slider_info.id < 0) || (fonts <= (int) visible_fonts))
5931 slider_info.y=slider_info.min_y;
5934 slider_info.id*(slider_info.max_y-slider_info.min_y+1)/fonts;
5935 if (slider_info.id != selection_info.id)
5938 Redraw scroll bar and file names.
5940 selection_info.id=slider_info.id;
5941 selection_info.y=list_info.y+(height >> 3)+2;
5942 for (i=0; i < (int) visible_fonts; i++)
5944 selection_info.raised=(slider_info.id+i) != list_info.id ?
5945 MagickTrue : MagickFalse;
5946 selection_info.text=(char *) NULL;
5947 if ((slider_info.id+i) < fonts)
5948 selection_info.text=fontlist[slider_info.id+i];
5949 XDrawWidgetText(display,&windows->widget,&selection_info);
5950 selection_info.y+=(int) selection_info.height;
5955 if (slider_info.y > expose_info.y)
5957 expose_info.height=(unsigned int) slider_info.y-expose_info.y;
5958 expose_info.y=slider_info.y-expose_info.height-
5959 slider_info.bevel_width-1;
5963 expose_info.height=(unsigned int) expose_info.y-slider_info.y;
5964 expose_info.y=slider_info.y+slider_info.height+
5965 slider_info.bevel_width+1;
5967 XDrawTriangleNorth(display,&windows->widget,&north_info);
5968 XDrawMatte(display,&windows->widget,&expose_info);
5969 XDrawBeveledButton(display,&windows->widget,&slider_info);
5970 XDrawTriangleSouth(display,&windows->widget,&south_info);
5971 expose_info.y=slider_info.y;
5973 state&=(~RedrawListState);
5975 if (state & RedrawActionState)
5981 Display the selected font in a drawing area.
5983 save_info=windows->widget.font_info;
5984 font_info=XLoadQueryFont(display,reply_info.text);
5985 if (font_info != (XFontStruct *) NULL)
5987 windows->widget.font_info=font_info;
5988 (void) XSetFont(display,windows->widget.widget_context,
5991 XDrawBeveledButton(display,&windows->widget,&mode_info);
5992 windows->widget.font_info=save_info;
5993 if (font_info != (XFontStruct *) NULL)
5995 (void) XSetFont(display,windows->widget.widget_context,
5996 windows->widget.font_info->fid);
5997 (void) XFreeFont(display,font_info);
5999 XHighlightWidget(display,&windows->widget,BorderOffset,BorderOffset);
6000 XDrawMatteText(display,&windows->widget,&reply_info);
6001 state&=(~RedrawActionState);
6004 Wait for next event.
6006 if (north_info.raised && south_info.raised)
6007 (void) XIfEvent(display,&event,XScreenEvent,(char *) windows);
6011 Brief delay before advancing scroll bar.
6013 XDelay(display,delay);
6015 (void) XCheckIfEvent(display,&event,XScreenEvent,(char *) windows);
6016 if (north_info.raised == MagickFalse)
6017 if (slider_info.id > 0)
6023 state|=RedrawListState;
6025 if (south_info.raised == MagickFalse)
6026 if (slider_info.id < fonts)
6032 state|=RedrawListState;
6034 if (event.type != ButtonRelease)
6041 if (MatteIsActive(slider_info,event.xbutton))
6046 slider_info.active=MagickTrue;
6049 if (MatteIsActive(north_info,event.xbutton))
6050 if (slider_info.id > 0)
6055 north_info.raised=MagickFalse;
6057 state|=RedrawListState;
6060 if (MatteIsActive(south_info,event.xbutton))
6061 if (slider_info.id < fonts)
6066 south_info.raised=MagickFalse;
6068 state|=RedrawListState;
6071 if (MatteIsActive(scroll_info,event.xbutton))
6076 if (event.xbutton.y < slider_info.y)
6077 slider_info.id-=(visible_fonts-1);
6079 slider_info.id+=(visible_fonts-1);
6080 state|=RedrawListState;
6083 if (MatteIsActive(list_info,event.xbutton))
6089 User pressed list matte.
6091 id=slider_info.id+(event.xbutton.y-(list_info.y+(height >> 1))+1)/
6092 selection_info.height;
6093 if (id >= (int) fonts)
6095 (void) CopyMagickString(reply_info.text,fontlist[id],MaxTextExtent);
6096 reply_info.highlight=MagickFalse;
6097 reply_info.marker=reply_info.text;
6098 reply_info.cursor=reply_info.text+Extent(reply_info.text);
6099 XDrawMatteText(display,&windows->widget,&reply_info);
6100 state|=RedrawActionState;
6101 if (id == list_info.id)
6103 (void) CopyMagickString(glob_pattern,reply_info.text,
6105 state|=UpdateListState;
6107 selection_info.id=(~0);
6109 state|=RedrawListState;
6112 if (MatteIsActive(back_info,event.xbutton))
6115 User pressed Back button.
6117 back_info.raised=MagickFalse;
6118 XDrawBeveledButton(display,&windows->widget,&back_info);
6121 if (MatteIsActive(reset_info,event.xbutton))
6124 User pressed Reset button.
6126 reset_info.raised=MagickFalse;
6127 XDrawBeveledButton(display,&windows->widget,&reset_info);
6130 if (MatteIsActive(action_info,event.xbutton))
6133 User pressed action button.
6135 action_info.raised=MagickFalse;
6136 XDrawBeveledButton(display,&windows->widget,&action_info);
6139 if (MatteIsActive(cancel_info,event.xbutton))
6142 User pressed Cancel button.
6144 cancel_info.raised=MagickFalse;
6145 XDrawBeveledButton(display,&windows->widget,&cancel_info);
6148 if (MatteIsActive(reply_info,event.xbutton) == MagickFalse)
6150 if (event.xbutton.button != Button2)
6156 Move text cursor to position of button press.
6158 x=event.xbutton.x-reply_info.x-(QuantumMargin >> 2);
6159 for (i=1; i <= Extent(reply_info.marker); i++)
6160 if (XTextWidth(font_info,reply_info.marker,i) > x)
6162 reply_info.cursor=reply_info.marker+i-1;
6163 if (event.xbutton.time > (click_time+DoubleClick))
6164 reply_info.highlight=MagickFalse;
6168 Become the XA_PRIMARY selection owner.
6170 (void) CopyMagickString(primary_selection,reply_info.text,
6172 (void) XSetSelectionOwner(display,XA_PRIMARY,windows->widget.id,
6173 event.xbutton.time);
6174 reply_info.highlight=XGetSelectionOwner(display,XA_PRIMARY) ==
6175 windows->widget.id ? MagickTrue : MagickFalse;
6177 XDrawMatteText(display,&windows->widget,&reply_info);
6178 click_time=event.xbutton.time;
6182 Request primary selection.
6184 (void) XConvertSelection(display,XA_PRIMARY,XA_STRING,XA_STRING,
6185 windows->widget.id,event.xbutton.time);
6190 if (windows->widget.mapped == MagickFalse)
6192 if (north_info.raised == MagickFalse)
6195 User released up button.
6197 delay=SuspendTime << 2;
6198 north_info.raised=MagickTrue;
6199 XDrawTriangleNorth(display,&windows->widget,&north_info);
6201 if (south_info.raised == MagickFalse)
6204 User released down button.
6206 delay=SuspendTime << 2;
6207 south_info.raised=MagickTrue;
6208 XDrawTriangleSouth(display,&windows->widget,&south_info);
6210 if (slider_info.active)
6213 Stop tracking slider.
6215 slider_info.active=MagickFalse;
6218 if (back_info.raised == MagickFalse)
6220 if (event.xbutton.window == windows->widget.id)
6221 if (MatteIsActive(back_info,event.xbutton))
6223 (void) CopyMagickString(glob_pattern,back_pattern,
6225 state|=UpdateListState;
6227 back_info.raised=MagickTrue;
6228 XDrawBeveledButton(display,&windows->widget,&back_info);
6230 if (reset_info.raised == MagickFalse)
6232 if (event.xbutton.window == windows->widget.id)
6233 if (MatteIsActive(reset_info,event.xbutton))
6235 (void) CopyMagickString(back_pattern,glob_pattern,MaxTextExtent);
6236 (void) CopyMagickString(glob_pattern,reset_pattern,MaxTextExtent);
6237 state|=UpdateListState;
6239 reset_info.raised=MagickTrue;
6240 XDrawBeveledButton(display,&windows->widget,&reset_info);
6242 if (action_info.raised == MagickFalse)
6244 if (event.xbutton.window == windows->widget.id)
6246 if (MatteIsActive(action_info,event.xbutton))
6248 if (*reply_info.text == '\0')
6249 (void) XBell(display,0);
6254 action_info.raised=MagickTrue;
6255 XDrawBeveledButton(display,&windows->widget,&action_info);
6257 if (cancel_info.raised == MagickFalse)
6259 if (event.xbutton.window == windows->widget.id)
6260 if (MatteIsActive(cancel_info,event.xbutton))
6262 *reply_info.text='\0';
6265 cancel_info.raised=MagickTrue;
6266 XDrawBeveledButton(display,&windows->widget,&cancel_info);
6273 If client window delete message, exit.
6275 if (event.xclient.message_type != windows->wm_protocols)
6277 if (*event.xclient.data.l == (int) windows->wm_take_focus)
6279 (void) XSetInputFocus(display,event.xclient.window,RevertToParent,
6280 (Time) event.xclient.data.l[1]);
6283 if (*event.xclient.data.l != (int) windows->wm_delete_window)
6285 if (event.xclient.window == windows->widget.id)
6287 *reply_info.text='\0';
6293 case ConfigureNotify:
6296 Update widget configuration.
6298 if (event.xconfigure.window != windows->widget.id)
6300 if ((event.xconfigure.width == (int) windows->widget.width) &&
6301 (event.xconfigure.height == (int) windows->widget.height))
6303 windows->widget.width=(unsigned int)
6304 MagickMax(event.xconfigure.width,(int) windows->widget.min_width);
6305 windows->widget.height=(unsigned int)
6306 MagickMax(event.xconfigure.height,(int) windows->widget.min_height);
6307 state|=UpdateConfigurationState;
6312 if (event.xcrossing.window != windows->widget.id)
6314 state&=(~InactiveWidgetState);
6319 if (event.xexpose.window != windows->widget.id)
6321 if (event.xexpose.count != 0)
6323 state|=RedrawWidgetState;
6329 command[MaxTextExtent];
6338 Respond to a user key press.
6340 if (event.xkey.window != windows->widget.id)
6342 length=XLookupString((XKeyEvent *) &event.xkey,command,
6343 (int) sizeof(command),&key_symbol,(XComposeStatus *) NULL);
6344 *(command+length)='\0';
6345 if (AreaIsActive(scroll_info,event.xkey))
6350 switch ((int) key_symbol)
6373 slider_info.id-=visible_fonts;
6379 slider_info.id+=visible_fonts;
6385 slider_info.id=fonts;
6389 state|=RedrawListState;
6392 if ((key_symbol == XK_Return) || (key_symbol == XK_KP_Enter))
6395 Read new font or glob patterm.
6397 if (*reply_info.text == '\0')
6399 (void) CopyMagickString(back_pattern,glob_pattern,MaxTextExtent);
6400 (void) CopyMagickString(glob_pattern,reply_info.text,MaxTextExtent);
6401 state|=UpdateListState;
6404 if (key_symbol == XK_Control_L)
6406 state|=ControlState;
6409 if (state & ControlState)
6410 switch ((int) key_symbol)
6416 Erase the entire line of text.
6418 *reply_info.text='\0';
6419 reply_info.cursor=reply_info.text;
6420 reply_info.marker=reply_info.text;
6421 reply_info.highlight=MagickFalse;
6427 XEditText(display,&reply_info,key_symbol,command,state);
6428 XDrawMatteText(display,&windows->widget,&reply_info);
6429 state|=JumpListState;
6435 command[MaxTextExtent];
6441 Respond to a user key release.
6443 if (event.xkey.window != windows->widget.id)
6445 (void) XLookupString((XKeyEvent *) &event.xkey,command,
6446 (int) sizeof(command),&key_symbol,(XComposeStatus *) NULL);
6447 if (key_symbol == XK_Control_L)
6448 state&=(~ControlState);
6453 if (event.xcrossing.window != windows->widget.id)
6455 state|=InactiveWidgetState;
6467 Discard pending button motion events.
6469 while (XCheckMaskEvent(display,ButtonMotionMask,&event)) ;
6470 if (slider_info.active)
6475 slider_info.y=event.xmotion.y-
6476 ((slider_info.height+slider_info.bevel_width) >> 1)+1;
6477 if (slider_info.y < slider_info.min_y)
6478 slider_info.y=slider_info.min_y;
6479 if (slider_info.y > slider_info.max_y)
6480 slider_info.y=slider_info.max_y;
6482 if (slider_info.y != slider_info.min_y)
6483 slider_info.id=(fonts*(slider_info.y-slider_info.min_y+1))/
6484 (slider_info.max_y-slider_info.min_y+1);
6485 state|=RedrawListState;
6488 if (state & InactiveWidgetState)
6490 if (back_info.raised == MatteIsActive(back_info,event.xmotion))
6493 Back button status changed.
6495 back_info.raised=!back_info.raised;
6496 XDrawBeveledButton(display,&windows->widget,&back_info);
6499 if (reset_info.raised == MatteIsActive(reset_info,event.xmotion))
6502 Reset button status changed.
6504 reset_info.raised=!reset_info.raised;
6505 XDrawBeveledButton(display,&windows->widget,&reset_info);
6508 if (action_info.raised == MatteIsActive(action_info,event.xmotion))
6511 Action button status changed.
6513 action_info.raised=action_info.raised == MagickFalse ?
6514 MagickTrue : MagickFalse;
6515 XDrawBeveledButton(display,&windows->widget,&action_info);
6518 if (cancel_info.raised == MatteIsActive(cancel_info,event.xmotion))
6521 Cancel button status changed.
6523 cancel_info.raised=cancel_info.raised == MagickFalse ?
6524 MagickTrue : MagickFalse;
6525 XDrawBeveledButton(display,&windows->widget,&cancel_info);
6530 case SelectionClear:
6532 reply_info.highlight=MagickFalse;
6533 XDrawMatteText(display,&windows->widget,&reply_info);
6536 case SelectionNotify:
6552 Obtain response from primary selection.
6554 if (event.xselection.property == (Atom) None)
6556 status=XGetWindowProperty(display,event.xselection.requestor,
6557 event.xselection.property,0L,2047L,MagickTrue,XA_STRING,&type,
6558 &format,&length,&after,&data);
6559 if ((status != Success) || (type != XA_STRING) || (format == 32) ||
6562 if ((Extent(reply_info.text)+length) >= MaxTextExtent)
6563 (void) XBell(display,0);
6567 Insert primary selection in reply text.
6569 *(data+length)='\0';
6570 XEditText(display,&reply_info,(KeySym) XK_Insert,(char *) data,
6572 XDrawMatteText(display,&windows->widget,&reply_info);
6573 state|=JumpListState;
6574 state|=RedrawActionState;
6576 (void) XFree((void *) data);
6579 case SelectionRequest:
6584 XSelectionRequestEvent
6588 Set XA_PRIMARY selection.
6590 request=(&(event.xselectionrequest));
6591 (void) XChangeProperty(request->display,request->requestor,
6592 request->property,request->target,8,PropModeReplace,
6593 (unsigned char *) primary_selection,Extent(primary_selection));
6594 notify.type=SelectionNotify;
6595 notify.display=request->display;
6596 notify.requestor=request->requestor;
6597 notify.selection=request->selection;
6598 notify.target=request->target;
6599 notify.time=request->time;
6600 if (request->property == None)
6601 notify.property=request->target;
6603 notify.property=request->property;
6604 (void) XSendEvent(request->display,request->requestor,False,0,
6605 (XEvent *) ¬ify);
6610 } while ((state & ExitState) == 0);
6611 XSetCursorState(display,windows,MagickFalse);
6612 (void) XWithdrawWindow(display,windows->widget.id,windows->widget.screen);
6613 XCheckRefreshWindows(display,windows);
6617 (void) XFreeFontNames(listhead);
6618 fontlist=(char **) RelinquishMagickMemory(fontlist);
6622 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6626 % X I n f o W i d g e t %
6630 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6632 % XInfoWidget() displays text in the Info widget. The purpose is to inform
6633 % the user that what activity is currently being performed (e.g. reading
6634 % an image, rotating an image, etc.).
6636 % The format of the XInfoWidget method is:
6638 % void XInfoWidget(Display *display,XWindows *windows,const char *activity)
6640 % A description of each parameter follows:
6642 % o display: Specifies a connection to an X server; returned from
6645 % o window: Specifies a pointer to a XWindows structure.
6647 % o activity: This character string reflects the current activity and is
6648 % displayed in the Info widget.
6651 MagickExport void XInfoWidget(Display *display,XWindows *windows,
6652 const char *activity)
6668 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
6669 assert(display != (Display *) NULL);
6670 assert(windows != (XWindows *) NULL);
6671 assert(activity != (char *) NULL);
6672 font_info=windows->info.font_info;
6673 width=WidgetTextWidth(font_info,(char *) activity)+((3*QuantumMargin) >> 1)+4;
6674 height=(unsigned int) (((6*(font_info->ascent+font_info->descent)) >> 2)+4);
6675 if ((windows->info.width != width) || (windows->info.height != height))
6678 Size Info widget to accommodate the activity text.
6680 windows->info.width=width;
6681 windows->info.height=height;
6682 window_changes.width=(int) width;
6683 window_changes.height=(int) height;
6684 (void) XReconfigureWMWindow(display,windows->info.id,windows->info.screen,
6685 (unsigned int) (CWWidth | CWHeight),&window_changes);
6687 if (windows->info.mapped == MagickFalse)
6689 (void) XMapRaised(display,windows->info.id);
6690 windows->info.mapped=MagickTrue;
6693 Initialize Info matte information.
6695 height=(unsigned int) (font_info->ascent+font_info->descent);
6696 XGetWidgetInfo(activity,&monitor_info);
6697 monitor_info.bevel_width--;
6698 margin=monitor_info.bevel_width+((windows->info.height-height) >> 1)-2;
6699 monitor_info.center=MagickFalse;
6700 monitor_info.x=(int) margin;
6701 monitor_info.y=(int) margin;
6702 monitor_info.width=windows->info.width-(margin << 1);
6703 monitor_info.height=windows->info.height-(margin << 1)+1;
6707 monitor_info.raised=MagickFalse;
6708 XDrawBeveledMatte(display,&windows->info,&monitor_info);
6709 monitor_info.raised=MagickTrue;
6710 XDrawWidgetText(display,&windows->info,&monitor_info);
6714 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6718 % X L i s t B r o w s e r W i d g e t %
6722 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6724 % XListBrowserWidget() displays a List Browser widget with a query to the
6725 % user. The user keys a reply or select a reply from the list. Finally, the
6726 % user presses the Action or Cancel button to exit. The typed text is
6727 % returned as the reply function parameter.
6729 % The format of the XListBrowserWidget method is:
6731 % void XListBrowserWidget(Display *display,XWindows *windows,
6732 % XWindowInfo *window_info,const char **list,const char *action,
6733 % const char *query,char *reply)
6735 % A description of each parameter follows:
6737 % o display: Specifies a connection to an X server; returned from
6740 % o window: Specifies a pointer to a XWindows structure.
6742 % o list: Specifies a pointer to an array of strings. The user can
6743 % select from these strings as a possible reply value.
6745 % o action: Specifies a pointer to the action of this widget.
6747 % o query: Specifies a pointer to the query to present to the user.
6749 % o reply: the response from the user is returned in this parameter.
6752 MagickExport void XListBrowserWidget(Display *display,XWindows *windows,
6753 XWindowInfo *window_info,const char **list,const char *action,
6754 const char *query,char *reply)
6756 #define CancelButtonText "Cancel"
6759 primary_selection[MaxTextExtent];
6767 static MagickStatusType
6768 mask = (MagickStatusType) (CWWidth | CWHeight | CWX | CWY);
6810 Count the number of entries in the list.
6812 assert(display != (Display *) NULL);
6813 assert(windows != (XWindows *) NULL);
6814 assert(window_info != (XWindowInfo *) NULL);
6815 assert(list != (const char **) NULL);
6816 assert(action != (char *) NULL);
6817 assert(query != (char *) NULL);
6818 assert(reply != (char *) NULL);
6819 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",action);
6820 XSetCursorState(display,windows,MagickTrue);
6821 XCheckRefreshWindows(display,windows);
6822 if (list == (const char **) NULL)
6824 XNoticeWidget(display,windows,"No text to browse:",(char *) NULL);
6827 for (entries=0; ; entries++)
6828 if (list[entries] == (char *) NULL)
6831 Determine Font Browser widget attributes.
6833 font_info=window_info->font_info;
6834 text_width=WidgetTextWidth(font_info,(char *) query);
6835 for (i=0; i < (int) entries; i++)
6836 if (WidgetTextWidth(font_info,(char *) list[i]) > text_width)
6837 text_width=WidgetTextWidth(font_info,(char *) list[i]);
6838 width=WidgetTextWidth(font_info,(char *) action);
6839 if (WidgetTextWidth(font_info,CancelButtonText) > width)
6840 width=WidgetTextWidth(font_info,CancelButtonText);
6841 width+=QuantumMargin;
6842 height=(unsigned int) (font_info->ascent+font_info->descent);
6844 Position List Browser widget.
6846 window_info->width=(unsigned int) MagickMin((int) text_width,(int)
6847 MaxTextWidth)+((9*QuantumMargin) >> 1);
6848 window_info->min_width=(unsigned int) (MinTextWidth+4*QuantumMargin);
6849 if (window_info->width < window_info->min_width)
6850 window_info->width=window_info->min_width;
6851 window_info->height=(unsigned int)
6852 (((81*height) >> 2)+((13*QuantumMargin) >> 1)+4);
6853 window_info->min_height=(unsigned int)
6854 (((23*height) >> 1)+((13*QuantumMargin) >> 1)+4);
6855 if (window_info->height < window_info->min_height)
6856 window_info->height=window_info->min_height;
6857 XConstrainWindowPosition(display,window_info);
6859 Map List Browser widget.
6861 (void) CopyMagickString(window_info->name,"Browse",MaxTextExtent);
6862 status=XStringListToTextProperty(&window_info->name,1,&window_name);
6863 if (status != False)
6865 XSetWMName(display,window_info->id,&window_name);
6866 XSetWMIconName(display,windows->widget.id,&window_name);
6867 (void) XFree((void *) window_name.value);
6869 window_changes.width=(int) window_info->width;
6870 window_changes.height=(int) window_info->height;
6871 window_changes.x=window_info->x;
6872 window_changes.y=window_info->y;
6873 (void) XReconfigureWMWindow(display,window_info->id,window_info->screen,mask,
6875 (void) XMapRaised(display,window_info->id);
6876 window_info->mapped=MagickFalse;
6878 Respond to X events.
6880 XGetWidgetInfo((char *) NULL,&slider_info);
6881 XGetWidgetInfo((char *) NULL,&north_info);
6882 XGetWidgetInfo((char *) NULL,&south_info);
6883 XGetWidgetInfo((char *) NULL,&expose_info);
6885 delay=SuspendTime << 2;
6886 state=UpdateConfigurationState;
6889 if (state & UpdateConfigurationState)
6895 Initialize button information.
6897 XGetWidgetInfo(CancelButtonText,&cancel_info);
6898 cancel_info.width=width;
6899 cancel_info.height=(unsigned int) ((3*height) >> 1);
6901 (window_info->width-cancel_info.width-QuantumMargin-2);
6903 (window_info->height-cancel_info.height-QuantumMargin);
6904 XGetWidgetInfo(action,&action_info);
6905 action_info.width=width;
6906 action_info.height=(unsigned int) ((3*height) >> 1);
6907 action_info.x=cancel_info.x-(cancel_info.width+(QuantumMargin >> 1)+
6908 (action_info.bevel_width << 1));
6909 action_info.y=cancel_info.y;
6911 Initialize reply information.
6913 XGetWidgetInfo(reply,&reply_info);
6914 reply_info.raised=MagickFalse;
6915 reply_info.bevel_width--;
6916 reply_info.width=window_info->width-((4*QuantumMargin) >> 1);
6917 reply_info.height=height << 1;
6918 reply_info.x=QuantumMargin;
6919 reply_info.y=action_info.y-reply_info.height-QuantumMargin;
6921 Initialize scroll information.
6923 XGetWidgetInfo((char *) NULL,&scroll_info);
6924 scroll_info.bevel_width--;
6925 scroll_info.width=height;
6926 scroll_info.height=(unsigned int)
6927 (reply_info.y-((6*QuantumMargin) >> 1)-height);
6928 scroll_info.x=reply_info.x+(reply_info.width-scroll_info.width);
6929 scroll_info.y=((5*QuantumMargin) >> 1)+height-reply_info.bevel_width;
6930 scroll_info.raised=MagickFalse;
6931 scroll_info.trough=MagickTrue;
6932 north_info=scroll_info;
6933 north_info.raised=MagickTrue;
6934 north_info.width-=(north_info.bevel_width << 1);
6935 north_info.height=north_info.width-1;
6936 north_info.x+=north_info.bevel_width;
6937 north_info.y+=north_info.bevel_width;
6938 south_info=north_info;
6939 south_info.y=scroll_info.y+scroll_info.height-scroll_info.bevel_width-
6942 slider_info=north_info;
6944 slider_info.width-=2;
6945 slider_info.min_y=north_info.y+north_info.height+north_info.bevel_width+
6946 slider_info.bevel_width+2;
6947 slider_info.height=scroll_info.height-((slider_info.min_y-
6948 scroll_info.y+1) << 1)+4;
6949 visible_entries=scroll_info.height/(height+(height >> 3));
6950 if (entries > visible_entries)
6951 slider_info.height=(visible_entries*slider_info.height)/entries;
6952 slider_info.max_y=south_info.y-south_info.bevel_width-
6953 slider_info.bevel_width-2;
6954 slider_info.x=scroll_info.x+slider_info.bevel_width+1;
6955 slider_info.y=slider_info.min_y;
6956 expose_info=scroll_info;
6957 expose_info.y=slider_info.y;
6959 Initialize list information.
6961 XGetWidgetInfo((char *) NULL,&list_info);
6962 list_info.raised=MagickFalse;
6963 list_info.bevel_width--;
6964 list_info.width=(unsigned int)
6965 (scroll_info.x-reply_info.x-(QuantumMargin >> 1));
6966 list_info.height=scroll_info.height;
6967 list_info.x=reply_info.x;
6968 list_info.y=scroll_info.y;
6969 if (window_info->mapped == MagickFalse)
6970 for (i=0; i < (int) entries; i++)
6971 if (LocaleCompare(list[i],reply) == 0)
6974 slider_info.id=i-(visible_entries >> 1);
6975 if (slider_info.id < 0)
6979 Initialize text information.
6981 XGetWidgetInfo(query,&text_info);
6982 text_info.width=reply_info.width;
6983 text_info.height=height;
6984 text_info.x=list_info.x-(QuantumMargin >> 1);
6985 text_info.y=QuantumMargin;
6987 Initialize selection information.
6989 XGetWidgetInfo((char *) NULL,&selection_info);
6990 selection_info.center=MagickFalse;
6991 selection_info.width=list_info.width;
6992 selection_info.height=(unsigned int) ((9*height) >> 3);
6993 selection_info.x=list_info.x;
6994 state&=(~UpdateConfigurationState);
6996 if (state & RedrawWidgetState)
6999 Redraw List Browser window.
7001 XDrawWidgetText(display,window_info,&text_info);
7002 XDrawBeveledMatte(display,window_info,&list_info);
7003 XDrawBeveledMatte(display,window_info,&scroll_info);
7004 XDrawTriangleNorth(display,window_info,&north_info);
7005 XDrawBeveledButton(display,window_info,&slider_info);
7006 XDrawTriangleSouth(display,window_info,&south_info);
7007 XDrawBeveledMatte(display,window_info,&reply_info);
7008 XDrawMatteText(display,window_info,&reply_info);
7009 XDrawBeveledButton(display,window_info,&action_info);
7010 XDrawBeveledButton(display,window_info,&cancel_info);
7011 XHighlightWidget(display,window_info,BorderOffset,BorderOffset);
7012 selection_info.id=(~0);
7013 state|=RedrawActionState;
7014 state|=RedrawListState;
7015 state&=(~RedrawWidgetState);
7017 if (state & RedrawListState)
7020 Determine slider id and position.
7022 if (slider_info.id >= (int) (entries-visible_entries))
7023 slider_info.id=(int) (entries-visible_entries);
7024 if ((slider_info.id < 0) || (entries <= visible_entries))
7026 slider_info.y=slider_info.min_y;
7029 slider_info.id*(slider_info.max_y-slider_info.min_y+1)/entries;
7030 if (slider_info.id != selection_info.id)
7033 Redraw scroll bar and file names.
7035 selection_info.id=slider_info.id;
7036 selection_info.y=list_info.y+(height >> 3)+2;
7037 for (i=0; i < (int) visible_entries; i++)
7039 selection_info.raised=(slider_info.id+i) != list_info.id ?
7040 MagickTrue : MagickFalse;
7041 selection_info.text=(char *) NULL;
7042 if ((slider_info.id+i) < (int) entries)
7043 selection_info.text=(char *) list[slider_info.id+i];
7044 XDrawWidgetText(display,window_info,&selection_info);
7045 selection_info.y+=(int) selection_info.height;
7050 if (slider_info.y > expose_info.y)
7052 expose_info.height=(unsigned int) slider_info.y-expose_info.y;
7053 expose_info.y=slider_info.y-expose_info.height-
7054 slider_info.bevel_width-1;
7058 expose_info.height=(unsigned int) expose_info.y-slider_info.y;
7059 expose_info.y=slider_info.y+slider_info.height+
7060 slider_info.bevel_width+1;
7062 XDrawTriangleNorth(display,window_info,&north_info);
7063 XDrawMatte(display,window_info,&expose_info);
7064 XDrawBeveledButton(display,window_info,&slider_info);
7065 XDrawTriangleSouth(display,window_info,&south_info);
7066 expose_info.y=slider_info.y;
7068 state&=(~RedrawListState);
7071 Wait for next event.
7073 if (north_info.raised && south_info.raised)
7074 (void) XIfEvent(display,&event,XScreenEvent,(char *) windows);
7078 Brief delay before advancing scroll bar.
7080 XDelay(display,delay);
7082 (void) XCheckIfEvent(display,&event,XScreenEvent,(char *) windows);
7083 if (north_info.raised == MagickFalse)
7084 if (slider_info.id > 0)
7090 state|=RedrawListState;
7092 if (south_info.raised == MagickFalse)
7093 if (slider_info.id < (int) entries)
7099 state|=RedrawListState;
7101 if (event.type != ButtonRelease)
7108 if (MatteIsActive(slider_info,event.xbutton))
7113 slider_info.active=MagickTrue;
7116 if (MatteIsActive(north_info,event.xbutton))
7117 if (slider_info.id > 0)
7122 north_info.raised=MagickFalse;
7124 state|=RedrawListState;
7127 if (MatteIsActive(south_info,event.xbutton))
7128 if (slider_info.id < (int) entries)
7133 south_info.raised=MagickFalse;
7135 state|=RedrawListState;
7138 if (MatteIsActive(scroll_info,event.xbutton))
7143 if (event.xbutton.y < slider_info.y)
7144 slider_info.id-=(visible_entries-1);
7146 slider_info.id+=(visible_entries-1);
7147 state|=RedrawListState;
7150 if (MatteIsActive(list_info,event.xbutton))
7156 User pressed list matte.
7158 id=slider_info.id+(event.xbutton.y-(list_info.y+(height >> 1))+1)/
7159 selection_info.height;
7160 if (id >= (int) entries)
7162 (void) CopyMagickString(reply_info.text,list[id],MaxTextExtent);
7163 reply_info.highlight=MagickFalse;
7164 reply_info.marker=reply_info.text;
7165 reply_info.cursor=reply_info.text+Extent(reply_info.text);
7166 XDrawMatteText(display,window_info,&reply_info);
7167 selection_info.id=(~0);
7168 if (id == list_info.id)
7170 action_info.raised=MagickFalse;
7171 XDrawBeveledButton(display,window_info,&action_info);
7175 state|=RedrawListState;
7178 if (MatteIsActive(action_info,event.xbutton))
7181 User pressed action button.
7183 action_info.raised=MagickFalse;
7184 XDrawBeveledButton(display,window_info,&action_info);
7187 if (MatteIsActive(cancel_info,event.xbutton))
7190 User pressed Cancel button.
7192 cancel_info.raised=MagickFalse;
7193 XDrawBeveledButton(display,window_info,&cancel_info);
7196 if (MatteIsActive(reply_info,event.xbutton) == MagickFalse)
7198 if (event.xbutton.button != Button2)
7204 Move text cursor to position of button press.
7206 x=event.xbutton.x-reply_info.x-(QuantumMargin >> 2);
7207 for (i=1; i <= Extent(reply_info.marker); i++)
7208 if (XTextWidth(font_info,reply_info.marker,i) > x)
7210 reply_info.cursor=reply_info.marker+i-1;
7211 if (event.xbutton.time > (click_time+DoubleClick))
7212 reply_info.highlight=MagickFalse;
7216 Become the XA_PRIMARY selection owner.
7218 (void) CopyMagickString(primary_selection,reply_info.text,
7220 (void) XSetSelectionOwner(display,XA_PRIMARY,window_info->id,
7221 event.xbutton.time);
7222 reply_info.highlight=XGetSelectionOwner(display,XA_PRIMARY) ==
7223 window_info->id ? MagickTrue : MagickFalse;
7225 XDrawMatteText(display,window_info,&reply_info);
7226 click_time=event.xbutton.time;
7230 Request primary selection.
7232 (void) XConvertSelection(display,XA_PRIMARY,XA_STRING,XA_STRING,
7233 window_info->id,event.xbutton.time);
7238 if (window_info->mapped == MagickFalse)
7240 if (north_info.raised == MagickFalse)
7243 User released up button.
7245 delay=SuspendTime << 2;
7246 north_info.raised=MagickTrue;
7247 XDrawTriangleNorth(display,window_info,&north_info);
7249 if (south_info.raised == MagickFalse)
7252 User released down button.
7254 delay=SuspendTime << 2;
7255 south_info.raised=MagickTrue;
7256 XDrawTriangleSouth(display,window_info,&south_info);
7258 if (slider_info.active)
7261 Stop tracking slider.
7263 slider_info.active=MagickFalse;
7266 if (action_info.raised == MagickFalse)
7268 if (event.xbutton.window == window_info->id)
7270 if (MatteIsActive(action_info,event.xbutton))
7272 if (*reply_info.text == '\0')
7273 (void) XBell(display,0);
7278 action_info.raised=MagickTrue;
7279 XDrawBeveledButton(display,window_info,&action_info);
7281 if (cancel_info.raised == MagickFalse)
7283 if (event.xbutton.window == window_info->id)
7284 if (MatteIsActive(cancel_info,event.xbutton))
7286 *reply_info.text='\0';
7289 cancel_info.raised=MagickTrue;
7290 XDrawBeveledButton(display,window_info,&cancel_info);
7292 if (MatteIsActive(reply_info,event.xbutton) == MagickFalse)
7299 If client window delete message, exit.
7301 if (event.xclient.message_type != windows->wm_protocols)
7303 if (*event.xclient.data.l == (int) windows->wm_take_focus)
7305 (void) XSetInputFocus(display,event.xclient.window,RevertToParent,
7306 (Time) event.xclient.data.l[1]);
7309 if (*event.xclient.data.l != (int) windows->wm_delete_window)
7311 if (event.xclient.window == window_info->id)
7313 *reply_info.text='\0';
7319 case ConfigureNotify:
7322 Update widget configuration.
7324 if (event.xconfigure.window != window_info->id)
7326 if ((event.xconfigure.width == (int) window_info->width) &&
7327 (event.xconfigure.height == (int) window_info->height))
7329 window_info->width=(unsigned int)
7330 MagickMax(event.xconfigure.width,(int) window_info->min_width);
7331 window_info->height=(unsigned int)
7332 MagickMax(event.xconfigure.height,(int) window_info->min_height);
7333 state|=UpdateConfigurationState;
7338 if (event.xcrossing.window != window_info->id)
7340 state&=(~InactiveWidgetState);
7345 if (event.xexpose.window != window_info->id)
7347 if (event.xexpose.count != 0)
7349 state|=RedrawWidgetState;
7355 command[MaxTextExtent];
7364 Respond to a user key press.
7366 if (event.xkey.window != window_info->id)
7368 length=XLookupString((XKeyEvent *) &event.xkey,command,
7369 (int) sizeof(command),&key_symbol,(XComposeStatus *) NULL);
7370 *(command+length)='\0';
7371 if (AreaIsActive(scroll_info,event.xkey))
7376 switch ((int) key_symbol)
7399 slider_info.id-=visible_entries;
7405 slider_info.id+=visible_entries;
7411 slider_info.id=(int) entries;
7415 state|=RedrawListState;
7418 if ((key_symbol == XK_Return) || (key_symbol == XK_KP_Enter))
7423 if (*reply_info.text == '\0')
7425 action_info.raised=MagickFalse;
7426 XDrawBeveledButton(display,window_info,&action_info);
7430 if (key_symbol == XK_Control_L)
7432 state|=ControlState;
7435 if (state & ControlState)
7436 switch ((int) key_symbol)
7442 Erase the entire line of text.
7444 *reply_info.text='\0';
7445 reply_info.cursor=reply_info.text;
7446 reply_info.marker=reply_info.text;
7447 reply_info.highlight=MagickFalse;
7453 XEditText(display,&reply_info,key_symbol,command,state);
7454 XDrawMatteText(display,window_info,&reply_info);
7460 command[MaxTextExtent];
7466 Respond to a user key release.
7468 if (event.xkey.window != window_info->id)
7470 (void) XLookupString((XKeyEvent *) &event.xkey,command,
7471 (int) sizeof(command),&key_symbol,(XComposeStatus *) NULL);
7472 if (key_symbol == XK_Control_L)
7473 state&=(~ControlState);
7478 if (event.xcrossing.window != window_info->id)
7480 state|=InactiveWidgetState;
7492 Discard pending button motion events.
7494 while (XCheckMaskEvent(display,ButtonMotionMask,&event)) ;
7495 if (slider_info.active)
7500 slider_info.y=event.xmotion.y-
7501 ((slider_info.height+slider_info.bevel_width) >> 1)+1;
7502 if (slider_info.y < slider_info.min_y)
7503 slider_info.y=slider_info.min_y;
7504 if (slider_info.y > slider_info.max_y)
7505 slider_info.y=slider_info.max_y;
7507 if (slider_info.y != slider_info.min_y)
7508 slider_info.id=(int) ((entries*(slider_info.y-
7509 slider_info.min_y+1))/(slider_info.max_y-slider_info.min_y+1));
7510 state|=RedrawListState;
7513 if (state & InactiveWidgetState)
7515 if (action_info.raised == MatteIsActive(action_info,event.xmotion))
7518 Action button status changed.
7520 action_info.raised=action_info.raised == MagickFalse ?
7521 MagickTrue : MagickFalse;
7522 XDrawBeveledButton(display,window_info,&action_info);
7525 if (cancel_info.raised == MatteIsActive(cancel_info,event.xmotion))
7528 Cancel button status changed.
7530 cancel_info.raised=cancel_info.raised == MagickFalse ?
7531 MagickTrue : MagickFalse;
7532 XDrawBeveledButton(display,window_info,&cancel_info);
7537 case SelectionClear:
7539 reply_info.highlight=MagickFalse;
7540 XDrawMatteText(display,window_info,&reply_info);
7543 case SelectionNotify:
7559 Obtain response from primary selection.
7561 if (event.xselection.property == (Atom) None)
7563 status=XGetWindowProperty(display,
7564 event.xselection.requestor,event.xselection.property,0L,2047L,
7565 MagickTrue,XA_STRING,&type,&format,&length,&after,&data);
7566 if ((status != Success) || (type != XA_STRING) || (format == 32) ||
7569 if ((Extent(reply_info.text)+length) >= MaxTextExtent)
7570 (void) XBell(display,0);
7574 Insert primary selection in reply text.
7576 *(data+length)='\0';
7577 XEditText(display,&reply_info,(KeySym) XK_Insert,(char *) data,
7579 XDrawMatteText(display,window_info,&reply_info);
7580 state|=RedrawActionState;
7582 (void) XFree((void *) data);
7585 case SelectionRequest:
7590 XSelectionRequestEvent
7593 if (reply_info.highlight == MagickFalse)
7596 Set primary selection.
7598 request=(&(event.xselectionrequest));
7599 (void) XChangeProperty(request->display,request->requestor,
7600 request->property,request->target,8,PropModeReplace,
7601 (unsigned char *) primary_selection,Extent(primary_selection));
7602 notify.type=SelectionNotify;
7603 notify.send_event=MagickTrue;
7604 notify.display=request->display;
7605 notify.requestor=request->requestor;
7606 notify.selection=request->selection;
7607 notify.target=request->target;
7608 notify.time=request->time;
7609 if (request->property == None)
7610 notify.property=request->target;
7612 notify.property=request->property;
7613 (void) XSendEvent(request->display,request->requestor,False,NoEventMask,
7614 (XEvent *) ¬ify);
7619 } while ((state & ExitState) == 0);
7620 XSetCursorState(display,windows,MagickFalse);
7621 (void) XWithdrawWindow(display,window_info->id,window_info->screen);
7622 XCheckRefreshWindows(display,windows);
7626 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7630 % X M e n u W i d g e t %
7634 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7636 % XMenuWidget() maps a menu and returns the command pointed to by the user
7637 % when the button is released.
7639 % The format of the XMenuWidget method is:
7641 % int XMenuWidget(Display *display,XWindows *windows,const char *title,
7642 % const char **selections,char *item)
7644 % A description of each parameter follows:
7646 % o selection_number: Specifies the number of the selection that the
7649 % o display: Specifies a connection to an X server; returned from
7652 % o window: Specifies a pointer to a XWindows structure.
7654 % o title: Specifies a character string that describes the menu selections.
7656 % o selections: Specifies a pointer to one or more strings that comprise
7657 % the choices in the menu.
7659 % o item: Specifies a character array. The item selected from the menu
7663 MagickExport int XMenuWidget(Display *display,XWindows *windows,
7664 const char *title,const char **selections,char *item)
7690 XSetWindowAttributes
7702 Determine Menu widget attributes.
7704 assert(display != (Display *) NULL);
7705 assert(windows != (XWindows *) NULL);
7706 assert(title != (char *) NULL);
7707 assert(selections != (const char **) NULL);
7708 assert(item != (char *) NULL);
7709 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",title);
7710 font_info=windows->widget.font_info;
7711 windows->widget.width=submenu_info.active == 0 ?
7712 WidgetTextWidth(font_info,(char *) title) : 0;
7713 for (id=0; selections[id] != (char *) NULL; id++)
7715 width=WidgetTextWidth(font_info,(char *) selections[id]);
7716 if (width > windows->widget.width)
7717 windows->widget.width=width;
7719 number_selections=(unsigned int) id;
7720 XGetWidgetInfo((char *) NULL,&menu_info);
7721 title_height=(unsigned int) (submenu_info.active == 0 ?
7722 (3*(font_info->descent+font_info->ascent) >> 1)+5 : 2);
7723 width=WidgetTextWidth(font_info,(char *) title);
7724 height=(unsigned int) ((3*(font_info->ascent+font_info->descent)) >> 1);
7726 Position Menu widget.
7728 windows->widget.width+=QuantumMargin+(menu_info.bevel_width << 1);
7729 top_offset=title_height+menu_info.bevel_width-1;
7730 windows->widget.height=top_offset+number_selections*height+4;
7731 windows->widget.min_width=windows->widget.width;
7732 windows->widget.min_height=windows->widget.height;
7733 XQueryPosition(display,windows->widget.root,&x,&y);
7734 windows->widget.x=x-(QuantumMargin >> 1);
7735 if (submenu_info.active != 0)
7738 windows->command.x+windows->command.width-QuantumMargin;
7739 toggle_info.raised=MagickTrue;
7740 XDrawTriangleEast(display,&windows->command,&toggle_info);
7742 windows->widget.y=submenu_info.active == 0 ? y-(ssize_t)
7743 ((3*title_height) >> 2) : y;
7744 if (submenu_info.active != 0)
7745 windows->widget.y=windows->command.y+submenu_info.y;
7746 XConstrainWindowPosition(display,&windows->widget);
7750 window_attributes.override_redirect=MagickTrue;
7751 (void) XChangeWindowAttributes(display,windows->widget.id,
7752 (size_t) CWOverrideRedirect,&window_attributes);
7753 window_changes.width=(int) windows->widget.width;
7754 window_changes.height=(int) windows->widget.height;
7755 window_changes.x=windows->widget.x;
7756 window_changes.y=windows->widget.y;
7757 (void) XReconfigureWMWindow(display,windows->widget.id,windows->widget.screen,
7758 (unsigned int) (CWWidth | CWHeight | CWX | CWY),&window_changes);
7759 (void) XMapRaised(display,windows->widget.id);
7760 windows->widget.mapped=MagickFalse;
7762 Respond to X events.
7764 selection_info.height=height;
7765 cursor=XCreateFontCursor(display,XC_right_ptr);
7766 (void) XCheckDefineCursor(display,windows->image.id,cursor);
7767 (void) XCheckDefineCursor(display,windows->command.id,cursor);
7768 (void) XCheckDefineCursor(display,windows->widget.id,cursor);
7769 state=UpdateConfigurationState;
7772 if (state & UpdateConfigurationState)
7775 Initialize selection information.
7777 XGetWidgetInfo((char *) NULL,&menu_info);
7778 menu_info.bevel_width--;
7779 menu_info.width=windows->widget.width-((menu_info.bevel_width) << 1);
7780 menu_info.height=windows->widget.height-((menu_info.bevel_width) << 1);
7781 menu_info.x=(int) menu_info.bevel_width;
7782 menu_info.y=(int) menu_info.bevel_width;
7783 XGetWidgetInfo((char *) NULL,&selection_info);
7784 selection_info.center=MagickFalse;
7785 selection_info.width=menu_info.width;
7786 selection_info.height=height;
7787 selection_info.x=menu_info.x;
7788 highlight_info=selection_info;
7789 highlight_info.bevel_width--;
7790 highlight_info.width-=(highlight_info.bevel_width << 1);
7791 highlight_info.height-=(highlight_info.bevel_width << 1);
7792 highlight_info.x+=highlight_info.bevel_width;
7793 state&=(~UpdateConfigurationState);
7795 if (state & RedrawWidgetState)
7800 if (submenu_info.active == 0)
7802 y=(int) title_height;
7803 XSetBevelColor(display,&windows->widget,MagickFalse);
7804 (void) XDrawLine(display,windows->widget.id,
7805 windows->widget.widget_context,selection_info.x,y-1,
7806 (int) selection_info.width,y-1);
7807 XSetBevelColor(display,&windows->widget,MagickTrue);
7808 (void) XDrawLine(display,windows->widget.id,
7809 windows->widget.widget_context,selection_info.x,y,
7810 (int) selection_info.width,y);
7811 (void) XSetFillStyle(display,windows->widget.widget_context,
7815 Draw menu selections.
7817 selection_info.center=MagickTrue;
7818 selection_info.y=(int) menu_info.bevel_width;
7819 selection_info.text=(char *) title;
7820 if (submenu_info.active == 0)
7821 XDrawWidgetText(display,&windows->widget,&selection_info);
7822 selection_info.center=MagickFalse;
7823 selection_info.y=(int) top_offset;
7824 for (id=0; id < (int) number_selections; id++)
7826 selection_info.text=(char *) selections[id];
7827 XDrawWidgetText(display,&windows->widget,&selection_info);
7828 highlight_info.y=selection_info.y+highlight_info.bevel_width;
7829 if (id == selection_info.id)
7830 XDrawBevel(display,&windows->widget,&highlight_info);
7831 selection_info.y+=(int) selection_info.height;
7833 XDrawBevel(display,&windows->widget,&menu_info);
7834 state&=(~RedrawWidgetState);
7836 if (number_selections > 2)
7841 y=(int) (top_offset+selection_info.height*(number_selections-1));
7842 XSetBevelColor(display,&windows->widget,MagickFalse);
7843 (void) XDrawLine(display,windows->widget.id,
7844 windows->widget.widget_context,selection_info.x,y-1,
7845 (int) selection_info.width,y-1);
7846 XSetBevelColor(display,&windows->widget,MagickTrue);
7847 (void) XDrawLine(display,windows->widget.id,
7848 windows->widget.widget_context,selection_info.x,y,
7849 (int) selection_info.width,y);
7850 (void) XSetFillStyle(display,windows->widget.widget_context,FillSolid);
7853 Wait for next event.
7855 (void) XIfEvent(display,&event,XScreenEvent,(char *) windows);
7860 if (event.xbutton.window != windows->widget.id)
7865 if (event.xbutton.window == windows->command.id)
7866 (void) XPutBackEvent(display,&event);
7867 selection_info.id=(~0);
7872 state&=(~InactiveWidgetState);
7873 id=(event.xbutton.y-top_offset)/(int) selection_info.height;
7874 selection_info.id=id;
7875 if ((id < 0) || (id >= (int) number_selections))
7878 Highlight this selection.
7880 selection_info.y=(int) (top_offset+id*selection_info.height);
7881 selection_info.text=(char *) selections[id];
7882 XDrawWidgetText(display,&windows->widget,&selection_info);
7883 highlight_info.y=selection_info.y+highlight_info.bevel_width;
7884 XDrawBevel(display,&windows->widget,&highlight_info);
7889 if (windows->widget.mapped == MagickFalse)
7891 if (event.xbutton.window == windows->command.id)
7892 if ((state & InactiveWidgetState) == 0)
7897 XSetCursorState(display,windows,MagickFalse);
7902 case ConfigureNotify:
7905 Update widget configuration.
7907 if (event.xconfigure.window != windows->widget.id)
7909 if ((event.xconfigure.width == (int) windows->widget.width) &&
7910 (event.xconfigure.height == (int) windows->widget.height))
7912 windows->widget.width=(unsigned int)
7913 MagickMax(event.xconfigure.width,(int) windows->widget.min_width);
7914 windows->widget.height=(unsigned int)
7915 MagickMax(event.xconfigure.height,(int) windows->widget.min_height);
7916 state|=UpdateConfigurationState;
7921 if (event.xcrossing.window != windows->widget.id)
7923 if (event.xcrossing.state == 0)
7925 state&=(~InactiveWidgetState);
7926 id=((event.xcrossing.y-top_offset)/(int) selection_info.height);
7927 if ((selection_info.id >= 0) &&
7928 (selection_info.id < (int) number_selections))
7931 Unhighlight last selection.
7933 if (id == selection_info.id)
7935 selection_info.y=(int)
7936 (top_offset+selection_info.id*selection_info.height);
7937 selection_info.text=(char *) selections[selection_info.id];
7938 XDrawWidgetText(display,&windows->widget,&selection_info);
7940 if ((id < 0) || (id >= (int) number_selections))
7943 Highlight this selection.
7945 selection_info.id=id;
7946 selection_info.y=(int)
7947 (top_offset+selection_info.id*selection_info.height);
7948 selection_info.text=(char *) selections[selection_info.id];
7949 XDrawWidgetText(display,&windows->widget,&selection_info);
7950 highlight_info.y=selection_info.y+highlight_info.bevel_width;
7951 XDrawBevel(display,&windows->widget,&highlight_info);
7956 if (event.xexpose.window != windows->widget.id)
7958 if (event.xexpose.count != 0)
7960 state|=RedrawWidgetState;
7965 if (event.xcrossing.window != windows->widget.id)
7967 state|=InactiveWidgetState;
7968 id=selection_info.id;
7969 if ((id < 0) || (id >= (int) number_selections))
7972 Unhighlight last selection.
7974 selection_info.y=(int) (top_offset+id*selection_info.height);
7975 selection_info.id=(~0);
7976 selection_info.text=(char *) selections[id];
7977 XDrawWidgetText(display,&windows->widget,&selection_info);
7983 Discard pending button motion events.
7985 while (XCheckMaskEvent(display,ButtonMotionMask,&event)) ;
7986 if (submenu_info.active != 0)
7987 if (event.xmotion.window == windows->command.id)
7989 if ((state & InactiveWidgetState) == 0)
7991 if (MatteIsActive(submenu_info,event.xmotion) == MagickFalse)
7993 selection_info.id=(~0);
8000 if (WindowIsActive(windows->command,event.xmotion))
8002 selection_info.id=(~0);
8008 if (event.xmotion.window != windows->widget.id)
8010 if (state & InactiveWidgetState)
8012 id=(event.xmotion.y-top_offset)/(int) selection_info.height;
8013 if ((selection_info.id >= 0) &&
8014 (selection_info.id < (int) number_selections))
8017 Unhighlight last selection.
8019 if (id == selection_info.id)
8021 selection_info.y=(int)
8022 (top_offset+selection_info.id*selection_info.height);
8023 selection_info.text=(char *) selections[selection_info.id];
8024 XDrawWidgetText(display,&windows->widget,&selection_info);
8026 selection_info.id=id;
8027 if ((id < 0) || (id >= (int) number_selections))
8030 Highlight this selection.
8032 selection_info.y=(int) (top_offset+id*selection_info.height);
8033 selection_info.text=(char *) selections[id];
8034 XDrawWidgetText(display,&windows->widget,&selection_info);
8035 highlight_info.y=selection_info.y+highlight_info.bevel_width;
8036 XDrawBevel(display,&windows->widget,&highlight_info);
8042 } while ((state & ExitState) == 0);
8043 (void) XFreeCursor(display,cursor);
8044 window_attributes.override_redirect=MagickFalse;
8045 (void) XChangeWindowAttributes(display,windows->widget.id,
8046 (size_t) CWOverrideRedirect,&window_attributes);
8047 (void) XWithdrawWindow(display,windows->widget.id,windows->widget.screen);
8048 XCheckRefreshWindows(display,windows);
8049 if (submenu_info.active != 0)
8051 submenu_info.active=MagickFalse;
8052 toggle_info.raised=MagickFalse;
8053 XDrawTriangleEast(display,&windows->command,&toggle_info);
8055 if ((selection_info.id < 0) || (selection_info.id >= (int) number_selections))
8057 (void) CopyMagickString(item,selections[selection_info.id],MaxTextExtent);
8058 return(selection_info.id);
8062 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8066 % X N o t i c e W i d g e t %
8070 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8072 % XNoticeWidget() displays a Notice widget with a notice to the user. The
8073 % function returns when the user presses the "Dismiss" button.
8075 % The format of the XNoticeWidget method is:
8077 % void XNoticeWidget(Display *display,XWindows *windows,
8078 % const char *reason,const char *description)
8080 % A description of each parameter follows:
8082 % o display: Specifies a connection to an X server; returned from
8085 % o window: Specifies a pointer to a XWindows structure.
8087 % o reason: Specifies the message to display before terminating the
8090 % o description: Specifies any description to the message.
8093 MagickExport void XNoticeWidget(Display *display,XWindows *windows,
8094 const char *reason,const char *description)
8096 #define DismissButtonText "Dismiss"
8135 Determine Notice widget attributes.
8137 assert(display != (Display *) NULL);
8138 assert(windows != (XWindows *) NULL);
8139 assert(reason != (char *) NULL);
8140 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",reason);
8141 XDelay(display,SuspendTime << 3); /* avoid surpise with delay */
8142 XSetCursorState(display,windows,MagickTrue);
8143 XCheckRefreshWindows(display,windows);
8144 font_info=windows->widget.font_info;
8145 width=WidgetTextWidth(font_info,DismissButtonText);
8146 text=GetLocaleExceptionMessage(XServerError,reason);
8147 if (text != (char *) NULL)
8148 if (WidgetTextWidth(font_info,(char *) text) > width)
8149 width=WidgetTextWidth(font_info,(char *) text);
8150 if (description != (char *) NULL)
8152 text=GetLocaleExceptionMessage(XServerError,description);
8153 if (text != (char *) NULL)
8154 if (WidgetTextWidth(font_info,(char *) text) > width)
8155 width=WidgetTextWidth(font_info,(char *) text);
8157 height=(unsigned int) (font_info->ascent+font_info->descent);
8159 Position Notice widget.
8161 windows->widget.width=width+4*QuantumMargin;
8162 windows->widget.min_width=width+QuantumMargin;
8163 if (windows->widget.width < windows->widget.min_width)
8164 windows->widget.width=windows->widget.min_width;
8165 windows->widget.height=(unsigned int) (12*height);
8166 windows->widget.min_height=(unsigned int) (7*height);
8167 if (windows->widget.height < windows->widget.min_height)
8168 windows->widget.height=windows->widget.min_height;
8169 XConstrainWindowPosition(display,&windows->widget);
8173 (void) CopyMagickString(windows->widget.name,"Notice",MaxTextExtent);
8174 status=XStringListToTextProperty(&windows->widget.name,1,&window_name);
8175 if (status != False)
8177 XSetWMName(display,windows->widget.id,&window_name);
8178 XSetWMIconName(display,windows->widget.id,&window_name);
8179 (void) XFree((void *) window_name.value);
8181 window_changes.width=(int) windows->widget.width;
8182 window_changes.height=(int) windows->widget.height;
8183 window_changes.x=windows->widget.x;
8184 window_changes.y=windows->widget.y;
8185 (void) XReconfigureWMWindow(display,windows->widget.id,windows->widget.screen,
8186 (unsigned int) (CWWidth | CWHeight | CWX | CWY),&window_changes);
8187 (void) XMapRaised(display,windows->widget.id);
8188 windows->widget.mapped=MagickFalse;
8189 (void) XBell(display,0);
8191 Respond to X events.
8193 timer=time((time_t *) NULL)+Timeout;
8194 state=UpdateConfigurationState;
8197 if (time((time_t *) NULL) > timer)
8199 if (state & UpdateConfigurationState)
8202 Initialize Dismiss button information.
8204 XGetWidgetInfo(DismissButtonText,&dismiss_info);
8205 dismiss_info.width=(unsigned int) QuantumMargin+
8206 WidgetTextWidth(font_info,DismissButtonText);
8207 dismiss_info.height=(unsigned int) ((3*height) >> 1);
8208 dismiss_info.x=(int)
8209 ((windows->widget.width >> 1)-(dismiss_info.width >> 1));
8210 dismiss_info.y=(int)
8211 (windows->widget.height-(dismiss_info.height << 1));
8212 state&=(~UpdateConfigurationState);
8214 if (state & RedrawWidgetState)
8217 Redraw Notice widget.
8219 width=WidgetTextWidth(font_info,(char *) reason);
8220 x=(int) ((windows->widget.width >> 1)-(width >> 1));
8221 y=(int) ((windows->widget.height >> 1)-(height << 1));
8222 (void) XDrawString(display,windows->widget.id,
8223 windows->widget.annotate_context,x,y,(char *) reason,Extent(reason));
8224 if (description != (char *) NULL)
8226 width=WidgetTextWidth(font_info,(char *) description);
8227 x=(int) ((windows->widget.width >> 1)-(width >> 1));
8229 (void) XDrawString(display,windows->widget.id,
8230 windows->widget.annotate_context,x,y,(char *) description,
8231 Extent(description));
8233 XDrawBeveledButton(display,&windows->widget,&dismiss_info);
8234 XHighlightWidget(display,&windows->widget,BorderOffset,BorderOffset);
8235 state&=(~RedrawWidgetState);
8238 Wait for next event.
8240 if (XCheckIfEvent(display,&event,XScreenEvent,(char *) windows) == MagickFalse)
8243 Do not block if delay > 0.
8245 XDelay(display,SuspendTime << 2);
8252 if (MatteIsActive(dismiss_info,event.xbutton))
8255 User pressed Dismiss button.
8257 dismiss_info.raised=MagickFalse;
8258 XDrawBeveledButton(display,&windows->widget,&dismiss_info);
8265 if (windows->widget.mapped == MagickFalse)
8267 if (dismiss_info.raised == MagickFalse)
8269 if (event.xbutton.window == windows->widget.id)
8270 if (MatteIsActive(dismiss_info,event.xbutton))
8272 dismiss_info.raised=MagickTrue;
8273 XDrawBeveledButton(display,&windows->widget,&dismiss_info);
8280 If client window delete message, exit.
8282 if (event.xclient.message_type != windows->wm_protocols)
8284 if (*event.xclient.data.l == (int) windows->wm_take_focus)
8286 (void) XSetInputFocus(display,event.xclient.window,RevertToParent,
8287 (Time) event.xclient.data.l[1]);
8290 if (*event.xclient.data.l != (int) windows->wm_delete_window)
8292 if (event.xclient.window == windows->widget.id)
8299 case ConfigureNotify:
8302 Update widget configuration.
8304 if (event.xconfigure.window != windows->widget.id)
8306 if ((event.xconfigure.width == (int) windows->widget.width) &&
8307 (event.xconfigure.height == (int) windows->widget.height))
8309 windows->widget.width=(unsigned int)
8310 MagickMax(event.xconfigure.width,(int) windows->widget.min_width);
8311 windows->widget.height=(unsigned int)
8312 MagickMax(event.xconfigure.height,(int) windows->widget.min_height);
8313 state|=UpdateConfigurationState;
8318 if (event.xcrossing.window != windows->widget.id)
8320 state&=(~InactiveWidgetState);
8325 if (event.xexpose.window != windows->widget.id)
8327 if (event.xexpose.count != 0)
8329 state|=RedrawWidgetState;
8335 command[MaxTextExtent];
8341 Respond to a user key press.
8343 if (event.xkey.window != windows->widget.id)
8345 (void) XLookupString((XKeyEvent *) &event.xkey,command,
8346 (int) sizeof(command),&key_symbol,(XComposeStatus *) NULL);
8347 if ((key_symbol == XK_Return) || (key_symbol == XK_KP_Enter))
8349 dismiss_info.raised=MagickFalse;
8350 XDrawBeveledButton(display,&windows->widget,&dismiss_info);
8358 if (event.xcrossing.window != windows->widget.id)
8360 state|=InactiveWidgetState;
8366 Discard pending button motion events.
8368 while (XCheckMaskEvent(display,ButtonMotionMask,&event)) ;
8369 if (state & InactiveWidgetState)
8371 if (dismiss_info.raised == MatteIsActive(dismiss_info,event.xmotion))
8374 Dismiss button status changed.
8376 dismiss_info.raised=
8377 dismiss_info.raised == MagickFalse ? MagickTrue : MagickFalse;
8378 XDrawBeveledButton(display,&windows->widget,&dismiss_info);
8386 } while ((state & ExitState) == 0);
8387 XSetCursorState(display,windows,MagickFalse);
8388 (void) XWithdrawWindow(display,windows->widget.id,windows->widget.screen);
8389 XCheckRefreshWindows(display,windows);
8393 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8397 % X P r e f e r e n c e s W i d g e t %
8401 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8403 % XPreferencesWidget() displays a Preferences widget with program preferences.
8404 % If the user presses the Apply button, the preferences are stored in a
8405 % configuration file in the users' home directory.
8407 % The format of the XPreferencesWidget method is:
8409 % MagickBooleanType XPreferencesWidget(Display *display,
8410 % XResourceInfo *resource_info,XWindows *windows)
8412 % A description of each parameter follows:
8414 % o display: Specifies a connection to an X server; returned from
8417 % o resource_info: Specifies a pointer to a X11 XResourceInfo structure.
8419 % o window: Specifies a pointer to a XWindows structure.
8422 MagickExport MagickBooleanType XPreferencesWidget(Display *display,
8423 XResourceInfo *resource_info,XWindows *windows)
8425 #define ApplyButtonText "Apply"
8426 #define CacheButtonText "%lu mega-bytes of memory in the undo edit cache "
8427 #define CancelButtonText "Cancel"
8428 #define NumberPreferences 8
8433 "display image centered on a backdrop",
8434 "confirm on program exit",
8435 "confirm on image edits",
8436 "correct image for display gamma",
8437 "display warning messages",
8438 "apply Floyd/Steinberg error diffusion to image",
8439 "use a shared colormap for colormapped X visuals",
8440 "display images as an X server pixmap"
8444 cache[MaxTextExtent];
8477 preferences_info[NumberPreferences];
8483 Determine Preferences widget attributes.
8485 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
8486 assert(display != (Display *) NULL);
8487 assert(resource_info != (XResourceInfo *) NULL);
8488 assert(windows != (XWindows *) NULL);
8489 XCheckRefreshWindows(display,windows);
8490 font_info=windows->widget.font_info;
8491 text_width=WidgetTextWidth(font_info,CacheButtonText);
8492 for (i=0; i < NumberPreferences; i++)
8493 if (WidgetTextWidth(font_info,(char *) Preferences[i]) > text_width)
8494 text_width=WidgetTextWidth(font_info,(char *) Preferences[i]);
8495 width=WidgetTextWidth(font_info,ApplyButtonText);
8496 if (WidgetTextWidth(font_info,CancelButtonText) > width)
8497 width=WidgetTextWidth(font_info,CancelButtonText);
8498 width+=(unsigned int) QuantumMargin;
8499 height=(unsigned int) (font_info->ascent+font_info->descent);
8501 Position Preferences widget.
8503 windows->widget.width=(unsigned int) (MagickMax((int) (width << 1),
8504 (int) text_width)+6*QuantumMargin);
8505 windows->widget.min_width=(width << 1)+QuantumMargin;
8506 if (windows->widget.width < windows->widget.min_width)
8507 windows->widget.width=windows->widget.min_width;
8508 windows->widget.height=(unsigned int)
8509 (7*height+NumberPreferences*(height+(QuantumMargin >> 1)));
8510 windows->widget.min_height=(unsigned int)
8511 (7*height+NumberPreferences*(height+(QuantumMargin >> 1)));
8512 if (windows->widget.height < windows->widget.min_height)
8513 windows->widget.height=windows->widget.min_height;
8514 XConstrainWindowPosition(display,&windows->widget);
8516 Map Preferences widget.
8518 (void) CopyMagickString(windows->widget.name,"Preferences",MaxTextExtent);
8519 status=XStringListToTextProperty(&windows->widget.name,1,&window_name);
8520 if (status != False)
8522 XSetWMName(display,windows->widget.id,&window_name);
8523 XSetWMIconName(display,windows->widget.id,&window_name);
8524 (void) XFree((void *) window_name.value);
8526 window_changes.width=(int) windows->widget.width;
8527 window_changes.height=(int) windows->widget.height;
8528 window_changes.x=windows->widget.x;
8529 window_changes.y=windows->widget.y;
8530 (void) XReconfigureWMWindow(display,windows->widget.id,windows->widget.screen,
8531 (unsigned int) (CWWidth | CWHeight | CWX | CWY),&window_changes);
8532 (void) XMapRaised(display,windows->widget.id);
8533 windows->widget.mapped=MagickFalse;
8535 Respond to X events.
8537 state=UpdateConfigurationState;
8538 XSetCursorState(display,windows,MagickTrue);
8541 if (state & UpdateConfigurationState)
8544 Initialize button information.
8546 XGetWidgetInfo(CancelButtonText,&cancel_info);
8547 cancel_info.width=width;
8548 cancel_info.height=(unsigned int) (3*height) >> 1;
8549 cancel_info.x=(int) windows->widget.width-cancel_info.width-
8550 (QuantumMargin << 1);
8551 cancel_info.y=(int) windows->widget.height-
8552 cancel_info.height-QuantumMargin;
8553 XGetWidgetInfo(ApplyButtonText,&apply_info);
8554 apply_info.width=width;
8555 apply_info.height=(unsigned int) (3*height) >> 1;
8556 apply_info.x=QuantumMargin << 1;
8557 apply_info.y=cancel_info.y;
8558 y=(int) (height << 1);
8559 for (i=0; i < NumberPreferences; i++)
8561 XGetWidgetInfo(Preferences[i],&preferences_info[i]);
8562 preferences_info[i].bevel_width--;
8563 preferences_info[i].width=(unsigned int) QuantumMargin >> 1;
8564 preferences_info[i].height=(unsigned int) QuantumMargin >> 1;
8565 preferences_info[i].x=QuantumMargin << 1;
8566 preferences_info[i].y=y;
8567 y+=height+(QuantumMargin >> 1);
8569 preferences_info[0].raised=resource_info->backdrop ==
8570 MagickFalse ? MagickTrue : MagickFalse;
8571 preferences_info[1].raised=resource_info->confirm_exit ==
8572 MagickFalse ? MagickTrue : MagickFalse;
8573 preferences_info[2].raised=resource_info->confirm_edit ==
8574 MagickFalse ? MagickTrue : MagickFalse;
8575 preferences_info[3].raised=resource_info->gamma_correct ==
8576 MagickFalse ? MagickTrue : MagickFalse;
8577 preferences_info[4].raised=resource_info->display_warnings ==
8578 MagickFalse ? MagickTrue : MagickFalse;
8579 preferences_info[5].raised=resource_info->quantize_info->dither ==
8580 MagickFalse ? MagickTrue : MagickFalse;
8581 preferences_info[6].raised=resource_info->colormap !=
8582 SharedColormap ? MagickTrue : MagickFalse;
8583 preferences_info[7].raised=resource_info->use_pixmap ==
8584 MagickFalse ? MagickTrue : MagickFalse;
8585 (void) FormatMagickString(cache,MaxTextExtent,CacheButtonText,
8586 (unsigned long) resource_info->undo_cache);
8587 XGetWidgetInfo(cache,&cache_info);
8588 cache_info.bevel_width--;
8589 cache_info.width=(unsigned int) QuantumMargin >> 1;
8590 cache_info.height=(unsigned int) QuantumMargin >> 1;
8591 cache_info.x=QuantumMargin << 1;
8593 state&=(~UpdateConfigurationState);
8595 if (state & RedrawWidgetState)
8598 Redraw Preferences widget.
8600 XDrawBeveledButton(display,&windows->widget,&apply_info);
8601 XDrawBeveledButton(display,&windows->widget,&cancel_info);
8602 for (i=0; i < NumberPreferences; i++)
8603 XDrawBeveledButton(display,&windows->widget,&preferences_info[i]);
8604 XDrawTriangleEast(display,&windows->widget,&cache_info);
8605 XHighlightWidget(display,&windows->widget,BorderOffset,BorderOffset);
8606 state&=(~RedrawWidgetState);
8609 Wait for next event.
8611 (void) XIfEvent(display,&event,XScreenEvent,(char *) windows);
8616 if (MatteIsActive(apply_info,event.xbutton))
8619 User pressed Apply button.
8621 apply_info.raised=MagickFalse;
8622 XDrawBeveledButton(display,&windows->widget,&apply_info);
8625 if (MatteIsActive(cancel_info,event.xbutton))
8628 User pressed Cancel button.
8630 cancel_info.raised=MagickFalse;
8631 XDrawBeveledButton(display,&windows->widget,&cancel_info);
8634 for (i=0; i < NumberPreferences; i++)
8635 if (MatteIsActive(preferences_info[i],event.xbutton))
8638 User pressed a Preferences button.
8640 preferences_info[i].raised=preferences_info[i].raised ==
8641 MagickFalse ? MagickTrue : MagickFalse;
8642 XDrawBeveledButton(display,&windows->widget,&preferences_info[i]);
8645 if (MatteIsActive(cache_info,event.xbutton))
8648 User pressed Cache button.
8650 x=cache_info.x+cache_info.width+cache_info.bevel_width+
8651 (QuantumMargin >> 1);
8652 y=cache_info.y+((cache_info.height-height) >> 1);
8653 width=WidgetTextWidth(font_info,cache);
8654 (void) XClearArea(display,windows->widget.id,x,y,width,height,
8656 resource_info->undo_cache<<=1;
8657 if (resource_info->undo_cache > 256)
8658 resource_info->undo_cache=1;
8659 (void) FormatMagickString(cache,MaxTextExtent,CacheButtonText,
8660 (unsigned long) resource_info->undo_cache);
8661 cache_info.raised=MagickFalse;
8662 XDrawTriangleEast(display,&windows->widget,&cache_info);
8669 if (windows->widget.mapped == MagickFalse)
8671 if (apply_info.raised == MagickFalse)
8673 if (event.xbutton.window == windows->widget.id)
8674 if (MatteIsActive(apply_info,event.xbutton))
8676 apply_info.raised=MagickTrue;
8677 XDrawBeveledButton(display,&windows->widget,&apply_info);
8678 apply_info.raised=MagickFalse;
8680 if (cancel_info.raised == MagickFalse)
8682 if (event.xbutton.window == windows->widget.id)
8683 if (MatteIsActive(cancel_info,event.xbutton))
8685 cancel_info.raised=MagickTrue;
8686 XDrawBeveledButton(display,&windows->widget,&cancel_info);
8688 if (cache_info.raised == MagickFalse)
8690 cache_info.raised=MagickTrue;
8691 XDrawTriangleEast(display,&windows->widget,&cache_info);
8698 If client window delete message, exit.
8700 if (event.xclient.message_type != windows->wm_protocols)
8702 if (*event.xclient.data.l == (int) windows->wm_take_focus)
8704 (void) XSetInputFocus(display,event.xclient.window,RevertToParent,
8705 (Time) event.xclient.data.l[1]);
8708 if (*event.xclient.data.l != (int) windows->wm_delete_window)
8710 if (event.xclient.window == windows->widget.id)
8717 case ConfigureNotify:
8720 Update widget configuration.
8722 if (event.xconfigure.window != windows->widget.id)
8724 if ((event.xconfigure.width == (int) windows->widget.width) &&
8725 (event.xconfigure.height == (int) windows->widget.height))
8727 windows->widget.width=(unsigned int)
8728 MagickMax(event.xconfigure.width,(int) windows->widget.min_width);
8729 windows->widget.height=(unsigned int)
8730 MagickMax(event.xconfigure.height,(int) windows->widget.min_height);
8731 state|=UpdateConfigurationState;
8736 if (event.xcrossing.window != windows->widget.id)
8738 state&=(~InactiveWidgetState);
8743 if (event.xexpose.window != windows->widget.id)
8745 if (event.xexpose.count != 0)
8747 state|=RedrawWidgetState;
8753 command[MaxTextExtent];
8759 Respond to a user key press.
8761 if (event.xkey.window != windows->widget.id)
8763 (void) XLookupString((XKeyEvent *) &event.xkey,command,
8764 (int) sizeof(command),&key_symbol,(XComposeStatus *) NULL);
8765 if ((key_symbol == XK_Return) || (key_symbol == XK_KP_Enter))
8767 apply_info.raised=MagickFalse;
8768 XDrawBeveledButton(display,&windows->widget,&apply_info);
8776 if (event.xcrossing.window != windows->widget.id)
8778 state|=InactiveWidgetState;
8784 Discard pending button motion events.
8786 while (XCheckMaskEvent(display,ButtonMotionMask,&event)) ;
8787 if (state & InactiveWidgetState)
8789 if (apply_info.raised == MatteIsActive(apply_info,event.xmotion))
8792 Apply button status changed.
8795 apply_info.raised == MagickFalse ? MagickTrue : MagickFalse;
8796 XDrawBeveledButton(display,&windows->widget,&apply_info);
8799 if (cancel_info.raised == MatteIsActive(cancel_info,event.xmotion))
8802 Cancel button status changed.
8805 cancel_info.raised == MagickFalse ? MagickTrue : MagickFalse;
8806 XDrawBeveledButton(display,&windows->widget,&cancel_info);
8814 } while ((state & ExitState) == 0);
8815 XSetCursorState(display,windows,MagickFalse);
8816 (void) XWithdrawWindow(display,windows->widget.id,windows->widget.screen);
8817 XCheckRefreshWindows(display,windows);
8818 if (apply_info.raised)
8819 return(MagickFalse);
8821 Save user preferences to the client configuration file.
8823 resource_info->backdrop=
8824 preferences_info[0].raised == MagickFalse ? MagickTrue : MagickFalse;
8825 resource_info->confirm_exit=
8826 preferences_info[1].raised == MagickFalse ? MagickTrue : MagickFalse;
8827 resource_info->confirm_edit=
8828 preferences_info[2].raised == MagickFalse ? MagickTrue : MagickFalse;
8829 resource_info->gamma_correct=
8830 preferences_info[3].raised == MagickFalse ? MagickTrue : MagickFalse;
8831 resource_info->display_warnings=
8832 preferences_info[4].raised == MagickFalse ? MagickTrue : MagickFalse;
8833 resource_info->quantize_info->dither=
8834 preferences_info[5].raised == MagickFalse ? MagickTrue : MagickFalse;
8835 resource_info->colormap=SharedColormap;
8836 if (preferences_info[6].raised)
8837 resource_info->colormap=PrivateColormap;
8838 resource_info->use_pixmap=
8839 preferences_info[7].raised == MagickFalse ? MagickTrue : MagickFalse;
8840 XUserPreferences(resource_info);
8845 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8849 % X P r o g r e s s M o n i t o r W i d g e t %
8853 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8855 % XProgressMonitorWidget() displays the progress a task is making in
8856 % completing a task. A span of zero toggles the active status. An inactive
8857 % state disables the progress monitor.
8859 % The format of the XProgressMonitorWidget method is:
8861 % void XProgressMonitorWidget(Display *display,XWindows *windows,
8862 % const char *task,const MagickOffsetType offset,
8863 % const MagickSizeType span)
8865 % A description of each parameter follows:
8867 % o display: Specifies a connection to an X server; returned from
8870 % o window: Specifies a pointer to a XWindows structure.
8872 % o task: Identifies the task in progress.
8874 % o offset: Specifies the offset position within the span which represents
8875 % how much progress has been made in completing a task.
8877 % o span: Specifies the span relative to completing a task.
8880 MagickExport void XProgressMonitorWidget(Display *display,XWindows *windows,
8881 const char *task,const MagickOffsetType offset,const MagickSizeType span)
8889 assert(display != (Display *) NULL);
8890 assert(windows != (XWindows *) NULL);
8891 assert(task != (const char *) NULL);
8892 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",task);
8896 Update image windows if there is a pending expose event.
8898 while (XCheckTypedWindowEvent(display,windows->command.id,Expose,&event))
8899 (void) XCommandWidget(display,windows,(const char **) NULL,&event);
8900 while (XCheckTypedWindowEvent(display,windows->image.id,Expose,&event))
8901 XRefreshWindow(display,&windows->image,&event);
8902 while (XCheckTypedWindowEvent(display,windows->info.id,Expose,&event))
8903 if (monitor_info.text != (char *) NULL)
8904 XInfoWidget(display,windows,monitor_info.text);
8906 Draw progress monitor bar to represent percent completion of a task.
8908 if ((windows->info.mapped == MagickFalse) || (task != monitor_info.text))
8909 XInfoWidget(display,windows,task);
8910 width=(unsigned int) (((offset+1)*(windows->info.width-
8911 (2*monitor_info.x)))/span);
8912 if (width < monitor_info.width)
8914 monitor_info.raised=MagickTrue;
8915 XDrawWidgetText(display,&windows->info,&monitor_info);
8916 monitor_info.raised=MagickFalse;
8918 monitor_info.width=width;
8919 XDrawWidgetText(display,&windows->info,&monitor_info);
8920 (void) XFlush(display);
8924 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8928 % X T e x t V i e w W i d g e t %
8932 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8934 % XTextViewWidget() displays text in a Text View widget.
8936 % The format of the XTextViewWidget method is:
8938 % void XTextViewWidget(Display *display,const XResourceInfo *resource_info,
8939 % XWindows *windows,const MagickBooleanType mono,const char *title,
8940 % const char **textlist)
8942 % A description of each parameter follows:
8944 % o display: Specifies a connection to an X server; returned from
8947 % o resource_info: Specifies a pointer to a X11 XResourceInfo structure.
8949 % o window: Specifies a pointer to a XWindows structure.
8951 % o mono: Use mono-spaced font when displaying text.
8953 % o title: This character string is displayed at the top of the widget
8956 % o textlist: This string list is displayed within the Text View widget.
8959 MagickExport void XTextViewWidget(Display *display,
8960 const XResourceInfo *resource_info,XWindows *windows,
8961 const MagickBooleanType mono,const char *title,const char **textlist)
8963 #define DismissButtonText "Dismiss"
8966 primary_selection[MaxTextExtent];
8971 static MagickStatusType
8972 mask = (MagickStatusType) (CWWidth | CWHeight | CWX | CWY);
9012 Convert text string to a text list.
9014 assert(display != (Display *) NULL);
9015 assert(resource_info != (XResourceInfo *) NULL);
9016 assert(windows != (XWindows *) NULL);
9017 assert(title != (const char *) NULL);
9018 assert(textlist != (const char **) NULL);
9019 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",title);
9020 XSetCursorState(display,windows,MagickTrue);
9021 XCheckRefreshWindows(display,windows);
9022 if (textlist == (const char **) NULL)
9024 XNoticeWidget(display,windows,"No text to view:",(char *) NULL);
9028 Determine Text View widget attributes.
9030 font_info=windows->widget.font_info;
9031 text_info=(XFontStruct *) NULL;
9032 if (mono != MagickFalse)
9033 text_info=XBestFont(display,resource_info,MagickTrue);
9034 if (text_info == (XFontStruct *) NULL)
9035 text_info=windows->widget.font_info;
9037 for (i=0; textlist[i] != (char *) NULL; i++)
9038 if (WidgetTextWidth(text_info,(char *) textlist[i]) > text_width)
9039 text_width=(unsigned int) XTextWidth(text_info,(char *) textlist[i],
9040 MagickMin(Extent(textlist[i]),160));
9041 lines=(unsigned int) i;
9042 width=WidgetTextWidth(font_info,DismissButtonText);
9043 width+=QuantumMargin;
9044 height=(unsigned int) (text_info->ascent+text_info->descent);
9046 Position Text View widget.
9048 windows->widget.width=(unsigned int) (MagickMin((int) text_width,
9049 (int) MaxTextWidth)+5*QuantumMargin);
9050 windows->widget.min_width=(unsigned int) (MinTextWidth+4*QuantumMargin);
9051 if (windows->widget.width < windows->widget.min_width)
9052 windows->widget.width=windows->widget.min_width;
9053 windows->widget.height=(unsigned int) (MagickMin(MagickMax((int) lines,3),32)*
9054 height+((13*height) >> 1)+((9*QuantumMargin) >> 1));
9055 windows->widget.min_height=(unsigned int) (3*height+((13*height) >> 1)+((9*
9056 QuantumMargin) >> 1));
9057 if (windows->widget.height < windows->widget.min_height)
9058 windows->widget.height=windows->widget.min_height;
9059 XConstrainWindowPosition(display,&windows->widget);
9061 Map Text View widget.
9063 (void) CopyMagickString(windows->widget.name,title,MaxTextExtent);
9064 status=XStringListToTextProperty(&windows->widget.name,1,&window_name);
9065 if (status != False)
9067 XSetWMName(display,windows->widget.id,&window_name);
9068 XSetWMIconName(display,windows->widget.id,&window_name);
9069 (void) XFree((void *) window_name.value);
9071 window_changes.width=(int) windows->widget.width;
9072 window_changes.height=(int) windows->widget.height;
9073 window_changes.x=windows->widget.x;
9074 window_changes.y=windows->widget.y;
9075 (void) XReconfigureWMWindow(display,windows->widget.id,
9076 windows->widget.screen,(unsigned int) mask,&window_changes);
9077 (void) XMapRaised(display,windows->widget.id);
9078 windows->widget.mapped=MagickFalse;
9080 Respond to X events.
9082 XGetWidgetInfo((char *) NULL,&slider_info);
9083 XGetWidgetInfo((char *) NULL,&north_info);
9084 XGetWidgetInfo((char *) NULL,&south_info);
9085 XGetWidgetInfo((char *) NULL,&expose_info);
9087 delay=SuspendTime << 2;
9088 height=(unsigned int) (font_info->ascent+font_info->descent);
9089 state=UpdateConfigurationState;
9092 if (state & UpdateConfigurationState)
9098 Initialize button information.
9100 XGetWidgetInfo(DismissButtonText,&dismiss_info);
9101 dismiss_info.width=width;
9102 dismiss_info.height=(unsigned int) ((3*height) >> 1);
9103 dismiss_info.x=(int) windows->widget.width-dismiss_info.width-
9105 dismiss_info.y=(int) windows->widget.height-dismiss_info.height-
9108 Initialize scroll information.
9110 XGetWidgetInfo((char *) NULL,&scroll_info);
9111 scroll_info.bevel_width--;
9112 scroll_info.width=height;
9113 scroll_info.height=(unsigned int) (dismiss_info.y-((5*QuantumMargin) >>
9115 scroll_info.x=(int) windows->widget.width-QuantumMargin-
9117 scroll_info.y=(3*QuantumMargin) >> 1;
9118 scroll_info.raised=MagickFalse;
9119 scroll_info.trough=MagickTrue;
9120 north_info=scroll_info;
9121 north_info.raised=MagickTrue;
9122 north_info.width-=(north_info.bevel_width << 1);
9123 north_info.height=north_info.width-1;
9124 north_info.x+=north_info.bevel_width;
9125 north_info.y+=north_info.bevel_width;
9126 south_info=north_info;
9127 south_info.y=scroll_info.y+scroll_info.height-scroll_info.bevel_width-
9130 slider_info=north_info;
9132 slider_info.width-=2;
9133 slider_info.min_y=north_info.y+north_info.height+north_info.bevel_width+
9134 slider_info.bevel_width+2;
9135 slider_info.height=scroll_info.height-((slider_info.min_y-
9136 scroll_info.y+1) << 1)+4;
9137 visible_lines=scroll_info.height/(text_info->ascent+text_info->descent+
9138 ((text_info->ascent+text_info->descent) >> 3));
9139 if (lines > visible_lines)
9140 slider_info.height=(unsigned int) (visible_lines*slider_info.height)/
9142 slider_info.max_y=south_info.y-south_info.bevel_width-
9143 slider_info.bevel_width-2;
9144 slider_info.x=scroll_info.x+slider_info.bevel_width+1;
9145 slider_info.y=slider_info.min_y;
9146 expose_info=scroll_info;
9147 expose_info.y=slider_info.y;
9149 Initialize list information.
9151 XGetWidgetInfo((char *) NULL,&list_info);
9152 list_info.raised=MagickFalse;
9153 list_info.bevel_width--;
9154 list_info.width=(unsigned int) scroll_info.x-((3*QuantumMargin) >> 1);
9155 list_info.height=scroll_info.height;
9156 list_info.x=QuantumMargin;
9157 list_info.y=scroll_info.y;
9159 Initialize selection information.
9161 XGetWidgetInfo((char *) NULL,&selection_info);
9162 selection_info.center=MagickFalse;
9163 selection_info.width=list_info.width;
9164 selection_info.height=(unsigned int)
9165 (9*(text_info->ascent+text_info->descent)) >> 3;
9166 selection_info.x=list_info.x;
9167 state&=(~UpdateConfigurationState);
9169 if (state & RedrawWidgetState)
9172 Redraw Text View window.
9174 XDrawBeveledMatte(display,&windows->widget,&list_info);
9175 XDrawBeveledMatte(display,&windows->widget,&scroll_info);
9176 XDrawTriangleNorth(display,&windows->widget,&north_info);
9177 XDrawBeveledButton(display,&windows->widget,&slider_info);
9178 XDrawTriangleSouth(display,&windows->widget,&south_info);
9179 XDrawBeveledButton(display,&windows->widget,&dismiss_info);
9180 XHighlightWidget(display,&windows->widget,BorderOffset,BorderOffset);
9181 selection_info.id=(~0);
9182 state|=RedrawListState;
9183 state&=(~RedrawWidgetState);
9185 if (state & RedrawListState)
9188 Determine slider id and position.
9190 if (slider_info.id >= (int) (lines-visible_lines))
9191 slider_info.id=(int) lines-visible_lines;
9192 if ((slider_info.id < 0) || (lines <= visible_lines))
9194 slider_info.y=slider_info.min_y;
9197 slider_info.id*(slider_info.max_y-slider_info.min_y+1)/lines;
9198 if (slider_info.id != selection_info.id)
9201 Redraw scroll bar and text.
9203 windows->widget.font_info=text_info;
9204 (void) XSetFont(display,windows->widget.annotate_context,
9206 (void) XSetFont(display,windows->widget.highlight_context,
9208 selection_info.id=slider_info.id;
9209 selection_info.y=list_info.y+(height >> 3)+2;
9210 for (i=0; i < (int) visible_lines; i++)
9212 selection_info.raised=
9213 (slider_info.id+i) != list_info.id ? MagickTrue : MagickFalse;
9214 selection_info.text=(char *) NULL;
9215 if ((slider_info.id+i) < (int) lines)
9216 selection_info.text=(char *) textlist[slider_info.id+i];
9217 XDrawWidgetText(display,&windows->widget,&selection_info);
9218 selection_info.y+=(int) selection_info.height;
9220 windows->widget.font_info=font_info;
9221 (void) XSetFont(display,windows->widget.annotate_context,
9223 (void) XSetFont(display,windows->widget.highlight_context,
9228 if (slider_info.y > expose_info.y)
9230 expose_info.height=(unsigned int) slider_info.y-expose_info.y;
9231 expose_info.y=slider_info.y-expose_info.height-
9232 slider_info.bevel_width-1;
9236 expose_info.height=(unsigned int) expose_info.y-slider_info.y;
9237 expose_info.y=slider_info.y+slider_info.height+
9238 slider_info.bevel_width+1;
9240 XDrawTriangleNorth(display,&windows->widget,&north_info);
9241 XDrawMatte(display,&windows->widget,&expose_info);
9242 XDrawBeveledButton(display,&windows->widget,&slider_info);
9243 XDrawTriangleSouth(display,&windows->widget,&south_info);
9244 expose_info.y=slider_info.y;
9246 state&=(~RedrawListState);
9249 Wait for next event.
9251 if (north_info.raised && south_info.raised)
9252 (void) XIfEvent(display,&event,XScreenEvent,(char *) windows);
9256 Brief delay before advancing scroll bar.
9258 XDelay(display,delay);
9260 (void) XCheckIfEvent(display,&event,XScreenEvent,(char *) windows);
9261 if (north_info.raised == MagickFalse)
9262 if (slider_info.id > 0)
9268 state|=RedrawListState;
9270 if (south_info.raised == MagickFalse)
9271 if (slider_info.id < (int) lines)
9277 state|=RedrawListState;
9279 if (event.type != ButtonRelease)
9286 if (MatteIsActive(slider_info,event.xbutton))
9291 slider_info.active=MagickTrue;
9294 if (MatteIsActive(north_info,event.xbutton))
9295 if (slider_info.id > 0)
9300 north_info.raised=MagickFalse;
9302 state|=RedrawListState;
9305 if (MatteIsActive(south_info,event.xbutton))
9306 if (slider_info.id < (int) lines)
9311 south_info.raised=MagickFalse;
9313 state|=RedrawListState;
9316 if (MatteIsActive(scroll_info,event.xbutton))
9321 if (event.xbutton.y < slider_info.y)
9322 slider_info.id-=(visible_lines-1);
9324 slider_info.id+=(visible_lines-1);
9325 state|=RedrawListState;
9328 if (MatteIsActive(dismiss_info,event.xbutton))
9331 User pressed Dismiss button.
9333 dismiss_info.raised=MagickFalse;
9334 XDrawBeveledButton(display,&windows->widget,&dismiss_info);
9337 if (MatteIsActive(list_info,event.xbutton))
9346 User pressed list matte.
9348 id=slider_info.id+(event.xbutton.y-(list_info.y+(height >> 1))+1)/
9349 selection_info.height;
9350 if (id >= (int) lines)
9352 if (id != list_info.id)
9355 click_time=event.xbutton.time;
9359 if (event.xbutton.time >= (click_time+DoubleClick))
9361 click_time=event.xbutton.time;
9364 click_time=event.xbutton.time;
9366 Become the XA_PRIMARY selection owner.
9368 (void) CopyMagickString(primary_selection,textlist[list_info.id],
9370 (void) XSetSelectionOwner(display,XA_PRIMARY,windows->widget.id,
9371 event.xbutton.time);
9372 if (XGetSelectionOwner(display,XA_PRIMARY) != windows->widget.id)
9374 selection_info.id=(~0);
9376 state|=RedrawListState;
9383 if (windows->widget.mapped == MagickFalse)
9385 if (north_info.raised == MagickFalse)
9388 User released up button.
9390 delay=SuspendTime << 2;
9391 north_info.raised=MagickTrue;
9392 XDrawTriangleNorth(display,&windows->widget,&north_info);
9394 if (south_info.raised == MagickFalse)
9397 User released down button.
9399 delay=SuspendTime << 2;
9400 south_info.raised=MagickTrue;
9401 XDrawTriangleSouth(display,&windows->widget,&south_info);
9403 if (slider_info.active)
9406 Stop tracking slider.
9408 slider_info.active=MagickFalse;
9411 if (dismiss_info.raised == MagickFalse)
9413 if (event.xbutton.window == windows->widget.id)
9414 if (MatteIsActive(dismiss_info,event.xbutton))
9416 dismiss_info.raised=MagickTrue;
9417 XDrawBeveledButton(display,&windows->widget,&dismiss_info);
9424 If client window delete message, exit.
9426 if (event.xclient.message_type != windows->wm_protocols)
9428 if (*event.xclient.data.l == (int) windows->wm_take_focus)
9430 (void) XSetInputFocus(display,event.xclient.window,RevertToParent,
9431 (Time) event.xclient.data.l[1]);
9434 if (*event.xclient.data.l != (int) windows->wm_delete_window)
9436 if (event.xclient.window == windows->widget.id)
9443 case ConfigureNotify:
9446 Update widget configuration.
9448 if (event.xconfigure.window != windows->widget.id)
9450 if ((event.xconfigure.width == (int) windows->widget.width) &&
9451 (event.xconfigure.height == (int) windows->widget.height))
9453 windows->widget.width=(unsigned int)
9454 MagickMax(event.xconfigure.width,(int) windows->widget.min_width);
9455 windows->widget.height=(unsigned int)
9456 MagickMax(event.xconfigure.height,(int) windows->widget.min_height);
9457 state|=UpdateConfigurationState;
9462 if (event.xcrossing.window != windows->widget.id)
9464 state&=(~InactiveWidgetState);
9469 if (event.xexpose.window != windows->widget.id)
9471 if (event.xexpose.count != 0)
9473 state|=RedrawWidgetState;
9479 command[MaxTextExtent];
9488 Respond to a user key press.
9490 if (event.xkey.window != windows->widget.id)
9492 length=XLookupString((XKeyEvent *) &event.xkey,command,
9493 (int) sizeof(command),&key_symbol,(XComposeStatus *) NULL);
9494 *(command+length)='\0';
9495 if ((key_symbol == XK_Return) || (key_symbol == XK_KP_Enter))
9497 dismiss_info.raised=MagickFalse;
9498 XDrawBeveledButton(display,&windows->widget,&dismiss_info);
9502 if (AreaIsActive(scroll_info,event.xkey))
9507 switch ((int) key_symbol)
9530 slider_info.id-=visible_lines;
9536 slider_info.id+=visible_lines;
9542 slider_info.id=(int) lines;
9546 state|=RedrawListState;
9555 if (event.xcrossing.window != windows->widget.id)
9557 state|=InactiveWidgetState;
9569 Discard pending button motion events.
9571 while (XCheckMaskEvent(display,ButtonMotionMask,&event)) ;
9572 if (slider_info.active)
9577 slider_info.y=event.xmotion.y-
9578 ((slider_info.height+slider_info.bevel_width) >> 1)+1;
9579 if (slider_info.y < slider_info.min_y)
9580 slider_info.y=slider_info.min_y;
9581 if (slider_info.y > slider_info.max_y)
9582 slider_info.y=slider_info.max_y;
9584 if (slider_info.y != slider_info.min_y)
9585 slider_info.id=(int) (lines*(slider_info.y-slider_info.min_y+1))/
9586 (slider_info.max_y-slider_info.min_y+1);
9587 state|=RedrawListState;
9590 if (state & InactiveWidgetState)
9592 if (dismiss_info.raised == MatteIsActive(dismiss_info,event.xmotion))
9595 Dismiss button status changed.
9597 dismiss_info.raised=
9598 dismiss_info.raised == MagickFalse ? MagickTrue : MagickFalse;
9599 XDrawBeveledButton(display,&windows->widget,&dismiss_info);
9604 case SelectionClear:
9607 selection_info.id=(~0);
9608 state|=RedrawListState;
9611 case SelectionRequest:
9616 XSelectionRequestEvent
9619 if (list_info.id == (~0))
9622 Set primary selection.
9624 request=(&(event.xselectionrequest));
9625 (void) XChangeProperty(request->display,request->requestor,
9626 request->property,request->target,8,PropModeReplace,
9627 (unsigned char *) primary_selection,Extent(primary_selection));
9628 notify.type=SelectionNotify;
9629 notify.send_event=MagickTrue;
9630 notify.display=request->display;
9631 notify.requestor=request->requestor;
9632 notify.selection=request->selection;
9633 notify.target=request->target;
9634 notify.time=request->time;
9635 if (request->property == None)
9636 notify.property=request->target;
9638 notify.property=request->property;
9639 (void) XSendEvent(request->display,request->requestor,False,NoEventMask,
9640 (XEvent *) ¬ify);
9645 } while ((state & ExitState) == 0);
9646 if (text_info != windows->widget.font_info)
9647 (void) XFreeFont(display,text_info);
9648 XSetCursorState(display,windows,MagickFalse);
9649 (void) XWithdrawWindow(display,windows->widget.id,windows->widget.screen);
9650 XCheckRefreshWindows(display,windows);