1 | /********************************************************************** <BR>
|
---|
2 | This file is part of Crack dot Com's free source code release of
|
---|
3 | Golgotha. <a href="http://www.crack.com/golgotha_release"> <BR> for
|
---|
4 | information about compiling & licensing issues visit this URL</a>
|
---|
5 | <PRE> If that doesn't help, contact Jonathan Clark at
|
---|
6 | golgotha_source@usa.net (Subject should have "GOLG" in it)
|
---|
7 | ***********************************************************************/
|
---|
8 |
|
---|
9 | #include "video/x11/x11_input.hh"
|
---|
10 | #include "main/main.hh"
|
---|
11 | #include "video/x11/x11_display.hh"
|
---|
12 | #include "video/x11/mitshm.hh"
|
---|
13 | #include "video/display.hh"
|
---|
14 | #include "device/event.hh"
|
---|
15 | #include "device/keys.hh"
|
---|
16 | #include "device/kernel.hh"
|
---|
17 | #include "image/context.hh"
|
---|
18 |
|
---|
19 | extern int i4_global_native_argc;
|
---|
20 | extern char **i4_global_native_argv;
|
---|
21 |
|
---|
22 |
|
---|
23 | int i4_system_choose_option(char **choices)
|
---|
24 | {
|
---|
25 | return 0;
|
---|
26 | }
|
---|
27 |
|
---|
28 | i4_bool x11_input_class::open_display()
|
---|
29 | {
|
---|
30 | // get the default display name from the environment variable DISPLAY
|
---|
31 | char ds_name[512];
|
---|
32 |
|
---|
33 | strcpy(ds_name,getenv("DISPLAY"));
|
---|
34 | if (ds_name[0]==0)
|
---|
35 | strcpy(ds_name,"unix:0.0");
|
---|
36 |
|
---|
37 | if (getenv("X_REPEAT_ON"))
|
---|
38 | repeat_on=i4_T;
|
---|
39 |
|
---|
40 | // check the command line args for another display
|
---|
41 | w32 i=1;
|
---|
42 | for (;i<i4_global_argc;i++)
|
---|
43 | {
|
---|
44 | if (i4_global_argv[i] == "-ron")
|
---|
45 | repeat_on=i4_T;
|
---|
46 | else if (i4_global_argv[i] == "-display")
|
---|
47 | {
|
---|
48 | i++;
|
---|
49 | i4_os_string(i4_global_argv[i], ds_name, sizeof(ds_name));
|
---|
50 | }
|
---|
51 | }
|
---|
52 | display=XOpenDisplay(ds_name);
|
---|
53 | if (!display)
|
---|
54 | return i4_F;
|
---|
55 |
|
---|
56 | if (!repeat_on)
|
---|
57 | XAutoRepeatOff(display);
|
---|
58 | return i4_T;
|
---|
59 | }
|
---|
60 |
|
---|
61 |
|
---|
62 | void x11_input_class::close_display()
|
---|
63 | {
|
---|
64 | if (display)
|
---|
65 | {
|
---|
66 | if (!repeat_on)
|
---|
67 | XAutoRepeatOn(display);
|
---|
68 |
|
---|
69 | XCloseDisplay(display);
|
---|
70 | display=NULL;
|
---|
71 | }
|
---|
72 | }
|
---|
73 |
|
---|
74 | x11_input_class::x11_input_class()
|
---|
75 | {
|
---|
76 | repeat_on=i4_F;
|
---|
77 | display=0;
|
---|
78 | need_first_time=i4_T;
|
---|
79 | }
|
---|
80 |
|
---|
81 | XVisualInfo *x11_input_class::find_visual_with_depth(int depth)
|
---|
82 | {
|
---|
83 | XVisualInfo vis_info, *v;
|
---|
84 | int items;
|
---|
85 |
|
---|
86 | if (!display && !open_display())
|
---|
87 | return 0;
|
---|
88 |
|
---|
89 | if (depth==8)
|
---|
90 | vis_info.c_class=PseudoColor;
|
---|
91 | else
|
---|
92 | vis_info.c_class=TrueColor;
|
---|
93 |
|
---|
94 | vis_info.depth=depth;
|
---|
95 |
|
---|
96 | v=XGetVisualInfo(display,VisualClassMask | VisualDepthMask, &vis_info, &items);
|
---|
97 |
|
---|
98 | if (items>0)
|
---|
99 | {
|
---|
100 | XMatchVisualInfo(display, screen_num, vis_info.depth, vis_info.c_class, &vis_info);
|
---|
101 | v->visual = vis_info.visual;
|
---|
102 | return v;
|
---|
103 | }
|
---|
104 | else if (depth==16)
|
---|
105 | return find_visual_with_depth(15);
|
---|
106 | else
|
---|
107 | return 0;
|
---|
108 | }
|
---|
109 |
|
---|
110 |
|
---|
111 | // makes a null cursor
|
---|
112 | static Cursor x11_CreateNullCursor(Display *display, Window root)
|
---|
113 | {
|
---|
114 | Pixmap cursormask;
|
---|
115 | XGCValues xgc;
|
---|
116 | GC gc;
|
---|
117 | XColor dummycolour;
|
---|
118 | Cursor cursor;
|
---|
119 |
|
---|
120 | cursormask = XCreatePixmap(display, root, 1, 1, 1/*depth*/);
|
---|
121 | xgc.function = GXclear;
|
---|
122 | gc = XCreateGC(display, cursormask, GCFunction, &xgc);
|
---|
123 | XFillRectangle(display, cursormask, gc, 0, 0, 1, 1);
|
---|
124 | dummycolour.pixel = 0;
|
---|
125 | dummycolour.red = 0;
|
---|
126 | dummycolour.flags = 04;
|
---|
127 | cursor = XCreatePixmapCursor(display, cursormask, cursormask,
|
---|
128 | &dummycolour,&dummycolour, 0,0);
|
---|
129 | XFreePixmap(display,cursormask);
|
---|
130 | XFreeGC(display,gc);
|
---|
131 | return cursor;
|
---|
132 | }
|
---|
133 |
|
---|
134 | i4_bool x11_input_class::create_window(sw32 x, sw32 y, w32 w, w32 h,
|
---|
135 | i4_display_class *_i4_display,
|
---|
136 | i4_bool takeup_fullscreen,
|
---|
137 | XVisualInfo *visual)
|
---|
138 | {
|
---|
139 | i4_display=_i4_display;
|
---|
140 |
|
---|
141 | if (!open_display())
|
---|
142 | return i4_F;
|
---|
143 |
|
---|
144 | XVisualInfo vis_info;
|
---|
145 | int items;
|
---|
146 | XEvent report;
|
---|
147 | XTextProperty winName;
|
---|
148 |
|
---|
149 |
|
---|
150 |
|
---|
151 | // this will be 8, 16, or 32, (most likely 16 for now)
|
---|
152 | my_visual = visual;
|
---|
153 |
|
---|
154 |
|
---|
155 | if (!my_visual)
|
---|
156 | return i4_F;
|
---|
157 |
|
---|
158 | screen_num = DefaultScreen(display);
|
---|
159 |
|
---|
160 |
|
---|
161 | Colormap tmpcmap;
|
---|
162 |
|
---|
163 | tmpcmap = XCreateColormap(display,
|
---|
164 | XRootWindow(display,my_visual->screen),my_visual->visual,
|
---|
165 | AllocNone);
|
---|
166 |
|
---|
167 | int attribmask = CWColormap | CWBorderPixel;
|
---|
168 | XSetWindowAttributes attribs;
|
---|
169 | attribs.border_pixel = 0;
|
---|
170 | attribs.colormap = tmpcmap;
|
---|
171 |
|
---|
172 | w=(w+3)&(~3);
|
---|
173 | mainwin=XCreateWindow(display,
|
---|
174 | XRootWindow(display,my_visual->screen),
|
---|
175 | x,y,
|
---|
176 | w,h,
|
---|
177 | 0,
|
---|
178 | my_visual->depth,
|
---|
179 | InputOutput,
|
---|
180 | my_visual->visual,
|
---|
181 | attribmask,
|
---|
182 | &attribs);
|
---|
183 | XFreeColormap(display,tmpcmap);
|
---|
184 |
|
---|
185 | XSelectInput(display,mainwin,
|
---|
186 | KeyPressMask | VisibilityChangeMask | ButtonPressMask | ButtonReleaseMask |
|
---|
187 | ButtonMotionMask | PointerMotionMask | KeyReleaseMask | ExposureMask |
|
---|
188 | StructureNotifyMask | EnterWindowMask | LeaveWindowMask);
|
---|
189 |
|
---|
190 | XGCValues values;
|
---|
191 | gc=XCreateGC(display,mainwin,0,&values);
|
---|
192 | XSetBackground(display,gc,BlackPixel(display,screen_num));
|
---|
193 |
|
---|
194 | XMapWindow(display,mainwin);
|
---|
195 | do
|
---|
196 | {
|
---|
197 | XNextEvent(display, &report);
|
---|
198 | } while (report.type!= Expose); // wait for our window to pop up
|
---|
199 |
|
---|
200 | i4_kernel.add_device(this);
|
---|
201 |
|
---|
202 | XDefineCursor(display, mainwin, x11_CreateNullCursor(display, mainwin));
|
---|
203 |
|
---|
204 |
|
---|
205 | wm_delete_window = XInternAtom (display, "WM_DELETE_WINDOW", True);
|
---|
206 | wm_protocols = XInternAtom (display, "WM_PROTOCOLS", True);
|
---|
207 |
|
---|
208 | Atom prot[2];
|
---|
209 | prot[0]=wm_delete_window;
|
---|
210 | prot[1]=wm_protocols;
|
---|
211 |
|
---|
212 | XSetWMProtocols(display, mainwin, prot, 2);
|
---|
213 |
|
---|
214 |
|
---|
215 | return i4_T;
|
---|
216 | }
|
---|
217 |
|
---|
218 |
|
---|
219 | void x11_input_class::destroy_window()
|
---|
220 | {
|
---|
221 | i4_kernel.remove_device(this);
|
---|
222 |
|
---|
223 | XFreeGC(display, gc);
|
---|
224 | XFree((char *)my_visual);
|
---|
225 |
|
---|
226 | close_display();
|
---|
227 |
|
---|
228 | // if (I4_SCREEN_DEPTH==8)
|
---|
229 | // XFreeColormap(display,xcolor_map);
|
---|
230 | }
|
---|
231 |
|
---|
232 |
|
---|
233 |
|
---|
234 | void x11_input_class::get_x_time(w32 xtick, i4_time_class &t)
|
---|
235 | {
|
---|
236 | i4_time_class now;
|
---|
237 |
|
---|
238 | if (need_first_time)
|
---|
239 | {
|
---|
240 | first_time=xtick;
|
---|
241 | i4_start_time=now;
|
---|
242 | need_first_time=i4_F;
|
---|
243 | }
|
---|
244 |
|
---|
245 | w32 xtime=xtick-first_time;
|
---|
246 |
|
---|
247 | t = i4_start_time;
|
---|
248 | t.add_milli(xtime);
|
---|
249 |
|
---|
250 | if (now<t)
|
---|
251 | {
|
---|
252 | i4_start_time=now;
|
---|
253 | i4_start_time.add_milli(-xtime);
|
---|
254 | t=now;
|
---|
255 | }
|
---|
256 | }
|
---|
257 |
|
---|
258 | i4_bool x11_input_class::process_events()
|
---|
259 | {
|
---|
260 | i4_bool motion_occured=i4_F;
|
---|
261 | sw32 final_x, final_y;
|
---|
262 |
|
---|
263 | if (display)
|
---|
264 | {
|
---|
265 | while (XPending(display))
|
---|
266 | {
|
---|
267 | XEvent xev;
|
---|
268 | XNextEvent(display,&xev);
|
---|
269 |
|
---|
270 | note_event(xev);
|
---|
271 |
|
---|
272 | switch (xev.type)
|
---|
273 | {
|
---|
274 | case Expose :
|
---|
275 | {
|
---|
276 | if (context)
|
---|
277 | {
|
---|
278 | context->add_both_dirty(xev.xexpose.x,
|
---|
279 | xev.xexpose.y,
|
---|
280 | xev.xexpose.x+xev.xexpose.width,
|
---|
281 | xev.xexpose.y+xev.xexpose.height);
|
---|
282 | }
|
---|
283 | } break;
|
---|
284 |
|
---|
285 |
|
---|
286 | case ClientMessage:
|
---|
287 | {
|
---|
288 | /* Client messages are the means of the window manager
|
---|
289 | * communicating with a program. We'll first check to
|
---|
290 | * see if this is really the window manager talking
|
---|
291 | * to us.
|
---|
292 | */
|
---|
293 | if (xev.xclient.message_type == wm_protocols)
|
---|
294 | {
|
---|
295 | if ((Atom) xev.xclient.data.l[0] == wm_delete_window)
|
---|
296 | {
|
---|
297 | i4_display_close_event_class dc(i4_display);
|
---|
298 | send_event_to_agents(&dc, i4_device_class::FLAG_DISPLAY_CLOSE);
|
---|
299 | }
|
---|
300 | }
|
---|
301 | } break;
|
---|
302 |
|
---|
303 | //{{{ not implemented yet
|
---|
304 | case ConfigureNotify :
|
---|
305 | {
|
---|
306 | XFlush(display);
|
---|
307 |
|
---|
308 | int new_width=xev.xconfigure.width&~3; // must be word alligned
|
---|
309 | int new_height=xev.xconfigure.height;
|
---|
310 | if (new_width!=xev.xconfigure.width)
|
---|
311 | XResizeWindow(display,mainwin,new_width,xev.xconfigure.height);
|
---|
312 |
|
---|
313 | XFlush(display);
|
---|
314 |
|
---|
315 | resize(new_width, new_height);
|
---|
316 |
|
---|
317 | i4_display_change_event_class d_change(i4_display,
|
---|
318 | i4_display_change_event_class::SIZE_CHANGE);
|
---|
319 |
|
---|
320 | send_event_to_agents(&d_change,FLAG_DISPLAY_CHANGE);
|
---|
321 | } break;
|
---|
322 |
|
---|
323 | case MotionNotify :
|
---|
324 | {
|
---|
325 | motion_occured=i4_T;
|
---|
326 | final_x=xev.xmotion.x;
|
---|
327 | final_y=xev.xmotion.y;
|
---|
328 | } break;
|
---|
329 |
|
---|
330 | case ButtonRelease :
|
---|
331 | case ButtonPress :
|
---|
332 | {
|
---|
333 | i4_mouse_button_event_class::btype but;
|
---|
334 | switch (xev.xbutton.button)
|
---|
335 | {
|
---|
336 | case 1 : but=i4_mouse_button_event_class::LEFT; break;
|
---|
337 | case 3 : but=i4_mouse_button_event_class::RIGHT; break;
|
---|
338 | case 2 : but=i4_mouse_button_event_class::CENTER; break;
|
---|
339 | }
|
---|
340 |
|
---|
341 | i4_time_class now;
|
---|
342 | if (xev.type == ButtonRelease)
|
---|
343 | {
|
---|
344 | i4_mouse_button_up_event_class up(but, mouse_x, mouse_y,
|
---|
345 | now, last_up[but]);
|
---|
346 | send_event_to_agents(&up,FLAG_MOUSE_BUTTON_UP);
|
---|
347 | last_up[but]=now;
|
---|
348 | }
|
---|
349 | else
|
---|
350 | {
|
---|
351 | i4_mouse_button_down_event_class up(but, mouse_x, mouse_y,
|
---|
352 | now, last_down[but]);
|
---|
353 | send_event_to_agents(&up,FLAG_MOUSE_BUTTON_DOWN);
|
---|
354 | last_down[but]=now;
|
---|
355 | }
|
---|
356 | } break;
|
---|
357 |
|
---|
358 | case KeyPress :
|
---|
359 | case KeyRelease :
|
---|
360 | {
|
---|
361 | char buf;
|
---|
362 | KeySym ks;
|
---|
363 | XLookupString(&xev.xkey,&buf,1,&ks,NULL);
|
---|
364 | w16 key, key_code;
|
---|
365 |
|
---|
366 | switch (ks)
|
---|
367 | {
|
---|
368 | case XK_Down : key_code=I4_DOWN; break;
|
---|
369 | case XK_Up : key_code=I4_UP; break;
|
---|
370 | case XK_Left : key_code=I4_LEFT; break;
|
---|
371 | case XK_Right : key_code=I4_RIGHT; break;
|
---|
372 | case XK_Control_L :
|
---|
373 | {
|
---|
374 | key_code=I4_CTRL_L;
|
---|
375 | if (xev.type==KeyPress)
|
---|
376 | modifier_state|=I4_MODIFIER_CTRL_L;
|
---|
377 | else
|
---|
378 | modifier_state&=~I4_MODIFIER_CTRL_L;
|
---|
379 | } break;
|
---|
380 |
|
---|
381 | case XK_Control_R :
|
---|
382 | {
|
---|
383 | key_code=I4_CTRL_R;
|
---|
384 | if (xev.type==KeyPress)
|
---|
385 | modifier_state|=I4_MODIFIER_CTRL_R;
|
---|
386 | else
|
---|
387 | modifier_state&=~I4_MODIFIER_CTRL_R;
|
---|
388 | } break;
|
---|
389 |
|
---|
390 | case XK_Alt_L :
|
---|
391 | {
|
---|
392 | key_code=I4_ALT_L;
|
---|
393 | if (xev.type==KeyPress)
|
---|
394 | modifier_state|=I4_MODIFIER_ALT_L;
|
---|
395 | else
|
---|
396 | modifier_state&=~I4_MODIFIER_ALT_L;
|
---|
397 | } break;
|
---|
398 |
|
---|
399 | case XK_Alt_R :
|
---|
400 | {
|
---|
401 | key_code=I4_ALT_R;
|
---|
402 | if (xev.type==KeyPress)
|
---|
403 | modifier_state|=I4_MODIFIER_ALT_R;
|
---|
404 | else
|
---|
405 | modifier_state&=~I4_MODIFIER_ALT_R;
|
---|
406 | } break;
|
---|
407 |
|
---|
408 |
|
---|
409 | case XK_Shift_L :
|
---|
410 | {
|
---|
411 | key_code=I4_SHIFT_L;
|
---|
412 | if (xev.type==KeyPress)
|
---|
413 | modifier_state|=I4_MODIFIER_SHIFT_L;
|
---|
414 | else
|
---|
415 | modifier_state&=~I4_MODIFIER_SHIFT_L;
|
---|
416 | } break;
|
---|
417 |
|
---|
418 | case XK_Shift_R :
|
---|
419 | {
|
---|
420 | key_code=I4_SHIFT_R;
|
---|
421 | if (xev.type==KeyPress)
|
---|
422 | modifier_state|=I4_MODIFIER_SHIFT_R;
|
---|
423 | else
|
---|
424 | modifier_state&=~I4_MODIFIER_SHIFT_R;
|
---|
425 | } break;
|
---|
426 |
|
---|
427 |
|
---|
428 | case XK_Num_Lock : key_code=I4_NUM_LOCK; break;
|
---|
429 | case XK_Home : key_code=I4_HOME; break;
|
---|
430 | case XK_End : key_code=I4_END; break;
|
---|
431 | case XK_BackSpace : key_code=I4_BACKSPACE; break;
|
---|
432 | case XK_Tab : key_code=I4_TAB; break;
|
---|
433 | case XK_Return : key_code=I4_ENTER; break;
|
---|
434 | case XK_Caps_Lock : key_code=I4_CAPS; break;
|
---|
435 | case XK_Escape : key_code=I4_ESC; break;
|
---|
436 | case XK_F1 : key_code=I4_F1; break;
|
---|
437 | case XK_F2 : key_code=I4_F2; break;
|
---|
438 | case XK_F3 : key_code=I4_F3; break;
|
---|
439 | case XK_F4 : key_code=I4_F4; break;
|
---|
440 | case XK_F5 : key_code=I4_F5; break;
|
---|
441 | case XK_F6 : key_code=I4_F6; break;
|
---|
442 | case XK_F7 : key_code=I4_F7; break;
|
---|
443 | case XK_F8 : key_code=I4_F8; break;
|
---|
444 | case XK_F9 : key_code=I4_F9; break;
|
---|
445 | case XK_F10 : key_code=I4_F10; break;
|
---|
446 | case XK_Insert : key_code=I4_INSERT; break;
|
---|
447 | case XK_Page_Up : key_code=I4_PAGEUP; break;
|
---|
448 | case XK_Page_Down : key_code=I4_PAGEDOWN; break;
|
---|
449 | case XK_Delete : key_code=I4_DEL; break;
|
---|
450 |
|
---|
451 | case XK_KP_0 : key_code=I4_KP0; break;
|
---|
452 | case XK_KP_1 : key_code=I4_KP1; break;
|
---|
453 | case XK_KP_2 : key_code=I4_KP2; break;
|
---|
454 | case XK_KP_3 : key_code=I4_KP3; break;
|
---|
455 | case XK_KP_4 : key_code=I4_KP4; break;
|
---|
456 | case XK_KP_5 : key_code=I4_KP5; break;
|
---|
457 | case XK_KP_6 : key_code=I4_KP6; break;
|
---|
458 | case XK_KP_7 : key_code=I4_KP7; break;
|
---|
459 | case XK_KP_8 : key_code=I4_KP8; break;
|
---|
460 | case XK_KP_9 : key_code=I4_KP9; break;
|
---|
461 |
|
---|
462 | case XK_KP_Insert : key_code=I4_KP0; break;
|
---|
463 | case XK_KP_End : key_code=I4_KP1; break;
|
---|
464 | case XK_KP_Down : key_code=I4_KP2; break;
|
---|
465 | case XK_KP_Page_Down : key_code=I4_KP3; break;
|
---|
466 | case XK_KP_Left : key_code=I4_KP4; break;
|
---|
467 | case XK_KP_Begin : key_code=I4_KP5; break;
|
---|
468 | case XK_KP_Right : key_code=I4_KP6; break;
|
---|
469 | case XK_KP_Home : key_code=I4_KP7; break;
|
---|
470 | case XK_KP_Up : key_code=I4_KP8; break;
|
---|
471 | case XK_KP_Page_Up : key_code=I4_KP9; break;
|
---|
472 |
|
---|
473 | case XK_KP_Delete :
|
---|
474 | case XK_KP_Decimal : key_code=I4_KPPERIOD; break;
|
---|
475 |
|
---|
476 | case ' ': key_code=I4_SPACE; break;
|
---|
477 | case '`':
|
---|
478 | case '~': key_code='`'; break;
|
---|
479 | case '-':
|
---|
480 | case '_': key_code='-'; break;
|
---|
481 | case '=':
|
---|
482 | case '+': key_code='='; break;
|
---|
483 | case '[':
|
---|
484 | case '{': key_code='['; break;
|
---|
485 | case ']':
|
---|
486 | case '}': key_code=']'; break;
|
---|
487 | case '\\':
|
---|
488 | case '|': key_code='\\'; break;
|
---|
489 | case ';':
|
---|
490 | case ':': key_code=';'; break;
|
---|
491 | case '\'':
|
---|
492 | case '"': key_code='\''; break;
|
---|
493 | case ',':
|
---|
494 | case '<': key_code=','; break;
|
---|
495 | case '.':
|
---|
496 | case '>': key_code='.'; break;
|
---|
497 | case '/':
|
---|
498 | case '?': key_code='/'; break;
|
---|
499 |
|
---|
500 | case ')': key_code='0'; break;
|
---|
501 | case '!': key_code='1'; break;
|
---|
502 | case '@': key_code='2'; break;
|
---|
503 | case '#': key_code='3'; break;
|
---|
504 | case '$': key_code='4'; break;
|
---|
505 | case '%': key_code='5'; break;
|
---|
506 | case '^': key_code='6'; break;
|
---|
507 | case '&': key_code='7'; break;
|
---|
508 | case '*': key_code='8'; break;
|
---|
509 | case '(': key_code='9'; break;
|
---|
510 |
|
---|
511 | default :
|
---|
512 | if ((ks>=XK_A && ks<=XK_Z) || (ks>=XK_0 && ks<=XK_9))
|
---|
513 | key_code = ks;
|
---|
514 | else if (ks>=XK_a && ks<=XK_z)
|
---|
515 | key_code = ks + 'A' - 'a';
|
---|
516 | else
|
---|
517 | key_code=0;
|
---|
518 | }
|
---|
519 |
|
---|
520 | if (key_code)
|
---|
521 | {
|
---|
522 | if (xev.type==KeyPress)
|
---|
523 | {
|
---|
524 | i4_time_class t;
|
---|
525 | get_x_time(xev.xkey.time, t);
|
---|
526 |
|
---|
527 | key = i4_key_translate(key_code,1,modifier_state);
|
---|
528 | i4_key_press_event_class ev(key, key_code, modifier_state, t);
|
---|
529 |
|
---|
530 | send_event_to_agents(&ev,FLAG_KEY_PRESS);
|
---|
531 | }
|
---|
532 | else
|
---|
533 | {
|
---|
534 | key = i4_key_translate(key_code,0, modifier_state);
|
---|
535 |
|
---|
536 | i4_time_class t;
|
---|
537 | get_x_time(xev.xkey.time, t);
|
---|
538 |
|
---|
539 | i4_key_release_event_class ev(key, key_code, modifier_state, t);
|
---|
540 | send_event_to_agents(&ev,FLAG_KEY_RELEASE);
|
---|
541 | }
|
---|
542 | }
|
---|
543 | } break;
|
---|
544 |
|
---|
545 | case EnterNotify:
|
---|
546 | if (!repeat_on)
|
---|
547 | XAutoRepeatOff(display);
|
---|
548 | break;
|
---|
549 |
|
---|
550 | case LeaveNotify:
|
---|
551 | if (!repeat_on)
|
---|
552 | XAutoRepeatOn(display);
|
---|
553 | break;
|
---|
554 | }
|
---|
555 | }
|
---|
556 | }
|
---|
557 |
|
---|
558 |
|
---|
559 | if (motion_occured && (final_x!=mouse_x || final_y!=mouse_y))
|
---|
560 | {
|
---|
561 | i4_mouse_move_event_class move(mouse_x, mouse_y, final_x, final_y);
|
---|
562 | send_event_to_agents(&move,FLAG_MOUSE_MOVE);
|
---|
563 |
|
---|
564 | if (mouse_locked)
|
---|
565 | XWarpPointer(display, None, mainwin, 0,0, 0,0, mouse_x, mouse_y);
|
---|
566 | else
|
---|
567 | {
|
---|
568 | mouse_x=final_x;
|
---|
569 | mouse_y=final_y;
|
---|
570 | }
|
---|
571 | }
|
---|
572 |
|
---|
573 | return i4_F;
|
---|
574 | }
|
---|