/* * [ ctwm ] * * Copyright 1992 Claude Lecommandeur. * * Permission to use, copy, modify and distribute this software [ctwm] and * its documentation for any purpose is hereby granted without fee, provided * that the above copyright notice appear in all copies and that both that * copyright notice and this permission notice appear in supporting documen- * tation, and that the name of Claude Lecommandeur not be used in adverti- * sing or publicity pertaining to distribution of the software without * specific, written prior permission. Claude Lecommandeur make no represen- * tations about the suitability of this software for any purpose. It is * provided "as is" without express or implied warranty. * * Claude Lecommandeur DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO * EVENT SHALL Claude Lecommandeur BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. * * Author: Claude Lecommandeur [ lecom@sic.epfl.ch ][ April 1992 ] */ #include #include #include "twm.h" #include "cursor.h" #include "screen.h" extern void twmrc_error_prefix(void); void InitVirtualScreens (ScreenInfo *scr) { Cursor cursor; unsigned long valuemask, attrmask; XSetWindowAttributes attributes; name_list *nptr; Atom _XA_WM_VIRTUALROOT = XInternAtom (dpy, "WM_VIRTUALROOT", False); Bool userealroot = True; NewFontCursor (&cursor, "X_cursor"); if (scr->VirtualScreens == NULL) { if (userealroot) { virtualScreen *vs = (virtualScreen*) malloc (sizeof (virtualScreen)); vs->x = 0; vs->y = 0; vs->w = scr->rootw; vs->h = scr->rooth; vs->window = scr->Root; vs->next = NULL; scr->vScreenList = vs; scr->currentvs = vs; return; #if 0 } else { scr->VirtualScreens = (name_list*) malloc (sizeof (name_list)); scr->VirtualScreens->next = NULL; scr->VirtualScreens->name = (char*) malloc (64); sprintf (scr->VirtualScreens->name, "%dx%d+0+0", scr->rootw, scr->rooth); #endif } } attrmask = ColormapChangeMask | EnterWindowMask | PropertyChangeMask | SubstructureRedirectMask | KeyPressMask | ButtonPressMask | ButtonReleaseMask; valuemask = CWBackingStore | CWSaveUnder | CWBackPixel | CWOverrideRedirect | CWEventMask | CWCursor; attributes.backing_store = NotUseful; attributes.save_under = False; attributes.override_redirect = True; attributes.event_mask = attrmask; attributes.cursor = cursor; attributes.background_pixel = Scr->Black; scr->vScreenList = NULL; for (nptr = Scr->VirtualScreens; nptr != NULL; nptr = nptr->next) { virtualScreen *vs; char *geometry = (char*) nptr->name; int x = 0, y = 0; unsigned int w = 0, h = 0; XParseGeometry (geometry, &x, &y, &w, &h); if ((x < 0) || (y < 0) || (w > scr->rootw) || (h > scr->rooth)) { twmrc_error_prefix (); fprintf (stderr, "InitVirtualScreens : invalid geometry : %s\n", geometry); continue; } vs = (virtualScreen*) malloc (sizeof (virtualScreen)); vs->x = x; vs->y = y; vs->w = w; vs->h = h; vs->window = XCreateWindow (dpy, Scr->Root, x, y, w, h, 0, CopyFromParent, (unsigned int) CopyFromParent, (Visual *) CopyFromParent, valuemask, &attributes); XSync (dpy, 0); XMapWindow (dpy, vs->window); XChangeProperty (dpy, vs->window, _XA_WM_VIRTUALROOT, XA_STRING, 8, PropModeReplace, (unsigned char *) "Yes", 4); vs->next = scr->vScreenList; scr->vScreenList = vs; } if (scr->vScreenList == NULL) { twmrc_error_prefix (); fprintf (stderr, "no valid VirtualScreens found, exiting...\n"); exit (1); } } virtualScreen *findIfVScreenOf (int x, int y) { virtualScreen *vs; for (vs = Scr->vScreenList; vs != NULL; vs = vs->next) { if ((x >= vs->x) && ((x - vs->x) < vs->w) && (y >= vs->y) && ((y - vs->y) < vs->h)) { return vs; } } return NULL; } virtualScreen *getVScreenOf (int x, int y) { virtualScreen *vs; if ((vs = findIfVScreenOf(x, y))) return vs; return Scr->vScreenList; } /* * Returns the order that virtual screens are displayed for the vscreen * list. This is stored this way so everything ends up in the right place * on a ctwm restart. */ Bool CtwmGetVScreenMap (Display *display, Window rootw, char *outbuf, int *outbuf_len) { Atom _XA_WM_CTWM_VSCREENMAP; unsigned char *prop; unsigned long bytesafter; unsigned long len; Atom actual_type; int actual_format; _XA_WM_CTWM_VSCREENMAP = XInternAtom (display, "WM_CTWM_VSCREENMAP", True); if (_XA_WM_CTWM_VSCREENMAP == None) return (False); if (XGetWindowProperty (display, rootw, _XA_WM_CTWM_VSCREENMAP, 0L, 512, False, XA_STRING, &actual_type, &actual_format, &len, &bytesafter, &prop) != Success) return (False); if (len == 0) return (False); *outbuf_len = (len>=*outbuf_len)?*outbuf_len-1:len; memcpy(outbuf, prop, *outbuf_len); outbuf[*outbuf_len] = '\0'; XFree((char *)prop); return True; } Bool CtwmSetVScreenMap(Display *display, Window rootw, struct virtualScreen *firstvs) { char buf[1024]; int tally = 0; Atom _XA_WM_CTWM_VSCREENMAP; struct virtualScreen *vs; _XA_WM_CTWM_VSCREENMAP = XInternAtom (display, "WM_CTWM_VSCREENMAP", True); if(_XA_WM_CTWM_VSCREENMAP == None) return(False); memset(buf, 0, sizeof(buf)); for(vs = firstvs; vs; vs = vs->next) { if(tally) strcat(buf, ","); if(vs->wsw&&vs->wsw->currentwspc&&vs->wsw->currentwspc->name) { strcat(buf, vs->wsw->currentwspc->name); tally++; } } if(! tally) return(False); XChangeProperty(display, rootw, _XA_WM_CTWM_VSCREENMAP, XA_STRING, 8, PropModeReplace, (unsigned char *)buf, strlen(buf)); return(True); }