add back some xinerama support (toolbar, slit (+menu), screen)

This commit is contained in:
rathnor 2003-05-19 14:26:30 +00:00
parent 68e9677bbb
commit cc9c7960c1
7 changed files with 336 additions and 22 deletions

View file

@ -1,6 +1,8 @@
(Format: Year/Month/Day)
Changes for 0.9.3:
*03/05/19:
* Add back some Xinerama support (still need placement + maximise) (Simon)
Screen.hh/cc Toolbar.cc Slit.cc Xinerama.hh
* Fix bsetroot segfault (Simon)
FbWindow.cc
*03/05/18:

View file

@ -117,7 +117,7 @@ Bugfixes/lower priority:
Release: 0.9.3
Approx Date: 26 May, 2003
Major Features:
- Xinerama (Simon)
= Xinerama (Simon)
* XRandr (Henrik)
Minor Features:
- Add some sort of program launch function (Simon)

View file

@ -22,7 +22,7 @@
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
// $Id: Screen.cc,v 1.171 2003/05/18 22:01:14 fluxgen Exp $
// $Id: Screen.cc,v 1.172 2003/05/19 14:26:29 rathnor Exp $
#include "Screen.hh"
@ -114,6 +114,12 @@
#include <X11/Xatom.h>
#include <X11/keysym.h>
#ifdef XINERAMA
extern "C" {
#include <X11/extensions/Xinerama.h>
}
#endif // XINERAMA
#include <iostream>
#include <memory>
#include <algorithm>
@ -480,13 +486,14 @@ BScreen::ScreenResource::ScreenResource(FbTk::ResourceManager &rm,
toolbar_on_head(rm, 0, scrname+".toolbar.onhead", altscrname+".Toolbar.onHead"),
toolbar_placement(rm, Toolbar::BOTTOMCENTER,
scrname+".toolbar.placement", altscrname+".Toolbar.Placement"),
slit_auto_hide(rm, false,
scrname+".slit.autoHide", altscrname+".Slit.AutoHide"),
slit_placement(rm, Slit::BOTTOMRIGHT,
scrname+".slit.placement", altscrname+".Slit.Placement"),
slit_direction(rm, Slit::VERTICAL,
scrname+".slit.direction", altscrname+".Slit.Direction"),
slit_alpha(rm, 255, scrname+".slit.alpha", altscrname+".Slit.Alpha") {
slit_auto_hide(rm, false,
scrname+".slit.autoHide", altscrname+".Slit.AutoHide"),
slit_placement(rm, Slit::BOTTOMRIGHT,
scrname+".slit.placement", altscrname+".Slit.Placement"),
slit_direction(rm, Slit::VERTICAL,
scrname+".slit.direction", altscrname+".Slit.Direction"),
slit_alpha(rm, 255, scrname+".slit.alpha", altscrname+".Slit.Alpha"),
slit_on_head(rm, 0, scrname+".slit.onhead", altscrname+".Slit.onHead") {
};
@ -516,6 +523,10 @@ BScreen::BScreen(FbTk::ResourceManager &rm,
Display *disp = FbTk::App::instance()->display();
#ifdef XINERAMA
initXinerama(disp);
#endif // XINERAMA
event_mask = ColormapChangeMask | EnterWindowMask | PropertyChangeMask |
SubstructureRedirectMask | KeyPressMask | KeyReleaseMask |
ButtonPressMask | ButtonReleaseMask| SubstructureNotifyMask;
@ -761,6 +772,12 @@ BScreen::~BScreen() {
}
netizenList.clear();
#ifdef XINERAMA
if (hasXinerama() && m_xinerama_headinfo) {
delete [] m_xinerama_headinfo;
}
#endif // XINERAMA
}
const FbTk::Menu &BScreen::toolbarModemenu() const {
@ -2524,3 +2541,102 @@ void BScreen::updateSize() {
//!! TODO: should we re-maximize the maximized windows?
}
#ifdef XINERAMA
void BScreen::initXinerama(Display *display) {
if (!XineramaIsActive(display)) {
m_xinerama_avail = false;
m_xinerama_headinfo = 0;
return;
}
m_xinerama_avail = true;
XineramaScreenInfo *screen_info;
int number;
screen_info = XineramaQueryScreens(display, &number);
m_xinerama_headinfo = new XineramaHeadInfo[number];
m_xinerama_num_heads = number;
for (int i=0; i < number; i++) {
m_xinerama_headinfo[i].x = screen_info[i].x_org;
m_xinerama_headinfo[i].y = screen_info[i].y_org;
m_xinerama_headinfo[i].width = screen_info[i].width;
m_xinerama_headinfo[i].height = screen_info[i].height;
}
}
int BScreen::getHead(int x, int y) const {
if (!hasXinerama()) return 0;
for (int i=0; i < m_xinerama_num_heads; i++) {
if (x >= m_xinerama_headinfo[i].x &&
x < (m_xinerama_headinfo[i].x + m_xinerama_headinfo[i].width) &&
y >= m_xinerama_headinfo[i].y &&
y < (m_xinerama_headinfo[i].y + m_xinerama_headinfo[i].height)) {
return i+1;
}
}
return 0;
}
int BScreen::getCurrHead() const {
if (!hasXinerama()) return 0;
int root_x, root_y, ignore_i;
unsigned int ignore_ui;
Window ignore_w;
XQueryPointer(FbTk::App::instance()->display(),
rootWindow().window(), &ignore_w,
&ignore_w, &root_x, &root_y,
&ignore_i, &ignore_i, &ignore_ui);
return getHead(root_x, root_y);
}
int BScreen::getHeadX(int head) const {
if (head == 0 || head > m_xinerama_num_heads) return 0;
return m_xinerama_headinfo[head-1].x;
}
int BScreen::getHeadY(int head) const {
if (head == 0 || head > m_xinerama_num_heads) return 0;
return m_xinerama_headinfo[head-1].y;
}
int BScreen::getHeadWidth(int head) const {
if (head == 0 || head > m_xinerama_num_heads) return width();
return m_xinerama_headinfo[head-1].width;
}
int BScreen::getHeadHeight(int head) const {
if (head == 0 || head > m_xinerama_num_heads) return height();
return m_xinerama_headinfo[head-1].height;
}
template <>
int BScreen::getOnHead<Toolbar>(Toolbar &tbar) {
return getToolbarOnHead();
}
template <>
void BScreen::setOnHead<Toolbar>(Toolbar &tbar, int head) {
saveToolbarOnHead(head);
tbar.reconfigure();
}
template <>
int BScreen::getOnHead<Slit>(Slit &tbar) {
return getSlitOnHead();
}
template <>
void BScreen::setOnHead<Slit>(Slit &slit, int head) {
saveSlitOnHead(head);
slit.reconfigure();
}
#endif // XINERAMA

View file

@ -22,7 +22,7 @@
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
// $Id: Screen.hh,v 1.99 2003/05/18 22:00:04 fluxgen Exp $
// $Id: Screen.hh,v 1.100 2003/05/19 14:26:30 rathnor Exp $
#ifndef SCREEN_HH
#define SCREEN_HH
@ -116,8 +116,8 @@ public:
inline void saveSlitDirection(Slit::Direction d) { resource.slit_direction = d; }
inline void saveSlitAutoHide(bool t) { resource.slit_auto_hide = t; }
inline unsigned int getSlitOnHead() const { return resource.slit_on_head; }
inline void saveSlitOnHead(unsigned int h) { resource.slit_on_head = h; }
inline int getSlitOnHead() const { return *resource.slit_on_head; }
inline void saveSlitOnHead(int h) { *resource.slit_on_head = h; }
inline const Toolbar *toolbar() const { return m_toolbarhandler->getToolbar(); }
inline Toolbar *toolbar() { return m_toolbarhandler->getToolbar(); }
@ -296,6 +296,29 @@ public:
/// (and maximized windows?)
void updateSize();
#ifdef XINERAMA
// Xinerama-related functions
inline bool hasXinerama() const { return m_xinerama_avail; }
inline int numHeads() const { return m_xinerama_num_heads; }
void initXinerama(Display *display);
int getHead(int x, int y) const;
int getCurrHead() const;
int getHeadX(int head) const;
int getHeadY(int head) const;
int getHeadWidth(int head) const;
int getHeadHeight(int head) const;
// magic to allow us to have "on head" placement without
// the object really knowing about it.
template <typename OnHeadObject>
int getOnHead(OnHeadObject &obj);
template <typename OnHeadObject>
void setOnHead(OnHeadObject &obj, int head);
#endif // XINERAMA
// notify netizens
void updateNetizenCurrentWorkspace();
void updateNetizenWorkspaceCount();
@ -412,9 +435,7 @@ private:
FbTk::Resource<bool> slit_auto_hide;
FbTk::Resource<Slit::Placement> slit_placement;
FbTk::Resource<Slit::Direction> slit_direction;
FbTk::Resource<int> slit_alpha;
unsigned int slit_on_head;
FbTk::Resource<int> slit_alpha, slit_on_head;
std::string strftime_format;
@ -425,6 +446,21 @@ private:
} resource;
std::auto_ptr<ToolbarHandler> m_toolbarhandler;
#ifdef XINERAMA
// Xinerama related private data
bool m_xinerama_avail;
int m_xinerama_num_heads;
int m_xinerama_center_x, m_xinerama_center_y;
struct XineramaHeadInfo {
int x, y, width, height;
} *m_xinerama_headinfo;
#endif
};

View file

@ -22,7 +22,7 @@
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
// $Id: Slit.cc,v 1.55 2003/05/17 11:00:50 fluxgen Exp $
// $Id: Slit.cc,v 1.56 2003/05/19 14:26:30 rathnor Exp $
#include "Slit.hh"
@ -52,6 +52,10 @@
#include "Transparent.hh"
#include "IntResMenuItem.hh"
#ifdef XINERAMA
#include "Xinerama.hh"
#endif // XINERAMA
#include <algorithm>
#include <iostream>
#include <cassert>
@ -790,8 +794,20 @@ void Slit::reposition() {
head_w,
head_h;
head_w = screen().width();
head_h = screen().height();
#ifdef XINERAMA
if (screen().hasXinerama()) {
int head = screen().getSlitOnHead();
head_x = screen().getHeadX(head);
head_y = screen().getHeadY(head);
head_w = screen().getHeadWidth(head);
head_h = screen().getHeadHeight(head);
} else
#endif // XINERAMA
{
head_w = screen().width();
head_h = screen().height();
}
int border_width = screen().rootTheme().borderWidth();
int bevel_width = screen().rootTheme().bevelWidth();
@ -1206,6 +1222,18 @@ void Slit::setupMenu() {
m_slitmenu.insert("Layer...", m_layermenu.get());
#ifdef XINERAMA
if (screen().hasXinerama()) {
m_slitmenu.insert("On Head...", new XineramaHeadMenu<Slit>(
*screen().menuTheme(),
screen(),
screen().imageControl(),
*screen().layerManager().getLayer(Fluxbox::instance()->getMenuLayer()),
this
));
}
#endif //XINERAMA
m_slitmenu.insert(new BoolMenuItem(i18n->getMessage(
CommonSet, CommonAutoHide,
"Auto hide"),

View file

@ -22,7 +22,7 @@
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
// $Id: Toolbar.cc,v 1.84 2003/05/17 11:30:59 fluxgen Exp $
// $Id: Toolbar.cc,v 1.85 2003/05/19 14:26:30 rathnor Exp $
#include "Toolbar.hh"
@ -43,6 +43,10 @@
#include "BoolMenuItem.hh"
#include "FbWinFrameTheme.hh"
#ifdef XINERAMA
#include "Xinerama.hh"
#endif XINERAMA
// use GNU extensions
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
@ -134,6 +138,18 @@ void setupMenus(Toolbar &tbar) {
menu.setInternalMenu();
menu.insert("Layer...", &tbar.layermenu());
#ifdef XINERAMA
if (tbar.screen().hasXinerama()) {
menu.insert("On Head...", new XineramaHeadMenu<Toolbar>(
*tbar.screen().menuTheme(),
tbar.screen(),
tbar.screen().imageControl(),
*tbar.screen().layerManager().getLayer(Fluxbox::instance()->getMenuLayer()),
&tbar
));
}
#endif //XINERAMA
// setup items in placement menu
struct {
@ -1091,10 +1107,21 @@ void Toolbar::setPlacement(Toolbar::Placement where) {
head_w,
head_h;
m_place = where;
#ifdef XINERAMA
if (screen().hasXinerama()) {
int head = screen().getToolbarOnHead();
head_x = screen().getHeadX(head);
head_y = screen().getHeadY(head);
head_w = screen().getHeadWidth(head);
head_h = screen().getHeadHeight(head);
} else
#endif // XINERAMA
{
head_w = screen().width();
head_h = screen().height();
}
head_w = screen().width();
head_h = screen().height();
m_place = where;
frame.width = head_w * screen().getToolbarWidthPercent() / 100;
frame.height = m_theme.font().height();

105
src/Xinerama.hh Normal file
View file

@ -0,0 +1,105 @@
// Xinerama.hh for Fluxbox - helpful tools for multiple heads
// Copyright (c) 2003 Henrik Kinnunen (fluxgen at users.sourceforge.net)
// and Simon Bowden (rathnor at users.sourceforge.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.
// $Id: Xinerama.hh,v 1.1 2003/05/19 14:26:30 rathnor Exp $
#ifndef XINERAMA_HH
#define XINERAMA_HH
#include "MenuItem.hh"
#include "FbMenu.hh"
#include "FbCommands.hh"
#include "RefCount.hh"
#include "SimpleCommand.hh"
#include "fluxbox.hh"
// provides a generic way for giving an object a xinerama head menu
// The object must have two functions:
// int getOnHead(), and
// void setOnHead(int)
/// this class holds the xinerama items
template <typename ItemType>
class XineramaHeadMenuItem : public FbTk::MenuItem {
public:
XineramaHeadMenuItem(const char *label, ItemType *object, int headnum,
FbTk::RefCount<FbTk::Command> &cmd):
FbTk::MenuItem(label,cmd), m_object(object), m_headnum(headnum) {}
XineramaHeadMenuItem(const char *label, ItemType *object, int headnum):
FbTk::MenuItem(label), m_object(object), m_headnum(headnum) {}
bool isEnabled() const { return m_object->screen().getOnHead(*m_object) != m_headnum; } ;
void click(int button, int time) {
m_object->screen().setOnHead(*m_object, m_headnum);
FbTk::MenuItem::click(button, time);
}
private:
ItemType *m_object;
int m_headnum;
};
/// Create a xinerama menu
template <typename ItemType>
class XineramaHeadMenu : public FbMenu {
public:
XineramaHeadMenu(FbTk::MenuTheme &tm, BScreen &screen, FbTk::ImageControl &imgctrl,
FbTk::XLayer &layer, ItemType *item);
private:
ItemType *m_object;
};
template <typename ItemType>
XineramaHeadMenu<ItemType>::XineramaHeadMenu(FbTk::MenuTheme &tm, BScreen &screen, FbTk::ImageControl &imgctrl,
FbTk::XLayer &layer, ItemType *item):
FbMenu(tm, screen.screenNumber(), imgctrl, layer),
m_object(item)
{
FbTk::RefCount<FbTk::Command> saverc_cmd(new FbTk::SimpleCommand<Fluxbox>(
*Fluxbox::instance(),
&Fluxbox::save_rc));
char tname[128];
for (int i=1; i <= screen.numHeads(); ++i) {
// TODO: nls
/*
sprintf(tname, I18n::instance()->
getMessage(
FBNLS::ScreenSet,
FBNLS::XineramaDefaultHeadFormat,
"Head %d"), i); //m_id starts at 0
*/
sprintf(tname, "Head %d", i);
insert(new XineramaHeadMenuItem<ItemType>(
tname, m_object, i, saverc_cmd));
}
// TODO: nls
insert(new XineramaHeadMenuItem<ItemType>(
"All Heads", m_object, 0, saverc_cmd));
update();
}
#endif // XINERAMA_HH