[PATCH libinput] test: add a semi-mt Alps test device

2014-07-23 Thread Peter Hutterer
Provides the bounding box only, with slot 0 always being the upper/left, slot
1 being the lower-right touch. This needs to use the touch_down etc. litest
interfaces, which are now widened to double (leftover from 489630f58) and a
device-specific private pointer in the litest device.

New device feature for litest: LITEST_SEMI_MT

Signed-off-by: Peter Hutterer 
---
 test/Makefile.am   |   1 +
 test/litest-alps-semi-mt.c | 258 +
 test/litest-int.h  |   4 +-
 test/litest.c  |  17 +--
 test/litest.h  |   6 ++
 5 files changed, 277 insertions(+), 9 deletions(-)
 create mode 100644 test/litest-alps-semi-mt.c

diff --git a/test/Makefile.am b/test/Makefile.am
index c3c293a..35c3bf8 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -15,6 +15,7 @@ liblitest_la_SOURCES = \
../src/libinput-util.c \
litest.h \
litest-int.h \
+   litest-alps-semi-mt.c \
litest-bcm5974.c \
litest-keyboard.c \
litest-mouse.c \
diff --git a/test/litest-alps-semi-mt.c b/test/litest-alps-semi-mt.c
new file mode 100644
index 000..2e85540
--- /dev/null
+++ b/test/litest-alps-semi-mt.c
@@ -0,0 +1,258 @@
+/*
+ * Copyright © 2014 Red Hat, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of the copyright holders not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  The copyright holders make no representations
+ * about the suitability of this software for any purpose.  It is provided "as
+ * is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include 
+
+#include "libinput-util.h"
+
+#include "litest.h"
+#include "litest-int.h"
+
+static int tracking_id;
+
+/* this is a semi-mt device, so we keep track of the touches that the tests
+ * send and modify them so that the first touch is always slot 0 and sends
+ * the top-left of the bounding box, the second is always slot 1 and sends
+ * the bottom-right of the bounding box.
+ * Lifting any of two fingers terminates slot 1
+ */
+struct alps {
+   /* The actual touches requested by the test for the two slots
+* in the 0..100 range used by litest */
+   struct {
+   double x, y;
+   } touches[2];
+};
+
+static void alps_create(struct litest_device *d);
+
+static void
+litest_alps_setup(void)
+{
+   struct litest_device *d = litest_create_device(LITEST_ALPS_SEMI_MT);
+   litest_set_current_device(d);
+}
+
+static void
+send_abs_xy(struct litest_device *d, double x, double y)
+{
+   struct input_event e;
+   int val;
+
+   e.type = EV_ABS;
+   e.code = ABS_X;
+   e.value = LITEST_AUTO_ASSIGN;
+   val = litest_auto_assign_value(d, &e, 0, x, y);
+   litest_event(d, EV_ABS, ABS_X, val);
+
+   e.code = ABS_Y;
+   val = litest_auto_assign_value(d, &e, 0, x, y);
+   litest_event(d, EV_ABS, ABS_Y, val);
+}
+
+static void
+send_abs_mt_xy(struct litest_device *d, double x, double y)
+{
+   struct input_event e;
+   int val;
+
+   e.type = EV_ABS;
+   e.code = ABS_MT_POSITION_X;
+   e.value = LITEST_AUTO_ASSIGN;
+   val = litest_auto_assign_value(d, &e, 0, x, y);
+   litest_event(d, EV_ABS, ABS_MT_POSITION_X, val);
+
+   e.code = ABS_MT_POSITION_Y;
+   e.value = LITEST_AUTO_ASSIGN;
+   val = litest_auto_assign_value(d, &e, 0, x, y);
+   litest_event(d, EV_ABS, ABS_MT_POSITION_Y, val);
+}
+
+static void
+alps_touch_down(struct litest_device *d, unsigned int slot, double x, double y)
+{
+   struct alps *alps = d->private;
+   double t, l, r, b; /* top, left, right, bottom */
+
+   if (d->ntouches_down > 2 || slot > 1)
+   return;
+
+   if (d->ntouches_down == 1) {
+   l = x;
+   t = y;
+   } else {
+   int other = (slot + 1) % 2;
+   l = min(x, alps->touches[other].x);
+   t = min(y, alps->touches[other].y);
+   r = max(x, alps->touches[other].x);
+   b = max(y, alps->touches[other].y);
+   }
+
+   send_abs_xy(d, l, t);
+ 

Re: Running wayland inside something other than monitors.

2014-07-23 Thread Pekka Paalanen
On Wed, 23 Jul 2014 22:23:38 +0200
Kalrish Bäakjen  wrote:

> I had the same idea, and asked in StackExchange whether it would be
> possible [1]. Even after reading the answers, the idea is flying in my
> mind. I am not an experienced programmer, but am anyway interested in this,
> so please tell me if you get anything.
> 
> Regards,
> KB
> 
> 1:
> http://gamedev.stackexchange.com/questions/79485/is-video-compositing-feasible

Umm... well, if the elements drawn in other processes than the main one
do not need to be accurately frame-synchronized to the main process'
output, this could certainly work. But if you do need exact
synchronization, the split to multiple processes will likely just hurt,
I believe.

With that assumption, you could very well use Wayland as the IPC there.
You probably want to replace the xdg_shell family of protocol
extensions with your own game-specific one that models your game
UI concepts better, but that also loses the option of running unmodified
toolkits or apps as Wayland clients to your game.

As to would all that really be worth it, it is quite hard for me to
imagine the benefits. An unmodified toolkit designed for desktop might
stick out from your game UI like a sore thumb, or maybe not if properly
themed... I don't know.

Technically it is all possible, but the benefits are unclear and depend
on case by case, IMHO. You would first need the game before you build
the tech. "Don't start with a framework, start with an actual game
and see if a framework falls out of it (after you have written your
Nth game)"... *shrug*

For prototyping, you could just have the additional processes as normal
graphical apps and see how it works, play your game in a window with
the other windows around, like the old Gimp UI style. That saves you the
effort of writing a Wayland compositor inside your game until you see
it would actually be good.


Thanks,
pq


> On Wed, Jul 23, 2014 at 8:08 AM, Pekka Paalanen  wrote:
> 
> > On Tue, 22 Jul 2014 23:24:35 -0400
> > Kyle Siefring  wrote:
> >
> > > I've seen a few GUIs implemented in video games and they always suck.
> > > I'm curious as to how one could get qt/gtk/ect running inside SDL. Would
> > > it be practical to pile a modified Wayland and a modified toolkit
> > > running inside SDL to get this effect?
> > >
> > > I don't want to dive into a bunch of unfamiliar C so I probably won't do
> > > this anytime soon, but I just want to know.
> >
> > Well, it would be perfectly possible to have your game act as a Wayland
> > compositor. You could then run even unmodified Wayland apps, and present
> > them inside your game. I'm not sure if that is what you are after
> > though, but it could be a way to get those popular toolkits into use
> > for your game with mostly the effort of implementing a Wayland
> > compositor for desktop protocols and not modifying the toolkits at all.

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


Re: Running wayland inside something other than monitors.

2014-07-23 Thread Kalrish Bäakjen
I had the same idea, and asked in StackExchange whether it would be
possible [1]. Even after reading the answers, the idea is flying in my
mind. I am not an experienced programmer, but am anyway interested in this,
so please tell me if you get anything.

Regards,
KB

1:
http://gamedev.stackexchange.com/questions/79485/is-video-compositing-feasible


On Wed, Jul 23, 2014 at 8:08 AM, Pekka Paalanen  wrote:

> On Tue, 22 Jul 2014 23:24:35 -0400
> Kyle Siefring  wrote:
>
> > I've seen a few GUIs implemented in video games and they always suck.
> > I'm curious as to how one could get qt/gtk/ect running inside SDL. Would
> > it be practical to pile a modified Wayland and a modified toolkit
> > running inside SDL to get this effect?
> >
> > I don't want to dive into a bunch of unfamiliar C so I probably won't do
> > this anytime soon, but I just want to know.
>
> Well, it would be perfectly possible to have your game act as a Wayland
> compositor. You could then run even unmodified Wayland apps, and present
> them inside your game. I'm not sure if that is what you are after
> though, but it could be a way to get those popular toolkits into use
> for your game with mostly the effort of implementing a Wayland
> compositor for desktop protocols and not modifying the toolkits at all.
>
>
> Thanks,
> pq
> ___
> wayland-devel mailing list
> wayland-devel@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/wayland-devel
>
___
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/wayland-devel


Re: [PATCH weston 1/2] compositor: keep track of the weston_layer a weston_view is in

2014-07-23 Thread Giulio Camuffo
2014-07-21 23:25 GMT+03:00 Jason Ekstrand :
> Guilio,
> I think I figured out what bothered me about this patch.  You use a
> weston_layer_entry to store the list in weston_layer instead of just
> wl_list.  I think the code would actually be clearer if you just used
> wl_list in that case.  That way we avoid all of the layer.view_list.link
> stuff which looks weird and inconsistent with the rest of our uses of the
> word "link".  Other than that, I'm ok with it.
> --Jason

Actually that was a deliberate decision. The point is that
weston_layer_entry_insert() needs two weston_layer_entry, both for the
list and the entry, so to avoid special casing the insertion of a view
at the head of the layer's list rather than in the middle of it I put
a weston_layer_entry at the head of the list too.

>
>
> On Fri, Jul 18, 2014 at 5:44 PM, Jason Ekstrand 
> wrote:
>>
>> I'm not sure what I think about this patch.  I really don't like
>> recreating wl_list and calling it wl_layer_entry just to keep track of the
>> layer pointer.  However, I can't really think of a better solution off-hand.
>> I'll think on it more and get back to you on Monday.
>> --Jason Ekstrand
>>
>>
>> On Wed, Jul 9, 2014 at 12:12 PM, Giulio Camuffo 
>> wrote:
>>>
>>> This introduces a new struct, weston_layer_entry, which is now used
>>> in place of wl_list to keep the link for the layer list in weston_view
>>> and the head of the list in weston_layer.
>>> weston_layer_entry also has a weston_layer*, which points to the layer
>>> the view is in or, in the case the entry it's the head of the list, to
>>> the layer itself.
>>> ---
>>>  desktop-shell/exposay.c |   4 +-
>>>  desktop-shell/input-panel.c |   7 ++-
>>>  desktop-shell/shell.c   | 145
>>> +++-
>>>  src/compositor.c|  33 +++---
>>>  src/compositor.h|  14 -
>>>  src/data-device.c   |   6 +-
>>>  src/input.c |   4 +-
>>>  tests/weston-test.c |   6 +-
>>>  8 files changed, 127 insertions(+), 92 deletions(-)
>>>
>>> diff --git a/desktop-shell/exposay.c b/desktop-shell/exposay.c
>>> index 104b9d9..4b65cbd 100644
>>> --- a/desktop-shell/exposay.c
>>> +++ b/desktop-shell/exposay.c
>>> @@ -219,7 +219,7 @@ exposay_layout(struct desktop_shell *shell, struct
>>> shell_output *shell_output)
>>> int last_row_removed = 0;
>>>
>>> eoutput->num_surfaces = 0;
>>> -   wl_list_for_each(view, &workspace->layer.view_list, layer_link) {
>>> +   wl_list_for_each(view, &workspace->layer.view_list.link,
>>> layer_link.link) {
>>> if (!get_shell_surface(view->surface))
>>> continue;
>>> if (view->output != output)
>>> @@ -272,7 +272,7 @@ exposay_layout(struct desktop_shell *shell, struct
>>> shell_output *shell_output)
>>> eoutput->surface_size = output->height / 2;
>>>
>>> i = 0;
>>> -   wl_list_for_each(view, &workspace->layer.view_list, layer_link) {
>>> +   wl_list_for_each(view, &workspace->layer.view_list.link,
>>> layer_link.link) {
>>> int pad;
>>>
>>> pad = eoutput->surface_size + eoutput->padding_inner;
>>> diff --git a/desktop-shell/input-panel.c b/desktop-shell/input-panel.c
>>> index 7623f6c..47bd73c 100644
>>> --- a/desktop-shell/input-panel.c
>>> +++ b/desktop-shell/input-panel.c
>>> @@ -75,8 +75,8 @@ show_input_panel_surface(struct input_panel_surface
>>> *ipsurf)
>>> weston_view_set_position(ipsurf->view, x, y);
>>> }
>>>
>>> -   wl_list_insert(&shell->input_panel_layer.view_list,
>>> -  &ipsurf->view->layer_link);
>>> +   weston_layer_entry_insert(&shell->input_panel_layer.view_list,
>>> + &ipsurf->view->layer_link);
>>> weston_view_geometry_dirty(ipsurf->view);
>>> weston_view_update_transform(ipsurf->view);
>>> weston_surface_damage(ipsurf->surface);
>>> @@ -135,7 +135,8 @@ hide_input_panels(struct wl_listener *listener, void
>>> *data)
>>> wl_list_remove(&shell->input_panel_layer.link);
>>>
>>> wl_list_for_each_safe(view, next,
>>> - &shell->input_panel_layer.view_list,
>>> layer_link)
>>> + &shell->input_panel_layer.view_list.link,
>>> + layer_link.link)
>>> weston_view_unmap(view);
>>>  }
>>>
>>> diff --git a/desktop-shell/shell.c b/desktop-shell/shell.c
>>> index f22cef8..6f6e25c 100644
>>> --- a/desktop-shell/shell.c
>>> +++ b/desktop-shell/shell.c
>>> @@ -279,12 +279,12 @@ shell_surface_is_top_fullscreen(struct
>>> shell_surface *shsurf)
>>>
>>> shell = shell_surface_get_shell(shsurf);
>>>
>>> -   if (wl_list_empty(&shell->fullscreen_layer.view_list))
>>> +   if (wl_list_empty(&shell->fullscreen_layer.view_list.link))
>>> return false;
>>>
>>> -   top_fs_ev = container_of(shell

[PATCH wayland v3] client: add a public function to make a roundtrip on a custom queue

2014-07-23 Thread Giulio Camuffo
wl_display_roundtrip(display) works on the default queue. Add a
parallel wl_event_queue_roundtrip(queue).
---

v3: renamed wl_display_roundtrip_queue() to wl_event_queue_roundtrip()

 src/wayland-client.c | 29 +++--
 src/wayland-client.h |  1 +
 2 files changed, 24 insertions(+), 6 deletions(-)

diff --git a/src/wayland-client.c b/src/wayland-client.c
index e8aab7e..b195e21 100644
--- a/src/wayland-client.c
+++ b/src/wayland-client.c
@@ -831,29 +831,30 @@ static const struct wl_callback_listener sync_listener = {
sync_callback
 };
 
-/** Block until all pending request are processed by the server
+/** Block until all pending request on a queue are processed by the server
  *
- * \param display The display context object
+ * \param queue The queue on which to run the roundtrip
  * \return The number of dispatched events on success or -1 on failure
  *
  * Blocks until the server process all currently issued requests and
- * sends out pending events on all event queues.
+ * sends out pending events on the given event queue.
  *
  * \memberof wl_display
  */
 WL_EXPORT int
-wl_display_roundtrip(struct wl_display *display)
+wl_event_queue_roundtrip(struct wl_event_queue *queue)
 {
struct wl_callback *callback;
int done, ret = 0;
 
done = 0;
-   callback = wl_display_sync(display);
+   callback = wl_display_sync(queue->display);
if (callback == NULL)
return -1;
+   wl_proxy_set_queue(callback, queue);
wl_callback_add_listener(callback, &sync_listener, &done);
while (!done && ret >= 0)
-   ret = wl_display_dispatch(display);
+   ret = wl_display_dispatch_queue(queue->display, queue);
 
if (ret == -1 && !done)
wl_callback_destroy(callback);
@@ -861,6 +862,22 @@ wl_display_roundtrip(struct wl_display *display)
return ret;
 }
 
+/** Block until all pending request on the default queue are processed by the 
server
+ *
+ * \param display The display context object
+ * \return The number of dispatched events on success or -1 on failure
+ *
+ * Blocks until the server process all currently issued requests and
+ * sends out pending events on the default event queue.
+ *
+ * \memberof wl_display
+ */
+WL_EXPORT int
+wl_display_roundtrip(struct wl_display *display)
+{
+   wl_event_queue_roundtrip(&display->default_queue);
+}
+
 static int
 create_proxies(struct wl_proxy *sender, struct wl_closure *closure)
 {
diff --git a/src/wayland-client.h b/src/wayland-client.h
index 2a32785..465a39e 100644
--- a/src/wayland-client.h
+++ b/src/wayland-client.h
@@ -120,6 +120,7 @@ struct wl_display;
 struct wl_event_queue;
 
 void wl_event_queue_destroy(struct wl_event_queue *queue);
+int wl_event_queue_roundtrip(struct wl_event_queue *queue);
 
 void wl_proxy_marshal(struct wl_proxy *p, uint32_t opcode, ...);
 void wl_proxy_marshal_array(struct wl_proxy *p, uint32_t opcode,
-- 
2.0.2

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


Re: [PATCH] touchpad: reset motion history when nfingers changes on semi-mt pads

2014-07-23 Thread Hans de Goede
Hi,

On 07/23/2014 07:58 AM, Peter Hutterer wrote:
> On Tue, Jul 22, 2014 at 09:18:26AM +0200, Hans de Goede wrote:
>> Hi,
>>
>> On 07/22/2014 01:34 AM, Peter Hutterer wrote:
>>> On Mon, Jul 21, 2014 at 03:25:47PM +0200, Hans de Goede wrote:
 On semi-mt touchpads the reported position of the first finger down may
 jump when the pad switches from st to mt mode. When this happens a large
 delta gets seen on the first finger at the same time the second fingers
 is first seen down, causing a spurious 2 finger scroll event.

 Reset the motion history when nfingers changes on semi-mt pads to avoid 
 this.

 Signed-off-by: Hans de Goede 
>>>
>>> I don't seem to have any good recordings here that show the SEMI_MT jumps.
>>> Any chance you can get one and add a test device for this?
>>
>> Attached is a recording.
>>
>> The jump starts at line 315, there slot 0 x / y are aprox. 640 / 1300, then
>> at line 326 they jump to 1400 / 1272. This jump happens because in 2 finger
>> mode the touchpad no longer reports exact locations, instead we get
>> a bounding box, where the fingers occupy 2 opposing corners, and in this case
>> the fingers are on 2 different corners then the ones the kernel chooses to
>> always report.
>>
>> I guess the kernel could / should be made smarter here, and could decide 
>> which
>> 2 corners to pick based on the last single touch coordinate, instead of 
>> always
>> picking the upper left and bottom right corners. I'll take a look at that,
>> resetting the motion history is still the right thing to do though, since
>> the 2 finger coordinates basically use a different coordinate system which
>> gets scaled to the single touch coordinate system.
> 
> if the kernel is no option (as you said in the other email), can we add a
> semi-mt specific touch filtering system so that we fix the touchpoints
> _before_ we get to the main touchpad processing code? That way we don't have
> to care at all about semi-mt once the touchpoints are fixed. It won't be
> perfect, but it's better than having to worry about semi-mt everywhere.

For the record, Peter and I discussed this on the phone, and we decided
that just leaving things as is + restting motion history when the number of
fingers changes is the best way forward with this.

>  
>> Adding a test device for this based on the recording should be easy.
>>
>>> ACK to the patch, but this is really something I'd like to see a specific
>>> test case for so we know what we're fixing here. plus, adding a semi-mt
>>> device to the test suite means we can figure out if everything else works
>>> fine with it.
>>
>> I already expected you would want a test-case, the problem is that currently
>> in litest we cannot send a motion event with it automatically getting a sync
>> added at the end of it, making it impossible to reproduce the behavior from
>> the recording in litest. I've been thinking a bit about this and I think
>> that the best way to deal with this is a suppress_syn flag which will 
>> basically
>> suppress all syn sending when set, then special cases like this one can
>> just set that flag, queue up events, clear the flag and do an explicit syn.
> 
> How about an API that takes multiple touch down events and
> strips the SYN_REPORTS out automatically. So e.g.
> 
> litest_multi_touch_down(0,  10, 10,
> 1,  50, 50,
> -1);
> 
> and the matching move/up calls. That won't cater for this particular case
> though, I think for this use-case you really need to just litest_write the
> specific event sequence. Or, even better, overwrite touch_down in the
> litest-device interface to mangle the touchpoints per slot to replicate the
> kernel behaviour, which would make the device applicable for all tests then.

We discussed this too, Peter has some plans to create a special test device
which accurately emulates semi-mt devices. Peter has put doing this on his
TODO list.

Regards,

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


[RFC wayland v2 1/2] connection: Move definitions

2014-07-23 Thread Boyan Ding
wayland-tracer will use them.

Signed-off-by: Boyan Ding 
---
 src/connection.c  | 18 +++---
 src/wayland-private.h | 18 +-
 2 files changed, 20 insertions(+), 16 deletions(-)

diff --git a/src/connection.c b/src/connection.c
index f292853..79197c9 100644
--- a/src/connection.c
+++ b/src/connection.c
@@ -44,23 +44,11 @@
 
 #define DIV_ROUNDUP(n, a) ( ((n) + ((a) - 1)) / (a) )
 
-struct wl_buffer {
-   char data[4096];
-   uint32_t head, tail;
-};
-
 #define MASK(i) ((i) & 4095)
 
 #define MAX_FDS_OUT28
 #define CLEN   (CMSG_LEN(MAX_FDS_OUT * sizeof(int32_t)))
 
-struct wl_connection {
-   struct wl_buffer in, out;
-   struct wl_buffer fds_in, fds_out;
-   int fd;
-   int want_flush;
-};
-
 static int
 wl_buffer_put(struct wl_buffer *b, const void *data, size_t count)
 {
@@ -135,7 +123,7 @@ wl_buffer_get_iov(struct wl_buffer *b, struct iovec *iov, 
int *count)
}
 }
 
-static void
+void
 wl_buffer_copy(struct wl_buffer *b, void *data, size_t count)
 {
uint32_t tail, size;
@@ -150,7 +138,7 @@ wl_buffer_copy(struct wl_buffer *b, void *data, size_t 
count)
}
 }
 
-static uint32_t
+uint32_t
 wl_buffer_size(struct wl_buffer *b)
 {
return b->head - b->tail;
@@ -394,7 +382,7 @@ wl_message_count_arrays(const struct wl_message *message)
return arrays;
 }
 
-static int
+int
 wl_connection_put_fd(struct wl_connection *connection, int32_t fd)
 {
if (wl_buffer_size(&connection->fds_out) == MAX_FDS_OUT * sizeof fd) {
diff --git a/src/wayland-private.h b/src/wayland-private.h
index 67e8783..ad5313e 100644
--- a/src/wayland-private.h
+++ b/src/wayland-private.h
@@ -78,13 +78,28 @@ void *wl_map_lookup(struct wl_map *map, uint32_t i);
 uint32_t wl_map_lookup_flags(struct wl_map *map, uint32_t i);
 void wl_map_for_each(struct wl_map *map, wl_iterator_func_t func, void *data);
 
-struct wl_connection;
+
+struct wl_buffer {
+   char data[4096];
+   uint32_t head, tail;
+};
+
+struct wl_connection {
+   struct wl_buffer in, out;
+   struct wl_buffer fds_in, fds_out;
+   int fd;
+   int want_flush;
+};
+
 struct wl_closure;
 struct wl_proxy;
 
 int wl_interface_equal(const struct wl_interface *iface1,
   const struct wl_interface *iface2);
 
+void wl_buffer_copy(struct wl_buffer *b, void *data, size_t count);
+uint32_t wl_buffer_size(struct wl_buffer *b);
+
 struct wl_connection *wl_connection_create(int fd);
 void wl_connection_destroy(struct wl_connection *connection);
 void wl_connection_copy(struct wl_connection *connection, void *data, size_t 
size);
@@ -96,6 +111,7 @@ int wl_connection_read(struct wl_connection *connection);
 int wl_connection_write(struct wl_connection *connection, const void *data, 
size_t count);
 int wl_connection_queue(struct wl_connection *connection,
const void *data, size_t count);
+int wl_connection_put_fd(struct wl_connection *connection, int32_t fd);
 
 struct wl_closure {
int count;
-- 
2.0.1


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


[RFC wayland v2 0/2] Wayland protocol dumper

2014-07-23 Thread Boyan Ding
The v2 of patches sees a lot of new code and the most notable change
is the introduction of "server mode". Under server mode, the program
will act as a wayland server and can accept multiple clients via
WAYLAND_DISPLAY variable. An interesting usecase of this feature is to
trace all clients of a compositor.

To make it run under server mode, run
shell> wayland-tracer -S SOCKET_NAME
SOCKET_NAME is a value like wayland-0 or so. If we set WAYLAND_DISPLAY
environment variable to SOCKET_NAME and launch a wayland app, that app
will be traced.

To make it run under default mode (now called "single mode"), run
shell> wayland-tracer -- program arguments ...

Also, EPOLLHUP is handled correctly in this version.

The next step will be adding xml protocol parsing and wire data
analysing according to protocol files. This will be much tougher but I
hope I can finish that.

Boyan Ding (2):
  connection: Move definitions
  Add a wayland protocol dumper wayland-tracer

 .gitignore|   1 +
 Makefile.am   |  10 +
 configure.ac  |   7 +
 src/connection.c  |  18 +-
 src/tracer.c  | 689 ++
 src/wayland-private.h |  18 +-
 6 files changed, 727 insertions(+), 16 deletions(-)
 create mode 100644 src/tracer.c

-- 
2.0.1


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


[RFC wayland v2 2/2] Add a wayland protocol dumper wayland-tracer

2014-07-23 Thread Boyan Ding
Signed-off-by: Boyan Ding 
---
 .gitignore   |   1 +
 Makefile.am  |  10 +
 configure.ac |   7 +
 src/tracer.c | 689 +++
 4 files changed, 707 insertions(+)
 create mode 100644 src/tracer.c

diff --git a/.gitignore b/.gitignore
index c146bac..510b7ae 100644
--- a/.gitignore
+++ b/.gitignore
@@ -54,4 +54,5 @@ sanity-test
 signal-test
 socket-test
 wayland-scanner
+wayland-tracer
 protocol/*.[ch]
diff --git a/Makefile.am b/Makefile.am
index fee19ab..61827dd 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -70,6 +70,16 @@ $(BUILT_SOURCES) : wayland-scanner
 pkgconfig_DATA += src/wayland-scanner.pc
 else
 wayland_scanner = wayland-scanner
+bin_PROGRAMS =
+endif
+
+if ENABLE_TRACER
+wayland_tracer = $(top_builddir)/wayland-tracer
+bin_PROGRAMS += wayland-tracer
+wayland_tracer_SOURCES = src/tracer.c
+wayland_tracer_LDADD = libwayland-util.la $(FFI_LIBS) -lrt
+else
+wayland_tracer = wayland-tracer
 endif
 
 protocol/%-protocol.c : $(top_srcdir)/protocol/%.xml
diff --git a/configure.ac b/configure.ac
index e16c5b5..b3e81a7 100644
--- a/configure.ac
+++ b/configure.ac
@@ -64,7 +64,14 @@ AC_ARG_ENABLE([documentation],
  [],
  [enable_documentation=yes])
 
+AC_ARG_ENABLE([tracer],
+  [AC_HELP_STRING([--disable-tracer],
+  [Disable compilation of wayland-tracer])],
+  [],
+  [enable_tracer=yes])
+
 AM_CONDITIONAL(ENABLE_SCANNER, test "x$enable_scanner" = xyes)
+AM_CONDITIONAL(ENABLE_TRACER, test "x$enable_tracer" = xyes)
 
 AC_ARG_WITH(icondir, [  --with-icondir=Look for cursor icons here],
 [  ICONDIR=$withval],
diff --git a/src/tracer.c b/src/tracer.c
new file mode 100644
index 000..9adb21f
--- /dev/null
+++ b/src/tracer.c
@@ -0,0 +1,689 @@
+/*
+ * Copyright © 2014 Boyan Ding
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of the copyright holders not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  The copyright holders make no representations
+ * about the suitability of this software for any purpose.  It is provided "as
+ * is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "wayland-os.h"
+#include "wayland-private.h"
+#include "wayland-util.h"
+
+#define TRACER_SERVER_SIDE 0
+#define TRACER_CLIENT_SIDE 1
+
+#define TRACER_MODE_SINGLE 0
+#define TRACER_MODE_SERVER 1
+
+#ifndef UNIX_PATH_MAX
+#define UNIX_PATH_MAX 108
+#endif
+
+#define LOCK_SUFFIX ".lock"
+#define LOCK_SUFFIXLEN 5
+struct tracer;
+struct tracer_instance;
+
+struct tracer_connection {
+   struct wl_connection *wl_conn;
+   struct tracer_connection *peer;
+   struct tracer_instance *instance;
+   int side;
+};
+
+struct tracer_instance {
+   int id;
+   struct tracer_connection *client_conn;
+   struct tracer_connection *server_conn;
+   struct tracer *tracer;
+   struct wl_list link;
+};
+
+/* A simple copy of wl_socket in wayland-server.c */
+struct tracer_socket {
+   int fd;
+   int fd_lock;
+   struct sockaddr_un addr;
+   char lock_addr[UNIX_PATH_MAX + LOCK_SUFFIXLEN];
+};
+
+struct tracer {
+   struct tracer_socket *socket;
+   int32_t epollfd;
+   int next_id;
+   struct wl_list instance_list;
+};
+
+struct tracer_options {
+   int mode;
+   char **spawn_args;
+   char *socket;
+};
+
+static int
+tracer_dump_bin(struct tracer_connection *connection)
+{
+   int i, len, fdlen, fd;
+   char buf[4096];
+   struct wl_connection *wl_conn= connection->wl_conn;
+   struct tracer_connection *peer = connection->peer;
+   struct tracer_instance *instance = connection->instance;
+
+   len = wl_buffer_size(&wl_conn->in);
+   if (len == 0)
+   return 0;
+
+   wl_connection_copy(wl_conn, buf, len);
+
+   printf("%d: %s Data dumped: %d bytes:\n", instance->id,
+  connection->side == TRACER_SERVER_SIDE ? "=>" : "<=", len);
+