~ubuntu-branches/ubuntu/vivid/blackbox/vivid

« back to all changes in this revision

Viewing changes to .pc/fix-spelling-errors.diff/src/blackbox.cc

  • Committer: Bazaar Package Importer
  • Author(s): Jakub Wilk
  • Date: 2011-03-13 21:19:15 UTC
  • mfrom: (2.1.4 sid)
  • Revision ID: james.westby@ubuntu.com-20110313211915-3h6a2hi3je83ihql
Tags: 0.70.1-3
* QA upload.
* Set the Maintainer field to Debian QA Group (closes: #553352, #572459).
  Thanks for Sandro Tosi and Jan Hauke Rahm for the bug reports.
* Drop the Uploaders field.
* Switch source format to 3.0 (quilt).
  + Convert monolithic diff into separate, small patches.
  + Undo Debian-specific changes to mk.sh; it isn't used at build time
    anyway.
  + Undo changes to files that could be automatically regenerated.
* Use dpkg-buildflags to set CFLAGS.
  + Update debian/rules.
  + Build depend on dpkg-dev (>= 1.15.7).
* Bump debhelper compatibility level to 7.
* Tidy up debian/rules.
  + Drop superfluous whitespace, uninteresting comments.
  + Avoid direct calls to ‘rm’ or ‘install’. Use debian/clean and
    debian/*.install files instead.
  + Remove call to (obsolete) dh_desktop.
  + Add call to dh_icons (closes: #466278). Thanks to James Westby for the
    bug report.
  + Don't pass --sourcedir to dh_install; not needed anymore.
  + Use dh_prep instead of dh_clean -k.
* Tidy up debian/control:
  + Add ${misc:Depends} to all packages' Depends.
  + Add Homepage field.
  + Clarify long description for libbt (closes: #551472). Thanks to Junichi
    Uekawa for the bug report.
* Run autoreconf at build time. Unconditionally update config.sub and
  config.guess.
  + Build-depend on autoconf, automake, libtool, autotools-dev.
  + Add regenerated files to dpkg's extend-diff-ignore.
* Declare bt::textPropertyToString unconditionally (closes: #614468) to fix
  FTBFS with recent versions of X libraries. Thanks to Lucas Nussbaum for
  the bug report.
* Bump standards version to 3.9.1:
  + Move /usr/lib/libbt.so to the -dev package.
  + Don't install /usr/lib/libbt.la.
* Add watch file.
* Fix spelling and typographic errors in the manual pages.
* Fix spelling errors in the code.
* Don't create empty directory: /usr/share/blackbox/nls. Natural language
  support has been defunct since 0.70.0.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// -*- mode: C++; indent-tabs-mode: nil; c-basic-offset: 2; -*-
 
2
// blackbox.cc for Blackbox - an X11 Window manager
 
3
// Copyright (c) 2001 - 2005 Sean 'Shaleh' Perry <shaleh at debian.org>
 
4
// Copyright (c) 1997 - 2000, 2002 - 2005
 
5
//         Bradley T Hughes <bhughes at trolltech.com>
 
6
//
 
7
// Permission is hereby granted, free of charge, to any person obtaining a
 
8
// copy of this software and associated documentation files (the "Software"),
 
9
// to deal in the Software without restriction, including without limitation
 
10
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
 
11
// and/or sell copies of the Software, and to permit persons to whom the
 
12
// Software is furnished to do so, subject to the following conditions:
 
13
//
 
14
// The above copyright notice and this permission notice shall be included in
 
15
// all copies or substantial portions of the Software.
 
16
//
 
17
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 
18
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 
19
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 
20
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 
21
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 
22
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 
23
// DEALINGS IN THE SOFTWARE.
 
24
 
 
25
#include "blackbox.hh"
 
26
#include "Screen.hh"
 
27
#include "Slit.hh"
 
28
#include "Window.hh"
 
29
 
 
30
#include <Pen.hh>
 
31
#include <PixmapCache.hh>
 
32
#include <Util.hh>
 
33
 
 
34
#include <X11/Xresource.h>
 
35
#include <sys/types.h>
 
36
#include <sys/stat.h>
 
37
#include <assert.h>
 
38
#include <signal.h>
 
39
#include <unistd.h>
 
40
 
 
41
// #define FOCUS_DEBUG
 
42
#ifdef FOCUS_DEBUG
 
43
static const char *Mode[] = {
 
44
  "Normal",
 
45
  "Grab",
 
46
  "Ungrab",
 
47
  "WhileGrabbed"
 
48
};
 
49
 
 
50
static const char *Detail[] = {
 
51
  "Ancestor",
 
52
  "Virtual",
 
53
  "Inferior",
 
54
  "Nonlinear",
 
55
  "NonlinearVirtual",
 
56
  "Pointer",
 
57
  "PointerRoot",
 
58
  "DetailNone"
 
59
};
 
60
#endif // FOCUS_DEBUG
 
61
 
 
62
 
 
63
void Blackbox::save_rc(void)
 
64
{ _resource.save(*this); }
 
65
 
 
66
 
 
67
void Blackbox::load_rc(void)
 
68
{ _resource.load(*this); }
 
69
 
 
70
 
 
71
void Blackbox::reload_rc(void) {
 
72
  load_rc();
 
73
  reconfigure();
 
74
}
 
75
 
 
76
 
 
77
void Blackbox::init_icccm(void) {
 
78
  char* atoms[7] = {
 
79
    "WM_COLORMAP_WINDOWS",
 
80
    "WM_PROTOCOLS",
 
81
    "WM_STATE",
 
82
    "WM_CHANGE_STATE",
 
83
    "WM_DELETE_WINDOW",
 
84
    "WM_TAKE_FOCUS",
 
85
    "_MOTIF_WM_HINTS"
 
86
  };
 
87
  Atom atoms_return[7];
 
88
  XInternAtoms(XDisplay(), atoms, 7, false, atoms_return);
 
89
  xa_wm_colormap_windows = atoms_return[0];
 
90
  xa_wm_protocols = atoms_return[1];
 
91
  xa_wm_state = atoms_return[2];
 
92
  xa_wm_change_state = atoms_return[3];
 
93
  xa_wm_delete_window = atoms_return[4];
 
94
  xa_wm_take_focus = atoms_return[5];
 
95
  motif_wm_hints = atoms_return[6];
 
96
 
 
97
  _ewmh = new bt::EWMH(display());
 
98
}
 
99
 
 
100
 
 
101
void Blackbox::updateActiveWindow() const {
 
102
  Window active = (focused_window) ? focused_window->clientWindow() : None;
 
103
  for (unsigned int i = 0; i < display().screenCount(); ++i)
 
104
    _ewmh->setActiveWindow(display().screenInfo(i).rootWindow(), active);
 
105
}
 
106
 
 
107
 
 
108
void Blackbox::shutdown(void) {
 
109
  bt::Application::shutdown();
 
110
 
 
111
  XGrabServer();
 
112
 
 
113
  XSetInputFocus(XDisplay(), PointerRoot, RevertToPointerRoot, XTime());
 
114
 
 
115
  std::for_each(screen_list, screen_list + screen_list_count,
 
116
                std::mem_fun(&BScreen::shutdown));
 
117
 
 
118
  XSync(XDisplay(), false);
 
119
 
 
120
  XUngrabServer();
 
121
}
 
122
 
 
123
 
 
124
static Bool scanForFocusIn(Display *, XEvent *e, XPointer) {
 
125
  if (e->type == FocusIn
 
126
      && e->xfocus.mode != NotifyGrab
 
127
      && (e->xfocus.detail == NotifyNonlinearVirtual
 
128
          || e->xfocus.detail == NotifyVirtual)) {
 
129
    return true;
 
130
  }
 
131
  return false;
 
132
}
 
133
 
 
134
 
 
135
void Blackbox::process_event(XEvent *e) {
 
136
  switch (e->type) {
 
137
  case MapRequest: {
 
138
#ifdef    DEBUG
 
139
    fprintf(stderr, "Blackbox::process_event(): MapRequest for 0x%lx\n",
 
140
            e->xmaprequest.window);
 
141
#endif // DEBUG
 
142
 
 
143
    BlackboxWindow *win = findWindow(e->xmaprequest.window);
 
144
 
 
145
    if (win) {
 
146
      if ((!activeScreen() || activeScreen() == win->screen()) &&
 
147
          (win->isTransient() || _resource.focusNewWindows()))
 
148
        win->activate();
 
149
    } else {
 
150
      BScreen *screen = findScreen(e->xmaprequest.parent);
 
151
 
 
152
      if (! screen) {
 
153
        /*
 
154
          we got a map request for a window who's parent isn't root. this
 
155
          can happen in only one circumstance:
 
156
 
 
157
          a client window unmapped a managed window, and then remapped it
 
158
          somewhere between unmapping the client window and reparenting it
 
159
          to root.
 
160
 
 
161
          regardless of how it happens, we need to find the screen that
 
162
          the window is on
 
163
        */
 
164
        XWindowAttributes wattrib;
 
165
        if (! XGetWindowAttributes(XDisplay(), e->xmaprequest.window,
 
166
                                   &wattrib)) {
 
167
          // failed to get the window attributes, perhaps the window has
 
168
          // now been destroyed?
 
169
          break;
 
170
        }
 
171
 
 
172
        screen = findScreen(wattrib.root);
 
173
        assert(screen != 0); // this should never happen
 
174
      }
 
