compositor: Forward pointer focus notification from compostor backend
authorKristian Høgsberg <krh@bitplanet.net>
Thu, 27 Jan 2011 01:35:07 +0000 (20:35 -0500)
committerKristian Høgsberg <krh@bitplanet.net>
Thu, 27 Jan 2011 01:35:09 +0000 (20:35 -0500)
This lets the compositor place the pointer sprite correctly when it receives
pointer focus and allows it to send pointer focus to any client that might
receive pointer focus as the compositor receives it.

compositor/compositor-wayland.c
compositor/compositor-x11.c
compositor/compositor.c
compositor/compositor.h
compositor/tty.c

index eb2f5e6..d80cf5f 100644 (file)
@@ -274,28 +274,6 @@ wayland_compositor_create_output(struct wayland_compositor *c,
        return 0;
 }
 
-static struct wl_buffer *
-create_invisible_pointer(struct wayland_compositor *c)
-{
-       struct wl_buffer *buffer;
-       struct wl_visual *visual;
-       GLuint texture;
-       const int width = 1, height = 1;
-       const GLubyte data[] = { 0, 0, 0, 0 };
-
-       glGenTextures(1, &texture);
-       glBindTexture(GL_TEXTURE_2D, texture);
-       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
-       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
-       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
-       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
-
-       visual = wl_display_get_premultiplied_argb_visual(c->parent.display);
-       buffer = c->base.create_buffer(&c->base, width, height, visual, data);
-
-       return buffer;
-}
-
 /* Events received from the wayland-server this compositor is client of: */
 
 /* parent output interface */
@@ -395,18 +373,15 @@ input_handle_pointer_focus(void *data,
                            int32_t x, int32_t y, int32_t sx, int32_t sy)
 {
        struct wayland_input *input = data;
+       struct wayland_output *output = data;
        struct wayland_compositor *c = input->compositor;
-       static struct wl_buffer *pntr_buffer = NULL;
 
        if (surface) {
-               c->base.focus = 1;
-               /* FIXME: extend protocol to allow hiding the cursor? */
-               if (pntr_buffer == NULL)
-                       pntr_buffer = create_invisible_pointer(c);
-               wl_input_device_attach(input_device, time, pntr_buffer, x, y);
+               output = wl_surface_get_user_data(surface);
+               notify_pointer_focus(c->base.input_device,
+                                    time, &output->base, sx, sy);
        } else {
-               /* FIXME. hide our own pointer */
-               c->base.focus = 0;
+               notify_pointer_focus(c->base.input_device, time, NULL, 0, 0);
        }
 }
 
index cbd266a..4a5f10b 100644 (file)
@@ -547,6 +547,7 @@ x11_compositor_handle_event(int fd, uint32_t mask, void *data)
        struct wl_event_loop *loop;
        xcb_client_message_event_t *client_message;
        xcb_motion_notify_event_t *motion_notify;
+       xcb_enter_notify_event_t *enter_notify;
        xcb_key_press_event_t *key_press;
        xcb_button_press_event_t *button_press;
        xcb_expose_event_t *expose;
@@ -605,13 +606,22 @@ x11_compositor_handle_event(int fd, uint32_t mask, void *data)
                        break;
 
                case XCB_ENTER_NOTIFY:
-                       c->base.focus = 1;
-                       wlsc_compositor_schedule_repaint(&c->base);
+                       enter_notify = (xcb_enter_notify_event_t *) event;
+                       output = x11_compositor_find_output(c, enter_notify->event);
+                       notify_pointer_focus(c->base.input_device,
+                                            enter_notify->time,
+                                            &output->base,
+                                            enter_notify->event_x,
+                                            enter_notify->event_y);
                        break;
 
                case XCB_LEAVE_NOTIFY:
-                       c->base.focus = 0;
-                       wlsc_compositor_schedule_repaint(&c->base);
+                       enter_notify = (xcb_enter_notify_event_t *) event;
+                       notify_pointer_focus(c->base.input_device,
+                                            enter_notify->time,
+                                            NULL,
+                                            enter_notify->event_x,
+                                            enter_notify->event_y);
                        break;
 
                case XCB_CLIENT_MESSAGE:
index 746a729..324e73d 100644 (file)
@@ -805,6 +805,39 @@ notify_key(struct wl_input_device *device,
                                     WL_INPUT_DEVICE_KEY, time, key, state);
 }
 
+void
+notify_pointer_focus(struct wl_input_device *device,
+                    uint32_t time, struct wlsc_output *output,
+                    int32_t x, int32_t y)
+{
+       struct wlsc_input_device *wd = (struct wlsc_input_device *) device;
+       struct wlsc_compositor *compositor =
+               (struct wlsc_compositor *) device->compositor;
+       struct wlsc_surface *es;
+       int32_t sx, sy;
+
+       if (output) {
+               device->x = x;
+               device->y = y;
+               es = pick_surface(device, &sx, &sy);
+               wl_input_device_set_pointer_focus(device,
+                                                 &es->surface,
+                                                 time, x, y, sx, sy);
+
+               compositor->focus = 1;
+
+               wd->sprite->x = device->x - wd->hotspot_x;
+               wd->sprite->y = device->y - wd->hotspot_y;
+               wlsc_surface_update_matrix(wd->sprite);
+       } else {
+               wl_input_device_set_pointer_focus(device, NULL,
+                                                 time, 0, 0, 0, 0);
+               compositor->focus = 0;
+       }
+
+       wlsc_compositor_schedule_repaint(compositor);
+}
+
 static void
 input_device_attach(struct wl_client *client,
                    struct wl_input_device *device_base,
index fbfaa59..e40006c 100644 (file)
@@ -156,6 +156,12 @@ notify_key(struct wl_input_device *device,
           uint32_t time, uint32_t key, uint32_t state);
 
 void
+notify_pointer_focus(struct wl_input_device *device,
+                    uint32_t time,
+                    struct wlsc_output *output,
+                    int32_t x, int32_t y);
+
+void
 wlsc_compositor_finish_frame(struct wlsc_compositor *compositor, int msecs);
 void
 wlsc_compositor_schedule_repaint(struct wlsc_compositor *compositor);
index 6314b14..0de7584 100644 (file)
@@ -54,7 +54,6 @@ static void on_enter_vt(int signal_number, void *data)
        ret = ioctl(tty->fd, KDSETMODE, KD_GRAPHICS);
        if (ret)
                fprintf(stderr, "failed to set KD_GRAPHICS mode on console: %m\n");
-       tty->compositor->focus = 1;
 }
 
 static void on_leave_vt(int signal_number, void *data)
@@ -67,8 +66,6 @@ static void on_leave_vt(int signal_number, void *data)
        if (ret)
                fprintf(stderr,
                        "failed to set KD_TEXT mode on console: %m\n");
-
-       tty->compositor->focus = 0;
 }
 
 static void