summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordiscomfitor <michael.blumenkrantz@gmail.com>2013-10-27 18:22:35 +0000
committerdiscomfitor <michael.blumenkrantz@gmail.com>2013-10-27 18:22:35 +0000
commit89e236f170829c2e7db86fe6c56effc36f8118a7 (patch)
treea3a559ee3aa6c3c1d1e83b267e18543f64deb5d9
parent022a75f5721656e119f2ee9cc64623cb00108638 (diff)
add spice-gtk patchHEADmaster
-rw-r--r--0001-evas-render-support.patch457
1 files changed, 457 insertions, 0 deletions
diff --git a/0001-evas-render-support.patch b/0001-evas-render-support.patch
new file mode 100644
index 0000000..3f9b546
--- /dev/null
+++ b/0001-evas-render-support.patch
@@ -0,0 +1,457 @@
1From e1ef4ae5dc17f0eedd6c3e16cbc6dea2753d0c52 Mon Sep 17 00:00:00 2001
2From: discomfitor <michael.blumenkrantz@gmail.com>
3Date: Sun, 8 Sep 2013 10:34:30 +0100
4Subject: [PATCH] evas render support
5
6---
7 configure.ac | 21 +++++-
8 gtk/Makefile.am | 9 +++
9 gtk/spice-widget-evas.c | 164 +++++++++++++++++++++++++++++++++++++++++++++
10 gtk/spice-widget-priv.h | 4 ++
11 gtk/spice-widget.c | 84 ++++++++++++-----------
12 spice-client-gtk-2.0.pc.in | 1 +
13 6 files changed, 244 insertions(+), 39 deletions(-)
14 create mode 100644 gtk/spice-widget-evas.c
15
16diff --git a/configure.ac b/configure.ac
17index bd59ccf..2077cb9 100644
18--- a/configure.ac
19+++ b/configure.ac
20@@ -216,6 +216,9 @@ fi
21 AC_ARG_WITH([x11],
22 AS_HELP_STRING([--with-x11], [Use x11/shm display backend instead of cairo @<:@default=no@:>@]))
23
24+AC_ARG_WITH([evas],
25+ AS_HELP_STRING([--with-evas], [Use evas backend instead of x11/cairo @<:@default=no@:>@]))
26+
27 AC_MSG_CHECKING([What rendering backend to use..])
28 if [test "x$with_x11" = "xyes" ]
29 then
30@@ -225,10 +228,25 @@ then
31 fi
32 AC_MSG_RESULT([x11])
33 AC_DEFINE([WITH_X11], 1, [Use X11 backend?])
34-else
35+elif [test "x$with_evas" = "xyes" ] ; then
36+ PKG_CHECK_MODULES([EVAS], [evas], [with_evas=yes], [with_evas=no])
37+fi
38+if [test "x$with_evas" = "xyes"] ; then
39+ AC_MSG_RESULT([evas])
40+ AC_DEFINE([WITH_EVAS], 1, [Use Evas backend])
41+ SPICE_GTK_REQUIRES+=" evas"
42+elif [test "x$with_x11" != "xyes" ] ; then
43 AC_MSG_RESULT([cairo])
44 fi
45+
46+if [test "x$with_evas" != "xyes"] ; then
47+ with_evas=
48+fi
49+
50 AM_CONDITIONAL([WITH_X11], [test "x$with_x11" = "xyes"])
51+AM_CONDITIONAL([WITH_EVAS], [test "x$with_evas" = "xyes"])
52+
53+AC_SUBST([with_evas])
54
55 AC_ARG_WITH([pnp-ids-path],
56 AC_HELP_STRING([--with-pnp-ids-path],
57@@ -688,6 +706,7 @@ AC_MSG_NOTICE([
58 Smartcard support: ${have_smartcard}
59 USB redirection support: ${have_usbredir}
60 Gtk: $GTK_API_VERSION
61+ Evas: $with_evas
62
63 Now type 'make' to build $PACKAGE
64
65diff --git a/gtk/Makefile.am b/gtk/Makefile.am
66index d1e6f66..d106263 100644
67--- a/gtk/Makefile.am
68+++ b/gtk/Makefile.am
69@@ -140,10 +140,19 @@ SPICE_GTK_SOURCES_COMMON += \
70 spice-widget-x11.c \
71 $(NULL)
72 else
73+if WITH_EVAS
74+SPICE_GTK_SOURCES_COMMON += \
75+ spice-widget-evas.c \
76+ $(NULL)
77+SPICE_COMMON_CPPFLAGS += @EVAS_CFLAGS@
78+SPICE_GTK_LIBADD_COMMON += @EVAS_LIBS@
79+
80+else
81 SPICE_GTK_SOURCES_COMMON += \
82 spice-widget-cairo.c \
83 $(NULL)
84 endif
85+endif
86
87 if HAVE_GTK_2
88 libspice_client_gtk_2_0_la_LDFLAGS = $(SPICE_GTK_LDFLAGS_COMMON)
89diff --git a/gtk/spice-widget-evas.c b/gtk/spice-widget-evas.c
90new file mode 100644
91index 0000000..6a108bc
92--- /dev/null
93+++ b/gtk/spice-widget-evas.c
94@@ -0,0 +1,164 @@
95+/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
96+/*
97+ Copyright (C) 2010 Red Hat, Inc.
98+
99+ This library is free software; you can redistribute it and/or
100+ modify it under the terms of the GNU Lesser General Public
101+ License as published by the Free Software Foundation; either
102+ version 2.1 of the License, or (at your option) any later version.
103+
104+ This library is distributed in the hope that it will be useful,
105+ but WITHOUT ANY WARRANTY; without even the implied warranty of
106+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
107+ Lesser General Public License for more details.
108+
109+ You should have received a copy of the GNU Lesser General Public
110+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
111+*/
112+#include "spice-widget.h"
113+#include "spice-widget-priv.h"
114+
115+#ifdef HAVE_CONFIG_H
116+#include "config.h"
117+#endif
118+
119+#include <Evas.h>
120+
121+G_GNUC_INTERNAL void spice_display_mouse_move(SpiceDisplay *display, int ex, int ey, int button_mask);
122+G_GNUC_INTERNAL void spice_display_mouse_button(SpiceDisplay *display, int bx, int by, int button, int button_mask, bool press);
123+
124+static int
125+button_mask_evas_to_spice(int button)
126+{
127+ int spice = 0;
128+
129+ if (button & (1 << 0))
130+ spice |= SPICE_MOUSE_BUTTON_MASK_LEFT;
131+ if (button & (1 << 1))
132+ spice |= SPICE_MOUSE_BUTTON_MASK_MIDDLE;
133+ if (button & (1 << 2))
134+ spice |= SPICE_MOUSE_BUTTON_MASK_RIGHT;
135+ return spice;
136+}
137+
138+static int
139+button_evas_to_spice(int evas)
140+{
141+ static const int map[] = {
142+ [ 1 ] = SPICE_MOUSE_BUTTON_LEFT,
143+ [ 2 ] = SPICE_MOUSE_BUTTON_MIDDLE,
144+ [ 3 ] = SPICE_MOUSE_BUTTON_RIGHT,
145+ [ 4 ] = SPICE_MOUSE_BUTTON_UP,
146+ [ 5 ] = SPICE_MOUSE_BUTTON_DOWN,
147+ };
148+
149+ if (evas < SPICE_N_ELEMENTS(map)) {
150+ return map [ evas ];
151+ }
152+ return 0;
153+}
154+
155+static void
156+_evas_mouse_move(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
157+{
158+ Evas_Event_Mouse_Move *ev = event_info;
159+
160+ spice_display_mouse_move(data, ev->cur.output.x, ev->cur.output.y, button_mask_evas_to_spice(ev->buttons));
161+}
162+
163+static void
164+_evas_mouse_down(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
165+{
166+ Evas_Event_Mouse_Down *ev = event_info;
167+
168+ spice_display_mouse_button(data, ev->output.x, ev->output.y, button_evas_to_spice(ev->button), 0, true);
169+}
170+
171+static void
172+_evas_mouse_up(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
173+{
174+ Evas_Event_Mouse_Up *ev = event_info;
175+
176+ spice_display_mouse_button(data, ev->output.x, ev->output.y, button_evas_to_spice(ev->button), 0, false);
177+}
178+
179+static void
180+_evas_mouse_in(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info)
181+{
182+ evas_object_focus_set(obj, EINA_TRUE);
183+}
184+
185+static void
186+_evas_mouse_out(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info)
187+{
188+ evas_object_focus_set(obj, EINA_FALSE);
189+}
190+
191+static void
192+_evas_key_down(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
193+{
194+ Evas_Event_Key_Down *ev = event_info;
195+ guint key = gdk_keyval_from_name(ev->keyname);
196+
197+ spice_display_send_keys(data, &key, 1, SPICE_DISPLAY_KEY_EVENT_PRESS);
198+}
199+
200+static void
201+_evas_key_up(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
202+{
203+ Evas_Event_Key_Up *ev = event_info;
204+ guint key = gdk_keyval_from_name(ev->keyname);
205+
206+ spice_display_send_keys(data, &key, 1, SPICE_DISPLAY_KEY_EVENT_RELEASE);
207+}
208+
209+G_GNUC_INTERNAL
210+int spicex_image_create(SpiceDisplay *display)
211+{
212+ SpiceDisplayPrivate *d = SPICE_DISPLAY_GET_PRIVATE(display);
213+
214+ if (d->ximage != NULL)
215+ return 0;
216+
217+ GObject *window = G_OBJECT(gtk_widget_get_toplevel(GTK_WIDGET(display)));
218+
219+ d->convert = false;
220+
221+ d->ximage = g_object_get_data(window, "evas_image");
222+ evas_object_event_callback_add(d->ximage, EVAS_CALLBACK_MOUSE_IN, _evas_mouse_in, display);
223+ evas_object_event_callback_add(d->ximage, EVAS_CALLBACK_MOUSE_OUT, _evas_mouse_out, display);
224+ evas_object_event_callback_add(d->ximage, EVAS_CALLBACK_MOUSE_MOVE, _evas_mouse_move, display);
225+ evas_object_event_callback_add(d->ximage, EVAS_CALLBACK_MOUSE_DOWN, _evas_mouse_down, display);
226+ evas_object_event_callback_add(d->ximage, EVAS_CALLBACK_MOUSE_UP, _evas_mouse_up, display);
227+ evas_object_event_callback_add(d->ximage, EVAS_CALLBACK_KEY_DOWN, _evas_key_down, display);
228+ evas_object_event_callback_add(d->ximage, EVAS_CALLBACK_KEY_UP, _evas_key_up, display);
229+ evas_object_image_size_set(d->ximage, d->width, d->height);
230+ evas_object_image_data_set(d->ximage, d->data);
231+ return 0;
232+}
233+
234+G_GNUC_INTERNAL
235+void spicex_image_destroy(SpiceDisplay *display)
236+{
237+ SpiceDisplayPrivate *d = SPICE_DISPLAY_GET_PRIVATE(display);
238+
239+ evas_object_event_callback_del_full(d->ximage, EVAS_CALLBACK_MOUSE_IN, _evas_mouse_in, display);
240+ evas_object_event_callback_del_full(d->ximage, EVAS_CALLBACK_MOUSE_OUT, _evas_mouse_out, display);
241+ evas_object_event_callback_del_full(d->ximage, EVAS_CALLBACK_MOUSE_MOVE, _evas_mouse_move, display);
242+ evas_object_event_callback_del_full(d->ximage, EVAS_CALLBACK_MOUSE_DOWN, _evas_mouse_down, display);
243+ evas_object_event_callback_del_full(d->ximage, EVAS_CALLBACK_MOUSE_UP, _evas_mouse_up, display);
244+ d->ximage = NULL;
245+}
246+
247+G_GNUC_INTERNAL
248+void spicex_expose_event(SpiceDisplay *display, GdkEventExpose *expose)
249+{
250+ /* WOOOOOOOOO SCENEGRAPH!!! */
251+ return;
252+}
253+
254+G_GNUC_INTERNAL
255+gboolean spicex_is_scaled(SpiceDisplay *display)
256+{
257+ return FALSE; /* backend doesn't support scaling yet */
258+}
259diff --git a/gtk/spice-widget-priv.h b/gtk/spice-widget-priv.h
260index 597ce10..1563893 100644
261--- a/gtk/spice-widget-priv.h
262+++ b/gtk/spice-widget-priv.h
263@@ -28,6 +28,8 @@ G_BEGIN_DECLS
264 #include <X11/Xlib.h>
265 #include <X11/extensions/XShm.h>
266 #include <gdk/gdkx.h>
267+#elif WITH_EVAS
268+#include <Evas.h>
269 #endif
270
271 #ifdef WIN32
272@@ -77,6 +79,8 @@ struct _SpiceDisplayPrivate {
273 XImage *ximage;
274 XShmSegmentInfo *shminfo;
275 GC gc;
276+#elif defined(WITH_EVAS)
277+ Evas_Object *ximage;
278 #else
279 cairo_surface_t *ximage;
280 #endif
281diff --git a/gtk/spice-widget.c b/gtk/spice-widget.c
282index d25edca..60b965e 100644
283--- a/gtk/spice-widget.c
284+++ b/gtk/spice-widget.c
285@@ -1542,25 +1542,23 @@ void spicex_transform_input (SpiceDisplay *display,
286 *input_y = floor (window_y * is);
287 }
288
289-static gboolean motion_event(GtkWidget *widget, GdkEventMotion *motion)
290+G_GNUC_INTERNAL
291+void spice_display_mouse_move(SpiceDisplay *display, int ex, int ey, int button_mask)
292 {
293- SpiceDisplay *display = SPICE_DISPLAY(widget);
294 SpiceDisplayPrivate *d = SPICE_DISPLAY_GET_PRIVATE(display);
295 int x, y;
296
297 if (!d->inputs)
298- return true;
299+ return;
300 if (d->disable_inputs)
301- return true;
302-
303- spicex_transform_input (display, motion->x, motion->y, &x, &y);
304-
305+ return;
306+ spicex_transform_input (display, ex, ey, &x, &y);
307 switch (d->mouse_mode) {
308 case SPICE_MOUSE_MODE_CLIENT:
309 if (x >= 0 && x < d->area.width &&
310 y >= 0 && y < d->area.height) {
311 spice_inputs_position(d->inputs, x, y, get_display_id(display),
312- button_mask_gdk_to_spice(motion->state));
313+ button_mask);
314 }
315 break;
316 case SPICE_MOUSE_MODE_SERVER:
317@@ -1568,19 +1566,27 @@ static gboolean motion_event(GtkWidget *widget, GdkEventMotion *motion)
318 gint dx = d->mouse_last_x != -1 ? x - d->mouse_last_x : 0;
319 gint dy = d->mouse_last_y != -1 ? y - d->mouse_last_y : 0;
320
321- spice_inputs_motion(d->inputs, dx, dy,
322- button_mask_gdk_to_spice(motion->state));
323+ spice_inputs_motion(d->inputs, dx, dy, button_mask);
324
325 d->mouse_last_x = x;
326 d->mouse_last_y = y;
327- if (dx != 0 || dy != 0)
328- mouse_wrap(display, motion);
329+#warning FIXME WRAP
330+ //if (dx != 0 || dy != 0)
331+ //mouse_wrap(display, motion);
332 }
333 break;
334 default:
335 g_warn_if_reached();
336 break;
337 }
338+
339+}
340+
341+static gboolean motion_event(GtkWidget *widget, GdkEventMotion *motion)
342+{
343+ SpiceDisplay *display = SPICE_DISPLAY(widget);
344+
345+ spice_display_mouse_move(display, motion->x, motion->y, button_mask_gdk_to_spice(motion->state));
346 return true;
347 }
348
349@@ -1613,32 +1619,28 @@ static gboolean scroll_event(GtkWidget *widget, GdkEventScroll *scroll)
350 return true;
351 }
352
353-static gboolean button_event(GtkWidget *widget, GdkEventButton *button)
354+G_GNUC_INTERNAL void
355+spice_display_mouse_button(SpiceDisplay *display, int bx, int by, int button, int button_mask, bool press)
356 {
357- SpiceDisplay *display = SPICE_DISPLAY(widget);
358 SpiceDisplayPrivate *d = SPICE_DISPLAY_GET_PRIVATE(display);
359 int x, y;
360
361- SPICE_DEBUG("%s %s: button %d, state 0x%x", __FUNCTION__,
362- button->type == GDK_BUTTON_PRESS ? "press" : "release",
363- button->button, button->state);
364-
365 if (d->disable_inputs)
366- return true;
367+ return;
368
369- spicex_transform_input (display, button->x, button->y, &x, &y);
370+ spicex_transform_input (display, bx, by, &x, &y);
371 if ((x < 0 || x >= d->area.width ||
372 y < 0 || y >= d->area.height) &&
373 d->mouse_mode == SPICE_MOUSE_MODE_CLIENT) {
374 /* rule out clicks in outside region */
375- return true;
376+ return;
377 }
378
379- gtk_widget_grab_focus(widget);
380+ gtk_widget_grab_focus(GTK_WIDGET(display));
381 if (d->mouse_mode == SPICE_MOUSE_MODE_SERVER) {
382 if (!d->mouse_grab_active) {
383 try_mouse_grab(display);
384- return true;
385+ return;
386 }
387 } else
388 /* allow to drag and drop between windows/displays:
389@@ -1656,22 +1658,23 @@ static gboolean button_event(GtkWidget *widget, GdkEventButton *button)
390 gdk_pointer_ungrab(GDK_CURRENT_TIME);
391
392 if (!d->inputs)
393- return true;
394+ return;
395
396- switch (button->type) {
397- case GDK_BUTTON_PRESS:
398- spice_inputs_button_press(d->inputs,
399- button_gdk_to_spice(button->button),
400- button_mask_gdk_to_spice(button->state));
401- break;
402- case GDK_BUTTON_RELEASE:
403- spice_inputs_button_release(d->inputs,
404- button_gdk_to_spice(button->button),
405- button_mask_gdk_to_spice(button->state));
406- break;
407- default:
408- break;
409- }
410+ if (press)
411+ spice_inputs_button_press(d->inputs, button, button_mask);
412+ else
413+ spice_inputs_button_release(d->inputs, button, button_mask);
414+}
415+
416+static gboolean button_event(GtkWidget *widget, GdkEventButton *button)
417+{
418+ SPICE_DEBUG("%s %s: button %d, state 0x%x", __FUNCTION__,
419+ button->type == GDK_BUTTON_PRESS ? "press" : "release",
420+ button->button, button->state);
421+ spice_display_mouse_button(SPICE_DISPLAY(widget), button->x, button->y,
422+ button_gdk_to_spice(button->button),
423+ button_mask_gdk_to_spice(button->state),
424+ button->type == GDK_BUTTON_PRESS);
425 return true;
426 }
427
428@@ -2156,9 +2159,14 @@ static void invalidate(SpiceChannel *channel,
429 x2 = ceil ((rect.x - d->area.x + rect.width) * s);
430 y2 = ceil ((rect.y - d->area.y + rect.height) * s);
431
432+#ifdef WITH_EVAS
433+ evas_object_image_data_update_add(d->ximage, display_x + x1, display_y + y1,
434+ x2 - x1, y2-y1);
435+#else
436 gtk_widget_queue_draw_area(GTK_WIDGET(display),
437 display_x + x1, display_y + y1,
438 x2 - x1, y2-y1);
439+#endif
440 }
441
442 static void mark(SpiceDisplay *display, gint mark)
443diff --git a/spice-client-gtk-2.0.pc.in b/spice-client-gtk-2.0.pc.in
444index a5b96e2..9526b11 100644
445--- a/spice-client-gtk-2.0.pc.in
446+++ b/spice-client-gtk-2.0.pc.in
447@@ -2,6 +2,7 @@ prefix=@prefix@
448 exec_prefix=@exec_prefix@
449 libdir=@libdir@
450 includedir=@includedir@
451+evas=@with_evas@
452
453 Name: spice-client-gtk-2.0
454 Description: SPICE Client Gtk 2.0 library
455--
4561.8.3.2
457