175
      screen->addWindow(e->xmaprequest.window);
 
176
    }
 
177
 
 
178
    break;
 
179
  }
 
180
 
 
181
  case ConfigureRequest: {
 
182
    BlackboxWindow *win = findWindow(e->xconfigurerequest.window);
 
183
    if (win) {
 
184
      // a window wants to resize
 
185
      win->configureRequestEvent(&e->xconfigurerequest);
 
186
      break;
 
187
    }
 
188
 
 
189
    Slit *slit =
 
190
      dynamic_cast<Slit *>(findEventHandler(e->xconfigurerequest.parent));
 
191
    if (slit) {
 
192
      // something in the slit wants to resize
 
193
      slit->configureRequestEvent(&e->xconfigurerequest);
 
194
      break;
 
195
    }
 
196
 
 
197
    /*
 
198
      handle configure requests for windows that have no EventHandlers
 
199
      by simply configuring them as requested.
 
200
 
 
201
      note: the event->window parameter points to the window being
 
202
      configured, and event->parent points to the window that received
 
203
      the event (in this case, the root window, since
 
204
      SubstructureRedirect has been selected).
 
205
    */
 
206
    XWindowChanges xwc;
 
207
    xwc.x = e->xconfigurerequest.x;
 
208
    xwc.y = e->xconfigurerequest.y;
 
209
    xwc.width = e->xconfigurerequest.width;
 
210
    xwc.height = e->xconfigurerequest.height;
 
211
    xwc.border_width = e->xconfigurerequest.border_width;
 
212
    xwc.sibling = e->xconfigurerequest.above;
 
213
    xwc.stack_mode = e->xconfigurerequest.detail;
 
214
    XConfigureWindow(XDisplay(),
 
215
                     e->xconfigurerequest.window,
 
216
                     e->xconfigurerequest.value_mask,
 
217
                     &xwc);
 
218
    break;
 
219
  }
 
