/* * @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: BeginSession.c /main/7 1995/07/14 11:31:26 drk $" #endif #endif /*********************************************************************** @(#)BeginSession.c 1.8 Date:03/04/91 Author: TAT History: 05/24/90 SJS add to sccs 08/30/90 SJS cosmetic changes, exit on error 10/03/90 SJS make keycode initialization changes Calls: Summary: Initializes the input synthesis libraries local copies of display and application context pointers. It also sets up local-globals for the screen and the root_window, and establishes pointers to functions which need to be defined external to this library. This remote function referencing is necessary since this library has been designed to know nothing internally about the widget set which it interacts with. One further addition is to do all the key code lookup *1* time. This is a change from looking the key codes up every time a keyclick needs to be done. INPUTS: display_in - the display that is connected to app_context_in - the Xt application context num_objects - number of unique objects defined generate_objects_func -a function which updates the object hierarchy get_object_type_name_func - a function which returns the object type name get_widget_class_name_func - a function which returns widget class name trace_msg_func - a function which prints out a trace message warning_msg_func - a function which prints out a warning message error_msg_func - a function which prints out an error message OUTPUTS: none RETURNS: nothing ************************************************************************/ #define DECLARE_XISLIB_GLOBALS_HERE #include #include "xislib.h" #include /* for XmKeyBinding */ #define XK_MISCELLANY #include void AutoGetAdditionalModifier(); void xisBeginSession(display_in,app_context_in,num_object_types, generate_objects_func, get_object_type_name_func, get_widget_class_name_func, window_to_widget_func, trace_msg_func, warning_msg_func, error_msg_func) Display *display_in; XtAppContext app_context_in; int num_object_types; void (*generate_objects_func) ( /* XisObjectRecord *root_obj, Root object */ ); char *(*get_object_type_name_func) ( /* int object_type Object type code (user defined) */ ); char *(*get_widget_class_name_func) ( /* Widget widget Widget to find lowest class name*/ ); Widget (*window_to_widget_func) ( /* Window window Window to find widget for */ ); void (*trace_msg_func)(); /* These three funcs have params like printf */ void (*warning_msg_func)(); void (*error_msg_func)(); { static char routine_name[] = "xisBeginSession():"; int i; char msg_string[125]; /* Validate incoming parameters */ xisTraceMsg = trace_msg_func; xisWarningMsg = warning_msg_func; xisErrorMsg = error_msg_func; if (error_msg_func == 0) { fprintf(stderr, "%s called with NULL error_msg_func\n", routine_name); exit(-1); } if (display_in == 0) { sprintf (msg_string, _AutoMessages[WARNMSG115], routine_name); AutoError(msg_string); } if (app_context_in == 0) { sprintf (msg_string, _AutoMessages[WARNMSG104], routine_name); AutoError(msg_string); } if (generate_objects_func == 0) { sprintf (msg_string, _AutoMessages[WARNMSG108], routine_name); AutoError(msg_string); } if (get_object_type_name_func == 0) { sprintf (msg_string, _AutoMessages[WARNMSG106], routine_name); AutoError(msg_string); } if (get_widget_class_name_func == 0) { sprintf (msg_string, _AutoMessages[WARNMSG110], routine_name); AutoError(msg_string); } if (window_to_widget_func == 0) { sprintf (msg_string, _AutoMessages[WARNMSG111], routine_name); AutoError(msg_string); } if (trace_msg_func == 0) { sprintf (msg_string, _AutoMessages[WARNMSG112], routine_name); AutoError(msg_string); } if (warning_msg_func == 0) { sprintf (msg_string, _AutoMessages[WARNMSG113], routine_name); AutoError(msg_string); } xisAppContext = app_context_in; xisDisplay = display_in; xisScreen = XDefaultScreen(xisDisplay); xisRootWindow = XDefaultRootWindow(xisDisplay); xisNumObjectTypes = num_object_types; xisGenerateObjects = generate_objects_func; xisGetObjectTypeName = get_object_type_name_func; xisGetWidgetClassName = get_widget_class_name_func; xisWindowToWidget = window_to_widget_func; /* Initialize the Root Object */ xisObjects[0].in_use = 1; xisObjects[0].id.window = xisRootWindow; xisObjects[0].id.widget = NULL; xisObjects[0].id.object_type = 0; /* corresponds to oUserDefined */ xisObjects[0].id.instance = 0; xisObjects[0].x = 0; xisObjects[0].y = 0; xisObjects[0].width = DisplayWidth(xisDisplay,xisScreen); xisObjects[0].height = DisplayHeight(xisDisplay,xisScreen); xisObjects[0].parent = NULL; xisObjects[0].first_child = NULL; xisObjects[0].next_sibling = NULL; xisObjects[0].proc_InformExpectedActions = NULL; xisMaxObjectNum++; /* "Alloc" the object */ } /* end xisBeginSession */ static void CvtVirtualToActualKeysym( dpy, virtKeysym, actualKeysymRtn, modifiersRtn ) Display *dpy ; KeySym virtKeysym ; KeySym *actualKeysymRtn ; Modifiers *modifiersRtn ; { int num_keys; XmKeyBinding keys; /* Initialize the return parameters. */ *actualKeysymRtn = NoSymbol; *modifiersRtn = 0; /* Arbitrarily return the first keysym in the list. */ num_keys = XmeVirtualToActualKeysyms(dpy, virtKeysym, &keys); if (num_keys > 0) { *actualKeysymRtn = keys[0].keysym; *modifiersRtn = keys[0].modifiers; } XtFree((char*) keys); } void xisInitKeyCodes(sh_widget) Widget sh_widget ; { KeySym tmp_key, tmp_key2 ; int i,j ; int x,y ; Boolean collision ; Modifiers new_modifier; char msg_string[125]; /* Initialize all keycodes declared */ for(i=0; i< _MaxKey; i++) { tmp_key = XStringToKeysym(xisKeySymName[i].key_name) ; /* if it is an osf key then translate it again */ if ( strncmp(xisKeySymName[i].key_name,"osf",3) == 0 ) CvtVirtualToActualKeysym(xisDisplay,tmp_key,&tmp_key2, &xisKeySymName[i].modifier) ; else /* just copy it over */ tmp_key2 = tmp_key ; xisKeySymName[i].code = XKeysymToKeycode(xisDisplay,tmp_key2) ; /* * The following two lines added for automation. */ AutoGetAdditionalModifier(xisDisplay, tmp_key2, &new_modifier); xisKeySymName[i].modifier |= new_modifier; (*xisTraceMsg)(" keycode number %2d: %s -> %d -> %d/%d --> %d \n", i,xisKeySymName[i].key_name,tmp_key,tmp_key2, xisKeySymName[i].modifier,xisKeySymName[i].code) ; /* a key is undefined */ if (( i != 0 ) && ( i != (_MaxKey-1) )) { if (( tmp_key == NoSymbol ) || ( tmp_key2 == NoSymbol )) { sprintf (msg_string,_AutoMessages[WARNMSG114], xisKeySymName[i].key_name) ; AutoMessage (msg_string); } } } /* look for duplicate key bindings */ collision = False ; for(i=1;i<(_MaxKey-1);i++) { for(j=i;j<(_MaxKey-1);j++) { if ( i != j ) { x = (int)xisKeySymName[i].code ; y = (int)xisKeySymName[j].code ; if ( x == y ) { collision = True ; } } } } } /* end xisInitKeyCodes */ /* * The following routine has been added to get the group modifier when * needed. If the key modmap is arranged in more than two columns * (i.e. when the no. of keysyms_per_keycode is greater than two), to * send the key event corresponding to any keysym in the third or * fourth column of the modmap, it is necessary to add the group modifier * to the current modifier switch in order for the server to interpret * the event correctly. This group modifier is available through the * variable 'mode_switch' in the display, which gets initialized when * the internal modmap for X is getting initialized. (InitModMap() in * XKeyBind.c). */ void AutoGetAdditionalModifier(dpy, ks, new_mod) Display *dpy; KeySym ks; Modifiers *new_mod; { register int i, j, n; Boolean done = False; KeySym ksym, *ks_list; XModifierKeymap *mod_keymap; int min_keycode_rtn, max_keycode_rtn ; int keysyms_per_keycode_rtn ; int keycode_count ; unsigned int mode_switch; *new_mod = 0; /* * Fix for CR 5663 -- Use function interface to retrieve * publicly accessible Display info. */ XDisplayKeycodes( dpy, &min_keycode_rtn, &max_keycode_rtn ) ; keycode_count = max_keycode_rtn - min_keycode_rtn + 1 ; if (!( ks_list = XGetKeyboardMapping( dpy, min_keycode_rtn, keycode_count, &keysyms_per_keycode_rtn ) ) ) return; /* * Fix for CR 5663 -- Since X11R5 made the display mode_switch * variable opaque, we will have to regenerate it here, using * the same algorithm as in XKeyBind.c. */ mod_keymap = XGetModifierMapping( dpy ); /* Find any Mod modifier acting as the Group modifier */ mode_switch = 0; n = 8 * mod_keymap->max_keypermod; for (i = 3*mod_keymap->max_keypermod; i < n; i++) { for (j = 0; j < keysyms_per_keycode_rtn; j++) { ksym = XKeycodeToKeysym(dpy, mod_keymap->modifiermap[i], j); if (ksym == XK_Mode_switch) mode_switch |= 1 << (i / mod_keymap->max_keypermod); } } for (i = min_keycode_rtn; i <= max_keycode_rtn && !done; i++) { for (j = 0; j < keysyms_per_keycode_rtn; j++) { if (XKeycodeToKeysym(dpy, (KeyCode) i, j) == ks) { if (j > 1) *new_mod = mode_switch; done = True; break; } } } XFree( ks_list ) ; XFreeModifiermap ( mod_keymap ); return; }