2 * Window Maker window manager
4 * Copyright (c) 1997, 1998 Alfredo K. Kojima
5 * Copyright (c) 1997, 1998 Dan Pascu
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
26 #include <X11/Xutil.h>
35 #include "WindowMaker.h"
37 #include "superfluous.h"
46 extern WPreferences wPreferences
;
51 play(Display
*dpy
, int pitch
, int delay
)
55 kc
.bell_pitch
= pitch
;
57 kc
.bell_duration
= delay
;
58 XChangeKeyboardControl(dpy
, KBBellPitch
|KBBellDuration
|KBBellPercent
,&kc
);
67 #ifdef DEMATERIALIZE_ICON
69 DoKaboom(WScreen
*scr
, Window win
, int x
, int y
)
83 h
= w
= wPreferences
.icon_size
;
84 if (x
< 0 || x
+ w
> scr
->scr_width
|| y
< 0 || y
+ h
> scr
->scr_height
)
87 icon
= RCreateImageFromDrawable(scr
->rcontext
, win
, None
);
91 gcv
.foreground
= scr
->white_pixel
;
92 gcv
.background
= scr
->black_pixel
;
93 gcv
.graphics_exposures
= False
;
94 gcv
.subwindow_mode
= IncludeInferiors
;
95 gc
= XCreateGC(dpy
, scr
->w_win
, GCForeground
|GCBackground
|GCSubwindowMode
96 |GCGraphicsExposures
, &gcv
);
100 RConvertImage(scr
->rcontext
, icon
, &pixmap
);
101 XUnmapWindow(dpy
, win
);
103 ximage
= XGetImage(dpy
, scr
->root_win
, x
, y
, w
, h
, AllPlanes
, ZPixmap
);
104 XCopyArea(dpy
, pixmap
, scr
->root_win
, gc
, 0, 0, w
, h
, x
, y
);
105 XFreePixmap(dpy
,pixmap
);
107 back
= RCreateImageFromXImage(scr
->rcontext
, ximage
, NULL
);
108 XDestroyImage(ximage
);
115 for (i
=0,run
=0; i
<DEMATERIALIZE_STEPS
; i
++) {
117 if (!run
&& XCheckTypedEvent(dpy
, ButtonPress
, &foo
)) {
119 XPutBackEvent(dpy
, &foo
);
121 image
= RCloneImage(back
);
122 RCombineImagesWithOpaqueness(image
, icon
,
123 (DEMATERIALIZE_STEPS
-1-i
)*256/(DEMATERIALIZE_STEPS
+2));
124 RConvertImage(scr
->rcontext
, image
, &pixmap
);
125 XCopyArea(dpy
, pixmap
, scr
->root_win
, gc
, 0, 0, w
, h
, x
, y
);
126 XFreePixmap(dpy
, pixmap
);
128 if(!run
) wusleep(1000);
131 while (XCheckTypedEvent(dpy
, MotionNotify
, &event
)) {
140 #endif /* DEMATERIALIZE_ICON */
147 #ifdef NORMAL_ICON_KABOOM
149 DoKaboom(WScreen
*scr
, Window win
, int x
, int y
)
152 int sw
=scr
->scr_width
, sh
=scr
->scr_height
;
153 #define KAB_PRECISION 4
156 #ifdef ICON_KABOOM_EXTRA
157 short ptx
[2][PIECES
], pty
[2][PIECES
];
160 char pvx
[PIECES
], pvy
[PIECES
];
161 /* in MkLinux/PPC gcc seems to think that char is unsigned? */
162 signed char ax
[PIECES
], ay
[PIECES
];
165 XSetClipMask(dpy
, scr
->copy_gc
, None
);
166 tmp
= XCreatePixmap(dpy
, scr
->root_win
, wPreferences
.icon_size
,
167 wPreferences
.icon_size
, scr
->depth
);
168 if (scr
->w_visual
== DefaultVisual(dpy
, scr
->screen
))
169 XCopyArea(dpy
, win
, tmp
, scr
->copy_gc
, 0, 0, wPreferences
.icon_size
,
170 wPreferences
.icon_size
, 0, 0);
174 image
= XGetImage(dpy
, win
, 0, 0, wPreferences
.icon_size
,
175 wPreferences
.icon_size
, AllPlanes
, ZPixmap
);
177 XUnmapWindow(dpy
, win
);
180 XPutImage(dpy
, tmp
, scr
->copy_gc
, image
, 0, 0, 0, 0,
181 wPreferences
.icon_size
, wPreferences
.icon_size
);
182 XDestroyImage(image
);
185 for (i
=0,k
=0; i
<wPreferences
.icon_size
/ICON_KABOOM_PIECE_SIZE
&& k
<PIECES
;
187 for (j
=0; j
<wPreferences
.icon_size
/ICON_KABOOM_PIECE_SIZE
&& k
<PIECES
;
192 px
[k
]=(x
+i
*ICON_KABOOM_PIECE_SIZE
)<<KAB_PRECISION
;
193 py
[k
]=y
+j
*ICON_KABOOM_PIECE_SIZE
;
194 pvx
[k
]=rand()%(1<<(KAB_PRECISION
+3))-(1<<(KAB_PRECISION
+3))/2;
196 #ifdef ICON_KABOOM_EXTRA
197 for (ll
=0; ll
<2; ll
++) {
209 XUnmapWindow(dpy
, win
);
215 if (XCheckTypedEvent(dpy
, ButtonPress
, &foo
)) {
216 XPutBackEvent(dpy
, &foo
);
217 XClearWindow(dpy
, scr
->root_win
);
221 for (i
=0; i
<j
; i
++) {
223 int _px
= px
[i
]>>KAB_PRECISION
;
224 #ifdef ICON_KABOOM_EXTRA
225 XClearArea(dpy
, scr
->root_win
, ptx
[1][i
], pty
[1][i
],
226 ICON_KABOOM_PIECE_SIZE
, ICON_KABOOM_PIECE_SIZE
,
229 ptx
[1][i
] = ptx
[0][i
];
230 pty
[1][i
] = pty
[0][i
];
234 XClearArea(dpy
, scr
->root_win
, _px
, py
[i
],
235 ICON_KABOOM_PIECE_SIZE
, ICON_KABOOM_PIECE_SIZE
,
240 _px
= px
[i
]>>KAB_PRECISION
;
242 if (_px
<-wPreferences
.icon_size
|| _px
>sw
|| py
[i
]>=sh
) {
243 #ifdef ICON_KABOOM_EXTRA
244 if (py
[i
]>sh
&& _px
<sw
&& _px
>0) {
245 pvy
[i
] = -(pvy
[i
]/2);
246 if (abs(pvy
[i
]) > 3) {
247 py
[i
] = sh
-ICON_KABOOM_PIECE_SIZE
;
248 XCopyArea(dpy
, tmp
, scr
->root_win
, scr
->copy_gc
,
249 ax
[i
]*ICON_KABOOM_PIECE_SIZE
,
250 ay
[i
]*ICON_KABOOM_PIECE_SIZE
,
251 ICON_KABOOM_PIECE_SIZE
,
252 ICON_KABOOM_PIECE_SIZE
,
261 for (ll
=0; ll
<2; ll
++)
262 XClearArea(dpy
, scr
->root_win
, ptx
[ll
][i
], pty
[ll
][i
],
263 ICON_KABOOM_PIECE_SIZE
,
264 ICON_KABOOM_PIECE_SIZE
, False
);
267 #else /* !ICON_KABOOM_EXTRA */
270 #endif /* !ICON_KABOOM_EXTRA */
272 XCopyArea(dpy
, tmp
, scr
->root_win
, scr
->copy_gc
,
273 ax
[i
]*ICON_KABOOM_PIECE_SIZE
, ay
[i
]*ICON_KABOOM_PIECE_SIZE
,
274 ICON_KABOOM_PIECE_SIZE
, ICON_KABOOM_PIECE_SIZE
,
282 play(dpy
, 100+rand()%250, 12);
284 # if (MINIATURIZE_ANIMATION_DELAY_Z > 0)
285 wusleep(MINIATURIZE_ANIMATION_DELAY_Z
*2);
290 XFreePixmap(dpy
, tmp
);
292 #endif /* NORMAL_ICON_KABOOM */
296 MakeGhostDock(WDock
*dock
, int sx
, int dx
, int y
)
298 WScreen
*scr
= dock
->screen_ptr
;
300 RImage
*back
, *dock_image
;
302 int i
, virtual_tiles
, h
, j
, n
;
303 unsigned long red_mask
, green_mask
, blue_mask
;
306 for (i
=0; i
<dock
->max_icons
; i
++) {
307 if (dock
->icon_array
[i
]!=NULL
&&
308 dock
->icon_array
[i
]->yindex
> virtual_tiles
)
309 virtual_tiles
= dock
->icon_array
[i
]->yindex
;
312 h
= virtual_tiles
* wPreferences
.icon_size
;
313 h
= (y
+ h
> scr
->scr_height
) ? scr
->scr_height
-y
: h
;
314 virtual_tiles
= h
/ wPreferences
.icon_size
; /* The visible ones */
315 if (h
% wPreferences
.icon_size
)
316 virtual_tiles
++; /* There is one partially visible tile at end */
318 img
=XGetImage(dpy
, scr
->root_win
, dx
, y
, wPreferences
.icon_size
, h
,
323 red_mask
= img
->red_mask
;
324 green_mask
= img
->green_mask
;
325 blue_mask
= img
->blue_mask
;
327 back
= RCreateImageFromXImage(scr
->rcontext
, img
, NULL
);
333 for (i
=0;i
<dock
->max_icons
;i
++) {
334 if (dock
->icon_array
[i
]!=NULL
&&
335 dock
->icon_array
[i
]->yindex
< virtual_tiles
) {
337 j
= dock
->icon_array
[i
]->yindex
* wPreferences
.icon_size
;
338 n
= (h
- j
< wPreferences
.icon_size
) ? h
- j
:
339 wPreferences
.icon_size
;
340 if (dock
->icon_array
[i
]->icon
->pixmap
)
341 which
= dock
->icon_array
[i
]->icon
->pixmap
;
343 which
= dock
->icon_array
[i
]->icon
->core
->window
;
345 img
=XGetImage(dpy
, which
, 0, 0, wPreferences
.icon_size
, n
,
352 img
->red_mask
= red_mask
;
353 img
->green_mask
= green_mask
;
354 img
->blue_mask
= blue_mask
;
356 dock_image
= RCreateImageFromXImage(scr
->rcontext
, img
, NULL
);
362 RCombineAreaWithOpaqueness(back
, dock_image
, 0, 0,
363 wPreferences
.icon_size
, n
,
364 0, j
, 30 * 256 / 100);
365 RReleaseImage(dock_image
);
370 RConvertImage(scr
->rcontext
, back
, &pixmap
);
379 MakeGhostIcon(WScreen
*scr
, Drawable drawable
)
389 back
= RCreateImageFromDrawable(scr
->rcontext
, drawable
, None
);
398 RClearImage(back
, &color
);
399 RConvertImage(scr
->rcontext
, back
, &pixmap
);
408 #ifdef WINDOW_BIRTH_ZOOM
410 DoWindowBirth(WWindow
*wwin
)
412 int width
= wwin
->frame
->core
->width
;
413 int height
= wwin
->frame
->core
->height
;
414 int w
= WMIN(width
, 20);
415 int h
= WMIN(height
, 20);
419 time_t time0
= time(NULL
);
421 dw
= (width
-w
)/WINDOW_BIRTH_STEPS
;
422 dh
= (height
-h
)/WINDOW_BIRTH_STEPS
;
424 x
= wwin
->frame_x
+ (width
-w
)/2;
425 y
= wwin
->frame_y
+ (height
-h
)/2;
427 XMoveResizeWindow(dpy
, wwin
->frame
->core
->window
, x
, y
, w
, h
);
429 XMapWindow(dpy
, wwin
->frame
->core
->window
);
432 for (i
=0; i
<WINDOW_BIRTH_STEPS
; i
++) {
437 XMoveResizeWindow(dpy
, wwin
->frame
->core
->window
, x
, y
, w
, h
);
440 if (time(NULL
)-time0
> MAX_ANIMATION_TIME
)
444 XMoveResizeWindow(dpy
, wwin
->frame
->core
->window
,
445 wwin
->frame_x
, wwin
->frame_y
, width
, height
);
450 DoWindowBirth(WWindow
*wwin
)
462 static WMPixmap
*data
[12];
465 loadData(WScreen
*scr
)
472 f
= fopen(PKGDATADIR
"/xtree.dat", "r");
476 image
= RCreateImage(50, 50, False
);
482 for (i
= 0; i
< 12; i
++) {
483 if (fread(image
->data
, 50*50*3, 1, f
)!=1) {
486 if (!RConvertImage(scr
->rcontext
, image
, &(d
[i
]))) {
490 RReleaseImage(image
);
494 for (i
=0; i
<12; i
++) {
495 data
[i
] = WMCreatePixmapFromXPixmaps(scr
->wmscreen
, d
[i
], None
, 50, 50,
502 RReleaseImage(image
);
507 XFreePixmap(dpy
, d
[i
]);
515 DoXThing(WWindow
*wwin
)
517 static int order
= 0;
521 return data
[order
% 12];
526 InitXThing(WScreen
*scr
)
537 if ((l
->tm_mon
!=11||l
->tm_mday
<24||l
->tm_mday
>26)) {
549 #endif /* SILLYNESS */
552 #ifdef GHOST_WINDOW_MOVE
568 /* the combined image */
577 InitGhostWindowMove(WWindow
*wwin
)
579 _GhostWindowData
*gdata
;
580 WScreen
*scr
= wwin
->screen_ptr
;
585 gdata
= wmalloc(sizeof(_GhostWindowData
));
587 gdata
->width
= wwin
->frame
->core
->width
;
588 gdata
->height
= wwin
->frame
->core
->height
;
590 gdata
->iniX
= wwin
->frame_x
;
591 gdata
->iniY
= wwin
->frame_y
;
593 gdata
->boxX
= wwin
->frame_x
;
594 gdata
->boxY
= wwin
->frame_y
;
597 XCreateSimpleWindow(dpy
, scr
->root_win
, wwin
->frame_x
, wwin
->frame_y
,
598 gdata
->width
, gdata
->height
, 0, 0, 0);
600 gdata
->winImage
= RGetXImage(scr
->rcontext
, wwin
->frame
->core
->window
,
601 0, 0, gdata
->width
, gdata
->height
);
603 gdata
->backImage
= RCreateXImage(scr
->rcontext
, scr
->w_depth
,
604 gdata
->width
, gdata
->height
);
606 memcpy(gdata
->backImage
->image
->data
, gdata
->winImage
->image
->data
,
607 gdata
->winImage
->image
->bytes_per_line
* gdata
->height
);
609 gdata
->image
= RCreateXImage(scr
->rcontext
, scr
->w_depth
,
610 gdata
->width
, gdata
->height
);
612 ptr
= (unsigned short*)gdata
->winImage
->image
->data
;
614 mask
= 0x7b00|0x3d0|0x1e;
617 i
< gdata
->winImage
->image
->bytes_per_line
* gdata
->height
;
628 mergeGhostWindow(_GhostWindowData
*gdata
)
630 register unsigned short *ptrw
, *ptrb
, *ptr
;
634 ptr
= (unsigned short*)gdata
->image
->image
->data
;
635 ptrw
= (unsigned short*)gdata
->winImage
->image
->data
;
636 ptrb
= (unsigned short*)gdata
->backImage
->image
->data
;
638 count
= gdata
->winImage
->image
->bytes_per_line
* gdata
->height
;
641 *ptr
= (*ptrw
+ *ptrb
) >> 1;
651 UpdateGhostWindowMove(void *data
, int x
, int y
)
653 _GhostWindowData
*gdata
= (_GhostWindowData
*)data
;
654 WScreen
*scr
= gdata
->scr
;
656 /* no intersection of new background with current */
657 if (x
+ gdata
->width
<= gdata
->boxX
658 || x
>= gdata
->boxX
+ gdata
->width
659 || y
+ gdata
->height
<= gdata
->boxY
660 || y
>= gdata
->boxY
+ gdata
->height
) {
663 RDestroyXImage(gdata
->backImage
);
665 gdata
->backImage
= RGetXImage(scr
->rcontext
, scr
->root_win
, x
, y
,
666 gdata
->width
, gdata
->height
);
668 ptr
= (unsigned short*)gdata
->backImage
->image
->data
;
670 mask
= 0x7b00|0x3d0|0x1e;
673 i
< gdata
->winImage
->image
->bytes_per_line
* gdata
->height
;
682 unsigned char *backP
= gdata
->backImage
->image
->data
;
683 unsigned char *winP
= gdata
->winImage
->image
->data
;
684 int backLineLen
= gdata
->backImage
->image
->bytes_per_line
;
685 int winLineLen
= gdata
->winImage
->image
->bytes_per_line
;
687 /* 1st move the area of the current backImage that overlaps
688 * the new backImage to it's new position */
690 if (x
< gdata
->boxX
) {
691 vx
= x
+ gdata
->width
;
692 vw
= gdata
->width
- vx
;
693 } else if (x
> gdata
->boxX
) {
694 vw
= gdata
->boxX
+ gdata
->width
- x
;
695 vx
= gdata
->boxX
- vw
;
701 if (y
< gdata
->boxY
) {
702 vy
= y
+ gdata
->height
;
703 vh
= gdata
->height
- vy
;
704 } else if (y
> gdata
->boxY
) {
705 vh
= gdata
->boxY
+ gdata
->height
- y
;
706 vy
= gdata
->boxY
- vh
;
712 if (y
< gdata
->boxY
) {
713 int dy
= vy
- gdata
->boxY
;
715 if (x
< gdata
->boxX
) {
716 for (i
= vh
- 1; i
>= 0; i
--) {
717 memmove(&backP
[(i
+ dy
) * backLineLen
+ 2 * vx
],
718 &backP
[i
* backLineLen
], 2 * vw
);
720 } else /* if (x > gdata->boxX) */ {
721 for (i
= vh
- 1; i
>= 0; i
--) {
722 memmove(&backP
[(i
+ dy
) * backLineLen
],
723 &backP
[i
* backLineLen
+ 2 * vx
], 2 * vw
);
726 } else /*if (y > gdata->boxY) */ {
727 int dy
= gdata
->boxY
- vy
;
729 if (x
< gdata
->boxX
) {
730 for (i
= 0; i
< vh
- 1; i
++) {
731 memmove(&backP
[i
* backLineLen
+ 2 * vx
],
732 &backP
[(i
+ dy
) * backLineLen
], 2 * vw
);
734 } else /*if (x > gdata->boxX) */ {
735 for (i
= 0; i
< vh
- 1; i
++) {
736 memmove(&backP
[i
* backLineLen
],
737 &backP
[(i
+ dy
) * backLineLen
+ 2 * vx
], 2 * vw
);
742 /* 2nd grab the background image from the screen and copy to the
743 * buffer. also maskout the lsb of rgb in each pixel of grabbed data */
745 if (y
< gdata
->boxY
) {
747 vh
= gdata
->boxY
- vy
;
750 hh
= gdata
->height
- vh
;
751 } else if (y
> gdata
->boxY
) {
752 vy
= gdata
->boxY
+ gdata
->height
;
753 vh
= vy
- (y
+ gdata
->height
);
756 hh
= y
- gdata
->boxY
;
764 if (x
< gdata
->boxX
) {
766 hw
= gdata
->boxX
- hx
;
767 } else if (x
> gdata
->boxX
) {
768 hx
= gdata
->boxX
+ gdata
->width
;
769 hw
= hx
- (x
+ gdata
->width
);
777 /* 1st the top/bottom part */
781 /* 2nd the left/right part */
784 mergeGhostWindow(gdata
);
788 #endif /* GHOST_WINDOW_MOVE */