diff options
Diffstat (limited to 'src/Shape.cc')
-rw-r--r-- | src/Shape.cc | 88 |
1 files changed, 61 insertions, 27 deletions
diff --git a/src/Shape.cc b/src/Shape.cc index 3f053a3..a073b9f 100644 --- a/src/Shape.cc +++ b/src/Shape.cc | |||
@@ -48,11 +48,10 @@ | |||
48 | 48 | ||
49 | using std::min; | 49 | using std::min; |
50 | 50 | ||
51 | namespace { | 51 | // ignore_border basically means do clip shape instead of bounding shape |
52 | 52 | FbTk::FbPixmap *Shape::createShape(bool ignore_border) { | |
53 | FbTk::FbPixmap *createShape(const FbTk::FbWindow &win, int place) { | 53 | if (m_win->window() == 0 || m_shapeplaces == 0 || |
54 | if (win.window() == 0 || place == 0 || | 54 | m_win->width() < 3 || m_win->height() < 3) |
55 | win.width() < 3 || win.height() < 3) | ||
56 | return 0; | 55 | return 0; |
57 | 56 | ||
58 | static char left_bits[] = { 0xc0, 0xf8, 0xfc, 0xfe, 0xfe, 0xfe, 0xff, 0xff }; | 57 | static char left_bits[] = { 0xc0, 0xf8, 0xfc, 0xfe, 0xfe, 0xfe, 0xff, 0xff }; |
@@ -60,9 +59,9 @@ FbTk::FbPixmap *createShape(const FbTk::FbWindow &win, int place) { | |||
60 | static char bottom_left_bits[] = { 0xff, 0xff, 0xfe, 0xfe, 0xfe, 0xfc, 0xf8, 0xc0 }; | 59 | static char bottom_left_bits[] = { 0xff, 0xff, 0xfe, 0xfe, 0xfe, 0xfc, 0xf8, 0xc0 }; |
61 | static char bottom_right_bits[] = { 0xff, 0xff, 0x7f, 0x7f, 0x7f, 0x3f, 0x1f, 0x03 }; | 60 | static char bottom_right_bits[] = { 0xff, 0xff, 0x7f, 0x7f, 0x7f, 0x3f, 0x1f, 0x03 }; |
62 | 61 | ||
63 | const int borderw = win.borderWidth(); | 62 | const int borderw = m_win->borderWidth(); |
64 | const int win_width = win.width() + 2*borderw; | 63 | const int win_width = m_win->width() + (ignore_border?0:2*borderw); |
65 | const int win_height = win.height() + 2*borderw; | 64 | const int win_height = m_win->height() + (ignore_border?0:2*borderw); |
66 | const int pixmap_width = min(8, win_width); | 65 | const int pixmap_width = min(8, win_width); |
67 | const int pixmap_height = min(8, win_height); | 66 | const int pixmap_height = min(8, win_height); |
68 | 67 | ||
@@ -77,7 +76,7 @@ FbTk::FbPixmap *createShape(const FbTk::FbWindow &win, int place) { | |||
77 | memset(data, 0xFF, data_size); | 76 | memset(data, 0xFF, data_size); |
78 | 77 | ||
79 | XImage *ximage = XCreateImage(disp, | 78 | XImage *ximage = XCreateImage(disp, |
80 | DefaultVisual(disp, win.screenNumber()), | 79 | DefaultVisual(disp, m_win->screenNumber()), |
81 | 1, | 80 | 1, |
82 | XYPixmap, 0, | 81 | XYPixmap, 0, |
83 | data, | 82 | data, |
@@ -90,7 +89,7 @@ FbTk::FbPixmap *createShape(const FbTk::FbWindow &win, int place) { | |||
90 | 89 | ||
91 | // shape corners | 90 | // shape corners |
92 | 91 | ||
93 | if (place & Shape::TOPLEFT) { | 92 | if (m_shapeplaces & Shape::TOPLEFT) { |
94 | for (int y=0; y<pixmap_height; y++) { | 93 | for (int y=0; y<pixmap_height; y++) { |
95 | for (int x=0; x<pixmap_width; x++) { | 94 | for (int x=0; x<pixmap_width; x++) { |
96 | XPutPixel(ximage, x, y, (left_bits[y] & (0x01 << x)) ? 1 : 0); | 95 | XPutPixel(ximage, x, y, (left_bits[y] & (0x01 << x)) ? 1 : 0); |
@@ -98,7 +97,7 @@ FbTk::FbPixmap *createShape(const FbTk::FbWindow &win, int place) { | |||
98 | } | 97 | } |
99 | } | 98 | } |
100 | 99 | ||
101 | if (place & Shape::TOPRIGHT) { | 100 | if (m_shapeplaces & Shape::TOPRIGHT) { |
102 | for (int y=0; y<pixmap_height; y++) { | 101 | for (int y=0; y<pixmap_height; y++) { |
103 | for (int x=0; x<pixmap_width; x++) { | 102 | for (int x=0; x<pixmap_width; x++) { |
104 | XPutPixel(ximage, x + win_width - pixmap_width, y, | 103 | XPutPixel(ximage, x + win_width - pixmap_width, y, |
@@ -107,7 +106,7 @@ FbTk::FbPixmap *createShape(const FbTk::FbWindow &win, int place) { | |||
107 | } | 106 | } |
108 | } | 107 | } |
109 | 108 | ||
110 | if (place & Shape::BOTTOMLEFT) { | 109 | if (m_shapeplaces & Shape::BOTTOMLEFT) { |
111 | for (int y=0; y<pixmap_height; y++) { | 110 | for (int y=0; y<pixmap_height; y++) { |
112 | for (int x=0; x<pixmap_width; x++) { | 111 | for (int x=0; x<pixmap_width; x++) { |
113 | XPutPixel(ximage, x, y + win_height - pixmap_height, | 112 | XPutPixel(ximage, x, y + win_height - pixmap_height, |
@@ -116,7 +115,7 @@ FbTk::FbPixmap *createShape(const FbTk::FbWindow &win, int place) { | |||
116 | } | 115 | } |
117 | } | 116 | } |
118 | 117 | ||
119 | if (place & Shape::BOTTOMRIGHT) { | 118 | if (m_shapeplaces & Shape::BOTTOMRIGHT) { |
120 | for (int y=0; y<pixmap_height; y++) { | 119 | for (int y=0; y<pixmap_height; y++) { |
121 | for (int x=0; x<pixmap_width; x++) { | 120 | for (int x=0; x<pixmap_width; x++) { |
122 | XPutPixel(ximage, x + win_width - pixmap_width, y + win_height - pixmap_height, | 121 | XPutPixel(ximage, x + win_width - pixmap_width, y + win_height - pixmap_height, |
@@ -125,7 +124,7 @@ FbTk::FbPixmap *createShape(const FbTk::FbWindow &win, int place) { | |||
125 | } | 124 | } |
126 | } | 125 | } |
127 | 126 | ||
128 | FbTk::FbPixmap *pm = new FbTk::FbPixmap(win, win_width, win_height, 1); | 127 | FbTk::FbPixmap *pm = new FbTk::FbPixmap(*m_win, win_width, win_height, 1); |
129 | 128 | ||
130 | 129 | ||
131 | FbTk::GContext gc(*pm); | 130 | FbTk::GContext gc(*pm); |
@@ -139,13 +138,12 @@ FbTk::FbPixmap *createShape(const FbTk::FbWindow &win, int place) { | |||
139 | 138 | ||
140 | } | 139 | } |
141 | 140 | ||
142 | } // end anonymous namespace | ||
143 | |||
144 | Shape::Shape(FbTk::FbWindow &win, int shapeplaces): | 141 | Shape::Shape(FbTk::FbWindow &win, int shapeplaces): |
145 | m_win(&win), | 142 | m_win(&win), |
146 | m_shapeplaces(shapeplaces) { | 143 | m_shapeplaces(shapeplaces) { |
147 | 144 | ||
148 | m_shape.reset(createShape(win, shapeplaces)); | 145 | m_clipshape.reset(createShape(true)); |
146 | m_boundingshape.reset(createShape(false)); | ||
149 | } | 147 | } |
150 | 148 | ||
151 | Shape::~Shape() { | 149 | Shape::~Shape() { |
@@ -155,11 +153,20 @@ Shape::~Shape() { | |||
155 | // Reset shape of window | 153 | // Reset shape of window |
156 | XShapeCombineMask(FbTk::App::instance()->display(), | 154 | XShapeCombineMask(FbTk::App::instance()->display(), |
157 | m_win->window(), | 155 | m_win->window(), |
158 | ShapeBounding, | 156 | ShapeClip, |
159 | 0, 0, | 157 | 0, 0, |
160 | 0, | 158 | 0, |
161 | ShapeSet); | 159 | ShapeSet); |
162 | } | 160 | // Reset shape of window |
161 | if (m_boundingshape.get()) { | ||
162 | XShapeCombineMask(FbTk::App::instance()->display(), | ||
163 | m_win->window(), | ||
164 | ShapeBounding, | ||
165 | 0, 0, | ||
166 | 0, | ||
167 | ShapeSet); | ||
168 | } | ||
169 | } | ||
163 | #endif // SHAPE | 170 | #endif // SHAPE |
164 | } | 171 | } |
165 | 172 | ||
@@ -171,19 +178,38 @@ void Shape::update() { | |||
171 | if (m_win == 0 || m_win->window() == 0) | 178 | if (m_win == 0 || m_win->window() == 0) |
172 | return; | 179 | return; |
173 | #ifdef SHAPE | 180 | #ifdef SHAPE |
174 | if (m_shape.get() == 0 || | 181 | if (m_clipshape.get() == 0 || |
175 | m_win->width() != width() || | 182 | m_win->width() != clipWidth() || |
176 | m_win->height() != height()) { | 183 | m_win->height() != clipHeight()) { |
177 | m_shape.reset(createShape(*m_win, m_shapeplaces)); | 184 | m_clipshape.reset(createShape(true)); |
185 | } | ||
186 | if (m_boundingshape.get() == 0 || | ||
187 | (m_win->width()+m_win->borderWidth()*2) != width() || | ||
188 | (m_win->height()+m_win->borderWidth()*2) != height()) { | ||
189 | if (m_win->borderWidth() != 0) | ||
190 | m_boundingshape.reset(createShape(false)); | ||
191 | else | ||
192 | m_boundingshape.reset(0); | ||
193 | |||
178 | } | 194 | } |
179 | 195 | ||
180 | // the m_shape can be = 0 which will just reset the shape mask | 196 | // the m_shape can be = 0 which will just raeset the shape mask |
197 | // and make the window normal | ||
198 | XShapeCombineMask(FbTk::App::instance()->display(), | ||
199 | m_win->window(), | ||
200 | ShapeClip, | ||
201 | 0, 0, | ||
202 | (m_clipshape.get() != 0)? m_clipshape->drawable() : 0, | ||
203 | ShapeSet); | ||
204 | |||
205 | // the m_shape can be = 0 which will just raeset the shape mask | ||
181 | // and make the window normal | 206 | // and make the window normal |
182 | XShapeCombineMask(FbTk::App::instance()->display(), | 207 | XShapeCombineMask(FbTk::App::instance()->display(), |
183 | m_win->window(), | 208 | m_win->window(), |
184 | ShapeBounding, | 209 | ShapeBounding, |
185 | -m_win->borderWidth(), -m_win->borderWidth(), | 210 | -m_win->borderWidth(), -m_win->borderWidth(), |
186 | m_shape.get() ? m_shape->drawable() : 0, | 211 | (m_boundingshape.get() != 0)? m_boundingshape->drawable() : |
212 | ((m_clipshape.get() != 0)? m_clipshape->drawable(): 0), | ||
187 | ShapeSet); | 213 | ShapeSet); |
188 | 214 | ||
189 | 215 | ||
@@ -223,9 +249,17 @@ bool Shape::isShaped(const FbTk::FbWindow &win) { | |||
223 | } | 249 | } |
224 | 250 | ||
225 | unsigned int Shape::width() const { | 251 | unsigned int Shape::width() const { |
226 | return m_shape.get() ? m_shape->width() : 0; | 252 | return m_boundingshape.get() ? m_boundingshape->width() : 0; |
227 | } | 253 | } |
228 | 254 | ||
229 | unsigned int Shape::height() const { | 255 | unsigned int Shape::height() const { |
230 | return m_shape.get() ? m_shape->height() : 0; | 256 | return m_boundingshape.get() ? m_boundingshape->height() : 0; |
257 | } | ||
258 | |||
259 | unsigned int Shape::clipWidth() const { | ||
260 | return m_clipshape.get() ? m_clipshape->width() : 0; | ||
261 | } | ||
262 | |||
263 | unsigned int Shape::clipHeight() const { | ||
264 | return m_clipshape.get() ? m_clipshape->height() : 0; | ||
231 | } | 265 | } |