[PATCH] xwayland: Clear pending cursor frame callbacks on pointer enter

2016-02-04 Thread Rui Matos
The last cursor frame we commited before the pointer left one of our
surfaces might not have been shown. In that case we'll have a cursor
surface frame callback pending which we need to clear so that we can
continue submitting new cursor frames.

Signed-off-by: Rui Matos <tiagoma...@gmail.com>
Reviewed-by: Daniel Stone <dani...@collabora.com>
---

v2: as suggested by Jonas, moved the hunk further up to stay close to
another related hack we already have and also removed the
xwl_seat_set_cursor() call since CheckMotion() will do that too.

I think Daniel's r-b still stands anyway.

 hw/xwayland/xwayland-input.c | 9 +
 1 file changed, 9 insertions(+)

diff --git a/hw/xwayland/xwayland-input.c b/hw/xwayland/xwayland-input.c
index 61ca70b..d6cbf32 100644
--- a/hw/xwayland/xwayland-input.c
+++ b/hw/xwayland/xwayland-input.c
@@ -251,6 +251,15 @@ pointer_handle_enter(void *data, struct wl_pointer 
*pointer,
 mipointer = MIPOINTER(master);
 mipointer->pSpriteCursor = (CursorPtr) 1;
 
+/* The last cursor frame we commited before the pointer left one
+ * of our surfaces might not have been shown. In that case we'll
+ * have a cursor surface frame callback pending which we need to
+ * clear so that we can continue submitting new cursor frames. */
+if (xwl_seat->cursor_frame_cb) {
+wl_callback_destroy(xwl_seat->cursor_frame_cb);
+xwl_seat->cursor_frame_cb = NULL;
+}
+
 CheckMotion(NULL, master);
 
 /* Ideally, X clients shouldn't see these button releases.  When
-- 
2.5.0

___
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/wayland-devel


[PATCH] xwayland: Clear pending cursor frame callbacks on pointer enter

2016-02-03 Thread Rui Matos
The last cursor frame we commited before the pointer left one of our
surfaces might not have been shown. In that case we'll have a cursor
surface frame callback pending which we need to clear so that we can
continue submitting new cursor frames.

Signed-off-by: Rui Matos <tiagoma...@gmail.com>
---

On Wed, Feb 3, 2016 at 9:30 AM, Pekka Paalanen <ppaala...@gmail.com> wrote:
> Xwayland commits a wl_buffer to a cursor wl_surface with a frame
> callback, and the frame callback may never be emitted by the
> compositor, right?
>
> Is Xwayland waiting for any previous frame callback to be signalled
> before it commits a buffer or re-sets the cursor role on the
> wl_surface? Even if the commit and re-set is caused by wl_pointer.enter?
>
> Would it be a better fix to destroy any pending frame callback and
> commit and re-set the role unconditionally on wl_pointer.enter?

Yes, this seems like the proper fix indeed. Thanks,

Rui

 hw/xwayland/xwayland-input.c | 10 ++
 1 file changed, 10 insertions(+)

diff --git a/hw/xwayland/xwayland-input.c b/hw/xwayland/xwayland-input.c
index 61ca70b..f9e3255 100644
--- a/hw/xwayland/xwayland-input.c
+++ b/hw/xwayland/xwayland-input.c
@@ -267,6 +267,16 @@ pointer_handle_enter(void *data, struct wl_pointer 
*pointer,
 for (i = 0; i < dev->button->numButtons; i++)
 if (BitIsOn(dev->button->down, i))
 QueuePointerEvents(dev, ButtonRelease, i, 0, );
+
+/* The last cursor frame we commited before the pointer left one
+ * of our surfaces might not have been shown. In that case we'll
+ * have a cursor surface frame callback pending which we need to
+ * clear so that we can continue submitting new cursor frames. */
+if (xwl_seat->cursor_frame_cb) {
+wl_callback_destroy(xwl_seat->cursor_frame_cb);
+xwl_seat->cursor_frame_cb = NULL;
+xwl_seat_set_cursor(xwl_seat);
+}
 }
 
 static void
-- 
2.5.0

___
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/wayland-devel


[PATCH] xwayland: Throttle our cursor surface updates with a frame callback

2015-05-27 Thread Rui Matos
In some extreme cases with animated cursors at a high frame rate we
could end up filling the wl_display outgoing buffer and end up with
wl_display_flush() failing.

In any case, using the frame callback to throttle ourselves is the
right thing to do.

Signed-off-by: Rui Matos tiagoma...@gmail.com
---


On Tue, May 26, 2015 at 10:58 PM, Keith Packard kei...@keithp.com wrote:
 Looks like there have been some other updates in this area? Can I get
 one of you to build a patch on master?

Sorry, my master branch was a couple of weeks old. Rebased.


 hw/xwayland/xwayland-cursor.c | 26 ++
 hw/xwayland/xwayland-input.c  |  2 ++
 hw/xwayland/xwayland.h|  4 +++-
 3 files changed, 31 insertions(+), 1 deletion(-)

diff --git a/hw/xwayland/xwayland-cursor.c b/hw/xwayland/xwayland-cursor.c
index 5a9d1fe..c137e1e 100644
--- a/hw/xwayland/xwayland-cursor.c
+++ b/hw/xwayland/xwayland-cursor.c
@@ -82,6 +82,23 @@ xwl_unrealize_cursor(DeviceIntPtr device, ScreenPtr screen, 
CursorPtr cursor)
 return xwl_shm_destroy_pixmap(pixmap);
 }
 
+static void
+frame_callback(void *data,
+   struct wl_callback *callback,
+   uint32_t time)
+{
+struct xwl_seat *xwl_seat = data;
+xwl_seat-cursor_frame_cb = NULL;
+if (xwl_seat-cursor_needs_update) {
+xwl_seat-cursor_needs_update = FALSE;
+xwl_seat_set_cursor(xwl_seat);
+}
+}
+
+static const struct wl_callback_listener frame_listener = {
+frame_callback
+};
+
 void
 xwl_seat_set_cursor(struct xwl_seat *xwl_seat)
 {
@@ -98,6 +115,11 @@ xwl_seat_set_cursor(struct xwl_seat *xwl_seat)
 return;
 }
 
+if (xwl_seat-cursor_frame_cb) {
+xwl_seat-cursor_needs_update = TRUE;
+return;
+}
+
 cursor = xwl_seat-x_cursor;
 pixmap = dixGetPrivate(cursor-devPrivates, xwl_cursor_private_key);
 stride = cursor-bits-width * 4;
@@ -117,6 +139,10 @@ xwl_seat_set_cursor(struct xwl_seat *xwl_seat)
 wl_surface_damage(xwl_seat-cursor, 0, 0,
   xwl_seat-x_cursor-bits-width,
   xwl_seat-x_cursor-bits-height);
+
+xwl_seat-cursor_frame_cb = wl_surface_frame(xwl_seat-cursor);
+wl_callback_add_listener(xwl_seat-cursor_frame_cb, frame_listener, 
xwl_seat);
+
 wl_surface_commit(xwl_seat-cursor);
 }
 
diff --git a/hw/xwayland/xwayland-input.c b/hw/xwayland/xwayland-input.c
index 51a3379..af11c5b 100644
--- a/hw/xwayland/xwayland-input.c
+++ b/hw/xwayland/xwayland-input.c
@@ -559,6 +559,8 @@ xwl_seat_destroy(struct xwl_seat *xwl_seat)
 RemoveDevice(xwl_seat-keyboard, FALSE);
 wl_seat_destroy(xwl_seat-seat);
 wl_surface_destroy(xwl_seat-cursor);
