aboutsummaryrefslogtreecommitdiff
path: root/util/fbcompose/BaseCompWindow.cc
diff options
context:
space:
mode:
Diffstat (limited to 'util/fbcompose/BaseCompWindow.cc')
-rw-r--r--util/fbcompose/BaseCompWindow.cc258
1 files changed, 258 insertions, 0 deletions
diff --git a/util/fbcompose/BaseCompWindow.cc b/util/fbcompose/BaseCompWindow.cc
new file mode 100644
index 0000000..618a1fd
--- /dev/null
+++ b/util/fbcompose/BaseCompWindow.cc
@@ -0,0 +1,258 @@
1/** BaseCompWindow.cc file for the fluxbox compositor. */
2
3// Copyright (c) 2011 Gediminas Liktaras (gliktaras at gmail dot com)
4//
5// Permission is hereby granted, free of charge, to any person obtaining a copy
6// of this software and associated documentation files (the "Software"), to deal
7// in the Software without restriction, including without limitation the rights
8// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9// copies of the Software, and to permit persons to whom the Software is
10// furnished to do so, subject to the following conditions:
11//
12// The above copyright notice and this permission notice shall be included in
13// all copies or substantial portions of the Software.
14//
15// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21// THE SOFTWARE.
22
23
24#include "BaseCompWindow.hh"
25
26#include "Atoms.hh"
27#include "BaseScreen.hh"
28#include "Logging.hh"
29
30#include <X11/extensions/shape.h>
31#include <X11/extensions/Xcomposite.h>
32
33#include <algorithm>
34#include <ostream>
35
36using namespace FbCompositor;
37
38
39//--- CONSTRUCTORS AND DESTRUCTORS ---------------------------------------------
40
41// Constructor.
42BaseCompWindow::BaseCompWindow(const BaseScreen &screen, Window window_xid, bool track_damage_deltas) :
43 FbTk::FbWindow(window_xid),
44 m_screen(screen) {
45
46 XWindowAttributes xwa;
47 XGetWindowAttributes(display(), window(), &xwa);
48
49 m_class = xwa.c_class;
50 m_is_mapped = (xwa.map_state != IsUnmapped);
51 m_is_remapped = true;
52 m_is_resized = true;
53 m_visual = xwa.visual;
54
55 m_clip_shape_changed = true;
56 m_clip_shape_rects = 0;
57 m_clip_shape_rect_count = 0;
58
59 m_is_ignored = false;
60
61 if (m_class == InputOutput) {
62 if (track_damage_deltas) {
63 m_damage = XDamageCreate(display(), window_xid, XDamageReportDeltaRectangles);
64 } else {
65 m_damage = XDamageCreate(display(), window_xid, XDamageReportNonEmpty);
66 }
67 } else {
68 m_damage = 0;
69 }
70
71 m_content_pixmap = None;
72
73 updateAlpha();
74 updateWindowType();
75
76 XShapeSelectInput(display(), window_xid, ShapeNotifyMask);
77}
78
79// Destructor.
80BaseCompWindow::~BaseCompWindow() {
81 if (m_clip_shape_rects) {
82 XFree(m_clip_shape_rects);
83 }
84 if (m_content_pixmap) {
85 XFreePixmap(display(), m_content_pixmap);
86 }
87 // m_damage is apparently destroyed server-side.
88}
89
90
91//--- WINDOW MANIPULATION ------------------------------------------------------
92
93// Add damage to a window.
94void BaseCompWindow::addDamage() {
95 m_is_damaged = true;
96}
97
98// Mark the window as mapped.
99void BaseCompWindow::setMapped() {
100 m_is_mapped = true;
101 m_is_remapped = true;
102}
103
104// Mark the window as unmapped.
105void BaseCompWindow::setUnmapped() {
106 m_is_mapped = false;
107}
108
109// Update the window's contents.
110// Note: this is an example implementation of this function. You should not
111// call this version at any time and override it in derived classes.
112void BaseCompWindow::updateContents() {
113 updateContentPixmap();
114 if (m_clip_shape_changed) {
115 updateShape();
116 }
117
118 clearDamage();
119}
120
121// Update window's geometry.
122void BaseCompWindow::updateGeometry() {
123 unsigned int old_border_width = borderWidth();
124 unsigned int old_height = height();
125 unsigned int old_width = width();
126 FbTk::FbWindow::updateGeometry();
127
128 if ((borderWidth() != old_border_width) || (height() != old_height) || (width() != old_width)) {
129 setClipShapeChanged();
130 m_is_resized = true;
131 }
132}
133
134// Update the window's clip shape.
135void BaseCompWindow::updateShape() {
136 int rect_order;
137
138 if (m_clip_shape_rects) {
139 XFree(m_clip_shape_rects);
140 m_clip_shape_rects = NULL;
141 }
142 m_clip_shape_rects = XShapeGetRectangles(display(), window(), ShapeClip, &m_clip_shape_rect_count, &rect_order);
143
144 if (!m_clip_shape_rects) {
145 m_clip_shape_rect_count = 0;
146 } else {
147 // We have to adjust the size here to account for borders.
148 for (int i = 0; i < m_clip_shape_rect_count; i++) {
149 m_clip_shape_rects[i].height = std::min(m_clip_shape_rects[i].height + 2 * borderWidth(), realHeight());
150 m_clip_shape_rects[i].width = std::min(m_clip_shape_rects[i].width + 2 * borderWidth(), realWidth());
151 }
152 }
153}
154
155// Update window's property.
156void BaseCompWindow::updateProperty(Atom property, int /*state*/) {
157 if (property == Atoms::opacityAtom()) {
158 updateAlpha();
159 } else if (property == Atoms::windowTypeAtom()) {
160 updateWindowType();
161 }
162}
163
164
165// Set the clip shape as changed.
166void BaseCompWindow::setClipShapeChanged() {
167 m_clip_shape_changed = true;
168}
169
170
171//--- PROTECTED WINDOW MANIPULATION --------------------------------------------
172
173// Removes all damage from the window.
174void BaseCompWindow::clearDamage() {
175 m_clip_shape_changed = false;
176 m_is_damaged = false;
177 m_is_remapped = false;
178 m_is_resized = false;
179}
180
181// Updates the window's content pixmap.
182void BaseCompWindow::updateContentPixmap() {
183 // We must reset the damage here, otherwise we may miss damage events.
184 // TODO: BadDamage might be thrown here, probably safe to ignore for now.
185 XDamageSubtract(display(), m_damage, None, None);
186
187 if (m_is_resized || m_is_remapped) {
188 XGrabServer(display());
189
190 XWindowAttributes xwa;
191 if (XGetWindowAttributes(display(), window(), &xwa)) {
192 if (xwa.map_state == IsViewable) {
193 Pixmap new_pixmap = XCompositeNameWindowPixmap(display(), window());
194 if (new_pixmap) {
195 if (m_content_pixmap) {
196 XFreePixmap(display(), m_content_pixmap);
197 }
198 m_content_pixmap = new_pixmap;
199 }
200 }
201 }
202 XUngrabServer(display());
203 }
204}
205
206
207//--- PROPERTY UPDATE FUNCTIONS ----------------------------------------
208
209// Updates window's alpha.
210void BaseCompWindow::updateAlpha() {
211 m_alpha = singlePropertyValue<long>(Atoms::opacityAtom(), 0xff) & 0xff;
212}
213
214// Updates the type of the window.
215void BaseCompWindow::updateWindowType() {
216 static std::vector< std::pair<Atom, WindowType> > type_list = Atoms::windowTypeAtomList();
217 Atom raw_type = singlePropertyValue<Atom>(Atoms::windowTypeAtom(), None);
218
219 m_type = WinType_Normal;
220 for (size_t i = 0; i < type_list.size(); i++) {
221 if (raw_type == type_list[i].first) {
222 m_type = type_list[i].second;
223 break;
224 }
225 }
226}
227
228
229//--- CONVENIENCE FUNCTIONS ----------------------------------------------------
230
231// Reads and returns raw property contents.
232bool BaseCompWindow::rawPropertyData(Atom property_atom, Atom property_type,
233 unsigned long *item_count_return, unsigned char **data_return) {
234 Atom actual_type;
235 int actual_format;
236 unsigned long bytes_left;
237
238 if (property(property_atom, 0, 0x7fffffff, False, property_type,
239 &actual_type, &actual_format, item_count_return, &bytes_left, data_return)) {
240 if (*item_count_return > 0) {
241 return true;
242 }
243 }
244
245 return false;
246}
247
248
249//--- OPERATORS ----------------------------------------------------------------
250
251// << output stream operator for the window class.
252std::ostream &FbCompositor::operator<<(std::ostream& out, const BaseCompWindow& w) {
253 out << "Window " << std::hex << w.window() << ": Geometry[" << std::dec << w.x()
254 << "," << w.y() << "," << w.width() << "," << w.height() << " " << w.borderWidth()
255 << "] Depth=" << w.depth() << " Type=" << w.type() << " Map=" << w.isMapped()
256 << " Dmg=" << w.isDamaged() << " Ignore=" << w.isIgnored();
257 return out;
258}