Update for 0.51.0
[wmaker-crm.git] / src / superfluous.c
blobb8cac573117b80cdbb5f086ba44f6ec4d9db10ef
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 (XCheckTypedWindowEvent(dpy, scr->root_win, ButtonPressMask,
186 &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
259 XFreePixmap(dpy, tmp);
261 #endif /* !DEMATERIALIZE_ICON */
264 Pixmap
265 MakeGhostDock(WDock *dock, int sx, int dx, int y)
267 WScreen *scr = dock->screen_ptr;
268 XImage *img;
269 RImage *back, *dock_image;
270 Pixmap pixmap;
271 int i, virtual_tiles, h, j, n;
272 unsigned long red_mask, green_mask, blue_mask;
274 virtual_tiles = 0;
275 for (i=0; i<dock->max_icons; i++) {
276 if (dock->icon_array[i]!=NULL &&
277 dock->icon_array[i]->yindex > virtual_tiles)
278 virtual_tiles = dock->icon_array[i]->yindex;
280 virtual_tiles++;
281 h = virtual_tiles * wPreferences.icon_size;
282 h = (y + h > scr->scr_height) ? scr->scr_height-y : h;
283 virtual_tiles = h / wPreferences.icon_size; /* The visible ones */
284 if (h % wPreferences.icon_size)
285 virtual_tiles++; /* There is one partially visible tile at end */
287 img=XGetImage(dpy, scr->root_win, dx, y, wPreferences.icon_size, h,
288 AllPlanes, ZPixmap);
289 if (!img)
290 return None;
292 red_mask = img->red_mask;
293 green_mask = img->green_mask;
294 blue_mask = img->blue_mask;
296 back = RCreateImageFromXImage(scr->rcontext, img, NULL);
297 XDestroyImage(img);
298 if (!back) {
299 return None;
302 for (i=0;i<dock->max_icons;i++) {
303 if (dock->icon_array[i]!=NULL &&
304 dock->icon_array[i]->yindex < virtual_tiles) {
305 Pixmap which;
306 j = dock->icon_array[i]->yindex * wPreferences.icon_size;
307 n = (h - j < wPreferences.icon_size) ? h - j :
308 wPreferences.icon_size;
309 if (dock->icon_array[i]->icon->pixmap)
310 which = dock->icon_array[i]->icon->pixmap;
311 else
312 which = dock->icon_array[i]->icon->core->window;
314 img=XGetImage(dpy, which, 0, 0, wPreferences.icon_size, n,
315 AllPlanes, ZPixmap);
317 if (!img){
318 RDestroyImage(back);
319 return None;
321 img->red_mask = red_mask;
322 img->green_mask = green_mask;
323 img->blue_mask = blue_mask;
325 dock_image = RCreateImageFromXImage(scr->rcontext, img, NULL);
326 XDestroyImage(img);
327 if (!dock_image) {
328 RDestroyImage(back);
329 return None;
331 RCombineAreaWithOpaqueness(back, dock_image, 0, 0,
332 wPreferences.icon_size, n,
333 0, j, 30 * 256 / 100);
334 RDestroyImage(dock_image);
339 RConvertImage(scr->rcontext, back, &pixmap);
341 RDestroyImage(back);
343 return pixmap;
347 Pixmap
348 MakeGhostIcon(WScreen *scr, Drawable drawable)
350 RImage *back;
351 RColor color;
352 Pixmap pixmap;
355 if (!drawable)
356 return None;
358 back = RCreateImageFromDrawable(scr->rcontext, drawable, None);
359 if (!back)
360 return None;
362 color.red = 0xff;
363 color.green = 0xff;
364 color.blue = 0xff;
365 color.alpha = 200;
367 RClearImage(back, &color);
368 RConvertImage(scr->rcontext, back, &pixmap);
370 RDestroyImage(back);
372 return pixmap;
377 #ifdef WINDOW_BIRTH_ZOOM
378 void
379 DoWindowBirth(WWindow *wwin)
381 int width = wwin->frame->core->width;
382 int height = wwin->frame->core->height;
383 int w = WMIN(width, 20);
384 int h = WMIN(height, 20);
385 int x, y;
386 int dw, dh;
387 int i;
388 time_t time0 = time(NULL);
390 dw = (width-w)/WINDOW_BIRTH_STEPS;
391 dh = (height-h)/WINDOW_BIRTH_STEPS;
393 x = wwin->frame_x + (width-w)/2;
394 y = wwin->frame_y + (height-h)/2;
396 XMoveResizeWindow(dpy, wwin->frame->core->window, x, y, w, h);
398 XMapWindow(dpy, wwin->frame->core->window);
400 XFlush(dpy);
401 for (i=0; i<WINDOW_BIRTH_STEPS; i++) {
402 x -= dw/2 + dw%2;
403 y -= dh/2 + dh%2;
404 w += dw;
405 h += dh;
406 XMoveResizeWindow(dpy, wwin->frame->core->window, x, y, w, h);
407 XFlush(dpy);
408 /* a timeout */
409 if (time(NULL)-time0 > MAX_ANIMATION_TIME)
410 break;
413 XMoveResizeWindow(dpy, wwin->frame->core->window,
414 wwin->frame_x, wwin->frame_y, width, height);
415 XFlush(dpy);
417 #else
418 void
419 DoWindowBirth(WWindow *wwin)
421 /* dummy stub */
423 #endif
427 #ifdef SILLYNESS
428 static WMPixmap *data[12];
431 static Bool
432 loadData(WScreen *scr)
434 FILE *f;
435 int i;
436 RImage *image;
437 Pixmap d[12];
439 f = fopen(PKGDATADIR"/xtree.dat", "r");
440 if (!f)
441 return False;
443 image = RCreateImage(50, 50, False);
444 if (!image) {
445 fclose(f);
446 return False;
449 for (i = 0; i < 12; i++) {
450 if (fread(image->data[0], 50*50, 1, f)!=1) {
451 goto error;
453 if (fread(image->data[1], 50*50, 1, f)!=1) {
454 goto error;
456 if (fread(image->data[2], 50*50, 1, f)!=1) {
457 goto error;
459 if (!RConvertImage(scr->rcontext, image, &(d[i]))) {
460 goto error;
463 RDestroyImage(image);
465 fclose(f);
467 for (i=0; i<12; i++) {
468 data[i] = WMCreatePixmapFromXPixmaps(scr->wmscreen, d[i], None, 50, 50,
469 scr->w_depth);
472 return True;
474 error:
475 RDestroyImage(image);
477 fclose(f);
479 while (--i > 0) {
480 XFreePixmap(dpy, d[i]);
483 return False;
487 WMPixmap*
488 DoXThing(WWindow *wwin)
490 static int order = 0;
492 order++;
494 return data[order % 12];
498 Bool
499 InitXThing(WScreen *scr)
501 time_t t;
502 struct tm *l;
503 static int i = 0;
505 if (i)
506 return True;
508 t = time(NULL);
509 l = localtime(&t);
510 if ((l->tm_mon!=12||l->tm_mday<24||l->tm_mday>26)) {
511 return False;
514 if (!loadData(scr))
515 return False;
517 i = 1;
519 return True;
522 #endif /* SILLYNESS */