/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % % % W W IIIII DDDD GGGG EEEEE TTTTT % % W W I D D G E T % % W W W I D D G GG EEE T % % WW WW I D D G G E T % % W W IIIII DDDD GGGG EEEEE T % % % % X11 User Interface Routines for ImageMagick. % % % % % % Software Design % % John Cristy % % September 1993 % % % % % % Copyright 1997 E. I. du Pont de Nemours and Company % % % % Permission to use, copy, modify, distribute, and sell this software and % % its documentation for any purpose is hereby granted without fee, % % provided that the above Copyright notice appear in all copies and that % % both that Copyright notice and this permission notice appear in % % supporting documentation, and that the name of E. I. du Pont de Nemours % % and Company not be used in advertising or publicity pertaining to % % distribution of the software without specific, written prior % % permission. E. I. du Pont de Nemours and Company makes no representations % % about the suitability of this software for any purpose. It is provided % % "as is" without express or implied warranty. % % % % E. I. du Pont de Nemours and Company disclaims all warranties with regard % % to this software, including all implied warranties of merchantability % % and fitness, in no event shall E. I. du Pont de Nemours and Company be % % liable for any special, indirect or consequential damages or any % % damages whatsoever resulting from loss of use, data or profits, whether % % in an action of contract, negligence or other tortious action, arising % % out of or in connection with the use or performance of this software. % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % */ /* Include declarations. */ #include "magick.h" /* Define declarations. */ #define AreaIsActive(matte_info,position) \ ((position.y >= (matte_info.y-matte_info.bevel_width)) && \ (position.y < (matte_info.y+matte_info.height+matte_info.bevel_width))) #define MatteIsActive(matte_info,position) \ ((position.x >= (matte_info.x-matte_info.bevel_width)) && \ (position.y >= (matte_info.y-matte_info.bevel_width)) && \ (position.x < (matte_info.x+matte_info.width+matte_info.bevel_width)) && \ (position.y < (matte_info.y+matte_info.height+matte_info.bevel_width))) #define WindowIsActive(window_info,position) \ ((position.x >= 0) && (position.y >= 0) && \ (position.x < window_info.width) && (position.y < window_info.height)) /* State declarations. */ #define ControlState 0x0001 #define DefaultState 0x0000 #define ExitState 0x0002 #define InactiveWidgetState 0x0004 #define JumpListState 0x0008 #define MaxTextWidth (80*XTextWidth(font_info,"_",1)) #define MinTextWidth (26*XTextWidth(font_info,"_",1)) #define QuantumMargin Max(font_info->max_bounds.width,12) #define RedrawActionState 0x0010 #define RedrawListState 0x0020 #define RedrawWidgetState 0x0040 #define UpdateConfigurationState 0x0080 #define UpdateListState 0x0100 /* Variable declarations. */ static XWidgetInfo monitor_info = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, (char *) NULL, (char *) NULL, (char *) NULL }, submenu_info = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, (char *) NULL, (char *) NULL, (char *) NULL }, toggle_info = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, (char *) NULL, (char *) NULL, (char *) NULL }; /* Function prototypes. */ static void XDrawMatte(Display *,const XWindowInfo *,const XWidgetInfo *), XSetBevelColor(Display *,const XWindowInfo *,const unsigned int), XSetMatteColor(Display *,const XWindowInfo *,const unsigned int), XSetTextColor(Display *,const XWindowInfo *,const unsigned int); /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % X D r a w B e v e l % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % Function XDrawBevel "sets off" an area with a highlighted upper and % left bevel and a shadowed lower and right bevel. The highlighted and % shadowed bevels create a 3-D effect. % % The format of the XDrawBevel function is: % % XDrawBevel(display,window_info,bevel_info) % % A description of each parameter follows: % % o display: Specifies a pointer to the Display structure; returned from % XOpenDisplay. % % o window_info: Specifies a pointer to a X11 XWindowInfo structure. % % o bevel_info: Specifies a pointer to a XWidgetInfo structure. It % contains the extents of the bevel. % % */ static void XDrawBevel(Display *display,const XWindowInfo *window_info, XWidgetInfo *bevel_info) { int x1, x2, y1, y2; unsigned int bevel_width; XPoint points[6]; /* Draw upper and left beveled border. */ x1=bevel_info->x; y1=bevel_info->y+bevel_info->height; x2=bevel_info->x+bevel_info->width; y2=bevel_info->y; bevel_width=bevel_info->bevel_width; points[0].x=x1; points[0].y=y1; points[1].x=x1; points[1].y=y2; points[2].x=x2; points[2].y=y2; points[3].x=x2+bevel_width; points[3].y=y2-bevel_width; points[4].x=x1-bevel_width; points[4].y=y2-bevel_width; points[5].x=x1-bevel_width; points[5].y=y1+bevel_width; XSetBevelColor(display,window_info,bevel_info->raised); XFillPolygon(display,window_info->id,window_info->widget_context,points,6, Complex,CoordModeOrigin); /* Draw lower and right beveled border. */ points[0].x=x1; points[0].y=y1; points[1].x=x2; points[1].y=y1; points[2].x=x2; points[2].y=y2; points[3].x=x2+bevel_width; points[3].y=y2-bevel_width; points[4].x=x2+bevel_width; points[4].y=y1+bevel_width; points[5].x=x1-bevel_width; points[5].y=y1+bevel_width; XSetBevelColor(display,window_info,(unsigned int) !bevel_info->raised); XFillPolygon(display,window_info->id,window_info->widget_context,points,6, Complex,CoordModeOrigin); XSetFillStyle(display,window_info->widget_context,FillSolid); } /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % X D r a w B e v e l e d B u t t o n % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % Function XDrawBeveledButton draws a button with a highlighted upper and % left bevel and a shadowed lower and right bevel. The highlighted and % shadowed bevels create a 3-D effect. % % The format of the XDrawBeveledButton function is: % % XDrawBeveledButton(display,window_info,button_info) % % A description of each parameter follows: % % o display: Specifies a pointer to the Display structure; returned from % XOpenDisplay. % % o window_info: Specifies a pointer to a X11 XWindowInfo structure. % % o button_info: Specifies a pointer to a XWidgetInfo structure. It % contains the extents of the button. % % */ static void XDrawBeveledButton(Display *display,const XWindowInfo *window_info, XWidgetInfo *button_info) { int x, y; unsigned int width; XFontStruct *font_info; XRectangle crop_info; /* Draw matte. */ XDrawBevel(display,window_info,button_info); XSetMatteColor(display,window_info,button_info->raised); XFillRectangle(display,window_info->id,window_info->widget_context, button_info->x,button_info->y,button_info->width,button_info->height); x=button_info->x-button_info->bevel_width-1; y=button_info->y-button_info->bevel_width-1; XSetForeground(display,window_info->widget_context, window_info->pixel_info->trough_color.pixel); if (button_info->raised || (window_info->depth == 1)) XDrawRectangle(display,window_info->id,window_info->widget_context,x,y, button_info->width+(button_info->bevel_width << 1)+1,button_info->height+ (button_info->bevel_width << 1)+1); if (button_info->text == (char *) NULL) return; /* Set cropping region. */ crop_info.width=button_info->width; crop_info.height=button_info->height; crop_info.x=button_info->x; crop_info.y=button_info->y; /* Draw text. */ font_info=window_info->font_info; width=XTextWidth(font_info,button_info->text,Extent(button_info->text)); x=button_info->x+(QuantumMargin >> 1); if (button_info->center) x=button_info->x+(button_info->width >> 1)-(width >> 1); y=button_info->y+((button_info->height- (font_info->ascent+font_info->descent)) >> 1)+font_info->ascent; if (button_info->width == (QuantumMargin >> 1)) { /* Option button-- write label to right of button. */ XSetTextColor(display,window_info,True); x=button_info->x+button_info->width+button_info->bevel_width+ (QuantumMargin >> 1); XDrawString(display,window_info->id,window_info->widget_context,x,y, button_info->text,Extent(button_info->text)); return; } XSetClipRectangles(display,window_info->widget_context,0,0,&crop_info,1, Unsorted); XSetTextColor(display,window_info,button_info->raised); XDrawString(display,window_info->id,window_info->widget_context,x,y, button_info->text,Extent(button_info->text)); XSetClipMask(display,window_info->widget_context,None); if (!button_info->raised) XDelay(display,SuspendTime << 2); } /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % X D r a w B e v e l e d M a t t e % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % Function XDrawBeveledMatte draws a matte with a shadowed upper and % left bevel and a highlighted lower and right bevel. The highlighted and % shadowed bevels create a 3-D effect. % % The format of the XDrawBeveledMatte function is: % % XDrawBeveledMatte(display,window_info,matte_info) % % A description of each parameter follows: % % o display: Specifies a pointer to the Display structure; returned from % XOpenDisplay. % % o window_info: Specifies a pointer to a X11 XWindowInfo structure. % % o matte_info: Specifies a pointer to a XWidgetInfo structure. It % contains the extents of the matte. % % */ static void XDrawBeveledMatte(Display *display,const XWindowInfo *window_info, XWidgetInfo *matte_info) { /* Draw matte. */ XDrawBevel(display,window_info,matte_info); XDrawMatte(display,window_info,matte_info); } /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % X D r a w M a t t e % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % Function XDrawMatte fills a rectangular area with the matte color. % % The format of the XDrawMatte function is: % % XDrawMatte(display,window_info,matte_info) % % A description of each parameter follows: % % o display: Specifies a pointer to the Display structure; returned from % XOpenDisplay. % % o window_info: Specifies a pointer to a X11 XWindowInfo structure. % % o matte_info: Specifies a pointer to a XWidgetInfo structure. It % contains the extents of the matte. % % */ static void XDrawMatte(Display *display,const XWindowInfo *window_info, const XWidgetInfo *matte_info) { /* Draw matte. */ if (!matte_info->trough || (window_info->depth == 1)) XFillRectangle(display,window_info->id,window_info->highlight_context, matte_info->x,matte_info->y,matte_info->width,matte_info->height); else { XSetForeground(display,window_info->widget_context, window_info->pixel_info->trough_color.pixel); XFillRectangle(display,window_info->id,window_info->widget_context, matte_info->x,matte_info->y,matte_info->width,matte_info->height); } } /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % X D r a w M a t t e T e x t % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % Function XDrawMatteText draws a matte with text. If the text exceeds the % extents of the text, a portion of the text relative to the cursor is % displayed. % % The format of the XDrawMatteText function is: % % XDrawMatteText(display,window_info,text_info) % % A description of each parameter follows: % % o display: Specifies a pointer to the Display structure; returned from % XOpenDisplay. % % o window_info: Specifies a pointer to a X11 XWindowInfo structure. % % o text_info: Specifies a pointer to a XWidgetInfo structure. It % contains the extents of the text. % % */ static void XDrawMatteText(Display *display,const XWindowInfo *window_info, XWidgetInfo *text_info) { char *text; int n, x, y; register int i; unsigned int height, width; XFontStruct *font_info; XRectangle crop_info; /* Clear the text area. */ XSetMatteColor(display,window_info,False); XFillRectangle(display,window_info->id,window_info->widget_context, text_info->x,text_info->y,text_info->width,text_info->height); if (text_info->text == (char *) NULL) return; XSetTextColor(display,window_info,text_info->highlight); font_info=window_info->font_info; x=text_info->x+(QuantumMargin >> 2); y=text_info->y+font_info->ascent+(text_info->height >> 2); width=text_info->width-(QuantumMargin >> 1); height=font_info->ascent+font_info->descent; if (*text_info->text == '\0') { /* No text-- just draw cursor. */ XDrawLine(display,window_info->id,window_info->annotate_context,x,y+3, x,y-height+3); return; } /* Set cropping region. */ crop_info.width=text_info->width; crop_info.height=text_info->height; crop_info.x=text_info->x; crop_info.y=text_info->y; /* Determine beginning of the visible text. */ if (text_info->cursor < text_info->marker) text_info->marker=text_info->cursor; else { text=text_info->marker; if (XTextWidth(font_info,text,(int) (text_info->cursor-text)) > width) { text=text_info->text; for (i=0; i < Extent(text); i++) { n=XTextWidth(font_info,text+i,(int) (text_info->cursor-text-i)); if (n <= width) break; } text_info->marker=text+i; } } /* Draw text and cursor. */ if (!text_info->highlight) { XSetClipRectangles(display,window_info->widget_context,0,0,&crop_info,1, Unsorted); XDrawString(display,window_info->id,window_info->widget_context,x,y, text_info->marker,Extent(text_info->marker)); XSetClipMask(display,window_info->widget_context,None); } else { XSetClipRectangles(display,window_info->annotate_context,0,0,&crop_info, 1,Unsorted); width=XTextWidth(font_info,text_info->marker,Extent(text_info->marker)); XFillRectangle(display,window_info->id,window_info->annotate_context,x, y-font_info->ascent,width,height); XSetClipMask(display,window_info->annotate_context,None); XSetClipRectangles(display,window_info->highlight_context,0,0,&crop_info, 1,Unsorted); XDrawString(display,window_info->id,window_info->highlight_context,x,y, text_info->marker,Extent(text_info->marker)); XSetClipMask(display,window_info->highlight_context,None); } x+=XTextWidth(font_info,text_info->marker,(int) (text_info->cursor-text_info->marker)); XDrawLine(display,window_info->id,window_info->annotate_context,x,y+3, x,y-height+3); } /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % X D r a w T r i a n g l e E a s t % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % Function XDrawTriangleEast draws a triangle with a highlighted left % bevel and a shadowed right and lower bevel. The highlighted and % shadowed bevels create a 3-D effect. % % The format of the XDrawTriangleEast function is: % % XDrawTriangleEast(display,window_info,triangle_info) % % A description of each parameter follows: % % o display: Specifies a pointer to the Display structure; returned from % XOpenDisplay. % % o window_info: Specifies a pointer to a X11 XWindowInfo structure. % % o triangle_info: Specifies a pointer to a XWidgetInfo structure. It % contains the extents of the triangle. % % */ static void XDrawTriangleEast(Display *display,const XWindowInfo *window_info, XWidgetInfo *triangle_info) { int x1, x2, x3, y1, y2, y3; unsigned int bevel_width; XFontStruct *font_info; XPoint points[4]; /* Draw triangle matte. */ x1=triangle_info->x; y1=triangle_info->y; x2=triangle_info->x+triangle_info->width; y2=triangle_info->y+(triangle_info->height >> 1); x3=triangle_info->x; y3=triangle_info->y+triangle_info->height; bevel_width=triangle_info->bevel_width; points[0].x=x1; points[0].y=y1; points[1].x=x2; points[1].y=y2; points[2].x=x3; points[2].y=y3; XSetMatteColor(display,window_info,triangle_info->raised); XFillPolygon(display,window_info->id,window_info->widget_context,points,3, Complex,CoordModeOrigin); /* Draw bottom bevel. */ points[0].x=x2; points[0].y=y2; points[1].x=x3; points[1].y=y3; points[2].x=x3-bevel_width; points[2].y=y3+bevel_width; points[3].x=x2+bevel_width; points[3].y=y2; XSetBevelColor(display,window_info,(unsigned int) !triangle_info->raised); XFillPolygon(display,window_info->id,window_info->widget_context,points,4, Complex,CoordModeOrigin); /* Draw Left bevel. */ points[0].x=x3; points[0].y=y3; points[1].x=x1; points[1].y=y1; points[2].x=x1-bevel_width+1; points[2].y=y1-bevel_width; points[3].x=x3-bevel_width+1; points[3].y=y3+bevel_width; XSetBevelColor(display,window_info,triangle_info->raised); XFillPolygon(display,window_info->id,window_info->widget_context,points,4, Complex,CoordModeOrigin); /* Draw top bevel. */ points[0].x=x1; points[0].y=y1; points[1].x=x2; points[1].y=y2; points[2].x=x2+bevel_width; points[2].y=y2; points[3].x=x1-bevel_width; points[3].y=y1-bevel_width; XFillPolygon(display,window_info->id,window_info->widget_context,points,4, Complex,CoordModeOrigin); XSetFillStyle(display,window_info->widget_context,FillSolid); if (triangle_info->text == (char *) NULL) return; /* Write label to right of triangle. */ font_info=window_info->font_info; XSetTextColor(display,window_info,True); x1=triangle_info->x+triangle_info->width+triangle_info->bevel_width+ (QuantumMargin >> 1); y1=triangle_info->y+((triangle_info->height- (font_info->ascent+font_info->descent)) >> 1)+font_info->ascent; XDrawString(display,window_info->id,window_info->widget_context,x1,y1, triangle_info->text,Extent(triangle_info->text)); } /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % X D r a w T r i a n g l e N o r t h % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % Function XDrawTriangleNorth draws a triangle with a highlighted left % bevel and a shadowed right and lower bevel. The highlighted and % shadowed bevels create a 3-D effect. % % The format of the XDrawTriangleNorth function is: % % XDrawTriangleNorth(display,window_info,triangle_info) % % A description of each parameter follows: % % o display: Specifies a pointer to the Display structure; returned from % XOpenDisplay. % % o window_info: Specifies a pointer to a X11 XWindowInfo structure. % % o triangle_info: Specifies a pointer to a XWidgetInfo structure. It % contains the extents of the triangle. % % */ static void XDrawTriangleNorth(Display *display,const XWindowInfo *window_info, XWidgetInfo *triangle_info) { int x1, x2, x3, y1, y2, y3; unsigned int bevel_width; XPoint points[4]; /* Draw triangle matte. */ x1=triangle_info->x; y1=triangle_info->y+triangle_info->height; x2=triangle_info->x+(triangle_info->width >> 1); y2=triangle_info->y; x3=triangle_info->x+triangle_info->width; y3=triangle_info->y+triangle_info->height; bevel_width=triangle_info->bevel_width; points[0].x=x1; points[0].y=y1; points[1].x=x2; points[1].y=y2; points[2].x=x3; points[2].y=y3; XSetMatteColor(display,window_info,triangle_info->raised); XFillPolygon(display,window_info->id,window_info->widget_context,points,3, Complex,CoordModeOrigin); /* Draw left bevel. */ points[0].x=x1; points[0].y=y1; points[1].x=x2; points[1].y=y2; points[2].x=x2; points[2].y=y2-bevel_width-2; points[3].x=x1-bevel_width-1; points[3].y=y1+bevel_width; XSetBevelColor(display,window_info,triangle_info->raised); XFillPolygon(display,window_info->id,window_info->widget_context,points,4, Complex,CoordModeOrigin); /* Draw right bevel. */ points[0].x=x2; points[0].y=y2; points[1].x=x3; points[1].y=y3; points[2].x=x3+bevel_width; points[2].y=y3+bevel_width; points[3].x=x2; points[3].y=y2-bevel_width; XSetBevelColor(display,window_info,(unsigned int) !triangle_info->raised); XFillPolygon(display,window_info->id,window_info->widget_context,points,4, Complex,CoordModeOrigin); /* Draw lower bevel. */ points[0].x=x3; points[0].y=y3; points[1].x=x1; points[1].y=y1; points[2].x=x1-bevel_width; points[2].y=y1+bevel_width; points[3].x=x3+bevel_width; points[3].y=y3+bevel_width; XFillPolygon(display,window_info->id,window_info->widget_context,points,4, Complex,CoordModeOrigin); XSetFillStyle(display,window_info->widget_context,FillSolid); } /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % X D r a w T r i a n g l e S o u t h % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % Function XDrawTriangleSouth draws a border with a highlighted left and % right bevel and a shadowed lower bevel. The highlighted and shadowed % bevels create a 3-D effect. % % The format of the XDrawTriangleSouth function is: % % XDrawTriangleSouth(display,window_info,triangle_info) % % A description of each parameter follows: % % o display: Specifies a pointer to the Display structure; returned from % XOpenDisplay. % % o window_info: Specifies a pointer to a X11 XWindowInfo structure. % % o triangle_info: Specifies a pointer to a XWidgetInfo structure. It % contains the extents of the triangle. % % */ static void XDrawTriangleSouth(Display *display,const XWindowInfo *window_info, XWidgetInfo *triangle_info) { int x1, x2, x3, y1, y2, y3; unsigned int bevel_width; XPoint points[4]; /* Draw triangle matte. */ x1=triangle_info->x; y1=triangle_info->y; x2=triangle_info->x+(triangle_info->width >> 1); y2=triangle_info->y+triangle_info->height; x3=triangle_info->x+triangle_info->width; y3=triangle_info->y; bevel_width=triangle_info->bevel_width; points[0].x=x1; points[0].y=y1; points[1].x=x2; points[1].y=y2; points[2].x=x3; points[2].y=y3; XSetMatteColor(display,window_info,triangle_info->raised); XFillPolygon(display,window_info->id,window_info->widget_context,points,3, Complex,CoordModeOrigin); /* Draw top bevel. */ points[0].x=x3; points[0].y=y3; points[1].x=x1; points[1].y=y1; points[2].x=x1-bevel_width; points[2].y=y1-bevel_width; points[3].x=x3+bevel_width; points[3].y=y3-bevel_width; XSetBevelColor(display,window_info,triangle_info->raised); XFillPolygon(display,window_info->id,window_info->widget_context,points,4, Complex,CoordModeOrigin); /* Draw right bevel. */ points[0].x=x2; points[0].y=y2; points[1].x=x3+1; points[1].y=y3-bevel_width; points[2].x=x3+bevel_width; points[2].y=y3-bevel_width; points[3].x=x2; points[3].y=y2+bevel_width; XSetBevelColor(display,window_info,(unsigned int) !triangle_info->raised); XFillPolygon(display,window_info->id,window_info->widget_context,points,4, Complex,CoordModeOrigin); /* Draw left bevel. */ points[0].x=x1; points[0].y=y1; points[1].x=x2; points[1].y=y2; points[2].x=x2; points[2].y=y2+bevel_width; points[3].x=x1-bevel_width; points[3].y=y1-bevel_width; XSetBevelColor(display,window_info,triangle_info->raised); XFillPolygon(display,window_info->id,window_info->widget_context,points,4, Complex,CoordModeOrigin); XSetFillStyle(display,window_info->widget_context,FillSolid); } /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % X D r a w W i d g e t T e x t % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % Function XDrawWidgetText first clears the widget and draws a text string % justifed left (or center) in the x-direction and centered within the % y-direction. % % The format of the XDrawWidgetText function is: % % XDrawWidgetText(display,window_info,text_info) % % A description of each parameter follows: % % o display: Specifies a pointer to the Display structure; returned from % XOpenDisplay. % % o window_info: Specifies a pointer to a XWindowText structure. % % o text_info: Specifies a pointer to XWidgetInfo structure. % % */ static void XDrawWidgetText(Display *display,const XWindowInfo *window_info, XWidgetInfo *text_info) { GC widget_context; int x, y; unsigned int height, width; XFontStruct *font_info; XRectangle crop_info; /* Clear the text area. */ widget_context=window_info->annotate_context; if (text_info->raised) XClearArea(display,window_info->id,text_info->x,text_info->y, text_info->width,text_info->height,False); else { XFillRectangle(display,window_info->id,widget_context,text_info->x, text_info->y,text_info->width,text_info->height); widget_context=window_info->highlight_context; } if (text_info->text == (char *) NULL) return; if (*text_info->text == '\0') return; /* Set cropping region. */ font_info=window_info->font_info; crop_info.width=text_info->width; crop_info.height=text_info->height; crop_info.x=text_info->x; crop_info.y=text_info->y; /* Draw text. */ width=XTextWidth(font_info,text_info->text,Extent(text_info->text)); x=text_info->x+(QuantumMargin >> 1); if (text_info->center) x=text_info->x+(text_info->width >> 1)-(width >> 1); if (text_info->raised) if (width > (text_info->width-QuantumMargin)) x+=(text_info->width-QuantumMargin-width); height=font_info->ascent+font_info->descent; y=text_info->y+((text_info->height-height) >> 1)+font_info->ascent; XSetClipRectangles(display,widget_context,0,0,&crop_info,1,Unsorted); XDrawString(display,window_info->id,widget_context,x,y,text_info->text, Extent(text_info->text)); XSetClipMask(display,widget_context,None); if (x < text_info->x) XDrawLine(display,window_info->id,window_info->annotate_context, text_info->x,text_info->y,text_info->x,text_info->y+text_info->height-1); } /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % X E d i t T e x t % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % Function XEditText edits a text string as indicated by the key symbol. % % The format of the XEditText function is: % % XEditText(display,text_info,key_symbol,text,state) % % A description of each parameter follows: % % o display: Specifies a connection to an X server; returned from % XOpenDisplay. % % o text_info: Specifies a pointer to a XWidgetInfo structure. It % contains the extents of the text. % % o key_symbol: A X11 KeySym that indicates what editing function to % perform to the text. % % o text: A character string to insert into the text. % % o state: An unsigned long that indicates whether the key symbol is a % control character or not. % % */ static void XEditText(Display *display,XWidgetInfo *text_info, const KeySym key_symbol,char *text,const unsigned long state) { switch (key_symbol) { case XK_BackSpace: case XK_Delete: { if (text_info->highlight) { /* Erase the entire line of text. */ *text_info->text='\0'; text_info->cursor=text_info->text; text_info->marker=text_info->text; text_info->highlight=False; } /* Erase one character. */ if (text_info->cursor != text_info->text) { text_info->cursor--; (void) strcpy(text_info->cursor,text_info->cursor+1); text_info->highlight=False; break; } } case XK_Left: case XK_KP_Left: { /* Move cursor one position left. */ if (text_info->cursor == text_info->text) break; text_info->cursor--; break; } case XK_Right: case XK_KP_Right: { /* Move cursor one position right. */ if (text_info->cursor == (text_info->text+Extent(text_info->text))) break; text_info->cursor++; break; } default: { register char *p, *q; register int i; if (state & ControlState) break; if (*text == '\0') break; if ((Extent(text_info->text)+1) >= MaxTextExtent) XBell(display,0); else { if (text_info->highlight) { /* Erase the entire line of text. */ *text_info->text='\0'; text_info->cursor=text_info->text; text_info->marker=text_info->text; text_info->highlight=False; } /* Insert a string into the text. */ q=text_info->text+Extent(text_info->text)+Extent(text); for (i=0; i <= Extent(text_info->cursor); i++) { *q=(*(q-Extent(text))); q--; } p=text; for (i=0; i < Extent(text); i++) *text_info->cursor++=(*p++); } break; } } } /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % X G e t W i d g e t I n f o % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % Function XGetWidgetInfo initializes the XWidgetInfo structure. % % The format of the XGetWidgetInfo function is: % % XGetWidgetInfo(text,widget_info) % % A description of each parameter follows: % % o text: A string of characters associated with the widget. % % o widget_info: Specifies a pointer to a X11 XWidgetInfo structure. % % */ static void XGetWidgetInfo(char *text,XWidgetInfo *widget_info) { /* Initialize widget info. */ widget_info->id=(~0); widget_info->bevel_width=3; widget_info->width=1; widget_info->height=1; widget_info->x=0; widget_info->y=0; widget_info->min_y=0; widget_info->max_y=0; widget_info->raised=True; widget_info->active=False; widget_info->center=True; widget_info->trough=False; widget_info->highlight=False; widget_info->text=text; widget_info->cursor=text; if (text != (char *) NULL) widget_info->cursor+=Extent(text); widget_info->marker=text; } /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % X H i g h l i g h t W i d g e t % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % Function XHighlightWidget draws a highlighted border around a window. % % The format of the XHighlightWidget function is: % % XHighlightWidget(display,window_info,x,y) % % A description of each parameter follows: % % o display: Specifies a pointer to the Display structure; returned from % XOpenDisplay. % % o window_info: Specifies a pointer to a X11 XWindowInfo structure. % % o x: Specifies an integer representing the rectangle offset in the % x-direction. % % o y: Specifies an integer representing the rectangle offset in the % y-direction. % % */ static void XHighlightWidget(Display *display,const XWindowInfo *window_info, int x,int y) { /* Draw the widget highlighting rectangle. */ XSetBevelColor(display,window_info,True); XDrawRectangle(display,window_info->id,window_info->widget_context,x,y, window_info->width-(x << 1),window_info->height-(y << 1)); XDrawRectangle(display,window_info->id,window_info->widget_context,x-1,y-1, window_info->width-(x << 1)+1,window_info->height-(y << 1)+1); XSetBevelColor(display,window_info,False); XDrawRectangle(display,window_info->id,window_info->widget_context,x-1,y-1, window_info->width-(x << 1),window_info->height-(y << 1)); XSetFillStyle(display,window_info->widget_context,FillSolid); } /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % X S c r e e n E v e n t % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % Function XScreenEvent returns True if the any event on the X server queue % is associated with the widget window. % % The format of the XScreenEvent function is: % % XScreenEvent(display,event,data) % % A description of each parameter follows: % % o display: Specifies a pointer to the Display structure; returned from % XOpenDisplay. % % o event: Specifies a pointer to a X11 XEvent structure. % % o data: Specifies a pointer to a XWindows structure. % % */ static int XScreenEvent(Display *display,XEvent *event,char *data) { XWindows *windows; windows=(XWindows *) data; if (event->xany.window == windows->popup.id) { if (event->type == MapNotify) windows->popup.mapped=True; if (event->type == UnmapNotify) windows->popup.mapped=False; return(True); } if (event->xany.window == windows->widget.id) { if (event->type == MapNotify) windows->widget.mapped=True; if (event->type == UnmapNotify) windows->widget.mapped=False; return(True); } switch (event->type) { case ButtonPress: { if ((event->xbutton.button == Button3) && (event->xbutton.state & Mod1Mask)) { /* Convert Alt-Button3 to Button2. */ event->xbutton.button=Button2; event->xbutton.state&=(~Mod1Mask); } return(True); } case Expose: { if (event->xexpose.window == windows->image.id) { XRefreshWindow(display,&windows->image,event); break; } if (event->xexpose.window == windows->magnify.id) if (event->xexpose.count == 0) if (windows->magnify.mapped) { XMakeMagnifyImage(display,windows); break; } if (event->xexpose.window == windows->command.id) if (event->xexpose.count == 0) { (void) XCommandWidget(display,windows,(char **) NULL,event); break; } break; } case FocusOut: { /* Set input focus for backdrop window. */ if (event->xfocus.window == windows->image.id) XSetInputFocus(display,windows->image.id,RevertToNone,CurrentTime); return(True); } case ButtonRelease: case KeyPress: case KeyRelease: case MotionNotify: case SelectionNotify: return(True); default: break; } return(False); } /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % X S e t B e v e l C o l o r % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % Function XSetBevelColor sets the graphic context for drawing a beveled % border. % % The format of the XSetBevelColor function is: % % XSetBevelColor(display,window_info,raised) % % A description of each parameter follows: % % o display: Specifies a pointer to the Display structure; returned from % XOpenDisplay. % % o window_info: Specifies a pointer to a X11 XWindowInfo structure. % % o raised: A value other than zero indicates the color show be a % "highlight" color, otherwise the "shadow" color is set. % % */ static void XSetBevelColor(Display *display,const XWindowInfo *window_info, const unsigned int raised) { if (window_info->depth == 1) { Pixmap stipple; /* Monochrome window. */ XSetBackground(display,window_info->widget_context, XBlackPixel(display,window_info->screen)); XSetForeground(display,window_info->widget_context, XWhitePixel(display,window_info->screen)); XSetFillStyle(display,window_info->widget_context,FillOpaqueStippled); stipple=window_info->highlight_stipple; if (!raised) stipple=window_info->shadow_stipple; XSetStipple(display,window_info->widget_context,stipple); } else if (raised) XSetForeground(display,window_info->widget_context, window_info->pixel_info->highlight_color.pixel); else XSetForeground(display,window_info->widget_context, window_info->pixel_info->shadow_color.pixel); } /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % X S e t M a t t e C o l o r % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % Function XSetMatteColor sets the graphic context for drawing the matte. % % The format of the XSetMatteColor function is: % % XSetMatteColor(display,window_info,raised) % % A description of each parameter follows: % % o display: Specifies a pointer to the Display structure; returned from % XOpenDisplay. % % o window_info: Specifies a pointer to a X11 XWindowInfo structure. % % o raised: A value other than zero indicates the matte is active. % % */ static void XSetMatteColor(Display *display,const XWindowInfo *window_info, const unsigned int raised) { if (window_info->depth == 1) { /* Monochrome window. */ if (raised) XSetForeground(display,window_info->widget_context, XWhitePixel(display,window_info->screen)); else XSetForeground(display,window_info->widget_context, XBlackPixel(display,window_info->screen)); } else if (raised) XSetForeground(display,window_info->widget_context, window_info->pixel_info->matte_color.pixel); else XSetForeground(display,window_info->widget_context, window_info->pixel_info->depth_color.pixel); } /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % X S e t T e x t C o l o r % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % Function XSetTextColor sets the graphic context for drawing text on a % matte. % % The format of the XSetTextColor function is: % % XSetTextColor(display,window_info,raised) % % A description of each parameter follows: % % o display: Specifies a pointer to the Display structure; returned from % XOpenDisplay. % % o window_info: Specifies a pointer to a X11 XWindowInfo structure. % % o raised: A value other than zero indicates the color show be a % "highlight" color, otherwise the "shadow" color is set. % % */ static void XSetTextColor(Display *display,const XWindowInfo *window_info, const unsigned int raised) { int foreground, matte; if (window_info->depth == 1) { /* Monochrome window. */ if (raised) XSetForeground(display,window_info->widget_context, XBlackPixel(display,window_info->screen)); else XSetForeground(display,window_info->widget_context, XWhitePixel(display,window_info->screen)); return; } foreground=XDownScale(Intensity(window_info->pixel_info->foreground_color)); matte=XDownScale(Intensity(window_info->pixel_info->matte_color)); if (AbsoluteValue(foreground-matte) > (MaxRGB >> 3)) XSetForeground(display,window_info->widget_context, window_info->pixel_info->foreground_color.pixel); else XSetForeground(display,window_info->widget_context, window_info->pixel_info->background_color.pixel); } /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % X C o l o r B r o w s e r W i d g e t % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % Function XColorBrowserWidget displays a Color Browser widget with a color % query to the user. The user keys a reply and presses the Action or Cancel % button to exit. The typed text is returned as the reply function parameter. % % The format of the XColorBrowserWidget routine is: % % XColorBrowserWidget(display,windows,action,reply) % % A description of each parameter follows: % % o display: Specifies a connection to an X server; returned from % XOpenDisplay. % % o window: Specifies a pointer to a XWindows structure. % % o action: Specifies a pointer to the action of this widget. % % o reply: The response from the user is returned in this parameter. % % */ Export void XColorBrowserWidget(Display *display,XWindows *windows,char *action, char *reply) { #define CancelButtonText "Cancel" #define ColornameText "Name:" #define ColorPatternText "Pattern:" #define GrabButtonText "Grab" #define ResetButtonText "Reset" char **colorlist, primary_selection[MaxTextExtent], reset_pattern[MaxTextExtent], text[MaxTextExtent]; int colors, status, x, y; register int i; static char glob_pattern[MaxTextExtent] = "*"; static char mask = CWWidth | CWHeight | CWX | CWY; unsigned int height, text_width, visible_colors, width; unsigned long delay, state; XColor color; XEvent event; XFontStruct *font_info; XTextProperty window_name; XWidgetInfo action_info, cancel_info, expose_info, grab_info, list_info, mode_info, north_info, reply_info, reset_info, scroll_info, selection_info, slider_info, south_info, text_info; XWindowChanges window_changes; /* Get color list and sort in ascending order. */ assert(display != (Display *) NULL); assert(windows != (XWindows *) NULL); assert(action != (char *) NULL); assert(reply != (char *) NULL); XSetCursorState(display,windows,True); XCheckRefreshWindows(display,windows); (void) strcpy(reset_pattern,"*"); colorlist=ListColors(glob_pattern,&colors); if (colorlist == (char **) NULL) { /* Pattern failed, obtain all the colors. */ (void) strcpy(glob_pattern,"*"); colorlist=ListColors(glob_pattern,&colors); if (colorlist == (char **) NULL) { XNoticeWidget(display,windows,"Unable to obtain colors names:", glob_pattern); (void) XDialogWidget(display,windows,action,"Enter color name:", reply); return; } } /* Determine Color Browser widget attributes. */ font_info=windows->widget.font_info; text_width=0; for (i=0; i < colors; i++) if (XTextWidth(font_info,colorlist[i],Extent(colorlist[i])) > text_width) text_width=XTextWidth(font_info,colorlist[i],Extent(colorlist[i])); width=XTextWidth(font_info,action,Extent(action)); if (XTextWidth(font_info,CancelButtonText,Extent(CancelButtonText)) > width) width=XTextWidth(font_info,CancelButtonText,Extent(CancelButtonText)); if (XTextWidth(font_info,ResetButtonText,Extent(ResetButtonText)) > width) width=XTextWidth(font_info,ResetButtonText,Extent(ResetButtonText)); if (XTextWidth(font_info,GrabButtonText,Extent(GrabButtonText)) > width) width=XTextWidth(font_info,GrabButtonText,Extent(GrabButtonText)); width+=QuantumMargin; if (XTextWidth(font_info,ColorPatternText,Extent(ColorPatternText)) > width) width=XTextWidth(font_info,ColorPatternText,Extent(ColorPatternText)); if (XTextWidth(font_info,ColornameText,Extent(ColornameText)) > width) width=XTextWidth(font_info,ColornameText,Extent(ColornameText)); height=font_info->ascent+font_info->descent; /* Position Color Browser widget. */ windows->widget.width=width+Min(text_width,MaxTextWidth)+6*QuantumMargin; windows->widget.min_width=width+MinTextWidth+4*QuantumMargin; if (windows->widget.width < windows->widget.min_width) windows->widget.width=windows->widget.min_width; windows->widget.height=((81*height) >> 2)+((13*QuantumMargin) >> 1)+4; windows->widget.min_height=((23*height) >> 1)+((13*QuantumMargin) >> 1)+4; if (windows->widget.height < windows->widget.min_height) windows->widget.height=windows->widget.min_height; XQueryPosition(display,windows->widget.root,&x,&y); windows->widget.x=x-((3*windows->widget.width) >> 2); windows->widget.y=y-(windows->widget.height >> 1); XConstrainWindowPosition(display,&windows->widget); /* Map Color Browser widget. */ (void) strcpy(windows->widget.name,"Browse and Select a Color"); status=XStringListToTextProperty(&windows->widget.name,1,&window_name); if (status != 0) { XSetWMName(display,windows->widget.id,&window_name); XSetWMIconName(display,windows->widget.id,&window_name); XFree((void *) window_name.value); } window_changes.width=windows->widget.width; window_changes.height=windows->widget.height; window_changes.x=windows->widget.x; window_changes.y=windows->widget.y; XReconfigureWMWindow(display,windows->widget.id,windows->widget.screen,mask, &window_changes); XMapRaised(display,windows->widget.id); windows->widget.mapped=False; /* Respond to X events. */ XGetWidgetInfo((char *) NULL,&slider_info); XGetWidgetInfo((char *) NULL,&north_info); XGetWidgetInfo((char *) NULL,&south_info); visible_colors=0; delay=SuspendTime << 2; state=UpdateConfigurationState; do { if (state & UpdateConfigurationState) { int id; /* Initialize button information. */ XGetWidgetInfo(CancelButtonText,&cancel_info); cancel_info.width=width; cancel_info.height=(3*height) >> 1; cancel_info.x=windows->widget.width-cancel_info.width-QuantumMargin-2; cancel_info.y=windows->widget.height-cancel_info.height-QuantumMargin; XGetWidgetInfo(action,&action_info); action_info.width=width; action_info.height=(3*height) >> 1; action_info.x=cancel_info.x-(cancel_info.width+(QuantumMargin >> 1)+ (action_info.bevel_width << 1)); action_info.y=cancel_info.y; XGetWidgetInfo(GrabButtonText,&grab_info); grab_info.width=width; grab_info.height=(3*height) >> 1; grab_info.x=QuantumMargin; grab_info.y=((5*QuantumMargin) >> 1)+height; XGetWidgetInfo(ResetButtonText,&reset_info); reset_info.width=width; reset_info.height=(3*height) >> 1; reset_info.x=QuantumMargin; reset_info.y=grab_info.y+grab_info.height+QuantumMargin; /* Initialize reply information. */ XGetWidgetInfo(reply,&reply_info); reply_info.raised=False; reply_info.bevel_width--; reply_info.width=windows->widget.width-width-((6*QuantumMargin) >> 1); reply_info.height=height << 1; reply_info.x=width+(QuantumMargin << 1); reply_info.y=action_info.y-reply_info.height-QuantumMargin; /* Initialize mode information. */ XGetWidgetInfo((char *) NULL,&mode_info); mode_info.active=True; mode_info.bevel_width=0; mode_info.width=action_info.x-reply_info.x-QuantumMargin; mode_info.height=action_info.height; mode_info.x=reply_info.x; mode_info.y=action_info.y; /* Initialize scroll information. */ XGetWidgetInfo((char *) NULL,&scroll_info); scroll_info.bevel_width--; scroll_info.width=height; scroll_info.height=reply_info.y-grab_info.y-(QuantumMargin >> 1); scroll_info.x=reply_info.x+(reply_info.width-scroll_info.width); scroll_info.y=grab_info.y-reply_info.bevel_width; scroll_info.raised=False; scroll_info.trough=True; north_info=scroll_info; north_info.raised=True; north_info.width-=(north_info.bevel_width << 1); north_info.height=north_info.width-1; north_info.x+=north_info.bevel_width; north_info.y+=north_info.bevel_width; south_info=north_info; south_info.y=scroll_info.y+scroll_info.height-scroll_info.bevel_width- south_info.height; id=slider_info.id; slider_info=north_info; slider_info.id=id; slider_info.width-=2; slider_info.min_y=north_info.y+north_info.height+north_info.bevel_width+ slider_info.bevel_width+2; slider_info.height= scroll_info.height-((slider_info.min_y-scroll_info.y+1) << 1)+2; visible_colors= (scroll_info.height-(height >> 3)-3)/((9*height) >> 3); if (colors > visible_colors) slider_info.height=(visible_colors*slider_info.height)/colors; slider_info.max_y=south_info.y-south_info.bevel_width- slider_info.bevel_width-2; slider_info.x=scroll_info.x+slider_info.bevel_width+1; slider_info.y=slider_info.min_y; expose_info=scroll_info; expose_info.y=slider_info.y; /* Initialize list information. */ XGetWidgetInfo((char *) NULL,&list_info); list_info.raised=False; list_info.bevel_width--; list_info.width=scroll_info.x-reply_info.x-(QuantumMargin >> 1); list_info.height=scroll_info.height; list_info.x=reply_info.x; list_info.y=scroll_info.y; if (!windows->widget.mapped) state|=JumpListState; /* Initialize text information. */ *text='\0'; XGetWidgetInfo(text,&text_info); text_info.center=False; text_info.width=reply_info.width; text_info.height=height; text_info.x=list_info.x-(QuantumMargin >> 1); text_info.y=QuantumMargin; /* Initialize selection information. */ XGetWidgetInfo((char *) NULL,&selection_info); selection_info.center=False; selection_info.width=list_info.width; selection_info.height=(9*height) >> 3; selection_info.x=list_info.x; state&=(~UpdateConfigurationState); } if (state & RedrawWidgetState) { /* Redraw Color Browser window. */ x=QuantumMargin; y=text_info.y+((text_info.height-height) >> 1)+font_info->ascent; XDrawString(display,windows->widget.id,windows->widget.annotate_context, x,y,ColorPatternText,Extent(ColorPatternText)); (void) sprintf(text_info.text,"%s",glob_pattern); XDrawWidgetText(display,&windows->widget,&text_info); XDrawBeveledButton(display,&windows->widget,&grab_info); XDrawBeveledButton(display,&windows->widget,&reset_info); XDrawBeveledMatte(display,&windows->widget,&list_info); XDrawBeveledMatte(display,&windows->widget,&scroll_info); XDrawTriangleNorth(display,&windows->widget,&north_info); XDrawBeveledButton(display,&windows->widget,&slider_info); XDrawTriangleSouth(display,&windows->widget,&south_info); x=QuantumMargin; y=reply_info.y+((reply_info.height-height) >> 1)+font_info->ascent; XDrawString(display,windows->widget.id,windows->widget.annotate_context, x,y,ColornameText,Extent(ColornameText)); XDrawBeveledMatte(display,&windows->widget,&reply_info); XDrawMatteText(display,&windows->widget,&reply_info); XDrawBeveledButton(display,&windows->widget,&action_info); XDrawBeveledButton(display,&windows->widget,&cancel_info); XHighlightWidget(display,&windows->widget,BorderOffset,BorderOffset); selection_info.id=(~0); state|=RedrawActionState; state|=RedrawListState; state&=(~RedrawWidgetState); } if (state & UpdateListState) { char **checklist; int number_colors; status=XParseColor(display,windows->widget.map_info->colormap, glob_pattern,&color); if ((status != 0) || (strchr(glob_pattern,'-') != (char *) NULL)) { /* Reply is a single color name-- exit. */ (void) strcpy(reply,glob_pattern); (void) strcpy(glob_pattern,reset_pattern); action_info.raised=False; XDrawBeveledButton(display,&windows->widget,&action_info); break; } /* Update color list. */ checklist=ListColors(glob_pattern,&number_colors); if (number_colors == 0) { (void) strcpy(glob_pattern,reset_pattern); XBell(display,0); } else { for (i=0; i < colors; i++) free((char *) colorlist[i]); if (colorlist != (char **) NULL) free((char *) colorlist); colorlist=checklist; colors=number_colors; } /* Sort color list in ascending order. */ slider_info.height= scroll_info.height-((slider_info.min_y-scroll_info.y+1) << 1)+1; if (colors > visible_colors) slider_info.height=(visible_colors*slider_info.height)/colors; slider_info.max_y=south_info.y-south_info.bevel_width- slider_info.bevel_width-2; slider_info.id=0; slider_info.y=slider_info.min_y; expose_info.y=slider_info.y; selection_info.id=(~0); list_info.id=(~0); state|=RedrawListState; /* Redraw color name & reply. */ *reply_info.text='\0'; reply_info.cursor=reply_info.text; (void) sprintf(text_info.text,"%s",glob_pattern); XDrawWidgetText(display,&windows->widget,&text_info); XDrawMatteText(display,&windows->widget,&reply_info); XDrawBeveledMatte(display,&windows->widget,&scroll_info); XDrawTriangleNorth(display,&windows->widget,&north_info); XDrawBeveledButton(display,&windows->widget,&slider_info); XDrawTriangleSouth(display,&windows->widget,&south_info); XHighlightWidget(display,&windows->widget,BorderOffset,BorderOffset); state&=(~UpdateListState); } if (state & JumpListState) { /* Jump scroll to match user color. */ list_info.id=(~0); for (i=0; i < colors; i++) if (strcmp(colorlist[i],reply) >= 0) { list_info.id=strcmp(colorlist[i],reply) == 0 ? i : ~0; break; } if ((i < slider_info.id) || (i >= (slider_info.id+visible_colors))) slider_info.id=i-(visible_colors >> 1); selection_info.id=(~0); state|=RedrawListState; state&=(~JumpListState); } if (state & RedrawListState) { /* Determine slider id and position. */ if (slider_info.id >= (int) (colors-visible_colors)) slider_info.id=colors-visible_colors; if ((slider_info.id < 0) || (colors <= visible_colors)) slider_info.id=0; slider_info.y=slider_info.min_y; if (colors > 0) slider_info.y+= slider_info.id*(slider_info.max_y-slider_info.min_y+1)/colors; if (slider_info.id != selection_info.id) { /* Redraw scroll bar and file names. */ selection_info.id=slider_info.id; selection_info.y=list_info.y+(height >> 3)+2; for (i=0; i < visible_colors; i++) { selection_info.raised=(slider_info.id+i) != list_info.id; selection_info.text=(char *) NULL; if ((slider_info.id+i) < colors) selection_info.text=colorlist[slider_info.id+i]; XDrawWidgetText(display,&windows->widget,&selection_info); selection_info.y+=(int) selection_info.height; } /* Update slider. */ if (slider_info.y > expose_info.y) { expose_info.height=slider_info.y-expose_info.y; expose_info.y=slider_info.y-expose_info.height- slider_info.bevel_width-1; } else { expose_info.height=expose_info.y-slider_info.y; expose_info.y=slider_info.y+slider_info.height+ slider_info.bevel_width+1; } XDrawTriangleNorth(display,&windows->widget,&north_info); XDrawMatte(display,&windows->widget,&expose_info); XDrawBeveledButton(display,&windows->widget,&slider_info); XDrawTriangleSouth(display,&windows->widget,&south_info); expose_info.y=slider_info.y; } state&=(~RedrawListState); } if (state & RedrawActionState) { static char colorname[MaxTextExtent]; /* Display the selected color in a drawing area. */ color=windows->widget.pixel_info->matte_color; (void) XParseColor(display,windows->widget.map_info->colormap, reply_info.text,&windows->widget.pixel_info->matte_color); XBestPixel(display,windows->widget.map_info->colormap,(XColor *) NULL, (unsigned int) windows->widget.visual_info->colormap_size, &windows->widget.pixel_info->matte_color); mode_info.text=colorname; (void) sprintf(mode_info.text,"#%02x%02x%02x", XDownScale(windows->widget.pixel_info->matte_color.red), XDownScale(windows->widget.pixel_info->matte_color.green), XDownScale(windows->widget.pixel_info->matte_color.blue)); XDrawBeveledButton(display,&windows->widget,&mode_info); windows->widget.pixel_info->matte_color=color; state&=(~RedrawActionState); } /* Wait for next event. */ if (north_info.raised && south_info.raised) XIfEvent(display,&event,XScreenEvent,(char *) windows); else { /* Brief delay before advancing scroll bar. */ XDelay(display,delay); delay=SuspendTime; XCheckIfEvent(display,&event,XScreenEvent,(char *) windows); if (!north_info.raised) if (slider_info.id > 0) { /* Move slider up. */ slider_info.id--; state|=RedrawListState; } if (!south_info.raised) if (slider_info.id < colors) { /* Move slider down. */ slider_info.id++; state|=RedrawListState; } if (event.type != ButtonRelease) continue; } switch (event.type) { case ButtonPress: { if (MatteIsActive(slider_info,event.xbutton)) { /* Track slider. */ slider_info.active=True; break; } if (MatteIsActive(north_info,event.xbutton)) if (slider_info.id > 0) { /* Move slider up. */ north_info.raised=False; slider_info.id--; state|=RedrawListState; break; } if (MatteIsActive(south_info,event.xbutton)) if (slider_info.id < colors) { /* Move slider down. */ south_info.raised=False; slider_info.id++; state|=RedrawListState; break; } if (MatteIsActive(scroll_info,event.xbutton)) { /* Move slider. */ if (event.xbutton.y < slider_info.y) slider_info.id-=(visible_colors-1); else slider_info.id+=(visible_colors-1); state|=RedrawListState; break; } if (MatteIsActive(list_info,event.xbutton)) { unsigned int id; /* User pressed list matte. */ id=slider_info.id+(event.xbutton.y-(list_info.y+(height >> 1))+1)/ selection_info.height; if (id >= colors) break; (void) strcpy(reply_info.text,colorlist[id]); reply_info.highlight=False; reply_info.marker=reply_info.text; reply_info.cursor=reply_info.text+Extent(reply_info.text); XDrawMatteText(display,&windows->widget,&reply_info); state|=RedrawActionState; if (id == list_info.id) { (void) strcpy(glob_pattern,reply_info.text); state|=UpdateListState; } selection_info.id=(~0); list_info.id=id; state|=RedrawListState; break; } if (MatteIsActive(grab_info,event.xbutton)) { /* User pressed Grab button. */ grab_info.raised=False; XDrawBeveledButton(display,&windows->widget,&grab_info); break; } if (MatteIsActive(reset_info,event.xbutton)) { /* User pressed Reset button. */ reset_info.raised=False; XDrawBeveledButton(display,&windows->widget,&reset_info); break; } if (MatteIsActive(mode_info,event.xbutton)) { /* User pressed mode button. */ (void) strcpy(reply_info.text,mode_info.text); (void) strcpy(primary_selection,reply_info.text); XSetSelectionOwner(display,XA_PRIMARY,windows->widget.id, event.xbutton.time); reply_info.highlight=XGetSelectionOwner(display,XA_PRIMARY) == windows->widget.id; reply_info.marker=reply_info.text; reply_info.cursor=reply_info.text+Extent(reply_info.text); XDrawMatteText(display,&windows->widget,&reply_info); break; } if (MatteIsActive(action_info,event.xbutton)) { /* User pressed action button. */ action_info.raised=False; XDrawBeveledButton(display,&windows->widget,&action_info); break; } if (MatteIsActive(cancel_info,event.xbutton)) { /* User pressed Cancel button. */ cancel_info.raised=False; XDrawBeveledButton(display,&windows->widget,&cancel_info); break; } if (!MatteIsActive(reply_info,event.xbutton)) break; if (event.xbutton.button != Button2) { static Time click_time; /* Move text cursor to position of button press. */ x=event.xbutton.x-reply_info.x-(QuantumMargin >> 2); for (i=1; i <= Extent(reply_info.marker); i++) if (XTextWidth(font_info,reply_info.marker,i) > x) break; reply_info.cursor=reply_info.marker+i-1; if (event.xbutton.time > (click_time+DoubleClick)) reply_info.highlight=False; else { /* Become the XA_PRIMARY selection owner. */ (void) strcpy(primary_selection,reply_info.text); XSetSelectionOwner(display,XA_PRIMARY,windows->widget.id, event.xbutton.time); reply_info.highlight=XGetSelectionOwner(display,XA_PRIMARY) == windows->widget.id; } XDrawMatteText(display,&windows->widget,&reply_info); click_time=event.xbutton.time; break; } /* Request primary selection. */ XConvertSelection(display,XA_PRIMARY,XA_STRING,XA_STRING, windows->widget.id,event.xbutton.time); break; } case ButtonRelease: { if (!windows->widget.mapped) break; if (!north_info.raised) { /* User released up button. */ delay=SuspendTime << 2; north_info.raised=True; XDrawTriangleNorth(display,&windows->widget,&north_info); } if (!south_info.raised) { /* User released down button. */ delay=SuspendTime << 2; south_info.raised=True; XDrawTriangleSouth(display,&windows->widget,&south_info); } if (slider_info.active) { /* Stop tracking slider. */ slider_info.active=False; break; } if (!grab_info.raised) { if (event.xbutton.window == windows->widget.id) if (MatteIsActive(grab_info,event.xbutton)) { /* Select a pen color from the X server. */ (void) XGetWindowColor(display,reply_info.text); reply_info.marker=reply_info.text; reply_info.cursor=reply_info.text+Extent(reply_info.text); XDrawMatteText(display,&windows->widget,&reply_info); state|=RedrawActionState; } grab_info.raised=True; XDrawBeveledButton(display,&windows->widget,&grab_info); } if (!reset_info.raised) { if (event.xbutton.window == windows->widget.id) if (MatteIsActive(reset_info,event.xbutton)) { (void) strcpy(glob_pattern,reset_pattern); state|=UpdateListState; } reset_info.raised=True; XDrawBeveledButton(display,&windows->widget,&reset_info); } if (!action_info.raised) { if (event.xbutton.window == windows->widget.id) if (MatteIsActive(action_info,event.xbutton)) if (*reply_info.text == '\0') XBell(display,0); else state|=ExitState; action_info.raised=True; XDrawBeveledButton(display,&windows->widget,&action_info); } if (!cancel_info.raised) { if (event.xbutton.window == windows->widget.id) if (MatteIsActive(cancel_info,event.xbutton)) { *reply_info.text='\0'; state|=ExitState; } cancel_info.raised=True; XDrawBeveledButton(display,&windows->widget,&cancel_info); } if (!MatteIsActive(reply_info,event.xbutton)) break; break; } case ClientMessage: { /* If client window delete message, exit. */ if (event.xclient.message_type != windows->wm_protocols) break; if (*event.xclient.data.l == windows->wm_take_focus) { XSetInputFocus(display,event.xclient.window,RevertToParent, event.xclient.data.l[1]); break; } if (*event.xclient.data.l != windows->wm_delete_window) break; if (event.xclient.window == windows->widget.id) { *reply_info.text='\0'; state|=ExitState; break; } break; } case ConfigureNotify: { /* Update widget configuration. */ if (event.xconfigure.window != windows->widget.id) break; if ((event.xconfigure.width == windows->widget.width) && (event.xconfigure.height == windows->widget.height)) break; windows->widget.width= Max(event.xconfigure.width,windows->widget.min_width); windows->widget.height= Max(event.xconfigure.height,windows->widget.min_height); state|=UpdateConfigurationState; break; } case EnterNotify: { if (event.xcrossing.window != windows->widget.id) break; state&=(~InactiveWidgetState); break; } case Expose: { if (event.xexpose.window != windows->widget.id) break; if (event.xexpose.count != 0) break; state|=RedrawWidgetState; break; } case KeyPress: { static char command[MaxTextExtent]; static int length; static KeySym key_symbol; if (event.xkey.window != windows->widget.id) break; /* Respond to a user key press. */ length=XLookupString((XKeyEvent *) &event.xkey,command,sizeof(command), &key_symbol,(XComposeStatus *) NULL); *(command+length)='\0'; if (AreaIsActive(scroll_info,event.xkey)) { /* Move slider. */ switch (key_symbol) { case XK_Home: case XK_KP_Home: { slider_info.id=0; break; } case XK_Up: case XK_KP_Up: { slider_info.id--; break; } case XK_Down: case XK_KP_Down: { slider_info.id++; break; } case XK_Prior: case XK_KP_Prior: { slider_info.id-=visible_colors; break; } case XK_Next: case XK_KP_Next: { slider_info.id+=visible_colors; break; } case XK_End: case XK_KP_End: { slider_info.id=colors; break; } } state|=RedrawListState; break; } if ((key_symbol == XK_Return) || (key_symbol == XK_KP_Enter)) { /* Read new color or glob patterm. */ if (*reply_info.text == '\0') break; (void) strcpy(glob_pattern,reply_info.text); state|=UpdateListState; break; } if (key_symbol == XK_Control_L) { state|=ControlState; break; } if (state & ControlState) switch (key_symbol) { case XK_u: case XK_U: { /* Erase the entire line of text. */ *reply_info.text='\0'; reply_info.cursor=reply_info.text; reply_info.marker=reply_info.text; reply_info.highlight=False; break; } default: break; } XEditText(display,&reply_info,key_symbol,command,state); XDrawMatteText(display,&windows->widget,&reply_info); state|=JumpListState; status=XParseColor(display,windows->widget.map_info->colormap, reply_info.text,&color); if (status != 0) state|=RedrawActionState; break; } case KeyRelease: { static char command[MaxTextExtent]; static KeySym key_symbol; if (event.xkey.window != windows->widget.id) break; /* Respond to a user key release. */ (void) XLookupString((XKeyEvent *) &event.xkey,command,sizeof(command), &key_symbol,(XComposeStatus *) NULL); if (key_symbol == XK_Control_L) state&=(~ControlState); break; } case LeaveNotify: { if (event.xcrossing.window != windows->widget.id) break; state|=InactiveWidgetState; break; } case MapNotify: { mask&=(~CWX); mask&=(~CWY); break; } case MotionNotify: { /* Discard pending button motion events. */ while (XCheckMaskEvent(display,ButtonMotionMask,&event)); if (slider_info.active) { /* Move slider matte. */ slider_info.y=event.xmotion.y- ((slider_info.height+slider_info.bevel_width) >> 1)+1; if (slider_info.y < slider_info.min_y) slider_info.y=slider_info.min_y; if (slider_info.y > slider_info.max_y) slider_info.y=slider_info.max_y; slider_info.id=0; if (slider_info.y != slider_info.min_y) slider_info.id=(colors*(slider_info.y-slider_info.min_y+1))/ (slider_info.max_y-slider_info.min_y+1); state|=RedrawListState; break; } if (state & InactiveWidgetState) break; if (grab_info.raised == MatteIsActive(grab_info,event.xmotion)) { /* Grab button status changed. */ grab_info.raised=!grab_info.raised; XDrawBeveledButton(display,&windows->widget,&grab_info); break; } if (reset_info.raised == MatteIsActive(reset_info,event.xmotion)) { /* Reset button status changed. */ reset_info.raised=!reset_info.raised; XDrawBeveledButton(display,&windows->widget,&reset_info); break; } if (action_info.raised == MatteIsActive(action_info,event.xmotion)) { /* Action button status changed. */ action_info.raised=!action_info.raised; XDrawBeveledButton(display,&windows->widget,&action_info); break; } if (cancel_info.raised == MatteIsActive(cancel_info,event.xmotion)) { /* Cancel button status changed. */ cancel_info.raised=!cancel_info.raised; XDrawBeveledButton(display,&windows->widget,&cancel_info); break; } break; } case SelectionClear: { reply_info.highlight=False; XDrawMatteText(display,&windows->widget,&reply_info); break; } case SelectionNotify: { Atom type; int format, status; unsigned char *data; unsigned long after, length; /* Obtain response from primary selection. */ if (event.xselection.property == (Atom) None) break; status=XGetWindowProperty(display,event.xselection.requestor, event.xselection.property,0L,2047L,True,XA_STRING,&type,&format, &length,&after,&data); if ((status != Success) || (type != XA_STRING) || (format == 32) || (length == 0)) break; if ((Extent(reply_info.text)+length) >= MaxTextExtent) XBell(display,0); else { /* Insert primary selection in reply text. */ *(data+length)='\0'; XEditText(display,&reply_info,(KeySym) XK_Insert,(char *) data, state); XDrawMatteText(display,&windows->widget,&reply_info); state|=JumpListState; state|=RedrawActionState; } XFree((void *) data); break; } case SelectionRequest: { XSelectionEvent notify; XSelectionRequestEvent *request; if (!reply_info.highlight) break; /* Set primary selection. */ request=(&(event.xselectionrequest)); XChangeProperty(request->display,request->requestor,request->property, request->target,8,PropModeReplace,(unsigned char *) primary_selection, Extent(primary_selection)); notify.type=SelectionNotify; notify.send_event=True; notify.display=request->display; notify.requestor=request->requestor; notify.selection=request->selection; notify.target=request->target; notify.time=request->time; if (request->property == None) notify.property=request->target; else notify.property=request->property; (void) XSendEvent(request->display,request->requestor,False,NoEventMask, (XEvent *) ¬ify); } default: break; } } while (!(state & ExitState)); XSetCursorState(display,windows,False); XWithdrawWindow(display,windows->widget.id,windows->widget.screen); XCheckRefreshWindows(display,windows); /* Free color list. */ for (i=0; i < colors; i++) free((char *) colorlist[i]); if (colorlist != (char **) NULL) free((char *) colorlist); if ((*reply == '\0') || (strchr(reply,'-') != (char *) NULL)) return; status=XParseColor(display,windows->widget.map_info->colormap,reply,&color); if (status != 0) return; XNoticeWidget(display,windows,"Color is unknown to X server:",reply); (void) strcpy(reply,"gray"); } /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % X C o m m a n d W i d g e t % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % Function XCommandWidget maps a menu and returns the command pointed to by % the user when the button is released. % % The format of the XCommandWidget routine is: % % selection_number=XCommandWidget(display,windows,selections,event) % % A description of each parameter follows: % % o selection_number: Specifies the number of the selection that the % user choose. % % o display: Specifies a connection to an X server; returned from % XOpenDisplay. % % o window: Specifies a pointer to a XWindows structure. % % o selections: Specifies a pointer to one or more strings that comprise % the choices in the menu. % % o event: Specifies a pointer to a X11 XEvent structure. % % */ Export int XCommandWidget(Display *display,XWindows *windows,char **selections, XEvent *event) { #define tile_width 112 #define tile_height 70 static unsigned char tile_bits[]= { 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x38, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0xbc, 0x9f, 0x03, 0x00, 0x3e, 0x00, 0xc0, 0x1f, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x1e, 0xfc, 0xff, 0x0f, 0x80, 0x3f, 0x00, 0xf0, 0x1f, 0xc0, 0x0f, 0x00, 0x00, 0x00, 0x1e, 0xfc, 0xff, 0x1f, 0xe0, 0x3f, 0x00, 0xfc, 0x1f, 0xf0, 0x0f, 0x00, 0x00, 0x00, 0x1e, 0xfc, 0xff, 0x1f, 0xf0, 0x3f, 0x00, 0xfe, 0x1f, 0xf8, 0x0f, 0x00, 0x00, 0x00, 0x1e, 0xfc, 0xfc, 0x3f, 0xf8, 0x3f, 0x00, 0xff, 0x1e, 0xfc, 0x0f, 0x00, 0x00, 0x00, 0x1e, 0x7c, 0xfc, 0x3e, 0xf8, 0x3c, 0x80, 0x1f, 0x1e, 0x7c, 0x0f, 0x00, 0x00, 0x00, 0x1e, 0x78, 0x78, 0x3c, 0x7c, 0x3c, 0xc0, 0x0f, 0x1e, 0x3e, 0x0f, 0x00, 0x00, 0x00, 0x1e, 0x78, 0x78, 0x3c, 0x7c, 0x3c, 0xc0, 0x07, 0x1e, 0x3e, 0x0f, 0x00, 0x00, 0x00, 0x1e, 0x78, 0x78, 0x3c, 0x7c, 0x7c, 0xc0, 0x0f, 0x1e, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x78, 0x78, 0x3c, 0xfc, 0x7c, 0x80, 0x7f, 0x1e, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x1e, 0xf8, 0x78, 0x7c, 0xf8, 0xff, 0x00, 0xff, 0x1f, 0xf8, 0xff, 0x00, 0x00, 0x00, 0x1e, 0xf8, 0x78, 0x7c, 0xf0, 0xff, 0x07, 0xfe, 0x1f, 0xf8, 0xff, 0x00, 0x00, 0x00, 0x1e, 0xf8, 0x78, 0x7c, 0xf0, 0xff, 0x07, 0xf8, 0x1f, 0xf0, 0xff, 0x01, 0x00, 0x00, 0x1e, 0xf8, 0x78, 0x7c, 0xc0, 0xef, 0x07, 0xe0, 0x1f, 0xc0, 0xff, 0x01, 0x00, 0x00, 0x1e, 0x70, 0x40, 0x78, 0x00, 0xc7, 0x07, 0x00, 0x1e, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x07, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x0f, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0xc0, 0x0f, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0xc0, 0x8f, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0xc0, 0x8f, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0xe0, 0x9f, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0xe0, 0xdf, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x78, 0x00, 0xe0, 0xdf, 0x7b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x0c, 0x78, 0x30, 0xf0, 0xff, 0x7b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x0f, 0xf8, 0x70, 0xf0, 0xff, 0x7b, 0x00, 0x00, 0x1f, 0x00, 0xe0, 0x0f, 0x1e, 0x80, 0x0f, 0xf8, 0x78, 0xf0, 0xfd, 0xf9, 0x00, 0xc0, 0x1f, 0x00, 0xf8, 0x0f, 0x00, 0xe0, 0x1f, 0xf8, 0x7c, 0xf0, 0xfc, 0xf9, 0x00, 0xf0, 0x1f, 0x00, 0xfe, 0x0f, 0x00, 0xf0, 0x07, 0xf8, 0x3e, 0xf8, 0xfc, 0xf0, 0x01, 0xf8, 0x1f, 0x00, 0xff, 0x0f, 0x1e, 0xf0, 0x03, 0xf8, 0x3f, 0xf8, 0xf8, 0xf0, 0x01, 0xfc, 0x1f, 0x80, 0x7f, 0x0f, 0x1e, 0xf8, 0x00, 0xf8, 0x1f, 0x78, 0x18, 0xf0, 0x01, 0x7c, 0x1e, 0xc0, 0x0f, 0x0f, 0x1e, 0x7c, 0x00, 0xf0, 0x0f, 0x78, 0x00, 0xf0, 0x01, 0x3e, 0x1e, 0xe0, 0x07, 0x0f, 0x1e, 0x7c, 0x00, 0xf0, 0x07, 0x7c, 0x00, 0xe0, 0x01, 0x3e, 0x1e, 0xe0, 0x03, 0x0f, 0x1e, 0x3e, 0x00, 0xf0, 0x0f, 0x7c, 0x00, 0xe0, 0x03, 0x3e, 0x3e, 0xe0, 0x07, 0x0f, 0x1e, 0x1e, 0x00, 0xf0, 0x1f, 0x3c, 0x00, 0xe0, 0x03, 0x7e, 0x3e, 0xc0, 0x3f, 0x0f, 0x1e, 0x3e, 0x00, 0xf0, 0x1f, 0x3e, 0x00, 0xe0, 0x03, 0xfc, 0x7f, 0x80, 0xff, 0x0f, 0x1e, 0xfc, 0x00, 0xf0, 0x3e, 0x3e, 0x00, 0xc0, 0x03, 0xf8, 0xff, 0x03, 0xff, 0x0f, 0x1e, 0xfc, 0x07, 0xf0, 0x7c, 0x1e, 0x00, 0xc0, 0x03, 0xf8, 0xff, 0x03, 0xfc, 0x0f, 0x1e, 0xf8, 0x1f, 0xf0, 0xf8, 0x1e, 0x00, 0xc0, 0x03, 0xe0, 0xf7, 0x03, 0xf0, 0x0f, 0x1e, 0xe0, 0x3f, 0xf0, 0x78, 0x1c, 0x00, 0x80, 0x03, 0x80, 0xe3, 0x03, 0x00, 0x0f, 0x1e, 0xc0, 0x3f, 0xf0, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x0e, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x0f, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; int id, y; register int i; static unsigned int number_selections; static XWidgetInfo *selection_info = (XWidgetInfo *) NULL; unsigned int height; unsigned long state; XFontStruct *font_info; assert(display != (Display *) NULL); assert(windows != (XWindows *) NULL); font_info=windows->command.font_info; height=font_info->ascent+font_info->descent; state=DefaultState; if (event == (XEvent *) NULL) { unsigned int width; XTextProperty window_name; XWindowChanges window_changes; /* Determine command window attributes. */ assert(selections != (char **) NULL); windows->command.width=0; for (i=0; selections[i] != (char *) NULL; i++) { width=XTextWidth(font_info,selections[i],Extent(selections[i])); if (width > windows->command.width) windows->command.width=width; } number_selections=i; windows->command.width+=3*QuantumMargin+10; if (windows->command.width < (tile_width+QuantumMargin+10)) windows->command.width=tile_width+QuantumMargin+10; windows->command.height= number_selections*(((3*height) >> 1)+10)+tile_height+20; windows->command.min_width=windows->command.width; windows->command.min_height=windows->command.height; XConstrainWindowPosition(display,&windows->command); if (windows->command.id != (Window) NULL) { int status; /* Reconfigure command window. */ status=XStringListToTextProperty(&windows->command.name,1, &window_name); if (status != 0) { XSetWMName(display,windows->command.id,&window_name); XSetWMIconName(display,windows->command.id,&window_name); XFree((void *) window_name.value); } window_changes.width=windows->command.width; window_changes.height=windows->command.height; XReconfigureWMWindow(display,windows->command.id, windows->command.screen,CWWidth | CWHeight,&window_changes); } /* Allocate selection info memory. */ if (selection_info != (XWidgetInfo *) NULL) free((char *) selection_info); selection_info=(XWidgetInfo *) malloc(number_selections*sizeof(XWidgetInfo)); if (selection_info == (XWidgetInfo *) NULL) Error("Unable to create Command Widget","Memory allocation failed"); state|=UpdateConfigurationState; } /* Wait for next event. */ id=(~0); if (event != (XEvent *) NULL) switch (event->type) { case ButtonPress: { for (i=0; i < number_selections; i++) { if (!MatteIsActive(selection_info[i],event->xbutton)) continue; if (i >= windows->command.data) { selection_info[i].raised=False; XDrawBeveledButton(display,&windows->command,&selection_info[i]); break; } submenu_info=selection_info[i]; submenu_info.active=True; toggle_info.y= submenu_info.y+(submenu_info.height >> 1)-(toggle_info.height >> 1); id=i; XCheckWindowEvent(display,windows->widget.id,LeaveWindowMask,event); break; } break; } case ButtonRelease: { for (i=0; i < number_selections; i++) { if (!MatteIsActive(selection_info[i],event->xbutton)) continue; id=i; if (id >= windows->command.data) { selection_info[id].raised=True; XDrawBeveledButton(display,&windows->command,&selection_info[id]); break; } break; } break; } case ClientMessage: { /* If client window delete message, withdraw command widget. */ if (event->xclient.message_type != windows->wm_protocols) break; if (*event->xclient.data.l != windows->wm_delete_window) break; XWithdrawWindow(display,windows->command.id,windows->command.screen); break; } case ConfigureNotify: { /* Update widget configuration. */ if (event->xconfigure.window != windows->command.id) break; if (event->xconfigure.send_event != 0) { windows->command.x=event->xconfigure.x; windows->command.y=event->xconfigure.y; } if ((event->xconfigure.width == windows->command.width) && (event->xconfigure.height == windows->command.height)) break; windows->command.width= Max(event->xconfigure.width,windows->command.min_width); windows->command.height= Max(event->xconfigure.height,windows->command.min_height); state|=UpdateConfigurationState; break; } case Expose: { if (event->xexpose.window != windows->command.id) break; if (event->xexpose.count != 0) break; state|=RedrawWidgetState; break; } case MotionNotify: { /* Return the ID of the highlighted menu entry. */ for ( ; ; ) { for (i=0; i < number_selections; i++) { if (i >= windows->command.data) { if (selection_info[i].raised == MatteIsActive(selection_info[i],event->xmotion)) { /* Button status changed. */ selection_info[i].raised=!selection_info[i].raised; XDrawBeveledButton(display,&windows->command, &selection_info[i]); } continue; } if (!MatteIsActive(selection_info[i],event->xmotion)) continue; submenu_info=selection_info[i]; submenu_info.active=True; toggle_info.raised=True; toggle_info.y=submenu_info.y+(submenu_info.height >> 1)- (toggle_info.height >> 1); XDrawTriangleEast(display,&windows->command,&toggle_info); id=i; } XDelay(display,SuspendTime); if (!XCheckMaskEvent(display,ButtonMotionMask,event)) break; while (XCheckMaskEvent(display,ButtonMotionMask,event)); toggle_info.raised=False; if (windows->command.data > 0) XDrawTriangleEast(display,&windows->command,&toggle_info); } break; } case MapNotify: { windows->command.mapped=True; break; } case UnmapNotify: { windows->command.mapped=False; break; } default: break; } if (state & UpdateConfigurationState) { /* Initialize button information. */ assert(selections != (char **) NULL); y=tile_height+20; for (i=0; i < number_selections; i++) { XGetWidgetInfo(selections[i],&selection_info[i]); selection_info[i].center=False; selection_info[i].bevel_width--; selection_info[i].height=(3*height) >> 1; selection_info[i].x=(QuantumMargin >> 1)+4; selection_info[i].width= windows->command.width-(selection_info[i].x << 1); selection_info[i].y=y; y+=selection_info[i].height+(selection_info[i].bevel_width << 1)+6; } XGetWidgetInfo((char *) NULL,&toggle_info); toggle_info.bevel_width--; toggle_info.width=((5*height) >> 3)-(toggle_info.bevel_width << 1); toggle_info.height=toggle_info.width; toggle_info.x=selection_info[0].x+selection_info[0].width- toggle_info.width-(QuantumMargin >> 1); if (windows->command.mapped) XClearWindow(display,windows->command.id); } if (state & RedrawWidgetState) { Pixmap tile_pixmap; /* Draw command buttons. */ tile_pixmap=XCreatePixmapFromBitmapData(display,windows->command.id, (char *) tile_bits,tile_width,tile_height,1L,0L,1); if (tile_pixmap != (Pixmap) NULL) { XCopyPlane(display,tile_pixmap,windows->command.id, windows->command.annotate_context,0,0,tile_width,tile_height, (windows->command.width-tile_width) >> 1,10,1L); XFreePixmap(display,tile_pixmap); } for (i=0; i < number_selections; i++) { XDrawBeveledButton(display,&windows->command,&selection_info[i]); if (i >= windows->command.data) continue; toggle_info.raised=i == id; toggle_info.y=selection_info[i].y+ (selection_info[i].height >> 1)-(toggle_info.height >> 1); XDrawTriangleEast(display,&windows->command,&toggle_info); } XHighlightWidget(display,&windows->command,BorderOffset,BorderOffset); } return(id); } /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % X C o n f i r m W i d g e t % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % Function XConfirmWidget displays a Confirm widget with a notice to the user. % The function returns -1 if Dismiss is pressed, 0 for Cancel, and 1 for % Yes. % % The format of the XConfirmWidget routine is: % % status=XConfirmWidget(display,windows,message,qualifier) % % A description of each parameter follows: % % o status: Function XConfirmWidget returns True if the user presses Yes % otherwise False is returned. % % o display: Specifies a connection to an X server; returned from % XOpenDisplay. % % o window: Specifies a pointer to a XWindows structure. % % o message: Specifies the message to display before terminating the % program. % % o qualifier: Specifies any qualifier to the message. % % */ Export int XConfirmWidget(Display *display,XWindows *windows, const char *message,const char *qualifier) { #define CancelButtonText "Cancel" #define DismissButtonText "Dismiss" #define YesButtonText "Yes" int confirm, status, x, y; unsigned int height, width; unsigned long state; XEvent event; XFontStruct *font_info; XTextProperty window_name; XWidgetInfo cancel_info, dismiss_info, yes_info; XWindowChanges window_changes; /* Determine Confirm widget attributes. */ assert(display != (Display *) NULL); assert(windows != (XWindows *) NULL); assert(message != (char *) NULL); assert(qualifier != (char *) NULL); XCheckRefreshWindows(display,windows); font_info=windows->widget.font_info; width=XTextWidth(font_info,CancelButtonText,Extent(CancelButtonText)); if (XTextWidth(font_info,DismissButtonText,Extent(DismissButtonText)) > width) width=XTextWidth(font_info,DismissButtonText,Extent(DismissButtonText)); if (XTextWidth(font_info,YesButtonText,Extent(YesButtonText)) > width) width=XTextWidth(font_info,YesButtonText,Extent(YesButtonText)); width<<=1; if (qualifier != (char *) NULL) if (XTextWidth(font_info,qualifier,Extent(qualifier)) > width) width=XTextWidth(font_info,qualifier,Extent(qualifier)); if (qualifier != (char *) NULL) if (XTextWidth(font_info,qualifier,Extent(qualifier)) > width) width=XTextWidth(font_info,qualifier,Extent(qualifier)); height=(font_info->ascent+font_info->descent); /* Position Confirm widget. */ windows->widget.width=width+9*QuantumMargin; windows->widget.min_width=9*QuantumMargin+ XTextWidth(font_info,CancelButtonText,Extent(CancelButtonText))+ XTextWidth(font_info,DismissButtonText,Extent(DismissButtonText))+ XTextWidth(font_info,YesButtonText,Extent(YesButtonText)); if (windows->widget.width < windows->widget.min_width) windows->widget.width=windows->widget.min_width; windows->widget.height=12*height; windows->widget.min_height=7*height; if (windows->widget.height < windows->widget.min_height) windows->widget.height=windows->widget.min_height; XQueryPosition(display,windows->widget.root,&x,&y); windows->widget.x=x-(windows->widget.width >> 1); windows->widget.y=y-((5*windows->widget.height) >> 3); XConstrainWindowPosition(display,&windows->widget); /* Map Confirm widget. */ (void) strcpy(windows->widget.name,"Confirm"); status=XStringListToTextProperty(&windows->widget.name,1,&window_name); if (status != 0) { XSetWMName(display,windows->widget.id,&window_name); XSetWMIconName(display,windows->widget.id,&window_name); XFree((void *) window_name.value); } window_changes.width=windows->widget.width; window_changes.height=windows->widget.height; window_changes.x=windows->widget.x; window_changes.y=windows->widget.y; XReconfigureWMWindow(display,windows->widget.id,windows->widget.screen, CWWidth | CWHeight | CWX | CWY,&window_changes); XMapRaised(display,windows->widget.id); windows->widget.mapped=False; /* Respond to X events. */ confirm=0; state=UpdateConfigurationState; XSetCursorState(display,windows,True); do { if (state & UpdateConfigurationState) { /* Initialize button information. */ XGetWidgetInfo(CancelButtonText,&cancel_info); cancel_info.width=QuantumMargin+ XTextWidth(font_info,CancelButtonText,Extent(CancelButtonText)); cancel_info.height=(3*height) >> 1; cancel_info.x=windows->widget.width-cancel_info.width-QuantumMargin; cancel_info.y=windows->widget.height-(cancel_info.height << 1); dismiss_info=cancel_info; dismiss_info.text=DismissButtonText; if (strcmp(qualifier,"Do you want to save it") == 0) dismiss_info.text="Don't Save"; dismiss_info.width=QuantumMargin+ XTextWidth(font_info,dismiss_info.text,Extent(dismiss_info.text)); dismiss_info.x=(windows->widget.width >> 1)-(dismiss_info.width >> 1); yes_info=cancel_info; yes_info.text=YesButtonText; if (strcmp(qualifier,"Do you want to save it") == 0) yes_info.text="Save"; yes_info.width=QuantumMargin+ XTextWidth(font_info,yes_info.text,Extent(yes_info.text)); if (yes_info.width < cancel_info.width) yes_info.width=cancel_info.width; yes_info.x=QuantumMargin; state&=(~UpdateConfigurationState); } if (state & RedrawWidgetState) { /* Redraw Confirm widget. */ width=XTextWidth(font_info,message,Extent(message)); x=(windows->widget.width >> 1)-(width >> 1); y=(windows->widget.height >> 1)-(height << 1); XDrawString(display,windows->widget.id,windows->widget.annotate_context, x,y,message,Extent(message)); if (qualifier != (char *) NULL) { char question[MaxTextExtent]; (void) strcpy(question,qualifier); (void) strcat(question,"?"); width=XTextWidth(font_info,question,Extent(question)); x=(windows->widget.width >> 1)-(width >> 1); y+=height; XDrawString(display,windows->widget.id, windows->widget.annotate_context,x,y,question,Extent(question)); } XDrawBeveledButton(display,&windows->widget,&cancel_info); XDrawBeveledButton(display,&windows->widget,&dismiss_info); XDrawBeveledButton(display,&windows->widget,&yes_info); XHighlightWidget(display,&windows->widget,BorderOffset,BorderOffset); state&=(~RedrawWidgetState); } /* Wait for next event. */ XIfEvent(display,&event,XScreenEvent,(char *) windows); switch (event.type) { case ButtonPress: { if (MatteIsActive(cancel_info,event.xbutton)) { /* User pressed No button. */ cancel_info.raised=False; XDrawBeveledButton(display,&windows->widget,&cancel_info); break; } if (MatteIsActive(dismiss_info,event.xbutton)) { /* User pressed Dismiss button. */ dismiss_info.raised=False; XDrawBeveledButton(display,&windows->widget,&dismiss_info); break; } if (MatteIsActive(yes_info,event.xbutton)) { /* User pressed Yes button. */ yes_info.raised=False; XDrawBeveledButton(display,&windows->widget,&yes_info); break; } break; } case ButtonRelease: { if (!windows->widget.mapped) break; if (!cancel_info.raised) { if (event.xbutton.window == windows->widget.id) if (MatteIsActive(cancel_info,event.xbutton)) { confirm=0; state|=ExitState; } cancel_info.raised=True; XDrawBeveledButton(display,&windows->widget,&cancel_info); } if (!dismiss_info.raised) { if (event.xbutton.window == windows->widget.id) if (MatteIsActive(dismiss_info,event.xbutton)) { confirm=(-1); state|=ExitState; } dismiss_info.raised=True; XDrawBeveledButton(display,&windows->widget,&dismiss_info); } if (!yes_info.raised) { if (event.xbutton.window == windows->widget.id) if (MatteIsActive(yes_info,event.xbutton)) { confirm=1; state|=ExitState; } yes_info.raised=True; XDrawBeveledButton(display,&windows->widget,&yes_info); } break; } case ClientMessage: { /* If client window delete message, exit. */ if (event.xclient.message_type != windows->wm_protocols) break; if (*event.xclient.data.l == windows->wm_take_focus) { XSetInputFocus(display,event.xclient.window,RevertToParent, event.xclient.data.l[1]); break; } if (*event.xclient.data.l != windows->wm_delete_window) break; if (event.xclient.window == windows->widget.id) { state|=ExitState; break; } break; } case ConfigureNotify: { /* Update widget configuration. */ if (event.xconfigure.window != windows->widget.id) break; if ((event.xconfigure.width == windows->widget.width) && (event.xconfigure.height == windows->widget.height)) break; windows->widget.width= Max(event.xconfigure.width,windows->widget.min_width); windows->widget.height= Max(event.xconfigure.height,windows->widget.min_height); state|=UpdateConfigurationState; break; } case EnterNotify: { if (event.xcrossing.window != windows->widget.id) break; state&=(~InactiveWidgetState); break; } case Expose: { if (event.xexpose.window != windows->widget.id) break; if (event.xexpose.count != 0) break; state|=RedrawWidgetState; break; } case KeyPress: { static char command[MaxTextExtent]; static KeySym key_symbol; if (event.xkey.window != windows->widget.id) break; /* Respond to a user key press. */ (void) XLookupString((XKeyEvent *) &event.xkey,command,sizeof(command), &key_symbol,(XComposeStatus *) NULL); if ((key_symbol == XK_Return) || (key_symbol == XK_KP_Enter)) { yes_info.raised=False; XDrawBeveledButton(display,&windows->widget,&yes_info); confirm=1; state|=ExitState; break; } break; } case LeaveNotify: { if (event.xcrossing.window != windows->widget.id) break; state|=InactiveWidgetState; break; } case MotionNotify: { /* Discard pending button motion events. */ while (XCheckMaskEvent(display,ButtonMotionMask,&event)); if (state & InactiveWidgetState) break; if (cancel_info.raised == MatteIsActive(cancel_info,event.xmotion)) { /* Cancel button status changed. */ cancel_info.raised=!cancel_info.raised; XDrawBeveledButton(display,&windows->widget,&cancel_info); break; } if (dismiss_info.raised == MatteIsActive(dismiss_info,event.xmotion)) { /* Dismiss button status changed. */ dismiss_info.raised=!cancel_info.raised; XDrawBeveledButton(display,&windows->widget,&dismiss_info); break; } if (yes_info.raised == MatteIsActive(yes_info,event.xmotion)) { /* Yes button status changed. */ yes_info.raised=!yes_info.raised; XDrawBeveledButton(display,&windows->widget,&yes_info); break; } break; } default: break; } } while (!(state & ExitState)); XSetCursorState(display,windows,False); XWithdrawWindow(display,windows->widget.id,windows->widget.screen); XCheckRefreshWindows(display,windows); return(confirm); } /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % X D i a l o g W i d g e t % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % Function XDialogWidget displays a Dialog widget with a query to the user. % The user keys a reply and presses the Ok or Cancel button to exit. The % typed text is returned as the reply function parameter. % % The format of the XDialogWidget routine is: % % XDialogWidget(display,windows,action,query,reply) % % A description of each parameter follows: % % o display: Specifies a connection to an X server; returned from % XOpenDisplay. % % o window: Specifies a pointer to a XWindows structure. % % o action: Specifies a pointer to the action of this widget. % % o query: Specifies a pointer to the query to present to the user. % % o reply: The response from the user is returned in this parameter. % % */ Export int XDialogWidget(Display *display,XWindows *windows,char *action, char *query,char *reply) { #define CancelButtonText "Cancel" char primary_selection[MaxTextExtent]; int status, x, y; register int i; static unsigned int raised = False; unsigned int anomaly, height, width; unsigned long state; XEvent event; XFontStruct *font_info; XTextProperty window_name; XWidgetInfo action_info, cancel_info, reply_info, special_info, text_info; XWindowChanges window_changes; /* Determine Dialog widget attributes. */ assert(display != (Display *) NULL); assert(windows != (XWindows *) NULL); assert(action != (char *) NULL); assert(query != (char *) NULL); assert(reply != (char *) NULL); XCheckRefreshWindows(display,windows); font_info=windows->widget.font_info; width=XTextWidth(font_info,action,Extent(action)); if (XTextWidth(font_info,CancelButtonText,Extent(CancelButtonText)) > width) width=XTextWidth(font_info,CancelButtonText,Extent(CancelButtonText)); width+=(3*QuantumMargin) >> 1; height=font_info->ascent+font_info->descent; /* Position Dialog widget. */ windows->widget.width=Max(2*width,XTextWidth(font_info,query,Extent(query))); if (windows->widget.width < XTextWidth(font_info,reply,Extent(reply))) windows->widget.width=XTextWidth(font_info,reply,Extent(reply)); windows->widget.width+=6*QuantumMargin; windows->widget.min_width= width+25*XTextWidth(font_info,"#",1)+4*QuantumMargin; if (windows->widget.width < windows->widget.min_width) windows->widget.width=windows->widget.min_width; windows->widget.height=7*height+(QuantumMargin << 1); windows->widget.min_height=windows->widget.height; if (windows->widget.height < windows->widget.min_height) windows->widget.height=windows->widget.min_height; XQueryPosition(display,windows->widget.root,&x,&y); windows->widget.x=x-(windows->widget.width >> 1); windows->widget.y=y-(windows->widget.height >> 1); XConstrainWindowPosition(display,&windows->widget); /* Map Dialog widget. */ (void) strcpy(windows->widget.name,"Dialog"); status=XStringListToTextProperty(&windows->widget.name,1,&window_name); if (status != 0) { XSetWMName(display,windows->widget.id,&window_name); XSetWMIconName(display,windows->widget.id,&window_name); XFree((void *) window_name.value); } window_changes.width=windows->widget.width; window_changes.height=windows->widget.height; window_changes.x=windows->widget.x; window_changes.y=windows->widget.y; XReconfigureWMWindow(display,windows->widget.id,windows->widget.screen, CWWidth | CWHeight | CWX | CWY,&window_changes); XMapRaised(display,windows->widget.id); windows->widget.mapped=False; /* Respond to X events. */ anomaly=(strcmp(action,"Background") == 0) || (strcmp(action,"New") == 0) || (strcmp(action,"Quantize") == 0) || (strcmp(action,"Resize") == 0) || (strcmp(action,"Save") == 0) || (strcmp(action,"Shade") == 0); state=UpdateConfigurationState; XSetCursorState(display,windows,True); do { if (state & UpdateConfigurationState) { /* Initialize button information. */ XGetWidgetInfo(CancelButtonText,&cancel_info); cancel_info.width=width; cancel_info.height=(3*height) >> 1; cancel_info.x= windows->widget.width-cancel_info.width-((3*QuantumMargin) >> 1); cancel_info.y= windows->widget.height-cancel_info.height-((3*QuantumMargin) >> 1); XGetWidgetInfo(action,&action_info); action_info.width=width; action_info.height=(3*height) >> 1; action_info.x=cancel_info.x-(cancel_info.width+QuantumMargin+ (action_info.bevel_width << 1)); action_info.y=cancel_info.y; /* Initialize reply information. */ XGetWidgetInfo(reply,&reply_info); reply_info.raised=False; reply_info.bevel_width--; reply_info.width=windows->widget.width-(3*QuantumMargin); reply_info.height=height << 1; reply_info.x=(3*QuantumMargin) >> 1; reply_info.y=action_info.y-reply_info.height-QuantumMargin; /* Initialize option information. */ XGetWidgetInfo("Dither",&special_info); special_info.raised=raised; special_info.bevel_width--; special_info.width=QuantumMargin >> 1; special_info.height=QuantumMargin >> 1; special_info.x=reply_info.x; special_info.y=action_info.y+action_info.height-special_info.height; if (strcmp(action,"Background") == 0) special_info.text="Backdrop"; if (strcmp(action,"New") == 0) special_info.text="Gradation"; if (strcmp(action,"Resize") == 0) special_info.text="Constrain ratio"; if (strcmp(action,"Save") == 0) special_info.text="Progressive"; if (strcmp(action,"Shade") == 0) special_info.text="Color shading"; /* Initialize text information. */ XGetWidgetInfo(query,&text_info); text_info.width=reply_info.width; text_info.height=height; text_info.x=reply_info.x-(QuantumMargin >> 1); text_info.y=QuantumMargin; text_info.center=False; state&=(~UpdateConfigurationState); } if (state & RedrawWidgetState) { /* Redraw Dialog widget. */ XDrawWidgetText(display,&windows->widget,&text_info); XDrawBeveledMatte(display,&windows->widget,&reply_info); XDrawMatteText(display,&windows->widget,&reply_info); if (anomaly) XDrawBeveledButton(display,&windows->widget,&special_info); XDrawBeveledButton(display,&windows->widget,&action_info); XDrawBeveledButton(display,&windows->widget,&cancel_info); XHighlightWidget(display,&windows->widget,BorderOffset,BorderOffset); state&=(~RedrawWidgetState); } /* Wait for next event. */ XIfEvent(display,&event,XScreenEvent,(char *) windows); switch (event.type) { case ButtonPress: { if (anomaly) if (MatteIsActive(special_info,event.xbutton)) { /* Option button status changed. */ special_info.raised=!special_info.raised; XDrawBeveledButton(display,&windows->widget,&special_info); break; } if (MatteIsActive(action_info,event.xbutton)) { /* User pressed Action button. */ action_info.raised=False; XDrawBeveledButton(display,&windows->widget,&action_info); break; } if (MatteIsActive(cancel_info,event.xbutton)) { /* User pressed Cancel button. */ cancel_info.raised=False; XDrawBeveledButton(display,&windows->widget,&cancel_info); break; } if (!MatteIsActive(reply_info,event.xbutton)) break; if (event.xbutton.button != Button2) { static Time click_time; /* Move text cursor to position of button press. */ x=event.xbutton.x-reply_info.x-(QuantumMargin >> 2); for (i=1; i <= Extent(reply_info.marker); i++) if (XTextWidth(font_info,reply_info.marker,i) > x) break; reply_info.cursor=reply_info.marker+i-1; if (event.xbutton.time > (click_time+DoubleClick)) reply_info.highlight=False; else { /* Become the XA_PRIMARY selection owner. */ (void) strcpy(primary_selection,reply_info.text); XSetSelectionOwner(display,XA_PRIMARY,windows->widget.id, event.xbutton.time); reply_info.highlight=XGetSelectionOwner(display,XA_PRIMARY) == windows->widget.id; } XDrawMatteText(display,&windows->widget,&reply_info); click_time=event.xbutton.time; break; } /* Request primary selection. */ XConvertSelection(display,XA_PRIMARY,XA_STRING,XA_STRING, windows->widget.id,event.xbutton.time); break; } case ButtonRelease: { if (!windows->widget.mapped) break; if (!action_info.raised) { if (event.xbutton.window == windows->widget.id) if (MatteIsActive(action_info,event.xbutton)) state|=ExitState; action_info.raised=True; XDrawBeveledButton(display,&windows->widget,&action_info); } if (!cancel_info.raised) { if (event.xbutton.window == windows->widget.id) if (MatteIsActive(cancel_info,event.xbutton)) { *reply_info.text='\0'; state|=ExitState; } cancel_info.raised=True; XDrawBeveledButton(display,&windows->widget,&cancel_info); } break; } case ClientMessage: { /* If client window delete message, exit. */ if (event.xclient.message_type != windows->wm_protocols) break; if (*event.xclient.data.l == windows->wm_take_focus) { XSetInputFocus(display,event.xclient.window,RevertToParent, event.xclient.data.l[1]); break; } if (*event.xclient.data.l != windows->wm_delete_window) break; if (event.xclient.window == windows->widget.id) { *reply_info.text='\0'; state|=ExitState; break; } break; } case ConfigureNotify: { /* Update widget configuration. */ if (event.xconfigure.window != windows->widget.id) break; if ((event.xconfigure.width == windows->widget.width) && (event.xconfigure.height =