/** Load the background for the specified desktop. */ void LoadBackground(int desktop) { XSetWindowAttributes attr; long attrValues; BackgroundNode *bp; /* Determine the background to load. */ for(bp = backgrounds; bp; bp = bp->next) { if(bp->desktop == desktop) { break; } } if(!bp) { bp = defaultBackground; } /* If there is no background specified for this desktop, just return. */ if(!bp || !bp->value) { return; } /* If the background isn't changing, don't do anything. */ if( lastBackground && bp->type == lastBackground->type && !strcmp(bp->value, lastBackground->value)) { return; } if(lastBackground && lastBackground->window) { JXUnmapWindow(display, lastBackground->window); } lastBackground = bp; /* Load the background based on type. */ switch(bp->type) { case BACKGROUND_COMMAND: RunCommand(bp->value); return; default: attrValues = CWBackPixmap; attr.background_pixmap = bp->pixmap; break; } JXChangeWindowAttributes(display, bp->window, attrValues, &attr); JXClearWindow(display, bp->window); JXMapWindow(display, bp->window); SetPixmapAtom(rootWindow, ATOM_XSETROOT_ID, bp->window); }
/** Prepare the connection. */ void StartupConnection(void) { XSetWindowAttributes attr; #ifdef USE_SHAPE int shapeError; #endif #ifdef USE_XRENDER int renderEvent; int renderError; #endif struct sigaction sa; char name[32]; Window win; XEvent event; int revert; initializing = 1; OpenConnection(); #if 0 XSynchronize(display, True); #endif /* Create the supporting window used to verify JWM is running. */ supportingWindow = JXCreateSimpleWindow(display, rootWindow, 0, 0, 1, 1, 0, 0, 0); /* Get the atom used for the window manager selection. */ snprintf(name, 32, "WM_S%d", rootScreen); managerSelection = JXInternAtom(display, name, False); /* Get the current window manager and take the selection. */ GrabServer(); win = JXGetSelectionOwner(display, managerSelection); if(win != None) { JXSelectInput(display, win, StructureNotifyMask); } JXSetSelectionOwner(display, managerSelection, supportingWindow, CurrentTime); UngrabServer(); /* Wait for the current selection owner to give up the selection. */ if(win != None) { /* Note that we need to wait for the current selection owner * to exit before we can expect to select SubstructureRedirectMask. */ XIfEvent(display, &event, SelectionReleased, (XPointer)&win); JXSync(display, False); } event.xclient.display = display; event.xclient.type = ClientMessage; event.xclient.window = rootWindow; event.xclient.message_type = JXInternAtom(display, managerProperty, False); event.xclient.format = 32; event.xclient.data.l[0] = CurrentTime; event.xclient.data.l[1] = managerSelection; event.xclient.data.l[2] = supportingWindow; event.xclient.data.l[3] = 2; event.xclient.data.l[4] = 0; JXSendEvent(display, rootWindow, False, StructureNotifyMask, &event); JXSync(display, False); JXSetErrorHandler(ErrorHandler); clientContext = XUniqueContext(); frameContext = XUniqueContext(); /* Set the events we want for the root window. * Note that asking for SubstructureRedirect will fail * if another window manager is already running. */ attr.event_mask = SubstructureRedirectMask | SubstructureNotifyMask | StructureNotifyMask | PropertyChangeMask | ColormapChangeMask | ButtonPressMask | ButtonReleaseMask | PointerMotionMask | PointerMotionHintMask; JXChangeWindowAttributes(display, rootWindow, CWEventMask, &attr); memset(&sa, 0, sizeof(sa)); sa.sa_flags = 0; sa.sa_handler = HandleExit; sigaction(SIGTERM, &sa, NULL); sigaction(SIGINT, &sa, NULL); sigaction(SIGHUP, &sa, NULL); sa.sa_flags = SA_NOCLDWAIT; sa.sa_handler = SIG_DFL; sigaction(SIGCHLD, &sa, NULL); #ifdef USE_SHAPE haveShape = JXShapeQueryExtension(display, &shapeEvent, &shapeError); if (haveShape) { Debug("shape extension enabled"); } else { Debug("shape extension disabled"); } #endif #ifdef USE_XRENDER haveRender = JXRenderQueryExtension(display, &renderEvent, &renderError); if(haveRender) { Debug("render extension enabled"); } else { Debug("render extension disabled"); } #endif /* Make sure we have input focus. */ win = None; JXGetInputFocus(display, &win, &revert); if(win == None) { JXSetInputFocus(display, rootWindow, RevertToParent, CurrentTime); } initializing = 0; }
/** Reparent a client window. */ void ReparentClient(ClientNode *np, char notOwner) { XSetWindowAttributes attr; int attrMask; int x, y, width, height; int north, south, east, west; Assert(np); if(notOwner) { JXAddToSaveSet(display, np->window); attr.event_mask = EnterWindowMask | ColormapChangeMask | PropertyChangeMask | KeyReleaseMask | StructureNotifyMask; attr.do_not_propagate_mask = NoEventMask; JXChangeWindowAttributes(display, np->window, CWEventMask | CWDontPropagate, &attr); } JXGrabButton(display, AnyButton, AnyModifier, np->window, True, ButtonPressMask, GrabModeSync, GrabModeAsync, None, None); if((np->state.border & (BORDER_TITLE | BORDER_OUTLINE)) == 0) { return; } attrMask = 0; /* We can't use PointerMotionHint mask here since the exact location * of the mouse on the frame is important. */ attrMask |= CWEventMask; attr.event_mask = ButtonPressMask | ButtonReleaseMask | ExposureMask | PointerMotionMask | SubstructureRedirectMask | SubstructureNotifyMask | EnterWindowMask | LeaveWindowMask | KeyPressMask | KeyReleaseMask; attrMask |= CWDontPropagate; attr.do_not_propagate_mask = ButtonPressMask | ButtonReleaseMask; attrMask |= CWBackPixel; attr.background_pixel = colors[COLOR_TITLE_BG2]; attrMask |= CWBorderPixel; attr.border_pixel = 0; x = np->x; y = np->y; width = np->width; height = np->height; GetBorderSize(&np->state, &north, &south, &east, &west); x -= west; y -= north; width += east + west; height += north + south; /* Create the frame window. */ np->parent = JXCreateWindow(display, rootWindow, x, y, width, height, 0, rootDepth, InputOutput, rootVisual, attrMask, &attr); /* Update the window to get only the events we want. */ attrMask = CWDontPropagate; attr.do_not_propagate_mask = ButtonPressMask | ButtonReleaseMask | PointerMotionMask | KeyPressMask | KeyReleaseMask; /* Make sure client doesn't muck with these. */ attrMask |= CWBackingStore; attr.backing_store = NotUseful; attrMask |= CWWinGravity; attr.win_gravity = NorthWestGravity; JXChangeWindowAttributes(display, np->window, attrMask, &attr); JXSetWindowBorderWidth(display, np->window, 0); /* Reparent the client window. */ JXReparentWindow(display, np->window, np->parent, west, north); }