Exemple #1
0
static void blinkCursor(void *data)
{
	TextField *tPtr = (TextField *) data;

	if (tPtr->flags.cursorOn) {
		tPtr->timerID = WMAddTimerHandler(CURSOR_BLINK_OFF_DELAY, blinkCursor, data);
	} else {
		tPtr->timerID = WMAddTimerHandler(CURSOR_BLINK_ON_DELAY, blinkCursor, data);
	}
	paintCursor(tPtr);
	tPtr->flags.cursorOn = !tPtr->flags.cursorOn;
}
Exemple #2
0
void W_DragSourceStartTimer(WMDraggingInfo * info)
{
	W_DragSourceStopTimer();

	dndSourceTimer = WMAddTimerHandler(XDND_DESTINATION_RESPONSE_MAX_DELAY,
					   dragSourceResponseTimeOut, XDND_SOURCE_VIEW(info));
}
Exemple #3
0
void W_BalloonHandleEnterView(WMView * view)
{
	Balloon *bPtr = view->screen->balloon;
	char *text;

	if (!bPtr->flags.enabled)
		return;

	text = WMHashGet(bPtr->table, view);
	if (!text) {
		if (bPtr->view->flags.realized)
			W_UnmapView(bPtr->view);

		return;
	}

	if (bPtr->timer)
		WMDeleteTimerHandler(bPtr->timer);
	bPtr->timer = NULL;

	if (bPtr->noDelayTimer)
		WMDeleteTimerHandler(bPtr->noDelayTimer);
	bPtr->noDelayTimer = NULL;

	bPtr->forWindow = view->window;

	if (bPtr->flags.noDelay) {
		bPtr->timer = NULL;

		showBalloon(view);
	} else {
		bPtr->timer = WMAddTimerHandler(bPtr->delay, showBalloon, view);
	}
}
Exemple #4
0
WMHandlerID
WMAddPersistentTimerHandler(int milliseconds, WMCallback *callback, void *cdata)
{
    TimerHandler *handler = WMAddTimerHandler(milliseconds, callback, cdata);

    if (handler != NULL)
        handler->nextDelay = milliseconds;

    return handler;
}
Exemple #5
0
static void autoScroll(void *clientData)
{
	Scroller *sPtr = (Scroller *) clientData;

	if (sPtr->action) {
		(*sPtr->action) (sPtr, sPtr->clientData);
		WMPostNotificationName(WMScrollerDidScrollNotification, sPtr, NULL);
	}
	sPtr->timerID = WMAddTimerHandler(AUTOSCROLL_DELAY, autoScroll, clientData);
}
Exemple #6
0
static void handleEvents(XEvent * event, void *data)
{
	TextField *tPtr = (TextField *) data;

	CHECK_CLASS(data, WC_TextField);

	switch (event->type) {
	case FocusIn:
		W_FocusIC(tPtr->view);
		if (W_FocusedViewOfToplevel(W_TopLevelOfView(tPtr->view)) != tPtr->view)
			return;
		tPtr->flags.focused = 1;

		if (!tPtr->timerID) {
			tPtr->timerID = WMAddTimerHandler(CURSOR_BLINK_ON_DELAY, blinkCursor, tPtr);
		}

		paintTextField(tPtr);

		NOTIFY(tPtr, didBeginEditing, WMTextDidBeginEditingNotification, NULL);

		tPtr->flags.notIllegalMovement = 0;
		break;

	case FocusOut:
		W_UnFocusIC(tPtr->view);
		tPtr->flags.focused = 0;

		if (tPtr->timerID)
			WMDeleteTimerHandler(tPtr->timerID);
		tPtr->timerID = NULL;

		paintTextField(tPtr);
		if (!tPtr->flags.notIllegalMovement) {
			NOTIFY(tPtr, didEndEditing, WMTextDidEndEditingNotification,
			       (void *)WMIllegalTextMovement);
		}
		break;

	case Expose:
		if (event->xexpose.count != 0)
			break;
		paintTextField(tPtr);
		break;

	case DestroyNotify:
		destroyTextField(tPtr);
		break;
	}
}
Exemple #7
0
static void frameBalloon(WObjDescriptor *object)
{
	WFrameWindow *fwin = (WFrameWindow *) object->parent;
	WScreen *scr = fwin->core->screen_ptr;

	if (fwin->titlebar != object->self || !fwin->flags.is_client_window_frame) {
		wBalloonHide(scr);
		return;
	}
	if (fwin->title && fwin->flags.incomplete_title) {
		scr->balloon->h = (fwin->titlebar ? fwin->titlebar->height : 0);
		scr->balloon->text = wstrdup(fwin->title);
		scr->balloon->objectWindow = fwin->core->window;
		scr->balloon->timer = WMAddTimerHandler(BALLOON_DELAY, (WMCallback *) showBalloon, scr);
	}
}
Exemple #8
0
void W_BalloonHandleLeaveView(WMView * view)
{
	Balloon *bPtr = view->screen->balloon;

	if (bPtr->forWindow == view->window) {
		if (bPtr->view->flags.mapped) {
			W_UnmapView(bPtr->view);
			bPtr->noDelayTimer = WMAddTimerHandler(NO_DELAY_DELAY, clearNoDelay, bPtr);
		}
		if (bPtr->timer)
			WMDeleteTimerHandler(bPtr->timer);

		bPtr->timer = NULL;

		bPtr->forWindow = None;
	}
}
Exemple #9
0
static void miniwindowBalloon(WObjDescriptor *object)
{
	WIcon *icon = (WIcon *) object->parent;
	WScreen *scr = icon->core->screen_ptr;

	if (!icon->icon_name) {
		wBalloonHide(scr);
		return;
	}
	scr->balloon->h = icon->core->height;
	scr->balloon->text = wstrdup(icon->icon_name);
	scr->balloon->apercu = icon->apercu;
	scr->balloon->objectWindow = icon->core->window;

	if ((scr->balloon->prevType == object->parent_type || scr->balloon->prevType == WCLASS_APPICON)
	    && scr->balloon->ignoreTimer) {
		XUnmapWindow(dpy, scr->balloon->window);
		showBalloon(scr);
	} else {
		scr->balloon->timer = WMAddTimerHandler(BALLOON_DELAY, (WMCallback *) showBalloon, scr);
	}
}
Exemple #10
0
static void hideWorkspaceName(void *data)
{
	WScreen *scr = (WScreen *) data;

	if (!scr->workspace_name_data || scr->workspace_name_data->count == 0
	    || time(NULL) > scr->workspace_name_data->timeout) {
		XUnmapWindow(dpy, scr->workspace_name);

		if (scr->workspace_name_data) {
			RReleaseImage(scr->workspace_name_data->back);
			RReleaseImage(scr->workspace_name_data->text);
			wfree(scr->workspace_name_data);

			scr->workspace_name_data = NULL;
		}
		scr->workspace_name_timer = NULL;
	} else {
		RImage *img = RCloneImage(scr->workspace_name_data->back);
		Pixmap pix;

		scr->workspace_name_timer = WMAddTimerHandler(WORKSPACE_NAME_FADE_DELAY, hideWorkspaceName, scr);

		RCombineImagesWithOpaqueness(img, scr->workspace_name_data->text,
					     scr->workspace_name_data->count * 255 / 10);

		RConvertImage(scr->rcontext, img, &pix);

		RReleaseImage(img);

		XSetWindowBackgroundPixmap(dpy, scr->workspace_name, pix);
		XClearWindow(dpy, scr->workspace_name);
		XFreePixmap(dpy, pix);
		XFlush(dpy);

		scr->workspace_name_data->count--;
	}
}
Exemple #11
0
static char *getTextSelection(WScreen * screen, Atom selection)
{
	int buffer = -1;

	switch (selection) {
	case XA_CUT_BUFFER0:
		buffer = 0;
		break;
	case XA_CUT_BUFFER1:
		buffer = 1;
		break;
	case XA_CUT_BUFFER2:
		buffer = 2;
		break;
	case XA_CUT_BUFFER3:
		buffer = 3;
		break;
	case XA_CUT_BUFFER4:
		buffer = 4;
		break;
	case XA_CUT_BUFFER5:
		buffer = 5;
		break;
	case XA_CUT_BUFFER6:
		buffer = 6;
		break;
	case XA_CUT_BUFFER7:
		buffer = 7;
		break;
	}
	if (buffer >= 0) {
		char *data;
		int size;

		data = XFetchBuffer(dpy, &size, buffer);

		return data;
	} else {
		char *data;
		int bits;
		Atom rtype;
		unsigned long len, bytes;
		WMHandlerID timer;
		int timeout = 0;
		XEvent ev;
		static Atom clipboard = 0;

		if (!clipboard)
			clipboard = XInternAtom(dpy, "CLIPBOARD", False);

		XDeleteProperty(dpy, screen->info_window, clipboard);

		XConvertSelection(dpy, selection, XA_STRING, clipboard, screen->info_window, CurrentTime);

		timer = WMAddTimerHandler(1000, timeoutHandler, &timeout);

		while (!XCheckTypedWindowEvent(dpy, screen->info_window, SelectionNotify, &ev) && !timeout) ;

		if (!timeout) {
			WMDeleteTimerHandler(timer);
		} else {
			wwarning("selection retrieval timed out");
			return NULL;
		}

		/* nobody owns the selection or the current owner has
		 * nothing to do with what we need */
		if (ev.xselection.property == None) {
			return NULL;
		}

		if (XGetWindowProperty(dpy, screen->info_window,
				       clipboard, 0, 1024,
				       False, XA_STRING, &rtype, &bits, &len,
				       &bytes, (unsigned char **)&data) != Success) {
			return NULL;
		}
		if (rtype != XA_STRING || bits != 8) {
			wwarning("invalid data in text selection");
			if (data)
				XFree(data);
			return NULL;
		}
		return data;
	}
}
Exemple #12
0
static void showWorkspaceName(WScreen * scr, int workspace)
{
	WorkspaceNameData *data;
	RXImage *ximg;
	Pixmap text, mask;
	int w, h;
	int px, py;
	char *name = w_global.workspace.array[workspace]->name;
	int len = strlen(name);
	int x, y;
#ifdef USE_XINERAMA
	int head;
	WMRect rect;
	int xx, yy;
#endif

	if (wPreferences.workspace_name_display_position == WD_NONE || w_global.workspace.count < 2)
		return;

	if (scr->workspace_name_timer) {
		WMDeleteTimerHandler(scr->workspace_name_timer);
		XUnmapWindow(dpy, scr->workspace_name);
		XFlush(dpy);
	}
	scr->workspace_name_timer = WMAddTimerHandler(WORKSPACE_NAME_DELAY, hideWorkspaceName, scr);

	if (scr->workspace_name_data) {
		RReleaseImage(scr->workspace_name_data->back);
		RReleaseImage(scr->workspace_name_data->text);
		wfree(scr->workspace_name_data);
	}

	data = wmalloc(sizeof(WorkspaceNameData));
	data->back = NULL;

	w = WMWidthOfString(w_global.workspace.font_for_name, name, len);
	h = WMFontHeight(w_global.workspace.font_for_name);

#ifdef USE_XINERAMA
	head = wGetHeadForPointerLocation(scr);
	rect = wGetRectForHead(scr, head);
	if (scr->xine_info.count) {
		xx = rect.pos.x + (scr->xine_info.screens[head].size.width - (w + 4)) / 2;
		yy = rect.pos.y + (scr->xine_info.screens[head].size.height - (h + 4)) / 2;
	}
	else {
		xx = (scr->scr_width - (w + 4)) / 2;
		yy = (scr->scr_height - (h + 4)) / 2;
	}
#endif

	switch (wPreferences.workspace_name_display_position) {
	case WD_TOP:
#ifdef USE_XINERAMA
		px = xx;
#else
		px = (scr->scr_width - (w + 4)) / 2;
#endif
		py = WORKSPACE_NAME_DISPLAY_PADDING;
		break;
	case WD_BOTTOM:
#ifdef USE_XINERAMA
		px = xx;
#else
		px = (scr->scr_width - (w + 4)) / 2;
#endif
		py = scr->scr_height - (h + 4 + WORKSPACE_NAME_DISPLAY_PADDING);
		break;
	case WD_TOPLEFT:
		px = WORKSPACE_NAME_DISPLAY_PADDING;
		py = WORKSPACE_NAME_DISPLAY_PADDING;
		break;
	case WD_TOPRIGHT:
		px = scr->scr_width - (w + 4 + WORKSPACE_NAME_DISPLAY_PADDING);
		py = WORKSPACE_NAME_DISPLAY_PADDING;
		break;
	case WD_BOTTOMLEFT:
		px = WORKSPACE_NAME_DISPLAY_PADDING;
		py = scr->scr_height - (h + 4 + WORKSPACE_NAME_DISPLAY_PADDING);
		break;
	case WD_BOTTOMRIGHT:
		px = scr->scr_width - (w + 4 + WORKSPACE_NAME_DISPLAY_PADDING);
		py = scr->scr_height - (h + 4 + WORKSPACE_NAME_DISPLAY_PADDING);
		break;
	case WD_CENTER:
	default:
#ifdef USE_XINERAMA
		px = xx;
		py = yy;
#else
		px = (scr->scr_width - (w + 4)) / 2;
		py = (scr->scr_height - (h + 4)) / 2;
#endif
		break;
	}
	XResizeWindow(dpy, scr->workspace_name, w + 4, h + 4);
	XMoveWindow(dpy, scr->workspace_name, px, py);

	text = XCreatePixmap(dpy, scr->w_win, w + 4, h + 4, scr->w_depth);
	mask = XCreatePixmap(dpy, scr->w_win, w + 4, h + 4, 1);

	/*XSetForeground(dpy, scr->mono_gc, 0);
	   XFillRectangle(dpy, mask, scr->mono_gc, 0, 0, w+4, h+4); */

	XFillRectangle(dpy, text, WMColorGC(scr->black), 0, 0, w + 4, h + 4);

	for (x = 0; x <= 4; x++)
		for (y = 0; y <= 4; y++)
			WMDrawString(scr->wmscreen, text, scr->white, w_global.workspace.font_for_name, x, y, name, len);

	XSetForeground(dpy, scr->mono_gc, 1);
	XSetBackground(dpy, scr->mono_gc, 0);

	XCopyPlane(dpy, text, mask, scr->mono_gc, 0, 0, w + 4, h + 4, 0, 0, 1 << (scr->w_depth - 1));

	/*XSetForeground(dpy, scr->mono_gc, 1); */
	XSetBackground(dpy, scr->mono_gc, 1);

	XFillRectangle(dpy, text, WMColorGC(scr->black), 0, 0, w + 4, h + 4);

	WMDrawString(scr->wmscreen, text, scr->white, w_global.workspace.font_for_name, 2, 2, name, len);

#ifdef USE_XSHAPE
	if (w_global.xext.shape.supported)
		XShapeCombineMask(dpy, scr->workspace_name, ShapeBounding, 0, 0, mask, ShapeSet);
#endif
	XSetWindowBackgroundPixmap(dpy, scr->workspace_name, text);
	XClearWindow(dpy, scr->workspace_name);

	data->text = RCreateImageFromDrawable(scr->rcontext, text, None);

	XFreePixmap(dpy, text);
	XFreePixmap(dpy, mask);

	if (!data->text) {
		XMapRaised(dpy, scr->workspace_name);
		XFlush(dpy);

		goto erro;
	}

	ximg = RGetXImage(scr->rcontext, scr->root_win, px, py, data->text->width, data->text->height);

	if (!ximg || !ximg->image) {
		goto erro;
	}

	XMapRaised(dpy, scr->workspace_name);
	XFlush(dpy);

	data->back = RCreateImageFromXImage(scr->rcontext, ximg->image, NULL);
	RDestroyXImage(scr->rcontext, ximg);

	if (!data->back) {
		goto erro;
	}

	data->count = 10;

	/* set a timeout for the effect */
	data->timeout = time(NULL) + 2 + (WORKSPACE_NAME_DELAY + WORKSPACE_NAME_FADE_DELAY * data->count) / 1000;

	scr->workspace_name_data = data;

	return;

 erro:
	if (scr->workspace_name_timer)
		WMDeleteTimerHandler(scr->workspace_name_timer);

	if (data->text)
		RReleaseImage(data->text);
	if (data->back)
		RReleaseImage(data->back);
	wfree(data);

	scr->workspace_name_data = NULL;

	scr->workspace_name_timer = WMAddTimerHandler(WORKSPACE_NAME_DELAY +
						      10 * WORKSPACE_NAME_FADE_DELAY, hideWorkspaceName, scr);
}
Exemple #13
0
static void handleActionEvents(XEvent * event, void *data)
{
	Scroller *sPtr = (Scroller *) data;
	int wheelDecrement, wheelIncrement;
	int id, dd;

	/* check if we're really dealing with a scroller, as something
	 * might have gone wrong in the event dispatching stuff */
	CHECK_CLASS(sPtr, WC_Scroller);

	id = sPtr->flags.incrDown;
	dd = sPtr->flags.decrDown;

	switch (event->type) {
	case EnterNotify:
		break;

	case LeaveNotify:
		if (sPtr->timerID) {
			WMDeleteTimerHandler(sPtr->timerID);
			sPtr->timerID = NULL;
		}
		sPtr->flags.incrDown = 0;
		sPtr->flags.decrDown = 0;
		break;

	case ButtonPress:
		/* FIXME: change Mod1Mask with something else */
		if (sPtr->flags.documentFullyVisible)
			break;

		if (sPtr->flags.horizontal) {
			wheelDecrement = WINGsConfiguration.mouseWheelDown;
			wheelIncrement = WINGsConfiguration.mouseWheelUp;
		} else {
			wheelDecrement = WINGsConfiguration.mouseWheelUp;
			wheelIncrement = WINGsConfiguration.mouseWheelDown;
		}

		if (event->xbutton.button == wheelDecrement) {
			if (event->xbutton.state & ControlMask) {
				sPtr->flags.hitPart = WSDecrementPage;
			} else if (event->xbutton.state & ShiftMask) {
				sPtr->flags.hitPart = WSDecrementLine;
			} else {
				sPtr->flags.hitPart = WSDecrementWheel;
			}
			if (sPtr->action) {
				(*sPtr->action) (sPtr, sPtr->clientData);
				WMPostNotificationName(WMScrollerDidScrollNotification, sPtr, NULL);
			}
		} else if (event->xbutton.button == wheelIncrement) {
			if (event->xbutton.state & ControlMask) {
				sPtr->flags.hitPart = WSIncrementPage;
			} else if (event->xbutton.state & ShiftMask) {
				sPtr->flags.hitPart = WSIncrementLine;
			} else {
				sPtr->flags.hitPart = WSIncrementWheel;
			}
			if (sPtr->action) {
				(*sPtr->action) (sPtr, sPtr->clientData);
				WMPostNotificationName(WMScrollerDidScrollNotification, sPtr, NULL);
			}
		} else {
			handlePush(sPtr, event->xbutton.x, event->xbutton.y, (event->xbutton.state & Mod1Mask)
				   || event->xbutton.button == Button2);
			/* continue scrolling if pushed on the buttons */
			if (sPtr->flags.hitPart == WSIncrementLine || sPtr->flags.hitPart == WSDecrementLine) {
				sPtr->timerID = WMAddTimerHandler(AUTOSCROLL_INITIAL_DELAY, autoScroll, sPtr);
			}
		}
		break;

	case ButtonRelease:
		if (sPtr->flags.draggingKnob) {
			if (sPtr->action) {
				(*sPtr->action) (sPtr, sPtr->clientData);
				WMPostNotificationName(WMScrollerDidScrollNotification, sPtr, NULL);
			}
		}
		if (sPtr->timerID) {
			WMDeleteTimerHandler(sPtr->timerID);
			sPtr->timerID = NULL;
		}
		sPtr->flags.incrDown = 0;
		sPtr->flags.decrDown = 0;
		sPtr->flags.draggingKnob = 0;
		break;

	case MotionNotify:
		handleMotion(sPtr, event->xbutton.x, event->xbutton.y);
		if (sPtr->timerID && sPtr->flags.hitPart != WSIncrementLine
		    && sPtr->flags.hitPart != WSDecrementLine) {
			WMDeleteTimerHandler(sPtr->timerID);
			sPtr->timerID = NULL;
		}
		break;
	}
	if (id != sPtr->flags.incrDown || dd != sPtr->flags.decrDown)
		paintScroller(sPtr);
}
Exemple #14
0
static void appiconBalloon(WObjDescriptor *object)
{
	WAppIcon *aicon = (WAppIcon *) object->parent;
	WScreen *scr = aicon->icon->core->screen_ptr;
	char *tmp;

	/* Show balloon if it is the Clip and the workspace name is > 5 chars */
	if (object->parent == w_global.clip.icon) {
		if (strlen(w_global.workspace.array[w_global.workspace.current]->name) > 5) {
			scr->balloon->text = wstrdup(w_global.workspace.array[w_global.workspace.current]->name);
		} else {
			wBalloonHide(scr);
			return;
		}
	} else if (aicon->command && aicon->wm_class) {
		int len;
		WApplication *app;
		unsigned int app_win_cnt = 0;

		if (object->parent_type == WCLASS_DOCK_ICON) {
			if (aicon->main_window) {
				app = wApplicationOf(aicon->main_window);
				if (app && app->main_window_desc && app->main_window_desc->fake_group)
					app_win_cnt = app->main_window_desc->fake_group->retainCount - 1;
			}
		}

		/* Check to see if it is a GNUstep app */
		if (strcmp(aicon->wm_class, "GNUstep") == 0)
			len = strlen(aicon->command) + strlen(aicon->wm_instance) + 8;
		else
			len = strlen(aicon->command) + strlen(aicon->wm_class) + 8;

		if (app_win_cnt > 0)
			len += 1 + snprintf(NULL, 0, "%u", app_win_cnt);

		tmp = wmalloc(len);
		/* Check to see if it is a GNUstep App */
		if (strcmp(aicon->wm_class, "GNUstep") == 0)
			if (app_win_cnt > 0)
				snprintf(tmp, len, "%u %s\n(%s)", app_win_cnt, aicon->wm_instance, aicon->command);
			else
				snprintf(tmp, len, "%s\n(%s)", aicon->wm_instance, aicon->command);
		else
			if (app_win_cnt > 0)
				snprintf(tmp, len, "%u %s\n(%s)", app_win_cnt, aicon->wm_class, aicon->command);
			else
				snprintf(tmp, len, "%s\n(%s)", aicon->wm_class, aicon->command);
		scr->balloon->text = tmp;
	} else if (aicon->command) {
		scr->balloon->text = wstrdup(aicon->command);
	} else if (aicon->wm_class) {
		/* Check to see if it is a GNUstep App */
		if (strcmp(aicon->wm_class, "GNUstep") == 0)
			scr->balloon->text = wstrdup(aicon->wm_instance);
		else
			scr->balloon->text = wstrdup(aicon->wm_class);
	} else {
		wBalloonHide(scr);
		return;
	}
	scr->balloon->h = aicon->icon->core->height - 2;

	scr->balloon->objectWindow = aicon->icon->core->window;
	if ((scr->balloon->prevType == object->parent_type || scr->balloon->prevType == WCLASS_MINIWINDOW)
	    && scr->balloon->ignoreTimer) {
		XUnmapWindow(dpy, scr->balloon->window);
		showBalloon(scr);
	} else {
		scr->balloon->timer = WMAddTimerHandler(BALLOON_DELAY, (WMCallback *) showBalloon, scr);
	}
}
Exemple #15
0
/*
 *----------------------------------------------------------
 * StartUp--
 * 	starts the window manager and setup global data.
 * Called from main() at startup.
 *
 * Side effects:
 * global data declared in main.c is initialized
 *----------------------------------------------------------
 */
