split the screeninfo class out to its own files
[dana/openbox.git] / src / screeninfo.cc
1 // -*- mode: C++; indent-tabs-mode: nil; -*-
2
3 #ifdef    HAVE_CONFIG_H
4 #  include "../config.h"
5 #endif // HAVE_CONFIG_H
6
7 #include "screeninfo.hh"
8 #include "basedisplay.hh"
9
10 using std::string;
11
12 ScreenInfo::ScreenInfo(BaseDisplay *d, unsigned int num) {
13   basedisplay = d;
14   screen_number = num;
15
16   root_window = RootWindow(basedisplay->getXDisplay(), screen_number);
17
18   rect.setSize(WidthOfScreen(ScreenOfDisplay(basedisplay->getXDisplay(),
19                                              screen_number)),
20                HeightOfScreen(ScreenOfDisplay(basedisplay->getXDisplay(),
21                                               screen_number)));
22   /*
23     If the default depth is at least 8 we will use that,
24     otherwise we try to find the largest TrueColor visual.
25     Preference is given to 24 bit over larger depths if 24 bit is an option.
26   */
27
28   depth = DefaultDepth(basedisplay->getXDisplay(), screen_number);
29   visual = DefaultVisual(basedisplay->getXDisplay(), screen_number);
30   colormap = DefaultColormap(basedisplay->getXDisplay(), screen_number);
31   
32   if (depth < 8) {
33     // search for a TrueColor Visual... if we can't find one...
34     // we will use the default visual for the screen
35     XVisualInfo vinfo_template, *vinfo_return;
36     int vinfo_nitems;
37     int best = -1;
38
39     vinfo_template.screen = screen_number;
40     vinfo_template.c_class = TrueColor;
41
42     vinfo_return = XGetVisualInfo(basedisplay->getXDisplay(),
43                                   VisualScreenMask | VisualClassMask,
44                                   &vinfo_template, &vinfo_nitems);
45     if (vinfo_return) {
46       int max_depth = 1;
47       for (int i = 0; i < vinfo_nitems; ++i) {
48         if (vinfo_return[i].depth > max_depth) {
49           if (max_depth == 24 && vinfo_return[i].depth > 24)
50             break;          // prefer 24 bit over 32
51           max_depth = vinfo_return[i].depth;
52           best = i;
53         }
54       }
55       if (max_depth < depth) best = -1;
56     }
57
58     if (best != -1) {
59       depth = vinfo_return[best].depth;
60       visual = vinfo_return[best].visual;
61       colormap = XCreateColormap(basedisplay->getXDisplay(), root_window,
62                                  visual, AllocNone);
63     }
64
65     XFree(vinfo_return);
66   }
67
68   // get the default display string and strip the screen number
69   string default_string = DisplayString(basedisplay->getXDisplay());
70   const string::size_type pos = default_string.rfind(".");
71   if (pos != string::npos)
72     default_string.resize(pos);
73
74   display_string = string("DISPLAY=") + default_string + '.' +
75     itostring(static_cast<unsigned long>(screen_number));
76   
77 #ifdef    XINERAMA
78   xinerama_active = False;
79
80   if (d->hasXineramaExtensions()) {
81     if (d->getXineramaMajorVersion() == 1) {
82       // we know the version 1(.1?) protocol
83
84       /*
85          in this version of Xinerama, we can't query on a per-screen basis, but
86          in future versions we should be able, so the 'activeness' is checked
87          on a pre-screen basis anyways.
88       */
89       if (XineramaIsActive(d->getXDisplay())) {
90         /*
91            If Xinerama is being used, there there is only going to be one screen
92            present. We still, of course, want to use the screen class, but that
93            is why no screen number is used in this function call. There should
94            never be more than one screen present with Xinerama active.
95         */
96         int num;
97         XineramaScreenInfo *info = XineramaQueryScreens(d->getXDisplay(), &num);
98         if (num > 0 && info) {
99           xinerama_areas.reserve(num);
100           for (int i = 0; i < num; ++i) {
101             xinerama_areas.push_back(Rect(info[i].x_org, info[i].y_org,
102                                           info[i].width, info[i].height));
103           }
104           XFree(info);
105
106           // if we can't find any xinerama regions, then we act as if it is not
107           // active, even though it said it was
108           xinerama_active = True;
109         }
110       }
111     }
112   }
113 #endif // XINERAMA
114 }