~jamespharaoh/ubuntu/oneiric/unity/fix-for-880672

« back to all changes in this revision

Viewing changes to .pc/debian-changes-4.8.2-0ubuntu3/plugins/unityshell/src/unityshell.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Sebastien Bacher
  • Date: 2011-08-19 18:53:28 UTC
  • Revision ID: james.westby@ubuntu.com-20110819185328-qaxk9eepjaghewu9
Tags: 4.8.2-0ubuntu4
Backport another trunk commit to fix an alt-tab segfault

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
2
 
/* Compiz unity plugin
3
 
 * unity.cpp
4
 
 *
5
 
 * Copyright (c) 2010-11 Canonical Ltd.
6
 
 *
7
 
 * This program is free software; you can redistribute it and/or
8
 
 * modify it under the terms of the GNU General Public License
9
 
 * as published by the Free Software Foundation; either version 3
10
 
 * of the License, or (at your option) any later version.
11
 
 *
12
 
 * This program is distributed in the hope that it will be useful,
13
 
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
 
 * GNU General Public License for more details.
16
 
 *
17
 
 * Your own copyright notice would go above. You are free to choose whatever
18
 
 * licence you want, just take note that some compiz code is GPL and you will
19
 
 * not be able to re-use it if you want to use a different licence.
20
 
 */
21
 
 
22
 
#include <NuxCore/Logger.h>
23
 
#include <Nux/Nux.h>
24
 
#include <Nux/HLayout.h>
25
 
#include <Nux/BaseWindow.h>
26
 
#include <Nux/WindowCompositor.h>
27
 
 
28
 
#include "IconRenderer.h"
29
 
#include "Launcher.h"
30
 
#include "LauncherIcon.h"
31
 
#include "LauncherController.h"
32
 
#include "PlacesSettings.h"
33
 
#include "GeisAdapter.h"
34
 
#include "DevicesSettings.h"
35
 
#include "PluginAdapter.h"
36
 
#include "StartupNotifyService.h"
37
 
#include "Timer.h"
38
 
#include "unityshell.h"
39
 
#include "BackgroundEffectHelper.h"
40
 
 
41
 
#include <dbus/dbus.h>
42
 
#include <dbus/dbus-glib.h>
43
 
#include <glib/gi18n-lib.h>
44
 
#include <gtk/gtk.h>
45
 
#include <gdk/gdk.h>
46
 
#include <libnotify/notify.h>
47
 
 
48
 
#include <sstream>
49
 
 
50
 
#include <core/atoms.h>
51
 
 
52
 
#include "unitya11y.h"
53
 
 
54
 
#include "ubus-server.h"
55
 
#include "UBusMessages.h"
56
 
 
57
 
#include "config.h"
58
 
 
59
 
/* FIXME: once we get a better method to add the toplevel windows to
60
 
   the accessible root object, this include would not be required */
61
 
#include "unity-util-accessible.h"
62
 
 
63
 
using namespace unity::switcher;
64
 
 
65
 
/* Set up vtable symbols */
66
 
COMPIZ_PLUGIN_20090315(unityshell, UnityPluginVTable);
67
 
 
68
 
using ::unity::logger::Timer;
69
 
 
70
 
namespace
71
 
{
72
 
 
73
 
nux::logging::Logger logger("unity.shell");
74
 
 
75
 
UnityScreen* uScreen = 0;
76
 
 
77
 
void configure_logging();
78
 
void capture_g_log_calls(const gchar* log_domain,
79
 
                         GLogLevelFlags log_level,
80
 
                         const gchar* message,
81
 
                         gpointer user_data);
82
 
gboolean is_extension_supported(const gchar* extensions, const gchar* extension);
83
 
gfloat get_opengl_version_f32(const gchar* version_string);
84
 
 
85
 
}
86
 
 
87
 
UnityScreen::UnityScreen(CompScreen* screen)
88
 
  : BaseSwitchScreen (screen)
89
 
  , PluginClassHandler <UnityScreen, CompScreen> (screen)
90
 
  , screen(screen)
91
 
  , cScreen(CompositeScreen::get(screen))
92
 
  , gScreen(GLScreen::get(screen))
93
 
  , launcher(nullptr)
94
 
  , controller(nullptr)
95
 
  , panelController(nullptr)
96
 
  , switcherController(nullptr)
97
 
  , gestureEngine(nullptr)
98
 
  , wt(nullptr)
99
 
  , launcherWindow(nullptr)
100
 
  , panelWindow(nullptr)
101
 
  , debugger(nullptr)
102
 
  , needsRelayout(false)
103
 
  , relayoutSourceId(0)
104
 
  , _edge_trigger_handle(0)
105
 
  , _edge_pointerY(0)
106
 
  , newFocusedWindow(nullptr)
107
 
  , lastFocusedWindow(nullptr)
108
 
  , doShellRepaint(false)
109
 
  , allowWindowPaint(false)
110
 
  , damaged(false)
111
 
  , _key_nav_mode_requested(false)
112
 
  , _last_output(nullptr)
113
 
  , switcher_desktop_icon(nullptr)
114
 
  , mActiveFbo (0)
115
 
{
116
 
  Timer timer;
117
 
  configure_logging();
118
 
  LOG_DEBUG(logger) << __PRETTY_FUNCTION__;
119
 
  int (*old_handler)(Display*, XErrorEvent*);
120
 
  old_handler = XSetErrorHandler(NULL);
121
 
 
122
 
  notify_init("unityshell");
123
 
 
124
 
  g_thread_init(NULL);
125
 
  dbus_g_thread_init();
126
 
 
127
 
  unity_a11y_preset_environment();
128
 
 
129
 
  XSetErrorHandler(old_handler);
130
 
 
131
 
  /* Wrap compiz interfaces */
132
 
  ScreenInterface::setHandler(screen);
133
 
  CompositeScreenInterface::setHandler(cScreen);
134
 
  GLScreenInterface::setHandler(gScreen);
135
 
 
136
 
  PluginAdapter::Initialize(screen);
137
 
  WindowManager::SetDefault(PluginAdapter::Default());
138
 
 
139
 
  StartupNotifyService::Default()->SetSnDisplay(screen->snDisplay(), screen->screenNum());
140
 
 
141
 
  nux::NuxInitialize(0);
142
 
  wt = nux::CreateFromForeignWindow(cScreen->output(),
143
 
                                    glXGetCurrentContext(),
144
 
                                    &UnityScreen::initUnity,
145
 
                                    this);
146
 
 
147
 
  wt->RedrawRequested.connect(sigc::mem_fun(this, &UnityScreen::onRedrawRequested));
148
 
 
149
 
  unity_a11y_init(wt);
150
 
 
151
 
  /* i18n init */
152
 
  bindtextdomain(GETTEXT_PACKAGE, LOCALE_DIR);
153
 
  bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8");
154
 
 
155
 
  wt->Run(NULL);
156
 
  uScreen = this;
157
 
 
158
 
  debugger = new DebugDBusInterface(this);
159
 
 
160
 
  _edge_timeout = optionGetLauncherRevealEdgeTimeout ();
161
 
 
162
 
  if (GL::fbo)
163
 
  {
164
 
    foreach (CompOutput &o, screen->outputDevs ())
165
 
      uScreen->mFbos[&o] = UnityFBO::Ptr (new UnityFBO (&o));
166
 
    
167
 
    uScreen->mFbos[&(screen->fullscreenOutput ())] = UnityFBO::Ptr (new UnityFBO (&(screen->fullscreenOutput ())));
168
 
  }
169
 
 
170
 
  optionSetLauncherHideModeNotify(boost::bind(&UnityScreen::optionChanged, this, _1, _2));
171
 
  optionSetBacklightModeNotify(boost::bind(&UnityScreen::optionChanged, this, _1, _2));
172
 
  optionSetLaunchAnimationNotify(boost::bind(&UnityScreen::optionChanged, this, _1, _2));
173
 
  optionSetUrgentAnimationNotify(boost::bind(&UnityScreen::optionChanged, this, _1, _2));
174
 
  optionSetPanelOpacityNotify(boost::bind(&UnityScreen::optionChanged, this, _1, _2));
175
 
  optionSetLauncherOpacityNotify(boost::bind(&UnityScreen::optionChanged, this, _1, _2));
176
 
  optionSetIconSizeNotify(boost::bind(&UnityScreen::optionChanged, this, _1, _2));
177
 
  optionSetAutohideAnimationNotify(boost::bind(&UnityScreen::optionChanged, this, _1, _2));
178
 
  optionSetDashBlurExperimentalNotify(boost::bind(&UnityScreen::optionChanged, this, _1, _2));
179
 
  optionSetDevicesOptionNotify(boost::bind (&UnityScreen::optionChanged, this, _1, _2));
180
 
  optionSetShowLauncherInitiate(boost::bind(&UnityScreen::showLauncherKeyInitiate, this, _1, _2, _3));
181
 
  optionSetShowLauncherTerminate(boost::bind(&UnityScreen::showLauncherKeyTerminate, this, _1, _2, _3));
182
 
  optionSetKeyboardFocusInitiate(boost::bind(&UnityScreen::setKeyboardFocusKeyInitiate, this, _1, _2, _3));
183
 
  //optionSetKeyboardFocusTerminate (boost::bind (&UnityScreen::setKeyboardFocusKeyTerminate, this, _1, _2, _3));
184
 
  optionSetExecuteCommandInitiate(boost::bind(&UnityScreen::executeCommand, this, _1, _2, _3));
185
 
  optionSetPanelFirstMenuInitiate(boost::bind(&UnityScreen::showPanelFirstMenuKeyInitiate, this, _1, _2, _3));
186
 
  optionSetPanelFirstMenuTerminate(boost::bind(&UnityScreen::showPanelFirstMenuKeyTerminate, this, _1, _2, _3));
187
 
  optionSetLauncherRevealEdgeInitiate(boost::bind(&UnityScreen::launcherRevealEdgeInitiate, this, _1, _2, _3));
188
 
  optionSetLauncherRevealEdgeTimeoutNotify(boost::bind(&UnityScreen::optionChanged, this, _1, _2));
189
 
  optionSetAutomaximizeValueNotify(boost::bind(&UnityScreen::optionChanged, this, _1, _2));
190
 
  optionSetAltTabTimeoutNotify(boost::bind(&UnityScreen::optionChanged, this, _1, _2));
191
 
  
192
 
  optionSetAltTabForwardInitiate(boost::bind(&UnityScreen::altTabForwardInitiate, this, _1, _2, _3));
193
 
  optionSetAltTabForwardTerminate(boost::bind(&UnityScreen::altTabForwardTerminate, this, _1, _2, _3));
194
 
  
195
 
  optionSetAltTabPrevInitiate(boost::bind(&UnityScreen::altTabPrevInitiate, this, _1, _2, _3));
196
 
  optionSetAltTabPrevTerminate(boost::bind(&UnityScreen::altTabPrevTerminate, this, _1, _2, _3));
197
 
  
198
 
  optionSetAltTabDetailStartInitiate(boost::bind(&UnityScreen::altTabDetailStartInitiate, this, _1, _2, _3));
199
 
  optionSetAltTabDetailStartTerminate(boost::bind(&UnityScreen::altTabDetailStartTerminate, this, _1, _2, _3));
200
 
 
201
 
  optionSetAltTabDetailStopInitiate(boost::bind(&UnityScreen::altTabDetailStopInitiate, this, _1, _2, _3));
202
 
  optionSetAltTabDetailStopTerminate(boost::bind(&UnityScreen::altTabDetailStopTerminate, this, _1, _2, _3));
203
 
 
204
 
  optionSetAltTabNextWindowInitiate(boost::bind(&UnityScreen::altTabNextWindowInitiate, this, _1, _2, _3));
205
 
  optionSetAltTabNextWindowTerminate(boost::bind(&UnityScreen::altTabNextWindowTerminate, this, _1, _2, _3));
206
 
 
207
 
  optionSetAltTabExitInitiate(boost::bind(&UnityScreen::altTabExitInitiate, this, _1, _2, _3));
208
 
  optionSetAltTabExitTerminate(boost::bind(&UnityScreen::altTabExitTerminate, this, _1, _2, _3));
209
 
  
210
 
 
211
 
  for (unsigned int i = 0; i < G_N_ELEMENTS(_ubus_handles); i++)
212
 
    _ubus_handles[i] = 0;
213
 
 
214
 
  UBusServer* ubus = ubus_server_get_default();
215
 
  _ubus_handles[0] = ubus_server_register_interest(ubus,
216
 
                                                   UBUS_LAUNCHER_START_KEY_NAV,
217
 
                                                   (UBusCallback)&UnityScreen::OnLauncherStartKeyNav,
218
 
                                                   this);
219
 
 
220
 
  _ubus_handles[1] = ubus_server_register_interest(ubus,
221
 
                                                   UBUS_LAUNCHER_END_KEY_NAV,
222
 
                                                   (UBusCallback)&UnityScreen::OnLauncherEndKeyNav,
223
 
                                                   this);
224
 
 
225
 
  _ubus_handles[2] = ubus_server_register_interest(ubus,
226
 
                                                   UBUS_QUICKLIST_END_KEY_NAV,
227
 
                                                   (UBusCallback)&UnityScreen::OnQuicklistEndKeyNav,
228
 
                                                   this);
229
 
 
230
 
  g_timeout_add(0, &UnityScreen::initPluginActions, this);
231
 
 
232
 
  GeisAdapter::Default(screen)->Run();
233
 
  gestureEngine = new GestureEngine(screen);
234
 
 
235
 
  CompString name(PKGDATADIR"/panel-shadow.png");
236
 
  CompString pname("unityshell");
237
 
  CompSize size(1, 20);
238
 
  _shadow_texture = GLTexture::readImageToTexture(name, pname, size);
239
 
 
240
 
  ubus_manager_.RegisterInterest(UBUS_PLACE_VIEW_SHOWN, [&](GVariant* args) { dash_is_open_ = true; });
241
 
  ubus_manager_.RegisterInterest(UBUS_PLACE_VIEW_HIDDEN, [&](GVariant* args) { dash_is_open_ = false; });
242
 
 
243
 
  EnsureKeybindings();
244
 
 
245
 
  LOG_INFO(logger) << "UnityScreen constructed: " << timer.ElapsedSeconds() << "s";
246
 
}
247
 
 
248
 
