Merge lp:~compiz-team/compiz/compiz.fix_1119608 into lp:compiz/0.9.9

Proposed by Sam Spilsbury
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
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)

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal
review: Needs Fixing (continuous-integration)
Revision history for this message
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.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal
review: Approve (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal
review: Needs Fixing (continuous-integration)
Revision history for this message
Brandon Schaefer (brandontschaefer) wrote : Posted in a previous version of this proposal

Overall looks good, a few things:

Some warning when compiling:
http://paste.ubuntu.com/1683356/

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_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, default_frames[i].d->height, frame->style_window_rgba);

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/noncopyable.hpp>

I don't see you inherit from this noncopyable class, do we need this header?

695 + int destroyUnusedPixmap (Pixmap pixmap) { return decor_post_delete_pixmap (mDisplay,
696 + 0,
697 + pixmap); }

Just needs little bit of lining up of the params :).

review: Needs Fixing
Revision history for this message
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://paste.ubuntu.com/1683356/

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_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, default_frames[i].d->height,
> frame->style_window_rgba);
>
> 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/noncopyable.hpp>
>
> 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_delete_pixmap (mDisplay,
> 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.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
3628. By Sam Spilsbury

Add xorg-gtest env

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
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.

review: Approve
Revision history for this message
Brandon Schaefer (brandontschaefer) wrote :

opps wrong MP, looks like CI did its job :)

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'gtk/window-decorator/cairo.c'
--- gtk/window-decorator/cairo.c 2012-09-18 11:32:20 +0000
+++ gtk/window-decorator/cairo.c 2013-02-20 07:34:20 +0000
@@ -317,19 +317,10 @@
317 color.g = style->bg[GTK_STATE_NORMAL].green / 65535.0;317 color.g = style->bg[GTK_STATE_NORMAL].green / 65535.0;
318 color.b = style->bg[GTK_STATE_NORMAL].blue / 65535.0;318 color.b = style->bg[GTK_STATE_NORMAL].blue / 65535.0;
319319
320 if (d->frame_window)320 if (d->buffer_pixmap)
321 {321 drawable = d->buffer_pixmap;
322 GdkColormap *cmap;
323
324 cmap = get_colormap_for_drawable (GDK_DRAWABLE (d->pixmap));
325 gdk_drawable_set_colormap (GDK_DRAWABLE (d->pixmap), cmap);
326 gdk_drawable_set_colormap (GDK_DRAWABLE (d->buffer_pixmap), cmap);
327 drawable = GDK_DRAWABLE (d->buffer_pixmap);
328 }
329 else if (d->buffer_pixmap)
330 drawable = GDK_DRAWABLE (d->buffer_pixmap);
331 else322 else
332 drawable = GDK_DRAWABLE (d->pixmap);323 drawable = d->pixmap;
333324
334 cr = gdk_cairo_create (GDK_DRAWABLE (drawable));325 cr = gdk_cairo_create (GDK_DRAWABLE (drawable));
335 if (!cr)326 if (!cr)
336327
=== modified file 'gtk/window-decorator/decorator.c'
--- gtk/window-decorator/decorator.c 2012-11-20 08:11:44 +0000
+++ gtk/window-decorator/decorator.c 2013-02-20 07:34:20 +0000
@@ -649,9 +649,9 @@
649 /* Get the correct depth for the frame window in reparenting mode, otherwise649 /* Get the correct depth for the frame window in reparenting mode, otherwise
650 * enforce 32 */650 * enforce 32 */
651 if (d->frame_window)651 if (d->frame_window)
652 pixmap = create_pixmap (d->width, d->height, d->frame->style_window_rgb);652 pixmap = create_native_pixmap_and_wrap (d->width, d->height, d->frame->style_window_rgb);
653 else653 else
654 pixmap = create_pixmap (d->width, d->height, d->frame->style_window_rgba);654 pixmap = create_native_pixmap_and_wrap (d->width, d->height, d->frame->style_window_rgba);
655655
656 gdk_flush ();656 gdk_flush ();
657657
@@ -686,16 +686,12 @@
686686
687 /* Destroy the old pixmaps and pictures */687 /* Destroy the old pixmaps and pictures */
688 if (d->pixmap)688 if (d->pixmap)
689 {689 g_object_unref (d->pixmap);
690 gpointer key = GINT_TO_POINTER (GDK_PIXMAP_XID (d->pixmap));690
691691 if (d->x11Pixmap)
692 if (d->old_pixmaps == NULL)692 decor_post_delete_pixmap (xdisplay,
693 d->old_pixmaps = g_hash_table_new_full (NULL, NULL, NULL,693 wnck_window_get_xid (d->win),
694 g_object_unref);694 d->x11Pixmap);
695
696 g_hash_table_insert (destroyed_pixmaps_table, key, d);
697 g_hash_table_insert (d->old_pixmaps, key, d->pixmap);
698 }
699695
700 if (d->buffer_pixmap)696 if (d->buffer_pixmap)
701 g_object_unref (G_OBJECT (d->buffer_pixmap));697 g_object_unref (G_OBJECT (d->buffer_pixmap));
@@ -708,6 +704,7 @@
708704
709 /* Assign new pixmaps and pictures */705 /* Assign new pixmaps and pictures */
710 d->pixmap = pixmap;706 d->pixmap = pixmap;
707 d->x11Pixmap = GDK_PIXMAP_XID (d->pixmap);
711 d->buffer_pixmap = buffer_pixmap;708 d->buffer_pixmap = buffer_pixmap;
712 d->cr = gdk_cairo_create (pixmap);709 d->cr = gdk_cairo_create (pixmap);
713710
@@ -1435,7 +1432,9 @@
1435 extents.top += frame->titlebar_height;1432 extents.top += frame->titlebar_height;
14361433
1437 default_frames[i].d->draw = theme_draw_window_decoration;1434 default_frames[i].d->draw = theme_draw_window_decoration;
1438 default_frames[i].d->pixmap = create_pixmap (default_frames[i].d->width, default_frames[i].d->height, frame->style_window_rgba);1435 default_frames[i].d->pixmap = create_native_pixmap_and_wrap (default_frames[i].d->width,
1436 default_frames[i].d->height,
1437 frame->style_window_rgba);
14391438
1440 unsigned int j, k;1439 unsigned int j, k;
14411440
14421441
=== modified file 'gtk/window-decorator/events.c'
--- gtk/window-decorator/events.c 2012-10-06 16:11:05 +0000
+++ gtk/window-decorator/events.c 2013-02-20 07:34:20 +0000
@@ -1093,17 +1093,6 @@
1093 if (win)1093 if (win)
1094 update_window_decoration_size (win);1094 update_window_decoration_size (win);
1095 }1095 }
1096 else if (xevent->xclient.message_type == decor_delete_pixmap_atom)
1097 {
1098 gconstpointer key = GINT_TO_POINTER (xevent->xclient.data.l[0]);
1099 decor_t *d = g_hash_table_lookup (destroyed_pixmaps_table, key);
1100
1101 if (d != NULL)
1102 {
1103 g_hash_table_remove (d->old_pixmaps, key);
1104 g_hash_table_remove (destroyed_pixmaps_table, key);
1105 }
1106 }
1107 default:1096 default:
1108 break;1097 break;
1109 }1098 }
11101099
=== modified file 'gtk/window-decorator/gdk.c'
--- gtk/window-decorator/gdk.c 2012-05-27 04:32:55 +0000
+++ gtk/window-decorator/gdk.c 2013-02-20 07:34:20 +0000
@@ -92,6 +92,26 @@
92}92}
9393
94GdkPixmap *94GdkPixmap *
95create_native_pixmap_and_wrap (int w,
96 int h,
97 GtkWidget *parent_style_window)
98{
99 GdkWindow *window;
100
101 if (w <= 0 || h <= 0)
102 abort ();
103
104 window = gtk_widget_get_window (parent_style_window);
105 GdkPixmap *pixmap =
106 gdk_pixmap_foreign_new (XCreatePixmap (gdk_x11_display_get_xdisplay (gdk_display_get_default ()),
107 GDK_WINDOW_XID (window), w, h,
108 gdk_drawable_get_depth (window)));
109 GdkColormap *cmap = get_colormap_for_drawable (GDK_DRAWABLE (pixmap));
110 gdk_drawable_set_colormap (GDK_DRAWABLE (pixmap), cmap);
111 return pixmap;
112}
113
114GdkPixmap *
95create_pixmap (int w,115create_pixmap (int w,
96 int h,116 int h,
97 GtkWidget *parent_style_window)117 GtkWidget *parent_style_window)
@@ -102,5 +122,9 @@
102 abort ();122 abort ();
103123
104 window = gtk_widget_get_window (parent_style_window);124 window = gtk_widget_get_window (parent_style_window);
105 return gdk_pixmap_new (GDK_DRAWABLE (window), w, h, -1 /* CopyFromParent */);125 GdkPixmap *pixmap = gdk_pixmap_new (GDK_DRAWABLE (window), w, h, -1 /* CopyFromParent */);
126
127 GdkColormap *cmap = get_colormap_for_drawable (GDK_DRAWABLE (pixmap));
128 gdk_drawable_set_colormap (GDK_DRAWABLE (pixmap), cmap);
129 return pixmap;
106}130}
107131
=== modified file 'gtk/window-decorator/gtk-window-decorator.c'
--- gtk/window-decorator/gtk-window-decorator.c 2012-10-06 16:11:05 +0000
+++ gtk/window-decorator/gtk-window-decorator.c 2013-02-20 07:34:20 +0000
@@ -136,7 +136,6 @@
136GtkWidget *switcher_label;136GtkWidget *switcher_label;
137137
138GHashTable *frame_table;138GHashTable *frame_table;
139GHashTable *destroyed_pixmaps_table;
140GtkWidget *action_menu = NULL;139GtkWidget *action_menu = NULL;
141gboolean action_menu_mapped = FALSE;140gboolean action_menu_mapped = FALSE;
142decor_color_t _title_color[2];141decor_color_t _title_color[2];
@@ -267,9 +266,9 @@
267 net_wm_state_atom = XInternAtom (xdisplay,"_NET_WM_STATE", 0);266 net_wm_state_atom = XInternAtom (xdisplay,"_NET_WM_STATE", 0);
268 net_wm_state_modal_atom = XInternAtom (xdisplay, "_NET_WM_STATE_MODAL", 0);267 net_wm_state_modal_atom = XInternAtom (xdisplay, "_NET_WM_STATE_MODAL", 0);
269268
270 decor_request_atom = XInternAtom (xdisplay, "_COMPIZ_DECOR_REQUEST", 0);269 decor_request_atom = XInternAtom (xdisplay, DECOR_REQUEST_PIXMAP_ATOM_NAME, 0);
271 decor_pending_atom = XInternAtom (xdisplay, "_COMPIZ_DECOR_PENDING", 0);270 decor_pending_atom = XInternAtom (xdisplay, DECOR_PIXMAP_PENDING_ATOM_NAME, 0);
272 decor_delete_pixmap_atom = XInternAtom (xdisplay, "_COMPIZ_DECOR_DELETE_PIXMAP", 0);271 decor_delete_pixmap_atom = XInternAtom (xdisplay, DECOR_DELETE_PIXMAP_ATOM_NAME, 0);
273272
274 status = decor_acquire_dm_session (xdisplay,273 status = decor_acquire_dm_session (xdisplay,
275 gdk_screen_get_number (gdkscreen),274 gdk_screen_get_number (gdkscreen),
@@ -343,7 +342,6 @@
343 xformat_rgb = XRenderFindStandardFormat (xdisplay, PictStandardRGB24);342 xformat_rgb = XRenderFindStandardFormat (xdisplay, PictStandardRGB24);
344343
345 frame_table = g_hash_table_new (NULL, NULL);344 frame_table = g_hash_table_new (NULL, NULL);
346 destroyed_pixmaps_table = g_hash_table_new (NULL, NULL);
347345
348 if (!create_tooltip_window ())346 if (!create_tooltip_window ())
349 {347 {
350348
=== modified file 'gtk/window-decorator/gtk-window-decorator.h'
--- gtk/window-decorator/gtk-window-decorator.h 2012-10-06 16:11:05 +0000
+++ gtk/window-decorator/gtk-window-decorator.h 2013-02-20 07:34:20 +0000
@@ -392,13 +392,13 @@
392 event_window button_windows[BUTTON_NUM];392 event_window button_windows[BUTTON_NUM];
393 Box *last_pos_entered;393 Box *last_pos_entered;
394 guint button_states[BUTTON_NUM];394 guint button_states[BUTTON_NUM];
395 Pixmap x11Pixmap;
395 GdkPixmap *pixmap;396 GdkPixmap *pixmap;
396 GdkPixmap *buffer_pixmap;397 GdkPixmap *buffer_pixmap;
397 GdkWindow *frame_window;398 GdkWindow *frame_window;
398 GtkWidget *decor_window;399 GtkWidget *decor_window;
399 GtkWidget *decor_event_box;400 GtkWidget *decor_event_box;
400 GtkWidget *decor_image;401 GtkWidget *decor_image;
401 GHashTable *old_pixmaps;
402 cairo_t *cr;402 cairo_t *cr;
403 decor_layout_t border_layout;403 decor_layout_t border_layout;
404 decor_context_t *context;404 decor_context_t *context;
@@ -470,7 +470,6 @@
470470
471/* list of all decorations */471/* list of all decorations */
472extern GHashTable *frame_table;472extern GHashTable *frame_table;
473extern GHashTable *destroyed_pixmaps_table;
474473
475/* action menu */474/* action menu */
476extern GtkWidget *action_menu;475extern GtkWidget *action_menu;
@@ -801,6 +800,11 @@
801 GtkWidget *parent_style_window);800 GtkWidget *parent_style_window);
802801
803GdkPixmap *802GdkPixmap *
803create_native_pixmap_and_wrap (int w,
804 int h,
805 GtkWidget *parent_style_window);
806
807GdkPixmap *
804pixmap_new_from_pixbuf (GdkPixbuf *pixbuf, GtkWidget *parent);808pixmap_new_from_pixbuf (GdkPixbuf *pixbuf, GtkWidget *parent);
805809
806/* metacity.c */810/* metacity.c */
807811
=== modified file 'gtk/window-decorator/metacity.c'
--- gtk/window-decorator/metacity.c 2012-09-10 12:59:17 +0000
+++ gtk/window-decorator/metacity.c 2013-02-20 07:34:20 +0000
@@ -616,15 +616,6 @@
616 if (!d->pixmap || !d->picture)616 if (!d->pixmap || !d->picture)
617 return;617 return;
618618
619 if (d->frame_window)
620 {
621 GdkColormap *cmap;
622
623 cmap = get_colormap_for_drawable (GDK_DRAWABLE (d->pixmap));
624 gdk_drawable_set_colormap (GDK_DRAWABLE (d->pixmap), cmap);
625 gdk_drawable_set_colormap (GDK_DRAWABLE (d->buffer_pixmap), cmap);
626 }
627
628 if (decoration_alpha == 1.0)619 if (decoration_alpha == 1.0)
629 alpha = 1.0;620 alpha = 1.0;
630621
@@ -692,13 +683,7 @@
692 XRenderPictFormat *format;683 XRenderPictFormat *format;
693684
694 if (d->frame_window)685 if (d->frame_window)
695 {
696 GdkColormap *cmap;
697
698 cmap = get_colormap_for_drawable (GDK_DRAWABLE (d->pixmap));
699 pixmap = create_pixmap (rect.width, size, d->frame->style_window_rgb);686 pixmap = create_pixmap (rect.width, size, d->frame->style_window_rgb);
700 gdk_drawable_set_colormap (GDK_DRAWABLE (pixmap), cmap);
701 }
702 else687 else
703 pixmap = create_pixmap (rect.width, size, d->frame->style_window_rgba);688 pixmap = create_pixmap (rect.width, size, d->frame->style_window_rgba);
704689
705690
=== modified file 'gtk/window-decorator/switcher.c'
--- gtk/window-decorator/switcher.c 2011-10-13 12:07:34 +0000
+++ gtk/window-decorator/switcher.c 2013-02-20 07:34:20 +0000
@@ -472,7 +472,7 @@
472 switcher_selected_window = selected;472 switcher_selected_window = selected;
473 }473 }
474474
475 pixmap = create_pixmap (width, height, d->frame->style_window_rgba);475 pixmap = create_native_pixmap_and_wrap (width, height, d->frame->style_window_rgba);
476 if (!pixmap)476 if (!pixmap)
477 return FALSE;477 return FALSE;
478478
@@ -486,6 +486,11 @@
486 if (d->pixmap)486 if (d->pixmap)
487 g_object_unref (G_OBJECT (d->pixmap));487 g_object_unref (G_OBJECT (d->pixmap));
488488
489 if (d->x11Pixmap)
490 decor_post_delete_pixmap (xdisplay,
491 wnck_window_get_xid (d->win),
492 d->x11Pixmap);
493
489 if (d->buffer_pixmap)494 if (d->buffer_pixmap)
490 g_object_unref (G_OBJECT (d->buffer_pixmap));495 g_object_unref (G_OBJECT (d->buffer_pixmap));
491496
@@ -496,6 +501,7 @@
496 XRenderFreePicture (xdisplay, d->picture);501 XRenderFreePicture (xdisplay, d->picture);
497502
498 d->pixmap = pixmap;503 d->pixmap = pixmap;
504 d->x11Pixmap = GDK_PIXMAP_XID (d->pixmap);
499 d->buffer_pixmap = buffer_pixmap;505 d->buffer_pixmap = buffer_pixmap;
500 d->cr = gdk_cairo_create (pixmap);506 d->cr = gdk_cairo_create (pixmap);
501507
502508
=== modified file 'gtk/window-decorator/wnck.c'
--- gtk/window-decorator/wnck.c 2012-11-05 20:50:59 +0000
+++ gtk/window-decorator/wnck.c 2013-02-20 07:34:20 +0000
@@ -455,22 +455,12 @@
455 d->created = TRUE;455 d->created = TRUE;
456}456}
457457
458gboolean
459clean_destroyed_pixmaps (gpointer key, gpointer value, gpointer d)
460{
461 return value == d;
462}
463
464void458void
465remove_frame_window (WnckWindow *win)459remove_frame_window (WnckWindow *win)
466{460{
467 decor_t *d = g_object_get_data (G_OBJECT (win), "decor");461 decor_t *d = g_object_get_data (G_OBJECT (win), "decor");
468 Display *xdisplay;462 Display *xdisplay;
469463
470 g_hash_table_foreach_remove (destroyed_pixmaps_table,
471 clean_destroyed_pixmaps,
472 d);
473
474 xdisplay = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ());464 xdisplay = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ());
475465
476 if (!d->frame_window)466 if (!d->frame_window)
@@ -507,12 +497,6 @@
507 d->buffer_pixmap = NULL;497 d->buffer_pixmap = NULL;
508 }498 }
509499
510 if (d->old_pixmaps)
511 {
512 g_hash_table_destroy (d->old_pixmaps);
513 d->old_pixmaps = NULL;
514 }
515
516 if (d->cr)500 if (d->cr)
517 {501 {
518 cairo_destroy (d->cr);502 cairo_destroy (d->cr);
519503
=== modified file 'include/decoration.h'
--- include/decoration.h 2012-09-05 14:25:35 +0000
+++ include/decoration.h 2013-02-20 07:34:20 +0000
@@ -50,6 +50,10 @@
50#define DECOR_TYPE_PIXMAP_ATOM_NAME "_COMPIZ_WINDOW_DECOR_TYPE_PIXMAP"50#define DECOR_TYPE_PIXMAP_ATOM_NAME "_COMPIZ_WINDOW_DECOR_TYPE_PIXMAP"
51#define DECOR_TYPE_WINDOW_ATOM_NAME "_COMPIZ_WINDOW_DECOR_TYPE_WINDOW"51#define DECOR_TYPE_WINDOW_ATOM_NAME "_COMPIZ_WINDOW_DECOR_TYPE_WINDOW"
5252
53#define DECOR_REQUEST_PIXMAP_ATOM_NAME "_COMPIZ_DECOR_REQUEST"
54#define DECOR_PIXMAP_PENDING_ATOM_NAME "_COMPIZ_DECOR_PENDING"
55#define DECOR_DELETE_PIXMAP_ATOM_NAME "_COMPIZ_DECOR_DELETE_PIXMAP"
56
53#define WINDOW_DECORATION_TYPE_PIXMAP (1 << 0)57#define WINDOW_DECORATION_TYPE_PIXMAP (1 << 0)
54#define WINDOW_DECORATION_TYPE_WINDOW (1 << 1)58#define WINDOW_DECORATION_TYPE_WINDOW (1 << 1)
5559
@@ -495,12 +499,13 @@
495int499int
496decor_post_pending (Display *xdisplay,500decor_post_pending (Display *xdisplay,
497 Window client,501 Window client,
502 unsigned int frame_type,
498 unsigned int frame_state,503 unsigned int frame_state,
499 unsigned int frame_type,
500 unsigned int frame_actions);504 unsigned int frame_actions);
501505
502int506int
503decor_post_delete_pixmap (Display *xdisplay,507decor_post_delete_pixmap (Display *xdisplay,
508 Window window,
504 Pixmap pixmap);509 Pixmap pixmap);
505510
506int511int
507512
=== modified file 'libdecoration/decoration.c'
--- libdecoration/decoration.c 2013-01-28 20:52:39 +0000
+++ libdecoration/decoration.c 2013-02-20 07:34:20 +0000
@@ -2890,13 +2890,13 @@
2890int2890int
2891decor_post_pending (Display *xdisplay,2891decor_post_pending (Display *xdisplay,
2892 Window client,2892 Window client,
2893 unsigned int frame_type,
2893 unsigned int frame_state,2894 unsigned int frame_state,
2894 unsigned int frame_type,
2895 unsigned int frame_actions)2895 unsigned int frame_actions)
2896{2896{
2897 XEvent event;2897 XEvent event;
28982898
2899 Atom decor_pending = XInternAtom (xdisplay, "_COMPIZ_DECOR_PENDING", FALSE);2899 Atom decor_pending = XInternAtom (xdisplay, DECOR_PIXMAP_PENDING_ATOM_NAME, FALSE);
29002900
2901 /* Send a client message indicating that a new2901 /* Send a client message indicating that a new
2902 * decoration can be generated for this window2902 * decoration can be generated for this window
@@ -2926,7 +2926,7 @@
2926{2926{
2927 XEvent event;2927 XEvent event;
29282928
2929 Atom decor_request = XInternAtom (xdisplay, "_COMPIZ_DECOR_REQUEST", FALSE);2929 Atom decor_request = XInternAtom (xdisplay, DECOR_REQUEST_PIXMAP_ATOM_NAME, FALSE);
29302930
2931 /* Send a client message indicating that a new2931 /* Send a client message indicating that a new
2932 * decoration can be generated for this window2932 * decoration can be generated for this window
@@ -2949,17 +2949,18 @@
29492949
2950int2950int
2951decor_post_delete_pixmap (Display *xdisplay,2951decor_post_delete_pixmap (Display *xdisplay,
2952 Window window,
2952 Pixmap pixmap)2953 Pixmap pixmap)
2953{2954{
2954 XEvent event;2955 XEvent event;
29552956
2956 Atom decor_delete_pixmap = XInternAtom (xdisplay, "_COMPIZ_DECOR_DELETE_PIXMAP", FALSE);2957 Atom decor_delete_pixmap = XInternAtom (xdisplay, DECOR_DELETE_PIXMAP_ATOM_NAME, FALSE);
29572958
2958 /* Send a client message indicating that a new2959 /* Send a client message indicating that this
2959 * decoration can be generated for this window2960 * pixmap is no longer in use and can be removed
2960 */2961 */
2961 event.xclient.type = ClientMessage;2962 event.xclient.type = ClientMessage;
2962 event.xclient.window = DefaultRootWindow (xdisplay);2963 event.xclient.window = window;
2963 event.xclient.message_type = decor_delete_pixmap;2964 event.xclient.message_type = decor_delete_pixmap;
2964 event.xclient.format = 32;2965 event.xclient.format = 32;
2965 event.xclient.data.l[0] = pixmap;2966 event.xclient.data.l[0] = pixmap;
@@ -2973,6 +2974,7 @@
29732974
2974 return 1;2975 return 1;
2975}2976}
2977
2976int2978int
2977decor_acquire_dm_session (Display *xdisplay,2979decor_acquire_dm_session (Display *xdisplay,
2978 int screen,2980 int screen,
29792981
=== modified file 'plugins/decor/src/decor.cpp'
--- plugins/decor/src/decor.cpp 2013-02-19 20:38:17 +0000
+++ plugins/decor/src/decor.cpp 2013-02-20 07:34:20 +0000
@@ -391,8 +391,7 @@
391 return t;391 return t;
392 }392 }
393393
394 X11PixmapDeletor::Ptr dl = boost::make_shared <X11PixmapDeletor> (screen->dpy ());394 DecorPixmap::Ptr pm = boost::make_shared <DecorPixmap> (pixmap, mReleasePool);
395 DecorPixmap::Ptr pm = boost::make_shared <DecorPixmap> (pixmap, dl);
396395
397 DecorTexture *texture = new DecorTexture (boost::shared_static_cast <DecorPixmapInterface> (pm));396 DecorTexture *texture = new DecorTexture (boost::shared_static_cast <DecorPixmapInterface> (pm));
398397
@@ -1285,7 +1284,7 @@
1285DecorationInterface::Ptr1284DecorationInterface::Ptr
1286DecorationList::findMatchingDecoration (unsigned int frameType,1285DecorationList::findMatchingDecoration (unsigned int frameType,
1287 unsigned int frameState,1286 unsigned int frameState,
1288 unsigned int frameActions)1287 unsigned int frameActions) const
1289{1288{
1290 foreach (const Decoration::Ptr &d, mList)1289 foreach (const Decoration::Ptr &d, mList)
1291 {1290 {
@@ -1298,6 +1297,18 @@
1298 return DecorationInterface::Ptr ();1297 return DecorationInterface::Ptr ();
1299}1298}
13001299
1300DecorationInterface::Ptr
1301DecorationList::findMatchingDecoration (Pixmap p) const
1302{
1303 foreach (const Decoration::Ptr &d, mList)
1304 {
1305 if (d->texture->pixmap->getPixmap () == p)
1306 return d;
1307 }
1308
1309 return DecorationInterface::Ptr ();
1310}
1311
1301/*1312/*
1302 * DecorationList::findMatchingDecoration1313 * DecorationList::findMatchingDecoration
1303 *1314 *
@@ -2334,6 +2345,42 @@
2334 isSwitcher = false;2345 isSwitcher = false;
2335}2346}
23362347
2348DecorPixmapRequestorInterface *
2349DecorScreen::findWindowRequestor (Window window)
2350{
2351 if (window == screen->root ())
2352 {
2353 return &mRequestor;
2354 }
2355 else
2356 {
2357 CompWindow *w = screen->findWindow (window);
2358
2359 if (w)
2360 return &(DecorWindow::get (w)->mRequestor);
2361
2362 return NULL;
2363 }
2364}
2365
2366DecorationListFindMatchingInterface *
2367DecorScreen::findWindowDecorations (Window window)
2368{
2369 if (window == screen->root ())
2370 {
2371 return &decor[DECOR_ACTIVE];
2372 }
2373 else
2374 {
2375 CompWindow *w = screen->findWindow (window);
2376
2377 if (w)
2378 return &(DecorWindow::get (w)->decor);
2379
2380 return NULL;
2381 }
2382}
2383
23372384
2338/*2385/*
2339 * DecorScreen::handleEvent2386 * DecorScreen::handleEvent
@@ -2376,18 +2423,8 @@
2376 dw->update (true);2423 dw->update (true);
2377 }2424 }
2378 }2425 }
2379 /* A decoration is pending creation, allow it to be created */2426
2380 if (event->xclient.message_type == decorPendingAtom)2427 mCommunicator.handleClientMessage (event->xclient);
2381 {
2382 CompWindow *w = screen->findWindow (event->xclient.window);
2383
2384 if (w)
2385 {
2386 DecorWindow *dw = DecorWindow::get (w);
2387
2388 dw->mRequestor.handlePending (event->xclient.data.l);
2389 }
2390 }
2391 break;2428 break;
2392 default:2429 default:
2393 /* Check for damage events. If the output or input window2430 /* Check for damage events. If the output or input window
@@ -3010,7 +3047,31 @@
3010 screen->root (),3047 screen->root (),
3011 NULL)),3048 NULL)),
3012 mMenusClipGroup (CompMatch ("type=Dock | type=DropdownMenu | type=PopupMenu")),3049 mMenusClipGroup (CompMatch ("type=Dock | type=DropdownMenu | type=PopupMenu")),
3013 mRequestor (screen->dpy (), screen->root (), &(decor[DECOR_ACTIVE]))3050 mRequestor (screen->dpy (), screen->root (), &(decor[DECOR_ACTIVE])),
3051 mReleasePool (new PixmapReleasePool (
3052 boost::bind (XFreePixmap,
3053 screen->dpy (),
3054 _1))),
3055 mPendingHandler (boost::bind (&DecorScreen::findWindowRequestor,
3056 this,
3057 _1)),
3058 mUnusedHandler (boost::bind (&DecorScreen::findWindowDecorations,
3059 this,
3060 _1),
3061 mReleasePool,
3062 boost::bind (XFreePixmap,
3063 screen->dpy (),
3064 _1)),
3065 mCommunicator (XInternAtom (screen->dpy (), DECOR_PIXMAP_PENDING_ATOM_NAME, FALSE),
3066 XInternAtom (screen->dpy (), DECOR_DELETE_PIXMAP_ATOM_NAME, FALSE),
3067 boost::bind (&PendingHandler::handleMessage,
3068 &mPendingHandler,
3069 _1,
3070 _2),
3071 boost::bind (&UnusedHandler::handleMessage,
3072 &mUnusedHandler,
3073 _1,
3074 _2))
3014{3075{
3015 supportingDmCheckAtom =3076 supportingDmCheckAtom =
3016 XInternAtom (s->dpy (), DECOR_SUPPORTING_DM_CHECK_ATOM_NAME, 0);3077 XInternAtom (s->dpy (), DECOR_SUPPORTING_DM_CHECK_ATOM_NAME, 0);
@@ -3033,9 +3094,9 @@
3033 decorSwitchWindowAtom =3094 decorSwitchWindowAtom =
3034 XInternAtom (s->dpy (), DECOR_SWITCH_WINDOW_ATOM_NAME, 0);3095 XInternAtom (s->dpy (), DECOR_SWITCH_WINDOW_ATOM_NAME, 0);
3035 decorPendingAtom =3096 decorPendingAtom =
3036 XInternAtom (s->dpy (), "_COMPIZ_DECOR_PENDING", 0);3097 XInternAtom (s->dpy (), DECOR_PIXMAP_PENDING_ATOM_NAME, 0);
3037 decorRequestAtom =3098 decorRequestAtom =
3038 XInternAtom (s->dpy (), "_COMPIZ_DECOR_REQUEST", 0);3099 XInternAtom (s->dpy (), DECOR_REQUEST_PIXMAP_ATOM_NAME, 0);
3039 requestFrameExtentsAtom =3100 requestFrameExtentsAtom =
3040 XInternAtom (s->dpy (), "_NET_REQUEST_FRAME_EXTENTS", 0);3101 XInternAtom (s->dpy (), "_NET_REQUEST_FRAME_EXTENTS", 0);
3041 shadowColorAtom =3102 shadowColorAtom =
30423103
=== modified file 'plugins/decor/src/decor.h'
--- plugins/decor/src/decor.h 2012-09-07 22:37:20 +0000
+++ plugins/decor/src/decor.h 2013-02-20 07:34:20 +0000
@@ -159,9 +159,10 @@
159{159{
160 public:160 public:
161 bool updateDecoration (Window id, Atom decorAtom, DecorPixmapRequestorInterface *requestor);161 bool updateDecoration (Window id, Atom decorAtom, DecorPixmapRequestorInterface *requestor);
162 DecorationInterface::Ptr findMatchingDecoration(unsigned int frameType,162 DecorationInterface::Ptr findMatchingDecoration (unsigned int frameType,
163 unsigned int frameState,163 unsigned int frameState,
164 unsigned int frameActions);164 unsigned int frameActions) const;
165 DecorationInterface::Ptr findMatchingDecoration (Pixmap p) const;
165 const Decoration::Ptr & findMatchingDecoration (CompWindow *w, bool sizeCheck);166 const Decoration::Ptr & findMatchingDecoration (CompWindow *w, bool sizeCheck);
166 void clear ()167 void clear ()
167 {168 {
@@ -220,6 +221,11 @@
220 bool registerPaintHandler (compiz::composite::PaintHandler *pHnd);221 bool registerPaintHandler (compiz::composite::PaintHandler *pHnd);
221 void unregisterPaintHandler ();222 void unregisterPaintHandler ();
222223
224 private:
225
226 DecorPixmapRequestorInterface * findWindowRequestor (Window);
227 DecorationListFindMatchingInterface * findWindowDecorations (Window);
228
223 public:229 public:
224230
225 CompositeScreen *cScreen;231 CompositeScreen *cScreen;
@@ -255,6 +261,10 @@
255261
256 MatchedDecorClipGroup mMenusClipGroup;262 MatchedDecorClipGroup mMenusClipGroup;
257 X11DecorPixmapRequestor mRequestor;263 X11DecorPixmapRequestor mRequestor;
264 PixmapReleasePool::Ptr mReleasePool;
265 PendingHandler mPendingHandler;
266 UnusedHandler mUnusedHandler;
267 protocol::Communicator mCommunicator;
258};268};
259269
260class DecorWindow :270class DecorWindow :
261271
=== modified file 'plugins/decor/src/pixmap-requests/include/pixmap-requests.h'
--- plugins/decor/src/pixmap-requests/include/pixmap-requests.h 2012-05-10 15:40:25 +0000
+++ plugins/decor/src/pixmap-requests/include/pixmap-requests.h 2013-02-20 07:34:20 +0000
@@ -26,14 +26,19 @@
26#ifndef _COMPIZ_DECOR_PIXMAP_REQUESTS_H26#ifndef _COMPIZ_DECOR_PIXMAP_REQUESTS_H
27#define _COMPIZ_DECOR_PIXMAP_REQUESTS_H27#define _COMPIZ_DECOR_PIXMAP_REQUESTS_H
2828
29#include <list>
30
29#include <boost/shared_ptr.hpp>31#include <boost/shared_ptr.hpp>
30#include <boost/shared_array.hpp>32#include <boost/shared_array.hpp>
31#include <boost/make_shared.hpp>33#include <boost/make_shared.hpp>
34#include <boost/noncopyable.hpp>
35#include <boost/function.hpp>
32#include <decoration.h>36#include <decoration.h>
3337
34#include <X11/Xlib.h>38#include <X11/Xlib.h>
3539
36class DecorPixmapInterface40class DecorPixmapInterface :
41 boost::noncopyable
37{42{
38 public:43 public:
3944
@@ -44,7 +49,8 @@
44 virtual Pixmap getPixmap () = 0;49 virtual Pixmap getPixmap () = 0;
45};50};
4651
47class DecorPixmapReceiverInterface52class DecorPixmapReceiverInterface :
53 boost::noncopyable
48{54{
49 public:55 public:
5056
@@ -57,7 +63,8 @@
57/* So far, nothing particularly interesting here63/* So far, nothing particularly interesting here
58 * we just need a way to pass around pointers for64 * we just need a way to pass around pointers for
59 * testing */65 * testing */
60class DecorationInterface66class DecorationInterface :
67 boost::noncopyable
61{68{
62 public:69 public:
6370
@@ -71,34 +78,50 @@
71 virtual unsigned int getFrameActions () const = 0;78 virtual unsigned int getFrameActions () const = 0;
72};79};
7380
74class DecorPixmapDeletionInterface81class PixmapDestroyQueue :
75{82 boost::noncopyable
76 public:83{
7784 public:
78 typedef boost::shared_ptr <DecorPixmapDeletionInterface> Ptr;85
7986 typedef boost::shared_ptr <PixmapDestroyQueue> Ptr;
80 virtual ~DecorPixmapDeletionInterface () {}87
8188 virtual ~PixmapDestroyQueue () {}
82 virtual int postDeletePixmap (Pixmap pixmap) = 0;89
83};90 virtual int destroyUnusedPixmap (Pixmap pixmap) = 0;
8491};
85class X11PixmapDeletor :92
86 public DecorPixmapDeletionInterface93class UnusedPixmapQueue :
87{94 boost::noncopyable
88 public:95{
8996 public:
90 typedef boost::shared_ptr <X11PixmapDeletor> Ptr;97
9198 typedef boost::shared_ptr <UnusedPixmapQueue> Ptr;
92 X11PixmapDeletor (Display *dpy) :99
93 mDisplay (dpy)100 virtual ~UnusedPixmapQueue () {}
94 {101
95 }102 virtual void markUnused (Pixmap pixmap) = 0;
96103};
97 int postDeletePixmap (Pixmap pixmap) { return decor_post_delete_pixmap (mDisplay, pixmap); }104
105class PixmapReleasePool :
106 public PixmapDestroyQueue,
107 public UnusedPixmapQueue
108{
109 public:
110
111 typedef boost::function <int (Pixmap)> FreePixmapFunc;
112
113 typedef boost::shared_ptr <PixmapReleasePool> Ptr;
114
115 PixmapReleasePool (const FreePixmapFunc &freePixmap);
116
117 void markUnused (Pixmap pixmap);
118 int destroyUnusedPixmap (Pixmap pixmap);
98119
99 private:120 private:
100121
101 Display *mDisplay;122 std::list <Pixmap> mPendingUnusedNotificationPixmaps;
123 FreePixmapFunc mFreePixmap;
124
102};125};
103126
104class DecorPixmap :127class DecorPixmap :
@@ -108,7 +131,7 @@
108131
109 typedef boost::shared_ptr <DecorPixmap> Ptr;132 typedef boost::shared_ptr <DecorPixmap> Ptr;
110133
111 DecorPixmap (Pixmap p, DecorPixmapDeletionInterface::Ptr deletor);134 DecorPixmap (Pixmap p, PixmapDestroyQueue::Ptr deletor);
112 ~DecorPixmap ();135 ~DecorPixmap ();
113136
114 Pixmap getPixmap ();137 Pixmap getPixmap ();
@@ -116,10 +139,11 @@
116 private:139 private:
117140
118 Pixmap mPixmap;141 Pixmap mPixmap;
119 DecorPixmapDeletionInterface::Ptr mDeletor;142 PixmapDestroyQueue::Ptr mDeletor;
120};143};
121144
122class DecorPixmapRequestorInterface145class DecorPixmapRequestorInterface :
146 boost::noncopyable
123{147{
124 public:148 public:
125149
@@ -129,7 +153,7 @@
129 unsigned int frameState,153 unsigned int frameState,
130 unsigned int frameActions) = 0;154 unsigned int frameActions) = 0;
131155
132 virtual void handlePending (long *data) = 0;156 virtual void handlePending (const long *data) = 0;
133};157};
134158
135class DecorationListFindMatchingInterface159class DecorationListFindMatchingInterface
@@ -140,8 +164,76 @@
140164
141 virtual DecorationInterface::Ptr findMatchingDecoration (unsigned int frameType,165 virtual DecorationInterface::Ptr findMatchingDecoration (unsigned int frameType,
142 unsigned int frameState,166 unsigned int frameState,
143 unsigned int frameActions) = 0;167 unsigned int frameActions) const = 0;
144};168 virtual DecorationInterface::Ptr findMatchingDecoration (Pixmap pixmap) const = 0;
169};
170
171namespace compiz
172{
173namespace decor
174{
175typedef boost::function <DecorationListFindMatchingInterface * (Window)> DecorListForWindow;
176typedef boost::function <DecorPixmapRequestorInterface * (Window)> RequestorForWindow;
177
178class PendingHandler :
179 virtual boost::noncopyable
180{
181 public:
182
183 PendingHandler (const RequestorForWindow &);
184
185 void handleMessage (Window window, const long *data);
186
187 private:
188
189 RequestorForWindow mRequestorForWindow;
190};
191
192class UnusedHandler :
193 virtual boost::noncopyable
194{
195 public:
196
197 UnusedHandler (const DecorListForWindow &,
198 const UnusedPixmapQueue::Ptr &,
199 const PixmapReleasePool::FreePixmapFunc &);
200
201 void handleMessage (Window, Pixmap);
202
203 private:
204
205 DecorListForWindow mListForWindow;
206 UnusedPixmapQueue::Ptr mQueue;
207 PixmapReleasePool::FreePixmapFunc mFreePixmap;
208};
209
210namespace protocol
211{
212typedef boost::function <void (Window, const long *)> PendingMessage;
213typedef boost::function <void (Window, Pixmap)> PixmapUnusedMessage;
214
215class Communicator :
216 virtual boost::noncopyable
217{
218 public:
219
220 Communicator (Atom pendingMsg,
221 Atom unusedMsg,
222 const PendingMessage &,
223 const PixmapUnusedMessage &);
224
225 void handleClientMessage (const XClientMessageEvent &);
226
227 private:
228
229 Atom mPendingMsgAtom;
230 Atom mUnusedMsgAtom;
231 PendingMessage mPendingHandler;
232 PixmapUnusedMessage mPixmapUnusedHander;
233};
234}
235}
236}
145237
146class X11DecorPixmapRequestor :238class X11DecorPixmapRequestor :
147 public DecorPixmapRequestorInterface239 public DecorPixmapRequestorInterface
@@ -156,7 +248,7 @@
156 unsigned int frameState,248 unsigned int frameState,
157 unsigned int frameActions);249 unsigned int frameActions);
158250
159 void handlePending (long *data);251 void handlePending (const long *data);
160252
161 private:253 private:
162254
163255
=== modified file 'plugins/decor/src/pixmap-requests/src/pixmap-requests.cpp'
--- plugins/decor/src/pixmap-requests/src/pixmap-requests.cpp 2012-05-10 15:40:25 +0000
+++ plugins/decor/src/pixmap-requests/src/pixmap-requests.cpp 2013-02-20 07:34:20 +0000
@@ -6,7 +6,10 @@
6#define foreach BOOST_FOREACH6#define foreach BOOST_FOREACH
7#endif7#endif
88
9DecorPixmap::DecorPixmap (Pixmap pixmap, DecorPixmapDeletionInterface::Ptr d) :9namespace cd = compiz::decor;
10namespace cdp = compiz::decor::protocol;
11
12DecorPixmap::DecorPixmap (Pixmap pixmap, PixmapDestroyQueue::Ptr d) :
10 mPixmap (pixmap),13 mPixmap (pixmap),
11 mDeletor (d)14 mDeletor (d)
12{15{
@@ -14,7 +17,7 @@
1417
15DecorPixmap::~DecorPixmap ()18DecorPixmap::~DecorPixmap ()
16{19{
17 mDeletor->postDeletePixmap (mPixmap);20 mDeletor->destroyUnusedPixmap (mPixmap);
18}21}
1922
20Pixmap23Pixmap
@@ -78,7 +81,7 @@
78}81}
7982
80void83void
81X11DecorPixmapRequestor::handlePending (long *data)84X11DecorPixmapRequestor::handlePending (const long *data)
82{85{
83 DecorationInterface::Ptr d = mListFinder->findMatchingDecoration (static_cast <unsigned int> (data[0]),86 DecorationInterface::Ptr d = mListFinder->findMatchingDecoration (static_cast <unsigned int> (data[0]),
84 static_cast <unsigned int> (data[1]),87 static_cast <unsigned int> (data[1]),
@@ -91,3 +94,103 @@
91 static_cast <unsigned int> (data[1]),94 static_cast <unsigned int> (data[1]),
92 static_cast <unsigned int> (data[2]));95 static_cast <unsigned int> (data[2]));
93}96}
97
98namespace
99{
100typedef PixmapReleasePool::FreePixmapFunc FreePixmapFunc;
101}
102
103PixmapReleasePool::PixmapReleasePool (const FreePixmapFunc &freePixmap) :
104 mFreePixmap (freePixmap)
105{
106}
107
108void
109PixmapReleasePool::markUnused (Pixmap pixmap)
110{
111 mPendingUnusedNotificationPixmaps.push_back (pixmap);
112 mPendingUnusedNotificationPixmaps.unique ();
113}
114
115int
116PixmapReleasePool::destroyUnusedPixmap (Pixmap pixmap)
117{
118 std::list <Pixmap>::iterator it =
119 std::find (mPendingUnusedNotificationPixmaps.begin (),
120 mPendingUnusedNotificationPixmaps.end (),
121 pixmap);
122
123 if (it != mPendingUnusedNotificationPixmaps.end ())
124 {
125 Pixmap pixmap (*it);
126 mPendingUnusedNotificationPixmaps.erase (it);
127
128 mFreePixmap (pixmap);
129 }
130
131 return 0;
132}
133
134cd::PendingHandler::PendingHandler (const cd::RequestorForWindow &requestorForWindow) :
135 mRequestorForWindow (requestorForWindow)
136{
137}
138
139void
140cd::PendingHandler::handleMessage (Window window, const long *data)
141{
142 DecorPixmapRequestorInterface *requestor = mRequestorForWindow (window);
143
144 if (requestor)
145 requestor->handlePending (data);
146}
147
148cd::UnusedHandler::UnusedHandler (const cd::DecorListForWindow &listForWindow,
149 const UnusedPixmapQueue::Ptr &queue,
150 const FreePixmapFunc &freePixmap) :
151 mListForWindow (listForWindow),
152 mQueue (queue),
153 mFreePixmap (freePixmap)
154{
155}
156
157void
158cd::UnusedHandler::handleMessage (Window window, Pixmap pixmap)
159{
160 DecorationListFindMatchingInterface *findMatching = mListForWindow (window);
161
162 if (findMatching)
163 {
164 DecorationInterface::Ptr decoration (findMatching->findMatchingDecoration (pixmap));
165
166 if (decoration)
167 {
168 mQueue->markUnused (pixmap);
169 return;
170 }
171 }
172
173 /* If a decoration was not found, then this pixmap is no longer in use
174 * and we should free it */
175 mFreePixmap (pixmap);
176}
177
178cdp::Communicator::Communicator (Atom pendingMsg,
179 Atom unusedMsg,
180 const cdp::PendingMessage &pending,
181 const cdp::PixmapUnusedMessage &pixmapUnused) :
182 mPendingMsgAtom (pendingMsg),
183 mUnusedMsgAtom (unusedMsg),
184 mPendingHandler (pending),
185 mPixmapUnusedHander (pixmapUnused)
186{
187}
188
189void
190cdp::Communicator::handleClientMessage (const XClientMessageEvent &xce)
191{
192 if (xce.message_type == mPendingMsgAtom)
193 mPendingHandler (xce.window, xce.data.l);
194 else if (xce.message_type == mUnusedMsgAtom)
195 mPixmapUnusedHander (xce.window, xce.data.l[0]);
196}
94197
=== modified file 'plugins/decor/src/pixmap-requests/tests/CMakeLists.txt'
--- plugins/decor/src/pixmap-requests/tests/CMakeLists.txt 2012-08-01 00:42:38 +0000
+++ plugins/decor/src/pixmap-requests/tests/CMakeLists.txt 2013-02-20 07:34:20 +0000
@@ -1,10 +1,17 @@
1include_directories(${CMAKE_CURRENT_SOURCE_DIR})1include_directories(${CMAKE_CURRENT_SOURCE_DIR})
22
3add_library (compiz_decor_pixmap_requests_mock STATIC
4 ${CMAKE_CURRENT_SOURCE_DIR}/compiz_decor_pixmap_requests_mock.cpp)
5
6target_link_libraries (compiz_decor_pixmap_requests_mock
7 compiz_decor_pixmap_requests)
8
3add_executable (compiz_test_decor_pixmap_requests9add_executable (compiz_test_decor_pixmap_requests
4 ${CMAKE_CURRENT_SOURCE_DIR}/pixmap-requests/src/test-decor-pixmap-requests.cpp)10 ${CMAKE_CURRENT_SOURCE_DIR}/test-decor-pixmap-requests.cpp)
511
6target_link_libraries (compiz_test_decor_pixmap_requests12target_link_libraries (compiz_test_decor_pixmap_requests
7 compiz_decor_pixmap_requests13 compiz_decor_pixmap_requests
14 compiz_decor_pixmap_requests_mock
8 decoration15 decoration
9 ${GTEST_BOTH_LIBRARIES}16 ${GTEST_BOTH_LIBRARIES}
10 ${GMOCK_LIBRARY}17 ${GMOCK_LIBRARY}
@@ -13,3 +20,5 @@
13 )20 )
1421
15compiz_discover_tests (compiz_test_decor_pixmap_requests COVERAGE compiz_decor_pixmap_requests)22compiz_discover_tests (compiz_test_decor_pixmap_requests COVERAGE compiz_decor_pixmap_requests)
23
24add_subdirectory (integration)
1625
=== added file 'plugins/decor/src/pixmap-requests/tests/compiz_decor_pixmap_requests_mock.cpp'
--- plugins/decor/src/pixmap-requests/tests/compiz_decor_pixmap_requests_mock.cpp 1970-01-01 00:00:00 +0000
+++ plugins/decor/src/pixmap-requests/tests/compiz_decor_pixmap_requests_mock.cpp 2013-02-20 07:34:20 +0000
@@ -0,0 +1,113 @@
1/*
2 * Copyright © 2012 Canonical Ltd.
3 * Copyright © 2013 Sam Spilsbury <smspillaz@gmail.com>
4 *
5 * Permission to use, copy, modify, distribute, and sell this software
6 * and its documentation for any purpose is hereby granted without
7 * fee, provided that the above copyright notice appear in all copies
8 * and that both that copyright notice and this permission notice
9 * appear in supporting documentation, and that the name of
10 * Canonical Ltd. not be used in advertising or publicity pertaining to
11 * distribution of the software without specific, written prior permission.
12 * Canonical Ltd. makes no representations about the suitability of this
13 * software for any purpose. It is provided "as is" without express or
14 * implied warranty.
15 *
16 * CANONICAL, LTD. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
17 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
18 * NO EVENT SHALL CANONICAL, LTD. BE LIABLE FOR ANY SPECIAL, INDIRECT OR
19 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
20 * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
21 * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
22 * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
23 *
24 * Authored by: Sam Spilsbury <sam.spilsbury@canonical.com>
25 */
26
27#include "compiz_decor_pixmap_requests_mock.h"
28
29/* These exist purely because the implicit details of the
30 * constructors of the MOCK_METHODs are quite complex. We can
31 * save compilation time by generating those constructors once,
32 * and linking, rather than generating multiple definitions and
33 * having the linker eliminate them */
34
35MockDecorPixmapDeletor::MockDecorPixmapDeletor ()
36{
37}
38
39MockDecorPixmapDeletor::~MockDecorPixmapDeletor ()
40{
41}
42
43MockDecorPixmapReceiver::MockDecorPixmapReceiver ()
44{
45}
46
47MockDecorPixmapReceiver::~MockDecorPixmapReceiver ()
48{
49}
50
51MockDecoration::MockDecoration ()
52{
53}
54
55MockDecoration::~MockDecoration ()
56{
57}
58
59MockDecorationListFindMatching::MockDecorationListFindMatching ()
60{
61}
62
63MockDecorationListFindMatching::~MockDecorationListFindMatching ()
64{
65}
66
67MockDecorPixmapRequestor::MockDecorPixmapRequestor ()
68{
69}
70
71MockDecorPixmapRequestor::~MockDecorPixmapRequestor ()
72{
73}
74
75XlibPixmapMock::XlibPixmapMock ()
76{
77}
78
79XlibPixmapMock::~XlibPixmapMock ()
80{
81}
82
83MockFindRequestor::MockFindRequestor ()
84{
85}
86
87MockFindRequestor::~MockFindRequestor ()
88{
89}
90
91MockFindList::MockFindList ()
92{
93}
94
95MockFindList::~MockFindList ()
96{
97}
98
99MockUnusedPixmapQueue::MockUnusedPixmapQueue ()
100{
101}
102
103MockUnusedPixmapQueue::~MockUnusedPixmapQueue ()
104{
105}
106
107MockProtocolDispatchFuncs::MockProtocolDispatchFuncs ()
108{
109}
110
111MockProtocolDispatchFuncs::~MockProtocolDispatchFuncs ()
112{
113}
0114
=== added file 'plugins/decor/src/pixmap-requests/tests/compiz_decor_pixmap_requests_mock.h'
--- plugins/decor/src/pixmap-requests/tests/compiz_decor_pixmap_requests_mock.h 1970-01-01 00:00:00 +0000
+++ plugins/decor/src/pixmap-requests/tests/compiz_decor_pixmap_requests_mock.h 2013-02-20 07:34:20 +0000
@@ -0,0 +1,179 @@
1/*
2 * Copyright © 2012 Canonical Ltd.
3 * Copyright © 2013 Sam Spilsbury <smspillaz@gmail.com>
4 *
5 * Permission to use, copy, modify, distribute, and sell this software
6 * and its documentation for any purpose is hereby granted without
7 * fee, provided that the above copyright notice appear in all copies
8 * and that both that copyright notice and this permission notice
9 * appear in supporting documentation, and that the name of
10 * Canonical Ltd. not be used in advertising or publicity pertaining to
11 * distribution of the software without specific, written prior permission.
12 * Canonical Ltd. makes no representations about the suitability of this
13 * software for any purpose. It is provided "as is" without express or
14 * implied warranty.
15 *
16 * CANONICAL, LTD. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
17 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
18 * NO EVENT SHALL CANONICAL, LTD. BE LIABLE FOR ANY SPECIAL, INDIRECT OR
19 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
20 * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
21 * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
22 * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
23 *
24 * Authored by: Sam Spilsbury <sam.spilsbury@canonical.com>
25 */
26
27#ifndef _COMPIZ_DECOR_PIXMAP_REQUESTS_MOCK_H
28#define _COMPIZ_DECOR_PIXMAP_REQUESTS_MOCK_H
29
30#include <gmock/gmock.h>
31#include <boost/bind.hpp>
32
33#include <X11/Xlib.h>
34#include "pixmap-requests.h"
35
36class MockDecorPixmapDeletor :
37 public PixmapDestroyQueue
38{
39 public:
40
41 MockDecorPixmapDeletor ();
42 ~MockDecorPixmapDeletor ();
43
44 MOCK_METHOD1 (destroyUnusedPixmap, int (Pixmap p));
45};
46
47class MockDecorPixmapReceiver :
48 public DecorPixmapReceiverInterface
49{
50 public:
51
52 MockDecorPixmapReceiver ();
53 ~MockDecorPixmapReceiver ();
54
55 MOCK_METHOD0 (pending, void ());
56 MOCK_METHOD0 (update, void ());
57};
58
59class MockDecoration :
60 public DecorationInterface
61{
62 public:
63
64 MockDecoration ();
65 ~MockDecoration ();
66
67 MOCK_METHOD0 (receiverInterface, DecorPixmapReceiverInterface & ());
68 MOCK_CONST_METHOD0 (getFrameType, unsigned int ());
69 MOCK_CONST_METHOD0 (getFrameState, unsigned int ());
70 MOCK_CONST_METHOD0 (getFrameActions, unsigned int ());
71};
72
73class MockDecorationListFindMatching :
74 public DecorationListFindMatchingInterface
75{
76 public:
77
78 MockDecorationListFindMatching ();
79 ~MockDecorationListFindMatching ();
80
81 MOCK_CONST_METHOD3 (findMatchingDecoration, DecorationInterface::Ptr (unsigned int, unsigned int, unsigned int));
82 MOCK_CONST_METHOD1 (findMatchingDecoration, DecorationInterface::Ptr (Pixmap));
83};
84
85class MockDecorPixmapRequestor :
86 public DecorPixmapRequestorInterface
87{
88 public:
89
90 MockDecorPixmapRequestor ();
91 ~MockDecorPixmapRequestor ();
92
93 MOCK_METHOD3 (postGenerateRequest, int (unsigned int, unsigned int, unsigned int));
94 MOCK_METHOD1 (handlePending, void (const long *));
95};
96
97class XlibPixmapMock
98{
99 public:
100
101 XlibPixmapMock ();
102 ~XlibPixmapMock ();
103
104 MOCK_METHOD1(freePixmap, int (Pixmap));
105};
106
107class MockFindRequestor
108{
109 public:
110
111 MockFindRequestor ();
112 ~MockFindRequestor ();
113
114 MOCK_METHOD1 (findRequestor, DecorPixmapRequestorInterface * (Window));
115};
116
117class MockFindList
118{
119 public:
120
121 MockFindList ();
122 ~MockFindList ();
123
124 MOCK_METHOD1 (findList, DecorationListFindMatchingInterface * (Window));
125};
126
127class MockUnusedPixmapQueue :
128 public UnusedPixmapQueue
129{
130 public:
131
132 MockUnusedPixmapQueue ();
133 ~MockUnusedPixmapQueue ();
134
135 typedef boost::shared_ptr <MockUnusedPixmapQueue> Ptr;
136
137 MOCK_METHOD1 (markUnused, void (Pixmap));
138};
139
140class StubReceiver :
141 public DecorPixmapReceiverInterface
142{
143 public:
144
145 void pending () {}
146 void update () {}
147};
148
149class StubDecoration :
150 public DecorationInterface
151{
152 public:
153
154 DecorPixmapReceiverInterface & receiverInterface ()
155 {
156 return mReceiver;
157 }
158
159 unsigned int getFrameType () const { return 0; }
160 unsigned int getFrameState () const { return 0; }
161 unsigned int getFrameActions () const { return 0; }
162
163 private:
164
165 StubReceiver mReceiver;
166};
167
168class MockProtocolDispatchFuncs
169{
170 public:
171
172 MockProtocolDispatchFuncs ();
173 ~MockProtocolDispatchFuncs ();
174
175 MOCK_METHOD2 (handlePending, void (Window, const long *));
176 MOCK_METHOD2 (handleUnused, void (Window, Pixmap));
177};
178
179#endif
0180
=== added directory 'plugins/decor/src/pixmap-requests/tests/integration'
=== added file 'plugins/decor/src/pixmap-requests/tests/integration/CMakeLists.txt'
--- plugins/decor/src/pixmap-requests/tests/integration/CMakeLists.txt 1970-01-01 00:00:00 +0000
+++ plugins/decor/src/pixmap-requests/tests/integration/CMakeLists.txt 2013-02-20 07:34:20 +0000
@@ -0,0 +1,1 @@
1add_subdirectory (xorg-gtest)
02
=== added directory 'plugins/decor/src/pixmap-requests/tests/integration/xorg-gtest'
=== added file 'plugins/decor/src/pixmap-requests/tests/integration/xorg-gtest/CMakeLists.txt'
--- plugins/decor/src/pixmap-requests/tests/integration/xorg-gtest/CMakeLists.txt 1970-01-01 00:00:00 +0000
+++ plugins/decor/src/pixmap-requests/tests/integration/xorg-gtest/CMakeLists.txt 2013-02-20 07:34:20 +0000
@@ -0,0 +1,41 @@
1include (FindPkgConfig)
2
3if (BUILD_XORG_GTEST)
4
5 include_directories (${compiz_SOURCE_DIR}/tests/shared
6 ${COMPIZ_XORG_SYSTEM_TEST_INCLUDE_DIR}
7 ${X11_INCLUDE_DIRS}
8 ${XORG_SERVER_INCLUDE_XORG_GTEST}
9 ${XORG_SERVER_GTEST_SRC}
10 ${GTEST_INCLUDE_DIRS}
11 ${COMPIZ_DECOR_PIXMAP_PROTOCOL_INTEGRATION_INCLUDE_DIRS})
12
13 link_directories (${X11_XI_LIBRARY_DIRS}
14 ${COMPIZ_COMPOSITE_DAMAGETRACKING_INTEGRATION_LIBRARY_DIRS})
15
16 add_executable (compiz_test_decor_pixmap_protocol_integration
17 ${CMAKE_CURRENT_SOURCE_DIR}/compiz_test_decor_pixmap_protocol_integration.cpp)
18
19 set (COMPIZ_DECOR_PIXMAP_PROTOCOL_XORG_INTEGRATION_TEST_LIBRARIES
20 xorg_gtest_all
21 xorg_gtest_main
22 compiz_xorg_gtest_system_test
23 compiz_decor_pixmap_requests
24 compiz_decor_pixmap_requests_mock
25 decoration
26 ${GMOCK_LIBRARY}
27 ${GMOCK_MAIN_LIBRARY}
28 ${GTEST_BOTH_LIBRARIES}
29 ${CMAKE_THREAD_LIBS_INIT}
30 ${XORG_SERVER_LIBRARIES}
31 ${X11_XI_LIBRARIES}
32 ${COMPIZ_DECOR_PIXMAP_PROTOCOL_INTEGRATION_LIBRARIES})
33
34 target_link_libraries (compiz_test_decor_pixmap_protocol_integration
35 ${COMPIZ_DECOR_PIXMAP_PROTOCOL_XORG_INTEGRATION_TEST_LIBRARIES})
36
37 compiz_discover_tests (compiz_test_decor_pixmap_protocol_integration WITH_XORG_GTEST COVERAGE
38 compiz_decor_pixmap_requests)
39
40endif (BUILD_XORG_GTEST)
41
042
=== added file 'plugins/decor/src/pixmap-requests/tests/integration/xorg-gtest/compiz_test_decor_pixmap_protocol_integration.cpp'
--- plugins/decor/src/pixmap-requests/tests/integration/xorg-gtest/compiz_test_decor_pixmap_protocol_integration.cpp 1970-01-01 00:00:00 +0000
+++ plugins/decor/src/pixmap-requests/tests/integration/xorg-gtest/compiz_test_decor_pixmap_protocol_integration.cpp 2013-02-20 07:34:20 +0000
@@ -0,0 +1,483 @@
1/*
2 * Compiz XOrg GTest Decoration Pixmap Protocol Integration Tests
3 *
4 * Copyright (C) 2013 Sam Spilsbury.
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 *
20 * Authored By:
21 * Sam Spilsbury <smspillaz@gmail.com>
22 */
23#include <gtest/gtest.h>
24#include <gmock/gmock.h>
25
26#include <boost/function.hpp>
27#include <boost/bind.hpp>
28
29#include <boost/shared_ptr.hpp>
30#include <boost/make_shared.hpp>
31
32#include <X11/Xlib.h>
33#include <X11/Xatom.h>
34
35#include "decoration.h"
36
37#include <xorg/gtest/xorg-gtest.h>
38#include <compiz-xorg-gtest.h>
39
40#include "pixmap-requests.h"
41#include "compiz_decor_pixmap_requests_mock.h"
42
43namespace xt = xorg::testing;
44namespace ct = compiz::testing;
45namespace cd = compiz::decor;
46namespace cdp = compiz::decor::protocol;
47
48using ::testing::AtLeast;
49using ::testing::ReturnNull;
50using ::testing::Return;
51using ::testing::MatcherInterface;
52using ::testing::MatchResultListener;
53using ::testing::_;
54
55class DecorPixmapProtocol :
56 public xorg::testing::Test
57{
58 public:
59
60 typedef boost::function <void (const XClientMessageEvent &)> ClientMessageReceiver;
61
62 void SetUp ();
63
64 void WaitForClientMessageOnAndDeliverTo (Window client,
65 Atom message,
66 const ClientMessageReceiver &receiver);
67
68 protected:
69
70 Atom deletePixmapMessage;
71 Atom pendingMessage;
72};
73
74namespace
75{
76bool Advance (Display *d, bool result)
77{
78 return ct::AdvanceToNextEventOnSuccess (d, result);
79}
80
81Window MOCK_WINDOW = 1;
82Pixmap MOCK_PIXMAP = 2;
83
84class MockClientMessageReceiver
85{
86 public:
87
88 MOCK_METHOD1 (receiveMsg, void (const XClientMessageEvent &));
89};
90
91class DisplayFetch
92{
93 public:
94
95 virtual ~DisplayFetch () {}
96
97 virtual ::Display * Display () const = 0;
98};
99
100class XFreePixmapWrapper
101{
102 public:
103
104 XFreePixmapWrapper (const DisplayFetch &df) :
105 mDisplayFetch (df)
106 {
107 }
108
109 int FreePixmap (Pixmap pixmap)
110 {
111 return XFreePixmap (mDisplayFetch.Display (), pixmap);
112 }
113
114 private:
115
116 const DisplayFetch &mDisplayFetch;
117};
118
119class XErrorTracker
120{
121 public:
122
123 XErrorTracker ();
124 ~XErrorTracker ();
125
126 MOCK_METHOD1 (errorHandler, void (int));
127
128 private:
129
130 XErrorHandler handler;
131
132 static int handleXError (Display *dpy, XErrorEvent *ev);
133 static XErrorTracker *tracker;
134};
135
136XErrorTracker * XErrorTracker::tracker = NULL;
137
138XErrorTracker::XErrorTracker ()
139{
140 tracker = this;
141 handler = XSetErrorHandler (handleXError);
142}
143
144XErrorTracker::~XErrorTracker ()
145{
146 tracker = NULL;
147 XSetErrorHandler (handler);
148}
149
150int
151XErrorTracker::handleXError (Display *dpy, XErrorEvent *ev)
152{
153 tracker->errorHandler (ev->error_code);
154 return 0;
155}
156
157bool PixmapValid (Display *d, Pixmap p)
158{
159 Window root;
160 unsigned int width, height, border, depth;
161 int x, y;
162
163 XErrorTracker tracker;
164
165 EXPECT_CALL (tracker, errorHandler (BadDrawable)).Times (AtLeast (0));
166
167 bool success = XGetGeometry (d, p, &root, &x, &y,
168 &width, &height, &border, &depth);
169
170 return success;
171}
172}
173
174void
175DecorPixmapProtocol::SetUp ()
176{
177 xorg::testing::Test::SetUp ();
178
179 XSelectInput (Display (),
180 DefaultRootWindow (Display ()),
181 StructureNotifyMask);
182
183 deletePixmapMessage = XInternAtom (Display (), DECOR_DELETE_PIXMAP_ATOM_NAME, 0);
184 pendingMessage = XInternAtom (Display (), DECOR_PIXMAP_PENDING_ATOM_NAME, 0);
185}
186
187class DeliveryMatcher :
188 public ct::XEventMatcher
189{
190 public:
191
192 DeliveryMatcher (Atom message,
193 const DecorPixmapProtocol::ClientMessageReceiver &receiver) :
194 mMessage (message),
195 mReceiver (receiver)
196 {
197 }
198
199 bool MatchAndExplain (const XEvent &xce,
200 MatchResultListener *listener) const
201 {
202 if (xce.xclient.message_type == mMessage)
203 {
204 mReceiver (reinterpret_cast <const XClientMessageEvent &> (xce));
205 return true;
206 }
207 else
208 return false;
209 }
210
211 void DescribeTo (std::ostream *os) const
212 {
213 *os << "Message delivered";
214 }
215
216 private:
217
218 Atom mMessage;
219 DecorPixmapProtocol::ClientMessageReceiver mReceiver;
220};
221
222void
223DecorPixmapProtocol::WaitForClientMessageOnAndDeliverTo (Window client,
224 Atom message,
225 const ClientMessageReceiver &receiver)
226{
227 ::Display *d = Display ();
228
229 DeliveryMatcher delivery (message, receiver);
230 ASSERT_TRUE (Advance (d, ct::WaitForEventOfTypeOnWindowMatching (d,
231 client,
232 ClientMessage,
233 -1,
234 -1,
235 delivery)));
236}
237
238TEST_F (DecorPixmapProtocol, PostDeleteCausesClientMessage)
239{
240 MockClientMessageReceiver receiver;
241 ::Display *d = Display ();
242
243 decor_post_delete_pixmap (d,
244 MOCK_WINDOW,
245 MOCK_PIXMAP);
246
247 EXPECT_CALL (receiver, receiveMsg (_)).Times (1);
248
249 WaitForClientMessageOnAndDeliverTo (MOCK_WINDOW,
250 deletePixmapMessage,
251 boost::bind (&MockClientMessageReceiver::receiveMsg,
252 &receiver,
253 _1));
254}
255
256TEST_F (DecorPixmapProtocol, PostDeleteDispatchesClientMessageToReceiver)
257{
258 MockProtocolDispatchFuncs dispatch;
259 cdp::Communicator communicator (pendingMessage,
260 deletePixmapMessage,
261 boost::bind (&MockProtocolDispatchFuncs::handlePending,
262 &dispatch,
263 _1,
264 _2),
265 boost::bind (&MockProtocolDispatchFuncs::handleUnused,
266 &dispatch,
267 _1,
268 _2));
269
270 decor_post_delete_pixmap (Display (),
271 MOCK_WINDOW,
272 MOCK_PIXMAP);
273
274 EXPECT_CALL (dispatch, handleUnused (MOCK_WINDOW, MOCK_PIXMAP)).Times (1);
275
276 WaitForClientMessageOnAndDeliverTo (MOCK_WINDOW,
277 deletePixmapMessage,
278 boost::bind (&cdp::Communicator::handleClientMessage,
279 &communicator,
280 _1));
281}
282
283/* Test end to end. Post the delete message and cause the pixmap to be freed */
284
285class DecorPixmapProtocolEndToEnd :
286 public DecorPixmapProtocol,
287 public DisplayFetch
288{
289 public:
290
291 DecorPixmapProtocolEndToEnd () :
292 freePixmap (*this),
293 releasePool (new PixmapReleasePool (
294 boost::bind (&XFreePixmapWrapper::FreePixmap,
295 &freePixmap,
296 _1))),
297 pendingHandler (boost::bind (&MockFindRequestor::findRequestor,
298 &mockFindRequestor,
299 _1)),
300 unusedHandler (boost::bind (&MockFindList::findList,
301 &mockFindList,
302 _1),
303 releasePool,
304 boost::bind (&XFreePixmapWrapper::FreePixmap,
305 &freePixmap,
306 _1)),
307 stubDecoration (new StubDecoration ())
308 {
309 }
310
311 void SetUp ()
312 {
313 DecorPixmapProtocol::SetUp ();
314
315 communicator.reset (new cdp::Communicator (
316 pendingMessage,
317 deletePixmapMessage,
318 boost::bind (&cd::PendingHandler::handleMessage,
319 &pendingHandler,
320 _1,
321 _2),
322 boost::bind (&cd::UnusedHandler::handleMessage,
323 &unusedHandler,
324 _1,
325 _2)));
326 }
327
328 ::Display *
329 Display () const
330 {
331 return DecorPixmapProtocol::Display ();
332 }
333
334 XFreePixmapWrapper freePixmap;
335 PixmapReleasePool::Ptr releasePool;
336 cd::PendingHandler pendingHandler;
337 cd::UnusedHandler unusedHandler;
338 boost::shared_ptr <cdp::Communicator> communicator;
339 MockFindList mockFindList;
340 MockFindRequestor mockFindRequestor;
341 StubDecoration::Ptr stubDecoration;
342 MockDecorPixmapRequestor mockRequestor;
343 MockDecorationListFindMatching mockFindMatching;
344
345};
346
347class DecorPixmapProtocolDeleteEndToEnd :
348 public DecorPixmapProtocolEndToEnd
349{
350 public:
351
352 void SetUp ()
353 {
354 DecorPixmapProtocolEndToEnd::SetUp ();
355
356 ::Display *d = Display ();
357
358 pixmap = XCreatePixmap (d,
359 DefaultRootWindow (d),
360 1,
361 1,
362 DefaultDepth (d,
363 DefaultScreen (d)));
364
365 decor_post_delete_pixmap (d,
366 MOCK_WINDOW,
367 pixmap);
368 }
369
370 void TearDown ()
371 {
372 if (PixmapValid (Display (), pixmap))
373 XFreePixmap (Display (), pixmap);
374 }
375
376 protected:
377
378 Pixmap pixmap;
379};
380
381TEST_F (DecorPixmapProtocolDeleteEndToEnd, TestFreeNotFoundWindowPixmapImmediately)
382{
383 ::Display *d = Display ();
384
385 EXPECT_CALL (mockFindList, findList (MOCK_WINDOW)).WillOnce (ReturnNull ());
386
387 /* Deliver it to the communicator */
388 WaitForClientMessageOnAndDeliverTo (MOCK_WINDOW,
389 deletePixmapMessage,
390 boost::bind (&cdp::Communicator::handleClientMessage,
391 communicator.get (),
392 _1));
393
394 /* Check if the pixmap is still valid */
395 EXPECT_FALSE (PixmapValid (d, pixmap));
396}
397
398TEST_F (DecorPixmapProtocolDeleteEndToEnd, TestFreeUnusedPixmapImmediately)
399{
400 ::Display *d = Display ();
401
402 EXPECT_CALL (mockFindMatching, findMatchingDecoration (pixmap)).WillOnce (Return (DecorationInterface::Ptr ()));
403 EXPECT_CALL (mockFindList, findList (MOCK_WINDOW)).WillOnce (Return (&mockFindMatching));
404 /* Deliver it to the communicator */
405 WaitForClientMessageOnAndDeliverTo (MOCK_WINDOW,
406 deletePixmapMessage,
407 boost::bind (&cdp::Communicator::handleClientMessage,
408 communicator.get (),
409 _1));
410
411 /* Check if the pixmap is still valid */
412 EXPECT_FALSE (PixmapValid (d, pixmap));
413}
414
415TEST_F (DecorPixmapProtocolDeleteEndToEnd, TestQueuePixmapIfUsed)
416{
417 ::Display *d = Display ();
418
419 EXPECT_CALL (mockFindMatching, findMatchingDecoration (pixmap)).WillOnce (Return (stubDecoration));
420 EXPECT_CALL (mockFindList, findList (MOCK_WINDOW)).WillOnce (Return (&mockFindMatching));
421 /* Deliver it to the communicator */
422 WaitForClientMessageOnAndDeliverTo (MOCK_WINDOW,
423 deletePixmapMessage,
424 boost::bind (&cdp::Communicator::handleClientMessage,
425 communicator.get (),
426 _1));
427
428 /* Check if the pixmap is still valid */
429 EXPECT_TRUE (PixmapValid (d, pixmap));
430
431 /* Call destroyUnusedPixmap on the release pool, it should release
432 * the pixmap which was otherwise unused */
433 releasePool->destroyUnusedPixmap (pixmap);
434
435 /* Pixmap should now be invalid */
436 EXPECT_FALSE (PixmapValid (d, pixmap));
437}
438
439class DecorPixmapProtocolPendingEndToEnd :
440 public DecorPixmapProtocolEndToEnd
441{
442 public:
443
444 DecorPixmapProtocolPendingEndToEnd () :
445 frameType (1),
446 frameState (2),
447 frameActions (3)
448 {
449 }
450
451 void SetUp ()
452 {
453 DecorPixmapProtocolEndToEnd::SetUp ();
454
455 ::Display *d = Display ();
456
457 decor_post_pending (d, MOCK_WINDOW, frameType, frameState, frameActions);
458 }
459
460 protected:
461
462 unsigned int frameType, frameState, frameActions;
463};
464
465MATCHER_P3 (MatchArrayValues3, v1, v2, v3, "Matches three array values")
466{
467 return static_cast <unsigned int> (arg[0]) == v1 &&
468 static_cast <unsigned int> (arg[1]) == v2 &&
469 static_cast <unsigned int> (arg[2]) == v3;
470}
471
472TEST_F (DecorPixmapProtocolPendingEndToEnd, TestPostPendingMarksAsPendingOnClient)
473{
474 EXPECT_CALL (mockFindRequestor, findRequestor (MOCK_WINDOW)).WillOnce (Return (&mockRequestor));
475 EXPECT_CALL (mockRequestor, handlePending (MatchArrayValues3 (frameType, frameState, frameActions)));
476
477 /* Deliver it to the communicator */
478 WaitForClientMessageOnAndDeliverTo (MOCK_WINDOW,
479 pendingMessage,
480 boost::bind (&cdp::Communicator::handleClientMessage,
481 communicator.get (),
482 _1));
483}
0484
=== 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'
--- plugins/decor/src/pixmap-requests/tests/pixmap-requests/src/test-decor-pixmap-requests.cpp 2012-05-10 15:40:25 +0000
+++ plugins/decor/src/pixmap-requests/tests/test-decor-pixmap-requests.cpp 2013-02-20 07:34:20 +0000
@@ -25,67 +25,29 @@
2525
26#include <gtest/gtest.h>26#include <gtest/gtest.h>
27#include <gmock/gmock.h>27#include <gmock/gmock.h>
28#include <boost/bind.hpp>
28#include <iostream>29#include <iostream>
30
31#include <X11/Xlib.h>
29#include "pixmap-requests.h"32#include "pixmap-requests.h"
33#include "compiz_decor_pixmap_requests_mock.h"
3034
35using ::testing::AtLeast;
36using ::testing::Pointee;
31using ::testing::Return;37using ::testing::Return;
3238using ::testing::ReturnNull;
33class DecorPixmapRequestsTest :39using ::testing::IsNull;
34 public ::testing::Test40using ::testing::_;
35{41
36};42namespace cd = compiz::decor;
3743namespace cdp = compiz::decor::protocol;
38class MockDecorPixmapDeletor :
39 public DecorPixmapDeletionInterface
40{
41 public:
42
43 MOCK_METHOD1 (postDeletePixmap, int (Pixmap p));
44};
45
46class MockDecorPixmapReceiver :
47 public DecorPixmapReceiverInterface
48{
49 public:
50
51 MOCK_METHOD0 (pending, void ());
52 MOCK_METHOD0 (update, void ());
53};
54
55class MockDecoration :
56 public DecorationInterface
57{
58 public:
59
60 MOCK_METHOD0 (receiverInterface, DecorPixmapReceiverInterface & ());
61 MOCK_CONST_METHOD0 (getFrameType, unsigned int ());
62 MOCK_CONST_METHOD0 (getFrameState, unsigned int ());
63 MOCK_CONST_METHOD0 (getFrameActions, unsigned int ());
64};
65
66class MockDecorationListFindMatching :
67 public DecorationListFindMatchingInterface
68{
69 public:
70
71 MOCK_METHOD3 (findMatchingDecoration, DecorationInterface::Ptr (unsigned int, unsigned int, unsigned int));
72};
73
74class MockDecorPixmapRequestor :
75 public DecorPixmapRequestorInterface
76{
77 public:
78
79 MOCK_METHOD3 (postGenerateRequest, int (unsigned int, unsigned int, unsigned int));
80 MOCK_METHOD1 (handlePending, void (long *));
81};
8244
83TEST(DecorPixmapRequestsTest, TestDestroyPixmapDeletes)45TEST(DecorPixmapRequestsTest, TestDestroyPixmapDeletes)
84{46{
85 boost::shared_ptr <MockDecorPixmapDeletor> mockDeletor = boost::make_shared <MockDecorPixmapDeletor> ();47 boost::shared_ptr <MockDecorPixmapDeletor> mockDeletor = boost::make_shared <MockDecorPixmapDeletor> ();
86 DecorPixmap pm (1, boost::shared_static_cast<DecorPixmapDeletionInterface> (mockDeletor));48 DecorPixmap pm (1, boost::shared_static_cast<PixmapDestroyQueue> (mockDeletor));
8749
88 EXPECT_CALL (*(mockDeletor.get ()), postDeletePixmap (1)).WillOnce (Return (1));50 EXPECT_CALL (*(mockDeletor.get ()), destroyUnusedPixmap (1)).WillOnce (Return (1));
89}51}
9052
91TEST(DecorPixmapRequestsTest, TestPendingGeneratesRequest)53TEST(DecorPixmapRequestsTest, TestPendingGeneratesRequest)
@@ -158,3 +120,284 @@
158 receiver.pending ();120 receiver.pending ();
159 receiver.update ();121 receiver.update ();
160}122}
123
124class DecorPixmapReleasePool :
125 public ::testing::Test
126{
127 public:
128
129 DecorPixmapReleasePool () :
130 mockFreeFunc (boost::bind (&XlibPixmapMock::freePixmap,
131 &xlibPixmapMock,
132 _1)),
133 releasePool (mockFreeFunc)
134 {
135 }
136
137 XlibPixmapMock xlibPixmapMock;
138 PixmapReleasePool::FreePixmapFunc mockFreeFunc;
139
140 PixmapReleasePool releasePool;
141};
142
143TEST_F (DecorPixmapReleasePool, MarkUnusedNoFree)
144{
145 /* Never free pixmaps on markUnused */
146
147 EXPECT_CALL (xlibPixmapMock, freePixmap (_)).Times (0);
148
149 releasePool.markUnused (static_cast <Pixmap> (1));
150}
151
152TEST_F (DecorPixmapReleasePool, NoFreeOnPostDeleteIfNotInList)
153{
154 EXPECT_CALL (xlibPixmapMock, freePixmap (_)).Times (0);
155
156 releasePool.destroyUnusedPixmap (static_cast <Pixmap> (1));
157}
158
159TEST_F (DecorPixmapReleasePool, FreeOnPostDeleteIfMarkedUnused)
160{
161 EXPECT_CALL (xlibPixmapMock, freePixmap (1)).Times (1);
162
163 releasePool.markUnused (static_cast <Pixmap> (1));
164 releasePool.destroyUnusedPixmap (static_cast <Pixmap> (1));
165}
166
167TEST_F (DecorPixmapReleasePool, FreeOnPostDeleteIfMarkedUnusedOnceOnly)
168{
169 EXPECT_CALL (xlibPixmapMock, freePixmap (1)).Times (1);
170
171 releasePool.markUnused (static_cast <Pixmap> (1));
172 releasePool.destroyUnusedPixmap (static_cast <Pixmap> (1));
173 releasePool.destroyUnusedPixmap (static_cast <Pixmap> (1));
174}
175
176TEST_F (DecorPixmapReleasePool, UnusedUniqueness)
177{
178 EXPECT_CALL (xlibPixmapMock, freePixmap (1)).Times (1);
179
180 releasePool.markUnused (static_cast <Pixmap> (1));
181 releasePool.markUnused (static_cast <Pixmap> (1));
182 releasePool.destroyUnusedPixmap (static_cast <Pixmap> (1));
183 releasePool.destroyUnusedPixmap (static_cast <Pixmap> (1));
184}
185
186class DecorPendingMessageHandler :
187 public ::testing::Test
188{
189 public:
190
191 DecorPendingMessageHandler () :
192 pendingHandler (boost::bind (&MockFindRequestor::findRequestor,
193 &mockRequestorFind,
194 _1))
195 {
196 }
197
198 MockFindRequestor mockRequestorFind;
199 MockDecorPixmapRequestor mockRequestor;
200
201 cd::PendingHandler pendingHandler;
202};
203
204namespace
205{
206Window mockWindow = 1;
207}
208
209TEST_F (DecorPendingMessageHandler, NoPendingIfNotFound)
210{
211 EXPECT_CALL (mockRequestor, handlePending (_)).Times (0);
212 EXPECT_CALL (mockRequestorFind, findRequestor (mockWindow)).WillOnce (ReturnNull ());
213
214 long data = 1;
215 pendingHandler.handleMessage (mockWindow, &data);
216}
217
218TEST_F (DecorPendingMessageHandler, PendingIfFound)
219{
220 long data = 1;
221
222 EXPECT_CALL (mockRequestor, handlePending (Pointee (data)));
223 EXPECT_CALL (mockRequestorFind, findRequestor (mockWindow)).WillOnce (Return (&mockRequestor));
224
225 pendingHandler.handleMessage (mockWindow, &data);
226}
227
228class DecorUnusedMessageHandler :
229 public ::testing::Test
230{
231 public:
232
233 DecorUnusedMessageHandler () :
234 mockUnusedPixmapQueue (new MockUnusedPixmapQueue ()),
235 unusedHandler (boost::bind (&MockFindList::findList,
236 &mockListFind,
237 _1),
238 mockUnusedPixmapQueue,
239 boost::bind (&XlibPixmapMock::freePixmap,
240 &xlibPixmapMock,
241 _1))
242 {
243 }
244
245 MockFindList mockListFind;
246 MockDecorationListFindMatching mockListFinder;
247 MockUnusedPixmapQueue::Ptr mockUnusedPixmapQueue;
248 XlibPixmapMock xlibPixmapMock;
249
250 cd::UnusedHandler unusedHandler;
251};
252
253namespace
254{
255Pixmap mockPixmap = 2;
256}
257
258TEST_F (DecorUnusedMessageHandler, FreeImmediatelyWindowNotFound)
259{
260 /* Don't verify calls to mockListFind */
261 EXPECT_CALL (mockListFind, findList (_)).Times (AtLeast (0));
262
263 /* Just free the pixmap immediately if no window was found */
264 EXPECT_CALL (xlibPixmapMock, freePixmap (mockPixmap)).Times (1);
265
266 ON_CALL (mockListFind, findList (mockWindow)).WillByDefault (ReturnNull ());
267 unusedHandler.handleMessage (mockWindow, mockPixmap);
268}
269
270TEST_F (DecorUnusedMessageHandler, FreeImmediatelyIfNoDecorationFound)
271{
272 /* Don't verify calls to mockListFind or mockListFinder */
273 EXPECT_CALL (mockListFind, findList (_)).Times (AtLeast (0));
274 EXPECT_CALL (mockListFinder, findMatchingDecoration (_)).Times (AtLeast (0));
275
276 EXPECT_CALL (xlibPixmapMock, freePixmap (mockPixmap)).Times (1);
277
278 ON_CALL (mockListFind, findList (mockWindow))
279 .WillByDefault (Return (&mockListFinder));
280 ON_CALL (mockListFinder, findMatchingDecoration (mockPixmap))
281 .WillByDefault (Return (DecorationInterface::Ptr ()));
282
283 unusedHandler.handleMessage (mockWindow, mockPixmap);
284}
285
286TEST_F (DecorUnusedMessageHandler, AddToQueueIfInUse)
287{
288 /* Don't verify calls to mockListFind or mockListFinder */
289 EXPECT_CALL (mockListFind, findList (_)).Times (AtLeast (0));
290 EXPECT_CALL (mockListFinder, findMatchingDecoration (_)).Times (AtLeast (0));
291
292 DecorationInterface::Ptr mockDecoration (new StubDecoration ());
293
294 /* Do not immediately free the pixmap */
295 EXPECT_CALL (xlibPixmapMock, freePixmap (mockPixmap)).Times (0);
296 EXPECT_CALL (*mockUnusedPixmapQueue, markUnused (mockPixmap)).Times (1);
297
298 ON_CALL (mockListFind, findList (mockWindow))
299 .WillByDefault (Return (&mockListFinder));
300 ON_CALL (mockListFinder, findMatchingDecoration (mockPixmap))
301 .WillByDefault (Return (mockDecoration));
302
303 unusedHandler.handleMessage (mockWindow, mockPixmap);
304}
305
306namespace
307{
308Atom pendingMsg = 3;
309Atom unusedMsg = 4;
310}
311
312class DecorProtocolCommunicator :
313 public ::testing::Test
314{
315 public:
316
317 DecorProtocolCommunicator () :
318 handlePendingFunc (boost::bind (&MockProtocolDispatchFuncs::handlePending,
319 &mockProtoDispatch,
320 _1,
321 _2)),
322 handleUnusedFunc (boost::bind (&MockProtocolDispatchFuncs::handleUnused,
323 &mockProtoDispatch,
324 _1,
325 _2)),
326 protocolCommunicator (pendingMsg,
327 unusedMsg,
328 handlePendingFunc,
329 handleUnusedFunc)
330 {
331 }
332
333 void ClientMessageData (XClientMessageEvent &msg,
334 Window window,
335 Atom atom,
336 long l1,
337 long l2,
338 long l3,
339 long l4)
340 {
341 msg.window = window;
342 msg.message_type = atom;
343 msg.data.l[0] = l1;
344 msg.data.l[1] = l2;
345 msg.data.l[2] = l3;
346 msg.data.l[3] = l4;
347 }
348
349 MockProtocolDispatchFuncs mockProtoDispatch;
350 cdp::PendingMessage handlePendingFunc;
351 cdp::PixmapUnusedMessage handleUnusedFunc;
352
353 cdp::Communicator protocolCommunicator;
354};
355
356MATCHER_P (MatchArray3, v, "Contains values")
357{
358 return arg[0] == v[0] &&
359 arg[1] == v[1] &&
360 arg[2] == v[2];
361}
362
363TEST_F (DecorProtocolCommunicator, TestDispatchToPendingHandler)
364{
365 long data[3];
366
367 data[0] = 1;
368 data[1] = 2;
369 data[2] = 3;
370
371 XClientMessageEvent ev;
372 ClientMessageData (ev,
373 mockWindow,
374 pendingMsg,
375 data[0],
376 data[1],
377 data[2],
378 0);
379
380 EXPECT_CALL (mockProtoDispatch, handlePending (mockWindow,
381 MatchArray3 (data)))
382 .Times (1);
383
384 protocolCommunicator.handleClientMessage (ev);
385}
386
387TEST_F (DecorProtocolCommunicator, TestDispatchToUnusedHandler)
388{
389 XClientMessageEvent ev;
390 ClientMessageData (ev,
391 mockWindow,
392 unusedMsg,
393 mockPixmap,
394 0,
395 0,
396 0);
397
398 EXPECT_CALL (mockProtoDispatch, handleUnused (mockWindow,
399 mockPixmap))
400 .Times (1);
401
402 protocolCommunicator.handleClientMessage (ev);
403}
161404
=== modified file 'tests/system/xorg-gtest/tests/CMakeLists.txt'
--- tests/system/xorg-gtest/tests/CMakeLists.txt 2013-02-19 12:00:19 +0000
+++ tests/system/xorg-gtest/tests/CMakeLists.txt 2013-02-20 07:34:20 +0000
@@ -52,6 +52,6 @@
52 target_link_libraries (compiz_xorg_gtest_test_shape_handling52 target_link_libraries (compiz_xorg_gtest_test_shape_handling
53 ${COMPIZ_XORG_GTEST_LIBRARIES})53 ${COMPIZ_XORG_GTEST_LIBRARIES})
5454
55 compiz_discover_tests (compiz_xorg_gtest_test_shape_handling)55 compiz_discover_tests (compiz_xorg_gtest_test_shape_handling WITH_XORG_GTEST)
5656
57endif (BUILD_XORG_GTEST AND X11_XI_FOUND)57endif (BUILD_XORG_GTEST AND X11_XI_FOUND)

Subscribers

People subscribed via source and target branches