aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Screen.cc132
-rw-r--r--src/Screen.hh48
-rw-r--r--src/Slit.cc34
-rw-r--r--src/Toolbar.cc35
-rw-r--r--src/Xinerama.hh105
5 files changed, 333 insertions, 21 deletions
diff --git a/src/Screen.cc b/src/Screen.cc
index d3eb39e..aaa2209 100644
--- a/src/Screen.cc
+++ b/src/Screen.cc
@@ -22,7 +22,7 @@
22// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 22// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23// DEALINGS IN THE SOFTWARE. 23// DEALINGS IN THE SOFTWARE.
24 24
25// $Id: Screen.cc,v 1.171 2003/05/18 22:01:14 fluxgen Exp $ 25// $Id: Screen.cc,v 1.172 2003/05/19 14:26:29 rathnor Exp $
26 26
27 27
28#include "Screen.hh" 28#include "Screen.hh"
@@ -114,6 +114,12 @@
114#include <X11/Xatom.h> 114#include <X11/Xatom.h>
115#include <X11/keysym.h> 115#include <X11/keysym.h>
116 116
117#ifdef XINERAMA
118extern "C" {
119#include <X11/extensions/Xinerama.h>
120}
121#endif // XINERAMA
122
117#include <iostream> 123#include <iostream>
118#include <memory> 124#include <memory>
119#include <algorithm> 125#include <algorithm>
@@ -480,13 +486,14 @@ BScreen::ScreenResource::ScreenResource(FbTk::ResourceManager &rm,
480 toolbar_on_head(rm, 0, scrname+".toolbar.onhead", altscrname+".Toolbar.onHead"), 486 toolbar_on_head(rm, 0, scrname+".toolbar.onhead", altscrname+".Toolbar.onHead"),
481 toolbar_placement(rm, Toolbar::BOTTOMCENTER, 487 toolbar_placement(rm, Toolbar::BOTTOMCENTER,
482 scrname+".toolbar.placement", altscrname+".Toolbar.Placement"), 488 scrname+".toolbar.placement", altscrname+".Toolbar.Placement"),
483 slit_auto_hide(rm, false, 489 slit_auto_hide(rm, false,
484 scrname+".slit.autoHide", altscrname+".Slit.AutoHide"), 490 scrname+".slit.autoHide", altscrname+".Slit.AutoHide"),
485 slit_placement(rm, Slit::BOTTOMRIGHT, 491 slit_placement(rm, Slit::BOTTOMRIGHT,
486 scrname+".slit.placement", altscrname+".Slit.Placement"), 492 scrname+".slit.placement", altscrname+".Slit.Placement"),
487 slit_direction(rm, Slit::VERTICAL, 493 slit_direction(rm, Slit::VERTICAL,
488 scrname+".slit.direction", altscrname+".Slit.Direction"), 494 scrname+".slit.direction", altscrname+".Slit.Direction"),
489 slit_alpha(rm, 255, scrname+".slit.alpha", altscrname+".Slit.Alpha") { 495 slit_alpha(rm, 255, scrname+".slit.alpha", altscrname+".Slit.Alpha"),
496 slit_on_head(rm, 0, scrname+".slit.onhead", altscrname+".Slit.onHead") {
490 497
491}; 498};
492 499
@@ -516,6 +523,10 @@ BScreen::BScreen(FbTk::ResourceManager &rm,
516 523
517 Display *disp = FbTk::App::instance()->display(); 524 Display *disp = FbTk::App::instance()->display();
518 525
526#ifdef XINERAMA
527 initXinerama(disp);
528#endif // XINERAMA
529
519 event_mask = ColormapChangeMask | EnterWindowMask | PropertyChangeMask | 530 event_mask = ColormapChangeMask | EnterWindowMask | PropertyChangeMask |
520 SubstructureRedirectMask | KeyPressMask | KeyReleaseMask | 531 SubstructureRedirectMask | KeyPressMask | KeyReleaseMask |
521 ButtonPressMask | ButtonReleaseMask| SubstructureNotifyMask; 532 ButtonPressMask | ButtonReleaseMask| SubstructureNotifyMask;
@@ -761,6 +772,12 @@ BScreen::~BScreen() {
761 } 772 }
762 773
763 netizenList.clear(); 774 netizenList.clear();
775
776#ifdef XINERAMA
777 if (hasXinerama() && m_xinerama_headinfo) {
778 delete [] m_xinerama_headinfo;
779 }
780#endif // XINERAMA
764} 781}
765 782
766const FbTk::Menu &BScreen::toolbarModemenu() const { 783const FbTk::Menu &BScreen::toolbarModemenu() const {
@@ -2524,3 +2541,102 @@ void BScreen::updateSize() {
2524 //!! TODO: should we re-maximize the maximized windows? 2541 //!! TODO: should we re-maximize the maximized windows?
2525 2542
2526} 2543}
2544
2545#ifdef XINERAMA
2546
2547void BScreen::initXinerama(Display *display) {
2548 if (!XineramaIsActive(display)) {
2549 m_xinerama_avail = false;
2550 m_xinerama_headinfo = 0;
2551 return;
2552 }
2553 m_xinerama_avail = true;
2554
2555 XineramaScreenInfo *screen_info;
2556 int number;
2557 screen_info = XineramaQueryScreens(display, &number);
2558 m_xinerama_headinfo = new XineramaHeadInfo[number];
2559 m_xinerama_num_heads = number;
2560 for (int i=0; i < number; i++) {
2561 m_xinerama_headinfo[i].x = screen_info[i].x_org;
2562 m_xinerama_headinfo[i].y = screen_info[i].y_org;
2563 m_xinerama_headinfo[i].width = screen_info[i].width;
2564 m_xinerama_headinfo[i].height = screen_info[i].height;
2565 }
2566
2567}
2568
2569int BScreen::getHead(int x, int y) const {
2570 if (!hasXinerama()) return 0;
2571
2572 for (int i=0; i < m_xinerama_num_heads; i++) {
2573 if (x >= m_xinerama_headinfo[i].x &&
2574 x < (m_xinerama_headinfo[i].x + m_xinerama_headinfo[i].width) &&
2575 y >= m_xinerama_headinfo[i].y &&
2576 y < (m_xinerama_headinfo[i].y + m_xinerama_headinfo[i].height)) {
2577 return i+1;
2578 }
2579 }
2580
2581 return 0;
2582}
2583
2584int BScreen::getCurrHead() const {
2585 if (!hasXinerama()) return 0;
2586 int root_x, root_y, ignore_i;
2587
2588 unsigned int ignore_ui;
2589
2590 Window ignore_w;
2591
2592 XQueryPointer(FbTk::App::instance()->display(),
2593 rootWindow().window(), &ignore_w,
2594 &ignore_w, &root_x, &root_y,
2595 &ignore_i, &ignore_i, &ignore_ui);
2596 return getHead(root_x, root_y);
2597
2598}
2599
2600int BScreen::getHeadX(int head) const {
2601 if (head == 0 || head > m_xinerama_num_heads) return 0;
2602 return m_xinerama_headinfo[head-1].x;
2603}
2604
2605int BScreen::getHeadY(int head) const {
2606 if (head == 0 || head > m_xinerama_num_heads) return 0;
2607 return m_xinerama_headinfo[head-1].y;
2608}
2609
2610int BScreen::getHeadWidth(int head) const {
2611 if (head == 0 || head > m_xinerama_num_heads) return width();
2612 return m_xinerama_headinfo[head-1].width;
2613}
2614
2615int BScreen::getHeadHeight(int head) const {
2616 if (head == 0 || head > m_xinerama_num_heads) return height();
2617 return m_xinerama_headinfo[head-1].height;
2618}
2619
2620template <>
2621int BScreen::getOnHead<Toolbar>(Toolbar &tbar) {
2622 return getToolbarOnHead();
2623}
2624
2625template <>
2626void BScreen::setOnHead<Toolbar>(Toolbar &tbar, int head) {
2627 saveToolbarOnHead(head);
2628 tbar.reconfigure();
2629}
2630
2631template <>
2632int BScreen::getOnHead<Slit>(Slit &tbar) {
2633 return getSlitOnHead();
2634}
2635
2636template <>
2637void BScreen::setOnHead<Slit>(Slit &slit, int head) {
2638 saveSlitOnHead(head);
2639 slit.reconfigure();
2640}
2641
2642#endif // XINERAMA
diff --git a/src/Screen.hh b/src/Screen.hh
index d06937b..f5585c7 100644
--- a/src/Screen.hh
+++ b/src/Screen.hh
@@ -22,7 +22,7 @@
22// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 22// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23// DEALINGS IN THE SOFTWARE. 23// DEALINGS IN THE SOFTWARE.
24 24
25// $Id: Screen.hh,v 1.99 2003/05/18 22:00:04 fluxgen Exp $ 25// $Id: Screen.hh,v 1.100 2003/05/19 14:26:30 rathnor Exp $
26 26
27#ifndef SCREEN_HH 27#ifndef SCREEN_HH
28#define SCREEN_HH 28#define SCREEN_HH
@@ -116,8 +116,8 @@ public:
116 inline void saveSlitDirection(Slit::Direction d) { resource.slit_direction = d; } 116 inline void saveSlitDirection(Slit::Direction d) { resource.slit_direction = d; }
117 inline void saveSlitAutoHide(bool t) { resource.slit_auto_hide = t; } 117 inline void saveSlitAutoHide(bool t) { resource.slit_auto_hide = t; }
118 118
119 inline unsigned int getSlitOnHead() const { return resource.slit_on_head; } 119 inline int getSlitOnHead() const { return *resource.slit_on_head; }
120 inline void saveSlitOnHead(unsigned int h) { resource.slit_on_head = h; } 120 inline void saveSlitOnHead(int h) { *resource.slit_on_head = h; }
121 121
122 inline const Toolbar *toolbar() const { return m_toolbarhandler->getToolbar(); } 122 inline const Toolbar *toolbar() const { return m_toolbarhandler->getToolbar(); }
123 inline Toolbar *toolbar() { return m_toolbarhandler->getToolbar(); } 123 inline Toolbar *toolbar() { return m_toolbarhandler->getToolbar(); }
@@ -296,6 +296,29 @@ public:
296 /// (and maximized windows?) 296 /// (and maximized windows?)
297 void updateSize(); 297 void updateSize();
298 298
299#ifdef XINERAMA
300 // Xinerama-related functions
301 inline bool hasXinerama() const { return m_xinerama_avail; }
302 inline int numHeads() const { return m_xinerama_num_heads; }
303
304 void initXinerama(Display *display);
305
306 int getHead(int x, int y) const;
307 int getCurrHead() const;
308 int getHeadX(int head) const;
309 int getHeadY(int head) const;
310 int getHeadWidth(int head) const;
311 int getHeadHeight(int head) const;
312
313 // magic to allow us to have "on head" placement without
314 // the object really knowing about it.
315 template <typename OnHeadObject>
316 int getOnHead(OnHeadObject &obj);
317
318 template <typename OnHeadObject>
319 void setOnHead(OnHeadObject &obj, int head);
320#endif // XINERAMA
321
299 // notify netizens 322 // notify netizens
300 void updateNetizenCurrentWorkspace(); 323 void updateNetizenCurrentWorkspace();
301 void updateNetizenWorkspaceCount(); 324 void updateNetizenWorkspaceCount();
@@ -412,9 +435,7 @@ private:
412 FbTk::Resource<bool> slit_auto_hide; 435 FbTk::Resource<bool> slit_auto_hide;
413 FbTk::Resource<Slit::Placement> slit_placement; 436 FbTk::Resource<Slit::Placement> slit_placement;
414 FbTk::Resource<Slit::Direction> slit_direction; 437 FbTk::Resource<Slit::Direction> slit_direction;
415 FbTk::Resource<int> slit_alpha; 438 FbTk::Resource<int> slit_alpha, slit_on_head;
416
417 unsigned int slit_on_head;
418 439
419 std::string strftime_format; 440 std::string strftime_format;
420 441
@@ -425,6 +446,21 @@ private:
425 } resource; 446 } resource;
426 447
427 std::auto_ptr<ToolbarHandler> m_toolbarhandler; 448 std::auto_ptr<ToolbarHandler> m_toolbarhandler;
449
450#ifdef XINERAMA
451 // Xinerama related private data
452 bool m_xinerama_avail;
453 int m_xinerama_num_heads;
454
455 int m_xinerama_center_x, m_xinerama_center_y;
456
457 struct XineramaHeadInfo {
458 int x, y, width, height;
459 } *m_xinerama_headinfo;
460
461
462
463#endif
428}; 464};
429 465
430 466
diff --git a/src/Slit.cc b/src/Slit.cc
index 6f1a7c4..b2dd383 100644
--- a/src/Slit.cc
+++ b/src/Slit.cc
@@ -22,7 +22,7 @@
22// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 22// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23// DEALINGS IN THE SOFTWARE. 23// DEALINGS IN THE SOFTWARE.
24 24
25// $Id: Slit.cc,v 1.55 2003/05/17 11:00:50 fluxgen Exp $ 25// $Id: Slit.cc,v 1.56 2003/05/19 14:26:30 rathnor Exp $
26 26
27#include "Slit.hh" 27#include "Slit.hh"
28 28
@@ -52,6 +52,10 @@
52#include "Transparent.hh" 52#include "Transparent.hh"
53#include "IntResMenuItem.hh" 53#include "IntResMenuItem.hh"
54 54
55#ifdef XINERAMA
56#include "Xinerama.hh"
57#endif // XINERAMA
58
55#include <algorithm> 59#include <algorithm>
56#include <iostream> 60#include <iostream>
57#include <cassert> 61#include <cassert>
@@ -790,8 +794,20 @@ void Slit::reposition() {
790 head_w, 794 head_w,
791 head_h; 795 head_h;
792 796
793 head_w = screen().width(); 797#ifdef XINERAMA
794 head_h = screen().height(); 798 if (screen().hasXinerama()) {
799 int head = screen().getSlitOnHead();
800 head_x = screen().getHeadX(head);
801 head_y = screen().getHeadY(head);
802 head_w = screen().getHeadWidth(head);
803 head_h = screen().getHeadHeight(head);
804 } else
805#endif // XINERAMA
806 {
807 head_w = screen().width();
808 head_h = screen().height();
809 }
810
795 int border_width = screen().rootTheme().borderWidth(); 811 int border_width = screen().rootTheme().borderWidth();
796 int bevel_width = screen().rootTheme().bevelWidth(); 812 int bevel_width = screen().rootTheme().bevelWidth();
797 813
@@ -1206,6 +1222,18 @@ void Slit::setupMenu() {
1206 1222
1207 m_slitmenu.insert("Layer...", m_layermenu.get()); 1223 m_slitmenu.insert("Layer...", m_layermenu.get());
1208 1224
1225#ifdef XINERAMA
1226 if (screen().hasXinerama()) {
1227 m_slitmenu.insert("On Head...", new XineramaHeadMenu<Slit>(
1228 *screen().menuTheme(),
1229 screen(),
1230 screen().imageControl(),
1231 *screen().layerManager().getLayer(Fluxbox::instance()->getMenuLayer()),
1232 this
1233 ));
1234 }
1235
1236#endif //XINERAMA
1209 m_slitmenu.insert(new BoolMenuItem(i18n->getMessage( 1237 m_slitmenu.insert(new BoolMenuItem(i18n->getMessage(
1210 CommonSet, CommonAutoHide, 1238 CommonSet, CommonAutoHide,
1211 "Auto hide"), 1239 "Auto hide"),
diff --git a/src/Toolbar.cc b/src/Toolbar.cc
index 2508ec9..9a29f79 100644
--- a/src/Toolbar.cc
+++ b/src/Toolbar.cc
@@ -22,7 +22,7 @@
22// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 22// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23// DEALINGS IN THE SOFTWARE. 23// DEALINGS IN THE SOFTWARE.
24 24
25// $Id: Toolbar.cc,v 1.84 2003/05/17 11:30:59 fluxgen Exp $ 25// $Id: Toolbar.cc,v 1.85 2003/05/19 14:26:30 rathnor Exp $
26 26
27#include "Toolbar.hh" 27#include "Toolbar.hh"
28 28
@@ -43,6 +43,10 @@
43#include "BoolMenuItem.hh" 43#include "BoolMenuItem.hh"
44#include "FbWinFrameTheme.hh" 44#include "FbWinFrameTheme.hh"
45 45
46#ifdef XINERAMA
47#include "Xinerama.hh"
48#endif XINERAMA
49
46// use GNU extensions 50// use GNU extensions
47#ifndef _GNU_SOURCE 51#ifndef _GNU_SOURCE
48#define _GNU_SOURCE 52#define _GNU_SOURCE
@@ -134,6 +138,18 @@ void setupMenus(Toolbar &tbar) {
134 menu.setInternalMenu(); 138 menu.setInternalMenu();
135 139
136 menu.insert("Layer...", &tbar.layermenu()); 140 menu.insert("Layer...", &tbar.layermenu());
141#ifdef XINERAMA
142 if (tbar.screen().hasXinerama()) {
143 menu.insert("On Head...", new XineramaHeadMenu<Toolbar>(
144 *tbar.screen().menuTheme(),
145 tbar.screen(),
146 tbar.screen().imageControl(),
147 *tbar.screen().layerManager().getLayer(Fluxbox::instance()->getMenuLayer()),
148 &tbar
149 ));
150 }
151
152#endif //XINERAMA
137 153
138 // setup items in placement menu 154 // setup items in placement menu
139 struct { 155 struct {
@@ -1091,10 +1107,21 @@ void Toolbar::setPlacement(Toolbar::Placement where) {
1091 head_w, 1107 head_w,
1092 head_h; 1108 head_h;
1093 1109
1094 m_place = where; 1110#ifdef XINERAMA
1111 if (screen().hasXinerama()) {
1112 int head = screen().getToolbarOnHead();
1113 head_x = screen().getHeadX(head);
1114 head_y = screen().getHeadY(head);
1115 head_w = screen().getHeadWidth(head);
1116 head_h = screen().getHeadHeight(head);
1117 } else
1118#endif // XINERAMA
1119 {
1120 head_w = screen().width();
1121 head_h = screen().height();
1122 }
1095 1123
1096 head_w = screen().width(); 1124 m_place = where;
1097 head_h = screen().height();
1098 1125
1099 frame.width = head_w * screen().getToolbarWidthPercent() / 100; 1126 frame.width = head_w * screen().getToolbarWidthPercent() / 100;
1100 frame.height = m_theme.font().height(); 1127 frame.height = m_theme.font().height();
diff --git a/src/Xinerama.hh b/src/Xinerama.hh
new file mode 100644
index 0000000..eebd431
--- /dev/null
+++ b/src/Xinerama.hh
@@ -0,0 +1,105 @@
1// Xinerama.hh for Fluxbox - helpful tools for multiple heads
2// Copyright (c) 2003 Henrik Kinnunen (fluxgen at users.sourceforge.net)
3// and Simon Bowden (rathnor at users.sourceforge.net)
4//
5// Permission is hereby granted, free of charge, to any person obtaining a
6// copy of this software and associated documentation files (the "Software"),
7// to deal in the Software without restriction, including without limitation
8// the rights to use, copy, modify, merge, publish, distribute, sublicense,
9// and/or sell copies of the Software, and to permit persons to whom the
10// Software is furnished to do so, subject to the following conditions:
11//
12// The above copyright notice and this permission notice shall be included in
13// all copies or substantial portions of the Software.
14//
15// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21// DEALINGS IN THE SOFTWARE.
22
23// $Id: Xinerama.hh,v 1.1 2003/05/19 14:26:30 rathnor Exp $
24
25#ifndef XINERAMA_HH
26#define XINERAMA_HH
27
28#include "MenuItem.hh"
29#include "FbMenu.hh"
30#include "FbCommands.hh"
31#include "RefCount.hh"
32#include "SimpleCommand.hh"
33
34#include "fluxbox.hh"
35
36// provides a generic way for giving an object a xinerama head menu
37// The object must have two functions:
38// int getOnHead(), and
39// void setOnHead(int)
40
41/// this class holds the xinerama items
42template <typename ItemType>
43class XineramaHeadMenuItem : public FbTk::MenuItem {
44public:
45 XineramaHeadMenuItem(const char *label, ItemType *object, int headnum,
46 FbTk::RefCount<FbTk::Command> &cmd):
47 FbTk::MenuItem(label,cmd), m_object(object), m_headnum(headnum) {}
48 XineramaHeadMenuItem(const char *label, ItemType *object, int headnum):
49 FbTk::MenuItem(label), m_object(object), m_headnum(headnum) {}
50
51 bool isEnabled() const { return m_object->screen().getOnHead(*m_object) != m_headnum; } ;
52 void click(int button, int time) {
53 m_object->screen().setOnHead(*m_object, m_headnum);
54 FbTk::MenuItem::click(button, time);
55 }
56
57private:
58 ItemType *m_object;
59 int m_headnum;
60};
61
62
63/// Create a xinerama menu
64template <typename ItemType>
65class XineramaHeadMenu : public FbMenu {
66public:
67 XineramaHeadMenu(FbTk::MenuTheme &tm, BScreen &screen, FbTk::ImageControl &imgctrl,
68 FbTk::XLayer &layer, ItemType *item);
69
70private:
71 ItemType *m_object;
72};
73
74
75template <typename ItemType>
76XineramaHeadMenu<ItemType>::XineramaHeadMenu(FbTk::MenuTheme &tm, BScreen &screen, FbTk::ImageControl &imgctrl,
77 FbTk::XLayer &layer, ItemType *item):
78 FbMenu(tm, screen.screenNumber(), imgctrl, layer),
79 m_object(item)
80{
81
82 FbTk::RefCount<FbTk::Command> saverc_cmd(new FbTk::SimpleCommand<Fluxbox>(
83 *Fluxbox::instance(),
84 &Fluxbox::save_rc));
85 char tname[128];
86 for (int i=1; i <= screen.numHeads(); ++i) {
87 // TODO: nls
88/*
89 sprintf(tname, I18n::instance()->
90 getMessage(
91 FBNLS::ScreenSet,
92 FBNLS::XineramaDefaultHeadFormat,
93 "Head %d"), i); //m_id starts at 0
94*/
95 sprintf(tname, "Head %d", i);
96 insert(new XineramaHeadMenuItem<ItemType>(
97 tname, m_object, i, saverc_cmd));
98 }
99 // TODO: nls
100 insert(new XineramaHeadMenuItem<ItemType>(
101 "All Heads", m_object, 0, saverc_cmd));
102 update();
103}
104
105#endif // XINERAMA_HH