wmmisc: Add version 1.1 to repository.
[dockapps.git] / wmmisc / src / wmgeneral.c
blob93663760bc14fde29390088d3d8c9314cc1404f3
1 /*
2 * wmmisc - WindowMaker Dockapp for monitoring misc. information.
3 * Copyright (C) 2003-2006 Jesse S. (luxorfalls@sbcglobal.net)
5 * wmmisc is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * wmmisc is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with wmmisc; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <unistd.h>
25 #include <ctype.h>
27 #include <X11/Xlib.h>
28 #include <X11/xpm.h>
29 #include <X11/extensions/shape.h>
31 #include "wmgeneral.h"
33 static Display *da_display;
34 static Window da_root_window;
35 static int da_screen;
36 static int da_x_fd;
37 static int da_display_depth;
38 static XSizeHints da_size_hints;
39 static XWMHints da_wm_hints;
40 static Pixel da_bg_pixel;
41 static Pixel da_fg_pixel;
42 static char* da_geometry = NULL;
43 static Window da_icon_window;
44 static Window da_window;
45 static GC da_normal_gc;
46 static xpm_icon da_window_icon;
47 static Pixmap da_pixmask;
49 typedef struct
51 int enable;
52 int top;
53 int bottom;
54 int left;
55 int right;
56 } mouse_region_t;
58 mouse_region_t mouse_region[MAX_MOUSE_REGION];
60 void
61 get_xpm( xpm_icon* window_icon, char** pixmap_bytes )
63 XWindowAttributes attributes;
64 int err;
66 XGetWindowAttributes( da_display, da_root_window, &attributes );
68 window_icon->attributes.valuemask |= ( XpmReturnPixels | XpmReturnExtensions );
70 err = XpmCreatePixmapFromData( da_display,
71 da_root_window,
72 pixmap_bytes,
73 &window_icon->pixmap,
74 &window_icon->mask,
75 &window_icon->attributes );
77 if ( XpmSuccess != err )
79 fprintf( stderr, "Not enough free color cells.\n" );
80 exit( 1 );
84 Pixel
85 get_color_by_name( const char* color_name )
87 XColor color;
88 XWindowAttributes attributes;
90 XGetWindowAttributes( da_display, da_root_window, &attributes );
92 color.pixel = 0;
94 if ( 0 == XParseColor( da_display, attributes.colormap, color_name, &color ) )
96 fprintf( stderr, "wmmisc: Can't parse color name: '%s'\n", color_name );
97 return 0;
100 if ( 0 == XAllocColor( da_display, attributes.colormap, &color ))
102 fprintf( stderr, "wmmisc: Can't allocate memory for color: '%s'\n", color_name );
103 return 0;
106 return color.pixel;
110 flush_expose( Window window )
112 XEvent dummy;
113 int i = 0;
115 while ( 0 != XCheckTypedWindowEvent( da_display, window, Expose, &dummy ) )
117 ++i;
120 return i;
123 void
124 redraw_window( void )
126 flush_expose( da_icon_window );
128 XCopyArea( da_display,
129 da_window_icon.pixmap,
130 da_icon_window,
131 da_normal_gc,
134 da_window_icon.attributes.width,
135 da_window_icon.attributes.height,
137 0 );
139 flush_expose( da_window );
141 XCopyArea( da_display,
142 da_window_icon.pixmap,
143 da_window,
144 da_normal_gc,
147 da_window_icon.attributes.width,
148 da_window_icon.attributes.height,
150 0 );
153 void
154 redraw_window_coords( int x, int y )
156 flush_expose( da_icon_window );
158 XCopyArea( da_display,
159 da_window_icon.pixmap,
160 da_icon_window,
161 da_normal_gc,
164 da_window_icon.attributes.width,
165 da_window_icon.attributes.height,
167 0 );
169 flush_expose( da_window );
171 XCopyArea( da_display,
172 da_window_icon.pixmap,
173 da_window,
174 da_normal_gc,
177 da_window_icon.attributes.width,
178 da_window_icon.attributes.height,
180 0 );
183 void
184 add_mouse_region( int m_index,
185 int m_left,
186 int m_top,
187 int m_right,
188 int m_bottom )
190 if ( MAX_MOUSE_REGION > m_index )
192 mouse_region[m_index].enable = 1;
193 mouse_region[m_index].top = m_top;
194 mouse_region[m_index].left = m_left;
195 mouse_region[m_index].bottom = m_bottom;
196 mouse_region[m_index].right = m_right;
201 check_mouse_region( int x, int y )
203 int i;
204 int found;
206 found = 0;
208 for ( i = 0; MAX_MOUSE_REGION > i && 0 == found; ++i )
210 if ( 0 != mouse_region[i].enable &&
211 x <= mouse_region[i].right &&
212 x >= mouse_region[i].left &&
213 y <= mouse_region[i].bottom &&
214 y >= mouse_region[i].top )
216 found = 1;
220 if ( 0 == found )
222 return -1;
225 return --i;
228 void
229 create_xbm_from_xpm( char* xbm, char** xpm, int sx, int sy )
231 int i;
232 int j;
233 int k;
234 int width;
235 int height;
236 int numcol;
237 int depth;
238 int zero = 0;
239 unsigned char bwrite;
240 int bcount;
241 int curpixel;
243 sscanf( *xpm, "%d %d %d %d", &width, &height, &numcol, &depth );
245 for ( k = 0; k != depth; ++k )
247 zero <<= 8;
248 zero |= xpm[2][k];
251 for ( i = numcol + 1; i < ( numcol + sy + 1 ); ++i )
253 bcount = 0;
254 bwrite = 0;
256 for ( j = 0; j < sx * depth; j += depth )
258 bwrite >>= 1;
260 curpixel = 0;
262 for ( k = 0; k != depth; ++k )
264 curpixel <<= 8;
265 curpixel |= xpm[i][j + k];
268 if ( curpixel != zero )
270 bwrite += 128;
273 bcount++;
275 if ( bcount == 8 )
277 *xbm = bwrite;
278 ++xbm;
279 bcount = 0;
280 bwrite = 0;
286 void
287 copy_xpm_area( int x,
288 int y,
289 unsigned int sx,
290 unsigned int sy,
291 int dx,
292 int dy )
294 XCopyArea( da_display,
295 da_window_icon.pixmap,
296 da_window_icon.pixmap,
297 da_normal_gc,
303 dy );
306 void
307 copy_xbm_area( int x,
308 int y,
309 unsigned int sx,
310 unsigned int sy,
311 int dx,
312 int dy )
314 XCopyArea( da_display,
315 da_window_icon.mask,
316 da_window_icon.pixmap,
317 da_normal_gc,
323 dy );
326 void
327 set_mask_coords( int x, int y )
329 XShapeCombineMask( da_display,
330 da_window,
331 ShapeBounding,
334 da_pixmask,
335 ShapeSet );
336 XShapeCombineMask( da_display,
337 da_icon_window,
338 ShapeBounding,
341 da_pixmask,
342 ShapeSet );
345 void
346 open_window( int argc,
347 char** argv,
348 char** pixmap_bytes,
349 char* pixmask_bits,
350 int pixmask_width,
351 int pixmask_height )
353 unsigned int borderwidth = 1;
354 XClassHint classHint;
355 char* display_name = NULL;
356 char* wname = NULL;
357 XTextProperty name;
358 XGCValues gcv;
359 unsigned long gcm;
360 char* geometry = NULL;
361 int dummy = 0;
362 int i;
363 int wx;
364 int wy;
366 wname = argv[0];
368 for ( i = 1; i < argc; ++i )
370 if ( 0 == strcmp( argv[i], "-display" ) )
372 display_name = argv[++i];
375 if ( 0 == strcmp( argv[i], "-geometry" ) )
377 geometry = argv[++i];
381 da_display = XOpenDisplay( display_name );
383 if ( NULL == da_display )
385 fprintf( stderr,
386 "%s: Can't open display: '%s'\n",
387 wname,
388 XDisplayName( display_name ) );
389 exit( 1 );
392 da_screen = DefaultScreen( da_display );
393 da_root_window = RootWindow( da_display, da_screen );
394 da_display_depth = DefaultDepth( da_display, da_screen );
395 da_x_fd = XConnectionNumber( da_display );
397 /* Convert XPM to XImage */
398 get_xpm( &da_window_icon, pixmap_bytes );
400 /* Create a window to hold the stuff */
401 da_size_hints.flags = USSize | USPosition;
402 da_size_hints.x = 0;
403 da_size_hints.y = 0;
405 da_bg_pixel = get_color_by_name( "white" );
406 da_fg_pixel = get_color_by_name( "black" );
408 XWMGeometry( da_display,
409 da_screen,
410 da_geometry,
411 NULL,
412 borderwidth,
413 &da_size_hints,
414 &da_size_hints.x,
415 &da_size_hints.y,
416 &da_size_hints.width,
417 &da_size_hints.height,
418 &dummy );
420 da_size_hints.width = 64;
421 da_size_hints.height = 64;
423 da_window = XCreateSimpleWindow( da_display,
424 da_root_window,
425 da_size_hints.x,
426 da_size_hints.y,
427 da_size_hints.width,
428 da_size_hints.height,
429 borderwidth,
430 da_fg_pixel,
431 da_bg_pixel );
433 da_icon_window = XCreateSimpleWindow( da_display,
434 da_window,
435 da_size_hints.x,
436 da_size_hints.y,
437 da_size_hints.width,
438 da_size_hints.height,
439 borderwidth,
440 da_fg_pixel,
441 da_bg_pixel );
443 /* Activate hints */
444 XSetWMNormalHints( da_display, da_window, &da_size_hints );
445 classHint.res_name = wname;
446 classHint.res_class = wname;
447 XSetClassHint( da_display, da_window, &classHint );
448 XSelectInput( da_display,
449 da_window,
450 ( ButtonPressMask |
451 ExposureMask |
452 ButtonReleaseMask |
453 PointerMotionMask |
454 StructureNotifyMask ) );
455 XSelectInput( da_display,
456 da_icon_window,
457 ( ButtonPressMask |
458 ExposureMask |
459 ButtonReleaseMask |
460 PointerMotionMask |
461 StructureNotifyMask ) );
463 if ( 0 == XStringListToTextProperty( &wname, 1, &name ) )
465 fprintf( stderr, "%s: can't allocate window name\n", wname );
466 exit( 1 );
469 XSetWMName( da_display, da_window, &name );
471 /* Create GC for drawing */
472 gcm = GCForeground | GCBackground | GCGraphicsExposures;
473 gcv.foreground = da_fg_pixel;
474 gcv.background = da_bg_pixel;
475 gcv.graphics_exposures = 0;
476 da_normal_gc = XCreateGC( da_display, da_root_window, gcm, &gcv );
478 /* ONLYSHAPE ON */
479 da_pixmask = XCreateBitmapFromData( da_display,
480 da_window,
481 pixmask_bits,
482 pixmask_width,
483 pixmask_height );
485 XShapeCombineMask( da_display,
486 da_window,
487 ShapeBounding,
490 da_pixmask,
491 ShapeSet );
492 XShapeCombineMask( da_display,
493 da_icon_window,
494 ShapeBounding,
497 da_pixmask,
498 ShapeSet );
500 /* ONLYSHAPE OFF */
501 da_wm_hints.initial_state = WithdrawnState;
502 da_wm_hints.icon_window = da_icon_window;
503 da_wm_hints.icon_x = da_size_hints.x;
504 da_wm_hints.icon_y = da_size_hints.y;
505 da_wm_hints.window_group = da_window;
506 da_wm_hints.flags = ( StateHint |
507 IconWindowHint |
508 IconPositionHint |
509 WindowGroupHint );
511 XSetWMHints( da_display, da_window, &da_wm_hints );
512 XSetCommand( da_display, da_window, argv, argc );
513 XMapWindow( da_display, da_window );
515 if ( NULL != geometry )
517 if ( 2 != sscanf( geometry, "+%d+%d", &wx, &wy ) )
519 fprintf( stderr, "Bad geometry string.\n" );
520 exit( 1 );
523 XMoveWindow( da_display, da_window, wx, wy );
526 if ( NULL != display_name )
528 free( display_name );