File: svr_x.c

package info (click to toggle)
xview 3.2p1.4-28.1
  • links: PTS
  • area: main
  • in suites: jessie, jessie-kfreebsd, wheezy
  • size: 26,680 kB
  • ctags: 34,403
  • sloc: ansic: 241,397; yacc: 1,435; sh: 1,086; makefile: 148; lex: 76; perl: 54; asm: 50; cpp: 15
file content (302 lines) | stat: -rw-r--r-- 8,677 bytes parent folder | download | duplicates (7)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
#ifndef lint
#ifdef sccs
static char     sccsid[] = "@(#)svr_x.c 20.57 93/06/28";
#endif
#endif

/*
 *	(c) Copyright 1989 Sun Microsystems, Inc. Sun design patents 
 *	pending in the U.S. and foreign countries. See LEGAL_NOTICE 
 *	file for terms of the license.
 */

#include <stdio.h>
#include <xview/pkg.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/time.h>
#ifdef _XV_DEBUG
#include <xview_private/xv_debug.h>
#endif /* _XV_DEBUG */
#include <xview_private/i18n_impl.h>
#include <xview/win_event.h>
#include <X11/Xlib.h>
#include <xview/defaults.h>
#include <xview/sel_svc.h>
#include <xview/server.h>
#include <xview_private/svr_impl.h>
#include <X11/keysym.h>

extern Display *XOpenDisplay();
#ifndef __linux__
Xv_private_data Defaults_pairs xv_kbd_cmds_value_pairs[4];
#else
/* Global already defined and initialized in in server/server.c */
extern Defaults_pairs xv_kbd_cmds_value_pairs[4];
#endif

/*
 * The following table describes the default key mappings for special 
 * XView keys. The first default key mapping is attempted. If this 
 * fails, then the machine we're on probably doesn't
 * have sufficient function keys, so we try the second mapping, and
 * so on. Right now, the rest of XView only supports the default mapping
 * so we set NUM_KEYSYM_SETS to 1 and only supply one set of keys to use.
 * In the future, this will go away and we'll provide a more elegant
 * and flexible way for the user to map function keys to XView functions.
 */

#define NUM_KEYSYM_SETS	1

	/* XXX: XK_F13 is left here to be compatible with V2.  V2 XView
		clients use XK_F13 in the modmap as a trigger that
		tells them the function keys have already been installed.
		In V3, we had changed it such that only F18 and F20 were
		installed.  See Bug 1060242 for more details.
	 */
static KeySym	default_fkey_keysyms[NUM_KEYSYM_SETS][SELN_FN_NUM] = {
		{			/* default keysyms */
			XK_F13,
			XK_F18,
			XK_F20
		}
};

#define MAX_RETRIES	10	/* max number of mapping retries */

static int
my_sync(display)
    Display        *display;
{
    XSync(display, 0);
}

Pkg_private     Xv_opaque
server_init_x(server_name)
    char           *server_name;
{
    register Display *display;

    if (!(display = XOpenDisplay(server_name)))
    	return ((Xv_opaque) NULL);

    if (defaults_get_boolean("window.synchronous", "Window.Synchronous", FALSE)
		 			        && !XSynchronize(display, TRUE))
	(void) XSetAfterFunction(display, my_sync);

    return ((Xv_opaque) display);
}

/*
 * keycode_in_map(map, keycode)
 *
 * returns the associated modifier index if the specified keycode is in the 
 * given modifier map. Otherwise, returns -1.
 */

static int
keycode_in_map(map, keycode)
	XModifierKeymap *map;
	KeyCode keycode;
{
	register int i, max;

	if (!keycode) return(0);

	max = 8 * map->max_keypermod;
	for (i = 0; i < max; i++) {
		if (map->modifiermap[i] == keycode) {
			return (i / map->max_keypermod);
		}
	}
	return -1;
}

static int
find_free_row(map)
	XModifierKeymap *map;
{
	int row, offset, base;

	/*
	 * Find the first unused row in the modifier map.
	 * An unused row will have all zeros in it.
	 */
	for (row = Mod1MapIndex; row <= Mod5MapIndex; row++) {
		base = row * map->max_keypermod;
		for (offset = 0; (offset < map->max_keypermod)  &&
			(map->modifiermap[base + offset] == 0); 
			offset++);
		if (offset == map->max_keypermod) {
			return(row);
		}
	}
	return(-1);
}

/*
 * server_refresh_modifiers(server, update_map)
 *
 * 1) Designates the meta keys as a modifier keys.
 * 2) Inserts all the keys in the array default_fkey_keysyms[] into
 * 	the server's modifier map (all under the same modifier; any
 *	of the modifiers Mod2-Mod5 may be used). This function then
 *	sets server->sel_modmask to be the appropriate mask for whatever
 *      modifier the keys were designated as.
 * 3) If update_map is false, do not try to insert new mappings into the
 *    modifier map.  Get the current mapping and update our internal
 *    understanding only.  update_map is false when a user runs xmodmap
 *    and changes the modifier map.  We don't want to override what the
 *    user just changed, so we try to live with it.
 */
