~ubuntu-branches/ubuntu/trusty/fluxbox/trusty-proposed

« back to all changes in this revision

Viewing changes to src/Shape.cc

  • Committer: Bazaar Package Importer
  • Author(s): Dmitry E. Oboukhov
  • Date: 2008-07-01 10:38:14 UTC
  • mfrom: (2.1.12 intrepid)
  • Revision ID: james.westby@ubuntu.com-20080701103814-khx2b6il152x9p93
Tags: 1.0.0+deb1-8
* x-dev has been removed from build-depends (out-of-date package).
* Standards-Version bumped to 3.8.0.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
// Shape.cc
2
 
// Copyright (c) 2003 - 2005 Henrik Kinnunen (fluxgen at fluxbox dot org)
3
 
// 
4
 
// Permission is hereby granted, free of charge, to any person obtaining a
5
 
// copy of this software and associated documentation files (the "Software"),
6
 
// to deal in the Software without restriction, including without limitation
7
 
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
8
 
// and/or sell copies of the Software, and to permit persons to whom the
9
 
// Software is furnished to do so, subject to the following conditions:
10
 
//
11
 
// The above copyright notice and this permission notice shall be included in
12
 
// all copies or substantial portions of the Software.
13
 
//
14
 
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
 
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
 
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
17
 
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
 
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19
 
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20
 
// DEALINGS IN THE SOFTWARE.
21
 
 
22
 
// $Id: Shape.cc 3865 2005-01-24 18:34:57Z mathias $
23
 
 
24
 
#include "Shape.hh"
25
 
 
26
 
#include "FbTk/FbWindow.hh"
27
 
#include "FbTk/App.hh"
28
 
#include "FbTk/GContext.hh"
29
 
#include "FbTk/FbPixmap.hh"
30
 
 
31
 
#ifdef HAVE_CSTRING
32
 
  #include <cstring>
33
 
#else
34
 
  #include <string.h>
35
 
#endif
36
 
 
37
 
#include <X11/Xutil.h>
38
 
#ifdef HAVE_CONFIG_H
39
 
#include "config.h"
40
 
#endif // HAVE_CONFIG_H
41
 
 
42
 
#ifdef SHAPE
43
 
#include <X11/extensions/shape.h>
44
 
#endif // SHAPE
45
 
 
46
 
#include <iostream>
47
 
#include <algorithm>
48
 
using namespace std;
49
 
 
50
 
namespace {
51
 
 
52
 
FbTk::FbPixmap *createShape(const FbTk::FbWindow &win, int place) {
53
 
    if (win.window() == 0 || place == 0 || 
54
 
        win.width() < 3 || win.height() < 3)
55
 
        return 0;
56
 
    
57
 
    static char left_bits[] = { 0xc0, 0xf8, 0xfc, 0xfe, 0xfe, 0xfe, 0xff, 0xff };
58
 
    static char right_bits[] = { 0x03, 0x1f, 0x3f, 0x7f, 0x7f, 0x7f, 0xff, 0xff};
59
 
    static char bottom_left_bits[] = { 0xff, 0xff, 0xfe, 0xfe, 0xfe, 0xfc, 0xf8, 0xc0 };
60
 
    static char bottom_right_bits[] = { 0xff, 0xff, 0x7f, 0x7f, 0x7f, 0x3f, 0x1f, 0x03 };
61
 
 
62
 
    const int borderw = win.borderWidth();
63
 
    const int win_width = win.width() + 2*borderw;
64
 
    const int win_height = win.height() + 2*borderw;
65
 
    const int pixmap_width = min(8, win_width);
66
 
    const int pixmap_height = min(8, win_height);
67
 
 
68
 
    Display *disp = FbTk::App::instance()->display();
69
 
    const size_t data_size = win_width * win_height;
70
 
    // we use calloc here so we get consistent C alloc/free with XDestroyImage
71
 
    // and no warnings in valgrind :)
72
 
    char *data = (char *)calloc(data_size, sizeof (char));
73
 
    if (data == 0)
74
 
        return 0;
75
 
 
76
 
    memset(data, 0xFF, data_size);
77
 
    
78
 
    XImage *ximage = XCreateImage(disp,
79
 
                                  DefaultVisual(disp, win.screenNumber()),
80
 
                                  1,
81
 
                                  XYPixmap, 0,
82
 
                                  data,
83
 
                                  win_width, win_height,
84
 
                                  32, 0);
85
 
    if (ximage == 0)
86
 
        return 0;
87
 
 
88
 
    XInitImage(ximage);
89
 
 
90
 
    // shape corners
91
 
 
92
 
    if (place & Shape::TOPLEFT) {
93
 
        for (int y=0; y<pixmap_height; y++) {
94
 
            for (int x=0; x<pixmap_width; x++) {
95
 
                XPutPixel(ximage, x, y, (left_bits[y] & (0x01 << x)) ? 1 : 0);
96
 
            }
97
 
        }
98
 
    }
99
 
    
100
 
    if (place & Shape::TOPRIGHT) {
101
 
        for (int y=0; y<pixmap_height; y++) {
102
 
            for (int x=0; x<pixmap_width; x++) {
103
 
                XPutPixel(ximage, x + win_width - pixmap_width, y, 
104
 
                          (right_bits[y] & (0x01 << x)) ? 1 : 0);
105
 
            }     
106
 
        }
107
 
    }
108
 
    
109
 
    if (place & Shape::BOTTOMLEFT) {
110
 
        for (int y=0; y<pixmap_height; y++) {
111
 
            for (int x=0; x<pixmap_width; x++) {
112
 
                XPutPixel(ximage, x, y + win_height - pixmap_height, 
113
 
                          (bottom_left_bits[y] & (0x01 << x)) ? 1 : 0);
114
 
            }
115
 
        }
116
 
    }
117
 
 
118
 
    if (place & Shape::BOTTOMRIGHT) {
119
 
        for (int y=0; y<pixmap_height; y++) {
120
 
            for (int x=0; x<pixmap_width; x++) {
121
 
                XPutPixel(ximage, x + win_width - pixmap_width, y + win_height - pixmap_height,
122
 
                          (bottom_right_bits[y] & (0x01 << x)) ? 1 : 0);
123
 
            }
124
 
        }
125
 
    }
126
 
 
127
 
    FbTk::FbPixmap *pm = new FbTk::FbPixmap(win, win_width, win_height, 1);
128
 
 
129
 
 
130
 
    FbTk::GContext gc(*pm);
131
 
        
132
 
    XPutImage(disp, pm->drawable(), gc.gc(), ximage, 0, 0, 0, 0,
133
 
              win_width, win_height);
134
 
 
135
 
    XDestroyImage(ximage);
136
 
 
137
 
    return pm;
138
 
 
139
 
}
140
 
 
141
 
} // end anonymous namespace
142
 
 
143
 
