home *** CD-ROM | disk | FTP | other *** search
- /* File: _Report.c
- * Purpose: Supplies functionality for a PopUp
- * Author: © Copyright 1993 Jason Williams
- * All rights reserved
- */
-
- #include <string.h>
-
- #include "DeskLib:WimpSWIs.h"
- #include "DeskLib:Icon.h"
- #include "DeskLib:Keycodes.h"
- #include "DeskLib:Sound.h"
- #include "DeskLib:StringCR.h"
- #include "DeskLib:Template.h"
-
- #include "Server.h"
-
-
- typedef struct
- {
- int flags;
- char oktext[12];
- char canceltext[12];
- char appname[12];
- char message[188];
- } report_data;
-
-
- typedef struct
- {
- int flags;
- window_block *window;
- } report_workspace;
-
-
- /* First of all, we define a handler_info structure for our PopUp handler
- * which describes it to the manager. This is referenced externally
- * by the server to find the procedure to call with events for any PopUp
- * of this type, etc.
- * (We also prototype the handler function so we can reference it here)
- */
-
- static int Handler_Report(int, ctrl_block *, void *, event_pollblock *);
-
- handler_info HandlerInfo_Report =
- {
- "Report", /* PopUp type/name string */
- 0x00000003, /* Flag word (MENU/STATIC) */
- Handler_Report, /* Handler procedure */
- 16 /* Instantiation workspace size */
- };
-
-
-
- static BOOL Finished(ctrl_block *ctrl, report_workspace *ws, BOOL okpressed)
- /* We have finished (are closing the window). Return state indicating if
- * the window was 'OKed' or Cancelled.
- * Note that we can kill the menu because we don't allow a Menu Leaf version
- * of the window, and we ALWAYS return a state message to the client so that
- * they don't sit waiting for us ad infinitum!
- */
- {
- /* IF we are a MENU instantiation, then we must be very careful.
- * If we just delete the window, but the menu was still 'open', the WIMP
- * crashes (and burns (and rolls (and explodes violently))).
- * However, if we always kill the menu, we get a nasty effect - if the
- * user clicked menu elsewhere to get rid of us, our menu has been closed
- * and the new menu shown BEFORE we are called, and so we kill the wrong
- * menu - nasty.
- * Luckily, we can tell if our window is still open as a menu - if the
- * window is still open! So we check this, and only close the existing menu
- * if we are a MENU PopUp and our window is still open.
- */
-
- if (ctrl != NULL) /* Have we managed to create the window at all? */
- {
- if (ws->window == NULL) /* No clone'd template data, so is a menu */
- {
- window_state state;
-
- Wimp_GetWindowState(ctrl->basewindow, &state);
- if (state.flags.data.open)
- Wimp_CreateMenu((menu_block *) -1, 0, 0);
- }
-
- Wimp_DeleteWindow(ctrl->basewindow);
- }
-
- if (ws->window != NULL) /* If static, release memory */
- Template_Free(&ws->window); /* used by cloned template */
-
- ws->flags &= 0xffffff00; /* Return User handle + flag */
- if (okpressed) ws->flags |= 0x02; else ws->flags |= 0x01;
-
- SendState(&ws->flags, sizeof(int));
-
- KillMe();
- return(TRUE);
- }
-
-
-
- /* The Handler_ function referenced in the above info struct will handle all
- * calls from the server during normal operation...
- */
-
- static BOOL Handler_Report(int reasoncode, ctrl_block *ctrl,
- void *privateworkspace, event_pollblock *event)
- {
- report_workspace *ws = privateworkspace;
-
- switch(reasoncode)
- {
- case REASON_OPEN:
- {
- window_handle windowhandle;
- window_block *window;
- report_data *info;
-
- info = (report_data *) (((int)event) + POPUP_DATA_OFFSET);
- ws->flags = info->flags;
-
- /* Find the template. NOTE that if you provide a STATIC popup, you
- * MUST support multiple instantiations, so MUST use Template_Clone()
- * Also note that if bringing up a MENU LEAF window, we must clone
- * our template data into the RMA so the WIMP does not crash! ;-(
- */
- if (ctrl->appflags & APPFLAGS_ISSTATIC)
- ws->window = window = Template_Clone("Report", 0);
- else
- {
- Wimp_CreateMenu((menu_block *) -1, 0, 0); /* Kill previous menu */
- ws->window = NULL;
- if((ctrl->appflags & APPFLAGS_ISLEAF) == 0)
- window = Template_Find("Report");
- else
- {
- Finished(NULL, ws, FALSE);
- return(FALSE);
- }
- }
-
- if (window == NULL)
- {
- Finished(NULL, ws, FALSE);
- return(FALSE);
- }
-
- /* Create the window, and fill in its icons with the data given
- * to us in the pollblock. (DATA_BASE is defined above)
- */
- strcpy(window->title.indirecttext.buffer, "Message");
- if (info->appname[0] > 31)
- {
- strcatcr(window->title.indirecttext.buffer, " from ");
- strcatcr(window->title.indirecttext.buffer, info->appname);
- }
-
- Wimp_CreateWindow(window, &windowhandle);
- info->message[187] = 0;
-
- if (info->flags & 0x02)
- SetIconText(windowhandle, 0, info->oktext);
- if (info->flags & 0x01)
- SetIconText(windowhandle, 2, info->canceltext);
-
- SetIconText(windowhandle, 1, info->message);
-
- if ((info->flags & 3) != 3) /* Only want 1 button */
- {
- int icon, dead, halfwidth, wmiddle;
- icon_createblock icreate;
-
- if (info->flags & 0x02)
- { icon = 0; dead = 2; }
- else
- { icon = 2; dead = 0; }
-
- icreate.window = windowhandle; /* Move the icon we want */
- Wimp_GetIconState(windowhandle, icon, &icreate.icondata);
- Wimp_DeleteIcon(windowhandle, icon);
-
- wmiddle = (window->workarearect.max.x - /* Center it in window */
- window->workarearect.min.x) / 2;
- halfwidth = (icreate.icondata.workarearect.max.x -
- icreate.icondata.workarearect.min.x) / 2;
-
- icreate.icondata.workarearect.min.x = wmiddle - halfwidth;
- icreate.icondata.workarearect.max.x = wmiddle + halfwidth;
- Wimp_CreateIcon(&icreate, &icon);
-
- Wimp_DeleteIcon(windowhandle, dead); /* And delete the other icon */
- }
-
- if (ctrl->appflags & APPFLAGS_ISSTATIC)
- ShowStaticPopUp(windowhandle, ctrl->openx, ctrl->openy);
-
- Sound_SysBeep();
-
- ctrl->pollmask.value = ~( (1 << event_CLOSE) |
- (1 << event_CLICK) |
- (1 << event_KEY) |
- (1 << event_NULL) );
- ctrl->basewindow = windowhandle; /* Let server know windowhandle */
- }
- return(TRUE);
-
-
- case REASON_CLOSE: /* Quietly close our window */
- return(Finished(ctrl, ws, FALSE));
-
-
- case REASON_EVENT: /* Handle a WIMP Event */
- switch(event->type)
- {
- case event_NULL:
- /* We need to check frequently if our window has been closed, as
- * under RISC OS 2.00 the Wimp doesn't tell us if it has done so!
- */
- {
- window_state wstate;
-
- Wimp_GetWindowState(ctrl->basewindow, &wstate);
- if (!wstate.flags.data.open) /* Window has indeed been closed */
- return(Finished(ctrl, ws, FALSE));
- }
- break;
-
- case event_CLOSE:
- if (event->data.openblock.window == ctrl->basewindow)
- return(Finished(ctrl, ws, FALSE));
- break;
-
- case event_CLICK:
- if (event->data.mouse.window == ctrl->basewindow)
- {
- switch(event->data.mouse.icon)
- {
- case 0: /* OK */
- return(Finished(ctrl, ws, TRUE));
-
- case 2: /* Cancel */
- return(Finished(ctrl, ws, FALSE));
- }
- return(TRUE);
- }
- break;
-
- case event_KEY:
- if (event->data.key.caret.window == ctrl->basewindow)
- {
- switch(event->data.key.code)
- {
- case keycode_RETURN:
- return(Finished(ctrl, ws, TRUE));
-
- case keycode_ESCAPE: /* Needed for the static case */
- return(Finished(ctrl, ws, FALSE));
- }
- return(TRUE);
- }
- break;
- }
- break;
- }
-
- return(FALSE); /* If we didn't handle this call, we MUST return 0 */
- }
-
-