UnityScreen::~UnityScreen()
249
 
{
250
 
  panelController->UnReference();
251
 
  delete controller;
252
 
  launcher->UnReference();
253
 
  launcherWindow->UnReference();
254
 
 
255
 
  notify_uninit();
256
 
 
257
 
  unity_a11y_finalize();
258
 
 
259
 
  UBusServer* ubus = ubus_server_get_default();
260
 
  for (unsigned int i = 0; i < G_N_ELEMENTS(_ubus_handles); i++)
261
 
  {
262
 
    if (_ubus_handles[i] != 0)
263
 
      ubus_server_unregister_interest(ubus, _ubus_handles[i]);
264
 
  }
265
 
 
266
 
  if (relayoutSourceId != 0)
267
 
    g_source_remove(relayoutSourceId);
268
 
 
269
 
  // Deleting the windows thread calls XCloseDisplay, which calls XSync, which
270
 
  // sits waiting for a reply.
271
 
  // delete wt;
272
 
 
273
 
  ::unity::ui::IconRenderer::DestroyTextures();
274
 
}
275
 
 
276
 
void UnityScreen::EnsureKeybindings()
277
 
{
278
 
  for (auto action : _shortcut_actions)
279
 
    screen->removeAction(action.get());
280
 
 
281
 
  _shortcut_actions.clear ();
282
 
 
283
 
  for (auto icon : *(launcher->GetModel()))
284
 
  {
285
 
    guint64 shortcut = icon->GetShortcut();
286
 
    if (shortcut == 0)
287
 
      continue;
288
 
 
289
 
    CompActionPtr action(new CompAction());
290
 
 
291
 
    CompAction::KeyBinding binding;
292
 
    std::ostringstream sout;
293
 
    sout << "<Super>" << static_cast<char>(shortcut);
294
 
    binding.fromString(sout.str());
295
 
 
296
 
    action->setKey(binding);
297
 
 
298
 
    screen->addAction(action.get());
299
 
    _shortcut_actions.push_back(action);
300
 
  }
301
 
}
302
 
 
303
 
void UnityScreen::nuxPrologue()
304
 
{
305
 
  /* Vertex lighting isn't used in Unity, we disable that state as it could have
306
 
   * been leaked by another plugin. That should theoretically be switched off
307
 
   * right after PushAttrib since ENABLE_BIT is meant to restore the LIGHTING
308
 
   * bit, but we do that here in order to workaround a bug (?) in the NVIDIA
309
 
   * drivers (lp:703140). */
310
 
  glDisable(GL_LIGHTING);
311
 
 
312
 
  /* reset matrices */
313
 
  glPushAttrib(GL_VIEWPORT_BIT | GL_ENABLE_BIT |
314
 
               GL_TEXTURE_BIT | GL_COLOR_BUFFER_BIT | GL_SCISSOR_BIT);
315
 
 
316
 
  glMatrixMode(GL_PROJECTION);
317
 
  glPushMatrix();
318
 
 
319
 
  glMatrixMode(GL_MODELVIEW);
320
 
  glPushMatrix();
321
 
 
322
 
  glGetError();
323
 
}
324
 
 
325
 
void UnityScreen::nuxEpilogue()
326
 
{
327
 
  (*GL::bindFramebuffer)(GL_FRAMEBUFFER_EXT, mActiveFbo);
328
 
 
329
 
  glMatrixMode(GL_PROJECTION);
330
 
  glLoadIdentity();
331
 
  glMatrixMode(GL_MODELVIEW);
332
 
  glLoadIdentity();
333
 
  glDepthRange(0, 1);
334
 
  glViewport(-1, -1, 2, 2);
335
 
  glRasterPos2f(0, 0);
336
 
 
337
 
  gScreen->resetRasterPos();
338
 
 
339
 
  glMatrixMode(GL_PROJECTION);
340
 
  glPopMatrix();
341
 
  glMatrixMode(GL_MODELVIEW);
342
 
  glPopMatrix();
343
 
 
344
 
  glDrawBuffer(GL_BACK);
345
 
  glReadBuffer(GL_BACK);
346
 
 
347
 
  glPopAttrib();
348
 
 
349
 
  glDisable(GL_SCISSOR_TEST);
350
 
}
351
 
 
352
 
void UnityScreen::OnLauncherHiddenChanged()
353
 
{
354
 
  if (launcher->Hidden())
355
 
    screen->addAction(&optionGetLauncherRevealEdge());
356
 
  else
357
 
    screen->removeAction(&optionGetLauncherRevealEdge());
358
 
}
359
 
 
360
 
void UnityScreen::paintPanelShadow(const GLMatrix& matrix)
361
 
{
362
 
  if (relayoutSourceId > 0)
363
 
    return;
364
 
 
365
 
  if (PluginAdapter::Default()->IsExpoActive())
366
 
    return;
367
 
 
368
 
  nuxPrologue();
369
 
 
370
 
  CompOutput* output = _last_output;
371
 
  float vc[4];
372
 
  float h = 20.0f;
373
 
  float w = 1.0f;
374
 
  float panel_h = 24.0f;
375
 
 
376
 
  float x1 = output->x();
377
 
  float y1 = panel_h;
378
 
  float x2 = x1 + output->width();
379
 
  float y2 = y1 + h;
380
 
 
381
 
  vc[0] = x1;
382
 
  vc[1] = x2;
383
 
  vc[2] = y1;
384
 
  vc[3] = y2;
385
 
 
386
 
  if (!dash_is_open_)
387
 
  {
388
 
    foreach(GLTexture * tex, _shadow_texture)
389
 
    {
390
 
      glEnable(GL_BLEND);
391
 
      glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
392
 
 
393
 
      GL::activeTexture(GL_TEXTURE0_ARB);
394
 
      tex->enable(GLTexture::Fast);
395
 
 
396
 
      glTexParameteri(tex->target(), GL_TEXTURE_WRAP_S, GL_REPEAT);
397
 
 
398
 
      glBegin(GL_QUADS);
399
 
      {
400
 
        glTexCoord2f(COMP_TEX_COORD_X(tex->matrix(), 0), COMP_TEX_COORD_Y(tex->matrix(), 0));
401
 
        glVertex2f(vc[0], vc[2]);
402
 
 
403
 
        glTexCoord2f(COMP_TEX_COORD_X(tex->matrix(), 0), COMP_TEX_COORD_Y(tex->matrix(), h));
404
 
        glVertex2f(vc[0], vc[3]);
405
 
 
406
 
        glTexCoord2f(COMP_TEX_COORD_X(tex->matrix(), w), COMP_TEX_COORD_Y(tex->matrix(), h));
407
 
        glVertex2f(vc[1], vc[3]);
408
 
 
409
 
        glTexCoord2f(COMP_TEX_COORD_X(tex->matrix(), w), COMP_TEX_COORD_Y(tex->matrix(), 0));
410
 
        glVertex2f(vc[1], vc[2]);
411
 
      }
412
 
      glEnd();
413
 
 
414
 
      tex->disable();
415
 
      glDisable(GL_BLEND);
416
 
    }
417
 
  }
418
 
  nuxEpilogue();
419
 
}
420
 
 
421
 
