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/string_.h"
52 #include "magick/timer-private.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)
59 DisableMSCWarning(4389)
60 DisableMSCWarning(4701)
65 #define AreaIsActive(matte_info,position) ( \
66 ((position.y >= (int) (matte_info.y-matte_info.bevel_width)) && \
67 (position.y < (int) (matte_info.y+matte_info.height+matte_info.bevel_width))) \
68 ? MagickTrue : MagickFalse)
69 #define Extent(s) ((int) strlen(s))
70 #define MatteIsActive(matte_info,position) ( \
71 ((position.x >= (int) (matte_info.x-matte_info.bevel_width)) && \
72 (position.y >= (int) (matte_info.y-matte_info.bevel_width)) && \
73 (position.x < (int) (matte_info.x+matte_info.width+matte_info.bevel_width)) && \
74 (position.y < (int) (matte_info.y+matte_info.height+matte_info.bevel_width))) \
75 ? MagickTrue : MagickFalse)
76 #define MaxTextWidth ((unsigned int) (255*XTextWidth(font_info,"_",1)))
77 #define MinTextWidth (26*XTextWidth(font_info,"_",1))
78 #define QuantumMargin MagickMax(font_info->max_bounds.width,12)
79 #define WidgetTextWidth(font_info,text) \
80 ((unsigned int) XTextWidth(font_info,text,Extent(text)))
81 #define WindowIsActive(window_info,position) ( \
82 ((position.x >= 0) && (position.y >= 0) && \
83 (position.x < (int) window_info.width) && \
84 (position.y < (int) window_info.height)) ? MagickTrue : MagickFalse)
91 ControlState = 0x0001,
92 InactiveWidgetState = 0x0004,
93 JumpListState = 0x0008,
94 RedrawActionState = 0x0010,
95 RedrawListState = 0x0020,
96 RedrawWidgetState = 0x0040,
97 UpdateListState = 0x0100
103 typedef struct _XWidgetInfo
138 (
char *) NULL, (
char *) NULL, (
char *) NULL, 0, 0, 0, 0, 0, 0, 0, 0,
139 MagickFalse, MagickFalse, MagickFalse, MagickFalse, MagickFalse
143 (
char *) NULL, (
char *) NULL, (
char *) NULL, 0, 0, 0, 0, 0, 0, 0, 0,
144 MagickFalse, MagickFalse, MagickFalse, MagickFalse, MagickFalse
146 *selection_info = (XWidgetInfo *) NULL,
149 (
char *) NULL, (
char *) NULL, (
char *) NULL, 0, 0, 0, 0, 0, 0, 0, 0,
150 MagickFalse, MagickFalse, MagickFalse, MagickFalse, MagickFalse
164 XDrawMatte(Display *,
const XWindowInfo *,
const XWidgetInfo *),
165 XSetBevelColor(Display *,
const XWindowInfo *,
const MagickStatusType),
166 XSetMatteColor(Display *,
const XWindowInfo *,
const MagickStatusType),
167 XSetTextColor(Display *,
const XWindowInfo *,
const MagickStatusType);
189 MagickExport
void DestroyXWidget(
void)
191 if (selection_info != (XWidgetInfo *) NULL)
192 selection_info=(XWidgetInfo *) RelinquishMagickMemory(selection_info);
225 static void XDrawBevel(Display *display,
const XWindowInfo *window_info,
226 const XWidgetInfo *bevel_info)
244 y1=bevel_info->y+bevel_info->height;
245 x2=bevel_info->x+bevel_info->width;
247 bevel_width=bevel_info->bevel_width;
254 points[3].x=x2+bevel_width;
255 points[3].y=y2-bevel_width;
256 points[4].x=x1-bevel_width;
257 points[4].y=y2-bevel_width;
258 points[5].x=x1-bevel_width;
259 points[5].y=y1+bevel_width;
260 XSetBevelColor(display,window_info,bevel_info->raised);
261 (void) XFillPolygon(display,window_info->id,window_info->widget_context,
262 points,6,Complex,CoordModeOrigin);
272 points[3].x=x2+bevel_width;
273 points[3].y=y2-bevel_width;
274 points[4].x=x2+bevel_width;
275 points[4].y=y1+bevel_width;
276 points[5].x=x1-bevel_width;
277 points[5].y=y1+bevel_width;
278 XSetBevelColor(display,window_info,!bevel_info->raised);
279 (void) XFillPolygon(display,window_info->id,window_info->widget_context,
280 points,6,Complex,CoordModeOrigin);
281 (void) XSetFillStyle(display,window_info->widget_context,FillSolid);
314 static void XDrawBeveledButton(Display *display,
const XWindowInfo *window_info,
315 const XWidgetInfo *button_info)
333 XDrawBevel(display,window_info,button_info);
334 XSetMatteColor(display,window_info,button_info->raised);
335 (void) XFillRectangle(display,window_info->id,window_info->widget_context,
336 button_info->x,button_info->y,button_info->width,button_info->height);
337 x=button_info->x-button_info->bevel_width-1;
338 y=button_info->y-button_info->bevel_width-1;
339 (void) XSetForeground(display,window_info->widget_context,
340 window_info->pixel_info->trough_color.pixel);
341 if (button_info->raised || (window_info->depth == 1))
342 (
void) XDrawRectangle(display,window_info->id,window_info->widget_context,
343 x,y,button_info->width+(button_info->bevel_width << 1)+1,
344 button_info->height+(button_info->bevel_width << 1)+1);
345 if (button_info->text == (
char *) NULL)
350 crop_info.width=(
unsigned short) button_info->width;
351 crop_info.height=(
unsigned short) button_info->height;
352 crop_info.x=button_info->x;
353 crop_info.y=button_info->y;
357 font_info=window_info->font_info;
358 width=WidgetTextWidth(font_info,button_info->text);
359 x=button_info->x+(QuantumMargin >> 1);
360 if (button_info->center)
361 x=button_info->x+(button_info->width >> 1)-(width >> 1);
362 y=button_info->y+((button_info->height-
363 (font_info->ascent+font_info->descent)) >> 1)+font_info->ascent;
364 if ((
int) button_info->width == (QuantumMargin >> 1))
369 XSetTextColor(display,window_info,MagickTrue);
370 x=button_info->x+button_info->width+button_info->bevel_width+
371 (QuantumMargin >> 1);
372 (void) XDrawString(display,window_info->id,window_info->widget_context,
373 x,y,button_info->text,Extent(button_info->text));
376 (void) XSetClipRectangles(display,window_info->widget_context,0,0,&crop_info,
378 XSetTextColor(display,window_info,button_info->raised);
379 (void) XDrawString(display,window_info->id,window_info->widget_context,x,y,
380 button_info->text,Extent(button_info->text));
381 (void) XSetClipMask(display,window_info->widget_context,None);
382 if (button_info->raised == MagickFalse)
383 XDelay(display,SuspendTime << 2);
416 static void XDrawBeveledMatte(Display *display,
const XWindowInfo *window_info,
417 const XWidgetInfo *matte_info)
422 XDrawBevel(display,window_info,matte_info);
423 XDrawMatte(display,window_info,matte_info);
454 static void XDrawMatte(Display *display,
const XWindowInfo *window_info,
455 const XWidgetInfo *matte_info)
460 if ((matte_info->trough == MagickFalse) || (window_info->depth == 1))
461 (void) XFillRectangle(display,window_info->id,
462 window_info->highlight_context,matte_info->x,matte_info->y,
463 matte_info->width,matte_info->height);
466 (void) XSetForeground(display,window_info->widget_context,
467 window_info->pixel_info->trough_color.pixel);
468 (void) XFillRectangle(display,window_info->id,window_info->widget_context,
469 matte_info->x,matte_info->y,matte_info->width,matte_info->height);
502 static void XDrawMatteText(Display *display,
const XWindowInfo *window_info,
503 XWidgetInfo *text_info)
529 XSetMatteColor(display,window_info,MagickFalse);
530 (void) XFillRectangle(display,window_info->id,window_info->widget_context,
531 text_info->x,text_info->y,text_info->width,text_info->height);
532 if (text_info->text == (
char *) NULL)
534 XSetTextColor(display,window_info,text_info->highlight);
535 font_info=window_info->font_info;
536 x=text_info->x+(QuantumMargin >> 2);
537 y=text_info->y+font_info->ascent+(text_info->height >> 2);
538 width=text_info->width-(QuantumMargin >> 1);
539 height=(
unsigned int) (font_info->ascent+font_info->descent);
540 if (*text_info->text ==
'\0')
545 (void) XDrawLine(display,window_info->id,window_info->annotate_context,
552 crop_info.width=(
unsigned short) text_info->width;
553 crop_info.height=(
unsigned short) text_info->height;
554 crop_info.x=text_info->x;
555 crop_info.y=text_info->y;
559 if (text_info->cursor < text_info->marker)
560 text_info->marker=text_info->cursor;
563 text=text_info->marker;
564 if (XTextWidth(font_info,(
char *) text,(int) (text_info->cursor-text)) >
567 text=text_info->text;
568 for (i=0; i < Extent(text); i++)
570 n=XTextWidth(font_info,(
char *) text+i,(
int)
571 (text_info->cursor-text-i));
572 if (n <= (
int) width)
575 text_info->marker=(
char *) text+i;
581 if (text_info->highlight == MagickFalse)
583 (void) XSetClipRectangles(display,window_info->widget_context,0,0,
584 &crop_info,1,Unsorted);
585 (void) XDrawString(display,window_info->id,window_info->widget_context,
586 x,y,text_info->marker,Extent(text_info->marker));
587 (void) XSetClipMask(display,window_info->widget_context,None);
591 (void) XSetClipRectangles(display,window_info->annotate_context,0,0,
592 &crop_info,1,Unsorted);
593 width=WidgetTextWidth(font_info,text_info->marker);
594 (void) XFillRectangle(display,window_info->id,
595 window_info->annotate_context,x,y-font_info->ascent,width,height);
596 (void) XSetClipMask(display,window_info->annotate_context,None);
597 (void) XSetClipRectangles(display,window_info->highlight_context,0,0,
598 &crop_info,1,Unsorted);
599 (void) XDrawString(display,window_info->id,
600 window_info->highlight_context,x,y,text_info->marker,
601 Extent(text_info->marker));
602 (void) XSetClipMask(display,window_info->highlight_context,None);
604 x+=XTextWidth(font_info,text_info->marker,(
int)
605 (text_info->cursor-text_info->marker));
606 (void) XDrawLine(display,window_info->id,window_info->annotate_context,x,y+3,
640 static void XDrawTriangleEast(Display *display,
const XWindowInfo *window_info,
641 const XWidgetInfo *triangle_info)
665 x2=triangle_info->x+triangle_info->width;
666 y2=triangle_info->y+(triangle_info->height >> 1);
668 y3=triangle_info->y+triangle_info->height;
669 bevel_width=triangle_info->bevel_width;
676 XSetMatteColor(display,window_info,triangle_info->raised);
677 (void) XFillPolygon(display,window_info->id,window_info->widget_context,
678 points,3,Complex,CoordModeOrigin);
686 points[2].x=x3-bevel_width;
687 points[2].y=y3+bevel_width;
688 points[3].x=x2+bevel_width;
690 XSetBevelColor(display,window_info,!triangle_info->raised);
691 (void) XFillPolygon(display,window_info->id,window_info->widget_context,
692 points,4,Complex,CoordModeOrigin);
700 points[2].x=x1-bevel_width+1;
701 points[2].y=y1-bevel_width;
702 points[3].x=x3-bevel_width+1;
703 points[3].y=y3+bevel_width;
704 XSetBevelColor(display,window_info,triangle_info->raised);
705 (void) XFillPolygon(display,window_info->id,window_info->widget_context,
706 points,4,Complex,CoordModeOrigin);
714 points[2].x=x2+bevel_width;
716 points[3].x=x1-bevel_width;
717 points[3].y=y1-bevel_width;
718 (void) XFillPolygon(display,window_info->id,window_info->widget_context,
719 points,4,Complex,CoordModeOrigin);
720 (void) XSetFillStyle(display,window_info->widget_context,FillSolid);
721 if (triangle_info->text == (
char *) NULL)
726 font_info=window_info->font_info;
727 XSetTextColor(display,window_info,MagickTrue);
728 x1=triangle_info->x+triangle_info->width+triangle_info->bevel_width+
729 (QuantumMargin >> 1);
730 y1=triangle_info->y+((triangle_info->height-
731 (font_info->ascent+font_info->descent)) >> 1)+font_info->ascent;
732 (
void) XDrawString(display,window_info->id,window_info->widget_context,x1,y1,
733 triangle_info->text,Extent(triangle_info->text));
766 static void XDrawTriangleNorth(Display *display,
const XWindowInfo *window_info,
767 const XWidgetInfo *triangle_info)
787 y1=triangle_info->y+triangle_info->height;
788 x2=triangle_info->x+(triangle_info->width >> 1);
790 x3=triangle_info->x+triangle_info->width;
791 y3=triangle_info->y+triangle_info->height;
792 bevel_width=triangle_info->bevel_width;
799 XSetMatteColor(display,window_info,triangle_info->raised);
800 (void) XFillPolygon(display,window_info->id,window_info->widget_context,
801 points,3,Complex,CoordModeOrigin);
810 points[2].y=y2-bevel_width-2;
811 points[3].x=x1-bevel_width-1;
812 points[3].y=y1+bevel_width;
813 XSetBevelColor(display,window_info,triangle_info->raised);
814 (void) XFillPolygon(display,window_info->id,window_info->widget_context,
815 points,4,Complex,CoordModeOrigin);
823 points[2].x=x3+bevel_width;
824 points[2].y=y3+bevel_width;
826 points[3].y=y2-bevel_width;
827 XSetBevelColor(display,window_info,!triangle_info->raised);
828 (void) XFillPolygon(display,window_info->id,window_info->widget_context,
829 points,4,Complex,CoordModeOrigin);
837 points[2].x=x1-bevel_width;
838 points[2].y=y1+bevel_width;
839 points[3].x=x3+bevel_width;
840 points[3].y=y3+bevel_width;
841 (void) XFillPolygon(display,window_info->id,window_info->widget_context,
842 points,4,Complex,CoordModeOrigin);
843 (void) XSetFillStyle(display,window_info->widget_context,FillSolid);
876 static void XDrawTriangleSouth(Display *display,
const XWindowInfo *window_info,
877 const XWidgetInfo *triangle_info)
898 x2=triangle_info->x+(triangle_info->width >> 1);
899 y2=triangle_info->y+triangle_info->height;
900 x3=triangle_info->x+triangle_info->width;
902 bevel_width=triangle_info->bevel_width;
909 XSetMatteColor(display,window_info,triangle_info->raised);
910 (void) XFillPolygon(display,window_info->id,window_info->widget_context,
911 points,3,Complex,CoordModeOrigin);
919 points[2].x=x1-bevel_width;
920 points[2].y=y1-bevel_width;
921 points[3].x=x3+bevel_width;
922 points[3].y=y3-bevel_width;
923 XSetBevelColor(display,window_info,triangle_info->raised);
924 (void) XFillPolygon(display,window_info->id,window_info->widget_context,
925 points,4,Complex,CoordModeOrigin);
932 points[1].y=y3-bevel_width;
933 points[2].x=x3+bevel_width;
934 points[2].y=y3-bevel_width;
936 points[3].y=y2+bevel_width;
937 XSetBevelColor(display,window_info,!triangle_info->raised);
938 (void) XFillPolygon(display,window_info->id,window_info->widget_context,
939 points,4,Complex,CoordModeOrigin);
948 points[2].y=y2+bevel_width;
949 points[3].x=x1-bevel_width;
950 points[3].y=y1-bevel_width;
951 XSetBevelColor(display,window_info,triangle_info->raised);
952 (void) XFillPolygon(display,window_info->id,window_info->widget_context,
953 points,4,Complex,CoordModeOrigin);
954 (void) XSetFillStyle(display,window_info->widget_context,FillSolid);
985 static void XDrawWidgetText(Display *display,
const XWindowInfo *window_info,
986 XWidgetInfo *text_info)
1008 widget_context=window_info->annotate_context;
1009 if (text_info->raised)
1010 (void) XClearArea(display,window_info->id,text_info->x,text_info->y,
1011 text_info->width,text_info->height,MagickFalse);
1014 (void) XFillRectangle(display,window_info->id,widget_context,text_info->x,
1015 text_info->y,text_info->width,text_info->height);
1016 widget_context=window_info->highlight_context;
1018 if (text_info->text == (
char *) NULL)
1020 if (*text_info->text ==
'\0')
1025 font_info=window_info->font_info;
1026 crop_info.width=(
unsigned short) text_info->width;
1027 crop_info.height=(
unsigned short) text_info->height;
1028 crop_info.x=text_info->x;
1029 crop_info.y=text_info->y;
1033 width=WidgetTextWidth(font_info,text_info->text);
1034 x=text_info->x+(QuantumMargin >> 1);
1035 if (text_info->center)
1036 x=text_info->x+(text_info->width >> 1)-(width >> 1);
1037 if (text_info->raised)
1038 if (width > (text_info->width-QuantumMargin))
1039 x+=(text_info->width-QuantumMargin-width);
1040 height=(
unsigned int) (font_info->ascent+font_info->descent);
1041 y=text_info->y+((text_info->height-height) >> 1)+font_info->ascent;
1042 (void) XSetClipRectangles(display,widget_context,0,0,&crop_info,1,Unsorted);
1043 (void) XDrawString(display,window_info->id,widget_context,x,y,text_info->text,
1044 Extent(text_info->text));
1045 (void) XSetClipMask(display,widget_context,None);
1046 if (x < text_info->x)
1047 (void) XDrawLine(display,window_info->id,window_info->annotate_context,
1048 text_info->x,text_info->y,text_info->x,text_info->y+text_info->height-1);
1085 static void XEditText(Display *display,XWidgetInfo *text_info,
1086 const KeySym key_symbol,
char *text,
const size_t state)
1088 switch ((
int) key_symbol)
1093 if (text_info->highlight)
1098 *text_info->text=
'\0';
1099 text_info->cursor=text_info->text;
1100 text_info->marker=text_info->text;
1101 text_info->highlight=MagickFalse;
1106 if (text_info->cursor != text_info->text)
1108 text_info->cursor--;
1109 (void) memmove(text_info->cursor,text_info->cursor+1,
1110 strlen(text_info->cursor+1)+1);
1111 text_info->highlight=MagickFalse;
1122 if (text_info->cursor == text_info->text)
1124 text_info->cursor--;
1133 if (text_info->cursor == (text_info->text+Extent(text_info->text)))
1135 text_info->cursor++;
1147 if (state & ControlState)
1151 if ((Extent(text_info->text)+1) >= (int) MaxTextExtent)
1152 (void) XBell(display,0);
1155 if (text_info->highlight)
1160 *text_info->text=
'\0';
1161 text_info->cursor=text_info->text;
1162 text_info->marker=text_info->text;
1163 text_info->highlight=MagickFalse;
1168 q=text_info->text+Extent(text_info->text)+strlen(text);
1169 for (i=0; i <= Extent(text_info->cursor); i++)
1171 *q=(*(q-Extent(text)));
1175 for (i=0; i < Extent(text); i++)
1176 *text_info->cursor++=(*p++);
1207 static void XGetWidgetInfo(
const char *text,XWidgetInfo *widget_info)
1212 widget_info->id=(~0);
1213 widget_info->bevel_width=3;
1214 widget_info->width=1;
1215 widget_info->height=1;
1218 widget_info->min_y=0;
1219 widget_info->max_y=0;
1220 widget_info->raised=MagickTrue;
1221 widget_info->active=MagickFalse;
1222 widget_info->center=MagickTrue;
1223 widget_info->trough=MagickFalse;
1224 widget_info->highlight=MagickFalse;
1225 widget_info->text=(
char *) text;
1226 widget_info->cursor=(
char *) text;
1227 if (text != (
char *) NULL)
1228 widget_info->cursor+=Extent(text);
1229 widget_info->marker=(
char *) text;
1263 static void XHighlightWidget(Display *display,
const XWindowInfo *window_info,
1264 const int x,
const int y)
1269 XSetBevelColor(display,window_info,MagickTrue);
1270 (void) XDrawRectangle(display,window_info->id,window_info->widget_context,x,y,
1271 window_info->width-(x << 1),window_info->height-(y << 1));
1272 (void) XDrawRectangle(display,window_info->id,window_info->widget_context,
1273 x-1,y-1,window_info->width-(x << 1)+1,window_info->height-(y << 1)+1);
1274 XSetBevelColor(display,window_info,MagickFalse);
1275 (void) XDrawRectangle(display,window_info->id,window_info->widget_context,
1276 x-1,y-1,window_info->width-(x << 1),window_info->height-(y << 1));
1277 (void) XSetFillStyle(display,window_info->widget_context,FillSolid);
1309 #if defined(__cplusplus) || defined(c_plusplus)
1313 static int XScreenEvent(Display *display,XEvent *event,
char *data)
1318 windows=(XWindows *) data;
1319 if (event->xany.window == windows->popup.id)
1321 if (event->type == MapNotify)
1322 windows->popup.mapped=MagickTrue;
1323 if (event->type == UnmapNotify)
1324 windows->popup.mapped=MagickFalse;
1327 if (event->xany.window == windows->widget.id)
1329 if (event->type == MapNotify)
1330 windows->widget.mapped=MagickTrue;
1331 if (event->type == UnmapNotify)
1332 windows->widget.mapped=MagickFalse;
1335 switch (event->type)
1339 if ((event->xbutton.button == Button3) &&
1340 (
event->xbutton.state & Mod1Mask))
1345 event->xbutton.button=Button2;
1346 event->xbutton.state&=(~Mod1Mask);
1352 if (event->xexpose.window == windows->image.id)
1354 XRefreshWindow(display,&windows->image,event);
1357 if (event->xexpose.window == windows->magnify.id)
1358 if (event->xexpose.count == 0)
1359 if (windows->magnify.mapped)
1361 XMakeMagnifyImage(display,windows);
1364 if (event->xexpose.window == windows->command.id)
1365 if (event->xexpose.count == 0)
1367 (void) XCommandWidget(display,windows,(
const char *
const *) NULL,
1378 if (event->xfocus.window == windows->image.id)
1379 (void) XSetInputFocus(display,windows->image.id,RevertToNone,
1387 case SelectionNotify:
1392 return(MagickFalse);
1395 #if defined(__cplusplus) || defined(c_plusplus)
1427 static void XSetBevelColor(Display *display,
const XWindowInfo *window_info,
1428 const MagickStatusType raised)
1430 if (window_info->depth == 1)
1438 (void) XSetBackground(display,window_info->widget_context,
1439 XBlackPixel(display,window_info->screen));
1440 (void) XSetForeground(display,window_info->widget_context,
1441 XWhitePixel(display,window_info->screen));
1442 (void) XSetFillStyle(display,window_info->widget_context,
1443 FillOpaqueStippled);
1444 stipple=window_info->highlight_stipple;
1445 if (raised == MagickFalse)
1446 stipple=window_info->shadow_stipple;
1447 (void) XSetStipple(display,window_info->widget_context,stipple);
1451 (void) XSetForeground(display,window_info->widget_context,
1452 window_info->pixel_info->highlight_color.pixel);
1454 (
void) XSetForeground(display,window_info->widget_context,
1455 window_info->pixel_info->shadow_color.pixel);
1485 static void XSetMatteColor(Display *display,
const XWindowInfo *window_info,
1486 const MagickStatusType raised)
1488 if (window_info->depth == 1)
1494 (void) XSetForeground(display,window_info->widget_context,
1495 XWhitePixel(display,window_info->screen));
1497 (
void) XSetForeground(display,window_info->widget_context,
1498 XBlackPixel(display,window_info->screen));
1502 (void) XSetForeground(display,window_info->widget_context,
1503 window_info->pixel_info->matte_color.pixel);
1505 (
void) XSetForeground(display,window_info->widget_context,
1506 window_info->pixel_info->depth_color.pixel);
1537 static void XSetTextColor(Display *display,
const XWindowInfo *window_info,
1538 const MagickStatusType raised)
1544 if (window_info->depth == 1)
1550 (void) XSetForeground(display,window_info->widget_context,
1551 XBlackPixel(display,window_info->screen));
1553 (
void) XSetForeground(display,window_info->widget_context,
1554 XWhitePixel(display,window_info->screen));
1557 foreground=(ssize_t) XPixelIntensity(
1558 &window_info->pixel_info->foreground_color);
1559 matte=(ssize_t) XPixelIntensity(&window_info->pixel_info->matte_color);
1560 if (MagickAbsoluteValue((
int) (foreground-matte)) > (65535L >> 3))
1561 (void) XSetForeground(display,window_info->widget_context,
1562 window_info->pixel_info->foreground_color.pixel);
1564 (
void) XSetForeground(display,window_info->widget_context,
1565 window_info->pixel_info->background_color.pixel);
1600 MagickExport
void XColorBrowserWidget(Display *display,XWindows *windows,
1601 const char *action,
char *reply)
1603 #define CancelButtonText "Cancel"
1604 #define ColornameText "Name:"
1605 #define ColorPatternText "Pattern:"
1606 #define GrabButtonText "Grab"
1607 #define ResetButtonText "Reset"
1611 primary_selection[MaxTextExtent] =
"",
1612 reset_pattern[MaxTextExtent],
1613 text[MaxTextExtent];
1626 glob_pattern[MaxTextExtent] =
"*";
1628 static MagickStatusType
1629 mask = (MagickStatusType) (CWWidth | CWHeight | CWX | CWY);
1679 assert(display != (Display *) NULL);
1680 assert(windows != (XWindows *) NULL);
1681 assert(action != (
char *) NULL);
1682 assert(reply != (
char *) NULL);
1683 if (IsEventLogging() != MagickFalse)
1684 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",action);
1685 XSetCursorState(display,windows,MagickTrue);
1686 XCheckRefreshWindows(display,windows);
1687 (void) CopyMagickString(reset_pattern,
"*",MaxTextExtent);
1688 exception=AcquireExceptionInfo();
1689 colorlist=GetColorList(glob_pattern,&colors,exception);
1690 if (colorlist == (
char **) NULL)
1695 (void) CopyMagickString(glob_pattern,
"*",MaxTextExtent);
1696 colorlist=GetColorList(glob_pattern,&colors,exception);
1697 if (colorlist == (
char **) NULL)
1699 XNoticeWidget(display,windows,
"Unable to obtain colors names:",
1701 (void) XDialogWidget(display,windows,action,
"Enter color name:",
1709 font_info=windows->widget.font_info;
1711 for (i=0; i < (int) colors; i++)
1712 if (WidgetTextWidth(font_info,colorlist[i]) > text_width)
1713 text_width=WidgetTextWidth(font_info,colorlist[i]);
1714 width=WidgetTextWidth(font_info,(
char *) action);
1715 if (WidgetTextWidth(font_info,CancelButtonText) > width)
1716 width=WidgetTextWidth(font_info,CancelButtonText);
1717 if (WidgetTextWidth(font_info,ResetButtonText) > width)
1718 width=WidgetTextWidth(font_info,ResetButtonText);
1719 if (WidgetTextWidth(font_info,GrabButtonText) > width)
1720 width=WidgetTextWidth(font_info,GrabButtonText);
1721 width+=QuantumMargin;
1722 if (WidgetTextWidth(font_info,ColorPatternText) > width)
1723 width=WidgetTextWidth(font_info,ColorPatternText);
1724 if (WidgetTextWidth(font_info,ColornameText) > width)
1725 width=WidgetTextWidth(font_info,ColornameText);
1726 height=(
unsigned int) (font_info->ascent+font_info->descent);
1730 windows->widget.width=(
unsigned int)
1731 (width+MagickMin((
int) text_width,(int) MaxTextWidth)+6*QuantumMargin);
1732 windows->widget.min_width=(
unsigned int)
1733 (width+MinTextWidth+4*QuantumMargin);
1734 if (windows->widget.width < windows->widget.min_width)
1735 windows->widget.width=windows->widget.min_width;
1736 windows->widget.height=(
unsigned int)
1737 ((81*height) >> 2)+((13*QuantumMargin) >> 1)+4;
1738 windows->widget.min_height=(
unsigned int)
1739 (((23*height) >> 1)+((13*QuantumMargin) >> 1)+4);
1740 if (windows->widget.height < windows->widget.min_height)
1741 windows->widget.height=windows->widget.min_height;
1742 XConstrainWindowPosition(display,&windows->widget);
1746 (void) CopyMagickString(windows->widget.name,
"Browse and Select a Color",
1748 status=XStringListToTextProperty(&windows->widget.name,1,&window_name);
1749 if (status != False)
1751 XSetWMName(display,windows->widget.id,&window_name);
1752 XSetWMIconName(display,windows->widget.id,&window_name);
1753 (void) XFree((
void *) window_name.value);
1755 window_changes.width=(int) windows->widget.width;
1756 window_changes.height=(
int) windows->widget.height;
1757 window_changes.x=windows->widget.x;
1758 window_changes.y=windows->widget.y;
1759 (void) XReconfigureWMWindow(display,windows->widget.id,windows->widget.screen,
1760 mask,&window_changes);
1761 (void) XMapRaised(display,windows->widget.id);
1762 windows->widget.mapped=MagickFalse;
1766 XGetWidgetInfo((
char *) NULL,&mode_info);
1767 XGetWidgetInfo((
char *) NULL,&slider_info);
1768 XGetWidgetInfo((
char *) NULL,&north_info);
1769 XGetWidgetInfo((
char *) NULL,&south_info);
1770 XGetWidgetInfo((
char *) NULL,&expose_info);
1771 XGetWidgetInfo((
char *) NULL,&selection_info);
1773 delay=SuspendTime << 2;
1774 state=UpdateConfigurationState;
1777 if (state & UpdateConfigurationState)
1785 XGetWidgetInfo(CancelButtonText,&cancel_info);
1786 cancel_info.width=width;
1787 cancel_info.height=(
unsigned int) ((3*height) >> 1);
1789 (windows->widget.width-cancel_info.width-QuantumMargin-2);
1791 (windows->widget.height-cancel_info.height-QuantumMargin);
1792 XGetWidgetInfo(action,&action_info);
1793 action_info.width=width;
1794 action_info.height=(
unsigned int) ((3*height) >> 1);
1795 action_info.x=(int) windows->widget.width-(
int) action_info.width-
1796 (int) cancel_info.width-2*QuantumMargin-2;
1797 action_info.y=cancel_info.y;
1798 XGetWidgetInfo(GrabButtonText,&grab_info);
1799 grab_info.width=width;
1800 grab_info.height=(
unsigned int) ((3*height) >> 1);
1801 grab_info.x=QuantumMargin;
1802 grab_info.y=((5*QuantumMargin) >> 1)+height;
1803 XGetWidgetInfo(ResetButtonText,&reset_info);
1804 reset_info.width=width;
1805 reset_info.height=(
unsigned int) ((3*height) >> 1);
1806 reset_info.x=QuantumMargin;
1807 reset_info.y=grab_info.y+grab_info.height+QuantumMargin;
1811 XGetWidgetInfo(reply,&reply_info);
1812 reply_info.raised=MagickFalse;
1813 reply_info.bevel_width--;
1814 reply_info.width=windows->widget.width-width-((6*QuantumMargin) >> 1);
1815 reply_info.height=height << 1;
1816 reply_info.x=(int) (width+(QuantumMargin << 1));
1817 reply_info.y=action_info.y-reply_info.height-QuantumMargin;
1821 XGetWidgetInfo((
char *) NULL,&mode_info);
1822 mode_info.active=MagickTrue;
1823 mode_info.bevel_width=0;
1824 mode_info.width=(
unsigned int) (action_info.x-(QuantumMargin << 1));
1825 mode_info.height=action_info.height;
1826 mode_info.x=QuantumMargin;
1827 mode_info.y=action_info.y;
1831 XGetWidgetInfo((
char *) NULL,&scroll_info);
1832 scroll_info.bevel_width--;
1833 scroll_info.width=height;
1834 scroll_info.height=(
unsigned int) (reply_info.y-grab_info.y-
1835 (QuantumMargin >> 1));
1836 scroll_info.x=reply_info.x+(reply_info.width-scroll_info.width);
1837 scroll_info.y=grab_info.y-reply_info.bevel_width;
1838 scroll_info.raised=MagickFalse;
1839 scroll_info.trough=MagickTrue;
1840 north_info=scroll_info;
1841 north_info.raised=MagickTrue;
1842 north_info.width-=(north_info.bevel_width << 1);
1843 north_info.height=north_info.width-1;
1844 north_info.x+=north_info.bevel_width;
1845 north_info.y+=north_info.bevel_width;
1846 south_info=north_info;
1847 south_info.y=scroll_info.y+scroll_info.height-scroll_info.bevel_width-
1850 slider_info=north_info;
1852 slider_info.width-=2;
1853 slider_info.min_y=north_info.y+north_info.height+north_info.bevel_width+
1854 slider_info.bevel_width+2;
1855 slider_info.height=scroll_info.height-((slider_info.min_y-
1856 scroll_info.y+1) << 1)+4;
1857 visible_colors=(
unsigned int) (scroll_info.height*
1858 PerceptibleReciprocal((
double) height+(height >> 3)));
1859 if (colors > visible_colors)
1860 slider_info.height=(
unsigned int) ((visible_colors*
1861 slider_info.height)/colors);
1862 slider_info.max_y=south_info.y-south_info.bevel_width-
1863 slider_info.bevel_width-2;
1864 slider_info.x=scroll_info.x+slider_info.bevel_width+1;
1865 slider_info.y=slider_info.min_y;
1866 expose_info=scroll_info;
1867 expose_info.y=slider_info.y;
1871 XGetWidgetInfo((
char *) NULL,&list_info);
1872 list_info.raised=MagickFalse;
1873 list_info.bevel_width--;
1874 list_info.width=(
unsigned int)
1875 (scroll_info.x-reply_info.x-(QuantumMargin >> 1));
1876 list_info.height=scroll_info.height;
1877 list_info.x=reply_info.x;
1878 list_info.y=scroll_info.y;
1879 if (windows->widget.mapped == MagickFalse)
1880 state|=JumpListState;
1885 XGetWidgetInfo(text,&text_info);
1886 text_info.center=MagickFalse;
1887 text_info.width=reply_info.width;
1888 text_info.height=height;
1889 text_info.x=list_info.x-(QuantumMargin >> 1);
1890 text_info.y=QuantumMargin;
1894 XGetWidgetInfo((
char *) NULL,&selection_info);
1895 selection_info.center=MagickFalse;
1896 selection_info.width=list_info.width;
1897 selection_info.height=(
unsigned int) ((9*height) >> 3);
1898 selection_info.x=list_info.x;
1899 state&=(~UpdateConfigurationState);
1901 if (state & RedrawWidgetState)
1907 y=text_info.y+((text_info.height-height) >> 1)+font_info->ascent;
1908 (void) XDrawString(display,windows->widget.id,
1909 windows->widget.annotate_context,x,y,ColorPatternText,
1910 Extent(ColorPatternText));
1911 (void) CopyMagickString(text_info.text,glob_pattern,MaxTextExtent);
1912 XDrawWidgetText(display,&windows->widget,&text_info);
1913 XDrawBeveledButton(display,&windows->widget,&grab_info);
1914 XDrawBeveledButton(display,&windows->widget,&reset_info);
1915 XDrawBeveledMatte(display,&windows->widget,&list_info);
1916 XDrawBeveledMatte(display,&windows->widget,&scroll_info);
1917 XDrawTriangleNorth(display,&windows->widget,&north_info);
1918 XDrawBeveledButton(display,&windows->widget,&slider_info);
1919 XDrawTriangleSouth(display,&windows->widget,&south_info);
1921 y=reply_info.y+((reply_info.height-height) >> 1)+font_info->ascent;
1922 (void) XDrawString(display,windows->widget.id,
1923 windows->widget.annotate_context,x,y,ColornameText,
1924 Extent(ColornameText));
1925 XDrawBeveledMatte(display,&windows->widget,&reply_info);
1926 XDrawMatteText(display,&windows->widget,&reply_info);
1927 XDrawBeveledButton(display,&windows->widget,&action_info);
1928 XDrawBeveledButton(display,&windows->widget,&cancel_info);
1929 XHighlightWidget(display,&windows->widget,BorderOffset,BorderOffset);
1930 selection_info.id=(~0);
1931 state|=RedrawActionState;
1932 state|=RedrawListState;
1933 state&=(~RedrawWidgetState);
1935 if (state & UpdateListState)
1943 status=XParseColor(display,windows->widget.map_info->colormap,
1944 glob_pattern,&color);
1945 if ((status != False) || (strchr(glob_pattern,
'-') != (
char *) NULL))
1950 (void) CopyMagickString(reply,glob_pattern,MaxTextExtent);
1951 (void) CopyMagickString(glob_pattern,reset_pattern,MaxTextExtent);
1952 action_info.raised=MagickFalse;
1953 XDrawBeveledButton(display,&windows->widget,&action_info);
1959 checklist=GetColorList(glob_pattern,&number_colors,exception);
1960 if (number_colors == 0)
1962 (void) CopyMagickString(glob_pattern,reset_pattern,MaxTextExtent);
1963 (void) XBell(display,0);
1967 for (i=0; i < (int) colors; i++)
1968 colorlist[i]=DestroyString(colorlist[i]);
1969 if (colorlist != (
char **) NULL)
1970 colorlist=(
char **) RelinquishMagickMemory(colorlist);
1971 colorlist=checklist;
1972 colors=number_colors;
1978 scroll_info.height-((slider_info.min_y-scroll_info.y+1) << 1)+1;
1979 if (colors > visible_colors)
1980 slider_info.height=(
unsigned int)
1981 ((visible_colors*slider_info.height)/colors);
1982 slider_info.max_y=south_info.y-south_info.bevel_width-
1983 slider_info.bevel_width-2;
1985 slider_info.y=slider_info.min_y;
1986 expose_info.y=slider_info.y;
1987 selection_info.id=(~0);
1989 state|=RedrawListState;
1993 *reply_info.text=
'\0';
1994 reply_info.cursor=reply_info.text;
1995 (void) CopyMagickString(text_info.text,glob_pattern,MaxTextExtent);
1996 XDrawWidgetText(display,&windows->widget,&text_info);
1997 XDrawMatteText(display,&windows->widget,&reply_info);
1998 XDrawBeveledMatte(display,&windows->widget,&scroll_info);
1999 XDrawTriangleNorth(display,&windows->widget,&north_info);
2000 XDrawBeveledButton(display,&windows->widget,&slider_info);
2001 XDrawTriangleSouth(display,&windows->widget,&south_info);
2002 XHighlightWidget(display,&windows->widget,BorderOffset,BorderOffset);
2003 state&=(~UpdateListState);
2005 if (state & JumpListState)
2011 for (i=0; i < (int) colors; i++)
2012 if (LocaleCompare(colorlist[i],reply) >= 0)
2014 list_info.id=LocaleCompare(colorlist[i],reply) == 0 ? i : ~0;
2017 if ((i < slider_info.id) ||
2018 (i >= (
int) (slider_info.id+visible_colors)))
2019 slider_info.id=i-(visible_colors >> 1);
2020 selection_info.id=(~0);
2021 state|=RedrawListState;
2022 state&=(~JumpListState);
2024 if (state & RedrawListState)
2029 if (slider_info.id >= (
int) (colors-visible_colors))
2030 slider_info.id=(int) (colors-visible_colors);
2031 if ((slider_info.id < 0) || (colors <= visible_colors))
2033 slider_info.y=slider_info.min_y;
2035 slider_info.y+=((ssize_t) slider_info.id*(slider_info.max_y-
2036 slider_info.min_y+1)/colors);
2037 if (slider_info.id != selection_info.id)
2042 selection_info.id=slider_info.id;
2043 selection_info.y=list_info.y+(height >> 3)+2;
2044 for (i=0; i < (int) visible_colors; i++)
2046 selection_info.raised=(slider_info.id+i) != list_info.id ?
2047 MagickTrue : MagickFalse;
2048 selection_info.text=(
char *) NULL;
2049 if ((slider_info.id+i) < (int) colors)
2050 selection_info.text=colorlist[slider_info.id+i];
2051 XDrawWidgetText(display,&windows->widget,&selection_info);
2052 selection_info.y+=(int) selection_info.height;
2057 if (slider_info.y > expose_info.y)
2059 expose_info.height=(
unsigned int) slider_info.y-expose_info.y;
2060 expose_info.y=slider_info.y-expose_info.height-
2061 slider_info.bevel_width-1;
2065 expose_info.height=(
unsigned int) expose_info.y-slider_info.y;
2066 expose_info.y=slider_info.y+slider_info.height+
2067 slider_info.bevel_width+1;
2069 XDrawTriangleNorth(display,&windows->widget,&north_info);
2070 XDrawMatte(display,&windows->widget,&expose_info);
2071 XDrawBeveledButton(display,&windows->widget,&slider_info);
2072 XDrawTriangleSouth(display,&windows->widget,&south_info);
2073 expose_info.y=slider_info.y;
2075 state&=(~RedrawListState);
2077 if (state & RedrawActionState)
2080 colorname[MaxTextExtent];
2085 color=windows->widget.pixel_info->matte_color;
2086 (void) XParseColor(display,windows->widget.map_info->colormap,
2087 reply_info.text,&windows->widget.pixel_info->matte_color);
2088 XBestPixel(display,windows->widget.map_info->colormap,(XColor *) NULL,
2089 (
unsigned int) windows->widget.visual_info->colormap_size,
2090 &windows->widget.pixel_info->matte_color);
2091 mode_info.text=colorname;
2092 (void) FormatLocaleString(mode_info.text,MaxTextExtent,
"#%02x%02x%02x",
2093 windows->widget.pixel_info->matte_color.red,
2094 windows->widget.pixel_info->matte_color.green,
2095 windows->widget.pixel_info->matte_color.blue);
2096 XDrawBeveledButton(display,&windows->widget,&mode_info);
2097 windows->widget.pixel_info->matte_color=color;
2098 state&=(~RedrawActionState);
2103 if (north_info.raised && south_info.raised)
2104 (void) XIfEvent(display,&event,XScreenEvent,(
char *) windows);
2110 XDelay(display,delay);
2112 (void) XCheckIfEvent(display,&event,XScreenEvent,(
char *) windows);
2113 if (north_info.raised == MagickFalse)
2114 if (slider_info.id > 0)
2120 state|=RedrawListState;
2122 if (south_info.raised == MagickFalse)
2123 if (slider_info.id < (
int) colors)
2129 state|=RedrawListState;
2131 if (event.type != ButtonRelease)
2138 if (MatteIsActive(slider_info,event.xbutton))
2143 slider_info.active=MagickTrue;
2146 if (MatteIsActive(north_info,event.xbutton))
2147 if (slider_info.id > 0)
2152 north_info.raised=MagickFalse;
2154 state|=RedrawListState;
2157 if (MatteIsActive(south_info,event.xbutton))
2158 if (slider_info.id < (
int) colors)
2163 south_info.raised=MagickFalse;
2165 state|=RedrawListState;
2168 if (MatteIsActive(scroll_info,event.xbutton))
2173 if (event.xbutton.y < slider_info.y)
2174 slider_info.id-=(visible_colors-1);
2176 slider_info.id+=(visible_colors-1);
2177 state|=RedrawListState;
2180 if (MatteIsActive(list_info,event.xbutton))
2188 id=slider_info.id+(
event.xbutton.y-(list_info.y+(height >> 1))+1)/
2189 selection_info.height;
2190 if (
id >= (
int) colors)
2192 (void) CopyMagickString(reply_info.text,colorlist[
id],
2194 reply_info.highlight=MagickFalse;
2195 reply_info.marker=reply_info.text;
2196 reply_info.cursor=reply_info.text+Extent(reply_info.text);
2197 XDrawMatteText(display,&windows->widget,&reply_info);
2198 state|=RedrawActionState;
2199 if (
id == list_info.id)
2201 (void) CopyMagickString(glob_pattern,reply_info.text,
2203 state|=UpdateListState;
2205 selection_info.id=(~0);
2207 state|=RedrawListState;
2210 if (MatteIsActive(grab_info,event.xbutton))
2215 grab_info.raised=MagickFalse;
2216 XDrawBeveledButton(display,&windows->widget,&grab_info);
2219 if (MatteIsActive(reset_info,event.xbutton))
2224 reset_info.raised=MagickFalse;
2225 XDrawBeveledButton(display,&windows->widget,&reset_info);
2228 if (MatteIsActive(mode_info,event.xbutton))
2233 if (mode_info.text != (
char *) NULL)
2234 (void) CopyMagickString(reply_info.text,mode_info.text,
2236 (void) CopyMagickString(primary_selection,reply_info.text,
2238 (void) XSetSelectionOwner(display,XA_PRIMARY,windows->widget.id,
2239 event.xbutton.time);
2240 reply_info.highlight=XGetSelectionOwner(display,XA_PRIMARY) ==
2241 windows->widget.id ? MagickTrue : MagickFalse;
2242 reply_info.marker=reply_info.text;
2243 reply_info.cursor=reply_info.text+Extent(reply_info.text);
2244 XDrawMatteText(display,&windows->widget,&reply_info);
2247 if (MatteIsActive(action_info,event.xbutton))
2252 action_info.raised=MagickFalse;
2253 XDrawBeveledButton(display,&windows->widget,&action_info);
2256 if (MatteIsActive(cancel_info,event.xbutton))
2261 cancel_info.raised=MagickFalse;
2262 XDrawBeveledButton(display,&windows->widget,&cancel_info);
2265 if (MatteIsActive(reply_info,event.xbutton) == MagickFalse)
2267 if (event.xbutton.button != Button2)
2275 x=
event.xbutton.x-reply_info.x-(QuantumMargin >> 2);
2276 if (font_info != (XFontStruct *) NULL)
2277 for (i=1; i <= Extent(reply_info.marker); i++)
2278 if (XTextWidth(font_info,reply_info.marker,i) > x)
2280 reply_info.cursor=reply_info.marker+i-1;
2281 if (event.xbutton.time > (click_time+DoubleClick))
2282 reply_info.highlight=MagickFalse;
2288 (
void) CopyMagickString(primary_selection,reply_info.text,
2290 (void) XSetSelectionOwner(display,XA_PRIMARY,windows->widget.id,
2291 event.xbutton.time);
2292 reply_info.highlight=XGetSelectionOwner(display,XA_PRIMARY) ==
2293 windows->widget.id ? MagickTrue : MagickFalse;
2295 XDrawMatteText(display,&windows->widget,&reply_info);
2296 click_time=
event.xbutton.time;
2302 (void) XConvertSelection(display,XA_PRIMARY,XA_STRING,XA_STRING,
2303 windows->widget.id,event.xbutton.time);
2308 if (windows->widget.mapped == MagickFalse)
2310 if (north_info.raised == MagickFalse)
2315 delay=SuspendTime << 2;
2316 north_info.raised=MagickTrue;
2317 XDrawTriangleNorth(display,&windows->widget,&north_info);
2319 if (south_info.raised == MagickFalse)
2324 delay=SuspendTime << 2;
2325 south_info.raised=MagickTrue;
2326 XDrawTriangleSouth(display,&windows->widget,&south_info);
2328 if (slider_info.active)
2333 slider_info.active=MagickFalse;
2336 if (grab_info.raised == MagickFalse)
2338 if (event.xbutton.window == windows->widget.id)
2339 if (MatteIsActive(grab_info,event.xbutton))
2344 (void) XGetWindowColor(display,windows,reply_info.text);
2345 reply_info.marker=reply_info.text;
2346 reply_info.cursor=reply_info.text+Extent(reply_info.text);
2347 XDrawMatteText(display,&windows->widget,&reply_info);
2348 state|=RedrawActionState;
2350 grab_info.raised=MagickTrue;
2351 XDrawBeveledButton(display,&windows->widget,&grab_info);
2353 if (reset_info.raised == MagickFalse)
2355 if (event.xbutton.window == windows->widget.id)
2356 if (MatteIsActive(reset_info,event.xbutton))
2358 (void) CopyMagickString(glob_pattern,reset_pattern,
2360 state|=UpdateListState;
2362 reset_info.raised=MagickTrue;
2363 XDrawBeveledButton(display,&windows->widget,&reset_info);
2365 if (action_info.raised == MagickFalse)
2367 if (event.xbutton.window == windows->widget.id)
2369 if (MatteIsActive(action_info,event.xbutton))
2371 if (*reply_info.text ==
'\0')
2372 (void) XBell(display,0);
2377 action_info.raised=MagickTrue;
2378 XDrawBeveledButton(display,&windows->widget,&action_info);
2380 if (cancel_info.raised == MagickFalse)
2382 if (event.xbutton.window == windows->widget.id)
2383 if (MatteIsActive(cancel_info,event.xbutton))
2385 *reply_info.text=
'\0';
2388 cancel_info.raised=MagickTrue;
2389 XDrawBeveledButton(display,&windows->widget,&cancel_info);
2391 if (MatteIsActive(reply_info,event.xbutton) == MagickFalse)
2400 if (event.xclient.message_type != windows->wm_protocols)
2402 if (*event.xclient.data.l == (
int) windows->wm_take_focus)
2404 (void) XSetInputFocus(display,event.xclient.window,RevertToParent,
2405 (Time)
event.xclient.data.l[1]);
2408 if (*event.xclient.data.l != (
int) windows->wm_delete_window)
2410 if (event.xclient.window == windows->widget.id)
2412 *reply_info.text=
'\0';
2418 case ConfigureNotify:
2423 if (event.xconfigure.window != windows->widget.id)
2425 if ((event.xconfigure.width == (
int) windows->widget.width) &&
2426 (
event.xconfigure.height == (int) windows->widget.height))
2428 windows->widget.width=(
unsigned int)
2429 MagickMax(event.xconfigure.width,(
int) windows->widget.min_width);
2430 windows->widget.height=(
unsigned int)
2431 MagickMax(event.xconfigure.height,(
int) windows->widget.min_height);
2432 state|=UpdateConfigurationState;
2437 if (event.xcrossing.window != windows->widget.id)
2439 state&=(~InactiveWidgetState);
2444 if (event.xexpose.window != windows->widget.id)
2446 if (event.xexpose.count != 0)
2448 state|=RedrawWidgetState;
2454 command[MaxTextExtent];
2465 if (event.xkey.window != windows->widget.id)
2467 length=XLookupString((XKeyEvent *) &event.xkey,command,
2468 (
int)
sizeof(command),&key_symbol,(XComposeStatus *) NULL);
2469 *(command+length)=
'\0';
2470 if (AreaIsActive(scroll_info,event.xkey))
2475 switch ((
int) key_symbol)
2498 slider_info.id-=visible_colors;
2504 slider_info.id+=visible_colors;
2510 slider_info.id=(int) colors;
2514 state|=RedrawListState;
2517 if ((key_symbol == XK_Return) || (key_symbol == XK_KP_Enter))
2522 if (*reply_info.text ==
'\0')
2524 (void) CopyMagickString(glob_pattern,reply_info.text,MaxTextExtent);
2525 state|=UpdateListState;
2528 if (key_symbol == XK_Control_L)
2530 state|=ControlState;
2533 if (state & ControlState)
2534 switch ((
int) key_symbol)
2542 *reply_info.text=
'\0';
2543 reply_info.cursor=reply_info.text;
2544 reply_info.marker=reply_info.text;
2545 reply_info.highlight=MagickFalse;
2551 XEditText(display,&reply_info,key_symbol,command,state);
2552 XDrawMatteText(display,&windows->widget,&reply_info);
2553 state|=JumpListState;
2554 status=XParseColor(display,windows->widget.map_info->colormap,
2555 reply_info.text,&color);
2556 if (status != False)
2557 state|=RedrawActionState;
2563 command[MaxTextExtent];
2571 if (event.xkey.window != windows->widget.id)
2573 (void) XLookupString((XKeyEvent *) &
event.xkey,command,
2574 (int)
sizeof(command),&key_symbol,(XComposeStatus *) NULL);
2575 if (key_symbol == XK_Control_L)
2576 state&=(~ControlState);
2581 if (event.xcrossing.window != windows->widget.id)
2583 state|=InactiveWidgetState;
2597 while (XCheckMaskEvent(display,ButtonMotionMask,&event)) ;
2598 if (slider_info.active)
2603 slider_info.y=
event.xmotion.y-
2604 ((slider_info.height+slider_info.bevel_width) >> 1)+1;
2605 if (slider_info.y < slider_info.min_y)
2606 slider_info.y=slider_info.min_y;
2607 if (slider_info.y > slider_info.max_y)
2608 slider_info.y=slider_info.max_y;
2610 if (slider_info.y != slider_info.min_y)
2611 slider_info.id=(int) ((colors*(slider_info.y-
2612 slider_info.min_y+1))/(slider_info.max_y-slider_info.min_y+1));
2613 state|=RedrawListState;
2616 if (state & InactiveWidgetState)
2618 if (grab_info.raised == MatteIsActive(grab_info,event.xmotion))
2623 grab_info.raised=!grab_info.raised;
2624 XDrawBeveledButton(display,&windows->widget,&grab_info);
2627 if (reset_info.raised == MatteIsActive(reset_info,event.xmotion))
2632 reset_info.raised=!reset_info.raised;
2633 XDrawBeveledButton(display,&windows->widget,&reset_info);
2636 if (action_info.raised == MatteIsActive(action_info,event.xmotion))
2641 action_info.raised=action_info.raised == MagickFalse ?
2642 MagickTrue : MagickFalse;
2643 XDrawBeveledButton(display,&windows->widget,&action_info);
2646 if (cancel_info.raised == MatteIsActive(cancel_info,event.xmotion))
2651 cancel_info.raised=cancel_info.raised == MagickFalse ?
2652 MagickTrue : MagickFalse;
2653 XDrawBeveledButton(display,&windows->widget,&cancel_info);
2658 case SelectionClear:
2660 reply_info.highlight=MagickFalse;
2661 XDrawMatteText(display,&windows->widget,&reply_info);
2664 case SelectionNotify:
2682 if (event.xselection.property == (Atom) None)
2684 status=XGetWindowProperty(display,event.xselection.requestor,
2685 event.xselection.property,0L,2047L,MagickTrue,XA_STRING,&type,
2686 &format,&length,&after,&data);
2687 if ((status != Success) || (type != XA_STRING) || (format == 32) ||
2690 if ((Extent(reply_info.text)+length) >= (MaxTextExtent-1))
2691 (void) XBell(display,0);
2697 *(data+length)=
'\0';
2698 XEditText(display,&reply_info,(KeySym) XK_Insert,(
char *) data,
2700 XDrawMatteText(display,&windows->widget,&reply_info);
2701 state|=JumpListState;
2702 state|=RedrawActionState;
2704 (void) XFree((
void *) data);
2707 case SelectionRequest:
2712 XSelectionRequestEvent
2715 if (reply_info.highlight == MagickFalse)
2720 request=(&(
event.xselectionrequest));
2721 (void) XChangeProperty(request->display,request->requestor,
2722 request->property,request->target,8,PropModeReplace,
2723 (
unsigned char *) primary_selection,Extent(primary_selection));
2724 notify.type=SelectionNotify;
2725 notify.send_event=MagickTrue;
2726 notify.display=request->display;
2727 notify.requestor=request->requestor;
2728 notify.selection=request->selection;
2729 notify.target=request->target;
2730 notify.time=request->time;
2731 if (request->property == None)
2732 notify.property=request->target;
2734 notify.property=request->property;
2735 (void) XSendEvent(request->display,request->requestor,False,
2736 NoEventMask,(XEvent *) ¬ify);
2741 }
while ((state & ExitState) == 0);
2742 XSetCursorState(display,windows,MagickFalse);
2743 (void) XWithdrawWindow(display,windows->widget.id,windows->widget.screen);
2744 XCheckRefreshWindows(display,windows);
2748 for (i=0; i < (int) colors; i++)
2749 colorlist[i]=DestroyString(colorlist[i]);
2750 if (colorlist != (
char **) NULL)
2751 colorlist=(
char **) RelinquishMagickMemory(colorlist);
2752 exception=DestroyExceptionInfo(exception);
2753 if ((*reply ==
'\0') || (strchr(reply,
'-') != (
char *) NULL))
2755 status=XParseColor(display,windows->widget.map_info->colormap,reply,&color);
2756 if (status != False)
2758 XNoticeWidget(display,windows,
"Color is unknown to X server:",reply);
2759 (void) CopyMagickString(reply,
"gray",MaxTextExtent);
2797 MagickExport
int XCommandWidget(Display *display,XWindows *windows,
2798 const char *
const *selections,XEvent *event)
2800 #define tile_width 112
2801 #define tile_height 70
2803 static const unsigned char
2806 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2807 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2808 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2809 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00,
2810 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00,
2811 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x00,
2812 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2813 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2814 0x00, 0x00, 0x1e, 0x38, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2815 0x00, 0x00, 0x00, 0x00, 0x1e, 0xbc, 0x9f, 0x03, 0x00, 0x3e, 0x00, 0xc0,
2816 0x1f, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x1e, 0xfc, 0xff, 0x0f, 0x80, 0x3f,
2817 0x00, 0xf0, 0x1f, 0xc0, 0x0f, 0x00, 0x00, 0x00, 0x1e, 0xfc, 0xff, 0x1f,
2818 0xe0, 0x3f, 0x00, 0xfc, 0x1f, 0xf0, 0x0f, 0x00, 0x00, 0x00, 0x1e, 0xfc,
2819 0xff, 0x1f, 0xf0, 0x3f, 0x00, 0xfe, 0x1f, 0xf8, 0x0f, 0x00, 0x00, 0x00,
2820 0x1e, 0xfc, 0xfc, 0x3f, 0xf8, 0x3f, 0x00, 0xff, 0x1e, 0xfc, 0x0f, 0x00,
2821 0x00, 0x00, 0x1e, 0x7c, 0xfc, 0x3e, 0xf8, 0x3c, 0x80, 0x1f, 0x1e, 0x7c,
2822 0x0f, 0x00, 0x00, 0x00, 0x1e, 0x78, 0x78, 0x3c, 0x7c, 0x3c, 0xc0, 0x0f,
2823 0x1e, 0x3e, 0x0f, 0x00, 0x00, 0x00, 0x1e, 0x78, 0x78, 0x3c, 0x7c, 0x3c,
2824 0xc0, 0x07, 0x1e, 0x3e, 0x0f, 0x00, 0x00, 0x00, 0x1e, 0x78, 0x78, 0x3c,
2825 0x7c, 0x7c, 0xc0, 0x0f, 0x1e, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x78,
2826 0x78, 0x3c, 0xfc, 0x7c, 0x80, 0x7f, 0x1e, 0x7c, 0x00, 0x00, 0x00, 0x00,
2827 0x1e, 0xf8, 0x78, 0x7c, 0xf8, 0xff, 0x00, 0xff, 0x1f, 0xf8, 0xff, 0x00,
2828 0x00, 0x00, 0x1e, 0xf8, 0x78, 0x7c, 0xf0, 0xff, 0x07, 0xfe, 0x1f, 0xf8,
2829 0xff, 0x00, 0x00, 0x00, 0x1e, 0xf8, 0x78, 0x7c, 0xf0, 0xff, 0x07, 0xf8,
2830 0x1f, 0xf0, 0xff, 0x01, 0x00, 0x00, 0x1e, 0xf8, 0x78, 0x7c, 0xc0, 0xef,
2831 0x07, 0xe0, 0x1f, 0xc0, 0xff, 0x01, 0x00, 0x00, 0x1e, 0x70, 0x40, 0x78,
2832 0x00, 0xc7, 0x07, 0x00, 0x1e, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x1e, 0x00,
2833 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00,
2834 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00,
2835 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00,
2836 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
2837 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2838 0x00, 0xc0, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2839 0x00, 0x00, 0x00, 0xe0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2840 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
2841 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x01, 0x00, 0x00, 0x00,
2842 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00,
2843 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78,
2844 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2845 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x02, 0x00,
2846 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x07,
2847 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2848 0xc0, 0x0f, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2849 0x60, 0x00, 0xc0, 0x0f, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2850 0x00, 0x00, 0x78, 0x00, 0xc0, 0x8f, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00,
2851 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0xc0, 0x8f, 0x3f, 0x00, 0x00, 0x00,
2852 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0xe0, 0x9f, 0x7f, 0x00,
2853 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0xe0, 0xdf,
2854 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x78, 0x00,
2855 0xe0, 0xdf, 0x7b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x0c,
2856 0x78, 0x30, 0xf0, 0xff, 0x7b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e,
2857 0x00, 0x0f, 0xf8, 0x70, 0xf0, 0xff, 0x7b, 0x00, 0x00, 0x1f, 0x00, 0xe0,
2858 0x0f, 0x1e, 0x80, 0x0f, 0xf8, 0x78, 0xf0, 0xfd, 0xf9, 0x00, 0xc0, 0x1f,
2859 0x00, 0xf8, 0x0f, 0x00, 0xe0, 0x1f, 0xf8, 0x7c, 0xf0, 0xfc, 0xf9, 0x00,
2860 0xf0, 0x1f, 0x00, 0xfe, 0x0f, 0x00, 0xf0, 0x07, 0xf8, 0x3e, 0xf8, 0xfc,
2861 0xf0, 0x01, 0xf8, 0x1f, 0x00, 0xff, 0x0f, 0x1e, 0xf0, 0x03, 0xf8, 0x3f,
2862 0xf8, 0xf8, 0xf0, 0x01, 0xfc, 0x1f, 0x80, 0x7f, 0x0f, 0x1e, 0xf8, 0x00,
2863 0xf8, 0x1f, 0x78, 0x18, 0xf0, 0x01, 0x7c, 0x1e, 0xc0, 0x0f, 0x0f, 0x1e,
2864 0x7c, 0x00, 0xf0, 0x0f, 0x78, 0x00, 0xf0, 0x01, 0x3e, 0x1e, 0xe0, 0x07,
2865 0x0f, 0x1e, 0x7c, 0x00, 0xf0, 0x07, 0x7c, 0x00, 0xe0, 0x01, 0x3e, 0x1e,
2866 0xe0, 0x03, 0x0f, 0x1e, 0x3e, 0x00, 0xf0, 0x0f, 0x7c, 0x00, 0xe0, 0x03,
2867 0x3e, 0x3e, 0xe0, 0x07, 0x0f, 0x1e, 0x1e, 0x00, 0xf0, 0x1f, 0x3c, 0x00,
2868 0xe0, 0x03, 0x7e, 0x3e, 0xc0, 0x3f, 0x0f, 0x1e, 0x3e, 0x00, 0xf0, 0x1f,
2869 0x3e, 0x00, 0xe0, 0x03, 0xfc, 0x7f, 0x80, 0xff, 0x0f, 0x1e, 0xfc, 0x00,
2870 0xf0, 0x3e, 0x3e, 0x00, 0xc0, 0x03, 0xf8, 0xff, 0x03, 0xff, 0x0f, 0x1e,
2871 0xfc, 0x07, 0xf0, 0x7c, 0x1e, 0x00, 0xc0, 0x03, 0xf8, 0xff, 0x03, 0xfc,
2872 0x0f, 0x1e, 0xf8, 0x1f, 0xf0, 0xf8, 0x1e, 0x00, 0xc0, 0x03, 0xe0, 0xf7,
2873 0x03, 0xf0, 0x0f, 0x1e, 0xe0, 0x3f, 0xf0, 0x78, 0x1c, 0x00, 0x80, 0x03,
2874 0x80, 0xe3, 0x03, 0x00, 0x0f, 0x1e, 0xc0, 0x3f, 0xf0, 0x30, 0x00, 0x00,
2875 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x0e, 0x00, 0x3e, 0x00, 0x00,
2876 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x0f, 0x00, 0x00, 0x10,
2877 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x0f, 0x00,
2878 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
2879 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2880 0x00, 0xe0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2881 0x00, 0x00, 0x00, 0xf0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2882 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
2883 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00,
2884 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00,
2885 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c,
2886 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2887 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
2909 assert(display != (Display *) NULL);
2910 assert(windows != (XWindows *) NULL);
2911 if (IsEventLogging() != MagickFalse)
2912 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"...");
2913 font_info=windows->command.font_info;
2914 height=(
unsigned int) (font_info->ascent+font_info->descent);
2917 if (event == (XEvent *) NULL)
2931 assert(selections != (
const char **) NULL);
2932 windows->command.width=0;
2933 for (i=0; selections[i] != (
char *) NULL; i++)
2935 width=WidgetTextWidth(font_info,(
char *) selections[i]);
2936 if (width > windows->command.width)
2937 windows->command.width=width;
2939 number_selections=(
unsigned int) i;
2940 windows->command.width+=3*QuantumMargin+10;
2941 if ((
int) windows->command.width < (tile_width+QuantumMargin+10))
2942 windows->command.width=(
unsigned int) (tile_width+QuantumMargin+10);
2943 windows->command.height=(
unsigned int) (number_selections*
2944 (((3*height) >> 1)+10)+tile_height+20);
2945 windows->command.min_width=windows->command.width;
2946 windows->command.min_height=windows->command.height;
2947 XConstrainWindowPosition(display,&windows->command);
2948 if (windows->command.id != (Window) NULL)
2956 status=XStringListToTextProperty(&windows->command.name,1,
2958 if (status != False)
2960 XSetWMName(display,windows->command.id,&window_name);
2961 XSetWMIconName(display,windows->command.id,&window_name);
2962 (void) XFree((
void *) window_name.value);
2964 window_changes.width=(int) windows->command.width;
2965 window_changes.height=(
int) windows->command.height;
2966 (void) XReconfigureWMWindow(display,windows->command.id,
2967 windows->command.screen,(
unsigned int) (CWWidth | CWHeight),
2973 if (selection_info != (XWidgetInfo *) NULL)
2974 selection_info=(XWidgetInfo *) RelinquishMagickMemory(selection_info);
2975 selection_info=(XWidgetInfo *) AcquireQuantumMemory(number_selections,
2976 sizeof(*selection_info));
2977 if (selection_info == (XWidgetInfo *) NULL)
2978 ThrowXWindowFatalException(ResourceLimitFatalError,
2979 "MemoryAllocationFailed",
"...");
2980 state|=UpdateConfigurationState | RedrawWidgetState;
2985 if (event != (XEvent *) NULL)
2986 switch (event->type)
2990 for (i=0; i < (int) number_selections; i++)
2992 if (MatteIsActive(selection_info[i],event->xbutton) == MagickFalse)
2994 if (i >= (
int) windows->command.data)
2996 selection_info[i].raised=MagickFalse;
2997 XDrawBeveledButton(display,&windows->command,&selection_info[i]);
3000 submenu_info=selection_info[i];
3001 submenu_info.active=MagickTrue;
3002 toggle_info.y=submenu_info.y+(submenu_info.height >> 1)-
3003 (toggle_info.height >> 1);
3005 (void) XCheckWindowEvent(display,windows->widget.id,LeaveWindowMask,
3013 for (i=0; i < (int) number_selections; i++)
3015 if (MatteIsActive(selection_info[i],event->xbutton) == MagickFalse)
3018 if (
id >= (
int) windows->command.data)
3020 selection_info[id].raised=MagickTrue;
3021 XDrawBeveledButton(display,&windows->command,&selection_info[
id]);
3033 if (event->xclient.message_type != windows->wm_protocols)
3035 if (*event->xclient.data.l != (
int) windows->wm_delete_window)
3037 (void) XWithdrawWindow(display,windows->command.id,
3038 windows->command.screen);
3041 case ConfigureNotify:
3046 if (event->xconfigure.window != windows->command.id)
3048 if (event->xconfigure.send_event != 0)
3050 windows->command.x=
event->xconfigure.x;
3051 windows->command.y=
event->xconfigure.y;
3053 if ((event->xconfigure.width == (
int) windows->command.width) &&
3054 (
event->xconfigure.height == (int) windows->command.height))
3056 windows->command.width=(
unsigned int)
3057 MagickMax(event->xconfigure.width,(
int) windows->command.min_width);
3058 windows->command.height=(
unsigned int)
3059 MagickMax(event->xconfigure.height,(
int) windows->command.min_height);
3060 state|=UpdateConfigurationState;
3065 if (event->xexpose.window != windows->command.id)
3067 if (event->xexpose.count != 0)
3069 state|=RedrawWidgetState;
3079 for (i=0; i < (int) number_selections; i++)
3081 if (i >= (
int) windows->command.data)
3083 if (selection_info[i].raised ==
3084 MatteIsActive(selection_info[i],event->xmotion))
3089 selection_info[i].raised=!selection_info[i].raised;
3090 XDrawBeveledButton(display,&windows->command,
3091 &selection_info[i]);
3095 if (MatteIsActive(selection_info[i],event->xmotion) == MagickFalse)
3097 submenu_info=selection_info[i];
3098 submenu_info.active=MagickTrue;
3099 toggle_info.raised=MagickTrue;
3100 toggle_info.y=submenu_info.y+(submenu_info.height >> 1)-
3101 (toggle_info.height >> 1);
3102 XDrawTriangleEast(display,&windows->command,&toggle_info);
3105 XDelay(display,SuspendTime);
3106 if (XCheckMaskEvent(display,ButtonMotionMask,event) == MagickFalse)
3108 while (XCheckMaskEvent(display,ButtonMotionMask,event)) ;
3109 toggle_info.raised=MagickFalse;
3110 if (windows->command.data != 0)
3111 XDrawTriangleEast(display,&windows->command,&toggle_info);
3117 windows->command.mapped=MagickTrue;
3122 windows->command.mapped=MagickFalse;
3128 if (state & UpdateConfigurationState)
3133 assert(selections != (
const char **) NULL);
3135 for (i=0; i < (int) number_selections; i++)
3137 XGetWidgetInfo(selections[i],&selection_info[i]);
3138 selection_info[i].center=MagickFalse;
3139 selection_info[i].bevel_width--;
3140 selection_info[i].height=(
unsigned int) ((3*height) >> 1);
3141 selection_info[i].x=(QuantumMargin >> 1)+4;
3142 selection_info[i].width=(
unsigned int) (windows->command.width-
3143 (selection_info[i].x << 1));
3144 selection_info[i].y=y;
3145 y+=selection_info[i].height+(selection_info[i].bevel_width << 1)+6;
3147 XGetWidgetInfo((
char *) NULL,&toggle_info);
3148 toggle_info.bevel_width--;
3149 toggle_info.width=(
unsigned int) (((5*height) >> 3)-
3150 (toggle_info.bevel_width << 1));
3151 toggle_info.height=toggle_info.width;
3152 toggle_info.x=selection_info[0].x+selection_info[0].width-
3153 toggle_info.width-(QuantumMargin >> 1);
3154 if (windows->command.mapped)
3155 (void) XClearWindow(display,windows->command.id);
3157 if (state & RedrawWidgetState)
3165 tile_pixmap=XCreatePixmapFromBitmapData(display,windows->command.id,
3166 (
char *) tile_bits,tile_width,tile_height,1L,0L,1);
3167 if (tile_pixmap != (Pixmap) NULL)
3169 (void) XCopyPlane(display,tile_pixmap,windows->command.id,
3170 windows->command.annotate_context,0,0,tile_width,tile_height,
3171 (
int) ((windows->command.width-tile_width) >> 1),10,1L);
3172 (void) XFreePixmap(display,tile_pixmap);
3174 for (i=0; i < (int) number_selections; i++)
3176 XDrawBeveledButton(display,&windows->command,&selection_info[i]);
3177 if (i >= (
int) windows->command.data)
3179 toggle_info.raised=MagickFalse;
3180 toggle_info.y=selection_info[i].y+(selection_info[i].height >> 1)-
3181 (toggle_info.height >> 1);
3182 XDrawTriangleEast(display,&windows->command,&toggle_info);
3184 XHighlightWidget(display,&windows->command,BorderOffset,BorderOffset);
3221 MagickExport
int XConfirmWidget(Display *display,XWindows *windows,
3222 const char *reason,
const char *description)
3224 #define CancelButtonText "Cancel"
3225 #define DismissButtonText "Dismiss"
3226 #define YesButtonText "Yes"
3263 assert(display != (Display *) NULL);
3264 assert(windows != (XWindows *) NULL);
3265 assert(reason != (
char *) NULL);
3266 assert(description != (
char *) NULL);
3267 if (IsEventLogging() != MagickFalse)
3268 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",reason);
3269 XCheckRefreshWindows(display,windows);
3270 font_info=windows->widget.font_info;
3271 width=WidgetTextWidth(font_info,CancelButtonText);
3272 if (WidgetTextWidth(font_info,DismissButtonText) > width)
3273 width=WidgetTextWidth(font_info,DismissButtonText);
3274 if (WidgetTextWidth(font_info,YesButtonText) > width)
3275 width=WidgetTextWidth(font_info,YesButtonText);
3277 if (description != (
char *) NULL)
3278 if (WidgetTextWidth(font_info,(
char *) description) > width)
3279 width=WidgetTextWidth(font_info,(
char *) description);
3280 height=(
unsigned int) (font_info->ascent+font_info->descent);
3284 windows->widget.width=(
unsigned int) (width+9*QuantumMargin);
3285 windows->widget.min_width=(
unsigned int) (9*QuantumMargin+
3286 WidgetTextWidth(font_info,CancelButtonText)+
3287 WidgetTextWidth(font_info,DismissButtonText)+
3288 WidgetTextWidth(font_info,YesButtonText));
3289 if (windows->widget.width < windows->widget.min_width)
3290 windows->widget.width=windows->widget.min_width;
3291 windows->widget.height=(
unsigned int) (12*height);
3292 windows->widget.min_height=(
unsigned int) (7*height);
3293 if (windows->widget.height < windows->widget.min_height)
3294 windows->widget.height=windows->widget.min_height;
3295 XConstrainWindowPosition(display,&windows->widget);
3299 (void) CopyMagickString(windows->widget.name,
"Confirm",MaxTextExtent);
3300 status=XStringListToTextProperty(&windows->widget.name,1,&window_name);
3301 if (status != False)
3303 XSetWMName(display,windows->widget.id,&window_name);
3304 XSetWMIconName(display,windows->widget.id,&window_name);
3305 (void) XFree((
void *) window_name.value);
3307 window_changes.width=(int) windows->widget.width;
3308 window_changes.height=(
int) windows->widget.height;
3309 window_changes.x=windows->widget.x;
3310 window_changes.y=windows->widget.y;
3311 (void) XReconfigureWMWindow(display,windows->widget.id,windows->widget.screen,
3312 (
unsigned int) (CWWidth | CWHeight | CWX | CWY),&window_changes);
3313 (void) XMapRaised(display,windows->widget.id);
3314 windows->widget.mapped=MagickFalse;
3319 state=UpdateConfigurationState;
3320 XSetCursorState(display,windows,MagickTrue);
3323 if (state & UpdateConfigurationState)
3328 XGetWidgetInfo(CancelButtonText,&cancel_info);
3329 cancel_info.width=(
unsigned int) QuantumMargin+
3330 WidgetTextWidth(font_info,CancelButtonText);
3331 cancel_info.height=(
unsigned int) ((3*height) >> 1);
3332 cancel_info.x=(int) (windows->widget.width-cancel_info.width-
3334 cancel_info.y=(int) (windows->widget.height-(cancel_info.height << 1));
3335 dismiss_info=cancel_info;
3336 dismiss_info.text=(
char *) DismissButtonText;
3337 if (LocaleCompare(description,
"Do you want to save it") == 0)
3338 dismiss_info.text=(
char *)
"Don't Save";
3339 dismiss_info.width=(
unsigned int) QuantumMargin+
3340 WidgetTextWidth(font_info,dismiss_info.text);
3341 dismiss_info.x=(int)
3342 ((windows->widget.width >> 1)-(dismiss_info.width >> 1));
3343 yes_info=cancel_info;
3344 yes_info.text=(
char *) YesButtonText;
3345 if (LocaleCompare(description,
"Do you want to save it") == 0)
3346 yes_info.text=(
char *)
"Save";
3347 yes_info.width=(
unsigned int) QuantumMargin+
3348 WidgetTextWidth(font_info,yes_info.text);
3349 if (yes_info.width < cancel_info.width)
3350 yes_info.width=cancel_info.width;
3351 yes_info.x=QuantumMargin;
3352 state&=(~UpdateConfigurationState);
3354 if (state & RedrawWidgetState)
3359 width=WidgetTextWidth(font_info,(
char *) reason);
3360 x=(int) ((windows->widget.width >> 1)-(width >> 1));
3361 y=(int) ((windows->widget.height >> 1)-(height << 1));
3362 (void) XDrawString(display,windows->widget.id,
3363 windows->widget.annotate_context,x,y,(
char *) reason,Extent(reason));
3364 if (description != (
char *) NULL)
3367 question[MaxTextExtent];
3369 (void) CopyMagickString(question,description,MaxTextExtent);
3370 (void) ConcatenateMagickString(question,
"?",MaxTextExtent);
3371 width=WidgetTextWidth(font_info,question);
3372 x=(int) ((windows->widget.width >> 1)-(width >> 1));
3374 (void) XDrawString(display,windows->widget.id,
3375 windows->widget.annotate_context,x,y,question,Extent(question));
3377 XDrawBeveledButton(display,&windows->widget,&cancel_info);
3378 XDrawBeveledButton(display,&windows->widget,&dismiss_info);
3379 XDrawBeveledButton(display,&windows->widget,&yes_info);
3380 XHighlightWidget(display,&windows->widget,BorderOffset,BorderOffset);
3381 state&=(~RedrawWidgetState);
3386 (void) XIfEvent(display,&event,XScreenEvent,(
char *) windows);
3391 if (MatteIsActive(cancel_info,event.xbutton))
3396 cancel_info.raised=MagickFalse;
3397 XDrawBeveledButton(display,&windows->widget,&cancel_info);
3400 if (MatteIsActive(dismiss_info,event.xbutton))
3405 dismiss_info.raised=MagickFalse;
3406 XDrawBeveledButton(display,&windows->widget,&dismiss_info);
3409 if (MatteIsActive(yes_info,event.xbutton))
3414 yes_info.raised=MagickFalse;
3415 XDrawBeveledButton(display,&windows->widget,&yes_info);
3422 if (windows->widget.mapped == MagickFalse)
3424 if (cancel_info.raised == MagickFalse)
3426 if (event.xbutton.window == windows->widget.id)
3427 if (MatteIsActive(cancel_info,event.xbutton))
3432 cancel_info.raised=MagickTrue;
3433 XDrawBeveledButton(display,&windows->widget,&cancel_info);
3435 if (dismiss_info.raised == MagickFalse)
3437 if (event.xbutton.window == windows->widget.id)
3438 if (MatteIsActive(dismiss_info,event.xbutton))
3443 dismiss_info.raised=MagickTrue;
3444 XDrawBeveledButton(display,&windows->widget,&dismiss_info);
3446 if (yes_info.raised == MagickFalse)
3448 if (event.xbutton.window == windows->widget.id)
3449 if (MatteIsActive(yes_info,event.xbutton))
3454 yes_info.raised=MagickTrue;
3455 XDrawBeveledButton(display,&windows->widget,&yes_info);
3464 if (event.xclient.message_type != windows->wm_protocols)
3466 if (*event.xclient.data.l == (
int) windows->wm_take_focus)
3468 (void) XSetInputFocus(display,event.xclient.window,RevertToParent,
3469 (Time)
event.xclient.data.l[1]);
3472 if (*event.xclient.data.l != (
int) windows->wm_delete_window)
3474 if (event.xclient.window == windows->widget.id)
3481 case ConfigureNotify:
3486 if (event.xconfigure.window != windows->widget.id)
3488 if ((event.xconfigure.width == (
int) windows->widget.width) &&
3489 (
event.xconfigure.height == (int) windows->widget.height))
3491 windows->widget.width=(
unsigned int)
3492 MagickMax(event.xconfigure.width,(
int) windows->widget.min_width);
3493 windows->widget.height=(
unsigned int)
3494 MagickMax(event.xconfigure.height,(
int) windows->widget.min_height);
3495 state|=UpdateConfigurationState;
3500 if (event.xcrossing.window != windows->widget.id)
3502 state&=(~InactiveWidgetState);
3507 if (event.xexpose.window != windows->widget.id)
3509 if (event.xexpose.count != 0)
3511 state|=RedrawWidgetState;
3517 command[MaxTextExtent];
3525 if (event.xkey.window != windows->widget.id)
3527 (void) XLookupString((XKeyEvent *) &
event.xkey,command,
3528 (int)
sizeof(command),&key_symbol,(XComposeStatus *) NULL);
3529 if ((key_symbol == XK_Return) || (key_symbol == XK_KP_Enter))
3531 yes_info.raised=MagickFalse;
3532 XDrawBeveledButton(display,&windows->widget,&yes_info);
3541 if (event.xcrossing.window != windows->widget.id)
3543 state|=InactiveWidgetState;
3551 while (XCheckMaskEvent(display,ButtonMotionMask,&event)) ;
3552 if (state & InactiveWidgetState)
3554 if (cancel_info.raised == MatteIsActive(cancel_info,event.xmotion))
3559 cancel_info.raised=cancel_info.raised == MagickFalse ?
3560 MagickTrue : MagickFalse;
3561 XDrawBeveledButton(display,&windows->widget,&cancel_info);
3564 if (dismiss_info.raised == MatteIsActive(dismiss_info,event.xmotion))
3569 dismiss_info.raised=dismiss_info.raised == MagickFalse ?
3570 MagickTrue : MagickFalse;
3571 XDrawBeveledButton(display,&windows->widget,&dismiss_info);
3574 if (yes_info.raised == MatteIsActive(yes_info,event.xmotion))
3579 yes_info.raised=yes_info.raised == MagickFalse ?
3580 MagickTrue : MagickFalse;
3581 XDrawBeveledButton(display,&windows->widget,&yes_info);
3589 }
while ((state & ExitState) == 0);
3590 XSetCursorState(display,windows,MagickFalse);
3591 (void) XWithdrawWindow(display,windows->widget.id,windows->widget.screen);
3592 XCheckRefreshWindows(display,windows);
3630 MagickExport
int XDialogWidget(Display *display,XWindows *windows,
3631 const char *action,
const char *query,
char *reply)
3633 #define CancelButtonText "Cancel"
3636 primary_selection[MaxTextExtent];
3644 static MagickBooleanType
3645 raised = MagickFalse;
3680 assert(display != (Display *) NULL);
3681 assert(windows != (XWindows *) NULL);
3682 assert(action != (
char *) NULL);
3683 assert(query != (
char *) NULL);
3684 assert(reply != (
char *) NULL);
3685 if (IsEventLogging() != MagickFalse)
3686 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",action);
3687 XCheckRefreshWindows(display,windows);
3688 font_info=windows->widget.font_info;
3689 width=WidgetTextWidth(font_info,(
char *) action);
3690 if (WidgetTextWidth(font_info,CancelButtonText) > width)
3691 width=WidgetTextWidth(font_info,CancelButtonText);
3692 width+=(3*QuantumMargin) >> 1;
3693 height=(
unsigned int) (font_info->ascent+font_info->descent);
3697 windows->widget.width=(
unsigned int) MagickMax((
int) (2*width),(
int)
3698 WidgetTextWidth(font_info,(
char *) query));
3699 if (windows->widget.width < WidgetTextWidth(font_info,reply))
3700 windows->widget.width=WidgetTextWidth(font_info,reply);
3701 windows->widget.width+=6*QuantumMargin;
3702 windows->widget.min_width=(
unsigned int)
3703 (width+28*XTextWidth(font_info,
"#",1)+4*QuantumMargin);
3704 if (windows->widget.width < windows->widget.min_width)
3705 windows->widget.width=windows->widget.min_width;
3706 windows->widget.height=(
unsigned int) (7*height+(QuantumMargin << 1));
3707 windows->widget.min_height=windows->widget.height;
3708 if (windows->widget.height < windows->widget.min_height)
3709 windows->widget.height=windows->widget.min_height;
3710 XConstrainWindowPosition(display,&windows->widget);
3714 (void) CopyMagickString(windows->widget.name,
"Dialog",MaxTextExtent);
3715 status=XStringListToTextProperty(&windows->widget.name,1,&window_name);
3716 if (status != False)
3718 XSetWMName(display,windows->widget.id,&window_name);
3719 XSetWMIconName(display,windows->widget.id,&window_name);
3720 (void) XFree((
void *) window_name.value);
3722 window_changes.width=(int) windows->widget.width;
3723 window_changes.height=(
int) windows->widget.height;
3724 window_changes.x=windows->widget.x;
3725 window_changes.y=windows->widget.y;
3726 (void) XReconfigureWMWindow(display,windows->widget.id,windows->widget.screen,
3727 (
unsigned int) (CWWidth | CWHeight | CWX | CWY),&window_changes);
3728 (void) XMapRaised(display,windows->widget.id);
3729 windows->widget.mapped=MagickFalse;
3733 anomaly=(LocaleCompare(action,
"Background") == 0) ||
3734 (LocaleCompare(action,
"New") == 0) ||
3735 (LocaleCompare(action,
"Quantize") == 0) ||
3736 (LocaleCompare(action,
"Resize") == 0) ||
3737 (LocaleCompare(action,
"Save") == 0) ||
3738 (LocaleCompare(action,
"Shade") == 0);
3739 state=UpdateConfigurationState;
3740 XSetCursorState(display,windows,MagickTrue);
3743 if (state & UpdateConfigurationState)
3748 XGetWidgetInfo(CancelButtonText,&cancel_info);
3749 cancel_info.width=width;
3750 cancel_info.height=(
unsigned int) ((3*height) >> 1);
3752 (windows->widget.width-cancel_info.width-((3*QuantumMargin) >> 1));
3754 (windows->widget.height-cancel_info.height-((3*QuantumMargin) >> 1));
3755 XGetWidgetInfo(action,&action_info);
3756 action_info.width=width;
3757 action_info.height=(
unsigned int) ((3*height) >> 1);
3758 action_info.x=cancel_info.x-(cancel_info.width+QuantumMargin+
3759 (action_info.bevel_width << 1));
3760 action_info.y=cancel_info.y;
3764 XGetWidgetInfo(reply,&reply_info);
3765 reply_info.raised=MagickFalse;
3766 reply_info.bevel_width--;
3767 reply_info.width=windows->widget.width-(3*QuantumMargin);
3768 reply_info.height=height << 1;
3769 reply_info.x=(3*QuantumMargin) >> 1;
3770 reply_info.y=action_info.y-reply_info.height-QuantumMargin;
3774 XGetWidgetInfo(
"Dither",&special_info);
3775 special_info.raised=raised;
3776 special_info.bevel_width--;
3777 special_info.width=(
unsigned int) QuantumMargin >> 1;
3778 special_info.height=(
unsigned int) QuantumMargin >> 1;
3779 special_info.x=reply_info.x;
3780 special_info.y=action_info.y+action_info.height-special_info.height;
3781 if (LocaleCompare(action,
"Background") == 0)
3782 special_info.text=(
char *)
"Backdrop";
3783 if (LocaleCompare(action,
"New") == 0)
3784 special_info.text=(
char *)
"Gradation";
3785 if (LocaleCompare(action,
"Resize") == 0)
3786 special_info.text=(
char *)
"Constrain ratio";
3787 if (LocaleCompare(action,
"Save") == 0)
3788 special_info.text=(
char *)
"Non-progressive";
3789 if (LocaleCompare(action,
"Shade") == 0)
3790 special_info.text=(
char *)
"Color shading";
3794 XGetWidgetInfo(query,&text_info);
3795 text_info.width=reply_info.width;
3796 text_info.height=height;
3797 text_info.x=reply_info.x-(QuantumMargin >> 1);
3798 text_info.y=QuantumMargin;
3799 text_info.center=MagickFalse;
3800 state&=(~UpdateConfigurationState);
3802 if (state & RedrawWidgetState)
3807 XDrawWidgetText(display,&windows->widget,&text_info);
3808 XDrawBeveledMatte(display,&windows->widget,&reply_info);
3809 XDrawMatteText(display,&windows->widget,&reply_info);
3811 XDrawBeveledButton(display,&windows->widget,&special_info);
3812 XDrawBeveledButton(display,&windows->widget,&action_info);
3813 XDrawBeveledButton(display,&windows->widget,&cancel_info);
3814 XHighlightWidget(display,&windows->widget,BorderOffset,BorderOffset);
3815 state&=(~RedrawWidgetState);
3820 (void) XIfEvent(display,&event,XScreenEvent,(
char *) windows);
3826 if (MatteIsActive(special_info,event.xbutton))
3831 special_info.raised=!special_info.raised;
3832 XDrawBeveledButton(display,&windows->widget,&special_info);
3835 if (MatteIsActive(action_info,event.xbutton))
3840 action_info.raised=MagickFalse;
3841 XDrawBeveledButton(display,&windows->widget,&action_info);
3844 if (MatteIsActive(cancel_info,event.xbutton))
3849 cancel_info.raised=MagickFalse;
3850 XDrawBeveledButton(display,&windows->widget,&cancel_info);
3853 if (MatteIsActive(reply_info,event.xbutton) == MagickFalse)
3855 if (event.xbutton.button != Button2)
3863 x=
event.xbutton.x-reply_info.x-(QuantumMargin >> 2);
3864 for (i=1; i <= Extent(reply_info.marker); i++)
3865 if (XTextWidth(font_info,reply_info.marker,i) > x)
3867 reply_info.cursor=reply_info.marker+i-1;
3868 if (event.xbutton.time > (click_time+DoubleClick))
3869 reply_info.highlight=MagickFalse;
3875 (
void) CopyMagickString(primary_selection,reply_info.text,
3877 (void) XSetSelectionOwner(display,XA_PRIMARY,windows->widget.id,
3878 event.xbutton.time);
3879 reply_info.highlight=XGetSelectionOwner(display,XA_PRIMARY) ==
3880 windows->widget.id ? MagickTrue : MagickFalse;
3882 XDrawMatteText(display,&windows->widget,&reply_info);
3883 click_time=
event.xbutton.time;
3889 (void) XConvertSelection(display,XA_PRIMARY,XA_STRING,XA_STRING,
3890 windows->widget.id,event.xbutton.time);
3895 if (windows->widget.mapped == MagickFalse)
3897 if (action_info.raised == MagickFalse)
3899 if (event.xbutton.window == windows->widget.id)
3900 if (MatteIsActive(action_info,event.xbutton))
3902 action_info.raised=MagickTrue;
3903 XDrawBeveledButton(display,&windows->widget,&action_info);
3905 if (cancel_info.raised == MagickFalse)
3907 if (event.xbutton.window == windows->widget.id)
3908 if (MatteIsActive(cancel_info,event.xbutton))
3910 *reply_info.text=
'\0';
3913 cancel_info.raised=MagickTrue;
3914 XDrawBeveledButton(display,&windows->widget,&cancel_info);
3923 if (event.xclient.message_type != windows->wm_protocols)
3925 if (*event.xclient.data.l == (
int) windows->wm_take_focus)
3927 (void) XSetInputFocus(display,event.xclient.window,RevertToParent,
3928 (Time)
event.xclient.data.l[1]);
3931 if (*event.xclient.data.l != (
int) windows->wm_delete_window)
3933 if (event.xclient.window == windows->widget.id)
3935 *reply_info.text=
'\0';
3941 case ConfigureNotify:
3946 if (event.xconfigure.window != windows->widget.id)
3948 if ((event.xconfigure.width == (
int) windows->widget.width) &&
3949 (
event.xconfigure.height == (int) windows->widget.height))
3951 windows->widget.width=(
unsigned int)
3952 MagickMax(event.xconfigure.width,(
int) windows->widget.min_width);
3953 windows->widget.height=(
unsigned int)
3954 MagickMax(event.xconfigure.height,(
int) windows->widget.min_height);
3955 state|=UpdateConfigurationState;
3960 if (event.xcrossing.window != windows->widget.id)
3962 state&=(~InactiveWidgetState);
3967 if (event.xexpose.window != windows->widget.id)
3969 if (event.xexpose.count != 0)
3971 state|=RedrawWidgetState;
3977 command[MaxTextExtent];
3988 if (event.xkey.window != windows->widget.id)
3990 length=XLookupString((XKeyEvent *) &event.xkey,command,
3991 (
int)
sizeof(command),&key_symbol,(XComposeStatus *) NULL);
3992 *(command+length)=
'\0';
3993 if ((key_symbol == XK_Return) || (key_symbol == XK_KP_Enter))
3995 action_info.raised=MagickFalse;
3996 XDrawBeveledButton(display,&windows->widget,&action_info);
4000 if (key_symbol == XK_Control_L)
4002 state|=ControlState;
4005 if (state & ControlState)
4006 switch ((
int) key_symbol)
4014 *reply_info.text=
'\0';
4015 reply_info.cursor=reply_info.text;
4016 reply_info.marker=reply_info.text;
4017 reply_info.highlight=MagickFalse;
4023 XEditText(display,&reply_info,key_symbol,command,state);
4024 XDrawMatteText(display,&windows->widget,&reply_info);
4030 command[MaxTextExtent];
4038 if (event.xkey.window != windows->widget.id)
4040 (void) XLookupString((XKeyEvent *) &
event.xkey,command,
4041 (int)
sizeof(command),&key_symbol,(XComposeStatus *) NULL);
4042 if (key_symbol == XK_Control_L)
4043 state&=(~ControlState);
4048 if (event.xcrossing.window != windows->widget.id)
4050 state|=InactiveWidgetState;
4058 while (XCheckMaskEvent(display,ButtonMotionMask,&event)) ;
4059 if (state & InactiveWidgetState)
4061 if (action_info.raised == MatteIsActive(action_info,event.xmotion))
4066 action_info.raised=action_info.raised == MagickFalse ?
4067 MagickTrue : MagickFalse;
4068 XDrawBeveledButton(display,&windows->widget,&action_info);
4071 if (cancel_info.raised == MatteIsActive(cancel_info,event.xmotion))
4076 cancel_info.raised=cancel_info.raised == MagickFalse ?
4077 MagickTrue : MagickFalse;
4078 XDrawBeveledButton(display,&windows->widget,&cancel_info);
4083 case SelectionClear:
4085 reply_info.highlight=MagickFalse;
4086 XDrawMatteText(display,&windows->widget,&reply_info);
4089 case SelectionNotify:
4107 if (event.xselection.property == (Atom) None)
4109 status=XGetWindowProperty(display,event.xselection.requestor,
4110 event.xselection.property,0L,2047L,MagickTrue,XA_STRING,&type,
4111 &format,&length,&after,&data);
4112 if ((status != Success) || (type != XA_STRING) || (format == 32) ||
4115 if ((Extent(reply_info.text)+length) >= (MaxTextExtent-1))
4116 (void) XBell(display,0);
4122 *(data+length)=
'\0';
4123 XEditText(display,&reply_info,(KeySym) XK_Insert,(
char *) data,
4125 XDrawMatteText(display,&windows->widget,&reply_info);
4127 (void) XFree((
void *) data);
4130 case SelectionRequest:
4135 XSelectionRequestEvent
4138 if (reply_info.highlight == MagickFalse)
4143 request=(&(
event.xselectionrequest));
4144 (void) XChangeProperty(request->display,request->requestor,
4145 request->property,request->target,8,PropModeReplace,
4146 (
unsigned char *) primary_selection,Extent(primary_selection));
4147 notify.type=SelectionNotify;
4148 notify.display=request->display;
4149 notify.requestor=request->requestor;
4150 notify.selection=request->selection;
4151 notify.target=request->target;
4152 notify.time=request->time;
4153 if (request->property == None)
4154 notify.property=request->target;
4156 notify.property=request->property;
4157 (void) XSendEvent(request->display,request->requestor,False,0,
4158 (XEvent *) ¬ify);
4163 }
while ((state & ExitState) == 0);
4164 XSetCursorState(display,windows,MagickFalse);
4165 (void) XWithdrawWindow(display,windows->widget.id,windows->widget.screen);
4166 XCheckRefreshWindows(display,windows);
4168 if (special_info.raised)
4171 return(raised == MagickFalse);
4206 MagickExport
void XFileBrowserWidget(Display *display,XWindows *windows,
4207 const char *action,
char *reply)
4209 #define CancelButtonText "Cancel"
4210 #define DirectoryText "Directory:"
4211 #define FilenameText "File name:"
4212 #define GrabButtonText "Grab"
4213 #define FormatButtonText "Format"
4214 #define HomeButtonText "Home"
4215 #define UpButtonText "Up"
4220 home_directory[MaxTextExtent],
4221 primary_selection[MaxTextExtent],
4222 text[MaxTextExtent],
4223 working_path[MaxTextExtent];
4233 glob_pattern[MaxTextExtent] =
"*",
4234 format[MaxTextExtent] =
"miff";
4236 static MagickStatusType
4237 mask = (MagickStatusType) (CWWidth | CWHeight | CWX | CWY);
4285 assert(display != (Display *) NULL);
4286 assert(windows != (XWindows *) NULL);
4287 assert(action != (
char *) NULL);
4288 assert(reply != (
char *) NULL);
4289 if (IsEventLogging() != MagickFalse)
4290 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",action);
4291 XSetCursorState(display,windows,MagickTrue);
4292 XCheckRefreshWindows(display,windows);
4293 directory=getcwd(home_directory,MaxTextExtent);
4295 (void) CopyMagickString(working_path,home_directory,MaxTextExtent);
4296 filelist=ListFiles(working_path,glob_pattern,&files);
4297 if (filelist == (
char **) NULL)
4302 XNoticeWidget(display,windows,
"Unable to read directory:",working_path);
4303 (void) XDialogWidget(display,windows,action,
"Enter filename:",reply);
4309 font_info=windows->widget.font_info;
4311 for (i=0; i < (ssize_t) files; i++)
4312 if (WidgetTextWidth(font_info,filelist[i]) > text_width)
4313 text_width=WidgetTextWidth(font_info,filelist[i]);
4314 width=WidgetTextWidth(font_info,(
char *) action);
4315 if (WidgetTextWidth(font_info,GrabButtonText) > width)
4316 width=WidgetTextWidth(font_info,GrabButtonText);
4317 if (WidgetTextWidth(font_info,FormatButtonText) > width)
4318 width=WidgetTextWidth(font_info,FormatButtonText);
4319 if (WidgetTextWidth(font_info,CancelButtonText) > width)
4320 width=WidgetTextWidth(font_info,CancelButtonText);
4321 if (WidgetTextWidth(font_info,HomeButtonText) > width)
4322 width=WidgetTextWidth(font_info,HomeButtonText);
4323 if (WidgetTextWidth(font_info,UpButtonText) > width)
4324 width=WidgetTextWidth(font_info,UpButtonText);
4325 width+=QuantumMargin;
4326 if (WidgetTextWidth(font_info,DirectoryText) > width)
4327 width=WidgetTextWidth(font_info,DirectoryText);
4328 if (WidgetTextWidth(font_info,FilenameText) > width)
4329 width=WidgetTextWidth(font_info,FilenameText);
4330 height=(
unsigned int) (font_info->ascent+font_info->descent);
4334 windows->widget.width=width+MagickMin((
int) text_width,(
int) MaxTextWidth)+
4336 windows->widget.min_width=width+MinTextWidth+4*QuantumMargin;
4337 if (windows->widget.width < windows->widget.min_width)
4338 windows->widget.width=windows->widget.min_width;
4339 windows->widget.height=(
unsigned int)
4340 (((81*height) >> 2)+((13*QuantumMargin) >> 1)+4);
4341 windows->widget.min_height=(
unsigned int)
4342 (((23*height) >> 1)+((13*QuantumMargin) >> 1)+4);
4343 if (windows->widget.height < windows->widget.min_height)
4344 windows->widget.height=windows->widget.min_height;
4345 XConstrainWindowPosition(display,&windows->widget);
4349 (void) CopyMagickString(windows->widget.name,
"Browse and Select a File",
4351 status=XStringListToTextProperty(&windows->widget.name,1,&window_name);
4352 if (status != False)
4354 XSetWMName(display,windows->widget.id,&window_name);
4355 XSetWMIconName(display,windows->widget.id,&window_name);
4356 (void) XFree((
void *) window_name.value);
4358 window_changes.width=(int) windows->widget.width;
4359 window_changes.height=(
int) windows->widget.height;
4360 window_changes.x=windows->widget.x;
4361 window_changes.y=windows->widget.y;
4362 (void) XReconfigureWMWindow(display,windows->widget.id,
4363 windows->widget.screen,mask,&window_changes);
4364 (void) XMapRaised(display,windows->widget.id);
4365 windows->widget.mapped=MagickFalse;
4369 XGetWidgetInfo((
char *) NULL,&slider_info);
4370 XGetWidgetInfo((
char *) NULL,&north_info);
4371 XGetWidgetInfo((
char *) NULL,&south_info);
4372 XGetWidgetInfo((
char *) NULL,&expose_info);
4374 anomaly=(LocaleCompare(action,
"Composite") == 0) ||
4375 (LocaleCompare(action,
"Open") == 0) || (LocaleCompare(action,
"Map") == 0);
4376 delay=SuspendTime << 2;
4377 state=UpdateConfigurationState;
4380 if (state & UpdateConfigurationState)
4388 XGetWidgetInfo(CancelButtonText,&cancel_info);
4389 cancel_info.width=width;
4390 cancel_info.height=(
unsigned int) ((3*height) >> 1);
4392 (windows->widget.width-cancel_info.width-QuantumMargin-2);
4394 (windows->widget.height-cancel_info.height-QuantumMargin);
4395 XGetWidgetInfo(action,&action_info);
4396 action_info.width=width;
4397 action_info.height=(
unsigned int) ((3*height) >> 1);
4398 action_info.x=cancel_info.x-(cancel_info.width+(QuantumMargin >> 1)+
4399 (action_info.bevel_width << 1));
4400 action_info.y=cancel_info.y;
4401 XGetWidgetInfo(GrabButtonText,&special_info);
4402 special_info.width=width;
4403 special_info.height=(
unsigned int) ((3*height) >> 1);
4404 special_info.x=action_info.x-(action_info.width+(QuantumMargin >> 1)+
4405 (special_info.bevel_width << 1));
4406 special_info.y=action_info.y;
4407 if (anomaly == MagickFalse)
4412 special_info.text=(
char *) FormatButtonText;
4413 p=reply+Extent(reply)-1;
4414 while ((p > (reply+1)) && (*(p-1) !=
'.'))
4416 if ((p > (reply+1)) && (*(p-1) ==
'.'))
4417 (void) CopyMagickString(format,p,MaxTextExtent);
4419 XGetWidgetInfo(UpButtonText,&up_info);
4420 up_info.width=width;
4421 up_info.height=(
unsigned int) ((3*height) >> 1);
4422 up_info.x=QuantumMargin;
4423 up_info.y=((5*QuantumMargin) >> 1)+height;
4424 XGetWidgetInfo(HomeButtonText,&home_info);
4425 home_info.width=width;
4426 home_info.height=(
unsigned int) ((3*height) >> 1);
4427 home_info.x=QuantumMargin;
4428 home_info.y=up_info.y+up_info.height+QuantumMargin;
4432 XGetWidgetInfo(reply,&reply_info);
4433 reply_info.raised=MagickFalse;
4434 reply_info.bevel_width--;
4435 reply_info.width=windows->widget.width-width-((6*QuantumMargin) >> 1);
4436 reply_info.height=height << 1;
4437 reply_info.x=(int) (width+(QuantumMargin << 1));
4438 reply_info.y=action_info.y-reply_info.height-QuantumMargin;
4442 XGetWidgetInfo((
char *) NULL,&scroll_info);
4443 scroll_info.bevel_width--;
4444 scroll_info.width=height;
4445 scroll_info.height=(
unsigned int)
4446 (reply_info.y-up_info.y-(QuantumMargin >> 1));
4447 scroll_info.x=reply_info.x+(reply_info.width-scroll_info.width);
4448 scroll_info.y=up_info.y-reply_info.bevel_width;
4449 scroll_info.raised=MagickFalse;
4450 scroll_info.trough=MagickTrue;
4451 north_info=scroll_info;
4452 north_info.raised=MagickTrue;
4453 north_info.width-=(north_info.bevel_width << 1);
4454 north_info.height=north_info.width-1;
4455 north_info.x+=north_info.bevel_width;
4456 north_info.y+=north_info.bevel_width;
4457 south_info=north_info;
4458 south_info.y=scroll_info.y+scroll_info.height-scroll_info.bevel_width-
4461 slider_info=north_info;
4463 slider_info.width-=2;
4464 slider_info.min_y=north_info.y+north_info.height+north_info.bevel_width+
4465 slider_info.bevel_width+2;
4466 slider_info.height=scroll_info.height-((slider_info.min_y-
4467 scroll_info.y+1) << 1)+4;
4468 visible_files=(
unsigned int) (scroll_info.height*
4469 PerceptibleReciprocal((
double) height+(height >> 3)));
4470 if (files > visible_files)
4471 slider_info.height=(
unsigned int) ((visible_files*
4472 slider_info.height)/files);
4473 slider_info.max_y=south_info.y-south_info.bevel_width-
4474 slider_info.bevel_width-2;
4475 slider_info.x=scroll_info.x+slider_info.bevel_width+1;
4476 slider_info.y=slider_info.min_y;
4477 expose_info=scroll_info;
4478 expose_info.y=slider_info.y;
4482 XGetWidgetInfo((
char *) NULL,&list_info);
4483 list_info.raised=MagickFalse;
4484 list_info.bevel_width--;
4485 list_info.width=(
unsigned int)
4486 (scroll_info.x-reply_info.x-(QuantumMargin >> 1));
4487 list_info.height=scroll_info.height;
4488 list_info.x=reply_info.x;
4489 list_info.y=scroll_info.y;
4490 if (windows->widget.mapped == MagickFalse)
4491 state|=JumpListState;
4496 XGetWidgetInfo(text,&text_info);
4497 text_info.center=MagickFalse;
4498 text_info.width=reply_info.width;
4499 text_info.height=height;
4500 text_info.x=list_info.x-(QuantumMargin >> 1);
4501 text_info.y=QuantumMargin;
4505 XGetWidgetInfo((
char *) NULL,&selection_info);
4506 selection_info.center=MagickFalse;
4507 selection_info.width=list_info.width;
4508 selection_info.height=(
unsigned int) ((9*height) >> 3);
4509 selection_info.x=list_info.x;
4510 state&=(~UpdateConfigurationState);
4512 if (state & RedrawWidgetState)
4518 y=text_info.y+((text_info.height-height) >> 1)+font_info->ascent;
4519 (void) XDrawString(display,windows->widget.id,
4520 windows->widget.annotate_context,x,y,DirectoryText,
4521 Extent(DirectoryText));
4522 (void) CopyMagickString(text_info.text,working_path,MaxTextExtent);
4523 (void) ConcatenateMagickString(text_info.text,DirectorySeparator,
4525 (void) ConcatenateMagickString(text_info.text,glob_pattern,
4527 XDrawWidgetText(display,&windows->widget,&text_info);
4528 XDrawBeveledButton(display,&windows->widget,&up_info);
4529 XDrawBeveledButton(display,&windows->widget,&home_info);
4530 XDrawBeveledMatte(display,&windows->widget,&list_info);
4531 XDrawBeveledMatte(display,&windows->widget,&scroll_info);
4532 XDrawTriangleNorth(display,&windows->widget,&north_info);
4533 XDrawBeveledButton(display,&windows->widget,&slider_info);
4534 XDrawTriangleSouth(display,&windows->widget,&south_info);
4536 y=reply_info.y+((reply_info.height-height) >> 1)+font_info->ascent;
4537 (void) XDrawString(display,windows->widget.id,
4538 windows->widget.annotate_context,x,y,FilenameText,
4539 Extent(FilenameText));
4540 XDrawBeveledMatte(display,&windows->widget,&reply_info);
4541 XDrawMatteText(display,&windows->widget,&reply_info);
4542 XDrawBeveledButton(display,&windows->widget,&special_info);
4543 XDrawBeveledButton(display,&windows->widget,&action_info);
4544 XDrawBeveledButton(display,&windows->widget,&cancel_info);
4545 XHighlightWidget(display,&windows->widget,BorderOffset,BorderOffset);
4546 selection_info.id=(~0);
4547 state|=RedrawListState;
4548 state&=(~RedrawWidgetState);
4550 if (state & UpdateListState)
4561 checklist=ListFiles(working_path,glob_pattern,&number_files);
4562 if (checklist == (
char **) NULL)
4567 action_info.raised=MagickFalse;
4568 XDrawBeveledButton(display,&windows->widget,&action_info);
4571 for (i=0; i < (ssize_t) files; i++)
4572 filelist[i]=DestroyString(filelist[i]);
4573 if (filelist != (
char **) NULL)
4574 filelist=(
char **) RelinquishMagickMemory(filelist);
4581 scroll_info.height-((slider_info.min_y-scroll_info.y+1) << 1)+1;
4582 if (files > visible_files)
4583 slider_info.height=(
unsigned int)
4584 ((visible_files*slider_info.height)/files);
4585 slider_info.max_y=south_info.y-south_info.bevel_width-
4586 slider_info.bevel_width-2;
4588 slider_info.y=slider_info.min_y;
4589 expose_info.y=slider_info.y;
4590 selection_info.id=(~0);
4592 state|=RedrawListState;
4596 if (IsGlob(reply_info.text) == MagickFalse)
4598 *reply_info.text=
'\0';
4599 reply_info.cursor=reply_info.text;
4601 (void) CopyMagickString(text_info.text,working_path,MaxTextExtent);
4602 (void) ConcatenateMagickString(text_info.text,DirectorySeparator,
4604 (void) ConcatenateMagickString(text_info.text,glob_pattern,
4606 XDrawWidgetText(display,&windows->widget,&text_info);
4607 XDrawMatteText(display,&windows->widget,&reply_info);
4608 XDrawBeveledMatte(display,&windows->widget,&scroll_info);
4609 XDrawTriangleNorth(display,&windows->widget,&north_info);
4610 XDrawBeveledButton(display,&windows->widget,&slider_info);
4611 XDrawTriangleSouth(display,&windows->widget,&south_info);
4612 XHighlightWidget(display,&windows->widget,BorderOffset,BorderOffset);
4613 state&=(~UpdateListState);
4615 if (state & JumpListState)
4621 for (i=0; i < (ssize_t) files; i++)
4622 if (LocaleCompare(filelist[i],reply) >= 0)
4625 (LocaleCompare(filelist[i],reply) == 0 ? i : ~0);
4628 if ((i < (ssize_t) slider_info.id) ||
4629 (i >= (ssize_t) (slider_info.id+visible_files)))
4630 slider_info.id=(
int) i-(visible_files >> 1);
4631 selection_info.id=(~0);
4632 state|=RedrawListState;
4633 state&=(~JumpListState);
4635 if (state & RedrawListState)
4640 if (slider_info.id >= (
int) (files-visible_files))
4641 slider_info.id=(int) (files-visible_files);
4642 if ((slider_info.id < 0) || (files <= visible_files))
4644 slider_info.y=slider_info.min_y;
4646 slider_info.y+=((ssize_t) slider_info.id*(slider_info.max_y-
4647 slider_info.min_y+1)/files);
4648 if (slider_info.id != selection_info.id)
4653 selection_info.id=slider_info.id;
4654 selection_info.y=list_info.y+(height >> 3)+2;
4655 for (i=0; i < (ssize_t) visible_files; i++)
4657 selection_info.raised=(int) (slider_info.id+i) != list_info.id ?
4658 MagickTrue : MagickFalse;
4659 selection_info.text=(
char *) NULL;
4660 if ((slider_info.id+i) < (ssize_t) files)
4661 selection_info.text=filelist[slider_info.id+i];
4662 XDrawWidgetText(display,&windows->widget,&selection_info);
4663 selection_info.y+=(int) selection_info.height;
4668 if (slider_info.y > expose_info.y)
4670 expose_info.height=(
unsigned int) slider_info.y-expose_info.y;
4671 expose_info.y=slider_info.y-expose_info.height-
4672 slider_info.bevel_width-1;
4676 expose_info.height=(
unsigned int) expose_info.y-slider_info.y;
4677 expose_info.y=slider_info.y+slider_info.height+
4678 slider_info.bevel_width+1;
4680 XDrawTriangleNorth(display,&windows->widget,&north_info);
4681 XDrawMatte(display,&windows->widget,&expose_info);
4682 XDrawBeveledButton(display,&windows->widget,&slider_info);
4683 XDrawTriangleSouth(display,&windows->widget,&south_info);
4684 expose_info.y=slider_info.y;
4686 state&=(~RedrawListState);
4691 if (north_info.raised && south_info.raised)
4692 (void) XIfEvent(display,&event,XScreenEvent,(
char *) windows);
4698 XDelay(display,delay);
4700 (void) XCheckIfEvent(display,&event,XScreenEvent,(
char *) windows);
4701 if (north_info.raised == MagickFalse)
4702 if (slider_info.id > 0)
4708 state|=RedrawListState;
4710 if (south_info.raised == MagickFalse)
4711 if (slider_info.id < (
int) files)
4717 state|=RedrawListState;
4719 if (event.type != ButtonRelease)
4726 if (MatteIsActive(slider_info,event.xbutton))
4731 slider_info.active=MagickTrue;
4734 if (MatteIsActive(north_info,event.xbutton))
4735 if (slider_info.id > 0)
4740 north_info.raised=MagickFalse;
4742 state|=RedrawListState;
4745 if (MatteIsActive(south_info,event.xbutton))
4746 if (slider_info.id < (
int) files)
4751 south_info.raised=MagickFalse;
4753 state|=RedrawListState;
4756 if (MatteIsActive(scroll_info,event.xbutton))
4761 if (event.xbutton.y < slider_info.y)
4762 slider_info.id-=(visible_files-1);
4764 slider_info.id+=(visible_files-1);
4765 state|=RedrawListState;
4768 if (MatteIsActive(list_info,event.xbutton))
4776 id=slider_info.id+(
event.xbutton.y-(list_info.y+(height >> 1))+1)/
4777 selection_info.height;
4778 if (
id >= (
int) files)
4780 (void) CopyMagickString(reply_info.text,filelist[
id],MaxTextExtent);
4781 reply_info.highlight=MagickFalse;
4782 reply_info.marker=reply_info.text;
4783 reply_info.cursor=reply_info.text+Extent(reply_info.text);
4784 XDrawMatteText(display,&windows->widget,&reply_info);
4785 if (
id == list_info.id)
4790 p=reply_info.text+strlen(reply_info.text)-1;
4791 if (*p == *DirectorySeparator)
4792 ChopPathComponents(reply_info.text,1);
4793 (void) ConcatenateMagickString(working_path,DirectorySeparator,
4795 (void) ConcatenateMagickString(working_path,reply_info.text,
4798 state|=UpdateListState;
4800 selection_info.id=(~0);
4802 state|=RedrawListState;
4805 if (MatteIsActive(up_info,event.xbutton))
4810 up_info.raised=MagickFalse;
4811 XDrawBeveledButton(display,&windows->widget,&up_info);
4814 if (MatteIsActive(home_info,event.xbutton))
4819 home_info.raised=MagickFalse;
4820 XDrawBeveledButton(display,&windows->widget,&home_info);
4823 if (MatteIsActive(special_info,event.xbutton))
4828 special_info.raised=MagickFalse;
4829 XDrawBeveledButton(display,&windows->widget,&special_info);
4832 if (MatteIsActive(action_info,event.xbutton))
4837 action_info.raised=MagickFalse;
4838 XDrawBeveledButton(display,&windows->widget,&action_info);
4841 if (MatteIsActive(cancel_info,event.xbutton))
4846 cancel_info.raised=MagickFalse;
4847 XDrawBeveledButton(display,&windows->widget,&cancel_info);
4850 if (MatteIsActive(reply_info,event.xbutton) == MagickFalse)
4852 if (event.xbutton.button != Button2)
4860 x=
event.xbutton.x-reply_info.x-(QuantumMargin >> 2);
4861 for (i=1; i <= (ssize_t) Extent(reply_info.marker); i++)
4862 if (XTextWidth(font_info,reply_info.marker,(
int) i) > x)
4864 reply_info.cursor=reply_info.marker+i-1;
4865 if (event.xbutton.time > (click_time+DoubleClick))
4866 reply_info.highlight=MagickFalse;
4872 (
void) CopyMagickString(primary_selection,reply_info.text,
4874 (void) XSetSelectionOwner(display,XA_PRIMARY,windows->widget.id,
4875 event.xbutton.time);
4876 reply_info.highlight=XGetSelectionOwner(display,XA_PRIMARY) ==
4877 windows->widget.id ? MagickTrue : MagickFalse;
4879 XDrawMatteText(display,&windows->widget,&reply_info);
4880 click_time=
event.xbutton.time;
4886 (void) XConvertSelection(display,XA_PRIMARY,XA_STRING,XA_STRING,
4887 windows->widget.id,event.xbutton.time);
4892 if (windows->widget.mapped == MagickFalse)
4894 if (north_info.raised == MagickFalse)
4899 delay=SuspendTime << 2;
4900 north_info.raised=MagickTrue;
4901 XDrawTriangleNorth(display,&windows->widget,&north_info);
4903 if (south_info.raised == MagickFalse)
4908 delay=SuspendTime << 2;
4909 south_info.raised=MagickTrue;
4910 XDrawTriangleSouth(display,&windows->widget,&south_info);
4912 if (slider_info.active)
4917 slider_info.active=MagickFalse;
4920 if (up_info.raised == MagickFalse)
4922 if (event.xbutton.window == windows->widget.id)
4923 if (MatteIsActive(up_info,event.xbutton))
4925 ChopPathComponents(working_path,1);
4926 if (*working_path ==
'\0')
4927 (void) CopyMagickString(working_path,DirectorySeparator,
4929 state|=UpdateListState;
4931 up_info.raised=MagickTrue;
4932 XDrawBeveledButton(display,&windows->widget,&up_info);
4934 if (home_info.raised == MagickFalse)
4936 if (event.xbutton.window == windows->widget.id)
4937 if (MatteIsActive(home_info,event.xbutton))
4939 (void) CopyMagickString(working_path,home_directory,
4941 state|=UpdateListState;
4943 home_info.raised=MagickTrue;
4944 XDrawBeveledButton(display,&windows->widget,&home_info);
4946 if (special_info.raised == MagickFalse)
4948 if (anomaly == MagickFalse)
4962 exception=AcquireExceptionInfo();
4963 formats=GetMagickList(
"*",&number_formats,exception);
4964 exception=DestroyExceptionInfo(exception);
4965 if (formats == (
char **) NULL)
4967 (void) XCheckDefineCursor(display,windows->widget.id,
4968 windows->widget.busy_cursor);
4969 windows->popup.x=windows->widget.x+60;
4970 windows->popup.y=windows->widget.y+60;
4971 XListBrowserWidget(display,windows,&windows->popup,
4972 (
const char **) formats,
"Select",
"Select image format type:",
4974 XSetCursorState(display,windows,MagickTrue);
4975 (void) XCheckDefineCursor(display,windows->widget.id,
4976 windows->widget.cursor);
4977 LocaleLower(format);
4978 AppendImageFormat(format,reply_info.text);
4979 reply_info.cursor=reply_info.text+Extent(reply_info.text);
4980 XDrawMatteText(display,&windows->widget,&reply_info);
4981 special_info.raised=MagickTrue;
4982 XDrawBeveledButton(display,&windows->widget,&special_info);
4983 for (i=0; i < (ssize_t) number_formats; i++)
4984 formats[i]=DestroyString(formats[i]);
4985 formats=(
char **) RelinquishMagickMemory(formats);
4988 if (event.xbutton.window == windows->widget.id)
4989 if (MatteIsActive(special_info,event.xbutton))
4991 (void) CopyMagickString(working_path,
"x:",MaxTextExtent);
4994 special_info.raised=MagickTrue;
4995 XDrawBeveledButton(display,&windows->widget,&special_info);
4997 if (action_info.raised == MagickFalse)
4999 if (event.xbutton.window == windows->widget.id)
5001 if (MatteIsActive(action_info,event.xbutton))
5003 if (*reply_info.text ==
'\0')
5004 (void) XBell(display,0);
5009 action_info.raised=MagickTrue;
5010 XDrawBeveledButton(display,&windows->widget,&action_info);
5012 if (cancel_info.raised == MagickFalse)
5014 if (event.xbutton.window == windows->widget.id)
5015 if (MatteIsActive(cancel_info,event.xbutton))
5017 *reply_info.text=
'\0';
5021 cancel_info.raised=MagickTrue;
5022 XDrawBeveledButton(display,&windows->widget,&cancel_info);
5031 if (event.xclient.message_type != windows->wm_protocols)
5033 if (*event.xclient.data.l == (
int) windows->wm_take_focus)
5035 (void) XSetInputFocus(display,event.xclient.window,RevertToParent,
5036 (Time)
event.xclient.data.l[1]);
5039 if (*event.xclient.data.l != (
int) windows->wm_delete_window)
5041 if (event.xclient.window == windows->widget.id)
5043 *reply_info.text=
'\0';
5049 case ConfigureNotify:
5054 if (event.xconfigure.window != windows->widget.id)
5056 if ((event.xconfigure.width == (
int) windows->widget.width) &&
5057 (
event.xconfigure.height == (int) windows->widget.height))
5059 windows->widget.width=(
unsigned int)
5060 MagickMax(event.xconfigure.width,(
int) windows->widget.min_width);
5061 windows->widget.height=(
unsigned int)
5062 MagickMax(event.xconfigure.height,(
int) windows->widget.min_height);
5063 state|=UpdateConfigurationState;
5068 if (event.xcrossing.window != windows->widget.id)
5070 state&=(~InactiveWidgetState);
5075 if (event.xexpose.window != windows->widget.id)
5077 if (event.xexpose.count != 0)
5079 state|=RedrawWidgetState;
5085 command[MaxTextExtent];
5096 if (event.xkey.window != windows->widget.id)
5098 length=XLookupString((XKeyEvent *) &event.xkey,command,
5099 (
int)
sizeof(command),&key_symbol,(XComposeStatus *) NULL);
5100 *(command+length)=
'\0';
5101 if (AreaIsActive(scroll_info,event.xkey))
5106 switch ((
int) key_symbol)
5129 slider_info.id-=visible_files;
5135 slider_info.id+=visible_files;
5141 slider_info.id=(int) files;
5145 state|=RedrawListState;
5148 if ((key_symbol == XK_Return) || (key_symbol == XK_KP_Enter))
5153 if (*reply_info.text ==
'\0')
5155 if (IsGlob(reply_info.text))
5156 (
void) CopyMagickString(glob_pattern,reply_info.text,
5160 (void) ConcatenateMagickString(working_path,DirectorySeparator,
5162 (void) ConcatenateMagickString(working_path,reply_info.text,
5164 if (*working_path ==
'~')
5165 ExpandFilename(working_path);
5168 state|=UpdateListState;
5171 if (key_symbol == XK_Control_L)
5173 state|=ControlState;
5176 if (state & ControlState)
5177 switch ((
int) key_symbol)
5185 *reply_info.text=
'\0';
5186 reply_info.cursor=reply_info.text;
5187 reply_info.marker=reply_info.text;
5188 reply_info.highlight=MagickFalse;
5194 XEditText(display,&reply_info,key_symbol,command,state);
5195 XDrawMatteText(display,&windows->widget,&reply_info);
5196 state|=JumpListState;
5202 command[MaxTextExtent];
5210 if (event.xkey.window != windows->widget.id)
5212 (void) XLookupString((XKeyEvent *) &
event.xkey,command,
5213 (int)
sizeof(command),&key_symbol,(XComposeStatus *) NULL);
5214 if (key_symbol == XK_Control_L)
5215 state&=(~ControlState);
5220 if (event.xcrossing.window != windows->widget.id)
5222 state|=InactiveWidgetState;
5236 while (XCheckMaskEvent(display,ButtonMotionMask,&event)) ;
5237 if (slider_info.active)
5242 slider_info.y=
event.xmotion.y-
5243 ((slider_info.height+slider_info.bevel_width) >> 1)+1;
5244 if (slider_info.y < slider_info.min_y)
5245 slider_info.y=slider_info.min_y;
5246 if (slider_info.y > slider_info.max_y)
5247 slider_info.y=slider_info.max_y;
5249 if (slider_info.y != slider_info.min_y)
5250 slider_info.id=(int) ((files*(slider_info.y-slider_info.min_y+1))/
5251 (slider_info.max_y-slider_info.min_y+1));
5252 state|=RedrawListState;
5255 if (state & InactiveWidgetState)
5257 if (up_info.raised == MatteIsActive(up_info,event.xmotion))
5262 up_info.raised=!up_info.raised;
5263 XDrawBeveledButton(display,&windows->widget,&up_info);
5266 if (home_info.raised == MatteIsActive(home_info,event.xmotion))
5271 home_info.raised=!home_info.raised;
5272 XDrawBeveledButton(display,&windows->widget,&home_info);
5275 if (special_info.raised == MatteIsActive(special_info,event.xmotion))
5280 special_info.raised=!special_info.raised;
5281 XDrawBeveledButton(display,&windows->widget,&special_info);
5284 if (action_info.raised == MatteIsActive(action_info,event.xmotion))
5289 action_info.raised=action_info.raised == MagickFalse ?
5290 MagickTrue : MagickFalse;
5291 XDrawBeveledButton(display,&windows->widget,&action_info);
5294 if (cancel_info.raised == MatteIsActive(cancel_info,event.xmotion))
5299 cancel_info.raised=cancel_info.raised == MagickFalse ?
5300 MagickTrue : MagickFalse;
5301 XDrawBeveledButton(display,&windows->widget,&cancel_info);
5306 case SelectionClear:
5308 reply_info.highlight=MagickFalse;
5309 XDrawMatteText(display,&windows->widget,&reply_info);
5312 case SelectionNotify:
5330 if (event.xselection.property == (Atom) None)
5332 status=XGetWindowProperty(display,event.xselection.requestor,
5333 event.xselection.property,0L,2047L,MagickTrue,XA_STRING,&type,
5334 &format,&length,&after,&data);
5335 if ((status != Success) || (type != XA_STRING) || (format == 32) ||
5338 if ((Extent(reply_info.text)+length) >= (MaxTextExtent-1))
5339 (void) XBell(display,0);
5345 *(data+length)=
'\0';
5346 XEditText(display,&reply_info,(KeySym) XK_Insert,(
char *) data,
5348 XDrawMatteText(display,&windows->widget,&reply_info);
5349 state|=JumpListState;
5350 state|=RedrawActionState;
5352 (void) XFree((
void *) data);
5355 case SelectionRequest:
5360 XSelectionRequestEvent
5363 if (reply_info.highlight == MagickFalse)
5368 request=(&(
event.xselectionrequest));
5369 (void) XChangeProperty(request->display,request->requestor,
5370 request->property,request->target,8,PropModeReplace,
5371 (
unsigned char *) primary_selection,Extent(primary_selection));
5372 notify.type=SelectionNotify;
5373 notify.display=request->display;
5374 notify.requestor=request->requestor;
5375 notify.selection=request->selection;
5376 notify.target=request->target;
5377 notify.time=request->time;
5378 if (request->property == None)
5379 notify.property=request->target;
5381 notify.property=request->property;
5382 (void) XSendEvent(request->display,request->requestor,False,0,
5383 (XEvent *) ¬ify);
5388 }
while ((state & ExitState) == 0);
5389 XSetCursorState(display,windows,MagickFalse);
5390 (void) XWithdrawWindow(display,windows->widget.id,windows->widget.screen);
5391 XCheckRefreshWindows(display,windows);
5395 for (i=0; i < (ssize_t) files; i++)
5396 filelist[i]=DestroyString(filelist[i]);
5397 if (filelist != (
char **) NULL)
5398 filelist=(
char **) RelinquishMagickMemory(filelist);
5401 (void) ConcatenateMagickString(working_path,DirectorySeparator,
5403 (void) ConcatenateMagickString(working_path,reply,MaxTextExtent);
5405 (void) CopyMagickString(reply,working_path,MaxTextExtent);
5407 ExpandFilename(reply);
5444 #if defined(__cplusplus) || defined(c_plusplus)
5448 static int FontCompare(
const void *x,
const void *y)
5454 p=(
char *) *((
char **) x);
5455 q=(
char *) *((
char **) y);
5456 while ((*p !=
'\0') && (*q !=
'\0') && (*p == *q))
5464 #if defined(__cplusplus) || defined(c_plusplus)
5468 MagickExport
void XFontBrowserWidget(Display *display,XWindows *windows,
5469 const char *action,
char *reply)
5471 #define BackButtonText "Back"
5472 #define CancelButtonText "Cancel"
5473 #define FontnameText "Name:"
5474 #define FontPatternText "Pattern:"
5475 #define ResetButtonText "Reset"
5478 back_pattern[MaxTextExtent] =
"",
5481 primary_selection[MaxTextExtent] =
"",
5482 reset_pattern[MaxTextExtent] =
"",
5483 text[MaxTextExtent] =
"";
5494 glob_pattern[MaxTextExtent] =
"*";
5496 static MagickStatusType
5497 mask = (MagickStatusType) (CWWidth | CWHeight | CWX | CWY);
5543 assert(display != (Display *) NULL);
5544 assert(windows != (XWindows *) NULL);
5545 assert(action != (
char *) NULL);
5546 assert(reply != (
char *) NULL);
5547 if (IsEventLogging() != MagickFalse)
5548 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",action);
5549 XSetCursorState(display,windows,MagickTrue);
5550 XCheckRefreshWindows(display,windows);
5551 (void) CopyMagickString(back_pattern,glob_pattern,MaxTextExtent);
5552 (void) CopyMagickString(reset_pattern,
"*",MaxTextExtent);
5553 fontlist=XListFonts(display,glob_pattern,32767,&fonts);
5559 XNoticeWidget(display,windows,
"Unable to obtain fonts names:",
5561 (void) CopyMagickString(glob_pattern,
"*",MaxTextExtent);
5562 fontlist=XListFonts(display,glob_pattern,32767,&fonts);
5563 if (fontlist == (
char **) NULL)
5565 XNoticeWidget(display,windows,
"Unable to obtain fonts names:",
5574 fontlist=(
char **) AcquireQuantumMemory((
size_t) fonts,
sizeof(*fontlist));
5575 if (fontlist == (
char **) NULL)
5577 XNoticeWidget(display,windows,
"MemoryAllocationFailed",
5578 "UnableToViewFonts");
5581 for (i=0; i < fonts; i++)
5582 fontlist[i]=listhead[i];
5583 qsort((
void *) fontlist,(
size_t) fonts,
sizeof(*fontlist),FontCompare);
5587 font_info=windows->widget.font_info;
5589 for (i=0; i < fonts; i++)
5590 if (WidgetTextWidth(font_info,fontlist[i]) > text_width)
5591 text_width=WidgetTextWidth(font_info,fontlist[i]);
5592 width=WidgetTextWidth(font_info,(
char *) action);
5593 if (WidgetTextWidth(font_info,CancelButtonText) > width)
5594 width=WidgetTextWidth(font_info,CancelButtonText);
5595 if (WidgetTextWidth(font_info,ResetButtonText) > width)
5596 width=WidgetTextWidth(font_info,ResetButtonText);
5597 if (WidgetTextWidth(font_info,BackButtonText) > width)
5598 width=WidgetTextWidth(font_info,BackButtonText);
5599 width+=QuantumMargin;
5600 if (WidgetTextWidth(font_info,FontPatternText) > width)
5601 width=WidgetTextWidth(font_info,FontPatternText);
5602 if (WidgetTextWidth(font_info,FontnameText) > width)
5603 width=WidgetTextWidth(font_info,FontnameText);
5604 height=(
unsigned int) (font_info->ascent+font_info->descent);
5608 windows->widget.width=width+MagickMin((
int) text_width,(
int) MaxTextWidth)+
5610 windows->widget.min_width=width+MinTextWidth+4*QuantumMargin;
5611 if (windows->widget.width < windows->widget.min_width)
5612 windows->widget.width=windows->widget.min_width;
5613 windows->widget.height=(
unsigned int)
5614 (((85*height) >> 2)+((13*QuantumMargin) >> 1)+4);
5615 windows->widget.min_height=(
unsigned int)
5616 (((27*height) >> 1)+((13*QuantumMargin) >> 1)+4);
5617 if (windows->widget.height < windows->widget.min_height)
5618 windows->widget.height=windows->widget.min_height;
5619 XConstrainWindowPosition(display,&windows->widget);
5623 (void) CopyMagickString(windows->widget.name,
"Browse and Select a Font",
5625 status=XStringListToTextProperty(&windows->widget.name,1,&window_name);
5626 if (status != False)
5628 XSetWMName(display,windows->widget.id,&window_name);
5629 XSetWMIconName(display,windows->widget.id,&window_name);
5630 (void) XFree((
void *) window_name.value);
5632 window_changes.width=(int) windows->widget.width;
5633 window_changes.height=(
int) windows->widget.height;
5634 window_changes.x=windows->widget.x;
5635 window_changes.y=windows->widget.y;
5636 (void) XReconfigureWMWindow(display,windows->widget.id,
5637 windows->widget.screen,mask,&window_changes);
5638 (void) XMapRaised(display,windows->widget.id);
5639 windows->widget.mapped=MagickFalse;
5643 XGetWidgetInfo((
char *) NULL,&slider_info);
5644 XGetWidgetInfo((
char *) NULL,&north_info);
5645 XGetWidgetInfo((
char *) NULL,&south_info);
5646 XGetWidgetInfo((
char *) NULL,&expose_info);
5647 XGetWidgetInfo((
char *) NULL,&selection_info);
5649 delay=SuspendTime << 2;
5650 state=UpdateConfigurationState;
5653 if (state & UpdateConfigurationState)
5661 XGetWidgetInfo(CancelButtonText,&cancel_info);
5662 cancel_info.width=width;
5663 cancel_info.height=(
unsigned int) ((3*height) >> 1);
5665 (windows->widget.width-cancel_info.width-QuantumMargin-2);
5667 (windows->widget.height-cancel_info.height-QuantumMargin);
5668 XGetWidgetInfo(action,&action_info);
5669 action_info.width=width;
5670 action_info.height=(
unsigned int) ((3*height) >> 1);
5671 action_info.x=(int) windows->widget.width-(
int) action_info.width-
5672 (int) cancel_info.width-2*QuantumMargin-2;
5673 action_info.y=cancel_info.y;
5674 XGetWidgetInfo(BackButtonText,&back_info);
5675 back_info.width=width;
5676 back_info.height=(
unsigned int) ((3*height) >> 1);
5677 back_info.x=QuantumMargin;
5678 back_info.y=((5*QuantumMargin) >> 1)+height;
5679 XGetWidgetInfo(ResetButtonText,&reset_info);
5680 reset_info.width=width;
5681 reset_info.height=(
unsigned int) ((3*height) >> 1);
5682 reset_info.x=QuantumMargin;
5683 reset_info.y=back_info.y+back_info.height+QuantumMargin;
5687 XGetWidgetInfo(reply,&reply_info);
5688 reply_info.raised=MagickFalse;
5689 reply_info.bevel_width--;
5690 reply_info.width=windows->widget.width-width-((6*QuantumMargin) >> 1);
5691 reply_info.height=height << 1;
5692 reply_info.x=(int) (width+(QuantumMargin << 1));
5693 reply_info.y=action_info.y-(action_info.height << 1)-QuantumMargin;
5697 XGetWidgetInfo(reply,&mode_info);
5698 mode_info.bevel_width=0;
5699 mode_info.width=(
unsigned int)
5700 (action_info.x-reply_info.x-QuantumMargin);
5701 mode_info.height=action_info.height << 1;
5702 mode_info.x=reply_info.x;
5703 mode_info.y=action_info.y-action_info.height+action_info.bevel_width;
5707 XGetWidgetInfo((
char *) NULL,&scroll_info);
5708 scroll_info.bevel_width--;
5709 scroll_info.width=height;
5710 scroll_info.height=(
unsigned int)
5711 (reply_info.y-back_info.y-(QuantumMargin >> 1));
5712 scroll_info.x=reply_info.x+(reply_info.width-scroll_info.width);
5713 scroll_info.y=back_info.y-reply_info.bevel_width;
5714 scroll_info.raised=MagickFalse;
5715 scroll_info.trough=MagickTrue;
5716 north_info=scroll_info;
5717 north_info.raised=MagickTrue;
5718 north_info.width-=(north_info.bevel_width << 1);
5719 north_info.height=north_info.width-1;
5720 north_info.x+=north_info.bevel_width;
5721 north_info.y+=north_info.bevel_width;
5722 south_info=north_info;
5723 south_info.y=scroll_info.y+scroll_info.height-scroll_info.bevel_width-
5726 slider_info=north_info;
5728 slider_info.width-=2;
5729 slider_info.min_y=north_info.y+north_info.height+north_info.bevel_width+
5730 slider_info.bevel_width+2;
5731 slider_info.height=scroll_info.height-((slider_info.min_y-
5732 scroll_info.y+1) << 1)+4;
5733 visible_fonts=(
unsigned int) (scroll_info.height*
5734 PerceptibleReciprocal((
double) height+(height >> 3)));
5735 if (fonts > (
int) visible_fonts)
5736 slider_info.height=(visible_fonts*slider_info.height)/fonts;
5737 slider_info.max_y=south_info.y-south_info.bevel_width-
5738 slider_info.bevel_width-2;
5739 slider_info.x=scroll_info.x+slider_info.bevel_width+1;
5740 slider_info.y=slider_info.min_y;
5741 expose_info=scroll_info;
5742 expose_info.y=slider_info.y;
5746 XGetWidgetInfo((
char *) NULL,&list_info);
5747 list_info.raised=MagickFalse;
5748 list_info.bevel_width--;
5749 list_info.width=(
unsigned int)
5750 (scroll_info.x-reply_info.x-(QuantumMargin >> 1));
5751 list_info.height=scroll_info.height;
5752 list_info.x=reply_info.x;
5753 list_info.y=scroll_info.y;
5754 if (windows->widget.mapped == MagickFalse)
5755 state|=JumpListState;
5760 XGetWidgetInfo(text,&text_info);
5761 text_info.center=MagickFalse;
5762 text_info.width=reply_info.width;
5763 text_info.height=height;
5764 text_info.x=list_info.x-(QuantumMargin >> 1);
5765 text_info.y=QuantumMargin;
5769 XGetWidgetInfo((
char *) NULL,&selection_info);
5770 selection_info.center=MagickFalse;
5771 selection_info.width=list_info.width;
5772 selection_info.height=(
unsigned int) ((9*height) >> 3);
5773 selection_info.x=list_info.x;
5774 state&=(~UpdateConfigurationState);
5776 if (state & RedrawWidgetState)
5782 y=text_info.y+((text_info.height-height) >> 1)+font_info->ascent;
5783 (void) XDrawString(display,windows->widget.id,
5784 windows->widget.annotate_context,x,y,FontPatternText,
5785 Extent(FontPatternText));
5786 (void) CopyMagickString(text_info.text,glob_pattern,MaxTextExtent);
5787 XDrawWidgetText(display,&windows->widget,&text_info);
5788 XDrawBeveledButton(display,&windows->widget,&back_info);
5789 XDrawBeveledButton(display,&windows->widget,&reset_info);
5790 XDrawBeveledMatte(display,&windows->widget,&list_info);
5791 XDrawBeveledMatte(display,&windows->widget,&scroll_info);
5792 XDrawTriangleNorth(display,&windows->widget,&north_info);
5793 XDrawBeveledButton(display,&windows->widget,&slider_info);
5794 XDrawTriangleSouth(display,&windows->widget,&south_info);
5796 y=reply_info.y+((reply_info.height-height) >> 1)+font_info->ascent;
5797 (void) XDrawString(display,windows->widget.id,
5798 windows->widget.annotate_context,x,y,FontnameText,
5799 Extent(FontnameText));
5800 XDrawBeveledMatte(display,&windows->widget,&reply_info);
5801 XDrawMatteText(display,&windows->widget,&reply_info);
5802 XDrawBeveledButton(display,&windows->widget,&action_info);
5803 XDrawBeveledButton(display,&windows->widget,&cancel_info);
5804 XHighlightWidget(display,&windows->widget,BorderOffset,BorderOffset);
5805 selection_info.id=(~0);
5806 state|=RedrawActionState;
5807 state|=RedrawListState;
5808 state&=(~RedrawWidgetState);
5810 if (state & UpdateListState)
5821 checklist=XListFonts(display,glob_pattern,32767,&number_fonts);
5822 if (checklist == (
char **) NULL)
5824 if ((strchr(glob_pattern,
'*') == (
char *) NULL) &&
5825 (strchr(glob_pattern,
'?') == (
char *) NULL))
5830 (void) CopyMagickString(reply,glob_pattern,MaxTextExtent);
5831 (void) CopyMagickString(glob_pattern,back_pattern,MaxTextExtent);
5832 action_info.raised=MagickFalse;
5833 XDrawBeveledButton(display,&windows->widget,&action_info);
5836 (void) CopyMagickString(glob_pattern,back_pattern,MaxTextExtent);
5837 (void) XBell(display,0);
5840 if (number_fonts == 1)
5845 (void) CopyMagickString(reply,checklist[0],MaxTextExtent);
5846 (void) CopyMagickString(glob_pattern,back_pattern,MaxTextExtent);
5847 (void) XFreeFontNames(checklist);
5848 action_info.raised=MagickFalse;
5849 XDrawBeveledButton(display,&windows->widget,&action_info);
5854 (void) XFreeFontNames(listhead);
5855 fontlist=(
char **) RelinquishMagickMemory(fontlist);
5863 fontlist=(
char **) AcquireQuantumMemory((
size_t) fonts,
5865 if (fontlist == (
char **) NULL)
5867 XNoticeWidget(display,windows,
"MemoryAllocationFailed",
5868 "UnableToViewFonts");
5871 for (i=0; i < fonts; i++)
5872 fontlist[i]=listhead[i];
5873 qsort((
void *) fontlist,(
size_t) fonts,
sizeof(*fontlist),FontCompare);
5875 scroll_info.height-((slider_info.min_y-scroll_info.y+1) << 1)+1;
5876 if (fonts > (
int) visible_fonts)
5877 slider_info.height=(visible_fonts*slider_info.height)/fonts;
5878 slider_info.max_y=south_info.y-south_info.bevel_width-
5879 slider_info.bevel_width-2;
5881 slider_info.y=slider_info.min_y;
5882 expose_info.y=slider_info.y;
5883 selection_info.id=(~0);
5885 state|=RedrawListState;
5889 *reply_info.text=
'\0';
5890 reply_info.cursor=reply_info.text;
5891 (void) CopyMagickString(text_info.text,glob_pattern,MaxTextExtent);
5892 XDrawWidgetText(display,&windows->widget,&text_info);
5893 XDrawMatteText(display,&windows->widget,&reply_info);
5894 XDrawBeveledMatte(display,&windows->widget,&scroll_info);
5895 XDrawTriangleNorth(display,&windows->widget,&north_info);
5896 XDrawBeveledButton(display,&windows->widget,&slider_info);
5897 XDrawTriangleSouth(display,&windows->widget,&south_info);
5898 XHighlightWidget(display,&windows->widget,BorderOffset,BorderOffset);
5899 state&=(~UpdateListState);
5901 if (state & JumpListState)
5907 for (i=0; i < fonts; i++)
5908 if (LocaleCompare(fontlist[i],reply) >= 0)
5910 list_info.id=LocaleCompare(fontlist[i],reply) == 0 ? i : ~0;
5913 if ((i < slider_info.id) || (i >= (
int) (slider_info.id+visible_fonts)))
5914 slider_info.id=i-(visible_fonts >> 1);
5915 selection_info.id=(~0);
5916 state|=RedrawListState;
5917 state&=(~JumpListState);
5919 if (state & RedrawListState)
5924 if (slider_info.id >= (
int) (fonts-visible_fonts))
5925 slider_info.id=fonts-visible_fonts;
5926 if ((slider_info.id < 0) || (fonts <= (int) visible_fonts))
5928 slider_info.y=slider_info.min_y;
5931 slider_info.id*(slider_info.max_y-slider_info.min_y+1)/fonts;
5932 if (slider_info.id != selection_info.id)
5937 selection_info.id=slider_info.id;
5938 selection_info.y=list_info.y+(height >> 3)+2;
5939 for (i=0; i < (int) visible_fonts; i++)
5941 selection_info.raised=(slider_info.id+i) != list_info.id ?
5942 MagickTrue : MagickFalse;
5943 selection_info.text=(
char *) NULL;
5944 if ((slider_info.id+i) < fonts)
5945 selection_info.text=fontlist[slider_info.id+i];
5946 XDrawWidgetText(display,&windows->widget,&selection_info);
5947 selection_info.y+=(int) selection_info.height;
5952 if (slider_info.y > expose_info.y)
5954 expose_info.height=(
unsigned int) slider_info.y-expose_info.y;
5955 expose_info.y=slider_info.y-expose_info.height-
5956 slider_info.bevel_width-1;
5960 expose_info.height=(
unsigned int) expose_info.y-slider_info.y;
5961 expose_info.y=slider_info.y+slider_info.height+
5962 slider_info.bevel_width+1;
5964 XDrawTriangleNorth(display,&windows->widget,&north_info);
5965 XDrawMatte(display,&windows->widget,&expose_info);
5966 XDrawBeveledButton(display,&windows->widget,&slider_info);
5967 XDrawTriangleSouth(display,&windows->widget,&south_info);
5968 expose_info.y=slider_info.y;
5970 state&=(~RedrawListState);
5972 if (state & RedrawActionState)
5980 save_info=windows->widget.font_info;
5981 font_info=XLoadQueryFont(display,reply_info.text);
5982 if (font_info != (XFontStruct *) NULL)
5984 windows->widget.font_info=font_info;
5985 (void) XSetFont(display,windows->widget.widget_context,
5988 XDrawBeveledButton(display,&windows->widget,&mode_info);
5989 windows->widget.font_info=save_info;
5990 if (font_info != (XFontStruct *) NULL)
5992 (void) XSetFont(display,windows->widget.widget_context,
5993 windows->widget.font_info->fid);
5994 (void) XFreeFont(display,font_info);
5996 XHighlightWidget(display,&windows->widget,BorderOffset,BorderOffset);
5997 XDrawMatteText(display,&windows->widget,&reply_info);
5998 state&=(~RedrawActionState);
6003 if (north_info.raised && south_info.raised)
6004 (void) XIfEvent(display,&event,XScreenEvent,(
char *) windows);
6010 XDelay(display,delay);
6012 (void) XCheckIfEvent(display,&event,XScreenEvent,(
char *) windows);
6013 if (north_info.raised == MagickFalse)
6014 if (slider_info.id > 0)
6020 state|=RedrawListState;
6022 if (south_info.raised == MagickFalse)
6023 if (slider_info.id < fonts)
6029 state|=RedrawListState;
6031 if (event.type != ButtonRelease)
6038 if (MatteIsActive(slider_info,event.xbutton))
6043 slider_info.active=MagickTrue;
6046 if (MatteIsActive(north_info,event.xbutton))
6047 if (slider_info.id > 0)
6052 north_info.raised=MagickFalse;
6054 state|=RedrawListState;
6057 if (MatteIsActive(south_info,event.xbutton))
6058 if (slider_info.id < fonts)
6063 south_info.raised=MagickFalse;
6065 state|=RedrawListState;
6068 if (MatteIsActive(scroll_info,event.xbutton))
6073 if (event.xbutton.y < slider_info.y)
6074 slider_info.id-=(visible_fonts-1);
6076 slider_info.id+=(visible_fonts-1);
6077 state|=RedrawListState;
6080 if (MatteIsActive(list_info,event.xbutton))
6088 id=slider_info.id+(
event.xbutton.y-(list_info.y+(height >> 1))+1)/
6089 selection_info.height;
6090 if (
id >= (
int) fonts)
6092 (void) CopyMagickString(reply_info.text,fontlist[
id],MaxTextExtent);
6093 reply_info.highlight=MagickFalse;
6094 reply_info.marker=reply_info.text;
6095 reply_info.cursor=reply_info.text+Extent(reply_info.text);
6096 XDrawMatteText(display,&windows->widget,&reply_info);
6097 state|=RedrawActionState;
6098 if (
id == list_info.id)
6100 (void) CopyMagickString(glob_pattern,reply_info.text,
6102 state|=UpdateListState;
6104 selection_info.id=(~0);
6106 state|=RedrawListState;
6109 if (MatteIsActive(back_info,event.xbutton))
6114 back_info.raised=MagickFalse;
6115 XDrawBeveledButton(display,&windows->widget,&back_info);
6118 if (MatteIsActive(reset_info,event.xbutton))
6123 reset_info.raised=MagickFalse;
6124 XDrawBeveledButton(display,&windows->widget,&reset_info);
6127 if (MatteIsActive(action_info,event.xbutton))
6132 action_info.raised=MagickFalse;
6133 XDrawBeveledButton(display,&windows->widget,&action_info);
6136 if (MatteIsActive(cancel_info,event.xbutton))
6141 cancel_info.raised=MagickFalse;
6142 XDrawBeveledButton(display,&windows->widget,&cancel_info);
6145 if (MatteIsActive(reply_info,event.xbutton) == MagickFalse)
6147 if (event.xbutton.button != Button2)
6155 x=
event.xbutton.x-reply_info.x-(QuantumMargin >> 2);
6156 for (i=1; i <= Extent(reply_info.marker); i++)
6157 if (XTextWidth(font_info,reply_info.marker,i) > x)
6159 reply_info.cursor=reply_info.marker+i-1;
6160 if (event.xbutton.time > (click_time+DoubleClick))
6161 reply_info.highlight=MagickFalse;
6167 (
void) CopyMagickString(primary_selection,reply_info.text,
6169 (void) XSetSelectionOwner(display,XA_PRIMARY,windows->widget.id,
6170 event.xbutton.time);
6171 reply_info.highlight=XGetSelectionOwner(display,XA_PRIMARY) ==
6172 windows->widget.id ? MagickTrue : MagickFalse;
6174 XDrawMatteText(display,&windows->widget,&reply_info);
6175 click_time=
event.xbutton.time;
6181 (void) XConvertSelection(display,XA_PRIMARY,XA_STRING,XA_STRING,
6182 windows->widget.id,event.xbutton.time);
6187 if (windows->widget.mapped == MagickFalse)
6189 if (north_info.raised == MagickFalse)
6194 delay=SuspendTime << 2;
6195 north_info.raised=MagickTrue;
6196 XDrawTriangleNorth(display,&windows->widget,&north_info);
6198 if (south_info.raised == MagickFalse)
6203 delay=SuspendTime << 2;
6204 south_info.raised=MagickTrue;
6205 XDrawTriangleSouth(display,&windows->widget,&south_info);
6207 if (slider_info.active)
6212 slider_info.active=MagickFalse;
6215 if (back_info.raised == MagickFalse)
6217 if (event.xbutton.window == windows->widget.id)
6218 if (MatteIsActive(back_info,event.xbutton))
6220 (void) CopyMagickString(glob_pattern,back_pattern,
6222 state|=UpdateListState;
6224 back_info.raised=MagickTrue;
6225 XDrawBeveledButton(display,&windows->widget,&back_info);
6227 if (reset_info.raised == MagickFalse)
6229 if (event.xbutton.window == windows->widget.id)
6230 if (MatteIsActive(reset_info,event.xbutton))
6232 (void) CopyMagickString(back_pattern,glob_pattern,MaxTextExtent);
6233 (void) CopyMagickString(glob_pattern,reset_pattern,MaxTextExtent);
6234 state|=UpdateListState;
6236 reset_info.raised=MagickTrue;
6237 XDrawBeveledButton(display,&windows->widget,&reset_info);
6239 if (action_info.raised == MagickFalse)
6241 if (event.xbutton.window == windows->widget.id)
6243 if (MatteIsActive(action_info,event.xbutton))
6245 if (*reply_info.text ==
'\0')
6246 (void) XBell(display,0);
6251 action_info.raised=MagickTrue;
6252 XDrawBeveledButton(display,&windows->widget,&action_info);
6254 if (cancel_info.raised == MagickFalse)
6256 if (event.xbutton.window == windows->widget.id)
6257 if (MatteIsActive(cancel_info,event.xbutton))
6259 *reply_info.text=
'\0';
6262 cancel_info.raised=MagickTrue;
6263 XDrawBeveledButton(display,&windows->widget,&cancel_info);
6272 if (event.xclient.message_type != windows->wm_protocols)
6274 if (*event.xclient.data.l == (
int) windows->wm_take_focus)
6276 (void) XSetInputFocus(display,event.xclient.window,RevertToParent,
6277 (Time)
event.xclient.data.l[1]);
6280 if (*event.xclient.data.l != (
int) windows->wm_delete_window)
6282 if (event.xclient.window == windows->widget.id)
6284 *reply_info.text=
'\0';
6290 case ConfigureNotify:
6295 if (event.xconfigure.window != windows->widget.id)
6297 if ((event.xconfigure.width == (
int) windows->widget.width) &&
6298 (
event.xconfigure.height == (int) windows->widget.height))
6300 windows->widget.width=(
unsigned int)
6301 MagickMax(event.xconfigure.width,(
int) windows->widget.min_width);
6302 windows->widget.height=(
unsigned int)
6303 MagickMax(event.xconfigure.height,(
int) windows->widget.min_height);
6304 state|=UpdateConfigurationState;
6309 if (event.xcrossing.window != windows->widget.id)
6311 state&=(~InactiveWidgetState);
6316 if (event.xexpose.window != windows->widget.id)
6318 if (event.xexpose.count != 0)
6320 state|=RedrawWidgetState;
6326 command[MaxTextExtent];
6337 if (event.xkey.window != windows->widget.id)
6339 length=XLookupString((XKeyEvent *) &event.xkey,command,
6340 (
int)
sizeof(command),&key_symbol,(XComposeStatus *) NULL);
6341 *(command+length)=
'\0';
6342 if (AreaIsActive(scroll_info,event.xkey))
6347 switch ((
int) key_symbol)
6370 slider_info.id-=visible_fonts;
6376 slider_info.id+=visible_fonts;
6382 slider_info.id=fonts;
6386 state|=RedrawListState;
6389 if ((key_symbol == XK_Return) || (key_symbol == XK_KP_Enter))
6394 if (*reply_info.text ==
'\0')
6396 (void) CopyMagickString(back_pattern,glob_pattern,MaxTextExtent);
6397 (void) CopyMagickString(glob_pattern,reply_info.text,MaxTextExtent);
6398 state|=UpdateListState;
6401 if (key_symbol == XK_Control_L)
6403 state|=ControlState;
6406 if (state & ControlState)
6407 switch ((
int) key_symbol)
6415 *reply_info.text=
'\0';
6416 reply_info.cursor=reply_info.text;
6417 reply_info.marker=reply_info.text;
6418 reply_info.highlight=MagickFalse;
6424 XEditText(display,&reply_info,key_symbol,command,state);
6425 XDrawMatteText(display,&windows->widget,&reply_info);
6426 state|=JumpListState;
6432 command[MaxTextExtent];
6440 if (event.xkey.window != windows->widget.id)
6442 (void) XLookupString((XKeyEvent *) &
event.xkey,command,
6443 (int)
sizeof(command),&key_symbol,(XComposeStatus *) NULL);
6444 if (key_symbol == XK_Control_L)
6445 state&=(~ControlState);
6450 if (event.xcrossing.window != windows->widget.id)
6452 state|=InactiveWidgetState;
6466 while (XCheckMaskEvent(display,ButtonMotionMask,&event)) ;
6467 if (slider_info.active)
6472 slider_info.y=
event.xmotion.y-
6473 ((slider_info.height+slider_info.bevel_width) >> 1)+1;
6474 if (slider_info.y < slider_info.min_y)
6475 slider_info.y=slider_info.min_y;
6476 if (slider_info.y > slider_info.max_y)
6477 slider_info.y=slider_info.max_y;
6479 if (slider_info.y != slider_info.min_y)
6480 slider_info.id=(fonts*(slider_info.y-slider_info.min_y+1))/
6481 (slider_info.max_y-slider_info.min_y+1);
6482 state|=RedrawListState;
6485 if (state & InactiveWidgetState)
6487 if (back_info.raised == MatteIsActive(back_info,event.xmotion))
6492 back_info.raised=!back_info.raised;
6493 XDrawBeveledButton(display,&windows->widget,&back_info);
6496 if (reset_info.raised == MatteIsActive(reset_info,event.xmotion))
6501 reset_info.raised=!reset_info.raised;
6502 XDrawBeveledButton(display,&windows->widget,&reset_info);
6505 if (action_info.raised == MatteIsActive(action_info,event.xmotion))
6510 action_info.raised=action_info.raised == MagickFalse ?
6511 MagickTrue : MagickFalse;
6512 XDrawBeveledButton(display,&windows->widget,&action_info);
6515 if (cancel_info.raised == MatteIsActive(cancel_info,event.xmotion))
6520 cancel_info.raised=cancel_info.raised == MagickFalse ?
6521 MagickTrue : MagickFalse;
6522 XDrawBeveledButton(display,&windows->widget,&cancel_info);
6527 case SelectionClear:
6529 reply_info.highlight=MagickFalse;
6530 XDrawMatteText(display,&windows->widget,&reply_info);
6533 case SelectionNotify:
6551 if (event.xselection.property == (Atom) None)
6553 status=XGetWindowProperty(display,event.xselection.requestor,
6554 event.xselection.property,0L,2047L,MagickTrue,XA_STRING,&type,
6555 &format,&length,&after,&data);
6556 if ((status != Success) || (type != XA_STRING) || (format == 32) ||
6559 if ((Extent(reply_info.text)+length) >= (MaxTextExtent-1))
6560 (void) XBell(display,0);
6566 *(data+length)=
'\0';
6567 XEditText(display,&reply_info,(KeySym) XK_Insert,(
char *) data,
6569 XDrawMatteText(display,&windows->widget,&reply_info);
6570 state|=JumpListState;
6571 state|=RedrawActionState;
6573 (void) XFree((
void *) data);
6576 case SelectionRequest:
6581 XSelectionRequestEvent
6587 request=(&(
event.xselectionrequest));
6588 (void) XChangeProperty(request->display,request->requestor,
6589 request->property,request->target,8,PropModeReplace,
6590 (
unsigned char *) primary_selection,Extent(primary_selection));
6591 notify.type=SelectionNotify;
6592 notify.display=request->display;
6593 notify.requestor=request->requestor;
6594 notify.selection=request->selection;
6595 notify.target=request->target;
6596 notify.time=request->time;
6597 if (request->property == None)
6598 notify.property=request->target;
6600 notify.property=request->property;
6601 (void) XSendEvent(request->display,request->requestor,False,0,
6602 (XEvent *) ¬ify);
6607 }
while ((state & ExitState) == 0);
6608 XSetCursorState(display,windows,MagickFalse);
6609 (void) XWithdrawWindow(display,windows->widget.id,windows->widget.screen);
6610 XCheckRefreshWindows(display,windows);
6614 (void) XFreeFontNames(listhead);
6615 fontlist=(
char **) RelinquishMagickMemory(fontlist);
6648 MagickExport
void XInfoWidget(Display *display,XWindows *windows,
6649 const char *activity)
6665 assert(display != (Display *) NULL);
6666 assert(windows != (XWindows *) NULL);
6667 assert(activity != (
char *) NULL);
6668 if (IsEventLogging() != MagickFalse)
6669 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"...");
6670 font_info=windows->info.font_info;
6671 width=WidgetTextWidth(font_info,(
char *) activity)+((3*QuantumMargin) >> 1)+4;
6672 height=(
unsigned int) (((6*(font_info->ascent+font_info->descent)) >> 2)+4);
6673 if ((windows->info.width != width) || (windows->info.height != height))
6678 windows->info.width=width;
6679 windows->info.height=height;
6680 window_changes.width=(int) width;
6681 window_changes.height=(int) height;
6682 (void) XReconfigureWMWindow(display,windows->info.id,windows->info.screen,
6683 (
unsigned int) (CWWidth | CWHeight),&window_changes);
6685 if (windows->info.mapped == MagickFalse)
6687 (void) XMapRaised(display,windows->info.id);
6688 windows->info.mapped=MagickTrue;
6693 height=(
unsigned int) (font_info->ascent+font_info->descent);
6694 XGetWidgetInfo(activity,&monitor_info);
6695 monitor_info.bevel_width--;
6696 margin=monitor_info.bevel_width+((windows->info.height-height) >> 1)-2;
6697 monitor_info.center=MagickFalse;
6698 monitor_info.x=(int) margin;
6699 monitor_info.y=(int) margin;
6700 monitor_info.width=windows->info.width-(margin << 1);
6701 monitor_info.height=windows->info.height-(margin << 1)+1;
6705 monitor_info.raised=MagickFalse;
6706 XDrawBeveledMatte(display,&windows->info,&monitor_info);
6707 monitor_info.raised=MagickTrue;
6708 XDrawWidgetText(display,&windows->info,&monitor_info);
6750 MagickExport
void XListBrowserWidget(Display *display,XWindows *windows,
6751 XWindowInfo *window_info,
const char *
const *list,
const char *action,
6752 const char *query,
char *reply)
6754 #define CancelButtonText "Cancel"
6757 primary_selection[MaxTextExtent];
6765 static MagickStatusType
6766 mask = (MagickStatusType) (CWWidth | CWHeight | CWX | CWY);
6810 assert(display != (Display *) NULL);
6811 assert(windows != (XWindows *) NULL);
6812 assert(window_info != (XWindowInfo *) NULL);
6813 assert(list != (
const char **) NULL);
6814 assert(action != (
char *) NULL);
6815 assert(query != (
char *) NULL);
6816 assert(reply != (
char *) NULL);
6817 if (IsEventLogging() != MagickFalse)
6818 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",action);
6819 XSetCursorState(display,windows,MagickTrue);
6820 XCheckRefreshWindows(display,windows);
6821 if (list == (
const char **) NULL)
6823 XNoticeWidget(display,windows,
"No text to browse:",(
char *) NULL);
6826 for (entries=0; ; entries++)
6827 if (list[entries] == (
char *) NULL)
6832 font_info=window_info->font_info;
6833 text_width=WidgetTextWidth(font_info,(
char *) query);
6834 for (i=0; i < (int) entries; i++)
6835 if (WidgetTextWidth(font_info,(
char *) list[i]) > text_width)
6836 text_width=WidgetTextWidth(font_info,(
char *) list[i]);
6837 width=WidgetTextWidth(font_info,(
char *) action);
6838 if (WidgetTextWidth(font_info,CancelButtonText) > width)
6839 width=WidgetTextWidth(font_info,CancelButtonText);
6840 width+=QuantumMargin;
6841 height=(
unsigned int) (font_info->ascent+font_info->descent);
6845 window_info->width=(
unsigned int) MagickMin((
int) text_width,(int)
6846 MaxTextWidth)+((9*QuantumMargin) >> 1);
6847 window_info->min_width=(
unsigned int) (MinTextWidth+4*QuantumMargin);
6848 if (window_info->width < window_info->min_width)
6849 window_info->width=window_info->min_width;
6850 window_info->height=(
unsigned int)
6851 (((81*height) >> 2)+((13*QuantumMargin) >> 1)+4);
6852 window_info->min_height=(
unsigned int)
6853 (((23*height) >> 1)+((13*QuantumMargin) >> 1)+4);
6854 if (window_info->height < window_info->min_height)
6855 window_info->height=window_info->min_height;
6856 XConstrainWindowPosition(display,window_info);
6860 (void) CopyMagickString(window_info->name,
"Browse",MaxTextExtent);
6861 status=XStringListToTextProperty(&window_info->name,1,&window_name);
6862 if (status != False)
6864 XSetWMName(display,window_info->id,&window_name);
6865 XSetWMIconName(display,windows->widget.id,&window_name);
6866 (void) XFree((
void *) window_name.value);
6868 window_changes.width=(int) window_info->width;
6869 window_changes.height=(
int) window_info->height;
6870 window_changes.x=window_info->x;
6871 window_changes.y=window_info->y;
6872 (void) XReconfigureWMWindow(display,window_info->id,window_info->screen,mask,
6874 (void) XMapRaised(display,window_info->id);
6875 window_info->mapped=MagickFalse;
6879 XGetWidgetInfo((
char *) NULL,&slider_info);
6880 XGetWidgetInfo((
char *) NULL,&north_info);
6881 XGetWidgetInfo((
char *) NULL,&south_info);
6882 XGetWidgetInfo((
char *) NULL,&expose_info);
6883 XGetWidgetInfo((
char *) NULL,&selection_info);
6885 delay=SuspendTime << 2;
6886 state=UpdateConfigurationState;
6889 if (state & UpdateConfigurationState)
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;
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;
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=(
unsigned int) (scroll_info.height*
6950 PerceptibleReciprocal((
double) height+(height >> 3)));
6951 if (entries > visible_entries)
6952 slider_info.height=(visible_entries*slider_info.height)/entries;
6953 slider_info.max_y=south_info.y-south_info.bevel_width-
6954 slider_info.bevel_width-2;
6955 slider_info.x=scroll_info.x+slider_info.bevel_width+1;
6956 slider_info.y=slider_info.min_y;
6957 expose_info=scroll_info;
6958 expose_info.y=slider_info.y;
6962 XGetWidgetInfo((
char *) NULL,&list_info);
6963 list_info.raised=MagickFalse;
6964 list_info.bevel_width--;
6965 list_info.width=(
unsigned int)
6966 (scroll_info.x-reply_info.x-(QuantumMargin >> 1));
6967 list_info.height=scroll_info.height;
6968 list_info.x=reply_info.x;
6969 list_info.y=scroll_info.y;
6970 if (window_info->mapped == MagickFalse)
6971 for (i=0; i < (int) entries; i++)
6972 if (LocaleCompare(list[i],reply) == 0)
6975 slider_info.id=i-(visible_entries >> 1);
6976 if (slider_info.id < 0)
6982 XGetWidgetInfo(query,&text_info);
6983 text_info.width=reply_info.width;
6984 text_info.height=height;
6985 text_info.x=list_info.x-(QuantumMargin >> 1);
6986 text_info.y=QuantumMargin;
6990 XGetWidgetInfo((
char *) NULL,&selection_info);
6991 selection_info.center=MagickFalse;
6992 selection_info.width=list_info.width;
6993 selection_info.height=(
unsigned int) ((9*height) >> 3);
6994 selection_info.x=list_info.x;
6995 state&=(~UpdateConfigurationState);
6997 if (state & RedrawWidgetState)
7002 XDrawWidgetText(display,window_info,&text_info);
7003 XDrawBeveledMatte(display,window_info,&list_info);
7004 XDrawBeveledMatte(display,window_info,&scroll_info);
7005 XDrawTriangleNorth(display,window_info,&north_info);
7006 XDrawBeveledButton(display,window_info,&slider_info);
7007 XDrawTriangleSouth(display,window_info,&south_info);
7008 XDrawBeveledMatte(display,window_info,&reply_info);
7009 XDrawMatteText(display,window_info,&reply_info);
7010 XDrawBeveledButton(display,window_info,&action_info);
7011 XDrawBeveledButton(display,window_info,&cancel_info);
7012 XHighlightWidget(display,window_info,BorderOffset,BorderOffset);
7013 selection_info.id=(~0);
7014 state|=RedrawActionState;
7015 state|=RedrawListState;
7016 state&=(~RedrawWidgetState);
7018 if (state & RedrawListState)
7023 if (slider_info.id >= (
int) (entries-visible_entries))
7024 slider_info.id=(int) (entries-visible_entries);
7025 if ((slider_info.id < 0) || (entries <= visible_entries))
7027 slider_info.y=slider_info.min_y;
7030 slider_info.id*(slider_info.max_y-slider_info.min_y+1)/entries;
7031 if (slider_info.id != selection_info.id)
7036 selection_info.id=slider_info.id;
7037 selection_info.y=list_info.y+(height >> 3)+2;
7038 for (i=0; i < (int) visible_entries; i++)
7040 selection_info.raised=(slider_info.id+i) != list_info.id ?
7041 MagickTrue : MagickFalse;
7042 selection_info.text=(
char *) NULL;
7043 if ((slider_info.id+i) < (int) entries)
7044 selection_info.text=(
char *) list[slider_info.id+i];
7045 XDrawWidgetText(display,window_info,&selection_info);
7046 selection_info.y+=(int) selection_info.height;
7051 if (slider_info.y > expose_info.y)
7053 expose_info.height=(
unsigned int) slider_info.y-expose_info.y;
7054 expose_info.y=slider_info.y-expose_info.height-
7055 slider_info.bevel_width-1;
7059 expose_info.height=(
unsigned int) expose_info.y-slider_info.y;
7060 expose_info.y=slider_info.y+slider_info.height+
7061 slider_info.bevel_width+1;
7063 XDrawTriangleNorth(display,window_info,&north_info);
7064 XDrawMatte(display,window_info,&expose_info);
7065 XDrawBeveledButton(display,window_info,&slider_info);
7066 XDrawTriangleSouth(display,window_info,&south_info);
7067 expose_info.y=slider_info.y;
7069 state&=(~RedrawListState);
7074 if (north_info.raised && south_info.raised)
7075 (void) XIfEvent(display,&event,XScreenEvent,(
char *) windows);
7081 XDelay(display,delay);
7083 (void) XCheckIfEvent(display,&event,XScreenEvent,(
char *) windows);
7084 if (north_info.raised == MagickFalse)
7085 if (slider_info.id > 0)
7091 state|=RedrawListState;
7093 if (south_info.raised == MagickFalse)
7094 if (slider_info.id < (
int) entries)
7100 state|=RedrawListState;
7102 if (event.type != ButtonRelease)
7109 if (MatteIsActive(slider_info,event.xbutton))
7114 slider_info.active=MagickTrue;
7117 if (MatteIsActive(north_info,event.xbutton))
7118 if (slider_info.id > 0)
7123 north_info.raised=MagickFalse;
7125 state|=RedrawListState;
7128 if (MatteIsActive(south_info,event.xbutton))
7129 if (slider_info.id < (
int) entries)
7134 south_info.raised=MagickFalse;
7136 state|=RedrawListState;
7139 if (MatteIsActive(scroll_info,event.xbutton))
7144 if (event.xbutton.y < slider_info.y)
7145 slider_info.id-=(visible_entries-1);
7147 slider_info.id+=(visible_entries-1);
7148 state|=RedrawListState;
7151 if (MatteIsActive(list_info,event.xbutton))
7159 id=slider_info.id+(
event.xbutton.y-(list_info.y+(height >> 1))+1)/
7160 selection_info.height;
7161 if (
id >= (
int) entries)
7163 (void) CopyMagickString(reply_info.text,list[
id],MaxTextExtent);
7164 reply_info.highlight=MagickFalse;
7165 reply_info.marker=reply_info.text;
7166 reply_info.cursor=reply_info.text+Extent(reply_info.text);
7167 XDrawMatteText(display,window_info,&reply_info);
7168 selection_info.id=(~0);
7169 if (
id == list_info.id)
7171 action_info.raised=MagickFalse;
7172 XDrawBeveledButton(display,window_info,&action_info);
7176 state|=RedrawListState;
7179 if (MatteIsActive(action_info,event.xbutton))
7184 action_info.raised=MagickFalse;
7185 XDrawBeveledButton(display,window_info,&action_info);
7188 if (MatteIsActive(cancel_info,event.xbutton))
7193 cancel_info.raised=MagickFalse;
7194 XDrawBeveledButton(display,window_info,&cancel_info);
7197 if (MatteIsActive(reply_info,event.xbutton) == MagickFalse)
7199 if (event.xbutton.button != Button2)
7207 x=
event.xbutton.x-reply_info.x-(QuantumMargin >> 2);
7208 for (i=1; i <= Extent(reply_info.marker); i++)
7209 if (XTextWidth(font_info,reply_info.marker,i) > x)
7211 reply_info.cursor=reply_info.marker+i-1;
7212 if (event.xbutton.time > (click_time+DoubleClick))
7213 reply_info.highlight=MagickFalse;
7219 (
void) CopyMagickString(primary_selection,reply_info.text,
7221 (void) XSetSelectionOwner(display,XA_PRIMARY,window_info->id,
7222 event.xbutton.time);
7223 reply_info.highlight=XGetSelectionOwner(display,XA_PRIMARY) ==
7224 window_info->id ? MagickTrue : MagickFalse;
7226 XDrawMatteText(display,window_info,&reply_info);
7227 click_time=
event.xbutton.time;
7233 (void) XConvertSelection(display,XA_PRIMARY,XA_STRING,XA_STRING,
7234 window_info->id,event.xbutton.time);
7239 if (window_info->mapped == MagickFalse)
7241 if (north_info.raised == MagickFalse)
7246 delay=SuspendTime << 2;
7247 north_info.raised=MagickTrue;
7248 XDrawTriangleNorth(display,window_info,&north_info);
7250 if (south_info.raised == MagickFalse)
7255 delay=SuspendTime << 2;
7256 south_info.raised=MagickTrue;
7257 XDrawTriangleSouth(display,window_info,&south_info);
7259 if (slider_info.active)
7264 slider_info.active=MagickFalse;
7267 if (action_info.raised == MagickFalse)
7269 if (event.xbutton.window == window_info->id)
7271 if (MatteIsActive(action_info,event.xbutton))
7273 if (*reply_info.text ==
'\0')
7274 (void) XBell(display,0);
7279 action_info.raised=MagickTrue;
7280 XDrawBeveledButton(display,window_info,&action_info);
7282 if (cancel_info.raised == MagickFalse)
7284 if (event.xbutton.window == window_info->id)
7285 if (MatteIsActive(cancel_info,event.xbutton))
7287 *reply_info.text=
'\0';
7290 cancel_info.raised=MagickTrue;
7291 XDrawBeveledButton(display,window_info,&cancel_info);
7293 if (MatteIsActive(reply_info,event.xbutton) == MagickFalse)
7302 if (event.xclient.message_type != windows->wm_protocols)
7304 if (*event.xclient.data.l == (
int) windows->wm_take_focus)
7306 (void) XSetInputFocus(display,event.xclient.window,RevertToParent,
7307 (Time)
event.xclient.data.l[1]);
7310 if (*event.xclient.data.l != (
int) windows->wm_delete_window)
7312 if (event.xclient.window == window_info->id)
7314 *reply_info.text=
'\0';
7320 case ConfigureNotify:
7325 if (event.xconfigure.window != window_info->id)
7327 if ((event.xconfigure.width == (
int) window_info->width) &&
7328 (
event.xconfigure.height == (int) window_info->height))
7330 window_info->width=(
unsigned int)
7331 MagickMax(event.xconfigure.width,(
int) window_info->min_width);
7332 window_info->height=(
unsigned int)
7333 MagickMax(event.xconfigure.height,(
int) window_info->min_height);
7334 state|=UpdateConfigurationState;
7339 if (event.xcrossing.window != window_info->id)
7341 state&=(~InactiveWidgetState);
7346 if (event.xexpose.window != window_info->id)
7348 if (event.xexpose.count != 0)
7350 state|=RedrawWidgetState;
7356 command[MaxTextExtent];
7367 if (event.xkey.window != window_info->id)
7369 length=XLookupString((XKeyEvent *) &event.xkey,command,
7370 (
int)
sizeof(command),&key_symbol,(XComposeStatus *) NULL);
7371 *(command+length)=
'\0';
7372 if (AreaIsActive(scroll_info,event.xkey))
7377 switch ((
int) key_symbol)
7400 slider_info.id-=visible_entries;
7406 slider_info.id+=visible_entries;
7412 slider_info.id=(int) entries;
7416 state|=RedrawListState;
7419 if ((key_symbol == XK_Return) || (key_symbol == XK_KP_Enter))
7424 if (*reply_info.text ==
'\0')
7426 action_info.raised=MagickFalse;
7427 XDrawBeveledButton(display,window_info,&action_info);
7431 if (key_symbol == XK_Control_L)
7433 state|=ControlState;
7436 if (state & ControlState)
7437 switch ((
int) key_symbol)
7445 *reply_info.text=
'\0';
7446 reply_info.cursor=reply_info.text;
7447 reply_info.marker=reply_info.text;
7448 reply_info.highlight=MagickFalse;
7454 XEditText(display,&reply_info,key_symbol,command,state);
7455 XDrawMatteText(display,window_info,&reply_info);
7461 command[MaxTextExtent];
7469 if (event.xkey.window != window_info->id)
7471 (void) XLookupString((XKeyEvent *) &
event.xkey,command,
7472 (int)
sizeof(command),&key_symbol,(XComposeStatus *) NULL);
7473 if (key_symbol == XK_Control_L)
7474 state&=(~ControlState);
7479 if (event.xcrossing.window != window_info->id)
7481 state|=InactiveWidgetState;
7495 while (XCheckMaskEvent(display,ButtonMotionMask,&event)) ;
7496 if (slider_info.active)
7501 slider_info.y=
event.xmotion.y-
7502 ((slider_info.height+slider_info.bevel_width) >> 1)+1;
7503 if (slider_info.y < slider_info.min_y)
7504 slider_info.y=slider_info.min_y;
7505 if (slider_info.y > slider_info.max_y)
7506 slider_info.y=slider_info.max_y;
7508 if (slider_info.y != slider_info.min_y)
7509 slider_info.id=(int) ((entries*(slider_info.y-
7510 slider_info.min_y+1))/(slider_info.max_y-slider_info.min_y+1));
7511 state|=RedrawListState;
7514 if (state & InactiveWidgetState)
7516 if (action_info.raised == MatteIsActive(action_info,event.xmotion))
7521 action_info.raised=action_info.raised == MagickFalse ?
7522 MagickTrue : MagickFalse;
7523 XDrawBeveledButton(display,window_info,&action_info);
7526 if (cancel_info.raised == MatteIsActive(cancel_info,event.xmotion))
7531 cancel_info.raised=cancel_info.raised == MagickFalse ?
7532 MagickTrue : MagickFalse;
7533 XDrawBeveledButton(display,window_info,&cancel_info);
7538 case SelectionClear:
7540 reply_info.highlight=MagickFalse;
7541 XDrawMatteText(display,window_info,&reply_info);
7544 case SelectionNotify:
7562 if (event.xselection.property == (Atom) None)
7564 status=XGetWindowProperty(display,
7565 event.xselection.requestor,event.xselection.property,0L,2047L,
7566 MagickTrue,XA_STRING,&type,&format,&length,&after,&data);
7567 if ((status != Success) || (type != XA_STRING) || (format == 32) ||
7570 if ((Extent(reply_info.text)+length) >= (MaxTextExtent-1))
7571 (void) XBell(display,0);
7577 *(data+length)=
'\0';
7578 XEditText(display,&reply_info,(KeySym) XK_Insert,(
char *) data,
7580 XDrawMatteText(display,window_info,&reply_info);
7581 state|=RedrawActionState;
7583 (void) XFree((
void *) data);
7586 case SelectionRequest:
7591 XSelectionRequestEvent
7594 if (reply_info.highlight == MagickFalse)
7599 request=(&(
event.xselectionrequest));
7600 (void) XChangeProperty(request->display,request->requestor,
7601 request->property,request->target,8,PropModeReplace,
7602 (
unsigned char *) primary_selection,Extent(primary_selection));
7603 notify.type=SelectionNotify;
7604 notify.send_event=MagickTrue;
7605 notify.display=request->display;
7606 notify.requestor=request->requestor;
7607 notify.selection=request->selection;
7608 notify.target=request->target;
7609 notify.time=request->time;
7610 if (request->property == None)
7611 notify.property=request->target;
7613 notify.property=request->property;
7614 (void) XSendEvent(request->display,request->requestor,False,NoEventMask,
7615 (XEvent *) ¬ify);
7620 }
while ((state & ExitState) == 0);
7621 XSetCursorState(display,windows,MagickFalse);
7622 (void) XWithdrawWindow(display,window_info->id,window_info->screen);
7623 XCheckRefreshWindows(display,windows);
7664 MagickExport
int XMenuWidget(Display *display,XWindows *windows,
7665 const char *title,
const char *
const *selections,
char *item)
7691 XSetWindowAttributes
7705 assert(display != (Display *) NULL);
7706 assert(windows != (XWindows *) NULL);
7707 assert(title != (
char *) NULL);
7708 assert(selections != (
const char **) NULL);
7709 assert(item != (
char *) NULL);
7710 if (IsEventLogging() != MagickFalse)
7711 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",title);
7712 font_info=windows->widget.font_info;
7713 windows->widget.width=submenu_info.active == 0 ?
7714 WidgetTextWidth(font_info,(
char *) title) : 0;
7715 for (
id=0; selections[id] != (
char *) NULL;
id++)
7717 width=WidgetTextWidth(font_info,(
char *) selections[
id]);
7718 if (width > windows->widget.width)
7719 windows->widget.width=width;
7721 number_selections=(
unsigned int)
id;
7722 XGetWidgetInfo((
char *) NULL,&menu_info);
7723 title_height=(
unsigned int) (submenu_info.active == 0 ?
7724 (3*(font_info->descent+font_info->ascent) >> 1)+5 : 2);
7725 width=WidgetTextWidth(font_info,(
char *) title);
7726 height=(
unsigned int) ((3*(font_info->ascent+font_info->descent)) >> 1);
7730 windows->widget.width+=QuantumMargin+(menu_info.bevel_width << 1);
7731 top_offset=title_height+menu_info.bevel_width-1;
7732 windows->widget.height=top_offset+number_selections*height+4;
7733 windows->widget.min_width=windows->widget.width;
7734 windows->widget.min_height=windows->widget.height;
7735 XQueryPosition(display,windows->widget.root,&x,&y);
7736 windows->widget.x=x-(QuantumMargin >> 1);
7737 if (submenu_info.active != 0)
7740 windows->command.x+windows->command.width-QuantumMargin;
7741 toggle_info.raised=MagickTrue;
7742 XDrawTriangleEast(display,&windows->command,&toggle_info);
7744 windows->widget.y=submenu_info.active == 0 ? y-(int)
7745 ((3*title_height) >> 2) : y;
7746 if (submenu_info.active != 0)
7747 windows->widget.y=windows->command.y+submenu_info.y;
7748 XConstrainWindowPosition(display,&windows->widget);
7752 window_attributes.override_redirect=MagickTrue;
7753 (void) XChangeWindowAttributes(display,windows->widget.id,
7754 (
size_t) CWOverrideRedirect,&window_attributes);
7755 window_changes.width=(int) windows->widget.width;
7756 window_changes.height=(
int) windows->widget.height;
7757 window_changes.x=windows->widget.x;
7758 window_changes.y=windows->widget.y;
7759 (void) XReconfigureWMWindow(display,windows->widget.id,windows->widget.screen,
7760 (
unsigned int) (CWWidth | CWHeight | CWX | CWY),&window_changes);
7761 (void) XMapRaised(display,windows->widget.id);
7762 windows->widget.mapped=MagickFalse;
7766 selection_info.height=height;
7767 cursor=XCreateFontCursor(display,XC_right_ptr);
7768 (void) XCheckDefineCursor(display,windows->image.id,cursor);
7769 (void) XCheckDefineCursor(display,windows->command.id,cursor);
7770 (void) XCheckDefineCursor(display,windows->widget.id,cursor);
7771 state=UpdateConfigurationState;
7774 if (state & UpdateConfigurationState)
7779 XGetWidgetInfo((
char *) NULL,&menu_info);
7780 menu_info.bevel_width--;
7781 menu_info.width=windows->widget.width-((menu_info.bevel_width) << 1);
7782 menu_info.height=windows->widget.height-((menu_info.bevel_width) << 1);
7783 menu_info.x=(int) menu_info.bevel_width;
7784 menu_info.y=(
int) menu_info.bevel_width;
7785 XGetWidgetInfo((
char *) NULL,&selection_info);
7786 selection_info.center=MagickFalse;
7787 selection_info.width=menu_info.width;
7788 selection_info.height=height;
7789 selection_info.x=menu_info.x;
7790 highlight_info=selection_info;
7791 highlight_info.bevel_width--;
7792 highlight_info.width-=(highlight_info.bevel_width << 1);
7793 highlight_info.height-=(highlight_info.bevel_width << 1);
7794 highlight_info.x+=highlight_info.bevel_width;
7795 state&=(~UpdateConfigurationState);
7797 if (state & RedrawWidgetState)
7802 if (submenu_info.active == 0)
7804 y=(int) title_height;
7805 XSetBevelColor(display,&windows->widget,MagickFalse);
7806 (void) XDrawLine(display,windows->widget.id,
7807 windows->widget.widget_context,selection_info.x,y-1,
7808 (
int) selection_info.width,y-1);
7809 XSetBevelColor(display,&windows->widget,MagickTrue);
7810 (void) XDrawLine(display,windows->widget.id,
7811 windows->widget.widget_context,selection_info.x,y,
7812 (
int) selection_info.width,y);
7813 (void) XSetFillStyle(display,windows->widget.widget_context,
7819 selection_info.center=MagickTrue;
7820 selection_info.y=(int) menu_info.bevel_width;
7821 selection_info.text=(
char *) title;
7822 if (submenu_info.active == 0)
7823 XDrawWidgetText(display,&windows->widget,&selection_info);
7824 selection_info.center=MagickFalse;
7825 selection_info.y=(int) top_offset;
7826 for (
id=0;
id < (int) number_selections;
id++)
7828 selection_info.text=(
char *) selections[
id];
7829 XDrawWidgetText(display,&windows->widget,&selection_info);
7830 highlight_info.y=selection_info.y+highlight_info.bevel_width;
7831 if (
id == selection_info.id)
7832 XDrawBevel(display,&windows->widget,&highlight_info);
7833 selection_info.y+=(int) selection_info.height;
7835 XDrawBevel(display,&windows->widget,&menu_info);
7836 state&=(~RedrawWidgetState);
7838 if (number_selections > 2)
7843 y=(int) (top_offset+selection_info.height*(number_selections-1));
7844 XSetBevelColor(display,&windows->widget,MagickFalse);
7845 (void) XDrawLine(display,windows->widget.id,
7846 windows->widget.widget_context,selection_info.x,y-1,
7847 (
int) selection_info.width,y-1);
7848 XSetBevelColor(display,&windows->widget,MagickTrue);
7849 (void) XDrawLine(display,windows->widget.id,
7850 windows->widget.widget_context,selection_info.x,y,
7851 (
int) selection_info.width,y);
7852 (void) XSetFillStyle(display,windows->widget.widget_context,FillSolid);
7857 (void) XIfEvent(display,&event,XScreenEvent,(
char *) windows);
7862 if (event.xbutton.window != windows->widget.id)
7867 if (event.xbutton.window == windows->command.id)
7868 (void) XPutBackEvent(display,&event);
7869 selection_info.id=(~0);
7874 state&=(~InactiveWidgetState);
7875 if (selection_info.height == 0)
7877 id=(
event.xbutton.y-top_offset)/(
int) selection_info.height;
7878 selection_info.id=id;
7879 if ((
id < 0) || (
id >= (int) number_selections))
7884 selection_info.y=(int) (top_offset+
id*selection_info.height);
7885 selection_info.text=(
char *) selections[
id];
7886 XDrawWidgetText(display,&windows->widget,&selection_info);
7887 highlight_info.y=selection_info.y+highlight_info.bevel_width;
7888 XDrawBevel(display,&windows->widget,&highlight_info);
7893 if (windows->widget.mapped == MagickFalse)
7895 if (event.xbutton.window == windows->command.id)
7896 if ((state & InactiveWidgetState) == 0)
7901 XSetCursorState(display,windows,MagickFalse);
7906 case ConfigureNotify:
7911 if (event.xconfigure.window != windows->widget.id)
7913 if ((event.xconfigure.width == (
int) windows->widget.width) &&
7914 (event.xconfigure.height == (
int) windows->widget.height))
7916 windows->widget.width=(
unsigned int)
7917 MagickMax(event.xconfigure.width,(
int) windows->widget.min_width);
7918 windows->widget.height=(
unsigned int)
7919 MagickMax(event.xconfigure.height,(
int) windows->widget.min_height);
7920 state|=UpdateConfigurationState;
7925 if (event.xcrossing.window != windows->widget.id)
7927 if (event.xcrossing.state == 0)
7929 state&=(~InactiveWidgetState);
7930 if (selection_info.height == 0)
7932 id=((
event.xcrossing.y-top_offset)/(
int) selection_info.height);
7933 if ((selection_info.id >= 0) &&
7934 (selection_info.id < (int) number_selections))
7939 if (
id == selection_info.id)
7941 selection_info.y=(int)
7942 (top_offset+selection_info.id*selection_info.height);
7943 selection_info.text=(
char *) selections[selection_info.id];
7944 XDrawWidgetText(display,&windows->widget,&selection_info);
7946 if ((
id < 0) || (
id >= (int) number_selections))
7951 selection_info.id=id;
7952 selection_info.y=(int)
7953 (top_offset+selection_info.id*selection_info.height);
7954 selection_info.text=(
char *) selections[selection_info.id];
7955 XDrawWidgetText(display,&windows->widget,&selection_info);
7956 highlight_info.y=selection_info.y+highlight_info.bevel_width;
7957 XDrawBevel(display,&windows->widget,&highlight_info);
7962 if (event.xexpose.window != windows->widget.id)
7964 if (event.xexpose.count != 0)
7966 state|=RedrawWidgetState;
7971 if (event.xcrossing.window != windows->widget.id)
7973 state|=InactiveWidgetState;
7974 id=selection_info.id;
7975 if ((
id < 0) || (
id >= (
int) number_selections))
7980 selection_info.y=(int) (top_offset+
id*selection_info.height);
7981 selection_info.id=(~0);
7982 selection_info.text=(
char *) selections[
id];
7983 XDrawWidgetText(display,&windows->widget,&selection_info);
7991 while (XCheckMaskEvent(display,ButtonMotionMask,&event)) ;
7992 if (submenu_info.active != 0)
7993 if (event.xmotion.window == windows->command.id)
7995 if ((state & InactiveWidgetState) == 0)
7997 if (MatteIsActive(submenu_info,event.xmotion) == MagickFalse)
7999 selection_info.id=(~0);
8006 if (WindowIsActive(windows->command,event.xmotion))
8008 selection_info.id=(~0);
8014 if (event.xmotion.window != windows->widget.id)
8016 if (state & InactiveWidgetState)
8018 if (selection_info.height == 0)
8020 id=(
event.xmotion.y-top_offset)/(
int) selection_info.height;
8021 if ((selection_info.id >= 0) &&
8022 (selection_info.id < (int) number_selections))
8027 if (
id == selection_info.id)
8029 selection_info.y=(int)
8030 (top_offset+selection_info.id*selection_info.height);
8031 selection_info.text=(
char *) selections[selection_info.id];
8032 XDrawWidgetText(display,&windows->widget,&selection_info);
8034 selection_info.id=id;
8035 if ((
id < 0) || (
id >= (int) number_selections))
8040 selection_info.y=(int) (top_offset+
id*selection_info.height);
8041 selection_info.text=(
char *) selections[
id];
8042 XDrawWidgetText(display,&windows->widget,&selection_info);
8043 highlight_info.y=selection_info.y+highlight_info.bevel_width;
8044 XDrawBevel(display,&windows->widget,&highlight_info);
8050 }
while ((state & ExitState) == 0);
8051 (void) XFreeCursor(display,cursor);
8052 window_attributes.override_redirect=MagickFalse;
8053 (void) XChangeWindowAttributes(display,windows->widget.id,
8054 (
size_t) CWOverrideRedirect,&window_attributes);
8055 (void) XWithdrawWindow(display,windows->widget.id,windows->widget.screen);
8056 XCheckRefreshWindows(display,windows);
8057 if (submenu_info.active != 0)
8059 submenu_info.active=MagickFalse;
8060 toggle_info.raised=MagickFalse;
8061 XDrawTriangleEast(display,&windows->command,&toggle_info);
8063 if ((selection_info.id < 0) || (selection_info.id >= (
int) number_selections))
8065 (void) CopyMagickString(item,selections[selection_info.id],MaxTextExtent);
8066 return(selection_info.id);
8101 MagickExport
void XNoticeWidget(Display *display,XWindows *windows,
8102 const char *reason,
const char *description)
8104 #define DismissButtonText "Dismiss"
8145 assert(display != (Display *) NULL);
8146 assert(windows != (XWindows *) NULL);
8147 assert(reason != (
char *) NULL);
8148 if (IsEventLogging() != MagickFalse)
8149 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",reason);
8150 XDelay(display,SuspendTime << 3);
8151 XSetCursorState(display,windows,MagickTrue);
8152 XCheckRefreshWindows(display,windows);
8153 font_info=windows->widget.font_info;
8154 width=WidgetTextWidth(font_info,DismissButtonText);
8155 text=GetLocaleExceptionMessage(XServerError,reason);
8156 if (text != (
char *) NULL)
8157 if (WidgetTextWidth(font_info,(
char *) text) > width)
8158 width=WidgetTextWidth(font_info,(
char *) text);
8159 if (description != (
char *) NULL)
8161 text=GetLocaleExceptionMessage(XServerError,description);
8162 if (text != (
char *) NULL)
8163 if (WidgetTextWidth(font_info,(
char *) text) > width)
8164 width=WidgetTextWidth(font_info,(
char *) text);
8166 height=(
unsigned int) (font_info->ascent+font_info->descent);
8170 windows->widget.width=width+4*QuantumMargin;
8171 windows->widget.min_width=width+QuantumMargin;
8172 if (windows->widget.width < windows->widget.min_width)
8173 windows->widget.width=windows->widget.min_width;
8174 windows->widget.height=(
unsigned int) (12*height);
8175 windows->widget.min_height=(
unsigned int) (7*height);
8176 if (windows->widget.height < windows->widget.min_height)
8177 windows->widget.height=windows->widget.min_height;
8178 XConstrainWindowPosition(display,&windows->widget);
8182 (void) CopyMagickString(windows->widget.name,
"Notice",MaxTextExtent);
8183 status=XStringListToTextProperty(&windows->widget.name,1,&window_name);
8184 if (status != False)
8186 XSetWMName(display,windows->widget.id,&window_name);
8187 XSetWMIconName(display,windows->widget.id,&window_name);
8188 (void) XFree((
void *) window_name.value);
8190 window_changes.width=(int) windows->widget.width;
8191 window_changes.height=(
int) windows->widget.height;
8192 window_changes.x=windows->widget.x;
8193 window_changes.y=windows->widget.y;
8194 (void) XReconfigureWMWindow(display,windows->widget.id,windows->widget.screen,
8195 (
unsigned int) (CWWidth | CWHeight | CWX | CWY),&window_changes);
8196 (void) XMapRaised(display,windows->widget.id);
8197 windows->widget.mapped=MagickFalse;
8198 (void) XBell(display,0);
8202 timer=GetMagickTime()+Timeout;
8203 state=UpdateConfigurationState;
8206 if (GetMagickTime() > timer)
8208 if (state & UpdateConfigurationState)
8213 XGetWidgetInfo(DismissButtonText,&dismiss_info);
8214 dismiss_info.width=(
unsigned int) QuantumMargin+
8215 WidgetTextWidth(font_info,DismissButtonText);
8216 dismiss_info.height=(
unsigned int) ((3*height) >> 1);
8217 dismiss_info.x=(int)
8218 ((windows->widget.width >> 1)-(dismiss_info.width >> 1));
8219 dismiss_info.y=(int)
8220 (windows->widget.height-(dismiss_info.height << 1));
8221 state&=(~UpdateConfigurationState);
8223 if (state & RedrawWidgetState)
8228 width=WidgetTextWidth(font_info,(
char *) reason);
8229 x=(int) ((windows->widget.width >> 1)-(width >> 1));
8230 y=(int) ((windows->widget.height >> 1)-(height << 1));
8231 (void) XDrawString(display,windows->widget.id,
8232 windows->widget.annotate_context,x,y,(
char *) reason,Extent(reason));
8233 if (description != (
char *) NULL)
8235 width=WidgetTextWidth(font_info,(
char *) description);
8236 x=(int) ((windows->widget.width >> 1)-(width >> 1));
8238 (void) XDrawString(display,windows->widget.id,
8239 windows->widget.annotate_context,x,y,(
char *) description,
8240 Extent(description));
8242 XDrawBeveledButton(display,&windows->widget,&dismiss_info);
8243 XHighlightWidget(display,&windows->widget,BorderOffset,BorderOffset);
8244 state&=(~RedrawWidgetState);
8249 if (XCheckIfEvent(display,&event,XScreenEvent,(
char *) windows) == MagickFalse)
8254 XDelay(display,SuspendTime << 2);
8261 if (MatteIsActive(dismiss_info,event.xbutton))
8266 dismiss_info.raised=MagickFalse;
8267 XDrawBeveledButton(display,&windows->widget,&dismiss_info);
8274 if (windows->widget.mapped == MagickFalse)
8276 if (dismiss_info.raised == MagickFalse)
8278 if (event.xbutton.window == windows->widget.id)
8279 if (MatteIsActive(dismiss_info,event.xbutton))
8281 dismiss_info.raised=MagickTrue;
8282 XDrawBeveledButton(display,&windows->widget,&dismiss_info);
8291 if (event.xclient.message_type != windows->wm_protocols)
8293 if (*event.xclient.data.l == (
int) windows->wm_take_focus)
8295 (void) XSetInputFocus(display,event.xclient.window,RevertToParent,
8296 (Time)
event.xclient.data.l[1]);
8299 if (*event.xclient.data.l != (
int) windows->wm_delete_window)
8301 if (event.xclient.window == windows->widget.id)
8308 case ConfigureNotify:
8313 if (event.xconfigure.window != windows->widget.id)
8315 if ((event.xconfigure.width == (
int) windows->widget.width) &&
8316 (
event.xconfigure.height == (int) windows->widget.height))
8318 windows->widget.width=(
unsigned int)
8319 MagickMax(event.xconfigure.width,(
int) windows->widget.min_width);
8320 windows->widget.height=(
unsigned int)
8321 MagickMax(event.xconfigure.height,(
int) windows->widget.min_height);
8322 state|=UpdateConfigurationState;
8327 if (event.xcrossing.window != windows->widget.id)
8329 state&=(~InactiveWidgetState);
8334 if (event.xexpose.window != windows->widget.id)
8336 if (event.xexpose.count != 0)
8338 state|=RedrawWidgetState;
8344 command[MaxTextExtent];
8352 if (event.xkey.window != windows->widget.id)
8354 (void) XLookupString((XKeyEvent *) &
event.xkey,command,
8355 (int)
sizeof(command),&key_symbol,(XComposeStatus *) NULL);
8356 if ((key_symbol == XK_Return) || (key_symbol == XK_KP_Enter))
8358 dismiss_info.raised=MagickFalse;
8359 XDrawBeveledButton(display,&windows->widget,&dismiss_info);
8367 if (event.xcrossing.window != windows->widget.id)
8369 state|=InactiveWidgetState;
8377 while (XCheckMaskEvent(display,ButtonMotionMask,&event)) ;
8378 if (state & InactiveWidgetState)
8380 if (dismiss_info.raised == MatteIsActive(dismiss_info,event.xmotion))
8385 dismiss_info.raised=
8386 dismiss_info.raised == MagickFalse ? MagickTrue : MagickFalse;
8387 XDrawBeveledButton(display,&windows->widget,&dismiss_info);
8395 }
while ((state & ExitState) == 0);
8396 XSetCursorState(display,windows,MagickFalse);
8397 (void) XWithdrawWindow(display,windows->widget.id,windows->widget.screen);
8398 XCheckRefreshWindows(display,windows);
8431 MagickExport MagickBooleanType XPreferencesWidget(Display *display,
8432 XResourceInfo *resource_info,XWindows *windows)
8434 #define ApplyButtonText "Apply"
8435 #define CacheButtonText "%lu mega-bytes of memory in the undo edit cache "
8436 #define CancelButtonText "Cancel"
8437 #define NumberPreferences 8
8442 "display image centered on a backdrop",
8443 "confirm on program exit",
8444 "confirm on image edits",
8445 "correct image for display gamma",
8446 "display warning messages",
8447 "apply Floyd/Steinberg error diffusion to image",
8448 "use a shared colormap for colormapped X visuals",
8449 "display images as an X server pixmap"
8453 cache[MaxTextExtent];
8486 preferences_info[NumberPreferences];
8494 assert(display != (Display *) NULL);
8495 assert(resource_info != (XResourceInfo *) NULL);
8496 assert(windows != (XWindows *) NULL);
8497 if (IsEventLogging() != MagickFalse)
8498 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"...");
8499 XCheckRefreshWindows(display,windows);
8500 font_info=windows->widget.font_info;
8501 text_width=WidgetTextWidth(font_info,CacheButtonText);
8502 for (i=0; i < NumberPreferences; i++)
8503 if (WidgetTextWidth(font_info,(
char *) Preferences[i]) > text_width)
8504 text_width=WidgetTextWidth(font_info,(
char *) Preferences[i]);
8505 width=WidgetTextWidth(font_info,ApplyButtonText);
8506 if (WidgetTextWidth(font_info,CancelButtonText) > width)
8507 width=WidgetTextWidth(font_info,CancelButtonText);
8508 width+=(
unsigned int) QuantumMargin;
8509 height=(
unsigned int) (font_info->ascent+font_info->descent);
8513 windows->widget.width=(
unsigned int) (MagickMax((
int) (width << 1),
8514 (
int) text_width)+6*QuantumMargin);
8515 windows->widget.min_width=(width << 1)+QuantumMargin;
8516 if (windows->widget.width < windows->widget.min_width)
8517 windows->widget.width=windows->widget.min_width;
8518 windows->widget.height=(
unsigned int)
8519 (7*height+NumberPreferences*(height+(QuantumMargin >> 1)));
8520 windows->widget.min_height=(
unsigned int)
8521 (7*height+NumberPreferences*(height+(QuantumMargin >> 1)));
8522 if (windows->widget.height < windows->widget.min_height)
8523 windows->widget.height=windows->widget.min_height;
8524 XConstrainWindowPosition(display,&windows->widget);
8528 (void) CopyMagickString(windows->widget.name,
"Preferences",MaxTextExtent);
8529 status=XStringListToTextProperty(&windows->widget.name,1,&window_name);
8530 if (status != False)
8532 XSetWMName(display,windows->widget.id,&window_name);
8533 XSetWMIconName(display,windows->widget.id,&window_name);
8534 (void) XFree((
void *) window_name.value);
8536 window_changes.width=(int) windows->widget.width;
8537 window_changes.height=(
int) windows->widget.height;
8538 window_changes.x=windows->widget.x;
8539 window_changes.y=windows->widget.y;
8540 (void) XReconfigureWMWindow(display,windows->widget.id,windows->widget.screen,
8541 (
unsigned int) (CWWidth | CWHeight | CWX | CWY),&window_changes);
8542 (void) XMapRaised(display,windows->widget.id);
8543 windows->widget.mapped=MagickFalse;
8547 state=UpdateConfigurationState;
8548 XSetCursorState(display,windows,MagickTrue);
8551 if (state & UpdateConfigurationState)
8556 XGetWidgetInfo(CancelButtonText,&cancel_info);
8557 cancel_info.width=width;
8558 cancel_info.height=(
unsigned int) (3*height) >> 1;
8559 cancel_info.x=(int) windows->widget.width-cancel_info.width-
8560 (QuantumMargin << 1);
8561 cancel_info.y=(int) windows->widget.height-
8562 cancel_info.height-QuantumMargin;
8563 XGetWidgetInfo(ApplyButtonText,&apply_info);
8564 apply_info.width=width;
8565 apply_info.height=(
unsigned int) (3*height) >> 1;
8566 apply_info.x=QuantumMargin << 1;
8567 apply_info.y=cancel_info.y;
8568 y=(int) (height << 1);
8569 for (i=0; i < NumberPreferences; i++)
8571 XGetWidgetInfo(Preferences[i],&preferences_info[i]);
8572 preferences_info[i].bevel_width--;
8573 preferences_info[i].width=(
unsigned int) QuantumMargin >> 1;
8574 preferences_info[i].height=(
unsigned int) QuantumMargin >> 1;
8575 preferences_info[i].x=QuantumMargin << 1;
8576 preferences_info[i].y=y;
8577 y+=height+(QuantumMargin >> 1);
8579 preferences_info[0].raised=resource_info->backdrop ==
8580 MagickFalse ? MagickTrue : MagickFalse;
8581 preferences_info[1].raised=resource_info->confirm_exit ==
8582 MagickFalse ? MagickTrue : MagickFalse;
8583 preferences_info[2].raised=resource_info->confirm_edit ==
8584 MagickFalse ? MagickTrue : MagickFalse;
8585 preferences_info[3].raised=resource_info->gamma_correct ==
8586 MagickFalse ? MagickTrue : MagickFalse;
8587 preferences_info[4].raised=resource_info->display_warnings ==
8588 MagickFalse ? MagickTrue : MagickFalse;
8589 preferences_info[5].raised=resource_info->quantize_info->dither ==
8590 MagickFalse ? MagickTrue : MagickFalse;
8591 preferences_info[6].raised=resource_info->colormap !=
8592 SharedColormap ? MagickTrue : MagickFalse;
8593 preferences_info[7].raised=resource_info->use_pixmap ==
8594 MagickFalse ? MagickTrue : MagickFalse;
8595 (void) FormatLocaleString(cache,MaxTextExtent,CacheButtonText,
8596 (
unsigned long) resource_info->undo_cache);
8597 XGetWidgetInfo(cache,&cache_info);
8598 cache_info.bevel_width--;
8599 cache_info.width=(
unsigned int) QuantumMargin >> 1;
8600 cache_info.height=(
unsigned int) QuantumMargin >> 1;
8601 cache_info.x=QuantumMargin << 1;
8603 state&=(~UpdateConfigurationState);
8605 if (state & RedrawWidgetState)
8610 XDrawBeveledButton(display,&windows->widget,&apply_info);
8611 XDrawBeveledButton(display,&windows->widget,&cancel_info);
8612 for (i=0; i < NumberPreferences; i++)
8613 XDrawBeveledButton(display,&windows->widget,&preferences_info[i]);
8614 XDrawTriangleEast(display,&windows->widget,&cache_info);
8615 XHighlightWidget(display,&windows->widget,BorderOffset,BorderOffset);
8616 state&=(~RedrawWidgetState);
8621 (void) XIfEvent(display,&event,XScreenEvent,(
char *) windows);
8626 if (MatteIsActive(apply_info,event.xbutton))
8631 apply_info.raised=MagickFalse;
8632 XDrawBeveledButton(display,&windows->widget,&apply_info);
8635 if (MatteIsActive(cancel_info,event.xbutton))
8640 cancel_info.raised=MagickFalse;
8641 XDrawBeveledButton(display,&windows->widget,&cancel_info);
8644 for (i=0; i < NumberPreferences; i++)
8645 if (MatteIsActive(preferences_info[i],event.xbutton))
8650 preferences_info[i].raised=preferences_info[i].raised ==
8651 MagickFalse ? MagickTrue : MagickFalse;
8652 XDrawBeveledButton(display,&windows->widget,&preferences_info[i]);
8655 if (MatteIsActive(cache_info,event.xbutton))
8660 x=cache_info.x+cache_info.width+cache_info.bevel_width+
8661 (QuantumMargin >> 1);
8662 y=cache_info.y+((cache_info.height-height) >> 1);
8663 width=WidgetTextWidth(font_info,cache);
8664 (void) XClearArea(display,windows->widget.id,x,y,width,height,
8666 resource_info->undo_cache<<=1;
8667 if (resource_info->undo_cache > 256)
8668 resource_info->undo_cache=1;
8669 (void) FormatLocaleString(cache,MaxTextExtent,CacheButtonText,
8670 (
unsigned long) resource_info->undo_cache);
8671 cache_info.raised=MagickFalse;
8672 XDrawTriangleEast(display,&windows->widget,&cache_info);
8679 if (windows->widget.mapped == MagickFalse)
8681 if (apply_info.raised == MagickFalse)
8683 if (event.xbutton.window == windows->widget.id)
8684 if (MatteIsActive(apply_info,event.xbutton))
8686 apply_info.raised=MagickTrue;
8687 XDrawBeveledButton(display,&windows->widget,&apply_info);
8688 apply_info.raised=MagickFalse;
8690 if (cancel_info.raised == MagickFalse)
8692 if (event.xbutton.window == windows->widget.id)
8693 if (MatteIsActive(cancel_info,event.xbutton))
8695 cancel_info.raised=MagickTrue;
8696 XDrawBeveledButton(display,&windows->widget,&cancel_info);
8698 if (cache_info.raised == MagickFalse)
8700 cache_info.raised=MagickTrue;
8701 XDrawTriangleEast(display,&windows->widget,&cache_info);
8710 if (event.xclient.message_type != windows->wm_protocols)
8712 if (*event.xclient.data.l == (
int) windows->wm_take_focus)
8714 (void) XSetInputFocus(display,event.xclient.window,RevertToParent,
8715 (Time)
event.xclient.data.l[1]);
8718 if (*event.xclient.data.l != (
int) windows->wm_delete_window)
8720 if (event.xclient.window == windows->widget.id)
8727 case ConfigureNotify:
8732 if (event.xconfigure.window != windows->widget.id)
8734 if ((event.xconfigure.width == (
int) windows->widget.width) &&
8735 (
event.xconfigure.height == (int) windows->widget.height))
8737 windows->widget.width=(
unsigned int)
8738 MagickMax(event.xconfigure.width,(
int) windows->widget.min_width);
8739 windows->widget.height=(
unsigned int)
8740 MagickMax(event.xconfigure.height,(
int) windows->widget.min_height);
8741 state|=UpdateConfigurationState;
8746 if (event.xcrossing.window != windows->widget.id)
8748 state&=(~InactiveWidgetState);
8753 if (event.xexpose.window != windows->widget.id)
8755 if (event.xexpose.count != 0)
8757 state|=RedrawWidgetState;
8763 command[MaxTextExtent];
8771 if (event.xkey.window != windows->widget.id)
8773 (void) XLookupString((XKeyEvent *) &
event.xkey,command,
8774 (int)
sizeof(command),&key_symbol,(XComposeStatus *) NULL);
8775 if ((key_symbol == XK_Return) || (key_symbol == XK_KP_Enter))
8777 apply_info.raised=MagickFalse;
8778 XDrawBeveledButton(display,&windows->widget,&apply_info);
8786 if (event.xcrossing.window != windows->widget.id)
8788 state|=InactiveWidgetState;
8796 while (XCheckMaskEvent(display,ButtonMotionMask,&event)) ;
8797 if (state & InactiveWidgetState)
8799 if (apply_info.raised == MatteIsActive(apply_info,event.xmotion))
8805 apply_info.raised == MagickFalse ? MagickTrue : MagickFalse;
8806 XDrawBeveledButton(display,&windows->widget,&apply_info);
8809 if (cancel_info.raised == MatteIsActive(cancel_info,event.xmotion))
8815 cancel_info.raised == MagickFalse ? MagickTrue : MagickFalse;
8816 XDrawBeveledButton(display,&windows->widget,&cancel_info);
8824 }
while ((state & ExitState) == 0);
8825 XSetCursorState(display,windows,MagickFalse);
8826 (void) XWithdrawWindow(display,windows->widget.id,windows->widget.screen);
8827 XCheckRefreshWindows(display,windows);
8828 if (apply_info.raised)
8829 return(MagickFalse);
8833 resource_info->backdrop=
8834 preferences_info[0].raised == MagickFalse ? MagickTrue : MagickFalse;
8835 resource_info->confirm_exit=
8836 preferences_info[1].raised == MagickFalse ? MagickTrue : MagickFalse;
8837 resource_info->confirm_edit=
8838 preferences_info[2].raised == MagickFalse ? MagickTrue : MagickFalse;
8839 resource_info->gamma_correct=
8840 preferences_info[3].raised == MagickFalse ? MagickTrue : MagickFalse;
8841 resource_info->display_warnings=
8842 preferences_info[4].raised == MagickFalse ? MagickTrue : MagickFalse;
8843 resource_info->quantize_info->dither=
8844 preferences_info[5].raised == MagickFalse ? MagickTrue : MagickFalse;
8845 resource_info->colormap=SharedColormap;
8846 if (preferences_info[6].raised)
8847 resource_info->colormap=PrivateColormap;
8848 resource_info->use_pixmap=
8849 preferences_info[7].raised == MagickFalse ? MagickTrue : MagickFalse;
8850 XUserPreferences(resource_info);
8890 MagickExport
void XProgressMonitorWidget(Display *display,XWindows *windows,
8891 const char *task,
const MagickOffsetType offset,
const MagickSizeType span)
8899 assert(display != (Display *) NULL);
8900 assert(windows != (XWindows *) NULL);
8901 assert(task != (
const char *) NULL);
8902 if (IsEventLogging() != MagickFalse)
8903 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",task);
8909 while (XCheckTypedWindowEvent(display,windows->command.id,Expose,&event))
8910 (
void) XCommandWidget(display,windows,(
const char *
const *) NULL,&event);
8911 while (XCheckTypedWindowEvent(display,windows->image.id,Expose,&event))
8912 XRefreshWindow(display,&windows->image,&event);
8913 while (XCheckTypedWindowEvent(display,windows->info.id,Expose,&event))
8914 if (monitor_info.text != (
char *) NULL)
8915 XInfoWidget(display,windows,monitor_info.text);
8919 if ((windows->info.mapped == MagickFalse) || (task != monitor_info.text))
8920 XInfoWidget(display,windows,task);
8921 width=(
unsigned int) (((offset+1)*(windows->info.width-
8922 (2*monitor_info.x)))/span);
8923 if (width < monitor_info.width)
8925 monitor_info.raised=MagickTrue;
8926 XDrawWidgetText(display,&windows->info,&monitor_info);
8927 monitor_info.raised=MagickFalse;
8929 monitor_info.width=width;
8930 XDrawWidgetText(display,&windows->info,&monitor_info);
8931 (void) XFlush(display);
8970 MagickExport
void XTextViewWidget(Display *display,
8971 const XResourceInfo *resource_info,XWindows *windows,
8972 const MagickBooleanType mono,
const char *title,
const char **textlist)
8974 #define DismissButtonText "Dismiss"
8977 primary_selection[MaxTextExtent];
8982 static MagickStatusType
8983 mask = (MagickStatusType) (CWWidth | CWHeight | CWX | CWY);
9025 assert(display != (Display *) NULL);
9026 assert(resource_info != (XResourceInfo *) NULL);
9027 assert(windows != (XWindows *) NULL);
9028 assert(title != (
const char *) NULL);
9029 assert(textlist != (
const char **) NULL);
9030 if (IsEventLogging() != MagickFalse)
9031 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",title);
9032 XSetCursorState(display,windows,MagickTrue);
9033 XCheckRefreshWindows(display,windows);
9034 if (textlist == (
const char **) NULL)
9036 XNoticeWidget(display,windows,
"No text to view:",(
char *) NULL);
9042 font_info=windows->widget.font_info;
9043 text_info=(XFontStruct *) NULL;
9044 if (mono != MagickFalse)
9045 text_info=XBestFont(display,resource_info,MagickTrue);
9046 if (text_info == (XFontStruct *) NULL)
9047 text_info=windows->widget.font_info;
9049 for (i=0; textlist[i] != (
char *) NULL; i++)
9050 if (WidgetTextWidth(text_info,(
char *) textlist[i]) > text_width)
9051 text_width=(
unsigned int) XTextWidth(text_info,(
char *) textlist[i],
9052 MagickMin(Extent(textlist[i]),160));
9053 lines=(
unsigned int) i;
9054 width=WidgetTextWidth(font_info,DismissButtonText);
9055 width+=QuantumMargin;
9056 height=(
unsigned int) (text_info->ascent+text_info->descent);
9060 windows->widget.width=(
unsigned int) (MagickMin((
int) text_width,
9061 (int) MaxTextWidth)+5*QuantumMargin);
9062 windows->widget.min_width=(
unsigned int) (MinTextWidth+4*QuantumMargin);
9063 if (windows->widget.width < windows->widget.min_width)
9064 windows->widget.width=windows->widget.min_width;
9065 windows->widget.height=(
unsigned int) (MagickMin(MagickMax((
int) lines,3),32)*
9066 height+((13*height) >> 1)+((9*QuantumMargin) >> 1));
9067 windows->widget.min_height=(
unsigned int) (3*height+((13*height) >> 1)+((9*
9068 QuantumMargin) >> 1));
9069 if (windows->widget.height < windows->widget.min_height)
9070 windows->widget.height=windows->widget.min_height;
9071 XConstrainWindowPosition(display,&windows->widget);
9075 (void) CopyMagickString(windows->widget.name,title,MaxTextExtent);
9076 status=XStringListToTextProperty(&windows->widget.name,1,&window_name);
9077 if (status != False)
9079 XSetWMName(display,windows->widget.id,&window_name);
9080 XSetWMIconName(display,windows->widget.id,&window_name);
9081 (void) XFree((
void *) window_name.value);
9083 window_changes.width=(int) windows->widget.width;
9084 window_changes.height=(
int) windows->widget.height;
9085 window_changes.x=windows->widget.x;
9086 window_changes.y=windows->widget.y;
9087 (void) XReconfigureWMWindow(display,windows->widget.id,
9088 windows->widget.screen,(
unsigned int) mask,&window_changes);
9089 (void) XMapRaised(display,windows->widget.id);
9090 windows->widget.mapped=MagickFalse;
9094 XGetWidgetInfo((
char *) NULL,&slider_info);
9095 XGetWidgetInfo((
char *) NULL,&north_info);
9096 XGetWidgetInfo((
char *) NULL,&south_info);
9097 XGetWidgetInfo((
char *) NULL,&expose_info);
9098 XGetWidgetInfo((
char *) NULL,&selection_info);
9100 delay=SuspendTime << 2;
9101 height=(
unsigned int) (font_info->ascent+font_info->descent);
9102 state=UpdateConfigurationState;
9105 if (state & UpdateConfigurationState)
9113 XGetWidgetInfo(DismissButtonText,&dismiss_info);
9114 dismiss_info.width=width;
9115 dismiss_info.height=(
unsigned int) ((3*height) >> 1);
9116 dismiss_info.x=(int) windows->widget.width-dismiss_info.width-
9118 dismiss_info.y=(
int) windows->widget.height-dismiss_info.height-
9123 XGetWidgetInfo((
char *) NULL,&scroll_info);
9124 scroll_info.bevel_width--;
9125 scroll_info.width=height;
9126 scroll_info.height=(
unsigned int) (dismiss_info.y-((5*QuantumMargin) >>
9128 scroll_info.x=(int) windows->widget.width-QuantumMargin-
9130 scroll_info.y=(3*QuantumMargin) >> 1;
9131 scroll_info.raised=MagickFalse;
9132 scroll_info.trough=MagickTrue;
9133 north_info=scroll_info;
9134 north_info.raised=MagickTrue;
9135 north_info.width-=(north_info.bevel_width << 1);
9136 north_info.height=north_info.width-1;
9137 north_info.x+=north_info.bevel_width;
9138 north_info.y+=north_info.bevel_width;
9139 south_info=north_info;
9140 south_info.y=scroll_info.y+scroll_info.height-scroll_info.bevel_width-
9143 slider_info=north_info;
9145 slider_info.width-=2;
9146 slider_info.min_y=north_info.y+north_info.height+north_info.bevel_width+
9147 slider_info.bevel_width+2;
9148 slider_info.height=scroll_info.height-((slider_info.min_y-
9149 scroll_info.y+1) << 1)+4;
9150 visible_lines=(
unsigned int) (scroll_info.height*PerceptibleReciprocal(
9151 (
double) text_info->ascent+text_info->descent+((text_info->ascent+
9152 text_info->descent) >> 3)));
9153 if (lines > visible_lines)
9154 slider_info.height=(
unsigned int) (visible_lines*slider_info.height)/
9156 slider_info.max_y=south_info.y-south_info.bevel_width-
9157 slider_info.bevel_width-2;
9158 slider_info.x=scroll_info.x+slider_info.bevel_width+1;
9159 slider_info.y=slider_info.min_y;
9160 expose_info=scroll_info;
9161 expose_info.y=slider_info.y;
9165 XGetWidgetInfo((
char *) NULL,&list_info);
9166 list_info.raised=MagickFalse;
9167 list_info.bevel_width--;
9168 list_info.width=(
unsigned int) scroll_info.x-((3*QuantumMargin) >> 1);
9169 list_info.height=scroll_info.height;
9170 list_info.x=QuantumMargin;
9171 list_info.y=scroll_info.y;
9175 XGetWidgetInfo((
char *) NULL,&selection_info);
9176 selection_info.center=MagickFalse;
9177 selection_info.width=list_info.width;
9178 selection_info.height=(
unsigned int)
9179 (9*(text_info->ascent+text_info->descent)) >> 3;
9180 selection_info.x=list_info.x;
9181 state&=(~UpdateConfigurationState);
9183 if (state & RedrawWidgetState)
9188 XDrawBeveledMatte(display,&windows->widget,&list_info);
9189 XDrawBeveledMatte(display,&windows->widget,&scroll_info);
9190 XDrawTriangleNorth(display,&windows->widget,&north_info);
9191 XDrawBeveledButton(display,&windows->widget,&slider_info);
9192 XDrawTriangleSouth(display,&windows->widget,&south_info);
9193 XDrawBeveledButton(display,&windows->widget,&dismiss_info);
9194 XHighlightWidget(display,&windows->widget,BorderOffset,BorderOffset);
9195 selection_info.id=(~0);
9196 state|=RedrawListState;
9197 state&=(~RedrawWidgetState);
9199 if (state & RedrawListState)
9204 if (slider_info.id >= (
int) (lines-visible_lines))
9205 slider_info.id=(int) lines-visible_lines;
9206 if ((slider_info.id < 0) || (lines <= visible_lines))
9208 slider_info.y=slider_info.min_y;
9211 slider_info.id*(slider_info.max_y-slider_info.min_y+1)/lines;
9212 if (slider_info.id != selection_info.id)
9217 windows->widget.font_info=text_info;
9218 (void) XSetFont(display,windows->widget.annotate_context,
9220 (void) XSetFont(display,windows->widget.highlight_context,
9222 selection_info.id=slider_info.id;
9223 selection_info.y=list_info.y+(height >> 3)+2;
9224 for (i=0; i < (int) visible_lines; i++)
9226 selection_info.raised=
9227 (slider_info.id+i) != list_info.id ? MagickTrue : MagickFalse;
9228 selection_info.text=(
char *) NULL;
9229 if ((slider_info.id+i) < (int) lines)
9230 selection_info.text=(
char *) textlist[slider_info.id+i];
9231 XDrawWidgetText(display,&windows->widget,&selection_info);
9232 selection_info.y+=(int) selection_info.height;
9234 windows->widget.font_info=font_info;
9235 (void) XSetFont(display,windows->widget.annotate_context,
9237 (void) XSetFont(display,windows->widget.highlight_context,
9242 if (slider_info.y > expose_info.y)
9244 expose_info.height=(
unsigned int) slider_info.y-expose_info.y;
9245 expose_info.y=slider_info.y-expose_info.height-
9246 slider_info.bevel_width-1;
9250 expose_info.height=(
unsigned int) expose_info.y-slider_info.y;
9251 expose_info.y=slider_info.y+slider_info.height+
9252 slider_info.bevel_width+1;
9254 XDrawTriangleNorth(display,&windows->widget,&north_info);
9255 XDrawMatte(display,&windows->widget,&expose_info);
9256 XDrawBeveledButton(display,&windows->widget,&slider_info);
9257 XDrawTriangleSouth(display,&windows->widget,&south_info);
9258 expose_info.y=slider_info.y;
9260 state&=(~RedrawListState);
9265 if (north_info.raised && south_info.raised)
9266 (void) XIfEvent(display,&event,XScreenEvent,(
char *) windows);
9272 XDelay(display,delay);
9274 (void) XCheckIfEvent(display,&event,XScreenEvent,(
char *) windows);
9275 if (north_info.raised == MagickFalse)
9276 if (slider_info.id > 0)
9282 state|=RedrawListState;
9284 if (south_info.raised == MagickFalse)
9285 if (slider_info.id < (
int) lines)
9291 state|=RedrawListState;
9293 if (event.type != ButtonRelease)
9300 if (MatteIsActive(slider_info,event.xbutton))
9305 slider_info.active=MagickTrue;
9308 if (MatteIsActive(north_info,event.xbutton))
9309 if (slider_info.id > 0)
9314 north_info.raised=MagickFalse;
9316 state|=RedrawListState;
9319 if (MatteIsActive(south_info,event.xbutton))
9320 if (slider_info.id < (
int) lines)
9325 south_info.raised=MagickFalse;
9327 state|=RedrawListState;
9330 if (MatteIsActive(scroll_info,event.xbutton))
9335 if (event.xbutton.y < slider_info.y)
9336 slider_info.id-=(visible_lines-1);
9338 slider_info.id+=(visible_lines-1);
9339 state|=RedrawListState;
9342 if (MatteIsActive(dismiss_info,event.xbutton))
9347 dismiss_info.raised=MagickFalse;
9348 XDrawBeveledButton(display,&windows->widget,&dismiss_info);
9351 if (MatteIsActive(list_info,event.xbutton))
9362 id=slider_info.id+(
event.xbutton.y-(list_info.y+(height >> 1))+1)/
9363 selection_info.height;
9364 if (
id >= (
int) lines)
9366 if (
id != list_info.id)
9369 click_time=
event.xbutton.time;
9373 if (event.xbutton.time >= (click_time+DoubleClick))
9375 click_time=
event.xbutton.time;
9378 click_time=
event.xbutton.time;
9382 (void) CopyMagickString(primary_selection,textlist[list_info.id],
9384 (void) XSetSelectionOwner(display,XA_PRIMARY,windows->widget.id,
9385 event.xbutton.time);
9386 if (XGetSelectionOwner(display,XA_PRIMARY) != windows->widget.id)
9388 selection_info.id=(~0);
9390 state|=RedrawListState;
9397 if (windows->widget.mapped == MagickFalse)
9399 if (north_info.raised == MagickFalse)
9404 delay=SuspendTime << 2;
9405 north_info.raised=MagickTrue;
9406 XDrawTriangleNorth(display,&windows->widget,&north_info);
9408 if (south_info.raised == MagickFalse)
9413 delay=SuspendTime << 2;
9414 south_info.raised=MagickTrue;
9415 XDrawTriangleSouth(display,&windows->widget,&south_info);
9417 if (slider_info.active)
9422 slider_info.active=MagickFalse;
9425 if (dismiss_info.raised == MagickFalse)
9427 if (event.xbutton.window == windows->widget.id)
9428 if (MatteIsActive(dismiss_info,event.xbutton))
9430 dismiss_info.raised=MagickTrue;
9431 XDrawBeveledButton(display,&windows->widget,&dismiss_info);
9440 if (event.xclient.message_type != windows->wm_protocols)
9442 if (*event.xclient.data.l == (
int) windows->wm_take_focus)
9444 (void) XSetInputFocus(display,event.xclient.window,RevertToParent,
9445 (Time)
event.xclient.data.l[1]);
9448 if (*event.xclient.data.l != (
int) windows->wm_delete_window)
9450 if (event.xclient.window == windows->widget.id)
9457 case ConfigureNotify:
9462 if (event.xconfigure.window != windows->widget.id)
9464 if ((event.xconfigure.width == (
int) windows->widget.width) &&
9465 (
event.xconfigure.height == (int) windows->widget.height))
9467 windows->widget.width=(
unsigned int)
9468 MagickMax(event.xconfigure.width,(
int) windows->widget.min_width);
9469 windows->widget.height=(
unsigned int)
9470 MagickMax(event.xconfigure.height,(
int) windows->widget.min_height);
9471 state|=UpdateConfigurationState;
9476 if (event.xcrossing.window != windows->widget.id)
9478 state&=(~InactiveWidgetState);
9483 if (event.xexpose.window != windows->widget.id)
9485 if (event.xexpose.count != 0)
9487 state|=RedrawWidgetState;
9493 command[MaxTextExtent];
9504 if (event.xkey.window != windows->widget.id)
9506 length=XLookupString((XKeyEvent *) &event.xkey,command,
9507 (
int)
sizeof(command),&key_symbol,(XComposeStatus *) NULL);
9508 *(command+length)=
'\0';
9509 if ((key_symbol == XK_Return) || (key_symbol == XK_KP_Enter))
9511 dismiss_info.raised=MagickFalse;
9512 XDrawBeveledButton(display,&windows->widget,&dismiss_info);
9516 if (AreaIsActive(scroll_info,event.xkey))
9521 switch ((
int) key_symbol)
9544 slider_info.id-=visible_lines;
9550 slider_info.id+=visible_lines;
9556 slider_info.id=(int) lines;
9560 state|=RedrawListState;
9569 if (event.xcrossing.window != windows->widget.id)
9571 state|=InactiveWidgetState;
9585 while (XCheckMaskEvent(display,ButtonMotionMask,&event)) ;
9586 if (slider_info.active)
9591 slider_info.y=
event.xmotion.y-
9592 ((slider_info.height+slider_info.bevel_width) >> 1)+1;
9593 if (slider_info.y < slider_info.min_y)
9594 slider_info.y=slider_info.min_y;
9595 if (slider_info.y > slider_info.max_y)
9596 slider_info.y=slider_info.max_y;
9598 if (slider_info.y != slider_info.min_y)
9599 slider_info.id=(int) (lines*(slider_info.y-slider_info.min_y+1))/
9600 (slider_info.max_y-slider_info.min_y+1);
9601 state|=RedrawListState;
9604 if (state & InactiveWidgetState)
9606 if (dismiss_info.raised == MatteIsActive(dismiss_info,event.xmotion))
9611 dismiss_info.raised=
9612 dismiss_info.raised == MagickFalse ? MagickTrue : MagickFalse;
9613 XDrawBeveledButton(display,&windows->widget,&dismiss_info);
9618 case SelectionClear:
9621 selection_info.id=(~0);
9622 state|=RedrawListState;
9625 case SelectionRequest:
9630 XSelectionRequestEvent
9633 if (list_info.id == (~0))
9638 request=(&(
event.xselectionrequest));
9639 (void) XChangeProperty(request->display,request->requestor,
9640 request->property,request->target,8,PropModeReplace,
9641 (
unsigned char *) primary_selection,Extent(primary_selection));
9642 notify.type=SelectionNotify;
9643 notify.send_event=MagickTrue;
9644 notify.display=request->display;
9645 notify.requestor=request->requestor;
9646 notify.selection=request->selection;
9647 notify.target=request->target;
9648 notify.time=request->time;
9649 if (request->property == None)
9650 notify.property=request->target;
9652 notify.property=request->property;
9653 (void) XSendEvent(request->display,request->requestor,False,NoEventMask,
9654 (XEvent *) ¬ify);
9659 }
while ((state & ExitState) == 0);
9660 if (text_info != windows->widget.font_info)
9661 (void) XFreeFont(display,text_info);
9662 XSetCursorState(display,windows,MagickFalse);
9663 (void) XWithdrawWindow(display,windows->widget.id,windows->widget.screen);
9664 XCheckRefreshWindows(display,windows);