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; }
void W_DragSourceStartTimer(WMDraggingInfo * info) { W_DragSourceStopTimer(); dndSourceTimer = WMAddTimerHandler(XDND_DESTINATION_RESPONSE_MAX_DELAY, dragSourceResponseTimeOut, XDND_SOURCE_VIEW(info)); }
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); } }
WMHandlerID WMAddPersistentTimerHandler(int milliseconds, WMCallback *callback, void *cdata) { TimerHandler *handler = WMAddTimerHandler(milliseconds, callback, cdata); if (handler != NULL) handler->nextDelay = milliseconds; return handler; }
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); }
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; } }
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); } }
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; } }
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); } }
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--; } }
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; } }
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); }
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); }
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); } }
/* *---------------------------------------------------------- * 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 }