Merge lp:~linaro-graphics-wg/compiz-core/linaro-gles2 into lp:compiz-core/0.9.5

Proposed by Sam Spilsbury
Status: Superseded
Proposed branch: lp:~linaro-graphics-wg/compiz-core/linaro-gles2
Merge into: lp:compiz-core/0.9.5
Diff against target: 41667 lines (+29201/-5352) (has conflicts)
161 files modified
CMakeLists.txt (+26/-0)
VERSION (+4/-0)
cmake/CMakeLists.txt (+2/-0)
cmake/CompizCommon.cmake (+67/-0)
cmake/CompizGSettings.cmake (+76/-0)
cmake/CompizPlugin.cmake (+14/-10)
cmake/FindOpenGLES2.cmake (+51/-0)
cmake/base.cmake (+3/-1)
cmake/plugin_extensions/CompizGenGSettings.cmake (+0/-104)
cmake/plugin_extensions/CompizOpenGLFixups.cmake (+22/-0)
gtk/CMakeLists.txt (+1/-1)
gtk/config.h.gtk.in (+0/-25)
gtk/gnome/CMakeLists.txt (+74/-0)
gtk/gnome/compiz.desktop.in (+1/-1)
gtk/window-decorator/actionmenu.c (+0/-133)
gtk/window-decorator/blurprops.c (+0/-89)
gtk/window-decorator/cairo.c (+915/-0)
gtk/window-decorator/decorator.c (+1301/-0)
gtk/window-decorator/decorprops.c (+161/-0)
gtk/window-decorator/events.c (+1177/-0)
gtk/window-decorator/forcequit.c (+0/-201)
gtk/window-decorator/frames.c (+316/-0)
gtk/window-decorator/gdk.c (+0/-106)
gtk/window-decorator/gtk-window-decorator.c (+453/-0)
gtk/window-decorator/gtk-window-decorator.h (+1140/-0)
gtk/window-decorator/gwd.schemas.in (+81/-0)
gtk/window-decorator/metacity.c (+1634/-0)
gtk/window-decorator/settings.c (+546/-0)
gtk/window-decorator/style.c (+0/-66)
gtk/window-decorator/switcher.c (+512/-0)
gtk/window-decorator/util.c (+0/-299)
gtk/window-decorator/wnck.c (+709/-0)
include/core/core.h (+4/-0)
include/core/rect.h.OTHER (+229/-0)
include/core/screen.h (+3/-1)
include/core/window.h (+28/-1)
include/decoration.h (+50/-59)
kde/window-decorator-kde4/decorator.cpp (+6/-17)
kde/window-decorator-kde4/decorator.h (+2/-19)
kde/window-decorator-kde4/switcher.cpp (+5/-10)
kde/window-decorator-kde4/utils.cpp (+2/-0)
kde/window-decorator-kde4/window.cpp (+14/-110)
kde/window-decorator-kde4/window.h (+1/-1)
libdecoration/decoration.c (+88/-112)
metadata/core.xml.in (+3/-3)
plugins/annotate/src/annotate.cpp (+160/-86)
plugins/bailer/CMakeLists.txt (+5/-0)
plugins/bailer/bailer.xml.in (+82/-0)
plugins/bailer/src/bailer.cpp (+277/-0)
plugins/bailer/src/bailer.h (+86/-0)
plugins/blur/CMakeLists.txt (+12/-12)
plugins/clone/src/clone.cpp (+4/-9)
plugins/compiztoolbox/include/compiztoolbox/compiztoolbox.h (+1/-1)
plugins/compiztoolbox/src/compiztoolbox.cpp (+14/-28)
plugins/composite/include/composite/composite.h (+26/-13)
plugins/composite/src/privates.h (+12/-0)
plugins/composite/src/screen.cpp (+77/-0)
plugins/copytex/src/copytex.cpp (+9/-0)
plugins/cube/CMakeLists.txt (+1/-1)
plugins/cube/cube.xml.in (+7/-6)
plugins/cube/src/cube.cpp (+40/-39)
plugins/debugspew/CMakeLists.txt (+5/-0)
plugins/debugspew/debugspew.xml.in (+24/-0)
plugins/debugspew/src/debugspew.cpp (+622/-0)
plugins/debugspew/src/debugspew.h (+55/-0)
plugins/decor/decor.xml.in (+38/-0)
plugins/decor/src/decor.cpp (+338/-885)
plugins/decor/src/decor.h (+14/-36)
plugins/detection/CMakeLists.txt (+5/-0)
plugins/detection/detection.xml.in (+28/-0)
plugins/detection/src/detection.cpp (+74/-0)
plugins/detection/src/detection.h (+52/-0)
plugins/fade/fade.xml.in (+2/-1)
plugins/imgsvg/src/imgsvg.cpp (+12/-9)
plugins/imgsvg/src/imgsvg.h (+2/-1)
plugins/kde/src/dispatcher.cpp (+18/-18)
plugins/kde/src/dispatcher.h (+8/-8)
plugins/kde/src/socket.cpp (+1/-1)
plugins/kde/src/timer.cpp (+1/-1)
plugins/move/src/move.cpp (+41/-0)
plugins/move/src/move.h (+7/-1)
plugins/obs/src/obs.cpp (+10/-9)
plugins/obs/src/obs.h (+1/-1)
plugins/opengl/CMakeLists.txt (+9/-4)
plugins/opengl/compiz-opengl.pc.in (+2/-2)
plugins/opengl/include/opengl/framebufferobject.h (+107/-0)
plugins/opengl/include/opengl/matrix.h (+2/-0)
plugins/opengl/include/opengl/opengl.h (+275/-65)
plugins/opengl/include/opengl/program.h (+75/-0)
plugins/opengl/include/opengl/programcache.h (+51/-0)
plugins/opengl/include/opengl/texture.h (+9/-0)
plugins/opengl/include/opengl/vector.h (+1/-1)
plugins/opengl/include/opengl/vertexbuffer.h (+100/-0)
plugins/opengl/opengl.xml.in (+1/-1)
plugins/opengl/src/framebufferobject.cpp (+191/-0)
plugins/opengl/src/matrix.cpp (+54/-0)
plugins/opengl/src/paint.cpp (+446/-360)
plugins/opengl/src/privatefragment.h (+0/-54)
plugins/opengl/src/privates.h (+41/-9)
plugins/opengl/src/privatetexture.h (+37/-0)
plugins/opengl/src/privatevertexbuffer.h (+136/-0)
plugins/opengl/src/program.cpp (+262/-0)
plugins/opengl/src/programcache.cpp (+175/-0)
plugins/opengl/src/screen.cpp (+813/-69)
plugins/opengl/src/shaders.h (+136/-0)
plugins/opengl/src/texture.cpp (+137/-12)
plugins/opengl/src/vertexbuffer.cpp (+530/-0)
plugins/opengl/src/window.cpp (+44/-84)
plugins/place/place.xml.in (+5/-0)
plugins/place/src/place.h (+15/-2)
plugins/resize/resize.xml.in (+8/-8)
plugins/resize/src/resize.cpp (+95/-40)
plugins/rotate/CMakeLists.txt (+1/-1)
plugins/rotate/src/rotate.cpp (+21/-21)
plugins/scale/scale.xml.in (+8/-10)
plugins/scale/src/privates.h (+4/-0)
plugins/scale/src/scale.cpp (+39/-24)
plugins/screenshot/src/screenshot.cpp (+52/-25)
plugins/switcher/src/switcher.cpp (+49/-48)
plugins/water/CMakeLists.txt (+1/-1)
plugins/water/src/shaders.h (+201/-0)
plugins/water/src/water.cpp (+265/-803)
plugins/water/src/water.h (+37/-67)
plugins/water/water.xml.in (+24/-0)
plugins/wobbly/CMakeLists.txt (+1/-1)
plugins/zoom/src/zoom.cpp.OTHER (+764/-0)
src/CMakeLists.txt (+36/-0)
src/event.cpp (+62/-0)
src/main.cpp (+67/-1)
src/plugin.cpp (+1/-3)
src/privatescreen.h (+83/-1)
src/screen.cpp (+212/-64)
src/stackdebugger.cpp (+985/-491)
src/window.cpp (+873/-104)
unity/unity_window_decorator/AUTHORS (+29/-0)
unity/unity_window_decorator/CMakeLists.txt (+38/-0)
unity/unity_window_decorator/COPYING (+6/-0)
unity/unity_window_decorator/COPYING.GPL (+340/-0)
unity/unity_window_decorator/INSTALL (+14/-0)
unity/unity_window_decorator/README (+8/-0)
unity/unity_window_decorator/src/CMakeLists.txt (+161/-0)
unity/unity_window_decorator/src/TODO (+6/-0)
unity/unity_window_decorator/src/actionmenu.c (+109/-0)
unity/unity_window_decorator/src/blurprops.c (+68/-0)
unity/unity_window_decorator/src/cairo.c (+1001/-0)
unity/unity_window_decorator/src/config.h.gtk.in (+25/-0)
unity/unity_window_decorator/src/decorator.c (+874/-0)
unity/unity_window_decorator/src/decorprops.c (+150/-0)
unity/unity_window_decorator/src/events.c (+1146/-0)
unity/unity_window_decorator/src/forcequit.c (+176/-0)
unity/unity_window_decorator/src/gdk.c (+87/-0)
unity/unity_window_decorator/src/gtk-window-decorator.c (+442/-0)
unity/unity_window_decorator/src/gtk-window-decorator.h (+1009/-0)
unity/unity_window_decorator/src/gwd.schemas.in (+81/-0)
unity/unity_window_decorator/src/metacity.c (+1943/-0)
unity/unity_window_decorator/src/settings.c (+567/-0)
unity/unity_window_decorator/src/style.c (+42/-0)
unity/unity_window_decorator/src/switcher.c (+452/-0)
unity/unity_window_decorator/src/util.c (+278/-0)
unity/unity_window_decorator/src/wnck.c (+714/-0)
xslt/compiz_gsettings_schemas.xslt.in (+0/-441)
Text conflict in CMakeLists.txt
Text conflict in VERSION
Text conflict in cmake/CompizCommon.cmake
Contents conflict in cmake/CompizGSettings.cmake
Text conflict in gtk/gnome/CMakeLists.txt
Contents conflict in gtk/window-decorator/cairo.c
Contents conflict in gtk/window-decorator/decorator.c
Contents conflict in gtk/window-decorator/decorprops.c
Contents conflict in gtk/window-decorator/events.c
Contents conflict in gtk/window-decorator/frames.c
Contents conflict in gtk/window-decorator/gtk-window-decorator.c
Contents conflict in gtk/window-decorator/gtk-window-decorator.h
Contents conflict in gtk/window-decorator/gwd.schemas.in
Contents conflict in gtk/window-decorator/metacity.c
Contents conflict in gtk/window-decorator/settings.c
Contents conflict in gtk/window-decorator/switcher.c
Contents conflict in gtk/window-decorator/wnck.c
Text conflict in include/core/core.h
Contents conflict in include/core/rect.h
Text conflict in include/core/window.h
Text conflict in libdecoration/decoration.c
Text conflict in plugins/composite/include/composite/composite.h
Text conflict in plugins/composite/src/privates.h
Text conflict in plugins/composite/src/screen.cpp
Text conflict in plugins/cube/src/cube.cpp
Text conflict in plugins/decor/decor.xml.in
Text conflict in plugins/decor/src/decor.cpp
Text conflict in plugins/decor/src/decor.h
Text conflict in plugins/move/src/move.cpp
Contents conflict in plugins/opengl/include/opengl/fragment.h
Text conflict in plugins/opengl/include/opengl/opengl.h
Text conflict in plugins/opengl/include/opengl/texture.h
Contents conflict in plugins/opengl/src/fragment.cpp
Text conflict in plugins/opengl/src/paint.cpp
Text conflict in plugins/opengl/src/privates.h
Text conflict in plugins/opengl/src/privatetexture.h
Text conflict in plugins/opengl/src/screen.cpp
Text conflict in plugins/place/place.xml.in
Text conflict in plugins/place/src/place.h
Text conflict in plugins/scale/src/privates.h
Text conflict in plugins/scale/src/scale.cpp
Conflict adding files to plugins/zoom.  Created directory.
Conflict because plugins/zoom is not versioned, but has versioned children.  Versioned directory.
Conflict adding files to plugins/zoom/src.  Created directory.
Conflict because plugins/zoom/src is not versioned, but has versioned children.  Versioned directory.
Contents conflict in plugins/zoom/src/zoom.cpp
Text conflict in src/CMakeLists.txt
Text conflict in src/event.cpp
Text conflict in src/main.cpp
Text conflict in src/privatescreen.h
Text conflict in src/screen.cpp
Text conflict in src/stackdebugger.cpp
Text conflict in src/window.cpp
To merge this branch: bzr merge lp:~linaro-graphics-wg/compiz-core/linaro-gles2
Reviewer Review Type Date Requested Status
Sam Spilsbury Pending
Review via email: mp+89765@code.launchpad.net

This proposal supersedes a proposal from 2011-08-10.

This proposal has been superseded by a proposal from 2012-02-21.

Description of the change

This branch contains the code to make compiz work on GLES. This includes several changes to the compiz API.

* GLVertexBuffer class added for managing vertices, normals, texture coordinates, and colors
* GLProgram class added for managing GLSL programs
* GLProgramCache class added for managing per-plugin GLSL programs efficiently, uses an LRU cache
  to avoid recompiling recently used GLSL programs all the time
* GLFragment class removed as fragment programs are no longer used (replaced with GLSL programs)
* GL_BLEND now always enabled when rendering as almost everything was enabling it anyway
* EGL context setup added
* EglTexture class added to use EGL_image extension instead of GLX_EXT_texture_from_pixmap for GLES

Things left to do for a complete port:

  * properly check for GLSL support on desktop, currently assumes if you have VBO support you
    have GLSL support
  * port blur, wobbly, rotate, cube, and water plugins
    * wobbly, cube, and rotate should be fairly straightforward, water and blur need updated to
      use GLSL instead of fragment programs

To post a comment you must log in.
Revision history for this message
Sam Spilsbury (smspillaz) wrote : Posted in a previous version of this proposal
Download full text (8.3 KiB)

1682 + int render (const GLMatrix &modelview,
1683 + const GLWindowPaintAttrib &attrib);
1684 +
1685 + int render (const GLMatrix &projection,
1686 + const GLMatrix &modelview,
1687 + const GLWindowPaintAttrib &attrib);

Probably for the sake of API confusion, it might be worth swapping the order of projection and modelview in this case, so you have

1685 + int render (const GLMatrix &modelview,
1686 + const GLMatrix &projection,
1687 + const GLWindowPaintAttrib &attrib);

--

1586 + GLProgram* operator () (std::list<GLShaderData*>);

Can that take a const std::list <GLShaderData *> & ?

1116 +#if !defined(GL_BGRA)
1117 + #if !defined(GL_BGRA_EXT)
1118 + #error GL_BGRA support is required
1119 + #else
1120 + #define GL_BGRA GL_BGRA_EXT
1121 + #endif
1122 +#endif

This can probably be detected in CMake by using try_compile () [1]

1703 - <default>true</default>
1704 + <default>false</default>

Does this need to be off by default?

1678 + void setProgram (GLProgram *program);
1679 +
1680 + int render (const GLMatrix &modelview);
1681 +
1682 + int render (const GLMatrix &modelview,
1683 + const GLWindowPaintAttrib &attrib);
1684 +
1685 + int render (const GLMatrix &projection,
1686 + const GLMatrix &modelview,
1687 + const GLWindowPaintAttrib &attrib);

The semantics of this are odd. Is GLVertexBuffer meant to be a stateful object which holds on to the state of what its rendering? In that case, it might be more appropriate to have a:

void setProjection ();
void setModelView ();
void setAttrib ();

However, on another though, perhaps all of these arguments are redundant. If glPushMatrix, glLoadMatrixf and glPopMatrix are all parts of the deprecated API, and PrivateGLVertexBuffer::render is really doing this:

+ GLfloat params[4] = {0, 0, 0, 0};
+ GLfloat attribs[3] = {1, 1, 1};
+ GLint index = 0;
+

+ program->setUniform ("projection", projection);
+ program->setUniform ("modelview", modelview);

+ //convert paint attribs to 0-1 range
+ attribs[0] = attrib.opacity / 65535.0f;
+ attribs[1] = attrib.brightness / 65535.0f;
+ attribs[2] = attrib.saturation / 65535.0f;
+ program->setUniform3f ("paintAttrib", attribs[0], attribs[1], attribs[2]);
+

Then it might make more sense to have helper objects in the OpenGL plugin to handle that so that you don't need to pass matrices or paint attributes to the GLVertexBuffer at render time and we don't need to continue to expand the ::render () function argument list should we add more things to the core profile.

The helper object might just server to build a GLProgram with that stuff built in so that it can be passed directly to GLVertexBuffer at render time. Just a thought.

+ #ifdef USE_GLES
+ Display *xdpy = screen->dpy ();
+
+ glFlush ();
+ if (mask & COMPOSITE_SCREEN_DAMAGE_ALL_MASK)
+ {
+ eglSwapBuffers (eglGetDisplay (xdpy), surface);
+ }
+ else
+ {
+ #warning use proper extension for this
+ eglSwapBuffers (eglGetDisplay (xdpy), surface);
+ }
+ eglW...

Read more...

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

Is there a reason nothing has happened here since Aug/Sep 2011?

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

All these conflicts seem to be here due to the fact that bzr seems to think we've deleted and re-added every file in the tree *sigh*

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

No problem. Just make a new branch and copy these files into it and propose the new one. Then bzr should be happier.

Revision history for this message
Frederic Plourde (fredinfinite23) :
2901. By Frederic Plourde

Fix compiz decorator's shadow blending

2902. By Frederic Plourde

Workaround GL_LINE_LOOP usage in resize plugin

2903. By Frederic Plourde

Fix blending in the resize plugin

2904. By Frederic Plourde

Draw resize plugin in fullscreen mode to workaround rendering instabilities

2905. By Alexandros Frantzis

Sync with lp:compiz-core.

2906. By Alexandros Frantzis

Sync with lp:compiz-core.

2907. By Alexandros Frantzis

Sync with lp:compiz-core.

2908. By Alexandros Frantzis

Use new WRAPABLE_HND_* macros.

2909. By Alexandros Frantzis

Correct count of wrapable functions in GLScreen.

2910. By Alexandros Frantzis

Sync with lp:compiz-core

2911. By Frederic Plourde

Fix decoration mapping instabilities and texturing artefacts.

2912. By Alexandros Frantzis

Work around compile issue on ARM.

When compiling with -O2 on ARM, the original code leads to an array index out
of bounds compilation error. In that case, the compiler doesn't infer that
sizeof(a)/sizeof(T) is a constant, and tries to compile cases in the switch
statement that use array indices that are invalid for the particular template
instantiation.

To fix this we use the 'C' template variable, which is constant for each
template instantiation, directly in the switch statement.

2913. By Alexandros Frantzis

Sync with lp:compiz-core.

2914. By Alexandros Frantzis

Sync with lp:compiz-core.

2915. By Alexandros Frantzis

opengl: Ensure blending is enabled, when needed, when drawing window contents.

2916. By Alexandros Frantzis

opengl: Refactor shader infrastructure to use small, performant programs.

This commit replaces the single complicated shader with minimal,
performant shaders, tailored to specific use cases. The new GLShaderCache
object is used for creating and caching the shader data for specific uses
cases (GLShaderParameters).

This commit also adds automatic creation of suitable GL programs in
GLVertexBuffers (see ::setAutoProgram) that don't have a program
explicitly set.

2917. By Alexandros Frantzis

Sync with lp:compiz-core.

2918. By Alexandros Frantzis

opengl: Disable blending by default when drawing the screen.

Each operation/plugin should enable it (and reset it) as needed
(as most operations are currently doing).

2919. By Alexandros Frantzis

Fix compilation with desktop GL.

2920. By Alexandros Frantzis

opengl: For OpenGL ES 2.0 ensure that format equals internalFormat when uploading texture data.

In OpenGL ES 2.0 no format conversion is allowed, i.e., format must equal internalFormat.

2921. By Alexandros Frantzis

Sync with lp:compiz-core.

2922. By Alexandros Frantzis

Sync with lp:compiz-core.

Unmerged revisions

2922. By Alexandros Frantzis

Sync with lp:compiz-core.

2921. By Alexandros Frantzis

Sync with lp:compiz-core.

2920. By Alexandros Frantzis

opengl: For OpenGL ES 2.0 ensure that format equals internalFormat when uploading texture data.

In OpenGL ES 2.0 no format conversion is allowed, i.e., format must equal internalFormat.

2919. By Alexandros Frantzis

Fix compilation with desktop GL.

2918. By Alexandros Frantzis

opengl: Disable blending by default when drawing the screen.

Each operation/plugin should enable it (and reset it) as needed
(as most operations are currently doing).

2917. By Alexandros Frantzis

Sync with lp:compiz-core.

2916. By Alexandros Frantzis

opengl: Refactor shader infrastructure to use small, performant programs.

This commit replaces the single complicated shader with minimal,
performant shaders, tailored to specific use cases. The new GLShaderCache
object is used for creating and caching the shader data for specific uses
cases (GLShaderParameters).

This commit also adds automatic creation of suitable GL programs in
GLVertexBuffers (see ::setAutoProgram) that don't have a program
explicitly set.

2915. By Alexandros Frantzis

opengl: Ensure blending is enabled, when needed, when drawing window contents.

2914. By Alexandros Frantzis

Sync with lp:compiz-core.

2913. By Alexandros Frantzis