+if (xwl_seat-cursor_frame_cb)
+wl_callback_destroy(xwl_seat-cursor_frame_cb);
 wl_array_release(xwl_seat-keys);
 free(xwl_seat);
 }
diff --git a/hw/xwayland/xwayland.h b/hw/xwayland/xwayland.h
index cfb343d..28b0c99 100644
--- a/hw/xwayland/xwayland.h
+++ b/hw/xwayland/xwayland.h
@@ -115,12 +115,14 @@ struct xwl_seat {
 struct wl_pointer *wl_pointer;
 struct wl_keyboard *wl_keyboard;
 struct wl_array keys;
-struct wl_surface *cursor;
 struct xwl_window *focus_window;
 uint32_t id;
 uint32_t pointer_enter_serial;
 struct xorg_list link;
 CursorPtr x_cursor;
+struct wl_surface *cursor;
+struct wl_callback *cursor_frame_cb;
+Bool cursor_needs_update;
 
 size_t keymap_size;
 char *keymap;
-- 
2.4.0

___
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/wayland-devel


[PATCH] xwayland: Throttle our cursor surface updates with a frame callback

2015-05-26 Thread Rui Matos
In some extreme cases with animated cursors at a high frame rate we
could end up filling the wl_display outgoing buffer and end up with
wl_display_flush() failing.

In any case, using the frame callback to throttle ourselves is the
right thing to do.

Signed-off-by: Rui Matos tiagoma...@gmail.com
---

v2: ensure that we don't lose cursor updates requested while a frame
callback is pending

 hw/xwayland/xwayland-cursor.c | 26 ++
 hw/xwayland/xwayland-input.c  |  2 ++
 hw/xwayland/xwayland.h|  4 +++-
 3 files changed, 31 insertions(+), 1 deletion(-)

diff --git a/hw/xwayland/xwayland-cursor.c b/hw/xwayland/xwayland-cursor.c
index 5a9d1fe..c137e1e 100644
--- a/hw/xwayland/xwayland-cursor.c
+++ b/hw/xwayland/xwayland-cursor.c
@@ -82,6 +82,23 @@ xwl_unrealize_cursor(DeviceIntPtr device, ScreenPtr screen, 
CursorPtr cursor)
 return xwl_shm_destroy_pixmap(pixmap);
 }
 
+static void
+frame_callback(void *data,
+   struct wl_callback *callback,
+   uint32_t time)
+{
+struct xwl_seat *xwl_seat = data;
+xwl_seat-cursor_frame_cb = NULL;
+if (xwl_seat-cursor_needs_update) {
+xwl_seat-cursor_needs_update = FALSE;
+xwl_seat_set_cursor(xwl_seat);
+}
+}
+
+static const struct wl_callback_listener frame_listener = {
+frame_callback
+};
+
 void
 xwl_seat_set_cursor(struct xwl_seat *xwl_seat)
 {
@@ -98,6 +115,11 @@ xwl_seat_set_cursor(struct xwl_seat *xwl_seat)
 return;
 }
 
+if (xwl_seat-cursor_frame_cb) {
+xwl_seat-cursor_needs_update = TRUE;
+return;
+}
+
 cursor = xwl_seat-x_cursor;
 pixmap = dixGetPrivate(cursor-devPrivates, xwl_cursor_private_key);
 stride = cursor-bits-width * 4;
@@ -117,6 +139,10 @@ xwl_seat_set_cursor(struct xwl_seat *xwl_seat)
 wl_surface_damage(xwl_seat-cursor, 0, 0,
   xwl_seat-x_cursor-bits-width,
   xwl_seat-x_cursor-bits-height);
+
+xwl_seat-cursor_frame_cb = wl_surface_frame(xwl_seat-cursor);
+wl_callback_add_listener(xwl_seat-cursor_frame_cb, frame_listener, 
xwl_seat);
+
 wl_surface_commit(xwl_seat-cursor);
 }
 
diff --git a/hw/xwayland/xwayland-input.c b/hw/xwayland/xwayland-input.c
index 5230d8c..a3142f4 100644
--- a/hw/xwayland/xwayland-input.c
+++ b/hw/xwayland/xwayland-input.c
@@ -586,6 +586,8 @@ xwl_seat_destroy(struct xwl_seat *xwl_seat)
 RemoveDevice(xwl_seat-keyboard, FALSE);
 wl_seat_destroy(xwl_seat-seat);
 wl_surface_destroy(xwl_seat-cursor);
+if (xwl_seat-cursor_frame_cb)
+wl_callback_destroy(xwl_seat-cursor_frame_cb);
 wl_array_release(xwl_seat-keys);
 free(xwl_seat);
 }
diff --git a/hw/xwayland/xwayland.h b/hw/xwayland/xwayland.h
index bfffa71..a31c040 100644
--- a/hw/xwayland/xwayland.h
+++ b/hw/xwayland/xwayland.h
@@ -115,12 +115,14 @@ struct xwl_seat {
 struct wl_pointer *wl_pointer;
 struct wl_keyboard *wl_keyboard;
 struct wl_array keys;
-struct wl_surface *cursor;
 struct xwl_window *focus_window;
 uint32_t id;
 uint32_t pointer_enter_serial;
 struct xorg_list link;
 CursorPtr x_cursor;
+struct wl_surface *cursor;
+struct wl_callback *cursor_frame_cb;
+Bool cursor_needs_update;
 
 wl_fixed_t horizontal_scroll;
 wl_fixed_t vertical_scroll;
-- 
2.4.0

___
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/wayland-devel


[PATCH xwayland] xwayland: Throttle our cursor surface updates with a frame callback

2015-05-25 Thread Rui Matos
In some extreme cases with animated cursors at a high frame rate we
could end up filling the wl_display outgoing buffer and end up with
wl_display_flush() failing.

In any case, using the frame callback to throttle ourselves is the
right thing to do.

Signed-off-by: Rui Matos tiagoma...@gmail.com
---
 hw/xwayland/xwayland-cursor.c | 20 
 hw/xwayland/xwayland-input.c  |  2 ++
 hw/xwayland/xwayland.h|  1 +
 3 files changed, 23 insertions(+)

diff --git a/hw/xwayland/xwayland-cursor.c b/hw/xwayland/xwayland-cursor.c
index 5a9d1fe..3ba5ad6 100644
--- a/hw/xwayland/xwayland-cursor.c
+++ b/hw/xwayland/xwayland-cursor.c
@@ -82,6 +82,19 @@ xwl_unrealize_cursor(DeviceIntPtr device, ScreenPtr screen, 
CursorPtr cursor)
 return xwl_shm_destroy_pixmap(pixmap);
 }
 
+static void
+frame_callback(void *data,
+   struct wl_callback *callback,
+   uint32_t time)
+{
+struct xwl_seat *xwl_seat = data;
+xwl_seat-cursor_frame_cb = NULL;
+}
+
+static const struct wl_callback_listener frame_listener = {
+frame_callback
+};
+
 void
 xwl_seat_set_cursor(struct xwl_seat *xwl_seat)
 {
@@ -98,6 +111,9 @@ xwl_seat_set_cursor(struct xwl_seat *xwl_seat)
 return;
 }
 
+if (xwl_seat-cursor_frame_cb)
+return;
+
 cursor = xwl_seat-x_cursor;
 pixmap = dixGetPrivate(cursor-devPrivates, xwl_cursor_private_key);
 stride = cursor-bits-width * 4;
@@ -117,6 +133,10 @@ xwl_seat_set_cursor(struct xwl_seat *xwl_seat)
 wl_surface_damage(xwl_seat-cursor, 0, 0,
   xwl_seat-x_cursor-bits-width,
   xwl_seat-x_cursor-bits-height);
