Merge lp:~compiz-team/compiz/compiz.fix_1002602_tests into lp:compiz/0.9.8

Proposed by Sam Spilsbury
Status: Merged
Merged at revision: 3244
Proposed branch: lp:~compiz-team/compiz/compiz.fix_1002602_tests
Merge into: lp:compiz/0.9.8
Diff against target: 1659 lines (+1196/-85)
26 files modified
include/core/abiversion.h (+1/-1)
include/core/screen.h (+3/-0)
plugins/CMakeLists.txt (+1/-0)
plugins/composite/CMakeLists.txt (+6/-2)
plugins/composite/include/composite/composite.h (+1/-4)
plugins/composite/src/pixmapbinding/CMakeLists.txt (+43/-0)
plugins/composite/src/pixmapbinding/include/pixmapbinding.h (+191/-0)
plugins/composite/src/pixmapbinding/src/pixmapbinding.cpp (+141/-0)
plugins/composite/src/pixmapbinding/tests/CMakeLists.txt (+24/-0)
plugins/composite/src/pixmapbinding/tests/test-composite-pixmapbinding.cpp (+444/-0)
plugins/composite/src/privates.h (+21/-6)
plugins/composite/src/screen.cpp (+2/-0)
plugins/composite/src/window.cpp (+68/-72)
plugins/opengl/src/window.cpp (+2/-0)
src/CMakeLists.txt (+5/-0)
src/event.cpp (+25/-0)
src/plugin.cpp (+2/-0)
src/plugin/CMakeLists.txt (+1/-0)
src/privatescreen.h (+8/-0)
src/privatescreen/tests/CMakeLists.txt (+1/-0)
src/privatescreen/tests/test-privatescreen.cpp (+5/-0)
src/servergrab/CMakeLists.txt (+42/-0)
src/servergrab/include/core/servergrab.h (+51/-0)
src/servergrab/src/servergrab.cpp (+39/-0)
src/servergrab/tests/CMakeLists.txt (+14/-0)
src/servergrab/tests/test-servergrab.cpp (+55/-0)
To merge this branch: bzr merge lp:~compiz-team/compiz/compiz.fix_1002602_tests
Reviewer Review Type Date Requested Status
Daniel van Vugt Approve
Compiz Maintainers Pending
Review via email: mp+108448@code.launchpad.net

This proposal supersedes a proposal from 2012-05-31.

Description of the change

Adds some tests for the pixmap rebinding code ... which also means some refactoring was done.

At the moment, I'm not too much of a fan that we need a method to change the strategy for notifying renderers that a pixmap rebind is required - it really should be injected on the constructor ... but the only way that we'd be able to do that is to actually inject the PixmapRebinder object into CompositeWindow from the renderer, which isn't very good either.

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

Fails to cmake before I can even build it (no Makefile generated):

CMake Error at src/CMakeLists.txt:12 (add_subdirectory):
  add_subdirectory given source "servergrab" which is not an existing
  directory.

review: Needs Fixing
Revision history for this message
Daniel van Vugt (vanvugt) wrote : Posted in a previous version of this proposal

Again, I would like to put a stop to using so many verbs in class names ("Rebind"-er). It usually indicates bad design, but sometimes can be solved just by thinking of a better class name.

Perhaps the solution here is to just rename "PixmapRebinder" to "PixmapBinding".

review: Needs Fixing
Revision history for this message
Daniel van Vugt (vanvugt) wrote : Posted in a previous version of this proposal

The file path (pixmapbinder) no longer matches the class name (PixmapBinding).

review: Needs Fixing
Revision history for this message
Daniel van Vugt (vanvugt) wrote : Posted in a previous version of this proposal

Valgrind: Good
Callgrind: Good
Code review: Needs fixing (minor issues):

1. Copyrights look a bit wrong. New files that are entirely your own work (like test cases) should be copyright to Canonical (and mention yourself as author). Please don't copyright them to other people unless portions of the code is by them.

2. mPixmapRebinder should be called mPixmapBinding

review: Needs Fixing
3238. By Daniel van Vugt

Remove a pointless line of code that was also causing a minor conflict.

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

A couple of minor complaints, which I'm sure I've mentioned before:

1. X functions use Bool, not bool. So should be passed False, not false:
   XSync (privateScreen.dpy, false);

2. For correctness and readability, don't assume None == 0. So:
     if (mPixmap)
   should be:
     if (mPixmap != None)

review: Approve
Revision history for this message
Sam Spilsbury (smspillaz) wrote :

Okay, I'll quickly fix those so we can get this merged in

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