void
422
 
UnityWindow::updateIconPos (int   &wx,
423
 
                            int   &wy,
424
 
                            int   x,
425
 
                            int   y,
426
 
                            float width,
427
 
                            float height)
428
 
{
429
 
  wx = x + (last_bound.width - width) / 2;
430
 
  wy = y + (last_bound.height - height) / 2;
431
 
}
432
 
 
433
 
void UnityScreen::paintDisplay(const CompRegion& region, const GLMatrix& transform, unsigned int mask)
434
 
{
435
 
  CompOutput *output = _last_output;
436
 
 
437
 
  mFbos[output]->unbind ();
438
 
 
439
 
  /* Draw the bit of the relevant framebuffer for each output */
440
 
  mFbos[output]->paint ();
441
 
 
442
 
  nuxPrologue();
443
 
  nux::ObjectPtr<nux::IOpenGLTexture2D> device_texture = 
444
 
  nux::GetGraphicsDisplay()->GetGpuDevice()->CreateTexture2DFromID(mFbos[output]->texture(), 
445
 
  output->width(), output->height(), 1, nux::BITFMT_R8G8B8A8);
446
 
 
447
 
  nux::GetGraphicsDisplay()->GetGpuDevice()->backup_texture0_ = device_texture;
448
 
 
449
 
  nux::Geometry geo = nux::Geometry (output->x (), output->y (), output->width (), output->height ());
450
 
 
451
 
  wt->RenderInterfaceFromForeignCmd (&geo);
452
 
  nuxEpilogue();
453
 
 
454
 
if (switcherController->Visible ())
455
 
  {
456
 
    LayoutWindowList targets = switcherController->ExternalRenderTargets ();
457
 
 
458
 
    for (LayoutWindow::Ptr target : targets)
459
 
    {
460
 
      CompWindow* window = screen->findWindow(target->xid);
461
 
      UnityWindow *unity_window = UnityWindow::get (window);
462
 
 
463
 
      unity_window->paintThumbnail (target->result, target->alpha);
464
 
    }
465
 
  }
466
 
 
467
 
  doShellRepaint = false;
468
 
  damaged = false;
469
 
  BackgroundEffectHelper::updates_enabled = true;
470
 
}
471
 
 
472
 
void UnityWindow::paintThumbnail (nux::Geometry const& bounding, float alpha)
473
 
{
474
 
  GLMatrix matrix;
475
 
  matrix.toScreenSpace (UnityScreen::get (screen)->_last_output, -DEFAULT_Z_CAMERA);
476
 
 
477
 
  nux::Geometry geo = bounding;
478
 
  geo.x += 3;
479
 
  geo.width -= 6;
480
 
 
481
 
  geo.y += 3;
482
 
  geo.height -= 6;
483
 
 
484
 
  last_bound = geo;
485
 
 
486
 
  GLWindowPaintAttrib attrib = gWindow->lastPaintAttrib ();
487
 
  attrib.opacity = (GLushort) (alpha * G_MAXUSHORT);
488
 
 
489
 
  paintThumb (attrib,
490
 
              matrix,
491
 
              0,
492
 
              geo.x,
493
 
              geo.y,
494
 
              geo.width,
495
 
              geo.height,
496
 
              geo.width,
497
 
              geo.height);
498
 
}
499
 
 
500
 
/* called whenever we need to repaint parts of the screen */
501
 
bool UnityScreen::glPaintOutput(const GLScreenPaintAttrib& attrib,
502
 
                                const GLMatrix& transform,
503
 
                                const CompRegion& region,
504
 
                                CompOutput* output,
505
 
                                unsigned int mask)
506
 
{
507
 
  bool ret;
508
 
 
509
 
  /* bind the framebuffer here */
510
 
  mFbos[output]->bind ();
511
 
 
512
 
  doShellRepaint = true;
513
 
  allowWindowPaint = true;
514
 
  _last_output = output;
515
 
 
516
 
  /* glPaintOutput is part of the opengl plugin, so we need the GLScreen base class. */
517
 
  ret = gScreen->glPaintOutput(attrib, transform, region, output, mask);
518
 
 
519
 
  if (doShellRepaint)
520
 
    paintDisplay(region, transform, mask);
521
 
 
522
 
  return ret;
523
 
}
524
 
 
525
 
/* called whenever a plugin needs to paint the entire scene
526
 
 * transformed */
527
 
 
528
 
void UnityScreen::glPaintTransformedOutput(const GLScreenPaintAttrib& attrib,
529
 
                                           const GLMatrix& transform,
530
 
                                           const CompRegion& region,
531
 
                                           CompOutput* output,
532
 
                                           unsigned int mask)
533
 
{
534
 
  /* bind the framebuffer here */
535
 
  mFbos[output]->bind ();
536
 
  allowWindowPaint = false;
537
 
  /* urgh */
538
 
  gScreen->glPaintOutput(attrib, transform, region, output, mask);
539
 
}
540
 
 
541
 
void UnityScreen::preparePaint(int ms)
542
 
{
543
 
  if (BackgroundEffectHelper::blur_type == unity::BLUR_ACTIVE)
544
 
  {
545
 
    // this causes queue draws to be called, we obviously dont want to disable updates
546
 
    // because we are updating the blur, so ignore them.
547
 
    bool tmp = BackgroundEffectHelper::updates_enabled;
548
 
    BackgroundEffectHelper::QueueDrawOnOwners();
549
 
    BackgroundEffectHelper::updates_enabled = tmp;
550
 
  }
551
 
 
552
 
  cScreen->preparePaint(ms);
553
 
 
554
 
  if (damaged)
555
 
  {
556
 
    damaged = false;
557
 
    damageNuxRegions();
558
 
  }
559
 
 
560
 
}
561
 
 
562
 
/* Grab changed nux regions and add damage rects for them */
563
 
void UnityScreen::damageNuxRegions()
564
 
{
565
 
  if (damaged)
566
 
    return;
567
 
 
568
 
  std::vector<nux::Geometry> dirty = wt->GetDrawList();
569
 
  damaged = true;
570
 
 
571
 
  for (std::vector<nux::Geometry>::iterator it = dirty.begin(), end = dirty.end();
572
 
       it != end; ++it)
573
 
  {
574
 
    nux::Geometry const& geo = *it;
575
 
    cScreen->damageRegion(CompRegion(geo.x, geo.y, geo.width, geo.height));
576
 
  }
577
 
 
578
 
  nux::Geometry geo = wt->GetWindowCompositor().GetTooltipMainWindowGeometry();
579
 
  cScreen->damageRegion(CompRegion(geo.x, geo.y, geo.width, geo.height));
580
 
  cScreen->damageRegion(CompRegion(lastTooltipArea.x, lastTooltipArea.y,
581
 
                                   lastTooltipArea.width, lastTooltipArea.height));
582
 
 
583
 
  lastTooltipArea = geo;
584
 
 
585
 
  wt->ClearDrawList();
586
 
}
587
 
 
588
 
/* handle X Events */
589
 
void UnityScreen::handleEvent(XEvent* event)
590
 
{
591
 
  bool skip_other_plugins = false;
592
 
 
593
 
  switch (event->type)
594
 
  {
595
 
    case FocusIn:
596
 
    case FocusOut:
597
 
      if (event->xfocus.mode == NotifyGrab)
598
 
        PluginAdapter::Default()->OnScreenGrabbed();
599
 
      else if (event->xfocus.mode == NotifyUngrab)
600
 
        PluginAdapter::Default()->OnScreenUngrabbed();
601
 
      cScreen->damageScreen();  // evil hack
602
 
      if (_key_nav_mode_requested)
603
 
        launcher->startKeyNavMode();
604
 
      _key_nav_mode_requested = false;
605
 
      break;
606
 
    case KeyPress:
607
 
      KeySym key_sym;
608
 
      char key_string[2];
609
 
      int result;
610
 
      if ((result = XLookupString(&(event->xkey), key_string, 2, &key_sym, 0)) > 0)
611
 
      {
612
 
        key_string[result] = 0;
613
 
        skip_other_plugins = launcher->CheckSuperShortcutPressed(key_sym, event->xkey.keycode, event->xkey.state, key_string);
614
 
      }
615
 
      break;
616
 
  }
617
 
 
618
 
  // avoid further propagation (key conflict for instance)
619
 
  if (!skip_other_plugins)
620
 
    screen->handleEvent(event);
621
 
 
622
 
  if (!skip_other_plugins && screen->otherGrabExist("deco", "move", "switcher", "resize", NULL))
623
 
  {
624
 
    wt->ProcessForeignEvent(event, NULL);
625
 
  }
626
 
}
627
 
 
628
 
void UnityScreen::handleCompizEvent(const char* plugin,
629
 
                                    const char* event,
630
 
                                    CompOption::Vector& option)
631
 
{
632
 
  /*
633
 
   *  don't take into account window over launcher state during
634
 
   *  the ws switch as we can get false positives
635
 
   *  (like switching to an empty viewport while grabbing a fullscreen window)
636
 
   */
637
 
  if (strcmp(event, "start_viewport_switch") == 0)
638
 
    launcher->EnableCheckWindowOverLauncher(false);
639
 
  else if (strcmp(event, "end_viewport_switch") == 0)
640
 
  {
641
 
    // compute again the list of all window on the new viewport
642
 
    // to decide if we should or not hide the launcher
643
 
    launcher->EnableCheckWindowOverLauncher(true);
644
 
    launcher->CheckWindowOverLauncher();
645
 
  }
646
 
  screen->handleCompizEvent(plugin, event, option);
647
 
}
648
 
 
649
 