+
+xwl_seat-cursor_frame_cb = wl_surface_frame(xwl_seat-cursor);
+wl_callback_add_listener(xwl_seat-cursor_frame_cb, frame_listener, 
xwl_seat);
+
 wl_surface_commit(xwl_seat-cursor);
 }
 
diff --git a/hw/xwayland/xwayland-input.c b/hw/xwayland/xwayland-input.c
index 5230d8c..a3142f4 100644
--- a/hw/xwayland/xwayland-input.c
+++ b/hw/xwayland/xwayland-input.c
@@ -586,6 +586,8 @@ xwl_seat_destroy(struct xwl_seat *xwl_seat)
 RemoveDevice(xwl_seat-keyboard, FALSE);
 wl_seat_destroy(xwl_seat-seat);
 wl_surface_destroy(xwl_seat-cursor);
+if (xwl_seat-cursor_frame_cb)
+wl_callback_destroy(xwl_seat-cursor_frame_cb);
 wl_array_release(xwl_seat-keys);
 free(xwl_seat);
 }
diff --git a/hw/xwayland/xwayland.h b/hw/xwayland/xwayland.h
index bfffa71..92d6d6e 100644
--- a/hw/xwayland/xwayland.h
+++ b/hw/xwayland/xwayland.h
@@ -116,6 +116,7 @@ struct xwl_seat {
 struct wl_keyboard *wl_keyboard;
 struct wl_array keys;
 struct wl_surface *cursor;
+struct wl_callback *cursor_frame_cb;
 struct xwl_window *focus_window;
 uint32_t id;
 uint32_t pointer_enter_serial;
-- 
2.4.0

___
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/wayland-devel


[PATCH] touchpad: Make sure we don't underflow tap_finger_count

2015-04-29 Thread Rui Matos
If a touch begins before tap gets enabled we underflow
tap_finger_count when the touch ends.

This happens in practice when enabling tapping on a GUI with a
touchpad click.

Signed-off-by: Rui Matos tiagoma...@gmail.com
---

This patch seems enough to fix the issue in my testing but I'm not
familiar with the state machine so it might not be the best solution.


 src/evdev-mt-touchpad-tap.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/src/evdev-mt-touchpad-tap.c b/src/evdev-mt-touchpad-tap.c
index 0f25e26..0feff70 100644
--- a/src/evdev-mt-touchpad-tap.c
+++ b/src/evdev-mt-touchpad-tap.c
@@ -659,7 +659,8 @@ tp_tap_handle_state(struct tp_dispatch *tp, uint64_t time)
tp_tap_handle_event(tp, t, TAP_EVENT_MOTION, 
time);
 
} else if (t-state == TOUCH_END) {
-   tp-tap.tap_finger_count--;
+   if (tp-tap.tap_finger_count  0)
+   tp-tap.tap_finger_count--;
tp_tap_handle_event(tp, t, TAP_EVENT_RELEASE, time);
t-tap.state = TAP_TOUCH_STATE_IDLE;
} else if (tp-tap.state != TAP_STATE_IDLE 
-- 
2.3.6

___
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/wayland-devel


[PATCH] doc/publican/Makefile.am: Add a missing order-only prerequisite

2015-01-06 Thread Rui Matos
Otherwise a parallel make invocation could fail due to the directory
not existing.

Signed-off-by: Rui Matos tiagoma...@gmail.com
---
 doc/publican/Makefile.am | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/doc/publican/Makefile.am b/doc/publican/Makefile.am
index 278da12..50a6188 100644
--- a/doc/publican/Makefile.am
+++ b/doc/publican/Makefile.am
@@ -85,7 +85,7 @@ $(builddir)/en-US/ProtocolSpec.xml: 
$(top_srcdir)/protocol/wayland.xml $(srcdir)
$(AM_V_GEN)$(XSLTPROC) $(srcdir)/protocol-to-docbook.xsl \
$(top_srcdir)/protocol/wayland.xml  $@
 
-$(builddir)/en-US/ProtocolInterfaces.xml: $(top_srcdir)/protocol/wayland.xml 
$(srcdir)/protocol-interfaces-to-docbook.xsl
+$(builddir)/en-US/ProtocolInterfaces.xml: $(top_srcdir)/protocol/wayland.xml 
$(srcdir)/protocol-interfaces-to-docbook.xsl | $(builddir)/en-US
$(AM_V_GEN)$(XSLTPROC) $(srcdir)/protocol-interfaces-to-docbook.xsl \
$(top_srcdir)/protocol/wayland.xml  $@
 
-- 
2.1.0

___
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/wayland-devel


[PATCH] protocol: Document how clients are supposed to get the xkb keycode

2014-03-25 Thread Rui Matos
This encodes what everyone is doing and avoids other implementers
having to guess.
---

Jasper suggested that it would be nice if the compositor sent keycodes
that clients could use directly as an index in the keymap. I suppose
we can't do that at this point so we should at least document it
clearly in the protocol so that implementers don't have to guess.


 protocol/wayland.xml | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/protocol/wayland.xml b/protocol/wayland.xml
index 3aa89af..db1b349 100644
--- a/protocol/wayland.xml
+++ b/protocol/wayland.xml
@@ -1503,7 +1503,8 @@
   /description
   entry name=no_keymap value=0
 summary=no keymap; client must understand how to interpret the 
raw keycode/
-  entry name=xkb_v1 value=1 summary=libxkbcommon compatible/
+  entry name=xkb_v1 value=1
+ summary=libxkbcommon compatible; to determine the xkb keycode, 
clients must add 8 to the key event keycode/
 /enum
 
 event name=keymap
-- 
1.9.0

___
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/wayland-devel


[PATCH] xwayland: Destroy wl_buffers only after they are released

2014-02-20 Thread Rui Matos
Destroying a wl_buffer that is still attached to a wl_surface is
undefined behavior according to the wayland protocol. We should delay
the destruction until we get the release event.

To achieve this we need to track ownership of wl_buffers, both our own
and the compositor's which occurs from either the first commit request
or the first commit request after a release event until the next
release event.
---

On 12 February 2014 08:54, Pekka Paalanen ppaala...@gmail.com wrote:
 I assume the code never added a wl_buffer listener before, because if
 it did, this patch would be a no-op. wl_buffer_add_listener is a
 misnomer, there can only ever be one listener, and trying to add
 another will not actually do anything.

Thanks for the headsup. But, indeed, there was nothing adding a
wl_buffer listener before.

 Also, you rely on wl_buffer.release not having arrived before you add
 the listener. With weston's gl-renderer, the release comes very soon
 after each wl_surface.commit for wl_shm buffers. Maybe it works, maybe
 it doesn't, but it seems very fragile. Did you check you don't leak
 wl_buffers now?

Right, I was leaking in some cases. So, I came up with the solution
below which, if I'm reading the logs correctly, doesn't leak and works
correctly.

This solution abuses the user_data field to essentially keep two
toggle references, our own and the compositor's, and only destroys the
wl_buffer when both are dropped.

Thanks,
Rui

---
 hw/xfree86/xwayland/xwayland-cursor.c  |  4 ++-
 hw/xfree86/xwayland/xwayland-private.h |  4 +++
 hw/xfree86/xwayland/xwayland-window.c  |  8 +++---
 hw/xfree86/xwayland/xwayland.c | 50 ++
 4 files changed, 61 insertions(+), 5 deletions(-)

diff --git a/hw/xfree86/xwayland/xwayland-cursor.c 
b/hw/xfree86/xwayland/xwayland-cursor.c
index 2b3cb5e..232b038 100644
--- a/hw/xfree86/xwayland/xwayland-cursor.c
+++ b/hw/xfree86/xwayland/xwayland-cursor.c
@@ -125,6 +125,7 @@ xwl_realize_cursor(DeviceIntPtr device, ScreenPtr screen, 
CursorPtr cursor)
  cursor-bits-width, cursor-bits-height,
  cursor-bits-width * 4,
  WL_SHM_FORMAT_ARGB);
