diff options
Diffstat (limited to 'src/Ewmh.cc')
-rw-r--r-- | src/Ewmh.cc | 72 |
1 files changed, 58 insertions, 14 deletions
diff --git a/src/Ewmh.cc b/src/Ewmh.cc index 14c74c6..2a9e1ab 100644 --- a/src/Ewmh.cc +++ b/src/Ewmh.cc | |||
@@ -76,16 +76,30 @@ namespace { | |||
76 | * byte being B. The first two cardinals are width, height. Data is in rows, | 76 | * byte being B. The first two cardinals are width, height. Data is in rows, |
77 | * left to right and top to bottom. | 77 | * left to right and top to bottom. |
78 | * | 78 | * |
79 | *** | ||
80 | * | ||
81 | * NOTE: the returned data for XA_CARDINAL is long if the rfmt equals | ||
82 | * 32. sizeof(long) on 64bit machines is 8. to quote from | ||
83 | * "man XGetWindowProperty": | ||
84 | * | ||
85 | * If the returned format is 32, the property data will be stored as | ||
86 | * an array of longs (which in a 64-bit application will be 64-bit | ||
87 | * values that are padded in the upper 4 bytes). | ||
88 | * | ||
89 | * this is especially true on 64bit machines when some of the clients | ||
90 | * (eg: tvtime, konqueror3) have problems to feed in the right data | ||
91 | * into the _NET_WM_ICON property. we faced some segfaults because | ||
92 | * width and height were not quite right because of ignoring 64bit | ||
93 | * behaviour on client side. | ||
94 | * | ||
79 | * TODO: maybe move the pixmap-creation code to FbTk? */ | 95 | * TODO: maybe move the pixmap-creation code to FbTk? */ |
80 | void extractNetWmIcon(Atom net_wm_icon, WinClient& winclient) { | 96 | void extractNetWmIcon(Atom net_wm_icon, WinClient& winclient) { |
81 | 97 | ||
82 | typedef std::pair<int, int> Size; | 98 | typedef std::pair<int, int> Size; |
83 | typedef std::map<Size, const unsigned long*> IconContainer; | 99 | typedef std::map<Size, const unsigned long*> IconContainer; |
84 | 100 | ||
85 | // attention: the returned data for XA_CARDINAL is long if the rfmt equals | ||
86 | // 32. sizeof(long) on 64bit machines is 8. | ||
87 | unsigned long* raw_data = 0; | 101 | unsigned long* raw_data = 0; |
88 | long nr_icon_data = 0; | 102 | unsigned long nr_icon_data = 0; |
89 | 103 | ||
90 | { | 104 | { |
91 | Atom rtype; | 105 | Atom rtype; |
@@ -106,7 +120,10 @@ void extractNetWmIcon(Atom net_wm_icon, WinClient& winclient) { | |||
106 | 120 | ||
107 | // actually there is some data in _NET_WM_ICON | 121 | // actually there is some data in _NET_WM_ICON |
108 | nr_icon_data = nr_bytes_left / sizeof(CARD32); | 122 | nr_icon_data = nr_bytes_left / sizeof(CARD32); |
109 | 123 | #ifdef DEBUG | |
124 | std::cerr << "extractNetWmIcon: " << winclient.title() << "\n"; | ||
125 | std::cerr << "nr_icon_data: " << nr_icon_data << "\n"; | ||
126 | #endif | ||
110 | // read all the icons stored in _NET_WM_ICON | 127 | // read all the icons stored in _NET_WM_ICON |
111 | if (raw_data) | 128 | if (raw_data) |
112 | XFree(raw_data); | 129 | XFree(raw_data); |
@@ -118,30 +135,57 @@ void extractNetWmIcon(Atom net_wm_icon, WinClient& winclient) { | |||
118 | 135 | ||
119 | return; | 136 | return; |
120 | } | 137 | } |
138 | #ifdef DEBUG | ||
139 | std::cerr << "nr_read: " << nr_read << "|" << nr_bytes_left << "\n"; | ||
140 | #endif | ||
121 | } | 141 | } |
122 | 142 | ||
123 | IconContainer icon_data; // stores all available data, sorted by size (width x height) | 143 | IconContainer icon_data; // stores all available data, sorted by size (width x height) |
124 | int width; | 144 | unsigned long width; |
125 | int height; | 145 | unsigned long height; |
126 | 146 | ||
127 | // analyze the available icons | 147 | // analyze the available icons |
128 | long i; | 148 | // |
129 | 149 | // check also for invalid values coming in from "bad" applications | |
150 | unsigned long i; | ||
130 | for (i = 0; i + 2 < nr_icon_data; i += width * height ) { | 151 | for (i = 0; i + 2 < nr_icon_data; i += width * height ) { |
131 | 152 | ||
132 | width = raw_data[i++]; | 153 | width = raw_data[i++]; |
154 | if (width >= nr_icon_data) { | ||
155 | #ifdef DEBUG | ||
156 | std::cerr << "Ewmh.cc extractNetWmIcon found strange _NET_WM_ICON width (" | ||
157 | << width << ") for " << winclient.title() << "\n"; | ||
158 | #endif | ||
159 | break; | ||
160 | } | ||
161 | |||
133 | height = raw_data[i++]; | 162 | height = raw_data[i++]; |
163 | if (height >= nr_icon_data) { | ||
164 | #ifdef DEBUG | ||
165 | std::cerr << "Ewmh.cc extractNetWmIcon found strange _NET_WM_ICON height (" | ||
166 | << height << ") for " << winclient.title() << "\n"; | ||
167 | #endif | ||
168 | break; | ||
169 | } | ||
134 | 170 | ||
135 | // strange values stored in the NETWM_ICON | 171 | // strange values stored in the NETWM_ICON |
136 | if (width <= 0 || height <= 0 || i + width * height > nr_icon_data) { | 172 | if (i + width * height > nr_icon_data) { |
137 | std::cerr << "Ewmh.cc extractNetWmIcon found strange _NET_WM_ICON dimensions for " << winclient.title() << "\n"; | 173 | #ifdef DEBUG |
138 | XFree(raw_data); | 174 | std::cerr << "Ewmh.cc extractNetWmIcon found strange _NET_WM_ICON dimensions (" |
139 | return; | 175 | << width << "x" << height << ")for " << winclient.title() << "\n"; |
176 | #endif | ||
177 | break; | ||
140 | } | 178 | } |
141 | 179 | ||
142 | icon_data[Size(width, height)] = &raw_data[i]; | 180 | icon_data[Size(width, height)] = &raw_data[i]; |
143 | } | 181 | } |
144 | 182 | ||
183 | // no valid icons found at all | ||
184 | if (icon_data.empty()) { | ||
185 | XFree(raw_data); | ||
186 | return; | ||
187 | } | ||
188 | |||
145 | Display* dpy = FbTk::App::instance()->display(); | 189 | Display* dpy = FbTk::App::instance()->display(); |
146 | int scrn = winclient.screen().screenNumber(); | 190 | int scrn = winclient.screen().screenNumber(); |
147 | 191 | ||
@@ -178,8 +222,8 @@ void extractNetWmIcon(Atom net_wm_icon, WinClient& winclient) { | |||
178 | const unsigned long* src = icon_data.begin()->second; | 222 | const unsigned long* src = icon_data.begin()->second; |
179 | unsigned int rgba; | 223 | unsigned int rgba; |
180 | unsigned long pixel; | 224 | unsigned long pixel; |
181 | int x; | 225 | unsigned long x; |
182 | int y; | 226 | unsigned long y; |
183 | unsigned char r, g, b, a; | 227 | unsigned char r, g, b, a; |
184 | 228 | ||
185 | for (y = 0; y < height; y++) { | 229 | for (y = 0; y < height; y++) { |