bool UnityScreen::showLauncherKeyInitiate(CompAction* action,
650
 
                                          CompAction::State state,
651
 
                                          CompOption::Vector& options)
652
 
{
653
 
  // to receive the Terminate event
654
 
  if (state & CompAction::StateInitKey)
655
 
    action->setState(action->state() | CompAction::StateTermKey);
656
 
 
657
 
  launcher->StartKeyShowLauncher();
658
 
  EnsureKeybindings ();
659
 
  return false;
660
 
}
661
 
 
662
 
bool UnityScreen::showLauncherKeyTerminate(CompAction* action,
663
 
                                           CompAction::State state,
664
 
                                           CompOption::Vector& options)
665
 
{
666
 
  launcher->EndKeyShowLauncher();
667
 
  return false;
668
 
}
669
 
 
670
 
bool UnityScreen::showPanelFirstMenuKeyInitiate(CompAction* action,
671
 
                                                CompAction::State state,
672
 
                                                CompOption::Vector& options)
673
 
{
674
 
  // to receive the Terminate event
675
 
  if (state & CompAction::StateInitKey)
676
 
    action->setState(action->state() | CompAction::StateTermKey);
677
 
 
678
 
  panelController->StartFirstMenuShow();
679
 
  return false;
680
 
}
681
 
 
682
 
bool UnityScreen::showPanelFirstMenuKeyTerminate(CompAction* action,
683
 
                                                 CompAction::State state,
684
 
                                                 CompOption::Vector& options)
685
 
{
686
 
  panelController->EndFirstMenuShow();
687
 
  return false;
688
 
}
689
 
 
690
 
gboolean UnityScreen::OnEdgeTriggerTimeout(gpointer data)
691
 
{
692
 
  UnityScreen* self = reinterpret_cast<UnityScreen*>(data);
693
 
 
694
 
  if (pointerX == 0)
695
 
  {
696
 
    if (abs(pointerY-self->_edge_pointerY) <= 5)
697
 
    {
698
 
      self->launcher->EdgeRevealTriggered();
699
 
    }
700
 
    else
701
 
    {
702
 
      /* We are still in the edge, but moving in Y, maybe we need another chance */
703
 
 
704
 
      if (abs(pointerY-self->_edge_pointerY) > 20)
705
 
      {
706
 
        /* We're quite far from the first hit spot, let's wait again */
707
 
        self->_edge_pointerY = pointerY;
708
 
        return true;
709
 
      }
710
 
      else
711
 
      {
712
 
        /* We're quite near to the first hit spot, so we can reduce our timeout */
713
 
        self->_edge_pointerY = pointerY;
714
 
        g_source_remove(self->_edge_trigger_handle);
715
 
        self->_edge_trigger_handle = g_timeout_add(self->_edge_timeout/2,
716
 
                                                   &UnityScreen::OnEdgeTriggerTimeout,
717
 
                                                   self);
718
 
        return false;
719
 
      }
720
 
    }
721
 
  }
722
 
 
723
 
  self->_edge_trigger_handle = 0;
724
 
  return false;
725
 
}
726
 
 
727
 
bool UnityScreen::launcherRevealEdgeInitiate(CompAction* action,
728
 
                                             CompAction::State state,
729
 
                                             CompOption::Vector& options)
730
 
{
731
 
  if (screen->grabbed())
732
 
    return false;
733
 
 
734
 
  if (_edge_trigger_handle)
735
 
    g_source_remove(_edge_trigger_handle);
736
 
 
737
 
  if (pointerX == 0)
738
 
  {
739
 
    _edge_pointerY = pointerY;
740
 
    _edge_trigger_handle = g_timeout_add(_edge_timeout,
741
 
                                         &UnityScreen::OnEdgeTriggerTimeout,
742
 
                                         this);
743
 
  }
744
 
 
745
 
  return false;
746
 
}
747
 
 
748
 
void UnityScreen::SendExecuteCommand()
749
 
{
750
 
  ubus_server_send_message(ubus_server_get_default(),
751
 
                           UBUS_PLACE_ENTRY_ACTIVATE_REQUEST,
752
 
                           g_variant_new("(sus)",
753
 
                                         "commands.lens",
754
 
                                         0,
755
 
                                         ""));
756
 
}
757
 
 
758
 
bool UnityScreen::executeCommand(CompAction* action,
759
 
                                 CompAction::State state,
760
 
                                 CompOption::Vector& options)
761
 
{
762
 
  SendExecuteCommand();
763
 
  return false;
764
 
}
765
 
 
766
 
void UnityScreen::restartLauncherKeyNav()
767
 
{
768
 
  // set input-focus on launcher-window and start key-nav mode
769
 
  if (newFocusedWindow != NULL)
770
 
  {
771
 
    newFocusedWindow->moveInputFocusTo();
772
 
    launcher->startKeyNavMode();
773
 
  }
774
 
}
775
 
 
776
 
void UnityScreen::startLauncherKeyNav()
777
 
{
778
 
  // get CompWindow* of launcher-window
779
 
  newFocusedWindow = screen->findWindow(launcherWindow->GetInputWindowId());
780
 
 
781
 
  // check if currently focused window isn't the launcher-window
782
 
  if (newFocusedWindow != screen->findWindow(screen->activeWindow()))
783
 
    lastFocusedWindow = screen->findWindow(screen->activeWindow());
784
 
 
785
 
  // set input-focus on launcher-window and start key-nav mode
786
 
  if (newFocusedWindow != NULL)
787
 
  {
788
 
    // Put the launcher BaseWindow at the top of the BaseWindow stack. The
789
 
    // input focus coming from the XinputWindow will be processed by the
790
 
    // launcher BaseWindow only. Then the Launcher BaseWindow will decide
791
 
    // which View will get the input focus.
792
 
    launcherWindow->PushToFront();
793
 
    newFocusedWindow->moveInputFocusTo();
794
 
  }
795
 
}
796
 
 
797
 
bool UnityScreen::setKeyboardFocusKeyInitiate(CompAction* action,
798
 
                                              CompAction::State state,
799
 
                                              CompOption::Vector& options)
800
 
{
801
 
  _key_nav_mode_requested = true;
802
 
  return false;
803
 
}
804
 
 
805
 
bool UnityScreen::altTabForwardInitiate(CompAction* action,
806
 
                                        CompAction::State state,
807
 
                                        CompOption::Vector& options)
808
 
{
809
 
  if (switcherController->Visible())
810
 
  {
811
 
    switcherController->Next();
812
 
  }
813
 
  else
814
 
  {
815
 
    std::vector<AbstractLauncherIcon*> results;
816
 
 
817
 
    if (!switcher_desktop_icon)
818
 
    {
819
 
      switcher_desktop_icon = new DesktopLauncherIcon(launcher);
820
 
      switcher_desktop_icon->SinkReference();
821
 
    }
822
 
 
823
 
    results.push_back(switcher_desktop_icon);
824
 
 
825
 
    LauncherModel::iterator it;
826
 
    for (it = launcher->GetModel()->begin(); it != launcher->GetModel()->end(); it++)
827
 
      if ((*it)->ShowInSwitcher())
828
 
        results.push_back(*it);
829
 
 
830
 
    // maybe check launcher position/hide state?
831
 
    switcherController->SetWorkspace(nux::Geometry(_primary_monitor.x + 100,
832
 
                                                   _primary_monitor.y + 100,
833
 
                                                   _primary_monitor.width - 200,
834
 
                                                   _primary_monitor.height - 200));
835
 
    switcherController->Show(SwitcherController::ALL, SwitcherController::FOCUS_ORDER, false, results);
836
 
  }
837
 
 
838
 
  action->setState(action->state() | CompAction::StateTermKey);
839
 
  return false;
840
 
}
841
 
 
842
 
bool UnityScreen::altTabForwardTerminate(CompAction* action, CompAction::State state, CompOption::Vector& options)
843
 
{
844
 
  action->setState(action->state() & (unsigned)~(CompAction::StateTermKey));
845
 
  bool accept_state = (state & CompAction::StateCancel) == 0;
846
 
  switcherController->Hide(accept_state);
847
 
  return false;
848
 
}
849
 
 
850
 
bool UnityScreen::altTabPrevInitiate(CompAction* action, CompAction::State state, CompOption::Vector& options)
851
 
{
852
 
  if (switcherController->Visible())
853
 
    switcherController->Prev();
854
 
 
855
 
  action->setState(action->state() | CompAction::StateTermKey);
856
 
  return false;
857
 
}
858
 
 
859
 
bool UnityScreen::altTabPrevTerminate(CompAction* action, CompAction::State state, CompOption::Vector& options)
860
 
{
861
 
  action->setState(action->state() & (unsigned)~(CompAction::StateTermKey));
862
 
  return false;
863
 
}
864
 
 
865
 
bool UnityScreen::altTabDetailStartInitiate(CompAction* action, CompAction::State state, CompOption::Vector& options)
866
 
{
867
 
  if (switcherController->Visible())
868
 
    switcherController->SetDetail(true);
869
 
 
870
 
  action->setState(action->state() | CompAction::StateTermKey);
871
 
  return false;
872
 
}
873
 
 
874
 
bool UnityScreen::altTabDetailStartTerminate(CompAction* action, CompAction::State state, CompOption::Vector& options)
875
 
{
876
 
  action->setState(action->state() & (unsigned)~(CompAction::StateTermKey));
877
 
  return false;
878
 
}
879
 
 
880
 
bool UnityScreen::altTabDetailStopInitiate(CompAction* action, CompAction::State state, CompOption::Vector& options)
881
 
{
882
 
  if (switcherController->Visible())
883
 
    switcherController->SetDetail(false);
884
 
 
885
 
  action->setState(action->state() | CompAction::StateTermKey);
886
 
  return false;
887
 
}
888
 
 
889
 
bool UnityScreen::altTabDetailStopTerminate(CompAction* action, CompAction::State state, CompOption::Vector& options)
890
 
{
891
 
  action->setState(action->state() & (unsigned)~(CompAction::StateTermKey));
892
 
  return false;
893
 
}
894
 
 
895
 
bool UnityScreen::altTabNextWindowInitiate(CompAction* action, CompAction::State state, CompOption::Vector& options)
896
 
