00001 #include "bcdisplayinfo.h"
00002 #include "clip.h"
00003
00004 #include <X11/X.h>
00005 #include <X11/Xlib.h>
00006 #include <X11/Xutil.h>
00007 #include <unistd.h>
00008
00009 #define TEST_SIZE 128
00010 #define TEST_SIZE2 164
00011 #define TEST_SIZE3 196
00012 int BC_DisplayInfo::top_border = -1;
00013 int BC_DisplayInfo::left_border = -1;
00014 int BC_DisplayInfo::bottom_border = -1;
00015 int BC_DisplayInfo::right_border = -1;
00016 int BC_DisplayInfo::auto_reposition_x = -1;
00017 int BC_DisplayInfo::auto_reposition_y = -1;
00018
00019
00020 BC_DisplayInfo::BC_DisplayInfo(char *display_name, int show_error)
00021 {
00022 init_window(display_name, show_error);
00023 }
00024
00025 BC_DisplayInfo::~BC_DisplayInfo()
00026 {
00027 XCloseDisplay(display);
00028 }
00029
00030
00031 void BC_DisplayInfo::parse_geometry(char *geom, int *x, int *y, int *width, int *height)
00032 {
00033 XParseGeometry(geom, x, y, (unsigned int*)width, (unsigned int*)height);
00034 }
00035
00036 void BC_DisplayInfo::test_window(int &x_out,
00037 int &y_out,
00038 int &x_out2,
00039 int &y_out2,
00040 int x_in,
00041 int y_in)
00042 {
00043 unsigned long mask = CWEventMask | CWWinGravity;
00044 XSetWindowAttributes attr;
00045 XSizeHints size_hints;
00046
00047
00048 x_out = 0;
00049 y_out = 0;
00050 x_out2 = 0;
00051 y_out2 = 0;
00052 attr.event_mask = StructureNotifyMask;
00053 attr.win_gravity = SouthEastGravity;
00054 Window win = XCreateWindow(display,
00055 rootwin,
00056 x_in,
00057 y_in,
00058 TEST_SIZE,
00059 TEST_SIZE,
00060 0,
00061 default_depth,
00062 InputOutput,
00063 vis,
00064 mask,
00065 &attr);
00066 XGetNormalHints(display, win, &size_hints);
00067 size_hints.flags = PPosition | PSize;
00068 size_hints.x = x_in;
00069 size_hints.y = y_in;
00070 size_hints.width = TEST_SIZE;
00071 size_hints.height = TEST_SIZE;
00072 XSetStandardProperties(display,
00073 win,
00074 "x",
00075 "x",
00076 None,
00077 0,
00078 0,
00079 &size_hints);
00080
00081 XMapWindow(display, win);
00082 XFlush(display);
00083 XSync(display, 0);
00084 XMoveResizeWindow(display,
00085 win,
00086 x_in,
00087 y_in,
00088 TEST_SIZE2,
00089 TEST_SIZE2);
00090 XFlush(display);
00091 XSync(display, 0);
00092
00093 XResizeWindow(display,
00094 win,
00095 TEST_SIZE3,
00096 TEST_SIZE3);
00097 XFlush(display);
00098 XSync(display, 0);
00099
00100 XEvent event;
00101 int last_w = 0;
00102 int last_h = 0;
00103 int state = 0;
00104
00105 do
00106 {
00107 XNextEvent(display, &event);
00108
00109 if(event.type == ConfigureNotify && event.xany.window == win)
00110 {
00111
00112 if(last_w != event.xconfigure.width || last_h != event.xconfigure.height)
00113 {
00114 state++;
00115 last_w = event.xconfigure.width;
00116 last_h = event.xconfigure.height;
00117 }
00118
00119 if(state == 1)
00120 {
00121 x_out = MAX(event.xconfigure.x + event.xconfigure.border_width - x_in, x_out);
00122 y_out = MAX(event.xconfigure.y + event.xconfigure.border_width - y_in, y_out);
00123 }
00124 else
00125 if(state == 2)
00126
00127 {
00128 x_out2 = MAX(event.xconfigure.x + event.xconfigure.border_width - x_in, x_out2);
00129 y_out2 = MAX(event.xconfigure.y + event.xconfigure.border_width - y_in, y_out2);
00130 }
00131
00132
00133
00134
00135
00136
00137
00138
00139 }
00140 }while(state != 3);
00141
00142 XDestroyWindow(display, win);
00143 XFlush(display);
00144 XSync(display, 0);
00145
00146 x_out = MAX(0, x_out);
00147 y_out = MAX(0, y_out);
00148 x_out = MIN(x_out, 30);
00149 y_out = MIN(y_out, 30);
00150
00151 }
00152
00153 void BC_DisplayInfo::init_borders()
00154 {
00155 if(top_border < 0)
00156 {
00157
00158 test_window(left_border,
00159 top_border,
00160 auto_reposition_x,
00161 auto_reposition_y,
00162 0,
00163 0);
00164 right_border = left_border;
00165 bottom_border = left_border;
00166
00167
00168
00169
00170
00171 }
00172 }
00173
00174
00175 int BC_DisplayInfo::get_top_border()
00176 {
00177 init_borders();
00178 return top_border;
00179 }
00180
00181 int BC_DisplayInfo::get_left_border()
00182 {
00183 init_borders();
00184 return left_border;
00185 }
00186
00187 int BC_DisplayInfo::get_right_border()
00188 {
00189 init_borders();
00190 return right_border;
00191 }
00192
00193 int BC_DisplayInfo::get_bottom_border()
00194 {
00195 init_borders();
00196 return bottom_border;
00197 }
00198
00199 void BC_DisplayInfo::init_window(char *display_name, int show_error)
00200 {
00201 if(display_name && display_name[0] == 0) display_name = NULL;
00202
00203
00204
00205 XInitThreads();
00206
00207 if((display = XOpenDisplay(display_name)) == NULL)
00208 {
00209 if(show_error)
00210 {
00211 printf("BC_DisplayInfo::init_window: cannot connect to X server.\n");
00212 if(getenv("DISPLAY") == NULL)
00213 printf("'DISPLAY' environment variable not set.\n");
00214 exit(1);
00215 }
00216 return;
00217 }
00218
00219 screen = DefaultScreen(display);
00220 rootwin = RootWindow(display, screen);
00221 vis = DefaultVisual(display, screen);
00222 default_depth = DefaultDepth(display, screen);
00223 }
00224
00225
00226 int BC_DisplayInfo::get_root_w()
00227 {
00228 Screen *screen_ptr = XDefaultScreenOfDisplay(display);
00229 return WidthOfScreen(screen_ptr);
00230 }
00231
00232 int BC_DisplayInfo::get_root_h()
00233 {
00234 Screen *screen_ptr = XDefaultScreenOfDisplay(display);
00235 return HeightOfScreen(screen_ptr);
00236 }
00237
00238 int BC_DisplayInfo::get_abs_cursor_x()
00239 {
00240 int abs_x, abs_y, win_x, win_y;
00241 unsigned int temp_mask;
00242 Window temp_win;
00243
00244 XQueryPointer(display,
00245 rootwin,
00246 &temp_win,
00247 &temp_win,
00248 &abs_x,
00249 &abs_y,
00250 &win_x,
00251 &win_y,
00252 &temp_mask);
00253 return abs_x;
00254 }
00255
00256 int BC_DisplayInfo::get_abs_cursor_y()
00257 {
00258 int abs_x, abs_y, win_x, win_y;
00259 unsigned int temp_mask;
00260 Window temp_win;
00261
00262 XQueryPointer(display,
00263 rootwin,
00264 &temp_win,
00265 &temp_win,
00266 &abs_x,
00267 &abs_y,
00268 &win_x,
00269 &win_y,
00270 &temp_mask);
00271 return abs_y;
00272 }