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

Proposed by Sam Spilsbury
Status: Superseded
Proposed branch: lp:~compiz-team/compiz/compiz.fix_1002602_tests
Merge into: lp:compiz/0.9.8
Diff against target: 1665 lines (+1201/-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/pixmapbinder/CMakeLists.txt (+43/-0)
plugins/composite/src/pixmapbinder/include/pixmapbinder.h (+191/-0)
plugins/composite/src/pixmapbinder/src/pixmapbinder.cpp (+141/-0)
plugins/composite/src/pixmapbinder/tests/CMakeLists.txt (+24/-0)
plugins/composite/src/pixmapbinder/tests/test-composite-pixmapbinder.cpp (+448/-0)
plugins/composite/src/privates.h (+22/-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 Needs Fixing
Compiz Maintainers Pending
Review via email: mp+107503@code.launchpad.net

This proposal has been superseded by a proposal from 2012-05-28.

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.
3233. By Sam Spilsbury

Compile size.cpp directly ... don't copy and paste

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

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
3234. By Sam Spilsbury

Added missing files

3235. By Sam Spilsbury

Rename PixmapRebinder to PixmapBinding

3236. By Sam Spilsbury

Renamed the file too

3237. By Sam Spilsbury

Fix copyright and s/PixmapBinder/PixmapBinding/

3238. By Daniel van Vugt

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

Unmerged revisions

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-05-28 07:56:18 +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-05-28 07:56:18 +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-05-28 07:56:18 +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-05-28 07:56:18 +0000
49@@ -2,5 +2,9 @@
50
51 include (CompizPlugin)
52
53-compiz_plugin (composite)
54-
55+include_directories (${CMAKE_CURRENT_SOURCE_DIR}/src/pixmapbinder/include)
56+link_directories (${CMAKE_CURRENT_BINARY_DIR}/src/pixmapbinder)
57+
58+compiz_plugin (composite LIBRARIES compiz_composite_pixmapbinder)
59+
60+add_subdirectory (src/pixmapbinder)
61
62=== modified file 'plugins/composite/include/composite/composite.h'
63--- plugins/composite/include/composite/composite.h 2012-05-25 03:54:23 +0000
64+++ plugins/composite/include/composite/composite.h 2012-05-28 07:56:18 +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/pixmapbinder'
93=== added file 'plugins/composite/src/pixmapbinder/CMakeLists.txt'
94--- plugins/composite/src/pixmapbinder/CMakeLists.txt 1970-01-01 00:00:00 +0000
95+++ plugins/composite/src/pixmapbinder/CMakeLists.txt 2012-05-28 07:56:18 +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/pixmapbinder.h
115+)
116+
117+SET(
118+ SRCS
119+ ${CMAKE_CURRENT_SOURCE_DIR}/src/pixmapbinder.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_pixmapbinder 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_pixmapbinder
137+ compiz_servergrab
138+ ${X11_LIBRARIES}
139+)
140
141=== added directory 'plugins/composite/src/pixmapbinder/include'
142=== added file 'plugins/composite/src/pixmapbinder/include/pixmapbinder.h'
143--- plugins/composite/src/pixmapbinder/include/pixmapbinder.h 1970-01-01 00:00:00 +0000
144+++ plugins/composite/src/pixmapbinder/include/pixmapbinder.h 2012-05-28 07:56:18 +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 PixmapRebinder :
302+ public CompositePixmapRebindInterface
303+{
304+ public:
305+
306+ typedef boost::function <void ()> NewPixmapReadyCallback;
307+
308+ PixmapRebinder (const NewPixmapReadyCallback &,
309+ WindowPixmapGetInterface *,
310+ WindowAttributesGetInterface *,
311+ ServerGrabInterface *);
312+
313+ ~PixmapRebinder ();
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/pixmapbinder/src'
339=== added file 'plugins/composite/src/pixmapbinder/src/pixmapbinder.cpp'
340--- plugins/composite/src/pixmapbinder/src/pixmapbinder.cpp 1970-01-01 00:00:00 +0000
341+++ plugins/composite/src/pixmapbinder/src/pixmapbinder.cpp 2012-05-28 07:56:18 +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 "pixmapbinder.h"
374+
375+PixmapRebinder::PixmapRebinder (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+PixmapRebinder::~PixmapRebinder ()
391+{
392+ needsRebind = false;
393+}
394+
395+const CompSize &
396+PixmapRebinder::size () const
397+{
398+ return mSize;
399+}
400+
401+Pixmap
402+PixmapRebinder::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+PixmapRebinder::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+PixmapRebinder::release ()
468+{
469+ needsRebind = true;
470+}
471+
472+void
473+PixmapRebinder::setNewPixmapReadyCallback (const NewPixmapReadyCallback &cb)
474+{
475+ newPixmapReadyCallback = cb;
476+}
477+
478+void
479+PixmapRebinder::allowFurtherRebindAttempts ()
480+{
481+ bindFailed = false;
482+ needsRebind = true;
483+}
484
485=== added directory 'plugins/composite/src/pixmapbinder/tests'
486=== added file 'plugins/composite/src/pixmapbinder/tests/CMakeLists.txt'
487--- plugins/composite/src/pixmapbinder/tests/CMakeLists.txt 1970-01-01 00:00:00 +0000
488+++ plugins/composite/src/pixmapbinder/tests/CMakeLists.txt 2012-05-28 07:56:18 +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_pixmapbinder
503+ ${CMAKE_CURRENT_SOURCE_DIR}/test-composite-pixmapbinder.cpp)
504+
505+target_link_libraries (compiz_test_composite_pixmapbinder
506+ compiz_composite_pixmapbinder
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_pixmapbinder "" ${CMAKE_CURRENT_SOURCE_DIR}/test-composite-pixmapbinder.cpp)
514
515=== added file 'plugins/composite/src/pixmapbinder/tests/test-composite-pixmapbinder.cpp'
516--- plugins/composite/src/pixmapbinder/tests/test-composite-pixmapbinder.cpp 1970-01-01 00:00:00 +0000
517+++ plugins/composite/src/pixmapbinder/tests/test-composite-pixmapbinder.cpp 2012-05-28 07:56:18 +0000
518@@ -0,0 +1,448 @@
519+/*
520+ * Copyright © 2012 Canonical Ltd.
521+ * Copyright © 2008 Dennis Kasprzyk
522+ * Copyright © 2007 Novell, Inc.
523+ *
524+ * Permission to use, copy, modify, distribute, and sell this software
525+ * and its documentation for any purpose is hereby granted without
526+ * fee, provided that the above copyright notice appear in all copies
527+ * and that both that copyright notice and this permission notice
528+ * appear in supporting documentation, and that the name of
529+ * Dennis Kasprzyk not be used in advertising or publicity pertaining to
530+ * distribution of the software without specific, written prior permission.
531+ * Dennis Kasprzyk makes no representations about the suitability of this
532+ * software for any purpose. It is provided "as is" without express or
533+ * implied warranty.
534+ *
535+ * DENNIS KASPRZYK DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
536+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
537+ * NO EVENT SHALL DENNIS KASPRZYK BE LIABLE FOR ANY SPECIAL, INDIRECT OR
538+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
539+ * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
540+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
541+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
542+ *
543+ * Authors: Dennis Kasprzyk <onestone@compiz-fusion.org>
544+ * David Reveman <davidr@novell.com>
545+ * Sam Spilsbury <sam.spilsbury@canonical.com>
546+ */
547+
548+#include <boost/shared_ptr.hpp>
549+#include <boost/make_shared.hpp>
550+
551+#include <gtest/gtest.h>
552+#include <gmock/gmock.h>
553+
554+#include <core/servergrab.h>
555+#include "pixmapbinder.h"
556+
557+using ::testing::Invoke;
558+using ::testing::Return;
559+using ::testing::_;
560+
561+class CompositePixmapBinderTest :
562+ public ::testing::Test
563+{
564+};
565+
566+class MockWindowPixmapGet :
567+ public WindowPixmapGetInterface
568+{
569+ public:
570+
571+ MOCK_METHOD0 (getPixmap, WindowPixmapInterface::Ptr ());
572+};
573+
574+class FakeWindowAttributesGet :
575+ public WindowAttributesGetInterface
576+{
577+ public:
578+
579+ FakeWindowAttributesGet (XWindowAttributes &wa) :
580+ mAttributes (wa)
581+ {
582+ }
583+
584+ bool getAttributes (XWindowAttributes &wa)
585+ {
586+ wa = mAttributes;
587+ return true;
588+ }
589+
590+ private:
591+
592+ XWindowAttributes mAttributes;
593+};
594+
595+class MockWindowAttributesGet :
596+ public WindowAttributesGetInterface
597+{
598+ public:
599+
600+ MOCK_METHOD1 (getAttributes, bool (XWindowAttributes &));
601+};
602+
603+class MockPixmap :
604+ public WindowPixmapInterface
605+{
606+ public:
607+
608+ typedef boost::shared_ptr <MockPixmap> Ptr;
609+
610+ MOCK_CONST_METHOD0 (pixmap, Pixmap ());
611+ MOCK_METHOD0 (releasePixmap, void ());
612+};
613+
614+class MockServerGrab :
615+ public ServerGrabInterface
616+{
617+ public:
618+
619+ MOCK_METHOD0 (grabServer, void ());
620+ MOCK_METHOD0 (ungrabServer, void ());
621+ MOCK_METHOD0 (syncServer, void ());
622+};
623+
624+class PixmapReadyInterface
625+{
626+ public:
627+
628+ virtual ~PixmapReadyInterface () {}
629+
630+ virtual void ready () = 0;
631+};
632+
633+class MockPixmapReady :
634+ public PixmapReadyInterface
635+{
636+ public:
637+
638+ MOCK_METHOD0 (ready, void ());
639+};
640+
641+TEST(CompositePixmapBinderTest, TestInitialBindSuccess)
642+{
643+ /* Leave this here
644+ * There's a bug in Google Mock at the moment where
645+ * if a function with an expectation which returns
646+ * Mock B through a container is itself contained in
647+ * Mock A, then when Mock A is destroyed, it will first
648+ * lock a mutex, and then it will invoke
649+ * the destructor the container containing Mock B which
650+ * in turn might invoke Mock B's destructor and thus
651+ * lock the same mutex in the same thread (deadlock).
652+ *
653+ * Keeping this reference here ensures that MockPixmap
654+ * stays alive while MockWindowPixmapGet is being destroyed
655+ */
656+ MockPixmap::Ptr wp (boost::make_shared <MockPixmap> ());
657+
658+ MockWindowPixmapGet mwpg;
659+ MockWindowAttributesGet mwag;
660+ MockServerGrab msg;
661+ XWindowAttributes xwa;
662+
663+ xwa.width = 100;
664+ xwa.height = 200;
665+ xwa.map_state = IsViewable;
666+ xwa.border_width = 1;
667+
668+ FakeWindowAttributesGet fwag (xwa);
669+
670+ MockPixmapReady ready;
671+
672+ boost::function <void ()> readyCb (boost::bind (&PixmapReadyInterface::ready, &ready));
673+
674+ PixmapRebinder pr (readyCb,
675+ &mwpg,
676+ &mwag,
677+ &msg);
678+
679+ EXPECT_CALL (msg, grabServer ());
680+ EXPECT_CALL (msg, syncServer ()).Times (2);
681+ EXPECT_CALL (mwag, getAttributes (_)).WillOnce (Invoke (&fwag, &FakeWindowAttributesGet::getAttributes));
682+ EXPECT_CALL (mwpg, getPixmap ()).WillOnce (Return (boost::shared_static_cast <WindowPixmapInterface> (wp)));
683+
684+ EXPECT_CALL (*wp, pixmap ()).WillOnce (Return (1));
685+
686+ EXPECT_CALL (ready, ready ());
687+ EXPECT_CALL (msg, ungrabServer ());
688+
689+ pr.bind ();
690+
691+ EXPECT_CALL (*wp, pixmap ()).WillOnce (Return (1));
692+
693+ EXPECT_EQ (pr.pixmap (), 1);
694+ EXPECT_EQ (pr.size (), CompSize (102, 202));
695+
696+ EXPECT_CALL (*wp, releasePixmap ());
697+}
698+
699+TEST(CompositePixmapBinderTest, TestInitialBindSuccessNoRebind)
700+{
701+ MockPixmap::Ptr wp (boost::make_shared <MockPixmap> ());
702+
703+ MockWindowPixmapGet mwpg;
704+ MockWindowAttributesGet mwag;
705+ MockServerGrab msg;
706+ XWindowAttributes xwa;
707+
708+ xwa.width = 100;
709+ xwa.height = 200;
710+ xwa.map_state = IsViewable;
711+ xwa.border_width = 1;
712+
713+ FakeWindowAttributesGet fwag (xwa);
714+
715+ MockPixmapReady ready;
716+
717+ boost::function <void ()> readyCb (boost::bind (&PixmapReadyInterface::ready, &ready));
718+
719+ PixmapRebinder pr (readyCb,
720+ &mwpg,
721+ &mwag,
722+ &msg);
723+
724+ EXPECT_CALL (msg, grabServer ());
725+ EXPECT_CALL (msg, syncServer ()).Times (2);
726+ EXPECT_CALL (mwag, getAttributes (_)).WillOnce (Invoke (&fwag, &FakeWindowAttributesGet::getAttributes));
727+ EXPECT_CALL (mwpg, getPixmap ()).WillOnce (Return (boost::shared_static_cast <WindowPixmapInterface> (wp)));
728+
729+ EXPECT_CALL (*wp, pixmap ()).WillOnce (Return (1));
730+
731+ EXPECT_CALL (ready, ready ());
732+ EXPECT_CALL (msg, ungrabServer ());
733+
734+ EXPECT_TRUE (pr.bind ());
735+ EXPECT_TRUE (pr.bind ());
736+
737+ EXPECT_CALL (*wp, pixmap ()).WillOnce (Return (1));
738+
739+ EXPECT_EQ (pr.pixmap (), 1);
740+ EXPECT_EQ (pr.size (), CompSize (102, 202));
741+
742+ EXPECT_CALL (*wp, releasePixmap ());
743+}
744+
745+TEST(CompositePixmapBinderTest, TestRebindAfterRelease)
746+{
747+ MockPixmap::Ptr wp (boost::make_shared <MockPixmap> ());
748+
749+ MockWindowPixmapGet mwpg;
750+ MockWindowAttributesGet mwag;
751+ MockServerGrab msg;
752+ XWindowAttributes xwa;
753+
754+ xwa.width = 100;
755+ xwa.height = 200;
756+ xwa.map_state = IsViewable;
757+ xwa.border_width = 1;
758+
759+ FakeWindowAttributesGet fwag (xwa);
760+
761+ MockPixmapReady ready;
762+
763+ boost::function <void ()> readyCb (boost::bind (&PixmapReadyInterface::ready, &ready));
764+
765+ PixmapRebinder pr (readyCb,
766+ &mwpg,
767+ &mwag,
768+ &msg);
769+
770+ EXPECT_CALL (msg, grabServer ());
771+ EXPECT_CALL (msg, syncServer ()).Times (2);
772+ EXPECT_CALL (mwag, getAttributes (_)).WillOnce (Invoke (&fwag, &FakeWindowAttributesGet::getAttributes));
773+ EXPECT_CALL (mwpg, getPixmap ()).WillOnce (Return (boost::shared_static_cast <WindowPixmapInterface> (wp)));
774+
775+ EXPECT_CALL (*wp, pixmap ()).WillOnce (Return (1));
776+
777+ EXPECT_CALL (ready, ready ());
778+ EXPECT_CALL (msg, ungrabServer ());
779+
780+ EXPECT_TRUE (pr.bind ());
781+
782+ EXPECT_CALL (*wp, pixmap ()).WillOnce (Return (1));
783+
784+ EXPECT_EQ (pr.pixmap (), 1);
785+ EXPECT_EQ (pr.size (), CompSize (102, 202));
786+
787+ EXPECT_CALL (*wp, releasePixmap ());
788+
789+ pr.release ();
790+
791+ EXPECT_CALL (msg, grabServer ());
792+ EXPECT_CALL (msg, syncServer ()).Times (2);
793+ EXPECT_CALL (mwag, getAttributes (_)).WillOnce (Invoke (&fwag, &FakeWindowAttributesGet::getAttributes));
794+ EXPECT_CALL (mwpg, getPixmap ()).WillOnce (Return (boost::shared_static_cast <WindowPixmapInterface> (wp)));
795+
796+ EXPECT_CALL (*wp, pixmap ()).WillOnce (Return (1));
797+
798+ EXPECT_CALL (ready, ready ());
799+ EXPECT_CALL (msg, ungrabServer ());
800+
801+ EXPECT_TRUE (pr.bind ());
802+
803+ EXPECT_CALL (*wp, pixmap ()).WillOnce (Return (1));
804+
805+ EXPECT_EQ (pr.pixmap (), 1);
806+ EXPECT_EQ (pr.size (), CompSize (102, 202));
807+
808+ EXPECT_CALL (*wp, releasePixmap ());
809+}
810+
811+TEST(CompositePixmapBinderTest, TestInitialBindFailureWindowUnmapped)
812+{
813+ MockWindowPixmapGet mwpg;
814+ MockWindowAttributesGet mwag;
815+ MockServerGrab msg;
816+ XWindowAttributes xwa;
817+
818+ xwa.width = 100;
819+ xwa.height = 200;
820+ xwa.map_state = IsUnmapped;
821+ xwa.border_width = 1;
822+
823+ FakeWindowAttributesGet fwag (xwa);
824+
825+ PixmapRebinder pr (boost::function <void ()> (),
826+ &mwpg,
827+ &mwag,
828+ &msg);
829+
830+ EXPECT_CALL (msg, grabServer ());
831+ EXPECT_CALL (msg, syncServer ()).Times (2);
832+ EXPECT_CALL (mwag, getAttributes (_)).WillOnce (Invoke (&fwag, &FakeWindowAttributesGet::getAttributes));
833+
834+ EXPECT_CALL (msg, ungrabServer ());
835+
836+ EXPECT_FALSE (pr.bind ());
837+
838+ EXPECT_EQ (pr.pixmap (), 0);
839+ EXPECT_EQ (pr.size (), CompSize (0, 0));
840+}
841+
842+TEST(CompositePixmapBinderTest, TestInitialBindFailureWindowZeroSize)
843+{
844+ MockWindowPixmapGet mwpg;
845+ MockWindowAttributesGet mwag;
846+ MockServerGrab msg;
847+ XWindowAttributes xwa;
848+
849+ xwa.width = 0;
850+ xwa.height = 0;
851+ xwa.map_state = IsViewable;
852+ xwa.border_width = 0;
853+
854+ FakeWindowAttributesGet fwag (xwa);
855+
856+ PixmapRebinder pr (boost::function <void ()> (),
857+ &mwpg,
858+ &mwag,
859+ &msg);
860+
861+ EXPECT_CALL (msg, grabServer ());
862+ EXPECT_CALL (msg, syncServer ()).Times (2);
863+ EXPECT_CALL (mwag, getAttributes (_)).WillOnce (Invoke (&fwag, &FakeWindowAttributesGet::getAttributes));
864+
865+ EXPECT_CALL (msg, ungrabServer ());
866+
867+ EXPECT_FALSE (pr.bind ());
868+
869+ EXPECT_EQ (pr.pixmap (), 0);
870+ EXPECT_EQ (pr.size (), CompSize (0, 0));
871+}
872+
873+TEST(CompositePixmapBinderTest, TestInitialBindFailureNilPixmapReturned)
874+{
875+ MockPixmap::Ptr wp (boost::make_shared <MockPixmap> ());
876+
877+ MockWindowPixmapGet mwpg;
878+ MockWindowAttributesGet mwag;
879+ MockServerGrab msg;
880+ XWindowAttributes xwa;
881+
882+ xwa.width = 100;
883+ xwa.height = 200;
884+ xwa.map_state = IsViewable;
885+ xwa.border_width = 0;
886+
887+ FakeWindowAttributesGet fwag (xwa);
888+
889+ PixmapRebinder pr (boost::function <void ()> (),
890+ &mwpg,
891+ &mwag,
892+ &msg);
893+
894+ EXPECT_CALL (msg, grabServer ());
895+ EXPECT_CALL (msg, syncServer ()).Times (2);
896+ EXPECT_CALL (mwag, getAttributes (_)).WillOnce (Invoke (&fwag, &FakeWindowAttributesGet::getAttributes));
897+ EXPECT_CALL (mwpg, getPixmap ()).WillOnce (Return (boost::shared_static_cast <WindowPixmapInterface> (wp)));
898+
899+ EXPECT_CALL (*wp, pixmap ()).WillOnce (Return (0));
900+
901+ EXPECT_CALL (msg, ungrabServer ());
902+
903+ EXPECT_FALSE (pr.bind ());
904+
905+ EXPECT_EQ (pr.pixmap (), 0);
906+ EXPECT_EQ (pr.size (), CompSize (0, 0));
907+}
908+
909+TEST(CompositePixmapBinderTest, TestInitialBindFailureWindowUnmappedSuccessOnRemap)
910+{
911+ MockPixmap::Ptr wp (boost::make_shared <MockPixmap> ());
912+
913+ MockWindowPixmapGet mwpg;
914+ MockWindowAttributesGet mwag;
915+ MockServerGrab msg;
916+ XWindowAttributes xwa;
917+
918+ xwa.width = 100;
919+ xwa.height = 200;
920+ xwa.map_state = IsUnmapped;
921+ xwa.border_width = 1;
922+
923+ FakeWindowAttributesGet fwag (xwa);
924+
925+ PixmapRebinder pr (boost::function <void ()> (),
926+ &mwpg,
927+ &mwag,
928+ &msg);
929+
930+ EXPECT_CALL (msg, grabServer ());
931+ EXPECT_CALL (msg, syncServer ()).Times (2);
932+ EXPECT_CALL (mwag, getAttributes (_)).WillOnce (Invoke (&fwag, &FakeWindowAttributesGet::getAttributes));
933+
934+ EXPECT_CALL (msg, ungrabServer ());
935+
936+ EXPECT_FALSE (pr.bind ());
937+
938+ EXPECT_EQ (pr.pixmap (), 0);
939+ EXPECT_EQ (pr.size (), CompSize (0, 0));
940+
941+ EXPECT_FALSE (pr.bind ());
942+
943+ pr.allowFurtherRebindAttempts ();
944+
945+ xwa.width = 100;
946+ xwa.height = 200;
947+ xwa.map_state = IsViewable;
948+ xwa.border_width = 1;
949+
950+ FakeWindowAttributesGet fwag2 (xwa);
951+
952+ EXPECT_CALL (msg, grabServer ());
953+ EXPECT_CALL (msg, syncServer ()).Times (2);
954+ EXPECT_CALL (mwag, getAttributes (_)).WillOnce (Invoke (&fwag2, &FakeWindowAttributesGet::getAttributes));
955+ EXPECT_CALL (mwpg, getPixmap ()).WillOnce (Return (boost::shared_static_cast <WindowPixmapInterface> (wp)));
956+
957+ EXPECT_CALL (msg, ungrabServer ());
958+
959+ EXPECT_CALL (*wp, pixmap ()).WillOnce (Return (1));
960+
961+ EXPECT_TRUE (pr.bind ());
962+
963+ EXPECT_CALL (*wp, pixmap ()).WillOnce (Return (1));
964+ EXPECT_EQ (pr.pixmap (), 1);
965+ EXPECT_EQ (pr.size (), CompSize (102, 202));
966+}
967
968=== modified file 'plugins/composite/src/privates.h'
969--- plugins/composite/src/privates.h 2012-05-25 03:54:23 +0000
970+++ plugins/composite/src/privates.h 2012-05-28 07:56:18 +0000
971@@ -28,9 +28,13 @@
972 #ifndef _COMPOSITE_PRIVATES_H
973 #define _COMPOSITE_PRIVATES_H
974
975+#include <memory>
976+#include <boost/shared_ptr.hpp>
977+
978 #include <composite/composite.h>
979 #include <core/atoms.h>
980
981+#include "pixmapbinder.h"
982 #include "composite_options.h"
983
984 extern CompPlugin::VTable *compositeVTable;
985@@ -106,9 +110,14 @@
986
987 Atom cmSnAtom;
988 Window newCmSnOwner;
989+ private:
990 };
991
992-class PrivateCompositeWindow : WindowInterface
993+class PrivateCompositeWindow :
994+ public WindowInterface,
995+ public CompositePixmapRebindInterface,
996+ public WindowPixmapGetInterface,
997+ public WindowAttributesGetInterface
998 {
999 public:
1000 PrivateCompositeWindow (CompWindow *w, CompositeWindow *cw);
1001@@ -118,6 +127,13 @@
1002 void resizeNotify (int dx, int dy, int dwidth, int dheight);
1003 void moveNotify (int dx, int dy, bool now);
1004
1005+ Pixmap pixmap () const;
1006+ bool bind ();
1007+ const CompSize & size () const;
1008+ void release ();
1009+ void setNewPixmapReadyCallback (const boost::function <void ()> &);
1010+ void allowFurtherRebindAttempts ();
1011+
1012 static void handleDamageRect (CompositeWindow *w,
1013 int x,
1014 int y,
1015@@ -129,17 +145,13 @@
1016 CompositeWindow *cWindow;
1017 CompositeScreen *cScreen;
1018
1019- Pixmap pixmap;
1020- CompSize size;
1021- bool needsRebind;
1022- CompositeWindow::NewPixmapReadyCallback newPixmapReadyCallback;
1023+ PixmapRebinder mPixmapRebinder;
1024
1025 Damage damage;
1026
1027 bool damaged;
1028 bool redirected;
1029 bool overlayWindow;
1030- bool bindFailed;
1031
1032 unsigned short opacity;
1033 unsigned short brightness;
1034@@ -148,6 +160,10 @@
1035 XRectangle *damageRects;
1036 int sizeDamage;
1037 int nDamage;
1038+ private:
1039+
1040+ bool getAttributes (XWindowAttributes &);
1041+ WindowPixmapInterface::Ptr getPixmap ();
1042 };
1043
1044 #endif
1045
1046=== modified file 'plugins/composite/src/screen.cpp'
1047--- plugins/composite/src/screen.cpp 2012-03-27 12:14:56 +0000
1048+++ plugins/composite/src/screen.cpp 2012-05-28 07:56:18 +0000
1049@@ -831,6 +831,8 @@
1050 return false;
1051 }
1052
1053+
1054+
1055 void
1056 CompositeScreen::preparePaint (int msSinceLastPaint)
1057 WRAPABLE_HND_FUNCTN (preparePaint, msSinceLastPaint)
1058
1059=== modified file 'plugins/composite/src/window.cpp'
1060--- plugins/composite/src/window.cpp 2012-05-25 03:54:23 +0000
1061+++ plugins/composite/src/window.cpp 2012-05-28 07:56:18 +0000
1062@@ -83,9 +83,21 @@
1063 }
1064
1065 void
1066-CompositeWindow::setNewPixmapReadyCallback (const NewPixmapReadyCallback &cb)
1067-{
1068- priv->newPixmapReadyCallback = cb;
1069+PrivateCompositeWindow::setNewPixmapReadyCallback (const PixmapRebinder::NewPixmapReadyCallback &cb)
1070+{
1071+ mPixmapRebinder.setNewPixmapReadyCallback (cb);
1072+}
1073+
1074+void
1075+CompositeWindow::setNewPixmapReadyCallback (const PixmapRebinder::NewPixmapReadyCallback &cb)
1076+{
1077+ priv->setNewPixmapReadyCallback (cb);
1078+}
1079+
1080+void
1081+PrivateCompositeWindow::allowFurtherRebindAttempts ()
1082+{
1083+ mPixmapRebinder.allowFurtherRebindAttempts ();
1084 }
1085
1086 PrivateCompositeWindow::PrivateCompositeWindow (CompWindow *w,
1087@@ -93,14 +105,14 @@
1088 window (w),
1089 cWindow (cw),
1090 cScreen (CompositeScreen::get (screen)),
1091- pixmap (None),
1092- needsRebind (true),
1093- newPixmapReadyCallback (),
1094+ mPixmapRebinder (boost::function <void ()> (),
1095+ this,
1096+ this,
1097+ screen->serverGrabInterface ()),
1098 damage (None),
1099 damaged (false),
1100 redirected (cScreen->compositingActive ()),
1101 overlayWindow (false),
1102- bindFailed (false),
1103 opacity (OPAQUE),
1104 brightness (BRIGHT),
1105 saturation (COLOR),
1106@@ -118,6 +130,14 @@
1107 free (damageRects);
1108 }
1109
1110+
1111+
1112+bool
1113+PrivateCompositeWindow::bind ()
1114+{
1115+ return mPixmapRebinder.bind ();
1116+}
1117+
1118 bool
1119 CompositeWindow::bind ()
1120 {
1121@@ -125,85 +145,61 @@
1122 return false;
1123
1124 redirect ();
1125- if (priv->needsRebind)
1126- {
1127- XWindowAttributes attr;
1128-
1129- /* don't try to bind window again if it failed previously */
1130- if (priv->bindFailed)
1131- return false;
1132-
1133- /* We have to grab the server here to make sure that window
1134- is mapped when getting the window pixmap */
1135- XGrabServer (screen->dpy ());
1136-
1137- /* Flush changes to the server and wait for it to process them */
1138- XSync (screen->dpy (), false);
1139- XGetWindowAttributes (screen->dpy (),
1140- ROOTPARENT (priv->window), &attr);
1141- if (attr.map_state != IsViewable)
1142- {
1143- XUngrabServer (screen->dpy ());
1144- XSync (screen->dpy (), false);
1145- priv->bindFailed = true;
1146- return false;
1147- }
1148-
1149- Pixmap newPixmap = XCompositeNameWindowPixmap
1150- (screen->dpy (), ROOTPARENT (priv->window));
1151- CompSize newSize = CompSize (attr.border_width * 2 + attr.width,
1152- attr.border_width * 2 + attr.height);
1153- XUngrabServer (screen->dpy ());
1154- XSync (screen->dpy (), false);
1155-
1156- if (newPixmap && newSize.width () && newSize.height ())
1157- {
1158- /* Notify renderer that a new pixmap is about to
1159- * be bound */
1160- if (priv->newPixmapReadyCallback)
1161- priv->newPixmapReadyCallback ();
1162-
1163- /* Release old pixmap */
1164- if (priv->pixmap)
1165- XFreePixmap (screen->dpy (), priv->pixmap);
1166-
1167- /* Assign new pixmap */
1168- priv->pixmap = newPixmap;
1169- priv->size = newSize;
1170-
1171- priv->needsRebind = false;
1172- }
1173- else
1174- {
1175- priv->bindFailed = true;
1176- priv->needsRebind = false;
1177- return false;
1178- }
1179- }
1180- return true;
1181+ return priv->bind ();
1182+}
1183+
1184+void
1185+PrivateCompositeWindow::release ()
1186+{
1187+ mPixmapRebinder.release ();
1188 }
1189
1190 void
1191 CompositeWindow::release ()
1192 {
1193- priv->needsRebind = true;
1194+ return priv->release ();
1195+}
1196+
1197+Pixmap
1198+PrivateCompositeWindow::pixmap () const
1199+{
1200+ return mPixmapRebinder.pixmap ();
1201+}
1202+
1203+WindowPixmapInterface::Ptr
1204+PrivateCompositeWindow::getPixmap ()
1205+{
1206+ Pixmap pixmap = XCompositeNameWindowPixmap (screen->dpy (), ROOTPARENT (window));
1207+ WindowPixmapInterface::Ptr p (new X11WindowPixmap (screen->dpy (), pixmap));
1208+ return p;
1209+}
1210+
1211+bool
1212+PrivateCompositeWindow::getAttributes (XWindowAttributes &attr)
1213+{
1214+ if (XGetWindowAttributes (screen->dpy (),
1215+ ROOTPARENT (window), &attr))
1216+ return true;
1217+
1218+ return false;
1219 }
1220
1221 Pixmap
1222 CompositeWindow::pixmap ()
1223 {
1224- static Pixmap nPixmap = None;
1225-
1226- if (priv->needsRebind)
1227- return nPixmap;
1228-
1229- return priv->pixmap;
1230+ return priv->pixmap ();
1231+}
1232+
1233+const CompSize &
1234+PrivateCompositeWindow::size () const
1235+{
1236+ return mPixmapRebinder.size ();
1237 }
1238
1239 const CompSize &
1240 CompositeWindow::size ()
1241 {
1242- return priv->size;
1243+ return priv->size ();
1244 }
1245
1246 void
1247@@ -537,7 +533,7 @@
1248 switch (n)
1249 {
1250 case CompWindowNotifyMap:
1251- bindFailed = false;
1252+ allowFurtherRebindAttempts ();
1253 damaged = false;
1254 break;
1255 case CompWindowNotifyUnmap:
1256
1257=== modified file 'plugins/opengl/src/window.cpp'
1258--- plugins/opengl/src/window.cpp 2012-05-25 03:54:23 +0000
1259+++ plugins/opengl/src/window.cpp 2012-05-28 07:56:18 +0000
1260@@ -112,6 +112,8 @@
1261 priv->needsRebind = false;
1262 return true;
1263 }
1264+ else
1265+ return false;
1266 }
1267
1268 GLTexture::List textures =
1269
1270=== modified file 'src/CMakeLists.txt'
1271--- src/CMakeLists.txt 2012-05-24 00:55:17 +0000
1272+++ src/CMakeLists.txt 2012-05-28 07:56:18 +0000
1273@@ -9,6 +9,7 @@
1274 add_subdirectory( rect )
1275 add_subdirectory( region )
1276 add_subdirectory( window )
1277+add_subdirectory( servergrab )
1278
1279 IF (COMPIZ_BUILD_TESTING)
1280 add_subdirectory( privatescreen/tests )
1281@@ -57,6 +58,9 @@
1282 ${CMAKE_CURRENT_SOURCE_DIR}/rect/include
1283 ${CMAKE_CURRENT_SOURCE_DIR}/rect/src
1284
1285+ ${CMAKE_CURRENT_SOURCE_DIR}/servergrab/include
1286+ ${CMAKE_CURRENT_SOURCE_DIR}/servergrab/src
1287+
1288 ${CMAKE_CURRENT_SOURCE_DIR}/region/include
1289 ${CMAKE_CURRENT_SOURCE_DIR}/region/src
1290
1291@@ -162,6 +166,7 @@
1292 compiz_window_geometry_saver
1293 compiz_window_extents
1294 compiz_window_constrainment
1295+ compiz_servergrab
1296 -Wl,-no-whole-archive
1297 # ${CORE_MOD_LIBRARIES}
1298 )
1299
1300=== modified file 'src/event.cpp'
1301--- src/event.cpp 2012-05-27 04:32:55 +0000
1302+++ src/event.cpp 2012-05-28 07:56:18 +0000
1303@@ -37,6 +37,7 @@
1304 #include <X11/extensions/Xfixes.h>
1305
1306 #include <core/atoms.h>
1307+#include <core/servergrab.h>
1308 #include "privatescreen.h"
1309 #include "privatewindow.h"
1310 #include "privatestackdebugger.h"
1311@@ -1070,6 +1071,30 @@
1312 }
1313 }
1314
1315+ServerGrabInterface *
1316+CompScreenImpl::serverGrabInterface ()
1317+{
1318+ return static_cast <ServerGrabInterface *> (this);
1319+}
1320+
1321+void
1322+CompScreenImpl::grabServer ()
1323+{
1324+ XGrabServer (privateScreen.dpy);
1325+}
1326+
1327+void
1328+CompScreenImpl::syncServer ()
1329+{
1330+ XSync (privateScreen.dpy, false);
1331+}
1332+
1333+void
1334+CompScreenImpl::ungrabServer ()
1335+{
1336+ XUngrabServer (privateScreen.dpy);
1337+}
1338+
1339 void
1340 CompScreenImpl::_handleEvent (XEvent *event)
1341 {
1342
1343=== modified file 'src/plugin.cpp'
1344--- src/plugin.cpp 2012-05-15 15:01:16 +0000
1345+++ src/plugin.cpp 2012-05-28 07:56:18 +0000
1346@@ -24,6 +24,8 @@
1347 */
1348
1349 #include "core/plugin.h"
1350+
1351+/* XXX: This dependency needs to go away */
1352 #include "privatescreen.h"
1353
1354 #include <boost/scoped_array.hpp>
1355
1356=== modified file 'src/plugin/CMakeLists.txt'
1357--- src/plugin/CMakeLists.txt 2012-05-21 06:43:20 +0000
1358+++ src/plugin/CMakeLists.txt 2012-05-28 07:56:18 +0000
1359@@ -14,6 +14,7 @@
1360 ${compiz_SOURCE_DIR}/src/window/extents/include
1361
1362 ${compiz_SOURCE_DIR}/src/pluginclasshandler/include
1363+ ${compiz_SOURCE_DIR}/src/servergrab/include
1364
1365 ${COMPIZ_INCLUDE_DIRS}
1366
1367
1368=== modified file 'src/privatescreen.h'
1369--- src/privatescreen.h 2012-05-23 07:37:37 +0000
1370+++ src/privatescreen.h 2012-05-28 07:56:18 +0000
1371@@ -33,6 +33,7 @@
1372 #include <core/point.h>
1373 #include <core/timer.h>
1374 #include <core/plugin.h>
1375+#include <core/servergrab.h>
1376 #include <time.h>
1377 #include <boost/shared_ptr.hpp>
1378
1379@@ -826,6 +827,7 @@
1380 * X server.
1381 */
1382 class CompScreenImpl : public CompScreen,
1383+ public ServerGrabInterface,
1384 ::compiz::private_screen::DesktopWindowCount,
1385 ::compiz::private_screen::MapNum,
1386 ::compiz::private_screen::Ping,
1387@@ -1045,6 +1047,8 @@
1388 virtual void processEvents ();
1389 virtual void alwaysHandleEvent (XEvent *event);
1390
1391+ virtual ServerGrabInterface * serverGrabInterface ();
1392+
1393 virtual void updatePassiveKeyGrabs () const;
1394 virtual void updatePassiveButtonGrabs(Window serverFrame);
1395
1396@@ -1145,6 +1149,10 @@
1397 virtual void _matchPropertyChanged(CompWindow *);
1398 virtual void _outputChangeNotify();
1399
1400+ void grabServer ();
1401+ void ungrabServer ();
1402+ void syncServer ();
1403+
1404 bool handlePingTimeout();
1405
1406 Window below;
1407
1408=== modified file 'src/privatescreen/tests/CMakeLists.txt'
1409--- src/privatescreen/tests/CMakeLists.txt 2012-05-21 06:43:20 +0000
1410+++ src/privatescreen/tests/CMakeLists.txt 2012-05-28 07:56:18 +0000
1411@@ -17,6 +17,7 @@
1412 ${compiz_SOURCE_DIR}/src/window/geometry/include
1413 ${compiz_SOURCE_DIR}/src/window/extents/include
1414 ${compiz_SOURCE_DIR}/src/screen/extents/include
1415+ ${compiz_SOURCE_DIR}/src/servergrab/include
1416
1417 ${compiz_SOURCE_DIR}/src/pluginclasshandler/include
1418
1419
1420=== modified file 'src/privatescreen/tests/test-privatescreen.cpp'
1421--- src/privatescreen/tests/test-privatescreen.cpp 2012-05-23 07:37:37 +0000
1422+++ src/privatescreen/tests/test-privatescreen.cpp 2012-05-28 07:56:18 +0000
1423@@ -204,6 +204,11 @@
1424 MOCK_METHOD1(getProtocols, unsigned int (Window id));
1425 MOCK_METHOD1(getWindowType, unsigned int (Window id));
1426 MOCK_METHOD1(getWindowState, unsigned int (Window id));
1427+
1428+ MOCK_METHOD0(grabServer, void ());
1429+ MOCK_METHOD0(ungrabServer, void ());
1430+ MOCK_METHOD0(syncServer, void ());
1431+ MOCK_METHOD0(serverGrabInterface, ServerGrabInterface * ());
1432 };
1433
1434 class MockViewportRetreival :
1435
1436=== added directory 'src/servergrab'
1437=== added file 'src/servergrab/CMakeLists.txt'
1438--- src/servergrab/CMakeLists.txt 1970-01-01 00:00:00 +0000
1439+++ src/servergrab/CMakeLists.txt 2012-05-28 07:56:18 +0000
1440@@ -0,0 +1,42 @@
1441+INCLUDE_DIRECTORIES (
1442+ ${CMAKE_CURRENT_SOURCE_DIR}/include
1443+ ${CMAKE_CURRENT_SOURCE_DIR}/src
1444+
1445+ ${Boost_INCLUDE_DIRS}
1446+)
1447+
1448+LINK_DIRECTORIES (${GLIBMM_LIBRARY_DIRS})
1449+
1450+SET (
1451+ PUBLIC_HEADERS
1452+ ${CMAKE_CURRENT_SOURCE_DIR}/include/core/servergrab.h
1453+)
1454+
1455+SET (
1456+ PRIVATE_HEADERS
1457+)
1458+
1459+SET(
1460+ SRCS
1461+ ${CMAKE_CURRENT_SOURCE_DIR}/src/servergrab.cpp
1462+)
1463+
1464+ADD_LIBRARY(
1465+ compiz_servergrab STATIC
1466+
1467+ ${SRCS}
1468+
1469+ ${PUBLIC_HEADERS}
1470+ ${PRIVATE_HEADERS}
1471+)
1472+
1473+IF (COMPIZ_BUILD_TESTING)
1474+ADD_SUBDIRECTORY( ${CMAKE_CURRENT_SOURCE_DIR}/tests )
1475+ENDIF (COMPIZ_BUILD_TESTING)
1476+
1477+SET_TARGET_PROPERTIES(
1478+ compiz_servergrab PROPERTIES
1479+ PUBLIC_HEADER "${PUBLIC_HEADERS}"
1480+)
1481+
1482+install (FILES ${PUBLIC_HEADERS} DESTINATION ${COMPIZ_CORE_INCLUDE_DIR})
1483
1484=== added directory 'src/servergrab/include'
1485=== added directory 'src/servergrab/include/core'
1486=== added file 'src/servergrab/include/core/servergrab.h'
1487--- src/servergrab/include/core/servergrab.h 1970-01-01 00:00:00 +0000
1488+++ src/servergrab/include/core/servergrab.h 2012-05-28 07:56:18 +0000
1489@@ -0,0 +1,51 @@
1490+/*
1491+ * Copyright © 2012 Canonical Ltd.
1492+ *
1493+ * Permission to use, copy, modify, distribute, and sell this software
1494+ * and its documentation for any purpose is hereby granted without
1495+ * fee, provided that the above copyright notice appear in all copies
1496+ * and that both that copyright notice and this permission notice
1497+ * appear in supporting documentation, and that the name of
1498+ * Canonical Ltd. not be used in advertising or publicity pertaining to
1499+ * distribution of the software without specific, written prior permission.
1500+ * Canonical Ltd. makes no representations about the suitability of this
1501+ * software for any purpose. It is provided "as is" without express or
1502+ * implied warranty.
1503+ *
1504+ * CANONICAL, LTD. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
1505+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
1506+ * NO EVENT SHALL CANONICAL, LTD. BE LIABLE FOR ANY SPECIAL, INDIRECT OR
1507+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
1508+ * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
1509+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
1510+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
1511+ *
1512+ * Authored by: Sam Spilsbury <sam.spilsbury@canonical.com>
1513+ */
1514+
1515+#ifndef _COMP_SERVER_GRAB_H
1516+#define _COMP_SERVER_GRAB_H
1517+
1518+class ServerGrabInterface
1519+{
1520+ public:
1521+ virtual ~ServerGrabInterface () {}
1522+
1523+ virtual void grabServer () = 0;
1524+ virtual void ungrabServer () = 0;
1525+ virtual void syncServer () = 0;
1526+};
1527+
1528+class ServerLock
1529+{
1530+ public:
1531+
1532+ ServerLock (ServerGrabInterface *i);
1533+ ~ServerLock ();
1534+
1535+ private:
1536+
1537+ ServerGrabInterface *mServerGrab;
1538+};
1539+
1540+#endif
1541
1542=== added directory 'src/servergrab/src'
1543=== added file 'src/servergrab/src/servergrab.cpp'
1544--- src/servergrab/src/servergrab.cpp 1970-01-01 00:00:00 +0000
1545+++ src/servergrab/src/servergrab.cpp 2012-05-28 07:56:18 +0000
1546@@ -0,0 +1,39 @@
1547+/*
1548+ * Copyright © 2012 Canonical Ltd.
1549+ *
1550+ * Permission to use, copy, modify, distribute, and sell this software
1551+ * and its documentation for any purpose is hereby granted without
1552+ * fee, provided that the above copyright notice appear in all copies
1553+ * and that both that copyright notice and this permission notice
1554+ * appear in supporting documentation, and that the name of
1555+ * Canonical Ltd. not be used in advertising or publicity pertaining to
1556+ * distribution of the software without specific, written prior permission.
1557+ * Canonical Ltd. makes no representations about the suitability of this
1558+ * software for any purpose. It is provided "as is" without express or
1559+ * implied warranty.
1560+ *
1561+ * CANONICAL, LTD. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
1562+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
1563+ * NO EVENT SHALL CANONICAL, LTD. BE LIABLE FOR ANY SPECIAL, INDIRECT OR
1564+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
1565+ * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
1566+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
1567+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
1568+ *
1569+ * Authored by: Sam Spilsbury <sam.spilsbury@canonical.com>
1570+ */
1571+
1572+#include <core/servergrab.h>
1573+
1574+ServerLock::ServerLock (ServerGrabInterface *i) :
1575+ mServerGrab (i)
1576+{
1577+ mServerGrab->grabServer ();
1578+ mServerGrab->syncServer ();
1579+}
1580+
1581+ServerLock::~ServerLock ()
1582+{
1583+ mServerGrab->ungrabServer ();
1584+ mServerGrab->syncServer ();
1585+}
1586
1587=== added directory 'src/servergrab/tests'
1588=== added file 'src/servergrab/tests/CMakeLists.txt'
1589--- src/servergrab/tests/CMakeLists.txt 1970-01-01 00:00:00 +0000
1590+++ src/servergrab/tests/CMakeLists.txt 2012-05-28 07:56:18 +0000
1591@@ -0,0 +1,14 @@
1592+include_directories(${CMAKE_CURRENT_SOURCE_DIR})
1593+
1594+add_executable (compiz_test_servergrab
1595+ ${CMAKE_CURRENT_SOURCE_DIR}/test-servergrab.cpp)
1596+
1597+target_link_libraries (compiz_test_servergrab
1598+ compiz_servergrab
1599+ ${GTEST_BOTH_LIBRARIES}
1600+ ${GMOCK_LIBRARY}
1601+ ${GMOCK_MAIN_LIBRARY}
1602+ ${CMAKE_THREAD_LIBS_INIT} # Link in pthread.
1603+ )
1604+
1605+gtest_add_tests (compiz_test_servergrab "" ${CMAKE_CURRENT_SOURCE_DIR}/test-servergrab.cpp)
1606
1607=== added file 'src/servergrab/tests/test-servergrab.cpp'
1608--- src/servergrab/tests/test-servergrab.cpp 1970-01-01 00:00:00 +0000
1609+++ src/servergrab/tests/test-servergrab.cpp 2012-05-28 07:56:18 +0000
1610@@ -0,0 +1,55 @@
1611+/*
1612+ * Copyright © 2012 Canonical Ltd.
1613+ *
1614+ * Permission to use, copy, modify, distribute, and sell this software
1615+ * and its documentation for any purpose is hereby granted without
1616+ * fee, provided that the above copyright notice appear in all copies
1617+ * and that both that copyright notice and this permission notice
1618+ * appear in supporting documentation, and that the name of
1619+ * Canonical Ltd. not be used in advertising or publicity pertaining to
1620+ * distribution of the software without specific, written prior permission.
1621+ * Canonical Ltd. makes no representations about the suitability of this
1622+ * software for any purpose. It is provided "as is" without express or
1623+ * implied warranty.
1624+ *
1625+ * CANONICAL, LTD. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
1626+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
1627+ * NO EVENT SHALL CANONICAL, LTD. BE LIABLE FOR ANY SPECIAL, INDIRECT OR
1628+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
1629+ * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
1630+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
1631+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
1632+ *
1633+ * Authored by: Sam Spilsbury <sam.spilsbury@canonical.com>
1634+ */
1635+
1636+#include <gtest/gtest.h>
1637+#include <gmock/gmock.h>
1638+#include <core/servergrab.h>
1639+
1640+class MockServerGrab :
1641+ public ServerGrabInterface
1642+{
1643+ public:
1644+
1645+ MOCK_METHOD0 (grabServer, void ());
1646+ MOCK_METHOD0 (ungrabServer, void ());
1647+ MOCK_METHOD0 (syncServer, void ());
1648+};
1649+
1650+class ServerGrabTest :
1651+ public ::testing::Test
1652+{
1653+};
1654+
1655+TEST(ServerGrabTest, TestServerGrab)
1656+{
1657+ MockServerGrab msg;
1658+
1659+ EXPECT_CALL (msg, grabServer ());
1660+ EXPECT_CALL (msg, syncServer ()).Times (2);
1661+
1662+ ServerLock l (&msg);
1663+
1664+ EXPECT_CALL (msg, ungrabServer ());
1665+}

Subscribers

People subscribed via source and target branches