{
897
 
  if (switcherController->Visible())
898
 
    switcherController->NextDetail();
899
 
 
900
 
  action->setState(action->state() | CompAction::StateTermKey);
901
 
  return false;
902
 
}
903
 
 
904
 
bool UnityScreen::altTabNextWindowTerminate(CompAction* action, CompAction::State state, CompOption::Vector& options)
905
 
{
906
 
  action->setState(action->state() & (unsigned)~(CompAction::StateTermKey));
907
 
  return false;
908
 
}
909
 
 
910
 
bool UnityScreen::altTabExitInitiate(CompAction* action, CompAction::State state, CompOption::Vector& options)
911
 
{
912
 
  switcherController->Hide(false);
913
 
  action->setState(action->state() | CompAction::StateTermKey);
914
 
  return false;
915
 
}
916
 
 
917
 
bool UnityScreen::altTabExitTerminate(CompAction* action, CompAction::State state, CompOption::Vector& options)
918
 
{
919
 
  action->setState(action->state() & (unsigned)~(CompAction::StateTermKey));
920
 
  return false;
921
 
}
922
 
 
923
 
void UnityScreen::OnLauncherStartKeyNav(GVariant* data, void* value)
924
 
{
925
 
  UnityScreen* self = reinterpret_cast<UnityScreen*>(value);
926
 
  self->startLauncherKeyNav();
927
 
}
928
 
 
929
 
void UnityScreen::OnLauncherEndKeyNav(GVariant* data, void* value)
930
 
{
931
 
  UnityScreen* self = reinterpret_cast<UnityScreen*>(value);
932
 
  bool preserve_focus = false;
933
 
 
934
 
  if (data)
935
 
  {
936
 
    preserve_focus = g_variant_get_boolean(data);
937
 
  }
938
 
 
939
 
  // Return input-focus to previously focused window (before key-nav-mode was
940
 
  // entered)
941
 
  if (preserve_focus && (self->lastFocusedWindow != NULL))
942
 
  {
943
 
    self->lastFocusedWindow->moveInputFocusTo();
944
 
  }
945
 
}
946
 
 
947
 
void UnityScreen::OnQuicklistEndKeyNav(GVariant* data, void* value)
948
 
{
949
 
  UnityScreen* self = reinterpret_cast<UnityScreen*>(value);
950
 
  self->restartLauncherKeyNav();
951
 
}
952
 
 
953
 
gboolean UnityScreen::initPluginActions(gpointer data)
954
 
{
955
 
  CompPlugin* p = CompPlugin::find("expo");
956
 
 
957
 
  if (p)
958
 
  {
959
 
    MultiActionList expoActions(0);
960
 
 
961
 
    foreach(CompOption & option, p->vTable->getOptions())
962
 
    {
963
 
      if (option.name() == "expo_key" ||
964
 
          option.name() == "expo_button" ||
965
 
          option.name() == "expo_edge")
966
 
      {
967
 
        CompAction* action = &option.value().action();
968
 
        expoActions.AddNewAction(action, false);
969
 
        break;
970
 
      }
971
 
    }
972
 
 
973
 
    PluginAdapter::Default()->SetExpoAction(expoActions);
974
 
  }
975
 
 
976
 
  p = CompPlugin::find("scale");
977
 
 
978
 
  if (p)
979
 
  {
980
 
    MultiActionList scaleActions(0);
981
 
 
982
 
    foreach(CompOption & option, p->vTable->getOptions())
983
 
    {
984
 
      if (option.name() == "initiate_all_key" ||
985
 
          option.name() == "initiate_all_edge" ||
986
 
          option.name() == "initiate_key" ||
987
 
          option.name() == "initiate_button" ||
988
 
          option.name() == "initiate_edge" ||
989
 
          option.name() == "initiate_group_key" ||
990
 
          option.name() == "initiate_group_button" ||
991
 
          option.name() == "initiate_group_edge" ||
992
 
          option.name() == "initiate_output_key" ||
993
 
          option.name() == "initiate_output_button" ||
994
 
          option.name() == "initiate_output_edge")
995
 
      {
996
 
        CompAction* action = &option.value().action();
997
 
        scaleActions.AddNewAction(action, false);
998
 
      }
999
 
      else if (option.name() == "initiate_all_button")
1000
 
      {
1001
 
        CompAction* action = &option.value().action();
1002
 
        scaleActions.AddNewAction(action, true);
1003
 
      }
1004
 
    }
1005
 
 
1006
 
    PluginAdapter::Default()->SetScaleAction(scaleActions);
1007
 
  }
1008
 
 
1009
 
  p = CompPlugin::find("unitymtgrabhandles");
1010
 
 
1011
 
  if (p)
1012
 
  {
1013
 
    foreach(CompOption & option, p->vTable->getOptions())
1014
 
    {
1015
 
      if (option.name() == "show_handles_key")
1016
 
        PluginAdapter::Default()->SetShowHandlesAction(&option.value().action());
1017
 
      else if (option.name() == "hide_handles_key")
1018
 
        PluginAdapter::Default()->SetHideHandlesAction(&option.value().action());
1019
 
      else if (option.name() == "toggle_handles_key")
1020
 
        PluginAdapter::Default()->SetToggleHandlesAction(&option.value().action());
1021
 
    }
1022
 
  }
1023
 
 
1024
 
  return FALSE;
1025
 
}
1026
 
 
1027
 
/* Set up expo and scale actions on the launcher */
1028
 
bool UnityScreen::initPluginForScreen(CompPlugin* p)
1029
 
{
1030
 
  if (p->vTable->name() == "expo" ||
1031
 
      p->vTable->name() == "scale")
1032
 
  {
1033
 
    initPluginActions(this);
1034
 
  }
1035
 
 
1036
 
  return screen->initPluginForScreen(p);
1037
 
}
1038
 
 
1039
 
void UnityScreen::AddProperties(GVariantBuilder* builder)
1040
 
{
1041
 
}
1042
 
 
1043
 
const gchar* UnityScreen::GetName()
1044
 
{
1045
 
  return "Unity";
1046
 
}
1047
 
 
1048
 
const CompWindowList& UnityScreen::getWindowPaintList()
1049
 
{
1050
 
  CompWindowList& pl = _withRemovedNuxWindows = cScreen->getWindowPaintList();
1051
 
  CompWindowList::reverse_iterator it = pl.rbegin();
1052
 
  CompWindowList::reverse_iterator end = pl.rend();
1053
 
  std::vector<Window> const& xwns = nux::XInputWindow::NativeHandleList();
1054
 
 
1055
 
  unsigned int size = xwns.size();
1056
 
 
1057
 
  while (it != end)
1058
 
  {
1059
 
    bool erased = false;
1060
 
    auto id = (*it)->id();
1061
 
    for (unsigned int i = 0; i < size; ++i)
1062
 
    {
1063
 
      if (xwns[i] == id)
1064
 
      {
1065
 
        /* Increment the reverse_iterator to ensure
1066
 
               * it is valid, then it++ returns the old
1067
 
         * position */
1068
 
        CompWindowList::reverse_iterator oit = it++;
1069
 
        /* Get the base and offset by -1 since
1070
 
         * &*(reverse_iterator(i)) == &*(i - 1)) */
1071
 
        CompWindowList::iterator eit = --(oit.base ());
1072
 
 
1073
 
        erased = true;
1074
 
 
1075
 
        /* Remove that from the list */
1076
 
        pl.erase(eit);
1077
 
        break;
1078
 
      }
1079
 
    }
1080
 
 
1081
 
    if (!erased)
1082
 
      it++;
1083
 
  }
1084
 
 
1085
 
  return pl;
1086
 
}
1087
 
 
1088
 
/* handle window painting in an opengl context
1089
 
 *
1090
 
 * we want to paint underneath other windows here,
1091
 
 * so we need to find if this window is actually
1092
 
 * stacked on top of one of the nux input windows
1093
 
 * and if so paint nux and stop us from painting
1094
 
 * other windows or on top of the whole screen */
1095
 
bool UnityWindow::glDraw(const GLMatrix& matrix,
1096
 
                         GLFragment::Attrib& attrib,
1097
 
                         const CompRegion& region,
1098
 
                         unsigned int mask)
1099
 
{
1100
 
  if (uScreen->doShellRepaint && uScreen->allowWindowPaint)
1101
 
  {
1102
 
    std::vector<Window> const& xwns = nux::XInputWindow::NativeHandleList();
1103
 
    unsigned int size = xwns.size();
1104
 
 
1105
 
    for (CompWindow* w = window; w && uScreen->doShellRepaint; w = w->prev)
1106
 
    {
1107
 
      auto id = w->id();
1108
 
      for (unsigned int i = 0; i < size; ++i)
1109
 
      {
1110
 
        if (xwns[i] == id)
1111
 
        {
1112
 
          uScreen->paintDisplay(region, matrix, mask);
1113
 
          break;
1114
 
        }
1115
 
      }
1116
 
    }
1117
 
  }
1118
 
 
1119
 
  bool ret = gWindow->glDraw(matrix, attrib, region, mask);
1120
 
 
1121
 
  if (window->type() == CompWindowTypeDesktopMask)
1122
 
  {
1123
 
    uScreen->paintPanelShadow(matrix);
1124
 
  }
1125
 
 
1126
 
  return ret;
1127
 
}
1128
 
 
1129
 
/* Called whenever a window is mapped, unmapped, minimized etc */
1130
 
void UnityWindow::windowNotify(CompWindowNotify n)
1131
 
{
1132
 
  PluginAdapter::Default()->Notify(window, n);
1133
 
  window->windowNotify(n);
1134
 
}
1135
 
 
1136
 
void UnityWindow::stateChangeNotify(unsigned int lastState)
1137
 
{
1138
 
  PluginAdapter::Default()->NotifyStateChange(window, window->state(), lastState);
1139
 
  window->stateChangeNotify(lastState);
1140
 
}
1141
 
 
1142
 
void UnityWindow::moveNotify(int x, int y, bool immediate)
1143
 
{
1144
 
  PluginAdapter::Default()->NotifyMoved(window, x, y);
1145
 
  window->moveNotify(x, y, immediate);
1146
 
}
1147
 
 
1148
 
void UnityWindow::resizeNotify(int x, int y, int w, int h)
1149
 
