Merge lp:~sil2100/compiz-core/cherry_rev3137 into lp:compiz-core

Proposed by Łukasz Zemczak
Status: Merged
Merged at revision: 3103
Proposed branch: lp:~sil2100/compiz-core/cherry_rev3137
Merge into: lp:compiz-core
Diff against target: 1474 lines (+856/-67)
15 files modified
gtk/window-decorator/decorator.c (+55/-25)
gtk/window-decorator/events.c (+12/-1)
gtk/window-decorator/gtk-window-decorator.c (+9/-0)
gtk/window-decorator/gtk-window-decorator.h (+8/-0)
gtk/window-decorator/wnck.c (+13/-11)
include/decoration.h (+18/-0)
libdecoration/decoration.c (+86/-0)
plugins/decor/CMakeLists.txt (+3/-1)
plugins/decor/src/decor.cpp (+99/-22)
plugins/decor/src/decor.h (+35/-7)
plugins/decor/src/pixmap-requests/CMakeLists.txt (+62/-0)
plugins/decor/src/pixmap-requests/include/pixmap-requests.h (+188/-0)
plugins/decor/src/pixmap-requests/src/pixmap-requests.cpp (+93/-0)
plugins/decor/src/pixmap-requests/tests/CMakeLists.txt (+15/-0)
plugins/decor/src/pixmap-requests/tests/pixmap-requests/src/test-decor-pixmap-requests.cpp (+160/-0)
To merge this branch: bzr merge lp:~sil2100/compiz-core/cherry_rev3137
Reviewer Review Type Date Requested Status
Daniel van Vugt Approve
Review via email: mp+110572@code.launchpad.net

Commit message

Cherry-picked from compiz trunk (rev 3137):
Add synchronization primitives to the decoration protocol so that there isn't a race where we bind a texture that's being freed. (LP: #454218) (LP: #929989)

Description of the change

Cherry picked from 0.9.8 branch:

Add synchronization primitives to the decoration protocol so that there isn't a race where we bind a texture that's being freed.

Things changed

 * update_window_decoration_size made semi-private, users should use request_update_window_decoration_size instead, which prepares for a pixmap update and sends a message to the decorated process that a new pixmap is waiting.
 * decor_post_pending : tells the decorated process that a new decoration is pending
 * decor_post_request : tells the decorator that a new pixmap can be drawn to
 * decor_post_delete_pixmap : tells the decorator that a pixmap is no longer in use by the decorated process and can be deleted by the server

I also did some necessary refactoring so we could get this under test, namely:

DecorPixmap class (implements DecorPixmapInterface): a simple RAII class which ensures that a DecorPixmapDeletionInterface is invoked to delete the server side pixmap when the DecorPixmap class is destructed

X11DecorPixmapReceiver class (implements DecorPixmapReceiverInterface): a per-decoration owned class which tracks the update state of the pixmap owned by the decoration from the decorator, calls through to appropriate methods on a DecorPixmapRequestorInterface to request new pixmaps (ensuring that chattyness is reduced to when a) the decorator tells us that a new pixmap is ready and b) when a new pixmap was already pending and we need to fetch the newest one)

X11DecorPixmapRequestor class (implements DecorPixmapRequestorInterface): a per-window owned class which handles dispatch to the decorator (eg decor_post_pending) and requests from the decorator in _COMPIZ_DECOR_PENDING messages to communicate when decorations should be redrawn at new sizes

X11PixmapDeletor class (implements DecorPixmapDeletionInterface): a per-pixmap class which sends decor_post_delete_pixmap to the decorator when a pixmap is no longer in use by the decor plugin

DecorationListFindMatchingInterface: an interface implemented by DecorationList to find a decoration matching a specified criteria

DecorationInterface: an interface implemented by Decoration to get the receiver and properties about that decoration.

Tests included (Google Mock)

Resubmitted to cover a potential race condition in LP#996901

To post a comment you must log in.
Revision history for this message
Daniel van Vugt (vanvugt) wrote :

I assume the ABI changes here don't affect Unity builds?... Better to ask a silly question now than later :)

Revision history for this message
Łukasz Zemczak (sil2100) wrote :

Good question, it seems they actually might. So hm, this cherry-pick might not be entirely safe. Daniel - could you somehow mark bug-fixes in bug reports which break the ABI? This would make picking changes for SRUs much easier.

Revision history for this message
Daniel van Vugt (vanvugt) wrote :

Yes, we're meant to update abiversion.h so it should be easy to tell. But people often forget :(

Revision history for this message
Daniel van Vugt (vanvugt) wrote :

It works and the bugs appear fixed.