+_buffer_init(buffer);
 wl_shm_pool_destroy(pool);
 
 dixSetPrivate(cursor-devPrivates,
@@ -143,7 +144,7 @@ xwl_unrealize_cursor(DeviceIntPtr device,
 xwl_screen = xwl_screen_get(screen);
 buffer = dixGetPrivate(cursor-devPrivates,
xwl_screen-cursor_private_key);
-wl_buffer_destroy(buffer);
+_buffer_disown(buffer);
 
 return TRUE;
 }
@@ -176,6 +177,7 @@ xwl_seat_set_cursor(struct xwl_seat *xwl_seat)
  xwl_seat-x_cursor-bits-width,
  xwl_seat-x_cursor-bits-height);
 wl_surface_commit(xwl_seat-cursor);
+_buffer_commited(buffer);
 }
 
 static void
diff --git a/hw/xfree86/xwayland/xwayland-private.h 
b/hw/xfree86/xwayland/xwayland-private.h
index bdecf8a..41e7e13 100644
--- a/hw/xfree86/xwayland/xwayland-private.h
+++ b/hw/xfree86/xwayland/xwayland-private.h
@@ -137,4 +137,8 @@ void xwl_output_remove(struct xwl_output *output);
 
 extern const struct xserver_listener xwl_server_listener;
 
+void _buffer_commited(struct wl_buffer *buffer);
+void _buffer_disown(struct wl_buffer *buffer);
+void _buffer_init(struct wl_buffer *buffer);
+
 #endif /* _XWAYLAND_PRIVATE_H_ */
diff --git a/hw/xfree86/xwayland/xwayland-window.c 
b/hw/xfree86/xwayland/xwayland-window.c
index a2a8206..d18c7f6 100644
--- a/hw/xfree86/xwayland/xwayland-window.c
+++ b/hw/xfree86/xwayland/xwayland-window.c
@@ -62,10 +62,8 @@ xwl_window_attach(struct xwl_window *xwl_window, PixmapPtr 
pixmap)
 struct xwl_screen *xwl_screen = xwl_window-xwl_screen;
 struct wl_callback *callback;
 
-/* We can safely destroy the buffer because we only use one buffer
- * per surface in xwayland model */
 if (xwl_window-buffer)
-wl_buffer_destroy(xwl_window-buffer);
+_buffer_disown(xwl_window-buffer);
 
 xwl_screen-driver-create_window_buffer(xwl_window, pixmap);
 
@@ -74,6 +72,8 @@ xwl_window_attach(struct xwl_window *xwl_window, PixmapPtr 
pixmap)
return;
 }
 
