/* Written by Dan Heller and Paula Ferguson. * Copyright 1994, O'Reilly & Associates, Inc. * Permission to use, copy, and modify this program without * restriction is hereby granted, as long as this copyright * notice appears in each copy of the program source code. * This program is freely distributable without licensing fees and * is provided without guarantee or warrantee expressed or implied. * This program is -not- in the public domain. */ /* warn_msg.c -- display a very urgent warning message. * Really catch the user's attention by flashing an urgent- * looking pixmap every 250 milliseconds. * The program demonstrates how to set the XmNsymbolPixmap * resource, how to destroy the pixmap and how to use timers. */ #include <Xm/MessageB.h> #include <Xm/PushB.h> #include "bang0.symbol" #include "bang1.symbol" #define TEXT "Alert!\n\ The computer room is ON FIRE!\n\ All of your e-mail will be lost." /* define the data structure we need to implement flashing effect */ typedef struct { XtIntervalId id; int which; Pixmap pix1, pix2; Widget dialog; XtAppContext app; } TimeOutClientData; main(argc, argv) int argc; char *argv[]; { XtAppContext app; Widget toplevel, button; XmString label; void warning(); XtSetLanguageProc (NULL, NULL, NULL); toplevel = XtVaAppInitialize (&app, "Demos", NULL, 0, &argc, argv, NULL, NULL); label = XmStringCreateLocalized ( "Don't Even Think About Pressing This Button"); button = XtVaCreateManagedWidget ("button", xmPushButtonWidgetClass, toplevel, XmNlabelString, label, NULL); XmStringFree (label); /* set up callback to popup warning */ XtAddCallback (button, XmNactivateCallback, warning, NULL); XtRealizeWidget (toplevel); XtAppMainLoop (app); } /* warning() -- callback routine for the button. Create a message * dialog and set the message string. Allocate an instance of * the TimeOutClientData structure and set a timer to alternate * between the two pixmaps. The data is passed to the timeout * routine and the callback for when the user presses "OK". */ void warning(parent, client_data, call_data) Widget parent; XtPointer client_data; XtPointer call_data; { Widget dialog; XtAppContext app = XtWidgetToApplicationContext (parent); XmString text; extern void done(), destroy_it(), blink(); Display *dpy = XtDisplay (parent); Screen *screen = XtScreen (parent); Pixel fg, bg; Arg args[5]; int n, depth; TimeOutClientData *data = XtNew (TimeOutClientData); /* Create the dialog */ n = 0; XtSetArg (args[n], XmNdeleteResponse, XmDESTROY); n++; dialog = XmCreateMessageDialog (parent, "danger", args, n); XtUnmanageChild (XmMessageBoxGetChild (dialog, XmDIALOG_CANCEL_BUTTON)); XtUnmanageChild (XmMessageBoxGetChild (dialog, XmDIALOG_HELP_BUTTON)); XtAddCallback (dialog, XmNokCallback, done, NULL); XtAddCallback (dialog, XmNdestroyCallback, destroy_it, data); /* now that dialog has been created, it's colors are initialized */ XtVaGetValues (dialog, XmNforeground, &fg, XmNbackground, &bg, XmNdepth, &depth, NULL); /* Create pixmaps that are going to be used as symbolPixmaps. * Use the foreground and background colors of the dialog. */ data->pix1 = XCreatePixmapFromBitmapData (dpy, XtWindow (parent), bang0_bits, bang0_width, bang0_height, fg, bg, depth); data->pix2 = XCreatePixmapFromBitmapData (dpy, XtWindow (parent), bang1_bits, bang1_width, bang1_height, fg, bg, depth); /* complete the timeout client data */ data->dialog = dialog; data->app = app; /* Add the timeout for blinking effect */ data->id = XtAppAddTimeOut (app, 1000L, blink, data); /* display the help text and the appropriate pixmap */ text = XmStringCreateLtoR (TEXT, XmFONTLIST_DEFAULT_TAG); XtVaSetValues (dialog, XmNmessageString, text, XmNsymbolPixmap, data->pix2, NULL); XmStringFree (text); XtManageChild (dialog); XtPopup (XtParent (dialog), XtGrabNone); } /* blink() -- visual blinking effect for dialog's symbol. Displays * flashing ! symbol, restarts timer and saves timer id. */ void blink(client_data, id) XtPointer client_data; XtIntervalId *id; { TimeOutClientData *data = (TimeOutClientData *) client_data; data->id = XtAppAddTimeOut (data->app, 250L, blink, data); data->which = !data->which; XtVaSetValues (data->dialog, XmNsymbolPixmap, data->which? data->pix1 : data->pix2, NULL); /*XtVaSetValues (data->dialog, XmNsymbolPixmap, (data->which = !data->which) ? data->pix1 : data->pix2, NULL);*/ } /* done() -- called when user presses "OK" in dialog or * if the user picked the Close button in system menu. * Remove the timeout id stored in data, free pixmaps and * make sure the widget is destroyed (which is only when * the user presses the "OK" button. */ void done(dialog, client_data, call_data) Widget dialog; XtPointer client_data; XtPointer call_data; { XtDestroyWidget(dialog); } /* destroy_it() -- called when dialog is destroyed. Removes * timer and frees allocated data. */ void destroy_it(dialog, client_data, call_data) Widget dialog; XtPointer client_data; XtPointer call_data; { TimeOutClientData *data = (TimeOutClientData *) client_data; Pixmap symbol; XtRemoveTimeOut (data->id); XFreePixmap (XtDisplay (data->dialog), data->pix1); XFreePixmap (XtDisplay (data->dialog), data->pix2); XtFree (data); }