{
1150
 
  PluginAdapter::Default()->NotifyResized(window, x, y, w, h);
1151
 
  window->resizeNotify(x, y, w, h);
1152
 
}
1153
 
 
1154
 
CompPoint UnityWindow::tryNotIntersectLauncher(CompPoint& pos)
1155
 
{
1156
 
  UnityScreen* us = UnityScreen::get(screen);
1157
 
  nux::Geometry geo = us->launcher->GetAbsoluteGeometry();
1158
 
  CompRect launcherGeo(geo.x, geo.y, geo.width, geo.height);
1159
 
 
1160
 
  if (launcherGeo.contains(pos))
1161
 
  {
1162
 
    if (screen->workArea().contains(CompRect(launcherGeo.right() + 1, pos.y(), window->width(), window->height())))
1163
 
      pos.setX(launcherGeo.right() + 1);
1164
 
  }
1165
 
 
1166
 
  return pos;
1167
 
}
1168
 
 
1169
 
bool UnityWindow::place(CompPoint& pos)
1170
 
{
1171
 
  UnityScreen* us = UnityScreen::get(screen);
1172
 
  Launcher::LauncherHideMode hideMode = us->launcher->GetHideMode();
1173
 
 
1174
 
  bool result = window->place(pos);
1175
 
 
1176
 
  switch (hideMode)
1177
 
  {
1178
 
    case Launcher::LAUNCHER_HIDE_DODGE_WINDOWS:
1179
 
    case Launcher::LAUNCHER_HIDE_DODGE_ACTIVE_WINDOW:
1180
 
      pos = tryNotIntersectLauncher(pos);
1181
 
      break;
1182
 
 
1183
 
    default:
1184
 
      break;
1185
 
  }
1186
 
 
1187
 
  return result;
1188
 
}
1189
 
 
1190
 
/* Configure callback for the launcher window */
1191
 
void UnityScreen::launcherWindowConfigureCallback(int WindowWidth, int WindowHeight,
1192
 
                                                  nux::Geometry& geo, void* user_data)
1193
 
{
1194
 
  UnityScreen* self = reinterpret_cast<UnityScreen*>(user_data);
1195
 
  geo = nux::Geometry(self->_primary_monitor.x, self->_primary_monitor.y + 24,
1196
 
                      geo.width, self->_primary_monitor.height - 24);
1197
 
}
1198
 
 
1199
 
/* Start up nux after OpenGL is initialized */
1200
 
void UnityScreen::initUnity(nux::NThread* thread, void* InitData)
1201
 
{
1202
 
  Timer timer;
1203
 
  initLauncher(thread, InitData);
1204
 
 
1205
 
  nux::ColorLayer background(nux::color::Transparent);
1206
 
  static_cast<nux::WindowThread*>(thread)->SetWindowBackgroundPaintLayer(&background);
1207
 
  LOG_INFO(logger) << "UnityScreen::initUnity: " << timer.ElapsedSeconds() << "s";
1208
 
}
1209
 
 
1210
 
void UnityScreen::onRedrawRequested()
1211
 
{
1212
 
  // disable blur updates so we dont waste perf. This can stall the blur during animations
1213
 
  // but ensures a smooth animation.
1214
 
  BackgroundEffectHelper::updates_enabled = false;
1215
 
  damageNuxRegions();
1216
 
}
1217
 
 
1218
 
/* Handle option changes and plug that into nux windows */
1219
 
void UnityScreen::optionChanged(CompOption* opt, UnityshellOptions::Options num)
1220
 
{
1221
 
  switch (num)
1222
 
  {
1223
 
    case UnityshellOptions::LauncherHideMode:
1224
 
      launcher->SetHideMode((Launcher::LauncherHideMode) optionGetLauncherHideMode());
1225
 
      break;
1226
 
    case UnityshellOptions::BacklightMode:
1227
 
      launcher->SetBacklightMode((Launcher::BacklightMode) optionGetBacklightMode());
1228
 
      break;
1229
 
    case UnityshellOptions::LaunchAnimation:
1230
 
      launcher->SetLaunchAnimation((Launcher::LaunchAnimation) optionGetLaunchAnimation());
1231
 
      break;
1232
 
    case UnityshellOptions::UrgentAnimation:
1233
 
      launcher->SetUrgentAnimation((Launcher::UrgentAnimation) optionGetUrgentAnimation());
1234
 
      break;
1235
 
    case UnityshellOptions::PanelOpacity:
1236
 
      panelController->SetOpacity(optionGetPanelOpacity());
1237
 
      break;
1238
 
    case UnityshellOptions::LauncherOpacity:
1239
 
      launcher->SetBackgroundAlpha(optionGetLauncherOpacity());
1240
 
      break;
1241
 
    case UnityshellOptions::IconSize:
1242
 
      panelController->SetBFBSize(optionGetIconSize() + 18);
1243
 
      launcher->SetIconSize(optionGetIconSize() + 6, optionGetIconSize());
1244
 
      dashController->launcher_width = optionGetIconSize() + 18;
1245
 
      break;
1246
 
    case UnityshellOptions::AutohideAnimation:
1247
 
      launcher->SetAutoHideAnimation((Launcher::AutoHideAnimation) optionGetAutohideAnimation());
1248
 
      break;
1249
 
    case UnityshellOptions::DashBlurExperimental:
1250
 
      BackgroundEffectHelper::blur_type = (unity::BlurType)optionGetDashBlurExperimental();
1251
 
      break;
1252
 
    case UnityshellOptions::AutomaximizeValue:
1253
 
      PluginAdapter::Default()->SetCoverageAreaBeforeAutomaximize(optionGetAutomaximizeValue() / 100.0f);
1254
 
      break;
1255
 
    case UnityshellOptions::DevicesOption:
1256
 
      unity::DevicesSettings::GetDefault().SetDevicesOption((unity::DevicesSettings::DevicesOption) optionGetDevicesOption());
1257
 
      break;
1258
 
    case UnityshellOptions::LauncherRevealEdgeTimeout:
1259
 
      _edge_timeout = optionGetLauncherRevealEdgeTimeout();
1260
 
      break;
1261
 
    case UnityshellOptions::AltTabTimeout:
1262
 
      switcherController->detail_on_timeout = optionGetAltTabTimeout();
1263
 
      break;
1264
 
    default:
1265
 
      break;
1266
 
  }
1267
 
}
1268
 
 
1269
 
void UnityScreen::NeedsRelayout()
1270
 
{
1271
 
  needsRelayout = true;
1272
 
}
1273
 
 
1274
 
void UnityScreen::ScheduleRelayout(guint timeout)
1275
 
{
1276
 
  if (relayoutSourceId == 0)
1277
 
    relayoutSourceId = g_timeout_add(timeout, &UnityScreen::RelayoutTimeout, this);
1278
 
}
1279
 
 
1280
 
void UnityScreen::Relayout()
1281
 
{
1282
 
  GdkScreen* scr;
1283
 
  GdkRectangle rect;
1284
 
  nux::Geometry lCurGeom;
1285
 
  gint primary_monitor;
1286
 
  int panel_height = 24;
1287
 
 
1288
 
  if (!needsRelayout)
1289
 
    return;
1290
 
 
1291
 
  if (GL::fbo)
1292
 
  {
1293
 
    foreach (CompOutput &o, screen->outputDevs ())
1294
 
      uScreen->mFbos[&o] = UnityFBO::Ptr (new UnityFBO (&o));
1295
 
    
1296
 
    uScreen->mFbos[&(screen->fullscreenOutput ())] = UnityFBO::Ptr (new UnityFBO (&(screen->fullscreenOutput ())));
1297
 
  }
1298
 
 
1299
 
  scr = gdk_screen_get_default ();
1300
 
  primary_monitor = gdk_screen_get_primary_monitor (scr);
1301
 
  gdk_screen_get_monitor_geometry (scr, primary_monitor, &rect);
1302
 
  _primary_monitor = rect;
1303
 
 
1304
 
  wt->SetWindowSize(rect.width, rect.height);
1305
 
 
1306
 
  lCurGeom = launcherWindow->GetGeometry();
1307
 
  launcher->SetMaximumHeight(rect.height - panel_height);
1308
 
 
1309
 
  g_debug("Setting to primary screen rect: x=%d y=%d w=%d h=%d",
1310
 
          rect.x,
1311
 
          rect.y,
1312
 
          rect.width,
1313
 
          rect.height);
1314
 
 
1315
 
  launcherWindow->SetGeometry(nux::Geometry(rect.x,
1316
 
                                            rect.y + panel_height,
1317
 
                                            lCurGeom.width,
1318
 
                                            rect.height - panel_height));
1319
 
  launcher->SetGeometry(nux::Geometry(rect.x,
1320
 
                                      rect.y + panel_height,
1321
 
                                      lCurGeom.width,
1322
 
                                      rect.height - panel_height));
1323
 
  needsRelayout = false;
1324
 
}
1325
 
 
1326
 
gboolean UnityScreen::RelayoutTimeout(gpointer data)
1327
 
{
1328
 
  UnityScreen* uScr = reinterpret_cast<UnityScreen*>(data);
1329
 
 
1330
 
  uScreen->mFbos.clear ();
1331
 
 
1332
 
  uScr->NeedsRelayout ();
1333
 
  uScr->Relayout();
1334
 
  uScr->relayoutSourceId = 0;
1335
 
 
1336
 
  uScr->cScreen->damageScreen();
1337
 
 
1338
 
  return FALSE;
1339
 
}
1340
 
 
1341
 
/* Handle changes in the number of workspaces by showing the switcher
1342
 
 * or not showing the switcher */
1343
 
bool UnityScreen::setOptionForPlugin(const char* plugin, const char* name,
1344
 
                                     CompOption::Value& v)
1345
 
{
1346
 
  bool status = screen->setOptionForPlugin(plugin, name, v);
1347
 
  if (status)
1348
 
  {
1349
 
    if (strcmp(plugin, "core") == 0 && strcmp(name, "hsize") == 0)
1350
 
    {
1351
 
      controller->UpdateNumWorkspaces(screen->vpSize().width() * screen->vpSize().height());
1352
 
    }
1353
 
  }
1354
 
  return status;
1355
 
}
1356
 
 
1357
 
void UnityScreen::outputChangeNotify()
1358
 
{
1359
 
  ScheduleRelayout(500);
1360
 
}
1361
 
 
1362
 