Shape::Shape(FbTk::FbWindow &win, int shapeplaces):
144
 
    m_win(&win),
145
 
    m_shapeplaces(shapeplaces) {
146
 
 
147
 
    m_shape.reset(createShape(win, shapeplaces));
148
 
}
149
 
 
150
 
Shape::~Shape() {
151
 
 
152
 
#ifdef SHAPE
153
 
    if (m_win != 0 && m_win->window()) {
154
 
        // Reset shape of window
155
 
        XShapeCombineMask(FbTk::App::instance()->display(),
156
 
                          m_win->window(),
157
 
                          ShapeBounding,
158
 
                          0, 0,
159
 
                          0,
160
 
                          ShapeSet);
161
 
    }
162
 
#endif // SHAPE
163
 
}
164
 
 
165
 
void Shape::setPlaces(int shapeplaces) {
166
 
    m_shapeplaces = shapeplaces;
167
 
}
168
 
 
169
 
void Shape::update() {
170
 
    if (m_win == 0 || m_win->window() == 0)
171
 
        return;
172
 
#ifdef SHAPE
173
 
    if (m_shape.get() == 0 ||
174
 
        m_win->width() != width() ||
175
 
        m_win->height() != height()) {
176
 
        m_shape.reset(createShape(*m_win, m_shapeplaces));
177
 
    }
178
 
 
179
 
    // the m_shape can be = 0 which will just reset the shape mask
180
 
    // and make the window normal 
181
 
    XShapeCombineMask(FbTk::App::instance()->display(),
182
 
                      m_win->window(),
183
 
                      ShapeBounding,
184
 
                      -m_win->borderWidth(), -m_win->borderWidth(),
185
 
                      m_shape.get() ? m_shape->drawable() : 0,
186
 
                      ShapeSet);
187
 
 
188
 
 
189
 
#endif // SHAPE
190
 
 
191
 
}
192
 
 
193
 
void Shape::setWindow(FbTk::FbWindow &win) {
194
 
    m_win = &win;
195
 
    update();
196
 
}
197
 
 
198
 
void Shape::setShapeNotify(const FbTk::FbWindow &win) {
199
 
#ifdef SHAPE
200
 
    XShapeSelectInput(FbTk::App::instance()->display(), 
201
 
                      win.window(), ShapeNotifyMask);
202
 
#endif // SHAPE
203
 
}
204
 
 
205
 
bool Shape::isShaped(const FbTk::FbWindow &win) {
206
 
    int shaped = 0;
207
 
 
208
 
#ifdef SHAPE
209
 
    int not_used;
210
 
    unsigned int not_used2;
211
 
    XShapeQueryExtents(FbTk::App::instance()->display(),
212
 
                       win.window(), 
213
 
                       &shaped,  /// bShaped
214
 
                       &not_used, &not_used,  // xbs, ybs
215
 
                       &not_used2, &not_used2, // wbs, hbs
216
 
                       &not_used, // cShaped
217
 
                       &not_used, &not_used, // xcs, ycs
218
 
                       &not_used2, &not_used2); // wcs, hcs
219
 
#endif // SHAPE
220
 
 
221
 
    return (shaped != 0 ? true : false);
222
 
}
223
 
 
224
 
unsigned int Shape::width() const {
225
 
    return m_shape.get() ? m_shape->width() : 0;
226
 
}
227
 
 
228
 
unsigned int Shape::height() const {
229
 
    return m_shape.get() ? m_shape->height() : 0;
230
 
}