I can't run the test cases for some reason, but that's not caused by this proposal in particular. See bug 1014957.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'gtk/window-decorator/decorator.c'
--- gtk/window-decorator/decorator.c 2012-03-30 07:01:48 +0000
+++ gtk/window-decorator/decorator.c 2012-06-15 17:09:21 +0000
@@ -564,6 +564,52 @@
564 }564 }
565}565}
566566
567/*
568 * request_update_window_decoration_size
569 * Description: asks the rendering process to allow a size update
570 * for pixmap synchronization */
571
572
573gboolean
574request_update_window_decoration_size (WnckWindow *win)
575{
576 decor_t *d;
577 gint width, height;
578 gint x, y, w, h, name_width;
579
580 if (win == NULL)
581 return FALSE;
582
583 d = g_object_get_data (G_OBJECT (win), "decor");
584
585 if (!d->decorated)
586 return FALSE;
587
588 /* Get the geometry of the window, we'll need it later */
589 wnck_window_get_client_window_geometry (win, &x, &y, &w, &h);
590
591 /* Get the width of the name */
592 name_width = max_window_name_width (win);
593
594 /* Ask the theme to tell us how much space it needs. If this is not successful
595 * update the decoration name and return false */
596 if (!(*theme_calc_decoration_size) (d, w, h, name_width, &width, &height))
597 {
598 update_window_decoration_name (win);
599 return FALSE;
600 }
601
602 d->width = width;
603 d->height = height;
604
605 decor_post_pending (gdk_x11_display_get_xdisplay (gdk_display_get_default ()),
606 wnck_window_get_xid (win),
607 populate_frame_type (d),
608 populate_frame_state (d),
609 populate_frame_actions (d));
610
611 return TRUE;
612}
567613
568/*614/*
569 * update_window_decoration_size615 * update_window_decoration_size
@@ -581,8 +627,6 @@
581 decor_t *d;627 decor_t *d;
582 GdkPixmap *pixmap, *buffer_pixmap = NULL;628 GdkPixmap *pixmap, *buffer_pixmap = NULL;
583 Picture picture;629 Picture picture;
584 gint width, height;
585 gint x, y, w, h, name_width;
586 Display *xdisplay;630 Display *xdisplay;
587 XRenderPictFormat *format;631 XRenderPictFormat *format;
588632
@@ -591,30 +635,19 @@
591635
592 d = g_object_get_data (G_OBJECT (win), "decor");636 d = g_object_get_data (G_OBJECT (win), "decor");
593637
638 if (!d->decorated)
639 return FALSE;
640
594 xdisplay = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ());641 xdisplay = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ());
595642
596 /* Get the geometry of the window, we'll need it later */
597 wnck_window_get_client_window_geometry (win, &x, &y, &w, &h);
598
599 /* Get the width of the name */
600 name_width = max_window_name_width (win);
601
602 /* Ask the theme to tell us how much space it needs. If this is not successful
603 * update the decoration name and return false */
604 if (!(*theme_calc_decoration_size) (d, w, h, name_width, &width, &height))
605 {
606 update_window_decoration_name (win);
607 return FALSE;
608 }
609
610 gdk_error_trap_push ();643 gdk_error_trap_push ();
611644
612 /* Get the correct depth for the frame window in reparenting mode, otherwise645 /* Get the correct depth for the frame window in reparenting mode, otherwise
613 * enforce 32 */646 * enforce 32 */
614 if (d->frame_window)647 if (d->frame_window)
615 pixmap = create_pixmap (width, height, d->frame->style_window_rgb);648 pixmap = create_pixmap (d->width, d->height, d->frame->style_window_rgb);
616 else649 else
617 pixmap = create_pixmap (width, height, d->frame->style_window_rgba);650 pixmap = create_pixmap (d->width, d->height, d->frame->style_window_rgba);
618651
619 gdk_flush ();652 gdk_flush ();
620653
@@ -628,9 +661,9 @@
628 gdk_error_trap_push ();661 gdk_error_trap_push ();
629662
630 if (d->frame_window)663 if (d->frame_window)
631 buffer_pixmap = create_pixmap (width, height, d->frame->style_window_rgb);664 buffer_pixmap = create_pixmap (d->width, d->height, d->frame->style_window_rgb);
632 else665 else
633 buffer_pixmap = create_pixmap (width, height, d->frame->style_window_rgba);666 buffer_pixmap = create_pixmap (d->width, d->height, d->frame->style_window_rgba);
634667
635 gdk_flush ();668 gdk_flush ();
636669
@@ -649,7 +682,7 @@
649682
650 /* Destroy the old pixmaps and pictures */683 /* Destroy the old pixmaps and pictures */
651 if (d->pixmap)684 if (d->pixmap)
652 g_object_unref (G_OBJECT (d->pixmap));685 g_hash_table_insert (destroyed_pixmaps_table, GINT_TO_POINTER (GDK_PIXMAP_XID (d->pixmap)), d->pixmap);
653686
654 if (d->buffer_pixmap)687 if (d->buffer_pixmap)
655 g_object_unref (G_OBJECT (d->buffer_pixmap));688 g_object_unref (G_OBJECT (d->buffer_pixmap));
@@ -667,9 +700,6 @@
667700
668 d->picture = picture;701 d->picture = picture;
669702
670 d->width = width;
671 d->height = height;
672
673 d->prop_xid = wnck_window_get_xid (win);703 d->prop_xid = wnck_window_get_xid (win);
674704
675 update_window_decoration_name (win);705 update_window_decoration_name (win);
@@ -1205,7 +1235,7 @@
1205 d->context = NULL;1235 d->context = NULL;
1206 d->width = d->height = 0;1236 d->width = d->height = 0;
12071237
1208 update_window_decoration_size (win);1238 request_update_window_decoration_size (win);
1209 update_event_windows (win);1239 update_event_windows (win);
1210 }1240 }
1211}1241}
12121242
=== modified file 'gtk/window-decorator/events.c'
--- gtk/window-decorator/events.c 2012-03-30 07:01:48 +0000
+++ gtk/window-decorator/events.c 2012-06-15 17:09:21 +0000
@@ -1014,7 +1014,7 @@
1014 update_window_decoration_state (win);1014 update_window_decoration_state (win);
1015 update_window_decoration_actions (win);1015 update_window_decoration_actions (win);
1016 update_window_decoration_icon (win);1016 update_window_decoration_icon (win);
1017 update_window_decoration_size (win);1017 request_update_window_decoration_size (win);
1018 update_event_windows (win);1018 update_event_windows (win);
1019 }1019 }
1020 else1020 else
@@ -1069,6 +1069,17 @@
1069 }1069 }
1070 }1070 }
1071 }1071 }
1072 else if (xevent->xclient.message_type == decor_request_atom)
1073 {
1074 WnckWindow *win = wnck_window_get (xevent->xclient.window);
1075
1076 if (win)
1077 update_window_decoration_size (win);
1078 }
1079 else if (xevent->xclient.message_type == decor_delete_pixmap_atom)
1080 {
1081 g_hash_table_remove (destroyed_pixmaps_table, GINT_TO_POINTER (xevent->xclient.data.l[0]));
1082 }
1072 default:1083 default:
1073 break;1084 break;
1074 }1085 }
10751086
=== modified file 'gtk/window-decorator/gtk-window-decorator.c'
--- gtk/window-decorator/gtk-window-decorator.c 2012-03-30 07:01:48 +0000
+++ gtk/window-decorator/gtk-window-decorator.c 2012-06-15 17:09:21 +0000
@@ -48,6 +48,9 @@
48Atom toolkit_action_atom;48Atom toolkit_action_atom;
49Atom toolkit_action_window_menu_atom;49Atom toolkit_action_window_menu_atom;
50Atom toolkit_action_force_quit_dialog_atom;50Atom toolkit_action_force_quit_dialog_atom;
51Atom decor_request_atom;
52Atom decor_pending_atom;
53Atom decor_delete_pixmap_atom;
5154
52Atom net_wm_state_atom;55Atom net_wm_state_atom;
53Atom net_wm_state_modal_atom;56Atom net_wm_state_modal_atom;
@@ -103,6 +106,7 @@
103GtkWidget *switcher_label;106GtkWidget *switcher_label;
104107
105GHashTable *frame_table;108GHashTable *frame_table;
109GHashTable *destroyed_pixmaps_table;
106GtkWidget *action_menu = NULL;110GtkWidget *action_menu = NULL;
107gboolean action_menu_mapped = FALSE;111gboolean action_menu_mapped = FALSE;
108decor_color_t _title_color[2];112decor_color_t _title_color[2];
@@ -305,6 +309,10 @@
305 net_wm_state_atom = XInternAtom (xdisplay,"_NET_WM_STATE", 0);309 net_wm_state_atom = XInternAtom (xdisplay,"_NET_WM_STATE", 0);
306 net_wm_state_modal_atom = XInternAtom (xdisplay, "_NET_WM_STATE_MODAL", 0);310 net_wm_state_modal_atom = XInternAtom (xdisplay, "_NET_WM_STATE_MODAL", 0);
307311
312 decor_request_atom = XInternAtom (xdisplay, "_COMPIZ_DECOR_REQUEST", 0);
313 decor_pending_atom = XInternAtom (xdisplay, "_COMPIZ_DECOR_PENDING", 0);
314 decor_delete_pixmap_atom = XInternAtom (xdisplay, "_COMPIZ_DECOR_DELETE_PIXMAP", 0);
315
308 status = decor_acquire_dm_session (xdisplay,316 status = decor_acquire_dm_session (xdisplay,
309 gdk_screen_get_number (gdkscreen),317 gdk_screen_get_number (gdkscreen),
310 "gwd", replace, &dm_sn_timestamp);318 "gwd", replace, &dm_sn_timestamp);
@@ -390,6 +398,7 @@
390 xformat_rgb = XRenderFindStandardFormat (xdisplay, PictStandardRGB24);398 xformat_rgb = XRenderFindStandardFormat (xdisplay, PictStandardRGB24);
391399
392 frame_table = g_hash_table_new (NULL, NULL);400 frame_table = g_hash_table_new (NULL, NULL);
401 destroyed_pixmaps_table = g_hash_table_new_full (NULL, NULL, NULL, g_object_unref);
393402
394 if (!create_tooltip_window ())403 if (!create_tooltip_window ())
395 {404 {
396405
=== modified file 'gtk/window-decorator/gtk-window-decorator.h'
--- gtk/window-decorator/gtk-window-decorator.h 2012-03-30 07:01:48 +0000
+++ gtk/window-decorator/gtk-window-decorator.h 2012-06-15 17:09:21 +0000
@@ -306,6 +306,9 @@
306extern Atom toolkit_action_force_quit_dialog_atom;306extern Atom toolkit_action_force_quit_dialog_atom;
307extern Atom net_wm_state_atom;307extern Atom net_wm_state_atom;
308extern Atom net_wm_state_modal_atom;308extern Atom net_wm_state_modal_atom;
309extern Atom decor_request_atom;
310extern Atom decor_pending_atom;
311extern Atom decor_delete_pixmap_atom;
309312
310extern Time dm_sn_timestamp;313extern Time dm_sn_timestamp;
311314
@@ -511,6 +514,7 @@
511514
512/* list of all decorations */515/* list of all decorations */
513extern GHashTable *frame_table;516extern GHashTable *frame_table;
517extern GHashTable *destroyed_pixmaps_table;
514518
515/* action menu */519/* action menu */
516extern GtkWidget *action_menu;520extern GtkWidget *action_menu;
@@ -628,9 +632,13 @@
628void632void
629destroy_bare_frame ();633destroy_bare_frame ();
630634
635/* Don't use directly */
631gboolean636gboolean
632update_window_decoration_size (WnckWindow *win);637update_window_decoration_size (WnckWindow *win);
633638
639gboolean
640request_update_window_decoration_size (WnckWindow *win);
641
634void642void
635update_window_decoration_name (WnckWindow *win);643update_window_decoration_name (WnckWindow *win);
636644
637645
=== modified file 'gtk/window-decorator/wnck.c'
--- gtk/window-decorator/wnck.c 2012-03-30 07:01:48 +0000
+++ gtk/window-decorator/wnck.c 2012-06-15 17:09:21 +0000
@@ -80,7 +80,7 @@
8080
81 if (d->decorated)81 if (d->decorated)
82 {82 {
83 if (!update_window_decoration_size (win))83 if (!request_update_window_decoration_size (win))
84 queue_decor_draw (d);84 queue_decor_draw (d);
85 }85 }
86}86}
@@ -102,7 +102,7 @@
102 d->client_width = width;102 d->client_width = width;
103 d->client_height = height;103 d->client_height = height;
104104
105 update_window_decoration_size (win);105 request_update_window_decoration_size (win);
106 update_event_windows (win);106 update_event_windows (win);
107 }107 }
108 }108 }
@@ -128,7 +128,7 @@
128 if (d->decorated)128 if (d->decorated)
129 {129 {
130 update_window_decoration_state (win);130 update_window_decoration_state (win);
131 if (!update_window_decoration_size (win))131 if (!request_update_window_decoration_size (win))
132 queue_decor_draw (d);132 queue_decor_draw (d);
133133
134 update_event_windows (win);134 update_event_windows (win);
@@ -143,7 +143,7 @@
143 if (d->decorated)143 if (d->decorated)
144 {144 {
145 update_window_decoration_actions (win);145 update_window_decoration_actions (win);
146 if (!update_window_decoration_size (win))146 if (!request_update_window_decoration_size (win))
147 queue_decor_draw (d);147 queue_decor_draw (d);
148148
149 update_event_windows (win);149 update_event_windows (win);
@@ -422,7 +422,7 @@
422 update_window_decoration_state (win);422 update_window_decoration_state (win);
423 update_window_decoration_actions (win);423 update_window_decoration_actions (win);
424 update_window_decoration_icon (win);424 update_window_decoration_icon (win);
425 update_window_decoration_size (win);425 request_update_window_decoration_size (win);
426426
427 update_event_windows (win);427 update_event_windows (win);
428 }428 }
@@ -585,7 +585,7 @@
585 if (win)585 if (win)
586 {586 {
587 d = g_object_get_data (G_OBJECT (win), "decor");587 d = g_object_get_data (G_OBJECT (win), "decor");
588 if (d && d->pixmap)588 if (d)
589 {589 {
590 d->active = wnck_window_is_active (win);590 d->active = wnck_window_is_active (win);
591591
@@ -642,8 +642,9 @@
642 * then we need to redraw the decoration anyways642 * then we need to redraw the decoration anyways
643 * since the image would have changed */643 * since the image would have changed */
644 if (d->win != NULL &&644 if (d->win != NULL &&
645 !update_window_decoration_size (d->win) &&645 !request_update_window_decoration_size (d->win) &&
646 d->decorated)646 d->decorated &&
647 d->pixmap)
647 queue_decor_draw (d);648 queue_decor_draw (d);
648649
649 }650 }
@@ -653,7 +654,7 @@
653 if (win)654 if (win)
654 {655 {
655 d = g_object_get_data (G_OBJECT (win), "decor");656 d = g_object_get_data (G_OBJECT (win), "decor");
656 if (d && d->pixmap)657 if (d)
657 {658 {
658 d->active = wnck_window_is_active (win);659 d->active = wnck_window_is_active (win);
659660
@@ -710,8 +711,9 @@
710 * then we need to redraw the decoration anyways711 * then we need to redraw the decoration anyways
711 * since the image would have changed */712 * since the image would have changed */
712 if (d->win != NULL &&713 if (d->win != NULL &&
713 !update_window_decoration_size (d->win) &&714 !request_update_window_decoration_size (d->win) &&
714 d->decorated)715 d->decorated &&
716 d->pixmap)
715 queue_decor_draw (d);717 queue_decor_draw (d);
716718
717 }719 }
718720
=== modified file 'include/decoration.h'
--- include/decoration.h 2012-02-09 07:48:57 +0000
+++ include/decoration.h 2012-06-15 17:09:21 +0000
@@ -492,6 +492,24 @@
492 XEvent *event,492 XEvent *event,
493 Time dm_sn_timestamp);493 Time dm_sn_timestamp);
494494
495int
496decor_post_pending (Display *xdisplay,
497 Window client,
498 unsigned int frame_state,
499 unsigned int frame_type,
500 unsigned int frame_actions);
501
502int
503decor_post_delete_pixmap (Display *xdisplay,
504 Pixmap pixmap);
505
506int
507decor_post_generate_request (Display *xdisplay,
508 Window client,
509 unsigned int frame_type,
510 unsigned int frame_state,
511 unsigned int frame_actions);
512
495#ifdef __cplusplus513#ifdef __cplusplus
496}514}
497#endif515#endif
498516
=== modified file 'libdecoration/decoration.c'
--- libdecoration/decoration.c 2012-02-27 06:43:04 +0000
+++ libdecoration/decoration.c 2012-06-15 17:09:21 +0000
@@ -2877,6 +2877,92 @@
2877}2877}
28782878
2879int2879int
2880decor_post_pending (Display *xdisplay,
2881 Window client,
2882 unsigned int frame_state,
2883 unsigned int frame_type,
2884 unsigned int frame_actions)
2885{
2886 XEvent event;
2887
2888 Atom decor_pending = XInternAtom (xdisplay, "_COMPIZ_DECOR_PENDING", FALSE);
2889
2890 /* Send a client message indicating that a new
2891 * decoration can be generated for this window
2892 */
2893 event.xclient.type = ClientMessage;
2894 event.xclient.window = client;
2895 event.xclient.message_type = decor_pending;
2896 event.xclient.format = 32;
2897 event.xclient.data.l[0] = frame_type;
2898 event.xclient.data.l[1] = frame_state;
2899 event.xclient.data.l[2] = frame_actions;
2900 event.xclient.data.l[3] = 0;
2901 event.xclient.data.l[4] = 0;
2902
2903 XSendEvent (xdisplay, DefaultRootWindow (xdisplay), 0,
2904 StructureNotifyMask, &event);
2905
2906 return 1;
2907}
2908
2909int
2910decor_post_generate_request (Display *xdisplay,
2911 Window client,
2912 unsigned int frame_type,
2913 unsigned int frame_state,
2914 unsigned int frame_actions)
2915{
2916 XEvent event;
2917
2918 Atom decor_request = XInternAtom (xdisplay, "_COMPIZ_DECOR_REQUEST", FALSE);
2919
2920 /* Send a client message indicating that a new
2921 * decoration can be generated for this window
2922 */
2923 event.xclient.type = ClientMessage;
2924 event.xclient.window = client;
2925 event.xclient.message_type = decor_request;
2926 event.xclient.format = 32;
2927 event.xclient.data.l[0] = frame_type;
2928 event.xclient.data.l[1] = frame_state;
2929 event.xclient.data.l[2] = frame_actions;
2930 event.xclient.data.l[3] = 0;
2931 event.xclient.data.l[4] = 0;
2932
2933 XSendEvent (xdisplay, DefaultRootWindow (xdisplay), 0,
2934 StructureNotifyMask, &event);
2935
2936 return 1;
2937}
2938
2939int
2940decor_post_delete_pixmap (Display *xdisplay,
2941 Pixmap pixmap)
2942{
2943 XEvent event;
2944
2945 Atom decor_delete_pixmap = XInternAtom (xdisplay, "_COMPIZ_DECOR_DELETE_PIXMAP", FALSE);
2946
2947 /* Send a client message indicating that a new
2948 * decoration can be generated for this window
2949 */
2950 event.xclient.type = ClientMessage;
2951 event.xclient.window = DefaultRootWindow (xdisplay);
2952 event.xclient.message_type = decor_delete_pixmap;
2953 event.xclient.format = 32;
2954 event.xclient.data.l[0] = pixmap;
2955 event.xclient.data.l[1] = 0;
2956 event.xclient.data.l[2] = 0;
2957 event.xclient.data.l[3] = 0;
2958 event.xclient.data.l[4] = 0;
2959
2960 XSendEvent (xdisplay, DefaultRootWindow (xdisplay), 0,
2961 StructureNotifyMask, &event);
2962
2963 return 1;
2964}
2965int
2880decor_acquire_dm_session (Display *xdisplay,2966decor_acquire_dm_session (Display *xdisplay,
2881 int screen,2967 int screen,
2882 const char *name,2968 const char *name,
28832969
=== modified file 'plugins/decor/CMakeLists.txt'
--- plugins/decor/CMakeLists.txt 2012-03-30 14:29:18 +0000
+++ plugins/decor/CMakeLists.txt 2012-06-15 17:09:21 +0000
@@ -4,10 +4,12 @@
4include (CompizCommon)4include (CompizCommon)
55
6include_directories (${CMAKE_CURRENT_SOURCE_DIR}/src/clip-groups/include/)6include_directories (${CMAKE_CURRENT_SOURCE_DIR}/src/clip-groups/include/)
7include_directories (${CMAKE_CURRENT_SOURCE_DIR}/src/pixmap-requests/include/)
78
8compiz_plugin(decor PLUGINDEPS composite opengl LIBRARIES decoration compiz_decor_clip_groups)9compiz_plugin(decor PLUGINDEPS composite opengl LIBRARIES decoration compiz_decor_clip_groups compiz_decor_pixmap_requests)
910
10add_subdirectory (src/clip-groups)11add_subdirectory (src/clip-groups)
12add_subdirectory (src/pixmap-requests)
1113
12if (COMPIZ_BUILD_WITH_RPATH AND NOT COMPIZ_DISABLE_PLUGIN_DECOR)14if (COMPIZ_BUILD_WITH_RPATH AND NOT COMPIZ_DISABLE_PLUGIN_DECOR)
1315
1416
=== modified file 'plugins/decor/src/decor.cpp'
--- plugins/decor/src/decor.cpp 2012-04-23 05:50:23 +0000
+++ plugins/decor/src/decor.cpp 2012-06-15 17:09:21 +0000
@@ -303,7 +303,6 @@
303}303}
304304
305static bool bindFailed;305static bool bindFailed;
306
307/*306/*
308 * DecorTexture::DecorTexture307 * DecorTexture::DecorTexture
309 *308 *
@@ -314,7 +313,7 @@
314 * for this pixmap313 * for this pixmap
315 */314 */
316315
317DecorTexture::DecorTexture (Pixmap pixmap) :316DecorTexture::DecorTexture (DecorPixmapInterface::Ptr pixmap) :
318 status (true),317 status (true),
319 refCount (1),318 refCount (1),
320 pixmap (pixmap),319 pixmap (pixmap),
@@ -324,7 +323,7 @@
324 Window root;323 Window root;
325 int i;324 int i;
326325
327 if (!XGetGeometry (screen->dpy (), pixmap, &root,326 if (!XGetGeometry (screen->dpy (), pixmap->getPixmap (), &root,
328 &i, &i, &width, &height, &ui, &depth))327 &i, &i, &width, &height, &ui, &depth))
329 {328 {
330 status = false;329 status = false;
@@ -332,7 +331,7 @@
332 }331 }
333332
334 bindFailed = false;333 bindFailed = false;
335 textures = GLTexture::bindPixmapToTexture (pixmap, width, height, depth);334 textures = GLTexture::bindPixmapToTexture (pixmap->getPixmap (), width, height, depth);
336 if (textures.size () != 1)335 if (textures.size () != 1)
337 {336 {
338 bindFailed = true;337 bindFailed = true;
@@ -343,7 +342,7 @@
343 if (!DecorScreen::get (screen)->optionGetMipmap ())342 if (!DecorScreen::get (screen)->optionGetMipmap ())
344 textures[0]->setMipmap (false);343 textures[0]->setMipmap (false);
345344
346 damage = XDamageCreate (screen->dpy (), pixmap,345 damage = XDamageCreate (screen->dpy (), pixmap->getPixmap (),
347 XDamageReportRawRectangles);346 XDamageReportRawRectangles);
348}347}
349348
@@ -378,13 +377,16 @@
378 return NULL;377 return NULL;
379378
380 foreach (DecorTexture *t, textures)379 foreach (DecorTexture *t, textures)
381 if (t->pixmap == pixmap)380 if (t->pixmap->getPixmap () == pixmap)
382 {381 {
383 t->refCount++;382 t->refCount++;
384 return t;383 return t;
385 }384 }
386385
387 DecorTexture *texture = new DecorTexture (pixmap);386 X11PixmapDeletor::Ptr dl = boost::make_shared <X11PixmapDeletor> (screen->dpy ());
387 DecorPixmap::Ptr pm = boost::make_shared <DecorPixmap> (pixmap, dl);
388
389 DecorTexture *texture = new DecorTexture (boost::shared_static_cast <DecorPixmapInterface> (pm));
388390
389 if (!texture->status)391 if (!texture->status)
390 {392 {
@@ -520,7 +522,8 @@
520 long *prop,522 long *prop,
521 unsigned int size,523 unsigned int size,
522 unsigned int type,524 unsigned int type,
523 unsigned int nOffset)525 unsigned int nOffset,
526 DecorPixmapRequestorInterface *requestor)
524{527{
525 unsigned int frameType, frameState, frameActions;528 unsigned int frameType, frameState, frameActions;
526 Pixmap pixmap = None;529 Pixmap pixmap = None;
@@ -568,7 +571,7 @@
568 throw std::exception ();571 throw std::exception ();
569 }572 }
570573
571 return Decoration::Ptr (new Decoration (type, border, input, maxBorder, maxInput, frameType, frameState, frameActions, minWidth, minHeight, pixmap, quad, nQuad));574 return Decoration::Ptr (new Decoration (type, border, input, maxBorder, maxInput, frameType, frameState, frameActions, minWidth, minHeight, pixmap, quad, nQuad, id, requestor));
572}575}
573576
574Decoration::Decoration (int type,577Decoration::Decoration (int type,
@@ -583,7 +586,9 @@
583 unsigned int minHeight,586 unsigned int minHeight,
584 Pixmap pixmap,587 Pixmap pixmap,
585 const boost::shared_array <decor_quad_t> &quad,588 const boost::shared_array <decor_quad_t> &quad,
586 unsigned int nQuad) :589 unsigned int nQuad,
590 Window owner,
591 DecorPixmapRequestorInterface *requestor) :
587 texture (DecorScreen::get (screen)->getTexture (pixmap)),592 texture (DecorScreen::get (screen)->getTexture (pixmap)),
588 border (border.left, border.right, border.top, border.bottom),593 border (border.left, border.right, border.top, border.bottom),
589 input (input.left, input.right, input.top, input.bottom),594 input (input.left, input.right, input.top, input.bottom),
@@ -596,7 +601,9 @@
596 frameActions (frameActions),601 frameActions (frameActions),
597 quad (quad),602 quad (quad),
598 nQuad (nQuad),603 nQuad (nQuad),
599 type (type)604 type (type),
605 updateState (0),
606 mPixmapReceiver (requestor, this)
600{607{
601 int left, right, top, bottom;608 int left, right, top, bottom;
602 int x1, y1, x2, y2;609 int x1, y1, x2, y2;
@@ -657,6 +664,30 @@
657 DecorScreen::get (screen)->releaseTexture (texture);664 DecorScreen::get (screen)->releaseTexture (texture);
658}665}
659666
667DecorPixmapReceiverInterface &
668Decoration::receiverInterface ()
669{
670 return mPixmapReceiver;
671}
672
673unsigned int
674Decoration::getFrameType () const
675{
676 return frameType;
677}
678
679unsigned int
680Decoration::getFrameState () const
681{
682 return frameState;
683}
684
685unsigned int
686Decoration::getFrameActions () const
687{
688 return frameActions;
689}
690
660/*691/*
661 * DecorationList is a class which allows multiple decorations692 * DecorationList is a class which allows multiple decorations
662 * to be stored in a list and read from a window property, which693 * to be stored in a list and read from a window property, which
@@ -692,7 +723,8 @@
692723
693bool724bool
694DecorationList::updateDecoration (Window id,725DecorationList::updateDecoration (Window id,
695 Atom decorAtom)726 Atom decorAtom,
727 DecorPixmapRequestorInterface *requestor)
696{728{
697 unsigned long n, nleft;729 unsigned long n, nleft;
698 unsigned char *data;730 unsigned char *data;
@@ -701,6 +733,12 @@
701 int result, format;733 int result, format;
702 unsigned int type;734 unsigned int type;
703735
736 /* Dispatch any new updates */
737 foreach (const Decoration::Ptr &d, mList)
738 {
739 d->mPixmapReceiver.update ();
740 }
741
704 result = XGetWindowProperty (screen->dpy (), id,742 result = XGetWindowProperty (screen->dpy (), id,
705 decorAtom, 0L,743 decorAtom, 0L,
706 PROP_HEADER_SIZE + 6 * (BASE_PROP_SIZE +744 PROP_HEADER_SIZE + 6 * (BASE_PROP_SIZE +
@@ -770,7 +808,9 @@
770 maxBorder.top = d->maxBorder.top;808 maxBorder.top = d->maxBorder.top;
771 maxBorder.bottom = d->maxBorder.bottom;809 maxBorder.bottom = d->maxBorder.bottom;
772810
773 int num = decor_match_pixmap (prop, n, &d->texture->pixmap, &input, &border, &maxInput, &maxBorder,811 Pixmap pm = d->texture->pixmap->getPixmap ();
812
813 int num = decor_match_pixmap (prop, n, &pm, &input, &border, &maxInput, &maxBorder,
774 d->minWidth, d->minHeight, d->frameType, d->frameState, d->frameActions,814 d->minWidth, d->minHeight, d->frameType, d->frameState, d->frameActions,
775 d->quad.get (), d->nQuad);815 d->quad.get (), d->nQuad);
776 if (num != -1)816 if (num != -1)
@@ -788,7 +828,7 @@
788 try828 try
789 {829 {
790 std::list <Decoration::Ptr>::iterator it = mList.begin ();830 std::list <Decoration::Ptr>::iterator it = mList.begin ();
791 Decoration::Ptr d = Decoration::create (id, prop, n, type, i);831 Decoration::Ptr d = Decoration::create (id, prop, n, type, i, requestor);
792832
793 /* Try to replace an existing decoration */833 /* Try to replace an existing decoration */
794 for (; it != mList.end (); it++)834 for (; it != mList.end (); it++)
@@ -873,7 +913,7 @@
873{913{
874 bindFailed = false;914 bindFailed = false;
875915
876 decor.updateDecoration (window->id (), dScreen->winDecorAtom);916 decor.updateDecoration (window->id (), dScreen->winDecorAtom, &mRequestor);
877 if (bindFailed)917 if (bindFailed)
878 pixmapFailed = true;918 pixmapFailed = true;
879 else919 else
@@ -1230,6 +1270,22 @@
1230 return (decorActions == 0);1270 return (decorActions == 0);
1231}1271}
12321272
1273DecorationInterface::Ptr
1274DecorationList::findMatchingDecoration (unsigned int frameType,
1275 unsigned int frameState,
1276 unsigned int frameActions)
1277{
1278 foreach (const Decoration::Ptr &d, mList)
1279 {
1280 if (d->frameType == frameType &&
1281 d->frameState == frameState &&
1282 d->frameActions == frameActions)
1283 return boost::shared_static_cast <DecorationInterface> (d);
1284 }
1285
1286 return DecorationInterface::Ptr ();
1287}
1288
1233/*1289/*
1234 * DecorationList::findMatchingDecoration1290 * DecorationList::findMatchingDecoration
1235 *1291 *
@@ -2053,7 +2109,7 @@
2053 {2109 {
2054 for (i = 0; i < DECOR_NUM; i++)2110 for (i = 0; i < DECOR_NUM; i++)
2055 {2111 {
2056 decor[i].updateDecoration (screen->root (), decorAtom[i]);2112 decor[i].updateDecoration (screen->root (), decorAtom[i], &mRequestor);
2057 }2113 }
2058 }2114 }
2059 else2115 else
@@ -2261,6 +2317,7 @@
2261 isSwitcher = false;2317 isSwitcher = false;
2262}2318}
22632319
2320
2264/*2321/*
2265 * DecorScreen::handleEvent2322 * DecorScreen::handleEvent
2266 *2323 *
@@ -2295,6 +2352,18 @@
2295 if (w)2352 if (w)
2296 DecorWindow::get (w)->update (true);2353 DecorWindow::get (w)->update (true);
2297 }2354 }
2355 /* A decoration is pending creation, allow it to be created */
2356 if (event->xclient.message_type == decorPendingAtom)
2357 {
2358 CompWindow *w = screen->findWindow (event->xclient.window);
2359
2360 if (w)
2361 {
2362 DecorWindow *dw = DecorWindow::get (w);
2363
2364 dw->mRequestor.handlePending (event->xclient.data.l);
2365 }
2366 }
2298 default:2367 default:
2299 /* Check for damage events. If the output or input window2368 /* Check for damage events. If the output or input window
2300 * or a texture is updated then damage output extents.2369 * or a texture is updated then damage output extents.
@@ -2309,7 +2378,7 @@
23092378
2310 foreach (DecorTexture *t, textures)2379 foreach (DecorTexture *t, textures)
2311 {2380 {
2312 if (t->pixmap == de->drawable)2381 if (t->pixmap->getPixmap () == de->drawable)
2313 {2382 {
2314 foreach (CompWindow *w, screen->windows ())2383 foreach (CompWindow *w, screen->windows ())
2315 {2384 {
@@ -2368,7 +2437,6 @@
2368 {2437 {
2369 DECOR_WINDOW (w);2438 DECOR_WINDOW (w);
2370 dw->updateDecoration ();2439 dw->updateDecoration ();
2371
2372 dw->update (true);2440 dw->update (true);
2373 }2441 }
2374 }2442 }
@@ -2401,7 +2469,8 @@
2401 if (event->xproperty.atom == decorAtom[i])2469 if (event->xproperty.atom == decorAtom[i])
2402 {2470 {
2403 decor[i].updateDecoration (screen->root (),2471 decor[i].updateDecoration (screen->root (),
2404 decorAtom[i]);2472 decorAtom[i],
2473 &mRequestor);
24052474
2406 foreach (CompWindow *w, screen->windows ())2475 foreach (CompWindow *w, screen->windows ())
2407 DecorWindow::get (w)->update (true);2476 DecorWindow::get (w)->update (true);
@@ -2935,8 +3004,11 @@
2935 0,3004 0,
2936 None,3005 None,
2937 boost::shared_array <decor_quad_t> (NULL),3006 boost::shared_array <decor_quad_t> (NULL),
2938 0)),3007 0,
2939 mMenusClipGroup (CompMatch ("type=Dock | type=DropdownMenu | type=PopupMenu"))3008 screen->root (),
3009 NULL)),
3010 mMenusClipGroup (CompMatch ("type=Dock | type=DropdownMenu | type=PopupMenu")),
3011 mRequestor (screen->dpy (), screen->root (), &(decor[DECOR_ACTIVE]))
2940{3012{
2941 supportingDmCheckAtom =3013 supportingDmCheckAtom =
2942 XInternAtom (s->dpy (), DECOR_SUPPORTING_DM_CHECK_ATOM_NAME, 0);3014 XInternAtom (s->dpy (), DECOR_SUPPORTING_DM_CHECK_ATOM_NAME, 0);
@@ -2958,6 +3030,10 @@
2958 XInternAtom (s->dpy (), DECOR_TYPE_WINDOW_ATOM_NAME, 0);3030 XInternAtom (s->dpy (), DECOR_TYPE_WINDOW_ATOM_NAME, 0);
2959 decorSwitchWindowAtom =3031 decorSwitchWindowAtom =
2960 XInternAtom (s->dpy (), DECOR_SWITCH_WINDOW_ATOM_NAME, 0);3032 XInternAtom (s->dpy (), DECOR_SWITCH_WINDOW_ATOM_NAME, 0);
3033 decorPendingAtom =
3034 XInternAtom (s->dpy (), "_COMPIZ_DECOR_PENDING", 0);
3035 decorRequestAtom =
3036 XInternAtom (s->dpy (), "_COMPIZ_DECOR_REQUEST", 0);
2961 requestFrameExtentsAtom =3037 requestFrameExtentsAtom =
2962 XInternAtom (s->dpy (), "_NET_REQUEST_FRAME_EXTENTS", 0);3038 XInternAtom (s->dpy (), "_NET_REQUEST_FRAME_EXTENTS", 0);
2963 shadowColorAtom =3039 shadowColorAtom =
@@ -3013,7 +3089,8 @@
3013 frameExtentsRequested (false),3089 frameExtentsRequested (false),
3014 mClipGroup (NULL),3090 mClipGroup (NULL),
3015 mOutputRegion (window->outputRect ()),3091 mOutputRegion (window->outputRect ()),
3016 mInputRegion (window->inputRect ())3092 mInputRegion (window->inputRect ()),
3093 mRequestor (screen->dpy (), w->id (), &decor)
3017{3094{
3018 WindowInterface::setHandler (window);3095 WindowInterface::setHandler (window);
30193096
30203097
=== modified file 'plugins/decor/src/decor.h'
--- plugins/decor/src/decor.h 2012-04-23 05:50:23 +0000
+++ plugins/decor/src/decor.h 2012-06-15 17:09:21 +0000
@@ -25,6 +25,7 @@
2525
26#include <boost/shared_ptr.hpp>26#include <boost/shared_ptr.hpp>
27#include <boost/shared_array.hpp>27#include <boost/shared_array.hpp>
28#include <boost/make_shared.hpp>
28#include <core/window.h>29#include <core/window.h>
29#include <core/pluginclasshandler.h>30#include <core/pluginclasshandler.h>
3031
@@ -34,6 +35,7 @@
34#include <core/windowextents.h>35#include <core/windowextents.h>
3536
36#include <clip-groups.h>37#include <clip-groups.h>
38#include <pixmap-requests.h>
3739
38#include "decor_options.h"40#include "decor_options.h"
3941
@@ -76,30 +78,36 @@
76class DecorTexture {78class DecorTexture {
7779
78 public:80 public:
79 DecorTexture (Pixmap pixmap);81 DecorTexture (DecorPixmapInterface::Ptr pixmap);
80 ~DecorTexture ();82 ~DecorTexture ();
8183
82 public:84 public:
83 bool status;85 bool status;
84 int refCount;86 int refCount;
85 Pixmap pixmap;87 DecorPixmapInterface::Ptr pixmap;
86 Damage damage;88 Damage damage;
87 GLTexture::List textures;89 GLTexture::List textures;
88};90};
8991
90class DecorWindow;92class DecorWindow;
9193
92class Decoration {94class Decoration :
95 public DecorationInterface
96{
9397
94 public:98 public:
9599
96 typedef boost::shared_ptr <Decoration> Ptr;100 typedef boost::shared_ptr <Decoration> Ptr;
97101
102 static const unsigned int UpdateRequested = 1 << 0;
103 static const unsigned int UpdatesPending = 1 << 1;
104
98 static Decoration::Ptr create (Window id,105 static Decoration::Ptr create (Window id,
99 long *prop,106 long *prop,
100 unsigned int size,107 unsigned int size,
101 unsigned int type,108 unsigned int type,
102 unsigned int nOffset);109 unsigned int nOffset,
110 DecorPixmapRequestorInterface *requestor);
103111
104 Decoration (int type,112 Decoration (int type,
105 const decor_extents_t &border,113 const decor_extents_t &border,
@@ -113,10 +121,18 @@
113 unsigned int minHeight,121 unsigned int minHeight,
114 Pixmap pixmap,122 Pixmap pixmap,
115 const boost::shared_array <decor_quad_t> &quad,123 const boost::shared_array <decor_quad_t> &quad,
116 unsigned int nQuad);124 unsigned int nQuad,
125 Window owner,
126 DecorPixmapRequestorInterface *);
117127
118 ~Decoration ();128 ~Decoration ();
119129
130 DecorPixmapReceiverInterface & receiverInterface ();
131
132 unsigned int getFrameType () const;
133 unsigned int getFrameState () const;
134 unsigned int getFrameActions () const;
135
120 public:136 public:
121 int refCount;137 int refCount;
122 DecorTexture *texture;138 DecorTexture *texture;
@@ -133,12 +149,19 @@
133 boost::shared_array <decor_quad_t> quad;149 boost::shared_array <decor_quad_t> quad;
134 int nQuad;150 int nQuad;
135 int type;151 int type;
152
153 unsigned int updateState;
154 X11DecorPixmapReceiver mPixmapReceiver;
136};155};
137156
138class DecorationList157class DecorationList :
158 public DecorationListFindMatchingInterface
139{159{
140 public:160 public:
141 bool updateDecoration (Window id, Atom decorAtom);161 bool updateDecoration (Window id, Atom decorAtom, DecorPixmapRequestorInterface *requestor);
162 DecorationInterface::Ptr findMatchingDecoration(unsigned int frameType,
163 unsigned int frameState,
164 unsigned int frameActions);
142 const Decoration::Ptr & findMatchingDecoration (CompWindow *w, bool sizeCheck);165 const Decoration::Ptr & findMatchingDecoration (CompWindow *w, bool sizeCheck);
143 void clear ()166 void clear ()
144 {167 {
@@ -215,6 +238,8 @@
215 Atom shadowColorAtom;238 Atom shadowColorAtom;
216 Atom shadowInfoAtom;239 Atom shadowInfoAtom;
217 Atom decorSwitchWindowAtom;240 Atom decorSwitchWindowAtom;
241 Atom decorPendingAtom;
242 Atom decorRequestAtom;
218243
219 Window dmWin;244 Window dmWin;
220 int dmSupports;245 int dmSupports;
@@ -229,6 +254,7 @@
229 CompTimer decoratorStart;254 CompTimer decoratorStart;
230255
231 MatchedDecorClipGroup mMenusClipGroup;256 MatchedDecorClipGroup mMenusClipGroup;
257 X11DecorPixmapRequestor mRequestor;
232};258};
233259
234class DecorWindow :260class DecorWindow :
@@ -335,6 +361,8 @@
335 DecorClipGroupInterface *mClipGroup;361 DecorClipGroupInterface *mClipGroup;
336 CompRegion mOutputRegion;362 CompRegion mOutputRegion;
337 CompRegion mInputRegion;363 CompRegion mInputRegion;
364
365 X11DecorPixmapRequestor mRequestor;
338};366};
339367
340class DecorPluginVTable :368class DecorPluginVTable :
341369
=== added directory 'plugins/decor/src/pixmap-requests'
=== added file 'plugins/decor/src/pixmap-requests/CMakeLists.txt'
--- plugins/decor/src/pixmap-requests/CMakeLists.txt 1970-01-01 00:00:00 +0000
+++ plugins/decor/src/pixmap-requests/CMakeLists.txt 2012-06-15 17:09:21 +0000
@@ -0,0 +1,62 @@
1pkg_check_modules (
2 GLIBMM
3 REQUIRED
4 glibmm-2.4 glib-2.0
5)
6
7INCLUDE_DIRECTORIES (
8 ${CMAKE_CURRENT_SOURCE_DIR}/include
9 ${CMAKE_CURRENT_SOURCE_DIR}/src
10
11 ${compiz_SOURCE_DIR}/src/point/include
12 ${compiz_SOURCE_DIR}/src/rect/include
13 ${compiz_SOURCE_DIR}/src/window/geometry/include
14 ${compiz_SOURCE_DIR}/src/window/geometry-saver/include
15 ${compiz_SOURCE_DIR}/src/window/extents/include
16 ${compiz_SOURCE_DIR}/include
17
18 ${Boost_INCLUDE_DIRS}
19
20 ${GLIBMM_INCLUDE_DIRS}
21)
22
23LINK_DIRECTORIES (${GLIBMM_LIBRARY_DIRS})
24
25SET (
26 PUBLIC_HEADERS
27)
28
29SET (
30 PRIVATE_HEADERS
31 ${CMAKE_CURRENT_SOURCE_DIR}/include/pixmap-requests.h
32)
33
34SET(
35 SRCS
36 ${CMAKE_CURRENT_SOURCE_DIR}/src/pixmap-requests.cpp
37)
38
39ADD_LIBRARY(
40 compiz_decor_pixmap_requests STATIC
41
42 ${SRCS}
43
44 ${PUBLIC_HEADERS}
45 ${PRIVATE_HEADERS}
46)
47
48if (COMPIZ_BUILD_TESTING)
49ADD_SUBDIRECTORY( ${CMAKE_CURRENT_SOURCE_DIR}/tests )
50endif (COMPIZ_BUILD_TESTING)
51
52SET_TARGET_PROPERTIES(
53 compiz_decor_pixmap_requests PROPERTIES
54 PUBLIC_HEADER "${PUBLIC_HEADERS}"
55)
56
57TARGET_LINK_LIBRARIES(
58 compiz_decor_pixmap_requests
59
60 compiz_core
61 ${GLIBMM_LIBRARIES}
62)
063
=== added directory 'plugins/decor/src/pixmap-requests/include'
=== added file 'plugins/decor/src/pixmap-requests/include/pixmap-requests.h'
--- plugins/decor/src/pixmap-requests/include/pixmap-requests.h 1970-01-01 00:00:00 +0000
+++ plugins/decor/src/pixmap-requests/include/pixmap-requests.h 2012-06-15 17:09:21 +0000
@@ -0,0 +1,188 @@
1/*
2 * Copyright © 2005 Novell, Inc.
3 *
4 * Permission to use, copy, modify, distribute, and sell this software
5 * and its documentation for any purpose is hereby granted without
6 * fee, provided that the above copyright notice appear in all copies
7 * and that both that copyright notice and this permission notice
8 * appear in supporting documentation, and that the name of
9 * Novell, Inc. not be used in advertising or publicity pertaining to
10 * distribution of the software without specific, written prior permission.
11 * Novell, Inc. makes no representations about the suitability of this
12 * software for any purpose. It is provided "as is" without express or
13 * implied warranty.
14 *
15 * NOVELL, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
16 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
17 * NO EVENT SHALL NOVELL, INC. BE LIABLE FOR ANY SPECIAL, INDIRECT OR
18 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
19 * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
20 * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
21 * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
22 *
23 * Author: David Reveman <davidr@novell.com>
24 */
25
26#ifndef _COMPIZ_DECOR_PIXMAP_REQUESTS_H
27#define _COMPIZ_DECOR_PIXMAP_REQUESTS_H
28
29#include <boost/shared_ptr.hpp>
30#include <boost/shared_array.hpp>
31#include <boost/make_shared.hpp>
32#include <decoration.h>
33
34#include <X11/Xlib.h>
35
36class DecorPixmapInterface
37{
38 public:
39
40 typedef boost::shared_ptr <DecorPixmapInterface> Ptr;
41
42 virtual ~DecorPixmapInterface () {};
43
44 virtual Pixmap getPixmap () = 0;
45};
46
47class DecorPixmapReceiverInterface
48{
49 public:
50
51 virtual ~DecorPixmapReceiverInterface () {}
52
53 virtual void pending () = 0;
54 virtual void update () = 0;
55};
56
57/* So far, nothing particularly interesting here
58 * we just need a way to pass around pointers for
59 * testing */
60class DecorationInterface
61{
62 public:
63
64 typedef boost::shared_ptr <DecorationInterface> Ptr;
65
66 virtual ~DecorationInterface () {}
67
68 virtual DecorPixmapReceiverInterface & receiverInterface () = 0;
69 virtual unsigned int getFrameType () const = 0;
70 virtual unsigned int getFrameState () const = 0;
71 virtual unsigned int getFrameActions () const = 0;
72};
73
74class DecorPixmapDeletionInterface
75{
76 public:
77
78 typedef boost::shared_ptr <DecorPixmapDeletionInterface> Ptr;
79
80 virtual ~DecorPixmapDeletionInterface () {}
81
82 virtual int postDeletePixmap (Pixmap pixmap) = 0;
83};
84
85class X11PixmapDeletor :
86 public DecorPixmapDeletionInterface
87{
88 public:
89
90 typedef boost::shared_ptr <X11PixmapDeletor> Ptr;
91
92 X11PixmapDeletor (Display *dpy) :
93 mDisplay (dpy)
94 {
95 }
96
97 int postDeletePixmap (Pixmap pixmap) { return decor_post_delete_pixmap (mDisplay, pixmap); }
98
99 private:
100
101 Display *mDisplay;
102};
103
104class DecorPixmap :
105 public DecorPixmapInterface
106{
107 public:
108
109 typedef boost::shared_ptr <DecorPixmap> Ptr;
110
111 DecorPixmap (Pixmap p, DecorPixmapDeletionInterface::Ptr deletor);
112 ~DecorPixmap ();
113
114 Pixmap getPixmap ();
115
116 private:
117
118 Pixmap mPixmap;
119 DecorPixmapDeletionInterface::Ptr mDeletor;
120};
121
122class DecorPixmapRequestorInterface
123{
124 public:
125
126 virtual ~DecorPixmapRequestorInterface () {}
127
128 virtual int postGenerateRequest (unsigned int frameType,
129 unsigned int frameState,
130 unsigned int frameActions) = 0;
131
132 virtual void handlePending (long *data) = 0;
133};
134
135class DecorationListFindMatchingInterface
136{
137 public:
138
139 virtual ~DecorationListFindMatchingInterface () {}
140
141 virtual DecorationInterface::Ptr findMatchingDecoration (unsigned int frameType,
142 unsigned int frameState,
143 unsigned int frameActions) = 0;
144};
145
146class X11DecorPixmapRequestor :
147 public DecorPixmapRequestorInterface
148{
149 public:
150
151 X11DecorPixmapRequestor (Display *dpy,
152 Window xid,
153 DecorationListFindMatchingInterface *listFinder);
154
155 int postGenerateRequest (unsigned int frameType,
156 unsigned int frameState,
157 unsigned int frameActions);
158
159 void handlePending (long *data);
160
161 private:
162
163 Display *mDpy;
164 Window mWindow;
165 DecorationListFindMatchingInterface *mListFinder;
166};
167
168class X11DecorPixmapReceiver :
169 public DecorPixmapReceiverInterface
170{
171 public:
172
173 static const unsigned int UpdateRequested = 1 << 0;
174 static const unsigned int UpdatesPending = 1 << 1;
175
176 X11DecorPixmapReceiver (DecorPixmapRequestorInterface *,
177 DecorationInterface *decor);
178
179 void pending ();
180 void update ();
181 private:
182
183 unsigned int mUpdateState;
184 DecorPixmapRequestorInterface *mDecorPixmapRequestor;
185 DecorationInterface *mDecoration;
186};
187
188#endif
0189
=== added directory 'plugins/decor/src/pixmap-requests/src'
=== added file 'plugins/decor/src/pixmap-requests/src/pixmap-requests.cpp'
--- plugins/decor/src/pixmap-requests/src/pixmap-requests.cpp 1970-01-01 00:00:00 +0000
+++ plugins/decor/src/pixmap-requests/src/pixmap-requests.cpp 2012-06-15 17:09:21 +0000
@@ -0,0 +1,93 @@
1#include "pixmap-requests.h"
2#include <boost/foreach.hpp>
3#include <algorithm>
4
5#ifndef foreach
6#define foreach BOOST_FOREACH
7#endif
8
9DecorPixmap::DecorPixmap (Pixmap pixmap, DecorPixmapDeletionInterface::Ptr d) :
10 mPixmap (pixmap),
11 mDeletor (d)
12{
13}
14
15DecorPixmap::~DecorPixmap ()
16{
17 mDeletor->postDeletePixmap (mPixmap);
18}
19
20Pixmap
21DecorPixmap::getPixmap ()
22{
23 return mPixmap;
24}
25
26X11DecorPixmapReceiver::X11DecorPixmapReceiver (DecorPixmapRequestorInterface *requestor,
27 DecorationInterface *decor) :
28 mUpdateState (0),
29 mDecorPixmapRequestor (requestor),
30 mDecoration (decor)
31{
32}
33
34void
35X11DecorPixmapReceiver::pending ()
36{
37 if (mUpdateState & X11DecorPixmapReceiver::UpdateRequested)
38 mUpdateState |= X11DecorPixmapReceiver::UpdatesPending;
39 else
40 {
41 mUpdateState |= X11DecorPixmapReceiver::UpdateRequested;
42
43 mDecorPixmapRequestor->postGenerateRequest (mDecoration->getFrameType (),
44 mDecoration->getFrameState (),
45 mDecoration->getFrameActions ());
46 }
47}
48
49void X11DecorPixmapReceiver::update ()
50{
51 if (mUpdateState & X11DecorPixmapReceiver::UpdatesPending)
52 mDecorPixmapRequestor->postGenerateRequest (mDecoration->getFrameType (),
53 mDecoration->getFrameState (),
54 mDecoration->getFrameActions ());
55
56 mUpdateState = 0;
57}
58
59X11DecorPixmapRequestor::X11DecorPixmapRequestor (Display *dpy,
60 Window window,
61 DecorationListFindMatchingInterface *listFinder) :
62 mDpy (dpy),
63 mWindow (window),
64 mListFinder (listFinder)
65{
66}
67
68int
69X11DecorPixmapRequestor::postGenerateRequest (unsigned int frameType,
70 unsigned int frameState,
71 unsigned int frameActions)
72{
73 return decor_post_generate_request (mDpy,
74 mWindow,
75 frameType,
76 frameState,
77 frameActions);
78}
79
80void
81X11DecorPixmapRequestor::handlePending (long *data)
82{
83 DecorationInterface::Ptr d = mListFinder->findMatchingDecoration (static_cast <unsigned int> (data[0]),
84 static_cast <unsigned int> (data[1]),
85 static_cast <unsigned int> (data[2]));
86
87 if (d)
88 d->receiverInterface ().pending ();
89 else
90 postGenerateRequest (static_cast <unsigned int> (data[0]),
91 static_cast <unsigned int> (data[1]),
92 static_cast <unsigned int> (data[2]));
93}
094
=== added directory 'plugins/decor/src/pixmap-requests/tests'
=== added file 'plugins/decor/src/pixmap-requests/tests/CMakeLists.txt'
--- plugins/decor/src/pixmap-requests/tests/CMakeLists.txt 1970-01-01 00:00:00 +0000
+++ plugins/decor/src/pixmap-requests/tests/CMakeLists.txt 2012-06-15 17:09:21 +0000
@@ -0,0 +1,15 @@
1include_directories(${CMAKE_CURRENT_SOURCE_DIR})
2
3add_executable (compiz_test_decor_pixmap_requests
4 ${CMAKE_CURRENT_SOURCE_DIR}/pixmap-requests/src/test-decor-pixmap-requests.cpp)
5
6target_link_libraries (compiz_test_decor_pixmap_requests
7 compiz_decor_pixmap_requests
8 decoration
9 ${GTEST_BOTH_LIBRARIES}
10 ${GMOCK_LIBRARY}
11 ${GMOCK_MAIN_LIBRARY}
12 ${CMAKE_THREAD_LIBS_INIT} # Link in pthread.
13 )
14
15gtest_add_tests (compiz_test_decor_pixmap_requests "" ${CMAKE_CURRENT_SOURCE_DIR}/pixmap-requests/src/test-decor-pixmap-requests.cpp)
016
=== added directory 'plugins/decor/src/pixmap-requests/tests/pixmap-requests'
=== added directory 'plugins/decor/src/pixmap-requests/tests/pixmap-requests/src'
=== added file 'plugins/decor/src/pixmap-requests/tests/pixmap-requests/src/test-decor-pixmap-requests.cpp'
--- plugins/decor/src/pixmap-requests/tests/pixmap-requests/src/test-decor-pixmap-requests.cpp 1970-01-01 00:00:00 +0000
+++ plugins/decor/src/pixmap-requests/tests/pixmap-requests/src/test-decor-pixmap-requests.cpp 2012-06-15 17:09:21 +0000
@@ -0,0 +1,160 @@
1/*
2 * Copyright © 2012 Canonical Ltd.
3 *
4 * Permission to use, copy, modify, distribute, and sell this software
5 * and its documentation for any purpose is hereby granted without
6 * fee, provided that the above copyright notice appear in all copies
7 * and that both that copyright notice and this permission notice
8 * appear in supporting documentation, and that the name of
9 * Canonical Ltd. not be used in advertising or publicity pertaining to
10 * distribution of the software without specific, written prior permission.
11 * Canonical Ltd. makes no representations about the suitability of this
12 * software for any purpose. It is provided "as is" without express or
13 * implied warranty.
14 *
15 * CANONICAL, LTD. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
16 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
17 * NO EVENT SHALL CANONICAL, LTD. BE LIABLE FOR ANY SPECIAL, INDIRECT OR
18 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
19 * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
20 * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
21 * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
22 *
23 * Authored by: Sam Spilsbury <sam.spilsbury@canonical.com>
24 */
25
26#include <gtest/gtest.h>
27#include <gmock/gmock.h>
28#include <iostream>
29#include "pixmap-requests.h"
30
31using ::testing::Return;
32
33class DecorPixmapRequestsTest :
34 public ::testing::Test
35{
36};
37
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};
82
83TEST(DecorPixmapRequestsTest, TestDestroyPixmapDeletes)
84{
85 boost::shared_ptr <MockDecorPixmapDeletor> mockDeletor = boost::make_shared <MockDecorPixmapDeletor> ();
86 DecorPixmap pm (1, boost::shared_static_cast<DecorPixmapDeletionInterface> (mockDeletor));
87
88 EXPECT_CALL (*(mockDeletor.get ()), postDeletePixmap (1)).WillOnce (Return (1));
89}
90
91TEST(DecorPixmapRequestsTest, TestPendingGeneratesRequest)
92{
93 MockDecorPixmapRequestor mockRequestor;
94 MockDecoration mockDecoration;
95 X11DecorPixmapReceiver receiver (&mockRequestor, &mockDecoration);
96
97 EXPECT_CALL (mockDecoration, getFrameActions ()).WillOnce (Return (3));
98 EXPECT_CALL (mockDecoration, getFrameState ()).WillOnce (Return (2));
99 EXPECT_CALL (mockDecoration, getFrameType ()).WillOnce (Return (1));
100
101 EXPECT_CALL (mockRequestor, postGenerateRequest (1, 2, 3));
102
103 receiver.pending ();
104}
105
106TEST(DecorPixmapRequestsTest, TestPendingGeneratesOnlyOneRequest)
107{
108 MockDecorPixmapRequestor mockRequestor;
109 MockDecoration mockDecoration;
110 X11DecorPixmapReceiver receiver (&mockRequestor, &mockDecoration);
111
112 EXPECT_CALL (mockDecoration, getFrameActions ()).WillOnce (Return (3));
113 EXPECT_CALL (mockDecoration, getFrameState ()).WillOnce (Return (2));
114 EXPECT_CALL (mockDecoration, getFrameType ()).WillOnce (Return (1));
115
116 EXPECT_CALL (mockRequestor, postGenerateRequest (1, 2, 3));
117
118 receiver.pending ();
119 receiver.pending ();
120}
121
122TEST(DecorPixmapRequestsTest, TestUpdateGeneratesRequestIfNewOnePending)
123{
124 MockDecorPixmapRequestor mockRequestor;
125 MockDecoration mockDecoration;
126 X11DecorPixmapReceiver receiver (&mockRequestor, &mockDecoration);
127
128 EXPECT_CALL (mockDecoration, getFrameActions ()).WillOnce (Return (3));
129 EXPECT_CALL (mockDecoration, getFrameState ()).WillOnce (Return (2));
130 EXPECT_CALL (mockDecoration, getFrameType ()).WillOnce (Return (1));
131
132 EXPECT_CALL (mockRequestor, postGenerateRequest (1, 2, 3));
133
134 receiver.pending ();
135 receiver.pending ();
136
137 EXPECT_CALL (mockDecoration, getFrameActions ()).WillOnce (Return (3));
138 EXPECT_CALL (mockDecoration, getFrameState ()).WillOnce (Return (2));
139 EXPECT_CALL (mockDecoration, getFrameType ()).WillOnce (Return (1));
140
141 EXPECT_CALL (mockRequestor, postGenerateRequest (1, 2, 3));
142
143 receiver.update ();
144}
145
146TEST(DecorPixmapRequestsTest, TestUpdateGeneratesNoRequestIfNoNewOnePending)
147{
148 MockDecorPixmapRequestor mockRequestor;
149 MockDecoration mockDecoration;
150 X11DecorPixmapReceiver receiver (&mockRequestor, &mockDecoration);
151
152 EXPECT_CALL (mockDecoration, getFrameActions ()).WillOnce (Return (3));
153 EXPECT_CALL (mockDecoration, getFrameState ()).WillOnce (Return (2));
154 EXPECT_CALL (mockDecoration, getFrameType ()).WillOnce (Return (1));
155
156 EXPECT_CALL (mockRequestor, postGenerateRequest (1, 2, 3));
157
158 receiver.pending ();
159 receiver.update ();
160}

Subscribers

People subscribed via source and target branches