Merge lp:~kdub/mir/common-fd-type into lp:mir/ubuntu
- common-fd-type
- Merge into ubuntu
Proposed by
Kevin DuBois
Status: | Superseded |
---|---|
Proposed branch: | lp:~kdub/mir/common-fd-type |
Merge into: | lp:mir/ubuntu |
Diff against target: |
10587 lines (+4833/-1684) 165 files modified
3rd_party/CMakeLists.txt (+11/-1) 3rd_party/xcursor/CMakeLists.txt (+11/-0) 3rd_party/xcursor/xcursor.c (+968/-0) 3rd_party/xcursor/xcursor.h (+65/-0) CMakeLists.txt (+27/-9) debian/changelog (+25/-9) debian/control (+4/-0) debian/rules (+7/-0) examples/eglcounter.cpp (+1/-1) examples/egltriangle.c (+1/-1) examples/minimal_server.cpp (+9/-1) examples/multiwin.c (+10/-0) include/client/mir_toolkit/mir_prompt_session.h (+17/-0) include/platform/mir/graphics/cursor_image.h (+7/-0) include/platform/mir/options/configuration.h (+1/-0) include/server/mir/default_server_configuration.h (+19/-4) include/server/mir/frontend/fd_sets.h (+2/-2) include/server/mir/frontend/session_authorizer.h (+1/-0) include/server/mir/input/cursor_images.h (+11/-8) include/server/mir/server_configuration.h (+1/-0) include/shared/mir/basic_observers.h (+122/-0) include/shared/mir/fd.h (+43/-0) include/shared/mir/graphics/android/fence.h (+2/-1) include/shared/mir/graphics/android/sync_fence.h (+4/-4) include/shared/mir/recursive_read_write_mutex.h (+77/-0) include/test/mir_test_doubles/mock_buffer_registrar.h (+6/-6) include/test/mir_test_doubles/mock_fence.h (+4/-0) include/test/mir_test_doubles/mock_hwc_device_wrapper.h (+5/-0) include/test/mir_test_doubles/null_client_buffer.h (+2/-1) include/test/mir_test_doubles/stub_renderable.h (+6/-1) include/test/mir_test_doubles/stub_session_authorizer.h (+13/-9) include/test/mir_test_framework/in_process_server.h (+3/-0) include/test/mir_test_framework/server_runner.h (+3/-0) src/client/android/CMakeLists.txt (+1/-1) src/client/android/android_client_buffer_factory.cpp (+4/-2) src/client/android/android_client_buffer_factory.h (+8/-8) src/client/android/android_client_platform.cpp (+2/-2) src/client/android/buffer.cpp (+8/-2) src/client/android/buffer.h (+4/-3) src/client/android/buffer_registrar.h (+10/-6) src/client/android/client_surface_interpreter.cpp (+1/-1) src/client/android/gralloc_registrar.cpp (+6/-4) src/client/android/gralloc_registrar.h (+6/-6) src/client/client_buffer.h (+1/-0) src/client/client_buffer_depository.cpp (+1/-0) src/client/mesa/client_buffer.cpp (+4/-0) src/client/mesa/client_buffer.h (+1/-0) src/client/mir_prompt_session_api.cpp (+12/-0) src/platform/graphics/android/android_alloc_adaptor.cpp (+1/-1) src/platform/graphics/android/hwc_common_device.cpp (+21/-26) src/platform/graphics/android/hwc_common_device.h (+5/-4) src/platform/graphics/android/hwc_device.cpp (+71/-59) src/platform/graphics/android/hwc_device.h (+1/-9) src/platform/graphics/android/hwc_fb_device.cpp (+13/-11) src/platform/graphics/android/hwc_fb_device.h (+1/-2) src/platform/graphics/android/hwc_layerlist.cpp (+22/-22) src/platform/graphics/android/hwc_layerlist.h (+13/-8) src/platform/graphics/android/hwc_layers.cpp (+33/-45) src/platform/graphics/android/hwc_layers.h (+16/-14) src/platform/graphics/android/hwc_wrapper.h (+6/-0) src/platform/graphics/android/real_hwc_wrapper.cpp (+45/-0) src/platform/graphics/android/real_hwc_wrapper.h (+5/-0) src/platform/graphics/android/resource_factory.cpp (+2/-2) src/platform/graphics/mesa/cursor.cpp (+73/-20) src/platform/graphics/mesa/cursor.h (+8/-0) src/platform/graphics/mesa/display_buffer.cpp (+1/-1) src/platform/options/default_configuration.cpp (+2/-0) src/server/CMakeLists.txt (+4/-1) src/server/asio_main_loop.cpp (+13/-2) src/server/compositor/buffer_queue.cpp (+4/-0) src/server/compositor/buffer_queue.h (+1/-1) src/server/compositor/buffer_stream_factory.cpp (+1/-1) src/server/default_emergency_cleanup.cpp (+46/-0) src/server/default_emergency_cleanup.h (+53/-0) src/server/default_server_configuration.cpp (+8/-29) src/server/display_server.cpp (+12/-0) src/server/frontend/CMakeLists.txt (+2/-0) src/server/frontend/default_configuration.cpp (+85/-2) src/server/frontend/default_ipc_factory.cpp (+11/-3) src/server/frontend/default_ipc_factory.h (+7/-3) src/server/frontend/no_prompt_shell.cpp (+56/-0) src/server/frontend/no_prompt_shell.h (+52/-0) src/server/frontend/protobuf_message_processor.cpp (+21/-26) src/server/frontend/session_mediator.cpp (+4/-3) src/server/frontend/session_mediator.h (+5/-2) src/server/frontend/shell_wrapper.cpp (+74/-0) src/server/frontend/shell_wrapper.h (+70/-0) src/server/frontend/socket_messenger.cpp (+2/-2) src/server/frontend/socket_messenger.h (+1/-1) src/server/graphics/CMakeLists.txt (+0/-1) src/server/graphics/default_configuration.cpp (+14/-29) src/server/graphics/nested/nested_display.cpp (+0/-4) src/server/input/CMakeLists.txt (+8/-1) src/server/input/builtin_cursor_images.cpp (+7/-2) src/server/input/builtin_cursor_images.h (+7/-9) src/server/input/default_configuration.cpp (+43/-7) src/server/input/nested_input_configuration.cpp (+0/-37) src/server/input/nested_input_configuration.h (+0/-43) src/server/input/xcursor_loader.cpp (+152/-0) src/server/input/xcursor_loader.h (+71/-0) src/server/run_mir.cpp (+5/-2) src/server/scene/basic_surface.cpp (+23/-58) src/server/scene/basic_surface.h (+4/-8) src/server/scene/surface_stack.cpp (+12/-40) src/server/scene/surface_stack.h (+5/-7) src/shared/CMakeLists.txt (+2/-1) src/shared/fd/CMakeLists.txt (+23/-0) src/shared/fd/fd.cpp (+49/-0) src/shared/graphics/android/CMakeLists.txt (+2/-0) src/shared/graphics/android/android_native_buffer.cpp (+1/-1) src/shared/graphics/android/syncfence.cpp (+7/-17) src/shared/protobuf/mir_protobuf.proto (+0/-2) src/shared/thread/CMakeLists.txt (+3/-2) src/shared/thread/recursive_read_write_mutex.cpp (+87/-0) tests/acceptance-tests/test_client_authorization.cpp (+1/-0) tests/acceptance-tests/test_client_cursor_api.cpp (+9/-3) tests/acceptance-tests/test_client_surface_events.cpp (+17/-4) tests/acceptance-tests/test_nested_mir.cpp (+184/-140) tests/acceptance-tests/test_prompt_session_client_api.cpp (+249/-64) tests/acceptance-tests/test_protobuf.cpp (+1/-1) tests/acceptance-tests/test_server_shutdown.cpp (+8/-7) tests/integration-tests/client/test_client_render.cpp (+2/-2) tests/integration-tests/client/test_screencast.cpp (+0/-12) tests/integration-tests/input/test_nested_input.cpp (+3/-8) tests/integration-tests/test_error_reporting.cpp (+2/-12) tests/integration-tests/test_surfaceloop.cpp (+23/-11) tests/mir_test_framework/server_runner.cpp (+7/-0) tests/mir_test_framework/testing_client_options.cpp (+3/-0) tests/unit-tests/CMakeLists.txt (+5/-0) tests/unit-tests/client/android/CMakeLists.txt (+1/-1) tests/unit-tests/client/android/test_android_native_window.cpp (+0/-1) tests/unit-tests/client/android/test_buffer.cpp (+3/-3) tests/unit-tests/client/android/test_client_surface_interpreter.cpp (+2/-1) tests/unit-tests/client/android/test_gralloc_registrar.cpp (+117/-202) tests/unit-tests/client/mesa/test_native_surface.cpp (+1/-1) tests/unit-tests/client/test_aging_buffer.cpp (+4/-0) tests/unit-tests/client/test_client_buffer_depository.cpp (+58/-54) tests/unit-tests/client/test_client_mir_surface.cpp (+2/-0) tests/unit-tests/client/test_event_distributor.cpp (+9/-1) tests/unit-tests/compositor/test_buffer_queue.cpp (+14/-43) tests/unit-tests/frontend/CMakeLists.txt (+0/-12) tests/unit-tests/frontend/test_protobuf_reports_errors.cpp (+0/-9) tests/unit-tests/frontend/test_protobuf_sends_fds.cpp (+0/-137) tests/unit-tests/frontend/test_session_mediator.cpp (+1/-1) tests/unit-tests/graphics/android/test_hwc_common_device.cpp (+59/-115) tests/unit-tests/graphics/android/test_hwc_device.cpp (+195/-90) tests/unit-tests/graphics/android/test_hwc_fb_device.cpp (+18/-12) tests/unit-tests/graphics/android/test_hwc_layerlist.cpp (+47/-4) tests/unit-tests/graphics/android/test_hwc_layers.cpp (+44/-36) tests/unit-tests/graphics/android/test_hwc_wrapper.cpp (+70/-0) tests/unit-tests/graphics/android/test_sync_fence.cpp (+17/-16) tests/unit-tests/graphics/mesa/test_cursor.cpp (+104/-17) tests/unit-tests/input/CMakeLists.txt (+1/-0) tests/unit-tests/input/test_cursor_controller.cpp (+1/-0) tests/unit-tests/input/test_xcursor_loader.cpp (+157/-0) tests/unit-tests/input/testing-cursor-theme/default/cursors/arrow.in (+1/-0) tests/unit-tests/input/testing-cursor-theme/default/cursors/blue.in (+1/-0) tests/unit-tests/input/testing-cursor-theme/default/cursors/generate-theme.sh (+5/-0) tests/unit-tests/input/testing-cursor-theme/default/cursors/green.in (+1/-0) tests/unit-tests/input/testing-cursor-theme/default/cursors/red.in (+1/-0) tests/unit-tests/scene/test_basic_surface.cpp (+84/-0) tests/unit-tests/scene/test_surface_stack.cpp (+56/-0) tests/unit-tests/test_asio_main_loop.cpp (+46/-0) tests/unit-tests/test_default_emergency_cleanup.cpp (+70/-0) tests/unit-tests/test_recursive_read_write_mutex.cpp (+176/-0) |
To merge this branch: | bzr merge lp:~kdub/mir/common-fd-type |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Mir development team | Pending | ||
Review via email: mp+226530@code.launchpad.net |
Commit message
add a common raii-friendly type for managing file descriptors.
Description of the change
add a common raii-friendly type for managing file descriptors, and have the protobuf sender and the android sync fences convert to using the new fence as a start. This is useful for me in sending a new fd on every send message, as I can just move the fence fd around.
We had a few things floating around for fd's... most of them just ints with close() in the right location. This mp aims to improve this situation a bit.
To post a comment you must log in.
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file '3rd_party/CMakeLists.txt' |
2 | --- 3rd_party/CMakeLists.txt 2013-08-28 03:41:48 +0000 |
3 | +++ 3rd_party/CMakeLists.txt 2014-07-11 20:27:44 +0000 |
4 | @@ -25,8 +25,18 @@ |
5 | MIR_ANDROID_INPUT_COMPILE_FLAGS |
6 | ${MIR_ANDROID_INPUT_COMPILE_FLAGS} |
7 | PARENT_SCOPE) |
8 | + |
9 | +add_subdirectory(xcursor) |
10 | +list( |
11 | + APPEND MIR_XCURSOR_INCLUDE_DIRECTORIES |
12 | + ${CMAKE_CURRENT_SOURCE_DIR}/xcursor/ |
13 | +) |
14 | + |
15 | +set(MIR_XCURSOR_INCLUDE_DIRECTORIES ${MIR_XCURSOR_INCLUDE_DIRECTORIES} PARENT_SCOPE) |
16 | |
17 | target_link_libraries( |
18 | 3rd_party |
19 | |
20 | - android-input) |
21 | + android-input |
22 | + xcursorloader |
23 | +) |
24 | |
25 | === added directory '3rd_party/xcursor' |
26 | === added file '3rd_party/xcursor/CMakeLists.txt' |
27 | --- 3rd_party/xcursor/CMakeLists.txt 1970-01-01 00:00:00 +0000 |
28 | +++ 3rd_party/xcursor/CMakeLists.txt 2014-07-11 20:27:44 +0000 |
29 | @@ -0,0 +1,11 @@ |
30 | +set( |
31 | + XCURSOR_SOURCES |
32 | + |
33 | + xcursor.c |
34 | +) |
35 | + |
36 | +add_library( |
37 | + xcursorloader STATIC |
38 | + |
39 | + ${XCURSOR_SOURCES} |
40 | +) |
41 | |
42 | === added file '3rd_party/xcursor/xcursor.c' |
43 | --- 3rd_party/xcursor/xcursor.c 1970-01-01 00:00:00 +0000 |
44 | +++ 3rd_party/xcursor/xcursor.c 2014-07-11 20:27:44 +0000 |
45 | @@ -0,0 +1,968 @@ |
46 | +/* |
47 | + * Copyright © 2002 Keith Packard |
48 | + * |
49 | + * Permission to use, copy, modify, distribute, and sell this software and its |
50 | + * documentation for any purpose is hereby granted without fee, provided that |
51 | + * the above copyright notice appear in all copies and that both that |
52 | + * copyright notice and this permission notice appear in supporting |
53 | + * documentation, and that the name of Keith Packard not be used in |
54 | + * advertising or publicity pertaining to distribution of the software without |
55 | + * specific, written prior permission. Keith Packard makes no |
56 | + * representations about the suitability of this software for any purpose. It |
57 | + * is provided "as is" without express or implied warranty. |
58 | + * |
59 | + * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, |
60 | + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO |
61 | + * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR |
62 | + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, |
63 | + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER |
64 | + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR |
65 | + * PERFORMANCE OF THIS SOFTWARE. |
66 | + */ |
67 | + |
68 | +#include "xcursor.h" |
69 | +#include <stdio.h> |
70 | +#include <stdlib.h> |
71 | +#include <string.h> |
72 | +#include <dirent.h> |
73 | + |
74 | +/* |
75 | + * From libXcursor/include/X11/extensions/Xcursor.h |
76 | + */ |
77 | + |
78 | +#define XcursorTrue 1 |
79 | +#define XcursorFalse 0 |
80 | + |
81 | +/* |
82 | + * Cursor files start with a header. The header |
83 | + * contains a magic number, a version number and a |
84 | + * table of contents which has type and offset information |
85 | + * for the remaining tables in the file. |
86 | + * |
87 | + * File minor versions increment for compatible changes |
88 | + * File major versions increment for incompatible changes (never, we hope) |
89 | + * |
90 | + * Chunks of the same type are always upward compatible. Incompatible |
91 | + * changes are made with new chunk types; the old data can remain under |
92 | + * the old type. Upward compatible changes can add header data as the |
93 | + * header lengths are specified in the file. |
94 | + * |
95 | + * File: |
96 | + * FileHeader |
97 | + * LISTofChunk |
98 | + * |
99 | + * FileHeader: |
100 | + * CARD32 magic magic number |
101 | + * CARD32 header bytes in file header |
102 | + * CARD32 version file version |
103 | + * CARD32 ntoc number of toc entries |
104 | + * LISTofFileToc toc table of contents |
105 | + * |
106 | + * FileToc: |
107 | + * CARD32 type entry type |
108 | + * CARD32 subtype entry subtype (size for images) |
109 | + * CARD32 position absolute file position |
110 | + */ |
111 | + |
112 | +#define XCURSOR_MAGIC 0x72756358 /* "Xcur" LSBFirst */ |
113 | + |
114 | +/* |
115 | + * Current Xcursor version number. Will be substituted by configure |
116 | + * from the version in the libXcursor configure.ac file. |
117 | + */ |
118 | + |
119 | +#define XCURSOR_LIB_MAJOR 1 |
120 | +#define XCURSOR_LIB_MINOR 1 |
121 | +#define XCURSOR_LIB_REVISION 13 |
122 | +#define XCURSOR_LIB_VERSION ((XCURSOR_LIB_MAJOR * 10000) + \ |
123 | + (XCURSOR_LIB_MINOR * 100) + \ |
124 | + (XCURSOR_LIB_REVISION)) |
125 | + |
126 | +/* |
127 | + * This version number is stored in cursor files; changes to the |
128 | + * file format require updating this version number |
129 | + */ |
130 | +#define XCURSOR_FILE_MAJOR 1 |
131 | +#define XCURSOR_FILE_MINOR 0 |
132 | +#define XCURSOR_FILE_VERSION ((XCURSOR_FILE_MAJOR << 16) | (XCURSOR_FILE_MINOR)) |
133 | +#define XCURSOR_FILE_HEADER_LEN (4 * 4) |
134 | +#define XCURSOR_FILE_TOC_LEN (3 * 4) |
135 | + |
136 | +typedef struct _XcursorFileToc { |
137 | + XcursorUInt type; /* chunk type */ |
138 | + XcursorUInt subtype; /* subtype (size for images) */ |
139 | + XcursorUInt position; /* absolute position in file */ |
140 | +} XcursorFileToc; |
141 | + |
142 | +typedef struct _XcursorFileHeader { |
143 | + XcursorUInt magic; /* magic number */ |
144 | + XcursorUInt header; /* byte length of header */ |
145 | + XcursorUInt version; /* file version number */ |
146 | + XcursorUInt ntoc; /* number of toc entries */ |
147 | + XcursorFileToc *tocs; /* table of contents */ |
148 | +} XcursorFileHeader; |
149 | + |
150 | +/* |
151 | + * The rest of the file is a list of chunks, each tagged by type |
152 | + * and version. |
153 | + * |
154 | + * Chunk: |
155 | + * ChunkHeader |
156 | + * <extra type-specific header fields> |
157 | + * <type-specific data> |
158 | + * |
159 | + * ChunkHeader: |
160 | + * CARD32 header bytes in chunk header + type header |
161 | + * CARD32 type chunk type |
162 | + * CARD32 subtype chunk subtype |
163 | + * CARD32 version chunk type version |
164 | + */ |
165 | + |
166 | +#define XCURSOR_CHUNK_HEADER_LEN (4 * 4) |
167 | + |
168 | +typedef struct _XcursorChunkHeader { |
169 | + XcursorUInt header; /* bytes in chunk header */ |
170 | + XcursorUInt type; /* chunk type */ |
171 | + XcursorUInt subtype; /* chunk subtype (size for images) */ |
172 | + XcursorUInt version; /* version of this type */ |
173 | +} XcursorChunkHeader; |
174 | + |
175 | +/* |
176 | + * Here's a list of the known chunk types |
177 | + */ |
178 | + |
179 | +/* |
180 | + * Comments consist of a 4-byte length field followed by |
181 | + * UTF-8 encoded text |
182 | + * |
183 | + * Comment: |
184 | + * ChunkHeader header chunk header |
185 | + * CARD32 length bytes in text |
186 | + * LISTofCARD8 text UTF-8 encoded text |
187 | + */ |
188 | + |
189 | +#define XCURSOR_COMMENT_TYPE 0xfffe0001 |
190 | +#define XCURSOR_COMMENT_VERSION 1 |
191 | +#define XCURSOR_COMMENT_HEADER_LEN (XCURSOR_CHUNK_HEADER_LEN + (1 *4)) |
192 | +#define XCURSOR_COMMENT_COPYRIGHT 1 |
193 | +#define XCURSOR_COMMENT_LICENSE 2 |
194 | +#define XCURSOR_COMMENT_OTHER 3 |
195 | +#define XCURSOR_COMMENT_MAX_LEN 0x100000 |
196 | + |
197 | +typedef struct _XcursorComment { |
198 | + XcursorUInt version; |
199 | + XcursorUInt comment_type; |
200 | + char *comment; |
201 | +} XcursorComment; |
202 | + |
203 | +/* |
204 | + * Each cursor image occupies a separate image chunk. |
205 | + * The length of the image header follows the chunk header |
206 | + * so that future versions can extend the header without |
207 | + * breaking older applications |
208 | + * |
209 | + * Image: |
210 | + * ChunkHeader header chunk header |
211 | + * CARD32 width actual width |
212 | + * CARD32 height actual height |
213 | + * CARD32 xhot hot spot x |
214 | + * CARD32 yhot hot spot y |
215 | + * CARD32 delay animation delay |
216 | + * LISTofCARD32 pixels ARGB pixels |
217 | + */ |
218 | + |
219 | +#define XCURSOR_IMAGE_TYPE 0xfffd0002 |
220 | +#define XCURSOR_IMAGE_VERSION 1 |
221 | +#define XCURSOR_IMAGE_HEADER_LEN (XCURSOR_CHUNK_HEADER_LEN + (5*4)) |
222 | +#define XCURSOR_IMAGE_MAX_SIZE 0x7fff /* 32767x32767 max cursor size */ |
223 | + |
224 | +typedef struct _XcursorFile XcursorFile; |
225 | + |
226 | +struct _XcursorFile { |
227 | + void *closure; |
228 | + int (*read) (XcursorFile *file, unsigned char *buf, int len); |
229 | + int (*write) (XcursorFile *file, unsigned char *buf, int len); |
230 | + int (*seek) (XcursorFile *file, long offset, int whence); |
231 | +}; |
232 | + |
233 | +typedef struct _XcursorComments { |
234 | + int ncomment; /* number of comments */ |
235 | + XcursorComment **comments; /* array of XcursorComment pointers */ |
236 | +} XcursorComments; |
237 | + |
238 | +/* |
239 | + * From libXcursor/src/file.c |
240 | + */ |
241 | + |
242 | +static XcursorImage * |
243 | +XcursorImageCreate (int width, int height) |
244 | +{ |
245 | + XcursorImage *image; |
246 | + |
247 | + image = malloc (sizeof (XcursorImage) + |
248 | + width * height * sizeof (XcursorPixel)); |
249 | + if (!image) |
250 | + return NULL; |
251 | + image->version = XCURSOR_IMAGE_VERSION; |
252 | + image->pixels = (XcursorPixel *) (image + 1); |
253 | + image->size = width > height ? width : height; |
254 | + image->width = width; |
255 | + image->height = height; |
256 | + image->delay = 0; |
257 | + return image; |
258 | +} |
259 | + |
260 | +static void |
261 | +XcursorImageDestroy (XcursorImage *image) |
262 | +{ |
263 | + free (image); |
264 | +} |
265 | + |
266 | +static XcursorImages * |
267 | +XcursorImagesCreate (int size) |
268 | +{ |
269 | + XcursorImages *images; |
270 | + |
271 | + images = malloc (sizeof (XcursorImages) + |
272 | + size * sizeof (XcursorImage *)); |
273 | + if (!images) |
274 | + return NULL; |
275 | + images->nimage = 0; |
276 | + images->images = (XcursorImage **) (images + 1); |
277 | + images->name = NULL; |
278 | + return images; |
279 | +} |
280 | + |
281 | +void |
282 | +XcursorImagesDestroy (XcursorImages *images) |
283 | +{ |
284 | + int n; |
285 | + |
286 | + if (!images) |
287 | + return; |
288 | + |
289 | + for (n = 0; n < images->nimage; n++) |
290 | + XcursorImageDestroy (images->images[n]); |
291 | + if (images->name) |
292 | + free (images->name); |
293 | + free (images); |
294 | +} |
295 | + |
296 | +static void |
297 | +XcursorImagesSetName (XcursorImages *images, const char *name) |
298 | +{ |
299 | + char *new; |
300 | + |
301 | + if (!images || !name) |
302 | + return; |
303 | + |
304 | + new = malloc (strlen (name) + 1); |
305 | + |
306 | + if (!new) |
307 | + return; |
308 | + |
309 | + strcpy (new, name); |
310 | + if (images->name) |
311 | + free (images->name); |
312 | + images->name = new; |
313 | +} |
314 | + |
315 | +static XcursorBool |
316 | +_XcursorReadUInt (XcursorFile *file, XcursorUInt *u) |
317 | +{ |
318 | + unsigned char bytes[4]; |
319 | + |
320 | + if (!file || !u) |
321 | + return XcursorFalse; |
322 | + |
323 | + if ((*file->read) (file, bytes, 4) != 4) |
324 | + return XcursorFalse; |
325 | + *u = ((bytes[0] << 0) | |
326 | + (bytes[1] << 8) | |
327 | + (bytes[2] << 16) | |
328 | + (bytes[3] << 24)); |
329 | + return XcursorTrue; |
330 | +} |
331 | + |
332 | +static void |
333 | +_XcursorFileHeaderDestroy (XcursorFileHeader *fileHeader) |
334 | +{ |
335 | + free (fileHeader); |
336 | +} |
337 | + |
338 | +static XcursorFileHeader * |
339 | +_XcursorFileHeaderCreate (int ntoc) |
340 | +{ |
341 | + XcursorFileHeader *fileHeader; |
342 | + |
343 | + if (ntoc > 0x10000) |
344 | + return NULL; |
345 | + fileHeader = malloc (sizeof (XcursorFileHeader) + |
346 | + ntoc * sizeof (XcursorFileToc)); |
347 | + if (!fileHeader) |
348 | + return NULL; |
349 | + fileHeader->magic = XCURSOR_MAGIC; |
350 | + fileHeader->header = XCURSOR_FILE_HEADER_LEN; |
351 | + fileHeader->version = XCURSOR_FILE_VERSION; |
352 | + fileHeader->ntoc = ntoc; |
353 | + fileHeader->tocs = (XcursorFileToc *) (fileHeader + 1); |
354 | + return fileHeader; |
355 | +} |
356 | + |
357 | +static XcursorFileHeader * |
358 | +_XcursorReadFileHeader (XcursorFile *file) |
359 | +{ |
360 | + XcursorFileHeader head, *fileHeader; |
361 | + XcursorUInt skip; |
362 | + unsigned int n; |
363 | + |
364 | + if (!file) |
365 | + return NULL; |
366 | + |
367 | + if (!_XcursorReadUInt (file, &head.magic)) |
368 | + return NULL; |
369 | + if (head.magic != XCURSOR_MAGIC) |
370 | + return NULL; |
371 | + if (!_XcursorReadUInt (file, &head.header)) |
372 | + return NULL; |
373 | + if (!_XcursorReadUInt (file, &head.version)) |
374 | + return NULL; |
375 | + if (!_XcursorReadUInt (file, &head.ntoc)) |
376 | + return NULL; |
377 | + skip = head.header - XCURSOR_FILE_HEADER_LEN; |
378 | + if (skip) |
379 | + if ((*file->seek) (file, skip, SEEK_CUR) == EOF) |
380 | + return NULL; |
381 | + fileHeader = _XcursorFileHeaderCreate (head.ntoc); |
382 | + if (!fileHeader) |
383 | + return NULL; |
384 | + fileHeader->magic = head.magic; |
385 | + fileHeader->header = head.header; |
386 | + fileHeader->version = head.version; |
387 | + fileHeader->ntoc = head.ntoc; |
388 | + for (n = 0; n < fileHeader->ntoc; n++) |
389 | + { |
390 | + if (!_XcursorReadUInt (file, &fileHeader->tocs[n].type)) |
391 | + break; |
392 | + if (!_XcursorReadUInt (file, &fileHeader->tocs[n].subtype)) |
393 | + break; |
394 | + if (!_XcursorReadUInt (file, &fileHeader->tocs[n].position)) |
395 | + break; |
396 | + } |
397 | + if (n != fileHeader->ntoc) |
398 | + { |
399 | + _XcursorFileHeaderDestroy (fileHeader); |
400 | + return NULL; |
401 | + } |
402 | + return fileHeader; |
403 | +} |
404 | + |
405 | +static XcursorBool |
406 | +_XcursorSeekToToc (XcursorFile *file, |
407 | + XcursorFileHeader *fileHeader, |
408 | + int toc) |
409 | +{ |
410 | + if (!file || !fileHeader || \ |
411 | + (*file->seek) (file, fileHeader->tocs[toc].position, SEEK_SET) == EOF) |
412 | + return XcursorFalse; |
413 | + return XcursorTrue; |
414 | +} |
415 | + |
416 | +static XcursorBool |
417 | +_XcursorFileReadChunkHeader (XcursorFile *file, |
418 | + XcursorFileHeader *fileHeader, |
419 | + int toc, |
420 | + XcursorChunkHeader *chunkHeader) |
421 | +{ |
422 | + if (!file || !fileHeader || !chunkHeader) |
423 | + return XcursorFalse; |
424 | + if (!_XcursorSeekToToc (file, fileHeader, toc)) |
425 | + return XcursorFalse; |
426 | + if (!_XcursorReadUInt (file, &chunkHeader->header)) |
427 | + return XcursorFalse; |
428 | + if (!_XcursorReadUInt (file, &chunkHeader->type)) |
429 | + return XcursorFalse; |
430 | + if (!_XcursorReadUInt (file, &chunkHeader->subtype)) |
431 | + return XcursorFalse; |
432 | + if (!_XcursorReadUInt (file, &chunkHeader->version)) |
433 | + return XcursorFalse; |
434 | + /* sanity check */ |
435 | + if (chunkHeader->type != fileHeader->tocs[toc].type || |
436 | + chunkHeader->subtype != fileHeader->tocs[toc].subtype) |
437 | + return XcursorFalse; |
438 | + return XcursorTrue; |
439 | +} |
440 | + |
441 | +#define dist(a,b) ((a) > (b) ? (a) - (b) : (b) - (a)) |
442 | + |
443 | +static XcursorDim |
444 | +_XcursorFindBestSize (XcursorFileHeader *fileHeader, |
445 | + XcursorDim size, |
446 | + int *nsizesp) |
447 | +{ |
448 | + unsigned int n; |
449 | + int nsizes = 0; |
450 | + XcursorDim bestSize = 0; |
451 | + XcursorDim thisSize; |
452 | + |
453 | + if (!fileHeader || !nsizesp) |
454 | + return 0; |
455 | + |
456 | + for (n = 0; n < fileHeader->ntoc; n++) |
457 | + { |
458 | + if (fileHeader->tocs[n].type != XCURSOR_IMAGE_TYPE) |
459 | + continue; |
460 | + thisSize = fileHeader->tocs[n].subtype; |
461 | + if (!bestSize || dist (thisSize, size) < dist (bestSize, size)) |
462 | + { |
463 | + bestSize = thisSize; |
464 | + nsizes = 1; |
465 | + } |
466 | + else if (thisSize == bestSize) |
467 | + nsizes++; |
468 | + } |
469 | + *nsizesp = nsizes; |
470 | + return bestSize; |
471 | +} |
472 | + |
473 | +static int |
474 | +_XcursorFindImageToc (XcursorFileHeader *fileHeader, |
475 | + XcursorDim size, |
476 | + int count) |
477 | +{ |
478 | + unsigned int toc; |
479 | + XcursorDim thisSize; |
480 | + |
481 | + if (!fileHeader) |
482 | + return 0; |
483 | + |
484 | + for (toc = 0; toc < fileHeader->ntoc; toc++) |
485 | + { |
486 | + if (fileHeader->tocs[toc].type != XCURSOR_IMAGE_TYPE) |
487 | + continue; |
488 | + thisSize = fileHeader->tocs[toc].subtype; |
489 | + if (thisSize != size) |
490 | + continue; |
491 | + if (!count) |
492 | + break; |
493 | + count--; |
494 | + } |
495 | + if (toc == fileHeader->ntoc) |
496 | + return -1; |
497 | + return toc; |
498 | +} |
499 | + |
500 | +static XcursorImage * |
501 | +_XcursorReadImage (XcursorFile *file, |
502 | + XcursorFileHeader *fileHeader, |
503 | + int toc) |
504 | +{ |
505 | + XcursorChunkHeader chunkHeader; |
506 | + XcursorImage head; |
507 | + XcursorImage *image; |
508 | + int n; |
509 | + XcursorPixel *p; |
510 | + |
511 | + if (!file || !fileHeader) |
512 | + return NULL; |
513 | + |
514 | + if (!_XcursorFileReadChunkHeader (file, fileHeader, toc, &chunkHeader)) |
515 | + return NULL; |
516 | + if (!_XcursorReadUInt (file, &head.width)) |
517 | + return NULL; |
518 | + if (!_XcursorReadUInt (file, &head.height)) |
519 | + return NULL; |
520 | + if (!_XcursorReadUInt (file, &head.xhot)) |
521 | + return NULL; |
522 | + if (!_XcursorReadUInt (file, &head.yhot)) |
523 | + return NULL; |
524 | + if (!_XcursorReadUInt (file, &head.delay)) |
525 | + return NULL; |
526 | + /* sanity check data */ |
527 | + if (head.width >= 0x10000 || head.height > 0x10000) |
528 | + return NULL; |
529 | + if (head.width == 0 || head.height == 0) |
530 | + return NULL; |
531 | + if (head.xhot > head.width || head.yhot > head.height) |
532 | + return NULL; |
533 | + |
534 | + /* Create the image and initialize it */ |
535 | + image = XcursorImageCreate (head.width, head.height); |
536 | + if (image == NULL) |
537 | + return NULL; |
538 | + if (chunkHeader.version < image->version) |
539 | + image->version = chunkHeader.version; |
540 | + image->size = chunkHeader.subtype; |
541 | + image->xhot = head.xhot; |
542 | + image->yhot = head.yhot; |
543 | + image->delay = head.delay; |
544 | + n = image->width * image->height; |
545 | + p = image->pixels; |
546 | + while (n--) |
547 | + { |
548 | + if (!_XcursorReadUInt (file, p)) |
549 | + { |
550 | + XcursorImageDestroy (image); |
551 | + return NULL; |
552 | + } |
553 | + p++; |
554 | + } |
555 | + return image; |
556 | +} |
557 | + |
558 | +static XcursorImages * |
559 | +XcursorXcFileLoadImages (XcursorFile *file, int size) |
560 | +{ |
561 | + XcursorFileHeader *fileHeader; |
562 | + XcursorDim bestSize; |
563 | + int nsize; |
564 | + XcursorImages *images; |
565 | + int n; |
566 | + int toc; |
567 | + |
568 | + if (!file || size < 0) |
569 | + return NULL; |
570 | + fileHeader = _XcursorReadFileHeader (file); |
571 | + if (!fileHeader) |
572 | + return NULL; |
573 | + bestSize = _XcursorFindBestSize (fileHeader, (XcursorDim) size, &nsize); |
574 | + if (!bestSize) |
575 | + { |
576 | + _XcursorFileHeaderDestroy (fileHeader); |
577 | + return NULL; |
578 | + } |
579 | + images = XcursorImagesCreate (nsize); |
580 | + if (!images) |
581 | + { |
582 | + _XcursorFileHeaderDestroy (fileHeader); |
583 | + return NULL; |
584 | + } |
585 | + for (n = 0; n < nsize; n++) |
586 | + { |
587 | + toc = _XcursorFindImageToc (fileHeader, bestSize, n); |
588 | + if (toc < 0) |
589 | + break; |
590 | + images->images[images->nimage] = _XcursorReadImage (file, fileHeader, |
591 | + toc); |
592 | + if (!images->images[images->nimage]) |
593 | + break; |
594 | + images->nimage++; |
595 | + } |
596 | + _XcursorFileHeaderDestroy (fileHeader); |
597 | + if (images->nimage != nsize) |
598 | + { |
599 | + XcursorImagesDestroy (images); |
600 | + images = NULL; |
601 | + } |
602 | + return images; |
603 | +} |
604 | + |
605 | +static int |
606 | +_XcursorStdioFileRead (XcursorFile *file, unsigned char *buf, int len) |
607 | +{ |
608 | + FILE *f = file->closure; |
609 | + return fread (buf, 1, len, f); |
610 | +} |
611 | + |
612 | +static int |
613 | +_XcursorStdioFileWrite (XcursorFile *file, unsigned char *buf, int len) |
614 | +{ |
615 | + FILE *f = file->closure; |
616 | + return fwrite (buf, 1, len, f); |
617 | +} |
618 | + |
619 | +static int |
620 | +_XcursorStdioFileSeek (XcursorFile *file, long offset, int whence) |
621 | +{ |
622 | + FILE *f = file->closure; |
623 | + return fseek (f, offset, whence); |
624 | +} |
625 | + |
626 | +static void |
627 | +_XcursorStdioFileInitialize (FILE *stdfile, XcursorFile *file) |
628 | +{ |
629 | + file->closure = stdfile; |
630 | + file->read = _XcursorStdioFileRead; |
631 | + file->write = _XcursorStdioFileWrite; |
632 | + file->seek = _XcursorStdioFileSeek; |
633 | +} |
634 | + |
635 | +static XcursorImages * |
636 | +XcursorFileLoadImages (FILE *file, int size) |
637 | +{ |
638 | + XcursorFile f; |
639 | + |
640 | + if (!file) |
641 | + return NULL; |
642 | + |
643 | + _XcursorStdioFileInitialize (file, &f); |
644 | + return XcursorXcFileLoadImages (&f, size); |
645 | +} |
646 | + |
647 | +/* |
648 | + * From libXcursor/src/library.c |
649 | + */ |
650 | + |
651 | +#ifndef ICONDIR |
652 | +#define ICONDIR "/usr/X11R6/lib/X11/icons" |
653 | +#endif |
654 | + |
655 | +#ifndef XCURSORPATH |
656 | +#define XCURSORPATH "~/.icons:/usr/share/icons:/usr/share/pixmaps:~/.cursors:/usr/share/cursors/xorg-x11:"ICONDIR |
657 | +#endif |
658 | + |
659 | +static const char * |
660 | +XcursorLibraryPath (void) |
661 | +{ |
662 | + static const char *path; |
663 | + |
664 | + if (!path) |
665 | + { |
666 | + path = getenv ("XCURSOR_PATH"); |
667 | + if (!path) |
668 | + path = XCURSORPATH; |
669 | + } |
670 | + return path; |
671 | +} |
672 | + |
673 | +static void |
674 | +_XcursorAddPathElt (char *path, const char *elt, int len) |
675 | +{ |
676 | + int pathlen = strlen (path); |
677 | + |
678 | + /* append / if the path doesn't currently have one */ |
679 | + if (path[0] == '\0' || path[pathlen - 1] != '/') |
680 | + { |
681 | + strcat (path, "/"); |
682 | + pathlen++; |
683 | + } |
684 | + if (len == -1) |
685 | + len = strlen (elt); |
686 | + /* strip leading slashes */ |
687 | + while (len && elt[0] == '/') |
688 | + { |
689 | + elt++; |
690 | + len--; |
691 | + } |
692 | + strncpy (path + pathlen, elt, len); |
693 | + path[pathlen + len] = '\0'; |
694 | +} |
695 | + |
696 | +static char * |
697 | +_XcursorBuildThemeDir (const char *dir, const char *theme) |
698 | +{ |
699 | + const char *colon; |
700 | + const char *tcolon; |
701 | + char *full; |
702 | + char *home; |
703 | + int dirlen; |
704 | + int homelen; |
705 | + int themelen; |
706 | + int len; |
707 | + |
708 | + if (!dir || !theme) |
709 | + return NULL; |
710 | + |
711 | + colon = strchr (dir, ':'); |
712 | + if (!colon) |
713 | + colon = dir + strlen (dir); |
714 | + |
715 | + dirlen = colon - dir; |
716 | + |
717 | + tcolon = strchr (theme, ':'); |
718 | + if (!tcolon) |
719 | + tcolon = theme + strlen (theme); |
720 | + |
721 | + themelen = tcolon - theme; |
722 | + |
723 | + home = NULL; |
724 | + homelen = 0; |
725 | + if (*dir == '~') |
726 | + { |
727 | + home = getenv ("HOME"); |
728 | + if (!home) |
729 | + return NULL; |
730 | + homelen = strlen (home); |
731 | + dir++; |
732 | + dirlen--; |
733 | + } |
734 | + |
735 | + /* |
736 | + * add space for any needed directory separators, one per component, |
737 | + * and one for the trailing null |
738 | + */ |
739 | + len = 1 + homelen + 1 + dirlen + 1 + themelen + 1; |
740 | + |
741 | + full = malloc (len); |
742 | + if (!full) |
743 | + return NULL; |
744 | + full[0] = '\0'; |
745 | + |
746 | + if (home) |
747 | + _XcursorAddPathElt (full, home, -1); |
748 | + _XcursorAddPathElt (full, dir, dirlen); |
749 | + _XcursorAddPathElt (full, theme, themelen); |
750 | + return full; |
751 | +} |
752 | + |
753 | +static char * |
754 | +_XcursorBuildFullname (const char *dir, const char *subdir, const char *file) |
755 | +{ |
756 | + char *full; |
757 | + |
758 | + if (!dir || !subdir || !file) |
759 | + return NULL; |
760 | + |
761 | + full = malloc (strlen (dir) + 1 + strlen (subdir) + 1 + strlen (file) + 1); |
762 | + if (!full) |
763 | + return NULL; |
764 | + full[0] = '\0'; |
765 | + _XcursorAddPathElt (full, dir, -1); |
766 | + _XcursorAddPathElt (full, subdir, -1); |
767 | + _XcursorAddPathElt (full, file, -1); |
768 | + return full; |
769 | +} |
770 | + |
771 | +static const char * |
772 | +_XcursorNextPath (const char *path) |
773 | +{ |
774 | + char *colon = strchr (path, ':'); |
775 | + |
776 | + if (!colon) |
777 | + return NULL; |
778 | + return colon + 1; |
779 | +} |
780 | + |
781 | +#define XcursorWhite(c) ((c) == ' ' || (c) == '\t' || (c) == '\n') |
782 | +#define XcursorSep(c) ((c) == ';' || (c) == ',') |
783 | + |
784 | +static char * |
785 | +_XcursorThemeInherits (const char *full) |
786 | +{ |
787 | + char line[8192]; |
788 | + char *result = NULL; |
789 | + FILE *f; |
790 | + |
791 | + if (!full) |
792 | + return NULL; |
793 | + |
794 | + f = fopen (full, "r"); |
795 | + if (f) |
796 | + { |
797 | + while (fgets (line, sizeof (line), f)) |
798 | + { |
799 | + if (!strncmp (line, "Inherits", 8)) |
800 | + { |
801 | + char *l = line + 8; |
802 | + char *r; |
803 | + while (*l == ' ') l++; |
804 | + if (*l != '=') continue; |
805 | + l++; |
806 | + while (*l == ' ') l++; |
807 | + result = malloc (strlen (l) + 1); |
808 | + if (result) |
809 | + { |
810 | + r = result; |
811 | + while (*l) |
812 | + { |
813 | + while (XcursorSep(*l) || XcursorWhite (*l)) l++; |
814 | + if (!*l) |
815 | + break; |
816 | + if (r != result) |
817 | + *r++ = ':'; |
818 | + while (*l && !XcursorWhite(*l) && |
819 | + !XcursorSep(*l)) |
820 | + *r++ = *l++; |
821 | + } |
822 | + *r++ = '\0'; |
823 | + } |
824 | + break; |
825 | + } |
826 | + } |
827 | + fclose (f); |
828 | + } |
829 | + return result; |
830 | +} |
831 | + |
832 | +static FILE * |
833 | +XcursorScanTheme (const char *theme, const char *name) |
834 | +{ |
835 | + FILE *f = NULL; |
836 | + char *full; |
837 | + char *dir; |
838 | + const char *path; |
839 | + char *inherits = NULL; |
840 | + const char *i; |
841 | + |
842 | + if (!theme || !name) |
843 | + return NULL; |
844 | + |
845 | + /* |
846 | + * Scan this theme |
847 | + */ |
848 | + for (path = XcursorLibraryPath (); |
849 | + path && f == NULL; |
850 | + path = _XcursorNextPath (path)) |
851 | + { |
852 | + dir = _XcursorBuildThemeDir (path, theme); |
853 | + if (dir) |
854 | + { |
855 | + full = _XcursorBuildFullname (dir, "cursors", name); |
856 | + if (full) |
857 | + { |
858 | + f = fopen (full, "r"); |
859 | + free (full); |
860 | + } |
861 | + if (!f && !inherits) |
862 | + { |
863 | + full = _XcursorBuildFullname (dir, "", "index.theme"); |
864 | + if (full) |
865 | + { |
866 | + inherits = _XcursorThemeInherits (full); |
867 | + free (full); |
868 | + } |
869 | + } |
870 | + free (dir); |
871 | + } |
872 | + } |
873 | + /* |
874 | + * Recurse to scan inherited themes |
875 | + */ |
876 | + for (i = inherits; i && f == NULL; i = _XcursorNextPath (i)) |
877 | + f = XcursorScanTheme (i, name); |
878 | + if (inherits != NULL) |
879 | + free (inherits); |
880 | + return f; |
881 | +} |
882 | + |
883 | +XcursorImages * |
884 | +XcursorLibraryLoadImages (const char *file, const char *theme, int size) |
885 | +{ |
886 | + FILE *f = NULL; |
887 | + XcursorImages *images = NULL; |
888 | + |
889 | + if (!file) |
890 | + return NULL; |
891 | + |
892 | + if (theme) |
893 | + f = XcursorScanTheme (theme, file); |
894 | + if (!f) |
895 | + f = XcursorScanTheme ("default", file); |
896 | + if (f) |
897 | + { |
898 | + images = XcursorFileLoadImages (f, size); |
899 | + if (images) |
900 | + XcursorImagesSetName (images, file); |
901 | + fclose (f); |
902 | + } |
903 | + return images; |
904 | +} |
905 | + |
906 | +static void |
907 | +load_all_cursors_from_dir(const char *path, int size, |
908 | + void (*load_callback)(XcursorImages *, void *), |
909 | + void *user_data) |
910 | +{ |
911 | + FILE *f; |
912 | + DIR *dir = opendir(path); |
913 | + struct dirent *ent; |
914 | + char *full; |
915 | + XcursorImages *images; |
916 | + |
917 | + if (!dir) |
918 | + return; |
919 | + |
920 | + for(ent = readdir(dir); ent; ent = readdir(dir)) { |
921 | +#ifdef _DIRENT_HAVE_D_TYPE |
922 | + if (ent->d_type != DT_UNKNOWN && |
923 | + (ent->d_type != DT_REG && ent->d_type != DT_LNK)) |
924 | + continue; |
925 | +#endif |
926 | + |
927 | + full = _XcursorBuildFullname(path, "", ent->d_name); |
928 | + if (!full) |
929 | + continue; |
930 | + |
931 | + f = fopen(full, "r"); |
932 | + if (!f) { |
933 | + free(full); |
934 | + continue; |
935 | + } |
936 | + |
937 | + images = XcursorFileLoadImages(f, size); |
938 | + |
939 | + if (images) { |
940 | + XcursorImagesSetName(images, ent->d_name); |
941 | + load_callback(images, user_data); |
942 | + } |
943 | + |
944 | + fclose (f); |
945 | + free(full); |
946 | + } |
947 | + |
948 | + closedir(dir); |
949 | +} |
950 | + |
951 | +/** Load all the cursor of a theme |
952 | + * |
953 | + * This function loads all the cursor images of a given theme and its |
954 | + * inherited themes. Each cursor is loaded into an XcursorImages object |
955 | + * which is passed to the caller's load callback. If a cursor appears |
956 | + * more than once across all the inherited themes, the load callback |
957 | + * will be called multiple times, with possibly different XcursorImages |
958 | + * object which have the same name. The user is expected to destroy the |
959 | + * XcursorImages objects passed to the callback with |
960 | + * XcursorImagesDestroy(). |
961 | + * |
962 | + * \param theme The name of theme that should be loaded |
963 | + * \param size The desired size of the cursor images |
964 | + * \param load_callback A callback function that will be called |
965 | + * for each cursor loaded. The first parameter is the XcursorImages |
966 | + * object representing the loaded cursor and the second is a pointer |
967 | + * to data provided by the user. |
968 | + * \param user_data The data that should be passed to the load callback |
969 | + */ |
970 | +void |
971 | +xcursor_load_theme(const char *theme, int size, |
972 | + void (*load_callback)(XcursorImages *, void *), |
973 | + void *user_data) |
974 | +{ |
975 | + char *full, *dir; |
976 | + char *inherits = NULL; |
977 | + const char *path, *i; |
978 | + |
979 | + if (!theme) |
980 | + theme = "default"; |
981 | + |
982 | + for (path = XcursorLibraryPath(); |
983 | + path; |
984 | + path = _XcursorNextPath(path)) { |
985 | + dir = _XcursorBuildThemeDir(path, theme); |
986 | + if (!dir) |
987 | + continue; |
988 | + |
989 | + full = _XcursorBuildFullname(dir, "cursors", ""); |
990 | + |
991 | + if (full) { |
992 | + load_all_cursors_from_dir(full, size, load_callback, |
993 | + user_data); |
994 | + free(full); |
995 | + } |
996 | + |
997 | + if (!inherits) { |
998 | + full = _XcursorBuildFullname(dir, "", "index.theme"); |
999 | + if (full) { |
1000 | + inherits = _XcursorThemeInherits(full); |
1001 | + free(full); |
1002 | + } |
1003 | + } |
1004 | + |
1005 | + free(dir); |
1006 | + } |
1007 | + |
1008 | + for (i = inherits; i; i = _XcursorNextPath(i)) |
1009 | + xcursor_load_theme(i, size, load_callback, user_data); |
1010 | + |
1011 | + if (inherits) |
1012 | + free(inherits); |
1013 | +} |
1014 | |
1015 | === added file '3rd_party/xcursor/xcursor.h' |
1016 | --- 3rd_party/xcursor/xcursor.h 1970-01-01 00:00:00 +0000 |
1017 | +++ 3rd_party/xcursor/xcursor.h 2014-07-11 20:27:44 +0000 |
1018 | @@ -0,0 +1,65 @@ |
1019 | +/* |
1020 | + * Copyright © 2002 Keith Packard |
1021 | + * |
1022 | + * Permission to use, copy, modify, distribute, and sell this software and its |
1023 | + * documentation for any purpose is hereby granted without fee, provided that |
1024 | + * the above copyright notice appear in all copies and that both that |
1025 | + * copyright notice and this permission notice appear in supporting |
1026 | + * documentation, and that the name of Keith Packard not be used in |
1027 | + * advertising or publicity pertaining to distribution of the software without |
1028 | + * specific, written prior permission. Keith Packard makes no |
1029 | + * representations about the suitability of this software for any purpose. It |
1030 | + * is provided "as is" without express or implied warranty. |
1031 | + * |
1032 | + * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, |
1033 | + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO |
1034 | + * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR |
1035 | + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, |
1036 | + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER |
1037 | + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR |
1038 | + * PERFORMANCE OF THIS SOFTWARE. |
1039 | + */ |
1040 | + |
1041 | +#ifndef XCURSOR_H |
1042 | +#define XCURSOR_H |
1043 | + |
1044 | +#include <stdint.h> |
1045 | + |
1046 | + |
1047 | +typedef int XcursorBool; |
1048 | +typedef uint32_t XcursorUInt; |
1049 | + |
1050 | +typedef XcursorUInt XcursorDim; |
1051 | +typedef XcursorUInt XcursorPixel; |
1052 | + |
1053 | +typedef struct _XcursorImage { |
1054 | + XcursorUInt version; /* version of the image data */ |
1055 | + XcursorDim size; /* nominal size for matching */ |
1056 | + XcursorDim width; /* actual width */ |
1057 | + XcursorDim height; /* actual height */ |
1058 | + XcursorDim xhot; /* hot spot x (must be inside image) */ |
1059 | + XcursorDim yhot; /* hot spot y (must be inside image) */ |
1060 | + XcursorUInt delay; /* animation delay to next frame (ms) */ |
1061 | + XcursorPixel *pixels; /* pointer to pixels */ |
1062 | +} XcursorImage; |
1063 | + |
1064 | +/* |
1065 | + * Other data structures exposed by the library API |
1066 | + */ |
1067 | +typedef struct _XcursorImages { |
1068 | + int nimage; /* number of images */ |
1069 | + XcursorImage **images; /* array of XcursorImage pointers */ |
1070 | + char *name; /* name used to load images */ |
1071 | +} XcursorImages; |
1072 | + |
1073 | +XcursorImages * |
1074 | +XcursorLibraryLoadImages (const char *file, const char *theme, int size); |
1075 | + |
1076 | +void |
1077 | +XcursorImagesDestroy (XcursorImages *images); |
1078 | + |
1079 | +void |
1080 | +xcursor_load_theme(const char *theme, int size, |
1081 | + void (*load_callback)(XcursorImages *, void *), |
1082 | + void *user_data); |
1083 | +#endif |
1084 | |
1085 | === modified file 'CMakeLists.txt' |
1086 | --- CMakeLists.txt 2014-06-25 07:27:23 +0000 |
1087 | +++ CMakeLists.txt 2014-07-11 20:27:44 +0000 |
1088 | @@ -27,7 +27,7 @@ |
1089 | set(LIBRARY_OUTPUT_PATH ${CMAKE_BINARY_DIR}/lib) |
1090 | |
1091 | set(MIR_VERSION_MAJOR 0) |
1092 | -set(MIR_VERSION_MINOR 4) # This should change at least with every MIRSERVER_ABI |
1093 | +set(MIR_VERSION_MINOR 5) # This should change at least with every MIRSERVER_ABI |
1094 | set(MIR_VERSION_PATCH 0) |
1095 | |
1096 | set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/cmake) |
1097 | @@ -47,15 +47,21 @@ |
1098 | include (cmake/PrePush.cmake) |
1099 | include (GNUInstallDirs) |
1100 | |
1101 | +set(build_types "None;Debug;Release;RelWithDebInfo;MinSizeRel;Coverage;AddressSanitizer") |
1102 | +# Change informational string for CMAKE_BUILD_TYPE |
1103 | +set(CMAKE_BUILD_TYPE ${CMAKE_BUILD_TYPE} CACHE STRING "${build_types}" FORCE) |
1104 | +# Enable cmake-gui to display a drop down list for CMAKE_BUILD_TYPE |
1105 | +set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "${build_types}") |
1106 | + |
1107 | set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -pthread -g -Werror -Wall -pedantic -Wextra -fPIC") |
1108 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pthread -g -std=c++0x -Werror -Wall -fno-strict-aliasing -pedantic -Wnon-virtual-dtor -Wextra -fPIC") |
1109 | -set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--no-undefined") |
1110 | -set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--no-undefined") |
1111 | |
1112 | if ("${CMAKE_CXX_COMPILER}" MATCHES "clang") |
1113 | set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-return-type-c-linkage -Wno-mismatched-tags") |
1114 | endif() |
1115 | |
1116 | +string(TOLOWER "${CMAKE_BUILD_TYPE}" cmake_build_type_lower) |
1117 | + |
1118 | ##################################################################### |
1119 | # Enable code coverage calculation with gcov/gcovr/lcov |
1120 | # Usage: |
1121 | @@ -64,12 +70,23 @@ |
1122 | # * Find html report in subdir coveragereport |
1123 | # * Find xml report feasible for jenkins in coverage.xml |
1124 | ##################################################################### |
1125 | -IF(CMAKE_BUILD_TYPE MATCHES [cC][oO][vV][eE][rR][aA][gG][eE]) |
1126 | - SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -ftest-coverage -fprofile-arcs" ) |
1127 | - SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -ftest-coverage -fprofile-arcs" ) |
1128 | - SET(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} -ftest-coverage -fprofile-arcs" ) |
1129 | - SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -ftest-coverage -fprofile-arcs" ) |
1130 | -ENDIF(CMAKE_BUILD_TYPE MATCHES [cC][oO][vV][eE][rR][aA][gG][eE]) |
1131 | +if(cmake_build_type_lower MATCHES "coverage") |
1132 | + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -ftest-coverage -fprofile-arcs") |
1133 | + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -ftest-coverage -fprofile-arcs") |
1134 | + set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} -ftest-coverage -fprofile-arcs") |
1135 | + set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -ftest-coverage -fprofile-arcs") |
1136 | +endif() |
1137 | + |
1138 | +if(cmake_build_type_lower MATCHES "addresssanitizer") |
1139 | + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address -fno-omit-frame-pointer") |
1140 | + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=address -fno-omit-frame-pointer") |
1141 | + set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} -fsanitize=address") |
1142 | + set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -fsanitize=address") |
1143 | +else() |
1144 | + # AddressSanitizer builds fail if we disallow undefined symbols |
1145 | + set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--no-undefined") |
1146 | + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--no-undefined") |
1147 | +endif() |
1148 | |
1149 | enable_testing() |
1150 | |
1151 | @@ -141,6 +158,7 @@ |
1152 | |
1153 | set(MIR_ANDROID_INCLUDE_DIRECTORIES) # to be filled by android-input |
1154 | set(MIR_ANDROID_INPUT_COMPILE_FLAGS) # to be filled by android-input |
1155 | +set(MIR_XCURSOR_INCLUDE_DIRECTORIES) |
1156 | set(MIR_3RD_PARTY_INCLUDE_DIRECTORIES) |
1157 | add_subdirectory(3rd_party/) |
1158 | |
1159 | |
1160 | === modified file 'debian/changelog' |
1161 | --- debian/changelog 2014-07-01 15:54:36 +0000 |
1162 | +++ debian/changelog 2014-07-11 20:27:44 +0000 |
1163 | @@ -1,3 +1,9 @@ |
1164 | +mir (0.5.0-0ubuntu1) UNRELEASED; urgency=medium |
1165 | + |
1166 | + * Under development |
1167 | + |
1168 | + -- Daniel van Vugt <daniel.van.vugt@canonical.com> Fri, 04 Jul 2014 12:45:30 +0800 |
1169 | + |
1170 | mir (0.4.0+14.10.20140701.1-0ubuntu1) utopic; urgency=medium |
1171 | |
1172 | * New upstream release 0.4.0 (https://launchpad.net/mir/+milestone/0.4.0) |
1173 | @@ -5,7 +11,6 @@ |
1174 | . Add surface attribute for visibility. |
1175 | . Add surface orientation API. |
1176 | - mirserver ABI bumped to 22. Shells need rebuilding. |
1177 | - . Allow setting the orientation of a server surface. |
1178 | . Change compositor::Scene to expose compositor::SceneElements instead |
1179 | of graphics::Renderables. |
1180 | . Change various input and Surface classes to support the client cursor |
1181 | @@ -16,18 +21,29 @@ |
1182 | mg::Renderables. |
1183 | . Add visibility tracking to mc::SceneElement interface and |
1184 | implementations. |
1185 | - . Unregister FD Handler from EventHandlerRegister. |
1186 | - . Sending user input events through Surfaces. |
1187 | . Move InputChannelFactory into DefaultServerConfiguration. |
1188 | - . Ensure default input region is updated when surface is resized. (LP: #1332632) |
1189 | - - android: support alpha blending overlays together in HWC. Bumps |
1190 | - android-headers version requirement from 4.2.2 to 4.4.2. (LP: #1329879) |
1191 | - - android: designate the buffer usage when attempting to access or |
1192 | - update the fence associated with the native buffer. (LP: #1329868) |
1193 | + - Unregister FD Handler from EventHandlerRegister. |
1194 | + - Sending user input events through Surfaces. |
1195 | + - Allow setting the orientation of a server surface. |
1196 | - Enable client cursor API. |
1197 | - Enable support for USB touchscreens. |
1198 | - Various test improvements. |
1199 | - - Ensure the_cursor() is not null. (LP: #1334010) |
1200 | + - Bugs fixed: |
1201 | + . can't display toolbar after dismissing it (LP: #1332632) |
1202 | + . [regression] demo client connection crashes the server (LP: #1334010) |
1203 | + . demo server locks up in certain scenarios with --disable-overlays |
1204 | + false when starting/stopping second clients (LP: #1329868) |
1205 | + . MultiThreadedCompositor deadlocks (LP: #1335311) |
1206 | + . Intermittent memory error in |
1207 | + ClientSurfaceEvents.client_can_query_current_orientation (LP: #1335819) |
1208 | + . Intermittent hang & fail in mir_acceptance_tests.TestClientCursorAPI.* |
1209 | + (LP: #1332011) |
1210 | + . MirClientSurfaceTests tests leak fds and eventually hang when ran |
1211 | + repeatedly (LP: #1333673) |
1212 | + . [testfail] Intermittent "Invalid read" in MirSurfaceSwapBuffersTest. |
1213 | + swap_buffers_does_not_block_when_surface_is_not_composited |
1214 | + (LP: #1334287) |
1215 | + . android: support alpha blending during hwc overlay (LP: #1329879) |
1216 | |
1217 | -- Ubuntu daily release <ps-jenkins@lists.canonical.com> Tue, 01 Jul 2014 15:54:36 +0000 |
1218 | |
1219 | |
1220 | === modified file 'debian/control' |
1221 | --- debian/control 2014-06-27 06:10:24 +0000 |
1222 | +++ debian/control 2014-07-11 20:27:44 +0000 |
1223 | @@ -10,6 +10,10 @@ |
1224 | doxygen, |
1225 | xsltproc, |
1226 | graphviz, |
1227 | +# We rely on C++11 features, and to prevent from ABI breaks |
1228 | +# in libstdc++ causing us issues, we explicitly select a G++ |
1229 | +# version. |
1230 | + g++-4.9, |
1231 | libboost-dev, |
1232 | libboost-chrono-dev, |
1233 | libboost-date-time-dev, |
1234 | |
1235 | === modified file 'debian/rules' |
1236 | --- debian/rules 2014-04-15 17:11:14 +0000 |
1237 | +++ debian/rules 2014-07-11 20:27:44 +0000 |
1238 | @@ -6,6 +6,13 @@ |
1239 | |
1240 | export DPKG_GENSYMBOLS_CHECK_LEVEL = 4 |
1241 | |
1242 | +include /usr/share/dpkg/default.mk |
1243 | + |
1244 | +# Explicitly selecting a G{CC,++}-version here to avoid accidental |
1245 | +# ABI breaks introduced by toolchain updates. |
1246 | +export CC=$(DEB_HOST_GNU_TYPE)-gcc-4.9 |
1247 | +export CXX=$(DEB_HOST_GNU_TYPE)-g++-4.9 |
1248 | + |
1249 | %: |
1250 | dh $@ --parallel --fail-missing |
1251 | |
1252 | |
1253 | === modified file 'examples/eglcounter.cpp' |
1254 | --- examples/eglcounter.cpp 2014-06-05 21:28:43 +0000 |
1255 | +++ examples/eglcounter.cpp 2014-07-11 20:27:44 +0000 |
1256 | @@ -201,7 +201,7 @@ |
1257 | }; |
1258 | |
1259 | /* Colours from http://design.ubuntu.com/brand/colour-palette */ |
1260 | -#define MID_AUBERGINE(x) x*0.368627451f, x*0.152941176f, x*0.31372549f |
1261 | +#define MID_AUBERGINE(x) (x)*0.368627451f, (x)*0.152941176f, (x)*0.31372549f |
1262 | #define ORANGE 0.866666667f, 0.282352941f, 0.141414141f |
1263 | |
1264 | int main(int argc, char *argv[]) |
1265 | |
1266 | === modified file 'examples/egltriangle.c' |
1267 | --- examples/egltriangle.c 2014-06-09 17:16:32 +0000 |
1268 | +++ examples/egltriangle.c 2014-07-11 20:27:44 +0000 |
1269 | @@ -44,7 +44,7 @@ |
1270 | } |
1271 | |
1272 | /* Colours from http://design.ubuntu.com/brand/colour-palette */ |
1273 | -#define MID_AUBERGINE(x) x*0.368627451f, x*0.152941176f, x*0.31372549f |
1274 | +#define MID_AUBERGINE(x) (x)*0.368627451f, (x)*0.152941176f, (x)*0.31372549f |
1275 | #define ORANGE 0.866666667f, 0.282352941f, 0.141414141f |
1276 | |
1277 | int main(int argc, char *argv[]) |
1278 | |
1279 | === modified file 'examples/minimal_server.cpp' |
1280 | --- examples/minimal_server.cpp 2014-04-30 07:05:40 +0000 |
1281 | +++ examples/minimal_server.cpp 2014-07-11 20:27:44 +0000 |
1282 | @@ -17,12 +17,20 @@ |
1283 | */ |
1284 | |
1285 | #include "mir/default_server_configuration.h" |
1286 | +#include "mir/report_exception.h" |
1287 | #include "mir/run_mir.h" |
1288 | |
1289 | +#include <iostream> |
1290 | + |
1291 | int main(int argc, char const* argv[]) |
1292 | +try |
1293 | { |
1294 | mir::DefaultServerConfiguration config(argc, argv); |
1295 | run_mir(config, [](mir::DisplayServer&){} ); |
1296 | return 0; |
1297 | } |
1298 | - |
1299 | +catch (...) |
1300 | +{ |
1301 | + mir::report_exception(std::cerr); |
1302 | + return 1; |
1303 | +} |
1304 | |
1305 | === modified file 'examples/multiwin.c' |
1306 | --- examples/multiwin.c 2014-03-06 06:05:17 +0000 |
1307 | +++ examples/multiwin.c 2014-07-11 20:27:44 +0000 |
1308 | @@ -44,6 +44,13 @@ |
1309 | } |
1310 | } |
1311 | |
1312 | +static void premultiply_alpha(Color *c) |
1313 | +{ |
1314 | + c->r = (unsigned)c->r * c->a / 255U; |
1315 | + c->g = (unsigned)c->g * c->a / 255U; |
1316 | + c->b = (unsigned)c->b * c->a / 255U; |
1317 | +} |
1318 | + |
1319 | static void put_pixels(void *where, int count, MirPixelFormat format, |
1320 | const Color *color) |
1321 | { |
1322 | @@ -187,6 +194,7 @@ |
1323 | win[0].fill.g = 0x00; |
1324 | win[0].fill.b = 0x00; |
1325 | win[0].fill.a = 0x50; |
1326 | + premultiply_alpha(&win[0].fill); |
1327 | |
1328 | parm.name = "green"; |
1329 | parm.width = 300; |
1330 | @@ -196,6 +204,7 @@ |
1331 | win[1].fill.g = 0xff; |
1332 | win[1].fill.b = 0x00; |
1333 | win[1].fill.a = 0x50; |
1334 | + premultiply_alpha(&win[1].fill); |
1335 | |
1336 | parm.name = "blue"; |
1337 | parm.width = 150; |
1338 | @@ -205,6 +214,7 @@ |
1339 | win[2].fill.g = 0x00; |
1340 | win[2].fill.b = 0xff; |
1341 | win[2].fill.a = 0x50; |
1342 | + premultiply_alpha(&win[2].fill); |
1343 | |
1344 | signal(SIGINT, shutdown); |
1345 | signal(SIGTERM, shutdown); |
1346 | |
1347 | === modified file 'include/client/mir_toolkit/mir_prompt_session.h' |
1348 | --- include/client/mir_toolkit/mir_prompt_session.h 2014-06-13 10:02:22 +0000 |
1349 | +++ include/client/mir_toolkit/mir_prompt_session.h 2014-07-11 20:27:44 +0000 |
1350 | @@ -79,6 +79,23 @@ |
1351 | */ |
1352 | void mir_prompt_session_release_sync(MirPromptSession *prompt_session); |
1353 | |
1354 | +/** |
1355 | + * Test for a valid prompt session |
1356 | + * \param [in] prompt_session The prompt session |
1357 | + * \return True if prompt_session is valid, false otherwise |
1358 | + */ |
1359 | +MirBool mir_prompt_session_is_valid(MirPromptSession *prompt_session); |
1360 | + |
1361 | +/** |
1362 | + * Retrieve a text description of the last error. The returned string is owned |
1363 | + * by the library and remains valid until the prompt session has been released. |
1364 | + * \param [in] prompt_session The prompt session |
1365 | + * \return A text description of any error resulting in an |
1366 | + * invalid connection, or the empty string "" if the |
1367 | + * connection is valid. |
1368 | + */ |
1369 | +char const *mir_prompt_session_error_message(MirPromptSession *prompt_session); |
1370 | + |
1371 | #ifdef __cplusplus |
1372 | } |
1373 | /**@}*/ |
1374 | |
1375 | === modified file 'include/platform/mir/graphics/cursor_image.h' |
1376 | --- include/platform/mir/graphics/cursor_image.h 2014-04-28 23:15:05 +0000 |
1377 | +++ include/platform/mir/graphics/cursor_image.h 2014-07-11 20:27:44 +0000 |
1378 | @@ -21,6 +21,7 @@ |
1379 | #define MIR_GRAPHICS_CURSOR_IMAGE_H_ |
1380 | |
1381 | #include "mir/geometry/size.h" |
1382 | +#include "mir/geometry/displacement.h" |
1383 | |
1384 | namespace mir |
1385 | { |
1386 | @@ -33,6 +34,12 @@ |
1387 | |
1388 | virtual void const* as_argb_8888() const = 0; |
1389 | virtual geometry::Size size() const = 0; |
1390 | + |
1391 | + // We use "hotspot" to mean the offset within a cursor image |
1392 | + // which should be placed at the onscreen |
1393 | + // location of the pointer. |
1394 | + virtual geometry::Displacement hotspot() const = 0; |
1395 | + |
1396 | |
1397 | protected: |
1398 | CursorImage() = default; |
1399 | |
1400 | === modified file 'include/platform/mir/options/configuration.h' |
1401 | --- include/platform/mir/options/configuration.h 2014-03-26 05:48:59 +0000 |
1402 | +++ include/platform/mir/options/configuration.h 2014-07-11 20:27:44 +0000 |
1403 | @@ -28,6 +28,7 @@ |
1404 | namespace options |
1405 | { |
1406 | extern char const* const server_socket_opt; |
1407 | +extern char const* const prompt_socket_opt; |
1408 | extern char const* const no_server_socket_opt; |
1409 | extern char const* const enable_input_opt; |
1410 | extern char const* const session_mediator_report_opt; |
1411 | |
1412 | === modified file 'include/server/mir/default_server_configuration.h' |
1413 | --- include/server/mir/default_server_configuration.h 2014-06-23 17:40:57 +0000 |
1414 | +++ include/server/mir/default_server_configuration.h 2014-07-11 20:27:44 +0000 |
1415 | @@ -98,6 +98,7 @@ |
1416 | } |
1417 | namespace graphics |
1418 | { |
1419 | +class NativePlatform; |
1420 | class Platform; |
1421 | class Display; |
1422 | class BufferInitializer; |
1423 | @@ -105,7 +106,6 @@ |
1424 | class GraphicBufferAllocator; |
1425 | class Cursor; |
1426 | class CursorImage; |
1427 | -class CursorImages; |
1428 | class GLConfig; |
1429 | class GLProgramFactory; |
1430 | namespace nested { class HostConnection; } |
1431 | @@ -124,6 +124,7 @@ |
1432 | class InputSendObserver; |
1433 | class NestedInputRelay; |
1434 | class EventHandler; |
1435 | +class CursorImages; |
1436 | namespace android |
1437 | { |
1438 | class InputRegistrar; |
1439 | @@ -157,6 +158,7 @@ |
1440 | * dependencies of DisplayServer on the rest of the Mir |
1441 | * @{ */ |
1442 | virtual std::shared_ptr<frontend::Connector> the_connector(); |
1443 | + virtual std::shared_ptr<frontend::Connector> the_prompt_connector(); |
1444 | virtual std::shared_ptr<graphics::Display> the_display(); |
1445 | virtual std::shared_ptr<compositor::Compositor> the_compositor(); |
1446 | virtual std::shared_ptr<input::InputManager> the_input_manager(); |
1447 | @@ -164,6 +166,7 @@ |
1448 | virtual std::shared_ptr<ServerStatusListener> the_server_status_listener(); |
1449 | virtual std::shared_ptr<DisplayChanger> the_display_changer(); |
1450 | virtual std::shared_ptr<graphics::Platform> the_graphics_platform(); |
1451 | + virtual std::shared_ptr<graphics::NativePlatform> the_graphics_native_platform(); |
1452 | virtual std::shared_ptr<input::InputConfiguration> the_input_configuration(); |
1453 | virtual std::shared_ptr<input::InputDispatcher> the_input_dispatcher(); |
1454 | virtual std::shared_ptr<input::InputSender> the_input_sender(); |
1455 | @@ -187,7 +190,7 @@ |
1456 | virtual std::shared_ptr<graphics::DisplayReport> the_display_report(); |
1457 | virtual std::shared_ptr<graphics::Cursor> the_cursor(); |
1458 | virtual std::shared_ptr<graphics::CursorImage> the_default_cursor_image(); |
1459 | - virtual std::shared_ptr<graphics::CursorImages> the_cursor_images(); |
1460 | + virtual std::shared_ptr<input::CursorImages> the_cursor_images(); |
1461 | |
1462 | /** @} */ |
1463 | |
1464 | @@ -222,6 +225,7 @@ |
1465 | * internal dependencies of frontend |
1466 | * @{ */ |
1467 | virtual std::shared_ptr<frontend::ConnectionCreator> the_connection_creator(); |
1468 | + virtual std::shared_ptr<frontend::ConnectionCreator> the_prompt_connection_creator(); |
1469 | virtual std::shared_ptr<frontend::ConnectorReport> the_connector_report(); |
1470 | /** @} */ |
1471 | /** @} */ |
1472 | @@ -290,6 +294,12 @@ |
1473 | virtual std::shared_ptr<graphics::GLProgramFactory> the_gl_program_factory(); |
1474 | virtual std::shared_ptr<input::InputChannelFactory> the_input_channel_factory(); |
1475 | virtual std::shared_ptr<scene::MediatingDisplayChanger> the_mediating_display_changer(); |
1476 | + virtual std::shared_ptr<frontend::ProtobufIpcFactory> new_ipc_factory( |
1477 | + std::shared_ptr<frontend::SessionAuthorizer> const& session_authorizer); |
1478 | + |
1479 | + // TODO Remove after 0.5.0 is branched: the_ipc_factory() is used by |
1480 | + // TODO clients that use the "PrivateProtobuf" but is it now deprecated |
1481 | + // TODO and only retained as a migration aid. |
1482 | virtual std::shared_ptr<frontend::ProtobufIpcFactory> the_ipc_factory( |
1483 | std::shared_ptr<frontend::Shell> const& shell, |
1484 | std::shared_ptr<graphics::GraphicBufferAllocator> const& allocator); |
1485 | @@ -318,6 +328,7 @@ |
1486 | CachedPtr<droidinput::InputDispatcherPolicyInterface> android_dispatcher_policy; |
1487 | |
1488 | CachedPtr<frontend::Connector> connector; |
1489 | + CachedPtr<frontend::Connector> prompt_connector; |
1490 | |
1491 | CachedPtr<input::InputConfiguration> input_configuration; |
1492 | |
1493 | @@ -331,20 +342,23 @@ |
1494 | CachedPtr<shell::InputTargeter> input_targeter; |
1495 | CachedPtr<input::CursorListener> cursor_listener; |
1496 | CachedPtr<graphics::Platform> graphics_platform; |
1497 | + CachedPtr<graphics::NativePlatform> graphics_native_platform; |
1498 | CachedPtr<graphics::BufferInitializer> buffer_initializer; |
1499 | CachedPtr<graphics::GraphicBufferAllocator> buffer_allocator; |
1500 | CachedPtr<graphics::Display> display; |
1501 | CachedPtr<graphics::Cursor> cursor; |
1502 | CachedPtr<graphics::CursorImage> default_cursor_image; |
1503 | - CachedPtr<graphics::CursorImages> cursor_images; |
1504 | + CachedPtr<input::CursorImages> cursor_images; |
1505 | |
1506 | CachedPtr<frontend::ConnectorReport> connector_report; |
1507 | + // TODO remove after 0.5.0 is branched - c.f. the_ipc_factory() |
1508 | CachedPtr<frontend::ProtobufIpcFactory> ipc_factory; |
1509 | CachedPtr<frontend::SessionMediatorReport> session_mediator_report; |
1510 | CachedPtr<frontend::MessageProcessorReport> message_processor_report; |
1511 | CachedPtr<frontend::SessionAuthorizer> session_authorizer; |
1512 | CachedPtr<frontend::EventSink> global_event_sink; |
1513 | CachedPtr<frontend::ConnectionCreator> connection_creator; |
1514 | + CachedPtr<frontend::ConnectionCreator> prompt_connection_creator; |
1515 | CachedPtr<frontend::Screencast> screencast; |
1516 | CachedPtr<compositor::RendererFactory> renderer_factory; |
1517 | CachedPtr<compositor::BufferStreamFactory> buffer_stream_factory; |
1518 | @@ -367,7 +381,8 @@ |
1519 | CachedPtr<compositor::CompositorReport> compositor_report; |
1520 | CachedPtr<logging::Logger> logger; |
1521 | CachedPtr<graphics::DisplayReport> display_report; |
1522 | - CachedPtr<time::Clock> clock; |
1523 | + // static to workaround the singleton clock in AsioMainLoop when running multiple servers |
1524 | + static CachedPtr<time::Clock> clock; |
1525 | CachedPtr<MainLoop> main_loop; |
1526 | CachedPtr<ServerStatusListener> server_status_listener; |
1527 | CachedPtr<graphics::DisplayConfigurationPolicy> display_configuration_policy; |
1528 | |
1529 | === modified file 'include/server/mir/frontend/fd_sets.h' |
1530 | --- include/server/mir/frontend/fd_sets.h 2014-03-06 06:05:17 +0000 |
1531 | +++ include/server/mir/frontend/fd_sets.h 2014-07-11 20:27:44 +0000 |
1532 | @@ -20,7 +20,7 @@ |
1533 | |
1534 | #include <vector> |
1535 | #include <initializer_list> |
1536 | -#include <stdint.h> |
1537 | +#include "mir/fd.h" |
1538 | |
1539 | namespace mir |
1540 | { |
1541 | @@ -28,7 +28,7 @@ |
1542 | { |
1543 | namespace detail |
1544 | { |
1545 | -typedef std::initializer_list<std::vector<int32_t>> FdSets; |
1546 | +typedef std::initializer_list<std::vector<Fd>> FdSets; |
1547 | } |
1548 | } |
1549 | } // namespace mir |
1550 | |
1551 | === modified file 'include/server/mir/frontend/session_authorizer.h' |
1552 | --- include/server/mir/frontend/session_authorizer.h 2014-06-02 17:07:02 +0000 |
1553 | +++ include/server/mir/frontend/session_authorizer.h 2014-07-11 20:27:44 +0000 |
1554 | @@ -36,6 +36,7 @@ |
1555 | virtual bool connection_is_allowed(SessionCredentials const& creds) = 0; |
1556 | virtual bool configure_display_is_allowed(SessionCredentials const& creds) = 0; |
1557 | virtual bool screencast_is_allowed(SessionCredentials const& creds) = 0; |
1558 | + virtual bool prompt_session_is_allowed(SessionCredentials const& creds) = 0; |
1559 | |
1560 | protected: |
1561 | SessionAuthorizer() = default; |
1562 | |
1563 | === renamed file 'include/server/mir/graphics/cursor_images.h' => 'include/server/mir/input/cursor_images.h' |
1564 | --- include/server/mir/graphics/cursor_images.h 2014-05-13 20:07:20 +0000 |
1565 | +++ include/server/mir/input/cursor_images.h 2014-07-11 20:27:44 +0000 |
1566 | @@ -17,8 +17,8 @@ |
1567 | */ |
1568 | |
1569 | |
1570 | -#ifndef MIR_GRAPHICS_CURSOR_LOADER_H_ |
1571 | -#define MIR_GRAPHICS_CURSOR_LOADER_H_ |
1572 | +#ifndef MIR_INPUT_CURSOR_IMAGES_H_ |
1573 | +#define MIR_INPUT_CURSOR_IMAGES_H_ |
1574 | |
1575 | #include "mir/geometry/size.h" |
1576 | |
1577 | @@ -30,10 +30,13 @@ |
1578 | namespace graphics |
1579 | { |
1580 | class CursorImage; |
1581 | - |
1582 | -geometry::Size const default_cursor_size{geometry::Width{64}, geometry::Height{64}}; |
1583 | - |
1584 | -/// CursorImages is used to lookup cursor images. |
1585 | +} |
1586 | + |
1587 | +namespace input |
1588 | +{ |
1589 | +/// CursorImages is used to lookup cursor images from the system theme. |
1590 | +geometry::Size const default_cursor_size{geometry::Width{24}, geometry::Height{24}}; |
1591 | + |
1592 | class CursorImages |
1593 | { |
1594 | public: |
1595 | @@ -41,7 +44,7 @@ |
1596 | |
1597 | /// Looks up the image for a named cursor. Cursor names |
1598 | /// follow the XCursor naming conventions. |
1599 | - virtual std::shared_ptr<CursorImage> image(std::string const& cursor_name, |
1600 | + virtual std::shared_ptr<graphics::CursorImage> image(std::string const& cursor_name, |
1601 | geometry::Size const& size) = 0; |
1602 | |
1603 | protected: |
1604 | @@ -52,4 +55,4 @@ |
1605 | } |
1606 | } |
1607 | |
1608 | -#endif /* MIR_GRAPHICS_CURSOR_LOADER_H_ */ |
1609 | +#endif /* MIR_INPUT_CURSOR_IMAGES_H_ */ |
1610 | |
1611 | === modified file 'include/server/mir/server_configuration.h' |
1612 | --- include/server/mir/server_configuration.h 2014-06-24 12:00:29 +0000 |
1613 | +++ include/server/mir/server_configuration.h 2014-07-11 20:27:44 +0000 |
1614 | @@ -60,6 +60,7 @@ |
1615 | // TODO most of these interfaces are wider DisplayServer needs... |
1616 | // TODO ...some or all of them need narrowing |
1617 | virtual std::shared_ptr<frontend::Connector> the_connector() = 0; |
1618 | + virtual std::shared_ptr<frontend::Connector> the_prompt_connector() = 0; |
1619 | virtual std::shared_ptr<graphics::Display> the_display() = 0; |
1620 | virtual std::shared_ptr<compositor::Compositor> the_compositor() = 0; |
1621 | virtual std::shared_ptr<input::InputManager> the_input_manager() = 0; |
1622 | |
1623 | === added file 'include/shared/mir/basic_observers.h' |
1624 | --- include/shared/mir/basic_observers.h 1970-01-01 00:00:00 +0000 |
1625 | +++ include/shared/mir/basic_observers.h 2014-07-11 20:27:44 +0000 |
1626 | @@ -0,0 +1,122 @@ |
1627 | +/* |
1628 | + * Copyright © 2014 Canonical Ltd. |
1629 | + * |
1630 | + * This program is free software: you can redistribute it and/or modify it |
1631 | + * under the terms of the GNU Lesser General Public License version 3, |
1632 | + * as published by the Free Software Foundation. |
1633 | + * |
1634 | + * This program is distributed in the hope that it will be useful, |
1635 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
1636 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1637 | + * GNU Lesser General Public License for more details. |
1638 | + * |
1639 | + * You should have received a copy of the GNU Lesser General Public License |
1640 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
1641 | + * |
1642 | + * Authored By: Alan Griffiths <alan@octopull.co.uk> |
1643 | + */ |
1644 | + |
1645 | +#ifndef MIR_BASIC_OBSERVERS_H_ |
1646 | +#define MIR_BASIC_OBSERVERS_H_ |
1647 | + |
1648 | +#include "mir/recursive_read_write_mutex.h" |
1649 | + |
1650 | +#include <atomic> |
1651 | +#include <memory> |
1652 | + |
1653 | +namespace mir |
1654 | +{ |
1655 | +template<class Observer> |
1656 | +class BasicObservers |
1657 | +{ |
1658 | +protected: |
1659 | + void add(std::shared_ptr<Observer> const& observer); |
1660 | + void remove(std::shared_ptr<Observer> const& observer); |
1661 | + void for_each(std::function<void(std::shared_ptr<Observer> const& observer)> const& f); |
1662 | + |
1663 | +private: |
1664 | + struct ListItem |
1665 | + { |
1666 | + ListItem() {} |
1667 | + RecursiveReadWriteMutex mutex; |
1668 | + std::shared_ptr<Observer> observer; |
1669 | + std::atomic<ListItem*> next{nullptr}; |
1670 | + |
1671 | + ~ListItem() { delete next.load(); } |
1672 | + } head; |
1673 | +}; |
1674 | + |
1675 | +template<class Observer> |
1676 | +void BasicObservers<Observer>::for_each( |
1677 | + std::function<void(std::shared_ptr<Observer> const& observer)> const& f) |
1678 | +{ |
1679 | + ListItem* current_item = &head; |
1680 | + |
1681 | + while (current_item) |
1682 | + { |
1683 | + RecursiveReadLock lock{current_item->mutex}; |
1684 | + |
1685 | + // We need to take a copy in case we recursively remove during call |
1686 | + if (auto const copy_of_observer = current_item->observer) f(copy_of_observer); |
1687 | + |
1688 | + current_item = current_item->next; |
1689 | + } |
1690 | +} |
1691 | + |
1692 | +template<class Observer> |
1693 | +void BasicObservers<Observer>::add(std::shared_ptr<Observer> const& observer) |
1694 | +{ |
1695 | + ListItem* current_item = &head; |
1696 | + |
1697 | + do |
1698 | + { |
1699 | + // Note: we release the read lock to avoid two threads calling add at |
1700 | + // the same time mutually blocking the other's upgrade to write lock. |
1701 | + { |
1702 | + RecursiveReadLock lock{current_item->mutex}; |
1703 | + if (current_item->observer) continue; |
1704 | + } |
1705 | + |
1706 | + RecursiveWriteLock lock{current_item->mutex}; |
1707 | + |
1708 | + if (!current_item->observer) |
1709 | + { |
1710 | + current_item->observer = observer; |
1711 | + return; |
1712 | + } |
1713 | + } |
1714 | + while (current_item->next && (current_item = current_item->next)); |
1715 | + |
1716 | + // No empty Items so append a new one |
1717 | + auto new_item = new ListItem; |
1718 | + new_item->observer = observer; |
1719 | + |
1720 | + for (ListItem* expected{nullptr}; |
1721 | + !current_item->next.compare_exchange_weak(expected, new_item); |
1722 | + expected = nullptr) |
1723 | + { |
1724 | + current_item = expected; |
1725 | + } |
1726 | +} |
1727 | + |
1728 | +template<class Observer> |
1729 | +void BasicObservers<Observer>::remove(std::shared_ptr<Observer> const& observer) |
1730 | +{ |
1731 | + ListItem* current_item = &head; |
1732 | + |
1733 | + while (current_item) |
1734 | + { |
1735 | + RecursiveWriteLock lock{current_item->mutex}; |
1736 | + |
1737 | + if (current_item->observer == observer) |
1738 | + { |
1739 | + current_item->observer.reset(); |
1740 | + return; |
1741 | + } |
1742 | + |
1743 | + current_item = current_item->next; |
1744 | + } |
1745 | +} |
1746 | +} |
1747 | + |
1748 | +#endif /* MIR_BASIC_OBSERVERS_H_ */ |
1749 | |
1750 | === added file 'include/shared/mir/fd.h' |
1751 | --- include/shared/mir/fd.h 1970-01-01 00:00:00 +0000 |
1752 | +++ include/shared/mir/fd.h 2014-07-11 20:27:44 +0000 |
1753 | @@ -0,0 +1,43 @@ |
1754 | +/* |
1755 | + * Copyright © 2014 Canonical Ltd. |
1756 | + * |
1757 | + * This program is free software: you can redistribute it and/or modify it |
1758 | + * under the terms of the GNU Lesser General Public License version 3, |
1759 | + * as published by the Free Software Foundation. |
1760 | + * |
1761 | + * This program is distributed in the hope that it will be useful, |
1762 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
1763 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1764 | + * GNU Lesser General Public License for more details. |
1765 | + * |
1766 | + * You should have received a copy of the GNU Lesser General Public License |
1767 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
1768 | + * |
1769 | + * Authored by: Kevin DuBois <kevin.dubois@canonical.com> |
1770 | + */ |
1771 | +#ifndef MIR_FD_H_ |
1772 | +#define MIR_FD_H_ |
1773 | + |
1774 | +namespace mir |
1775 | +{ |
1776 | +class Fd |
1777 | +{ |
1778 | +public: |
1779 | + //transfer ownership of the POD-int to the object. The int no longer needs close()ing, |
1780 | + //and has the lifetime of the Fd object. |
1781 | + explicit Fd(int&& fd); |
1782 | + explicit Fd(Fd&&); |
1783 | + Fd& operator=(Fd&&); |
1784 | + ~Fd() noexcept; |
1785 | + |
1786 | + //bit of a convenient kludge. take care not to close or otherwise destroy the FD. |
1787 | + operator int() const; |
1788 | + |
1789 | +private: |
1790 | + Fd(Fd const&) = delete; |
1791 | + Fd& operator=(Fd const&) = delete; |
1792 | + int fd; |
1793 | +}; |
1794 | +} // namespace mir |
1795 | + |
1796 | +#endif // MIR_FD_H_ |
1797 | |
1798 | === modified file 'include/shared/mir/graphics/android/fence.h' |
1799 | --- include/shared/mir/graphics/android/fence.h 2013-10-15 08:53:10 +0000 |
1800 | +++ include/shared/mir/graphics/android/fence.h 2014-07-11 20:27:44 +0000 |
1801 | @@ -26,6 +26,7 @@ |
1802 | namespace android |
1803 | { |
1804 | |
1805 | +//TODO: (kdub) remove this type in favor of mir::Fd |
1806 | typedef int NativeFence; |
1807 | |
1808 | class Fence |
1809 | @@ -34,7 +35,7 @@ |
1810 | virtual ~Fence() = default; |
1811 | |
1812 | virtual void wait() = 0; |
1813 | - virtual void merge_with(NativeFence& merge_fd) = 0; |
1814 | + virtual void merge_with(NativeFence&& merge_fd) = 0; |
1815 | virtual NativeFence copy_native_handle() const = 0; |
1816 | |
1817 | protected: |
1818 | |
1819 | === modified file 'include/shared/mir/graphics/android/sync_fence.h' |
1820 | --- include/shared/mir/graphics/android/sync_fence.h 2013-10-15 08:53:10 +0000 |
1821 | +++ include/shared/mir/graphics/android/sync_fence.h 2014-07-11 20:27:44 +0000 |
1822 | @@ -19,6 +19,7 @@ |
1823 | #define MIR_GRAPHICS_ANDROID_SYNC_FENCE_H_ |
1824 | |
1825 | #include "mir/graphics/android/fence.h" |
1826 | +#include "mir/fd.h" |
1827 | #include <memory> |
1828 | |
1829 | namespace mir |
1830 | @@ -48,18 +49,17 @@ |
1831 | class SyncFence : public Fence |
1832 | { |
1833 | public: |
1834 | - SyncFence(std::shared_ptr<SyncFileOps> const&, int fd); |
1835 | - ~SyncFence() noexcept; |
1836 | + explicit SyncFence(std::shared_ptr<SyncFileOps> const&, Fd&& fd); |
1837 | |
1838 | void wait(); |
1839 | - void merge_with(NativeFence& merge_fd); |
1840 | + void merge_with(NativeFence&& merge_fd); |
1841 | NativeFence copy_native_handle() const; |
1842 | |
1843 | private: |
1844 | SyncFence(SyncFence const&) = delete; |
1845 | SyncFence& operator=(SyncFence const&) = delete; |
1846 | |
1847 | - int fence_fd; |
1848 | + Fd fence_fd; |
1849 | std::shared_ptr<SyncFileOps> const ops; |
1850 | |
1851 | int const infinite_timeout = -1; |
1852 | |
1853 | === added file 'include/shared/mir/recursive_read_write_mutex.h' |
1854 | --- include/shared/mir/recursive_read_write_mutex.h 1970-01-01 00:00:00 +0000 |
1855 | +++ include/shared/mir/recursive_read_write_mutex.h 2014-07-11 20:27:44 +0000 |
1856 | @@ -0,0 +1,77 @@ |
1857 | +/* |
1858 | + * Copyright © 2014 Canonical Ltd. |
1859 | + * |
1860 | + * This program is free software: you can redistribute it and/or modify it |
1861 | + * under the terms of the GNU Lesser General Public License version 3, |
1862 | + * as published by the Free Software Foundation. |
1863 | + * |
1864 | + * This program is distributed in the hope that it will be useful, |
1865 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
1866 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1867 | + * GNU Lesser General Public License for more details. |
1868 | + * |
1869 | + * You should have received a copy of the GNU Lesser General Public License |
1870 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
1871 | + * |
1872 | + * Authored By: Alan Griffiths <alan@octopull.co.uk> |
1873 | + */ |
1874 | + |
1875 | +#ifndef MIR_RECURSIVE_READ_WRITE_MUTEX_H_ |
1876 | +#define MIR_RECURSIVE_READ_WRITE_MUTEX_H_ |
1877 | + |
1878 | +#include <condition_variable> |
1879 | +#include <thread> |
1880 | +#include <vector> |
1881 | + |
1882 | +namespace mir |
1883 | +{ |
1884 | +/** a recursive read-write mutex. |
1885 | + * Note that a write lock can be acquired if no other threads have a read lock. |
1886 | + */ |
1887 | +class RecursiveReadWriteMutex |
1888 | +{ |
1889 | +public: |
1890 | + void read_lock(); |
1891 | + |
1892 | + void read_unlock(); |
1893 | + |
1894 | + void write_lock(); |
1895 | + |
1896 | + void write_unlock(); |
1897 | + |
1898 | +private: |
1899 | + std::mutex mutex; |
1900 | + std::condition_variable cv; |
1901 | + struct ThreadLockCount |
1902 | + { |
1903 | + ThreadLockCount() : id(), count(0) {} |
1904 | + ThreadLockCount(std::thread::id id, unsigned int count) : id(id), count(count) {} |
1905 | + std::thread::id id; |
1906 | + unsigned int count; |
1907 | + }; |
1908 | + std::vector<ThreadLockCount> read_locking_threads; |
1909 | + ThreadLockCount write_locking_thread; |
1910 | +}; |
1911 | + |
1912 | +class RecursiveReadLock |
1913 | +{ |
1914 | +public: |
1915 | + explicit RecursiveReadLock(RecursiveReadWriteMutex& mutex) : mutex(mutex) { mutex.read_lock(); } |
1916 | + ~RecursiveReadLock() { mutex.read_unlock(); } |
1917 | + |
1918 | +private: |
1919 | + RecursiveReadWriteMutex& mutex; |
1920 | +}; |
1921 | + |
1922 | +class RecursiveWriteLock |
1923 | +{ |
1924 | +public: |
1925 | + explicit RecursiveWriteLock(RecursiveReadWriteMutex& mutex) : mutex(mutex) { mutex.write_lock(); } |
1926 | + ~RecursiveWriteLock() { mutex.write_unlock(); } |
1927 | + |
1928 | +private: |
1929 | + RecursiveReadWriteMutex& mutex; |
1930 | +}; |
1931 | +} |
1932 | + |
1933 | +#endif /* MIR_RECURSIVE_READ_WRITE_MUTEX_H_ */ |
1934 | |
1935 | === renamed file 'include/test/mir_test_doubles/mock_android_registrar.h' => 'include/test/mir_test_doubles/mock_buffer_registrar.h' |
1936 | --- include/test/mir_test_doubles/mock_android_registrar.h 2014-03-06 06:05:17 +0000 |
1937 | +++ include/test/mir_test_doubles/mock_buffer_registrar.h 2014-07-11 20:27:44 +0000 |
1938 | @@ -17,11 +17,11 @@ |
1939 | * Kevin DuBois <kevin.dubois@canonical.com> |
1940 | */ |
1941 | |
1942 | -#ifndef MIR_TEST_DOUBLES_MOCK_ANDROID_REGISTRAR_H_ |
1943 | -#define MIR_TEST_DOUBLES_MOCK_ANDROID_REGISTRAR_H_ |
1944 | +#ifndef MIR_TEST_DOUBLES_MOCK_BUFFER_REGISTRAR_H_ |
1945 | +#define MIR_TEST_DOUBLES_MOCK_BUFFER_REGISTRAR_H_ |
1946 | |
1947 | +#include "src/client/android/buffer_registrar.h" |
1948 | #include <gmock/gmock.h> |
1949 | -#include "src/client/android/android_registrar.h" |
1950 | |
1951 | namespace mir |
1952 | { |
1953 | @@ -33,9 +33,9 @@ |
1954 | { |
1955 | namespace doubles |
1956 | { |
1957 | -struct MockAndroidRegistrar : public client::android::AndroidRegistrar |
1958 | +struct MockBufferRegistrar : public client::android::BufferRegistrar |
1959 | { |
1960 | - ~MockAndroidRegistrar() noexcept {} |
1961 | + ~MockBufferRegistrar() noexcept {} |
1962 | MOCK_CONST_METHOD1(register_buffer, |
1963 | std::shared_ptr<const native_handle_t>(std::shared_ptr<MirBufferPackage> const&)); |
1964 | MOCK_METHOD2(secure_for_cpu, std::shared_ptr<char>(std::shared_ptr<const native_handle_t>, geometry::Rectangle)); |
1965 | @@ -44,4 +44,4 @@ |
1966 | } |
1967 | } |
1968 | |
1969 | -#endif /* MIR_TEST_DOUBLES_MOCK_ANDROID_REGISTRAR_H_ */ |
1970 | +#endif /* MIR_TEST_DOUBLES_MOCK_BUFFER_REGISTRAR_H_ */ |
1971 | |
1972 | === modified file 'include/test/mir_test_doubles/mock_fence.h' |
1973 | --- include/test/mir_test_doubles/mock_fence.h 2013-10-10 22:42:31 +0000 |
1974 | +++ include/test/mir_test_doubles/mock_fence.h 2014-07-11 20:27:44 +0000 |
1975 | @@ -32,6 +32,10 @@ |
1976 | |
1977 | struct MockFence : public graphics::android::Fence |
1978 | { |
1979 | + void merge_with(graphics::android::NativeFence&& fence) |
1980 | + { |
1981 | + merge_with(fence); |
1982 | + } |
1983 | MOCK_METHOD0(wait, void()); |
1984 | MOCK_METHOD1(merge_with, void(graphics::android::NativeFence&)); |
1985 | MOCK_CONST_METHOD0(copy_native_handle, graphics::android::NativeFence()); |
1986 | |
1987 | === modified file 'include/test/mir_test_doubles/mock_hwc_device_wrapper.h' |
1988 | --- include/test/mir_test_doubles/mock_hwc_device_wrapper.h 2014-03-19 21:56:42 +0000 |
1989 | +++ include/test/mir_test_doubles/mock_hwc_device_wrapper.h 2014-07-11 20:27:44 +0000 |
1990 | @@ -34,6 +34,11 @@ |
1991 | { |
1992 | MOCK_CONST_METHOD1(prepare, void(hwc_display_contents_1_t&)); |
1993 | MOCK_CONST_METHOD1(set, void(hwc_display_contents_1_t&)); |
1994 | + MOCK_CONST_METHOD1(register_hooks, void(hwc_procs_t*)); |
1995 | + MOCK_CONST_METHOD0(vsync_signal_on, void()); |
1996 | + MOCK_CONST_METHOD0(vsync_signal_off, void()); |
1997 | + MOCK_CONST_METHOD0(display_on, void()); |
1998 | + MOCK_CONST_METHOD0(display_off, void()); |
1999 | }; |
2000 | |
2001 | } |
2002 | |
2003 | === modified file 'include/test/mir_test_doubles/null_client_buffer.h' |
2004 | --- include/test/mir_test_doubles/null_client_buffer.h 2014-01-21 18:03:46 +0000 |
2005 | +++ include/test/mir_test_doubles/null_client_buffer.h 2014-07-11 20:27:44 +0000 |
2006 | @@ -39,8 +39,9 @@ |
2007 | geometry::Stride stride() const { return geometry::Stride(); } |
2008 | MirPixelFormat pixel_format() const { return mir_pixel_format_invalid; } |
2009 | uint32_t age() const { return 0; } |
2010 | - void increment_age() { } |
2011 | + void increment_age() {} |
2012 | void mark_as_submitted() {} |
2013 | + void update_from(MirBufferPackage const&) {} |
2014 | std::shared_ptr<graphics::NativeBuffer> native_buffer_handle() const |
2015 | { |
2016 | return nullptr; |
2017 | |
2018 | === modified file 'include/test/mir_test_doubles/stub_renderable.h' |
2019 | --- include/test/mir_test_doubles/stub_renderable.h 2014-07-01 08:40:57 +0000 |
2020 | +++ include/test/mir_test_doubles/stub_renderable.h 2014-07-11 20:27:44 +0000 |
2021 | @@ -55,6 +55,11 @@ |
2022 | StubRenderable(make_stub_buffer({{},{}}), {{},{}}) |
2023 | {} |
2024 | |
2025 | + void set_buffer(std::shared_ptr<graphics::Buffer> const& buffer) |
2026 | + { |
2027 | + stub_buffer = buffer; |
2028 | + } |
2029 | + |
2030 | ID id() const override |
2031 | { |
2032 | return this; |
2033 | @@ -103,7 +108,7 @@ |
2034 | |
2035 | glm::mat4 trans; |
2036 | geometry::Rectangle const rect; |
2037 | - std::shared_ptr<graphics::Buffer> const stub_buffer; |
2038 | + std::shared_ptr<graphics::Buffer> stub_buffer; |
2039 | }; |
2040 | |
2041 | struct StubTransformedRenderable : public StubRenderable |
2042 | |
2043 | === modified file 'include/test/mir_test_doubles/stub_session_authorizer.h' |
2044 | --- include/test/mir_test_doubles/stub_session_authorizer.h 2014-06-02 17:07:02 +0000 |
2045 | +++ include/test/mir_test_doubles/stub_session_authorizer.h 2014-07-11 20:27:44 +0000 |
2046 | @@ -30,15 +30,19 @@ |
2047 | |
2048 | class StubSessionAuthorizer : public frontend::SessionAuthorizer |
2049 | { |
2050 | - bool connection_is_allowed(mir::frontend::SessionCredentials const&) |
2051 | - { |
2052 | - return true; |
2053 | - } |
2054 | - bool configure_display_is_allowed(mir::frontend::SessionCredentials const&) |
2055 | - { |
2056 | - return true; |
2057 | - } |
2058 | - bool screencast_is_allowed(mir::frontend::SessionCredentials const&) |
2059 | + bool connection_is_allowed(mir::frontend::SessionCredentials const&) override |
2060 | + { |
2061 | + return true; |
2062 | + } |
2063 | + bool configure_display_is_allowed(mir::frontend::SessionCredentials const&) override |
2064 | + { |
2065 | + return true; |
2066 | + } |
2067 | + bool screencast_is_allowed(mir::frontend::SessionCredentials const&) override |
2068 | + { |
2069 | + return true; |
2070 | + } |
2071 | + bool prompt_session_is_allowed(mir::frontend::SessionCredentials const&) override |
2072 | { |
2073 | return true; |
2074 | } |
2075 | |
2076 | === modified file 'include/test/mir_test_framework/in_process_server.h' |
2077 | --- include/test/mir_test_framework/in_process_server.h 2014-06-23 15:57:55 +0000 |
2078 | +++ include/test/mir_test_framework/in_process_server.h 2014-07-11 20:27:44 +0000 |
2079 | @@ -38,6 +38,9 @@ |
2080 | |
2081 | /// \return a connection string for a new client to connect to the server |
2082 | using ServerRunner::new_connection; |
2083 | + |
2084 | + /// \return a connection string for a new client to connect to the prompt server |
2085 | + using ServerRunner::new_prompt_connection; |
2086 | }; |
2087 | } |
2088 | |
2089 | |
2090 | === modified file 'include/test/mir_test_framework/server_runner.h' |
2091 | --- include/test/mir_test_framework/server_runner.h 2014-06-10 12:28:03 +0000 |
2092 | +++ include/test/mir_test_framework/server_runner.h 2014-07-11 20:27:44 +0000 |
2093 | @@ -47,6 +47,9 @@ |
2094 | /// \return a connection string for a new client to connect to the server |
2095 | std::string new_connection(); |
2096 | |
2097 | + /// \return a connection string for a new client to connect to the prompt server |
2098 | + std::string new_prompt_connection(); |
2099 | + |
2100 | private: |
2101 | mir::DisplayServer* start_mir_server(); |
2102 | virtual mir::DefaultServerConfiguration& server_config() = 0; |
2103 | |
2104 | === modified file 'src/client/android/CMakeLists.txt' |
2105 | --- src/client/android/CMakeLists.txt 2014-06-26 19:16:29 +0000 |
2106 | +++ src/client/android/CMakeLists.txt 2014-07-11 20:27:44 +0000 |
2107 | @@ -6,7 +6,7 @@ |
2108 | |
2109 | buffer.cpp |
2110 | android_client_buffer_factory.cpp |
2111 | - android_registrar.cpp |
2112 | + gralloc_registrar.cpp |
2113 | android_client_platform.cpp |
2114 | client_platform_factory.cpp |
2115 | client_surface_interpreter.cpp |
2116 | |
2117 | === modified file 'src/client/android/android_client_buffer_factory.cpp' |
2118 | --- src/client/android/android_client_buffer_factory.cpp 2014-06-26 19:16:29 +0000 |
2119 | +++ src/client/android/android_client_buffer_factory.cpp 2014-07-11 20:27:44 +0000 |
2120 | @@ -18,14 +18,16 @@ |
2121 | */ |
2122 | |
2123 | #include "android_client_buffer_factory.h" |
2124 | +#include "buffer_registrar.h" |
2125 | #include "buffer.h" |
2126 | |
2127 | namespace mcl=mir::client; |
2128 | namespace mcla=mir::client::android; |
2129 | namespace geom=mir::geometry; |
2130 | |
2131 | -mcla::AndroidClientBufferFactory::AndroidClientBufferFactory(std::shared_ptr<AndroidRegistrar> const& buffer_registrar) |
2132 | - : registrar(buffer_registrar) |
2133 | +mcla::AndroidClientBufferFactory::AndroidClientBufferFactory( |
2134 | + std::shared_ptr<BufferRegistrar> const& buffer_registrar) : |
2135 | + registrar(buffer_registrar) |
2136 | { |
2137 | } |
2138 | |
2139 | |
2140 | === modified file 'src/client/android/android_client_buffer_factory.h' |
2141 | --- src/client/android/android_client_buffer_factory.h 2014-03-06 06:05:17 +0000 |
2142 | +++ src/client/android/android_client_buffer_factory.h 2014-07-11 20:27:44 +0000 |
2143 | @@ -33,20 +33,20 @@ |
2144 | namespace client |
2145 | { |
2146 | class ClientBuffer; |
2147 | - |
2148 | namespace android |
2149 | { |
2150 | -class AndroidRegistrar; |
2151 | - |
2152 | +class BufferRegistrar; |
2153 | class AndroidClientBufferFactory : public ClientBufferFactory |
2154 | { |
2155 | public: |
2156 | - explicit AndroidClientBufferFactory(std::shared_ptr<AndroidRegistrar> const&); |
2157 | - |
2158 | - virtual std::shared_ptr<ClientBuffer> create_buffer(std::shared_ptr<MirBufferPackage> const& package, |
2159 | - geometry::Size size, MirPixelFormat pf); |
2160 | + explicit AndroidClientBufferFactory( |
2161 | + std::shared_ptr<BufferRegistrar> const& registrar); |
2162 | + std::shared_ptr<ClientBuffer> create_buffer( |
2163 | + std::shared_ptr<MirBufferPackage> const& package, |
2164 | + geometry::Size size, |
2165 | + MirPixelFormat pf) override; |
2166 | private: |
2167 | - std::shared_ptr<AndroidRegistrar> registrar; |
2168 | + std::shared_ptr<BufferRegistrar> const registrar; |
2169 | }; |
2170 | |
2171 | } |
2172 | |
2173 | === modified file 'src/client/android/android_client_platform.cpp' |
2174 | --- src/client/android/android_client_platform.cpp 2014-03-06 06:05:17 +0000 |
2175 | +++ src/client/android/android_client_platform.cpp 2014-07-11 20:27:44 +0000 |
2176 | @@ -18,7 +18,7 @@ |
2177 | |
2178 | #include "mir/graphics/android/mir_native_window.h" |
2179 | #include "android_client_platform.h" |
2180 | -#include "android_registrar_gralloc.h" |
2181 | +#include "gralloc_registrar.h" |
2182 | #include "android_client_buffer_factory.h" |
2183 | #include "client_surface_interpreter.h" |
2184 | #include "../mir_connection.h" |
2185 | @@ -56,7 +56,7 @@ |
2186 | /* we use an empty deleter because hw_get_module does not give us the ownership of the ptr */ |
2187 | EmptyDeleter empty_del; |
2188 | auto gralloc_dev = std::shared_ptr<gralloc_module_t>(gr_dev, empty_del); |
2189 | - auto registrar = std::make_shared<mcla::AndroidRegistrarGralloc>(gralloc_dev); |
2190 | + auto registrar = std::make_shared<mcla::GrallocRegistrar>(gralloc_dev); |
2191 | return std::make_shared<mcla::AndroidClientBufferFactory>(registrar); |
2192 | } |
2193 | |
2194 | |
2195 | === modified file 'src/client/android/buffer.cpp' |
2196 | --- src/client/android/buffer.cpp 2014-06-26 19:16:29 +0000 |
2197 | +++ src/client/android/buffer.cpp 2014-07-11 20:27:44 +0000 |
2198 | @@ -19,6 +19,7 @@ |
2199 | #include "mir/graphics/android/android_native_buffer.h" |
2200 | #include "mir/graphics/android/sync_fence.h" |
2201 | #include "mir_toolkit/mir_client_library.h" |
2202 | +#include "buffer_registrar.h" |
2203 | #include "buffer.h" |
2204 | #include <hardware/gralloc.h> |
2205 | |
2206 | @@ -28,7 +29,7 @@ |
2207 | namespace mga=mir::graphics::android; |
2208 | |
2209 | mcla::Buffer::Buffer( |
2210 | - std::shared_ptr<AndroidRegistrar> const& registrar, |
2211 | + std::shared_ptr<BufferRegistrar> const& registrar, |
2212 | std::shared_ptr<const native_handle_t> const& handle, |
2213 | geom::Size size, |
2214 | MirPixelFormat pf, |
2215 | @@ -40,7 +41,7 @@ |
2216 | buffer_size(size) |
2217 | { |
2218 | auto ops = std::make_shared<mga::RealSyncFileOps>(); |
2219 | - auto fence = std::make_shared<mga::SyncFence>(ops, -1); |
2220 | + auto fence = std::make_shared<mga::SyncFence>(ops, mir::Fd(-1)); |
2221 | auto anwb = std::shared_ptr<mga::RefCountedNativeBuffer>( |
2222 | new mga::RefCountedNativeBuffer(handle), |
2223 | [](mga::RefCountedNativeBuffer* buffer) |
2224 | @@ -96,3 +97,8 @@ |
2225 | { |
2226 | return native_window_buffer; |
2227 | } |
2228 | + |
2229 | +void mcla::Buffer::update_from(MirBufferPackage const& update_package) |
2230 | +{ |
2231 | + (void) update_package; |
2232 | +} |
2233 | |
2234 | === modified file 'src/client/android/buffer.h' |
2235 | --- src/client/android/buffer.h 2014-06-26 19:16:29 +0000 |
2236 | +++ src/client/android/buffer.h 2014-07-11 20:27:44 +0000 |
2237 | @@ -22,7 +22,6 @@ |
2238 | |
2239 | #include "mir/graphics/android/android_native_buffer.h" |
2240 | #include "../aging_buffer.h" |
2241 | -#include "android_registrar.h" |
2242 | |
2243 | #include <system/window.h> |
2244 | #include <memory> |
2245 | @@ -34,11 +33,12 @@ |
2246 | namespace android |
2247 | { |
2248 | |
2249 | +class BufferRegistrar; |
2250 | class Buffer : public AgingBuffer |
2251 | { |
2252 | public: |
2253 | Buffer( |
2254 | - std::shared_ptr<AndroidRegistrar> const&, |
2255 | + std::shared_ptr<BufferRegistrar> const&, |
2256 | std::shared_ptr<const native_handle_t> const&, |
2257 | geometry::Size size, |
2258 | MirPixelFormat pf, |
2259 | @@ -50,13 +50,14 @@ |
2260 | geometry::Stride stride() const; |
2261 | MirPixelFormat pixel_format() const; |
2262 | std::shared_ptr<mir::graphics::NativeBuffer> native_buffer_handle() const; |
2263 | + void update_from(MirBufferPackage const& update_package); |
2264 | |
2265 | Buffer(const Buffer&) = delete; |
2266 | Buffer& operator=(const Buffer&) = delete; |
2267 | private: |
2268 | void pack_native_window_buffer(); |
2269 | |
2270 | - std::shared_ptr<AndroidRegistrar> buffer_registrar; |
2271 | + std::shared_ptr<BufferRegistrar> buffer_registrar; |
2272 | std::shared_ptr<graphics::android::AndroidNativeBuffer> native_window_buffer; |
2273 | std::shared_ptr<const native_handle_t> native_handle; |
2274 | const MirPixelFormat buffer_pf; |
2275 | |
2276 | === renamed file 'src/client/android/android_registrar.h' => 'src/client/android/buffer_registrar.h' |
2277 | --- src/client/android/android_registrar.h 2013-06-21 22:14:10 +0000 |
2278 | +++ src/client/android/buffer_registrar.h 2014-07-11 20:27:44 +0000 |
2279 | @@ -17,14 +17,14 @@ |
2280 | * Kevin DuBois <kevin.dubois@canonical.com> |
2281 | */ |
2282 | |
2283 | -#ifndef MIR_CLIENT_ANDROID_ANDROID_REGISTRAR_H_ |
2284 | -#define MIR_CLIENT_ANDROID_ANDROID_REGISTRAR_H_ |
2285 | +#ifndef MIR_CLIENT_ANDROID_BUFFER_REGISTRAR_H_ |
2286 | +#define MIR_CLIENT_ANDROID_BUFFER_REGISTRAR_H_ |
2287 | |
2288 | #include <mir_toolkit/mir_native_buffer.h> |
2289 | #include "mir/geometry/rectangle.h" |
2290 | #include <cutils/native_handle.h> |
2291 | - |
2292 | #include <memory> |
2293 | + |
2294 | namespace mir |
2295 | { |
2296 | namespace client |
2297 | @@ -33,16 +33,20 @@ |
2298 | |
2299 | namespace android |
2300 | { |
2301 | -class AndroidRegistrar |
2302 | +class BufferRegistrar |
2303 | { |
2304 | public: |
2305 | - virtual ~AndroidRegistrar() = default; |
2306 | + virtual ~BufferRegistrar() = default; |
2307 | virtual std::shared_ptr<const native_handle_t> register_buffer( |
2308 | std::shared_ptr<MirBufferPackage> const& package) const = 0; |
2309 | virtual std::shared_ptr<char> secure_for_cpu(std::shared_ptr<const native_handle_t> handle, const geometry::Rectangle) = 0; |
2310 | +protected: |
2311 | + BufferRegistrar() = default; |
2312 | + BufferRegistrar(BufferRegistrar const&) = delete; |
2313 | + BufferRegistrar& operator=(BufferRegistrar const&) = delete; |
2314 | }; |
2315 | |
2316 | } |
2317 | } |
2318 | } |
2319 | -#endif /* MIR_CLIENT_ANDROID_REGISTRAR_H_ */ |
2320 | +#endif /* MIR_CLIENT_ANDROID_BUFFER_REGISTRAR_H_ */ |
2321 | |
2322 | === modified file 'src/client/android/client_surface_interpreter.cpp' |
2323 | --- src/client/android/client_surface_interpreter.cpp 2014-05-20 03:37:18 +0000 |
2324 | +++ src/client/android/client_surface_interpreter.cpp 2014-07-11 20:27:44 +0000 |
2325 | @@ -46,7 +46,7 @@ |
2326 | void mcla::ClientSurfaceInterpreter::driver_returns_buffer(ANativeWindowBuffer*, int fence_fd) |
2327 | { |
2328 | //TODO: pass fence to server instead of waiting here |
2329 | - mga::SyncFence sync_fence(sync_ops, fence_fd); |
2330 | + mga::SyncFence sync_fence(sync_ops, mir::Fd(std::move(fence_fd))); |
2331 | sync_fence.wait(); |
2332 | |
2333 | surface.request_and_wait_for_next_buffer(); |
2334 | |
2335 | === renamed file 'src/client/android/android_registrar.cpp' => 'src/client/android/gralloc_registrar.cpp' |
2336 | --- src/client/android/android_registrar.cpp 2014-03-06 06:05:17 +0000 |
2337 | +++ src/client/android/gralloc_registrar.cpp 2014-07-11 20:27:44 +0000 |
2338 | @@ -16,7 +16,7 @@ |
2339 | * Authored by: Kevin DuBois<kevin.dubois@canonical.com> |
2340 | */ |
2341 | |
2342 | -#include "android_registrar_gralloc.h" |
2343 | +#include "gralloc_registrar.h" |
2344 | #include "../client_buffer.h" |
2345 | |
2346 | #include <boost/throw_exception.hpp> |
2347 | @@ -66,12 +66,12 @@ |
2348 | }; |
2349 | } |
2350 | |
2351 | -mcla::AndroidRegistrarGralloc::AndroidRegistrarGralloc(const std::shared_ptr<const gralloc_module_t>& gr_module) |
2352 | +mcla::GrallocRegistrar::GrallocRegistrar(const std::shared_ptr<const gralloc_module_t>& gr_module) |
2353 | : gralloc_module(gr_module) |
2354 | { |
2355 | } |
2356 | |
2357 | -std::shared_ptr<const native_handle_t> mcla::AndroidRegistrarGralloc::register_buffer( |
2358 | +std::shared_ptr<const native_handle_t> mcla::GrallocRegistrar::register_buffer( |
2359 | std::shared_ptr<MirBufferPackage> const& package) const |
2360 | { |
2361 | int native_handle_header_size = sizeof(native_handle_t); |
2362 | @@ -102,7 +102,9 @@ |
2363 | return std::shared_ptr<const native_handle_t>(handle, del); |
2364 | } |
2365 | |
2366 | -std::shared_ptr<char> mcla::AndroidRegistrarGralloc::secure_for_cpu(std::shared_ptr<const native_handle_t> handle, const geometry::Rectangle rect) |
2367 | +std::shared_ptr<char> mcla::GrallocRegistrar::secure_for_cpu( |
2368 | + std::shared_ptr<const native_handle_t> handle, |
2369 | + const geometry::Rectangle rect) |
2370 | { |
2371 | char* vaddr; |
2372 | int usage = GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN; |
2373 | |
2374 | === renamed file 'src/client/android/android_registrar_gralloc.h' => 'src/client/android/gralloc_registrar.h' |
2375 | --- src/client/android/android_registrar_gralloc.h 2014-03-06 06:05:17 +0000 |
2376 | +++ src/client/android/gralloc_registrar.h 2014-07-11 20:27:44 +0000 |
2377 | @@ -17,11 +17,11 @@ |
2378 | * Kevin DuBois <kevin.dubois@canonical.com> |
2379 | */ |
2380 | |
2381 | -#ifndef MIR_CLIENT_ANDROID_ANDROID_REGISTRAR_GRALLOC_H_ |
2382 | -#define MIR_CLIENT_ANDROID_ANDROID_REGISTRAR_GRALLOC_H_ |
2383 | +#ifndef MIR_CLIENT_ANDROID_GRALLOC_REGISTRAR_H_ |
2384 | +#define MIR_CLIENT_ANDROID_GRALLOC_REGISTRAR_H_ |
2385 | |
2386 | #include "mir_toolkit/common.h" |
2387 | -#include "android_registrar.h" |
2388 | +#include "buffer_registrar.h" |
2389 | #include <hardware/gralloc.h> |
2390 | |
2391 | namespace mir |
2392 | @@ -31,10 +31,10 @@ |
2393 | namespace android |
2394 | { |
2395 | |
2396 | -class AndroidRegistrarGralloc : public AndroidRegistrar |
2397 | +class GrallocRegistrar : public BufferRegistrar |
2398 | { |
2399 | public: |
2400 | - AndroidRegistrarGralloc(const std::shared_ptr<const gralloc_module_t>& gralloc_dev); |
2401 | + GrallocRegistrar(const std::shared_ptr<const gralloc_module_t>& gralloc_dev); |
2402 | |
2403 | std::shared_ptr<const native_handle_t> register_buffer( |
2404 | std::shared_ptr<MirBufferPackage> const& package) const; |
2405 | @@ -47,4 +47,4 @@ |
2406 | } |
2407 | } |
2408 | } |
2409 | -#endif /* MIR_CLIENT_ANDROID_ANDROID_REGISTRAR_GRALLOC_H_ */ |
2410 | +#endif /* MIR_CLIENT_ANDROID_GRALLOC_REGISTRAR_H_ */ |
2411 | |
2412 | === modified file 'src/client/client_buffer.h' |
2413 | --- src/client/client_buffer.h 2014-03-06 06:05:17 +0000 |
2414 | +++ src/client/client_buffer.h 2014-07-11 20:27:44 +0000 |
2415 | @@ -62,6 +62,7 @@ |
2416 | virtual void increment_age() = 0; |
2417 | virtual void mark_as_submitted() = 0; |
2418 | virtual std::shared_ptr<graphics::NativeBuffer> native_buffer_handle() const = 0; |
2419 | + virtual void update_from(MirBufferPackage const& update_package) = 0; |
2420 | |
2421 | protected: |
2422 | ClientBuffer() = default; |
2423 | |
2424 | === modified file 'src/client/client_buffer_depository.cpp' |
2425 | --- src/client/client_buffer_depository.cpp 2014-03-06 06:05:17 +0000 |
2426 | +++ src/client/client_buffer_depository.cpp 2014-07-11 20:27:44 +0000 |
2427 | @@ -53,6 +53,7 @@ |
2428 | } |
2429 | else |
2430 | { |
2431 | + existing_buffer_id_pair->second->update_from(*package); |
2432 | buffers.push_front(*existing_buffer_id_pair); |
2433 | buffers.erase(existing_buffer_id_pair); |
2434 | } |
2435 | |
2436 | === modified file 'src/client/mesa/client_buffer.cpp' |
2437 | --- src/client/mesa/client_buffer.cpp 2014-03-06 06:05:17 +0000 |
2438 | +++ src/client/mesa/client_buffer.cpp 2014-07-11 20:27:44 +0000 |
2439 | @@ -131,3 +131,7 @@ |
2440 | creation_package->age = age(); |
2441 | return creation_package; |
2442 | } |
2443 | + |
2444 | +void mclm::ClientBuffer::update_from(MirBufferPackage const&) |
2445 | +{ |
2446 | +} |
2447 | |
2448 | === modified file 'src/client/mesa/client_buffer.h' |
2449 | --- src/client/mesa/client_buffer.h 2014-03-06 06:05:17 +0000 |
2450 | +++ src/client/mesa/client_buffer.h 2014-07-11 20:27:44 +0000 |
2451 | @@ -50,6 +50,7 @@ |
2452 | geometry::Stride stride() const; |
2453 | MirPixelFormat pixel_format() const; |
2454 | std::shared_ptr<MirNativeBuffer> native_buffer_handle() const; |
2455 | + void update_from(MirBufferPackage const&); |
2456 | |
2457 | private: |
2458 | std::shared_ptr<BufferFileOps> const buffer_file_ops; |
2459 | |
2460 | === modified file 'src/client/mir_prompt_session_api.cpp' |
2461 | --- src/client/mir_prompt_session_api.cpp 2014-06-13 10:02:22 +0000 |
2462 | +++ src/client/mir_prompt_session_api.cpp 2014-07-11 20:27:44 +0000 |
2463 | @@ -116,3 +116,15 @@ |
2464 | mir_wait_for(prompt_session->stop(&null_callback, nullptr)); |
2465 | delete prompt_session; |
2466 | } |
2467 | + |
2468 | +MirBool mir_prompt_session_is_valid(MirPromptSession *prompt_session) |
2469 | +{ |
2470 | + auto const err = prompt_session->get_error_message(); |
2471 | + |
2472 | + return MirBool(!*err); |
2473 | +} |
2474 | + |
2475 | +char const *mir_prompt_session_error_message(MirPromptSession *prompt_session) |
2476 | +{ |
2477 | + return prompt_session->get_error_message(); |
2478 | +} |
2479 | |
2480 | === modified file 'src/platform/graphics/android/android_alloc_adaptor.cpp' |
2481 | --- src/platform/graphics/android/android_alloc_adaptor.cpp 2014-06-17 18:24:48 +0000 |
2482 | +++ src/platform/graphics/android/android_alloc_adaptor.cpp 2014-07-11 20:27:44 +0000 |
2483 | @@ -72,7 +72,7 @@ |
2484 | std::shared_ptr<native_handle_t const> handle(buf_handle, del1); |
2485 | |
2486 | auto ops = std::make_shared<mga::RealSyncFileOps>(); |
2487 | - auto fence = std::make_shared<mga::SyncFence>(ops, -1); |
2488 | + auto fence = std::make_shared<mga::SyncFence>(ops, mir::Fd(-1)); |
2489 | |
2490 | auto anwb = std::shared_ptr<mga::RefCountedNativeBuffer>( |
2491 | new mga::RefCountedNativeBuffer(handle), |
2492 | |
2493 | === modified file 'src/platform/graphics/android/hwc_common_device.cpp' |
2494 | --- src/platform/graphics/android/hwc_common_device.cpp 2014-06-16 21:16:14 +0000 |
2495 | +++ src/platform/graphics/android/hwc_common_device.cpp 2014-07-11 20:27:44 +0000 |
2496 | @@ -17,6 +17,7 @@ |
2497 | */ |
2498 | |
2499 | #include "hwc_common_device.h" |
2500 | +#include "hwc_wrapper.h" |
2501 | #include "hwc_vsync_coordinator.h" |
2502 | |
2503 | #include <boost/throw_exception.hpp> |
2504 | @@ -42,8 +43,8 @@ |
2505 | } |
2506 | } |
2507 | |
2508 | -mga::HWCCommonDevice::HWCCommonDevice(std::shared_ptr<hwc_composer_device_1> const& hwc_device, |
2509 | - std::shared_ptr<mga::HWCVsyncCoordinator> const& coordinator) |
2510 | +mga::HWCCommonDevice::HWCCommonDevice(std::shared_ptr<HwcWrapper> const& hwc_device, |
2511 | + std::shared_ptr<HWCVsyncCoordinator> const& coordinator) |
2512 | : coordinator(coordinator), |
2513 | hwc_device(hwc_device), |
2514 | current_mode(mir_power_mode_on) |
2515 | @@ -53,16 +54,23 @@ |
2516 | callbacks.hooks.hotplug = hotplug_hook; |
2517 | callbacks.self = this; |
2518 | |
2519 | - hwc_device->registerProcs(hwc_device.get(), &callbacks.hooks); |
2520 | + hwc_device->register_hooks(&callbacks.hooks); |
2521 | |
2522 | turn_screen_on(); |
2523 | } |
2524 | |
2525 | mga::HWCCommonDevice::~HWCCommonDevice() noexcept |
2526 | { |
2527 | - std::unique_lock<std::mutex> lg(blanked_mutex); |
2528 | if (current_mode == mir_power_mode_on) |
2529 | - turn_screen_off(); |
2530 | + { |
2531 | + std::unique_lock<std::mutex> lg(blanked_mutex); |
2532 | + try |
2533 | + { |
2534 | + turn_screen_off(); |
2535 | + } catch (...) |
2536 | + { |
2537 | + } |
2538 | + } |
2539 | } |
2540 | |
2541 | void mga::HWCCommonDevice::notify_vsync() |
2542 | @@ -73,7 +81,6 @@ |
2543 | void mga::HWCCommonDevice::mode(MirPowerMode mode_request) |
2544 | { |
2545 | std::unique_lock<std::mutex> lg(blanked_mutex); |
2546 | - int err = 0; |
2547 | |
2548 | if ((mode_request == mir_power_mode_suspend) || |
2549 | (mode_request == mir_power_mode_standby)) |
2550 | @@ -84,22 +91,12 @@ |
2551 | if ((mode_request == mir_power_mode_on) && |
2552 | (current_mode == mir_power_mode_off)) |
2553 | { |
2554 | - err = turn_screen_on(); |
2555 | + turn_screen_on(); |
2556 | } |
2557 | else if ((mode_request == mir_power_mode_off) && |
2558 | (current_mode == mir_power_mode_on)) |
2559 | { |
2560 | - err = turn_screen_off(); |
2561 | - } |
2562 | - |
2563 | - if (err) |
2564 | - { |
2565 | - std::string blanking_status_msg = "Could not " + |
2566 | - ((mode_request == mir_power_mode_off) ? std::string("blank") : std::string("unblank")) + " display"; |
2567 | - BOOST_THROW_EXCEPTION( |
2568 | - boost::enable_error_info( |
2569 | - std::runtime_error(blanking_status_msg)) << |
2570 | - boost::errinfo_errno(-err)); |
2571 | + turn_screen_off(); |
2572 | } |
2573 | |
2574 | current_mode = mode_request; |
2575 | @@ -114,18 +111,16 @@ |
2576 | return std::move(lg); |
2577 | } |
2578 | |
2579 | -int mga::HWCCommonDevice::turn_screen_on() const noexcept(true) |
2580 | +void mga::HWCCommonDevice::turn_screen_on() const |
2581 | { |
2582 | - if (auto err = hwc_device->blank(hwc_device.get(), HWC_DISPLAY_PRIMARY, 0)) |
2583 | - return err; |
2584 | - return hwc_device->eventControl(hwc_device.get(), 0, HWC_EVENT_VSYNC, 1); |
2585 | + hwc_device->display_on(); |
2586 | + hwc_device->vsync_signal_on(); |
2587 | } |
2588 | |
2589 | -int mga::HWCCommonDevice::turn_screen_off() const noexcept(true) |
2590 | +void mga::HWCCommonDevice::turn_screen_off() const |
2591 | { |
2592 | - if (auto err = hwc_device->eventControl(hwc_device.get(), 0, HWC_EVENT_VSYNC, 0)) |
2593 | - return err; |
2594 | - return hwc_device->blank(hwc_device.get(), HWC_DISPLAY_PRIMARY, 1); |
2595 | + hwc_device->vsync_signal_off(); |
2596 | + hwc_device->display_off(); |
2597 | } |
2598 | |
2599 | bool mga::HWCCommonDevice::apply_orientation(MirOrientation) const |
2600 | |
2601 | === modified file 'src/platform/graphics/android/hwc_common_device.h' |
2602 | --- src/platform/graphics/android/hwc_common_device.h 2014-03-26 05:48:59 +0000 |
2603 | +++ src/platform/graphics/android/hwc_common_device.h 2014-07-11 20:27:44 +0000 |
2604 | @@ -33,6 +33,7 @@ |
2605 | namespace android |
2606 | { |
2607 | |
2608 | +class HwcWrapper; |
2609 | class HWCVsyncCoordinator; |
2610 | class HWCCommonDevice; |
2611 | struct HWCCallbacks |
2612 | @@ -51,19 +52,19 @@ |
2613 | bool apply_orientation(MirOrientation orientation) const; |
2614 | |
2615 | protected: |
2616 | - HWCCommonDevice(std::shared_ptr<hwc_composer_device_1> const& hwc_device, |
2617 | + HWCCommonDevice(std::shared_ptr<HwcWrapper> const& hwc_wrapper, |
2618 | std::shared_ptr<HWCVsyncCoordinator> const& coordinator); |
2619 | |
2620 | std::shared_ptr<HWCVsyncCoordinator> const coordinator; |
2621 | std::unique_lock<std::mutex> lock_unblanked(); |
2622 | |
2623 | private: |
2624 | - int turn_screen_on() const noexcept(true); |
2625 | - int turn_screen_off() const noexcept(true); |
2626 | + void turn_screen_on() const; |
2627 | + void turn_screen_off() const; |
2628 | |
2629 | HWCCallbacks callbacks; |
2630 | |
2631 | - std::shared_ptr<hwc_composer_device_1> const hwc_device; |
2632 | + std::shared_ptr<HwcWrapper> const hwc_device; |
2633 | |
2634 | std::mutex blanked_mutex; |
2635 | std::condition_variable blanked_cond; |
2636 | |
2637 | === modified file 'src/platform/graphics/android/hwc_device.cpp' |
2638 | --- src/platform/graphics/android/hwc_device.cpp 2014-06-21 02:09:15 +0000 |
2639 | +++ src/platform/graphics/android/hwc_device.cpp 2014-07-11 20:27:44 +0000 |
2640 | @@ -64,57 +64,46 @@ |
2641 | } |
2642 | } |
2643 | |
2644 | -void mga::HwcDevice::setup_layer_types() |
2645 | -{ |
2646 | - auto it = hwc_list.additional_layers_begin(); |
2647 | - auto const num_additional_layers = std::distance(it, hwc_list.end()); |
2648 | - switch (num_additional_layers) |
2649 | - { |
2650 | - case fbtarget_plus_skip_size: |
2651 | - it->set_layer_type(mga::LayerType::skip); |
2652 | - ++it; |
2653 | - case fbtarget_size: |
2654 | - it->set_layer_type(mga::LayerType::framebuffer_target); |
2655 | - default: |
2656 | - break; |
2657 | - } |
2658 | -} |
2659 | - |
2660 | -void mga::HwcDevice::set_list_framebuffer(mg::Buffer const& buffer) |
2661 | -{ |
2662 | - geom::Rectangle const disp_frame{{0,0}, {buffer.size()}}; |
2663 | - for(auto it = hwc_list.additional_layers_begin(); it != hwc_list.end(); it++) |
2664 | - { |
2665 | - //TODO: the functions on mga::Layer should be consolidated |
2666 | - it->set_render_parameters(disp_frame, false); |
2667 | - it->set_buffer(buffer); |
2668 | - it->prepare_for_draw(); |
2669 | - } |
2670 | -} |
2671 | - |
2672 | -mga::HwcDevice::HwcDevice(std::shared_ptr<hwc_composer_device_1> const& hwc_device, |
2673 | - std::shared_ptr<HwcWrapper> const& hwc_wrapper, |
2674 | +mga::HwcDevice::HwcDevice(std::shared_ptr<HwcWrapper> const& hwc_wrapper, |
2675 | std::shared_ptr<HWCVsyncCoordinator> const& coordinator, |
2676 | std::shared_ptr<SyncFileOps> const& sync_ops) |
2677 | - : HWCCommonDevice(hwc_device, coordinator), |
2678 | - hwc_list{{}, 2}, |
2679 | + : HWCCommonDevice(hwc_wrapper, coordinator), |
2680 | + hwc_list{{}, fbtarget_plus_skip_size}, |
2681 | hwc_wrapper(hwc_wrapper), |
2682 | sync_ops(sync_ops) |
2683 | { |
2684 | - setup_layer_types(); |
2685 | } |
2686 | |
2687 | void mga::HwcDevice::post_gl(SwappingGLContext const& context) |
2688 | { |
2689 | - hwc_list.update_list_and_check_if_changed({}, fbtarget_plus_skip_size); |
2690 | - setup_layer_types(); |
2691 | + auto lg = lock_unblanked(); |
2692 | + hwc_list.update_list({}, fbtarget_plus_skip_size); |
2693 | + auto& skip = *hwc_list.additional_layers_begin(); |
2694 | + auto& fbtarget = *(++hwc_list.additional_layers_begin()); |
2695 | + |
2696 | + auto buffer = context.last_rendered_buffer(); |
2697 | + geom::Rectangle const disp_frame{{0,0}, {buffer->size()}}; |
2698 | + skip.layer.setup_layer(mga::LayerType::skip, disp_frame, false, *buffer); |
2699 | + fbtarget.layer.setup_layer(mga::LayerType::framebuffer_target, disp_frame, false, *buffer); |
2700 | |
2701 | hwc_wrapper->prepare(*hwc_list.native_list().lock()); |
2702 | |
2703 | context.swap_buffers(); |
2704 | |
2705 | - post(context); |
2706 | + buffer = context.last_rendered_buffer(); |
2707 | + skip.layer.setup_layer(mga::LayerType::skip, disp_frame, false, *buffer); |
2708 | + fbtarget.layer.setup_layer(mga::LayerType::framebuffer_target, disp_frame, false, *buffer); |
2709 | + |
2710 | + for(auto& layer : hwc_list) |
2711 | + layer.layer.set_acquirefence_from(*buffer); |
2712 | + |
2713 | + hwc_wrapper->set(*hwc_list.native_list().lock()); |
2714 | onscreen_overlay_buffers.clear(); |
2715 | + |
2716 | + for(auto& layer : hwc_list) |
2717 | + layer.layer.update_from_releasefence(*buffer); |
2718 | + |
2719 | + mir::Fd retire_fd(hwc_list.retirement_fence()); |
2720 | } |
2721 | |
2722 | bool mga::HwcDevice::post_overlays( |
2723 | @@ -124,40 +113,63 @@ |
2724 | { |
2725 | if (renderable_list_is_hwc_incompatible(renderables)) |
2726 | return false; |
2727 | - if (!hwc_list.update_list_and_check_if_changed(renderables, fbtarget_size)) |
2728 | + |
2729 | + hwc_list.update_list(renderables, fbtarget_size); |
2730 | + |
2731 | + bool needs_commit{false}; |
2732 | + for(auto& layer : hwc_list) |
2733 | + needs_commit |= layer.needs_commit; |
2734 | + if (!needs_commit) |
2735 | return false; |
2736 | - setup_layer_types(); |
2737 | + |
2738 | + auto lg = lock_unblanked(); |
2739 | + auto& fbtarget = *hwc_list.additional_layers_begin(); |
2740 | + |
2741 | + auto buffer = context.last_rendered_buffer(); |
2742 | + geom::Rectangle const disp_frame{{0,0}, {buffer->size()}}; |
2743 | + fbtarget.layer.setup_layer(mga::LayerType::framebuffer_target, disp_frame, false, *buffer); |
2744 | |
2745 | hwc_wrapper->prepare(*hwc_list.native_list().lock()); |
2746 | |
2747 | mg::RenderableList rejected_renderables; |
2748 | - |
2749 | std::vector<std::shared_ptr<mg::Buffer>> next_onscreen_overlay_buffers; |
2750 | - auto layers_it = hwc_list.begin(); |
2751 | + auto it = hwc_list.begin(); |
2752 | for(auto const& renderable : renderables) |
2753 | { |
2754 | - layers_it->prepare_for_draw(); |
2755 | - if (layers_it->needs_gl_render()) |
2756 | + if (it->layer.needs_gl_render()) |
2757 | + { |
2758 | rejected_renderables.push_back(renderable); |
2759 | + } |
2760 | else |
2761 | + { |
2762 | + if (it->needs_commit) |
2763 | + it->layer.set_acquirefence_from(*renderable->buffer()); |
2764 | next_onscreen_overlay_buffers.push_back(renderable->buffer()); |
2765 | - layers_it++; |
2766 | - } |
2767 | - |
2768 | - list_compositor.render(rejected_renderables, context); |
2769 | - post(context); |
2770 | + } |
2771 | + it++; |
2772 | + } |
2773 | + |
2774 | + if (!rejected_renderables.empty()) |
2775 | + { |
2776 | + list_compositor.render(rejected_renderables, context); |
2777 | + |
2778 | + buffer = context.last_rendered_buffer(); |
2779 | + fbtarget.layer.setup_layer(mga::LayerType::framebuffer_target, disp_frame, false, *buffer); |
2780 | + fbtarget.layer.set_acquirefence_from(*buffer); |
2781 | + } |
2782 | + |
2783 | + hwc_wrapper->set(*hwc_list.native_list().lock()); |
2784 | onscreen_overlay_buffers = std::move(next_onscreen_overlay_buffers); |
2785 | + |
2786 | + it = hwc_list.begin(); |
2787 | + for(auto const& renderable : renderables) |
2788 | + { |
2789 | + it->layer.update_from_releasefence(*renderable->buffer()); |
2790 | + it++; |
2791 | + } |
2792 | + if (!rejected_renderables.empty()) |
2793 | + fbtarget.layer.update_from_releasefence(*buffer); |
2794 | + |
2795 | + mir::Fd retire_fd(hwc_list.retirement_fence()); |
2796 | return true; |
2797 | } |
2798 | - |
2799 | -void mga::HwcDevice::post(SwappingGLContext const& context) |
2800 | -{ |
2801 | - auto lg = lock_unblanked(); |
2802 | - set_list_framebuffer(*context.last_rendered_buffer()); |
2803 | - hwc_wrapper->set(*hwc_list.native_list().lock()); |
2804 | - |
2805 | - for(auto& layer : hwc_list) |
2806 | - layer.update_fence_and_release_buffer(); |
2807 | - |
2808 | - mga::SyncFence retire_fence(sync_ops, hwc_list.retirement_fence()); |
2809 | -} |
2810 | |
2811 | === modified file 'src/platform/graphics/android/hwc_device.h' |
2812 | --- src/platform/graphics/android/hwc_device.h 2014-06-16 14:47:14 +0000 |
2813 | +++ src/platform/graphics/android/hwc_device.h 2014-07-11 20:27:44 +0000 |
2814 | @@ -41,10 +41,7 @@ |
2815 | class HwcDevice : public HWCCommonDevice |
2816 | { |
2817 | public: |
2818 | - //TODO: the first two constructor arguments are redundant. eliminate the 1st one when the 2nd |
2819 | - // one can be used by the HWCCommonDevice |
2820 | - HwcDevice(std::shared_ptr<hwc_composer_device_1> const& hwc_device, |
2821 | - std::shared_ptr<HwcWrapper> const& hwc_wrapper, |
2822 | + HwcDevice(std::shared_ptr<HwcWrapper> const& hwc_wrapper, |
2823 | std::shared_ptr<HWCVsyncCoordinator> const& coordinator, |
2824 | std::shared_ptr<SyncFileOps> const& sync_ops); |
2825 | |
2826 | @@ -55,14 +52,9 @@ |
2827 | RenderableListCompositor const& list_compositor); |
2828 | |
2829 | private: |
2830 | - void post(SwappingGLContext const& context); |
2831 | - |
2832 | LayerList hwc_list; |
2833 | std::vector<std::shared_ptr<Buffer>> onscreen_overlay_buffers; |
2834 | |
2835 | - void set_list_framebuffer(Buffer const&); |
2836 | - void setup_layer_types(); |
2837 | - |
2838 | std::shared_ptr<HwcWrapper> const hwc_wrapper; |
2839 | std::shared_ptr<SyncFileOps> const sync_ops; |
2840 | }; |
2841 | |
2842 | === modified file 'src/platform/graphics/android/hwc_fb_device.cpp' |
2843 | --- src/platform/graphics/android/hwc_fb_device.cpp 2014-06-17 18:24:48 +0000 |
2844 | +++ src/platform/graphics/android/hwc_fb_device.cpp 2014-07-11 20:27:44 +0000 |
2845 | @@ -35,20 +35,22 @@ |
2846 | namespace mga = mir::graphics::android; |
2847 | namespace geom = mir::geometry; |
2848 | |
2849 | -mga::HwcFbDevice::HwcFbDevice(std::shared_ptr<hwc_composer_device_1> const& hwc_device, |
2850 | - std::shared_ptr<HwcWrapper> const& hwc_wrapper, |
2851 | - std::shared_ptr<framebuffer_device_t> const& fb_device, |
2852 | - std::shared_ptr<HWCVsyncCoordinator> const& coordinator) |
2853 | - : HWCCommonDevice(hwc_device, coordinator), |
2854 | - hwc_wrapper(hwc_wrapper), |
2855 | - fb_device(fb_device), |
2856 | - layer_list{{},1} |
2857 | +mga::HwcFbDevice::HwcFbDevice( |
2858 | + std::shared_ptr<HwcWrapper> const& hwc_wrapper, |
2859 | + std::shared_ptr<framebuffer_device_t> const& fb_device, |
2860 | + std::shared_ptr<HWCVsyncCoordinator> const& coordinator) : |
2861 | + HWCCommonDevice(hwc_wrapper, coordinator), |
2862 | + hwc_wrapper(hwc_wrapper), |
2863 | + fb_device(fb_device), |
2864 | + layer_list{{},1} |
2865 | { |
2866 | - layer_list.additional_layers_begin()->set_layer_type(mga::LayerType::skip); |
2867 | } |
2868 | |
2869 | void mga::HwcFbDevice::post_gl(SwappingGLContext const& context) |
2870 | { |
2871 | + auto& buffer = *context.last_rendered_buffer(); |
2872 | + layer_list.begin()->layer.setup_layer(mga::LayerType::skip, {{0,0},buffer.size()}, false, buffer); |
2873 | + |
2874 | if (auto display_list = layer_list.native_list().lock()) |
2875 | { |
2876 | hwc_wrapper->prepare(*display_list); |
2877 | @@ -68,8 +70,8 @@ |
2878 | |
2879 | auto lg = lock_unblanked(); |
2880 | |
2881 | - auto const& buffer = context.last_rendered_buffer(); |
2882 | - auto native_buffer = buffer->native_buffer_handle(); |
2883 | + buffer = *context.last_rendered_buffer(); |
2884 | + auto native_buffer = buffer.native_buffer_handle(); |
2885 | native_buffer->ensure_available_for(mga::BufferAccess::read); |
2886 | if (fb_device->post(fb_device.get(), native_buffer->handle()) != 0) |
2887 | { |
2888 | |
2889 | === modified file 'src/platform/graphics/android/hwc_fb_device.h' |
2890 | --- src/platform/graphics/android/hwc_fb_device.h 2014-06-16 14:47:14 +0000 |
2891 | +++ src/platform/graphics/android/hwc_fb_device.h 2014-07-11 20:27:44 +0000 |
2892 | @@ -35,8 +35,7 @@ |
2893 | class HwcFbDevice : public HWCCommonDevice |
2894 | { |
2895 | public: |
2896 | - HwcFbDevice(std::shared_ptr<hwc_composer_device_1> const& hwc_device, |
2897 | - std::shared_ptr<HwcWrapper> const& hwc_wrapper, |
2898 | + HwcFbDevice(std::shared_ptr<HwcWrapper> const& hwc_wrapper, |
2899 | std::shared_ptr<framebuffer_device_t> const& fb_device, |
2900 | std::shared_ptr<HWCVsyncCoordinator> const& coordinator); |
2901 | |
2902 | |
2903 | === modified file 'src/platform/graphics/android/hwc_layerlist.cpp' |
2904 | --- src/platform/graphics/android/hwc_layerlist.cpp 2014-06-04 23:06:47 +0000 |
2905 | +++ src/platform/graphics/android/hwc_layerlist.cpp 2014-07-11 20:27:44 +0000 |
2906 | @@ -51,13 +51,16 @@ |
2907 | } |
2908 | } |
2909 | |
2910 | -bool mga::LayerList::update_list_and_check_if_changed( |
2911 | - RenderableList const& renderlist, |
2912 | - size_t additional_layers) |
2913 | +mga::HwcLayerEntry::HwcLayerEntry(HWCLayer && layer, bool needs_commit) : |
2914 | + layer(std::move(layer)), |
2915 | + needs_commit{needs_commit} |
2916 | +{ |
2917 | +} |
2918 | + |
2919 | +void mga::LayerList::update_list(RenderableList const& renderlist, size_t additional_layers) |
2920 | { |
2921 | size_t needed_size = renderlist.size() + additional_layers; |
2922 | |
2923 | - bool any_buffer_updated = false; |
2924 | if ((!hwc_representation) || hwc_representation->numHwLayers != needed_size) |
2925 | { |
2926 | hwc_representation = generate_hwc_list(needed_size); |
2927 | @@ -65,21 +68,20 @@ |
2928 | |
2929 | if (layers.size() == needed_size) |
2930 | { |
2931 | - auto layers_it = layers.begin(); |
2932 | + auto it = layers.begin(); |
2933 | for(auto renderable : renderlist) |
2934 | { |
2935 | - layers_it->set_render_parameters( |
2936 | - renderable->screen_position(), renderable->alpha_enabled()); |
2937 | - layers_it->set_buffer(*renderable->buffer()); |
2938 | - any_buffer_updated |= layers_it->needs_hwc_commit(); |
2939 | - layers_it->set_layer_type(mga::LayerType::gl_rendered); |
2940 | - layers_it++; |
2941 | + it->needs_commit = it->layer.setup_layer( |
2942 | + mga::LayerType::gl_rendered, |
2943 | + renderable->screen_position(), |
2944 | + renderable->alpha_enabled(), |
2945 | + *renderable->buffer()); |
2946 | + it++; |
2947 | } |
2948 | } |
2949 | else |
2950 | { |
2951 | - any_buffer_updated = true; |
2952 | - std::list<HWCLayer> new_layers; |
2953 | + std::list<HwcLayerEntry> new_layers; |
2954 | auto i = 0u; |
2955 | for(auto const& renderable : renderlist) |
2956 | { |
2957 | @@ -88,13 +90,13 @@ |
2958 | mga::LayerType::gl_rendered, |
2959 | renderable->screen_position(), |
2960 | renderable->alpha_enabled(), |
2961 | - hwc_representation, i++)); |
2962 | - new_layers.back().set_buffer(*renderable->buffer()); |
2963 | + *renderable->buffer(), |
2964 | + hwc_representation, i++), true); |
2965 | } |
2966 | |
2967 | for(; i < needed_size; i++) |
2968 | { |
2969 | - new_layers.emplace_back(mga::HWCLayer(hwc_representation, i)); |
2970 | + new_layers.emplace_back(mga::HWCLayer(hwc_representation, i), false); |
2971 | } |
2972 | layers = std::move(new_layers); |
2973 | } |
2974 | @@ -108,21 +110,19 @@ |
2975 | first_additional_layer = layers.begin(); |
2976 | std::advance(first_additional_layer, renderlist.size()); |
2977 | } |
2978 | - |
2979 | - return any_buffer_updated; |
2980 | } |
2981 | |
2982 | -std::list<mga::HWCLayer>::iterator mga::LayerList::begin() |
2983 | +std::list<mga::HwcLayerEntry>::iterator mga::LayerList::begin() |
2984 | { |
2985 | return layers.begin(); |
2986 | } |
2987 | |
2988 | -std::list<mga::HWCLayer>::iterator mga::LayerList::additional_layers_begin() |
2989 | +std::list<mga::HwcLayerEntry>::iterator mga::LayerList::additional_layers_begin() |
2990 | { |
2991 | return first_additional_layer; |
2992 | } |
2993 | |
2994 | -std::list<mga::HWCLayer>::iterator mga::LayerList::end() |
2995 | +std::list<mga::HwcLayerEntry>::iterator mga::LayerList::end() |
2996 | { |
2997 | return layers.end(); |
2998 | } |
2999 | @@ -141,6 +141,6 @@ |
3000 | RenderableList const& renderlist, |
3001 | size_t additional_layers) |
3002 | { |
3003 | - update_list_and_check_if_changed(renderlist, additional_layers); |
3004 | + update_list(renderlist, additional_layers); |
3005 | } |
3006 | |
3007 | |
3008 | === modified file 'src/platform/graphics/android/hwc_layerlist.h' |
3009 | --- src/platform/graphics/android/hwc_layerlist.h 2014-03-26 05:48:59 +0000 |
3010 | +++ src/platform/graphics/android/hwc_layerlist.h 2014-07-11 20:27:44 +0000 |
3011 | @@ -39,6 +39,13 @@ |
3012 | namespace android |
3013 | { |
3014 | |
3015 | +struct HwcLayerEntry |
3016 | +{ |
3017 | + HwcLayerEntry(HWCLayer && layer, bool needs_commit); |
3018 | + HWCLayer layer; |
3019 | + bool needs_commit; |
3020 | +}; |
3021 | + |
3022 | /* this is a partitioned list. renderlist makes up the first renderlist.size() elements |
3023 | of the list, and there are additional_layers added to the end. |
3024 | std::distance(begin(), additional_layers_begin()) == renderlist.size() |
3025 | @@ -49,13 +56,11 @@ |
3026 | { |
3027 | public: |
3028 | LayerList(RenderableList const& renderlist, size_t additional_layers); |
3029 | - bool update_list_and_check_if_changed( |
3030 | - RenderableList const& renderlist, |
3031 | - size_t additional_layers); |
3032 | + void update_list(RenderableList const& renderlist, size_t additional_layers); |
3033 | |
3034 | - std::list<HWCLayer>::iterator begin(); |
3035 | - std::list<HWCLayer>::iterator additional_layers_begin(); |
3036 | - std::list<HWCLayer>::iterator end(); |
3037 | + std::list<HwcLayerEntry>::iterator begin(); |
3038 | + std::list<HwcLayerEntry>::iterator additional_layers_begin(); |
3039 | + std::list<HwcLayerEntry>::iterator end(); |
3040 | |
3041 | std::weak_ptr<hwc_display_contents_1_t> native_list(); |
3042 | NativeFence retirement_fence(); |
3043 | @@ -63,9 +68,9 @@ |
3044 | LayerList& operator=(LayerList const&) = delete; |
3045 | LayerList(LayerList const&) = delete; |
3046 | |
3047 | - std::list<HWCLayer> layers; |
3048 | + std::list<HwcLayerEntry> layers; |
3049 | std::shared_ptr<hwc_display_contents_1_t> hwc_representation; |
3050 | - std::list<HWCLayer>::iterator first_additional_layer; |
3051 | + std::list<HwcLayerEntry>::iterator first_additional_layer; |
3052 | }; |
3053 | |
3054 | } |
3055 | |
3056 | === modified file 'src/platform/graphics/android/hwc_layers.cpp' |
3057 | --- src/platform/graphics/android/hwc_layers.cpp 2014-06-21 02:09:15 +0000 |
3058 | +++ src/platform/graphics/android/hwc_layers.cpp 2014-07-11 20:27:44 +0000 |
3059 | @@ -55,8 +55,7 @@ |
3060 | |
3061 | mga::HWCLayer::HWCLayer(std::shared_ptr<hwc_display_contents_1_t> list, size_t layer_index) |
3062 | : hwc_layer(&list->hwLayers[layer_index]), |
3063 | - hwc_list(list), |
3064 | - associated_buffer(nullptr) //todo: take this as a constructor param |
3065 | + hwc_list(list) |
3066 | { |
3067 | memset(hwc_layer, 0, sizeof(hwc_layer_1_t)); |
3068 | memset(&visible_rect, 0, sizeof(hwc_rect_t)); |
3069 | @@ -74,34 +73,40 @@ |
3070 | |
3071 | mga::HWCLayer::HWCLayer( |
3072 | LayerType type, |
3073 | - geometry::Rectangle position, |
3074 | + geometry::Rectangle const& position, |
3075 | bool alpha_enabled, |
3076 | + Buffer const& buffer, |
3077 | std::shared_ptr<hwc_display_contents_1_t> list, |
3078 | size_t layer_index) |
3079 | : HWCLayer(list, layer_index) |
3080 | { |
3081 | - set_layer_type(type); |
3082 | - set_render_parameters(position, alpha_enabled); |
3083 | + setup_layer(type, position, alpha_enabled, buffer); |
3084 | } |
3085 | |
3086 | bool mga::HWCLayer::needs_gl_render() const |
3087 | { |
3088 | - return ((hwc_layer->compositionType == HWC_FRAMEBUFFER) || (hwc_layer->flags == HWC_SKIP_LAYER)); |
3089 | + return (hwc_layer->compositionType == HWC_FRAMEBUFFER); |
3090 | } |
3091 | |
3092 | -void mga::HWCLayer::update_fence_and_release_buffer() |
3093 | +void mga::HWCLayer::update_from_releasefence(mg::Buffer const& buffer) |
3094 | { |
3095 | if (hwc_layer->compositionType != HWC_FRAMEBUFFER) |
3096 | { |
3097 | - associated_buffer->update_usage(hwc_layer->releaseFenceFd, mga::BufferAccess::read); |
3098 | + auto const& native_buffer = buffer.native_buffer_handle(); |
3099 | + native_buffer->update_usage(hwc_layer->releaseFenceFd, mga::BufferAccess::read); |
3100 | hwc_layer->releaseFenceFd = -1; |
3101 | hwc_layer->acquireFenceFd = -1; |
3102 | - associated_buffer.reset(); |
3103 | } |
3104 | } |
3105 | |
3106 | -void mga::HWCLayer::set_layer_type(LayerType type) |
3107 | +bool mga::HWCLayer::setup_layer( |
3108 | + LayerType type, |
3109 | + geometry::Rectangle const& position, |
3110 | + bool alpha_enabled, |
3111 | + Buffer const& buffer) |
3112 | { |
3113 | + bool needs_commit = needs_gl_render(); |
3114 | + |
3115 | hwc_layer->flags = 0; |
3116 | switch(type) |
3117 | { |
3118 | @@ -122,10 +127,7 @@ |
3119 | default: |
3120 | BOOST_THROW_EXCEPTION(std::logic_error("invalid layer type")); |
3121 | } |
3122 | -} |
3123 | |
3124 | -void mga::HWCLayer::set_render_parameters(geometry::Rectangle position, bool alpha_enabled) |
3125 | -{ |
3126 | if (alpha_enabled) |
3127 | hwc_layer->blending = HWC_BLENDING_PREMULT; |
3128 | else |
3129 | @@ -141,45 +143,31 @@ |
3130 | position.bottom_right().x.as_int(), |
3131 | position.bottom_right().y.as_int() |
3132 | }; |
3133 | - |
3134 | - visible_rect = hwc_layer->displayFrame; |
3135 | -} |
3136 | - |
3137 | -void mga::HWCLayer::set_buffer(Buffer const& buffer) |
3138 | -{ |
3139 | - associated_buffer.reset(); |
3140 | - associated_buffer = buffer.native_buffer_handle(); |
3141 | - updated = (hwc_layer->handle != associated_buffer->handle()); |
3142 | - |
3143 | - hwc_layer->handle = associated_buffer->handle(); |
3144 | hwc_layer->sourceCrop = |
3145 | { |
3146 | 0, 0, |
3147 | - associated_buffer->anwb()->width, |
3148 | - associated_buffer->anwb()->height |
3149 | + buffer.size().width.as_int(), |
3150 | + buffer.size().height.as_int() |
3151 | }; |
3152 | + |
3153 | + visible_rect = hwc_layer->displayFrame; |
3154 | + |
3155 | + auto const& native_buffer = buffer.native_buffer_handle(); |
3156 | + needs_commit |= (hwc_layer->handle != native_buffer->handle()); |
3157 | + hwc_layer->handle = native_buffer->handle(); |
3158 | + |
3159 | + return needs_commit; |
3160 | } |
3161 | |
3162 | -void mga::HWCLayer::prepare_for_draw() |
3163 | +void mga::HWCLayer::set_acquirefence_from(mg::Buffer const& buffer) |
3164 | { |
3165 | + hwc_layer->releaseFenceFd = -1; |
3166 | + hwc_layer->acquireFenceFd = -1; |
3167 | //we shouldn't be copying the FD unless the HWC has marked this as a buffer its interested in. |
3168 | //we disregard fences that haven't changed, as the hwc will still own the buffer |
3169 | - if (updated && (((hwc_layer->compositionType == HWC_OVERLAY) || |
3170 | - (hwc_layer->compositionType == HWC_FRAMEBUFFER_TARGET)))) |
3171 | - { |
3172 | - hwc_layer->acquireFenceFd = associated_buffer->copy_fence(); |
3173 | - } |
3174 | - //the HWC is not interested in this buffer. we can release the buffer. |
3175 | - else if (hwc_layer->compositionType == HWC_FRAMEBUFFER) |
3176 | - { |
3177 | - hwc_layer->acquireFenceFd = -1; |
3178 | - associated_buffer.reset(); |
3179 | - } |
3180 | - |
3181 | - hwc_layer->releaseFenceFd = -1; |
3182 | -} |
3183 | - |
3184 | -bool mga::HWCLayer::needs_hwc_commit() const |
3185 | -{ |
3186 | - return (updated || needs_gl_render()); |
3187 | + if (!needs_gl_render()) |
3188 | + { |
3189 | + auto const& native_buffer = buffer.native_buffer_handle(); |
3190 | + hwc_layer->acquireFenceFd = native_buffer->copy_fence(); |
3191 | + } |
3192 | } |
3193 | |
3194 | === modified file 'src/platform/graphics/android/hwc_layers.h' |
3195 | --- src/platform/graphics/android/hwc_layers.h 2014-06-16 21:16:14 +0000 |
3196 | +++ src/platform/graphics/android/hwc_layers.h 2014-07-11 20:27:44 +0000 |
3197 | @@ -50,11 +50,15 @@ |
3198 | class HWCLayer |
3199 | { |
3200 | public: |
3201 | - HWCLayer(std::shared_ptr<hwc_display_contents_1_t> list, size_t layer_index); |
3202 | - HWCLayer(LayerType, |
3203 | - geometry::Rectangle screen_position, |
3204 | - bool alpha_enabled, |
3205 | - std::shared_ptr<hwc_display_contents_1_t> list, size_t layer_index); |
3206 | + HWCLayer( |
3207 | + std::shared_ptr<hwc_display_contents_1_t> list, |
3208 | + size_t layer_index); |
3209 | + HWCLayer( |
3210 | + LayerType, |
3211 | + geometry::Rectangle const& screen_position, |
3212 | + bool alpha_enabled, |
3213 | + Buffer const& buffer, |
3214 | + std::shared_ptr<hwc_display_contents_1_t> list, size_t layer_index); |
3215 | |
3216 | HWCLayer& operator=(HWCLayer && layer); |
3217 | HWCLayer(HWCLayer && layer); |
3218 | @@ -62,20 +66,18 @@ |
3219 | HWCLayer& operator=(HWCLayer const& layer) = delete; |
3220 | HWCLayer(HWCLayer const& layer) = delete; |
3221 | |
3222 | - void set_layer_type(LayerType type); |
3223 | - void set_render_parameters(geometry::Rectangle screen_position, bool alpha_enabled); |
3224 | - void set_buffer(Buffer const& buffer); |
3225 | - |
3226 | - void update_fence_and_release_buffer(); |
3227 | + bool setup_layer( |
3228 | + LayerType type, |
3229 | + geometry::Rectangle const& position, |
3230 | + bool alpha_enabled, |
3231 | + Buffer const& buffer); |
3232 | bool needs_gl_render() const; |
3233 | - bool needs_hwc_commit() const; |
3234 | - void prepare_for_draw(); |
3235 | + void set_acquirefence_from(Buffer const& buffer); |
3236 | + void update_from_releasefence(Buffer const& buffer); |
3237 | private: |
3238 | hwc_layer_1_t* hwc_layer; |
3239 | std::shared_ptr<hwc_display_contents_1_t> hwc_list; |
3240 | hwc_rect_t visible_rect; |
3241 | - std::shared_ptr<NativeBuffer> associated_buffer; |
3242 | - bool updated{false}; |
3243 | }; |
3244 | } |
3245 | } |
3246 | |
3247 | === modified file 'src/platform/graphics/android/hwc_wrapper.h' |
3248 | --- src/platform/graphics/android/hwc_wrapper.h 2014-03-19 21:56:42 +0000 |
3249 | +++ src/platform/graphics/android/hwc_wrapper.h 2014-07-11 20:27:44 +0000 |
3250 | @@ -27,6 +27,7 @@ |
3251 | { |
3252 | namespace android |
3253 | { |
3254 | +struct HWCCallbacks; |
3255 | class HwcWrapper |
3256 | { |
3257 | public: |
3258 | @@ -34,6 +35,11 @@ |
3259 | |
3260 | virtual void prepare(hwc_display_contents_1_t&) const = 0; |
3261 | virtual void set(hwc_display_contents_1_t&) const = 0; |
3262 | + virtual void register_hooks(hwc_procs_t* callbacks) const = 0; |
3263 | + virtual void vsync_signal_on() const = 0; |
3264 | + virtual void vsync_signal_off() const = 0; |
3265 | + virtual void display_on() const = 0; |
3266 | + virtual void display_off() const = 0; |
3267 | |
3268 | protected: |
3269 | HwcWrapper() = default; |
3270 | |
3271 | === modified file 'src/platform/graphics/android/real_hwc_wrapper.cpp' |
3272 | --- src/platform/graphics/android/real_hwc_wrapper.cpp 2014-03-26 05:48:59 +0000 |
3273 | +++ src/platform/graphics/android/real_hwc_wrapper.cpp 2014-07-11 20:27:44 +0000 |
3274 | @@ -60,3 +60,48 @@ |
3275 | BOOST_THROW_EXCEPTION(std::runtime_error(ss.str())); |
3276 | } |
3277 | } |
3278 | + |
3279 | +void mga::RealHwcWrapper::register_hooks(hwc_procs_t* callbacks) const |
3280 | +{ |
3281 | + hwc_device->registerProcs(hwc_device.get(), callbacks); |
3282 | +} |
3283 | + |
3284 | +void mga::RealHwcWrapper::vsync_signal_on() const |
3285 | +{ |
3286 | + if (auto rc = hwc_device->eventControl(hwc_device.get(), 0, HWC_EVENT_VSYNC, 1)) |
3287 | + { |
3288 | + std::stringstream ss; |
3289 | + ss << "error turning vsync signal on. rc = " << std::hex << rc; |
3290 | + BOOST_THROW_EXCEPTION(std::runtime_error(ss.str())); |
3291 | + } |
3292 | +} |
3293 | + |
3294 | +void mga::RealHwcWrapper::vsync_signal_off() const |
3295 | +{ |
3296 | + if (auto rc = hwc_device->eventControl(hwc_device.get(), 0, HWC_EVENT_VSYNC, 0)) |
3297 | + { |
3298 | + std::stringstream ss; |
3299 | + ss << "error turning vsync signal off. rc = " << std::hex << rc; |
3300 | + BOOST_THROW_EXCEPTION(std::runtime_error(ss.str())); |
3301 | + } |
3302 | +} |
3303 | + |
3304 | +void mga::RealHwcWrapper::display_on() const |
3305 | +{ |
3306 | + if (auto rc = hwc_device->blank(hwc_device.get(), HWC_DISPLAY_PRIMARY, 0)) |
3307 | + { |
3308 | + std::stringstream ss; |
3309 | + ss << "error turning display on. rc = " << std::hex << rc; |
3310 | + BOOST_THROW_EXCEPTION(std::runtime_error(ss.str())); |
3311 | + } |
3312 | +} |
3313 | + |
3314 | +void mga::RealHwcWrapper::display_off() const |
3315 | +{ |
3316 | + if (auto rc = hwc_device->blank(hwc_device.get(), HWC_DISPLAY_PRIMARY, 1)) |
3317 | + { |
3318 | + std::stringstream ss; |
3319 | + ss << "error turning display off. rc = " << std::hex << rc; |
3320 | + BOOST_THROW_EXCEPTION(std::runtime_error(ss.str())); |
3321 | + } |
3322 | +} |
3323 | |
3324 | === modified file 'src/platform/graphics/android/real_hwc_wrapper.h' |
3325 | --- src/platform/graphics/android/real_hwc_wrapper.h 2014-03-26 05:48:59 +0000 |
3326 | +++ src/platform/graphics/android/real_hwc_wrapper.h 2014-07-11 20:27:44 +0000 |
3327 | @@ -39,6 +39,11 @@ |
3328 | |
3329 | void prepare(hwc_display_contents_1_t&) const override; |
3330 | void set(hwc_display_contents_1_t&) const override; |
3331 | + void register_hooks(hwc_procs_t* callbacks) const override; |
3332 | + void vsync_signal_on() const override; |
3333 | + void vsync_signal_off() const override; |
3334 | + void display_on() const override; |
3335 | + void display_off() const override; |
3336 | private: |
3337 | static size_t const num_displays{3}; //primary, external, virtual |
3338 | std::shared_ptr<hwc_composer_device_1> const hwc_device; |
3339 | |
3340 | === modified file 'src/platform/graphics/android/resource_factory.cpp' |
3341 | --- src/platform/graphics/android/resource_factory.cpp 2014-06-02 19:36:02 +0000 |
3342 | +++ src/platform/graphics/android/resource_factory.cpp 2014-07-11 20:27:44 +0000 |
3343 | @@ -100,7 +100,7 @@ |
3344 | auto syncer = std::make_shared<mga::HWCVsync>(); |
3345 | auto file_ops = std::make_shared<mga::RealSyncFileOps>(); |
3346 | auto wrapper = std::make_shared<mga::RealHwcWrapper>(hwc_native_device, logger); |
3347 | - return std::make_shared<mga::HwcDevice>(hwc_native_device, wrapper, syncer, file_ops); |
3348 | + return std::make_shared<mga::HwcDevice>(wrapper, syncer, file_ops); |
3349 | } |
3350 | |
3351 | std::shared_ptr<mga::DisplayDevice> mga::ResourceFactory::create_hwc_fb_device( |
3352 | @@ -109,5 +109,5 @@ |
3353 | { |
3354 | auto syncer = std::make_shared<mga::HWCVsync>(); |
3355 | auto wrapper = std::make_shared<mga::RealHwcWrapper>(hwc_native_device, logger); |
3356 | - return std::make_shared<mga::HwcFbDevice>(hwc_native_device, wrapper, fb_native_device, syncer); |
3357 | + return std::make_shared<mga::HwcFbDevice>(wrapper, fb_native_device, syncer); |
3358 | } |
3359 | |
3360 | === modified file 'src/platform/graphics/mesa/cursor.cpp' |
3361 | --- src/platform/graphics/mesa/cursor.cpp 2014-06-17 22:07:15 +0000 |
3362 | +++ src/platform/graphics/mesa/cursor.cpp 2014-07-11 20:27:44 +0000 |
3363 | @@ -35,8 +35,8 @@ |
3364 | |
3365 | namespace |
3366 | { |
3367 | -int const width = 64; |
3368 | -int const height = 64; |
3369 | +int const buffer_width = 64; |
3370 | +int const buffer_height = 64; |
3371 | |
3372 | // Transforms a relative position within the display bounds described by \a rect which is rotated with \a orientation |
3373 | geom::Displacement transform(geom::Rectangle const& rect, geom::Displacement const& vector, MirOrientation orientation) |
3374 | @@ -59,8 +59,8 @@ |
3375 | mgm::Cursor::GBMBOWrapper::GBMBOWrapper(gbm_device* gbm) : |
3376 | buffer(gbm_bo_create( |
3377 | gbm, |
3378 | - width, |
3379 | - height, |
3380 | + buffer_width, |
3381 | + buffer_height, |
3382 | GBM_FORMAT_ARGB8888, |
3383 | GBM_BO_USE_CURSOR_64X64 | GBM_BO_USE_WRITE)) |
3384 | { |
3385 | @@ -82,8 +82,6 @@ |
3386 | current_configuration(current_configuration) |
3387 | { |
3388 | show(*initial_image); |
3389 | - |
3390 | - resume(); |
3391 | } |
3392 | |
3393 | mgm::Cursor::~Cursor() noexcept |
3394 | @@ -91,19 +89,9 @@ |
3395 | hide(); |
3396 | } |
3397 | |
3398 | -void mgm::Cursor::show(CursorImage const& cursor_image) |
3399 | +void mgm::Cursor::write_buffer_data_locked(std::lock_guard<std::mutex> const&, void const* data, size_t count) |
3400 | { |
3401 | - std::lock_guard<std::mutex> lg(guard); |
3402 | - visible = true; |
3403 | - |
3404 | - auto const& size = cursor_image.size(); |
3405 | - |
3406 | - if (size != geometry::Size{width, height}) |
3407 | - BOOST_THROW_EXCEPTION(std::logic_error("No support for cursors that aren't 64x64")); |
3408 | - |
3409 | - auto const count = size.width.as_uint32_t() * size.height.as_uint32_t() * sizeof(uint32_t); |
3410 | - |
3411 | - if (auto result = gbm_bo_write(buffer, cursor_image.as_argb_8888(), count)) |
3412 | + if (auto result = gbm_bo_write(buffer, data, count)) |
3413 | { |
3414 | BOOST_THROW_EXCEPTION( |
3415 | ::boost::enable_error_info(std::runtime_error("failed to initialize gbm buffer")) |
3416 | @@ -111,6 +99,58 @@ |
3417 | } |
3418 | } |
3419 | |
3420 | +void mgm::Cursor::pad_and_write_image_data_locked(std::lock_guard<std::mutex> const& lg, CursorImage const& image) |
3421 | +{ |
3422 | + uint32_t const* image_argb = static_cast<uint32_t const*>(image.as_argb_8888()); |
3423 | + auto image_width = image.size().width.as_uint32_t(); |
3424 | + auto image_height = image.size().height.as_uint32_t(); |
3425 | + |
3426 | + if (image_width > buffer_width || image_height > buffer_height) |
3427 | + { |
3428 | + BOOST_THROW_EXCEPTION(std::logic_error("Image is too big for GBM cursor buffer")); |
3429 | + } |
3430 | + |
3431 | + uint32_t pixels[buffer_width*buffer_height] {}; |
3432 | + // 'pixels' is initialized to transparent so we just need to copy the initial image |
3433 | + // in to the top left corner. |
3434 | + for (unsigned int i = 0; i < image_height; i++) |
3435 | + { |
3436 | + for (unsigned int j = 0; j < image_width; j++) |
3437 | + { |
3438 | + pixels[buffer_width*i+j] = image_argb[image_width*i + j]; |
3439 | + } |
3440 | + } |
3441 | + |
3442 | + auto const count = buffer_width * buffer_height * sizeof(uint32_t); |
3443 | + write_buffer_data_locked(lg, pixels, count); |
3444 | +} |
3445 | + |
3446 | +void mgm::Cursor::show(CursorImage const& cursor_image) |
3447 | +{ |
3448 | + std::lock_guard<std::mutex> lg(guard); |
3449 | + |
3450 | + auto const& size = cursor_image.size(); |
3451 | + |
3452 | + if (size != geometry::Size{buffer_width, buffer_height}) |
3453 | + { |
3454 | + pad_and_write_image_data_locked(lg, cursor_image); |
3455 | + } |
3456 | + else |
3457 | + { |
3458 | + auto const count = size.width.as_uint32_t() * size.height.as_uint32_t() * sizeof(uint32_t); |
3459 | + write_buffer_data_locked(lg, cursor_image.as_argb_8888(), count); |
3460 | + } |
3461 | + hotspot = cursor_image.hotspot(); |
3462 | + |
3463 | + // The hotspot may have changed so we need to call drmModeSetCursor again if the cursor was already visible. |
3464 | + if (visible) |
3465 | + place_cursor_at_locked(lg, current_position, ForceState); |
3466 | + |
3467 | + // Writing the data could throw an exception so lets |
3468 | + // hold off on setting visible until after we have succeeded. |
3469 | + visible = true; |
3470 | +} |
3471 | + |
3472 | void mgm::Cursor::move_to(geometry::Point position) |
3473 | { |
3474 | place_cursor_at(position, UpdateState); |
3475 | @@ -162,6 +202,14 @@ |
3476 | ForceCursorState force_state) |
3477 | { |
3478 | std::lock_guard<std::mutex> lg(guard); |
3479 | + place_cursor_at_locked(lg, position, force_state); |
3480 | +} |
3481 | + |
3482 | +void mgm::Cursor::place_cursor_at_locked( |
3483 | + std::lock_guard<std::mutex> const&, |
3484 | + geometry::Point position, |
3485 | + ForceCursorState force_state) |
3486 | +{ |
3487 | |
3488 | current_position = position; |
3489 | |
3490 | @@ -173,10 +221,15 @@ |
3491 | if (output_rect.contains(position)) |
3492 | { |
3493 | auto dp = transform(output_rect, position - output_rect.top_left, orientation); |
3494 | - output.move_cursor({dp.dx.as_int(), dp.dy.as_int()}); |
3495 | + |
3496 | + // It's a little strange that we implement hotspot this way as there is |
3497 | + // drmModeSetCursor2 with hotspot support. However it appears to not actually |
3498 | + // work on radeon and intel. There also seems to be precedent in weston for |
3499 | + // implementing hotspot in this fashion. |
3500 | + output.move_cursor(geom::Point{dp.dx.as_int(), dp.dy.as_int()} - hotspot); |
3501 | if (force_state || !output.has_cursor()) // TODO - or if orientation had changed - then set buffer.. |
3502 | { |
3503 | - output.set_cursor(buffer);// TODO - select rotated buffer image |
3504 | + output.set_cursor(buffer); |
3505 | } |
3506 | } |
3507 | else |
3508 | |
3509 | === modified file 'src/platform/graphics/mesa/cursor.h' |
3510 | --- src/platform/graphics/mesa/cursor.h 2014-06-17 22:07:15 +0000 |
3511 | +++ src/platform/graphics/mesa/cursor.h 2014-07-11 20:27:44 +0000 |
3512 | @@ -21,6 +21,9 @@ |
3513 | #define MIR_GRAPHICS_MESA_CURSOR_H_ |
3514 | |
3515 | #include "mir/graphics/cursor.h" |
3516 | +#include "mir/geometry/point.h" |
3517 | +#include "mir/geometry/displacement.h" |
3518 | + |
3519 | #include "mir_toolkit/common.h" |
3520 | |
3521 | #include <gbm.h> |
3522 | @@ -82,11 +85,16 @@ |
3523 | enum ForceCursorState { UpdateState, ForceState }; |
3524 | void for_each_used_output(std::function<void(KMSOutput&, geometry::Rectangle const&, MirOrientation orientation)> const& f); |
3525 | void place_cursor_at(geometry::Point position, ForceCursorState force_state); |
3526 | + void place_cursor_at_locked(std::lock_guard<std::mutex> const&, geometry::Point position, ForceCursorState force_state); |
3527 | + void write_buffer_data_locked(std::lock_guard<std::mutex> const&, void const* data, size_t count); |
3528 | + void pad_and_write_image_data_locked(std::lock_guard<std::mutex> const&, CursorImage const& image); |
3529 | |
3530 | std::mutex guard; |
3531 | |
3532 | KMSOutputContainer& output_container; |
3533 | geometry::Point current_position; |
3534 | + geometry::Displacement hotspot; |
3535 | + |
3536 | bool visible; |
3537 | |
3538 | struct GBMBOWrapper |
3539 | |
3540 | === modified file 'src/platform/graphics/mesa/display_buffer.cpp' |
3541 | --- src/platform/graphics/mesa/display_buffer.cpp 2014-06-10 14:40:23 +0000 |
3542 | +++ src/platform/graphics/mesa/display_buffer.cpp 2014-07-11 20:27:44 +0000 |
3543 | @@ -303,7 +303,7 @@ |
3544 | * the next frame, but not for bypass frames. Deferring the flip of |
3545 | * bypass frames would increase the time we held |
3546 | * last_flipped_bypass_buf unacceptably, resulting in client stuttering |
3547 | - * unless we allocate quad-buffers (which I'm trying to avoid). |
3548 | + * unless we allocate more buffers (which I'm trying to avoid). |
3549 | * Also, bypass does not need the deferred page flip because it has |
3550 | * no compositing/rendering step for which to save time for. |
3551 | */ |
3552 | |
3553 | === modified file 'src/platform/options/default_configuration.cpp' |
3554 | --- src/platform/options/default_configuration.cpp 2014-04-15 14:47:19 +0000 |
3555 | +++ src/platform/options/default_configuration.cpp 2014-07-11 20:27:44 +0000 |
3556 | @@ -26,6 +26,7 @@ |
3557 | namespace mo = mir::options; |
3558 | |
3559 | char const* const mo::server_socket_opt = "file,f"; |
3560 | +char const* const mo::prompt_socket_opt = "prompt-file,p"; |
3561 | char const* const mo::no_server_socket_opt = "no-file"; |
3562 | char const* const mo::enable_input_opt = "enable-input,i"; |
3563 | char const* const mo::session_mediator_report_opt = "session-mediator-report"; |
3564 | @@ -77,6 +78,7 @@ |
3565 | (server_socket_opt, po::value<std::string>()->default_value(::mir::default_server_socket), |
3566 | "Socket filename [string:default=$XDG_RUNTIME_DIR/mir_socket or /tmp/mir_socket]") |
3567 | (no_server_socket_opt, "Do not provide a socket filename for client connections") |
3568 | + (prompt_socket_opt, "Provide a \"..._trusted\" filename for prompt helper connections") |
3569 | (platform_graphics_lib, po::value<std::string>()->default_value(default_platform_graphics_lib), |
3570 | "Library to use for platform graphics support") |
3571 | (enable_input_opt, po::value<bool>()->default_value(enable_input_default), |
3572 | |
3573 | === modified file 'src/server/CMakeLists.txt' |
3574 | --- src/server/CMakeLists.txt 2014-06-25 07:27:23 +0000 |
3575 | +++ src/server/CMakeLists.txt 2014-07-11 20:27:44 +0000 |
3576 | @@ -30,6 +30,7 @@ |
3577 | display_server.cpp |
3578 | default_server_configuration.cpp |
3579 | asio_main_loop.cpp |
3580 | + default_emergency_cleanup.cpp |
3581 | ) |
3582 | |
3583 | set(MIRSERVER_LINKAGE SHARED) |
3584 | @@ -47,9 +48,10 @@ |
3585 | mirsharedinput |
3586 | mirsharedgeometry |
3587 | mirsharedlogging |
3588 | + mirsharedfd |
3589 | mirsharedenv |
3590 | mirsharedsharedlibrary |
3591 | - mirsharedthreadname |
3592 | + mirsharedthread |
3593 | mirshell |
3594 | mirscene |
3595 | mirtime |
3596 | @@ -65,6 +67,7 @@ |
3597 | mirplatform |
3598 | mirclient |
3599 | 3rd_party |
3600 | + xcursorloader |
3601 | ${EGL_LDFLAGS} ${EGL_LIBRARIES} |
3602 | ${GLESv2_LDFLAGS} ${GLESv2_LIBRARIES} |
3603 | ${UDEV_LDFLAGS} ${UDEV_LIBRARIES} |
3604 | |
3605 | === modified file 'src/server/asio_main_loop.cpp' |
3606 | --- src/server/asio_main_loop.cpp 2014-06-27 07:07:35 +0000 |
3607 | +++ src/server/asio_main_loop.cpp 2014-07-11 20:27:44 +0000 |
3608 | @@ -352,7 +352,9 @@ |
3609 | { |
3610 | } |
3611 | |
3612 | - std::recursive_mutex m; |
3613 | + std::mutex m; |
3614 | + int callbacks_running = 0; |
3615 | + std::condition_variable callback_done; |
3616 | std::function<void(void)> const callback; |
3617 | State state; |
3618 | }; |
3619 | @@ -381,7 +383,12 @@ |
3620 | if (data->state == mir::time::Alarm::pending) |
3621 | { |
3622 | data->state = mir::time::Alarm::triggered; |
3623 | + ++data->callbacks_running; |
3624 | + lock.unlock(); |
3625 | data->callback(); |
3626 | + lock.lock(); |
3627 | + --data->callbacks_running; |
3628 | + data->callback_done.notify_all(); |
3629 | } |
3630 | } |
3631 | } |
3632 | @@ -420,7 +427,11 @@ |
3633 | |
3634 | bool AlarmImpl::cancel() |
3635 | { |
3636 | - std::lock_guard<decltype(data->m)> lock(data->m); |
3637 | + std::unique_lock<decltype(data->m)> lock(data->m); |
3638 | + |
3639 | + while (data->callbacks_running > 0) |
3640 | + data->callback_done.wait(lock); |
3641 | + |
3642 | if (data->state == triggered) |
3643 | return false; |
3644 | |
3645 | |
3646 | === modified file 'src/server/compositor/buffer_queue.cpp' |
3647 | --- src/server/compositor/buffer_queue.cpp 2014-06-12 15:35:08 +0000 |
3648 | +++ src/server/compositor/buffer_queue.cpp 2014-07-11 20:27:44 +0000 |
3649 | @@ -245,6 +245,10 @@ |
3650 | current_buffer_users.push_back(user_id); |
3651 | current_compositor_buffer = pop(ready_to_composite_queue); |
3652 | } |
3653 | + else if (current_buffer_users.empty()) |
3654 | + { // current_buffer_users and ready_to_composite_queue both empty |
3655 | + current_buffer_users.push_back(user_id); |
3656 | + } |
3657 | |
3658 | buffers_sent_to_compositor.push_back(current_compositor_buffer); |
3659 | |
3660 | |
3661 | === modified file 'src/server/compositor/buffer_queue.h' |
3662 | --- src/server/compositor/buffer_queue.h 2014-06-12 15:35:08 +0000 |
3663 | +++ src/server/compositor/buffer_queue.h 2014-07-11 20:27:44 +0000 |
3664 | @@ -61,11 +61,11 @@ |
3665 | int buffers_ready_for_compositor() const override; |
3666 | int buffers_free_for_client() const override; |
3667 | bool framedropping_allowed() const; |
3668 | + bool is_a_current_buffer_user(void const* user_id) const; |
3669 | |
3670 | private: |
3671 | void give_buffer_to_client(graphics::Buffer* buffer, |
3672 | std::unique_lock<std::mutex> lock); |
3673 | - bool is_a_current_buffer_user(void const* user_id) const; |
3674 | void release(graphics::Buffer* buffer, |
3675 | std::unique_lock<std::mutex> lock); |
3676 | void drop_frame(std::unique_lock<std::mutex> lock); |
3677 | |
3678 | === modified file 'src/server/compositor/buffer_stream_factory.cpp' |
3679 | --- src/server/compositor/buffer_stream_factory.cpp 2014-06-09 17:16:32 +0000 |
3680 | +++ src/server/compositor/buffer_stream_factory.cpp 2014-07-11 20:27:44 +0000 |
3681 | @@ -47,7 +47,7 @@ |
3682 | std::shared_ptr<mc::BufferStream> mc::BufferStreamFactory::create_buffer_stream( |
3683 | mg::BufferProperties const& buffer_properties) |
3684 | { |
3685 | - // Note: Framedropping and bypass both require a minimum 3 buffers |
3686 | + // Note: Framedropping requires a minimum 3 buffers |
3687 | auto switching_bundle = std::make_shared<mc::BufferQueue>(3, gralloc, buffer_properties, *policy_factory); |
3688 | return std::make_shared<mc::BufferStreamSurfaces>(switching_bundle); |
3689 | } |
3690 | |
3691 | === added file 'src/server/default_emergency_cleanup.cpp' |
3692 | --- src/server/default_emergency_cleanup.cpp 1970-01-01 00:00:00 +0000 |
3693 | +++ src/server/default_emergency_cleanup.cpp 2014-07-11 20:27:44 +0000 |
3694 | @@ -0,0 +1,46 @@ |
3695 | +/* |
3696 | + * Copyright © 2014 Canonical Ltd. |
3697 | + * |
3698 | + * This program is free software: you can redistribute it and/or modify it |
3699 | + * under the terms of the GNU General Public License version 3, |
3700 | + * as published by the Free Software Foundation. |
3701 | + * |
3702 | + * This program is distributed in the hope that it will be useful, |
3703 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
3704 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
3705 | + * GNU General Public License for more details. |
3706 | + * |
3707 | + * You should have received a copy of the GNU General Public License |
3708 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
3709 | + * |
3710 | + * Authored by: Alexandros Frantzis <alexandros.frantzis@canonical.com> |
3711 | + */ |
3712 | + |
3713 | +#include "default_emergency_cleanup.h" |
3714 | + |
3715 | +void mir::DefaultEmergencyCleanup::add(EmergencyCleanupHandler const& handler) |
3716 | +{ |
3717 | + std::lock_guard<std::mutex> lock{handlers_mutex}; |
3718 | + |
3719 | + last_item()->next.reset(new ListItem{handler, nullptr}); |
3720 | + ++num_handlers; |
3721 | +} |
3722 | + |
3723 | +void mir::DefaultEmergencyCleanup::operator()() const |
3724 | +{ |
3725 | + int handlers_left = num_handlers; |
3726 | + ListItem const* item = &head; |
3727 | + while (handlers_left-- > 0) |
3728 | + { |
3729 | + item = item->next.get(); |
3730 | + item->handler(); |
3731 | + } |
3732 | +} |
3733 | + |
3734 | +mir::DefaultEmergencyCleanup::ListItem* mir::DefaultEmergencyCleanup::last_item() |
3735 | +{ |
3736 | + ListItem* item = &head; |
3737 | + while (item->next) |
3738 | + item = item->next.get(); |
3739 | + return item; |
3740 | +} |
3741 | |
3742 | === added file 'src/server/default_emergency_cleanup.h' |
3743 | --- src/server/default_emergency_cleanup.h 1970-01-01 00:00:00 +0000 |
3744 | +++ src/server/default_emergency_cleanup.h 2014-07-11 20:27:44 +0000 |
3745 | @@ -0,0 +1,53 @@ |
3746 | +/* |
3747 | + * Copyright © 2014 Canonical Ltd. |
3748 | + * |
3749 | + * This program is free software: you can redistribute it and/or modify it |
3750 | + * under the terms of the GNU General Public License version 3, |
3751 | + * as published by the Free Software Foundation. |
3752 | + * |
3753 | + * This program is distributed in the hope that it will be useful, |
3754 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
3755 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
3756 | + * GNU General Public License for more details. |
3757 | + * |
3758 | + * You should have received a copy of the GNU General Public License |
3759 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
3760 | + * |
3761 | + * Authored by: Alexandros Frantzis <alexandros.frantzis@canonical.com> |
3762 | + */ |
3763 | + |
3764 | +#ifndef MIR_DEFAULT_EMERGENCY_CLEANUP_H_ |
3765 | +#define MIR_DEFAULT_EMERGENCY_CLEANUP_H_ |
3766 | + |
3767 | +#include <mir/emergency_cleanup.h> |
3768 | + |
3769 | +#include <memory> |
3770 | +#include <atomic> |
3771 | +#include <mutex> |
3772 | + |
3773 | +namespace mir |
3774 | +{ |
3775 | + |
3776 | +class DefaultEmergencyCleanup : public EmergencyCleanup |
3777 | +{ |
3778 | +public: |
3779 | + void add(EmergencyCleanupHandler const& handler) override; |
3780 | + void operator()() const override; |
3781 | + |
3782 | +private: |
3783 | + struct ListItem |
3784 | + { |
3785 | + EmergencyCleanupHandler handler; |
3786 | + std::unique_ptr<ListItem> next; |
3787 | + }; |
3788 | + |
3789 | + ListItem* last_item(); |
3790 | + |
3791 | + ListItem head; |
3792 | + std::atomic<int> num_handlers{0}; |
3793 | + std::mutex handlers_mutex; |
3794 | +}; |
3795 | + |
3796 | +} |
3797 | + |
3798 | +#endif |
3799 | |
3800 | === modified file 'src/server/default_server_configuration.cpp' |
3801 | --- src/server/default_server_configuration.cpp 2014-06-17 22:07:15 +0000 |
3802 | +++ src/server/default_server_configuration.cpp 2014-07-11 20:27:44 +0000 |
3803 | @@ -38,10 +38,7 @@ |
3804 | #include "mir/geometry/rectangles.h" |
3805 | #include "mir/default_configuration.h" |
3806 | #include "mir/scene/null_prompt_session_listener.h" |
3807 | - |
3808 | -#include <map> |
3809 | -#include <vector> |
3810 | -#include <mutex> |
3811 | +#include "default_emergency_cleanup.h" |
3812 | |
3813 | namespace mc = mir::compositor; |
3814 | namespace geom = mir::geometry; |
3815 | @@ -139,6 +136,11 @@ |
3816 | { |
3817 | return true; |
3818 | } |
3819 | + |
3820 | + bool prompt_session_is_allowed(mf::SessionCredentials const& /* creds */) override |
3821 | + { |
3822 | + return true; |
3823 | + } |
3824 | }; |
3825 | return session_authorizer( |
3826 | [&]() |
3827 | @@ -147,6 +149,8 @@ |
3828 | }); |
3829 | } |
3830 | |
3831 | +mir::CachedPtr<mir::time::Clock> mir::DefaultServerConfiguration::clock; |
3832 | + |
3833 | std::shared_ptr<mir::time::Clock> mir::DefaultServerConfiguration::the_clock() |
3834 | { |
3835 | return clock( |
3836 | @@ -181,31 +185,6 @@ |
3837 | |
3838 | std::shared_ptr<mir::EmergencyCleanup> mir::DefaultServerConfiguration::the_emergency_cleanup() |
3839 | { |
3840 | - struct DefaultEmergencyCleanup : public EmergencyCleanup |
3841 | - { |
3842 | - void add(EmergencyCleanupHandler const& handler) override |
3843 | - { |
3844 | - std::lock_guard<std::mutex> lock{handlers_mutex}; |
3845 | - handlers.push_back(handler); |
3846 | - } |
3847 | - |
3848 | - void operator()() const override |
3849 | - { |
3850 | - decltype(handlers) handlers_copy; |
3851 | - |
3852 | - { |
3853 | - std::unique_lock<std::mutex> lock{handlers_mutex}; |
3854 | - handlers_copy = handlers; |
3855 | - } |
3856 | - |
3857 | - for (auto const& handler : handlers_copy) |
3858 | - handler(); |
3859 | - } |
3860 | - |
3861 | - mutable std::mutex handlers_mutex; |
3862 | - std::vector<EmergencyCleanupHandler> handlers; |
3863 | - }; |
3864 | - |
3865 | return emergency_cleanup( |
3866 | []() |
3867 | { |
3868 | |
3869 | === modified file 'src/server/display_server.cpp' |
3870 | --- src/server/display_server.cpp 2014-06-03 11:04:15 +0000 |
3871 | +++ src/server/display_server.cpp 2014-07-11 20:27:44 +0000 |
3872 | @@ -77,6 +77,7 @@ |
3873 | input_configuration{config.the_input_configuration()}, |
3874 | compositor{config.the_compositor()}, |
3875 | connector{config.the_connector()}, |
3876 | + prompt_connector{config.the_prompt_connector()}, |
3877 | input_manager{config.the_input_manager()}, |
3878 | main_loop{config.the_main_loop()}, |
3879 | server_status_listener{config.the_server_status_listener()}, |
3880 | @@ -112,6 +113,10 @@ |
3881 | [this] { compositor->stop(); }, |
3882 | [this] { compositor->start(); }}; |
3883 | |
3884 | + TryButRevertIfUnwinding prompt{ |
3885 | + [this] { prompt_connector->stop(); }, |
3886 | + [this] { prompt_connector->start(); }}; |
3887 | + |
3888 | TryButRevertIfUnwinding comm{ |
3889 | [this] { connector->stop(); }, |
3890 | [this] { connector->start(); }}; |
3891 | @@ -140,6 +145,10 @@ |
3892 | [this] { connector->start(); }, |
3893 | [this] { connector->stop(); }}; |
3894 | |
3895 | + TryButRevertIfUnwinding prompt{ |
3896 | + [this] { prompt_connector->start(); }, |
3897 | + [this] { prompt_connector->stop(); }}; |
3898 | + |
3899 | TryButRevertIfUnwinding display_config_processing{ |
3900 | [this] { display_changer->resume_display_config_processing(); }, |
3901 | [this] { display_changer->pause_display_config_processing(); }}; |
3902 | @@ -180,6 +189,7 @@ |
3903 | std::shared_ptr<input::InputConfiguration> const input_configuration; |
3904 | std::shared_ptr<mc::Compositor> const compositor; |
3905 | std::shared_ptr<mf::Connector> const connector; |
3906 | + std::shared_ptr<mf::Connector> const prompt_connector; |
3907 | std::shared_ptr<mi::InputManager> const input_manager; |
3908 | std::shared_ptr<mir::MainLoop> const main_loop; |
3909 | std::shared_ptr<mir::ServerStatusListener> const server_status_listener; |
3910 | @@ -203,6 +213,7 @@ |
3911 | void mir::DisplayServer::run() |
3912 | { |
3913 | p->connector->start(); |
3914 | + p->prompt_connector->start(); |
3915 | p->compositor->start(); |
3916 | p->input_manager->start(); |
3917 | p->input_dispatcher->start(); |
3918 | @@ -214,6 +225,7 @@ |
3919 | p->input_dispatcher->stop(); |
3920 | p->input_manager->stop(); |
3921 | p->compositor->stop(); |
3922 | + p->prompt_connector->stop(); |
3923 | p->connector->stop(); |
3924 | } |
3925 | |
3926 | |
3927 | === modified file 'src/server/frontend/CMakeLists.txt' |
3928 | --- src/server/frontend/CMakeLists.txt 2014-06-02 17:07:02 +0000 |
3929 | +++ src/server/frontend/CMakeLists.txt 2014-07-11 20:27:44 +0000 |
3930 | @@ -3,7 +3,9 @@ |
3931 | |
3932 | client_buffer_tracker.cpp |
3933 | connection_context.cpp |
3934 | + no_prompt_shell.cpp |
3935 | session_mediator.cpp |
3936 | + shell_wrapper.cpp |
3937 | protobuf_message_processor.cpp |
3938 | protobuf_responder.cpp |
3939 | protobuf_buffer_packer.cpp |
3940 | |
3941 | === modified file 'src/server/frontend/default_configuration.cpp' |
3942 | --- src/server/frontend/default_configuration.cpp 2014-06-17 22:07:15 +0000 |
3943 | +++ src/server/frontend/default_configuration.cpp 2014-07-11 20:27:44 +0000 |
3944 | @@ -23,6 +23,7 @@ |
3945 | #include "published_socket_connector.h" |
3946 | |
3947 | #include "mir/frontend/protobuf_connection_creator.h" |
3948 | +#include "mir/frontend/session_authorizer.h" |
3949 | #include "mir/options/configuration.h" |
3950 | #include "mir/options/option.h" |
3951 | |
3952 | @@ -34,9 +35,10 @@ |
3953 | { |
3954 | return connection_creator([this] |
3955 | { |
3956 | + auto const session_authorizer = the_session_authorizer(); |
3957 | return std::make_shared<mf::ProtobufConnectionCreator>( |
3958 | - the_ipc_factory(the_frontend_shell(), the_buffer_allocator()), |
3959 | - the_session_authorizer(), |
3960 | + new_ipc_factory(session_authorizer), |
3961 | + session_authorizer, |
3962 | the_message_processor_report()); |
3963 | }); |
3964 | } |
3965 | @@ -68,6 +70,72 @@ |
3966 | }); |
3967 | } |
3968 | |
3969 | +std::shared_ptr<mf::ConnectionCreator> |
3970 | +mir::DefaultServerConfiguration::the_prompt_connection_creator() |
3971 | +{ |
3972 | + struct PromptSessionAuthorizer : public mf::SessionAuthorizer |
3973 | + { |
3974 | + bool connection_is_allowed(mf::SessionCredentials const& /* creds */) override |
3975 | + { |
3976 | + return true; |
3977 | + } |
3978 | + |
3979 | + bool configure_display_is_allowed(mf::SessionCredentials const& /* creds */) override |
3980 | + { |
3981 | + return true; |
3982 | + } |
3983 | + |
3984 | + bool screencast_is_allowed(mf::SessionCredentials const& /* creds */) override |
3985 | + { |
3986 | + return true; |
3987 | + } |
3988 | + |
3989 | + bool prompt_session_is_allowed(mf::SessionCredentials const& /* creds */) override |
3990 | + { |
3991 | + return true; |
3992 | + } |
3993 | + }; |
3994 | + |
3995 | + return prompt_connection_creator([this] |
3996 | + { |
3997 | + auto const session_authorizer = std::make_shared<PromptSessionAuthorizer>(); |
3998 | + return std::make_shared<mf::ProtobufConnectionCreator>( |
3999 | + new_ipc_factory(session_authorizer), |
4000 | + session_authorizer, |
4001 | + the_message_processor_report()); |
4002 | + }); |
4003 | +} |
4004 | + |
4005 | +std::shared_ptr<mf::Connector> |
4006 | +mir::DefaultServerConfiguration::the_prompt_connector() |
4007 | +{ |
4008 | + return prompt_connector( |
4009 | + [&,this]() -> std::shared_ptr<mf::Connector> |
4010 | + { |
4011 | + auto const threads = the_options()->get<int>(options::frontend_threads_opt); |
4012 | + |
4013 | + if (the_options()->is_set(options::prompt_socket_opt)) |
4014 | + { |
4015 | + return std::make_shared<mf::PublishedSocketConnector>( |
4016 | + the_socket_file() + "_trusted", |
4017 | + the_prompt_connection_creator(), |
4018 | + threads, |
4019 | + *the_emergency_cleanup(), |
4020 | + the_connector_report()); |
4021 | + } |
4022 | + else |
4023 | + { |
4024 | + return std::make_shared<mf::BasicConnector>( |
4025 | + the_prompt_connection_creator(), |
4026 | + threads, |
4027 | + the_connector_report()); |
4028 | + } |
4029 | + }); |
4030 | +} |
4031 | + |
4032 | +// TODO Remove after 0.5.0 is branched: the_ipc_factory() is used by |
4033 | +// TODO clients that use the "PrivateProtobuf" but is it now deprecated |
4034 | +// TODO and only retained as a migration aid. |
4035 | std::shared_ptr<mir::frontend::ProtobufIpcFactory> |
4036 | mir::DefaultServerConfiguration::the_ipc_factory( |
4037 | std::shared_ptr<mf::Shell> const& shell, |
4038 | @@ -87,3 +155,18 @@ |
4039 | the_cursor_images()); |
4040 | }); |
4041 | } |
4042 | + |
4043 | +std::shared_ptr<mir::frontend::ProtobufIpcFactory> |
4044 | +mir::DefaultServerConfiguration::new_ipc_factory( |
4045 | + std::shared_ptr<mf::SessionAuthorizer> const& session_authorizer) |
4046 | +{ |
4047 | + return std::make_shared<mf::DefaultIpcFactory>( |
4048 | + the_frontend_shell(), |
4049 | + the_session_mediator_report(), |
4050 | + the_graphics_platform(), |
4051 | + the_frontend_display_changer(), |
4052 | + the_buffer_allocator(), |
4053 | + the_screencast(), |
4054 | + session_authorizer, |
4055 | + the_cursor_images()); |
4056 | +} |
4057 | |
4058 | === modified file 'src/server/frontend/default_ipc_factory.cpp' |
4059 | --- src/server/frontend/default_ipc_factory.cpp 2014-05-14 21:53:39 +0000 |
4060 | +++ src/server/frontend/default_ipc_factory.cpp 2014-07-11 20:27:44 +0000 |
4061 | @@ -18,6 +18,7 @@ |
4062 | |
4063 | #include "default_ipc_factory.h" |
4064 | |
4065 | +#include "no_prompt_shell.h" |
4066 | #include "session_mediator.h" |
4067 | #include "unauthorized_display_changer.h" |
4068 | #include "unauthorized_screencast.h" |
4069 | @@ -27,6 +28,7 @@ |
4070 | |
4071 | namespace mf = mir::frontend; |
4072 | namespace mg = mir::graphics; |
4073 | +namespace mi = mir::input; |
4074 | |
4075 | mf::DefaultIpcFactory::DefaultIpcFactory( |
4076 | std::shared_ptr<Shell> const& shell, |
4077 | @@ -36,8 +38,9 @@ |
4078 | std::shared_ptr<mg::GraphicBufferAllocator> const& buffer_allocator, |
4079 | std::shared_ptr<Screencast> const& screencast, |
4080 | std::shared_ptr<SessionAuthorizer> const& session_authorizer, |
4081 | - std::shared_ptr<mg::CursorImages> const& cursor_images) : |
4082 | + std::shared_ptr<mi::CursorImages> const& cursor_images) : |
4083 | shell(shell), |
4084 | + no_prompt_shell(std::make_shared<NoPromptShell>(shell)), |
4085 | sm_report(sm_report), |
4086 | cache(std::make_shared<ResourceCache>()), |
4087 | graphics_platform(graphics_platform), |
4088 | @@ -75,8 +78,13 @@ |
4089 | effective_screencast = std::make_shared<UnauthorizedScreencast>(); |
4090 | } |
4091 | |
4092 | + auto const allow_prompt_session = |
4093 | + session_authorizer->prompt_session_is_allowed(creds); |
4094 | + |
4095 | + auto const effective_shell = allow_prompt_session ? shell : no_prompt_shell; |
4096 | + |
4097 | return make_mediator( |
4098 | - shell, |
4099 | + effective_shell, |
4100 | graphics_platform, |
4101 | changer, |
4102 | buffer_allocator, |
4103 | @@ -100,7 +108,7 @@ |
4104 | std::shared_ptr<EventSink> const& sink, |
4105 | std::shared_ptr<Screencast> const& effective_screencast, |
4106 | ConnectionContext const& connection_context, |
4107 | - std::shared_ptr<mg::CursorImages> const& cursor_images) |
4108 | + std::shared_ptr<mi::CursorImages> const& cursor_images) |
4109 | { |
4110 | return std::make_shared<SessionMediator>( |
4111 | shell, |
4112 | |
4113 | === modified file 'src/server/frontend/default_ipc_factory.h' |
4114 | --- src/server/frontend/default_ipc_factory.h 2014-05-14 21:53:39 +0000 |
4115 | +++ src/server/frontend/default_ipc_factory.h 2014-07-11 20:27:44 +0000 |
4116 | @@ -27,6 +27,9 @@ |
4117 | { |
4118 | class Platform; |
4119 | class GraphicBufferAllocator; |
4120 | +} |
4121 | +namespace input |
4122 | +{ |
4123 | class CursorImages; |
4124 | } |
4125 | |
4126 | @@ -49,7 +52,7 @@ |
4127 | std::shared_ptr<graphics::GraphicBufferAllocator> const& buffer_allocator, |
4128 | std::shared_ptr<Screencast> const& screencast, |
4129 | std::shared_ptr<SessionAuthorizer> const& session_authorizer, |
4130 | - std::shared_ptr<graphics::CursorImages> const& cursor_images); |
4131 | + std::shared_ptr<input::CursorImages> const& cursor_images); |
4132 | |
4133 | std::shared_ptr<detail::DisplayServer> make_ipc_server( |
4134 | SessionCredentials const& creds, |
4135 | @@ -67,10 +70,11 @@ |
4136 | std::shared_ptr<EventSink> const& sink, |
4137 | std::shared_ptr<Screencast> const& effective_screencast, |
4138 | ConnectionContext const& connection_context, |
4139 | - std::shared_ptr<graphics::CursorImages> const& cursor_images); |
4140 | + std::shared_ptr<input::CursorImages> const& cursor_images); |
4141 | |
4142 | private: |
4143 | std::shared_ptr<Shell> const shell; |
4144 | + std::shared_ptr<Shell> const no_prompt_shell; |
4145 | std::shared_ptr<SessionMediatorReport> const sm_report; |
4146 | std::shared_ptr<ResourceCache> const cache; |
4147 | std::shared_ptr<graphics::Platform> const graphics_platform; |
4148 | @@ -78,7 +82,7 @@ |
4149 | std::shared_ptr<graphics::GraphicBufferAllocator> const buffer_allocator; |
4150 | std::shared_ptr<Screencast> const screencast; |
4151 | std::shared_ptr<SessionAuthorizer> const session_authorizer; |
4152 | - std::shared_ptr<graphics::CursorImages> const cursor_images; |
4153 | + std::shared_ptr<input::CursorImages> const cursor_images; |
4154 | }; |
4155 | } |
4156 | } |
4157 | |
4158 | === added file 'src/server/frontend/no_prompt_shell.cpp' |
4159 | --- src/server/frontend/no_prompt_shell.cpp 1970-01-01 00:00:00 +0000 |
4160 | +++ src/server/frontend/no_prompt_shell.cpp 2014-07-11 20:27:44 +0000 |
4161 | @@ -0,0 +1,56 @@ |
4162 | +/* |
4163 | + * Copyright © 2014 Canonical Ltd. |
4164 | + * |
4165 | + * This program is free software: you can redistribute it and/or modify it |
4166 | + * under the terms of the GNU General Public License version 3, |
4167 | + * as published by the Free Software Foundation. |
4168 | + * |
4169 | + * This program is distributed in the hope that it will be useful, |
4170 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
4171 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
4172 | + * GNU General Public License for more details. |
4173 | + * |
4174 | + * You should have received a copy of the GNU General Public License |
4175 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
4176 | + * |
4177 | + * Authored By: Alan Griffiths <alan@octopull.co.uk> |
4178 | + */ |
4179 | + |
4180 | +#include "no_prompt_shell.h" |
4181 | + |
4182 | +#include <boost/throw_exception.hpp> |
4183 | +#include <stdexcept> |
4184 | + |
4185 | +namespace mf = mir::frontend; |
4186 | + |
4187 | +namespace |
4188 | +{ |
4189 | +char const* const prompt_sessions_disabled = "Prompt sessions disabled"; |
4190 | +} |
4191 | + |
4192 | +std::shared_ptr<mf::PromptSession> mf::NoPromptShell::start_prompt_session_for( |
4193 | + std::shared_ptr<Session> const& /*session*/, |
4194 | + scene::PromptSessionCreationParameters const& /*params*/) |
4195 | +{ |
4196 | + BOOST_THROW_EXCEPTION(std::runtime_error(prompt_sessions_disabled)); |
4197 | +} |
4198 | + |
4199 | +void mf::NoPromptShell::add_prompt_provider_process_for( |
4200 | + std::shared_ptr<PromptSession> const& /*prompt_session*/, |
4201 | + pid_t /*process_id*/) |
4202 | +{ |
4203 | + BOOST_THROW_EXCEPTION(std::runtime_error(prompt_sessions_disabled)); |
4204 | +} |
4205 | + |
4206 | +void mf::NoPromptShell::add_prompt_provider_for( |
4207 | + std::shared_ptr<PromptSession> const& /*prompt_session*/, |
4208 | + std::shared_ptr<Session> const& /*session*/) |
4209 | +{ |
4210 | + BOOST_THROW_EXCEPTION(std::runtime_error(prompt_sessions_disabled)); |
4211 | +} |
4212 | + |
4213 | +void mf::NoPromptShell::stop_prompt_session( |
4214 | + std::shared_ptr<PromptSession> const& /*prompt_session*/) |
4215 | +{ |
4216 | + BOOST_THROW_EXCEPTION(std::runtime_error(prompt_sessions_disabled)); |
4217 | +} |
4218 | |
4219 | === added file 'src/server/frontend/no_prompt_shell.h' |
4220 | --- src/server/frontend/no_prompt_shell.h 1970-01-01 00:00:00 +0000 |
4221 | +++ src/server/frontend/no_prompt_shell.h 2014-07-11 20:27:44 +0000 |
4222 | @@ -0,0 +1,52 @@ |
4223 | +/* |
4224 | + * Copyright © 2014 Canonical Ltd. |
4225 | + * |
4226 | + * This program is free software: you can redistribute it and/or modify it |
4227 | + * under the terms of the GNU General Public License version 3, |
4228 | + * as published by the Free Software Foundation. |
4229 | + * |
4230 | + * This program is distributed in the hope that it will be useful, |
4231 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
4232 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
4233 | + * GNU General Public License for more details. |
4234 | + * |
4235 | + * You should have received a copy of the GNU General Public License |
4236 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
4237 | + * |
4238 | + * Authored By: Alan Griffiths <alan@octopull.co.uk> |
4239 | + */ |
4240 | + |
4241 | +#ifndef MIR_FRONTEND_NO_PROMPT_SHELL_H_ |
4242 | +#define MIR_FRONTEND_NO_PROMPT_SHELL_H_ |
4243 | + |
4244 | +#include "shell_wrapper.h" |
4245 | + |
4246 | +namespace mir |
4247 | +{ |
4248 | +namespace frontend |
4249 | +{ |
4250 | +class NoPromptShell : public ShellWrapper |
4251 | +{ |
4252 | +public: |
4253 | + |
4254 | + using ShellWrapper::ShellWrapper; |
4255 | + |
4256 | + std::shared_ptr<PromptSession> start_prompt_session_for( |
4257 | + std::shared_ptr<Session> const& session, |
4258 | + scene::PromptSessionCreationParameters const& params) override; |
4259 | + |
4260 | + void add_prompt_provider_process_for( |
4261 | + std::shared_ptr<PromptSession> const& prompt_session, |
4262 | + pid_t process_id) override; |
4263 | + |
4264 | + void add_prompt_provider_for( |
4265 | + std::shared_ptr<PromptSession> const& prompt_session, |
4266 | + std::shared_ptr<Session> const& session) override; |
4267 | + |
4268 | + void stop_prompt_session( |
4269 | + std::shared_ptr<PromptSession> const& prompt_session) override; |
4270 | +}; |
4271 | +} |
4272 | +} |
4273 | + |
4274 | +#endif /* MIR_FRONTEND_NO_PROMPT_SHELL_H_ */ |
4275 | |
4276 | === modified file 'src/server/frontend/protobuf_message_processor.cpp' |
4277 | --- src/server/frontend/protobuf_message_processor.cpp 2014-06-11 16:11:32 +0000 |
4278 | +++ src/server/frontend/protobuf_message_processor.cpp 2014-07-11 20:27:44 +0000 |
4279 | @@ -29,9 +29,14 @@ |
4280 | namespace |
4281 | { |
4282 | template<class Response> |
4283 | -std::vector<int32_t> extract_fds_from(Response* response) |
4284 | +std::vector<mir::Fd> extract_fds_from(Response* response) |
4285 | { |
4286 | - std::vector<int32_t> fd(response->fd().data(), response->fd().data() + response->fd().size()); |
4287 | + std::vector<mir::Fd> fd; |
4288 | + for(auto i = 0u; i < response->fd().size(); ++i) |
4289 | + { |
4290 | + int fence = response->fd().data()[i]; |
4291 | + fd.emplace_back(mir::Fd(std::move(fence))); |
4292 | + } |
4293 | response->clear_fd(); |
4294 | response->set_fds_on_side_channel(fd.size()); |
4295 | return fd; |
4296 | @@ -151,10 +156,6 @@ |
4297 | { |
4298 | invoke(this, display_server.get(), &DisplayServer::release_surface, invocation); |
4299 | } |
4300 | - else if ("test_file_descriptors" == invocation.method_name()) |
4301 | - { |
4302 | - invoke(this, display_server.get(), &DisplayServer::test_file_descriptors, invocation); |
4303 | - } |
4304 | else if ("drm_auth_magic" == invocation.method_name()) |
4305 | { |
4306 | invoke(this, display_server.get(), &DisplayServer::drm_auth_magic, invocation); |
4307 | @@ -228,8 +229,7 @@ |
4308 | |
4309 | void mfd::ProtobufMessageProcessor::send_response(::google::protobuf::uint32 id, mir::protobuf::Buffer* response) |
4310 | { |
4311 | - const auto& fd = extract_fds_from(response); |
4312 | - sender->send_response(id, response, {fd}); |
4313 | + sender->send_response(id, response, {extract_fds_from(response)}); |
4314 | } |
4315 | |
4316 | void mfd::ProtobufMessageProcessor::send_response(::google::protobuf::uint32 id, std::shared_ptr<protobuf::Buffer> response) |
4317 | @@ -239,35 +239,30 @@ |
4318 | |
4319 | void mfd::ProtobufMessageProcessor::send_response(::google::protobuf::uint32 id, mir::protobuf::Connection* response) |
4320 | { |
4321 | - const auto& fd = response->has_platform() ? |
4322 | - extract_fds_from(response->mutable_platform()) : |
4323 | - std::vector<int32_t>(); |
4324 | - |
4325 | - sender->send_response(id, response, {fd}); |
4326 | + if (response->has_platform()) |
4327 | + sender->send_response(id, response, {extract_fds_from(response->mutable_platform())}); |
4328 | + else |
4329 | + sender->send_response(id, response, {}); |
4330 | } |
4331 | |
4332 | void mfd::ProtobufMessageProcessor::send_response(::google::protobuf::uint32 id, mir::protobuf::Surface* response) |
4333 | { |
4334 | - auto const& surface_fd = extract_fds_from(response); |
4335 | - const auto& buffer_fd = response->has_buffer() ? |
4336 | - extract_fds_from(response->mutable_buffer()) : |
4337 | - std::vector<int32_t>(); |
4338 | - |
4339 | - sender->send_response(id, response, {surface_fd, buffer_fd}); |
4340 | + if (response->has_buffer()) |
4341 | + sender->send_response(id, response, {extract_fds_from(response), extract_fds_from(response->mutable_buffer())}); |
4342 | + else |
4343 | + sender->send_response(id, response, {extract_fds_from(response)}); |
4344 | } |
4345 | |
4346 | void mfd::ProtobufMessageProcessor::send_response( |
4347 | ::google::protobuf::uint32 id, mir::protobuf::Screencast* response) |
4348 | { |
4349 | - auto const& buffer_fd = response->has_buffer() ? |
4350 | - extract_fds_from(response->mutable_buffer()) : |
4351 | - std::vector<int32_t>(); |
4352 | - |
4353 | - sender->send_response(id, response, {buffer_fd}); |
4354 | + if (response->has_buffer()) |
4355 | + sender->send_response(id, response, {extract_fds_from(response->mutable_buffer())}); |
4356 | + else |
4357 | + sender->send_response(id, response, {}); |
4358 | } |
4359 | |
4360 | void mfd::ProtobufMessageProcessor::send_response(::google::protobuf::uint32 id, mir::protobuf::SocketFD* response) |
4361 | { |
4362 | - const auto& fd = extract_fds_from(response); |
4363 | - sender->send_response(id, response, {fd}); |
4364 | + sender->send_response(id, response, {extract_fds_from(response)}); |
4365 | } |
4366 | |
4367 | === modified file 'src/server/frontend/session_mediator.cpp' |
4368 | --- src/server/frontend/session_mediator.cpp 2014-06-23 02:57:39 +0000 |
4369 | +++ src/server/frontend/session_mediator.cpp 2014-07-11 20:27:44 +0000 |
4370 | @@ -29,7 +29,7 @@ |
4371 | #include "mir_toolkit/common.h" |
4372 | #include "mir/graphics/buffer_id.h" |
4373 | #include "mir/graphics/buffer.h" |
4374 | -#include "mir/graphics/cursor_images.h" |
4375 | +#include "mir/input/cursor_images.h" |
4376 | #include "mir/compositor/buffer_stream.h" |
4377 | #include "mir/geometry/dimensions.h" |
4378 | #include "mir/frontend/display_changer.h" |
4379 | @@ -58,6 +58,7 @@ |
4380 | namespace mf = mir::frontend; |
4381 | namespace mfd=mir::frontend::detail; |
4382 | namespace mg = mir::graphics; |
4383 | +namespace mi = mir::input; |
4384 | namespace geom = mir::geometry; |
4385 | |
4386 | mf::SessionMediator::SessionMediator( |
4387 | @@ -70,7 +71,7 @@ |
4388 | std::shared_ptr<ResourceCache> const& resource_cache, |
4389 | std::shared_ptr<Screencast> const& screencast, |
4390 | ConnectionContext const& connection_context, |
4391 | - std::shared_ptr<mg::CursorImages> const& cursor_images) : |
4392 | + std::shared_ptr<mi::CursorImages> const& cursor_images) : |
4393 | client_pid_(0), |
4394 | shell(shell), |
4395 | graphics_platform(graphics_platform), |
4396 | @@ -464,7 +465,7 @@ |
4397 | |
4398 | if (cursor_request->has_name()) |
4399 | { |
4400 | - auto const& image = cursor_images->image(cursor_request->name(), mg::default_cursor_size); |
4401 | + auto const& image = cursor_images->image(cursor_request->name(), mi::default_cursor_size); |
4402 | surface->set_cursor_image(image); |
4403 | } |
4404 | else |
4405 | |
4406 | === modified file 'src/server/frontend/session_mediator.h' |
4407 | --- src/server/frontend/session_mediator.h 2014-06-23 02:57:39 +0000 |
4408 | +++ src/server/frontend/session_mediator.h 2014-07-11 20:27:44 +0000 |
4409 | @@ -39,6 +39,9 @@ |
4410 | class Platform; |
4411 | class Display; |
4412 | class GraphicBufferAllocator; |
4413 | +} |
4414 | +namespace input |
4415 | +{ |
4416 | class CursorImages; |
4417 | } |
4418 | |
4419 | @@ -72,7 +75,7 @@ |
4420 | std::shared_ptr<ResourceCache> const& resource_cache, |
4421 | std::shared_ptr<Screencast> const& screencast, |
4422 | ConnectionContext const& connection_context, |
4423 | - std::shared_ptr<graphics::CursorImages> const& cursor_images); |
4424 | + std::shared_ptr<input::CursorImages> const& cursor_images); |
4425 | |
4426 | ~SessionMediator() noexcept; |
4427 | |
4428 | @@ -186,7 +189,7 @@ |
4429 | std::shared_ptr<ResourceCache> const resource_cache; |
4430 | std::shared_ptr<Screencast> const screencast; |
4431 | ConnectionContext const connection_context; |
4432 | - std::shared_ptr<graphics::CursorImages> const cursor_images; |
4433 | + std::shared_ptr<input::CursorImages> const cursor_images; |
4434 | |
4435 | std::unordered_map<SurfaceId,graphics::Buffer*> client_buffer_resource; |
4436 | std::unordered_map<SurfaceId, std::shared_ptr<ClientBufferTracker>> client_buffer_tracker; |
4437 | |
4438 | === added file 'src/server/frontend/shell_wrapper.cpp' |
4439 | --- src/server/frontend/shell_wrapper.cpp 1970-01-01 00:00:00 +0000 |
4440 | +++ src/server/frontend/shell_wrapper.cpp 2014-07-11 20:27:44 +0000 |
4441 | @@ -0,0 +1,74 @@ |
4442 | +/* |
4443 | + * Copyright © 2014 Canonical Ltd. |
4444 | + * |
4445 | + * This program is free software: you can redistribute it and/or modify it |
4446 | + * under the terms of the GNU General Public License version 3, |
4447 | + * as published by the Free Software Foundation. |
4448 | + * |
4449 | + * This program is distributed in the hope that it will be useful, |
4450 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
4451 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
4452 | + * GNU General Public License for more details. |
4453 | + * |
4454 | + * You should have received a copy of the GNU General Public License |
4455 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
4456 | + * |
4457 | + * Authored By: Alan Griffiths <alan@octopull.co.uk> |
4458 | + */ |
4459 | + |
4460 | +#include "shell_wrapper.h" |
4461 | + |
4462 | +namespace mf = mir::frontend; |
4463 | + |
4464 | +std::shared_ptr<mf::Session> mf::ShellWrapper::open_session( |
4465 | + pid_t client_pid, |
4466 | + std::string const& name, |
4467 | + std::shared_ptr<EventSink> const& sink) |
4468 | +{ |
4469 | + return wrapped->open_session(client_pid, name,sink); |
4470 | +} |
4471 | + |
4472 | +void mf::ShellWrapper::close_session(std::shared_ptr<Session> const& session) |
4473 | +{ |
4474 | + wrapped->close_session(session); |
4475 | +} |
4476 | + |
4477 | +mf::SurfaceId mf::ShellWrapper::create_surface_for( |
4478 | + std::shared_ptr<Session> const& session, |
4479 | + scene::SurfaceCreationParameters const& params) |
4480 | +{ |
4481 | + return wrapped->create_surface_for(session, params); |
4482 | +} |
4483 | + |
4484 | +void mf::ShellWrapper::handle_surface_created( |
4485 | + std::shared_ptr<Session> const& session) |
4486 | +{ |
4487 | + wrapped->handle_surface_created(session); |
4488 | +} |
4489 | + |
4490 | +std::shared_ptr<mf::PromptSession> mf::ShellWrapper::start_prompt_session_for( |
4491 | + std::shared_ptr<Session> const& session, |
4492 | + scene::PromptSessionCreationParameters const& params) |
4493 | +{ |
4494 | + return wrapped->start_prompt_session_for(session, params); |
4495 | +} |
4496 | + |
4497 | +void mf::ShellWrapper::add_prompt_provider_process_for( |
4498 | + std::shared_ptr<PromptSession> const& prompt_session, |
4499 | + pid_t process_id) |
4500 | +{ |
4501 | + wrapped->add_prompt_provider_process_for(prompt_session, process_id); |
4502 | +} |
4503 | + |
4504 | +void mf::ShellWrapper::add_prompt_provider_for( |
4505 | + std::shared_ptr<PromptSession> const& prompt_session, |
4506 | + std::shared_ptr<Session> const& session) |
4507 | +{ |
4508 | + wrapped->add_prompt_provider_for(prompt_session, session); |
4509 | +} |
4510 | + |
4511 | +void mf::ShellWrapper::stop_prompt_session( |
4512 | + std::shared_ptr<PromptSession> const& prompt_session) |
4513 | +{ |
4514 | + wrapped->stop_prompt_session(prompt_session); |
4515 | +} |
4516 | |
4517 | === added file 'src/server/frontend/shell_wrapper.h' |
4518 | --- src/server/frontend/shell_wrapper.h 1970-01-01 00:00:00 +0000 |
4519 | +++ src/server/frontend/shell_wrapper.h 2014-07-11 20:27:44 +0000 |
4520 | @@ -0,0 +1,70 @@ |
4521 | +/* |
4522 | + * Copyright © 2014 Canonical Ltd. |
4523 | + * |
4524 | + * This program is free software: you can redistribute it and/or modify it |
4525 | + * under the terms of the GNU General Public License version 3, |
4526 | + * as published by the Free Software Foundation. |
4527 | + * |
4528 | + * This program is distributed in the hope that it will be useful, |
4529 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
4530 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
4531 | + * GNU General Public License for more details. |
4532 | + * |
4533 | + * You should have received a copy of the GNU General Public License |
4534 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
4535 | + * |
4536 | + * Authored By: Alan Griffiths <alan@octopull.co.uk> |
4537 | + */ |
4538 | + |
4539 | +#ifndef MIR_FRONTEND_SHELL_WRAPPER_H_ |
4540 | +#define MIR_FRONTEND_SHELL_WRAPPER_H_ |
4541 | + |
4542 | +#include "mir/frontend/shell.h" |
4543 | + |
4544 | +namespace mir |
4545 | +{ |
4546 | +namespace frontend |
4547 | +{ |
4548 | +class ShellWrapper : public Shell |
4549 | +{ |
4550 | +public: |
4551 | + explicit ShellWrapper(std::shared_ptr<Shell> const& wrapped) : |
4552 | + wrapped(wrapped) {} |
4553 | + |
4554 | + virtual ~ShellWrapper() = default; |
4555 | + |
4556 | + std::shared_ptr<Session> open_session( |
4557 | + pid_t client_pid, |
4558 | + std::string const& name, |
4559 | + std::shared_ptr<EventSink> const& sink) override; |
4560 | + |
4561 | + void close_session(std::shared_ptr<Session> const& session) override; |
4562 | + |
4563 | + SurfaceId create_surface_for( |
4564 | + std::shared_ptr<Session> const& session, |
4565 | + scene::SurfaceCreationParameters const& params) override; |
4566 | + |
4567 | + void handle_surface_created(std::shared_ptr<Session> const& session) override; |
4568 | + |
4569 | + std::shared_ptr<PromptSession> start_prompt_session_for( |
4570 | + std::shared_ptr<Session> const& session, |
4571 | + scene::PromptSessionCreationParameters const& params) override; |
4572 | + |
4573 | + void add_prompt_provider_process_for( |
4574 | + std::shared_ptr<PromptSession> const& prompt_session, |
4575 | + pid_t process_id) override; |
4576 | + |
4577 | + void add_prompt_provider_for( |
4578 | + std::shared_ptr<PromptSession> const& prompt_session, |
4579 | + std::shared_ptr<Session> const& session) override; |
4580 | + |
4581 | + void stop_prompt_session( |
4582 | + std::shared_ptr<PromptSession> const& prompt_session) override; |
4583 | + |
4584 | +protected: |
4585 | + std::shared_ptr<Shell> const wrapped; |
4586 | +}; |
4587 | +} |
4588 | +} |
4589 | + |
4590 | +#endif /* MIR_FRONTEND_SHELL_WRAPPER_H_ */ |
4591 | |
4592 | === modified file 'src/server/frontend/socket_messenger.cpp' |
4593 | --- src/server/frontend/socket_messenger.cpp 2014-06-12 15:35:08 +0000 |
4594 | +++ src/server/frontend/socket_messenger.cpp 2014-07-11 20:27:44 +0000 |
4595 | @@ -83,7 +83,7 @@ |
4596 | send_fds_locked(lg, fds); |
4597 | } |
4598 | |
4599 | -void mfd::SocketMessenger::send_fds_locked(std::unique_lock<std::mutex> const&, std::vector<int32_t> const& fds) |
4600 | +void mfd::SocketMessenger::send_fds_locked(std::unique_lock<std::mutex> const&, std::vector<mir::Fd> const& fds) |
4601 | { |
4602 | if (fds.size() > 0) |
4603 | { |
4604 | @@ -119,7 +119,7 @@ |
4605 | |
4606 | int* const data = reinterpret_cast<int*>(CMSG_DATA(message)); |
4607 | int i = 0; |
4608 | - for (auto fd : fds) |
4609 | + for (auto& fd : fds) |
4610 | data[i++] = fd; |
4611 | |
4612 | auto const sent = sendmsg(socket->native_handle(), &header, 0); |
4613 | |
4614 | === modified file 'src/server/frontend/socket_messenger.h' |
4615 | --- src/server/frontend/socket_messenger.h 2014-06-03 11:04:15 +0000 |
4616 | +++ src/server/frontend/socket_messenger.h 2014-07-11 20:27:44 +0000 |
4617 | @@ -51,7 +51,7 @@ |
4618 | std::mutex message_lock; |
4619 | SessionCredentials session_creds{0, 0, 0}; |
4620 | |
4621 | - void send_fds_locked(std::unique_lock<std::mutex> const& lock, std::vector<int32_t> const& fds); |
4622 | + void send_fds_locked(std::unique_lock<std::mutex> const& lock, std::vector<Fd> const& fds); |
4623 | }; |
4624 | } |
4625 | } |
4626 | |
4627 | === modified file 'src/server/graphics/CMakeLists.txt' |
4628 | --- src/server/graphics/CMakeLists.txt 2014-06-03 11:04:15 +0000 |
4629 | +++ src/server/graphics/CMakeLists.txt 2014-07-11 20:27:44 +0000 |
4630 | @@ -8,7 +8,6 @@ |
4631 | gl_extensions_base.cpp |
4632 | program_factory.cpp |
4633 | surfaceless_egl_context.cpp |
4634 | - builtin_cursor_images.cpp |
4635 | ) |
4636 | |
4637 | add_subdirectory(nested/) |
4638 | |
4639 | === modified file 'src/server/graphics/default_configuration.cpp' |
4640 | --- src/server/graphics/default_configuration.cpp 2014-06-24 21:44:55 +0000 |
4641 | +++ src/server/graphics/default_configuration.cpp 2014-07-11 20:27:44 +0000 |
4642 | @@ -39,8 +39,6 @@ |
4643 | |
4644 | #include <boost/throw_exception.hpp> |
4645 | |
4646 | -#include "builtin_cursor_images.h" |
4647 | - |
4648 | #include <map> |
4649 | |
4650 | namespace mg = mir::graphics; |
4651 | @@ -70,22 +68,31 @@ |
4652 | return graphics_platform( |
4653 | [this]()->std::shared_ptr<mg::Platform> |
4654 | { |
4655 | - auto graphics_lib = mir::load_library(the_options()->get<std::string>(options::platform_graphics_lib)); |
4656 | - |
4657 | if (!the_options()->is_set(options::host_socket_opt)) |
4658 | { |
4659 | // fallback to standalone if host socket is unset |
4660 | + auto graphics_lib = mir::load_library(the_options()->get<std::string>(options::platform_graphics_lib)); |
4661 | auto create_platform = graphics_lib->load_function<mg::CreatePlatform>("create_platform"); |
4662 | return create_platform(the_options(), the_emergency_cleanup(), the_display_report()); |
4663 | } |
4664 | |
4665 | - auto create_native_platform = graphics_lib->load_function<mg::CreateNativePlatform>("create_native_platform"); |
4666 | - |
4667 | return std::make_shared<mir::graphics::nested::NestedPlatform>( |
4668 | the_host_connection(), |
4669 | the_input_dispatcher(), |
4670 | the_display_report(), |
4671 | - create_native_platform(the_display_report())); |
4672 | + the_graphics_native_platform()); |
4673 | + }); |
4674 | +} |
4675 | + |
4676 | +std::shared_ptr<mg::NativePlatform> mir::DefaultServerConfiguration::the_graphics_native_platform() |
4677 | +{ |
4678 | + return graphics_native_platform( |
4679 | + [this]() |
4680 | + { |
4681 | + auto graphics_lib = mir::load_library(the_options()->get<std::string>(options::platform_graphics_lib)); |
4682 | + auto create_native_platform = graphics_lib->load_function<mg::CreateNativePlatform>("create_native_platform"); |
4683 | + |
4684 | + return create_native_platform(the_display_report()); |
4685 | }); |
4686 | } |
4687 | |
4688 | @@ -145,28 +152,6 @@ |
4689 | }); |
4690 | } |
4691 | |
4692 | -std::shared_ptr<mg::CursorImage> |
4693 | -mir::DefaultServerConfiguration::the_default_cursor_image() |
4694 | -{ |
4695 | - static geometry::Size const default_cursor_size = {geometry::Width{64}, |
4696 | - geometry::Height{64}}; |
4697 | - return default_cursor_image( |
4698 | - [this]() |
4699 | - { |
4700 | - return the_cursor_images()->image(mir_default_cursor_name, default_cursor_size); |
4701 | - }); |
4702 | -} |
4703 | - |
4704 | -std::shared_ptr<mg::CursorImages> |
4705 | -mir::DefaultServerConfiguration::the_cursor_images() |
4706 | -{ |
4707 | - return cursor_images( |
4708 | - [this]() |
4709 | - { |
4710 | - return std::make_shared<mg::BuiltinCursorImages>(); |
4711 | - }); |
4712 | -} |
4713 | - |
4714 | auto mir::DefaultServerConfiguration::the_host_connection() |
4715 | -> std::shared_ptr<graphics::nested::HostConnection> |
4716 | { |
4717 | |
4718 | === modified file 'src/server/graphics/nested/nested_display.cpp' |
4719 | --- src/server/graphics/nested/nested_display.cpp 2014-06-02 17:07:02 +0000 |
4720 | +++ src/server/graphics/nested/nested_display.cpp 2014-07-11 20:27:44 +0000 |
4721 | @@ -215,10 +215,6 @@ |
4722 | }); |
4723 | }); |
4724 | |
4725 | - if (result.empty()) |
4726 | - BOOST_THROW_EXCEPTION(std::runtime_error("Nested Mir needs at least one output for display")); |
4727 | - |
4728 | - |
4729 | { |
4730 | std::unique_lock<std::mutex> lock(outputs_mutex); |
4731 | outputs.swap(result); |
4732 | |
4733 | === modified file 'src/server/input/CMakeLists.txt' |
4734 | --- src/server/input/CMakeLists.txt 2014-06-24 15:28:09 +0000 |
4735 | +++ src/server/input/CMakeLists.txt 2014-07-11 20:27:44 +0000 |
4736 | @@ -1,5 +1,7 @@ |
4737 | include_directories(${MIR_3RD_PARTY_INCLUDE_DIRECTORIES}) |
4738 | include_directories(${MIR_ANDROID_INCLUDE_DIRECTORIES}) |
4739 | +include_directories(${MIR_XCURSOR_INCLUDE_DIRECTORIES}) |
4740 | + |
4741 | set( |
4742 | INPUT_SOURCES |
4743 | |
4744 | @@ -8,11 +10,12 @@ |
4745 | null_input_channel_factory.cpp |
4746 | null_input_configuration.cpp |
4747 | null_input_dispatcher.cpp |
4748 | - nested_input_configuration.cpp |
4749 | display_input_region.cpp |
4750 | vt_filter.cpp |
4751 | cursor_controller.cpp |
4752 | default_configuration.cpp |
4753 | + xcursor_loader.cpp |
4754 | + builtin_cursor_images.cpp |
4755 | ) |
4756 | |
4757 | add_subdirectory(android) |
4758 | @@ -23,3 +26,7 @@ |
4759 | ${INPUT_SOURCES} |
4760 | ) |
4761 | uses_android_input(mirinput) |
4762 | +target_link_libraries( |
4763 | + mirinput |
4764 | + xcursorloader |
4765 | +) |
4766 | |
4767 | === renamed file 'src/server/graphics/black_arrow.c' => 'src/server/input/black_arrow.c' |
4768 | === renamed file 'src/server/graphics/black_arrow.xcf' => 'src/server/input/black_arrow.xcf' |
4769 | === renamed file 'src/server/graphics/builtin_cursor_images.cpp' => 'src/server/input/builtin_cursor_images.cpp' |
4770 | --- src/server/graphics/builtin_cursor_images.cpp 2014-04-23 23:07:05 +0000 |
4771 | +++ src/server/input/builtin_cursor_images.cpp 2014-07-11 20:27:44 +0000 |
4772 | @@ -21,6 +21,7 @@ |
4773 | |
4774 | #include "mir/graphics/cursor_image.h" |
4775 | |
4776 | +namespace mi = mir::input; |
4777 | namespace mg = mir::graphics; |
4778 | namespace geom = mir::geometry; |
4779 | |
4780 | @@ -36,15 +37,19 @@ |
4781 | { |
4782 | return { black_arrow.width, black_arrow.height }; |
4783 | } |
4784 | + geom::Displacement hotspot() const |
4785 | + { |
4786 | + return {0, 0}; |
4787 | + } |
4788 | }; |
4789 | } |
4790 | |
4791 | -mg::BuiltinCursorImages::BuiltinCursorImages() |
4792 | +mi::BuiltinCursorImages::BuiltinCursorImages() |
4793 | : builtin_image(std::make_shared<BlackArrowCursorImage>()) |
4794 | { |
4795 | } |
4796 | |
4797 | -std::shared_ptr<mg::CursorImage> mg::BuiltinCursorImages::image(std::string const& /* cursor_name */, |
4798 | +std::shared_ptr<mg::CursorImage> mi::BuiltinCursorImages::image(std::string const& /* cursor_name */, |
4799 | geom::Size const& /* size */) |
4800 | { |
4801 | // Builtin repository only has one cursor at a single size. |
4802 | |
4803 | === renamed file 'src/server/graphics/builtin_cursor_images.h' => 'src/server/input/builtin_cursor_images.h' |
4804 | --- src/server/graphics/builtin_cursor_images.h 2014-04-23 23:07:05 +0000 |
4805 | +++ src/server/input/builtin_cursor_images.h 2014-07-11 20:27:44 +0000 |
4806 | @@ -17,24 +17,22 @@ |
4807 | */ |
4808 | |
4809 | |
4810 | -#ifndef MIR_GRAPHICS_BUILTIN_CURSOR_LOADER_H_ |
4811 | -#define MIR_GRAPHICS_BUILTIN_CURSOR_LOADER_H_ |
4812 | +#ifndef MIR_INPUT_BUILTIN_CURSOR_IMAGES_H_ |
4813 | +#define MIR_INPUT_BUILTIN_CURSOR_IMAGES_H_ |
4814 | |
4815 | -#include "mir/graphics/cursor_images.h" |
4816 | +#include "mir/input/cursor_images.h" |
4817 | |
4818 | namespace mir |
4819 | { |
4820 | -namespace graphics |
4821 | +namespace input |
4822 | { |
4823 | -class CursorImage; |
4824 | - |
4825 | class BuiltinCursorImages : public CursorImages |
4826 | { |
4827 | public: |
4828 | BuiltinCursorImages(); |
4829 | virtual ~BuiltinCursorImages() = default; |
4830 | |
4831 | - std::shared_ptr<CursorImage> image(std::string const& cursor_name, |
4832 | + std::shared_ptr<graphics::CursorImage> image(std::string const& cursor_name, |
4833 | geometry::Size const& size); |
4834 | |
4835 | protected: |
4836 | @@ -42,10 +40,10 @@ |
4837 | BuiltinCursorImages& operator=(BuiltinCursorImages const&) = delete; |
4838 | |
4839 | private: |
4840 | - std::shared_ptr<CursorImage> const builtin_image; |
4841 | + std::shared_ptr<graphics::CursorImage> const builtin_image; |
4842 | }; |
4843 | } |
4844 | } |
4845 | |
4846 | |
4847 | -#endif /* MIR_GRAPHICS_BUILTIN_CURSOR_LOADER_H_ */ |
4848 | +#endif /* MIR_INPUT_BUILTIN_CURSOR_IMAGES_H_ */ |
4849 | |
4850 | === modified file 'src/server/input/default_configuration.cpp' |
4851 | --- src/server/input/default_configuration.cpp 2014-06-26 16:10:36 +0000 |
4852 | +++ src/server/input/default_configuration.cpp 2014-07-11 20:27:44 +0000 |
4853 | @@ -28,11 +28,12 @@ |
4854 | #include "android/input_channel_factory.h" |
4855 | #include "display_input_region.h" |
4856 | #include "event_filter_chain.h" |
4857 | -#include "nested_input_configuration.h" |
4858 | #include "null_input_configuration.h" |
4859 | #include "cursor_controller.h" |
4860 | #include "null_input_dispatcher.h" |
4861 | #include "null_input_targeter.h" |
4862 | +#include "xcursor_loader.h" |
4863 | +#include "builtin_cursor_images.h" |
4864 | #include "null_input_send_observer.h" |
4865 | #include "null_input_channel_factory.h" |
4866 | |
4867 | @@ -50,6 +51,7 @@ |
4868 | namespace mia = mi::android; |
4869 | namespace mr = mir::report; |
4870 | namespace ms = mir::scene; |
4871 | +namespace mg = mir::graphics; |
4872 | namespace msh = mir::shell; |
4873 | |
4874 | std::shared_ptr<mi::InputRegion> mir::DefaultServerConfiguration::the_input_region() |
4875 | @@ -79,11 +81,11 @@ |
4876 | [this]() -> std::shared_ptr<mi::InputConfiguration> |
4877 | { |
4878 | auto const options = the_options(); |
4879 | - if (!options->get<bool>(options::enable_input_opt)) |
4880 | - { |
4881 | - return std::make_shared<mi::NullInputConfiguration>(); |
4882 | - } |
4883 | - else if (!options->is_set(options::host_socket_opt)) |
4884 | + bool input_reading_required = |
4885 | + options->get<bool>(options::enable_input_opt) && |
4886 | + !options->is_set(options::host_socket_opt); |
4887 | + |
4888 | + if (input_reading_required) |
4889 | { |
4890 | // fallback to standalone if host socket is unset |
4891 | return std::make_shared<mia::DefaultInputConfiguration>( |
4892 | @@ -95,7 +97,7 @@ |
4893 | } |
4894 | else |
4895 | { |
4896 | - return std::make_shared<mi::NestedInputConfiguration>(); |
4897 | + return std::make_shared<mi::NullInputConfiguration>(); |
4898 | } |
4899 | }); |
4900 | } |
4901 | @@ -235,3 +237,37 @@ |
4902 | }); |
4903 | |
4904 | } |
4905 | + |
4906 | +std::shared_ptr<mg::CursorImage> |
4907 | +mir::DefaultServerConfiguration::the_default_cursor_image() |
4908 | +{ |
4909 | + return default_cursor_image( |
4910 | + [this]() |
4911 | + { |
4912 | + return the_cursor_images()->image(mir_default_cursor_name, mi::default_cursor_size); |
4913 | + }); |
4914 | +} |
4915 | + |
4916 | +namespace |
4917 | +{ |
4918 | +bool has_default_cursor(mi::CursorImages& images) |
4919 | +{ |
4920 | + if (images.image(mir_default_cursor_name, mi::default_cursor_size)) |
4921 | + return true; |
4922 | + return false; |
4923 | +} |
4924 | +} |
4925 | + |
4926 | +std::shared_ptr<mi::CursorImages> |
4927 | +mir::DefaultServerConfiguration::the_cursor_images() |
4928 | +{ |
4929 | + return cursor_images( |
4930 | + [this]() -> std::shared_ptr<mi::CursorImages> |
4931 | + { |
4932 | + auto xcursor_loader = std::make_shared<mi::XCursorLoader>(); |
4933 | + if (has_default_cursor(*xcursor_loader)) |
4934 | + return xcursor_loader; |
4935 | + else |
4936 | + return std::make_shared<mi::BuiltinCursorImages>(); |
4937 | + }); |
4938 | +} |
4939 | |
4940 | === removed file 'src/server/input/nested_input_configuration.cpp' |
4941 | --- src/server/input/nested_input_configuration.cpp 2014-06-24 15:28:09 +0000 |
4942 | +++ src/server/input/nested_input_configuration.cpp 1970-01-01 00:00:00 +0000 |
4943 | @@ -1,37 +0,0 @@ |
4944 | -/* |
4945 | - * Copyright © 2013-2014 Canonical Ltd. |
4946 | - * |
4947 | - * This program is free software: you can redistribute it and/or modify it |
4948 | - * under the terms of the GNU General Public License version 3, |
4949 | - * as published by the Free Software Foundation. |
4950 | - * |
4951 | - * This program is distributed in the hope that it will be useful, |
4952 | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
4953 | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
4954 | - * GNU General Public License for more details. |
4955 | - * |
4956 | - * You should have received a copy of the GNU General Public License |
4957 | - * along with this program. If not, see <http://www.gnu.org/licenses/>. |
4958 | - * |
4959 | - * Authored by: Alan Griffiths <alan@octopull.co.uk> |
4960 | - * Andreas Pokorny <andreas.pokorny@canonical.com> |
4961 | - */ |
4962 | - |
4963 | -#include "nested_input_configuration.h" |
4964 | -#include "null_input_manager.h" |
4965 | - |
4966 | -#include "android/input_channel_factory.h" |
4967 | - |
4968 | -#include <memory> |
4969 | - |
4970 | -namespace mi = mir::input; |
4971 | -namespace mia = mir::input::android; |
4972 | - |
4973 | -std::shared_ptr<mi::InputManager> mi::NestedInputConfiguration::the_input_manager() |
4974 | -{ |
4975 | - return input_manager( |
4976 | - [this]() |
4977 | - { |
4978 | - return std::make_shared<NullInputManager>(); |
4979 | - }); |
4980 | -} |
4981 | |
4982 | === removed file 'src/server/input/nested_input_configuration.h' |
4983 | --- src/server/input/nested_input_configuration.h 2014-06-24 15:28:09 +0000 |
4984 | +++ src/server/input/nested_input_configuration.h 1970-01-01 00:00:00 +0000 |
4985 | @@ -1,43 +0,0 @@ |
4986 | -/* |
4987 | - * Copyright © 2013 Canonical Ltd. |
4988 | - * |
4989 | - * This program is free software: you can redistribute it and/or modify it |
4990 | - * under the terms of the GNU General Public License version 3, |
4991 | - * as published by the Free Software Foundation. |
4992 | - * |
4993 | - * This program is distributed in the hope that it will be useful, |
4994 | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
4995 | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
4996 | - * GNU General Public License for more details. |
4997 | - * |
4998 | - * You should have received a copy of the GNU General Public License |
4999 | - * along with this program. If not, see <http://www.gnu.org/licenses/>. |
5000 | - * |
The diff has been truncated for viewing.