drawing.c revision 0bbfda8a
10bbfda8aSnia/* 20bbfda8aSnia * Various drawing routines. 30bbfda8aSnia * 40bbfda8aSnia * These are generalized routines that are used in multiple places in the 50bbfda8aSnia * codebase. A number of other functions that are "drawing" related are 60bbfda8aSnia * left in various places through the codebase; some are only used in one 70bbfda8aSnia * file, and are left there for internal linkage, while others are 80bbfda8aSnia * part of a more abstract subdivision (e.g., the window decoration bits 90bbfda8aSnia * in win_decorations.c) and so belong there. 100bbfda8aSnia */ 110bbfda8aSnia 120bbfda8aSnia#include "ctwm.h" 130bbfda8aSnia 140bbfda8aSnia 150bbfda8aSnia#include "screen.h" 160bbfda8aSnia#include "gram.tab.h" 170bbfda8aSnia#include "occupation.h" 180bbfda8aSnia#include "vscreen.h" 190bbfda8aSnia 200bbfda8aSnia#include "drawing.h" 210bbfda8aSnia 220bbfda8aSnia 230bbfda8aSnia 240bbfda8aSnia/* 250bbfda8aSnia * "3D border" drawings are used all over the place, not just in the 260bbfda8aSnia * obvious usage as window borders. 270bbfda8aSnia */ 280bbfda8aSnia#define FBGC(gc, fix_fore, fix_back)\ 290bbfda8aSnia Gcv.foreground = fix_fore;\ 300bbfda8aSnia Gcv.background = fix_back;\ 310bbfda8aSnia XChangeGC(dpy, gc, GCForeground|GCBackground,&Gcv) 320bbfda8aSnia 330bbfda8aSniavoid 340bbfda8aSniaDraw3DBorder(Window w, int x, int y, int width, int height, int bw, 350bbfda8aSnia ColorPair cp, ButtonState state, bool fill, bool forcebw) 360bbfda8aSnia{ 370bbfda8aSnia int i; 380bbfda8aSnia XGCValues gcv; 390bbfda8aSnia unsigned long gcm; 400bbfda8aSnia 410bbfda8aSnia if((width < 1) || (height < 1)) { 420bbfda8aSnia return; 430bbfda8aSnia } 440bbfda8aSnia if(Scr->Monochrome != COLOR) { 450bbfda8aSnia if(fill) { 460bbfda8aSnia gcm = GCFillStyle; 470bbfda8aSnia gcv.fill_style = FillOpaqueStippled; 480bbfda8aSnia XChangeGC(dpy, Scr->BorderGC, gcm, &gcv); 490bbfda8aSnia XFillRectangle(dpy, w, Scr->BorderGC, x, y, width, height); 500bbfda8aSnia } 510bbfda8aSnia gcm = 0; 520bbfda8aSnia gcm |= GCLineStyle; 530bbfda8aSnia gcv.line_style = (state == on) ? LineSolid : LineDoubleDash; 540bbfda8aSnia gcm |= GCFillStyle; 550bbfda8aSnia gcv.fill_style = FillSolid; 560bbfda8aSnia XChangeGC(dpy, Scr->BorderGC, gcm, &gcv); 570bbfda8aSnia for(i = 0; i < bw; i++) { 580bbfda8aSnia XDrawLine(dpy, w, Scr->BorderGC, x, y + i, 590bbfda8aSnia x + width - i - 1, y + i); 600bbfda8aSnia XDrawLine(dpy, w, Scr->BorderGC, x + i, y, 610bbfda8aSnia x + i, y + height - i - 1); 620bbfda8aSnia } 630bbfda8aSnia 640bbfda8aSnia gcm = 0; 650bbfda8aSnia gcm |= GCLineStyle; 660bbfda8aSnia gcv.line_style = (state == on) ? LineDoubleDash : LineSolid; 670bbfda8aSnia gcm |= GCFillStyle; 680bbfda8aSnia gcv.fill_style = FillSolid; 690bbfda8aSnia XChangeGC(dpy, Scr->BorderGC, gcm, &gcv); 700bbfda8aSnia for(i = 0; i < bw; i++) { 710bbfda8aSnia XDrawLine(dpy, w, Scr->BorderGC, x + width - i - 1, y + i, 720bbfda8aSnia x + width - i - 1, y + height - 1); 730bbfda8aSnia XDrawLine(dpy, w, Scr->BorderGC, x + i, y + height - i - 1, 740bbfda8aSnia x + width - 1, y + height - i - 1); 750bbfda8aSnia } 760bbfda8aSnia return; 770bbfda8aSnia } 780bbfda8aSnia 790bbfda8aSnia if(fill) { 800bbfda8aSnia FBGC(Scr->BorderGC, cp.back, cp.fore); 810bbfda8aSnia XFillRectangle(dpy, w, Scr->BorderGC, x, y, width, height); 820bbfda8aSnia } 830bbfda8aSnia if(Scr->BeNiceToColormap) { 840bbfda8aSnia int dashoffset = 0; 850bbfda8aSnia 860bbfda8aSnia gcm = 0; 870bbfda8aSnia gcm |= GCLineStyle; 880bbfda8aSnia gcv.line_style = (forcebw) ? LineSolid : LineDoubleDash; 890bbfda8aSnia gcm |= GCBackground; 900bbfda8aSnia gcv.background = cp.back; 910bbfda8aSnia XChangeGC(dpy, Scr->BorderGC, gcm, &gcv); 920bbfda8aSnia 930bbfda8aSnia if(state == on) { 940bbfda8aSnia XSetForeground(dpy, Scr->BorderGC, Scr->Black); 950bbfda8aSnia } 960bbfda8aSnia else { 970bbfda8aSnia XSetForeground(dpy, Scr->BorderGC, Scr->White); 980bbfda8aSnia } 990bbfda8aSnia for(i = 0; i < bw; i++) { 1000bbfda8aSnia XDrawLine(dpy, w, Scr->BorderGC, x + i, y + dashoffset, 1010bbfda8aSnia x + i, y + height - i - 1); 1020bbfda8aSnia XDrawLine(dpy, w, Scr->BorderGC, x + dashoffset, y + i, 1030bbfda8aSnia x + width - i - 1, y + i); 1040bbfda8aSnia dashoffset = 1 - dashoffset; 1050bbfda8aSnia } 1060bbfda8aSnia XSetForeground(dpy, Scr->BorderGC, ((state == on) ? Scr->White : Scr->Black)); 1070bbfda8aSnia for(i = 0; i < bw; i++) { 1080bbfda8aSnia XDrawLine(dpy, w, Scr->BorderGC, x + i, y + height - i - 1, 1090bbfda8aSnia x + width - 1, y + height - i - 1); 1100bbfda8aSnia XDrawLine(dpy, w, Scr->BorderGC, x + width - i - 1, y + i, 1110bbfda8aSnia x + width - i - 1, y + height - 1); 1120bbfda8aSnia } 1130bbfda8aSnia return; 1140bbfda8aSnia } 1150bbfda8aSnia if(state == on) { 1160bbfda8aSnia FBGC(Scr->BorderGC, cp.shadd, cp.shadc); 1170bbfda8aSnia } 1180bbfda8aSnia else { 1190bbfda8aSnia FBGC(Scr->BorderGC, cp.shadc, cp.shadd); 1200bbfda8aSnia } 1210bbfda8aSnia for(i = 0; i < bw; i++) { 1220bbfda8aSnia XDrawLine(dpy, w, Scr->BorderGC, x, y + i, 1230bbfda8aSnia x + width - i - 1, y + i); 1240bbfda8aSnia XDrawLine(dpy, w, Scr->BorderGC, x + i, y, 1250bbfda8aSnia x + i, y + height - i - 1); 1260bbfda8aSnia } 1270bbfda8aSnia 1280bbfda8aSnia if(state == on) { 1290bbfda8aSnia FBGC(Scr->BorderGC, cp.shadc, cp.shadd); 1300bbfda8aSnia } 1310bbfda8aSnia else { 1320bbfda8aSnia FBGC(Scr->BorderGC, cp.shadd, cp.shadc); 1330bbfda8aSnia } 1340bbfda8aSnia for(i = 0; i < bw; i++) { 1350bbfda8aSnia XDrawLine(dpy, w, Scr->BorderGC, x + width - i - 1, y + i, 1360bbfda8aSnia x + width - i - 1, y + height - 1); 1370bbfda8aSnia XDrawLine(dpy, w, Scr->BorderGC, x + i, y + height - i - 1, 1380bbfda8aSnia x + width - 1, y + height - i - 1); 1390bbfda8aSnia } 1400bbfda8aSnia return; 1410bbfda8aSnia} 1420bbfda8aSnia 1430bbfda8aSnia#undef FBGC 1440bbfda8aSnia 1450bbfda8aSnia 1460bbfda8aSnia 1470bbfda8aSnia/* 1480bbfda8aSnia * Paint a button representing a workspace. This is used in the 1490bbfda8aSnia * workspace manager window when it button mode, as well as in the 1500bbfda8aSnia * f.occupy window. 1510bbfda8aSnia */ 1520bbfda8aSniavoid 1530bbfda8aSniaPaintWsButton(PWBType which, VirtualScreen *vs, Window w, 1540bbfda8aSnia char *label, ColorPair cp, ButtonState state) 1550bbfda8aSnia{ 1560bbfda8aSnia int bwidth, bheight; 1570bbfda8aSnia MyFont font; 1580bbfda8aSnia int hspace, vspace; 1590bbfda8aSnia 1600bbfda8aSnia if(which == WSPCWINDOW) { 1610bbfda8aSnia bwidth = vs->wsw->bwidth; 1620bbfda8aSnia bheight = vs->wsw->bheight; 1630bbfda8aSnia font = Scr->workSpaceMgr.buttonFont; 1640bbfda8aSnia } 1650bbfda8aSnia else if(which == OCCUPYWINDOW) { 1660bbfda8aSnia OccupyWindow *occwin = Scr->workSpaceMgr.occupyWindow; 1670bbfda8aSnia bwidth = occwin->bwidth; 1680bbfda8aSnia bheight = occwin->bheight; 1690bbfda8aSnia font = occwin->font; 1700bbfda8aSnia } 1710bbfda8aSnia else if(which == OCCUPYBUTTON) { 1720bbfda8aSnia OccupyWindow *occwin = Scr->workSpaceMgr.occupyWindow; 1730bbfda8aSnia bwidth = occwin->owidth; 1740bbfda8aSnia bheight = occwin->bheight; 1750bbfda8aSnia font = occwin->font; 1760bbfda8aSnia } 1770bbfda8aSnia else { 1780bbfda8aSnia return; 1790bbfda8aSnia } 1800bbfda8aSnia 1810bbfda8aSnia { 1820bbfda8aSnia int strWid, strHei; 1830bbfda8aSnia XRectangle inc_rect; 1840bbfda8aSnia XRectangle logical_rect; 1850bbfda8aSnia 1860bbfda8aSnia XmbTextExtents(font.font_set, label, strlen(label), &inc_rect, 1870bbfda8aSnia &logical_rect); 1880bbfda8aSnia strHei = logical_rect.height; 1890bbfda8aSnia vspace = ((bheight + strHei - font.descent) / 2); 1900bbfda8aSnia strWid = logical_rect.width; 1910bbfda8aSnia hspace = (bwidth - strWid) / 2; 1920bbfda8aSnia } 1930bbfda8aSnia 1940bbfda8aSnia if(hspace < (Scr->WMgrButtonShadowDepth + 1)) { 1950bbfda8aSnia hspace = Scr->WMgrButtonShadowDepth + 1; 1960bbfda8aSnia } 1970bbfda8aSnia XClearWindow(dpy, w); 1980bbfda8aSnia 1990bbfda8aSnia if(Scr->Monochrome == COLOR) { 2000bbfda8aSnia Draw3DBorder(w, 0, 0, bwidth, bheight, Scr->WMgrButtonShadowDepth, 2010bbfda8aSnia cp, state, true, false); 2020bbfda8aSnia 2030bbfda8aSnia switch(Scr->workSpaceMgr.buttonStyle) { 2040bbfda8aSnia case STYLE_NORMAL: 2050bbfda8aSnia break; 2060bbfda8aSnia 2070bbfda8aSnia case STYLE_STYLE1: 2080bbfda8aSnia Draw3DBorder(w, 2090bbfda8aSnia Scr->WMgrButtonShadowDepth - 1, 2100bbfda8aSnia Scr->WMgrButtonShadowDepth - 1, 2110bbfda8aSnia bwidth - 2 * Scr->WMgrButtonShadowDepth + 2, 2120bbfda8aSnia bheight - 2 * Scr->WMgrButtonShadowDepth + 2, 2130bbfda8aSnia 1, cp, (state == on) ? off : on, true, false); 2140bbfda8aSnia break; 2150bbfda8aSnia 2160bbfda8aSnia case STYLE_STYLE2: 2170bbfda8aSnia Draw3DBorder(w, 2180bbfda8aSnia Scr->WMgrButtonShadowDepth / 2, 2190bbfda8aSnia Scr->WMgrButtonShadowDepth / 2, 2200bbfda8aSnia bwidth - Scr->WMgrButtonShadowDepth, 2210bbfda8aSnia bheight - Scr->WMgrButtonShadowDepth, 2220bbfda8aSnia 1, cp, (state == on) ? off : on, true, false); 2230bbfda8aSnia break; 2240bbfda8aSnia 2250bbfda8aSnia case STYLE_STYLE3: 2260bbfda8aSnia Draw3DBorder(w, 2270bbfda8aSnia 1, 2280bbfda8aSnia 1, 2290bbfda8aSnia bwidth - 2, 2300bbfda8aSnia bheight - 2, 2310bbfda8aSnia 1, cp, (state == on) ? off : on, true, false); 2320bbfda8aSnia break; 2330bbfda8aSnia } 2340bbfda8aSnia FB(cp.fore, cp.back); 2350bbfda8aSnia XmbDrawString(dpy, w, font.font_set, Scr->NormalGC, hspace, vspace, 2360bbfda8aSnia label, strlen(label)); 2370bbfda8aSnia } 2380bbfda8aSnia else { 2390bbfda8aSnia Draw3DBorder(w, 0, 0, bwidth, bheight, Scr->WMgrButtonShadowDepth, 2400bbfda8aSnia cp, state, true, false); 2410bbfda8aSnia if(state == on) { 2420bbfda8aSnia FB(cp.fore, cp.back); 2430bbfda8aSnia XmbDrawImageString(dpy, w, font.font_set, Scr->NormalGC, hspace, vspace, 2440bbfda8aSnia label, strlen(label)); 2450bbfda8aSnia } 2460bbfda8aSnia else { 2470bbfda8aSnia FB(cp.back, cp.fore); 2480bbfda8aSnia XmbDrawImageString(dpy, w, font.font_set, Scr->NormalGC, hspace, vspace, 2490bbfda8aSnia label, strlen(label)); 2500bbfda8aSnia } 2510bbfda8aSnia } 2520bbfda8aSnia} 253