220
 
 
221
  case FocusIn: {
 
222
#ifdef FOCUS_DEBUG
 
223
    printf("FocusIn : window %8lx mode %s detail %s\n",
 
224
           e->xfocus.window, Mode[e->xfocus.mode], Detail[e->xfocus.detail]);
 
225
#endif
 
226
 
 
227
    if (e->xfocus.mode == NotifyGrab
 
228
        || (e->xfocus.detail != NotifyNonlinearVirtual
 
229
            && e->xfocus.detail != NotifyVirtual)) {
 
230
      /*
 
231
        don't process FocusIns when:
 
232
        1. they are the result of a grab
 
233
        2. the new focus window isn't an ancestor or inferior of the
 
234
        old focus window (NotifyNonlinearVirtual and NotifyVirtual)
 
235
      */
 
236
      break;
 
237
    }
 
238
 
 
239
    BlackboxWindow *win = findWindow(e->xfocus.window);
 
240
    if (!win || win->isFocused())
 
241
      break;
 
242
 
 
243
#ifdef FOCUS_DEBUG
 
244
    printf("          win %p got focus\n", win);
 
245
#endif
 
246
    win->setFocused(true);
 
247
    setFocusedWindow(win);
 
248
 
 
249
    /*
 
250
      set the event window to None.  when the FocusOut event handler calls
 
251
      this function recursively, it uses this as an indication that focus
 
252
      has moved to a known window.
 
253
    */
 
254
    e->xfocus.window = None;
 
255
 
 
256
    break;
 
257
  }
 
