-// BaseDisplay.cc for Openbox
-// Copyright (c) 2001 Sean 'Shaleh' Perry <shaleh@debian.org>
+// -*- mode: C++; indent-tabs-mode: nil; -*-
+// BaseDisplay.cc for Blackbox - an X11 Window manager
+// Copyright (c) 2001 - 2002 Sean 'Shaleh' Perry <shaleh@debian.org>
// Copyright (c) 1997 - 2000 Brad Hughes (bhughes@tcac.net)
//
// Permission is hereby granted, free of charge, to any person obtaining a
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
-// stupid macros needed to access some functions in version 2 of the GNU C
-// library
-#ifndef _GNU_SOURCE
-#define _GNU_SOURCE
-#endif // _GNU_SOURCE
-
#ifdef HAVE_CONFIG_H
# include "../config.h"
#endif // HAVE_CONFIG_H
+extern "C" {
#include <X11/Xlib.h>
#include <X11/Xatom.h>
#include <X11/Xutil.h>
-#include <X11/cursorfont.h>
#include <X11/keysym.h>
#ifdef SHAPE
# include <stdio.h>
#endif // HAVE_STDIO_H
-#ifdef HAVE_STDLIB_H
+#ifdef HAVE_STDLIB_H
# include <stdlib.h>
#endif // HAVE_STDLIB_H
-#ifdef HAVE_STRING_H
+#ifdef HAVE_STRING_H
# include <string.h>
#endif // HAVE_STRING_H
# include <sys/types.h>
# include <sys/wait.h>
#endif // HAVE_SYS_WAIT_H
+}
-#if defined(HAVE_PROCESS_H) && defined(__EMX__)
-# include <process.h>
-#endif // HAVE_PROCESS_H __EMX__
+#include <sstream>
+using std::string;
-#include "i18n.h"
-#include "BaseDisplay.h"
-#include "Timer.h"
+#include "i18n.hh"
+#include "BaseDisplay.hh"
+#include "GCCache.hh"
+#include "Timer.hh"
+#include "Util.hh"
-#include <algorithm>
// X error handler to handle any and all X errors while the application is
// running
-static Bool internal_error = False;
+static bool internal_error = False;
static Window last_bad_window = None;
BaseDisplay *base_display;
-static int handleXErrors(Display *d, XErrorEvent *e) {
#ifdef DEBUG
+static int handleXErrors(Display *d, XErrorEvent *e) {
char errtxt[128];
XGetErrorText(d, e->error_code, errtxt, 128);
- fprintf(stderr, i18n(BaseDisplaySet, BaseDisplayXError,
- "%s: X error: %s(%d) opcodes %d/%d\n resource 0x%lx\n"
- ),
+ fprintf(stderr,
+ i18n(BaseDisplaySet, BaseDisplayXError,
+ "%s: X error: %s(%d) opcodes %d/%d\n resource 0x%lx\n"),
base_display->getApplicationName(), errtxt, e->error_code,
e->request_code, e->minor_code, e->resourceid);
+#else
+static int handleXErrors(Display *, XErrorEvent *e) {
#endif // DEBUG
if (e->error_code == BadWindow) last_bad_window = e->resourceid;
// signal handler to allow for proper and gentle shutdown
#ifndef HAVE_SIGACTION
-static RETSIGTYPE signalhandler(int sig)
+static RETSIGTYPE signalhandler(int sig) {
#else // HAVE_SIGACTION
-static void signalhandler(int sig)
+static void signalhandler(int sig) {
#endif // HAVE_SIGACTION
-{
+
static int re_enter = 0;
switch (sig) {
}
-// convenience functions
-#ifndef __EMX__
-void bexec(const char *command, char* displaystring) {
- if (! fork()) {
- setsid();
- putenv(displaystring);
- execl("/bin/sh", "/bin/sh", "-c", command, NULL);
- exit(0);
- }
-}
-#endif // !__EMX__
+BaseDisplay::BaseDisplay(const char *app_name, const char *dpy_name) {
+ application_name = app_name;
-char *bstrdup(const char *s) {
- const int l = strlen(s) + 1;
- char *n = new char[l];
- strncpy(n, s, l);
- return n;
-}
-
-BaseDisplay::BaseDisplay(const char *app_name, char *dpy_name) {
- application_name = bstrdup(app_name);
-
- _startup = True;
- _shutdown = False;
- server_grabs = 0;
+ run_state = STARTUP;
last_bad_window = None;
::base_display = this;
#endif // HAVE_SIGACTION
if (! (display = XOpenDisplay(dpy_name))) {
- fprintf(stderr, i18n(BaseDisplaySet, BaseDisplayXConnectFail,
- "BaseDisplay::BaseDisplay: connection to X server failed.\n"));
+ fprintf(stderr,
+ i18n(BaseDisplaySet, BaseDisplayXConnectFail,
+ "BaseDisplay::BaseDisplay: connection to X server failed.\n"));
::exit(2);
} else if (fcntl(ConnectionNumber(display), F_SETFD, 1) == -1) {
fprintf(stderr,
shape.extensions = False;
#endif // SHAPE
- xa_wm_colormap_windows =
- XInternAtom(display, "WM_COLORMAP_WINDOWS", False);
- xa_wm_protocols = XInternAtom(display, "WM_PROTOCOLS", False);
- xa_wm_state = XInternAtom(display, "WM_STATE", False);
- xa_wm_change_state = XInternAtom(display, "WM_CHANGE_STATE", False);
- xa_wm_delete_window = XInternAtom(display, "WM_DELETE_WINDOW", False);
- xa_wm_take_focus = XInternAtom(display, "WM_TAKE_FOCUS", False);
- motif_wm_hints = XInternAtom(display, "_MOTIF_WM_HINTS", False);
-
- openbox_hints = XInternAtom(display, "_BLACKBOX_HINTS", False);
- openbox_attributes = XInternAtom(display, "_BLACKBOX_ATTRIBUTES", False);
- openbox_change_attributes =
- XInternAtom(display, "_BLACKBOX_CHANGE_ATTRIBUTES", False);
-
- openbox_structure_messages =
- XInternAtom(display, "_BLACKBOX_STRUCTURE_MESSAGES", False);
- openbox_notify_startup =
- XInternAtom(display, "_BLACKBOX_NOTIFY_STARTUP", False);
- openbox_notify_window_add =
- XInternAtom(display, "_BLACKBOX_NOTIFY_WINDOW_ADD", False);
- openbox_notify_window_del =
- XInternAtom(display, "_BLACKBOX_NOTIFY_WINDOW_DEL", False);
- openbox_notify_current_workspace =
- XInternAtom(display, "_BLACKBOX_NOTIFY_CURRENT_WORKSPACE", False);
- openbox_notify_workspace_count =
- XInternAtom(display, "_BLACKBOX_NOTIFY_WORKSPACE_COUNT", False);
- openbox_notify_window_focus =
- XInternAtom(display, "_BLACKBOX_NOTIFY_WINDOW_FOCUS", False);
- openbox_notify_window_raise =
- XInternAtom(display, "_BLACKBOX_NOTIFY_WINDOW_RAISE", False);
- openbox_notify_window_lower =
- XInternAtom(display, "_BLACKBOX_NOTIFY_WINDOW_LOWER", False);
-
- openbox_change_workspace =
- XInternAtom(display, "_BLACKBOX_CHANGE_WORKSPACE", False);
- openbox_change_window_focus =
- XInternAtom(display, "_BLACKBOX_CHANGE_WINDOW_FOCUS", False);
- openbox_cycle_window_focus =
- XInternAtom(display, "_BLACKBOX_CYCLE_WINDOW_FOCUS", False);
-
-#ifdef NEWWMSPEC
-
- net_supported = XInternAtom(display, "_NET_SUPPORTED", False);
- net_client_list = XInternAtom(display, "_NET_CLIENT_LIST", False);
- net_client_list_stacking = XInternAtom(display, "_NET_CLIENT_LIST_STACKING", False);
- net_number_of_desktops = XInternAtom(display, "_NET_NUMBER_OF_DESKTOPS", False);
- net_desktop_geometry = XInternAtom(display, "_NET_DESKTOP_GEOMETRY", False);
- net_desktop_viewport = XInternAtom(display, "_NET_DESKTOP_VIEWPORT", False);
- net_current_desktop = XInternAtom(display, "_NET_CURRENT_DESKTOP", False);
- net_desktop_names = XInternAtom(display, "_NET_DESKTOP_NAMES", False);
- net_active_window = XInternAtom(display, "_NET_ACTIVE_WINDOW", False);
- net_workarea = XInternAtom(display, "_NET_WORKAREA", False);
- net_supporting_wm_check = XInternAtom(display, "_NET_SUPPORTING_WM_CHECK", False);
- net_virtual_roots = XInternAtom(display, "_NET_VIRTUAL_ROOTS", False);
-
- net_close_window = XInternAtom(display, "_NET_CLOSE_WINDOW", False);
- net_wm_moveresize = XInternAtom(display, "_NET_WM_MOVERESIZE", False);
-
- net_properties = XInternAtom(display, "_NET_PROPERTIES", False);
- net_wm_name = XInternAtom(display, "_NET_WM_NAME", False);
- net_wm_desktop = XInternAtom(display, "_NET_WM_DESKTOP", False);
- net_wm_window_type = XInternAtom(display, "_NET_WM_WINDOW_TYPE", False);
- net_wm_state = XInternAtom(display, "_NET_WM_STATE", False);
- net_wm_strut = XInternAtom(display, "_NET_WM_STRUT", False);
- net_wm_icon_geometry = XInternAtom(display, "_NET_WM_ICON_GEOMETRY", False);
- net_wm_icon = XInternAtom(display, "_NET_WM_ICON", False);
- net_wm_pid = XInternAtom(display, "_NET_WM_PID", False);
- net_wm_handled_icons = XInternAtom(display, "_NET_WM_HANDLED_ICONS", False);
-
- net_wm_ping = XInternAtom(display, "_NET_WM_PING", False);
-
-#endif // NEWWMSPEC
-
- cursor.session = XCreateFontCursor(display, XC_left_ptr);
- cursor.move = XCreateFontCursor(display, XC_fleur);
- cursor.ll_angle = XCreateFontCursor(display, XC_ll_angle);
- cursor.lr_angle = XCreateFontCursor(display, XC_lr_angle);
- cursor.ul_angle = XCreateFontCursor(display, XC_ul_angle);
- cursor.ur_angle = XCreateFontCursor(display, XC_ur_angle);
-
XSetErrorHandler((XErrorHandler) handleXErrors);
- screenInfoList.reserve(numberOfScreens());
- for (unsigned int s = 0; s < numberOfScreens(); s++)
- screenInfoList.push_back(new ScreenInfo(*this, s));
+ screenInfoList.reserve(ScreenCount(display));
+ for (int i = 0; i < ScreenCount(display); ++i)
+ screenInfoList.push_back(ScreenInfo(this, i));
-#ifndef NOCLOBBER
NumLockMask = ScrollLockMask = 0;
const XModifierKeymap* const modmap = XGetModifierMapping(display);
// get the values of the keyboard lock modifiers
// Note: Caps lock is not retrieved the same way as Scroll and Num lock
// since it doesn't need to be.
- const KeyCode num_lock_code = XKeysymToKeycode(display, XK_Num_Lock);
- const KeyCode scroll_lock_code = XKeysymToKeycode(display, XK_Scroll_Lock);
+ const KeyCode num_lock = XKeysymToKeycode(display, XK_Num_Lock);
+ const KeyCode scroll_lock = XKeysymToKeycode(display, XK_Scroll_Lock);
for (size_t cnt = 0; cnt < size; ++cnt) {
if (! modmap->modifiermap[cnt]) continue;
- if (num_lock_code == modmap->modifiermap[cnt])
+ if (num_lock == modmap->modifiermap[cnt])
NumLockMask = mask_table[cnt / modmap->max_keypermod];
- if (scroll_lock_code == modmap->modifiermap[cnt])
+ if (scroll_lock == modmap->modifiermap[cnt])
ScrollLockMask = mask_table[cnt / modmap->max_keypermod];
}
}
MaskListLength = sizeof(MaskList) / sizeof(MaskList[0]);
if (modmap) XFreeModifiermap(const_cast<XModifierKeymap*>(modmap));
-#else
- NumLockMask = Mod2Mask;
- ScrollLockMask = Mod5Mask;
-#endif // NOCLOBBER
+
+ gccache = 0;
}
BaseDisplay::~BaseDisplay(void) {
- std::for_each(screenInfoList.begin(), screenInfoList.end(),
- PointerAssassin());
- // we don't create the BTimers, we don't delete them
-
- if (application_name != NULL)
- delete [] application_name;
+ delete gccache;
XCloseDisplay(display);
}
void BaseDisplay::eventLoop(void) {
run();
- int xfd = ConnectionNumber(display);
+ const int xfd = ConnectionNumber(display);
- while ((! _shutdown) && (! internal_error)) {
+ while (run_state == RUNNING && ! internal_error) {
if (XPending(display)) {
XEvent e;
XNextEvent(display, &e);
- if (last_bad_window != None && e.xany.window == last_bad_window) {
-#ifdef DEBUG
- fprintf(stderr, i18n(BaseDisplaySet,
- BaseDisplayBadWindowRemove,
- "BaseDisplay::eventLoop(): removing bad window "
- "from event queue\n"));
-#endif // DEBUG
- } else {
- last_bad_window = None;
- process_event(&e);
- }
+ if (last_bad_window != None && e.xany.window == last_bad_window)
+ continue;
+
+ last_bad_window = None;
+ process_event(&e);
} else {
fd_set rfds;
timeval now, tm, *timeout = (timeval *) 0;
FD_ZERO(&rfds);
FD_SET(xfd, &rfds);
- if (!timerList.empty()) {
- gettimeofday(&now, 0);
-
- tm.tv_sec = tm.tv_usec = 0l;
-
- BTimer *timer = timerList.front();
- ASSERT(timer != NULL);
+ if (! timerList.empty()) {
+ const BTimer* const timer = timerList.top();
- tm.tv_sec = timer->getStartTime().tv_sec +
- timer->getTimeout().tv_sec - now.tv_sec;
- tm.tv_usec = timer->getStartTime().tv_usec +
- timer->getTimeout().tv_usec - now.tv_usec;
-
- while (tm.tv_usec >= 1000000) {
- tm.tv_sec++;
- tm.tv_usec -= 1000000;
- }
-
- while (tm.tv_usec < 0) {
- if (tm.tv_sec > 0) {
- tm.tv_sec--;
- tm.tv_usec += 1000000;
- } else {
- tm.tv_usec = 0;
- break;
- }
- }
+ gettimeofday(&now, 0);
+ tm = timer->timeRemaining(now);
timeout = &tm;
}
// check for timer timeout
gettimeofday(&now, 0);
- TimerList::iterator it;
- for (it = timerList.begin(); it != timerList.end(); ++it) {
- BTimer *timer = *it;
- ASSERT(timer != NULL);
-
- tm.tv_sec = timer->getStartTime().tv_sec +
- timer->getTimeout().tv_sec;
- tm.tv_usec = timer->getStartTime().tv_usec +
- timer->getTimeout().tv_usec;
-
- if ((now.tv_sec < tm.tv_sec) ||
- (now.tv_sec == tm.tv_sec && now.tv_usec < tm.tv_usec))
+ // there is a small chance for deadlock here:
+ // *IF* the timer list keeps getting refreshed *AND* the time between
+ // timer->start() and timer->shouldFire() is within the timer's period
+ // then the timer will keep firing. This should be VERY near impossible.
+ while (! timerList.empty()) {
+ BTimer *timer = timerList.top();
+ if (! timer->shouldFire(now))
break;
- timer->fireTimeout();
+ timerList.pop();
- // restart the current timer so that the start time is updated
- if (! timer->doOnce()) {
- // reorder
- removeTimer(timer);
- addTimer(timer);
+ timer->fireTimeout();
+ timer->halt();
+ if (timer->isRecurring())
timer->start();
- } else
- timer->stop();
- it = timerList.begin(); // we no longer have any idea if the iterator is
- // valid, but what was at the front() is no
- // longer.
}
}
}
}
-const Bool BaseDisplay::validateWindow(Window window) {
- XEvent event;
- if (XCheckTypedWindowEvent(display, window, DestroyNotify, &event)) {
- XPutBackEvent(display, &event);
-
- return False;
- }
-
- return True;
-}
-
-
-void BaseDisplay::grab(void) {
- if (! server_grabs++)
- XGrabServer(display);
-}
-
-
-void BaseDisplay::ungrab(void) {
- if (! --server_grabs)
- XUngrabServer(display);
-}
-
-
void BaseDisplay::addTimer(BTimer *timer) {
- ASSERT(timer != (BTimer *) 0);
-
- TimerList::iterator it;
- for (it = timerList.begin(); it != timerList.end(); ++it) {
- BTimer *tmp = *it;
- if ((tmp->getTimeout().tv_sec > timer->getTimeout().tv_sec) ||
- ((tmp->getTimeout().tv_sec == timer->getTimeout().tv_sec) &&
- (tmp->getTimeout().tv_usec >= timer->getTimeout().tv_usec)))
- break;
- }
+ if (! timer) return;
- timerList.insert(it, timer);
+ timerList.push(timer);
}
void BaseDisplay::removeTimer(BTimer *timer) {
- ASSERT(timer != (BTimer *) 0);
- timerList.remove(timer);
+ timerList.release(timer);
}
/*
- * Grabs a button, but also grabs the button in every possible combination with
- * the keyboard lock keys, so that they do not cancel out the event.
+ * Grabs a button, but also grabs the button in every possible combination
+ * with the keyboard lock keys, so that they do not cancel out the event.
*/
void BaseDisplay::grabButton(unsigned int button, unsigned int modifiers,
- Window grab_window, Bool owner_events,
+ Window grab_window, bool owner_events,
unsigned int event_mask, int pointer_mode,
- int keybaord_mode, Window confine_to,
- Cursor cursor) const
-{
-#ifndef NOCLOBBER
- for (size_t cnt = 0; cnt < MaskListLength; ++cnt)
+ int keyboard_mode, Window confine_to,
+ Cursor cursor) const {
+ for (size_t cnt = 0; cnt < MaskListLength; ++cnt) {
XGrabButton(display, button, modifiers | MaskList[cnt], grab_window,
- owner_events, event_mask, pointer_mode, keybaord_mode,
+ owner_events, event_mask, pointer_mode, keyboard_mode,
confine_to, cursor);
-#else // NOCLOBBER
- XGrabButton(display, button, modifiers, grab_window,
- owner_events, event_mask, pointer_mode, keybaord_mode,
- confine_to, cursor);
-#endif // NOCLOBBER
+ }
}
/*
*/
void BaseDisplay::ungrabButton(unsigned int button, unsigned int modifiers,
Window grab_window) const {
-#ifndef NOCLOBBER
- for (size_t cnt = 0; cnt < MaskListLength; ++cnt)
+ for (size_t cnt = 0; cnt < MaskListLength; ++cnt) {
XUngrabButton(display, button, modifiers | MaskList[cnt], grab_window);
-#else // NOCLOBBER
- XUngrabButton(display, button, modifiers, grab_window);
-#endif // NOCLOBBER
+ }
+}
+
+
+const ScreenInfo* BaseDisplay::getScreenInfo(unsigned int s) const {
+ if (s < screenInfoList.size())
+ return &screenInfoList[s];
+ return (const ScreenInfo*) 0;
}
-ScreenInfo::ScreenInfo(BaseDisplay &d, int num) : basedisplay(d),
-screen_number(num)
+BGCCache *BaseDisplay::gcCache(void) const
{
+ if (! gccache) gccache = new BGCCache(this);
+ return gccache;
+}
+
- root_window = RootWindow(basedisplay.getXDisplay(), screen_number);
- depth = DefaultDepth(basedisplay.getXDisplay(), screen_number);
+ScreenInfo::ScreenInfo(BaseDisplay *d, unsigned int num) {
+ basedisplay = d;
+ screen_number = num;
- m_size = Size(WidthOfScreen(ScreenOfDisplay(basedisplay.getXDisplay(),
- screen_number)),
- HeightOfScreen(ScreenOfDisplay(basedisplay.getXDisplay(),
- screen_number)));
+ root_window = RootWindow(basedisplay->getXDisplay(), screen_number);
+ depth = DefaultDepth(basedisplay->getXDisplay(), screen_number);
+
+ rect.setSize(WidthOfScreen(ScreenOfDisplay(basedisplay->getXDisplay(),
+ screen_number)),
+ HeightOfScreen(ScreenOfDisplay(basedisplay->getXDisplay(),
+ screen_number)));
// search for a TrueColor Visual... if we can't find one... we will use the
// default visual for the screen
visual = (Visual *) 0;
- if ((vinfo_return = XGetVisualInfo(basedisplay.getXDisplay(),
- VisualScreenMask | VisualClassMask,
- &vinfo_template, &vinfo_nitems)) &&
- vinfo_nitems > 0) {
+ vinfo_return = XGetVisualInfo(basedisplay->getXDisplay(),
+ VisualScreenMask | VisualClassMask,
+ &vinfo_template, &vinfo_nitems);
+ if (vinfo_return && vinfo_nitems > 0) {
for (int i = 0; i < vinfo_nitems; i++) {
if (depth < (vinfo_return + i)->depth) {
depth = (vinfo_return + i)->depth;
}
if (visual) {
- colormap = XCreateColormap(basedisplay.getXDisplay(), root_window,
+ colormap = XCreateColormap(basedisplay->getXDisplay(), root_window,
visual, AllocNone);
} else {
- visual = DefaultVisual(basedisplay.getXDisplay(), screen_number);
- colormap = DefaultColormap(basedisplay.getXDisplay(), screen_number);
+ visual = DefaultVisual(basedisplay->getXDisplay(), screen_number);
+ colormap = DefaultColormap(basedisplay->getXDisplay(), screen_number);
}
+
+ // get the default display string and strip the screen number
+ string default_string = DisplayString(basedisplay->getXDisplay());
+ const string::size_type pos = default_string.rfind(".");
+ if (pos != string::npos)
+ default_string.resize(pos);
+
+ std::ostringstream formatter;
+ formatter << "DISPLAY=" << default_string << '.' << screen_number;
+ display_string = formatter.str();
}
+++ /dev/null
-// BaseDisplay.h for Openbox
-// Copyright (c) 2001 Sean 'Shaleh' Perry <shaleh@debian.org>
-// Copyright (c) 1997 - 2000 Brad Hughes (bhughes@tcac.net)
-//
-// Permission is hereby granted, free of charge, to any person obtaining a
-// copy of this software and associated documentation files (the "Software"),
-// to deal in the Software without restriction, including without limitation
-// the rights to use, copy, modify, merge, publish, distribute, sublicense,
-// and/or sell copies of the Software, and to permit persons to whom the
-// Software is furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-// DEALINGS IN THE SOFTWARE.
-
-#ifndef __BaseDisplay_hh
-#define __BaseDisplay_hh
-
-#include <X11/Xlib.h>
-#include <X11/Xatom.h>
-
-// forward declaration
-class BaseDisplay;
-class ScreenInfo;
-
-#include "Timer.h"
-#include "Geometry.h"
-#include "Util.h"
-#include <vector>
-#include <list>
-
-#define AttribShaded (1l << 0)
-#define AttribMaxHoriz (1l << 1)
-#define AttribMaxVert (1l << 2)
-#define AttribOmnipresent (1l << 3)
-#define AttribWorkspace (1l << 4)
-#define AttribStack (1l << 5)
-#define AttribDecoration (1l << 6)
-
-#define StackTop (0)
-#define StackNormal (1)
-#define StackBottom (2)
-
-#define DecorNone (0)
-#define DecorNormal (1)
-#define DecorTiny (2)
-#define DecorTool (3)
-
-typedef struct _openbox_hints {
- unsigned long flags, attrib, workspace, stack, decoration;
-} OpenboxHints;
-
-typedef struct _openbox_attributes {
- unsigned long flags, attrib, workspace, stack, decoration;
- int premax_x, premax_y;
- unsigned int premax_w, premax_h;
-} OpenboxAttributes;
-
-#define PropOpenboxHintsElements (5)
-#define PropOpenboxAttributesElements (9)
-
-#ifndef __EMX__
-void bexec(const char *, char *);
-#endif // !__EMX__
-
-char *bstrdup(const char *);
-
-class BaseDisplay {
-private:
- struct cursor {
- Cursor session, move, ll_angle, lr_angle, ul_angle, ur_angle;
- } cursor;
-
- struct shape {
- Bool extensions;
- int event_basep, error_basep;
- } shape;
-
-#ifndef NOCLOBBER
- unsigned int MaskList[8];
- size_t MaskListLength;
-#endif // NOCLOBBER
-
- Atom xa_wm_colormap_windows, xa_wm_protocols, xa_wm_state,
- xa_wm_delete_window, xa_wm_take_focus, xa_wm_change_state,
- motif_wm_hints;
-
- // NETAttributes
- Atom openbox_attributes, openbox_change_attributes, openbox_hints;
-
- // NETStructureMessages
- Atom openbox_structure_messages, openbox_notify_startup,
- openbox_notify_window_add, openbox_notify_window_del,
- openbox_notify_window_focus, openbox_notify_current_workspace,
- openbox_notify_workspace_count, openbox_notify_window_raise,
- openbox_notify_window_lower;
-
- // message_types for client -> wm messages
- Atom openbox_change_workspace, openbox_change_window_focus,
- openbox_cycle_window_focus;
-
-#ifdef NEWWMSPEC
-
- // root window properties
- Atom net_supported, net_client_list, net_client_list_stacking,
- net_number_of_desktops, net_desktop_geometry, net_desktop_viewport,
- net_current_desktop, net_desktop_names, net_active_window, net_workarea,
- net_supporting_wm_check, net_virtual_roots;
-
- // root window messages
- Atom net_close_window, net_wm_moveresize;
-
- // application window properties
- Atom net_properties, net_wm_name, net_wm_desktop, net_wm_window_type,
- net_wm_state, net_wm_strut, net_wm_icon_geometry, net_wm_icon, net_wm_pid,
- net_wm_handled_icons;
-
- // application protocols
- Atom net_wm_ping;
-
-#endif // NEWWMSPEC
-
- Bool _startup, _shutdown;
- Display *display;
-
- typedef std::vector<ScreenInfo*> ScreenInfoList;
- ScreenInfoList screenInfoList;
-
- typedef std::list<BTimer*> TimerList;
- TimerList timerList;
-
- char *display_name, *application_name;
- unsigned int server_grabs, colors_per_channel;
-
-
-protected:
- // pure virtual function... you must override this
- virtual void process_event(XEvent *) = 0;
-
- // the masks of the modifiers which are ignored in button events.
- int NumLockMask, ScrollLockMask;
-
-
-public:
- BaseDisplay(const char *, char * = 0);
- virtual ~BaseDisplay();
-
- inline const Atom &getWMChangeStateAtom() const
- { return xa_wm_change_state; }
- inline const Atom &getWMStateAtom() const
- { return xa_wm_state; }
- inline const Atom &getWMDeleteAtom() const
- { return xa_wm_delete_window; }
- inline const Atom &getWMProtocolsAtom() const
- { return xa_wm_protocols; }
- inline const Atom &getWMTakeFocusAtom() const
- { return xa_wm_take_focus; }
- inline const Atom &getWMColormapAtom() const
- { return xa_wm_colormap_windows; }
- inline const Atom &getMotifWMHintsAtom() const
- { return motif_wm_hints; }
-
- // this atom is for normal app->WM hints about decorations, stacking,
- // starting workspace etc...
- inline const Atom &getOpenboxHintsAtom() const
- { return openbox_hints;}
-
- // these atoms are for normal app->WM interaction beyond the scope of the
- // ICCCM...
- inline const Atom &getOpenboxAttributesAtom() const
- { return openbox_attributes; }
- inline const Atom &getOpenboxChangeAttributesAtom() const
- { return openbox_change_attributes; }
-
- // these atoms are for window->WM interaction, with more control and
- // information on window "structure"... common examples are
- // notifying apps when windows are raised/lowered... when the user changes
- // workspaces... i.e. "pager talk"
- inline const Atom &getOpenboxStructureMessagesAtom() const
- { return openbox_structure_messages; }
-
- // *Notify* portions of the NETStructureMessages protocol
- inline const Atom &getOpenboxNotifyStartupAtom() const
- { return openbox_notify_startup; }
- inline const Atom &getOpenboxNotifyWindowAddAtom() const
- { return openbox_notify_window_add; }
- inline const Atom &getOpenboxNotifyWindowDelAtom() const
- { return openbox_notify_window_del; }
- inline const Atom &getOpenboxNotifyWindowFocusAtom() const
- { return openbox_notify_window_focus; }
- inline const Atom &getOpenboxNotifyCurrentWorkspaceAtom() const
- { return openbox_notify_current_workspace; }
- inline const Atom &getOpenboxNotifyWorkspaceCountAtom() const
- { return openbox_notify_workspace_count; }
- inline const Atom &getOpenboxNotifyWindowRaiseAtom() const
- { return openbox_notify_window_raise; }
- inline const Atom &getOpenboxNotifyWindowLowerAtom() const
- { return openbox_notify_window_lower; }
-
- // atoms to change that request changes to the desktop environment during
- // runtime... these messages can be sent by any client... as the sending
- // client window id is not included in the ClientMessage event...
- inline const Atom &getOpenboxChangeWorkspaceAtom() const
- { return openbox_change_workspace; }
- inline const Atom &getOpenboxChangeWindowFocusAtom() const
- { return openbox_change_window_focus; }
- inline const Atom &getOpenboxCycleWindowFocusAtom() const
- { return openbox_cycle_window_focus; }
-
-#ifdef NEWWMSPEC
-
- // root window properties
- inline const Atom &getNETSupportedAtom() const
- { return net_supported; }
- inline const Atom &getNETClientListAtom() const
- { return net_client_list; }
- inline const Atom &getNETClientListStackingAtom() const
- { return net_client_list_stacking; }
- inline const Atom &getNETNumberOfDesktopsAtom() const
- { return net_number_of_desktops; }
- inline const Atom &getNETDesktopGeometryAtom() const
- { return net_desktop_geometry; }
- inline const Atom &getNETDesktopViewportAtom() const
- { return net_desktop_viewport; }
- inline const Atom &getNETCurrentDesktopAtom() const
- { return net_current_desktop; }
- inline const Atom &getNETDesktopNamesAtom() const
- { return net_desktop_names; }
- inline const Atom &getNETActiveWindowAtom() const
- { return net_active_window; }
- inline const Atom &getNETWorkareaAtom() const
- { return net_workarea; }
- inline const Atom &getNETSupportingWMCheckAtom() const
- { return net_supporting_wm_check; }
- inline const Atom &getNETVirtualRootsAtom() const
- { return net_virtual_roots; }
-
- // root window messages
- inline const Atom &getNETCloseWindowAtom() const
- { return net_close_window; }
- inline const Atom &getNETWMMoveResizeAtom() const
- { return net_wm_moveresize; }
-
- // application window properties
- inline const Atom &getNETPropertiesAtom() const
- { return net_properties; }
- inline const Atom &getNETWMNameAtom() const
- { return net_wm_name; }
- inline const Atom &getNETWMDesktopAtom() const
- { return net_wm_desktop; }
- inline const Atom &getNETWMWindowTypeAtom() const
- { return net_wm_window_type; }
- inline const Atom &getNETWMStateAtom() const
- { return net_wm_state; }
- inline const Atom &getNETWMStrutAtom() const
- { return net_wm_strut; }
- inline const Atom &getNETWMIconGeometryAtom() const
- { return net_wm_icon_geometry; }
- inline const Atom &getNETWMIconAtom() const
- { return net_wm_icon; }
- inline const Atom &getNETWMPidAtom() const
- { return net_wm_pid; }
- inline const Atom &getNETWMHandledIconsAtom() const
- { return net_wm_handled_icons; }
-
- // application protocols
- inline const Atom &getNETWMPingAtom() const
- { return net_wm_ping; }
-
-#endif // NEWWMSPEC
-
- inline ScreenInfo *getScreenInfo(unsigned int s) {
- ASSERT(s < screenInfoList.size());
- return screenInfoList[s];
- }
-
- inline const Bool &hasShapeExtensions() const
- { return shape.extensions; }
- inline const Bool &doShutdown() const
- { return _shutdown; }
- inline const Bool &isStartup() const
- { return _startup; }
-
- inline const Cursor &getSessionCursor() const
- { return cursor.session; }
- inline const Cursor &getMoveCursor() const
- { return cursor.move; }
- inline const Cursor &getLowerLeftAngleCursor() const
- { return cursor.ll_angle; }
- inline const Cursor &getLowerRightAngleCursor() const
- { return cursor.lr_angle; }
- inline const Cursor &getUpperLeftAngleCursor() const
- { return cursor.ul_angle; }
- inline const Cursor &getUpperRightAngleCursor() const
- { return cursor.ur_angle; }
-
- inline Display *getXDisplay() { return display; }
-
- inline const char *getXDisplayName() const
- { return (const char *) display_name; }
- inline const char *getApplicationName() const
- { return (const char *) application_name; }
-
- inline const unsigned int numberOfScreens() const
- { return ScreenCount(display); }
- inline const int &getShapeEventBase() const
- { return shape.event_basep; }
-
- inline void shutdown() { _shutdown = True; }
- inline void run() { _startup = _shutdown = False; }
-
- const Bool validateWindow(Window);
-
- void grabButton(unsigned int, unsigned int, Window, Bool, unsigned int, int,
- int, Window, Cursor) const;
- void ungrabButton(unsigned int button, unsigned int modifiers,
- Window grab_window) const;
-
- void grab();
- void ungrab();
- void eventLoop();
- void addTimer(BTimer *);
- void removeTimer(BTimer *);
-
- // another pure virtual... this is used to handle signals that BaseDisplay
- // doesn't understand itself
- virtual Bool handleSignal(int) = 0;
-};
-
-
-class ScreenInfo {
-private:
- BaseDisplay &basedisplay;
- Visual *visual;
- Window root_window;
- Colormap colormap;
-
- int depth, screen_number;
- Size m_size;
-
-
-public:
- ScreenInfo(BaseDisplay &, int);
-
- inline BaseDisplay &getBaseDisplay() { return basedisplay; }
-
- inline Visual *getVisual() const { return visual; }
- inline const Window &getRootWindow() const { return root_window; }
- inline const Colormap &getColormap() const { return colormap; }
-
- inline const int &getDepth() const { return depth; }
- inline const int &getScreenNumber() const { return screen_number; }
-
-// inline const unsigned int &getWidth() const { return width; }
-// inline const unsigned int &getHeight() const { return height; }
- inline const Size &size() const { return m_size; }
-};
-
-
-#endif // __BaseDisplay_hh
--- /dev/null
+// -*- mode: C++; indent-tabs-mode: nil; -*-
+// BaseDisplay.hh for Blackbox - an X11 Window manager
+// Copyright (c) 2001 - 2002 Sean 'Shaleh' Perry <shaleh@debian.org>
+// Copyright (c) 1997 - 2000 Brad Hughes (bhughes@tcac.net)
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#ifndef __BaseDisplay_hh
+#define __BaseDisplay_hh
+
+extern "C" {
+#include <X11/Xlib.h>
+#include <X11/Xatom.h>
+}
+
+#include <vector>
+#include <string>
+
+// forward declaration
+class BaseDisplay;
+class BGCCache;
+
+#include "Timer.hh"
+#include "Util.hh"
+
+class ScreenInfo {
+private:
+ BaseDisplay *basedisplay;
+ Visual *visual;
+ Window root_window;
+ Colormap colormap;
+
+ int depth;
+ unsigned int screen_number;
+ std::string display_string;
+ Rect rect;
+
+public:
+ ScreenInfo(BaseDisplay *d, unsigned int num);
+
+ inline BaseDisplay *getBaseDisplay(void) const { return basedisplay; }
+ inline Visual *getVisual(void) const { return visual; }
+ inline Window getRootWindow(void) const { return root_window; }
+ inline Colormap getColormap(void) const { return colormap; }
+ inline int getDepth(void) const { return depth; }
+ inline unsigned int getScreenNumber(void) const
+ { return screen_number; }
+ inline const Rect& getRect(void) const { return rect; }
+ inline unsigned int getWidth(void) const { return rect.width(); }
+ inline unsigned int getHeight(void) const { return rect.height(); }
+ inline const std::string& displayString(void) const
+ { return display_string; }
+};
+
+
+class BaseDisplay: public TimerQueueManager {
+private:
+ struct BShape {
+ bool extensions;
+ int event_basep, error_basep;
+ };
+ BShape shape;
+
+ unsigned int MaskList[8];
+ size_t MaskListLength;
+
+ enum RunState { STARTUP, RUNNING, SHUTDOWN };
+ RunState run_state;
+
+ Display *display;
+ mutable BGCCache *gccache;
+
+ typedef std::vector<ScreenInfo> ScreenInfoList;
+ ScreenInfoList screenInfoList;
+ TimerQueue timerList;
+
+ const char *display_name, *application_name;
+
+ // no copying!
+ BaseDisplay(const BaseDisplay &);
+ BaseDisplay& operator=(const BaseDisplay&);
+
+protected:
+ // pure virtual function... you must override this
+ virtual void process_event(XEvent *e) = 0;
+
+ // the masks of the modifiers which are ignored in button events.
+ int NumLockMask, ScrollLockMask;
+
+
+public:
+ BaseDisplay(const char *app_name, const char *dpy_name = 0);
+ virtual ~BaseDisplay(void);
+
+ const ScreenInfo* getScreenInfo(const unsigned int s) const;
+
+ BGCCache *gcCache(void) const;
+
+ inline bool hasShapeExtensions(void) const
+ { return shape.extensions; }
+ inline bool doShutdown(void) const
+ { return run_state == SHUTDOWN; }
+ inline bool isStartup(void) const
+ { return run_state == STARTUP; }
+
+ inline Display *getXDisplay(void) const { return display; }
+
+ inline const char *getXDisplayName(void) const
+ { return display_name; }
+ inline const char *getApplicationName(void) const
+ { return application_name; }
+
+ inline unsigned int getNumberOfScreens(void) const
+ { return screenInfoList.size(); }
+ inline int getShapeEventBase(void) const
+ { return shape.event_basep; }
+
+ inline void shutdown(void) { run_state = SHUTDOWN; }
+ inline void run(void) { run_state = RUNNING; }
+
+ void grabButton(unsigned int button, unsigned int modifiers,
+ Window grab_window, bool owner_events,
+ unsigned int event_mask, int pointer_mode,
+ int keyboard_mode, Window confine_to, Cursor cursor) const;
+ void ungrabButton(unsigned int button, unsigned int modifiers,
+ Window grab_window) const;
+
+ void eventLoop(void);
+
+ // from TimerQueueManager interface
+ virtual void addTimer(BTimer *timer);
+ virtual void removeTimer(BTimer *timer);
+
+ // another pure virtual... this is used to handle signals that BaseDisplay
+ // doesn't understand itself
+ virtual bool handleSignal(int sig) = 0;
+};
+
+
+#endif // __BaseDisplay_hh
-// Basemenu.cc for Openbox
-// Copyright (c) 2001 Sean 'Shaleh' Perry <shaleh@debian.org>
+// -*- mode: C++; indent-tabs-mode: nil; c-basic-offset: 2; -*-
+// Basemenu.cc for Blackbox - an X11 Window manager
+// Copyright (c) 2001 - 2002 Sean 'Shaleh' Perry <shaleh@debian.org>
// Copyright (c) 1997 - 2000 Brad Hughes (bhughes@tcac.net)
//
// Permission is hereby granted, free of charge, to any person obtaining a
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
-// stupid macros needed to access some functions in version 2 of the GNU C
-// library
-#ifndef _GNU_SOURCE
-#define _GNU_SOURCE
-#endif // _GNU_SOURCE
-
#ifdef HAVE_CONFIG_H
# include "../config.h"
#endif // HAVE_CONFIG_H
+extern "C" {
#ifdef HAVE_STDIO_H
# include <stdio.h>
#endif // HAVE_STDIO_H
-#ifdef HAVE_STDLIB_H
+#ifdef HAVE_STDLIB_H
# include <stdlib.h>
#endif // HAVE_STDLIB_H
-#ifdef HAVE_STRING_H
+#ifdef HAVE_STRING_H
# include <string.h>
#endif // HAVE_STRING_H
+}
#include <algorithm>
-using std::min;
-using std::max;
+using namespace std;
+
+#include "i18n.hh"
+#include "blackbox.hh"
+#include "Basemenu.hh"
+#include "GCCache.hh"
+#include "Image.hh"
+#include "Screen.hh"
+#include "Util.hh"
-#include "i18n.h"
-#include "openbox.h"
-#include "Basemenu.h"
-#include "Screen.h"
static Basemenu *shown = (Basemenu *) 0;
-Basemenu::Basemenu(BScreen &scrn) : openbox(scrn.getOpenbox()), screen(scrn) {
- image_ctrl = screen.getImageControl();
- display = openbox.getXDisplay();
+Basemenu::Basemenu(BScreen *scrn) {
+ screen = scrn;
+ blackbox = screen->getBlackbox();
+ image_ctrl = screen->getImageControl();
+ display = blackbox->getXDisplay();
parent = (Basemenu *) 0;
alignment = AlignDontCare;
menu.hilite_pixmap =
menu.sel_pixmap = None;
- menu.bevel_w = screen.getBevelWidth();
+ menu.bevel_w = screen->getBevelWidth();
if (i18n.multibyte())
menu.width = menu.title_h = menu.item_w = menu.frame_h =
- screen.getMenuStyle()->t_fontset_extents->max_ink_extent.height +
+ screen->getMenuStyle()->t_fontset_extents->max_ink_extent.height +
(menu.bevel_w * 2);
else
menu.width = menu.title_h = menu.item_w = menu.frame_h =
- screen.getMenuStyle()->t_font->ascent +
- screen.getMenuStyle()->t_font->descent + (menu.bevel_w * 2);
-
- menu.label = 0;
+ screen->getMenuStyle()->t_font->ascent +
+ screen->getMenuStyle()->t_font->descent + (menu.bevel_w * 2);
menu.sublevels =
menu.persub =
menu.minsub = 0;
- MenuStyle *style = screen.getMenuStyle();
+ MenuStyle *style = screen->getMenuStyle();
if (i18n.multibyte()) {
menu.item_h = style->f_fontset_extents->max_ink_extent.height +
(menu.bevel_w);
(menu.bevel_w);
}
- menu.height = menu.title_h + screen.getBorderWidth() + menu.frame_h;
+ menu.height = menu.title_h + screen->getBorderWidth() + menu.frame_h;
unsigned long attrib_mask = CWBackPixmap | CWBackPixel | CWBorderPixel |
CWColormap | CWOverrideRedirect | CWEventMask;
XSetWindowAttributes attrib;
attrib.background_pixmap = None;
attrib.background_pixel = attrib.border_pixel =
- screen.getBorderColor()->getPixel();
- attrib.colormap = screen.getColormap();
+ screen->getBorderColor()->pixel();
+ attrib.colormap = screen->getColormap();
attrib.override_redirect = True;
attrib.event_mask = ButtonPressMask | ButtonReleaseMask |
ButtonMotionMask | ExposureMask;
menu.window =
- XCreateWindow(display, screen.getRootWindow(), menu.x, menu.y, menu.width,
- menu.height, screen.getBorderWidth(), screen.getDepth(),
- InputOutput, screen.getVisual(), attrib_mask, &attrib);
- openbox.saveMenuSearch(menu.window, this);
+ XCreateWindow(display, screen->getRootWindow(),
+ menu.x, menu.y, menu.width, menu.height,
+ screen->getBorderWidth(), screen->getDepth(),
+ InputOutput, screen->getVisual(), attrib_mask, &attrib);
+ blackbox->saveMenuSearch(menu.window, this);
attrib_mask = CWBackPixmap | CWBackPixel | CWBorderPixel | CWEventMask;
- attrib.background_pixel = screen.getBorderColor()->getPixel();
+ attrib.background_pixel = screen->getBorderColor()->pixel();
attrib.event_mask |= EnterWindowMask | LeaveWindowMask;
menu.title =
XCreateWindow(display, menu.window, 0, 0, menu.width, menu.height, 0,
- screen.getDepth(), InputOutput, screen.getVisual(),
+ screen->getDepth(), InputOutput, screen->getVisual(),
attrib_mask, &attrib);
- openbox.saveMenuSearch(menu.title, this);
+ blackbox->saveMenuSearch(menu.title, this);
attrib.event_mask |= PointerMotionMask;
menu.frame = XCreateWindow(display, menu.window, 0,
- menu.title_h + screen.getBorderWidth(),
+ menu.title_h + screen->getBorderWidth(),
menu.width, menu.frame_h, 0,
- screen.getDepth(), InputOutput,
- screen.getVisual(), attrib_mask, &attrib);
- openbox.saveMenuSearch(menu.frame, this);
+ screen->getDepth(), InputOutput,
+ screen->getVisual(), attrib_mask, &attrib);
+ blackbox->saveMenuSearch(menu.frame, this);
// even though this is the end of the constructor the menu is still not
// completely created. items must be inserted and it must be update()'d
}
-
Basemenu::~Basemenu(void) {
XUnmapWindow(display, menu.window);
if (shown && shown->getWindowID() == getWindowID())
shown = (Basemenu *) 0;
- while (!menuitems.empty())
- remove(0);
+ MenuItems::const_iterator it = menuitems.begin();
+ while (it != menuitems.end()) {
+ BasemenuItem *item = *it;
+ if ((! internal_menu)) {
+ Basemenu *tmp = (Basemenu *) item->submenu();
+ if (tmp) {
+ if (! tmp->internal_menu) {
+ delete tmp;
+ } else {
+ tmp->internal_hide();
+ }
+ }
+ }
+ ++it;
+ }
- if (menu.label)
- delete [] menu.label;
+ std::for_each(menuitems.begin(), menuitems.end(), PointerAssassin());
if (menu.title_pixmap)
image_ctrl->removeImage(menu.title_pixmap);
if (menu.sel_pixmap)
image_ctrl->removeImage(menu.sel_pixmap);
- openbox.removeMenuSearch(menu.title);
+ blackbox->removeMenuSearch(menu.title);
XDestroyWindow(display, menu.title);
- openbox.removeMenuSearch(menu.frame);
+ blackbox->removeMenuSearch(menu.frame);
XDestroyWindow(display, menu.frame);
- openbox.removeMenuSearch(menu.window);
+ blackbox->removeMenuSearch(menu.window);
XDestroyWindow(display, menu.window);
}
-int Basemenu::insert(const char *l, int function, const char *e, int pos) {
- char *label = 0, *exec = 0;
+BasemenuItem::~BasemenuItem(void) {}
- if (l) label = bstrdup(l);
- if (e) exec = bstrdup(e);
- BasemenuItem *item = new BasemenuItem(label, function, exec);
- if (pos == -1)
- menuitems.push_back(item);
- else
- menuitems.insert(menuitems.begin() + pos, item);
+BasemenuItem *Basemenu::find(int index) {
+ if (index < 0 || index > static_cast<signed>(menuitems.size()))
+ return (BasemenuItem*) 0;
- return menuitems.size();
+ return *(menuitems.begin() + index);
}
-int Basemenu::insert(const char *l, Basemenu *submenu, int pos) {
- char *label = 0;
-
- if (l) label = bstrdup(l);
-
- BasemenuItem *item = new BasemenuItem(label, submenu);
- if (pos == -1)
+int Basemenu::insert(BasemenuItem *item, int pos) {
+ if (pos < 0) {
menuitems.push_back(item);
- else
- menuitems.insert(menuitems.begin() + pos, item);
+ } else {
+ assert(pos < static_cast<signed>(menuitems.size()));
+ menuitems.insert((menuitems.begin() + pos), item);
+ }
+ return menuitems.size();
+}
- submenu->parent = this;
- return menuitems.size();
+int Basemenu::insert(const string& label, int function,
+ const string& exec, int pos) {
+ BasemenuItem *item = new BasemenuItem(label, function, exec);
+ return insert(item, pos);
}
-int Basemenu::insert(const char **ulabel, int pos, int function) {
- BasemenuItem *item = new BasemenuItem(ulabel, function);
- if (pos == -1)
- menuitems.push_back(item);
- else
- menuitems.insert(menuitems.begin() + pos, item);
+int Basemenu::insert(const string& label, Basemenu *submenu, int pos) {
+ BasemenuItem *item = new BasemenuItem(label, submenu);
+ submenu->parent = this;
- return menuitems.size();
+ return insert(item, pos);
}
int Basemenu::remove(int index) {
- if (index < 0 || index > (signed)menuitems.size()) return -1;
-
- BasemenuItem *item = menuitems[index];
- menuitems.erase(menuitems.begin() + index);
-
- if (item) {
- if ((!internal_menu) && (item->submenu())) {
- Basemenu *tmp = (Basemenu *) item->submenu();
+ BasemenuItem *item = find(index);
+ if (! item) return -1;
+ if ((! internal_menu)) {
+ Basemenu *tmp = (Basemenu *) item->submenu();
+ if (tmp) {
if (! tmp->internal_menu) {
delete tmp;
} else {
tmp->internal_hide();
}
}
-
- if (item->label())
- delete [] item->label();
-
- if (item->exec())
- delete [] item->exec();
-
- delete item;
}
+ delete item;
+
if (which_sub == index)
which_sub = -1;
else if (which_sub > index)
which_sub--;
+ menuitems.erase(menuitems.begin() + index);
+
return menuitems.size();
}
void Basemenu::update(void) {
- MenuStyle *style = screen.getMenuStyle();
+ MenuStyle *style = screen->getMenuStyle();
if (i18n.multibyte()) {
menu.item_h = style->f_fontset_extents->max_ink_extent.height +
menu.bevel_w;
}
if (title_vis) {
- const char *s = (menu.label) ? menu.label :
- i18n(BasemenuSet, BasemenuOpenboxMenu,
- "Openbox Menu");
+ const char *s = getLabel();
int l = strlen(s);
-
if (i18n.multibyte()) {
XRectangle ink, logical;
- XmbTextExtents(screen.getMenuStyle()->t_fontset, s, l, &ink, &logical);
+ XmbTextExtents(screen->getMenuStyle()->t_fontset, s, l, &ink, &logical);
menu.item_w = logical.width;
} else {
- menu.item_w = XTextWidth(screen.getMenuStyle()->t_font, s, l);
+ menu.item_w = XTextWidth(screen->getMenuStyle()->t_font, s, l);
}
menu.item_w += (menu.bevel_w * 2);
menu.item_w = 1;
}
- int ii = 0;
- menuitemList::const_iterator it = menuitems.begin();
- for (; it != menuitems.end(); it++) {
- const char *s = (((*it)->u && *(*it)->u) ? *(*it)->u :
- (((*it)->l) ? (*it)->l : (const char *) 0));
+ unsigned int ii = 0;
+ MenuItems::iterator it = menuitems.begin(), end = menuitems.end();
+ for (; it != end; ++it) {
+ BasemenuItem *tmp = *it;
+ const char *s = tmp->l.c_str();
int l = strlen(s);
if (i18n.multibyte()) {
XRectangle ink, logical;
- XmbTextExtents(screen.getMenuStyle()->f_fontset, s, l, &ink, &logical);
+ XmbTextExtents(screen->getMenuStyle()->f_fontset, s, l, &ink, &logical);
ii = logical.width;
} else
- ii = XTextWidth(screen.getMenuStyle()->f_font, s, l);
+ ii = XTextWidth(screen->getMenuStyle()->f_font, s, l);
ii += (menu.bevel_w * 2) + (menu.item_h * 2);
- menu.item_w = ((menu.item_w < (unsigned int) ii) ? ii : menu.item_w);
+ menu.item_w = ((menu.item_w < ii) ? ii : menu.item_w);
}
- if (menuitems.size()) {
+ if (! menuitems.empty()) {
menu.sublevels = 1;
- while (((menu.item_h * (menuitems.size() + 1) / menu.sublevels)
- + menu.title_h + screen.getBorderWidth()) >
- screen.size().h())
+ unsigned int menu_size = menuitems.size();
+ while (((menu.item_h * (menu_size + 1) / menu.sublevels)
+ + menu.title_h + screen->getBorderWidth()) >
+ screen->getHeight())
menu.sublevels++;
if (menu.sublevels < menu.minsub) menu.sublevels = menu.minsub;
- menu.persub = menuitems.size() / menu.sublevels;
- if (menuitems.size() % menu.sublevels) menu.persub++;
+ menu.persub = menu_size / menu.sublevels;
+ if (menu_size % menu.sublevels) menu.persub++;
} else {
menu.sublevels = 0;
menu.persub = 0;
if (! menu.width) menu.width = menu.item_w;
menu.frame_h = (menu.item_h * menu.persub);
- menu.height = ((title_vis) ? menu.title_h + screen.getBorderWidth() : 0) +
+ menu.height = ((title_vis) ? menu.title_h + screen->getBorderWidth() : 0) +
menu.frame_h;
if (! menu.frame_h) menu.frame_h = 1;
if (menu.height < 1) menu.height = 1;
BTexture *texture;
if (title_vis) {
tmp = menu.title_pixmap;
- texture = &(screen.getMenuStyle()->title);
- if (texture->getTexture() == (BImage_Flat | BImage_Solid)) {
+ texture = &(screen->getMenuStyle()->title);
+ if (texture->texture() == (BTexture::Flat | BTexture::Solid)) {
menu.title_pixmap = None;
XSetWindowBackground(display, menu.title,
- texture->getColor()->getPixel());
+ texture->color().pixel());
} else {
menu.title_pixmap =
- image_ctrl->renderImage(menu.width, menu.title_h, texture);
+ image_ctrl->renderImage(menu.width, menu.title_h, *texture);
XSetWindowBackgroundPixmap(display, menu.title, menu.title_pixmap);
}
if (tmp) image_ctrl->removeImage(tmp);
}
tmp = menu.frame_pixmap;
- texture = &(screen.getMenuStyle()->frame);
- if (texture->getTexture() == (BImage_Flat | BImage_Solid)) {
+ texture = &(screen->getMenuStyle()->frame);
+ if (texture->texture() == (BTexture::Flat | BTexture::Solid)) {
menu.frame_pixmap = None;
XSetWindowBackground(display, menu.frame,
- texture->getColor()->getPixel());
+ texture->color().pixel());
} else {
menu.frame_pixmap =
- image_ctrl->renderImage(menu.width, menu.frame_h, texture);
+ image_ctrl->renderImage(menu.width, menu.frame_h, *texture);
XSetWindowBackgroundPixmap(display, menu.frame, menu.frame_pixmap);
}
if (tmp) image_ctrl->removeImage(tmp);
tmp = menu.hilite_pixmap;
- texture = &(screen.getMenuStyle()->hilite);
- if (texture->getTexture() == (BImage_Flat | BImage_Solid)) {
+ texture = &(screen->getMenuStyle()->hilite);
+ if (texture->texture() == (BTexture::Flat | BTexture::Solid)) {
menu.hilite_pixmap = None;
} else {
menu.hilite_pixmap =
- image_ctrl->renderImage(menu.item_w, menu.item_h, texture);
+ image_ctrl->renderImage(menu.item_w, menu.item_h, *texture);
}
if (tmp) image_ctrl->removeImage(tmp);
tmp = menu.sel_pixmap;
- if (texture->getTexture() == (BImage_Flat | BImage_Solid)) {
+ if (texture->texture() == (BTexture::Flat | BTexture::Solid)) {
menu.sel_pixmap = None;
} else {
int hw = menu.item_h / 2;
menu.sel_pixmap =
- image_ctrl->renderImage(hw, hw, texture);
+ image_ctrl->renderImage(hw, hw, *texture);
}
if (tmp) image_ctrl->removeImage(tmp);
XMoveResizeWindow(display, menu.frame, 0,
((title_vis) ? menu.title_h +
- screen.getBorderWidth() : 0), menu.width,
+ screen->getBorderWidth() : 0), menu.width,
menu.frame_h);
XClearWindow(display, menu.window);
if (title_vis && visible) redrawTitle();
- for (int i = 0; visible && i < (signed)menuitems.size(); i++) {
+ const int menu_size = menuitems.size();
+ for (int i = 0; visible && i < menu_size; i++) {
if (i == which_sub) {
drawItem(i, True, 0);
drawSubmenu(i);
void Basemenu::internal_hide(void) {
- if (which_sub != -1) {
- BasemenuItem *tmp = menuitems[which_sub];
+ BasemenuItem *tmp = find(which_sub);
+ if (tmp)
tmp->submenu()->internal_hide();
- }
if (parent && (! torn)) {
parent->drawItem(parent->which_sub, False, True);
void Basemenu::redrawTitle(void) {
- char *text = (char *) ((menu.label) ? menu.label :
- i18n(BasemenuSet, BasemenuOpenboxMenu,
- "Openbox Menu"));
+ const char *text = (! menu.label.empty()) ? getLabel() :
+ i18n(BasemenuSet, BasemenuBlackboxMenu, "Blackbox Menu");
int dx = menu.bevel_w, len = strlen(text);
unsigned int l;
if (i18n.multibyte()) {
XRectangle ink, logical;
- XmbTextExtents(screen.getMenuStyle()->t_fontset, text, len, &ink, &logical);
+ XmbTextExtents(screen->getMenuStyle()->t_fontset, text, len,
+ &ink, &logical);
l = logical.width;
} else {
- l = XTextWidth(screen.getMenuStyle()->t_font, text, len);
+ l = XTextWidth(screen->getMenuStyle()->t_font, text, len);
}
l += (menu.bevel_w * 2);
- switch (screen.getMenuStyle()->t_justify) {
- case BScreen::RightJustify:
+ switch (screen->getMenuStyle()->t_justify) {
+ case RightJustify:
dx += menu.width - l;
break;
- case BScreen::CenterJustify:
+ case CenterJustify:
dx += (menu.width - l) / 2;
break;
+
+ case LeftJustify:
+ default:
+ break;
}
- MenuStyle *style = screen.getMenuStyle();
+ MenuStyle *style = screen->getMenuStyle();
+ BPen pen(style->t_text, style->t_font);
if (i18n.multibyte())
- XmbDrawString(display, menu.title, style->t_fontset, style->t_text_gc, dx,
+ XmbDrawString(display, menu.title, style->t_fontset, pen.gc(), dx,
(menu.bevel_w - style->t_fontset_extents->max_ink_extent.y),
text, len);
else
- XDrawString(display, menu.title, style->t_text_gc, dx,
+ XDrawString(display, menu.title, pen.gc(), dx,
(style->t_font->ascent + menu.bevel_w), text, len);
}
void Basemenu::drawSubmenu(int index) {
- if (which_sub != -1 && which_sub != index) {
- BasemenuItem *itmp = menuitems[which_sub];
+ BasemenuItem *item = find(which_sub);
+ if (item && item->submenu() && ! item->submenu()->isTorn() &&
+ which_sub != index)
+ item->submenu()->internal_hide();
+
+ item = find(index);
+ if (! item)
+ return;
+ Basemenu *submenu = item->submenu();
+
+ if (submenu && visible && ! submenu->isTorn() && item->isEnabled()) {
+ if (submenu->parent != this) submenu->parent = this;
+ int sbl = index / menu.persub, i = index - (sbl * menu.persub),
+ x = menu.x + ((menu.item_w * (sbl + 1)) + screen->getBorderWidth()), y;
+
+ if (alignment == AlignTop) {
+ y = (((shifted) ? menu.y_shift : menu.y) +
+ ((title_vis) ? menu.title_h + screen->getBorderWidth() : 0) -
+ ((submenu->title_vis) ?
+ submenu->menu.title_h + screen->getBorderWidth() : 0));
+ } else {
+ y = (((shifted) ? menu.y_shift : menu.y) +
+ (menu.item_h * i) +
+ ((title_vis) ? menu.title_h + screen->getBorderWidth() : 0) -
+ ((submenu->title_vis) ?
+ submenu->menu.title_h + screen->getBorderWidth() : 0));
+ }
- if (! itmp->submenu()->isTorn())
- itmp->submenu()->internal_hide();
- }
+ if (alignment == AlignBottom &&
+ (y + submenu->menu.height) > ((shifted) ? menu.y_shift :
+ menu.y) + menu.height)
+ y = (((shifted) ? menu.y_shift : menu.y) +
+ menu.height - submenu->menu.height);
- if (index >= 0 && index < (signed)menuitems.size()) {
- BasemenuItem *item = menuitems[index];
- if (item->submenu() && visible && (! item->submenu()->isTorn()) &&
- item->isEnabled()) {
- if (item->submenu()->parent != this) item->submenu()->parent = this;
- int sbl = index / menu.persub, i = index - (sbl * menu.persub),
- x = menu.x +
- ((menu.item_w * (sbl + 1)) + screen.getBorderWidth()), y;
-
- if (alignment == AlignTop)
- y = (((shifted) ? menu.y_shift : menu.y) +
- ((title_vis) ? menu.title_h + screen.getBorderWidth() : 0) -
- ((item->submenu()->title_vis) ?
- item->submenu()->menu.title_h + screen.getBorderWidth() : 0));
- else
- y = (((shifted) ? menu.y_shift : menu.y) +
- (menu.item_h * i) +
- ((title_vis) ? menu.title_h + screen.getBorderWidth() : 0) -
- ((item->submenu()->title_vis) ?
- item->submenu()->menu.title_h + screen.getBorderWidth() : 0));
-
- if (alignment == AlignBottom &&
- (y + item->submenu()->menu.height) > ((shifted) ? menu.y_shift :
- menu.y) + menu.height)
- y = (((shifted) ? menu.y_shift : menu.y) +
- menu.height - item->submenu()->menu.height);
-
- if ((x + item->submenu()->getWidth()) > screen.size().w()) {
- x = ((shifted) ? menu.x_shift : menu.x) -
- item->submenu()->getWidth() - screen.getBorderWidth();
- }
+ if ((x + submenu->getWidth()) > screen->getWidth())
+ x = ((shifted) ? menu.x_shift : menu.x) -
+ submenu->getWidth() - screen->getBorderWidth();
- if (x < 0) x = 0;
+ if (x < 0) x = 0;
- if ((y + item->submenu()->getHeight()) > screen.size().h())
- y = screen.size().h() - item->submenu()->getHeight() -
- (screen.getBorderWidth() * 2);
- if (y < 0) y = 0;
+ if ((y + submenu->getHeight()) > screen->getHeight())
+ y = screen->getHeight() - submenu->getHeight() -
+ (screen->getBorderWidth() * 2);
+ if (y < 0) y = 0;
- item->submenu()->move(x, y);
- if (! moving) drawItem(index, True);
+ submenu->move(x, y);
+ if (! moving) drawItem(index, True);
- if (! item->submenu()->isVisible())
- item->submenu()->show();
- item->submenu()->moving = moving;
- which_sub = index;
- } else {
- which_sub = -1;
- }
+ if (! submenu->isVisible())
+ submenu->show();
+ submenu->moving = moving;
+ which_sub = index;
+ } else {
+ which_sub = -1;
}
}
bool Basemenu::hasSubmenu(int index) {
- if (index < 0 | index >= (signed)menuitems.size())
- return false;
- return (menuitems[index]->submenu());
+ BasemenuItem *item = find(index);
+ if (item && item->submenu())
+ return True;
+ return False;
}
-void Basemenu::drawItem(int index, Bool highlight, Bool clear,
+void Basemenu::drawItem(int index, bool highlight, bool clear,
int x, int y, unsigned int w, unsigned int h)
{
- if (index < 0 || index > (signed)menuitems.size()) return;
-
- BasemenuItem *item = menuitems[index];
+ BasemenuItem *item = find(index);
if (! item) return;
- Bool dotext = True, dohilite = True, dosel = True;
- const char *text = (item->ulabel()) ? *item->ulabel() : item->label();
+ bool dotext = True, dohilite = True, dosel = True;
+ const char *text = item->label();
int sbl = index / menu.persub, i = index - (sbl * menu.persub);
int item_x = (sbl * menu.item_w), item_y = (i * menu.item_h);
int hilite_x = item_x, hilite_y = item_y, hoff_x = 0, hoff_y = 0;
int text_x = 0, text_y = 0, len = strlen(text), sel_x = 0, sel_y = 0;
unsigned int hilite_w = menu.item_w, hilite_h = menu.item_h, text_w = 0,
- text_h = 0;
+ text_h = 0;
unsigned int half_w = menu.item_h / 2, quarter_w = menu.item_h / 4;
if (text) {
if (i18n.multibyte()) {
XRectangle ink, logical;
- XmbTextExtents(screen.getMenuStyle()->f_fontset,
+ XmbTextExtents(screen->getMenuStyle()->f_fontset,
text, len, &ink, &logical);
text_w = logical.width;
text_y = item_y + (menu.bevel_w / 2) -
- screen.getMenuStyle()->f_fontset_extents->max_ink_extent.y;
+ screen->getMenuStyle()->f_fontset_extents->max_ink_extent.y;
} else {
- text_w = XTextWidth(screen.getMenuStyle()->f_font, text, len);
+ text_w = XTextWidth(screen->getMenuStyle()->f_font, text, len);
text_y = item_y +
- screen.getMenuStyle()->f_font->ascent +
+ screen->getMenuStyle()->f_font->ascent +
(menu.bevel_w / 2);
}
- switch(screen.getMenuStyle()->f_justify) {
- case BScreen::LeftJustify:
+ switch(screen->getMenuStyle()->f_justify) {
+ case LeftJustify:
text_x = item_x + menu.bevel_w + menu.item_h + 1;
break;
- case BScreen::RightJustify:
+ case RightJustify:
text_x = item_x + menu.item_w - (menu.item_h + menu.bevel_w + text_w);
break;
- case BScreen::CenterJustify:
+ case CenterJustify:
text_x = item_x + ((menu.item_w + 1 - text_w) / 2);
break;
}
text_h = menu.item_h - menu.bevel_w;
}
- GC gc =
- ((highlight || item->isSelected()) ? screen.getMenuStyle()->h_text_gc :
- screen.getMenuStyle()->f_text_gc),
- tgc =
- ((highlight) ? screen.getMenuStyle()->h_text_gc :
- ((item->isEnabled()) ? screen.getMenuStyle()->f_text_gc :
- screen.getMenuStyle()->d_text_gc));
+ MenuStyle *style = screen->getMenuStyle();
+ BPen pen((highlight || item->isSelected()) ? style->h_text : style->f_text),
+ textpen((highlight) ? style->h_text :
+ item->isEnabled() ? style->f_text : style->d_text, style->f_font),
+ hipen(style->hilite.color());
+
sel_x = item_x;
- if (screen.getMenuStyle()->bullet_pos == Right)
+ if (screen->getMenuStyle()->bullet_pos == Right)
sel_x += (menu.item_w - menu.item_h - menu.bevel_w);
sel_x += quarter_w;
sel_y = item_y + quarter_w;
False);
} else if (! (x == y && y == -1 && w == h && h == 0)) {
// calculate the which part of the hilite to redraw
- if (! (max(item_x, x) <= (signed) min(item_x + menu.item_w, x + w) &&
- max(item_y, y) <= (signed) min(item_y + menu.item_h, y + h))) {
+ if (! (max(item_x, x) <= min<signed>(item_x + menu.item_w, x + w) &&
+ max(item_y, y) <= min<signed>(item_y + menu.item_h, y + h))) {
dohilite = False;
} else {
hilite_x = max(item_x, x);
hoff_y = hilite_y % menu.item_h;
}
- // check if we need to redraw the text
+ // check if we need to redraw the text
int text_ry = item_y + (menu.bevel_w / 2);
- if (! (max(text_x, x) <= (signed) min(text_x + text_w, x + w) &&
- max(text_ry, y) <= (signed) min(text_ry + text_h, y + h)))
+ if (! (max(text_x, x) <= min<signed>(text_x + text_w, x + w) &&
+ max(text_ry, y) <= min<signed>(text_ry + text_h, y + h)))
dotext = False;
// check if we need to redraw the select pixmap/menu bullet
- if (! (max(sel_x, x) <= (signed) min(sel_x + half_w, x + w) &&
- max(sel_y, y) <= (signed) min(sel_y + half_w, y + h)))
+ if (! (max(sel_x, x) <= min<signed>(sel_x + half_w, x + w) &&
+ max(sel_y, y) <= min<signed>(sel_y + half_w, y + h)))
dosel = False;
}
if (dohilite && highlight && (menu.hilite_pixmap != ParentRelative)) {
if (menu.hilite_pixmap)
XCopyArea(display, menu.hilite_pixmap, menu.frame,
- screen.getMenuStyle()->hilite_gc, hoff_x, hoff_y,
+ hipen.gc(), hoff_x, hoff_y,
hilite_w, hilite_h, hilite_x, hilite_y);
else
- XFillRectangle(display, menu.frame,
- screen.getMenuStyle()->hilite_gc,
+ XFillRectangle(display, menu.frame, hipen.gc(),
hilite_x, hilite_y, hilite_w, hilite_h);
} else if (dosel && item->isSelected() &&
(menu.sel_pixmap != ParentRelative)) {
if (menu.sel_pixmap)
- XCopyArea(display, menu.sel_pixmap, menu.frame,
- screen.getMenuStyle()->hilite_gc, 0, 0,
+ XCopyArea(display, menu.sel_pixmap, menu.frame, hipen.gc(), 0, 0,
half_w, half_w, sel_x, sel_y);
else
- XFillRectangle(display, menu.frame,
- screen.getMenuStyle()->hilite_gc,
- sel_x, sel_y, half_w, half_w);
+ XFillRectangle(display, menu.frame, hipen.gc(), sel_x, sel_y, half_w, half_w);
}
if (dotext && text) {
if (i18n.multibyte())
- XmbDrawString(display, menu.frame, screen.getMenuStyle()->f_fontset,
- tgc, text_x, text_y, text, len);
+ XmbDrawString(display, menu.frame, screen->getMenuStyle()->f_fontset,
+ textpen.gc(), text_x, text_y, text, len);
else
- XDrawString(display, menu.frame, tgc, text_x, text_y, text, len);
+ XDrawString(display, menu.frame, textpen.gc(), text_x, text_y, text, len);
}
if (dosel && item->submenu()) {
- switch (screen.getMenuStyle()->bullet) {
+ switch (screen->getMenuStyle()->bullet) {
case Square:
- XDrawRectangle(display, menu.frame, gc, sel_x, sel_y, half_w, half_w);
+ XDrawRectangle(display, menu.frame, pen.gc(), sel_x, sel_y, half_w, half_w);
break;
case Triangle:
XPoint tri[3];
- if (screen.getMenuStyle()->bullet_pos == Right) {
+ if (screen->getMenuStyle()->bullet_pos == Right) {
tri[0].x = sel_x + quarter_w - 2;
tri[0].y = sel_y + quarter_w - 2;
tri[1].x = 4;
tri[2].y = -4;
}
- XFillPolygon(display, menu.frame, gc, tri, 3, Convex,
+ XFillPolygon(display, menu.frame, pen.gc(), tri, 3, Convex,
CoordModePrevious);
break;
dia[3].x = -3;
dia[3].y = 3;
- XFillPolygon(display, menu.frame, gc, dia, 4, Convex,
+ XFillPolygon(display, menu.frame, pen.gc(), dia, 4, Convex,
CoordModePrevious);
break;
}
}
-void Basemenu::setLabel(const char *l) {
- if (menu.label)
- delete [] menu.label;
-
- if (l) menu.label = bstrdup(l);
- else menu.label = 0;
+void Basemenu::setLabel(const string& label) {
+ menu.label = label;
}
void Basemenu::setItemSelected(int index, bool sel) {
- if (index < 0 || index >= (signed)menuitems.size()) return;
-
+ assert(index >= 0);
BasemenuItem *item = find(index);
if (! item) return;
bool Basemenu::isItemSelected(int index) {
- if (index < 0 || index >= (signed)menuitems.size()) return false;
-
+ assert(index >= 0);
BasemenuItem *item = find(index);
- if (! item) return false;
+ if (! item) return False;
return item->isSelected();
}
void Basemenu::setItemEnabled(int index, bool enable) {
- if (index < 0 || index >= (signed)menuitems.size()) return;
-
+ assert(index >= 0);
BasemenuItem *item = find(index);
if (! item) return;
bool Basemenu::isItemEnabled(int index) {
- if (index < 0 || index >= (signed)menuitems.size()) return false;
-
+ assert(index >= 0);
BasemenuItem *item = find(index);
if (! item) return False;
int sbl = (be->x / menu.item_w), i = (be->y / menu.item_h);
int w = (sbl * menu.persub) + i;
- if (w < (signed)menuitems.size() && w >= 0) {
+ BasemenuItem *item = find(w);
+ if (item) {
which_press = i;
which_sbl = sbl;
- BasemenuItem *item = menuitems[w];
if (item->submenu())
drawSubmenu(w);
drawSubmenu(which_sub);
}
- if (re->x >= 0 && re->x <= (signed) menu.width &&
- re->y >= 0 && re->y <= (signed) menu.title_h)
+ if (re->x >= 0 && re->x <= static_cast<signed>(menu.width) &&
+ re->y >= 0 && re->y <= static_cast<signed>(menu.title_h))
if (re->button == 3)
hide();
} else if (re->window == menu.frame &&
- re->x >= 0 && re->x < (signed) menu.width &&
- re->y >= 0 && re->y < (signed) menu.frame_h) {
+ re->x >= 0 && re->x < static_cast<signed>(menu.width) &&
+ re->y >= 0 && re->y < static_cast<signed>(menu.frame_h)) {
if (re->button == 3) {
hide();
} else {
int sbl = (re->x / menu.item_w), i = (re->y / menu.item_h),
- ix = sbl * menu.item_w, iy = i * menu.item_h,
- w = (sbl * menu.persub) + i,
- p = (which_sbl * menu.persub) + which_press;
+ ix = sbl * menu.item_w, iy = i * menu.item_h,
+ w = (sbl * menu.persub) + i,
+ p = (which_sbl * menu.persub) + which_press;
- if (w < (signed)menuitems.size() && w >= 0) {
+ if (w >= 0 && w < static_cast<signed>(menuitems.size())) {
drawItem(p, (p == which_sub), True);
if (p == w && isItemEnabled(w)) {
- if (re->x > ix && re->x < (signed) (ix + menu.item_w) &&
- re->y > iy && re->y < (signed) (iy + menu.item_h)) {
+ if (re->x > ix && re->x < static_cast<signed>(ix + menu.item_w) &&
+ re->y > iy && re->y < static_cast<signed>(iy + menu.item_h)) {
itemSelected(re->button, w);
}
}
- } else
+ } else {
drawItem(p, False, True);
+ }
}
}
}
drawSubmenu(which_sub);
} else {
menu.x = me->x_root - menu.x_move,
- menu.y = me->y_root - menu.y_move;
+ menu.y = me->y_root - menu.y_move;
XMoveWindow(display, menu.window, menu.x, menu.y);
}
}
} else if ((! (me->state & Button1Mask)) && me->window == menu.frame &&
- me->x >= 0 && me->x < (signed) menu.width &&
- me->y >= 0 && me->y < (signed) menu.frame_h) {
+ me->x >= 0 && me->x < static_cast<signed>(menu.width) &&
+ me->y >= 0 && me->y < static_cast<signed>(menu.frame_h)) {
int sbl = (me->x / menu.item_w), i = (me->y / menu.item_h),
- w = (sbl * menu.persub) + i;
+ w = (sbl * menu.persub) + i;
if ((i != which_press || sbl != which_sbl) &&
- (w < (signed)menuitems.size() && w >= 0)) {
+ (w >= 0 && w < static_cast<signed>(menuitems.size()))) {
if (which_press != -1 && which_sbl != -1) {
int p = (which_sbl * menu.persub) + which_press;
- BasemenuItem *item = menuitems[p];
+ BasemenuItem *item = find(p);
drawItem(p, False, True);
if (item->submenu())
which_press = i;
which_sbl = sbl;
- BasemenuItem *itmp = menuitems[w];
+ BasemenuItem *itmp = find(w);
if (itmp->submenu())
drawSubmenu(w);
// items down in that sublevel
int sbl = (ee->x / menu.item_w), id = (ee->y / menu.item_h),
- // next... figure out how many sublevels over the redraw spans
- sbl_d = ((ee->x + ee->width) / menu.item_w),
- // then we see how many items down to redraw
- id_d = ((ee->y + ee->height) / menu.item_h);
+ // next... figure out how many sublevels over the redraw spans
+ sbl_d = ((ee->x + ee->width) / menu.item_w),
+ // then we see how many items down to redraw
+ id_d = ((ee->y + ee->height) / menu.item_h);
if (id_d > menu.persub) id_d = menu.persub;
// draw the sublevels and the number of items the exposure spans
- menuitemList::const_iterator it = menuitems.begin();
+ MenuItems::iterator it,
+ end = menuitems.end();
int i, ii;
for (i = sbl; i <= sbl_d; i++) {
// set the iterator to the first item in the sublevel needing redrawing
it = menuitems.begin() + (id + (i * menu.persub));
- for (ii = id; ii <= id_d && it != menuitems.end(); it++, ii++) {
+ for (ii = id; ii <= id_d && it != end; ++it, ii++) {
int index = ii + (i * menu.persub);
// redraw the item
drawItem(index, (which_sub == index), False,
void Basemenu::enterNotifyEvent(XCrossingEvent *ce) {
if (ce->window == menu.frame) {
menu.x_shift = menu.x, menu.y_shift = menu.y;
- if (menu.x + menu.width > screen.size().w()) {
- menu.x_shift = screen.size().w() - menu.width -
- screen.getBorderWidth();
+ if (menu.x + menu.width > screen->getWidth()) {
+ menu.x_shift = screen->getWidth() - menu.width -
+ screen->getBorderWidth();
shifted = True;
} else if (menu.x < 0) {
- menu.x_shift = -screen.getBorderWidth();
+ menu.x_shift = -screen->getBorderWidth();
shifted = True;
}
- if (menu.y + menu.height > screen.size().h()) {
- menu.y_shift = screen.size().h() - menu.height -
- screen.getBorderWidth();
+ if (menu.y + menu.height > screen->getHeight()) {
+ menu.y_shift = screen->getHeight() - menu.height -
+ screen->getBorderWidth();
shifted = True;
- } else if (menu.y + (signed) menu.title_h < 0) {
- menu.y_shift = -screen.getBorderWidth();
+ } else if (menu.y + static_cast<signed>(menu.title_h) < 0) {
+ menu.y_shift = -screen->getBorderWidth();
shifted = True;
}
XMoveWindow(display, menu.window, menu.x_shift, menu.y_shift);
if (which_sub != -1) {
- BasemenuItem *tmp = menuitems[which_sub];
+ BasemenuItem *tmp = find(which_sub);
if (tmp->submenu()->isVisible()) {
int sbl = (ce->x / menu.item_w), i = (ce->y / menu.item_h),
- w = (sbl * menu.persub) + i;
+ w = (sbl * menu.persub) + i;
if (w != which_sub && (! tmp->submenu()->isTorn())) {
tmp->submenu()->internal_hide();
void Basemenu::reconfigure(void) {
XSetWindowBackground(display, menu.window,
- screen.getBorderColor()->getPixel());
+ screen->getBorderColor()->pixel());
XSetWindowBorder(display, menu.window,
- screen.getBorderColor()->getPixel());
- XSetWindowBorderWidth(display, menu.window, screen.getBorderWidth());
+ screen->getBorderColor()->pixel());
+ XSetWindowBorderWidth(display, menu.window, screen->getBorderWidth());
- menu.bevel_w = screen.getBevelWidth();
+ menu.bevel_w = screen->getBevelWidth();
update();
}
+
+
+void Basemenu::changeItemLabel(unsigned int index, const string& label) {
+ BasemenuItem *item = find(index);
+ assert(item);
+ item->newLabel(label);
+}
+++ /dev/null
-// Basemenu.h for Openbox
-// Copyright (c) 2001 Sean 'Shaleh' Perry <shaleh@debian.org>
-// Copyright (c) 1997 - 2000 Brad Hughes (bhughes@tcac.net)
-//
-// Permission is hereby granted, free of charge, to any person obtaining a
-// copy of this software and associated documentation files (the "Software"),
-// to deal in the Software without restriction, including without limitation
-// the rights to use, copy, modify, merge, publish, distribute, sublicense,
-// and/or sell copies of the Software, and to permit persons to whom the
-// Software is furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-// DEALINGS IN THE SOFTWARE.
-
-#ifndef __Basemenu_hh
-#define __Basemenu_hh
-
-#include <X11/Xlib.h>
-
-class Openbox;
-class BImageControl;
-class BScreen;
-class Basemenu;
-class BasemenuItem;
-#include <vector>
-typedef std::vector<BasemenuItem *> menuitemList;
-
-class Basemenu {
-private:
- menuitemList menuitems;
- Openbox &openbox;
- Basemenu *parent;
- BImageControl *image_ctrl;
- BScreen &screen;
-
- Bool moving, visible, movable, torn, internal_menu, title_vis, shifted,
- hide_tree;
- Display *display;
- int which_sub, which_press, which_sbl, alignment;
-
- struct _menu {
- Pixmap frame_pixmap, title_pixmap, hilite_pixmap, sel_pixmap;
- Window window, frame, title;
-
- char *label;
- int x, y, x_move, y_move, x_shift, y_shift, sublevels, persub, minsub,
- grab_x, grab_y;
- unsigned int width, height, title_h, frame_h, item_w, item_h, bevel_w,
- bevel_h;
- } menu;
-
-
-protected:
- inline BasemenuItem *find(int index) { return menuitems[index]; }
- inline void setTitleVisibility(Bool b) { title_vis = b; }
- inline void setMovable(Bool b) { movable = b; }
- inline void setHideTree(Bool h) { hide_tree = h; }
- inline void setMinimumSublevels(int m) { menu.minsub = m; }
-
- virtual void itemSelected(int, int) = 0;
- virtual void drawItem(int, Bool = False, Bool = False,
- int = -1, int = -1, unsigned int = 0,
- unsigned int = 0);
- virtual void redrawTitle();
- virtual void internal_hide(void);
-
-
-public:
- Basemenu(BScreen &);
- virtual ~Basemenu(void);
-
- inline const Bool &isTorn(void) const { return torn; }
- inline const Bool &isVisible(void) const { return visible; }
-
- inline BScreen &getScreen(void) { return screen; }
-
- inline const Window &getWindowID(void) const { return menu.window; }
-
- inline const char *getLabel(void) const { return menu.label; }
-
- int insert(const char *, int = 0, const char * = (const char *) 0, int = -1);
- int insert(const char **, int = -1, int = 0);
- int insert(const char *, Basemenu *, int = -1);
- int remove(int);
-
- inline int getX(void) const { return menu.x; }
- inline int getY(void) const { return menu.y; }
- inline unsigned int getCount(void) { return menuitems.size(); }
- inline int getCurrentSubmenu(void) const { return which_sub; }
-
- inline unsigned int getWidth(void) const { return menu.width; }
- inline unsigned int getHeight(void) const { return menu.height; }
- inline unsigned int getTitleHeight(void) const { return menu.title_h; }
-
- inline void setInternalMenu(void) { internal_menu = True; }
- inline void setAlignment(int a) { alignment = a; }
- inline void setTorn(void) { torn = True; }
- inline void removeParent(void)
- { if (internal_menu) parent = (Basemenu *) 0; }
-
- bool hasSubmenu(int);
- bool isItemSelected(int);
- bool isItemEnabled(int);
-
- void buttonPressEvent(XButtonEvent *);
- void buttonReleaseEvent(XButtonEvent *);
- void motionNotifyEvent(XMotionEvent *);
- void enterNotifyEvent(XCrossingEvent *);
- void leaveNotifyEvent(XCrossingEvent *);
- void exposeEvent(XExposeEvent *);
- void reconfigure(void);
- void setLabel(const char *n);
- void move(int, int);
- void update(void);
- void setItemSelected(int, bool);
- void setItemEnabled(int, bool);
-
- virtual void drawSubmenu(int);
- virtual void show(void);
- virtual void hide(void);
-
- enum { AlignDontCare = 1, AlignTop, AlignBottom };
- enum { Right = 1, Left };
- enum { Empty = 0, Square, Triangle, Diamond };
-};
-
-
-class BasemenuItem {
-private:
- Basemenu *s;
- const char **u, *l, *e;
- int f, enabled, selected;
-
- friend class Basemenu;
-
-protected:
-
-public:
- BasemenuItem(const char *lp, int fp, const char *ep = (const char *) 0):
- s(0), u(0), l(lp), e(ep), f(fp), enabled(1), selected(0) {}
-
- BasemenuItem(const char *lp, Basemenu *mp): s(mp), u(0), l(lp), e(0), f(0),
- enabled(1), selected(0) {}
-
- BasemenuItem(const char **up, int fp): s(0), u(up), l(0), e(0), f(fp),
- enabled(1), selected(0) {}
-
- inline const char *exec(void) const { return e; }
- inline const char *label(void) const { return l; }
- inline const char **ulabel(void) const { return u; }
- inline const int &function(void) const { return f; }
- inline Basemenu *submenu(void) { return s; }
-
- inline const int &isEnabled(void) const { return enabled; }
- inline void setEnabled(int e) { enabled = e; }
- inline const int &isSelected(void) const { return selected; }
- inline void setSelected(int s) { selected = s; }
-};
-
-
-#endif // __Basemenu_hh
-// Clientmenu.cc for Openbox
-// Copyright (c) 2001 Sean 'Shaleh' Perry <shaleh@debian.org>
+// -*- mode: C++; indent-tabs-mode: nil; -*-
+// Clientmenu.cc for Blackbox - an X11 Window manager
+// Copyright (c) 2001 - 2002 Sean 'Shaleh' Perry <shaleh@debian.org>
// Copyright (c) 1997 - 2000 Brad Hughes (bhughes@tcac.net)
//
// Permission is hereby granted, free of charge, to any person obtaining a
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
-// stupid macros needed to access some functions in version 2 of the GNU C
-// library
-#ifndef _GNU_SOURCE
-#define _GNU_SOURCE
-#endif // _GNU_SOURCE
-
#ifdef HAVE_CONFIG_H
# include "../config.h"
#endif // HAVE_CONFIG_H
-#include "openbox.h"
-#include "Clientmenu.h"
-#include "Screen.h"
-#include "Window.h"
-#include "Workspace.h"
-#include "Workspacemenu.h"
+#include "blackbox.hh"
+#include "Clientmenu.hh"
+#include "Screen.hh"
+#include "Window.hh"
+#include "Workspace.hh"
+#include "Workspacemenu.hh"
+
+Clientmenu::Clientmenu(Workspace *ws) : Basemenu(ws->getScreen()) {
+ wkspc = ws;
-Clientmenu::Clientmenu(Workspace &ws) : Basemenu(ws.getScreen()),
- screen(ws.getScreen()), wkspc(ws)
-{
setInternalMenu();
}
-void Clientmenu::itemSelected(int button, int index) {
+void Clientmenu::itemSelected(int button, unsigned int index) {
if (button > 2) return;
- OpenboxWindow *win = wkspc.getWindow(index);
+ BlackboxWindow *win = wkspc->getWindow(index);
if (win) {
if (button == 1) {
- if (! wkspc.isCurrent()) wkspc.setCurrent();
+ if (! wkspc->isCurrent()) wkspc->setCurrent();
} else if (button == 2) {
- if (! wkspc.isCurrent()) win->deiconify(True, False);
+ if (! wkspc->isCurrent()) win->deiconify(True, False);
}
- wkspc.raiseWindow(win);
+ wkspc->raiseWindow(win);
win->setInputFocus();
}
- if (! (screen.getWorkspacemenu()->isTorn() || isTorn())) hide();
+ Workspacemenu* wkspcmenu = wkspc->getScreen()->getWorkspacemenu();
+ if (! (wkspcmenu->isTorn() || isTorn())) hide();
}
-// Clientmenu.h for Openbox
-// Copyright (c) 2001 Sean 'Shaleh' Perry <shaleh@debian.org>
+// -*- mode: C++; indent-tabs-mode: nil; -*-
+// Clientmenu.hh for Blackbox - an X11 Window manager
+// Copyright (c) 2001 - 2002 Sean 'Shaleh' Perry <shaleh@debian.org>
// Copyright (c) 1997 - 2000 Brad Hughes (bhughes@tcac.net)
//
// Permission is hereby granted, free of charge, to any person obtaining a
#ifndef __Clientmenu_hh
#define __Clientmenu_hh
-#include "Basemenu.h"
+#include "Basemenu.hh"
class Workspace;
class BScreen;
class Clientmenu : public Basemenu {
private:
- BScreen &screen;
- Workspace &wkspc;
+ Workspace *wkspc;
+
+ Clientmenu(const Clientmenu&);
+ Clientmenu& operator=(const Clientmenu&);
protected:
- virtual void itemSelected(int, int);
+ virtual void itemSelected(int button, unsigned int index);
public:
- Clientmenu(Workspace &);
+ Clientmenu(Workspace *ws);
};
--- /dev/null
+// -*- mode: C++; indent-tabs-mode: nil; c-basic-offset: 2; -*-
+// Color.cc for Blackbox - an X11 Window manager
+// Copyright (c) 2001 - 2002 Sean 'Shaleh' Perry <shaleh at debian.org>
+// Copyright (c) 1997 - 2000, 2002 Bradley T Hughes <bhughes at trolltech.com>
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#ifdef HAVE_CONFIG_H
+# include "../config.h"
+#endif // HAVE_CONFIG_H
+
+#include "Color.hh"
+#include "BaseDisplay.hh"
+
+extern "C" {
+#include <stdio.h>
+}
+
+
+BColor::ColorCache BColor::colorcache;
+bool BColor::cleancache = false;
+
+BColor::BColor(const BaseDisplay * const _display, unsigned int _screen)
+ : allocated(false), r(-1), g(-1), b(-1), p(0), dpy(_display), scrn(_screen)
+{}
+
+BColor::BColor(int _r, int _g, int _b,
+ const BaseDisplay * const _display, unsigned int _screen)
+ : allocated(false), r(_r), g(_g), b(_b), p(0), dpy(_display), scrn(_screen)
+{}
+
+
+BColor::BColor(const std::string &_name,
+ const BaseDisplay * const _display, unsigned int _screen)
+ : allocated(false), r(-1), g(-1), b(-1), p(0), dpy(_display), scrn(_screen),
+ colorname(_name) {
+ parseColorName();
+}
+
+
+BColor::~BColor(void) {
+ deallocate();
+}
+
+
+void BColor::setDisplay(const BaseDisplay * const _display,
+ unsigned int _screen) {
+ if (_display == display() && _screen == screen()) {
+ // nothing to do
+ return;
+ }
+
+ deallocate();
+
+ dpy = _display;
+ scrn = _screen;
+
+ if (! colorname.empty()) {
+ parseColorName();
+ }
+}
+
+
+unsigned long BColor::pixel(void) const {
+ if (! allocated) {
+ // mutable
+ BColor *that = (BColor *) this;
+ that->allocate();
+ }
+
+ return p;
+}
+
+
+void BColor::parseColorName(void) {
+ assert(dpy != 0);
+
+ if (colorname.empty()) {
+ fprintf(stderr, "BColor: empty colorname, cannot parse (using black)\n");
+ setRGB(0, 0, 0);
+ }
+
+ if (scrn == ~(0u))
+ scrn = DefaultScreen(display()->getXDisplay());
+ Colormap colormap = display()->getScreenInfo(scrn)->getColormap();
+
+ // get rgb values from colorname
+ XColor xcol;
+ xcol.red = 0;
+ xcol.green = 0;
+ xcol.blue = 0;
+ xcol.pixel = 0;
+
+ if (! XParseColor(display()->getXDisplay(), colormap,
+ colorname.c_str(), &xcol)) {
+ fprintf(stderr, "BColor::allocate: color parse error: \"%s\"\n",
+ colorname.c_str());
+ setRGB(0, 0, 0);
+ return;
+ }
+
+ setRGB(xcol.red >> 8, xcol.green >> 8, xcol.blue >> 8);
+}
+
+
+void BColor::allocate(void) {
+ assert(dpy != 0);
+
+ if (scrn == ~(0u)) scrn = DefaultScreen(display()->getXDisplay());
+ Colormap colormap = display()->getScreenInfo(scrn)->getColormap();
+
+ if (! isValid()) {
+ if (colorname.empty()) {
+ fprintf(stderr, "BColor: cannot allocate invalid color (using black)\n");
+ setRGB(0, 0, 0);
+ } else {
+ parseColorName();
+ }
+ }
+
+ // see if we have allocated this color before
+ RGB rgb(display(), scrn, r, g, b);
+ ColorCache::iterator it = colorcache.find(rgb);
+ if (it != colorcache.end()) {
+ // found
+ allocated = true;
+ p = (*it).second.p;
+ (*it).second.count++;
+ return;
+ }
+
+ // allocate color from rgb values
+ XColor xcol;
+ xcol.red = r | r << 8;
+ xcol.green = g | g << 8;
+ xcol.blue = b | b << 8;
+ xcol.pixel = 0;
+
+ if (! XAllocColor(display()->getXDisplay(), colormap, &xcol)) {
+ fprintf(stderr, "BColor::allocate: color alloc error: rgb:%x/%x/%x\n",
+ r, g, b);
+ xcol.pixel = 0;
+ }
+
+ p = xcol.pixel;
+ allocated = true;
+
+ colorcache.insert(ColorCacheItem(rgb, PixelRef(p)));
+
+ if (cleancache)
+ doCacheCleanup();
+}
+
+
+void BColor::deallocate(void) {
+ if (! allocated)
+ return;
+
+ assert(dpy != 0);
+
+ ColorCache::iterator it = colorcache.find(RGB(display(), scrn, r, g, b));
+ if (it != colorcache.end()) {
+ if ((*it).second.count >= 1)
+ (*it).second.count--;
+ }
+
+ if (cleancache)
+ doCacheCleanup();
+
+ allocated = false;
+}
+
+
+BColor &BColor::operator=(const BColor &c) {
+ deallocate();
+
+ setRGB(c.r, c.g, c.b);
+ colorname = c.colorname;
+ dpy = c.dpy;
+ scrn = c.scrn;
+ return *this;
+}
+
+
+void BColor::cleanupColorCache(void) {
+ cleancache = true;
+}
+
+
+void BColor::doCacheCleanup(void) {
+ // ### TODO - support multiple displays!
+ ColorCache::iterator it = colorcache.begin();
+ if (it == colorcache.end()) {
+ // nothing to do
+ return;
+ }
+
+ const BaseDisplay* const display = (*it).first.display;
+ unsigned long *pixels = new unsigned long[ colorcache.size() ];
+ unsigned int i, count;
+
+ for (i = 0; i < display->getNumberOfScreens(); i++) {
+ count = 0;
+ it = colorcache.begin();
+
+ while (it != colorcache.end()) {
+ if ((*it).second.count != 0 || (*it).first.screen != i) {
+ ++it;
+ continue;
+ }
+
+ pixels[ count++ ] = (*it).second.p;
+ ColorCache::iterator it2 = it;
+ ++it;
+ colorcache.erase(it2);
+ }
+
+ if (count > 0)
+ XFreeColors(display->getXDisplay(),
+ display->getScreenInfo(i)->getColormap(),
+ pixels, count, 0);
+ }
+
+ delete [] pixels;
+ cleancache = false;
+}
--- /dev/null
+// -*- mode: C++; indent-tabs-mode: nil; c-basic-offset: 2; -*-
+// Color.hh for Blackbox - an X11 Window manager
+// Copyright (c) 2001 - 2002 Sean 'Shaleh' Perry <shaleh at debian.org>
+// Copyright (c) 1997 - 2000, 2002 Bradley T Hughes <bhughes at trolltech.com>
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#ifndef COLOR_HH
+#define COLOR_HH
+
+extern "C" {
+#include <X11/Xlib.h>
+}
+
+#include <map>
+#include <string>
+
+class BaseDisplay;
+
+class BColor {
+public:
+ BColor(const BaseDisplay * const _display = 0, unsigned int _screen = ~(0u));
+ BColor(int _r, int _g, int _b,
+ const BaseDisplay * const _display, unsigned int _screen = ~(0u));
+ BColor(const std::string &_name,
+ const BaseDisplay * const _display, unsigned int _screen = ~(0u));
+ ~BColor(void);
+
+ inline const std::string &name(void) const { return colorname; }
+
+ inline int red(void) const { return r; }
+ inline int green(void) const { return g; }
+ inline int blue(void) const { return b; }
+ void setRGB(int _r, int _g, int _b) {
+ deallocate();
+ r = _r;
+ g = _g;
+ b = _b;
+ }
+
+ inline const BaseDisplay *display(void) const { return dpy; }
+ inline unsigned int screen(void) const { return scrn; }
+ void setDisplay(const BaseDisplay * const _display,
+ unsigned int _screen = ~(0u));
+
+ inline bool isAllocated(void) const { return allocated; }
+
+ inline bool isValid(void) const { return r != -1 && g != -1 && b != -1; }
+
+ unsigned long pixel(void) const;
+
+ // operators
+ BColor &operator=(const BColor &c);
+ inline bool operator==(const BColor &c) const
+ { return (r == c.r && b == c.b && b == c.b); }
+ inline bool operator!=(const BColor &c) const
+ { return (! operator==(c)); }
+
+ static void cleanupColorCache(void);
+
+private:
+ void parseColorName(void);
+ void allocate(void);
+ void deallocate(void);
+
+ bool allocated;
+ int r, g, b;
+ unsigned long p;
+ const BaseDisplay *dpy;
+ unsigned int scrn;
+ std::string colorname;
+
+ // global color allocator/deallocator
+ struct RGB {
+ const BaseDisplay* const display;
+ const unsigned int screen;
+ const int r, g, b;
+
+ RGB(void) : display(0), screen(~(0u)), r(-1), g(-1), b(-1) { }
+ RGB(const BaseDisplay * const a, const unsigned int b,
+ const int x, const int y, const int z)
+ : display(a), screen(b), r(x), g(y), b(z) {}
+ RGB(const RGB &x)
+ : display(x.display), screen(x.screen), r(x.r), g(x.g), b(x.b) {}
+
+ inline bool operator==(const RGB &x) const {
+ return display == x.display &&
+ screen == x.screen &&
+ r == x.r && g == x.g && b == x.b;
+ }
+
+ inline bool operator<(const RGB &x) const {
+ unsigned long p1, p2;
+ p1 = (screen << 24 | r << 16 | g << 8 | b) & 0x00ffffff;
+ p2 = (x.screen << 24 | x.r << 16 | x.g << 8 | x.b) & 0x00ffffff;
+ return p1 < p2;
+ }
+ };
+ struct PixelRef {
+ const unsigned long p;
+ unsigned int count;
+ inline PixelRef(void) : p(0), count(0) { }
+ inline PixelRef(const unsigned long x) : p(x), count(1) { }
+ };
+ typedef std::map<RGB,PixelRef> ColorCache;
+ typedef ColorCache::value_type ColorCacheItem;
+ static ColorCache colorcache;
+ static bool cleancache;
+ static void doCacheCleanup(void);
+};
+
+#endif // COLOR_HH
-// Configmenu.cc for Openbox
-// Copyright (c) 2002 - 2002 Ben Jansens <ben@orodu.net>
-// Copyright (c) 2001 Sean 'Shaleh' Perry <shaleh@debian.org>
+// -*- mode: C++; indent-tabs-mode: nil; c-basic-offset: 2; -*-
+// Configmenu.cc for Blackbox - An X11 Window Manager
+// Copyright (c) 2001 - 2002 Sean 'Shaleh' Perry <shaleh@debian.org>
// Copyright (c) 1997 - 2000 Brad Hughes (bhughes@tcac.net)
//
// Permission is hereby granted, free of charge, to any person obtaining a
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
-// stupid macros needed to access some functions in version 2 of the GNU C
-// library
-#ifndef _GNU_SOURCE
-# define _GNU_SOURCE
-#endif // _GNU_SOURCE
-
#ifdef HAVE_CONFIG_H
# include "../config.h"
#endif // HAVE_CONFIG_H
-#include "i18n.h"
-#include "Configmenu.h"
-#include "Toolbar.h"
-#include "Window.h"
-#include "Screen.h"
+#include "i18n.hh"
+#include "Configmenu.hh"
+#include "Image.hh"
+#include "Toolbar.hh"
+#include "Window.hh"
+#include "Screen.hh"
-Configmenu::Configmenu(BScreen &scr) : Basemenu(scr), screen(scr)
-{
- setLabel(i18n(ConfigmenuSet, ConfigmenuConfigOptions,
- "Config options"));
+Configmenu::Configmenu(BScreen *scr) : Basemenu(scr) {
+ setLabel(i18n(ConfigmenuSet, ConfigmenuConfigOptions, "Config options"));
setInternalMenu();
focusmenu = new Focusmenu(this);
"Focus New Windows"), 4);
insert(i18n(ConfigmenuSet, ConfigmenuFocusLast,
"Focus Last Window on Workspace"), 5);
- insert(i18n(ConfigmenuSet, ConfigmenuHideToolbar,
- "Hide toolbar"), 6);
update();
- setValues();
-}
-
-void Configmenu::setValues() {
- setItemSelected(2, screen.imageDither());
- setItemSelected(3, screen.opaqueMove());
- setItemSelected(4, screen.fullMax());
- setItemSelected(5, screen.focusNew());
- setItemSelected(6, screen.focusLast());
- setItemSelected(7, screen.hideToolbar());
+ setItemSelected(2, getScreen()->getImageControl()->doDither());
+ setItemSelected(3, getScreen()->doOpaqueMove());
+ setItemSelected(4, getScreen()->doFullMax());
+ setItemSelected(5, getScreen()->doFocusNew());
+ setItemSelected(6, getScreen()->doFocusLast());
}
-Configmenu::~Configmenu() {
+Configmenu::~Configmenu(void) {
delete focusmenu;
delete placementmenu;
}
-void Configmenu::itemSelected(int button, int index) {
+void Configmenu::itemSelected(int button, unsigned int index) {
if (button != 1)
return;
switch(item->function()) {
case 1: { // dither
- screen.setImageDither(!screen.imageDither());
+ getScreen()->getImageControl()->
+ setDither((! getScreen()->getImageControl()->doDither()));
- setItemSelected(index, screen.imageDither());
+ setItemSelected(index, getScreen()->getImageControl()->doDither());
break;
}
case 2: { // opaque move
- screen.setOpaqueMove(!screen.opaqueMove());
+ getScreen()->saveOpaqueMove((! getScreen()->doOpaqueMove()));
- setItemSelected(index, screen.opaqueMove());
+ setItemSelected(index, getScreen()->doOpaqueMove());
break;
}
case 3: { // full maximization
- screen.setFullMax(!screen.fullMax());
+ getScreen()->saveFullMax((! getScreen()->doFullMax()));
- setItemSelected(index, screen.fullMax());
+ setItemSelected(index, getScreen()->doFullMax());
break;
}
case 4: { // focus new windows
- screen.setFocusNew(!screen.focusNew());
+ getScreen()->saveFocusNew((! getScreen()->doFocusNew()));
- setItemSelected(index, screen.focusNew());
+ setItemSelected(index, getScreen()->doFocusNew());
break;
}
case 5: { // focus last window on workspace
- screen.setFocusLast(!screen.focusLast());
- setItemSelected(index, screen.focusLast());
- break;
- }
- case 6:{ //toggle toolbar hide
- screen.setHideToolbar(!screen.hideToolbar());
- setItemSelected(index, screen.hideToolbar());
+ getScreen()->saveFocusLast((! getScreen()->doFocusLast()));
+ setItemSelected(index, getScreen()->doFocusLast());
break;
}
} // switch
}
-void Configmenu::reconfigure() {
- setValues();
+
+void Configmenu::reconfigure(void) {
focusmenu->reconfigure();
placementmenu->reconfigure();
Basemenu::reconfigure();
}
-Configmenu::Focusmenu::Focusmenu(Configmenu *cm) : Basemenu(cm->screen) {
- configmenu = cm;
- setLabel(i18n(ConfigmenuSet, ConfigmenuFocusModel,
- "Focus Model"));
+Configmenu::Focusmenu::Focusmenu(Configmenu *cm) : Basemenu(cm->getScreen()) {
+ setLabel(i18n(ConfigmenuSet, ConfigmenuFocusModel, "Focus Model"));
setInternalMenu();
- insert(i18n(ConfigmenuSet, ConfigmenuClickToFocus,
- "Click To Focus"), 1);
- insert(i18n(ConfigmenuSet, ConfigmenuSloppyFocus,
- "Sloppy Focus"), 2);
- insert(i18n(ConfigmenuSet, ConfigmenuAutoRaise,
- "Auto Raise"), 3);
+ insert(i18n(ConfigmenuSet, ConfigmenuClickToFocus, "Click To Focus"), 1);
+ insert(i18n(ConfigmenuSet, ConfigmenuSloppyFocus, "Sloppy Focus"), 2);
+ insert(i18n(ConfigmenuSet, ConfigmenuAutoRaise, "Auto Raise"), 3);
+ insert(i18n(ConfigmenuSet, ConfigmenuClickRaise, "Click Raise"), 4);
update();
- setValues();
+ setItemSelected(0, (! getScreen()->isSloppyFocus()));
+ setItemSelected(1, getScreen()->isSloppyFocus());
+ setItemEnabled(2, getScreen()->isSloppyFocus());
+ setItemSelected(2, getScreen()->doAutoRaise());
+ setItemEnabled(3, getScreen()->isSloppyFocus());
+ setItemSelected(3, getScreen()->doClickRaise());
}
-void Configmenu::Focusmenu::setValues() {
- setItemSelected(0, !configmenu->screen.sloppyFocus());
- setItemSelected(1, configmenu->screen.sloppyFocus());
- setItemEnabled(2, configmenu->screen.sloppyFocus());
- setItemSelected(2, configmenu->screen.autoRaise());
-}
-void Configmenu::Focusmenu::reconfigure() {
- setValues();
- Basemenu::reconfigure();
-}
-
-void Configmenu::Focusmenu::itemSelected(int button, int index) {
+void Configmenu::Focusmenu::itemSelected(int button, unsigned int index) {
if (button != 1)
return;
switch (item->function()) {
case 1: // click to focus
- configmenu->screen.setSloppyFocus(false);
- configmenu->screen.setAutoRaise(false);
- // make windows all grab button1 clicks
- configmenu->screen.reconfigure();
+ getScreen()->toggleFocusModel(BScreen::ClickToFocus);
break;
case 2: // sloppy focus
- configmenu->screen.setSloppyFocus(true);
- // make windows stop grabbing button1 clicks
- configmenu->screen.reconfigure();
+ getScreen()->toggleFocusModel(BScreen::SloppyFocus);
break;
case 3: // auto raise with sloppy focus
- configmenu->screen.setAutoRaise(!configmenu->screen.autoRaise());
+ getScreen()->saveAutoRaise(! getScreen()->doAutoRaise());
+ break;
+
+ case 4: // click raise with sloppy focus
+ getScreen()->saveClickRaise(! getScreen()->doClickRaise());
+ getScreen()->updateFocusModel();
break;
}
- setItemSelected(0, !configmenu->screen.sloppyFocus());
- setItemSelected(1, configmenu->screen.sloppyFocus());
- setItemEnabled(2, configmenu->screen.sloppyFocus());
- setItemSelected(2, configmenu->screen.autoRaise());
+ setItemSelected(0, (! getScreen()->isSloppyFocus()));
+ setItemSelected(1, getScreen()->isSloppyFocus());
+ setItemEnabled(2, getScreen()->isSloppyFocus());
+ setItemSelected(2, getScreen()->doAutoRaise());
+ setItemEnabled(3, getScreen()->isSloppyFocus());
+ setItemSelected(3, getScreen()->doClickRaise());
}
-Configmenu::Placementmenu::Placementmenu(Configmenu *cm) :
-Basemenu(cm->screen) {
- configmenu = cm;
- setLabel(i18n(ConfigmenuSet, ConfigmenuWindowPlacement,
- "Window Placement"));
+Configmenu::Placementmenu::Placementmenu(Configmenu *cm):
+ Basemenu(cm->getScreen()) {
+ setLabel(i18n(ConfigmenuSet, ConfigmenuWindowPlacement, "Window Placement"));
setInternalMenu();
- insert(i18n(ConfigmenuSet, ConfigmenuSmartRows,
- "Smart Placement (Rows)"),
+ insert(i18n(ConfigmenuSet, ConfigmenuSmartRows, "Smart Placement (Rows)"),
BScreen::RowSmartPlacement);
- insert(i18n(ConfigmenuSet, ConfigmenuSmartCols,
- "Smart Placement (Columns)"),
+ insert(i18n(ConfigmenuSet, ConfigmenuSmartCols, "Smart Placement (Columns)"),
BScreen::ColSmartPlacement);
- insert(i18n(ConfigmenuSet, ConfigmenuCascade,
- "Cascade Placement"), BScreen::CascadePlacement);
- insert(i18n(ConfigmenuSet, ConfigmenuBestFit,
- "Best Fit Placement"), BScreen::BestFitPlacement);
- insert(i18n(ConfigmenuSet, ConfigmenuUnderMouse,
- "Under Mouse Placement"),
- BScreen::UnderMousePlacement);
- insert(i18n(ConfigmenuSet, ConfigmenuClickMouse,
- "Click Mouse Placement"),
- BScreen::ClickMousePlacement);
- insert(i18n(ConfigmenuSet, ConfigmenuLeftRight,
- "Left to Right"), BScreen::LeftRight);
- insert(i18n(ConfigmenuSet, ConfigmenuRightLeft,
- "Right to Left"), BScreen::RightLeft);
- insert(i18n(ConfigmenuSet, ConfigmenuTopBottom,
- "Top to Bottom"), BScreen::TopBottom);
- insert(i18n(ConfigmenuSet, ConfigmenuBottomTop,
- "Bottom to Top"), BScreen::BottomTop);
+ insert(i18n(ConfigmenuSet, ConfigmenuCascade, "Cascade Placement"),
+ BScreen::CascadePlacement);
+ insert(i18n(ConfigmenuSet, ConfigmenuLeftRight, "Left to Right"),
+ BScreen::LeftRight);
+ insert(i18n(ConfigmenuSet, ConfigmenuRightLeft, "Right to Left"),
+ BScreen::RightLeft);
+ insert(i18n(ConfigmenuSet, ConfigmenuTopBottom, "Top to Bottom"),
+ BScreen::TopBottom);
+ insert(i18n(ConfigmenuSet, ConfigmenuBottomTop, "Bottom to Top"),
+ BScreen::BottomTop);
update();
- setValues();
-}
+ switch (getScreen()->getPlacementPolicy()) {
+ case BScreen::RowSmartPlacement:
+ setItemSelected(0, True);
+ break;
+
+ case BScreen::ColSmartPlacement:
+ setItemSelected(1, True);
+ break;
-void Configmenu::Placementmenu::setValues() {
- const int p = configmenu->screen.placementPolicy();
- setItemSelected(0, p == BScreen::RowSmartPlacement);
- setItemSelected(1, p == BScreen::ColSmartPlacement);
- setItemSelected(2, p == BScreen::CascadePlacement);
- setItemSelected(3, p == BScreen::BestFitPlacement);
- setItemSelected(4, p == BScreen::UnderMousePlacement);
- setItemSelected(5, p == BScreen::ClickMousePlacement);
+ case BScreen::CascadePlacement:
+ setItemSelected(2, True);
+ break;
+ }
- bool rl = (configmenu->screen.rowPlacementDirection() ==
+ bool rl = (getScreen()->getRowPlacementDirection() ==
BScreen::LeftRight),
- tb = (configmenu->screen.colPlacementDirection() ==
- BScreen::TopBottom);
-
- setItemSelected(6, rl);
- setItemEnabled(6, (p != BScreen::UnderMousePlacement &&
- p != BScreen::ClickMousePlacement));
- setItemSelected(7, !rl);
- setItemEnabled(7, (p != BScreen::UnderMousePlacement &&
- p != BScreen::ClickMousePlacement));
-
- setItemSelected(8, tb);
- setItemEnabled(8, (p != BScreen::UnderMousePlacement &&
- p != BScreen::ClickMousePlacement));
- setItemSelected(9, !tb);
- setItemEnabled(9, (p != BScreen::UnderMousePlacement &&
- p != BScreen::ClickMousePlacement));
-}
+ tb = (getScreen()->getColPlacementDirection() ==
+ BScreen::TopBottom);
-void Configmenu::Placementmenu::reconfigure() {
- setValues();
- Basemenu::reconfigure();
+ setItemSelected(3, rl);
+ setItemSelected(4, ! rl);
+
+ setItemSelected(5, tb);
+ setItemSelected(6, ! tb);
}
-void Configmenu::Placementmenu::itemSelected(int button, int index) {
+
+void Configmenu::Placementmenu::itemSelected(int button, unsigned int index) {
if (button != 1)
return;
switch (item->function()) {
case BScreen::RowSmartPlacement:
- configmenu->screen.setPlacementPolicy(item->function());
+ getScreen()->savePlacementPolicy(item->function());
+
+ setItemSelected(0, True);
+ setItemSelected(1, False);
+ setItemSelected(2, False);
+
break;
case BScreen::ColSmartPlacement:
- configmenu->screen.setPlacementPolicy(item->function());
- break;
+ getScreen()->savePlacementPolicy(item->function());
- case BScreen::CascadePlacement:
- configmenu->screen.setPlacementPolicy(item->function());
- break;
+ setItemSelected(0, False);
+ setItemSelected(1, True);
+ setItemSelected(2, False);
- case BScreen::BestFitPlacement:
- configmenu->screen.setPlacementPolicy(item->function());
break;
- case BScreen::UnderMousePlacement:
- configmenu->screen.setPlacementPolicy(item->function());
- break;
+ case BScreen::CascadePlacement:
+ getScreen()->savePlacementPolicy(item->function());
+
+ setItemSelected(0, False);
+ setItemSelected(1, False);
+ setItemSelected(2, True);
- case BScreen::ClickMousePlacement:
- configmenu->screen.setPlacementPolicy(item->function());
break;
case BScreen::LeftRight:
- configmenu->screen.setRowPlacementDirection(BScreen::LeftRight);
+ getScreen()->saveRowPlacementDirection(BScreen::LeftRight);
+
+ setItemSelected(3, True);
+ setItemSelected(4, False);
+
break;
case BScreen::RightLeft:
- configmenu->screen.setRowPlacementDirection(BScreen::RightLeft);
+ getScreen()->saveRowPlacementDirection(BScreen::RightLeft);
+
+ setItemSelected(3, False);
+ setItemSelected(4, True);
+
break;
case BScreen::TopBottom:
- configmenu->screen.setColPlacementDirection(BScreen::TopBottom);
+ getScreen()->saveColPlacementDirection(BScreen::TopBottom);
+
+ setItemSelected(5, True);
+ setItemSelected(6, False);
+
break;
case BScreen::BottomTop:
- configmenu->screen.setColPlacementDirection(BScreen::BottomTop);
+ getScreen()->saveColPlacementDirection(BScreen::BottomTop);
+
+ setItemSelected(5, False);
+ setItemSelected(6, True);
+
break;
}
- setValues();
}
-// Configmenu.h for Openbox
-// Copyright (c) 2001 Sean 'Shaleh' Perry <shaleh@debian.org>
+// -*- mode: C++; indent-tabs-mode: nil; -*-
+// Configmenu.hh for Blackbox - An X11 Window Manager
+// Copyright (c) 2001 - 2002 Sean 'Shaleh' Perry <shaleh@debian.org>
// Copyright (c) 1997 - 2000 Brad Hughes (bhughes@tcac.net)
//
// Permission is hereby granted, free of charge, to any person obtaining a
#ifndef __Configmenu_hh
#define __Configmenu_hh
-#include "Basemenu.h"
+#include "Basemenu.hh"
// forward declaration
-class Openbox;
+class Blackbox;
class BScreen;
class Configmenu;
private:
class Focusmenu : public Basemenu {
private:
- Configmenu *configmenu;
+ Focusmenu(const Focusmenu&);
+ Focusmenu& operator=(const Focusmenu&);
protected:
- virtual void itemSelected(int, int);
- virtual void setValues();
+ virtual void itemSelected(int button, unsigned int index);
public:
- Focusmenu(Configmenu *);
- void reconfigure();
+ Focusmenu(Configmenu *cm);
};
class Placementmenu : public Basemenu {
private:
- Configmenu *configmenu;
+ Placementmenu(const Placementmenu&);
+ Placementmenu& operator=(const Placementmenu&);
protected:
- virtual void itemSelected(int, int);
- virtual void setValues();
-
+ virtual void itemSelected(int button, unsigned int index);
public:
- Placementmenu(Configmenu *);
- void reconfigure();
+ Placementmenu(Configmenu *cm);
};
- BScreen &screen;
Focusmenu *focusmenu;
Placementmenu *placementmenu;
friend class Focusmenu;
friend class Placementmenu;
-protected:
- virtual void itemSelected(int, int);
- virtual void setValues();
+ Configmenu(const Configmenu&);
+ Configmenu& operator=(const Configmenu&);
+protected:
+ virtual void itemSelected(int button, unsigned int index);
public:
- Configmenu(BScreen &);
- virtual ~Configmenu();
+ Configmenu(BScreen *scr);
+ virtual ~Configmenu(void);
- inline Basemenu *getFocusmenu() { return focusmenu; }
- inline Basemenu *getPlacementmenu() { return placementmenu; }
+ inline Basemenu *getFocusmenu(void) { return focusmenu; }
+ inline Basemenu *getPlacementmenu(void) { return placementmenu; }
- void reconfigure();
+ void reconfigure(void);
};
#endif // __Configmenu_hh
--- /dev/null
+// -*- mode: C++; indent-tabs-mode: nil; c-basic-offset: 2; -*-
+// GCCache.cc for Blackbox - an X11 Window manager
+// Copyright (c) 2001 - 2002 Sean 'Shaleh' Perry <shaleh at debian.org>
+// Copyright (c) 1997 - 2000, 2002 Bradley T Hughes <bhughes at trolltech.com>
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#ifdef HAVE_CONFIG_H
+# include "../config.h"
+#endif // HAVE_CONFIG_H
+
+extern "C" {
+#include <stdio.h>
+}
+
+#include "GCCache.hh"
+#include "BaseDisplay.hh"
+#include "Color.hh"
+#include "Util.hh"
+
+
+void BGCCacheContext::set(const BColor &_color,
+ const XFontStruct * const _font,
+ const int _function, const int _subwindow) {
+ XGCValues gcv;
+ pixel = gcv.foreground = _color.pixel();
+ function = gcv.function = _function;
+ subwindow = gcv.subwindow_mode = _subwindow;
+ unsigned long mask = GCForeground | GCFunction | GCSubwindowMode;
+
+ if (_font) {
+ fontid = gcv.font = _font->fid;
+ mask |= GCFont;
+ } else {
+ fontid = 0;
+ }
+
+ XChangeGC(display->getXDisplay(), gc, mask, &gcv);
+}
+
+
+void BGCCacheContext::set(const XFontStruct * const _font) {
+ if (! _font) {
+ fontid = 0;
+ return;
+ }
+
+ XGCValues gcv;
+ fontid = gcv.font = _font->fid;
+ XChangeGC(display->getXDisplay(), gc, GCFont, &gcv);
+}
+
+
+BGCCache::BGCCache(const BaseDisplay * const _display)
+ : display(_display), context_count(128u),
+ cache_size(16u), cache_buckets(8u),
+ cache_total_size(cache_size * cache_buckets) {
+
+ contexts = new BGCCacheContext*[context_count];
+ unsigned int i;
+ for (i = 0; i < context_count; i++) {
+ contexts[i] = new BGCCacheContext(display);
+ }
+
+ cache = new BGCCacheItem*[cache_total_size];
+ for (i = 0; i < cache_total_size; ++i) {
+ cache[i] = new BGCCacheItem;
+ }
+}
+
+
+BGCCache::~BGCCache(void) {
+ std::for_each(contexts, contexts + context_count, PointerAssassin());
+ std::for_each(cache, cache + cache_total_size, PointerAssassin());
+ delete [] cache;
+ delete [] contexts;
+ cache = 0;
+ contexts = 0;
+}
+
+
+BGCCacheContext *BGCCache::nextContext(unsigned int scr) {
+ Window hd = display->getScreenInfo(scr)->getRootWindow();
+
+ BGCCacheContext *c;
+
+ for (unsigned int i = 0; i < context_count; ++i) {
+ c = contexts[i];
+
+ if (! c->gc) {
+ c->gc = XCreateGC(display->getXDisplay(), hd, 0, 0);
+ c->used = false;
+ c->screen = scr;
+ }
+ if (! c->used && c->screen == scr) {
+ c->used = true;
+ return c;
+ }
+ }
+
+ fprintf(stderr, "BGCCache: context fault!\n");
+ abort();
+}
+
+
+void BGCCache::release(BGCCacheContext *ctx) {
+ ctx->used = false;
+}
+
+
+BGCCacheItem *BGCCache::find(const BColor &_color,
+ const XFontStruct * const _font,
+ int _function, int _subwindow) {
+ const unsigned long pixel = _color.pixel();
+ const unsigned int screen = _color.screen();
+ const int key = _color.red() ^ _color.green() ^ _color.blue();
+ int k = (key % cache_size) * cache_buckets;
+ int i = 0; // loop variable
+ BGCCacheItem *c = cache[ k ], *prev = 0;
+
+ // this will either loop 8 times then return/abort or it will stop matching
+ while (c->ctx &&
+ (c->ctx->pixel != pixel || c->ctx->function != _function ||
+ c->ctx->subwindow != _subwindow || c->ctx->screen != screen)) {
+ if (i < 7) {
+ prev = c;
+ c = cache[ ++k ];
+ ++i;
+ continue;
+ }
+ if (c->count == 0 && c->ctx->screen == screen) {
+ // use this cache item
+ c->ctx->set(_color, _font, _function, _subwindow);
+ c->ctx->used = true;
+ c->count = 1;
+ c->hits = 1;
+ return c;
+ }
+ // cache fault!
+ fprintf(stderr, "BGCCache: cache fault\n");
+ abort();
+ }
+
+ const unsigned long fontid = _font ? _font->fid : 0;
+ if (c->ctx) {
+ // reuse existing context
+ if (fontid && fontid != c->ctx->fontid)
+ c->ctx->set(_font);
+ c->count++;
+ c->hits++;
+ if (prev && c->hits > prev->hits) {
+ cache[ k ] = prev;
+ cache[ k - 1 ] = c;
+ }
+ } else {
+ c->ctx = nextContext(screen);
+ c->ctx->set(_color, _font, _function, _subwindow);
+ c->ctx->used = true;
+ c->count = 1;
+ c->hits = 1;
+ }
+
+ return c;
+}
+
+
+void BGCCache::release(BGCCacheItem *_item) {
+ _item->count--;
+}
+
+
+void BGCCache::purge(void) {
+ for (unsigned int i = 0; i < cache_total_size; ++i) {
+ BGCCacheItem *d = cache[ i ];
+
+ if (d->ctx && d->count == 0) {
+ release(d->ctx);
+ d->ctx = 0;
+ }
+ }
+}
--- /dev/null
+// -*- mode: C++; indent-tabs-mode: nil; c-basic-offset: 2; -*-
+// GCCache.hh for Blackbox - an X11 Window manager
+// Copyright (c) 2001 - 2002 Sean 'Shaleh' Perry <shaleh at debian.org>
+// Copyright (c) 1997 - 2000, 2002 Bradley T Hughes <bhughes at trolltech.com>
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#ifndef GCCACHE_HH
+#define GCCACHE_HH
+
+extern "C" {
+#include <X11/Xlib.h>
+}
+
+#include "BaseDisplay.hh"
+#include "Color.hh"
+
+class BGCCacheItem;
+
+class BGCCacheContext {
+public:
+ void set(const BColor &_color, const XFontStruct * const _font,
+ const int _function, const int _subwindow);
+ void set(const XFontStruct * const _font);
+
+private:
+ BGCCacheContext(const BaseDisplay * const _display)
+ : display(_display), gc(0), pixel(0ul), fontid(0ul),
+ function(0), subwindow(0), used(false), screen(~(0u)) {}
+
+ const BaseDisplay *display;
+ GC gc;
+ unsigned long pixel;
+ unsigned long fontid;
+ int function;
+ int subwindow;
+ bool used;
+ unsigned int screen;
+
+ BGCCacheContext(const BGCCacheContext &_nocopy);
+ BGCCacheContext &operator=(const BGCCacheContext &_nocopy);
+
+ friend class BGCCache;
+ friend class BGCCacheItem;
+};
+
+class BGCCacheItem {
+public:
+ inline const GC &gc(void) const { return ctx->gc; }
+
+private:
+ BGCCacheItem(void) : ctx(0), count(0), hits(0), fault(false) { }
+
+ BGCCacheContext *ctx;
+ unsigned int count;
+ unsigned int hits;
+ bool fault;
+
+ BGCCacheItem(const BGCCacheItem &_nocopy);
+ BGCCacheItem &operator=(const BGCCacheItem &_nocopy);
+
+ friend class BGCCache;
+};
+
+class BGCCache {
+public:
+ explicit BGCCache(const BaseDisplay * const _display);
+ ~BGCCache(void);
+
+ // cleans up the cache
+ void purge(void);
+
+ BGCCacheItem *find(const BColor &_color, const XFontStruct * const _font = 0,
+ int _function = GXcopy, int _subwindow = ClipByChildren);
+ void release(BGCCacheItem *_item);
+
+private:
+ BGCCacheContext *nextContext(unsigned int _screen);
+ void release(BGCCacheContext *ctx);
+
+ // this is closely modelled after the Qt GC cache, but with some of the
+ // complexity stripped out
+ const BaseDisplay *display;
+
+ const unsigned int context_count;
+ const unsigned int cache_size;
+ const unsigned int cache_buckets;
+ const unsigned int cache_total_size;
+ BGCCacheContext **contexts;
+ BGCCacheItem **cache;
+};
+
+class BPen {
+public:
+ inline BPen(const BColor &_color, const XFontStruct * const _font = 0,
+ int _function = GXcopy, int _subwindow = ClipByChildren)
+ : color(_color), font(_font), function(_function), subwindow(_subwindow),
+ cache(_color.display()->gcCache()), item(0) { }
+ inline ~BPen(void) { if (item) cache->release(item); }
+
+ inline const GC &gc(void) const {
+ if (! item) item = cache->find(color, font, function, subwindow);
+ return item->gc();
+ }
+
+private:
+ const BColor &color;
+ const XFontStruct *font;
+ int function;
+ int subwindow;
+
+ mutable BGCCache *cache;
+ mutable BGCCacheItem *item;
+};
+
+
+#endif // GCCACHE_HH
+++ /dev/null
-// Geometry.cc for Openbox
-// Copyright (c) 2002 - 2002 ben Jansens (ben@orodu.net)
-//
-// Permission is hereby granted, free of charge, to any person obtaining a
-// copy of this software and associated documentation files (the "Software"),
-// to deal in the Software without restriction, including without limitation
-// the rights to use, copy, modify, merge, publish, distribute, sublicense,
-// and/or sell copies of the Software, and to permit persons to whom the
-// Software is furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-// DEALINGS IN THE SOFTWARE.
-
-#include "Geometry.h"
-
-Point::Point() : m_x(0), m_y(0) {
-}
-
-Point::Point(const Point &point) : m_x(point.m_x), m_y(point.m_y) {
-}
-
-Point::Point(const int x, const int y) : m_x(x), m_y(y) {
-}
-
-void Point::setX(const int x) {
- m_x = x;
-}
-
-void Point::setY(const int y) {
- m_y = y;
-}
-
-Size::Size() : m_w(0), m_h(0) {
-}
-
-Size::Size(const Size &size) : m_w(size.m_w), m_h(size.m_h) {
-}
-
-Size::Size(const unsigned int w, const unsigned int h) : m_w(w), m_h(h) {
-}
-
-void Size::setW(const unsigned int w) {
- m_w = w;
-}
-
-void Size::setH(const unsigned int h) {
- m_h = h;
-}
-
-Rect::Rect() : m_origin(0, 0), m_size(0, 0) {
-}
-
-Rect::Rect(const Point &origin, const Size &size) : m_origin(origin),
- m_size(size) {
-}
-
-Rect::Rect(const int x, const int y, const unsigned int w, const unsigned int h)
- : m_origin(x, y), m_size(w, h) {
-}
-
-void Rect::setSize(const Size &size) {
- m_size = size;
-}
-
-void Rect::setSize(const unsigned int w, const unsigned int h) {
- m_size.setW(w);
- m_size.setH(h);
-}
-
-void Rect::setOrigin(const Point &origin) {
- m_origin = origin;
-}
-
-void Rect::setOrigin(const int x, const int y) {
- m_origin.setX(x);
- m_origin.setY(y);
-}
-
-void Rect::setX(const int x) {
- m_origin.setX(x);
-}
-
-void Rect::setY(const int y) {
- m_origin.setY(y);
-}
-
-void Rect::setW(unsigned int w) {
- m_size.setW(w);
-}
-
-void Rect::setH(unsigned int h) {
- m_size.setH(h);
-}
-
-bool Rect::Intersect(const Rect &r) const {
- return
- (x() < (r.x()+(signed)r.w()) ) &&
- ( (x()+(signed)w()) > r.x()) &&
- (y() < (r.y()+(signed)r.h()) ) &&
- ( (y()+(signed)h()) > r.y());
-}
-
-Rect Rect::Inflate(const unsigned int i) const {
- return Rect(x(), y(), w()+i, h()+i);
-}
-
-Rect Rect::Inflate(const unsigned int iw, const unsigned int ih) const {
- return Rect(x(), y(), w()+iw, h()+ih);
-}
-
-Rect Rect::Inflate(const Size &i) const {
- return Rect(x(), y(), w()+i.w(), h()+i.h());
-}
-
-Rect Rect::Deflate(const unsigned int d) const {
- return Rect(x(), y(), w()-d, h()-d);
-}
-
-Rect Rect::Deflate(const unsigned int dw, const unsigned int dh) const {
- return Rect(x(), y(), w()-dw, h()-dh);
-}
-
-Rect Rect::Deflate(const Size &d) const {
- return Rect(x(), y(), w()-d.w(), h()-d.h());
-}
-
-Rect Rect::Translate(const int t) const {
- return Rect(x()+t, y()+t, w(), h());
-}
-
-Rect Rect::Translate(const int tx, const int ty) const {
- return Rect(x()+tx, y()+ty, w(), h());
-}
-
-Rect Rect::Translate(const Point &t) const {
- return Rect(x()+t.x(), y()+t.y(), w(), h());
-}
+++ /dev/null
-// Geometry.h for Openbox
-// Copyright (c) 2002 - 2002 ben Jansens (ben@orodu.net)
-//
-// Permission is hereby granted, free of charge, to any person obtaining a
-// copy of this software and associated documentation files (the "Software"),
-// to deal in the Software without restriction, including without limitation
-// the rights to use, copy, modify, merge, publish, distribute, sublicense,
-// and/or sell copies of the Software, and to permit persons to whom the
-// Software is furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-// DEALINGS IN THE SOFTWARE.
-
-#ifndef __geometry_h
-#define __geometry_h
-
-class Point{
- int m_x, m_y;
-public:
- Point();
- Point(const Point &point);
- Point(const int x, const int y);
-
- void setX(const int x);
- inline int x() const {
- return m_x;
- }
-
- void setY(const int y);
- inline int y() const {
- return m_y;
- }
-};
-
-class Size{
- unsigned int m_w, m_h;
-public:
- Size();
- Size(const Size &size);
- Size(const unsigned int w, const unsigned int h);
-
- void setW(const unsigned int w);
- inline unsigned int w() const {
- return m_w;
- }
-
- void setH(const unsigned int h);
- inline unsigned int h() const {
- return m_h;
- }
-};
-
-class Rect{
- Point m_origin;
- Size m_size;
-public:
- Rect();
- Rect(const Point &origin, const Size &size);
- Rect(const int x, const int y, const unsigned int w, const unsigned int h);
-
- void setSize(const Size &size);
- void setSize(const unsigned int w, const unsigned int h);
- inline const Size &size() const {
- return const_cast<const Size &>(m_size);
- }
-
- void setOrigin(const Point &origin);
- void setOrigin(const int x, const int y);
- inline const Point &origin() const {
- return const_cast<const Point &>(m_origin);
- }
-
- void setX(const int x);
- inline int x() const {
- return m_origin.x();
- }
-
- void setY(const int y);
- inline int y() const {
- return m_origin.y();
- }
-
- void setW(const unsigned int w);
- inline unsigned int w() const {
- return m_size.w();
- }
-
- void setH(const unsigned int h);
- inline unsigned int h() const {
- return m_size.h();
- }
-
- bool Intersect(const Rect &r) const;
- // returns a rect that is this rect increased in size by the passed in amount
- Rect Inflate(const unsigned int i) const;
- Rect Inflate(const unsigned int iw, const unsigned int ih) const;
- Rect Inflate(const Size &i) const;
- // returns a rect that is this rect decreased in size by the passed in amount
- Rect Deflate(const unsigned int d) const;
- Rect Deflate(const unsigned int dw, const unsigned int dh) const;
- Rect Deflate(const Size &d) const;
- // returns a rect that is moved the amount specified
- Rect Translate(const int t) const;
- Rect Translate(const int tx, const int ty) const;
- Rect Translate(const Point &t) const;
-};
-
-#endif // __geometry_h
-// Iconmenu.cc for Openbox
-// Copyright (c) 2001 Sean 'Shaleh' Perry <shaleh@debian.org>
+// -*- mode: C++; indent-tabs-mode: nil; -*-
+// Icon.cc for Blackbox - an X11 Window manager
+// Copyright (c) 2001 - 2002 Sean 'Shaleh' Perry <shaleh@debian.org>
// Copyright (c) 1997 - 2000 Brad Hughes (bhughes@tcac.net)
//
// Permission is hereby granted, free of charge, to any person obtaining a
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
-// stupid macros needed to access some functions in version 2 of the GNU C
-// library
-#ifndef _GNU_SOURCE
-#define _GNU_SOURCE
-#endif // _GNU_SOURCE
-
#ifdef HAVE_CONFIG_H
# include "../config.h"
#endif // HAVE_CONFIG_H
-#include "i18n.h"
-#include "Iconmenu.h"
-#include "Screen.h"
-#include "Window.h"
+#include "i18n.hh"
+#include "Iconmenu.hh"
+#include "Screen.hh"
+#include "Window.hh"
-Iconmenu::Iconmenu(BScreen &scrn) : Basemenu(scrn), screen(scrn) {
+Iconmenu::Iconmenu(BScreen *scrn) : Basemenu(scrn) {
setInternalMenu();
setLabel(i18n(IconSet, IconIcons, "Icons"));
}
-void Iconmenu::itemSelected(int button, int index) {
+void Iconmenu::itemSelected(int button, unsigned int index) {
if (button != 1)
return;
- if (index >= 0 && index < screen.getIconCount()) {
- OpenboxWindow *win = screen.getIcon(index);
+ if (index < getScreen()->getIconCount()) {
+ BlackboxWindow *win = getScreen()->getIcon(index);
if (win) {
win->deiconify();
}
}
- if (! (screen.getWorkspacemenu()->isTorn() || isTorn()))
+ if (! (getScreen()->getWorkspacemenu()->isTorn() || isTorn()))
hide();
}
+++ /dev/null
-// Iconmenu.h for Openbox
-// Copyright (c) 2001 Sean 'Shaleh' Perry <shaleh@debian.org>
-// Copyright (c) 1997 - 2000 Brad Hughes (bhughes@tcac.net)
-//
-// Permission is hereby granted, free of charge, to any person obtaining a
-// copy of this software and associated documentation files (the "Software"),
-// to deal in the Software without restriction, including without limitation
-// the rights to use, copy, modify, merge, publish, distribute, sublicense,
-// and/or sell copies of the Software, and to permit persons to whom the
-// Software is furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-// DEALINGS IN THE SOFTWARE.
-
-#ifndef __Icon_hh
-#define __Icon_hh
-
-#include "Basemenu.h"
-
-// forward declaration
-class Iconmenu;
-class BScreen;
-
-class Iconmenu : public Basemenu {
-private:
- BScreen &screen;
-
-protected:
- virtual void itemSelected(int, int);
-
-public:
- Iconmenu(BScreen &);
-};
-
-
-#endif // __Icon_hh
-// Image.cc for Openbox
-// Copyright (c) 2001 Sean 'Shaleh' Perry <shaleh@debian.org>
+// -*- mode: C++; indent-tabs-mode: nil; -*-
+// Image.cc for Blackbox - an X11 Window manager
+// Copyright (c) 2001 - 2002 Sean 'Shaleh' Perry <shaleh@debian.org>
// Copyright (c) 1997 - 2000 Brad Hughes (bhughes@tcac.net)
//
// Permission is hereby granted, free of charge, to any person obtaining a
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
-// stupid macros needed to access some functions in version 2 of the GNU C
-// library
-#ifndef _GNU_SOURCE
-#define _GNU_SOURCE
-#endif // _GNU_SOURCE
-
#ifdef HAVE_CONFIG_H
# include "../config.h"
#endif // HAVE_CONFIG_H
-#include "i18n.h"
-#include "BaseDisplay.h"
-#include "Image.h"
-
-#ifdef HAVE_SYS_TYPES_H
-# include <sys/types.h>
-#endif // HAVE_SYS_TYPES_H
-
-#ifndef u_int32_t
-# ifdef uint_32_t
-typedef uint32_t u_int32_t;
-# else
-# ifdef __uint32_t
-typedef __uint32_t u_int32_t;
-# else
-typedef unsigned int u_int32_t;
-# endif
-# endif
-#endif
-
-#ifdef HAVE_STDLIB_H
-# include <stdlib.h>
-#endif // HAVE_STDLIB_H
-
-#ifdef HAVE_STRING_H
-# include <string.h>
-#endif // HAVE_STRING_H
-
#ifdef HAVE_STDIO_H
# include <stdio.h>
#endif // HAVE_STDIO_H
-#ifdef HAVE_CTYPE_H
-# include <ctype.h>
-#endif // HAVE_CTYPE_H
-
#include <algorithm>
-using std::min;
using std::max;
+using std::min;
-static unsigned long bsqrt(unsigned long x) {
- if (x <= 0) return 0;
- if (x == 1) return 1;
+#include "blackbox.hh"
+#include "i18n.hh"
+#include "BaseDisplay.hh"
+#include "GCCache.hh"
+#include "Image.hh"
+#include "Texture.hh"
- unsigned long r = x >> 1;
- unsigned long q;
- while (1) {
- q = x / r;
- if (q >= r) return r;
- r = (r + q) >> 1;
- }
-}
+BImage::BImage(BImageControl *c, unsigned int w, unsigned int h) {
+ control = c;
-
-BImage::BImage(BImageControl &c, unsigned int w, unsigned int h) : control(c) {
width = ((signed) w > 0) ? w : 1;
height = ((signed) h > 0) ? h : 1;
xtable = ytable = (unsigned int *) 0;
- cpc = control.getColorsPerChannel();
+ cpc = control->getColorsPerChannel();
cpccpc = cpc * cpc;
- control.getColorTables(&red_table, &green_table, &blue_table,
- &red_offset, &green_offset, &blue_offset,
- &red_bits, &green_bits, &blue_bits);
+ control->getColorTables(&red_table, &green_table, &blue_table,
+ &red_offset, &green_offset, &blue_offset,
+ &red_bits, &green_bits, &blue_bits);
- if (control.getVisual()->c_class != TrueColor)
- control.getXColorTable(&colors, &ncolors);
+ if (control->getVisual()->c_class != TrueColor)
+ control->getXColorTable(&colors, &ncolors);
}
}
-Pixmap BImage::render(BTexture *texture) {
- if (texture->getTexture() & BImage_ParentRelative)
+Pixmap BImage::render(const BTexture &texture) {
+ if ((texture.texture() & BTexture::Parent_Relative))
return ParentRelative;
- else if (texture->getTexture() & BImage_Solid)
+ else if ((texture.texture() & BTexture::Solid))
return render_solid(texture);
- else if (texture->getTexture() & BImage_Gradient)
+ else if ((texture.texture() & BTexture::Gradient))
return render_gradient(texture);
-
return None;
}
-Pixmap BImage::render_solid(BTexture *texture) {
- Pixmap pixmap = XCreatePixmap(control.getBaseDisplay().getXDisplay(),
- control.getDrawable(), width,
- height, control.getDepth());
+Pixmap BImage::render_solid(const BTexture &texture) {
+ Pixmap pixmap = XCreatePixmap(control->getBaseDisplay()->getXDisplay(),
+ control->getDrawable(), width,
+ height, control->getDepth());
if (pixmap == None) {
fprintf(stderr, i18n(ImageSet, ImageErrorCreatingSolidPixmap,
"BImage::render_solid: error creating pixmap\n"));
return None;
}
- XGCValues gcv;
- GC gc, hgc, lgc;
-
- gcv.foreground = texture->getColor()->getPixel();
- gcv.fill_style = FillSolid;
- gc = XCreateGC(control.getBaseDisplay().getXDisplay(), pixmap,
- GCForeground | GCFillStyle, &gcv);
-
- gcv.foreground = texture->getHiColor()->getPixel();
- hgc = XCreateGC(control.getBaseDisplay().getXDisplay(), pixmap,
- GCForeground, &gcv);
-
- gcv.foreground = texture->getLoColor()->getPixel();
- lgc = XCreateGC(control.getBaseDisplay().getXDisplay(), pixmap,
- GCForeground, &gcv);
+ Display *display = control->getBaseDisplay()->getXDisplay();
- XFillRectangle(control.getBaseDisplay().getXDisplay(), pixmap, gc, 0, 0,
- width, height);
+ BPen pen(texture.color());
+ BPen penlight(texture.lightColor());
+ BPen penshadow(texture.shadowColor());
-#ifdef INTERLACE
- if (texture->getTexture() & BImage_Interlaced) {
- gcv.foreground = texture->getColorTo()->getPixel();
- GC igc = XCreateGC(control.getBaseDisplay().getXDisplay(), pixmap,
- GCForeground, &gcv);
+ XFillRectangle(display, pixmap, pen.gc(), 0, 0, width, height);
+ if (texture.texture() & BTexture::Interlaced) {
+ BPen peninterlace(texture.colorTo());
register unsigned int i = 0;
for (; i < height; i += 2)
- XDrawLine(control.getBaseDisplay().getXDisplay(), pixmap, igc,
- 0, i, width, i);
-
- XFreeGC(control.getBaseDisplay().getXDisplay(), igc);
+ XDrawLine(display, pixmap, peninterlace.gc(), 0, i, width, i);
}
-#endif // INTERLACE
-
- if (texture->getTexture() & BImage_Bevel1) {
- if (texture->getTexture() & BImage_Raised) {
- XDrawLine(control.getBaseDisplay().getXDisplay(), pixmap, lgc,
+ if (texture.texture() & BTexture::Bevel1) {
+ if (texture.texture() & BTexture::Raised) {
+ XDrawLine(display, pixmap, penshadow.gc(),
0, height - 1, width - 1, height - 1);
- XDrawLine(control.getBaseDisplay().getXDisplay(), pixmap, lgc,
+ XDrawLine(display, pixmap, penshadow.gc(),
width - 1, height - 1, width - 1, 0);
- XDrawLine(control.getBaseDisplay().getXDisplay(), pixmap, hgc,
+ XDrawLine(display, pixmap, penlight.gc(),
0, 0, width - 1, 0);
- XDrawLine(control.getBaseDisplay().getXDisplay(), pixmap, hgc,
+ XDrawLine(display, pixmap, penlight.gc(),
0, height - 1, 0, 0);
- } else if (texture->getTexture() & BImage_Sunken) {
- XDrawLine(control.getBaseDisplay().getXDisplay(), pixmap, hgc,
+ } else if (texture.texture() & BTexture::Sunken) {
+ XDrawLine(display, pixmap, penlight.gc(),
0, height - 1, width - 1, height - 1);
- XDrawLine(control.getBaseDisplay().getXDisplay(), pixmap, hgc,
+ XDrawLine(display, pixmap, penlight.gc(),
width - 1, height - 1, width - 1, 0);
- XDrawLine(control.getBaseDisplay().getXDisplay(), pixmap, lgc,
+ XDrawLine(display, pixmap, penshadow.gc(),
0, 0, width - 1, 0);
- XDrawLine(control.getBaseDisplay().getXDisplay(), pixmap, lgc,
+ XDrawLine(display, pixmap, penshadow.gc(),
0, height - 1, 0, 0);
}
- } else if (texture->getTexture() & BImage_Bevel2) {
- if (texture->getTexture() & BImage_Raised) {
- XDrawLine(control.getBaseDisplay().getXDisplay(), pixmap, lgc,
+ } else if (texture.texture() & BTexture::Bevel2) {
+ if (texture.texture() & BTexture::Raised) {
+ XDrawLine(display, pixmap, penshadow.gc(),
1, height - 3, width - 3, height - 3);
- XDrawLine(control.getBaseDisplay().getXDisplay(), pixmap, lgc,
+ XDrawLine(display, pixmap, penshadow.gc(),
width - 3, height - 3, width - 3, 1);
- XDrawLine(control.getBaseDisplay().getXDisplay(), pixmap, hgc,
+ XDrawLine(display, pixmap, penlight.gc(),
1, 1, width - 3, 1);
- XDrawLine(control.getBaseDisplay().getXDisplay(), pixmap, hgc,
+ XDrawLine(display, pixmap, penlight.gc(),
1, height - 3, 1, 1);
- } else if (texture->getTexture() & BImage_Sunken) {
- XDrawLine(control.getBaseDisplay().getXDisplay(), pixmap, hgc,
+ } else if (texture.texture() & BTexture::Sunken) {
+ XDrawLine(display, pixmap, penlight.gc(),
1, height - 3, width - 3, height - 3);
- XDrawLine(control.getBaseDisplay().getXDisplay(), pixmap, hgc,
+ XDrawLine(display, pixmap, penlight.gc(),
width - 3, height - 3, width - 3, 1);
- XDrawLine(control.getBaseDisplay().getXDisplay(), pixmap, lgc,
+ XDrawLine(display, pixmap, penshadow.gc(),
1, 1, width - 3, 1);
- XDrawLine(control.getBaseDisplay().getXDisplay(), pixmap, lgc,
+ XDrawLine(display, pixmap, penshadow.gc(),
1, height - 3, 1, 1);
}
}
- XFreeGC(control.getBaseDisplay().getXDisplay(), gc);
- XFreeGC(control.getBaseDisplay().getXDisplay(), hgc);
- XFreeGC(control.getBaseDisplay().getXDisplay(), lgc);
-
return pixmap;
}
-Pixmap BImage::render_gradient(BTexture *texture) {
- int inverted = 0;
+Pixmap BImage::render_gradient(const BTexture &texture) {
+ int inverted = 0;
-#ifdef INTERLACE
- interlaced = texture->getTexture() & BImage_Interlaced;
-#endif // INTERLACE
+ interlaced = texture.texture() & BTexture::Interlaced;
- if (texture->getTexture() & BImage_Sunken) {
- from = texture->getColorTo();
- to = texture->getColor();
+ if (texture.texture() & BTexture::Sunken) {
+ from = texture.colorTo();
+ to = texture.color();
- if (! (texture->getTexture() & BImage_Invert)) inverted = 1;
+ if (! (texture.texture() & BTexture::Invert)) inverted = 1;
} else {
- from = texture->getColor();
- to = texture->getColorTo();
+ from = texture.color();
+ to = texture.colorTo();
- if (texture->getTexture() & BImage_Invert) inverted = 1;
+ if (texture.texture() & BTexture::Invert) inverted = 1;
}
- control.getGradientBuffers(width, height, &xtable, &ytable);
+ control->getGradientBuffers(width, height, &xtable, &ytable);
- if (texture->getTexture() & BImage_Diagonal) dgradient();
- else if (texture->getTexture() & BImage_Elliptic) egradient();
- else if (texture->getTexture() & BImage_Horizontal) hgradient();
- else if (texture->getTexture() & BImage_Pyramid) pgradient();
- else if (texture->getTexture() & BImage_Rectangle) rgradient();
- else if (texture->getTexture() & BImage_Vertical) vgradient();
- else if (texture->getTexture() & BImage_CrossDiagonal) cdgradient();
- else if (texture->getTexture() & BImage_PipeCross) pcgradient();
+ if (texture.texture() & BTexture::Diagonal) dgradient();
+ else if (texture.texture() & BTexture::Elliptic) egradient();
+ else if (texture.texture() & BTexture::Horizontal) hgradient();
+ else if (texture.texture() & BTexture::Pyramid) pgradient();
+ else if (texture.texture() & BTexture::Rectangle) rgradient();
+ else if (texture.texture() & BTexture::Vertical) vgradient();
+ else if (texture.texture() & BTexture::CrossDiagonal) cdgradient();
+ else if (texture.texture() & BTexture::PipeCross) pcgradient();
- if (texture->getTexture() & BImage_Bevel1) bevel1();
- else if (texture->getTexture() & BImage_Bevel2) bevel2();
+ if (texture.texture() & BTexture::Bevel1) bevel1();
+ else if (texture.texture() & BTexture::Bevel2) bevel2();
if (inverted) invert();
}
+static const unsigned char dither4[4][4] = {
+ {0, 4, 1, 5},
+ {6, 2, 7, 3},
+ {1, 5, 0, 4},
+ {7, 3, 6, 2}
+};
+
+
+/*
+ * Helper function for TrueColorDither and renderXImage
+ *
+ * This handles the proper setting of the image data based on the image depth
+ * and the machine's byte ordering
+ */
+static inline
+void assignPixelData(unsigned int bit_depth, unsigned char **data,
+ unsigned long pixel) {
+ unsigned char *pixel_data = *data;
+ switch (bit_depth) {
+ case 8: // 8bpp
+ *pixel_data++ = pixel;
+ break;
+
+ case 16: // 16bpp LSB
+ *pixel_data++ = pixel;
+ *pixel_data++ = pixel >> 8;
+ break;
+
+ case 17: // 16bpp MSB
+ *pixel_data++ = pixel >> 8;
+ *pixel_data++ = pixel;
+ break;
+
+ case 24: // 24bpp LSB
+ *pixel_data++ = pixel;
+ *pixel_data++ = pixel >> 8;
+ *pixel_data++ = pixel >> 16;
+ break;
+
+ case 25: // 24bpp MSB
+ *pixel_data++ = pixel >> 16;
+ *pixel_data++ = pixel >> 8;
+ *pixel_data++ = pixel;
+ break;
+
+ case 32: // 32bpp LSB
+ *pixel_data++ = pixel;
+ *pixel_data++ = pixel >> 8;
+ *pixel_data++ = pixel >> 16;
+ *pixel_data++ = pixel >> 24;
+ break;
+
+ case 33: // 32bpp MSB
+ *pixel_data++ = pixel >> 24;
+ *pixel_data++ = pixel >> 16;
+ *pixel_data++ = pixel >> 8;
+ *pixel_data++ = pixel;
+ break;
+ }
+ *data = pixel_data; // assign back so we don't lose our place
+}
+
+
+// algorithm: ordered dithering... many many thanks to rasterman
+// (raster@rasterman.com) for telling me about this... portions of this
+// code is based off of his code in Imlib
+void BImage::TrueColorDither(unsigned int bit_depth, int bytes_per_line,
+ unsigned char *pixel_data) {
+ unsigned int x, y, dithx, dithy, r, g, b, er, eg, eb, offset;
+ unsigned char *ppixel_data = pixel_data;
+ unsigned long pixel;
+
+ for (y = 0, offset = 0; y < height; y++) {
+ dithy = y & 0x3;
+
+ for (x = 0; x < width; x++, offset++) {
+ dithx = x & 0x3;
+ r = red[offset];
+ g = green[offset];
+ b = blue[offset];
+
+ er = r & (red_bits - 1);
+ eg = g & (green_bits - 1);
+ eb = b & (blue_bits - 1);
+
+ r = red_table[r];
+ g = green_table[g];
+ b = blue_table[b];
+
+ if ((dither4[dithy][dithx] < er) && (r < red_table[255])) r++;
+ if ((dither4[dithy][dithx] < eg) && (g < green_table[255])) g++;
+ if ((dither4[dithy][dithx] < eb) && (b < blue_table[255])) b++;
+
+ pixel = (r << red_offset) | (g << green_offset) | (b << blue_offset);
+ assignPixelData(bit_depth, &pixel_data, pixel);
+ }
+
+ pixel_data = (ppixel_data += bytes_per_line);
+ }
+}
+
+#ifdef ORDEREDPSEUDO
+const static unsigned char dither8[8][8] = {
+ { 0, 32, 8, 40, 2, 34, 10, 42},
+ { 48, 16, 56, 24, 50, 18, 58, 26},
+ { 12, 44, 4, 36, 14, 46, 6, 38},
+ { 60, 28, 52, 20, 62, 30, 54, 22},
+ { 3, 35, 11, 43, 1, 33, 9, 41},
+ { 51, 19, 59, 27, 49, 17, 57, 25},
+ { 15, 47, 7, 39, 13, 45, 5, 37},
+ { 63, 31, 55, 23, 61, 29, 53, 21}
+};
+
+void BImage::OrderedPseudoColorDither(int bytes_per_line,
+ unsigned char *pixel_data) {
+ unsigned int x, y, dithx, dithy, r, g, b, er, eg, eb, offset;
+ unsigned long pixel;
+ unsigned char *ppixel_data = pixel_data;
+
+ for (y = 0, offset = 0; y < height; y++) {
+ dithy = y & 7;
+
+ for (x = 0; x < width; x++, offset++) {
+ dithx = x & 7;
+
+ r = red[offset];
+ g = green[offset];
+ b = blue[offset];
+
+ er = r & (red_bits - 1);
+ eg = g & (green_bits - 1);
+ eb = b & (blue_bits - 1);
+
+ r = red_table[r];
+ g = green_table[g];
+ b = blue_table[b];
+
+ if ((dither8[dithy][dithx] < er) && (r < red_table[255])) r++;
+ if ((dither8[dithy][dithx] < eg) && (g < green_table[255])) g++;
+ if ((dither8[dithy][dithx] < eb) && (b < blue_table[255])) b++;
+
+ pixel = (r * cpccpc) + (g * cpc) + b;
+ *(pixel_data++) = colors[pixel].pixel;
+ }
+
+ pixel_data = (ppixel_data += bytes_per_line);
+ }
+}
+#endif
+
+void BImage::PseudoColorDither(int bytes_per_line, unsigned char *pixel_data) {
+ short *terr,
+ *rerr = new short[width + 2],
+ *gerr = new short[width + 2],
+ *berr = new short[width + 2],
+ *nrerr = new short[width + 2],
+ *ngerr = new short[width + 2],
+ *nberr = new short[width + 2];
+
+ int rr, gg, bb, rer, ger, ber;
+ int dd = 255 / control->getColorsPerChannel();
+ unsigned int x, y, r, g, b, offset;
+ unsigned long pixel;
+ unsigned char *ppixel_data = pixel_data;
+
+ for (x = 0; x < width; x++) {
+ *(rerr + x) = *(red + x);
+ *(gerr + x) = *(green + x);
+ *(berr + x) = *(blue + x);
+ }
+
+ *(rerr + x) = *(gerr + x) = *(berr + x) = 0;
+
+ for (y = 0, offset = 0; y < height; y++) {
+ if (y < (height - 1)) {
+ int i = offset + width;
+ for (x = 0; x < width; x++, i++) {
+ *(nrerr + x) = *(red + i);
+ *(ngerr + x) = *(green + i);
+ *(nberr + x) = *(blue + i);
+ }
+
+ *(nrerr + x) = *(red + (--i));
+ *(ngerr + x) = *(green + i);
+ *(nberr + x) = *(blue + i);
+ }
+
+ for (x = 0; x < width; x++) {
+ rr = rerr[x];
+ gg = gerr[x];
+ bb = berr[x];
+
+ if (rr > 255) rr = 255; else if (rr < 0) rr = 0;
+ if (gg > 255) gg = 255; else if (gg < 0) gg = 0;
+ if (bb > 255) bb = 255; else if (bb < 0) bb = 0;
+
+ r = red_table[rr];
+ g = green_table[gg];
+ b = blue_table[bb];
+
+ rer = rerr[x] - r*dd;
+ ger = gerr[x] - g*dd;
+ ber = berr[x] - b*dd;
+
+ pixel = (r * cpccpc) + (g * cpc) + b;
+ *pixel_data++ = colors[pixel].pixel;
+
+ r = rer >> 1;
+ g = ger >> 1;
+ b = ber >> 1;
+ rerr[x+1] += r;
+ gerr[x+1] += g;
+ berr[x+1] += b;
+ nrerr[x] += r;
+ ngerr[x] += g;
+ nberr[x] += b;
+ }
+
+ offset += width;
+
+ pixel_data = (ppixel_data += bytes_per_line);
+
+ terr = rerr;
+ rerr = nrerr;
+ nrerr = terr;
+
+ terr = gerr;
+ gerr = ngerr;
+ ngerr = terr;
+
+ terr = berr;
+ berr = nberr;
+ nberr = terr;
+ }
+
+ delete [] rerr;
+ delete [] gerr;
+ delete [] berr;
+ delete [] nrerr;
+ delete [] ngerr;
+ delete [] nberr;
+}
+
XImage *BImage::renderXImage(void) {
XImage *image =
- XCreateImage(control.getBaseDisplay().getXDisplay(),
- control.getVisual(), control.getDepth(), ZPixmap, 0, 0,
+ XCreateImage(control->getBaseDisplay()->getXDisplay(),
+ control->getVisual(), control->getDepth(), ZPixmap, 0, 0,
width, height, 32, 0);
if (! image) {
image->data = (char *) 0;
unsigned char *d = new unsigned char[image->bytes_per_line * (height + 1)];
- register unsigned int x, y, dithx, dithy, r, g, b, o, er, eg, eb, offset;
- unsigned char *pixel_data = d, *ppixel_data = d;
- unsigned long pixel;
+ unsigned int o = image->bits_per_pixel +
+ ((image->byte_order == MSBFirst) ? 1 : 0);
+
+ if (control->doDither() && width > 1 && height > 1) {
+ switch (control->getVisual()->c_class) {
+ case TrueColor:
+ TrueColorDither(o, image->bytes_per_line, d);
+ break;
- o = image->bits_per_pixel + ((image->byte_order == MSBFirst) ? 1 : 0);
-
- if (control.doDither() && width > 1 && height > 1) {
- unsigned char dither4[4][4] = { {0, 4, 1, 5},
- {6, 2, 7, 3},
- {1, 5, 0, 4},
- {7, 3, 6, 2} };
-
-#ifdef ORDEREDPSEUDO
- unsigned char dither8[8][8] = { { 0, 32, 8, 40, 2, 34, 10, 42 },
- { 48, 16, 56, 24, 50, 18, 58, 26 },
- { 12, 44, 4, 36, 14, 46, 6, 38 },
- { 60, 28, 52, 20, 62, 30, 54, 22 },
- { 3, 35, 11, 43, 1, 33, 9, 41 },
- { 51, 19, 59, 27, 49, 17, 57, 25 },
- { 15, 47, 7, 39, 13, 45, 5, 37 },
- { 63, 31, 55, 23, 61, 29, 53, 21 } };
-#endif // ORDEREDPSEUDO
-
- switch (control.getVisual()->c_class) {
- case TrueColor:
- // algorithm: ordered dithering... many many thanks to rasterman
- // (raster@rasterman.com) for telling me about this... portions of this
- // code is based off of his code in Imlib
- for (y = 0, offset = 0; y < height; y++) {
- dithy = y & 0x3;
-
- for (x = 0; x < width; x++, offset++) {
- dithx = x & 0x3;
- r = red[offset];
- g = green[offset];
- b = blue[offset];
-
- er = r & (red_bits - 1);
- eg = g & (green_bits - 1);
- eb = b & (blue_bits - 1);
-
- r = red_table[r];
- g = green_table[g];
- b = blue_table[b];
-
- if ((dither4[dithy][dithx] < er) && (r < red_table[255])) r++;
- if ((dither4[dithy][dithx] < eg) && (g < green_table[255])) g++;
- if ((dither4[dithy][dithx] < eb) && (b < blue_table[255])) b++;
-
- pixel = (r << red_offset) | (g << green_offset) | (b << blue_offset);
-
- switch (o) {
- case 8: // 8bpp
- *pixel_data++ = pixel;
- break;
-
- case 16: // 16bpp LSB
- *pixel_data++ = pixel;
- *pixel_data++ = pixel >> 8;
- break;
-
- case 17: // 16bpp MSB
- *pixel_data++ = pixel >> 8;
- *pixel_data++ = pixel;
- break;
-
- case 24: // 24bpp LSB
- *pixel_data++ = pixel;
- *pixel_data++ = pixel >> 8;
- *pixel_data++ = pixel >> 16;
- break;
-
- case 25: // 24bpp MSB
- *pixel_data++ = pixel >> 16;
- *pixel_data++ = pixel >> 8;
- *pixel_data++ = pixel;
- break;
-
- case 32: // 32bpp LSB
- *pixel_data++ = pixel;
- *pixel_data++ = pixel >> 8;
- *pixel_data++ = pixel >> 16;
- *pixel_data++ = pixel >> 24;
- break;
-
- case 33: // 32bpp MSB
- *pixel_data++ = pixel >> 24;
- *pixel_data++ = pixel >> 16;
- *pixel_data++ = pixel >> 8;
- *pixel_data++ = pixel;
- break;
- }
- }
-
- pixel_data = (ppixel_data += image->bytes_per_line);
- }
-
- break;
-
- case StaticColor:
- case PseudoColor: {
-#ifndef ORDEREDPSEUDO
- short *terr,
- *rerr = new short[width + 2],
- *gerr = new short[width + 2],
- *berr = new short[width + 2],
- *nrerr = new short[width + 2],
- *ngerr = new short[width + 2],
- *nberr = new short[width + 2];
- int rr, gg, bb, rer, ger, ber;
- int dd = 255 / control.getColorsPerChannel();
-
- for (x = 0; x < width; x++) {
- *(rerr + x) = *(red + x);
- *(gerr + x) = *(green + x);
- *(berr + x) = *(blue + x);
- }
-
- *(rerr + x) = *(gerr + x) = *(berr + x) = 0;
-#endif // ORDEREDPSEUDO
-
- for (y = 0, offset = 0; y < height; y++) {
-#ifdef ORDEREDPSEUDO
- dithy = y & 7;
-
- for (x = 0; x < width; x++, offset++) {
- dithx = x & 7;
-
- r = red[offset];
- g = green[offset];
- b = blue[offset];
-
- er = r & (red_bits - 1);
- eg = g & (green_bits - 1);
- eb = b & (blue_bits - 1);
-
- r = red_table[r];
- g = green_table[g];
- b = blue_table[b];
-
- if ((dither8[dithy][dithx] < er) && (r < red_table[255])) r++;
- if ((dither8[dithy][dithx] < eg) && (g < green_table[255])) g++;
- if ((dither8[dithy][dithx] < eb) && (b < blue_table[255])) b++;
-
- pixel = (r * cpccpc) + (g * cpc) + b;
- *(pixel_data++) = colors[pixel].pixel;
- }
-
- pixel_data = (ppixel_data += image->bytes_per_line);
- }
-#else // !ORDEREDPSEUDO
- if (y < (height - 1)) {
- int i = offset + width;
- for (x = 0; x < width; x++, i++) {
- *(nrerr + x) = *(red + i);
- *(ngerr + x) = *(green + i);
- *(nberr + x) = *(blue + i);
- }
-
- *(nrerr + x) = *(red + (--i));
- *(ngerr + x) = *(green + i);
- *(nberr + x) = *(blue + i);
- }
-
- for (x = 0; x < width; x++) {
- rr = rerr[x];
- gg = gerr[x];
- bb = berr[x];
-
- if (rr > 255) rr = 255; else if (rr < 0) rr = 0;
- if (gg > 255) gg = 255; else if (gg < 0) gg = 0;
- if (bb > 255) bb = 255; else if (bb < 0) bb = 0;
-
- r = red_table[rr];
- g = green_table[gg];
- b = blue_table[bb];
-
- rer = rerr[x] - r*dd;
- ger = gerr[x] - g*dd;
- ber = berr[x] - b*dd;
-
- pixel = (r * cpccpc) + (g * cpc) + b;
- *pixel_data++ = colors[pixel].pixel;
-
- r = rer >> 1;
- g = ger >> 1;
- b = ber >> 1;
- rerr[x+1] += r;
- gerr[x+1] += g;
- berr[x+1] += b;
- nrerr[x] += r;
- ngerr[x] += g;
- nberr[x] += b;
- }
-
- offset += width;
-
- pixel_data = (ppixel_data += image->bytes_per_line);
-
- terr = rerr;
- rerr = nrerr;
- nrerr = terr;
-
- terr = gerr;
- gerr = ngerr;
- ngerr = terr;
-
- terr = berr;
- berr = nberr;
- nberr = terr;
+ case StaticColor:
+ case PseudoColor: {
+#ifdef ORDEREDPSEUDO
+ OrderedPseudoColorDither(image->bytes_per_line, d);
+#else
+ PseudoColorDither(image->bytes_per_line, d);
+#endif
+ break;
+ }
+
+ default:
+ fprintf(stderr, i18n(ImageSet, ImageUnsupVisual,
+ "BImage::renderXImage: unsupported visual\n"));
+ delete [] d;
+ XDestroyImage(image);
+ return (XImage *) 0;
+ }
+ } else {
+ register unsigned int x, y, r, g, b, offset;
+
+ unsigned char *pixel_data = d, *ppixel_data = d;
+ unsigned long pixel;
+
+ switch (control->getVisual()->c_class) {
+ case StaticColor:
+ case PseudoColor:
+ for (y = 0, offset = 0; y < height; y++) {
+ for (x = 0; x < width; x++, offset++) {
+ r = red_table[red[offset]];
+ g = green_table[green[offset]];
+ b = blue_table[blue[offset]];
+
+ pixel = (r * cpccpc) + (g * cpc) + b;
+ *pixel_data++ = colors[pixel].pixel;
}
- delete [] rerr;
- delete [] gerr;
- delete [] berr;
- delete [] nrerr;
- delete [] ngerr;
- delete [] nberr;
-#endif // ORDEREDPSUEDO
-
- break; }
-
- default:
- fprintf(stderr, i18n(ImageSet, ImageUnsupVisual,
- "BImage::renderXImage: unsupported visual\n"));
- delete [] d;
- XDestroyImage(image);
- return (XImage *) 0;
- }
-} else {
- switch (control.getVisual()->c_class) {
- case StaticColor:
- case PseudoColor:
- for (y = 0, offset = 0; y < height; y++) {
- for (x = 0; x < width; x++, offset++) {
- r = red_table[red[offset]];
- g = green_table[green[offset]];
- b = blue_table[blue[offset]];
-
- pixel = (r * cpccpc) + (g * cpc) + b;
- *pixel_data++ = colors[pixel].pixel;
+ pixel_data = (ppixel_data += image->bytes_per_line);
}
- pixel_data = (ppixel_data += image->bytes_per_line);
- }
+ break;
- break;
+ case TrueColor:
+ for (y = 0, offset = 0; y < height; y++) {
+ for (x = 0; x < width; x++, offset++) {
+ r = red_table[red[offset]];
+ g = green_table[green[offset]];
+ b = blue_table[blue[offset]];
- case TrueColor:
- for (y = 0, offset = 0; y < height; y++) {
- for (x = 0; x < width; x++, offset++) {
- r = red_table[red[offset]];
- g = green_table[green[offset]];
- b = blue_table[blue[offset]];
-
- pixel = (r << red_offset) | (g << green_offset) | (b << blue_offset);
-
- switch (o) {
- case 8: // 8bpp
- *pixel_data++ = pixel;
- break;
-
- case 16: // 16bpp LSB
- *pixel_data++ = pixel;
- *pixel_data++ = pixel >> 8;
- break;
-
- case 17: // 16bpp MSB
- *pixel_data++ = pixel >> 8;
- *pixel_data++ = pixel;
- break;
-
- case 24: // 24bpp LSB
- *pixel_data++ = pixel;
- *pixel_data++ = pixel >> 8;
- *pixel_data++ = pixel >> 16;
- break;
-
- case 25: // 24bpp MSB
- *pixel_data++ = pixel >> 16;
- *pixel_data++ = pixel >> 8;
- *pixel_data++ = pixel;
- break;
-
- case 32: // 32bpp LSB
- *pixel_data++ = pixel;
- *pixel_data++ = pixel >> 8;
- *pixel_data++ = pixel >> 16;
- *pixel_data++ = pixel >> 24;
- break;
-
- case 33: // 32bpp MSB
- *pixel_data++ = pixel >> 24;
- *pixel_data++ = pixel >> 16;
- *pixel_data++ = pixel >> 8;
- *pixel_data++ = pixel;
- break;
+ pixel = (r << red_offset) | (g << green_offset) | (b << blue_offset);
+ assignPixelData(o, &pixel_data, pixel);
}
+
+ pixel_data = (ppixel_data += image->bytes_per_line);
}
- pixel_data = (ppixel_data += image->bytes_per_line);
- }
+ break;
- break;
+ case StaticGray:
+ case GrayScale:
+ for (y = 0, offset = 0; y < height; y++) {
+ for (x = 0; x < width; x++, offset++) {
+ r = *(red_table + *(red + offset));
+ g = *(green_table + *(green + offset));
+ b = *(blue_table + *(blue + offset));
- case StaticGray:
- case GrayScale:
- for (y = 0, offset = 0; y < height; y++) {
- for (x = 0; x < width; x++, offset++) {
- r = *(red_table + *(red + offset));
- g = *(green_table + *(green + offset));
- b = *(blue_table + *(blue + offset));
+ g = ((r * 30) + (g * 59) + (b * 11)) / 100;
+ *pixel_data++ = colors[g].pixel;
+ }
- g = ((r * 30) + (g * 59) + (b * 11)) / 100;
- *pixel_data++ = colors[g].pixel;
+ pixel_data = (ppixel_data += image->bytes_per_line);
}
- pixel_data = (ppixel_data += image->bytes_per_line);
- }
-
- break;
+ break;
- default:
- fprintf(stderr, i18n(ImageSet, ImageUnsupVisual,
- "BImage::renderXImage: unsupported visual\n"));
- delete [] d;
- XDestroyImage(image);
- return (XImage *) 0;
+ default:
+ fprintf(stderr, i18n(ImageSet, ImageUnsupVisual,
+ "BImage::renderXImage: unsupported visual\n"));
+ delete [] d;
+ XDestroyImage(image);
+ return (XImage *) 0;
+ }
}
-}
-image->data = (char *) d;
-return image;
+ image->data = (char *) d;
+ return image;
}
Pixmap BImage::renderPixmap(void) {
Pixmap pixmap =
- XCreatePixmap(control.getBaseDisplay().getXDisplay(),
- control.getDrawable(), width, height, control.getDepth());
+ XCreatePixmap(control->getBaseDisplay()->getXDisplay(),
+ control->getDrawable(), width, height, control->getDepth());
if (pixmap == None) {
fprintf(stderr, i18n(ImageSet, ImageErrorCreatingPixmap,
XImage *image = renderXImage();
if (! image) {
- XFreePixmap(control.getBaseDisplay().getXDisplay(), pixmap);
+ XFreePixmap(control->getBaseDisplay()->getXDisplay(), pixmap);
return None;
} else if (! image->data) {
XDestroyImage(image);
- XFreePixmap(control.getBaseDisplay().getXDisplay(), pixmap);
+ XFreePixmap(control->getBaseDisplay()->getXDisplay(), pixmap);
return None;
}
- XPutImage(control.getBaseDisplay().getXDisplay(), pixmap,
- DefaultGC(control.getBaseDisplay().getXDisplay(),
- control.getScreenInfo().getScreenNumber()),
+ XPutImage(control->getBaseDisplay()->getXDisplay(), pixmap,
+ DefaultGC(control->getBaseDisplay()->getXDisplay(),
+ control->getScreenInfo()->getScreenNumber()),
image, 0, 0, 0, 0, width, height);
if (image->data) {
void BImage::bevel2(void) {
if (width > 4 && height > 4) {
unsigned char r, g, b, rr ,gg ,bb, *pr = red + width + 1,
- *pg = green + width + 1, *pb = blue + width + 1;
+ *pg = green + width + 1, *pb = blue + width + 1;
unsigned int w = width - 2, h = height - 1, wh = width * (height - 3);
while (--w) {
// modified for interlacing by Brad Hughes
float drx, dgx, dbx, dry, dgy, dby, yr = 0.0, yg = 0.0, yb = 0.0,
- xr = (float) from->getRed(),
- xg = (float) from->getGreen(),
- xb = (float) from->getBlue();
+ xr = (float) from.red(),
+ xg = (float) from.green(),
+ xb = (float) from.blue();
unsigned char *pr = red, *pg = green, *pb = blue;
unsigned int w = width * 2, h = height * 2, *xt = xtable, *yt = ytable;
register unsigned int x, y;
- dry = drx = (float) (to->getRed() - from->getRed());
- dgy = dgx = (float) (to->getGreen() - from->getGreen());
- dby = dbx = (float) (to->getBlue() - from->getBlue());
+ dry = drx = (float) (to.red() - from.red());
+ dgy = dgx = (float) (to.green() - from.green());
+ dby = dbx = (float) (to.blue() - from.blue());
// Create X table
drx /= w;
// Combine tables to create gradient
-#ifdef INTERLACE
if (! interlaced) {
-#endif // INTERLACE
-
// normal dgradient
for (yt = ytable, y = 0; y < height; y++, yt += 3) {
for (xt = xtable, x = 0; x < width; x++) {
*(pb++) = *(xt++) + *(yt + 2);
}
}
-
-#ifdef INTERLACE
} else {
// faked interlacing effect
unsigned char channel, channel2;
}
}
}
-#endif // INTERLACE
-
}
void BImage::hgradient(void) {
float drx, dgx, dbx,
- xr = (float) from->getRed(),
- xg = (float) from->getGreen(),
- xb = (float) from->getBlue();
+ xr = (float) from.red(),
+ xg = (float) from.green(),
+ xb = (float) from.blue();
unsigned char *pr = red, *pg = green, *pb = blue;
register unsigned int x, y;
- drx = (float) (to->getRed() - from->getRed());
- dgx = (float) (to->getGreen() - from->getGreen());
- dbx = (float) (to->getBlue() - from->getBlue());
+ drx = (float) (to.red() - from.red());
+ dgx = (float) (to.green() - from.green());
+ dbx = (float) (to.blue() - from.blue());
drx /= width;
dgx /= width;
dbx /= width;
-#ifdef INTERLACE
if (interlaced && height > 2) {
// faked interlacing effect
unsigned char channel, channel2;
memcpy(pb, (blue + offset), width);
}
} else {
-#endif // INTERLACE
-
// normal hgradient
for (x = 0; x < width; x++) {
*(pr++) = (unsigned char) (xr);
memcpy(pg, green, width);
memcpy(pb, blue, width);
}
-
-#ifdef INTERLACE
}
-#endif // INTERLACE
-
}
void BImage::vgradient(void) {
float dry, dgy, dby,
- yr = (float) from->getRed(),
- yg = (float) from->getGreen(),
- yb = (float) from->getBlue();
+ yr = (float) from.red(),
+ yg = (float) from.green(),
+ yb = (float) from.blue();
unsigned char *pr = red, *pg = green, *pb = blue;
register unsigned int y;
- dry = (float) (to->getRed() - from->getRed());
- dgy = (float) (to->getGreen() - from->getGreen());
- dby = (float) (to->getBlue() - from->getBlue());
+ dry = (float) (to.red() - from.red());
+ dgy = (float) (to.green() - from.green());
+ dby = (float) (to.blue() - from.blue());
dry /= height;
dgy /= height;
dby /= height;
-#ifdef INTERLACE
if (interlaced) {
// faked interlacing effect
unsigned char channel, channel2;
yb += dby;
}
} else {
-#endif // INTERLACE
-
// normal vgradient
for (y = 0; y < height; y++, pr += width, pg += width, pb += width) {
memset(pr, (unsigned char) yr, width);
yg += dgy;
yb += dby;
}
-
-#ifdef INTERLACE
}
-#endif // INTERLACE
-
}
void BImage::pgradient(void) {
// pyramid gradient - based on original dgradient, written by
// Mosfet (mosfet@kde.org)
- // adapted from kde sources for Openbox by Brad Hughes
+ // adapted from kde sources for Blackbox by Brad Hughes
float yr, yg, yb, drx, dgx, dbx, dry, dgy, dby,
- xr, xg, xb;
+ xr, xg, xb;
int rsign, gsign, bsign;
unsigned char *pr = red, *pg = green, *pb = blue;
- unsigned int tr = to->getRed(), tg = to->getGreen(), tb = to->getBlue(),
- *xt = xtable, *yt = ytable;
+ unsigned int tr = to.red(), tg = to.green(), tb = to.blue(),
+ *xt = xtable, *yt = ytable;
register unsigned int x, y;
- dry = drx = (float) (to->getRed() - from->getRed());
- dgy = dgx = (float) (to->getGreen() - from->getGreen());
- dby = dbx = (float) (to->getBlue() - from->getBlue());
+ dry = drx = (float) (to.red() - from.red());
+ dgy = dgx = (float) (to.green() - from.green());
+ dby = dbx = (float) (to.blue() - from.blue());
rsign = (drx < 0) ? -1 : 1;
gsign = (dgx < 0) ? -1 : 1;
// Combine tables to create gradient
-#ifdef INTERLACE
if (! interlaced) {
-#endif // INTERLACE
-
// normal pgradient
for (yt = ytable, y = 0; y < height; y++, yt += 3) {
for (xt = xtable, x = 0; x < width; x++) {
*(pb++) = (unsigned char) (tb - (bsign * (*(xt++) + *(yt + 2))));
}
}
-
-#ifdef INTERLACE
} else {
// faked interlacing effect
unsigned char channel, channel2;
}
}
}
-#endif // INTERLACE
}
void BImage::rgradient(void) {
// rectangle gradient - based on original dgradient, written by
// Mosfet (mosfet@kde.org)
- // adapted from kde sources for Openbox by Brad Hughes
+ // adapted from kde sources for Blackbox by Brad Hughes
float drx, dgx, dbx, dry, dgy, dby, xr, xg, xb, yr, yg, yb;
int rsign, gsign, bsign;
unsigned char *pr = red, *pg = green, *pb = blue;
- unsigned int tr = to->getRed(), tg = to->getGreen(), tb = to->getBlue(),
- *xt = xtable, *yt = ytable;
+ unsigned int tr = to.red(), tg = to.green(), tb = to.blue(),
+ *xt = xtable, *yt = ytable;
register unsigned int x, y;
- dry = drx = (float) (to->getRed() - from->getRed());
- dgy = dgx = (float) (to->getGreen() - from->getGreen());
- dby = dbx = (float) (to->getBlue() - from->getBlue());
+ dry = drx = (float) (to.red() - from.red());
+ dgy = dgx = (float) (to.green() - from.green());
+ dby = dbx = (float) (to.blue() - from.blue());
rsign = (drx < 0) ? -2 : 2;
gsign = (dgx < 0) ? -2 : 2;
// Combine tables to create gradient
-#ifdef INTERLACE
if (! interlaced) {
-#endif // INTERLACE
-
// normal rgradient
for (yt = ytable, y = 0; y < height; y++, yt += 3) {
for (xt = xtable, x = 0; x < width; x++) {
*(pb++) = (unsigned char) (tb - (bsign * max(*(xt++), *(yt + 2))));
}
}
-
-#ifdef INTERLACE
} else {
// faked interlacing effect
unsigned char channel, channel2;
}
}
}
-#endif // INTERLACE
}
void BImage::egradient(void) {
// elliptic gradient - based on original dgradient, written by
// Mosfet (mosfet@kde.org)
- // adapted from kde sources for Openbox by Brad Hughes
+ // adapted from kde sources for Blackbox by Brad Hughes
float drx, dgx, dbx, dry, dgy, dby, yr, yg, yb, xr, xg, xb;
int rsign, gsign, bsign;
unsigned char *pr = red, *pg = green, *pb = blue;
unsigned int *xt = xtable, *yt = ytable,
- tr = (unsigned long) to->getRed(),
- tg = (unsigned long) to->getGreen(),
- tb = (unsigned long) to->getBlue();
+ tr = (unsigned long) to.red(),
+ tg = (unsigned long) to.green(),
+ tb = (unsigned long) to.blue();
register unsigned int x, y;
- dry = drx = (float) (to->getRed() - from->getRed());
- dgy = dgx = (float) (to->getGreen() - from->getGreen());
- dby = dbx = (float) (to->getBlue() - from->getBlue());
+ dry = drx = (float) (to.red() - from.red());
+ dgy = dgx = (float) (to.green() - from.green());
+ dby = dbx = (float) (to.blue() - from.blue());
rsign = (drx < 0) ? -1 : 1;
gsign = (dgx < 0) ? -1 : 1;
// Combine tables to create gradient
-#ifdef INTERLACE
if (! interlaced) {
-#endif // INTERLACE
-
// normal egradient
for (yt = ytable, y = 0; y < height; y++, yt += 3) {
for (xt = xtable, x = 0; x < width; x++) {
*(pr++) = (unsigned char)
- (tr - (rsign * control.getSqrt(*(xt++) + *(yt))));
+ (tr - (rsign * control->getSqrt(*(xt++) + *(yt))));
*(pg++) = (unsigned char)
- (tg - (gsign * control.getSqrt(*(xt++) + *(yt + 1))));
+ (tg - (gsign * control->getSqrt(*(xt++) + *(yt + 1))));
*(pb++) = (unsigned char)
- (tb - (bsign * control.getSqrt(*(xt++) + *(yt + 2))));
+ (tb - (bsign * control->getSqrt(*(xt++) + *(yt + 2))));
}
}
-
-#ifdef INTERLACE
} else {
// faked interlacing effect
unsigned char channel, channel2;
for (xt = xtable, x = 0; x < width; x++) {
if (y & 1) {
channel = (unsigned char)
- (tr - (rsign * control.getSqrt(*(xt++) + *(yt))));
+ (tr - (rsign * control->getSqrt(*(xt++) + *(yt))));
channel2 = (channel >> 1) + (channel >> 2);
if (channel2 > channel) channel2 = 0;
*(pr++) = channel2;
channel = (unsigned char)
- (tg - (gsign * control.getSqrt(*(xt++) + *(yt + 1))));
+ (tg - (gsign * control->getSqrt(*(xt++) + *(yt + 1))));
channel2 = (channel >> 1) + (channel >> 2);
if (channel2 > channel) channel2 = 0;
*(pg++) = channel2;
channel = (unsigned char)
- (tb - (bsign * control.getSqrt(*(xt++) + *(yt + 2))));
+ (tb - (bsign * control->getSqrt(*(xt++) + *(yt + 2))));
channel2 = (channel >> 1) + (channel >> 2);
if (channel2 > channel) channel2 = 0;
*(pb++) = channel2;
} else {
channel = (unsigned char)
- (tr - (rsign * control.getSqrt(*(xt++) + *(yt))));
+ (tr - (rsign * control->getSqrt(*(xt++) + *(yt))));
channel2 = channel + (channel >> 3);
if (channel2 < channel) channel2 = ~0;
*(pr++) = channel2;
channel = (unsigned char)
- (tg - (gsign * control.getSqrt(*(xt++) + *(yt + 1))));
+ (tg - (gsign * control->getSqrt(*(xt++) + *(yt + 1))));
channel2 = channel + (channel >> 3);
if (channel2 < channel) channel2 = ~0;
*(pg++) = channel2;
channel = (unsigned char)
- (tb - (bsign * control.getSqrt(*(xt++) + *(yt + 2))));
+ (tb - (bsign * control->getSqrt(*(xt++) + *(yt + 2))));
channel2 = channel + (channel >> 3);
if (channel2 < channel) channel2 = ~0;
*(pb++) = channel2;
}
}
}
-#endif // INTERLACE
}
void BImage::pcgradient(void) {
// pipe cross gradient - based on original dgradient, written by
// Mosfet (mosfet@kde.org)
- // adapted from kde sources for Openbox by Brad Hughes
+ // adapted from kde sources for Blackbox by Brad Hughes
float drx, dgx, dbx, dry, dgy, dby, xr, xg, xb, yr, yg, yb;
int rsign, gsign, bsign;
unsigned char *pr = red, *pg = green, *pb = blue;
unsigned int *xt = xtable, *yt = ytable,
- tr = to->getRed(),
- tg = to->getGreen(),
- tb = to->getBlue();
+ tr = to.red(),
+ tg = to.green(),
+ tb = to.blue();
register unsigned int x, y;
- dry = drx = (float) (to->getRed() - from->getRed());
- dgy = dgx = (float) (to->getGreen() - from->getGreen());
- dby = dbx = (float) (to->getBlue() - from->getBlue());
+ dry = drx = (float) (to.red() - from.red());
+ dgy = dgx = (float) (to.green() - from.green());
+ dby = dbx = (float) (to.blue() - from.blue());
rsign = (drx < 0) ? -2 : 2;
gsign = (dgx < 0) ? -2 : 2;
// Combine tables to create gradient
-#ifdef INTERLACE
if (! interlaced) {
-#endif // INTERLACE
-
// normal pcgradient
for (yt = ytable, y = 0; y < height; y++, yt += 3) {
for (xt = xtable, x = 0; x < width; x++) {
*(pb++) = (unsigned char) (tb - (bsign * min(*(xt++), *(yt + 2))));
}
}
-
-#ifdef INTERLACE
} else {
// faked interlacing effect
unsigned char channel, channel2;
}
}
}
-#endif // INTERLACE
}
void BImage::cdgradient(void) {
// cross diagonal gradient - based on original dgradient, written by
// Mosfet (mosfet@kde.org)
- // adapted from kde sources for Openbox by Brad Hughes
+ // adapted from kde sources for Blackbox by Brad Hughes
float drx, dgx, dbx, dry, dgy, dby, yr = 0.0, yg = 0.0, yb = 0.0,
- xr = (float) from->getRed(),
- xg = (float) from->getGreen(),
- xb = (float) from->getBlue();
+ xr = (float) from.red(),
+ xg = (float) from.green(),
+ xb = (float) from.blue();
unsigned char *pr = red, *pg = green, *pb = blue;
unsigned int w = width * 2, h = height * 2, *xt, *yt;
register unsigned int x, y;
- dry = drx = (float) (to->getRed() - from->getRed());
- dgy = dgx = (float) (to->getGreen() - from->getGreen());
- dby = dbx = (float) (to->getBlue() - from->getBlue());
+ dry = drx = (float) (to.red() - from.red());
+ dgy = dgx = (float) (to.green() - from.green());
+ dby = dbx = (float) (to.blue() - from.blue());
// Create X table
drx /= w;
// Combine tables to create gradient
-#ifdef INTERLACE
if (! interlaced) {
-#endif // INTERLACE
-
// normal cdgradient
for (yt = ytable, y = 0; y < height; y++, yt += 3) {
for (xt = xtable, x = 0; x < width; x++) {
*(pb++) = *(xt++) + *(yt + 2);
}
}
-
-#ifdef INTERLACE
} else {
// faked interlacing effect
unsigned char channel, channel2;
}
}
}
-#endif // INTERLACE
-}
-
-
-BImageControl::BImageControl(BaseDisplay &dpy, ScreenInfo &scrn, Bool _dither,
- int _cpc, unsigned long cache_timeout,
- unsigned long cmax) : basedisplay(dpy),
-screeninfo(scrn)
-{
- setDither(_dither);
- setColorsPerChannel(_cpc);
-
- cache_max = cmax;
-#ifdef TIMEDCACHE
- if (cache_timeout) {
- timer = new BTimer(basedisplay, *this);
- timer->setTimeout(cache_timeout);
- timer->start();
- } else
- timer = (BTimer *) 0;
-#endif // TIMEDCACHE
-
- colors = (XColor *) 0;
- ncolors = 0;
-
- grad_xbuffer = grad_ybuffer = (unsigned int *) 0;
- grad_buffer_width = grad_buffer_height = 0;
-
- sqrt_table = (unsigned long *) 0;
-
- screen_depth = screeninfo.getDepth();
- window = screeninfo.getRootWindow();
- screen_number = screeninfo.getScreenNumber();
-
- int count;
- XPixmapFormatValues *pmv = XListPixmapFormats(basedisplay.getXDisplay(),
- &count);
- colormap = screeninfo.getColormap();
-
- if (pmv) {
- bits_per_pixel = 0;
- for (int i = 0; i < count; i++)
- if (pmv[i].depth == screen_depth) {
- bits_per_pixel = pmv[i].bits_per_pixel;
- break;
- }
-
- XFree(pmv);
- }
-
- if (bits_per_pixel == 0) bits_per_pixel = screen_depth;
- if (bits_per_pixel >= 24) setDither(False);
-
- red_offset = green_offset = blue_offset = 0;
-
- switch (getVisual()->c_class) {
- case TrueColor:
- {
- int i;
-
- // compute color tables
- unsigned long red_mask = getVisual()->red_mask,
- green_mask = getVisual()->green_mask,
- blue_mask = getVisual()->blue_mask;
-
- while (! (red_mask & 1)) { red_offset++; red_mask >>= 1; }
- while (! (green_mask & 1)) { green_offset++; green_mask >>= 1; }
- while (! (blue_mask & 1)) { blue_offset++; blue_mask >>= 1; }
-
- red_bits = 255 / red_mask;
- green_bits = 255 / green_mask;
- blue_bits = 255 / blue_mask;
-
- for (i = 0; i < 256; i++) {
- red_color_table[i] = i / red_bits;
- green_color_table[i] = i / green_bits;
- blue_color_table[i] = i / blue_bits;
- }
- }
-
- break;
-
- case PseudoColor:
- case StaticColor:
- {
- ncolors = colors_per_channel * colors_per_channel * colors_per_channel;
-
- if (ncolors > (1 << screen_depth)) {
- colors_per_channel = (1 << screen_depth) / 3;
- ncolors = colors_per_channel * colors_per_channel * colors_per_channel;
- }
-
- if (colors_per_channel < 2 || ncolors > (1 << screen_depth)) {
- fprintf(stderr, i18n(ImageSet, ImageInvalidColormapSize,
- "BImageControl::BImageControl: invalid colormap size %d "
- "(%d/%d/%d) - reducing"),
- ncolors, colors_per_channel, colors_per_channel,
- colors_per_channel);
-
- colors_per_channel = (1 << screen_depth) / 3;
- }
-
- colors = new XColor[ncolors];
- if (! colors) {
- fprintf(stderr, i18n(ImageSet,
- ImageErrorAllocatingColormap,
- "BImageControl::BImageControl: error allocating "
- "colormap\n"));
- exit(1);
- }
-
- int i = 0, ii, p, r, g, b,
-
-#ifdef ORDEREDPSEUDO
- bits = 256 / colors_per_channel;
-#else // !ORDEREDPSEUDO
- bits = 255 / (colors_per_channel - 1);
-#endif // ORDEREDPSEUDO
-
- red_bits = green_bits = blue_bits = bits;
-
- for (i = 0; i < 256; i++)
- red_color_table[i] = green_color_table[i] = blue_color_table[i] =
- i / bits;
-
- for (r = 0, i = 0; r < colors_per_channel; r++)
- for (g = 0; g < colors_per_channel; g++)
- for (b = 0; b < colors_per_channel; b++, i++) {
- colors[i].red = (r * 0xffff) / (colors_per_channel - 1);
- colors[i].green = (g * 0xffff) / (colors_per_channel - 1);
- colors[i].blue = (b * 0xffff) / (colors_per_channel - 1);;
- colors[i].flags = DoRed|DoGreen|DoBlue;
- }
-
- basedisplay.grab();
-
- for (i = 0; i < ncolors; i++)
- if (! XAllocColor(basedisplay.getXDisplay(), colormap, &colors[i])) {
- fprintf(stderr, i18n(ImageSet, ImageColorAllocFail,
- "couldn't alloc color %i %i %i\n"),
- colors[i].red, colors[i].green, colors[i].blue);
- colors[i].flags = 0;
- } else
- colors[i].flags = DoRed|DoGreen|DoBlue;
-
- basedisplay.ungrab();
-
- XColor icolors[256];
- int incolors = (((1 << screen_depth) > 256) ? 256 : (1 << screen_depth));
-
- for (i = 0; i < incolors; i++)
- icolors[i].pixel = i;
-
- XQueryColors(basedisplay.getXDisplay(), colormap, icolors, incolors);
- for (i = 0; i < ncolors; i++) {
- if (! colors[i].flags) {
- unsigned long chk = 0xffffffff, pixel, close = 0;
-
- p = 2;
- while (p--) {
- for (ii = 0; ii < incolors; ii++) {
- r = (colors[i].red - icolors[i].red) >> 8;
- g = (colors[i].green - icolors[i].green) >> 8;
- b = (colors[i].blue - icolors[i].blue) >> 8;
- pixel = (r * r) + (g * g) + (b * b);
-
- if (pixel < chk) {
- chk = pixel;
- close = ii;
- }
-
- colors[i].red = icolors[close].red;
- colors[i].green = icolors[close].green;
- colors[i].blue = icolors[close].blue;
-
- if (XAllocColor(basedisplay.getXDisplay(), colormap,
- &colors[i])) {
- colors[i].flags = DoRed|DoGreen|DoBlue;
- break;
- }
- }
- }
- }
- }
-
- break;
- }
-
- case GrayScale:
- case StaticGray:
- {
-
- if (getVisual()->c_class == StaticGray) {
- ncolors = 1 << screen_depth;
- } else {
- ncolors = colors_per_channel * colors_per_channel * colors_per_channel;
-
- if (ncolors > (1 << screen_depth)) {
- colors_per_channel = (1 << screen_depth) / 3;
- ncolors =
- colors_per_channel * colors_per_channel * colors_per_channel;
- }
- }
-
- if (colors_per_channel < 2 || ncolors > (1 << screen_depth)) {
- fprintf(stderr, i18n(ImageSet, ImageInvalidColormapSize,
- "BImageControl::BImageControl: invalid colormap size %d "
- "(%d/%d/%d) - reducing"),
- ncolors, colors_per_channel, colors_per_channel,
- colors_per_channel);
-
- colors_per_channel = (1 << screen_depth) / 3;
- }
-
- colors = new XColor[ncolors];
- if (! colors) {
- fprintf(stderr, i18n(ImageSet,
- ImageErrorAllocatingColormap,
- "BImageControl::BImageControl: error allocating "
- "colormap\n"));
- exit(1);
- }
-
- int i = 0, ii, p, bits = 255 / (colors_per_channel - 1);
- red_bits = green_bits = blue_bits = bits;
-
- for (i = 0; i < 256; i++)
- red_color_table[i] = green_color_table[i] = blue_color_table[i] =
- i / bits;
-
- basedisplay.grab();
- for (i = 0; i < ncolors; i++) {
- colors[i].red = (i * 0xffff) / (colors_per_channel - 1);
- colors[i].green = (i * 0xffff) / (colors_per_channel - 1);
- colors[i].blue = (i * 0xffff) / (colors_per_channel - 1);;
- colors[i].flags = DoRed|DoGreen|DoBlue;
-
- if (! XAllocColor(basedisplay.getXDisplay(), colormap,
- &colors[i])) {
- fprintf(stderr, i18n(ImageSet, ImageColorAllocFail,
- "couldn't alloc color %i %i %i\n"),
- colors[i].red, colors[i].green, colors[i].blue);
- colors[i].flags = 0;
- } else
- colors[i].flags = DoRed|DoGreen|DoBlue;
- }
-
- basedisplay.ungrab();
-
- XColor icolors[256];
- int incolors = (((1 << screen_depth) > 256) ? 256 :
- (1 << screen_depth));
-
- for (i = 0; i < incolors; i++)
- icolors[i].pixel = i;
-
- XQueryColors(basedisplay.getXDisplay(), colormap, icolors, incolors);
- for (i = 0; i < ncolors; i++) {
- if (! colors[i].flags) {
- unsigned long chk = 0xffffffff, pixel, close = 0;
-
- p = 2;
- while (p--) {
- for (ii = 0; ii < incolors; ii++) {
- int r = (colors[i].red - icolors[i].red) >> 8;
- int g = (colors[i].green - icolors[i].green) >> 8;
- int b = (colors[i].blue - icolors[i].blue) >> 8;
- pixel = (r * r) + (g * g) + (b * b);
-
- if (pixel < chk) {
- chk = pixel;
- close = ii;
- }
-
- colors[i].red = icolors[close].red;
- colors[i].green = icolors[close].green;
- colors[i].blue = icolors[close].blue;
-
- if (XAllocColor(basedisplay.getXDisplay(), colormap,
- &colors[i])) {
- colors[i].flags = DoRed|DoGreen|DoBlue;
- break;
- }
- }
- }
- }
- }
-
- break;
- }
-
- default:
- fprintf(stderr, i18n(ImageSet, ImageUnsupVisual,
- "BImageControl::BImageControl: unsupported visual %d\n"),
- getVisual()->c_class);
- exit(1);
- }
-}
-
-
-BImageControl::~BImageControl(void) {
- if (sqrt_table) {
- delete [] sqrt_table;
- }
-
- if (grad_xbuffer) {
- delete [] grad_xbuffer;
- }
-
- if (grad_ybuffer) {
- delete [] grad_ybuffer;
- }
-
- if (colors) {
- unsigned long *pixels = new unsigned long [ncolors];
-
- int i;
- for (i = 0; i < ncolors; i++)
- *(pixels + i) = (*(colors + i)).pixel;
-
- XFreeColors(basedisplay.getXDisplay(), colormap, pixels, ncolors, 0);
-
- delete [] colors;
- }
-
- if (!cache.empty()) {
- int i, n = cache.size();
- fprintf(stderr, i18n(ImageSet, ImagePixmapRelease,
- "BImageContol::~BImageControl: pixmap cache - "
- "releasing %d pixmaps\n"), n);
-
- for (i = 0; i < n; i++) {
- Cache *tmp = cache.front();
- XFreePixmap(basedisplay.getXDisplay(), tmp->pixmap);
- cache.remove(tmp);
- delete tmp;
- }
-
-#ifdef TIMEDCACHE
- if (timer) {
- timer->stop();
- delete timer;
- }
-#endif // TIMEDCACHE
- }
-}
-
-
-Pixmap BImageControl::searchCache(unsigned int width, unsigned int height,
- unsigned long texture,
- BColor *c1, BColor *c2) {
- if (!cache.empty()) {
-
- CacheList::iterator it;
- for (it = cache.begin(); it != cache.end(); ++it) {
- Cache *tmp = *it;
- if ((tmp->width == width) && (tmp->height == height) &&
- (tmp->texture == texture) && (tmp->pixel1 == c1->getPixel()))
- if (texture & BImage_Gradient) {
- if (tmp->pixel2 == c2->getPixel()) {
- tmp->count++;
- return tmp->pixmap;
- }
- } else {
- tmp->count++;
- return tmp->pixmap;
- }
- }
- }
-
- return None;
-}
-
-
-Pixmap BImageControl::renderImage(unsigned int width, unsigned int height,
- BTexture *texture) {
- if (texture->getTexture() & BImage_ParentRelative) return ParentRelative;
-
- Pixmap pixmap = searchCache(width, height, texture->getTexture(),
- texture->getColor(), texture->getColorTo());
- if (pixmap) return pixmap;
-
- BImage image(*this, width, height);
- pixmap = image.render(texture);
-
- if (pixmap) {
- Cache *tmp = new Cache;
-
- tmp->pixmap = pixmap;
- tmp->width = width;
- tmp->height = height;
- tmp->count = 1;
- tmp->texture = texture->getTexture();
- tmp->pixel1 = texture->getColor()->getPixel();
-
- if (texture->getTexture() & BImage_Gradient)
- tmp->pixel2 = texture->getColorTo()->getPixel();
- else
- tmp->pixel2 = 0l;
-
- cache.push_back(tmp);
-
- if ((unsigned) cache.size() > cache_max) {
-#ifdef DEBUG
- fprintf(stderr, i18n(ImageSet, ImagePixmapCacheLarge,
- "BImageControl::renderImage: cache is large, "
- "forcing cleanout\n"));
-#endif // DEBUG
-
- timeout();
- }
-
- return pixmap;
- }
-
- return None;
-}
-
-
-void BImageControl::removeImage(Pixmap pixmap) {
- if (pixmap) {
- CacheList::iterator it;
- for (it = cache.begin(); it != cache.end(); ++it) {
- Cache *tmp = *it;
- if (tmp->pixmap == pixmap) {
- if (tmp->count) {
- tmp->count--;
-
-#ifdef TIMEDCACHE
- if (! timer) timeout();
-#else // !TIMEDCACHE
- if (! tmp->count) timeout();
-#endif // TIMEDCACHE
- }
-
- return;
- }
- }
- }
-}
-
-
-unsigned long BImageControl::getColor(const char *colorname,
- unsigned char *r, unsigned char *g,
- unsigned char *b)
-{
- XColor color;
- color.pixel = 0;
-
- if (! XParseColor(basedisplay.getXDisplay(), colormap, colorname, &color))
- fprintf(stderr, "BImageControl::getColor: color parse error: \"%s\"\n",
- colorname);
- else if (! XAllocColor(basedisplay.getXDisplay(), colormap, &color))
- fprintf(stderr, "BImageControl::getColor: color alloc error: \"%s\"\n",
- colorname);
-
- if (color.red == 65535) *r = 0xff;
- else *r = (unsigned char) (color.red / 0xff);
- if (color.green == 65535) *g = 0xff;
- else *g = (unsigned char) (color.green / 0xff);
- if (color.blue == 65535) *b = 0xff;
- else *b = (unsigned char) (color.blue / 0xff);
-
- return color.pixel;
-}
-
-
-unsigned long BImageControl::getColor(const char *colorname) {
- XColor color;
- color.pixel = 0;
-
- if (! XParseColor(basedisplay.getXDisplay(), colormap, colorname, &color))
- fprintf(stderr, "BImageControl::getColor: color parse error: \"%s\"\n",
- colorname);
- else if (! XAllocColor(basedisplay.getXDisplay(), colormap, &color))
- fprintf(stderr, "BImageControl::getColor: color alloc error: \"%s\"\n",
- colorname);
-
- return color.pixel;
-}
-
-
-void BImageControl::getColorTables(unsigned char **rmt, unsigned char **gmt,
- unsigned char **bmt,
- int *roff, int *goff, int *boff,
- int *rbit, int *gbit, int *bbit) {
- if (rmt) *rmt = red_color_table;
- if (gmt) *gmt = green_color_table;
- if (bmt) *bmt = blue_color_table;
-
- if (roff) *roff = red_offset;
- if (goff) *goff = green_offset;
- if (boff) *boff = blue_offset;
-
- if (rbit) *rbit = red_bits;
- if (gbit) *gbit = green_bits;
- if (bbit) *bbit = blue_bits;
-}
-
-
-void BImageControl::getXColorTable(XColor **c, int *n) {
- if (c) *c = colors;
- if (n) *n = ncolors;
-}
-
-
-void BImageControl::getGradientBuffers(unsigned int w,
- unsigned int h,
- unsigned int **xbuf,
- unsigned int **ybuf)
-{
- if (w > grad_buffer_width) {
- if (grad_xbuffer) {
- delete [] grad_xbuffer;
- }
-
- grad_buffer_width = w;
-
- grad_xbuffer = new unsigned int[grad_buffer_width * 3];
- }
-
- if (h > grad_buffer_height) {
- if (grad_ybuffer) {
- delete [] grad_ybuffer;
- }
-
- grad_buffer_height = h;
-
- grad_ybuffer = new unsigned int[grad_buffer_height * 3];
- }
-
- *xbuf = grad_xbuffer;
- *ybuf = grad_ybuffer;
-}
-
-
-void BImageControl::installRootColormap(void) {
- basedisplay.grab();
-
- Bool install = True;
- int i = 0, ncmap = 0;
- Colormap *cmaps =
- XListInstalledColormaps(basedisplay.getXDisplay(), window, &ncmap);
-
- if (cmaps) {
- for (i = 0; i < ncmap; i++)
- if (*(cmaps + i) == colormap)
- install = False;
-
- if (install)
- XInstallColormap(basedisplay.getXDisplay(), colormap);
-
- XFree(cmaps);
- }
-
- basedisplay.ungrab();
-}
-
-
-void BImageControl::setColorsPerChannel(int cpc) {
- if (cpc < 2) cpc = 2;
- if (cpc > 6) cpc = 6;
-
- colors_per_channel = cpc;
-}
-
-
-unsigned long BImageControl::getSqrt(unsigned int x) {
- if (! sqrt_table) {
- // build sqrt table for use with elliptic gradient
-
- sqrt_table = new unsigned long[(256 * 256 * 2) + 1];
- int i = 0;
-
- for (; i < (256 * 256 * 2); i++)
- *(sqrt_table + i) = bsqrt(i);
- }
-
- return (*(sqrt_table + x));
-}
-
-
-void BImageControl::parseTexture(BTexture *texture, const char *t) {
- if ((! texture) || (! t)) return;
-
- int t_len = strlen(t) + 1, i;
- char *ts = new char[t_len];
- if (! ts) return;
-
- // convert to lower case
- for (i = 0; i < t_len; i++)
- *(ts + i) = tolower(*(t + i));
-
- if (strstr(ts, "parentrelative")) {
- texture->setTexture(BImage_ParentRelative);
- } else {
- texture->setTexture(0);
-
- if (strstr(ts, "solid"))
- texture->addTexture(BImage_Solid);
- else if (strstr(ts, "gradient")) {
- texture->addTexture(BImage_Gradient);
- if (strstr(ts, "crossdiagonal"))
- texture->addTexture(BImage_CrossDiagonal);
- else if (strstr(ts, "rectangle"))
- texture->addTexture(BImage_Rectangle);
- else if (strstr(ts, "pyramid"))
- texture->addTexture(BImage_Pyramid);
- else if (strstr(ts, "pipecross"))
- texture->addTexture(BImage_PipeCross);
- else if (strstr(ts, "elliptic"))
- texture->addTexture(BImage_Elliptic);
- else if (strstr(ts, "diagonal"))
- texture->addTexture(BImage_Diagonal);
- else if (strstr(ts, "horizontal"))
- texture->addTexture(BImage_Horizontal);
- else if (strstr(ts, "vertical"))
- texture->addTexture(BImage_Vertical);
- else
- texture->addTexture(BImage_Diagonal);
- } else
- texture->addTexture(BImage_Solid);
-
- if (strstr(ts, "raised"))
- texture->addTexture(BImage_Raised);
- else if (strstr(ts, "sunken"))
- texture->addTexture(BImage_Sunken);
- else if (strstr(ts, "flat"))
- texture->addTexture(BImage_Flat);
- else
- texture->addTexture(BImage_Raised);
-
- if (! (texture->getTexture() & BImage_Flat))
- if (strstr(ts, "bevel2"))
- texture->addTexture(BImage_Bevel2);
- else
- texture->addTexture(BImage_Bevel1);
-
-#ifdef INTERLACE
- if (strstr(ts, "interlaced"))
- texture->addTexture(BImage_Interlaced);
-#endif // INTERLACE
- }
-
- delete [] ts;
-}
-
-
-void BImageControl::parseColor(BColor *color, const char *c) {
- if (! color) return;
-
- if (color->isAllocated()) {
- unsigned long pixel = color->getPixel();
-
- XFreeColors(basedisplay.getXDisplay(), colormap, &pixel, 1, 0);
-
- color->setPixel(0l);
- color->setRGB(0, 0, 0);
- color->setAllocated(False);
- }
-
- if (c) {
- unsigned char r, g, b;
-
- color->setPixel(getColor(c, &r, &g, &b));
- color->setRGB(r, g, b);
- color->setAllocated(True);
- }
-}
-
-
-void BImageControl::timeout(void) {
- CacheList::iterator it;
- for (it = cache.begin(); it != cache.end(); ) {
- Cache *tmp = *it;
- ++it; // move on to the next item before this one is removed
- if (tmp->count <= 0) {
- XFreePixmap(basedisplay.getXDisplay(), tmp->pixmap);
- cache.remove(tmp);
- delete tmp;
- }
- }
}
+++ /dev/null
-// Image.h for Openbox
-// Copyright (c) 2001 Sean 'Shaleh' Perry <shaleh@debian.org>
-// Copyright (c) 1997 - 2000 Brad Hughes (bhughes@tcac.net)
-//
-// Permission is hereby granted, free of charge, to any person obtaining a
-// copy of this software and associated documentation files (the "Software"),
-// to deal in the Software without restriction, including without limitation
-// the rights to use, copy, modify, merge, publish, distribute, sublicense,
-// and/or sell copies of the Software, and to permit persons to whom the
-// Software is furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-// DEALINGS IN THE SOFTWARE.
-
-#ifndef __Image_hh
-#define __Image_hh
-
-#include <X11/Xlib.h>
-#include <X11/Xutil.h>
-
-#include "Timer.h"
-#include <list>
-
-class ScreenInfo;
-class BImage;
-class BImageControl;
-
-
-// bevel options
-#define BImage_Flat (1l<<1)
-#define BImage_Sunken (1l<<2)
-#define BImage_Raised (1l<<3)
-
-// textures
-#define BImage_Solid (1l<<4)
-#define BImage_Gradient (1l<<5)
-
-// gradients
-#define BImage_Horizontal (1l<<6)
-#define BImage_Vertical (1l<<7)
-#define BImage_Diagonal (1l<<8)
-#define BImage_CrossDiagonal (1l<<9)
-#define BImage_Rectangle (1l<<10)
-#define BImage_Pyramid (1l<<11)
-#define BImage_PipeCross (1l<<12)
-#define BImage_Elliptic (1l<<13)
-
-// bevel types
-#define BImage_Bevel1 (1l<<14)
-#define BImage_Bevel2 (1l<<15)
-
-// inverted image
-#define BImage_Invert (1l<<16)
-
-// parent relative image
-#define BImage_ParentRelative (1l<<17)
-
-#ifdef INTERLACE
-// fake interlaced image
-# define BImage_Interlaced (1l<<18)
-#endif // INTERLACE
-
-class BColor {
-private:
- int allocated;
- unsigned char red, green, blue;
- unsigned long pixel;
-
-public:
- BColor(char r = 0, char g = 0, char b = 0)
- { red = r; green = g; blue = b; pixel = 0; allocated = 0; }
-
- inline const int &isAllocated(void) const { return allocated; }
-
- inline const unsigned char &getRed(void) const { return red; }
- inline const unsigned char &getGreen(void) const { return green; }
- inline const unsigned char &getBlue(void) const { return blue; }
-
- inline const unsigned long &getPixel(void) const { return pixel; }
-
- inline void setAllocated(int a) { allocated = a; }
- inline void setRGB(char r, char g, char b) { red = r; green = g; blue = b; }
- inline void setPixel(unsigned long p) { pixel = p; }
-};
-
-
-class BTexture {
-private:
- BColor color, colorTo, hiColor, loColor;
- unsigned long texture;
-
-public:
- BTexture(void) { texture = 0; }
-
- inline BColor *getColor(void) { return &color; }
- inline BColor *getColorTo(void) { return &colorTo; }
- inline BColor *getHiColor(void) { return &hiColor; }
- inline BColor *getLoColor(void) { return &loColor; }
-
- inline const unsigned long &getTexture(void) const { return texture; }
-
- inline void setTexture(unsigned long t) { texture = t; }
- inline void addTexture(unsigned long t) { texture |= t; }
-};
-
-
-class BImage {
-private:
- BImageControl &control;
-
-#ifdef INTERLACE
- Bool interlaced;
-#endif // INTERLACE
-
- XColor *colors;
-
- BColor *from, *to;
- int red_offset, green_offset, blue_offset, red_bits, green_bits, blue_bits,
- ncolors, cpc, cpccpc;
- unsigned char *red, *green, *blue, *red_table, *green_table, *blue_table;
- unsigned int width, height, *xtable, *ytable;
-
-
-protected:
- Pixmap renderPixmap(void);
-
- XImage *renderXImage(void);
-
- void invert(void);
- void bevel1(void);
- void bevel2(void);
- void dgradient(void);
- void egradient(void);
- void hgradient(void);
- void pgradient(void);
- void rgradient(void);
- void vgradient(void);
- void cdgradient(void);
- void pcgradient(void);
-
-
-public:
- BImage(BImageControl &, unsigned int, unsigned int);
- ~BImage(void);
-
- Pixmap render(BTexture *);
- Pixmap render_solid(BTexture *);
- Pixmap render_gradient(BTexture *);
-};
-
-
-class BImageControl : public TimeoutHandler {
-private:
- Bool dither;
- BaseDisplay &basedisplay;
- ScreenInfo &screeninfo;
-#ifdef TIMEDCACHE
- BTimer *timer;
-#endif // TIMEDCACHE
-
- Colormap colormap;
-
- Window window;
- XColor *colors;
- int colors_per_channel, ncolors, screen_number, screen_depth,
- bits_per_pixel, red_offset, green_offset, blue_offset,
- red_bits, green_bits, blue_bits;
- unsigned char red_color_table[256], green_color_table[256],
- blue_color_table[256];
- unsigned int *grad_xbuffer, *grad_ybuffer, grad_buffer_width,
- grad_buffer_height;
- unsigned long *sqrt_table, cache_max;
-
- typedef struct Cache {
- Pixmap pixmap;
-
- unsigned int count, width, height;
- unsigned long pixel1, pixel2, texture;
- } Cache;
-
- typedef std::list<Cache*> CacheList;
- CacheList cache;
-
-
-protected:
- Pixmap searchCache(unsigned int, unsigned int, unsigned long, BColor *,
- BColor *);
-
-
-public:
- BImageControl(BaseDisplay &, ScreenInfo &, Bool = False, int = 4,
- unsigned long = 300000l, unsigned long = 200l);
- virtual ~BImageControl(void);
-
- inline BaseDisplay &getBaseDisplay(void) { return basedisplay; }
-
- inline const Bool &doDither(void) { return dither; }
-
- inline ScreenInfo &getScreenInfo(void) { return screeninfo; }
-
- inline const Window &getDrawable(void) const { return window; }
-
- inline Visual *getVisual(void) const { return screeninfo.getVisual(); }
-
- inline const int &getBitsPerPixel(void) const { return bits_per_pixel; }
- inline const int &getDepth(void) const { return screen_depth; }
- inline const int &getColorsPerChannel(void) const
- { return colors_per_channel; }
-
- unsigned long getColor(const char *);
- unsigned long getColor(const char *, unsigned char *, unsigned char *,
- unsigned char *);
- unsigned long getSqrt(unsigned int);
-
- Pixmap renderImage(unsigned int, unsigned int, BTexture *);
-
- void installRootColormap(void);
- void removeImage(Pixmap);
- void getColorTables(unsigned char **, unsigned char **, unsigned char **,
- int *, int *, int *, int *, int *, int *);
- void getXColorTable(XColor **, int *);
- void getGradientBuffers(unsigned int, unsigned int,
- unsigned int **, unsigned int **);
- void setDither(Bool d) { dither = d; }
- void setColorsPerChannel(int);
- void parseTexture(BTexture *, const char *);
- void parseColor(BColor *, const char * = 0);
-
- virtual void timeout(void);
-};
-
-
-#endif // __Image_hh
-
--- /dev/null
+// -*- mode: C++; indent-tabs-mode: nil; -*-
+// Image.hh for Blackbox - an X11 Window manager
+// Copyright (c) 2001 - 2002 Sean 'Shaleh' Perry <shaleh@debian.org>
+// Copyright (c) 1997 - 2000 Brad Hughes (bhughes@tcac.net)
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#ifndef __Image_hh
+#define __Image_hh
+
+extern "C" {
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+}
+
+#include <list>
+
+#include "Timer.hh"
+#include "BaseDisplay.hh"
+#include "Color.hh"
+
+class BImageControl;
+class BTexture;
+class BImageCache;
+
+class BImage {
+private:
+ BImageControl *control;
+ bool interlaced;
+ XColor *colors;
+
+ BColor from, to;
+ int red_offset, green_offset, blue_offset, red_bits, green_bits, blue_bits,
+ ncolors, cpc, cpccpc;
+ unsigned char *red, *green, *blue, *red_table, *green_table, *blue_table;
+ unsigned int width, height, *xtable, *ytable;
+
+ void TrueColorDither(unsigned int bit_depth, int bytes_per_line,
+ unsigned char *pixel_data);
+ void PseudoColorDither(int bytes_per_line, unsigned char *pixel_data);
+#ifdef ORDEREDPSEUDO
+ void OrderedPseudoColorDither(int bytes_per_line, unsigned char *pixel_data);
+#endif
+
+ Pixmap renderPixmap(void);
+
+ XImage *renderXImage(void);
+
+ void invert(void);
+ void bevel1(void);
+ void bevel2(void);
+ void dgradient(void);
+ void egradient(void);
+ void hgradient(void);
+ void pgradient(void);
+ void rgradient(void);
+ void vgradient(void);
+ void cdgradient(void);
+ void pcgradient(void);
+
+
+public:
+ BImage(BImageControl *c, unsigned int w, unsigned int h);
+ ~BImage(void);
+
+ Pixmap render(const BTexture &texture);
+ Pixmap render_solid(const BTexture &texture);
+ Pixmap render_gradient(const BTexture &texture);
+
+ // static methods for the builtin cache
+ static unsigned long maximumCacheSize(void);
+ static void setMaximumCacheSize(const unsigned long cache_max);
+
+ static unsigned long cacheTimeout(void);
+ static void setCacheTimeout(const unsigned long cache_timeout);
+
+private:
+ // global image cache
+ static BImageCache *imagecache;
+};
+
+
+class BImageControl : public TimeoutHandler {
+public:
+ struct CachedImage {
+ Pixmap pixmap;
+
+ unsigned int count, width, height;
+ unsigned long pixel1, pixel2, texture;
+ };
+
+ BImageControl(BaseDisplay *dpy, const ScreenInfo *scrn,
+ bool _dither= False, int _cpc = 4,
+ unsigned long cache_timeout = 300000l,
+ unsigned long cmax = 200l);
+ virtual ~BImageControl(void);
+
+ inline BaseDisplay *getBaseDisplay(void) const { return basedisplay; }
+
+ inline bool doDither(void) { return dither; }
+
+ inline const ScreenInfo *getScreenInfo(void) { return screeninfo; }
+
+ inline Window getDrawable(void) const { return window; }
+
+ inline Visual *getVisual(void) { return screeninfo->getVisual(); }
+
+ inline int getBitsPerPixel(void) const { return bits_per_pixel; }
+ inline int getDepth(void) const { return screen_depth; }
+ inline int getColorsPerChannel(void) const
+ { return colors_per_channel; }
+
+ unsigned long getSqrt(unsigned int x);
+
+ Pixmap renderImage(unsigned int width, unsigned int height,
+ const BTexture &texture);
+
+ void installRootColormap(void);
+ void removeImage(Pixmap pixmap);
+ void getColorTables(unsigned char **rmt, unsigned char **gmt,
+ unsigned char **bmt,
+ int *roff, int *goff, int *boff,
+ int *rbit, int *gbit, int *bbit);
+ void getXColorTable(XColor **c, int *n);
+ void getGradientBuffers(unsigned int w, unsigned int h,
+ unsigned int **xbuf, unsigned int **ybuf);
+ void setDither(bool d) { dither = d; }
+ void setColorsPerChannel(int cpc);
+
+ virtual void timeout(void);
+
+private:
+ bool dither;
+ BaseDisplay *basedisplay;
+ const ScreenInfo *screeninfo;
+#ifdef TIMEDCACHE
+ BTimer *timer;
+#endif // TIMEDCACHE
+
+ Colormap colormap;
+
+ Window window;
+ XColor *colors;
+ int colors_per_channel, ncolors, screen_number, screen_depth,
+ bits_per_pixel, red_offset, green_offset, blue_offset,
+ red_bits, green_bits, blue_bits;
+ unsigned char red_color_table[256], green_color_table[256],
+ blue_color_table[256];
+ unsigned int *grad_xbuffer, *grad_ybuffer, grad_buffer_width,
+ grad_buffer_height;
+ unsigned long *sqrt_table, cache_max;
+
+ typedef std::list<CachedImage> CacheContainer;
+ CacheContainer cache;
+
+ Pixmap searchCache(const unsigned int width, const unsigned int height,
+ const unsigned long texture,
+ const BColor &c1, const BColor &c2);
+};
+
+
+#endif // __Image_hh
+
--- /dev/null
+// -*- mode: C++; indent-tabs-mode: nil; -*-
+// ImageControl.cc for Blackbox - an X11 Window manager
+// Copyright (c) 2001 - 2002 Sean 'Shaleh' Perry <shaleh@debian.org>
+// Copyright (c) 1997 - 2000 Brad Hughes (bhughes@tcac.net)
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#ifdef HAVE_CONFIG_H
+# include "../config.h"
+#endif // HAVE_CONFIG_H
+
+extern "C" {
+#ifdef HAVE_STDIO_H
+# include <stdio.h>
+#endif // HAVE_STDIO_H
+
+#ifdef HAVE_CTYPE_H
+# include <ctype.h>
+#endif // HAVE_CTYPE_H
+
+#include <X11/Xlib.h>
+}
+
+#include <algorithm>
+
+#include "blackbox.hh"
+#include "i18n.hh"
+#include "BaseDisplay.hh"
+#include "Color.hh"
+#include "Image.hh"
+#include "Texture.hh"
+
+static unsigned long bsqrt(unsigned long x) {
+ if (x <= 0) return 0;
+ if (x == 1) return 1;
+
+ unsigned long r = x >> 1;
+ unsigned long q;
+
+ while (1) {
+ q = x / r;
+ if (q >= r) return r;
+ r = (r + q) >> 1;
+ }
+}
+
+BImageControl *ctrl = 0;
+
+BImageControl::BImageControl(BaseDisplay *dpy, const ScreenInfo *scrn,
+ bool _dither, int _cpc,
+ unsigned long cache_timeout,
+ unsigned long cmax)
+{
+ if (! ctrl) ctrl = this;
+
+ basedisplay = dpy;
+ screeninfo = scrn;
+ setDither(_dither);
+ setColorsPerChannel(_cpc);
+
+ cache_max = cmax;
+#ifdef TIMEDCACHE
+ if (cache_timeout) {
+ timer = new BTimer(basedisplay, this);
+ timer->setTimeout(cache_timeout);
+ timer->start();
+ } else {
+ timer = (BTimer *) 0;
+ }
+#endif // TIMEDCACHE
+
+ colors = (XColor *) 0;
+ ncolors = 0;
+
+ grad_xbuffer = grad_ybuffer = (unsigned int *) 0;
+ grad_buffer_width = grad_buffer_height = 0;
+
+ sqrt_table = (unsigned long *) 0;
+
+ screen_depth = screeninfo->getDepth();
+ window = screeninfo->getRootWindow();
+ screen_number = screeninfo->getScreenNumber();
+ colormap = screeninfo->getColormap();
+
+ int count;
+ XPixmapFormatValues *pmv = XListPixmapFormats(basedisplay->getXDisplay(),
+ &count);
+ if (pmv) {
+ bits_per_pixel = 0;
+ for (int i = 0; i < count; i++)
+ if (pmv[i].depth == screen_depth) {
+ bits_per_pixel = pmv[i].bits_per_pixel;
+ break;
+ }
+
+ XFree(pmv);
+ }
+
+ if (bits_per_pixel == 0) bits_per_pixel = screen_depth;
+ if (bits_per_pixel >= 24) setDither(False);
+
+ red_offset = green_offset = blue_offset = 0;
+
+ switch (getVisual()->c_class) {
+ case TrueColor: {
+ int i;
+
+ // compute color tables
+ unsigned long red_mask = getVisual()->red_mask,
+ green_mask = getVisual()->green_mask,
+ blue_mask = getVisual()->blue_mask;
+
+ while (! (red_mask & 1)) { red_offset++; red_mask >>= 1; }
+ while (! (green_mask & 1)) { green_offset++; green_mask >>= 1; }
+ while (! (blue_mask & 1)) { blue_offset++; blue_mask >>= 1; }
+
+ red_bits = 255 / red_mask;
+ green_bits = 255 / green_mask;
+ blue_bits = 255 / blue_mask;
+
+ for (i = 0; i < 256; i++) {
+ red_color_table[i] = i / red_bits;
+ green_color_table[i] = i / green_bits;
+ blue_color_table[i] = i / blue_bits;
+ }
+ break;
+ }
+
+ case PseudoColor:
+ case StaticColor: {
+ ncolors = colors_per_channel * colors_per_channel * colors_per_channel;
+
+ if (ncolors > (1 << screen_depth)) {
+ colors_per_channel = (1 << screen_depth) / 3;
+ ncolors = colors_per_channel * colors_per_channel * colors_per_channel;
+ }
+
+ if (colors_per_channel < 2 || ncolors > (1 << screen_depth)) {
+ fprintf(stderr,
+ i18n(ImageSet, ImageInvalidColormapSize,
+ "BImageControl::BImageControl: invalid colormap size %d "
+ "(%d/%d/%d) - reducing"),
+ ncolors, colors_per_channel, colors_per_channel,
+ colors_per_channel);
+
+ colors_per_channel = (1 << screen_depth) / 3;
+ }
+
+ colors = new XColor[ncolors];
+ if (! colors) {
+ fprintf(stderr, i18n(ImageSet, ImageErrorAllocatingColormap,
+ "BImageControl::BImageControl: error allocating "
+ "colormap\n"));
+ exit(1);
+ }
+
+ int i = 0, ii, p, r, g, b,
+
+#ifdef ORDEREDPSEUDO
+ bits = 256 / colors_per_channel;
+#else // !ORDEREDPSEUDO
+ bits = 255 / (colors_per_channel - 1);
+#endif // ORDEREDPSEUDO
+
+ red_bits = green_bits = blue_bits = bits;
+
+ for (i = 0; i < 256; i++)
+ red_color_table[i] = green_color_table[i] = blue_color_table[i] =
+ i / bits;
+
+ for (r = 0, i = 0; r < colors_per_channel; r++)
+ for (g = 0; g < colors_per_channel; g++)
+ for (b = 0; b < colors_per_channel; b++, i++) {
+ colors[i].red = (r * 0xffff) / (colors_per_channel - 1);
+ colors[i].green = (g * 0xffff) / (colors_per_channel - 1);
+ colors[i].blue = (b * 0xffff) / (colors_per_channel - 1);;
+ colors[i].flags = DoRed|DoGreen|DoBlue;
+ }
+
+ for (i = 0; i < ncolors; i++) {
+ if (! XAllocColor(basedisplay->getXDisplay(), colormap, &colors[i])) {
+ fprintf(stderr, i18n(ImageSet, ImageColorAllocFail,
+ "couldn't alloc color %i %i %i\n"),
+ colors[i].red, colors[i].green, colors[i].blue);
+ colors[i].flags = 0;
+ } else {
+ colors[i].flags = DoRed|DoGreen|DoBlue;
+ }
+ }
+
+ XColor icolors[256];
+ int incolors = (((1 << screen_depth) > 256) ? 256 : (1 << screen_depth));
+
+ for (i = 0; i < incolors; i++)
+ icolors[i].pixel = i;
+
+ XQueryColors(basedisplay->getXDisplay(), colormap, icolors, incolors);
+ for (i = 0; i < ncolors; i++) {
+ if (! colors[i].flags) {
+ unsigned long chk = 0xffffffff, pixel, close = 0;
+
+ p = 2;
+ while (p--) {
+ for (ii = 0; ii < incolors; ii++) {
+ r = (colors[i].red - icolors[i].red) >> 8;
+ g = (colors[i].green - icolors[i].green) >> 8;
+ b = (colors[i].blue - icolors[i].blue) >> 8;
+ pixel = (r * r) + (g * g) + (b * b);
+
+ if (pixel < chk) {
+ chk = pixel;
+ close = ii;
+ }
+
+ colors[i].red = icolors[close].red;
+ colors[i].green = icolors[close].green;
+ colors[i].blue = icolors[close].blue;
+
+ if (XAllocColor(basedisplay->getXDisplay(), colormap,
+ &colors[i])) {
+ colors[i].flags = DoRed|DoGreen|DoBlue;
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ break;
+ }
+
+ case GrayScale:
+ case StaticGray: {
+ if (getVisual()->c_class == StaticGray) {
+ ncolors = 1 << screen_depth;
+ } else {
+ ncolors = colors_per_channel * colors_per_channel * colors_per_channel;
+
+ if (ncolors > (1 << screen_depth)) {
+ colors_per_channel = (1 << screen_depth) / 3;
+ ncolors =
+ colors_per_channel * colors_per_channel * colors_per_channel;
+ }
+ }
+
+ if (colors_per_channel < 2 || ncolors > (1 << screen_depth)) {
+ fprintf(stderr,
+ i18n(ImageSet, ImageInvalidColormapSize,
+ "BImageControl::BImageControl: invalid colormap size %d "
+ "(%d/%d/%d) - reducing"),
+ ncolors, colors_per_channel, colors_per_channel,
+ colors_per_channel);
+
+ colors_per_channel = (1 << screen_depth) / 3;
+ }
+
+ colors = new XColor[ncolors];
+ if (! colors) {
+ fprintf(stderr,
+ i18n(ImageSet, ImageErrorAllocatingColormap,
+ "BImageControl::BImageControl: error allocating colormap\n"));
+ exit(1);
+ }
+
+ int i = 0, ii, p, bits = 255 / (colors_per_channel - 1);
+ red_bits = green_bits = blue_bits = bits;
+
+ for (i = 0; i < 256; i++)
+ red_color_table[i] = green_color_table[i] = blue_color_table[i] =
+ i / bits;
+
+ for (i = 0; i < ncolors; i++) {
+ colors[i].red = (i * 0xffff) / (colors_per_channel - 1);
+ colors[i].green = (i * 0xffff) / (colors_per_channel - 1);
+ colors[i].blue = (i * 0xffff) / (colors_per_channel - 1);;
+ colors[i].flags = DoRed|DoGreen|DoBlue;
+
+ if (! XAllocColor(basedisplay->getXDisplay(), colormap,
+ &colors[i])) {
+ fprintf(stderr, i18n(ImageSet, ImageColorAllocFail,
+ "couldn't alloc color %i %i %i\n"),
+ colors[i].red, colors[i].green, colors[i].blue);
+ colors[i].flags = 0;
+ } else {
+ colors[i].flags = DoRed|DoGreen|DoBlue;
+ }
+ }
+
+ XColor icolors[256];
+ int incolors = (((1 << screen_depth) > 256) ? 256 :
+ (1 << screen_depth));
+
+ for (i = 0; i < incolors; i++)
+ icolors[i].pixel = i;
+
+ XQueryColors(basedisplay->getXDisplay(), colormap, icolors, incolors);
+ for (i = 0; i < ncolors; i++) {
+ if (! colors[i].flags) {
+ unsigned long chk = 0xffffffff, pixel, close = 0;
+
+ p = 2;
+ while (p--) {
+ for (ii = 0; ii < incolors; ii++) {
+ int r = (colors[i].red - icolors[i].red) >> 8;
+ int g = (colors[i].green - icolors[i].green) >> 8;
+ int b = (colors[i].blue - icolors[i].blue) >> 8;
+ pixel = (r * r) + (g * g) + (b * b);
+
+ if (pixel < chk) {
+ chk = pixel;
+ close = ii;
+ }
+
+ colors[i].red = icolors[close].red;
+ colors[i].green = icolors[close].green;
+ colors[i].blue = icolors[close].blue;
+
+ if (XAllocColor(basedisplay->getXDisplay(), colormap,
+ &colors[i])) {
+ colors[i].flags = DoRed|DoGreen|DoBlue;
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ break;
+ }
+
+ default:
+ fprintf(stderr,
+ i18n(ImageSet, ImageUnsupVisual,
+ "BImageControl::BImageControl: unsupported visual %d\n"),
+ getVisual()->c_class);
+ exit(1);
+ }
+}
+
+
+BImageControl::~BImageControl(void) {
+ delete [] sqrt_table;
+
+ delete [] grad_xbuffer;
+
+ delete [] grad_ybuffer;
+
+ if (colors) {
+ unsigned long *pixels = new unsigned long [ncolors];
+
+ int i;
+ for (i = 0; i < ncolors; i++)
+ *(pixels + i) = (*(colors + i)).pixel;
+
+ XFreeColors(basedisplay->getXDisplay(), colormap, pixels, ncolors, 0);
+
+ delete [] colors;
+ }
+
+ if (!cache.empty()) {
+ //#ifdef DEBUG
+ fprintf(stderr, i18n(ImageSet, ImagePixmapRelease,
+ "BImageContol::~BImageControl: pixmap cache - "
+ "releasing %d pixmaps\n"), cache.size());
+ //#endif
+ CacheContainer::iterator it = cache.begin();
+ const CacheContainer::iterator end = cache.end();
+ for (; it != end; ++it) {
+ XFreePixmap(basedisplay->getXDisplay(), (*it).pixmap);
+ }
+ }
+#ifdef TIMEDCACHE
+ if (timer) {
+ timer->stop();
+ delete timer;
+ }
+#endif // TIMEDCACHE
+}
+
+
+Pixmap BImageControl::searchCache(const unsigned int width,
+ const unsigned int height,
+ const unsigned long texture,
+ const BColor &c1, const BColor &c2) {
+ if (cache.empty())
+ return None;
+
+ CacheContainer::iterator it = cache.begin();
+ const CacheContainer::iterator end = cache.end();
+ for (; it != end; ++it) {
+ CachedImage& tmp = *it;
+ if ((tmp.width == width) && (tmp.height == height) &&
+ (tmp.texture == texture) && (tmp.pixel1 == c1.pixel()))
+ if (texture & BTexture::Gradient) {
+ if (tmp.pixel2 == c2.pixel()) {
+ tmp.count++;
+ return tmp.pixmap;
+ }
+ } else {
+ tmp.count++;
+ return tmp.pixmap;
+ }
+ }
+ return None;
+}
+
+
+Pixmap BImageControl::renderImage(unsigned int width, unsigned int height,
+ const BTexture &texture) {
+ if (texture.texture() & BTexture::Parent_Relative) return ParentRelative;
+
+ Pixmap pixmap = searchCache(width, height, texture.texture(),
+ texture.color(), texture.colorTo());
+ if (pixmap) return pixmap;
+
+ BImage image(this, width, height);
+ pixmap = image.render(texture);
+
+ if (!pixmap)
+ return None;
+
+ CachedImage tmp;
+
+ tmp.pixmap = pixmap;
+ tmp.width = width;
+ tmp.height = height;
+ tmp.count = 1;
+ tmp.texture = texture.texture();
+ tmp.pixel1 = texture.color().pixel();
+
+ if (texture.texture() & BTexture::Gradient)
+ tmp.pixel2 = texture.colorTo().pixel();
+ else
+ tmp.pixel2 = 0l;
+
+ cache.push_back(tmp);
+
+ if (cache.size() > cache_max) {
+#ifdef DEBUG
+ fprintf(stderr, i18n(ImageSet, ImagePixmapCacheLarge,
+ "BImageControl::renderImage: cache is large, "
+ "forcing cleanout\n"));
+#endif // DEBUG
+
+ timeout();
+ }
+
+ return pixmap;
+}
+
+
+void BImageControl::removeImage(Pixmap pixmap) {
+ if (!pixmap)
+ return;
+
+ CacheContainer::iterator it = cache.begin();
+ const CacheContainer::iterator end = cache.end();
+ for (; it != end; ++it) {
+ CachedImage &tmp = *it;
+ if (tmp.pixmap == pixmap && tmp.count > 0)
+ tmp.count--;
+ }
+
+#ifdef TIMEDCACHE
+ if (! timer)
+#endif // TIMEDCACHE
+ timeout();
+}
+
+
+void BImageControl::getColorTables(unsigned char **rmt, unsigned char **gmt,
+ unsigned char **bmt,
+ int *roff, int *goff, int *boff,
+ int *rbit, int *gbit, int *bbit) {
+ if (rmt) *rmt = red_color_table;
+ if (gmt) *gmt = green_color_table;
+ if (bmt) *bmt = blue_color_table;
+
+ if (roff) *roff = red_offset;
+ if (goff) *goff = green_offset;
+ if (boff) *boff = blue_offset;
+
+ if (rbit) *rbit = red_bits;
+ if (gbit) *gbit = green_bits;
+ if (bbit) *bbit = blue_bits;
+}
+
+
+void BImageControl::getXColorTable(XColor **c, int *n) {
+ if (c) *c = colors;
+ if (n) *n = ncolors;
+}
+
+
+void BImageControl::getGradientBuffers(unsigned int w,
+ unsigned int h,
+ unsigned int **xbuf,
+ unsigned int **ybuf)
+{
+ if (w > grad_buffer_width) {
+ if (grad_xbuffer) {
+ delete [] grad_xbuffer;
+ }
+
+ grad_buffer_width = w;
+
+ grad_xbuffer = new unsigned int[grad_buffer_width * 3];
+ }
+
+ if (h > grad_buffer_height) {
+ if (grad_ybuffer) {
+ delete [] grad_ybuffer;
+ }
+
+ grad_buffer_height = h;
+
+ grad_ybuffer = new unsigned int[grad_buffer_height * 3];
+ }
+
+ *xbuf = grad_xbuffer;
+ *ybuf = grad_ybuffer;
+}
+
+
+void BImageControl::installRootColormap(void) {
+ int ncmap = 0;
+ Colormap *cmaps =
+ XListInstalledColormaps(basedisplay->getXDisplay(), window, &ncmap);
+
+ if (cmaps) {
+ bool install = True;
+ for (int i = 0; i < ncmap; i++)
+ if (*(cmaps + i) == colormap)
+ install = False;
+
+ if (install)
+ XInstallColormap(basedisplay->getXDisplay(), colormap);
+
+ XFree(cmaps);
+ }
+}
+
+
+void BImageControl::setColorsPerChannel(int cpc) {
+ if (cpc < 2) cpc = 2;
+ if (cpc > 6) cpc = 6;
+
+ colors_per_channel = cpc;
+}
+
+
+unsigned long BImageControl::getSqrt(unsigned int x) {
+ if (! sqrt_table) {
+ // build sqrt table for use with elliptic gradient
+
+ sqrt_table = new unsigned long[(256 * 256 * 2) + 1];
+
+ for (int i = 0; i < (256 * 256 * 2); i++)
+ *(sqrt_table + i) = bsqrt(i);
+ }
+
+ return (*(sqrt_table + x));
+}
+
+
+struct ZeroRefCheck {
+ inline bool operator()(const BImageControl::CachedImage &image) const {
+ return (image.count == 0);
+ }
+};
+
+struct CacheCleaner {
+ Display *display;
+ ZeroRefCheck ref_check;
+ CacheCleaner(Display *d): display(d) {}
+ inline void operator()(const BImageControl::CachedImage& image) const {
+ if (ref_check(image))
+ XFreePixmap(display, image.pixmap);
+ }
+};
+
+
+void BImageControl::timeout(void) {
+ CacheCleaner cleaner(basedisplay->getXDisplay());
+ std::for_each(cache.begin(), cache.end(), cleaner);
+ cache.remove_if(cleaner.ref_check);
+}
+
-# src/Makefile.am for Openbox
+# src/Makefile.am for Blackbox - an X11 Window manager
# Copyright (c) 1997 - 2000 Brad Hughes (bhughes@tcac.net)
#
# Permission is hereby granted, free of charge, to any person obtaining a
# DEALINGS IN THE SOFTWARE.
DEFAULT_MENU=$(pkgdatadir)/menu
-DEFAULT_STYLE=$(pkgdatadir)/styles/steelblue
+DEFAULT_STYLE=$(pkgdatadir)/styles/Results
-CPPFLAGS= @CPPFLAGS@ @SHAPE@ @SLIT@ @INTERLACE@ @ORDEREDPSEUDO@ \
-@DEBUG@ @NEWWMSPEC@ @NLS@ @TIMEDCACHE@ @CLOBBER@ \
+CPPFLAGS= @CPPFLAGS@ @SHAPE@ @ORDEREDPSEUDO@ \
+@DEBUG@ @NLS@ @TIMEDCACHE@ @SLIT@ @CLOBBER@ \
-DLOCALEPATH=\"$(pkgdatadir)/nls\" \
-DDEFAULTMENU=\"$(DEFAULT_MENU)\" \
-DDEFAULTSTYLE=\"$(DEFAULT_STYLE)\"
-bin_PROGRAMS= openbox
+bin_PROGRAMS= blackbox
-openbox_SOURCES= BaseDisplay.cc Basemenu.cc Clientmenu.cc Configmenu.cc Geometry.cc Iconmenu.cc Image.cc Netizen.cc Resource.cc Rootmenu.cc Screen.cc Slit.cc Timer.cc Toolbar.cc Window.cc Windowmenu.cc Workspace.cc Workspacemenu.cc XAtom.cc openbox.cc bsd-snprintf.c i18n.cc main.cc
+blackbox_SOURCES= BaseDisplay.cc Basemenu.cc Clientmenu.cc Color.cc Configmenu.cc GCCache.cc Iconmenu.cc Image.cc ImageControl.cc Netizen.cc Rootmenu.cc Screen.cc Slit.cc Texture.cc Timer.cc Toolbar.cc Util.cc Window.cc Windowmenu.cc Workspace.cc Workspacemenu.cc blackbox.cc i18n.cc main.cc
MAINTAINERCLEANFILES= Makefile.in
# local dependencies
-BaseDisplay.o: BaseDisplay.cc i18n.h BaseDisplay.h \
- Timer.h
-Basemenu.o: Basemenu.cc i18n.h openbox.h BaseDisplay.h \
- Timer.h Image.h Iconmenu.h Basemenu.h \
- Windowmenu.h Slit.h Screen.h Configmenu.h Netizen.h Rootmenu.h \
- Workspace.h Workspacemenu.h Resource.h
-Clientmenu.o: Clientmenu.cc openbox.h BaseDisplay.h \
- Timer.h Image.h Window.h Iconmenu.h Basemenu.h Windowmenu.h Slit.h \
- Clientmenu.h Workspace.h Screen.h Configmenu.h Netizen.h \
- Rootmenu.h Workspacemenu.h Resource.h Geometry.h
-Configmenu.o: Configmenu.cc i18n.h Configmenu.h Basemenu.h \
- Screen.h BaseDisplay.h Timer.h Iconmenu.h Netizen.h \
- Rootmenu.h Workspace.h Workspacemenu.h openbox.h Image.h \
- Window.h Windowmenu.h Slit.h Toolbar.h Resource.h Geometry.h
-Geometry.o: Geometry.cc Geometry.h
-Icon.o: Iconmenu.cc i18n.h openbox.h BaseDisplay.h \
- Timer.h Image.h Window.h Iconmenu.h Basemenu.h Windowmenu.h Slit.h \
- Screen.h Configmenu.h Netizen.h Rootmenu.h Workspace.h \
- Workspacemenu.h Toolbar.h Resource.h Geometry.h
-Image.o: Image.cc i18n.h BaseDisplay.h Timer.h \
- Image.h
-Netizen.o: Netizen.cc Netizen.h BaseDisplay.h Timer.h \
- Screen.h Configmenu.h Basemenu.h openbox.h Image.h Window.h \
- Iconmenu.h Windowmenu.h Slit.h Rootmenu.h Workspace.h \
- Workspacemenu.h Resource.h Geometry.h
-Resource.o: Resource.cc Resource.h Util.h
-Rootmenu.o: Rootmenu.cc openbox.h BaseDisplay.h \
- Timer.h Image.h Window.h Iconmenu.h Basemenu.h Windowmenu.h Slit.h \
- Rootmenu.h Screen.h Configmenu.h Netizen.h Workspace.h \
- Workspacemenu.h Resource.h Geometry.h
-Screen.o: Screen.cc i18n.h bsd-snprintf.h openbox.h BaseDisplay.h \
- Timer.h Image.h Window.h Iconmenu.h Basemenu.h \
- Windowmenu.h Slit.h Clientmenu.h Workspace.h Screen.h Configmenu.h \
- Netizen.h Rootmenu.h Workspacemenu.h Toolbar.h Resource.h Geometry.h
-Slit.o: Slit.cc i18n.h openbox.h BaseDisplay.h \
- Timer.h Image.h Window.h Iconmenu.h Basemenu.h Windowmenu.h Slit.h \
- Screen.h Configmenu.h Netizen.h Rootmenu.h Workspace.h \
- Workspacemenu.h Toolbar.h Resource.h Geometry.h
-Timer.o: Timer.cc BaseDisplay.h Timer.h
-Toolbar.o: Toolbar.cc i18n.h openbox.h BaseDisplay.h \
- Timer.h Image.h Window.h Iconmenu.h Basemenu.h Windowmenu.h Slit.h \
- Clientmenu.h Workspace.h Rootmenu.h Screen.h Configmenu.h \
- Netizen.h Workspacemenu.h Toolbar.h Resource.h Geometry.h
-XAtom.o: XAtom.cc XAtom.h Geometry.h Util.h
-Window.o: Window.cc i18n.h openbox.h BaseDisplay.h \
- Timer.h Image.h Window.h Iconmenu.h Basemenu.h Windowmenu.h Slit.h \
- Screen.h Configmenu.h Netizen.h Rootmenu.h Workspace.h \
- Workspacemenu.h Toolbar.h Resource.h Geometry.h
-Windowmenu.o: Windowmenu.cc i18n.h openbox.h BaseDisplay.h \
- Timer.h Image.h Window.h Iconmenu.h Basemenu.h \
- Windowmenu.h Slit.h Screen.h Configmenu.h Netizen.h Rootmenu.h \
- Workspace.h Workspacemenu.h Resource.h Geometry.h
-Workspace.o: Workspace.cc i18n.h openbox.h BaseDisplay.h \
- Timer.h Image.h Window.h Iconmenu.h Basemenu.h \
- Windowmenu.h Slit.h Clientmenu.h Workspace.h Screen.h \
- Configmenu.h Netizen.h Rootmenu.h Workspacemenu.h Toolbar.h Resource.h \
- Geometry.h Geometry.h Util.h
-Workspacemenu.o: Workspacemenu.cc i18n.h openbox.h BaseDisplay.h \
- Timer.h Image.h Window.h Iconmenu.h Basemenu.h \
- Windowmenu.h Slit.h Screen.h Configmenu.h Netizen.h Rootmenu.h \
- Workspace.h Workspacemenu.h Toolbar.h Resource.h Geometry.h
-openbox.o: openbox.cc i18n.h openbox.h BaseDisplay.h \
- Timer.h Image.h Window.h Iconmenu.h Basemenu.h \
- Windowmenu.h Slit.h Clientmenu.h Workspace.h Rootmenu.h \
- Screen.h Configmenu.h Netizen.h Workspacemenu.h Toolbar.h Resource.h \
- Geometry.h Util.h
-bsd-snprintf.o: bsd-snprintf.c bsd-snprintf.h
-i18n.o: i18n.cc i18n.h
-main.o: main.cc ../version.h i18n.h openbox.h BaseDisplay.h \
- Timer.h Image.h Window.h Iconmenu.h Basemenu.h \
- Windowmenu.h Slit.h Resource.h Geometry.h
+BaseDisplay.o: BaseDisplay.cc ../config.h i18n.hh \
+ ../nls/blackbox-nls.hh BaseDisplay.hh Timer.hh GCCache.hh Color.hh \
+ Util.hh
+Basemenu.o: Basemenu.cc ../config.h i18n.hh ../nls/blackbox-nls.hh \
+ blackbox.hh BaseDisplay.hh Timer.hh Basemenu.hh GCCache.hh Color.hh \
+ Image.hh Screen.hh Texture.hh Util.hh Configmenu.hh Iconmenu.hh \
+ Netizen.hh Rootmenu.hh Workspace.hh Workspacemenu.hh
+Clientmenu.o: Clientmenu.cc ../config.h blackbox.hh i18n.hh \
+ ../nls/blackbox-nls.hh BaseDisplay.hh Timer.hh Clientmenu.hh \
+ Basemenu.hh Screen.hh Color.hh Texture.hh Util.hh Configmenu.hh \
+ Iconmenu.hh Netizen.hh Rootmenu.hh Workspace.hh Workspacemenu.hh \
+ Window.hh Windowmenu.hh
+Color.o: Color.cc ../config.h Color.hh BaseDisplay.hh Timer.hh
+Configmenu.o: Configmenu.cc ../config.h i18n.hh ../nls/blackbox-nls.hh \
+ Configmenu.hh Basemenu.hh Image.hh Timer.hh BaseDisplay.hh Color.hh \
+ Toolbar.hh Screen.hh Texture.hh Util.hh Iconmenu.hh Netizen.hh \
+ Rootmenu.hh Workspace.hh Workspacemenu.hh blackbox.hh Window.hh \
+ Windowmenu.hh
+GCCache.o: GCCache.cc ../config.h GCCache.hh BaseDisplay.hh Timer.hh \
+ Color.hh Util.hh
+Iconmenu.o: Iconmenu.cc ../config.h i18n.hh ../nls/blackbox-nls.hh \
+ Iconmenu.hh Basemenu.hh Screen.hh Color.hh Texture.hh Util.hh \
+ Configmenu.hh Netizen.hh Rootmenu.hh Timer.hh Workspace.hh \
+ Workspacemenu.hh blackbox.hh BaseDisplay.hh Window.hh Windowmenu.hh
+Image.o: Image.cc ../config.h blackbox.hh i18n.hh \
+ ../nls/blackbox-nls.hh BaseDisplay.hh Timer.hh GCCache.hh Color.hh \
+ Image.hh Texture.hh Util.hh
+ImageControl.o: ImageControl.cc ../config.h blackbox.hh i18n.hh \
+ ../nls/blackbox-nls.hh BaseDisplay.hh Timer.hh Color.hh Image.hh \
+ Texture.hh Util.hh
+Netizen.o: Netizen.cc ../config.h Netizen.hh Screen.hh Color.hh \
+ Texture.hh Util.hh Configmenu.hh Basemenu.hh Iconmenu.hh Rootmenu.hh \
+ Timer.hh Workspace.hh Workspacemenu.hh blackbox.hh i18n.hh \
+ ../nls/blackbox-nls.hh BaseDisplay.hh
+Rootmenu.o: Rootmenu.cc ../config.h blackbox.hh i18n.hh \
+ ../nls/blackbox-nls.hh BaseDisplay.hh Timer.hh Rootmenu.hh \
+ Basemenu.hh Screen.hh Color.hh Texture.hh Util.hh Configmenu.hh \
+ Iconmenu.hh Netizen.hh Workspace.hh Workspacemenu.hh
+Screen.o: Screen.cc ../config.h i18n.hh ../nls/blackbox-nls.hh \
+ blackbox.hh BaseDisplay.hh Timer.hh Clientmenu.hh Basemenu.hh \
+ GCCache.hh Color.hh Iconmenu.hh Image.hh Screen.hh Texture.hh Util.hh \
+ Configmenu.hh Netizen.hh Rootmenu.hh Workspace.hh Workspacemenu.hh \
+ Slit.hh Toolbar.hh Window.hh Windowmenu.hh
+Slit.o: Slit.cc ../config.h i18n.hh ../nls/blackbox-nls.hh blackbox.hh \
+ BaseDisplay.hh Timer.hh Image.hh Color.hh Screen.hh Texture.hh \
+ Util.hh Configmenu.hh Basemenu.hh Iconmenu.hh Netizen.hh Rootmenu.hh \
+ Workspace.hh Workspacemenu.hh Slit.hh Toolbar.hh
+Texture.o: Texture.cc ../config.h Texture.hh Color.hh Util.hh \
+ BaseDisplay.hh Timer.hh Image.hh Screen.hh Configmenu.hh Basemenu.hh \
+ Iconmenu.hh Netizen.hh Rootmenu.hh Workspace.hh Workspacemenu.hh \
+ blackbox.hh i18n.hh ../nls/blackbox-nls.hh
+Timer.o: Timer.cc ../config.h BaseDisplay.hh Timer.hh Util.hh
+Toolbar.o: Toolbar.cc ../config.h i18n.hh ../nls/blackbox-nls.hh \
+ blackbox.hh BaseDisplay.hh Timer.hh Clientmenu.hh Basemenu.hh \
+ GCCache.hh Color.hh Iconmenu.hh Image.hh Rootmenu.hh Screen.hh \
+ Texture.hh Util.hh Configmenu.hh Netizen.hh Workspace.hh \
+ Workspacemenu.hh Toolbar.hh Window.hh Windowmenu.hh Slit.hh
+Util.o: Util.cc ../config.h Util.hh
+Window.o: Window.cc ../config.h i18n.hh ../nls/blackbox-nls.hh \
+ blackbox.hh BaseDisplay.hh Timer.hh GCCache.hh Color.hh Iconmenu.hh \
+ Basemenu.hh Image.hh Screen.hh Texture.hh Util.hh Configmenu.hh \
+ Netizen.hh Rootmenu.hh Workspace.hh Workspacemenu.hh Toolbar.hh \
+ Window.hh Windowmenu.hh Slit.hh
+Windowmenu.o: Windowmenu.cc ../config.h i18n.hh ../nls/blackbox-nls.hh \
+ blackbox.hh BaseDisplay.hh Timer.hh Screen.hh Color.hh Texture.hh \
+ Util.hh Configmenu.hh Basemenu.hh Iconmenu.hh Netizen.hh Rootmenu.hh \
+ Workspace.hh Workspacemenu.hh Window.hh Windowmenu.hh
+Workspace.o: Workspace.cc ../config.h i18n.hh ../nls/blackbox-nls.hh \
+ blackbox.hh BaseDisplay.hh Timer.hh Clientmenu.hh Basemenu.hh \
+ Netizen.hh Screen.hh Color.hh Texture.hh Util.hh Configmenu.hh \
+ Iconmenu.hh Rootmenu.hh Workspace.hh Workspacemenu.hh Toolbar.hh \
+ Window.hh Windowmenu.hh
+Workspacemenu.o: Workspacemenu.cc ../config.h i18n.hh \
+ ../nls/blackbox-nls.hh blackbox.hh BaseDisplay.hh Timer.hh Screen.hh \
+ Color.hh Texture.hh Util.hh Configmenu.hh Basemenu.hh Iconmenu.hh \
+ Netizen.hh Rootmenu.hh Workspace.hh Workspacemenu.hh Toolbar.hh
+blackbox.o: blackbox.cc ../config.h i18n.hh ../nls/blackbox-nls.hh \
+ blackbox.hh BaseDisplay.hh Timer.hh Basemenu.hh Clientmenu.hh \
+ GCCache.hh Color.hh Image.hh Rootmenu.hh Screen.hh Texture.hh Util.hh \
+ Configmenu.hh Iconmenu.hh Netizen.hh Workspace.hh Workspacemenu.hh \
+ Slit.hh Toolbar.hh Window.hh Windowmenu.hh
+i18n.o: i18n.cc ../config.h i18n.hh ../nls/blackbox-nls.hh
+main.o: main.cc ../version.h ../config.h i18n.hh \
+ ../nls/blackbox-nls.hh blackbox.hh BaseDisplay.hh Timer.hh
-// Netizen.cc for Openbox
+// -*- mode: C++; indent-tabs-mode: nil; -*-
+// Netizen.cc for Blackbox - An X11 Window Manager
// Copyright (c) 2001 Sean 'Shaleh' Perry <shaleh@debian.org>
// Copyright (c) 1997 - 2000 Brad Hughes (bhughes@tcac.net)
//
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
-// stupid macros needed to access some functions in version 2 of the GNU C
-// library
-#ifndef _GNU_SOURCE
-#define _GNU_SOURCE
-#endif // _GNU_SOURCE
-
#ifdef HAVE_CONFIG_H
#include "../config.h"
#endif // HAVE_CONFIG_H
-#include "Netizen.h"
-#include "Screen.h"
+#include "Netizen.hh"
+#include "Screen.hh"
+
+Netizen::Netizen(BScreen *scr, Window win) {
+ screen = scr;
+ blackbox = scr->getBlackbox();
+ window = win;
-Netizen::Netizen(BScreen &scr, Window win) :basedisplay(scr.getBaseDisplay()),
- screen(scr), window(win)
-{
event.type = ClientMessage;
- event.xclient.message_type = basedisplay.getOpenboxStructureMessagesAtom();
- event.xclient.display = basedisplay.getXDisplay();
+ event.xclient.message_type =
+ blackbox->getBlackboxStructureMessagesAtom();
+ event.xclient.display = blackbox->getXDisplay();
event.xclient.window = window;
event.xclient.format = 32;
- event.xclient.data.l[0] = basedisplay.getOpenboxNotifyStartupAtom();
+ event.xclient.data.l[0] = blackbox->getBlackboxNotifyStartupAtom();
event.xclient.data.l[1] = event.xclient.data.l[2] =
event.xclient.data.l[3] = event.xclient.data.l[4] = 0l;
- XSendEvent(basedisplay.getXDisplay(), window, False, NoEventMask, &event);
+ XSendEvent(blackbox->getXDisplay(), window, False, NoEventMask, &event);
}
void Netizen::sendWorkspaceCount(void) {
- event.xclient.data.l[0] = basedisplay.getOpenboxNotifyWorkspaceCountAtom();
- event.xclient.data.l[1] = screen.getWorkspaceCount();
+ event.xclient.data.l[0] =
+ blackbox->getBlackboxNotifyWorkspaceCountAtom();
+ event.xclient.data.l[1] = screen->getWorkspaceCount();
- XSendEvent(basedisplay.getXDisplay(), window, False, NoEventMask, &event);
+ XSendEvent(blackbox->getXDisplay(), window, False, NoEventMask, &event);
}
void Netizen::sendCurrentWorkspace(void) {
- event.xclient.data.l[0] = basedisplay.getOpenboxNotifyCurrentWorkspaceAtom();
- event.xclient.data.l[1] = screen.getCurrentWorkspaceID();
+ event.xclient.data.l[0] =
+ blackbox->getBlackboxNotifyCurrentWorkspaceAtom();
+ event.xclient.data.l[1] = screen->getCurrentWorkspaceID();
- XSendEvent(basedisplay.getXDisplay(), window, False, NoEventMask, &event);
+ XSendEvent(blackbox->getXDisplay(), window, False, NoEventMask, &event);
}
void Netizen::sendWindowFocus(Window w) {
- event.xclient.data.l[0] = basedisplay.getOpenboxNotifyWindowFocusAtom();
+ event.xclient.data.l[0] = blackbox->getBlackboxNotifyWindowFocusAtom();
event.xclient.data.l[1] = w;
- XSendEvent(basedisplay.getXDisplay(), window, False, NoEventMask, &event);
+ XSendEvent(blackbox->getXDisplay(), window, False, NoEventMask, &event);
}
void Netizen::sendWindowAdd(Window w, unsigned long p) {
- event.xclient.data.l[0] = basedisplay.getOpenboxNotifyWindowAddAtom();
+ event.xclient.data.l[0] = blackbox->getBlackboxNotifyWindowAddAtom();
event.xclient.data.l[1] = w;
event.xclient.data.l[2] = p;
- XSendEvent(basedisplay.getXDisplay(), window, False, NoEventMask, &event);
+ XSendEvent(blackbox->getXDisplay(), window, False, NoEventMask, &event);
event.xclient.data.l[2] = 0l;
}
void Netizen::sendWindowDel(Window w) {
- event.xclient.data.l[0] = basedisplay.getOpenboxNotifyWindowDelAtom();
+ event.xclient.data.l[0] = blackbox->getBlackboxNotifyWindowDelAtom();
event.xclient.data.l[1] = w;
- XSendEvent(basedisplay.getXDisplay(), window, False, NoEventMask, &event);
+ XSendEvent(blackbox->getXDisplay(), window, False, NoEventMask, &event);
}
void Netizen::sendWindowRaise(Window w) {
- event.xclient.data.l[0] = basedisplay.getOpenboxNotifyWindowRaiseAtom();
+ event.xclient.data.l[0] = blackbox->getBlackboxNotifyWindowRaiseAtom();
event.xclient.data.l[1] = w;
- XSendEvent(basedisplay.getXDisplay(), window, False, NoEventMask, &event);
+ XSendEvent(blackbox->getXDisplay(), window, False, NoEventMask, &event);
}
void Netizen::sendWindowLower(Window w) {
- event.xclient.data.l[0] = basedisplay.getOpenboxNotifyWindowLowerAtom();
+ event.xclient.data.l[0] = blackbox->getBlackboxNotifyWindowLowerAtom();
event.xclient.data.l[1] = w;
- XSendEvent(basedisplay.getXDisplay(), window, False, NoEventMask, &event);
+ XSendEvent(blackbox->getXDisplay(), window, False, NoEventMask, &event);
}
void Netizen::sendConfigNotify(XEvent *e) {
- XSendEvent(basedisplay.getXDisplay(), window, False,
+ XSendEvent(blackbox->getXDisplay(), window, False,
StructureNotifyMask, e);
}
-// Netizen.h for Openbox
+// -*- mode: C++; indent-tabs-mode: nil; -*-
+// Netizen.hh for Blackbox - An X11 Window Manager
// Copyright (c) 2001 Sean 'Shaleh' Perry <shaleh@debian.org>
// Copyright (c) 1997 - 2000 Brad Hughes (bhughes@tcac.net)
//
#ifndef __Netizen_hh
#define __Netizen_hh
+extern "C" {
#include <X11/Xlib.h>
+}
// forward declaration
-class BaseDisplay;
+class Blackbox;
class BScreen;
class Netizen;
class Netizen {
private:
- BaseDisplay &basedisplay;
- BScreen &screen;
+ Blackbox *blackbox;
+ BScreen *screen;
Window window;
XEvent event;
-protected:
-
public:
- Netizen(BScreen &, Window);
+ Netizen(BScreen *, Window);
- inline const Window &getWindowID(void) const { return window; }
+ inline Window getWindowID(void) const { return window; }
void sendWorkspaceCount(void);
void sendCurrentWorkspace(void);
+++ /dev/null
-// Resource.cc for Openbox
-// Copyright (c) 2002 - 2002 Ben Jansens (ben@orodu.net)
-//
-// Permission is hereby granted, free of charge, to any person obtaining a
-// copy of this software and associated documentation files (the "Software"),
-// to deal in the Software without restriction, including without limitation
-// the rights to use, copy, modify, merge, publish, distribute, sublicense,
-// and/or sell copies of the Software, and to permit persons to whom the
-// Software is furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-// DEALINGS IN THE SOFTWARE.
-
-#include "Resource.h"
-#include "Util.h"
-
-#ifdef HAVE_CONFIG_H
-# include "../config.h"
-#endif // HAVE_CONFIG_H
-
-#ifdef HAVE_STDLIB_H
-# include <stdlib.h>
-#endif // HAVE_STDLIB_H
-
-#ifdef HAVE_STDIO_H
-# include <stdio.h>
-#endif // HAVE_STDIO_H
-
-bool Resource::m_initialized = false;
-
-Resource::Resource(const std::string &file) {
- setFile(file);
- m_modified = false;
- m_database = NULL;
- m_autosave = true;
- if (!m_initialized) {
- XrmInitialize();
- m_initialized = true;
- }
-}
-
-Resource::Resource() {
- m_modified = false;
- m_database = NULL;
- m_autosave = true;
- if (!m_initialized) {
- XrmInitialize();
- m_initialized = true;
- }
-}
-
-Resource::~Resource() {
- if (m_database != NULL)
- XrmDestroyDatabase(m_database);
-}
-
-void Resource::setFile(const std::string &file) {
- m_file = file;
-}
-
-void Resource::setAutoSave(bool autosave) {
- m_autosave = autosave;
-}
-
-void Resource::save() {
- ASSERT(m_database != NULL);
- XrmPutFileDatabase(m_database, m_file.c_str());
- m_modified = false;
-}
-
-bool Resource::load() {
- if (m_database != NULL)
- XrmDestroyDatabase(m_database);
- m_modified = false;
- if (NULL == (m_database = XrmGetFileDatabase(m_file.c_str())))
- return false;
- return true;
-}
-
-void Resource::create() {
- if (m_database != NULL)
- XrmDestroyDatabase(m_database);
- m_modified = false;
- ASSERT(NULL != (m_database = XrmGetStringDatabase("")));
-}
-
-void Resource::setValue(const std::string &rname, bool value) {
- ASSERT(m_database != NULL);
-
- const char *val = (value ? "True" : "False");
- std::string rc_string = rname + ": " + val;
- XrmPutLineResource(&m_database, rc_string.c_str());
-
- m_modified = true;
- if (m_autosave)
- save();
-}
-
-void Resource::setValue(const std::string &rname, int value) {
- setValue(rname, (long)value);
-}
-
-void Resource::setValue(const std::string &rname, long value) {
- ASSERT(m_database != NULL);
-
- char val[11];
- sprintf(val, "%ld", value);
- std::string rc_string = rname + ": " + val;
- XrmPutLineResource(&m_database, rc_string.c_str());
-
- m_modified = true;
- if (m_autosave)
- save();
-}
-
-void Resource::setValue(const std::string &rname, const char *value) {
- ASSERT(m_database != NULL);
- ASSERT(value != NULL);
-
- std::string rc_string = rname + ": " + value;
- XrmPutLineResource(&m_database, rc_string.c_str());
-
- m_modified = true;
- if (m_autosave)
- save();
-}
-
-void Resource::setValue(const std::string &rname, const std::string &value) {
- ASSERT(m_database != NULL);
-
- std::string rc_string = rname + ": " + value;
- XrmPutLineResource(&m_database, rc_string.c_str());
-
- m_modified = true;
- if (m_autosave)
- save();
-}
-
-bool Resource::getValue(const std::string &rname, const std::string &rclass,
- bool &value) const {
- ASSERT(rclass.c_str() != NULL);
- ASSERT(m_database != NULL);
-
- char *rettype;
- XrmValue retvalue;
- if (0 == XrmGetResource(m_database, rname.c_str(), rclass.c_str(),
- &rettype, &retvalue) || retvalue.addr == NULL)
- return false;
- std::string val = retvalue.addr;
- if (0 == strncasecmp(val.c_str(), "true", val.length()))
- value = true;
- else
- value = false;
- return true;
-}
-
-bool Resource::getValue(const std::string &rname, const std::string &rclass,
- long &value) const {
- ASSERT(m_database != NULL);
-
- char *rettype;
- XrmValue retvalue;
- if (0 == XrmGetResource(m_database, rname.c_str(), rclass.c_str(),
- &rettype, &retvalue) || retvalue.addr == NULL)
- return false;
- char *end;
- value = strtol(retvalue.addr, &end, 10);
- if (end == retvalue.addr)
- return false;
- return true;
-}
-
-bool Resource::getValue(const std::string &rname, const std::string &rclass,
- std::string &value) const {
- ASSERT(m_database != NULL);
-
- char *rettype;
- XrmValue retvalue;
- if (0 == XrmGetResource(m_database, rname.c_str(), rclass.c_str(),
- &rettype, &retvalue) || retvalue.addr == NULL)
- return false;
- value = retvalue.addr;
- return true;
-}
+++ /dev/null
-// Resource.h for Openbox
-// Copyright (c) 2002 - 2002 Ben Jansens (ben@orodu.net)
-//
-// Permission is hereby granted, free of charge, to any person obtaining a
-// copy of this software and associated documentation files (the "Software"),
-// to deal in the Software without restriction, including without limitation
-// the rights to use, copy, modify, merge, publish, distribute, sublicense,
-// and/or sell copies of the Software, and to permit persons to whom the
-// Software is furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-// DEALINGS IN THE SOFTWARE.
-
-#ifndef __Resource_hh
-#define __Resource_hh
-
-#include <string>
-
-#include <X11/Xlib.h>
-#include <X11/Xresource.h>
-
-class Resource {
-public:
- explicit Resource(const std::string &file);
- Resource();
- virtual ~Resource();
-
- inline const std::string &file() const {
- return static_cast<const std::string &>(m_file);
- }
- void setFile(const std::string &file);
-
- // defaults to true!
- inline bool autoSave() const {
- return m_autosave;
- }
- void setAutoSave(bool);
-
- inline bool isModified() const {
- return m_modified;
- }
-
- void save();
- bool load();
- void create();
-
- void setValue(const std::string &rname, bool value);
- void setValue(const std::string &rname, int value);
- void setValue(const std::string &rname, long value);
- void setValue(const std::string &rname, const std::string &value);
- void setValue(const std::string &rname, const char *value);
-
- bool getValue(const std::string &rname, const std::string &rclass,
- bool &value) const;
- bool getValue(const std::string &rname, const std::string &rclass,
- long &value) const;
- bool getValue(const std::string &rname, const std::string &rclass,
- std::string &value) const;
-
-private:
- static bool m_initialized;
- std::string m_file;
- bool m_modified;
- bool m_autosave;
- XrmDatabase m_database;
-};
-
-#endif // __Resource_hh
-// Rootmenu.cc for Openbox
-// Copyright (c) 2001 Sean 'Shaleh' Perry <shaleh@debian.org>
+// -*- mode: C++; indent-tabs-mode: nil; -*-
+// Rootmenu.cc for Blackbox - an X11 Window manager
+// Copyright (c) 2001 - 2002 Sean 'Shaleh' Perry <shaleh@debian.org>
// Copyright (c) 1997 - 2000 Brad Hughes (bhughes@tcac.net)
//
// Permission is hereby granted, free of charge, to any person obtaining a
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
-// stupid macros needed to access some functions in version 2 of the GNU C
-// library
-#ifndef _GNU_SOURCE
-#define _GNU_SOURCE
-#endif // _GNU_SOURCE
-
#ifdef HAVE_CONFIG_H
# include "../config.h"
#endif // HAVE_CONFIG_H
-#include "openbox.h"
-#include "Rootmenu.h"
-#include "Screen.h"
-
+extern "C" {
#ifdef HAVE_STDIO_H
# include <stdio.h>
#endif // HAVE_STDIO_H
-#ifdef HAVE_STDLIB_H
+#ifdef HAVE_STDLIB_H
# include <stdlib.h>
#endif // HAVE_STDLIB_H
-#ifdef HAVE_STRING_H
+#ifdef HAVE_STRING_H
# include <string.h>
#endif // HAVE_STRING_H
#ifdef HAVE_SYS_PARAM_H
# include <sys/param.h>
#endif // HAVE_SYS_PARAM_H
+}
-#ifndef MAXPATHLEN
-#define MAXPATHLEN 255
-#endif // MAXPATHLEN
+#include "blackbox.hh"
+#include "Rootmenu.hh"
+#include "Screen.hh"
+#include "Util.hh"
-Rootmenu::Rootmenu(BScreen &scrn) : Basemenu(scrn), openbox(scrn.getOpenbox()),
- screen(scrn)
-{
-}
+Rootmenu::Rootmenu(BScreen *scrn) : Basemenu(scrn) { }
-void Rootmenu::itemSelected(int button, int index) {
+void Rootmenu::itemSelected(int button, unsigned int index) {
if (button != 1)
return;
switch (item->function()) {
case BScreen::Execute:
- if (item->exec()) {
-#ifndef __EMX__
- char displaystring[MAXPATHLEN];
- sprintf(displaystring, "DISPLAY=%s",
- DisplayString(screen.getBaseDisplay().getXDisplay()));
- sprintf(displaystring + strlen(displaystring) - 1, "%d",
- screen.getScreenNumber());
-
- bexec(item->exec(), displaystring);
-#else // __EMX__
- spawnlp(P_NOWAIT, "cmd.exe", "cmd.exe", "/c", item->exec(), NULL);
-#endif // !__EMX__
- }
+ if (item->exec())
+ bexec(item->exec(), getScreen()->displayString());
break;
case BScreen::Restart:
- openbox.restart();
+ getScreen()->getBlackbox()->restart();
break;
case BScreen::RestartOther:
if (item->exec())
- openbox.restart(item->exec());
+ getScreen()->getBlackbox()->restart(item->exec());
break;
case BScreen::Exit:
- openbox.shutdown();
+ getScreen()->getBlackbox()->shutdown();
break;
case BScreen::SetStyle:
if (item->exec())
- openbox.setStyleFilename(item->exec());
+ getScreen()->getBlackbox()->saveStyleFilename(item->exec());
case BScreen::Reconfigure:
- openbox.reconfigure();
+ getScreen()->getBlackbox()->reconfigure();
return;
}
- if (! (screen.getRootmenu()->isTorn() || isTorn()) &&
+ if (! (getScreen()->getRootmenu()->isTorn() || isTorn()) &&
item->function() != BScreen::Reconfigure &&
item->function() != BScreen::SetStyle)
hide();
-// Rootmenu.h for Openbox
-// Copyright (c) 2001 Sean 'Shaleh' Perry <shaleh@debian.org>
+// -*- mode: C++; indent-tabs-mode: nil; -*-
+// Rootmenu.hh for Blackbox - an X11 Window manager
+// Copyright (c) 2001 - 2002 Sean 'Shaleh' Perry <shaleh@debian.org>
// Copyright (c) 1997 - 2000 Brad Hughes (bhughes@tcac.net)
//
// Permission is hereby granted, free of charge, to any person obtaining a
#define __Rootmenu_hh
// forward declarations
-class Rootmenu;
-
-class Openbox;
class BScreen;
-#include "Basemenu.h"
+#include "Basemenu.hh"
class Rootmenu : public Basemenu {
private:
- Openbox &openbox;
- BScreen &screen;
-
+ Rootmenu(const Rootmenu&);
+ Rootmenu& operator=(const Rootmenu&);
protected:
- virtual void itemSelected(int, int);
-
+ virtual void itemSelected(int button, unsigned int index);
public:
- Rootmenu(BScreen &);
+ Rootmenu(BScreen *scrn);
};
-// Screen.cc for Openbox
-// Copyright (c) 2001 Sean 'Shaleh' Perry <shaleh@debian.org>
+// -*- mode: C++; indent-tabs-mode: nil; c-basic-offset: 2; -*-
+// Screen.cc for Blackbox - an X11 Window manager
+// Copyright (c) 2001 - 2002 Sean 'Shaleh' Perry <shaleh@debian.org>
// Copyright (c) 1997 - 2000 Brad Hughes (bhughes@tcac.net)
//
// Permission is hereby granted, free of charge, to any person obtaining a
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
-// stupid macros needed to access some functions in version 2 of the GNU C
-// library
-#ifndef _GNU_SOURCE
-#define _GNU_SOURCE
-#endif // _GNU_SOURCE
-
#ifdef HAVE_CONFIG_H
# include "../config.h"
#endif // HAVE_CONFIG_H
+extern "C" {
#include <X11/Xatom.h>
#include <X11/keysym.h>
-#include "i18n.h"
-#include "openbox.h"
-#include "Clientmenu.h"
-#include "Iconmenu.h"
-#include "Image.h"
-#include "Screen.h"
-
-#ifdef SLIT
-#include "Slit.h"
-#endif // SLIT
-
-#include "Rootmenu.h"
-#include "Toolbar.h"
-#include "Window.h"
-#include "Workspace.h"
-#include "Workspacemenu.h"
-#include "Util.h"
-
-#ifdef HAVE_STDLIB_H
+// for strcasestr()
+#ifndef _GNU_SOURCE
+# define _GNU_SOURCE
+#endif // _GNU_SOURCE
+
+#ifdef HAVE_STDLIB_H
# include <stdlib.h>
#endif // HAVE_STDLIB_H
-#ifdef HAVE_STRING_H
+#ifdef HAVE_STRING_H
# include <string.h>
#endif // HAVE_STRING_H
-#ifdef HAVE_SYS_TYPES_H
-# include <sys/types.h>
-#endif // HAVE_SYS_TYPES_H
-
#ifdef HAVE_CTYPE_H
# include <ctype.h>
#endif // HAVE_CTYPE_H
+#ifdef HAVE_UNISTD_H
+# include <sys/types.h>
+# include <unistd.h>
+#endif // HAVE_UNISTD_H
+
#ifdef HAVE_DIRENT_H
# include <dirent.h>
#endif // HAVE_DIRENT_H
# include <locale.h>
#endif // HAVE_LOCALE_H
-#ifdef HAVE_UNISTD_H
-# include <sys/types.h>
-# include <unistd.h>
-#endif // HAVE_UNISTD_H
-
#ifdef HAVE_SYS_STAT_H
# include <sys/stat.h>
#endif // HAVE_SYS_STAT_H
#ifdef HAVE_STDARG_H
# include <stdarg.h>
#endif // HAVE_STDARG_H
+}
-#ifndef HAVE_SNPRINTF
-# include "bsd-snprintf.h"
-#endif // !HAVE_SNPRINTF
-
-#ifndef MAXPATHLEN
-#define MAXPATHLEN 255
-#endif // MAXPATHLEN
+#include <algorithm>
+#include <functional>
+using std::string;
+
+#include "i18n.hh"
+#include "blackbox.hh"
+#include "Clientmenu.hh"
+#include "GCCache.hh"
+#include "Iconmenu.hh"
+#include "Image.hh"
+#include "Screen.hh"
+#include "Slit.hh"
+#include "Rootmenu.hh"
+#include "Toolbar.hh"
+#include "Util.hh"
+#include "Window.hh"
+#include "Workspace.hh"
+#include "Workspacemenu.hh"
#ifndef FONT_ELEMENT_SIZE
#define FONT_ELEMENT_SIZE 50
#endif // FONT_ELEMENT_SIZE
-#include <strstream>
-#include <string>
-#include <algorithm>
-#include <functional>
-using std::ends;
-static Bool running = True;
+static bool running = True;
static int anotherWMRunning(Display *display, XErrorEvent *) {
fprintf(stderr, i18n(ScreenSet, ScreenAnotherWMRunning,
- "BScreen::BScreen: an error occured while querying the X server.\n"
- " another window manager already running on display %s.\n"),
+ "BScreen::BScreen: an error occured while querying the X server.\n"
+ " another window manager already running on display %s.\n"),
DisplayString(display));
running = False;
return(-1);
}
-struct dcmp {
- bool operator()(const char *one, const char *two) const {
- return (strcmp(one, two) < 0) ? True : False;
- }
-};
-
-#ifndef HAVE_STRCASESTR
-static const char * strcasestr(const char *str, const char *ptn) {
- const char *s2, *p2;
- for( ; *str; str++) {
- for(s2=str,p2=ptn; ; s2++,p2++) {
- if (!*p2) return str;
- if (toupper(*s2) != toupper(*p2)) break;
- }
- }
- return NULL;
-}
-#endif // HAVE_STRCASESTR
-
-static const char *getFontElement(const char *pattern, char *buf, int bufsiz, ...) {
- const char *p, *v;
- char *p2;
- va_list va;
-
- va_start(va, bufsiz);
- buf[bufsiz-1] = 0;
- buf[bufsiz-2] = '*';
- while((v = va_arg(va, char *)) != NULL) {
- p = strcasestr(pattern, v);
- if (p) {
- strncpy(buf, p+1, bufsiz-2);
- p2 = strchr(buf, '-');
- if (p2) *p2=0;
- va_end(va);
- return p;
- }
- }
- va_end(va);
- strncpy(buf, "*", bufsiz);
- return NULL;
-}
-
-static const char *getFontSize(const char *pattern, int *size) {
- const char *p;
- const char *p2=NULL;
- int n=0;
-
- for (p=pattern; 1; p++) {
- if (!*p) {
- if (p2!=NULL && n>1 && n<72) {
- *size = n; return p2+1;
- } else {
- *size = 16; return NULL;
- }
- } else if (*p=='-') {
- if (n>1 && n<72 && p2!=NULL) {
- *size = n;
- return p2+1;
- }
- p2=p; n=0;
- } else if (*p>='0' && *p<='9' && p2!=NULL) {
- n *= 10;
- n += *p-'0';
- } else {
- p2=NULL; n=0;
- }
- }
-}
+BScreen::BScreen(Blackbox *bb, unsigned int scrn) : ScreenInfo(bb, scrn) {
+ blackbox = bb;
-BScreen::BScreen(Openbox &ob, int scrn, Resource &conf) : ScreenInfo(ob, scrn),
-openbox(ob), config(conf)
-{
event_mask = ColormapChangeMask | EnterWindowMask | PropertyChangeMask |
- SubstructureRedirectMask | KeyPressMask | KeyReleaseMask |
- ButtonPressMask | ButtonReleaseMask;
+ SubstructureRedirectMask | ButtonPressMask | ButtonReleaseMask;
XErrorHandler old = XSetErrorHandler((XErrorHandler) anotherWMRunning);
- XSelectInput(getBaseDisplay().getXDisplay(), getRootWindow(), event_mask);
- XSync(getBaseDisplay().getXDisplay(), False);
+ XSelectInput(getBaseDisplay()->getXDisplay(), getRootWindow(), event_mask);
+ XSync(getBaseDisplay()->getXDisplay(), False);
XSetErrorHandler((XErrorHandler) old);
managed = running;
getDepth());
rootmenu = 0;
+ resource.stylerc = 0;
resource.mstyle.t_fontset = resource.mstyle.f_fontset =
- resource.tstyle.fontset = resource.wstyle.fontset = NULL;
+ resource.tstyle.fontset = resource.wstyle.fontset = (XFontSet) 0;
resource.mstyle.t_font = resource.mstyle.f_font = resource.tstyle.font =
- resource.wstyle.font = NULL;
- resource.root_command = NULL;
-#ifdef HAVE_STRFTIME
- resource.strftime_format = NULL;
-#endif // HAVE_STRFTIME
-
-#ifdef SLIT
- slit = NULL;
-#endif // SLIT
- toolbar = NULL;
- current_workspace = (Workspace *) 0;
+ resource.wstyle.font = (XFontStruct *) 0;
#ifdef HAVE_GETPID
pid_t bpid = getpid();
- XChangeProperty(getBaseDisplay().getXDisplay(), getRootWindow(),
- openbox.getOpenboxPidAtom(), XA_CARDINAL,
+ XChangeProperty(blackbox->getXDisplay(), getRootWindow(),
+ blackbox->getBlackboxPidAtom(), XA_CARDINAL,
sizeof(pid_t) * 8, PropModeReplace,
(unsigned char *) &bpid, 1);
#endif // HAVE_GETPID
- XDefineCursor(getBaseDisplay().getXDisplay(), getRootWindow(),
- openbox.getSessionCursor());
+ XDefineCursor(blackbox->getXDisplay(), getRootWindow(),
+ blackbox->getSessionCursor());
+
+ // start off full screen, top left.
+ usableArea.setSize(getWidth(), getHeight());
image_control =
- new BImageControl(openbox, *this, True, openbox.getColorsPerChannel(),
- openbox.getCacheLife(), openbox.getCacheMax());
+ new BImageControl(blackbox, this, True, blackbox->getColorsPerChannel(),
+ blackbox->getCacheLife(), blackbox->getCacheMax());
image_control->installRootColormap();
root_colormap_installed = True;
- load(); // load config options from Resources
+ blackbox->load_rc(this);
+
+ image_control->setDither(resource.image_dither);
+
LoadStyle();
XGCValues gcv;
unsigned long gc_value_mask = GCForeground;
if (! i18n.multibyte()) gc_value_mask |= GCFont;
- gcv.foreground = WhitePixel(getBaseDisplay().getXDisplay(),
- getScreenNumber())
- ^ BlackPixel(getBaseDisplay().getXDisplay(),
- getScreenNumber());
+ gcv.foreground = WhitePixel(blackbox->getXDisplay(), getScreenNumber())
+ ^ BlackPixel(blackbox->getXDisplay(), getScreenNumber());
gcv.function = GXxor;
gcv.subwindow_mode = IncludeInferiors;
- opGC = XCreateGC(getBaseDisplay().getXDisplay(), getRootWindow(),
+ opGC = XCreateGC(blackbox->getXDisplay(), getRootWindow(),
GCForeground | GCFunction | GCSubwindowMode, &gcv);
- gcv.foreground = resource.wstyle.l_text_focus.getPixel();
- if (resource.wstyle.font)
- gcv.font = resource.wstyle.font->fid;
- resource.wstyle.l_text_focus_gc =
- XCreateGC(getBaseDisplay().getXDisplay(), getRootWindow(),
- gc_value_mask, &gcv);
-
- gcv.foreground = resource.wstyle.l_text_unfocus.getPixel();
- if (resource.wstyle.font)
- gcv.font = resource.wstyle.font->fid;
- resource.wstyle.l_text_unfocus_gc =
- XCreateGC(getBaseDisplay().getXDisplay(), getRootWindow(),
- gc_value_mask, &gcv);
-
- gcv.foreground = resource.wstyle.b_pic_focus.getPixel();
- resource.wstyle.b_pic_focus_gc =
- XCreateGC(getBaseDisplay().getXDisplay(), getRootWindow(),
- GCForeground, &gcv);
-
- gcv.foreground = resource.wstyle.b_pic_unfocus.getPixel();
- resource.wstyle.b_pic_unfocus_gc =
- XCreateGC(getBaseDisplay().getXDisplay(), getRootWindow(),
- GCForeground, &gcv);
-
- gcv.foreground = resource.mstyle.t_text.getPixel();
- if (resource.mstyle.t_font)
- gcv.font = resource.mstyle.t_font->fid;
- resource.mstyle.t_text_gc =
- XCreateGC(getBaseDisplay().getXDisplay(), getRootWindow(),
- gc_value_mask, &gcv);
-
- gcv.foreground = resource.mstyle.f_text.getPixel();
- if (resource.mstyle.f_font)
- gcv.font = resource.mstyle.f_font->fid;
- resource.mstyle.f_text_gc =
- XCreateGC(getBaseDisplay().getXDisplay(), getRootWindow(),
- gc_value_mask, &gcv);
-
- gcv.foreground = resource.mstyle.h_text.getPixel();
- resource.mstyle.h_text_gc =
- XCreateGC(getBaseDisplay().getXDisplay(), getRootWindow(),
- gc_value_mask, &gcv);
-
- gcv.foreground = resource.mstyle.d_text.getPixel();
- resource.mstyle.d_text_gc =
- XCreateGC(getBaseDisplay().getXDisplay(), getRootWindow(),
- gc_value_mask, &gcv);
-
- gcv.foreground = resource.mstyle.hilite.getColor()->getPixel();
- resource.mstyle.hilite_gc =
- XCreateGC(getBaseDisplay().getXDisplay(), getRootWindow(),
- gc_value_mask, &gcv);
-
- gcv.foreground = resource.tstyle.l_text.getPixel();
- if (resource.tstyle.font)
- gcv.font = resource.tstyle.font->fid;
- resource.tstyle.l_text_gc =
- XCreateGC(getBaseDisplay().getXDisplay(), getRootWindow(),
- gc_value_mask, &gcv);
-
- gcv.foreground = resource.tstyle.w_text.getPixel();
- resource.tstyle.w_text_gc =
- XCreateGC(getBaseDisplay().getXDisplay(), getRootWindow(),
- gc_value_mask, &gcv);
-
- gcv.foreground = resource.tstyle.c_text.getPixel();
- resource.tstyle.c_text_gc =
- XCreateGC(getBaseDisplay().getXDisplay(), getRootWindow(),
- gc_value_mask, &gcv);
-
- gcv.foreground = resource.tstyle.b_pic.getPixel();
- resource.tstyle.b_pic_gc =
- XCreateGC(getBaseDisplay().getXDisplay(), getRootWindow(),
- gc_value_mask, &gcv);
-
const char *s = i18n(ScreenSet, ScreenPositionLength,
"0: 0000 x 0: 0000");
int l = strlen(s);
XSetWindowAttributes attrib;
unsigned long mask = CWBorderPixel | CWColormap | CWSaveUnder;
- attrib.border_pixel = getBorderColor()->getPixel();
+ attrib.border_pixel = getBorderColor()->pixel();
attrib.colormap = getColormap();
attrib.save_under = True;
- geom_window =
- XCreateWindow(getBaseDisplay().getXDisplay(), getRootWindow(),
- 0, 0, geom_w, geom_h, resource.border_width, getDepth(),
- InputOutput, getVisual(), mask, &attrib);
+ geom_window = XCreateWindow(blackbox->getXDisplay(), getRootWindow(),
+ 0, 0, geom_w, geom_h, resource.border_width,
+ getDepth(), InputOutput, getVisual(),
+ mask, &attrib);
geom_visible = False;
- if (resource.wstyle.l_focus.getTexture() & BImage_ParentRelative) {
- if (resource.wstyle.t_focus.getTexture() ==
- (BImage_Flat | BImage_Solid)) {
- geom_pixmap = None;
- XSetWindowBackground(getBaseDisplay().getXDisplay(), geom_window,
- resource.wstyle.t_focus.getColor()->getPixel());
- } else {
- geom_pixmap = image_control->renderImage(geom_w, geom_h,
- &resource.wstyle.t_focus);
- XSetWindowBackgroundPixmap(getBaseDisplay().getXDisplay(),
- geom_window, geom_pixmap);
- }
- } else {
- if (resource.wstyle.l_focus.getTexture() ==
- (BImage_Flat | BImage_Solid)) {
- geom_pixmap = None;
- XSetWindowBackground(getBaseDisplay().getXDisplay(), geom_window,
- resource.wstyle.l_focus.getColor()->getPixel());
- } else {
- geom_pixmap = image_control->renderImage(geom_w, geom_h,
- &resource.wstyle.l_focus);
- XSetWindowBackgroundPixmap(getBaseDisplay().getXDisplay(),
- geom_window, geom_pixmap);
- }
- }
+ BTexture* texture = &(resource.wstyle.l_focus);
+ geom_pixmap = texture->render(geom_w, geom_h, geom_pixmap);
+ if (! geom_pixmap)
+ XSetWindowBackground(blackbox->getXDisplay(), geom_window,
+ texture->color().pixel());
+ else
+ XSetWindowBackgroundPixmap(blackbox->getXDisplay(),
+ geom_window, geom_pixmap);
- workspacemenu = new Workspacemenu(*this);
- iconmenu = new Iconmenu(*this);
- configmenu = new Configmenu(*this);
+ workspacemenu = new Workspacemenu(this);
+ iconmenu = new Iconmenu(this);
+ configmenu = new Configmenu(this);
- Workspace *wkspc = NULL;
+ Workspace *wkspc = (Workspace *) 0;
if (resource.workspaces != 0) {
- for (int i = 0; i < resource.workspaces; ++i) {
- wkspc = new Workspace(*this, workspacesList.size());
+ for (unsigned int i = 0; i < resource.workspaces; ++i) {
+ wkspc = new Workspace(this, workspacesList.size());
workspacesList.push_back(wkspc);
workspacemenu->insert(wkspc->getName(), wkspc->getMenu());
}
} else {
- setWorkspaceCount(1);
- wkspc = new Workspace(*this, workspacesList.size());
+ wkspc = new Workspace(this, workspacesList.size());
workspacesList.push_back(wkspc);
workspacemenu->insert(wkspc->getName(), wkspc->getMenu());
}
- saveWorkspaceNames();
- workspacemenu->insert(i18n(IconSet, IconIcons, "Icons"),
- iconmenu);
+ workspacemenu->insert(i18n(IconSet, IconIcons, "Icons"), iconmenu);
workspacemenu->update();
current_workspace = workspacesList.front();
workspacemenu->setItemSelected(2, True);
- toolbar = new Toolbar(*this, config);
+ toolbar = new Toolbar(this);
-#ifdef SLIT
- slit = new Slit(*this, config);
-#endif // SLIT
+ slit = new Slit(this);
InitMenu();
raiseWindows(0, 0);
rootmenu->update();
+ updateAvailableArea();
+
changeWorkspaceID(0);
- int i;
- unsigned int nchild;
+ unsigned int i, j, nchild;
Window r, p, *children;
- XQueryTree(getBaseDisplay().getXDisplay(), getRootWindow(), &r, &p,
+ XQueryTree(blackbox->getXDisplay(), getRootWindow(), &r, &p,
&children, &nchild);
// preen the window list of all icon windows... for better dockapp support
- for (i = 0; i < (int) nchild; i++) {
+ for (i = 0; i < nchild; i++) {
if (children[i] == None) continue;
- XWMHints *wmhints = XGetWMHints(getBaseDisplay().getXDisplay(),
+ XWMHints *wmhints = XGetWMHints(blackbox->getXDisplay(),
children[i]);
if (wmhints) {
if ((wmhints->flags & IconWindowHint) &&
- (wmhints->icon_window != children[i]))
- for (int j = 0; j < (int) nchild; j++)
+ (wmhints->icon_window != children[i])) {
+ for (j = 0; j < nchild; j++) {
if (children[j] == wmhints->icon_window) {
children[j] = None;
-
break;
}
+ }
+ }
XFree(wmhints);
}
}
// manage shown windows
- for (i = 0; i < (int) nchild; ++i) {
- if (children[i] == None || (! openbox.validateWindow(children[i])))
+ for (i = 0; i < nchild; ++i) {
+ if (children[i] == None || (! blackbox->validateWindow(children[i])))
continue;
XWindowAttributes attrib;
- if (XGetWindowAttributes(getBaseDisplay().getXDisplay(), children[i],
- &attrib)) {
+ if (XGetWindowAttributes(blackbox->getXDisplay(), children[i], &attrib)) {
if (attrib.override_redirect) continue;
if (attrib.map_state != IsUnmapped) {
- new OpenboxWindow(openbox, children[i], this);
-
- OpenboxWindow *win = openbox.searchWindow(children[i]);
- if (win) {
- XMapRequestEvent mre;
- mre.window = children[i];
- win->restoreAttributes();
- win->mapRequestEvent(&mre);
- }
+ manageWindow(children[i]);
}
}
}
XFree(children);
- XFlush(getBaseDisplay().getXDisplay());
+
+ // call this again just in case a window we found updates the Strut list
+ updateAvailableArea();
}
image_control->removeImage(geom_pixmap);
if (geom_window != None)
- XDestroyWindow(getBaseDisplay().getXDisplay(), geom_window);
-
- removeWorkspaceNames();
+ XDestroyWindow(blackbox->getXDisplay(), geom_window);
std::for_each(workspacesList.begin(), workspacesList.end(),
PointerAssassin());
+
std::for_each(iconList.begin(), iconList.end(), PointerAssassin());
- std::for_each(netizenList.begin(), netizenList.end(), PointerAssassin());
-#ifdef HAVE_STRFTIME
- if (resource.strftime_format)
- delete [] resource.strftime_format;
-#endif // HAVE_STRFTIME
+ std::for_each(netizenList.begin(), netizenList.end(), PointerAssassin());
delete rootmenu;
delete workspacemenu;
delete iconmenu;
delete configmenu;
-
-#ifdef SLIT
delete slit;
-#endif // SLIT
-
delete toolbar;
delete image_control;
if (resource.wstyle.fontset)
- XFreeFontSet(getBaseDisplay().getXDisplay(), resource.wstyle.fontset);
+ XFreeFontSet(blackbox->getXDisplay(), resource.wstyle.fontset);
if (resource.mstyle.t_fontset)
- XFreeFontSet(getBaseDisplay().getXDisplay(), resource.mstyle.t_fontset);
+ XFreeFontSet(blackbox->getXDisplay(), resource.mstyle.t_fontset);
if (resource.mstyle.f_fontset)
- XFreeFontSet(getBaseDisplay().getXDisplay(), resource.mstyle.f_fontset);
+ XFreeFontSet(blackbox->getXDisplay(), resource.mstyle.f_fontset);
if (resource.tstyle.fontset)
- XFreeFontSet(getBaseDisplay().getXDisplay(), resource.tstyle.fontset);
+ XFreeFontSet(blackbox->getXDisplay(), resource.tstyle.fontset);
if (resource.wstyle.font)
- XFreeFont(getBaseDisplay().getXDisplay(), resource.wstyle.font);
+ XFreeFont(blackbox->getXDisplay(), resource.wstyle.font);
if (resource.mstyle.t_font)
- XFreeFont(getBaseDisplay().getXDisplay(), resource.mstyle.t_font);
+ XFreeFont(blackbox->getXDisplay(), resource.mstyle.t_font);
if (resource.mstyle.f_font)
- XFreeFont(getBaseDisplay().getXDisplay(), resource.mstyle.f_font);
+ XFreeFont(blackbox->getXDisplay(), resource.mstyle.f_font);
if (resource.tstyle.font)
- XFreeFont(getBaseDisplay().getXDisplay(), resource.tstyle.font);
- if (resource.root_command != NULL)
- delete [] resource.root_command;
-
- XFreeGC(getBaseDisplay().getXDisplay(), opGC);
-
- XFreeGC(getBaseDisplay().getXDisplay(),
- resource.wstyle.l_text_focus_gc);
- XFreeGC(getBaseDisplay().getXDisplay(),
- resource.wstyle.l_text_unfocus_gc);
- XFreeGC(getBaseDisplay().getXDisplay(),
- resource.wstyle.b_pic_focus_gc);
- XFreeGC(getBaseDisplay().getXDisplay(),
- resource.wstyle.b_pic_unfocus_gc);
-
- XFreeGC(getBaseDisplay().getXDisplay(),
- resource.mstyle.t_text_gc);
- XFreeGC(getBaseDisplay().getXDisplay(),
- resource.mstyle.f_text_gc);
- XFreeGC(getBaseDisplay().getXDisplay(),
- resource.mstyle.h_text_gc);
- XFreeGC(getBaseDisplay().getXDisplay(),
- resource.mstyle.d_text_gc);
- XFreeGC(getBaseDisplay().getXDisplay(),
- resource.mstyle.hilite_gc);
-
- XFreeGC(getBaseDisplay().getXDisplay(),
- resource.tstyle.l_text_gc);
- XFreeGC(getBaseDisplay().getXDisplay(),
- resource.tstyle.w_text_gc);
- XFreeGC(getBaseDisplay().getXDisplay(),
- resource.tstyle.c_text_gc);
- XFreeGC(getBaseDisplay().getXDisplay(),
- resource.tstyle.b_pic_gc);
+ XFreeFont(blackbox->getXDisplay(), resource.tstyle.font);
+
+ XFreeGC(blackbox->getXDisplay(), opGC);
}
-Rect BScreen::availableArea() const {
- // the following code is temporary and will be taken care of by Screen in the
- // future (with the NETWM 'strut')
- Rect space(0, 0, size().w(), size().h());
- if (!resource.full_max) {
-#ifdef SLIT
- int slit_x = slit->autoHide() ? slit->hiddenOrigin().x() : slit->area().x(),
- slit_y = slit->autoHide() ? slit->hiddenOrigin().y() : slit->area().y();
- unsigned int tbarh = resource.hide_toolbar ? 0 :
- toolbar->getExposedHeight() + resource.border_width * 2;
- bool tbartop;
- switch (toolbar->placement()) {
- case Toolbar::TopLeft:
- case Toolbar::TopCenter:
- case Toolbar::TopRight:
- tbartop = true;
- break;
- case Toolbar::BottomLeft:
- case Toolbar::BottomCenter:
- case Toolbar::BottomRight:
- tbartop = false;
- break;
- default:
- ASSERT(false); // unhandled placement
- }
- if ((slit->direction() == Slit::Horizontal &&
- (slit->placement() == Slit::TopLeft ||
- slit->placement() == Slit::TopRight)) ||
- slit->placement() == Slit::TopCenter) {
- // exclude top
- if (tbartop && slit_y + slit->area().h() < tbarh) {
- space.setY(space.y() + tbarh);
- space.setH(space.h() - tbarh);
- } else {
- space.setY(space.y() + (slit_y + slit->area().h() +
- resource.border_width * 2));
- space.setH(space.h() - (slit_y + slit->area().h() +
- resource.border_width * 2));
- if (!tbartop)
- space.setH(space.h() - tbarh);
- }
- } else if ((slit->direction() == Slit::Vertical &&
- (slit->placement() == Slit::TopRight ||
- slit->placement() == Slit::BottomRight)) ||
- slit->placement() == Slit::CenterRight) {
- // exclude right
- space.setW(space.w() - (size().w() - slit_x));
- if (tbartop)
- space.setY(space.y() + tbarh);
- space.setH(space.h() - tbarh);
- } else if ((slit->direction() == Slit::Horizontal &&
- (slit->placement() == Slit::BottomLeft ||
- slit->placement() == Slit::BottomRight)) ||
- slit->placement() == Slit::BottomCenter) {
- // exclude bottom
- if (!tbartop && (size().h() - slit_y) < tbarh) {
- space.setH(space.h() - tbarh);
- } else {
- space.setH(space.h() - (size().h() - slit_y));
- if (tbartop) {
- space.setY(space.y() + tbarh);
- space.setH(space.h() - tbarh);
- }
- }
- } else {// if ((slit->direction() == Slit::Vertical &&
- // (slit->placement() == Slit::TopLeft ||
- // slit->placement() == Slit::BottomLeft)) ||
- // slit->placement() == Slit::CenterLeft)
- // exclude left
- space.setX(slit_x + slit->area().w() +
- resource.border_width * 2);
- space.setW(space.w() - (slit_x + slit->area().w() +
- resource.border_width * 2));
- if (tbartop)
- space.setY(space.y() + tbarh);
- space.setH(space.h() - tbarh);
- }
-#else // !SLIT
- int tbarh = resource.hide_toolbar ? 0 :
- toolbar->getExposedHeight() + resource.border_width * 2;
- switch (toolbar->placement()) {
- case Toolbar::TopLeft:
- case Toolbar::TopCenter:
- case Toolbar::TopRight:
- space.setY(toolbar->getExposedHeight());
- space.setH(space.h() - toolbar->getExposedHeight());
- break;
- case Toolbar::BottomLeft:
- case Toolbar::BottomCenter:
- case Toolbar::BottomRight:
- space.setH(space.h() - tbarh);
- break;
- default:
- ASSERT(false); // unhandled placement
- }
-#endif // SLIT
- }
- return space;
+void BScreen::removeWorkspaceNames(void) {
+ workspaceNames.clear();
}
-void BScreen::readDatabaseTexture(const char *rname, const char *rclass,
- BTexture *texture,
- unsigned long default_pixel)
-{
- std::string s;
+void BScreen::reconfigure(void) {
+ LoadStyle();
- if (resource.styleconfig.getValue(rname, rclass, s))
- image_control->parseTexture(texture, s.c_str());
- else
- texture->setTexture(BImage_Solid | BImage_Flat);
-
- if (texture->getTexture() & BImage_Solid) {
- int clen = strlen(rclass) + 32, nlen = strlen(rname) + 32;
-
- char *colorclass = new char[clen], *colorname = new char[nlen];
-
- sprintf(colorclass, "%s.Color", rclass);
- sprintf(colorname, "%s.color", rname);
-
- readDatabaseColor(colorname, colorclass, texture->getColor(),
- default_pixel);
-
-#ifdef INTERLACE
- sprintf(colorclass, "%s.ColorTo", rclass);
- sprintf(colorname, "%s.colorTo", rname);
-
- readDatabaseColor(colorname, colorclass, texture->getColorTo(),
- default_pixel);
-#endif // INTERLACE
-
- delete [] colorclass;
- delete [] colorname;
-
- if ((! texture->getColor()->isAllocated()) ||
- (texture->getTexture() & BImage_Flat))
- return;
-
- XColor xcol;
-
- xcol.red = (unsigned int) (texture->getColor()->getRed() +
- (texture->getColor()->getRed() >> 1));
- if (xcol.red >= 0xff) xcol.red = 0xffff;
- else xcol.red *= 0xff;
- xcol.green = (unsigned int) (texture->getColor()->getGreen() +
- (texture->getColor()->getGreen() >> 1));
- if (xcol.green >= 0xff) xcol.green = 0xffff;
- else xcol.green *= 0xff;
- xcol.blue = (unsigned int) (texture->getColor()->getBlue() +
- (texture->getColor()->getBlue() >> 1));
- if (xcol.blue >= 0xff) xcol.blue = 0xffff;
- else xcol.blue *= 0xff;
-
- if (! XAllocColor(getBaseDisplay().getXDisplay(),
- getColormap(), &xcol))
- xcol.pixel = 0;
-
- texture->getHiColor()->setPixel(xcol.pixel);
-
- xcol.red =
- (unsigned int) ((texture->getColor()->getRed() >> 2) +
- (texture->getColor()->getRed() >> 1)) * 0xff;
- xcol.green =
- (unsigned int) ((texture->getColor()->getGreen() >> 2) +
- (texture->getColor()->getGreen() >> 1)) * 0xff;
- xcol.blue =
- (unsigned int) ((texture->getColor()->getBlue() >> 2) +
- (texture->getColor()->getBlue() >> 1)) * 0xff;
-
- if (! XAllocColor(getBaseDisplay().getXDisplay(),
- getColormap(), &xcol))
- xcol.pixel = 0;
-
- texture->getLoColor()->setPixel(xcol.pixel);
- } else if (texture->getTexture() & BImage_Gradient) {
- int clen = strlen(rclass) + 10, nlen = strlen(rname) + 10;
-
- char *colorclass = new char[clen], *colorname = new char[nlen],
- *colortoclass = new char[clen], *colortoname = new char[nlen];
-
- sprintf(colorclass, "%s.Color", rclass);
- sprintf(colorname, "%s.color", rname);
-
- sprintf(colortoclass, "%s.ColorTo", rclass);
- sprintf(colortoname, "%s.colorTo", rname);
-
- readDatabaseColor(colorname, colorclass, texture->getColor(),
- default_pixel);
- readDatabaseColor(colortoname, colortoclass, texture->getColorTo(),
- default_pixel);
-
- delete [] colorclass;
- delete [] colorname;
- delete [] colortoclass;
- delete [] colortoname;
- }
-}
+ XGCValues gcv;
+ unsigned long gc_value_mask = GCForeground;
+ if (! i18n.multibyte()) gc_value_mask |= GCFont;
+ gcv.foreground = WhitePixel(blackbox->getXDisplay(),
+ getScreenNumber());
+ gcv.function = GXinvert;
+ gcv.subwindow_mode = IncludeInferiors;
+ XChangeGC(blackbox->getXDisplay(), opGC,
+ GCForeground | GCFunction | GCSubwindowMode, &gcv);
-void BScreen::readDatabaseColor(const char *rname, const char *rclass,
- BColor *color, unsigned long default_pixel)
-{
- std::string s;
+ const char *s = i18n(ScreenSet, ScreenPositionLength,
+ "0: 0000 x 0: 0000");
+ int l = strlen(s);
- if (resource.styleconfig.getValue(rname, rclass, s))
- image_control->parseColor(color, s.c_str());
- else {
- // parsing with no color std::string just deallocates the color, if it has
- // been previously allocated
- image_control->parseColor(color);
- color->setPixel(default_pixel);
+ if (i18n.multibyte()) {
+ XRectangle ink, logical;
+ XmbTextExtents(resource.wstyle.fontset, s, l, &ink, &logical);
+ geom_w = logical.width;
+
+ geom_h = resource.wstyle.fontset_extents->max_ink_extent.height;
+ } else {
+ geom_w = XTextWidth(resource.wstyle.font, s, l);
+
+ geom_h = resource.wstyle.font->ascent + resource.wstyle.font->descent;
}
-}
+ geom_w += (resource.bevel_width * 2);
+ geom_h += (resource.bevel_width * 2);
+
+ BTexture* texture = &(resource.wstyle.l_focus);
+ geom_pixmap = texture->render(geom_w, geom_h, geom_pixmap);
+ if (! geom_pixmap)
+ XSetWindowBackground(blackbox->getXDisplay(), geom_window,
+ texture->color().pixel());
+ else
+ XSetWindowBackgroundPixmap(blackbox->getXDisplay(),
+ geom_window, geom_pixmap);
+
+ XSetWindowBorderWidth(blackbox->getXDisplay(), geom_window,
+ resource.border_width);
+ XSetWindowBorder(blackbox->getXDisplay(), geom_window,
+ resource.border_color.pixel());
-void BScreen::readDatabaseFontSet(const char *rname, const char *rclass,
- XFontSet *fontset) {
- if (! fontset) return;
+ workspacemenu->reconfigure();
+ iconmenu->reconfigure();
- static char *defaultFont = "fixed";
- bool load_default = false;
- std::string s;
+ int remember_sub = rootmenu->getCurrentSubmenu();
+ InitMenu();
+ raiseWindows(0, 0);
+ rootmenu->reconfigure();
+ rootmenu->drawSubmenu(remember_sub);
- if (*fontset)
- XFreeFontSet(getBaseDisplay().getXDisplay(), *fontset);
+ configmenu->reconfigure();
- if (resource.styleconfig.getValue(rname, rclass, s)) {
- if (! (*fontset = createFontSet(s.c_str())))
- load_default = true;
- } else
- load_default = true;
+ toolbar->reconfigure();
- if (load_default) {
- *fontset = createFontSet(defaultFont);
+ slit->reconfigure();
- if (! *fontset) {
- fprintf(stderr, i18n(ScreenSet, ScreenDefaultFontLoadFail,
- "BScreen::LoadStyle(): couldn't load default font.\n"));
- exit(2);
- }
+ std::for_each(workspacesList.begin(), workspacesList.end(),
+ std::mem_fun(&Workspace::reconfigure));
+
+ BlackboxWindowList::iterator iit = iconList.begin();
+ for (; iit != iconList.end(); ++iit) {
+ BlackboxWindow *bw = *iit;
+ if (bw->validateClient())
+ bw->reconfigure();
}
+
+ image_control->timeout();
}
-void BScreen::readDatabaseFont(const char *rname, const char *rclass,
- XFontStruct **font) {
- if (! font) return;
+void BScreen::rereadMenu(void) {
+ InitMenu();
+ raiseWindows(0, 0);
- static char *defaultFont = "fixed";
- bool load_default = false;
- std::string s;
+ rootmenu->reconfigure();
+}
- if (*font)
- XFreeFont(getBaseDisplay().getXDisplay(), *font);
- if (resource.styleconfig.getValue(rname, rclass, s)) {
- if ((*font = XLoadQueryFont(getBaseDisplay().getXDisplay(),
- s.c_str())) == NULL) {
- fprintf(stderr, i18n(ScreenSet, ScreenFontLoadFail,
- "BScreen::LoadStyle(): couldn't load font '%s'\n"),
- s.c_str());
- load_default = true;
- }
- } else
- load_default = true;
+void BScreen::LoadStyle(void) {
+ resource.stylerc = XrmGetFileDatabase(blackbox->getStyleFilename());
+ if (! resource.stylerc)
+ resource.stylerc = XrmGetFileDatabase(DEFAULTSTYLE);
- if (load_default) {
- if ((*font = XLoadQueryFont(getBaseDisplay().getXDisplay(),
- defaultFont)) == NULL) {
- fprintf(stderr, i18n(ScreenSet, ScreenDefaultFontLoadFail,
- "BScreen::LoadStyle(): couldn't load default font.\n"));
- exit(2);
- }
- }
-}
+ XrmValue value;
+ char *value_type;
+ // load fonts/fontsets
+ if (resource.wstyle.fontset)
+ XFreeFontSet(blackbox->getXDisplay(), resource.wstyle.fontset);
+ if (resource.tstyle.fontset)
+ XFreeFontSet(blackbox->getXDisplay(), resource.tstyle.fontset);
+ if (resource.mstyle.f_fontset)
+ XFreeFontSet(blackbox->getXDisplay(), resource.mstyle.f_fontset);
+ if (resource.mstyle.t_fontset)
+ XFreeFontSet(blackbox->getXDisplay(), resource.mstyle.t_fontset);
+ resource.wstyle.fontset = 0;
+ resource.tstyle.fontset = 0;
+ resource.mstyle.f_fontset = 0;
+ resource.mstyle.t_fontset = 0;
+ if (resource.wstyle.font)
+ XFreeFont(blackbox->getXDisplay(), resource.wstyle.font);
+ if (resource.tstyle.font)
+ XFreeFont(blackbox->getXDisplay(), resource.tstyle.font);
+ if (resource.mstyle.f_font)
+ XFreeFont(blackbox->getXDisplay(), resource.mstyle.f_font);
+ if (resource.mstyle.t_font)
+ XFreeFont(blackbox->getXDisplay(), resource.mstyle.t_font);
+ resource.wstyle.font = 0;
+ resource.tstyle.font = 0;
+ resource.mstyle.f_font = 0;
+ resource.mstyle.t_font = 0;
-XFontSet BScreen::createFontSet(const char *fontname) {
- XFontSet fs;
- char **missing, *def = "-";
- int nmissing, pixel_size = 0, buf_size = 0;
- char weight[FONT_ELEMENT_SIZE], slant[FONT_ELEMENT_SIZE];
+ if (i18n.multibyte()) {
+ resource.wstyle.fontset =
+ readDatabaseFontSet("window.font", "Window.Font");
+ resource.tstyle.fontset =
+ readDatabaseFontSet("toolbar.font", "Toolbar.Font");
+ resource.mstyle.t_fontset =
+ readDatabaseFontSet("menu.title.font", "Menu.Title.Font");
+ resource.mstyle.f_fontset =
+ readDatabaseFontSet("menu.frame.font", "Menu.Frame.Font");
+
+ resource.mstyle.t_fontset_extents =
+ XExtentsOfFontSet(resource.mstyle.t_fontset);
+ resource.mstyle.f_fontset_extents =
+ XExtentsOfFontSet(resource.mstyle.f_fontset);
+ resource.tstyle.fontset_extents =
+ XExtentsOfFontSet(resource.tstyle.fontset);
+ resource.wstyle.fontset_extents =
+ XExtentsOfFontSet(resource.wstyle.fontset);
+ } else {
+ resource.wstyle.font =
+ readDatabaseFont("window.font", "Window.Font");
+ resource.tstyle.font =
+ readDatabaseFont("toolbar.font", "Toolbar.Font");
+ resource.mstyle.t_font =
+ readDatabaseFont("menu.title.font", "Menu.Title.Font");
+ resource.mstyle.f_font =
+ readDatabaseFont("menu.frame.font", "Menu.Frame.Font");
+ }
- fs = XCreateFontSet(getBaseDisplay().getXDisplay(),
- fontname, &missing, &nmissing, &def);
- if (fs && (! nmissing)) return fs;
+ // load window config
+ resource.wstyle.t_focus =
+ readDatabaseTexture("window.title.focus", "Window.Title.Focus", "white");
+ resource.wstyle.t_unfocus =
+ readDatabaseTexture("window.title.unfocus",
+ "Window.Title.Unfocus", "black");
+ resource.wstyle.l_focus =
+ readDatabaseTexture("window.label.focus", "Window.Label.Focus", "white" );
+ resource.wstyle.l_unfocus =
+ readDatabaseTexture("window.label.unfocus", "Window.Label.Unfocus",
+ "black");
+ resource.wstyle.h_focus =
+ readDatabaseTexture("window.handle.focus", "Window.Handle.Focus", "white");
+ resource.wstyle.h_unfocus =
+ readDatabaseTexture("window.handle.unfocus",
+ "Window.Handle.Unfocus", "black");
+ resource.wstyle.g_focus =
+ readDatabaseTexture("window.grip.focus", "Window.Grip.Focus", "white");
+ resource.wstyle.g_unfocus =
+ readDatabaseTexture("window.grip.unfocus", "Window.Grip.Unfocus", "black");
+ resource.wstyle.b_focus =
+ readDatabaseTexture("window.button.focus", "Window.Button.Focus", "white");
+ resource.wstyle.b_unfocus =
+ readDatabaseTexture("window.button.unfocus",
+ "Window.Button.Unfocus", "black");
+ resource.wstyle.b_pressed =
+ readDatabaseTexture("window.button.pressed",
+ "Window.Button.Pressed", "black");
+ resource.wstyle.f_focus =
+ readDatabaseColor("window.frame.focusColor",
+ "Window.Frame.FocusColor", "white");
+ resource.wstyle.f_unfocus =
+ readDatabaseColor("window.frame.unfocusColor",
+ "Window.Frame.UnfocusColor", "black");
+ resource.wstyle.l_text_focus =
+ readDatabaseColor("window.label.focus.textColor",
+ "Window.Label.Focus.TextColor", "black");
+ resource.wstyle.l_text_unfocus =
+ readDatabaseColor("window.label.unfocus.textColor",
+ "Window.Label.Unfocus.TextColor", "white");
+ resource.wstyle.b_pic_focus =
+ readDatabaseColor("window.button.focus.picColor",
+ "Window.Button.Focus.PicColor", "black");
+ resource.wstyle.b_pic_unfocus =
+ readDatabaseColor("window.button.unfocus.picColor",
+ "Window.Button.Unfocus.PicColor", "white");
+
+ resource.wstyle.justify = LeftJustify;
+ if (XrmGetResource(resource.stylerc, "window.justify", "Window.Justify",
+ &value_type, &value)) {
+ if (strstr(value.addr, "right") || strstr(value.addr, "Right"))
+ resource.wstyle.justify = RightJustify;
+ else if (strstr(value.addr, "center") || strstr(value.addr, "Center"))
+ resource.wstyle.justify = CenterJustify;
+ }
-#ifdef HAVE_SETLOCALE
- if (! fs) {
- if (nmissing) XFreeStringList(missing);
+ // load toolbar config
+ resource.tstyle.toolbar =
+ readDatabaseTexture("toolbar", "Toolbar", "black");
+ resource.tstyle.label =
+ readDatabaseTexture("toolbar.label", "Toolbar.Label", "black");
+ resource.tstyle.window =
+ readDatabaseTexture("toolbar.windowLabel", "Toolbar.WindowLabel", "black");
+ resource.tstyle.button =
+ readDatabaseTexture("toolbar.button", "Toolbar.Button", "white");
+ resource.tstyle.pressed =
+ readDatabaseTexture("toolbar.button.pressed",
+ "Toolbar.Button.Pressed", "black");
+ resource.tstyle.clock =
+ readDatabaseTexture("toolbar.clock", "Toolbar.Clock", "black");
+ resource.tstyle.l_text =
+ readDatabaseColor("toolbar.label.textColor",
+ "Toolbar.Label.TextColor", "white");
+ resource.tstyle.w_text =
+ readDatabaseColor("toolbar.windowLabel.textColor",
+ "Toolbar.WindowLabel.TextColor", "white");
+ resource.tstyle.c_text =
+ readDatabaseColor("toolbar.clock.textColor",
+ "Toolbar.Clock.TextColor", "white");
+ resource.tstyle.b_pic =
+ readDatabaseColor("toolbar.button.picColor",
+ "Toolbar.Button.PicColor", "black");
+
+ resource.tstyle.justify = LeftJustify;
+ if (XrmGetResource(resource.stylerc, "toolbar.justify",
+ "Toolbar.Justify", &value_type, &value)) {
+ if (strstr(value.addr, "right") || strstr(value.addr, "Right"))
+ resource.tstyle.justify = RightJustify;
+ else if (strstr(value.addr, "center") || strstr(value.addr, "Center"))
+ resource.tstyle.justify = CenterJustify;
+ }
- setlocale(LC_CTYPE, "C");
- fs = XCreateFontSet(getBaseDisplay().getXDisplay(), fontname,
- &missing, &nmissing, &def);
- setlocale(LC_CTYPE, "");
+ // load menu config
+ resource.mstyle.title =
+ readDatabaseTexture("menu.title", "Menu.Title", "white");
+ resource.mstyle.frame =
+ readDatabaseTexture("menu.frame", "Menu.Frame", "black");
+ resource.mstyle.hilite =
+ readDatabaseTexture("menu.hilite", "Menu.Hilite", "white");
+ resource.mstyle.t_text =
+ readDatabaseColor("menu.title.textColor", "Menu.Title.TextColor", "black");
+ resource.mstyle.f_text =
+ readDatabaseColor("menu.frame.textColor", "Menu.Frame.TextColor", "white");
+ resource.mstyle.d_text =
+ readDatabaseColor("menu.frame.disableColor",
+ "Menu.Frame.DisableColor", "black");
+ resource.mstyle.h_text =
+ readDatabaseColor("menu.hilite.textColor",
+ "Menu.Hilite.TextColor", "black");
+
+ resource.mstyle.t_justify = LeftJustify;
+ if (XrmGetResource(resource.stylerc, "menu.title.justify",
+ "Menu.Title.Justify",
+ &value_type, &value)) {
+ if (strstr(value.addr, "right") || strstr(value.addr, "Right"))
+ resource.mstyle.t_justify = RightJustify;
+ else if (strstr(value.addr, "center") || strstr(value.addr, "Center"))
+ resource.mstyle.t_justify = CenterJustify;
}
-#endif // HAVE_SETLOCALE
- if (fs) {
- XFontStruct **fontstructs;
- char **fontnames;
- XFontsOfFontSet(fs, &fontstructs, &fontnames);
- fontname = fontnames[0];
+ resource.mstyle.f_justify = LeftJustify;
+ if (XrmGetResource(resource.stylerc, "menu.frame.justify",
+ "Menu.Frame.Justify",
+ &value_type, &value)) {
+ if (strstr(value.addr, "right") || strstr(value.addr, "Right"))
+ resource.mstyle.f_justify = RightJustify;
+ else if (strstr(value.addr, "center") || strstr(value.addr, "Center"))
+ resource.mstyle.f_justify = CenterJustify;
}
- getFontElement(fontname, weight, FONT_ELEMENT_SIZE,
- "-medium-", "-bold-", "-demibold-", "-regular-", NULL);
- getFontElement(fontname, slant, FONT_ELEMENT_SIZE,
- "-r-", "-i-", "-o-", "-ri-", "-ro-", NULL);
- getFontSize(fontname, &pixel_size);
+ resource.mstyle.bullet = Basemenu::Triangle;
+ if (XrmGetResource(resource.stylerc, "menu.bullet", "Menu.Bullet",
+ &value_type, &value)) {
+ if (! strncasecmp(value.addr, "empty", value.size))
+ resource.mstyle.bullet = Basemenu::Empty;
+ else if (! strncasecmp(value.addr, "square", value.size))
+ resource.mstyle.bullet = Basemenu::Square;
+ else if (! strncasecmp(value.addr, "diamond", value.size))
+ resource.mstyle.bullet = Basemenu::Diamond;
+ }
- if (! strcmp(weight, "*")) strncpy(weight, "medium", FONT_ELEMENT_SIZE);
- if (! strcmp(slant, "*")) strncpy(slant, "r", FONT_ELEMENT_SIZE);
- if (pixel_size < 3) pixel_size = 3;
- else if (pixel_size > 97) pixel_size = 97;
+ resource.mstyle.bullet_pos = Basemenu::Left;
+ if (XrmGetResource(resource.stylerc, "menu.bullet.position",
+ "Menu.Bullet.Position", &value_type, &value)) {
+ if (! strncasecmp(value.addr, "right", value.size))
+ resource.mstyle.bullet_pos = Basemenu::Right;
+ }
- buf_size = strlen(fontname) + (FONT_ELEMENT_SIZE * 2) + 64;
- char *pattern2 = new char[buf_size];
- snprintf(pattern2, buf_size - 1,
- "%s,"
- "-*-*-%s-%s-*-*-%d-*-*-*-*-*-*-*,"
- "-*-*-*-*-*-*-%d-*-*-*-*-*-*-*,*",
- fontname, weight, slant, pixel_size, pixel_size);
- fontname = pattern2;
+ resource.border_color =
+ readDatabaseColor("borderColor", "BorderColor", "black");
- if (nmissing) XFreeStringList(missing);
- if (fs) XFreeFontSet(getBaseDisplay().getXDisplay(), fs);
+ unsigned int uint_value;
- fs = XCreateFontSet(getBaseDisplay().getXDisplay(), fontname,
- &missing, &nmissing, &def);
- delete [] pattern2;
+ // load bevel, border and handle widths
+ resource.handle_width = 6;
+ if (XrmGetResource(resource.stylerc, "handleWidth", "HandleWidth",
+ &value_type, &value) &&
+ sscanf(value.addr, "%u", &uint_value) == 1 &&
+ uint_value <= (getWidth() / 2) && uint_value != 0) {
+ resource.handle_width = uint_value;
+ }
- return fs;
-}
+ resource.border_width = 1;
+ if (XrmGetResource(resource.stylerc, "borderWidth", "BorderWidth",
+ &value_type, &value) &&
+ sscanf(value.addr, "%u", &uint_value) == 1) {
+ resource.border_width = uint_value;
+ }
+ resource.bevel_width = 3;
+ if (XrmGetResource(resource.stylerc, "bevelWidth", "BevelWidth",
+ &value_type, &value) &&
+ sscanf(value.addr, "%u", &uint_value) == 1 &&
+ uint_value <= (getWidth() / 2) && uint_value != 0) {
+ resource.bevel_width = uint_value;
+ }
-void BScreen::setSloppyFocus(bool b) {
- resource.sloppy_focus = b;
- std::ostrstream s;
- s << "session.screen" << getScreenNumber() << ".focusModel" << ends;
- config.setValue(s.str(),
- (resource.sloppy_focus ?
- (resource.auto_raise ? "AutoRaiseSloppyFocus" : "SloppyFocus")
- : "ClickToFocus"));
- s.rdbuf()->freeze(0);
-}
+ resource.frame_width = resource.bevel_width;
+ if (XrmGetResource(resource.stylerc, "frameWidth", "FrameWidth",
+ &value_type, &value) &&
+ sscanf(value.addr, "%u", &uint_value) == 1 &&
+ uint_value <= (getWidth() / 2)) {
+ resource.frame_width = uint_value;
+ }
+ if (XrmGetResource(resource.stylerc, "rootCommand", "RootCommand",
+ &value_type, &value)) {
+ bexec(value.addr, displayString());
+ }
-void BScreen::setAutoRaise(bool a) {
- resource.auto_raise = a;
- std::ostrstream s;
- s << "session.screen" << getScreenNumber() << ".focusModel" << ends;
- config.setValue(s.str(),
- (resource.sloppy_focus ?
- (resource.auto_raise ? "AutoRaiseSloppyFocus" : "SloppyFocus")
- : "ClickToFocus"));
- s.rdbuf()->freeze(0);
+ XrmDestroyDatabase(resource.stylerc);
}
-void BScreen::setImageDither(bool d, bool reconfig) {
- image_control->setDither(d);
- std::ostrstream s;
- s << "session.screen" << getScreenNumber() << ".imageDither" << ends;
- config.setValue(s.str(), imageDither());
- if (reconfig)
- reconfigure();
- s.rdbuf()->freeze(0);
-}
+void BScreen::addIcon(BlackboxWindow *w) {
+ if (! w) return;
+ w->setWorkspace(BSENTINEL);
+ w->setWindowNumber(iconList.size());
-void BScreen::setOpaqueMove(bool o) {
- resource.opaque_move = o;
- std::ostrstream s;
- s << "session.screen" << getScreenNumber() << ".opaqueMove" << ends;
- config.setValue(s.str(), resource.opaque_move);
- s.rdbuf()->freeze(0);
+ iconList.push_back(w);
+
+ const char* title = w->getIconTitle();
+ iconmenu->insert(title);
+ iconmenu->update();
}
-void BScreen::setFullMax(bool f) {
- resource.full_max = f;
- std::ostrstream s;
- s << "session.screen" << getScreenNumber() << ".fullMaximization" << ends;
- config.setValue(s.str(), resource.full_max);
- s.rdbuf()->freeze(0);
-}
+void BScreen::removeIcon(BlackboxWindow *w) {
+ if (! w) return;
+ iconList.remove(w);
-void BScreen::setFocusNew(bool f) {
- resource.focus_new = f;
- std::ostrstream s;
- s << "session.screen" << getScreenNumber() << ".focusNewWindows" << ends;
- config.setValue(s.str(), resource.focus_new);
- s.rdbuf()->freeze(0);
+ iconmenu->remove(w->getWindowNumber());
+ iconmenu->update();
+
+ BlackboxWindowList::iterator it = iconList.begin(),
+ end = iconList.end();
+ for (int i = 0; it != end; ++it)
+ (*it)->setWindowNumber(i++);
}
-void BScreen::setFocusLast(bool f) {
- resource.focus_last = f;
- std::ostrstream s;
- s << "session.screen" << getScreenNumber() << ".focusLastWindow" << ends;
- config.setValue(s.str(), resource.focus_last);
- s.rdbuf()->freeze(0);
+BlackboxWindow *BScreen::getIcon(unsigned int index) {
+ if (index < iconList.size()) {
+ BlackboxWindowList::iterator it = iconList.begin();
+ for (; index > 0; --index, ++it) ; /* increment to index */
+ return *it;
+ }
+
+ return (BlackboxWindow *) 0;
}
-void BScreen::setWindowZones(int z) {
- resource.zones = z;
- std::ostrstream s;
- s << "session.screen" << getScreenNumber() << ".windowZones" << ends;
- config.setValue(s.str(), resource.zones);
- s.rdbuf()->freeze(0);
-}
+unsigned int BScreen::addWorkspace(void) {
+ Workspace *wkspc = new Workspace(this, workspacesList.size());
+ workspacesList.push_back(wkspc);
+ workspacemenu->insert(wkspc->getName(), wkspc->getMenu(),
+ wkspc->getID() + 2);
+ workspacemenu->update();
-void BScreen::setWorkspaceCount(int w) {
- resource.workspaces = w;
- std::ostrstream s;
- s << "session.screen" << getScreenNumber() << ".workspaces" << ends;
- config.setValue(s.str(), resource.workspaces);
- s.rdbuf()->freeze(0);
-}
+ toolbar->reconfigure();
+ updateNetizenWorkspaceCount();
-void BScreen::setPlacementPolicy(int p) {
- resource.placement_policy = p;
- std::ostrstream s;
- s << "session.screen" << getScreenNumber() << ".windowPlacement" << ends;
- const char *placement;
- switch (resource.placement_policy) {
- case CascadePlacement: placement = "CascadePlacement"; break;
- case BestFitPlacement: placement = "BestFitPlacement"; break;
- case ColSmartPlacement: placement = "ColSmartPlacement"; break;
- case UnderMousePlacement: placement = "UnderMousePlacement"; break;
- case ClickMousePlacement: placement = "ClickMousePlacement"; break;
- default:
- case RowSmartPlacement: placement = "RowSmartPlacement"; break;
- }
- config.setValue(s.str(), placement);
- s.rdbuf()->freeze(0);
+ return workspacesList.size();
}
-void BScreen::setEdgeSnapThreshold(int t) {
- resource.edge_snap_threshold = t;
- std::ostrstream s;
- s << "session.screen" << getScreenNumber() << ".edgeSnapThreshold" << ends;
- config.setValue(s.str(), resource.edge_snap_threshold);
- s.rdbuf()->freeze(0);
-}
+unsigned int BScreen::removeLastWorkspace(void) {
+ if (workspacesList.size() == 1)
+ return 1;
+ Workspace *wkspc = workspacesList.back();
-void BScreen::setRowPlacementDirection(int d) {
- resource.row_direction = d;
- std::ostrstream s;
- s << "session.screen" << getScreenNumber() << ".rowPlacementDirection" << ends;
- config.setValue(s.str(),
- resource.row_direction == LeftRight ?
- "LeftToRight" : "RightToLeft");
- s.rdbuf()->freeze(0);
-}
+ if (current_workspace->getID() == wkspc->getID())
+ changeWorkspaceID(current_workspace->getID() - 1);
+ wkspc->removeAll();
-void BScreen::setColPlacementDirection(int d) {
- resource.col_direction = d;
- std::ostrstream s;
- s << "session.screen" << getScreenNumber() << ".colPlacementDirection" << ends;
- config.setValue(s.str(),
- resource.col_direction == TopBottom ?
- "TopToBottom" : "BottomToTop");
- s.rdbuf()->freeze(0);
-}
+ workspacemenu->remove(wkspc->getID() + 2);
+ workspacemenu->update();
+ workspacesList.pop_back();
+ delete wkspc;
-void BScreen::setRootCommand(const char *cmd) {
- if (resource.root_command != NULL)
- delete [] resource.root_command;
- if (cmd != NULL)
- resource.root_command = bstrdup(cmd);
- else
- resource.root_command = NULL;
- // this doesn't save to the Resources config because it can't be changed
- // inside Openbox, and this way we dont add an empty command which would over-
- // ride the styles command when none has been specified
-}
+ toolbar->reconfigure();
+ updateNetizenWorkspaceCount();
-#ifdef HAVE_STRFTIME
-void BScreen::setStrftimeFormat(const char *f) {
- if (resource.strftime_format != NULL)
- delete [] resource.strftime_format;
-
- resource.strftime_format = bstrdup(f);
- std::ostrstream s;
- s << "session.screen" << getScreenNumber() << ".strftimeFormat" << ends;
- config.setValue(s.str(), resource.strftime_format);
- s.rdbuf()->freeze(0);
+ return workspacesList.size();
}
-#else // !HAVE_STRFTIME
-void BScreen::setDateFormat(int f) {
- resource.date_format = f;
- std::ostrstream s;
- s << "session.screen" << getScreenNumber() << ".dateFormat" << ends;
- config.setValue(s.str(), resource.date_format == B_EuropeanDate ?
- "European" : "American");
- s.rdbuf()->freeze(0);
-}
+void BScreen::changeWorkspaceID(unsigned int id) {
+ if (! current_workspace) return;
+ if (id != current_workspace->getID()) {
+ current_workspace->hideAll();
-void BScreen::setClock24Hour(Bool c) {
- resource.clock24hour = c;
- std::ostrstream s;
- s << "session.screen" << getScreenNumber() << ".clockFormat" << ends;
- config.setValue(s.str(), resource.clock24hour ? 24 : 12);
- s.rdbuf()->freeze(0);
-}
-#endif // HAVE_STRFTIME
+ workspacemenu->setItemSelected(current_workspace->getID() + 2, False);
+ if (blackbox->getFocusedWindow() &&
+ blackbox->getFocusedWindow()->getScreen() == this &&
+ (! blackbox->getFocusedWindow()->isStuck())) {
+ current_workspace->setLastFocusedWindow(blackbox->getFocusedWindow());
+ blackbox->setFocusedWindow((BlackboxWindow *) 0);
+ }
-void BScreen::setHideToolbar(bool b) {
- resource.hide_toolbar = b;
- if (resource.hide_toolbar)
- getToolbar()->unMapToolbar();
- else
- getToolbar()->mapToolbar();
- std::ostrstream s;
- s << "session.screen" << getScreenNumber() << ".hideToolbar" << ends;
- config.setValue(s.str(), resource.hide_toolbar ? "True" : "False");
- s.rdbuf()->freeze(0);
-}
+ current_workspace = getWorkspace(id);
+ workspacemenu->setItemSelected(current_workspace->getID() + 2, True);
+ toolbar->redrawWorkspaceLabel(True);
-void BScreen::saveWorkspaceNames() {
- std::ostrstream rc, names;
+ current_workspace->showAll();
- wkspList::iterator it;
- wkspList::iterator last = workspacesList.end() - 1;
- for (it = workspacesList.begin(); it != workspacesList.end(); ++it) {
- names << (*it)->getName();
- if (it != last)
- names << ",";
+ if (resource.focus_last && current_workspace->getLastFocusedWindow()) {
+ XSync(blackbox->getXDisplay(), False);
+ current_workspace->getLastFocusedWindow()->setInputFocus();
+ }
}
- names << ends;
- rc << "session.screen" << getScreenNumber() << ".workspaceNames" << ends;
- config.setValue(rc.str(), names.str());
- rc.rdbuf()->freeze(0);
- names.rdbuf()->freeze(0);
+ updateNetizenCurrentWorkspace();
}
-void BScreen::save() {
- setSloppyFocus(resource.sloppy_focus);
- setAutoRaise(resource.auto_raise);
- setImageDither(imageDither(), false);
- setOpaqueMove(resource.opaque_move);
- setFullMax(resource.full_max);
- setFocusNew(resource.focus_new);
- setFocusLast(resource.focus_last);
- setWindowZones(resource.zones);
- setWorkspaceCount(resource.workspaces);
- setPlacementPolicy(resource.placement_policy);
- setEdgeSnapThreshold(resource.edge_snap_threshold);
- setRowPlacementDirection(resource.row_direction);
- setColPlacementDirection(resource.col_direction);
- setRootCommand(resource.root_command);
-#ifdef HAVE_STRFTIME
- // it deletes the current value before setting the new one, so we have to
- // duplicate the current value.
- std::string s = resource.strftime_format;
- setStrftimeFormat(s.c_str());
-#else // !HAVE_STRFTIME
- setDateFormat(resource.date_format);
- setClock24Hour(resource.clock24hour);
-#endif // HAVE_STRFTIME
- setHideToolbar(resource.hide_toolbar);
-
- toolbar->save();
-#ifdef SLIT
- slit->save();
-#endif // SLIT
-}
-
-
-void BScreen::load() {
- std::ostrstream rscreen, rname, rclass;
- std::string s;
- bool b;
- long l;
- rscreen << "session.screen" << getScreenNumber() << '.' << ends;
-
- rname << rscreen.str() << "hideToolbar" << ends;
- rclass << rscreen.str() << "HideToolbar" << ends;
- if (config.getValue(rname.str(), rclass.str(), b))
- resource.hide_toolbar = b;
- else
- resource.hide_toolbar = false;
- Toolbar *t = getToolbar();
- if (t != NULL) {
- if (resource.hide_toolbar)
- t->unMapToolbar();
- else
- t->mapToolbar();
- }
-
- rname.seekp(0); rclass.seekp(0);
- rname.rdbuf()->freeze(0); rclass.rdbuf()->freeze(0);
- rname << rscreen.str() << "fullMaximization" << ends;
- rclass << rscreen.str() << "FullMaximization" << ends;
- if (config.getValue(rname.str(), rclass.str(), b))
- resource.full_max = b;
- else
- resource.full_max = false;
-
- rname.seekp(0); rclass.seekp(0);
- rname.rdbuf()->freeze(0); rclass.rdbuf()->freeze(0);
- rname << rscreen.str() << "focusNewWindows" << ends;
- rclass << rscreen.str() << "FocusNewWindows" << ends;
- if (config.getValue(rname.str(), rclass.str(), b))
- resource.focus_new = b;
- else
- resource.focus_new = false;
-
- rname.seekp(0); rclass.seekp(0);
- rname.rdbuf()->freeze(0); rclass.rdbuf()->freeze(0);
- rname << rscreen.str() << "focusLastWindow" << ends;
- rclass << rscreen.str() << "FocusLastWindow" << ends;
- if (config.getValue(rname.str(), rclass.str(), b))
- resource.focus_last = b;
- else
- resource.focus_last = false;
-
- rname.seekp(0); rclass.seekp(0);
- rname.rdbuf()->freeze(0); rclass.rdbuf()->freeze(0);
- rname << rscreen.str() << "rowPlacementDirection" << ends;
- rclass << rscreen.str() << "RowPlacementDirection" << ends;
- if (config.getValue(rname.str(), rclass.str(), s)) {
- if (0 == strncasecmp(s.c_str(), "RightToLeft", s.length()))
- resource.row_direction = RightLeft;
- else //if (0 == strncasecmp(s.c_str(), "LeftToRight", s.length()))
- resource.row_direction = LeftRight;
- } else
- resource.row_direction = LeftRight;
-
- rname.seekp(0); rclass.seekp(0);
- rname.rdbuf()->freeze(0); rclass.rdbuf()->freeze(0);
- rname << rscreen.str() << "colPlacementDirection" << ends;
- rclass << rscreen.str() << "ColPlacementDirection" << ends;
- if (config.getValue(rname.str(), rclass.str(), s)) {
- if (0 == strncasecmp(s.c_str(), "BottomToTop", s.length()))
- resource.col_direction = BottomTop;
- else //if (0 == strncasecmp(s.c_str(), "TopToBottom", s.length()))
- resource.col_direction = TopBottom;
- } else
- resource.col_direction = TopBottom;
-
- rname.seekp(0); rclass.seekp(0);
- rname.rdbuf()->freeze(0); rclass.rdbuf()->freeze(0);
- rname << rscreen.str() << "workspaces" << ends;
- rclass << rscreen.str() << "Workspaces" << ends;
- if (config.getValue(rname.str(), rclass.str(), l)) {
- resource.workspaces = l;
- } else
- resource.workspaces = 1;
-
- removeWorkspaceNames();
- rname.seekp(0); rclass.seekp(0);
- rname.rdbuf()->freeze(0); rclass.rdbuf()->freeze(0);
- rname << rscreen.str() << "workspaceNames" << ends;
- rclass << rscreen.str() << "WorkspaceNames" << ends;
- if (config.getValue(rname.str(), rclass.str(), s)) {
- std::string::const_iterator it = s.begin(), end = s.end();
- while(1) {
- std::string::const_iterator tmp = it;// current string.begin()
- it = std::find(tmp, end, ','); // look for comma between tmp and end
- std::string name(tmp, it); // name = s[tmp:it]
- addWorkspaceName(name.c_str());
- if (it == end)
- break;
- ++it;
- }
- }
-
- rname.seekp(0); rclass.seekp(0);
- rname.rdbuf()->freeze(0); rclass.rdbuf()->freeze(0);
- rname << rscreen.str() << "focusModel" << ends;
- rclass << rscreen.str() << "FocusModel" << ends;
- if (config.getValue(rname.str(), rclass.str(), s)) {
- if (0 == strncasecmp(s.c_str(), "ClickToFocus", s.length())) {
- resource.auto_raise = false;
- resource.sloppy_focus = false;
- } else if (0 == strncasecmp(s.c_str(), "AutoRaiseSloppyFocus",
- s.length())) {
- resource.sloppy_focus = true;
- resource.auto_raise = true;
- } else { //if (0 == strncasecmp(s.c_str(), "SloppyFocus", s.length())) {
- resource.sloppy_focus = true;
- resource.auto_raise = false;
- }
- } else {
- resource.sloppy_focus = true;
- resource.auto_raise = false;
- }
-
- rname.seekp(0); rclass.seekp(0);
- rname.rdbuf()->freeze(0); rclass.rdbuf()->freeze(0);
- rname << rscreen.str() << "windowZones" << ends;
- rclass << rscreen.str() << "WindowZones" << ends;
- if (config.getValue(rname.str(), rclass.str(), l))
- resource.zones = (l == 1 || l == 2 || l == 4) ? l : 1;
- else
- resource.zones = 4;
-
- rname.seekp(0); rclass.seekp(0);
- rname.rdbuf()->freeze(0); rclass.rdbuf()->freeze(0);
- rname << rscreen.str() << "windowPlacement" << ends;
- rclass << rscreen.str() << "WindowPlacement" << ends;
- if (config.getValue(rname.str(), rclass.str(), s)) {
- if (0 == strncasecmp(s.c_str(), "RowSmartPlacement", s.length()))
- resource.placement_policy = RowSmartPlacement;
- else if (0 == strncasecmp(s.c_str(), "ColSmartPlacement", s.length()))
- resource.placement_policy = ColSmartPlacement;
- else if (0 == strncasecmp(s.c_str(), "BestFitPlacement", s.length()))
- resource.placement_policy = BestFitPlacement;
- else if (0 == strncasecmp(s.c_str(), "UnderMousePlacement", s.length()))
- resource.placement_policy = UnderMousePlacement;
- else if (0 == strncasecmp(s.c_str(), "ClickMousePlacement", s.length()))
- resource.placement_policy = ClickMousePlacement;
- else //if (0 == strncasecmp(s.c_str(), "CascadePlacement", s.length()))
- resource.placement_policy = CascadePlacement;
- } else
- resource.placement_policy = CascadePlacement;
-
-#ifdef HAVE_STRFTIME
- rname.seekp(0); rclass.seekp(0);
- rname.rdbuf()->freeze(0); rclass.rdbuf()->freeze(0);
- rname << rscreen.str() << "strftimeFormat" << ends;
- rclass << rscreen.str() << "StrftimeFormat" << ends;
-
- if (resource.strftime_format != NULL)
- delete [] resource.strftime_format;
-
- if (config.getValue(rname.str(), rclass.str(), s))
- resource.strftime_format = bstrdup(s.c_str());
- else
- resource.strftime_format = bstrdup("%I:%M %p");
-#else // !HAVE_STRFTIME
- rname.seekp(0); rclass.seekp(0);
- rname.rdbuf()->freeze(0); rclass.rdbuf()->freeze(0);
- rname << rscreen.str() << "dateFormat" << ends;
- rclass << rscreen.str() << "DateFormat" << ends;
- if (config.getValue(rname.str(), rclass.str(), s)) {
- if (strncasecmp(s.c_str(), "European", s.length()))
- resource.date_format = B_EuropeanDate;
- else //if (strncasecmp(s.c_str(), "American", s.length()))
- resource.date_format = B_AmericanDate;
- } else
- resource.date_format = B_AmericanDate;
-
- rname.seekp(0); rclass.seekp(0);
- rname.rdbuf()->freeze(0); rclass.rdbuf()->freeze(0);
- rname << rscreen.str() << "clockFormat" << ends;
- rclass << rscreen.str() << "ClockFormat" << ends;
- if (config.getValue(rname.str(), rclass.str(), l)) {
- if (clock == 24)
- resource.clock24hour = true;
- else if (clock == 12)
- resource.clock24hour = false;
- } else
- resource.clock24hour = false;
-#endif // HAVE_STRFTIME
-
- rname.seekp(0); rclass.seekp(0);
- rname.rdbuf()->freeze(0); rclass.rdbuf()->freeze(0);
- rname << rscreen.str() << "edgeSnapThreshold" << ends;
- rclass << rscreen.str() << "EdgeSnapThreshold" << ends;
- if (config.getValue(rname.str(), rclass.str(), l))
- resource.edge_snap_threshold = l;
- else
- resource.edge_snap_threshold = 4;
-
- rname.seekp(0); rclass.seekp(0);
- rname.rdbuf()->freeze(0); rclass.rdbuf()->freeze(0);
- rname << rscreen.str() << "imageDither" << ends;
- rclass << rscreen.str() << "ImageDither" << ends;
- if (config.getValue(rname.str(), rclass.str(), b))
- image_control->setDither(b);
- else
- image_control->setDither(true);
-
- rname.seekp(0); rclass.seekp(0);
- rname.rdbuf()->freeze(0); rclass.rdbuf()->freeze(0);
- rname << rscreen.str() << "rootCommand" << ends;
- rclass << rscreen.str() << "RootCommand" << ends;
-
- if (resource.root_command != NULL)
- delete [] resource.root_command;
-
- if (config.getValue(rname.str(), rclass.str(), s))
- resource.root_command = bstrdup(s.c_str());
- else
- resource.root_command = NULL;
-
- rname.seekp(0); rclass.seekp(0);
- rname.rdbuf()->freeze(0); rclass.rdbuf()->freeze(0);
- rname << rscreen.str() << "opaqueMove" << ends;
- rclass << rscreen.str() << "OpaqueMove" << ends;
- if (config.getValue(rname.str(), rclass.str(), b))
- resource.opaque_move = b;
- else
- resource.opaque_move = false;
-
- rscreen.rdbuf()->freeze(0);
- rname.rdbuf()->freeze(0); rclass.rdbuf()->freeze(0);
- }
-
- void BScreen::reconfigure(void) {
- load();
- toolbar->load();
-#ifdef SLIT
- slit->load();
-#endif // SLIT
- LoadStyle();
-
- XGCValues gcv;
- unsigned long gc_value_mask = GCForeground;
- if (! i18n.multibyte()) gc_value_mask |= GCFont;
-
- gcv.foreground = WhitePixel(getBaseDisplay().getXDisplay(),
- getScreenNumber());
- gcv.function = GXinvert;
- gcv.subwindow_mode = IncludeInferiors;
- XChangeGC(getBaseDisplay().getXDisplay(), opGC,
- GCForeground | GCFunction | GCSubwindowMode, &gcv);
-
- gcv.foreground = resource.wstyle.l_text_focus.getPixel();
- if (resource.wstyle.font)
- gcv.font = resource.wstyle.font->fid;
- XChangeGC(getBaseDisplay().getXDisplay(), resource.wstyle.l_text_focus_gc,
- gc_value_mask, &gcv);
-
- gcv.foreground = resource.wstyle.l_text_unfocus.getPixel();
- XChangeGC(getBaseDisplay().getXDisplay(), resource.wstyle.l_text_unfocus_gc,
- gc_value_mask, &gcv);
-
- gcv.foreground = resource.wstyle.b_pic_focus.getPixel();
- XChangeGC(getBaseDisplay().getXDisplay(), resource.wstyle.b_pic_focus_gc,
- GCForeground, &gcv);
-
- gcv.foreground = resource.wstyle.b_pic_unfocus.getPixel();
- XChangeGC(getBaseDisplay().getXDisplay(), resource.wstyle.b_pic_unfocus_gc,
- GCForeground, &gcv);
-
- gcv.foreground = resource.mstyle.t_text.getPixel();
- if (resource.mstyle.t_font)
- gcv.font = resource.mstyle.t_font->fid;
- XChangeGC(getBaseDisplay().getXDisplay(), resource.mstyle.t_text_gc,
- gc_value_mask, &gcv);
-
- gcv.foreground = resource.mstyle.f_text.getPixel();
- if (resource.mstyle.f_font)
- gcv.font = resource.mstyle.f_font->fid;
- XChangeGC(getBaseDisplay().getXDisplay(), resource.mstyle.f_text_gc,
- gc_value_mask, &gcv);
-
- gcv.foreground = resource.mstyle.h_text.getPixel();
- XChangeGC(getBaseDisplay().getXDisplay(), resource.mstyle.h_text_gc,
- gc_value_mask, &gcv);
-
- gcv.foreground = resource.mstyle.d_text.getPixel();
- XChangeGC(getBaseDisplay().getXDisplay(), resource.mstyle.d_text_gc,
- gc_value_mask, &gcv);
-
- gcv.foreground = resource.mstyle.hilite.getColor()->getPixel();
- XChangeGC(getBaseDisplay().getXDisplay(), resource.mstyle.hilite_gc,
- gc_value_mask, &gcv);
-
- gcv.foreground = resource.tstyle.l_text.getPixel();
- if (resource.tstyle.font)
- gcv.font = resource.tstyle.font->fid;
- XChangeGC(getBaseDisplay().getXDisplay(), resource.tstyle.l_text_gc,
- gc_value_mask, &gcv);
-
- gcv.foreground = resource.tstyle.w_text.getPixel();
- XChangeGC(getBaseDisplay().getXDisplay(), resource.tstyle.w_text_gc,
- gc_value_mask, &gcv);
-
- gcv.foreground = resource.tstyle.c_text.getPixel();
- XChangeGC(getBaseDisplay().getXDisplay(), resource.tstyle.c_text_gc,
- gc_value_mask, &gcv);
-
- gcv.foreground = resource.tstyle.b_pic.getPixel();
- XChangeGC(getBaseDisplay().getXDisplay(), resource.tstyle.b_pic_gc,
- gc_value_mask, &gcv);
-
- const char *s = i18n(ScreenSet, ScreenPositionLength,
- "0: 0000 x 0: 0000");
- int l = strlen(s);
-
- if (i18n.multibyte()) {
- XRectangle ink, logical;
- XmbTextExtents(resource.wstyle.fontset, s, l, &ink, &logical);
- geom_w = logical.width;
-
- geom_h = resource.wstyle.fontset_extents->max_ink_extent.height;
- } else {
- geom_w = XTextWidth(resource.wstyle.font, s, l);
- geom_h = resource.wstyle.font->ascent +
- resource.wstyle.font->descent;
- }
-
- geom_w += (resource.bevel_width * 2);
- geom_h += (resource.bevel_width * 2);
+void BScreen::manageWindow(Window w) {
+ new BlackboxWindow(blackbox, w, this);
- Pixmap tmp = geom_pixmap;
- if (resource.wstyle.l_focus.getTexture() & BImage_ParentRelative) {
- if (resource.wstyle.t_focus.getTexture() ==
- (BImage_Flat | BImage_Solid)) {
- geom_pixmap = None;
- XSetWindowBackground(getBaseDisplay().getXDisplay(), geom_window,
- resource.wstyle.t_focus.getColor()->getPixel());
- } else {
- geom_pixmap = image_control->renderImage(geom_w, geom_h,
- &resource.wstyle.t_focus);
- XSetWindowBackgroundPixmap(getBaseDisplay().getXDisplay(),
- geom_window, geom_pixmap);
- }
- } else {
- if (resource.wstyle.l_focus.getTexture() ==
- (BImage_Flat | BImage_Solid)) {
- geom_pixmap = None;
- XSetWindowBackground(getBaseDisplay().getXDisplay(), geom_window,
- resource.wstyle.l_focus.getColor()->getPixel());
- } else {
- geom_pixmap = image_control->renderImage(geom_w, geom_h,
- &resource.wstyle.l_focus);
- XSetWindowBackgroundPixmap(getBaseDisplay().getXDisplay(),
- geom_window, geom_pixmap);
- }
- }
- if (tmp) image_control->removeImage(tmp);
-
- XSetWindowBorderWidth(getBaseDisplay().getXDisplay(), geom_window,
- resource.border_width);
- XSetWindowBorder(getBaseDisplay().getXDisplay(), geom_window,
- resource.border_color.getPixel());
-
- workspacemenu->reconfigure();
- iconmenu->reconfigure();
-
- {
- int remember_sub = rootmenu->getCurrentSubmenu();
- InitMenu();
- raiseWindows(0, 0);
- rootmenu->reconfigure();
- rootmenu->drawSubmenu(remember_sub);
- }
+ BlackboxWindow *win = blackbox->searchWindow(w);
+ if (! win)
+ return;
- configmenu->reconfigure();
+ windowList.push_back(win);
- toolbar->reconfigure();
+ XMapRequestEvent mre;
+ mre.window = w;
+ win->restoreAttributes();
+ win->mapRequestEvent(&mre);
+}
-#ifdef SLIT
- slit->reconfigure();
-#endif // SLIT
- std::for_each(workspacesList.begin(), workspacesList.end(),
- std::mem_fun(&Workspace::reconfigure));
+void BScreen::unmanageWindow(BlackboxWindow *w, bool remap) {
+ w->restore(remap);
- for (winList::iterator it = iconList.begin(); it != iconList.end(); ++it)
- if ((*it)->validateClient())
- (*it)->reconfigure();
+ if (w->getWorkspaceNumber() != BSENTINEL &&
+ w->getWindowNumber() != BSENTINEL)
+ getWorkspace(w->getWorkspaceNumber())->removeWindow(w);
+ else if (w->isIconic())
+ removeIcon(w);
- image_control->timeout();
- }
+ windowList.remove(w);
+ if (blackbox->getFocusedWindow() == w)
+ blackbox->setFocusedWindow((BlackboxWindow *) 0);
- void BScreen::rereadMenu(void) {
- InitMenu();
- raiseWindows(0, 0);
+ removeNetizen(w->getClientWindow());
- rootmenu->reconfigure();
- }
+ delete w;
+}
- void BScreen::removeWorkspaceNames(void) {
- workspaceNames.clear();
- }
+void BScreen::addNetizen(Netizen *n) {
+ netizenList.push_back(n);
+ n->sendWorkspaceCount();
+ n->sendCurrentWorkspace();
- void BScreen::LoadStyle(void) {
- Resource &conf = resource.styleconfig;
+ WorkspaceList::iterator it = workspacesList.begin();
+ const WorkspaceList::iterator end = workspacesList.end();
+ for (; it != end; ++it)
+ (*it)->sendWindowList(*n);
- const char *sfile = openbox.getStyleFilename();
- bool loaded = false;
- if (sfile != NULL) {
- conf.setFile(sfile);
- loaded = conf.load();
- }
- if (!loaded) {
- conf.setFile(DEFAULTSTYLE);
- if (!conf.load()) {
- fprintf(stderr, i18n(ScreenSet, ScreenDefaultStyleLoadFail,
- "BScreen::LoadStyle(): couldn't load "
- "default style.\n"));
- exit(2);
- }
- }
+ Window f = ((blackbox->getFocusedWindow()) ?
+ blackbox->getFocusedWindow()->getClientWindow() : None);
+ n->sendWindowFocus(f);
+}
- std::string s;
- long l;
-
- // load fonts/fontsets
-
- if (i18n.multibyte()) {
- readDatabaseFontSet("window.font", "Window.Font",
- &resource.wstyle.fontset);
- readDatabaseFontSet("toolbar.font", "Toolbar.Font",
- &resource.tstyle.fontset);
- readDatabaseFontSet("menu.title.font", "Menu.Title.Font",
- &resource.mstyle.t_fontset);
- readDatabaseFontSet("menu.frame.font", "Menu.Frame.Font",
- &resource.mstyle.f_fontset);
-
- resource.mstyle.t_fontset_extents =
- XExtentsOfFontSet(resource.mstyle.t_fontset);
- resource.mstyle.f_fontset_extents =
- XExtentsOfFontSet(resource.mstyle.f_fontset);
- resource.tstyle.fontset_extents =
- XExtentsOfFontSet(resource.tstyle.fontset);
- resource.wstyle.fontset_extents =
- XExtentsOfFontSet(resource.wstyle.fontset);
- } else {
- readDatabaseFont("window.font", "Window.Font",
- &resource.wstyle.font);
- readDatabaseFont("menu.title.font", "Menu.Title.Font",
- &resource.mstyle.t_font);
- readDatabaseFont("menu.frame.font", "Menu.Frame.Font",
- &resource.mstyle.f_font);
- readDatabaseFont("toolbar.font", "Toolbar.Font",
- &resource.tstyle.font);
- }
- // load window config
- readDatabaseTexture("window.title.focus", "Window.Title.Focus",
- &resource.wstyle.t_focus,
- WhitePixel(getBaseDisplay().getXDisplay(),
- getScreenNumber()));
- readDatabaseTexture("window.title.unfocus", "Window.Title.Unfocus",
- &resource.wstyle.t_unfocus,
- BlackPixel(getBaseDisplay().getXDisplay(),
- getScreenNumber()));
- readDatabaseTexture("window.label.focus", "Window.Label.Focus",
- &resource.wstyle.l_focus,
- WhitePixel(getBaseDisplay().getXDisplay(),
- getScreenNumber()));
- readDatabaseTexture("window.label.unfocus", "Window.Label.Unfocus",
- &resource.wstyle.l_unfocus,
- BlackPixel(getBaseDisplay().getXDisplay(),
- getScreenNumber()));
- readDatabaseTexture("window.handle.focus", "Window.Handle.Focus",
- &resource.wstyle.h_focus,
- WhitePixel(getBaseDisplay().getXDisplay(),
- getScreenNumber()));
- readDatabaseTexture("window.handle.unfocus", "Window.Handle.Unfocus",
- &resource.wstyle.h_unfocus,
- BlackPixel(getBaseDisplay().getXDisplay(),
- getScreenNumber()));
- readDatabaseTexture("window.grip.focus", "Window.Grip.Focus",
- &resource.wstyle.g_focus,
- WhitePixel(getBaseDisplay().getXDisplay(),
- getScreenNumber()));
- readDatabaseTexture("window.grip.unfocus", "Window.Grip.Unfocus",
- &resource.wstyle.g_unfocus,
- BlackPixel(getBaseDisplay().getXDisplay(),
- getScreenNumber()));
- readDatabaseTexture("window.button.focus", "Window.Button.Focus",
- &resource.wstyle.b_focus,
- WhitePixel(getBaseDisplay().getXDisplay(),
- getScreenNumber()));
- readDatabaseTexture("window.button.unfocus", "Window.Button.Unfocus",
- &resource.wstyle.b_unfocus,
- BlackPixel(getBaseDisplay().getXDisplay(),
- getScreenNumber()));
- readDatabaseTexture("window.button.pressed", "Window.Button.Pressed",
- &resource.wstyle.b_pressed,
- BlackPixel(getBaseDisplay().getXDisplay(),
- getScreenNumber()));
- readDatabaseColor("window.frame.focusColor",
- "Window.Frame.FocusColor",
- &resource.wstyle.f_focus,
- WhitePixel(getBaseDisplay().getXDisplay(),
- getScreenNumber()));
- readDatabaseColor("window.frame.unfocusColor",
- "Window.Frame.UnfocusColor",
- &resource.wstyle.f_unfocus,
- BlackPixel(getBaseDisplay().getXDisplay(),
- getScreenNumber()));
- readDatabaseColor("window.label.focus.textColor",
- "Window.Label.Focus.TextColor",
- &resource.wstyle.l_text_focus,
- BlackPixel(getBaseDisplay().getXDisplay(),
- getScreenNumber()));
- readDatabaseColor("window.label.unfocus.textColor",
- "Window.Label.Unfocus.TextColor",
- &resource.wstyle.l_text_unfocus,
- WhitePixel(getBaseDisplay().getXDisplay(),
- getScreenNumber()));
- readDatabaseColor("window.button.focus.picColor",
- "Window.Button.Focus.PicColor",
- &resource.wstyle.b_pic_focus,
- BlackPixel(getBaseDisplay().getXDisplay(),
- getScreenNumber()));
- readDatabaseColor("window.button.unfocus.picColor",
- "Window.Button.Unfocus.PicColor",
- &resource.wstyle.b_pic_unfocus,
- WhitePixel(getBaseDisplay().getXDisplay(),
- getScreenNumber()));
-
- if (conf.getValue("window.justify", "Window.Justify", s)) {
- if (0 == strncasecmp(s.c_str(), "right", s.length()))
- resource.wstyle.justify = BScreen::RightJustify;
- else if (0 == strncasecmp(s.c_str(), "center", s.length()))
- resource.wstyle.justify = BScreen::CenterJustify;
- else
- resource.wstyle.justify = BScreen::LeftJustify;
- } else
- resource.wstyle.justify = BScreen::LeftJustify;
-
- // load toolbar config
- readDatabaseTexture("toolbar", "Toolbar",
- &resource.tstyle.toolbar,
- BlackPixel(getBaseDisplay().getXDisplay(),
- getScreenNumber()));
- readDatabaseTexture("toolbar.label", "Toolbar.Label",
- &resource.tstyle.label,
- BlackPixel(getBaseDisplay().getXDisplay(),
- getScreenNumber()));
- readDatabaseTexture("toolbar.windowLabel", "Toolbar.WindowLabel",
- &resource.tstyle.window,
- BlackPixel(getBaseDisplay().getXDisplay(),
- getScreenNumber()));
- readDatabaseTexture("toolbar.button", "Toolbar.Button",
- &resource.tstyle.button,
- WhitePixel(getBaseDisplay().getXDisplay(),
- getScreenNumber()));
- readDatabaseTexture("toolbar.button.pressed", "Toolbar.Button.Pressed",
- &resource.tstyle.pressed,
- BlackPixel(getBaseDisplay().getXDisplay(),
- getScreenNumber()));
- readDatabaseTexture("toolbar.clock", "Toolbar.Clock",
- &resource.tstyle.clock,
- BlackPixel(getBaseDisplay().getXDisplay(),
- getScreenNumber()));
- readDatabaseColor("toolbar.label.textColor", "Toolbar.Label.TextColor",
- &resource.tstyle.l_text,
- WhitePixel(getBaseDisplay().getXDisplay(),
- getScreenNumber()));
- readDatabaseColor("toolbar.windowLabel.textColor",
- "Toolbar.WindowLabel.TextColor",
- &resource.tstyle.w_text,
- WhitePixel(getBaseDisplay().getXDisplay(),
- getScreenNumber()));
- readDatabaseColor("toolbar.clock.textColor", "Toolbar.Clock.TextColor",
- &resource.tstyle.c_text,
- WhitePixel(getBaseDisplay().getXDisplay(),
- getScreenNumber()));
- readDatabaseColor("toolbar.button.picColor", "Toolbar.Button.PicColor",
- &resource.tstyle.b_pic,
- BlackPixel(getBaseDisplay().getXDisplay(),
- getScreenNumber()));
-
- if (conf.getValue("toolbar.justify", "Toolbar.Justify", s)) {
- if (0 == strncasecmp(s.c_str(), "right", s.length()))
- resource.tstyle.justify = BScreen::RightJustify;
- else if (0 == strncasecmp(s.c_str(), "center", s.length()))
- resource.tstyle.justify = BScreen::CenterJustify;
- else
- resource.tstyle.justify = BScreen::LeftJustify;
- } else
- resource.tstyle.justify = BScreen::LeftJustify;
-
- // load menu config
- readDatabaseTexture("menu.title", "Menu.Title",
- &resource.mstyle.title,
- WhitePixel(getBaseDisplay().getXDisplay(),
- getScreenNumber()));
- readDatabaseTexture("menu.frame", "Menu.Frame",
- &resource.mstyle.frame,
- BlackPixel(getBaseDisplay().getXDisplay(),
- getScreenNumber()));
- readDatabaseTexture("menu.hilite", "Menu.Hilite",
- &resource.mstyle.hilite,
- WhitePixel(getBaseDisplay().getXDisplay(),
- getScreenNumber()));
- readDatabaseColor("menu.title.textColor", "Menu.Title.TextColor",
- &resource.mstyle.t_text,
- BlackPixel(getBaseDisplay().getXDisplay(),
- getScreenNumber()));
- readDatabaseColor("menu.frame.textColor", "Menu.Frame.TextColor",
- &resource.mstyle.f_text,
- WhitePixel(getBaseDisplay().getXDisplay(),
- getScreenNumber()));
- readDatabaseColor("menu.frame.disableColor", "Menu.Frame.DisableColor",
- &resource.mstyle.d_text,
- BlackPixel(getBaseDisplay().getXDisplay(),
- getScreenNumber()));
- readDatabaseColor("menu.hilite.textColor", "Menu.Hilite.TextColor",
- &resource.mstyle.h_text,
- BlackPixel(getBaseDisplay().getXDisplay(),
- getScreenNumber()));
-
- if (conf.getValue("menu.title.justify", "Menu.Title.Justify", s)) {
- if (0 == strncasecmp(s.c_str(), "right", s.length()))
- resource.mstyle.t_justify = BScreen::RightJustify;
- else if (0 == strncasecmp(s.c_str(), "center", s.length()))
- resource.mstyle.t_justify = BScreen::CenterJustify;
- else
- resource.mstyle.t_justify = BScreen::LeftJustify;
- } else
- resource.mstyle.t_justify = BScreen::LeftJustify;
-
- if (conf.getValue("menu.frame.justify", "Menu.Frame.Justify", s)) {
- if (0 == strncasecmp(s.c_str(), "right", s.length()))
- resource.mstyle.f_justify = BScreen::RightJustify;
- else if (0 == strncasecmp(s.c_str(), "center", s.length()))
- resource.mstyle.f_justify = BScreen::CenterJustify;
- else
- resource.mstyle.f_justify = BScreen::LeftJustify;
- } else
- resource.mstyle.f_justify = BScreen::LeftJustify;
-
- if (conf.getValue("menu.bullet", "Menu.Bullet", s)) {
- if (0 == strncasecmp(s.c_str(), "empty", s.length()))
- resource.mstyle.bullet = Basemenu::Empty;
- else if (0 == strncasecmp(s.c_str(), "square", s.length()))
- resource.mstyle.bullet = Basemenu::Square;
- else if (0 == strncasecmp(s.c_str(), "diamond", s.length()))
- resource.mstyle.bullet = Basemenu::Diamond;
- else
- resource.mstyle.bullet = Basemenu::Triangle;
- } else
- resource.mstyle.bullet = Basemenu::Triangle;
-
- if (conf.getValue("menu.bullet.position", "Menu.Bullet.Position", s)) {
- if (0 == strncasecmp(s.c_str(), "right", s.length()))
- resource.mstyle.bullet_pos = Basemenu::Right;
- else
- resource.mstyle.bullet_pos = Basemenu::Left;
- } else
- resource.mstyle.bullet_pos = Basemenu::Left;
-
- readDatabaseColor("borderColor", "BorderColor", &resource.border_color,
- BlackPixel(getBaseDisplay().getXDisplay(),
- getScreenNumber()));
-
- // load bevel, border and handle widths
- if (conf.getValue("handleWidth", "HandleWidth", l)) {
- if (l <= (signed)size().w() / 2 && l != 0)
- resource.handle_width = l;
- else
- resource.handle_width = 6;
- } else
- resource.handle_width = 6;
-
- if (conf.getValue("borderWidth", "BorderWidth", l))
- resource.border_width = l;
- else
- resource.border_width = 1;
-
- if (conf.getValue("bevelWidth", "BevelWidth", l)) {
- if (l <= (signed)size().w() / 2 && l != 0)
- resource.bevel_width = l;
- else
- resource.bevel_width = 3;
- } else
- resource.bevel_width = 3;
-
- if (conf.getValue("frameWidth", "FrameWidth", l)) {
- if (l <= (signed)size().w() / 2)
- resource.frame_width = l;
- else
- resource.frame_width = resource.bevel_width;
- } else
- resource.frame_width = resource.bevel_width;
-
- const char *cmd = resource.root_command;
- if (cmd != NULL || conf.getValue("rootCommand", "RootCommand", s)) {
- if (cmd == NULL)
- cmd = s.c_str(); // not specified by the screen, so use the one from the
- // style file
-#ifndef __EMX__
- char displaystring[MAXPATHLEN];
- sprintf(displaystring, "DISPLAY=%s",
- DisplayString(getBaseDisplay().getXDisplay()));
- sprintf(displaystring + strlen(displaystring) - 1, "%d",
- getScreenNumber());
-
- bexec(cmd, displaystring);
-#else // __EMX__
- spawnlp(P_NOWAIT, "cmd.exe", "cmd.exe", "/c", cmd, NULL);
-#endif // !__EMX__
+void BScreen::removeNetizen(Window w) {
+ NetizenList::iterator it = netizenList.begin();
+ for (; it != netizenList.end(); ++it) {
+ if ((*it)->getWindowID() == w) {
+ delete *it;
+ netizenList.erase(it);
+ break;
}
}
+}
- void BScreen::addIcon(OpenboxWindow *w) {
- if (! w) return;
-
- w->setWorkspace(-1);
- w->setWindowNumber(iconList.size());
-
- iconList.push_back(w);
-
- iconmenu->insert((const char **) w->getIconTitle());
- iconmenu->update();
- }
-
-
- void BScreen::removeIcon(OpenboxWindow *w) {
- if (! w) return;
-
- iconList.remove(w);
-
- iconmenu->remove(w->getWindowNumber());
- iconmenu->update();
-
- winList::iterator it = iconList.begin();
- for (int i = 0; it != iconList.end(); ++it, ++i)
- (*it)->setWindowNumber(i);
- }
-
-
- OpenboxWindow *BScreen::getIcon(int index) {
- if (index < 0 || index >= (signed)iconList.size())
- return (OpenboxWindow *) 0;
-
- winList::iterator it = iconList.begin();
- for (; index > 0; --index, ++it); // increment to index
- return *it;
- }
+void BScreen::updateNetizenCurrentWorkspace(void) {
+ std::for_each(netizenList.begin(), netizenList.end(),
+ std::mem_fun(&Netizen::sendCurrentWorkspace));
+}
- int BScreen::addWorkspace(void) {
- Workspace *wkspc = new Workspace(*this, workspacesList.size());
- workspacesList.push_back(wkspc);
- setWorkspaceCount(workspaceCount()+1);
- saveWorkspaceNames();
+void BScreen::updateNetizenWorkspaceCount(void) {
+ std::for_each(netizenList.begin(), netizenList.end(),
+ std::mem_fun(&Netizen::sendWorkspaceCount));
+}
- workspacemenu->insert(wkspc->getName(), wkspc->getMenu(),
- wkspc->getWorkspaceID() + 2);
- workspacemenu->update();
- toolbar->reconfigure();
+void BScreen::updateNetizenWindowFocus(void) {
+ Window f = ((blackbox->getFocusedWindow()) ?
+ blackbox->getFocusedWindow()->getClientWindow() : None);
+ NetizenList::iterator it = netizenList.begin();
+ for (; it != netizenList.end(); ++it)
+ (*it)->sendWindowFocus(f);
+}
- updateNetizenWorkspaceCount();
- return workspacesList.size();
+void BScreen::updateNetizenWindowAdd(Window w, unsigned long p) {
+ NetizenList::iterator it = netizenList.begin();
+ for (; it != netizenList.end(); ++it) {
+ (*it)->sendWindowAdd(w, p);
}
+}
- int BScreen::removeLastWorkspace(void) {
- if (workspacesList.size() == 1)
- return 0;
-
- Workspace *wkspc = workspacesList.back();
-
- if (current_workspace->getWorkspaceID() == wkspc->getWorkspaceID())
- changeWorkspaceID(current_workspace->getWorkspaceID() - 1);
-
- wkspc->removeAll();
-
- workspacemenu->remove(wkspc->getWorkspaceID() + 2);
- workspacemenu->update();
-
- workspacesList.pop_back();
- delete wkspc;
-
- setWorkspaceCount(workspaceCount()-1);
- saveWorkspaceNames();
-
- toolbar->reconfigure();
+void BScreen::updateNetizenWindowDel(Window w) {
+ NetizenList::iterator it = netizenList.begin();
+ for (; it != netizenList.end(); ++it)
+ (*it)->sendWindowDel(w);
+}
- updateNetizenWorkspaceCount();
-
- return workspacesList.size();
- }
+void BScreen::updateNetizenWindowRaise(Window w) {
+ NetizenList::iterator it = netizenList.begin();
+ for (; it != netizenList.end(); ++it)
+ (*it)->sendWindowRaise(w);
+}
- void BScreen::changeWorkspaceID(int id) {
- if (! current_workspace) return;
- if (id != current_workspace->getWorkspaceID()) {
- current_workspace->hideAll();
+void BScreen::updateNetizenWindowLower(Window w) {
+ NetizenList::iterator it = netizenList.begin();
+ for (; it != netizenList.end(); ++it)
+ (*it)->sendWindowLower(w);
+}
- workspacemenu->setItemSelected(current_workspace->getWorkspaceID() + 2,
- False);
- OpenboxWindow *fw = openbox.focusedWindow();
- if (fw && fw->getScreen() == this)
- openbox.focusWindow(0);
+void BScreen::updateNetizenConfigNotify(XEvent *e) {
+ NetizenList::iterator it = netizenList.begin();
+ for (; it != netizenList.end(); ++it)
+ (*it)->sendConfigNotify(e);
+}
- current_workspace = getWorkspace(id);
- workspacemenu->setItemSelected(current_workspace->getWorkspaceID() + 2,
- True);
- toolbar->redrawWorkspaceLabel(True);
+void BScreen::raiseWindows(Window *workspace_stack, unsigned int num) {
+ // XXX: why 13??
+ Window *session_stack = new
+ Window[(num + workspacesList.size() + rootmenuList.size() + 13)];
+ unsigned int i = 0, k = num;
- current_workspace->showAll();
+ XRaiseWindow(blackbox->getXDisplay(), iconmenu->getWindowID());
+ *(session_stack + i++) = iconmenu->getWindowID();
- if (resource.focus_last && current_workspace->lastFocusedWindow()) {
- XSync(openbox.getXDisplay(), False);
- current_workspace->lastFocusedWindow()->setInputFocus();
- }
- }
+ WorkspaceList::iterator wit = workspacesList.begin();
+ const WorkspaceList::iterator w_end = workspacesList.end();
+ for (; wit != w_end; ++wit)
+ *(session_stack + i++) = (*wit)->getMenu()->getWindowID();
- updateNetizenCurrentWorkspace();
- }
+ *(session_stack + i++) = workspacemenu->getWindowID();
+ *(session_stack + i++) = configmenu->getFocusmenu()->getWindowID();
+ *(session_stack + i++) = configmenu->getPlacementmenu()->getWindowID();
+ *(session_stack + i++) = configmenu->getWindowID();
- void BScreen::addNetizen(Netizen *n) {
- netizenList.push_back(n);
+ *(session_stack + i++) = slit->getMenu()->getDirectionmenu()->getWindowID();
+ *(session_stack + i++) = slit->getMenu()->getPlacementmenu()->getWindowID();
+ *(session_stack + i++) = slit->getMenu()->getWindowID();
- n->sendWorkspaceCount();
- n->sendCurrentWorkspace();
+ *(session_stack + i++) =
+ toolbar->getMenu()->getPlacementmenu()->getWindowID();
+ *(session_stack + i++) = toolbar->getMenu()->getWindowID();
- wkspList::iterator it;
- for (it = workspacesList.begin(); it != workspacesList.end(); ++it) {
- for (int i = 0; i < (*it)->getCount(); i++)
- n->sendWindowAdd((*it)->getWindow(i)->getClientWindow(),
- (*it)->getWorkspaceID());
- }
+ RootmenuList::iterator rit = rootmenuList.begin();
+ for (; rit != rootmenuList.end(); ++rit)
+ *(session_stack + i++) = (*rit)->getWindowID();
+ *(session_stack + i++) = rootmenu->getWindowID();
- Window f = ((openbox.focusedWindow()) ?
- openbox.focusedWindow()->getClientWindow() : None);
- n->sendWindowFocus(f);
- }
+ if (toolbar->isOnTop())
+ *(session_stack + i++) = toolbar->getWindowID();
+ if (slit->isOnTop())
+ *(session_stack + i++) = slit->getWindowID();
- void BScreen::removeNetizen(Window w) {
- netList::iterator it;
+ while (k--)
+ *(session_stack + i++) = *(workspace_stack + k);
- for (it = netizenList.begin(); it != netizenList.end(); ++it)
- if ((*it)->getWindowID() == w) {
- Netizen *tmp = *it;
- netizenList.erase(it);
- delete tmp;
- break;
- }
- }
+ XRestackWindows(blackbox->getXDisplay(), session_stack, i);
+ delete [] session_stack;
+}
- void BScreen::updateNetizenCurrentWorkspace(void) {
- netList::iterator it;
- for (it = netizenList.begin(); it != netizenList.end(); ++it)
- (*it)->sendCurrentWorkspace();
- }
+#ifdef HAVE_STRFTIME
+void BScreen::saveStrftimeFormat(const string& format) {
+ resource.strftime_format = format;
+}
+#endif // HAVE_STRFTIME
- void BScreen::updateNetizenWorkspaceCount(void) {
- netList::iterator it;
- for (it = netizenList.begin(); it != netizenList.end(); ++it)
- (*it)->sendWorkspaceCount();
- }
+void BScreen::addWorkspaceName(const string& name) {
+ workspaceNames.push_back(name);
+}
- void BScreen::updateNetizenWindowFocus(void) {
- Window f = ((openbox.focusedWindow()) ?
- openbox.focusedWindow()->getClientWindow() : None);
- netList::iterator it;
- for (it = netizenList.begin(); it != netizenList.end(); ++it)
- (*it)->sendWindowFocus(f);
- }
+/*
+ * I would love to kill this function and the accompanying workspaceNames
+ * list. However, we have a chicken and egg situation. The names are read
+ * in during load_rc() which happens before the workspaces are created.
+ * The current solution is to read the names into a list, then use the list
+ * later for constructing the workspaces. It is only used during initial
+ * BScreen creation.
+ */
+const string BScreen::getNameOfWorkspace(unsigned int id) {
+ if (id < workspaceNames.size())
+ return workspaceNames[id];
+ return string("");
+}
- void BScreen::updateNetizenWindowAdd(Window w, unsigned long p) {
- netList::iterator it;
- for (it = netizenList.begin(); it != netizenList.end(); ++it)
- (*it)->sendWindowAdd(w, p);
- }
+void BScreen::reassociateWindow(BlackboxWindow *w, unsigned int wkspc_id,
+ bool ignore_sticky) {
+ if (! w) return;
- void BScreen::updateNetizenWindowDel(Window w) {
- netList::iterator it;
- for (it = netizenList.begin(); it != netizenList.end(); ++it)
- (*it)->sendWindowDel(w);
- }
+ if (wkspc_id == BSENTINEL)
+ wkspc_id = current_workspace->getID();
+ if (w->getWorkspaceNumber() == wkspc_id)
+ return;
- void BScreen::updateNetizenWindowRaise(Window w) {
- netList::iterator it;
- for (it = netizenList.begin(); it != netizenList.end(); ++it)
- (*it)->sendWindowRaise(w);
+ if (w->isIconic()) {
+ removeIcon(w);
+ getWorkspace(wkspc_id)->addWindow(w);
+ } else if (ignore_sticky || ! w->isStuck()) {
+ getWorkspace(w->getWorkspaceNumber())->removeWindow(w);
+ getWorkspace(wkspc_id)->addWindow(w);
}
+}
- void BScreen::updateNetizenWindowLower(Window w) {
- netList::iterator it;
- for (it = netizenList.begin(); it != netizenList.end(); ++it)
- (*it)->sendWindowLower(w);
+void BScreen::propagateWindowName(const BlackboxWindow *bw) {
+ if (bw->isIconic()) {
+ iconmenu->changeItemLabel(bw->getWindowNumber(), bw->getIconTitle());
+ iconmenu->update();
}
+ else {
+ Clientmenu *clientmenu = getWorkspace(bw->getWorkspaceNumber())->getMenu();
+ clientmenu->changeItemLabel(bw->getWindowNumber(), bw->getTitle());
+ clientmenu->update();
-
- void BScreen::updateNetizenConfigNotify(XEvent *e) {
- netList::iterator it;
- for (it = netizenList.begin(); it != netizenList.end(); ++it)
- (*it)->sendConfigNotify(e);
+ if (blackbox->getFocusedWindow() == bw)
+ toolbar->redrawWindowLabel(True);
}
+}
- void BScreen::raiseWindows(Window *workspace_stack, int num) {
- Window *session_stack = new
- Window[(num + workspacesList.size() + rootmenuList.size() + 13)];
- int i = 0, k = num;
-
- XRaiseWindow(getBaseDisplay().getXDisplay(), iconmenu->getWindowID());
- *(session_stack + i++) = iconmenu->getWindowID();
-
- wkspList::iterator it;
- for (it = workspacesList.begin(); it != workspacesList.end(); ++it)
- *(session_stack + i++) = (*it)->getMenu()->getWindowID();
-
- *(session_stack + i++) = workspacemenu->getWindowID();
-
- *(session_stack + i++) = configmenu->getFocusmenu()->getWindowID();
- *(session_stack + i++) = configmenu->getPlacementmenu()->getWindowID();
- *(session_stack + i++) = configmenu->getWindowID();
-
-#ifdef SLIT
- *(session_stack + i++) = slit->getMenu()->getDirectionmenu()->getWindowID();
- *(session_stack + i++) = slit->getMenu()->getPlacementmenu()->getWindowID();
- *(session_stack + i++) = slit->getMenu()->getWindowID();
-#endif // SLIT
-
- *(session_stack + i++) =
- toolbar->getMenu()->getPlacementmenu()->getWindowID();
- *(session_stack + i++) = toolbar->getMenu()->getWindowID();
-
- menuList::iterator rit;
- for (rit = rootmenuList.begin(); rit != rootmenuList.end(); ++rit)
- *(session_stack + i++) = (*rit)->getWindowID();
- *(session_stack + i++) = rootmenu->getWindowID();
-
- if (toolbar->onTop())
- *(session_stack + i++) = toolbar->getWindowID();
-
-#ifdef SLIT
- if (slit->onTop())
- *(session_stack + i++) = slit->getWindowID();
-#endif // SLIT
-
- while (k--)
- *(session_stack + i++) = *(workspace_stack + k);
-
- XRestackWindows(getBaseDisplay().getXDisplay(), session_stack, i);
+void BScreen::nextFocus(void) {
+ BlackboxWindow *focused = blackbox->getFocusedWindow(),
+ *next = focused;
- delete [] session_stack;
+ if (focused) {
+ // if window is not on this screen, ignore it
+ if (focused->getScreen()->getScreenNumber() != getScreenNumber())
+ focused = (BlackboxWindow*) 0;
}
+ if (focused && current_workspace->getCount() > 1) {
+ // next is the next window to recieve focus, current is a place holder
+ BlackboxWindow *current;
+ do {
+ current = next;
+ next = current_workspace->getNextWindowInList(current);
+ } while(!next->setInputFocus() && next != focused);
- void BScreen::addWorkspaceName(const char *name) {
- workspaceNames.push_back(name);
- }
-
+ if (next != focused)
+ current_workspace->raiseWindow(next);
+ } else if (current_workspace->getCount() >= 1) {
+ next = current_workspace->getTopWindowOnStack();
- const char *BScreen::getNameOfWorkspace(int id) {
- if (id < 0 || id >= (signed)workspaceNames.size())
- return (const char *) 0;
- return workspaceNames[id].c_str();
+ current_workspace->raiseWindow(next);
+ next->setInputFocus();
}
+}
- void BScreen::reassociateWindow(OpenboxWindow *w, int wkspc_id, Bool ignore_sticky) {
- if (! w) return;
-
- if (wkspc_id == -1)
- wkspc_id = current_workspace->getWorkspaceID();
-
- if (w->getWorkspaceNumber() == wkspc_id)
- return;
+void BScreen::prevFocus(void) {
+ BlackboxWindow *focused = blackbox->getFocusedWindow(),
+ *next = focused;
- if (w->isIconic()) {
- removeIcon(w);
- getWorkspace(wkspc_id)->addWindow(w);
- } else if (ignore_sticky || ! w->isStuck()) {
- getWorkspace(w->getWorkspaceNumber())->removeWindow(w);
- getWorkspace(wkspc_id)->addWindow(w);
- }
+ if (focused) {
+ // if window is not on this screen, ignore it
+ if (focused->getScreen()->getScreenNumber() != getScreenNumber())
+ focused = (BlackboxWindow*) 0;
}
+ if (focused && current_workspace->getCount() > 1) {
+ // next is the next window to recieve focus, current is a place holder
+ BlackboxWindow *current;
+ do {
+ current = next;
+ next = current_workspace->getPrevWindowInList(current);
+ } while(!next->setInputFocus() && next != focused);
- void BScreen::nextFocus(void) {
- Bool have_focused = False;
- int focused_window_number = -1;
- OpenboxWindow *next;
-
- if (openbox.focusedWindow()) {
- if (openbox.focusedWindow()->getScreen()->getScreenNumber() ==
- getScreenNumber()) {
- have_focused = True;
- focused_window_number = openbox.focusedWindow()->getWindowNumber();
- }
- }
-
- if ((getCurrentWorkspace()->getCount() > 1) && have_focused) {
- int next_window_number = focused_window_number;
- do {
- if ((++next_window_number) >= getCurrentWorkspace()->getCount())
- next_window_number = 0;
-
- next = getCurrentWorkspace()->getWindow(next_window_number);
- } while ((! next->setInputFocus()) && (next_window_number !=
- focused_window_number));
-
- if (next_window_number != focused_window_number)
- getCurrentWorkspace()->raiseWindow(next);
- } else if (getCurrentWorkspace()->getCount() >= 1) {
- next = current_workspace->getWindow(0);
-
+ if (next != focused)
current_workspace->raiseWindow(next);
- next->setInputFocus();
- }
- }
-
+ } else if (current_workspace->getCount() >= 1) {
+ next = current_workspace->getTopWindowOnStack();
- void BScreen::prevFocus(void) {
- Bool have_focused = False;
- int focused_window_number = -1;
- OpenboxWindow *prev;
-
- if (openbox.focusedWindow()) {
- if (openbox.focusedWindow()->getScreen()->getScreenNumber() ==
- getScreenNumber()) {
- have_focused = True;
- focused_window_number = openbox.focusedWindow()->getWindowNumber();
- }
- }
-
- if ((getCurrentWorkspace()->getCount() > 1) && have_focused) {
- int prev_window_number = focused_window_number;
- do {
- if ((--prev_window_number) < 0)
- prev_window_number = getCurrentWorkspace()->getCount() - 1;
+ current_workspace->raiseWindow(next);
+ next->setInputFocus();
+ }
+}
- prev = getCurrentWorkspace()->getWindow(prev_window_number);
- } while ((! prev->setInputFocus()) && (prev_window_number !=
- focused_window_number));
- if (prev_window_number != focused_window_number)
- getCurrentWorkspace()->raiseWindow(prev);
- } else if (getCurrentWorkspace()->getCount() >= 1) {
- prev = current_workspace->getWindow(0);
+void BScreen::raiseFocus(void) {
+ BlackboxWindow *focused = blackbox->getFocusedWindow();
+ if (! focused)
+ return;
- current_workspace->raiseWindow(prev);
- prev->setInputFocus();
- }
+ // if on this Screen, raise it
+ if (focused->getScreen()->getScreenNumber() == getScreenNumber()) {
+ Workspace *workspace = getWorkspace(focused->getWorkspaceNumber());
+ workspace->raiseWindow(focused);
}
+}
- void BScreen::raiseFocus(void) {
- Bool have_focused = False;
- int focused_window_number = -1;
+void BScreen::InitMenu(void) {
+ if (rootmenu) {
+ rootmenuList.clear();
- if (openbox.focusedWindow()) {
- if (openbox.focusedWindow()->getScreen()->getScreenNumber() ==
- getScreenNumber()) {
- have_focused = True;
- focused_window_number = openbox.focusedWindow()->getWindowNumber();
- }
- }
-
- if ((getCurrentWorkspace()->getCount() > 1) && have_focused)
- getWorkspace(openbox.focusedWindow()->getWorkspaceNumber())->
- raiseWindow(openbox.focusedWindow());
+ while (rootmenu->getCount())
+ rootmenu->remove(0);
+ } else {
+ rootmenu = new Rootmenu(this);
}
+ bool defaultMenu = True;
+ if (blackbox->getMenuFilename()) {
+ FILE *menu_file = fopen(blackbox->getMenuFilename(), "r");
- void BScreen::InitMenu(void) {
- if (rootmenu) {
- rootmenuList.clear();
- while (rootmenu->getCount())
- rootmenu->remove(0);
+ if (!menu_file) {
+ perror(blackbox->getMenuFilename());
} else {
- rootmenu = new Rootmenu(*this);
- }
- bool defaultMenu = true;
-
- FILE *menu_file;
- const char *menu_filename = openbox.getMenuFilename();
-
- if (!(menu_file = fopen(menu_filename, "r"))) {
- perror(menu_filename);
- menu_filename = (char *) 0;
- }
- if (menu_filename == (char *) 0) {
- // opening the menu file failed, try the DEFAULTMENU
- menu_filename = DEFAULTMENU;
- if (!(menu_file = fopen(menu_filename, "r"))) {
- perror(menu_filename);
- menu_filename = (char *) 0;
- }
- }
-
- if (menu_filename) {
if (feof(menu_file)) {
fprintf(stderr, i18n(ScreenSet, ScreenEmptyMenuFile,
- "%s: Empty menu file"), menu_filename);
- menu_filename = (char *) 0;
+ "%s: Empty menu file"),
+ blackbox->getMenuFilename());
} else {
- // successsfully opened a menu file
char line[1024], label[1024];
memset(line, 0, 1024);
memset(label, 0, 1024);
if (line[0] != '#') {
int i, key = 0, index = -1, len = strlen(line);
- key = 0;
for (i = 0; i < len; i++) {
if (line[i] == '[') index = 0;
else if (line[i] == ']') break;
key += tolower(line[i]);
}
- if (key == 517) {
+ if (key == 517) { // [begin]
index = -1;
for (i = index; i < len; i++) {
if (line[i] == '(') index = 0;
rootmenu->setLabel(label);
defaultMenu = parseMenuFile(menu_file, rootmenu);
- if (!defaultMenu)
- openbox.addMenuTimestamp(menu_filename);
break;
}
}
}
fclose(menu_file);
}
+ }
- if (defaultMenu) {
- rootmenu->setInternalMenu();
- rootmenu->insert(i18n(ScreenSet, Screenxterm, "xterm"),
- BScreen::Execute,
- i18n(ScreenSet, Screenxterm, "xterm"));
- rootmenu->insert(i18n(ScreenSet, ScreenRestart, "Restart"),
- BScreen::Restart);
- rootmenu->insert(i18n(ScreenSet, ScreenExit, "Exit"),
- BScreen::Exit);
- }
+ if (defaultMenu) {
+ rootmenu->setInternalMenu();
+ rootmenu->insert(i18n(ScreenSet, Screenxterm, "xterm"),
+ BScreen::Execute,
+ i18n(ScreenSet, Screenxterm, "xterm"));
+ rootmenu->insert(i18n(ScreenSet, ScreenRestart, "Restart"),
+ BScreen::Restart);
+ rootmenu->insert(i18n(ScreenSet, ScreenExit, "Exit"),
+ BScreen::Exit);
+ rootmenu->setLabel(i18n(BasemenuSet, BasemenuBlackboxMenu,
+ "Blackbox Menu"));
+ } else {
+ blackbox->saveMenuFilename(blackbox->getMenuFilename());
}
+}
+
+
+bool BScreen::parseMenuFile(FILE *file, Rootmenu *menu) {
+ char line[1024], label[1024], command[1024];
+ while (! feof(file)) {
+ memset(line, 0, 1024);
+ memset(label, 0, 1024);
+ memset(command, 0, 1024);
- Bool BScreen::parseMenuFile(FILE *file, Rootmenu *menu) {
- char line[1024], label[1024], command[1024];
-
- while (! feof(file)) {
- memset(line, 0, 1024);
- memset(label, 0, 1024);
- memset(command, 0, 1024);
-
- if (fgets(line, 1024, file)) {
- if (line[0] != '#') {
- register int i, key = 0, parse = 0, index = -1,
- line_length = strlen(line),
- label_length = 0, command_length = 0;
-
- // determine the keyword
- key = 0;
- for (i = 0; i < line_length; i++) {
- if (line[i] == '[') parse = 1;
- else if (line[i] == ']') break;
- else if (line[i] != ' ')
- if (parse)
- key += tolower(line[i]);
+ if (fgets(line, 1024, file)) {
+ if (line[0] != '#') {
+ int i, key = 0, parse = 0, index = -1, line_length = strlen(line);
+
+ // determine the keyword
+ for (i = 0; i < line_length; i++) {
+ if (line[i] == '[') parse = 1;
+ else if (line[i] == ']') break;
+ else if (line[i] != ' ')
+ if (parse)
+ key += tolower(line[i]);
+ }
+
+ // get the label enclosed in ()'s
+ parse = 0;
+
+ for (i = 0; i < line_length; i++) {
+ if (line[i] == '(') {
+ index = 0;
+ parse = 1;
+ } else if (line[i] == ')') break;
+ else if (index++ >= 0) {
+ if (line[i] == '\\' && i < line_length - 1) i++;
+ label[index - 1] = line[i];
}
+ }
- // get the label enclosed in ()'s
- parse = 0;
-
- for (i = 0; i < line_length; i++) {
- if (line[i] == '(') {
- index = 0;
- parse = 1;
- } else if (line[i] == ')') break;
- else if (index++ >= 0) {
- if (line[i] == '\\' && i < line_length - 1) i++;
- label[index - 1] = line[i];
- }
+ if (parse) {
+ label[index] = '\0';
+ } else {
+ label[0] = '\0';
+ }
+
+ // get the command enclosed in {}'s
+ parse = 0;
+ index = -1;
+ for (i = 0; i < line_length; i++) {
+ if (line[i] == '{') {
+ index = 0;
+ parse = 1;
+ } else if (line[i] == '}') break;
+ else if (index++ >= 0) {
+ if (line[i] == '\\' && i < line_length - 1) i++;
+ command[index - 1] = line[i];
}
+ }
+
+ if (parse) {
+ command[index] = '\0';
+ } else {
+ command[0] = '\0';
+ }
+
+ switch (key) {
+ case 311: // end
+ return ((menu->getCount() == 0) ? True : False);
- if (parse) {
- label[index] = '\0';
- label_length = index;
- } else {
+ break;
+
+ case 333: // nop
+ if (! *label)
label[0] = '\0';
- label_length = 0;
+ menu->insert(label);
+
+ break;
+
+ case 421: // exec
+ if ((! *label) && (! *command)) {
+ fprintf(stderr, i18n(ScreenSet, ScreenEXECError,
+ "BScreen::parseMenuFile: [exec] error, "
+ "no menu label and/or command defined\n"));
+ continue;
}
- // get the command enclosed in {}'s
- parse = 0;
- index = -1;
- for (i = 0; i < line_length; i++) {
- if (line[i] == '{') {
- index = 0;
- parse = 1;
- } else if (line[i] == '}') break;
- else if (index++ >= 0) {
- if (line[i] == '\\' && i < line_length - 1) i++;
- command[index - 1] = line[i];
- }
+ menu->insert(label, BScreen::Execute, command);
+
+ break;
+
+ case 442: // exit
+ if (! *label) {
+ fprintf(stderr, i18n(ScreenSet, ScreenEXITError,
+ "BScreen::parseMenuFile: [exit] error, "
+ "no menu label defined\n"));
+ continue;
}
- if (parse) {
- command[index] = '\0';
- command_length = index;
- } else {
- command[0] = '\0';
- command_length = 0;
+ menu->insert(label, BScreen::Exit);
+
+ break;
+
+ case 561: // style
+ {
+ if ((! *label) || (! *command)) {
+ fprintf(stderr,
+ i18n(ScreenSet, ScreenSTYLEError,
+ "BScreen::parseMenuFile: [style] error, "
+ "no menu label and/or filename defined\n"));
+ continue;
+ }
+
+ string style = expandTilde(command);
+
+ menu->insert(label, BScreen::SetStyle, style.c_str());
}
- switch (key) {
- case 311: //end
- return ((menu->getCount() == 0) ? True : False);
+ break;
- break;
+ case 630: // config
+ if (! *label) {
+ fprintf(stderr, i18n(ScreenSet, ScreenCONFIGError,
+ "BScreen::parseMenufile: [config] error, "
+ "no label defined"));
+ continue;
+ }
- case 333: // nop
- menu->insert(label);
+ menu->insert(label, configmenu);
- break;
+ break;
- case 421: // exec
- if ((! *label) && (! *command)) {
- fprintf(stderr, i18n(ScreenSet, ScreenEXECError,
- "BScreen::parseMenuFile: [exec] error, "
- "no menu label and/or command defined\n"));
+ case 740: // include
+ {
+ if (! *label) {
+ fprintf(stderr, i18n(ScreenSet, ScreenINCLUDEError,
+ "BScreen::parseMenuFile: [include] error, "
+ "no filename defined\n"));
continue;
}
- menu->insert(label, BScreen::Execute, command);
+ string newfile = expandTilde(label);
+ FILE *submenufile = fopen(newfile.c_str(), "r");
- break;
+ if (submenufile) {
+ struct stat buf;
+ if (fstat(fileno(submenufile), &buf) ||
+ (! S_ISREG(buf.st_mode))) {
+ fprintf(stderr,
+ i18n(ScreenSet, ScreenINCLUDEErrorReg,
+ "BScreen::parseMenuFile: [include] error: "
+ "'%s' is not a regular file\n"), newfile.c_str());
+ break;
+ }
+
+ if (! feof(submenufile)) {
+ if (! parseMenuFile(submenufile, menu))
+ blackbox->saveMenuFilename(newfile);
+
+ fclose(submenufile);
+ }
+ } else {
+ perror(newfile.c_str());
+ }
+ }
- case 442: // exit
+ break;
+
+ case 767: // submenu
+ {
if (! *label) {
- fprintf(stderr, i18n(ScreenSet, ScreenEXITError,
- "BScreen::parseMenuFile: [exit] error, "
+ fprintf(stderr, i18n(ScreenSet, ScreenSUBMENUError,
+ "BScreen::parseMenuFile: [submenu] error, "
"no menu label defined\n"));
continue;
}
- menu->insert(label, BScreen::Exit);
+ Rootmenu *submenu = new Rootmenu(this);
- break;
+ if (*command)
+ submenu->setLabel(command);
+ else
+ submenu->setLabel(label);
- case 561: // style
- {
- if ((! *label) || (! *command)) {
- fprintf(stderr, i18n(ScreenSet, ScreenSTYLEError,
- "BScreen::parseMenuFile: [style] error, "
- "no menu label and/or filename defined\n"));
- continue;
- }
+ parseMenuFile(file, submenu);
+ submenu->update();
+ menu->insert(label, submenu);
+ rootmenuList.push_back(submenu);
+ }
- char style[MAXPATHLEN];
+ break;
- // perform shell style ~ home directory expansion
- char *homedir = 0;
- int homedir_len = 0;
- if (*command == '~' && *(command + 1) == '/') {
- homedir = getenv("HOME");
- homedir_len = strlen(homedir);
- }
+ case 773: // restart
+ {
+ if (! *label) {
+ fprintf(stderr, i18n(ScreenSet, ScreenRESTARTError,
+ "BScreen::parseMenuFile: [restart] error, "
+ "no menu label defined\n"));
+ continue;
+ }
- if (homedir && homedir_len != 0) {
- strncpy(style, homedir, homedir_len);
+ if (*command)
+ menu->insert(label, BScreen::RestartOther, command);
+ else
+ menu->insert(label, BScreen::Restart);
+ }
- strncpy(style + homedir_len, command + 1,
- command_length - 1);
- *(style + command_length + homedir_len - 1) = '\0';
- } else {
- strncpy(style, command, command_length);
- *(style + command_length) = '\0';
- }
+ break;
- menu->insert(label, BScreen::SetStyle, style);
+ case 845: // reconfig
+ {
+ if (! *label) {
+ fprintf(stderr,
+ i18n(ScreenSet, ScreenRECONFIGError,
+ "BScreen::parseMenuFile: [reconfig] error, "
+ "no menu label defined\n"));
+ continue;
}
- break;
+ menu->insert(label, BScreen::Reconfigure);
+ }
- case 630: // config
- if (! *label) {
- fprintf(stderr, i18n(ScreenSet, ScreenCONFIGError,
- "BScreen::parseMenufile: [config] error, "
- "no label defined"));
+ break;
+
+ case 995: // stylesdir
+ case 1113: // stylesmenu
+ {
+ bool newmenu = ((key == 1113) ? True : False);
+
+ if ((! *label) || ((! *command) && newmenu)) {
+ fprintf(stderr,
+ i18n(ScreenSet, ScreenSTYLESDIRError,
+ "BScreen::parseMenuFile: [stylesdir/stylesmenu]"
+ " error, no directory defined\n"));
continue;
}
- menu->insert(label, configmenu);
+ char *directory = ((newmenu) ? command : label);
- break;
+ string stylesdir = expandTilde(directory);
- case 740: // include
- {
- if (! *label) {
- fprintf(stderr, i18n(ScreenSet, ScreenINCLUDEError,
- "BScreen::parseMenuFile: [include] error, "
- "no filename defined\n"));
- continue;
- }
+ struct stat statbuf;
- char newfile[MAXPATHLEN];
+ if (! stat(stylesdir.c_str(), &statbuf)) {
+ if (S_ISDIR(statbuf.st_mode)) {
+ Rootmenu *stylesmenu;
- // perform shell style ~ home directory expansion
- char *homedir = 0;
- int homedir_len = 0;
- if (*label == '~' && *(label + 1) == '/') {
- homedir = getenv("HOME");
- homedir_len = strlen(homedir);
- }
+ if (newmenu)
+ stylesmenu = new Rootmenu(this);
+ else
+ stylesmenu = menu;
+
+ DIR *d = opendir(stylesdir.c_str());
+ struct dirent *p;
+ std::vector<string> ls;
+
+ while((p = readdir(d)))
+ ls.push_back(p->d_name);
+
+ closedir(d);
- if (homedir && homedir_len != 0) {
- strncpy(newfile, homedir, homedir_len);
+ std::sort(ls.begin(), ls.end());
- strncpy(newfile + homedir_len, label + 1,
- label_length - 1);
- *(newfile + label_length + homedir_len - 1) = '\0';
+ std::vector<string>::iterator it = ls.begin(),
+ end = ls.end();
+ for (; it != end; ++it) {
+ const string& fname = *it;
+
+ if (fname[fname.size()-1] == '~')
+ continue;
+
+ string style = stylesdir;
+ style += '/';
+ style += fname;
+
+ if ((! stat(style.c_str(), &statbuf)) &&
+ S_ISREG(statbuf.st_mode))
+ stylesmenu->insert(fname, BScreen::SetStyle, style);
+ }
+
+ stylesmenu->update();
+
+ if (newmenu) {
+ stylesmenu->setLabel(label);
+ menu->insert(label, stylesmenu);
+ rootmenuList.push_back(stylesmenu);
+ }
+
+ blackbox->saveMenuFilename(stylesdir);
} else {
- strncpy(newfile, label, label_length);
- *(newfile + label_length) = '\0';
+ fprintf(stderr,
+ i18n(ScreenSet, ScreenSTYLESDIRErrorNotDir,
+ "BScreen::parseMenuFile:"
+ " [stylesdir/stylesmenu] error, %s is not a"
+ " directory\n"), stylesdir.c_str());
}
+ } else {
+ fprintf(stderr,
+ i18n(ScreenSet, ScreenSTYLESDIRErrorNoExist,
+ "BScreen::parseMenuFile: [stylesdir/stylesmenu]"
+ " error, %s does not exist\n"), stylesdir.c_str());
+ }
+ break;
+ }
- if (newfile) {
- FILE *submenufile = fopen(newfile, "r");
-
- if (submenufile) {
- struct stat buf;
- if (fstat(fileno(submenufile), &buf) ||
- (! S_ISREG(buf.st_mode))) {
- fprintf(stderr,
- i18n(ScreenSet, ScreenINCLUDEErrorReg,
- "BScreen::parseMenuFile: [include] error: "
- "'%s' is not a regular file\n"), newfile);
- break;
- }
-
- if (! feof(submenufile)) {
- if (!parseMenuFile(submenufile, menu))
- openbox.addMenuTimestamp(newfile);
- fclose(submenufile);
- }
- } else
- perror(newfile);
- }
+ case 1090: // workspaces
+ {
+ if (! *label) {
+ fprintf(stderr,
+ i18n(ScreenSet, ScreenWORKSPACESError,
+ "BScreen:parseMenuFile: [workspaces] error, "
+ "no menu label defined\n"));
+ continue;
}
+ menu->insert(label, workspacemenu);
+
break;
+ }
+ }
+ }
+ }
+ }
- case 767: // submenu
- {
- if (! *label) {
- fprintf(stderr, i18n(ScreenSet, ScreenSUBMENUError,
- "BScreen::parseMenuFile: [submenu] error, "
- "no menu label defined\n"));
- continue;
- }
+ return ((menu->getCount() == 0) ? True : False);
+}
- Rootmenu *submenu = new Rootmenu(*this);
- if (*command)
- submenu->setLabel(command);
- else
- submenu->setLabel(label);
+void BScreen::shutdown(void) {
+ XSelectInput(blackbox->getXDisplay(), getRootWindow(), NoEventMask);
+ XSync(blackbox->getXDisplay(), False);
- parseMenuFile(file, submenu);
- submenu->update();
- menu->insert(label, submenu);
- rootmenuList.push_back(submenu);
- }
+ while(! windowList.empty())
+ unmanageWindow(windowList.front(), True);
- break;
+ slit->shutdown();
+}
- case 773: // restart
- {
- if (! *label) {
- fprintf(stderr, i18n(ScreenSet, ScreenRESTARTError,
- "BScreen::parseMenuFile: [restart] error, "
- "no menu label defined\n"));
- continue;
- }
- if (*command)
- menu->insert(label, BScreen::RestartOther, command);
- else
- menu->insert(label, BScreen::Restart);
- }
+void BScreen::showPosition(int x, int y) {
+ if (! geom_visible) {
+ XMoveResizeWindow(blackbox->getXDisplay(), geom_window,
+ (getWidth() - geom_w) / 2,
+ (getHeight() - geom_h) / 2, geom_w, geom_h);
+ XMapWindow(blackbox->getXDisplay(), geom_window);
+ XRaiseWindow(blackbox->getXDisplay(), geom_window);
- break;
+ geom_visible = True;
+ }
- case 845: // reconfig
- {
- if (! *label) {
- fprintf(stderr, i18n(ScreenSet, ScreenRECONFIGError,
- "BScreen::parseMenuFile: [reconfig] error, "
- "no menu label defined\n"));
- continue;
- }
+ char label[1024];
- menu->insert(label, BScreen::Reconfigure);
- }
+ sprintf(label, i18n(ScreenSet, ScreenPositionFormat,
+ "X: %4d x Y: %4d"), x, y);
- break;
+ XClearWindow(blackbox->getXDisplay(), geom_window);
- case 995: // stylesdir
- case 1113: // stylesmenu
- {
- Bool newmenu = ((key == 1113) ? True : False);
+ BPen pen(resource.wstyle.l_text_focus, resource.wstyle.font);
+ if (i18n.multibyte()) {
+ XmbDrawString(blackbox->getXDisplay(), geom_window,
+ resource.wstyle.fontset, pen.gc(),
+ resource.bevel_width, resource.bevel_width -
+ resource.wstyle.fontset_extents->max_ink_extent.y,
+ label, strlen(label));
+ } else {
+ XDrawString(blackbox->getXDisplay(), geom_window,
+ pen.gc(), resource.bevel_width,
+ resource.wstyle.font->ascent + resource.bevel_width,
+ label, strlen(label));
+ }
+}
- if ((! *label) || ((! *command) && newmenu)) {
- fprintf(stderr,
- i18n(ScreenSet, ScreenSTYLESDIRError,
- "BScreen::parseMenuFile: [stylesdir/stylesmenu]"
- " error, no directory defined\n"));
- continue;
- }
- char stylesdir[MAXPATHLEN];
+void BScreen::showGeometry(unsigned int gx, unsigned int gy) {
+ if (! geom_visible) {
+ XMoveResizeWindow(blackbox->getXDisplay(), geom_window,
+ (getWidth() - geom_w) / 2,
+ (getHeight() - geom_h) / 2, geom_w, geom_h);
+ XMapWindow(blackbox->getXDisplay(), geom_window);
+ XRaiseWindow(blackbox->getXDisplay(), geom_window);
- char *directory = ((newmenu) ? command : label);
- int directory_length = ((newmenu) ? command_length : label_length);
+ geom_visible = True;
+ }
- // perform shell style ~ home directory expansion
- char *homedir = 0;
- int homedir_len = 0;
+ char label[1024];
- if (*directory == '~' && *(directory + 1) == '/') {
- homedir = getenv("HOME");
- homedir_len = strlen(homedir);
- }
+ sprintf(label, i18n(ScreenSet, ScreenGeometryFormat,
+ "W: %4d x H: %4d"), gx, gy);
- if (homedir && homedir_len != 0) {
- strncpy(stylesdir, homedir, homedir_len);
+ XClearWindow(blackbox->getXDisplay(), geom_window);
- strncpy(stylesdir + homedir_len, directory + 1,
- directory_length - 1);
- *(stylesdir + directory_length + homedir_len - 1) = '\0';
- } else {
- strncpy(stylesdir, directory, directory_length);
- *(stylesdir + directory_length) = '\0';
- }
+ BPen pen(resource.wstyle.l_text_focus, resource.wstyle.font);
+ if (i18n.multibyte()) {
+ XmbDrawString(blackbox->getXDisplay(), geom_window,
+ resource.wstyle.fontset, pen.gc(),
+ resource.bevel_width, resource.bevel_width -
+ resource.wstyle.fontset_extents->max_ink_extent.y,
+ label, strlen(label));
+ } else {
+ XDrawString(blackbox->getXDisplay(), geom_window,
+ pen.gc(), resource.bevel_width,
+ resource.wstyle.font->ascent +
+ resource.bevel_width, label, strlen(label));
+ }
+}
- struct stat statbuf;
- if (! stat(stylesdir, &statbuf)) {
- if (S_ISDIR(statbuf.st_mode)) {
- Rootmenu *stylesmenu;
+void BScreen::hideGeometry(void) {
+ if (geom_visible) {
+ XUnmapWindow(blackbox->getXDisplay(), geom_window);
+ geom_visible = False;
+ }
+}
- if (newmenu)
- stylesmenu = new Rootmenu(*this);
- else
- stylesmenu = menu;
- DIR *d = opendir(stylesdir);
- int entries = 0;
- struct dirent *p;
+void BScreen::addStrut(Strut *strut) {
+ strutList.push_back(strut);
+}
- // get the total number of directory entries
- while ((p = readdir(d))) entries++;
- rewinddir(d);
- char **ls = new char* [entries];
- int index = 0;
- while ((p = readdir(d)))
- ls[index++] = bstrdup(p->d_name);
+void BScreen::removeStrut(Strut *strut) {
+ strutList.remove(strut);
+}
- closedir(d);
- std::sort(ls, ls + entries, dcmp());
+const Rect& BScreen::availableArea(void) const {
+ if (doFullMax())
+ return getRect(); // return the full screen
+ return usableArea;
+}
- int n, slen = strlen(stylesdir);
- for (n = 0; n < entries; n++) {
- if (ls[n][strlen(ls[n])-1] != '~') {
- int nlen = strlen(ls[n]);
- char style[MAXPATHLEN + 1];
- strncpy(style, stylesdir, slen);
- *(style + slen) = '/';
- strncpy(style + slen + 1, ls[n], nlen + 1);
+void BScreen::updateAvailableArea(void) {
+ Rect old_area = usableArea;
+ usableArea = getRect(); // reset to full screen
+
+ /* these values represent offsets from the screen edge
+ * we look for the biggest offset on each edge and then apply them
+ * all at once
+ * do not be confused by the similarity to the names of Rect's members
+ */
+ unsigned int current_left = 0, current_right = 0, current_top = 0,
+ current_bottom = 0;
+
+ StrutList::const_iterator it = strutList.begin(), end = strutList.end();
+
+ for(; it != end; ++it) {
+ Strut *strut = *it;
+ if (strut->left > current_left)
+ current_left = strut->left;
+ if (strut->top > current_top)
+ current_top = strut->top;
+ if (strut->right > current_right)
+ current_right = strut->right;
+ if (strut->bottom > current_bottom)
+ current_bottom = strut->bottom;
+ }
- if ((! stat(style, &statbuf)) && S_ISREG(statbuf.st_mode))
- stylesmenu->insert(ls[n], BScreen::SetStyle, style);
- }
+ usableArea.setPos(current_left, current_top);
+ usableArea.setSize(usableArea.width() - (current_left + current_right),
+ usableArea.height() - (current_top + current_bottom));
- delete [] ls[n];
- }
+ if (old_area != usableArea) {
+ BlackboxWindowList::iterator it = windowList.begin(),
+ end = windowList.end();
+ for (; it != end; ++it)
+ if ((*it)->isMaximized()) (*it)->remaximize();
+ }
+}
- delete [] ls;
- stylesmenu->update();
+Workspace* BScreen::getWorkspace(unsigned int index) {
+ assert(index < workspacesList.size());
+ return workspacesList[index];
+}
- if (newmenu) {
- stylesmenu->setLabel(label);
- menu->insert(label, stylesmenu);
- rootmenuList.push_back(stylesmenu);
- }
- openbox.addMenuTimestamp(stylesdir);
- } else {
- fprintf(stderr, i18n(ScreenSet,
- ScreenSTYLESDIRErrorNotDir,
- "BScreen::parseMenuFile:"
- " [stylesdir/stylesmenu] error, %s is not a"
- " directory\n"), stylesdir);
- }
- } else {
- fprintf(stderr,
- i18n(ScreenSet, ScreenSTYLESDIRErrorNoExist,
- "BScreen::parseMenuFile: [stylesdir/stylesmenu]"
- " error, %s does not exist\n"), stylesdir);
- }
- break;
- }
+void BScreen::buttonPressEvent(XButtonEvent *xbutton) {
+ if (xbutton->button == 1) {
+ if (! isRootColormapInstalled())
+ image_control->installRootColormap();
- case 1090: // workspaces
- {
- if (! *label) {
- fprintf(stderr,
- i18n(ScreenSet, ScreenWORKSPACESError,
- "BScreen:parseMenuFile: [workspaces] error, "
- "no menu label defined\n"));
- continue;
- }
+ if (workspacemenu->isVisible())
+ workspacemenu->hide();
- menu->insert(label, workspacemenu);
+ if (rootmenu->isVisible())
+ rootmenu->hide();
+ } else if (xbutton->button == 2) {
+ int mx = xbutton->x_root - (workspacemenu->getWidth() / 2);
+ int my = xbutton->y_root - (workspacemenu->getTitleHeight() / 2);
- break;
- }
- }
- }
- }
+ if (mx < 0) mx = 0;
+ if (my < 0) my = 0;
+
+ if (mx + workspacemenu->getWidth() > getWidth())
+ mx = getWidth() - workspacemenu->getWidth() - getBorderWidth();
+
+ if (my + workspacemenu->getHeight() > getHeight())
+ my = getHeight() - workspacemenu->getHeight() - getBorderWidth();
+
+ workspacemenu->move(mx, my);
+
+ if (! workspacemenu->isVisible()) {
+ workspacemenu->removeParent();
+ workspacemenu->show();
}
+ } else if (xbutton->button == 3) {
+ int mx = xbutton->x_root - (rootmenu->getWidth() / 2);
+ int my = xbutton->y_root - (rootmenu->getTitleHeight() / 2);
+
+ if (mx < 0) mx = 0;
+ if (my < 0) my = 0;
- return ((menu->getCount() == 0) ? True : False);
+ if (mx + rootmenu->getWidth() > getWidth())
+ mx = getWidth() - rootmenu->getWidth() - getBorderWidth();
+
+ if (my + rootmenu->getHeight() > getHeight())
+ my = getHeight() - rootmenu->getHeight() - getBorderWidth();
+
+ rootmenu->move(mx, my);
+
+ if (! rootmenu->isVisible()) {
+ blackbox->checkMenu();
+ rootmenu->show();
+ }
}
+}
+
+void BScreen::toggleFocusModel(FocusModel model) {
+ if (model == SloppyFocus) {
+ saveSloppyFocus(True);
+ } else {
+ saveSloppyFocus(False);
+ saveAutoRaise(False);
+ saveClickRaise(False);
+ }
- void BScreen::shutdown(void) {
- openbox.grab();
+ updateFocusModel();
+}
- XSelectInput(getBaseDisplay().getXDisplay(), getRootWindow(), NoEventMask);
- XSync(getBaseDisplay().getXDisplay(), False);
- std::for_each(workspacesList.begin(), workspacesList.end(),
- std::mem_fun(&Workspace::shutdown));
+void BScreen::updateFocusModel()
+{
+ std::for_each(workspacesList.begin(), workspacesList.end(),
+ std::mem_fun(&Workspace::updateFocusModel));
+}
- while (!iconList.empty())
- iconList.front()->restore();
-#ifdef SLIT
- slit->shutdown();
-#endif // SLIT
+BTexture BScreen::readDatabaseTexture(const string &rname,
+ const string &rclass,
+ const string &default_color) {
+ BTexture texture;
+ XrmValue value;
+ char *value_type;
- openbox.ungrab();
+ if (XrmGetResource(resource.stylerc, rname.c_str(), rclass.c_str(),
+ &value_type, &value))
+ texture = BTexture(value.addr);
+ else
+ texture.setTexture(BTexture::Solid | BTexture::Flat);
+
+ // associate this texture with this screen
+ texture.setDisplay(getBaseDisplay(), getScreenNumber());
+ texture.setImageControl(image_control);
+
+ if (texture.texture() & BTexture::Solid) {
+ texture.setColor(readDatabaseColor(rname + ".color",
+ rclass + ".Color",
+ default_color));
+ texture.setColorTo(readDatabaseColor(rname + ".colorTo",
+ rclass + ".ColorTo",
+ default_color));
+ } else if (texture.texture() & BTexture::Gradient) {
+ texture.setColor(readDatabaseColor(rname + ".color",
+ rclass + ".Color",
+ default_color));
+ texture.setColorTo(readDatabaseColor(rname + ".colorTo",
+ rclass + ".ColorTo",
+ default_color));
}
+ return texture;
+}
+
+
+BColor BScreen::readDatabaseColor(const string &rname, const string &rclass,
+ const string &default_color) {
+ BColor color;
+ XrmValue value;
+ char *value_type;
+ if (XrmGetResource(resource.stylerc, rname.c_str(), rclass.c_str(),
+ &value_type, &value))
+ color = BColor(value.addr, getBaseDisplay(), getScreenNumber());
+ else
+ color = BColor(default_color, getBaseDisplay(), getScreenNumber());
+ return color;
+}
+
- void BScreen::showPosition(int x, int y) {
- if (! geom_visible) {
- XMoveResizeWindow(getBaseDisplay().getXDisplay(), geom_window,
- (size().w() - geom_w) / 2,
- (size().h() - geom_h) / 2, geom_w, geom_h);
- XMapWindow(getBaseDisplay().getXDisplay(), geom_window);
- XRaiseWindow(getBaseDisplay().getXDisplay(), geom_window);
+XFontSet BScreen::readDatabaseFontSet(const string &rname,
+ const string &rclass) {
+ char *defaultFont = "fixed";
- geom_visible = True;
+ bool load_default = True;
+ XrmValue value;
+ char *value_type;
+ XFontSet fontset = 0;
+ if (XrmGetResource(resource.stylerc, rname.c_str(), rclass.c_str(),
+ &value_type, &value) &&
+ (fontset = createFontSet(value.addr))) {
+ load_default = False;
+ }
+
+ if (load_default) {
+ fontset = createFontSet(defaultFont);
+
+ if (! fontset) {
+ fprintf(stderr,
+ i18n(ScreenSet, ScreenDefaultFontLoadFail,
+ "BScreen::setCurrentStyle(): couldn't load default font.\n"));
+ exit(2);
}
+ }
+
+ return fontset;
+}
- char label[1024];
- sprintf(label, i18n(ScreenSet, ScreenPositionFormat,
- "X: %4d x Y: %4d"), x, y);
+XFontStruct *BScreen::readDatabaseFont(const string &rname,
+ const string &rclass) {
+ char *defaultFont = "fixed";
- XClearWindow(getBaseDisplay().getXDisplay(), geom_window);
+ bool load_default = False;
+ XrmValue value;
+ char *value_type;
+ XFontStruct *font = 0;
+ if (XrmGetResource(resource.stylerc, rname.c_str(), rclass.c_str(),
+ &value_type, &value)) {
+ if ((font = XLoadQueryFont(blackbox->getXDisplay(), value.addr)) == NULL) {
+ fprintf(stderr,
+ i18n(ScreenSet, ScreenFontLoadFail,
+ "BScreen::setCurrentStyle(): couldn't load font '%s'\n"),
+ value.addr);
- if (i18n.multibyte()) {
- XmbDrawString(getBaseDisplay().getXDisplay(), geom_window,
- resource.wstyle.fontset, resource.wstyle.l_text_focus_gc,
- resource.bevel_width, resource.bevel_width -
- resource.wstyle.fontset_extents->max_ink_extent.y,
- label, strlen(label));
- } else {
- XDrawString(getBaseDisplay().getXDisplay(), geom_window,
- resource.wstyle.l_text_focus_gc,
- resource.bevel_width,
- resource.wstyle.font->ascent +
- resource.bevel_width, label, strlen(label));
+ load_default = True;
}
+ } else {
+ load_default = True;
}
+ if (load_default) {
+ font = XLoadQueryFont(blackbox->getXDisplay(), defaultFont);
+ if (font == NULL) {
+ fprintf(stderr,
+ i18n(ScreenSet, ScreenDefaultFontLoadFail,
+ "BScreen::setCurrentStyle(): couldn't load default font.\n"));
+ exit(2);
+ }
+ }
+
+ return font;
+}
- void BScreen::showGeometry(unsigned int gx, unsigned int gy) {
- if (! geom_visible) {
- XMoveResizeWindow(getBaseDisplay().getXDisplay(), geom_window,
- (size().w() - geom_w) / 2,
- (size().h() - geom_h) / 2, geom_w, geom_h);
- XMapWindow(getBaseDisplay().getXDisplay(), geom_window);
- XRaiseWindow(getBaseDisplay().getXDisplay(), geom_window);
- geom_visible = True;
+#ifndef HAVE_STRCASESTR
+static const char * strcasestr(const char *str, const char *ptn) {
+ const char *s2, *p2;
+ for(; *str; str++) {
+ for(s2=str,p2=ptn; ; s2++,p2++) {
+ if (!*p2) return str;
+ if (toupper(*s2) != toupper(*p2)) break;
}
+ }
+ return NULL;
+}
+#endif // HAVE_STRCASESTR
- char label[1024];
- sprintf(label, i18n(ScreenSet, ScreenGeometryFormat,
- "W: %4d x H: %4d"), gx, gy);
+static const char *getFontElement(const char *pattern, char *buf,
+ int bufsiz, ...) {
+ const char *p, *v;
+ char *p2;
+ va_list va;
+
+ va_start(va, bufsiz);
+ buf[bufsiz-1] = 0;
+ buf[bufsiz-2] = '*';
+ while((v = va_arg(va, char *)) != NULL) {
+ p = strcasestr(pattern, v);
+ if (p) {
+ strncpy(buf, p+1, bufsiz-2);
+ p2 = strchr(buf, '-');
+ if (p2) *p2=0;
+ va_end(va);
+ return p;
+ }
+ }
+ va_end(va);
+ strncpy(buf, "*", bufsiz);
+ return NULL;
+}
- XClearWindow(getBaseDisplay().getXDisplay(), geom_window);
- if (i18n.multibyte()) {
- XmbDrawString(getBaseDisplay().getXDisplay(), geom_window,
- resource.wstyle.fontset, resource.wstyle.l_text_focus_gc,
- resource.bevel_width, resource.bevel_width -
- resource.wstyle.fontset_extents->max_ink_extent.y,
- label, strlen(label));
+static const char *getFontSize(const char *pattern, int *size) {
+ const char *p;
+ const char *p2=NULL;
+ int n=0;
+
+ for (p=pattern; 1; p++) {
+ if (!*p) {
+ if (p2!=NULL && n>1 && n<72) {
+ *size = n; return p2+1;
+ } else {
+ *size = 16; return NULL;
+ }
+ } else if (*p=='-') {
+ if (n>1 && n<72 && p2!=NULL) {
+ *size = n;
+ return p2+1;
+ }
+ p2=p; n=0;
+ } else if (*p>='0' && *p<='9' && p2!=NULL) {
+ n *= 10;
+ n += *p-'0';
} else {
- XDrawString(getBaseDisplay().getXDisplay(), geom_window,
- resource.wstyle.l_text_focus_gc,
- resource.bevel_width,
- resource.wstyle.font->ascent +
- resource.bevel_width, label, strlen(label));
+ p2=NULL; n=0;
}
}
+}
- void BScreen::hideGeometry(void) {
- if (geom_visible) {
- XUnmapWindow(getBaseDisplay().getXDisplay(), geom_window);
- geom_visible = False;
- }
+
+XFontSet BScreen::createFontSet(const string &fontname) {
+ XFontSet fs;
+ char **missing, *def = "-";
+ int nmissing, pixel_size = 0, buf_size = 0;
+ char weight[FONT_ELEMENT_SIZE], slant[FONT_ELEMENT_SIZE];
+
+ fs = XCreateFontSet(blackbox->getXDisplay(),
+ fontname.c_str(), &missing, &nmissing, &def);
+ if (fs && (! nmissing))
+ return fs;
+
+ const char *nfontname = fontname.c_str();
+#ifdef HAVE_SETLOCALE
+ if (! fs) {
+ if (nmissing) XFreeStringList(missing);
+
+ setlocale(LC_CTYPE, "C");
+ fs = XCreateFontSet(blackbox->getXDisplay(), fontname.c_str(),
+ &missing, &nmissing, &def);
+ setlocale(LC_CTYPE, "");
}
+#endif // HAVE_SETLOCALE
+
+ if (fs) {
+ XFontStruct **fontstructs;
+ char **fontnames;
+ XFontsOfFontSet(fs, &fontstructs, &fontnames);
+ nfontname = fontnames[0];
+ }
+
+ getFontElement(nfontname, weight, FONT_ELEMENT_SIZE,
+ "-medium-", "-bold-", "-demibold-", "-regular-", NULL);
+ getFontElement(nfontname, slant, FONT_ELEMENT_SIZE,
+ "-r-", "-i-", "-o-", "-ri-", "-ro-", NULL);
+ getFontSize(nfontname, &pixel_size);
+
+ if (! strcmp(weight, "*"))
+ strncpy(weight, "medium", FONT_ELEMENT_SIZE);
+ if (! strcmp(slant, "*"))
+ strncpy(slant, "r", FONT_ELEMENT_SIZE);
+ if (pixel_size < 3)
+ pixel_size = 3;
+ else if (pixel_size > 97)
+ pixel_size = 97;
+
+ buf_size = strlen(nfontname) + (FONT_ELEMENT_SIZE * 2) + 64;
+ char *pattern2 = new char[buf_size];
+ sprintf(pattern2,
+ "%s,"
+ "-*-*-%s-%s-*-*-%d-*-*-*-*-*-*-*,"
+ "-*-*-*-*-*-*-%d-*-*-*-*-*-*-*,*",
+ nfontname, weight, slant, pixel_size, pixel_size);
+ nfontname = pattern2;
+
+ if (nmissing)
+ XFreeStringList(missing);
+ if (fs)
+ XFreeFontSet(blackbox->getXDisplay(), fs);
+
+ fs = XCreateFontSet(blackbox->getXDisplay(), nfontname, &missing,
+ &nmissing, &def);
+
+ delete [] pattern2;
+
+ return fs;
+}
+++ /dev/null
-// Screen.h for Openbox
-// Copyright (c) 2001 Sean 'Shaleh' Perry <shaleh@debian.org>
-// Copyright (c) 1997 - 2000 Brad Hughes (bhughes@tcac.net)
-//
-// Permission is hereby granted, free of charge, to any person obtaining a
-// copy of this software and associated documentation files (the "Software"),
-// to deal in the Software without restriction, including without limitation
-// the rights to use, copy, modify, merge, publish, distribute, sublicense,
-// and/or sell copies of the Software, and to permit persons to whom the
-// Software is furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-// DEALINGS IN THE SOFTWARE.
-
-#ifndef __Screen_hh
-#define __Screen_hh
-
-#include <X11/Xlib.h>
-#include <X11/Xresource.h>
-
-#ifdef TIME_WITH_SYS_TIME
-# include <sys/time.h>
-# include <time.h>
-#else // !TIME_WITH_SYS_TIME
-# ifdef HAVE_SYS_TIME_H
-# include <sys/time.h>
-# else // !HAVE_SYS_TIME_H
-# include <time.h>
-# endif // HAVE_SYS_TIME_H
-#endif // TIME_WITH_SYS_TIME
-
-#include "BaseDisplay.h"
-#include "Configmenu.h"
-#include "Iconmenu.h"
-#include "Netizen.h"
-#include "Rootmenu.h"
-#include "Timer.h"
-#include "Workspace.h"
-#include "Workspacemenu.h"
-#include "openbox.h"
-#ifdef SLIT
-# include "Slit.h"
-#endif // SLIT
-#include "Image.h"
-#include "Resource.h"
-#include "Util.h"
-
-#include <list>
-#include <vector>
-
-// forward declaration
-class BScreen;
-
-struct WindowStyle {
- BColor f_focus, f_unfocus, l_text_focus, l_text_unfocus, b_pic_focus,
- b_pic_unfocus;
- BTexture t_focus, t_unfocus, l_focus, l_unfocus, h_focus, h_unfocus,
- b_focus, b_unfocus, b_pressed, g_focus, g_unfocus;
- GC l_text_focus_gc, l_text_unfocus_gc, b_pic_focus_gc, b_pic_unfocus_gc;
-
- XFontSet fontset;
- XFontSetExtents *fontset_extents;
- XFontStruct *font;
-
- int justify;
-};
-
-struct ToolbarStyle {
- BColor l_text, w_text, c_text, b_pic;
- BTexture toolbar, label, window, button, pressed, clock;
- GC l_text_gc, w_text_gc, c_text_gc, b_pic_gc;
-
- XFontSet fontset;
- XFontSetExtents *fontset_extents;
- XFontStruct *font;
-
- int justify;
-};
-
-struct MenuStyle {
- BColor t_text, f_text, h_text, d_text;
- BTexture title, frame, hilite;
- GC t_text_gc, f_text_gc, h_text_gc, d_text_gc, hilite_gc;
-
- XFontSet t_fontset, f_fontset;
- XFontSetExtents *t_fontset_extents, *f_fontset_extents;
- XFontStruct *t_font, *f_font;
-
- int t_justify, f_justify, bullet, bullet_pos;
-};
-
-
-class BScreen : public ScreenInfo {
-private:
- Bool root_colormap_installed, managed, geom_visible;
- GC opGC;
- Pixmap geom_pixmap;
- Window geom_window;
-
- Openbox &openbox;
- Resource &config;
- BImageControl *image_control;
- Configmenu *configmenu;
- Iconmenu *iconmenu;
- Rootmenu *rootmenu;
-
- typedef std::list<Rootmenu *> menuList;
- menuList rootmenuList;
- typedef std::list<Netizen *> netList;
- netList netizenList;
- typedef std::list<OpenboxWindow *> winList;
- winList iconList; // winList is declared in Workspace.h
-
-#ifdef SLIT
- Slit *slit;
-#endif // SLIT
-
- Toolbar *toolbar;
- Workspace *current_workspace;
- Workspacemenu *workspacemenu;
-
- unsigned int geom_w, geom_h;
- unsigned long event_mask;
-
- typedef std::vector<std::string> wkspNameList;
- wkspNameList workspaceNames;
- typedef std::vector<Workspace *> wkspList;
- wkspList workspacesList;
-
- struct resource {
- WindowStyle wstyle;
- ToolbarStyle tstyle;
- MenuStyle mstyle;
-
- bool sloppy_focus, auto_raise, auto_edge_balance, focus_last,
- ordered_dither, opaque_move, hide_toolbar, full_max, focus_new;
- BColor border_color;
- Resource styleconfig;
-
- int workspaces, placement_policy, edge_snap_threshold, row_direction,
- col_direction;
-
- unsigned int handle_width, bevel_width, frame_width, border_width;
- int zones; // number of zones to be used when alt-resizing a window
-
-#ifdef HAVE_STRFTIME
- char *strftime_format;
-#else // !HAVE_STRFTIME
- bool clock24hour;
- int date_format;
-#endif // HAVE_STRFTIME
-
- char *root_command;
- } resource;
-
-
-protected:
- Bool parseMenuFile(FILE *, Rootmenu *);
-
- void readDatabaseTexture(const char *, const char *, BTexture *,
- unsigned long);
- void readDatabaseColor(const char *, const char *, BColor *, unsigned long);
-
- void readDatabaseFontSet(const char *, const char *, XFontSet *);
- XFontSet createFontSet(const char *);
- void readDatabaseFont(const char *, const char *, XFontStruct **);
-
- void InitMenu();
- void LoadStyle();
-
-
-public:
- BScreen(Openbox &, int, Resource &);
- ~BScreen();
-
- inline const Bool &isScreenManaged() const { return managed; }
- inline const GC &getOpGC() const { return opGC; }
-
- inline Openbox &getOpenbox() { return openbox; }
- inline BColor *getBorderColor() { return &resource.border_color; }
- inline BImageControl *getImageControl() { return image_control; }
- inline Rootmenu *getRootmenu() { return rootmenu; }
-
-#ifdef SLIT
- inline Slit *getSlit() { return slit; }
-#endif // SLIT
-
- inline Toolbar *getToolbar() { return toolbar; }
-
- Rect availableArea() const;
-
- inline Workspace *getWorkspace(unsigned int w) {
- ASSERT(w < workspacesList.size());
- return workspacesList[w];
- }
- inline Workspace *getCurrentWorkspace() { return current_workspace; }
-
- inline Workspacemenu *getWorkspacemenu() { return workspacemenu; }
-
- inline void iconUpdate() { iconmenu->update(); }
-
- inline const unsigned int &getHandleWidth() const
- { return resource.handle_width; }
- inline const unsigned int &getBevelWidth() const
- { return resource.bevel_width; }
- inline const unsigned int &getFrameWidth() const
- { return resource.frame_width; }
- inline const unsigned int &getBorderWidth() const
- { return resource.border_width; }
-
- inline const int getCurrentWorkspaceID()
- { return current_workspace->getWorkspaceID(); }
- inline const int getWorkspaceCount() { return workspacesList.size(); }
- inline const int getIconCount() { return iconList.size(); }
-
- inline const Bool &isRootColormapInstalled() const
- { return root_colormap_installed; }
- inline void setRootColormapInstalled(Bool r) { root_colormap_installed = r; }
-
- inline bool sloppyFocus() const { return resource.sloppy_focus; }
- void setSloppyFocus(bool s);
-
- inline bool autoRaise() const { return resource.auto_raise; }
- void setAutoRaise(bool a);
-
- inline bool imageDither() const { return image_control->doDither(); }
- void setImageDither(bool d, bool reconfig = true);
-
- inline bool orderedDither() const { return resource.ordered_dither; }
-
- inline bool opaqueMove() const { return resource.opaque_move; }
- void setOpaqueMove(bool o);
-
- inline bool fullMax() const { return resource.full_max; }
- void setFullMax(bool f);
-
- inline bool focusNew() const { return resource.focus_new; }
- void setFocusNew(bool f);
-
- inline bool focusLast() const { return resource.focus_last; }
- void setFocusLast(bool f);
-
- inline int getWindowZones() const { return resource.zones; }
- void setWindowZones(int z);
-
- inline int workspaceCount() const { return resource.workspaces; }
- void setWorkspaceCount(int w);
-
- inline int placementPolicy() const { return resource.placement_policy; }
- void setPlacementPolicy(int p);
-
- inline int edgeSnapThreshold() const { return resource.edge_snap_threshold; }
- void setEdgeSnapThreshold(int t);
-
- inline int rowPlacementDirection() const { return resource.row_direction; }
- void setRowPlacementDirection(int d);
-
- inline int colPlacementDirection() const { return resource.col_direction; }
- void setColPlacementDirection(int d);
-
- inline char *rootCommand() const { return resource.root_command; }
- inline void setRootCommand(const char *cmd);
-
-#ifdef HAVE_STRFTIME
- inline char *strftimeFormat() { return resource.strftime_format; }
- void setStrftimeFormat(const char *);
-#else // !HAVE_STRFTIME
- inline int dateFormat() { return resource.date_format; }
- void setDateFormat(int f);
- inline bool clock24Hour() { return resource.clock24hour; }
- void setClock24Hour(Bool c);
-#endif // HAVE_STRFTIME
-
- inline bool hideToolbar() const { return resource.hide_toolbar; }
- void setHideToolbar(bool);
-
- inline WindowStyle *getWindowStyle() { return &resource.wstyle; }
- inline MenuStyle *getMenuStyle() { return &resource.mstyle; }
- inline ToolbarStyle *getToolbarStyle() { return &resource.tstyle; }
-
- OpenboxWindow *getIcon(int);
-
- int addWorkspace();
- int removeLastWorkspace();
-
- void removeWorkspaceNames();
- void addWorkspaceName(const char *);
- void saveWorkspaceNames();
- void addNetizen(Netizen *);
- void removeNetizen(Window);
- void addIcon(OpenboxWindow *);
- void removeIcon(OpenboxWindow *);
- const char *getNameOfWorkspace(int);
- void changeWorkspaceID(int);
- void raiseWindows(Window *, int);
- void reassociateWindow(OpenboxWindow *, int, Bool);
- void prevFocus();
- void nextFocus();
- void raiseFocus();
- void reconfigure();
- void load();
- void save();
- void rereadMenu();
- void shutdown();
- void showPosition(int, int);
- void showGeometry(unsigned int, unsigned int);
- void hideGeometry();
- void updateNetizenCurrentWorkspace();
- void updateNetizenWorkspaceCount();
- void updateNetizenWindowFocus();
- void updateNetizenWindowAdd(Window, unsigned long);
- void updateNetizenWindowDel(Window);
- void updateNetizenConfigNotify(XEvent *);
- void updateNetizenWindowRaise(Window);
- void updateNetizenWindowLower(Window);
-
- enum { RowSmartPlacement = 1, ColSmartPlacement, CascadePlacement,
- BestFitPlacement, UnderMousePlacement, ClickMousePlacement,
- LeftRight, RightLeft, TopBottom, BottomTop };
- enum { LeftJustify = 1, RightJustify, CenterJustify };
- enum { RoundBullet = 1, TriangleBullet, SquareBullet, NoBullet };
- enum { Restart = 1, RestartOther, Exit, Shutdown, Execute, Reconfigure,
- WindowShade, WindowIconify, WindowMaximize, WindowClose, WindowRaise,
- WindowLower, WindowStick, WindowKill, SetStyle };
-};
-
-
-#endif // __Screen_hh
--- /dev/null
+// -*- mode: C++; indent-tabs-mode: nil; c-basic-offset: 2; -*-
+// Screen.hh for Blackbox - an X11 Window manager
+// Copyright (c) 2001 - 2002 Sean 'Shaleh' Perry <shaleh@debian.org>
+// Copyright (c) 1997 - 2000 Brad Hughes (bhughes@tcac.net)
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#ifndef __Screen_hh
+#define __Screen_hh
+
+extern "C" {
+#include <X11/Xlib.h>
+#include <X11/Xresource.h>
+
+#ifdef TIME_WITH_SYS_TIME
+# include <sys/time.h>
+# include <time.h>
+#else // !TIME_WITH_SYS_TIME
+# ifdef HAVE_SYS_TIME_H
+# include <sys/time.h>
+# else // !HAVE_SYS_TIME_H
+# include <time.h>
+# endif // HAVE_SYS_TIME_H
+#endif // TIME_WITH_SYS_TIME
+}
+
+#include <list>
+#include <vector>
+
+#include "Color.hh"
+#include "Texture.hh"
+#include "Configmenu.hh"
+#include "Iconmenu.hh"
+#include "Netizen.hh"
+#include "Rootmenu.hh"
+#include "Timer.hh"
+#include "Workspace.hh"
+#include "Workspacemenu.hh"
+#include "blackbox.hh"
+class Slit; // forward reference
+
+enum TextJustify { LeftJustify = 1, RightJustify, CenterJustify };
+
+struct WindowStyle {
+ BColor f_focus, f_unfocus, l_text_focus, l_text_unfocus, b_pic_focus,
+ b_pic_unfocus;
+ BTexture t_focus, t_unfocus, l_focus, l_unfocus, h_focus, h_unfocus,
+ b_focus, b_unfocus, b_pressed, g_focus, g_unfocus;
+
+ XFontSet fontset;
+ XFontSetExtents *fontset_extents;
+ XFontStruct *font;
+
+ TextJustify justify;
+
+ int doJustify(const char *text, int &start_pos, unsigned int max_length,
+ unsigned int modifier, bool multibyte) const;
+};
+
+struct ToolbarStyle {
+ BColor l_text, w_text, c_text, b_pic;
+ BTexture toolbar, label, window, button, pressed, clock;
+
+ XFontSet fontset;
+ XFontSetExtents *fontset_extents;
+ XFontStruct *font;
+
+ TextJustify justify;
+
+ int doJustify(const char *text, int &start_pos, unsigned int max_length,
+ unsigned int modifier, bool multibyte) const;
+};
+
+struct MenuStyle {
+ BColor t_text, f_text, h_text, d_text;
+ BTexture title, frame, hilite;
+
+ XFontSet t_fontset, f_fontset;
+ XFontSetExtents *t_fontset_extents, *f_fontset_extents;
+ XFontStruct *t_font, *f_font;
+
+ TextJustify t_justify, f_justify;
+ int bullet, bullet_pos;
+};
+
+struct Strut {
+ unsigned int top, bottom, left, right;
+
+ Strut(void): top(0), bottom(0), left(0), right(0) {}
+};
+
+class BScreen : public ScreenInfo {
+private:
+ bool root_colormap_installed, managed, geom_visible;
+ GC opGC;
+ Pixmap geom_pixmap;
+ Window geom_window;
+
+ Blackbox *blackbox;
+ BImageControl *image_control;
+ Configmenu *configmenu;
+ Iconmenu *iconmenu;
+ Rootmenu *rootmenu;
+
+ typedef std::list<Rootmenu*> RootmenuList;
+ RootmenuList rootmenuList;
+
+ typedef std::list<Netizen*> NetizenList;
+ NetizenList netizenList;
+ BlackboxWindowList iconList, windowList;
+
+ Slit *slit;
+ Toolbar *toolbar;
+ Workspace *current_workspace;
+ Workspacemenu *workspacemenu;
+
+ unsigned int geom_w, geom_h;
+ unsigned long event_mask;
+
+ Rect usableArea;
+
+ typedef std::list<Strut*> StrutList;
+ StrutList strutList;
+ typedef std::vector<std::string> WorkspaceNamesList;
+ WorkspaceNamesList workspaceNames;
+ typedef std::vector<Workspace*> WorkspaceList;
+ WorkspaceList workspacesList;
+
+ struct screen_resource {
+ WindowStyle wstyle;
+ ToolbarStyle tstyle;
+ MenuStyle mstyle;
+
+ bool toolbar_on_top, toolbar_auto_hide, sloppy_focus, auto_raise,
+ auto_edge_balance, image_dither, ordered_dither, opaque_move, full_max,
+ focus_new, focus_last, click_raise;
+ BColor border_color;
+ XrmDatabase stylerc;
+
+ unsigned int workspaces;
+ int toolbar_placement, toolbar_width_percent, placement_policy,
+ edge_snap_threshold, row_direction, col_direction;
+
+ bool slit_on_top, slit_auto_hide;
+ int slit_placement, slit_direction;
+
+ unsigned int handle_width, bevel_width, frame_width, border_width;
+
+#ifdef HAVE_STRFTIME
+ std::string strftime_format;
+#else // !HAVE_STRFTIME
+ bool clock24hour;
+ int date_format;
+#endif // HAVE_STRFTIME
+
+ } resource;
+
+ BScreen(const BScreen&);
+ BScreen& operator=(const BScreen&);
+
+ bool parseMenuFile(FILE *file, Rootmenu *menu);
+
+ BTexture readDatabaseTexture(const std::string &rname,
+ const std::string &rclass,
+ const std::string &default_color);
+ BColor readDatabaseColor(const std::string &rname,
+ const std::string &rclass,
+ const std::string &default_color);
+ XFontSet readDatabaseFontSet(const std::string &rname,
+ const std::string &rclass);
+ XFontStruct *readDatabaseFont(const std::string &rname,
+ const std::string &rclass);
+ XFontSet createFontSet(const std::string &fontname);
+
+ void InitMenu(void);
+ void LoadStyle(void);
+
+
+public:
+ enum { RowSmartPlacement = 1, ColSmartPlacement, CascadePlacement, LeftRight,
+ RightLeft, TopBottom, BottomTop };
+ enum { RoundBullet = 1, TriangleBullet, SquareBullet, NoBullet };
+ enum { Restart = 1, RestartOther, Exit, Shutdown, Execute, Reconfigure,
+ WindowShade, WindowIconify, WindowMaximize, WindowClose, WindowRaise,
+ WindowLower, WindowStick, WindowKill, SetStyle };
+ enum FocusModel { SloppyFocus, ClickToFocus };
+
+ BScreen(Blackbox *bb, unsigned int scrn);
+ ~BScreen(void);
+
+ inline bool isToolbarOnTop(void) const
+ { return resource.toolbar_on_top; }
+ inline bool doToolbarAutoHide(void) const
+ { return resource.toolbar_auto_hide; }
+ inline bool isSloppyFocus(void) const
+ { return resource.sloppy_focus; }
+ inline bool isRootColormapInstalled(void) const
+ { return root_colormap_installed; }
+ inline bool doAutoRaise(void) const { return resource.auto_raise; }
+ inline bool doClickRaise(void) const { return resource.click_raise; }
+ inline bool isScreenManaged(void) const { return managed; }
+ inline bool doImageDither(void) const
+ { return resource.image_dither; }
+ inline bool doOrderedDither(void) const
+ { return resource.ordered_dither; }
+ inline bool doOpaqueMove(void) const { return resource.opaque_move; }
+ inline bool doFullMax(void) const { return resource.full_max; }
+ inline bool doFocusNew(void) const { return resource.focus_new; }
+ inline bool doFocusLast(void) const { return resource.focus_last; }
+
+ inline const GC &getOpGC(void) const { return opGC; }
+
+ inline Blackbox *getBlackbox(void) { return blackbox; }
+ inline BColor *getBorderColor(void) { return &resource.border_color; }
+ inline BImageControl *getImageControl(void) { return image_control; }
+ inline Rootmenu *getRootmenu(void) { return rootmenu; }
+
+ inline bool isSlitOnTop(void) const { return resource.slit_on_top; }
+ inline bool doSlitAutoHide(void) const
+ { return resource.slit_auto_hide; }
+ inline Slit *getSlit(void) { return slit; }
+ inline int getSlitPlacement(void) const
+ { return resource.slit_placement; }
+ inline int getSlitDirection(void) const
+ { return resource.slit_direction; }
+ inline void saveSlitPlacement(int p) { resource.slit_placement = p; }
+ inline void saveSlitDirection(int d) { resource.slit_direction = d; }
+ inline void saveSlitOnTop(bool t) { resource.slit_on_top = t; }
+ inline void saveSlitAutoHide(bool t) { resource.slit_auto_hide = t; }
+
+ inline Toolbar *getToolbar(void) { return toolbar; }
+
+ Workspace *getWorkspace(unsigned int index);
+
+ inline Workspace *getCurrentWorkspace(void) { return current_workspace; }
+
+ inline Workspacemenu *getWorkspacemenu(void) { return workspacemenu; }
+
+ inline unsigned int getHandleWidth(void) const
+ { return resource.handle_width; }
+ inline unsigned int getBevelWidth(void) const
+ { return resource.bevel_width; }
+ inline unsigned int getFrameWidth(void) const
+ { return resource.frame_width; }
+ inline unsigned int getBorderWidth(void) const
+ { return resource.border_width; }
+
+ inline unsigned int getCurrentWorkspaceID(void)
+ { return current_workspace->getID(); }
+ inline unsigned int getWorkspaceCount(void)
+ { return workspacesList.size(); }
+ inline unsigned int getIconCount(void) { return iconList.size(); }
+ inline unsigned int getNumberOfWorkspaces(void) const
+ { return resource.workspaces; }
+ inline int getToolbarPlacement(void) const
+ { return resource.toolbar_placement; }
+ inline int getToolbarWidthPercent(void) const
+ { return resource.toolbar_width_percent; }
+ inline int getPlacementPolicy(void) const
+ { return resource.placement_policy; }
+ inline int getEdgeSnapThreshold(void) const
+ { return resource.edge_snap_threshold; }
+ inline int getRowPlacementDirection(void) const
+ { return resource.row_direction; }
+ inline int getColPlacementDirection(void) const
+ { return resource.col_direction; }
+
+ inline void setRootColormapInstalled(bool r) { root_colormap_installed = r; }
+ inline void saveSloppyFocus(bool s) { resource.sloppy_focus = s; }
+ inline void saveAutoRaise(bool a) { resource.auto_raise = a; }
+ inline void saveClickRaise(bool c) { resource.click_raise = c; }
+ inline void saveWorkspaces(unsigned int w) { resource.workspaces = w; }
+ inline void saveToolbarOnTop(bool r) { resource.toolbar_on_top = r; }
+ inline void saveToolbarAutoHide(bool r) { resource.toolbar_auto_hide = r; }
+ inline void saveToolbarWidthPercent(int w)
+ { resource.toolbar_width_percent = w; }
+ inline void saveToolbarPlacement(int p) { resource.toolbar_placement = p; }
+ inline void savePlacementPolicy(int p) { resource.placement_policy = p; }
+ inline void saveRowPlacementDirection(int d) { resource.row_direction = d; }
+ inline void saveColPlacementDirection(int d) { resource.col_direction = d; }
+ inline void saveEdgeSnapThreshold(int t)
+ { resource.edge_snap_threshold = t; }
+ inline void saveImageDither(bool d) { resource.image_dither = d; }
+ inline void saveOpaqueMove(bool o) { resource.opaque_move = o; }
+ inline void saveFullMax(bool f) { resource.full_max = f; }
+ inline void saveFocusNew(bool f) { resource.focus_new = f; }
+ inline void saveFocusLast(bool f) { resource.focus_last = f; }
+ inline void iconUpdate(void) { iconmenu->update(); }
+
+#ifdef HAVE_STRFTIME
+ inline const char *getStrftimeFormat(void)
+ { return resource.strftime_format.c_str(); }
+ void saveStrftimeFormat(const std::string& format);
+#else // !HAVE_STRFTIME
+ inline int getDateFormat(void) { return resource.date_format; }
+ inline void saveDateFormat(int f) { resource.date_format = f; }
+ inline bool isClock24Hour(void) { return resource.clock24hour; }
+ inline void saveClock24Hour(bool c) { resource.clock24hour = c; }
+#endif // HAVE_STRFTIME
+
+ inline WindowStyle *getWindowStyle(void) { return &resource.wstyle; }
+ inline MenuStyle *getMenuStyle(void) { return &resource.mstyle; }
+ inline ToolbarStyle *getToolbarStyle(void) { return &resource.tstyle; }
+
+ BlackboxWindow *getIcon(unsigned int index);
+
+ const Rect& availableArea(void) const;
+ void updateAvailableArea(void);
+ void addStrut(Strut *strut);
+ void removeStrut(Strut *strut);
+
+ unsigned int addWorkspace(void);
+ unsigned int removeLastWorkspace(void);
+ void removeWorkspaceNames(void);
+ void addWorkspaceName(const std::string& name);
+ const std::string getNameOfWorkspace(unsigned int id);
+ void changeWorkspaceID(unsigned int id);
+
+ void addNetizen(Netizen *n);
+ void removeNetizen(Window w);
+
+ void addIcon(BlackboxWindow *w);
+ void removeIcon(BlackboxWindow *w);
+
+ void manageWindow(Window w);
+ void unmanageWindow(BlackboxWindow *w, bool remap);
+ void raiseWindows(Window *workspace_stack, unsigned int num);
+ void reassociateWindow(BlackboxWindow *w, unsigned int wkspc_id,
+ bool ignore_sticky);
+ void propagateWindowName(const BlackboxWindow *bw);
+ void prevFocus(void);
+ void nextFocus(void);
+ void raiseFocus(void);
+ void reconfigure(void);
+ void toggleFocusModel(FocusModel model);
+ void updateFocusModel(void);
+ void rereadMenu(void);
+ void shutdown(void);
+ void showPosition(int x, int y);
+ void showGeometry(unsigned int gx, unsigned int gy);
+ void hideGeometry(void);
+
+ void buttonPressEvent(XButtonEvent *xbutton);
+
+ void updateNetizenCurrentWorkspace(void);
+ void updateNetizenWorkspaceCount(void);
+ void updateNetizenWindowFocus(void);
+ void updateNetizenWindowAdd(Window w, unsigned long p);
+ void updateNetizenWindowDel(Window w);
+ void updateNetizenConfigNotify(XEvent *e);
+ void updateNetizenWindowRaise(Window w);
+ void updateNetizenWindowLower(Window w);
+};
+
+
+#endif // __Screen_hh
-// Slit.cc for Openbox
-// Copyright (c) 2001 Sean 'Shaleh' Perry <shaleh@debian.org>
+// -*- mode: C++; indent-tabs-mode: nil; c-basic-offset: 2; -*-
+// Slit.cc for Blackbox - an X11 Window manager
+// Copyright (c) 2001 - 2002 Sean 'Shaleh' Perry <shaleh@debian.org>
// Copyright (c) 1997 - 2000 Brad Hughes (bhughes@tcac.net)
//
// Permission is hereby granted, free of charge, to any person obtaining a
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
-// stupid macros needed to access some functions in version 2 of the GNU C
-// library
-#ifndef _GNU_SOURCE
-#define _GNU_SOURCE
-#endif // _GNU_SOURCE
-
#ifdef HAVE_CONFIG_H
# include "../config.h"
#endif // HAVE_CONFIG_H
-#ifdef SLIT
-
+extern "C" {
#include <X11/keysym.h>
+}
+
+#include "i18n.hh"
+#include "blackbox.hh"
+#include "Image.hh"
+#include "Screen.hh"
+#include "Slit.hh"
+#include "Toolbar.hh"
-#include "i18n.h"
-#include "openbox.h"
-#include "Image.h"
-#include "Screen.h"
-#include "Slit.h"
-#include "Toolbar.h"
-#include <strstream>
-#include <string>
-using std::ends;
+Slit::Slit(BScreen *scr) {
+ screen = scr;
+ blackbox = screen->getBlackbox();
-Slit::Slit(BScreen &scr, Resource &conf) : openbox(scr.getOpenbox()),
-screen(scr), config(conf)
-{
- load();
+ on_top = screen->isSlitOnTop();
+ hidden = do_auto_hide = screen->doSlitAutoHide();
- display = screen.getBaseDisplay().getXDisplay();
+ display = screen->getBaseDisplay()->getXDisplay();
frame.window = frame.pixmap = None;
- timer = new BTimer(openbox, *this);
- // the time out is set in ::reconfigure()
- timer->fireOnce(True);
+ timer = new BTimer(blackbox, this);
+ timer->setTimeout(blackbox->getAutoRaiseDelay());
- slitmenu = new Slitmenu(*this);
+ slitmenu = new Slitmenu(this);
XSetWindowAttributes attrib;
unsigned long create_mask = CWBackPixmap | CWBackPixel | CWBorderPixel |
- CWColormap | CWOverrideRedirect | CWEventMask;
+ CWColormap | CWOverrideRedirect | CWEventMask;
attrib.background_pixmap = None;
attrib.background_pixel = attrib.border_pixel =
- screen.getBorderColor()->getPixel();
- attrib.colormap = screen.getColormap();
+ screen->getBorderColor()->pixel();
+ attrib.colormap = screen->getColormap();
attrib.override_redirect = True;
attrib.event_mask = SubstructureRedirectMask | ButtonPressMask |
- EnterWindowMask | LeaveWindowMask;
+ EnterWindowMask | LeaveWindowMask;
- frame.area = Rect(0, 0, 1, 1);
+ frame.rect.setSize(1, 1);
frame.window =
- XCreateWindow(display, screen.getRootWindow(),
- frame.area.x(), frame.area.y(),
- frame.area.w(), frame.area.h(), screen.getBorderWidth(),
- screen.getDepth(), InputOutput, screen.getVisual(),
- create_mask, &attrib);
- openbox.saveSlitSearch(frame.window, this);
+ XCreateWindow(display, screen->getRootWindow(),
+ frame.rect.x(), frame.rect.y(),
+ frame.rect.width(), frame.rect.height(),
+ screen->getBorderWidth(), screen->getDepth(), InputOutput,
+ screen->getVisual(), create_mask, &attrib);
+ blackbox->saveSlitSearch(frame.window, this);
+
+ screen->addStrut(&strut);
reconfigure();
}
-Slit::~Slit() {
- openbox.grab();
-
- if (timer->isTiming()) timer->stop();
+Slit::~Slit(void) {
delete timer;
- clientList.clear();
-
delete slitmenu;
- screen.getImageControl()->removeImage(frame.pixmap);
+ screen->getImageControl()->removeImage(frame.pixmap);
- openbox.removeSlitSearch(frame.window);
+ blackbox->removeSlitSearch(frame.window);
XDestroyWindow(display, frame.window);
-
- openbox.ungrab();
}
void Slit::addClient(Window w) {
- openbox.grab();
-
- if (openbox.validateWindow(w)) {
- SlitClient *client = new SlitClient;
- client->client_window = w;
-
- XWMHints *wmhints = XGetWMHints(display, w);
-
- if (wmhints) {
- if ((wmhints->flags & IconWindowHint) &&
- (wmhints->icon_window != None)) {
- XMoveWindow(display, client->client_window, screen.size().w() + 10,
- screen.size().h() + 10);
- XMapWindow(display, client->client_window);
-
- client->icon_window = wmhints->icon_window;
- client->window = client->icon_window;
- } else {
- client->icon_window = None;
- client->window = client->client_window;
- }
+ if (! blackbox->validateWindow(w))
+ return;
+
+ SlitClient *client = new SlitClient;
+ client->client_window = w;
+
+ XWMHints *wmhints = XGetWMHints(display, w);
- XFree(wmhints);
+ if (wmhints) {
+ if ((wmhints->flags & IconWindowHint) &&
+ (wmhints->icon_window != None)) {
+ // some dock apps use separate windows, we need to hide these
+ XMoveWindow(display, client->client_window, screen->getWidth() + 10,
+ screen->getHeight() + 10);
+ XMapWindow(display, client->client_window);
+
+ client->icon_window = wmhints->icon_window;
+ client->window = client->icon_window;
} else {
client->icon_window = None;
client->window = client->client_window;
}
- XWindowAttributes attrib;
- if (XGetWindowAttributes(display, client->window, &attrib)) {
- client->width = attrib.width;
- client->height = attrib.height;
- } else {
- client->width = client->height = 64;
- }
-
- XSetWindowBorderWidth(display, client->window, 0);
+ XFree(wmhints);
+ } else {
+ client->icon_window = None;
+ client->window = client->client_window;
+ }
- XSelectInput(display, frame.window, NoEventMask);
- XSelectInput(display, client->window, NoEventMask);
+ XWindowAttributes attrib;
+ if (XGetWindowAttributes(display, client->window, &attrib)) {
+ client->rect.setSize(attrib.width, attrib.height);
+ } else {
+ client->rect.setSize(64, 64);
+ }
- XReparentWindow(display, client->window, frame.window, 0, 0);
- XMapRaised(display, client->window);
- XChangeSaveSet(display, client->window, SetModeInsert);
+ XSetWindowBorderWidth(display, client->window, 0);
- XSelectInput(display, frame.window, SubstructureRedirectMask |
- ButtonPressMask | EnterWindowMask | LeaveWindowMask);
- XSelectInput(display, client->window, StructureNotifyMask |
- SubstructureNotifyMask | EnterWindowMask);
- XFlush(display);
+ XGrabServer(display);
+ XSelectInput(display, frame.window, NoEventMask);
+ XSelectInput(display, client->window, NoEventMask);
+ XReparentWindow(display, client->window, frame.window, 0, 0);
+ XMapRaised(display, client->window);
+ XChangeSaveSet(display, client->window, SetModeInsert);
+ XSelectInput(display, frame.window, SubstructureRedirectMask |
+ ButtonPressMask | EnterWindowMask | LeaveWindowMask);
+ XSelectInput(display, client->window, StructureNotifyMask |
+ SubstructureNotifyMask | EnterWindowMask);
- clientList.push_back(client);
+ XUngrabServer(display);
- openbox.saveSlitSearch(client->client_window, this);
- openbox.saveSlitSearch(client->icon_window, this);
- reconfigure();
- }
+ clientList.push_back(client);
- openbox.ungrab();
+ blackbox->saveSlitSearch(client->client_window, this);
+ blackbox->saveSlitSearch(client->icon_window, this);
+ reconfigure();
}
-void Slit::removeClient(SlitClient *client, Bool remap) {
- openbox.removeSlitSearch(client->client_window);
- openbox.removeSlitSearch(client->icon_window);
-
+void Slit::removeClient(SlitClient *client, bool remap) {
+ blackbox->removeSlitSearch(client->client_window);
+ blackbox->removeSlitSearch(client->icon_window);
clientList.remove(client);
- screen.removeNetizen(client->window);
+ screen->removeNetizen(client->window);
- if (remap && openbox.validateWindow(client->window)) {
+ if (remap && blackbox->validateWindow(client->window)) {
+ XGrabServer(display);
XSelectInput(display, frame.window, NoEventMask);
XSelectInput(display, client->window, NoEventMask);
- XReparentWindow(display, client->window, screen.getRootWindow(),
- client->x, client->y);
+ XReparentWindow(display, client->window, screen->getRootWindow(),
+ client->rect.x(), client->rect.y());
XChangeSaveSet(display, client->window, SetModeDelete);
XSelectInput(display, frame.window, SubstructureRedirectMask |
ButtonPressMask | EnterWindowMask | LeaveWindowMask);
- XFlush(display);
+ XUngrabServer(display);
}
delete client;
}
-void Slit::removeClient(Window w, Bool remap) {
- openbox.grab();
+struct SlitClientMatch {
+ Window window;
+ SlitClientMatch(Window w): window(w) {}
+ inline bool operator()(const Slit::SlitClient* client) const {
+ return (client->window == window);
+ }
+};
- Bool reconf = False;
- slitClientList::iterator it;
- for (it = clientList.begin(); it != clientList.end(); it++)
- if ((*it)->window == w) {
- removeClient(*it, remap);
- reconf = True;
- break;
- }
+void Slit::removeClient(Window w, bool remap) {
+ SlitClientList::iterator it = clientList.begin();
+ const SlitClientList::iterator end = clientList.end();
- if (reconf)
+ it = std::find_if(it, end, SlitClientMatch(w));
+ if (it != end) {
+ removeClient(*it, remap);
reconfigure();
-
- openbox.ungrab();
-}
-
-void Slit::setOnTop(bool b) {
- m_ontop = b;
- std::ostrstream s;
- s << "session.screen" << screen.getScreenNumber() << ".slit.onTop" << ends;
- config.setValue(s.str(), m_ontop ? "True" : "False");
- s.rdbuf()->freeze(0);
-}
-
-void Slit::setAutoHide(bool b) {
- m_autohide = b;
- std::ostrstream s;
- s << "session.screen" << screen.getScreenNumber() << ".slit.autoHide" << ends;
- config.setValue(s.str(), m_autohide ? "True" : "False");
- s.rdbuf()->freeze(0);
-}
-
-void Slit::setPlacement(int p) {
- m_placement = p;
- std::ostrstream s;
- s << "session.screen" << screen.getScreenNumber() << ".slit.placement"
- << ends;
- const char *placement;
- switch (m_placement) {
- case TopLeft: placement = "TopLeft"; break;
- case CenterLeft: placement = "CenterLeft"; break;
- case BottomLeft: placement = "BottomLeft"; break;
- case TopCenter: placement = "TopCenter"; break;
- case BottomCenter: placement = "BottomCenter"; break;
- case TopRight: placement = "TopRight"; break;
- case BottomRight: placement = "BottomRight"; break;
- case CenterRight: default: placement = "CenterRight"; break;
}
- config.setValue(s.str(), placement);
- s.rdbuf()->freeze(0);
-}
-
-void Slit::setDirection(int d) {
- m_direction = d;
- std::ostrstream s;
- s << "session.screen" << screen.getScreenNumber() << ".slit.direction"
- << ends;
- config.setValue(s.str(),
- m_direction == Horizontal ? "Horizontal" : "Vertical");
- s.rdbuf()->freeze(0);
}
-void Slit::save() {
- setOnTop(m_ontop);
- setAutoHide(m_autohide);
- setPlacement(m_placement);
- setDirection(m_direction);
-}
-
-void Slit::load() {
- std::ostrstream rscreen, rname, rclass;
- std::string s;
- bool b;
- rscreen << "session.screen" << screen.getScreenNumber() << '.' << ends;
-
- rname << rscreen.str() << "slit.placement" << ends;
- rclass << rscreen.str() << "Slit.Placement" << ends;
- if (config.getValue(rname.str(), rclass.str(), s)) {
- if (0 == strncasecmp(s.c_str(), "TopLeft", s.length()))
- m_placement = TopLeft;
- else if (0 == strncasecmp(s.c_str(), "CenterLeft", s.length()))
- m_placement = CenterLeft;
- else if (0 == strncasecmp(s.c_str(), "BottomLeft", s.length()))
- m_placement = BottomLeft;
- else if (0 == strncasecmp(s.c_str(), "TopCenter", s.length()))
- m_placement = TopCenter;
- else if (0 == strncasecmp(s.c_str(), "BottomCenter", s.length()))
- m_placement = BottomCenter;
- else if (0 == strncasecmp(s.c_str(), "TopRight", s.length()))
- m_placement = TopRight;
- else if (0 == strncasecmp(s.c_str(), "BottomRight", s.length()))
- m_placement = BottomRight;
- else if (0 == strncasecmp(s.c_str(), "CenterRight", s.length()))
- m_placement = CenterRight;
- } else
- m_placement = CenterRight;
-
- rname.seekp(0); rclass.seekp(0);
- rname.rdbuf()->freeze(0); rclass.rdbuf()->freeze(0);
- rname << rscreen.str() << "slit.direction" << ends;
- rclass << rscreen.str() << "Slit.Direction" << ends;
- if (config.getValue(rname.str(), rclass.str(), s)) {
- if (0 == strncasecmp(s.c_str(), "Horizontal", s.length()))
- m_direction = Horizontal;
- else if (0 == strncasecmp(s.c_str(), "Vertical", s.length()))
- m_direction = Vertical;
- } else
- m_direction = Vertical;
-
- rname.seekp(0); rclass.seekp(0);
- rname.rdbuf()->freeze(0); rclass.rdbuf()->freeze(0);
- rname << rscreen.str() << "slit.onTop" << ends;
- rclass << rscreen.str() << "Slit.OnTop" << ends;
- if (config.getValue(rname.str(), rclass.str(), b))
- m_ontop = b;
- else
- m_ontop = false;
-
- rname.seekp(0); rclass.seekp(0);
- rname.rdbuf()->freeze(0); rclass.rdbuf()->freeze(0);
- rname << rscreen.str() << "slit.autoHide" << ends;
- rclass << rscreen.str() << "Slit.AutoHide" << ends;
- if (config.getValue(rname.str(), rclass.str(), b))
- m_hidden = m_autohide = b;
- else
- m_hidden = m_autohide = false;
-
- rscreen.rdbuf()->freeze(0);
- rname.rdbuf()->freeze(0); rclass.rdbuf()->freeze(0);
-}
void Slit::reconfigure(void) {
- timer->setTimeout(openbox.getAutoRaiseDelay());
+ SlitClientList::iterator it = clientList.begin();
+ const SlitClientList::iterator end = clientList.end();
+ SlitClient *client;
- frame.area.setSize(0, 0);
- slitClientList::const_iterator it;
+ unsigned int width = 0, height = 0;
- switch (m_direction) {
+ switch (screen->getSlitDirection()) {
case Vertical:
- for (it = clientList.begin(); it != clientList.end(); it++) {
- frame.area.setH(frame.area.h() + (*it)->height + screen.getBevelWidth());
+ for (; it != end; ++it) {
+ client = *it;
+ height += client->rect.height() + screen->getBevelWidth();
- if (frame.area.w() < (*it)->width)
- frame.area.setW((*it)->width);
+ if (width < client->rect.width())
+ width = client->rect.width();
}
- if (frame.area.w() < 1)
- frame.area.setW(1);
+ if (width < 1)
+ width = 1;
else
- frame.area.setW(frame.area.w() + (screen.getBevelWidth() * 2));
+ width += (screen->getBevelWidth() * 2);
- if (frame.area.h() < 1)
- frame.area.setH(1);
+ if (height < 1)
+ height = 1;
else
- frame.area.setH(frame.area.h() + screen.getBevelWidth());
+ height += screen->getBevelWidth();
break;
case Horizontal:
- for (it = clientList.begin(); it != clientList.end(); it++) {
- frame.area.setW(frame.area.w() + (*it)->width + screen.getBevelWidth());
+ for (; it != end; ++it) {
+ client = *it;
+ width += client->rect.width() + screen->getBevelWidth();
- if (frame.area.h() < (*it)->height)
- frame.area.setH((*it)->height);
+ if (height < client->rect.height())
+ height = client->rect.height();
}
- if (frame.area.w() < 1)
- frame.area.setW(1);
+ if (width < 1)
+ width = 1;
else
- frame.area.setW(frame.area.w() + screen.getBevelWidth());
+ width += screen->getBevelWidth();
- if (frame.area.h() < 1)
- frame.area.setH(1);
+ if (height < 1)
+ height = 1;
else
- frame.area.setH(frame.area.h() + (screen.getBevelWidth() * 2));
+ height += (screen->getBevelWidth() * 2);
break;
}
+ frame.rect.setSize(width, height);
reposition();
- XSetWindowBorderWidth(display ,frame.window, screen.getBorderWidth());
+ XSetWindowBorderWidth(display ,frame.window, screen->getBorderWidth());
XSetWindowBorder(display, frame.window,
- screen.getBorderColor()->getPixel());
+ screen->getBorderColor()->pixel());
- if (! clientList.size())
+ if (clientList.empty())
XUnmapWindow(display, frame.window);
else
XMapWindow(display, frame.window);
- Pixmap tmp = frame.pixmap;
- BImageControl *image_ctrl = screen.getImageControl();
- BTexture *texture = &(screen.getToolbarStyle()->toolbar);
- if (texture->getTexture() == (BImage_Flat | BImage_Solid)) {
- frame.pixmap = None;
- XSetWindowBackground(display, frame.window,
- texture->getColor()->getPixel());
- } else {
- frame.pixmap = image_ctrl->renderImage(frame.area.w(), frame.area.h(),
- texture);
+ BTexture *texture = &(screen->getToolbarStyle()->toolbar);
+ frame.pixmap = texture->render(frame.rect.width(), frame.rect.height(),
+ frame.pixmap);
+ if (! frame.pixmap)
+ XSetWindowBackground(display, frame.window, texture->color().pixel());
+ else
XSetWindowBackgroundPixmap(display, frame.window, frame.pixmap);
- }
- if (tmp) image_ctrl->removeImage(tmp);
+
XClearWindow(display, frame.window);
+ it = clientList.begin();
+
int x, y;
- switch (m_direction) {
+ switch (screen->getSlitDirection()) {
case Vertical:
x = 0;
- y = screen.getBevelWidth();
+ y = screen->getBevelWidth();
- for (it = clientList.begin(); it != clientList.end(); it++) {
- x = (frame.area.w() - (*it)->width) / 2;
+ for (; it != end; ++it) {
+ client = *it;
+ x = (frame.rect.width() - client->rect.width()) / 2;
- XMoveResizeWindow(display, (*it)->window, x, y,
- (*it)->width, (*it)->height);
- XMapWindow(display, (*it)->window);
+ XMoveResizeWindow(display, client->window, x, y,
+ client->rect.width(), client->rect.height());
+ XMapWindow(display, client->window);
// for ICCCM compliance
- (*it)->x = x;
- (*it)->y = y;
+ client->rect.setPos(x, y);
XEvent event;
event.type = ConfigureNotify;
event.xconfigure.display = display;
- event.xconfigure.event = (*it)->window;
- event.xconfigure.window = (*it)->window;
+ event.xconfigure.event = client->window;
+ event.xconfigure.window = client->window;
event.xconfigure.x = x;
event.xconfigure.y = y;
- event.xconfigure.width = (*it)->width;
- event.xconfigure.height = (*it)->height;
+ event.xconfigure.width = client->rect.width();
+ event.xconfigure.height = client->rect.height();
event.xconfigure.border_width = 0;
event.xconfigure.above = frame.window;
event.xconfigure.override_redirect = False;
- XSendEvent(display, (*it)->window, False, StructureNotifyMask, &event);
+ XSendEvent(display, client->window, False, StructureNotifyMask, &event);
- y += (*it)->height + screen.getBevelWidth();
+ y += client->rect.height() + screen->getBevelWidth();
}
break;
case Horizontal:
- x = screen.getBevelWidth();
+ x = screen->getBevelWidth();
y = 0;
- for (it = clientList.begin(); it != clientList.end(); it++) {
- y = (frame.area.h() - (*it)->height) / 2;
+ for (; it != end; ++it) {
+ client = *it;
+ y = (frame.rect.height() - client->rect.height()) / 2;
- XMoveResizeWindow(display, (*it)->window, x, y,
- (*it)->width, (*it)->height);
- XMapWindow(display, (*it)->window);
+ XMoveResizeWindow(display, client->window, x, y,
+ client->rect.width(), client->rect.height());
+ XMapWindow(display, client->window);
// for ICCCM compliance
- (*it)->x = x;
- (*it)->y = y;
+ client->rect.setPos(x, y);
XEvent event;
event.type = ConfigureNotify;
event.xconfigure.display = display;
- event.xconfigure.event = (*it)->window;
- event.xconfigure.window = (*it)->window;
+ event.xconfigure.event = client->window;
+ event.xconfigure.window = client->window;
event.xconfigure.x = x;
event.xconfigure.y = y;
- event.xconfigure.width = (*it)->width;
- event.xconfigure.height = (*it)->height;
+ event.xconfigure.width = client->rect.width();
+ event.xconfigure.height = client->rect.height();
event.xconfigure.border_width = 0;
event.xconfigure.above = frame.window;
event.xconfigure.override_redirect = False;
- XSendEvent(display, (*it)->window, False, StructureNotifyMask, &event);
+ XSendEvent(display, client->window, False, StructureNotifyMask, &event);
- x += (*it)->width + screen.getBevelWidth();
+ x += client->rect.width() + screen->getBevelWidth();
}
-
break;
}
}
+void Slit::updateStrut(void) {
+ strut.top = strut.bottom = strut.left = strut.right = 0;
+
+ if (! clientList.empty()) {
+ switch (screen->getSlitDirection()) {
+ case Vertical:
+ switch (screen->getSlitPlacement()) {
+ case TopCenter:
+ strut.top = getY() + getExposedHeight() +
+ (screen->getBorderWidth() * 2);
+ break;
+ case BottomCenter:
+ strut.bottom = screen->getHeight() - getY();
+ break;
+ case TopLeft:
+ case CenterLeft:
+ case BottomLeft:
+ strut.left = getExposedWidth() + (screen->getBorderWidth() * 2);
+ break;
+ case TopRight:
+ case CenterRight:
+ case BottomRight:
+ strut.right = getExposedWidth() + (screen->getBorderWidth() * 2);
+ break;
+ }
+ break;
+ case Horizontal:
+ switch (screen->getSlitPlacement()) {
+ case TopCenter:
+ case TopLeft:
+ case TopRight:
+ strut.top = getY() + getExposedHeight() +
+ (screen->getBorderWidth() * 2);
+ break;
+ case BottomCenter:
+ case BottomLeft:
+ case BottomRight:
+ strut.bottom = screen->getHeight() - getY();
+ break;
+ case CenterLeft:
+ strut.left = getExposedWidth() + (screen->getBorderWidth() * 2);
+ break;
+ case CenterRight:
+ strut.right = getExposedWidth() + (screen->getBorderWidth() * 2);
+ break;
+ }
+ break;
+ }
+ }
+
+ // update area with new Strut info
+ screen->updateAvailableArea();
+}
+
+
void Slit::reposition(void) {
// place the slit in the appropriate place
- switch (m_placement) {
+ switch (screen->getSlitPlacement()) {
case TopLeft:
- frame.area.setOrigin(0, 0);
- if (m_direction == Vertical) {
- frame.hidden = Point(screen.getBevelWidth() - screen.getBorderWidth()
- - frame.area.w(), 0);
+ frame.rect.setPos(0, 0);
+
+ if (screen->getSlitDirection() == Vertical) {
+ frame.x_hidden = screen->getBevelWidth() - screen->getBorderWidth()
+ - frame.rect.width();
+ frame.y_hidden = 0;
} else {
- frame.hidden = Point(0, screen.getBevelWidth() - screen.getBorderWidth()
- - frame.area.h());
+ frame.x_hidden = 0;
+ frame.y_hidden = screen->getBevelWidth() - screen->getBorderWidth()
+ - frame.rect.height();
}
break;
case CenterLeft:
- frame.area.setOrigin(0, (screen.size().h() - frame.area.h()) / 2);
- frame.hidden = Point(screen.getBevelWidth() - screen.getBorderWidth()
- - frame.area.w(), frame.area.y());
+ frame.rect.setPos(0, (screen->getHeight() - frame.rect.height()) / 2);
+
+ frame.x_hidden = screen->getBevelWidth() - screen->getBorderWidth()
+ - frame.rect.width();
+ frame.y_hidden = frame.rect.y();
break;
case BottomLeft:
- frame.area.setOrigin(0, screen.size().h() - frame.area.h()
- - (screen.getBorderWidth() * 2));
- if (m_direction == Vertical)
- frame.hidden = Point(screen.getBevelWidth() - screen.getBorderWidth()
- - frame.area.w(), frame.area.y());
- else
- frame.hidden = Point(0, screen.size().h() - screen.getBevelWidth()
- - screen.getBorderWidth());
+ frame.rect.setPos(0, (screen->getHeight() - frame.rect.height()
+ - (screen->getBorderWidth() * 2)));
+
+ if (screen->getSlitDirection() == Vertical) {
+ frame.x_hidden = screen->getBevelWidth() - screen->getBorderWidth()
+ - frame.rect.width();
+ frame.y_hidden = frame.rect.y();
+ } else {
+ frame.x_hidden = 0;
+ frame.y_hidden = screen->getHeight() - screen->getBevelWidth()
+ - screen->getBorderWidth();
+ }
break;
case TopCenter:
- frame.area.setOrigin((screen.size().w() - frame.area.w()) / 2, 0);
- frame.hidden = Point(frame.area.x(), screen.getBevelWidth()
- - screen.getBorderWidth() - frame.area.h());
+ frame.rect.setPos((screen->getWidth() - frame.rect.width()) / 2, 0);
+
+ frame.x_hidden = frame.rect.x();
+ frame.y_hidden = screen->getBevelWidth() - screen->getBorderWidth()
+ - frame.rect.height();
break;
case BottomCenter:
- frame.area.setOrigin((screen.size().w() - frame.area.w()) / 2,
- screen.size().h() - frame.area.h()
- - (screen.getBorderWidth() * 2));
- frame.hidden = Point(frame.area.x(), screen.size().h()
- - screen.getBevelWidth() - screen.getBorderWidth());
+ frame.rect.setPos((screen->getWidth() - frame.rect.width()) / 2,
+ (screen->getHeight() - frame.rect.height()
+ - (screen->getBorderWidth() * 2)));
+ frame.x_hidden = frame.rect.x();
+ frame.y_hidden = screen->getHeight() - screen->getBevelWidth()
+ - screen->getBorderWidth();
break;
case TopRight:
- frame.area.setOrigin(screen.size().w() - frame.area.w()
- - (screen.getBorderWidth() * 2), 0);
- if (m_direction == Vertical)
- frame.hidden = Point(screen.size().w() - screen.getBevelWidth()
- - screen.getBorderWidth(), 0);
- else
- frame.hidden = Point(frame.area.x(), screen.getBevelWidth()
- - screen.getBorderWidth() - frame.area.h());
+ frame.rect.setPos((screen->getWidth() - frame.rect.width()
+ - (screen->getBorderWidth() * 2)), 0);
+
+ if (screen->getSlitDirection() == Vertical) {
+ frame.x_hidden = screen->getWidth() - screen->getBevelWidth()
+ - screen->getBorderWidth();
+ frame.y_hidden = 0;
+ } else {
+ frame.x_hidden = frame.rect.x();
+ frame.y_hidden = screen->getBevelWidth() - screen->getBorderWidth()
+ - frame.rect.height();
+ }
break;
case CenterRight:
default:
- frame.area.setOrigin(screen.size().w() - frame.area.w()
- - (screen.getBorderWidth() * 2),
- (screen.size().h() - frame.area.h()) / 2);
- frame.hidden = Point(screen.size().w() - screen.getBevelWidth()
- - screen.getBorderWidth(), frame.area.y());
+ frame.rect.setPos((screen->getWidth() - frame.rect.width()
+ - (screen->getBorderWidth() * 2)),
+ (screen->getHeight() - frame.rect.height()) / 2);
+
+ frame.x_hidden = screen->getWidth() - screen->getBevelWidth()
+ - screen->getBorderWidth();
+ frame.y_hidden = frame.rect.y();
break;
case BottomRight:
- frame.area.setOrigin(screen.size().w() - frame.area.w()
- - (screen.getBorderWidth() * 2),
- screen.size().h() - frame.area.h()
- - (screen.getBorderWidth() * 2));
- if (m_direction == Vertical)
- frame.hidden = Point(screen.size().w() - screen.getBevelWidth()
- - screen.getBorderWidth(), frame.area.y());
- else
- frame.hidden = Point(frame.area.x(), screen.size().h() -
- screen.getBevelWidth() - screen.getBorderWidth());
+ frame.rect.setPos((screen->getWidth() - frame.rect.width()
+ - (screen->getBorderWidth() * 2)),
+ (screen->getHeight() - frame.rect.height()
+ - (screen->getBorderWidth() * 2)));
+
+ if (screen->getSlitDirection() == Vertical) {
+ frame.x_hidden = screen->getWidth() - screen->getBevelWidth()
+ - screen->getBorderWidth();
+ frame.y_hidden = frame.rect.y();
+ } else {
+ frame.x_hidden = frame.rect.x();
+ frame.y_hidden = screen->getHeight() - screen->getBevelWidth()
+ - screen->getBorderWidth();
+ }
break;
}
- Toolbar *tbar = screen.getToolbar();
- int sw = frame.area.w() + (screen.getBorderWidth() * 2),
- sh = frame.area.h() + (screen.getBorderWidth() * 2),
- tw = tbar->area().w() + screen.getBorderWidth(),
- th = tbar->area().h() + screen.getBorderWidth();
-
- if (tbar->area().x() < frame.area.x() + sw &&
- tbar->area().x() + tw > frame.area.x() &&
- tbar->area().y() < frame.area.y() + sh &&
- tbar->area().y() + th > frame.area.y()) {
- if (frame.area.y() < th) {
- frame.area.setY(frame.area.y() + tbar->getExposedHeight());
- if (m_direction == Vertical)
- frame.hidden.setY(frame.hidden.y() + tbar->getExposedHeight());
- else
- frame.hidden.setY(frame.area.y());
- } else {
- frame.area.setY(frame.area.y() - tbar->getExposedHeight());
- if (m_direction == Vertical)
- frame.hidden.setY(frame.area.y() - tbar->getExposedHeight());
- else
- frame.hidden.setY(frame.area.y());
+ Rect tbar_rect = screen->getToolbar()->getRect();
+ tbar_rect.setSize(tbar_rect.width() + (screen->getBorderWidth() * 2),
+ tbar_rect.height() + (screen->getBorderWidth() * 2));
+ Rect slit_rect = frame.rect;
+ slit_rect.setSize(slit_rect.width() + (screen->getBorderWidth() * 2),
+ slit_rect.height() + (screen->getBorderWidth() * 2));
+
+ if (slit_rect.intersects(tbar_rect)) {
+ Toolbar *tbar = screen->getToolbar();
+ frame.y_hidden = frame.rect.y();
+
+ int delta = tbar->getExposedHeight() + (screen->getBorderWidth() * 2);
+ if (frame.rect.bottom() <= tbar_rect.bottom()) {
+ delta = -delta;
}
+ frame.rect.setY(frame.rect.y() + delta);
+ if (screen->getSlitDirection() == Vertical)
+ frame.y_hidden += delta;
}
- if (m_hidden)
- XMoveResizeWindow(display, frame.window, frame.hidden.x(),
- frame.hidden.y(), frame.area.w(), frame.area.h());
+ updateStrut();
+
+ if (hidden)
+ XMoveResizeWindow(display, frame.window, frame.x_hidden,
+ frame.y_hidden, frame.rect.width(), frame.rect.height());
else
- XMoveResizeWindow(display, frame.window, frame.area.x(),
- frame.area.y(), frame.area.w(), frame.area.h());
+ XMoveResizeWindow(display, frame.window, frame.rect.x(), frame.rect.y(),
+ frame.rect.width(), frame.rect.height());
}
void Slit::shutdown(void) {
- while (clientList.size())
+ while (! clientList.empty())
removeClient(clientList.front());
}
void Slit::buttonPressEvent(XButtonEvent *e) {
if (e->window != frame.window) return;
- if (e->button == Button1 && !m_ontop) {
+ if (e->button == Button1 && (! on_top)) {
Window w[1] = { frame.window };
- screen.raiseWindows(w, 1);
- } else if (e->button == Button2 && !m_ontop) {
+ screen->raiseWindows(w, 1);
+ } else if (e->button == Button2 && (! on_top)) {
XLowerWindow(display, frame.window);
} else if (e->button == Button3) {
if (! slitmenu->isVisible()) {
if (x < 0)
x = 0;
- else if (x + slitmenu->getWidth() > screen.size().w())
- x = screen.size().w() - slitmenu->getWidth();
+ else if (x + slitmenu->getWidth() > screen->getWidth())
+ x = screen->getWidth() - slitmenu->getWidth();
if (y < 0)
y = 0;
- else if (y + slitmenu->getHeight() > screen.size().h())
- y = screen.size().h() - slitmenu->getHeight();
+ else if (y + slitmenu->getHeight() > screen->getHeight())
+ y = screen->getHeight() - slitmenu->getHeight();
slitmenu->move(x, y);
slitmenu->show();
void Slit::enterNotifyEvent(XCrossingEvent *) {
- if (!m_autohide)
+ if (! do_auto_hide)
return;
- if (m_hidden) {
+ if (hidden) {
if (! timer->isTiming()) timer->start();
} else {
if (timer->isTiming()) timer->stop();
void Slit::leaveNotifyEvent(XCrossingEvent *) {
- if (!m_autohide)
+ if (! do_auto_hide)
return;
- if (m_hidden) {
+ if (hidden) {
if (timer->isTiming()) timer->stop();
} else if (! slitmenu->isVisible()) {
- if (!timer->isTiming()) timer->start();
+ if (! timer->isTiming()) timer->start();
}
}
void Slit::configureRequestEvent(XConfigureRequestEvent *e) {
- openbox.grab();
-
- if (openbox.validateWindow(e->window)) {
- Bool reconf = False;
- XWindowChanges xwc;
-
- xwc.x = e->x;
- xwc.y = e->y;
- xwc.width = e->width;
- xwc.height = e->height;
- xwc.border_width = 0;
- xwc.sibling = e->above;
- xwc.stack_mode = e->detail;
-
- XConfigureWindow(display, e->window, e->value_mask, &xwc);
-
- slitClientList::iterator it = clientList.begin();
- for (; it != clientList.end(); it++) {
- SlitClient *client = *it;
- if (client->window == e->window)
- if (client->width != ((unsigned) e->width) ||
- client->height != ((unsigned) e->height)) {
- client->width = (unsigned) e->width;
- client->height = (unsigned) e->height;
- reconf = True;
- break;
- }
- }
+ if (! blackbox->validateWindow(e->window))
+ return;
+
+ XWindowChanges xwc;
+
+ xwc.x = e->x;
+ xwc.y = e->y;
+ xwc.width = e->width;
+ xwc.height = e->height;
+ xwc.border_width = 0;
+ xwc.sibling = e->above;
+ xwc.stack_mode = e->detail;
+
+ XConfigureWindow(display, e->window, e->value_mask, &xwc);
+
+ SlitClientList::iterator it = clientList.begin();
+ const SlitClientList::iterator end = clientList.end();
+ for (; it != end; ++it) {
+ SlitClient *client = *it;
+ if (client->window == e->window &&
+ (static_cast<signed>(client->rect.width()) != e->width ||
+ static_cast<signed>(client->rect.height()) != e->height)) {
+ client->rect.setSize(e->width, e->height);
- if (reconf)
reconfigure();
+ return;
+ }
}
- openbox.ungrab();
}
void Slit::timeout(void) {
- m_hidden = !m_hidden;
- if (m_hidden)
- XMoveWindow(display, frame.window, frame.hidden.x(), frame.hidden.y());
+ hidden = ! hidden;
+ if (hidden)
+ XMoveWindow(display, frame.window, frame.x_hidden, frame.y_hidden);
else
- XMoveWindow(display, frame.window, frame.area.x(), frame.area.y());
+ XMoveWindow(display, frame.window, frame.rect.x(), frame.rect.y());
}
-Slitmenu::Slitmenu(Slit &sl) : Basemenu(sl.screen), slit(sl) {
+void Slit::toggleAutoHide(void) {
+ do_auto_hide = (do_auto_hide) ? False : True;
+
+ updateStrut();
+
+ if (do_auto_hide == False && hidden) {
+ // force the slit to be visible
+ if (timer->isTiming()) timer->stop();
+ timeout();
+ }
+}
+
+
+void Slit::unmapNotifyEvent(XUnmapEvent *e) {
+ removeClient(e->window);
+}
+
+
+Slitmenu::Slitmenu(Slit *sl) : Basemenu(sl->screen) {
+ slit = sl;
+
setLabel(i18n(SlitSet, SlitSlitTitle, "Slit"));
setInternalMenu();
- directionmenu = new Directionmenu(*this);
- placementmenu = new Placementmenu(*this);
+ directionmenu = new Directionmenu(this);
+ placementmenu = new Placementmenu(this);
insert(i18n(CommonSet, CommonDirectionTitle, "Direction"),
directionmenu);
update();
- setValues();
-}
-
-void Slitmenu::setValues() {
- setItemSelected(2, slit.onTop());
- setItemSelected(3, slit.autoHide());
+ if (slit->isOnTop()) setItemSelected(2, True);
+ if (slit->doAutoHide()) setItemSelected(3, True);
}
}
-void Slitmenu::itemSelected(int button, int index) {
+void Slitmenu::itemSelected(int button, unsigned int index) {
if (button != 1)
return;
switch (item->function()) {
case 1: { // always on top
- bool change = ((slit.onTop()) ? false : true);
- slit.setOnTop(change);
- setItemSelected(2, change);
+ slit->on_top = ((slit->isOnTop()) ? False : True);
+ setItemSelected(2, slit->on_top);
- if (slit.onTop()) slit.screen.raiseWindows((Window *) 0, 0);
+ if (slit->isOnTop()) slit->screen->raiseWindows((Window *) 0, 0);
break;
}
case 2: { // auto hide
- Bool change = ((slit.autoHide()) ? false : true);
- slit.setAutoHide(change);
- setItemSelected(3, change);
+ slit->toggleAutoHide();
+ setItemSelected(3, slit->do_auto_hide);
break;
}
void Slitmenu::internal_hide(void) {
Basemenu::internal_hide();
- if (slit.autoHide())
- slit.timeout();
+ if (slit->doAutoHide())
+ slit->timeout();
}
void Slitmenu::reconfigure(void) {
- setValues();
directionmenu->reconfigure();
placementmenu->reconfigure();
}
-Slitmenu::Directionmenu::Directionmenu(Slitmenu &sm)
- : Basemenu(sm.slit.screen), slitmenu(sm) {
- setLabel(i18n(SlitSet, SlitSlitDirection, "Slit Direction"));
- setInternalMenu();
+Slitmenu::Directionmenu::Directionmenu(Slitmenu *sm)
+ : Basemenu(sm->slit->screen) {
- insert(i18n(CommonSet, CommonDirectionHoriz, "Horizontal"),
- Slit::Horizontal);
- insert(i18n(CommonSet, CommonDirectionVert, "Vertical"),
- Slit::Vertical);
-
- update();
+ setLabel(i18n(SlitSet, SlitSlitDirection, "Slit Direction"));
+ setInternalMenu();
- setValues();
- }
+ insert(i18n(CommonSet, CommonDirectionHoriz, "Horizontal"),
+ Slit::Horizontal);
+ insert(i18n(CommonSet, CommonDirectionVert, "Vertical"),
+ Slit::Vertical);
+ update();
-void Slitmenu::Directionmenu::setValues() {
- if (slitmenu.slit.direction() == Slit::Horizontal)
+ if (getScreen()->getSlitDirection() == Slit::Horizontal)
setItemSelected(0, True);
else
setItemSelected(1, True);
}
-void Slitmenu::Directionmenu::reconfigure() {
- setValues();
- Basemenu::reconfigure();
-}
-
-void Slitmenu::Directionmenu::itemSelected(int button, int index) {
+void Slitmenu::Directionmenu::itemSelected(int button, unsigned int index) {
if (button != 1)
return;
BasemenuItem *item = find(index);
if (! item) return;
- slitmenu.slit.setDirection(item->function());
+ getScreen()->saveSlitDirection(item->function());
if (item->function() == Slit::Horizontal) {
setItemSelected(0, True);
}
hide();
- slitmenu.slit.reconfigure();
+ getScreen()->getSlit()->reconfigure();
}
-Slitmenu::Placementmenu::Placementmenu(Slitmenu &sm)
- : Basemenu(sm.slit.screen), slitmenu(sm) {
-
- setLabel(i18n(SlitSet, SlitSlitPlacement, "Slit Placement"));
- setMinimumSublevels(3);
- setInternalMenu();
-
- insert(i18n(CommonSet, CommonPlacementTopLeft, "Top Left"),
- Slit::TopLeft);
- insert(i18n(CommonSet, CommonPlacementCenterLeft, "Center Left"),
- Slit::CenterLeft);
- insert(i18n(CommonSet, CommonPlacementBottomLeft, "Bottom Left"),
- Slit::BottomLeft);
- insert(i18n(CommonSet, CommonPlacementTopCenter, "Top Center"),
- Slit::TopCenter);
- insert("");
- insert(i18n(CommonSet, CommonPlacementBottomCenter,
- "Bottom Center"),
- Slit::BottomCenter);
- insert(i18n(CommonSet, CommonPlacementTopRight, "Top Right"),
- Slit::TopRight);
- insert(i18n(CommonSet, CommonPlacementCenterRight,
- "Center Right"),
- Slit::CenterRight);
- insert(i18n(CommonSet, CommonPlacementBottomRight,
- "Bottom Right"),
- Slit::BottomRight);
-
- update();
- }
+Slitmenu::Placementmenu::Placementmenu(Slitmenu *sm)
+ : Basemenu(sm->slit->screen) {
+
+ setLabel(i18n(SlitSet, SlitSlitPlacement, "Slit Placement"));
+ setMinimumSublevels(3);
+ setInternalMenu();
+
+ insert(i18n(CommonSet, CommonPlacementTopLeft, "Top Left"),
+ Slit::TopLeft);
+ insert(i18n(CommonSet, CommonPlacementCenterLeft, "Center Left"),
+ Slit::CenterLeft);
+ insert(i18n(CommonSet, CommonPlacementBottomLeft, "Bottom Left"),
+ Slit::BottomLeft);
+ insert(i18n(CommonSet, CommonPlacementTopCenter, "Top Center"),
+ Slit::TopCenter);
+ insert("");
+ insert(i18n(CommonSet, CommonPlacementBottomCenter, "Bottom Center"),
+ Slit::BottomCenter);
+ insert(i18n(CommonSet, CommonPlacementTopRight, "Top Right"),
+ Slit::TopRight);
+ insert(i18n(CommonSet, CommonPlacementCenterRight, "Center Right"),
+ Slit::CenterRight);
+ insert(i18n(CommonSet, CommonPlacementBottomRight, "Bottom Right"),
+ Slit::BottomRight);
+
+ update();
+}
-void Slitmenu::Placementmenu::itemSelected(int button, int index) {
+void Slitmenu::Placementmenu::itemSelected(int button, unsigned int index) {
if (button != 1)
return;
BasemenuItem *item = find(index);
if (! (item && item->function())) return;
- slitmenu.slit.setPlacement(item->function());
+ getScreen()->saveSlitPlacement(item->function());
hide();
- slitmenu.slit.reconfigure();
+ getScreen()->getSlit()->reconfigure();
}
-#endif // SLIT
+++ /dev/null
-// Slit.h for Openbox
-// Copyright (c) 2001 Sean 'Shaleh' Perry <shaleh@debian.org>
-// Copyright (c) 1997 - 2000 Brad Hughes (bhughes@tcac.net)
-//
-// Permission is hereby granted, free of charge, to any person obtaining a
-// copy of this software and associated documentation files (the "Software"),
-// to deal in the Software without restriction, including without limitation
-// the rights to use, copy, modify, merge, publish, distribute, sublicense,
-// and/or sell copies of the Software, and to permit persons to whom the
-// Software is furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-// DEALINGS IN THE SOFTWARE.
-
-#ifndef __Slit_hh
-#define __Slit_hh
-
-#include <X11/Xlib.h>
-#include <X11/Xutil.h>
-
-#include "Basemenu.h"
-#include "Geometry.h"
-#include <list>
-
-// forward declaration
-class Slit;
-class Slitmenu;
-
-class Slitmenu : public Basemenu {
-private:
- class Directionmenu : public Basemenu {
- private:
- Slitmenu &slitmenu;
-
- protected:
- virtual void itemSelected(int, int);
- virtual void setValues();
-
- public:
- Directionmenu(Slitmenu &);
- void reconfigure();
- };
-
- class Placementmenu : public Basemenu {
- private:
- Slitmenu &slitmenu;
-
- protected:
- virtual void itemSelected(int, int);
-
- public:
- Placementmenu(Slitmenu &);
- };
-
- Directionmenu *directionmenu;
- Placementmenu *placementmenu;
-
- Slit &slit;
-
- friend class Directionmenu;
- friend class Placementmenu;
- friend class Slit;
-
-
-protected:
- virtual void itemSelected(int, int);
- virtual void internal_hide();
- virtual void setValues();
-
-public:
- Slitmenu(Slit &);
- virtual ~Slitmenu();
-
- inline Basemenu *getDirectionmenu() { return directionmenu; }
- inline Basemenu *getPlacementmenu() { return placementmenu; }
-
- void reconfigure();
-};
-
-
-class Slit : public TimeoutHandler {
-private:
- class SlitClient {
- public:
- Window window, client_window, icon_window;
-
- int x, y;
- unsigned int width, height;
- };
-
- bool m_ontop, m_autohide, m_hidden;
- int m_direction, m_placement;
- Display *display;
-
- Openbox &openbox;
- BScreen &screen;
- Resource &config;
- BTimer *timer;
-
- typedef std::list<SlitClient *> slitClientList;
- slitClientList clientList;
- Slitmenu *slitmenu;
-
- struct frame {
- Pixmap pixmap;
- Window window;
-
- Rect area;
- Point hidden;
- } frame;
-
-
- friend class Slitmenu;
- friend class Slitmenu::Directionmenu;
- friend class Slitmenu::Placementmenu;
-
-
-public:
- Slit(BScreen &, Resource &);
- virtual ~Slit();
-
- inline Slitmenu *getMenu() { return slitmenu; }
-
- inline const Window &getWindowID() const { return frame.window; }
-
- inline const Point &origin() const { return frame.area.origin(); }
- inline const Size &size() const { return frame.area.size(); }
- inline const Rect &area() const { return frame.area; }
- inline const Point &hiddenOrigin() const { return frame.hidden; }
-
- void addClient(Window);
- void removeClient(SlitClient *, Bool = True);
- void removeClient(Window, Bool = True);
- void reconfigure();
- void load();
- void save();
- void reposition();
- void shutdown();
-
- void buttonPressEvent(XButtonEvent *);
- void enterNotifyEvent(XCrossingEvent *);
- void leaveNotifyEvent(XCrossingEvent *);
- void configureRequestEvent(XConfigureRequestEvent *);
-
- virtual void timeout();
-
- inline bool isHidden() const { return m_hidden; }
-
- inline bool onTop() const { return m_ontop; }
- void setOnTop(bool);
-
- inline bool autoHide() const { return m_autohide; }
- void setAutoHide(bool);
-
- inline int placement() const { return m_placement; }
- void setPlacement(int);
-
- inline int direction() const { return m_direction; }
- void setDirection(int);
-
- enum { Vertical = 1, Horizontal };
- enum { TopLeft = 1, CenterLeft, BottomLeft, TopCenter, BottomCenter,
- TopRight, CenterRight, BottomRight };
-};
-
-
-#endif // __Slit_hh
--- /dev/null
+// -*- mode: C++; indent-tabs-mode: nil; c-basic-offset: 2; -*-
+// Texture.cc for Blackbox - an X11 Window manager
+// Copyright (c) 2001 - 2002 Sean 'Shaleh' Perry <shaleh at debian.org>
+// Copyright (c) 1997 - 2000, 2002 Bradley T Hughes <bhughes at trolltech.com>
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#ifdef HAVE_CONFIG_H
+# include "../config.h"
+#endif // HAVE_CONFIG_H
+
+extern "C" {
+#include <stdio.h>
+#ifdef HAVE_CTYPE_H
+#include <ctype.h>
+#endif
+}
+
+#include "Texture.hh"
+#include "BaseDisplay.hh"
+#include "Image.hh"
+#include "Screen.hh"
+#include "blackbox.hh"
+
+using std::string;
+
+
+BTexture::BTexture(const BaseDisplay * const _display,
+ unsigned int _screen, BImageControl* _ctrl)
+ : c(_display, _screen), ct(_display, _screen),
+ lc(_display, _screen), sc(_display, _screen), t(0),
+ dpy(_display), ctrl(_ctrl), scrn(_screen) { }
+
+
+BTexture::BTexture(const string &d, const BaseDisplay * const _display,
+ unsigned int _screen, BImageControl* _ctrl)
+ : c(_display, _screen), ct(_display, _screen),
+ lc(_display, _screen), sc(_display, _screen), t(0),
+ dpy(_display), ctrl(_ctrl), scrn(_screen) {
+ setDescription(d);
+}
+
+
+void BTexture::setColor(const BColor &cc) {
+ c = cc;
+ c.setDisplay(display(), screen());
+
+ unsigned char r, g, b, rr, gg, bb;
+
+ // calculate the light color
+ r = c.red();
+ g = c.green();
+ b = c.blue();
+ rr = r + (r >> 1);
+ gg = g + (g >> 1);
+ bb = b + (b >> 1);
+ if (rr < r) rr = ~0;
+ if (gg < g) gg = ~0;
+ if (bb < b) bb = ~0;
+ lc = BColor(rr, gg, bb, display(), screen());
+
+ // calculate the shadow color
+ r = c.red();
+ g = c.green();
+ b = c.blue();
+ rr = (r >> 2) + (r >> 1);
+ gg = (g >> 2) + (g >> 1);
+ bb = (b >> 2) + (b >> 1);
+ if (rr > r) rr = 0;
+ if (gg > g) gg = 0;
+ if (bb > b) bb = 0;
+ sc = BColor(rr, gg, bb, display(), screen());
+}
+
+
+void BTexture::setDescription(const string &d) {
+ descr.erase();
+ descr.reserve(d.length());
+
+ string::const_iterator it = d.begin(), end = d.end();
+ for (; it != end; ++it)
+ descr += tolower(*it);
+
+ if (descr.find("parentrelative") != string::npos) {
+ setTexture(BTexture::Parent_Relative);
+ } else {
+ setTexture(0);
+
+ if (descr.find("gradient") != string::npos) {
+ addTexture(BTexture::Gradient);
+ if (descr.find("crossdiagonal") != string::npos)
+ addTexture(BTexture::CrossDiagonal);
+ else if (descr.find("rectangle") != string::npos)
+ addTexture(BTexture::Rectangle);
+ else if (descr.find("pyramid") != string::npos)
+ addTexture(BTexture::Pyramid);
+ else if (descr.find("pipecross") != string::npos)
+ addTexture(BTexture::PipeCross);
+ else if (descr.find("elliptic") != string::npos)
+ addTexture(BTexture::Elliptic);
+ else if (descr.find("diagonal") != string::npos)
+ addTexture(BTexture::Diagonal);
+ else if (descr.find("horizontal") != string::npos)
+ addTexture(BTexture::Horizontal);
+ else if (descr.find("vertical") != string::npos)
+ addTexture(BTexture::Vertical);
+ else
+ addTexture(BTexture::Diagonal);
+ } else {
+ addTexture(BTexture::Solid);
+ }
+
+ if (descr.find("raised") != string::npos)
+ addTexture(BTexture::Raised);
+ else if (descr.find("sunken") != string::npos)
+ addTexture(BTexture::Sunken);
+ else if (descr.find("flat") != string::npos)
+ addTexture(BTexture::Flat);
+ else
+ addTexture(BTexture::Raised);
+
+ if (! (texture() & BTexture::Flat)) {
+ if (descr.find("bevel2") != string::npos)
+ addTexture(BTexture::Bevel2);
+ else
+ addTexture(BTexture::Bevel1);
+ }
+
+ if (descr.find("interlaced") != string::npos)
+ addTexture(BTexture::Interlaced);
+ }
+}
+
+void BTexture::setDisplay(const BaseDisplay * const _display,
+ const unsigned int _screen) {
+ if (_display == display() && _screen == screen()) {
+ // nothing to do
+ return;
+ }
+
+ dpy = _display;
+ scrn = _screen;
+ c.setDisplay(_display, _screen);
+ ct.setDisplay(_display, _screen);
+ lc.setDisplay(_display, _screen);
+ sc.setDisplay(_display, _screen);
+}
+
+
+BTexture& BTexture::operator=(const BTexture &tt) {
+ c = tt.c;
+ ct = tt.ct;
+ lc = tt.lc;
+ sc = tt.sc;
+ descr = tt.descr;
+ t = tt.t;
+ dpy = tt.dpy;
+ scrn = tt.scrn;
+ ctrl = tt.ctrl;
+
+ return *this;
+}
+
+
+Pixmap BTexture::render(const unsigned int width, const unsigned int height,
+ const Pixmap old) {
+ assert(display() != 0);
+
+ if (texture() == (BTexture::Flat | BTexture::Solid))
+ return None;
+ if (texture() == BTexture::Parent_Relative)
+ return ParentRelative;
+
+ if (screen() == ~(0u))
+ scrn = DefaultScreen(display()->getXDisplay());
+
+ assert(ctrl != 0);
+ Pixmap ret = ctrl->renderImage(width, height, *this);
+
+ if (old)
+ ctrl->removeImage(old);
+
+ return ret;
+}
--- /dev/null
+// -*- mode: C++; indent-tabs-mode: nil; c-basic-offset: 2; -*-
+// Texture.hh for Blackbox - an X11 Window manager
+// Copyright (c) 2001 - 2002 Sean 'Shaleh' Perry <shaleh at debian.org>
+// Copyright (c) 1997 - 2000, 2002 Bradley T Hughes <bhughes at trolltech.com>
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#ifndef TEXTURE_HH
+#define TEXTURE_HH
+
+#include "Color.hh"
+#include "Util.hh"
+class BImageControl;
+
+#include <string>
+
+class BTexture {
+public:
+ enum Type {
+ // bevel options
+ Flat = (1l<<0),
+ Sunken = (1l<<1),
+ Raised = (1l<<2),
+ // textures
+ Solid = (1l<<3),
+ Gradient = (1l<<4),
+ // gradients
+ Horizontal = (1l<<5),
+ Vertical = (1l<<6),
+ Diagonal = (1l<<7),
+ CrossDiagonal = (1l<<8),
+ Rectangle = (1l<<9),
+ Pyramid = (1l<<10),
+ PipeCross = (1l<<11),
+ Elliptic = (1l<<12),
+ // bevel types
+ Bevel1 = (1l<<13),
+ Bevel2 = (1l<<14),
+ // inverted image
+ Invert = (1l<<15),
+ // parent relative image
+ Parent_Relative = (1l<<16),
+ // fake interlaced image
+ Interlaced = (1l<<17)
+ };
+
+ BTexture(const BaseDisplay * const _display = 0,
+ unsigned int _screen = ~(0u), BImageControl* _ctrl = 0);
+ BTexture(const std::string &_description,
+ const BaseDisplay * const _display = 0,
+ unsigned int _screen = ~(0u), BImageControl* _ctrl = 0);
+
+ void setColor(const BColor &_color);
+ void setColorTo(const BColor &_colorTo) { ct = _colorTo; }
+
+ const BColor &color(void) const { return c; }
+ const BColor &colorTo(void) const { return ct; }
+ const BColor &lightColor(void) const { return lc; }
+ const BColor &shadowColor(void) const { return sc; }
+
+ unsigned long texture(void) const { return t; }
+ void setTexture(const unsigned long _texture) { t = _texture; }
+ void addTexture(const unsigned long _texture) { t |= _texture; }
+
+ BTexture &operator=(const BTexture &tt);
+ inline bool operator==(const BTexture &tt)
+ { return (c == tt.c && ct == tt.ct && lc == tt.lc &&
+ sc == tt.sc && t == tt.t); }
+ inline bool operator!=(const BTexture &tt)
+ { return (! operator==(tt)); }
+
+ const BaseDisplay *display(void) const { return dpy; }
+ unsigned int screen(void) const { return scrn; }
+ void setDisplay(const BaseDisplay * const _display,
+ const unsigned int _screen);
+ void setImageControl(BImageControl* _ctrl) { ctrl = _ctrl; }
+ const std::string &description(void) const { return descr; }
+ void setDescription(const std::string &d);
+
+ Pixmap render(const unsigned int width, const unsigned int height,
+ const Pixmap old = 0);
+
+private:
+ BColor c, ct, lc, sc;
+ std::string descr;
+ unsigned long t;
+ const BaseDisplay *dpy;
+ BImageControl *ctrl;
+ unsigned int scrn;
+};
+
+#endif // TEXTURE_HH
-// Timer.cc for Openbox
-// Copyright (c) 2001 Sean 'Shaleh' Perry <shaleh@debian.org>
+// -*- mode: C++; indent-tabs-mode: nil; -*-
+// Timer.cc for Blackbox - An X11 Window Manager
+// Copyright (c) 2001 - 2002 Sean 'Shaleh' Perry <shaleh@debian.org>
// Copyright (c) 1997 - 2000 Brad Hughes (bhughes@tcac.net)
//
// Permission is hereby granted, free of charge, to any person obtaining a
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
-// stupid macros needed to access some functions in version 2 of the GNU C
-// library
-#ifndef _GNU_SOURCE
-# define _GNU_SOURCE
-#endif // _GNU_SOURCE
-
#ifdef HAVE_CONFIG_H
# include "../config.h"
#endif // HAVE_CONFIG_H
-#include "BaseDisplay.h"
-#include "Timer.h"
+#include "BaseDisplay.hh"
+#include "Timer.hh"
+#include "Util.hh"
+
+BTimer::BTimer(TimerQueueManager *m, TimeoutHandler *h) {
+ manager = m;
+ handler = h;
-BTimer::BTimer(BaseDisplay &d, TimeoutHandler &h) : display(d), handler(h) {
- once = timing = False;
+ recur = timing = False;
}
+
BTimer::~BTimer(void) {
if (timing) stop();
}
+
void BTimer::setTimeout(long t) {
_timeout.tv_sec = t / 1000;
- _timeout.tv_usec = t;
- _timeout.tv_usec -= (_timeout.tv_sec * 1000);
+ _timeout.tv_usec = t % 1000;
_timeout.tv_usec *= 1000;
- if (timing) {
- display.removeTimer(this);
- display.addTimer(this); // reorder the display
- }
}
-void BTimer::setTimeout(timeval t) {
+
+void BTimer::setTimeout(const timeval &t) {
_timeout.tv_sec = t.tv_sec;
_timeout.tv_usec = t.tv_usec;
}
+
void BTimer::start(void) {
gettimeofday(&_start, 0);
if (! timing) {
timing = True;
- display.addTimer(this);
+ manager->addTimer(this);
}
}
+
void BTimer::stop(void) {
- if (timing) {
- timing = False;
+ timing = False;
- display.removeTimer(this);
- }
+ manager->removeTimer(this);
}
+
+void BTimer::halt(void) {
+ timing = False;
+}
+
+
void BTimer::fireTimeout(void) {
- handler.timeout();
+ if (handler)
+ handler->timeout();
+}
+
+
+timeval BTimer::timeRemaining(const timeval &tm) const {
+ timeval ret = endpoint();
+
+ ret.tv_sec -= tm.tv_sec;
+ ret.tv_usec -= tm.tv_usec;
+
+ return normalizeTimeval(ret);
+}
+
+
+timeval BTimer::endpoint(void) const {
+ timeval ret;
+
+ ret.tv_sec = _start.tv_sec + _timeout.tv_sec;
+ ret.tv_usec = _start.tv_usec + _timeout.tv_usec;
+
+ return normalizeTimeval(ret);
+}
+
+
+bool BTimer::shouldFire(const timeval &tm) const {
+ timeval end = endpoint();
+
+ return !((tm.tv_sec < end.tv_sec) ||
+ (tm.tv_sec == end.tv_sec && tm.tv_usec < end.tv_usec));
}
+++ /dev/null
-// Timer.h for Openbox
-// Copyright (c) 2001 Sean 'Shaleh' Perry <shaleh@debian.org>
-// Copyright (c) 1997 - 2000 Brad Hughes (bhughes@tcac.net)
-//
-// Permission is hereby granted, free of charge, to any person obtaining a
-// copy of this software and associated documentation files (the "Software"),
-// to deal in the Software without restriction, including without limitation
-// the rights to use, copy, modify, merge, publish, distribute, sublicense,
-// and/or sell copies of the Software, and to permit persons to whom the
-// Software is furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-// DEALINGS IN THE SOFTWARE.
-
-#ifndef __Timer_hh
-#define __Timer_hh
-
-#ifdef TIME_WITH_SYS_TIME
-# include <sys/time.h>
-# include <time.h>
-#else // !TIME_WITH_SYS_TIME
-# ifdef HAVE_SYS_TIME_H
-# include <sys/time.h>
-# else // !HAVE_SYS_TIME_H
-# include <time.h>
-# endif // HAVE_SYS_TIME_H
-#endif // TIME_WITH_SYS_TIME
-
-// forward declaration
-class BTimer;
-class TimeoutHandler;
-class BaseDisplay;
-
-class TimeoutHandler {
-public:
- virtual void timeout(void) = 0;
-};
-
-class BTimer {
- friend class BaseDisplay;
-private:
- BaseDisplay &display;
- TimeoutHandler &handler;
- int timing, once;
-
- timeval _start, _timeout;
-
-protected:
- void fireTimeout(void);
-
-public:
- BTimer(BaseDisplay &, TimeoutHandler &);
- virtual ~BTimer(void);
-
- inline const int &isTiming(void) const { return timing; }
- inline const int &doOnce(void) const { return once; }
-
- inline const timeval &getTimeout(void) const { return _timeout; }
- inline const timeval &getStartTime(void) const { return _start; }
-
- inline void fireOnce(int o) { once = o; }
-
- void setTimeout(long);
- void setTimeout(timeval);
- void start(void);
- void stop(void);
-};
-
-#endif // __Timer_hh
-
--- /dev/null
+// -*- mode: C++; indent-tabs-mode: nil; -*-
+// Timer.hh for Blackbox - An X11 Window Manager
+// Copyright (c) 2001 - 2002 Sean 'Shaleh' Perry <shaleh@debian.org>
+// Copyright (c) 1997 - 2000 Brad Hughes (bhughes@tcac.net)
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#ifndef _BLACKBOX_Timer_hh
+#define _BLACKBOX_Timer_hh
+
+extern "C" {
+#ifdef TIME_WITH_SYS_TIME
+# include <sys/time.h>
+# include <time.h>
+#else // !TIME_WITH_SYS_TIME
+# ifdef HAVE_SYS_TIME_H
+# include <sys/time.h>
+# else // !HAVE_SYS_TIME_H
+# include <time.h>
+# endif // HAVE_SYS_TIME_H
+#endif // TIME_WITH_SYS_TIME
+}
+
+// forward declaration
+class TimerQueueManager;
+
+class TimeoutHandler {
+public:
+ virtual void timeout(void) = 0;
+};
+
+class BTimer {
+private:
+ TimerQueueManager *manager;
+ TimeoutHandler *handler;
+ bool timing, recur;
+
+ timeval _start, _timeout;
+
+ BTimer(const BTimer&);
+ BTimer& operator=(const BTimer&);
+
+public:
+ BTimer(TimerQueueManager *m, TimeoutHandler *h);
+ virtual ~BTimer(void);
+
+ void fireTimeout(void);
+
+ inline bool isTiming(void) const { return timing; }
+ inline bool isRecurring(void) const { return recur; }
+
+ inline const timeval &getTimeout(void) const { return _timeout; }
+ inline const timeval &getStartTime(void) const { return _start; }
+
+ timeval timeRemaining(const timeval &tm) const;
+ bool shouldFire(const timeval &tm) const;
+ timeval endpoint(void) const;
+
+ inline void recurring(bool b) { recur = b; }
+
+ void setTimeout(long t);
+ void setTimeout(const timeval &t);
+
+ void start(void); // manager acquires timer
+ void stop(void); // manager releases timer
+ void halt(void); // halts the timer
+
+ bool operator<(const BTimer& other) const
+ { return shouldFire(other.endpoint()); }
+};
+
+
+#include <queue>
+#include <algorithm>
+
+template <class _Tp, class _Sequence, class _Compare>
+class _timer_queue: protected std::priority_queue<_Tp, _Sequence, _Compare> {
+public:
+ typedef std::priority_queue<_Tp, _Sequence, _Compare> _Base;
+
+ _timer_queue(void): _Base() {}
+ ~_timer_queue(void) {}
+
+ void release(const _Tp& value) {
+ c.erase(std::remove(c.begin(), c.end(), value), c.end());
+ // after removing the item we need to make the heap again
+ std::make_heap(c.begin(), c.end(), comp);
+ }
+ bool empty(void) const { return _Base::empty(); }
+ size_t size(void) const { return _Base::size(); }
+ void push(const _Tp& value) { _Base::push(value); }
+ void pop(void) { _Base::pop(); }
+ const _Tp& top(void) const { return _Base::top(); }
+private:
+ // no copying!
+ _timer_queue(const _timer_queue&) {}
+ _timer_queue& operator=(const _timer_queue&) {}
+};
+
+struct TimerLessThan {
+ bool operator()(const BTimer* const l, const BTimer* const r) const {
+ return *r < *l;
+ }
+};
+
+#include <deque>
+typedef _timer_queue<BTimer*, std::deque<BTimer*>, TimerLessThan> TimerQueue;
+
+class TimerQueueManager {
+public:
+ virtual void addTimer(BTimer* timer) = 0;
+ virtual void removeTimer(BTimer* timer) = 0;
+};
+
+#endif // _BLACKBOX_Timer_hh
-// Toolbar.cc for Openbox
-// Copyright (c) 2001 Sean 'Shaleh' Perry <shaleh@debian.org>
+// -*- mode: C++; indent-tabs-mode: nil; -*-
+// Toolbar.cc for Blackbox - an X11 Window manager
+// Copyright (c) 2001 - 2002 Sean 'Shaleh' Perry <shaleh@debian.org>
// Copyright (c) 1997 - 2000 Brad Hughes (bhughes@tcac.net)
//
// Permission is hereby granted, free of charge, to any person obtaining a
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
-// stupid macros needed to access some functions in version 2 of the GNU C
-// library
-#ifndef _GNU_SOURCE
-#define _GNU_SOURCE
-#endif // _GNU_SOURCE
-
#ifdef HAVE_CONFIG_H
# include "../config.h"
#endif // HAVE_CONFIG_H
-#include "i18n.h"
-#include "openbox.h"
-#include "Clientmenu.h"
-#include "Iconmenu.h"
-#include "Rootmenu.h"
-#include "Screen.h"
-#include "Toolbar.h"
-#include "Window.h"
-#include "Workspace.h"
-#include "Workspacemenu.h"
-
+extern "C" {
#include <X11/keysym.h>
-#ifdef HAVE_STRING_H
+#ifdef HAVE_STRING_H
# include <string.h>
#endif // HAVE_STRING_H
# include <time.h>
# endif // HAVE_SYS_TIME_H
#endif // TIME_WITH_SYS_TIME
+}
-#include <strstream>
#include <string>
-using std::ends;
+using std::string;
+
+#include "i18n.hh"
+#include "blackbox.hh"
+#include "Clientmenu.hh"
+#include "GCCache.hh"
+#include "Iconmenu.hh"
+#include "Image.hh"
+#include "Rootmenu.hh"
+#include "Screen.hh"
+#include "Toolbar.hh"
+#include "Window.hh"
+#include "Workspace.hh"
+#include "Workspacemenu.hh"
+#include "Slit.hh"
+
+
+static long aMinuteFromNow(void) {
+ timeval now;
+ gettimeofday(&now, 0);
+ return ((60 - (now.tv_sec % 60)) * 1000);
+}
+
-Toolbar::Toolbar(BScreen &scrn, Resource &conf) : openbox(scrn.getOpenbox()),
-screen(scrn), config(conf)
-{
- load();
+Toolbar::Toolbar(BScreen *scrn) {
+ screen = scrn;
+ blackbox = screen->getBlackbox();
// get the clock updating every minute
- clock_timer = new BTimer(openbox, *this);
- timeval now;
- gettimeofday(&now, 0);
- clock_timer->setTimeout((60 - (now.tv_sec % 60)) * 1000);
+ clock_timer = new BTimer(blackbox, this);
+ clock_timer->setTimeout(aMinuteFromNow());
+ clock_timer->recurring(True);
clock_timer->start();
+ frame.minute = frame.hour = -1;
hide_handler.toolbar = this;
- hide_timer = new BTimer(openbox, hide_handler);
- // the time out is set in ::reconfigure()
- hide_timer->fireOnce(True);
+ hide_timer = new BTimer(blackbox, &hide_handler);
+ hide_timer->setTimeout(blackbox->getAutoRaiseDelay());
- image_ctrl = screen.getImageControl();
+ on_top = screen->isToolbarOnTop();
+ hidden = do_auto_hide = screen->doToolbarAutoHide();
- m_editing = False;
- new_workspace_name = (char *) 0;
+ editing = False;
new_name_pos = 0;
frame.grab_x = frame.grab_y = 0;
- toolbarmenu = new Toolbarmenu(*this);
+ toolbarmenu = new Toolbarmenu(this);
- display = openbox.getXDisplay();
+ display = blackbox->getXDisplay();
XSetWindowAttributes attrib;
unsigned long create_mask = CWBackPixmap | CWBackPixel | CWBorderPixel |
- CWColormap | CWOverrideRedirect | CWEventMask;
+ CWColormap | CWOverrideRedirect | CWEventMask;
attrib.background_pixmap = None;
attrib.background_pixel = attrib.border_pixel =
- screen.getBorderColor()->getPixel();
- attrib.colormap = screen.getColormap();
+ screen->getBorderColor()->pixel();
+ attrib.colormap = screen->getColormap();
attrib.override_redirect = True;
attrib.event_mask = ButtonPressMask | ButtonReleaseMask |
- EnterWindowMask | LeaveWindowMask;
+ EnterWindowMask | LeaveWindowMask;
frame.window =
- XCreateWindow(display, screen.getRootWindow(), 0, 0, 1, 1, 0,
- screen.getDepth(), InputOutput, screen.getVisual(),
+ XCreateWindow(display, screen->getRootWindow(), 0, 0, 1, 1, 0,
+ screen->getDepth(), InputOutput, screen->getVisual(),
create_mask, &attrib);
- openbox.saveToolbarSearch(frame.window, this);
+ blackbox->saveToolbarSearch(frame.window, this);
attrib.event_mask = ButtonPressMask | ButtonReleaseMask | ExposureMask |
- KeyPressMask | EnterWindowMask;
+ KeyPressMask | EnterWindowMask;
frame.workspace_label =
- XCreateWindow(display, frame.window, 0, 0, 1, 1, 0, screen.getDepth(),
- InputOutput, screen.getVisual(), create_mask, &attrib);
- openbox.saveToolbarSearch(frame.workspace_label, this);
+ XCreateWindow(display, frame.window, 0, 0, 1, 1, 0, screen->getDepth(),
+ InputOutput, screen->getVisual(), create_mask, &attrib);
+ blackbox->saveToolbarSearch(frame.workspace_label, this);
frame.window_label =
- XCreateWindow(display, frame.window, 0, 0, 1, 1, 0, screen.getDepth(),
- InputOutput, screen.getVisual(), create_mask, &attrib);
- openbox.saveToolbarSearch(frame.window_label, this);
+ XCreateWindow(display, frame.window, 0, 0, 1, 1, 0, screen->getDepth(),
+ InputOutput, screen->getVisual(), create_mask, &attrib);
+ blackbox->saveToolbarSearch(frame.window_label, this);
frame.clock =
- XCreateWindow(display, frame.window, 0, 0, 1, 1, 0, screen.getDepth(),
- InputOutput, screen.getVisual(), create_mask, &attrib);
- openbox.saveToolbarSearch(frame.clock, this);
+ XCreateWindow(display, frame.window, 0, 0, 1, 1, 0, screen->getDepth(),
+ InputOutput, screen->getVisual(), create_mask, &attrib);
+ blackbox->saveToolbarSearch(frame.clock, this);
frame.psbutton =
- XCreateWindow(display ,frame.window, 0, 0, 1, 1, 0, screen.getDepth(),
- InputOutput, screen.getVisual(), create_mask, &attrib);
- openbox.saveToolbarSearch(frame.psbutton, this);
+ XCreateWindow(display ,frame.window, 0, 0, 1, 1, 0, screen->getDepth(),
+ InputOutput, screen->getVisual(), create_mask, &attrib);
+ blackbox->saveToolbarSearch(frame.psbutton, this);
frame.nsbutton =
- XCreateWindow(display ,frame.window, 0, 0, 1, 1, 0, screen.getDepth(),
- InputOutput, screen.getVisual(), create_mask, &attrib);
- openbox.saveToolbarSearch(frame.nsbutton, this);
+ XCreateWindow(display ,frame.window, 0, 0, 1, 1, 0, screen->getDepth(),
+ InputOutput, screen->getVisual(), create_mask, &attrib);
+ blackbox->saveToolbarSearch(frame.nsbutton, this);
frame.pwbutton =
- XCreateWindow(display ,frame.window, 0, 0, 1, 1, 0, screen.getDepth(),
- InputOutput, screen.getVisual(), create_mask, &attrib);
- openbox.saveToolbarSearch(frame.pwbutton, this);
+ XCreateWindow(display ,frame.window, 0, 0, 1, 1, 0, screen->getDepth(),
+ InputOutput, screen->getVisual(), create_mask, &attrib);
+ blackbox->saveToolbarSearch(frame.pwbutton, this);
frame.nwbutton =
- XCreateWindow(display ,frame.window, 0, 0, 1, 1, 0, screen.getDepth(),
- InputOutput, screen.getVisual(), create_mask, &attrib);
- openbox.saveToolbarSearch(frame.nwbutton, this);
+ XCreateWindow(display ,frame.window, 0, 0, 1, 1, 0, screen->getDepth(),
+ InputOutput, screen->getVisual(), create_mask, &attrib);
+ blackbox->saveToolbarSearch(frame.nwbutton, this);
frame.base = frame.label = frame.wlabel = frame.clk = frame.button =
frame.pbutton = None;
- reconfigure();
- mapToolbar();
-}
+ screen->addStrut(&strut);
-Rect Toolbar::area() const {
- int x = ((m_hidden) ? frame.x_hidden : frame.x);
- int y;
- if (screen.hideToolbar()) y = screen.size().h();
- else if (m_hidden) y = frame.y_hidden;
- else y = frame.y;
- return Rect(x, y, frame.width, frame.height);
-}
+ reconfigure();
-unsigned int Toolbar::getExposedHeight() const {
- if (screen.hideToolbar()) return 0;
- else if (m_autohide) return frame.bevel_w;
- else return frame.height;
+ XMapSubwindows(display, frame.window);
+ XMapWindow(display, frame.window);
}
-void Toolbar::mapToolbar(){
- if (!screen.hideToolbar()) {
- //not hidden, so windows should not maximize over the toolbar
- XMapSubwindows(display, frame.window);
- XMapWindow(display, frame.window);
- }
-}
-void Toolbar::unMapToolbar(){
- //hidden so we can maximize over the toolbar
+Toolbar::~Toolbar(void) {
XUnmapWindow(display, frame.window);
-}
-Toolbar::~Toolbar() {
- unMapToolbar();
- if (frame.base) image_ctrl->removeImage(frame.base);
- if (frame.label) image_ctrl->removeImage(frame.label);
- if (frame.wlabel) image_ctrl->removeImage(frame.wlabel);
- if (frame.clk) image_ctrl->removeImage(frame.clk);
- if (frame.button) image_ctrl->removeImage(frame.button);
- if (frame.pbutton) image_ctrl->removeImage(frame.pbutton);
-
- openbox.removeToolbarSearch(frame.window);
- openbox.removeToolbarSearch(frame.workspace_label);
- openbox.removeToolbarSearch(frame.window_label);
- openbox.removeToolbarSearch(frame.clock);
- openbox.removeToolbarSearch(frame.psbutton);
- openbox.removeToolbarSearch(frame.nsbutton);
- openbox.removeToolbarSearch(frame.pwbutton);
- openbox.removeToolbarSearch(frame.nwbutton);
+ if (frame.base) screen->getImageControl()->removeImage(frame.base);
+ if (frame.label) screen->getImageControl()->removeImage(frame.label);
+ if (frame.wlabel) screen->getImageControl()->removeImage(frame.wlabel);
+ if (frame.clk) screen->getImageControl()->removeImage(frame.clk);
+ if (frame.button) screen->getImageControl()->removeImage(frame.button);
+ if (frame.pbutton) screen->getImageControl()->removeImage(frame.pbutton);
+
+ blackbox->removeToolbarSearch(frame.window);
+ blackbox->removeToolbarSearch(frame.workspace_label);
+ blackbox->removeToolbarSearch(frame.window_label);
+ blackbox->removeToolbarSearch(frame.clock);
+ blackbox->removeToolbarSearch(frame.psbutton);
+ blackbox->removeToolbarSearch(frame.nsbutton);
+ blackbox->removeToolbarSearch(frame.pwbutton);
+ blackbox->removeToolbarSearch(frame.nwbutton);
XDestroyWindow(display, frame.workspace_label);
XDestroyWindow(display, frame.window_label);
}
-void Toolbar::setOnTop(bool b) {
- m_ontop = b;
- std::ostrstream s;
- s << "session.screen" << screen.getScreenNumber() << ".toolbar.onTop" << ends;
- config.setValue(s.str(), m_ontop ? "True" : "False");
- s.rdbuf()->freeze(0);
-}
-
-void Toolbar::setAutoHide(bool b) {
- m_autohide = b;
- std::ostrstream s;
- s << "session.screen" << screen.getScreenNumber() << ".toolbar.autoHide"
- << ends;
- config.setValue(s.str(), m_autohide ? "True" : "False");
- s.rdbuf()->freeze(0);
-}
+void Toolbar::reconfigure(void) {
+ unsigned int height = 0,
+ width = (screen->getWidth() * screen->getToolbarWidthPercent()) / 100;
-void Toolbar::setWidthPercent(int w) {
- m_width_percent = w;
- std::ostrstream s;
- s << "session.screen" << screen.getScreenNumber() << ".toolbar.widthPercent"
- << ends;
- config.setValue(s.str(), m_width_percent);
- s.rdbuf()->freeze(0);
-}
-
-void Toolbar::setPlacement(int p) {
- m_placement = p;
- std::ostrstream s;
- s << "session.screen" << screen.getScreenNumber() << ".toolbar.placement"
- << ends;
- const char *placement;
- switch (m_placement) {
- case TopLeft: placement = "TopLeft"; break;
- case BottomLeft: placement = "BottomLeft"; break;
- case TopCenter: placement = "TopCenter"; break;
- case TopRight: placement = "TopRight"; break;
- case BottomRight: placement = "BottomRight"; break;
- case BottomCenter: default: placement = "BottomCenter"; break;
- }
- config.setValue(s.str(), placement);
- s.rdbuf()->freeze(0);
-}
-
-void Toolbar::save() {
- setOnTop(m_ontop);
- setAutoHide(m_autohide);
- setWidthPercent(m_width_percent);
- setPlacement(m_placement);
-}
-
-void Toolbar::load() {
- std::ostrstream rscreen, rname, rclass;
- std::string s;
- bool b;
- long l;
- rscreen << "session.screen" << screen.getScreenNumber() << '.' << ends;
-
- rname << rscreen.str() << "toolbar.widthPercent" << ends;
- rclass << rscreen.str() << "Toolbar.WidthPercent" << ends;
- if (config.getValue(rname.str(), rclass.str(), l) && (l > 0 && l <= 100))
- m_width_percent = l;
- else
- m_width_percent =66;
-
- rname.seekp(0); rclass.seekp(0);
- rname.rdbuf()->freeze(0); rclass.rdbuf()->freeze(0);
- rname << rscreen.str() << "toolbar.placement" << ends;
- rclass << rscreen.str() << "Toolbar.Placement" << ends;
- if (config.getValue(rname.str(), rclass.str(), s)) {
- if (0 == strncasecmp(s.c_str(), "TopLeft", s.length()))
- m_placement = TopLeft;
- else if (0 == strncasecmp(s.c_str(), "BottomLeft", s.length()))
- m_placement = BottomLeft;
- else if (0 == strncasecmp(s.c_str(), "TopCenter", s.length()))
- m_placement = TopCenter;
- else if (0 == strncasecmp(s.c_str(), "TopRight", s.length()))
- m_placement = TopRight;
- else if ( 0 == strncasecmp(s.c_str(), "BottomRight", s.length()))
- m_placement = BottomRight;
- else if ( 0 == strncasecmp(s.c_str(), "BottomCenter", s.length()))
- m_placement = BottomCenter;
- } else
- m_placement = BottomCenter;
-
- rname.seekp(0); rclass.seekp(0);
- rname.rdbuf()->freeze(0); rclass.rdbuf()->freeze(0);
- rname << rscreen.str() << "toolbar.onTop" << ends;
- rclass << rscreen.str() << "Toolbar.OnTop" << ends;
- if (config.getValue(rname.str(), rclass.str(), b))
- m_ontop = b;
- else
- m_ontop = false;
-
- rname.seekp(0); rclass.seekp(0);
- rname.rdbuf()->freeze(0); rclass.rdbuf()->freeze(0);
- rname << rscreen.str() << "toolbar.autoHide" << ends;
- rclass << rscreen.str() << "Toolbar.AutoHide" << ends;
- if (config.getValue(rname.str(), rclass.str(), b))
- m_hidden = m_autohide = b;
+ if (i18n.multibyte())
+ height = screen->getToolbarStyle()->fontset_extents->max_ink_extent.height;
else
- m_hidden = m_autohide = false;
-
- rscreen.rdbuf()->freeze(0);
- rname.rdbuf()->freeze(0); rclass.rdbuf()->freeze(0);
-}
+ height = screen->getToolbarStyle()->font->ascent +
+ screen->getToolbarStyle()->font->descent;
-void Toolbar::reconfigure() {
- hide_timer->setTimeout(openbox.getAutoRaiseDelay());
+ frame.bevel_w = screen->getBevelWidth();
+ frame.button_w = height;
+ height += 2;
+ frame.label_h = height;
+ height += (frame.bevel_w * 2);
- frame.bevel_w = screen.getBevelWidth();
- frame.width = screen.size().w() * m_width_percent / 100;
+ frame.rect.setSize(width, height);
- if (i18n.multibyte())
- frame.height =
- screen.getToolbarStyle()->fontset_extents->max_ink_extent.height;
- else
- frame.height = screen.getToolbarStyle()->font->ascent +
- screen.getToolbarStyle()->font->descent;
- frame.button_w = frame.height;
- frame.height += 2;
- frame.label_h = frame.height;
- frame.height += (frame.bevel_w * 2);
-
- switch (m_placement) {
+ int x, y;
+ switch (screen->getToolbarPlacement()) {
case TopLeft:
- frame.x = 0;
- frame.y = 0;
- frame.x_hidden = 0;
- frame.y_hidden = screen.getBevelWidth() - screen.getBorderWidth()
- - frame.height;
- break;
+ case TopRight:
+ case TopCenter:
+ if (screen->getToolbarPlacement() == TopLeft)
+ x = 0;
+ else if (screen->getToolbarPlacement() == TopRight)
+ x = screen->getWidth() - frame.rect.width()
+ - (screen->getBorderWidth() * 2);
+ else
+ x = (screen->getWidth() - frame.rect.width()) / 2;
- case BottomLeft:
- frame.x = 0;
- frame.y = screen.size().h() - frame.height
- - (screen.getBorderWidth() * 2);
- frame.x_hidden = 0;
- frame.y_hidden = screen.size().h() - screen.getBevelWidth()
- - screen.getBorderWidth();
- break;
+ y = 0;
- case TopCenter:
- frame.x = (screen.size().w() - frame.width) / 2;
- frame.y = 0;
- frame.x_hidden = frame.x;
- frame.y_hidden = screen.getBevelWidth() - screen.getBorderWidth()
- - frame.height;
+ frame.x_hidden = x;
+ frame.y_hidden = screen->getBevelWidth() - screen->getBorderWidth()
+ - frame.rect.height();
break;
+ case BottomLeft:
+ case BottomRight:
case BottomCenter:
default:
- frame.x = (screen.size().w() - frame.width) / 2;
- frame.y = screen.size().h() - frame.height
- - (screen.getBorderWidth() * 2);
- frame.x_hidden = frame.x;
- frame.y_hidden = screen.size().h() - screen.getBevelWidth()
- - screen.getBorderWidth();
- break;
+ if (screen->getToolbarPlacement() == BottomLeft)
+ x = 0;
+ else if (screen->getToolbarPlacement() == BottomRight)
+ x = screen->getWidth() - frame.rect.width()
+ - (screen->getBorderWidth() * 2);
+ else
+ x = (screen->getWidth() - frame.rect.width()) / 2;
- case TopRight:
- frame.x = screen.size().w() - frame.width
- - (screen.getBorderWidth() * 2);
- frame.y = 0;
- frame.x_hidden = frame.x;
- frame.y_hidden = screen.getBevelWidth() - screen.getBorderWidth()
- - frame.height;
- break;
+ y = screen->getHeight() - frame.rect.height()
+ - (screen->getBorderWidth() * 2);
- case BottomRight:
- frame.x = screen.size().w() - frame.width
- - (screen.getBorderWidth() * 2);
- frame.y = screen.size().h() - frame.height
- - (screen.getBorderWidth() * 2);
- frame.x_hidden = frame.x;
- frame.y_hidden = screen.size().h() - screen.getBevelWidth()
- - screen.getBorderWidth();
+ frame.x_hidden = x;
+ frame.y_hidden = screen->getHeight() - screen->getBevelWidth()
+ - screen->getBorderWidth();
break;
}
+ frame.rect.setPos(x, y);
+
+ updateStrut();
+
#ifdef HAVE_STRFTIME
time_t ttmp = time(NULL);
- struct tm *tt = 0;
+ frame.clock_w = 0;
if (ttmp != -1) {
- tt = localtime(&ttmp);
+ struct tm *tt = localtime(&ttmp);
if (tt) {
- char t[1025], *time_string = (char *) 0;
- int len = strftime(t, 1024, screen.strftimeFormat(), tt);
- t[len++] = 'A'; // add size to the string for padding
- t[len++] = 'A'; // add size to the string for padding
- t[len] = '\0';
-
+ char t[1024];
+ int len = strftime(t, 1024, screen->getStrftimeFormat(), tt);
+ if (len == 0) { // invalid time format found
+ screen->saveStrftimeFormat("%I:%M %p"); // so use the default
+ len = strftime(t, 1024, screen->getStrftimeFormat(), tt);
+ }
+ // find the length of the rendered string and add room for two extra
+ // characters to it. This allows for variable width output of the fonts
if (i18n.multibyte()) {
XRectangle ink, logical;
- XmbTextExtents(screen.getToolbarStyle()->fontset, t, len, &ink,
- &logical);
- frame.clock_w = logical.width;
-
- // ben's additional solution to pad some space beside the numbers
- //frame.clock_w +=
- // screen.getToolbarStyle()->fontset_extents->max_logical_extent.width *
- // 4;
-
- // brad's solution, which is currently buggy, too big
- //frame.clock_w =
- // screen.getToolbarStyle()->fontset_extents->max_logical_extent.width
- // * len;
+ XmbTextExtents(screen->getToolbarStyle()->fontset, t, len,
+ &ink, &logical);
+ XFontSetExtents* extents = screen->getToolbarStyle()->fontset_extents;
+ frame.clock_w = logical.width +
+ (extents->max_logical_extent.width * 2);
} else {
- frame.clock_w = XTextWidth(screen.getToolbarStyle()->font, t, len);
- // ben's additional solution to pad some space beside the numbers
- //frame.clock_w += screen.getToolbarStyle()->font->max_bounds.width * 4;
- // brad's solution again, too big
- //frame.clock_w = screen.getToolbarStyle()->font->max_bounds.width * len;
+ XFontStruct* font = screen->getToolbarStyle()->font;
+ frame.clock_w = XTextWidth(font, t, len) +
+ ((font->max_bounds.rbearing - font->min_bounds.lbearing) * 2);
}
- frame.clock_w += (frame.bevel_w * 4);
-
- delete [] time_string;
- } else {
- frame.clock_w = 0;
}
- } else {
- frame.clock_w = 0;
}
#else // !HAVE_STRFTIME
frame.clock_w =
- XTextWidth(screen.getToolbarStyle()->font,
- i18n(ToolbarSet, ToolbarNoStrftimeLength,
- "00:00000"),
+ XTextWidth(screen->getToolbarStyle()->font,
+ i18n(ToolbarSet, ToolbarNoStrftimeLength, "00:00000"),
strlen(i18n(ToolbarSet, ToolbarNoStrftimeLength,
- "00:00000"))) + (frame.bevel_w * 4);
+ "00:00000")));
#endif // HAVE_STRFTIME
- int i;
- unsigned int w = 0;
- frame.workspace_label_w = 0;
-
- for (i = 0; i < screen.getWorkspaceCount(); i++) {
- if (i18n.multibyte()) {
- XRectangle ink, logical;
- XmbTextExtents(screen.getToolbarStyle()->fontset,
- screen.getWorkspace(i)->getName(),
- strlen(screen.getWorkspace(i)->getName()),
- &ink, &logical);
- w = logical.width;
- } else {
- w = XTextWidth(screen.getToolbarStyle()->font,
- screen.getWorkspace(i)->getName(),
- strlen(screen.getWorkspace(i)->getName()));
- }
- w += (frame.bevel_w * 4);
-
- if (w > frame.workspace_label_w) frame.workspace_label_w = w;
- }
-
- if (frame.workspace_label_w < frame.clock_w)
- frame.workspace_label_w = frame.clock_w;
- else if (frame.workspace_label_w > frame.clock_w)
- frame.clock_w = frame.workspace_label_w;
-
- frame.window_label_w =
- (frame.width - (frame.clock_w + (frame.button_w * 4) +
- frame.workspace_label_w + (frame.bevel_w * 8) + 6));
-
- if (m_hidden) {
- XMoveResizeWindow(display, frame.window, frame.x_hidden, frame.y_hidden,
- frame.width, frame.height);
- } else {
- XMoveResizeWindow(display, frame.window, frame.x, frame.y,
- frame.width, frame.height);
- }
-
- XMoveResizeWindow(display, frame.workspace_label, frame.bevel_w,
- frame.bevel_w, frame.workspace_label_w,
- frame.label_h);
- XMoveResizeWindow(display, frame.psbutton, (frame.bevel_w * 2) +
- frame.workspace_label_w + 1, frame.bevel_w + 1,
- frame.button_w, frame.button_w);
- XMoveResizeWindow(display ,frame.nsbutton, (frame.bevel_w * 3) +
- frame.workspace_label_w + frame.button_w + 2,
- frame.bevel_w + 1, frame.button_w, frame.button_w);
- XMoveResizeWindow(display, frame.window_label, (frame.bevel_w * 4) +
- (frame.button_w * 2) + frame.workspace_label_w + 3,
- frame.bevel_w, frame.window_label_w, frame.label_h);
- XMoveResizeWindow(display, frame.pwbutton, (frame.bevel_w * 5) +
- (frame.button_w * 2) + frame.workspace_label_w +
- frame.window_label_w + 4, frame.bevel_w + 1,
- frame.button_w, frame.button_w);
- XMoveResizeWindow(display, frame.nwbutton, (frame.bevel_w * 6) +
- (frame.button_w * 3) + frame.workspace_label_w +
- frame.window_label_w + 5, frame.bevel_w + 1,
- frame.button_w, frame.button_w);
- XMoveResizeWindow(display, frame.clock, frame.width - frame.clock_w -
- frame.bevel_w, frame.bevel_w, frame.clock_w,
- frame.label_h);
-
- Pixmap tmp = frame.base;
- BTexture *texture = &(screen.getToolbarStyle()->toolbar);
- if (texture->getTexture() == (BImage_Flat | BImage_Solid)) {
- frame.base = None;
- XSetWindowBackground(display, frame.window,
- texture->getColor()->getPixel());
- } else {
- frame.base =
- image_ctrl->renderImage(frame.width, frame.height, texture);
- XSetWindowBackgroundPixmap(display, frame.window, frame.base);
- }
- if (tmp) image_ctrl->removeImage(tmp);
-
- tmp = frame.label;
- texture = &(screen.getToolbarStyle()->window);
- if (texture->getTexture() == (BImage_Flat | BImage_Solid)) {
- frame.label = None;
- XSetWindowBackground(display, frame.window_label,
- texture->getColor()->getPixel());
- } else {
- frame.label =
- image_ctrl->renderImage(frame.window_label_w, frame.label_h, texture);
- XSetWindowBackgroundPixmap(display, frame.window_label, frame.label);
- }
- if (tmp) image_ctrl->removeImage(tmp);
-
- tmp = frame.wlabel;
- texture = &(screen.getToolbarStyle()->label);
- if (texture->getTexture() == (BImage_Flat | BImage_Solid)) {
- frame.wlabel = None;
- XSetWindowBackground(display, frame.workspace_label,
- texture->getColor()->getPixel());
- } else {
- frame.wlabel =
- image_ctrl->renderImage(frame.workspace_label_w, frame.label_h, texture);
- XSetWindowBackgroundPixmap(display, frame.workspace_label, frame.wlabel);
- }
- if (tmp) image_ctrl->removeImage(tmp);
-
- tmp = frame.clk;
- texture = &(screen.getToolbarStyle()->clock);
- if (texture->getTexture() == (BImage_Flat | BImage_Solid)) {
- frame.clk = None;
- XSetWindowBackground(display, frame.clock,
- texture->getColor()->getPixel());
- } else {
- frame.clk =
- image_ctrl->renderImage(frame.clock_w, frame.label_h, texture);
- XSetWindowBackgroundPixmap(display, frame.clock, frame.clk);
- }
- if (tmp) image_ctrl->removeImage(tmp);
-
- tmp = frame.button;
- texture = &(screen.getToolbarStyle()->button);
- if (texture->getTexture() == (BImage_Flat | BImage_Solid)) {
- frame.button = None;
-
- frame.button_pixel = texture->getColor()->getPixel();
- XSetWindowBackground(display, frame.psbutton, frame.button_pixel);
- XSetWindowBackground(display, frame.nsbutton, frame.button_pixel);
- XSetWindowBackground(display, frame.pwbutton, frame.button_pixel);
- XSetWindowBackground(display, frame.nwbutton, frame.button_pixel);
- } else {
- frame.button =
- image_ctrl->renderImage(frame.button_w, frame.button_w, texture);
-
- XSetWindowBackgroundPixmap(display, frame.psbutton, frame.button);
- XSetWindowBackgroundPixmap(display, frame.nsbutton, frame.button);
- XSetWindowBackgroundPixmap(display, frame.pwbutton, frame.button);
- XSetWindowBackgroundPixmap(display, frame.nwbutton, frame.button);
- }
- if (tmp) image_ctrl->removeImage(tmp);
-
- tmp = frame.pbutton;
- texture = &(screen.getToolbarStyle()->pressed);
- if (texture->getTexture() == (BImage_Flat | BImage_Solid)) {
- frame.pbutton = None;
- frame.pbutton_pixel = texture->getColor()->getPixel();
- } else {
- frame.pbutton =
- image_ctrl->renderImage(frame.button_w, frame.button_w, texture);
- }
- if (tmp) image_ctrl->removeImage(tmp);
-
- XSetWindowBorder(display, frame.window,
- screen.getBorderColor()->getPixel());
- XSetWindowBorderWidth(display, frame.window, screen.getBorderWidth());
-
- XClearWindow(display, frame.window);
- XClearWindow(display, frame.workspace_label);
- XClearWindow(display, frame.window_label);
- XClearWindow(display, frame.clock);
- XClearWindow(display, frame.psbutton);
- XClearWindow(display, frame.nsbutton);
- XClearWindow(display, frame.pwbutton);
- XClearWindow(display, frame.nwbutton);
-
- redrawWindowLabel();
- redrawWorkspaceLabel();
- redrawPrevWorkspaceButton();
- redrawNextWorkspaceButton();
- redrawPrevWindowButton();
- redrawNextWindowButton();
- checkClock(True);
-
- toolbarmenu->reconfigure();
+ frame.workspace_label_w = 0;
+
+ for (unsigned int i = 0; i < screen->getWorkspaceCount(); i++) {
+ const string& workspace_name = screen->getWorkspace(i)->getName();
+ if (i18n.multibyte()) {
+ XRectangle ink, logical;
+ XmbTextExtents(screen->getToolbarStyle()->fontset,
+ workspace_name.c_str(), workspace_name.length(),
+ &ink, &logical);
+ width = logical.width;
+ } else {
+ width = XTextWidth(screen->getToolbarStyle()->font,
+ workspace_name.c_str(), workspace_name.length());
+ }
+
+ if (width > frame.workspace_label_w) frame.workspace_label_w = width;
+ }
+
+ frame.workspace_label_w = frame.clock_w =
+ std::max(frame.workspace_label_w, frame.clock_w) + (frame.bevel_w * 4);
+
+ // XXX: where'd the +6 come from?
+ frame.window_label_w =
+ (frame.rect.width() - (frame.clock_w + (frame.button_w * 4) +
+ frame.workspace_label_w + (frame.bevel_w * 8) + 6));
+
+ if (hidden) {
+ XMoveResizeWindow(display, frame.window, frame.x_hidden, frame.y_hidden,
+ frame.rect.width(), frame.rect.height());
+ } else {
+ XMoveResizeWindow(display, frame.window, frame.rect.x(), frame.rect.y(),
+ frame.rect.width(), frame.rect.height());
+ }
+
+ XMoveResizeWindow(display, frame.workspace_label, frame.bevel_w,
+ frame.bevel_w, frame.workspace_label_w,
+ frame.label_h);
+ XMoveResizeWindow(display, frame.psbutton,
+ ((frame.bevel_w * 2) + frame.workspace_label_w + 1),
+ frame.bevel_w + 1, frame.button_w, frame.button_w);
+ XMoveResizeWindow(display, frame.nsbutton,
+ ((frame.bevel_w * 3) + frame.workspace_label_w +
+ frame.button_w + 2), frame.bevel_w + 1, frame.button_w,
+ frame.button_w);
+ XMoveResizeWindow(display, frame.window_label,
+ ((frame.bevel_w * 4) + (frame.button_w * 2) +
+ frame.workspace_label_w + 3), frame.bevel_w,
+ frame.window_label_w, frame.label_h);
+ XMoveResizeWindow(display, frame.pwbutton,
+ ((frame.bevel_w * 5) + (frame.button_w * 2) +
+ frame.workspace_label_w + frame.window_label_w + 4),
+ frame.bevel_w + 1, frame.button_w, frame.button_w);
+ XMoveResizeWindow(display, frame.nwbutton,
+ ((frame.bevel_w * 6) + (frame.button_w * 3) +
+ frame.workspace_label_w + frame.window_label_w + 5),
+ frame.bevel_w + 1, frame.button_w, frame.button_w);
+ XMoveResizeWindow(display, frame.clock,
+ frame.rect.width() - frame.clock_w - (frame.bevel_w * 2),
+ frame.bevel_w, frame.clock_w, frame.label_h);
+
+ ToolbarStyle *style = screen->getToolbarStyle();
+ frame.base = style->toolbar.render(frame.rect.width(), frame.rect.height(),
+ frame.base);
+ if (! frame.base)
+ XSetWindowBackground(display, frame.window,
+ style->toolbar.color().pixel());
+ else
+ XSetWindowBackgroundPixmap(display, frame.window, frame.base);
+
+ frame.label = style->window.render(frame.window_label_w, frame.label_h,
+ frame.label);
+ if (! frame.label)
+ XSetWindowBackground(display, frame.window_label,
+ style->window.color().pixel());
+ else
+ XSetWindowBackgroundPixmap(display, frame.window_label, frame.label);
+
+ frame.wlabel = style->label.render(frame.workspace_label_w, frame.label_h,
+ frame.wlabel);
+ if (! frame.wlabel)
+ XSetWindowBackground(display, frame.workspace_label,
+ style->label.color().pixel());
+ else
+ XSetWindowBackgroundPixmap(display, frame.workspace_label, frame.wlabel);
+
+ frame.clk = style->clock.render(frame.clock_w, frame.label_h, frame.clk);
+ if (! frame.clk)
+ XSetWindowBackground(display, frame.clock, style->clock.color().pixel());
+ else
+ XSetWindowBackgroundPixmap(display, frame.clock, frame.clk);
+
+ frame.button = style->button.render(frame.button_w, frame.button_w,
+ frame.button);
+ if (! frame.button) {
+ frame.button_pixel = style->button.color().pixel();
+ XSetWindowBackground(display, frame.psbutton, frame.button_pixel);
+ XSetWindowBackground(display, frame.nsbutton, frame.button_pixel);
+ XSetWindowBackground(display, frame.pwbutton, frame.button_pixel);
+ XSetWindowBackground(display, frame.nwbutton, frame.button_pixel);
+ } else {
+ XSetWindowBackgroundPixmap(display, frame.psbutton, frame.button);
+ XSetWindowBackgroundPixmap(display, frame.nsbutton, frame.button);
+ XSetWindowBackgroundPixmap(display, frame.pwbutton, frame.button);
+ XSetWindowBackgroundPixmap(display, frame.nwbutton, frame.button);
+ }
+
+ frame.pbutton = style->pressed.render(frame.button_w, frame.button_w,
+ frame.pbutton);
+ if (! frame.pbutton)
+ frame.pbutton_pixel = style->pressed.color().pixel();
+
+ XSetWindowBorder(display, frame.window,
+ screen->getBorderColor()->pixel());
+ XSetWindowBorderWidth(display, frame.window, screen->getBorderWidth());
+
+ XClearWindow(display, frame.window);
+ XClearWindow(display, frame.workspace_label);
+ XClearWindow(display, frame.window_label);
+ XClearWindow(display, frame.clock);
+ XClearWindow(display, frame.psbutton);
+ XClearWindow(display, frame.nsbutton);
+ XClearWindow(display, frame.pwbutton);
+ XClearWindow(display, frame.nwbutton);
+
+ redrawWindowLabel();
+ redrawWorkspaceLabel();
+ redrawPrevWorkspaceButton();
+ redrawNextWorkspaceButton();
+ redrawPrevWindowButton();
+ redrawNextWindowButton();
+ checkClock(True);
+
+ toolbarmenu->reconfigure();
+}
+
+
+void Toolbar::updateStrut(void) {
+ // left and right are always 0
+ strut.top = strut.bottom = 0;
+
+ switch(screen->getToolbarPlacement()) {
+ case TopLeft:
+ case TopCenter:
+ case TopRight:
+ strut.top = getExposedHeight() + (screen->getBorderWidth() * 2);
+ break;
+ default:
+ strut.bottom = getExposedHeight() + (screen->getBorderWidth() * 2);
+ }
+
+ screen->updateAvailableArea();
}
#ifdef HAVE_STRFTIME
-void Toolbar::checkClock(Bool redraw) {
+void Toolbar::checkClock(bool redraw) {
#else // !HAVE_STRFTIME
- void Toolbar::checkClock(Bool redraw, Bool date) {
+void Toolbar::checkClock(bool redraw, bool date) {
#endif // HAVE_STRFTIME
- time_t tmp = 0;
- struct tm *tt = 0;
-
- if ((tmp = time(NULL)) != -1) {
- if (! (tt = localtime(&tmp))) return;
- if (tt->tm_min != frame.minute || tt->tm_hour != frame.hour) {
- frame.hour = tt->tm_hour;
- frame.minute = tt->tm_min;
- XClearWindow(display, frame.clock);
- redraw = True;
- }
+ time_t tmp = 0;
+ struct tm *tt = 0;
+
+ if ((tmp = time(NULL)) != -1) {
+ if (! (tt = localtime(&tmp))) return;
+ if (tt->tm_min != frame.minute || tt->tm_hour != frame.hour) {
+ frame.hour = tt->tm_hour;
+ frame.minute = tt->tm_min;
+ XClearWindow(display, frame.clock);
+ redraw = True;
}
+ }
- if (redraw) {
+ if (redraw) {
#ifdef HAVE_STRFTIME
- char t[1024];
- if (! strftime(t, 1024, screen.strftimeFormat(), tt))
- return;
+ char t[1024];
+ if (! strftime(t, 1024, screen->getStrftimeFormat(), tt))
+ return;
#else // !HAVE_STRFTIME
- char t[9];
- if (date) {
- // format the date... with special consideration for y2k ;)
- if (screen.getDateFormat() == Openbox::B_EuropeanDate)
- sprintf(t, 18n->getMessage(ToolbarSet, ToolbarNoStrftimeDateFormatEu,
- "%02d.%02d.%02d"),
- tt->tm_mday, tt->tm_mon + 1,
- (tt->tm_year >= 100) ? tt->tm_year - 100 : tt->tm_year);
- else
- sprintf(t, i18n(ToolbarSet, ToolbarNoStrftimeDateFormat,
- "%02d/%02d/%02d"),
- tt->tm_mon + 1, tt->tm_mday,
- (tt->tm_year >= 100) ? tt->tm_year - 100 : tt->tm_year);
- } else {
- if (screen.isClock24Hour())
- sprintf(t, i18n(ToolbarSet, ToolbarNoStrftimeTimeFormat24,
- " %02d:%02d "),
- frame.hour, frame.minute);
- else
- sprintf(t, i18n(ToolbarSet, ToolbarNoStrftimeTimeFormat12,
- "%02d:%02d %sm"),
- ((frame.hour > 12) ? frame.hour - 12 :
- ((frame.hour == 0) ? 12 : frame.hour)), frame.minute,
- ((frame.hour >= 12) ?
- i18n(ToolbarSet,
- ToolbarNoStrftimeTimeFormatP, "p") :
- i18n(ToolbarSet,
- ToolbarNoStrftimeTimeFormatA, "a")));
- }
+ char t[9];
+ if (date) {
+ // format the date... with special consideration for y2k ;)
+ if (screen->getDateFormat() == Blackbox::B_EuropeanDate)
+ sprintf(t, 18n(ToolbarSet, ToolbarNoStrftimeDateFormatEu,
+ "%02d.%02d.%02d"),
+ tt->tm_mday, tt->tm_mon + 1,
+ (tt->tm_year >= 100) ? tt->tm_year - 100 : tt->tm_year);
+ else
+ sprintf(t, i18n(ToolbarSet, ToolbarNoStrftimeDateFormat,
+ "%02d/%02d/%02d"),
+ tt->tm_mon + 1, tt->tm_mday,
+ (tt->tm_year >= 100) ? tt->tm_year - 100 : tt->tm_year);
+ } else {
+ if (screen->isClock24Hour())
+ sprintf(t, i18n(ToolbarSet, ToolbarNoStrftimeTimeFormat24,
+ " %02d:%02d "),
+ frame.hour, frame.minute);
+ else
+ sprintf(t, i18n(ToolbarSet, ToolbarNoStrftimeTimeFormat12,
+ "%02d:%02d %sm"),
+ ((frame.hour > 12) ? frame.hour - 12 :
+ ((frame.hour == 0) ? 12 : frame.hour)), frame.minute,
+ ((frame.hour >= 12) ?
+ i18n(ToolbarSet, ToolbarNoStrftimeTimeFormatP, "p") :
+ i18n(ToolbarSet, ToolbarNoStrftimeTimeFormatA, "a")));
+ }
#endif // HAVE_STRFTIME
- int dx = (frame.bevel_w * 2), dlen = strlen(t);
- unsigned int l;
+ ToolbarStyle *style = screen->getToolbarStyle();
- if (i18n.multibyte()) {
- XRectangle ink, logical;
- XmbTextExtents(screen.getToolbarStyle()->fontset,
- t, dlen, &ink, &logical);
- l = logical.width;
- } else {
- l = XTextWidth(screen.getToolbarStyle()->font, t, dlen);
- }
+ int pos = frame.bevel_w * 2, // this is modified by doJustify()
+ dlen = style->doJustify(t, pos, frame.clock_w,
+ frame.bevel_w * 4, i18n.multibyte());
+ BPen pen(style->c_text, style->font);
+ if (i18n.multibyte())
+ XmbDrawString(display, frame.clock, style->fontset, pen.gc(),
+ pos, (1 - style->fontset_extents->max_ink_extent.y),
+ t, dlen);
+ else
+ XDrawString(display, frame.clock, pen.gc(), pos,
+ (style->font->ascent + 1), t, dlen);
+ }
+}
- l += (frame.bevel_w * 4);
-
- if (l > frame.clock_w) {
- for (; dlen >= 0; dlen--) {
- if (i18n.multibyte()) {
- XRectangle ink, logical;
- XmbTextExtents(screen.getToolbarStyle()->fontset,
- t, dlen, &ink, &logical);
- l = logical.width;
- } else {
- l = XTextWidth(screen.getToolbarStyle()->font, t, dlen);
- }
- l+= (frame.bevel_w * 4);
-
- if (l < frame.clock_w)
- break;
- }
- }
- switch (screen.getToolbarStyle()->justify) {
- case BScreen::RightJustify:
- dx += frame.clock_w - l;
- break;
-
- case BScreen::CenterJustify:
- dx += (frame.clock_w - l) / 2;
- break;
- }
- ToolbarStyle *style = screen.getToolbarStyle();
- if (i18n.multibyte())
- XmbDrawString(display, frame.clock, style->fontset, style->c_text_gc,
- dx, (1 - style->fontset_extents->max_ink_extent.y),
- t, dlen);
- else
- XDrawString(display, frame.clock, style->c_text_gc, dx,
- (style->font->ascent + 1), t, dlen);
- }
+void Toolbar::redrawWindowLabel(bool redraw) {
+ BlackboxWindow *foc = screen->getBlackbox()->getFocusedWindow();
+ if (! foc) {
+ XClearWindow(display, frame.window_label);
+ return;
}
+ if (redraw)
+ XClearWindow(display, frame.window_label);
- void Toolbar::redrawWindowLabel(Bool redraw) {
- OpenboxWindow *foc = screen.getOpenbox().focusedWindow();
- if (foc == (OpenboxWindow *) 0) {
- XClearWindow(display, frame.window_label);
- } else {
- if (redraw)
- XClearWindow(display, frame.window_label);
+ if (foc->getScreen() != screen) return;
- if (foc->getScreen() != &screen) return;
+ const char *title = foc->getTitle();
+ ToolbarStyle *style = screen->getToolbarStyle();
- int dx = (frame.bevel_w * 2), dlen = strlen(*foc->getTitle());
- unsigned int l;
+ int pos = frame.bevel_w * 2, // modified by doJustify()
+ dlen = style->doJustify(title, pos, frame.window_label_w,
+ frame.bevel_w * 4, i18n.multibyte());
+ BPen pen(style->w_text, style->font);
+ if (i18n.multibyte())
+ XmbDrawString(display, frame.window_label, style->fontset, pen.gc(), pos,
+ (1 - style->fontset_extents->max_ink_extent.y),
+ title, dlen);
+ else
+ XDrawString(display, frame.window_label, pen.gc(), pos,
+ (style->font->ascent + 1), title, dlen);
+}
- if (i18n.multibyte()) {
- XRectangle ink, logical;
- XmbTextExtents(screen.getToolbarStyle()->fontset, *foc->getTitle(),
- dlen, &ink, &logical);
- l = logical.width;
- } else {
- l = XTextWidth(screen.getToolbarStyle()->font, *foc->getTitle(), dlen);
- }
- l += (frame.bevel_w * 4);
-
- if (l > frame.window_label_w) {
- for (; dlen >= 0; dlen--) {
- if (i18n.multibyte()) {
- XRectangle ink, logical;
- XmbTextExtents(screen.getToolbarStyle()->fontset,
- *foc->getTitle(), dlen, &ink, &logical);
- l = logical.width;
- } else {
- l = XTextWidth(screen.getToolbarStyle()->font,
- *foc->getTitle(), dlen);
- }
- l += (frame.bevel_w * 4);
-
- if (l < frame.window_label_w)
- break;
- }
- }
- switch (screen.getToolbarStyle()->justify) {
- case BScreen::RightJustify:
- dx += frame.window_label_w - l;
- break;
-
- case BScreen::CenterJustify:
- dx += (frame.window_label_w - l) / 2;
- break;
- }
- ToolbarStyle *style = screen.getToolbarStyle();
- if (i18n.multibyte())
- XmbDrawString(display, frame.window_label, style->fontset,
- style->w_text_gc, dx,
- (1 - style->fontset_extents->max_ink_extent.y),
- *foc->getTitle(), dlen);
- else
- XDrawString(display, frame.window_label, style->w_text_gc, dx,
- (style->font->ascent + 1), *foc->getTitle(), dlen);
- }
- }
+void Toolbar::redrawWorkspaceLabel(bool redraw) {
+ const string& name = screen->getCurrentWorkspace()->getName();
+ if (redraw)
+ XClearWindow(display, frame.workspace_label);
- void Toolbar::redrawWorkspaceLabel(Bool redraw) {
- if (screen.getCurrentWorkspace()->getName()) {
- if (redraw)
- XClearWindow(display, frame.workspace_label);
+ ToolbarStyle *style = screen->getToolbarStyle();
- int dx = (frame.bevel_w * 2), dlen =
- strlen(screen.getCurrentWorkspace()->getName());
- unsigned int l;
+ int pos = frame.bevel_w * 2,
+ dlen = style->doJustify(name.c_str(), pos, frame.workspace_label_w,
+ frame.bevel_w * 4, i18n.multibyte());
+ BPen pen(style->l_text, style->font);
+ if (i18n.multibyte())
+ XmbDrawString(display, frame.workspace_label, style->fontset, pen.gc(),
+ pos, (1 - style->fontset_extents->max_ink_extent.y),
+ name.c_str(), dlen);
+ else
+ XDrawString(display, frame.workspace_label, pen.gc(), pos,
+ (style->font->ascent + 1),
+ name.c_str(), dlen);
+}
- if (i18n.multibyte()) {
- XRectangle ink, logical;
- XmbTextExtents(screen.getToolbarStyle()->fontset,
- screen.getCurrentWorkspace()->getName(), dlen,
- &ink, &logical);
- l = logical.width;
- } else {
- l = XTextWidth(screen.getToolbarStyle()->font,
- screen.getCurrentWorkspace()->getName(), dlen);
- }
- l += (frame.bevel_w * 4);
-
- if (l > frame.workspace_label_w) {
- for (; dlen >= 0; dlen--) {
- if (i18n.multibyte()) {
- XRectangle ink, logical;
- XmbTextExtents(screen.getToolbarStyle()->fontset,
- screen.getCurrentWorkspace()->getName(), dlen,
- &ink, &logical);
- l = logical.width;
- } else {
- l = XTextWidth(screen.getWindowStyle()->font,
- screen.getCurrentWorkspace()->getName(), dlen);
- }
- l += (frame.bevel_w * 4);
-
- if (l < frame.workspace_label_w)
- break;
- }
- }
- switch (screen.getToolbarStyle()->justify) {
- case BScreen::RightJustify:
- dx += frame.workspace_label_w - l;
- break;
-
- case BScreen::CenterJustify:
- dx += (frame.workspace_label_w - l) / 2;
- break;
- }
- ToolbarStyle *style = screen.getToolbarStyle();
- if (i18n.multibyte())
- XmbDrawString(display, frame.workspace_label, style->fontset,
- style->l_text_gc, dx,
- (1 - style->fontset_extents->max_ink_extent.y),
- (char *) screen.getCurrentWorkspace()->getName(), dlen);
+void Toolbar::redrawPrevWorkspaceButton(bool pressed, bool redraw) {
+ if (redraw) {
+ if (pressed) {
+ if (frame.pbutton)
+ XSetWindowBackgroundPixmap(display, frame.psbutton, frame.pbutton);
else
- XDrawString(display, frame.workspace_label, style->l_text_gc, dx,
- (style->font->ascent + 1),
- (char *) screen.getCurrentWorkspace()->getName(), dlen);
+ XSetWindowBackground(display, frame.psbutton, frame.pbutton_pixel);
+ } else {
+ if (frame.button)
+ XSetWindowBackgroundPixmap(display, frame.psbutton, frame.button);
+ else
+ XSetWindowBackground(display, frame.psbutton, frame.button_pixel);
}
+ XClearWindow(display, frame.psbutton);
}
+ int hh = frame.button_w / 2, hw = frame.button_w / 2;
- void Toolbar::redrawPrevWorkspaceButton(Bool pressed, Bool redraw) {
- if (redraw) {
- if (pressed) {
- if (frame.pbutton)
- XSetWindowBackgroundPixmap(display, frame.psbutton, frame.pbutton);
- else
- XSetWindowBackground(display, frame.psbutton, frame.pbutton_pixel);
- } else {
- if (frame.button)
- XSetWindowBackgroundPixmap(display, frame.psbutton, frame.button);
- else
- XSetWindowBackground(display, frame.psbutton, frame.button_pixel);
- }
- XClearWindow(display, frame.psbutton);
- }
-
- int hh = frame.button_w / 2, hw = frame.button_w / 2;
-
- XPoint pts[3];
- pts[0].x = hw - 2; pts[0].y = hh;
- pts[1].x = 4; pts[1].y = 2;
- pts[2].x = 0; pts[2].y = -4;
+ XPoint pts[3];
+ pts[0].x = hw - 2; pts[0].y = hh;
+ pts[1].x = 4; pts[1].y = 2;
+ pts[2].x = 0; pts[2].y = -4;
- XFillPolygon(display, frame.psbutton, screen.getToolbarStyle()->b_pic_gc,
- pts, 3, Convex, CoordModePrevious);
- }
+ ToolbarStyle *style = screen->getToolbarStyle();
+ BPen pen(style->b_pic, style->font);
+ XFillPolygon(display, frame.psbutton, pen.gc(),
+ pts, 3, Convex, CoordModePrevious);
+}
- void Toolbar::redrawNextWorkspaceButton(Bool pressed, Bool redraw) {
- if (redraw) {
- if (pressed) {
- if (frame.pbutton)
- XSetWindowBackgroundPixmap(display, frame.nsbutton, frame.pbutton);
- else
- XSetWindowBackground(display, frame.nsbutton, frame.pbutton_pixel);
- } else {
- if (frame.button)
- XSetWindowBackgroundPixmap(display, frame.nsbutton, frame.button);
- else
- XSetWindowBackground(display, frame.nsbutton, frame.button_pixel);
- }
- XClearWindow(display, frame.nsbutton);
+void Toolbar::redrawNextWorkspaceButton(bool pressed, bool redraw) {
+ if (redraw) {
+ if (pressed) {
+ if (frame.pbutton)
+ XSetWindowBackgroundPixmap(display, frame.nsbutton, frame.pbutton);
+ else
+ XSetWindowBackground(display, frame.nsbutton, frame.pbutton_pixel);
+ } else {
+ if (frame.button)
+ XSetWindowBackgroundPixmap(display, frame.nsbutton, frame.button);
+ else
+ XSetWindowBackground(display, frame.nsbutton, frame.button_pixel);
}
-
- int hh = frame.button_w / 2, hw = frame.button_w / 2;
-
- XPoint pts[3];
- pts[0].x = hw - 2; pts[0].y = hh - 2;
- pts[1].x = 4; pts[1].y = 2;
- pts[2].x = -4; pts[2].y = 2;
-
- XFillPolygon(display, frame.nsbutton, screen.getToolbarStyle()->b_pic_gc,
- pts, 3, Convex, CoordModePrevious);
+ XClearWindow(display, frame.nsbutton);
}
+ int hh = frame.button_w / 2, hw = frame.button_w / 2;
- void Toolbar::redrawPrevWindowButton(Bool pressed, Bool redraw) {
- if (redraw) {
- if (pressed) {
- if (frame.pbutton)
- XSetWindowBackgroundPixmap(display, frame.pwbutton, frame.pbutton);
- else
- XSetWindowBackground(display, frame.pwbutton, frame.pbutton_pixel);
- } else {
- if (frame.button)
- XSetWindowBackgroundPixmap(display, frame.pwbutton, frame.button);
- else
- XSetWindowBackground(display, frame.pwbutton, frame.button_pixel);
- }
- XClearWindow(display, frame.pwbutton);
- }
+ XPoint pts[3];
+ pts[0].x = hw - 2; pts[0].y = hh - 2;
+ pts[1].x = 4; pts[1].y = 2;
+ pts[2].x = -4; pts[2].y = 2;
- int hh = frame.button_w / 2, hw = frame.button_w / 2;
+ ToolbarStyle *style = screen->getToolbarStyle();
+ BPen pen(style->b_pic, style->font);
+ XFillPolygon(display, frame.nsbutton, pen.gc(),
+ pts, 3, Convex, CoordModePrevious);
+}
- XPoint pts[3];
- pts[0].x = hw - 2; pts[0].y = hh;
- pts[1].x = 4; pts[1].y = 2;
- pts[2].x = 0; pts[2].y = -4;
- XFillPolygon(display, frame.pwbutton, screen.getToolbarStyle()->b_pic_gc,
- pts, 3, Convex, CoordModePrevious);
+void Toolbar::redrawPrevWindowButton(bool pressed, bool redraw) {
+ if (redraw) {
+ if (pressed) {
+ if (frame.pbutton)
+ XSetWindowBackgroundPixmap(display, frame.pwbutton, frame.pbutton);
+ else
+ XSetWindowBackground(display, frame.pwbutton, frame.pbutton_pixel);
+ } else {
+ if (frame.button)
+ XSetWindowBackgroundPixmap(display, frame.pwbutton, frame.button);
+ else
+ XSetWindowBackground(display, frame.pwbutton, frame.button_pixel);
+ }
+ XClearWindow(display, frame.pwbutton);
}
+ int hh = frame.button_w / 2, hw = frame.button_w / 2;
- void Toolbar::redrawNextWindowButton(Bool pressed, Bool redraw) {
- if (redraw) {
- if (pressed) {
- if (frame.pbutton)
- XSetWindowBackgroundPixmap(display, frame.nwbutton, frame.pbutton);
- else
- XSetWindowBackground(display, frame.nwbutton, frame.pbutton_pixel);
- } else {
- if (frame.button)
- XSetWindowBackgroundPixmap(display, frame.nwbutton, frame.button);
- else
- XSetWindowBackground(display, frame.nwbutton, frame.button_pixel);
- }
- XClearWindow(display, frame.nwbutton);
- }
+ XPoint pts[3];
+ pts[0].x = hw - 2; pts[0].y = hh;
+ pts[1].x = 4; pts[1].y = 2;
+ pts[2].x = 0; pts[2].y = -4;
- int hh = frame.button_w / 2, hw = frame.button_w / 2;
+ ToolbarStyle *style = screen->getToolbarStyle();
+ BPen pen(style->b_pic, style->font);
+ XFillPolygon(display, frame.pwbutton, pen.gc(),
+ pts, 3, Convex, CoordModePrevious);
+}
- XPoint pts[3];
- pts[0].x = hw - 2; pts[0].y = hh - 2;
- pts[1].x = 4; pts[1].y = 2;
- pts[2].x = -4; pts[2].y = 2;
- XFillPolygon(display, frame.nwbutton, screen.getToolbarStyle()->b_pic_gc,
- pts, 3, Convex, CoordModePrevious);
+void Toolbar::redrawNextWindowButton(bool pressed, bool redraw) {
+ if (redraw) {
+ if (pressed) {
+ if (frame.pbutton)
+ XSetWindowBackgroundPixmap(display, frame.nwbutton, frame.pbutton);
+ else
+ XSetWindowBackground(display, frame.nwbutton, frame.pbutton_pixel);
+ } else {
+ if (frame.button)
+ XSetWindowBackgroundPixmap(display, frame.nwbutton, frame.button);
+ else
+ XSetWindowBackground(display, frame.nwbutton, frame.button_pixel);
+ }
+ XClearWindow(display, frame.nwbutton);
}
+ int hh = frame.button_w / 2, hw = frame.button_w / 2;
- void Toolbar::edit() {
- Window window;
- int foo;
+ XPoint pts[3];
+ pts[0].x = hw - 2; pts[0].y = hh - 2;
+ pts[1].x = 4; pts[1].y = 2;
+ pts[2].x = -4; pts[2].y = 2;
- m_editing = True;
- if (XGetInputFocus(display, &window, &foo) &&
- window == frame.workspace_label)
- return;
+ ToolbarStyle *style = screen->getToolbarStyle();
+ BPen pen(style->b_pic, style->font);
+ XFillPolygon(display, frame.nwbutton, pen.gc(), pts, 3, Convex,
+ CoordModePrevious);
+}
- XSetInputFocus(display, frame.workspace_label,
- RevertToPointerRoot, CurrentTime);
- XClearWindow(display, frame.workspace_label);
- openbox.setNoFocus(True);
- if (openbox.focusedWindow())
- openbox.focusedWindow()->setFocusFlag(False);
-
- XDrawRectangle(display, frame.workspace_label,
- screen.getWindowStyle()->l_text_focus_gc,
- frame.workspace_label_w / 2, 0, 1,
- frame.label_h - 1);
-
- // change the background of the window to that of an active window label
- Pixmap tmp = frame.wlabel;
- BTexture *texture = &(screen.getWindowStyle()->l_focus);
- if (texture->getTexture() == (BImage_Flat | BImage_Solid)) {
- frame.wlabel = None;
- XSetWindowBackground(display, frame.workspace_label,
- texture->getColor()->getPixel());
- } else {
- frame.wlabel =
- image_ctrl->renderImage(frame.workspace_label_w, frame.label_h, texture);
- XSetWindowBackgroundPixmap(display, frame.workspace_label, frame.wlabel);
- }
- if (tmp) image_ctrl->removeImage(tmp);
- }
+void Toolbar::edit(void) {
+ Window window;
+ int foo;
+
+ editing = True;
+ XGetInputFocus(display, &window, &foo);
+ if (window == frame.workspace_label)
+ return;
+
+ XSetInputFocus(display, frame.workspace_label,
+ RevertToPointerRoot, CurrentTime);
+ XClearWindow(display, frame.workspace_label);
+
+ blackbox->setNoFocus(True);
+ if (blackbox->getFocusedWindow())
+ blackbox->getFocusedWindow()->setFocusFlag(False);
+
+ ToolbarStyle *style = screen->getToolbarStyle();
+ BPen pen(style->l_text, style->font);
+ XDrawRectangle(display, frame.workspace_label, pen.gc(),
+ frame.workspace_label_w / 2, 0, 1,
+ frame.label_h - 1);
+ // change the background of the window to that of an active window label
+ BTexture *texture = &(screen->getWindowStyle()->l_focus);
+ frame.wlabel = texture->render(frame.workspace_label_w, frame.label_h,
+ frame.wlabel);
+ if (! frame.wlabel)
+ XSetWindowBackground(display, frame.workspace_label,
+ texture->color().pixel());
+ else
+ XSetWindowBackgroundPixmap(display, frame.workspace_label, frame.wlabel);
+}
- void Toolbar::buttonPressEvent(XButtonEvent *be) {
- if (be->button == 1) {
- if (be->window == frame.psbutton)
- redrawPrevWorkspaceButton(True, True);
- else if (be->window == frame.nsbutton)
- redrawNextWorkspaceButton(True, True);
- else if (be->window == frame.pwbutton)
- redrawPrevWindowButton(True, True);
- else if (be->window == frame.nwbutton)
- redrawNextWindowButton(True, True);
+void Toolbar::buttonPressEvent(XButtonEvent *be) {
+ if (be->button == 1) {
+ if (be->window == frame.psbutton)
+ redrawPrevWorkspaceButton(True, True);
+ else if (be->window == frame.nsbutton)
+ redrawNextWorkspaceButton(True, True);
+ else if (be->window == frame.pwbutton)
+ redrawPrevWindowButton(True, True);
+ else if (be->window == frame.nwbutton)
+ redrawNextWindowButton(True, True);
#ifndef HAVE_STRFTIME
- else if (be->window == frame.clock) {
- XClearWindow(display, frame.clock);
- checkClock(True, True);
- }
+ else if (be->window == frame.clock) {
+ XClearWindow(display, frame.clock);
+ checkClock(True, True);
+ }
#endif // HAVE_STRFTIME
- else if (! m_ontop) {
- Window w[1] = { frame.window };
- screen.raiseWindows(w, 1);
- }
- } else if (be->button == 2 && (! m_ontop)) {
- XLowerWindow(display, frame.window);
- } else if (be->button == 3) {
- if (! toolbarmenu->isVisible()) {
- int x, y;
-
- x = be->x_root - (toolbarmenu->getWidth() / 2);
- y = be->y_root - (toolbarmenu->getHeight() / 2);
-
- if (x < 0)
- x = 0;
- else if (x + toolbarmenu->getWidth() > screen.size().w())
- x = screen.size().w() - toolbarmenu->getWidth();
-
- if (y < 0)
- y = 0;
- else if (y + toolbarmenu->getHeight() > screen.size().h())
- y = screen.size().h() - toolbarmenu->getHeight();
-
- toolbarmenu->move(x, y);
- toolbarmenu->show();
- } else
- toolbarmenu->hide();
+ else if (! on_top) {
+ Window w[1] = { frame.window };
+ screen->raiseWindows(w, 1);
}
- }
+ } else if (be->button == 2 && (! on_top)) {
+ XLowerWindow(display, frame.window);
+ } else if (be->button == 3) {
+ if (toolbarmenu->isVisible()) {
+ toolbarmenu->hide();
+ } else {
+ int x, y;
+ x = be->x_root - (toolbarmenu->getWidth() / 2);
+ y = be->y_root - (toolbarmenu->getHeight() / 2);
+ if (x < 0)
+ x = 0;
+ else if (x + toolbarmenu->getWidth() > screen->getWidth())
+ x = screen->getWidth() - toolbarmenu->getWidth();
- void Toolbar::buttonReleaseEvent(XButtonEvent *re) {
- if (re->button == 1) {
- if (re->window == frame.psbutton) {
- redrawPrevWorkspaceButton(False, True);
-
- if (re->x >= 0 && re->x < (signed) frame.button_w &&
- re->y >= 0 && re->y < (signed) frame.button_w)
- if (screen.getCurrentWorkspace()->getWorkspaceID() > 0)
- screen.changeWorkspaceID(screen.getCurrentWorkspace()->
- getWorkspaceID() - 1);
- else
- screen.changeWorkspaceID(screen.getWorkspaceCount() - 1);
- } else if (re->window == frame.nsbutton) {
- redrawNextWorkspaceButton(False, True);
-
- if (re->x >= 0 && re->x < (signed) frame.button_w &&
- re->y >= 0 && re->y < (signed) frame.button_w)
- if (screen.getCurrentWorkspace()->getWorkspaceID() <
- screen.getWorkspaceCount() - 1)
- screen.changeWorkspaceID(screen.getCurrentWorkspace()->
- getWorkspaceID() + 1);
- else
- screen.changeWorkspaceID(0);
- } else if (re->window == frame.pwbutton) {
- redrawPrevWindowButton(False, True);
-
- if (re->x >= 0 && re->x < (signed) frame.button_w &&
- re->y >= 0 && re->y < (signed) frame.button_w)
- screen.prevFocus();
- } else if (re->window == frame.nwbutton) {
- redrawNextWindowButton(False, True);
-
- if (re->x >= 0 && re->x < (signed) frame.button_w &&
- re->y >= 0 && re->y < (signed) frame.button_w)
- screen.nextFocus();
- } else if (re->window == frame.window_label)
- screen.raiseFocus();
-#ifndef HAVE_STRFTIME
- else if (re->window == frame.clock) {
- XClearWindow(display, frame.clock);
- checkClock(True);
- }
-#endif // HAVE_STRFTIME
+ if (y < 0)
+ y = 0;
+ else if (y + toolbarmenu->getHeight() > screen->getHeight())
+ y = screen->getHeight() - toolbarmenu->getHeight();
+
+ toolbarmenu->move(x, y);
+ toolbarmenu->show();
}
}
+}
- void Toolbar::enterNotifyEvent(XCrossingEvent *) {
- if (! m_autohide)
- return;
- if (m_hidden) {
- if (! hide_timer->isTiming()) hide_timer->start();
- } else {
- if (hide_timer->isTiming()) hide_timer->stop();
+void Toolbar::buttonReleaseEvent(XButtonEvent *re) {
+ if (re->button == 1) {
+ if (re->window == frame.psbutton) {
+ redrawPrevWorkspaceButton(False, True);
+
+ if (re->x >= 0 && re->x < static_cast<signed>(frame.button_w) &&
+ re->y >= 0 && re->y < static_cast<signed>(frame.button_w))
+ if (screen->getCurrentWorkspace()->getID() > 0)
+ screen->changeWorkspaceID(screen->getCurrentWorkspace()->
+ getID() - 1);
+ else
+ screen->changeWorkspaceID(screen->getWorkspaceCount() - 1);
+ } else if (re->window == frame.nsbutton) {
+ redrawNextWorkspaceButton(False, True);
+
+ if (re->x >= 0 && re->x < static_cast<signed>(frame.button_w) &&
+ re->y >= 0 && re->y < static_cast<signed>(frame.button_w))
+ if (screen->getCurrentWorkspace()->getID() <
+ (screen->getWorkspaceCount() - 1))
+ screen->changeWorkspaceID(screen->getCurrentWorkspace()->
+ getID() + 1);
+ else
+ screen->changeWorkspaceID(0);
+ } else if (re->window == frame.pwbutton) {
+ redrawPrevWindowButton(False, True);
+
+ if (re->x >= 0 && re->x < static_cast<signed>(frame.button_w) &&
+ re->y >= 0 && re->y < static_cast<signed>(frame.button_w))
+ screen->prevFocus();
+ } else if (re->window == frame.nwbutton) {
+ redrawNextWindowButton(False, True);
+
+ if (re->x >= 0 && re->x < static_cast<signed>(frame.button_w) &&
+ re->y >= 0 && re->y < static_cast<signed>(frame.button_w))
+ screen->nextFocus();
+ } else if (re->window == frame.window_label)
+ screen->raiseFocus();
+#ifndef HAVE_STRFTIME
+ else if (re->window == frame.clock) {
+ XClearWindow(display, frame.clock);
+ checkClock(True);
}
+#endif // HAVE_STRFTIME
}
+}
- void Toolbar::leaveNotifyEvent(XCrossingEvent *) {
- if (! m_autohide)
- return;
- if (m_hidden) {
- if (hide_timer->isTiming()) hide_timer->stop();
- } else if (! toolbarmenu->isVisible()) {
- if (! hide_timer->isTiming()) hide_timer->start();
- }
+void Toolbar::enterNotifyEvent(XCrossingEvent *) {
+ if (! do_auto_hide)
+ return;
+
+ if (hidden) {
+ if (! hide_timer->isTiming()) hide_timer->start();
+ } else {
+ if (hide_timer->isTiming()) hide_timer->stop();
}
+}
+void Toolbar::leaveNotifyEvent(XCrossingEvent *) {
+ if (! do_auto_hide)
+ return;
- void Toolbar::exposeEvent(XExposeEvent *ee) {
- if (ee->window == frame.clock) checkClock(True);
- else if (ee->window == frame.workspace_label && (! m_editing))
- redrawWorkspaceLabel();
- else if (ee->window == frame.window_label) redrawWindowLabel();
- else if (ee->window == frame.psbutton) redrawPrevWorkspaceButton();
- else if (ee->window == frame.nsbutton) redrawNextWorkspaceButton();
- else if (ee->window == frame.pwbutton) redrawPrevWindowButton();
- else if (ee->window == frame.nwbutton) redrawNextWindowButton();
+ if (hidden) {
+ if (hide_timer->isTiming()) hide_timer->stop();
+ } else if (! toolbarmenu->isVisible()) {
+ if (! hide_timer->isTiming()) hide_timer->start();
}
+}
- void Toolbar::keyPressEvent(XKeyEvent *ke) {
- if (ke->window == frame.workspace_label && m_editing) {
- openbox.grab();
+void Toolbar::exposeEvent(XExposeEvent *ee) {
+ if (ee->window == frame.clock) checkClock(True);
+ else if (ee->window == frame.workspace_label && (! editing))
+ redrawWorkspaceLabel();
+ else if (ee->window == frame.window_label) redrawWindowLabel();
+ else if (ee->window == frame.psbutton) redrawPrevWorkspaceButton();
+ else if (ee->window == frame.nsbutton) redrawNextWorkspaceButton();
+ else if (ee->window == frame.pwbutton) redrawPrevWindowButton();
+ else if (ee->window == frame.nwbutton) redrawNextWindowButton();
+}
- if (! new_workspace_name) {
- new_workspace_name = new char[128];
- new_name_pos = 0;
- if (! new_workspace_name) return;
- }
+void Toolbar::keyPressEvent(XKeyEvent *ke) {
+ if (ke->window == frame.workspace_label && editing) {
+ if (new_workspace_name.empty()) {
+ new_name_pos = 0;
+ }
- KeySym ks;
- char keychar[1];
- XLookupString(ke, keychar, 1, &ks, 0);
-
- // either we are told to end with a return or we hit the end of the buffer
- if (ks == XK_Return || new_name_pos == 127) {
- *(new_workspace_name + new_name_pos) = 0;
-
- m_editing = False;
-
- openbox.setNoFocus(False);
- if (openbox.focusedWindow()) {
- openbox.focusedWindow()->setInputFocus();
- openbox.focusedWindow()->setFocusFlag(True);
- } else
- openbox.focusWindow((OpenboxWindow *) 0);
-
- // check to make sure that new_name[0] != 0... otherwise we have a null
- // workspace name which causes serious problems, especially for the
- // Openbox::LoadRC() method.
- if (*new_workspace_name) {
- screen.getCurrentWorkspace()->setName(new_workspace_name);
- screen.getCurrentWorkspace()->getMenu()->hide();
- screen.getWorkspacemenu()->
- remove(screen.getCurrentWorkspace()->getWorkspaceID() + 2);
- screen.getWorkspacemenu()->
- insert(screen.getCurrentWorkspace()->getName(),
- screen.getCurrentWorkspace()->getMenu(),
- screen.getCurrentWorkspace()->getWorkspaceID() + 2);
- screen.getWorkspacemenu()->update();
- }
+ KeySym ks;
+ char keychar[1];
+ XLookupString(ke, keychar, 1, &ks, 0);
- delete [] new_workspace_name;
- new_workspace_name = (char *) 0;
- new_name_pos = 0;
-
- // reset the background to that of the workspace label (its normal
- // setting)
- Pixmap tmp = frame.wlabel;
- BTexture *texture = &(screen.getToolbarStyle()->label);
- if (texture->getTexture() == (BImage_Flat | BImage_Solid)) {
- frame.wlabel = None;
- XSetWindowBackground(display, frame.workspace_label,
- texture->getColor()->getPixel());
- } else {
- frame.wlabel =
- image_ctrl->renderImage(frame.workspace_label_w, frame.label_h, texture);
- XSetWindowBackgroundPixmap(display, frame.workspace_label, frame.wlabel);
- }
- if (tmp) image_ctrl->removeImage(tmp);
-
- reconfigure();
- } else if (! (ks == XK_Shift_L || ks == XK_Shift_R ||
- ks == XK_Control_L || ks == XK_Control_R ||
- ks == XK_Caps_Lock || ks == XK_Shift_Lock ||
- ks == XK_Meta_L || ks == XK_Meta_R ||
- ks == XK_Alt_L || ks == XK_Alt_R ||
- ks == XK_Super_L || ks == XK_Super_R ||
- ks == XK_Hyper_L || ks == XK_Hyper_R)) {
- if (ks == XK_BackSpace) {
- if (new_name_pos > 0) {
- --new_name_pos;
- *(new_workspace_name + new_name_pos) = '\0';
- } else {
- *new_workspace_name = '\0';
- }
- } else {
- *(new_workspace_name + new_name_pos) = *keychar;
- ++new_name_pos;
- *(new_workspace_name + new_name_pos) = '\0';
- }
+ // either we are told to end with a return or we hit 127 chars
+ if (ks == XK_Return || new_name_pos == 127) {
+ editing = False;
- XClearWindow(display, frame.workspace_label);
- int l = strlen(new_workspace_name), tw, x;
+ blackbox->setNoFocus(False);
+ if (blackbox->getFocusedWindow()) {
+ blackbox->getFocusedWindow()->setInputFocus();
+ } else {
+ blackbox->setFocusedWindow(0);
+ }
- if (i18n.multibyte()) {
- XRectangle ink, logical;
- XmbTextExtents(screen.getToolbarStyle()->fontset,
- new_workspace_name, l, &ink, &logical);
- tw = logical.width;
+ Workspace *wkspc = screen->getCurrentWorkspace();
+ wkspc->setName(new_workspace_name);
+ wkspc->getMenu()->hide();
+
+ screen->getWorkspacemenu()->changeItemLabel(wkspc->getID() + 2,
+ wkspc->getName());
+ screen->getWorkspacemenu()->update();
+
+ new_workspace_name.erase();
+ new_name_pos = 0;
+
+ // reset the background to that of the workspace label (its normal
+ // setting)
+ BTexture *texture = &(screen->getToolbarStyle()->label);
+ frame.wlabel = texture->render(frame.workspace_label_w, frame.label_h,
+ frame.wlabel);
+ if (! frame.wlabel)
+ XSetWindowBackground(display, frame.workspace_label,
+ texture->color().pixel());
+ else
+ XSetWindowBackgroundPixmap(display, frame.workspace_label,
+ frame.wlabel);
+ reconfigure();
+ } else if (! (ks == XK_Shift_L || ks == XK_Shift_R ||
+ ks == XK_Control_L || ks == XK_Control_R ||
+ ks == XK_Caps_Lock || ks == XK_Shift_Lock ||
+ ks == XK_Meta_L || ks == XK_Meta_R ||
+ ks == XK_Alt_L || ks == XK_Alt_R ||
+ ks == XK_Super_L || ks == XK_Super_R ||
+ ks == XK_Hyper_L || ks == XK_Hyper_R)) {
+ if (ks == XK_BackSpace) {
+ if (new_name_pos > 0) {
+ --new_name_pos;
+ new_workspace_name.erase(new_name_pos);
} else {
- tw = XTextWidth(screen.getToolbarStyle()->font,
- new_workspace_name, l);
+ new_workspace_name.resize(0);
}
- x = (frame.workspace_label_w - tw) / 2;
-
- if (x < (signed) frame.bevel_w) x = frame.bevel_w;
+ } else {
+ new_workspace_name += (*keychar);
+ ++new_name_pos;
+ }
- WindowStyle *style = screen.getWindowStyle();
- if (i18n.multibyte())
- XmbDrawString(display, frame.workspace_label, style->fontset,
- style->l_text_focus_gc, x,
- (1 - style->fontset_extents->max_ink_extent.y),
- new_workspace_name, l);
- else
- XDrawString(display, frame.workspace_label, style->l_text_focus_gc, x,
- (style->font->ascent + 1),
- new_workspace_name, l);
+ XClearWindow(display, frame.workspace_label);
+ unsigned int l = new_workspace_name.length(), tw, x;
- XDrawRectangle(display, frame.workspace_label,
- screen.getWindowStyle()->l_text_focus_gc, x + tw, 0, 1,
- frame.label_h - 1);
+ if (i18n.multibyte()) {
+ XRectangle ink, logical;
+ XmbTextExtents(screen->getToolbarStyle()->fontset,
+ new_workspace_name.c_str(), l, &ink, &logical);
+ tw = logical.width;
+ } else {
+ tw = XTextWidth(screen->getToolbarStyle()->font,
+ new_workspace_name.c_str(), l);
}
+ x = (frame.workspace_label_w - tw) / 2;
+
+ if (x < frame.bevel_w) x = frame.bevel_w;
- openbox.ungrab();
+ ToolbarStyle *style = screen->getToolbarStyle();
+ BPen pen(style->l_text, style->font);
+ if (i18n.multibyte())
+ XmbDrawString(display, frame.workspace_label, style->fontset,
+ pen.gc(), x,
+ (1 - style->fontset_extents->max_ink_extent.y),
+ new_workspace_name.c_str(), l);
+ else
+ XDrawString(display, frame.workspace_label, pen.gc(), x,
+ (style->font->ascent + 1),
+ new_workspace_name.c_str(), l);
+ XDrawRectangle(display, frame.workspace_label, pen.gc(), x + tw, 0, 1,
+ frame.label_h - 1);
}
}
+}
- void Toolbar::timeout() {
- checkClock(True);
+void Toolbar::timeout(void) {
+ checkClock(True);
- timeval now;
- gettimeofday(&now, 0);
- clock_timer->setTimeout((60 - (now.tv_sec % 60)) * 1000);
- }
+ clock_timer->setTimeout(aMinuteFromNow());
+}
- void Toolbar::HideHandler::timeout() {
- toolbar->m_hidden = !toolbar->m_hidden;
- if (toolbar->m_hidden)
- XMoveWindow(toolbar->display, toolbar->frame.window,
- toolbar->frame.x_hidden, toolbar->frame.y_hidden);
- else
- XMoveWindow(toolbar->display, toolbar->frame.window,
- toolbar->frame.x, toolbar->frame.y);
+void Toolbar::HideHandler::timeout(void) {
+ toolbar->hidden = ! toolbar->hidden;
+ if (toolbar->hidden)
+ XMoveWindow(toolbar->display, toolbar->frame.window,
+ toolbar->frame.x_hidden, toolbar->frame.y_hidden);
+ else
+ XMoveWindow(toolbar->display, toolbar->frame.window,
+ toolbar->frame.rect.x(), toolbar->frame.rect.y());
+}
+
+
+void Toolbar::toggleAutoHide(void) {
+ do_auto_hide = (do_auto_hide) ? False : True;
+
+ updateStrut();
+ screen->getSlit()->reposition();
+
+ if (do_auto_hide == False && hidden) {
+ // force the slit to be visible
+ if (hide_timer->isTiming()) hide_timer->stop();
+ hide_handler.timeout();
}
+}
- Toolbarmenu::Toolbarmenu(Toolbar &tb) : Basemenu(tb.screen), toolbar(tb) {
- setLabel(i18n(ToolbarSet, ToolbarToolbarTitle, "Toolbar"));
- setInternalMenu();
+Toolbarmenu::Toolbarmenu(Toolbar *tb) : Basemenu(tb->screen) {
+ toolbar = tb;
- placementmenu = new Placementmenu(*this);
+ setLabel(i18n(ToolbarSet, ToolbarToolbarTitle, "Toolbar"));
+ setInternalMenu();
- insert(i18n(CommonSet, CommonPlacementTitle, "Placement"),
- placementmenu);
- insert(i18n(CommonSet, CommonAlwaysOnTop, "Always on top"), 1);
- insert(i18n(CommonSet, CommonAutoHide, "Auto hide"), 2);
- insert(i18n(ToolbarSet, ToolbarEditWkspcName,
- "Edit current workspace name"), 3);
+ placementmenu = new Placementmenu(this);
- update();
+ insert(i18n(CommonSet, CommonPlacementTitle, "Placement"),
+ placementmenu);
+ insert(i18n(CommonSet, CommonAlwaysOnTop, "Always on top"), 1);
+ insert(i18n(CommonSet, CommonAutoHide, "Auto hide"), 2);
+ insert(i18n(ToolbarSet, ToolbarEditWkspcName,
+ "Edit current workspace name"), 3);
- setValues();
- }
+ update();
- void Toolbarmenu::setValues() {
- setItemSelected(1, toolbar.onTop());
- setItemSelected(2, toolbar.autoHide());
+ if (toolbar->isOnTop()) setItemSelected(1, True);
+ if (toolbar->doAutoHide()) setItemSelected(2, True);
+}
+
+
+Toolbarmenu::~Toolbarmenu(void) {
+ delete placementmenu;
+}
+
+
+void Toolbarmenu::itemSelected(int button, unsigned int index) {
+ if (button != 1)
+ return;
+
+ BasemenuItem *item = find(index);
+ if (! item) return;
+
+ switch (item->function()) {
+ case 1: { // always on top
+ toolbar->on_top = ((toolbar->isOnTop()) ? False : True);;
+ setItemSelected(1, toolbar->on_top);
+
+ if (toolbar->isOnTop()) getScreen()->raiseWindows((Window *) 0, 0);
+ break;
}
+ case 2: { // auto hide
+ toolbar->toggleAutoHide();
+ setItemSelected(2, toolbar->do_auto_hide);
- Toolbarmenu::~Toolbarmenu() {
- delete placementmenu;
+ break;
}
+ case 3: { // edit current workspace name
+ toolbar->edit();
+ hide();
- void Toolbarmenu::itemSelected(int button, int index) {
- if (button != 1)
- return;
+ break;
+ }
+ } // switch
+}
- BasemenuItem *item = find(index);
- if (! item) return;
- switch (item->function()) {
- case 1: { // always on top
- Bool change = ((toolbar.onTop()) ? False : True);
- toolbar.setOnTop(change);
- setItemSelected(1, change);
+void Toolbarmenu::internal_hide(void) {
+ Basemenu::internal_hide();
+ if (toolbar->doAutoHide() && ! toolbar->isEditing())
+ toolbar->hide_handler.timeout();
+}
- if (toolbar.onTop()) toolbar.screen.raiseWindows((Window *) 0, 0);
- break;
- }
- case 2: { // auto hide
- Bool change = ((toolbar.autoHide()) ? False : True);
- toolbar.setAutoHide(change);
- setItemSelected(2, change);
+void Toolbarmenu::reconfigure(void) {
+ placementmenu->reconfigure();
-#ifdef SLIT
- toolbar.screen.getSlit()->reposition();
-#endif // SLIT
- break;
- }
+ Basemenu::reconfigure();
+}
- case 3: { // edit current workspace name
- toolbar.edit();
- hide();
- break;
- }
- } // switch
- }
+Toolbarmenu::Placementmenu::Placementmenu(Toolbarmenu *tm)
+ : Basemenu(tm->toolbar->screen) {
+ setLabel(i18n(ToolbarSet, ToolbarToolbarPlacement, "Toolbar Placement"));
+ setInternalMenu();
+ setMinimumSublevels(3);
+
+ insert(i18n(CommonSet, CommonPlacementTopLeft, "Top Left"),
+ Toolbar::TopLeft);
+ insert(i18n(CommonSet, CommonPlacementBottomLeft, "Bottom Left"),
+ Toolbar::BottomLeft);
+ insert(i18n(CommonSet, CommonPlacementTopCenter, "Top Center"),
+ Toolbar::TopCenter);
+ insert(i18n(CommonSet, CommonPlacementBottomCenter, "Bottom Center"),
+ Toolbar::BottomCenter);
+ insert(i18n(CommonSet, CommonPlacementTopRight, "Top Right"),
+ Toolbar::TopRight);
+ insert(i18n(CommonSet, CommonPlacementBottomRight, "Bottom Right"),
+ Toolbar::BottomRight);
+ update();
+}
- void Toolbarmenu::internal_hide() {
- Basemenu::internal_hide();
- if (toolbar.autoHide() && ! toolbar.isEditing())
- toolbar.hide_handler.timeout();
- }
+void Toolbarmenu::Placementmenu::itemSelected(int button, unsigned int index) {
+ if (button != 1)
+ return;
+ BasemenuItem *item = find(index);
+ if (! item) return;
- void Toolbarmenu::reconfigure() {
- setValues();
- placementmenu->reconfigure();
+ getScreen()->saveToolbarPlacement(item->function());
+ hide();
+ getScreen()->getToolbar()->reconfigure();
- Basemenu::reconfigure();
- }
+ // reposition the slit as well to make sure it doesn't intersect the
+ // toolbar
+ getScreen()->getSlit()->reposition();
+}
- Toolbarmenu::Placementmenu::Placementmenu(Toolbarmenu &tm)
- : Basemenu(tm.toolbar.screen), toolbarmenu(tm) {
- setLabel(i18n(ToolbarSet, ToolbarToolbarPlacement,
- "Toolbar Placement"));
- setInternalMenu();
- setMinimumSublevels(3);
-
- insert(i18n(CommonSet, CommonPlacementTopLeft,
- "Top Left"), Toolbar::TopLeft);
- insert(i18n(CommonSet, CommonPlacementBottomLeft,
- "Bottom Left"), Toolbar::BottomLeft);
- insert(i18n(CommonSet, CommonPlacementTopCenter,
- "Top Center"), Toolbar::TopCenter);
- insert(i18n(CommonSet, CommonPlacementBottomCenter,
- "Bottom Center"), Toolbar::BottomCenter);
- insert(i18n(CommonSet, CommonPlacementTopRight,
- "Top Right"), Toolbar::TopRight);
- insert(i18n(CommonSet, CommonPlacementBottomRight,
- "Bottom Right"), Toolbar::BottomRight);
- update();
- }
+int ToolbarStyle::doJustify(const char *text, int &start_pos,
+ unsigned int max_length, unsigned int modifier,
+ bool multibyte) const {
+ size_t text_len = strlen(text);
+ unsigned int length;
- void Toolbarmenu::Placementmenu::itemSelected(int button, int index) {
- if (button != 1)
- return;
+ do {
+ if (multibyte) {
+ XRectangle ink, logical;
+ XmbTextExtents(fontset, text, text_len, &ink, &logical);
+ length = logical.width;
+ } else {
+ length = XTextWidth(font, text, text_len);
+ }
+ length += modifier;
+ } while (length > max_length && text_len-- > 0);
- BasemenuItem *item = find(index);
- if (! item) return;
+ switch (justify) {
+ case RightJustify:
+ start_pos += max_length - length;
+ break;
- toolbarmenu.toolbar.setPlacement(item->function());
- hide();
- toolbarmenu.toolbar.reconfigure();
+ case CenterJustify:
+ start_pos += (max_length - length) / 2;
+ break;
-#ifdef SLIT
- // reposition the slit as well to make sure it doesn't intersect the
- // toolbar
- toolbarmenu.toolbar.screen.getSlit()->reposition();
-#endif // SLIT
+ case LeftJustify:
+ default:
+ break;
}
+
+ return text_len;
+}
+++ /dev/null
-// Toolbar.h for Openbox
-// Copyright (c) 2001 Sean 'Shaleh' Perry <shaleh@debian.org>
-// Copyright (c) 1997 - 2000 Brad Hughes (bhughes@tcac.net)
-//
-// Permission is hereby granted, free of charge, to any person obtaining a
-// copy of this software and associated documentation files (the "Software"),
-// to deal in the Software without restriction, including without limitation
-// the rights to use, copy, modify, merge, publish, distribute, sublicense,
-// and/or sell copies of the Software, and to permit persons to whom the
-// Software is furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-// DEALINGS IN THE SOFTWARE.
-
-#ifndef __Toolbar_hh
-#define __Toolbar_hh
-
-#include <X11/Xlib.h>
-
-#include "Basemenu.h"
-#include "Timer.h"
-#include "Resource.h"
-#include "Screen.h"
-#include "Geometry.h"
-
-// forward declaration
-class Toolbar;
-
-class Toolbarmenu : public Basemenu {
-private:
- class Placementmenu : public Basemenu {
- private:
- Toolbarmenu &toolbarmenu;
-
- protected:
- virtual void itemSelected(int, int);
-
- public:
- Placementmenu(Toolbarmenu &);
- };
-
- Toolbar &toolbar;
- Placementmenu *placementmenu;
-
- friend class Placementmenu;
- friend class Toolbar;
-
-
-protected:
- virtual void itemSelected(int, int);
- virtual void internal_hide();
- virtual void setValues();
-
-public:
- Toolbarmenu(Toolbar &);
- ~Toolbarmenu();
-
- inline Basemenu *getPlacementmenu() { return placementmenu; }
-
- void reconfigure();
-};
-
-
-class Toolbar : public TimeoutHandler {
-private:
- bool m_ontop, m_editing, m_hidden, m_autohide;
- int m_width_percent, m_placement;
- Display *display;
-
- struct frame {
- unsigned long button_pixel, pbutton_pixel;
- Pixmap base, label, wlabel, clk, button, pbutton;
- Window window, workspace_label, window_label, clock, psbutton, nsbutton,
- pwbutton, nwbutton;
-
- int x, y, x_hidden, y_hidden, hour, minute, grab_x, grab_y;
- unsigned int width, height, window_label_w, workspace_label_w, clock_w,
- button_w, bevel_w, label_h;
- } frame;
-
- class HideHandler : public TimeoutHandler {
- public:
- Toolbar *toolbar;
- virtual void timeout();
- } hide_handler;
-
- Openbox &openbox;
- BScreen &screen;
- Resource &config;
- BImageControl *image_ctrl;
- BTimer *clock_timer, *hide_timer;
- Toolbarmenu *toolbarmenu;
-
- char *new_workspace_name;
- size_t new_name_pos;
-
- friend class HideHandler;
- friend class Toolbarmenu;
- friend class Toolbarmenu::Placementmenu;
-
-
-public:
- Toolbar(BScreen &, Resource &);
- virtual ~Toolbar();
-
- inline Toolbarmenu *getMenu() { return toolbarmenu; }
-
- inline const Window &getWindowID() const { return frame.window; }
-
- //inline unsigned int getWidth() const { return frame.width; }
- //inline unsigned int getHeight() const { return frame.height; }
- unsigned int getExposedHeight() const;
-
- //int getX() const;
- //int getY() const;
-
- Rect area() const;
- //Size size() const { return area().size(); }
- //Point origin() const { return area().origin(); }
-
- void buttonPressEvent(XButtonEvent *);
- void buttonReleaseEvent(XButtonEvent *);
- void enterNotifyEvent(XCrossingEvent *);
- void leaveNotifyEvent(XCrossingEvent *);
- void exposeEvent(XExposeEvent *);
- void keyPressEvent(XKeyEvent *);
-
- void redrawWindowLabel(Bool = False);
- void redrawWorkspaceLabel(Bool = False);
- void redrawPrevWorkspaceButton(Bool = False, Bool = False);
- void redrawNextWorkspaceButton(Bool = False, Bool = False);
- void redrawPrevWindowButton(Bool = False, Bool = False);
- void redrawNextWindowButton(Bool = False, Bool = False);
- void edit();
- void reconfigure();
- void load();
- void save();
- void mapToolbar();
- void unMapToolbar();
-#ifdef HAVE_STRFTIME
- void checkClock(Bool = False);
-#else // HAVE_STRFTIME
- void checkClock(Bool = False, Bool = False);
-#endif // HAVE_STRFTIME
-
- virtual void timeout();
-
- inline bool onTop() const { return m_ontop; }
- void setOnTop(bool);
-
- inline bool autoHide() const { return m_autohide; }
- void setAutoHide(bool);
-
- inline int widthPercent() const { return m_width_percent; }
- void setWidthPercent(int);
-
- inline int placement() const { return m_placement; }
- void setPlacement(int);
-
- inline bool isEditing() const { return m_editing; }
- inline bool isHidden() const { return m_hidden; }
-
- enum { TopLeft = 1, BottomLeft, TopCenter,
- BottomCenter, TopRight, BottomRight };
-};
-
-
-#endif // __Toolbar_hh
--- /dev/null
+// -*- mode: C++; indent-tabs-mode: nil; -*-
+// Toolbar.hh for Blackbox - an X11 Window manager
+// Copyright (c) 2001 - 2002 Sean 'Shaleh' Perry <shaleh@debian.org>
+// Copyright (c) 1997 - 2000 Brad Hughes (bhughes@tcac.net)
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#ifndef __Toolbar_hh
+#define __Toolbar_hh
+
+extern "C" {
+#include <X11/Xlib.h>
+}
+
+#include "Screen.hh"
+#include "Basemenu.hh"
+#include "Timer.hh"
+
+// forward declaration
+class Toolbar;
+
+class Toolbarmenu : public Basemenu {
+private:
+ class Placementmenu : public Basemenu {
+ private:
+ Placementmenu(const Placementmenu&);
+ Placementmenu& operator=(const Placementmenu&);
+
+ protected:
+ virtual void itemSelected(int button, unsigned int index);
+
+ public:
+ Placementmenu(Toolbarmenu *tm);
+ };
+
+ Toolbar *toolbar;
+ Placementmenu *placementmenu;
+
+ friend class Placementmenu;
+ friend class Toolbar;
+
+ Toolbarmenu(const Toolbarmenu&);
+ Toolbarmenu& operator=(const Toolbarmenu&);
+
+protected:
+ virtual void itemSelected(int button, unsigned int index);
+ virtual void internal_hide(void);
+
+public:
+ Toolbarmenu(Toolbar *tb);
+ ~Toolbarmenu(void);
+
+ inline Basemenu *getPlacementmenu(void) { return placementmenu; }
+
+ void reconfigure(void);
+};
+
+
+class Toolbar : public TimeoutHandler {
+private:
+ bool on_top, editing, hidden, do_auto_hide;
+ Display *display;
+
+ struct ToolbarFrame {
+ unsigned long button_pixel, pbutton_pixel;
+ Pixmap base, label, wlabel, clk, button, pbutton;
+ Window window, workspace_label, window_label, clock, psbutton, nsbutton,
+ pwbutton, nwbutton;
+
+ int x_hidden, y_hidden, hour, minute, grab_x, grab_y;
+ unsigned int window_label_w, workspace_label_w, clock_w,
+ button_w, bevel_w, label_h;
+
+ Rect rect;
+ } frame;
+
+ class HideHandler : public TimeoutHandler {
+ public:
+ Toolbar *toolbar;
+
+ virtual void timeout(void);
+ } hide_handler;
+
+ Blackbox *blackbox;
+ BScreen *screen;
+ BTimer *clock_timer, *hide_timer;
+ Toolbarmenu *toolbarmenu;
+ Strut strut;
+
+ std::string new_workspace_name;
+ size_t new_name_pos;
+
+ friend class HideHandler;
+ friend class Toolbarmenu;
+ friend class Toolbarmenu::Placementmenu;
+
+ void redrawPrevWorkspaceButton(bool pressed = False, bool redraw = False);
+ void redrawNextWorkspaceButton(bool pressed = False, bool redraw = False);
+ void redrawPrevWindowButton(bool preseed = False, bool redraw = False);
+ void redrawNextWindowButton(bool preseed = False, bool redraw = False);
+
+ void updateStrut(void);
+
+#ifdef HAVE_STRFTIME
+ void checkClock(bool redraw = False);
+#else // HAVE_STRFTIME
+ void checkClock(bool redraw = False, bool date = False);
+#endif // HAVE_STRFTIME
+
+ Toolbar(const Toolbar&);
+ Toolbar& operator=(const Toolbar&);
+
+public:
+ Toolbar(BScreen *scrn);
+ virtual ~Toolbar(void);
+
+ inline Toolbarmenu *getMenu(void) { return toolbarmenu; }
+
+ inline bool isEditing(void) const { return editing; }
+ inline bool isOnTop(void) const { return on_top; }
+ inline bool isHidden(void) const { return hidden; }
+ inline bool doAutoHide(void) const { return do_auto_hide; }
+
+ inline Window getWindowID(void) const { return frame.window; }
+
+ inline const Rect& getRect(void) const { return frame.rect; }
+ inline unsigned int getWidth(void) const { return frame.rect.width(); }
+ inline unsigned int getHeight(void) const { return frame.rect.height(); }
+ inline unsigned int getExposedHeight(void) const
+ { return ((do_auto_hide) ? frame.bevel_w : frame.rect.height()); }
+ inline int getX(void) const
+ { return ((hidden) ? frame.x_hidden : frame.rect.x()); }
+ inline int getY(void) const
+ { return ((hidden) ? frame.y_hidden : frame.rect.y()); }
+
+ void buttonPressEvent(XButtonEvent *be);
+ void buttonReleaseEvent(XButtonEvent *re);
+ void enterNotifyEvent(XCrossingEvent * /*unused*/);
+ void leaveNotifyEvent(XCrossingEvent * /*unused*/);
+ void exposeEvent(XExposeEvent *ee);
+ void keyPressEvent(XKeyEvent *ke);
+
+ void edit(void);
+ void reconfigure(void);
+ void toggleAutoHide(void);
+
+ void redrawWindowLabel(bool redraw = False);
+ void redrawWorkspaceLabel(bool redraw = False);
+
+ virtual void timeout(void);
+
+ enum { TopLeft = 1, BottomLeft, TopCenter,
+ BottomCenter, TopRight, BottomRight };
+};
+
+
+#endif // __Toolbar_hh
// -*- mode: C++; indent-tabs-mode: nil; c-basic-offset: 2; -*-
-// Util.cc for Openbox
-// Copyright (c) 2002 - 2002 Ben Jansens (ben at orodu.net)
-// Copyright (c) 2001 - 2002 Sean 'Shaleh' Perry (shaleh at debian.org)
-// Copyright (c) 1997 - 2000 Brad Hughes (bhughes at tcac.net)
+// Util.cc for Blackbox - an X11 Window manager
+// Copyright (c) 2002 Sean 'Shaleh' Perry <shaleh@debian.org>
+// Copyright (c) 1997 - 2000, 2002 Brad Hughes (bhughes@tcac.net)
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
-#include "../config.h"
+#ifdef HAVE_CONFIG_H
+# include "../config.h"
+#endif // HAVE_CONFIG_H
-#ifdef HAVE_SYS_TYPES_H
-# include <sys/types.h>
+extern "C" {
+#ifdef HAVE_STRING_H
+#include <string.h>
#endif
-
-#ifdef HAVE_UNISTD_H
-# include <unistd.h>
-#endif
-
#ifdef HAVE_STDLIB_H
-# include <stdlib.h>
+#include <stdlib.h>
#endif
+#ifdef TIME_WITH_SYS_TIME
+# include <sys/time.h>
+# include <time.h>
+#else // !TIME_WITH_SYS_TIME
+# ifdef HAVE_SYS_TIME_H
+# include <sys/time.h>
+# else // !HAVE_SYS_TIME_H
+# include <time.h>
+# endif // HAVE_SYS_TIME_H
+#endif // TIME_WITH_SYS_TIME
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif // HAVE_UNISTD_H
+#if defined(HAVE_PROCESS_H) && defined(__EMX__)
+# include <process.h>
+#endif // HAVE_PROCESS_H __EMX__
+}
+
+#include <X11/Xatom.h>
+
+#include <algorithm>
+
+#include "Util.hh"
+
+using std::string;
+
+
+void Rect::setX(int __x) {
+ _x2 += __x - _x1;
+ _x1 = __x;
+}
+
+
+void Rect::setY(int __y)
+{
+ _y2 += __y - _y1;
+ _y1 = __y;
+}
+
+
+void Rect::setPos(int __x, int __y) {
+ _x2 += __x - _x1;
+ _x1 = __x;
+ _y2 += __y - _y1;
+ _y1 = __y;
+}
+
+
+void Rect::setWidth(unsigned int __w) {
+ _x2 = __w + _x1 - 1;
+}
+
+
+void Rect::setHeight(unsigned int __h) {
+ _y2 = __h + _y1 - 1;
+}
+
+
+void Rect::setSize(unsigned int __w, unsigned int __h) {
+ _x2 = __w + _x1 - 1;
+ _y2 = __h + _y1 - 1;
+}
+
+
+void Rect::setRect(int __x, int __y, unsigned int __w, unsigned int __h) {
+ *this = Rect(__x, __y, __w, __h);
+}
+
+
+void Rect::setCoords(int __l, int __t, int __r, int __b) {
+ _x1 = __l;
+ _y1 = __t;
+ _x2 = __r;
+ _y2 = __b;
+}
+
+Rect Rect::operator|(const Rect &a) const {
+ Rect b;
+ b._x1 = std::min(_x1, a._x1);
+ b._y1 = std::min(_y1, a._y1);
+ b._x2 = std::max(_x2, a._x2);
+ b._y2 = std::max(_y2, a._y2);
+
+ return b;
+}
+
+
+Rect Rect::operator&(const Rect &a) const {
+ Rect b;
+
+ b._x1 = std::max(_x1, a._x1);
+ b._y1 = std::max(_y1, a._y1);
+ b._x2 = std::min(_x2, a._x2);
+ b._y2 = std::min(_y2, a._y2);
+
+ return b;
+}
+
+
+bool Rect::intersects(const Rect &a) const {
+ return std::max(_x1, a._x1) <= std::min(_x2, a._x2) &&
+ std::max(_y1, a._y1) <= std::min(_y2, a._y2);
+}
+
+
+string expandTilde(const string& s) {
+ if (s[0] != '~') return s;
+
+ const char* const home = getenv("HOME");
+ if (home == NULL) return s;
+
+ return string(home + s.substr(s.find('/')));
+}
+
+
+void bexec(const string& command, const string& displaystring) {
#ifndef __EMX__
-void bexec(const char *command, char* displaystring) {
if (! fork()) {
setsid();
- putenv(displaystring);
- execl("/bin/sh", "/bin/sh", "-c", command, NULL);
+ int ret = putenv(const_cast<char *>(displaystring.c_str()));
+ assert(ret != -1);
+ string cmd = "exec ";
+ cmd += command;
+ execl("/bin/sh", "/bin/sh", "-c", cmd.c_str(), NULL);
exit(0);
}
-}
+#else // __EMX__
+ spawnlp(P_NOWAIT, "cmd.exe", "cmd.exe", "/c", command, NULL);
#endif // !__EMX__
+}
-char *bstrdup(const char *s) {
- const int l = strlen(s) + 1;
- char *n = new char[l];
- strncpy(n, s, l);
- return n;
+#ifndef HAVE_BASENAME
+string basename (const string& path) {
+ string::size_type slash = path.rfind('/');
+ if (slash == string::npos)
+ return path;
+ return path.substr(slash+1);
}
+#endif // HAVE_BASENAME
-#ifndef HAVE_BASENAME
-char *basename (char *s) {
- char *save = s;
+string textPropertyToString(Display *display, XTextProperty& text_prop) {
+ string ret;
- while (*s) if (*s++ == '/') save = s;
+ if (text_prop.value && text_prop.nitems > 0) {
+ ret = (char *) text_prop.value;
+ if (text_prop.encoding != XA_STRING) {
+ text_prop.nitems = strlen((char *) text_prop.value);
- return save;
+ char **list;
+ int num;
+ if (XmbTextPropertyToTextList(display, &text_prop,
+ &list, &num) == Success &&
+ num > 0 && *list) {
+ ret = *list;
+ XFreeStringList(list);
+ }
+ }
+ }
+
+ return ret;
+}
+
+
+timeval normalizeTimeval(const timeval &tm) {
+ timeval ret = tm;
+
+ while (ret.tv_usec < 0) {
+ if (ret.tv_sec > 0) {
+ --ret.tv_sec;
+ ret.tv_usec += 1000000;
+ } else {
+ ret.tv_usec = 0;
+ }
+ }
+
+ if (ret.tv_usec >= 1000000) {
+ ret.tv_sec += ret.tv_usec / 1000000;
+ ret.tv_usec %= 1000000;
+ }
+
+ if (ret.tv_sec < 0) ret.tv_sec = 0;
+
+ return ret;
}
-#endif // HAVE_BASENAME
+++ /dev/null
-// Util.h for Openbox
-// Copyright (c) 2002 - 2002 Ben Jansens (ben@orodu.net)
-//
-// Permission is hereby granted, free of charge, to any person obtaining a
-// copy of this software and associated documentation files (the "Software"),
-// to deal in the Software without restriction, including without limitation
-// the rights to use, copy, modify, merge, publish, distribute, sublicense,
-// and/or sell copies of the Software, and to permit persons to whom the
-// Software is furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-// DEALINGS IN THE SOFTWARE.
-
-#ifndef __Util_hh
-#define __Util_hh
-
-#ifdef DEBUG
-# include <assert.h>
-# define ASSERT(x) assert(x)
-#else // !DEBUG
-# define ASSERT(x)
-#endif // DEBUG
-
-struct PointerAssassin {
- template<typename T>
- inline void operator()(const T ptr) const {
- delete ptr;
- }
-};
-
-#endif // __Util_hh
--- /dev/null
+// -*- mode: C++; indent-tabs-mode: nil; c-basic-offset: 2; -*-
+// Util.cc for Blackbox - an X11 Window manager
+// Copyright (c) 2002 Sean 'Shaleh' Perry <shaleh@debian.org>
+// Copyright (c) 1997 - 2000 Brad Hughes (bhughes@tcac.net)
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#ifndef _BLACKBOX_UTIL_HH
+#define _BLACKBOX_UTIL_HH
+
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+
+#include <string>
+
+class Rect {
+public:
+ inline Rect(void) : _x1(0), _y1(0), _x2(0), _y2(0) { }
+ inline Rect(int __x, int __y, unsigned int __w, unsigned int __h)
+ : _x1(__x), _y1(__y), _x2(__w + __x - 1), _y2(__h + __y - 1) { }
+ inline explicit Rect(const XRectangle& xrect)
+ : _x1(xrect.x), _y1(xrect.y), _x2(xrect.width + xrect.x - 1),
+ _y2(xrect.height + xrect.y - 1) { }
+
+ inline int left(void) const { return _x1; }
+ inline int top(void) const { return _y1; }
+ inline int right(void) const { return _x2; }
+ inline int bottom(void) const { return _y2; }
+
+ inline int x(void) const { return _x1; }
+ inline int y(void) const { return _y1; }
+ void setX(int __x);
+ void setY(int __y);
+ void setPos(int __x, int __y);
+
+ inline unsigned int width(void) const { return _x2 - _x1 + 1; }
+ inline unsigned int height(void) const { return _y2 - _y1 + 1; }
+ void setWidth(unsigned int __w);
+ void setHeight(unsigned int __h);
+ void setSize(unsigned int __w, unsigned int __h);
+
+ void setRect(int __x, int __y, unsigned int __w, unsigned int __h);
+
+ void setCoords(int __l, int __t, int __r, int __b);
+
+ inline bool operator==(const Rect &a)
+ { return _x1 == a._x1 && _y1 == a._y1 && _x2 == a._x2 && _y2 == a._y2; }
+ inline bool operator!=(const Rect &a) { return ! operator==(a); }
+
+ Rect operator|(const Rect &a) const;
+ Rect operator&(const Rect &a) const;
+ inline Rect &operator|=(const Rect &a) { *this = *this | a; return *this; }
+ inline Rect &operator&=(const Rect &a) { *this = *this & a; return *this; }
+
+ inline bool valid(void) const { return _x2 > _x1 && _y2 > _y1; }
+
+ bool intersects(const Rect &a) const;
+
+private:
+ int _x1, _y1, _x2, _y2;
+};
+
+/* XXX: this needs autoconf help */
+const unsigned int BSENTINEL = 65535;
+
+std::string expandTilde(const std::string& s);
+
+void bexec(const std::string& command, const std::string& displaystring);
+
+#ifndef HAVE_BASENAME
+std::string basename(const std::string& path);
+#endif
+
+std::string textPropertyToString(Display *display, XTextProperty& text_prop);
+
+struct timeval; // forward declare to avoid the header
+timeval normalizeTimeval(const timeval &tm);
+
+struct PointerAssassin {
+ template<typename T>
+ inline void operator()(const T ptr) const {
+ delete ptr;
+ }
+};
+
+#endif
-// Window.cc for Openbox
-// Copyright (c) 2002 - 2002 Ben Jansens (ben at orodu.net)
-// Copyright (c) 2001 - 2002 Sean 'Shaleh' Perry (shaleh at debian.org)
-// Copyright (c) 1997 - 2000 Brad Hughes (bhughes at tcac.net)
+// -*- mode: C++; indent-tabs-mode: nil; c-basic-offset: 2; -*-
+// Window.cc for Blackbox - an X11 Window manager
+// Copyright (c) 2001 - 2002 Sean 'Shaleh' Perry <shaleh at debian.org>
+// Copyright (c) 1997 - 2000, 2002 Brad Hughes <bhughes at trolltech.com>
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
-// stupid macros needed to access some functions in version 2 of the GNU C
-// library
-#ifndef _GNU_SOURCE
-#define _GNU_SOURCE
-#endif // _GNU_SOURCE
-
#ifdef HAVE_CONFIG_H
# include "../config.h"
#endif // HAVE_CONFIG_H
+extern "C" {
#include <X11/Xatom.h>
#include <X11/keysym.h>
-#ifdef HAVE_STRING_H
+#ifdef HAVE_STRING_H
# include <string.h>
#endif // HAVE_STRING_H
# include <stdio.h>
# endif // HAVE_STDIO_H
#endif // DEBUG
+}
+
+#include <cstdlib>
+
+#include "i18n.hh"
+#include "blackbox.hh"
+#include "GCCache.hh"
+#include "Iconmenu.hh"
+#include "Image.hh"
+#include "Screen.hh"
+#include "Toolbar.hh"
+#include "Util.hh"
+#include "Window.hh"
+#include "Windowmenu.hh"
+#include "Workspace.hh"
+#include "Slit.hh"
-#include "i18n.h"
-#include "openbox.h"
-#include "Iconmenu.h"
-#include "Screen.h"
-#include "Toolbar.h"
-#include "Window.h"
-#include "Windowmenu.h"
-#include "Workspace.h"
-#ifdef SLIT
-# include "Slit.h"
-#endif // SLIT
-#include "Util.h"
/*
* Initializes the class with default values/the window's set initial values.
*/
-OpenboxWindow::OpenboxWindow(Openbox &o, Window w, BScreen *s) : openbox(o) {
+BlackboxWindow::BlackboxWindow(Blackbox *b, Window w, BScreen *s) {
+ // fprintf(stderr, "BlackboxWindow size: %d bytes\n",
+ // sizeof(BlackboxWindow));
+
#ifdef DEBUG
- fprintf(stderr, i18n(WindowSet, WindowCreating,
- "OpenboxWindow::OpenboxWindow(): creating 0x%lx\n"),
- w);
+ fprintf(stderr, "BlackboxWindow::BlackboxWindow(): creating 0x%lx\n", w);
#endif // DEBUG
+ // set timer to zero... it is initialized properly later, so we check
+ // if timer is zero in the destructor, and assume that the window is not
+ // fully constructed if timer is zero...
+ timer = 0;
+ blackbox = b;
client.window = w;
- display = openbox.getXDisplay();
+ screen = s;
+
+ if (! validateClient()) {
+ delete this;
+ return;
+ }
- openbox.grab();
- if (! validateClient()) return;
+ // set the eventmask early in the game so that we make sure we get
+ // all the events we are interested in
+ XSetWindowAttributes attrib_set;
+ attrib_set.event_mask = PropertyChangeMask | FocusChangeMask |
+ StructureNotifyMask;
+ attrib_set.do_not_propagate_mask = ButtonPressMask | ButtonReleaseMask |
+ ButtonMotionMask;
+ XChangeWindowAttributes(blackbox->getXDisplay(), client.window,
+ CWEventMask|CWDontPropagate, &attrib_set);
// fetch client size and placement
XWindowAttributes wattrib;
- if ((! XGetWindowAttributes(display, client.window, &wattrib)) ||
+ if ((! XGetWindowAttributes(blackbox->getXDisplay(),
+ client.window, &wattrib)) ||
(! wattrib.screen) || wattrib.override_redirect) {
#ifdef DEBUG
fprintf(stderr,
- i18n(WindowSet, WindowXGetWindowAttributesFail,
- "OpenboxWindow::OpenboxWindow(): XGetWindowAttributes "
- "failed\n"));
+ "BlackboxWindow::BlackboxWindow(): XGetWindowAttributes failed\n");
#endif // DEBUG
- openbox.ungrab();
+ delete this;
return;
}
- if (s) {
- screen = s;
- } else {
- screen = openbox.searchScreen(RootWindowOfScreen(wattrib.screen));
- if (! screen) {
-#ifdef DEBUG
- fprintf(stderr, i18n(WindowSet, WindowCannotFindScreen,
- "OpenboxWindow::OpenboxWindow(): can't find screen\n"
- "\tfor root window 0x%lx\n"),
- RootWindowOfScreen(wattrib.screen));
-#endif // DEBUG
-
- openbox.ungrab();
- return;
- }
- }
-
flags.moving = flags.resizing = flags.shaded = flags.visible =
- flags.iconic = flags.transient = flags.focused =
- flags.stuck = flags.modal = flags.send_focus_message =
- flags.shaped = flags.managed = False;
+ flags.iconic = flags.focused = flags.stuck = flags.modal =
+ flags.send_focus_message = flags.shaped = False;
flags.maximized = 0;
- openbox_attrib.workspace = workspace_number = window_number = -1;
+ blackbox_attrib.workspace = window_number = BSENTINEL;
- openbox_attrib.flags = openbox_attrib.attrib = openbox_attrib.stack
- = openbox_attrib.decoration = 0l;
- openbox_attrib.premax_x = openbox_attrib.premax_y = 0;
- openbox_attrib.premax_w = openbox_attrib.premax_h = 0;
+ blackbox_attrib.flags = blackbox_attrib.attrib = blackbox_attrib.stack
+ = blackbox_attrib.decoration = 0l;
+ blackbox_attrib.premax_x = blackbox_attrib.premax_y = 0;
+ blackbox_attrib.premax_w = blackbox_attrib.premax_h = 0;
+ frame.border_w = 1;
frame.window = frame.plate = frame.title = frame.handle = None;
frame.close_button = frame.iconify_button = frame.maximize_button = None;
frame.right_grip = frame.left_grip = None;
+ frame.ulabel_pixel = frame.flabel_pixel = frame.utitle_pixel =
+ frame.ftitle_pixel = frame.uhandle_pixel = frame.fhandle_pixel =
+ frame.ubutton_pixel = frame.fbutton_pixel = frame.pbutton_pixel =
+ frame.uborder_pixel = frame.fborder_pixel = frame.ugrip_pixel =
+ frame.fgrip_pixel = 0;
frame.utitle = frame.ftitle = frame.uhandle = frame.fhandle = None;
frame.ulabel = frame.flabel = frame.ubutton = frame.fbutton = None;
- frame.pbutton = frame.ugrip = frame.fgrip = None;
+ frame.pbutton = frame.ugrip = frame.fgrip = decorations;
- decorations.titlebar = decorations.border = decorations.handle = True;
- decorations.iconify = decorations.maximize = decorations.menu = True;
- functions.resize = functions.move = functions.iconify =
- functions.maximize = True;
- functions.close = decorations.close = False;
+ decorations = Decor_Titlebar | Decor_Border | Decor_Handle |
+ Decor_Iconify | Decor_Maximize;
+ functions = Func_Resize | Func_Move | Func_Iconify | Func_Maximize;
client.wm_hint_flags = client.normal_hint_flags = 0;
- client.transient_for = client.transient = 0;
- client.title = 0;
- client.title_len = 0;
- client.icon_title = 0;
- client.mwm_hint = (MwmHints *) 0;
- client.openbox_hint = (OpenboxHints *) 0;
+ client.transient_for = 0;
// get the initial size and location of client window (relative to the
// _root window_). This position is the reference point used with the
// window's gravity to find the window's initial position.
- client.x = wattrib.x;
- client.y = wattrib.y;
- client.width = wattrib.width;
- client.height = wattrib.height;
+ client.rect.setRect(wattrib.x, wattrib.y, wattrib.width, wattrib.height);
client.old_bw = wattrib.border_width;
windowmenu = 0;
lastButtonPressTime = 0;
- image_ctrl = screen->getImageControl();
- timer = new BTimer(openbox, *this);
- timer->setTimeout(openbox.getAutoRaiseDelay());
- timer->fireOnce(True);
+ timer = new BTimer(blackbox, this);
+ timer->setTimeout(blackbox->getAutoRaiseDelay());
- getOpenboxHints();
- if (! client.openbox_hint)
+ if (! getBlackboxHints())
getMWMHints();
// get size, aspect, minimum/maximum size and other hints set by the
getWMHints();
getWMNormalHints();
-#ifdef SLIT
if (client.initial_state == WithdrawnState) {
screen->getSlit()->addClient(client.window);
- openbox.ungrab();
delete this;
return;
}
-#endif // SLIT
- flags.managed = True;
- openbox.saveWindowSearch(client.window, this);
+ frame.window = createToplevelWindow();
+ frame.plate = createChildWindow(frame.window);
+ associateClientWindow();
- // determine if this is a transient window
- Window win;
- if (XGetTransientForHint(display, client.window, &win)) {
- if (win && (win != client.window)) {
- OpenboxWindow *tr;
- if ((tr = openbox.searchWindow(win))) {
- while (tr->client.transient) tr = tr->client.transient;
- client.transient_for = tr;
- tr->client.transient = this;
- flags.stuck = client.transient_for->flags.stuck;
- flags.transient = True;
- } else if (win == client.window_group) {
- if ((tr = openbox.searchGroup(win, this))) {
- while (tr->client.transient) tr = tr->client.transient;
- client.transient_for = tr;
- tr->client.transient = this;
- flags.stuck = client.transient_for->flags.stuck;
- flags.transient = True;
- }
- }
- }
+ blackbox->saveWindowSearch(frame.window, this);
+ blackbox->saveWindowSearch(frame.plate, this);
+ blackbox->saveWindowSearch(client.window, this);
- if (win == screen->getRootWindow()) flags.modal = True;
- }
+ // determine if this is a transient window
+ getTransientInfo();
// adjust the window decorations based on transience and window sizes
- if (flags.transient)
- decorations.maximize = decorations.handle = functions.maximize = False;
+ if (isTransient()) {
+ decorations &= ~(Decor_Maximize | Decor_Handle);
+ functions &= ~Func_Maximize;
+ }
if ((client.normal_hint_flags & PMinSize) &&
(client.normal_hint_flags & PMaxSize) &&
client.max_width <= client.min_width &&
client.max_height <= client.min_height) {
- decorations.maximize = decorations.handle =
- functions.resize = functions.maximize = False;
+ decorations &= ~(Decor_Maximize | Decor_Handle);
+ functions &= ~(Func_Resize | Func_Maximize);
}
upsize();
- place_window = true;
- if (openbox.isStartup() || flags.transient ||
+ bool place_window = True;
+ if (blackbox->isStartup() || isTransient() ||
client.normal_hint_flags & (PPosition|USPosition)) {
setGravityOffsets();
- if ((openbox.isStartup()) ||
- (frame.x >= 0 &&
- (signed) (frame.y + frame.y_border) >= 0 &&
- frame.x <= (signed) screen->size().w() &&
- frame.y <= (signed) screen->size().h()))
- place_window = false;
- }
-
- frame.window = createToplevelWindow(frame.x, frame.y, frame.width,
- frame.height,
- frame.border_w);
- openbox.saveWindowSearch(frame.window, this);
-
- frame.plate = createChildWindow(frame.window);
- openbox.saveWindowSearch(frame.plate, this);
- if (decorations.titlebar) {
- frame.title = createChildWindow(frame.window);
- frame.label = createChildWindow(frame.title);
- openbox.saveWindowSearch(frame.title, this);
- openbox.saveWindowSearch(frame.label, this);
+ if (blackbox->isStartup() ||
+ client.rect.intersects(screen->availableArea()))
+ place_window = False;
}
- if (decorations.handle) {
- frame.handle = createChildWindow(frame.window);
- openbox.saveWindowSearch(frame.handle, this);
+ if (decorations & Decor_Titlebar)
+ createTitlebar();
- frame.left_grip =
- createChildWindow(frame.handle, openbox.getLowerLeftAngleCursor());
- openbox.saveWindowSearch(frame.left_grip, this);
+ if (decorations & Decor_Handle)
+ createHandle();
- frame.right_grip =
- createChildWindow(frame.handle, openbox.getLowerRightAngleCursor());
- openbox.saveWindowSearch(frame.right_grip, this);
+#ifdef SHAPE
+ if (blackbox->hasShapeExtensions() && flags.shaped) {
+ configureShape();
}
+#endif // SHAPE
- associateClientWindow();
-
- if (! screen->sloppyFocus())
- openbox.grabButton(Button1, 0, frame.plate, True, ButtonPressMask,
- GrabModeSync, GrabModeSync, frame.plate, None);
+ if ((! screen->isSloppyFocus()) || screen->doClickRaise()) {
+ // grab button 1 for changing focus/raising
+ blackbox->grabButton(Button1, 0, frame.plate, True, ButtonPressMask,
+ GrabModeSync, GrabModeSync, frame.plate, None);
+ }
- openbox.grabButton(Button1, Mod1Mask, frame.window, True,
- ButtonReleaseMask | ButtonMotionMask, GrabModeAsync,
- GrabModeAsync, frame.window, openbox.getMoveCursor());
- openbox.grabButton(Button2, Mod1Mask, frame.window, True,
- ButtonReleaseMask, GrabModeAsync, GrabModeAsync, frame.window, None);
- openbox.grabButton(Button3, Mod1Mask, frame.window, True,
- ButtonReleaseMask | ButtonMotionMask, GrabModeAsync,
- GrabModeAsync, frame.window, None);
+ blackbox->grabButton(Button1, Mod1Mask, frame.window, True,
+ ButtonReleaseMask | ButtonMotionMask, GrabModeAsync,
+ GrabModeAsync, frame.window, blackbox->getMoveCursor());
+ blackbox->grabButton(Button2, Mod1Mask, frame.window, True,
+ ButtonReleaseMask, GrabModeAsync, GrabModeAsync,
+ frame.window, None);
+ blackbox->grabButton(Button3, Mod1Mask, frame.window, True,
+ ButtonReleaseMask | ButtonMotionMask, GrabModeAsync,
+ GrabModeAsync, frame.window,
+ blackbox->getLowerRightAngleCursor());
positionWindows();
- XRaiseWindow(display, frame.plate);
- XMapSubwindows(display, frame.plate);
- if (decorations.titlebar) XMapSubwindows(display, frame.title);
- XMapSubwindows(display, frame.window);
+ decorate();
- if (decorations.menu)
- windowmenu = new Windowmenu(*this);
+ if (decorations & Decor_Titlebar)
+ XMapSubwindows(blackbox->getXDisplay(), frame.title);
+ XMapSubwindows(blackbox->getXDisplay(), frame.window);
- decorate();
+ windowmenu = new Windowmenu(this);
- if (workspace_number < 0 || workspace_number >= screen->getWorkspaceCount())
+ if (blackbox_attrib.workspace >= screen->getWorkspaceCount())
screen->getCurrentWorkspace()->addWindow(this, place_window);
else
- screen->getWorkspace(workspace_number)->addWindow(this, place_window);
+ screen->getWorkspace(blackbox_attrib.workspace)->
+ addWindow(this, place_window);
- configure(frame.x, frame.y, frame.width, frame.height);
+ if (! place_window) {
+ // don't need to call configure if we are letting the workspace
+ // place the window
+ configure(frame.rect.x(), frame.rect.y(),
+ frame.rect.width(), frame.rect.height());
+ }
if (flags.shaded) {
flags.shaded = False;
shade();
}
- if (flags.maximized && functions.maximize) {
- unsigned int button = flags.maximized;
- flags.maximized = 0;
- maximize(button);
+ if (flags.maximized && (functions & Func_Maximize)) {
+ remaximize();
}
setFocusFlag(False);
-
- openbox.ungrab();
}
-OpenboxWindow::~OpenboxWindow(void) {
- if (flags.moving || flags.resizing) {
- screen->hideGeometry();
- XUngrabPointer(display, CurrentTime);
- }
-
- if (workspace_number != -1 && window_number != -1) {
- if (flags.stuck) {
- // make sure no other workspaces think that we're focused
- for (int i=0; i < screen->getWorkspaceCount(); i++)
- screen->getWorkspace(i)->removeWindow(this);
- } else
- screen->getWorkspace(workspace_number)->removeWindow(this);
- } else if (flags.iconic)
- screen->removeIcon(this);
-
- if (timer) {
- if (timer->isTiming()) timer->stop();
- delete timer;
- }
-
- if (windowmenu) delete windowmenu;
-
- if (client.title)
- delete [] client.title;
-
- if (client.icon_title)
- delete [] client.icon_title;
-
- if (client.mwm_hint)
- XFree(client.mwm_hint);
+BlackboxWindow::~BlackboxWindow(void) {
- if (client.openbox_hint)
- XFree(client.openbox_hint);
-
- if (client.window_group)
- openbox.removeGroupSearch(client.window_group);
-
- if (flags.transient && client.transient_for)
- client.transient_for->client.transient = client.transient;
- if (client.transient)
- client.transient->client.transient_for = client.transient_for;
-
- if (frame.close_button) {
- openbox.removeWindowSearch(frame.close_button);
- XDestroyWindow(display, frame.close_button);
- }
+#ifdef DEBUG
+ fprintf(stderr, "BlackboxWindow::~BlackboxWindow: destroying 0x%lx\n",
+ client.window);
+#endif // DEBUG
- if (frame.iconify_button) {
- openbox.removeWindowSearch(frame.iconify_button);
- XDestroyWindow(display, frame.iconify_button);
- }
+ if (! timer) // window not managed...
+ return;
- if (frame.maximize_button) {
- openbox.removeWindowSearch(frame.maximize_button);
- XDestroyWindow(display, frame.maximize_button);
+ if (flags.moving || flags.resizing) {
+ screen->hideGeometry();
+ XUngrabPointer(blackbox->getXDisplay(), CurrentTime);
}
- if (frame.title) {
- if (frame.ftitle)
- image_ctrl->removeImage(frame.ftitle);
-
- if (frame.utitle)
- image_ctrl->removeImage(frame.utitle);
-
- if (frame.flabel)
- image_ctrl->removeImage(frame.flabel);
+ delete timer;
- if( frame.ulabel)
- image_ctrl->removeImage(frame.ulabel);
+ delete windowmenu;
- openbox.removeWindowSearch(frame.label);
- openbox.removeWindowSearch(frame.title);
- XDestroyWindow(display, frame.label);
- XDestroyWindow(display, frame.title);
+ if (client.window_group) {
+ BWindowGroup *group = blackbox->searchGroup(client.window_group);
+ if (group) group->removeWindow(this);
}
- if (frame.handle) {
- if (frame.fhandle)
- image_ctrl->removeImage(frame.fhandle);
-
- if (frame.uhandle)
- image_ctrl->removeImage(frame.uhandle);
-
- if (frame.fgrip)
- image_ctrl->removeImage(frame.fgrip);
-
- if (frame.ugrip)
- image_ctrl->removeImage(frame.ugrip);
-
- openbox.removeWindowSearch(frame.handle);
- openbox.removeWindowSearch(frame.right_grip);
- openbox.removeWindowSearch(frame.left_grip);
- XDestroyWindow(display, frame.right_grip);
- XDestroyWindow(display, frame.left_grip);
- XDestroyWindow(display, frame.handle);
+ // remove ourselves from our transient_for
+ if (isTransient()) {
+ if (client.transient_for != (BlackboxWindow *) ~0ul) {
+ client.transient_for->client.transientList.remove(this);
+ }
+ client.transient_for = (BlackboxWindow*) 0;
}
- if (frame.fbutton)
- image_ctrl->removeImage(frame.fbutton);
+ if (client.transientList.size() > 0) {
+ // reset transient_for for all transients
+ BlackboxWindowList::iterator it, end = client.transientList.end();
+ for (it = client.transientList.begin(); it != end; ++it) {
+ (*it)->client.transient_for = (BlackboxWindow*) 0;
+ }
+ }
- if (frame.ubutton)
- image_ctrl->removeImage(frame.ubutton);
+ if (frame.title)
+ destroyTitlebar();
- if (frame.pbutton)
- image_ctrl->removeImage(frame.pbutton);
+ if (frame.handle)
+ destroyHandle();
if (frame.plate) {
- openbox.removeWindowSearch(frame.plate);
- XDestroyWindow(display, frame.plate);
+ blackbox->removeWindowSearch(frame.plate);
+ XDestroyWindow(blackbox->getXDisplay(), frame.plate);
}
if (frame.window) {
- openbox.removeWindowSearch(frame.window);
- XDestroyWindow(display, frame.window);
+ blackbox->removeWindowSearch(frame.window);
+ XDestroyWindow(blackbox->getXDisplay(), frame.window);
}
- if (flags.managed) {
- openbox.removeWindowSearch(client.window);
- screen->removeNetizen(client.window);
- }
+ blackbox->removeWindowSearch(client.window);
}
* width.
* Returns: the newly created window
*/
-Window OpenboxWindow::createToplevelWindow(int x, int y, unsigned int width,
- unsigned int height,
- unsigned int borderwidth)
-{
+Window BlackboxWindow::createToplevelWindow(void) {
XSetWindowAttributes attrib_create;
unsigned long create_mask = CWBackPixmap | CWBorderPixel | CWColormap |
- CWOverrideRedirect | CWEventMask;
+ CWOverrideRedirect | CWEventMask;
attrib_create.background_pixmap = None;
attrib_create.colormap = screen->getColormap();
attrib_create.override_redirect = True;
attrib_create.event_mask = ButtonPressMask | ButtonReleaseMask |
- ButtonMotionMask | EnterWindowMask;
+ ButtonMotionMask | EnterWindowMask;
- return XCreateWindow(display, screen->getRootWindow(), x, y, width, height,
- borderwidth, screen->getDepth(), InputOutput,
- screen->getVisual(), create_mask,
+ return XCreateWindow(blackbox->getXDisplay(), screen->getRootWindow(),
+ -1, -1, 1, 1, frame.border_w, screen->getDepth(),
+ InputOutput, screen->getVisual(), create_mask,
&attrib_create);
}
* Creates a child window, and optionally associates a given cursor with
* the new window.
*/
-Window OpenboxWindow::createChildWindow(Window parent, Cursor cursor) {
+Window BlackboxWindow::createChildWindow(Window parent, Cursor cursor) {
XSetWindowAttributes attrib_create;
unsigned long create_mask = CWBackPixmap | CWBorderPixel |
- CWEventMask;
+ CWEventMask;
attrib_create.background_pixmap = None;
attrib_create.event_mask = ButtonPressMask | ButtonReleaseMask |
- ButtonMotionMask | ExposureMask |
- EnterWindowMask | LeaveWindowMask;
+ ButtonMotionMask | ExposureMask;
if (cursor) {
create_mask |= CWCursor;
attrib_create.cursor = cursor;
}
- return XCreateWindow(display, parent, 0, 0, 1, 1, 0, screen->getDepth(),
- InputOutput, screen->getVisual(), create_mask,
- &attrib_create);
+ return XCreateWindow(blackbox->getXDisplay(), parent, 0, 0, 1, 1, 0,
+ screen->getDepth(), InputOutput, screen->getVisual(),
+ create_mask, &attrib_create);
}
-void OpenboxWindow::associateClientWindow(void) {
- XSetWindowBorderWidth(display, client.window, 0);
+void BlackboxWindow::associateClientWindow(void) {
+ XSetWindowBorderWidth(blackbox->getXDisplay(), client.window, 0);
getWMName();
getWMIconName();
- XChangeSaveSet(display, client.window, SetModeInsert);
- XSetWindowAttributes attrib_set;
+ XChangeSaveSet(blackbox->getXDisplay(), client.window, SetModeInsert);
- XSelectInput(display, frame.plate, NoEventMask);
- XReparentWindow(display, client.window, frame.plate, 0, 0);
- XSelectInput(display, frame.plate, SubstructureRedirectMask);
+ XSelectInput(blackbox->getXDisplay(), frame.plate, SubstructureRedirectMask);
- XFlush(display);
+ XGrabServer(blackbox->getXDisplay());
+ XSelectInput(blackbox->getXDisplay(), client.window, NoEventMask);
+ XReparentWindow(blackbox->getXDisplay(), client.window, frame.plate, 0, 0);
+ XSelectInput(blackbox->getXDisplay(), client.window,
+ PropertyChangeMask | FocusChangeMask | StructureNotifyMask);
+ XUngrabServer(blackbox->getXDisplay());
- attrib_set.event_mask = PropertyChangeMask | StructureNotifyMask |
- FocusChangeMask;
- attrib_set.do_not_propagate_mask = ButtonPressMask | ButtonReleaseMask |
- ButtonMotionMask;
+ XRaiseWindow(blackbox->getXDisplay(), frame.plate);
+ XMapSubwindows(blackbox->getXDisplay(), frame.plate);
- XChangeWindowAttributes(display, client.window, CWEventMask|CWDontPropagate,
- &attrib_set);
#ifdef SHAPE
- if (openbox.hasShapeExtensions()) {
- XShapeSelectInput(display, client.window, ShapeNotifyMask);
+ if (blackbox->hasShapeExtensions()) {
+ XShapeSelectInput(blackbox->getXDisplay(), client.window,
+ ShapeNotifyMask);
+ Bool shaped = False;
int foo;
unsigned int ufoo;
- XShapeQueryExtents(display, client.window, &flags.shaped, &foo, &foo,
- &ufoo, &ufoo, &foo, &foo, &foo, &ufoo, &ufoo);
-
- if (flags.shaped) {
- XShapeCombineShape(display, frame.window, ShapeBounding,
- frame.mwm_border_w, frame.y_border +
- frame.mwm_border_w, client.window,
- ShapeBounding, ShapeSet);
-
- int num = 1;
- XRectangle xrect[2];
- xrect[0].x = xrect[0].y = 0;
- xrect[0].width = frame.width;
- xrect[0].height = frame.y_border;
-
- if (decorations.handle) {
- xrect[1].x = 0;
- xrect[1].y = frame.y_handle;
- xrect[1].width = frame.width;
- xrect[1].height = frame.handle_h + frame.border_w;
- num++;
- }
-
- XShapeCombineRectangles(display, frame.window, ShapeBounding, 0, 0,
- xrect, num, ShapeUnion, Unsorted);
- }
+ XShapeQueryExtents(blackbox->getXDisplay(), client.window, &shaped,
+ &foo, &foo, &ufoo, &ufoo, &foo, &foo, &foo,
+ &ufoo, &ufoo);
+ flags.shaped = shaped;
}
#endif // SHAPE
-
- if (decorations.iconify) createIconifyButton();
- if (decorations.maximize) createMaximizeButton();
- if (decorations.close) createCloseButton();
}
-void OpenboxWindow::decorate(void) {
- Pixmap tmp = frame.fbutton;
- BTexture *texture = &(screen->getWindowStyle()->b_focus);
- if (texture->getTexture() == (BImage_Flat | BImage_Solid)) {
- frame.fbutton = None;
- frame.fbutton_pixel = texture->getColor()->getPixel();
- } else {
- frame.fbutton =
- image_ctrl->renderImage(frame.button_w, frame.button_h, texture);
- }
- if (tmp) image_ctrl->removeImage(tmp);
+void BlackboxWindow::decorate(void) {
+ BTexture* texture;
+
+ texture = &(screen->getWindowStyle()->b_focus);
+ frame.fbutton = texture->render(frame.button_w, frame.button_w,
+ frame.fbutton);
+ if (! frame.fbutton)
+ frame.fbutton_pixel = texture->color().pixel();
- tmp = frame.ubutton;
texture = &(screen->getWindowStyle()->b_unfocus);
- if (texture->getTexture() == (BImage_Flat | BImage_Solid)) {
- frame.ubutton = None;
- frame.ubutton_pixel = texture->getColor()->getPixel();
- } else {
- frame.ubutton =
- image_ctrl->renderImage(frame.button_w, frame.button_h, texture);
- }
- if (tmp) image_ctrl->removeImage(tmp);
+ frame.ubutton = texture->render(frame.button_w, frame.button_w,
+ frame.ubutton);
+ if (! frame.ubutton)
+ frame.ubutton_pixel = texture->color().pixel();
- tmp = frame.pbutton;
texture = &(screen->getWindowStyle()->b_pressed);
- if (texture->getTexture() == (BImage_Flat | BImage_Solid)) {
- frame.pbutton = None;
- frame.pbutton_pixel = texture->getColor()->getPixel();
- } else {
- frame.pbutton =
- image_ctrl->renderImage(frame.button_w, frame.button_h, texture);
- }
- if (tmp) image_ctrl->removeImage(tmp);
+ frame.pbutton = texture->render(frame.button_w, frame.button_w,
+ frame.pbutton);
+ if (! frame.pbutton)
+ frame.pbutton_pixel = texture->color().pixel();
- if (decorations.titlebar) {
- tmp = frame.ftitle;
+ if (decorations & Decor_Titlebar) {
texture = &(screen->getWindowStyle()->t_focus);
- if (texture->getTexture() == (BImage_Flat | BImage_Solid)) {
- frame.ftitle = None;
- frame.ftitle_pixel = texture->getColor()->getPixel();
- } else {
- frame.ftitle =
- image_ctrl->renderImage(frame.width, frame.title_h, texture);
- }
- if (tmp) image_ctrl->removeImage(tmp);
+ frame.ftitle = texture->render(frame.inside_w, frame.title_h,
+ frame.ftitle);
+ if (! frame.ftitle)
+ frame.ftitle_pixel = texture->color().pixel();
- tmp = frame.utitle;
texture = &(screen->getWindowStyle()->t_unfocus);
- if (texture->getTexture() == (BImage_Flat | BImage_Solid)) {
- frame.utitle = None;
- frame.utitle_pixel = texture->getColor()->getPixel();
- } else {
- frame.utitle =
- image_ctrl->renderImage(frame.width, frame.title_h, texture);
- }
- if (tmp) image_ctrl->removeImage(tmp);
+ frame.utitle = texture->render(frame.inside_w, frame.title_h,
+ frame.utitle);
+ if (! frame.utitle)
+ frame.utitle_pixel = texture->color().pixel();
- XSetWindowBorder(display, frame.title,
- screen->getBorderColor()->getPixel());
+ XSetWindowBorder(blackbox->getXDisplay(), frame.title,
+ screen->getBorderColor()->pixel());
decorateLabel();
}
- if (decorations.border) {
- frame.fborder_pixel = screen->getWindowStyle()->f_focus.getPixel();
- frame.uborder_pixel = screen->getWindowStyle()->f_unfocus.getPixel();
- openbox_attrib.flags |= AttribDecoration;
- openbox_attrib.decoration = DecorNormal;
+ if (decorations & Decor_Border) {
+ frame.fborder_pixel = screen->getWindowStyle()->f_focus.pixel();
+ frame.uborder_pixel = screen->getWindowStyle()->f_unfocus.pixel();
+ blackbox_attrib.flags |= AttribDecoration;
+ blackbox_attrib.decoration = DecorNormal;
} else {
- openbox_attrib.flags |= AttribDecoration;
- openbox_attrib.decoration = DecorNone;
+ blackbox_attrib.flags |= AttribDecoration;
+ blackbox_attrib.decoration = DecorNone;
}
- if (decorations.handle) {
- tmp = frame.fhandle;
+ if (decorations & Decor_Handle) {
texture = &(screen->getWindowStyle()->h_focus);
- if (texture->getTexture() == (BImage_Flat | BImage_Solid)) {
- frame.fhandle = None;
- frame.fhandle_pixel = texture->getColor()->getPixel();
- } else {
- frame.fhandle =
- image_ctrl->renderImage(frame.width, frame.handle_h, texture);
- }
- if (tmp) image_ctrl->removeImage(tmp);
+ frame.fhandle = texture->render(frame.inside_w, frame.handle_h,
+ frame.fhandle);
+ if (! frame.fhandle)
+ frame.fhandle_pixel = texture->color().pixel();
- tmp = frame.uhandle;
texture = &(screen->getWindowStyle()->h_unfocus);
- if (texture->getTexture() == (BImage_Flat | BImage_Solid)) {
- frame.uhandle = None;
- frame.uhandle_pixel = texture->getColor()->getPixel();
- } else {
- frame.uhandle =
- image_ctrl->renderImage(frame.width, frame.handle_h, texture);
- }
- if (tmp) image_ctrl->removeImage(tmp);
+ frame.uhandle = texture->render(frame.inside_w, frame.handle_h,
+ frame.uhandle);
+ if (! frame.uhandle)
+ frame.uhandle_pixel = texture->color().pixel();
- tmp = frame.fgrip;
texture = &(screen->getWindowStyle()->g_focus);
- if (texture->getTexture() == (BImage_Flat | BImage_Solid)) {
- frame.fgrip = None;
- frame.fgrip_pixel = texture->getColor()->getPixel();
- } else {
- frame.fgrip =
- image_ctrl->renderImage(frame.grip_w, frame.grip_h, texture);
- }
- if (tmp) image_ctrl->removeImage(tmp);
+ frame.fgrip = texture->render(frame.grip_w, frame.handle_h, frame.fgrip);
+ if (! frame.fgrip)
+ frame.fgrip_pixel = texture->color().pixel();
- tmp = frame.ugrip;
texture = &(screen->getWindowStyle()->g_unfocus);
- if (texture->getTexture() == (BImage_Flat | BImage_Solid)) {
- frame.ugrip = None;
- frame.ugrip_pixel = texture->getColor()->getPixel();
- } else {
- frame.ugrip =
- image_ctrl->renderImage(frame.grip_w, frame.grip_h, texture);
- }
- if (tmp) image_ctrl->removeImage(tmp);
+ frame.ugrip = texture->render(frame.grip_w, frame.handle_h, frame.ugrip);
+ if (! frame.ugrip)
+ frame.ugrip_pixel = texture->color().pixel();
- XSetWindowBorder(display, frame.handle,
- screen->getBorderColor()->getPixel());
- XSetWindowBorder(display, frame.left_grip,
- screen->getBorderColor()->getPixel());
- XSetWindowBorder(display, frame.right_grip,
- screen->getBorderColor()->getPixel());
+ XSetWindowBorder(blackbox->getXDisplay(), frame.handle,
+ screen->getBorderColor()->pixel());
+ XSetWindowBorder(blackbox->getXDisplay(), frame.left_grip,
+ screen->getBorderColor()->pixel());
+ XSetWindowBorder(blackbox->getXDisplay(), frame.right_grip,
+ screen->getBorderColor()->pixel());
}
- XSetWindowBorder(display, frame.window,
- screen->getBorderColor()->getPixel());
+ XSetWindowBorder(blackbox->getXDisplay(), frame.window,
+ screen->getBorderColor()->pixel());
}
-void OpenboxWindow::decorateLabel(void) {
- Pixmap tmp = frame.flabel;
- BTexture *texture = &(screen->getWindowStyle()->l_focus);
- if (texture->getTexture() == (BImage_Flat | BImage_Solid)) {
- frame.flabel = None;
- frame.flabel_pixel = texture->getColor()->getPixel();
- } else {
- frame.flabel =
- image_ctrl->renderImage(frame.label_w, frame.label_h, texture);
- }
- if (tmp) image_ctrl->removeImage(tmp);
+void BlackboxWindow::decorateLabel(void) {
+ BTexture *texture;
+
+ texture = &(screen->getWindowStyle()->l_focus);
+ frame.flabel = texture->render(frame.label_w, frame.label_h, frame.flabel);
+ if (! frame.flabel)
+ frame.flabel_pixel = texture->color().pixel();
- tmp = frame.ulabel;
texture = &(screen->getWindowStyle()->l_unfocus);
- if (texture->getTexture() == (BImage_Flat | BImage_Solid)) {
- frame.ulabel = None;
- frame.ulabel_pixel = texture->getColor()->getPixel();
- } else {
- frame.ulabel =
- image_ctrl->renderImage(frame.label_w, frame.label_h, texture);
- }
- if (tmp) image_ctrl->removeImage(tmp);
+ frame.ulabel = texture->render(frame.label_w, frame.label_h, frame.ulabel);
+ if (! frame.ulabel)
+ frame.ulabel_pixel = texture->color().pixel();
+}
+
+
+void BlackboxWindow::createHandle(void) {
+ frame.handle = createChildWindow(frame.window);
+ blackbox->saveWindowSearch(frame.handle, this);
+
+ frame.left_grip =
+ createChildWindow(frame.handle, blackbox->getLowerLeftAngleCursor());
+ blackbox->saveWindowSearch(frame.left_grip, this);
+
+ frame.right_grip =
+ createChildWindow(frame.handle, blackbox->getLowerRightAngleCursor());
+ blackbox->saveWindowSearch(frame.right_grip, this);
+}
+
+
+void BlackboxWindow::destroyHandle(void) {
+ if (frame.fhandle)
+ screen->getImageControl()->removeImage(frame.fhandle);
+
+ if (frame.uhandle)
+ screen->getImageControl()->removeImage(frame.uhandle);
+
+ if (frame.fgrip)
+ screen->getImageControl()->removeImage(frame.fgrip);
+
+ if (frame.ugrip)
+ screen->getImageControl()->removeImage(frame.ugrip);
+
+ blackbox->removeWindowSearch(frame.left_grip);
+ blackbox->removeWindowSearch(frame.right_grip);
+
+ XDestroyWindow(blackbox->getXDisplay(), frame.left_grip);
+ XDestroyWindow(blackbox->getXDisplay(), frame.right_grip);
+ frame.left_grip = frame.right_grip = None;
+
+ blackbox->removeWindowSearch(frame.handle);
+ XDestroyWindow(blackbox->getXDisplay(), frame.handle);
+ frame.handle = None;
+}
+
+
+void BlackboxWindow::createTitlebar(void) {
+ frame.title = createChildWindow(frame.window);
+ frame.label = createChildWindow(frame.title);
+ blackbox->saveWindowSearch(frame.title, this);
+ blackbox->saveWindowSearch(frame.label, this);
+
+ if (decorations & Decor_Iconify) createIconifyButton();
+ if (decorations & Decor_Maximize) createMaximizeButton();
+ if (decorations & Decor_Close) createCloseButton();
+}
+
+
+void BlackboxWindow::destroyTitlebar(void) {
+ if (frame.close_button)
+ destroyCloseButton();
+
+ if (frame.iconify_button)
+ destroyIconifyButton();
+
+ if (frame.maximize_button)
+ destroyMaximizeButton();
+
+ if (frame.ftitle)
+ screen->getImageControl()->removeImage(frame.ftitle);
+
+ if (frame.utitle)
+ screen->getImageControl()->removeImage(frame.utitle);
+
+ if (frame.flabel)
+ screen->getImageControl()->removeImage(frame.flabel);
+
+ if( frame.ulabel)
+ screen->getImageControl()->removeImage(frame.ulabel);
+
+ if (frame.fbutton)
+ screen->getImageControl()->removeImage(frame.fbutton);
+
+ if (frame.ubutton)
+ screen->getImageControl()->removeImage(frame.ubutton);
+
+ if (frame.pbutton)
+ screen->getImageControl()->removeImage(frame.pbutton);
+
+ blackbox->removeWindowSearch(frame.title);
+ blackbox->removeWindowSearch(frame.label);
+
+ XDestroyWindow(blackbox->getXDisplay(), frame.label);
+ XDestroyWindow(blackbox->getXDisplay(), frame.title);
+ frame.title = frame.label = None;
}
-void OpenboxWindow::createCloseButton(void) {
- if (decorations.close && frame.title != None) {
+void BlackboxWindow::createCloseButton(void) {
+ if (frame.title != None) {
frame.close_button = createChildWindow(frame.title);
- openbox.saveWindowSearch(frame.close_button, this);
+ blackbox->saveWindowSearch(frame.close_button, this);
}
}
-void OpenboxWindow::createIconifyButton(void) {
- if (decorations.iconify && frame.title != None) {
+void BlackboxWindow::destroyCloseButton(void) {
+ blackbox->removeWindowSearch(frame.close_button);
+ XDestroyWindow(blackbox->getXDisplay(), frame.close_button);
+ frame.close_button = None;
+}
+
+
+void BlackboxWindow::createIconifyButton(void) {
+ if (frame.title != None) {
frame.iconify_button = createChildWindow(frame.title);
- openbox.saveWindowSearch(frame.iconify_button, this);
+ blackbox->saveWindowSearch(frame.iconify_button, this);
}
}
-void OpenboxWindow::createMaximizeButton(void) {
- if (decorations.maximize && frame.title != None) {
+void BlackboxWindow::destroyIconifyButton(void) {
+ blackbox->removeWindowSearch(frame.iconify_button);
+ XDestroyWindow(blackbox->getXDisplay(), frame.iconify_button);
+ frame.iconify_button = None;
+}
+
+
+void BlackboxWindow::createMaximizeButton(void) {
+ if (frame.title != None) {
frame.maximize_button = createChildWindow(frame.title);
- openbox.saveWindowSearch(frame.maximize_button, this);
- }
-}
-
-
-void OpenboxWindow::positionButtons() {
- const char *format = openbox.getTitleBarLayout();
- const unsigned int bw = frame.bevel_w + 1;
- const unsigned int by = frame.bevel_w + 1;
- unsigned int bx = frame.bevel_w + 1;
- unsigned int bcount = strlen(format) - 1;
-
- if (!decorations.close)
- bcount--;
- if (!decorations.maximize)
- bcount--;
- if (!decorations.iconify)
- bcount--;
- frame.label_w = frame.width - bx * 2 - (frame.button_w + bw) * bcount;
-
- bool hasclose, hasiconify, hasmaximize;
- hasclose = hasiconify = hasmaximize = false;
-
- for (int i = 0; format[i] != '\0' && i < 4; i++) {
- switch(format[i]) {
- case 'C':
- if (decorations.close) {
- if (frame.close_button == None)
- createCloseButton();
- XMoveResizeWindow(display, frame.close_button, bx, by,
- frame.button_w, frame.button_h);
- XMapWindow(display, frame.close_button);
- XClearWindow(display, frame.close_button);
- bx += frame.button_w + bw;
- hasclose = true;
- }
- break;
- case 'I':
- if (decorations.iconify) {
- if (frame.iconify_button == None)
- createIconifyButton();
- XMoveResizeWindow(display, frame.iconify_button, bx, by,
- frame.button_w, frame.button_h);
- XMapWindow(display, frame.iconify_button);
- XClearWindow(display, frame.iconify_button);
- bx += frame.button_w + bw;
- hasiconify = true;
- }
- break;
- case 'M':
- if (decorations.maximize) {
- if (frame.maximize_button == None)
- createMaximizeButton();
- XMoveResizeWindow(display, frame.maximize_button, bx, by,
- frame.button_w, frame.button_h);
- XMapWindow(display, frame.maximize_button);
- XClearWindow(display, frame.maximize_button);
- bx += frame.button_w + bw;
- hasmaximize = true;
- }
- break;
- case 'L':
- XMoveResizeWindow(display, frame.label, bx, by - 1,
- frame.label_w, frame.label_h);
- bx += frame.label_w + bw;
- break;
- }
+ blackbox->saveWindowSearch(frame.maximize_button, this);
}
+}
+
- if (!hasclose && frame.close_button) {
- openbox.removeWindowSearch(frame.close_button);
- XDestroyWindow(display, frame.close_button);
- frame.close_button = None;
+void BlackboxWindow::destroyMaximizeButton(void) {
+ blackbox->removeWindowSearch(frame.maximize_button);
+ XDestroyWindow(blackbox->getXDisplay(), frame.maximize_button);
+ frame.maximize_button = None;
+}
+
+
+void BlackboxWindow::positionButtons(bool redecorate_label) {
+ unsigned int bw = frame.button_w + frame.bevel_w + 1,
+ by = frame.bevel_w + 1, lx = by, lw = frame.inside_w - by;
+
+ if (decorations & Decor_Iconify) {
+ if (frame.iconify_button == None) createIconifyButton();
+
+ XMoveResizeWindow(blackbox->getXDisplay(), frame.iconify_button, by, by,
+ frame.button_w, frame.button_w);
+ XMapWindow(blackbox->getXDisplay(), frame.iconify_button);
+ XClearWindow(blackbox->getXDisplay(), frame.iconify_button);
+
+ lx += bw;
+ lw -= bw;
+ } else if (frame.iconify_button) {
+ destroyIconifyButton();
}
- if (!hasiconify && frame.iconify_button) {
- openbox.removeWindowSearch(frame.iconify_button);
- XDestroyWindow(display, frame.iconify_button);
- frame.iconify_button = None;
+ int bx = frame.inside_w - bw;
+
+ if (decorations & Decor_Close) {
+ if (frame.close_button == None) createCloseButton();
+
+ XMoveResizeWindow(blackbox->getXDisplay(), frame.close_button, bx, by,
+ frame.button_w, frame.button_w);
+ XMapWindow(blackbox->getXDisplay(), frame.close_button);
+ XClearWindow(blackbox->getXDisplay(), frame.close_button);
+
+ bx -= bw;
+ lw -= bw;
+ } else if (frame.close_button) {
+ destroyCloseButton();
}
- if (!hasmaximize && frame.iconify_button) {
- openbox.removeWindowSearch(frame.maximize_button);
- XDestroyWindow(display, frame.maximize_button);
- frame.maximize_button = None;
+ if (decorations & Decor_Maximize) {
+ if (frame.maximize_button == None) createMaximizeButton();
+
+ XMoveResizeWindow(blackbox->getXDisplay(), frame.maximize_button, bx, by,
+ frame.button_w, frame.button_w);
+ XMapWindow(blackbox->getXDisplay(), frame.maximize_button);
+ XClearWindow(blackbox->getXDisplay(), frame.maximize_button);
+
+ lw -= bw;
+ } else if (frame.maximize_button) {
+ destroyMaximizeButton();
}
+ frame.label_w = lw - by;
+ XMoveResizeWindow(blackbox->getXDisplay(), frame.label, lx, frame.bevel_w,
+ frame.label_w, frame.label_h);
+ if (redecorate_label) decorateLabel();
redrawLabel();
redrawAllButtons();
}
-void OpenboxWindow::reconfigure(void) {
+void BlackboxWindow::reconfigure(void) {
upsize();
- client.x = frame.x + frame.mwm_border_w + frame.border_w;
- client.y = frame.y + frame.y_border + frame.mwm_border_w +
- frame.border_w;
-
- if (client.title) {
- if (i18n.multibyte()) {
- XRectangle ink, logical;
- XmbTextExtents(screen->getWindowStyle()->fontset,
- client.title, client.title_len, &ink, &logical);
- client.title_text_w = logical.width;
- } else {
- client.title_text_w = XTextWidth(screen->getWindowStyle()->font,
- client.title, client.title_len);
- }
- client.title_text_w += (frame.bevel_w * 4);
- }
+ client.rect.setPos(frame.rect.left() + frame.margin.left,
+ frame.rect.top() + frame.margin.top);
positionWindows();
decorate();
- XClearWindow(display, frame.window);
+ XClearWindow(blackbox->getXDisplay(), frame.window);
setFocusFlag(flags.focused);
- configure(frame.x, frame.y, frame.width, frame.height);
-
- if (! screen->sloppyFocus())
- openbox.grabButton(Button1, 0, frame.plate, True, ButtonPressMask,
- GrabModeSync, GrabModeSync, None, None);
- else
- openbox.ungrabButton(Button1, 0, frame.plate);
+ configure(frame.rect.x(), frame.rect.y(),
+ frame.rect.width(), frame.rect.height());
if (windowmenu) {
- windowmenu->move(windowmenu->getX(), frame.y + frame.title_h);
+ windowmenu->move(windowmenu->getX(), frame.rect.y() + frame.title_h);
windowmenu->reconfigure();
}
+}
+
- // re-get the timeout delay
- timer->setTimeout(openbox.getAutoRaiseDelay());
+void BlackboxWindow::updateFocusModel(void) {
+ if ((! screen->isSloppyFocus()) || screen->doClickRaise()) {
+ // grab button 1 for changing focus/raising
+ blackbox->grabButton(Button1, 0, frame.plate, True, ButtonPressMask,
+ GrabModeSync, GrabModeSync, None, None);
+ } else {
+ blackbox->ungrabButton(Button1, 0, frame.plate);
+ }
}
-void OpenboxWindow::positionWindows(void) {
- XResizeWindow(display, frame.window, frame.width,
- ((flags.shaded) ? frame.title_h : frame.height));
- XSetWindowBorderWidth(display, frame.window, frame.border_w);
- XSetWindowBorderWidth(display, frame.plate, frame.mwm_border_w);
- XMoveResizeWindow(display, frame.plate, 0, frame.y_border,
- client.width, client.height);
- XMoveResizeWindow(display, client.window, 0, 0, client.width, client.height);
+void BlackboxWindow::positionWindows(void) {
+ XMoveResizeWindow(blackbox->getXDisplay(), frame.window,
+ frame.rect.x(), frame.rect.y(), frame.inside_w,
+ (flags.shaded) ? frame.title_h : frame.inside_h);
+ XSetWindowBorderWidth(blackbox->getXDisplay(), frame.window, frame.border_w);
+ XSetWindowBorderWidth(blackbox->getXDisplay(), frame.plate,
+ frame.mwm_border_w);
+ XMoveResizeWindow(blackbox->getXDisplay(), frame.plate,
+ frame.margin.left - frame.mwm_border_w - frame.border_w,
+ frame.margin.top - frame.mwm_border_w - frame.border_w,
+ client.rect.width(), client.rect.height());
+ XMoveResizeWindow(blackbox->getXDisplay(), client.window,
+ 0, 0, client.rect.width(), client.rect.height());
- if (decorations.titlebar) {
- XSetWindowBorderWidth(display, frame.title, frame.border_w);
- XMoveResizeWindow(display, frame.title, -frame.border_w,
- -frame.border_w, frame.width, frame.title_h);
+ if (decorations & Decor_Titlebar) {
+ if (frame.title == None) createTitlebar();
+
+ XSetWindowBorderWidth(blackbox->getXDisplay(), frame.title,
+ frame.border_w);
+ XMoveResizeWindow(blackbox->getXDisplay(), frame.title, -frame.border_w,
+ -frame.border_w, frame.inside_w, frame.title_h);
positionButtons();
+ XMapSubwindows(blackbox->getXDisplay(), frame.title);
+ XMapWindow(blackbox->getXDisplay(), frame.title);
} else if (frame.title) {
- XUnmapWindow(display, frame.title);
- }
- if (decorations.handle) {
- XSetWindowBorderWidth(display, frame.handle, frame.border_w);
- XSetWindowBorderWidth(display, frame.left_grip, frame.border_w);
- XSetWindowBorderWidth(display, frame.right_grip, frame.border_w);
-
- XMoveResizeWindow(display, frame.handle, -frame.border_w,
- frame.y_handle - frame.border_w,
- frame.width, frame.handle_h);
- XMoveResizeWindow(display, frame.left_grip, -frame.border_w,
- -frame.border_w, frame.grip_w, frame.grip_h);
- XMoveResizeWindow(display, frame.right_grip,
- frame.width - frame.grip_w - frame.border_w,
- -frame.border_w, frame.grip_w, frame.grip_h);
- XMapSubwindows(display, frame.handle);
+ destroyTitlebar();
+ }
+ if (decorations & Decor_Handle) {
+ if (frame.handle == None) createHandle();
+ XSetWindowBorderWidth(blackbox->getXDisplay(), frame.handle,
+ frame.border_w);
+ XSetWindowBorderWidth(blackbox->getXDisplay(), frame.left_grip,
+ frame.border_w);
+ XSetWindowBorderWidth(blackbox->getXDisplay(), frame.right_grip,
+ frame.border_w);
+
+ XMoveResizeWindow(blackbox->getXDisplay(), frame.handle,
+ -frame.border_w,
+ frame.rect.height() - frame.margin.bottom +
+ frame.mwm_border_w - frame.border_w,
+ frame.inside_w, frame.handle_h);
+ XMoveResizeWindow(blackbox->getXDisplay(), frame.left_grip,
+ -frame.border_w, -frame.border_w,
+ frame.grip_w, frame.handle_h);
+ XMoveResizeWindow(blackbox->getXDisplay(), frame.right_grip,
+ frame.inside_w - frame.grip_w - frame.border_w,
+ -frame.border_w, frame.grip_w, frame.handle_h);
+ XMapSubwindows(blackbox->getXDisplay(), frame.handle);
+ XMapWindow(blackbox->getXDisplay(), frame.handle);
} else if (frame.handle) {
- XUnmapWindow(display, frame.handle);
+ destroyHandle();
}
}
-void OpenboxWindow::getWMName(void) {
- if (client.title) {
- delete [] client.title;
- client.title = (char *) 0;
- }
-
+void BlackboxWindow::getWMName(void) {
XTextProperty text_prop;
- char **list;
- int num;
-
- if (XGetWMName(display, client.window, &text_prop)) {
- if (text_prop.value && text_prop.nitems > 0) {
- if (text_prop.encoding != XA_STRING) {
- text_prop.nitems = strlen((char *) text_prop.value);
-
- if ((XmbTextPropertyToTextList(display, &text_prop,
- &list, &num) == Success) &&
- (num > 0) && *list) {
- client.title = bstrdup(*list);
- XFreeStringList(list);
- } else {
- client.title = bstrdup((char *) text_prop.value);
- }
- } else {
- client.title = bstrdup((char *) text_prop.value);
- }
- XFree((char *) text_prop.value);
- } else {
- client.title = bstrdup(i18n(WindowSet, WindowUnnamed,
- "Unnamed"));
- }
- } else {
- client.title = bstrdup(i18n(WindowSet, WindowUnnamed,
- "Unnamed"));
- }
- client.title_len = strlen(client.title);
- if (i18n.multibyte()) {
- XRectangle ink, logical;
- XmbTextExtents(screen->getWindowStyle()->fontset,
- client.title, client.title_len, &ink, &logical);
- client.title_text_w = logical.width;
+ if (XGetWMName(blackbox->getXDisplay(), client.window, &text_prop)) {
+ client.title = textPropertyToString(blackbox->getXDisplay(), text_prop);
+ if (client.title.empty())
+ client.title = i18n(WindowSet, WindowUnnamed, "Unnamed");
+ XFree((char *) text_prop.value);
} else {
- client.title_len = strlen(client.title);
- client.title_text_w = XTextWidth(screen->getWindowStyle()->font,
- client.title, client.title_len);
+ client.title = i18n(WindowSet, WindowUnnamed, "Unnamed");
}
-
- client.title_text_w += (frame.bevel_w * 4);
}
-void OpenboxWindow::getWMIconName(void) {
- if (client.icon_title) {
- delete [] client.icon_title;
- client.icon_title = (char *) 0;
- }
-
+void BlackboxWindow::getWMIconName(void) {
XTextProperty text_prop;
- char **list;
- int num;
-
- if (XGetWMIconName(display, client.window, &text_prop)) {
- if (text_prop.value && text_prop.nitems > 0) {
- if (text_prop.encoding != XA_STRING) {
- text_prop.nitems = strlen((char *) text_prop.value);
-
- if ((XmbTextPropertyToTextList(display, &text_prop,
- &list, &num) == Success) &&
- (num > 0) && *list) {
- client.icon_title = bstrdup(*list);
- XFreeStringList(list);
- } else {
- client.icon_title = bstrdup((char *) text_prop.value);
- }
- } else {
- client.icon_title = bstrdup((char *) text_prop.value);
- }
- XFree((char *) text_prop.value);
- } else {
- client.icon_title = bstrdup(client.title);
- }
+
+ if (XGetWMIconName(blackbox->getXDisplay(), client.window, &text_prop)) {
+ client.icon_title =
+ textPropertyToString(blackbox->getXDisplay(), text_prop);
+ if (client.icon_title.empty())
+ client.icon_title = client.title;
+ XFree((char *) text_prop.value);
} else {
- client.icon_title = bstrdup(client.title);
+ client.icon_title = client.title;
}
}
* If the WM_TAKE_FOCUS protocol is supported, save a value that indicates
* this.
*/
-void OpenboxWindow::getWMProtocols(void) {
+void BlackboxWindow::getWMProtocols(void) {
Atom *proto;
int num_return = 0;
- if (XGetWMProtocols(display, client.window, &proto, &num_return)) {
+ if (XGetWMProtocols(blackbox->getXDisplay(), client.window,
+ &proto, &num_return)) {
for (int i = 0; i < num_return; ++i) {
- if (proto[i] == openbox.getWMDeleteAtom())
- functions.close = decorations.close = True;
- else if (proto[i] == openbox.getWMTakeFocusAtom())
+ if (proto[i] == blackbox->getWMDeleteAtom()) {
+ decorations |= Decor_Close;
+ functions |= Func_Close;
+ } else if (proto[i] == blackbox->getWMTakeFocusAtom())
flags.send_focus_message = True;
- else if (proto[i] == openbox.getOpenboxStructureMessagesAtom())
- screen->addNetizen(new Netizen(*screen, client.window));
+ else if (proto[i] == blackbox->getBlackboxStructureMessagesAtom())
+ screen->addNetizen(new Netizen(screen, client.window));
}
XFree(proto);
* Gets the value of the WM_HINTS property.
* If the property is not set, then use a set of default values.
*/
-void OpenboxWindow::getWMHints(void) {
- XWMHints *wmhint = XGetWMHints(display, client.window);
+void BlackboxWindow::getWMHints(void) {
+ focus_mode = F_Passive;
+ client.initial_state = NormalState;
+
+ // remove from current window group
+ if (client.window_group) {
+ BWindowGroup *group = blackbox->searchGroup(client.window_group);
+ if (group) group->removeWindow(this);
+ }
+ client.window_group = None;
+
+ XWMHints *wmhint = XGetWMHints(blackbox->getXDisplay(), client.window);
if (! wmhint) {
- flags.visible = True;
- flags.iconic = False;
- focus_mode = F_Passive;
- client.window_group = None;
- client.initial_state = NormalState;
return;
}
- client.wm_hint_flags = wmhint->flags;
+
if (wmhint->flags & InputHint) {
if (wmhint->input == True) {
if (flags.send_focus_message)
focus_mode = F_LocallyActive;
- else
- focus_mode = F_Passive;
} else {
if (flags.send_focus_message)
focus_mode = F_GloballyActive;
else
focus_mode = F_NoInput;
}
- } else {
- focus_mode = F_Passive;
}
if (wmhint->flags & StateHint)
client.initial_state = wmhint->initial_state;
- else
- client.initial_state = NormalState;
if (wmhint->flags & WindowGroupHint) {
- if (! client.window_group) {
- client.window_group = wmhint->window_group;
- openbox.saveGroupSearch(client.window_group, this);
- }
- } else {
- client.window_group = None;
+ client.window_group = wmhint->window_group;
+
+ // add window to the appropriate group
+ BWindowGroup *group = blackbox->searchGroup(client.window_group);
+ if (! group) // no group found, create it!
+ group = new BWindowGroup(blackbox, client.window_group);
+ group->addWindow(this);
}
+
+ client.wm_hint_flags = wmhint->flags;
XFree(wmhint);
}
* Gets the value of the WM_NORMAL_HINTS property.
* If the property is not set, then use a set of default values.
*/
-void OpenboxWindow::getWMNormalHints(void) {
+void BlackboxWindow::getWMNormalHints(void) {
long icccm_mask;
XSizeHints sizehint;
+ const Rect& screen_area = screen->availableArea();
+
client.min_width = client.min_height =
- client.base_width = client.base_height =
client.width_inc = client.height_inc = 1;
- client.max_width = screen->size().w();
- client.max_height = screen->size().h();
+ client.base_width = client.base_height = 0;
+ client.max_width = screen_area.width();
+ client.max_height = screen_area.height();
client.min_aspect_x = client.min_aspect_y =
client.max_aspect_x = client.max_aspect_y = 1;
client.win_gravity = NorthWestGravity;
- if (! XGetWMNormalHints(display, client.window, &sizehint, &icccm_mask))
+ if (! XGetWMNormalHints(blackbox->getXDisplay(), client.window,
+ &sizehint, &icccm_mask))
return;
client.normal_hint_flags = sizehint.flags;
* Gets the MWM hints for the class' contained window.
* This is used while initializing the window to its first state, and not
* thereafter.
- * Returns: true if the MWM hints are successfully retreived and applied; false
- * if they are not.
+ * Returns: true if the MWM hints are successfully retreived and applied;
+ * false if they are not.
*/
-void OpenboxWindow::getMWMHints(void) {
+void BlackboxWindow::getMWMHints(void) {
int format;
Atom atom_return;
unsigned long num, len;
+ MwmHints *mwm_hint = 0;
- int ret = XGetWindowProperty(display, client.window,
- openbox.getMotifWMHintsAtom(), 0,
+ int ret = XGetWindowProperty(blackbox->getXDisplay(), client.window,
+ blackbox->getMotifWMHintsAtom(), 0,
PropMwmHintsElements, False,
- openbox.getMotifWMHintsAtom(), &atom_return,
+ blackbox->getMotifWMHintsAtom(), &atom_return,
&format, &num, &len,
- (unsigned char **) &client.mwm_hint);
+ (unsigned char **) &mwm_hint);
- if (ret != Success || !client.mwm_hint || num != PropMwmHintsElements)
+ if (ret != Success || ! mwm_hint || num != PropMwmHintsElements)
return;
- if (client.mwm_hint->flags & MwmHintsDecorations) {
- if (client.mwm_hint->decorations & MwmDecorAll) {
- decorations.titlebar = decorations.handle = decorations.border =
- decorations.iconify = decorations.maximize =
- decorations.close = decorations.menu = True;
+ if (mwm_hint->flags & MwmHintsDecorations) {
+ if (mwm_hint->decorations & MwmDecorAll) {
+ decorations = Decor_Titlebar | Decor_Handle | Decor_Border |
+ Decor_Iconify | Decor_Maximize | Decor_Close;
} else {
- decorations.titlebar = decorations.handle = decorations.border =
- decorations.iconify = decorations.maximize =
- decorations.close = decorations.menu = False;
-
- if (client.mwm_hint->decorations & MwmDecorBorder)
- decorations.border = True;
- if (client.mwm_hint->decorations & MwmDecorHandle)
- decorations.handle = True;
- if (client.mwm_hint->decorations & MwmDecorTitle)
- decorations.titlebar = True;
- if (client.mwm_hint->decorations & MwmDecorMenu)
- decorations.menu = True;
- if (client.mwm_hint->decorations & MwmDecorIconify)
- decorations.iconify = True;
- if (client.mwm_hint->decorations & MwmDecorMaximize)
- decorations.maximize = True;
+ decorations = 0;
+
+ if (mwm_hint->decorations & MwmDecorBorder)
+ decorations |= Decor_Border;
+ if (mwm_hint->decorations & MwmDecorHandle)
+ decorations |= Decor_Handle;
+ if (mwm_hint->decorations & MwmDecorTitle)
+ decorations |= Decor_Titlebar;
+ if (mwm_hint->decorations & MwmDecorIconify)
+ decorations |= Decor_Iconify;
+ if (mwm_hint->decorations & MwmDecorMaximize)
+ decorations |= Decor_Maximize;
}
}
- if (client.mwm_hint->flags & MwmHintsFunctions) {
- if (client.mwm_hint->functions & MwmFuncAll) {
- functions.resize = functions.move = functions.iconify =
- functions.maximize = functions.close = True;
+ if (mwm_hint->flags & MwmHintsFunctions) {
+ if (mwm_hint->functions & MwmFuncAll) {
+ functions = Func_Resize | Func_Move | Func_Iconify | Func_Maximize |
+ Func_Close;
} else {
- functions.resize = functions.move = functions.iconify =
- functions.maximize = functions.close = False;
-
- if (client.mwm_hint->functions & MwmFuncResize)
- functions.resize = True;
- if (client.mwm_hint->functions & MwmFuncMove)
- functions.move = True;
- if (client.mwm_hint->functions & MwmFuncIconify)
- functions.iconify = True;
- if (client.mwm_hint->functions & MwmFuncMaximize)
- functions.maximize = True;
- if (client.mwm_hint->functions & MwmFuncClose)
- functions.close = True;
+ functions = 0;
+
+ if (mwm_hint->functions & MwmFuncResize)
+ functions |= Func_Resize;
+ if (mwm_hint->functions & MwmFuncMove)
+ functions |= Func_Move;
+ if (mwm_hint->functions & MwmFuncIconify)
+ functions |= Func_Iconify;
+ if (mwm_hint->functions & MwmFuncMaximize)
+ functions |= Func_Maximize;
+ if (mwm_hint->functions & MwmFuncClose)
+ functions |= Func_Close;
}
}
+ XFree(mwm_hint);
}
/*
- * Gets the openbox hints from the class' contained window.
+ * Gets the blackbox hints from the class' contained window.
* This is used while initializing the window to its first state, and not
* thereafter.
* Returns: true if the hints are successfully retreived and applied; false if
* they are not.
*/
-void OpenboxWindow::getOpenboxHints(void) {
+bool BlackboxWindow::getBlackboxHints(void) {
int format;
Atom atom_return;
unsigned long num, len;
+ BlackboxHints *blackbox_hint = 0;
- int ret = XGetWindowProperty(display, client.window,
- openbox.getOpenboxHintsAtom(), 0,
- PropOpenboxHintsElements, False,
- openbox.getOpenboxHintsAtom(), &atom_return,
+ int ret = XGetWindowProperty(blackbox->getXDisplay(), client.window,
+ blackbox->getBlackboxHintsAtom(), 0,
+ PropBlackboxHintsElements, False,
+ blackbox->getBlackboxHintsAtom(), &atom_return,
&format, &num, &len,
- (unsigned char **) &client.openbox_hint);
- if (ret != Success || !client.openbox_hint ||
- num != PropOpenboxHintsElements)
- return;
+ (unsigned char **) &blackbox_hint);
+ if (ret != Success || ! blackbox_hint || num != PropBlackboxHintsElements)
+ return False;
- if (client.openbox_hint->flags & AttribShaded)
- flags.shaded = (client.openbox_hint->attrib & AttribShaded);
+ if (blackbox_hint->flags & AttribShaded)
+ flags.shaded = (blackbox_hint->attrib & AttribShaded);
- if ((client.openbox_hint->flags & AttribMaxHoriz) &&
- (client.openbox_hint->flags & AttribMaxVert))
- flags.maximized = (client.openbox_hint->attrib &
+ if ((blackbox_hint->flags & AttribMaxHoriz) &&
+ (blackbox_hint->flags & AttribMaxVert))
+ flags.maximized = (blackbox_hint->attrib &
(AttribMaxHoriz | AttribMaxVert)) ? 1 : 0;
- else if (client.openbox_hint->flags & AttribMaxVert)
- flags.maximized = (client.openbox_hint->attrib & AttribMaxVert) ? 2 : 0;
- else if (client.openbox_hint->flags & AttribMaxHoriz)
- flags.maximized = (client.openbox_hint->attrib & AttribMaxHoriz) ? 3 : 0;
+ else if (blackbox_hint->flags & AttribMaxVert)
+ flags.maximized = (blackbox_hint->attrib & AttribMaxVert) ? 2 : 0;
+ else if (blackbox_hint->flags & AttribMaxHoriz)
+ flags.maximized = (blackbox_hint->attrib & AttribMaxHoriz) ? 3 : 0;
- if (client.openbox_hint->flags & AttribOmnipresent)
- flags.stuck = (client.openbox_hint->attrib & AttribOmnipresent);
+ if (blackbox_hint->flags & AttribOmnipresent)
+ flags.stuck = (blackbox_hint->attrib & AttribOmnipresent);
- if (client.openbox_hint->flags & AttribWorkspace)
- workspace_number = client.openbox_hint->workspace;
+ if (blackbox_hint->flags & AttribWorkspace)
+ blackbox_attrib.workspace = blackbox_hint->workspace;
- // if (client.openbox_hint->flags & AttribStack)
- // don't yet have always on top/bottom for openbox yet... working
+ // if (blackbox_hint->flags & AttribStack)
+ // don't yet have always on top/bottom for blackbox yet... working
// on that
- if (client.openbox_hint->flags & AttribDecoration) {
- switch (client.openbox_hint->decoration) {
+ if (blackbox_hint->flags & AttribDecoration) {
+ switch (blackbox_hint->decoration) {
case DecorNone:
- decorations.titlebar = decorations.border = decorations.handle =
- decorations.iconify = decorations.maximize =
- decorations.menu = False;
- functions.resize = functions.move = functions.iconify =
- functions.maximize = False;
+ // clear all decorations except close
+ decorations &= Decor_Close;
+ // clear all functions except close
+ functions &= Func_Close;
break;
case DecorTiny:
- decorations.titlebar = decorations.iconify = decorations.menu =
- functions.move = functions.iconify = True;
- decorations.border = decorations.handle = decorations.maximize =
- functions.resize = functions.maximize = False;
+ decorations |= Decor_Titlebar | Decor_Iconify;
+ decorations &= ~(Decor_Border | Decor_Handle | Decor_Maximize);
+ functions |= Func_Move | Func_Iconify;
+ functions &= ~(Func_Resize | Func_Maximize);
break;
case DecorTool:
- decorations.titlebar = decorations.menu = functions.move = True;
- decorations.iconify = decorations.border = decorations.handle =
- decorations.maximize = functions.resize = functions.maximize =
- functions.iconify = False;
+ decorations |= Decor_Titlebar;
+ decorations &= ~(Decor_Iconify | Decor_Border | Decor_Handle);
+ functions |= Func_Move;
+ functions &= ~(Func_Resize | Func_Maximize | Func_Iconify);
break;
case DecorNormal:
default:
- decorations.titlebar = decorations.border = decorations.handle =
- decorations.iconify = decorations.maximize =
- decorations.menu = True;
- functions.resize = functions.move = functions.iconify =
- functions.maximize = True;
+ decorations |= Decor_Titlebar | Decor_Border | Decor_Handle |
+ Decor_Iconify | Decor_Maximize;
+ functions |= Func_Resize | Func_Move | Func_Iconify | Func_Maximize;
break;
}
reconfigure();
}
+ XFree(blackbox_hint);
+ return True;
+}
+
+
+void BlackboxWindow::getTransientInfo(void) {
+ if (client.transient_for &&
+ client.transient_for != (BlackboxWindow *) ~0ul) {
+ // the transient for hint was removed, so we need to tell our
+ // previous transient_for that we are going away
+ client.transient_for->client.transientList.remove(this);
+ }
+
+ // we have no transient_for until we find a new one
+ client.transient_for = 0;
+
+ Window trans_for;
+ if (!XGetTransientForHint(blackbox->getXDisplay(), client.window,
+ &trans_for)) {
+ // transient_for hint not set
+ return;
+ }
+
+ if (trans_for == client.window) {
+ // wierd client... treat this window as a normal window
+ return;
+ }
+
+ if (trans_for == None || trans_for == screen->getRootWindow()) {
+ // this is an undocumented interpretation of the ICCCM. a transient
+ // associated with None/Root/itself is assumed to be a modal root
+ // transient. we don't support the concept of a global transient,
+ // so we just associate this transient with nothing, and perhaps
+ // we will add support later for global modality.
+ client.transient_for = (BlackboxWindow *) ~0ul;
+ flags.modal = True;
+ return;
+ }
+
+ client.transient_for = blackbox->searchWindow(trans_for);
+ if (! client.transient_for &&
+ client.window_group && trans_for == client.window_group) {
+ // no direct transient_for, perhaps this is a group transient?
+ BWindowGroup *group = blackbox->searchGroup(client.window_group);
+ if (group) client.transient_for = group->find(screen);
+ }
+
+ if (! client.transient_for || client.transient_for == this) {
+ // no transient_for found, or we have a wierd client that wants to be
+ // a transient for itself, so we treat this window as a normal window
+ client.transient_for = (BlackboxWindow*) 0;
+ return;
+ }
+
+ // register ourselves with our new transient_for
+ client.transient_for->client.transientList.push_back(this);
+ flags.stuck = client.transient_for->flags.stuck;
+}
+
+
+BlackboxWindow *BlackboxWindow::getTransientFor(void) const {
+ if (client.transient_for &&
+ client.transient_for != (BlackboxWindow*) ~0ul)
+ return client.transient_for;
+ return 0;
}
-void OpenboxWindow::configure(int dx, int dy,
- unsigned int dw, unsigned int dh) {
- Bool send_event = (frame.x != dx || frame.y != dy);
+void BlackboxWindow::configure(int dx, int dy,
+ unsigned int dw, unsigned int dh) {
+ bool send_event = (frame.rect.x() != dx || frame.rect.y() != dy);
- if ((dw != frame.width) || (dh != frame.height)) {
- if ((((signed) frame.width) + dx) < 0) dx = 0;
- if ((((signed) frame.height) + dy) < 0) dy = 0;
+ if ((dw != frame.rect.width()) || (dh != frame.rect.height())) {
+ frame.rect.setRect(dx, dy, dw, dh);
+ frame.inside_w = frame.rect.width() - (frame.border_w * 2);
+ frame.inside_h = frame.rect.height() - (frame.border_w * 2);
- frame.x = dx;
- frame.y = dy;
- frame.width = dw;
- frame.height = dh;
+ if (frame.rect.right() <= 0 || frame.rect.bottom() <= 0)
+ frame.rect.setPos(0, 0);
- downsize();
+ client.rect.setCoords(frame.rect.left() + frame.margin.left,
+ frame.rect.top() + frame.margin.top,
+ frame.rect.right() - frame.margin.right,
+ frame.rect.bottom() - frame.margin.bottom);
#ifdef SHAPE
- if (openbox.hasShapeExtensions() && flags.shaped) {
- XShapeCombineShape(display, frame.window, ShapeBounding,
- frame.mwm_border_w, frame.y_border +
- frame.mwm_border_w, client.window,
- ShapeBounding, ShapeSet);
-
- int num = 1;
- XRectangle xrect[2];
- xrect[0].x = xrect[0].y = 0;
- xrect[0].width = frame.width;
- xrect[0].height = frame.y_border;
-
- if (decorations.handle) {
- xrect[1].x = 0;
- xrect[1].y = frame.y_handle;
- xrect[1].width = frame.width;
- xrect[1].height = frame.handle_h + frame.border_w;
- num++;
- }
-
- XShapeCombineRectangles(display, frame.window, ShapeBounding, 0, 0,
- xrect, num, ShapeUnion, Unsorted);
+ if (blackbox->hasShapeExtensions() && flags.shaped) {
+ configureShape();
}
#endif // SHAPE
- XMoveWindow(display, frame.window, frame.x, frame.y);
-
- setFocusFlag(flags.focused);
positionWindows();
decorate();
+ setFocusFlag(flags.focused);
+ redrawAllButtons();
} else {
- frame.x = dx;
- frame.y = dy;
+ frame.rect.setPos(dx, dy);
- XMoveWindow(display, frame.window, frame.x, frame.y);
+ XMoveWindow(blackbox->getXDisplay(), frame.window,
+ frame.rect.x(), frame.rect.y());
if (! flags.moving) send_event = True;
}
if (send_event && ! flags.moving) {
- client.x = dx + frame.mwm_border_w + frame.border_w;
- client.y = dy + frame.y_border + frame.mwm_border_w +
- frame.border_w;
+ client.rect.setPos(frame.rect.left() + frame.margin.left,
+ frame.rect.top() + frame.margin.top);
XEvent event;
event.type = ConfigureNotify;
- event.xconfigure.display = display;
+ event.xconfigure.display = blackbox->getXDisplay();
event.xconfigure.event = client.window;
event.xconfigure.window = client.window;
- event.xconfigure.x = client.x;
- event.xconfigure.y = client.y;
- event.xconfigure.width = client.width;
- event.xconfigure.height = client.height;
+ event.xconfigure.x = client.rect.x();
+ event.xconfigure.y = client.rect.y();
+ event.xconfigure.width = client.rect.width();
+ event.xconfigure.height = client.rect.height();
event.xconfigure.border_width = client.old_bw;
event.xconfigure.above = frame.window;
event.xconfigure.override_redirect = False;
- XSendEvent(display, client.window, True, NoEventMask, &event);
+ XSendEvent(blackbox->getXDisplay(), client.window, True,
+ NoEventMask, &event);
screen->updateNetizenConfigNotify(&event);
}
}
-bool OpenboxWindow::setInputFocus(void) {
- if (((signed) (frame.x + frame.width)) < 0) {
- if (((signed) (frame.y + frame.y_border)) < 0)
- configure(frame.border_w, frame.border_w, frame.width, frame.height);
- else if (frame.y > (signed) screen->size().h())
- configure(frame.border_w, screen->size().h() - frame.height,
- frame.width, frame.height);
- else
- configure(frame.border_w, frame.y + frame.border_w,
- frame.width, frame.height);
- } else if (frame.x > (signed) screen->size().w()) {
- if (((signed) (frame.y + frame.y_border)) < 0)
- configure(screen->size().w() - frame.width, frame.border_w,
- frame.width, frame.height);
- else if (frame.y > (signed) screen->size().h())
- configure(screen->size().w() - frame.width,
- screen->size().h() - frame.height, frame.width, frame.height);
- else
- configure(screen->size().w() - frame.width,
- frame.y + frame.border_w, frame.width, frame.height);
- }
-
- openbox.grab();
- if (! validateClient()) return False;
-
- bool ret = false;
-
- if (client.transient && flags.modal) {
- ret = client.transient->setInputFocus();
- } else if (! flags.focused) {
- if (focus_mode == F_LocallyActive || focus_mode == F_Passive) {
- XSetInputFocus(display, client.window,
- RevertToPointerRoot, CurrentTime);
- openbox.focusWindow(this);
-
- if (flags.send_focus_message) {
- XEvent ce;
- ce.xclient.type = ClientMessage;
- ce.xclient.message_type = openbox.getWMProtocolsAtom();
- ce.xclient.display = display;
- ce.xclient.window = client.window;
- ce.xclient.format = 32;
- ce.xclient.data.l[0] = openbox.getWMTakeFocusAtom();
- ce.xclient.data.l[1] = openbox.getLastTime();
- ce.xclient.data.l[2] = 0l;
- ce.xclient.data.l[3] = 0l;
- ce.xclient.data.l[4] = 0l;
- XSendEvent(display, client.window, False, NoEventMask, &ce);
- }
+#ifdef SHAPE
+void BlackboxWindow::configureShape(void) {
+ XShapeCombineShape(blackbox->getXDisplay(), frame.window, ShapeBounding,
+ frame.margin.left - frame.border_w,
+ frame.margin.top - frame.border_w,
+ client.window, ShapeBounding, ShapeSet);
- if (screen->sloppyFocus() && screen->autoRaise())
- timer->start();
+ int num = 0;
+ XRectangle xrect[2];
- ret = true;
- }
+ if (decorations & Decor_Titlebar) {
+ xrect[0].x = xrect[0].y = -frame.border_w;
+ xrect[0].width = frame.rect.width();
+ xrect[0].height = frame.title_h + (frame.border_w * 2);
+ ++num;
}
- openbox.ungrab();
+ if (decorations & Decor_Handle) {
+ xrect[1].x = -frame.border_w;
+ xrect[1].y = frame.rect.height() - frame.margin.bottom +
+ frame.mwm_border_w - frame.border_w;
+ xrect[1].width = frame.rect.width();
+ xrect[1].height = frame.handle_h + (frame.border_w * 2);
+ ++num;
+ }
- return ret;
+ XShapeCombineRectangles(blackbox->getXDisplay(), frame.window,
+ ShapeBounding, 0, 0, xrect, num,
+ ShapeUnion, Unsorted);
}
+#endif // SHAPE
-void OpenboxWindow::iconify(void) {
- if (flags.iconic) return;
+bool BlackboxWindow::setInputFocus(void) {
+ if (flags.focused) return True;
- if (flags.moving)
- endMove();
+ if (! client.rect.intersects(screen->getRect())) {
+ // client is outside the screen, move it to the center
+ configure((screen->getWidth() - frame.rect.width()) / 2,
+ (screen->getHeight() - frame.rect.height()) / 2,
+ frame.rect.width(), frame.rect.height());
+ }
+
+ if (client.transientList.size() > 0) {
+ // transfer focus to any modal transients
+ BlackboxWindowList::iterator it, end = client.transientList.end();
+ for (it = client.transientList.begin(); it != end; ++it) {
+ if ((*it)->flags.modal) return (*it)->setInputFocus();
+ }
+ }
+
+ bool ret = True;
+ if (focus_mode == F_LocallyActive || focus_mode == F_Passive) {
+ XSetInputFocus(blackbox->getXDisplay(), client.window,
+ RevertToPointerRoot, CurrentTime);
+
+ blackbox->setFocusedWindow(this);
+ } else {
+ /* we could set the focus to none, since the window doesn't accept focus,
+ * but we shouldn't set focus to nothing since this would surely make
+ * someone angry
+ */
+ ret = False;
+ }
+
+ if (flags.send_focus_message) {
+ XEvent ce;
+ ce.xclient.type = ClientMessage;
+ ce.xclient.message_type = blackbox->getWMProtocolsAtom();
+ ce.xclient.display = blackbox->getXDisplay();
+ ce.xclient.window = client.window;
+ ce.xclient.format = 32;
+ ce.xclient.data.l[0] = blackbox->getWMTakeFocusAtom();
+ ce.xclient.data.l[1] = blackbox->getLastTime();
+ ce.xclient.data.l[2] = 0l;
+ ce.xclient.data.l[3] = 0l;
+ ce.xclient.data.l[4] = 0l;
+ XSendEvent(blackbox->getXDisplay(), client.window, False,
+ NoEventMask, &ce);
+ }
+
+ return ret;
+}
+
+
+void BlackboxWindow::iconify(void) {
+ if (flags.iconic) return;
if (windowmenu) windowmenu->hide();
setState(IconicState);
- XSelectInput(display, client.window, NoEventMask);
- XUnmapWindow(display, client.window);
- XSelectInput(display, client.window,
- PropertyChangeMask | StructureNotifyMask | FocusChangeMask);
-
- XUnmapWindow(display, frame.window);
+ /*
+ * we don't want this XUnmapWindow call to generate an UnmapNotify event, so
+ * we need to clear the event mask on client.window for a split second.
+ * HOWEVER, since X11 is asynchronous, the window could be destroyed in that
+ * split second, leaving us with a ghost window... so, we need to do this
+ * while the X server is grabbed
+ */
+ XGrabServer(blackbox->getXDisplay());
+ XSelectInput(blackbox->getXDisplay(), client.window, NoEventMask);
+ XUnmapWindow(blackbox->getXDisplay(), client.window);
+ XSelectInput(blackbox->getXDisplay(), client.window,
+ PropertyChangeMask | FocusChangeMask | StructureNotifyMask);
+ XUngrabServer(blackbox->getXDisplay());
+
+ XUnmapWindow(blackbox->getXDisplay(), frame.window);
flags.visible = False;
flags.iconic = True;
- screen->getWorkspace(workspace_number)->removeWindow(this);
+ screen->getWorkspace(blackbox_attrib.workspace)->removeWindow(this);
- if (flags.transient && client.transient_for &&
- !client.transient_for->flags.iconic) {
- client.transient_for->iconify();
+ if (isTransient()) {
+ if (client.transient_for != (BlackboxWindow *) ~0ul &&
+ ! client.transient_for->flags.iconic) {
+ // iconify our transient_for
+ client.transient_for->iconify();
+ }
}
+
screen->addIcon(this);
- if (client.transient && !client.transient->flags.iconic) {
- client.transient->iconify();
+ if (client.transientList.size() > 0) {
+ // iconify all transients
+ BlackboxWindowList::iterator it, end = client.transientList.end();
+ for (it = client.transientList.begin(); it != end; ++it) {
+ if (! (*it)->flags.iconic) (*it)->iconify();
+ }
}
}
-void OpenboxWindow::deiconify(bool reassoc, bool raise, bool initial) {
- if (flags.iconic || reassoc)
- screen->reassociateWindow(this, -1, False);
- else if (workspace_number != screen->getCurrentWorkspace()->getWorkspaceID())
- return;
-
+void BlackboxWindow::show(void) {
setState(NormalState);
- XSelectInput(display, client.window, NoEventMask);
- XMapWindow(display, client.window);
- XSelectInput(display, client.window,
- PropertyChangeMask | StructureNotifyMask | FocusChangeMask);
+ XMapWindow(blackbox->getXDisplay(), client.window);
+ XMapSubwindows(blackbox->getXDisplay(), frame.window);
+ XMapWindow(blackbox->getXDisplay(), frame.window);
- XMapSubwindows(display, frame.window);
- XMapWindow(display, frame.window);
+ flags.visible = True;
+ flags.iconic = False;
+}
- // if we're using the click to place placement type, then immediately
- // after the window is mapped, we need to start interactively moving it
- if (initial && place_window &&
- screen->placementPolicy() == BScreen::ClickMousePlacement) {
- int x, y, rx, ry;
- Window c, r;
- unsigned int m;
- XQueryPointer(openbox.getXDisplay(), screen->getRootWindow(),
- &r, &c, &rx, &ry, &x, &y, &m);
- startMove(rx, ry);
- }
- if (flags.iconic && screen->focusNew()) setInputFocus();
+void BlackboxWindow::deiconify(bool reassoc, bool raise) {
+ if (flags.iconic || reassoc)
+ screen->reassociateWindow(this, BSENTINEL, False);
+ else if (blackbox_attrib.workspace != screen->getCurrentWorkspace()->getID())
+ return;
- flags.visible = True;
- flags.iconic = False;
+ show();
- if (reassoc && client.transient) client.transient->deiconify(True, False);
+ // reassociate and deiconify all transients
+ if (reassoc && client.transientList.size() > 0) {
+ BlackboxWindowList::iterator it, end = client.transientList.end();
+ for (it = client.transientList.begin(); it != end; ++it) {
+ (*it)->deiconify(True, False);
+ }
+ }
if (raise)
- screen->getWorkspace(workspace_number)->raiseWindow(this);
+ screen->getWorkspace(blackbox_attrib.workspace)->raiseWindow(this);
}
-void OpenboxWindow::close(void) {
+void BlackboxWindow::close(void) {
XEvent ce;
ce.xclient.type = ClientMessage;
- ce.xclient.message_type = openbox.getWMProtocolsAtom();
- ce.xclient.display = display;
+ ce.xclient.message_type = blackbox->getWMProtocolsAtom();
+ ce.xclient.display = blackbox->getXDisplay();
ce.xclient.window = client.window;
ce.xclient.format = 32;
- ce.xclient.data.l[0] = openbox.getWMDeleteAtom();
+ ce.xclient.data.l[0] = blackbox->getWMDeleteAtom();
ce.xclient.data.l[1] = CurrentTime;
ce.xclient.data.l[2] = 0l;
ce.xclient.data.l[3] = 0l;
ce.xclient.data.l[4] = 0l;
- XSendEvent(display, client.window, False, NoEventMask, &ce);
+ XSendEvent(blackbox->getXDisplay(), client.window, False, NoEventMask, &ce);
}
-void OpenboxWindow::withdraw(void) {
- if (flags.moving)
- endMove();
+void BlackboxWindow::withdraw(void) {
+ setState(current_state);
flags.visible = False;
flags.iconic = False;
- XUnmapWindow(display, frame.window);
+ XUnmapWindow(blackbox->getXDisplay(), frame.window);
- XSelectInput(display, client.window, NoEventMask);
- XUnmapWindow(display, client.window);
- XSelectInput(display, client.window,
- PropertyChangeMask | StructureNotifyMask | FocusChangeMask);
+ XGrabServer(blackbox->getXDisplay());
+ XSelectInput(blackbox->getXDisplay(), client.window, NoEventMask);
+ XUnmapWindow(blackbox->getXDisplay(), client.window);
+ XSelectInput(blackbox->getXDisplay(), client.window,
+ PropertyChangeMask | FocusChangeMask | StructureNotifyMask);
+ XUngrabServer(blackbox->getXDisplay());
if (windowmenu) windowmenu->hide();
}
-void OpenboxWindow::maximize(unsigned int button) {
- if (flags.moving)
- endMove();
-
+void BlackboxWindow::maximize(unsigned int button) {
// handle case where menu is open then the max button is used instead
if (windowmenu && windowmenu->isVisible()) windowmenu->hide();
if (flags.maximized) {
flags.maximized = 0;
- openbox_attrib.flags &= ! (AttribMaxHoriz | AttribMaxVert);
- openbox_attrib.attrib &= ! (AttribMaxHoriz | AttribMaxVert);
+ blackbox_attrib.flags &= ! (AttribMaxHoriz | AttribMaxVert);
+ blackbox_attrib.attrib &= ! (AttribMaxHoriz | AttribMaxVert);
// when a resize is begun, maximize(0) is called to clear any maximization
// flags currently set. Otherwise it still thinks it is maximized.
// so we do not need to call configure() because resizing will handle it
if (!flags.resizing)
- configure(openbox_attrib.premax_x, openbox_attrib.premax_y,
- openbox_attrib.premax_w, openbox_attrib.premax_h);
+ configure(blackbox_attrib.premax_x, blackbox_attrib.premax_y,
+ blackbox_attrib.premax_w, blackbox_attrib.premax_h);
- openbox_attrib.premax_x = openbox_attrib.premax_y = 0;
- openbox_attrib.premax_w = openbox_attrib.premax_h = 0;
+ blackbox_attrib.premax_x = blackbox_attrib.premax_y = 0;
+ blackbox_attrib.premax_w = blackbox_attrib.premax_h = 0;
- redrawMaximizeButton(flags.maximized);
+ redrawAllButtons();
setState(current_state);
return;
}
- openbox_attrib.premax_x = frame.x;
- openbox_attrib.premax_y = frame.y;
- openbox_attrib.premax_w = frame.width;
- openbox_attrib.premax_h = frame.height;
-
- Rect space = screen->availableArea();
- unsigned int dw = space.w(),
- dh = space.h();
- dw -= frame.border_w * 2;
- dw -= frame.mwm_border_w * 2;
- dw -= client.base_width;
+ blackbox_attrib.premax_x = frame.rect.x();
+ blackbox_attrib.premax_y = frame.rect.y();
+ blackbox_attrib.premax_w = frame.rect.width();
+ blackbox_attrib.premax_h = frame.rect.height();
- dh -= frame.border_w * 2;
- dh -= frame.mwm_border_w * 2;
- dh -= ((frame.handle_h + frame.border_w) * decorations.handle);
- dh -= client.base_height;
- dh -= frame.y_border;
-
- if (dw < client.min_width) dw = client.min_width;
- if (dh < client.min_height) dh = client.min_height;
- if (dw > client.max_width) dw = client.max_width;
- if (dh > client.max_height) dh = client.max_height;
-
- dw -= (dw % client.width_inc);
- dw += client.base_width;
- dw += frame.mwm_border_w * 2;
-
- dh -= (dh % client.height_inc);
- dh += client.base_height;
- dh += frame.y_border;
- dh += ((frame.handle_h + frame.border_w) * decorations.handle);
- dh += frame.mwm_border_w * 2;
-
- int dx = space.x() + ((space.w() - dw) / 2) - frame.border_w,
- dy = space.y() + ((space.h() - dh) / 2) - frame.border_w;
+ const Rect &screen_area = screen->availableArea();
+ frame.changing = screen_area;
+ constrain(TopLeft);
switch(button) {
case 1:
- openbox_attrib.flags |= AttribMaxHoriz | AttribMaxVert;
- openbox_attrib.attrib |= AttribMaxHoriz | AttribMaxVert;
+ blackbox_attrib.flags |= AttribMaxHoriz | AttribMaxVert;
+ blackbox_attrib.attrib |= AttribMaxHoriz | AttribMaxVert;
break;
case 2:
- openbox_attrib.flags |= AttribMaxVert;
- openbox_attrib.attrib |= AttribMaxVert;
+ blackbox_attrib.flags |= AttribMaxVert;
+ blackbox_attrib.attrib |= AttribMaxVert;
- dw = frame.width;
- dx = frame.x;
+ frame.changing.setX(frame.rect.x());
+ frame.changing.setWidth(frame.rect.width());
break;
case 3:
- openbox_attrib.flags |= AttribMaxHoriz;
- openbox_attrib.attrib |= AttribMaxHoriz;
+ blackbox_attrib.flags |= AttribMaxHoriz;
+ blackbox_attrib.attrib |= AttribMaxHoriz;
- dh = frame.height;
- dy = frame.y;
+ frame.changing.setY(frame.rect.y());
+ frame.changing.setHeight(frame.rect.height());
break;
}
if (flags.shaded) {
- openbox_attrib.flags ^= AttribShaded;
- openbox_attrib.attrib ^= AttribShaded;
+ blackbox_attrib.flags ^= AttribShaded;
+ blackbox_attrib.attrib ^= AttribShaded;
flags.shaded = False;
}
flags.maximized = button;
- configure(dx, dy, dw, dh);
- screen->getWorkspace(workspace_number)->raiseWindow(this);
- redrawMaximizeButton(flags.maximized);
+ configure(frame.changing.x(), frame.changing.y(),
+ frame.changing.width(), frame.changing.height());
+ screen->getWorkspace(blackbox_attrib.workspace)->raiseWindow(this);
+ redrawAllButtons();
setState(current_state);
}
-void OpenboxWindow::setWorkspace(int n) {
- ASSERT(n < screen->getWorkspaceCount());
- workspace_number = n;
+// re-maximizes the window to take into account availableArea changes
+void BlackboxWindow::remaximize(void) {
+ // save the original dimensions because maximize will wipe them out
+ int premax_x = blackbox_attrib.premax_x,
+ premax_y = blackbox_attrib.premax_y,
+ premax_w = blackbox_attrib.premax_w,
+ premax_h = blackbox_attrib.premax_h;
- openbox_attrib.flags |= AttribWorkspace;
- openbox_attrib.workspace = workspace_number;
+ unsigned int button = flags.maximized;
+ flags.maximized = 0; // trick maximize() into working
+ maximize(button);
+
+ // restore saved values
+ blackbox_attrib.premax_x = premax_x;
+ blackbox_attrib.premax_y = premax_y;
+ blackbox_attrib.premax_w = premax_w;
+ blackbox_attrib.premax_h = premax_h;
}
-void OpenboxWindow::shade(void) {
- if (!decorations.titlebar)
+void BlackboxWindow::setWorkspace(unsigned int n) {
+ blackbox_attrib.flags |= AttribWorkspace;
+ blackbox_attrib.workspace = n;
+}
+
+
+void BlackboxWindow::shade(void) {
+ if (! (decorations & Decor_Titlebar))
return;
if (flags.shaded) {
- XResizeWindow(display, frame.window, frame.width, frame.height);
+ XResizeWindow(blackbox->getXDisplay(), frame.window,
+ frame.inside_w, frame.inside_h);
flags.shaded = False;
- openbox_attrib.flags ^= AttribShaded;
- openbox_attrib.attrib ^= AttribShaded;
+ blackbox_attrib.flags ^= AttribShaded;
+ blackbox_attrib.attrib ^= AttribShaded;
setState(NormalState);
+
+ // set the frame rect to the normal size
+ frame.rect.setHeight(client.rect.height() + frame.margin.top +
+ frame.margin.bottom);
} else {
- XResizeWindow(display, frame.window, frame.width, frame.title_h);
+ XResizeWindow(blackbox->getXDisplay(), frame.window,
+ frame.inside_w, frame.title_h);
flags.shaded = True;
- openbox_attrib.flags |= AttribShaded;
- openbox_attrib.attrib |= AttribShaded;
+ blackbox_attrib.flags |= AttribShaded;
+ blackbox_attrib.attrib |= AttribShaded;
setState(IconicState);
+
+ // set the frame rect to the shaded size
+ frame.rect.setHeight(frame.title_h + (frame.border_w * 2));
}
}
-void OpenboxWindow::stick(void) {
+void BlackboxWindow::stick(void) {
if (flags.stuck) {
- openbox_attrib.flags ^= AttribOmnipresent;
- openbox_attrib.attrib ^= AttribOmnipresent;
+ blackbox_attrib.flags ^= AttribOmnipresent;
+ blackbox_attrib.attrib ^= AttribOmnipresent;
flags.stuck = False;
if (! flags.iconic)
- screen->reassociateWindow(this, -1, True);
+ screen->reassociateWindow(this, BSENTINEL, True);
setState(current_state);
} else {
flags.stuck = True;
- openbox_attrib.flags |= AttribOmnipresent;
- openbox_attrib.attrib |= AttribOmnipresent;
+ blackbox_attrib.flags |= AttribOmnipresent;
+ blackbox_attrib.attrib |= AttribOmnipresent;
setState(current_state);
}
}
-void OpenboxWindow::setFocusFlag(Bool focus) {
+void BlackboxWindow::setFocusFlag(bool focus) {
flags.focused = focus;
- if (decorations.titlebar) {
+ if (decorations & Decor_Titlebar) {
if (flags.focused) {
if (frame.ftitle)
- XSetWindowBackgroundPixmap(display, frame.title, frame.ftitle);
+ XSetWindowBackgroundPixmap(blackbox->getXDisplay(),
+ frame.title, frame.ftitle);
else
- XSetWindowBackground(display, frame.title, frame.ftitle_pixel);
+ XSetWindowBackground(blackbox->getXDisplay(),
+ frame.title, frame.ftitle_pixel);
} else {
if (frame.utitle)
- XSetWindowBackgroundPixmap(display, frame.title, frame.utitle);
+ XSetWindowBackgroundPixmap(blackbox->getXDisplay(),
+ frame.title, frame.utitle);
else
- XSetWindowBackground(display, frame.title, frame.utitle_pixel);
+ XSetWindowBackground(blackbox->getXDisplay(),
+ frame.title, frame.utitle_pixel);
}
- XClearWindow(display, frame.title);
+ XClearWindow(blackbox->getXDisplay(), frame.title);
redrawLabel();
redrawAllButtons();
}
- if (decorations.handle) {
+ if (decorations & Decor_Handle) {
if (flags.focused) {
if (frame.fhandle)
- XSetWindowBackgroundPixmap(display, frame.handle, frame.fhandle);
+ XSetWindowBackgroundPixmap(blackbox->getXDisplay(),
+ frame.handle, frame.fhandle);
else
- XSetWindowBackground(display, frame.handle, frame.fhandle_pixel);
+ XSetWindowBackground(blackbox->getXDisplay(),
+ frame.handle, frame.fhandle_pixel);
if (frame.fgrip) {
- XSetWindowBackgroundPixmap(display, frame.right_grip, frame.fgrip);
- XSetWindowBackgroundPixmap(display, frame.left_grip, frame.fgrip);
+ XSetWindowBackgroundPixmap(blackbox->getXDisplay(),
+ frame.left_grip, frame.fgrip);
+ XSetWindowBackgroundPixmap(blackbox->getXDisplay(),
+ frame.right_grip, frame.fgrip);
} else {
- XSetWindowBackground(display, frame.right_grip, frame.fgrip_pixel);
- XSetWindowBackground(display, frame.left_grip, frame.fgrip_pixel);
+ XSetWindowBackground(blackbox->getXDisplay(),
+ frame.left_grip, frame.fgrip_pixel);
+ XSetWindowBackground(blackbox->getXDisplay(),
+ frame.right_grip, frame.fgrip_pixel);
}
} else {
if (frame.uhandle)
- XSetWindowBackgroundPixmap(display, frame.handle, frame.uhandle);
+ XSetWindowBackgroundPixmap(blackbox->getXDisplay(),
+ frame.handle, frame.uhandle);
else
- XSetWindowBackground(display, frame.handle, frame.uhandle_pixel);
+ XSetWindowBackground(blackbox->getXDisplay(),
+ frame.handle, frame.uhandle_pixel);
if (frame.ugrip) {
- XSetWindowBackgroundPixmap(display, frame.right_grip, frame.ugrip);
- XSetWindowBackgroundPixmap(display, frame.left_grip, frame.ugrip);
+ XSetWindowBackgroundPixmap(blackbox->getXDisplay(),
+ frame.left_grip, frame.ugrip);
+ XSetWindowBackgroundPixmap(blackbox->getXDisplay(),
+ frame.right_grip, frame.ugrip);
} else {
- XSetWindowBackground(display, frame.right_grip, frame.ugrip_pixel);
- XSetWindowBackground(display, frame.left_grip, frame.ugrip_pixel);
+ XSetWindowBackground(blackbox->getXDisplay(),
+ frame.left_grip, frame.ugrip_pixel);
+ XSetWindowBackground(blackbox->getXDisplay(),
+ frame.right_grip, frame.ugrip_pixel);
}
}
- XClearWindow(display, frame.handle);
- XClearWindow(display, frame.right_grip);
- XClearWindow(display, frame.left_grip);
+ XClearWindow(blackbox->getXDisplay(), frame.handle);
+ XClearWindow(blackbox->getXDisplay(), frame.left_grip);
+ XClearWindow(blackbox->getXDisplay(), frame.right_grip);
}
- if (decorations.border) {
+ if (decorations & Decor_Border) {
if (flags.focused)
- XSetWindowBorder(display, frame.plate, frame.fborder_pixel);
+ XSetWindowBorder(blackbox->getXDisplay(),
+ frame.plate, frame.fborder_pixel);
else
- XSetWindowBorder(display, frame.plate, frame.uborder_pixel);
+ XSetWindowBorder(blackbox->getXDisplay(),
+ frame.plate, frame.uborder_pixel);
}
- if (screen->sloppyFocus() && screen->autoRaise() && timer->isTiming())
- timer->stop();
+ if (screen->isSloppyFocus() && screen->doAutoRaise()) {
+ if (isFocused()) timer->start();
+ else timer->stop();
+ }
+ if (isFocused())
+ blackbox->setFocusedWindow(this);
}
-void OpenboxWindow::installColormap(Bool install) {
- openbox.grab();
- if (! validateClient()) return;
-
+void BlackboxWindow::installColormap(bool install) {
int i = 0, ncmap = 0;
- Colormap *cmaps = XListInstalledColormaps(display, client.window, &ncmap);
+ Colormap *cmaps = XListInstalledColormaps(blackbox->getXDisplay(),
+ client.window, &ncmap);
XWindowAttributes wattrib;
if (cmaps) {
- if (XGetWindowAttributes(display, client.window, &wattrib)) {
+ if (XGetWindowAttributes(blackbox->getXDisplay(),
+ client.window, &wattrib)) {
if (install) {
// install the window's colormap
for (i = 0; i < ncmap; i++) {
}
// otherwise, install the window's colormap
if (install)
- XInstallColormap(display, wattrib.colormap);
+ XInstallColormap(blackbox->getXDisplay(), wattrib.colormap);
} else {
// uninstall the window's colormap
for (i = 0; i < ncmap; i++) {
if (*(cmaps + i) == wattrib.colormap)
// we found the colormap to uninstall
- XUninstallColormap(display, wattrib.colormap);
+ XUninstallColormap(blackbox->getXDisplay(), wattrib.colormap);
}
}
}
XFree(cmaps);
}
-
- openbox.ungrab();
}
-void OpenboxWindow::setState(unsigned long new_state) {
+void BlackboxWindow::setState(unsigned long new_state) {
current_state = new_state;
unsigned long state[2];
- state[0] = (unsigned long) current_state;
- state[1] = (unsigned long) None;
- XChangeProperty(display, client.window, openbox.getWMStateAtom(),
- openbox.getWMStateAtom(), 32, PropModeReplace,
- (unsigned char *) state, 2);
+ state[0] = current_state;
+ state[1] = None;
+ XChangeProperty(blackbox->getXDisplay(), client.window,
+ blackbox->getWMStateAtom(), blackbox->getWMStateAtom(), 32,
+ PropModeReplace, (unsigned char *) state, 2);
- XChangeProperty(display, client.window,
- openbox.getOpenboxAttributesAtom(),
- openbox.getOpenboxAttributesAtom(), 32, PropModeReplace,
- (unsigned char *) &openbox_attrib,
- PropOpenboxAttributesElements);
+ XChangeProperty(blackbox->getXDisplay(), client.window,
+ blackbox->getBlackboxAttributesAtom(),
+ blackbox->getBlackboxAttributesAtom(), 32, PropModeReplace,
+ (unsigned char *) &blackbox_attrib,
+ PropBlackboxAttributesElements);
}
-Bool OpenboxWindow::getState(void) {
+bool BlackboxWindow::getState(void) {
current_state = 0;
Atom atom_return;
- Bool ret = False;
+ bool ret = False;
int foo;
unsigned long *state, ulfoo, nitems;
- if ((XGetWindowProperty(display, client.window, openbox.getWMStateAtom(),
- 0l, 2l, False, openbox.getWMStateAtom(),
+ if ((XGetWindowProperty(blackbox->getXDisplay(), client.window,
+ blackbox->getWMStateAtom(),
+ 0l, 2l, False, blackbox->getWMStateAtom(),
&atom_return, &foo, &nitems, &ulfoo,
(unsigned char **) &state) != Success) ||
(! state)) {
- openbox.ungrab();
return False;
}
if (nitems >= 1) {
- current_state = (unsigned long) state[0];
+ current_state = static_cast<unsigned long>(state[0]);
ret = True;
}
}
-void OpenboxWindow::setGravityOffsets(void) {
- // x coordinates for each gravity type
- const int x_west = client.x;
- const int x_east = client.x + client.width - frame.width;
- const int x_center = client.x + client.width - frame.width/2;
- // y coordinates for each gravity type
- const int y_north = client.y;
- const int y_south = client.y + client.height - frame.height;
- const int y_center = client.y + client.height - frame.height/2;
-
- switch (client.win_gravity) {
- case NorthWestGravity:
- default:
- frame.x = x_west;
- frame.y = y_north;
- break;
- case NorthGravity:
- frame.x = x_center;
- frame.y = y_north;
- break;
- case NorthEastGravity:
- frame.x = x_east;
- frame.y = y_north;
- break;
- case SouthWestGravity:
- frame.x = x_west;
- frame.y = y_south;
- break;
- case SouthGravity:
- frame.x = x_center;
- frame.y = y_south;
- break;
- case SouthEastGravity:
- frame.x = x_east;
- frame.y = y_south;
- break;
- case WestGravity:
- frame.x = x_west;
- frame.y = y_center;
- break;
- case EastGravity:
- frame.x = x_east;
- frame.y = y_center;
- break;
- case CenterGravity:
- frame.x = x_center;
- frame.y = y_center;
- break;
- case ForgetGravity:
- case StaticGravity:
- frame.x = client.x - frame.mwm_border_w + frame.border_w;
- frame.y = client.y - frame.y_border - frame.mwm_border_w - frame.border_w;
- break;
- }
-}
-
-
-void OpenboxWindow::restoreAttributes(void) {
+void BlackboxWindow::restoreAttributes(void) {
if (! getState()) current_state = NormalState;
Atom atom_return;
int foo;
unsigned long ulfoo, nitems;
- OpenboxAttributes *net;
- int ret = XGetWindowProperty(display, client.window,
- openbox.getOpenboxAttributesAtom(), 0l,
- PropOpenboxAttributesElements, False,
- openbox.getOpenboxAttributesAtom(),
+ BlackboxAttributes *net;
+ int ret = XGetWindowProperty(blackbox->getXDisplay(), client.window,
+ blackbox->getBlackboxAttributesAtom(), 0l,
+ PropBlackboxAttributesElements, False,
+ blackbox->getBlackboxAttributesAtom(),
&atom_return, &foo, &nitems, &ulfoo,
(unsigned char **) &net);
- if (ret != Success || !net || nitems != PropOpenboxAttributesElements)
+ if (ret != Success || !net || nitems != PropBlackboxAttributesElements)
return;
- openbox_attrib.flags = net->flags;
- openbox_attrib.attrib = net->attrib;
- openbox_attrib.decoration = net->decoration;
- openbox_attrib.workspace = net->workspace;
- openbox_attrib.stack = net->stack;
- openbox_attrib.premax_x = net->premax_x;
- openbox_attrib.premax_y = net->premax_y;
- openbox_attrib.premax_w = net->premax_w;
- openbox_attrib.premax_h = net->premax_h;
-
- XFree((void *) net);
-
- if (openbox_attrib.flags & AttribShaded &&
- openbox_attrib.attrib & AttribShaded) {
+ if (net->flags & AttribShaded &&
+ net->attrib & AttribShaded) {
int save_state =
((current_state == IconicState) ? NormalState : current_state);
current_state = save_state;
}
- if (((int) openbox_attrib.workspace != screen->getCurrentWorkspaceID()) &&
- ((int) openbox_attrib.workspace < screen->getWorkspaceCount())) {
- screen->reassociateWindow(this, openbox_attrib.workspace, True);
+ if ((net->workspace != screen->getCurrentWorkspaceID()) &&
+ (net->workspace < screen->getWorkspaceCount())) {
+ screen->reassociateWindow(this, net->workspace, True);
if (current_state == NormalState) current_state = WithdrawnState;
} else if (current_state == WithdrawnState) {
current_state = NormalState;
}
- if (openbox_attrib.flags & AttribOmnipresent &&
- openbox_attrib.attrib & AttribOmnipresent) {
+ if (net->flags & AttribOmnipresent &&
+ net->attrib & AttribOmnipresent) {
flags.stuck = False;
stick();
current_state = NormalState;
}
- if ((openbox_attrib.flags & AttribMaxHoriz) ||
- (openbox_attrib.flags & AttribMaxVert)) {
- int x = openbox_attrib.premax_x, y = openbox_attrib.premax_y;
- unsigned int w = openbox_attrib.premax_w, h = openbox_attrib.premax_h;
+ if ((net->flags & AttribMaxHoriz) ||
+ (net->flags & AttribMaxVert)) {
+ int x = net->premax_x, y = net->premax_y;
+ unsigned int w = net->premax_w, h = net->premax_h;
flags.maximized = 0;
- unsigned int m = False;
- if ((openbox_attrib.flags & AttribMaxHoriz) &&
- (openbox_attrib.flags & AttribMaxVert))
- m = (openbox_attrib.attrib & (AttribMaxHoriz | AttribMaxVert)) ? 1 : 0;
- else if (openbox_attrib.flags & AttribMaxVert)
- m = (openbox_attrib.attrib & AttribMaxVert) ? 2 : 0;
- else if (openbox_attrib.flags & AttribMaxHoriz)
- m = (openbox_attrib.attrib & AttribMaxHoriz) ? 3 : 0;
+ unsigned int m = 0;
+ if ((net->flags & AttribMaxHoriz) &&
+ (net->flags & AttribMaxVert))
+ m = (net->attrib & (AttribMaxHoriz | AttribMaxVert)) ? 1 : 0;
+ else if (net->flags & AttribMaxVert)
+ m = (net->attrib & AttribMaxVert) ? 2 : 0;
+ else if (net->flags & AttribMaxHoriz)
+ m = (net->attrib & AttribMaxHoriz) ? 3 : 0;
if (m) maximize(m);
- openbox_attrib.premax_x = x;
- openbox_attrib.premax_y = y;
- openbox_attrib.premax_w = w;
- openbox_attrib.premax_h = h;
+ blackbox_attrib.premax_x = x;
+ blackbox_attrib.premax_y = y;
+ blackbox_attrib.premax_w = w;
+ blackbox_attrib.premax_h = h;
}
setState(current_state);
+
+ XFree((void *) net);
+}
+
+
+/*
+ * Positions the frame according the the client window position and window
+ * gravity.
+ */
+void BlackboxWindow::setGravityOffsets(void) {
+ // x coordinates for each gravity type
+ const int x_west = client.rect.x();
+ const int x_east = client.rect.right() - frame.inside_w + 1;
+ const int x_center = client.rect.right() - (frame.rect.width()/2) + 1;
+ // y coordinates for each gravity type
+ const int y_north = client.rect.y();
+ const int y_south = client.rect.bottom() - frame.inside_h + 1;
+ const int y_center = client.rect.bottom() - (frame.rect.height()/2) + 1;
+
+ switch (client.win_gravity) {
+ default:
+ case NorthWestGravity: frame.rect.setPos(x_west, y_north); break;
+ case NorthGravity: frame.rect.setPos(x_center, y_north); break;
+ case NorthEastGravity: frame.rect.setPos(x_east, y_north); break;
+ case SouthWestGravity: frame.rect.setPos(x_west, y_south); break;
+ case SouthGravity: frame.rect.setPos(x_center, y_south); break;
+ case SouthEastGravity: frame.rect.setPos(x_east, y_south); break;
+ case WestGravity: frame.rect.setPos(x_west, y_center); break;
+ case CenterGravity: frame.rect.setPos(x_center, y_center); break;
+ case EastGravity: frame.rect.setPos(x_east, y_center); break;
+
+ case ForgetGravity:
+ case StaticGravity:
+ frame.rect.setPos(client.rect.x() - frame.margin.left,
+ client.rect.y() - frame.margin.top);
+ break;
+ }
}
* The reverse of the setGravityOffsets function. Uses the frame window's
* position to find the window's reference point.
*/
-void OpenboxWindow::restoreGravity(void) {
+void BlackboxWindow::restoreGravity(void) {
// x coordinates for each gravity type
- const int x_west = frame.x;
- const int x_east = frame.x + frame.width - client.width;
- const int x_center = frame.x + (frame.width/2) - client.width;
+ const int x_west = frame.rect.x();
+ const int x_east = frame.rect.x() + frame.inside_w - client.rect.width();
+ const int x_center = frame.rect.x() + (frame.rect.width()/2) -
+ client.rect.width();
// y coordinates for each gravity type
- const int y_north = frame.y;
- const int y_south = frame.y + frame.height - client.height;
- const int y_center = frame.y + (frame.height/2) - client.height;
+ const int y_north = frame.rect.y();
+ const int y_south = frame.rect.y() + frame.inside_h - client.rect.height();
+ const int y_center = frame.rect.y() + (frame.rect.height()/2) -
+ client.rect.height();
switch(client.win_gravity) {
default:
- case NorthWestGravity:
- client.x = x_west;
- client.y = y_north;
- break;
- case NorthGravity:
- client.x = x_center;
- client.y = y_north;
- break;
- case NorthEastGravity:
- client.x = x_east;
- client.y = y_north;
- break;
- case SouthWestGravity:
- client.x = x_west;
- client.y = y_south;
- break;
- case SouthGravity:
- client.x = x_center;
- client.y = y_south;
- break;
- case SouthEastGravity:
- client.x = x_east;
- client.y = y_south;
- break;
- case WestGravity:
- client.x = x_west;
- client.y = y_center;
- break;
- case EastGravity:
- client.x = x_east;
- client.y = y_center;
- break;
- case CenterGravity:
- client.x = x_center;
- client.y = y_center;
- break;
+ case NorthWestGravity: client.rect.setPos(x_west, y_north); break;
+ case NorthGravity: client.rect.setPos(x_center, y_north); break;
+ case NorthEastGravity: client.rect.setPos(x_east, y_north); break;
+ case SouthWestGravity: client.rect.setPos(x_west, y_south); break;
+ case SouthGravity: client.rect.setPos(x_center, y_south); break;
+ case SouthEastGravity: client.rect.setPos(x_east, y_south); break;
+ case WestGravity: client.rect.setPos(x_west, y_center); break;
+ case CenterGravity: client.rect.setPos(x_center, y_center); break;
+ case EastGravity: client.rect.setPos(x_east, y_center); break;
+
case ForgetGravity:
case StaticGravity:
- client.x = frame.x + frame.mwm_border_w + frame.border_w;
- client.y = frame.y + frame.y_border + frame.mwm_border_w +
- frame.border_w;
+ client.rect.setPos(frame.rect.left() + frame.margin.left,
+ frame.rect.top() + frame.margin.top);
break;
}
}
-void OpenboxWindow::redrawLabel(void) {
- int dx = frame.bevel_w * 2, dlen = client.title_len;
- unsigned int l = client.title_text_w;
-
+void BlackboxWindow::redrawLabel(void) {
if (flags.focused) {
if (frame.flabel)
- XSetWindowBackgroundPixmap(display, frame.label, frame.flabel);
+ XSetWindowBackgroundPixmap(blackbox->getXDisplay(),
+ frame.label, frame.flabel);
else
- XSetWindowBackground(display, frame.label, frame.flabel_pixel);
+ XSetWindowBackground(blackbox->getXDisplay(),
+ frame.label, frame.flabel_pixel);
} else {
if (frame.ulabel)
- XSetWindowBackgroundPixmap(display, frame.label, frame.ulabel);
+ XSetWindowBackgroundPixmap(blackbox->getXDisplay(),
+ frame.label, frame.ulabel);
else
- XSetWindowBackground(display, frame.label, frame.ulabel_pixel);
- }
- XClearWindow(display, frame.label);
-
- if (client.title_text_w > frame.label_w) {
- for (; dlen >= 0; dlen--) {
- if (i18n.multibyte()) {
- XRectangle ink, logical;
- XmbTextExtents(screen->getWindowStyle()->fontset, client.title, dlen,
- &ink, &logical);
- l = logical.width;
- } else {
- l = XTextWidth(screen->getWindowStyle()->font, client.title, dlen);
- }
- l += (frame.bevel_w * 4);
-
- if (l < frame.label_w)
- break;
- }
+ XSetWindowBackground(blackbox->getXDisplay(),
+ frame.label, frame.ulabel_pixel);
}
+ XClearWindow(blackbox->getXDisplay(), frame.label);
- switch (screen->getWindowStyle()->justify) {
- case BScreen::RightJustify:
- dx += frame.label_w - l;
- break;
+ WindowStyle *style = screen->getWindowStyle();
- case BScreen::CenterJustify:
- dx += (frame.label_w - l) / 2;
- break;
- }
+ int pos = frame.bevel_w * 2,
+ dlen = style->doJustify(client.title.c_str(), pos, frame.label_w,
+ frame.bevel_w * 4, i18n.multibyte());
- WindowStyle *style = screen->getWindowStyle();
- GC text_gc = (flags.focused) ? style->l_text_focus_gc :
- style->l_text_unfocus_gc;
+ BPen pen((flags.focused) ? style->l_text_focus : style->l_text_unfocus,
+ style->font);
if (i18n.multibyte())
- XmbDrawString(display, frame.label, style->fontset, text_gc, dx,
+ XmbDrawString(blackbox->getXDisplay(), frame.label, style->fontset,
+ pen.gc(), pos,
(1 - style->fontset_extents->max_ink_extent.y),
- client.title, dlen);
+ client.title.c_str(), dlen);
else
- XDrawString(display, frame.label, text_gc, dx,
- (style->font->ascent + 1), client.title, dlen);
+ XDrawString(blackbox->getXDisplay(), frame.label, pen.gc(), pos,
+ (style->font->ascent + 1), client.title.c_str(), dlen);
}
-void OpenboxWindow::redrawAllButtons(void) {
+void BlackboxWindow::redrawAllButtons(void) {
if (frame.iconify_button) redrawIconifyButton(False);
if (frame.maximize_button) redrawMaximizeButton(flags.maximized);
if (frame.close_button) redrawCloseButton(False);
}
-void OpenboxWindow::redrawIconifyButton(Bool pressed) {
+void BlackboxWindow::redrawIconifyButton(bool pressed) {
if (! pressed) {
if (flags.focused) {
if (frame.fbutton)
- XSetWindowBackgroundPixmap(display, frame.iconify_button,
- frame.fbutton);
+ XSetWindowBackgroundPixmap(blackbox->getXDisplay(),
+ frame.iconify_button, frame.fbutton);
else
- XSetWindowBackground(display, frame.iconify_button,
- frame.fbutton_pixel);
+ XSetWindowBackground(blackbox->getXDisplay(),
+ frame.iconify_button, frame.fbutton_pixel);
} else {
if (frame.ubutton)
- XSetWindowBackgroundPixmap(display, frame.iconify_button,
- frame.ubutton);
+ XSetWindowBackgroundPixmap(blackbox->getXDisplay(),
+ frame.iconify_button, frame.ubutton);
else
- XSetWindowBackground(display, frame.iconify_button,
+ XSetWindowBackground(blackbox->getXDisplay(), frame.iconify_button,
frame.ubutton_pixel);
}
} else {
if (frame.pbutton)
- XSetWindowBackgroundPixmap(display, frame.iconify_button, frame.pbutton);
+ XSetWindowBackgroundPixmap(blackbox->getXDisplay(),
+ frame.iconify_button, frame.pbutton);
else
- XSetWindowBackground(display, frame.iconify_button, frame.pbutton_pixel);
+ XSetWindowBackground(blackbox->getXDisplay(),
+ frame.iconify_button, frame.pbutton_pixel);
}
- XClearWindow(display, frame.iconify_button);
+ XClearWindow(blackbox->getXDisplay(), frame.iconify_button);
- XDrawRectangle(display, frame.iconify_button,
- ((flags.focused) ? screen->getWindowStyle()->b_pic_focus_gc :
- screen->getWindowStyle()->b_pic_unfocus_gc),
- 2, (frame.button_h - 5), (frame.button_w - 5), 2);
+ BPen pen((flags.focused) ? screen->getWindowStyle()->b_pic_focus :
+ screen->getWindowStyle()->b_pic_unfocus);
+ XDrawRectangle(blackbox->getXDisplay(), frame.iconify_button, pen.gc(),
+ 2, (frame.button_w - 5), (frame.button_w - 5), 2);
}
-void OpenboxWindow::redrawMaximizeButton(Bool pressed) {
+void BlackboxWindow::redrawMaximizeButton(bool pressed) {
if (! pressed) {
if (flags.focused) {
if (frame.fbutton)
- XSetWindowBackgroundPixmap(display, frame.maximize_button,
- frame.fbutton);
+ XSetWindowBackgroundPixmap(blackbox->getXDisplay(),
+ frame.maximize_button, frame.fbutton);
else
- XSetWindowBackground(display, frame.maximize_button,
+ XSetWindowBackground(blackbox->getXDisplay(), frame.maximize_button,
frame.fbutton_pixel);
} else {
if (frame.ubutton)
- XSetWindowBackgroundPixmap(display, frame.maximize_button,
- frame.ubutton);
+ XSetWindowBackgroundPixmap(blackbox->getXDisplay(),
+ frame.maximize_button, frame.ubutton);
else
- XSetWindowBackground(display, frame.maximize_button,
+ XSetWindowBackground(blackbox->getXDisplay(), frame.maximize_button,
frame.ubutton_pixel);
}
} else {
if (frame.pbutton)
- XSetWindowBackgroundPixmap(display, frame.maximize_button,
- frame.pbutton);
+ XSetWindowBackgroundPixmap(blackbox->getXDisplay(),
+ frame.maximize_button, frame.pbutton);
else
- XSetWindowBackground(display, frame.maximize_button,
+ XSetWindowBackground(blackbox->getXDisplay(), frame.maximize_button,
frame.pbutton_pixel);
}
- XClearWindow(display, frame.maximize_button);
+ XClearWindow(blackbox->getXDisplay(), frame.maximize_button);
- XDrawRectangle(display, frame.maximize_button,
- ((flags.focused) ? screen->getWindowStyle()->b_pic_focus_gc :
- screen->getWindowStyle()->b_pic_unfocus_gc),
- 2, 2, (frame.button_w - 5), (frame.button_h - 5));
- XDrawLine(display, frame.maximize_button,
- ((flags.focused) ? screen->getWindowStyle()->b_pic_focus_gc :
- screen->getWindowStyle()->b_pic_unfocus_gc),
+ BPen pen((flags.focused) ? screen->getWindowStyle()->b_pic_focus :
+ screen->getWindowStyle()->b_pic_unfocus);
+ XDrawRectangle(blackbox->getXDisplay(), frame.maximize_button, pen.gc(),
+ 2, 2, (frame.button_w - 5), (frame.button_w - 5));
+ XDrawLine(blackbox->getXDisplay(), frame.maximize_button, pen.gc(),
2, 3, (frame.button_w - 3), 3);
}
-void OpenboxWindow::redrawCloseButton(Bool pressed) {
+void BlackboxWindow::redrawCloseButton(bool pressed) {
if (! pressed) {
if (flags.focused) {
if (frame.fbutton)
- XSetWindowBackgroundPixmap(display, frame.close_button,
+ XSetWindowBackgroundPixmap(blackbox->getXDisplay(), frame.close_button,
frame.fbutton);
else
- XSetWindowBackground(display, frame.close_button,
+ XSetWindowBackground(blackbox->getXDisplay(), frame.close_button,
frame.fbutton_pixel);
} else {
if (frame.ubutton)
- XSetWindowBackgroundPixmap(display, frame.close_button,
+ XSetWindowBackgroundPixmap(blackbox->getXDisplay(), frame.close_button,
frame.ubutton);
else
- XSetWindowBackground(display, frame.close_button,
+ XSetWindowBackground(blackbox->getXDisplay(), frame.close_button,
frame.ubutton_pixel);
}
} else {
if (frame.pbutton)
- XSetWindowBackgroundPixmap(display, frame.close_button, frame.pbutton);
+ XSetWindowBackgroundPixmap(blackbox->getXDisplay(),
+ frame.close_button, frame.pbutton);
else
- XSetWindowBackground(display, frame.close_button, frame.pbutton_pixel);
+ XSetWindowBackground(blackbox->getXDisplay(),
+ frame.close_button, frame.pbutton_pixel);
}
- XClearWindow(display, frame.close_button);
+ XClearWindow(blackbox->getXDisplay(), frame.close_button);
- XDrawLine(display, frame.close_button,
- ((flags.focused) ? screen->getWindowStyle()->b_pic_focus_gc :
- screen->getWindowStyle()->b_pic_unfocus_gc), 2, 2,
- (frame.button_w - 3), (frame.button_h - 3));
- XDrawLine(display, frame.close_button,
- ((flags.focused) ? screen->getWindowStyle()->b_pic_focus_gc :
- screen->getWindowStyle()->b_pic_unfocus_gc), 2,
- (frame.button_h - 3),
- (frame.button_w - 3), 2);
+ BPen pen((flags.focused) ? screen->getWindowStyle()->b_pic_focus :
+ screen->getWindowStyle()->b_pic_unfocus);
+ XDrawLine(blackbox->getXDisplay(), frame.close_button, pen.gc(),
+ 2, 2, (frame.button_w - 3), (frame.button_w - 3));
+ XDrawLine(blackbox->getXDisplay(), frame.close_button, pen.gc(),
+ 2, (frame.button_w - 3), (frame.button_w - 3), 2);
}
-void OpenboxWindow::mapRequestEvent(XMapRequestEvent *re) {
- if (re->window == client.window) {
+void BlackboxWindow::mapRequestEvent(XMapRequestEvent *re) {
+ if (re->window != client.window)
+ return;
+
#ifdef DEBUG
- fprintf(stderr, i18n(WindowSet, WindowMapRequest,
- "OpenboxWindow::mapRequestEvent() for 0x%lx\n"),
- client.window);
+ fprintf(stderr, "BlackboxWindow::mapRequestEvent() for 0x%lx\n",
+ client.window);
#endif // DEBUG
- openbox.grab();
- if (! validateClient()) return;
-
- Bool get_state_ret = getState();
- if (! (get_state_ret && openbox.isStartup())) {
- if ((client.wm_hint_flags & StateHint) &&
- (! (current_state == NormalState || current_state == IconicState)))
- current_state = client.initial_state;
- else
- current_state = NormalState;
- } else if (flags.iconic) {
+ bool get_state_ret = getState();
+ if (! (get_state_ret && blackbox->isStartup())) {
+ if ((client.wm_hint_flags & StateHint) &&
+ (! (current_state == NormalState || current_state == IconicState)))
+ current_state = client.initial_state;
+ else
current_state = NormalState;
- }
-
- switch (current_state) {
- case IconicState:
- iconify();
- break;
-
- case WithdrawnState:
- withdraw();
- break;
-
- case NormalState:
- case InactiveState:
- case ZoomState:
- default:
- deiconify(False, True, True); // specify that we're initializing the
- // window
- break;
- }
-
- openbox.ungrab();
+ } else if (flags.iconic) {
+ current_state = NormalState;
}
-}
-
-void OpenboxWindow::mapNotifyEvent(XMapEvent *ne) {
- if ((ne->window == client.window) && (! ne->override_redirect)
- && (flags.visible)) {
- openbox.grab();
- if (! validateClient()) return;
+ switch (current_state) {
+ case IconicState:
+ iconify();
+ break;
- setState(NormalState);
+ case WithdrawnState:
+ withdraw();
+ break;
- if (flags.transient || screen->focusNew())
+ case NormalState:
+ case InactiveState:
+ case ZoomState:
+ default:
+ show();
+ screen->getWorkspace(blackbox_attrib.workspace)->raiseWindow(this);
+ if (! blackbox->isStartup() && (isTransient() || screen->doFocusNew())) {
+ XSync(blackbox->getXDisplay(), False); // make sure the frame is mapped..
setInputFocus();
- else
- setFocusFlag(False);
-
- flags.visible = True;
- flags.iconic = False;
-
- openbox.ungrab();
+ }
+ break;
}
}
-void OpenboxWindow::unmapNotifyEvent(XUnmapEvent *ue) {
- if (ue->window == client.window) {
+void BlackboxWindow::unmapNotifyEvent(XUnmapEvent *ue) {
+ if (ue->window != client.window)
+ return;
+
#ifdef DEBUG
- fprintf(stderr, i18n(WindowSet, WindowUnmapNotify,
- "OpenboxWindow::unmapNotifyEvent() for 0x%lx\n"),
- client.window);
+ fprintf(stderr, "BlackboxWindow::unmapNotifyEvent() for 0x%lx\n",
+ client.window);
#endif // DEBUG
- openbox.grab();
- if (! validateClient()) return;
-
- if (flags.moving)
- endMove();
-
- XChangeSaveSet(display, client.window, SetModeDelete);
- XSelectInput(display, client.window, NoEventMask);
+ screen->unmanageWindow(this, False);
+}
- XDeleteProperty(display, client.window, openbox.getWMStateAtom());
- XDeleteProperty(display, client.window,
- openbox.getOpenboxAttributesAtom());
- XUnmapWindow(display, frame.window);
- XUnmapWindow(display, client.window);
+void BlackboxWindow::destroyNotifyEvent(XDestroyWindowEvent *de) {
+ if (de->window != client.window)
+ return;
- XEvent dummy;
- if (! XCheckTypedWindowEvent(display, client.window, ReparentNotify,
- &dummy)) {
#ifdef DEBUG
- fprintf(stderr, i18n(WindowSet, WindowUnmapNotifyReparent,
- "OpenboxWindow::unmapNotifyEvent(): reparent 0x%lx to "
- "root.\n"), client.window);
+ fprintf(stderr, "BlackboxWindow::destroyNotifyEvent() for 0x%lx\n",
+ client.window);
#endif // DEBUG
- restoreGravity();
- XReparentWindow(display, client.window, screen->getRootWindow(),
- client.x, client.y);
- }
-
- XFlush(display);
-
- openbox.ungrab();
-
- delete this;
- }
+ screen->unmanageWindow(this, False);
}
-void OpenboxWindow::destroyNotifyEvent(XDestroyWindowEvent *de) {
- if (de->window == client.window) {
- if (flags.moving)
- endMove();
- XUnmapWindow(display, frame.window);
+void BlackboxWindow::reparentNotifyEvent(XReparentEvent *re) {
+ if (re->window != client.window || re->parent == frame.plate)
+ return;
+
+#ifdef DEBUG
+ fprintf(stderr, "BlackboxWindow::reparentNotifyEvent(): reparent 0x%lx to "
+ "0x%lx.\n", client.window, re->parent);
+#endif // DEBUG
- delete this;
- }
+ XEvent ev;
+ ev.xreparent = *re;
+ XPutBackEvent(blackbox->getXDisplay(), &ev);
+ screen->unmanageWindow(this, True);
}
-void OpenboxWindow::propertyNotifyEvent(Atom atom) {
- openbox.grab();
- if (! validateClient()) return;
-
+void BlackboxWindow::propertyNotifyEvent(Atom atom) {
switch(atom) {
case XA_WM_CLASS:
case XA_WM_CLIENT_MACHINE:
case XA_WM_COMMAND:
break;
- case XA_WM_TRANSIENT_FOR:
+ case XA_WM_TRANSIENT_FOR: {
// determine if this is a transient window
- Window win;
- if (XGetTransientForHint(display, client.window, &win)) {
- if (win && (win != client.window)) {
- if ((client.transient_for = openbox.searchWindow(win))) {
- client.transient_for->client.transient = this;
- flags.stuck = client.transient_for->flags.stuck;
- flags.transient = True;
- } else if (win == client.window_group) {
- //jr This doesn't look quite right...
- if ((client.transient_for = openbox.searchGroup(win, this))) {
- client.transient_for->client.transient = this;
- flags.stuck = client.transient_for->flags.stuck;
- flags.transient = True;
- }
- }
- }
-
- if (win == screen->getRootWindow()) flags.modal = True;
- }
+ getTransientInfo();
// adjust the window decorations based on transience
- if (flags.transient)
- decorations.maximize = decorations.handle = functions.maximize = False;
+ if (isTransient()) {
+ decorations &= ~(Decor_Maximize | Decor_Handle);
+ functions &= ~Func_Maximize;
+ }
reconfigure();
-
+ }
break;
case XA_WM_HINTS:
case XA_WM_ICON_NAME:
getWMIconName();
- if (flags.iconic) screen->iconUpdate();
+ if (flags.iconic) screen->propagateWindowName(this);
break;
case XA_WM_NAME:
getWMName();
- if (decorations.titlebar)
+ if (decorations & Decor_Titlebar)
redrawLabel();
- if (! flags.iconic)
- screen->getWorkspace(workspace_number)->update();
-
+ screen->propagateWindowName(this);
break;
case XA_WM_NORMAL_HINTS: {
if ((client.normal_hint_flags & PMinSize) &&
(client.normal_hint_flags & PMaxSize)) {
if (client.max_width <= client.min_width &&
- client.max_height <= client.min_height)
- decorations.maximize = decorations.handle =
- functions.resize = functions.maximize = False;
- else
- decorations.maximize = decorations.handle =
- functions.resize = functions.maximize = True;
+ client.max_height <= client.min_height) {
+ decorations &= ~(Decor_Maximize | Decor_Handle);
+ functions &= ~(Func_Resize | Func_Maximize);
+ } else {
+ decorations |= Decor_Maximize | Decor_Handle;
+ functions |= Func_Resize | Func_Maximize;
+ }
}
- int x = frame.x, y = frame.y;
- unsigned int w = frame.width, h = frame.height;
+ Rect old_rect = frame.rect;
upsize();
- if ((x != frame.x) || (y != frame.y) ||
- (w != frame.width) || (h != frame.height))
+ if (old_rect != frame.rect)
reconfigure();
break;
}
default:
- if (atom == openbox.getWMProtocolsAtom()) {
+ if (atom == blackbox->getWMProtocolsAtom()) {
getWMProtocols();
- if (decorations.close && (! frame.close_button)) {
+ if ((decorations & Decor_Close) && (! frame.close_button)) {
createCloseButton();
- if (decorations.titlebar) {
- positionButtons();
- decorateLabel();
+ if (decorations & Decor_Titlebar) {
+ positionButtons(True);
+ XMapSubwindows(blackbox->getXDisplay(), frame.title);
}
if (windowmenu) windowmenu->reconfigure();
}
break;
}
-
- openbox.ungrab();
}
-void OpenboxWindow::exposeEvent(XExposeEvent *ee) {
- if (frame.label == ee->window && decorations.titlebar)
+void BlackboxWindow::exposeEvent(XExposeEvent *ee) {
+ if (frame.label == ee->window && (decorations & Decor_Titlebar))
redrawLabel();
else if (frame.close_button == ee->window)
redrawCloseButton(False);
}
-void OpenboxWindow::configureRequestEvent(XConfigureRequestEvent *cr) {
- if (cr->window == client.window) {
- openbox.grab();
- if (! validateClient()) return;
+void BlackboxWindow::configureRequestEvent(XConfigureRequestEvent *cr) {
+ if (cr->window != client.window || flags.iconic)
+ return;
- int cx = frame.x, cy = frame.y;
- unsigned int cw = frame.width, ch = frame.height;
+ int cx = frame.rect.x(), cy = frame.rect.y();
+ unsigned int cw = frame.rect.width(), ch = frame.rect.height();
- if (cr->value_mask & CWBorderWidth)
- client.old_bw = cr->border_width;
+ if (cr->value_mask & CWBorderWidth)
+ client.old_bw = cr->border_width;
- if (cr->value_mask & CWX)
- cx = cr->x - frame.mwm_border_w - frame.border_w;
+ if (cr->value_mask & CWX)
+ cx = cr->x - frame.margin.left;
- if (cr->value_mask & CWY)
- cy = cr->y - frame.y_border - frame.mwm_border_w -
- frame.border_w;
+ if (cr->value_mask & CWY)
+ cy = cr->y - frame.margin.top;
- if (cr->value_mask & CWWidth)
- cw = cr->width + (frame.mwm_border_w * 2);
+ if (cr->value_mask & CWWidth)
+ cw = cr->width + frame.margin.left + frame.margin.right;
- if (cr->value_mask & CWHeight)
- ch = cr->height + frame.y_border + (frame.mwm_border_w * 2) +
- (frame.border_w * decorations.handle) + frame.handle_h;
+ if (cr->value_mask & CWHeight)
+ ch = cr->height + frame.margin.top + frame.margin.bottom;
- if (frame.x != cx || frame.y != cy ||
- frame.width != cw || frame.height != ch)
- configure(cx, cy, cw, ch);
+ if (frame.rect != Rect(cx, cy, cw, ch))
+ configure(cx, cy, cw, ch);
- if (cr->value_mask & CWStackMode) {
- switch (cr->detail) {
- case Above:
- case TopIf:
- default:
- if (flags.iconic) deiconify();
- screen->getWorkspace(workspace_number)->raiseWindow(this);
- break;
+ if (cr->value_mask & CWStackMode) {
+ switch (cr->detail) {
+ case Below:
+ case BottomIf:
+ screen->getWorkspace(blackbox_attrib.workspace)->lowerWindow(this);
+ break;
- case Below:
- case BottomIf:
- if (flags.iconic) deiconify();
- screen->getWorkspace(workspace_number)->lowerWindow(this);
- break;
- }
+ case Above:
+ case TopIf:
+ default:
+ screen->getWorkspace(blackbox_attrib.workspace)->raiseWindow(this);
+ break;
}
-
- openbox.ungrab();
}
}
-void OpenboxWindow::buttonPressEvent(XButtonEvent *be) {
- openbox.grab();
- if (! validateClient())
- return;
+void BlackboxWindow::buttonPressEvent(XButtonEvent *be) {
+ if (frame.maximize_button == be->window) {
+ redrawMaximizeButton(True);
+ } else if (be->button == 1 || (be->button == 3 && be->state == Mod1Mask)) {
+ if (! flags.focused)
+ setInputFocus();
- int stack_change = 1; // < 0 means to lower the window
- // > 0 means to raise the window
- // 0 means to leave it where it is
-
- // alt + left/right click begins interactively moving/resizing the window
- // when the mouse is moved
- if (be->state == Mod1Mask && (be->button == 1 || be->button == 3)) {
- if (be->button == 3) {
- if (screen->getWindowZones() == 4 &&
- be->y < (signed) frame.height / 2) {
- resize_zone = ZoneTop;
- } else {
- resize_zone = ZoneBottom;
- }
- if (screen->getWindowZones() >= 2 &&
- be->x < (signed) frame.width / 2) {
- resize_zone |= ZoneLeft;
- } else {
- resize_zone |= ZoneRight;
- }
- }
- // control + left click on the titlebar shades the window
- } else if (be->state == ControlMask && be->button == 1) {
- if (be->window == frame.title ||
- be->window == frame.label)
- shade();
- // left click
- } else if (be->state == 0 && be->button == 1) {
- if (windowmenu && windowmenu->isVisible())
- windowmenu->hide();
-
- if (be->window == frame.maximize_button) {
- redrawMaximizeButton(True);
- } else if (be->window == frame.iconify_button) {
+ if (frame.iconify_button == be->window) {
redrawIconifyButton(True);
- } else if (be->window == frame.close_button) {
+ } else if (frame.close_button == be->window) {
redrawCloseButton(True);
- } else if (be->window == frame.plate) {
- XAllowEvents(display, ReplayPointer, be->time);
- } else if (be->window == frame.title ||
- be->window == frame.label) {
- // shade the window when the titlebar is double clicked
- if ( (be->time - lastButtonPressTime) <=
- openbox.getDoubleClickInterval()) {
- lastButtonPressTime = 0;
- shade();
- } else {
- lastButtonPressTime = be->time;
- }
- // clicking and dragging on the titlebar moves the window, so on a click
- // we need to save the coords of the click in case the user drags
- frame.grab_x = be->x_root - frame.x - frame.border_w;
- frame.grab_y = be->y_root - frame.y - frame.border_w;
- } else if (be->window == frame.handle ||
- be->window == frame.left_grip ||
- be->window == frame.right_grip ||
- be->window == frame.window) {
- // clicking and dragging on the window's frame moves the window, so on a
- // click we need to save the coords of the click in case the user drags
- frame.grab_x = be->x_root - frame.x - frame.border_w;
- frame.grab_y = be->y_root - frame.y - frame.border_w;
- if (be->window == frame.left_grip)
- resize_zone = ZoneBottom | ZoneLeft;
- else if (be->window == frame.right_grip)
- resize_zone = ZoneBottom | ZoneRight;
- }
- // middle click
- } else if (be->state == 0 && be->button == 2) {
- if (be->window == frame.maximize_button) {
- redrawMaximizeButton(True);
- // a middle click anywhere on the window's frame except for on the buttons
- // will lower the window
- } else if (! (be->window == frame.iconify_button ||
- be->window == frame.close_button) ) {
- stack_change = -1;
- }
- // right click
- } else if (be->state == 0 && be->button == 3) {
- if (be->window == frame.maximize_button) {
- redrawMaximizeButton(True);
- // a right click on the window's frame will show or hide the window's
- // windowmenu
- } else if (be->window == frame.title ||
- be->window == frame.label ||
- be->window == frame.handle ||
- be->window == frame.window) {
- int mx, my;
- if (windowmenu) {
- if (windowmenu->isVisible()) {
- windowmenu->hide();
+ } else if (frame.plate == be->window) {
+ if (windowmenu && windowmenu->isVisible()) windowmenu->hide();
+
+ screen->getWorkspace(blackbox_attrib.workspace)->raiseWindow(this);
+
+ XAllowEvents(blackbox->getXDisplay(), ReplayPointer, be->time);
+ } else {
+ if (frame.title == be->window || frame.label == be->window) {
+ if (((be->time - lastButtonPressTime) <=
+ blackbox->getDoubleClickInterval()) ||
+ (be->state & ControlMask)) {
+ lastButtonPressTime = 0;
+ shade();
} else {
- // get the coords for the menu
- mx = be->x_root - windowmenu->getWidth() / 2;
- if (be->window == frame.title || be->window == frame.label) {
- my = frame.y + frame.title_h;
- } else if (be->window == frame.handle) {
- my = frame.y + frame.y_handle - windowmenu->getHeight();
- } else { // (be->window == frame.window)
- if (be->y <= (signed) frame.bevel_w) {
- my = frame.y + frame.y_border;
- } else {
- my = be->y_root - (windowmenu->getHeight() / 2);
- }
- }
-
- if (mx > (signed) (frame.x + frame.width -
- windowmenu->getWidth())) {
- mx = frame.x + frame.width - windowmenu->getWidth();
- } else if (mx < frame.x) {
- mx = frame.x;
- }
-
- if (my > (signed) (frame.y + frame.y_handle -
- windowmenu->getHeight())) {
- my = frame.y + frame.y_handle - windowmenu->getHeight();
- } else if (my < (signed) (frame.y +
- ((decorations.titlebar) ? frame.title_h : frame.y_border))) {
- my = frame.y +
- ((decorations.titlebar) ? frame.title_h : frame.y_border);
- }
-
- windowmenu->move(mx, my);
- windowmenu->show();
- XRaiseWindow(display, windowmenu->getWindowID());
- XRaiseWindow(display, windowmenu->getSendToMenu()->getWindowID());
- stack_change = 0; // dont raise the window overtop of the menu
+ lastButtonPressTime = be->time;
}
}
- }
- // mouse wheel up
- } else if (be->state == 0 && be->button == 4) {
- if ((be->window == frame.label ||
- be->window == frame.title) &&
- !flags.shaded)
- shade();
- // mouse wheel down
- } else if (be->state == 0 && be->button == 5) {
- if ((be->window == frame.label ||
- be->window == frame.title) &&
- flags.shaded)
- shade();
- }
-
- if (! (flags.focused || screen->sloppyFocus()) ) {
- setInputFocus(); // any click focus' the window in 'click to focus'
- }
- if (stack_change < 0) {
- screen->getWorkspace(workspace_number)->lowerWindow(this);
- } else if (stack_change > 0) {
- screen->getWorkspace(workspace_number)->raiseWindow(this);
- }
-
- openbox.ungrab();
-}
+ frame.grab_x = be->x_root - frame.rect.x() - frame.border_w;
+ frame.grab_y = be->y_root - frame.rect.y() - frame.border_w;
-void OpenboxWindow::buttonReleaseEvent(XButtonEvent *re) {
- openbox.grab();
- if (! validateClient())
- return;
+ if (windowmenu && windowmenu->isVisible()) windowmenu->hide();
- // alt + middle button released
- if (re->state == (Mod1Mask & Button2Mask) && re->button == 2) {
- if (re->window == frame.window) {
- XUngrabPointer(display, CurrentTime); // why? i dont know
- }
- // left button released
- } else if (re->button == 1) {
- if (re->window == frame.maximize_button) {
- if (re->state == Button1Mask && // only the left button was depressed
- (re->x >= 0) && ((unsigned) re->x <= frame.button_w) &&
- (re->y >= 0) && ((unsigned) re->y <= frame.button_h)) {
- maximize(re->button);
- } else {
- redrawMaximizeButton(False);
- }
- } else if (re->window == frame.iconify_button) {
- if (re->state == Button1Mask && // only the left button was depressed
- (re->x >= 0) && ((unsigned) re->x <= frame.button_w) &&
- (re->y >= 0) && ((unsigned) re->y <= frame.button_h)) {
- iconify();
- } else {
- redrawIconifyButton(False);
- }
- } else if (re->window == frame.close_button) {
- if (re->state == Button1Mask && // only the left button was depressed
- (re->x >= 0) && ((unsigned) re->x <= frame.button_w) &&
- (re->y >= 0) && ((unsigned) re->y <= frame.button_h)) {
- close();
- }
- //we should always redraw the close button. some applications
- //eg. acroread don't honour the close.
- redrawCloseButton(False);
+ screen->getWorkspace(blackbox_attrib.workspace)->raiseWindow(this);
}
- // middle button released
- } else if (re->button == 2) {
- if (re->window == frame.maximize_button) {
- if (re->state == Button2Mask && // only the middle button was depressed
- (re->x >= 0) && ((unsigned) re->x <= frame.button_w) &&
- (re->y >= 0) && ((unsigned) re->y <= frame.button_h)) {
- maximize(re->button);
- } else {
- redrawMaximizeButton(False);
- }
+ } else if (be->button == 2 && (be->window != frame.iconify_button) &&
+ (be->window != frame.close_button)) {
+ screen->getWorkspace(blackbox_attrib.workspace)->lowerWindow(this);
+ } else if (windowmenu && be->button == 3 &&
+ (frame.title == be->window || frame.label == be->window ||
+ frame.handle == be->window || frame.window == be->window)) {
+ int mx = 0, my = 0;
+
+ if (frame.title == be->window || frame.label == be->window) {
+ mx = be->x_root - (windowmenu->getWidth() / 2);
+ my = frame.rect.y() + frame.title_h + frame.border_w;
+ } else if (frame.handle == be->window) {
+ mx = be->x_root - (windowmenu->getWidth() / 2);
+ my = frame.rect.bottom() - frame.handle_h - (frame.border_w * 3) -
+ windowmenu->getHeight();
+ } else {
+ mx = be->x_root - (windowmenu->getWidth() / 2);
+
+ if (be->y <= static_cast<signed>(frame.bevel_w))
+ my = frame.rect.y() + frame.title_h;
+ else
+ my = be->y_root - (windowmenu->getHeight() / 2);
}
- // right button released
- } else if (re->button == 3) {
- if (re->window == frame.maximize_button) {
- if (re->state == Button3Mask && // only the right button was depressed
- (re->x >= 0) && ((unsigned) re->x <= frame.button_w) &&
- (re->y >= 0) && ((unsigned) re->y <= frame.button_h)) {
- maximize(re->button);
+
+ // snap the window menu into a corner if necessary - we check the
+ // position of the menu with the coordinates of the client to
+ // make the comparisions easier.
+ // ### this needs some work!
+ if (mx > client.rect.right() -
+ static_cast<signed>(windowmenu->getWidth()))
+ mx = frame.rect.right() - windowmenu->getWidth() - frame.border_w + 1;
+ if (mx < client.rect.left())
+ mx = frame.rect.x();
+
+ if (my > client.rect.bottom() -
+ static_cast<signed>(windowmenu->getHeight()))
+ my = frame.rect.bottom() - windowmenu->getHeight() - frame.border_w + 1;
+ if (my < client.rect.top())
+ my = frame.rect.y() + ((decorations & Decor_Titlebar) ?
+ frame.title_h : 0);
+
+ if (windowmenu) {
+ if (! windowmenu->isVisible()) {
+ windowmenu->move(mx, my);
+ windowmenu->show();
+ XRaiseWindow(blackbox->getXDisplay(), windowmenu->getWindowID());
+ XRaiseWindow(blackbox->getXDisplay(),
+ windowmenu->getSendToMenu()->getWindowID());
} else {
- redrawMaximizeButton(False);
+ windowmenu->hide();
}
}
}
-
- // when the window is being interactively moved, a button release stops the
- // move where it is
- if (flags.moving) {
- endMove();
- // when the window is being interactively resized, a button release stops the
- // resizing
- } else if (flags.resizing) {
- flags.resizing = False;
- XDrawRectangle(display, screen->getRootWindow(), screen->getOpGC(),
- frame.resize_x, frame.resize_y,
- frame.resize_w - 1, frame.resize_h - 1);
- screen->hideGeometry();
- if (resize_zone & ZoneLeft) {
- left_fixsize();
- } else { // when resizing with "Alt+Button3", the resize is the same as if
- // done with the right grip (the right side of the window is what
- // moves)
- right_fixsize();
- }
- // unset maximized state when resized after fully maximized
- if (flags.maximized == 1) {
- maximize(0);
- }
- configure(frame.resize_x, frame.resize_y,
- frame.resize_w - (frame.border_w * 2),
- frame.resize_h - (frame.border_w * 2));
- openbox.ungrab();
- XUngrabPointer(display, CurrentTime);
- resize_zone = 0;
- }
-
- openbox.ungrab();
}
-void OpenboxWindow::startMove(int x, int y) {
- ASSERT(!flags.moving);
-
- // make sure only one window is moving at a time
- OpenboxWindow *w = openbox.getMaskedWindow();
- if (w != (OpenboxWindow *) 0 && w->flags.moving)
- w->endMove();
-
- XGrabPointer(display, frame.window, False, PointerMotionMask |
- ButtonReleaseMask, GrabModeAsync, GrabModeAsync,
- None, openbox.getMoveCursor(), CurrentTime);
-
- if (windowmenu && windowmenu->isVisible())
- windowmenu->hide();
-
- flags.moving = True;
-
- openbox.maskWindowEvents(client.window, this);
+void BlackboxWindow::buttonReleaseEvent(XButtonEvent *re) {
+ if (re->window == frame.maximize_button) {
+ if ((re->x >= 0 && re->x <= static_cast<signed>(frame.button_w)) &&
+ (re->y >= 0 && re->y <= static_cast<signed>(frame.button_w))) {
+ maximize(re->button);
+ } else {
+ redrawMaximizeButton(flags.maximized);
+ }
+ } else if (re->window == frame.iconify_button) {
+ if ((re->x >= 0 && re->x <= static_cast<signed>(frame.button_w)) &&
+ (re->y >= 0 && re->y <= static_cast<signed>(frame.button_w))) {
+ iconify();
+ } else {
+ redrawIconifyButton(False);
+ }
+ } else if (re->window == frame.close_button) {
+ if ((re->x >= 0 && re->x <= static_cast<signed>(frame.button_w)) &&
+ (re->y >= 0 && re->y <= static_cast<signed>(frame.button_w)))
+ close();
+ redrawCloseButton(False);
+ } else if (flags.moving) {
+ flags.moving = False;
+
+ if (! screen->doOpaqueMove()) {
+ /* when drawing the rubber band, we need to make sure we only draw inside
+ * the frame... frame.changing_* contain the new coords for the window,
+ * so we need to subtract 1 from changing_w/changing_h every where we
+ * draw the rubber band (for both moving and resizing)
+ */
+ XDrawRectangle(blackbox->getXDisplay(), screen->getRootWindow(),
+ screen->getOpGC(), frame.changing.x(), frame.changing.y(),
+ frame.changing.width() - 1, frame.changing.height() - 1);
+ XUngrabServer(blackbox->getXDisplay());
+
+ configure(frame.changing.x(), frame.changing.y(),
+ frame.changing.width(), frame.changing.height());
+ } else {
+ configure(frame.rect.x(), frame.rect.y(),
+ frame.rect.width(), frame.rect.height());
+ }
+ screen->hideGeometry();
+ XUngrabPointer(blackbox->getXDisplay(), CurrentTime);
+ } else if (flags.resizing) {
+ XDrawRectangle(blackbox->getXDisplay(), screen->getRootWindow(),
+ screen->getOpGC(), frame.changing.x(), frame.changing.y(),
+ frame.changing.width() - 1, frame.changing.height() - 1);
+ XUngrabServer(blackbox->getXDisplay());
- if (! screen->opaqueMove()) {
- openbox.grab();
+ screen->hideGeometry();
- frame.move_x = frame.x;
- frame.move_y = frame.y;
- frame.resize_w = frame.width + (frame.border_w * 2);
- frame.resize_h = ((flags.shaded) ? frame.title_h : frame.height) +
- (frame.border_w * 2);
+ constrain((re->window == frame.left_grip) ? TopRight : TopLeft);
- screen->showPosition(frame.x, frame.y);
+ // unset maximized state when resized after fully maximized
+ if (flags.maximized == 1)
+ maximize(0);
+ flags.resizing = False;
+ configure(frame.changing.x(), frame.changing.y(),
+ frame.changing.width(), frame.changing.height());
- XDrawRectangle(display, screen->getRootWindow(), screen->getOpGC(),
- frame.move_x, frame.move_y,
- frame.resize_w - 1, frame.resize_h - 1);
+ XUngrabPointer(blackbox->getXDisplay(), CurrentTime);
+ } else if (re->window == frame.window) {
+ if (re->button == 2 && re->state == Mod1Mask)
+ XUngrabPointer(blackbox->getXDisplay(), CurrentTime);
}
- frame.grab_x = x - frame.x - frame.border_w;
- frame.grab_y = y - frame.y - frame.border_w;
}
-void OpenboxWindow::doMove(int x, int y) {
- ASSERT(flags.moving);
-
- int dx = x - frame.grab_x, dy = y - frame.grab_y;
-
- dx -= frame.border_w;
- dy -= frame.border_w;
-
- int snap_distance = screen->edgeSnapThreshold();
- // width/height of the snapping window
- unsigned int snap_w = frame.width + (frame.border_w * 2);
- unsigned int snap_h = area().h() + (frame.border_w * 2);
- if (snap_distance) {
- int drx = screen->size().w() - (dx + snap_w);
-
- if (dx < drx && (dx > 0 && dx < snap_distance) ||
- (dx < 0 && dx > -snap_distance) )
- dx = 0;
- else if ( (drx > 0 && drx < snap_distance) ||
- (drx < 0 && drx > -snap_distance) )
- dx = screen->size().w() - snap_w;
-
- int dtty, dbby, dty, dby;
- switch (screen->getToolbar()->placement()) {
- case Toolbar::TopLeft:
- case Toolbar::TopCenter:
- case Toolbar::TopRight:
- dtty = screen->getToolbar()->getExposedHeight() +
- frame.border_w;
- dbby = screen->size().h();
- break;
-
- default:
- dtty = 0;
- dbby = screen->getToolbar()->area().y();
- break;
- }
-
- dty = dy - dtty;
- dby = dbby - (dy + snap_h);
-
- if ( (dy > 0 && dty < snap_distance) ||
- (dy < 0 && dty > -snap_distance) )
- dy = dtty;
- else if ( (dby > 0 && dby < snap_distance) ||
- (dby < 0 && dby > -snap_distance) )
- dy = dbby - snap_h;
- }
-
- if (screen->opaqueMove()) {
- configure(dx, dy, frame.width, frame.height);
- } else {
- XDrawRectangle(display, screen->getRootWindow(), screen->getOpGC(),
- frame.move_x, frame.move_y, frame.resize_w - 1,
- frame.resize_h - 1);
-
- frame.move_x = dx;
- frame.move_y = dy;
-
- XDrawRectangle(display, screen->getRootWindow(), screen->getOpGC(),
- frame.move_x, frame.move_y, frame.resize_w - 1,
- frame.resize_h - 1);
- }
-
- screen->showPosition(dx, dy);
-}
+void BlackboxWindow::motionNotifyEvent(XMotionEvent *me) {
+ if (!flags.resizing && (me->state & Button1Mask) &&
+ (functions & Func_Move) &&
+ (frame.title == me->window || frame.label == me->window ||
+ frame.handle == me->window || frame.window == me->window)) {
+ if (! flags.moving) {
+ XGrabPointer(blackbox->getXDisplay(), me->window, False,
+ Button1MotionMask | ButtonReleaseMask,
+ GrabModeAsync, GrabModeAsync,
+ None, blackbox->getMoveCursor(), CurrentTime);
+ if (windowmenu && windowmenu->isVisible())
+ windowmenu->hide();
-void OpenboxWindow::endMove() {
- ASSERT(flags.moving);
+ flags.moving = True;
- flags.moving = False;
+ if (! screen->doOpaqueMove()) {
+ XGrabServer(blackbox->getXDisplay());
- openbox.maskWindowEvents(0, (OpenboxWindow *) 0);
- if (!screen->opaqueMove()) {
- XDrawRectangle(display, screen->getRootWindow(), screen->getOpGC(),
- frame.move_x, frame.move_y, frame.resize_w - 1,
- frame.resize_h - 1);
+ frame.changing = frame.rect;
+ screen->showPosition(frame.changing.x(), frame.changing.y());
- configure(frame.move_x, frame.move_y, frame.width, frame.height);
- openbox.ungrab();
- } else {
- configure(frame.x, frame.y, frame.width, frame.height);
- }
- screen->hideGeometry();
- XUngrabPointer(display, CurrentTime);
- // if there are any left over motions from the move, drop them now cuz they
- // cause problems
- XEvent e;
- while (XCheckTypedWindowEvent(display, frame.window, MotionNotify, &e));
-}
+ XDrawRectangle(blackbox->getXDisplay(), screen->getRootWindow(),
+ screen->getOpGC(),
+ frame.changing.x(),
+ frame.changing.y(),
+ frame.changing.width() - 1,
+ frame.changing.height() - 1);
+ }
+ } else {
+ int dx = me->x_root - frame.grab_x, dy = me->y_root - frame.grab_y;
+ dx -= frame.border_w;
+ dy -= frame.border_w;
+
+ const int snap_distance = screen->getEdgeSnapThreshold();
+
+ if (snap_distance) {
+ Rect srect = screen->availableArea();
+ // window corners
+ const int wleft = dx,
+ wright = dx + frame.rect.width() - 1,
+ wtop = dy,
+ wbottom = dy + frame.rect.height() - 1;
+
+ int dleft = std::abs(wleft - srect.left()),
+ dright = std::abs(wright - srect.right()),
+ dtop = std::abs(wtop - srect.top()),
+ dbottom = std::abs(wbottom - srect.bottom());
+
+ // snap left?
+ if (dleft < snap_distance && dleft < dright)
+ dx = srect.left();
+ // snap right?
+ else if (dright < snap_distance && dright < dleft)
+ dx = srect.right() - frame.rect.width() + 1;
+
+ // snap top?
+ if (dtop < snap_distance && dtop < dbottom)
+ dy = srect.top();
+ // snap bottom?
+ else if (dbottom < snap_distance && dbottom < dtop)
+ dy = srect.bottom() - frame.rect.height() + 1;
+
+ srect = screen->getRect(); // now get the full screen
+
+ dleft = std::abs(wleft - srect.left()),
+ dright = std::abs(wright - srect.right()),
+ dtop = std::abs(wtop - srect.top()),
+ dbottom = std::abs(wbottom - srect.bottom());
+
+ // snap left?
+ if (dleft < snap_distance && dleft < dright)
+ dx = srect.left();
+ // snap right?
+ else if (dright < snap_distance && dright < dleft)
+ dx = srect.right() - frame.rect.width() + 1;
+
+ // snap top?
+ if (dtop < snap_distance && dtop < dbottom)
+ dy = srect.top();
+ // snap bottom?
+ else if (dbottom < snap_distance && dbottom < dtop)
+ dy = srect.bottom() - frame.rect.height() + 1;
+ }
+ if (screen->doOpaqueMove()) {
+ configure(dx, dy, frame.rect.width(), frame.rect.height());
+ } else {
+ XDrawRectangle(blackbox->getXDisplay(), screen->getRootWindow(),
+ screen->getOpGC(),
+ frame.changing.x(),
+ frame.changing.y(),
+ frame.changing.width() - 1,
+ frame.changing.height() - 1);
+
+ frame.changing.setPos(dx, dy);
+
+ XDrawRectangle(blackbox->getXDisplay(), screen->getRootWindow(),
+ screen->getOpGC(),
+ frame.changing.x(),
+ frame.changing.y(),
+ frame.changing.width() - 1,
+ frame.changing.height() - 1);
+ }
-void OpenboxWindow::motionNotifyEvent(XMotionEvent *me) {
- if (flags.moving)
- doMove(me->x_root, me->y_root);
- else if (!flags.resizing && (me->state & Button1Mask) && functions.move &&
- (frame.title == me->window || frame.label == me->window ||
- frame.handle == me->window || frame.window == me->window))
- startMove(me->x_root, me->y_root);
- else if (functions.resize &&
- (((me->state & Button1Mask) && (me->window == frame.right_grip ||
- me->window == frame.left_grip)) ||
- (me->state == (Mod1Mask | Button3Mask) &&
- me->window == frame.window))) {
- Bool left = resize_zone & ZoneLeft;
+ screen->showPosition(dx, dy);
+ }
+ } else if ((functions & Func_Resize) &&
+ (((me->state & Button1Mask) &&
+ (me->window == frame.right_grip ||
+ me->window == frame.left_grip)) ||
+ (me->state & (Mod1Mask | Button3Mask) &&
+ me->window == frame.window))) {
+ bool left = (me->window == frame.left_grip);
if (! flags.resizing) {
- Cursor cursor;
- if (resize_zone & ZoneTop)
- cursor = (resize_zone & ZoneLeft) ?
- openbox.getUpperLeftAngleCursor() :
- openbox.getUpperRightAngleCursor();
- else
- cursor = (resize_zone & ZoneLeft) ?
- openbox.getLowerLeftAngleCursor() :
- openbox.getLowerRightAngleCursor();
- XGrabPointer(display, me->window, False, ButtonMotionMask |
- ButtonReleaseMask, GrabModeAsync, GrabModeAsync, None,
- cursor, CurrentTime);
+ XGrabServer(blackbox->getXDisplay());
+ XGrabPointer(blackbox->getXDisplay(), me->window, False,
+ ButtonMotionMask | ButtonReleaseMask,
+ GrabModeAsync, GrabModeAsync, None,
+ ((left) ? blackbox->getLowerLeftAngleCursor() :
+ blackbox->getLowerRightAngleCursor()),
+ CurrentTime);
flags.resizing = True;
- openbox.grab();
+ int gw, gh;
+ frame.grab_x = me->x;
+ frame.grab_y = me->y;
+ frame.changing = frame.rect;
- int gx, gy;
- if (resize_zone & ZoneRight)
- frame.grab_x = me->x - screen->getBorderWidth();
- else
- frame.grab_x = me->x + screen->getBorderWidth();
- if (resize_zone & ZoneTop)
- frame.grab_y = me->y + screen->getBorderWidth() * 2;
- else
- frame.grab_y = me->y - screen->getBorderWidth() * 2;
- frame.resize_x = frame.x;
- frame.resize_y = frame.y;
- frame.resize_w = frame.width + (frame.border_w * 2);
- frame.resize_h = frame.height + (frame.border_w * 2);
-
- if (left)
- left_fixsize(&gx, &gy);
- else
- right_fixsize(&gx, &gy);
+ constrain((left) ? TopRight : TopLeft, &gw, &gh);
- screen->showGeometry(gx, gy);
+ XDrawRectangle(blackbox->getXDisplay(), screen->getRootWindow(),
+ screen->getOpGC(), frame.changing.x(), frame.changing.y(),
+ frame.changing.width() - 1, frame.changing.height() - 1);
- XDrawRectangle(display, screen->getRootWindow(), screen->getOpGC(),
- frame.resize_x, frame.resize_y,
- frame.resize_w - 1, frame.resize_h - 1);
+ screen->showGeometry(gw, gh);
} else {
- XDrawRectangle(display, screen->getRootWindow(), screen->getOpGC(),
- frame.resize_x, frame.resize_y,
- frame.resize_w - 1, frame.resize_h - 1);
+ XDrawRectangle(blackbox->getXDisplay(), screen->getRootWindow(),
+ screen->getOpGC(), frame.changing.x(), frame.changing.y(),
+ frame.changing.width() - 1, frame.changing.height() - 1);
- int gx, gy;
+ int gw, gh;
- if (resize_zone & ZoneTop)
- frame.resize_h = frame.height - (me->y - frame.grab_y);
- else
- frame.resize_h = frame.height + (me->y - frame.grab_y);
- if (frame.resize_h < 1) frame.resize_h = 1;
+ Corner anchor;
if (left) {
- frame.resize_x = me->x_root - frame.grab_x;
- if (frame.resize_x > (signed) (frame.x + frame.width))
- frame.resize_x = frame.resize_x + frame.width - 1;
-
- left_fixsize(&gx, &gy);
+ anchor = TopRight;
+ frame.changing.setCoords(me->x_root - frame.grab_x, frame.rect.top(),
+ frame.rect.right(), frame.rect.bottom());
+ frame.changing.setHeight(frame.rect.height() + (me->y - frame.grab_y));
} else {
- frame.resize_w = frame.width + (me->x - frame.grab_x);
- if (frame.resize_w < 1) frame.resize_w = 1;
-
- right_fixsize(&gx, &gy);
+ anchor = TopLeft;
+ frame.changing.setSize(frame.rect.width() + (me->x - frame.grab_x),
+ frame.rect.height() + (me->y - frame.grab_y));
}
- XDrawRectangle(display, screen->getRootWindow(), screen->getOpGC(),
- frame.resize_x, frame.resize_y,
- frame.resize_w - 1, frame.resize_h - 1);
+ constrain(anchor, &gw, &gh);
+
+ XDrawRectangle(blackbox->getXDisplay(), screen->getRootWindow(),
+ screen->getOpGC(), frame.changing.x(), frame.changing.y(),
+ frame.changing.width() - 1, frame.changing.height() - 1);
- screen->showGeometry(gx, gy);
+ screen->showGeometry(gw, gh);
}
}
}
#ifdef SHAPE
-void OpenboxWindow::shapeEvent(XShapeEvent *) {
- if (openbox.hasShapeExtensions()) {
- if (flags.shaped) {
- openbox.grab();
- if (! validateClient()) return;
- XShapeCombineShape(display, frame.window, ShapeBounding,
- frame.mwm_border_w, frame.y_border +
- frame.mwm_border_w, client.window,
- ShapeBounding, ShapeSet);
-
- int num = 1;
- XRectangle xrect[2];
- xrect[0].x = xrect[0].y = 0;
- xrect[0].width = frame.width;
- xrect[0].height = frame.y_border;
-
- if (decorations.handle) {
- xrect[1].x = 0;
- xrect[1].y = frame.y_handle;
- xrect[1].width = frame.width;
- xrect[1].height = frame.handle_h + frame.border_w;
- num++;
- }
-
- XShapeCombineRectangles(display, frame.window, ShapeBounding, 0, 0,
- xrect, num, ShapeUnion, Unsorted);
- openbox.ungrab();
- }
+void BlackboxWindow::shapeEvent(XShapeEvent *) {
+ if (blackbox->hasShapeExtensions() && flags.shaped) {
+ configureShape();
}
}
#endif // SHAPE
-bool OpenboxWindow::validateClient(void) {
- XSync(display, False);
+bool BlackboxWindow::validateClient(void) {
+ XSync(blackbox->getXDisplay(), False);
XEvent e;
- if (XCheckTypedWindowEvent(display, client.window, DestroyNotify, &e) ||
- XCheckTypedWindowEvent(display, client.window, UnmapNotify, &e)) {
- XPutBackEvent(display, &e);
- openbox.ungrab();
+ if (XCheckTypedWindowEvent(blackbox->getXDisplay(), client.window,
+ DestroyNotify, &e) ||
+ XCheckTypedWindowEvent(blackbox->getXDisplay(), client.window,
+ UnmapNotify, &e)) {
+ XPutBackEvent(blackbox->getXDisplay(), &e);
- return false;
+ return False;
}
- return true;
+ return True;
}
-void OpenboxWindow::restore(void) {
- XChangeSaveSet(display, client.window, SetModeDelete);
- XSelectInput(display, client.window, NoEventMask);
+void BlackboxWindow::restore(bool remap) {
+ XChangeSaveSet(blackbox->getXDisplay(), client.window, SetModeDelete);
+ XSelectInput(blackbox->getXDisplay(), client.window, NoEventMask);
+ XSelectInput(blackbox->getXDisplay(), frame.plate, NoEventMask);
restoreGravity();
- XUnmapWindow(display, frame.window);
- XUnmapWindow(display, client.window);
+ XUnmapWindow(blackbox->getXDisplay(), frame.window);
+ XUnmapWindow(blackbox->getXDisplay(), client.window);
- XSetWindowBorderWidth(display, client.window, client.old_bw);
- XReparentWindow(display, client.window, screen->getRootWindow(),
- client.x, client.y);
- XMapWindow(display, client.window);
+ XSetWindowBorderWidth(blackbox->getXDisplay(), client.window, client.old_bw);
- XFlush(display);
+ XEvent ev;
+ if (! XCheckTypedWindowEvent(blackbox->getXDisplay(), client.window,
+ ReparentNotify, &ev)) {
+ // according to the ICCCM - if the client doesn't reparent to
+ // root, then we have to do it for them
+ XReparentWindow(blackbox->getXDisplay(), client.window,
+ screen->getRootWindow(),
+ client.rect.x(), client.rect.y());
+ }
- delete this;
+ if (remap) XMapWindow(blackbox->getXDisplay(), client.window);
}
-void OpenboxWindow::timeout(void) {
- screen->getWorkspace(workspace_number)->raiseWindow(this);
+// timer for autoraise
+void BlackboxWindow::timeout(void) {
+ screen->getWorkspace(blackbox_attrib.workspace)->raiseWindow(this);
}
-void OpenboxWindow::changeOpenboxHints(OpenboxHints *net) {
+void BlackboxWindow::changeBlackboxHints(BlackboxHints *net) {
if ((net->flags & AttribShaded) &&
- ((openbox_attrib.attrib & AttribShaded) !=
+ ((blackbox_attrib.attrib & AttribShaded) !=
(net->attrib & AttribShaded)))
shade();
if (flags.visible && // watch out for requests when we can not be seen
(net->flags & (AttribMaxVert | AttribMaxHoriz)) &&
- ((openbox_attrib.attrib & (AttribMaxVert | AttribMaxHoriz)) !=
+ ((blackbox_attrib.attrib & (AttribMaxVert | AttribMaxHoriz)) !=
(net->attrib & (AttribMaxVert | AttribMaxHoriz)))) {
if (flags.maximized) {
maximize(0);
}
if ((net->flags & AttribOmnipresent) &&
- ((openbox_attrib.attrib & AttribOmnipresent) !=
+ ((blackbox_attrib.attrib & AttribOmnipresent) !=
(net->attrib & AttribOmnipresent)))
stick();
if ((net->flags & AttribWorkspace) &&
- (workspace_number != (signed) net->workspace)) {
+ (blackbox_attrib.workspace != net->workspace)) {
screen->reassociateWindow(this, net->workspace, True);
- if (screen->getCurrentWorkspaceID() != (signed) net->workspace) withdraw();
- else deiconify();
+ if (screen->getCurrentWorkspaceID() != net->workspace) {
+ withdraw();
+ } else {
+ show();
+ screen->getWorkspace(blackbox_attrib.workspace)->raiseWindow(this);
+ }
}
if (net->flags & AttribDecoration) {
switch (net->decoration) {
case DecorNone:
- decorations.titlebar = decorations.border = decorations.handle =
- decorations.iconify = decorations.maximize = decorations.menu = False;
+ // clear all decorations except close
+ decorations &= Decor_Close;
break;
default:
case DecorNormal:
- decorations.titlebar = decorations.iconify = decorations.menu =
- decorations.border = True;
- decorations.handle = (functions.resize && !flags.transient);
- decorations.maximize = functions.maximize;
+ decorations |= Decor_Titlebar | Decor_Handle | Decor_Border |
+ Decor_Iconify | Decor_Maximize;
break;
case DecorTiny:
- decorations.titlebar = decorations.iconify = decorations.menu = True;
- decorations.border = decorations.border = decorations.handle = False;
- decorations.maximize = functions.maximize;
+ decorations |= Decor_Titlebar | Decor_Iconify;
+ decorations &= ~(Decor_Border | Decor_Handle | Decor_Maximize);
break;
case DecorTool:
- decorations.titlebar = decorations.menu = True;
- decorations.iconify = decorations.border = False;
- decorations.handle = (functions.resize && !flags.transient);
- decorations.maximize = functions.maximize;
+ decorations |= Decor_Titlebar;
+ decorations &= ~(Decor_Iconify | Decor_Border | Decor_Handle);
+ functions |= Func_Move;
break;
}
if (frame.window) {
- XMapSubwindows(display, frame.window);
- XMapWindow(display, frame.window);
+ XMapSubwindows(blackbox->getXDisplay(), frame.window);
+ XMapWindow(blackbox->getXDisplay(), frame.window);
}
reconfigure();
* Set the sizes of all components of the window frame
* (the window decorations).
* These values are based upon the current style settings and the client
- * window's dimentions.
+ * window's dimensions.
*/
-void OpenboxWindow::upsize(void) {
+void BlackboxWindow::upsize(void) {
frame.bevel_w = screen->getBevelWidth();
- if (decorations.border) {
+ if (decorations & Decor_Border) {
frame.border_w = screen->getBorderWidth();
- if (!flags.transient)
+ if (!isTransient())
frame.mwm_border_w = screen->getFrameWidth();
else
frame.mwm_border_w = 0;
frame.mwm_border_w = frame.border_w = 0;
}
- if (decorations.titlebar) {
+ if (decorations & Decor_Titlebar) {
// the height of the titlebar is based upon the height of the font being
// used to display the window's title
WindowStyle *style = screen->getWindowStyle();
(frame.bevel_w * 2) + 2);
frame.label_h = frame.title_h - (frame.bevel_w * 2);
- frame.button_w = frame.button_h = (frame.label_h - 2);
- frame.y_border = frame.title_h + frame.border_w;
+ frame.button_w = (frame.label_h - 2);
+
+ // set the top frame margin
+ frame.margin.top = frame.border_w + frame.title_h +
+ frame.border_w + frame.mwm_border_w;
} else {
frame.title_h = 0;
frame.label_h = 0;
- frame.button_w = frame.button_h = 0;
- frame.y_border = 0;
+ frame.button_w = 0;
+
+ // set the top frame margin
+ frame.margin.top = frame.border_w + frame.mwm_border_w;
}
- frame.border_h = client.height + frame.mwm_border_w * 2;
+ // set the left/right frame margin
+ frame.margin.left = frame.margin.right = frame.border_w + frame.mwm_border_w;
- if (decorations.handle) {
- frame.y_handle = frame.y_border + frame.border_h + frame.border_w;
+ if (decorations & Decor_Handle) {
frame.grip_w = frame.button_w * 2;
- frame.grip_h = frame.handle_h = screen->getHandleWidth();
+ frame.handle_h = screen->getHandleWidth();
+
+ // set the bottom frame margin
+ frame.margin.bottom = frame.border_w + frame.handle_h +
+ frame.border_w + frame.mwm_border_w;
} else {
- frame.y_handle = frame.y_border + frame.border_h;
frame.handle_h = 0;
- frame.grip_w = frame.grip_h = 0;
+ frame.grip_w = 0;
+
+ // set the bottom frame margin
+ frame.margin.bottom = frame.border_w + frame.mwm_border_w;
}
- frame.width = client.width + (frame.mwm_border_w * 2);
- frame.height = frame.y_handle + frame.handle_h;
+ // set the frame rect
+ frame.rect.setSize(client.rect.width() + frame.margin.left +
+ frame.margin.right,
+ client.rect.height() + frame.margin.top +
+ frame.margin.bottom);
+ frame.inside_w = frame.rect.width() - (frame.border_w * 2);
+ frame.inside_h = frame.rect.height() - (frame.border_w * 2);
}
/*
- * Set the size and position of the client window.
- * These values are based upon the current style settings and the frame
- * window's dimensions.
+ * Calculate the size of the client window and constrain it to the
+ * size specified by the size hints of the client window.
+ *
+ * The logical width and height are placed into pw and ph, if they
+ * are non-zero. Logical size refers to the users perception of
+ * the window size (for example an xterm has resizes in cells, not in
+ * pixels).
+ *
+ * The physical geometry is placed into frame.changing_{x,y,width,height}.
+ * Physical geometry refers to the geometry of the window in pixels.
*/
-void OpenboxWindow::downsize(void) {
- frame.y_handle = frame.height - frame.handle_h;
- frame.border_h = frame.y_handle - frame.y_border -
- (decorations.handle ? frame.border_w : 0);
+void BlackboxWindow::constrain(Corner anchor, int *pw, int *ph) {
+ // frame.changing represents the requested frame size, we need to
+ // strip the frame margin off and constrain the client size
+ frame.changing.setCoords(frame.changing.left() + frame.margin.left,
+ frame.changing.top() + frame.margin.top,
+ frame.changing.right() - frame.margin.right,
+ frame.changing.bottom() - frame.margin.bottom);
+
+ int dw = frame.changing.width(), dh = frame.changing.height(),
+ base_width = (client.base_width) ? client.base_width : client.min_width,
+ base_height = (client.base_height) ? client.base_height :
+ client.min_height;
+
+ // constrain
+ if (dw < static_cast<signed>(client.min_width)) dw = client.min_width;
+ if (dh < static_cast<signed>(client.min_height)) dh = client.min_height;
+ if (dw > static_cast<signed>(client.max_width)) dw = client.max_width;
+ if (dh > static_cast<signed>(client.max_height)) dh = client.max_height;
+
+ dw -= base_width;
+ dw /= client.width_inc;
+ dh -= base_height;
+ dh /= client.height_inc;
+
+ if (pw) *pw = dw;
+ if (ph) *ph = dh;
+
+ dw *= client.width_inc;
+ dw += base_width;
+ dh *= client.height_inc;
+ dh += base_height;
+
+ frame.changing.setSize(dw, dh);
+
+ // add the frame margin back onto frame.changing
+ frame.changing.setCoords(frame.changing.left() - frame.margin.left,
+ frame.changing.top() - frame.margin.top,
+ frame.changing.right() + frame.margin.right,
+ frame.changing.bottom() + frame.margin.bottom);
+
+ // move frame.changing to the specified anchor
+ switch (anchor) {
+ case TopLeft:
+ // nothing to do
+ break;
- client.x = frame.x + frame.mwm_border_w + frame.border_w;
- client.y = frame.y + frame.y_border + frame.mwm_border_w + frame.border_w;
+ case TopRight:
+ int dx = frame.rect.right() - frame.changing.right();
+ frame.changing.setPos(frame.changing.x() + dx, frame.changing.y());
+ break;
+ }
+}
- client.width = frame.width - (frame.mwm_border_w * 2);
- client.height = frame.height - frame.y_border - (frame.mwm_border_w * 2)
- - frame.handle_h - (decorations.handle ? frame.border_w : 0);
- frame.y_handle = frame.border_h + frame.y_border + frame.border_w;
-}
+int WindowStyle::doJustify(const char *text, int &start_pos,
+ unsigned int max_length, unsigned int modifier,
+ bool multibyte) const {
+ size_t text_len = strlen(text);
+ unsigned int length;
+ do {
+ if (multibyte) {
+ XRectangle ink, logical;
+ XmbTextExtents(fontset, text, text_len, &ink, &logical);
+ length = logical.width;
+ } else {
+ length = XTextWidth(font, text, text_len);
+ }
+ length += modifier;
+ } while (length > max_length && text_len-- > 0);
-void OpenboxWindow::right_fixsize(int *gx, int *gy) {
- // calculate the size of the client window and conform it to the
- // size specified by the size hints of the client window...
- int dx = 1 + frame.resize_w - client.base_width - (frame.mwm_border_w * 2) -
- (frame.border_w * 2) + (client.width_inc / 2);
- int dy = 1 + frame.resize_h - frame.y_border - client.base_height -
- frame.handle_h - (frame.border_w * 3) - (frame.mwm_border_w * 2)
- + (client.height_inc / 2);
+ switch (justify) {
+ case RightJustify:
+ start_pos += max_length - length;
+ break;
- if (dx < (signed) client.min_width) dx = client.min_width;
- if (dy < (signed) client.min_height) dy = client.min_height;
- if ((unsigned) dx > client.max_width) dx = client.max_width;
- if ((unsigned) dy > client.max_height) dy = client.max_height;
+ case CenterJustify:
+ start_pos += (max_length - length) / 2;
+ break;
- dx /= client.width_inc;
- dy /= client.height_inc;
+ case LeftJustify:
+ default:
+ break;
+ }
- if (gx) *gx = dx;
- if (gy) *gy = dy;
+ return text_len;
+}
- dx = (dx * client.width_inc) + client.base_width;
- dy = (dy * client.height_inc) + client.base_height;
- frame.resize_w = dx + (frame.mwm_border_w * 2) + (frame.border_w * 2) - 1;
- frame.resize_h = dy + frame.y_border + frame.handle_h +
- (frame.mwm_border_w * 2) + (frame.border_w * 3) - 1;
- if (resize_zone & ZoneTop)
- frame.resize_y = frame.y + frame.height - frame.resize_h +
- screen->getBorderWidth() * 2;
+BWindowGroup::BWindowGroup(Blackbox *b, Window _group)
+ : blackbox(b), group(_group) {
+ // watch for destroy notify on the group window
+ XSelectInput(blackbox->getXDisplay(), group, StructureNotifyMask);
+ blackbox->saveGroupSearch(group, this);
}
-void OpenboxWindow::left_fixsize(int *gx, int *gy) {
- // calculate the size of the client window and conform it to the
- // size specified by the size hints of the client window...
- int dx = 1 + frame.x + frame.width - frame.resize_x - client.base_width -
- (frame.mwm_border_w * 2) + (client.width_inc / 2);
- int dy = 1 + frame.resize_h - frame.y_border - client.base_height -
- frame.handle_h - (frame.border_w * 3) - (frame.mwm_border_w * 2)
- + (client.height_inc / 2);
+BWindowGroup::~BWindowGroup(void) {
+ blackbox->removeGroupSearch(group);
+}
+
- if (dx < (signed) client.min_width) dx = client.min_width;
- if (dy < (signed) client.min_height) dy = client.min_height;
- if ((unsigned) dx > client.max_width) dx = client.max_width;
- if ((unsigned) dy > client.max_height) dy = client.max_height;
+BlackboxWindow *
+BWindowGroup::find(BScreen *screen, bool allow_transients) const {
+ BlackboxWindow *ret = blackbox->getFocusedWindow();
- dx /= client.width_inc;
- dy /= client.height_inc;
+ // does the focus window match (or any transient_fors)?
+ while (ret) {
+ if (ret->getScreen() == screen && ret->getGroupWindow() == group) {
+ if (ret->isTransient() && allow_transients) break;
+ else if (! ret->isTransient()) break;
+ }
- if (gx) *gx = dx;
- if (gy) *gy = dy;
+ ret = ret->getTransientFor();
+ }
- dx = (dx * client.width_inc) + client.base_width;
- dy = (dy * client.height_inc) + client.base_height;
+ if (ret) return ret;
- frame.resize_w = dx + (frame.mwm_border_w * 2) + (frame.border_w * 2) - 1;
- frame.resize_x = frame.x + frame.width - frame.resize_w +
- (frame.border_w * 2);
- frame.resize_h = dy + frame.y_border + frame.handle_h +
- (frame.mwm_border_w * 2) + (frame.border_w * 3) - 1;
- if (resize_zone & ZoneTop)
- frame.resize_y = frame.y + frame.height - frame.resize_h +
- screen->getBorderWidth() * 2;
+ // the focus window didn't match, look in the group's window list
+ BlackboxWindowList::const_iterator it, end = windowList.end();
+ for (it = windowList.begin(); it != end; ++it) {
+ ret = *it;
+ if (ret->getScreen() == screen && ret->getGroupWindow() == group) {
+ if (ret->isTransient() && allow_transients) break;
+ else if (! ret->isTransient()) break;
+ }
+ }
+ return ret;
}
+++ /dev/null
-// Window.h for Openbox
-// Copyright (c) 2001 Sean 'Shaleh' Perry <shaleh@debian.org>
-// Copyright (c) 1997 - 2000 Brad Hughes (bhughes@tcac.net)
-//
-// Permission is hereby granted, free of charge, to any person obtaining a
-// copy of this software and associated documentation files (the "Software"),
-// to deal in the Software without restriction, including without limitation
-// the rights to use, copy, modify, merge, publish, distribute, sublicense,
-// and/or sell copies of the Software, and to permit persons to whom the
-// Software is furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-// DEALINGS IN THE SOFTWARE.
-
-#ifndef __Window_hh
-#define __Window_hh
-
-#include <X11/Xlib.h>
-#include <X11/Xutil.h>
-#ifdef SHAPE
-# include <X11/extensions/shape.h>
-#endif // SHAPE
-
-#include "BaseDisplay.h"
-#include "Timer.h"
-#include "Windowmenu.h"
-#include "Geometry.h"
-
-// forward declaration
-class OpenboxWindow;
-
-#define MwmHintsFunctions (1l << 0)
-#define MwmHintsDecorations (1l << 1)
-
-#define MwmFuncAll (1l << 0)
-#define MwmFuncResize (1l << 1)
-#define MwmFuncMove (1l << 2)
-#define MwmFuncIconify (1l << 3)
-#define MwmFuncMaximize (1l << 4)
-#define MwmFuncClose (1l << 5)
-
-#define MwmDecorAll (1l << 0)
-#define MwmDecorBorder (1l << 1)
-#define MwmDecorHandle (1l << 2)
-#define MwmDecorTitle (1l << 3)
-#define MwmDecorMenu (1l << 4)
-#define MwmDecorIconify (1l << 5)
-#define MwmDecorMaximize (1l << 6)
-
-// this structure only contains 3 elements... the Motif 2.0 structure contains
-// 5... we only need the first 3... so that is all we will define
-typedef struct MwmHints {
- unsigned long flags, functions, decorations;
-} MwmHints;
-
-#define PropMwmHintsElements 3
-
-
-class OpenboxWindow : public TimeoutHandler {
-private:
- BImageControl *image_ctrl;
- Openbox &openbox;
- BScreen *screen;
- Display *display;
- BTimer *timer;
- OpenboxAttributes openbox_attrib;
-
- Time lastButtonPressTime; // used for double clicks, when were we clicked
- Windowmenu *windowmenu;
-
- int window_number, workspace_number;
- unsigned long current_state;
- bool place_window; // place the window ourselves when mapped
-
- enum FocusMode { F_NoInput = 0, F_Passive,
- F_LocallyActive, F_GloballyActive };
- FocusMode focus_mode;
-
- enum ResizeZones {
- ZoneTop = 1 << 0,
- ZoneBottom = 1 << 1,
- ZoneLeft = 1 << 2,
- ZoneRight = 1 << 3
- };
- unsigned int resize_zone; // bitmask of ResizeZones values
-
- struct _flags {
- Bool moving, // is moving?
- resizing, // is resizing?
- shaded, // is shaded?
- visible, // is visible?
- iconic, // is iconified?
- transient, // is a transient window?
- focused, // has focus?
- stuck, // is omnipresent
- modal, // is modal? (must be dismissed to continue)
- send_focus_message, // should we send focus messages to our client?
- shaped, // does the frame use the shape extension?
- managed; // under openbox's control?
- // maximize is special, the number corresponds
- // with a mouse button
- // if 0, not maximized
- unsigned int maximized; // 1 = HorizVert, 2 = Vertical, 3 = Horizontal
- } flags;
-
- struct _client {
- OpenboxWindow *transient_for, // which window are we a transient for?
- *transient; // which window is our transient?
-
- Window window, // the client's window
- window_group; // the client's window group
-
- char *title, *icon_title;
- size_t title_len; // strlen(title)
-
- int x, y,
- old_bw; // client's borderwidth
-
- unsigned int width, height,
- title_text_w, // width as rendered in the current font
- min_width, min_height, // can not be resized smaller
- max_width, max_height, // can not be resized larger
- width_inc, height_inc, // increment step
- min_aspect_x, min_aspect_y, // minimum aspect ratio
- max_aspect_x, max_aspect_y, // maximum aspect ratio
- base_width, base_height,
- win_gravity;
-
- unsigned long initial_state, normal_hint_flags, wm_hint_flags;
-
- MwmHints *mwm_hint;
- OpenboxHints *openbox_hint;
- } client;
-
- struct _functions {
- Bool resize, move, iconify, maximize, close;
- } functions;
-
- /*
- * client window = the application's window
- * frame window = the window drawn around the outside of the client window
- * by the window manager which contains items like the
- * titlebar and close button
- * title = the titlebar drawn above the client window, it displays the
- * window's name and any buttons for interacting with the window,
- * such as iconify, maximize, and close
- * label = the window in the titlebar where the title is drawn
- * buttons = maximize, iconify, close
- * handle = the bar drawn at the bottom of the window, which contains the
- * left and right grips used for resizing the window
- * grips = the smaller reactangles in the handle, one of each side of it.
- * When clicked and dragged, these resize the window interactively
- * border = the line drawn around the outside edge of the frame window,
- * between the title, the bordered client window, and the handle.
- * Also drawn between the grips and the handle
- */
-
- /*
- * what decorations do we have?
- * this is based on the type of the client window as well as user input
- * the menu is not really decor, but it goes hand in hand with the decor
- */
- struct _decorations {
- Bool titlebar, handle, border, iconify, maximize, close, menu;
- } decorations;
-
- struct _frame {
- // u -> unfocused, f -> has focus
- unsigned long ulabel_pixel, flabel_pixel, utitle_pixel,
- ftitle_pixel, uhandle_pixel, fhandle_pixel, ubutton_pixel,
- fbutton_pixel, pbutton_pixel, uborder_pixel, fborder_pixel,
- ugrip_pixel, fgrip_pixel;
- Pixmap ulabel, flabel, utitle, ftitle, uhandle, fhandle,
- ubutton, fbutton, pbutton, ugrip, fgrip;
-
- Window window, // the frame
- plate, // holds the client
- title,
- label,
- handle,
- close_button, iconify_button, maximize_button,
- right_grip, left_grip;
-
-
- unsigned int resize_w, resize_h;
- int resize_x, resize_y, // size and location of box drawn while resizing
- move_x, move_y; // location of box drawn while moving
-
- int x, y,
- grab_x, grab_y, // where was the window when it was grabbed?
- y_border, y_handle; // where within frame is the border and handle
-
- unsigned int width, height, title_h, label_w, label_h, handle_h,
- button_w, button_h, grip_w, grip_h, mwm_border_w, border_h, border_w,
- bevel_w;
- } frame;
-
-protected:
- Bool getState();
- Window createToplevelWindow(int x, int y, unsigned int width,
- unsigned int height, unsigned int borderwidth);
- Window createChildWindow(Window parent, Cursor = None);
-
- void getWMName();
- void getWMIconName();
- void getWMNormalHints();
- void getWMProtocols();
- void getWMHints();
- void getMWMHints();
- void getOpenboxHints();
- void setNetWMAttributes();
- void associateClientWindow();
- void decorate();
- void decorateLabel();
- void positionButtons();
- void positionWindows();
- void createCloseButton();
- void createIconifyButton();
- void createMaximizeButton();
- void redrawLabel();
- void redrawAllButtons();
- void redrawCloseButton(Bool);
- void redrawIconifyButton(Bool);
- void redrawMaximizeButton(Bool);
- void restoreGravity();
- void setGravityOffsets();
- void setState(unsigned long);
- void upsize();
- void downsize();
- void right_fixsize(int *gx = 0, int *gy = 0);
- void left_fixsize(int *gx = 0, int *gy = 0);
- void doMove(int x, int y);
-
-
-public:
- OpenboxWindow(Openbox &b, Window w, BScreen *s = (BScreen *) 0);
- virtual ~OpenboxWindow();
-
- inline Bool isTransient() const { return flags.transient; }
- inline Bool isFocused() const { return flags.focused; }
- inline Bool isVisible() const { return flags.visible; }
- inline Bool isIconic() const { return flags.iconic; }
- inline Bool isShaded() const { return flags.shaded; }
- inline Bool isMaximized() const { return flags.maximized; }
- inline Bool isMaximizedFull() const { return flags.maximized == 1; }
- inline Bool isStuck() const { return flags.stuck; }
- inline Bool isIconifiable() const { return functions.iconify; }
- inline Bool isMaximizable() const { return functions.maximize; }
- inline Bool isResizable() const { return functions.resize; }
- inline Bool isClosable() const { return functions.close; }
-
- inline Bool hasTitlebar() const { return decorations.titlebar; }
- inline Bool hasTransient() const
- { return ((client.transient) ? True : False); }
-
- inline OpenboxWindow *getTransient() { return client.transient; }
- inline OpenboxWindow *getTransientFor() { return client.transient_for; }
-
- inline BScreen *getScreen() { return screen; }
-
- inline const Window &getFrameWindow() const { return frame.window; }
- inline const Window &getClientWindow() const { return client.window; }
-
- inline Windowmenu * getWindowmenu() { return windowmenu; }
-
- inline char **getTitle() { return &client.title; }
- inline char **getIconTitle() { return &client.icon_title; }
- //inline const int &getXFrame() const { return frame.x; }
- //inline const int &getYFrame() const { return frame.y; }
- //inline const int &getXClient() const { return client.x; }
- //inline const int &getYClient() const { return client.y; }
- inline const int &getWorkspaceNumber() const { return workspace_number; }
- inline const int &getWindowNumber() const { return window_number; }
-
- //inline const unsigned int &getWidth() const { return frame.width; }
- //inline const unsigned int &getHeight() const {
- // if (!flags.shaded)
- // return frame.height;
- // else
- // return frame.title_h;
- //}
- //inline const unsigned int &getClientHeight() const
- //{ return client.height; }
- //inline const unsigned int &getClientWidth() const
- //{ return client.width; }
- inline const unsigned int &getTitleHeight() const
- { return frame.title_h; }
-
- //inline const Point origin() const {
- // return Point(frame.x, frame.y);
- //}
- //inline const Point clientOrigin() const {
- // return Point(client.x, client.y);
- //}
- //inline const Size size() const {
- // return Size(frame.width, flags.shaded ? frame.title_h : frame.height);
- //}
- //inline const Size clientSize() const {
- // return Size(client.width, client.height);
- //}
- inline const Rect area() const {
- return Rect(frame.x, frame.y, frame.width,
- flags.shaded ? frame.title_h : frame.height);
- }
- inline const Rect clientArea() const {
- return Rect(client.x, client.y, client.width, client.height);
- }
-
- inline void setWindowNumber(int n) { window_number = n; }
-
- bool validateClient();
- bool setInputFocus();
-
- void setFocusFlag(Bool);
- void iconify();
- void deiconify(bool reassoc = true, bool raise = true, bool initial = false);
- void close();
- void withdraw();
- void maximize(unsigned int button);
- void shade();
- void stick();
- void unstick();
- void reconfigure();
- void installColormap(Bool);
- void restore();
- void configure(int dx, int dy, unsigned int dw, unsigned int dh);
- void setWorkspace(int n);
- void changeOpenboxHints(OpenboxHints *);
- void restoreAttributes();
-
- void startMove(int x, int y);
- void endMove();
-
- void buttonPressEvent(XButtonEvent *);
- void buttonReleaseEvent(XButtonEvent *);
- void motionNotifyEvent(XMotionEvent *);
- void destroyNotifyEvent(XDestroyWindowEvent *);
- void mapRequestEvent(XMapRequestEvent *);
- void mapNotifyEvent(XMapEvent *);
- void unmapNotifyEvent(XUnmapEvent *);
- void propertyNotifyEvent(Atom);
- void exposeEvent(XExposeEvent *);
- void configureRequestEvent(XConfigureRequestEvent *);
-
-#ifdef SHAPE
- void shapeEvent(XShapeEvent *);
-#endif // SHAPE
-
- virtual void timeout();
-};
-
-
-#endif // __Window_hh
--- /dev/null
+// -*- mode: C++; indent-tabs-mode: nil; c-basic-offset: 2; -*-
+// Window.hh for Blackbox - an X11 Window manager
+// Copyright (c) 2001 - 2002 Sean 'Shaleh' Perry <shaleh@debian.org>
+// Copyright (c) 1997 - 2000 Brad Hughes (bhughes@tcac.net)
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#ifndef __Window_hh
+#define __Window_hh
+
+extern "C" {
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#ifdef SHAPE
+# include <X11/extensions/shape.h>
+#endif // SHAPE
+}
+
+#include <string>
+
+#include "BaseDisplay.hh"
+#include "Timer.hh"
+#include "Util.hh"
+#include "Windowmenu.hh"
+
+#define MwmHintsFunctions (1l << 0)
+#define MwmHintsDecorations (1l << 1)
+
+#define MwmFuncAll (1l << 0)
+#define MwmFuncResize (1l << 1)
+#define MwmFuncMove (1l << 2)
+#define MwmFuncIconify (1l << 3)
+#define MwmFuncMaximize (1l << 4)
+#define MwmFuncClose (1l << 5)
+
+#define MwmDecorAll (1l << 0)
+#define MwmDecorBorder (1l << 1)
+#define MwmDecorHandle (1l << 2)
+#define MwmDecorTitle (1l << 3)
+#define MwmDecorMenu (1l << 4) // not used
+#define MwmDecorIconify (1l << 5)
+#define MwmDecorMaximize (1l << 6)
+
+// this structure only contains 3 elements... the Motif 2.0 structure contains
+// 5... we only need the first 3... so that is all we will define
+typedef struct MwmHints {
+ unsigned long flags, functions, decorations;
+} MwmHints;
+
+#define PropMwmHintsElements 3
+
+class BWindowGroup {
+private:
+ Blackbox *blackbox;
+ Window group;
+ BlackboxWindowList windowList;
+
+public:
+ BWindowGroup(Blackbox *b, Window _group);
+ ~BWindowGroup(void);
+
+ inline Window groupWindow(void) const { return group; }
+
+ inline bool empty(void) const { return windowList.empty(); }
+
+ void addWindow(BlackboxWindow *w) { windowList.push_back(w); }
+ void removeWindow(BlackboxWindow *w) { windowList.remove(w); }
+
+ /*
+ find a window on the specified screen. the focused window (if any) is
+ checked first, otherwise the first matching window found is returned.
+ transients are returned only if allow_transients is True.
+ */
+ BlackboxWindow *find(BScreen *screen, bool allow_transients = False) const;
+};
+
+
+class BlackboxWindow : public TimeoutHandler {
+public:
+ enum Function { Func_Resize = (1l << 0),
+ Func_Move = (1l << 1),
+ Func_Iconify = (1l << 2),
+ Func_Maximize = (1l << 3),
+ Func_Close = (1l << 4) };
+ typedef unsigned int FunctionFlags;
+
+ enum Decoration { Decor_Titlebar = (1l << 0),
+ Decor_Handle = (1l << 1),
+ Decor_Border = (1l << 2),
+ Decor_Iconify = (1l << 3),
+ Decor_Maximize = (1l << 4),
+ Decor_Close = (1l << 5) };
+ typedef unsigned int DecorationFlags;
+
+private:
+ Blackbox *blackbox;
+ BScreen *screen;
+ BTimer *timer;
+ BlackboxAttributes blackbox_attrib;
+
+ Time lastButtonPressTime; // used for double clicks, when were we clicked
+ Windowmenu *windowmenu;
+
+ unsigned int window_number;
+ unsigned long current_state;
+
+ enum FocusMode { F_NoInput = 0, F_Passive,
+ F_LocallyActive, F_GloballyActive };
+ FocusMode focus_mode;
+
+ struct _flags {
+ bool moving, // is moving?
+ resizing, // is resizing?
+ shaded, // is shaded?
+ visible, // is visible?
+ iconic, // is iconified?
+ focused, // has focus?
+ stuck, // is omnipresent
+ modal, // is modal? (must be dismissed to continue)
+ send_focus_message, // should we send focus messages to our client?
+ shaped; // does the frame use the shape extension?
+ unsigned int maximized; // maximize is special, the number corresponds
+ // with a mouse button
+ // if 0, not maximized
+ // 1 = HorizVert, 2 = Vertical, 3 = Horizontal
+ } flags;
+
+ struct _client {
+ Window window, // the client's window
+ window_group;
+ BlackboxWindow *transient_for; // which window are we a transient for?
+ BlackboxWindowList transientList; // which windows are our transients?
+
+ std::string title, icon_title;
+
+ Rect rect;
+
+ int old_bw; // client's borderwidth
+
+ unsigned int
+ min_width, min_height, // can not be resized smaller
+ max_width, max_height, // can not be resized larger
+ width_inc, height_inc, // increment step
+ min_aspect_x, min_aspect_y, // minimum aspect ratio
+ max_aspect_x, max_aspect_y, // maximum aspect ratio
+ base_width, base_height,
+ win_gravity;
+
+ unsigned long initial_state, normal_hint_flags, wm_hint_flags;
+ } client;
+
+ FunctionFlags functions;
+ /*
+ * what decorations do we have?
+ * this is based on the type of the client window as well as user input
+ * the menu is not really decor, but it goes hand in hand with the decor
+ */
+ DecorationFlags decorations;
+
+ /*
+ * client window = the application's window
+ * frame window = the window drawn around the outside of the client window
+ * by the window manager which contains items like the
+ * titlebar and close button
+ * title = the titlebar drawn above the client window, it displays the
+ * window's name and any buttons for interacting with the window,
+ * such as iconify, maximize, and close
+ * label = the window in the titlebar where the title is drawn
+ * buttons = maximize, iconify, close
+ * handle = the bar drawn at the bottom of the window, which contains the
+ * left and right grips used for resizing the window
+ * grips = the smaller reactangles in the handle, one of each side of it.
+ * When clicked and dragged, these resize the window interactively
+ * border = the line drawn around the outside edge of the frame window,
+ * between the title, the bordered client window, and the handle.
+ * Also drawn between the grips and the handle
+ */
+
+ struct _frame {
+ // u -> unfocused, f -> has focus
+ unsigned long ulabel_pixel, flabel_pixel, utitle_pixel,
+ ftitle_pixel, uhandle_pixel, fhandle_pixel, ubutton_pixel,
+ fbutton_pixel, pbutton_pixel, uborder_pixel, fborder_pixel,
+ ugrip_pixel, fgrip_pixel;
+ Pixmap ulabel, flabel, utitle, ftitle, uhandle, fhandle,
+ ubutton, fbutton, pbutton, ugrip, fgrip;
+
+ Window window, // the frame
+ plate, // holds the client
+ title,
+ label,
+ handle,
+ close_button, iconify_button, maximize_button,
+ right_grip, left_grip;
+
+ /*
+ * size and location of the box drawn while the window dimensions or
+ * location is being changed, ie. resized or moved
+ */
+ Rect changing;
+
+ Rect rect; // frame geometry
+ Strut margin; // margins between the frame and client
+
+ int grab_x, grab_y; // where was the window when it was grabbed?
+
+ unsigned int inside_w, inside_h, // window w/h without border_w
+ title_h, label_w, label_h, handle_h,
+ button_w, grip_w, mwm_border_w, border_w,
+ bevel_w;
+ } frame;
+
+ BlackboxWindow(const BlackboxWindow&);
+ BlackboxWindow& operator=(const BlackboxWindow&);
+
+ bool getState(void);
+ Window createToplevelWindow();
+ Window createChildWindow(Window parent, Cursor = None);
+
+ void getWMName(void);
+ void getWMIconName(void);
+ void getWMNormalHints(void);
+ void getWMProtocols(void);
+ void getWMHints(void);
+ void getMWMHints(void);
+ bool getBlackboxHints(void);
+ void getTransientInfo(void);
+ void setNetWMAttributes(void);
+ void associateClientWindow(void);
+ void decorate(void);
+ void decorateLabel(void);
+ void positionButtons(bool redecorate_label = False);
+ void positionWindows(void);
+ void createHandle(void);
+ void destroyHandle(void);
+ void createTitlebar(void);
+ void destroyTitlebar(void);
+ void createCloseButton(void);
+ void destroyCloseButton(void);
+ void createIconifyButton(void);
+ void destroyIconifyButton(void);
+ void createMaximizeButton(void);
+ void destroyMaximizeButton(void);
+ void redrawLabel(void);
+ void redrawAllButtons(void);
+ void redrawCloseButton(bool pressed);
+ void redrawIconifyButton(bool pressed);
+ void redrawMaximizeButton(bool pressed);
+ void restoreGravity(void);
+ void setGravityOffsets(void);
+ void setState(unsigned long new_state);
+ void upsize(void);
+
+ enum Corner { TopLeft, TopRight };
+ void constrain(Corner anchor, int *pw = 0, int *ph = 0);
+
+public:
+ BlackboxWindow(Blackbox *b, Window w, BScreen *s);
+ virtual ~BlackboxWindow(void);
+
+ inline bool isTransient(void) const { return client.transient_for != 0; }
+ inline bool isFocused(void) const { return flags.focused; }
+ inline bool isVisible(void) const { return flags.visible; }
+ inline bool isIconic(void) const { return flags.iconic; }
+ inline bool isShaded(void) const { return flags.shaded; }
+ inline bool isMaximized(void) const { return flags.maximized; }
+ inline bool isStuck(void) const { return flags.stuck; }
+ inline bool isIconifiable(void) const { return functions & Func_Iconify; }
+ inline bool isMaximizable(void) const { return functions & Func_Maximize; }
+ inline bool isResizable(void) const { return functions & Func_Resize; }
+ inline bool isClosable(void) const { return functions & Func_Close; }
+
+ inline bool hasTitlebar(void) const { return decorations & Decor_Titlebar; }
+
+ inline const BlackboxWindowList &getTransients(void) const
+ { return client.transientList; }
+ BlackboxWindow *getTransientFor(void) const;
+
+ inline BScreen *getScreen(void) { return screen; }
+
+ inline Window getFrameWindow(void) const { return frame.window; }
+ inline Window getClientWindow(void) const { return client.window; }
+ inline Window getGroupWindow(void) const { return client.window_group; }
+
+ inline Windowmenu * getWindowmenu(void) { return windowmenu; }
+
+ inline const char *getTitle(void) const
+ { return client.title.c_str(); }
+ inline const char *getIconTitle(void) const
+ { return client.icon_title.c_str(); }
+
+ inline unsigned int getWorkspaceNumber(void) const
+ { return blackbox_attrib.workspace; }
+ inline unsigned int getWindowNumber(void) const { return window_number; }
+
+ inline const Rect &frameRect(void) const { return frame.rect; }
+ inline const Rect &clientRect(void) const { return client.rect; }
+
+ inline unsigned int getTitleHeight(void) const
+ { return frame.title_h; }
+
+ inline void setWindowNumber(int n) { window_number = n; }
+
+ bool validateClient(void);
+ bool setInputFocus(void);
+
+ void setFocusFlag(bool focus);
+ void iconify(void);
+ void deiconify(bool reassoc = True, bool raise = True);
+ void show(void);
+ void close(void);
+ void withdraw(void);
+ void maximize(unsigned int button);
+ void remaximize(void);
+ void shade(void);
+ void stick(void);
+ void unstick(void);
+ void reconfigure(void);
+ void updateFocusModel(void);
+ void installColormap(bool install);
+ void restore(bool remap);
+ void configure(int dx, int dy, unsigned int dw, unsigned int dh);
+ void setWorkspace(unsigned int n);
+ void changeBlackboxHints(BlackboxHints *net);
+ void restoreAttributes(void);
+
+ void buttonPressEvent(XButtonEvent *be);
+ void buttonReleaseEvent(XButtonEvent *re);
+ void motionNotifyEvent(XMotionEvent *me);
+ void destroyNotifyEvent(XDestroyWindowEvent */*unused*/);
+ void mapRequestEvent(XMapRequestEvent *mre);
+ void unmapNotifyEvent(XUnmapEvent */*unused*/);
+ void reparentNotifyEvent(XReparentEvent */*unused*/);
+ void propertyNotifyEvent(Atom atom);
+ void exposeEvent(XExposeEvent *ee);
+ void configureRequestEvent(XConfigureRequestEvent *cr);
+
+#ifdef SHAPE
+ void configureShape(void);
+ void shapeEvent(XShapeEvent * /*unused*/);
+#endif // SHAPE
+
+ virtual void timeout(void);
+};
+
+
+#endif // __Window_hh
-// Windowmenu.cc for Openbox
-// Copyright (c) 2001 Sean 'Shaleh' Perry <shaleh@debian.org>
+// -*- mode: C++; indent-tabs-mode: nil; -*-
+// Windowmenu.cc for Blackbox - an X11 Window manager
+// Copyright (c) 2001 - 2002 Sean 'Shaleh' Perry <shaleh@debian.org>
// Copyright (c) 1997 - 2000 Brad Hughes (bhughes@tcac.net)
//
// Permission is hereby granted, free of charge, to any person obtaining a
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
-// stupid macros needed to access some functions in version 2 of the GNU C
-// library
-#ifndef _GNU_SOURCE
-#define _GNU_SOURCE
-#endif // _GNU_SOURCE
-
#ifdef HAVE_CONFIG_H
# include "../config.h"
#endif // HAVE_CONFIG_H
-#include "i18n.h"
-#include "openbox.h"
-#include "Screen.h"
-#include "Window.h"
-#include "Windowmenu.h"
-#include "Workspace.h"
-
-#ifdef HAVE_STRING_H
+extern "C" {
+#ifdef HAVE_STRING_H
# include <string.h>
#endif // HAVE_STRING_H
+}
+#include "i18n.hh"
+#include "blackbox.hh"
+#include "Screen.hh"
+#include "Window.hh"
+#include "Windowmenu.hh"
+#include "Workspace.hh"
-Windowmenu::Windowmenu(OpenboxWindow &win) : Basemenu(*win.getScreen()),
-window(win), screen(*win.getScreen())
-{
+
+Windowmenu::Windowmenu(BlackboxWindow *win) : Basemenu(win->getScreen()) {
+ window = win;
setTitleVisibility(False);
setMovable(False);
setInternalMenu();
- sendToMenu = new SendtoWorkspacemenu(*this);
+ sendToMenu = new SendtoWorkspacemenu(this);
insert(i18n(WindowmenuSet, WindowmenuSendTo, "Send To ..."),
sendToMenu);
insert(i18n(WindowmenuSet, WindowmenuShade, "Shade"),
update();
- setItemEnabled(1, window.hasTitlebar());
- setItemEnabled(2, window.isIconifiable());
- setItemEnabled(3, window.isMaximizable());
- setItemEnabled(8, window.isClosable());
+ setItemEnabled(1, window->hasTitlebar());
+ setItemEnabled(2, window->isIconifiable());
+ setItemEnabled(3, window->isMaximizable());
+ setItemEnabled(8, window->isClosable());
}
void Windowmenu::show(void) {
- if (isItemEnabled(1)) setItemSelected(1, window.isShaded());
- if (isItemEnabled(3)) setItemSelected(3, window.isMaximized());
- if (isItemEnabled(6)) setItemSelected(6, window.isStuck());
+ if (isItemEnabled(1)) setItemSelected(1, window->isShaded());
+ if (isItemEnabled(3)) setItemSelected(3, window->isMaximized());
+ if (isItemEnabled(6)) setItemSelected(6, window->isStuck());
Basemenu::show();
}
-void Windowmenu::itemSelected(int button, int index) {
+void Windowmenu::itemSelected(int button, unsigned int index) {
BasemenuItem *item = find(index);
- /* Added by Scott Moynes, April 8, 2002
- Ignore the middle button for every item except the maximize
- button in the window menu. Maximize needs it for
- horizontal/vertical maximize, however, for the others it is
- inconsistent with the rest of the window behaviour.
- */
- if(button != 2) {
- hide();
- switch (item->function()) {
- case BScreen::WindowShade:
- window.shade();
- break;
-
- case BScreen::WindowIconify:
- window.iconify();
- break;
-
- case BScreen::WindowMaximize:
- window.maximize((unsigned int) button);
- break;
-
- case BScreen::WindowClose:
- window.close();
- break;
-
- case BScreen::WindowRaise:
- screen.getWorkspace(window.getWorkspaceNumber())->raiseWindow(&window);
- break;
-
- case BScreen::WindowLower:
- screen.getWorkspace(window.getWorkspaceNumber())->lowerWindow(&window);
- break;
-
- case BScreen::WindowStick:
- window.stick();
- break;
-
- case BScreen::WindowKill:
- XKillClient(screen.getBaseDisplay().getXDisplay(),
- window.getClientWindow());
- break;
- }
- } else if (item->function() == BScreen::WindowMaximize) {
- hide();
- window.maximize((unsigned int) button);
+ hide();
+ switch (item->function()) {
+ case BScreen::WindowShade:
+ window->shade();
+ break;
+
+ case BScreen::WindowIconify:
+ window->iconify();
+ break;
+
+ case BScreen::WindowMaximize:
+ window->maximize(button);
+ break;
+
+ case BScreen::WindowClose:
+ window->close();
+ break;
+
+ case BScreen::WindowRaise: {
+ Workspace *wkspc = getScreen()->getWorkspace(window->getWorkspaceNumber());
+ wkspc->raiseWindow(window);
+ }
+ break;
+
+ case BScreen::WindowLower: {
+ Workspace *wkspc = getScreen()->getWorkspace(window->getWorkspaceNumber());
+ wkspc->lowerWindow(window);
+ }
+ break;
+
+ case BScreen::WindowStick:
+ window->stick();
+ break;
+
+ case BScreen::WindowKill:
+ XKillClient(getScreen()->getBaseDisplay()->getXDisplay(),
+ window->getClientWindow());
+ break;
}
}
void Windowmenu::reconfigure(void) {
- setItemEnabled(1, window.hasTitlebar());
- setItemEnabled(2, window.isIconifiable());
- setItemEnabled(3, window.isMaximizable());
- setItemEnabled(8, window.isClosable());
+ setItemEnabled(1, window->hasTitlebar());
+ setItemEnabled(2, window->isIconifiable());
+ setItemEnabled(3, window->isMaximizable());
+ setItemEnabled(8, window->isClosable());
sendToMenu->reconfigure();
}
-Windowmenu::SendtoWorkspacemenu::SendtoWorkspacemenu(Windowmenu &w)
- : Basemenu(w.screen), windowmenu(w) {
- setTitleVisibility(False);
- setMovable(False);
- setInternalMenu();
- update();
- }
+Windowmenu::SendtoWorkspacemenu::SendtoWorkspacemenu(Windowmenu *w)
+ : Basemenu(w->getScreen()) {
+ window = w->window;
-void Windowmenu::SendtoWorkspacemenu::itemSelected(int button, int index) {
+ setTitleVisibility(False);
+ setMovable(False);
+ setInternalMenu();
+ update();
+}
+
+
+void Windowmenu::SendtoWorkspacemenu::itemSelected(int button,
+ unsigned int index) {
if (button > 2) return;
- if (index <= windowmenu.screen.getWorkspaceCount()) {
- if (index == windowmenu.screen.getCurrentWorkspaceID()) return;
- if (windowmenu.window.isStuck()) windowmenu.window.stick();
+ if (index <= getScreen()->getWorkspaceCount()) {
+ if (index == getScreen()->getCurrentWorkspaceID()) return;
+ if (window->isStuck()) window->stick();
- if (button == 1) windowmenu.window.withdraw();
- windowmenu.screen.reassociateWindow(&(windowmenu.window), index, True);
- if (button == 2) windowmenu.screen.changeWorkspaceID(index);
+ if (button == 1) window->withdraw();
+ getScreen()->reassociateWindow(window, index, True);
+ if (button == 2) getScreen()->changeWorkspaceID(index);
}
hide();
}
void Windowmenu::SendtoWorkspacemenu::update(void) {
- int i, r = getCount();
-
- if (r != 0)
- for (i = 0; i < r; ++i)
+ unsigned int i, r = getCount(),
+ workspace_count = getScreen()->getWorkspaceCount();
+ if (r > workspace_count) {
+ for (i = r; i < workspace_count; ++i)
remove(0);
+ r = getCount();
+ }
- for (i = 0; i < windowmenu.screen.getWorkspaceCount(); ++i)
- insert(windowmenu.screen.getWorkspace(i)->getName());
+ for (i = 0; i < workspace_count; ++i) {
+ if (r < workspace_count) {
+ insert(getScreen()->getWorkspace(i)->getName());
+ ++r;
+ } else {
+ changeItemLabel(i, getScreen()->getWorkspace(i)->getName());
+ }
+ }
Basemenu::update();
}
+++ /dev/null
-// Windowmenu.h for Openbox
-// Copyright (c) 2001 Sean 'Shaleh' Perry <shaleh@debian.org>
-// Copyright (c) 1997 - 2000 Brad Hughes (bhughes@tcac.net)
-//
-// Permission is hereby granted, free of charge, to any person obtaining a
-// copy of this software and associated documentation files (the "Software"),
-// to deal in the Software without restriction, including without limitation
-// the rights to use, copy, modify, merge, publish, distribute, sublicense,
-// and/or sell copies of the Software, and to permit persons to whom the
-// Software is furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-// DEALINGS IN THE SOFTWARE.
-
-#ifndef __Windowmenu_hh
-#define __Windowmenu_hh
-
-#include "Basemenu.h"
-
-// forward declaration
-class Windowmenu;
-class SendtoWorkspaceMenu;
-
-class Openbox;
-class OpenboxWindow;
-class Toolbar;
-
-class Windowmenu : public Basemenu {
-private:
- OpenboxWindow &window;
- BScreen &screen;
-
- class SendtoWorkspacemenu : public Basemenu {
- private:
- Windowmenu &windowmenu;
-
- protected:
- virtual void itemSelected(int, int);
-
- public:
- SendtoWorkspacemenu(Windowmenu &);
-
- void update(void);
-
- virtual void show(void);
- };
-
- SendtoWorkspacemenu *sendToMenu;
-
- friend class SendtoWorkspacemenu;
-
-
-protected:
- virtual void itemSelected(int, int);
-
-
-public:
- Windowmenu(OpenboxWindow &);
- virtual ~Windowmenu(void);
-
- inline Basemenu *getSendToMenu(void) { return (Basemenu *) sendToMenu; }
-
- void reconfigure(void);
- void setClosable(void);
-
- virtual void show(void);
-};
-
-
-#endif // __Windowmenu_hh
-// Workspace.cc for Openbox
-// Copyright (c) 2002 - 2002 Ben Jansens (ben@orodu.net)
-// Copyright (c) 2001 Sean 'Shaleh' Perry <shaleh@debian.org>
+// -*- mode: C++; indent-tabs-mode: nil; c-basic-offset: 2; -*-
+// Workspace.cc for Blackbox - an X11 Window manager
+// Copyright (c) 2001 - 2002 Sean 'Shaleh' Perry <shaleh@debian.org>
// Copyright (c) 1997 - 2000 Brad Hughes (bhughes@tcac.net)
//
// Permission is hereby granted, free of charge, to any person obtaining a
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
-// stupid macros needed to access some functions in version 2 of the GNU C
-// library
-#ifndef _GNU_SOURCE
-#define _GNU_SOURCE
-#endif // _GNU_SOURCE
-
#ifdef HAVE_CONFIG_H
# include "../config.h"
#endif // HAVE_CONFIG_H
+extern "C" {
+#include <X11/Xlib.h>
+#include <X11/Xatom.h>
+
#ifdef HAVE_STDIO_H
# include <stdio.h>
#endif // HAVE_STDIO_H
-#ifdef HAVE_STDLIB_H
-# include <stdlib.h>
-#endif // HAVE_STDLIB_H
-
-#ifdef HAVE_STRING_H
+#ifdef HAVE_STRING_H
# include <string.h>
#endif // HAVE_STRING_H
+}
-#include <X11/Xlib.h>
-#include <X11/Xatom.h>
+#include <functional>
+#include <string>
-#include "i18n.h"
-#include "openbox.h"
-#include "Clientmenu.h"
-#include "Screen.h"
-#include "Toolbar.h"
-#include "Window.h"
-#include "Workspace.h"
-#include "Windowmenu.h"
-#include "Geometry.h"
-#include "Util.h"
-
-#include <algorithm>
-#include <vector>
-typedef std::vector<Rect> rectList;
+using std::string;
-Workspace::Workspace(BScreen &scrn, int i) : screen(scrn) {
- cascade_x = cascade_y = 0;
- _focused = _last = (OpenboxWindow *) 0;
- id = i;
+#include "i18n.hh"
+#include "blackbox.hh"
+#include "Clientmenu.hh"
+#include "Netizen.hh"
+#include "Screen.hh"
+#include "Toolbar.hh"
+#include "Util.hh"
+#include "Window.hh"
+#include "Workspace.hh"
+#include "Windowmenu.hh"
- clientmenu = new Clientmenu(*this);
- name = (char *) 0;
- setName(screen.getNameOfWorkspace(id));
-}
+Workspace::Workspace(BScreen *scrn, unsigned int i) {
+ screen = scrn;
+ cascade_x = cascade_y = 32;
-Workspace::~Workspace(void) {
- delete clientmenu;
+ id = i;
- if (name)
- delete [] name;
+ clientmenu = new Clientmenu(this);
+
+ lastfocus = (BlackboxWindow *) 0;
+
+ setName(screen->getNameOfWorkspace(id));
}
-int Workspace::addWindow(OpenboxWindow *w, bool place) {
- if (! w) return -1;
+void Workspace::addWindow(BlackboxWindow *w, bool place) {
+ assert(w != 0);
- if (place) placeWindow(*w);
+ if (place) placeWindow(w);
w->setWorkspace(id);
- w->setWindowNumber(_windows.size());
+ w->setWindowNumber(windowList.size());
- _zorder.push_front(w);
- _windows.push_back(w);
+ stackingList.push_front(w);
+ windowList.push_back(w);
- clientmenu->insert((const char **) w->getTitle());
+ clientmenu->insert(w->getTitle());
clientmenu->update();
- screen.updateNetizenWindowAdd(w->getClientWindow(), id);
+ screen->updateNetizenWindowAdd(w->getClientWindow(), id);
raiseWindow(w);
-
- return w->getWindowNumber();
}
-int Workspace::removeWindow(OpenboxWindow *w) {
- if (! w) return -1;
+unsigned int Workspace::removeWindow(BlackboxWindow *w) {
+ assert(w != 0);
- winVect::iterator winit = std::find(_windows.begin(), _windows.end(), w);
+ stackingList.remove(w);
- if (winit == _windows.end()) {
- if (w == _last)
- _last = (OpenboxWindow *) 0;
- if (w == _focused)
- _focused = (OpenboxWindow *) 0;
- return _windows.size();
+ if (w->isFocused() && ! screen->getBlackbox()->doShutdown()) {
+ BlackboxWindow *newfocus = 0;
+ if (w->isTransient())
+ newfocus = w->getTransientFor();
+ if (! newfocus && ! stackingList.empty())
+ newfocus = stackingList.front();
+ if (! newfocus || ! newfocus->setInputFocus())
+ screen->getBlackbox()->setFocusedWindow(0);
}
-
- _zorder.remove(w);
-
- if (w == _last)
- _last = (OpenboxWindow *) 0;
- if (w == _focused) {
- OpenboxWindow *fw = (OpenboxWindow *) 0;
- if (w->isTransient() && w->getTransientFor() &&
- w->getTransientFor()->isVisible())
- fw = w->getTransientFor();
- else if (screen.sloppyFocus()) // sloppy focus
- fw = (OpenboxWindow *) 0;
- else if (!_zorder.empty()) // click focus
- fw = _zorder.front();
-
- if (!(fw != (OpenboxWindow *) 0 && fw->setInputFocus()))
- screen.getOpenbox().focusWindow(0);
- }
-
- _windows.erase(winit);
+
+ if (lastfocus == w)
+ lastfocus = (BlackboxWindow *) 0;
+
+ windowList.remove(w);
clientmenu->remove(w->getWindowNumber());
clientmenu->update();
- screen.updateNetizenWindowDel(w->getClientWindow());
+ screen->updateNetizenWindowDel(w->getClientWindow());
- winVect::iterator it = _windows.begin();
- for (int i=0; it != _windows.end(); ++it, ++i)
+ BlackboxWindowList::iterator it = windowList.begin();
+ const BlackboxWindowList::iterator end = windowList.end();
+ unsigned int i = 0;
+ for (; it != end; ++it, ++i)
(*it)->setWindowNumber(i);
- return _windows.size();
-}
-
+ if (i == 0)
+ cascade_x = cascade_y = 32;
-void Workspace::focusWindow(OpenboxWindow *win) {
- if (_focused != (OpenboxWindow *) 0)
- clientmenu->setItemSelected(_focused->getWindowNumber(), false);
- _focused = win;
- // make sure the focused window belongs to this workspace before highlighting
- // it in the menu (sticky windows arent in this workspace's menu).
- if (_focused != (OpenboxWindow *) 0 && _focused->getWorkspaceNumber() == id)
- clientmenu->setItemSelected(_focused->getWindowNumber(), true);
- if (win != (OpenboxWindow *) 0)
- _last = win;
+ return i;
}
void Workspace::showAll(void) {
- winList::iterator it;
- for (it = _zorder.begin(); it != _zorder.end(); ++it)
- (*it)->deiconify(false, false);
+ std::for_each(stackingList.begin(), stackingList.end(),
+ std::mem_fun(&BlackboxWindow::show));
}
void Workspace::hideAll(void) {
- winList::reverse_iterator it;
- for (it = _zorder.rbegin(); it != _zorder.rend(); ++it)
- if (!(*it)->isStuck())
- (*it)->withdraw();
-}
+ // withdraw in reverse order to minimize the number of Expose events
+ BlackboxWindowList lst(stackingList.rbegin(), stackingList.rend());
-void Workspace::removeAll(void) {
- winVect::iterator it;
- for (it = _windows.begin(); it != _windows.end(); ++it)
- (*it)->iconify();
+ BlackboxWindowList::iterator it = lst.begin();
+ const BlackboxWindowList::iterator end = lst.end();
+ for (; it != end; ++it) {
+ BlackboxWindow *bw = *it;
+ if (! bw->isStuck())
+ bw->withdraw();
+ }
}
-void Workspace::raiseWindow(OpenboxWindow *w) {
- OpenboxWindow *win = (OpenboxWindow *) 0, *bottom = w;
+void Workspace::removeAll(void) {
+ while (! windowList.empty())
+ windowList.front()->iconify();
+}
- while (bottom->isTransient() && bottom->getTransientFor())
- bottom = bottom->getTransientFor();
- int i = 1;
- win = bottom;
- while (win->hasTransient() && win->getTransient()) {
- win = win->getTransient();
+/*
+ * returns the number of transients for win, plus the number of transients
+ * associated with each transient of win
+ */
+static int countTransients(const BlackboxWindow * const win) {
+ int ret = win->getTransients().size();
+ if (ret > 0) {
+ BlackboxWindowList::const_iterator it, end = win->getTransients().end();
+ for (it = win->getTransients().begin(); it != end; ++it) {
+ ret += countTransients(*it);
+ }
+ }
+ return ret;
+}
+
+
+/*
+ * puts the transients of win into the stack. windows are stacked above
+ * the window before it in the stackvector being iterated, meaning
+ * stack[0] is on bottom, stack[1] is above stack[0], stack[2] is above
+ * stack[1], etc...
+ */
+void Workspace::raiseTransients(const BlackboxWindow * const win,
+ StackVector::iterator &stack) {
+ if (win->getTransients().size() == 0) return; // nothing to do
+
+ // put win's transients in the stack
+ BlackboxWindowList::const_iterator it, end = win->getTransients().end();
+ for (it = win->getTransients().begin(); it != end; ++it) {
+ *stack++ = (*it)->getFrameWindow();
+ screen->updateNetizenWindowRaise((*it)->getClientWindow());
+
+ if (! (*it)->isIconic()) {
+ Workspace *wkspc = screen->getWorkspace((*it)->getWorkspaceNumber());
+ wkspc->stackingList.remove((*it));
+ wkspc->stackingList.push_front((*it));
+ }
+ }
- i++;
+ // put transients of win's transients in the stack
+ for (it = win->getTransients().begin(); it != end; ++it) {
+ raiseTransients(*it, stack);
}
+}
- Window *nstack = new Window[i], *curr = nstack;
- Workspace *wkspc;
- win = bottom;
- while (true) {
- *(curr++) = win->getFrameWindow();
- screen.updateNetizenWindowRaise(win->getClientWindow());
+void Workspace::lowerTransients(const BlackboxWindow * const win,
+ StackVector::iterator &stack) {
+ if (win->getTransients().size() == 0) return; // nothing to do
- if (! win->isIconic()) {
- wkspc = screen.getWorkspace(win->getWorkspaceNumber());
- wkspc->_zorder.remove(win);
- wkspc->_zorder.push_front(win);
- }
+ // put transients of win's transients in the stack
+ BlackboxWindowList::const_reverse_iterator it,
+ end = win->getTransients().rend();
+ for (it = win->getTransients().rbegin(); it != end; ++it) {
+ lowerTransients(*it, stack);
+ }
- if (! win->hasTransient() || ! win->getTransient())
- break;
+ // put win's transients in the stack
+ for (it = win->getTransients().rbegin(); it != end; ++it) {
+ *stack++ = (*it)->getFrameWindow();
+ screen->updateNetizenWindowLower((*it)->getClientWindow());
- win = win->getTransient();
+ if (! (*it)->isIconic()) {
+ Workspace *wkspc = screen->getWorkspace((*it)->getWorkspaceNumber());
+ wkspc->stackingList.remove((*it));
+ wkspc->stackingList.push_back((*it));
+ }
}
- screen.raiseWindows(nstack, i);
-
- delete [] nstack;
}
-void Workspace::lowerWindow(OpenboxWindow *w) {
- OpenboxWindow *win = (OpenboxWindow *) 0, *bottom = w;
+void Workspace::raiseWindow(BlackboxWindow *w) {
+ BlackboxWindow *win = w;
+
+ // walk up the transient_for's to the window that is not a transient
+ while (win->isTransient()) {
+ if (! win->getTransientFor()) break;
+ win = win->getTransientFor();
+ }
- while (bottom->isTransient() && bottom->getTransientFor())
- bottom = bottom->getTransientFor();
+ // get the total window count (win and all transients)
+ unsigned int i = 1 + countTransients(win);
- int i = 1;
- win = bottom;
- while (win->hasTransient() && win->getTransient()) {
- win = win->getTransient();
+ // stack the window with all transients above
+ StackVector stack_vector(i);
+ StackVector::iterator stack = stack_vector.begin();
- i++;
+ *(stack++) = win->getFrameWindow();
+ screen->updateNetizenWindowRaise(win->getClientWindow());
+ if (! win->isIconic()) {
+ Workspace *wkspc = screen->getWorkspace(win->getWorkspaceNumber());
+ wkspc->stackingList.remove(win);
+ wkspc->stackingList.push_front(win);
}
- Window *nstack = new Window[i], *curr = nstack;
- Workspace *wkspc;
+ raiseTransients(win, stack);
- while (true) {
- *(curr++) = win->getFrameWindow();
- screen.updateNetizenWindowLower(win->getClientWindow());
+ screen->raiseWindows(&stack_vector[0], stack_vector.size());
+}
- if (! win->isIconic()) {
- wkspc = screen.getWorkspace(win->getWorkspaceNumber());
- wkspc->_zorder.remove(win);
- wkspc->_zorder.push_back(win);
- }
- if (! win->getTransientFor())
- break;
+void Workspace::lowerWindow(BlackboxWindow *w) {
+ BlackboxWindow *win = w;
+ // walk up the transient_for's to the window that is not a transient
+ while (win->isTransient()) {
+ if (! win->getTransientFor()) break;
win = win->getTransientFor();
}
- screen.getOpenbox().grab();
+ // get the total window count (win and all transients)
+ unsigned int i = 1 + countTransients(win);
+
+ // stack the window with all transients above
+ StackVector stack_vector(i);
+ StackVector::iterator stack = stack_vector.begin();
- XLowerWindow(screen.getBaseDisplay().getXDisplay(), *nstack);
- XRestackWindows(screen.getBaseDisplay().getXDisplay(), nstack, i);
+ lowerTransients(win, stack);
- screen.getOpenbox().ungrab();
+ *(stack++) = win->getFrameWindow();
+ screen->updateNetizenWindowLower(win->getClientWindow());
+ if (! win->isIconic()) {
+ Workspace *wkspc = screen->getWorkspace(win->getWorkspaceNumber());
+ wkspc->stackingList.remove(win);
+ wkspc->stackingList.push_back(win);
+ }
- delete [] nstack;
+ XLowerWindow(screen->getBaseDisplay()->getXDisplay(), stack_vector.front());
+ XRestackWindows(screen->getBaseDisplay()->getXDisplay(),
+ &stack_vector[0], stack_vector.size());
}
void Workspace::reconfigure(void) {
clientmenu->reconfigure();
+ std::for_each(windowList.begin(), windowList.end(),
+ std::mem_fun(&BlackboxWindow::reconfigure));
+}
+
- winVect::iterator it;
- for (it = _windows.begin(); it != _windows.end(); ++it)
- if ((*it)->validateClient())
- (*it)->reconfigure();
+void Workspace::updateFocusModel(void) {
+ std::for_each(windowList.begin(), windowList.end(),
+ std::mem_fun(&BlackboxWindow::updateFocusModel));
}
-OpenboxWindow *Workspace::getWindow(int index) {
- if ((index >= 0) && (index < (signed)_windows.size()))
- return _windows[index];
- else
- return (OpenboxWindow *) 0;
+BlackboxWindow *Workspace::getWindow(unsigned int index) {
+ if (index < windowList.size()) {
+ BlackboxWindowList::iterator it = windowList.begin();
+ for(; index > 0; --index, ++it); /* increment to index */
+ return *it;
+ }
+ return 0;
}
-int Workspace::getCount(void) {
- return (signed)_windows.size();
+BlackboxWindow*
+Workspace::getNextWindowInList(BlackboxWindow *w) {
+ BlackboxWindowList::iterator it = std::find(windowList.begin(),
+ windowList.end(),
+ w);
+ assert(it != windowList.end()); // window must be in list
+ ++it; // next window
+ if (it == windowList.end())
+ return windowList.front(); // if we walked off the end, wrap around
+
+ return *it;
}
-void Workspace::update(void) {
- clientmenu->update();
- screen.getToolbar()->redrawWindowLabel(true);
+BlackboxWindow* Workspace::getPrevWindowInList(BlackboxWindow *w) {
+ BlackboxWindowList::iterator it = std::find(windowList.begin(),
+ windowList.end(),
+ w);
+ assert(it != windowList.end()); // window must be in list
+ if (it == windowList.begin())
+ return windowList.back(); // if we walked of the front, wrap around
+
+ return *(--it);
}
-bool Workspace::isCurrent(void) {
- return (id == screen.getCurrentWorkspaceID());
+BlackboxWindow* Workspace::getTopWindowOnStack(void) const {
+ return stackingList.front();
}
-void Workspace::setCurrent(void) {
- screen.changeWorkspaceID(id);
+void Workspace::sendWindowList(Netizen &n) {
+ BlackboxWindowList::iterator it = windowList.begin(),
+ end = windowList.end();
+ for(; it != end; ++it)
+ n.sendWindowAdd((*it)->getClientWindow(), getID());
+}
+
+
+unsigned int Workspace::getCount(void) const {
+ return windowList.size();
+}
+
+
+bool Workspace::isCurrent(void) const {
+ return (id == screen->getCurrentWorkspaceID());
}
-void Workspace::setName(const char *new_name) {
- if (name)
- delete [] name;
+bool Workspace::isLastWindow(const BlackboxWindow* const w) const {
+ return (w == windowList.back());
+}
+
+void Workspace::setCurrent(void) {
+ screen->changeWorkspaceID(id);
+}
+
- if (new_name) {
- name = bstrdup(new_name);
+void Workspace::setName(const string& new_name) {
+ if (! new_name.empty()) {
+ name = new_name;
} else {
- name = new char[128];
- sprintf(name, i18n(WorkspaceSet, WorkspaceDefaultNameFormat,
- "Workspace %d"), id + 1);
+ string tmp =i18n(WorkspaceSet, WorkspaceDefaultNameFormat, "Workspace %d");
+ assert(tmp.length() < 32);
+ char default_name[32];
+ sprintf(default_name, tmp.c_str(), id + 1);
+ name = default_name;
}
clientmenu->setLabel(name);
clientmenu->update();
- screen.saveWorkspaceNames();
}
-void Workspace::shutdown(void) {
- while (!_windows.empty())
- _windows[0]->restore();
-}
+/*
+ * Calculate free space available for window placement.
+ */
+typedef std::vector<Rect> rectList;
static rectList calcSpace(const Rect &win, const rectList &spaces) {
+ Rect isect, extra;
rectList result;
- rectList::const_iterator siter;
- for(siter=spaces.begin(); siter!=spaces.end(); ++siter) {
- if(win.Intersect(*siter)) {
- //Check for space to the left of the window
- if(win.x() > siter->x())
- result.push_back(Rect(siter->x(), siter->y(),
- win.x() - siter->x() - 1,
- siter->h()));
- //Check for space above the window
- if(win.y() > siter->y())
- result.push_back(Rect(siter->x(), siter->y(),
- siter->w(),
- win.y() - siter->y() - 1));
- //Check for space to the right of the window
- if((win.x()+win.w()) <
- (siter->x()+siter->w()))
- result.push_back(Rect(win.x() + win.w() + 1,
- siter->y(),
- siter->x() + siter->w() -
- win.x() - win.w() - 1,
- siter->h()));
- //Check for space below the window
- if((win.y()+win.h()) <
- (siter->y()+siter->h()))
- result.push_back(Rect(siter->x(),
- win.y() + win.h() + 1,
- siter->w(),
- siter->y() + siter->h()-
- win.y() - win.h() - 1));
+ rectList::const_iterator siter, end = spaces.end();
+ for (siter = spaces.begin(); siter != end; ++siter) {
+ const Rect &curr = *siter;
+ if(! win.intersects(curr)) {
+ result.push_back(curr);
+ continue;
}
- else
- result.push_back(*siter);
+
+ /* Use an intersection of win and curr to determine the space around
+ * curr that we can use.
+ *
+ * NOTE: the spaces calculated can overlap.
+ */
+ isect = curr & win;
+
+ // left
+ extra.setCoords(curr.left(), curr.top(),
+ isect.left() - 1, curr.bottom());
+ if (extra.valid()) result.push_back(extra);
+
+ // top
+ extra.setCoords(curr.left(), curr.top(),
+ curr.right(), isect.top() - 1);
+ if (extra.valid()) result.push_back(extra);
+
+ // right
+ extra.setCoords(isect.right() + 1, curr.top(),
+ curr.right(), curr.bottom());
+ if (extra.valid()) result.push_back(extra);
+
+ // bottom
+ extra.setCoords(curr.left(), isect.bottom() + 1,
+ curr.right(), curr.bottom());
+ if (extra.valid()) result.push_back(extra);
}
return result;
}
-bool rowRLBT(const Rect &first, const Rect &second){
- if (first.y()+first.h()==second.y()+second.h())
- return first.x()+first.w()>second.x()+second.w();
- return first.y()+first.h()>second.y()+second.h();
+
+static bool rowRLBT(const Rect &first, const Rect &second) {
+ if (first.bottom() == second.bottom())
+ return first.right() > second.right();
+ return first.bottom() > second.bottom();
}
-bool rowRLTB(const Rect &first, const Rect &second){
- if (first.y()==second.y())
- return first.x()+first.w()>second.x()+second.w();
- return first.y()<second.y();
+static bool rowRLTB(const Rect &first, const Rect &second) {
+ if (first.y() == second.y())
+ return first.right() > second.right();
+ return first.y() < second.y();
}
-bool rowLRBT(const Rect &first, const Rect &second){
- if (first.y()+first.h()==second.y()+second.h())
- return first.x()<second.x();
- return first.y()+first.h()>second.y()+second.h();
+static bool rowLRBT(const Rect &first, const Rect &second) {
+ if (first.bottom() == second.bottom())
+ return first.x() < second.x();
+ return first.bottom() > second.bottom();
}
-bool rowLRTB(const Rect &first, const Rect &second){
- if (first.y()==second.y())
- return first.x()<second.x();
- return first.y()<second.y();
+static bool rowLRTB(const Rect &first, const Rect &second) {
+ if (first.y() == second.y())
+ return first.x() < second.x();
+ return first.y() < second.y();
}
-bool colLRTB(const Rect &first, const Rect &second){
- if (first.x()==second.x())
- return first.y()<second.y();
- return first.x()<second.x();
+static bool colLRTB(const Rect &first, const Rect &second) {
+ if (first.x() == second.x())
+ return first.y() < second.y();
+ return first.x() < second.x();
}
-bool colLRBT(const Rect &first, const Rect &second){
- if (first.x()==second.x())
- return first.y()+first.h()>second.y()+second.h();
- return first.x()<second.x();
+static bool colLRBT(const Rect &first, const Rect &second) {
+ if (first.x() == second.x())
+ return first.bottom() > second.bottom();
+ return first.x() < second.x();
}
-bool colRLTB(const Rect &first, const Rect &second){
- if (first.x()+first.w()==second.x()+second.w())
- return first.y()<second.y();
- return first.x()+first.w()>second.x()+second.w();
+static bool colRLTB(const Rect &first, const Rect &second) {
+ if (first.right() == second.right())
+ return first.y() < second.y();
+ return first.right() > second.right();
}
-bool colRLBT(const Rect &first, const Rect &second){
- if (first.x()+first.w()==second.x()+second.w())
- return first.y()+first.h()>second.y()+second.h();
- return first.x()+first.w()>second.x()+second.w();
+static bool colRLBT(const Rect &first, const Rect &second) {
+ if (first.right() == second.right())
+ return first.bottom() > second.bottom();
+ return first.right() > second.right();
}
-//BestFitPlacement finds the smallest free space that fits the window
-//to be placed. It currentl ignores whether placement is right to left or top
-//to bottom.
-Point *Workspace::bestFitPlacement(const Size &win_size, const Rect &space) {
- const Rect *best;
+bool Workspace::smartPlacement(Rect& win, const Rect& availableArea) {
rectList spaces;
- rectList::const_iterator siter;
- spaces.push_back(space); //initially the entire screen is free
+ spaces.push_back(availableArea); //initially the entire screen is free
//Find Free Spaces
- winVect::iterator it;
- for (it = _windows.begin(); it != _windows.end(); ++it)
- spaces = calcSpace((*it)->area().Inflate(screen.getBorderWidth() * 4),
- spaces);
-
- //Find first space that fits the window
- best = NULL;
- for (siter=spaces.begin(); siter!=spaces.end(); ++siter) {
- if ((siter->w() >= win_size.w()) && (siter->h() >= win_size.h())) {
- if (best==NULL)
- best = &*siter;
- else if(siter->w()*siter->h()<best->h()*best->w())
- best = &*siter;
- }
+ BlackboxWindowList::iterator wit = windowList.begin(),
+ end = windowList.end();
+ Rect tmp;
+ for (; wit != end; ++wit) {
+ const BlackboxWindow* const curr = *wit;
+ tmp.setRect(curr->frameRect().x(), curr->frameRect().y(),
+ curr->frameRect().width() + screen->getBorderWidth(),
+ curr->frameRect().height() + screen->getBorderWidth());
+
+ spaces = calcSpace(tmp, spaces);
}
- if (best != NULL) {
- Point *pt = new Point(best->origin());
- if (screen.colPlacementDirection() != BScreen::TopBottom)
- pt->setY(pt->y() + (best->h() - win_size.h()));
- if (screen.rowPlacementDirection() != BScreen::LeftRight)
- pt->setX(pt->x() + (best->w() - win_size.w()));
- return pt;
- } else
- return NULL; //fall back to cascade
-}
-
-Point *Workspace::underMousePlacement(const Size &win_size, const Rect &space) {
- Point *pt;
-
- int x, y, rx, ry;
- Window c, r;
- unsigned int m;
- XQueryPointer(screen.getOpenbox().getXDisplay(), screen.getRootWindow(),
- &r, &c, &rx, &ry, &x, &y, &m);
- pt = new Point(rx - win_size.w() / 2, ry - win_size.h() / 2);
-
- if (pt->x() < space.x())
- pt->setX(space.x());
- if (pt->y() < space.y())
- pt->setY(space.y());
- if (pt->x() + win_size.w() > space.x() + space.w())
- pt->setX(space.x() + space.w() - win_size.w());
- if (pt->y() + win_size.h() > space.y() + space.h())
- pt->setY(space.y() + space.h() - win_size.h());
- return pt;
-}
-
-Point *Workspace::rowSmartPlacement(const Size &win_size, const Rect &space) {
- const Rect *best;
- rectList spaces;
- rectList::const_iterator siter;
- spaces.push_back(space); //initially the entire screen is free
+ if (screen->getPlacementPolicy() == BScreen::RowSmartPlacement) {
+ if(screen->getRowPlacementDirection() == BScreen::LeftRight) {
+ if(screen->getColPlacementDirection() == BScreen::TopBottom)
+ sort(spaces.begin(), spaces.end(), rowLRTB);
+ else
+ sort(spaces.begin(), spaces.end(), rowLRBT);
+ } else {
+ if(screen->getColPlacementDirection() == BScreen::TopBottom)
+ sort(spaces.begin(), spaces.end(), rowRLTB);
+ else
+ sort(spaces.begin(), spaces.end(), rowRLBT);
+ }
+ } else {
+ if(screen->getColPlacementDirection() == BScreen::TopBottom) {
+ if(screen->getRowPlacementDirection() == BScreen::LeftRight)
+ sort(spaces.begin(), spaces.end(), colLRTB);
+ else
+ sort(spaces.begin(), spaces.end(), colRLTB);
+ } else {
+ if(screen->getRowPlacementDirection() == BScreen::LeftRight)
+ sort(spaces.begin(), spaces.end(), colLRBT);
+ else
+ sort(spaces.begin(), spaces.end(), colRLBT);
+ }
+ }
- //Find Free Spaces
- winVect::iterator it;
- for (it = _windows.begin(); it != _windows.end(); ++it)
- spaces = calcSpace((*it)->area().Inflate(screen.getBorderWidth() * 4),
- spaces);
- //Sort spaces by preference
- if(screen.rowPlacementDirection() == BScreen::RightLeft)
- if(screen.colPlacementDirection() == BScreen::TopBottom)
- sort(spaces.begin(),spaces.end(),rowRLTB);
- else
- sort(spaces.begin(),spaces.end(),rowRLBT);
- else
- if(screen.colPlacementDirection() == BScreen::TopBottom)
- sort(spaces.begin(),spaces.end(),rowLRTB);
- else
- sort(spaces.begin(),spaces.end(),rowLRBT);
- best = NULL;
- for (siter=spaces.begin(); siter!=spaces.end(); ++siter)
- if ((siter->w() >= win_size.w()) && (siter->h() >= win_size.h())) {
- best = &*siter;
+ rectList::const_iterator sit = spaces.begin(), spaces_end = spaces.end();
+ for(; sit != spaces_end; ++sit) {
+ if (sit->width() >= win.width() && sit->height() >= win.height())
break;
- }
+ }
- if (best != NULL) {
- Point *pt = new Point(best->origin());
- if (screen.colPlacementDirection() != BScreen::TopBottom)
- pt->setY(best->y() + best->h() - win_size.h());
- if (screen.rowPlacementDirection() != BScreen::LeftRight)
- pt->setX(best->x()+best->w()-win_size.w());
- return pt;
- } else
- return NULL; //fall back to cascade
-}
+ if (sit == spaces_end)
+ return False;
-Point *Workspace::colSmartPlacement(const Size &win_size, const Rect &space) {
- const Rect *best;
- rectList spaces;
+ //set new position based on the empty space found
+ const Rect& where = *sit;
+ win.setX(where.x());
+ win.setY(where.y());
+
+ // adjust the location() based on left/right and top/bottom placement
+ if (screen->getPlacementPolicy() == BScreen::RowSmartPlacement) {
+ if (screen->getRowPlacementDirection() == BScreen::RightLeft)
+ win.setX(where.right() - win.width());
+ if (screen->getColPlacementDirection() == BScreen::BottomTop)
+ win.setY(where.bottom() - win.height());
+ } else {
+ if (screen->getColPlacementDirection() == BScreen::BottomTop)
+ win.setY(win.y() + where.height() - win.height());
+ if (screen->getRowPlacementDirection() == BScreen::RightLeft)
+ win.setX(win.x() + where.width() - win.width());
+ }
+ return True;
+}
- rectList::const_iterator siter;
- spaces.push_back(space); //initially the entire screen is free
- //Find Free Spaces
- winVect::iterator it;
- for (it = _windows.begin(); it != _windows.end(); ++it)
- spaces = calcSpace((*it)->area().Inflate(screen.getBorderWidth() * 4),
- spaces);
- //Sort spaces by user preference
- if(screen.colPlacementDirection() == BScreen::TopBottom)
- if(screen.rowPlacementDirection() == BScreen::LeftRight)
- sort(spaces.begin(),spaces.end(),colLRTB);
- else
- sort(spaces.begin(),spaces.end(),colRLTB);
- else
- if(screen.rowPlacementDirection() == BScreen::LeftRight)
- sort(spaces.begin(),spaces.end(),colLRBT);
- else
- sort(spaces.begin(),spaces.end(),colRLBT);
-
- //Find first space that fits the window
- best = NULL;
- for (siter=spaces.begin(); siter!=spaces.end(); ++siter)
- if ((siter->w() >= win_size.w()) && (siter->h() >= win_size.h())) {
- best = &*siter;
- break;
- }
+bool Workspace::cascadePlacement(Rect &win, const Rect &availableArea) {
+ if ((cascade_x > static_cast<signed>(availableArea.width() / 2)) ||
+ (cascade_y > static_cast<signed>(availableArea.height() / 2)))
+ cascade_x = cascade_y = 32;
- if (best != NULL) {
- Point *pt = new Point(best->origin());
- if (screen.colPlacementDirection() != BScreen::TopBottom)
- pt->setY(pt->y() + (best->h() - win_size.h()));
- if (screen.rowPlacementDirection() != BScreen::LeftRight)
- pt->setX(pt->x() + (best->w() - win_size.w()));
- return pt;
- } else
- return NULL; //fall back to cascade
-}
-
-
-Point *const Workspace::cascadePlacement(const OpenboxWindow &win,
- const Rect &space) {
- if ((cascade_x + win.area().w() + screen.getBorderWidth() * 2 >
- (space.x() + space.w())) ||
- (cascade_y + win.area().h() + screen.getBorderWidth() * 2 >
- (space.y() + space.h())))
- cascade_x = cascade_y = 0;
- if (cascade_x < space.x() || cascade_y < space.y()) {
- cascade_x = space.x();
- cascade_y = space.y();
+ if (cascade_x == 32) {
+ cascade_x += availableArea.x();
+ cascade_y += availableArea.y();
}
- Point *p = new Point(cascade_x, cascade_y);
- cascade_x += win.getTitleHeight();
- cascade_y += win.getTitleHeight();
- return p;
+ win.setPos(cascade_x, cascade_y);
+
+ return True;
}
-void Workspace::placeWindow(OpenboxWindow &win) {
- Rect space = screen.availableArea();
- const Size window_size(win.area().w()+screen.getBorderWidth() * 2,
- win.area().h()+screen.getBorderWidth() * 2);
- Point *place = NULL;
+void Workspace::placeWindow(BlackboxWindow *win) {
+ Rect availableArea(screen->availableArea()),
+ new_win(availableArea.x(), availableArea.y(),
+ win->frameRect().width(), win->frameRect().height());
+ bool placed = False;
- switch (screen.placementPolicy()) {
- case BScreen::BestFitPlacement:
- place = bestFitPlacement(window_size, space);
- break;
+ switch (screen->getPlacementPolicy()) {
case BScreen::RowSmartPlacement:
- place = rowSmartPlacement(window_size, space);
- break;
case BScreen::ColSmartPlacement:
- place = colSmartPlacement(window_size, space);
- break;
- case BScreen::UnderMousePlacement:
- case BScreen::ClickMousePlacement:
- place = underMousePlacement(window_size, space);
+ placed = smartPlacement(new_win, availableArea);
break;
+ default:
+ break; // handled below
} // switch
- if (place == NULL)
- place = cascadePlacement(win, space);
-
- ASSERT(place != NULL);
- if (place->x() + window_size.w() > (signed) space.x() + space.w())
- place->setX(((signed) space.x() + space.w() - window_size.w()) / 2);
- if (place->y() + window_size.h() > (signed) space.y() + space.h())
- place->setY(((signed) space.y() + space.h() - window_size.h()) / 2);
+ if (placed == False) {
+ cascadePlacement(new_win, availableArea);
+ cascade_x += win->getTitleHeight() + (screen->getBorderWidth() * 2);
+ cascade_y += win->getTitleHeight() + (screen->getBorderWidth() * 2);
+ }
- win.configure(place->x(), place->y(), win.area().w(), win.area().h());
- delete place;
+ if (new_win.right() > availableArea.right())
+ new_win.setX(availableArea.left());
+ if (new_win.bottom() > availableArea.bottom())
+ new_win.setY(availableArea.top());
+ win->configure(new_win.x(), new_win.y(), new_win.width(), new_win.height());
}
+++ /dev/null
-// Workspace.h for Openbox
-// Copyright (c) 2001 Sean 'Shaleh' Perry <shaleh@debian.org>
-// Copyright (c) 1997 - 2000 Brad Hughes (bhughes@tcac.net)
-//
-// Permission is hereby granted, free of charge, to any person obtaining a
-// copy of this software and associated documentation files (the "Software"),
-// to deal in the Software without restriction, including without limitation
-// the rights to use, copy, modify, merge, publish, distribute, sublicense,
-// and/or sell copies of the Software, and to permit persons to whom the
-// Software is furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-// DEALINGS IN THE SOFTWARE.
-
-#ifndef __Workspace_hh
-#define __Workspace_hh
-
-#include <X11/Xlib.h>
-
-#include <vector>
-#include <list>
-
-class BScreen;
-class Clientmenu;
-class Workspace;
-class OpenboxWindow;
-class Size;
-class Rect;
-
-class Workspace {
-private:
- BScreen &screen;
- Clientmenu *clientmenu;
-
- typedef std::vector<OpenboxWindow *> winVect;
- winVect _windows;
- typedef std::list<OpenboxWindow *> winList;
- winList _zorder;
-
- char *name;
- int id, cascade_x, cascade_y;
-
- OpenboxWindow *_focused, *_last; // last is the same as focused except
- // that when focus is removed from all
- // windows on the workspace, last doesnt
- // change to NULL
-
-protected:
- void placeWindow(OpenboxWindow &);
- Point *bestFitPlacement(const Size &win_size, const Rect &space);
- Point *underMousePlacement(const Size &win_size, const Rect &space);
- Point *rowSmartPlacement(const Size &win_size, const Rect &space);
- Point *colSmartPlacement(const Size &win_size, const Rect &space);
- Point *const cascadePlacement(const OpenboxWindow &window, const Rect &space);
-
-public:
- Workspace(BScreen &, int = 0);
- ~Workspace(void);
-
- inline BScreen &getScreen(void) { return screen; }
- inline Clientmenu *getMenu(void) { return clientmenu; }
- inline const char *getName(void) const { return name; }
- inline int getWorkspaceID(void) const { return id; }
- inline OpenboxWindow *focusedWindow() { return _focused; }
- inline OpenboxWindow *lastFocusedWindow() { return _last; }
- void focusWindow(OpenboxWindow *win);
- OpenboxWindow *getWindow(int);
- bool isCurrent(void);
- int addWindow(OpenboxWindow *, bool = false);
- int removeWindow(OpenboxWindow *);
- int getCount(void);
- void showAll(void);
- void hideAll(void);
- void removeAll(void);
- void raiseWindow(OpenboxWindow *);
- void lowerWindow(OpenboxWindow *);
- void reconfigure();
- void update();
- void setCurrent(void);
- void setName(const char *);
- void shutdown(void);
-};
-
-
-#endif // __Workspace_hh
-
--- /dev/null
+// -*- mode: C++; indent-tabs-mode: nil; c-basic-offset: 2; -*-
+// Workspace.hh for Blackbox - an X11 Window manager
+// Copyright (c) 2001 - 2002 Sean 'Shaleh' Perry <shaleh@debian.org>
+// Copyright (c) 1997 - 2000 Brad Hughes (bhughes@tcac.net)
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#ifndef __Workspace_hh
+#define __Workspace_hh
+
+extern "C" {
+#include <X11/Xlib.h>
+}
+
+#include <list>
+#include <string>
+#include <vector>
+
+class BScreen;
+class Clientmenu;
+class Workspace;
+class BlackboxWindow;
+class Netizen;
+
+typedef std::list<BlackboxWindow*> BlackboxWindowList;
+typedef std::vector<Window> StackVector;
+
+class Workspace {
+private:
+ BScreen *screen;
+ BlackboxWindow *lastfocus;
+ Clientmenu *clientmenu;
+
+ BlackboxWindowList stackingList, windowList;
+
+ std::string name;
+ unsigned int id;
+ int cascade_x, cascade_y;
+
+ Workspace(const Workspace&);
+ Workspace& operator=(const Workspace&);
+
+ void raiseTransients(const BlackboxWindow * const win,
+ StackVector::iterator &stack);
+ void lowerTransients(const BlackboxWindow * const win,
+ StackVector::iterator &stack);
+
+ void placeWindow(BlackboxWindow *win);
+ bool cascadePlacement(Rect& win, const Rect& availableArea);
+ bool smartPlacement(Rect& win, const Rect& availableArea);
+
+public:
+ Workspace(BScreen *scrn, unsigned int i = 0);
+
+ inline BScreen *getScreen(void) { return screen; }
+
+ inline BlackboxWindow *getLastFocusedWindow(void) { return lastfocus; }
+
+ inline Clientmenu *getMenu(void) { return clientmenu; }
+
+ inline const std::string& getName(void) const { return name; }
+
+ inline unsigned int getID(void) const { return id; }
+
+ inline void setLastFocusedWindow(BlackboxWindow *w) { lastfocus = w; }
+
+ BlackboxWindow* getWindow(unsigned int index);
+ BlackboxWindow* getNextWindowInList(BlackboxWindow *w);
+ BlackboxWindow* getPrevWindowInList(BlackboxWindow *w);
+ BlackboxWindow* getTopWindowOnStack(void) const;
+ void sendWindowList(Netizen &n);
+
+ bool isCurrent(void) const;
+ bool isLastWindow(const BlackboxWindow* w) const;
+
+ void addWindow(BlackboxWindow *w, bool place = False);
+ unsigned int removeWindow(BlackboxWindow *w);
+ unsigned int getCount(void) const;
+
+ void showAll(void);
+ void hideAll(void);
+ void removeAll(void);
+ void raiseWindow(BlackboxWindow *w);
+ void lowerWindow(BlackboxWindow *w);
+ void reconfigure(void);
+ void updateFocusModel(void);
+ void setCurrent(void);
+ void setName(const std::string& new_name);
+};
+
+
+#endif // __Workspace_hh
+
-// Workspacemenu.cc for Openbox
-// Copyright (c) 2001 Sean 'Shaleh' Perry <shaleh@debian.org>
+// -*- mode: C++; indent-tabs-mode: nil; -*-
+// Workspacemenu.cc for Blackbox - an X11 Window manager
+// Copyright (c) 2001 - 2002 Sean 'Shaleh' Perry <shaleh@debian.org>
// Copyright (c) 1997 - 2000 Brad Hughes (bhughes@tcac.net)
//
// Permission is hereby granted, free of charge, to any person obtaining a
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
-// stupid macros needed to access some functions in version 2 of the GNU C
-// library
-#ifndef _GNU_SOURCE
-#define _GNU_SOURCE
-#endif // _GNU_SOURCE
-
#ifdef HAVE_CONFIG_H
# include "../config.h"
#endif // HAVE_CONFIG_H
-#include "i18n.h"
-#include "openbox.h"
-#include "Screen.h"
-#include "Toolbar.h"
-#include "Workspacemenu.h"
-#include "Workspace.h"
+#include "i18n.hh"
+#include "blackbox.hh"
+#include "Screen.hh"
+#include "Toolbar.hh"
+#include "Workspacemenu.hh"
+#include "Workspace.hh"
-Workspacemenu::Workspacemenu(BScreen &scrn) : Basemenu(scrn), screen(scrn) {
+Workspacemenu::Workspacemenu(BScreen *scrn) : Basemenu(scrn) {
setInternalMenu();
- setLabel(i18n(WorkspacemenuSet, WorkspacemenuWorkspacesTitle,
- "Workspaces"));
- insert(i18n(WorkspacemenuSet, WorkspacemenuNewWorkspace,
- "New Workspace"));
- insert(i18n(WorkspacemenuSet, WorkspacemenuRemoveLast,
- "Remove Last"));
+ setLabel(i18n(WorkspacemenuSet, WorkspacemenuWorkspacesTitle, "Workspaces"));
+ insert(i18n(WorkspacemenuSet, WorkspacemenuNewWorkspace, "New Workspace"));
+ insert(i18n(WorkspacemenuSet, WorkspacemenuRemoveLast, "Remove Last"));
}
-void Workspacemenu::itemSelected(int button, int index) {
+void Workspacemenu::itemSelected(int button, unsigned int index) {
if (button != 1)
return;
- if (index == 0)
- screen.addWorkspace();
- else if (index == 1)
- screen.removeLastWorkspace();
- else if ((screen.getCurrentWorkspace()->getWorkspaceID() !=
- (index - 2)) && ((index - 2) < screen.getWorkspaceCount()))
- screen.changeWorkspaceID(index - 2);
-
- if (! (screen.getWorkspacemenu()->isTorn() || isTorn()))
+ if (index == 0) {
+ getScreen()->addWorkspace();
+ } else if (index == 1) {
+ getScreen()->removeLastWorkspace();
+ } else {
+ index -= 2;
+ const Workspace* const wkspc = getScreen()->getCurrentWorkspace();
+ if (wkspc->getID() != index && index < getScreen()->getWorkspaceCount())
+ getScreen()->changeWorkspaceID(index);
+ }
+ if (! (getScreen()->getWorkspacemenu()->isTorn() || isTorn()))
hide();
}
-// WorkspaceMenu.h for Openbox - an X11 Window manager
-// Copyright (c) 2001 Sean 'Shaleh' Perry <shaleh@debian.org>
+// -*- mode: C++; indent-tabs-mode: nil; -*-
+// WorkspaceMenu.hh for Blackbox - an X11 Window manager
+// Copyright (c) 2001 - 2002 Sean 'Shaleh' Perry <shaleh@debian.org>
// Copyright (c) 1997 - 2000 Brad Hughes (bhughes@tcac.net)
//
// Permission is hereby granted, free of charge, to any person obtaining a
#ifndef __Workspacemenu_hh
#define __Workspacemenu_hh
-#include "Basemenu.h"
+#include "Basemenu.hh"
// forward declaration
class Workspacemenu;
class Workspacemenu : public Basemenu {
private:
- BScreen &screen;
+ Workspacemenu(const Workspacemenu&);
+ Workspacemenu& operator=(const Workspacemenu&);
protected:
- virtual void itemSelected(int, int);
+ virtual void itemSelected(int button, unsigned int index);
public:
- Workspacemenu(BScreen &);
+ Workspacemenu(BScreen *scrn);
};
+++ /dev/null
-// XAtom.cc for Openbox
-// Copyright (c) 2002 - 2002 Ben Jansens (xor at orodu.net)
-//
-// Permission is hereby granted, free of charge, to any person obtaining a
-// copy of this software and associated documentation files (the "Software"),
-// to deal in the Software without restriction, including without limitation
-// the rights to use, copy, modify, merge, publish, distribute, sublicense,
-// and/or sell copies of the Software, and to permit persons to whom the
-// Software is furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-// DEALINGS IN THE SOFTWARE.
-
-#include "XAtom.h"
-#include "openbox.h"
-#include "Screen.h"
-#include "Util.h"
-
-XAtom::XAtom(Openbox &ob) {
- _display = ob.getXDisplay();
-
-#ifdef HAVE_GETPID
- openbox_pid = getAtom("_BLACKBOX_PID");
-#endif // HAVE_GETPID
-
- wm_colormap_windows = getAtom("WM_COLORMAP_WINDOWS");
- wm_protocols = getAtom("WM_PROTOCOLS");
- wm_state = getAtom("WM_STATE");
- wm_change_state = getAtom("WM_CHANGE_STATE");
- wm_delete_window = getAtom("WM_DELETE_WINDOW");
- wm_take_focus = getAtom("WM_TAKE_FOCUS");
- motif_wm_hints = getAtom("_MOTIF_WM_HINTS");
- openbox_hints = getAtom("_BLACKBOX_HINTS");
- openbox_attributes = getAtom("_BLACKBOX_ATTRIBUTES");
- openbox_change_attributes = getAtom("_BLACKBOX_CHANGE_ATTRIBUTES");
-
- openbox_structure_messages = getAtom("_BLACKBOX_STRUCTURE_MESSAGES");
- openbox_notify_startup = getAtom("_BLACKBOX_NOTIFY_STARTUP");
- openbox_notify_window_add = getAtom("_BLACKBOX_NOTIFY_WINDOW_ADD");
- openbox_notify_window_del = getAtom("_BLACKBOX_NOTIFY_WINDOW_DEL");
- openbox_notify_current_workspace =
- getAtom("_BLACKBOX_NOTIFY_CURRENT_WORKSPACE");
- openbox_notify_workspace_count = getAtom("_BLACKBOX_NOTIFY_WORKSPACE_COUNT");
- openbox_notify_window_focus = getAtom("_BLACKBOX_NOTIFY_WINDOW_FOCUS");
- openbox_notify_window_raise = getAtom("_BLACKBOX_NOTIFY_WINDOW_RAISE");
- openbox_notify_window_lower = getAtom("_BLACKBOX_NOTIFY_WINDOW_LOWER");
-
- openbox_change_workspace = getAtom("_BLACKBOX_CHANGE_WORKSPACE");
- openbox_change_window_focus = getAtom("_BLACKBOX_CHANGE_WINDOW_FOCUS");
- openbox_cycle_window_focus = getAtom("_BLACKBOX_CYCLE_WINDOW_FOCUS");
-
- net_supported = getAtom("_NET_SUPPORTED");
- net_client_list = getAtom("_NET_CLIENT_LIST");
- net_client_list_stacking = getAtom("_NET_CLIENT_LIST_STACKING");
- net_number_of_desktops = getAtom("_NET_NUMBER_OF_DESKTOPS");
- net_desktop_geometry = getAtom("_NET_DESKTOP_GEOMETRY");
- net_desktop_viewport = getAtom("_NET_DESKTOP_VIEWPORT");
- net_current_desktop = getAtom("_NET_CURRENT_DESKTOP");
- net_desktop_names = getAtom("_NET_DESKTOP_NAMES");
- net_active_window = getAtom("_NET_ACTIVE_WINDOW");
- net_workarea = getAtom("_NET_WORKAREA");
- net_supporting_wm_check = getAtom("_NET_SUPPORTING_WM_CHECK");
- net_virtual_roots = getAtom("_NET_VIRTUAL_ROOTS");
-
- net_close_window = getAtom("_NET_CLOSE_WINDOW");
- net_wm_moveresize = getAtom("_NET_WM_MOVERESIZE");
-
- net_properties = getAtom("_NET_PROPERTIES");
- net_wm_name = getAtom("_NET_WM_NAME");
- net_wm_desktop = getAtom("_NET_WM_DESKTOP");
- net_wm_window_type = getAtom("_NET_WM_WINDOW_TYPE");
- net_wm_state = getAtom("_NET_WM_STATE");
- net_wm_strut = getAtom("_NET_WM_STRUT");
- net_wm_icon_geometry = getAtom("_NET_WM_ICON_GEOMETRY");
- net_wm_icon = getAtom("_NET_WM_ICON");
- net_wm_pid = getAtom("_NET_WM_PID");
- net_wm_handled_icons = getAtom("_NET_WM_HANDLED_ICONS");
-
- net_wm_ping = getAtom("_NET_WM_PING");
-
- for (unsigned int s = 0, c = ob.managedScreenCount(); s < c; ++s)
- setSupported( static_cast<ScreenInfo*>(ob.getScreen(s)) );
-}
-
-
-/*
- * clean up the class' members
- */
-XAtom::~XAtom() {
- while (!_support_windows.empty()) {
- // make sure we aren't fucking with this somewhere
- ASSERT(_support_windows.back() != None);
- XDestroyWindow(_display, _support_windows.back());
- _support_windows.pop_back();
- }
-}
-
-
-/*
- * Returns an atom from the Xserver, creating it if necessary.
- */
-Atom XAtom::getAtom(const char *name) const {
- return XInternAtom(_display, name, False);
-}
-
-
-/*
- * Sets which atoms are supported for NETWM, by Openbox, on the root window.
- */
-void XAtom::setSupported(const ScreenInfo *screen) {
- // create the netwm support window
- Window w = XCreateSimpleWindow(_display, screen->getRootWindow(),
- 0, 0, 1, 1, 0, 0, 0);
- ASSERT(w != None);
- _support_windows.push_back(w);
-
- // we don't support any yet..
-}
-
-
-/*
- * Internal setValue used by all typed setValue functions.
- * Sets a window property on a window, optionally appending to the existing
- * value.
- */
-void XAtom::setValue(Window win, Atom atom, Atom type, unsigned char* data,
- int size, int nelements, bool append) const {
- ASSERT(win != None); ASSERT(atom != None); ASSERT(type != None);
- ASSERT(data != (unsigned char *) 0);
- ASSERT(size == 8 || size == 16 || size == 32);
- ASSERT(nelements > 0);
- XChangeProperty(_display, win, atom, type, size,
- (append ? PropModeAppend : PropModeReplace),
- data, nelements);
-}
-
-
-/*
- * Set a 32-bit CARDINAL property value on a window.
- */
-void XAtom::setCardValue(Window win, Atom atom, long value) const {
- setValue(win, atom, XA_CARDINAL, reinterpret_cast<unsigned char*>(&value),
- 32, 1, false);
-}
-
-
-/*
- * Set an Atom property value on a window.
- */
-void XAtom::setAtomValue(Window win, Atom atom, Atom value) const {
- setValue(win, atom, XA_ATOM, reinterpret_cast<unsigned char*>(&value),
- 32, 1, false);
-}
-
-
-/*
- * Set a Window property value on a window.
- */
-void XAtom::setWindowValue(Window win, Atom atom, Window value) const {
- setValue(win, atom, XA_WINDOW, reinterpret_cast<unsigned char*>(&value),
- 32, 1, false);
-}
-
-
-/*
- * Set a Pixmap property value on a window.
- */
-void XAtom::setPixmapValue(Window win, Atom atom, Pixmap value) const {
- setValue(win, atom, XA_PIXMAP, reinterpret_cast<unsigned char*>(&value),
- 32, 1, false);
-}
-
-
-/*
- * Set a string property value on a window.
- */
-void XAtom::setStringValue(Window win, Atom atom,
- const std::string &value) const {
- setValue(win, atom, XA_STRING,
- const_cast<unsigned char*>
- (reinterpret_cast<const unsigned char*>(value.c_str())),
- 8, value.size(), false);
-}
-
-
-/*
- * Add elements to a 32-bit CARDINAL property value on a window.
- */
-void XAtom::addCardValue(Window win, Atom atom, long value) const {
- setValue(win, atom, XA_CARDINAL, reinterpret_cast<unsigned char*>(&value),
- 32, 1, true);
-}
-
-
-/*
- * Add elements to an Atom property value on a window.
- */
-void XAtom::addAtomValue(Window win, Atom atom, Atom value) const {
- setValue(win, atom, XA_ATOM, reinterpret_cast<unsigned char*>(&value),
- 32, 1, true);
-}
-
-
-/*
- * Add elements to a Window property value on a window.
- */
-void XAtom::addWindowValue(Window win, Atom atom, Window value) const {
- setValue(win, atom, XA_WINDOW, reinterpret_cast<unsigned char*>(&value),
- 32, 1, true);
-}
-
-
-/*
- * Add elements to a Pixmap property value on a window.
- */
-void XAtom::addPixmapValue(Window win, Atom atom, Pixmap value) const {
- setValue(win, atom, XA_PIXMAP, reinterpret_cast<unsigned char*>(&value),
- 32, 1, true);
-}
-
-
-/*
- * Add characters to a string property value on a window.
- */
-void XAtom::addStringValue(Window win, Atom atom,
- const std::string &value) const {
- setValue(win, atom, XA_STRING,
- const_cast<unsigned char*>
- (reinterpret_cast<const unsigned char *>
- (value.c_str())),
- 8, value.size(), true);
-}
-
-
-/*
- * Internal getValue function used by all of the typed getValue functions.
- * Gets an property's value from a window.
- * Returns true if the property was successfully retrieved; false if the
- * property did not exist on the window, or has a different type/size format
- * than the user tried to retrieve.
- */
-bool XAtom::getValue(Window win, Atom atom, Atom type, unsigned long *nelements,
- unsigned char **value, int size) const {
- unsigned char *c_val; // value alloc'd with c malloc
- Atom ret_type;
- int ret_size;
- unsigned long ret_bytes;
- XGetWindowProperty(_display, win, atom, 0l, 1l, False, AnyPropertyType,
- &ret_type, &ret_size, nelements, &ret_bytes,
- &c_val); // try get the first element
- if (ret_type == None)
- // the property does not exist on the window
- return false;
- if (ret_type != type || ret_size != size) {
- // wrong data in property
- XFree(c_val);
- return false;
- }
- // the data is correct, now, is there more than 1 element?
- if (ret_bytes == 0) {
- // we got the whole property's value
- *value = new unsigned char[*nelements * size/8 + 1];
- memcpy(*value, c_val, *nelements * size/8 + 1);
- XFree(c_val);
- return true;
- }
- // get the entire property since it is larger than one long
- free(c_val);
- // the number of longs that need to be retreived to get the property's entire
- // value. The last + 1 is the first long that we retrieved above.
- const int remain = (ret_bytes - 1)/sizeof(long) + 1 + 1;
- XGetWindowProperty(_display, win, atom, 0l, remain, False, type, &ret_type,
- &ret_size, nelements, &ret_bytes, &c_val);
- ASSERT(ret_bytes == 0);
- *value = new unsigned char[*nelements * size/8 + 1];
- memcpy(*value, c_val, *nelements * size/8 + 1);
- XFree(c_val);
- return true;
-}
-
-
-/*
- * Gets a 32-bit Cardinal property's value from a window.
- */
-bool XAtom::getCardValue(Window win, Atom atom, unsigned long *nelements,
- long **value) const {
- return XAtom::getValue(win, atom, XA_CARDINAL, nelements,
- reinterpret_cast<unsigned char **>(value), 32);
-}
-
-
-/*
- * Gets an Atom property's value from a window.
- */
-bool XAtom::getAtomValue(Window win, Atom atom, unsigned long *nelements,
- Atom **value) const {
- return XAtom::getValue(win, atom, XA_ATOM, nelements,
- reinterpret_cast<unsigned char **>(value), 32);
-}
-
-
-/*
- * Gets an Window property's value from a window.
- */
-bool XAtom::getWindowValue(Window win, Atom atom, unsigned long *nelements,
- Window **value) const {
- return XAtom::getValue(win, atom, XA_WINDOW, nelements,
- reinterpret_cast<unsigned char **>(value), 32);
-}
-
-
-/*
- * Gets an Pixmap property's value from a window.
- */
-bool XAtom::getPixmapValue(Window win, Atom atom, unsigned long *nelements,
- Pixmap **value) const {
- return XAtom::getValue(win, atom, XA_PIXMAP, nelements,
- reinterpret_cast<unsigned char **>(value), 32);
-}
-
-
-/*
- * Gets an string property's value from a window.
- */
-bool XAtom::getStringValue(Window win, Atom atom, std::string &value) const {
- unsigned char *data;
- unsigned long nelements;
- bool ret = XAtom::getValue(win, atom, XA_STRING, &nelements, &data, 8);
- if (ret)
- value = reinterpret_cast<char*>(data);
- return ret;
-}
-
-
-/*
- * Removes a property entirely from a window.
- */
-void XAtom::eraseValue(Window win, Atom atom) const {
- XDeleteProperty(_display, win, atom);
-}
+++ /dev/null
-// XAtom.h for Openbox
-// Copyright (c) 2002 - 2002 Ben Janens (ben at orodu.net)
-//
-// Permission is hereby granted, free of charge, to any person obtaining a
-// copy of this software and associated documentation files (the "Software"),
-// to deal in the Software without restriction, including without limitation
-// the rights to use, copy, modify, merge, publish, distribute, sublicense,
-// and/or sell copies of the Software, and to permit persons to whom the
-// Software is furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-// DEALINGS IN THE SOFTWARE.
-
-#ifndef __XAtom_h
-#define __XAtom_h
-
-#include "../config.h"
-
-#include <X11/Xlib.h>
-#include <X11/Xatom.h>
-#include <vector>
-#include <string>
-
-class Openbox;
-class ScreenInfo;
-
-class XAtom {
- typedef std::vector<Window> SupportWindows;
-
- Display *_display;
- // windows used to specify support for NETWM
- SupportWindows _support_windows;
-
- Atom
-#ifdef HAVE_GETPID
- openbox_pid,
-#endif // HAVE_GETPID
-
- // window hints
- wm_colormap_windows,
- wm_protocols,
- wm_state,
- wm_delete_window,
- wm_take_focus,
- wm_change_state,
- motif_wm_hints,
- openbox_attributes,
- openbox_change_attributes,
- openbox_hints,
-
- // blackbox-protocol atoms (wm -> client)
- openbox_structure_messages,
- openbox_notify_startup,
- openbox_notify_window_add,
- openbox_notify_window_del,
- openbox_notify_window_focus,
- openbox_notify_current_workspace,
- openbox_notify_workspace_count,
- openbox_notify_window_raise,
- openbox_notify_window_lower,
- // blackbox-protocol atoms (client -> wm)
- openbox_change_workspace,
- openbox_change_window_focus,
- openbox_cycle_window_focus,
-
- // NETWM atoms
- // root window properties
- net_supported,
- net_client_list,
- net_client_list_stacking,
- net_number_of_desktops,
- net_desktop_geometry,
- net_desktop_viewport,
- net_current_desktop,
- net_desktop_names,
- net_active_window,
- net_workarea,
- net_supporting_wm_check,
- net_virtual_roots,
- // root window messages
- net_close_window,
- net_wm_moveresize,
- // application window properties
- net_properties,
- net_wm_name,
- net_wm_desktop,
- net_wm_window_type,
- net_wm_state,
- net_wm_strut,
- net_wm_icon_geometry,
- net_wm_icon,
- net_wm_pid,
- net_wm_handled_icons,
- // application protocols
- net_wm_ping;
-
- Atom getAtom(const char *name) const;
- void setSupported(const ScreenInfo *screen);
-
- void setValue(Window win, Atom atom, Atom type, unsigned char *data,
- int size, int nelements, bool append) const;
- bool getValue(Window win, Atom atom, Atom type, unsigned long *nelements,
- unsigned char **value, int size) const;
-
- // no copying!!
- XAtom(const XAtom &);
- XAtom& operator=(const XAtom&);
-
-public:
- XAtom(Openbox &ob);
- virtual ~XAtom();
-
- void setCardValue(Window win, Atom atom, long value) const; // 32-bit CARDINAL
- void setAtomValue(Window win, Atom atom, Atom value) const;
- void setWindowValue(Window win, Atom atom, Window value) const;
- void setPixmapValue(Window win, Atom atom, Pixmap value) const;
- void setStringValue(Window win, Atom atom, const std::string &value) const;
-
- void addCardValue(Window win, Atom atom, long value) const; // 32-bit CARDINAL
- void addAtomValue(Window win, Atom atom, Atom value) const;
- void addWindowValue(Window win, Atom atom, Window value) const;
- void addPixmapValue(Window win, Atom atom, Pixmap value) const;
- void addStringValue(Window win, Atom atom, const std::string &value) const;
-
- // the 'value' is allocated inside the function and
- // delete [] value needs to be called when you are done with it.
- // teh 'value' array returned is null terminated, and has 'nelements'
- // elements in it plus the null.
- bool getCardValue(Window win, Atom atom, unsigned long *nelements,
- long **value) const; // 32-bit CARDINAL
- bool getAtomValue(Window win, Atom atom, unsigned long *nelements,
- Atom **value) const;
- bool getWindowValue(Window win, Atom atom, unsigned long *nelements,
- Window **value) const;
- bool getPixmapValue(Window win, Atom atom, unsigned long *nelements,
- Pixmap **value) const;
- bool getStringValue(Window win, Atom atom, std::string &value) const;
-
- void eraseValue(Window win, Atom atom) const;
-
-#ifdef HAVE_GETPID
- inline Atom openboxPid() const { return openbox_pid; }
-#endif // HAVE_GETPID
-
- inline Atom wmChangeState() const { return wm_change_state; }
- inline Atom wmState() const { return wm_state; }
- inline Atom wmDelete() const { return wm_delete_window; }
- inline Atom wmProtocols() const { return wm_protocols; }
- inline Atom wmTakeFocus() const { return wm_take_focus; }
- inline Atom wmColormap() const { return wm_colormap_windows; }
- inline Atom motifWMHints() const { return motif_wm_hints; }
-
- // this atom is for normal app->WM hints about decorations, stacking,
- // starting workspace etc...
- inline Atom openboxHints() const { return openbox_hints;}
-
- // these atoms are for normal app->WM interaction beyond the scope of the
- // ICCCM...
- inline Atom openboxAttributes() const { return openbox_attributes; }
- inline Atom openboxChangeAttributes() const
- { return openbox_change_attributes; }
-
- // these atoms are for window->WM interaction, with more control and
- // information on window "structure"... common examples are
- // notifying apps when windows are raised/lowered... when the user changes
- // workspaces... i.e. "pager talk"
- inline Atom openboxStructureMessages() const
- { return openbox_structure_messages; }
-
- inline Atom openboxNotifyStartup() const
- { return openbox_notify_startup; }
- inline Atom openboxNotifyWindowAdd() const
- { return openbox_notify_window_add; }
- inline Atom openboxNotifyWindowDel() const
- { return openbox_notify_window_del; }
- inline Atom openboxNotifyWindowFocus() const
- { return openbox_notify_window_focus; }
- inline Atom openboxNotifyCurrentWorkspace() const
- { return openbox_notify_current_workspace; }
- inline Atom openboxNotifyWorkspaceCount() const
- { return openbox_notify_workspace_count; }
- inline Atom openboxNotifyWindowRaise() const
- { return openbox_notify_window_raise; }
- inline Atom openboxNotifyWindowLower() const
- { return openbox_notify_window_lower; }
-
- // atoms to change that request changes to the desktop environment during
- // runtime... these messages can be sent by any client... as the sending
- // client window id is not included in the ClientMessage event...
- inline Atom openboxChangeWorkspace() const
- { return openbox_change_workspace; }
- inline Atom openboxChangeWindowFocus() const
- { return openbox_change_window_focus; }
- inline Atom openboxCycleWindowFocus() const
- { return openbox_cycle_window_focus; }
-
- // root window properties
- inline Atom netClientList() const { return net_client_list; }
- inline Atom netClientListStacking() const { return net_client_list_stacking; }
- inline Atom netNumberOfDesktops() const { return net_number_of_desktops; }
- inline Atom netDesktopGeometry() const { return net_desktop_geometry; }
- inline Atom netDesktopViewport() const { return net_desktop_viewport; }
- inline Atom netCurrentDesktop() const { return net_current_desktop; }
- inline Atom netDesktopNames() const { return net_desktop_names; }
- inline Atom netActiveWindow() const { return net_active_window; }
- inline Atom netWorkarea() const { return net_workarea; }
- inline Atom netSupportingWMCheck() const { return net_supporting_wm_check; }
- inline Atom netVirtualRoots() const { return net_virtual_roots; }
-
- // root window messages
- inline Atom netCloseWindow() const { return net_close_window; }
- inline Atom netWMMoveResize() const { return net_wm_moveresize; }
-
- // application window properties
- inline Atom netProperties() const { return net_properties; }
- inline Atom netWMName() const { return net_wm_name; }
- inline Atom netWMDesktop() const { return net_wm_desktop; }
- inline Atom netWMWindowType() const { return net_wm_window_type; }
- inline Atom netWMState() const { return net_wm_state; }
- inline Atom netWMStrut() const { return net_wm_strut; }
- inline Atom netWMIconGeometry() const { return net_wm_icon_geometry; }
- inline Atom netWMIcon() const { return net_wm_icon; }
- inline Atom netWMPid() const { return net_wm_pid; }
- inline Atom netWMHandledIcons() const { return net_wm_handled_icons; }
-
- // application protocols
- inline Atom netWMPing() const { return net_wm_ping; }
-};
-
-#endif // __XAtom_h
+++ /dev/null
-// XDisplay.cc for Openbox
-// Copyright (c) 2002 - 2002 Ben Janens (ben at orodu.net)
-//
-// Permission is hereby granted, free of charge, to any person obtaining a
-// copy of this software and associated documentation files (the "Software"),
-// to deal in the Software without restriction, including without limitation
-// the rights to use, copy, modify, merge, publish, distribute, sublicense,
-// and/or sell copies of the Software, and to permit persons to whom the
-// Software is furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-// DEALINGS IN THE SOFTWARE.
-
-#ifdef HAVE_CONFIG_H
-# include "../config.h"
-#endif
-
-#ifdef HAVE_UNNISTD_H
-# include <unistd.h>
-#endif
-
-#ifdef HAVE_FCNTL_H
-# include <fcntl.h>
-#endif
-
-#ifdef SHAPE
-# include <X11/extensions/shape.h>
-#endif
-
-#include "XDisplay.h"
-#include "Util.h"
-#include <iostream>
-#include <algorithm>
-
-using std::cerr;
-using std::endl;
-
-std::string XDisplay::_app_name;
-Window XDisplay::_last_bad_window = None;
-
-/*
- * X error handler to handle all X errors while the application is
- * running.
- */
-int XDisplay::errorHandler(Display *d, XErrorEvent *e) {
-#ifdef DEBUG
- char errtxt[128];
- XGetErrorText(d, e->error_code, errtxt, sizeof(errtxt)/sizeof(char));
- cerr << _app_name.c_str() << ": X error: " <<
- errtxt << "(" << e->error_code << ") opcodes " <<
- e->request_code << "/" << e->minor_code << endl;
- cerr.flags(std::ios_base::hex);
- cerr << " resource 0x" << e->resourceid << endl;
- cerr.flags(std::ios_base::dec);
-#endif
-
- if (e->error_code == BadWindow)
- _last_bad_window = e->resourceid;
-
- return False;
-}
-
-
-XDisplay::XDisplay(const std::string &application_name, const char *dpyname) {
- _app_name = application_name;
- _grabs = 0;
- _hasshape = false;
-
- _display = XOpenDisplay(dpyname);
- if (_display == NULL) {
- cerr << "Could not open display. Connection to X server failed.\n";
- ::exit(2);
- }
- if (-1 == fcntl(ConnectionNumber(_display), F_SETFD, 1)) {
- cerr << "Could not mark display connection as close-on-exec.\n";
- ::exit(2);
- }
- _name = XDisplayName(dpyname);
-
- XSetErrorHandler(errorHandler);
-
-#ifdef SHAPE
- int waste;
- _hasshape = XShapeQueryExtension(_display, &_shape_event_base, &waste);
-#endif // SHAPE
-
-#ifndef NOCLOBBER
- getLockModifiers();
-#endif
-}
-
-
-XDisplay::~XDisplay() {
- std::for_each(_screens.begin(), _screens.end(), PointerAssassin());
- XCloseDisplay(_display);
-}
-
-
-/*
- * Grab the X server
- */
-void XDisplay::grab() {
- if (_grabs++ == 0)
- XGrabServer(_display);
-}
-
-
-/*
- * Release the X server from a grab
- */
-void XDisplay::ungrab() {
- if (--_grabs == 0)
- XUngrabServer(_display);
-}
-
-
-/*
- * Gets the next event on the queue from the X server.
- *
- * Returns: true if e contains a new event; false if there is no event to be
- * returned.
- */
-bool XDisplay::nextEvent(XEvent &e) {
- if(!XPending(_display))
- return false;
- XNextEvent(_display, &e);
- if (_last_bad_window != None) {
- if (e.xany.window == _last_bad_window) {
- cerr << "XDisplay::nextEvent(): Removing event for bad window from " <<
- "event queue\n";
- return false;
- } else
- _last_bad_window = None;
- }
- return true;
-}
-
-
-int XDisplay::connectionNumber() const {
- return ConnectionNumber(_display);
-}
-
-
-/*
- * Creates a font cursor in the X server and returns it.
- */
-Cursor createCursor(unsigned int shape) const {
- return XCreateFontCursor(_display, shape);
-}
-
-
-#ifndef NOCLOBBER
-void XDisplay::getLockModifers() {
- NumLockMask = ScrollLockMask = 0;
-
- const XModifierKeymap* const modmap = XGetModifierMapping(display);
- if (modmap && modmap->max_keypermod > 0) {
- const int mask_table[] = {
- ShiftMask, LockMask, ControlMask, Mod1Mask,
- Mod2Mask, Mod3Mask, Mod4Mask, Mod5Mask
- };
- const size_t size = (sizeof(mask_table) / sizeof(mask_table[0])) *
- modmap->max_keypermod;
- // get the values of the keyboard lock modifiers
- // Note: Caps lock is not retrieved the same way as Scroll and Num lock
- // since it doesn't need to be.
- const KeyCode num_lock_code = XKeysymToKeycode(display, XK_Num_Lock);
- const KeyCode scroll_lock_code = XKeysymToKeycode(display, XK_Scroll_Lock);
-
- for (size_t cnt = 0; cnt < size; ++cnt) {
- if (! modmap->modifiermap[cnt]) continue;
-
- if (num_lock_code == modmap->modifiermap[cnt])
- NumLockMask = mask_table[cnt / modmap->max_keypermod];
- if (scroll_lock_code == modmap->modifiermap[cnt])
- ScrollLockMask = mask_table[cnt / modmap->max_keypermod];
- }
- }
-
- MaskList[0] = 0;
- MaskList[1] = LockMask;
- MaskList[2] = NumLockMask;
- MaskList[3] = ScrollLockMask;
- MaskList[4] = LockMask | NumLockMask;
- MaskList[5] = NumLockMask | ScrollLockMask;
- MaskList[6] = LockMask | ScrollLockMask;
- MaskList[7] = LockMask | NumLockMask | ScrollLockMask;
-
- if (modmap) XFreeModifiermap(const_cast<XModifierKeymap*>(modmap));
-}
-#endif // NOCLOBBER
-
-unsigned int XDisplay::stripModifiers(const unsigned int state) const {
-#ifndef NOCLOBBER
- return state &= ~(NumLockMask() | ScrollLockMask | LockMask);
-#else
- return state &= ~LockMask;
-#endif
-}
-
-
-/*
- * Verifies that a window has not requested to be destroyed/unmapped, so
- * if it is a valid window or not.
- * Returns: true if the window is valid; false if it is no longer valid.
- */
-bool XDisplay::validateWindow(Window window) {
- XEvent event;
- if (XCheckTypedWindowEvent(_display, window, DestroyNotify, &event)) {
- XPutBackEvent(display, &event);
- return false;
- }
- return true;
-}
-
-
-/*
- * Grabs a button, but also grabs the button in every possible combination with
- * the keyboard lock keys, so that they do not cancel out the event.
- */
-void BaseDisplay::grabButton(unsigned int button, unsigned int modifiers,
- Window grab_window, Bool owner_events,
- unsigned int event_mask, int pointer_mode,
- int keybaord_mode, Window confine_to,
- Cursor cursor) const
-{
-#ifndef NOCLOBBER
- for (size_t cnt = 0; cnt < 8; ++cnt)
- XGrabButton(_display, button, modifiers | MaskList[cnt], grab_window,
- owner_events, event_mask, pointer_mode, keybaord_mode,
- confine_to, cursor);
-#else // NOCLOBBER
- XGrabButton(_display, button, modifiers, grab_window,
- owner_events, event_mask, pointer_mode, keybaord_mode,
- confine_to, cursor);
-#endif // NOCLOBBER
-}
-
-
-/*
- * Releases the grab on a button, and ungrabs all possible combinations of the
- * keyboard lock keys.
- */
-void BaseDisplay::ungrabButton(unsigned int button, unsigned int modifiers,
- Window grab_window) const {
-#ifndef NOCLOBBER
- for (size_t cnt = 0; cnt < 8; ++cnt)
- XUngrabButton(display, button, modifiers | MaskList[cnt], grab_window);
-#else // NOCLOBBER
- XUngrabButton(display, button, modifiers, grab_window);
-#endif // NOCLOBBER
-}
+++ /dev/null
-// XDisplay.h for Openbox
-// Copyright (c) 2002 - 2002 Ben Janens (ben at orodu.net)
-//
-// Permission is hereby granted, free of charge, to any person obtaining a
-// copy of this software and associated documentation files (the "Software"),
-// to deal in the Software without restriction, including without limitation
-// the rights to use, copy, modify, merge, publish, distribute, sublicense,
-// and/or sell copies of the Software, and to permit persons to whom the
-// Software is furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-// DEALINGS IN THE SOFTWARE.
-
-#ifndef __XDisplay_h
-#define __XDisplay_h
-
-#include <X11/Xlib.h>
-#include <string>
-#include <vector>
-#include "XAtom.h"
-#include "XScreen.h"
-
-class XDisplay {
- friend XAtom::XAtom(const XDisplay *);
- friend XScreen::XScreen(const XDisplay *, const unsigned int);
-
-private:
- Display *_display;
- std::string _name;
- unsigned int _grabs;
- bool _hasshape;
- int _shape_event_base;
-
-#ifndef NOCLOBBER
- // the server's values for the lock key modifiers
- void getLockModifiers();
- unsigned int MaskList[8];
- // the masks of the modifiers which are ignored in button events.
- int NumLockMask, ScrollLockMask;
-#endif // NOCLOBBER
-
-
- // X error handling
- static int errorHandler(Display *d, XErrorEvent *e);
- static std::string _app_name;
- static Window _last_bad_window;
-
- // no copying!!
- XDisplay(const XDisplay &);
- XDisplay& operator=(const XDisplay&);
-
-protected:
- virtual void process_event(XEvent *) = 0;
-
-public:
- XDisplay(const std::string &application_name, const char *dpyname = 0);
- virtual ~XDisplay();
-
- inline virtual unsigned int screenCount() const
- { return ScreenCount(_display); }
-
- inline bool hasShape() const { return _hasshape; }
- inline int shapeEventBase() const { return _shape_event_base; }
-
- //inline Display *display() const { return _display; }
-
- inline std::string applicationName() const { return _app_name; }
- inline std::string name() const { return _name; }
-
- void grab();
- void ungrab();
-
- bool nextEvent(XEvent &e);
-
- int connectionNumber() const;
-
- Cursor createCursor(unsigned int shape) const;
-
- unsigned int stripModifiers(const unsigned int state) const;
-
- // these belong in Xwindow
- const bool validateWindow(Window);
- void grabButton(unsigned int, unsigned int, Window, Bool, unsigned int, int,
- int, Window, Cursor) const;
- void ungrabButton(unsigned int button, unsigned int modifiers,
- Window grab_window) const;
-};
-
-#endif // _XDisplay_h
+++ /dev/null
-// XScreen.cc for Openbox
-// Copyright (c) 2002 - 2002 Ben Janens (ben at orodu.net)
-//
-// Permission is hereby granted, free of charge, to any person obtaining a
-// copy of this software and associated documentation files (the "Software"),
-// to deal in the Software without restriction, including without limitation
-// the rights to use, copy, modify, merge, publish, distribute, sublicense,
-// and/or sell copies of the Software, and to permit persons to whom the
-// Software is furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-// DEALINGS IN THE SOFTWARE.
-
-#include <X11/Xutil.h>
-#include "XScreen.h"
-#include "XDisplay.h"
-#include "Geometry.h"
-
-XScreen::XScreen(const XDisplay *display, const unsigned int number) {
- _display = display->_display;
- _number = number;
-
- _root = RootWindow(_display, _number);
- _size = Size(WidthOfScreen(ScreenOfDisplay(_display, _number)),
- HeightOfScreen(ScreenOfDisplay(_display, _number)));
- setColorData();
-}
-
-
-XScreen::~XScreen() {
-}
-
-
-/*
- * This sets up the _depth, _visual, and _colormap properties.
- */
-void XScreen::setColorData() {
- _depth = DefaultDepth(_display, _number);
- _visual = (Visual *) 0;
-
- // search for a TrueColor Visual. If we can't find one, use the default
- // visual for the screen
- XVisualInfo vinfo_template, *vinfo_return;
- int vinfo_nitems;
-
- vinfo_template.screen = _number;
- vinfo_template.c_class = TrueColor;
-
- vinfo_return = XGetVisualInfo(_display, VisualScreenMask | VisualClassMask,
- &vinfo_template, &vinfo_nitems);
- if (vinfo_return && vinfo_nitems > 0) {
- for (int i = 0; i < vinfo_nitems; i++)
- if (_depth < (vinfo_return + i)->depth) {
- _depth = (vinfo_return + i)->depth;
- _visual = (vinfo_return + i)->visual;
- }
- XFree(vinfo_return);
- }
- if (_visual)
- _colormap = XCreateColormap(_display, _root, _visual, AllocNone);
- else {
- _visual = DefaultVisual(_display, _number);
- _colormap = DefaultColormap(_display, _number);
- }
-}
-
-
-/*
- * Creates a window on screen.
- */
-Window createWindow(Window parent, const Rect &area, int borderw,
- unsigned int winclass, unsigned long attrib_mask,
- XSetWindowAttributes *attrib) const {
- return XCreateWindow(_display, parent,
- area.x(), area.y(), area.w(), area.h(),
- borderw, depth(), winclass, visual(),
- attrib_mask, attrib);
-}
+++ /dev/null
-// XScreen.h for Openbox
-// Copyright (c) 2002 - 2002 Ben Janens (ben at orodu.net)
-//
-// Permission is hereby granted, free of charge, to any person obtaining a
-// copy of this software and associated documentation files (the "Software"),
-// to deal in the Software without restriction, including without limitation
-// the rights to use, copy, modify, merge, publish, distribute, sublicense,
-// and/or sell copies of the Software, and to permit persons to whom the
-// Software is furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-// DEALINGS IN THE SOFTWARE.
-
-#ifndef __XScreen_h
-#define __XScreen_h
-
-#include <X11/Xlib.h>
-#include "Geometry.h"
-
-class XDisplay;
-
-class XScreen {
-private:
- Display *_display;
- unsigned int _number;
- Visual *_visual;
- Window _root;
- Colormap _colormap;
- int _depth;
- Size _size;
-
- void setColorData();
-
- // no copying!!
- XScreen(const XScreen &);
- XScreen& operator=(const XScreen&);
-
-public:
- XScreen(const XDisplay *display, const unsigned int number);
- virtual ~XScreen();
-
- inline Visual *visual() const { return _visual; }
- inline Window rootWindow() const { return _root; }
- inline Colormap colormap() const { return _colormap; }
- inline unsigned int depth() const { return _depth; }
- inline unsigned int number() const { return _number; }
- inline const Size &size() const { return _size; }
-
- Window createWindow(Window parent, const Rect &area, int borderw,
- unsigned int winclass,
- unsigned long attrib_mask,
- XSetWindowAttributes *attrib) const;
-};
-
-#endif // __XScreen_h
--- /dev/null
+// -*- mode: C++; indent-tabs-mode: nil; c-basic-offset: 2; -*-
+// blackbox.cc for Blackbox - an X11 Window manager
+// Copyright (c) 2001 - 2002 Sean 'Shaleh' Perry <shaleh@debian.org>
+// Copyright (c) 1997 - 2000 Brad Hughes (bhughes@tcac.net)
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#ifdef HAVE_CONFIG_H
+# include "../config.h"
+#endif // HAVE_CONFIG_H
+
+extern "C" {
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <X11/Xresource.h>
+#include <X11/Xatom.h>
+#include <X11/cursorfont.h>
+#include <X11/keysym.h>
+
+#ifdef SHAPE
+#include <X11/extensions/shape.h>
+#endif // SHAPE
+
+#ifdef HAVE_STDIO_H
+# include <stdio.h>
+#endif // HAVE_STDIO_H
+
+#ifdef HAVE_STDLIB_H
+# include <stdlib.h>
+#endif // HAVE_STDLIB_H
+
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif // HAVE_STRING_H
+
+#ifdef HAVE_UNISTD_H
+# include <sys/types.h>
+# include <unistd.h>
+#endif // HAVE_UNISTD_H
+
+#ifdef HAVE_SYS_PARAM_H
+# include <sys/param.h>
+#endif // HAVE_SYS_PARAM_H
+
+#ifdef HAVE_SYS_SELECT_H
+# include <sys/select.h>
+#endif // HAVE_SYS_SELECT_H
+
+#ifdef HAVE_SIGNAL_H
+# include <signal.h>
+#endif // HAVE_SIGNAL_H
+
+#ifdef HAVE_SYS_SIGNAL_H
+# include <sys/signal.h>
+#endif // HAVE_SYS_SIGNAL_H
+
+#ifdef HAVE_SYS_STAT_H
+# include <sys/types.h>
+# include <sys/stat.h>
+#endif // HAVE_SYS_STAT_H
+
+#ifdef TIME_WITH_SYS_TIME
+# include <sys/time.h>
+# include <time.h>
+#else // !TIME_WITH_SYS_TIME
+# ifdef HAVE_SYS_TIME_H
+# include <sys/time.h>
+# else // !HAVE_SYS_TIME_H
+# include <time.h>
+# endif // HAVE_SYS_TIME_H
+#endif // TIME_WITH_SYS_TIME
+
+#ifdef HAVE_LIBGEN_H
+# include <libgen.h>
+#endif // HAVE_LIBGEN_H
+}
+
+#include <algorithm>
+#include <string>
+using std::string;
+
+#include "i18n.hh"
+#include "blackbox.hh"
+#include "Basemenu.hh"
+#include "Clientmenu.hh"
+#include "GCCache.hh"
+#include "Image.hh"
+#include "Rootmenu.hh"
+#include "Screen.hh"
+#include "Slit.hh"
+#include "Toolbar.hh"
+#include "Util.hh"
+#include "Window.hh"
+#include "Workspace.hh"
+#include "Workspacemenu.hh"
+
+
+// X event scanner for enter/leave notifies - adapted from twm
+struct scanargs {
+ Window w;
+ bool leave, inferior, enter;
+};
+
+static Bool queueScanner(Display *, XEvent *e, char *args) {
+ scanargs *scan = (scanargs *) args;
+ if ((e->type == LeaveNotify) &&
+ (e->xcrossing.window == scan->w) &&
+ (e->xcrossing.mode == NotifyNormal)) {
+ scan->leave = True;
+ scan->inferior = (e->xcrossing.detail == NotifyInferior);
+ } else if ((e->type == EnterNotify) && (e->xcrossing.mode == NotifyUngrab)) {
+ scan->enter = True;
+ }
+
+ return False;
+}
+
+Blackbox *blackbox;
+
+
+Blackbox::Blackbox(char **m_argv, char *dpy_name, char *rc)
+ : BaseDisplay(m_argv[0], dpy_name) {
+ if (! XSupportsLocale())
+ fprintf(stderr, "X server does not support locale\n");
+
+ if (XSetLocaleModifiers("") == NULL)
+ fprintf(stderr, "cannot set locale modifiers\n");
+
+ ::blackbox = this;
+ argv = m_argv;
+ if (! rc) rc = "~/.blackboxrc";
+ rc_file = expandTilde(rc);
+
+ no_focus = False;
+
+ resource.auto_raise_delay.tv_sec = resource.auto_raise_delay.tv_usec = 0;
+
+ active_screen = 0;
+ focused_window = (BlackboxWindow *) 0;
+
+ XrmInitialize();
+ load_rc();
+
+ init_icccm();
+
+ cursor.session = XCreateFontCursor(getXDisplay(), XC_left_ptr);
+ cursor.move = XCreateFontCursor(getXDisplay(), XC_fleur);
+ cursor.ll_angle = XCreateFontCursor(getXDisplay(), XC_ll_angle);
+ cursor.lr_angle = XCreateFontCursor(getXDisplay(), XC_lr_angle);
+
+ for (unsigned int i = 0; i < getNumberOfScreens(); i++) {
+ BScreen *screen = new BScreen(this, i);
+
+ if (! screen->isScreenManaged()) {
+ delete screen;
+ continue;
+ }
+
+ screenList.push_back(screen);
+ }
+
+ if (screenList.empty()) {
+ fprintf(stderr,
+ i18n(blackboxSet, blackboxNoManagableScreens,
+ "Blackbox::Blackbox: no managable screens found, aborting.\n"));
+ ::exit(3);
+ }
+
+ // set the screen with mouse to the first managed screen
+ active_screen = screenList.front();
+ setFocusedWindow(0);
+
+ XSynchronize(getXDisplay(), False);
+ XSync(getXDisplay(), False);
+
+ reconfigure_wait = reread_menu_wait = False;
+
+ timer = new BTimer(this, this);
+ timer->setTimeout(0l);
+}
+
+
+Blackbox::~Blackbox(void) {
+ std::for_each(screenList.begin(), screenList.end(), PointerAssassin());
+
+ std::for_each(menuTimestamps.begin(), menuTimestamps.end(),
+ PointerAssassin());
+
+ delete timer;
+}
+
+
+void Blackbox::process_event(XEvent *e) {
+ switch (e->type) {
+ case ButtonPress: {
+ // strip the lock key modifiers
+ e->xbutton.state &= ~(NumLockMask | ScrollLockMask | LockMask);
+
+ last_time = e->xbutton.time;
+
+ BlackboxWindow *win = (BlackboxWindow *) 0;
+ Basemenu *menu = (Basemenu *) 0;
+ Slit *slit = (Slit *) 0;
+ Toolbar *tbar = (Toolbar *) 0;
+ BScreen *scrn = (BScreen *) 0;
+
+ if ((win = searchWindow(e->xbutton.window))) {
+ win->buttonPressEvent(&e->xbutton);
+
+ /* XXX: is this sane on low colour desktops? */
+ if (e->xbutton.button == 1)
+ win->installColormap(True);
+ } else if ((menu = searchMenu(e->xbutton.window))) {
+ menu->buttonPressEvent(&e->xbutton);
+ } else if ((slit = searchSlit(e->xbutton.window))) {
+ slit->buttonPressEvent(&e->xbutton);
+ } else if ((tbar = searchToolbar(e->xbutton.window))) {
+ tbar->buttonPressEvent(&e->xbutton);
+ } else if ((scrn = searchScreen(e->xbutton.window))) {
+ scrn->buttonPressEvent(&e->xbutton);
+ if (active_screen != scrn) {
+ active_screen = scrn;
+ // first, set no focus window on the old screen
+ setFocusedWindow(0);
+ // and move focus to this screen
+ setFocusedWindow(0);
+ }
+ }
+ break;
+ }
+
+ case ButtonRelease: {
+ // strip the lock key modifiers
+ e->xbutton.state &= ~(NumLockMask | ScrollLockMask | LockMask);
+
+ last_time = e->xbutton.time;
+
+ BlackboxWindow *win = (BlackboxWindow *) 0;
+ Basemenu *menu = (Basemenu *) 0;
+ Toolbar *tbar = (Toolbar *) 0;
+
+ if ((win = searchWindow(e->xbutton.window)))
+ win->buttonReleaseEvent(&e->xbutton);
+ else if ((menu = searchMenu(e->xbutton.window)))
+ menu->buttonReleaseEvent(&e->xbutton);
+ else if ((tbar = searchToolbar(e->xbutton.window)))
+ tbar->buttonReleaseEvent(&e->xbutton);
+
+ break;
+ }
+
+ case ConfigureRequest: {
+ // compress configure requests...
+ XEvent realevent;
+ unsigned int i = 0;
+ while(XCheckTypedWindowEvent(getXDisplay(), e->xconfigurerequest.window,
+ ConfigureRequest, &realevent)) {
+ i++;
+ }
+ if ( i > 0 )
+ e = &realevent;
+
+ BlackboxWindow *win = (BlackboxWindow *) 0;
+ Slit *slit = (Slit *) 0;
+
+ if ((win = searchWindow(e->xconfigurerequest.window))) {
+ win->configureRequestEvent(&e->xconfigurerequest);
+ } else if ((slit = searchSlit(e->xconfigurerequest.window))) {
+ slit->configureRequestEvent(&e->xconfigurerequest);
+ } else {
+ if (validateWindow(e->xconfigurerequest.window)) {
+ XWindowChanges xwc;
+
+ xwc.x = e->xconfigurerequest.x;
+ xwc.y = e->xconfigurerequest.y;
+ xwc.width = e->xconfigurerequest.width;
+ xwc.height = e->xconfigurerequest.height;
+ xwc.border_width = e->xconfigurerequest.border_width;
+ xwc.sibling = e->xconfigurerequest.above;
+ xwc.stack_mode = e->xconfigurerequest.detail;
+
+ XConfigureWindow(getXDisplay(), e->xconfigurerequest.window,
+ e->xconfigurerequest.value_mask, &xwc);
+ }
+ }
+
+ break;
+ }
+
+ case MapRequest: {
+#ifdef DEBUG
+ fprintf(stderr, "Blackbox::process_event(): MapRequest for 0x%lx\n",
+ e->xmaprequest.window);
+#endif // DEBUG
+
+ BlackboxWindow *win = searchWindow(e->xmaprequest.window);
+
+ if (! win) {
+ BScreen *screen = searchScreen(e->xmaprequest.parent);
+
+ if (! screen) {
+ /*
+ we got a map request for a window who's parent isn't root. this
+ can happen in only one circumstance:
+
+ a client window unmapped a managed window, and then remapped it
+ somewhere between unmapping the client window and reparenting it
+ to root.
+
+ regardless of how it happens, we need to find the screen that
+ the window is on
+ */
+ XWindowAttributes wattrib;
+ if (! XGetWindowAttributes(getXDisplay(), e->xmaprequest.window,
+ &wattrib)) {
+ // failed to get the window attributes, perhaps the window has
+ // now been destroyed?
+ break;
+ }
+
+ screen = searchScreen(wattrib.root);
+ assert(screen != 0); // this should never happen
+ }
+
+ screen->manageWindow(e->xmaprequest.window);
+ }
+
+ break;
+ }
+
+ case UnmapNotify: {
+ BlackboxWindow *win = (BlackboxWindow *) 0;
+ Slit *slit = (Slit *) 0;
+
+ if ((win = searchWindow(e->xunmap.window))) {
+ win->unmapNotifyEvent(&e->xunmap);
+ } else if ((slit = searchSlit(e->xunmap.window))) {
+ slit->unmapNotifyEvent(&e->xunmap);
+ }
+
+ break;
+ }
+
+ case DestroyNotify: {
+ BlackboxWindow *win = (BlackboxWindow *) 0;
+ Slit *slit = (Slit *) 0;
+ BWindowGroup *group = (BWindowGroup *) 0;
+
+ if ((win = searchWindow(e->xdestroywindow.window))) {
+ win->destroyNotifyEvent(&e->xdestroywindow);
+ } else if ((slit = searchSlit(e->xdestroywindow.window))) {
+ slit->removeClient(e->xdestroywindow.window, False);
+ } else if ((group = searchGroup(e->xdestroywindow.window))) {
+ delete group;
+ }
+
+ break;
+ }
+
+ case ReparentNotify: {
+ /*
+ this event is quite rare and is usually handled in unmapNotify
+ however, if the window is unmapped when the reparent event occurs
+ the window manager never sees it because an unmap event is not sent
+ to an already unmapped window.
+ */
+ BlackboxWindow *win = searchWindow(e->xreparent.window);
+ if (win) {
+ win->reparentNotifyEvent(&e->xreparent);
+ } else {
+ Slit *slit = searchSlit(e->xreparent.window);
+ if (slit && slit->getWindowID() != e->xreparent.parent)
+ slit->removeClient(e->xreparent.window, True);
+ }
+ break;
+ }
+
+ case MotionNotify: {
+ // motion notify compression...
+ XEvent realevent;
+ unsigned int i = 0;
+ while (XCheckTypedWindowEvent(getXDisplay(), e->xmotion.window,
+ MotionNotify, &realevent)) {
+ i++;
+ }
+
+ // if we have compressed some motion events, use the last one
+ if ( i > 0 )
+ e = &realevent;
+
+ // strip the lock key modifiers
+ e->xbutton.state &= ~(NumLockMask | ScrollLockMask | LockMask);
+
+ last_time = e->xmotion.time;
+
+ BlackboxWindow *win = (BlackboxWindow *) 0;
+ Basemenu *menu = (Basemenu *) 0;
+
+ if ((win = searchWindow(e->xmotion.window)))
+ win->motionNotifyEvent(&e->xmotion);
+ else if ((menu = searchMenu(e->xmotion.window)))
+ menu->motionNotifyEvent(&e->xmotion);
+
+ break;
+ }
+
+ case PropertyNotify: {
+ last_time = e->xproperty.time;
+
+ if (e->xproperty.state != PropertyDelete) {
+ BlackboxWindow *win = searchWindow(e->xproperty.window);
+
+ if (win)
+ win->propertyNotifyEvent(e->xproperty.atom);
+ }
+
+ break;
+ }
+
+ case EnterNotify: {
+ last_time = e->xcrossing.time;
+
+ BScreen *screen = (BScreen *) 0;
+ BlackboxWindow *win = (BlackboxWindow *) 0;
+ Basemenu *menu = (Basemenu *) 0;
+ Toolbar *tbar = (Toolbar *) 0;
+ Slit *slit = (Slit *) 0;
+
+ if (e->xcrossing.mode == NotifyGrab) break;
+
+ XEvent dummy;
+ scanargs sa;
+ sa.w = e->xcrossing.window;
+ sa.enter = sa.leave = False;
+ XCheckIfEvent(getXDisplay(), &dummy, queueScanner, (char *) &sa);
+
+ if ((e->xcrossing.window == e->xcrossing.root) &&
+ (screen = searchScreen(e->xcrossing.window))) {
+ screen->getImageControl()->installRootColormap();
+ } else if ((win = searchWindow(e->xcrossing.window))) {
+ if (win->getScreen()->isSloppyFocus() &&
+ (! win->isFocused()) && (! no_focus)) {
+ if (((! sa.leave) || sa.inferior) && win->isVisible()) {
+ if (win->setInputFocus())
+ win->installColormap(True); // XXX: shouldnt we honour no install?
+ }
+ }
+ } else if ((menu = searchMenu(e->xcrossing.window))) {
+ menu->enterNotifyEvent(&e->xcrossing);
+ } else if ((tbar = searchToolbar(e->xcrossing.window))) {
+ tbar->enterNotifyEvent(&e->xcrossing);
+ } else if ((slit = searchSlit(e->xcrossing.window))) {
+ slit->enterNotifyEvent(&e->xcrossing);
+ }
+ break;
+ }
+
+ case LeaveNotify: {
+ last_time = e->xcrossing.time;
+
+ BlackboxWindow *win = (BlackboxWindow *) 0;
+ Basemenu *menu = (Basemenu *) 0;
+ Toolbar *tbar = (Toolbar *) 0;
+ Slit *slit = (Slit *) 0;
+
+ if ((menu = searchMenu(e->xcrossing.window)))
+ menu->leaveNotifyEvent(&e->xcrossing);
+ else if ((win = searchWindow(e->xcrossing.window)))
+ win->installColormap(False);
+ else if ((tbar = searchToolbar(e->xcrossing.window)))
+ tbar->leaveNotifyEvent(&e->xcrossing);
+ else if ((slit = searchSlit(e->xcrossing.window)))
+ slit->leaveNotifyEvent(&e->xcrossing);
+ break;
+ }
+
+ case Expose: {
+ // compress expose events
+ XEvent realevent;
+ unsigned int i = 0;
+ int ex1, ey1, ex2, ey2;
+ ex1 = e->xexpose.x;
+ ey1 = e->xexpose.y;
+ ex2 = ex1 + e->xexpose.width - 1;
+ ey2 = ey1 + e->xexpose.height - 1;
+ while (XCheckTypedWindowEvent(getXDisplay(), e->xexpose.window,
+ Expose, &realevent)) {
+ i++;
+
+ // merge expose area
+ ex1 = std::min(realevent.xexpose.x, ex1);
+ ey1 = std::min(realevent.xexpose.y, ey1);
+ ex2 = std::max(realevent.xexpose.x + realevent.xexpose.width - 1, ex2);
+ ey2 = std::max(realevent.xexpose.y + realevent.xexpose.height - 1, ey2);
+ }
+ if ( i > 0 )
+ e = &realevent;
+
+ // use the merged area
+ e->xexpose.x = ex1;
+ e->xexpose.y = ey1;
+ e->xexpose.width = ex2 - ex1 + 1;
+ e->xexpose.height = ey2 - ey1 + 1;
+
+ BlackboxWindow *win = (BlackboxWindow *) 0;
+ Basemenu *menu = (Basemenu *) 0;
+ Toolbar *tbar = (Toolbar *) 0;
+
+ if ((win = searchWindow(e->xexpose.window)))
+ win->exposeEvent(&e->xexpose);
+ else if ((menu = searchMenu(e->xexpose.window)))
+ menu->exposeEvent(&e->xexpose);
+ else if ((tbar = searchToolbar(e->xexpose.window)))
+ tbar->exposeEvent(&e->xexpose);
+
+ break;
+ }
+
+ case KeyPress: {
+ Toolbar *tbar = searchToolbar(e->xkey.window);
+
+ if (tbar && tbar->isEditing())
+ tbar->keyPressEvent(&e->xkey);
+
+ break;
+ }
+
+ case ColormapNotify: {
+ BScreen *screen = searchScreen(e->xcolormap.window);
+
+ if (screen)
+ screen->setRootColormapInstalled((e->xcolormap.state ==
+ ColormapInstalled) ? True : False);
+
+ break;
+ }
+
+ case FocusIn: {
+ if (e->xfocus.detail != NotifyNonlinear) {
+ /*
+ don't process FocusIns when:
+ 1. the new focus window isn't an ancestor or inferior of the old
+ focus window (NotifyNonlinear)
+ */
+ break;
+ }
+
+ BlackboxWindow *win = searchWindow(e->xfocus.window);
+ if (win) {
+ if (! win->isFocused())
+ win->setFocusFlag(True);
+
+ /*
+ set the event window to None. when the FocusOut event handler calls
+ this function recursively, it uses this as an indication that focus
+ has moved to a known window.
+ */
+ e->xfocus.window = None;
+ }
+
+ break;
+ }
+
+ case FocusOut: {
+ if (e->xfocus.detail != NotifyNonlinear) {
+ /*
+ don't process FocusOuts when:
+ 2. the new focus window isn't an ancestor or inferior of the old
+ focus window (NotifyNonlinear)
+ */
+ break;
+ }
+
+ BlackboxWindow *win = searchWindow(e->xfocus.window);
+ if (win && win->isFocused()) {
+ /*
+ before we mark "win" as unfocused, we need to verify that focus is
+ going to a known location, is in a known location, or set focus
+ to a known location.
+ */
+
+ XEvent event;
+ // don't check the current focus if FocusOut was generated during a grab
+ bool check_focus = (e->xfocus.mode == NotifyNormal);
+
+ /*
+ First, check if there is a pending FocusIn event waiting. if there
+ is, process it and determine if focus has moved to another window
+ (the FocusIn event handler sets the window in the event
+ structure to None to indicate this).
+ */
+ if (XCheckTypedEvent(getXDisplay(), FocusIn, &event)) {
+
+ process_event(&event);
+ if (event.xfocus.window == None) {
+ // focus has moved
+ check_focus = False;
+ }
+ }
+
+ if (check_focus) {
+ /*
+ Second, we query the X server for the current input focus.
+ to make sure that we keep a consistent state.
+ */
+ BlackboxWindow *focus;
+ Window w;
+ int revert;
+ XGetInputFocus(getXDisplay(), &w, &revert);
+ focus = searchWindow(w);
+ if (focus) {
+ /*
+ focus got from "win" to "focus" under some very strange
+ circumstances, and we need to make sure that the focus indication
+ is correct.
+ */
+ setFocusedWindow(focus);
+ } else {
+ // we have no idea where focus went... so we set it to somewhere
+ setFocusedWindow(0);
+ }
+ }
+ }
+
+ break;
+ }
+
+ case ClientMessage: {
+ if (e->xclient.format == 32) {
+ if (e->xclient.message_type == getWMChangeStateAtom()) {
+ BlackboxWindow *win = searchWindow(e->xclient.window);
+ if (! win || ! win->validateClient()) return;
+
+ if (e->xclient.data.l[0] == IconicState)
+ win->iconify();
+ if (e->xclient.data.l[0] == NormalState)
+ win->deiconify();
+ } else if(e->xclient.message_type == getBlackboxChangeWorkspaceAtom()) {
+ BScreen *screen = searchScreen(e->xclient.window);
+
+ if (screen && e->xclient.data.l[0] >= 0 &&
+ e->xclient.data.l[0] <
+ static_cast<signed>(screen->getWorkspaceCount()))
+ screen->changeWorkspaceID(e->xclient.data.l[0]);
+ } else if (e->xclient.message_type == getBlackboxChangeWindowFocusAtom()) {
+ BlackboxWindow *win = searchWindow(e->xclient.window);
+
+ if (win && win->isVisible() && win->setInputFocus())
+ win->installColormap(True);
+ } else if (e->xclient.message_type == getBlackboxCycleWindowFocusAtom()) {
+ BScreen *screen = searchScreen(e->xclient.window);
+
+ if (screen) {
+ if (! e->xclient.data.l[0])
+ screen->prevFocus();
+ else
+ screen->nextFocus();
+ }
+ } else if (e->xclient.message_type == getBlackboxChangeAttributesAtom()) {
+ BlackboxWindow *win = searchWindow(e->xclient.window);
+
+ if (win && win->validateClient()) {
+ BlackboxHints net;
+ net.flags = e->xclient.data.l[0];
+ net.attrib = e->xclient.data.l[1];
+ net.workspace = e->xclient.data.l[2];
+ net.stack = e->xclient.data.l[3];
+ net.decoration = e->xclient.data.l[4];
+
+ win->changeBlackboxHints(&net);
+ }
+ }
+ }
+
+ break;
+ }
+
+ case NoExpose:
+ case ConfigureNotify:
+ case MapNotify:
+ break; // not handled, just ignore
+
+ default: {
+#ifdef SHAPE
+ if (e->type == getShapeEventBase()) {
+ XShapeEvent *shape_event = (XShapeEvent *) e;
+ BlackboxWindow *win = searchWindow(e->xany.window);
+
+ if (win)
+ win->shapeEvent(shape_event);
+ }
+#endif // SHAPE
+ }
+ } // switch
+}
+
+
+bool Blackbox::handleSignal(int sig) {
+ switch (sig) {
+ case SIGHUP:
+ reconfigure();
+ break;
+
+ case SIGUSR1:
+ reload_rc();
+ break;
+
+ case SIGUSR2:
+ rereadMenu();
+ break;
+
+ case SIGPIPE:
+ case SIGSEGV:
+ case SIGFPE:
+ case SIGINT:
+ case SIGTERM:
+ shutdown();
+
+ default:
+ return False;
+ }
+
+ return True;
+}
+
+
+void Blackbox::init_icccm(void) {
+ xa_wm_colormap_windows =
+ XInternAtom(getXDisplay(), "WM_COLORMAP_WINDOWS", False);
+ xa_wm_protocols = XInternAtom(getXDisplay(), "WM_PROTOCOLS", False);
+ xa_wm_state = XInternAtom(getXDisplay(), "WM_STATE", False);
+ xa_wm_change_state = XInternAtom(getXDisplay(), "WM_CHANGE_STATE", False);
+ xa_wm_delete_window = XInternAtom(getXDisplay(), "WM_DELETE_WINDOW", False);
+ xa_wm_take_focus = XInternAtom(getXDisplay(), "WM_TAKE_FOCUS", False);
+ motif_wm_hints = XInternAtom(getXDisplay(), "_MOTIF_WM_HINTS", False);
+
+ blackbox_hints = XInternAtom(getXDisplay(), "_BLACKBOX_HINTS", False);
+ blackbox_attributes =
+ XInternAtom(getXDisplay(), "_BLACKBOX_ATTRIBUTES", False);
+ blackbox_change_attributes =
+ XInternAtom(getXDisplay(), "_BLACKBOX_CHANGE_ATTRIBUTES", False);
+ blackbox_structure_messages =
+ XInternAtom(getXDisplay(), "_BLACKBOX_STRUCTURE_MESSAGES", False);
+ blackbox_notify_startup =
+ XInternAtom(getXDisplay(), "_BLACKBOX_NOTIFY_STARTUP", False);
+ blackbox_notify_window_add =
+ XInternAtom(getXDisplay(), "_BLACKBOX_NOTIFY_WINDOW_ADD", False);
+ blackbox_notify_window_del =
+ XInternAtom(getXDisplay(), "_BLACKBOX_NOTIFY_WINDOW_DEL", False);
+ blackbox_notify_current_workspace =
+ XInternAtom(getXDisplay(), "_BLACKBOX_NOTIFY_CURRENT_WORKSPACE", False);
+ blackbox_notify_workspace_count =
+ XInternAtom(getXDisplay(), "_BLACKBOX_NOTIFY_WORKSPACE_COUNT", False);
+ blackbox_notify_window_focus =
+ XInternAtom(getXDisplay(), "_BLACKBOX_NOTIFY_WINDOW_FOCUS", False);
+ blackbox_notify_window_raise =
+ XInternAtom(getXDisplay(), "_BLACKBOX_NOTIFY_WINDOW_RAISE", False);
+ blackbox_notify_window_lower =
+ XInternAtom(getXDisplay(), "_BLACKBOX_NOTIFY_WINDOW_LOWER", False);
+ blackbox_change_workspace =
+ XInternAtom(getXDisplay(), "_BLACKBOX_CHANGE_WORKSPACE", False);
+ blackbox_change_window_focus =
+ XInternAtom(getXDisplay(), "_BLACKBOX_CHANGE_WINDOW_FOCUS", False);
+ blackbox_cycle_window_focus =
+ XInternAtom(getXDisplay(), "_BLACKBOX_CYCLE_WINDOW_FOCUS", False);
+
+#ifdef NEWWMSPEC
+ net_supported = XInternAtom(getXDisplay(), "_NET_SUPPORTED", False);
+ net_client_list = XInternAtom(getXDisplay(), "_NET_CLIENT_LIST", False);
+ net_client_list_stacking =
+ XInternAtom(getXDisplay(), "_NET_CLIENT_LIST_STACKING", False);
+ net_number_of_desktops =
+ XInternAtom(getXDisplay(), "_NET_NUMBER_OF_DESKTOPS", False);
+ net_desktop_geometry =
+ XInternAtom(getXDisplay(), "_NET_DESKTOP_GEOMETRY", False);
+ net_desktop_viewport =
+ XInternAtom(getXDisplay(), "_NET_DESKTOP_VIEWPORT", False);
+ net_current_desktop =
+ XInternAtom(getXDisplay(), "_NET_CURRENT_DESKTOP", False);
+ net_desktop_names = XInternAtom(getXDisplay(), "_NET_DESKTOP_NAMES", False);
+ net_active_window = XInternAtom(getXDisplay(), "_NET_ACTIVE_WINDOW", False);
+ net_workarea = XInternAtom(getXDisplay(), "_NET_WORKAREA", False);
+ net_supporting_wm_check =
+ XInternAtom(getXDisplay(), "_NET_SUPPORTING_WM_CHECK", False);
+ net_virtual_roots = XInternAtom(getXDisplay(), "_NET_VIRTUAL_ROOTS", False);
+ net_close_window = XInternAtom(getXDisplay(), "_NET_CLOSE_WINDOW", False);
+ net_wm_moveresize = XInternAtom(getXDisplay(), "_NET_WM_MOVERESIZE", False);
+ net_properties = XInternAtom(getXDisplay(), "_NET_PROPERTIES", False);
+ net_wm_name = XInternAtom(getXDisplay(), "_NET_WM_NAME", False);
+ net_wm_desktop = XInternAtom(getXDisplay(), "_NET_WM_DESKTOP", False);
+ net_wm_window_type =
+ XInternAtom(getXDisplay(), "_NET_WM_WINDOW_TYPE", False);
+ net_wm_state = XInternAtom(getXDisplay(), "_NET_WM_STATE", False);
+ net_wm_strut = XInternAtom(getXDisplay(), "_NET_WM_STRUT", False);
+ net_wm_icon_geometry =
+ XInternAtom(getXDisplay(), "_NET_WM_ICON_GEOMETRY", False);
+ net_wm_icon = XInternAtom(getXDisplay(), "_NET_WM_ICON", False);
+ net_wm_pid = XInternAtom(getXDisplay(), "_NET_WM_PID", False);
+ net_wm_handled_icons =
+ XInternAtom(getXDisplay(), "_NET_WM_HANDLED_ICONS", False);
+ net_wm_ping = XInternAtom(getXDisplay(), "_NET_WM_PING", False);
+#endif // NEWWMSPEC
+
+#ifdef HAVE_GETPID
+ blackbox_pid = XInternAtom(getXDisplay(), "_BLACKBOX_PID", False);
+#endif // HAVE_GETPID
+}
+
+
+bool Blackbox::validateWindow(Window window) {
+ XEvent event;
+ if (XCheckTypedWindowEvent(getXDisplay(), window, DestroyNotify, &event)) {
+ XPutBackEvent(getXDisplay(), &event);
+
+ return False;
+ }
+
+ return True;
+}
+
+
+BScreen *Blackbox::searchScreen(Window window) {
+ ScreenList::iterator it = screenList.begin();
+
+ for (; it != screenList.end(); ++it) {
+ BScreen *s = *it;
+ if (s->getRootWindow() == window)
+ return s;
+ }
+
+ return (BScreen *) 0;
+}
+
+
+BlackboxWindow *Blackbox::searchWindow(Window window) {
+ WindowLookup::iterator it = windowSearchList.find(window);
+ if (it != windowSearchList.end())
+ return it->second;
+
+ return (BlackboxWindow*) 0;
+}
+
+
+BWindowGroup *Blackbox::searchGroup(Window window) {
+ GroupLookup::iterator it = groupSearchList.find(window);
+ if (it != groupSearchList.end())
+ return it->second;
+
+ return (BWindowGroup *) 0;
+}
+
+
+Basemenu *Blackbox::searchMenu(Window window) {
+ MenuLookup::iterator it = menuSearchList.find(window);
+ if (it != menuSearchList.end())
+ return it->second;
+
+ return (Basemenu*) 0;
+}
+
+
+Toolbar *Blackbox::searchToolbar(Window window) {
+ ToolbarLookup::iterator it = toolbarSearchList.find(window);
+ if (it != toolbarSearchList.end())
+ return it->second;
+
+ return (Toolbar*) 0;
+}
+
+
+Slit *Blackbox::searchSlit(Window window) {
+ SlitLookup::iterator it = slitSearchList.find(window);
+ if (it != slitSearchList.end())
+ return it->second;
+
+ return (Slit*) 0;
+}
+
+
+void Blackbox::saveWindowSearch(Window window, BlackboxWindow *data) {
+ windowSearchList.insert(WindowLookupPair(window, data));
+}
+
+
+void Blackbox::saveGroupSearch(Window window, BWindowGroup *data) {
+ groupSearchList.insert(GroupLookupPair(window, data));
+}
+
+
+void Blackbox::saveMenuSearch(Window window, Basemenu *data) {
+ menuSearchList.insert(MenuLookupPair(window, data));
+}
+
+
+void Blackbox::saveToolbarSearch(Window window, Toolbar *data) {
+ toolbarSearchList.insert(ToolbarLookupPair(window, data));
+}
+
+
+void Blackbox::saveSlitSearch(Window window, Slit *data) {
+ slitSearchList.insert(SlitLookupPair(window, data));
+}
+
+
+void Blackbox::removeWindowSearch(Window window) {
+ windowSearchList.erase(window);
+}
+
+
+void Blackbox::removeGroupSearch(Window window) {
+ groupSearchList.erase(window);
+}
+
+
+void Blackbox::removeMenuSearch(Window window) {
+ menuSearchList.erase(window);
+}
+
+
+void Blackbox::removeToolbarSearch(Window window) {
+ toolbarSearchList.erase(window);
+}
+
+
+void Blackbox::removeSlitSearch(Window window) {
+ slitSearchList.erase(window);
+}
+
+
+void Blackbox::restart(const char *prog) {
+ shutdown();
+
+ if (prog) {
+ execlp(prog, prog, NULL);
+ perror(prog);
+ }
+
+ // fall back in case the above execlp doesn't work
+ execvp(argv[0], argv);
+ string name = basename(argv[0]);
+ execvp(name.c_str(), argv);
+}
+
+
+void Blackbox::shutdown(void) {
+ BaseDisplay::shutdown();
+
+ XSetInputFocus(getXDisplay(), PointerRoot, None, CurrentTime);
+
+ std::for_each(screenList.begin(), screenList.end(),
+ std::mem_fun(&BScreen::shutdown));
+
+ XSync(getXDisplay(), False);
+
+ save_rc();
+}
+
+
+void Blackbox::save_rc(void) {
+ XrmDatabase new_blackboxrc = (XrmDatabase) 0;
+ char rc_string[1024];
+
+ load_rc();
+
+ sprintf(rc_string, "session.menuFile: %s", getMenuFilename());
+ XrmPutLineResource(&new_blackboxrc, rc_string);
+
+ sprintf(rc_string, "session.colorsPerChannel: %d",
+ resource.colors_per_channel);
+ XrmPutLineResource(&new_blackboxrc, rc_string);
+
+ sprintf(rc_string, "session.doubleClickInterval: %lu",
+ resource.double_click_interval);
+ XrmPutLineResource(&new_blackboxrc, rc_string);
+
+ sprintf(rc_string, "session.autoRaiseDelay: %lu",
+ ((resource.auto_raise_delay.tv_sec * 1000) +
+ (resource.auto_raise_delay.tv_usec / 1000)));
+ XrmPutLineResource(&new_blackboxrc, rc_string);
+
+ sprintf(rc_string, "session.cacheLife: %lu", resource.cache_life / 60000);
+ XrmPutLineResource(&new_blackboxrc, rc_string);
+
+ sprintf(rc_string, "session.cacheMax: %lu", resource.cache_max);
+ XrmPutLineResource(&new_blackboxrc, rc_string);
+
+ ScreenList::iterator it = screenList.begin();
+ for (; it != screenList.end(); ++it) {
+ BScreen *screen = *it;
+ int screen_number = screen->getScreenNumber();
+
+ char *placement = (char *) 0;
+
+ switch (screen->getSlitPlacement()) {
+ case Slit::TopLeft: placement = "TopLeft"; break;
+ case Slit::CenterLeft: placement = "CenterLeft"; break;
+ case Slit::BottomLeft: placement = "BottomLeft"; break;
+ case Slit::TopCenter: placement = "TopCenter"; break;
+ case Slit::BottomCenter: placement = "BottomCenter"; break;
+ case Slit::TopRight: placement = "TopRight"; break;
+ case Slit::BottomRight: placement = "BottomRight"; break;
+ case Slit::CenterRight: default: placement = "CenterRight"; break;
+ }
+
+ sprintf(rc_string, "session.screen%d.slit.placement: %s", screen_number,
+ placement);
+ XrmPutLineResource(&new_blackboxrc, rc_string);
+
+ sprintf(rc_string, "session.screen%d.slit.direction: %s", screen_number,
+ ((screen->getSlitDirection() == Slit::Horizontal) ? "Horizontal" :
+ "Vertical"));
+ XrmPutLineResource(&new_blackboxrc, rc_string);
+
+ sprintf(rc_string, "session.screen%d.slit.onTop: %s", screen_number,
+ ((screen->getSlit()->isOnTop()) ? "True" : "False"));
+ XrmPutLineResource(&new_blackboxrc, rc_string);
+
+ sprintf(rc_string, "session.screen%d.slit.autoHide: %s", screen_number,
+ ((screen->getSlit()->doAutoHide()) ? "True" : "False"));
+ XrmPutLineResource(&new_blackboxrc, rc_string);
+
+ sprintf(rc_string, "session.opaqueMove: %s",
+ ((screen->doOpaqueMove()) ? "True" : "False"));
+ XrmPutLineResource(&new_blackboxrc, rc_string);
+
+ sprintf(rc_string, "session.imageDither: %s",
+ ((screen->getImageControl()->doDither()) ? "True" : "False"));
+ XrmPutLineResource(&new_blackboxrc, rc_string);
+
+ sprintf(rc_string, "session.screen%d.fullMaximization: %s", screen_number,
+ ((screen->doFullMax()) ? "True" : "False"));
+ XrmPutLineResource(&new_blackboxrc, rc_string);
+
+ sprintf(rc_string, "session.screen%d.focusNewWindows: %s", screen_number,
+ ((screen->doFocusNew()) ? "True" : "False"));
+ XrmPutLineResource(&new_blackboxrc, rc_string);
+
+ sprintf(rc_string, "session.screen%d.focusLastWindow: %s", screen_number,
+ ((screen->doFocusLast()) ? "True" : "False"));
+ XrmPutLineResource(&new_blackboxrc, rc_string);
+
+ sprintf(rc_string, "session.screen%d.rowPlacementDirection: %s",
+ screen_number,
+ ((screen->getRowPlacementDirection() == BScreen::LeftRight) ?
+ "LeftToRight" : "RightToLeft"));
+ XrmPutLineResource(&new_blackboxrc, rc_string);
+
+ sprintf(rc_string, "session.screen%d.colPlacementDirection: %s",
+ screen_number,
+ ((screen->getColPlacementDirection() == BScreen::TopBottom) ?
+ "TopToBottom" : "BottomToTop"));
+ XrmPutLineResource(&new_blackboxrc, rc_string);
+
+ switch (screen->getPlacementPolicy()) {
+ case BScreen::CascadePlacement:
+ placement = "CascadePlacement";
+ break;
+ case BScreen::ColSmartPlacement:
+ placement = "ColSmartPlacement";
+ break;
+
+ case BScreen::RowSmartPlacement:
+ default:
+ placement = "RowSmartPlacement";
+ break;
+ }
+ sprintf(rc_string, "session.screen%d.windowPlacement: %s", screen_number,
+ placement);
+ XrmPutLineResource(&new_blackboxrc, rc_string);
+
+ string fmodel;
+ if (screen->isSloppyFocus()) {
+ fmodel = "SloppyFocus";
+ if (screen->doAutoRaise()) fmodel += " AutoRaise";
+ if (screen->doClickRaise()) fmodel += " ClickRaise";
+ } else {
+ fmodel = "ClickToFocus";
+ }
+ sprintf(rc_string, "session.screen%d.focusModel: %s", screen_number,
+ fmodel.c_str());
+ XrmPutLineResource(&new_blackboxrc, rc_string);
+
+ sprintf(rc_string, "session.screen%d.workspaces: %d", screen_number,
+ screen->getWorkspaceCount());
+ XrmPutLineResource(&new_blackboxrc, rc_string);
+
+ sprintf(rc_string, "session.screen%d.toolbar.onTop: %s", screen_number,
+ ((screen->getToolbar()->isOnTop()) ? "True" : "False"));
+ XrmPutLineResource(&new_blackboxrc, rc_string);
+
+ sprintf(rc_string, "session.screen%d.toolbar.autoHide: %s",
+ screen_number,
+ ((screen->getToolbar()->doAutoHide()) ? "True" : "False"));
+ XrmPutLineResource(&new_blackboxrc, rc_string);
+
+ switch (screen->getToolbarPlacement()) {
+ case Toolbar::TopLeft: placement = "TopLeft"; break;
+ case Toolbar::BottomLeft: placement = "BottomLeft"; break;
+ case Toolbar::TopCenter: placement = "TopCenter"; break;
+ case Toolbar::TopRight: placement = "TopRight"; break;
+ case Toolbar::BottomRight: placement = "BottomRight"; break;
+ case Toolbar::BottomCenter: default: placement = "BottomCenter"; break;
+ }
+
+ sprintf(rc_string, "session.screen%d.toolbar.placement: %s",
+ screen_number, placement);
+ XrmPutLineResource(&new_blackboxrc, rc_string);
+
+ load_rc(screen);
+
+ // these are static, but may not be saved in the users .blackboxrc,
+ // writing these resources will allow the user to edit them at a later
+ // time... but loading the defaults before saving allows us to rewrite the
+ // users changes...
+
+#ifdef HAVE_STRFTIME
+ sprintf(rc_string, "session.screen%d.strftimeFormat: %s", screen_number,
+ screen->getStrftimeFormat());
+ XrmPutLineResource(&new_blackboxrc, rc_string);
+#else // !HAVE_STRFTIME
+ sprintf(rc_string, "session.screen%d.dateFormat: %s", screen_number,
+ ((screen->getDateFormat() == B_EuropeanDate) ?
+ "European" : "American"));
+ XrmPutLineResource(&new_blackboxrc, rc_string);
+
+ sprintf(rc_string, "session.screen%d.clockFormat: %d", screen_number,
+ ((screen->isClock24Hour()) ? 24 : 12));
+ XrmPutLineResource(&new_blackboxrc, rc_string);
+#endif // HAVE_STRFTIME
+
+ sprintf(rc_string, "session.screen%d.edgeSnapThreshold: %d",
+ screen_number, screen->getEdgeSnapThreshold());
+ XrmPutLineResource(&new_blackboxrc, rc_string);
+
+ sprintf(rc_string, "session.screen%d.toolbar.widthPercent: %d",
+ screen_number, screen->getToolbarWidthPercent());
+ XrmPutLineResource(&new_blackboxrc, rc_string);
+
+ // write out the user's workspace names
+
+ string save_string = screen->getWorkspace(0)->getName();
+ for (unsigned int i = 1; i < screen->getWorkspaceCount(); ++i) {
+ save_string += ',';
+ save_string += screen->getWorkspace(i)->getName();
+ }
+
+ char *resource_string = new char[save_string.length() + 48];
+ sprintf(resource_string, "session.screen%d.workspaceNames: %s",
+ screen_number, save_string.c_str());
+ XrmPutLineResource(&new_blackboxrc, resource_string);
+
+ delete [] resource_string;
+ }
+
+ XrmDatabase old_blackboxrc = XrmGetFileDatabase(rc_file.c_str());
+
+ XrmMergeDatabases(new_blackboxrc, &old_blackboxrc);
+ XrmPutFileDatabase(old_blackboxrc, rc_file.c_str());
+ XrmDestroyDatabase(old_blackboxrc);
+}
+
+
+void Blackbox::load_rc(void) {
+ XrmDatabase database = (XrmDatabase) 0;
+
+ database = XrmGetFileDatabase(rc_file.c_str());
+
+ XrmValue value;
+ char *value_type;
+ int int_value;
+ unsigned long long_value;
+
+ if (XrmGetResource(database, "session.menuFile", "Session.MenuFile",
+ &value_type, &value)) {
+ resource.menu_file = expandTilde(value.addr);
+ } else {
+ resource.menu_file = DEFAULTMENU;
+ }
+
+ resource.colors_per_channel = 4;
+ if (XrmGetResource(database, "session.colorsPerChannel",
+ "Session.ColorsPerChannel", &value_type, &value) &&
+ sscanf(value.addr, "%d", &int_value) == 1) {
+ resource.colors_per_channel = int_value;
+ if (resource.colors_per_channel < 2) resource.colors_per_channel = 2;
+ if (resource.colors_per_channel > 6) resource.colors_per_channel = 6;
+ }
+
+ if (XrmGetResource(database, "session.styleFile", "Session.StyleFile",
+ &value_type, &value))
+ resource.style_file = expandTilde(value.addr);
+ else
+ resource.style_file = DEFAULTSTYLE;
+
+ resource.double_click_interval = 250;
+ if (XrmGetResource(database, "session.doubleClickInterval",
+ "Session.DoubleClickInterval", &value_type, &value) &&
+ sscanf(value.addr, "%lu", &long_value) == 1) {
+ resource.double_click_interval = long_value;
+ }
+
+ resource.auto_raise_delay.tv_usec = 400;
+ if (XrmGetResource(database, "session.autoRaiseDelay",
+ "Session.AutoRaiseDelay", &value_type, &value) &&
+ sscanf(value.addr, "%lu", &long_value) == 1) {
+ resource.auto_raise_delay.tv_usec = long_value;
+ }
+
+ resource.auto_raise_delay.tv_sec = resource.auto_raise_delay.tv_usec / 1000;
+ resource.auto_raise_delay.tv_usec -=
+ (resource.auto_raise_delay.tv_sec * 1000);
+ resource.auto_raise_delay.tv_usec *= 1000;
+
+ resource.cache_life = 5l;
+ if (XrmGetResource(database, "session.cacheLife", "Session.CacheLife",
+ &value_type, &value) &&
+ sscanf(value.addr, "%lu", &long_value) == 1) {
+ resource.cache_life = long_value;
+ }
+ resource.cache_life *= 60000;
+
+ resource.cache_max = 200;
+ if (XrmGetResource(database, "session.cacheMax", "Session.CacheMax",
+ &value_type, &value) &&
+ sscanf(value.addr, "%lu", &long_value) == 1) {
+ resource.cache_max = long_value;
+ }
+}
+
+
+void Blackbox::load_rc(BScreen *screen) {
+ XrmDatabase database = (XrmDatabase) 0;
+
+ database = XrmGetFileDatabase(rc_file.c_str());
+
+ XrmValue value;
+ char *value_type, name_lookup[1024], class_lookup[1024];
+ int screen_number = screen->getScreenNumber();
+ int int_value;
+
+ sprintf(name_lookup, "session.screen%d.fullMaximization", screen_number);
+ sprintf(class_lookup, "Session.Screen%d.FullMaximization", screen_number);
+ screen->saveFullMax(False);
+ if (XrmGetResource(database, name_lookup, class_lookup, &value_type,
+ &value) &&
+ ! strncasecmp(value.addr, "true", value.size)) {
+ screen->saveFullMax(True);
+ }
+
+ sprintf(name_lookup, "session.screen%d.focusNewWindows", screen_number);
+ sprintf(class_lookup, "Session.Screen%d.FocusNewWindows", screen_number);
+ screen->saveFocusNew(False);
+ if (XrmGetResource(database, name_lookup, class_lookup, &value_type,
+ &value) &&
+ ! strncasecmp(value.addr, "true", value.size)) {
+ screen->saveFocusNew(True);
+ }
+
+ sprintf(name_lookup, "session.screen%d.focusLastWindow", screen_number);
+ sprintf(class_lookup, "Session.Screen%d.focusLastWindow", screen_number);
+ screen->saveFocusLast(False);
+ if (XrmGetResource(database, name_lookup, class_lookup, &value_type,
+ &value) &&
+ ! strncasecmp(value.addr, "true", value.size)) {
+ screen->saveFocusLast(True);
+ }
+
+ sprintf(name_lookup, "session.screen%d.rowPlacementDirection",
+ screen_number);
+ sprintf(class_lookup, "Session.Screen%d.RowPlacementDirection",
+ screen_number);
+ screen->saveRowPlacementDirection(BScreen::LeftRight);
+ if (XrmGetResource(database, name_lookup, class_lookup, &value_type,
+ &value) &&
+ ! strncasecmp(value.addr, "righttoleft", value.size)) {
+ screen->saveRowPlacementDirection(BScreen::RightLeft);
+ }
+
+ sprintf(name_lookup, "session.screen%d.colPlacementDirection",
+ screen_number);
+ sprintf(class_lookup, "Session.Screen%d.ColPlacementDirection",
+ screen_number);
+ screen->saveColPlacementDirection(BScreen::TopBottom);
+ if (XrmGetResource(database, name_lookup, class_lookup, &value_type,
+ &value) &&
+ ! strncasecmp(value.addr, "bottomtotop", value.size)) {
+ screen->saveColPlacementDirection(BScreen::BottomTop);
+ }
+
+ sprintf(name_lookup, "session.screen%d.workspaces", screen_number);
+ sprintf(class_lookup, "Session.Screen%d.Workspaces", screen_number);
+ screen->saveWorkspaces(1);
+ if (XrmGetResource(database, name_lookup, class_lookup,
+ &value_type, &value) &&
+ sscanf(value.addr, "%d", &int_value) == 1 &&
+ int_value > 0 && int_value < 128) {
+ screen->saveWorkspaces(int_value);
+ }
+
+ sprintf(name_lookup, "session.screen%d.toolbar.widthPercent",
+ screen_number);
+ sprintf(class_lookup, "Session.Screen%d.Toolbar.WidthPercent",
+ screen_number);
+ screen->saveToolbarWidthPercent(66);
+ if (XrmGetResource(database, name_lookup, class_lookup, &value_type,
+ &value) &&
+ sscanf(value.addr, "%d", &int_value) == 1 &&
+ int_value > 0 && int_value <= 100) {
+ screen->saveToolbarWidthPercent(int_value);
+ }
+
+ sprintf(name_lookup, "session.screen%d.toolbar.placement", screen_number);
+ sprintf(class_lookup, "Session.Screen%d.Toolbar.Placement", screen_number);
+ screen->saveToolbarPlacement(Toolbar::BottomCenter);
+ if (XrmGetResource(database, name_lookup, class_lookup, &value_type,
+ &value)) {
+ if (! strncasecmp(value.addr, "TopLeft", value.size))
+ screen->saveToolbarPlacement(Toolbar::TopLeft);
+ else if (! strncasecmp(value.addr, "BottomLeft", value.size))
+ screen->saveToolbarPlacement(Toolbar::BottomLeft);
+ else if (! strncasecmp(value.addr, "TopCenter", value.size))
+ screen->saveToolbarPlacement(Toolbar::TopCenter);
+ else if (! strncasecmp(value.addr, "TopRight", value.size))
+ screen->saveToolbarPlacement(Toolbar::TopRight);
+ else if (! strncasecmp(value.addr, "BottomRight", value.size))
+ screen->saveToolbarPlacement(Toolbar::BottomRight);
+ }
+ screen->removeWorkspaceNames();
+
+ sprintf(name_lookup, "session.screen%d.workspaceNames", screen_number);
+ sprintf(class_lookup, "Session.Screen%d.WorkspaceNames", screen_number);
+ if (XrmGetResource(database, name_lookup, class_lookup, &value_type,
+ &value)) {
+ string search = value.addr;
+ string::const_iterator it = search.begin(),
+ end = search.end();
+ while (1) {
+ string::const_iterator tmp = it; // current string.begin()
+ it = std::find(tmp, end, ','); // look for comma between tmp and end
+ screen->addWorkspaceName(string(tmp, it)); // string = search[tmp:it]
+ if (it == end) break;
+ ++it;
+ }
+ }
+
+ sprintf(name_lookup, "session.screen%d.toolbar.onTop", screen_number);
+ sprintf(class_lookup, "Session.Screen%d.Toolbar.OnTop", screen_number);
+ screen->saveToolbarOnTop(False);
+ if (XrmGetResource(database, name_lookup, class_lookup, &value_type,
+ &value) &&
+ ! strncasecmp(value.addr, "true", value.size)) {
+ screen->saveToolbarOnTop(True);
+ }
+
+ sprintf(name_lookup, "session.screen%d.toolbar.autoHide", screen_number);
+ sprintf(class_lookup, "Session.Screen%d.Toolbar.autoHide", screen_number);
+ screen->saveToolbarAutoHide(False);
+ if (XrmGetResource(database, name_lookup, class_lookup, &value_type,
+ &value) &&
+ ! strncasecmp(value.addr, "true", value.size)) {
+ screen->saveToolbarAutoHide(True);
+ }
+
+ sprintf(name_lookup, "session.screen%d.focusModel", screen_number);
+ sprintf(class_lookup, "Session.Screen%d.FocusModel", screen_number);
+ screen->saveSloppyFocus(True);
+ screen->saveAutoRaise(False);
+ screen->saveClickRaise(False);
+ if (XrmGetResource(database, name_lookup, class_lookup, &value_type,
+ &value)) {
+ string fmodel = value.addr;
+
+ if (fmodel.find("ClickToFocus") != string::npos) {
+ screen->saveSloppyFocus(False);
+ } else {
+ // must be sloppy
+
+ if (fmodel.find("AutoRaise") != string::npos)
+ screen->saveAutoRaise(True);
+ if (fmodel.find("ClickRaise") != string::npos)
+ screen->saveClickRaise(True);
+ }
+ }
+
+ sprintf(name_lookup, "session.screen%d.windowPlacement", screen_number);
+ sprintf(class_lookup, "Session.Screen%d.WindowPlacement", screen_number);
+ screen->savePlacementPolicy(BScreen::RowSmartPlacement);
+ if (XrmGetResource(database, name_lookup, class_lookup, &value_type,
+ &value)) {
+ if (! strncasecmp(value.addr, "RowSmartPlacement", value.size))
+ /* pass */;
+ else if (! strncasecmp(value.addr, "ColSmartPlacement", value.size))
+ screen->savePlacementPolicy(BScreen::ColSmartPlacement);
+ else if (! strncasecmp(value.addr, "CascadePlacement", value.size))
+ screen->savePlacementPolicy(BScreen::CascadePlacement);
+ }
+
+ sprintf(name_lookup, "session.screen%d.slit.placement", screen_number);
+ sprintf(class_lookup, "Session.Screen%d.Slit.Placement", screen_number);
+ screen->saveSlitPlacement(Slit::CenterRight);
+ if (XrmGetResource(database, name_lookup, class_lookup, &value_type,
+ &value)) {
+ if (! strncasecmp(value.addr, "TopLeft", value.size))
+ screen->saveSlitPlacement(Slit::TopLeft);
+ else if (! strncasecmp(value.addr, "CenterLeft", value.size))
+ screen->saveSlitPlacement(Slit::CenterLeft);
+ else if (! strncasecmp(value.addr, "BottomLeft", value.size))
+ screen->saveSlitPlacement(Slit::BottomLeft);
+ else if (! strncasecmp(value.addr, "TopCenter", value.size))
+ screen->saveSlitPlacement(Slit::TopCenter);
+ else if (! strncasecmp(value.addr, "BottomCenter", value.size))
+ screen->saveSlitPlacement(Slit::BottomCenter);
+ else if (! strncasecmp(value.addr, "TopRight", value.size))
+ screen->saveSlitPlacement(Slit::TopRight);
+ else if (! strncasecmp(value.addr, "BottomRight", value.size))
+ screen->saveSlitPlacement(Slit::BottomRight);
+ }
+
+ sprintf(name_lookup, "session.screen%d.slit.direction", screen_number);
+ sprintf(class_lookup, "Session.Screen%d.Slit.Direction", screen_number);
+ screen->saveSlitDirection(Slit::Vertical);
+ if (XrmGetResource(database, name_lookup, class_lookup, &value_type,
+ &value) &&
+ ! strncasecmp(value.addr, "Horizontal", value.size)) {
+ screen->saveSlitDirection(Slit::Horizontal);
+ }
+
+ sprintf(name_lookup, "session.screen%d.slit.onTop", screen_number);
+ sprintf(class_lookup, "Session.Screen%d.Slit.OnTop", screen_number);
+ screen->saveSlitOnTop(False);
+ if (XrmGetResource(database, name_lookup, class_lookup, &value_type,
+ &value) &&
+ ! strncasecmp(value.addr, "True", value.size)) {
+ screen->saveSlitOnTop(True);
+ }
+
+ sprintf(name_lookup, "session.screen%d.slit.autoHide", screen_number);
+ sprintf(class_lookup, "Session.Screen%d.Slit.AutoHide", screen_number);
+ screen->saveSlitAutoHide(False);
+ if (XrmGetResource(database, name_lookup, class_lookup, &value_type,
+ &value) &&
+ ! strncasecmp(value.addr, "true", value.size)) {
+ screen->saveSlitAutoHide(True);
+ }
+
+#ifdef HAVE_STRFTIME
+ sprintf(name_lookup, "session.screen%d.strftimeFormat", screen_number);
+ sprintf(class_lookup, "Session.Screen%d.StrftimeFormat", screen_number);
+ if (XrmGetResource(database, name_lookup, class_lookup, &value_type,
+ &value)) {
+ screen->saveStrftimeFormat(value.addr);
+ } else {
+ screen->saveStrftimeFormat("%I:%M %p");
+ }
+#else // HAVE_STRFTIME
+ sprintf(name_lookup, "session.screen%d.dateFormat", screen_number);
+ sprintf(class_lookup, "Session.Screen%d.DateFormat", screen_number);
+ screen->saveDateFormat(B_AmericanDate);
+ if (XrmGetResource(database, name_lookup, class_lookup, &value_type,
+ &value)) {
+ if (! strncasecmp(value.addr, "european", value.size))
+ screen->saveDateFormat(B_EuropeanDate);
+ }
+
+ sprintf(name_lookup, "session.screen%d.clockFormat", screen_number);
+ sprintf(class_lookup, "Session.Screen%d.ClockFormat", screen_number);
+ screen->saveClock24Hour(False);
+ if (XrmGetResource(database, name_lookup, class_lookup, &value_type,
+ &value) &&
+ sscanf(value.addr, "%d", &int_value) == 1 && int_value == 24) {
+ screen->saveClock24Hour(True);
+ }
+#endif // HAVE_STRFTIME
+
+ sprintf(name_lookup, "session.screen%d.edgeSnapThreshold", screen_number);
+ sprintf(class_lookup, "Session.Screen%d.EdgeSnapThreshold", screen_number);
+ if (XrmGetResource(database, name_lookup, class_lookup, &value_type,
+ &value) &&
+ sscanf(value.addr, "%d", &int_value) == 1) {
+ screen->saveEdgeSnapThreshold(int_value);
+ }
+
+ screen->saveImageDither(True);
+ if (XrmGetResource(database, "session.imageDither", "Session.ImageDither",
+ &value_type, &value) &&
+ ! strncasecmp("false", value.addr, value.size)) {
+ screen->saveImageDither(False);
+ }
+
+ screen->saveOpaqueMove(False);
+ if (XrmGetResource(database, "session.opaqueMove", "Session.OpaqueMove",
+ &value_type, &value) &&
+ ! strncasecmp("true", value.addr, value.size)) {
+ screen->saveOpaqueMove(True);
+ }
+
+ XrmDestroyDatabase(database);
+}
+
+
+void Blackbox::reload_rc(void) {
+ load_rc();
+ reconfigure();
+}
+
+
+void Blackbox::reconfigure(void) {
+ reconfigure_wait = True;
+
+ if (! timer->isTiming()) timer->start();
+}
+
+
+void Blackbox::real_reconfigure(void) {
+ XrmDatabase new_blackboxrc = (XrmDatabase) 0;
+ char *style = new char[resource.style_file.length() + 20];
+
+ sprintf(style, "session.styleFile: %s", getStyleFilename());
+ XrmPutLineResource(&new_blackboxrc, style);
+
+ delete [] style;
+
+ XrmDatabase old_blackboxrc = XrmGetFileDatabase(rc_file.c_str());
+
+ XrmMergeDatabases(new_blackboxrc, &old_blackboxrc);
+ XrmPutFileDatabase(old_blackboxrc, rc_file.c_str());
+ if (old_blackboxrc) XrmDestroyDatabase(old_blackboxrc);
+
+ std::for_each(menuTimestamps.begin(), menuTimestamps.end(),
+ PointerAssassin());
+ menuTimestamps.clear();
+
+ gcCache()->purge();
+
+ std::for_each(screenList.begin(), screenList.end(),
+ std::mem_fun(&BScreen::reconfigure));
+}
+
+
+void Blackbox::checkMenu(void) {
+ bool reread = False;
+ MenuTimestampList::iterator it = menuTimestamps.begin();
+ for(; it != menuTimestamps.end(); ++it) {
+ MenuTimestamp *tmp = *it;
+ struct stat buf;
+
+ if (! stat(tmp->filename.c_str(), &buf)) {
+ if (tmp->timestamp != buf.st_ctime)
+ reread = True;
+ } else {
+ reread = True;
+ }
+ }
+
+ if (reread) rereadMenu();
+}
+
+
+void Blackbox::rereadMenu(void) {
+ reread_menu_wait = True;
+
+ if (! timer->isTiming()) timer->start();
+}
+
+
+void Blackbox::real_rereadMenu(void) {
+ std::for_each(menuTimestamps.begin(), menuTimestamps.end(),
+ PointerAssassin());
+ menuTimestamps.clear();
+
+ std::for_each(screenList.begin(), screenList.end(),
+ std::mem_fun(&BScreen::rereadMenu));
+}
+
+
+void Blackbox::saveStyleFilename(const string& filename) {
+ assert(! filename.empty());
+ resource.style_file = filename;
+}
+
+
+void Blackbox::saveMenuFilename(const string& filename) {
+ assert(! filename.empty());
+ bool found = False;
+
+ MenuTimestampList::iterator it = menuTimestamps.begin();
+ for (; it != menuTimestamps.end() && !found; ++it) {
+ if ((*it)->filename == filename) found = True;
+ }
+ if (! found) {
+ struct stat buf;
+
+ if (! stat(filename.c_str(), &buf)) {
+ MenuTimestamp *ts = new MenuTimestamp;
+
+ ts->filename = filename;
+ ts->timestamp = buf.st_ctime;
+
+ menuTimestamps.push_back(ts);
+ }
+ }
+}
+
+
+void Blackbox::timeout(void) {
+ if (reconfigure_wait)
+ real_reconfigure();
+
+ if (reread_menu_wait)
+ real_rereadMenu();
+
+ reconfigure_wait = reread_menu_wait = False;
+}
+
+
+void Blackbox::setFocusedWindow(BlackboxWindow *win) {
+ if (focused_window && focused_window == win) // nothing to do
+ return;
+
+ BScreen *old_screen = 0;
+
+ if (focused_window) {
+ focused_window->setFocusFlag(False);
+ old_screen = focused_window->getScreen();
+ }
+
+ if (win && ! win->isIconic()) {
+ // the active screen is the one with the last focused window...
+ // this will keep focus on this screen no matter where the mouse goes,
+ // so multihead keybindings will continue to work on that screen until the
+ // user focuses a window on a different screen.
+ active_screen = win->getScreen();
+ focused_window = win;
+ } else {
+ focused_window = 0;
+ if (! old_screen) {
+ if (active_screen) {
+ // set input focus to the toolbar of the screen with mouse
+ XSetInputFocus(getXDisplay(),
+ active_screen->getToolbar()->getWindowID(),
+ RevertToPointerRoot, CurrentTime);
+ } else {
+ // set input focus to the toolbar of the first managed screen
+ XSetInputFocus(getXDisplay(),
+ screenList.front()->getToolbar()->getWindowID(),
+ RevertToPointerRoot, CurrentTime);
+ }
+ } else {
+ // set input focus to the toolbar of the last screen
+ XSetInputFocus(getXDisplay(), old_screen->getToolbar()->getWindowID(),
+ RevertToPointerRoot, CurrentTime);
+ }
+ }
+
+ if (active_screen && active_screen->isScreenManaged()) {
+ active_screen->getToolbar()->redrawWindowLabel(True);
+ active_screen->updateNetizenWindowFocus();
+ }
+
+ if (old_screen && old_screen != active_screen) {
+ old_screen->getToolbar()->redrawWindowLabel(True);
+ old_screen->updateNetizenWindowFocus();
+ }
+}
--- /dev/null
+// -*- mode: C++; indent-tabs-mode: nil; c-basic-offset: 2; -*-
+// blackbox.hh for Blackbox - an X11 Window manager
+// Copyright (c) 2001 - 2002 Sean 'Shaleh' Perry <shaleh@debian.org>
+// Copyright (c) 1997 - 2000 Brad Hughes (bhughes@tcac.net)
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#ifndef __blackbox_hh
+#define __blackbox_hh
+
+extern "C" {
+#include <X11/Xlib.h>
+#include <X11/Xresource.h>
+
+#ifdef HAVE_STDIO_H
+# include <stdio.h>
+#endif // HAVE_STDIO_H
+
+#ifdef TIME_WITH_SYS_TIME
+# include <sys/time.h>
+# include <time.h>
+#else // !TIME_WITH_SYS_TIME
+# ifdef HAVE_SYS_TIME_H
+# include <sys/time.h>
+# else // !HAVE_SYS_TIME_H
+# include <time.h>
+# endif // HAVE_SYS_TIME_H
+#endif // TIME_WITH_SYS_TIME
+}
+
+#include <list>
+#include <map>
+#include <string>
+
+#include "i18n.hh"
+#include "BaseDisplay.hh"
+#include "Timer.hh"
+
+#define AttribShaded (1l << 0)
+#define AttribMaxHoriz (1l << 1)
+#define AttribMaxVert (1l << 2)
+#define AttribOmnipresent (1l << 3)
+#define AttribWorkspace (1l << 4)
+#define AttribStack (1l << 5)
+#define AttribDecoration (1l << 6)
+
+#define StackTop (0)
+#define StackNormal (1)
+#define StackBottom (2)
+
+#define DecorNone (0)
+#define DecorNormal (1)
+#define DecorTiny (2)
+#define DecorTool (3)
+
+struct BlackboxHints {
+ unsigned long flags, attrib, workspace, stack, decoration;
+};
+
+struct BlackboxAttributes {
+ unsigned long flags, attrib, workspace, stack, decoration;
+ int premax_x, premax_y;
+ unsigned int premax_w, premax_h;
+};
+
+#define PropBlackboxHintsElements (5)
+#define PropBlackboxAttributesElements (9)
+
+
+//forward declaration
+class BScreen;
+class Blackbox;
+class BlackboxWindow;
+class BWindowGroup;
+class Basemenu;
+class Toolbar;
+class Slit;
+
+extern I18n i18n;
+
+class Blackbox : public BaseDisplay, public TimeoutHandler {
+private:
+ struct BCursor {
+ Cursor session, move, ll_angle, lr_angle;
+ };
+ BCursor cursor;
+
+ struct MenuTimestamp {
+ std::string filename;
+ time_t timestamp;
+ };
+
+ struct BResource {
+ Time double_click_interval;
+
+ std::string menu_file, style_file;
+ int colors_per_channel;
+ timeval auto_raise_delay;
+ unsigned long cache_life, cache_max;
+ } resource;
+
+ typedef std::map<Window, BlackboxWindow*> WindowLookup;
+ typedef WindowLookup::value_type WindowLookupPair;
+ WindowLookup windowSearchList;
+
+ typedef std::map<Window, BWindowGroup*> GroupLookup;
+ typedef GroupLookup::value_type GroupLookupPair;
+ GroupLookup groupSearchList;
+
+ typedef std::map<Window, Basemenu*> MenuLookup;
+ typedef MenuLookup::value_type MenuLookupPair;
+ MenuLookup menuSearchList;
+
+ typedef std::map<Window, Toolbar*> ToolbarLookup;
+ typedef ToolbarLookup::value_type ToolbarLookupPair;
+ ToolbarLookup toolbarSearchList;
+
+ typedef std::map<Window, Slit*> SlitLookup;
+ typedef SlitLookup::value_type SlitLookupPair;
+ SlitLookup slitSearchList;
+
+ typedef std::list<MenuTimestamp*> MenuTimestampList;
+ MenuTimestampList menuTimestamps;
+
+ typedef std::list<BScreen*> ScreenList;
+ ScreenList screenList;
+
+ BScreen *active_screen;
+ BlackboxWindow *focused_window;
+ BTimer *timer;
+
+ bool no_focus, reconfigure_wait, reread_menu_wait;
+ Time last_time;
+ char **argv;
+ std::string rc_file;
+
+ Atom xa_wm_colormap_windows, xa_wm_protocols, xa_wm_state,
+ xa_wm_delete_window, xa_wm_take_focus, xa_wm_change_state,
+ motif_wm_hints;
+
+ // NETAttributes
+ Atom blackbox_attributes, blackbox_change_attributes, blackbox_hints;
+#ifdef HAVE_GETPID
+ Atom blackbox_pid;
+#endif // HAVE_GETPID
+
+ // NETStructureMessages
+ Atom blackbox_structure_messages, blackbox_notify_startup,
+ blackbox_notify_window_add, blackbox_notify_window_del,
+ blackbox_notify_window_focus, blackbox_notify_current_workspace,
+ blackbox_notify_workspace_count, blackbox_notify_window_raise,
+ blackbox_notify_window_lower;
+
+ // message_types for client -> wm messages
+ Atom blackbox_change_workspace, blackbox_change_window_focus,
+ blackbox_cycle_window_focus;
+
+#ifdef NEWWMSPEC
+ // root window properties
+ Atom net_supported, net_client_list, net_client_list_stacking,
+ net_number_of_desktops, net_desktop_geometry, net_desktop_viewport,
+ net_current_desktop, net_desktop_names, net_active_window, net_workarea,
+ net_supporting_wm_check, net_virtual_roots;
+
+ // root window messages
+ Atom net_close_window, net_wm_moveresize;
+
+ // application window properties
+ Atom net_properties, net_wm_name, net_wm_desktop, net_wm_window_type,
+ net_wm_state, net_wm_strut, net_wm_icon_geometry, net_wm_icon, net_wm_pid,
+ net_wm_handled_icons;
+
+ // application protocols
+ Atom net_wm_ping;
+#endif // NEWWMSPEC
+
+ Blackbox(const Blackbox&);
+ Blackbox& operator=(const Blackbox&);
+
+ void load_rc(void);
+ void save_rc(void);
+ void reload_rc(void);
+ void real_rereadMenu(void);
+ void real_reconfigure(void);
+
+ void init_icccm(void);
+
+ virtual void process_event(XEvent *);
+
+
+public:
+ Blackbox(char **m_argv, char *dpy_name = 0, char *rc = 0);
+ virtual ~Blackbox(void);
+
+ Basemenu *searchMenu(Window window);
+ BWindowGroup *searchGroup(Window window);
+ BlackboxWindow *searchWindow(Window window);
+ BScreen *searchScreen(Window window);
+ Toolbar *searchToolbar(Window);
+ Slit *searchSlit(Window);
+
+ void saveMenuSearch(Window window, Basemenu *data);
+ void saveWindowSearch(Window window, BlackboxWindow *data);
+ void saveGroupSearch(Window window, BWindowGroup *data);
+ void saveToolbarSearch(Window window, Toolbar *data);
+ void saveSlitSearch(Window window, Slit *data);
+ void removeMenuSearch(Window window);
+ void removeWindowSearch(Window window);
+ void removeGroupSearch(Window window);
+ void removeToolbarSearch(Window window);
+ void removeSlitSearch(Window window);
+
+ inline BlackboxWindow *getFocusedWindow(void) { return focused_window; }
+
+ inline const Time &getDoubleClickInterval(void) const
+ { return resource.double_click_interval; }
+ inline const Time &getLastTime(void) const { return last_time; }
+
+ inline const char *getStyleFilename(void) const
+ { return resource.style_file.c_str(); }
+ inline const char *getMenuFilename(void) const
+ { return resource.menu_file.c_str(); }
+
+ inline int getColorsPerChannel(void) const
+ { return resource.colors_per_channel; }
+
+ inline const timeval &getAutoRaiseDelay(void) const
+ { return resource.auto_raise_delay; }
+
+ inline unsigned long getCacheLife(void) const
+ { return resource.cache_life; }
+ inline unsigned long getCacheMax(void) const
+ { return resource.cache_max; }
+
+ inline void setNoFocus(bool f) { no_focus = f; }
+
+ inline Cursor getSessionCursor(void) const
+ { return cursor.session; }
+ inline Cursor getMoveCursor(void) const
+ { return cursor.move; }
+ inline Cursor getLowerLeftAngleCursor(void) const
+ { return cursor.ll_angle; }
+ inline Cursor getLowerRightAngleCursor(void) const
+ { return cursor.lr_angle; }
+
+ void setFocusedWindow(BlackboxWindow *w);
+ void shutdown(void);
+ void load_rc(BScreen *screen);
+ void saveStyleFilename(const std::string& filename);
+ void saveMenuFilename(const std::string& filename);
+ void restart(const char *prog = 0);
+ void reconfigure(void);
+ void rereadMenu(void);
+ void checkMenu(void);
+
+ bool validateWindow(Window window);
+
+ virtual bool handleSignal(int sig);
+
+ virtual void timeout(void);
+
+#ifndef HAVE_STRFTIME
+ enum { B_AmericanDate = 1, B_EuropeanDate };
+#endif // HAVE_STRFTIME
+
+#ifdef HAVE_GETPID
+ inline Atom getBlackboxPidAtom(void) const { return blackbox_pid; }
+#endif // HAVE_GETPID
+
+ inline Atom getWMChangeStateAtom(void) const
+ { return xa_wm_change_state; }
+ inline Atom getWMStateAtom(void) const
+ { return xa_wm_state; }
+ inline Atom getWMDeleteAtom(void) const
+ { return xa_wm_delete_window; }
+ inline Atom getWMProtocolsAtom(void) const
+ { return xa_wm_protocols; }
+ inline Atom getWMTakeFocusAtom(void) const
+ { return xa_wm_take_focus; }
+ inline Atom getWMColormapAtom(void) const
+ { return xa_wm_colormap_windows; }
+ inline Atom getMotifWMHintsAtom(void) const
+ { return motif_wm_hints; }
+
+ // this atom is for normal app->WM hints about decorations, stacking,
+ // starting workspace etc...
+ inline Atom getBlackboxHintsAtom(void) const
+ { return blackbox_hints;}
+
+ // these atoms are for normal app->WM interaction beyond the scope of the
+ // ICCCM...
+ inline Atom getBlackboxAttributesAtom(void) const
+ { return blackbox_attributes; }
+ inline Atom getBlackboxChangeAttributesAtom(void) const
+ { return blackbox_change_attributes; }
+
+ // these atoms are for window->WM interaction, with more control and
+ // information on window "structure"... common examples are
+ // notifying apps when windows are raised/lowered... when the user changes
+ // workspaces... i.e. "pager talk"
+ inline Atom getBlackboxStructureMessagesAtom(void) const
+ { return blackbox_structure_messages; }
+
+ // *Notify* portions of the NETStructureMessages protocol
+ inline Atom getBlackboxNotifyStartupAtom(void) const
+ { return blackbox_notify_startup; }
+ inline Atom getBlackboxNotifyWindowAddAtom(void) const
+ { return blackbox_notify_window_add; }
+ inline Atom getBlackboxNotifyWindowDelAtom(void) const
+ { return blackbox_notify_window_del; }
+ inline Atom getBlackboxNotifyWindowFocusAtom(void) const
+ { return blackbox_notify_window_focus; }
+ inline Atom getBlackboxNotifyCurrentWorkspaceAtom(void) const
+ { return blackbox_notify_current_workspace; }
+ inline Atom getBlackboxNotifyWorkspaceCountAtom(void) const
+ { return blackbox_notify_workspace_count; }
+ inline Atom getBlackboxNotifyWindowRaiseAtom(void) const
+ { return blackbox_notify_window_raise; }
+ inline Atom getBlackboxNotifyWindowLowerAtom(void) const
+ { return blackbox_notify_window_lower; }
+
+ // atoms to change that request changes to the desktop environment during
+ // runtime... these messages can be sent by any client... as the sending
+ // client window id is not included in the ClientMessage event...
+ inline Atom getBlackboxChangeWorkspaceAtom(void) const
+ { return blackbox_change_workspace; }
+ inline Atom getBlackboxChangeWindowFocusAtom(void) const
+ { return blackbox_change_window_focus; }
+ inline Atom getBlackboxCycleWindowFocusAtom(void) const
+ { return blackbox_cycle_window_focus; }
+
+#ifdef NEWWMSPEC
+ // root window properties
+ inline Atom getNETSupportedAtom(void) const
+ { return net_supported; }
+ inline Atom getNETClientListAtom(void) const
+ { return net_client_list; }
+ inline Atom getNETClientListStackingAtom(void) const
+ { return net_client_list_stacking; }
+ inline Atom getNETNumberOfDesktopsAtom(void) const
+ { return net_number_of_desktops; }
+ inline Atom getNETDesktopGeometryAtom(void) const
+ { return net_desktop_geometry; }
+ inline Atom getNETDesktopViewportAtom(void) const
+ { return net_desktop_viewport; }
+ inline Atom getNETCurrentDesktopAtom(void) const
+ { return net_current_desktop; }
+ inline Atom getNETDesktopNamesAtom(void) const
+ { return net_desktop_names; }
+ inline Atom getNETActiveWindowAtom(void) const
+ { return net_active_window; }
+ inline Atom getNETWorkareaAtom(void) const
+ { return net_workarea; }
+ inline Atom getNETSupportingWMCheckAtom(void) const
+ { return net_supporting_wm_check; }
+ inline Atom getNETVirtualRootsAtom(void) const
+ { return net_virtual_roots; }
+
+ // root window messages
+ inline Atom getNETCloseWindowAtom(void) const
+ { return net_close_window; }
+ inline Atom getNETWMMoveResizeAtom(void) const
+ { return net_wm_moveresize; }
+
+ // application window properties
+ inline Atom getNETPropertiesAtom(void) const
+ { return net_properties; }
+ inline Atom getNETWMNameAtom(void) const
+ { return net_wm_name; }
+ inline Atom getNETWMDesktopAtom(void) const
+ { return net_wm_desktop; }
+ inline Atom getNETWMWindowTypeAtom(void) const
+ { return net_wm_window_type; }
+ inline Atom getNETWMStateAtom(void) const
+ { return net_wm_state; }
+ inline Atom getNETWMStrutAtom(void) const
+ { return net_wm_strut; }
+ inline Atom getNETWMIconGeometryAtom(void) const
+ { return net_wm_icon_geometry; }
+ inline Atom getNETWMIconAtom(void) const
+ { return net_wm_icon; }
+ inline Atom getNETWMPidAtom(void) const
+ { return net_wm_pid; }
+ inline Atom getNETWMHandledIconsAtom(void) const
+ { return net_wm_handled_icons; }
+
+ // application protocols
+ inline Atom getNETWMPingAtom(void) const
+ { return net_wm_ping; }
+#endif // NEWWMSPEC
+};
+
+
+#endif // __blackbox_hh
+++ /dev/null
-/**************************************************************
- * Original:
- * Patrick Powell Tue Apr 11 09:48:21 PDT 1995
- * A bombproof version of doprnt (dopr) included.
- * Sigh. This sort of thing is always nasty do deal with. Note that
- * the version here does not include floating point...
- *
- * snprintf() is used instead of sprintf() as it does limit checks
- * for string length. This covers a nasty loophole.
- *
- * The other functions are there to prevent NULL pointers from
- * causing nast effects.
- *
- * More Recently:
- * Brandon Long <blong@fiction.net> 9/15/96 for mutt 0.43
- * This was ugly. It is still ugly. I opted out of floating point
- * numbers, but the formatter understands just about everything
- * from the normal C string format, at least as far as I can tell from
- * the Solaris 2.5 printf(3S) man page.
- *
- * Brandon Long <blong@fiction.net> 10/22/97 for mutt 0.87.1
- * Ok, added some minimal floating point support, which means this
- * probably requires libm on most operating systems. Don't yet
- * support the exponent (e,E) and sigfig (g,G). Also, fmtint()
- * was pretty badly broken, it just wasn't being exercised in ways
- * which showed it, so that's been fixed. Also, formated the code
- * to mutt conventions, and removed dead code left over from the
- * original. Also, there is now a builtin-test, just compile with:
- * gcc -DTEST_SNPRINTF -o snprintf snprintf.c -lm
- * and run snprintf for results.
- *
- * Thomas Roessler <roessler@guug.de> 01/27/98 for mutt 0.89i
- * The PGP code was using unsigned hexadecimal formats.
- * Unfortunately, unsigned formats simply didn't work.
- *
- * Michael Elkins <me@cs.hmc.edu> 03/05/98 for mutt 0.90.8
- * The original code assumed that both snprintf() and vsnprintf() were
- * missing. Some systems only have snprintf() but not vsnprintf(), so
- * the code is now broken down under HAVE_SNPRINTF and HAVE_VSNPRINTF.
- *
- **************************************************************/
-
-#include "config.h"
-
-#if !defined(HAVE_SNPRINTF) || !defined(HAVE_VSNPRINTF)
-
-#include <string.h>
-# include <ctype.h>
-#include <sys/types.h>
-
-/* Define this as a fall through, HAVE_STDARG_H is probably already set */
-
-#define HAVE_VARARGS_H
-
-/* varargs declarations: */
-
-#if defined(HAVE_STDARG_H)
-# include <stdarg.h>
-# define HAVE_STDARGS /* let's hope that works everywhere (mj) */
-# define VA_LOCAL_DECL va_list ap
-# define VA_START(f) va_start(ap, f)
-# define VA_SHIFT(v,t) ; /* no-op for ANSI */
-# define VA_END va_end(ap)
-#else
-# if defined(HAVE_VARARGS_H)
-# include <varargs.h>
-# undef HAVE_STDARGS
-# define VA_LOCAL_DECL va_list ap
-# define VA_START(f) va_start(ap) /* f is ignored! */
-# define VA_SHIFT(v,t) v = va_arg(ap,t)
-# define VA_END va_end(ap)
-# else
-/*XX ** NO VARARGS ** XX*/
-# endif
-#endif
-
-/*int snprintf (char *str, size_t count, const char *fmt, ...);*/
-/*int vsnprintf (char *str, size_t count, const char *fmt, va_list arg);*/
-
-static void dopr (char *buffer, size_t maxlen, const char *format,
- va_list args);
-static void fmtstr (char *buffer, size_t *currlen, size_t maxlen,
- char *value, int flags, int min, int max);
-static void fmtint (char *buffer, size_t *currlen, size_t maxlen,
- long value, int base, int min, int max, int flags);
-static void fmtfp (char *buffer, size_t *currlen, size_t maxlen,
- long double fvalue, int min, int max, int flags);
-static void dopr_outch (char *buffer, size_t *currlen, size_t maxlen, char c );
-
-/*
- * dopr(): poor man's version of doprintf
- */
-
-/* format read states */
-#define DP_S_DEFAULT 0
-#define DP_S_FLAGS 1
-#define DP_S_MIN 2
-#define DP_S_DOT 3
-#define DP_S_MAX 4
-#define DP_S_MOD 5
-#define DP_S_CONV 6
-#define DP_S_DONE 7
-
-/* format flags - Bits */
-#define DP_F_MINUS (1 << 0)
-#define DP_F_PLUS (1 << 1)
-#define DP_F_SPACE (1 << 2)
-#define DP_F_NUM (1 << 3)
-#define DP_F_ZERO (1 << 4)
-#define DP_F_UP (1 << 5)
-#define DP_F_UNSIGNED (1 << 6)
-
-/* Conversion Flags */
-#define DP_C_SHORT 1
-#define DP_C_LONG 2
-#define DP_C_LDOUBLE 3
-
-#define char_to_int(p) (p - '0')
-#define MAX(p,q) ((p >= q) ? p : q)
-
-static void dopr (char *buffer, size_t maxlen, const char *format, va_list args)
-{
- char ch;
- long value;
- long double fvalue;
- char *strvalue;
- int min;
- int max;
- int state;
- int flags;
- int cflags;
- size_t currlen;
-
- state = DP_S_DEFAULT;
- currlen = flags = cflags = min = 0;
- max = -1;
- ch = *format++;
-
- while (state != DP_S_DONE)
- {
- if ((ch == '\0') || (currlen >= maxlen))
- state = DP_S_DONE;
-
- switch(state)
- {
- case DP_S_DEFAULT:
- if (ch == '%')
- state = DP_S_FLAGS;
- else
- dopr_outch (buffer, &currlen, maxlen, ch);
- ch = *format++;
- break;
- case DP_S_FLAGS:
- switch (ch)
- {
- case '-':
- flags |= DP_F_MINUS;
- ch = *format++;
- break;
- case '+':
- flags |= DP_F_PLUS;
- ch = *format++;
- break;
- case ' ':
- flags |= DP_F_SPACE;
- ch = *format++;
- break;
- case '#':
- flags |= DP_F_NUM;
- ch = *format++;
- break;
- case '0':
- flags |= DP_F_ZERO;
- ch = *format++;
- break;
- default:
- state = DP_S_MIN;
- break;
- }
- break;
- case DP_S_MIN:
- if (isdigit((unsigned char)ch))
- {
- min = 10*min + char_to_int (ch);
- ch = *format++;
- }
- else if (ch == '*')
- {
- min = va_arg (args, int);
- ch = *format++;
- state = DP_S_DOT;
- }
- else
- state = DP_S_DOT;
- break;
- case DP_S_DOT:
- if (ch == '.')
- {
- state = DP_S_MAX;
- ch = *format++;
- }
- else
- state = DP_S_MOD;
- break;
- case DP_S_MAX:
- if (isdigit((unsigned char)ch))
- {
- if (max < 0)
- max = 0;
- max = 10*max + char_to_int (ch);
- ch = *format++;
- }
- else if (ch == '*')
- {
- max = va_arg (args, int);
- ch = *format++;
- state = DP_S_MOD;
- }
- else
- state = DP_S_MOD;
- break;
- case DP_S_MOD:
- /* Currently, we don't support Long Long, bummer */
- switch (ch)
- {
- case 'h':
- cflags = DP_C_SHORT;
- ch = *format++;
- break;
- case 'l':
- cflags = DP_C_LONG;
- ch = *format++;
- break;
- case 'L':
- cflags = DP_C_LDOUBLE;
- ch = *format++;
- break;
- default:
- break;
- }
- state = DP_S_CONV;
- break;
- case DP_S_CONV:
- switch (ch)
- {
- case 'd':
- case 'i':
- if (cflags == DP_C_SHORT)
- value = va_arg (args, short int);
- else if (cflags == DP_C_LONG)
- value = va_arg (args, long int);
- else
- value = va_arg (args, int);
- fmtint (buffer, &currlen, maxlen, value, 10, min, max, flags);
- break;
- case 'o':
- flags |= DP_F_UNSIGNED;
- if (cflags == DP_C_SHORT)
- value = va_arg (args, unsigned short int);
- else if (cflags == DP_C_LONG)
- value = va_arg (args, unsigned long int);
- else
- value = va_arg (args, unsigned int);
- fmtint (buffer, &currlen, maxlen, value, 8, min, max, flags);
- break;
- case 'u':
- flags |= DP_F_UNSIGNED;
- if (cflags == DP_C_SHORT)
- value = va_arg (args, unsigned short int);
- else if (cflags == DP_C_LONG)
- value = va_arg (args, unsigned long int);
- else
- value = va_arg (args, unsigned int);
- fmtint (buffer, &currlen, maxlen, value, 10, min, max, flags);
- break;
- case 'X':
- flags |= DP_F_UP;
- case 'x':
- flags |= DP_F_UNSIGNED;
- if (cflags == DP_C_SHORT)
- value = va_arg (args, unsigned short int);
- else if (cflags == DP_C_LONG)
- value = va_arg (args, unsigned long int);
- else
- value = va_arg (args, unsigned int);
- fmtint (buffer, &currlen, maxlen, value, 16, min, max, flags);
- break;
- case 'f':
- if (cflags == DP_C_LDOUBLE)
- fvalue = va_arg (args, long double);
- else
- fvalue = va_arg (args, double);
- /* um, floating point? */
- fmtfp (buffer, &currlen, maxlen, fvalue, min, max, flags);
- break;
- case 'E':
- flags |= DP_F_UP;
- case 'e':
- if (cflags == DP_C_LDOUBLE)
- fvalue = va_arg (args, long double);
- else
- fvalue = va_arg (args, double);
- break;
- case 'G':
- flags |= DP_F_UP;
- case 'g':
- if (cflags == DP_C_LDOUBLE)
- fvalue = va_arg (args, long double);
- else
- fvalue = va_arg (args, double);
- break;
- case 'c':
- dopr_outch (buffer, &currlen, maxlen, va_arg (args, int));
- break;
- case 's':
- strvalue = va_arg (args, char *);
- if (max < 0)
- max = maxlen; /* ie, no max */
- fmtstr (buffer, &currlen, maxlen, strvalue, flags, min, max);
- break;
- case 'p':
- strvalue = va_arg (args, void *);
- fmtint (buffer, &currlen, maxlen, (long) strvalue, 16, min, max, flags);
- break;
- case 'n':
- if (cflags == DP_C_SHORT)
- {
- short int *num;
- num = va_arg (args, short int *);
- *num = currlen;
- }
- else if (cflags == DP_C_LONG)
- {
- long int *num;
- num = va_arg (args, long int *);
- *num = currlen;
- }
- else
- {
- int *num;
- num = va_arg (args, int *);
- *num = currlen;
- }
- break;
- case '%':
- dopr_outch (buffer, &currlen, maxlen, ch);
- break;
- case 'w':
- /* not supported yet, treat as next char */
- ch = *format++;
- break;
- default:
- /* Unknown, skip */
- break;
- }
- ch = *format++;
- state = DP_S_DEFAULT;
- flags = cflags = min = 0;
- max = -1;
- break;
- case DP_S_DONE:
- break;
- default:
- /* hmm? */
- break; /* some picky compilers need this */
- }
- }
- if (currlen < maxlen - 1)
- buffer[currlen] = '\0';
- else
- buffer[maxlen - 1] = '\0';
-}
-
-static void fmtstr (char *buffer, size_t *currlen, size_t maxlen,
- char *value, int flags, int min, int max)
-{
- int padlen, strln; /* amount to pad */
- int cnt = 0;
-
- if (value == 0)
- {
- value = "<NULL>";
- }
-
- for (strln = 0; value[strln]; ++strln); /* strlen */
- padlen = min - strln;
- if (padlen < 0)
- padlen = 0;
- if (flags & DP_F_MINUS)
- padlen = -padlen; /* Left Justify */
-
- while ((padlen > 0) && (cnt < max))
- {
- dopr_outch (buffer, currlen, maxlen, ' ');
- --padlen;
- ++cnt;
- }
- while (*value && (cnt < max))
- {
- dopr_outch (buffer, currlen, maxlen, *value++);
- ++cnt;
- }
- while ((padlen < 0) && (cnt < max))
- {
- dopr_outch (buffer, currlen, maxlen, ' ');
- ++padlen;
- ++cnt;
- }
-}
-
-/* Have to handle DP_F_NUM (ie 0x and 0 alternates) */
-
-static void fmtint (char *buffer, size_t *currlen, size_t maxlen,
- long value, int base, int min, int max, int flags)
-{
- int signvalue = 0;
- unsigned long uvalue;
- char convert[20];
- int place = 0;
- int spadlen = 0; /* amount to space pad */
- int zpadlen = 0; /* amount to zero pad */
- int caps = 0;
-
- if (max < 0)
- max = 0;
-
- uvalue = value;
-
- if(!(flags & DP_F_UNSIGNED))
- {
- if( value < 0 ) {
- signvalue = '-';
- uvalue = -value;
- }
- else
- if (flags & DP_F_PLUS) /* Do a sign (+/i) */
- signvalue = '+';
- else
- if (flags & DP_F_SPACE)
- signvalue = ' ';
- }
-
- if (flags & DP_F_UP) caps = 1; /* Should characters be upper case? */
-
- do {
- convert[place++] =
- (caps? "0123456789ABCDEF":"0123456789abcdef")
- [uvalue % (unsigned)base ];
- uvalue = (uvalue / (unsigned)base );
- } while(uvalue && (place < 20));
- if (place == 20) place--;
- convert[place] = 0;
-
- zpadlen = max - place;
- spadlen = min - MAX (max, place) - (signvalue ? 1 : 0);
- if (zpadlen < 0) zpadlen = 0;
- if (spadlen < 0) spadlen = 0;
- if (flags & DP_F_ZERO)
- {
- zpadlen = MAX(zpadlen, spadlen);
- spadlen = 0;
- }
- if (flags & DP_F_MINUS)
- spadlen = -spadlen; /* Left Justifty */
-
-#ifdef DEBUG_SNPRINTF
- dprint (1, (debugfile, "zpad: %d, spad: %d, min: %d, max: %d, place: %d\n",
- zpadlen, spadlen, min, max, place));
-#endif
-
- /* Spaces */
- while (spadlen > 0)
- {
- dopr_outch (buffer, currlen, maxlen, ' ');
- --spadlen;
- }
-
- /* Sign */
- if (signvalue)
- dopr_outch (buffer, currlen, maxlen, signvalue);
-
- /* Zeros */
- if (zpadlen > 0)
- {
- while (zpadlen > 0)
- {
- dopr_outch (buffer, currlen, maxlen, '0');
- --zpadlen;
- }
- }
-
- /* Digits */
- while (place > 0)
- dopr_outch (buffer, currlen, maxlen, convert[--place]);
-
- /* Left Justified spaces */
- while (spadlen < 0) {
- dopr_outch (buffer, currlen, maxlen, ' ');
- ++spadlen;
- }
-}
-
-static long double abs_val (long double value)
-{
- long double result = value;
-
- if (value < 0)
- result = -value;
-
- return result;
-}
-
-static long double pow10 (int exp)
-{
- long double result = 1;
-
- while (exp)
- {
- result *= 10;
- exp--;
- }
-
- return result;
-}
-
-static long round (long double value)
-{
- long intpart;
-
- intpart = value;
- value = value - intpart;
- if (value >= 0.5)
- intpart++;
-
- return intpart;
-}
-
-static void fmtfp (char *buffer, size_t *currlen, size_t maxlen,
- long double fvalue, int min, int max, int flags)
-{
- int signvalue = 0;
- long double ufvalue;
- char iconvert[20];
- char fconvert[20];
- int iplace = 0;
- int fplace = 0;
- int padlen = 0; /* amount to pad */
- int zpadlen = 0;
- int caps = 0;
- long intpart;
- long fracpart;
-
- /*
- * AIX manpage says the default is 0, but Solaris says the default
- * is 6, and sprintf on AIX defaults to 6
- */
- if (max < 0)
- max = 6;
-
- ufvalue = abs_val (fvalue);
-
- if (fvalue < 0)
- signvalue = '-';
- else
- if (flags & DP_F_PLUS) /* Do a sign (+/i) */
- signvalue = '+';
- else
- if (flags & DP_F_SPACE)
- signvalue = ' ';
-
-#if 0
- if (flags & DP_F_UP) caps = 1; /* Should characters be upper case? */
-#endif
-
- intpart = ufvalue;
-
- /*
- * Sorry, we only support 9 digits past the decimal because of our
- * conversion method
- */
- if (max > 9)
- max = 9;
-
- /* We "cheat" by converting the fractional part to integer by
- * multiplying by a factor of 10
- */
- fracpart = round ((pow10 (max)) * (ufvalue - intpart));
-
- if (fracpart >= pow10 (max))
- {
- intpart++;
- fracpart -= pow10 (max);
- }
-
-#ifdef DEBUG_SNPRINTF
- dprint (1, (debugfile, "fmtfp: %f =? %d.%d\n", fvalue, intpart, fracpart));
-#endif
-
- /* Convert integer part */
- do {
- iconvert[iplace++] =
- (caps? "0123456789ABCDEF":"0123456789abcdef")[intpart % 10];
- intpart = (intpart / 10);
- } while(intpart && (iplace < 20));
- if (iplace == 20) iplace--;
- iconvert[iplace] = 0;
-
- /* Convert fractional part */
- do {
- fconvert[fplace++] =
- (caps? "0123456789ABCDEF":"0123456789abcdef")[fracpart % 10];
- fracpart = (fracpart / 10);
- } while(fracpart && (fplace < 20));
- if (fplace == 20) fplace--;
- fconvert[fplace] = 0;
-
- /* -1 for decimal point, another -1 if we are printing a sign */
- padlen = min - iplace - max - 1 - ((signvalue) ? 1 : 0);
- zpadlen = max - fplace;
- if (zpadlen < 0)
- zpadlen = 0;
- if (padlen < 0)
- padlen = 0;
- if (flags & DP_F_MINUS)
- padlen = -padlen; /* Left Justifty */
-
- if ((flags & DP_F_ZERO) && (padlen > 0))
- {
- if (signvalue)
- {
- dopr_outch (buffer, currlen, maxlen, signvalue);
- --padlen;
- signvalue = 0;
- }
- while (padlen > 0)
- {
- dopr_outch (buffer, currlen, maxlen, '0');
- --padlen;
- }
- }
- while (padlen > 0)
- {
- dopr_outch (buffer, currlen, maxlen, ' ');
- --padlen;
- }
- if (signvalue)
- dopr_outch (buffer, currlen, maxlen, signvalue);
-
- while (iplace > 0)
- dopr_outch (buffer, currlen, maxlen, iconvert[--iplace]);
-
- /*
- * Decimal point. This should probably use locale to find the correct
- * char to print out.
- */
- dopr_outch (buffer, currlen, maxlen, '.');
-
- while (fplace > 0)
- dopr_outch (buffer, currlen, maxlen, fconvert[--fplace]);
-
- while (zpadlen > 0)
- {
- dopr_outch (buffer, currlen, maxlen, '0');
- --zpadlen;
- }
-
- while (padlen < 0)
- {
- dopr_outch (buffer, currlen, maxlen, ' ');
- ++padlen;
- }
-}
-
-static void dopr_outch (char *buffer, size_t *currlen, size_t maxlen, char c)
-{
- if (*currlen < maxlen)
- buffer[(*currlen)++] = c;
-}
-#endif /* !defined(HAVE_SNPRINTF) || !defined(HAVE_VSNPRINTF) */
-
-#ifndef HAVE_VSNPRINTF
-int vsnprintf (char *str, size_t count, const char *fmt, va_list args)
-{
- str[0] = 0;
- dopr(str, count, fmt, args);
- return(strlen(str));
-}
-#endif /* !HAVE_VSNPRINTF */
-
-#ifndef HAVE_SNPRINTF
-/* VARARGS3 */
-#ifdef HAVE_STDARGS
-int snprintf (char *str,size_t count,const char *fmt,...)
-#else
-int snprintf (va_alist) va_dcl
-#endif
-{
-#ifndef HAVE_STDARGS
- char *str;
- size_t count;
- char *fmt;
-#endif
- VA_LOCAL_DECL;
-
- VA_START (fmt);
- VA_SHIFT (str, char *);
- VA_SHIFT (count, size_t );
- VA_SHIFT (fmt, char *);
- (void) vsnprintf(str, count, fmt, ap);
- VA_END;
- return(strlen(str));
-}
-
-#ifdef TEST_SNPRINTF
-#ifndef LONG_STRING
-#define LONG_STRING 1024
-#endif
-int main (void)
-{
- char buf1[LONG_STRING];
- char buf2[LONG_STRING];
- char *fp_fmt[] = {
- "%-1.5f",
- "%1.5f",
- "%123.9f",
- "%10.5f",
- "% 10.5f",
- "%+22.9f",
- "%+4.9f",
- "%01.3f",
- "%4f",
- "%3.1f",
- "%3.2f",
- NULL
- };
- double fp_nums[] = { -1.5, 134.21, 91340.2, 341.1234, 0203.9, 0.96, 0.996,
- 0.9996, 1.996, 4.136, 0};
- char *int_fmt[] = {
- "%-1.5d",
- "%1.5d",
- "%123.9d",
- "%5.5d",
- "%10.5d",
- "% 10.5d",
- "%+22.33d",
- "%01.3d",
- "%4d",
- NULL
- };
- long int_nums[] = { -1, 134, 91340, 341, 0203, 0};
- int x, y;
- int fail = 0;
- int num = 0;
-
- printf ("Testing snprintf format codes against system sprintf...\n");
-
- for (x = 0; fp_fmt[x] != NULL ; x++)
- for (y = 0; fp_nums[y] != 0 ; y++)
- {
- snprintf (buf1, sizeof (buf1), fp_fmt[x], fp_nums[y]);
- sprintf (buf2, fp_fmt[x], fp_nums[y]);
- if (strcmp (buf1, buf2))
- {
- printf("snprintf doesn't match Format: %s\n\tsnprintf = %s\n\tsprintf = %s\n",
- fp_fmt[x], buf1, buf2);
- fail++;
- }
- num++;
- }
-
- for (x = 0; int_fmt[x] != NULL ; x++)
- for (y = 0; int_nums[y] != 0 ; y++)
- {
- snprintf (buf1, sizeof (buf1), int_fmt[x], int_nums[y]);
- sprintf (buf2, int_fmt[x], int_nums[y]);
- if (strcmp (buf1, buf2))
- {
- printf("snprintf doesn't match Format: %s\n\tsnprintf = %s\n\tsprintf = %s\n",
- int_fmt[x], buf1, buf2);
- fail++;
- }
- num++;
- }
- printf ("%d tests failed out of %d.\n", fail, num);
-}
-#endif /* SNPRINTF_TEST */
-
-#endif /* !HAVE_SNPRINTF */
+++ /dev/null
-#ifndef _BSD_SNPRINTF_H
-#define _BSD_SNPRINTF_H
-
-#include "config.h"
-
-#include <sys/types.h> /* For size_t */
-
-#ifndef HAVE_SNPRINTF
-int snprintf(char *str, size_t count, const char *fmt, ...);
-#endif /* !HAVE_SNPRINTF */
-
-#ifndef HAVE_VSNPRINTF
-int vsnprintf(char *str, size_t count, const char *fmt, va_list args);
-#endif /* !HAVE_SNPRINTF */
-
-
-#endif /* _BSD_SNPRINTF_H */
// -*- mode: C++; indent-tabs-mode: nil; c-basic-offset: 2; -*-
-// i18n.cc for Openbox
+// i18n.cc for Blackbox - an X11 Window manager
// Copyright (c) 2001 - 2002 Sean 'Shaleh' Perry <shaleh@debian.org>
// Copyright (c) 1997 - 2000 Brad Hughes (bhughes@tcac.net)
//
}
#include <string>
+using std::string;
-#include "i18n.h"
+#include "i18n.hh"
-I18n::I18n(const char *catalog) {
- mb = false;
+
+// the rest of bb source uses True and False from X, so we continue that
+#define True true
+#define False false
+
+I18n::I18n(void) {
+ mb = False;
#ifdef HAVE_SETLOCALE
locale = setlocale(LC_ALL, "");
if (! locale) {
} else {
// MB_CUR_MAX returns the size of a char in the current locale
if (MB_CUR_MAX > 1)
- mb = true;
+ mb = True;
// truncate any encoding off the end of the locale
char *l = strchr(locale, '@');
if (l) *l = '\0';
catalog_fd = (nl_catd) -1;
#endif
#endif // HAVE_SETLOCALE
- if (catalog)
- openCatalog(catalog);
}
-I18n::~I18n() {
+I18n::~I18n(void) {
#if defined(NLS) && defined(HAVE_CATCLOSE)
if (catalog_fd != (nl_catd) -1)
catclose(catalog_fd);
}
-#if defined(NLS) && defined(HAVE_CATOPEN)
void I18n::openCatalog(const char *catalog) {
- std::string catalog_filename = LOCALEPATH;
+#if defined(NLS) && defined(HAVE_CATOPEN)
+ string catalog_filename = LOCALEPATH;
catalog_filename += '/';
catalog_filename += locale;
catalog_filename += '/';
if (catalog_fd == (nl_catd) -1)
fprintf(stderr, "failed to open catalog, using default messages\n");
-}
-#else
-void I18n::openCatalog(const char *) {
-}
#endif // HAVE_CATOPEN
+}
-#if defined(NLS) && defined(HAVE_CATGETS)
const char* I18n::operator()(int set, int msg, const char *msgString) const {
+#if defined(NLS) && defined(HAVE_CATGETS)
if (catalog_fd != (nl_catd) -1)
return catgets(catalog_fd, set, msg, msgString);
else
+#endif
return msgString;
}
-#else
-const char* I18n::operator()(int, int, const char *msgString) const {
- return msgString;
-}
-#endif
// -*- mode: C++; indent-tabs-mode: nil; -*-
-// i18n.hh for Openbox
+// i18n.hh for Blackbox - an X11 Window manager
// Copyright (c) 2001 - 2002 Sean 'Shaleh' Perry <shaleh@debian.org>
// Copyright (c) 1997 - 2000 Brad Hughes (bhughes@tcac.net)
//
// always include this just for the #defines
// this keeps the calls to i18n->getMessage clean, otherwise we have to
// add ifdefs to every call to getMessage
-#include "../nls/openbox-nls.h"
+#include "../nls/blackbox-nls.hh"
extern "C" {
#ifdef HAVE_LOCALE_H
#endif
public:
- I18n(const char *catalog = 0);
- ~I18n();
+ I18n(void);
+ ~I18n(void);
inline bool multibyte(void) const { return mb; }
void openCatalog(const char *catalog);
};
-extern I18n i18n; // located in main.cc
+extern I18n i18n;
#endif // __i18n_h
-// main.cc for Openbox
-// Copyright (c) 2001 Sean 'Shaleh' Perry <shaleh@debian.org>
+// -*- mode: C++; indent-tabs-mode: nil; -*-
+// main.cc for Blackbox - an X11 Window manager
+// Copyright (c) 2001 - 2002 Sean 'Shaleh' Perry <shaleh@debian.org>
// Copyright (c) 1997 - 2000 Brad Hughes (bhughes@tcac.net)
//
// Permission is hereby granted, free of charge, to any person obtaining a
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
-// stupid macros needed to access some functions in version 2 of the GNU C
-// library
-#ifndef _GNU_SOURCE
-#define _GNU_SOURCE
-#endif // _GNU_SOURCE
-
#include "../version.h"
#ifdef HAVE_CONFIG_H
# include "../config.h"
#endif // HAVE_CONFIG_H
+extern "C" {
#ifdef HAVE_STDIO_H
# include <stdio.h>
#endif // HAVE_STDIO_H
-#ifdef HAVE_STDLIB_H
+#ifdef HAVE_STDLIB_H
# include <stdlib.h>
#endif // HAVE_STDLIB_H
-#ifdef HAVE_STRING_H
+#ifdef HAVE_STRING_H
# include <string.h>
#endif // HAVE_STRING_H
#ifdef HAVE_SYS_PARAM_H
# include <sys/param.h>
#endif // HAVE_SYS_PARAM_H
+}
-#ifndef MAXPATHLEN
-#define MAXPATHLEN 255
-#endif // MAXPATHLEN
+#include <string>
+using std::string;
-#include "openbox.h"
-#include "i18n.h"
+#include "i18n.hh"
+#include "blackbox.hh"
-I18n i18n("openbox.cat");
+
+I18n i18n; // initialized in main
static void showHelp(int exitval) {
// print program usage and command line options
printf(i18n(mainSet, mainUsage,
- "Openbox %s : (c) 2002 - 2002 Ben Jansens\n"
- "\t\t\t 2001 - 2002 Sean 'Shaleh' Perry\n\n"
- "\t\t\t 1997 - 2000 Brad Hughes\n\n"
+ "Blackbox %s : (c) 2001 - 2002 Sean 'Shaleh' Perry\n"
+ "\t\t\t 1997 - 2000, 2002 Brad Hughes\n\n"
" -display <string>\t\tuse display connection.\n"
" -rc <string>\t\t\tuse alternate resource file.\n"
- " -menu <string>\t\t\tuse alternate menu file.\n"
" -version\t\t\tdisplay version and exit.\n"
" -help\t\t\t\tdisplay this help text and exit.\n\n"),
- __openbox_version);
+ __blackbox_version);
// some people have requested that we print out compile options
// as well
- fprintf(stdout,i18n(mainSet, mainCompileOptions,
- "Compile time options:\n"
- " Debugging:\t\t\t%s\n"
- " Interlacing:\t\t\t%s\n"
- " Shape:\t\t\t%s\n"
- " Slit:\t\t\t\t%s\n"
- " 8bpp Ordered Dithering:\t%s\n"
- " Event Clobbering:\t\t%s\n\n"),
+ printf(i18n(mainSet, mainCompileOptions,
+ "Compile time options:\n"
+ " Debugging:\t\t\t%s\n"
+ " Shape:\t\t\t%s\n"
+ " 8bpp Ordered Dithering:\t%s\n\n"),
#ifdef DEBUG
- i18n(CommonSet, CommonYes, "yes"),
+ i18n(CommonSet, CommonYes, "yes"),
#else // !DEBUG
- i18n(CommonSet, CommonNo, "no"),
+ i18n(CommonSet, CommonNo, "no"),
#endif // DEBUG
-#ifdef INTERLACE
- i18n(CommonSet, CommonYes, "yes"),
-#else // !INTERLACE
- i18n(CommonSet, CommonNo, "no"),
-#endif // INTERLACE
-
#ifdef SHAPE
- i18n(CommonSet, CommonYes, "yes"),
+ i18n(CommonSet, CommonYes, "yes"),
#else // !SHAPE
- i18n(CommonSet, CommonNo, "no"),
+ i18n(CommonSet, CommonNo, "no"),
#endif // SHAPE
-#ifdef SLIT
- i18n(CommonSet, CommonYes, "yes"),
-#else // !SLIT
- i18n(CommonSet, CommonNo, "no"),
-#endif // SLIT
-
#ifdef ORDEREDPSEUDO
- i18n(CommonSet, CommonYes, "yes"),
+ i18n(CommonSet, CommonYes, "yes")
#else // !ORDEREDPSEUDO
- i18n(CommonSet, CommonNo, "no"),
+ i18n(CommonSet, CommonNo, "no")
#endif // ORDEREDPSEUDO
+ );
-#ifndef NOCLOBBER
- i18n(CommonSet, CommonYes, "yes")
-#else // !NOCLOBBER
- i18n(CommonSet, CommonNo, "no")
-#endif // NOCLOBBER
- );
-
- ::exit(exitval);
+ ::exit(exitval);
}
int main(int argc, char **argv) {
char *session_display = (char *) 0;
char *rc_file = (char *) 0;
- char *menu_file = (char *) 0;
+
+ i18n.openCatalog("blackbox.cat");
for (int i = 1; i < argc; ++i) {
if (! strcmp(argv[i], "-rc")) {
if ((++i) >= argc) {
fprintf(stderr,
i18n(mainSet, mainRCRequiresArg,
- "error: '-rc' requires and argument\n"));
+ "error: '-rc' requires and argument\n"));
::exit(1);
}
rc_file = argv[i];
- } else if (! strcmp(argv[i], "-menu")) {
- // look for alternative menu file to use
-
- if ((++i) >= argc) {
- fprintf(stderr,
- i18n(mainSet, mainMENURequiresArg,
- "error: '-menu' requires and argument\n"));
-
- ::exit(1);
- }
-
- menu_file = argv[i];
} else if (! strcmp(argv[i], "-display")) {
// check for -display option... to run on a display other than the one
// set by the environment variable DISPLAY
if ((++i) >= argc) {
fprintf(stderr,
i18n(mainSet, mainDISPLAYRequiresArg,
- "error: '-display' requires an argument\n"));
+ "error: '-display' requires an argument\n"));
::exit(1);
}
session_display = argv[i];
- char dtmp[MAXPATHLEN];
- sprintf(dtmp, "DISPLAY=%s", session_display);
+ string dtmp = "DISPLAY=";
+ dtmp += session_display;
- if (putenv(dtmp)) {
- fprintf(stderr,
- i18n(mainSet, mainWarnDisplaySet,
- "warning: couldn't set environment variable 'DISPLAY'\n"));
+ if (putenv(const_cast<char*>(dtmp.c_str()))) {
+ fprintf(stderr, i18n(mainSet, mainWarnDisplaySet,
+ "warning: couldn't set environment variable 'DISPLAY'\n"));
perror("putenv()");
}
} else if (! strcmp(argv[i], "-version")) {
// print current version string
- printf("Openbox %s : (c) 2002 - 2002 Ben Jansens\n"
- "\t\t 2001 - 2002 Sean 'Shaleh' Perry\n"
- "\t\t 1997 - 2000 Brad Hughes\n",
- __openbox_version);
+ printf("Blackbox %s : (c) 2001 - 2002 Sean 'Shaleh' Perry\n",
+ "\t\t\t 1997 - 2000 Brad Hughes\n"
+ __blackbox_version);
::exit(0);
} else if (! strcmp(argv[i], "-help")) {
_chdir2(getenv("X11ROOT"));
#endif // __EMX__
- Openbox openbox(argc, argv, session_display, rc_file, menu_file);
- openbox.eventLoop();
+ Blackbox blackbox(argv, session_display, rc_file);
+ blackbox.eventLoop();
return(0);
}
+++ /dev/null
-// openbox.cc for Openbox
-// Copyright (c) 2001 Sean 'Shaleh' Perry <shaleh@debian.org>
-// Copyright (c) 1997 - 2000 Brad Hughes (bhughes@tcac.net)
-//
-// Permission is hereby granted, free of charge, to any person obtaining a
-// copy of this software and associated documentation files (the "Software"),
-// to deal in the Software without restriction, including without limitation
-// the rights to use, copy, modify, merge, publish, distribute, sublicense,
-// and/or sell copies of the Software, and to permit persons to whom the
-// Software is furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-// DEALINGS IN THE SOFTWARE.
-
-// stupid macros needed to access some functions in version 2 of the GNU C
-// library
-#ifndef _GNU_SOURCE
-#define _GNU_SOURCE
-#endif // _GNU_SOURCE
-
-#ifdef HAVE_CONFIG_H
-# include "../config.h"
-#endif // HAVE_CONFIG_H
-
-#include <X11/Xlib.h>
-#include <X11/Xutil.h>
-#include <X11/Xresource.h>
-#include <X11/Xatom.h>
-#include <X11/keysym.h>
-
-#ifdef SHAPE
-#include <X11/extensions/shape.h>
-#endif // SHAPE
-
-#include "i18n.h"
-#include "openbox.h"
-#include "Basemenu.h"
-#include "Clientmenu.h"
-#include "Rootmenu.h"
-#include "Screen.h"
-
-#ifdef SLIT
-#include "Slit.h"
-#endif // SLIT
-
-#include "Toolbar.h"
-#include "Window.h"
-#include "Workspace.h"
-#include "Workspacemenu.h"
-#include "Util.h"
-
-#include <string>
-#include <algorithm>
-
-#ifdef HAVE_STDIO_H
-# include <stdio.h>
-#endif // HAVE_STDIO_H
-
-#ifdef HAVE_STDLIB_H
-# include <stdlib.h>
-#endif // HAVE_STDLIB_H
-
-#ifdef HAVE_STRING_H
-# include <string.h>
-#endif // HAVE_STRING_H
-
-#ifdef HAVE_UNISTD_H
-# include <sys/types.h>
-# include <unistd.h>
-#endif // HAVE_UNISTD_H
-
-#ifdef HAVE_SYS_PARAM_H
-# include <sys/param.h>
-#endif // HAVE_SYS_PARAM_H
-
-#ifndef MAXPATHLEN
-#define MAXPATHLEN 255
-#endif // MAXPATHLEN
-
-#ifdef HAVE_SYS_SELECT_H
-# include <sys/select.h>
-#endif // HAVE_SYS_SELECT_H
-
-#ifdef HAVE_SIGNAL_H
-# include <signal.h>
-#endif // HAVE_SIGNAL_H
-
-#ifdef HAVE_SYS_SIGNAL_H
-# include <sys/signal.h>
-#endif // HAVE_SYS_SIGNAL_H
-
-#ifdef HAVE_SYS_STAT_H
-# include <sys/types.h>
-# include <sys/stat.h>
-#endif // HAVE_SYS_STAT_H
-
-#ifdef TIME_WITH_SYS_TIME
-# include <sys/time.h>
-# include <time.h>
-#else // !TIME_WITH_SYS_TIME
-# ifdef HAVE_SYS_TIME_H
-# include <sys/time.h>
-# else // !HAVE_SYS_TIME_H
-# include <time.h>
-# endif // HAVE_SYS_TIME_H
-#endif // TIME_WITH_SYS_TIME
-
-#ifdef HAVE_LIBGEN_H
-# include <libgen.h>
-#endif // HAVE_LIBGEN_H
-
-#ifndef HAVE_BASENAME
-static inline char *basename (char *s) {
- char *save = s;
-
- while (*s) if (*s++ == '/') save = s;
-
- return save;
-}
-#endif // HAVE_BASENAME
-
-
-// X event scanner for enter/leave notifies - adapted from twm
-typedef struct scanargs {
- Window w;
- Bool leave, inferior, enter;
-} scanargs;
-
-static Bool queueScanner(Display *, XEvent *e, char *args) {
- if ((e->type == LeaveNotify) &&
- (e->xcrossing.window == ((scanargs *) args)->w) &&
- (e->xcrossing.mode == NotifyNormal)) {
- ((scanargs *) args)->leave = True;
- ((scanargs *) args)->inferior = (e->xcrossing.detail == NotifyInferior);
- } else if ((e->type == EnterNotify) &&
- (e->xcrossing.mode == NotifyUngrab)) {
- ((scanargs *) args)->enter = True;
- }
-
- return False;
-}
-
-Openbox *openbox;
-
-
-Openbox::Openbox(int m_argc, char **m_argv, char *dpy_name, char *rc,
- char *menu) : BaseDisplay(m_argv[0], dpy_name) {
- grab();
-
- if (! XSupportsLocale())
- fprintf(stderr, "X server does not support locale\n");
-
- if (XSetLocaleModifiers("") == NULL)
- fprintf(stderr, "cannot set locale modifiers\n");
-
- ::openbox = this;
- argc = m_argc;
- argv = m_argv;
- if (rc == NULL || menu == NULL) {
- char *homedir = getenv("HOME");
- char *configdir = new char[strlen(homedir) + strlen("/.openbox") + 1];
- sprintf(configdir, "%s/.openbox", homedir);
- // try to make sure the ~/.openbox directory exists
- mkdir(configdir, S_IREAD | S_IWRITE | S_IEXEC |
- S_IRGRP | S_IWGRP | S_IXGRP |
- S_IROTH | S_IWOTH | S_IXOTH);
-
-
- if (rc == NULL) {
- rc_file = new char[strlen(configdir) + strlen("/rc") + 1];
- sprintf(rc_file, "%s/rc", configdir);
- } else
- rc_file = bstrdup(rc);
-
- if (menu == NULL) {
- menu_file = new char[strlen(configdir) + strlen("/menu") + 1];
- sprintf(menu_file, "%s/menu", configdir);
- } else
- menu_file = bstrdup(menu);
-
- delete [] configdir;
- }
- config.setFile(rc_file);
-
- no_focus = False;
-
- resource.style_file = NULL;
- resource.titlebar_layout = NULL;
- resource.auto_raise_delay.tv_sec = resource.auto_raise_delay.tv_usec = 0;
-
- current_screen = (BScreen *) 0;
- masked_window = (OpenboxWindow *) 0;
- masked = None;
-
- load();
-
-#ifdef HAVE_GETPID
- openbox_pid = XInternAtom(getXDisplay(), "_BLACKBOX_PID", False);
-#endif // HAVE_GETPID
-
- for (unsigned int s = 0; s < numberOfScreens(); s++) {
- BScreen *screen = new BScreen(*this, s, config);
-
- if (! screen->isScreenManaged()) {
- delete screen;
- continue;
- }
-
- screenList.push_back(screen);
- }
-
- if (screenList.empty()) {
- fprintf(stderr,
- i18n(openboxSet, openboxNoManagableScreens,
- "Openbox::Openbox: no managable screens found, aborting.\n"));
- ::exit(3);
- }
- current_screen = screenList[0];
-
- // save current settings and default values
- save();
-
- XSynchronize(getXDisplay(), False);
- XSync(getXDisplay(), False);
-
- reconfigure_wait = reread_menu_wait = False;
-
- timer = new BTimer(*this, *this);
- timer->setTimeout(0);
- timer->fireOnce(True);
-
- ungrab();
-
- focusWindow(0);
- }
-
-
-Openbox::~Openbox() {
- for_each(screenList.begin(), screenList.end(),
- PointerAssassin());
-
- for_each(menuTimestamps.begin(), menuTimestamps.end(),
- PointerAssassin());
-
- if (resource.style_file)
- delete [] resource.style_file;
-
- if (resource.titlebar_layout)
- delete [] resource.titlebar_layout;
-
- delete timer;
-
- delete [] rc_file;
- delete [] menu_file;
-}
-
-
-void Openbox::process_event(XEvent *e) {
- if ((masked == e->xany.window && masked_window) &&
- (e->type == MotionNotify)) {
- last_time = e->xmotion.time;
- masked_window->motionNotifyEvent(&e->xmotion);
- return;
- }
-
- switch (e->type) {
- case ButtonPress: {
- // strip the lock key modifiers
- e->xbutton.state &= ~(NumLockMask | ScrollLockMask | LockMask);
-
- last_time = e->xbutton.time;
-
- OpenboxWindow *win = (OpenboxWindow *) 0;
- Basemenu *menu = (Basemenu *) 0;
-
-#ifdef SLIT
- Slit *slit = (Slit *) 0;
-#endif // SLIT
-
- Toolbar *tbar = (Toolbar *) 0;
-
- if ((win = searchWindow(e->xbutton.window))) {
- win->buttonPressEvent(&e->xbutton);
-
- if (e->xbutton.button == 1)
- win->installColormap(True);
- } else if ((menu = searchMenu(e->xbutton.window))) {
- menu->buttonPressEvent(&e->xbutton);
-
-#ifdef SLIT
- } else if ((slit = searchSlit(e->xbutton.window))) {
- slit->buttonPressEvent(&e->xbutton);
-#endif // SLIT
-
- } else if ((tbar = searchToolbar(e->xbutton.window))) {
- tbar->buttonPressEvent(&e->xbutton);
- } else {
- ScreenList::iterator it;
- for (it = screenList.begin(); it != screenList.end(); ++it) {
- BScreen *screen = *it;
- if (e->xbutton.window == screen->getRootWindow()) {
- if (e->xbutton.button == 1) {
- if (! screen->isRootColormapInstalled())
- screen->getImageControl()->installRootColormap();
-
- if (screen->getWorkspacemenu()->isVisible())
- screen->getWorkspacemenu()->hide();
-
- if (screen->getRootmenu()->isVisible())
- screen->getRootmenu()->hide();
- } else if (e->xbutton.button == 2) {
- int mx = e->xbutton.x_root -
- (screen->getWorkspacemenu()->getWidth() / 2);
- int my = e->xbutton.y_root -
- (screen->getWorkspacemenu()->getTitleHeight() / 2);
-
- if (mx < 0) mx = 0;
- if (my < 0) my = 0;
-
- if (mx + screen->getWorkspacemenu()->getWidth() >
- screen->size().w())
- mx = screen->size().w() -
- screen->getWorkspacemenu()->getWidth() -
- screen->getBorderWidth();
-
- if (my + screen->getWorkspacemenu()->getHeight() >
- screen->size().h())
- my = screen->size().h() -
- screen->getWorkspacemenu()->getHeight() -
- screen->getBorderWidth();
-
- screen->getWorkspacemenu()->move(mx, my);
-
- if (! screen->getWorkspacemenu()->isVisible()) {
- screen->getWorkspacemenu()->removeParent();
- screen->getWorkspacemenu()->show();
- }
- } else if (e->xbutton.button == 3) {
- int mx = e->xbutton.x_root -
- (screen->getRootmenu()->getWidth() / 2);
- int my = e->xbutton.y_root -
- (screen->getRootmenu()->getTitleHeight() / 2);
-
- if (mx < 0) mx = 0;
- if (my < 0) my = 0;
-
- if (mx + screen->getRootmenu()->getWidth() > screen->size().w())
- mx = screen->size().w() -
- screen->getRootmenu()->getWidth() -
- screen->getBorderWidth();
-
- if (my + screen->getRootmenu()->getHeight() > screen->size().h())
- my = screen->size().h() -
- screen->getRootmenu()->getHeight() -
- screen->getBorderWidth();
-
- screen->getRootmenu()->move(mx, my);
-
- if (! screen->getRootmenu()->isVisible()) {
- checkMenu();
- screen->getRootmenu()->show();
- }
- } else if (e->xbutton.button == 4) {
- if ((screen->getCurrentWorkspaceID() + 1) >
- screen->getWorkspaceCount() - 1)
- screen->changeWorkspaceID(0);
- else
- screen->changeWorkspaceID(screen->getCurrentWorkspaceID() + 1);
- } else if (e->xbutton.button == 5) {
- if ((screen->getCurrentWorkspaceID() - 1) < 0)
- screen->changeWorkspaceID(screen->getWorkspaceCount() - 1);
- else
- screen->changeWorkspaceID(screen->getCurrentWorkspaceID() - 1);
- }
- }
- }
- }
-
- break;
- }
-
- case ButtonRelease: {
- // strip the lock key modifiers
- e->xbutton.state &= ~(NumLockMask | ScrollLockMask | LockMask);
-
- last_time = e->xbutton.time;
-
- OpenboxWindow *win = (OpenboxWindow *) 0;
- Basemenu *menu = (Basemenu *) 0;
- Toolbar *tbar = (Toolbar *) 0;
-
- if ((win = searchWindow(e->xbutton.window)))
- win->buttonReleaseEvent(&e->xbutton);
- else if ((menu = searchMenu(e->xbutton.window)))
- menu->buttonReleaseEvent(&e->xbutton);
- else if ((tbar = searchToolbar(e->xbutton.window)))
- tbar->buttonReleaseEvent(&e->xbutton);
-
- break;
- }
-
- case ConfigureRequest: {
- OpenboxWindow *win = (OpenboxWindow *) 0;
-
-#ifdef SLIT
- Slit *slit = (Slit *) 0;
-#endif // SLIT
-
- if ((win = searchWindow(e->xconfigurerequest.window))) {
- win->configureRequestEvent(&e->xconfigurerequest);
-
-#ifdef SLIT
- } else if ((slit = searchSlit(e->xconfigurerequest.window))) {
- slit->configureRequestEvent(&e->xconfigurerequest);
-#endif // SLIT
-
- } else {
- grab();
-
- if (validateWindow(e->xconfigurerequest.window)) {
- XWindowChanges xwc;
-
- xwc.x = e->xconfigurerequest.x;
- xwc.y = e->xconfigurerequest.y;
- xwc.width = e->xconfigurerequest.width;
- xwc.height = e->xconfigurerequest.height;
- xwc.border_width = e->xconfigurerequest.border_width;
- xwc.sibling = e->xconfigurerequest.above;
- xwc.stack_mode = e->xconfigurerequest.detail;
-
- XConfigureWindow(getXDisplay(), e->xconfigurerequest.window,
- e->xconfigurerequest.value_mask, &xwc);
- }
-
- ungrab();
- }
-
- break;
- }
-
- case MapRequest: {
-#ifdef DEBUG
- fprintf(stderr,
- i18n(openboxSet, openboxMapRequest,
- "Openbox::process_event(): MapRequest for 0x%lx\n"),
- e->xmaprequest.window);
-#endif // DEBUG
-
- OpenboxWindow *win = searchWindow(e->xmaprequest.window);
-
- if (! win)
- win = new OpenboxWindow(*this, e->xmaprequest.window);
-
- if ((win = searchWindow(e->xmaprequest.window)))
- win->mapRequestEvent(&e->xmaprequest);
-
- break;
- }
-
- case MapNotify: {
- OpenboxWindow *win = searchWindow(e->xmap.window);
-
- if (win)
- win->mapNotifyEvent(&e->xmap);
-
- break;
- }
-
- case UnmapNotify: {
- OpenboxWindow *win = (OpenboxWindow *) 0;
-
-#ifdef SLIT
- Slit *slit = (Slit *) 0;
-#endif // SLIT
-
- if ((win = searchWindow(e->xunmap.window))) {
- win->unmapNotifyEvent(&e->xunmap);
-#ifdef SLIT
- } else if ((slit = searchSlit(e->xunmap.window))) {
- slit->removeClient(e->xunmap.window);
-#endif // SLIT
-
- }
-
- break;
- }
-
- case DestroyNotify: {
- OpenboxWindow *win = (OpenboxWindow *) 0;
-
-#ifdef SLIT
- Slit *slit = (Slit *) 0;
-#endif // SLIT
-
- if ((win = searchWindow(e->xdestroywindow.window))) {
- win->destroyNotifyEvent(&e->xdestroywindow);
-#ifdef SLIT
- } else if ((slit = searchSlit(e->xdestroywindow.window))) {
- slit->removeClient(e->xdestroywindow.window, False);
-#endif // SLIT
- }
-
- break;
- }
-
- case MotionNotify: {
- // strip the lock key modifiers
- e->xbutton.state &= ~(NumLockMask | ScrollLockMask | LockMask);
-
- last_time = e->xmotion.time;
-
- OpenboxWindow *win = (OpenboxWindow *) 0;
- Basemenu *menu = (Basemenu *) 0;
-
- if ((win = searchWindow(e->xmotion.window)))
- win->motionNotifyEvent(&e->xmotion);
- else if ((menu = searchMenu(e->xmotion.window)))
- menu->motionNotifyEvent(&e->xmotion);
-
- break;
- }
-
- case PropertyNotify: {
- last_time = e->xproperty.time;
-
- if (e->xproperty.state != PropertyDelete) {
- OpenboxWindow *win = searchWindow(e->xproperty.window);
-
- if (win)
- win->propertyNotifyEvent(e->xproperty.atom);
- }
-
- break;
- }
-
- case EnterNotify: {
- last_time = e->xcrossing.time;
-
- BScreen *screen = (BScreen *) 0;
- OpenboxWindow *win = (OpenboxWindow *) 0;
- Basemenu *menu = (Basemenu *) 0;
- Toolbar *tbar = (Toolbar *) 0;
-
-#ifdef SLIT
- Slit *slit = (Slit *) 0;
-#endif // SLIT
-
- if (e->xcrossing.mode == NotifyGrab) break;
-
- XEvent dummy;
- scanargs sa;
- sa.w = e->xcrossing.window;
- sa.enter = sa.leave = False;
- XCheckIfEvent(getXDisplay(), &dummy, queueScanner, (char *) &sa);
-
- if ((e->xcrossing.window == e->xcrossing.root) &&
- (screen = searchScreen(e->xcrossing.window))) {
- screen->getImageControl()->installRootColormap();
- } else if ((win = searchWindow(e->xcrossing.window))) {
- if (win->getScreen()->sloppyFocus() &&
- (! win->isFocused()) && (! no_focus)) {
- grab();
-
- if (((! sa.leave) || sa.inferior) && win->isVisible() &&
- win->setInputFocus())
- win->installColormap(True);
-
- ungrab();
- }
- } else if ((menu = searchMenu(e->xcrossing.window))) {
- menu->enterNotifyEvent(&e->xcrossing);
- } else if ((tbar = searchToolbar(e->xcrossing.window))) {
- tbar->enterNotifyEvent(&e->xcrossing);
-#ifdef SLIT
- } else if ((slit = searchSlit(e->xcrossing.window))) {
- slit->enterNotifyEvent(&e->xcrossing);
-#endif // SLIT
- }
- break;
- }
-
- case LeaveNotify: {
- last_time = e->xcrossing.time;
-
- OpenboxWindow *win = (OpenboxWindow *) 0;
- Basemenu *menu = (Basemenu *) 0;
- Toolbar *tbar = (Toolbar *) 0;
-
-#ifdef SLIT
- Slit *slit = (Slit *) 0;
-#endif // SLIT
-
- if ((menu = searchMenu(e->xcrossing.window)))
- menu->leaveNotifyEvent(&e->xcrossing);
- else if ((win = searchWindow(e->xcrossing.window)))
- win->installColormap(False);
- else if ((tbar = searchToolbar(e->xcrossing.window)))
- tbar->leaveNotifyEvent(&e->xcrossing);
-#ifdef SLIT
- else if ((slit = searchSlit(e->xcrossing.window)))
- slit->leaveNotifyEvent(&e->xcrossing);
-#endif // SLIT
-
- break;
- }
-
- case Expose: {
- OpenboxWindow *win = (OpenboxWindow *) 0;
- Basemenu *menu = (Basemenu *) 0;
- Toolbar *tbar = (Toolbar *) 0;
-
- if ((win = searchWindow(e->xexpose.window)))
- win->exposeEvent(&e->xexpose);
- else if ((menu = searchMenu(e->xexpose.window)))
- menu->exposeEvent(&e->xexpose);
- else if ((tbar = searchToolbar(e->xexpose.window)))
- tbar->exposeEvent(&e->xexpose);
-
- break;
- }
-
- case KeyPress: {
- Toolbar *tbar = searchToolbar(e->xkey.window);
-
- if (tbar && tbar->isEditing())
- tbar->keyPressEvent(&e->xkey);
-
- break;
- }
-
- case ColormapNotify: {
- BScreen *screen = searchScreen(e->xcolormap.window);
-
- if (screen)
- screen->setRootColormapInstalled((e->xcolormap.state ==
- ColormapInstalled) ? True : False);
-
- break;
- }
-
- case FocusIn: {
- if (e->xfocus.mode == NotifyUngrab || e->xfocus.detail == NotifyPointer)
- break;
-
- OpenboxWindow *win = searchWindow(e->xfocus.window);
- if (win && !win->isFocused())
- focusWindow(win);
-
- break;
- }
-
- case FocusOut:
- break;
-
- case ClientMessage: {
- if (e->xclient.format == 32) {
- if (e->xclient.message_type == getWMChangeStateAtom()) {
- OpenboxWindow *win = searchWindow(e->xclient.window);
- if (! win || ! win->validateClient()) return;
-
- if (e->xclient.data.l[0] == IconicState)
- win->iconify();
- if (e->xclient.data.l[0] == NormalState)
- win->deiconify();
- } else if (e->xclient.message_type == getOpenboxChangeWorkspaceAtom()) {
- BScreen *screen = searchScreen(e->xclient.window);
-
- if (screen && e->xclient.data.l[0] >= 0 &&
- e->xclient.data.l[0] < screen->getWorkspaceCount())
- screen->changeWorkspaceID(e->xclient.data.l[0]);
- } else if (e->xclient.message_type == getOpenboxChangeWindowFocusAtom()) {
- OpenboxWindow *win = searchWindow(e->xclient.window);
-
- if (win && win->isVisible() && win->setInputFocus())
- win->installColormap(True);
- } else if (e->xclient.message_type == getOpenboxCycleWindowFocusAtom()) {
- BScreen *screen = searchScreen(e->xclient.window);
-
- if (screen) {
- if (! e->xclient.data.l[0])
- screen->prevFocus();
- else
- screen->nextFocus();
- }
- } else if (e->xclient.message_type == getOpenboxChangeAttributesAtom()) {
- OpenboxWindow *win = searchWindow(e->xclient.window);
-
- if (win && win->validateClient()) {
- OpenboxHints net;
- net.flags = e->xclient.data.l[0];
- net.attrib = e->xclient.data.l[1];
- net.workspace = e->xclient.data.l[2];
- net.stack = e->xclient.data.l[3];
- net.decoration = e->xclient.data.l[4];
-
- win->changeOpenboxHints(&net);
- }
- }
- }
-
- break;
- }
-
-
- default: {
-#ifdef SHAPE
- if (e->type == getShapeEventBase()) {
- XShapeEvent *shape_event = (XShapeEvent *) e;
- OpenboxWindow *win = (OpenboxWindow *) 0;
-
- if ((win = searchWindow(e->xany.window)) ||
- (shape_event->kind != ShapeBounding))
- win->shapeEvent(shape_event);
- }
-#endif // SHAPE
-
- }
- } // switch
-}
-
-
-Bool Openbox::handleSignal(int sig) {
- switch (sig) {
- case SIGHUP:
- case SIGUSR1:
- reconfigure();
- break;
-
- case SIGUSR2:
- rereadMenu();
- break;
-
- case SIGPIPE:
- case SIGSEGV:
- case SIGFPE:
- case SIGINT:
- case SIGTERM:
- shutdown();
-
- default:
- return False;
- }
-
- return True;
-}
-
-
-BScreen *Openbox::searchScreen(Window window) {
- ScreenList::iterator it;
- for (it = screenList.begin(); it != screenList.end(); ++it)
- if ((*it)->getRootWindow() == window)
- return *it;
- return (BScreen *) 0;
-}
-
-
-OpenboxWindow *Openbox::searchWindow(Window window) {
- WindowLookup::iterator it = windowSearchList.find(window);
- if (it == windowSearchList.end())
- return (OpenboxWindow *) 0;
- return it->second;
-}
-
-
-OpenboxWindow *Openbox::searchGroup(Window window, OpenboxWindow *win) {
- WindowLookup::iterator it = groupSearchList.find(window);
- if (it != groupSearchList.end())
- if (it->second->getClientWindow() != win->getClientWindow())
- return win;
- return (OpenboxWindow *) 0;
-}
-
-
-Basemenu *Openbox::searchMenu(Window window) {
- MenuLookup::iterator it = menuSearchList.find(window);
- if (it == menuSearchList.end())
- return (Basemenu *) 0;
- return it->second;
-}
-
-
-Toolbar *Openbox::searchToolbar(Window window) {
- ToolbarLookup::iterator it = toolbarSearchList.find(window);
- if (it == toolbarSearchList.end())
- return (Toolbar *) 0;
- return it->second;
-}
-
-
-#ifdef SLIT
-Slit *Openbox::searchSlit(Window window) {
- SlitLookup::iterator it = slitSearchList.find(window);
- if (it == slitSearchList.end())
- return (Slit *) 0;
- return it->second;
-}
-#endif // SLIT
-
-
-void Openbox::saveWindowSearch(Window window, OpenboxWindow *data) {
- windowSearchList.insert(WindowLookupPair(window, data));
-}
-
-
-void Openbox::saveGroupSearch(Window window, OpenboxWindow *data) {
- groupSearchList.insert(WindowLookupPair(window, data));
-}
-
-
-void Openbox::saveMenuSearch(Window window, Basemenu *data) {
- menuSearchList.insert(MenuLookupPair(window, data));
-}
-
-
-void Openbox::saveToolbarSearch(Window window, Toolbar *data) {
- toolbarSearchList.insert(ToolbarLookupPair(window, data));
-}
-
-
-#ifdef SLIT
-void Openbox::saveSlitSearch(Window window, Slit *data) {
- slitSearchList.insert(SlitLookupPair(window, data));
-}
-#endif // SLIT
-
-
-void Openbox::removeWindowSearch(Window window) {
- windowSearchList.erase(window);
-}
-
-
-void Openbox::removeGroupSearch(Window window) {
- groupSearchList.erase(window);
-}
-
-
-void Openbox::removeMenuSearch(Window window) {
- menuSearchList.erase(window);
-}
-
-
-void Openbox::removeToolbarSearch(Window window) {
- toolbarSearchList.erase(window);
-}
-
-
-#ifdef SLIT
-void Openbox::removeSlitSearch(Window window) {
- slitSearchList.erase(window);
-}
-#endif // SLIT
-
-
-void Openbox::restart(const char *prog) {
- shutdown();
-
- if (prog) {
- execlp(prog, prog, NULL);
- perror(prog);
- }
-
- // fall back in case the above execlp doesn't work
- execvp(argv[0], argv);
- execvp(basename(argv[0]), argv);
-}
-
-
-void Openbox::shutdown() {
- BaseDisplay::shutdown();
-
- std::for_each(screenList.begin(), screenList.end(),
- std::mem_fun(&BScreen::shutdown));
-
- focusWindow(0);
-
- XSync(getXDisplay(), False);
-}
-
-
-void Openbox::save() {
- config.setAutoSave(false);
-
- // save all values as they are so that the defaults will be written to the rc
- // file
-
- config.setValue("session.colorsPerChannel",
- resource.colors_per_channel);
- config.setValue("session.styleFile", resource.style_file);
- config.setValue("session.titlebarLayout", resource.titlebar_layout);
- config.setValue("session.doubleClickInterval",
- (long)resource.double_click_interval);
- config.setValue("session.autoRaiseDelay",
- ((resource.auto_raise_delay.tv_sec * 1000) +
- (resource.auto_raise_delay.tv_usec / 1000)));
- config.setValue("session.cacheLife", (long)resource.cache_life / 60000);
- config.setValue("session.cacheMax", (long)resource.cache_max);
-
- std::for_each(screenList.begin(), screenList.end(),
- std::mem_fun(&BScreen::save));
-
- config.setAutoSave(true);
- config.save();
-}
-
-void Openbox::load() {
- if (!config.load())
- config.create();
-
- std::string s;
- long l;
-
- if (config.getValue("session.colorsPerChannel", "Session.ColorsPerChannel",
- l))
- resource.colors_per_channel = (l < 2 ? 2 : (l > 6 ? 6 : l)); // >= 2, <= 6
- else
- resource.colors_per_channel = 4;
-
- if (resource.style_file)
- delete [] resource.style_file;
- if (config.getValue("session.styleFile", "Session.StyleFile", s))
- resource.style_file = bstrdup(s.c_str());
- else
- resource.style_file = bstrdup(DEFAULTSTYLE);
-
- if (resource.titlebar_layout)
- delete [] resource.titlebar_layout;
- if (config.getValue("session.titlebarLayout", "Session.TitlebarLayout", s))
- resource.titlebar_layout = bstrdup(s.c_str());
- else
- resource.titlebar_layout = bstrdup("ILMC");
-
- if (config.getValue("session.doubleClickInterval",
- "Session.DoubleClickInterval", l))
- resource.double_click_interval = l;
- else
- resource.double_click_interval = 250;
-
- if (config.getValue("session.autoRaiseDelay", "Session.AutoRaiseDelay", l))
- resource.auto_raise_delay.tv_usec = l;
- else
- resource.auto_raise_delay.tv_usec = 400;
- resource.auto_raise_delay.tv_sec = resource.auto_raise_delay.tv_usec / 1000;
- resource.auto_raise_delay.tv_usec -=
- (resource.auto_raise_delay.tv_sec * 1000);
- resource.auto_raise_delay.tv_usec *= 1000;
-
- if (config.getValue("session.cacheLife", "Session.CacheLife", l))
- resource.cache_life = l;
- else
- resource.cache_life = 51;
- resource.cache_life *= 60000;
-
- if (config.getValue("session.cacheMax", "Session.CacheMax", l))
- resource.cache_max = l;
- else
- resource.cache_max = 200;
-}
-
-
-void Openbox::reconfigure() {
- reconfigure_wait = True;
-
- if (! timer->isTiming()) timer->start();
-}
-
-
-void Openbox::real_reconfigure() {
- grab();
-
- load();
-
- for_each(menuTimestamps.begin(), menuTimestamps.end(),
- PointerAssassin());
- menuTimestamps.clear();
-
- std::for_each(screenList.begin(), screenList.end(),
- std::mem_fun(&BScreen::reconfigure));
-
- ungrab();
-}
-
-
-void Openbox::checkMenu() {
- MenuTimestampList::iterator it;
- for (it = menuTimestamps.begin(); it != menuTimestamps.end(); ++it) {
- struct stat buf;
-
- if (stat((*it)->filename, &buf) || (*it)->timestamp != buf.st_ctime) {
- rereadMenu();
- return;
- }
- }
-}
-
-
-void Openbox::addMenuTimestamp(const char *filename) {
- bool found = false;
-
- MenuTimestampList::iterator it;
- for (it = menuTimestamps.begin(); it != menuTimestamps.end(); ++it)
- if (! strcmp((*it)->filename, filename)) {
- found = true;
- break;
- }
- if (!found) {
- struct stat buf;
-
- if (! stat(filename, &buf)) {
- MenuTimestamp *ts = new MenuTimestamp;
-
- ts->filename = bstrdup(filename);
- ts->timestamp = buf.st_ctime;
-
- menuTimestamps.push_back(ts);
- }
- }
-}
-
-void Openbox::rereadMenu() {
- reread_menu_wait = True;
-
- if (! timer->isTiming()) timer->start();
-}
-
-
-void Openbox::real_rereadMenu() {
- std::for_each(menuTimestamps.begin(), menuTimestamps.end(),
- PointerAssassin());
- menuTimestamps.clear();
-
- std::for_each(screenList.begin(), screenList.end(),
- std::mem_fun(&BScreen::rereadMenu));
-}
-
-
-void Openbox::setStyleFilename(const char *filename) {
- if (resource.style_file)
- delete [] resource.style_file;
-
- resource.style_file = bstrdup(filename);
- config.setValue("session.styleFile", resource.style_file);
-}
-
-
-void Openbox::timeout() {
- if (reconfigure_wait)
- real_reconfigure();
-
- if (reread_menu_wait)
- real_rereadMenu();
-
- reconfigure_wait = reread_menu_wait = False;
-}
-
-
-OpenboxWindow *Openbox::focusedWindow() {
- Workspace *w;
- if (current_screen)
- if ((w = current_screen->getCurrentWorkspace()))
- return w->focusedWindow();
- return (OpenboxWindow *) 0;
-}
-
-
-void Openbox::focusWindow(OpenboxWindow *win) {
- BScreen *old_screen = (BScreen *) 0;
- Toolbar *old_tbar = (Toolbar *) 0, *tbar = (Toolbar *) 0;
- Workspace *old_wkspc = (Workspace *) 0, *wkspc = (Workspace *) 0;
-
- OpenboxWindow *old_win = focusedWindow();
- if (old_win != (OpenboxWindow *) 0) {
- old_screen = old_win->getScreen();
- old_wkspc = old_screen->getWorkspace(old_win->getWorkspaceNumber());
- old_tbar = old_screen->getToolbar();
-
- old_win->setFocusFlag(false);
- old_wkspc->focusWindow((OpenboxWindow *) 0);
- }
-
- if (win && !win->isIconic()) {
- current_screen = win->getScreen();
- tbar = current_screen->getToolbar();
- if (win->isStuck())
- wkspc = current_screen->getCurrentWorkspace();
- else
- wkspc = current_screen->getWorkspace(win->getWorkspaceNumber());
- win->setFocusFlag(true);
- wkspc->focusWindow(win);
-
- if (tbar)
- tbar->redrawWindowLabel(true);
- current_screen->updateNetizenWindowFocus();
- } else {
- XSetInputFocus(getXDisplay(), PointerRoot, None, CurrentTime);
- }
-
- if (old_tbar && old_tbar != tbar)
- old_tbar->redrawWindowLabel(true);
- if (old_screen && old_screen != current_screen)
- old_screen->updateNetizenWindowFocus();
-}
+++ /dev/null
-// openbox.h for Openbox
-// Copyright (c) 2001 Sean 'Shaleh' Perry <shaleh@debian.org>
-// Copyright (c) 1997 - 2000 Brad Hughes (bhughes@tcac.net)
-//
-// Permission is hereby granted, free of charge, to any person obtaining a
-// copy of this software and associated documentation files (the "Software"),
-// to deal in the Software without restriction, including without limitation
-// the rights to use, copy, modify, merge, publish, distribute, sublicense,
-// and/or sell copies of the Software, and to permit persons to whom the
-// Software is furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-// DEALINGS IN THE SOFTWARE.
-
-#ifndef __openbox_hh
-#define __openbox_hh
-
-#include <X11/Xlib.h>
-#include <X11/Xresource.h>
-
-#ifdef HAVE_STDIO_H
-# include <stdio.h>
-#endif // HAVE_STDIO_H
-
-#ifdef TIME_WITH_SYS_TIME
-# include <sys/time.h>
-# include <time.h>
-#else // !TIME_WITH_SYS_TIME
-# ifdef HAVE_SYS_TIME_H
-# include <sys/time.h>
-# else // !HAVE_SYS_TIME_H
-# include <time.h>
-# endif // HAVE_SYS_TIME_H
-#endif // TIME_WITH_SYS_TIME
-
-#include "Resource.h"
-#include "BaseDisplay.h"
-#include "Timer.h"
-
-#include <map>
-#include <list>
-#include <vector>
-
-//forward declaration
-class BScreen;
-class Openbox;
-class BImageControl;
-class OpenboxWindow;
-class Basemenu;
-class Toolbar;
-#ifdef SLIT
-class Slit;
-#endif // SLIT
-
-template <class Z>
-class DataSearch {
-private:
- Window window;
- Z *data;
-
-public:
- DataSearch(Window w, Z *d): window(w), data(d) {}
-
- inline const Window &getWindow() const { return window; }
- inline Z *getData() { return data; }
-};
-
-
-class Openbox : public BaseDisplay, public TimeoutHandler {
-private:
- typedef struct MenuTimestamp {
- virtual ~MenuTimestamp() {
- if (filename != (char *) 0)
- delete [] filename;
- }
- char *filename;
- time_t timestamp;
- } MenuTimestamp;
-
- struct resource {
- Time double_click_interval;
-
- char *style_file;
- char *titlebar_layout;
- int colors_per_channel;
- timeval auto_raise_delay;
- unsigned long cache_life, cache_max;
- } resource;
-
- typedef std::map<Window, OpenboxWindow*> WindowLookup;
- typedef WindowLookup::value_type WindowLookupPair;
- WindowLookup windowSearchList, groupSearchList;
-
- typedef std::map<Window, Basemenu*> MenuLookup;
- typedef MenuLookup::value_type MenuLookupPair;
- MenuLookup menuSearchList;
-
- typedef std::map<Window, Toolbar*> ToolbarLookup;
- typedef ToolbarLookup::value_type ToolbarLookupPair;
- ToolbarLookup toolbarSearchList;
-
-#ifdef SLIT
- typedef std::map<Window, Slit*> SlitLookup;
- typedef SlitLookup::value_type SlitLookupPair;
- SlitLookup slitSearchList;
-#endif // SLIT
-
- typedef std::list<MenuTimestamp*> MenuTimestampList;
- MenuTimestampList menuTimestamps;
-
- typedef std::vector<BScreen*> ScreenList;
- ScreenList screenList;
-
- BScreen *current_screen;
- OpenboxWindow *masked_window;
- BTimer *timer;
-
-#ifdef HAVE_GETPID
- Atom openbox_pid;
-#endif // HAVE_GETPID
-
- Bool no_focus, reconfigure_wait, reread_menu_wait;
- Time last_time;
- Window masked;
- char *menu_file, *rc_file, **argv;
- int argc;
- Resource config;
-
-
-protected:
- void load();
- void save();
- void real_rereadMenu();
- void real_reconfigure();
-
- virtual void process_event(XEvent *);
-
-
-public:
- Openbox(int, char **, char * = 0, char * = 0, char * = 0);
- virtual ~Openbox();
-
-#ifdef HAVE_GETPID
- inline const Atom &getOpenboxPidAtom() const { return openbox_pid; }
-#endif // HAVE_GETPID
-
- Basemenu *searchMenu(Window);
-
- OpenboxWindow *searchGroup(Window, OpenboxWindow *);
- OpenboxWindow *searchWindow(Window);
- OpenboxWindow *focusedWindow();
- void focusWindow(OpenboxWindow *w);
-
- inline BScreen *getScreen(unsigned int s) {
- ASSERT(s < screenList.size());
- return screenList[s];
- }
- BScreen *searchScreen(Window);
- inline unsigned int managedScreenCount() const {
- return screenList.size();
- }
-
- inline Resource &getConfig() {
- return config;
- }
- inline const Time &getDoubleClickInterval() const
- { return resource.double_click_interval; }
- inline const Time &getLastTime() const { return last_time; }
-
- Toolbar *searchToolbar(Window);
-
- inline const char *getStyleFilename() const
- { return resource.style_file; }
- inline const char *getMenuFilename() const
- { return menu_file; }
- void addMenuTimestamp(const char *filename);
-
- inline const int &getColorsPerChannel() const
- { return resource.colors_per_channel; }
-
- inline const timeval &getAutoRaiseDelay() const
- { return resource.auto_raise_delay; }
-
- inline const char *getTitleBarLayout() const
- { return resource.titlebar_layout; }
-
- inline const unsigned long &getCacheLife() const
- { return resource.cache_life; }
- inline const unsigned long &getCacheMax() const
- { return resource.cache_max; }
-
- inline OpenboxWindow *getMaskedWindow() const
- { return masked_window; }
- inline void maskWindowEvents(Window w, OpenboxWindow *bw)
- { masked = w; masked_window = bw; }
- inline void setNoFocus(Bool f) { no_focus = f; }
-
- void shutdown();
- void setStyleFilename(const char *);
- void saveMenuSearch(Window, Basemenu *);
- void saveWindowSearch(Window, OpenboxWindow *);
- void saveToolbarSearch(Window, Toolbar *);
- void saveGroupSearch(Window, OpenboxWindow *);
- void removeMenuSearch(Window);
- void removeWindowSearch(Window);
- void removeToolbarSearch(Window);
- void removeGroupSearch(Window);
- void restart(const char * = 0);
- void reconfigure();
- void rereadMenu();
- void checkMenu();
-
- virtual Bool handleSignal(int);
-
- virtual void timeout();
-
-#ifdef SLIT
- Slit *searchSlit(Window);
-
- void saveSlitSearch(Window, Slit *);
- void removeSlitSearch(Window);
-#endif // SLIT
-
-#ifndef HAVE_STRFTIME
-
- enum { B_AmericanDate = 1, B_EuropeanDate };
-#endif // HAVE_STRFTIME
-};
-
-
-#endif // __openbox_hh