diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/Screen.cc | 132 | ||||
-rw-r--r-- | src/Screen.hh | 48 | ||||
-rw-r--r-- | src/Slit.cc | 34 | ||||
-rw-r--r-- | src/Toolbar.cc | 35 | ||||
-rw-r--r-- | src/Xinerama.hh | 105 |
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 | ||
118 | extern "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 | ||
766 | const FbTk::Menu &BScreen::toolbarModemenu() const { | 783 | const 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 | |||
2547 | void 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 | |||
2569 | int 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 | |||
2584 | int 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 | |||
2600 | int 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 | |||
2605 | int 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 | |||
2610 | int 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 | |||
2615 | int 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 | |||
2620 | template <> | ||
2621 | int BScreen::getOnHead<Toolbar>(Toolbar &tbar) { | ||
2622 | return getToolbarOnHead(); | ||
2623 | } | ||
2624 | |||
2625 | template <> | ||
2626 | void BScreen::setOnHead<Toolbar>(Toolbar &tbar, int head) { | ||
2627 | saveToolbarOnHead(head); | ||
2628 | tbar.reconfigure(); | ||
2629 | } | ||
2630 | |||
2631 | template <> | ||
2632 | int BScreen::getOnHead<Slit>(Slit &tbar) { | ||
2633 | return getSlitOnHead(); | ||
2634 | } | ||
2635 | |||
2636 | template <> | ||
2637 | void 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 | ||
42 | template <typename ItemType> | ||
43 | class XineramaHeadMenuItem : public FbTk::MenuItem { | ||
44 | public: | ||
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 | |||
57 | private: | ||
58 | ItemType *m_object; | ||
59 | int m_headnum; | ||
60 | }; | ||
61 | |||
62 | |||
63 | /// Create a xinerama menu | ||
64 | template <typename ItemType> | ||
65 | class XineramaHeadMenu : public FbMenu { | ||
66 | public: | ||
67 | XineramaHeadMenu(FbTk::MenuTheme &tm, BScreen &screen, FbTk::ImageControl &imgctrl, | ||
68 | FbTk::XLayer &layer, ItemType *item); | ||
69 | |||
70 | private: | ||
71 | ItemType *m_object; | ||
72 | }; | ||
73 | |||
74 | |||
75 | template <typename ItemType> | ||
76 | XineramaHeadMenu<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 | ||