|
48 | 48 | #include <X11/Xutil.h>
|
49 | 49 | #include <X11/extensions/XShm.h>
|
50 | 50 | #include <X11/extensions/shmproto.h>
|
| 51 | +#include <X11/extensions/XInput2.h> |
51 | 52 | #include <X11/Xatom.h>
|
52 | 53 | #include <X11/cursorfont.h>
|
53 | 54 | #include <X11/Xlib-xcb.h>
|
@@ -379,6 +380,9 @@ static Window mkwindow(Ghandles * g, struct windowdata *vm_window)
|
379 | 380 | ButtonPressMask | ButtonReleaseMask |
|
380 | 381 | PointerMotionMask | EnterWindowMask | LeaveWindowMask |
|
381 | 382 | FocusChangeMask | StructureNotifyMask | PropertyChangeMask);
|
| 383 | + |
| 384 | + // TODO: select XI events here |
| 385 | + |
382 | 386 | XSetWMProtocols(g->display, child_win, &g->wmDeleteMessage, 1);
|
383 | 387 | if (g->icon_data) {
|
384 | 388 | XChangeProperty(g->display, child_win, g->net_wm_icon, XA_CARDINAL, 32,
|
@@ -639,6 +643,9 @@ static void mkghandles(Ghandles * g)
|
639 | 643 | if (!XQueryExtension(g->display, "MIT-SHM",
|
640 | 644 | &g->shm_major_opcode, &ev_base, &err_base))
|
641 | 645 | fprintf(stderr, "MIT-SHM X extension missing!\n");
|
| 646 | + if (!XQueryExtension(g->display, "XInputExtension", &g->xi_opcode, &ev_base, &err_base)) { |
| 647 | + fprintf(stderr, "X Input extension not available.\n"); |
| 648 | + } |
642 | 649 | /* get the work area */
|
643 | 650 | XSelectInput(g->display, g->root_win, PropertyChangeMask);
|
644 | 651 | update_work_area(g);
|
@@ -2310,73 +2317,99 @@ static void process_xevent_xembed(Ghandles * g, const XClientMessageEvent * ev)
|
2310 | 2317 |
|
2311 | 2318 | }
|
2312 | 2319 |
|
| 2320 | +// static void process_xievent(Ghandles * g, XIDeviceEvent event) { |
| 2321 | +// switch (event.evtype) |
| 2322 | +// { |
| 2323 | +// case XI_RawButtonPress: |
| 2324 | +// case XI_RawButtonRelease: |
| 2325 | +// case XI_RawMotion: |
| 2326 | +// case XI_RawKeyPress: |
| 2327 | +// case XI_RawKeyRelease: |
| 2328 | +// // TODO: handle raw events, no flags on raw events |
| 2329 | +// break; |
| 2330 | +// case XI_KeyPress: |
| 2331 | +// case XI_KeyRelease: |
| 2332 | +// printf(" flags: %s\n", (event->flags & XIKeyRepeat) ? "repeat" : ""); |
| 2333 | +// // TODO: handle events |
| 2334 | +// break; |
| 2335 | +// case XI_ButtonPress: |
| 2336 | +// case XI_ButtonRelease: |
| 2337 | +// case XI_Motion: |
| 2338 | +// printf(" flags: %s\n", (event->flags & XIPointerEmulated) ? "emulated" : ""); |
| 2339 | +// // TODO: handle events |
| 2340 | +// break; |
| 2341 | +// } |
| 2342 | +// } |
| 2343 | + |
2313 | 2344 | /* dispatch local Xserver event */
|
2314 | 2345 | static void process_xevent(Ghandles * g)
|
2315 | 2346 | {
|
2316 | 2347 | XEvent event_buffer;
|
2317 | 2348 | XNextEvent(g->display, &event_buffer);
|
2318 |
| - bool is_xinput_event = false; |
2319 | 2349 |
|
2320 | 2350 | if (event_buffer.type == GenericEvent &&
|
2321 | 2351 | event_buffer.xcookie.extension == g->xi_opcode) {
|
2322 |
| - is_xinput_event = (XIDeviceEvent*)&event_buffer; |
2323 |
| - } |
2324 |
| - |
2325 |
| - switch (event_buffer.type) { |
2326 |
| - case KeyPress: |
2327 |
| - case KeyRelease: |
2328 |
| - process_xevent_keypress(g, (XKeyEvent *) & event_buffer); |
2329 |
| - break; |
2330 |
| - case ReparentNotify: |
2331 |
| - process_xevent_reparent(g, (XReparentEvent *) &event_buffer); |
2332 |
| - break; |
2333 |
| - case ConfigureNotify: |
2334 |
| - process_xevent_configure(g, (XConfigureEvent *) & |
2335 |
| - event_buffer); |
2336 |
| - break; |
2337 |
| - case ButtonPress: |
2338 |
| - case ButtonRelease: |
2339 |
| - process_xevent_button(g, (XButtonEvent *) & event_buffer); |
2340 |
| - break; |
2341 |
| - case MotionNotify: |
2342 |
| - process_xevent_motion(g, (XMotionEvent *) & event_buffer); |
2343 |
| - break; |
2344 |
| - case EnterNotify: |
2345 |
| - case LeaveNotify: |
2346 |
| - process_xevent_crossing(g, |
2347 |
| - (XCrossingEvent *) & event_buffer); |
2348 |
| - break; |
2349 |
| - case FocusIn: |
2350 |
| - case FocusOut: |
2351 |
| - process_xevent_focus(g, |
2352 |
| - (XFocusChangeEvent *) & event_buffer); |
2353 |
| - break; |
2354 |
| - case Expose: |
2355 |
| - process_xevent_expose(g, (XExposeEvent *) & event_buffer); |
2356 |
| - break; |
2357 |
| - case MapNotify: |
2358 |
| - process_xevent_mapnotify(g, (XMapEvent *) & event_buffer); |
2359 |
| - break; |
2360 |
| - case PropertyNotify: |
2361 |
| - process_xevent_propertynotify(g, (XPropertyEvent *) & event_buffer); |
2362 |
| - break; |
2363 |
| - case ClientMessage: |
2364 |
| -// fprintf(stderr, "xclient, atom=%s\n", |
2365 |
| -// XGetAtomName(g->display, |
2366 |
| -// event_buffer.xclient.message_type)); |
2367 |
| - if (event_buffer.xclient.message_type == g->xembed_message) { |
2368 |
| - process_xevent_xembed(g, (XClientMessageEvent *) & |
2369 |
| - event_buffer); |
2370 |
| - } else if ((Atom)event_buffer.xclient.data.l[0] == |
2371 |
| - g->wmDeleteMessage) { |
2372 |
| - if (g->log_level > 0) |
2373 |
| - fprintf(stderr, "close for 0x%x\n", |
2374 |
| - (int) event_buffer.xclient.window); |
2375 |
| - process_xevent_close(g, |
2376 |
| - event_buffer.xclient.window); |
| 2352 | + XIDeviceEvent* xi_event = (XIDeviceEvent*)&event_buffer; |
| 2353 | + switch (xi_event->evtype) { |
| 2354 | + case XI_KeyPress: |
| 2355 | + case XI_KeyRelease: |
| 2356 | + if (xi_event && xi_event->flags & XIKeyRepeat) break; // don't send key repeat events |
| 2357 | + process_xevent_keypress(g, xi_event); |
| 2358 | + break; |
| 2359 | + } |
| 2360 | + } else { |
| 2361 | + switch (event_buffer.type) { |
| 2362 | + case ReparentNotify: |
| 2363 | + process_xevent_reparent(g, (XReparentEvent *) &event_buffer); |
| 2364 | + break; |
| 2365 | + case ConfigureNotify: |
| 2366 | + process_xevent_configure(g, (XConfigureEvent *) & |
| 2367 | + event_buffer); |
| 2368 | + break; |
| 2369 | + case ButtonPress: |
| 2370 | + case ButtonRelease: |
| 2371 | + process_xevent_button(g, (XButtonEvent *) & event_buffer); |
| 2372 | + break; |
| 2373 | + case MotionNotify: |
| 2374 | + process_xevent_motion(g, (XMotionEvent *) & event_buffer); |
| 2375 | + break; |
| 2376 | + case EnterNotify: |
| 2377 | + case LeaveNotify: |
| 2378 | + process_xevent_crossing(g, |
| 2379 | + (XCrossingEvent *) & event_buffer); |
| 2380 | + break; |
| 2381 | + case FocusIn: |
| 2382 | + case FocusOut: |
| 2383 | + process_xevent_focus(g, |
| 2384 | + (XFocusChangeEvent *) & event_buffer); |
| 2385 | + break; |
| 2386 | + case Expose: |
| 2387 | + process_xevent_expose(g, (XExposeEvent *) & event_buffer); |
| 2388 | + break; |
| 2389 | + case MapNotify: |
| 2390 | + process_xevent_mapnotify(g, (XMapEvent *) & event_buffer); |
| 2391 | + break; |
| 2392 | + case PropertyNotify: |
| 2393 | + process_xevent_propertynotify(g, (XPropertyEvent *) & event_buffer); |
| 2394 | + break; |
| 2395 | + case ClientMessage: |
| 2396 | + // fprintf(stderr, "xclient, atom=%s\n", |
| 2397 | + // XGetAtomName(g->display, |
| 2398 | + // event_buffer.xclient.message_type)); |
| 2399 | + if (event_buffer.xclient.message_type == g->xembed_message) { |
| 2400 | + process_xevent_xembed(g, (XClientMessageEvent *) & |
| 2401 | + event_buffer); |
| 2402 | + } else if ((Atom)event_buffer.xclient.data.l[0] == |
| 2403 | + g->wmDeleteMessage) { |
| 2404 | + if (g->log_level > 0) |
| 2405 | + fprintf(stderr, "close for 0x%x\n", |
| 2406 | + (int) event_buffer.xclient.window); |
| 2407 | + process_xevent_close(g, |
| 2408 | + event_buffer.xclient.window); |
| 2409 | + } |
| 2410 | + break; |
| 2411 | + default:; |
2377 | 2412 | }
|
2378 |
| - break; |
2379 |
| - default:; |
2380 | 2413 | }
|
2381 | 2414 | }
|
2382 | 2415 |
|
|
0 commit comments