/* * @OPENGROUP_COPYRIGHT@ * COPYRIGHT NOTICE * Copyright (c) 1990, 1991, 1992, 1993 Open Software Foundation, Inc. * Copyright (c) 1996, 1997, 1998, 1999, 2000 The Open Group * ALL RIGHTS RESERVED (MOTIF). See the file named COPYRIGHT.MOTIF for * the full copyright text. * * This software is subject to an open license. It may only be * used on, with or for operating systems which are themselves open * source systems. You must contact The Open Group for a license * allowing distribution and sublicensing of this software on, with, * or for operating systems which are not Open Source programs. * * See http://www.opengroup.org/openmotif/license for full * details of the license agreement. Any use, reproduction, or * distribution of the program constitutes recipient's acceptance of * this agreement. * * EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS * PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY * WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY * OR FITNESS FOR A PARTICULAR PURPOSE * * EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT * NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE * EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. */ /* * HISTORY */ #ifdef REV_INFO #ifndef lint static char rcsid[] = "$XConsortium: ProcesEvents.c /main/7 1995/07/14 11:30:48 drk $" #endif #endif /*********************************************************************** @(#)ProcesEvents.c 1.10.1.1 Date:1/22/91 Author: TAT History: 05/29/90 SJS add to sccs 06/21/90 SJS do not set focus to unmapped widgets 07/11/90 SJS test return of XmProcessTraversal() for what its worth 08/22/90 SJS set our internal concept of focus to the "real" widget when keyboard focus mode is NATURAL 10/10/90 SJS do SetExpected for Focus In/Out. Try to follow Motif focus. Calls: Summary: Processes all events generated by Xm, Xt, and X-server until the next quiescent condition. Then it returns control back to the calling routine. INPUTS: done_func - external function which determines if the processing is done yet based on external environment conditions which are known to it (i.e., callbacks, etc.). max_wait_time - Maximum number of milliseconds to wait overall before giving up on sync_func. OUTPUTS: none RETURNS: void ************************************************************************/ #include "xislib.h" #include /* Warning: Potentially non-portable */ #include static XtIntervalId interval_timer_id=0; static void timer_expire_callback(client_data,timer_id) XtPointer client_data; XtIntervalId *timer_id; { if (*timer_id != interval_timer_id) { AutoMessage(_AutoMessages[WARNMSG77]); } interval_timer_id = 0; } void xisProcessEvents(done_func,max_wait_time) int (*done_func)(); int max_wait_time; { static char routine_name[] = "xisProcessEvents"; int done=0; int called_dispatch = 0; Window focus_window; int revert_to; XisObjectRecord *new_object; xisUseSessionInfo(routine_name); called_dispatch = xisSynchronize(); if (done_func != NULL) { if ((*done_func)() == 0) { interval_timer_id = 0; interval_timer_id = XtAppAddTimeOut(xisAppContext,max_wait_time, timer_expire_callback, (XtPointer) 0); while (!done) { if ((XtAppPending(xisAppContext)&XtIMTimer) > 0) XtAppProcessEvent(xisAppContext,XtIMTimer); if (interval_timer_id == 0) { done = 1; } else { called_dispatch = xisSynchronize(); done = (*done_func)(); } } if (interval_timer_id != 0) XtRemoveTimeOut(interval_timer_id); } /* End if ((*done_func)() == 0) */ } /* End if (done_func != NULL) */ if (called_dispatch) { xisProcessObjects(); } /* Make sure that the correct window has the keyboard focus */ XGetInputFocus(xisDisplay,&focus_window,&revert_to); if (xisKeyboardFocusMode == KEYBOARD_FOCUS_CONTROLLED && focus_window != xisState.focus_window) { (*xisTraceMsg)("WARNING..Window manager changed focus window; changing back\n"); if (!xisState.focus_window || xisState.focus_window == xisRootWindow || !xisWindowExists(xisState.focus_window) || !xisIsMapped(xisState.focus_window) ) { if (!xisDummyFocusWindow) { xisCreateSimple(); called_dispatch = xisSynchronize(); } xisState.focus_window = xisDummyFocusWindow; xisState.focus_widget = NULL; xisState.focus_revert_to = RevertToNone; } else { /* In this case, the window manager moved focus out. We need to do an Xis event for this FocusOut and for the FocusIn we are about to cause */ new_object = xisGetObjectFromWidget(xisState.focus_widget); if (new_object->proc_InformExpectedActions != NULL) { xisInform.current_obj = new_object; xisInform.is_valid = 1; xisInform.action_obj = new_object; xisInform.modifier_key_status = 0; xisInform.button_num = 0; xisInform.key_code = 0; xisInform.edge_code = 0; xisInform.num_clicks = 0; xisInform.event_code = EventFocusOut; (*new_object->proc_InformExpectedActions)(EventFocusOut); xisInform.event_code = EventFocusIn; (*new_object->proc_InformExpectedActions)(EventFocusIn); } } if (xisState.focus_widget == NULL) { XSetInputFocus(xisDisplay,xisState.focus_window, RevertToNone,CurrentTime); } else { XSetInputFocus(xisDisplay, XtWindow(xisGetShellWidget(xisState.focus_widget)), RevertToNone,CurrentTime); if(!XmProcessTraversal(xisState.focus_widget,XmTRAVERSE_CURRENT)) { XisObjectRecord *new_focus; /* Lord knows where it ends up */ XGetInputFocus(xisDisplay,&xisState.focus_window, &xisState.focus_revert_to); new_focus = xisFindObjectFromWindow(xisState.focus_window); xisState.focus_widget = new_focus->id.widget; xisState.focus_object_type = new_focus->id.object_type; xisState.focus_instance = new_focus->id.instance; } else { XGetInputFocus(xisDisplay,&xisState.focus_window, &xisState.focus_revert_to); } } } /* End if(KEYBOARD_FOCUS_CONTROLLED) */ else { /* KEYBOARD_FOCUS_NATURAL */ /* Do our best to find out where it went. THIS IS THE CODE THAT SHOULD BE CHANGED IF MOTIF EVER GIVES US A REAL FOCUS QUERY FUNCTION */ Widget new_widget; XisObjectRecord *tmp_object; XisObjectRecord *tmp2_object; new_widget = xisGetFocusWidget(); if(new_widget != NULL) { if(new_widget != xisState.focus_widget) {/* New widget with focus */ new_object = xisGetObjectFromWidget(new_widget); tmp_object = new_object; if(focus_window != xisState.focus_window) { /* Focus move in hierarchy, too */ while(tmp_object != NULL) { if (tmp_object->proc_InformExpectedActions != NULL) { xisInform.current_obj = tmp_object; xisInform.is_valid = 1; xisInform.action_obj = new_object; xisInform.modifier_key_status = 0; xisInform.button_num = 0; xisInform.key_code = 0; xisInform.edge_code = 0; xisInform.num_clicks = 0; xisInform.event_code = EventFocusIn; (*tmp_object->proc_InformExpectedActions)(EventFocusIn); } tmp_object = tmp_object->parent; } tmp_object = xisGetObjectFromWidget(xisState.focus_widget); tmp2_object = tmp_object; while(tmp2_object != NULL ) { if (tmp2_object->proc_InformExpectedActions != NULL) { xisInform.current_obj = tmp2_object; xisInform.is_valid = 1; xisInform.action_obj = tmp_object; xisInform.modifier_key_status = 0; xisInform.button_num = 0; xisInform.key_code = 0; xisInform.edge_code = 0; xisInform.num_clicks = 0; xisInform.event_code = EventFocusOut; (*tmp2_object->proc_InformExpectedActions) (EventFocusOut); } tmp2_object = tmp2_object->parent; } } if((new_object != NULL)&&(focus_window != xisDummyFocusWindow)){ xisState.focus_window = focus_window; xisState.focus_widget = new_widget; xisState.focus_object_type = new_object->id.object_type; xisState.focus_instance = new_object->id.instance; } } } /* End if(new_widget != xisState.focus_widget) */ } /* End else KEYBOARD_FOCUS_NATURAL */ } /* End xisProcessEvents() */