258
 
 
259
  case FocusOut: {
 
260
#ifdef FOCUS_DEBUG
 
261
    printf("FocusOut: window %8lx mode %s detail %s\n",
 
262
           e->xfocus.window, Mode[e->xfocus.mode], Detail[e->xfocus.detail]);
 
263
#endif
 
264
 
 
265
    if (e->xfocus.mode == NotifyGrab
 
266
        || (e->xfocus.detail != NotifyNonlinearVirtual
 
267
            && e->xfocus.detail != NotifyVirtual)) {
 
268
      /*
 
269
        don't process FocusOuts when:
 
270
        1. they are the result of a grab
 
271
        2. the new focus window isn't an ancestor or inferior of the
 
272
        old focus window (NotifyNonlinearVirtual and NotifyNonlinearVirtual)
 
273
      */
 
274
      break;
 
275
    }
 
276
 
 
277
    BlackboxWindow *win = findWindow(e->xfocus.window);
 
278
    if (!win || !win->isFocused())
 
279
      break;
 
280
 
 
281
    bool lost_focus = true; // did the window really lose focus?
 
282
    bool no_focus = true;   // did another window get focus?
 
283
 
 
284
    XEvent event;
 
285
    if (XCheckIfEvent(XDisplay(), &event, scanForFocusIn, NULL)) {
 
286
      process_event(&event);
 
287
 
 
288
      if (event.xfocus.window == None)
 
289
        no_focus = false;
 
290
    } else {
 
291
      XWindowAttributes attr;
 
292
      Window w;
 
293
      int unused;
 
294
      XGetInputFocus(XDisplay(), &w, &unused);
 
295
      if (w != None
 
296
          && XGetWindowAttributes(XDisplay(), w, &attr)
 
297
          && attr.override_redirect) {
 
298
#ifdef FOCUS_DEBUG
 
299
        printf("          focused moved to an override_redirect window\n");
 
300
#endif
 
301
        lost_focus = (e->xfocus.mode == NotifyNormal);
 
302
      }
 
303
    }
 
304
 
 
305
    if (lost_focus) {
 
306
#ifdef FOCUS_DEBUG
 
307
      printf("          win %p lost focus\n", win);
 
308
#endif
 
309
      win->setFocused(false);
 
310
 
 
311
      if (no_focus) {
 
312
#ifdef FOCUS_DEBUG
 
313
        printf("          no window has focus\n");
 
314
#endif
 
315
        setFocusedWindow(0);
 
316
      }
 
317
    }
 
318
 
 
319
    break;
 
320
  }
 
321
 
 
322
  default:
 
323
    // Send the event through the default EventHandlers.
 
324
    bt::Application::process_event(e);
 
325
    break;
 
326
  } // switch
 
327
}
 
328
 
 
329
 
 
330
bool Blackbox::process_signal(int sig) {
 
331
  switch (sig) {
 
332
  case SIGHUP:
 
333
    reconfigure();
 
334
    break;
 
335
 
 
336
  case SIGUSR1:
 
337
    reload_rc();
 
338
    break;
 
339
 
 
340
  case SIGUSR2:
 
341
    rereadMenu();
 
342
    break;
 
343
 
 
344
  default:
 
345
    return bt::Application::process_signal(sig);
 
346
  } // switch
 
347
 
 
348
  return true;
 
349
}
 
350
 
 
351
 
 
352
void Blackbox::timeout(bt::Timer *) {
 
353
  XrmDatabase new_blackboxrc = (XrmDatabase) 0;
 
354
 
 
355
  std::string style = "session.styleFile: ";
 
356
  style += _resource.styleFilename();
 
357
  XrmPutLineResource(&new_blackboxrc, style.c_str());
 
358
 
 
359
  XrmDatabase old_blackboxrc = XrmGetFileDatabase(_resource.rcFilename());
 
360
 
 
361
  XrmMergeDatabases(new_blackboxrc, &old_blackboxrc);
 
362
  XrmPutFileDatabase(old_blackboxrc, _resource.rcFilename());
 
363
  if (old_blackboxrc) XrmDestroyDatabase(old_blackboxrc);
 
364
 
 
365
  std::for_each(menuTimestamps.begin(), menuTimestamps.end(),
 
366
                bt::PointerAssassin());
 
367
  menuTimestamps.clear();
 
368
 
 
369
  std::for_each(screen_list, screen_list + screen_list_count,
 
370
                std::mem_fun(&BScreen::reconfigure));
 
371
 
 
372
  bt::Font::clearCache();
 
373
  bt::PixmapCache::clearCache();
 
374
  bt::Pen::clearCache();
 
375
 
 
376
  // clear the color cache here to allow the pen cache to deallocate
 
377
  // all unused colors
 
378
  bt::Color::clearCache();
 
379
}
 
380
 
 
381
 
 
382
Blackbox::Blackbox(char **m_argv, const char *dpy_name,
 
383
                   const std::string& rc, bool multi_head)
 
384
  : bt::Application(m_argv[0], dpy_name, multi_head),
 