It's approved, so you don't need to fix them.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'include/core/abiversion.h'
2--- include/core/abiversion.h 2012-05-14 15:45:24 +0000
3+++ include/core/abiversion.h 2012-06-05 09:04:24 +0000
4@@ -5,6 +5,6 @@
5 # error Conflicting definitions of CORE_ABIVERSION
6 #endif
7
8-#define CORE_ABIVERSION 20120514
9+#define CORE_ABIVERSION 20120526
10
11 #endif // COMPIZ_ABIVERSION_H
12
13=== modified file 'include/core/screen.h'
14--- include/core/screen.h 2012-05-27 04:32:55 +0000
15+++ include/core/screen.h 2012-06-05 09:04:24 +0000
16@@ -45,6 +45,7 @@
17 class CompManager;
18 class CoreWindow;
19 class CoreOptions;
20+class ServerGrabInterface;
21
22 typedef std::list<CompWindow *> CompWindowList;
23 typedef std::vector<CompWindow *> CompWindowVector;
24@@ -391,6 +392,8 @@
25 virtual void processEvents () = 0;
26 virtual void alwaysHandleEvent (XEvent *event) = 0;
27
28+ virtual ServerGrabInterface * serverGrabInterface () = 0;
29+
30 // Replacements for friends accessing priv. They are declared virtual to
31 // ensure the ABI is stable if/when they are moved to CompScreenImpl.
32 // They are only intended for use within compiz-core
33
34=== modified file 'plugins/CMakeLists.txt'
35--- plugins/CMakeLists.txt 2012-05-21 06:43:20 +0000
36+++ plugins/CMakeLists.txt 2012-06-05 09:04:24 +0000
37@@ -16,6 +16,7 @@
38 ${CMAKE_CURRENT_SOURCE_DIR}/../src/pluginclasshandler/include
39 ${CMAKE_CURRENT_SOURCE_DIR}/../src/point/include
40 ${CMAKE_CURRENT_SOURCE_DIR}/../src/rect/include
41+ ${CMAKE_CURRENT_SOURCE_DIR}/../src/servergrab/include
42 ${CMAKE_CURRENT_SOURCE_DIR}/../src/region/include
43 ${CMAKE_CURRENT_SOURCE_DIR}/../src/window/geometry/include
44 ${CMAKE_CURRENT_SOURCE_DIR}/../src/window/geometry-saver/include
45
46=== modified file 'plugins/composite/CMakeLists.txt'
47--- plugins/composite/CMakeLists.txt 2012-02-08 10:54:35 +0000
48+++ plugins/composite/CMakeLists.txt 2012-06-05 09:04:24 +0000
49@@ -2,5 +2,9 @@
50
51 include (CompizPlugin)
52
53-compiz_plugin (composite)
54-
55+include_directories (${CMAKE_CURRENT_SOURCE_DIR}/src/pixmapbinding/include)
56+link_directories (${CMAKE_CURRENT_BINARY_DIR}/src/pixmapbinding)
57+
58+compiz_plugin (composite LIBRARIES compiz_composite_pixmapbinding)
59+
60+add_subdirectory (src/pixmapbinding)
61
62=== modified file 'plugins/composite/include/composite/composite.h'
63--- plugins/composite/include/composite/composite.h 2012-06-05 07:40:03 +0000
64+++ plugins/composite/include/composite/composite.h 2012-06-05 09:04:24 +0000
65@@ -171,7 +171,6 @@
66 virtual void damageRegion (const CompRegion &r);
67 };
68
69-
70 class CompositeScreen :
71 public WrapableHandler<CompositeScreenInterface, 7>,
72 public PluginClassHandler<CompositeScreen, CompScreen, COMPIZ_COMPOSITE_ABI>,
73@@ -327,8 +326,6 @@
74 {
75 public:
76
77- typedef boost::function <void ()> NewPixmapReadyCallback;
78-
79 CompositeWindow (CompWindow *w);
80 ~CompositeWindow ();
81
82@@ -430,7 +427,7 @@
83 * A function to call when a new pixmap is ready to
84 * be bound just before the old one is released
85 */
86- void setNewPixmapReadyCallback (const NewPixmapReadyCallback &cb);
87+ void setNewPixmapReadyCallback (const boost::function <void ()> &cb);
88
89 WRAPABLE_HND (0, CompositeWindowInterface, bool, damageRect,
90 bool, const CompRect &);
91
92=== added directory 'plugins/composite/src/pixmapbinding'
93=== added file 'plugins/composite/src/pixmapbinding/CMakeLists.txt'
94--- plugins/composite/src/pixmapbinding/CMakeLists.txt 1970-01-01 00:00:00 +0000
95+++ plugins/composite/src/pixmapbinding/CMakeLists.txt 2012-06-05 09:04:24 +0000
96@@ -0,0 +1,43 @@
97+include (FindPkgConfig)
98+
99+PKG_CHECK_MODULES (X11 x11)
100+
101+INCLUDE_DIRECTORIES (
102+ ${CMAKE_CURRENT_SOURCE_DIR}/include
103+ ${CMAKE_CURRENT_SOURCE_DIR}/src
104+
105+ ${Boost_INCLUDE_DIRS}
106+
107+ ${X11_INCLUDE_DIRS}
108+)
109+
110+LINK_DIRECTORIES (${GLIBMM_LIBRARY_DIRS} ${COMPIZ_LIBRARY_DIRS})
111+
112+SET (
113+ PRIVATE_HEADERS
114+ ${CMAKE_CURRENT_SOURCE_DIR}/include/pixmapbinding.h
115+)
116+
117+SET(
118+ SRCS
119+ ${CMAKE_CURRENT_SOURCE_DIR}/src/pixmapbinding.cpp
120+ ${compiz_SOURCE_DIR}/src/size.cpp # XXX: Remove once we've merged this into a general geometry lib
121+)
122+
123+ADD_LIBRARY(
124+ compiz_composite_pixmapbinding STATIC
125+
126+ ${SRCS}
127+
128+ ${PRIVATE_HEADERS}
129+)
130+
131+if (COMPIZ_BUILD_TESTING)
132+ADD_SUBDIRECTORY( ${CMAKE_CURRENT_SOURCE_DIR}/tests )
133+endif (COMPIZ_BUILD_TESTING)
134+
135+TARGET_LINK_LIBRARIES(
136+ compiz_composite_pixmapbinding
137+ compiz_servergrab
138+ ${X11_LIBRARIES}
139+)
140
141=== added directory 'plugins/composite/src/pixmapbinding/include'
142=== added file 'plugins/composite/src/pixmapbinding/include/pixmapbinding.h'
143--- plugins/composite/src/pixmapbinding/include/pixmapbinding.h 1970-01-01 00:00:00 +0000
144+++ plugins/composite/src/pixmapbinding/include/pixmapbinding.h 2012-06-05 09:04:24 +0000
145@@ -0,0 +1,191 @@
146+/*
147+ * Copyright © 2012 Canonical Ltd.
148+ * Copyright © 2008 Dennis Kasprzyk
149+ * Copyright © 2007 Novell, Inc.
150+ *
151+ * Permission to use, copy, modify, distribute, and sell this software
152+ * and its documentation for any purpose is hereby granted without
153+ * fee, provided that the above copyright notice appear in all copies
154+ * and that both that copyright notice and this permission notice
155+ * appear in supporting documentation, and that the name of
156+ * Dennis Kasprzyk not be used in advertising or publicity pertaining to
157+ * distribution of the software without specific, written prior permission.
158+ * Dennis Kasprzyk makes no representations about the suitability of this
159+ * software for any purpose. It is provided "as is" without express or
160+ * implied warranty.
161+ *
162+ * DENNIS KASPRZYK DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
163+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
164+ * NO EVENT SHALL DENNIS KASPRZYK BE LIABLE FOR ANY SPECIAL, INDIRECT OR
165+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
166+ * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
167+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
168+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
169+ *
170+ * Authors: Dennis Kasprzyk <onestone@compiz-fusion.org>
171+ * David Reveman <davidr@novell.com>
172+ * Sam Spilsbury <sam.spilsbury@canonical.com>
173+ */
174+
175+#ifndef _COMPOSITE_PIXMAP_REBIND_H
176+#define _COMPOSITE_PIXMAP_REBIND_H
177+
178+#include <memory>
179+#include <boost/shared_ptr.hpp>
180+#include <boost/function.hpp>
181+#include <boost/bind.hpp>
182+
183+#include <core/size.h>
184+
185+#include <X11/Xlib.h>
186+
187+class ServerGrabInterface;
188+
189+class CompositePixmapRebindInterface
190+{
191+ public:
192+
193+ virtual ~CompositePixmapRebindInterface () {}
194+
195+ virtual Pixmap pixmap () const = 0;
196+ virtual bool bind () = 0;
197+ virtual const CompSize & size () const = 0;
198+ virtual void release () = 0;
199+
200+ /* This isn't great API, but probably necessary
201+ * unless we make it a requirement that the
202+ * renderer sets the strategy for the rebinder */
203+ virtual void setNewPixmapReadyCallback (const boost::function <void ()> &) = 0;
204+
205+ /* Also don't like this either */
206+ virtual void allowFurtherRebindAttempts () = 0;
207+};
208+
209+class WindowAttributesGetInterface
210+{
211+ public:
212+
213+ virtual ~WindowAttributesGetInterface () {}
214+
215+ virtual bool getAttributes (XWindowAttributes &) = 0;
216+};
217+
218+class WindowPixmapInterface
219+{
220+ public:
221+
222+ virtual ~WindowPixmapInterface () {}
223+
224+ typedef boost::shared_ptr <WindowPixmapInterface> Ptr;
225+
226+ virtual Pixmap pixmap () const = 0;
227+ virtual void releasePixmap () = 0;
228+};
229+
230+class X11WindowPixmap :
231+ public WindowPixmapInterface
232+{
233+ public:
234+
235+ X11WindowPixmap (Display *d, Pixmap p) :
236+ mDisplay (d),
237+ mPixmap (p)
238+ {
239+ }
240+
241+ Pixmap pixmap () const
242+ {
243+ return mPixmap;
244+ }
245+
246+ void releasePixmap ()
247+ {
248+ if (mPixmap)
249+ XFreePixmap (mDisplay, mPixmap);
250+
251+ mPixmap = None;
252+ }
253+
254+ private:
255+
256+ Display *mDisplay;
257+ Pixmap mPixmap;
258+};
259+
260+class WindowPixmap
261+{
262+ public:
263+
264+ WindowPixmap () :
265+ mPixmap ()
266+ {
267+ }
268+
269+ WindowPixmap (WindowPixmapInterface::Ptr &pm) :
270+ mPixmap (pm)
271+ {
272+ }
273+
274+ Pixmap pixmap () const
275+ {
276+ if (mPixmap)
277+ return mPixmap->pixmap ();
278+
279+ return None;
280+ }
281+
282+ ~WindowPixmap ()
283+ {
284+ if (mPixmap)
285+ mPixmap->releasePixmap ();
286+ }
287+ private:
288+
289+ WindowPixmapInterface::Ptr mPixmap;
290+};
291+
292+class WindowPixmapGetInterface
293+{
294+ public:
295+
296+ virtual ~WindowPixmapGetInterface () {}
297+
298+ virtual WindowPixmapInterface::Ptr getPixmap () = 0;
299+};
300+
301+class PixmapBinding :
302+ public CompositePixmapRebindInterface
303+{
304+ public:
305+
306+ typedef boost::function <void ()> NewPixmapReadyCallback;
307+
308+ PixmapBinding (const NewPixmapReadyCallback &,
309+ WindowPixmapGetInterface *,
310+ WindowAttributesGetInterface *,
311+ ServerGrabInterface *);
312+
313+ ~PixmapBinding ();
314+
315+ Pixmap pixmap () const;
316+ bool bind ();
317+ const CompSize & size () const;
318+ void release ();
319+ void setNewPixmapReadyCallback (const boost::function <void ()> &);
320+ void allowFurtherRebindAttempts ();
321+
322+ private:
323+
324+ std::auto_ptr <WindowPixmap> mPixmap;
325+ CompSize mSize;
326+ bool needsRebind;
327+ bool bindFailed;
328+ NewPixmapReadyCallback newPixmapReadyCallback;
329+
330+ WindowPixmapGetInterface *windowPixmapRetreiver;
331+ WindowAttributesGetInterface *windowAttributesRetreiver;
332+ ServerGrabInterface *serverGrab;
333+
334+};
335+
336+#endif
337
338=== added directory 'plugins/composite/src/pixmapbinding/src'
339=== added file 'plugins/composite/src/pixmapbinding/src/pixmapbinding.cpp'
340--- plugins/composite/src/pixmapbinding/src/pixmapbinding.cpp 1970-01-01 00:00:00 +0000
341+++ plugins/composite/src/pixmapbinding/src/pixmapbinding.cpp 2012-06-05 09:04:24 +0000
342@@ -0,0 +1,141 @@
343+/*
344+ * Copyright © 2012 Canonical Ltd.
345+ * Copyright © 2008 Dennis Kasprzyk
346+ * Copyright © 2007 Novell, Inc.
347+ *
348+ * Permission to use, copy, modify, distribute, and sell this software
349+ * and its documentation for any purpose is hereby granted without
350+ * fee, provided that the above copyright notice appear in all copies
351+ * and that both that copyright notice and this permission notice
352+ * appear in supporting documentation, and that the name of
353+ * Dennis Kasprzyk not be used in advertising or publicity pertaining to
354+ * distribution of the software without specific, written prior permission.
355+ * Dennis Kasprzyk makes no representations about the suitability of this
356+ * software for any purpose. It is provided "as is" without express or
357+ * implied warranty.
358+ *
359+ * DENNIS KASPRZYK DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
360+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
361+ * NO EVENT SHALL DENNIS KASPRZYK BE LIABLE FOR ANY SPECIAL, INDIRECT OR
362+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
363+ * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
364+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
365+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
366+ *
367+ * Authors: Dennis Kasprzyk <onestone@compiz-fusion.org>
368+ * David Reveman <davidr@novell.com>
369+ * Sam Spilsbury <sam.spilsbury@canonical.com>
370+ */
371+
372+#include <core/servergrab.h>
373+#include "pixmapbinding.h"
374+
375+PixmapBinding::PixmapBinding (const NewPixmapReadyCallback &cb,
376+ WindowPixmapGetInterface *pmg,
377+ WindowAttributesGetInterface *wag,
378+ ServerGrabInterface *sg) :
379+ mPixmap (),
380+ mSize (),
381+ needsRebind (true),
382+ bindFailed (false),
383+ newPixmapReadyCallback (cb),
384+ windowPixmapRetreiver (pmg),
385+ windowAttributesRetreiver (wag),
386+ serverGrab (sg)
387+{
388+}
389+
390+PixmapBinding::~PixmapBinding ()
391+{
392+ needsRebind = false;
393+}
394+
395+const CompSize &
396+PixmapBinding::size () const
397+{
398+ return mSize;
399+}
400+
401+Pixmap
402+PixmapBinding::pixmap () const
403+{
404+ static Pixmap nPixmap = None;
405+
406+ if (needsRebind ||
407+ !mPixmap.get ())
408+ return nPixmap;
409+
410+ return mPixmap->pixmap ();
411+}
412+
413+bool
414+PixmapBinding::bind ()
415+{
416+ /* don't try to bind window again if it failed previously */
417+ if (bindFailed)
418+ return false;
419+
420+ if (needsRebind)
421+ {
422+ XWindowAttributes attr;
423+
424+ /* We have to grab the server here to make sure that window
425+ is mapped when getting the window pixmap */
426+ ServerLock mLock (serverGrab);
427+
428+ windowAttributesRetreiver->getAttributes (attr);
429+ if (attr.map_state != IsViewable ||
430+ (attr.width == 0 && attr.border_width == 0) ||
431+ (attr.height == 0 && attr.border_width == 0))
432+ {
433+ bindFailed = true;
434+ needsRebind = false;
435+ return false;
436+ }
437+
438+ WindowPixmapInterface::Ptr newPixmap = windowPixmapRetreiver->getPixmap ();
439+ CompSize newSize = CompSize (attr.border_width * 2 + attr.width,
440+ attr.border_width * 2 + attr.height);
441+
442+ if (newPixmap->pixmap () && newSize.width () && newSize.height ())
443+ {
444+ /* Notify renderer that a new pixmap is about to
445+ * be bound */
446+ if (newPixmapReadyCallback)
447+ newPixmapReadyCallback ();
448+
449+ /* Assign new pixmap */
450+ std::auto_ptr <WindowPixmap> newPixmapWrapper (new WindowPixmap (newPixmap));
451+ mPixmap = newPixmapWrapper;
452+ mSize = newSize;
453+
454+ needsRebind = false;
455+ }
456+ else
457+ {
458+ bindFailed = true;
459+ needsRebind = false;
460+ return false;
461+ }
462+ }
463+ return true;
464+}
465+
466+void
467+PixmapBinding::release ()
468+{
469+ needsRebind = true;
470+}
471+
472+void
473+PixmapBinding::setNewPixmapReadyCallback (const NewPixmapReadyCallback &cb)
474+{
475+ newPixmapReadyCallback = cb;
476+}
477+
478+void
479+PixmapBinding::allowFurtherRebindAttempts ()
480+{
481+ bindFailed = false;
482+ needsRebind = true;
483+}
484
485=== added directory 'plugins/composite/src/pixmapbinding/tests'
486=== added file 'plugins/composite/src/pixmapbinding/tests/CMakeLists.txt'
487--- plugins/composite/src/pixmapbinding/tests/CMakeLists.txt 1970-01-01 00:00:00 +0000
488+++ plugins/composite/src/pixmapbinding/tests/CMakeLists.txt 2012-06-05 09:04:24 +0000
489@@ -0,0 +1,24 @@
490+find_library (GMOCK_LIBRARY gmock)
491+find_library (GMOCK_MAIN_LIBRARY gmock_main)
492+
493+if (NOT GMOCK_LIBRARY OR NOT GMOCK_MAIN_LIBRARY OR NOT GTEST_FOUND)
494+ message ("Google Mock and Google Test not found - cannot build tests!")
495+ set (COMPIZ_BUILD_TESTING OFF)
496+endif (NOT GMOCK_LIBRARY OR NOT GMOCK_MAIN_LIBRARY OR NOT GTEST_FOUND)
497+
498+include_directories (${GTEST_INCLUDE_DIRS})
499+
500+link_directories (${COMPIZ_LIBRARY_DIRS})
501+
502+add_executable (compiz_test_composite_pixmapbinding
503+ ${CMAKE_CURRENT_SOURCE_DIR}/test-composite-pixmapbinding.cpp)
504+
505+target_link_libraries (compiz_test_composite_pixmapbinding
506+ compiz_composite_pixmapbinding
507+ ${GTEST_BOTH_LIBRARIES}
508+ ${GMOCK_LIBRARY}
509+ ${GMOCK_MAIN_LIBRARY}
510+ ${CMAKE_THREAD_LIBS_INIT} # Link in pthread.
511+ )
512+
513+gtest_add_tests (compiz_test_composite_pixmapbinding "" ${CMAKE_CURRENT_SOURCE_DIR}/test-composite-pixmapbinding.cpp)
514
515=== added file 'plugins/composite/src/pixmapbinding/tests/test-composite-pixmapbinding.cpp'
516--- plugins/composite/src/pixmapbinding/tests/test-composite-pixmapbinding.cpp 1970-01-01 00:00:00 +0000
517+++ plugins/composite/src/pixmapbinding/tests/test-composite-pixmapbinding.cpp 2012-06-05 09:04:24 +0000
518@@ -0,0 +1,444 @@
519+/*
520+ * Copyright © 2012 Canonical Ltd.
521+ *
522+ * Permission to use, copy, modify, distribute, and sell this software
523+ * and its documentation for any purpose is hereby granted without
524+ * fee, provided that the above copyright notice appear in all copies
525+ * and that both that copyright notice and this permission notice
526+ * appear in supporting documentation, and that the name of
527+ * Dennis Kasprzyk not be used in advertising or publicity pertaining to
528+ * distribution of the software without specific, written prior permission.
529+ * Dennis Kasprzyk makes no representations about the suitability of this
530+ * software for any purpose. It is provided "as is" without express or
531+ * implied warranty.
532+ *
533+ * DENNIS KASPRZYK DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
534+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
535+ * NO EVENT SHALL DENNIS KASPRZYK BE LIABLE FOR ANY SPECIAL, INDIRECT OR
536+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
537+ * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
538+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
539+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
540+ *
541+ * Authors: Sam Spilsbury <sam.spilsbury@canonical.com>
542+ */
543+
544+#include <boost/shared_ptr.hpp>
545+#include <boost/make_shared.hpp>
546+
547+#include <gtest/gtest.h>
548+#include <gmock/gmock.h>
549+
550+#include <core/servergrab.h>
551+#include "pixmapbinding.h"
552+
553+using ::testing::Invoke;
554+using ::testing::Return;
555+using ::testing::_;
556+
557+class CompositePixmapBinderTest :
558+ public ::testing::Test
559+{
560+};
561+
562+class MockWindowPixmapGet :
563+ public WindowPixmapGetInterface
564+{
565+ public:
566+
567+ MOCK_METHOD0 (getPixmap, WindowPixmapInterface::Ptr ());
568+};
569+
570+class FakeWindowAttributesGet :
571+ public WindowAttributesGetInterface
572+{
573+ public:
574+
575+ FakeWindowAttributesGet (XWindowAttributes &wa) :
576+ mAttributes (wa)
577+ {
578+ }
579+
580+ bool getAttributes (XWindowAttributes &wa)
581+ {
582+ wa = mAttributes;
583+ return true;
584+ }
585+
586+ private:
587+
588+ XWindowAttributes mAttributes;
589+};
590+
591+class MockWindowAttributesGet :
592+ public WindowAttributesGetInterface
593+{
594+ public:
595+
596+ MOCK_METHOD1 (getAttributes, bool (XWindowAttributes &));
597+};
598+
599+class MockPixmap :
600+ public WindowPixmapInterface
601+{
602+ public:
603+
604+ typedef boost::shared_ptr <MockPixmap> Ptr;
605+
606+ MOCK_CONST_METHOD0 (pixmap, Pixmap ());
607+ MOCK_METHOD0 (releasePixmap, void ());
608+};
609+
610+class MockServerGrab :
611+ public ServerGrabInterface
612+{
613+ public:
614+
615+ MOCK_METHOD0 (grabServer, void ());
616+ MOCK_METHOD0 (ungrabServer, void ());
617+ MOCK_METHOD0 (syncServer, void ());
618+};
619+
620+class PixmapReadyInterface
621+{
622+ public:
623+
624+ virtual ~PixmapReadyInterface () {}
625+
626+ virtual void ready () = 0;
627+};
628+
629+class MockPixmapReady :
630+ public PixmapReadyInterface
631+{
632+ public:
633+
634+ MOCK_METHOD0 (ready, void ());
635+};
636+
637+TEST(CompositePixmapBinderTest, TestInitialBindSuccess)
638+{
639+ /* Leave this here
640+ * There's a bug in Google Mock at the moment where
641+ * if a function with an expectation which returns
642+ * Mock B through a container is itself contained in
643+ * Mock A, then when Mock A is destroyed, it will first
644+ * lock a mutex, and then it will invoke
645+ * the destructor the container containing Mock B which
646+ * in turn might invoke Mock B's destructor and thus
647+ * lock the same mutex in the same thread (deadlock).
648+ *
649+ * Keeping this reference here ensures that MockPixmap
650+ * stays alive while MockWindowPixmapGet is being destroyed
651+ */
652+ MockPixmap::Ptr wp (boost::make_shared <MockPixmap> ());
653+
654+ MockWindowPixmapGet mwpg;
655+ MockWindowAttributesGet mwag;
656+ MockServerGrab msg;
657+ XWindowAttributes xwa;
658+
659+ xwa.width = 100;
660+ xwa.height = 200;
661+ xwa.map_state = IsViewable;
662+ xwa.border_width = 1;
663+
664+ FakeWindowAttributesGet fwag (xwa);
665+
666+ MockPixmapReady ready;
667+
668+ boost::function <void ()> readyCb (boost::bind (&PixmapReadyInterface::ready, &ready));
669+
670+ PixmapBinding pr (readyCb,
671+ &mwpg,
672+ &mwag,
673+ &msg);
674+
675+ EXPECT_CALL (msg, grabServer ());
676+ EXPECT_CALL (msg, syncServer ()).Times (2);
677+ EXPECT_CALL (mwag, getAttributes (_)).WillOnce (Invoke (&fwag, &FakeWindowAttributesGet::getAttributes));
678+ EXPECT_CALL (mwpg, getPixmap ()).WillOnce (Return (boost::shared_static_cast <WindowPixmapInterface> (wp)));
679+
680+ EXPECT_CALL (*wp, pixmap ()).WillOnce (Return (1));
681+
682+ EXPECT_CALL (ready, ready ());
683+ EXPECT_CALL (msg, ungrabServer ());
684+
685+ pr.bind ();
686+
687+ EXPECT_CALL (*wp, pixmap ()).WillOnce (Return (1));
688+
689+ EXPECT_EQ (pr.pixmap (), 1);
690+ EXPECT_EQ (pr.size (), CompSize (102, 202));
691+
692+ EXPECT_CALL (*wp, releasePixmap ());
693+}
694+
695+TEST(CompositePixmapBinderTest, TestInitialBindSuccessNoRebind)
696+{
697+ MockPixmap::Ptr wp (boost::make_shared <MockPixmap> ());
698+
699+ MockWindowPixmapGet mwpg;
700+ MockWindowAttributesGet mwag;
701+ MockServerGrab msg;
702+ XWindowAttributes xwa;
703+
704+ xwa.width = 100;
705+ xwa.height = 200;
706+ xwa.map_state = IsViewable;
707+ xwa.border_width = 1;
708+
709+ FakeWindowAttributesGet fwag (xwa);
710+
711+ MockPixmapReady ready;
712+
713+ boost::function <void ()> readyCb (boost::bind (&PixmapReadyInterface::ready, &ready));
714+
715+ PixmapBinding pr (readyCb,
716+ &mwpg,
717+ &mwag,
718+ &msg);
719+
720+ EXPECT_CALL (msg, grabServer ());
721+ EXPECT_CALL (msg, syncServer ()).Times (2);
722+ EXPECT_CALL (mwag, getAttributes (_)).WillOnce (Invoke (&fwag, &FakeWindowAttributesGet::getAttributes));
723+ EXPECT_CALL (mwpg, getPixmap ()).WillOnce (Return (boost::shared_static_cast <WindowPixmapInterface> (wp)));
724+
725+ EXPECT_CALL (*wp, pixmap ()).WillOnce (Return (1));
726+
727+ EXPECT_CALL (ready, ready ());
728+ EXPECT_CALL (msg, ungrabServer ());
729+
730+ EXPECT_TRUE (pr.bind ());
731+ EXPECT_TRUE (pr.bind ());
732+
733+ EXPECT_CALL (*wp, pixmap ()).WillOnce (Return (1));
734+
735+ EXPECT_EQ (pr.pixmap (), 1);
736+ EXPECT_EQ (pr.size (), CompSize (102, 202));
737+
738+ EXPECT_CALL (*wp, releasePixmap ());
739+}
740+
741+TEST(CompositePixmapBinderTest, TestRebindAfterRelease)
742+{
743+ MockPixmap::Ptr wp (boost::make_shared <MockPixmap> ());
744+
745+ MockWindowPixmapGet mwpg;
746+ MockWindowAttributesGet mwag;
747+ MockServerGrab msg;
748+ XWindowAttributes xwa;
749+
750+ xwa.width = 100;
751+ xwa.height = 200;
752+ xwa.map_state = IsViewable;
753+ xwa.border_width = 1;
754+
755+ FakeWindowAttributesGet fwag (xwa);
756+
757+ MockPixmapReady ready;
758+
759+ boost::function <void ()> readyCb (boost::bind (&PixmapReadyInterface::ready, &ready));
760+
761+ PixmapBinding pr (readyCb,
762+ &mwpg,
763+ &mwag,
764+ &msg);
765+
766+ EXPECT_CALL (msg, grabServer ());
767+ EXPECT_CALL (msg, syncServer ()).Times (2);
768+ EXPECT_CALL (mwag, getAttributes (_)).WillOnce (Invoke (&fwag, &FakeWindowAttributesGet::getAttributes));
769+ EXPECT_CALL (mwpg, getPixmap ()).WillOnce (Return (boost::shared_static_cast <WindowPixmapInterface> (wp)));
770+
771+ EXPECT_CALL (*wp, pixmap ()).WillOnce (Return (1));
772+
773+ EXPECT_CALL (ready, ready ());
774+ EXPECT_CALL (msg, ungrabServer ());
775+
776+ EXPECT_TRUE (pr.bind ());
777+
778+ EXPECT_CALL (*wp, pixmap ()).WillOnce (Return (1));
779+
780+ EXPECT_EQ (pr.pixmap (), 1);
781+ EXPECT_EQ (pr.size (), CompSize (102, 202));
782+
783+ EXPECT_CALL (*wp, releasePixmap ());
784+
785+ pr.release ();
786+
787+ EXPECT_CALL (msg, grabServer ());
788+ EXPECT_CALL (msg, syncServer ()).Times (2);
789+ EXPECT_CALL (mwag, getAttributes (_)).WillOnce (Invoke (&fwag, &FakeWindowAttributesGet::getAttributes));
790+ EXPECT_CALL (mwpg, getPixmap ()).WillOnce (Return (boost::shared_static_cast <WindowPixmapInterface> (wp)));
791+
792+ EXPECT_CALL (*wp, pixmap ()).WillOnce (Return (1));
793+
794+ EXPECT_CALL (ready, ready ());
795+ EXPECT_CALL (msg, ungrabServer ());
796+
797+ EXPECT_TRUE (pr.bind ());
798+
799+ EXPECT_CALL (*wp, pixmap ()).WillOnce (Return (1));
800+
801+ EXPECT_EQ (pr.pixmap (), 1);
802+ EXPECT_EQ (pr.size (), CompSize (102, 202));
803+
804+ EXPECT_CALL (*wp, releasePixmap ());
805+}
806+
807+TEST(CompositePixmapBinderTest, TestInitialBindFailureWindowUnmapped)
808+{
809+ MockWindowPixmapGet mwpg;
810+ MockWindowAttributesGet mwag;
811+ MockServerGrab msg;
812+ XWindowAttributes xwa;
813+
814+ xwa.width = 100;
815+ xwa.height = 200;
816+ xwa.map_state = IsUnmapped;
817+ xwa.border_width = 1;
818+
819+ FakeWindowAttributesGet fwag (xwa);
820+
821+ PixmapBinding pr (boost::function <void ()> (),
822+ &mwpg,
823+ &mwag,
824+ &msg);
825+
826+ EXPECT_CALL (msg, grabServer ());
827+ EXPECT_CALL (msg, syncServer ()).Times (2);
828+ EXPECT_CALL (mwag, getAttributes (_)).WillOnce (Invoke (&fwag, &FakeWindowAttributesGet::getAttributes));
829+
830+ EXPECT_CALL (msg, ungrabServer ());
831+
832+ EXPECT_FALSE (pr.bind ());
833+
834+ EXPECT_EQ (pr.pixmap (), 0);
835+ EXPECT_EQ (pr.size (), CompSize (0, 0));
836+}
837+
838+TEST(CompositePixmapBinderTest, TestInitialBindFailureWindowZeroSize)
839+{
840+ MockWindowPixmapGet mwpg;
841+ MockWindowAttributesGet mwag;
842+ MockServerGrab msg;
843+ XWindowAttributes xwa;
844+
845+ xwa.width = 0;
846+ xwa.height = 0;
847+ xwa.map_state = IsViewable;
848+ xwa.border_width = 0;
849+
850+ FakeWindowAttributesGet fwag (xwa);
851+
852+ PixmapBinding pr (boost::function <void ()> (),
853+ &mwpg,
854+ &mwag,
855+ &msg);
856+
857+ EXPECT_CALL (msg, grabServer ());
858+ EXPECT_CALL (msg, syncServer ()).Times (2);
859+ EXPECT_CALL (mwag, getAttributes (_)).WillOnce (Invoke (&fwag, &FakeWindowAttributesGet::getAttributes));
860+
861+ EXPECT_CALL (msg, ungrabServer ());
862+
863+ EXPECT_FALSE (pr.bind ());
864+
865+ EXPECT_EQ (pr.pixmap (), 0);
866+ EXPECT_EQ (pr.size (), CompSize (0, 0));
867+}
868+
869+TEST(CompositePixmapBinderTest, TestInitialBindFailureNilPixmapReturned)
870+{
871+ MockPixmap::Ptr wp (boost::make_shared <MockPixmap> ());
872+
873+ MockWindowPixmapGet mwpg;
874+ MockWindowAttributesGet mwag;
875+ MockServerGrab msg;
876+ XWindowAttributes xwa;
877+
878+ xwa.width = 100;
879+ xwa.height = 200;
880+ xwa.map_state = IsViewable;
881+ xwa.border_width = 0;
882+
883+ FakeWindowAttributesGet fwag (xwa);
884+
885+ PixmapBinding pr (boost::function <void ()> (),
886+ &mwpg,
887+ &mwag,
888+ &msg);
889+
890+ EXPECT_CALL (msg, grabServer ());
891+ EXPECT_CALL (msg, syncServer ()).Times (2);
892+ EXPECT_CALL (mwag, getAttributes (_)).WillOnce (Invoke (&fwag, &FakeWindowAttributesGet::getAttributes));
893+ EXPECT_CALL (mwpg, getPixmap ()).WillOnce (Return (boost::shared_static_cast <WindowPixmapInterface> (wp)));
894+
895+ EXPECT_CALL (*wp, pixmap ()).WillOnce (Return (0));
896+
897+ EXPECT_CALL (msg, ungrabServer ());
898+
899+ EXPECT_FALSE (pr.bind ());
900+
901+ EXPECT_EQ (pr.pixmap (), 0);
902+ EXPECT_EQ (pr.size (), CompSize (0, 0));
903+}
904+
905+TEST(CompositePixmapBinderTest, TestInitialBindFailureWindowUnmappedSuccessOnRemap)
906+{
907+ MockPixmap::Ptr wp (boost::make_shared <MockPixmap> ());
908+
909+ MockWindowPixmapGet mwpg;
910+ MockWindowAttributesGet mwag;
911+ MockServerGrab msg;
912+ XWindowAttributes xwa;
913+
914+ xwa.width = 100;
915+ xwa.height = 200;
916+ xwa.map_state = IsUnmapped;
917+ xwa.border_width = 1;
918+
919+ FakeWindowAttributesGet fwag (xwa);
920+
921+ PixmapBinding pr (boost::function <void ()> (),
922+ &mwpg,
923+ &mwag,
924+ &msg);
925+
926+ EXPECT_CALL (msg, grabServer ());
927+ EXPECT_CALL (msg, syncServer ()).Times (2);
928+ EXPECT_CALL (mwag, getAttributes (_)).WillOnce (Invoke (&fwag, &FakeWindowAttributesGet::getAttributes));
929+
930+ EXPECT_CALL (msg, ungrabServer ());
931+
932+ EXPECT_FALSE (pr.bind ());
933+
934+ EXPECT_EQ (pr.pixmap (), 0);
935+ EXPECT_EQ (pr.size (), CompSize (0, 0));
936+
937+ EXPECT_FALSE (pr.bind ());
938+
939+ pr.allowFurtherRebindAttempts ();
940+
941+ xwa.width = 100;
942+ xwa.height = 200;
943+ xwa.map_state = IsViewable;
944+ xwa.border_width = 1;
945+
946+ FakeWindowAttributesGet fwag2 (xwa);
947+
948+ EXPECT_CALL (msg, grabServer ());
949+ EXPECT_CALL (msg, syncServer ()).Times (2);
950+ EXPECT_CALL (mwag, getAttributes (_)).WillOnce (Invoke (&fwag2, &FakeWindowAttributesGet::getAttributes));
951+ EXPECT_CALL (mwpg, getPixmap ()).WillOnce (Return (boost::shared_static_cast <WindowPixmapInterface> (wp)));
952+
953+ EXPECT_CALL (msg, ungrabServer ());
954+
955+ EXPECT_CALL (*wp, pixmap ()).WillOnce (Return (1));
956+
957+ EXPECT_TRUE (pr.bind ());
958+
959+ EXPECT_CALL (*wp, pixmap ()).WillOnce (Return (1));
960+ EXPECT_EQ (pr.pixmap (), 1);
961+ EXPECT_EQ (pr.size (), CompSize (102, 202));
962+}
963
964=== modified file 'plugins/composite/src/privates.h'
965--- plugins/composite/src/privates.h 2012-06-05 07:40:03 +0000
966+++ plugins/composite/src/privates.h 2012-06-05 09:04:24 +0000
967@@ -28,10 +28,14 @@
968 #ifndef _COMPOSITE_PRIVATES_H
969 #define _COMPOSITE_PRIVATES_H
970
971+#include <memory>
972+#include <boost/shared_ptr.hpp>
973+
974 #include <composite/composite.h>
975 #include <core/atoms.h>
976 #include <set>
977
978+#include "pixmapbinding.h"
979 #include "composite_options.h"
980
981 extern CompPlugin::VTable *compositeVTable;
982@@ -111,7 +115,11 @@
983 std::set<Damage> damages;
984 };
985
986-class PrivateCompositeWindow : WindowInterface
987+class PrivateCompositeWindow :
988+ public WindowInterface,
989+ public CompositePixmapRebindInterface,
990+ public WindowPixmapGetInterface,
991+ public WindowAttributesGetInterface
992 {
993 public:
994 PrivateCompositeWindow (CompWindow *w, CompositeWindow *cw);
995@@ -121,6 +129,13 @@
996 void resizeNotify (int dx, int dy, int dwidth, int dheight);
997 void moveNotify (int dx, int dy, bool now);
998
999+ Pixmap pixmap () const;
1000+ bool bind ();
1001+ const CompSize & size () const;
1002+ void release ();
1003+ void setNewPixmapReadyCallback (const boost::function <void ()> &);
1004+ void allowFurtherRebindAttempts ();
1005+
1006 static void handleDamageRect (CompositeWindow *w,
1007 int x,
1008 int y,
1009@@ -132,17 +147,13 @@
1010 CompositeWindow *cWindow;
1011 CompositeScreen *cScreen;
1012
1013- Pixmap pixmap;
1014- CompSize size;
1015- bool needsRebind;
1016- CompositeWindow::NewPixmapReadyCallback newPixmapReadyCallback;
1017+ PixmapBinding mPixmapBinding;
1018
1019 Damage damage;
1020
1021 bool damaged;
1022 bool redirected;
1023 bool overlayWindow;
1024- bool bindFailed;
1025
1026 unsigned short opacity;
1027 unsigned short brightness;
1028@@ -151,6 +162,10 @@
1029 XRectangle *damageRects;
1030 int sizeDamage;
1031 int nDamage;
1032+ private:
1033+
1034+ bool getAttributes (XWindowAttributes &);
1035+ WindowPixmapInterface::Ptr getPixmap ();
1036 };
1037
1038 #endif
1039
1040=== modified file 'plugins/composite/src/screen.cpp'
1041--- plugins/composite/src/screen.cpp 2012-06-05 07:40:03 +0000
1042+++ plugins/composite/src/screen.cpp 2012-06-05 09:04:24 +0000
1043@@ -840,6 +840,8 @@
1044 return false;
1045 }
1046
1047+
1048+
1049 void
1050 CompositeScreen::preparePaint (int msSinceLastPaint)
1051 WRAPABLE_HND_FUNCTN (preparePaint, msSinceLastPaint)
1052
1053=== modified file 'plugins/composite/src/window.cpp'
1054--- plugins/composite/src/window.cpp 2012-06-05 07:40:03 +0000
1055+++ plugins/composite/src/window.cpp 2012-06-05 09:04:24 +0000
1056@@ -83,9 +83,21 @@
1057 }
1058
1059 void
1060-CompositeWindow::setNewPixmapReadyCallback (const NewPixmapReadyCallback &cb)
1061-{
1062- priv->newPixmapReadyCallback = cb;
1063+PrivateCompositeWindow::setNewPixmapReadyCallback (const PixmapBinding::NewPixmapReadyCallback &cb)
1064+{
1065+ mPixmapBinding.setNewPixmapReadyCallback (cb);
1066+}
1067+
1068+void
1069+CompositeWindow::setNewPixmapReadyCallback (const PixmapBinding::NewPixmapReadyCallback &cb)
1070+{
1071+ priv->setNewPixmapReadyCallback (cb);
1072+}
1073+
1074+void
1075+PrivateCompositeWindow::allowFurtherRebindAttempts ()
1076+{
1077+ mPixmapBinding.allowFurtherRebindAttempts ();
1078 }
1079
1080 PrivateCompositeWindow::PrivateCompositeWindow (CompWindow *w,
1081@@ -93,14 +105,14 @@
1082 window (w),
1083 cWindow (cw),
1084 cScreen (CompositeScreen::get (screen)),
1085- pixmap (None),
1086- needsRebind (true),
1087- newPixmapReadyCallback (),
1088+ mPixmapBinding (boost::function <void ()> (),
1089+ this,
1090+ this,
1091+ screen->serverGrabInterface ()),
1092 damage (None),
1093 damaged (false),
1094 redirected (cScreen->compositingActive ()),
1095 overlayWindow (false),
1096- bindFailed (false),
1097 opacity (OPAQUE),
1098 brightness (BRIGHT),
1099 saturation (COLOR),
1100@@ -118,6 +130,14 @@
1101 free (damageRects);
1102 }
1103
1104+
1105+
1106+bool
1107+PrivateCompositeWindow::bind ()
1108+{
1109+ return mPixmapBinding.bind ();
1110+}
1111+
1112 bool
1113 CompositeWindow::bind ()
1114 {
1115@@ -125,85 +145,61 @@
1116 return false;
1117
1118 redirect ();
1119- if (priv->needsRebind)
1120- {
1121- XWindowAttributes attr;
1122-
1123- /* don't try to bind window again if it failed previously */
1124- if (priv->bindFailed)
1125- return false;
1126-
1127- /* We have to grab the server here to make sure that window
1128- is mapped when getting the window pixmap */
1129- XGrabServer (screen->dpy ());
1130-
1131- /* Flush changes to the server and wait for it to process them */
1132- XSync (screen->dpy (), false);
1133- XGetWindowAttributes (screen->dpy (),
1134- ROOTPARENT (priv->window), &attr);
1135- if (attr.map_state != IsViewable)
1136- {
1137- XUngrabServer (screen->dpy ());
1138- XSync (screen->dpy (), false);
1139- priv->bindFailed = true;
1140- return false;
1141- }
1142-
1143- Pixmap newPixmap = XCompositeNameWindowPixmap
1144- (screen->dpy (), ROOTPARENT (priv->window));
1145- CompSize newSize = CompSize (attr.border_width * 2 + attr.width,
1146- attr.border_width * 2 + attr.height);
1147- XUngrabServer (screen->dpy ());
1148- XSync (screen->dpy (), false);
1149-
1150- if (newPixmap && newSize.width () && newSize.height ())
1151- {
1152- /* Notify renderer that a new pixmap is about to
1153- * be bound */
1154- if (priv->newPixmapReadyCallback)
1155- priv->newPixmapReadyCallback ();
1156-
1157- /* Release old pixmap */
1158- if (priv->pixmap)
1159- XFreePixmap (screen->dpy (), priv->pixmap);
1160-
1161- /* Assign new pixmap */
1162- priv->pixmap = newPixmap;
1163- priv->size = newSize;
1164-
1165- priv->needsRebind = false;
1166- }
1167- else
1168- {
1169- priv->bindFailed = true;
1170- priv->needsRebind = false;
1171- return false;
1172- }
1173- }
1174- return true;
1175+ return priv->bind ();
1176+}
1177+
1178+void
1179+PrivateCompositeWindow::release ()
1180+{
1181+ mPixmapBinding.release ();
1182 }
1183
1184 void
1185 CompositeWindow::release ()
1186 {
1187- priv->needsRebind = true;
1188+ return priv->release ();
1189+}
1190+
1191+Pixmap
1192+PrivateCompositeWindow::pixmap () const
1193+{
1194+ return mPixmapBinding.pixmap ();
1195+}
1196+
1197+WindowPixmapInterface::Ptr
1198+PrivateCompositeWindow::getPixmap ()
1199+{
1200+ Pixmap pixmap = XCompositeNameWindowPixmap (screen->dpy (), ROOTPARENT (window));
1201+ WindowPixmapInterface::Ptr p (new X11WindowPixmap (screen->dpy (), pixmap));
1202+ return p;
1203+}
1204+
1205+bool
1206+PrivateCompositeWindow::getAttributes (XWindowAttributes &attr)
1207+{
1208+ if (XGetWindowAttributes (screen->dpy (),
1209+ ROOTPARENT (window), &attr))
1210+ return true;
1211+
1212+ return false;
1213 }
1214
1215 Pixmap
1216 CompositeWindow::pixmap ()
1217 {
1218- static Pixmap nPixmap = None;
1219-
1220- if (priv->needsRebind)
1221- return nPixmap;
1222-
1223- return priv->pixmap;
1224+ return priv->pixmap ();
1225+}
1226+
1227+const CompSize &
1228+PrivateCompositeWindow::size () const
1229+{
1230+ return mPixmapBinding.size ();
1231 }
1232
1233 const CompSize &
1234 CompositeWindow::size ()
1235 {
1236- return priv->size;
1237+ return priv->size ();
1238 }
1239
1240 void
1241@@ -537,7 +533,7 @@
1242 switch (n)
1243 {
1244 case CompWindowNotifyMap:
1245- bindFailed = false;
1246+ allowFurtherRebindAttempts ();
1247 damaged = false;
1248 break;
1249 case CompWindowNotifyUnmap:
1250
1251=== modified file 'plugins/opengl/src/window.cpp'
1252--- plugins/opengl/src/window.cpp 2012-05-25 03:54:23 +0000
1253+++ plugins/opengl/src/window.cpp 2012-06-05 09:04:24 +0000
1254@@ -112,6 +112,8 @@
1255 priv->needsRebind = false;
1256 return true;
1257 }
1258+ else
1259+ return false;
1260 }
1261
1262 GLTexture::List textures =
1263
1264=== modified file 'src/CMakeLists.txt'
1265--- src/CMakeLists.txt 2012-05-24 00:55:17 +0000
1266+++ src/CMakeLists.txt 2012-06-05 09:04:24 +0000
1267@@ -9,6 +9,7 @@
1268 add_subdirectory( rect )
1269 add_subdirectory( region )
1270 add_subdirectory( window )
1271+add_subdirectory( servergrab )
1272
1273 IF (COMPIZ_BUILD_TESTING)
1274 add_subdirectory( privatescreen/tests )
1275@@ -57,6 +58,9 @@
1276 ${CMAKE_CURRENT_SOURCE_DIR}/rect/include
1277 ${CMAKE_CURRENT_SOURCE_DIR}/rect/src
1278
1279+ ${CMAKE_CURRENT_SOURCE_DIR}/servergrab/include
1280+ ${CMAKE_CURRENT_SOURCE_DIR}/servergrab/src
1281+
1282 ${CMAKE_CURRENT_SOURCE_DIR}/region/include
1283 ${CMAKE_CURRENT_SOURCE_DIR}/region/src
1284
1285@@ -162,6 +166,7 @@
1286 compiz_window_geometry_saver
1287 compiz_window_extents
1288 compiz_window_constrainment
1289+ compiz_servergrab
1290 -Wl,-no-whole-archive
1291 # ${CORE_MOD_LIBRARIES}
1292 )
1293
1294=== modified file 'src/event.cpp'
1295--- src/event.cpp 2012-06-01 03:47:24 +0000
1296+++ src/event.cpp 2012-06-05 09:04:24 +0000
1297@@ -37,6 +37,7 @@
1298 #include <X11/extensions/Xfixes.h>
1299
1300 #include <core/atoms.h>
1301+#include <core/servergrab.h>
1302 #include "privatescreen.h"
1303 #include "privatewindow.h"
1304 #include "privatestackdebugger.h"
1305@@ -1079,6 +1080,30 @@
1306 }
1307 }
1308
1309+ServerGrabInterface *
1310+CompScreenImpl::serverGrabInterface ()
1311+{
1312+ return static_cast <ServerGrabInterface *> (this);
1313+}
1314+
1315+void
1316+CompScreenImpl::grabServer ()
1317+{
1318+ XGrabServer (privateScreen.dpy);
1319+}
1320+
1321+void
1322+CompScreenImpl::syncServer ()
1323+{
1324+ XSync (privateScreen.dpy, false);
1325+}
1326+
1327+void
1328+CompScreenImpl::ungrabServer ()
1329+{
1330+ XUngrabServer (privateScreen.dpy);
1331+}
1332+
1333 void
1334 CompScreenImpl::_handleEvent (XEvent *event)
1335 {
1336
1337=== modified file 'src/plugin.cpp'
1338--- src/plugin.cpp 2012-05-15 15:01:16 +0000
1339+++ src/plugin.cpp 2012-06-05 09:04:24 +0000
1340@@ -24,6 +24,8 @@
1341 */
1342
1343 #include "core/plugin.h"
1344+
1345+/* XXX: This dependency needs to go away */
1346 #include "privatescreen.h"
1347
1348 #include <boost/scoped_array.hpp>
1349
1350=== modified file 'src/plugin/CMakeLists.txt'
1351--- src/plugin/CMakeLists.txt 2012-05-21 06:43:20 +0000
1352+++ src/plugin/CMakeLists.txt 2012-06-05 09:04:24 +0000
1353@@ -14,6 +14,7 @@
1354 ${compiz_SOURCE_DIR}/src/window/extents/include
1355
1356 ${compiz_SOURCE_DIR}/src/pluginclasshandler/include
1357+ ${compiz_SOURCE_DIR}/src/servergrab/include
1358
1359 ${COMPIZ_INCLUDE_DIRS}
1360
1361
1362=== modified file 'src/privatescreen.h'
1363--- src/privatescreen.h 2012-05-23 07:37:37 +0000
1364+++ src/privatescreen.h 2012-06-05 09:04:24 +0000
1365@@ -33,6 +33,7 @@
1366 #include <core/point.h>
1367 #include <core/timer.h>
1368 #include <core/plugin.h>
1369+#include <core/servergrab.h>
1370 #include <time.h>
1371 #include <boost/shared_ptr.hpp>
1372
1373@@ -826,6 +827,7 @@
1374 * X server.
1375 */
1376 class CompScreenImpl : public CompScreen,
1377+ public ServerGrabInterface,
1378 ::compiz::private_screen::DesktopWindowCount,
1379 ::compiz::private_screen::MapNum,
1380 ::compiz::private_screen::Ping,
1381@@ -1045,6 +1047,8 @@
1382 virtual void processEvents ();
1383 virtual void alwaysHandleEvent (XEvent *event);
1384
1385+ virtual ServerGrabInterface * serverGrabInterface ();
1386+
1387 virtual void updatePassiveKeyGrabs () const;
1388 virtual void updatePassiveButtonGrabs(Window serverFrame);
1389
1390@@ -1145,6 +1149,10 @@
1391 virtual void _matchPropertyChanged(CompWindow *);
1392 virtual void _outputChangeNotify();
1393
1394+ void grabServer ();
1395+ void ungrabServer ();
1396+ void syncServer ();
1397+
1398 bool handlePingTimeout();
1399
1400 Window below;
1401
1402=== modified file 'src/privatescreen/tests/CMakeLists.txt'
1403--- src/privatescreen/tests/CMakeLists.txt 2012-05-21 06:43:20 +0000
1404+++ src/privatescreen/tests/CMakeLists.txt 2012-06-05 09:04:24 +0000
1405@@ -17,6 +17,7 @@
1406 ${compiz_SOURCE_DIR}/src/window/geometry/include
1407 ${compiz_SOURCE_DIR}/src/window/extents/include
1408 ${compiz_SOURCE_DIR}/src/screen/extents/include
1409+ ${compiz_SOURCE_DIR}/src/servergrab/include
1410
1411 ${compiz_SOURCE_DIR}/src/pluginclasshandler/include
1412
1413
1414=== modified file 'src/privatescreen/tests/test-privatescreen.cpp'
1415--- src/privatescreen/tests/test-privatescreen.cpp 2012-05-23 07:37:37 +0000
1416+++ src/privatescreen/tests/test-privatescreen.cpp 2012-06-05 09:04:24 +0000
1417@@ -204,6 +204,11 @@
1418 MOCK_METHOD1(getProtocols, unsigned int (Window id));
1419 MOCK_METHOD1(getWindowType, unsigned int (Window id));
1420 MOCK_METHOD1(getWindowState, unsigned int (Window id));
1421+
1422+ MOCK_METHOD0(grabServer, void ());
1423+ MOCK_METHOD0(ungrabServer, void ());
1424+ MOCK_METHOD0(syncServer, void ());
1425+ MOCK_METHOD0(serverGrabInterface, ServerGrabInterface * ());
1426 };
1427
1428 class MockViewportRetreival :
1429
1430=== added directory 'src/servergrab'
1431=== added file 'src/servergrab/CMakeLists.txt'
1432--- src/servergrab/CMakeLists.txt 1970-01-01 00:00:00 +0000
1433+++ src/servergrab/CMakeLists.txt 2012-06-05 09:04:24 +0000
1434@@ -0,0 +1,42 @@
1435+INCLUDE_DIRECTORIES (
1436+ ${CMAKE_CURRENT_SOURCE_DIR}/include
1437+ ${CMAKE_CURRENT_SOURCE_DIR}/src
1438+
1439+ ${Boost_INCLUDE_DIRS}
1440+)
1441+
1442+LINK_DIRECTORIES (${GLIBMM_LIBRARY_DIRS})
1443+
1444+SET (
1445+ PUBLIC_HEADERS
1446+ ${CMAKE_CURRENT_SOURCE_DIR}/include/core/servergrab.h
1447+)
1448+
1449+SET (
1450+ PRIVATE_HEADERS
1451+)
1452+
1453+SET(
1454+ SRCS
1455+ ${CMAKE_CURRENT_SOURCE_DIR}/src/servergrab.cpp
1456+)
1457+
1458+ADD_LIBRARY(
1459+ compiz_servergrab STATIC
1460+
1461+ ${SRCS}
1462+
1463+ ${PUBLIC_HEADERS}
1464+ ${PRIVATE_HEADERS}
1465+)
1466+
1467+IF (COMPIZ_BUILD_TESTING)
1468+ADD_SUBDIRECTORY( ${CMAKE_CURRENT_SOURCE_DIR}/tests )
1469+ENDIF (COMPIZ_BUILD_TESTING)
1470+
1471+SET_TARGET_PROPERTIES(
1472+ compiz_servergrab PROPERTIES
1473+ PUBLIC_HEADER "${PUBLIC_HEADERS}"
1474+)
1475+
1476+install (FILES ${PUBLIC_HEADERS} DESTINATION ${COMPIZ_CORE_INCLUDE_DIR})
1477
1478=== added directory 'src/servergrab/include'
1479=== added directory 'src/servergrab/include/core'
1480=== added file 'src/servergrab/include/core/servergrab.h'
1481--- src/servergrab/include/core/servergrab.h 1970-01-01 00:00:00 +0000
1482+++ src/servergrab/include/core/servergrab.h 2012-06-05 09:04:24 +0000
1483@@ -0,0 +1,51 @@
1484+/*
1485+ * Copyright © 2012 Canonical Ltd.
1486+ *
1487+ * Permission to use, copy, modify, distribute, and sell this software
1488+ * and its documentation for any purpose is hereby granted without
1489+ * fee, provided that the above copyright notice appear in all copies
1490+ * and that both that copyright notice and this permission notice
1491+ * appear in supporting documentation, and that the name of
1492+ * Canonical Ltd. not be used in advertising or publicity pertaining to
1493+ * distribution of the software without specific, written prior permission.
1494+ * Canonical Ltd. makes no representations about the suitability of this
1495+ * software for any purpose. It is provided "as is" without express or
1496+ * implied warranty.
1497+ *
1498+ * CANONICAL, LTD. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
1499+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
1500+ * NO EVENT SHALL CANONICAL, LTD. BE LIABLE FOR ANY SPECIAL, INDIRECT OR
1501+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
1502+ * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
1503+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
1504+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
1505+ *
1506+ * Authored by: Sam Spilsbury <sam.spilsbury@canonical.com>
1507+ */
1508+
1509+#ifndef _COMP_SERVER_GRAB_H
1510+#define _COMP_SERVER_GRAB_H
1511+
1512+class ServerGrabInterface
1513+{
1514+ public:
1515+ virtual ~ServerGrabInterface () {}
1516+
1517+ virtual void grabServer () = 0;
1518+ virtual void ungrabServer () = 0;
1519+ virtual void syncServer () = 0;
1520+};
1521+
1522+class ServerLock
1523+{
1524+ public:
1525+
1526+ ServerLock (ServerGrabInterface *i);
1527+ ~ServerLock ();
1528+
1529+ private:
1530+
1531+ ServerGrabInterface *mServerGrab;
1532+};
1533+
1534+#endif
1535
1536=== added directory 'src/servergrab/src'
1537=== added file 'src/servergrab/src/servergrab.cpp'
1538--- src/servergrab/src/servergrab.cpp 1970-01-01 00:00:00 +0000
1539+++ src/servergrab/src/servergrab.cpp 2012-06-05 09:04:24 +0000
1540@@ -0,0 +1,39 @@
1541+/*
1542+ * Copyright © 2012 Canonical Ltd.
1543+ *
1544+ * Permission to use, copy, modify, distribute, and sell this software
1545+ * and its documentation for any purpose is hereby granted without
1546+ * fee, provided that the above copyright notice appear in all copies
1547+ * and that both that copyright notice and this permission notice
1548+ * appear in supporting documentation, and that the name of
1549+ * Canonical Ltd. not be used in advertising or publicity pertaining to
1550+ * distribution of the software without specific, written prior permission.
1551+ * Canonical Ltd. makes no representations about the suitability of this
1552+ * software for any purpose. It is provided "as is" without express or
1553+ * implied warranty.
1554+ *
1555+ * CANONICAL, LTD. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
1556+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
1557+ * NO EVENT SHALL CANONICAL, LTD. BE LIABLE FOR ANY SPECIAL, INDIRECT OR
1558+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
1559+ * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
1560+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
1561+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
1562+ *
1563+ * Authored by: Sam Spilsbury <sam.spilsbury@canonical.com>
1564+ */
1565+
1566+#include <core/servergrab.h>
1567+
1568+ServerLock::ServerLock (ServerGrabInterface *i) :
1569+ mServerGrab (i)
1570+{
1571+ mServerGrab->grabServer ();
1572+ mServerGrab->syncServer ();
1573+}
1574+
1575+ServerLock::~ServerLock ()
1576+{
1577+ mServerGrab->ungrabServer ();
1578+ mServerGrab->syncServer ();
1579+}
1580
1581=== added directory 'src/servergrab/tests'
1582=== added file 'src/servergrab/tests/CMakeLists.txt'
1583--- src/servergrab/tests/CMakeLists.txt 1970-01-01 00:00:00 +0000
1584+++ src/servergrab/tests/CMakeLists.txt 2012-06-05 09:04:24 +0000
1585@@ -0,0 +1,14 @@
1586+include_directories(${CMAKE_CURRENT_SOURCE_DIR})
1587+
1588+add_executable (compiz_test_servergrab
1589+ ${CMAKE_CURRENT_SOURCE_DIR}/test-servergrab.cpp)
1590+
1591+target_link_libraries (compiz_test_servergrab
1592+ compiz_servergrab
1593+ ${GTEST_BOTH_LIBRARIES}
1594+ ${GMOCK_LIBRARY}
1595+ ${GMOCK_MAIN_LIBRARY}
1596+ ${CMAKE_THREAD_LIBS_INIT} # Link in pthread.
1597+ )
1598+
1599+gtest_add_tests (compiz_test_servergrab "" ${CMAKE_CURRENT_SOURCE_DIR}/test-servergrab.cpp)
1600
1601=== added file 'src/servergrab/tests/test-servergrab.cpp'
1602--- src/servergrab/tests/test-servergrab.cpp 1970-01-01 00:00:00 +0000
1603+++ src/servergrab/tests/test-servergrab.cpp 2012-06-05 09:04:24 +0000
1604@@ -0,0 +1,55 @@
1605+/*
1606+ * Copyright © 2012 Canonical Ltd.
1607+ *
1608+ * Permission to use, copy, modify, distribute, and sell this software
1609+ * and its documentation for any purpose is hereby granted without
1610+ * fee, provided that the above copyright notice appear in all copies
1611+ * and that both that copyright notice and this permission notice
1612+ * appear in supporting documentation, and that the name of
1613+ * Canonical Ltd. not be used in advertising or publicity pertaining to
1614+ * distribution of the software without specific, written prior permission.
1615+ * Canonical Ltd. makes no representations about the suitability of this
1616+ * software for any purpose. It is provided "as is" without express or
1617+ * implied warranty.
1618+ *
1619+ * CANONICAL, LTD. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
1620+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
1621+ * NO EVENT SHALL CANONICAL, LTD. BE LIABLE FOR ANY SPECIAL, INDIRECT OR
1622+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
1623+ * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
1624+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
1625+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
1626+ *
1627+ * Authored by: Sam Spilsbury <sam.spilsbury@canonical.com>
1628+ */
1629+
1630+#include <gtest/gtest.h>
1631+#include <gmock/gmock.h>
1632+#include <core/servergrab.h>
1633+
1634+class MockServerGrab :
1635+ public ServerGrabInterface
1636+{
1637+ public:
1638+
1639+ MOCK_METHOD0 (grabServer, void ());
1640+ MOCK_METHOD0 (ungrabServer, void ());
1641+ MOCK_METHOD0 (syncServer, void ());
1642+};
1643+
1644+class ServerGrabTest :
1645+ public ::testing::Test
1646+{
1647+};
1648+
1649+TEST(ServerGrabTest, TestServerGrab)
1650+{
1651+ MockServerGrab msg;
1652+
1653+ EXPECT_CALL (msg, grabServer ());
1654+ EXPECT_CALL (msg, syncServer ()).Times (2);
1655+
1656+ ServerLock l (&msg);
1657+
1658+ EXPECT_CALL (msg, ungrabServer ());
1659+}

Subscribers

People subscribed via source and target branches