0.51.1 pre snapshot. Be careful, it may be buggy. It fixes some bugs though.
[wmaker-crm.git] / src / superfluous.c
blob2106e6bfbf75c1095c7210270b8a2c7974ef3951
1 /*
2 * Window Maker window manager
3 *
4 * Copyright (c) 1997, 1998 Alfredo K. Kojima
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
19 * USA.
22 #include "wconfig.h"
24 #include <X11/Xlib.h>
25 #include <X11/Xutil.h>
27 #include <stdlib.h>
28 #include <unistd.h>
30 #include <time.h>
32 #include <wraster.h>
34 #include "WindowMaker.h"
35 #include "screen.h"
36 #include "superfluous.h"
37 #include "dock.h"
38 #include "wcore.h"
39 #include "framewin.h"
40 #include "window.h"
41 #include "icon.h"
42 #include "appicon.h"
45 extern WPreferences wPreferences;
48 #ifdef SPEAKER_SOUND
49 static void
50 play(Display *dpy, int pitch, int delay)
52 XKeyboardControl kc;
54 kc.bell_pitch = pitch;
55 kc.bell_percent = 50;
56 kc.bell_duration = delay;
57 XChangeKeyboardControl(dpy, KBBellPitch|KBBellDuration|KBBellPercent,&kc);
58 XBell(dpy, 50);
59 XFlush(dpy);
60 wusleep(delay);
62 #endif
64 #ifdef DEMATERIALIZE_ICON
65 void
66 DoKaboom(WScreen *scr, Window win, int x, int y)
68 RImage *icon;
69 RImage *back;
70 RImage *image;
71 Pixmap pixmap;
72 XImage *ximage;
73 int i;
74 int w, h;
76 h = w = wPreferences.icon_size;
77 if (x < 0 || x + w > scr->scr_width || y < 0 || y + h > scr->scr_height)
78 return;
80 icon = RCreateImageFromDrawable(scr->rcontext, win, None);
81 if (!icon)
82 return;
84 XUnmapWindow(dpy, win);
85 XSync(dpy, False);
87 ximage = XGetImage(dpy, scr->root_win, x, y, w, h, AllPlanes, ZPixmap);
88 back = RCreateImageFromXImage(scr->rcontext, ximage, NULL);
89 XDestroyImage(ximage);
90 if (!back) {
91 RDestroyImage(icon);
92 return;
95 for (i=0; i<DEMATERIALIZE_STEPS; i++) {
96 XEvent foo;
97 if (XCheckTypedWindowEvent(dpy, scr->root_win, ButtonPressMask,
98 &foo)) {
99 XClearWindow(dpy, scr->root_win);
100 break;
102 image = RCloneImage(back);
103 RCombineImagesWithOpaqueness(image, icon,
104 (DEMATERIALIZE_STEPS-1-i)*256/(DEMATERIALIZE_STEPS+2));
105 RConvertImage(scr->rcontext, image, &pixmap);
106 XCopyArea(dpy, pixmap, scr->root_win, scr->copy_gc, 0, 0, w, h, x, y);
107 XFreePixmap(dpy, pixmap);
108 XFlush(dpy);
110 XClearArea(dpy, scr->root_win, x, y, w, h, False);
111 XFlush(dpy);
113 RDestroyImage(icon);
114 RDestroyImage(back);
117 #else /* !DEMATERIALIZE_ICON */
118 void
119 DoKaboom(WScreen *scr, Window win, int x, int y)
121 int i, j, k;
122 int sw=scr->scr_width, sh=scr->scr_height;
123 #define KAB_PRECISION 4
124 int px[PIECES];
125 short py[PIECES];
126 #ifdef ICON_KABOOM_EXTRA
127 short ptx[2][PIECES], pty[2][PIECES];
128 int ll;
129 #endif
130 char pvx[PIECES], pvy[PIECES];
131 /* in MkLinux/PPC gcc seems to think that char is unsigned? */
132 signed char ax[PIECES], ay[PIECES];
133 Pixmap tmp;
135 XSetClipMask(dpy, scr->copy_gc, None);
136 tmp = XCreatePixmap(dpy, scr->root_win, wPreferences.icon_size,
137 wPreferences.icon_size, scr->depth);
138 if (scr->w_visual == DefaultVisual(dpy, scr->screen))
139 XCopyArea(dpy, win, tmp, scr->copy_gc, 0, 0, wPreferences.icon_size,
140 wPreferences.icon_size, 0, 0);
141 else {
142 XImage *image;
144 image = XGetImage(dpy, win, 0, 0, wPreferences.icon_size,
145 wPreferences.icon_size, AllPlanes, ZPixmap);
146 if (!image) {
147 XUnmapWindow(dpy, win);
148 return;
150 XPutImage(dpy, tmp, scr->copy_gc, image, 0, 0, 0, 0,
151 wPreferences.icon_size, wPreferences.icon_size);
152 XDestroyImage(image);
155 for (i=0,k=0; i<wPreferences.icon_size/ICON_KABOOM_PIECE_SIZE && k<PIECES;
156 i++) {
157 for (j=0; j<wPreferences.icon_size/ICON_KABOOM_PIECE_SIZE && k<PIECES;
158 j++) {
159 if (rand()%2) {
160 ax[k]=i;
161 ay[k]=j;
162 px[k]=(x+i*ICON_KABOOM_PIECE_SIZE)<<KAB_PRECISION;
163 py[k]=y+j*ICON_KABOOM_PIECE_SIZE;
164 pvx[k]=rand()%(1<<(KAB_PRECISION+3))-(1<<(KAB_PRECISION+3))/2;
165 pvy[k]=-15-rand()%7;
166 #ifdef ICON_KABOOM_EXTRA
167 for (ll=0; ll<2; ll++) {
168 ptx[ll][k] = px[k];
169 pty[ll][k] = py[k];
171 #endif
172 k++;
173 } else {
174 ax[k]=-1;
179 XUnmapWindow(dpy, win);
181 j=k;
182 while (k>0) {
183 XEvent foo;
185 if (XCheckTypedEvent(dpy, ButtonPress, &foo)) {
186 XPutBackEvent(dpy, &foo);
187 XClearWindow(dpy, scr->root_win);
188 break;
191 for (i=0; i<j ; i++) {
192 if (ax[i]>=0) {
193 int _px = px[i]>>KAB_PRECISION;
194 #ifdef ICON_KABOOM_EXTRA
195 XClearArea(dpy, scr->root_win, ptx[1][i], pty[1][i],
196 ICON_KABOOM_PIECE_SIZE, ICON_KABOOM_PIECE_SIZE,
197 False);
199 ptx[1][i] = ptx[0][i];
200 pty[1][i] = pty[0][i];
201 ptx[0][i] = _px;
202 pty[0][i] = py[i];
203 #else
204 XClearArea(dpy, scr->root_win, _px, py[i],
205 ICON_KABOOM_PIECE_SIZE, ICON_KABOOM_PIECE_SIZE,
206 False);
207 #endif
208 px[i]+=pvx[i];
209 py[i]+=pvy[i];
210 _px = px[i]>>KAB_PRECISION;
211 pvy[i]++;
212 if (_px<-wPreferences.icon_size || _px>sw || py[i]>=sh) {
213 #ifdef ICON_KABOOM_EXTRA
214 if (py[i]>sh && _px<sw && _px>0) {
215 pvy[i] = -(pvy[i]/2);
216 if (abs(pvy[i]) > 3) {
217 py[i] = sh-ICON_KABOOM_PIECE_SIZE;
218 XCopyArea(dpy, tmp, scr->root_win, scr->copy_gc,
219 ax[i]*ICON_KABOOM_PIECE_SIZE,
220 ay[i]*ICON_KABOOM_PIECE_SIZE,
221 ICON_KABOOM_PIECE_SIZE,
222 ICON_KABOOM_PIECE_SIZE,
223 _px, py[i]);
224 } else {
225 ax[i] = -1;
227 } else {
228 ax[i] = -1;
230 if (ax[i]<0) {
231 for (ll=0; ll<2; ll++)
232 XClearArea(dpy, scr->root_win, ptx[ll][i], pty[ll][i],
233 ICON_KABOOM_PIECE_SIZE,
234 ICON_KABOOM_PIECE_SIZE, False);
235 k--;
237 #else /* !ICON_KABOOM_EXTRA */
238 ax[i]=-1;
239 k--;
240 #endif /* !ICON_KABOOM_EXTRA */
241 } else {
242 XCopyArea(dpy, tmp, scr->root_win, scr->copy_gc,
243 ax[i]*ICON_KABOOM_PIECE_SIZE, ay[i]*ICON_KABOOM_PIECE_SIZE,
244 ICON_KABOOM_PIECE_SIZE, ICON_KABOOM_PIECE_SIZE,
245 _px, py[i]);
250 XFlush(dpy);
251 #ifdef SPEAKER_SOUND
252 play(dpy, 100+rand()%250, 12);
253 #else
254 # if (MINIATURIZE_ANIMATION_DELAY_Z > 0)
255 wusleep(MINIATURIZE_ANIMATION_DELAY_Z*2);
256 # endif
257 #endif
260 XFreePixmap(dpy, tmp);
262 #endif /* !DEMATERIALIZE_ICON */
265 Pixmap
266 MakeGhostDock(WDock *dock, int sx, int dx, int y)
268 WScreen *scr = dock->screen_ptr;
269 XImage *img;
270 RImage *back, *dock_image;
271 Pixmap pixmap;
272 int i, virtual_tiles, h, j, n;
273 unsigned long red_mask, green_mask, blue_mask;
275 virtual_tiles = 0;
276 for (i=0; i<dock->max_icons; i++) {
277 if (dock->icon_array[i]!=NULL &&
278 dock->icon_array[i]->yindex > virtual_tiles)
279 virtual_tiles = dock->icon_array[i]->yindex;
281 virtual_tiles++;
282 h = virtual_tiles * wPreferences.icon_size;
283 h = (y + h > scr->scr_height) ? scr->scr_height-y : h;
284 virtual_tiles = h / wPreferences.icon_size; /* The visible ones */
285 if (h % wPreferences.icon_size)
286 virtual_tiles++; /* There is one partially visible tile at end */
288 img=XGetImage(dpy, scr->root_win, dx, y, wPreferences.icon_size, h,
289 AllPlanes, ZPixmap);
290 if (!img)
291 return None;
293 red_mask = img->red_mask;
294 green_mask = img->green_mask;
295 blue_mask = img->blue_mask;
297 back = RCreateImageFromXImage(scr->rcontext, img, NULL);
298 XDestroyImage(img);
299 if (!back) {
300 return None;
303 for (i=0;i<dock->max_icons;i++) {
304 if (dock->icon_array[i]!=NULL &&
305 dock->icon_array[i]->yindex < virtual_tiles) {
306 Pixmap which;
307 j = dock->icon_array[i]->yindex * wPreferences.icon_size;
308 n = (h - j < wPreferences.icon_size) ? h - j :
309 wPreferences.icon_size;
310 if (dock->icon_array[i]->icon->pixmap)
311 which = dock->icon_array[i]->icon->pixmap;
312 else
313 which = dock->icon_array[i]->icon->core->window;
315 img=XGetImage(dpy, which, 0, 0, wPreferences.icon_size, n,
316 AllPlanes, ZPixmap);
318 if (!img){
319 RDestroyImage(back);
320 return None;
322 img->red_mask = red_mask;
323 img->green_mask = green_mask;
324 img->blue_mask = blue_mask;
326 dock_image = RCreateImageFromXImage(scr->rcontext, img, NULL);
327 XDestroyImage(img);
328 if (!dock_image) {
329 RDestroyImage(back);
330 return None;
332 RCombineAreaWithOpaqueness(back, dock_image, 0, 0,
333 wPreferences.icon_size, n,
334 0, j, 30 * 256 / 100);
335 RDestroyImage(dock_image);
340 RConvertImage(scr->rcontext, back, &pixmap);
342 RDestroyImage(back);
344 return pixmap;
348 Pixmap
349 MakeGhostIcon(WScreen *scr, Drawable drawable)
351 RImage *back;
352 RColor color;
353 Pixmap pixmap;
356 if (!drawable)
357 return None;
359 back = RCreateImageFromDrawable(scr->rcontext, drawable, None);
360 if (!back)
361 return None;
363 color.red = 0xff;
364 color.green = 0xff;
365 color.blue = 0xff;
366 color.alpha = 200;
368 RClearImage(back, &color);
369 RConvertImage(scr->rcontext, back, &pixmap);
371 RDestroyImage(back);
373 return pixmap;
378 #ifdef WINDOW_BIRTH_ZOOM
379 void
380 DoWindowBirth(WWindow *wwin)
382 int width = wwin->frame->core->width;
383 int height = wwin->frame->core->height;
384 int w = WMIN(width, 20);
385 int h = WMIN(height, 20);
386 int x, y;
387 int dw, dh;
388 int i;
389 time_t time0 = time(NULL);
391 dw = (width-w)/WINDOW_BIRTH_STEPS;
392 dh = (height-h)/WINDOW_BIRTH_STEPS;
394 x = wwin->frame_x + (width-w)/2;
395 y = wwin->frame_y + (height-h)/2;
397 XMoveResizeWindow(dpy, wwin->frame->core->window, x, y, w, h);
399 XMapWindow(dpy, wwin->frame->core->window);
401 XFlush(dpy);
402 for (i=0; i<WINDOW_BIRTH_STEPS; i++) {
403 x -= dw/2 + dw%2;
404 y -= dh/2 + dh%2;
405 w += dw;
406 h += dh;
407 XMoveResizeWindow(dpy, wwin->frame->core->window, x, y, w, h);
408 XFlush(dpy);
409 /* a timeout */
410 if (time(NULL)-time0 > MAX_ANIMATION_TIME)
411 break;
414 XMoveResizeWindow(dpy, wwin->frame->core->window,
415 wwin->frame_x, wwin->frame_y, width, height);
416 XFlush(dpy);
418 #else
419 void
420 DoWindowBirth(WWindow *wwin)
422 /* dummy stub */
424 #endif
428 #ifdef SILLYNESS
429 static WMPixmap *data[12];
432 static Bool
433 loadData(WScreen *scr)
435 FILE *f;
436 int i;
437 RImage *image;
438 Pixmap d[12];
440 f = fopen(PKGDATADIR"/xtree.dat", "r");
441 if (!f)
442 return False;
444 image = RCreateImage(50, 50, False);
445 if (!image) {
446 fclose(f);
447 return False;
450 for (i = 0; i < 12; i++) {
451 if (fread(image->data[0], 50*50, 1, f)!=1) {
452 goto error;
454 if (fread(image->data[1], 50*50, 1, f)!=1) {
455 goto error;
457 if (fread(image->data[2], 50*50, 1, f)!=1) {
458 goto error;
460 if (!RConvertImage(scr->rcontext, image, &(d[i]))) {
461 goto error;
464 RDestroyImage(image);
466 fclose(f);
468 for (i=0; i<12; i++) {
469 data[i] = WMCreatePixmapFromXPixmaps(scr->wmscreen, d[i], None, 50, 50,
470 scr->w_depth);
473 return True;
475 error:
476 RDestroyImage(image);
478 fclose(f);
480 while (--i > 0) {
481 XFreePixmap(dpy, d[i]);
484 return False;
488 WMPixmap*
489 DoXThing(WWindow *wwin)
491 static int order = 0;
493 order++;
495 return data[order % 12];
499 Bool
500 InitXThing(WScreen *scr)
502 time_t t;
503 struct tm *l;
504 static int i = 0;
506 if (i)
507 return True;
509 t = time(NULL);
510 l = localtime(&t);
511 if ((l->tm_mon!=12||l->tm_mday<24||l->tm_mday>26)) {
512 return False;
515 if (!loadData(scr))
516 return False;
518 i = 1;
520 return True;
523 #endif /* SILLYNESS */