void UnityFBO::paint ()
1363
 
{
1364
 
  //CompositeScreen *cScreen = CompositeScreen::get (screen);
1365
 
  //unsigned int    mask = cScreen->damageMask ();
1366
 
  float texx, texy, texwidth, texheight;
1367
 
 
1368
 
  /* Draw the bit of the relevant framebuffer for each output */
1369
 
  GLMatrix transform;
1370
 
 
1371
 
  glViewport (output->x (), screen->height () - output->y2 (), output->width (), output->height ());
1372
 
 
1373
 
  transform.toScreenSpace (output, -DEFAULT_Z_CAMERA);
1374
 
  glPushMatrix ();
1375
 
  glLoadMatrixf (transform.getMatrix ());
1376
 
 
1377
 
  /* Note that texcoords here are normalized, so it's just (0,0)-(1,1) */
1378
 
  texx = 0.0;
1379
 
  texy = 0.0;
1380
 
  texwidth = 1.0f;
1381
 
  texheight = 1.0f;
1382
 
 
1383
 
  if (mFBTexture)
1384
 
  {
1385
 
    glEnable (GL_TEXTURE_2D);
1386
 
    GL::activeTexture (GL_TEXTURE0_ARB);
1387
 
    glBindTexture (GL_TEXTURE_2D, mFBTexture);
1388
 
    glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1389
 
    glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1390
 
    
1391
 
    glPushAttrib (GL_SCISSOR_BIT);
1392
 
    glEnable (GL_SCISSOR_TEST);
1393
 
 
1394
 
    glScissor (output->x1 (), screen->height () - output->y2 (),
1395
 
                output->width (), output->height ());
1396
 
    
1397
 
    /* FIXME: This needs to be GL_TRIANGLE_STRIP */
1398
 
    glBegin (GL_QUADS);
1399
 
    glTexCoord2f (texx, texy + texheight);
1400
 
    glVertex2i   (output->x1 (), output->y1 ());
1401
 
    glTexCoord2f (texx, texy);
1402
 
    glVertex2i   (output->x1 (),        output->y2 ());
1403
 
    glTexCoord2f (texx + texwidth, texy);
1404
 
    glVertex2i   (output->x2 (), output->y2 ());
1405
 
    glTexCoord2f (texx + texwidth, texy + texheight);
1406
 
    glVertex2i   (output->x2 (),        output->y1 ());
1407
 
    glEnd ();
1408
 
    
1409
 
    GL::activeTexture (GL_TEXTURE0_ARB);
1410
 
    glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1411
 
    glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1412
 
    glBindTexture (GL_TEXTURE_2D, 0);
1413
 
    glEnable (GL_TEXTURE_2D);
1414
 
    
1415
 
    glDisable (GL_SCISSOR_TEST);
1416
 
    glPopAttrib ();
1417
 
  }
1418
 
 
1419
 
  glPopMatrix();
1420
 
}
1421
 
 
1422
 
void UnityFBO::unbind ()
1423
 
{
1424
 
  uScreen->setActiveFbo (0);
1425
 
  (*GL::bindFramebuffer) (GL_FRAMEBUFFER_EXT, 0);
1426
 
 
1427
 
  glDrawBuffer (GL_BACK);
1428
 
  glReadBuffer (GL_BACK);
1429
 
 
1430
 
}
1431
 
 
1432
 
bool UnityFBO::status ()
1433
 
{
1434
 
  return mFboStatus;
1435
 
}
1436
 
 
1437
 
void UnityFBO::bind ()
1438
 
{
1439
 
  if (!mFBTexture)
1440
 
  {
1441
 
    glGenTextures (1, &mFBTexture);
1442
 
 
1443
 
    glBindTexture (GL_TEXTURE_2D, mFBTexture);
1444
 
    glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1445
 
    glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1446
 
    glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1447
 
    glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1448
 
    glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA, output->width (), output->height (), 0, GL_BGRA,
1449
 
#if IMAGE_BYTE_ORDER == MSBFirst
1450
 
                  GL_UNSIGNED_INT_8_8_8_8_REV,
1451
 
#else
1452
 
                  GL_UNSIGNED_BYTE,
1453
 
#endif
1454
 
                  NULL);
1455
 
 
1456
 
    glBindTexture (GL_TEXTURE_2D, 0);
1457
 
  }
1458
 
 
1459
 
  glGetError ();
1460
 
 
1461
 
  (*GL::bindFramebuffer) (GL_FRAMEBUFFER_EXT, mFboHandle);
1462
 
 
1463
 
  (*GL::framebufferTexture2D) (GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
1464
 
                               GL_TEXTURE_2D, mFBTexture, 0);
1465
 
 
1466
 
  /* Ensure that a framebuffer is actually available */
1467
 
  if (!mFboStatus)
1468
 
  {
1469
 
    GLint status = (*GL::checkFramebufferStatus) (GL_DRAW_FRAMEBUFFER);
1470
 
 
1471
 
    if (status != GL_FRAMEBUFFER_COMPLETE)
1472
 
    {
1473
 
       switch (status)
1474
 
       {
1475
 
          case GL_FRAMEBUFFER_UNDEFINED:
1476
 
            compLogMessage ("unity", CompLogLevelWarn, "no window"); break;
1477
 
          case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT:
1478
 
            compLogMessage ("unity", CompLogLevelWarn, "attachment incomplete"); break;
1479
 
          case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:
1480
 
            compLogMessage ("unity", CompLogLevelWarn, "no buffers attached to fbo"); break;
1481
 
          case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER:
1482
 
            compLogMessage ("unity", CompLogLevelWarn, "some attachment in glDrawBuffers doesn't exist in FBO"); break;
1483
 
          case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER:
1484
 
            compLogMessage ("unity", CompLogLevelWarn, "some attachment in glReadBuffers doesn't exist in FBO"); break;
1485
 
          case GL_FRAMEBUFFER_UNSUPPORTED:
1486
 
            compLogMessage ("unity", CompLogLevelWarn, "unsupported internal format"); break;
1487
 
          case GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE:
1488
 
            compLogMessage ("unity", CompLogLevelWarn, "different levels of sampling for each attachment"); break;
1489
 
          case GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS:
1490
 
            compLogMessage ("unity", CompLogLevelWarn, "number of layers is different"); break;
1491
 
          default:
1492
 
            compLogMessage ("unity", CompLogLevelWarn, "unable to bind the framebuffer for an unknown reason"); break;
1493
 
       }
1494
 
 
1495
 
       GL::bindFramebuffer (GL_FRAMEBUFFER_EXT, 0);
1496
 
       GL::deleteFramebuffers (1, &mFboHandle);
1497
 
 
1498
 
       glDrawBuffer (GL_BACK);
1499
 
       glReadBuffer (GL_BACK);
1500
 
 
1501
 
       mFboHandle = 0;
1502
 
 
1503
 
       mFboStatus = false;
1504
 
       uScreen->setActiveFbo (0);
1505
 
     }
1506
 
     else
1507
 
       mFboStatus = true;
1508
 
   }
1509
 
 
1510
 
  if (mFboStatus)
1511
 
  {
1512
 
    uScreen->setActiveFbo (mFboHandle);
1513
 
 
1514
 
    glDrawBuffer (GL_COLOR_ATTACHMENT0_EXT);
1515
 
    glReadBuffer (GL_COLOR_ATTACHMENT0_EXT);
1516
 
 
1517
 
    glViewport (0,
1518
 
                0,
1519
 
                output->width (),
1520
 
                output->height ());
1521
 
 
1522
 
  }
1523
 
}
1524
 
 
1525
 
UnityFBO::UnityFBO (CompOutput *o)
1526
 
 : mFboStatus (false)
1527
 
 , mFBTexture (0)
1528
 
 , output (o)
1529
 
{
1530
 
  (*GL::genFramebuffers) (1, &mFboHandle);
1531
 
}
1532
 
 
1533
 
UnityFBO::~UnityFBO ()
1534
 
{
1535
 
  (*GL::deleteFramebuffers) (1, &mFboHandle);
1536
 
 
1537
 
  if (mFBTexture)
1538
 
    glDeleteTextures (1, &mFBTexture);
1539
 
}
1540
 
 
1541
 
/* Start up the launcher */
1542
 
void UnityScreen::initLauncher(nux::NThread* thread, void* InitData)
1543
 
