1
0
mirror of https://github.com/gryf/wmaker.git synced 2025-12-20 21:08:08 +01:00
Files
wmaker/src/superfluous.c
David Maciejak 8d731b719e wmaker: superfluous.c possible null pointer dereference
As reported by cppcheck:
[src/superfluous.c:238] -> [src/superfluous.c:199]: (warning) Possible null pointer dereference: aicon - otherwise it is redundant to check it against null.
[src/superfluous.c:239] -> [src/superfluous.c:199]: (warning) Possible null pointer dereference: aicon - otherwise it is redundant to check it against null.
[src/superfluous.c:240] -> [src/superfluous.c:199]: (warning) Possible null pointer dereference: aicon - otherwise it is redundant to check it against null.

The patch is adding a test to check if variable aicon exists.
2014-07-27 09:45:03 -06:00

387 lines
9.1 KiB
C

/*
* Window Maker window manager
*
* Copyright (c) 1997-2003 Alfredo K. Kojima
* Copyright (c) 1998-2003 Dan Pascu
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "wconfig.h"
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <stdlib.h>
#include <unistd.h>
#include <math.h>
#include <time.h>
#include <wraster.h>
#include "WindowMaker.h"
#include "screen.h"
#include "superfluous.h"
#include "framewin.h"
#include "window.h"
#include "actions.h"
#include "xinerama.h"
#include "stacking.h"
#define PIECES ((64/ICON_KABOOM_PIECE_SIZE)*(64/ICON_KABOOM_PIECE_SIZE))
#define KAB_PRECISION 4
#define BOUNCE_HZ 25
#define BOUNCE_DELAY (1000/BOUNCE_HZ)
#define BOUNCE_HEIGHT 24
#define BOUNCE_LENGTH 0.3
#define BOUNCE_DAMP 0.6
#define URGENT_BOUNCE_DELAY 3000
void DoKaboom(WScreen * scr, Window win, int x, int y)
{
#ifdef NORMAL_ICON_KABOOM
int i, j, k;
int sw = scr->scr_width, sh = scr->scr_height;
int px[PIECES];
short py[PIECES];
char pvx[PIECES], pvy[PIECES];
/* in MkLinux/PPC gcc seems to think that char is unsigned? */
signed char ax[PIECES], ay[PIECES];
Pixmap tmp;
XSetClipMask(dpy, scr->copy_gc, None);
tmp = XCreatePixmap(dpy, scr->root_win, wPreferences.icon_size, wPreferences.icon_size, scr->depth);
if (scr->w_visual == DefaultVisual(dpy, scr->screen))
XCopyArea(dpy, win, tmp, scr->copy_gc, 0, 0, wPreferences.icon_size, wPreferences.icon_size, 0, 0);
else {
XImage *image;
image = XGetImage(dpy, win, 0, 0, wPreferences.icon_size,
wPreferences.icon_size, AllPlanes, ZPixmap);
if (!image) {
XUnmapWindow(dpy, win);
return;
}
XPutImage(dpy, tmp, scr->copy_gc, image, 0, 0, 0, 0,
wPreferences.icon_size, wPreferences.icon_size);
XDestroyImage(image);
}
for (i = 0, k = 0; i < wPreferences.icon_size / ICON_KABOOM_PIECE_SIZE && k < PIECES; i++) {
for (j = 0; j < wPreferences.icon_size / ICON_KABOOM_PIECE_SIZE && k < PIECES; j++) {
if (rand() % 2) {
ax[k] = i;
ay[k] = j;
px[k] = (x + i * ICON_KABOOM_PIECE_SIZE) << KAB_PRECISION;
py[k] = y + j * ICON_KABOOM_PIECE_SIZE;
pvx[k] = rand() % (1 << (KAB_PRECISION + 3)) - (1 << (KAB_PRECISION + 3)) / 2;
pvy[k] = -15 - rand() % 7;
k++;
} else {
ax[k] = -1;
}
}
}
XUnmapWindow(dpy, win);
j = k;
while (k > 0) {
XEvent foo;
if (XCheckTypedEvent(dpy, ButtonPress, &foo)) {
XPutBackEvent(dpy, &foo);
XClearWindow(dpy, scr->root_win);
break;
}
for (i = 0; i < j; i++) {
if (ax[i] >= 0) {
int _px = px[i] >> KAB_PRECISION;
XClearArea(dpy, scr->root_win, _px, py[i],
ICON_KABOOM_PIECE_SIZE, ICON_KABOOM_PIECE_SIZE, False);
px[i] += pvx[i];
py[i] += pvy[i];
_px = px[i] >> KAB_PRECISION;
pvy[i]++;
if (_px < -wPreferences.icon_size || _px > sw || py[i] >= sh) {
ax[i] = -1;
k--;
} else {
XCopyArea(dpy, tmp, scr->root_win, scr->copy_gc,
ax[i] * ICON_KABOOM_PIECE_SIZE, ay[i] * ICON_KABOOM_PIECE_SIZE,
ICON_KABOOM_PIECE_SIZE, ICON_KABOOM_PIECE_SIZE, _px, py[i]);
}
}
}
XFlush(dpy);
wusleep(MINIATURIZE_ANIMATION_DELAY_Z * 2);
}
XFreePixmap(dpy, tmp);
#endif /* NORMAL_ICON_KABOOM */
}
Pixmap MakeGhostIcon(WScreen * scr, Drawable drawable)
{
RImage *back;
RColor color;
Pixmap pixmap;
if (!drawable)
return None;
back = RCreateImageFromDrawable(scr->rcontext, drawable, None);
if (!back)
return None;
color.red = 0xff;
color.green = 0xff;
color.blue = 0xff;
color.alpha = 200;
RClearImage(back, &color);
RConvertImage(scr->rcontext, back, &pixmap);
RReleaseImage(back);
return pixmap;
}
void DoWindowBirth(WWindow *wwin)
{
#ifdef WINDOW_BIRTH_ZOOM
int center_x, center_y;
int width = wwin->frame->core->width;
int height = wwin->frame->core->height;
int w = WMIN(width, 20);
int h = WMIN(height, 20);
WScreen *scr = wwin->screen_ptr;
center_x = wwin->frame_x + (width - w) / 2;
center_y = wwin->frame_y + (height - h) / 2;
animateResize(scr, center_x, center_y, 1, 1, wwin->frame_x, wwin->frame_y, width, height);
#else
/* Parameter not used, but tell the compiler that it is ok */
(void) wwin;
#endif
}
typedef struct AppBouncerData {
WApplication *wapp;
int count;
int pow;
int dir;
WMHandlerID *timer;
} AppBouncerData;
static void doAppBounce(void *arg)
{
AppBouncerData *data = (AppBouncerData*)arg;
WAppIcon *aicon = data->wapp->app_icon;
if (!aicon)
return;
reinit:
if (data->wapp->refcount > 1) {
if (wPreferences.raise_appicons_when_bouncing)
XRaiseWindow(dpy, aicon->icon->core->window);
const double ticks = BOUNCE_HZ * BOUNCE_LENGTH;
const double s = sqrt(BOUNCE_HEIGHT)/(ticks/2);
double h = BOUNCE_HEIGHT*pow(BOUNCE_DAMP, data->pow);
double sqrt_h = sqrt(h);
if (h > 3) {
double offset, x = s * data->count - sqrt_h;
if (x > sqrt_h) {
++data->pow;
data->count = 0;
goto reinit;
} else ++data->count;
offset = h - x*x;
switch (data->dir) {
case 0: /* left, bounce to right */
XMoveWindow(dpy, aicon->icon->core->window,
aicon->x_pos + (int)offset, aicon->y_pos);
break;
case 1: /* right, bounce to left */
XMoveWindow(dpy, aicon->icon->core->window,
aicon->x_pos - (int)offset, aicon->y_pos);
break;
case 2: /* top, bounce down */
XMoveWindow(dpy, aicon->icon->core->window,
aicon->x_pos, aicon->y_pos + (int)offset);
break;
case 3: /* bottom, bounce up */
XMoveWindow(dpy, aicon->icon->core->window,
aicon->x_pos, aicon->y_pos - (int)offset);
break;
}
return;
}
}
XMoveWindow(dpy, aicon->icon->core->window,
aicon->x_pos, aicon->y_pos);
CommitStackingForWindow(aicon->icon->core);
data->wapp->flags.bouncing = 0;
WMDeleteTimerHandler(data->timer);
wApplicationDestroy(data->wapp);
free(data);
}
static int bounceDirection(WAppIcon *aicon)
{
enum { left_e = 1, right_e = 2, top_e = 4, bottom_e = 8 };
WScreen *scr = aicon->icon->core->screen_ptr;
WMRect rr, sr;
int l, r, t, b, h, v;
int dir = 0;
rr.pos.x = aicon->x_pos;
rr.pos.y = aicon->y_pos;
rr.size.width = rr.size.height = 64;
sr = wGetRectForHead(scr, wGetHeadForRect(scr, rr));
l = rr.pos.x - sr.pos.x;
r = sr.pos.x + sr.size.width - rr.pos.x - rr.size.width;
t = rr.pos.y - sr.pos.y;
b = sr.pos.y + sr.size.height - rr.pos.y - rr.size.height;
if (l < r) {
dir |= left_e;
h = l;
} else {
dir |= right_e;
h = r;
}
if (t < b) {
dir |= top_e;
v = t;
} else {
dir |= bottom_e;
v = b;
}
if (aicon->dock && abs(aicon->xindex) != abs(aicon->yindex)) {
if (abs(aicon->xindex) < abs(aicon->yindex)) dir &= ~(top_e | bottom_e);
else dir &= ~(left_e | right_e);
} else {
if (h < v) dir &= ~(top_e | bottom_e);
else dir &= ~(left_e | right_e);
}
switch (dir) {
case left_e:
dir = 0;
break;
case right_e:
dir = 1;
break;
case top_e:
dir = 2;
break;
case bottom_e:
dir = 3;
break;
default:
wwarning(_("Impossible direction: %d"), dir);
dir = 3;
break;
}
return dir;
}
void wAppBounce(WApplication *wapp)
{
if (!wPreferences.no_animations && wapp->app_icon && !wapp->flags.bouncing
&& !wPreferences.do_not_make_appicons_bounce) {
++wapp->refcount;
wapp->flags.bouncing = 1;
AppBouncerData *data = (AppBouncerData *)malloc(sizeof(AppBouncerData));
data->wapp = wapp;
data->count = data->pow = 0;
data->dir = bounceDirection(wapp->app_icon);
data->timer = WMAddPersistentTimerHandler(BOUNCE_DELAY, doAppBounce, data);
}
}
static int appIsUrgent(WApplication *wapp)
{
WScreen *scr;
WWindow *wlist;
if (!wapp->main_window_desc) {
wwarning("group leader not found for window group");
return 0;
}
scr = wapp->main_window_desc->screen_ptr;
wlist = scr->focused_window;
if (!wlist)
return 0;
while (wlist) {
if (wlist->main_window == wapp->main_window) {
if (wlist->flags.urgent)
return 1;
}
wlist = wlist->prev;
}
return 0;
}
static void doAppUrgentBounce(void *arg)
{
WApplication *wapp = (WApplication *)arg;
if (appIsUrgent(wapp)) {
if(wPreferences.bounce_appicons_when_urgent) wAppBounce(wapp);
} else {
WMDeleteTimerHandler(wapp->urgent_bounce_timer);
wapp->urgent_bounce_timer = NULL;
}
}
void wAppBounceWhileUrgent(WApplication *wapp)
{
if (!wapp) return;
if (appIsUrgent(wapp)) {
if (!wapp->urgent_bounce_timer) {
wapp->urgent_bounce_timer = WMAddPersistentTimerHandler(URGENT_BOUNCE_DELAY, doAppUrgentBounce, wapp);
doAppUrgentBounce(wapp);
}
} else {
if (wapp->urgent_bounce_timer) {
WMDeleteTimerHandler(wapp->urgent_bounce_timer);
wapp->urgent_bounce_timer = NULL;
}
}
}