home *** CD-ROM | disk | FTP | other *** search
- /*
- Copyright 1988 Torch Computers Ltd.
-
- Permission to use, copy, modify, and otherwise generally do what you like
- with this software is hereby granted provided that the above copyright notice
- appears in all copies.
-
- Torch disclaims all warranties implied or expressed with regard to this
- software. In no event shall Torch be liable for any damages arising from
- this use of software.
- */
-
- /********************************************************
- * *
- * Title Yorn, Gs and Alert *
- * *
- * File : alert.c *
- * Author : Gary Henderson *
- * Mark Howells *
- * Date : 27th Sep 1988. *
- * Purpose : Create and display the widgets for the *
- * yorn and alert boxes. *
- * *
- *********************************************************/
-
- /*------Include files-----------------------------------*/
-
- #include <stdio.h>
- #include <X11/Xlib.h>
- #include <X11/Xos.h>
- #include <X11/Xutil.h>
- #include <X11/StringDefs.h>
- #include <X11/Intrinsic.h>
- #include <X11/Form.h>
- #include <X11/Core.h>
- #include <X11/Shell.h>
- #include <X11/Label.h>
- #include <X11/Command.h>
-
- #include "alert.bitmaps"
-
- /*------Forward delarations-----------------------------*/
-
- static void Nack();
- static void OkAck();
- static void AlertExposures();
- static void AlertText();
- static Pixmap LoadSymbol ();
- extern long time ();
-
- typedef struct {
- unsigned int width, height;
- Pixmap id;
- Pixel foreground, background;
- } symbol;
-
- /*------Constants and macros----------------------------*/
-
- #define ALBOX1X 150
- #define ALBOX2X 250
-
- #define CROSS 1
- #define CHECK 0
- #define NOREPLY 100
-
- #ifndef MIN
- #define MIN(a,b) ((a) > (b) ? (b) : (a))
- #endif MIN
-
- #define ALTEXTWIDTH MIN ((sysfont->max_bounds.width * 40), \
- root_width / 5)
-
- #define ALTEXTHEIGHT ((sysfont->max_bounds.descent + \
- sysfont->max_bounds.ascent) * 6)
-
- #define ALONX ((root_width / 5 + rand () % 48))
-
- #define ALONY ((root_height / 5 + rand () % 48))
-
- /*------Exported variables/functions--------------------*/
-
- int ackreply = CROSS;
- Widget alertwidget;
-
- /*------Imported variables/functions--------------------*/
-
- extern Widget a_widget;
- extern XFontStruct *sysfont;
- extern unsigned int root_width, root_height;
- extern Display * display;
- extern Window root_window;
- extern int screen_number;
- extern Screen * screen;
- extern Boolean zoom;
- extern char *yornsym_name, *alertsym_name, *oksym_name, *ticksym_name,
- *crosssym_name;
- extern Cursor arrow_cursor;
-
- extern void ReadWidgetColours ();
-
- /*------Static variables--------------------------------*/
-
- static char *curtext;
- static Widget triangle, button1, button2, textwidget;
- static GC alert_gc, text_gc;
- static symbol warn, query, tick, cross, ok;
- static symbol *triangle_symbol, *button1_symbol, *button2_symbol;
-
- /*
- *****************
- * *
- * INITALERT *
- * *
- *****************
- -------------------------------------------------------------------------
- | Initialise the widgets for the yorn and alert boxes. |
- -------------------------------------------------------------------------
- */
- void InitAlert (geometry)
- char * geometry;
- {
- Widget formwidget;
- Arg args[10];
-
- static XtCallbackRec ackbacks[] = {
- {OkAck, NULL},
- {NULL, NULL},
- };
-
- static XtCallbackRec nackbacks[] = {
- {Nack, NULL},
- {NULL, NULL},
- };
- Pixel foreground, background;
-
- #ifdef BSD
- (void) srand ((int) time ((long *) 0));
- #endif BSD
-
- #if defined(UNISOFTV) || defined(SYSV)
- (void) srand ((unsigned int) time ((long *) 0));
- #endif /* UNISOFTV || SYSV */
-
- alert_gc = XCreateGC (display, root_window, 0L, (XGCValues *) 0);
- text_gc = XCreateGC (display, root_window, 0L, (XGCValues *) 0);
-
- XSetGraphicsExposures (display, alert_gc, False);
- XSetFillStyle (display, alert_gc, FillStippled);
-
- XSetGraphicsExposures (display, text_gc, False);
-
- XtSetArg (args[0], XtNx, ALONX);
- XtSetArg (args[1], XtNy, ALONY);
- XtSetArg (args[2], XtNgeometry, geometry);
-
- /* An alert (or yorn) box is a popup widget, its exact type depends
- on the zoom resource option */
-
- alertwidget = XtCreatePopupShell ("alert/yorn",
- zoom ? topLevelShellWidgetClass :
- overrideShellWidgetClass,
- a_widget,
- args,
- geometry ? 3 : 2);
-
- formwidget= XtCreateManagedWidget ("contents",
- formWidgetClass,
- alertwidget,
- (ArgList) 0,
- 0);
-
- /* Now a label widget for the /\ or /\
- / \ / \
- / ? \ / ! \
- ------ ------
- (a label widget has foreground colour that is used for the symbol's
- other colour) */
-
- XtSetArg (args[0], XtNhorizDistance, 10);
- XtSetArg (args[1], XtNvertDistance, 10);
- XtSetArg (args[2], XtNresizable, False);
- XtSetArg (args[3], XtNborderWidth, 0);
- XtSetArg (args[4], XtNlabel, "\0");
-
- triangle = XtCreateManagedWidget ("symbol", labelWidgetClass,
- formwidget, args, 5);
-
- query.width = queryform_width;
- query.height = queryform_height;
-
- query.id = LoadSymbol (triangle,
- queryform_bits,
- yornsym_name,
- &query.width,
- &query.height,
- &query.foreground,
- &query.background);
-
- warn.width = warnform_width;
- warn.height = warnform_height;
-
- warn.id = LoadSymbol (triangle,
- warnform_bits,
- alertsym_name,
- &warn.width,
- &warn.height,
- &warn.foreground,
- &warn.background);
-
- XtSetArg (args[0], XtNwidth, warn.width > query.width ?
- warn.width : query.width);
- XtSetArg (args[1], XtNheight, warn.height > query.height ?
- warn.height : query.height);
-
- XtSetValues (triangle, args, 2);
-
- XtAddEventHandler (triangle,
- StructureNotifyMask | ExposureMask,
- True,
- AlertExposures,
- (caddr_t) 0);
-
- /* Now a widget for the text. Use a label widget (because it has a
- foreground colour) and format the text ourselves. */
-
- XtSetArg (args[0], XtNborderWidth, 0);
- XtSetArg (args[1], XtNwidth, ALTEXTWIDTH);
- XtSetArg (args[2], XtNheight, ALTEXTHEIGHT);
- XtSetArg (args[3], XtNresizable, True);
- XtSetArg (args[4], XtNhorizDistance, 5);
- XtSetArg (args[5], XtNvertDistance, 1);
- XtSetArg (args[6], XtNfromHoriz, triangle);
- XtSetArg (args[7], XtNlabel, "\0");
-
- textwidget= XtCreateManagedWidget ("text", labelWidgetClass,
- formwidget, args, 8);
-
- ReadWidgetColours (textwidget, &foreground, &background);
-
- XSetForeground (display, text_gc, foreground);
- XSetBackground (display, text_gc, background);
- XSetFont (display, text_gc, sysfont->fid);
-
- XtAddEventHandler (textwidget,
- StructureNotifyMask | ExposureMask,
- True,
- AlertText,
- (caddr_t) &curtext);
-
- /* And finally (Esther) two command buttons */
-
- XtSetArg (args[0], XtNhorizDistance, ALBOX1X);
- XtSetArg (args[1], XtNvertDistance, 1);
- XtSetArg (args[2], XtNresizable, True);
- XtSetArg (args[3], XtNfromVert, textwidget);
- XtSetArg (args[4], XtNcallback, ackbacks);
- XtSetArg (args[5], XtNlabel, "\0");
-
- button1 = XtCreateManagedWidget("ok/yes button",
- commandWidgetClass,
- formwidget,
- args,
- 6);
-
- ok.width = okform_width;
- ok.height = okform_height;
-
- ok.id = LoadSymbol (button1,
- okform_bits,
- oksym_name,
- &ok.width,
- &ok.height,
- &ok.foreground,
- &ok.background);
-
- tick.width = tickform_width;
- tick.height = tickform_height;
-
- tick.id = LoadSymbol (button1,
- tickform_bits,
- ticksym_name,
- &tick.width,
- &tick.height,
- &tick.foreground,
- &tick.background);
-
- XtSetArg (args[0], XtNwidth, ok.width > tick.width ?
- ok.width : tick.width);
- XtSetArg (args[1], XtNheight, ok.height > tick.height ?
- ok.height : tick.height);
-
- XtSetValues (button1, args, 2);
-
- XtAddEventHandler (button1,
- StructureNotifyMask | LeaveWindowMask | ExposureMask,
- True,
- AlertExposures,
- (caddr_t) 1);
-
- XtSetArg (args[0], XtNhorizDistance, ALBOX2X);
- XtSetArg (args[1], XtNvertDistance, 1);
- XtSetArg (args[2], XtNresizable, True);
- XtSetArg (args[3], XtNfromVert, textwidget);
- XtSetArg (args[4], XtNcallback, nackbacks);
- XtSetArg (args[5], XtNlabel, "\0");
-
- button2 = XtCreateManagedWidget("no button",
- commandWidgetClass,
- formwidget,
- args,
- 6);
-
- cross.height = crossform_height;
- cross.width = crossform_width;
-
- cross.id = LoadSymbol (button2,
- crossform_bits,
- crosssym_name,
- &cross.width,
- &cross.height,
- &cross.foreground,
- &cross.background);
-
- XtSetArg (args[0], XtNwidth, cross.width);
- XtSetArg (args[1], XtNheight, cross.height);
-
- XtSetValues (button2, args, 2);
-
- XtAddEventHandler (button2,
- StructureNotifyMask | LeaveWindowMask | ExposureMask,
- True,
- AlertExposures,
- (caddr_t) 2);
-
- XtRealizeWidget (alertwidget);
- }
- /*
- *****************
- * *
- * OKACK *
- * NACK *
- *****************
- -------------------------------------------------------------------------
- | One of the buttons has been pressed by the user. |
- -------------------------------------------------------------------------
- */
-
- /*ARGSUSED*/
- static void OkAck (widget, client_data, call_data)
- Widget widget;
- caddr_t client_data,call_data;
- {
- ackreply = CHECK;
- XtPopdown (alertwidget);
- }
-
- /*ARGSUSED*/
- static void Nack (widget, client_data, call_data)
- Widget widget;
- caddr_t client_data,call_data;
- {
- ackreply = CROSS;
- XtPopdown (alertwidget);
- }
-
- /*
- *****************
- * *
- * ALERT *
- * *
- *****************
- -------------------------------------------------------------------------
- | Popup an alert box and wait for the user to click the acknowlegde |
- | button. |
- -------------------------------------------------------------------------
- */
- void Alert (text)
- char *text;
- {
- XEvent xevent;
-
- ackreply = NOREPLY;
- DrawAlert (&warn, &ok, (symbol *) 0, text);
-
- while (ackreply == NOREPLY)
- {
- XtNextEvent (&xevent);
- XtDispatchEvent (&xevent);
- }
-
- exit (0);
- }
-
- /*
- *****************
- * *
- * YORN *
- * *
- *****************
- -------------------------------------------------------------------------
- | Popup a yorn box and wait for the user to click in the tick or cross |
- | button and return the answer to the calling program. |
- -------------------------------------------------------------------------
- */
-
- void Yorn (text)
- char *text;
- {
- XEvent xevent;
-
- ackreply = NOREPLY;
- DrawAlert (&query, &tick, &cross, text);
-
- while (ackreply == NOREPLY)
- {
- XtNextEvent (&xevent);
- XtDispatchEvent (&xevent);
- }
-
- exit (ackreply);
- }
-
- /*
- *****************
- * *
- * DRAWALERT *
- * *
- *****************
- -------------------------------------------------------------------------
- | Note what symbols to use and how many buttons to show, then actually |
- | popup the widget. |
- -------------------------------------------------------------------------
- */
- DrawAlert (tri_symbol, first_button, second_button, text)
- symbol *tri_symbol, *first_button, *second_button;
- char *text;
- {
- if (second_button)
- XtMapWidget (button2);
- else
- XtUnmapWidget (button2);
-
- triangle_symbol = tri_symbol;
- button1_symbol = first_button;
- button2_symbol = second_button;
- curtext = text;
-
- XtPopup (alertwidget, XtGrabNone);
-
- XDefineCursor (display, XtWindow (alertwidget), arrow_cursor);
-
- XFlush (display);
- }
-
- /*
- *****************
- * *
- * ALERTEXPOSURES*
- * *
- *****************
- -------------------------------------------------------------------------
- | Exposure and reconfigure event processing for widgets containing |
- | symbols. Redraws the symbols when necessary. |
- -------------------------------------------------------------------------
- */
- static void AlertExposures (widget, which1, event)
- Widget widget;
- caddr_t which1;
- XEvent *event;
- {
- XRectangle rect;
- Arg args[2];
- int width;
- int height;
- symbol *sym;
-
- if (!XtIsRealized (widget))
- return;
-
- XtSetArg (args[0], XtNwidth, &width);
- XtSetArg (args[1], XtNheight, &height);
-
- XtGetValues (widget, args, 2);
-
- switch (event->type)
- {
- case Expose: rect.x = event->xexpose.x;
- rect.y = event->xexpose.y;
- rect.width = event->xexpose.width;
- rect.height = event->xexpose.height;
- break;
-
- case GraphicsExpose:
- rect.x = event->xgraphicsexpose.x;
- rect.y = event->xgraphicsexpose.y;
- rect.width = event->xgraphicsexpose.width;
- rect.height = event->xgraphicsexpose.height;
- break;
-
- case ConfigureNotify:
- XClearWindow (display, XtWindow (widget));
-
- /* Deliberate fall through ... */
-
- case LeaveNotify:
- rect.x = 0;
- rect.y = 0;
- rect.width = width;
- rect.height = height;
- break;
- default:
- return;
- }
-
- XSetClipRectangles (display, alert_gc, 0, 0, &rect, 1, Unsorted);
-
- switch ((int) which1)
- {
- case 0: sym = triangle_symbol;
- break;
-
- case 1: sym = button1_symbol;
- break;
-
- case 2: sym = button2_symbol;
- break;
-
- default: return;
- }
-
- if (sym == (symbol *) 0)
- return;
-
- XSetForeground (display, alert_gc, sym->foreground);
- XSetBackground (display, alert_gc, sym->background);
- XSetStipple (display, alert_gc, sym->id);
- XSetTSOrigin (display,
- alert_gc,
- (width - (int) sym->width) / 2,
- (height - (int) sym->height) / 2);
-
- XFillRectangle (display,
- XtWindow (widget),
- alert_gc,
- (width - (int) sym->width) / 2,
- (height - (int) sym->height) / 2,
- sym->width,
- sym->height);
- }
-
- /*
- *****************
- * *
- * ALERTTEXT *
- * *
- *****************
- -------------------------------------------------------------------------
- | Draw the alert or yorn text in the text widget. Format (word wrap) |
- | the text to best fit the curent widget size. |
- -------------------------------------------------------------------------
- */
- static void AlertText (widget, str, event)
- Widget widget;
- caddr_t str;
- XEvent *event;
- {
- register char *text = *(char **) str;
- register pos, ppos, slen, textx, texty;
- int text_width;
-
- XRectangle rect;
- Arg args[2];
- int width, height;
-
- XtSetArg (args[0], XtNwidth, &width);
- XtSetArg (args[1], XtNheight, &height);
- XtGetValues (widget, args, 2);
-
- pos = 0; /* position of next 'space' in string */
- ppos = 0; /* previous of a 'space' in string */
- slen = strlen (text); /* length of string */
- textx = 10; /* Current x position, (indent 1st line) */
- texty = 10; /* Current y position */
-
- /* Work out clip rectangle */
-
- switch (event->type)
- {
- case Expose: rect.x = event->xexpose.x;
- rect.y = event->xexpose.y;
- rect.width = event->xexpose.width;
- rect.height = event->xexpose.height;
- break;
-
- case GraphicsExpose:
- rect.x = event->xgraphicsexpose.x;
- rect.y = event->xgraphicsexpose.y;
- rect.width = event->xgraphicsexpose.width;
- rect.height = event->xgraphicsexpose.height;
- break;
-
- case ConfigureNotify:
- XClearWindow (display, XtWindow(widget));
- rect.x = 0;
- rect.y = 0;
- rect.width = width;
- rect.height = height;
- break;
-
- default: return;
- }
-
- XSetClipRectangles (display, text_gc, 0, 0, &rect, 1, Unsorted);
-
- while (pos < slen)
- {
- /* Wrap lines at spaces if possible */
-
- while (pos < slen)
- if (*(text + pos++) == ' ')
- break;
-
- text_width = XTextWidth (sysfont, text + ppos,pos - ppos);
-
- /* If this would run over end when printed, wrap!! */
-
- if (textx + text_width >= width)
- {
- texty += sysfont->ascent + sysfont->descent;
- textx = 10;
- }
-
- /* print sub-string */
-
- /* If this would still run over end when printed, draw a char at a time */
-
- if (textx + text_width >= width)
- {
- while ((textx + XTextWidth(sysfont,text + ppos,1) <= width) &&
- ppos <= pos)
- {
- XDrawString (display,
- XtWindow (widget),
- text_gc,
- textx,
- texty + sysfont->ascent,
- text + ppos,
- 1);
-
- textx += XTextWidth (sysfont,text + ppos,1);
- ppos ++;
- }
- }
- else
- {
- XDrawString (display,
- XtWindow (widget),
- text_gc,
- textx,
- texty + sysfont->ascent,
- text + ppos,
- pos - ppos);
-
- textx += text_width;
-
- /* Update ppos */
-
- ppos = pos;
- }
- }
- }
-
- /*
- *****************
- * *
- * LOADSYMBOL *
- * *
- *****************
- -------------------------------------------------------------------------
- | Download a bitmap to the server to use as one of the symbols for the |
- | yorn or alert boxes. |
- | Returns the pixmap XID, two colours (the pixel values) to use when |
- | drawing the symbol and modifies the width and height values if a |
- | different bitmap (from a file) has been used. |
- -------------------------------------------------------------------------
- */
- static Pixmap LoadSymbol (widget, bits, name, width, height, fore, back)
- Widget widget;
- char *bits, *name;
- unsigned int *width, *height;
- Pixel *fore, *back;
- {
- Pixmap pixmap;
- unsigned int wid, hei;
-
- ReadWidgetColours (widget, fore, back);
-
- /* If a name of an alternative bitmap file has been supplied, try to
- read it. If that fails for any reason, or no name is given, download
- the default bitmap */
-
- if (name)
- if (XReadBitmapFile (display,
- root_window,
- name,
- &wid,
- &hei,
- &pixmap,
- (int *) 0,
- (int *) 0) == BitmapSuccess)
- {
- *width = wid;
- *height = hei;
-
- return pixmap;
- }
-
- return XCreateBitmapFromData (display, root_window, bits, *width, *height);
- }
-