天天看點

display:The Wayland Book 節選Input

source code:https://git.sr.ht/~sircmpwn/wayland-book

本文内容均節選自 《The Wayland Book》

Seats: Handling input

From the client's perspective, it's reasonably straightforward. If you bind to the wl_seat global

分三種,pointer,keyboard,touch

This interface is relatively straightforward. The server will send the client a capabilities event to signal what kinds of input devices are supported by this seat — represented by a bitfield of capability values — and the client can bind to the input devices it wishes to use accordingly. For example, if the server sends capabilities where (caps & WL_SEAT_CAPABILITY_KEYBOARD) > 0 is true, the client may then use the get_keyboard request to obtain a wl_keyboard object for this seat. The semantics for each particular input device are covered in the remaining chapters.

client端要有一個wl_seat_listener去監聽sever發過來的支援序列,然後通過cap&wl_seat_capability_xxx去判斷,監聽對應的事件類型,如上所說,pointer/keyboard/touch

Event serials

Input frames

Releasing devices

Poniter input

Using the wl_seat.get_pointer request, clients may obtain a wl_pointer object. The server will send events to it whenever the user moves their pointer, presses mouse buttons, uses the scroll wheel, etc — whenever the pointer is over one of your surfaces.Once a pointer has entered your surface, you'll start receiving additional events for it, which we'll discuss shortly. The first thing you will likely want to do, however, is provide a cursor image. The process is as such:

  1.  Create a new wl_surface with the wl_compositor .
  2.  Use wl_pointer.set_cursor to attach that surface to the pointer.
  3.  Attach a cursor image wl_buffer to the surface and commit it.

After the cursor has entered your surface and you have attached an appropriate cursor, you're ready to start processing input events. There are motion, button, and axis events.

Point frames

Clients should accumulate all wl_pointer events as they're received, then process pending inputs as a single pointer event once the "frame" event is received.

Motion events

Button events

Axis events

axis事件用于滾動操作,例如旋轉滾動輪或從左到右搖動滾動輪。

XKB-x keyboard

。。。

Expanding our example code

In previous chapters, we built a simple client which can present its surfaces on the display. Let's expand this code a bit to build a client which can receive input events. For the sake of simplicity, we're just going to be logging input events to stderr. This is going to require a lot more code than we've worked with so far, so get strapped in. The first thing we need to do is set up the seat.

Setting up the seat

The first thing we'll need is a reference to a seat. We'll add it to our client_state struct, and add keyboard, pointer, and touch objects for later use as well:聲明結構體

struct wl_shm *wl_shm;
         struct wl_compositor *wl_compositor;
         struct xdg_wm_base *xdg_wm_base;
 +       struct wl_seat *wl_seat;
         /* Objects */
         struct wl_surface *wl_surface;
         struct xdg_surface *xdg_surface;
 +       struct wl_keyboard *wl_keyboard;
 +       struct wl_pointer *wl_pointer;
 +       struct wl_touch *wl_touch;
         /* State */
         float offset;
         uint32_t last_frame;
         int width, height;
           

 We'll also need to update registry_global to register a listener for that seat.綁定對應服務

wl_registry, name, &xdg_wm_base_interface, 1);
                 xdg_wm_base_add_listener(state->xdg_wm_base,
                                 &xdg_wm_base_listener, state);
 +       } else if (strcmp(interface, wl_seat_interface.name) == 0) {
 +               state->wl_seat = wl_registry_bind(
 +                               wl_registry, name, &wl_seat_interface, 7);
 +               wl_seat_add_listener(state->wl_seat,
 +                               &wl_seat_listener, state);
         }
  }
           

 Note that we bind to the latest version of the seat interface, version 7. Let's also rig up that listener:

+static void
 +wl_seat_capabilities(void *data, struct wl_seat *wl_seat, uint32_t capabilities)
 +{
 +       struct client_state *state = data;
 +       /* TODO */
 +}
 + +static void
 +wl_seat_name(void *data, struct wl_seat *wl_seat, const char *name)
 +{
 +       fprintf(stderr, "seat name: %s\n", name);
 +}
 +
 +const static struct wl_seat_listener wl_seat_listener = {
 +       .capabilities = wl_seat_capabilities,
 +       .name = wl_seat_name, +};
           

run this , you should seat the name of the seat printed to stderr.