aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPetteri Aimonen <jpa@git.mail.kapsi.fi>2013-03-02 16:27:31 +0200
committerPetteri Aimonen <jpa@git.mail.kapsi.fi>2013-03-02 16:27:31 +0200
commitf8a143fdfeea69a106e1bc7a774c5f96eba3da7c (patch)
tree4502d0ab6c733bb68651b99b20fe218445f7c066
parent0e3053894ff200288fc16056a50ac37b62785471 (diff)
Update documentation
-rw-r--r--docs/concepts.rst16
-rw-r--r--docs/index.rst18
-rw-r--r--docs/reference.rst36
3 files changed, 35 insertions, 35 deletions
diff --git a/docs/concepts.rst b/docs/concepts.rst
index b18c5057..052edcc1 100644
--- a/docs/concepts.rst
+++ b/docs/concepts.rst
@@ -255,16 +255,8 @@ For example this submessage in the Person.proto file::
generates this field description array for the structure *Person_PhoneNumber*::
const pb_field_t Person_PhoneNumber_fields[3] = {
- {1, PB_HTYPE_REQUIRED | PB_LTYPE_STRING,
- offsetof(Person_PhoneNumber, number), 0,
- pb_membersize(Person_PhoneNumber, number), 0, 0},
-
- {2, PB_HTYPE_OPTIONAL | PB_LTYPE_VARINT,
- pb_delta(Person_PhoneNumber, type, number),
- pb_delta(Person_PhoneNumber, has_type, type),
- pb_membersize(Person_PhoneNumber, type), 0,
- &Person_PhoneNumber_type_default},
-
+ PB_FIELD( 1, STRING , REQUIRED, STATIC, Person_PhoneNumber, number, number, 0),
+ PB_FIELD( 2, ENUM , OPTIONAL, STATIC, Person_PhoneNumber, type, number, &Person_PhoneNumber_type_default),
PB_LAST_FIELD
};
@@ -276,8 +268,8 @@ Most functions in nanopb return bool: *true* means success, *false* means failur
The error messages help in guessing what is the underlying cause of the error. The most common error conditions are:
-1) Running out of memory. Because everything is allocated from the stack, nanopb can't detect this itself. Encoding or decoding the same type of a message always takes the same amount of stack space. Therefore, if it works once, it works always.
-2) Invalid field description. These are usually stored as constants, so if it works under the debugger, it always does.
+1) Running out of memory, i.e. stack overflow.
+2) Invalid field descriptors (would usually mean a bug in the generator).
3) IO errors in your own stream callbacks.
4) Errors that happen in your callback functions.
5) Exceeding the max_size or bytes_left of a stream.
diff --git a/docs/index.rst b/docs/index.rst
index 31d781ea..897f5529 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -36,23 +36,26 @@ Features and limitations
**Features**
#) Pure C runtime
-#) Small code size (2–10 kB depending on processor)
-#) Small ram usage (typically 200 bytes)
+#) Small code size (2–10 kB depending on processor, plus any message definitions)
+#) Small ram usage (typically ~300 bytes, plus any message structs)
#) Allows specifying maximum size for strings and arrays, so that they can be allocated statically.
#) No malloc needed: everything can be allocated statically or on the stack.
#) You can use either encoder or decoder alone to cut the code size in half.
+#) Support for most protobuf features, including: all data types, nested submessages, default values, repeated and optional fields, packed arrays.
+#) Callback mechanism for handling messages larger than can fit in available RAM.
+#) Extensive set of tests.
**Limitations**
#) User must provide callbacks when decoding arrays or strings without maximum size. Malloc support could be added as a separate module.
-#) Some speed has been sacrificed for code size. For example varint calculations are always done in 64 bits.
+#) Some speed has been sacrificed for code size.
#) Encoding is focused on writing to streams. For memory buffers only it could be made more efficient.
#) The deprecated Protocol Buffers feature called "groups" is not supported.
#) Fields in the generated structs are ordered by the tag number, instead of the natural ordering in .proto file.
#) Unknown fields are not preserved when decoding and re-encoding a message.
#) Reflection (runtime introspection) is not supported. E.g. you can't request a field by giving its name in a string.
#) Numeric arrays are always encoded as packed, even if not marked as packed in .proto. This causes incompatibility with decoders that do not support packed format.
-#) Cyclic references between messages are not supported. They could be supported in callback-mode if there was an option in the generator to set the mode.
+#) Cyclic references between messages are supported only in callback mode.
Getting started
===============
@@ -104,10 +107,3 @@ Debugging and testing
=====================
Extensive unittests are included under the *tests* folder. Just type *make* there to run the tests.
-This also generates a file called *breakpoints* which includes all lines returning *false* in nanopb. You can use this in gdb by typing *source breakpoints*, after which gdb will break on first nanopb error.
-
-Wishlist
-========
-#) A specialized encoder for encoding to a memory buffer. Should serialize in reverse order to avoid having to determine submessage size beforehand.
-#) A cleaner rewrite of the Python-based source generator.
-#) Better performance for 16- and 8-bit platforms: use smaller datatypes where possible.
diff --git a/docs/reference.rst b/docs/reference.rst
index fee1b702..93aae8b0 100644
--- a/docs/reference.rst
+++ b/docs/reference.rst
@@ -37,22 +37,23 @@ pb_type_t
---------
Defines the encoder/decoder behaviour that should be used for a field. ::
- typedef enum { ... } pb_type_t;
+ typedef uint8_t pb_type_t;
-The low-order byte of the enumeration values defines the function that can be used for encoding and decoding the field data:
+The low-order nibble of the enumeration values defines the function that can be used for encoding and decoding the field data:
==================== ===== ================================================
LTYPE identifier Value Storage format
==================== ===== ================================================
PB_LTYPE_VARINT 0x00 Integer.
PB_LTYPE_SVARINT 0x01 Integer, zigzag encoded.
-PB_LTYPE_FIXED 0x02 Integer or floating point.
-PB_LTYPE_BYTES 0x03 Structure with *size_t* field and byte array.
-PB_LTYPE_STRING 0x04 Null-terminated string.
-PB_LTYPE_SUBMESSAGE 0x05 Submessage structure.
+PB_LTYPE_FIXED32 0x02 32-bit integer or floating point.
+PB_LTYPE_FIXED64 0x03 64-bit integer or floating point.
+PB_LTYPE_BYTES 0x04 Structure with *size_t* field and byte array.
+PB_LTYPE_STRING 0x05 Null-terminated string.
+PB_LTYPE_SUBMESSAGE 0x06 Submessage structure.
==================== ===== ================================================
-The high-order byte defines whether the field is required, optional, repeated or callback:
+The bits 4-5 define whether the field is required, optional or repeated:
==================== ===== ================================================
HTYPE identifier Value Field handling
@@ -60,13 +61,24 @@ HTYPE identifier Value Field handling
PB_HTYPE_REQUIRED 0x00 Verify that field exists in decoded message.
PB_HTYPE_OPTIONAL 0x10 Use separate *has_<field>* boolean to specify
whether the field is present.
-PB_HTYPE_ARRAY 0x20 A repeated field with preallocated array.
+ (Unless it is a callback)
+PB_HTYPE_REPEATED 0x20 A repeated field with preallocated array.
Separate *<field>_count* for number of items.
-PB_HTYPE_CALLBACK 0x30 A field with dynamic storage size, data is
- actually a pointer to a structure containing a
- callback function.
+ (Unless it is a callback)
==================== ===== ================================================
+The bits 6-7 define the how the storage for the field is allocated:
+
+==================== ===== ================================================
+ATYPE identifier Value Allocation method
+==================== ===== ================================================
+PB_ATYPE_STATIC 0x00 Statically allocated storage in the structure.
+PB_ATYPE_CALLBACK 0x40 A field with dynamic storage size. Struct field
+ actually contains a pointer to a callback
+ function.
+==================== ===== ================================================
+
+
pb_field_t
----------
Describes a single structure field with memory position in relation to others. The descriptions are usually autogenerated. ::
@@ -83,7 +95,7 @@ Describes a single structure field with memory position in relation to others. T
} pb_packed;
:tag: Tag number of the field or 0 to terminate a list of fields.
-:type: LTYPE and HTYPE of the field.
+:type: LTYPE, HTYPE and ATYPE of the field.
:data_offset: Offset of field data, relative to the end of the previous field.
:size_offset: Offset of *bool* flag for optional fields or *size_t* count for arrays, relative to field data.
:data_size: Size of a single data entry, in bytes. For PB_LTYPE_BYTES, the size of the byte array inside the containing structure. For PB_HTYPE_CALLBACK, size of the C data type if known.
riable */ .highlight .ow { color: #008800 } /* Operator.Word */ .highlight .w { color: #bbbbbb } /* Text.Whitespace */ .highlight .mb { color: #0000DD; font-weight: bold } /* Literal.Number.Bin */ .highlight .mf { color: #0000DD; font-weight: bold } /* Literal.Number.Float */ .highlight .mh { color: #0000DD; font-weight: bold } /* Literal.Number.Hex */ .highlight .mi { color: #0000DD; font-weight: bold } /* Literal.Number.Integer */ .highlight .mo { color: #0000DD; font-weight: bold } /* Literal.Number.Oct */ .highlight .sa { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Affix */ .highlight .sb { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Backtick */ .highlight .sc { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Char */ .highlight .dl { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Delimiter */ .highlight .sd { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Doc */ .highlight .s2 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Double */ .highlight .se { color: #0044dd; background-color: #fff0f0 } /* Literal.String.Escape */ .highlight .sh { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Heredoc */ .highlight .si { color: #3333bb; background-color: #fff0f0 } /* Literal.String.Interpol */ .highlight .sx { color: #22bb22; background-color: #f0fff0 } /* Literal.String.Other */ .highlight .sr { color: #008800; background-color: #fff0ff } /* Literal.String.Regex */ .highlight .s1 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Single */ .highlight .ss { color: #aa6600; background-color: #fff0f0 } /* Literal.String.Symbol */ .highlight .bp { color: #003388 } /* Name.Builtin.Pseudo */ .highlight .fm { color: #0066bb; font-weight: bold } /* Name.Function.Magic */ .highlight .vc { color: #336699 } /* Name.Variable.Class */ .highlight .vg { color: #dd7700 } /* Name.Variable.Global */ .highlight .vi { color: #3333bb } /* Name.Variable.Instance */ .highlight .vm { color: #336699 } /* Name.Variable.Magic */ .highlight .il { color: #0000DD; font-weight: bold } /* Literal.Number.Integer.Long */
From 90fafb6ea39940161f3bf86ab7f557197ff389ff Mon Sep 17 00:00:00 2001
From: Pooja Prajod <a0132412@ti.com>
Date: Fri, 26 Feb 2016 16:46:39 -0500
Subject: [PATCH] Enable mouse movement for videos on waylandsink

This patch enables grab, drag and ungrab of videos
that are being played on waylandsink.

Signed-off-by: Pooja Prajod <a0132412@ti.com>
---
 ext/wayland/gstwaylandsink.c | 283 +++++++++++++++++++++++++++++++++++++++++++
 ext/wayland/gstwaylandsink.h |  26 ++++
 2 files changed, 309 insertions(+)

diff --git a/ext/wayland/gstwaylandsink.c b/ext/wayland/gstwaylandsink.c
index cabf310..7394a2b 100644
--- a/ext/wayland/gstwaylandsink.c
+++ b/ext/wayland/gstwaylandsink.c
@@ -41,6 +41,7 @@
 #endif
 
 #include "gstwaylandsink.h"
+#include <linux/input.h>
 
 /* signals */
 enum
@@ -100,6 +101,9 @@ static void create_window (GstWaylandSink * sink, struct display *display,
     int width, int height);
 static void shm_pool_destroy (struct shm_pool *pool);
 
+static void input_grab (struct input *input, struct window *window);
+static void input_ungrab (struct input *input);
+
 typedef struct
 {
   uint32_t wl_format;
@@ -225,6 +229,54 @@ gst_wayland_sink_set_property (GObject * object,
 }
 
 static void
+input_grab (struct input *input, struct window *window)
+{
+  input->grab = window;
+}
+
+static void
+input_ungrab (struct input *input)
+{
+  input->grab = NULL;
+}
+
+static void
+input_remove_pointer_focus (struct input *input)
+{
+  struct window *window = input->pointer_focus;
+
+  if (!window)
+    return;
+
+  input->pointer_focus = NULL;
+}
+
+static void
+input_destroy (struct input *input)
+{
+  input_remove_pointer_focus (input);
+
+  if (input->display->seat_version >= 3) {
+    if (input->pointer)
+      wl_pointer_release (input->pointer);
+  }
+
+  wl_list_remove (&input->link);
+  wl_seat_destroy (input->seat);
+  free (input);
+}
+
+static void
+display_destroy_inputs (struct display *display)
+{
+  struct input *tmp;
+  struct input *input;
+
+  wl_list_for_each_safe (input, tmp, &display->input_list, link)
+      input_destroy (input);
+}
+
+static void
 destroy_display (struct display *display)
 {
   if (display->shm)
@@ -236,6 +288,7 @@ destroy_display (struct display *display)
   if (display->compositor)
     wl_compositor_destroy (display->compositor);
 
+  display_destroy_inputs (display);
   wl_display_flush (display->display);
   wl_display_disconnect (display->display);
   free (display);
@@ -318,6 +371,229 @@ struct wl_shm_listener shm_listenter = {
   shm_format
 };
 
+
+static void
+pointer_handle_enter (void *data, struct wl_pointer *pointer,
+    uint32_t serial, struct wl_surface *surface,
+    wl_fixed_t sx_w, wl_fixed_t sy_w)
+{
+  struct input *input = data;
+
+  if (!surface) {
+    /* enter event for a window we've just destroyed */
+    return;
+  }
+
+  input->display->serial = serial;
+  input->pointer_focus = wl_surface_get_user_data (surface);
+}
+
+static void
+pointer_handle_leave (void *data, struct wl_pointer *pointer,
+    uint32_t serial, struct wl_surface *surface)
+{
+  struct input *input = data;
+
+  input_remove_pointer_focus (input);
+}
+
+static void
+pointer_handle_motion (void *data, struct wl_pointer *pointer,
+    uint32_t time, wl_fixed_t sx_w, wl_fixed_t sy_w)
+{
+  struct input *input = data;
+  struct window *window = input->pointer_focus;
+
+  if (!window)
+    return;
+
+  if (input->grab)
+    wl_shell_surface_move (input->grab->shell_surface, input->seat,
+        input->display->serial);
+
+}
+
+static void
+pointer_handle_button (void *data, struct wl_pointer *pointer, uint32_t serial,
+    uint32_t time, uint32_t button, uint32_t state_w)
+{
+  struct input *input = data;
+  enum wl_pointer_button_state state = state_w;
+  input->display->serial = serial;
+
+  if (button == BTN_LEFT) {
+    if (state == WL_POINTER_BUTTON_STATE_PRESSED)
+      input_grab (input, input->pointer_focus);
+
+    if (input->grab && state == WL_POINTER_BUTTON_STATE_RELEASED)
+      input_ungrab (input);
+  }
+
+  if (input->grab)
+    wl_shell_surface_move (input->grab->shell_surface, input->seat,
+        input->display->serial);
+}
+
+static void
+pointer_handle_axis (void *data, struct wl_pointer *pointer,
+    uint32_t time, uint32_t axis, wl_fixed_t value)
+{
+}
+
+static const struct wl_pointer_listener pointer_listener = {
+  pointer_handle_enter,
+  pointer_handle_leave,
+  pointer_handle_motion,
+  pointer_handle_button,
+  pointer_handle_axis,
+};
+
+static void
+touch_handle_down (void *data, struct wl_touch *wl_touch,
+    uint32_t serial, uint32_t time, struct wl_surface *surface,
+    int32_t id, wl_fixed_t x_w, wl_fixed_t y_w)
+{
+  struct input *input = data;
+  struct touch_point *tp;
+
+  input->display->serial = serial;
+  input->touch_focus = wl_surface_get_user_data (surface);
+  if (!input->touch_focus) {
+    return;
+  }
+
+  tp = malloc (sizeof *tp);
+  if (tp) {
+    tp->id = id;
+    wl_list_insert (&input->touch_point_list, &tp->link);
+    wl_shell_surface_move (input->touch_focus->shell_surface, input->seat,
+        serial);
+  }
+}
+
+static void
+touch_handle_motion (void *data, struct wl_touch *wl_touch,
+    uint32_t time, int32_t id, wl_fixed_t x_w, wl_fixed_t y_w)
+{
+  struct input *input = data;
+  struct touch_point *tp;
+
+
+  if (!input->touch_focus) {
+    return;
+  }
+  wl_list_for_each (tp, &input->touch_point_list, link) {
+    if (tp->id != id)
+      continue;
+
+    wl_shell_surface_move (input->touch_focus->shell_surface, input->seat,
+        input->display->serial);
+
+    return;
+  }
+}
+
+static void
+touch_handle_frame (void *data, struct wl_touch *wl_touch)
+{
+}
+
+static void
+touch_handle_cancel (void *data, struct wl_touch *wl_touch)
+{
+}
+
+static void
+touch_handle_up (void *data, struct wl_touch *wl_touch,
+    uint32_t serial, uint32_t time, int32_t id)
+{
+  struct input *input = data;
+  struct touch_point *tp, *tmp;
+
+  if (!input->touch_focus) {
+    return;
+  }
+
+  wl_list_for_each_safe (tp, tmp, &input->touch_point_list, link) {
+    if (tp->id != id)
+      continue;
+
+    wl_list_remove (&tp->link);
+    free (tp);
+
+    return;
+  }
+}
+
+static const struct wl_touch_listener touch_listener = {
+  touch_handle_down,
+  touch_handle_up,
+  touch_handle_motion,
+  touch_handle_frame,
+  touch_handle_cancel,
+};
+
+
+
+static void
+seat_handle_capabilities (void *data, struct wl_seat *seat,
+    enum wl_seat_capability caps)
+{
+  struct input *input = data;
+
+  if ((caps & WL_SEAT_CAPABILITY_POINTER) && !input->pointer) {
+    input->pointer = wl_seat_get_pointer (seat);
+    wl_pointer_set_user_data (input->pointer, input);
+    wl_pointer_add_listener (input->pointer, &pointer_listener, input);
+  } else if (!(caps & WL_SEAT_CAPABILITY_POINTER) && input->pointer) {
+    wl_pointer_destroy (input->pointer);
+    input->pointer = NULL;
+  }
+
+  if ((caps & WL_SEAT_CAPABILITY_TOUCH) && !input->touch) {
+    input->touch = wl_seat_get_touch (seat);
+    wl_touch_set_user_data (input->touch, input);
+    wl_touch_add_listener (input->touch, &touch_listener, input);
+  } else if (!(caps & WL_SEAT_CAPABILITY_TOUCH) && input->touch) {
+    wl_touch_destroy (input->touch);
+    input->touch = NULL;
+  }
+}
+
+static void
+seat_handle_name (void *data, struct wl_seat *seat, const char *name)
+{
+
+}
+
+static const struct wl_seat_listener seat_listener = {
+  seat_handle_capabilities,
+  seat_handle_name
+};
+
+static void
+display_add_input (struct display *d, uint32_t id)
+{
+  struct input *input;
+
+  input = calloc (1, sizeof (*input));
+  if (input == NULL) {
+    fprintf (stderr, "%s: out of memory\n", "gst-wayland-sink");
+    exit (EXIT_FAILURE);
+  }
+  input->display = d;
+  input->seat = wl_registry_bind (d->registry, id, &wl_seat_interface,
+      MAX (d->seat_version, 3));
+  input->touch_focus = NULL;
+  input->pointer_focus = NULL;
+  wl_list_init (&input->touch_point_list);
+  wl_list_insert (d->input_list.prev, &input->link);
+
+  wl_seat_add_listener (input->seat, &seat_listener, input);
+  wl_seat_set_user_data (input->seat, input);
+
+}
+
 static void
 registry_handle_global (void *data, struct wl_registry *registry,
     uint32_t id, const char *interface, uint32_t version)
@@ -332,6 +608,9 @@ registry_handle_global (void *data, struct wl_registry *registry,
   } else if (strcmp (interface, "wl_shm") == 0) {
     d->shm = wl_registry_bind (registry, id, &wl_shm_interface, 1);
     wl_shm_add_listener (d->shm, &shm_listenter, d);
+  } else if (strcmp (interface, "wl_seat") == 0) {
+    d->seat_version = version;
+    display_add_input (d, id);
   }
 }
 
@@ -352,6 +631,8 @@ create_display (void)
     return NULL;
   }
 
+  wl_list_init (&display->input_list);
+
   display->registry = wl_display_get_registry (display->display);
   wl_registry_add_listener (display->registry, &registry_listener, display);
 
@@ -491,6 +772,8 @@ create_window (GstWaylandSink * sink, struct display *display, int width,
 
   window->surface = wl_compositor_create_surface (display->compositor);
 
+  wl_surface_set_user_data (window->surface, window);
+
   window->shell_surface = wl_shell_get_shell_surface (display->shell,
       window->surface);
 
diff --git a/ext/wayland/gstwaylandsink.h b/ext/wayland/gstwaylandsink.h
index cb3383e..f7d30dc 100644
--- a/ext/wayland/gstwaylandsink.h
+++ b/ext/wayland/gstwaylandsink.h
@@ -55,6 +55,27 @@
 #define GST_WAYLAND_SINK_GET_CLASS(inst) \
         (G_TYPE_INSTANCE_GET_CLASS ((inst), GST_TYPE_WAYLAND_SINK, GstWaylandSinkClass))
 
+struct touch_point
+{
+  int32_t id;
+  struct wl_list link;
+};
+
+struct input
+{
+  struct display *display;
+  struct wl_seat *seat;
+  struct wl_pointer *pointer;
+  struct wl_touch *touch;
+  struct wl_list touch_point_list;
+  struct window *pointer_focus;
+  struct window *touch_focus;
+  struct wl_list link;
+  struct window *grab;
+
+};
+
+
 struct  display
 {
   struct wl_display *display;
@@ -63,6 +84,11 @@ struct  display
   struct wl_shell *shell;
   struct wl_shm *shm;
   uint32_t formats;
+
+  struct wl_list input_list;
+  int seat_version;
+  uint32_t serial;
+
 };
 
 struct window
-- 
1.9.1