~brandontschaefer/unity/bump-to-new-nux-abi

3566.5.24 by Marco Trevisan (Treviño)
CompizUtils: add some utilities to handle cairo textures in unity trough compiz
1
// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
2
/*
3806.12.23 by Marco Trevisan (Treviño)
CompizUtils: add WindowDecorationElements that returns a bitset describing the elements available
3
* Copyright (C) 2013-2014 Canonical Ltd
3566.5.24 by Marco Trevisan (Treviño)
CompizUtils: add some utilities to handle cairo textures in unity trough compiz
4
*
5
* This program is free software: you can redistribute it and/or modify
6
* it under the terms of the GNU General Public License version 3 as
7
* published by the Free Software Foundation.
8
*
9
* This program 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
12
* GNU General Public License for more details.
13
*
14
* You should have received a copy of the GNU General Public License
15
* along with this program.  If not, see <http://www.gnu.org/licenses/>.
16
*
17
* Authored by: Marco Trevisan <marco.trevisan@canonical.com>
18
*/
19
20
#include "CompizUtils.h"
21
#include <cairo-xlib.h>
22
#include <cairo-xlib-xrender.h>
23
#include <core/screen.h>
24
25
namespace unity
26
{
27
namespace compiz_utils
28
{
29
namespace
30
{
3566.7.10 by Brandon Schaefer
* Update the window button scale
31
  const unsigned PIXMAP_DEPTH  = 32;
32
  const float    DEFAULT_SCALE = 1.0f;
3806.12.23 by Marco Trevisan (Treviño)
CompizUtils: add WindowDecorationElements that returns a bitset describing the elements available
33
  const unsigned DECORABLE_WINDOW_TYPES = CompWindowTypeDialogMask |
34
                                          CompWindowTypeModalDialogMask |
35
                                          CompWindowTypeUtilMask |
36
                                          CompWindowTypeMenuMask |
37
                                          CompWindowTypeNormalMask;
3566.5.24 by Marco Trevisan (Treviño)
CompizUtils: add some utilities to handle cairo textures in unity trough compiz
38
}
39
3566.5.41 by Marco Trevisan (Treviño)
CompizUtils: add SimpleTexture base class and use it in SimpleTextureQuad (it was PixmapTextureQuad)
40
SimpleTexture::SimpleTexture(GLTexture::List const& tex)
41
  : texture_(tex)
42
{}
43
44
//
45
3566.7.10 by Brandon Schaefer
* Update the window button scale
46
SimpleTextureQuad::SimpleTextureQuad()
3806.12.11 by Marco Trevisan (Treviño)
CompizUtils: avoid matrix updates when only a texture size changes
47
  : scale_(DEFAULT_SCALE)
3566.5.418 by Marco Trevisan (Treviño)
Merging with Brandon's HiDPI stuff
48
{}
49
3566.5.325 by Marco Trevisan (Treviño)
CompizUtils: return a bool on all the Set functions (if anything changed)
50
bool SimpleTextureQuad::SetTexture(SimpleTexture::Ptr const& simple_texture)
3566.5.41 by Marco Trevisan (Treviño)
CompizUtils: add SimpleTexture base class and use it in SimpleTextureQuad (it was PixmapTextureQuad)
51
{
3566.5.325 by Marco Trevisan (Treviño)
CompizUtils: return a bool on all the Set functions (if anything changed)
52
  if (st == simple_texture)
53
    return false;
54
3566.5.41 by Marco Trevisan (Treviño)
CompizUtils: add SimpleTexture base class and use it in SimpleTextureQuad (it was PixmapTextureQuad)
55
  st = simple_texture;
56
57
  if (st && st->texture())
58
  {
59
    auto* tex = st->texture();
3806.12.11 by Marco Trevisan (Treviño)
CompizUtils: avoid matrix updates when only a texture size changes
60
    CompSize size(tex->width() * scale_, tex->height() * scale_);
61
62
    if (quad.box.width() != size.width() || quad.box.height() != size.height())
63
    {
64
      quad.box.setSize(size);
65
      UpdateMatrix();
66
    }
3566.5.41 by Marco Trevisan (Treviño)
CompizUtils: add SimpleTexture base class and use it in SimpleTextureQuad (it was PixmapTextureQuad)
67
  }
3566.5.325 by Marco Trevisan (Treviño)
CompizUtils: return a bool on all the Set functions (if anything changed)
68
69
  return true;
3566.5.41 by Marco Trevisan (Treviño)
CompizUtils: add SimpleTexture base class and use it in SimpleTextureQuad (it was PixmapTextureQuad)
70
}
71
3806.12.11 by Marco Trevisan (Treviño)
CompizUtils: avoid matrix updates when only a texture size changes
72
bool SimpleTextureQuad::SetScale(double s)
3566.5.418 by Marco Trevisan (Treviño)
Merging with Brandon's HiDPI stuff
73
{
3806.12.11 by Marco Trevisan (Treviño)
CompizUtils: avoid matrix updates when only a texture size changes
74
  if (!st || scale_ == s)
3566.5.418 by Marco Trevisan (Treviño)
Merging with Brandon's HiDPI stuff
75
    return false;
76
3806.12.11 by Marco Trevisan (Treviño)
CompizUtils: avoid matrix updates when only a texture size changes
77
  scale_ = s;
3566.5.427 by Marco Trevisan (Treviño)
CompizUtils: update the geometry size when setting the scale
78
  auto* tex = st->texture();
3806.12.11 by Marco Trevisan (Treviño)
CompizUtils: avoid matrix updates when only a texture size changes
79
  quad.box.setWidth(tex->width() * scale_);
80
  quad.box.setHeight(tex->height() * scale_);
3566.5.418 by Marco Trevisan (Treviño)
Merging with Brandon's HiDPI stuff
81
  UpdateMatrix();
82
  return true;
83
}
84
3566.5.325 by Marco Trevisan (Treviño)
CompizUtils: return a bool on all the Set functions (if anything changed)
85
bool SimpleTextureQuad::SetCoords(int x, int y)
3566.5.41 by Marco Trevisan (Treviño)
CompizUtils: add SimpleTexture base class and use it in SimpleTextureQuad (it was PixmapTextureQuad)
86
{
3566.5.144 by Marco Trevisan (Treviño)
CompizUtils: avoid some computations if new values are equal to old ones
87
  if (x == quad.box.x() && y == quad.box.y())
3566.5.325 by Marco Trevisan (Treviño)
CompizUtils: return a bool on all the Set functions (if anything changed)
88
    return false;
3566.5.144 by Marco Trevisan (Treviño)
CompizUtils: avoid some computations if new values are equal to old ones
89
3566.5.41 by Marco Trevisan (Treviño)
CompizUtils: add SimpleTexture base class and use it in SimpleTextureQuad (it was PixmapTextureQuad)
90
  quad.box.setX(x);
91
  quad.box.setY(y);
3566.7.10 by Brandon Schaefer
* Update the window button scale
92
  UpdateMatrix();
3566.5.418 by Marco Trevisan (Treviño)
Merging with Brandon's HiDPI stuff
93
  return true;
3566.7.10 by Brandon Schaefer
* Update the window button scale
94
}
95
96
void SimpleTextureQuad::UpdateMatrix()
97
{
98
  int x = quad.box.x();
99
  int y = quad.box.y();
100
3566.5.41 by Marco Trevisan (Treviño)
CompizUtils: add SimpleTexture base class and use it in SimpleTextureQuad (it was PixmapTextureQuad)
101
  quad.matrix = (st && st->texture()) ? st->texture()->matrix() : GLTexture::Matrix();
3806.12.11 by Marco Trevisan (Treviño)
CompizUtils: avoid matrix updates when only a texture size changes
102
  quad.matrix.xx /= scale_;
103
  quad.matrix.yy /= scale_;
3566.5.41 by Marco Trevisan (Treviño)
CompizUtils: add SimpleTexture base class and use it in SimpleTextureQuad (it was PixmapTextureQuad)
104
  quad.matrix.x0 = 0.0f - COMP_TEX_COORD_X(quad.matrix, x);
105
  quad.matrix.y0 = 0.0f - COMP_TEX_COORD_Y(quad.matrix, y);
3566.5.325 by Marco Trevisan (Treviño)
CompizUtils: return a bool on all the Set functions (if anything changed)
106
}
107
108
bool SimpleTextureQuad::SetX(int x)
109
{
110
  return SetCoords(x, quad.box.y());
111
}
112
113
bool SimpleTextureQuad::SetY(int y)
114
{
115
  return SetCoords(quad.box.x(), y);
3566.5.50 by Marco Trevisan (Treviño)
CompizUtils: add more utility functions and compile guard
116
}
117
3566.5.41 by Marco Trevisan (Treviño)
CompizUtils: add SimpleTexture base class and use it in SimpleTextureQuad (it was PixmapTextureQuad)
118
//
119
120
PixmapTexture::PixmapTexture(int w, int h)
3680.1.105 by Marco Trevisan (Treviño)
CompizUtils: don't try to create a pixmap with invalid size
121
 : pixmap_(0)
3566.5.41 by Marco Trevisan (Treviño)
CompizUtils: add SimpleTexture base class and use it in SimpleTextureQuad (it was PixmapTextureQuad)
122
{
3680.1.105 by Marco Trevisan (Treviño)
CompizUtils: don't try to create a pixmap with invalid size
123
  if (w > 0 && h > 0)
124
  {
125
    pixmap_ = XCreatePixmap(screen->dpy(), screen->root(), w, h, PIXMAP_DEPTH);
126
    texture_ = GLTexture::bindPixmapToTexture(pixmap_, w, h, PIXMAP_DEPTH);
127
  }
3566.5.41 by Marco Trevisan (Treviño)
CompizUtils: add SimpleTexture base class and use it in SimpleTextureQuad (it was PixmapTextureQuad)
128
}
3566.5.24 by Marco Trevisan (Treviño)
CompizUtils: add some utilities to handle cairo textures in unity trough compiz
129
130
PixmapTexture::~PixmapTexture()
131
{
132
  texture_.clear();
133
134
  if (pixmap_)
135
    XFreePixmap(screen->dpy(), pixmap_);
136
}
137
138
//
139
3680.1.16 by Marco Trevisan (Treviño)
CairoContext: add scale parameter
140
CairoContext::CairoContext(int w, int h, double scale)
3566.5.24 by Marco Trevisan (Treviño)
CompizUtils: add some utilities to handle cairo textures in unity trough compiz
141
  : pixmap_texture_(std::make_shared<PixmapTexture>(w, h))
142
  , surface_(nullptr)
143
  , cr_(nullptr)
144
{
145
  Screen *xscreen = ScreenOfDisplay(screen->dpy(), screen->screenNum());
146
  XRenderPictFormat* format = XRenderFindStandardFormat(screen->dpy(), PictStandardARGB32);
147
  surface_ = cairo_xlib_surface_create_with_xrender_format(screen->dpy(), pixmap_texture_->pixmap(),
148
                                                           xscreen, format, w, h);
3680.1.16 by Marco Trevisan (Treviño)
CairoContext: add scale parameter
149
  cairo_surface_set_device_scale(surface_, scale, scale);
3566.5.24 by Marco Trevisan (Treviño)
CompizUtils: add some utilities to handle cairo textures in unity trough compiz
150
151
  cr_ = cairo_create(surface_);
152
  cairo_save(cr_);
153
  cairo_set_operator(cr_, CAIRO_OPERATOR_CLEAR);
154
  cairo_paint(cr_);
155
  cairo_restore(cr_);
156
}
157
158
CairoContext::~CairoContext()
159
{
160
  if (cr_)
161
    cairo_destroy(cr_);
162
163
  if (surface_)
164
    cairo_surface_destroy(surface_);
165
}
166
167
int CairoContext::width() const
168
{
169
  return cairo_xlib_surface_get_width(surface_);
170
}
171
172
int CairoContext::height() const
173
{
174
  return cairo_xlib_surface_get_height(surface_);
175
}
3806.12.28 by Marco Trevisan (Treviño)
CompizUtils: make possible for non-rectangular windows to have edges
176
177
//
3806.12.21 by Marco Trevisan (Treviño)
CompizUtils: add missing comments
178
//
179
3884.2.1 by Marco Trevisan (Treviño)
CompizUtils: allow to filter-out unmapped windows
180
unsigned WindowDecorationElements(CompWindow* win, WindowFilter::Value wf)
3566.5.200 by Marco Trevisan (Treviño)
DecoratedWindow: move decoration support checks in CompizUtils
181
{
3806.12.23 by Marco Trevisan (Treviño)
CompizUtils: add WindowDecorationElements that returns a bitset describing the elements available
182
  unsigned elements = DecorationElement::NONE;
183
3566.5.200 by Marco Trevisan (Treviño)
DecoratedWindow: move decoration support checks in CompizUtils
184
  if (!win)
3806.12.23 by Marco Trevisan (Treviño)
CompizUtils: add WindowDecorationElements that returns a bitset describing the elements available
185
    return elements;
3566.5.200 by Marco Trevisan (Treviño)
DecoratedWindow: move decoration support checks in CompizUtils
186
3884.2.1 by Marco Trevisan (Treviño)
CompizUtils: allow to filter-out unmapped windows
187
  if (!win->isViewable() && wf == WindowFilter::NONE)
3806.12.23 by Marco Trevisan (Treviño)
CompizUtils: add WindowDecorationElements that returns a bitset describing the elements available
188
    return elements;
3566.5.200 by Marco Trevisan (Treviño)
DecoratedWindow: move decoration support checks in CompizUtils
189
190
  if (win->wmType() & (CompWindowTypeDockMask | CompWindowTypeDesktopMask))
3806.12.23 by Marco Trevisan (Treviño)
CompizUtils: add WindowDecorationElements that returns a bitset describing the elements available
191
    return elements;
3566.5.200 by Marco Trevisan (Treviño)
DecoratedWindow: move decoration support checks in CompizUtils
192
3806.12.7 by Marco Trevisan (Treviño)
CompizUtils: undecorate windows in showDesktop mode
193
  if (win->inShowDesktopMode())
3806.12.23 by Marco Trevisan (Treviño)
CompizUtils: add WindowDecorationElements that returns a bitset describing the elements available
194
    return elements;
3806.12.7 by Marco Trevisan (Treviño)
CompizUtils: undecorate windows in showDesktop mode
195
3806.12.28 by Marco Trevisan (Treviño)
CompizUtils: make possible for non-rectangular windows to have edges
196
  auto const& region = win->region();
197
  bool rectangular = (region.numRects() == 1);
198
  bool alpha = win->alpha();
199
200
  if (!rectangular && alpha) // Non-rectangular windows with alpha channel
201
    return elements;
202
203
  if (region.boundingRect() != win->geometry()) // Shaped windows
204
    return elements;
205
206
  if (rectangular)
207
    elements |= DecorationElement::SHADOW;
3806.12.23 by Marco Trevisan (Treviño)
CompizUtils: add WindowDecorationElements that returns a bitset describing the elements available
208
209
  if (!win->overrideRedirect() &&
210
      (win->type() & DECORABLE_WINDOW_TYPES) &&
3884.2.1 by Marco Trevisan (Treviño)
CompizUtils: allow to filter-out unmapped windows
211
      (win->frame() || win->hasUnmapReference() || wf == WindowFilter::UNMAPPED))
3806.12.23 by Marco Trevisan (Treviño)
CompizUtils: add WindowDecorationElements that returns a bitset describing the elements available
212
  {
213
    if (win->actions() & CompWindowActionResizeMask)
214
      elements |= DecorationElement::EDGE;
215
3806.12.28 by Marco Trevisan (Treviño)
CompizUtils: make possible for non-rectangular windows to have edges
216
    if (rectangular && (win->mwmDecor() & (MwmDecorAll | MwmDecorTitle)))
3806.12.23 by Marco Trevisan (Treviño)
CompizUtils: add WindowDecorationElements that returns a bitset describing the elements available
217
      elements |= DecorationElement::BORDER;
218
  }
219
3806.12.29 by Marco Trevisan (Treviño)
CompizUtils: don't remove shadows to windows that have Motif borders set
220
  if (alpha && !(elements & DecorationElement::BORDER) && !(win->mwmDecor() & MwmDecorBorder))
3806.12.23 by Marco Trevisan (Treviño)
CompizUtils: add WindowDecorationElements that returns a bitset describing the elements available
221
    elements &= ~DecorationElement::SHADOW;
222
223
  return elements;
224
}
225
226
bool IsWindowEdgeDecorable(CompWindow* win)
227
{
228
  return WindowDecorationElements(win) & DecorationElement::EDGE;
229
}
230
231
bool IsWindowShadowDecorable(CompWindow* win)
232
{
233
  return WindowDecorationElements(win) & DecorationElement::SHADOW;
3566.5.200 by Marco Trevisan (Treviño)
DecoratedWindow: move decoration support checks in CompizUtils
234
}
235
236
bool IsWindowFullyDecorable(CompWindow* win)
237
{
3806.12.23 by Marco Trevisan (Treviño)
CompizUtils: add WindowDecorationElements that returns a bitset describing the elements available
238
  return WindowDecorationElements(win) & DecorationElement::BORDER;
3566.5.200 by Marco Trevisan (Treviño)
DecoratedWindow: move decoration support checks in CompizUtils
239
}
240
3566.5.24 by Marco Trevisan (Treviño)
CompizUtils: add some utilities to handle cairo textures in unity trough compiz
241
} // compiz_utils namespace
242
} // unity namespace
3566.5.74 by Marco Trevisan (Treviño)
CompizUtils: define operator<< for CompRect
243
244
std::ostream& operator<<(std::ostream &os, CompRect const& r)
245
{
246
  return os << "CompRect: coords = " << r.x() << "x" << r.y() << ", size = " << r.width() << "x" << r.height();
247
}