Updating to version 0.20.2
[wmaker-crm.git] / src / superfluous.c
blob56e72b00b57163df8cef4e04fbf2544ce749d104
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"
43 extern WPreferences wPreferences;
46 #ifdef SPEAKER_SOUND
47 static void
48 play(Display *dpy, int pitch, int delay)
50 XKeyboardControl kc;
52 kc.bell_pitch = pitch;
53 kc.bell_percent = 50;
54 kc.bell_duration = delay;
55 XChangeKeyboardControl(dpy, KBBellPitch|KBBellDuration|KBBellPercent,&kc);
56 XBell(dpy, 50);
57 XFlush(dpy);
58 wusleep(delay);
60 #endif
62 #ifdef DEMATERIALIZE_ICON
63 void
64 DoKaboom(WScreen *scr, Window win, int x, int y)
66 RImage *icon;
67 RImage *back;
68 RImage *image;
69 Pixmap pixmap;
70 XImage *ximage;
71 int i;
72 int w, h;
74 h = w = wPreferences.icon_size;
75 if (x < 0 || x + w > scr->scr_width || y < 0 || y + h > scr->scr_height)
76 return;
78 icon = RCreateImageFromDrawable(scr->rcontext, win, None);
79 if (!icon)
80 return;
82 XUnmapWindow(dpy, win);
83 XSync(dpy, False);
85 ximage = XGetImage(dpy, scr->root_win, x, y, w, h, AllPlanes, ZPixmap);
86 back = RCreateImageFromXImage(scr->rcontext, ximage, NULL);
87 XDestroyImage(ximage);
88 if (!back) {
89 RDestroyImage(icon);
90 return;
93 for (i=0; i<DEMATERIALIZE_STEPS; i++) {
94 image = RCloneImage(back);
95 RCombineImagesWithOpaqueness(image, icon,
96 (DEMATERIALIZE_STEPS-1-i)*256/(DEMATERIALIZE_STEPS+2));
97 RConvertImage(scr->rcontext, image, &pixmap);
98 XCopyArea(dpy, pixmap, scr->root_win, scr->copy_gc, 0, 0, w, h, x, y);
99 XFreePixmap(dpy, pixmap);
100 XFlush(dpy);
102 XClearArea(dpy, scr->root_win, x, y, w, h, False);
103 XFlush(dpy);
105 RDestroyImage(icon);
106 RDestroyImage(back);
109 #else /* !DEMATERIALIZE_ICON */
110 void
111 DoKaboom(WScreen *scr, Window win, int x, int y)
113 int i, j, k;
114 int sw=scr->scr_width, sh=scr->scr_height;
115 #define KAB_PRECISION 4
116 int px[PIECES];
117 short py[PIECES];
118 #ifdef ICON_KABOOM_EXTRA
119 short ptx[2][PIECES], pty[2][PIECES];
120 int ll;
121 #endif
122 char pvx[PIECES], pvy[PIECES];
123 char ax[PIECES], ay[PIECES];
124 Pixmap tmp;
126 XSetClipMask(dpy, scr->copy_gc, None);
127 tmp = XCreatePixmap(dpy, scr->root_win, wPreferences.icon_size,
128 wPreferences.icon_size, scr->depth);
129 if (scr->w_visual == DefaultVisual(dpy, scr->screen))
130 XCopyArea(dpy, win, tmp, scr->copy_gc, 0, 0, wPreferences.icon_size,
131 wPreferences.icon_size, 0, 0);
132 else {
133 XImage *image;
135 image = XGetImage(dpy, win, 0, 0, wPreferences.icon_size,
136 wPreferences.icon_size, AllPlanes, ZPixmap);
137 if (!image) {
138 XUnmapWindow(dpy, win);
139 return;
141 XPutImage(dpy, tmp, scr->copy_gc, image, 0, 0, 0, 0,
142 wPreferences.icon_size, wPreferences.icon_size);
143 XDestroyImage(image);
146 for (i=0,k=0; i<wPreferences.icon_size/ICON_KABOOM_PIECE_SIZE && k<PIECES;
147 i++) {
148 for (j=0; j<wPreferences.icon_size/ICON_KABOOM_PIECE_SIZE && k<PIECES;
149 j++) {
150 if (rand()%2) {
151 ax[k]=i;
152 ay[k]=j;
153 px[k]=(x+i*ICON_KABOOM_PIECE_SIZE)<<KAB_PRECISION;
154 py[k]=y+j*ICON_KABOOM_PIECE_SIZE;
155 pvx[k]=rand()%(1<<(KAB_PRECISION+3))-(1<<(KAB_PRECISION+3))/2;
156 pvy[k]=-15-rand()%7;
157 #ifdef ICON_KABOOM_EXTRA
158 for (ll=0; ll<2; ll++) {
159 ptx[ll][k] = px[k];
160 pty[ll][k] = py[k];
162 #endif
163 k++;
164 } else {
165 ax[k]=-1;
170 XUnmapWindow(dpy, win);
172 j=k;
173 while (k>0) {
174 for (i=0; i<j; i++) {
175 if (ax[i]>=0) {
176 int _px = px[i]>>KAB_PRECISION;
177 #ifdef ICON_KABOOM_EXTRA
178 XClearArea(dpy, scr->root_win, ptx[1][i], pty[1][i],
179 ICON_KABOOM_PIECE_SIZE, ICON_KABOOM_PIECE_SIZE,
180 False);
182 ptx[1][i] = ptx[0][i];
183 pty[1][i] = pty[0][i];
184 ptx[0][i] = _px;
185 pty[0][i] = py[i];
186 #else
187 XClearArea(dpy, scr->root_win, _px, py[i],
188 ICON_KABOOM_PIECE_SIZE, ICON_KABOOM_PIECE_SIZE,
189 False);
190 #endif
191 px[i]+=pvx[i];
192 py[i]+=pvy[i];
193 _px = px[i]>>KAB_PRECISION;
194 pvy[i]++;
195 if (_px<-wPreferences.icon_size || _px>sw || py[i]>=sh) {
196 #ifdef ICON_KABOOM_EXTRA
197 if (py[i]>sh && _px<sw && _px>0) {
198 pvy[i] = -(pvy[i]/2);
199 if (abs(pvy[i]) > 3) {
200 py[i] = sh-ICON_KABOOM_PIECE_SIZE;
201 XCopyArea(dpy, tmp, scr->root_win, scr->copy_gc,
202 ax[i]*ICON_KABOOM_PIECE_SIZE,
203 ay[i]*ICON_KABOOM_PIECE_SIZE,
204 ICON_KABOOM_PIECE_SIZE,
205 ICON_KABOOM_PIECE_SIZE,
206 _px, py[i]);
207 } else {
208 ax[i] = -1;
210 } else {
211 ax[i] = -1;
213 if (ax[i]<0) {
214 for (ll=0; ll<2; ll++)
215 XClearArea(dpy, scr->root_win, ptx[ll][i], pty[ll][i],
216 ICON_KABOOM_PIECE_SIZE,
217 ICON_KABOOM_PIECE_SIZE, False);
218 k--;
220 #else /* !ICON_KABOOM_EXTRA */
221 ax[i]=-1;
222 k--;
223 #endif /* !ICON_KABOOM_EXTRA */
224 } else {
225 XCopyArea(dpy, tmp, scr->root_win, scr->copy_gc,
226 ax[i]*ICON_KABOOM_PIECE_SIZE, ay[i]*ICON_KABOOM_PIECE_SIZE,
227 ICON_KABOOM_PIECE_SIZE, ICON_KABOOM_PIECE_SIZE,
228 _px, py[i]);
233 XFlush(dpy);
234 #ifdef SPEAKER_SOUND
235 play(dpy, 100+rand()%250, 12);
236 #else
237 # if (MINIATURIZE_ANIMATION_DELAY_Z > 0)
238 wusleep(MINIATURIZE_ANIMATION_DELAY_Z*2);
239 # endif
240 #endif
242 XFreePixmap(dpy, tmp);
244 #endif /* !DEMATERIALIZE_ICON */
247 Pixmap
248 MakeGhostDock(WDock *dock, int sx, int dx, int y)
250 WScreen *scr = dock->screen_ptr;
251 XImage *img;
252 RImage *back, *dock_image;
253 Pixmap pixmap;
254 int i, virtual_tiles, h, j, n;
255 unsigned long red_mask, green_mask, blue_mask;
257 virtual_tiles = 0;
258 for (i=0; i<dock->max_icons; i++) {
259 if (dock->icon_array[i]!=NULL &&
260 dock->icon_array[i]->yindex > virtual_tiles)
261 virtual_tiles = dock->icon_array[i]->yindex;
263 virtual_tiles++;
264 h = virtual_tiles * wPreferences.icon_size;
265 h = (y + h > scr->scr_height) ? scr->scr_height-y : h;
266 virtual_tiles = h / wPreferences.icon_size; /* The visible ones */
267 if (h % wPreferences.icon_size)
268 virtual_tiles++; /* There is one partially visible tile at end */
270 img=XGetImage(dpy, scr->root_win, dx, y, wPreferences.icon_size, h,
271 AllPlanes, ZPixmap);
272 if (!img)
273 return None;
275 red_mask = img->red_mask;
276 green_mask = img->green_mask;
277 blue_mask = img->blue_mask;
279 back = RCreateImageFromXImage(scr->rcontext, img, NULL);
280 XDestroyImage(img);
281 if (!back) {
282 return None;
285 for (i=0;i<dock->max_icons;i++) {
286 if (dock->icon_array[i]!=NULL &&
287 dock->icon_array[i]->yindex < virtual_tiles) {
288 Pixmap which;
289 j = dock->icon_array[i]->yindex * wPreferences.icon_size;
290 n = (h - j < wPreferences.icon_size) ? h - j :
291 wPreferences.icon_size;
292 if (dock->icon_array[i]->icon->pixmap)
293 which = dock->icon_array[i]->icon->pixmap;
294 else
295 which = dock->icon_array[i]->icon->core->window;
297 img=XGetImage(dpy, which, 0, 0, wPreferences.icon_size, n,
298 AllPlanes, ZPixmap);
300 if (!img){
301 RDestroyImage(back);
302 return None;
304 img->red_mask = red_mask;
305 img->green_mask = green_mask;
306 img->blue_mask = blue_mask;
308 dock_image = RCreateImageFromXImage(scr->rcontext, img, NULL);
309 XDestroyImage(img);
310 if (!dock_image) {
311 RDestroyImage(back);
312 return None;
314 RCombineAreaWithOpaqueness(back, dock_image, 0, 0,
315 wPreferences.icon_size, n,
316 0, j, 30 * 256 / 100);
317 RDestroyImage(dock_image);
322 RConvertImage(scr->rcontext, back, &pixmap);
324 RDestroyImage(back);
326 return pixmap;
330 Pixmap
331 MakeGhostIcon(WScreen *scr, Drawable drawable)
333 RImage *back;
334 RColor color;
335 Pixmap pixmap;
338 if (!drawable)
339 return None;
341 back = RCreateImageFromDrawable(scr->rcontext, drawable, None);
342 if (!back)
343 return None;
345 color.red = 0xff;
346 color.green = 0xff;
347 color.blue = 0xff;
348 color.alpha = 200;
350 RClearImage(back, &color);
351 RConvertImage(scr->rcontext, back, &pixmap);
353 RDestroyImage(back);
355 return pixmap;
360 #ifdef WINDOW_BIRTH_ZOOM
361 void
362 DoWindowBirth(WWindow *wwin)
364 int width = wwin->frame->core->width;
365 int height = wwin->frame->core->height;
366 int w = WMIN(width, 20);
367 int h = WMIN(height, 20);
368 int x, y;
369 int dw, dh;
370 int i;
371 time_t time0 = time(NULL);
373 dw = (width-w)/WINDOW_BIRTH_STEPS;
374 dh = (height-h)/WINDOW_BIRTH_STEPS;
376 x = wwin->frame_x + (width-w)/2;
377 y = wwin->frame_y + (height-h)/2;
379 XMoveResizeWindow(dpy, wwin->frame->core->window, x, y, w, h);
381 XMapWindow(dpy, wwin->frame->core->window);
383 XFlush(dpy);
384 for (i=0; i<WINDOW_BIRTH_STEPS; i++) {
385 x -= dw/2 + dw%2;
386 y -= dh/2 + dh%2;
387 w += dw;
388 h += dh;
389 XMoveResizeWindow(dpy, wwin->frame->core->window, x, y, w, h);
390 XFlush(dpy);
391 /* a timeout */
392 if (time(NULL)-time0 > MAX_ANIMATION_TIME)
393 break;
396 XMoveResizeWindow(dpy, wwin->frame->core->window,
397 wwin->frame_x, wwin->frame_y, width, height);
398 XFlush(dpy);
400 #else
401 void
402 DoWindowBirth(WWindow *wwin)
404 /* dummy stub */
406 #endif