1 /* Skippy - Seduces Kids Into Perversion
3 * Copyright (C) 2004 Hyriand <hyriand@thegraveyard.org>
5 * This program 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 * This program 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 this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 find_argb_visual (Display *dpy, int scr)
30 XRenderPictFormat *format;
33 template.screen = scr;
35 template.class = TrueColor;
36 xvi = XGetVisualInfo (dpy,
45 for (i = 0; i < nvi; i++)
47 format = XRenderFindVisualFormat (dpy, xvi[i].visual);
48 if (format->type == PictTypeDirect && format->direct.alphaMask)
50 visual = xvi[i].visual;
60 mainwin_create(Display *dpy, dlist *config)
65 XSetWindowAttributes wattr;
66 XWindowAttributes rootattr;
67 XRenderPictureAttributes pa;
74 MainWin *mw = (MainWin *)malloc(sizeof(MainWin));
77 mw->screen = DefaultScreen(dpy);
78 mw->root = RootWindow(dpy, mw->screen);
79 mw->lazy_trans = (strcasecmp(config_get(config, "general", "lazyTrans", "false"), "true") == 0) ? True : False;
83 mw->visual = find_argb_visual(dpy, DefaultScreen(dpy));
86 fprintf(stderr, "WARNING: Couldn't find argb visual, disabling lazy transparency.\n");
87 mw->lazy_trans = False;
92 mw->depth = DefaultDepth(dpy, mw->screen);
93 mw->visual = DefaultVisual(dpy, mw->screen);
95 mw->colormap = XCreateColormap(dpy, mw->root, mw->visual, AllocNone);
97 mw->background = None;
98 mw->format = XRenderFindVisualFormat(dpy, mw->visual);
100 mw->xin_info = mw->xin_active = 0;
102 #endif /* XINERAMA */
104 mw->pressed = mw->focus = 0;
107 mw->key_up = XKeysymToKeycode(dpy, XK_Up);
108 mw->key_down = XKeysymToKeycode(dpy, XK_Down);
109 mw->key_left = XKeysymToKeycode(dpy, XK_Left);
110 mw->key_right = XKeysymToKeycode(dpy, XK_Right);
111 mw->key_enter = XKeysymToKeycode(dpy, XK_Return);
112 mw->key_space = XKeysymToKeycode(dpy, XK_space);
113 mw->key_escape = XKeysymToKeycode(dpy, XK_Escape);
114 mw->key_q = XKeysymToKeycode(dpy, XK_q);
115 mw->key_f6 = XKeysymToKeycode(dpy, XK_F6);
116 mw->key_f7 = XKeysymToKeycode(dpy, XK_F7);
117 mw->key_f8 = XKeysymToKeycode(dpy, XK_F8);
118 mw->key_f5 = XKeysymToKeycode(dpy, XK_F5);
120 XGetWindowAttributes(dpy, mw->root, &rootattr);
122 mw->width = rootattr.width;
123 mw->height = rootattr.height;
125 wattr.colormap = mw->colormap;
126 wattr.background_pixel = wattr.border_pixel = 0;
127 wattr.event_mask = VisibilityChangeMask |
130 mw->window = XCreateWindow(dpy, mw->root, 0, 0, mw->width, mw->height, 0,
131 mw->depth, InputOutput, mw->visual,
132 CWBackPixel|CWBorderPixel|CWColormap|CWEventMask, &wattr);
133 if(mw->window == None) {
140 fprintf(stderr, "--> checking for Xinerama extension... ");
142 if(XineramaQueryExtension(dpy, &event_base, &error_base))
145 fprintf(stderr, "yes\n--> checking if Xinerama is enabled... ");
147 if(XineramaIsActive(dpy))
150 fprintf(stderr, "yes\n--> fetching Xinerama info... ");
152 mw->xin_info = XineramaQueryScreens(mw->dpy, &mw->xin_screens);
154 fprintf(stderr, "done (%i screens)\n", mw->xin_screens);
159 fprintf(stderr, "no\n");
164 fprintf(stderr, "no\n");
166 #endif /* XINERAMA */
168 if(! XDamageQueryExtension (dpy, &mw->damage_event_base, &error_base))
170 fprintf(stderr, "FATAL: XDamage extension not found.\n");
174 if(! XCompositeQueryExtension(dpy, &event_base, &error_base))
176 fprintf(stderr, "FATAL: XComposite extension not found.\n");
180 if(! XRenderQueryExtension(dpy, &event_base, &error_base))
182 fprintf(stderr, "FATAL: XRender extension not found.\n");
186 if(! XFixesQueryExtension(dpy, &event_base, &error_base))
188 fprintf(stderr, "FATAL: XFixes extension not found.\n");
192 XCompositeRedirectSubwindows (mw->dpy, mw->root, CompositeRedirectAutomatic);
194 tmp_d = strtod(config_get(config, "general", "updateFreq", "10.0"), 0);
196 mw->poll_time = (1.0 / tmp_d) * 1000.0;
200 tmp = config_get(config, "normal", "tint", "black");
201 if(! XParseColor(mw->dpy, mw->colormap, tmp, &exact_color))
203 fprintf(stderr, "Couldn't look up color '%s', reverting to black", tmp);
204 mw->normalTint.red = mw->normalTint.green = mw->normalTint.blue = 0;
208 mw->normalTint.red = exact_color.red;
209 mw->normalTint.green = exact_color.green;
210 mw->normalTint.blue = exact_color.blue;
212 mw->normalTint.alpha = MAX(0, MIN(strtol(config_get(config, "normal", "tintOpacity", "0"), 0, 0) * 256, 65535));
214 tmp = config_get(config, "highlight", "tint", "#101020");
215 if(! XParseColor(mw->dpy, mw->colormap, tmp, &exact_color))
217 fprintf(stderr, "Couldn't look up color '%s', reverting to #101020", tmp);
218 mw->highlightTint.red = mw->highlightTint.green = 0x10;
219 mw->highlightTint.blue = 0x20;
223 mw->highlightTint.red = exact_color.red;
224 mw->highlightTint.green = exact_color.green;
225 mw->highlightTint.blue = exact_color.blue;
227 mw->highlightTint.alpha = MAX(0, MIN(strtol(config_get(config, "highlight", "tintOpacity", "64"), 0, 0) * 256, 65535));
230 clear.alpha = MAX(0, MIN(strtol(config_get(config, "normal", "opacity", "200"), 0, 10) * 256, 65535));
231 mw->normalPixmap = XCreatePixmap(mw->dpy, mw->window, 1, 1, 8);
232 mw->normalPicture = XRenderCreatePicture(mw->dpy, mw->normalPixmap, XRenderFindStandardFormat(mw->dpy, PictStandardA8), CPRepeat, &pa);
233 XRenderFillRectangle(mw->dpy, PictOpSrc, mw->normalPicture, &clear, 0, 0, 1, 1);
235 clear.alpha = MAX(0, MIN(strtol(config_get(config, "highlight", "opacity", "255"), 0, 10) * 256, 65535));
236 mw->highlightPixmap = XCreatePixmap(mw->dpy, mw->window, 1, 1, 8);
237 mw->highlightPicture = XRenderCreatePicture(mw->dpy, mw->highlightPixmap, XRenderFindStandardFormat(mw->dpy, PictStandardA8), CPRepeat, &pa);
238 XRenderFillRectangle(mw->dpy, PictOpSrc, mw->highlightPicture, &clear, 0, 0, 1, 1);
240 tmp = config_get(config, "general", "distance", "50");
241 mw->distance = MAX(1, strtol(tmp, 0, 10));
243 if(! strcasecmp(config_get(config, "tooltip", "show", "true"), "true"))
244 mw->tooltip = tooltip_create(mw, config);
250 load_image (MainWin *mw, Bool rotate, Imlib_Image rootimg)
262 imlib_context_set_image (buffer);
264 imlib_context_set_image (rootimg);
265 imlib_blend_image_onto_image (buffer, 0, 0, 0, imlib_image_get_width (), imlib_image_get_height (),
266 0, 0, mw->width, mw->height);
268 imlib_context_set_image (buffer);
271 imlib_context_set_image (rootimg);
279 mainwin_update_background(MainWin *mw)
281 /* Pixmap root = wm_get_root_pmap(mw->dpy);
282 XRenderColor black = { 0, 0, 0, 65535};*/
283 XRenderPictureAttributes pa;
284 Imlib_Context *context;
294 XFreePixmap(mw->dpy, mw->bg_pixmap);
296 XRenderFreePicture(mw->dpy, mw->background);
298 mw->bg_pixmap = XCreatePixmap(mw->dpy, mw->window, mw->width, mw->height, mw->depth);
300 mw->background = XRenderCreatePicture(mw->dpy, mw->bg_pixmap, mw->format, CPRepeat, &pa);
303 context = imlib_context_new ();
304 imlib_context_push (context);
305 imlib_context_set_display (mw->dpy);
306 imlib_context_set_visual (mw->visual);
307 imlib_context_set_colormap (mw->colormap);
308 imlib_context_set_drawable (mw->bg_pixmap);
309 imlib_context_set_color_range (imlib_create_color_range ());
311 image = imlib_create_image (mw->width, mw->height);
312 imlib_context_set_image (image);
314 imlib_context_set_color (0, 0, 0, 255);
315 imlib_image_fill_rectangle (0, 0, mw->width, mw->height);
317 imlib_context_set_dither (1);
318 imlib_context_set_blend (1);
320 if (load_image (mw, rotate, image) == 0)
322 fprintf (stderr, "Bad image\n");
326 imlib_render_image_on_drawable (0, 0);
328 imlib_free_color_range ();
331 XRenderFillRectangle(mw->dpy, PictOpSrc, mw->background, &black, 0, 0, mw->width, mw->height);
334 Picture from = XRenderCreatePicture(mw->dpy, root, XRenderFindVisualFormat(mw->dpy, DefaultVisual(mw->dpy, mw->screen)), 0, 0);
335 XRenderComposite(mw->dpy, PictOpSrc, from, None, mw->background, mw->x, mw->y, 0, 0, 0, 0, mw->width, mw->height);
336 XRenderFreePicture(mw->dpy, from);
339 XSetWindowBackgroundPixmap(mw->dpy, mw->window, mw->bg_pixmap);
340 XClearWindow(mw->dpy, mw->window);
344 mainwin_update(MainWin *mw)
347 XineramaScreenInfo *iter;
350 int root_x, root_y, dummy_i;
351 unsigned int dummy_u;
353 if(! mw->xin_info || ! mw->xin_screens)
355 mainwin_update_background(mw);
360 fprintf(stderr, "--> querying pointer... ");
362 XQueryPointer(mw->dpy, mw->root, &dummy_w, &dummy_w, &root_x, &root_y, &dummy_i, &dummy_i, &dummy_u);
364 fprintf(stderr, "+%i+%i\n", root_x, root_y);
366 fprintf(stderr, "--> figuring out which screen we're on... ");
369 for(i = 0; i < mw->xin_screens; ++i)
371 if(root_x >= iter->x_org && root_x < iter->x_org + iter->width &&
372 root_y >= iter->y_org && root_y < iter->y_org + iter->height)
375 fprintf(stderr, "screen %i %ix%i+%i+%i\n", iter->screen_number, iter->width, iter->height, iter->x_org, iter->y_org);
381 if(i == mw->xin_screens)
384 fprintf(stderr, "unknown\n");
390 mw->width = iter->width;
391 mw->height = iter->height;
392 XMoveResizeWindow(mw->dpy, mw->window, iter->x_org, iter->y_org, mw->width, mw->height);
393 mw->xin_active = iter;
394 #endif /* XINERAMA */
395 mainwin_update_background(mw);
399 mainwin_map(MainWin *mw)
401 wm_set_fullscreen(mw->dpy, mw->window, mw->x, mw->y, mw->width, mw->height);
403 XMapWindow(mw->dpy, mw->window);
404 XRaiseWindow(mw->dpy, mw->window);
408 mainwin_unmap(MainWin *mw)
411 tooltip_unmap(mw->tooltip);
414 XFreePixmap(mw->dpy, mw->bg_pixmap);
415 mw->bg_pixmap = None;
417 XUnmapWindow(mw->dpy, mw->window);
421 mainwin_destroy(MainWin *mw)
424 tooltip_destroy(mw->tooltip);
426 if(mw->background != None)
427 XRenderFreePicture(mw->dpy, mw->background);
429 if(mw->bg_pixmap != None)
430 XFreePixmap(mw->dpy, mw->bg_pixmap);
432 if(mw->normalPicture != None)
433 XRenderFreePicture(mw->dpy, mw->normalPicture);
435 if(mw->highlightPicture != None)
436 XRenderFreePicture(mw->dpy, mw->highlightPicture);
438 if(mw->normalPixmap != None)
439 XFreePixmap(mw->dpy, mw->normalPixmap);
441 if(mw->highlightPixmap != None)
442 XFreePixmap(mw->dpy, mw->highlightPixmap);
444 XDestroyWindow(mw->dpy, mw->window);
449 #endif /* XINERAMA */
455 mainwin_transform(MainWin *mw, float f)
457 mw->transform.matrix[0][0] = XDoubleToFixed(1.0 / f);
458 mw->transform.matrix[0][1] = 0.0;
459 mw->transform.matrix[0][2] = 0.0;
460 mw->transform.matrix[1][0] = 0.0;
461 mw->transform.matrix[1][1] = XDoubleToFixed(1.0 / f);
462 mw->transform.matrix[1][2] = 0.0;
463 mw->transform.matrix[2][0] = 0.0;
464 mw->transform.matrix[2][1] = 0.0;
465 mw->transform.matrix[2][2] = XDoubleToFixed(1.0);
469 mainwin_handle(MainWin *mw, XEvent *ev)
474 if(ev->xkey.keycode == XKeysymToKeycode(mw->dpy, XK_q))
480 case VisibilityNotify:
481 if(ev->xvisibility.state && mw->focus)
483 XSetInputFocus(mw->dpy, mw->focus->mini.window, RevertToParent, CurrentTime);