[PATCH weston 1/4 v2] Implement text cursor position protocol.
Kristian Høgsberg
hoegsberg at gmail.com
Tue May 22 09:32:59 PDT 2012
On Mon, May 21, 2012 at 03:21:24PM -0600, Scott Moreau wrote:
> Here we create a new client/compositor interface in weston to allow
> clients to report their x/y cursor position to the compositor. These
> values are then used to center the zoom area on this point. This
> is useful for everyone, especially people who are visually impaired.
> ---
>
> Rebased against master, 380deee3c7b18574d66511287bb01dde51027fbf
>
> clients/.gitignore | 2 +
> clients/Makefile.am | 6 ++-
> clients/terminal.c | 11 ++++-
> clients/window.c | 12 +++++
> clients/window.h | 3 +
> protocol/text-cursor-position.xml | 11 +++++
> src/.gitignore | 2 +
> src/Makefile.am | 5 ++
> src/compositor.c | 21 +++++++++
> src/compositor.h | 5 ++
> src/text-cursor-position.c | 86 +++++++++++++++++++++++++++++++++++++
> 11 files changed, 162 insertions(+), 2 deletions(-)
> create mode 100644 protocol/text-cursor-position.xml
> create mode 100644 src/text-cursor-position.c
>
> diff --git a/clients/.gitignore b/clients/.gitignore
> index 81dab06..e47d674 100644
> --- a/clients/.gitignore
> +++ b/clients/.gitignore
> @@ -10,6 +10,8 @@ libtoytoolkit.a
> resizor
> screenshooter-client-protocol.h
> screenshooter-protocol.c
> +text-cursor-position-client-protocol.h
> +text-cursor-position-protocol.c
> simple-egl
> simple-shm
> simple-touch
> diff --git a/clients/Makefile.am b/clients/Makefile.am
> index 93754d8..573cf59 100644
> --- a/clients/Makefile.am
> +++ b/clients/Makefile.am
> @@ -57,7 +57,9 @@ noinst_LIBRARIES = libtoytoolkit.a
>
> libtoytoolkit_a_SOURCES = \
> window.c \
> - window.h
> + window.h \
> + text-cursor-position-protocol.c \
> + text-cursor-position-client-protocol.h
>
> toolkit_libs = \
> libtoytoolkit.a \
> @@ -106,6 +108,8 @@ weston_tablet_shell_LDADD = $(toolkit_libs)
> BUILT_SOURCES = \
> screenshooter-client-protocol.h \
> screenshooter-protocol.c \
> + text-cursor-position-client-protocol.h \
> + text-cursor-position-protocol.c \
> desktop-shell-client-protocol.h \
> desktop-shell-protocol.c \
> tablet-shell-client-protocol.h \
> diff --git a/clients/terminal.c b/clients/terminal.c
> index c7300e6..5c5b6a4 100644
> --- a/clients/terminal.c
> +++ b/clients/terminal.c
> @@ -372,6 +372,7 @@ struct terminal {
> int data_pitch, attr_pitch; /* The width in bytes of a line */
> int width, height, start, row, column;
> int saved_row, saved_column;
> + int send_cursor_position;
> int fd, master;
> uint32_t modifiers;
> char escape[MAX_ESCAPE+1];
> @@ -926,7 +927,7 @@ redraw_handler(struct widget *widget, void *data)
> struct rectangle allocation;
> cairo_t *cr;
> int top_margin, side_margin;
> - int row, col;
> + int row, col, cursor_x, cursor_y;
> union utf8_char *p_row;
> union decoded_attr attr;
> int text_x, text_y;
> @@ -1022,6 +1023,13 @@ redraw_handler(struct widget *widget, void *data)
> cairo_paint(cr);
> cairo_destroy(cr);
> cairo_surface_destroy(surface);
> +
> + if (terminal->send_cursor_position) {
> + cursor_x = side_margin + allocation.x + terminal->column * extents.max_x_advance;
> + cursor_y = top_margin + allocation.y + terminal->row * extents.height;
> + window_set_text_cursor_position(terminal->window, cursor_x, cursor_y);
> + terminal->send_cursor_position = 0;
> + }
> }
>
> static void
> @@ -1029,6 +1037,7 @@ terminal_write(struct terminal *terminal, const char *data, size_t length)
> {
> if (write(terminal->master, data, length) < 0)
> abort();
> + terminal->send_cursor_position = 1;
Shouldn't we only update position when the user actually presses a
key? What if you're dumping a lot of data to the terminal?
> }
>
> static void
> diff --git a/clients/window.c b/clients/window.c
> index 5c4d28b..80b663f 100644
> --- a/clients/window.c
> +++ b/clients/window.c
> @@ -60,6 +60,7 @@
> #include <linux/input.h>
> #include <wayland-client.h>
> #include "../shared/cairo-util.h"
> +#include "text-cursor-position-client-protocol.h"
>
> #include "window.h"
>
> @@ -72,6 +73,7 @@ struct display {
> struct wl_shell *shell;
> struct wl_shm *shm;
> struct wl_data_device_manager *data_device_manager;
> + struct text_cursor_position *text_cursor_position;
> EGLDisplay dpy;
> EGLConfig argb_config;
> EGLContext argb_ctx;
> @@ -2568,6 +2570,13 @@ window_get_title(struct window *window)
> }
>
> void
> +window_set_text_cursor_position(struct window *window, int32_t x, int32_t y)
> +{
> + struct text_cursor_position *text_cursor_position = window->display->text_cursor_position;
Break the line after '='?
> + text_cursor_position_notify(text_cursor_position, window->surface, x, y);
> +}
Let's check for window->display->text_cursor_position == NULL so it
will work even if the compositor doesn't have that extension.
> +
> +void
> window_damage(struct window *window, int32_t x, int32_t y,
> int32_t width, int32_t height)
> {
> @@ -3055,6 +3064,9 @@ display_handle_global(struct wl_display *display, uint32_t id,
> d->data_device_manager =
> wl_display_bind(display, id,
> &wl_data_device_manager_interface);
> + } else if (strcmp(interface, "text_cursor_position") == 0) {
> + d->text_cursor_position =
> + wl_display_bind(display, id, &text_cursor_position_interface);
> }
> }
>
> diff --git a/clients/window.h b/clients/window.h
> index 162cc34..932f232 100644
> --- a/clients/window.h
> +++ b/clients/window.h
> @@ -308,6 +308,9 @@ window_set_title(struct window *window, const char *title);
> const char *
> window_get_title(struct window *window);
>
> +void
> +window_set_text_cursor_position(struct window *window, int32_t x, int32_t y);
> +
> struct widget *
> widget_add_widget(struct widget *parent, void *data);
> void
> diff --git a/protocol/text-cursor-position.xml b/protocol/text-cursor-position.xml
> new file mode 100644
> index 0000000..dbeda72
> --- /dev/null
> +++ b/protocol/text-cursor-position.xml
> @@ -0,0 +1,11 @@
> +<protocol name="text_cursor_position">
> +
> + <interface name="text_cursor_position" version="1">
> + <request name="notify">
> + <arg name="surface" type="object" interface="wl_surface"/>
> + <arg name="x" type="uint"/>
> + <arg name="y" type="uint"/>
> + </request>
> + </interface>
> +
> +</protocol>
> diff --git a/src/.gitignore b/src/.gitignore
> index 56fc1ae..eb3bbb5 100644
> --- a/src/.gitignore
> +++ b/src/.gitignore
> @@ -2,6 +2,8 @@ weston
> weston-launch
> screenshooter-protocol.c
> screenshooter-server-protocol.h
> +text-cursor-position-protocol.c
> +text-cursor-position-server-protocol.h
> tablet-shell-protocol.c
> tablet-shell-server-protocol.h
> xserver-protocol.c
> diff --git a/src/Makefile.am b/src/Makefile.am
> index 794b521..f74fd9a 100644
> --- a/src/Makefile.am
> +++ b/src/Makefile.am
> @@ -18,6 +18,9 @@ weston_SOURCES = \
> screenshooter.c \
> screenshooter-protocol.c \
> screenshooter-server-protocol.h \
> + text-cursor-position.c \
> + text-cursor-position-protocol.c \
> + text-cursor-position-server-protocol.h \
> util.c \
> matrix.c \
> matrix.h \
> @@ -144,6 +147,8 @@ endif
> BUILT_SOURCES = \
> screenshooter-server-protocol.h \
> screenshooter-protocol.c \
> + text-cursor-position-server-protocol.h \
> + text-cursor-position-protocol.c \
> tablet-shell-protocol.c \
> tablet-shell-server-protocol.h \
> desktop-shell-protocol.c \
> diff --git a/src/compositor.c b/src/compositor.c
> index ab4c970..06e944f 100644
> --- a/src/compositor.c
> +++ b/src/compositor.c
> @@ -2440,6 +2440,26 @@ weston_output_destroy(struct weston_output *output)
> }
>
> WL_EXPORT void
> +weston_text_cursor_position_notify(struct weston_surface *surface,
> + int32_t x, int32_t y)
> +{
> + struct weston_output *output;
> + int32_t surface_x, surface_y;
> + int32_t cur_pos_x, cur_pos_y;
> +
> + weston_surface_to_global(surface, 0, 0, &surface_x, &surface_y);
> +
> + cur_pos_x = surface_x + x;
> + cur_pos_y = surface_y + y;
This should just be
weston_surface_to_global(surface, x, y, &surface_x, &surface_y);
weston_surface_to_global() takes a coordinate in surface space (which
x, y is) and translates that into global space.
> + wl_list_for_each(output, &surface->compositor->output_list, link)
> + if (output->zoom.active &&
> + pixman_region32_contains_point(&output->region,
> + cur_pos_x, cur_pos_y, NULL))
> + weston_output_update_zoom(output, cur_pos_x * 256, cur_pos_y * 256);
Use wl_fixed_from_int here. Alternatively, just make the protocol
take wl_fixed_t for x and y (and change the client to send wl_fixed_t
x and y), and then use weston_surface_to_global_fixed().
> +}
> +
> +WL_EXPORT void
> weston_output_update_zoom(struct weston_output *output, wl_fixed_t fx, wl_fixed_t fy)
> {
> float ratio;
> @@ -2641,6 +2661,7 @@ weston_compositor_init(struct weston_compositor *ec, struct wl_display *display)
> weston_layer_init(&ec->cursor_layer, &ec->fade_layer.link);
>
> screenshooter_create(ec);
> + text_cursor_position_notifier_create(ec);
>
> ec->ping_handler = NULL;
>
> diff --git a/src/compositor.h b/src/compositor.h
> index 7af423d..59a97a7 100644
> --- a/src/compositor.h
> +++ b/src/compositor.h
> @@ -554,6 +554,8 @@ weston_compositor_shutdown(struct weston_compositor *ec);
> void
> weston_output_update_zoom(struct weston_output *output, int x, int y);
> void
> +weston_text_cursor_position_notify(struct weston_surface *surface, int x, int y);
> +void
> weston_output_update_matrix(struct weston_output *output);
> void
> weston_output_move(struct weston_output *output, int x, int y);
> @@ -589,6 +591,9 @@ tty_activate_vt(struct tty *tty, int vt);
> void
> screenshooter_create(struct weston_compositor *ec);
>
> +void
> +text_cursor_position_notifier_create(struct weston_compositor *ec);
> +
> struct weston_process;
> typedef void (*weston_process_cleanup_func_t)(struct weston_process *process,
> int status);
> diff --git a/src/text-cursor-position.c b/src/text-cursor-position.c
> new file mode 100644
> index 0000000..2c07dca
> --- /dev/null
> +++ b/src/text-cursor-position.c
> @@ -0,0 +1,86 @@
> +/*
> + * Copyright © 2012 Scott Moreau
> + *
> + * 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 <stdlib.h>
> +
> +#include "compositor.h"
> +#include "text-cursor-position-server-protocol.h"
> +
> +struct text_cursor_position {
> + struct wl_object base;
> + struct weston_compositor *ec;
> + struct wl_global *global;
> + struct wl_listener destroy_listener;
> +};
> +
> +static void
> +text_cursor_position_notify(struct wl_client *client,
> + struct wl_resource *resource,
> + struct wl_resource *surface_resource,
> + uint32_t x, uint32_t y)
> +{
> + weston_text_cursor_position_notify((struct weston_surface *) surface_resource, x, y);
> +}
> +
> +struct text_cursor_position_interface text_cursor_position_implementation = {
> + text_cursor_position_notify
> +};
> +
> +static void
> +bind_text_cursor_position(struct wl_client *client,
> + void *data, uint32_t version, uint32_t id)
> +{
> + wl_client_add_object(client, &text_cursor_position_interface,
> + &text_cursor_position_implementation, id, data);
> +}
> +
> +static void
> +text_cursor_position_notifier_destroy(struct wl_listener *listener, void *data)
> +{
> + struct text_cursor_position *text_cursor_position =
> + container_of(listener, struct text_cursor_position, destroy_listener);
> +
> + wl_display_remove_global(text_cursor_position->ec->wl_display, text_cursor_position->global);
> + free(text_cursor_position);
> +}
> +
> +void
> +text_cursor_position_notifier_create(struct weston_compositor *ec)
> +{
> + struct text_cursor_position *text_cursor_position;
> +
> + text_cursor_position = malloc(sizeof *text_cursor_position);
> + if (text_cursor_position == NULL)
> + return;
> +
> + text_cursor_position->base.interface = &text_cursor_position_interface;
> + text_cursor_position->base.implementation =
> + (void(**)(void)) &text_cursor_position_implementation;
> + text_cursor_position->ec = ec;
> +
> + text_cursor_position->global = wl_display_add_global(ec->wl_display,
> + &text_cursor_position_interface,
> + text_cursor_position, bind_text_cursor_position);
> +
> + text_cursor_position->destroy_listener.notify = text_cursor_position_notifier_destroy;
> + wl_signal_add(&ec->destroy_signal, &text_cursor_position->destroy_listener);
> +}
> --
> 1.7.7.6
>
> _______________________________________________
> wayland-devel mailing list
> wayland-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/wayland-devel
More information about the wayland-devel
mailing list