{
1544
 
  Timer timer;
1545
 
  UnityScreen* self = reinterpret_cast<UnityScreen*>(InitData);
1546
 
 
1547
 
  self->launcherWindow = new nux::BaseWindow(TEXT("LauncherWindow"));
1548
 
  self->launcherWindow->SinkReference();
1549
 
 
1550
 
  self->launcher = new Launcher(self->launcherWindow, self->screen);
1551
 
  self->launcher->SinkReference();
1552
 
  self->launcher->hidden_changed.connect(sigc::mem_fun(self, &UnityScreen::OnLauncherHiddenChanged));
1553
 
 
1554
 
  self->AddChild(self->launcher);
1555
 
 
1556
 
  nux::HLayout* layout = new nux::HLayout();
1557
 
  layout->AddView(self->launcher, 1);
1558
 
  layout->SetContentDistribution(nux::eStackLeft);
1559
 
  layout->SetVerticalExternalMargin(0);
1560
 
  layout->SetHorizontalExternalMargin(0);
1561
 
 
1562
 
  self->controller = new LauncherController(self->launcher, self->screen);
1563
 
 
1564
 
  self->launcherWindow->SetConfigureNotifyCallback(&UnityScreen::launcherWindowConfigureCallback, self);
1565
 
  self->launcherWindow->SetLayout(layout);
1566
 
  self->launcherWindow->SetBackgroundColor(nux::Color(0x00000000));
1567
 
  self->launcherWindow->ShowWindow(true);
1568
 
  self->launcherWindow->EnableInputWindow(true, "launcher", false, false);
1569
 
  self->launcherWindow->InputWindowEnableStruts(true);
1570
 
  self->launcherWindow->SetEnterFocusInputArea(self->launcher);
1571
 
 
1572
 
  self->switcherController = new SwitcherController();
1573
 
  /* FIXME: this should not be manual, should be managed with a
1574
 
     show/hide callback like in GAIL*/
1575
 
  if (unity_a11y_initialized () == TRUE)
1576
 
    {
1577
 
      AtkObject *atk_obj = NULL;
1578
 
 
1579
 
      atk_obj = unity_util_accessible_add_window (self->launcherWindow);
1580
 
 
1581
 
      atk_object_set_name (atk_obj, _("Launcher"));
1582
 
    }
1583
 
 
1584
 
  self->launcher->SetIconSize(54, 48);
1585
 
  self->launcher->SetBacklightMode(Launcher::BACKLIGHT_ALWAYS_ON);
1586
 
 
1587
 
  LOG_INFO(logger) << "initLauncher-Launcher " << timer.ElapsedSeconds() << "s";
1588
 
 
1589
 
  /* Setup panel */
1590
 
  timer.Reset();
1591
 
  self->panelController = new PanelController();
1592
 
  self->AddChild(self->panelController);
1593
 
  LOG_INFO(logger) << "initLauncher-Panel " << timer.ElapsedSeconds() << "s";
1594
 
 
1595
 
  /* Setup Places */
1596
 
  self->dashController = DashController::Ptr(new DashController());
1597
 
 
1598
 
  /* FIXME: this should not be manual, should be managed with a
1599
 
     show/hide callback like in GAIL
1600
 
  if (unity_a11y_initialized() == TRUE)
1601
 
  {
1602
 
    AtkObject* atk_obj = NULL;
1603
 
 
1604
 
    atk_obj = unity_util_accessible_add_window(self->placesController->GetWindow());
1605
 
 
1606
 
    atk_object_set_name(atk_obj, _("Places"));
1607
 
  }
1608
 
  */
1609
 
 
1610
 
  self->launcher->SetHideMode(Launcher::LAUNCHER_HIDE_DODGE_WINDOWS);
1611
 
  self->launcher->SetLaunchAnimation(Launcher::LAUNCH_ANIMATION_PULSE);
1612
 
  self->launcher->SetUrgentAnimation(Launcher::URGENT_ANIMATION_WIGGLE);
1613
 
  self->ScheduleRelayout(0);
1614
 
 
1615
 
  self->OnLauncherHiddenChanged();
1616
 
}
1617
 
 
1618
 
/* Window init */
1619
 
UnityWindow::UnityWindow(CompWindow* window)
1620
 
  : BaseSwitchWindow (dynamic_cast<BaseSwitchScreen *> (UnityScreen::get (screen)), window)
1621
 
  , PluginClassHandler<UnityWindow, CompWindow>(window)
1622
 
  , window(window)
1623
 
  , gWindow(GLWindow::get(window))
1624
 
{
1625
 
  WindowInterface::setHandler(window);
1626
 
  GLWindowInterface::setHandler(gWindow);
1627
 
}
1628
 
 
1629
 
UnityWindow::~UnityWindow()
1630
 
{
1631
 
  UnityScreen* us = UnityScreen::get(screen);
1632
 
  if (us->newFocusedWindow && (UnityWindow::get(us->newFocusedWindow) == this))
1633
 
    us->newFocusedWindow = NULL;
1634
 
  if (us->lastFocusedWindow && (UnityWindow::get(us->lastFocusedWindow) == this))
1635
 
    us->lastFocusedWindow = NULL;
1636
 
}
1637
 
 
1638
 
/* vtable init */
1639
 
bool UnityPluginVTable::init()
1640
 
{
1641
 
  gfloat version;
1642
 
  gchar* extensions;
1643
 
 
1644
 
  if (!CompPlugin::checkPluginABI("core", CORE_ABIVERSION))
1645
 
    return false;
1646
 
  if (!CompPlugin::checkPluginABI("composite", COMPIZ_COMPOSITE_ABI))
1647
 
    return false;
1648
 
  if (!CompPlugin::checkPluginABI("opengl", COMPIZ_OPENGL_ABI))
1649
 
    return false;
1650
 
 
1651
 
  /* Ensure OpenGL version is 1.4+. */
1652
 
  version = get_opengl_version_f32((const gchar*) glGetString(GL_VERSION));
1653
 
  if (version < 1.4f)
1654
 
  {
1655
 
    compLogMessage("unityshell", CompLogLevelError,
1656
 
                   "OpenGL 1.4+ not supported\n");
1657
 
    return false;
1658
 
  }
1659
 
 
1660
 
  /* Ensure OpenGL extensions required by the Unity plugin are available. */
1661
 
  extensions = (gchar*) glGetString(GL_EXTENSIONS);
1662
 
  if (!is_extension_supported(extensions, "GL_ARB_vertex_program"))
1663
 
  {
1664
 
    compLogMessage("unityshell", CompLogLevelError,
1665
 
                   "GL_ARB_vertex_program not supported\n");
1666
 
    return false;
1667
 
  }
1668
 
  if (!is_extension_supported(extensions, "GL_ARB_fragment_program"))
1669
 
  {
1670
 
    compLogMessage("unityshell", CompLogLevelError,
1671
 
                   "GL_ARB_fragment_program not supported\n");
1672
 
    return false;
1673
 
  }
1674
 
  if (!is_extension_supported(extensions, "GL_ARB_vertex_buffer_object"))
1675
 
  {
1676
 
    compLogMessage("unityshell", CompLogLevelError,
1677
 
                   "GL_ARB_vertex_buffer_object not supported\n");
1678
 
    return false;
1679
 
  }
1680
 
  if (!is_extension_supported(extensions, "GL_ARB_framebuffer_object"))
1681
 
  {
1682
 
    if (!is_extension_supported(extensions, "GL_EXT_framebuffer_object"))
1683
 
    {
1684
 
      compLogMessage("unityshell", CompLogLevelError,
1685
 
                     "GL_ARB_framebuffer_object or GL_EXT_framebuffer_object "
1686
 
                     "not supported\n");
1687
 
      return false;
1688
 
    }
1689
 
  }
1690
 
  if (!is_extension_supported(extensions, "GL_ARB_texture_non_power_of_two"))
1691
 
  {
1692
 
    if (!is_extension_supported(extensions, "GL_ARB_texture_rectangle"))
1693
 
    {
1694
 
      compLogMessage("unityshell", CompLogLevelError,
1695
 
                     "GL_ARB_texture_non_power_of_two or "
1696
 
                     "GL_ARB_texture_rectangle not supported\n");
1697
 
      return false;
1698
 
    }
1699
 
  }
1700
 
 
1701
 
  return true;
1702
 
}
1703
 
 
1704
 
 
1705
 
namespace
1706
 
{
1707
 
 
1708
 
void configure_logging()
1709
 
{
1710
 
  // The default behaviour of the logging infrastructure is to send all output
1711
 
  // to std::cout for warning or above.
1712
 
 
1713
 
  // TODO: write a file output handler that keeps track of backups.
1714
 
  nux::logging::configure_logging(::getenv("UNITY_LOG_SEVERITY"));
1715
 
  g_log_set_default_handler(capture_g_log_calls, NULL);
1716
 
}
1717
 
 
1718
 
/* Checks whether an extension is supported by the GLX or OpenGL implementation
1719
 
 * given the extension name and the list of supported extensions. */
1720
 
gboolean is_extension_supported(const gchar* extensions, const gchar* extension)
1721
 
{
1722
 
  if (extensions != NULL && extension != NULL)
1723
 
  {
1724
 
    const gsize len = strlen(extension);
1725
 
    gchar* p = (gchar*) extensions;
1726
 
    gchar* end = p + strlen(p);
1727
 
 
1728
 
    while (p < end)
1729
 
    {
1730
 
      const gsize size = strcspn(p, " ");
1731
 
      if (len == size && strncmp(extension, p, size) == 0)
1732
 
        return TRUE;
1733
 
      p += size + 1;
1734
 
    }
1735
 
  }
1736
 
 
1737
 
  return FALSE;
1738
 
}
1739
 
 
1740
 
/* Gets the OpenGL version as a floating-point number given the string. */
1741
 
gfloat get_opengl_version_f32(const gchar* version_string)
1742
 
{
1743
 
  gfloat version = 0.0f;
1744
 
  gint32 i;
1745
 
 
1746
 
  for (i = 0; isdigit(version_string[i]); i++)
1747
 
    version = version * 10.0f + (version_string[i] - 48);
1748
 
 
1749
 
  if ((version_string[i] == '.' || version_string[i] == ',') &&
1750
 
      isdigit(version_string[i + 1]))
1751
 
  {
1752
 
    version = version * 10.0f + (version_string[i + 1] - 48);
1753
 
    return (version + 0.1f) * 0.1f;
1754
 
  }
1755
 
  else
1756
 
    return 0.0f;
1757
 
}
1758
 
 
1759
 
nux::logging::Level glog_level_to_nux(GLogLevelFlags log_level)
1760
 
{
1761
 
  // For some weird reason, ERROR is more critical than CRITICAL in gnome.
1762
 
  if (log_level & G_LOG_LEVEL_ERROR)
1763
 
    return nux::logging::Critical;
1764
 
  if (log_level & G_LOG_LEVEL_CRITICAL)
1765
 
    return nux::logging::Error;
1766
 
  if (log_level & G_LOG_LEVEL_WARNING)
1767
 
    return nux::logging::Warning;
1768
 
  if (log_level & G_LOG_LEVEL_MESSAGE ||
1769
 
      log_level & G_LOG_LEVEL_INFO)
1770
 
    return nux::logging::Info;
1771
 
  // default to debug.
1772
 
  return nux::logging::Debug;
1773
 
}
1774
 
 
1775
 
void capture_g_log_calls(const gchar* log_domain,
1776
 
                         GLogLevelFlags log_level,
1777
 
                         const gchar* message,
1778
 
                         gpointer user_data)
1779
 
{
1780
 
  // Since we aren't entirely sure if log_domain contains anything, lets have
1781
 
  // a glib prefix.
1782
 
  std::string module("glib");
1783
 
  if (log_domain)
1784
 
  {
1785
 
    module += std::string(".") + log_domain;
1786
 
  }
1787
 
  nux::logging::Logger logger(module);
1788
 
  nux::logging::Level level = glog_level_to_nux(log_level);
1789
 
  if (logger.GetEffectiveLogLevel() >= level)
1790
 
  {
1791
 
    nux::logging::LogStream(level, logger.module(), "<unknown>", 0).stream()
1792
 
        << message;
1793
 
  }
1794
 
}
1795
 
 
1796
 
} // anonymous namespace