385
    grab_count(0u), _resource(rc)
 
386
{
 
387
  if (! XSupportsLocale())
 
388
    fprintf(stderr, "X server does not support locale\n");
 
389
 
 
390
  if (XSetLocaleModifiers("") == NULL)
 
391
    fprintf(stderr, "cannot set locale modifiers\n");
 
392
 
 
393
  argv = m_argv;
 
394
 
 
395
  active_screen = 0;
 
396
  focused_window = (BlackboxWindow *) 0;
 
397
  _ewmh = (bt::EWMH*) 0;
 
398
 
 
399
  init_icccm();
 
400
 
 
401
  if (! multi_head || display().screenCount() == 1)
 
402
    screen_list_count = 1;
 
403
  else
 
404
    screen_list_count = display().screenCount();
 
405
 
 
406
  _resource.load(*this);
 
407
 
 
408
  screen_list = new BScreen*[screen_list_count];
 
409
  unsigned int managed = 0;
 
410
  for (unsigned int i = 0; i < screen_list_count; ++i) {
 
411
    BScreen *screen = new BScreen(this, i);
 
412
 
 
413
    if (! screen->isScreenManaged()) {
 
414
      delete screen;
 
415
      continue;
 
416
    }
 
417
 
 
418
    screen_list[i] = screen;
 
419
    ++managed;
 
420
  }
 
421
 
 
422
  if (managed == 0) {
 
423
    fprintf(stderr, "%s: no managable screens found, exiting...\n",
 
424
            applicationName().c_str());
 
425
    ::exit(3);
 
426
  }
 
427
 
 
428
  screen_list_count = managed;
 
429
 
 
430
  // start with the first managed screen as the active screen
 
431
  setActiveScreen(screen_list[0]);
 
432
 
 
433
  XSynchronize(XDisplay(), false);
 
434
  XSync(XDisplay(), false);
 
435
 
 
436
  timer = new bt::Timer(this, this);
 
437
  timer->setTimeout(0l);
 
438
}
 
439
 
 
440
 
 
441
Blackbox::~Blackbox(void) {
 
442
  std::for_each(screen_list, screen_list + screen_list_count,
 
443
                bt::PointerAssassin());
 
444
 
 
445
  delete [] screen_list;
 
446
  std::for_each(menuTimestamps.begin(), menuTimestamps.end(),
 
447
                bt::PointerAssassin());
 
448
 
 
449
  delete timer;
 
450
  delete _ewmh;
 
451
}
 
452
 
 
453
 
 
454
void Blackbox::XGrabServer(void) {
 
455
  if (grab_count++ == 0)
 
456
    ::XGrabServer(XDisplay());
 
457
}
 
458
 
 
459
 
 
460
void Blackbox::XUngrabServer(void) {
 
461
  if (--grab_count == 0)
 
462
    ::XUngrabServer(XDisplay());
 
463
}
 
464
 
 
465
 
 
466
BScreen *Blackbox::findScreen(Window window) const {
 
467
  for (unsigned int i = 0; i < screen_list_count; ++i)
 
468
    if (screen_list[i]->screenInfo().rootWindow() == window)
 
469
      return screen_list[i];
 
470
  return 0;
 
471
}
 
472
 
 
473
 
 
474
void Blackbox::setActiveScreen(BScreen *screen) {
 
475
  if (active_screen && active_screen == screen) // nothing to do
 
476
    return;
 
477
 
 
478
  assert(screen != 0);
 
479
  active_screen = screen;
 
480
 
 
481
  // install screen colormap
 
482
  XInstallColormap(XDisplay(), active_screen->screenInfo().colormap());
 
483
 
 
484
  if (! focused_window || focused_window->screen() != active_screen)
 
485
    setFocusedWindow(0);
 
486
}
 
487
 
 
488
 
 
489
BScreen* Blackbox::screenNumber(unsigned int n) {
 
490
  assert(n < screen_list_count);
 
491
  return screen_list[n];
 
492
}
 
493
 
 
494
 
 
495
BlackboxWindow *Blackbox::findWindow(Window window) const {
 
496
  WindowLookup::const_iterator it = windowSearchList.find(window);
 
497
  if (it != windowSearchList.end())
 
498
    return it->second;
 
499
  return 0;
 
500
}
 
501
 
 
502
 
 
503
void Blackbox::insertWindow(Window window, BlackboxWindow *data)
 
504
{ windowSearchList.insert(WindowLookupPair(window, data)); }
 
505
 
 
506
 
 
507
void Blackbox::removeWindow(Window window)
 
