Start a modal loop
void *PtModalBlock( PtModalCtrl_t *ctrl, unsigned flags );
ph
PtModalBlock() implements a modal loop.
We recommend using PtModalBlock() as a replacement for the PtModalStart() / PtProcessEvent() / PtModalEnd() loop. This function makes it easier for you to write modal code that's compatible with multithreaded applications. |
The PtModalCtrl_t structure is a replacement for the “done” flag typically used by the modal loop. PtModalUnblock() is a replacement for setting that flag.
PtModalBlock() doesn't return until PtModalUnblock() is called with the same value of its ctrl argument. The structure pointed to by ctrl doesn't need to be initialized in any special way.
While PtModalBlock() is running, Photon events are processed by either the same thread, other threads, or both. PtModalUnblock() causes the corresponding PtModalBlock() call to return the value passed to the result argument.
The flags argument can be one of:
If you pass 0 for flags, PtModalBlock() tries to guess the best possible behavior:
Either way, the previous status of the thread as a reader or nonreader is restored before PtModalBlock() returns, even if the status was changed by a callback invoked from within PtModalBlock() rather than by PtModalBlock() itself.
If another thread calls PtExit() while this function is blocked, the function does not return, even if a third thread calls PtModalUnblock().
NULL on error, or the value passed as the second argument to PtModalUnblock() (don't use NULL or you won't be able to recognize a failure).
/* callbacks.c */ /* */ /* This application demonstrates how to optain set */ /* up a modal dialog in an application in order to */ /* obtain information from the user before continuing. */ /* */ /* This file contains: */ /* */ /* modal_btn_done_activateCB */ /* Callback type: Pt_CB_ACTIVATE */ /* Widget: modal_btn_done */ /* */ /* This function displays how to obtain and pass back */ /* some data input by the user, and then unblock from */ /* a modal situation */ /* */ /*-------------------------------------------------------*/ /* */ /* nonmodal_btn_launchmodaldlg_activateCB */ /* */ /* Callback type: Pt_CB_ACTIVATE */ /* Widget: modal_btn_done */ /* */ /* This function launchs our modal dialog, blocks */ /* other windows in the application, changes their */ /* cursors (and overrides those of their children) to */ /* be the noninput cursor, and then calls */ /* PtModalBlock() to wait for the user to return from */ /* the dialog (via modal_btn_done_activateCB()). */ /* */ /* Information obtained from the user in the modal */ /* dialog is used, and then the other windows are */ /* restored to normal. */ /* */ /*-------------------------------------------------------*/ /* */ /* AppBuilder Photon Code Lib */ /* Version 2.01A */ /* Standard headers */ #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string.h> /* Toolkit headers */ #include <Ph.h> #include <Pt.h> #include <Ap.h> /* Local headers */ #include "globals.h" #include "abimport.h" #include "proto.h" /* * global variables */ PtModalCtrl_t modalctrl; int *choice; /*************************************************************** * * modal_btn_done_activateCB * ***************************************************************/ int modal_btn_done_activateCB( PtWidget_t *widget, ApInfo_t *apinfo, PtCallbackInfo_t *cbinfo ) { PtArg_t arg[1]; int *users_choice; PtSetArg( &arg[0], Pt_ARG_NUMERIC_VALUE, &users_choice, 0 ); PtGetResources( ABW_modal_nint_choice, 1, arg ); choice = users_choice; PtModalUnblock( &modalctrl, NULL ); /* eliminate 'unreferenced' warnings */ widget = widget, apinfo = apinfo, cbinfo = cbinfo; return( Pt_CONTINUE ); } /*************************************************************** * * nonmodal_btn_launchmodaldlg_activateCB * ***************************************************************/ int nonmodal_btn_launchmodaldlg_activateCB( PtWidget_t *widget, ApInfo_t *apinfo, PtCallbackInfo_t *cbinfo ) { char choice_as_string[3]; /* we're expecting only 2-digit #'s between 0 and 42 */ unsigned short *ptr2oldcursor, base_oldcursor, nonmodal_oldcursor; int cursor_override_state, base_oldcursoroverride, nonmodal_oldcursoroverride; PtArg_t args[3]; /* * Create and realize a dialog to get a user respons; in * it we'll ask the user to choose a value with a * PtNumericInteger. (We created the dialog in PhAB, along * with an internal link to it. Note that the internal * link needs a pointer to a widget in order to place * the dialog) */ ApCreateModule( ABM_modal, widget, NULL ); /* * save away cursor data from other windows */ PtSetArg( &args[0], Pt_ARG_CURSOR_TYPE, &ptr2oldcursor, 0 ); PtSetArg( &args[1], Pt_ARG_CURSOR_OVERRIDE, &cursor_override_state, 0 ); PtGetResources( ABW_base, 2, args ); base_oldcursor = *ptr2oldcursor; base_oldcursoroverride = cursor_override_state; PtGetResources( ABW_nonmodal, 2, args ); nonmodal_oldcursor = *ptr2oldcursor; nonmodal_oldcursoroverride = cursor_override_state; /* * block user interaction to windows - note that instead of * blocking each window individually, we'd normally use * PtBlockAllWindows(); we'll also alter the windows' * cursors to reflect their blocked state */ PtSetArg( &args[0], Pt_ARG_FLAGS, Pt_BLOCKED, Pt_BLOCKED ); PtSetArg( &args[1], Pt_ARG_CURSOR_TYPE, Ph_CURSOR_NOINPUT, 0 ); PtSetArg( &args[2], Pt_ARG_CURSOR_OVERRIDE, Pt_TRUE, 0 ); PtSetResources( ABW_base, 3, args ); PtSetResources( ABW_nonmodal, 3, args ); /* * block; this will return when PtModalUnblock() is called */ PtModalBlock( &modalctrl, 0 ); /* * the global variable "choice" has now been filled in; * we'll display that value now */ itoa( *choice, choice_as_string, 10 ); PtSetArg( &args[0], Pt_ARG_TEXT_STRING, choice_as_string, 0 ); PtSetResources( ABW_nonmodal_lbl_choice, 1, args ); /* * unblock user interaction to windows and restore cursors to * original states */ PtSetArg( &args[0], Pt_ARG_FLAGS, 0, Pt_BLOCKED ); PtSetArg( &args[1], Pt_ARG_CURSOR_TYPE, base_oldcursor, 0 ); if( base_oldcursoroverride ) PtSetArg (&args[2], Pt_ARG_CURSOR_OVERRIDE, Pt_TRUE, 0); else PtSetArg (&args[2], Pt_ARG_CURSOR_OVERRIDE, Pt_FALSE, 0); PtSetResources( ABW_base, 3, args ); PtSetArg( &args[1], Pt_ARG_CURSOR_TYPE, nonmodal_oldcursor, 0 ); if( nonmodal_oldcursoroverride ) PtSetArg (&args[2], Pt_ARG_CURSOR_OVERRIDE, Pt_TRUE, 0); else PtSetArg (&args[2], Pt_ARG_CURSOR_OVERRIDE, Pt_FALSE, 0); PtSetResources( ABW_nonmodal, 3, args ); /* eliminate 'unreferenced' warnings */ widget = widget, apinfo = apinfo, cbinfo = cbinfo; return( Pt_CONTINUE ); }
Photon
Safety: | |
---|---|
Interrupt handler | No |
Signal handler | No |
Thread | No |
PtModalEnd(), PtModalStart(), PtModalUnblock(), PtProcessEvent()
“Threads” in the Parallel Operations chapter, and “Modal dialogs” in the Window Management chapter of the Photon Programmer's Guide