2010-01-07 03:45:19 +00:00
|
|
|
/* -*- mode: c++; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: t -*-
|
|
|
|
* vim: ts=4 sw=4 noet ai cindent syntax=cpp
|
2009-07-28 21:44:22 +00:00
|
|
|
*
|
|
|
|
* Conky, a system monitor, based on torsmo
|
2005-08-05 01:06:17 +00:00
|
|
|
*
|
2007-08-10 19:53:44 +00:00
|
|
|
* Any original torsmo code is licensed under the BSD license
|
|
|
|
*
|
|
|
|
* All code written since the fork of torsmo is licensed under the GPL
|
|
|
|
*
|
|
|
|
* Please see COPYING for details
|
|
|
|
*
|
|
|
|
* Copyright (c) 2004, Hannu Saransaari and Lauri Hakkarainen
|
2012-05-03 23:34:44 +00:00
|
|
|
* Copyright (c) 2005-2012 Brenden Matthews, Philip Kovacs, et. al.
|
2008-02-20 20:30:45 +00:00
|
|
|
* (see AUTHORS)
|
2007-08-10 19:53:44 +00:00
|
|
|
* All rights reserved.
|
|
|
|
*
|
|
|
|
* This program is free software: you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
|
|
* (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
* You should have received a copy of the GNU General Public License
|
2008-02-20 20:30:45 +00:00
|
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
2005-08-05 01:06:17 +00:00
|
|
|
*
|
2008-12-09 23:35:49 +00:00
|
|
|
*/
|
2005-08-05 01:06:17 +00:00
|
|
|
|
2008-12-15 21:40:24 +00:00
|
|
|
#include "config.h"
|
2005-07-20 00:30:40 +00:00
|
|
|
#include "conky.h"
|
2008-12-15 21:40:24 +00:00
|
|
|
#include "logging.h"
|
|
|
|
#include "common.h"
|
2005-08-30 00:22:55 +00:00
|
|
|
|
2008-12-15 21:40:24 +00:00
|
|
|
#include "x11.h"
|
2005-07-20 00:30:40 +00:00
|
|
|
#include <X11/Xlib.h>
|
|
|
|
#include <X11/Xatom.h>
|
2006-03-08 06:31:18 +00:00
|
|
|
#include <X11/Xmd.h>
|
2005-07-20 00:30:40 +00:00
|
|
|
#include <X11/Xutil.h>
|
2010-01-10 23:35:22 +00:00
|
|
|
#ifdef BUILD_IMLIB2
|
2009-05-06 03:45:05 +00:00
|
|
|
#include "imlib2.h"
|
2010-01-10 23:35:22 +00:00
|
|
|
#endif /* BUILD_IMLIB2 */
|
2010-11-23 12:58:53 +00:00
|
|
|
#ifndef OWN_WINDOW
|
|
|
|
#include <iostream>
|
|
|
|
#endif
|
2010-01-07 02:38:12 +00:00
|
|
|
#ifdef BUILD_XFT
|
2005-07-20 00:30:40 +00:00
|
|
|
#include <X11/Xft/Xft.h>
|
|
|
|
#endif
|
2015-12-01 12:53:43 +00:00
|
|
|
#ifdef BUILD_XINERAMA
|
|
|
|
#include <X11/extensions/Xinerama.h>
|
|
|
|
#endif
|
2005-07-20 00:30:40 +00:00
|
|
|
|
2010-01-07 02:38:12 +00:00
|
|
|
#ifdef BUILD_ARGB
|
2010-02-26 17:29:46 +00:00
|
|
|
bool have_argb_visual;
|
2010-01-07 02:38:12 +00:00
|
|
|
#endif /* BUILD_ARGB */
|
2010-01-01 23:01:51 +00:00
|
|
|
|
2005-07-20 00:30:40 +00:00
|
|
|
/* some basic X11 stuff */
|
2009-05-28 13:45:15 +00:00
|
|
|
Display *display = NULL;
|
2005-07-20 00:30:40 +00:00
|
|
|
int display_width;
|
|
|
|
int display_height;
|
|
|
|
int screen;
|
|
|
|
|
|
|
|
/* workarea from _NET_WORKAREA, this is where window / text is aligned */
|
|
|
|
int workarea[4];
|
|
|
|
|
2009-08-07 07:24:24 +00:00
|
|
|
/* Window stuff */
|
|
|
|
struct conky_window window;
|
2009-11-21 14:45:00 +00:00
|
|
|
char window_created = 0;
|
2009-08-07 07:24:24 +00:00
|
|
|
|
2005-07-20 00:30:40 +00:00
|
|
|
/* local prototypes */
|
2008-03-29 02:01:03 +00:00
|
|
|
static void update_workarea(void);
|
2006-03-07 19:46:51 +00:00
|
|
|
static Window find_desktop_window(Window *p_root, Window *p_desktop);
|
2005-07-20 00:30:40 +00:00
|
|
|
static Window find_subwindow(Window win, int w, int h);
|
2010-03-10 20:02:13 +00:00
|
|
|
static void init_X11();
|
|
|
|
static void deinit_X11();
|
2010-04-23 15:35:41 +00:00
|
|
|
static void init_window(lua::state &l, bool own);
|
2010-03-10 20:02:13 +00:00
|
|
|
|
|
|
|
/********************* <SETTINGS> ************************/
|
|
|
|
namespace priv {
|
|
|
|
void out_to_x_setting::lua_setter(lua::state &l, bool init)
|
|
|
|
{
|
|
|
|
lua::stack_sentry s(l, -2);
|
|
|
|
|
|
|
|
Base::lua_setter(l, init);
|
|
|
|
|
|
|
|
if(init && do_convert(l, -1).first)
|
|
|
|
init_X11();
|
|
|
|
|
|
|
|
++s;
|
|
|
|
}
|
|
|
|
|
|
|
|
void out_to_x_setting::cleanup(lua::state &l)
|
|
|
|
{
|
|
|
|
lua::stack_sentry s(l, -1);
|
|
|
|
|
|
|
|
if(do_convert(l, -1).first)
|
|
|
|
deinit_X11();
|
|
|
|
|
|
|
|
l.pop();
|
|
|
|
}
|
|
|
|
|
2010-04-23 15:35:41 +00:00
|
|
|
void own_window_setting::lua_setter(lua::state &l, bool init)
|
|
|
|
{
|
|
|
|
lua::stack_sentry s(l, -2);
|
|
|
|
|
|
|
|
Base::lua_setter(l, init);
|
|
|
|
|
|
|
|
if(init) {
|
|
|
|
if(do_convert(l, -1).first) {
|
|
|
|
#ifndef OWN_WINDOW
|
|
|
|
std::cerr << "Support for the own_window setting has been "
|
|
|
|
"disabled during compilation\n";
|
|
|
|
l.pop();
|
|
|
|
l.pushboolean(false);
|
|
|
|
#endif
|
|
|
|
}
|
2010-09-12 13:32:05 +00:00
|
|
|
|
2010-11-18 15:09:36 +00:00
|
|
|
if(out_to_x.get(l))
|
|
|
|
init_window(l, do_convert(l, -1).first);
|
|
|
|
else {
|
2010-09-12 13:32:05 +00:00
|
|
|
// own_window makes no sense when not drawing to X
|
|
|
|
l.pop();
|
|
|
|
l.pushboolean(false);
|
2010-11-18 15:09:36 +00:00
|
|
|
}
|
2010-04-23 15:35:41 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
++s;
|
|
|
|
}
|
|
|
|
|
2010-04-23 19:54:40 +00:00
|
|
|
#ifdef BUILD_XDBE
|
|
|
|
bool use_xdbe_setting::set_up(lua::state &l)
|
|
|
|
{
|
|
|
|
// double_buffer makes no sense when not drawing to X
|
|
|
|
if(not out_to_x.get(l))
|
|
|
|
return false;
|
|
|
|
|
|
|
|
int major, minor;
|
|
|
|
|
|
|
|
if (not XdbeQueryExtension(display, &major, &minor)) {
|
|
|
|
NORM_ERR("No compatible double buffer extension found");
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
window.back_buffer = XdbeAllocateBackBufferName(display,
|
|
|
|
window.window, XdbeBackground);
|
|
|
|
if (window.back_buffer != None) {
|
|
|
|
window.drawable = window.back_buffer;
|
|
|
|
} else {
|
|
|
|
NORM_ERR("Failed to allocate back buffer");
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
XFlush(display);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void use_xdbe_setting::lua_setter(lua::state &l, bool init)
|
|
|
|
{
|
|
|
|
lua::stack_sentry s(l, -2);
|
|
|
|
|
|
|
|
Base::lua_setter(l, init);
|
|
|
|
|
|
|
|
if(init && do_convert(l, -1).first) {
|
|
|
|
if(not set_up(l)) {
|
|
|
|
l.pop();
|
|
|
|
l.pushboolean(false);
|
|
|
|
}
|
|
|
|
|
|
|
|
fprintf(stderr, PACKAGE_NAME": drawing to %s buffer\n",
|
|
|
|
do_convert(l, -1).first?"double":"single");
|
|
|
|
}
|
|
|
|
|
|
|
|
++s;
|
|
|
|
}
|
2012-04-11 16:06:47 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#else
|
|
|
|
bool use_xpmdb_setting::set_up(lua::state &l)
|
|
|
|
{
|
|
|
|
// double_buffer makes no sense when not drawing to X
|
|
|
|
if(not out_to_x.get(l))
|
|
|
|
return false;
|
|
|
|
|
|
|
|
window.back_buffer = XCreatePixmap(display,
|
|
|
|
window.window, window.width+1, window.height+1, DefaultDepth(display, screen));
|
|
|
|
if (window.back_buffer != None) {
|
|
|
|
window.drawable = window.back_buffer;
|
|
|
|
} else {
|
|
|
|
NORM_ERR("Failed to allocate back buffer");
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
XFlush(display);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void use_xpmdb_setting::lua_setter(lua::state &l, bool init)
|
|
|
|
{
|
|
|
|
lua::stack_sentry s(l, -2);
|
|
|
|
|
|
|
|
Base::lua_setter(l, init);
|
|
|
|
|
|
|
|
if(init && do_convert(l, -1).first) {
|
|
|
|
if(not set_up(l)) {
|
|
|
|
l.pop();
|
|
|
|
l.pushboolean(false);
|
|
|
|
}
|
|
|
|
|
|
|
|
fprintf(stderr, PACKAGE_NAME": drawing to %s buffer\n",
|
|
|
|
do_convert(l, -1).first?"double":"single");
|
|
|
|
}
|
|
|
|
|
|
|
|
++s;
|
|
|
|
}
|
2010-04-23 19:54:40 +00:00
|
|
|
#endif
|
|
|
|
|
2010-03-11 10:28:12 +00:00
|
|
|
void colour_setting::lua_setter(lua::state &l, bool init)
|
|
|
|
{
|
|
|
|
lua::stack_sentry s(l, -2);
|
2010-03-10 20:02:13 +00:00
|
|
|
|
2010-03-11 10:28:12 +00:00
|
|
|
if(not out_to_x.get(l)) {
|
|
|
|
// ignore if we're not using X
|
|
|
|
l.replace(-2);
|
|
|
|
} else
|
|
|
|
Base::lua_setter(l, init);
|
|
|
|
|
|
|
|
++s;
|
|
|
|
}
|
2010-03-10 20:02:13 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
template<>
|
|
|
|
conky::lua_traits<alignment>::Map conky::lua_traits<alignment>::map = {
|
|
|
|
{ "top_left", TOP_LEFT },
|
|
|
|
{ "top_right", TOP_RIGHT },
|
|
|
|
{ "top_middle", TOP_MIDDLE },
|
|
|
|
{ "bottom_left", BOTTOM_LEFT },
|
|
|
|
{ "bottom_right", BOTTOM_RIGHT },
|
|
|
|
{ "bottom_middle", BOTTOM_MIDDLE },
|
|
|
|
{ "middle_left", MIDDLE_LEFT },
|
|
|
|
{ "middle_middle", MIDDLE_MIDDLE },
|
|
|
|
{ "middle_right", MIDDLE_RIGHT },
|
2016-09-08 15:24:54 +00:00
|
|
|
{ "tl", TOP_LEFT },
|
|
|
|
{ "tr", TOP_RIGHT },
|
|
|
|
{ "tm", TOP_MIDDLE },
|
|
|
|
{ "bl", BOTTOM_LEFT },
|
|
|
|
{ "br", BOTTOM_RIGHT },
|
|
|
|
{ "bm", BOTTOM_MIDDLE },
|
|
|
|
{ "ml", MIDDLE_LEFT },
|
|
|
|
{ "mm", MIDDLE_MIDDLE },
|
|
|
|
{ "mr", MIDDLE_RIGHT },
|
2010-03-10 20:02:13 +00:00
|
|
|
{ "none", NONE }
|
|
|
|
};
|
|
|
|
|
2010-11-23 12:58:53 +00:00
|
|
|
#ifdef OWN_WINDOW
|
2010-03-10 20:02:13 +00:00
|
|
|
template<>
|
|
|
|
conky::lua_traits<window_type>::Map conky::lua_traits<window_type>::map = {
|
|
|
|
{ "normal", TYPE_NORMAL },
|
|
|
|
{ "dock", TYPE_DOCK },
|
|
|
|
{ "panel", TYPE_PANEL },
|
|
|
|
{ "desktop", TYPE_DESKTOP },
|
|
|
|
{ "override", TYPE_OVERRIDE }
|
|
|
|
};
|
|
|
|
|
|
|
|
template<>
|
|
|
|
conky::lua_traits<window_hints>::Map conky::lua_traits<window_hints>::map = {
|
|
|
|
{ "undecorated", HINT_UNDECORATED },
|
|
|
|
{ "below", HINT_BELOW },
|
|
|
|
{ "above", HINT_ABOVE },
|
|
|
|
{ "sticky", HINT_STICKY },
|
|
|
|
{ "skip_taskbar", HINT_SKIP_TASKBAR },
|
|
|
|
{ "skip_pager", HINT_SKIP_PAGER }
|
|
|
|
};
|
|
|
|
|
|
|
|
std::pair<uint16_t, bool>
|
|
|
|
window_hints_traits::convert(lua::state &l, int index, const std::string &name)
|
|
|
|
{
|
|
|
|
typedef conky::lua_traits<window_hints> Traits;
|
|
|
|
|
|
|
|
lua::stack_sentry s(l);
|
|
|
|
l.checkstack(1);
|
|
|
|
|
|
|
|
std::string hints = l.tostring(index);
|
|
|
|
// add a sentinel to simplify the following loop
|
|
|
|
hints += ',';
|
|
|
|
size_t pos = 0;
|
|
|
|
size_t newpos;
|
|
|
|
uint16_t ret = 0;
|
|
|
|
while((newpos = hints.find_first_of(", ", pos)) != std::string::npos) {
|
|
|
|
if(newpos > pos) {
|
|
|
|
l.pushstring(hints.substr(pos, newpos-pos));
|
|
|
|
auto t = conky::lua_traits<window_hints>::convert(l, -1, name);
|
|
|
|
if(not t.second)
|
|
|
|
return {0, false};
|
|
|
|
SET_HINT(ret, t.first);
|
|
|
|
l.pop();
|
|
|
|
}
|
|
|
|
pos = newpos+1;
|
|
|
|
}
|
|
|
|
return {ret, true};
|
|
|
|
}
|
2010-11-23 12:58:53 +00:00
|
|
|
#endif
|
2010-03-10 20:02:13 +00:00
|
|
|
|
|
|
|
namespace {
|
|
|
|
// used to set the default value for own_window_title
|
|
|
|
std::string gethostnamecxx()
|
|
|
|
{ update_uname(); return info.uname_s.nodename; }
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* The order of these settings cannot be completely arbitrary. Some of them depend on others, and
|
2010-04-23 19:54:40 +00:00
|
|
|
* the setters are called in the order in which they are defined. The order should be:
|
2010-03-10 20:02:13 +00:00
|
|
|
* display_name -> out_to_x -> everything colour related
|
2010-08-29 12:31:22 +00:00
|
|
|
* -> border_*, own_window_*, etc -> own_window -> double_buffer -> imlib_cache_size
|
2010-03-10 20:02:13 +00:00
|
|
|
*/
|
|
|
|
|
2011-10-23 20:26:15 +00:00
|
|
|
conky::simple_config_setting<alignment> text_alignment("alignment", BOTTOM_LEFT, false);
|
2010-03-10 20:02:13 +00:00
|
|
|
conky::simple_config_setting<std::string> display_name("display", std::string(), false);
|
2015-12-01 12:53:43 +00:00
|
|
|
static conky::simple_config_setting<int> head_index("xinerama_head", 0, true);
|
2010-03-10 20:02:13 +00:00
|
|
|
priv::out_to_x_setting out_to_x;
|
|
|
|
|
2010-03-11 10:28:12 +00:00
|
|
|
priv::colour_setting color[10] = {
|
|
|
|
{ "color0", 0xffffff },
|
|
|
|
{ "color1", 0xffffff },
|
|
|
|
{ "color2", 0xffffff },
|
|
|
|
{ "color3", 0xffffff },
|
|
|
|
{ "color4", 0xffffff },
|
|
|
|
{ "color5", 0xffffff },
|
|
|
|
{ "color6", 0xffffff },
|
|
|
|
{ "color7", 0xffffff },
|
|
|
|
{ "color8", 0xffffff },
|
|
|
|
{ "color9", 0xffffff }
|
|
|
|
};
|
2010-03-11 11:08:55 +00:00
|
|
|
priv::colour_setting default_color("default_color", 0xffffff);
|
|
|
|
priv::colour_setting default_shade_color("default_shade_color", 0x000000);
|
|
|
|
priv::colour_setting default_outline_color("default_outline_color", 0x000000);
|
2010-03-11 10:28:12 +00:00
|
|
|
|
2010-04-22 19:59:12 +00:00
|
|
|
conky::range_config_setting<int> border_inner_margin("border_inner_margin", 0,
|
|
|
|
std::numeric_limits<int>::max(), 3, true);
|
|
|
|
conky::range_config_setting<int> border_outer_margin("border_outer_margin", 0,
|
|
|
|
std::numeric_limits<int>::max(), 1, true);
|
2010-04-22 23:22:22 +00:00
|
|
|
conky::range_config_setting<int> border_width("border_width", 0,
|
|
|
|
std::numeric_limits<int>::max(), 1, true);
|
2010-04-21 17:33:39 +00:00
|
|
|
#ifdef BUILD_XFT
|
|
|
|
conky::simple_config_setting<bool> use_xft("use_xft", false, false);
|
|
|
|
#endif
|
|
|
|
|
2010-03-10 20:02:13 +00:00
|
|
|
#ifdef OWN_WINDOW
|
|
|
|
conky::simple_config_setting<bool> set_transparent("own_window_transparent", false, false);
|
|
|
|
conky::simple_config_setting<std::string> own_window_class("own_window_class",
|
|
|
|
PACKAGE_NAME, false);
|
|
|
|
|
|
|
|
conky::simple_config_setting<std::string> own_window_title("own_window_title",
|
|
|
|
PACKAGE_NAME " (" + gethostnamecxx()+")", false);
|
|
|
|
|
|
|
|
conky::simple_config_setting<window_type> own_window_type("own_window_type", TYPE_NORMAL, false);
|
|
|
|
conky::simple_config_setting<uint16_t, window_hints_traits>
|
|
|
|
own_window_hints("own_window_hints", 0, false);
|
|
|
|
|
2010-11-23 22:18:50 +00:00
|
|
|
priv::colour_setting background_colour("own_window_colour", 0);
|
2010-03-10 20:02:13 +00:00
|
|
|
|
|
|
|
#ifdef BUILD_ARGB
|
|
|
|
conky::simple_config_setting<bool> use_argb_visual("own_window_argb_visual", false, false);
|
|
|
|
conky::range_config_setting<int> own_window_argb_value("own_window_argb_value",
|
|
|
|
0, 255, 255, false);
|
|
|
|
#endif
|
|
|
|
#endif /*OWN_WINDOW*/
|
2010-04-23 19:54:40 +00:00
|
|
|
priv::own_window_setting own_window;
|
|
|
|
|
|
|
|
#ifdef BUILD_XDBE
|
|
|
|
priv::use_xdbe_setting use_xdbe;
|
2012-04-11 16:06:47 +00:00
|
|
|
#else
|
|
|
|
priv::use_xpmdb_setting use_xpmdb;
|
2010-04-23 19:54:40 +00:00
|
|
|
#endif
|
|
|
|
|
2010-08-29 12:31:22 +00:00
|
|
|
#ifdef BUILD_IMLIB2
|
|
|
|
/*
|
|
|
|
* the only reason this is not in imlib2.cc is so that we can be sure it's setter executes after
|
|
|
|
* use_xdbe
|
|
|
|
*/
|
|
|
|
imlib_cache_size_setting imlib_cache_size;
|
|
|
|
#endif
|
2010-03-10 20:02:13 +00:00
|
|
|
/******************** </SETTINGS> ************************/
|
2005-07-20 00:30:40 +00:00
|
|
|
|
2010-03-10 19:01:26 +00:00
|
|
|
#ifdef DEBUG
|
|
|
|
/* WARNING, this type not in Xlib spec */
|
|
|
|
static int __attribute__((noreturn)) x11_error_handler(Display *d, XErrorEvent *err)
|
|
|
|
{
|
|
|
|
NORM_ERR("X Error: type %i Display %lx XID %li serial %lu error_code %i request_code %i minor_code %i other Display: %lx\n",
|
|
|
|
err->type,
|
|
|
|
(long unsigned)err->display,
|
|
|
|
(long)err->resourceid,
|
|
|
|
err->serial,
|
|
|
|
err->error_code,
|
|
|
|
err->request_code,
|
|
|
|
err->minor_code,
|
|
|
|
(long unsigned)d
|
|
|
|
);
|
|
|
|
abort();
|
|
|
|
}
|
|
|
|
|
|
|
|
static int __attribute__((noreturn)) x11_ioerror_handler(Display *d)
|
|
|
|
{
|
|
|
|
NORM_ERR("X Error: Display %lx\n",
|
|
|
|
(long unsigned)d
|
|
|
|
);
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
#endif /* DEBUG */
|
|
|
|
|
2005-07-20 00:30:40 +00:00
|
|
|
/* X11 initializer */
|
2010-03-10 19:01:26 +00:00
|
|
|
static void init_X11()
|
2005-07-20 00:30:40 +00:00
|
|
|
{
|
2009-06-07 04:53:40 +00:00
|
|
|
if (!display) {
|
2010-03-04 17:31:28 +00:00
|
|
|
const std::string &dispstr = display_name.get(*state).c_str();
|
|
|
|
// passing NULL to XOpenDisplay should open the default display
|
|
|
|
const char *disp = dispstr.size() ? dispstr.c_str() : NULL;
|
2009-06-07 04:53:40 +00:00
|
|
|
if ((display = XOpenDisplay(disp)) == NULL) {
|
2010-03-10 19:01:26 +00:00
|
|
|
throw std::runtime_error(std::string("can't open display: ") + XDisplayName(disp));
|
2009-06-07 04:53:40 +00:00
|
|
|
}
|
2008-02-20 20:30:45 +00:00
|
|
|
}
|
2005-07-20 00:30:40 +00:00
|
|
|
|
2010-03-10 19:01:26 +00:00
|
|
|
info.x11.monitor.number = 1;
|
|
|
|
info.x11.monitor.current = 0;
|
|
|
|
info.x11.desktop.current = 1;
|
|
|
|
info.x11.desktop.number = 1;
|
|
|
|
info.x11.desktop.all_names.clear();
|
|
|
|
info.x11.desktop.name.clear();
|
|
|
|
|
2005-07-20 00:30:40 +00:00
|
|
|
screen = DefaultScreen(display);
|
|
|
|
display_width = DisplayWidth(display, screen);
|
|
|
|
display_height = DisplayHeight(display, screen);
|
|
|
|
|
2009-07-14 14:57:51 +00:00
|
|
|
get_x11_desktop_info(display, 0);
|
|
|
|
|
2005-07-20 00:30:40 +00:00
|
|
|
update_workarea();
|
2010-03-10 19:01:26 +00:00
|
|
|
|
|
|
|
#ifdef DEBUG
|
|
|
|
_Xdebug = 1;
|
|
|
|
/* WARNING, this type not in Xlib spec */
|
|
|
|
XSetErrorHandler(&x11_error_handler);
|
|
|
|
XSetIOErrorHandler(&x11_ioerror_handler);
|
|
|
|
#endif /* DEBUG */
|
|
|
|
}
|
|
|
|
|
|
|
|
static void deinit_X11()
|
|
|
|
{
|
|
|
|
XCloseDisplay(display);
|
|
|
|
display = NULL;
|
2005-07-20 00:30:40 +00:00
|
|
|
}
|
|
|
|
|
2008-03-29 02:01:03 +00:00
|
|
|
static void update_workarea(void)
|
2005-07-20 00:30:40 +00:00
|
|
|
{
|
|
|
|
/* default work area is display */
|
|
|
|
workarea[0] = 0;
|
|
|
|
workarea[1] = 0;
|
|
|
|
workarea[2] = display_width;
|
|
|
|
workarea[3] = display_height;
|
2015-12-01 12:53:43 +00:00
|
|
|
|
|
|
|
#ifdef BUILD_XINERAMA
|
|
|
|
/* if xinerama is being used, adjust workarea to the head's area */
|
|
|
|
int useless1, useless2;
|
|
|
|
if (!XineramaQueryExtension(display, &useless1, &useless2)) {
|
|
|
|
return; /* doesn't even have xinerama */
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!XineramaIsActive(display)) {
|
|
|
|
return; /* has xinerama but isn't using it */
|
|
|
|
}
|
|
|
|
|
|
|
|
int heads = 0;
|
|
|
|
XineramaScreenInfo *si = XineramaQueryScreens(display, &heads);
|
|
|
|
if (!si) {
|
|
|
|
NORM_ERR("warning: XineramaQueryScreen returned NULL, ignoring head settings");
|
|
|
|
return; /* queryscreens failed? */
|
|
|
|
}
|
|
|
|
|
|
|
|
int i = head_index.get(*state);
|
|
|
|
if (i < 0 || i >= heads) {
|
|
|
|
NORM_ERR("warning: invalid head index, ignoring head settings");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
XineramaScreenInfo *ps = &si[i];
|
|
|
|
workarea[0] = ps->x_org;
|
|
|
|
workarea[1] = ps->y_org;
|
|
|
|
workarea[2] = workarea[0] + ps->width;
|
2017-02-11 21:39:18 +00:00
|
|
|
workarea[3] = workarea[1] + ps->height;
|
|
|
|
XFree(si);
|
2015-12-01 12:53:43 +00:00
|
|
|
|
|
|
|
DBGP("Fixed xinerama area to: %d %d %d %d",
|
|
|
|
workarea[0], workarea[1], workarea[2], workarea[3]);
|
|
|
|
#endif
|
2005-07-20 00:30:40 +00:00
|
|
|
}
|
|
|
|
|
2008-02-20 20:30:45 +00:00
|
|
|
/* Find root window and desktop window.
|
|
|
|
* Return desktop window on success,
|
|
|
|
* and set root and desktop byref return values.
|
|
|
|
* Return 0 on failure. */
|
2006-03-07 19:46:51 +00:00
|
|
|
static Window find_desktop_window(Window *p_root, Window *p_desktop)
|
2005-07-20 00:30:40 +00:00
|
|
|
{
|
|
|
|
Atom type;
|
|
|
|
int format, i;
|
|
|
|
unsigned long nitems, bytes;
|
|
|
|
unsigned int n;
|
|
|
|
Window root = RootWindow(display, screen);
|
|
|
|
Window win = root;
|
|
|
|
Window troot, parent, *children;
|
|
|
|
unsigned char *buf = NULL;
|
|
|
|
|
2008-02-20 20:30:45 +00:00
|
|
|
if (!p_root || !p_desktop) {
|
|
|
|
return 0;
|
|
|
|
}
|
2006-03-07 19:46:51 +00:00
|
|
|
|
2005-07-20 00:30:40 +00:00
|
|
|
/* some window managers set __SWM_VROOT to some child of root window */
|
|
|
|
|
|
|
|
XQueryTree(display, root, &troot, &parent, &children, &n);
|
|
|
|
for (i = 0; i < (int) n; i++) {
|
2008-02-20 20:30:45 +00:00
|
|
|
if (XGetWindowProperty(display, children[i], ATOM(__SWM_VROOT), 0, 1,
|
2009-07-27 21:34:06 +00:00
|
|
|
False, XA_WINDOW, &type, &format, &nitems, &bytes, &buf)
|
2008-02-20 20:30:45 +00:00
|
|
|
== Success && type == XA_WINDOW) {
|
2005-07-20 00:30:40 +00:00
|
|
|
win = *(Window *) buf;
|
|
|
|
XFree(buf);
|
|
|
|
XFree(children);
|
|
|
|
fprintf(stderr,
|
2009-07-27 21:34:06 +00:00
|
|
|
PACKAGE_NAME": desktop window (%lx) found from __SWM_VROOT property\n",
|
|
|
|
win);
|
2006-03-06 23:35:41 +00:00
|
|
|
fflush(stderr);
|
2008-02-20 20:30:45 +00:00
|
|
|
*p_root = win;
|
|
|
|
*p_desktop = win;
|
2005-07-20 00:30:40 +00:00
|
|
|
return win;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (buf) {
|
|
|
|
XFree(buf);
|
|
|
|
buf = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
XFree(children);
|
|
|
|
|
|
|
|
/* get subwindows from root */
|
|
|
|
win = find_subwindow(root, -1, -1);
|
|
|
|
|
|
|
|
update_workarea();
|
|
|
|
|
|
|
|
win = find_subwindow(win, workarea[2], workarea[3]);
|
|
|
|
|
|
|
|
if (buf) {
|
|
|
|
XFree(buf);
|
|
|
|
buf = 0;
|
|
|
|
}
|
|
|
|
|
2008-02-20 20:30:45 +00:00
|
|
|
if (win != root) {
|
2005-07-20 00:30:40 +00:00
|
|
|
fprintf(stderr,
|
2009-07-27 21:34:06 +00:00
|
|
|
PACKAGE_NAME": desktop window (%lx) is subwindow of root window (%lx)\n",
|
|
|
|
win, root);
|
2008-02-20 20:30:45 +00:00
|
|
|
} else {
|
2008-07-12 10:25:05 +00:00
|
|
|
fprintf(stderr, PACKAGE_NAME": desktop window (%lx) is root window\n", win);
|
2008-02-20 20:30:45 +00:00
|
|
|
}
|
2005-07-20 00:30:40 +00:00
|
|
|
|
2006-03-06 23:35:41 +00:00
|
|
|
fflush(stderr);
|
2006-03-07 19:46:51 +00:00
|
|
|
|
2008-02-20 20:30:45 +00:00
|
|
|
*p_root = root;
|
|
|
|
*p_desktop = win;
|
2006-03-07 19:46:51 +00:00
|
|
|
|
2005-07-20 00:30:40 +00:00
|
|
|
return win;
|
|
|
|
}
|
|
|
|
|
2010-11-23 12:58:53 +00:00
|
|
|
#ifdef OWN_WINDOW
|
2010-02-28 14:51:01 +00:00
|
|
|
namespace {
|
|
|
|
/* helper function for set_transparent_background() */
|
|
|
|
void do_set_background(Window win, int argb)
|
|
|
|
{
|
2010-03-10 20:02:13 +00:00
|
|
|
unsigned long colour = background_colour.get(*state) | (argb<<24);
|
|
|
|
XSetWindowBackground(display, win, colour);
|
2010-02-28 14:51:01 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-01-01 23:01:51 +00:00
|
|
|
/* if no argb visual is configured sets background to ParentRelative for the Window and all parents,
|
|
|
|
else real transparency is used */
|
2010-02-27 21:28:33 +00:00
|
|
|
void set_transparent_background(Window win)
|
2005-07-20 00:30:40 +00:00
|
|
|
{
|
2010-01-07 02:38:12 +00:00
|
|
|
#ifdef BUILD_ARGB
|
2010-01-01 23:01:51 +00:00
|
|
|
if (have_argb_visual) {
|
|
|
|
// real transparency
|
2010-03-10 20:02:13 +00:00
|
|
|
do_set_background(win, set_transparent.get(*state) ? 0 : own_window_argb_value.get(*state));
|
2010-01-01 23:01:51 +00:00
|
|
|
} else {
|
2010-01-07 02:38:12 +00:00
|
|
|
#endif /* BUILD_ARGB */
|
2010-01-01 23:01:51 +00:00
|
|
|
// pseudo transparency
|
|
|
|
|
2010-02-26 17:38:15 +00:00
|
|
|
if (set_transparent.get(*state)) {
|
2005-08-25 09:24:26 +00:00
|
|
|
Window parent = win;
|
|
|
|
unsigned int i;
|
2008-02-20 20:30:45 +00:00
|
|
|
|
2005-08-26 02:16:35 +00:00
|
|
|
for (i = 0; i < 50 && parent != RootWindow(display, screen); i++) {
|
2005-08-25 09:24:26 +00:00
|
|
|
Window r, *children;
|
|
|
|
unsigned int n;
|
2008-02-20 20:30:45 +00:00
|
|
|
|
2005-08-25 09:24:26 +00:00
|
|
|
XSetWindowBackgroundPixmap(display, parent, ParentRelative);
|
2008-02-20 20:30:45 +00:00
|
|
|
|
2005-08-25 09:24:26 +00:00
|
|
|
XQueryTree(display, parent, &r, &parent, &children, &n);
|
|
|
|
XFree(children);
|
2008-02-20 20:30:45 +00:00
|
|
|
}
|
2010-02-28 14:51:01 +00:00
|
|
|
} else
|
|
|
|
do_set_background(win, 0);
|
2010-01-07 02:38:12 +00:00
|
|
|
#ifdef BUILD_ARGB
|
2010-01-01 23:01:51 +00:00
|
|
|
}
|
2010-01-07 02:38:12 +00:00
|
|
|
#endif /* BUILD_ARGB */
|
2010-01-01 23:01:51 +00:00
|
|
|
}
|
2010-11-23 12:58:53 +00:00
|
|
|
#endif
|
2010-01-01 23:01:51 +00:00
|
|
|
|
2010-01-07 02:38:12 +00:00
|
|
|
#ifdef BUILD_ARGB
|
2010-01-01 23:01:51 +00:00
|
|
|
static int get_argb_visual(Visual** visual, int *depth) {
|
|
|
|
/* code from gtk project, gdk_screen_get_rgba_visual */
|
|
|
|
XVisualInfo visual_template;
|
|
|
|
XVisualInfo *visual_list;
|
|
|
|
int nxvisuals = 0, i;
|
|
|
|
|
|
|
|
visual_template.screen = screen;
|
|
|
|
visual_list = XGetVisualInfo (display, VisualScreenMask,
|
|
|
|
&visual_template, &nxvisuals);
|
|
|
|
for (i = 0; i < nxvisuals; i++) {
|
|
|
|
if (visual_list[i].depth == 32 &&
|
|
|
|
(visual_list[i].red_mask == 0xff0000 &&
|
|
|
|
visual_list[i].green_mask == 0x00ff00 &&
|
|
|
|
visual_list[i].blue_mask == 0x0000ff)) {
|
|
|
|
*visual = visual_list[i].visual;
|
|
|
|
*depth = visual_list[i].depth;
|
2010-01-02 19:43:29 +00:00
|
|
|
DBGP("Found ARGB Visual");
|
2010-01-02 22:22:46 +00:00
|
|
|
XFree(visual_list);
|
2010-01-01 23:01:51 +00:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// no argb visual available
|
2010-01-02 19:43:29 +00:00
|
|
|
DBGP("No ARGB Visual found");
|
2010-01-02 22:22:46 +00:00
|
|
|
XFree(visual_list);
|
2010-01-01 23:01:51 +00:00
|
|
|
return 0;
|
2005-07-20 00:30:40 +00:00
|
|
|
}
|
2010-01-07 02:38:12 +00:00
|
|
|
#endif /* BUILD_ARGB */
|
2005-07-20 00:30:40 +00:00
|
|
|
|
2009-05-20 03:34:43 +00:00
|
|
|
void destroy_window(void)
|
|
|
|
{
|
2010-01-07 02:38:12 +00:00
|
|
|
#ifdef BUILD_XFT
|
2009-07-15 14:33:18 +00:00
|
|
|
if(window.xftdraw) {
|
|
|
|
XftDrawDestroy(window.xftdraw);
|
|
|
|
}
|
2010-01-07 02:38:12 +00:00
|
|
|
#endif /* BUILD_XFT */
|
2009-07-15 14:33:18 +00:00
|
|
|
if(window.gc) {
|
|
|
|
XFreeGC(display, window.gc);
|
|
|
|
}
|
2009-05-20 03:34:43 +00:00
|
|
|
memset(&window, 0, sizeof(struct conky_window));
|
|
|
|
}
|
|
|
|
|
2010-11-23 15:43:14 +00:00
|
|
|
static void init_window(lua::state &l __attribute__((unused)), bool own)
|
2005-07-20 00:30:40 +00:00
|
|
|
{
|
2010-04-23 15:35:41 +00:00
|
|
|
// own is unused if OWN_WINDOW is not defined
|
|
|
|
(void) own;
|
|
|
|
|
2009-11-21 14:45:00 +00:00
|
|
|
window_created = 1;
|
2005-07-20 00:30:40 +00:00
|
|
|
|
2006-02-14 06:15:38 +00:00
|
|
|
#ifdef OWN_WINDOW
|
2010-04-23 15:35:41 +00:00
|
|
|
if (own) {
|
Enable X11 backing store
In our XCreateWindow call, we always set the backing_store attribute
to 'Always'. But since we never add the CWBackingStore to our value
mask, the backing_store setting always gets set to the default
NotUseful. This means that the backing store is never turned on, and
so when unobscuring the conky window, portions of the display will not
be drawn immediately if conky is blocked doing something else (e.g.
network, disk, the process is stopped), which is really annoying.
To fix this, specify the CWBackingStore flag in our value mask, so the
conky data is always visible, even if conky is blocking on some other
operation.
2014-10-26 00:04:48 +00:00
|
|
|
int depth = 0, flags = CWOverrideRedirect | CWBackingStore;
|
2010-01-01 23:01:51 +00:00
|
|
|
Visual *visual = NULL;
|
|
|
|
|
2008-02-20 20:30:45 +00:00
|
|
|
if (!find_desktop_window(&window.root, &window.desktop)) {
|
|
|
|
return;
|
|
|
|
}
|
2010-01-01 23:01:51 +00:00
|
|
|
|
2010-01-07 02:38:12 +00:00
|
|
|
#ifdef BUILD_ARGB
|
2010-04-23 15:35:41 +00:00
|
|
|
if (use_argb_visual.get(l) && get_argb_visual(&visual, &depth)) {
|
2010-02-26 17:29:46 +00:00
|
|
|
have_argb_visual = true;
|
2010-01-01 23:01:51 +00:00
|
|
|
window.visual = visual;
|
|
|
|
window.colourmap = XCreateColormap(display,
|
|
|
|
DefaultRootWindow(display), window.visual, AllocNone);
|
|
|
|
} else {
|
2010-01-07 02:38:12 +00:00
|
|
|
#endif /* BUILD_ARGB */
|
2010-01-01 23:01:51 +00:00
|
|
|
window.visual = DefaultVisual(display, screen);
|
|
|
|
window.colourmap = DefaultColormap(display, screen);
|
|
|
|
depth = CopyFromParent;
|
|
|
|
visual = CopyFromParent;
|
2010-01-07 02:38:12 +00:00
|
|
|
#ifdef BUILD_ARGB
|
2010-01-01 23:01:51 +00:00
|
|
|
}
|
2010-01-07 02:38:12 +00:00
|
|
|
#endif /* BUILD_ARGB */
|
2006-03-09 18:51:57 +00:00
|
|
|
|
2010-04-23 15:35:41 +00:00
|
|
|
int b = border_inner_margin.get(l) + border_width.get(l)
|
|
|
|
+ border_outer_margin.get(l);
|
2015-07-31 06:22:20 +00:00
|
|
|
|
|
|
|
/* Sanity check to avoid making an invalid 0x0 window */
|
|
|
|
if (b == 0) {
|
|
|
|
b = 1;
|
|
|
|
}
|
2010-04-23 15:35:41 +00:00
|
|
|
|
|
|
|
if (own_window_type.get(l) == TYPE_OVERRIDE) {
|
2006-03-09 18:51:57 +00:00
|
|
|
|
2008-02-20 20:30:45 +00:00
|
|
|
/* An override_redirect True window.
|
|
|
|
* No WM hints or button processing needed. */
|
|
|
|
XSetWindowAttributes attrs = { ParentRelative, 0L, 0, 0L, 0, 0,
|
|
|
|
Always, 0L, 0L, False, StructureNotifyMask | ExposureMask, 0L,
|
|
|
|
True, 0, 0 };
|
2010-01-07 02:38:12 +00:00
|
|
|
#ifdef BUILD_ARGB
|
2010-01-01 23:01:51 +00:00
|
|
|
if (have_argb_visual) {
|
|
|
|
attrs.colormap = window.colourmap;
|
2014-10-25 23:59:25 +00:00
|
|
|
flags |= CWBorderPixel | CWColormap;
|
2010-01-01 23:01:51 +00:00
|
|
|
} else {
|
2010-01-07 02:38:12 +00:00
|
|
|
#endif /* BUILD_ARGB */
|
2014-10-25 23:59:25 +00:00
|
|
|
flags |= CWBackPixel;
|
2010-01-07 02:38:12 +00:00
|
|
|
#ifdef BUILD_ARGB
|
2010-01-01 23:01:51 +00:00
|
|
|
}
|
2010-01-07 02:38:12 +00:00
|
|
|
#endif /* BUILD_ARGB */
|
2006-03-09 18:51:57 +00:00
|
|
|
|
2008-02-20 20:30:45 +00:00
|
|
|
/* Parent is desktop window (which might be a child of root) */
|
|
|
|
window.window = XCreateWindow(display, window.desktop, window.x,
|
2010-04-23 15:35:41 +00:00
|
|
|
window.y, b, b, 0, depth, InputOutput, visual,
|
2010-01-01 23:01:51 +00:00
|
|
|
flags, &attrs);
|
2006-03-09 18:51:57 +00:00
|
|
|
|
2008-02-20 20:30:45 +00:00
|
|
|
XLowerWindow(display, window.window);
|
2006-03-09 18:51:57 +00:00
|
|
|
|
2008-07-12 10:25:05 +00:00
|
|
|
fprintf(stderr, PACKAGE_NAME": window type - override\n");
|
2008-02-20 20:30:45 +00:00
|
|
|
fflush(stderr);
|
2010-04-23 15:35:41 +00:00
|
|
|
} else { /* own_window_type.get(l) != TYPE_OVERRIDE */
|
2006-03-09 18:51:57 +00:00
|
|
|
|
2008-02-20 20:30:45 +00:00
|
|
|
/* A window managed by the window manager.
|
|
|
|
* Process hints and buttons. */
|
|
|
|
XSetWindowAttributes attrs = { ParentRelative, 0L, 0, 0L, 0, 0,
|
|
|
|
Always, 0L, 0L, False, StructureNotifyMask | ExposureMask |
|
2009-07-27 21:34:06 +00:00
|
|
|
ButtonPressMask | ButtonReleaseMask, 0L, False, 0, 0 };
|
2006-03-06 05:58:58 +00:00
|
|
|
|
|
|
|
XClassHint classHint;
|
|
|
|
XWMHints wmHint;
|
2006-03-06 23:35:41 +00:00
|
|
|
Atom xa;
|
2010-01-01 23:01:51 +00:00
|
|
|
|
2010-01-07 02:38:12 +00:00
|
|
|
#ifdef BUILD_ARGB
|
2010-01-01 23:01:51 +00:00
|
|
|
if (have_argb_visual) {
|
|
|
|
attrs.colormap = window.colourmap;
|
2014-10-25 23:59:25 +00:00
|
|
|
flags |= CWBorderPixel | CWColormap;
|
2010-01-01 23:01:51 +00:00
|
|
|
} else {
|
2010-01-07 02:38:12 +00:00
|
|
|
#endif /* BUILD_ARGB */
|
2014-10-25 23:59:25 +00:00
|
|
|
flags |= CWBackPixel;
|
2010-01-07 02:38:12 +00:00
|
|
|
#ifdef BUILD_ARGB
|
2010-01-01 23:01:51 +00:00
|
|
|
}
|
2010-01-07 02:38:12 +00:00
|
|
|
#endif /* BUILD_ARGB */
|
2005-07-20 00:30:40 +00:00
|
|
|
|
2010-04-23 15:35:41 +00:00
|
|
|
if (own_window_type.get(l) == TYPE_DOCK) {
|
2008-12-07 20:44:56 +00:00
|
|
|
window.x = window.y = 0;
|
|
|
|
}
|
2006-03-09 18:51:57 +00:00
|
|
|
/* Parent is root window so WM can take control */
|
2008-02-20 20:30:45 +00:00
|
|
|
window.window = XCreateWindow(display, window.root, window.x,
|
2010-04-23 15:35:41 +00:00
|
|
|
window.y, b, b, 0, depth, InputOutput, visual,
|
2010-01-01 23:01:51 +00:00
|
|
|
flags, &attrs);
|
2006-01-26 01:27:41 +00:00
|
|
|
|
2010-02-26 16:42:56 +00:00
|
|
|
// class_name must be a named local variable, so that c_str() remains valid until we
|
|
|
|
// call XmbSetWMProperties(). We use const_cast because, for whatever reason,
|
|
|
|
// res_name is not declared as const char *. XmbSetWMProperties hopefully doesn't
|
|
|
|
// modify the value (hell, even their own example app assigns a literal string
|
|
|
|
// constant to the field)
|
2010-04-23 15:35:41 +00:00
|
|
|
const std::string &class_name = own_window_class.get(l);
|
2010-02-26 16:42:56 +00:00
|
|
|
|
|
|
|
classHint.res_name = const_cast<char *>(class_name.c_str());
|
2006-03-06 05:58:58 +00:00
|
|
|
classHint.res_class = classHint.res_name;
|
|
|
|
|
2010-04-23 15:35:41 +00:00
|
|
|
uint16_t hints = own_window_hints.get(l);
|
2010-03-02 19:30:15 +00:00
|
|
|
|
2006-03-06 05:58:58 +00:00
|
|
|
wmHint.flags = InputHint | StateHint;
|
2008-02-20 20:30:45 +00:00
|
|
|
/* allow decorated windows to be given input focus by WM */
|
|
|
|
wmHint.input =
|
2010-03-02 19:30:15 +00:00
|
|
|
TEST_HINT(hints, HINT_UNDECORATED) ? False : True;
|
2010-04-23 15:35:41 +00:00
|
|
|
if (own_window_type.get(l) == TYPE_DOCK || own_window_type.get(l) == TYPE_PANEL) {
|
2009-06-13 21:36:28 +00:00
|
|
|
wmHint.initial_state = WithdrawnState;
|
2009-07-27 21:34:06 +00:00
|
|
|
} else {
|
2009-06-13 21:36:28 +00:00
|
|
|
wmHint.initial_state = NormalState;
|
2009-07-27 21:34:06 +00:00
|
|
|
}
|
2006-03-06 05:58:58 +00:00
|
|
|
|
2010-04-23 15:35:41 +00:00
|
|
|
XmbSetWMProperties(display, window.window, NULL, NULL, argv_copy,
|
|
|
|
argc_copy, NULL, &wmHint, &classHint);
|
|
|
|
XStoreName(display, window.window, own_window_title.get(l).c_str() );
|
2006-03-06 05:58:58 +00:00
|
|
|
|
|
|
|
/* Sets an empty WM_PROTOCOLS property */
|
2008-02-20 20:30:45 +00:00
|
|
|
XSetWMProtocols(display, window.window, NULL, 0);
|
2006-03-06 23:35:41 +00:00
|
|
|
|
2006-03-08 22:17:27 +00:00
|
|
|
/* Set window type */
|
2008-02-20 20:30:45 +00:00
|
|
|
if ((xa = ATOM(_NET_WM_WINDOW_TYPE)) != None) {
|
2006-03-08 22:17:27 +00:00
|
|
|
Atom prop;
|
2008-02-20 20:30:45 +00:00
|
|
|
|
2010-04-23 15:35:41 +00:00
|
|
|
switch (own_window_type.get(l)) {
|
2008-02-20 20:30:45 +00:00
|
|
|
case TYPE_DESKTOP:
|
|
|
|
prop = ATOM(_NET_WM_WINDOW_TYPE_DESKTOP);
|
2008-07-12 10:25:05 +00:00
|
|
|
fprintf(stderr, PACKAGE_NAME": window type - desktop\n");
|
2008-02-20 20:30:45 +00:00
|
|
|
fflush(stderr);
|
|
|
|
break;
|
2008-04-29 21:31:04 +00:00
|
|
|
case TYPE_DOCK:
|
|
|
|
prop = ATOM(_NET_WM_WINDOW_TYPE_DOCK);
|
2008-07-12 10:25:05 +00:00
|
|
|
fprintf(stderr, PACKAGE_NAME": window type - dock\n");
|
2008-04-29 21:31:04 +00:00
|
|
|
fflush(stderr);
|
|
|
|
break;
|
2009-06-13 21:36:28 +00:00
|
|
|
case TYPE_PANEL:
|
|
|
|
prop = ATOM(_NET_WM_WINDOW_TYPE_DOCK);
|
|
|
|
fprintf(stderr, PACKAGE_NAME": window type - panel\n");
|
|
|
|
fflush(stderr);
|
|
|
|
break;
|
2008-02-20 20:30:45 +00:00
|
|
|
case TYPE_NORMAL:
|
|
|
|
default:
|
|
|
|
prop = ATOM(_NET_WM_WINDOW_TYPE_NORMAL);
|
2008-07-12 10:25:05 +00:00
|
|
|
fprintf(stderr, PACKAGE_NAME": window type - normal\n");
|
2008-02-20 20:30:45 +00:00
|
|
|
fflush(stderr);
|
|
|
|
break;
|
2006-03-08 22:17:27 +00:00
|
|
|
}
|
2008-02-20 20:30:45 +00:00
|
|
|
XChangeProperty(display, window.window, xa, XA_ATOM, 32,
|
2009-07-27 21:34:06 +00:00
|
|
|
PropModeReplace, (unsigned char *) &prop, 1);
|
2006-03-06 23:35:41 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Set desired hints */
|
2008-02-20 20:30:45 +00:00
|
|
|
|
2006-03-06 23:35:41 +00:00
|
|
|
/* Window decorations */
|
2010-03-02 19:30:15 +00:00
|
|
|
if (TEST_HINT(hints, HINT_UNDECORATED)) {
|
2008-07-12 10:25:05 +00:00
|
|
|
/* fprintf(stderr, PACKAGE_NAME": hint - undecorated\n");
|
2009-07-27 21:34:06 +00:00
|
|
|
fflush(stderr); */
|
2008-02-20 20:30:45 +00:00
|
|
|
|
|
|
|
xa = ATOM(_MOTIF_WM_HINTS);
|
|
|
|
if (xa != None) {
|
|
|
|
long prop[5] = { 2, 0, 0, 0, 0 };
|
|
|
|
XChangeProperty(display, window.window, xa, xa, 32,
|
2009-07-27 21:34:06 +00:00
|
|
|
PropModeReplace, (unsigned char *) prop, 5);
|
2008-02-20 20:30:45 +00:00
|
|
|
}
|
2006-03-06 23:35:41 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Below other windows */
|
2010-03-02 19:30:15 +00:00
|
|
|
if (TEST_HINT(hints, HINT_BELOW)) {
|
2008-07-12 10:25:05 +00:00
|
|
|
/* fprintf(stderr, PACKAGE_NAME": hint - below\n");
|
2009-07-27 21:34:06 +00:00
|
|
|
fflush(stderr); */
|
2008-02-20 20:30:45 +00:00
|
|
|
|
|
|
|
xa = ATOM(_WIN_LAYER);
|
|
|
|
if (xa != None) {
|
|
|
|
long prop = 0;
|
|
|
|
|
|
|
|
XChangeProperty(display, window.window, xa, XA_CARDINAL, 32,
|
2009-07-27 21:34:06 +00:00
|
|
|
PropModeAppend, (unsigned char *) &prop, 1);
|
2008-02-20 20:30:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
xa = ATOM(_NET_WM_STATE);
|
|
|
|
if (xa != None) {
|
|
|
|
Atom xa_prop = ATOM(_NET_WM_STATE_BELOW);
|
|
|
|
|
|
|
|
XChangeProperty(display, window.window, xa, XA_ATOM, 32,
|
2009-07-27 21:34:06 +00:00
|
|
|
PropModeAppend, (unsigned char *) &xa_prop, 1);
|
2008-02-20 20:30:45 +00:00
|
|
|
}
|
2006-03-06 23:35:41 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Above other windows */
|
2010-03-02 19:30:15 +00:00
|
|
|
if (TEST_HINT(hints, HINT_ABOVE)) {
|
2008-07-12 10:25:05 +00:00
|
|
|
/* fprintf(stderr, PACKAGE_NAME": hint - above\n");
|
2009-07-27 21:34:06 +00:00
|
|
|
fflush(stderr); */
|
2008-02-20 20:30:45 +00:00
|
|
|
|
|
|
|
xa = ATOM(_WIN_LAYER);
|
|
|
|
if (xa != None) {
|
|
|
|
long prop = 6;
|
|
|
|
|
|
|
|
XChangeProperty(display, window.window, xa, XA_CARDINAL, 32,
|
2009-07-27 21:34:06 +00:00
|
|
|
PropModeAppend, (unsigned char *) &prop, 1);
|
2008-02-20 20:30:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
xa = ATOM(_NET_WM_STATE);
|
|
|
|
if (xa != None) {
|
|
|
|
Atom xa_prop = ATOM(_NET_WM_STATE_ABOVE);
|
|
|
|
|
|
|
|
XChangeProperty(display, window.window, xa, XA_ATOM, 32,
|
2009-07-27 21:34:06 +00:00
|
|
|
PropModeAppend, (unsigned char *) &xa_prop, 1);
|
2008-02-20 20:30:45 +00:00
|
|
|
}
|
|
|
|
}
|
2006-03-06 23:35:41 +00:00
|
|
|
|
|
|
|
/* Sticky */
|
2010-03-02 19:30:15 +00:00
|
|
|
if (TEST_HINT(hints, HINT_STICKY)) {
|
2008-07-12 10:25:05 +00:00
|
|
|
/* fprintf(stderr, PACKAGE_NAME": hint - sticky\n");
|
2009-07-27 21:34:06 +00:00
|
|
|
fflush(stderr); */
|
2008-02-20 20:30:45 +00:00
|
|
|
|
|
|
|
xa = ATOM(_NET_WM_DESKTOP);
|
|
|
|
if (xa != None) {
|
|
|
|
CARD32 xa_prop = 0xFFFFFFFF;
|
|
|
|
|
|
|
|
XChangeProperty(display, window.window, xa, XA_CARDINAL, 32,
|
2009-07-27 21:34:06 +00:00
|
|
|
PropModeAppend, (unsigned char *) &xa_prop, 1);
|
2008-02-20 20:30:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
xa = ATOM(_NET_WM_STATE);
|
|
|
|
if (xa != None) {
|
|
|
|
Atom xa_prop = ATOM(_NET_WM_STATE_STICKY);
|
|
|
|
|
|
|
|
XChangeProperty(display, window.window, xa, XA_ATOM, 32,
|
2009-07-27 21:34:06 +00:00
|
|
|
PropModeAppend, (unsigned char *) &xa_prop, 1);
|
2008-02-20 20:30:45 +00:00
|
|
|
}
|
|
|
|
}
|
2006-03-06 23:35:41 +00:00
|
|
|
|
|
|
|
/* Skip taskbar */
|
2010-03-02 19:30:15 +00:00
|
|
|
if (TEST_HINT(hints, HINT_SKIP_TASKBAR)) {
|
2008-07-12 10:25:05 +00:00
|
|
|
/* fprintf(stderr, PACKAGE_NAME": hint - skip_taskbar\n");
|
2009-07-27 21:34:06 +00:00
|
|
|
fflush(stderr); */
|
2008-02-20 20:30:45 +00:00
|
|
|
|
|
|
|
xa = ATOM(_NET_WM_STATE);
|
|
|
|
if (xa != None) {
|
|
|
|
Atom xa_prop = ATOM(_NET_WM_STATE_SKIP_TASKBAR);
|
|
|
|
|
|
|
|
XChangeProperty(display, window.window, xa, XA_ATOM, 32,
|
2009-07-27 21:34:06 +00:00
|
|
|
PropModeAppend, (unsigned char *) &xa_prop, 1);
|
2008-02-20 20:30:45 +00:00
|
|
|
}
|
|
|
|
}
|
2006-03-06 23:35:41 +00:00
|
|
|
|
|
|
|
/* Skip pager */
|
2010-03-02 19:30:15 +00:00
|
|
|
if (TEST_HINT(hints, HINT_SKIP_PAGER)) {
|
2008-07-12 10:25:05 +00:00
|
|
|
/* fprintf(stderr, PACKAGE_NAME": hint - skip_pager\n");
|
2009-07-27 21:34:06 +00:00
|
|
|
fflush(stderr); */
|
2006-03-06 23:35:41 +00:00
|
|
|
|
2008-02-20 20:30:45 +00:00
|
|
|
xa = ATOM(_NET_WM_STATE);
|
|
|
|
if (xa != None) {
|
|
|
|
Atom xa_prop = ATOM(_NET_WM_STATE_SKIP_PAGER);
|
|
|
|
|
|
|
|
XChangeProperty(display, window.window, xa, XA_ATOM, 32,
|
2009-07-27 21:34:06 +00:00
|
|
|
PropModeAppend, (unsigned char *) &xa_prop, 1);
|
2008-02-20 20:30:45 +00:00
|
|
|
}
|
|
|
|
}
|
2009-07-27 21:34:06 +00:00
|
|
|
}
|
2008-02-20 20:30:45 +00:00
|
|
|
|
2008-07-12 10:25:05 +00:00
|
|
|
fprintf(stderr, PACKAGE_NAME": drawing to created window (0x%lx)\n",
|
2009-07-27 21:34:06 +00:00
|
|
|
window.window);
|
2006-03-09 18:51:57 +00:00
|
|
|
fflush(stderr);
|
|
|
|
|
|
|
|
XMapWindow(display, window.window);
|
2009-03-19 04:02:25 +00:00
|
|
|
|
2009-07-27 21:34:06 +00:00
|
|
|
} else
|
|
|
|
#endif /* OWN_WINDOW */
|
2005-07-20 00:30:40 +00:00
|
|
|
{
|
|
|
|
XWindowAttributes attrs;
|
|
|
|
|
2008-02-20 20:30:45 +00:00
|
|
|
if (!window.window) {
|
|
|
|
window.window = find_desktop_window(&window.root, &window.desktop);
|
|
|
|
}
|
2010-01-19 23:01:01 +00:00
|
|
|
window.visual = DefaultVisual(display, screen);
|
|
|
|
window.colourmap = DefaultColormap(display, screen);
|
2005-07-20 00:30:40 +00:00
|
|
|
|
|
|
|
if (XGetWindowAttributes(display, window.window, &attrs)) {
|
|
|
|
window.width = attrs.width;
|
|
|
|
window.height = attrs.height;
|
|
|
|
}
|
2006-02-14 06:15:38 +00:00
|
|
|
|
2008-07-12 10:25:05 +00:00
|
|
|
fprintf(stderr, PACKAGE_NAME": drawing to desktop window\n");
|
2005-07-20 00:30:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Drawable is same as window. This may be changed by double buffering. */
|
|
|
|
window.drawable = window.window;
|
|
|
|
|
|
|
|
XFlush(display);
|
|
|
|
|
2009-07-14 14:57:51 +00:00
|
|
|
XSelectInput(display, window.window, ExposureMask | PropertyChangeMask
|
2005-07-20 00:30:40 +00:00
|
|
|
#ifdef OWN_WINDOW
|
2010-04-23 15:35:41 +00:00
|
|
|
| (own_window.get(l) ? (StructureNotifyMask |
|
2009-07-27 21:34:06 +00:00
|
|
|
ButtonPressMask | ButtonReleaseMask) : 0)
|
2005-07-20 00:30:40 +00:00
|
|
|
#endif
|
2009-07-27 21:34:06 +00:00
|
|
|
);
|
2005-07-20 00:30:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static Window find_subwindow(Window win, int w, int h)
|
|
|
|
{
|
|
|
|
unsigned int i, j;
|
|
|
|
Window troot, parent, *children;
|
|
|
|
unsigned int n;
|
|
|
|
|
|
|
|
/* search subwindows with same size as display or work area */
|
|
|
|
|
|
|
|
for (i = 0; i < 10; i++) {
|
|
|
|
XQueryTree(display, win, &troot, &parent, &children, &n);
|
|
|
|
|
|
|
|
for (j = 0; j < n; j++) {
|
|
|
|
XWindowAttributes attrs;
|
|
|
|
|
2008-02-20 20:30:45 +00:00
|
|
|
if (XGetWindowAttributes(display, children[j], &attrs)) {
|
|
|
|
/* Window must be mapped and same size as display or
|
|
|
|
* work space */
|
|
|
|
if (attrs.map_state != 0 && ((attrs.width == display_width
|
2009-07-27 21:34:06 +00:00
|
|
|
&& attrs.height == display_height)
|
|
|
|
|| (attrs.width == w && attrs.height == h))) {
|
2005-07-20 00:30:40 +00:00
|
|
|
win = children[j];
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
XFree(children);
|
2008-02-20 20:30:45 +00:00
|
|
|
if (j == n) {
|
2005-07-20 00:30:40 +00:00
|
|
|
break;
|
2008-02-20 20:30:45 +00:00
|
|
|
}
|
2005-07-20 00:30:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return win;
|
|
|
|
}
|
|
|
|
|
2008-03-29 02:01:03 +00:00
|
|
|
void create_gc(void)
|
2005-07-20 00:30:40 +00:00
|
|
|
{
|
|
|
|
XGCValues values;
|
2008-02-20 20:30:45 +00:00
|
|
|
|
2005-07-20 00:30:40 +00:00
|
|
|
values.graphics_exposures = 0;
|
|
|
|
values.function = GXcopy;
|
|
|
|
window.gc = XCreateGC(display, window.drawable,
|
2009-07-27 21:34:06 +00:00
|
|
|
GCFunction | GCGraphicsExposures, &values);
|
2005-07-20 00:30:40 +00:00
|
|
|
}
|
2005-08-29 17:06:31 +00:00
|
|
|
|
2009-07-14 14:57:51 +00:00
|
|
|
//Get current desktop number
|
2009-07-14 15:43:27 +00:00
|
|
|
static inline void get_x11_desktop_current(Display *current_display, Window root, Atom atom)
|
2008-06-21 20:37:58 +00:00
|
|
|
{
|
2009-07-27 21:34:06 +00:00
|
|
|
Atom actual_type;
|
2009-07-11 08:50:02 +00:00
|
|
|
int actual_format;
|
|
|
|
unsigned long nitems;
|
|
|
|
unsigned long bytes_after;
|
|
|
|
unsigned char *prop = NULL;
|
2008-06-21 20:37:58 +00:00
|
|
|
struct information *current_info = &info;
|
2009-07-11 08:50:02 +00:00
|
|
|
|
2009-07-28 03:01:55 +00:00
|
|
|
if (atom == None) return;
|
|
|
|
|
2009-07-14 15:43:27 +00:00
|
|
|
if ( (XGetWindowProperty( current_display, root, atom,
|
2009-07-27 21:34:06 +00:00
|
|
|
0, 1L, False, XA_CARDINAL,
|
|
|
|
&actual_type, &actual_format, &nitems,
|
|
|
|
&bytes_after, &prop ) == Success ) &&
|
|
|
|
(actual_type == XA_CARDINAL) &&
|
|
|
|
(nitems == 1L) && (actual_format == 32) ) {
|
|
|
|
current_info->x11.desktop.current = prop[0]+1;
|
2009-07-14 14:57:51 +00:00
|
|
|
}
|
|
|
|
if(prop) {
|
2009-07-27 21:34:06 +00:00
|
|
|
XFree(prop);
|
2009-07-14 14:57:51 +00:00
|
|
|
}
|
|
|
|
}
|
2009-07-11 08:50:02 +00:00
|
|
|
|
2009-07-14 14:57:51 +00:00
|
|
|
//Get total number of available desktops
|
2009-07-14 15:43:27 +00:00
|
|
|
static inline void get_x11_desktop_number(Display *current_display, Window root, Atom atom)
|
2009-07-14 14:57:51 +00:00
|
|
|
{
|
2009-07-27 21:34:06 +00:00
|
|
|
Atom actual_type;
|
2009-07-14 14:57:51 +00:00
|
|
|
int actual_format;
|
|
|
|
unsigned long nitems;
|
|
|
|
unsigned long bytes_after;
|
|
|
|
unsigned char *prop = NULL;
|
|
|
|
struct information *current_info = &info;
|
|
|
|
|
2009-07-28 03:01:55 +00:00
|
|
|
if (atom == None) return;
|
|
|
|
|
2009-07-14 15:43:27 +00:00
|
|
|
if ( (XGetWindowProperty( current_display, root, atom,
|
2009-07-27 21:34:06 +00:00
|
|
|
0, 1L, False, XA_CARDINAL,
|
|
|
|
&actual_type, &actual_format, &nitems,
|
|
|
|
&bytes_after, &prop ) == Success ) &&
|
|
|
|
(actual_type == XA_CARDINAL) &&
|
|
|
|
(nitems == 1L) && (actual_format == 32) ) {
|
|
|
|
current_info->x11.desktop.number = prop[0];
|
2009-07-14 14:57:51 +00:00
|
|
|
}
|
|
|
|
if(prop) {
|
2009-07-27 21:34:06 +00:00
|
|
|
XFree(prop);
|
2009-07-11 08:50:02 +00:00
|
|
|
}
|
2009-07-14 14:57:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//Get all desktop names
|
2009-07-14 15:43:27 +00:00
|
|
|
static inline void get_x11_desktop_names(Display *current_display, Window root, Atom atom)
|
2009-07-14 14:57:51 +00:00
|
|
|
{
|
2009-07-27 21:34:06 +00:00
|
|
|
Atom actual_type;
|
2009-07-14 14:57:51 +00:00
|
|
|
int actual_format;
|
|
|
|
unsigned long nitems;
|
|
|
|
unsigned long bytes_after;
|
|
|
|
unsigned char *prop = NULL;
|
|
|
|
struct information *current_info = &info;
|
2009-07-11 08:50:02 +00:00
|
|
|
|
2009-07-28 03:01:55 +00:00
|
|
|
if (atom == None) return;
|
|
|
|
|
2009-07-14 15:43:27 +00:00
|
|
|
if ( (XGetWindowProperty( current_display, root, atom,
|
2009-07-27 21:34:06 +00:00
|
|
|
0, (~0L), False, ATOM(UTF8_STRING),
|
|
|
|
&actual_type, &actual_format, &nitems,
|
|
|
|
&bytes_after, &prop ) == Success ) &&
|
|
|
|
(actual_type == ATOM(UTF8_STRING)) &&
|
|
|
|
(nitems > 0L) && (actual_format == 8) ) {
|
|
|
|
|
2010-03-10 19:01:26 +00:00
|
|
|
current_info->x11.desktop.all_names.assign(reinterpret_cast<const char *>(prop), nitems);
|
2009-07-14 14:57:51 +00:00
|
|
|
}
|
|
|
|
if(prop) {
|
2009-07-27 21:34:06 +00:00
|
|
|
XFree(prop);
|
2009-07-11 08:50:02 +00:00
|
|
|
}
|
2009-07-14 14:57:51 +00:00
|
|
|
}
|
2009-07-11 08:50:02 +00:00
|
|
|
|
2009-07-14 14:57:51 +00:00
|
|
|
//Get current desktop name
|
2010-03-10 19:01:26 +00:00
|
|
|
static inline void get_x11_desktop_current_name(const std::string &names)
|
2009-07-14 14:57:51 +00:00
|
|
|
{
|
|
|
|
struct information *current_info = &info;
|
|
|
|
unsigned int i = 0, j = 0;
|
|
|
|
int k = 0;
|
|
|
|
|
2010-03-10 19:01:26 +00:00
|
|
|
while ( i < names.size() ) {
|
2009-07-27 21:34:06 +00:00
|
|
|
if ( names[i++] == '\0' ) {
|
|
|
|
if ( ++k == current_info->x11.desktop.current ) {
|
2010-03-10 19:01:26 +00:00
|
|
|
current_info->x11.desktop.name.assign(names.c_str()+j);
|
2009-07-27 21:34:06 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
j = i;
|
|
|
|
}
|
2009-07-11 08:50:02 +00:00
|
|
|
}
|
2009-07-14 14:57:51 +00:00
|
|
|
}
|
|
|
|
|
2009-07-14 15:43:27 +00:00
|
|
|
void get_x11_desktop_info(Display *current_display, Atom atom)
|
2009-07-14 14:57:51 +00:00
|
|
|
{
|
2009-07-27 21:34:06 +00:00
|
|
|
Window root;
|
2009-07-14 14:57:51 +00:00
|
|
|
static Atom atom_current, atom_number, atom_names;
|
|
|
|
struct information *current_info = &info;
|
2009-07-14 17:17:14 +00:00
|
|
|
XWindowAttributes window_attributes;
|
2009-07-11 08:50:02 +00:00
|
|
|
|
2009-07-14 15:43:27 +00:00
|
|
|
root = RootWindow(current_display, current_info->x11.monitor.current);
|
2009-07-14 14:57:51 +00:00
|
|
|
|
2009-07-28 03:01:55 +00:00
|
|
|
/* Check if we initialise else retrieve changed property */
|
2009-07-14 14:57:51 +00:00
|
|
|
if (atom == 0) {
|
2009-07-27 21:34:06 +00:00
|
|
|
atom_current = XInternAtom(current_display, "_NET_CURRENT_DESKTOP", True);
|
|
|
|
atom_number = XInternAtom(current_display, "_NET_NUMBER_OF_DESKTOPS", True);
|
|
|
|
atom_names = XInternAtom(current_display, "_NET_DESKTOP_NAMES", True);
|
|
|
|
get_x11_desktop_current(current_display, root, atom_current);
|
|
|
|
get_x11_desktop_number(current_display, root, atom_number);
|
|
|
|
get_x11_desktop_names(current_display, root, atom_names);
|
|
|
|
get_x11_desktop_current_name(current_info->x11.desktop.all_names);
|
|
|
|
|
2009-07-28 03:01:55 +00:00
|
|
|
/* Set the PropertyChangeMask on the root window, if not set */
|
2009-07-27 21:34:06 +00:00
|
|
|
XGetWindowAttributes(display, root, &window_attributes);
|
|
|
|
if (!(window_attributes.your_event_mask & PropertyChangeMask)) {
|
|
|
|
XSetWindowAttributes attributes;
|
|
|
|
attributes.event_mask = window_attributes.your_event_mask | PropertyChangeMask;
|
|
|
|
XChangeWindowAttributes(display, root, CWEventMask, &attributes);
|
|
|
|
XGetWindowAttributes(display, root, &window_attributes);
|
|
|
|
}
|
2009-07-14 14:57:51 +00:00
|
|
|
} else {
|
2009-07-27 21:34:06 +00:00
|
|
|
if (atom == atom_current) {
|
|
|
|
get_x11_desktop_current(current_display, root, atom_current);
|
|
|
|
get_x11_desktop_current_name(current_info->x11.desktop.all_names);
|
|
|
|
} else if (atom == atom_number) {
|
|
|
|
get_x11_desktop_number(current_display, root, atom_number);
|
|
|
|
} else if (atom == atom_names) {
|
|
|
|
get_x11_desktop_names(current_display, root, atom_names);
|
|
|
|
get_x11_desktop_current_name(current_info->x11.desktop.all_names);
|
|
|
|
}
|
2009-07-14 14:57:51 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-11-13 18:40:43 +00:00
|
|
|
static const char NOT_IN_X[] = "Not running in X";
|
2009-11-25 22:56:19 +00:00
|
|
|
|
|
|
|
void print_monitor(struct text_object *obj, char *p, int p_max_size)
|
|
|
|
{
|
|
|
|
(void)obj;
|
|
|
|
|
2010-11-13 18:40:43 +00:00
|
|
|
if(not out_to_x.get(*state)) {
|
2009-11-25 22:56:19 +00:00
|
|
|
strncpy(p, NOT_IN_X, p_max_size);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
snprintf(p, p_max_size, "%d", XDefaultScreen(display));
|
|
|
|
}
|
|
|
|
|
|
|
|
void print_monitor_number(struct text_object *obj, char *p, int p_max_size)
|
|
|
|
{
|
|
|
|
(void)obj;
|
|
|
|
|
2010-11-13 18:40:43 +00:00
|
|
|
if(not out_to_x.get(*state)) {
|
2009-11-25 22:56:19 +00:00
|
|
|
strncpy(p, NOT_IN_X, p_max_size);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
snprintf(p, p_max_size, "%d", XScreenCount(display));
|
|
|
|
}
|
|
|
|
|
|
|
|
void print_desktop(struct text_object *obj, char *p, int p_max_size)
|
|
|
|
{
|
|
|
|
(void)obj;
|
|
|
|
|
2010-11-13 18:40:43 +00:00
|
|
|
if(not out_to_x.get(*state)) {
|
2009-11-25 22:56:19 +00:00
|
|
|
strncpy(p, NOT_IN_X, p_max_size);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
snprintf(p, p_max_size, "%d", info.x11.desktop.current);
|
|
|
|
}
|
|
|
|
|
|
|
|
void print_desktop_number(struct text_object *obj, char *p, int p_max_size)
|
|
|
|
{
|
|
|
|
(void)obj;
|
|
|
|
|
2010-11-13 18:40:43 +00:00
|
|
|
if(not out_to_x.get(*state)) {
|
2009-11-25 22:56:19 +00:00
|
|
|
strncpy(p, NOT_IN_X, p_max_size);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
snprintf(p, p_max_size, "%d", info.x11.desktop.number);
|
|
|
|
}
|
|
|
|
|
|
|
|
void print_desktop_name(struct text_object *obj, char *p, int p_max_size)
|
|
|
|
{
|
|
|
|
(void)obj;
|
|
|
|
|
2010-03-10 19:01:26 +00:00
|
|
|
if(not out_to_x.get(*state)) {
|
2009-11-25 22:56:19 +00:00
|
|
|
strncpy(p, NOT_IN_X, p_max_size);
|
2010-03-10 19:01:26 +00:00
|
|
|
} else {
|
|
|
|
strncpy(p, info.x11.desktop.name.c_str(), p_max_size);
|
2009-11-25 22:56:19 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-07-13 21:19:32 +00:00
|
|
|
#ifdef OWN_WINDOW
|
2009-06-13 21:36:28 +00:00
|
|
|
/* reserve window manager space */
|
|
|
|
void set_struts(int sidenum)
|
|
|
|
{
|
|
|
|
Atom strut;
|
|
|
|
if ((strut = ATOM(_NET_WM_STRUT)) != None) {
|
|
|
|
/* reserve space at left, right, top, bottom */
|
|
|
|
signed long sizes[12] = {0};
|
|
|
|
int i;
|
|
|
|
|
|
|
|
/* define strut depth */
|
|
|
|
switch (sidenum) {
|
|
|
|
case 0:
|
|
|
|
/* left side */
|
|
|
|
sizes[0] = window.x + window.width;
|
|
|
|
break;
|
|
|
|
case 1:
|
|
|
|
/* right side */
|
|
|
|
sizes[1] = display_width - window.x;
|
|
|
|
break;
|
|
|
|
case 2:
|
|
|
|
/* top side */
|
|
|
|
sizes[2] = window.y + window.height;
|
|
|
|
break;
|
|
|
|
case 3:
|
|
|
|
/* bottom side */
|
|
|
|
sizes[3] = display_height - window.y;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* define partial strut length */
|
|
|
|
if (sidenum <= 1) {
|
|
|
|
sizes[4 + (sidenum*2)] = window.y;
|
|
|
|
sizes[5 + (sidenum*2)] = window.y + window.height;
|
|
|
|
} else if (sidenum <= 3) {
|
|
|
|
sizes[4 + (sidenum*2)] = window.x;
|
|
|
|
sizes[5 + (sidenum*2)] = window.x + window.width;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* check constraints */
|
|
|
|
for (i = 0; i < 12; i++) {
|
|
|
|
if (sizes[i] < 0) {
|
|
|
|
sizes[i] = 0;
|
|
|
|
} else {
|
|
|
|
if (i <= 1 || i >= 8) {
|
|
|
|
if (sizes[i] > display_width) {
|
|
|
|
sizes[i] = display_width;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if (sizes[i] > display_height) {
|
|
|
|
sizes[i] = display_height;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
XChangeProperty(display, window.window, strut, XA_CARDINAL, 32,
|
|
|
|
PropModeReplace, (unsigned char *) &sizes, 4);
|
|
|
|
|
|
|
|
if ((strut = ATOM(_NET_WM_STRUT_PARTIAL)) != None) {
|
|
|
|
XChangeProperty(display, window.window, strut, XA_CARDINAL, 32,
|
|
|
|
PropModeReplace, (unsigned char *) &sizes, 12);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2009-07-13 21:19:32 +00:00
|
|
|
#endif /* OWN_WINDOW */
|
2009-08-05 21:41:29 +00:00
|
|
|
|
2010-01-07 02:38:12 +00:00
|
|
|
#ifdef BUILD_XDBE
|
2009-08-05 21:41:29 +00:00
|
|
|
void xdbe_swap_buffers(void)
|
|
|
|
{
|
2010-04-23 19:54:40 +00:00
|
|
|
if (use_xdbe.get(*state)) {
|
2009-08-05 21:41:29 +00:00
|
|
|
XdbeSwapInfo swap;
|
|
|
|
|
|
|
|
swap.swap_window = window.window;
|
|
|
|
swap.swap_action = XdbeBackground;
|
|
|
|
XdbeSwapBuffers(display, &swap, 1);
|
|
|
|
}
|
|
|
|
}
|
2012-04-11 16:06:47 +00:00
|
|
|
#else
|
|
|
|
void xpmdb_swap_buffers(void)
|
|
|
|
{
|
|
|
|
if (use_xpmdb.get(*state)) {
|
|
|
|
XCopyArea(display, window.back_buffer, window.window, window.gc, 0, 0, window.width, window.height, 0, 0);
|
|
|
|
XSetForeground(display, window.gc, 0);
|
|
|
|
XFillRectangle(display, window.drawable, window.gc, 0, 0, window.width, window.height);
|
|
|
|
XFlush(display);
|
|
|
|
}
|
|
|
|
}
|
2010-01-07 02:38:12 +00:00
|
|
|
#endif /* BUILD_XDBE */
|