Merge lp:~compiz-team/compiz/compiz.fix_1119608 into lp:compiz/0.9.9
- compiz.fix_1119608
- Merge into 0.9.9
Status: | Merged |
---|---|
Approved by: | Brandon Schaefer |
Approved revision: | 3628 |
Merged at revision: | 3618 |
Proposed branch: | lp:~compiz-team/compiz/compiz.fix_1119608 |
Merge into: | lp:compiz/0.9.9 |
Diff against target: |
2244 lines (+1519/-197) 23 files modified
gtk/window-decorator/cairo.c (+3/-12) gtk/window-decorator/decorator.c (+12/-13) gtk/window-decorator/events.c (+0/-11) gtk/window-decorator/gdk.c (+25/-1) gtk/window-decorator/gtk-window-decorator.c (+3/-5) gtk/window-decorator/gtk-window-decorator.h (+6/-2) gtk/window-decorator/metacity.c (+0/-15) gtk/window-decorator/switcher.c (+7/-1) gtk/window-decorator/wnck.c (+0/-16) include/decoration.h (+6/-1) libdecoration/decoration.c (+9/-7) plugins/decor/src/decor.cpp (+79/-18) plugins/decor/src/decor.h (+13/-3) plugins/decor/src/pixmap-requests/include/pixmap-requests.h (+127/-35) plugins/decor/src/pixmap-requests/src/pixmap-requests.cpp (+106/-3) plugins/decor/src/pixmap-requests/tests/CMakeLists.txt (+10/-1) plugins/decor/src/pixmap-requests/tests/compiz_decor_pixmap_requests_mock.cpp (+113/-0) plugins/decor/src/pixmap-requests/tests/compiz_decor_pixmap_requests_mock.h (+179/-0) plugins/decor/src/pixmap-requests/tests/integration/CMakeLists.txt (+1/-0) plugins/decor/src/pixmap-requests/tests/integration/xorg-gtest/CMakeLists.txt (+41/-0) plugins/decor/src/pixmap-requests/tests/integration/xorg-gtest/compiz_test_decor_pixmap_protocol_integration.cpp (+483/-0) plugins/decor/src/pixmap-requests/tests/test-decor-pixmap-requests.cpp (+295/-52) tests/system/xorg-gtest/tests/CMakeLists.txt (+1/-1) |
To merge this branch: | bzr merge lp:~compiz-team/compiz/compiz.fix_1119608 |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Brandon Schaefer (community) | Approve | ||
PS Jenkins bot (community) | continuous-integration | Approve | |
Review via email: mp+149458@code.launchpad.net |
This proposal supersedes a proposal from 2013-02-19.
Commit message
Redesign the optional pixmap deletion protocol to make the consumer responsible for deleting the pixmaps.
The previous optional protocol had the consumer send a message back to the producer when a pixmap was ready to be deleted, and then the producer would take it from its pool of pixmaps marked for deletion and delete it there. That protocol did not really work out in practise though, because of a race condition where the consumer would never become aware of a new pixmap (because the new pixmap value was read synchronously instead of delivered asynchronously) and then that pixmap would just sit there in the consumer's memory and never be deleted. The new optional protocol makes the consumer responsible for freeing the pixmap once the producer has marked it ready for deletion. That way the consumer can keep on using the pixmap until it needs to delete it. This is important on drivers that use loose binding, because the texture contents are undefined as soon as the pixmap is freed on the server side.
In order to represent that, there were a few new objects added. The first is a "communicator" object which handles all of the requests that come from the decorator through ClientMessage events and dispatch to the right place. The next are the individual message handlers, which determine whether or not the pixmap can be deleted immediately or if it should go into the pixmap release pool. The final is the release pool, which stores in-use pixmaps in a list which can then be marked for deletion when the texture they are bound to goes away.
Unit and Integration tests were added to demonstrate the code and protocol behaviour.
(LP: #1119608)
Description of the change
Redesign the optional pixmap deletion protocol to make the consumer responsible for deleting the pixmaps.
The previous optional protocol had the consumer send a message back to the producer when a pixmap was ready to be deleted, and then the producer would take it from its pool of pixmaps marked for deletion and delete it there. That protocol did not really work out in practise though, because of a race condition where the consumer would never become aware of a new pixmap (because the new pixmap value was read synchronously instead of delivered asynchronously) and then that pixmap would just sit there in the consumer's memory and never be deleted. The new optional protocol makes the consumer responsible for freeing the pixmap once the producer has marked it ready for deletion. That way the consumer can keep on using the pixmap until it needs to delete it. This is important on drivers that use loose binding, because the texture contents are undefined as soon as the pixmap is freed on the server side.
In order to represent that, there were a few new objects added. The first is a "communicator" object which handles all of the requests that come from the decorator through ClientMessage events and dispatch to the right place. The next are the individual message handlers, which determine whether or not the pixmap can be deleted immediately or if it should go into the pixmap release pool. The final is the release pool, which stores in-use pixmaps in a list which can then be marked for deletion when the texture they are bound to goes away.
Unit and Integration tests were added to demonstrate the code and protocol behaviour.
(LP: #1119608)
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal | # |
Martin Mrazik (mrazik) wrote : Posted in a previous version of this proposal | # |
Sorry. I had to abort the build due to some jenkins issues we are experiencing. Will re-trigger it later.
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal | # |
PASSED: Continuous integration, rev:3624
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal | # |
FAILED: Continuous integration, rev:3624
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal | # |
FAILED: Continuous integration, rev:3625
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
Brandon Schaefer (brandontschaefer) wrote : Posted in a previous version of this proposal | # |
Overall looks good, a few things:
Some warning when compiling:
http://
CI had some test seg fault (which I don't get here), so possibly taking a look into that.
Just some minor things here:
78 - default_
79 + default_
Just looks like a small indentation error.
119 + if (w == 0 || h == 0)
120 + abort ();
I've seen w or h on windows get to -1 before, should we possibly change it to w <= 0 || h <= 0?
446 + foreach (const Decoration::Ptr &d, mList)
Though I do love this macro, I would love a range for loop but compiz doesn't use c++0x :(. (just a comment)
622 +#include <boost/
I don't see you inherit from this noncopyable class, do we need this header?
695 + int destroyUnusedPixmap (Pixmap pixmap) { return decor_post_
696 + 0,
697 + pixmap); }
Just needs little bit of lining up of the params :).
Sam Spilsbury (smspillaz) wrote : Posted in a previous version of this proposal | # |
> Overall looks good, a few things:
>
Thanks for the quick feedback.
> Some warning when compiling:
> http://
Fixed.
>
> CI had some test seg fault (which I don't get here), so possibly taking a look
> into that.
I think that should be fixed now. I wasn't running the tests through the wrapper.
>
> Just some minor things here:
>
> 78 - default_
> (default_
> frame->
> 79 + default_
> (default_
> frame->
>
> Just looks like a small indentation error.
Fixed.
>
>
> 119 + if (w == 0 || h == 0)
> 120 + abort ();
>
> I've seen w or h on windows get to -1 before, should we possibly change it to
> w <= 0 || h <= 0?
Fixed.
>
> 446 + foreach (const Decoration::Ptr &d, mList)
>
> Though I do love this macro, I would love a range for loop but compiz doesn't
> use c++0x :(. (just a comment)
Likewise, but we should do them all in one go. Its just BOOST_FOREACH.
>
> 622 +#include <boost/
>
> I don't see you inherit from this noncopyable class, do we need this header?
Nice catch, forgot to do it.
>
> 695 + int destroyUnusedPixmap (Pixmap pixmap) { return
> decor_post_
> 696 + 0,
> 697 + pixmap); }
>
> Just needs little bit of lining up of the params :).
The class was unused anyways so I got rid of it.
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal | # |
FAILED: Continuous integration, rev:3627
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:3627
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
- 3628. By Sam Spilsbury
-
Add xorg-gtest env
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:3628
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Brandon Schaefer (brandontschaefer) wrote : Posted in a previous version of this proposal | # |
Everything looks good to me, im approving this but waiting for CI to give the green light for a merge.
Brandon Schaefer (brandontschaefer) wrote : | # |
opps wrong MP, looks like CI did its job :)
Preview Diff
1 | === modified file 'gtk/window-decorator/cairo.c' |
2 | --- gtk/window-decorator/cairo.c 2012-09-18 11:32:20 +0000 |
3 | +++ gtk/window-decorator/cairo.c 2013-02-20 07:34:20 +0000 |
4 | @@ -317,19 +317,10 @@ |
5 | color.g = style->bg[GTK_STATE_NORMAL].green / 65535.0; |
6 | color.b = style->bg[GTK_STATE_NORMAL].blue / 65535.0; |
7 | |
8 | - if (d->frame_window) |
9 | - { |
10 | - GdkColormap *cmap; |
11 | - |
12 | - cmap = get_colormap_for_drawable (GDK_DRAWABLE (d->pixmap)); |
13 | - gdk_drawable_set_colormap (GDK_DRAWABLE (d->pixmap), cmap); |
14 | - gdk_drawable_set_colormap (GDK_DRAWABLE (d->buffer_pixmap), cmap); |
15 | - drawable = GDK_DRAWABLE (d->buffer_pixmap); |
16 | - } |
17 | - else if (d->buffer_pixmap) |
18 | - drawable = GDK_DRAWABLE (d->buffer_pixmap); |
19 | + if (d->buffer_pixmap) |
20 | + drawable = d->buffer_pixmap; |
21 | else |
22 | - drawable = GDK_DRAWABLE (d->pixmap); |
23 | + drawable = d->pixmap; |
24 | |
25 | cr = gdk_cairo_create (GDK_DRAWABLE (drawable)); |
26 | if (!cr) |
27 | |
28 | === modified file 'gtk/window-decorator/decorator.c' |
29 | --- gtk/window-decorator/decorator.c 2012-11-20 08:11:44 +0000 |
30 | +++ gtk/window-decorator/decorator.c 2013-02-20 07:34:20 +0000 |
31 | @@ -649,9 +649,9 @@ |
32 | /* Get the correct depth for the frame window in reparenting mode, otherwise |
33 | * enforce 32 */ |
34 | if (d->frame_window) |
35 | - pixmap = create_pixmap (d->width, d->height, d->frame->style_window_rgb); |
36 | + pixmap = create_native_pixmap_and_wrap (d->width, d->height, d->frame->style_window_rgb); |
37 | else |
38 | - pixmap = create_pixmap (d->width, d->height, d->frame->style_window_rgba); |
39 | + pixmap = create_native_pixmap_and_wrap (d->width, d->height, d->frame->style_window_rgba); |
40 | |
41 | gdk_flush (); |
42 | |
43 | @@ -686,16 +686,12 @@ |
44 | |
45 | /* Destroy the old pixmaps and pictures */ |
46 | if (d->pixmap) |
47 | - { |
48 | - gpointer key = GINT_TO_POINTER (GDK_PIXMAP_XID (d->pixmap)); |
49 | - |
50 | - if (d->old_pixmaps == NULL) |
51 | - d->old_pixmaps = g_hash_table_new_full (NULL, NULL, NULL, |
52 | - g_object_unref); |
53 | - |
54 | - g_hash_table_insert (destroyed_pixmaps_table, key, d); |
55 | - g_hash_table_insert (d->old_pixmaps, key, d->pixmap); |
56 | - } |
57 | + g_object_unref (d->pixmap); |
58 | + |
59 | + if (d->x11Pixmap) |
60 | + decor_post_delete_pixmap (xdisplay, |
61 | + wnck_window_get_xid (d->win), |
62 | + d->x11Pixmap); |
63 | |
64 | if (d->buffer_pixmap) |
65 | g_object_unref (G_OBJECT (d->buffer_pixmap)); |
66 | @@ -708,6 +704,7 @@ |
67 | |
68 | /* Assign new pixmaps and pictures */ |
69 | d->pixmap = pixmap; |
70 | + d->x11Pixmap = GDK_PIXMAP_XID (d->pixmap); |
71 | d->buffer_pixmap = buffer_pixmap; |
72 | d->cr = gdk_cairo_create (pixmap); |
73 | |
74 | @@ -1435,7 +1432,9 @@ |
75 | extents.top += frame->titlebar_height; |
76 | |
77 | default_frames[i].d->draw = theme_draw_window_decoration; |
78 | - default_frames[i].d->pixmap = create_pixmap (default_frames[i].d->width, default_frames[i].d->height, frame->style_window_rgba); |
79 | + default_frames[i].d->pixmap = create_native_pixmap_and_wrap (default_frames[i].d->width, |
80 | + default_frames[i].d->height, |
81 | + frame->style_window_rgba); |
82 | |
83 | unsigned int j, k; |
84 | |
85 | |
86 | === modified file 'gtk/window-decorator/events.c' |
87 | --- gtk/window-decorator/events.c 2012-10-06 16:11:05 +0000 |
88 | +++ gtk/window-decorator/events.c 2013-02-20 07:34:20 +0000 |
89 | @@ -1093,17 +1093,6 @@ |
90 | if (win) |
91 | update_window_decoration_size (win); |
92 | } |
93 | - else if (xevent->xclient.message_type == decor_delete_pixmap_atom) |
94 | - { |
95 | - gconstpointer key = GINT_TO_POINTER (xevent->xclient.data.l[0]); |
96 | - decor_t *d = g_hash_table_lookup (destroyed_pixmaps_table, key); |
97 | - |
98 | - if (d != NULL) |
99 | - { |
100 | - g_hash_table_remove (d->old_pixmaps, key); |
101 | - g_hash_table_remove (destroyed_pixmaps_table, key); |
102 | - } |
103 | - } |
104 | default: |
105 | break; |
106 | } |
107 | |
108 | === modified file 'gtk/window-decorator/gdk.c' |
109 | --- gtk/window-decorator/gdk.c 2012-05-27 04:32:55 +0000 |
110 | +++ gtk/window-decorator/gdk.c 2013-02-20 07:34:20 +0000 |
111 | @@ -92,6 +92,26 @@ |
112 | } |
113 | |
114 | GdkPixmap * |
115 | +create_native_pixmap_and_wrap (int w, |
116 | + int h, |
117 | + GtkWidget *parent_style_window) |
118 | +{ |
119 | + GdkWindow *window; |
120 | + |
121 | + if (w <= 0 || h <= 0) |
122 | + abort (); |
123 | + |
124 | + window = gtk_widget_get_window (parent_style_window); |
125 | + GdkPixmap *pixmap = |
126 | + gdk_pixmap_foreign_new (XCreatePixmap (gdk_x11_display_get_xdisplay (gdk_display_get_default ()), |
127 | + GDK_WINDOW_XID (window), w, h, |
128 | + gdk_drawable_get_depth (window))); |
129 | + GdkColormap *cmap = get_colormap_for_drawable (GDK_DRAWABLE (pixmap)); |
130 | + gdk_drawable_set_colormap (GDK_DRAWABLE (pixmap), cmap); |
131 | + return pixmap; |
132 | +} |
133 | + |
134 | +GdkPixmap * |
135 | create_pixmap (int w, |
136 | int h, |
137 | GtkWidget *parent_style_window) |
138 | @@ -102,5 +122,9 @@ |
139 | abort (); |
140 | |
141 | window = gtk_widget_get_window (parent_style_window); |
142 | - return gdk_pixmap_new (GDK_DRAWABLE (window), w, h, -1 /* CopyFromParent */); |
143 | + GdkPixmap *pixmap = gdk_pixmap_new (GDK_DRAWABLE (window), w, h, -1 /* CopyFromParent */); |
144 | + |
145 | + GdkColormap *cmap = get_colormap_for_drawable (GDK_DRAWABLE (pixmap)); |
146 | + gdk_drawable_set_colormap (GDK_DRAWABLE (pixmap), cmap); |
147 | + return pixmap; |
148 | } |
149 | |
150 | === modified file 'gtk/window-decorator/gtk-window-decorator.c' |
151 | --- gtk/window-decorator/gtk-window-decorator.c 2012-10-06 16:11:05 +0000 |
152 | +++ gtk/window-decorator/gtk-window-decorator.c 2013-02-20 07:34:20 +0000 |
153 | @@ -136,7 +136,6 @@ |
154 | GtkWidget *switcher_label; |
155 | |
156 | GHashTable *frame_table; |
157 | -GHashTable *destroyed_pixmaps_table; |
158 | GtkWidget *action_menu = NULL; |
159 | gboolean action_menu_mapped = FALSE; |
160 | decor_color_t _title_color[2]; |
161 | @@ -267,9 +266,9 @@ |
162 | net_wm_state_atom = XInternAtom (xdisplay,"_NET_WM_STATE", 0); |
163 | net_wm_state_modal_atom = XInternAtom (xdisplay, "_NET_WM_STATE_MODAL", 0); |
164 | |
165 | - decor_request_atom = XInternAtom (xdisplay, "_COMPIZ_DECOR_REQUEST", 0); |
166 | - decor_pending_atom = XInternAtom (xdisplay, "_COMPIZ_DECOR_PENDING", 0); |
167 | - decor_delete_pixmap_atom = XInternAtom (xdisplay, "_COMPIZ_DECOR_DELETE_PIXMAP", 0); |
168 | + decor_request_atom = XInternAtom (xdisplay, DECOR_REQUEST_PIXMAP_ATOM_NAME, 0); |
169 | + decor_pending_atom = XInternAtom (xdisplay, DECOR_PIXMAP_PENDING_ATOM_NAME, 0); |
170 | + decor_delete_pixmap_atom = XInternAtom (xdisplay, DECOR_DELETE_PIXMAP_ATOM_NAME, 0); |
171 | |
172 | status = decor_acquire_dm_session (xdisplay, |
173 | gdk_screen_get_number (gdkscreen), |
174 | @@ -343,7 +342,6 @@ |
175 | xformat_rgb = XRenderFindStandardFormat (xdisplay, PictStandardRGB24); |
176 | |
177 | frame_table = g_hash_table_new (NULL, NULL); |
178 | - destroyed_pixmaps_table = g_hash_table_new (NULL, NULL); |
179 | |
180 | if (!create_tooltip_window ()) |
181 | { |
182 | |
183 | === modified file 'gtk/window-decorator/gtk-window-decorator.h' |
184 | --- gtk/window-decorator/gtk-window-decorator.h 2012-10-06 16:11:05 +0000 |
185 | +++ gtk/window-decorator/gtk-window-decorator.h 2013-02-20 07:34:20 +0000 |
186 | @@ -392,13 +392,13 @@ |
187 | event_window button_windows[BUTTON_NUM]; |
188 | Box *last_pos_entered; |
189 | guint button_states[BUTTON_NUM]; |
190 | + Pixmap x11Pixmap; |
191 | GdkPixmap *pixmap; |
192 | GdkPixmap *buffer_pixmap; |
193 | GdkWindow *frame_window; |
194 | GtkWidget *decor_window; |
195 | GtkWidget *decor_event_box; |
196 | GtkWidget *decor_image; |
197 | - GHashTable *old_pixmaps; |
198 | cairo_t *cr; |
199 | decor_layout_t border_layout; |
200 | decor_context_t *context; |
201 | @@ -470,7 +470,6 @@ |
202 | |
203 | /* list of all decorations */ |
204 | extern GHashTable *frame_table; |
205 | -extern GHashTable *destroyed_pixmaps_table; |
206 | |
207 | /* action menu */ |
208 | extern GtkWidget *action_menu; |
209 | @@ -801,6 +800,11 @@ |
210 | GtkWidget *parent_style_window); |
211 | |
212 | GdkPixmap * |
213 | +create_native_pixmap_and_wrap (int w, |
214 | + int h, |
215 | + GtkWidget *parent_style_window); |
216 | + |
217 | +GdkPixmap * |
218 | pixmap_new_from_pixbuf (GdkPixbuf *pixbuf, GtkWidget *parent); |
219 | |
220 | /* metacity.c */ |
221 | |
222 | === modified file 'gtk/window-decorator/metacity.c' |
223 | --- gtk/window-decorator/metacity.c 2012-09-10 12:59:17 +0000 |
224 | +++ gtk/window-decorator/metacity.c 2013-02-20 07:34:20 +0000 |
225 | @@ -616,15 +616,6 @@ |
226 | if (!d->pixmap || !d->picture) |
227 | return; |
228 | |
229 | - if (d->frame_window) |
230 | - { |
231 | - GdkColormap *cmap; |
232 | - |
233 | - cmap = get_colormap_for_drawable (GDK_DRAWABLE (d->pixmap)); |
234 | - gdk_drawable_set_colormap (GDK_DRAWABLE (d->pixmap), cmap); |
235 | - gdk_drawable_set_colormap (GDK_DRAWABLE (d->buffer_pixmap), cmap); |
236 | - } |
237 | - |
238 | if (decoration_alpha == 1.0) |
239 | alpha = 1.0; |
240 | |
241 | @@ -692,13 +683,7 @@ |
242 | XRenderPictFormat *format; |
243 | |
244 | if (d->frame_window) |
245 | - { |
246 | - GdkColormap *cmap; |
247 | - |
248 | - cmap = get_colormap_for_drawable (GDK_DRAWABLE (d->pixmap)); |
249 | pixmap = create_pixmap (rect.width, size, d->frame->style_window_rgb); |
250 | - gdk_drawable_set_colormap (GDK_DRAWABLE (pixmap), cmap); |
251 | - } |
252 | else |
253 | pixmap = create_pixmap (rect.width, size, d->frame->style_window_rgba); |
254 | |
255 | |
256 | === modified file 'gtk/window-decorator/switcher.c' |
257 | --- gtk/window-decorator/switcher.c 2011-10-13 12:07:34 +0000 |
258 | +++ gtk/window-decorator/switcher.c 2013-02-20 07:34:20 +0000 |
259 | @@ -472,7 +472,7 @@ |
260 | switcher_selected_window = selected; |
261 | } |
262 | |
263 | - pixmap = create_pixmap (width, height, d->frame->style_window_rgba); |
264 | + pixmap = create_native_pixmap_and_wrap (width, height, d->frame->style_window_rgba); |
265 | if (!pixmap) |
266 | return FALSE; |
267 | |
268 | @@ -486,6 +486,11 @@ |
269 | if (d->pixmap) |
270 | g_object_unref (G_OBJECT (d->pixmap)); |
271 | |
272 | + if (d->x11Pixmap) |
273 | + decor_post_delete_pixmap (xdisplay, |
274 | + wnck_window_get_xid (d->win), |
275 | + d->x11Pixmap); |
276 | + |
277 | if (d->buffer_pixmap) |
278 | g_object_unref (G_OBJECT (d->buffer_pixmap)); |
279 | |
280 | @@ -496,6 +501,7 @@ |
281 | XRenderFreePicture (xdisplay, d->picture); |
282 | |
283 | d->pixmap = pixmap; |
284 | + d->x11Pixmap = GDK_PIXMAP_XID (d->pixmap); |
285 | d->buffer_pixmap = buffer_pixmap; |
286 | d->cr = gdk_cairo_create (pixmap); |
287 | |
288 | |
289 | === modified file 'gtk/window-decorator/wnck.c' |
290 | --- gtk/window-decorator/wnck.c 2012-11-05 20:50:59 +0000 |
291 | +++ gtk/window-decorator/wnck.c 2013-02-20 07:34:20 +0000 |
292 | @@ -455,22 +455,12 @@ |
293 | d->created = TRUE; |
294 | } |
295 | |
296 | -gboolean |
297 | -clean_destroyed_pixmaps (gpointer key, gpointer value, gpointer d) |
298 | -{ |
299 | - return value == d; |
300 | -} |
301 | - |
302 | void |
303 | remove_frame_window (WnckWindow *win) |
304 | { |
305 | decor_t *d = g_object_get_data (G_OBJECT (win), "decor"); |
306 | Display *xdisplay; |
307 | |
308 | - g_hash_table_foreach_remove (destroyed_pixmaps_table, |
309 | - clean_destroyed_pixmaps, |
310 | - d); |
311 | - |
312 | xdisplay = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()); |
313 | |
314 | if (!d->frame_window) |
315 | @@ -507,12 +497,6 @@ |
316 | d->buffer_pixmap = NULL; |
317 | } |
318 | |
319 | - if (d->old_pixmaps) |
320 | - { |
321 | - g_hash_table_destroy (d->old_pixmaps); |
322 | - d->old_pixmaps = NULL; |
323 | - } |
324 | - |
325 | if (d->cr) |
326 | { |
327 | cairo_destroy (d->cr); |
328 | |
329 | === modified file 'include/decoration.h' |
330 | --- include/decoration.h 2012-09-05 14:25:35 +0000 |
331 | +++ include/decoration.h 2013-02-20 07:34:20 +0000 |
332 | @@ -50,6 +50,10 @@ |
333 | #define DECOR_TYPE_PIXMAP_ATOM_NAME "_COMPIZ_WINDOW_DECOR_TYPE_PIXMAP" |
334 | #define DECOR_TYPE_WINDOW_ATOM_NAME "_COMPIZ_WINDOW_DECOR_TYPE_WINDOW" |
335 | |
336 | +#define DECOR_REQUEST_PIXMAP_ATOM_NAME "_COMPIZ_DECOR_REQUEST" |
337 | +#define DECOR_PIXMAP_PENDING_ATOM_NAME "_COMPIZ_DECOR_PENDING" |
338 | +#define DECOR_DELETE_PIXMAP_ATOM_NAME "_COMPIZ_DECOR_DELETE_PIXMAP" |
339 | + |
340 | #define WINDOW_DECORATION_TYPE_PIXMAP (1 << 0) |
341 | #define WINDOW_DECORATION_TYPE_WINDOW (1 << 1) |
342 | |
343 | @@ -495,12 +499,13 @@ |
344 | int |
345 | decor_post_pending (Display *xdisplay, |
346 | Window client, |
347 | + unsigned int frame_type, |
348 | unsigned int frame_state, |
349 | - unsigned int frame_type, |
350 | unsigned int frame_actions); |
351 | |
352 | int |
353 | decor_post_delete_pixmap (Display *xdisplay, |
354 | + Window window, |
355 | Pixmap pixmap); |
356 | |
357 | int |
358 | |
359 | === modified file 'libdecoration/decoration.c' |
360 | --- libdecoration/decoration.c 2013-01-28 20:52:39 +0000 |
361 | +++ libdecoration/decoration.c 2013-02-20 07:34:20 +0000 |
362 | @@ -2890,13 +2890,13 @@ |
363 | int |
364 | decor_post_pending (Display *xdisplay, |
365 | Window client, |
366 | + unsigned int frame_type, |
367 | unsigned int frame_state, |
368 | - unsigned int frame_type, |
369 | unsigned int frame_actions) |
370 | { |
371 | XEvent event; |
372 | |
373 | - Atom decor_pending = XInternAtom (xdisplay, "_COMPIZ_DECOR_PENDING", FALSE); |
374 | + Atom decor_pending = XInternAtom (xdisplay, DECOR_PIXMAP_PENDING_ATOM_NAME, FALSE); |
375 | |
376 | /* Send a client message indicating that a new |
377 | * decoration can be generated for this window |
378 | @@ -2926,7 +2926,7 @@ |
379 | { |
380 | XEvent event; |
381 | |
382 | - Atom decor_request = XInternAtom (xdisplay, "_COMPIZ_DECOR_REQUEST", FALSE); |
383 | + Atom decor_request = XInternAtom (xdisplay, DECOR_REQUEST_PIXMAP_ATOM_NAME, FALSE); |
384 | |
385 | /* Send a client message indicating that a new |
386 | * decoration can be generated for this window |
387 | @@ -2949,17 +2949,18 @@ |
388 | |
389 | int |
390 | decor_post_delete_pixmap (Display *xdisplay, |
391 | + Window window, |
392 | Pixmap pixmap) |
393 | { |
394 | XEvent event; |
395 | |
396 | - Atom decor_delete_pixmap = XInternAtom (xdisplay, "_COMPIZ_DECOR_DELETE_PIXMAP", FALSE); |
397 | + Atom decor_delete_pixmap = XInternAtom (xdisplay, DECOR_DELETE_PIXMAP_ATOM_NAME, FALSE); |
398 | |
399 | - /* Send a client message indicating that a new |
400 | - * decoration can be generated for this window |
401 | + /* Send a client message indicating that this |
402 | + * pixmap is no longer in use and can be removed |
403 | */ |
404 | event.xclient.type = ClientMessage; |
405 | - event.xclient.window = DefaultRootWindow (xdisplay); |
406 | + event.xclient.window = window; |
407 | event.xclient.message_type = decor_delete_pixmap; |
408 | event.xclient.format = 32; |
409 | event.xclient.data.l[0] = pixmap; |
410 | @@ -2973,6 +2974,7 @@ |
411 | |
412 | return 1; |
413 | } |
414 | + |
415 | int |
416 | decor_acquire_dm_session (Display *xdisplay, |
417 | int screen, |
418 | |
419 | === modified file 'plugins/decor/src/decor.cpp' |
420 | --- plugins/decor/src/decor.cpp 2013-02-19 20:38:17 +0000 |
421 | +++ plugins/decor/src/decor.cpp 2013-02-20 07:34:20 +0000 |
422 | @@ -391,8 +391,7 @@ |
423 | return t; |
424 | } |
425 | |
426 | - X11PixmapDeletor::Ptr dl = boost::make_shared <X11PixmapDeletor> (screen->dpy ()); |
427 | - DecorPixmap::Ptr pm = boost::make_shared <DecorPixmap> (pixmap, dl); |
428 | + DecorPixmap::Ptr pm = boost::make_shared <DecorPixmap> (pixmap, mReleasePool); |
429 | |
430 | DecorTexture *texture = new DecorTexture (boost::shared_static_cast <DecorPixmapInterface> (pm)); |
431 | |
432 | @@ -1285,7 +1284,7 @@ |
433 | DecorationInterface::Ptr |
434 | DecorationList::findMatchingDecoration (unsigned int frameType, |
435 | unsigned int frameState, |
436 | - unsigned int frameActions) |
437 | + unsigned int frameActions) const |
438 | { |
439 | foreach (const Decoration::Ptr &d, mList) |
440 | { |
441 | @@ -1298,6 +1297,18 @@ |
442 | return DecorationInterface::Ptr (); |
443 | } |
444 | |
445 | +DecorationInterface::Ptr |
446 | +DecorationList::findMatchingDecoration (Pixmap p) const |
447 | +{ |
448 | + foreach (const Decoration::Ptr &d, mList) |
449 | + { |
450 | + if (d->texture->pixmap->getPixmap () == p) |
451 | + return d; |
452 | + } |
453 | + |
454 | + return DecorationInterface::Ptr (); |
455 | +} |
456 | + |
457 | /* |
458 | * DecorationList::findMatchingDecoration |
459 | * |
460 | @@ -2334,6 +2345,42 @@ |
461 | isSwitcher = false; |
462 | } |
463 | |
464 | +DecorPixmapRequestorInterface * |
465 | +DecorScreen::findWindowRequestor (Window window) |
466 | +{ |
467 | + if (window == screen->root ()) |
468 | + { |
469 | + return &mRequestor; |
470 | + } |
471 | + else |
472 | + { |
473 | + CompWindow *w = screen->findWindow (window); |
474 | + |
475 | + if (w) |
476 | + return &(DecorWindow::get (w)->mRequestor); |
477 | + |
478 | + return NULL; |
479 | + } |
480 | +} |
481 | + |
482 | +DecorationListFindMatchingInterface * |
483 | +DecorScreen::findWindowDecorations (Window window) |
484 | +{ |
485 | + if (window == screen->root ()) |
486 | + { |
487 | + return &decor[DECOR_ACTIVE]; |
488 | + } |
489 | + else |
490 | + { |
491 | + CompWindow *w = screen->findWindow (window); |
492 | + |
493 | + if (w) |
494 | + return &(DecorWindow::get (w)->decor); |
495 | + |
496 | + return NULL; |
497 | + } |
498 | +} |
499 | + |
500 | |
501 | /* |
502 | * DecorScreen::handleEvent |
503 | @@ -2376,18 +2423,8 @@ |
504 | dw->update (true); |
505 | } |
506 | } |
507 | - /* A decoration is pending creation, allow it to be created */ |
508 | - if (event->xclient.message_type == decorPendingAtom) |
509 | - { |
510 | - CompWindow *w = screen->findWindow (event->xclient.window); |
511 | - |
512 | - if (w) |
513 | - { |
514 | - DecorWindow *dw = DecorWindow::get (w); |
515 | - |
516 | - dw->mRequestor.handlePending (event->xclient.data.l); |
517 | - } |
518 | - } |
519 | + |
520 | + mCommunicator.handleClientMessage (event->xclient); |
521 | break; |
522 | default: |
523 | /* Check for damage events. If the output or input window |
524 | @@ -3010,7 +3047,31 @@ |
525 | screen->root (), |
526 | NULL)), |
527 | mMenusClipGroup (CompMatch ("type=Dock | type=DropdownMenu | type=PopupMenu")), |
528 | - mRequestor (screen->dpy (), screen->root (), &(decor[DECOR_ACTIVE])) |
529 | + mRequestor (screen->dpy (), screen->root (), &(decor[DECOR_ACTIVE])), |
530 | + mReleasePool (new PixmapReleasePool ( |
531 | + boost::bind (XFreePixmap, |
532 | + screen->dpy (), |
533 | + _1))), |
534 | + mPendingHandler (boost::bind (&DecorScreen::findWindowRequestor, |
535 | + this, |
536 | + _1)), |
537 | + mUnusedHandler (boost::bind (&DecorScreen::findWindowDecorations, |
538 | + this, |
539 | + _1), |
540 | + mReleasePool, |
541 | + boost::bind (XFreePixmap, |
542 | + screen->dpy (), |
543 | + _1)), |
544 | + mCommunicator (XInternAtom (screen->dpy (), DECOR_PIXMAP_PENDING_ATOM_NAME, FALSE), |
545 | + XInternAtom (screen->dpy (), DECOR_DELETE_PIXMAP_ATOM_NAME, FALSE), |
546 | + boost::bind (&PendingHandler::handleMessage, |
547 | + &mPendingHandler, |
548 | + _1, |
549 | + _2), |
550 | + boost::bind (&UnusedHandler::handleMessage, |
551 | + &mUnusedHandler, |
552 | + _1, |
553 | + _2)) |
554 | { |
555 | supportingDmCheckAtom = |
556 | XInternAtom (s->dpy (), DECOR_SUPPORTING_DM_CHECK_ATOM_NAME, 0); |
557 | @@ -3033,9 +3094,9 @@ |
558 | decorSwitchWindowAtom = |
559 | XInternAtom (s->dpy (), DECOR_SWITCH_WINDOW_ATOM_NAME, 0); |
560 | decorPendingAtom = |
561 | - XInternAtom (s->dpy (), "_COMPIZ_DECOR_PENDING", 0); |
562 | + XInternAtom (s->dpy (), DECOR_PIXMAP_PENDING_ATOM_NAME, 0); |
563 | decorRequestAtom = |
564 | - XInternAtom (s->dpy (), "_COMPIZ_DECOR_REQUEST", 0); |
565 | + XInternAtom (s->dpy (), DECOR_REQUEST_PIXMAP_ATOM_NAME, 0); |
566 | requestFrameExtentsAtom = |
567 | XInternAtom (s->dpy (), "_NET_REQUEST_FRAME_EXTENTS", 0); |
568 | shadowColorAtom = |
569 | |
570 | === modified file 'plugins/decor/src/decor.h' |
571 | --- plugins/decor/src/decor.h 2012-09-07 22:37:20 +0000 |
572 | +++ plugins/decor/src/decor.h 2013-02-20 07:34:20 +0000 |
573 | @@ -159,9 +159,10 @@ |
574 | { |
575 | public: |
576 | bool updateDecoration (Window id, Atom decorAtom, DecorPixmapRequestorInterface *requestor); |
577 | - DecorationInterface::Ptr findMatchingDecoration(unsigned int frameType, |
578 | - unsigned int frameState, |
579 | - unsigned int frameActions); |
580 | + DecorationInterface::Ptr findMatchingDecoration (unsigned int frameType, |
581 | + unsigned int frameState, |
582 | + unsigned int frameActions) const; |
583 | + DecorationInterface::Ptr findMatchingDecoration (Pixmap p) const; |
584 | const Decoration::Ptr & findMatchingDecoration (CompWindow *w, bool sizeCheck); |
585 | void clear () |
586 | { |
587 | @@ -220,6 +221,11 @@ |
588 | bool registerPaintHandler (compiz::composite::PaintHandler *pHnd); |
589 | void unregisterPaintHandler (); |
590 | |
591 | + private: |
592 | + |
593 | + DecorPixmapRequestorInterface * findWindowRequestor (Window); |
594 | + DecorationListFindMatchingInterface * findWindowDecorations (Window); |
595 | + |
596 | public: |
597 | |
598 | CompositeScreen *cScreen; |
599 | @@ -255,6 +261,10 @@ |
600 | |
601 | MatchedDecorClipGroup mMenusClipGroup; |
602 | X11DecorPixmapRequestor mRequestor; |
603 | + PixmapReleasePool::Ptr mReleasePool; |
604 | + PendingHandler mPendingHandler; |
605 | + UnusedHandler mUnusedHandler; |
606 | + protocol::Communicator mCommunicator; |
607 | }; |
608 | |
609 | class DecorWindow : |
610 | |
611 | === modified file 'plugins/decor/src/pixmap-requests/include/pixmap-requests.h' |
612 | --- plugins/decor/src/pixmap-requests/include/pixmap-requests.h 2012-05-10 15:40:25 +0000 |
613 | +++ plugins/decor/src/pixmap-requests/include/pixmap-requests.h 2013-02-20 07:34:20 +0000 |
614 | @@ -26,14 +26,19 @@ |
615 | #ifndef _COMPIZ_DECOR_PIXMAP_REQUESTS_H |
616 | #define _COMPIZ_DECOR_PIXMAP_REQUESTS_H |
617 | |
618 | +#include <list> |
619 | + |
620 | #include <boost/shared_ptr.hpp> |
621 | #include <boost/shared_array.hpp> |
622 | #include <boost/make_shared.hpp> |
623 | +#include <boost/noncopyable.hpp> |
624 | +#include <boost/function.hpp> |
625 | #include <decoration.h> |
626 | |
627 | #include <X11/Xlib.h> |
628 | |
629 | -class DecorPixmapInterface |
630 | +class DecorPixmapInterface : |
631 | + boost::noncopyable |
632 | { |
633 | public: |
634 | |
635 | @@ -44,7 +49,8 @@ |
636 | virtual Pixmap getPixmap () = 0; |
637 | }; |
638 | |
639 | -class DecorPixmapReceiverInterface |
640 | +class DecorPixmapReceiverInterface : |
641 | + boost::noncopyable |
642 | { |
643 | public: |
644 | |
645 | @@ -57,7 +63,8 @@ |
646 | /* So far, nothing particularly interesting here |
647 | * we just need a way to pass around pointers for |
648 | * testing */ |
649 | -class DecorationInterface |
650 | +class DecorationInterface : |
651 | + boost::noncopyable |
652 | { |
653 | public: |
654 | |
655 | @@ -71,34 +78,50 @@ |
656 | virtual unsigned int getFrameActions () const = 0; |
657 | }; |
658 | |
659 | -class DecorPixmapDeletionInterface |
660 | -{ |
661 | - public: |
662 | - |
663 | - typedef boost::shared_ptr <DecorPixmapDeletionInterface> Ptr; |
664 | - |
665 | - virtual ~DecorPixmapDeletionInterface () {} |
666 | - |
667 | - virtual int postDeletePixmap (Pixmap pixmap) = 0; |
668 | -}; |
669 | - |
670 | -class X11PixmapDeletor : |
671 | - public DecorPixmapDeletionInterface |
672 | -{ |
673 | - public: |
674 | - |
675 | - typedef boost::shared_ptr <X11PixmapDeletor> Ptr; |
676 | - |
677 | - X11PixmapDeletor (Display *dpy) : |
678 | - mDisplay (dpy) |
679 | - { |
680 | - } |
681 | - |
682 | - int postDeletePixmap (Pixmap pixmap) { return decor_post_delete_pixmap (mDisplay, pixmap); } |
683 | +class PixmapDestroyQueue : |
684 | + boost::noncopyable |
685 | +{ |
686 | + public: |
687 | + |
688 | + typedef boost::shared_ptr <PixmapDestroyQueue> Ptr; |
689 | + |
690 | + virtual ~PixmapDestroyQueue () {} |
691 | + |
692 | + virtual int destroyUnusedPixmap (Pixmap pixmap) = 0; |
693 | +}; |
694 | + |
695 | +class UnusedPixmapQueue : |
696 | + boost::noncopyable |
697 | +{ |
698 | + public: |
699 | + |
700 | + typedef boost::shared_ptr <UnusedPixmapQueue> Ptr; |
701 | + |
702 | + virtual ~UnusedPixmapQueue () {} |
703 | + |
704 | + virtual void markUnused (Pixmap pixmap) = 0; |
705 | +}; |
706 | + |
707 | +class PixmapReleasePool : |
708 | + public PixmapDestroyQueue, |
709 | + public UnusedPixmapQueue |
710 | +{ |
711 | + public: |
712 | + |
713 | + typedef boost::function <int (Pixmap)> FreePixmapFunc; |
714 | + |
715 | + typedef boost::shared_ptr <PixmapReleasePool> Ptr; |
716 | + |
717 | + PixmapReleasePool (const FreePixmapFunc &freePixmap); |
718 | + |
719 | + void markUnused (Pixmap pixmap); |
720 | + int destroyUnusedPixmap (Pixmap pixmap); |
721 | |
722 | private: |
723 | |
724 | - Display *mDisplay; |
725 | + std::list <Pixmap> mPendingUnusedNotificationPixmaps; |
726 | + FreePixmapFunc mFreePixmap; |
727 | + |
728 | }; |
729 | |
730 | class DecorPixmap : |
731 | @@ -108,7 +131,7 @@ |
732 | |
733 | typedef boost::shared_ptr <DecorPixmap> Ptr; |
734 | |
735 | - DecorPixmap (Pixmap p, DecorPixmapDeletionInterface::Ptr deletor); |
736 | + DecorPixmap (Pixmap p, PixmapDestroyQueue::Ptr deletor); |
737 | ~DecorPixmap (); |
738 | |
739 | Pixmap getPixmap (); |
740 | @@ -116,10 +139,11 @@ |
741 | private: |
742 | |
743 | Pixmap mPixmap; |
744 | - DecorPixmapDeletionInterface::Ptr mDeletor; |
745 | + PixmapDestroyQueue::Ptr mDeletor; |
746 | }; |
747 | |
748 | -class DecorPixmapRequestorInterface |
749 | +class DecorPixmapRequestorInterface : |
750 | + boost::noncopyable |
751 | { |
752 | public: |
753 | |
754 | @@ -129,7 +153,7 @@ |
755 | unsigned int frameState, |
756 | unsigned int frameActions) = 0; |
757 | |
758 | - virtual void handlePending (long *data) = 0; |
759 | + virtual void handlePending (const long *data) = 0; |
760 | }; |
761 | |
762 | class DecorationListFindMatchingInterface |
763 | @@ -140,8 +164,76 @@ |
764 | |
765 | virtual DecorationInterface::Ptr findMatchingDecoration (unsigned int frameType, |
766 | unsigned int frameState, |
767 | - unsigned int frameActions) = 0; |
768 | -}; |
769 | + unsigned int frameActions) const = 0; |
770 | + virtual DecorationInterface::Ptr findMatchingDecoration (Pixmap pixmap) const = 0; |
771 | +}; |
772 | + |
773 | +namespace compiz |
774 | +{ |
775 | +namespace decor |
776 | +{ |
777 | +typedef boost::function <DecorationListFindMatchingInterface * (Window)> DecorListForWindow; |
778 | +typedef boost::function <DecorPixmapRequestorInterface * (Window)> RequestorForWindow; |
779 | + |
780 | +class PendingHandler : |
781 | + virtual boost::noncopyable |
782 | +{ |
783 | + public: |
784 | + |
785 | + PendingHandler (const RequestorForWindow &); |
786 | + |
787 | + void handleMessage (Window window, const long *data); |
788 | + |
789 | + private: |
790 | + |
791 | + RequestorForWindow mRequestorForWindow; |
792 | +}; |
793 | + |
794 | +class UnusedHandler : |
795 | + virtual boost::noncopyable |
796 | +{ |
797 | + public: |
798 | + |
799 | + UnusedHandler (const DecorListForWindow &, |
800 | + const UnusedPixmapQueue::Ptr &, |
801 | + const PixmapReleasePool::FreePixmapFunc &); |
802 | + |
803 | + void handleMessage (Window, Pixmap); |
804 | + |
805 | + private: |
806 | + |
807 | + DecorListForWindow mListForWindow; |
808 | + UnusedPixmapQueue::Ptr mQueue; |
809 | + PixmapReleasePool::FreePixmapFunc mFreePixmap; |
810 | +}; |
811 | + |
812 | +namespace protocol |
813 | +{ |
814 | +typedef boost::function <void (Window, const long *)> PendingMessage; |
815 | +typedef boost::function <void (Window, Pixmap)> PixmapUnusedMessage; |
816 | + |
817 | +class Communicator : |
818 | + virtual boost::noncopyable |
819 | +{ |
820 | + public: |
821 | + |
822 | + Communicator (Atom pendingMsg, |
823 | + Atom unusedMsg, |
824 | + const PendingMessage &, |
825 | + const PixmapUnusedMessage &); |
826 | + |
827 | + void handleClientMessage (const XClientMessageEvent &); |
828 | + |
829 | + private: |
830 | + |
831 | + Atom mPendingMsgAtom; |
832 | + Atom mUnusedMsgAtom; |
833 | + PendingMessage mPendingHandler; |
834 | + PixmapUnusedMessage mPixmapUnusedHander; |
835 | +}; |
836 | +} |
837 | +} |
838 | +} |
839 | |
840 | class X11DecorPixmapRequestor : |
841 | public DecorPixmapRequestorInterface |
842 | @@ -156,7 +248,7 @@ |
843 | unsigned int frameState, |
844 | unsigned int frameActions); |
845 | |
846 | - void handlePending (long *data); |
847 | + void handlePending (const long *data); |
848 | |
849 | private: |
850 | |
851 | |
852 | === modified file 'plugins/decor/src/pixmap-requests/src/pixmap-requests.cpp' |
853 | --- plugins/decor/src/pixmap-requests/src/pixmap-requests.cpp 2012-05-10 15:40:25 +0000 |
854 | +++ plugins/decor/src/pixmap-requests/src/pixmap-requests.cpp 2013-02-20 07:34:20 +0000 |
855 | @@ -6,7 +6,10 @@ |
856 | #define foreach BOOST_FOREACH |
857 | #endif |
858 | |
859 | -DecorPixmap::DecorPixmap (Pixmap pixmap, DecorPixmapDeletionInterface::Ptr d) : |
860 | +namespace cd = compiz::decor; |
861 | +namespace cdp = compiz::decor::protocol; |
862 | + |
863 | +DecorPixmap::DecorPixmap (Pixmap pixmap, PixmapDestroyQueue::Ptr d) : |
864 | mPixmap (pixmap), |
865 | mDeletor (d) |
866 | { |
867 | @@ -14,7 +17,7 @@ |
868 | |
869 | DecorPixmap::~DecorPixmap () |
870 | { |
871 | - mDeletor->postDeletePixmap (mPixmap); |
872 | + mDeletor->destroyUnusedPixmap (mPixmap); |
873 | } |
874 | |
875 | Pixmap |
876 | @@ -78,7 +81,7 @@ |
877 | } |
878 | |
879 | void |
880 | -X11DecorPixmapRequestor::handlePending (long *data) |
881 | +X11DecorPixmapRequestor::handlePending (const long *data) |
882 | { |
883 | DecorationInterface::Ptr d = mListFinder->findMatchingDecoration (static_cast <unsigned int> (data[0]), |
884 | static_cast <unsigned int> (data[1]), |
885 | @@ -91,3 +94,103 @@ |
886 | static_cast <unsigned int> (data[1]), |
887 | static_cast <unsigned int> (data[2])); |
888 | } |
889 | + |
890 | +namespace |
891 | +{ |
892 | +typedef PixmapReleasePool::FreePixmapFunc FreePixmapFunc; |
893 | +} |
894 | + |
895 | +PixmapReleasePool::PixmapReleasePool (const FreePixmapFunc &freePixmap) : |
896 | + mFreePixmap (freePixmap) |
897 | +{ |
898 | +} |
899 | + |
900 | +void |
901 | +PixmapReleasePool::markUnused (Pixmap pixmap) |
902 | +{ |
903 | + mPendingUnusedNotificationPixmaps.push_back (pixmap); |
904 | + mPendingUnusedNotificationPixmaps.unique (); |
905 | +} |
906 | + |
907 | +int |
908 | +PixmapReleasePool::destroyUnusedPixmap (Pixmap pixmap) |
909 | +{ |
910 | + std::list <Pixmap>::iterator it = |
911 | + std::find (mPendingUnusedNotificationPixmaps.begin (), |
912 | + mPendingUnusedNotificationPixmaps.end (), |
913 | + pixmap); |
914 | + |
915 | + if (it != mPendingUnusedNotificationPixmaps.end ()) |
916 | + { |
917 | + Pixmap pixmap (*it); |
918 | + mPendingUnusedNotificationPixmaps.erase (it); |
919 | + |
920 | + mFreePixmap (pixmap); |
921 | + } |
922 | + |
923 | + return 0; |
924 | +} |
925 | + |
926 | +cd::PendingHandler::PendingHandler (const cd::RequestorForWindow &requestorForWindow) : |
927 | + mRequestorForWindow (requestorForWindow) |
928 | +{ |
929 | +} |
930 | + |
931 | +void |
932 | +cd::PendingHandler::handleMessage (Window window, const long *data) |
933 | +{ |
934 | + DecorPixmapRequestorInterface *requestor = mRequestorForWindow (window); |
935 | + |
936 | + if (requestor) |
937 | + requestor->handlePending (data); |
938 | +} |
939 | + |
940 | +cd::UnusedHandler::UnusedHandler (const cd::DecorListForWindow &listForWindow, |
941 | + const UnusedPixmapQueue::Ptr &queue, |
942 | + const FreePixmapFunc &freePixmap) : |
943 | + mListForWindow (listForWindow), |
944 | + mQueue (queue), |
945 | + mFreePixmap (freePixmap) |
946 | +{ |
947 | +} |
948 | + |
949 | +void |
950 | +cd::UnusedHandler::handleMessage (Window window, Pixmap pixmap) |
951 | +{ |
952 | + DecorationListFindMatchingInterface *findMatching = mListForWindow (window); |
953 | + |
954 | + if (findMatching) |
955 | + { |
956 | + DecorationInterface::Ptr decoration (findMatching->findMatchingDecoration (pixmap)); |
957 | + |
958 | + if (decoration) |
959 | + { |
960 | + mQueue->markUnused (pixmap); |
961 | + return; |
962 | + } |
963 | + } |
964 | + |
965 | + /* If a decoration was not found, then this pixmap is no longer in use |
966 | + * and we should free it */ |
967 | + mFreePixmap (pixmap); |
968 | +} |
969 | + |
970 | +cdp::Communicator::Communicator (Atom pendingMsg, |
971 | + Atom unusedMsg, |
972 | + const cdp::PendingMessage &pending, |
973 | + const cdp::PixmapUnusedMessage &pixmapUnused) : |
974 | + mPendingMsgAtom (pendingMsg), |
975 | + mUnusedMsgAtom (unusedMsg), |
976 | + mPendingHandler (pending), |
977 | + mPixmapUnusedHander (pixmapUnused) |
978 | +{ |
979 | +} |
980 | + |
981 | +void |
982 | +cdp::Communicator::handleClientMessage (const XClientMessageEvent &xce) |
983 | +{ |
984 | + if (xce.message_type == mPendingMsgAtom) |
985 | + mPendingHandler (xce.window, xce.data.l); |
986 | + else if (xce.message_type == mUnusedMsgAtom) |
987 | + mPixmapUnusedHander (xce.window, xce.data.l[0]); |
988 | +} |
989 | |
990 | === modified file 'plugins/decor/src/pixmap-requests/tests/CMakeLists.txt' |
991 | --- plugins/decor/src/pixmap-requests/tests/CMakeLists.txt 2012-08-01 00:42:38 +0000 |
992 | +++ plugins/decor/src/pixmap-requests/tests/CMakeLists.txt 2013-02-20 07:34:20 +0000 |
993 | @@ -1,10 +1,17 @@ |
994 | include_directories(${CMAKE_CURRENT_SOURCE_DIR}) |
995 | |
996 | +add_library (compiz_decor_pixmap_requests_mock STATIC |
997 | + ${CMAKE_CURRENT_SOURCE_DIR}/compiz_decor_pixmap_requests_mock.cpp) |
998 | + |
999 | +target_link_libraries (compiz_decor_pixmap_requests_mock |
1000 | + compiz_decor_pixmap_requests) |
1001 | + |
1002 | add_executable (compiz_test_decor_pixmap_requests |
1003 | - ${CMAKE_CURRENT_SOURCE_DIR}/pixmap-requests/src/test-decor-pixmap-requests.cpp) |
1004 | + ${CMAKE_CURRENT_SOURCE_DIR}/test-decor-pixmap-requests.cpp) |
1005 | |
1006 | target_link_libraries (compiz_test_decor_pixmap_requests |
1007 | compiz_decor_pixmap_requests |
1008 | + compiz_decor_pixmap_requests_mock |
1009 | decoration |
1010 | ${GTEST_BOTH_LIBRARIES} |
1011 | ${GMOCK_LIBRARY} |
1012 | @@ -13,3 +20,5 @@ |
1013 | ) |
1014 | |
1015 | compiz_discover_tests (compiz_test_decor_pixmap_requests COVERAGE compiz_decor_pixmap_requests) |
1016 | + |
1017 | +add_subdirectory (integration) |
1018 | |
1019 | === added file 'plugins/decor/src/pixmap-requests/tests/compiz_decor_pixmap_requests_mock.cpp' |
1020 | --- plugins/decor/src/pixmap-requests/tests/compiz_decor_pixmap_requests_mock.cpp 1970-01-01 00:00:00 +0000 |
1021 | +++ plugins/decor/src/pixmap-requests/tests/compiz_decor_pixmap_requests_mock.cpp 2013-02-20 07:34:20 +0000 |
1022 | @@ -0,0 +1,113 @@ |
1023 | +/* |
1024 | + * Copyright © 2012 Canonical Ltd. |
1025 | + * Copyright © 2013 Sam Spilsbury <smspillaz@gmail.com> |
1026 | + * |
1027 | + * Permission to use, copy, modify, distribute, and sell this software |
1028 | + * and its documentation for any purpose is hereby granted without |
1029 | + * fee, provided that the above copyright notice appear in all copies |
1030 | + * and that both that copyright notice and this permission notice |
1031 | + * appear in supporting documentation, and that the name of |
1032 | + * Canonical Ltd. not be used in advertising or publicity pertaining to |
1033 | + * distribution of the software without specific, written prior permission. |
1034 | + * Canonical Ltd. makes no representations about the suitability of this |
1035 | + * software for any purpose. It is provided "as is" without express or |
1036 | + * implied warranty. |
1037 | + * |
1038 | + * CANONICAL, LTD. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, |
1039 | + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN |
1040 | + * NO EVENT SHALL CANONICAL, LTD. BE LIABLE FOR ANY SPECIAL, INDIRECT OR |
1041 | + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS |
1042 | + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, |
1043 | + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION |
1044 | + * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
1045 | + * |
1046 | + * Authored by: Sam Spilsbury <sam.spilsbury@canonical.com> |
1047 | + */ |
1048 | + |
1049 | +#include "compiz_decor_pixmap_requests_mock.h" |
1050 | + |
1051 | +/* These exist purely because the implicit details of the |
1052 | + * constructors of the MOCK_METHODs are quite complex. We can |
1053 | + * save compilation time by generating those constructors once, |
1054 | + * and linking, rather than generating multiple definitions and |
1055 | + * having the linker eliminate them */ |
1056 | + |
1057 | +MockDecorPixmapDeletor::MockDecorPixmapDeletor () |
1058 | +{ |
1059 | +} |
1060 | + |
1061 | +MockDecorPixmapDeletor::~MockDecorPixmapDeletor () |
1062 | +{ |
1063 | +} |
1064 | + |
1065 | +MockDecorPixmapReceiver::MockDecorPixmapReceiver () |
1066 | +{ |
1067 | +} |
1068 | + |
1069 | +MockDecorPixmapReceiver::~MockDecorPixmapReceiver () |
1070 | +{ |
1071 | +} |
1072 | + |
1073 | +MockDecoration::MockDecoration () |
1074 | +{ |
1075 | +} |
1076 | + |
1077 | +MockDecoration::~MockDecoration () |
1078 | +{ |
1079 | +} |
1080 | + |
1081 | +MockDecorationListFindMatching::MockDecorationListFindMatching () |
1082 | +{ |
1083 | +} |
1084 | + |
1085 | +MockDecorationListFindMatching::~MockDecorationListFindMatching () |
1086 | +{ |
1087 | +} |
1088 | + |
1089 | +MockDecorPixmapRequestor::MockDecorPixmapRequestor () |
1090 | +{ |
1091 | +} |
1092 | + |
1093 | +MockDecorPixmapRequestor::~MockDecorPixmapRequestor () |
1094 | +{ |
1095 | +} |
1096 | + |
1097 | +XlibPixmapMock::XlibPixmapMock () |
1098 | +{ |
1099 | +} |
1100 | + |
1101 | +XlibPixmapMock::~XlibPixmapMock () |
1102 | +{ |
1103 | +} |
1104 | + |
1105 | +MockFindRequestor::MockFindRequestor () |
1106 | +{ |
1107 | +} |
1108 | + |
1109 | +MockFindRequestor::~MockFindRequestor () |
1110 | +{ |
1111 | +} |
1112 | + |
1113 | +MockFindList::MockFindList () |
1114 | +{ |
1115 | +} |
1116 | + |
1117 | +MockFindList::~MockFindList () |
1118 | +{ |
1119 | +} |
1120 | + |
1121 | +MockUnusedPixmapQueue::MockUnusedPixmapQueue () |
1122 | +{ |
1123 | +} |
1124 | + |
1125 | +MockUnusedPixmapQueue::~MockUnusedPixmapQueue () |
1126 | +{ |
1127 | +} |
1128 | + |
1129 | +MockProtocolDispatchFuncs::MockProtocolDispatchFuncs () |
1130 | +{ |
1131 | +} |
1132 | + |
1133 | +MockProtocolDispatchFuncs::~MockProtocolDispatchFuncs () |
1134 | +{ |
1135 | +} |
1136 | |
1137 | === added file 'plugins/decor/src/pixmap-requests/tests/compiz_decor_pixmap_requests_mock.h' |
1138 | --- plugins/decor/src/pixmap-requests/tests/compiz_decor_pixmap_requests_mock.h 1970-01-01 00:00:00 +0000 |
1139 | +++ plugins/decor/src/pixmap-requests/tests/compiz_decor_pixmap_requests_mock.h 2013-02-20 07:34:20 +0000 |
1140 | @@ -0,0 +1,179 @@ |
1141 | +/* |
1142 | + * Copyright © 2012 Canonical Ltd. |
1143 | + * Copyright © 2013 Sam Spilsbury <smspillaz@gmail.com> |
1144 | + * |
1145 | + * Permission to use, copy, modify, distribute, and sell this software |
1146 | + * and its documentation for any purpose is hereby granted without |
1147 | + * fee, provided that the above copyright notice appear in all copies |
1148 | + * and that both that copyright notice and this permission notice |
1149 | + * appear in supporting documentation, and that the name of |
1150 | + * Canonical Ltd. not be used in advertising or publicity pertaining to |
1151 | + * distribution of the software without specific, written prior permission. |
1152 | + * Canonical Ltd. makes no representations about the suitability of this |
1153 | + * software for any purpose. It is provided "as is" without express or |
1154 | + * implied warranty. |
1155 | + * |
1156 | + * CANONICAL, LTD. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, |
1157 | + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN |
1158 | + * NO EVENT SHALL CANONICAL, LTD. BE LIABLE FOR ANY SPECIAL, INDIRECT OR |
1159 | + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS |
1160 | + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, |
1161 | + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION |
1162 | + * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
1163 | + * |
1164 | + * Authored by: Sam Spilsbury <sam.spilsbury@canonical.com> |
1165 | + */ |
1166 | + |
1167 | +#ifndef _COMPIZ_DECOR_PIXMAP_REQUESTS_MOCK_H |
1168 | +#define _COMPIZ_DECOR_PIXMAP_REQUESTS_MOCK_H |
1169 | + |
1170 | +#include <gmock/gmock.h> |
1171 | +#include <boost/bind.hpp> |
1172 | + |
1173 | +#include <X11/Xlib.h> |
1174 | +#include "pixmap-requests.h" |
1175 | + |
1176 | +class MockDecorPixmapDeletor : |
1177 | + public PixmapDestroyQueue |
1178 | +{ |
1179 | + public: |
1180 | + |
1181 | + MockDecorPixmapDeletor (); |
1182 | + ~MockDecorPixmapDeletor (); |
1183 | + |
1184 | + MOCK_METHOD1 (destroyUnusedPixmap, int (Pixmap p)); |
1185 | +}; |
1186 | + |
1187 | +class MockDecorPixmapReceiver : |
1188 | + public DecorPixmapReceiverInterface |
1189 | +{ |
1190 | + public: |
1191 | + |
1192 | + MockDecorPixmapReceiver (); |
1193 | + ~MockDecorPixmapReceiver (); |
1194 | + |
1195 | + MOCK_METHOD0 (pending, void ()); |
1196 | + MOCK_METHOD0 (update, void ()); |
1197 | +}; |
1198 | + |
1199 | +class MockDecoration : |
1200 | + public DecorationInterface |
1201 | +{ |
1202 | + public: |
1203 | + |
1204 | + MockDecoration (); |
1205 | + ~MockDecoration (); |
1206 | + |
1207 | + MOCK_METHOD0 (receiverInterface, DecorPixmapReceiverInterface & ()); |
1208 | + MOCK_CONST_METHOD0 (getFrameType, unsigned int ()); |
1209 | + MOCK_CONST_METHOD0 (getFrameState, unsigned int ()); |
1210 | + MOCK_CONST_METHOD0 (getFrameActions, unsigned int ()); |
1211 | +}; |
1212 | + |
1213 | +class MockDecorationListFindMatching : |
1214 | + public DecorationListFindMatchingInterface |
1215 | +{ |
1216 | + public: |
1217 | + |
1218 | + MockDecorationListFindMatching (); |
1219 | + ~MockDecorationListFindMatching (); |
1220 | + |
1221 | + MOCK_CONST_METHOD3 (findMatchingDecoration, DecorationInterface::Ptr (unsigned int, unsigned int, unsigned int)); |
1222 | + MOCK_CONST_METHOD1 (findMatchingDecoration, DecorationInterface::Ptr (Pixmap)); |
1223 | +}; |
1224 | + |
1225 | +class MockDecorPixmapRequestor : |
1226 | + public DecorPixmapRequestorInterface |
1227 | +{ |
1228 | + public: |
1229 | + |
1230 | + MockDecorPixmapRequestor (); |
1231 | + ~MockDecorPixmapRequestor (); |
1232 | + |
1233 | + MOCK_METHOD3 (postGenerateRequest, int (unsigned int, unsigned int, unsigned int)); |
1234 | + MOCK_METHOD1 (handlePending, void (const long *)); |
1235 | +}; |
1236 | + |
1237 | +class XlibPixmapMock |
1238 | +{ |
1239 | + public: |
1240 | + |
1241 | + XlibPixmapMock (); |
1242 | + ~XlibPixmapMock (); |
1243 | + |
1244 | + MOCK_METHOD1(freePixmap, int (Pixmap)); |
1245 | +}; |
1246 | + |
1247 | +class MockFindRequestor |
1248 | +{ |
1249 | + public: |
1250 | + |
1251 | + MockFindRequestor (); |
1252 | + ~MockFindRequestor (); |
1253 | + |
1254 | + MOCK_METHOD1 (findRequestor, DecorPixmapRequestorInterface * (Window)); |
1255 | +}; |
1256 | + |
1257 | +class MockFindList |
1258 | +{ |
1259 | + public: |
1260 | + |
1261 | + MockFindList (); |
1262 | + ~MockFindList (); |
1263 | + |
1264 | + MOCK_METHOD1 (findList, DecorationListFindMatchingInterface * (Window)); |
1265 | +}; |
1266 | + |
1267 | +class MockUnusedPixmapQueue : |
1268 | + public UnusedPixmapQueue |
1269 | +{ |
1270 | + public: |
1271 | + |
1272 | + MockUnusedPixmapQueue (); |
1273 | + ~MockUnusedPixmapQueue (); |
1274 | + |
1275 | + typedef boost::shared_ptr <MockUnusedPixmapQueue> Ptr; |
1276 | + |
1277 | + MOCK_METHOD1 (markUnused, void (Pixmap)); |
1278 | +}; |
1279 | + |
1280 | +class StubReceiver : |
1281 | + public DecorPixmapReceiverInterface |
1282 | +{ |
1283 | + public: |
1284 | + |
1285 | + void pending () {} |
1286 | + void update () {} |
1287 | +}; |
1288 | + |
1289 | +class StubDecoration : |
1290 | + public DecorationInterface |
1291 | +{ |
1292 | + public: |
1293 | + |
1294 | + DecorPixmapReceiverInterface & receiverInterface () |
1295 | + { |
1296 | + return mReceiver; |
1297 | + } |
1298 | + |
1299 | + unsigned int getFrameType () const { return 0; } |
1300 | + unsigned int getFrameState () const { return 0; } |
1301 | + unsigned int getFrameActions () const { return 0; } |
1302 | + |
1303 | + private: |
1304 | + |
1305 | + StubReceiver mReceiver; |
1306 | +}; |
1307 | + |
1308 | +class MockProtocolDispatchFuncs |
1309 | +{ |
1310 | + public: |
1311 | + |
1312 | + MockProtocolDispatchFuncs (); |
1313 | + ~MockProtocolDispatchFuncs (); |
1314 | + |
1315 | + MOCK_METHOD2 (handlePending, void (Window, const long *)); |
1316 | + MOCK_METHOD2 (handleUnused, void (Window, Pixmap)); |
1317 | +}; |
1318 | + |
1319 | +#endif |
1320 | |
1321 | === added directory 'plugins/decor/src/pixmap-requests/tests/integration' |
1322 | === added file 'plugins/decor/src/pixmap-requests/tests/integration/CMakeLists.txt' |
1323 | --- plugins/decor/src/pixmap-requests/tests/integration/CMakeLists.txt 1970-01-01 00:00:00 +0000 |
1324 | +++ plugins/decor/src/pixmap-requests/tests/integration/CMakeLists.txt 2013-02-20 07:34:20 +0000 |
1325 | @@ -0,0 +1,1 @@ |
1326 | +add_subdirectory (xorg-gtest) |
1327 | |
1328 | === added directory 'plugins/decor/src/pixmap-requests/tests/integration/xorg-gtest' |
1329 | === added file 'plugins/decor/src/pixmap-requests/tests/integration/xorg-gtest/CMakeLists.txt' |
1330 | --- plugins/decor/src/pixmap-requests/tests/integration/xorg-gtest/CMakeLists.txt 1970-01-01 00:00:00 +0000 |
1331 | +++ plugins/decor/src/pixmap-requests/tests/integration/xorg-gtest/CMakeLists.txt 2013-02-20 07:34:20 +0000 |
1332 | @@ -0,0 +1,41 @@ |
1333 | +include (FindPkgConfig) |
1334 | + |
1335 | +if (BUILD_XORG_GTEST) |
1336 | + |
1337 | + include_directories (${compiz_SOURCE_DIR}/tests/shared |
1338 | + ${COMPIZ_XORG_SYSTEM_TEST_INCLUDE_DIR} |
1339 | + ${X11_INCLUDE_DIRS} |
1340 | + ${XORG_SERVER_INCLUDE_XORG_GTEST} |
1341 | + ${XORG_SERVER_GTEST_SRC} |
1342 | + ${GTEST_INCLUDE_DIRS} |
1343 | + ${COMPIZ_DECOR_PIXMAP_PROTOCOL_INTEGRATION_INCLUDE_DIRS}) |
1344 | + |
1345 | + link_directories (${X11_XI_LIBRARY_DIRS} |
1346 | + ${COMPIZ_COMPOSITE_DAMAGETRACKING_INTEGRATION_LIBRARY_DIRS}) |
1347 | + |
1348 | + add_executable (compiz_test_decor_pixmap_protocol_integration |
1349 | + ${CMAKE_CURRENT_SOURCE_DIR}/compiz_test_decor_pixmap_protocol_integration.cpp) |
1350 | + |
1351 | + set (COMPIZ_DECOR_PIXMAP_PROTOCOL_XORG_INTEGRATION_TEST_LIBRARIES |
1352 | + xorg_gtest_all |
1353 | + xorg_gtest_main |
1354 | + compiz_xorg_gtest_system_test |
1355 | + compiz_decor_pixmap_requests |
1356 | + compiz_decor_pixmap_requests_mock |
1357 | + decoration |
1358 | + ${GMOCK_LIBRARY} |
1359 | + ${GMOCK_MAIN_LIBRARY} |
1360 | + ${GTEST_BOTH_LIBRARIES} |
1361 | + ${CMAKE_THREAD_LIBS_INIT} |
1362 | + ${XORG_SERVER_LIBRARIES} |
1363 | + ${X11_XI_LIBRARIES} |
1364 | + ${COMPIZ_DECOR_PIXMAP_PROTOCOL_INTEGRATION_LIBRARIES}) |
1365 | + |
1366 | + target_link_libraries (compiz_test_decor_pixmap_protocol_integration |
1367 | + ${COMPIZ_DECOR_PIXMAP_PROTOCOL_XORG_INTEGRATION_TEST_LIBRARIES}) |
1368 | + |
1369 | + compiz_discover_tests (compiz_test_decor_pixmap_protocol_integration WITH_XORG_GTEST COVERAGE |
1370 | + compiz_decor_pixmap_requests) |
1371 | + |
1372 | +endif (BUILD_XORG_GTEST) |
1373 | + |
1374 | |
1375 | === added file 'plugins/decor/src/pixmap-requests/tests/integration/xorg-gtest/compiz_test_decor_pixmap_protocol_integration.cpp' |
1376 | --- plugins/decor/src/pixmap-requests/tests/integration/xorg-gtest/compiz_test_decor_pixmap_protocol_integration.cpp 1970-01-01 00:00:00 +0000 |
1377 | +++ plugins/decor/src/pixmap-requests/tests/integration/xorg-gtest/compiz_test_decor_pixmap_protocol_integration.cpp 2013-02-20 07:34:20 +0000 |
1378 | @@ -0,0 +1,483 @@ |
1379 | +/* |
1380 | + * Compiz XOrg GTest Decoration Pixmap Protocol Integration Tests |
1381 | + * |
1382 | + * Copyright (C) 2013 Sam Spilsbury. |
1383 | + * |
1384 | + * This library is free software; you can redistribute it and/or |
1385 | + * modify it under the terms of the GNU Lesser General Public |
1386 | + * License as published by the Free Software Foundation; either |
1387 | + * version 2.1 of the License, or (at your option) any later version. |
1388 | + |
1389 | + * This library is distributed in the hope that it will be useful, |
1390 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
1391 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
1392 | + * Lesser General Public License for more details. |
1393 | + |
1394 | + * You should have received a copy of the GNU Lesser General Public |
1395 | + * License along with this library; if not, write to the Free Software |
1396 | + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
1397 | + * |
1398 | + * Authored By: |
1399 | + * Sam Spilsbury <smspillaz@gmail.com> |
1400 | + */ |
1401 | +#include <gtest/gtest.h> |
1402 | +#include <gmock/gmock.h> |
1403 | + |
1404 | +#include <boost/function.hpp> |
1405 | +#include <boost/bind.hpp> |
1406 | + |
1407 | +#include <boost/shared_ptr.hpp> |
1408 | +#include <boost/make_shared.hpp> |
1409 | + |
1410 | +#include <X11/Xlib.h> |
1411 | +#include <X11/Xatom.h> |
1412 | + |
1413 | +#include "decoration.h" |
1414 | + |
1415 | +#include <xorg/gtest/xorg-gtest.h> |
1416 | +#include <compiz-xorg-gtest.h> |
1417 | + |
1418 | +#include "pixmap-requests.h" |
1419 | +#include "compiz_decor_pixmap_requests_mock.h" |
1420 | + |
1421 | +namespace xt = xorg::testing; |
1422 | +namespace ct = compiz::testing; |
1423 | +namespace cd = compiz::decor; |
1424 | +namespace cdp = compiz::decor::protocol; |
1425 | + |
1426 | +using ::testing::AtLeast; |
1427 | +using ::testing::ReturnNull; |
1428 | +using ::testing::Return; |
1429 | +using ::testing::MatcherInterface; |
1430 | +using ::testing::MatchResultListener; |
1431 | +using ::testing::_; |
1432 | + |
1433 | +class DecorPixmapProtocol : |
1434 | + public xorg::testing::Test |
1435 | +{ |
1436 | + public: |
1437 | + |
1438 | + typedef boost::function <void (const XClientMessageEvent &)> ClientMessageReceiver; |
1439 | + |
1440 | + void SetUp (); |
1441 | + |
1442 | + void WaitForClientMessageOnAndDeliverTo (Window client, |
1443 | + Atom message, |
1444 | + const ClientMessageReceiver &receiver); |
1445 | + |
1446 | + protected: |
1447 | + |
1448 | + Atom deletePixmapMessage; |
1449 | + Atom pendingMessage; |
1450 | +}; |
1451 | + |
1452 | +namespace |
1453 | +{ |
1454 | +bool Advance (Display *d, bool result) |
1455 | +{ |
1456 | + return ct::AdvanceToNextEventOnSuccess (d, result); |
1457 | +} |
1458 | + |
1459 | +Window MOCK_WINDOW = 1; |
1460 | +Pixmap MOCK_PIXMAP = 2; |
1461 | + |
1462 | +class MockClientMessageReceiver |
1463 | +{ |
1464 | + public: |
1465 | + |
1466 | + MOCK_METHOD1 (receiveMsg, void (const XClientMessageEvent &)); |
1467 | +}; |
1468 | + |
1469 | +class DisplayFetch |
1470 | +{ |
1471 | + public: |
1472 | + |
1473 | + virtual ~DisplayFetch () {} |
1474 | + |
1475 | + virtual ::Display * Display () const = 0; |
1476 | +}; |
1477 | + |
1478 | +class XFreePixmapWrapper |
1479 | +{ |
1480 | + public: |
1481 | + |
1482 | + XFreePixmapWrapper (const DisplayFetch &df) : |
1483 | + mDisplayFetch (df) |
1484 | + { |
1485 | + } |
1486 | + |
1487 | + int FreePixmap (Pixmap pixmap) |
1488 | + { |
1489 | + return XFreePixmap (mDisplayFetch.Display (), pixmap); |
1490 | + } |
1491 | + |
1492 | + private: |
1493 | + |
1494 | + const DisplayFetch &mDisplayFetch; |
1495 | +}; |
1496 | + |
1497 | +class XErrorTracker |
1498 | +{ |
1499 | + public: |
1500 | + |
1501 | + XErrorTracker (); |
1502 | + ~XErrorTracker (); |
1503 | + |
1504 | + MOCK_METHOD1 (errorHandler, void (int)); |
1505 | + |
1506 | + private: |
1507 | + |
1508 | + XErrorHandler handler; |
1509 | + |
1510 | + static int handleXError (Display *dpy, XErrorEvent *ev); |
1511 | + static XErrorTracker *tracker; |
1512 | +}; |
1513 | + |
1514 | +XErrorTracker * XErrorTracker::tracker = NULL; |
1515 | + |
1516 | +XErrorTracker::XErrorTracker () |
1517 | +{ |
1518 | + tracker = this; |
1519 | + handler = XSetErrorHandler (handleXError); |
1520 | +} |
1521 | + |
1522 | +XErrorTracker::~XErrorTracker () |
1523 | +{ |
1524 | + tracker = NULL; |
1525 | + XSetErrorHandler (handler); |
1526 | +} |
1527 | + |
1528 | +int |
1529 | +XErrorTracker::handleXError (Display *dpy, XErrorEvent *ev) |
1530 | +{ |
1531 | + tracker->errorHandler (ev->error_code); |
1532 | + return 0; |
1533 | +} |
1534 | + |
1535 | +bool PixmapValid (Display *d, Pixmap p) |
1536 | +{ |
1537 | + Window root; |
1538 | + unsigned int width, height, border, depth; |
1539 | + int x, y; |
1540 | + |
1541 | + XErrorTracker tracker; |
1542 | + |
1543 | + EXPECT_CALL (tracker, errorHandler (BadDrawable)).Times (AtLeast (0)); |
1544 | + |
1545 | + bool success = XGetGeometry (d, p, &root, &x, &y, |
1546 | + &width, &height, &border, &depth); |
1547 | + |
1548 | + return success; |
1549 | +} |
1550 | +} |
1551 | + |
1552 | +void |
1553 | +DecorPixmapProtocol::SetUp () |
1554 | +{ |
1555 | + xorg::testing::Test::SetUp (); |
1556 | + |
1557 | + XSelectInput (Display (), |
1558 | + DefaultRootWindow (Display ()), |
1559 | + StructureNotifyMask); |
1560 | + |
1561 | + deletePixmapMessage = XInternAtom (Display (), DECOR_DELETE_PIXMAP_ATOM_NAME, 0); |
1562 | + pendingMessage = XInternAtom (Display (), DECOR_PIXMAP_PENDING_ATOM_NAME, 0); |
1563 | +} |
1564 | + |
1565 | +class DeliveryMatcher : |
1566 | + public ct::XEventMatcher |
1567 | +{ |
1568 | + public: |
1569 | + |
1570 | + DeliveryMatcher (Atom message, |
1571 | + const DecorPixmapProtocol::ClientMessageReceiver &receiver) : |
1572 | + mMessage (message), |
1573 | + mReceiver (receiver) |
1574 | + { |
1575 | + } |
1576 | + |
1577 | + bool MatchAndExplain (const XEvent &xce, |
1578 | + MatchResultListener *listener) const |
1579 | + { |
1580 | + if (xce.xclient.message_type == mMessage) |
1581 | + { |
1582 | + mReceiver (reinterpret_cast <const XClientMessageEvent &> (xce)); |
1583 | + return true; |
1584 | + } |
1585 | + else |
1586 | + return false; |
1587 | + } |
1588 | + |
1589 | + void DescribeTo (std::ostream *os) const |
1590 | + { |
1591 | + *os << "Message delivered"; |
1592 | + } |
1593 | + |
1594 | + private: |
1595 | + |
1596 | + Atom mMessage; |
1597 | + DecorPixmapProtocol::ClientMessageReceiver mReceiver; |
1598 | +}; |
1599 | + |
1600 | +void |
1601 | +DecorPixmapProtocol::WaitForClientMessageOnAndDeliverTo (Window client, |
1602 | + Atom message, |
1603 | + const ClientMessageReceiver &receiver) |
1604 | +{ |
1605 | + ::Display *d = Display (); |
1606 | + |
1607 | + DeliveryMatcher delivery (message, receiver); |
1608 | + ASSERT_TRUE (Advance (d, ct::WaitForEventOfTypeOnWindowMatching (d, |
1609 | + client, |
1610 | + ClientMessage, |
1611 | + -1, |
1612 | + -1, |
1613 | + delivery))); |
1614 | +} |
1615 | + |
1616 | +TEST_F (DecorPixmapProtocol, PostDeleteCausesClientMessage) |
1617 | +{ |
1618 | + MockClientMessageReceiver receiver; |
1619 | + ::Display *d = Display (); |
1620 | + |
1621 | + decor_post_delete_pixmap (d, |
1622 | + MOCK_WINDOW, |
1623 | + MOCK_PIXMAP); |
1624 | + |
1625 | + EXPECT_CALL (receiver, receiveMsg (_)).Times (1); |
1626 | + |
1627 | + WaitForClientMessageOnAndDeliverTo (MOCK_WINDOW, |
1628 | + deletePixmapMessage, |
1629 | + boost::bind (&MockClientMessageReceiver::receiveMsg, |
1630 | + &receiver, |
1631 | + _1)); |
1632 | +} |
1633 | + |
1634 | +TEST_F (DecorPixmapProtocol, PostDeleteDispatchesClientMessageToReceiver) |
1635 | +{ |
1636 | + MockProtocolDispatchFuncs dispatch; |
1637 | + cdp::Communicator communicator (pendingMessage, |
1638 | + deletePixmapMessage, |
1639 | + boost::bind (&MockProtocolDispatchFuncs::handlePending, |
1640 | + &dispatch, |
1641 | + _1, |
1642 | + _2), |
1643 | + boost::bind (&MockProtocolDispatchFuncs::handleUnused, |
1644 | + &dispatch, |
1645 | + _1, |
1646 | + _2)); |
1647 | + |
1648 | + decor_post_delete_pixmap (Display (), |
1649 | + MOCK_WINDOW, |
1650 | + MOCK_PIXMAP); |
1651 | + |
1652 | + EXPECT_CALL (dispatch, handleUnused (MOCK_WINDOW, MOCK_PIXMAP)).Times (1); |
1653 | + |
1654 | + WaitForClientMessageOnAndDeliverTo (MOCK_WINDOW, |
1655 | + deletePixmapMessage, |
1656 | + boost::bind (&cdp::Communicator::handleClientMessage, |
1657 | + &communicator, |
1658 | + _1)); |
1659 | +} |
1660 | + |
1661 | +/* Test end to end. Post the delete message and cause the pixmap to be freed */ |
1662 | + |
1663 | +class DecorPixmapProtocolEndToEnd : |
1664 | + public DecorPixmapProtocol, |
1665 | + public DisplayFetch |
1666 | +{ |
1667 | + public: |
1668 | + |
1669 | + DecorPixmapProtocolEndToEnd () : |
1670 | + freePixmap (*this), |
1671 | + releasePool (new PixmapReleasePool ( |
1672 | + boost::bind (&XFreePixmapWrapper::FreePixmap, |
1673 | + &freePixmap, |
1674 | + _1))), |
1675 | + pendingHandler (boost::bind (&MockFindRequestor::findRequestor, |
1676 | + &mockFindRequestor, |
1677 | + _1)), |
1678 | + unusedHandler (boost::bind (&MockFindList::findList, |
1679 | + &mockFindList, |
1680 | + _1), |
1681 | + releasePool, |
1682 | + boost::bind (&XFreePixmapWrapper::FreePixmap, |
1683 | + &freePixmap, |
1684 | + _1)), |
1685 | + stubDecoration (new StubDecoration ()) |
1686 | + { |
1687 | + } |
1688 | + |
1689 | + void SetUp () |
1690 | + { |
1691 | + DecorPixmapProtocol::SetUp (); |
1692 | + |
1693 | + communicator.reset (new cdp::Communicator ( |
1694 | + pendingMessage, |
1695 | + deletePixmapMessage, |
1696 | + boost::bind (&cd::PendingHandler::handleMessage, |
1697 | + &pendingHandler, |
1698 | + _1, |
1699 | + _2), |
1700 | + boost::bind (&cd::UnusedHandler::handleMessage, |
1701 | + &unusedHandler, |
1702 | + _1, |
1703 | + _2))); |
1704 | + } |
1705 | + |
1706 | + ::Display * |
1707 | + Display () const |
1708 | + { |
1709 | + return DecorPixmapProtocol::Display (); |
1710 | + } |
1711 | + |
1712 | + XFreePixmapWrapper freePixmap; |
1713 | + PixmapReleasePool::Ptr releasePool; |
1714 | + cd::PendingHandler pendingHandler; |
1715 | + cd::UnusedHandler unusedHandler; |
1716 | + boost::shared_ptr <cdp::Communicator> communicator; |
1717 | + MockFindList mockFindList; |
1718 | + MockFindRequestor mockFindRequestor; |
1719 | + StubDecoration::Ptr stubDecoration; |
1720 | + MockDecorPixmapRequestor mockRequestor; |
1721 | + MockDecorationListFindMatching mockFindMatching; |
1722 | + |
1723 | +}; |
1724 | + |
1725 | +class DecorPixmapProtocolDeleteEndToEnd : |
1726 | + public DecorPixmapProtocolEndToEnd |
1727 | +{ |
1728 | + public: |
1729 | + |
1730 | + void SetUp () |
1731 | + { |
1732 | + DecorPixmapProtocolEndToEnd::SetUp (); |
1733 | + |
1734 | + ::Display *d = Display (); |
1735 | + |
1736 | + pixmap = XCreatePixmap (d, |
1737 | + DefaultRootWindow (d), |
1738 | + 1, |
1739 | + 1, |
1740 | + DefaultDepth (d, |
1741 | + DefaultScreen (d))); |
1742 | + |
1743 | + decor_post_delete_pixmap (d, |
1744 | + MOCK_WINDOW, |
1745 | + pixmap); |
1746 | + } |
1747 | + |
1748 | + void TearDown () |
1749 | + { |
1750 | + if (PixmapValid (Display (), pixmap)) |
1751 | + XFreePixmap (Display (), pixmap); |
1752 | + } |
1753 | + |
1754 | + protected: |
1755 | + |
1756 | + Pixmap pixmap; |
1757 | +}; |
1758 | + |
1759 | +TEST_F (DecorPixmapProtocolDeleteEndToEnd, TestFreeNotFoundWindowPixmapImmediately) |
1760 | +{ |
1761 | + ::Display *d = Display (); |
1762 | + |
1763 | + EXPECT_CALL (mockFindList, findList (MOCK_WINDOW)).WillOnce (ReturnNull ()); |
1764 | + |
1765 | + /* Deliver it to the communicator */ |
1766 | + WaitForClientMessageOnAndDeliverTo (MOCK_WINDOW, |
1767 | + deletePixmapMessage, |
1768 | + boost::bind (&cdp::Communicator::handleClientMessage, |
1769 | + communicator.get (), |
1770 | + _1)); |
1771 | + |
1772 | + /* Check if the pixmap is still valid */ |
1773 | + EXPECT_FALSE (PixmapValid (d, pixmap)); |
1774 | +} |
1775 | + |
1776 | +TEST_F (DecorPixmapProtocolDeleteEndToEnd, TestFreeUnusedPixmapImmediately) |
1777 | +{ |
1778 | + ::Display *d = Display (); |
1779 | + |
1780 | + EXPECT_CALL (mockFindMatching, findMatchingDecoration (pixmap)).WillOnce (Return (DecorationInterface::Ptr ())); |
1781 | + EXPECT_CALL (mockFindList, findList (MOCK_WINDOW)).WillOnce (Return (&mockFindMatching)); |
1782 | + /* Deliver it to the communicator */ |
1783 | + WaitForClientMessageOnAndDeliverTo (MOCK_WINDOW, |
1784 | + deletePixmapMessage, |
1785 | + boost::bind (&cdp::Communicator::handleClientMessage, |
1786 | + communicator.get (), |
1787 | + _1)); |
1788 | + |
1789 | + /* Check if the pixmap is still valid */ |
1790 | + EXPECT_FALSE (PixmapValid (d, pixmap)); |
1791 | +} |
1792 | + |
1793 | +TEST_F (DecorPixmapProtocolDeleteEndToEnd, TestQueuePixmapIfUsed) |
1794 | +{ |
1795 | + ::Display *d = Display (); |
1796 | + |
1797 | + EXPECT_CALL (mockFindMatching, findMatchingDecoration (pixmap)).WillOnce (Return (stubDecoration)); |
1798 | + EXPECT_CALL (mockFindList, findList (MOCK_WINDOW)).WillOnce (Return (&mockFindMatching)); |
1799 | + /* Deliver it to the communicator */ |
1800 | + WaitForClientMessageOnAndDeliverTo (MOCK_WINDOW, |
1801 | + deletePixmapMessage, |
1802 | + boost::bind (&cdp::Communicator::handleClientMessage, |
1803 | + communicator.get (), |
1804 | + _1)); |
1805 | + |
1806 | + /* Check if the pixmap is still valid */ |
1807 | + EXPECT_TRUE (PixmapValid (d, pixmap)); |
1808 | + |
1809 | + /* Call destroyUnusedPixmap on the release pool, it should release |
1810 | + * the pixmap which was otherwise unused */ |
1811 | + releasePool->destroyUnusedPixmap (pixmap); |
1812 | + |
1813 | + /* Pixmap should now be invalid */ |
1814 | + EXPECT_FALSE (PixmapValid (d, pixmap)); |
1815 | +} |
1816 | + |
1817 | +class DecorPixmapProtocolPendingEndToEnd : |
1818 | + public DecorPixmapProtocolEndToEnd |
1819 | +{ |
1820 | + public: |
1821 | + |
1822 | + DecorPixmapProtocolPendingEndToEnd () : |
1823 | + frameType (1), |
1824 | + frameState (2), |
1825 | + frameActions (3) |
1826 | + { |
1827 | + } |
1828 | + |
1829 | + void SetUp () |
1830 | + { |
1831 | + DecorPixmapProtocolEndToEnd::SetUp (); |
1832 | + |
1833 | + ::Display *d = Display (); |
1834 | + |
1835 | + decor_post_pending (d, MOCK_WINDOW, frameType, frameState, frameActions); |
1836 | + } |
1837 | + |
1838 | + protected: |
1839 | + |
1840 | + unsigned int frameType, frameState, frameActions; |
1841 | +}; |
1842 | + |
1843 | +MATCHER_P3 (MatchArrayValues3, v1, v2, v3, "Matches three array values") |
1844 | +{ |
1845 | + return static_cast <unsigned int> (arg[0]) == v1 && |
1846 | + static_cast <unsigned int> (arg[1]) == v2 && |
1847 | + static_cast <unsigned int> (arg[2]) == v3; |
1848 | +} |
1849 | + |
1850 | +TEST_F (DecorPixmapProtocolPendingEndToEnd, TestPostPendingMarksAsPendingOnClient) |
1851 | +{ |
1852 | + EXPECT_CALL (mockFindRequestor, findRequestor (MOCK_WINDOW)).WillOnce (Return (&mockRequestor)); |
1853 | + EXPECT_CALL (mockRequestor, handlePending (MatchArrayValues3 (frameType, frameState, frameActions))); |
1854 | + |
1855 | + /* Deliver it to the communicator */ |
1856 | + WaitForClientMessageOnAndDeliverTo (MOCK_WINDOW, |
1857 | + pendingMessage, |
1858 | + boost::bind (&cdp::Communicator::handleClientMessage, |
1859 | + communicator.get (), |
1860 | + _1)); |
1861 | +} |
1862 | |
1863 | === renamed file 'plugins/decor/src/pixmap-requests/tests/pixmap-requests/src/test-decor-pixmap-requests.cpp' => 'plugins/decor/src/pixmap-requests/tests/test-decor-pixmap-requests.cpp' |
1864 | --- plugins/decor/src/pixmap-requests/tests/pixmap-requests/src/test-decor-pixmap-requests.cpp 2012-05-10 15:40:25 +0000 |
1865 | +++ plugins/decor/src/pixmap-requests/tests/test-decor-pixmap-requests.cpp 2013-02-20 07:34:20 +0000 |
1866 | @@ -25,67 +25,29 @@ |
1867 | |
1868 | #include <gtest/gtest.h> |
1869 | #include <gmock/gmock.h> |
1870 | +#include <boost/bind.hpp> |
1871 | #include <iostream> |
1872 | + |
1873 | +#include <X11/Xlib.h> |
1874 | #include "pixmap-requests.h" |
1875 | +#include "compiz_decor_pixmap_requests_mock.h" |
1876 | |
1877 | +using ::testing::AtLeast; |
1878 | +using ::testing::Pointee; |
1879 | using ::testing::Return; |
1880 | - |
1881 | -class DecorPixmapRequestsTest : |
1882 | - public ::testing::Test |
1883 | -{ |
1884 | -}; |
1885 | - |
1886 | -class MockDecorPixmapDeletor : |
1887 | - public DecorPixmapDeletionInterface |
1888 | -{ |
1889 | - public: |
1890 | - |
1891 | - MOCK_METHOD1 (postDeletePixmap, int (Pixmap p)); |
1892 | -}; |
1893 | - |
1894 | -class MockDecorPixmapReceiver : |
1895 | - public DecorPixmapReceiverInterface |
1896 | -{ |
1897 | - public: |
1898 | - |
1899 | - MOCK_METHOD0 (pending, void ()); |
1900 | - MOCK_METHOD0 (update, void ()); |
1901 | -}; |
1902 | - |
1903 | -class MockDecoration : |
1904 | - public DecorationInterface |
1905 | -{ |
1906 | - public: |
1907 | - |
1908 | - MOCK_METHOD0 (receiverInterface, DecorPixmapReceiverInterface & ()); |
1909 | - MOCK_CONST_METHOD0 (getFrameType, unsigned int ()); |
1910 | - MOCK_CONST_METHOD0 (getFrameState, unsigned int ()); |
1911 | - MOCK_CONST_METHOD0 (getFrameActions, unsigned int ()); |
1912 | -}; |
1913 | - |
1914 | -class MockDecorationListFindMatching : |
1915 | - public DecorationListFindMatchingInterface |
1916 | -{ |
1917 | - public: |
1918 | - |
1919 | - MOCK_METHOD3 (findMatchingDecoration, DecorationInterface::Ptr (unsigned int, unsigned int, unsigned int)); |
1920 | -}; |
1921 | - |
1922 | -class MockDecorPixmapRequestor : |
1923 | - public DecorPixmapRequestorInterface |
1924 | -{ |
1925 | - public: |
1926 | - |
1927 | - MOCK_METHOD3 (postGenerateRequest, int (unsigned int, unsigned int, unsigned int)); |
1928 | - MOCK_METHOD1 (handlePending, void (long *)); |
1929 | -}; |
1930 | +using ::testing::ReturnNull; |
1931 | +using ::testing::IsNull; |
1932 | +using ::testing::_; |
1933 | + |
1934 | +namespace cd = compiz::decor; |
1935 | +namespace cdp = compiz::decor::protocol; |
1936 | |
1937 | TEST(DecorPixmapRequestsTest, TestDestroyPixmapDeletes) |
1938 | { |
1939 | boost::shared_ptr <MockDecorPixmapDeletor> mockDeletor = boost::make_shared <MockDecorPixmapDeletor> (); |
1940 | - DecorPixmap pm (1, boost::shared_static_cast<DecorPixmapDeletionInterface> (mockDeletor)); |
1941 | + DecorPixmap pm (1, boost::shared_static_cast<PixmapDestroyQueue> (mockDeletor)); |
1942 | |
1943 | - EXPECT_CALL (*(mockDeletor.get ()), postDeletePixmap (1)).WillOnce (Return (1)); |
1944 | + EXPECT_CALL (*(mockDeletor.get ()), destroyUnusedPixmap (1)).WillOnce (Return (1)); |
1945 | } |
1946 | |
1947 | TEST(DecorPixmapRequestsTest, TestPendingGeneratesRequest) |
1948 | @@ -158,3 +120,284 @@ |
1949 | receiver.pending (); |
1950 | receiver.update (); |
1951 | } |
1952 | + |
1953 | +class DecorPixmapReleasePool : |
1954 | + public ::testing::Test |
1955 | +{ |
1956 | + public: |
1957 | + |
1958 | + DecorPixmapReleasePool () : |
1959 | + mockFreeFunc (boost::bind (&XlibPixmapMock::freePixmap, |
1960 | + &xlibPixmapMock, |
1961 | + _1)), |
1962 | + releasePool (mockFreeFunc) |
1963 | + { |
1964 | + } |
1965 | + |
1966 | + XlibPixmapMock xlibPixmapMock; |
1967 | + PixmapReleasePool::FreePixmapFunc mockFreeFunc; |
1968 | + |
1969 | + PixmapReleasePool releasePool; |
1970 | +}; |
1971 | + |
1972 | +TEST_F (DecorPixmapReleasePool, MarkUnusedNoFree) |
1973 | +{ |
1974 | + /* Never free pixmaps on markUnused */ |
1975 | + |
1976 | + EXPECT_CALL (xlibPixmapMock, freePixmap (_)).Times (0); |
1977 | + |
1978 | + releasePool.markUnused (static_cast <Pixmap> (1)); |
1979 | +} |
1980 | + |
1981 | +TEST_F (DecorPixmapReleasePool, NoFreeOnPostDeleteIfNotInList) |
1982 | +{ |
1983 | + EXPECT_CALL (xlibPixmapMock, freePixmap (_)).Times (0); |
1984 | + |
1985 | + releasePool.destroyUnusedPixmap (static_cast <Pixmap> (1)); |
1986 | +} |
1987 | + |
1988 | +TEST_F (DecorPixmapReleasePool, FreeOnPostDeleteIfMarkedUnused) |
1989 | +{ |
1990 | + EXPECT_CALL (xlibPixmapMock, freePixmap (1)).Times (1); |
1991 | + |
1992 | + releasePool.markUnused (static_cast <Pixmap> (1)); |
1993 | + releasePool.destroyUnusedPixmap (static_cast <Pixmap> (1)); |
1994 | +} |
1995 | + |
1996 | +TEST_F (DecorPixmapReleasePool, FreeOnPostDeleteIfMarkedUnusedOnceOnly) |
1997 | +{ |
1998 | + EXPECT_CALL (xlibPixmapMock, freePixmap (1)).Times (1); |
1999 | + |
2000 | + releasePool.markUnused (static_cast <Pixmap> (1)); |
2001 | + releasePool.destroyUnusedPixmap (static_cast <Pixmap> (1)); |
2002 | + releasePool.destroyUnusedPixmap (static_cast <Pixmap> (1)); |
2003 | +} |
2004 | + |
2005 | +TEST_F (DecorPixmapReleasePool, UnusedUniqueness) |
2006 | +{ |
2007 | + EXPECT_CALL (xlibPixmapMock, freePixmap (1)).Times (1); |
2008 | + |
2009 | + releasePool.markUnused (static_cast <Pixmap> (1)); |
2010 | + releasePool.markUnused (static_cast <Pixmap> (1)); |
2011 | + releasePool.destroyUnusedPixmap (static_cast <Pixmap> (1)); |
2012 | + releasePool.destroyUnusedPixmap (static_cast <Pixmap> (1)); |
2013 | +} |
2014 | + |
2015 | +class DecorPendingMessageHandler : |
2016 | + public ::testing::Test |
2017 | +{ |
2018 | + public: |
2019 | + |
2020 | + DecorPendingMessageHandler () : |
2021 | + pendingHandler (boost::bind (&MockFindRequestor::findRequestor, |
2022 | + &mockRequestorFind, |
2023 | + _1)) |
2024 | + { |
2025 | + } |
2026 | + |
2027 | + MockFindRequestor mockRequestorFind; |
2028 | + MockDecorPixmapRequestor mockRequestor; |
2029 | + |
2030 | + cd::PendingHandler pendingHandler; |
2031 | +}; |
2032 | + |
2033 | +namespace |
2034 | +{ |
2035 | +Window mockWindow = 1; |
2036 | +} |
2037 | + |
2038 | +TEST_F (DecorPendingMessageHandler, NoPendingIfNotFound) |
2039 | +{ |
2040 | + EXPECT_CALL (mockRequestor, handlePending (_)).Times (0); |
2041 | + EXPECT_CALL (mockRequestorFind, findRequestor (mockWindow)).WillOnce (ReturnNull ()); |
2042 | + |
2043 | + long data = 1; |
2044 | + pendingHandler.handleMessage (mockWindow, &data); |
2045 | +} |
2046 | + |
2047 | +TEST_F (DecorPendingMessageHandler, PendingIfFound) |
2048 | +{ |
2049 | + long data = 1; |
2050 | + |
2051 | + EXPECT_CALL (mockRequestor, handlePending (Pointee (data))); |
2052 | + EXPECT_CALL (mockRequestorFind, findRequestor (mockWindow)).WillOnce (Return (&mockRequestor)); |
2053 | + |
2054 | + pendingHandler.handleMessage (mockWindow, &data); |
2055 | +} |
2056 | + |
2057 | +class DecorUnusedMessageHandler : |
2058 | + public ::testing::Test |
2059 | +{ |
2060 | + public: |
2061 | + |
2062 | + DecorUnusedMessageHandler () : |
2063 | + mockUnusedPixmapQueue (new MockUnusedPixmapQueue ()), |
2064 | + unusedHandler (boost::bind (&MockFindList::findList, |
2065 | + &mockListFind, |
2066 | + _1), |
2067 | + mockUnusedPixmapQueue, |
2068 | + boost::bind (&XlibPixmapMock::freePixmap, |
2069 | + &xlibPixmapMock, |
2070 | + _1)) |
2071 | + { |
2072 | + } |
2073 | + |
2074 | + MockFindList mockListFind; |
2075 | + MockDecorationListFindMatching mockListFinder; |
2076 | + MockUnusedPixmapQueue::Ptr mockUnusedPixmapQueue; |
2077 | + XlibPixmapMock xlibPixmapMock; |
2078 | + |
2079 | + cd::UnusedHandler unusedHandler; |
2080 | +}; |
2081 | + |
2082 | +namespace |
2083 | +{ |
2084 | +Pixmap mockPixmap = 2; |
2085 | +} |
2086 | + |
2087 | +TEST_F (DecorUnusedMessageHandler, FreeImmediatelyWindowNotFound) |
2088 | +{ |
2089 | + /* Don't verify calls to mockListFind */ |
2090 | + EXPECT_CALL (mockListFind, findList (_)).Times (AtLeast (0)); |
2091 | + |
2092 | + /* Just free the pixmap immediately if no window was found */ |
2093 | + EXPECT_CALL (xlibPixmapMock, freePixmap (mockPixmap)).Times (1); |
2094 | + |
2095 | + ON_CALL (mockListFind, findList (mockWindow)).WillByDefault (ReturnNull ()); |
2096 | + unusedHandler.handleMessage (mockWindow, mockPixmap); |
2097 | +} |
2098 | + |
2099 | +TEST_F (DecorUnusedMessageHandler, FreeImmediatelyIfNoDecorationFound) |
2100 | +{ |
2101 | + /* Don't verify calls to mockListFind or mockListFinder */ |
2102 | + EXPECT_CALL (mockListFind, findList (_)).Times (AtLeast (0)); |
2103 | + EXPECT_CALL (mockListFinder, findMatchingDecoration (_)).Times (AtLeast (0)); |
2104 | + |
2105 | + EXPECT_CALL (xlibPixmapMock, freePixmap (mockPixmap)).Times (1); |
2106 | + |
2107 | + ON_CALL (mockListFind, findList (mockWindow)) |
2108 | + .WillByDefault (Return (&mockListFinder)); |
2109 | + ON_CALL (mockListFinder, findMatchingDecoration (mockPixmap)) |
2110 | + .WillByDefault (Return (DecorationInterface::Ptr ())); |
2111 | + |
2112 | + unusedHandler.handleMessage (mockWindow, mockPixmap); |
2113 | +} |
2114 | + |
2115 | +TEST_F (DecorUnusedMessageHandler, AddToQueueIfInUse) |
2116 | +{ |
2117 | + /* Don't verify calls to mockListFind or mockListFinder */ |
2118 | + EXPECT_CALL (mockListFind, findList (_)).Times (AtLeast (0)); |
2119 | + EXPECT_CALL (mockListFinder, findMatchingDecoration (_)).Times (AtLeast (0)); |
2120 | + |
2121 | + DecorationInterface::Ptr mockDecoration (new StubDecoration ()); |
2122 | + |
2123 | + /* Do not immediately free the pixmap */ |
2124 | + EXPECT_CALL (xlibPixmapMock, freePixmap (mockPixmap)).Times (0); |
2125 | + EXPECT_CALL (*mockUnusedPixmapQueue, markUnused (mockPixmap)).Times (1); |
2126 | + |
2127 | + ON_CALL (mockListFind, findList (mockWindow)) |
2128 | + .WillByDefault (Return (&mockListFinder)); |
2129 | + ON_CALL (mockListFinder, findMatchingDecoration (mockPixmap)) |
2130 | + .WillByDefault (Return (mockDecoration)); |
2131 | + |
2132 | + unusedHandler.handleMessage (mockWindow, mockPixmap); |
2133 | +} |
2134 | + |
2135 | +namespace |
2136 | +{ |
2137 | +Atom pendingMsg = 3; |
2138 | +Atom unusedMsg = 4; |
2139 | +} |
2140 | + |
2141 | +class DecorProtocolCommunicator : |
2142 | + public ::testing::Test |
2143 | +{ |
2144 | + public: |
2145 | + |
2146 | + DecorProtocolCommunicator () : |
2147 | + handlePendingFunc (boost::bind (&MockProtocolDispatchFuncs::handlePending, |
2148 | + &mockProtoDispatch, |
2149 | + _1, |
2150 | + _2)), |
2151 | + handleUnusedFunc (boost::bind (&MockProtocolDispatchFuncs::handleUnused, |
2152 | + &mockProtoDispatch, |
2153 | + _1, |
2154 | + _2)), |
2155 | + protocolCommunicator (pendingMsg, |
2156 | + unusedMsg, |
2157 | + handlePendingFunc, |
2158 | + handleUnusedFunc) |
2159 | + { |
2160 | + } |
2161 | + |
2162 | + void ClientMessageData (XClientMessageEvent &msg, |
2163 | + Window window, |
2164 | + Atom atom, |
2165 | + long l1, |
2166 | + long l2, |
2167 | + long l3, |
2168 | + long l4) |
2169 | + { |
2170 | + msg.window = window; |
2171 | + msg.message_type = atom; |
2172 | + msg.data.l[0] = l1; |
2173 | + msg.data.l[1] = l2; |
2174 | + msg.data.l[2] = l3; |
2175 | + msg.data.l[3] = l4; |
2176 | + } |
2177 | + |
2178 | + MockProtocolDispatchFuncs mockProtoDispatch; |
2179 | + cdp::PendingMessage handlePendingFunc; |
2180 | + cdp::PixmapUnusedMessage handleUnusedFunc; |
2181 | + |
2182 | + cdp::Communicator protocolCommunicator; |
2183 | +}; |
2184 | + |
2185 | +MATCHER_P (MatchArray3, v, "Contains values") |
2186 | +{ |
2187 | + return arg[0] == v[0] && |
2188 | + arg[1] == v[1] && |
2189 | + arg[2] == v[2]; |
2190 | +} |
2191 | + |
2192 | +TEST_F (DecorProtocolCommunicator, TestDispatchToPendingHandler) |
2193 | +{ |
2194 | + long data[3]; |
2195 | + |
2196 | + data[0] = 1; |
2197 | + data[1] = 2; |
2198 | + data[2] = 3; |
2199 | + |
2200 | + XClientMessageEvent ev; |
2201 | + ClientMessageData (ev, |
2202 | + mockWindow, |
2203 | + pendingMsg, |
2204 | + data[0], |
2205 | + data[1], |
2206 | + data[2], |
2207 | + 0); |
2208 | + |
2209 | + EXPECT_CALL (mockProtoDispatch, handlePending (mockWindow, |
2210 | + MatchArray3 (data))) |
2211 | + .Times (1); |
2212 | + |
2213 | + protocolCommunicator.handleClientMessage (ev); |
2214 | +} |
2215 | + |
2216 | +TEST_F (DecorProtocolCommunicator, TestDispatchToUnusedHandler) |
2217 | +{ |
2218 | + XClientMessageEvent ev; |
2219 | + ClientMessageData (ev, |
2220 | + mockWindow, |
2221 | + unusedMsg, |
2222 | + mockPixmap, |
2223 | + 0, |
2224 | + 0, |
2225 | + 0); |
2226 | + |
2227 | + EXPECT_CALL (mockProtoDispatch, handleUnused (mockWindow, |
2228 | + mockPixmap)) |
2229 | + .Times (1); |
2230 | + |
2231 | + protocolCommunicator.handleClientMessage (ev); |
2232 | +} |
2233 | |
2234 | === modified file 'tests/system/xorg-gtest/tests/CMakeLists.txt' |
2235 | --- tests/system/xorg-gtest/tests/CMakeLists.txt 2013-02-19 12:00:19 +0000 |
2236 | +++ tests/system/xorg-gtest/tests/CMakeLists.txt 2013-02-20 07:34:20 +0000 |
2237 | @@ -52,6 +52,6 @@ |
2238 | target_link_libraries (compiz_xorg_gtest_test_shape_handling |
2239 | ${COMPIZ_XORG_GTEST_LIBRARIES}) |
2240 | |
2241 | - compiz_discover_tests (compiz_xorg_gtest_test_shape_handling) |
2242 | + compiz_discover_tests (compiz_xorg_gtest_test_shape_handling WITH_XORG_GTEST) |
2243 | |
2244 | endif (BUILD_XORG_GTEST AND X11_XI_FOUND) |
FAILED: Continuous integration, rev:3624 jenkins. qa.ubuntu. com/job/ compiz- ci/5/ jenkins. qa.ubuntu. com/job/ compiz- clang-ci/ ./build= pbuilder, distribution= quantal, flavor= amd64/43/ console jenkins. qa.ubuntu. com/job/ compiz- gles-ci/ ./build= pbuilder, distribution= quantal, flavor= amd64/42/ console jenkins. qa.ubuntu. com/job/ compiz- pbuilder/ ./build= pbuilder, distribution= quantal, flavor= amd64/394/ console
http://
Executed test runs:
None: http://
None: http://
None: http://
Click here to trigger a rebuild: jenkins. qa.ubuntu. com/job/ compiz- ci/5//rebuild/?
http://