1 /* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2 /*
3    Copyright (C) 2010 Red Hat, Inc.
4 
5    This library is free software; you can redistribute it and/or
6    modify it under the terms of the GNU Lesser General Public
7    License as published by the Free Software Foundation; either
8    version 2.1 of the License, or (at your option) any later version.
9 
10    This library is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13    Lesser General Public License for more details.
14 
15    You should have received a copy of the GNU Lesser General Public
16    License along with this library; if not, see <http://www.gnu.org/licenses/>.
17 */
18 #ifndef __SPICE_WIDGET_PRIV_H__
19 #define __SPICE_WIDGET_PRIV_H__
20 
21 #include "config.h"
22 
23 #ifdef WIN32
24 #include <windows.h>
25 #endif
26 
27 #ifdef HAVE_EPOXY_EGL_H
28 #include <epoxy/egl.h>
29 #endif
30 
31 #include "spice-widget.h"
32 #include "spice-common.h"
33 #include "spice-gtk-session.h"
34 
35 #include <gst/video/videooverlay.h>
36 
37 G_BEGIN_DECLS
38 
39 #define DISPLAY_DEBUG(display, fmt, ...) \
40     SPICE_DEBUG("%d:%d " fmt, \
41                 SPICE_DISPLAY(display)->priv->channel_id, \
42                 SPICE_DISPLAY(display)->priv->monitor_id, \
43                 ## __VA_ARGS__)
44 
45 typedef struct _SpiceDisplayPrivate SpiceDisplayPrivate;
46 
47 struct _SpiceDisplay {
48     GtkEventBox parent;
49     SpiceDisplayPrivate *priv;
50 };
51 
52 struct _SpiceDisplayClass {
53     GtkEventBoxClass parent_class;
54 
55     /* signals */
56     void (*mouse_grab)(SpiceChannel *channel, gint grabbed);
57     void (*keyboard_grab)(SpiceChannel *channel, gint grabbed);
58 };
59 
60 struct _SpiceDisplayPrivate {
61     GtkStack                *stack;
62     GtkWidget               *label;
63     gint                    channel_id;
64     gint                    monitor_id;
65 
66     /* options */
67     bool                    keyboard_grab_enable;
68     gboolean                keyboard_grab_inhibit;
69     bool                    mouse_grab_enable;
70     bool                    resize_guest_enable;
71 
72     /* state */
73     gboolean                ready;
74     gboolean                monitor_ready;
75     struct {
76         enum SpiceSurfaceFmt    format;
77         gint                    width, height, stride;
78         gpointer                data_origin; /* the original display image data */
79         gpointer                data; /* converted if necessary to 32 bits */
80         bool                    convert;
81         cairo_surface_t         *surface;
82     } canvas;
83     GdkRectangle            area;
84     /* window border */
85     gint                    ww, wh, mx, my;
86 
87     gboolean                allow_scaling;
88     gboolean                only_downscale;
89     gboolean                disable_inputs;
90 
91     SpiceSession            *session;
92     SpiceGtkSession         *gtk_session;
93     SpiceMainChannel        *main;
94     SpiceDisplayChannel     *display;
95     SpiceCursorChannel      *cursor;
96     SpiceInputsChannel      *inputs;
97     SpiceSmartcardChannel   *smartcard;
98 
99     enum SpiceMouseMode     mouse_mode;
100     int                     mouse_grab_active;
101     bool                    mouse_have_pointer;
102     GdkCursor               *mouse_cursor;
103     GdkPixbuf               *mouse_pixbuf;
104     GdkPoint                mouse_hotspot;
105     GdkCursor               *show_cursor;
106     int                     mouse_last_x;
107     int                     mouse_last_y;
108     int                     mouse_guest_x;
109     int                     mouse_guest_y;
110 
111     bool                    keyboard_grab_active;
112     bool                    keyboard_have_focus;
113 
114     const guint16          *keycode_map;
115     size_t                  keycode_maplen;
116     uint32_t                key_state[512 / 32];
117     int                     key_delayed_scancode;
118     guint                   key_delayed_id;
119     SpiceGrabSequence         *grabseq; /* the configured key sequence */
120     gboolean                *activeseq; /* the currently pressed keys */
121     gboolean                seq_pressed;
122     gboolean                keyboard_grab_released;
123     gint                    mark;
124 #ifdef WIN32
125     HHOOK                   keyboard_hook;
126     int                     win_mouse[3];
127     int                     win_mouse_speed;
128 #endif
129     guint                   keypress_delay;
130     gint                    zoom_level;
131 #ifdef GDK_WINDOWING_X11
132     int                     x11_accel_numerator;
133     int                     x11_accel_denominator;
134     int                     x11_threshold;
135 #endif
136 #if HAVE_EGL
137     struct {
138         gboolean            context_ready;
139         gboolean            enabled;
140         EGLSurface          surface;
141         EGLDisplay          display;
142         EGLConfig           conf;
143         EGLContext          ctx;
144         gint                mproj, attr_pos, attr_tex;
145         guint               vbuf_id;
146         guint               tex_id;
147         guint               tex_pointer_id;
148         guint               prog;
149         EGLImageKHR         image;
150         gboolean            call_draw_done;
151         SpiceGlScanout      scanout;
152     } egl;
153 #endif // HAVE_EGL
154     double scroll_delta_y;
155     GWeakRef overlay_weak_ref;
156 };
157 
158 int      spice_cairo_image_create                 (SpiceDisplay *display);
159 void     spice_cairo_image_destroy                (SpiceDisplay *display);
160 void     spice_cairo_draw_event                   (SpiceDisplay *display, cairo_t *cr);
161 gboolean spice_cairo_is_scaled                    (SpiceDisplay *display);
162 void     spice_display_get_scaling           (SpiceDisplay *display, double *s, int *x, int *y, int *w, int *h);
163 gboolean spice_egl_init                      (SpiceDisplay *display, GError **err);
164 gboolean spice_egl_realize_display           (SpiceDisplay *display, GdkWindow *win,
165                                               GError **err);
166 void     spice_egl_unrealize_display         (SpiceDisplay *display);
167 void     spice_egl_update_display            (SpiceDisplay *display);
168 void     spice_egl_resize_display            (SpiceDisplay *display, int w, int h);
169 gboolean spice_egl_update_scanout            (SpiceDisplay *display,
170                                               const SpiceGlScanout *scanout,
171                                               GError **err);
172 void     spice_egl_cursor_set                (SpiceDisplay *display);
173 
174 #ifdef HAVE_EGL
175 void     spice_display_widget_gl_scanout     (SpiceDisplay *display);
176 #endif
177 void     spice_display_widget_update_monitor_area(SpiceDisplay *display);
178 
179 G_END_DECLS
180 
181 #endif
182