+_buffer_init(xwl_window-buffer);
+
 wl_surface_attach(xwl_window-surface, xwl_window-buffer, 0, 0);
 wl_surface_damage(xwl_window-surface, 0, 0,
  pixmap-drawable.width,
@@ -185,7 +185,7 @@ xwl_unrealize_window(WindowPtr window)
return ret;
 
 if (xwl_window-buffer)
-   wl_buffer_destroy(xwl_window-buffer);
+_buffer_disown(xwl_window-buffer);
 wl_surface_destroy(xwl_window-surface);
 xorg_list_del(xwl_window-link);
 if (RegionNotEmpty(DamageRegion(xwl_window-damage)))
diff --git a/hw/xfree86/xwayland/xwayland.c b/hw/xfree86/xwayland/xwayland.c
index c70a52d..c373fcc 100644
--- a/hw/xfree86/xwayland/xwayland.c
+++ b/hw/xfree86/xwayland/xwayland.c
@@ -72,6 +72,55 @@ const struct xserver_listener 

[PATCH] xwayland: Destroy wl_buffers only after they are released

2014-02-11 Thread Rui Matos
Destroying a wl_buffer that is still attached to a wl_surface is
undefined behavior according to the wayland protocol. We should delay
the destruction until we get the release event.
---

So, I'm not sure why there was this comment saying that it was safe to
do this, perhaps it was in an old protocol version?

In any case, this has been making xwayland crash under mutter ever
since this mutter commit
https://git.gnome.org/browse/mutter/commit/?h=waylandid=3e98ffaf9958366b584b360ac12bbc03cd070c07
 .

 hw/xfree86/xwayland/xwayland-window.c | 16 
 1 file changed, 12 insertions(+), 4 deletions(-)

diff --git a/hw/xfree86/xwayland/xwayland-window.c 
b/hw/xfree86/xwayland/xwayland-window.c
index a2a8206..a005cc6 100644
--- a/hw/xfree86/xwayland/xwayland-window.c
+++ b/hw/xfree86/xwayland/xwayland-window.c
@@ -43,6 +43,16 @@
 static DevPrivateKeyRec xwl_window_private_key;
 
 static void
+free_buffer(void *data, struct wl_buffer *buffer)
+{
+wl_buffer_destroy(buffer);
+}
+
+static const struct wl_buffer_listener buffer_listener = {
+free_buffer,
+};
+
+static void
 free_pixmap(void *data, struct wl_callback *callback, uint32_t time)
 {
 PixmapPtr pixmap = data;
@@ -62,10 +72,8 @@ xwl_window_attach(struct xwl_window *xwl_window, PixmapPtr 
pixmap)
 struct xwl_screen *xwl_screen = xwl_window-xwl_screen;
 struct wl_callback *callback;
 
-/* We can safely destroy the buffer because we only use one buffer
- * per surface in xwayland model */
 if (xwl_window-buffer)
-wl_buffer_destroy(xwl_window-buffer);
+wl_buffer_add_listener(xwl_window-buffer, buffer_listener, NULL);
 
 xwl_screen-driver-create_window_buffer(xwl_window, pixmap);
 
@@ -185,7 +193,7 @@ xwl_unrealize_window(WindowPtr window)
return ret;
 
 if (xwl_window-buffer)
-   wl_buffer_destroy(xwl_window-buffer);
+wl_buffer_add_listener(xwl_window-buffer, buffer_listener, NULL);
 wl_surface_destroy(xwl_window-surface);
 xorg_list_del(xwl_window-link);
 if (RegionNotEmpty(DamageRegion(xwl_window-damage)))
-- 
1.8.3.1

___
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/wayland-devel


[PATCH] input: Don't leak the initial keymap

2013-10-24 Thread Rui Matos
weston_xkb_info_create() takes ownership of the xkb_keymap instance so
we should drop our reference or we would leak it later if the keymap
was changed.
---
 src/input.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/input.c b/src/input.c
index 2fed718..da89b47 100644
--- a/src/input.c
+++ b/src/input.c
@@ -1706,6 +1706,7 @@ weston_compositor_build_global_keymap(struct 
weston_compositor *ec)
}
 
ec-xkb_info = weston_xkb_info_create(keymap);
+   xkb_keymap_unref(keymap);
if (ec-xkb_info == NULL)
return -1;
 
-- 
1.8.3.1

___
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/wayland-devel


[PATCH v2 1/3] xkb: Repurpose XkbCopyDeviceKeymap to apply a given keymap to a device

2013-10-22 Thread Rui Matos
This will also make it useful for cases when we have a new keymap to
apply to a device but don't have a source device.
---

On 21 October 2013 19:04, Daniel Stone dan...@fooishbar.org wrote:
 CopyKeyClass is only called when device-key is set.

True, amended.

 But for the rest:
 Reviewed-by: Daniel Stone dan...@fooishbar.org

Thanks for the reviews.

Rui

 Xi/exevents.c|  2 +-
 include/xkbsrv.h |  4 ++--
 xkb/xkb.c|  2 +-
 xkb/xkbUtils.c   | 14 +++---
 4 files changed, 11 insertions(+), 11 deletions(-)

diff --git a/Xi/exevents.c b/Xi/exevents.c
index f510a9e..5b6d370 100644
--- a/Xi/exevents.c
+++ b/Xi/exevents.c
@@ -230,7 +230,7 @@ CopyKeyClass(DeviceIntPtr device, DeviceIntPtr master)
 
 mk-sourceid = device-id;
 
-if (!XkbCopyDeviceKeymap(master, device))
+if (!XkbDeviceApplyKeymap(master, device-key-xkbInfo-desc))
 FatalError(Couldn't pivot keymap from device to core!\n);
 }
 
diff --git a/include/xkbsrv.h b/include/xkbsrv.h
index bef98ef..83ee1d0 100644
--- a/include/xkbsrv.h
+++ b/include/xkbsrv.h
@@ -812,8 +812,8 @@ extern _X_EXPORT void XkbSendNewKeyboardNotify(DeviceIntPtr 
/* kbd */ ,
 extern Bool XkbCopyKeymap(XkbDescPtr /* dst */ ,
   XkbDescPtr /* src */ );
 
-extern _X_EXPORT Bool XkbCopyDeviceKeymap(DeviceIntPtr /* dst */ ,
-  DeviceIntPtr /* src */ );
+extern _X_EXPORT Bool XkbDeviceApplyKeymap(DeviceIntPtr /* dst */ ,
+   XkbDescPtr /* src */ );
 
 extern void XkbFilterEvents(ClientPtr /* pClient */ ,
 int /* nEvents */ ,
diff --git a/xkb/xkb.c b/xkb/xkb.c
index c78aceb..7a631b8 100644
--- a/xkb/xkb.c
+++ b/xkb/xkb.c
@@ -5991,7 +5991,7 @@ ProcXkbGetKbdByName(ClientPtr client)
 continue;
 
 if (tmpd != dev)
-XkbCopyDeviceKeymap(tmpd, dev);
+XkbDeviceApplyKeymap(tmpd, xkb);
 
 if (tmpd-kbdfeed  tmpd-kbdfeed-xkb_sli) {
 old_sli = tmpd-kbdfeed-xkb_sli;
diff --git a/xkb/xkbUtils.c b/xkb/xkbUtils.c
index 6c6af60..1f8a839 100644
--- a/xkb/xkbUtils.c
+++ b/xkb/xkbUtils.c
@@ -1999,28 +1999,28 @@ XkbCopyKeymap(XkbDescPtr dst, XkbDescPtr src)
 }
 
 Bool
-XkbCopyDeviceKeymap(DeviceIntPtr dst, DeviceIntPtr src)
+XkbDeviceApplyKeymap(DeviceIntPtr dst, XkbDescPtr desc)
 {
 xkbNewKeyboardNotify nkn;
 Bool ret;
 
-if (!dst-key || !src-key)
+if (!dst-key || !desc)
 return FALSE;
 
 memset(nkn, 0, sizeof(xkbNewKeyboardNotify));
 nkn.oldMinKeyCode = dst-key-xkbInfo-desc-min_key_code;
 nkn.oldMaxKeyCode = dst-key-xkbInfo-desc-max_key_code;
 nkn.deviceID = dst-id;
-nkn.oldDeviceID = dst-id;  /* maybe src-id? */
-nkn.minKeyCode = src-key-xkbInfo-desc-min_key_code;
-nkn.maxKeyCode = src-key-xkbInfo-desc-max_key_code;
+nkn.oldDeviceID = dst-id;
+nkn.minKeyCode = desc-min_key_code;
+nkn.maxKeyCode = desc-max_key_code;
 nkn.requestMajor = XkbReqCode;
 nkn.requestMinor = X_kbSetMap;  /* Near enough's good enough. */
 nkn.changed = XkbNKN_KeycodesMask;
-if (src-key-xkbInfo-desc-geom)
+if (desc-geom)
 nkn.changed |= XkbNKN_GeometryMask;
 
-ret = XkbCopyKeymap(dst-key-xkbInfo-desc, src-key-xkbInfo-desc);
+ret = XkbCopyKeymap(dst-key-xkbInfo-desc, desc);
 if (ret)
 XkbSendNewKeyboardNotify(dst, nkn);
 
-- 
1.8.3.1

___
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/wayland-devel


[PATCH xwayland] Handle wayland keymap events

2013-10-21 Thread Rui Matos
These patches add support for changing the X keymap on wayland keymap
events.

I wonder what we should do for X client requests to change the keymap
though. We could:

a) somehow try to change the wayland keymap accordingly, possibly
   through some private compositor protocol;

b) ignore such requests, which seems legal according to both the core
   X protocol and XKB;

c) keep the current status quo, i.e. if an X client changes the keymap
   we have a different keymap for X clients and wayland clients until
   the next time the wayland keymap is updated.

Rui

___
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/wayland-devel


[PATCH 1/3] xkb: Repurpose XkbCopyDeviceKeymap to apply a given keymap to a device

2013-10-21 Thread Rui Matos
This will also make it useful for cases when we have a new keymap to
apply to a device but don't have a source device.
---
 Xi/exevents.c|  2 +-
 include/xkbsrv.h |  4 ++--
 xkb/xkb.c|  2 +-
 xkb/xkbUtils.c   | 14 +++---
 4 files changed, 11 insertions(+), 11 deletions(-)

diff --git a/Xi/exevents.c b/Xi/exevents.c
index f510a9e..8aec526 100644
--- a/Xi/exevents.c
+++ b/Xi/exevents.c
@@ -230,7 +230,7 @@ CopyKeyClass(DeviceIntPtr device, DeviceIntPtr master)
 
 mk-sourceid = device-id;
 
-if (!XkbCopyDeviceKeymap(master, device))
+if (device-key  !XkbDeviceApplyKeymap(master, 
device-key-xkbInfo-desc))
 FatalError(Couldn't pivot keymap from device to core!\n);
 }
 
diff --git a/include/xkbsrv.h b/include/xkbsrv.h
index bef98ef..83ee1d0 100644
--- a/include/xkbsrv.h
+++ b/include/xkbsrv.h
@@ -812,8 +812,8 @@ extern _X_EXPORT void XkbSendNewKeyboardNotify(DeviceIntPtr 
/* kbd */ ,
 extern Bool XkbCopyKeymap(XkbDescPtr /* dst */ ,
   XkbDescPtr /* src */ );
 
-extern _X_EXPORT Bool XkbCopyDeviceKeymap(DeviceIntPtr /* dst */ ,
-  DeviceIntPtr /* src */ );
+extern _X_EXPORT Bool XkbDeviceApplyKeymap(DeviceIntPtr /* dst */ ,
+   XkbDescPtr /* src */ );
 
 extern void XkbFilterEvents(ClientPtr /* pClient */ ,
 int /* nEvents */ ,
diff --git a/xkb/xkb.c b/xkb/xkb.c
index c78aceb..7a631b8 100644
--- a/xkb/xkb.c
+++ b/xkb/xkb.c
@@ -5991,7 +5991,7 @@ ProcXkbGetKbdByName(ClientPtr client)
 continue;
 
 if (tmpd != dev)
-XkbCopyDeviceKeymap(tmpd, dev);
+XkbDeviceApplyKeymap(tmpd, xkb);
 
 if (tmpd-kbdfeed  tmpd-kbdfeed-xkb_sli) {
 old_sli = tmpd-kbdfeed-xkb_sli;
diff --git a/xkb/xkbUtils.c b/xkb/xkbUtils.c
index 6c6af60..1f8a839 100644
--- a/xkb/xkbUtils.c
+++ b/xkb/xkbUtils.c
@@ -1999,28 +1999,28 @@ XkbCopyKeymap(XkbDescPtr dst, XkbDescPtr src)
 }
 
 Bool
-XkbCopyDeviceKeymap(DeviceIntPtr dst, DeviceIntPtr src)
+XkbDeviceApplyKeymap(DeviceIntPtr dst, XkbDescPtr desc)
 {
 xkbNewKeyboardNotify nkn;
 Bool ret;
 
-if (!dst-key || !src-key)
+if (!dst-key || !desc)
 return FALSE;
 
 memset(nkn, 0, sizeof(xkbNewKeyboardNotify));
 nkn.oldMinKeyCode = dst-key-xkbInfo-desc-min_key_code;
 nkn.oldMaxKeyCode = dst-key-xkbInfo-desc-max_key_code;
 nkn.deviceID = dst-id;
-nkn.oldDeviceID = dst-id;  /* maybe src-id? */
-nkn.minKeyCode = src-key-xkbInfo-desc-min_key_code;
-nkn.maxKeyCode = src-key-xkbInfo-desc-max_key_code;
+nkn.oldDeviceID = dst-id;
+nkn.minKeyCode = desc-min_key_code;
+nkn.maxKeyCode = desc-max_key_code;
 nkn.requestMajor = XkbReqCode;
 nkn.requestMinor = X_kbSetMap;  /* Near enough's good enough. */
 nkn.changed = XkbNKN_KeycodesMask;
-if (src-key-xkbInfo-desc-geom)
+if (desc-geom)
 nkn.changed |= XkbNKN_GeometryMask;
 
-ret = XkbCopyKeymap(dst-key-xkbInfo-desc, src-key-xkbInfo-desc);
+ret = XkbCopyKeymap(dst-key-xkbInfo-desc, desc);
 if (ret)
 XkbSendNewKeyboardNotify(dst, nkn);
 
-- 
1.8.3.1

___
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/wayland-devel


[PATCH 2/3] xkb: Factor out a function to copy a keymap's controls unto another

2013-10-21 Thread Rui Matos
---
 include/xkbsrv.h |  3 +++
 xkb/xkb.c| 14 +-
 xkb/xkbUtils.c   | 23 +++
 3 files changed, 27 insertions(+), 13 deletions(-)

diff --git a/include/xkbsrv.h b/include/xkbsrv.h
index 83ee1d0..6a2e96e 100644
--- a/include/xkbsrv.h
+++ b/include/xkbsrv.h
@@ -829,6 +829,9 @@ extern void XkbFakeDeviceButton(DeviceIntPtr /* dev */ ,
 int /* press */ ,
 int /* button */ );
 
+extern _X_EXPORT void XkbCopyControls(XkbDescPtr /* dst */ ,
+  XkbDescPtr /* src */ );
+
 #include xkbfile.h
 #include xkbrules.h
 
diff --git a/xkb/xkb.c b/xkb/xkb.c
index 7a631b8..6a68e81 100644
--- a/xkb/xkb.c
+++ b/xkb/xkb.c
@@ -5950,25 +5950,13 @@ ProcXkbGetKbdByName(ClientPtr client)
 if (rep.loaded) {
 XkbDescPtr old_xkb;
 xkbNewKeyboardNotify nkn;
-int i, nG, nTG;
 
 old_xkb = xkb;
 xkb = new;
 dev-key-xkbInfo-desc = xkb;
 new = old_xkb;  /* so it'll get freed automatically */
 
-*xkb-ctrls = *old_xkb-ctrls;
-for (nG = nTG = 0, i = xkb-min_key_code; i = xkb-max_key_code; i++) 
{
-nG = XkbKeyNumGroups(xkb, i);
-if (nG = XkbNumKbdGroups) {
-nTG = XkbNumKbdGroups;
-break;
-}
-if (nG  nTG) {
-nTG = nG;
-}
-}
-xkb-ctrls-num_groups = nTG;
+XkbCopyControls(xkb, old_xkb);
 
 nkn.deviceID = nkn.oldDeviceID = dev-id;
 nkn.minKeyCode = new-min_key_code;
diff --git a/xkb/xkbUtils.c b/xkb/xkbUtils.c
index 1f8a839..6cf6e79 100644
--- a/xkb/xkbUtils.c
+++ b/xkb/xkbUtils.c
@@ -2090,3 +2090,26 @@ XkbMergeLockedPtrBtns(DeviceIntPtr master)
 xkbi-lockedPtrButtons |= d-key-xkbInfo-lockedPtrButtons;
 }
 }
+
+void
+XkbCopyControls(XkbDescPtr dst, XkbDescPtr src)
+{
+int i, nG, nTG;
+
+if (!dst || !src)
+return;
+
+*dst-ctrls = *src-ctrls;
+
+for (nG = nTG = 0, i = dst-min_key_code; i = dst-max_key_code; i++) {
+nG = XkbKeyNumGroups(dst, i);
+if (nG = XkbNumKbdGroups) {
+nTG = XkbNumKbdGroups;
+break;
+}
+if (nG  nTG) {
+nTG = nG;
+}
+}
+dst-ctrls-num_groups = nTG;
+}
-- 
1.8.3.1

___
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/wayland-devel


[PATCH v2 1/4] input: Add core API to update the keymap

2013-10-10 Thread Rui Matos
How and when to update the keymap is left to each backend.

The new keymap only becomes effective when no keys are pressed and we
keep latched and locked modifiers from the previous state.

---
v2:
 - defer updating the keymap until no keys are pressed;

 - keep latched and locked modifiers state;

 - send the new keymap also to the focus_resource_list clients - not
   sure how I missed this in testing before;

 - send the new modifiers state to all keyboard clients if any bit is
   set since a new keymap means that they have to reset their state so
   we need to tell them if we are keeping some

 src/compositor.h |   3 ++
 src/input.c  | 109 +++
 2 files changed, 112 insertions(+)

diff --git a/src/compositor.h b/src/compositor.h
index a19d966..a4fedc3 100644
--- a/src/compositor.h
+++ b/src/compositor.h
@@ -486,6 +486,7 @@ struct weston_seat {
struct xkb_state *state;
enum weston_led leds;
} xkb_state;
+   struct xkb_keymap *pending_keymap;
 
struct input_method *input_method;
char *seat_name;
@@ -1115,6 +1116,8 @@ void
 weston_seat_init_touch(struct weston_seat *seat);
 void
 weston_seat_repick(struct weston_seat *seat);
+void
+weston_seat_update_keymap(struct weston_seat *seat, struct xkb_keymap *keymap);
 
 void
 weston_seat_release(struct weston_seat *seat);
diff --git a/src/input.c b/src/input.c
index 1313b52..539aba3 100644
--- a/src/input.c
+++ b/src/input.c
@@ -889,6 +889,86 @@ update_modifier_state(struct weston_seat *seat, uint32_t 
serial, uint32_t key,
 
notify_modifiers(seat, serial);
 }
+
+static void
+send_keymap(struct wl_resource *resource, struct weston_xkb_info *xkb_info)
+{
+   wl_keyboard_send_keymap(resource,
+   WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1,
+   xkb_info-keymap_fd,
+   xkb_info-keymap_size);
+}
+
+static void
+send_modifiers(struct wl_resource *resource, uint32_t serial, struct 
weston_keyboard *keyboard)
+{
+   wl_keyboard_send_modifiers(resource, serial,
+  keyboard-modifiers.mods_depressed,
+  keyboard-modifiers.mods_latched,
+  keyboard-modifiers.mods_locked,
+  keyboard-modifiers.group);
+}
+
+static struct weston_xkb_info *
+weston_xkb_info_create(struct xkb_keymap *keymap);
+static void
+weston_xkb_info_destroy(struct weston_xkb_info *xkb_info);
+
+static void
+update_keymap(struct weston_seat *seat)
+{
+   struct wl_resource *resource;
+   struct weston_xkb_info *xkb_info;
+   struct xkb_state *state;
+   xkb_mod_mask_t latched_mods;
+   xkb_mod_mask_t locked_mods;
+
+   xkb_info = weston_xkb_info_create(seat-pending_keymap);
+
+   xkb_keymap_unref(seat-pending_keymap);
+   seat-pending_keymap = NULL;
+
+   if (!xkb_info) {
+   weston_log(failed to create XKB info\n);
+   return;
+   }
+
+   state = xkb_state_new(xkb_info-keymap);
+   if (!state) {
+   weston_log(failed to initialise XKB state\n);
+   weston_xkb_info_destroy(xkb_info);
+   return;
+   }
+
+   latched_mods = xkb_state_serialize_mods(seat-xkb_state.state, 
XKB_STATE_MODS_LATCHED);
+   locked_mods = xkb_state_serialize_mods(seat-xkb_state.state, 
XKB_STATE_MODS_LOCKED);
+   xkb_state_update_mask(state,
+ 0, /* depressed */
+ latched_mods,
+ locked_mods,
+ 0, 0, 0);
+
+   weston_xkb_info_destroy(seat-xkb_info);
+   seat-xkb_info = xkb_info;
+
+   xkb_state_unref(seat-xkb_state.state);
+   seat-xkb_state.state = state;
+
+   wl_resource_for_each(resource, seat-keyboard-resource_list)
+   send_keymap(resource, xkb_info);
+   wl_resource_for_each(resource, seat-keyboard-focus_resource_list)
+   send_keymap(resource, xkb_info);
+
+   notify_modifiers(seat, 
wl_display_next_serial(seat-compositor-wl_display));
+
+   if (!latched_mods  !locked_mods)
+   return;
+
+   wl_resource_for_each(resource, seat-keyboard-resource_list)
+   send_modifiers(resource, 
wl_display_get_serial(seat-compositor-wl_display), seat-keyboard);
+   wl_resource_for_each(resource, seat-keyboard-focus_resource_list)
+   send_modifiers(resource, 
wl_display_get_serial(seat-compositor-wl_display), seat-keyboard);
+}
 #else
 WL_EXPORT void
 notify_modifiers(struct weston_seat *seat, uint32_t serial)
@@ -900,6 +980,11 @@ update_modifier_state(struct weston_seat *seat, uint32_t 
serial, uint32_t key,
  enum wl_keyboard_key_state state)
 {
 }
+
+static void
+update_keymap(struct weston_seat *seat)
+{
+}
 #endif
 
 WL_EXPORT void
@@ -950,6 +1035,10 @@ 

[PATCH v2 3/4] compositor-wayland: Handle keymap changes

2013-10-10 Thread Rui Matos
---
 src/compositor-wayland.c | 6 +-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/src/compositor-wayland.c b/src/compositor-wayland.c
index 77b2a2c..0fd7267 100644
--- a/src/compositor-wayland.c
+++ b/src/compositor-wayland.c
@@ -515,7 +515,11 @@ input_handle_keymap(void *data, struct wl_keyboard 
*keyboard, uint32_t format,
return;
}
 
-   weston_seat_init_keyboard(input-base, keymap);
+   if (input-base.keyboard)
+   weston_seat_update_keymap(input-base, keymap);
+   else
+   weston_seat_init_keyboard(input-base, keymap);
+
xkb_map_unref(keymap);
 }
 
-- 
1.8.3.1

___
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/wayland-devel


[PATCH v2 4/4] clients/window: Dispose of previous keymap and state on keymap change

2013-10-10 Thread Rui Matos
---
 clients/window.c | 24 +++-
 1 file changed, 15 insertions(+), 9 deletions(-)

diff --git a/clients/window.c b/clients/window.c
index 5b20da5..1f32c73 100644
--- a/clients/window.c
+++ b/clients/window.c
@@ -3037,6 +3037,8 @@ keyboard_handle_keymap(void *data, struct wl_keyboard 
*keyboard,
   uint32_t format, int fd, uint32_t size)
 {
struct input *input = data;
+   struct xkb_keymap *keymap;
+   struct xkb_state *state;
char *map_str;
 
if (!data) {
@@ -3055,26 +3057,30 @@ keyboard_handle_keymap(void *data, struct wl_keyboard 
*keyboard,
return;
}
 
-   input-xkb.keymap = xkb_map_new_from_string(input-display-xkb_context,
-   map_str,
-   XKB_KEYMAP_FORMAT_TEXT_V1,
-   0);
+   keymap = xkb_map_new_from_string(input-display-xkb_context,
+map_str,
+XKB_KEYMAP_FORMAT_TEXT_V1,
+0);
munmap(map_str, size);
close(fd);
 
-   if (!input-xkb.keymap) {
+   if (!keymap) {
fprintf(stderr, failed to compile keymap\n);
return;
}
 
-   input-xkb.state = xkb_state_new(input-xkb.keymap);
-   if (!input-xkb.state) {
+   state = xkb_state_new(keymap);
+   if (!state) {
fprintf(stderr, failed to create XKB state\n);
-   xkb_map_unref(input-xkb.keymap);
-   input-xkb.keymap = NULL;
+   xkb_map_unref(keymap);
return;
}
 
+   xkb_keymap_unref(input-xkb.keymap);
+   xkb_state_unref(input-xkb.state);
+   input-xkb.keymap = keymap;
+   input-xkb.state = state;
+
input-xkb.control_mask =
1  xkb_map_mod_get_index(input-xkb.keymap, Control);
input-xkb.alt_mask =
-- 
1.8.3.1

___
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/wayland-devel


[PATCH weston] Add a way to update the keymap

2013-10-07 Thread Rui Matos
We'll need something like this in mutter-wayland to allow people to
add/change their keyboard layouts with gnome-control-center so I
figured I'd start by implementing the basics in weston first.

There's an implementation for a couple of backends and a fix for the
client side which would leak on keymap events.

Comments welcome, especially about the state handling - right now I'm
just reseting the XKB state but I'm not sure this is the correct thing
to do.

Rui

___
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/wayland-devel


[PATCH 1/4] input: Add core API to update the keymap

2013-10-07 Thread Rui Matos
How and when to update the keymap is left to each backend.
---
 src/compositor.h |  2 ++
 src/input.c  | 38 ++
 2 files changed, 40 insertions(+)

diff --git a/src/compositor.h b/src/compositor.h
index a19d966..041758a 100644
--- a/src/compositor.h
+++ b/src/compositor.h
@@ -1115,6 +1115,8 @@ void
 weston_seat_init_touch(struct weston_seat *seat);
 void
 weston_seat_repick(struct weston_seat *seat);
+void
+weston_seat_update_keyboard(struct weston_seat *seat, struct xkb_keymap 
*keymap);
 
 void
 weston_seat_release(struct weston_seat *seat);
diff --git a/src/input.c b/src/input.c
index 1313b52..e769554 100644
--- a/src/input.c
+++ b/src/input.c
@@ -1623,6 +1623,44 @@ weston_compositor_xkb_destroy(struct weston_compositor 
*ec)
 }
 #endif
 
+WL_EXPORT void
+weston_seat_update_keyboard(struct weston_seat *seat, struct xkb_keymap 
*keymap)
+{
+   struct wl_resource *resource;
+
+   if (!seat-keyboard)
+   return;
+
+#ifdef ENABLE_XKBCOMMON
+   if (seat-compositor-use_xkbcommon) {
+   if (seat-xkb_info != NULL)
+   weston_xkb_info_destroy(seat-xkb_info);
+   seat-xkb_info = weston_xkb_info_create(keymap);
+   if (seat-xkb_info == NULL) {
+   weston_log(failed to create XKB info\n);
+   return;
+   }
+
+   if (seat-xkb_state.state != NULL)
+   xkb_state_unref(seat-xkb_state.state);
+   seat-xkb_state.state = xkb_state_new(seat-xkb_info-keymap);
+   if (seat-xkb_state.state == NULL) {
+   weston_log(failed to initialise XKB state\n);
+   return;
+   }
+
+   wl_resource_for_each(resource, seat-keyboard-resource_list) {
+   wl_keyboard_send_keymap(resource,
+   
WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1,
+   seat-xkb_info-keymap_fd,
+   seat-xkb_info-keymap_size);
+   }
+
+   notify_modifiers(seat, 
wl_display_next_serial(seat-compositor-wl_display));
+   }
+#endif
+}
+
 WL_EXPORT int
 weston_seat_init_keyboard(struct weston_seat *seat, struct xkb_keymap *keymap)
 {
-- 
1.8.3.1

___
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/wayland-devel


[PATCH 2/4] compositor-x11: Update keymap when XKB keymap changes

2013-10-07 Thread Rui Matos
---
 src/compositor-x11.c | 35 +--
 1 file changed, 29 insertions(+), 6 deletions(-)

diff --git a/src/compositor-x11.c b/src/compositor-x11.c
index 704e751..bdff323 100644
--- a/src/compositor-x11.c
+++ b/src/compositor-x11.c
@@ -201,6 +201,7 @@ x11_compositor_setup_xkb(struct x11_compositor *c)
xcb_xkb_per_client_flags_reply_t *pcf_reply;
xcb_xkb_get_state_cookie_t state;
xcb_xkb_get_state_reply_t *state_reply;
+   uint32_t values[1] = { XCB_EVENT_MASK_PROPERTY_CHANGE };
 
c-has_xkb = 0;
c-xkb_event_base = 0;
@@ -280,10 +281,24 @@ x11_compositor_setup_xkb(struct x11_compositor *c)
 
free(state_reply);
 
+   xcb_change_window_attributes(c-conn, c-screen-root,
+XCB_CW_EVENT_MASK, values);
+
c-has_xkb = 1;
 #endif
 }
 
+static void
+update_xkb_keymap(struct x11_compositor *c)
+{
+   struct xkb_keymap *keymap;
+
+   keymap = x11_compositor_get_keymap(c);
+   weston_seat_update_keyboard (c-core_seat, keymap);
+   if (keymap)
+   xkb_map_unref(keymap);
+}
+
 static int
 x11_input_create(struct x11_compositor *c, int no_input)
 {
@@ -1284,12 +1299,20 @@ x11_compositor_handle_event(int fd, uint32_t mask, void 
*data)
}
 
 #ifdef HAVE_XCB_XKB
-   if (c-has_xkb 
-   response_type == c-xkb_event_base) {
-   xcb_xkb_state_notify_event_t *state =
-   (xcb_xkb_state_notify_event_t *) event;
-   if (state-xkbType == XCB_XKB_STATE_NOTIFY)
-   update_xkb_state(c, state);
+   if (c-has_xkb) {
+   if (response_type == c-xkb_event_base) {
+   xcb_xkb_state_notify_event_t *state =
+   (xcb_xkb_state_notify_event_t *) event;
+   if (state-xkbType == XCB_XKB_STATE_NOTIFY)
+   update_xkb_state(c, state);
+   } else if (response_type == XCB_PROPERTY_NOTIFY) {
+   xcb_property_notify_event_t *prop_notify =
+   (xcb_property_notify_event_t *) event;
+   if (prop_notify-window == c-screen-root 
+   prop_notify-atom == c-atom.xkb_names 
+   prop_notify-state == 
XCB_PROPERTY_NEW_VALUE)
+   update_xkb_keymap(c);
+   }
}
 #endif
 
-- 
1.8.3.1

___
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/wayland-devel


[PATCH 3/4] compositor-wayland: Handle keymap changes

2013-10-07 Thread Rui Matos
---
 src/compositor-wayland.c | 6 +-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/src/compositor-wayland.c b/src/compositor-wayland.c
index 77b2a2c..95545bc 100644
--- a/src/compositor-wayland.c
+++ b/src/compositor-wayland.c
@@ -515,7 +515,11 @@ input_handle_keymap(void *data, struct wl_keyboard 
*keyboard, uint32_t format,
return;
}
 
-   weston_seat_init_keyboard(input-base, keymap);
+   if (input-base.keyboard)
+   weston_seat_update_keyboard(input-base, keymap);
+   else
+   weston_seat_init_keyboard(input-base, keymap);
+
xkb_map_unref(keymap);
 }
 
-- 
1.8.3.1

___
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/wayland-devel


[PATCH 4/4] clients/window: Dispose of previous keymap and state on keymap change

2013-10-07 Thread Rui Matos
---
 clients/window.c | 24 +++-
 1 file changed, 15 insertions(+), 9 deletions(-)

diff --git a/clients/window.c b/clients/window.c
index 5b20da5..1f32c73 100644
--- a/clients/window.c
+++ b/clients/window.c
@@ -3037,6 +3037,8 @@ keyboard_handle_keymap(void *data, struct wl_keyboard 
*keyboard,
   uint32_t format, int fd, uint32_t size)
 {
struct input *input = data;
+   struct xkb_keymap *keymap;
+   struct xkb_state *state;
char *map_str;
 
if (!data) {
@@ -3055,26 +3057,30 @@ keyboard_handle_keymap(void *data, struct wl_keyboard 
*keyboard,
return;
}
 
-   input-xkb.keymap = xkb_map_new_from_string(input-display-xkb_context,
-   map_str,
-   XKB_KEYMAP_FORMAT_TEXT_V1,
-   0);
+   keymap = xkb_map_new_from_string(input-display-xkb_context,
+map_str,
+XKB_KEYMAP_FORMAT_TEXT_V1,
+0);
munmap(map_str, size);
close(fd);
 
-   if (!input-xkb.keymap) {
+   if (!keymap) {
fprintf(stderr, failed to compile keymap\n);
return;
}
 
-   input-xkb.state = xkb_state_new(input-xkb.keymap);
-   if (!input-xkb.state) {
+   state = xkb_state_new(keymap);
+   if (!state) {
fprintf(stderr, failed to create XKB state\n);
-   xkb_map_unref(input-xkb.keymap);
-   input-xkb.keymap = NULL;
+   xkb_map_unref(keymap);
return;
}
 
+   xkb_keymap_unref(input-xkb.keymap);
+   xkb_state_unref(input-xkb.state);
+   input-xkb.keymap = keymap;
+   input-xkb.state = state;
+
input-xkb.control_mask =
1  xkb_map_mod_get_index(input-xkb.keymap, Control);
input-xkb.alt_mask =
-- 
1.8.3.1

___
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/wayland-devel