Sync with lp:compiz-core.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'CMakeLists.txt'
--- CMakeLists.txt 2012-01-24 10:43:23 +0000
+++ CMakeLists.txt 2012-02-08 18:50:27 +0000
@@ -86,6 +86,7 @@
86 libxml-2.086 libxml-2.0
87 libxslt87 libxslt
88 glib-2.088 glib-2.0
89 gtk+-3.0
89 gio-2.090 gio-2.0
90 glibmm-2.491 glibmm-2.4
91 "libstartup-notification-1.0 >= 0.7"92 "libstartup-notification-1.0 >= 0.7"
@@ -119,6 +120,7 @@
119 DESTINATION ${COMPIZ_DESTDIR}${libdir}/pkgconfig120 DESTINATION ${COMPIZ_DESTDIR}${libdir}/pkgconfig
120)121)
121122
123<<<<<<< TREE
122# Build Google Test and make its headers known124# Build Google Test and make its headers known
123find_package (GTest)125find_package (GTest)
124find_library (GMOCK_LIBRARY gmock)126find_library (GMOCK_LIBRARY gmock)
@@ -134,6 +136,14 @@
134find_package (Threads REQUIRED)136find_package (Threads REQUIRED)
135137
136# Add the rest of compiz138# Add the rest of compiz
139=======
140# temporarily disable plugins that aren't ported yed
141set (COMPIZ_DISABLE_PLUGIN_BLUR ON)
142set (COMPIZ_DISABLE_PLUGIN_CUBE ON)
143set (COMPIZ_DISABLE_PLUGIN_ROTATE ON)
144set (COMPIZ_DISABLE_PLUGIN_WOBBLY ON)
145
146>>>>>>> MERGE-SOURCE
137add_subdirectory (cmake)147add_subdirectory (cmake)
138add_subdirectory (include)148add_subdirectory (include)
139add_subdirectory (images)149add_subdirectory (images)
@@ -145,7 +155,14 @@
145add_subdirectory (src)155add_subdirectory (src)
146add_subdirectory (xslt)156add_subdirectory (xslt)
147add_subdirectory (plugins)157add_subdirectory (plugins)
158<<<<<<< TREE
148add_subdirectory (tests)159add_subdirectory (tests)
160=======
161add_subdirectory (unity/unity_window_decorator)
162if (BUILD_TESTING)
163 add_subdirectory (tests)
164endif (BUILD_TESTING)
165>>>>>>> MERGE-SOURCE
149166
150compiz_ensure_linkage ()167compiz_ensure_linkage ()
151compiz_package_generation ("Compiz")168compiz_package_generation ("Compiz")
@@ -159,7 +176,16 @@
159176
160_check_compiz_cmake_macro (${CMAKE_MODULE_PATH_ORIG})177_check_compiz_cmake_macro (${CMAKE_MODULE_PATH_ORIG})
161178
179<<<<<<< TREE
162# Enable coverage reporting for compiz180# Enable coverage reporting for compiz
163enable_coverage_report()181enable_coverage_report()
164182
165183
184=======
185# temporarily disable plugins that aren't ported yed
186SET(COMPIZ_DISABLE_PLUGIN_BLUR "ON")
187SET(COMPIZ_DISABLE_PLUGIN_CUBE "ON")
188SET(COMPIZ_DISABLE_PLUGIN_ROTATE "ON")
189SET(COMPIZ_DISABLE_PLUGIN_WATER "ON")
190SET(COMPIZ_DISABLE_PLUGIN_WOBBLY "ON")
191>>>>>>> MERGE-SOURCE
166192
=== modified file 'NEWS'
=== modified file 'VERSION'
--- VERSION 2012-01-24 09:11:41 +0000
+++ VERSION 2012-02-08 18:50:27 +0000
@@ -1,1 +1,5 @@
1<<<<<<< TREE
10.9.7.020.9.7.0
3=======
40.9.6
5>>>>>>> MERGE-SOURCE
26
=== modified file 'cmake/CMakeLists.txt'
--- cmake/CMakeLists.txt 2011-07-27 16:13:28 +0000
+++ cmake/CMakeLists.txt 2012-02-08 18:50:27 +0000
@@ -15,6 +15,8 @@
15 plugin_extensions/CompizGenInstallData.cmake)15 plugin_extensions/CompizGenInstallData.cmake)
16list (APPEND _PluginExtensionFiles16list (APPEND _PluginExtensionFiles
17 plugin_extensions/CompizGenInstallImages.cmake)17 plugin_extensions/CompizGenInstallImages.cmake)
18list (APPEND _PluginExtensionFiles
19 plugin_extensions/CompizOpenGLFixups.cmake)
1820
19if (USE_GCONF)21if (USE_GCONF)
20 list (APPEND _files CompizGconf.cmake)22 list (APPEND _files CompizGconf.cmake)
2123
=== modified file 'cmake/CompizCommon.cmake'
--- cmake/CompizCommon.cmake 2012-01-27 07:01:47 +0000
+++ cmake/CompizCommon.cmake 2012-02-08 18:50:27 +0000
@@ -18,6 +18,7 @@
1818
19set (CMAKE_SKIP_RPATH FALSE)19set (CMAKE_SKIP_RPATH FALSE)
2020
21option (BUILD_GLES "Build against GLESv2 instead of GL" OFF)
21option (COMPIZ_BUILD_WITH_RPATH "Leave as ON unless building packages" ON)22option (COMPIZ_BUILD_WITH_RPATH "Leave as ON unless building packages" ON)
22option (COMPIZ_RUN_LDCONFIG "Leave OFF unless you need to run ldconfig after install")23option (COMPIZ_RUN_LDCONFIG "Leave OFF unless you need to run ldconfig after install")
23option (COMPIZ_PACKAGING_ENABLED "Enable to manually set prefix, exec_prefix, libdir, includedir, datadir" OFF)24option (COMPIZ_PACKAGING_ENABLED "Enable to manually set prefix, exec_prefix, libdir, includedir, datadir" OFF)
@@ -75,6 +76,17 @@
75 set(IS_BZR_REPO 0)76 set(IS_BZR_REPO 0)
76endif (IS_DIRECTORY ${CMAKE_SOURCE_DIR}/.bzr)77endif (IS_DIRECTORY ${CMAKE_SOURCE_DIR}/.bzr)
7778
79set (USE_GLES ${BUILD_GLES})
80
81if (USE_GLES)
82 find_package(OpenGLES2)
83
84 if (NOT OPENGLES2_FOUND)
85 set (USE_GLES 0)
86 message (SEND_ERROR "OpenGLESv2 not found")
87 endif (NOT OPENGLES2_FOUND)
88endif (USE_GLES)
89
78function (compiz_ensure_linkage)90function (compiz_ensure_linkage)
79 find_program (LDCONFIG_EXECUTABLE ldconfig)91 find_program (LDCONFIG_EXECUTABLE ldconfig)
80 mark_as_advanced (FORCE LDCONFIG_EXECUTABLE)92 mark_as_advanced (FORCE LDCONFIG_EXECUTABLE)
@@ -124,8 +136,13 @@
124 add_custom_target (release-signoff)136 add_custom_target (release-signoff)
125137
126 add_custom_target (release-update-working-tree138 add_custom_target (release-update-working-tree
139<<<<<<< TREE
127 COMMAND cp NEWS ${CMAKE_SOURCE_DIR} && bzr add ${CMAKE_SOURCE_DIR}/NEWS &&140 COMMAND cp NEWS ${CMAKE_SOURCE_DIR} && bzr add ${CMAKE_SOURCE_DIR}/NEWS &&
128 cp AUTHORS ${CMAKE_SOURCE_DIR} && bzr add ${CMAKE_SOURCE_DIR}/AUTHORS141 cp AUTHORS ${CMAKE_SOURCE_DIR} && bzr add ${CMAKE_SOURCE_DIR}/AUTHORS
142=======
143 COMMAND cp NEWS ${CMAKE_SOURCE_DIR} && git add ${CMAKE_SOURCE_DIR}/NEWS &&
144 cp AUTHORS ${CMAKE_SOURCE_DIR} && git add ${CMAKE_SOURCE_DIR}/AUTHORS
145>>>>>>> MERGE-SOURCE
129 COMMENT "Updating working tree"146 COMMENT "Updating working tree"
130 WORKING_DIRECTORY ${CMAKE_BINARY_DIR}) 147 WORKING_DIRECTORY ${CMAKE_BINARY_DIR})
131148
@@ -190,6 +207,7 @@
190 message ("-- Using auto news update: " ${AUTO_NEWS_UPDATE})207 message ("-- Using auto news update: " ${AUTO_NEWS_UPDATE})
191 endif (AUTO_NEWS_UPDATE)208 endif (AUTO_NEWS_UPDATE)
192209
210<<<<<<< TREE
193 if (NOT EXISTS ${CMAKE_SOURCE_DIR}/.AUTHORS.sed)211 if (NOT EXISTS ${CMAKE_SOURCE_DIR}/.AUTHORS.sed)
194 file (WRITE ${CMAKE_SOURCE_DIR}/.AUTHORS.sed "")212 file (WRITE ${CMAKE_SOURCE_DIR}/.AUTHORS.sed "")
195 endif (NOT EXISTS ${CMAKE_SOURCE_DIR}/.AUTHORS.sed)213 endif (NOT EXISTS ${CMAKE_SOURCE_DIR}/.AUTHORS.sed)
@@ -210,6 +228,55 @@
210 COMMENT "Generating NEWS Header"228 COMMENT "Generating NEWS Header"
211 WORKING_DIRECTORY ${CMAKE_SOURCE_DIR})229 WORKING_DIRECTORY ${CMAKE_SOURCE_DIR})
212 endif (AUTO_NEWS_UPDATE)230 endif (AUTO_NEWS_UPDATE)
231=======
232 if (NOT EXISTS ${CMAKE_SOURCE_DIR}/.AUTHORS.sed)
233 file (WRITE ${CMAKE_SOURCE_DIR}/.AUTHORS.sed "")
234 endif (NOT EXISTS ${CMAKE_SOURCE_DIR}/.AUTHORS.sed)
235
236 if (${IS_GIT_REPO})
237 find_program (GEN_GIT_LOG gen-git-log.sh)
238 add_custom_target (authors
239 COMMAND git shortlog -se | cut -c8- | sed -r -f ${CMAKE_SOURCE_DIR}/.AUTHORS.sed | sort -u > AUTHORS
240 COMMENT "Generating AUTHORS"
241 WORKING_DIRECTORY ${CMAKE_BINARY_DIR})
242
243 if (AUTO_NEWS_UPDATE)
244 add_custom_target (news-header echo > ${CMAKE_BINARY_DIR}/NEWS.update
245 COMMAND echo 'Release ${VERSION} ('`date +%Y-%m-%d`' '`git config user.name`' <'`git config user.email`'>)' > ${CMAKE_BINARY_DIR}/NEWS.update && seq -s "=" `cat ${CMAKE_BINARY_DIR}/NEWS.update | wc -c` | sed 's/[0-9]//g' >> ${CMAKE_BINARY_DIR}/NEWS.update && echo '${AUTO_NEWS_UPDATE}' >> ${CMAKE_BINARY_DIR}/NEWS.update && echo >> ${CMAKE_BINARY_DIR}/NEWS.update
246 COMMENT "Generating NEWS Header"
247 WORKING_DIRECTORY ${CMAKE_BINARY_DIR})
248 else (AUTO_NEWS_UPDATE)
249 add_custom_target (news-header echo > ${CMAKE_BINARY_DIR}/NEWS.update
250 COMMAND echo 'Release ${VERSION} ('`date +%Y-%m-%d`' '`git config user.name`' <'`git config user.email`'>)' > ${CMAKE_BINARY_DIR}/NEWS.update && seq -s "=" `cat ${CMAKE_BINARY_DIR}/NEWS.update | wc -c` | sed 's/[0-9]//g' >> ${CMAKE_BINARY_DIR}/NEWS.update && $ENV{EDITOR} ${CMAKE_BINARY_DIR}/NEWS.update && echo >> ${CMAKE_BINARY_DIR}/NEWS.update
251 COMMENT "Generating NEWS Header"
252 WORKING_DIRECTORY ${CMAKE_BINARY_DIR})
253 endif (AUTO_NEWS_UPDATE)
254
255 else (${IS_GIT_REPO})
256 if (${IS_BZR_REPO})
257 add_custom_target (authors
258 COMMAND bzr log --long --levels=0 | grep -e "^\\s*author:" -e "^\\s*committer:" | cut -d ":" -f 2 | sed -r -f ${CMAKE_SOURCE_DIR}/.AUTHORS.sed | sort -u > AUTHORS
259 COMMENT "Generating AUTHORS")
260
261 if (AUTO_NEWS_UPDATE)
262
263 add_custom_target (news-header echo > ${CMAKE_BINARY_DIR}/NEWS.update
264 COMMAND echo 'Release ${VERSION} ('`date +%Y-%m-%d`' '`bzr config email`')' > ${CMAKE_BINARY_DIR}/NEWS.update && seq -s "=" `cat ${CMAKE_BINARY_DIR}/NEWS.update | wc -c` | sed 's/[0-9]//g' >> ${CMAKE_BINARY_DIR}/NEWS.update && echo '${AUTO_NEWS_UPDATE}' >> ${CMAKE_BINARY_DIR}/NEWS.update && echo >> ${CMAKE_BINARY_DIR}/NEWS.update
265 COMMENT "Generating NEWS Header"
266 WORKING_DIRECTORY ${CMAKE_SOURCE_DIR})
267 else (AUTO_NEWS_UPDATE)
268 add_custom_target (news-header echo > ${CMAKE_BINARY_DIR}/NEWS.update
269 COMMAND echo 'Release ${VERSION} ('`date +%Y-%m-%d`' '`bzr config email`')' > ${CMAKE_BINARY_DIR}/NEWS.update && seq -s "=" `cat ${CMAKE_BINARY_DIR}/NEWS.update | wc -c` | sed 's/[0-9]//g' >> ${CMAKE_BINARY_DIR}/NEWS.update && $ENV{EDITOR} ${CMAKE_BINARY_DIR}/NEWS.update && echo >> ${CMAKE_BINARY_DIR}/NEWS.update
270 COMMENT "Generating NEWS Header"
271 WORKING_DIRECTORY ${CMAKE_SOURCE_DIR})
272 endif (AUTO_NEWS_UPDATE)
273
274 else (${IS_BZR_REPO})
275 add_custom_target (authors)
276 add_custom_target (news-header)
277 endif (${IS_BZR_REPO})
278 endif (${IS_GIT_REPO})
279>>>>>>> MERGE-SOURCE
213280
214 add_custom_target (news281 add_custom_target (news
215 COMMAND cat ${CMAKE_SOURCE_DIR}/NEWS > NEWS.old &&282 COMMAND cat ${CMAKE_SOURCE_DIR}/NEWS > NEWS.old &&
216283
=== added file 'cmake/CompizGSettings.cmake'
--- cmake/CompizGSettings.cmake 1970-01-01 00:00:00 +0000
+++ cmake/CompizGSettings.cmake 2012-02-08 18:50:27 +0000
@@ -0,0 +1,76 @@
1option (
2 USE_GSETTINGS
3 "Generate GSettings schemas"
4 ON
5)
6
7option (
8 COMPIZ_DISABLE_GS_SCHEMAS_INSTALL
9 "Disables gsettings schema installation"
10 OFF
11)
12
13set (
14 COMPIZ_INSTALL_GSETTINGS_SCHEMA_DIR ${COMPIZ_INSTALL_GSETTINGS_SCHEMA_DIR} CACHE PATH
15 "Installation path of the gsettings schema file"
16)
17
18function (compiz_install_gsettings_schema _src _dst)
19 find_program (PKG_CONFIG_TOOL pkg-config)
20 find_program (GLIB_COMPILE_SCHEMAS glib-compile-schemas)
21 mark_as_advanced (FORCE PKG_CONFIG_TOOL)
22
23 # find out where schemas need to go if we are installing them systemwide
24 execute_process (COMMAND ${PKG_CONFIG_TOOL} glib-2.0 --variable prefix OUTPUT_VARIABLE GSETTINGS_GLIB_PREFIX OUTPUT_STRIP_TRAILING_WHITESPACE)
25 SET (GSETTINGS_GLOBAL_INSTALL_DIR "${GSETTINGS_GLIB_PREFIX}/share/glib-2.0/schemas/")
26
27 if (PKG_CONFIG_TOOL AND
28 GLIB_COMPILE_SCHEMAS AND NOT
29 COMPIZ_DISABLE_SCHEMAS_INSTALL AND
30 USE_GSETTINGS)
31 install (CODE "
32 message (\"$ENV{USER} is the username in use right now\")
33 if (\"$ENV{USER}\"\ STREQUAL \"root\")
34 message (\"-- Installing GSettings schemas ${GSETTINGS_GLOBAL_INSTALL_DIR}\"\)
35 file (INSTALL DESTINATION \"${GSETTINGS_GLOBAL_INSTALL_DIR}\"
36 TYPE FILE
37 FILES \"${_src}\")
38 message (\"-- Recompiling GSettings schemas in ${GSETTINGS_GLOBAL_INSTALL_DIR}\"\)
39 execute_process (COMMAND ${GLIB_COMPILE_SCHEMAS} ${GSETTINGS_GLOBAL_INSTALL_DIR})
40
41 else (\"$ENV{USER}\"\ STREQUAL \"root\"\)
42 # It seems like this is only available in CMake > 2.8.5
43 # but hardly anybody has that, so comment out this warning for now
44 # string (FIND $ENV{XDG_DATA_DIRS} \"${COMPIZ_DESTDIR}${_dst}\" XDG_INSTALL_PATH)
45 # if (NOT XDG_INSTALL_PATH)
46 # message (\"[WARNING]: Installing GSettings schemas to directory that is not in XDG_DATA_DIRS, you need to add ${COMPIZ_DESTDIR}${_dst} to your XDG_DATA_DIRS in order for GSettings schemas to be found!\"\)
47 # endif (NOT XDG_INSTALL_PATH)
48 message (\"-- Installing GSettings schemas to ${COMPIZ_DESTDIR}${_dst}\"\)
49 file (INSTALL DESTINATION \"${COMPIZ_DESTDIR}${_dst}\"
50 TYPE FILE
51 FILES \"${_src}\")
52 message (\"-- Recompiling GSettings schemas in ${COMPIZ_DESTDIR}${_dst}\"\)
53 execute_process (COMMAND ${GLIB_COMPILE_SCHEMAS} ${COMPIZ_DESTDIR}${_dst})
54 endif (\"$ENV{USER}\" STREQUAL \"root\"\)
55 ")
56 endif ()
57endfunction ()
58
59# generate gconf schema
60function (compiz_gsettings_schema _src _dst _inst)
61 find_program (XSLTPROC_EXECUTABLE xsltproc)
62 mark_as_advanced (FORCE XSLTPROC_EXECUTABLE)
63
64 if (XSLTPROC_EXECUTABLE AND USE_GSETTINGS)
65 message ("generating gsettings schema for core")
66 add_custom_command (
67 OUTPUT ${_dst}
68 COMMAND ${XSLTPROC_EXECUTABLE}
69 -o ${_dst}
70 ${COMPIZ_GSETTINGS_SCHEMAS_XSLT}
71 ${_src}
72 DEPENDS ${_src}
73 )
74 compiz_install_gsettings_schema (${_dst} ${_inst})
75 endif ()
76endfunction ()
077
=== renamed file 'cmake/CompizGSettings.cmake' => 'cmake/CompizGSettings.cmake.THIS'
=== modified file 'cmake/CompizPlugin.cmake'
--- cmake/CompizPlugin.cmake 2012-01-23 17:33:54 +0000
+++ cmake/CompizPlugin.cmake 2012-02-08 18:50:27 +0000
@@ -257,6 +257,16 @@
257 NO_DEFAULT_PATH257 NO_DEFAULT_PATH
258 )258 )
259259
260 set (COMPIZ_CURRENT_PLUGIN ${plugin})
261 set (COMPIZ_CURRENT_XML_FILE ${_translated_xml})
262
263 # find extension files
264 file (GLOB _extension_files "${COMPIZ_CMAKE_MODULE_PATH}/plugin_extensions/*.cmake")
265
266 foreach (_file ${_extension_files})
267 include (${_file})
268 endforeach ()
269
260 # generate pkgconfig file and install it and the plugin header file270 # generate pkgconfig file and install it and the plugin header file
261 if (_${plugin}_pkg AND EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/include/${plugin})271 if (_${plugin}_pkg AND EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/include/${plugin})
262 if ("${PLUGIN_BUILDTYPE}" STREQUAL "local")272 if ("${PLUGIN_BUILDTYPE}" STREQUAL "local")
@@ -269,11 +279,15 @@
269 set (VERSION 0.0.1-git)279 set (VERSION 0.0.1-git)
270 endif (NOT VERSION)280 endif (NOT VERSION)
271281
282 #add CFLAGSADD so pkg-config file has correct flags
283 set (COMPIZ_CFLAGS ${COMPIZ_CFLAGS} ${${_PLUGIN}_CFLAGSADD})
284
272 compiz_configure_file (285 compiz_configure_file (
273 ${_${plugin}_pkg}286 ${_${plugin}_pkg}
274 ${CMAKE_BINARY_DIR}/generated/compiz-${plugin}.pc287 ${CMAKE_BINARY_DIR}/generated/compiz-${plugin}.pc
275 COMPIZ_REQUIRES288 COMPIZ_REQUIRES
276 COMPIZ_CFLAGS289 COMPIZ_CFLAGS
290 PKGCONFIG_LIBS
277 )291 )
278292
279 install (293 install (
@@ -287,16 +301,6 @@
287 endif ()301 endif ()
288 endif ()302 endif ()
289303
290 set (COMPIZ_CURRENT_PLUGIN ${plugin})
291 set (COMPIZ_CURRENT_XML_FILE ${_translated_xml})
292
293 # find extension files
294 file (GLOB _extension_files "${COMPIZ_CMAKE_MODULE_PATH}/plugin_extensions/*.cmake")
295
296 foreach (_file ${_extension_files})
297 include (${_file})
298 endforeach ()
299
300 # find files for build304 # find files for build
301 file (GLOB _h_files "${CMAKE_CURRENT_SOURCE_DIR}/src/*.h")305 file (GLOB _h_files "${CMAKE_CURRENT_SOURCE_DIR}/src/*.h")
302 file (GLOB _h_ins_files "${CMAKE_CURRENT_SOURCE_DIR}/include/${plugin}/*.h")306 file (GLOB _h_ins_files "${CMAKE_CURRENT_SOURCE_DIR}/include/${plugin}/*.h")
303307
=== added file 'cmake/FindOpenGLES2.cmake'
--- cmake/FindOpenGLES2.cmake 1970-01-01 00:00:00 +0000
+++ cmake/FindOpenGLES2.cmake 2012-02-08 18:50:27 +0000
@@ -0,0 +1,51 @@
1# - Try to find OpenGLES
2# Once done this will define
3#
4# OPENGLES2_FOUND - system has OpenGLES
5# OPENGLES2_INCLUDE_DIR - the GLES include directory
6# OPENGLES2_LIBRARY - the GLES library
7# OPENGLES2_LIBRARIES - Link this to use OpenGLES
8#
9
10FIND_PATH(OPENGLES2_INCLUDE_DIR GLES2/gl2.h
11 /usr/openwin/share/include
12 /opt/graphics/OpenGL/include /usr/X11R6/include
13 /usr/include
14)
15
16FIND_LIBRARY(OPENGLES2_LIBRARY
17 NAMES GLESv2
18 PATHS /opt/graphics/OpenGL/lib
19 /usr/openwin/lib
20 /usr/shlib /usr/X11R6/lib
21 /usr/lib
22)
23
24FIND_LIBRARY(OPENGLES2_EGL_LIBRARY
25 NAMES EGL
26 PATHS /usr/shlib /usr/X11R6/lib
27 /usr/lib
28)
29
30# On Unix OpenGL most certainly always requires X11.
31# Feel free to tighten up these conditions if you don't
32# think this is always true.
33# It's not true on OSX.
34
35IF (OPENGLES2_LIBRARY)
36 IF(NOT X11_FOUND)
37 INCLUDE(FindX11)
38 ENDIF(NOT X11_FOUND)
39 IF (X11_FOUND)
40 IF (NOT APPLE)
41 SET (OPENGLES2_LIBRARIES ${X11_LIBRARIES})
42 ENDIF (NOT APPLE)
43 ENDIF (X11_FOUND)
44ENDIF(OPENGLES2_LIBRARY)
45
46SET( OPENGLES2_FOUND "NO" )
47IF(OPENGLES2_LIBRARY AND OPENGLES2_EGL_LIBRARY)
48 SET( OPENGLES2_LIBRARIES ${OPENGLES2_LIBRARY} ${OPENGLES2_EGL_LIBRARY} ${OPENGLES2_LIBRARIES})
49 SET( OPENGLES2_FOUND "YES" )
50ENDIF(OPENGLES2_LIBRARY AND OPENGLES2_EGL_LIBRARY)
51
052
=== modified file 'cmake/base.cmake'
--- cmake/base.cmake 2011-07-27 16:13:28 +0000
+++ cmake/base.cmake 2012-02-08 18:50:27 +0000
@@ -24,6 +24,7 @@
24 compiz_print_configure_header ("Compiz")24 compiz_print_configure_header ("Compiz")
25 compiz_color_message ("\n${_escape}[4mOptional features:${_escape}[0m\n")25 compiz_color_message ("\n${_escape}[4mOptional features:${_escape}[0m\n")
2626
27 compiz_print_result_message ("GLESv2" USE_GLES)
27 compiz_print_result_message ("gtk window decorator" USE_GTK)28 compiz_print_result_message ("gtk window decorator" USE_GTK)
28 compiz_print_result_message ("metacity theme support" USE_METACITY)29 compiz_print_result_message ("metacity theme support" USE_METACITY)
29 compiz_print_result_message ("gconf schemas" USE_GCONF)30 compiz_print_result_message ("gconf schemas" USE_GCONF)
@@ -46,7 +47,8 @@
46 endif ()47 endif ()
47 add_custom_target (findcompiz_install48 add_custom_target (findcompiz_install
48 ${CMAKE_COMMAND} -E make_directory ${COMPIZ_DESTDIR}${CMAKE_ROOT}/Modules &&49 ${CMAKE_COMMAND} -E make_directory ${COMPIZ_DESTDIR}${CMAKE_ROOT}/Modules &&
49 ${CMAKE_COMMAND} -E copy ${CMAKE_SOURCE_DIR}/cmake/FindCompiz.cmake ${COMPIZ_DESTDIR}${CMAKE_ROOT}/Modules50 ${CMAKE_COMMAND} -E copy ${CMAKE_SOURCE_DIR}/cmake/FindCompiz.cmake ${COMPIZ_DESTDIR}${CMAKE_ROOT}/Modules &&
51 ${CMAKE_COMMAND} -E copy ${CMAKE_SOURCE_DIR}/cmake/FindOpenGLES2.cmake ${COMPIZ_DESTDIR}${CMAKE_ROOT}/Modules
50 )52 )
51endfunction ()53endfunction ()
5254
5355
=== added file 'cmake/plugin_extensions/CompizGenGSettings.cmake'
--- cmake/plugin_extensions/CompizGenGSettings.cmake 1970-01-01 00:00:00 +0000
+++ cmake/plugin_extensions/CompizGenGSettings.cmake 2012-02-08 18:50:27 +0000
@@ -0,0 +1,104 @@
1option (
2 COMPIZ_DISABLE_SCHEMAS_INSTALL
3 "Disables gsettings schema installation"
4 OFF
5)
6
7option (
8 USE_GSETTINGS
9 "Generate GSettings schemas"
10 ON
11)
12
13set (
14 COMPIZ_INSTALL_GSETTINGS_SCHEMA_DIR ${COMPIZ_INSTALL_GSETTINGS_SCHEMA_DIR} CACHE PATH
15 "Installation path of the gsettings schema file"
16)
17
18macro (compiz_gsettings_prepare_install_dirs)
19 # package
20 if ("${COMPIZ_PLUGIN_INSTALL_TYPE}" STREQUAL "package")
21 if (NOT COMPIZ_INSTALL_GSETTINGS_SCHEMA_DIR)
22 set (PLUGIN_SCHEMADIR "${datadir}/glib-2.0/schemas/")
23 else (NOT COMPIZ_INSTALL_GSETTINGS_SCHEMA_DIR)
24 set (PLUGIN_SCHEMADIR "${COMPIZ_INSTALL_GSETTINGS_SCHEMA_DIR}")
25 endif (NOT COMPIZ_INSTALL_GSETTINGS_SCHEMA_DIR)
26 # compiz
27 elseif ("${COMPIZ_PLUGIN_INSTALL_TYPE}" STREQUAL "compiz" OR
28 "$ENV{BUILD_GLOBAL}" STREQUAL "true")
29 if (NOT COMPIZ_INSTALL_GSETTINGS_SCHEMA_DIR)
30 set (PLUGIN_SCHEMADIR "${COMPIZ_PREFIX}/share/glib-2.0/schemas/")
31 else (NOT COMPIZ_INSTALL_GSETTINGS_SCHEMA_DIR)
32 set (PLUGIN_SCHEMADIR "${COMPIZ_INSTALL_GSETTINGS_SCHEMA_DIR}")
33 endif (NOT COMPIZ_INSTALL_GSETTINGS_SCHEMA_DIR)
34 # local
35 else ("${COMPIZ_PLUGIN_INSTALL_TYPE}" STREQUAL "compiz" OR
36 "$ENV{BUILD_GLOBAL}" STREQUAL "true")
37
38 if (NOT COMPIZ_INSTALL_GSETTINGS_SCHEMA_DIR)
39 set (PLUGIN_SCHEMADIR "$ENV{HOME}/.config/compiz-1/gsettings/schemas")
40 else (NOT COMPIZ_INSTALL_GSETTINGS_SCHEMA_DIR)
41 set (PLUGIN_SCHEMADIR "${COMPIZ_INSTALL_GSETTINGS_SCHEMA_DIR}")
42 endif (NOT COMPIZ_INSTALL_GSETTINGS_SCHEMA_DIR)
43
44 endif ("${COMPIZ_PLUGIN_INSTALL_TYPE}" STREQUAL "package")
45endmacro (compiz_gsettings_prepare_install_dirs)
46
47function (compiz_install_gsettings_schema _src _dst)
48 find_program (PKG_CONFIG_TOOL pkg-config)
49 find_program (GLIB_COMPILE_SCHEMAS glib-compile-schemas)
50 mark_as_advanced (FORCE PKG_CONFIG_TOOL)
51
52 # find out where schemas need to go if we are installing them systemwide
53 execute_process (COMMAND ${PKG_CONFIG_TOOL} glib-2.0 --variable prefix OUTPUT_VARIABLE GSETTINGS_GLIB_PREFIX OUTPUT_STRIP_TRAILING_WHITESPACE)
54 SET (GSETTINGS_GLOBAL_INSTALL_DIR "${GSETTINGS_GLIB_PREFIX}/share/glib-2.0/schemas/")
55
56 if (USE_GSETTINGS AND
57 PKG_CONFIG_TOOL AND
58 GLIB_COMPILE_SCHEMAS AND NOT
59 COMPIZ_DISABLE_SCHEMAS_INSTALL)
60 install (CODE "
61 if (\"$ENV{USER}\"\ STREQUAL \"root\")
62 message (\"-- Installing GSettings schemas ${GSETTINGS_GLOBAL_INSTALL_DIR}\"\)
63 file (INSTALL DESTINATION \"${GSETTINGS_GLOBAL_INSTALL_DIR}\"
64 TYPE FILE
65 FILES \"${_src}\")
66 message (\"-- Recompiling GSettings schemas in ${GSETTINGS_GLOBAL_INSTALL_DIR}\"\)
67 execute_process (COMMAND ${GLIB_COMPILE_SCHEMAS} ${GSETTINGS_GLOBAL_INSTALL_DIR})
68
69 else (\"$ENV{USER}\"\ STREQUAL \"root\"\)
70 # It seems like this is only available in CMake > 2.8.5
71 # but hardly anybody has that, so comment out this warning for now
72 # string (FIND $ENV{XDG_DATA_DIRS} \"${COMPIZ_DESTDIR}${_dst}\" XDG_INSTALL_PATH)
73 # if (NOT XDG_INSTALL_PATH)
74 message (\"[WARNING]: Installing GSettings schemas to a custom location that might not be in XDG_DATA_DIRS, you need to add ${COMPIZ_DESTDIR}${_dst} to your XDG_DATA_DIRS in order for GSettings schemas to be found!\"\)
75 # endif (NOT XDG_INSTALL_PATH)
76 message (\"-- Installing GSettings schemas to ${COMPIZ_DESTDIR}${_dst}\"\)
77 file (INSTALL DESTINATION \"${COMPIZ_DESTDIR}${_dst}\"
78 TYPE FILE
79 FILES \"${_src}\")
80 message (\"-- Recompiling GSettings schemas in ${COMPIZ_DESTDIR}${_dst}\"\)
81 execute_process (COMMAND ${GLIB_COMPILE_SCHEMAS} ${COMPIZ_DESTDIR}${_dst})
82 endif (\"$ENV{USER}\" STREQUAL \"root\"\)
83 ")
84 endif ()
85endfunction ()
86
87# generate gsettings schema
88find_program (XSLTPROC_EXECUTABLE xsltproc)
89mark_as_advanced (FORCE XSLTPROC_EXECUTABLE)
90
91if (XSLTPROC_EXECUTABLE AND USE_GSETTINGS)
92 compiz_gsettings_prepare_install_dirs ()
93
94 add_custom_command (
95 OUTPUT "${CMAKE_BINARY_DIR}/generated/org.freedesktop.compiz.${COMPIZ_CURRENT_PLUGIN}.gschema.xml"
96 COMMAND ${XSLTPROC_EXECUTABLE}
97 -o "${CMAKE_BINARY_DIR}/generated/org.freedesktop.compiz.${COMPIZ_CURRENT_PLUGIN}.gschema.xml"
98 ${COMPIZ_GSETTINGS_SCHEMAS_XSLT}
99 ${COMPIZ_CURRENT_XML_FILE}
100 DEPENDS ${COMPIZ_CURRENT_XML_FILE}
101 )
102 compiz_install_gsettings_schema ("${CMAKE_BINARY_DIR}/generated/org.freedesktop.compiz.${COMPIZ_CURRENT_PLUGIN}.gschema.xml" ${PLUGIN_SCHEMADIR})
103 list (APPEND COMPIZ_CURRENT_SOURCES_ADDS ${CMAKE_BINARY_DIR}/generated/org.freedesktop.compiz.${COMPIZ_CURRENT_PLUGIN}.gschema.xml)
104endif ()
0105
=== removed file 'cmake/plugin_extensions/CompizGenGSettings.cmake'
--- cmake/plugin_extensions/CompizGenGSettings.cmake 2011-09-29 03:29:41 +0000
+++ cmake/plugin_extensions/CompizGenGSettings.cmake 1970-01-01 00:00:00 +0000
@@ -1,104 +0,0 @@
1option (
2 COMPIZ_DISABLE_SCHEMAS_INSTALL
3 "Disables gsettings schema installation"
4 OFF
5)
6
7option (
8 USE_GSETTINGS
9 "Generate GSettings schemas"
10 ON
11)
12
13set (
14 COMPIZ_INSTALL_GSETTINGS_SCHEMA_DIR ${COMPIZ_INSTALL_GSETTINGS_SCHEMA_DIR} CACHE PATH
15 "Installation path of the gsettings schema file"
16)
17
18macro (compiz_gsettings_prepare_install_dirs)
19 # package
20 if ("${COMPIZ_PLUGIN_INSTALL_TYPE}" STREQUAL "package")
21 if (NOT COMPIZ_INSTALL_GSETTINGS_SCHEMA_DIR)
22 set (PLUGIN_SCHEMADIR "${datadir}/glib-2.0/schemas/")
23 else (NOT COMPIZ_INSTALL_GSETTINGS_SCHEMA_DIR)
24 set (PLUGIN_SCHEMADIR "${COMPIZ_INSTALL_GSETTINGS_SCHEMA_DIR}")
25 endif (NOT COMPIZ_INSTALL_GSETTINGS_SCHEMA_DIR)
26 # compiz
27 elseif ("${COMPIZ_PLUGIN_INSTALL_TYPE}" STREQUAL "compiz" OR
28 "$ENV{BUILD_GLOBAL}" STREQUAL "true")
29 if (NOT COMPIZ_INSTALL_GSETTINGS_SCHEMA_DIR)
30 set (PLUGIN_SCHEMADIR "${COMPIZ_PREFIX}/share/glib-2.0/schemas/")
31 else (NOT COMPIZ_INSTALL_GSETTINGS_SCHEMA_DIR)
32 set (PLUGIN_SCHEMADIR "${COMPIZ_INSTALL_GSETTINGS_SCHEMA_DIR}")
33 endif (NOT COMPIZ_INSTALL_GSETTINGS_SCHEMA_DIR)
34 # local
35 else ("${COMPIZ_PLUGIN_INSTALL_TYPE}" STREQUAL "compiz" OR
36 "$ENV{BUILD_GLOBAL}" STREQUAL "true")
37
38 if (NOT COMPIZ_INSTALL_GSETTINGS_SCHEMA_DIR)
39 set (PLUGIN_SCHEMADIR "$ENV{HOME}/.config/compiz-1/gsettings/schemas")
40 else (NOT COMPIZ_INSTALL_GSETTINGS_SCHEMA_DIR)
41 set (PLUGIN_SCHEMADIR "${COMPIZ_INSTALL_GSETTINGS_SCHEMA_DIR}")
42 endif (NOT COMPIZ_INSTALL_GSETTINGS_SCHEMA_DIR)
43
44 endif ("${COMPIZ_PLUGIN_INSTALL_TYPE}" STREQUAL "package")
45endmacro (compiz_gsettings_prepare_install_dirs)
46
47function (compiz_install_gsettings_schema _src _dst)
48 find_program (PKG_CONFIG_TOOL pkg-config)
49 find_program (GLIB_COMPILE_SCHEMAS glib-compile-schemas)
50 mark_as_advanced (FORCE PKG_CONFIG_TOOL)
51
52 # find out where schemas need to go if we are installing them systemwide
53 execute_process (COMMAND ${PKG_CONFIG_TOOL} glib-2.0 --variable prefix OUTPUT_VARIABLE GSETTINGS_GLIB_PREFIX OUTPUT_STRIP_TRAILING_WHITESPACE)
54 SET (GSETTINGS_GLOBAL_INSTALL_DIR "${GSETTINGS_GLIB_PREFIX}/share/glib-2.0/schemas/")
55
56 if (USE_GSETTINGS AND
57 PKG_CONFIG_TOOL AND
58 GLIB_COMPILE_SCHEMAS AND NOT
59 COMPIZ_DISABLE_SCHEMAS_INSTALL)
60 install (CODE "
61 if (\"$ENV{USER}\"\ STREQUAL \"root\")
62 message (\"-- Installing GSettings schemas ${GSETTINGS_GLOBAL_INSTALL_DIR}\"\)
63 file (INSTALL DESTINATION \"${GSETTINGS_GLOBAL_INSTALL_DIR}\"
64 TYPE FILE
65 FILES \"${_src}\")
66 message (\"-- Recompiling GSettings schemas in ${GSETTINGS_GLOBAL_INSTALL_DIR}\"\)
67 execute_process (COMMAND ${GLIB_COMPILE_SCHEMAS} ${GSETTINGS_GLOBAL_INSTALL_DIR})
68
69 else (\"$ENV{USER}\"\ STREQUAL \"root\"\)
70 # It seems like this is only available in CMake > 2.8.5
71 # but hardly anybody has that, so comment out this warning for now
72 # string (FIND $ENV{XDG_DATA_DIRS} \"${COMPIZ_DESTDIR}${_dst}\" XDG_INSTALL_PATH)
73 # if (NOT XDG_INSTALL_PATH)
74 message (\"[WARNING]: Installing GSettings schemas to a custom location that might not be in XDG_DATA_DIRS, you need to add ${COMPIZ_DESTDIR}${_dst} to your XDG_DATA_DIRS in order for GSettings schemas to be found!\"\)
75 # endif (NOT XDG_INSTALL_PATH)
76 message (\"-- Installing GSettings schemas to ${COMPIZ_DESTDIR}${_dst}\"\)
77 file (INSTALL DESTINATION \"${COMPIZ_DESTDIR}${_dst}\"
78 TYPE FILE
79 FILES \"${_src}\")
80 message (\"-- Recompiling GSettings schemas in ${COMPIZ_DESTDIR}${_dst}\"\)
81 execute_process (COMMAND ${GLIB_COMPILE_SCHEMAS} ${COMPIZ_DESTDIR}${_dst})
82 endif (\"$ENV{USER}\" STREQUAL \"root\"\)
83 ")
84 endif ()
85endfunction ()
86
87# generate gsettings schema
88find_program (XSLTPROC_EXECUTABLE xsltproc)
89mark_as_advanced (FORCE XSLTPROC_EXECUTABLE)
90
91if (XSLTPROC_EXECUTABLE AND USE_GSETTINGS)
92 compiz_gsettings_prepare_install_dirs ()
93
94 add_custom_command (
95 OUTPUT "${CMAKE_BINARY_DIR}/generated/org.freedesktop.compiz.${COMPIZ_CURRENT_PLUGIN}.gschema.xml"
96 COMMAND ${XSLTPROC_EXECUTABLE}
97 -o "${CMAKE_BINARY_DIR}/generated/org.freedesktop.compiz.${COMPIZ_CURRENT_PLUGIN}.gschema.xml"
98 ${COMPIZ_GSETTINGS_SCHEMAS_XSLT}
99 ${COMPIZ_CURRENT_XML_FILE}
100 DEPENDS ${COMPIZ_CURRENT_XML_FILE}
101 )
102 compiz_install_gsettings_schema ("${CMAKE_BINARY_DIR}/generated/org.freedesktop.compiz.${COMPIZ_CURRENT_PLUGIN}.gschema.xml" ${PLUGIN_SCHEMADIR})
103 list (APPEND COMPIZ_CURRENT_SOURCES_ADDS ${CMAKE_BINARY_DIR}/generated/org.freedesktop.compiz.${COMPIZ_CURRENT_PLUGIN}.gschema.xml)
104endif ()
1050
=== added file 'cmake/plugin_extensions/CompizOpenGLFixups.cmake'
--- cmake/plugin_extensions/CompizOpenGLFixups.cmake 1970-01-01 00:00:00 +0000
+++ cmake/plugin_extensions/CompizOpenGLFixups.cmake 2012-02-08 18:50:27 +0000
@@ -0,0 +1,22 @@
1
2# modify pkg-config libs for opengl based on if we found GLES or not
3if (${COMPIZ_CURRENT_PLUGIN} STREQUAL "opengl")
4 if (USE_GLES)
5 set (PKGCONFIG_LIBS "-lGLESv2 -lEGL")
6 else (USE_GLES)
7 set (PKGCONFIG_LIBS "-lGL")
8 endif (USE_GLES)
9endif (${COMPIZ_CURRENT_PLUGIN} STREQUAL "opengl")
10
11# if plugin is using opengl plugin check for GLES library and set correct define
12if (NOT "${${_PLUGIN}_PLUGINDEPS}" STREQUAL "")
13 string (REGEX MATCH "opengl" opengl_found ${${_PLUGIN}_PLUGINDEPS})
14
15 if (opengl_found STREQUAL "opengl")
16 if (USE_GLES)
17 set (${_PLUGIN}_CFLAGSADD ${${_PLUGIN}_CFLAGSADD} " -DUSE_GLES")
18 string (REPLACE ";" " " ${_PLUGIN}_CFLAGSADD ${${_PLUGIN}_CFLAGSADD})
19 endif (USE_GLES)
20 endif (opengl_found STREQUAL "opengl")
21endif (NOT "${${_PLUGIN}_PLUGINDEPS}" STREQUAL "")
22
023
=== modified file 'gtk/CMakeLists.txt'
--- gtk/CMakeLists.txt 2011-10-13 14:06:05 +0000
+++ gtk/CMakeLists.txt 2012-02-08 18:50:27 +0000
@@ -82,7 +82,7 @@
8282
83configure_file (83configure_file (
84 ${CMAKE_CURRENT_SOURCE_DIR}/config.h.gtk.in84 ${CMAKE_CURRENT_SOURCE_DIR}/config.h.gtk.in
85 ${CMAKE_CURRENT_BINARY_DIR}/config.h85 ${CMAKE_CURRENT_BINARY_DIR}/config.h
86)86)
8787
88add_subdirectory (window-decorator)88add_subdirectory (window-decorator)
8989
=== added file 'gtk/config.h.gtk.in'
--- gtk/config.h.gtk.in 1970-01-01 00:00:00 +0000
+++ gtk/config.h.gtk.in 2012-02-08 18:50:27 +0000
@@ -0,0 +1,25 @@
1/* Define to 1 if Metacity support is enabled */
2#cmakedefine USE_METACITY 1
3
4/* Define to 1 if Gconf support is enabled */
5#cmakedefine USE_GCONF 1
6
7/* Define to 1 if you have the `wnck_window_has_name' function. */
8#cmakedefine HAVE_WNCK_WINDOW_HAS_NAME 1
9
10/* Define to 1 if libwnck version >= 2_18_1 */
11#cmakedefine HAVE_LIBWNCK_2_18_1 1
12
13/* Define to 1 if libwnck version >= 2_19_4 */
14#cmakedefine HAVE_LIBWNCK_2_19_4 1
15
16/* Define to 1 if metacity version >= 2.15.21 */
17#cmakedefine HAVE_METACITY_2_15_21 1
18
19/* Define to 1 if metacity version >= 2.17.0 */
20#cmakedefine HAVE_METACITY_2_17_0 1
21
22/* Define to 1 if metacity version >= 2.23.2 */
23#cmakedefine HAVE_METACITY_2_23_2 1
24
25#define GETTEXT_PACKAGE "${GETTEXT_PACKAGE}"
026
=== removed file 'gtk/config.h.gtk.in'
--- gtk/config.h.gtk.in 2008-10-14 10:27:55 +0000
+++ gtk/config.h.gtk.in 1970-01-01 00:00:00 +0000
@@ -1,25 +0,0 @@
1/* Define to 1 if Metacity support is enabled */
2#cmakedefine USE_METACITY 1
3
4/* Define to 1 if Gconf support is enabled */
5#cmakedefine USE_GCONF 1
6
7/* Define to 1 if you have the `wnck_window_has_name' function. */
8#cmakedefine HAVE_WNCK_WINDOW_HAS_NAME 1
9
10/* Define to 1 if libwnck version >= 2_18_1 */
11#cmakedefine HAVE_LIBWNCK_2_18_1 1
12
13/* Define to 1 if libwnck version >= 2_19_4 */
14#cmakedefine HAVE_LIBWNCK_2_19_4 1
15
16/* Define to 1 if metacity version >= 2.15.21 */
17#cmakedefine HAVE_METACITY_2_15_21 1
18
19/* Define to 1 if metacity version >= 2.17.0 */
20#cmakedefine HAVE_METACITY_2_17_0 1
21
22/* Define to 1 if metacity version >= 2.23.2 */
23#cmakedefine HAVE_METACITY_2_23_2 1
24
25#define GETTEXT_PACKAGE "${GETTEXT_PACKAGE}"
260
=== modified file 'gtk/gnome/CMakeLists.txt'
--- gtk/gnome/CMakeLists.txt 2011-10-13 14:06:05 +0000
+++ gtk/gnome/CMakeLists.txt 2012-02-08 18:50:27 +0000
@@ -9,5 +9,79 @@
9 DESTINATION ${COMPIZ_DESTDIR}${datadir}/applications9 DESTINATION ${COMPIZ_DESTDIR}${datadir}/applications
10 )10 )
1111
12<<<<<<< TREE
12 add_custom_target (compiz.desktop ALL SOURCES ${desktop_file})13 add_custom_target (compiz.desktop ALL SOURCES ${desktop_file})
13endif (BUILD_GNOME)14endif (BUILD_GNOME)
15=======
16 set (wmproperties_file ${CMAKE_CURRENT_BINARY_DIR}/compiz-wm.desktop)
17 compiz_translate_desktop_file (
18 ${CMAKE_CURRENT_SOURCE_DIR}/compiz-wm.desktop.in
19 ${wmproperties_file}
20 )
21 compiz_opt_install_file (
22 ${wmproperties_file}
23 ${windowsettingsdatadir}/gnome/wm-properties/compiz-wm.desktop
24 )
25
26
27 if (USE_GNOME_KEYBINDINGS)
28 compiz_translate_xml (
29 ${CMAKE_CURRENT_SOURCE_DIR}/50-compiz-desktop-key.xml.in
30 ${CMAKE_CURRENT_BINARY_DIR}/50-compiz-desktop-key.xml
31 )
32 compiz_translate_xml (
33 ${CMAKE_CURRENT_SOURCE_DIR}/50-compiz-key.xml.in
34 ${CMAKE_CURRENT_BINARY_DIR}/50-compiz-key.xml
35 )
36 set (key_xml
37 ${CMAKE_CURRENT_BINARY_DIR}/50-compiz-desktop-key.xml
38 ${CMAKE_CURRENT_BINARY_DIR}/50-compiz-key.xml
39 )
40 compiz_opt_install_file (
41 ${CMAKE_CURRENT_BINARY_DIR}/50-compiz-desktop-key.xml
42 ${keybindingsdir}/50-compiz-desktop-key.xml
43 )
44 compiz_opt_install_file (
45 ${CMAKE_CURRENT_BINARY_DIR}/50-compiz-key.xml
46 ${keybindingsdir}/50-compiz-key.xml
47 )
48 endif (USE_GNOME_KEYBINDINGS)
49
50 add_library (gnome-compiz MODULE
51 compiz-window-manager.c
52 compiz-window-manager.h
53 ${key_xml}
54 ${desktop_file}
55 ${wmproperties_file}
56 )
57
58
59 set_target_properties (gnome-compiz
60 PROPERTIES OUTPUT_NAME compiz
61 SKIP_BUILD_RPATH 1
62 )
63
64 target_link_libraries (
65 gnome-compiz ${GNOME_WINDOW_SETTINGS_LIBRARIES}
66 )
67
68 compiz_opt_install_file (
69 ${CMAKE_CURRENT_BINARY_DIR}/libcompiz.so
70 ${windowsettingslibdir}/window-manager-settings/libcompiz.so
71 )
72else (USE_GNOME)
73
74 set (desktop_file ${CMAKE_CURRENT_BINARY_DIR}/compiz.desktop)
75 compiz_translate_desktop_file (
76 ${CMAKE_CURRENT_SOURCE_DIR}/compiz.desktop.in
77 ${desktop_file}
78 )
79
80 install (
81 FILES ${desktop_file}
82 DESTINATION ${COMPIZ_DESTDIR}${datadir}/applications
83 )
84
85 add_custom_target (gnome-compiz ALL
86 DEPENDS ${desktop_file})
87endif (USE_GNOME)>>>>>>> MERGE-SOURCE
1488
=== modified file 'gtk/gnome/compiz.desktop.in'
--- gtk/gnome/compiz.desktop.in 2009-03-08 12:21:32 +0000
+++ gtk/gnome/compiz.desktop.in 2012-02-08 18:50:27 +0000
@@ -5,7 +5,7 @@
5Exec=compiz5Exec=compiz
6NoDisplay=true6NoDisplay=true
7# name of loadable control center module7# name of loadable control center module
8X-GNOME-WMSettingsModule=compiz8X-GNOME-WMSettingsModule=metacity
9# autostart phase9# autostart phase
10X-GNOME-Autostart-Phase=WindowManager10X-GNOME-Autostart-Phase=WindowManager
11X-GNOME-Provides=windowmanager11X-GNOME-Provides=windowmanager
1212
=== added file 'gtk/window-decorator/actionmenu.c'
--- gtk/window-decorator/actionmenu.c 1970-01-01 00:00:00 +0000
+++ gtk/window-decorator/actionmenu.c 2012-02-08 18:50:27 +0000
@@ -0,0 +1,134 @@
1/*
2 * Copyright © 2006 Novell, Inc.
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
18 *
19 * Author: David Reveman <davidr@novell.com>
20 */
21
22#include "gtk-window-decorator.h"
23
24static void
25action_menu_unmap (GObject *object)
26{
27 action_menu_mapped = FALSE;
28}
29
30static void
31position_action_menu (GtkMenu *menu,
32 gint *x,
33 gint *y,
34 gboolean *push_in,
35 gpointer user_data)
36{
37 WnckWindow *win = (WnckWindow *) user_data;
38 WnckWindowType win_type = wnck_window_get_window_type (win);
39 decor_frame_t *frame = gwd_get_decor_frame (win);
40 decor_t *d = g_object_get_data (G_OBJECT (win), "decor");
41 gint bx, by, width, height;
42
43 wnck_window_get_client_window_geometry (win, x, y, &width, &height);
44
45 if ((*theme_get_button_position) (d, BUTTON_MENU, width, height,
46 &bx, &by, &width, &height))
47 *x = *x - frame->win_extents.left + bx;
48
49 gwd_decor_frame_unref (frame);
50
51 if (gtk_widget_get_default_direction () == GTK_TEXT_DIR_RTL)
52 {
53 GtkRequisition req;
54
55 gtk_widget_size_request (GTK_WIDGET (menu), &req);
56 *x = MAX (0, *x - req.width + width);
57 }
58
59 *push_in = TRUE;
60}
61
62void
63action_menu_map (WnckWindow *win,
64 long button,
65 Time time)
66{
67 GdkDisplay *gdkdisplay;
68 GdkScreen *screen;
69
70 gdkdisplay = gdk_display_get_default ();
71 screen = gdk_display_get_default_screen (gdkdisplay);
72
73 if (action_menu)
74 {
75 if (action_menu_mapped)
76 {
77 gtk_widget_destroy (action_menu);
78 action_menu_mapped = FALSE;
79 action_menu = NULL;
80 return;
81 }
82 else
83 gtk_widget_destroy (action_menu);
84 }
85
86 switch (wnck_window_get_window_type (win)) {
87 case WNCK_WINDOW_DESKTOP:
88 case WNCK_WINDOW_DOCK:
89 /* don't allow window action */
90 return;
91 case WNCK_WINDOW_NORMAL:
92 case WNCK_WINDOW_DIALOG:
93
94#ifndef HAVE_LIBWNCK_2_19_4
95 case WNCK_WINDOW_MODAL_DIALOG:
96#endif
97
98 case WNCK_WINDOW_TOOLBAR:
99 case WNCK_WINDOW_MENU:
100 case WNCK_WINDOW_UTILITY:
101 case WNCK_WINDOW_SPLASHSCREEN:
102 /* allow window action menu */
103 break;
104 }
105
106 action_menu = wnck_create_window_action_menu (win);
107
108 gtk_menu_set_screen (GTK_MENU (action_menu), screen);
109
110 g_signal_connect_object (G_OBJECT (action_menu), "unmap",
111 G_CALLBACK (action_menu_unmap),
112 0, 0);
113
114 gtk_widget_show (action_menu);
115
116 if (!button || button == 1)
117 {
118 gtk_menu_popup (GTK_MENU (action_menu),
119 NULL, NULL,
120 position_action_menu, (gpointer) win,
121 button,
122 time);
123 }
124 else
125 {
126 gtk_menu_popup (GTK_MENU (action_menu),
127 NULL, NULL,
128 NULL, NULL,
129 button,
130 time);
131 }
132
133 action_menu_mapped = TRUE;
134}
0135
=== removed file 'gtk/window-decorator/actionmenu.c'
--- gtk/window-decorator/actionmenu.c 2011-05-07 08:58:10 +0000
+++ gtk/window-decorator/actionmenu.c 1970-01-01 00:00:00 +0000
@@ -1,133 +0,0 @@
1/*
2 * Copyright © 2006 Novell, Inc.
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
18 *
19 * Author: David Reveman <davidr@novell.com>
20 */
21
22#include "gtk-window-decorator.h"
23
24static void
25action_menu_unmap (GObject *object)
26{
27 action_menu_mapped = FALSE;
28}
29
30static void
31position_action_menu (GtkMenu *menu,
32 gint *x,
33 gint *y,
34 gboolean *push_in,
35 gpointer user_data)
36{
37 WnckWindow *win = (WnckWindow *) user_data;
38 decor_frame_t *frame = gwd_get_decor_frame (get_frame_type (win));
39 decor_t *d = g_object_get_data (G_OBJECT (win), "decor");
40 gint bx, by, width, height;
41
42 wnck_window_get_client_window_geometry (win, x, y, &width, &height);
43
44 if ((*theme_get_button_position) (d, BUTTON_MENU, width, height,
45 &bx, &by, &width, &height))
46 *x = *x - frame->win_extents.left + bx;
47
48 gwd_decor_frame_unref (frame);
49
50 if (gtk_widget_get_default_direction () == GTK_TEXT_DIR_RTL)
51 {
52 GtkRequisition req;
53
54 gtk_widget_size_request (GTK_WIDGET (menu), &req);
55 *x = MAX (0, *x - req.width + width);
56 }
57
58 *push_in = TRUE;
59}
60
61void
62action_menu_map (WnckWindow *win,
63 long button,
64 Time time)
65{
66 GdkDisplay *gdkdisplay;
67 GdkScreen *screen;
68
69 gdkdisplay = gdk_display_get_default ();
70 screen = gdk_display_get_default_screen (gdkdisplay);
71
72 if (action_menu)
73 {
74 if (action_menu_mapped)
75 {
76 gtk_widget_destroy (action_menu);
77 action_menu_mapped = FALSE;
78 action_menu = NULL;
79 return;
80 }
81 else
82 gtk_widget_destroy (action_menu);
83 }
84
85 switch (wnck_window_get_window_type (win)) {
86 case WNCK_WINDOW_DESKTOP:
87 case WNCK_WINDOW_DOCK:
88 /* don't allow window action */
89 return;
90 case WNCK_WINDOW_NORMAL:
91 case WNCK_WINDOW_DIALOG:
92
93#ifndef HAVE_LIBWNCK_2_19_4
94 case WNCK_WINDOW_MODAL_DIALOG:
95#endif
96
97 case WNCK_WINDOW_TOOLBAR:
98 case WNCK_WINDOW_MENU:
99 case WNCK_WINDOW_UTILITY:
100 case WNCK_WINDOW_SPLASHSCREEN:
101 /* allow window action menu */
102 break;
103 }
104
105 action_menu = wnck_create_window_action_menu (win);
106
107 gtk_menu_set_screen (GTK_MENU (action_menu), screen);
108
109 g_signal_connect_object (G_OBJECT (action_menu), "unmap",
110 G_CALLBACK (action_menu_unmap),
111 0, 0);
112
113 gtk_widget_show (action_menu);
114
115 if (!button || button == 1)
116 {
117 gtk_menu_popup (GTK_MENU (action_menu),
118 NULL, NULL,
119 position_action_menu, (gpointer) win,
120 button,
121 time);
122 }
123 else
124 {
125 gtk_menu_popup (GTK_MENU (action_menu),
126 NULL, NULL,
127 NULL, NULL,
128 button,
129 time);
130 }
131
132 action_menu_mapped = TRUE;
133}
1340
=== added file 'gtk/window-decorator/blurprops.c'
--- gtk/window-decorator/blurprops.c 1970-01-01 00:00:00 +0000
+++ gtk/window-decorator/blurprops.c 2012-02-08 18:50:27 +0000
@@ -0,0 +1,89 @@
1/*
2 * Copyright © 2006 Novell, Inc.
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
18 *
19 * Author: David Reveman <davidr@novell.com>
20 */
21
22#include "gtk-window-decorator.h"
23
24void
25decor_update_blur_property (decor_t *d,
26 int width,
27 int height,
28 Region top_region,
29 int top_offset,
30 Region bottom_region,
31 int bottom_offset,
32 Region left_region,
33 int left_offset,
34 Region right_region,
35 int right_offset)
36{
37 Display *xdisplay = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ());
38 long *data = NULL;
39 int size = 0;
40
41 if (settings->blur_type != BLUR_TYPE_ALL)
42 {
43 bottom_region = NULL;
44 left_region = NULL;
45 right_region = NULL;
46
47 if (settings->blur_type != BLUR_TYPE_TITLEBAR)
48 top_region = NULL;
49 }
50
51 if (top_region)
52 size += top_region->numRects;
53 if (bottom_region)
54 size += bottom_region->numRects;
55 if (left_region)
56 size += left_region->numRects;
57 if (right_region)
58 size += right_region->numRects;
59
60 if (size)
61 data = (long *) malloc (sizeof (long) * (2 + size * 6));
62
63 if (data)
64 {
65 decor_region_to_blur_property (data, 4, 0, width, height,
66 top_region, top_offset,
67 bottom_region, bottom_offset,
68 left_region, left_offset,
69 right_region, right_offset);
70
71 gdk_error_trap_push ();
72 XChangeProperty (xdisplay, d->prop_xid,
73 win_blur_decor_atom,
74 XA_INTEGER,
75 32, PropModeReplace, (guchar *) data,
76 2 + size * 6);
77 gdk_display_sync (gdk_display_get_default ());
78 gdk_error_trap_pop ();
79
80 free (data);
81 }
82 else
83 {
84 gdk_error_trap_push ();
85 XDeleteProperty (xdisplay, d->prop_xid, win_blur_decor_atom);
86 gdk_display_sync (gdk_display_get_default ());
87 gdk_error_trap_pop ();
88 }
89}
090
=== removed file 'gtk/window-decorator/blurprops.c'
--- gtk/window-decorator/blurprops.c 2011-02-21 09:53:08 +0000
+++ gtk/window-decorator/blurprops.c 1970-01-01 00:00:00 +0000
@@ -1,89 +0,0 @@
1/*
2 * Copyright © 2006 Novell, Inc.
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
18 *
19 * Author: David Reveman <davidr@novell.com>
20 */
21
22#include "gtk-window-decorator.h"
23
24void
25decor_update_blur_property (decor_t *d,
26 int width,
27 int height,
28 Region top_region,
29 int top_offset,
30 Region bottom_region,
31 int bottom_offset,
32 Region left_region,
33 int left_offset,
34 Region right_region,
35 int right_offset)
36{
37 Display *xdisplay = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ());
38 long *data = NULL;
39 int size = 0;
40
41 if (settings->blur_type != BLUR_TYPE_ALL)
42 {
43 bottom_region = NULL;
44 left_region = NULL;
45 right_region = NULL;
46
47 if (settings->blur_type != BLUR_TYPE_TITLEBAR)
48 top_region = NULL;
49 }
50
51 if (top_region)
52 size += top_region->numRects;
53 if (bottom_region)
54 size += bottom_region->numRects;
55 if (left_region)
56 size += left_region->numRects;
57 if (right_region)
58 size += right_region->numRects;
59
60 if (size)
61 data = (long *) malloc (sizeof (long) * (2 + size * 6));
62
63 if (data)
64 {
65 decor_region_to_blur_property (data, 4, 0, width, height,
66 top_region, top_offset,
67 bottom_region, bottom_offset,
68 left_region, left_offset,
69 right_region, right_offset);
70
71 gdk_error_trap_push ();
72 XChangeProperty (xdisplay, d->prop_xid,
73 win_blur_decor_atom,
74 XA_INTEGER,
75 32, PropModeReplace, (guchar *) data,
76 2 + size * 6);
77 gdk_display_sync (gdk_display_get_default ());
78 gdk_error_trap_pop ();
79
80 free (data);
81 }
82 else
83 {
84 gdk_error_trap_push ();
85 XDeleteProperty (xdisplay, d->prop_xid, win_blur_decor_atom);
86 gdk_display_sync (gdk_display_get_default ());
87 gdk_error_trap_pop ();
88 }
89}
900
=== added file 'gtk/window-decorator/cairo.c'
--- gtk/window-decorator/cairo.c 1970-01-01 00:00:00 +0000
+++ gtk/window-decorator/cairo.c 2012-02-08 18:50:27 +0000
@@ -0,0 +1,915 @@
1/*
2 * Copyright © 2006 Novell, Inc.
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
18 *
19 * Author: David Reveman <davidr@novell.com>
20 *
21 * 2D Mode: Copyright © 2010 Sam Spilsbury <smspillaz@gmail.com>
22 * Frames Management: Copright © 2011 Canonical Ltd.
23 * Authored By: Sam Spilsbury <sam.spilsbury@canonical.com>
24 */
25
26#include "gtk-window-decorator.h"
27
28void
29rounded_rectangle (cairo_t *cr,
30 double x,
31 double y,
32 double w,
33 double h,
34 double radius,
35 int corner)
36{
37 if (corner & CORNER_TOPLEFT)
38 cairo_move_to (cr, x + radius, y);
39 else
40 cairo_move_to (cr, x, y);
41
42 if (corner & CORNER_TOPRIGHT)
43 cairo_arc (cr, x + w - radius, y + radius, radius,
44 M_PI * 1.5, M_PI * 2.0);
45 else
46 cairo_line_to (cr, x + w, y);
47
48 if (corner & CORNER_BOTTOMRIGHT)
49 cairo_arc (cr, x + w - radius, y + h - radius, radius,
50 0.0, M_PI * 0.5);
51 else
52 cairo_line_to (cr, x + w, y + h);
53
54 if (corner & CORNER_BOTTOMLEFT)
55 cairo_arc (cr, x + radius, y + h - radius, radius,
56 M_PI * 0.5, M_PI);
57 else
58 cairo_line_to (cr, x, y + h);
59
60 if (corner & CORNER_TOPLEFT)
61 cairo_arc (cr, x + radius, y + radius, radius, M_PI, M_PI * 1.5);
62 else
63 cairo_line_to (cr, x, y);
64}
65
66void
67fill_rounded_rectangle (cairo_t *cr,
68 double x,
69 double y,
70 double w,
71 double h,
72 double radius,
73 int corner,
74 decor_color_t *c0,
75 double alpha0,
76 decor_color_t *c1,
77 double alpha1,
78 int gravity)
79{
80 cairo_pattern_t *pattern;
81
82 rounded_rectangle (cr, x, y, w, h, radius, corner);
83
84 if (gravity & SHADE_RIGHT)
85 {
86 x = x + w;
87 w = -w;
88 }
89 else if (!(gravity & SHADE_LEFT))
90 {
91 x = w = 0;
92 }
93
94 if (gravity & SHADE_BOTTOM)
95 {
96 y = y + h;
97 h = -h;
98 }
99 else if (!(gravity & SHADE_TOP))
100 {
101 y = h = 0;
102 }
103
104 if (w && h)
105 {
106 cairo_matrix_t matrix;
107
108 pattern = cairo_pattern_create_radial (0.0, 0.0, 0.0, 0.0, 0.0, w);
109
110 cairo_matrix_init_scale (&matrix, 1.0, w / h);
111 cairo_matrix_translate (&matrix, -(x + w), -(y + h));
112
113 cairo_pattern_set_matrix (pattern, &matrix);
114 }
115 else
116 {
117 pattern = cairo_pattern_create_linear (x + w, y + h, x, y);
118 }
119
120 cairo_pattern_add_color_stop_rgba (pattern, 0.0, c0->r, c0->g, c0->b,
121 alpha0);
122
123 cairo_pattern_add_color_stop_rgba (pattern, 1.0, c1->r, c1->g, c1->b,
124 alpha1);
125
126 cairo_pattern_set_extend (pattern, CAIRO_EXTEND_PAD);
127
128 cairo_set_source (cr, pattern);
129 cairo_fill (cr);
130 cairo_pattern_destroy (pattern);
131}
132
133void
134draw_shadow_background (decor_t *d,
135 cairo_t *cr,
136 decor_shadow_t *s,
137 decor_context_t *c)
138{
139 Display *xdisplay = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ());
140
141 if (!s || !s->picture ||!d->picture)
142 {
143 cairo_set_source_rgba (cr, 0.0, 0.0, 0.0, 0.0);
144 cairo_paint (cr);
145 }
146 else
147 {
148 decor_fill_picture_extents_with_shadow (xdisplay,
149 s, c,
150 d->picture,
151 &d->border_layout);
152 }
153}
154
155static void
156draw_close_button (decor_t *d,
157 cairo_t *cr,
158 double s)
159{
160 cairo_rel_move_to (cr, 0.0, s);
161
162 cairo_rel_line_to (cr, s, -s);
163 cairo_rel_line_to (cr, s, s);
164 cairo_rel_line_to (cr, s, -s);
165 cairo_rel_line_to (cr, s, s);
166
167 cairo_rel_line_to (cr, -s, s);
168 cairo_rel_line_to (cr, s, s);
169 cairo_rel_line_to (cr, -s, s);
170 cairo_rel_line_to (cr, -s, -s);
171
172 cairo_rel_line_to (cr, -s, s);
173 cairo_rel_line_to (cr, -s, -s);
174 cairo_rel_line_to (cr, s, -s);
175
176 cairo_close_path (cr);
177}
178
179static void
180draw_max_button (decor_t *d,
181 cairo_t *cr,
182 double s)
183{
184 cairo_rel_line_to (cr, 12.0, 0.0);
185 cairo_rel_line_to (cr, 0.0, 12.0);
186 cairo_rel_line_to (cr, -12.0, 0.0);
187
188 cairo_close_path (cr);
189
190 cairo_rel_move_to (cr, 2.0, s);
191
192 cairo_rel_line_to (cr, 12.0 - 4.0, 0.0);
193 cairo_rel_line_to (cr, 0.0, 12.0 - s - 2.0);
194 cairo_rel_line_to (cr, -(12.0 - 4.0), 0.0);
195
196 cairo_close_path (cr);
197}
198
199static void
200draw_unmax_button (decor_t *d,
201 cairo_t *cr,
202 double s)
203{
204 cairo_rel_move_to (cr, 1.0, 1.0);
205
206 cairo_rel_line_to (cr, 10.0, 0.0);
207 cairo_rel_line_to (cr, 0.0, 10.0);
208 cairo_rel_line_to (cr, -10.0, 0.0);
209
210 cairo_close_path (cr);
211
212 cairo_rel_move_to (cr, 2.0, s);
213
214 cairo_rel_line_to (cr, 10.0 - 4.0, 0.0);
215 cairo_rel_line_to (cr, 0.0, 10.0 - s - 2.0);
216 cairo_rel_line_to (cr, -(10.0 - 4.0), 0.0);
217
218 cairo_close_path (cr);
219}
220
221static void
222draw_min_button (decor_t *d,
223 cairo_t *cr,
224 double s)
225{
226 cairo_rel_move_to (cr, 0.0, 8.0);
227
228 cairo_rel_line_to (cr, 12.0, 0.0);
229 cairo_rel_line_to (cr, 0.0, s);
230 cairo_rel_line_to (cr, -12.0, 0.0);
231
232 cairo_close_path (cr);
233}
234
235typedef void (*draw_proc) (cairo_t *cr);
236
237static void
238button_state_offsets (gdouble x,
239 gdouble y,
240 guint state,
241 gdouble *return_x,
242 gdouble *return_y)
243{
244 static double off[] = { 0.0, 0.0, 0.0, 0.5 };
245
246 *return_x = x + off[state];
247 *return_y = y + off[state];
248}
249
250static void
251button_state_paint (cairo_t *cr,
252 GtkStyle *style,
253 decor_color_t *color,
254 guint state)
255{
256
257#define IN_STATE (PRESSED_EVENT_WINDOW | IN_EVENT_WINDOW)
258
259 if ((state & IN_STATE) == IN_STATE)
260 {
261 if (state & IN_EVENT_WINDOW)
262 cairo_set_source_rgb (cr, 1.0, 1.0, 1.0);
263 else
264 cairo_set_source_rgba (cr, color->r, color->g, color->b, 0.95);
265
266 cairo_fill_preserve (cr);
267
268 gdk_cairo_set_source_color_alpha (cr,
269 &style->fg[GTK_STATE_NORMAL],
270 STROKE_ALPHA);
271
272 cairo_set_line_width (cr, 1.0);
273 cairo_stroke (cr);
274 cairo_set_line_width (cr, 2.0);
275 }
276 else
277 {
278 gdk_cairo_set_source_color_alpha (cr,
279 &style->fg[GTK_STATE_NORMAL],
280 STROKE_ALPHA);
281 cairo_stroke_preserve (cr);
282
283 if (state & IN_EVENT_WINDOW)
284 cairo_set_source_rgb (cr, 1.0, 1.0, 1.0);
285 else
286 cairo_set_source_rgba (cr, color->r, color->g, color->b, 0.95);
287
288 cairo_fill (cr);
289 }
290}
291
292void
293draw_window_decoration (decor_t *d)
294{
295 cairo_t *cr;
296 GtkStyle *style;
297 GdkDrawable *drawable;
298 decor_color_t color;
299 double alpha;
300 double x1, y1, x2, y2, x, y, h;
301 int corners = SHADE_LEFT | SHADE_RIGHT | SHADE_TOP | SHADE_BOTTOM;
302 int top;
303 int button_x;
304
305 if (!d->pixmap)
306 return;
307
308
309 style = gtk_widget_get_style (d->frame->style_window_rgba);
310
311 if (d->state & (WNCK_WINDOW_STATE_MAXIMIZED_HORIZONTALLY |
312 WNCK_WINDOW_STATE_MAXIMIZED_VERTICALLY))
313 corners = 0;
314
315 color.r = style->bg[GTK_STATE_NORMAL].red / 65535.0;
316 color.g = style->bg[GTK_STATE_NORMAL].green / 65535.0;
317 color.b = style->bg[GTK_STATE_NORMAL].blue / 65535.0;
318
319 if (d->frame_window)
320 {
321 GdkColormap *cmap;
322
323 cmap = get_colormap_for_drawable (GDK_DRAWABLE (d->pixmap));
324 gdk_drawable_set_colormap (GDK_DRAWABLE (d->pixmap), cmap);
325 gdk_drawable_set_colormap (GDK_DRAWABLE (d->buffer_pixmap), cmap);
326 drawable = GDK_DRAWABLE (d->buffer_pixmap);
327 }
328 else if (d->buffer_pixmap)
329 drawable = GDK_DRAWABLE (d->buffer_pixmap);
330 else
331 drawable = GDK_DRAWABLE (d->pixmap);
332
333 cr = gdk_cairo_create (GDK_DRAWABLE (drawable));
334 if (!cr)
335 return;
336
337 cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
338
339 top = d->frame->win_extents.top + d->frame->titlebar_height;
340
341 x1 = d->context->left_space - d->frame->win_extents.left;
342 y1 = d->context->top_space - d->frame->win_extents.top - d->frame->titlebar_height;
343 x2 = d->width - d->context->right_space + d->frame->win_extents.right;
344 y2 = d->height - d->context->bottom_space + d->frame->win_extents.bottom;
345
346 h = d->height - d->context->top_space - d->context->bottom_space;
347
348 cairo_set_line_width (cr, 1.0);
349
350 if (!d->frame_window)
351 draw_shadow_background (d, cr, d->shadow, d->context);
352
353 if (d->active)
354 {
355 decor_color_t *title_color = _title_color;
356
357 alpha = settings->decoration_alpha + 0.3;
358
359 fill_rounded_rectangle (cr,
360 x1 + 0.5,
361 y1 + 0.5,
362 d->frame->win_extents.left - 0.5,
363 top - 0.5,
364 5.0, CORNER_TOPLEFT & corners,
365 &title_color[0], 1.0, &title_color[1], alpha,
366 SHADE_TOP | SHADE_LEFT);
367
368 fill_rounded_rectangle (cr,
369 x1 + d->frame->win_extents.left,
370 y1 + 0.5,
371 x2 - x1 - d->frame->win_extents.left -
372 d->frame->win_extents.right,
373 top - 0.5,
374 5.0, 0,
375 &title_color[0], 1.0, &title_color[1], alpha,
376 SHADE_TOP);
377
378 fill_rounded_rectangle (cr,
379 x2 - d->frame->win_extents.right,
380 y1 + 0.5,
381 d->frame->win_extents.right - 0.5,
382 top - 0.5,
383 5.0, CORNER_TOPRIGHT & corners,
384 &title_color[0], 1.0, &title_color[1], alpha,
385 SHADE_TOP | SHADE_RIGHT);
386 }
387 else
388 {
389 alpha = settings->decoration_alpha;
390
391 fill_rounded_rectangle (cr,
392 x1 + 0.5,
393 y1 + 0.5,
394 d->frame->win_extents.left - 0.5,
395 top - 0.5,
396 5.0, CORNER_TOPLEFT & corners,
397 &color, 1.0, &color, alpha,
398 SHADE_TOP | SHADE_LEFT);
399
400 fill_rounded_rectangle (cr,
401 x1 + d->frame->win_extents.left,
402 y1 + 0.5,
403 x2 - x1 - d->frame->win_extents.left -
404 d->frame->win_extents.right,
405 top - 0.5,
406 5.0, 0,
407 &color, 1.0, &color, alpha,
408 SHADE_TOP);
409
410 fill_rounded_rectangle (cr,
411 x2 - d->frame->win_extents.right,
412 y1 + 0.5,
413 d->frame->win_extents.right - 0.5,
414 top - 0.5,
415 5.0, CORNER_TOPRIGHT & corners,
416 &color, 1.0, &color, alpha,
417 SHADE_TOP | SHADE_RIGHT);
418 }
419
420 fill_rounded_rectangle (cr,
421 x1 + 0.5,
422 y1 + top,
423 d->frame->win_extents.left - 0.5,
424 h,
425 5.0, 0,
426 &color, 1.0, &color, alpha,
427 SHADE_LEFT);
428
429 fill_rounded_rectangle (cr,
430 x2 - d->frame->win_extents.right,
431 y1 + top,
432 d->frame->win_extents.right - 0.5,
433 h,
434 5.0, 0,
435 &color, 1.0, &color, alpha,
436 SHADE_RIGHT);
437
438
439 fill_rounded_rectangle (cr,
440 x1 + 0.5,
441 y2 - d->frame->win_extents.bottom,
442 d->frame->win_extents.left - 0.5,
443 d->frame->win_extents.bottom - 0.5,
444 5.0, CORNER_BOTTOMLEFT & corners,
445 &color, 1.0, &color, alpha,
446 SHADE_BOTTOM | SHADE_LEFT);
447
448 fill_rounded_rectangle (cr,
449 x1 + d->frame->win_extents.left,
450 y2 - d->frame->win_extents.bottom,
451 x2 - x1 - d->frame->win_extents.left -
452 d->frame->win_extents.right,
453 d->frame->win_extents.bottom - 0.5,
454 5.0, 0,
455 &color, 1.0, &color, alpha,
456 SHADE_BOTTOM);
457
458 fill_rounded_rectangle (cr,
459 x2 - d->frame->win_extents.right,
460 y2 - d->frame->win_extents.bottom,
461 d->frame->win_extents.right - 0.5,
462 d->frame->win_extents.bottom - 0.5,
463 5.0, CORNER_BOTTOMRIGHT & corners,
464 &color, 1.0, &color, alpha,
465 SHADE_BOTTOM | SHADE_RIGHT);
466
467 cairo_rectangle (cr,
468 d->context->left_space,
469 d->context->top_space,
470 d->width - d->context->left_space -
471 d->context->right_space,
472 h);
473 gdk_cairo_set_source_color (cr, &style->bg[GTK_STATE_NORMAL]);
474 cairo_fill (cr);
475
476 cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
477
478 if (d->active)
479 {
480 gdk_cairo_set_source_color_alpha (cr,
481 &style->fg[GTK_STATE_NORMAL],
482 0.7);
483
484 cairo_move_to (cr, x1 + 0.5, y1 + top - 0.5);
485 cairo_rel_line_to (cr, x2 - x1 - 1.0, 0.0);
486
487 cairo_stroke (cr);
488 }
489
490 rounded_rectangle (cr,
491 x1 + 0.5, y1 + 0.5,
492 x2 - x1 - 1.0, y2 - y1 - 1.0,
493 5.0,
494 (CORNER_TOPLEFT | CORNER_TOPRIGHT | CORNER_BOTTOMLEFT |
495 CORNER_BOTTOMRIGHT) & corners);
496
497 cairo_clip (cr);
498
499 cairo_translate (cr, 1.0, 1.0);
500
501 rounded_rectangle (cr,
502 x1 + 0.5, y1 + 0.5,
503 x2 - x1 - 1.0, y2 - y1 - 1.0,
504 5.0,
505 (CORNER_TOPLEFT | CORNER_TOPRIGHT | CORNER_BOTTOMLEFT |
506 CORNER_BOTTOMRIGHT) & corners);
507
508 cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, 0.4);
509
510 cairo_stroke (cr);
511
512 cairo_translate (cr, -2.0, -2.0);
513
514 rounded_rectangle (cr,
515 x1 + 0.5, y1 + 0.5,
516 x2 - x1 - 1.0, y2 - y1 - 1.0,
517 5.0,
518 (CORNER_TOPLEFT | CORNER_TOPRIGHT | CORNER_BOTTOMLEFT |
519 CORNER_BOTTOMRIGHT) & corners);
520
521 cairo_set_source_rgba (cr, 0.0, 0.0, 0.0, 0.1);
522
523 cairo_stroke (cr);
524
525 cairo_translate (cr, 1.0, 1.0);
526
527 cairo_reset_clip (cr);
528
529 rounded_rectangle (cr,
530 x1 + 0.5, y1 + 0.5,
531 x2 - x1 - 1.0, y2 - y1 - 1.0,
532 5.0,
533 (CORNER_TOPLEFT | CORNER_TOPRIGHT | CORNER_BOTTOMLEFT |
534 CORNER_BOTTOMRIGHT) & corners);
535
536 gdk_cairo_set_source_color_alpha (cr,
537 &style->fg[GTK_STATE_NORMAL],
538 alpha);
539
540 cairo_stroke (cr);
541
542 cairo_set_line_width (cr, 2.0);
543
544 button_x = d->width - d->context->right_space - 13;
545
546 if (d->actions & WNCK_WINDOW_ACTION_CLOSE)
547 {
548 button_state_offsets (button_x,
549 y1 - 3.0 + d->frame->titlebar_height / 2,
550 d->button_states[BUTTON_CLOSE], &x, &y);
551
552 button_x -= 17;
553
554 if (d->active)
555 {
556 cairo_move_to (cr, x, y);
557 draw_close_button (d, cr, 3.0);
558 button_state_paint (cr, style, &color,
559 d->button_states[BUTTON_CLOSE]);
560 }
561 else
562 {
563 gdk_cairo_set_source_color_alpha (cr,
564 &style->fg[GTK_STATE_NORMAL],
565 alpha * 0.75);
566
567 cairo_move_to (cr, x, y);
568 draw_close_button (d, cr, 3.0);
569 cairo_fill (cr);
570 }
571 }
572
573 if (d->actions & WNCK_WINDOW_ACTION_MAXIMIZE)
574 {
575 button_state_offsets (button_x,
576 y1 - 3.0 + d->frame->titlebar_height / 2,
577 d->button_states[BUTTON_MAX], &x, &y);
578
579 button_x -= 17;
580
581 cairo_set_fill_rule (cr, CAIRO_FILL_RULE_EVEN_ODD);
582
583 if (d->active)
584 {
585 gdk_cairo_set_source_color_alpha (cr,
586 &style->fg[GTK_STATE_NORMAL],
587 STROKE_ALPHA);
588
589 cairo_move_to (cr, x, y);
590
591 if (d->state & (WNCK_WINDOW_STATE_MAXIMIZED_HORIZONTALLY |
592 WNCK_WINDOW_STATE_MAXIMIZED_VERTICALLY))
593 draw_unmax_button (d, cr, 4.0);
594 else
595 draw_max_button (d, cr, 4.0);
596
597 button_state_paint (cr, style, &color,
598 d->button_states[BUTTON_MAX]);
599 }
600 else
601 {
602 gdk_cairo_set_source_color_alpha (cr,
603 &style->fg[GTK_STATE_NORMAL],
604 alpha * 0.75);
605
606 cairo_move_to (cr, x, y);
607
608 if (d->state & (WNCK_WINDOW_STATE_MAXIMIZED_HORIZONTALLY |
609 WNCK_WINDOW_STATE_MAXIMIZED_VERTICALLY))
610 draw_unmax_button (d, cr, 4.0);
611 else
612 draw_max_button (d, cr, 4.0);
613
614 cairo_fill (cr);
615 }
616 }
617
618 if (d->actions & WNCK_WINDOW_ACTION_MINIMIZE)
619 {
620 button_state_offsets (button_x,
621 y1 - 3.0 + d->frame->titlebar_height / 2,
622 d->button_states[BUTTON_MIN], &x, &y);
623
624 button_x -= 17;
625
626 if (d->active)
627 {
628 gdk_cairo_set_source_color_alpha (cr,
629 &style->fg[GTK_STATE_NORMAL],
630 STROKE_ALPHA);
631
632
633 cairo_move_to (cr, x, y);
634 draw_min_button (d, cr, 4.0);
635 button_state_paint (cr, style, &color,
636 d->button_states[BUTTON_MIN]);
637 }
638 else
639 {
640 gdk_cairo_set_source_color_alpha (cr,
641 &style->fg[GTK_STATE_NORMAL],
642 alpha * 0.75);
643
644 cairo_move_to (cr, x, y);
645 draw_min_button (d, cr, 4.0);
646 cairo_fill (cr);
647 }
648 }
649
650 if (d->layout)
651 {
652 if (d->active)
653 {
654 cairo_move_to (cr,
655 d->context->left_space + 21.0,
656 y1 + 2.0 + (d->frame->titlebar_height - d->frame->text_height) / 2.0);
657
658 gdk_cairo_set_source_color_alpha (cr,
659 &style->fg[GTK_STATE_NORMAL],
660 STROKE_ALPHA);
661
662 pango_cairo_layout_path (cr, d->layout);
663 cairo_stroke (cr);
664
665 cairo_set_source_rgb (cr, 1.0, 1.0, 1.0);
666 }
667 else
668 {
669 gdk_cairo_set_source_color_alpha (cr,
670 &style->fg[GTK_STATE_NORMAL],
671 alpha);
672 }
673
674 cairo_move_to (cr,
675 d->context->left_space + 21.0,
676 y1 + 2.0 + (d->frame->titlebar_height - d->frame->text_height) / 2.0);
677
678 pango_cairo_show_layout (cr, d->layout);
679 }
680
681 if (d->icon)
682 {
683 cairo_translate (cr, d->context->left_space + 1,
684 y1 - 5.0 + d->frame->titlebar_height / 2);
685 cairo_set_source (cr, d->icon);
686 cairo_rectangle (cr, 0.0, 0.0, 16.0, 16.0);
687 cairo_clip (cr);
688
689 if (d->active)
690 cairo_paint (cr);
691 else
692 cairo_paint_with_alpha (cr, alpha);
693 }
694
695 cairo_destroy (cr);
696
697 copy_to_front_buffer (d);
698
699 if (d->frame_window)
700 {
701 GdkWindow *gdk_frame_window = gtk_widget_get_window (d->decor_window);
702
703 gtk_image_set_from_pixmap (GTK_IMAGE (d->decor_image), d->pixmap, NULL);
704 gtk_window_resize (GTK_WINDOW (d->decor_window), d->width, d->height);
705 gdk_window_move (gdk_frame_window, 0, 0);
706 gdk_window_lower (gdk_frame_window);
707 }
708
709 if (d->prop_xid)
710 {
711 decor_update_window_property (d);
712 d->prop_xid = 0;
713 }
714}
715
716static void
717calc_button_size (decor_t *d)
718{
719 gint button_width;
720
721 button_width = 0;
722
723 if (d->actions & WNCK_WINDOW_ACTION_CLOSE)
724 button_width += 17;
725
726 if (d->actions & (WNCK_WINDOW_ACTION_MAXIMIZE_HORIZONTALLY |
727 WNCK_WINDOW_ACTION_MAXIMIZE_VERTICALLY |
728 WNCK_WINDOW_ACTION_UNMAXIMIZE_HORIZONTALLY |
729 WNCK_WINDOW_ACTION_UNMAXIMIZE_VERTICALLY))
730 button_width += 17;
731
732 if (d->actions & (WNCK_WINDOW_ACTION_MINIMIZE |
733 WNCK_WINDOW_ACTION_MINIMIZE))
734 button_width += 17;
735
736 if (button_width)
737 button_width++;
738
739 d->button_width = button_width;
740}
741
742gboolean
743calc_decoration_size (decor_t *d,
744 gint w,
745 gint h,
746 gint name_width,
747 gint *width,
748 gint *height)
749{
750 decor_layout_t layout;
751 int top_width;
752
753 /* To avoid wasting texture memory, we only calculate the minimal
754 * required decoration size then clip and stretch the texture where
755 * appropriate
756 */
757
758 if (!d->frame_window)
759 {
760 calc_button_size (d);
761
762 if (w < ICON_SPACE + d->button_width)
763 return FALSE;
764
765 top_width = name_width + d->button_width + ICON_SPACE;
766 if (w < top_width)
767 top_width = MAX (ICON_SPACE + d->button_width, w);
768
769 decor_get_default_layout (&d->frame->window_context, top_width, 1, &layout);
770
771 if (!d->context || memcmp (&layout, &d->border_layout, sizeof (layout)))
772 {
773 *width = layout.width;
774 *height = layout.height;
775
776 d->border_layout = layout;
777 d->context = &d->frame->window_context;
778 d->shadow = d->frame->border_shadow;
779
780 return TRUE;
781 }
782 }
783 else
784 {
785 calc_button_size (d);
786
787 /* _default_win_extents + top height */
788
789 top_width = name_width + d->button_width + ICON_SPACE;
790 if (w < top_width)
791 top_width = MAX (ICON_SPACE + d->button_width, w);
792
793 decor_get_default_layout (&d->frame->window_context_no_shadow,
794 d->client_width, d->client_height, &layout);
795
796 *width = layout.width;
797 *height = layout.height;
798
799 d->border_layout = layout;
800 d->context = &d->frame->window_context_no_shadow;
801 d->shadow = d->frame->border_no_shadow;
802
803 return TRUE;
804 }
805
806 return FALSE;
807}
808
809gboolean
810get_button_position (decor_t *d,
811 gint i,
812 gint width,
813 gint height,
814 gint *x,
815 gint *y,
816 gint *w,
817 gint *h)
818{
819 if (i > BUTTON_MENU)
820 return FALSE;
821
822 if (d->frame_window)
823 {
824 *x = bpos[i].x + bpos[i].xw * width + d->frame->win_extents.left + 4;
825 *y = bpos[i].y + bpos[i].yh * height + bpos[i].yth *
826 (d->frame->titlebar_height - 17) + d->frame->win_extents.top + 2;
827 }
828 else
829 {
830 *x = bpos[i].x + bpos[i].xw * width;
831 *y = bpos[i].y + bpos[i].yh * height + bpos[i].yth *
832 (d->frame->titlebar_height - 17);
833 }
834
835 *w = bpos[i].w + bpos[i].ww * width;
836 *h = bpos[i].h + bpos[i].hh * height + bpos[i].hth +
837 (d->frame->titlebar_height - 17);
838
839 /* hack to position multiple buttons on the right */
840 if (i != BUTTON_MENU)
841 *x -= 10 + 16 * i;
842
843 return TRUE;
844}
845
846void
847get_event_window_position (decor_t *d,
848 gint i,
849 gint j,
850 gint width,
851 gint height,
852 gint *x,
853 gint *y,
854 gint *w,
855 gint *h)
856{
857 if (d->frame_window)
858 {
859 *x = pos[i][j].x + pos[i][j].xw * width + d->frame->win_extents.left;
860 *y = pos[i][j].y + d->frame->win_extents.top +
861 pos[i][j].yh * height + pos[i][j].yth * (d->frame->titlebar_height - 17);
862
863 if (i == 0 && (j == 0 || j == 2))
864 *y -= d->frame->titlebar_height;
865 }
866 else
867 {
868 *x = pos[i][j].x + pos[i][j].xw * width;
869 *y = pos[i][j].y +
870 pos[i][j].yh * height + pos[i][j].yth * (d->frame->titlebar_height - 17);
871 }
872
873 if ((d->state & WNCK_WINDOW_STATE_MAXIMIZED_HORIZONTALLY) &&
874 (j == 0 || j == 2))
875 {
876 *w = 0;
877 }
878 else
879 {
880 *w = pos[i][j].w + pos[i][j].ww * width;
881 }
882
883 if ((d->state & WNCK_WINDOW_STATE_MAXIMIZED_VERTICALLY) &&
884 (i == 0 || i == 2))
885 {
886 *h = 0;
887 }
888 else
889 {
890 *h = pos[i][j].h +
891 pos[i][j].hh * height + pos[i][j].hth * (d->frame->titlebar_height - 17);
892 }
893}
894
895gfloat
896get_title_scale (decor_frame_t *frame)
897{
898 return 1.0f;
899}
900
901void
902update_border_extents (decor_frame_t *frame)
903{
904 decor_frame_t *default_frame = gwd_get_decor_frame ("default");
905
906 frame = gwd_decor_frame_ref (frame);
907
908 frame->win_extents = default_frame->win_extents;
909 frame->max_win_extents = default_frame->win_extents;
910 frame->titlebar_height = frame->max_titlebar_height =
911 (frame->text_height < 17) ? 17 : frame->text_height;
912
913 gwd_decor_frame_unref (frame);
914 gwd_decor_frame_unref (default_frame);
915}
0916
=== renamed file 'gtk/window-decorator/cairo.c' => 'gtk/window-decorator/cairo.c.THIS'
=== added file 'gtk/window-decorator/decorator.c'
--- gtk/window-decorator/decorator.c 1970-01-01 00:00:00 +0000
+++ gtk/window-decorator/decorator.c 2012-02-08 18:50:27 +0000
@@ -0,0 +1,1301 @@
1/*
2 * Copyright © 2006 Novell, Inc.
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
18 *
19 * Author: David Reveman <davidr@novell.com>
20 *
21 * 2D Mode: Copyright © 2010 Sam Spilsbury <smspillaz@gmail.com>
22 * Frames Management: Copright © 2011 Canonical Ltd.
23 * Authored By: Sam Spilsbury <sam.spilsbury@canonical.com>
24 */
25
26#include "gtk-window-decorator.h"
27
28decor_frame_t *
29create_normal_frame (const gchar *type)
30{
31 decor_frame_t *frame = decor_frame_new (type);
32
33 decor_context_t _window_context = {
34 { 0, 0, 0, 0 },
35 6, 6, 4, 6,
36 0, 0, 0, 0
37 };
38
39 decor_context_t _max_window_context = {
40 { 0, 0, 0, 0 },
41 6, 6, 4, 6,
42 0, 0, 0, 0
43 };
44
45 decor_context_t _window_context_no_shadow = {
46 { 0, 0, 0, 0 },
47 6, 6, 4, 6,
48 0, 0, 0, 0
49 };
50
51 decor_context_t _max_window_context_no_shadow = {
52 { 0, 0, 0, 0 },
53 6, 6, 4, 6,
54 0, 0, 0, 0
55 };
56
57 decor_extents_t _win_extents = { 6, 6, 6, 6 };
58 decor_extents_t _max_win_extents = { 6, 6, 4, 6 };
59
60 frame->win_extents = _win_extents;
61 frame->max_win_extents = _max_win_extents;
62 frame->update_shadow = decor_frame_update_shadow;
63 frame->window_context = _window_context;
64 frame->window_context_no_shadow = _window_context_no_shadow;
65 frame->max_window_context = _max_window_context;
66 frame->max_window_context_no_shadow = _max_window_context_no_shadow;
67
68 return frame;
69}
70
71void
72destroy_normal_frame (decor_frame_t *frame)
73{
74 decor_frame_destroy (frame);
75}
76
77decor_frame_t *
78create_bare_frame (const gchar *type)
79{
80 decor_frame_t *frame = decor_frame_new (type);
81 decor_context_t _shadow_context = {
82 { 0, 0, 0, 0 },
83 0, 0, 0, 0,
84 0, 0, 0, 0,
85 };
86
87 decor_extents_t _shadow_extents = { 0, 0, 0, 0 };
88
89 frame->win_extents = _shadow_extents;
90 frame->max_win_extents = _shadow_extents;
91 frame->win_extents = _shadow_extents;
92 frame->window_context = _shadow_context;
93 frame->window_context_no_shadow = _shadow_context;
94 frame->max_window_context = _shadow_context;
95 frame->max_window_context_no_shadow = _shadow_context;
96 frame->update_shadow = bare_frame_update_shadow;
97
98 return frame;
99}
100
101void
102destroy_bare_frame (decor_frame_t *frame)
103{
104 decor_frame_destroy (frame);
105}
106
107
108/*
109 * get_titlebar_font
110 *
111 * Returns: PangoFontDescription * or NULL if using system font
112 * Description: Helper function to get the font for the titlebar
113 */
114static const PangoFontDescription *
115get_titlebar_font (decor_frame_t *frame)
116{
117 if (settings->use_system_font)
118 return NULL;
119 else
120 return frame->titlebar_font;
121}
122
123/*
124 * frame_update_titlebar_font
125 *
126 * Returns: void
127 * Description: updates the titlebar font from the pango context, should
128 * be called whenever the gtk style or font has changed
129 */
130void
131frame_update_titlebar_font (decor_frame_t *frame)
132{
133 const PangoFontDescription *font_desc;
134 PangoFontMetrics *metrics;
135 PangoLanguage *lang;
136
137 frame = gwd_decor_frame_ref (frame);
138
139 font_desc = get_titlebar_font (frame);
140 if (!font_desc)
141 {
142 GtkStyle *default_style;
143
144 default_style = gtk_widget_get_default_style ();
145 font_desc = default_style->font_desc;
146 }
147
148 pango_context_set_font_description (frame->pango_context, font_desc);
149
150 lang = pango_context_get_language (frame->pango_context);
151 metrics = pango_context_get_metrics (frame->pango_context, font_desc, lang);
152
153 frame->text_height = PANGO_PIXELS (pango_font_metrics_get_ascent (metrics) +
154 pango_font_metrics_get_descent (metrics));
155
156 gwd_decor_frame_unref (frame);
157
158 pango_font_metrics_unref (metrics);
159}
160
161void
162update_frames_titlebar_fonts (gpointer key,
163 gpointer value,
164 gpointer user_data)
165{
166 frame_update_titlebar_font ((decor_frame_t *) value);
167}
168
169void
170update_titlebar_font ()
171{
172 gwd_frames_foreach (update_frames_titlebar_fonts, NULL);
173}
174
175
176/*
177 * update_event_windows
178 *
179 * Returns: void
180 * Description: creates small "event windows" for the buttons specified to be
181 * on the titlebar by wnck. Note here that for the pixmap mode we create actual
182 * X windows but in the reparenting mode this is not possible so we create event
183 * capture boxes on the window instead. The geometry of the decoration is retrieved
184 * with wnck_window_get_client_window_geometry and adjusted for shade. Also we
185 * need to query the theme for what window positions are appropriate here.
186 *
187 * This function works on the buttons and also the small event regions that we need
188 * in order to toggle certain actions on the window decoration (eg resize, move)
189 *
190 * So your window decoration might look something like this (not to scale):
191 *
192 * -----------------------------------------------------------
193 * | rtl | rt | rtr |
194 * | --- |---------------------------------------------| --- |
195 * | | [i][s][m] mv [_][M][X] | |
196 * | |---------------------------------------------| |
197 * | | | |
198 * | rl | window contents | rr |
199 * | | | |
200 * | | | |
201 * | --- |---------------------------------------------| --- |
202 * | rbl | rb | rbr |
203 * -----------------------------------------------------------
204 *
205 * Where:
206 * - rtl = resize top left
207 * - rtr = resize top right
208 * - rbl = resize bottom left
209 * - rbr = resize bottom right
210 * - rt = resize top
211 * - rb = resize bottom
212 * - rl = resize left
213 * - rr = resize right
214 * - mv = "grab move" area (eg titlebar)
215 * - i = icon
216 * - s = shade
217 * - m = menu
218 * - _ = minimize
219 * - M = maximize
220 * - X = close
221 *
222 * For the reparenting mode we use button_windows[i].pos and for the pixmap mode
223 * we use buttons_windows[i].window
224 *
225 */
226void
227update_event_windows (WnckWindow *win)
228{
229 Display *xdisplay;
230 decor_t *d = g_object_get_data (G_OBJECT (win), "decor");
231 gint x0, y0, width, height, x, y, w, h;
232 gint i, j, k, l;
233 gint actions = d->actions;
234
235 xdisplay = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ());
236
237 /* Get the geometry of the client */
238 wnck_window_get_client_window_geometry (win, &x0, &y0, &width, &height);
239
240 /* Shaded windows have no height - also skip some event windows */
241 if (d->state & WNCK_WINDOW_STATE_SHADED)
242 {
243 height = 0;
244 k = l = 1;
245 }
246 else
247 {
248 k = 0;
249 l = 2;
250 }
251
252 gdk_error_trap_push ();
253
254 /* [rtl, ru, rtr], [rl, mv, rr], [rbl, rb, rbr] */
255 for (i = 0; i < 3; i++)
256 {
257 static guint event_window_actions[3][3] = {
258 {
259 WNCK_WINDOW_ACTION_RESIZE,
260 WNCK_WINDOW_ACTION_RESIZE,
261 WNCK_WINDOW_ACTION_RESIZE
262 }, {
263 WNCK_WINDOW_ACTION_RESIZE,
264 WNCK_WINDOW_ACTION_MOVE,
265 WNCK_WINDOW_ACTION_RESIZE
266 }, {
267 WNCK_WINDOW_ACTION_RESIZE,
268 WNCK_WINDOW_ACTION_RESIZE,
269 WNCK_WINDOW_ACTION_RESIZE
270 }
271 };
272
273 for (j = 0; j < 3; j++)
274 {
275 w = 0;
276 h = 0;
277
278 if (actions & event_window_actions[i][j] && i >= k && i <= l)
279 (*theme_get_event_window_position) (d, i, j, width, height,
280 &x, &y, &w, &h);
281
282 /* Reparenting mode - create boxes which we monitor motionnotify on */
283 if (d->frame_window)
284 {
285 BoxPtr box = &d->event_windows[i][j].pos;
286 box->x1 = x;
287 box->x2 = x + w;
288 box->y1 = y;
289 box->y2 = y + h;
290 }
291 /* Pixmap mode with window geometry - create small event windows */
292 else if (!d->frame_window && w != 0 && h != 0)
293 {
294 XMapWindow (xdisplay, d->event_windows[i][j].window);
295 XMoveResizeWindow (xdisplay, d->event_windows[i][j].window,
296 x, y, w, h);
297 }
298 /* No parent and no geometry - unmap all event windows */
299 else if (!d->frame_window)
300 {
301 XUnmapWindow (xdisplay, d->event_windows[i][j].window);
302 }
303 }
304 }
305
306 /* no button event windows if width is less than minimum width */
307 if (width < ICON_SPACE + d->button_width)
308 actions = 0;
309
310 /* Above, stick, unshade and unstick are only available in wnck => 2.18.1 */
311 for (i = 0; i < BUTTON_NUM; i++)
312 {
313 static guint button_actions[BUTTON_NUM] = {
314 WNCK_WINDOW_ACTION_CLOSE,
315 WNCK_WINDOW_ACTION_MAXIMIZE,
316 WNCK_WINDOW_ACTION_MINIMIZE,
317 0,
318 WNCK_WINDOW_ACTION_SHADE,
319
320#ifdef HAVE_LIBWNCK_2_18_1
321 WNCK_WINDOW_ACTION_ABOVE,
322 WNCK_WINDOW_ACTION_STICK,
323 WNCK_WINDOW_ACTION_UNSHADE,
324 WNCK_WINDOW_ACTION_ABOVE,
325 WNCK_WINDOW_ACTION_UNSTICK
326#else
327 0,
328 0,
329 0,
330 0,
331 0
332#endif
333
334 };
335
336 /* Reparenting mode - if a box was set and we no longer need it reset its geometry */
337 if (d->frame_window &&
338 button_actions[i] && !(actions & button_actions[i]))
339 {
340 memset (&d->button_windows[i].pos, 0, sizeof (Box));
341 }
342 /* Pixmap mode - if a box was set and we no longer need it unmap its window */
343 else if (!d->frame_window &&
344 button_actions[i] && !(actions & button_actions[i]))
345 {
346 XUnmapWindow (xdisplay, d->button_windows[i].window);
347 continue;
348 }
349
350 /* Reparenting mode - if there is a button position for this
351 * button then set the geometry */
352 if (d->frame_window &&
353 (*theme_get_button_position) (d, i, width, height, &x, &y, &w, &h))
354 {
355 BoxPtr box = &d->button_windows[i].pos;
356 box->x1 = x;
357 box->y1 = y;
358 box->x2 = x + w;
359 box->y2 = y + h;
360 }
361 /* Pixmap mode - if there is a button position for this button then map the window
362 * and resize it to this position */
363 else if (!d->frame_window &&
364 (*theme_get_button_position) (d, i, width, height,
365 &x, &y, &w, &h))
366 {
367 Window win = d->button_windows[i].window;
368 XMapWindow (xdisplay, win);
369 XMoveResizeWindow (xdisplay, win, x, y, w, h);
370 }
371 else if (!d->frame_window)
372 {
373 XUnmapWindow (xdisplay, d->button_windows[i].window);
374 }
375 }
376
377 gdk_display_sync (gdk_display_get_default ());
378 gdk_error_trap_pop ();
379}
380
381/*
382 * wnck_window_get_real_name
383 *
384 * Returns: const char * or NULL
385 * Description: Wrapper function to either get the name of the window or
386 * return NULL
387 */
388
389#ifdef HAVE_WNCK_WINDOW_HAS_NAME
390static const char *
391wnck_window_get_real_name (WnckWindow *win)
392{
393 return wnck_window_has_name (win) ? wnck_window_get_name (win) : NULL;
394}
395#define wnck_window_get_name wnck_window_get_real_name
396#endif
397
398/*
399 * max_window_name_width
400 *
401 * Returns: gint
402 * Description: Calculate the width of the decoration required to display
403 * the window name using pango (with 6px padding)
404 * Returns zero if window has no name.
405 */
406gint
407max_window_name_width (WnckWindow *win)
408{
409 decor_t *d = g_object_get_data (G_OBJECT (win), "decor");
410 const gchar *name;
411 gint w;
412
413 /* Ensure that a layout is created */
414 if (!d->layout)
415 {
416 d->layout = pango_layout_new (d->frame->pango_context);
417 if (!d->layout)
418 return 0;
419
420 pango_layout_set_wrap (d->layout, PANGO_WRAP_CHAR);
421 }
422
423 /* Return zero if window has no name */
424 name = wnck_window_get_name (win);
425 if (!name)
426 return 0;
427
428 /* Reset the width, set hte text and get the size required */
429 pango_layout_set_auto_dir (d->layout, FALSE);
430 pango_layout_set_width (d->layout, -1);
431 pango_layout_set_text (d->layout, name, strlen (name));
432 pango_layout_get_pixel_size (d->layout, &w, NULL);
433
434 if (d->name)
435 pango_layout_set_text (d->layout, d->name, strlen (d->name));
436
437 return w + 6;
438}
439
440/*
441 * update_window_decoration_name
442 *
443 * Returns: void
444 * Description: frees the last window name and gets the new one from
445 * wnck. Also checks to see if the name has a length (slight optimization)
446 * and re-creates the pango context to re-render the name
447 */
448void
449update_window_decoration_name (WnckWindow *win)
450{
451 decor_t *d = g_object_get_data (G_OBJECT (win), "decor");
452 const gchar *name;
453 glong name_length;
454 PangoLayoutLine *line;
455
456 if (d->name)
457 {
458 g_free (d->name);
459 d->name = NULL;
460 }
461
462 /* Only operate if the window name has a length */
463 name = wnck_window_get_name (win);
464 if (name && (name_length = strlen (name)))
465 {
466 gint w;
467
468 /* Cairo mode: w = SHRT_MAX */
469 if (theme_draw_window_decoration != draw_window_decoration)
470 {
471 w = SHRT_MAX;
472 }
473 /* Need to get a minimum width for the name */
474 else
475 {
476 gint width;
477
478 wnck_window_get_client_window_geometry (win, NULL, NULL,
479 &width, NULL);
480
481 w = width - ICON_SPACE - 2 - d->button_width;
482 if (w < 1)
483 w = 1;
484 }
485
486 /* Set the maximum width for the layout (in case
487 * decoration size < text width) since we
488 * still need to show the buttons and the window name */
489 pango_layout_set_auto_dir (d->layout, FALSE);
490 pango_layout_set_width (d->layout, w * PANGO_SCALE);
491 pango_layout_set_text (d->layout, name, name_length);
492
493 line = pango_layout_get_line (d->layout, 0);
494
495 name_length = line->length;
496 if (pango_layout_get_line_count (d->layout) > 1)
497 {
498 if (name_length < 4)
499 {
500 pango_layout_set_text (d->layout, NULL, 0);
501 return;
502 }
503
504 d->name = g_strndup (name, name_length);
505 strcpy (d->name + name_length - 3, "...");
506 }
507 else
508 d->name = g_strndup (name, name_length);
509
510 /* Truncate the text */
511 pango_layout_set_text (d->layout, d->name, name_length);
512 }
513}
514
515/*
516 * update_window_decoration_icon
517 *
518 * Updates the window icon (destroys the existing cairo pattern
519 * and creates a new one for the pixmap)
520 */
521void
522update_window_decoration_icon (WnckWindow *win)
523{
524 decor_t *d = g_object_get_data (G_OBJECT (win), "decor");
525
526 /* Destroy old stuff */
527 if (d->icon)
528 {
529 cairo_pattern_destroy (d->icon);
530 d->icon = NULL;
531 }
532
533 if (d->icon_pixmap)
534 {
535 g_object_unref (G_OBJECT (d->icon_pixmap));
536 d->icon_pixmap = NULL;
537 }
538
539 if (d->icon_pixbuf)
540 g_object_unref (G_OBJECT (d->icon_pixbuf));
541
542 /* Get the mini icon pixbuf from libwnck */
543 d->icon_pixbuf = wnck_window_get_mini_icon (win);
544 if (d->icon_pixbuf)
545 {
546 cairo_t *cr;
547
548 g_object_ref (G_OBJECT (d->icon_pixbuf));
549
550 /* 32 bit pixmap on pixmap mode, 24 for reparenting */
551 if (d->frame_window)
552 d->icon_pixmap = pixmap_new_from_pixbuf (d->icon_pixbuf,
553 d->frame->style_window_rgba);
554 else
555 d->icon_pixmap = pixmap_new_from_pixbuf (d->icon_pixbuf,
556 d->frame->style_window_rgb);
557 cr = gdk_cairo_create (GDK_DRAWABLE (d->icon_pixmap));
558 d->icon = cairo_pattern_create_for_surface (cairo_get_target (cr));
559 cairo_destroy (cr);
560 }
561}
562
563
564/*
565 * update_window_decoration_size
566 * Returns: FALSE for failure, TRUE for success
567 * Description: Calculates the minimum size of the decoration that we need
568 * to render. This is mostly done by the theme but there is some work that
569 * we need to do here first, such as getting the client geometry, setting
570 * drawable depths, creating pixmaps, creating XRenderPictures and
571 * updating the window decoration name
572 */
573
574gboolean
575update_window_decoration_size (WnckWindow *win)
576{
577 decor_t *d = g_object_get_data (G_OBJECT (win), "decor");
578 GdkPixmap *pixmap, *buffer_pixmap = NULL;
579 Picture picture;
580 gint width, height;
581 gint x, y, w, h, name_width;
582 Display *xdisplay;
583 XRenderPictFormat *format;
584
585 xdisplay = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ());
586
587 /* Get the geometry of the window, we'll need it later */
588 wnck_window_get_client_window_geometry (win, &x, &y, &w, &h);
589
590 /* Get the width of the name */
591 name_width = max_window_name_width (win);
592
593 /* Ask the theme to tell us how much space it needs. If this is not successful
594 * update the decoration name and return false */
595 if (!(*theme_calc_decoration_size) (d, w, h, name_width, &width, &height))
596 {
597 update_window_decoration_name (win);
598 return FALSE;
599 }
600
601 gdk_error_trap_push ();
602
603 /* Get the correct depth for the frame window in reparenting mode, otherwise
604 * enforce 32 */
605 if (d->frame_window)
606 pixmap = create_pixmap (width, height, d->frame->style_window_rgb);
607 else
608 pixmap = create_pixmap (width, height, d->frame->style_window_rgba);
609
610 gdk_flush ();
611
612 /* Handle failure */
613 if (!pixmap || gdk_error_trap_pop ())
614 {
615 memset (pixmap, 0, sizeof (pixmap));
616 return FALSE;
617 }
618
619 gdk_error_trap_push ();
620
621 if (d->frame_window)
622 buffer_pixmap = create_pixmap (width, height, d->frame->style_window_rgb);
623 else
624 buffer_pixmap = create_pixmap (width, height, d->frame->style_window_rgba);
625
626 gdk_flush ();
627
628 /* Handle failure */
629 if (!buffer_pixmap || gdk_error_trap_pop ())
630 {
631 memset (buffer_pixmap, 0, sizeof (buffer_pixmap));
632 g_object_unref (G_OBJECT (pixmap));
633 return FALSE;
634 }
635
636 /* Create XRender context */
637 format = get_format_for_drawable (d, GDK_DRAWABLE (buffer_pixmap));
638 picture = XRenderCreatePicture (xdisplay, GDK_PIXMAP_XID (buffer_pixmap),
639 format, 0, NULL);
640
641 /* Destroy the old pixmaps and pictures */
642 if (d->pixmap)
643 g_object_unref (G_OBJECT (d->pixmap));
644
645 if (d->buffer_pixmap)
646 g_object_unref (G_OBJECT (d->buffer_pixmap));
647
648 if (d->picture)
649 XRenderFreePicture (xdisplay, d->picture);
650
651 if (d->cr)
652 cairo_destroy (d->cr);
653
654 /* Assign new pixmaps and pictures */
655 d->pixmap = pixmap;
656 d->buffer_pixmap = buffer_pixmap;
657 d->cr = gdk_cairo_create (pixmap);
658
659 d->picture = picture;
660
661 d->width = width;
662 d->height = height;
663
664 d->prop_xid = wnck_window_get_xid (win);
665
666 update_window_decoration_name (win);
667
668 /* Redraw decoration on idle */
669 queue_decor_draw (d);
670
671 return TRUE;
672}
673
674/* to save some memory, value is specific to current decorations */
675#define TRANSLUCENT_CORNER_SIZE 3
676
677/*
678 * draw_border_shape
679 * Returns: void
680 * Description: Draws a slight border around the decoration
681 */
682static void
683draw_border_shape (Display *xdisplay,
684 Pixmap pixmap,
685 Picture picture,
686 int width,
687 int height,
688 decor_context_t *c,
689 void *closure)
690{
691 static XRenderColor white = { 0xffff, 0xffff, 0xffff, 0xffff };
692 GdkColormap *colormap;
693 decor_t d;
694 decor_shadow_info_t *info = (decor_shadow_info_t *) closure;
695 double save_decoration_alpha;
696
697 memset (&d, 0, sizeof (d));
698
699 if (info)
700 d.frame = info->frame;
701 else
702 d.frame = gwd_get_decor_frame ("default");
703
704 d.pixmap = gdk_pixmap_foreign_new_for_display (gdk_display_get_default (),
705 pixmap);
706 d.width = width;
707 d.height = height;
708 d.active = TRUE;
709 d.draw = theme_draw_window_decoration;
710 d.picture = picture;
711 d.context = c;
712
713 /* we use closure argument if maximized */
714 if (info)
715 d.state = info->state;
716 else
717 d.state = 0;
718
719 decor_get_default_layout (c, 1, 1, &d.border_layout);
720
721 colormap = get_colormap_for_drawable (GDK_DRAWABLE (d.pixmap));
722 gdk_drawable_set_colormap (d.pixmap, colormap);
723
724 /* create shadow from opaque decoration
725 * FIXME: Should not modify settings value
726 * like this */
727 save_decoration_alpha = settings->decoration_alpha;
728 settings->decoration_alpha = 1.0;
729
730 (*d.draw) (&d);
731
732 settings->decoration_alpha = save_decoration_alpha;
733
734 XRenderFillRectangle (xdisplay, PictOpSrc, picture, &white,
735 c->left_space,
736 c->top_space,
737 width - c->left_space - c->right_space,
738 height - c->top_space - c->bottom_space);
739
740 if (!info)
741 gwd_decor_frame_unref (d.frame);
742
743 g_object_unref (G_OBJECT (d.pixmap));
744}
745
746
747/*
748 * update_shadow
749 * Returns: 1 for success, 0 for failure
750 * Description: creates a libdecoration shadow context and updates
751 * the decoration context for the shadow for the properties that we
752 * have already read from the root window.
753 *
754 * For the pixmap mode we have opt_shadow which is passed to
755 * decor_shadow_create (which contains the shadow settings from
756 * the root window)
757 *
758 * For the reparenting mode we always enforce a zero-shadow in
759 * the opt_no_shadow passed to decor_shadow_create.
760 *
761 * We do something similar for the maximimzed mode as well
762 */
763void
764bare_frame_update_shadow (Display *xdisplay,
765 Screen *screen,
766 decor_frame_t *frame,
767 decor_shadow_info_t *info,
768 decor_shadow_options_t *opt_shadow,
769 decor_shadow_options_t *opt_no_shadow)
770{
771 if (frame->border_shadow)
772 {
773 decor_shadow_destroy (xdisplay, frame->border_shadow);
774 frame->border_shadow = NULL;
775 }
776
777 frame->border_shadow = decor_shadow_create (xdisplay,
778 screen,
779 1, 1,
780 0,
781 0,
782 0,
783 0,
784 0, 0, 0, 0,
785 opt_shadow,
786 &frame->window_context,
787 decor_draw_simple,
788 NULL);
789}
790
791void
792switcher_frame_update_shadow (Display *xdisplay,
793 Screen *screen,
794 decor_frame_t *frame,
795 decor_shadow_info_t *info,
796 decor_shadow_options_t *opt_shadow,
797 decor_shadow_options_t *opt_no_shadow)
798{
799 if (frame->border_shadow)
800 {
801 decor_shadow_destroy (xdisplay, frame->border_shadow);
802 frame->border_shadow = NULL;
803 }
804
805 frame->border_shadow = decor_shadow_create (xdisplay,
806 screen,
807 1, 1,
808 frame->win_extents.left,
809 frame->win_extents.right,
810 frame->win_extents.top,
811 frame->win_extents.bottom,
812 frame->win_extents.left -
813 TRANSLUCENT_CORNER_SIZE,
814 frame->win_extents.right -
815 TRANSLUCENT_CORNER_SIZE,
816 frame->win_extents.top -
817 TRANSLUCENT_CORNER_SIZE,
818 frame->win_extents.bottom -
819 TRANSLUCENT_CORNER_SIZE,
820 opt_shadow,
821 &frame->window_context,
822 decor_draw_simple,
823 NULL);
824}
825
826void
827decor_frame_update_shadow (Display *xdisplay,
828 Screen *screen,
829 decor_frame_t *frame,
830 decor_shadow_info_t *info,
831 decor_shadow_options_t *opt_shadow,
832 decor_shadow_options_t *opt_no_shadow)
833{
834 if (frame->border_shadow)
835 {
836 decor_shadow_destroy (xdisplay, frame->border_shadow);
837 frame->border_shadow = NULL;
838 }
839
840 frame->border_shadow = decor_shadow_create (xdisplay,
841 screen,
842 1, 1,
843 frame->win_extents.left,
844 frame->win_extents.right,
845 frame->win_extents.top + frame->titlebar_height,
846 frame->win_extents.bottom,
847 frame->win_extents.left -
848 TRANSLUCENT_CORNER_SIZE,
849 frame->win_extents.right -
850 TRANSLUCENT_CORNER_SIZE,
851 frame->win_extents.top + frame->titlebar_height -
852 TRANSLUCENT_CORNER_SIZE,
853 frame->win_extents.bottom -
854 TRANSLUCENT_CORNER_SIZE,
855 opt_shadow,
856 &frame->window_context,
857 draw_border_shape,
858 (void *) info);
859 if (frame->border_no_shadow)
860 {
861 decor_shadow_destroy (xdisplay, frame->border_no_shadow);
862 frame->border_no_shadow = NULL;
863 }
864
865 frame->border_no_shadow = decor_shadow_create (xdisplay,
866 screen,
867 1, 1,
868 frame->win_extents.left,
869 frame->win_extents.right,
870 frame->win_extents.top + frame->titlebar_height,
871 frame->win_extents.bottom,
872 frame->win_extents.left -
873 TRANSLUCENT_CORNER_SIZE,
874 frame->win_extents.right -
875 TRANSLUCENT_CORNER_SIZE,
876 frame->win_extents.top + frame->titlebar_height -
877 TRANSLUCENT_CORNER_SIZE,
878 frame->win_extents.bottom -
879 TRANSLUCENT_CORNER_SIZE,
880 opt_no_shadow,
881 &frame->window_context_no_shadow,
882 draw_border_shape,
883 0);
884
885 /* Maximized border shadow pixmap mode */
886 if (frame->max_border_shadow)
887 {
888 decor_shadow_destroy (xdisplay, frame->max_border_shadow);
889 frame->max_border_shadow = NULL;
890 }
891
892 info->state = (WNCK_WINDOW_STATE_MAXIMIZED_HORIZONTALLY |
893 WNCK_WINDOW_STATE_MAXIMIZED_VERTICALLY);
894
895 frame->max_border_shadow =
896 decor_shadow_create (xdisplay,
897 screen,
898 1, 1,
899 frame->max_win_extents.left,
900 frame->max_win_extents.right,
901 frame->max_win_extents.top + frame->max_titlebar_height,
902 frame->max_win_extents.bottom,
903 frame->max_win_extents.left - TRANSLUCENT_CORNER_SIZE,
904 frame->max_win_extents.right - TRANSLUCENT_CORNER_SIZE,
905 frame->max_win_extents.top + frame->max_titlebar_height -
906 TRANSLUCENT_CORNER_SIZE,
907 frame->max_win_extents.bottom - TRANSLUCENT_CORNER_SIZE,
908 opt_shadow,
909 &frame->max_window_context,
910 draw_border_shape,
911 (void *) info);
912
913 /* Enforced maximize zero shadow reparenting mode */
914 if (frame->max_border_no_shadow)
915 {
916 decor_shadow_destroy (xdisplay, frame->max_border_shadow);
917 frame->max_border_shadow = NULL;
918 }
919
920 frame->max_border_no_shadow =
921 decor_shadow_create (xdisplay,
922 screen,
923 1, 1,
924 frame->max_win_extents.left,
925 frame->max_win_extents.right,
926 frame->max_win_extents.top + frame->max_titlebar_height,
927 frame->max_win_extents.bottom,
928 frame->max_win_extents.left - TRANSLUCENT_CORNER_SIZE,
929 frame->max_win_extents.right - TRANSLUCENT_CORNER_SIZE,
930 frame->max_win_extents.top + frame->max_titlebar_height -
931 TRANSLUCENT_CORNER_SIZE,
932 frame->max_win_extents.bottom - TRANSLUCENT_CORNER_SIZE,
933 opt_no_shadow,
934 &frame->max_window_context_no_shadow,
935 draw_border_shape,
936 (void *) info);
937}
938
939
940typedef struct _tdtd_shadow_options
941{
942 decor_shadow_options_t *shadow;
943 decor_shadow_options_t *no_shadow;
944} tdtd_shadow_options_t;
945
946void
947frame_update_shadow (decor_frame_t *frame,
948 decor_shadow_info_t *info,
949 decor_shadow_options_t *opt_shadow,
950 decor_shadow_options_t *opt_no_shadow)
951{
952 gwd_decor_frame_ref (frame);
953
954 (*frame->update_shadow) (gdk_x11_get_default_xdisplay (),
955 gdk_x11_screen_get_xscreen (gdk_screen_get_default ()),
956 frame, info, opt_shadow, opt_no_shadow);
957
958 gwd_decor_frame_unref (frame);
959}
960
961void
962update_frames_shadows (gpointer key,
963 gpointer value,
964 gpointer user_data)
965{
966 decor_frame_t *frame = (decor_frame_t *) value;
967 tdtd_shadow_options_t *opts = (tdtd_shadow_options_t *) user_data;
968
969 gwd_decor_frame_ref (frame);
970
971 decor_shadow_info_t *info = malloc (sizeof (decor_shadow_info_t));
972
973 if (!info)
974 return;
975
976 info->frame = frame;
977 info->state = 0;
978
979 frame_update_shadow (frame, info, opts->shadow, opts->no_shadow);
980
981 gwd_decor_frame_unref (frame);
982
983 free (info);
984 info = NULL;
985
986}
987
988int
989update_shadow (void)
990{
991 decor_shadow_options_t opt_shadow;
992 decor_shadow_options_t opt_no_shadow;
993 tdtd_shadow_options_t *opts;
994
995 opts = malloc (sizeof (tdtd_shadow_options_t));
996
997 if (!opts)
998 return 0;
999
1000 opt_shadow.shadow_radius = settings->shadow_radius;
1001 opt_shadow.shadow_opacity = settings->shadow_opacity;
1002
1003 memcpy (opt_shadow.shadow_color, settings->shadow_color, sizeof (settings->shadow_color));
1004
1005 opt_shadow.shadow_offset_x = settings->shadow_offset_x;
1006 opt_shadow.shadow_offset_y = settings->shadow_offset_y;
1007
1008 opt_no_shadow.shadow_radius = 0;
1009 opt_no_shadow.shadow_opacity = 0;
1010
1011 opt_no_shadow.shadow_offset_x = 0;
1012 opt_no_shadow.shadow_offset_y = 0;
1013
1014 opts->shadow = &opt_shadow;
1015 opts->no_shadow = &opt_no_shadow;
1016
1017 gwd_frames_foreach (update_frames_shadows, (gpointer ) opts);
1018
1019 if (opts)
1020 free (opts);
1021
1022 return 1;
1023}
1024
1025/*
1026 * update_window_decoration
1027 *
1028 * Returns: void
1029 * Description: The master function to update the window decoration
1030 * if the pixmap needs to be redrawn
1031 */
1032void
1033update_window_decoration (WnckWindow *win)
1034{
1035 decor_t *d = g_object_get_data (G_OBJECT (win), "decor");
1036
1037 if (d->decorated)
1038 {
1039 /* force size update */
1040 d->context = NULL;
1041 d->width = d->height = 0;
1042
1043 update_window_decoration_size (win);
1044 update_event_windows (win);
1045 }
1046}
1047
1048/*
1049 * update_window_decoration_state
1050 *
1051 * Returns: void
1052 * Description: helper function to update the state of the decor_t
1053 */
1054void
1055update_window_decoration_state (WnckWindow *win)
1056{
1057 decor_t *d = g_object_get_data (G_OBJECT (win), "decor");
1058
1059 d->state = wnck_window_get_state (win);
1060}
1061
1062/*
1063 * update_window_decoration_actions
1064 *
1065 * Returns: void
1066 * Description: helper function to update the actions of the decor_t
1067 */
1068void
1069update_window_decoration_actions (WnckWindow *win)
1070{
1071 decor_t *d = g_object_get_data (G_OBJECT (win), "decor");
1072
1073 d->actions = wnck_window_get_actions (win);
1074}
1075
1076
1077/*
1078 * draw_decor_list
1079 *
1080 * Returns: bool
1081 * Description: function to be called on g_idle_add to draw window
1082 * decorations when we are not doing anything
1083 */
1084static gboolean
1085draw_decor_list (void *data)
1086{
1087 GSList *list;
1088 decor_t *d;
1089
1090 draw_idle_id = 0;
1091
1092 for (list = draw_list; list; list = list->next)
1093 {
1094 d = (decor_t *) list->data;
1095 (*d->draw) (d);
1096 }
1097
1098 g_slist_free (draw_list);
1099 draw_list = NULL;
1100
1101 return FALSE;
1102}
1103
1104/*
1105 * queue_decor_draw
1106 *
1107 * Description :queue a redraw request for this decoration. Since this function
1108 * only gets called on idle, don't redraw window decorations multiple
1109 * times if they are already waiting to be drawn (since the drawn copy
1110 * will always be the most updated one)
1111 */
1112void
1113queue_decor_draw (decor_t *d)
1114{
1115 if (g_slist_find (draw_list, d))
1116 return;
1117
1118 draw_list = g_slist_append (draw_list, d);
1119
1120 if (!draw_idle_id)
1121 draw_idle_id = g_idle_add (draw_decor_list, NULL);
1122}
1123
1124/*
1125 * update_default_decorations
1126 *
1127 * Description: update the default decorations
1128 */
1129void
1130update_default_decorations (GdkScreen *screen)
1131{
1132 long data[256];
1133 Window xroot;
1134 GdkDisplay *gdkdisplay = gdk_display_get_default ();
1135 Display *xdisplay = gdk_x11_display_get_xdisplay (gdkdisplay);
1136 Atom bareAtom, normalAtom, activeAtom;
1137 decor_t d;
1138 gint nQuad;
1139 decor_quad_t quads[N_QUADS_MAX];
1140 decor_frame_t *frame;
1141 decor_frame_t *bare_frame = gwd_get_decor_frame ("bare");
1142 decor_extents_t extents;
1143
1144 xroot = RootWindowOfScreen (gdk_x11_screen_get_xscreen (screen));
1145
1146 bareAtom = XInternAtom (xdisplay, DECOR_BARE_ATOM_NAME, FALSE);
1147 normalAtom = XInternAtom (xdisplay, DECOR_NORMAL_ATOM_NAME, FALSE);
1148 activeAtom = XInternAtom (xdisplay, DECOR_ACTIVE_ATOM_NAME, FALSE);
1149
1150 if (bare_frame->border_shadow)
1151 {
1152 decor_layout_t layout;
1153
1154 decor_get_default_layout (&bare_frame->window_context, 1, 1, &layout);
1155
1156 nQuad = decor_set_lSrStSbS_window_quads (quads, &bare_frame->window_context,
1157 &layout);
1158
1159 decor_quads_to_property (data, bare_frame->border_shadow->pixmap,
1160 &bare_frame->win_extents, &bare_frame->win_extents,
1161 &bare_frame->win_extents, &bare_frame->win_extents,
1162 0, 0, quads, nQuad);
1163
1164 XChangeProperty (xdisplay, xroot,
1165 bareAtom,
1166 XA_INTEGER,
1167 32, PropModeReplace, (guchar *) data,
1168 BASE_PROP_SIZE + QUAD_PROP_SIZE * nQuad);
1169
1170 if (minimal)
1171 {
1172 XChangeProperty (xdisplay, xroot,
1173 normalAtom,
1174 XA_INTEGER,
1175 32, PropModeReplace, (guchar *) data,
1176 BASE_PROP_SIZE + QUAD_PROP_SIZE * nQuad);
1177 XChangeProperty (xdisplay, xroot,
1178 activeAtom,
1179 XA_INTEGER,
1180 32, PropModeReplace, (guchar *) data,
1181 BASE_PROP_SIZE + QUAD_PROP_SIZE * nQuad);
1182 }
1183 }
1184 else
1185 {
1186 XDeleteProperty (xdisplay, xroot, bareAtom);
1187
1188 if (minimal)
1189 {
1190 XDeleteProperty (xdisplay, xroot, normalAtom);
1191 XDeleteProperty (xdisplay, xroot, activeAtom);
1192 }
1193 }
1194
1195 if (minimal)
1196 {
1197 gwd_decor_frame_unref (bare_frame);
1198 return;
1199 }
1200
1201 memset (&d, 0, sizeof (d));
1202
1203 frame = gwd_get_decor_frame ("default");
1204 extents = frame->win_extents;
1205
1206 d.context = &frame->window_context;
1207 d.shadow = frame->border_shadow;
1208 d.layout = pango_layout_new (frame->pango_context);
1209
1210 decor_get_default_layout (d.context, 1, 1, &d.border_layout);
1211
1212 d.width = d.border_layout.width;
1213 d.height = d.border_layout.height;
1214
1215 d.frame = frame;
1216
1217 extents.top += frame->titlebar_height;
1218
1219 d.draw = theme_draw_window_decoration;
1220
1221 if (decor_normal_pixmap)
1222 g_object_unref (G_OBJECT (decor_normal_pixmap));
1223
1224 nQuad = decor_set_lSrStSbS_window_quads (quads, d.context,
1225 &d.border_layout);
1226
1227 decor_normal_pixmap = create_pixmap (d.width, d.height, frame->style_window_rgba);
1228
1229 if (decor_normal_pixmap)
1230 {
1231 d.pixmap = decor_normal_pixmap;
1232 d.active = FALSE;
1233 d.picture = XRenderCreatePicture (xdisplay,
1234 GDK_PIXMAP_XID (d.pixmap),
1235 xformat_rgba, 0, NULL);
1236
1237 (*d.draw) (&d);
1238
1239 XRenderFreePicture (xdisplay, d.picture);
1240
1241 decor_quads_to_property (data, GDK_PIXMAP_XID (d.pixmap),
1242 &extents, &extents,
1243 &extents, &extents, 0, 0, quads, nQuad);
1244
1245 XChangeProperty (xdisplay, xroot,
1246 normalAtom,
1247 XA_INTEGER,
1248 32, PropModeReplace, (guchar *) data,
1249 BASE_PROP_SIZE + QUAD_PROP_SIZE * nQuad);
1250 }
1251
1252 if (decor_active_pixmap)
1253 g_object_unref (G_OBJECT (decor_active_pixmap));
1254
1255 decor_active_pixmap = create_pixmap (d.width, d.height, frame->style_window_rgba);
1256
1257 if (decor_active_pixmap)
1258 {
1259 d.pixmap = decor_active_pixmap;
1260 d.active = TRUE;
1261 d.picture = XRenderCreatePicture (xdisplay,
1262 GDK_PIXMAP_XID (d.pixmap),
1263 xformat_rgba, 0, NULL);
1264
1265 (*d.draw) (&d);
1266
1267 XRenderFreePicture (xdisplay, d.picture);
1268
1269 decor_quads_to_property (data, GDK_PIXMAP_XID (d.pixmap),
1270 &extents, &extents,
1271 &extents, &extents, 0, 0, quads, nQuad);
1272
1273 XChangeProperty (xdisplay, xroot,
1274 activeAtom,
1275 XA_INTEGER,
1276 32, PropModeReplace, (guchar *) data,
1277 BASE_PROP_SIZE + QUAD_PROP_SIZE * nQuad);
1278 }
1279
1280 gwd_decor_frame_unref (frame);
1281 gwd_decor_frame_unref (bare_frame);
1282
1283 if (d.layout)
1284 g_object_unref (G_OBJECT (d.layout));
1285}
1286
1287/*
1288 * copy_to_front_buffer
1289 *
1290 * Description: Helper function to copy the buffer pixmap to a front buffer
1291 */
1292void
1293copy_to_front_buffer (decor_t *d)
1294{
1295 if (!d->buffer_pixmap)
1296 return;
1297
1298 cairo_set_operator (d->cr, CAIRO_OPERATOR_SOURCE);
1299 gdk_cairo_set_source_pixmap (d->cr, d->buffer_pixmap, 0, 0);
1300 cairo_paint (d->cr);
1301}
01302
=== renamed file 'gtk/window-decorator/decorator.c' => 'gtk/window-decorator/decorator.c.THIS'
=== added file 'gtk/window-decorator/decorprops.c'
--- gtk/window-decorator/decorprops.c 1970-01-01 00:00:00 +0000
+++ gtk/window-decorator/decorprops.c 2012-02-08 18:50:27 +0000
@@ -0,0 +1,161 @@
1/*
2 * Copyright © 2006 Novell, Inc.
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
18 *
19 * Author: David Reveman <davidr@novell.com>
20 *
21 * 2D Mode: Copyright © 2010 Sam Spilsbury <smspillaz@gmail.com>
22 * Frames Management: Copright © 2011 Canonical Ltd.
23 * Authored By: Sam Spilsbury <sam.spilsbury@canonical.com>
24 */
25
26#include "gtk-window-decorator.h"
27
28void
29decor_update_window_property (decor_t *d)
30{
31 long data[256];
32 Display *xdisplay =
33 GDK_DISPLAY_XDISPLAY (gdk_display_get_default ());
34 decor_extents_t extents = d->frame->win_extents;
35 gint nQuad;
36 decor_quad_t quads[N_QUADS_MAX];
37 int w, h;
38 gint stretch_offset;
39 REGION top, bottom, left, right;
40
41 w = d->border_layout.top.x2 - d->border_layout.top.x1 -
42 d->context->left_space - d->context->right_space;
43
44 if (d->border_layout.rotation)
45 h = d->border_layout.left.x2 - d->border_layout.left.x1;
46 else
47 h = d->border_layout.left.y2 - d->border_layout.left.y1;
48
49 stretch_offset = w - d->button_width - 1;
50
51 nQuad = decor_set_lSrStXbS_window_quads (quads, d->context,
52 &d->border_layout,
53 stretch_offset);
54
55 extents.top += d->frame->titlebar_height;
56
57 if (d->frame_window)
58 {
59 decor_gen_window_property (data, &extents, &extents, 20, 20);
60 }
61 else
62 {
63 decor_quads_to_property (data, GDK_PIXMAP_XID (d->pixmap),
64 &extents, &extents,
65 &extents, &extents,
66 ICON_SPACE + d->button_width,
67 0,
68 quads, nQuad);
69 }
70
71 gdk_error_trap_push ();
72 XChangeProperty (xdisplay, d->prop_xid,
73 win_decor_atom,
74 XA_INTEGER,
75 32, PropModeReplace, (guchar *) data,
76 BASE_PROP_SIZE + QUAD_PROP_SIZE * nQuad);
77 gdk_display_sync (gdk_display_get_default ());
78 gdk_error_trap_pop ();
79
80 top.rects = &top.extents;
81 top.numRects = top.size = 1;
82
83 top.extents.x1 = -extents.left;
84 top.extents.y1 = -extents.top;
85 top.extents.x2 = w + extents.right;
86 top.extents.y2 = 0;
87
88 bottom.rects = &bottom.extents;
89 bottom.numRects = bottom.size = 1;
90
91 bottom.extents.x1 = -extents.left;
92 bottom.extents.y1 = 0;
93 bottom.extents.x2 = w + extents.right;
94 bottom.extents.y2 = extents.bottom;
95
96 left.rects = &left.extents;
97 left.numRects = left.size = 1;
98
99 left.extents.x1 = -extents.left;
100 left.extents.y1 = 0;
101 left.extents.x2 = 0;
102 left.extents.y2 = h;
103
104 right.rects = &right.extents;
105 right.numRects = right.size = 1;
106
107 right.extents.x1 = 0;
108 right.extents.y1 = 0;
109 right.extents.x2 = extents.right;
110 right.extents.y2 = h;
111
112 decor_update_blur_property (d,
113 w, h,
114 &top, stretch_offset,
115 &bottom, w / 2,
116 &left, h / 2,
117 &right, h / 2);
118}
119
120void
121decor_update_switcher_property (decor_t *d)
122{
123 long data[256];
124 Display *xdisplay = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ());
125 gint nQuad;
126 decor_quad_t quads[N_QUADS_MAX];
127 GtkStyle *style;
128 long fgColor[4];
129
130 nQuad = decor_set_lSrStSbX_window_quads (quads, &d->frame->window_context,
131 &d->border_layout,
132 d->border_layout.top.x2 -
133 d->border_layout.top.x1 -
134 d->frame->window_context.extents.left -
135 d->frame->window_context.extents.right -
136 32);
137
138 decor_quads_to_property (data, GDK_PIXMAP_XID (d->pixmap),
139 &d->frame->win_extents, &d->frame->win_extents,
140 &d->frame->win_extents, &d->frame->win_extents,
141 0, 0, quads, nQuad);
142
143 style = gtk_widget_get_style (d->frame->style_window_rgba);
144
145 fgColor[0] = style->fg[GTK_STATE_NORMAL].red;
146 fgColor[1] = style->fg[GTK_STATE_NORMAL].green;
147 fgColor[2] = style->fg[GTK_STATE_NORMAL].blue;
148 fgColor[3] = SWITCHER_ALPHA;
149
150 gdk_error_trap_push ();
151 XChangeProperty (xdisplay, d->prop_xid,
152 win_decor_atom,
153 XA_INTEGER,
154 32, PropModeReplace, (guchar *) data,
155 BASE_PROP_SIZE + QUAD_PROP_SIZE * nQuad);
156 XChangeProperty (xdisplay, d->prop_xid, switcher_fg_atom,
157 XA_INTEGER, 32, PropModeReplace, (guchar *) fgColor, 4);
158 gdk_display_sync (gdk_display_get_default ());
159 gdk_error_trap_pop ();
160
161}
0162
=== renamed file 'gtk/window-decorator/decorprops.c' => 'gtk/window-decorator/decorprops.c.THIS'
=== added file 'gtk/window-decorator/events.c'
--- gtk/window-decorator/events.c 1970-01-01 00:00:00 +0000
+++ gtk/window-decorator/events.c 2012-02-08 18:50:27 +0000
@@ -0,0 +1,1177 @@
1/*
2 * Copyright © 2006 Novell, Inc.
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
18 *
19 * Author: David Reveman <davidr@novell.com>
20 *
21 * 2D Mode: Copyright © 2010 Sam Spilsbury <smspillaz@gmail.com>
22 * Frames Management: Copright © 2011 Canonical Ltd.
23 * Authored By: Sam Spilsbury <sam.spilsbury@canonical.com>
24 */
25
26#include "gtk-window-decorator.h"
27
28void
29move_resize_window (WnckWindow *win,
30 int direction,
31 decor_event *gtkwd_event)
32{
33 Display *xdisplay;
34 GdkDisplay *gdkdisplay;
35 GdkScreen *screen;
36 Window xroot;
37 XEvent ev;
38
39 gdkdisplay = gdk_display_get_default ();
40 xdisplay = GDK_DISPLAY_XDISPLAY (gdkdisplay);
41 screen = gdk_display_get_default_screen (gdkdisplay);
42 xroot = RootWindowOfScreen (gdk_x11_screen_get_xscreen (screen));
43
44 if (action_menu_mapped)
45 {
46 gtk_object_destroy (GTK_OBJECT (action_menu));
47 action_menu_mapped = FALSE;
48 action_menu = NULL;
49 return;
50 }
51
52 ev.xclient.type = ClientMessage;
53 ev.xclient.display = xdisplay;
54
55 ev.xclient.serial = 0;
56 ev.xclient.send_event = TRUE;
57
58 ev.xclient.window = wnck_window_get_xid (win);
59 ev.xclient.message_type = wm_move_resize_atom;
60 ev.xclient.format = 32;
61
62 ev.xclient.data.l[0] = gtkwd_event->x_root;
63 ev.xclient.data.l[1] = gtkwd_event->y_root;
64 ev.xclient.data.l[2] = direction;
65 ev.xclient.data.l[3] = gtkwd_event->button;
66 ev.xclient.data.l[4] = 1;
67
68 XUngrabPointer (xdisplay, gtkwd_event->time);
69 XUngrabKeyboard (xdisplay, gtkwd_event->time);
70
71 XSendEvent (xdisplay, xroot, FALSE,
72 SubstructureRedirectMask | SubstructureNotifyMask,
73 &ev);
74
75 XSync (xdisplay, FALSE);
76}
77
78void
79common_button_event (WnckWindow *win,
80 decor_event *gtkwd_event,
81 decor_event_type gtkwd_type,
82 int button,
83 int max,
84 char *tooltip)
85{
86 decor_t *d = g_object_get_data (G_OBJECT (win), "decor");
87 guint state = d->button_states[button];
88
89 handle_tooltip_event (win, gtkwd_event, gtkwd_type, state, tooltip);
90
91 if (d->frame_window && gtkwd_type == GEnterNotify)
92 {
93 GdkCursor* cursor;
94 cursor = gdk_cursor_new (GDK_LEFT_PTR);
95 gdk_window_set_cursor (d->frame_window, cursor);
96 gdk_cursor_unref (cursor);
97 }
98
99 switch (gtkwd_type) {
100 case GButtonPress:
101 if (gtkwd_event->button <= max)
102 d->button_states[button] |= PRESSED_EVENT_WINDOW;
103 break;
104 case GButtonRelease:
105 if (gtkwd_event->button <= max)
106 d->button_states[button] &= ~PRESSED_EVENT_WINDOW;
107 break;
108 case GEnterNotify:
109 d->button_states[button] |= IN_EVENT_WINDOW;
110 break;
111 case GLeaveNotify:
112 d->button_states[button] &= ~IN_EVENT_WINDOW;
113 break;
114 default:
115 break;
116 }
117
118 if (state != d->button_states[button])
119 queue_decor_draw (d);
120}
121
122#define BUTTON_EVENT_ACTION_STATE (PRESSED_EVENT_WINDOW | IN_EVENT_WINDOW)
123
124void
125close_button_event (WnckWindow *win,
126 decor_event *gtkwd_event,
127 decor_event_type gtkwd_type)
128{
129 decor_t *d = g_object_get_data (G_OBJECT (win), "decor");
130 guint state = d->button_states[BUTTON_CLOSE];
131
132 common_button_event (win, gtkwd_event, gtkwd_type,
133 BUTTON_CLOSE, 1, _("Close Window"));
134
135 switch (gtkwd_type) {
136 case GButtonRelease:
137 if (gtkwd_event->button == 1)
138 if (state == BUTTON_EVENT_ACTION_STATE)
139 wnck_window_close (win, gtkwd_event->time);
140 break;
141 default:
142 break;
143 }
144}
145
146void
147max_button_event (WnckWindow *win,
148 decor_event *gtkwd_event,
149 decor_event_type gtkwd_type)
150{
151 decor_t *d = g_object_get_data (G_OBJECT (win), "decor");
152 guint state = d->button_states[BUTTON_MAX];
153
154 if (wnck_window_is_maximized (win))
155 common_button_event (win, gtkwd_event, gtkwd_type, BUTTON_MAX,
156 3, _("Unmaximize Window"));
157 else
158 common_button_event (win, gtkwd_event, gtkwd_type, BUTTON_MAX,
159 3, _("Maximize Window"));
160
161 switch (gtkwd_type) {
162 case GButtonRelease:
163 if (gtkwd_event->button <= 3)
164 {
165 if (state == BUTTON_EVENT_ACTION_STATE)
166 {
167 if (gtkwd_event->button == 2)
168 {
169 if (wnck_window_is_maximized_vertically (win))
170 wnck_window_unmaximize_vertically (win);
171 else
172 wnck_window_maximize_vertically (win);
173 }
174 else if (gtkwd_event->button == 3)
175 {
176 if (wnck_window_is_maximized_horizontally (win))
177 wnck_window_unmaximize_horizontally (win);
178 else
179 wnck_window_maximize_horizontally (win);
180 }
181 else
182 {
183 if (wnck_window_is_maximized (win))
184 wnck_window_unmaximize (win);
185 else
186 wnck_window_maximize (win);
187 }
188 }
189 }
190 break;
191 default:
192 break;
193 }
194}
195
196void
197min_button_event (WnckWindow *win,
198 decor_event *gtkwd_event,
199 decor_event_type gtkwd_type)
200{
201 decor_t *d = g_object_get_data (G_OBJECT (win), "decor");
202 guint state = d->button_states[BUTTON_MIN];
203
204 common_button_event (win, gtkwd_event, gtkwd_type,
205 BUTTON_MIN, 1, _("Minimize Window"));
206
207 switch (gtkwd_type) {
208 case GButtonRelease:
209 if (gtkwd_event->button == 1)
210 if (state == BUTTON_EVENT_ACTION_STATE)
211 wnck_window_minimize (win);
212 break;
213 default:
214 break;
215 }
216}
217
218void
219menu_button_event (WnckWindow *win,
220 decor_event *gtkwd_event,
221 decor_event_type gtkwd_type)
222{
223
224 common_button_event (win, gtkwd_event, gtkwd_type,
225 BUTTON_MENU, 1, _("Window Menu"));
226
227 switch (gtkwd_type) {
228 case GButtonPress:
229 if (gtkwd_event->button == 1)
230 action_menu_map (win,
231 gtkwd_event->button,
232 gtkwd_event->time);
233 break;
234 default:
235 break;
236 }
237}
238
239void
240shade_button_event (WnckWindow *win,
241 decor_event *gtkwd_event,
242 decor_event_type gtkwd_type)
243{
244 decor_t *d = g_object_get_data (G_OBJECT (win), "decor");
245 guint state = d->button_states[BUTTON_SHADE];
246
247 common_button_event (win, gtkwd_event, gtkwd_type,
248 BUTTON_SHADE, 1, _("Shade"));
249
250 switch (gtkwd_type) {
251 case GButtonRelease:
252 if (gtkwd_event->button == 1)
253 {
254 if (state == BUTTON_EVENT_ACTION_STATE)
255 wnck_window_shade (win);
256 }
257 break;
258 default:
259 break;
260 }
261}
262
263void
264above_button_event (WnckWindow *win,
265 decor_event *gtkwd_event,
266 decor_event_type gtkwd_type)
267{
268 decor_t *d = g_object_get_data (G_OBJECT (win), "decor");
269 guint state = d->button_states[BUTTON_ABOVE];
270
271 common_button_event (win, gtkwd_event, gtkwd_type,
272 BUTTON_ABOVE, 1, _("Make Above"));
273
274 switch (gtkwd_type) {
275 case GButtonRelease:
276 if (gtkwd_event->button == 1)
277 if (state == BUTTON_EVENT_ACTION_STATE)
278#ifdef HAVE_LIBWNCK_2_18_1
279 wnck_window_make_above (win);
280#endif
281 break;
282 default:
283 break;
284 }
285}
286
287void
288stick_button_event (WnckWindow *win,
289 decor_event *gtkwd_event,
290 decor_event_type gtkwd_type)
291{
292 decor_t *d = g_object_get_data (G_OBJECT (win), "decor");
293 guint state = d->button_states[BUTTON_STICK];
294
295 common_button_event (win, gtkwd_event, gtkwd_type,
296 BUTTON_STICK, 1, _("Stick"));
297
298 switch (gtkwd_type) {
299 case GButtonRelease:
300 if (gtkwd_event->button == 1)
301 if (state == BUTTON_EVENT_ACTION_STATE)
302 wnck_window_stick (win);
303 break;
304 default:
305 break;
306 }
307}
308
309void
310unshade_button_event (WnckWindow *win,
311 decor_event *gtkwd_event,
312 decor_event_type gtkwd_type)
313{
314 decor_t *d = g_object_get_data (G_OBJECT (win), "decor");
315 guint state = d->button_states[BUTTON_UNSHADE];
316
317 common_button_event (win, gtkwd_event, gtkwd_type,
318 BUTTON_UNSHADE, 1, _("Unshade"));
319
320 switch (gtkwd_type) {
321 case GButtonRelease:
322 if (gtkwd_event->button == 1)
323 if (state == BUTTON_EVENT_ACTION_STATE)
324 wnck_window_unshade (win);
325 break;
326 default:
327 break;
328 }
329}
330
331void
332unabove_button_event (WnckWindow *win,
333 decor_event *gtkwd_event,
334 decor_event_type gtkwd_type)
335{
336 decor_t *d = g_object_get_data (G_OBJECT (win), "decor");
337 guint state = d->button_states[BUTTON_UNABOVE];
338
339 common_button_event (win, gtkwd_event, gtkwd_type,
340 BUTTON_UNABOVE, 1, _("Unmake Above"));
341
342 switch (gtkwd_type) {
343 case GButtonRelease:
344 if (gtkwd_event->button == 1)
345 if (state == BUTTON_EVENT_ACTION_STATE)
346#ifdef HAVE_LIBWNCK_2_18_1
347 wnck_window_unmake_above (win);
348#endif
349 break;
350 default:
351 break;
352 }
353}
354
355void
356unstick_button_event (WnckWindow *win,
357 decor_event *gtkwd_event,
358 decor_event_type gtkwd_type)
359{
360 decor_t *d = g_object_get_data (G_OBJECT (win), "decor");
361 guint state = d->button_states[BUTTON_UNSTICK];
362
363 common_button_event (win, gtkwd_event, gtkwd_type,
364 BUTTON_UNSTICK, 1, _("Unstick"));
365
366 switch (gtkwd_type) {
367 case GButtonRelease:
368 if (gtkwd_event->button == 1)
369 if (state == BUTTON_EVENT_ACTION_STATE)
370 wnck_window_unstick (win);
371 break;
372 default:
373 break;
374 }
375}
376
377void
378handle_title_button_event (WnckWindow *win,
379 int action,
380 decor_event *gtkwd_event)
381{
382 switch (action) {
383 case CLICK_ACTION_SHADE:
384 if (wnck_window_is_shaded (win))
385 wnck_window_unshade (win);
386 else
387 wnck_window_shade (win);
388 break;
389 case CLICK_ACTION_MAXIMIZE:
390 if (wnck_window_is_maximized (win))
391 wnck_window_unmaximize (win);
392 else
393 wnck_window_maximize (win);
394 break;
395 case CLICK_ACTION_MINIMIZE:
396 if (!wnck_window_is_minimized (win))
397 wnck_window_minimize (win);
398 break;
399 case CLICK_ACTION_RAISE:
400 restack_window (win, Above);
401 break;
402 case CLICK_ACTION_LOWER:
403 restack_window (win, Below);
404 break;
405 case CLICK_ACTION_MENU:
406 action_menu_map (win, gtkwd_event->button, gtkwd_event->time);
407 break;
408 }
409}
410
411void
412handle_mouse_wheel_title_event (WnckWindow *win,
413 unsigned int button)
414{
415 switch (settings->wheel_action) {
416 case WHEEL_ACTION_SHADE:
417 if (button == 4)
418 {
419 if (!wnck_window_is_shaded (win))
420 wnck_window_shade (win);
421 }
422 else if (button == 5)
423 {
424 if (wnck_window_is_shaded (win))
425 wnck_window_unshade (win);
426 }
427 break;
428 default:
429 break;
430 }
431}
432
433void
434title_event (WnckWindow *win,
435 decor_event *gtkwd_event,
436 decor_event_type gtkwd_type)
437{
438 static int last_button_num = 0;
439 static Window last_button_xwindow = None;
440 static Time last_button_time = 0;
441 static int last_button_x = 0;
442 static int last_button_y = 0;
443
444 decor_t *d = g_object_get_data (G_OBJECT (win), "decor");
445
446 if (d->frame_window && gtkwd_type == GEnterNotify)
447 {
448 GdkCursor* cursor = gdk_cursor_new (GDK_LEFT_PTR);
449 gdk_window_set_cursor (d->frame_window, cursor);
450 gdk_cursor_unref (cursor);
451 }
452
453 if (gtkwd_type != GButtonPress)
454 return;
455
456 if (gtkwd_event->button == 1)
457 {
458 if (gtkwd_event->button == last_button_num &&
459 gtkwd_event->window == last_button_xwindow &&
460 gtkwd_event->time < last_button_time + double_click_timeout &&
461 dist (gtkwd_event->x, gtkwd_event->y,
462 last_button_x, last_button_y) < DOUBLE_CLICK_DISTANCE)
463 {
464 handle_title_button_event (win, settings->double_click_action,
465 gtkwd_event);
466
467 last_button_num = 0;
468 last_button_xwindow = None;
469 last_button_time = 0;
470 last_button_x = 0;
471 last_button_y = 0;
472 }
473 else
474 {
475 last_button_num = gtkwd_event->button;
476 last_button_xwindow = gtkwd_event->window;
477 last_button_time = gtkwd_event->time;
478 last_button_x = gtkwd_event->x;
479 last_button_y = gtkwd_event->y;
480
481 restack_window (win, Above);
482
483 move_resize_window (win, WM_MOVERESIZE_MOVE, gtkwd_event);
484 }
485 }
486 else if (gtkwd_event->button == 2)
487 {
488 handle_title_button_event (win, settings->middle_click_action,
489 gtkwd_event);
490 }
491 else if (gtkwd_event->button == 3)
492 {
493 handle_title_button_event (win, settings->right_click_action,
494 gtkwd_event);
495 }
496 else if (gtkwd_event->button == 4 ||
497 gtkwd_event->button == 5)
498 {
499 handle_mouse_wheel_title_event (win, gtkwd_event->button);
500 }
501}
502
503void
504frame_common_event (WnckWindow *win,
505 int direction,
506 decor_event *gtkwd_event,
507 decor_event_type gtkwd_type)
508{
509
510 decor_t *d = g_object_get_data (G_OBJECT (win), "decor");
511
512 if (d->frame_window && gtkwd_type == GEnterNotify)
513 {
514 GdkCursor *cursor = NULL;
515
516 switch (direction)
517 {
518 case WM_MOVERESIZE_SIZE_TOPLEFT:
519 cursor = gdk_cursor_new (GDK_TOP_LEFT_CORNER);
520 break;
521 case WM_MOVERESIZE_SIZE_LEFT:
522 cursor = gdk_cursor_new (GDK_LEFT_SIDE);
523 break;
524 case WM_MOVERESIZE_SIZE_BOTTOMLEFT:
525 cursor = gdk_cursor_new (GDK_BOTTOM_LEFT_CORNER);
526 break;
527 case WM_MOVERESIZE_SIZE_BOTTOM:
528 cursor = gdk_cursor_new (GDK_BOTTOM_SIDE);
529 break;
530 case WM_MOVERESIZE_SIZE_BOTTOMRIGHT:
531 cursor = gdk_cursor_new (GDK_BOTTOM_RIGHT_CORNER);
532 break;
533 case WM_MOVERESIZE_SIZE_RIGHT:
534 cursor = gdk_cursor_new (GDK_RIGHT_SIDE);
535 break;
536 case WM_MOVERESIZE_SIZE_TOPRIGHT:
537 cursor = gdk_cursor_new (GDK_TOP_RIGHT_CORNER);
538 break;
539 case WM_MOVERESIZE_SIZE_TOP:
540 cursor = gdk_cursor_new (GDK_TOP_SIDE);
541 break;
542 default:
543 break;
544 }
545
546 if (cursor)
547 {
548 gdk_window_set_cursor (d->frame_window, cursor);
549 gdk_cursor_unref (cursor);
550 }
551 }
552
553 if (gtkwd_type != GButtonPress)
554 return;
555
556 switch (gtkwd_event->button) {
557 case 1:
558 move_resize_window (win, direction, gtkwd_event);
559 restack_window (win, Above);
560 break;
561 case 2:
562 handle_title_button_event (win, settings->middle_click_action,
563 gtkwd_event);
564 break;
565 case 3:
566 handle_title_button_event (win, settings->right_click_action,
567 gtkwd_event);
568 break;
569 }
570}
571
572void
573top_left_event (WnckWindow *win,
574 decor_event *gtkwd_event,
575 decor_event_type gtkwd_type)
576{
577 frame_common_event (win, WM_MOVERESIZE_SIZE_TOPLEFT,
578 gtkwd_event, gtkwd_type);
579}
580
581void
582top_event (WnckWindow *win,
583 decor_event *gtkwd_event,
584 decor_event_type gtkwd_type)
585{
586 frame_common_event (win, WM_MOVERESIZE_SIZE_TOP,
587 gtkwd_event, gtkwd_type);
588}
589
590void
591top_right_event (WnckWindow *win,
592 decor_event *gtkwd_event,
593 decor_event_type gtkwd_type)
594{
595 frame_common_event (win, WM_MOVERESIZE_SIZE_TOPRIGHT,
596 gtkwd_event, gtkwd_type);
597}
598
599void
600left_event (WnckWindow *win,
601 decor_event *gtkwd_event,
602 decor_event_type gtkwd_type)
603{
604 frame_common_event (win, WM_MOVERESIZE_SIZE_LEFT,
605 gtkwd_event, gtkwd_type);
606}
607
608void
609right_event (WnckWindow *win,
610 decor_event *gtkwd_event,
611 decor_event_type gtkwd_type)
612{
613 frame_common_event (win, WM_MOVERESIZE_SIZE_RIGHT,
614 gtkwd_event, gtkwd_type);
615}
616
617void
618bottom_left_event (WnckWindow *win,
619 decor_event *gtkwd_event,
620 decor_event_type gtkwd_type)
621{
622 frame_common_event (win, WM_MOVERESIZE_SIZE_BOTTOMLEFT,
623 gtkwd_event, gtkwd_type);
624}
625
626void
627bottom_event (WnckWindow *win,
628 decor_event *gtkwd_event,
629 decor_event_type gtkwd_type)
630{
631 frame_common_event (win, WM_MOVERESIZE_SIZE_BOTTOM,
632 gtkwd_event, gtkwd_type);
633}
634
635void
636bottom_right_event (WnckWindow *win,
637 decor_event *gtkwd_event,
638 decor_event_type gtkwd_type)
639{
640 frame_common_event (win, WM_MOVERESIZE_SIZE_BOTTOMRIGHT,
641 gtkwd_event, gtkwd_type);
642}
643
644void
645frame_window_realized (GtkWidget *widget,
646 gpointer data)
647{
648 decor_t *d = (decor_t *) data;
649
650 if (d)
651 {
652 GdkWindow *gdk_frame_window = gtk_widget_get_window (d->decor_window);
653 gdk_window_reparent (gdk_frame_window, d->frame_window, 0, 0);
654 gdk_window_lower (gdk_frame_window);
655
656 }
657}
658
659event_callback
660find_event_callback_for_point (decor_t *d,
661 int x,
662 int y,
663 Bool *enter,
664 Bool *leave,
665 BoxPtr *entered_box)
666{
667 int i, j;
668 BoxPtr box;
669
670 for (i = 0; i < BUTTON_NUM; i++)
671 {
672 box = &d->button_windows[i].pos;
673 if (x >= box->x1 && x <= box->x2 &&
674 y >= box->y1 && y <= box->y2)
675 {
676 if (d->last_pos_entered != box)
677 {
678 if (enter)
679 *enter = TRUE;
680 if (leave && d->last_pos_entered)
681 *leave = TRUE;
682 if (entered_box)
683 *entered_box = box;
684 }
685 return d->button_windows[i].callback;
686 }
687 }
688
689 for (i = 0; i < 3; i++)
690 {
691 for (j = 0; j < 3; j++)
692 {
693 box = &d->event_windows[i][j].pos;
694 if (x >= box->x1 && x <= box->x2 &&
695 y >= box->y1 && y <= box->y2)
696 {
697 if (d->last_pos_entered != box)
698 {
699 if (enter)
700 *enter = TRUE;
701 if (leave && d->last_pos_entered)
702 *leave = TRUE;
703 if (entered_box)
704 *entered_box = box;
705 }
706 return d->event_windows[i][j].callback;
707 }
708 }
709 }
710
711 return NULL;
712}
713
714event_callback
715find_leave_event_callback (decor_t *d)
716{
717 int i, j;
718
719 for (i = 0; i < BUTTON_NUM; i++)
720 {
721 if (d->last_pos_entered == &d->button_windows[i].pos)
722 return d->button_windows[i].callback;
723 }
724
725 for (i = 0; i < 3; i++)
726 {
727 for (j = 0; j < 3; j++)
728 {
729 if (d->last_pos_entered == &d->event_windows[i][j].pos)
730 return d->event_windows[i][j].callback;
731 }
732 }
733
734 return NULL;
735}
736
737void
738frame_handle_button_press (GtkWidget *widget,
739 GdkEventButton *event,
740 gpointer user_data)
741{
742 decor_t *d = (decor_t *) user_data;
743
744 if (d)
745 {
746 /* Check to see where the event happened and fill out an appropriate
747 * struct
748 */
749 event_callback cb;
750
751 cb = find_event_callback_for_point (d, event->x, event->y,
752 NULL, NULL, NULL);
753
754 if (cb && d->decorated)
755 {
756 decor_event gtkwd_event;
757
758 gtkwd_event.window = GDK_WINDOW_XID (d->frame_window);
759 gtkwd_event.button = event->button;
760 gtkwd_event.x = event->x;
761 gtkwd_event.y = event->y;
762 gtkwd_event.x_root = event->x_root;
763 gtkwd_event.y_root = event->y_root;
764 gtkwd_event.time = event->time;
765
766 (*cb) (d->win, &gtkwd_event, GButtonPress);
767 }
768 }
769}
770
771void
772frame_handle_button_release (GtkWidget *widget,
773 GdkEventButton *event,
774 gpointer user_data)
775{
776 decor_t *d = (decor_t *) user_data;
777
778 if (d)
779 {
780 event_callback cb;
781
782 cb = find_event_callback_for_point (d, event->x, event->y,
783 NULL, NULL, NULL);
784
785 if (cb && d->decorated)
786 {
787 decor_event gtkwd_event;
788
789 gtkwd_event.window = GDK_WINDOW_XID (d->frame_window);
790 gtkwd_event.button = event->button;
791 gtkwd_event.x = event->x;
792 gtkwd_event.y = event->y;
793 gtkwd_event.x_root = event->x_root;
794 gtkwd_event.y_root = event->y_root;
795 gtkwd_event.time = event->time;
796
797 (*cb) (d->win, &gtkwd_event, GButtonRelease);
798 }
799 }
800}
801
802void
803frame_handle_motion (GtkWidget *widget,
804 GdkEventMotion *event,
805 gpointer user_data)
806{
807 decor_t *d = (decor_t *) user_data;
808
809 if (d)
810 {
811 event_callback cb = NULL;
812 Bool send_enter = FALSE;
813 Bool send_leave = FALSE;
814 BoxPtr entered_box;
815
816 cb = find_event_callback_for_point (d, event->x, event->y,
817 &send_enter, &send_leave,
818 &entered_box);
819
820 if (cb && d->decorated)
821 {
822 decor_event gtkwd_event;
823
824 gtkwd_event.window = GDK_WINDOW_XID (d->frame_window);
825 gtkwd_event.x = event->x;
826 gtkwd_event.y = event->y;
827 gtkwd_event.x_root = event->x_root;
828 gtkwd_event.y_root = event->y_root;
829 gtkwd_event.time = event->time;
830
831 if (send_enter)
832 (*cb) (d->win, &gtkwd_event, GEnterNotify);
833
834 if (send_leave)
835 {
836 event_callback leave_cb;
837
838 leave_cb = find_leave_event_callback (d);
839
840 if (leave_cb)
841 (*leave_cb) (d->win, &gtkwd_event, GLeaveNotify);
842
843 }
844
845 if (send_enter)
846 d->last_pos_entered = entered_box;
847 }
848 else if (d->last_pos_entered && d->decorated)
849 {
850 /* We are not in an event / button window but last_pos_entered
851 * is still set, so send a GLeaveNotify to last_pos_entered
852 * and set it to NULL
853 */
854
855 event_callback leave_cb;
856
857 leave_cb = find_leave_event_callback (d);
858
859 if (leave_cb)
860 {
861 decor_event gtkwd_event;
862
863 gtkwd_event.window = GDK_WINDOW_XID (d->frame_window);
864 gtkwd_event.x = event->x;
865 gtkwd_event.y = event->y;
866 gtkwd_event.x_root = event->x_root;
867 gtkwd_event.y_root = event->y_root;
868 gtkwd_event.time = event->time;
869
870 (*leave_cb) (d->win, &gtkwd_event, GLeaveNotify);
871 }
872
873 d->last_pos_entered = NULL;
874 }
875 }
876}
877
878GdkFilterReturn
879event_filter_func (GdkXEvent *gdkxevent,
880 GdkEvent *event,
881 gpointer data)
882{
883 Display *xdisplay;
884 GdkDisplay *gdkdisplay;
885 XEvent *xevent = gdkxevent;
886 gulong xid = 0;
887 Window select = 0;
888
889 gdkdisplay = gdk_display_get_default ();
890 xdisplay = GDK_DISPLAY_XDISPLAY (gdkdisplay);
891
892 switch (xevent->type) {
893 case CreateNotify:
894 {
895 if (!wnck_window_get (xevent->xcreatewindow.window))
896 {
897 GdkWindow *toplevel = create_foreign_window (xevent->xcreatewindow.window);
898
899 if (toplevel)
900 {
901 gdk_window_set_events (toplevel,
902 gdk_window_get_events (toplevel) |
903 GDK_PROPERTY_CHANGE_MASK);
904
905 /* check if the window is a switcher and update accordingly */
906
907 if (get_window_prop (xevent->xcreatewindow.window, select_window_atom, &select))
908 update_switcher_window (xevent->xcreatewindow.window, select);
909 }
910 }
911 }
912 break;
913 case ButtonPress:
914 case ButtonRelease:
915 xid = (gulong)
916 g_hash_table_lookup (frame_table,
917 GINT_TO_POINTER (xevent->xbutton.window));
918 break;
919 case EnterNotify:
920 case LeaveNotify:
921 xid = (gulong)
922 g_hash_table_lookup (frame_table,
923 GINT_TO_POINTER (xevent->xcrossing.window));
924 break;
925 case MotionNotify:
926 xid = (gulong)
927 g_hash_table_lookup (frame_table,
928 GINT_TO_POINTER (xevent->xmotion.window));
929 break;
930 case PropertyNotify:
931 if (xevent->xproperty.atom == frame_input_window_atom)
932 {
933 WnckWindow *win;
934
935 xid = xevent->xproperty.window;
936
937 win = wnck_window_get (xid);
938 if (win)
939 {
940 Window frame;
941
942 if (!get_window_prop (xid, select_window_atom, &select))
943 {
944 if (get_window_prop (xid, frame_input_window_atom, &frame))
945 add_frame_window (win, frame, FALSE);
946 else
947 remove_frame_window (win);
948 }
949 }
950 }
951 if (xevent->xproperty.atom == frame_output_window_atom)
952 {
953 WnckWindow *win;
954
955 xid = xevent->xproperty.window;
956
957 win = wnck_window_get (xid);
958 if (win)
959 {
960 Window frame;
961
962 if (!get_window_prop (xid, select_window_atom, &select))
963 {
964 if (get_window_prop (xid, frame_output_window_atom, &frame))
965 add_frame_window (win, frame, TRUE);
966 else
967 remove_frame_window (win);
968 }
969 }
970 }
971 else if (xevent->xproperty.atom == compiz_shadow_info_atom ||
972 xevent->xproperty.atom == compiz_shadow_color_atom)
973 {
974 GdkScreen *g_screen = gdk_display_get_default_screen (gdkdisplay);
975 Window root = GDK_WINDOW_XWINDOW (gdk_screen_get_root_window (g_screen));
976 WnckScreen *screen;
977
978 screen = wnck_screen_get_for_root (root);
979
980 if (screen)
981 {
982 if (shadow_property_changed (screen))
983 decorations_changed (screen);
984 }
985 }
986 else if (xevent->xproperty.atom == mwm_hints_atom)
987 {
988 WnckWindow *win;
989
990 xid = xevent->xproperty.window;
991
992 win = wnck_window_get (xid);
993 if (win)
994 {
995 decor_t *d = g_object_get_data (G_OBJECT (win), "decor");
996 gboolean decorated = FALSE;
997
998 if (get_mwm_prop (xid) & (MWM_DECOR_ALL | MWM_DECOR_TITLE))
999 decorated = TRUE;
1000
1001 if (decorated != d->decorated)
1002 {
1003 d->decorated = decorated;
1004 if (decorated)
1005 {
1006 d->context = NULL;
1007 d->width = d->height = 0;
1008
1009 d->frame = gwd_get_decor_frame (get_frame_type (win));
1010
1011 update_window_decoration_size (win);
1012 update_event_windows (win);
1013 }
1014 else
1015 {
1016 gwd_decor_frame_unref (d->frame);
1017 d->frame = NULL;
1018
1019 gdk_error_trap_push ();
1020 XDeleteProperty (xdisplay, xid, win_decor_atom);
1021 gdk_display_sync (gdk_display_get_default ());
1022 gdk_error_trap_pop ();
1023 }
1024 }
1025 }
1026 }
1027 else if (xevent->xproperty.atom == select_window_atom)
1028 {
1029 Window select;
1030
1031 if (get_window_prop (xevent->xproperty.window, select_window_atom, &select))
1032 update_switcher_window (xevent->xproperty.window, select);
1033 }
1034 break;
1035 case DestroyNotify:
1036 g_hash_table_remove (frame_table,
1037 GINT_TO_POINTER (xevent->xproperty.window));
1038 break;
1039 case ClientMessage:
1040 if (xevent->xclient.message_type == toolkit_action_atom)
1041 {
1042 long action;
1043
1044 action = xevent->xclient.data.l[0];
1045 if (action == toolkit_action_window_menu_atom)
1046 {
1047 WnckWindow *win;
1048
1049 win = wnck_window_get (xevent->xclient.window);
1050 if (win)
1051 {
1052 action_menu_map (win,
1053 xevent->xclient.data.l[2],
1054 xevent->xclient.data.l[1]);
1055 }
1056 }
1057 else if (action == toolkit_action_force_quit_dialog_atom)
1058 {
1059 WnckWindow *win;
1060
1061 win = wnck_window_get (xevent->xclient.window);
1062 if (win)
1063 {
1064 if (xevent->xclient.data.l[2])
1065 show_force_quit_dialog (win,
1066 xevent->xclient.data.l[1]);
1067 else
1068 hide_force_quit_dialog (win);
1069 }
1070 }
1071 }
1072 default:
1073 break;
1074 }
1075
1076 if (xid)
1077 {
1078 WnckWindow *win;
1079
1080 win = wnck_window_get (xid);
1081 if (win)
1082 {
1083 decor_t *d = g_object_get_data (G_OBJECT (win), "decor");
1084
1085 if (d->decorated)
1086 {
1087 gint i, j;
1088 event_callback cb = NULL;
1089 Window w = xevent->xany.window;
1090
1091 for (i = 0; i < 3; i++)
1092 for (j = 0; j < 3; j++)
1093 if (d->event_windows[i][j].window == w)
1094 cb = d->event_windows[i][j].callback;
1095
1096 if (!cb)
1097 {
1098 for (i = 0; i < BUTTON_NUM; i++)
1099 if (d->button_windows[i].window == w)
1100 cb = d->button_windows[i].callback;
1101 }
1102
1103 if (cb)
1104 {
1105 decor_event gtkwd_event;
1106 decor_event_type gtkwd_type;
1107
1108 gtkwd_event.window = w;
1109
1110 switch (xevent->type)
1111 {
1112 case ButtonPress:
1113 case ButtonRelease:
1114 if (xevent->type == ButtonPress)
1115 gtkwd_type = GButtonPress;
1116 else
1117 gtkwd_type = GButtonRelease;
1118 gtkwd_event.button = xevent->xbutton.button;
1119 gtkwd_event.x = xevent->xbutton.x;
1120 gtkwd_event.y = xevent->xbutton.y;
1121 gtkwd_event.x_root = xevent->xbutton.x_root;
1122 gtkwd_event.y_root = xevent->xbutton.y_root;
1123 gtkwd_event.time = xevent->xbutton.time;
1124 break;
1125 case EnterNotify:
1126 case LeaveNotify:
1127 if (xevent->type == EnterNotify)
1128 gtkwd_type = GEnterNotify;
1129 else
1130 gtkwd_type = GLeaveNotify;
1131 gtkwd_event.x = xevent->xcrossing.x;
1132 gtkwd_event.y = xevent->xcrossing.y;
1133 gtkwd_event.x_root = xevent->xcrossing.x_root;
1134 gtkwd_event.y_root = xevent->xcrossing.y_root;
1135 gtkwd_event.time = xevent->xcrossing.time;
1136 break;
1137 default:
1138 cb = NULL;
1139 break;
1140 }
1141 if (cb)
1142 (*cb) (win, &gtkwd_event, gtkwd_type);
1143 }
1144 }
1145 }
1146 }
1147
1148 return GDK_FILTER_CONTINUE;
1149}
1150
1151GdkFilterReturn
1152selection_event_filter_func (GdkXEvent *gdkxevent,
1153 GdkEvent *event,
1154 gpointer data)
1155{
1156 Display *xdisplay;
1157 GdkDisplay *gdkdisplay;
1158 XEvent *xevent = gdkxevent;
1159 int status;
1160
1161 gdkdisplay = gdk_display_get_default ();
1162 xdisplay = GDK_DISPLAY_XDISPLAY (gdkdisplay);
1163
1164 switch (xevent->type) {
1165 case SelectionRequest:
1166 decor_handle_selection_request (xdisplay, xevent, dm_sn_timestamp);
1167 break;
1168 case SelectionClear:
1169 status = decor_handle_selection_clear (xdisplay, xevent, 0);
1170 if (status == DECOR_SELECTION_GIVE_UP)
1171 gtk_main_quit ();
1172 default:
1173 break;
1174 }
1175
1176 return GDK_FILTER_CONTINUE;
1177}
01178
=== renamed file 'gtk/window-decorator/events.c' => 'gtk/window-decorator/events.c.THIS'
=== added file 'gtk/window-decorator/forcequit.c'
--- gtk/window-decorator/forcequit.c 1970-01-01 00:00:00 +0000
+++ gtk/window-decorator/forcequit.c 2012-02-08 18:50:27 +0000
@@ -0,0 +1,201 @@
1/*
2 * Copyright © 2006 Novell, Inc.
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
18 *
19 * Author: David Reveman <davidr@novell.com>
20 *
21 * 2D Mode: Copyright © 2010 Sam Spilsbury <smspillaz@gmail.com>
22 * Frames Management: Copright © 2011 Canonical Ltd.
23 * Authored By: Sam Spilsbury <sam.spilsbury@canonical.com>
24 */
25
26#include "gtk-window-decorator.h"
27
28static char *
29get_client_machine (Window xwindow)
30{
31 Atom atom, type;
32 gulong nitems, bytes_after;
33 guchar *str = NULL;
34 int format, result;
35 char *retval;
36
37 atom = XInternAtom (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), "WM_CLIENT_MACHINE", FALSE);
38
39 gdk_error_trap_push ();
40
41 result = XGetWindowProperty (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()),
42 xwindow, atom,
43 0, G_MAXLONG,
44 FALSE, XA_STRING, &type, &format, &nitems,
45 &bytes_after, &str);
46
47 gdk_error_trap_pop ();
48
49 if (result != Success)
50 return NULL;
51
52 if (type != XA_STRING)
53 {
54 XFree (str);
55 return NULL;
56 }
57
58 retval = g_strdup ((gchar *) str);
59
60 XFree (str);
61
62 return retval;
63}
64
65static void
66kill_window (WnckWindow *win)
67{
68 WnckApplication *app;
69
70 app = wnck_window_get_application (win);
71 if (app)
72 {
73 gchar buf[257], *client_machine;
74 int pid;
75
76 pid = wnck_application_get_pid (app);
77 client_machine = get_client_machine (wnck_application_get_xid (app));
78
79 if (client_machine && pid > 0)
80 {
81 if (gethostname (buf, sizeof (buf) - 1) == 0)
82 {
83 if (strcmp (buf, client_machine) == 0)
84 kill (pid, 9);
85 }
86 }
87
88 if (client_machine)
89 g_free (client_machine);
90 }
91
92 gdk_error_trap_push ();
93 XKillClient (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), wnck_window_get_xid (win));
94 gdk_display_sync (gdk_display_get_default ());
95 gdk_error_trap_pop ();
96}
97
98static void
99force_quit_dialog_realize (GtkWidget *dialog,
100 void *data)
101{
102 WnckWindow *win = data;
103
104 gdk_error_trap_push ();
105 XSetTransientForHint (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()),
106 GDK_WINDOW_XID (dialog->window),
107 wnck_window_get_xid (win));
108 gdk_display_sync (gdk_display_get_default ());
109 gdk_error_trap_pop ();
110}
111
112static void
113force_quit_dialog_response (GtkWidget *dialog,
114 gint response,
115 void *data)
116{
117 WnckWindow *win = data;
118 decor_t *d = g_object_get_data (G_OBJECT (win), "decor");
119
120 if (response == GTK_RESPONSE_ACCEPT)
121 kill_window (win);
122
123 if (d->force_quit_dialog)
124 {
125 d->force_quit_dialog = NULL;
The diff has been truncated for viewing.

Subscribers

People subscribed via source and target branches