Xv_private void
server_refresh_modifiers(server_public, update_map)
	Xv_opaque	 server_public;
	Bool		 update_map;   /* Update the server map */
{
	Server_info	*server = SERVER_PRIVATE(server_public);
	Display	*display = (Display *)server->xdisplay;
	XModifierKeymap *map;
	int             i, modifier, func_modifier, updated = False;
	int		keysym_set, result, retry_count;

	for (keysym_set = 0; keysym_set < NUM_KEYSYM_SETS; keysym_set++) {
		if (!(map = XGetModifierMapping(display))) {
			return;
		}

		/* See if META is already installed. */
		if ((modifier = keycode_in_map(map,
		     XKeysymToKeycode(display, XK_Meta_L))) == -1) {
		    /* Find a free row for META */
		    if (update_map && (modifier = find_free_row(map)) != -1) {
			updated = True;
			/* Insert the meta keys as modifiers. */
			map = XInsertModifiermapEntry(map,
			    XKeysymToKeycode(display, (KeySym) XK_Meta_L),
			    modifier);
			map = XInsertModifiermapEntry(map,
			    XKeysymToKeycode(display, (KeySym) XK_Meta_R),
			    modifier);
			}
		}
		if (modifier == -1 || modifier == 0)
		    server->meta_modmask = 0;
		else
		    server->meta_modmask = 1<<modifier;

		/* See if NUM LOCK is already installed. */
		if ((modifier = keycode_in_map(map,
		     XKeysymToKeycode(display, XK_Num_Lock))) == -1) {
		    /* Find a free row for NUM LOCK */
		    if (update_map && (modifier = find_free_row(map)) != -1) {
			updated = True;
			/* Insert the meta keys as modifiers. */
			map = XInsertModifiermapEntry(map,
			    XKeysymToKeycode(display, (KeySym) XK_Num_Lock),
			    modifier);
			}
		}
		if (modifier == -1 || modifier == 0)
		    server->num_lock_modmask = 0;
		else
		    server->num_lock_modmask = 1<<modifier;

		if (defaults_get_enum("openWindows.keyboardCommands",
				      "OpenWindows.KeyboardCommands",
				      xv_kbd_cmds_value_pairs) >=
		    KBD_CMDS_BASIC) {
		    /* See if ALT is already installed. */
		    if ((modifier = keycode_in_map(map,
			 XKeysymToKeycode(display, XK_Alt_L))) == -1) {
			/* Find a free row for ALT */
			if (update_map && (modifier = find_free_row(map))!=-1) {
			    updated = True;
			    /* Insert the alt keys as modifiers. */
			    map = XInsertModifiermapEntry(map,
				XKeysymToKeycode(display, (KeySym) XK_Alt_L),
				modifier);
			    map = XInsertModifiermapEntry(map,
				XKeysymToKeycode(display, (KeySym) XK_Alt_R),
				modifier);
			}
		    }
		    if (modifier == -1 || modifier == 0)
			server->alt_modmask = 0;
		    else
			server->alt_modmask = 1<<modifier;
		}

					       /* See if function keys in map */
		if (((func_modifier = keycode_in_map(map,
			       XKeysymToKeycode(display,
			       default_fkey_keysyms[keysym_set][0]))) == -1) ||
		    ((func_modifier = keycode_in_map(map,
			       XKeysymToKeycode(display,
			       default_fkey_keysyms[keysym_set][1]))) == -1)) {
					                  /* Find a free row. */
			if (update_map &&
				   (func_modifier = find_free_row(map)) != -1) {
			    for (i = 0; i < SELN_FN_NUM; i++) {
				updated = True;
				map = XInsertModifiermapEntry(map,
					XKeysymToKeycode(display,
					   default_fkey_keysyms[keysym_set][i]),
								 func_modifier);
			    }
			    server->sel_modmask = 1 << func_modifier;
			}
		} else
  			server->sel_modmask = 1 << func_modifier;

		if (func_modifier == -1 || func_modifier == 0)/* no free rows */
			server->sel_modmask = 0;

		/*
		 * Attempt to install the modifier mapping.
		 * If successful, exit this function. If not, try another 
		 * set of keysyms.
		 */
		if (updated) {
		    for (retry_count = 0;
			((result = XSetModifierMapping(display, map)) 
				== MappingBusy && retry_count < MAX_RETRIES);
			retry_count++) {
				sleep(1);/* if busy, wait 1 sec and retry */
		    }
  	  	    if (result == Success) {
    			XFreeModifiermap(map);
			return;
		    }
		} else {
    		    XFreeModifiermap(map);
		    return;
		}
	}

	/* all our attempts failed */
	xv_error(NULL,
		 ERROR_STRING, 
		    XV_MSG("Problems setting default modifier mapping"),
		 ERROR_PKG, SERVER,
		 0);

    	XFreeModifiermap(map);
}


Xv_private void
server_set_seln_function_pending(server_public, flag)
    Xv_Server       server_public;
    int             flag;
{
    Server_info    *server = SERVER_PRIVATE(server_public);
    server->seln_function_pending = flag ? TRUE : FALSE;
}

Xv_private int
server_get_seln_function_pending(server_public)
    Xv_Server       server_public;
{
    return (SERVER_PRIVATE(server_public)->seln_function_pending);
}