508
{ windowSearchList.erase(window); }
 
509
 
 
510
 
 
511
BWindowGroup *Blackbox::findWindowGroup(Window window) const {
 
512
  GroupLookup::const_iterator it = groupSearchList.find(window);
 
513
  if (it != groupSearchList.end())
 
514
    return it->second;
 
515
  return 0;
 
516
}
 
517
 
 
518
 
 
519
void Blackbox::insertWindowGroup(Window window, BWindowGroup *data)
 
520
{ groupSearchList.insert(GroupLookupPair(window, data)); }
 
521
 
 
522
 
 
523
void Blackbox::removeWindowGroup(Window window)
 
524
{ groupSearchList.erase(window); }
 
525
 
 
526
 
 
527
void Blackbox::setFocusedWindow(BlackboxWindow *win) {
 
528
  if (focused_window && focused_window == win) // nothing to do
 
529
    return;
 
530
 
 
531
  if (win && !win->isIconic()) {
 
532
    // the active screen is the one with the newly focused window...
 
533
    active_screen = win->screen();
 
534
    focused_window = win;
 
535
  } else {
 
536
    // nothing has focus
 
537
    focused_window = 0;
 
538
    assert(active_screen != 0);
 
539
    XSetInputFocus(XDisplay(), active_screen->noFocusWindow(),
 
540
                   RevertToPointerRoot, XTime());
 
541
  }
 
542
 
 
543
  updateActiveWindow();
 
544
}
 
545
 
 
546
 
 
547
void Blackbox::restart(const std::string &prog) {
 
548
  setRunState(bt::Application::SHUTDOWN);
 
549
 
 
550
  /*
 
551
    since we don't allow control to return to the eventloop, we need
 
552
    to call shutdown() explicitly
 
553
  */
 
554
  shutdown();
 
555
 
 
556
  if (! prog.empty()) {
 
557
    putenv(const_cast<char *>
 
558
           (display().screenInfo(0).displayString().c_str()));
 
559
    execlp(prog.c_str(), prog.c_str(), NULL);
 
560
    perror(prog.c_str());
 
561
  }
 
562
 
 
563
  // fall back in case the above execlp doesn't work
 
564
  execvp(argv[0], argv);
 
565
  std::string name = bt::basename(argv[0]);
 
566
  execvp(name.c_str(), argv);
 
567
}
 
568
 
 
569
 
 
570
void Blackbox::reconfigure(void) {
 
571
  if (! timer->isTiming())
 
572
    timer->start();
 
573
}
 
574
 
 
575
 
 
576
void Blackbox::saveMenuFilename(const std::string& filename) {
 
577
  assert(!filename.empty());
 
578
  bool found = false;
 
579
 
 
580
  MenuTimestampList::iterator it = menuTimestamps.begin();
 
581
  for (; it != menuTimestamps.end() && !found; ++it)
 
582
    found = (*it)->filename == filename;
 
583
  if (found)
 
584
    return;
 
585
 
 
586
  struct stat buf;
 
587
  if (stat(filename.c_str(), &buf) != 0)
 
588
    return; // file doesn't exist
 
589
 
 
590
  MenuTimestamp *ts = new MenuTimestamp;
 
591
  ts->filename = filename;
 
592
  ts->timestamp = buf.st_ctime;
 
593
  menuTimestamps.push_back(ts);
 
594
}
 
595
 
 
596
 
 
597
void Blackbox::checkMenu(void) {
 
598
  bool reread = false;
 
599
  MenuTimestampList::iterator it = menuTimestamps.begin();
 
600
  for(; it != menuTimestamps.end(); ++it) {
 
601
    MenuTimestamp *tmp = *it;
 
602
    struct stat buf;
 
603
 
 
604
    if (! stat(tmp->filename.c_str(), &buf)) {
 
605
      if (tmp->timestamp != buf.st_ctime)
 
606
        reread = true;
 
607
    } else {
 
608
      reread = true;
 
609
    }
 
610
  }
 
611
 
 
612
  if (reread)
 
613
    rereadMenu();
 
614
}
 
615
 
 
616
 
 
617
void Blackbox::rereadMenu(void) {
 
618
  std::for_each(menuTimestamps.begin(), menuTimestamps.end(),
 
619
                bt::PointerAssassin());
 
620
  menuTimestamps.clear();
 
621
 
 
622
  std::for_each(screen_list, screen_list + screen_list_count,
 
623
                std::mem_fun(&BScreen::rereadMenu));
 
624
}