void StartUp(Bool defaultScreenOnly)
{
	struct sigaction sig_action;
	int i, j, max;
	char **formats;
	Atom atom[wlengthof(atomNames)];

	/*
	 * Ignore CapsLock in modifiers
	 */
	w_global.shortcut.modifiers_mask = 0xff & ~LockMask;

	getOffendingModifiers();
	/*
	 * Ignore NumLock and ScrollLock too
	 */
	w_global.shortcut.modifiers_mask &= ~(_NumLockMask | _ScrollLockMask);

	memset(&wKeyBindings, 0, sizeof(wKeyBindings));

	w_global.context.client_win = XUniqueContext();
	w_global.context.app_win = XUniqueContext();
	w_global.context.stack = XUniqueContext();

	/*    _XA_VERSION = XInternAtom(dpy, "VERSION", False); */

#ifdef HAVE_XINTERNATOMS
	XInternAtoms(dpy, atomNames, wlengthof(atomNames), False, atom);
#else

	{
		int i;
		for (i = 0; i < wlengthof(atomNames); i++)
			atom[i] = XInternAtom(dpy, atomNames[i], False);
	}
#endif

	w_global.atom.wm.state = atom[0];
	w_global.atom.wm.change_state = atom[1];
	w_global.atom.wm.protocols = atom[2];
	w_global.atom.wm.take_focus = atom[3];
	w_global.atom.wm.delete_window = atom[4];
	w_global.atom.wm.save_yourself = atom[5];
	w_global.atom.wm.client_leader = atom[6];
	w_global.atom.wm.colormap_windows = atom[7];
	w_global.atom.wm.colormap_notify = atom[8];

	w_global.atom.wmaker.menu = atom[9];
	w_global.atom.wmaker.state = atom[10];
	w_global.atom.wmaker.wm_protocols = atom[11];
	w_global.atom.wmaker.wm_function = atom[12];
	w_global.atom.wmaker.noticeboard = atom[13];
	w_global.atom.wmaker.command = atom[14];
	w_global.atom.wmaker.icon_size = atom[15];
	w_global.atom.wmaker.icon_tile = atom[16];

	w_global.atom.gnustep.wm_attr = atom[17];
	w_global.atom.gnustep.wm_miniaturize_window = atom[18];
	w_global.atom.gnustep.titlebar_state = atom[19];

	w_global.atom.wm.ignore_focus_events = atom[20];

#ifdef XDND
	wXDNDInitializeAtoms();
#endif

	/* cursors */
	wPreferences.cursor[WCUR_NORMAL] = None;	/* inherit from root */
	wPreferences.cursor[WCUR_ROOT] = XCreateFontCursor(dpy, XC_left_ptr);
	wPreferences.cursor[WCUR_ARROW] = XCreateFontCursor(dpy, XC_top_left_arrow);
	wPreferences.cursor[WCUR_MOVE] = XCreateFontCursor(dpy, XC_fleur);
	wPreferences.cursor[WCUR_RESIZE] = XCreateFontCursor(dpy, XC_sizing);
	wPreferences.cursor[WCUR_TOPLEFTRESIZE] = XCreateFontCursor(dpy, XC_top_left_corner);
	wPreferences.cursor[WCUR_TOPRIGHTRESIZE] = XCreateFontCursor(dpy, XC_top_right_corner);
	wPreferences.cursor[WCUR_BOTTOMLEFTRESIZE] = XCreateFontCursor(dpy, XC_bottom_left_corner);
	wPreferences.cursor[WCUR_BOTTOMRIGHTRESIZE] = XCreateFontCursor(dpy, XC_bottom_right_corner);
	wPreferences.cursor[WCUR_VERTICALRESIZE] = XCreateFontCursor(dpy, XC_sb_v_double_arrow);
	wPreferences.cursor[WCUR_HORIZONRESIZE] = XCreateFontCursor(dpy, XC_sb_h_double_arrow);
	wPreferences.cursor[WCUR_WAIT] = XCreateFontCursor(dpy, XC_watch);
	wPreferences.cursor[WCUR_QUESTION] = XCreateFontCursor(dpy, XC_question_arrow);
	wPreferences.cursor[WCUR_TEXT] = XCreateFontCursor(dpy, XC_xterm);	/* odd name??? */
	wPreferences.cursor[WCUR_SELECT] = XCreateFontCursor(dpy, XC_cross);

	Pixmap cur = XCreatePixmap(dpy, DefaultRootWindow(dpy), 16, 16, 1);
	GC gc = XCreateGC(dpy, cur, 0, NULL);
	XColor black;
	memset(&black, 0, sizeof(XColor));
	XSetForeground(dpy, gc, 0);
	XFillRectangle(dpy, cur, gc, 0, 0, 16, 16);
	XFreeGC(dpy, gc);
	wPreferences.cursor[WCUR_EMPTY] = XCreatePixmapCursor(dpy, cur, cur, &black, &black, 0, 0);
	XFreePixmap(dpy, cur);

	/* emergency exit... */
	sig_action.sa_handler = handleSig;
	sigemptyset(&sig_action.sa_mask);

	sig_action.sa_flags = SA_RESTART;
	sigaction(SIGQUIT, &sig_action, NULL);
	/* instead of catching these, we let the default handler abort the
	 * program. The new monitor process will take appropriate action
	 * when it detects the crash.
	 sigaction(SIGSEGV, &sig_action, NULL);
	 sigaction(SIGBUS, &sig_action, NULL);
	 sigaction(SIGFPE, &sig_action, NULL);
	 sigaction(SIGABRT, &sig_action, NULL);
	 */

	sig_action.sa_handler = handleExitSig;

	/* Here we set SA_RESTART for safety, because SIGUSR1 may not be handled
	 * immediately. -Dan */
	sig_action.sa_flags = SA_RESTART;
	sigaction(SIGTERM, &sig_action, NULL);
	sigaction(SIGINT, &sig_action, NULL);
	sigaction(SIGHUP, &sig_action, NULL);
	sigaction(SIGUSR1, &sig_action, NULL);
	sigaction(SIGUSR2, &sig_action, NULL);

	/* ignore dead pipe */
	/* Because POSIX mandates that only signal with handlers are reset
	 * accross an exec*(), we do not want to propagate ignoring SIGPIPEs
	 * to children. Hence the dummy handler.
	 * Philippe Troin <*****@*****.**>
	 */
	sig_action.sa_handler = &dummyHandler;
	sig_action.sa_flags = SA_RESTART;
	sigaction(SIGPIPE, &sig_action, NULL);

	/* handle dead children */
	sig_action.sa_handler = buryChild;
	sig_action.sa_flags = SA_NOCLDSTOP | SA_RESTART;
	sigaction(SIGCHLD, &sig_action, NULL);

	/* Now we unblock all signals, that may have been blocked by the parent
	 * who exec()-ed us. This can happen for example if Window Maker crashes
	 * and restarts itself or another window manager from the signal handler.
	 * In this case, the new proccess inherits the blocked signal mask and
	 * will no longer react to that signal, until unblocked.
	 * This is because the signal handler of the proccess who crashed (parent)
	 * didn't return, and the signal remained blocked. -Dan
	 */
	sigfillset(&sig_action.sa_mask);
	sigprocmask(SIG_UNBLOCK, &sig_action.sa_mask, NULL);

	/* handle X shutdowns a such */
	XSetIOErrorHandler(handleXIO);

	/* set hook for out event dispatcher in WINGs event dispatcher */
	WMHookEventHandler(DispatchEvent);

	/* initialize defaults stuff */
	w_global.domain.wmaker = wDefaultsInitDomain("WindowMaker", True);
	if (!w_global.domain.wmaker->dictionary)
		wwarning(_("could not read domain \"%s\" from defaults database"), "WindowMaker");

	/* read defaults that don't change until a restart and are
	 * screen independent */
	wReadStaticDefaults(w_global.domain.wmaker ? w_global.domain.wmaker->dictionary : NULL);

	/* check sanity of some values */
	if (wPreferences.icon_size < 16) {
		wwarning(_("icon size is configured to %i, but it's too small. Using 16 instead"),
			 wPreferences.icon_size);
		wPreferences.icon_size = 16;
	}

	/* init other domains */
	w_global.domain.root_menu = wDefaultsInitDomain("WMRootMenu", False);
	if (!w_global.domain.root_menu->dictionary)
		wwarning(_("could not read domain \"%s\" from defaults database"), "WMRootMenu");

	wDefaultsMergeGlobalMenus(w_global.domain.root_menu);

	w_global.domain.window_attr = wDefaultsInitDomain("WMWindowAttributes", True);
	if (!w_global.domain.window_attr->dictionary)
		wwarning(_("could not read domain \"%s\" from defaults database"), "WMWindowAttributes");

	XSetErrorHandler((XErrorHandler) catchXError);

#ifdef USE_XSHAPE
	/* ignore j */
	w_global.xext.shape.supported = XShapeQueryExtension(dpy, &w_global.xext.shape.event_base, &j);
#endif

#ifdef USE_XRANDR
	w_global.xext.randr.supported = XRRQueryExtension(dpy, &w_global.xext.randr.event_base, &j);
#endif

#ifdef KEEP_XKB_LOCK_STATUS
	w_global.xext.xkb.supported = XkbQueryExtension(dpy, NULL, &w_global.xext.xkb.event_base, NULL, NULL, NULL);
	if (wPreferences.modelock && !w_global.xext.xkb.supported) {
		wwarning(_("XKB is not supported. KbdModeLock is automatically disabled."));
		wPreferences.modelock = 0;
	}
#endif

	if (defaultScreenOnly)
		max = 1;
	else
		max = ScreenCount(dpy);

	wScreen = wmalloc(sizeof(WScreen *) * max);

	w_global.screen_count = 0;

	/* Check if TIFF images are supported */
	formats = RSupportedFileFormats();
	if (formats) {
		for (i = 0; formats[i] != NULL; i++) {
			if (strcmp(formats[i], "TIFF") == 0) {
				wPreferences.supports_tiff = 1;
				break;
			}
		}
	}

	/* manage the screens */
	for (j = 0; j < max; j++) {
		if (defaultScreenOnly || max == 1) {
			wScreen[w_global.screen_count] = wScreenInit(DefaultScreen(dpy));
			if (!wScreen[w_global.screen_count]) {
				wfatal(_("it seems that there is already a window manager running"));
				Exit(1);
			}
		} else {
			wScreen[w_global.screen_count] = wScreenInit(j);
			if (!wScreen[w_global.screen_count]) {
				wwarning(_("could not manage screen %i"), j);
				continue;
			}
		}
		w_global.screen_count++;
	}

	InitializeSwitchMenu();

	/* initialize/restore state for the screens */
	for (j = 0; j < w_global.screen_count; j++) {
		int lastDesktop;

		lastDesktop = wNETWMGetCurrentDesktopFromHint(wScreen[j]);

		wScreenRestoreState(wScreen[j]);

		/* manage all windows that were already here before us */
		if (!wPreferences.flags.nodock && wScreen[j]->dock)
			wScreen[j]->last_dock = wScreen[j]->dock;

		manageAllWindows(wScreen[j], wPreferences.flags.restarting == 2);

		/* restore saved menus */
		wMenuRestoreState(wScreen[j]);

		/* If we're not restarting, restore session */
		if (wPreferences.flags.restarting == 0 && !wPreferences.flags.norestore)
			wSessionRestoreState(wScreen[j]);

		if (!wPreferences.flags.noautolaunch) {
			/* auto-launch apps */
			if (!wPreferences.flags.nodock && wScreen[j]->dock) {
				wScreen[j]->last_dock = wScreen[j]->dock;
				wDockDoAutoLaunch(wScreen[j]->dock, 0);
			}
			/* auto-launch apps in clip */
			if (!wPreferences.flags.noclip) {
				int i;
				for (i = 0; i < w_global.workspace.count; i++) {
					if (w_global.workspace.array[i]->clip) {
						wScreen[j]->last_dock = w_global.workspace.array[i]->clip;
						wDockDoAutoLaunch(w_global.workspace.array[i]->clip, i);
					}
				}
			}
			/* auto-launch apps in drawers */
			if (!wPreferences.flags.nodrawer) {
				WDrawerChain *dc;
				for (dc = wScreen[j]->drawers; dc; dc = dc->next) {
					wScreen[j]->last_dock = dc->adrawer;
					wDockDoAutoLaunch(dc->adrawer, 0);
				}
			}
		}

		/* go to workspace where we were before restart */
		if (lastDesktop >= 0)
			wWorkspaceForceChange(wScreen[j], lastDesktop);
		else
			wSessionRestoreLastWorkspace(wScreen[j]);
	}

	if (w_global.screen_count == 0) {
		wfatal(_("could not manage any screen"));
		Exit(1);
	}

#ifndef HAVE_INOTIFY
	/* setup defaults file polling */
	if (!wPreferences.flags.nopolling && !wPreferences.flags.noupdates)
		WMAddTimerHandler(3000, wDefaultsCheckDomains, NULL);
#endif

}