/****************************************************************************/ /* This module is based on fvwm, but has been siginificantly modified */ /* by TakaC Hasegawa (tak@bioele.nuee.nagoya-u.ac.jp) */ /****************************************************************************/ /**************************************************************************** * This module is based on Twm, but has been siginificantly modified * by Rob Nation (nation@rocket.sanders.lockheed.com) ****************************************************************************/ /*****************************************************************************/ /** Copyright 1988 by Evans & Sutherland Computer Corporation, **/ /** Salt Lake City, Utah **/ /** Portions Copyright 1989 by the Massachusetts Institute of Technology **/ /** Cambridge, Massachusetts **/ /** **/ /** All Rights Reserved **/ /** **/ /** Permission to use, copy, modify, and distribute this software and **/ /** its documentation for any purpose and without fee is hereby **/ /** granted, provided that the above copyright notice appear in all **/ /** copies and that both that copyright notice and this permis- **/ /** sion notice appear in supporting documentation, and that the **/ /** names of Evans & Sutherland and M.I.T. not be used in advertising **/ /** in publicity pertaining to distribution of the software without **/ /** specific, written prior permission. **/ /** **/ /** EVANS & SUTHERLAND AND M.I.T. DISCLAIM ALL WARRANTIES WITH REGARD **/ /** TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANT- **/ /** ABILITY AND FITNESS, IN NO EVENT SHALL EVANS & SUTHERLAND OR **/ /** M.I.T. BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAM- **/ /** AGES 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. **/ /*****************************************************************************/ #include #include #include #include "mlvwm.h" #include "screen.h" #include "misc.h" #include "borders.h" #include static unsigned char mesh_bits_v[] = { 0x04, 0x01 }; static unsigned char mesh_bits_h[] = { 0x01, 0x00, 0x02, 0x00 }; void DrawShadowBox( int x, int y, int w, int h, Window win, int d, GC hilight, GC shadow, char mode ) { int lp; w--; h--; for( lp=0; lpflags&(TITLE|SBARV|SBARH|RESIZER) ){ shape_x = (Scr.flags&SYSTEM8?5:0); shape_y = tmp_win->flags & TITLE ? TITLE_HEIGHT+1 : 0; } else{ shape_x = 6; shape_y = 6; } XShapeCombineShape (dpy, tmp_win->frame, ShapeBounding, shape_x, shape_y, tmp_win->w, ShapeBounding, ShapeSet); if ( tmp_win->flags&TITLE ){ rect[0].x = -1; rect[0].y = -1; rect[0].width = w-1; rect[0].height = TITLE_HEIGHT+2; point++; for( lp=0; lp<3; lp++ ){ rect[lp+1].x = tmp_win->frame_w-2+lp; rect[lp+1].y = lp; rect[lp+1].width = 1; rect[lp+1].height = TITLE_HEIGHT+1-lp; point++; } if( tmp_win->flags&SHADE ) for( lp=0; lp<3; lp++ ){ rect[lp+4].x = lp; rect[lp+4].y = tmp_win->frame_h-2+lp; rect[lp+4].width = tmp_win->frame_w+1-lp; rect[lp+4].height = 1; point++; } XShapeCombineRectangles(dpy,tmp_win->frame,ShapeBounding, 0,0,rect,point,ShapeUnion,Unsorted); } if ( tmp_win->flags&RESIZER ){ rect[0].x = tmp_win->frame_w-SBAR_WH-2-1-(Scr.flags&SYSTEM8?4:0); rect[0].y = tmp_win->frame_h-SBAR_WH-2-1-(Scr.flags&SYSTEM8?4:0); rect[0].width = SBAR_WH+2+(Scr.flags&SYSTEM8?4:0); rect[0].height = SBAR_WH+2+(Scr.flags&SYSTEM8?4:0); XShapeCombineRectangles(dpy,tmp_win->frame,ShapeBounding, 0,0,rect,1,ShapeUnion,Unsorted); } } void SetUpFrame( MlvwmWindow *t, int x, int y, int w, int h, Bool sendEvent ) { XWindowChanges xwcv; unsigned long xwcm; int title_height, sbar_v, sbar_h, resize_r; int sbar_vh, sbar_hw; title_height = t->flags & TITLE ? TITLE_HEIGHT : 0; sbar_v = t->flags & SBARV ? SBAR_WH : 0; sbar_h = t->flags & SBARH ? SBAR_WH : 0; resize_r = t->flags & RESIZER ? SBAR_WH : ( sbar_v!=0 && sbar_h!=0 ? SBAR_WH : 0 ); if( t->flags&TITLE ) XResizeWindow( dpy, t->title_w, w-2-(t->flags&SBARV?0:1)-(Scr.flags&SYSTEM8?4:0), TITLE_HEIGHT ); if( t->flags&MINMAXR ){ if( Scr.flags&SYSTEM8 ) XMoveWindow(dpy, t->minmax_b, w-BOXSIZE-9-(t->flags&SHADER?BOXSIZE+4:0), (TITLE_HEIGHT-BOXSIZE)/2); else XMoveWindow(dpy, t->minmax_b, w-BOXSIZE*2-1, (TITLE_HEIGHT-BOXSIZE)/2); } if( t->flags&SHADER ) XMoveWindow(dpy, t->shade_b, w-BOXSIZE-9, (TITLE_HEIGHT-BOXSIZE)/2); if( !(t->flags&SHADE) ){ if( t->flags & ( TITLE | SBARV | SBARH | RESIZER ) ){ t->attr.width = w-sbar_v-(t->flags&SBARV ? 2 : 1 )-1; t->attr.height = h-sbar_h-title_height-2- (t->flags&TITLE ? 1 : 0)- (t->flags&SBARH ? 1 : 0); if( Scr.flags&SYSTEM8 ){ t->attr.width -= 12; t->attr.height -= 6; } XMoveResizeWindow( dpy, t->Parent, Scr.flags&SYSTEM8?5:-1, t->flags & TITLE ? TITLE_HEIGHT : -1, t->attr.width, t->attr.height ); } else{ t->attr.width = w-12; t->attr.height = h-12; XMoveResizeWindow( dpy, t->Parent, 5, 5, t->attr.width, t->attr.height ); } if( t->flags&RESIZER ) XMoveWindow( dpy, t->resize_b, w-SBAR_WH-3-(Scr.flags&SYSTEM8?4:0), h-SBAR_WH-3-(Scr.flags&SYSTEM8?4:0) ); /* Vertical Scroll bar Height */ sbar_vh = t->attr.height- (t->flags&RESIZER && !(t->flags&SBARH)?SBAR_WH+1:0); /* Horizontal Scroll width */ sbar_hw = t->attr.width- (t->flags&RESIZER && !(t->flags&SBARV)?SBAR_WH+1:0); if( t->flags&SBARV ){ int anker_position; XMoveResizeWindow( dpy, t->scroll_v[0], t->attr.width+(Scr.flags&SYSTEM8?6:0), t->flags & TITLE ? TITLE_HEIGHT : -1, SBAR_WH, sbar_vh ); XMoveWindow( dpy, t->scroll_v[2], 0, sbar_vh-SBAR_WH ); if( t->flags&SCROLL ){ if( t->frame_hwin_h ) anker_position = (double)((sbar_vh-3*SBAR_WH-2)*t->win_y)/ (double)(t->frame_h-t->win_h) + SBAR_WH+1; else anker_position = SBAR_WH+2; if( anker_position>sbar_vh-3*SBAR_WH-2+SBAR_WH+1 ){ anker_position = sbar_vh-3*SBAR_WH-2+SBAR_WH+1; t->win_y = t->frame_h-t->win_h; } XMoveWindow( dpy, t->scroll_v[3], 0, anker_position ); } } if( t->flags&SBARH ){ int anker_position; XMoveResizeWindow( dpy,t->scroll_h[0], Scr.flags&SYSTEM8?5:-1, h-1-SBAR_WH-2-(Scr.flags&SYSTEM8?6:0), sbar_hw, SBAR_WH ); XMoveWindow( dpy, t->scroll_h[2], sbar_hw-SBAR_WH, 0 ); if( t->flags&SCROLL ){ if( t->frame_wwin_w ) anker_position = (double)( (sbar_hw-3*SBAR_WH-2)*t->win_x)/ (double)(t->frame_w-t->win_w) + SBAR_WH+1; else anker_position = SBAR_WH+2; if( anker_position>sbar_hw-3*SBAR_WH-2+SBAR_WH+1 ){ anker_position = sbar_hw-3*SBAR_WH-2+SBAR_WH+1; t->win_x = t->frame_w-t->win_w; } XMoveWindow( dpy, t->scroll_h[3], anker_position, 0 ); } } } if( t->flags & SCROLL ){ if( t->flags & SBARH ){ t->attr.width = w>t->win_w ? t->attr.width : t->win_w-sbar_v-(t->flags&SBARV ? 2 : 1 )-1 -(Scr.flags&SYSTEM8?12:0); t->win_x = w>t->win_w ? 0 : t->win_x; } if( t->flags & SBARV ){ t->attr.height = h>t->win_h ? t->attr.height : t->win_h-sbar_h-title_height-2- (t->flags&TITLE ? 1 : 0)-(t->flags&SBARH ? 1 : 0) -(Scr.flags&SYSTEM8?6:0); t->win_y = h>t->win_h ? 0 : t->win_y; } } else{ t->win_x = 0; t->win_y = 0; } XMoveResizeWindow( dpy, t->w, t->win_x, t->win_y, t->attr.width, t->attr.height ); xwcm = (CWWidth | CWHeight | CWX | CWY ); xwcv.x = x; xwcv.y = y; xwcv.width = w; xwcv.height = h; XConfigureWindow( dpy, t->frame, xwcm, &xwcv ); if( (!(t->wShaped) || t->flags&SHADE) && t->flags & ( TITLE | SBARV | SBARH | RESIZER )){ int lp; XRectangle rect[7]; rect[0].x = -1; rect[0].y = -1; rect[0].width = t->frame_w-1; rect[0].height = t->frame_h-1; for( lp=0; lp<3; lp++ ){ rect[lp+1].x = t->frame_w-2+lp; rect[lp+1].y = lp; rect[lp+1].width = 1; rect[lp+1].height = t->frame_h+1-lp; } for( lp=0; lp<3; lp++ ){ rect[lp+4].x = lp; rect[lp+4].y = t->frame_h-2+lp; rect[lp+4].width = t->frame_w+1-lp; rect[lp+4].height = 1; } XShapeCombineRectangles(dpy,t->frame,ShapeBounding, 0,0,rect,7,ShapeSet,YSorted); } if( t->wShaped ) SetShape( t, w ); if (sendEvent && !(t->flags&SHADE) ){ XEvent client_event; client_event.type = ConfigureNotify; client_event.xconfigure.display = dpy; client_event.xconfigure.event = t->w; client_event.xconfigure.window = t->w; if( t->flags&(TITLE|SBARV|SBARH|RESIZER)){ client_event.xconfigure.x = x + 1 + t->win_x; client_event.xconfigure.y = y + title_height + 1 + t->win_y; if( Scr.flags&SYSTEM8 ) client_event.xconfigure.x += 6; } else{ client_event.xconfigure.x = x + 6; client_event.xconfigure.y = y + 6; } client_event.xconfigure.width = t->attr.width; client_event.xconfigure.height = t->attr.height; client_event.xconfigure.border_width =0; /* Modifed */ client_event.xconfigure.above = t->frame; client_event.xconfigure.override_redirect = False; XSendEvent(dpy, t->w, False, StructureNotifyMask, &client_event); } } void FillGradation( Window win ) { XClearWindow( dpy, win ); XDrawRectangle( dpy, win, Scr.BlackGC, 1, 1, BOXSIZE-3, BOXSIZE-3 ); DrawShadowBox( 0, 0, BOXSIZE, BOXSIZE, win, 1, Scr.Gray3GC, Scr.WhiteGC, SHADOW_ALL ); DrawShadowBox( 4, 4, BOXSIZE-6, BOXSIZE-6, win, BOXSIZE/2-2, Scr.WhiteGC, Scr.WhiteGC, SHADOW_BOTTOM|SHADOW_RIGHT ); DrawShadowBox( 2, 2, BOXSIZE-6, BOXSIZE-6, win, BOXSIZE/2-2, Scr.Gray3GC, Scr.WhiteGC, SHADOW_TOP|SHADOW_LEFT ); DrawShadowBox( 2, 2, 3, 3, win, 2, Scr.Gray2GC, Scr.WhiteGC, SHADOW_TOP|SHADOW_LEFT ); DrawShadowBox( 2, 2, BOXSIZE-4, BOXSIZE-4, win, 1, Scr.WhiteGC, Scr.Gray3GC, SHADOW_ALL ); } void DrawCloseBox( MlvwmWindow *t, Bool on ) { unsigned long mask, valuemask; XSetWindowAttributes attributes_box; XGCValues xgcv; mask = GCForeground; if( on || Scr.flags&SYSTEM8 ){ if( !XGetGCValues( dpy, (Scr.flags&SYSTEM8?Scr.Gray4GC:Scr.Gray3GC), mask, &xgcv ) ){ fprintf( stderr, "Sorry Can not get GC Values 3\n"); xgcv.foreground = WhitePixel( dpy, Scr.screen ); } attributes_box.background_pixel = xgcv.foreground; } else attributes_box.background_pixel = WhitePixel( dpy, Scr.screen ); if( on ) attributes_box.cursor = Scr.MlvwmCursors[DESTROY]; else attributes_box.cursor = Scr.MlvwmCursors[DEFAULT]; valuemask = CWBackPixel | CWCursor; XChangeWindowAttributes( dpy, t->close_b, valuemask, &attributes_box ); XClearWindow( dpy, t->close_b ); if( on ){ if( Scr.flags&SYSTEM8 ){ XFillRectangle( dpy, t->title_w, Scr.Gray4GC, 4, (TITLE_HEIGHT-BOXSIZE)/2-2, BOXSIZE+7, BOXSIZE+2 ); FillGradation( t->close_b ); } else{ XFillRectangle( dpy, t->title_w, Scr.Gray4GC, BOXSIZE-1, (TITLE_HEIGHT-BOXSIZE)/2-1, BOXSIZE+4, BOXSIZE+1 ); DrawShadowBox( 0, 0, BOXSIZE, BOXSIZE, t->close_b, 1, Scr.BlackGC, Scr.WhiteGC, SHADOW_ALL ); DrawShadowBox( 1, 1, BOXSIZE-2, BOXSIZE-2, t->close_b, 1, Scr.WhiteGC, Scr.BlackGC, SHADOW_ALL ); } } } void DrawMinMax( MlvwmWindow *t, Bool on ) { unsigned long mask, valuemask; XSetWindowAttributes attributes_box; XGCValues xgcv; mask = GCForeground; if( on || Scr.flags&SYSTEM8 ){ if( !XGetGCValues( dpy, (Scr.flags&SYSTEM8?Scr.Gray4GC:Scr.Gray3GC), mask, &xgcv ) ){ fprintf( stderr, "Sorry Can not get GC Values 3\n"); xgcv.foreground = WhitePixel( dpy, Scr.screen ); } attributes_box.background_pixel = xgcv.foreground; } else attributes_box.background_pixel = WhitePixel( dpy, Scr.screen ); if( on ) attributes_box.cursor = Scr.MlvwmCursors[MINMAX_CURSOR]; else attributes_box.cursor = Scr.MlvwmCursors[DEFAULT]; valuemask = CWBackPixel | CWCursor; XChangeWindowAttributes( dpy, t->minmax_b, valuemask, &attributes_box ); XClearWindow( dpy, t->minmax_b ); if( on ){ if( Scr.flags&SYSTEM8 ){ XFillRectangle( dpy, t->title_w, Scr.Gray4GC, t->frame_w-BOXSIZE-15- (t->flags&SHADER?BOXSIZE+6:0), (TITLE_HEIGHT-BOXSIZE)/2-1, BOXSIZE+8, BOXSIZE+2 ); FillGradation( t->minmax_b ); XDrawRectangle( dpy, t->minmax_b, Scr.BlackGC, 1, 1, BOXSIZE-6, BOXSIZE-6 ); } else{ XFillRectangle( dpy, t->title_w, Scr.Gray4GC, t->frame_w-BOXSIZE*2-3,(TITLE_HEIGHT-BOXSIZE)/2-1, BOXSIZE+4, BOXSIZE+1 ); DrawShadowBox( 0, 0, BOXSIZE, BOXSIZE, t->minmax_b, 1, Scr.BlackGC, Scr.WhiteGC, SHADOW_ALL ); DrawShadowBox( 1, 1, BOXSIZE-2, BOXSIZE-2, t->minmax_b, 1, Scr.WhiteGC, Scr.BlackGC, SHADOW_ALL ); DrawShadowBox( 1, 1, BOXSIZE-6, BOXSIZE-6, t->minmax_b, 1, Scr.WhiteGC, Scr.BlackGC, SHADOW_ALL ); } } } void DrawShadeR( MlvwmWindow *t, Bool on ) { unsigned long mask, valuemask; XSetWindowAttributes attributes_box; XGCValues xgcv; mask = GCForeground; if( on || Scr.flags&SYSTEM8 ){ if( !XGetGCValues( dpy, (Scr.flags&SYSTEM8?Scr.Gray4GC:Scr.Gray3GC), mask, &xgcv ) ){ fprintf( stderr, "Sorry Can not get GC Values 3\n"); xgcv.foreground = WhitePixel( dpy, Scr.screen ); } attributes_box.background_pixel = xgcv.foreground; } else attributes_box.background_pixel = WhitePixel( dpy, Scr.screen ); if( on ){ if( t->flags&SHADE ) attributes_box.cursor = Scr.MlvwmCursors[SHADER_DOWN_CURSOR]; else attributes_box.cursor = Scr.MlvwmCursors[SHADER_UP_CURSOR]; } else attributes_box.cursor = Scr.MlvwmCursors[DEFAULT]; valuemask = CWBackPixel | CWCursor; XChangeWindowAttributes( dpy, t->shade_b, valuemask, &attributes_box ); XClearWindow( dpy, t->shade_b ); if( on ){ XFillRectangle( dpy, t->title_w, Scr.Gray4GC, t->frame_w-BOXSIZE-15, (TITLE_HEIGHT-BOXSIZE)/2-1, BOXSIZE+8, BOXSIZE+2 ); FillGradation( t->shade_b ); XDrawLine( dpy, t->shade_b, Scr.BlackGC, 1, BOXSIZE/2-1, BOXSIZE-3, BOXSIZE/2-1 ); XDrawLine( dpy, t->shade_b, Scr.BlackGC, 1, BOXSIZE/2+1, BOXSIZE-3, BOXSIZE/2+1 ); } } void SetTitleBar( MlvwmWindow *t, Bool on_off ) { int w, offset; int titlelength, drawable; int lp; unsigned long mask, valuemask; XSetWindowAttributes attributes_title, attributes_box; XGCValues xgcv; GC dispgc; mask = GCForeground; if( on_off || Scr.flags&SYSTEM8 ){ if( !XGetGCValues( dpy, Scr.Gray4GC, mask, &xgcv ) ){ fprintf( stderr, "Sorry Can not get GC Values 4\n"); xgcv.foreground = WhitePixel( dpy, Scr.screen ); } attributes_title.background_pixel = xgcv.foreground; if( !XGetGCValues( dpy, Scr.Gray3GC, mask, &xgcv ) ){ fprintf( stderr, "Sorry Can not get GC Values 3\n"); xgcv.foreground = WhitePixel( dpy, Scr.screen ); } if( Scr.flags&SYSTEM8 ) attributes_box.background_pixel = WhitePixel( dpy, Scr.screen ); else attributes_box.background_pixel = xgcv.foreground; } else{ attributes_title.background_pixel = WhitePixel( dpy, Scr.screen ); attributes_box.background_pixel = WhitePixel( dpy, Scr.screen ); } if( on_off ) attributes_title.cursor = Scr.MlvwmCursors[TITLE_CURSOR]; else attributes_title.cursor = Scr.MlvwmCursors[DEFAULT]; valuemask = CWBackPixel | CWCursor; XChangeWindowAttributes( dpy, t->title_w, valuemask, &attributes_title ); XClearWindow( dpy, t->title_w ); drawable = t->frame_w-14*4; if( t->flags&CLOSER || t->flags&MINMAXR ) drawable-=BOXSIZE*2; if( t->flags&SHADER && t->flags&MINMAXR ) drawable-=BOXSIZE*2; titlelength = strlen( t->name )+1; do{ titlelength--; StrWidthHeight( WINDOWFONT, &w, NULL, &offset, t->name, titlelength ); } while( w+20>drawable && titlelength>0 ); if( on_off ){ for( lp=4; lp<14; lp+=3 ){ if( Scr.d_depth>1 ){ if( Scr.flags&SYSTEM8 ) DrawShadowBox( 4, lp-2, t->frame_w-15, 2, t->title_w, 1, Scr.WhiteGC, Scr.Gray1GC, SHADOW_ALL ); else DrawShadowBox( 4, lp-1, t->frame_w-11, 2, t->title_w, 1, Scr.Gray1GC, Scr.WhiteGC, SHADOW_ALL ); } else XDrawLine( dpy, t->title_w, Scr.BlackGC, 4, lp-1, t->frame_w-7, lp-1 ); } if( Scr.d_depth>1 ){ if( Scr.flags&SYSTEM8 ) DrawShadowBox( 4, 14, t->frame_w-15, 2, t->title_w, 1, Scr.WhiteGC, Scr.Gray1GC, SHADOW_ALL ); else XDrawLine( dpy, t->title_w, Scr.Gray1GC, 4, 15, t->frame_w-9, 15 ); } else XDrawLine( dpy, t->title_w, Scr.BlackGC, 4, 15, t->frame_w-7, 15 ); if( Scr.flags&SYSTEM8 ){ DrawShadowBox( 0, 0, t->frame_w-2, TITLE_HEIGHT, t->title_w, 1, Scr.WhiteGC, Scr.Gray2GC, SHADOW_TOP ); if( !(t->flags&SHADE) ) XDrawLine( dpy, t->title_w, Scr.Gray2GC, 2, TITLE_HEIGHT-1, t->frame_w-9, TITLE_HEIGHT-1 ); } else DrawShadowBox( 0, 0, t->frame_w-2, TITLE_HEIGHT, t->title_w, 1, Scr.WhiteGC, Scr.Gray2GC, SHADOW_ALL ); XFillRectangle( dpy, t->title_w, Scr.Gray4GC, (t->frame_w-w)/2-10, 1, w+20, TITLE_HEIGHT-2 ); dispgc = Scr.BlackGC; } else{ if( Scr.d_depth>1 ) dispgc = Scr.Gray3GC; else dispgc = Scr.BlackGC; } if( t->flags&CLOSER ) DrawCloseBox( t, on_off ); if( t->flags&MINMAXR ) DrawMinMax( t, on_off ); if( t->flags&SHADER ) DrawShadeR( t, on_off ); XDRAWSTRING( dpy, t->title_w, WINDOWFONT, dispgc, (t->frame_w-w)/2, TITLE_HEIGHT/2-offset, t->name, titlelength ); if( Scr.d_depth<2 && !on_off ){ xgcv.function = GXor; mask = GCFunction; XChangeGC( dpy, Scr.BlackGC, mask, &xgcv ); XSetFillStyle( dpy, Scr.BlackGC, FillTiled ); XFillRectangle( dpy, t->title_w, Scr.BlackGC, (t->frame_w-w)/2, 1, w, TITLE_HEIGHT-2 ); XSetFillStyle( dpy, Scr.BlackGC, FillSolid ); xgcv.function = GXcopy; XChangeGC( dpy, Scr.BlackGC, mask, &xgcv ); } } void DrawArrow( Window w, int direction, GC color ) { XPoint arrow_p[] = { {9,3},{2,10},{6,10},{6,15},{12,15},{12,10},{16,10},{9,3}, {0,0}}, arrow_p8[] = {{15,11},{9,5},{3,11},{15,11}, {0,0}}; XPoint *use_p; int lp, JunkX, point; if( Scr.flags&SYSTEM8 ) use_p = arrow_p8; else use_p = arrow_p; for( point=0; use_p[point].x!=0; point++ ){ use_p[point].x = use_p[point].x*SBAR_WH/19.+0.5; use_p[point].y = use_p[point].y*SBAR_WH/19.+0.5; } if( direction==C_SBAR_LEFT || direction==C_SBAR_RIGHT ){ for( lp=0; lpscroll_h[3]; size = t->frame_w-t->win_w; } if( context==C_SBAR_V_AN ){ win = t->scroll_v[3]; size = t->frame_h-t->win_h; } if( on_off ){ if( t->flags&SCROLL && size<0 ){ mask = GCForeground; if( !XGetGCValues( dpy, Scr.flags&SYSTEM8? Scr.ScrollBlueGC:Scr.Gray4GC, mask, &xgcv ) ){ fprintf( stderr, "Sorry Can not get GC Values 4\n"); xgcv.foreground = WhitePixel( dpy, Scr.screen ); } attributes.background_pixel = xgcv.foreground; attributes.cursor = Scr.MlvwmCursors[DEFAULT]; valuemask = CWBackPixel | CWCursor; valuemask = CWBackPixel; XChangeWindowAttributes( dpy, win, valuemask, &attributes ); XClearWindow( dpy, win ); DrawShadowBox( 0, 0, SBAR_WH, SBAR_WH, win, 1, Scr.WhiteGC, Scr.Gray2GC, SHADOW_ALL ); scale = 11*SBAR_WH/19.+0.5; if( context==C_SBAR_H_AN ){ for( lp=0; lp<(SBAR_WH-6)/3; lp++ ) DrawShadowBox( (lp+1)*3, (SBAR_WH-scale)/2+1, 3, scale, win, 1, Scr.WhiteGC, Scr.BlackGC, SHADOW_ALL ); } if( context==C_SBAR_V_AN ){ scale = 11*SBAR_WH/19.+0.5; for( lp=0; lp<(SBAR_WH-6)/3; lp++ ) DrawShadowBox( (SBAR_WH-scale)/2, (lp+1)*3, scale, 3, win, 1, Scr.WhiteGC, Scr.BlackGC, SHADOW_ALL ); } } else{ mask = GCForeground; if( !XGetGCValues( dpy, Scr.Gray4GC, mask, &xgcv ) ){ fprintf( stderr, "Sorry Can not get GC Values 4\n"); xgcv.foreground = WhitePixel( dpy, Scr.screen ); } attributes.background_pixel = xgcv.foreground; attributes.cursor = Scr.MlvwmCursors[DEFAULT]; valuemask = CWBackPixel | CWCursor; XChangeWindowAttributes(dpy, win, valuemask, &attributes); XClearWindow( dpy, win ); } } else{ attributes.background_pixel = WhitePixel( dpy, Scr.screen ); attributes.cursor = Scr.MlvwmCursors[DEFAULT]; valuemask = CWBackPixel | CWCursor; XChangeWindowAttributes(dpy, win, valuemask, &attributes); XClearWindow( dpy, win ); } } void DrawSbarArrow( MlvwmWindow *t, int context, Bool on_off ) { int size; unsigned int mask, valuemask; Window win; XGCValues xgcv; XSetWindowAttributes attributes; Cursor cursor; switch( context ){ case C_SBAR_UP: win = t->scroll_v[1]; size = t->frame_h-t->win_h; cursor = Scr.MlvwmCursors[SBARV_CURSOR]; break; case C_SBAR_DOWN: win = t->scroll_v[2]; size = t->frame_h-t->win_h; cursor = Scr.MlvwmCursors[SBARV_CURSOR]; break; case C_SBAR_LEFT: win = t->scroll_h[1]; size = t->frame_w-t->win_w; cursor = Scr.MlvwmCursors[SBARH_CURSOR]; break; case C_SBAR_RIGHT: win = t->scroll_h[2]; size = t->frame_w-t->win_w; cursor = Scr.MlvwmCursors[SBARH_CURSOR]; break; } if( on_off ){ mask = GCForeground; if( !XGetGCValues( dpy, Scr.Gray4GC, mask, &xgcv ) ){ fprintf( stderr, "Sorry Can not get GC Values 4\n"); xgcv.foreground = WhitePixel( dpy, Scr.screen ); } attributes.background_pixel = xgcv.foreground; if( t->flags&SCROLL && size<0 ) attributes.cursor = cursor; else attributes.cursor = Scr.MlvwmCursors[DEFAULT]; valuemask = CWBackPixel | CWCursor; XChangeWindowAttributes( dpy, win, valuemask, &attributes ); XClearWindow( dpy, win ); if( t->flags&SCROLL && size<0 ) DrawShadowBox( 0, 0, SBAR_WH, SBAR_WH, win, 1, Scr.WhiteGC, Scr.Gray2GC, SHADOW_ALL ); DrawArrow( win, context, Scr.Gray3GC ); } else{ mask = GCForeground; attributes.background_pixel = WhitePixel( dpy, Scr.screen ); attributes.cursor = Scr.MlvwmCursors[DEFAULT]; valuemask = CWBackPixel | CWCursor; XChangeWindowAttributes( dpy, win, valuemask, &attributes ); XClearWindow( dpy, win ); } } void DrawSbarBar( MlvwmWindow *t, int context, Bool on_off ) { unsigned long mask, valuemask; XSetWindowAttributes attributes; XWindowAttributes winattrs; XGCValues xgcv; Window win; int x, y, width_f, height_f, width, height, size, mesh_w, mesh_h; char *mesh; if( context==C_SBAR_H ) win = t->scroll_h[0]; if( context==C_SBAR_V ) win = t->scroll_v[0]; XSetWindowBackgroundPixmap( dpy, win, None ); XGetWindowAttributes(dpy, win, &winattrs); if( context==C_SBAR_H ){ size = t->frame_w-t->win_w; x = SBAR_WH+1; y = 0; width_f = winattrs.width; height_f = SBAR_WH; width = winattrs.width-SBAR_WH*2-2; height = SBAR_WH; mesh = mesh_bits_h; mesh_w = 2; mesh_h = 4; } if( context==C_SBAR_V ){ size = t->frame_h-t->win_h; x = 0; y = SBAR_WH+1; width_f = SBAR_WH; height_f = winattrs.height; width = SBAR_WH; height = winattrs.height-SBAR_WH*2-2; mesh = mesh_bits_v; mesh_w = 4; mesh_h = 2; } if( on_off ){ if( t->flags&SCROLL && size<0 ){ if( Scr.flags&SYSTEM8 ){ Pixmap bgpix; bgpix = XCreatePixmap( dpy, Scr.Root, width_f, height_f, Scr.d_depth ); XFillRectangle(dpy,bgpix,Scr.Gray3GC,0,0,width_f,height_f); DrawShadowBox( x, y, width, height, bgpix, 1, Scr.Gray2GC, Scr.WhiteGC, SHADOW_ALL ); XSetWindowBackgroundPixmap( dpy, win, bgpix ); XFreePixmap( dpy, bgpix ); } else{ XSetWindowBackgroundPixmap( dpy, win, XCreatePixmapFromBitmapData( dpy, Scr.Root, mesh, mesh_w, mesh_h, BlackPixel(dpy,Scr.screen), WhitePixel(dpy,Scr.screen), Scr.d_depth )); } XClearWindow( dpy, win ); } else{ mask = GCForeground; if( !XGetGCValues( dpy, Scr.Gray4GC, mask, &xgcv ) ){ fprintf( stderr, "Sorry Can not get GC Values 4\n"); xgcv.foreground = WhitePixel( dpy, Scr.screen ); } attributes.background_pixel = xgcv.foreground; attributes.cursor = Scr.MlvwmCursors[DEFAULT]; valuemask = CWBackPixel | CWCursor; XChangeWindowAttributes( dpy, win, valuemask, &attributes ); XClearWindow( dpy, win ); } if( context==C_SBAR_V ){ XDrawLine(dpy, win, Scr.BlackGC, x, y-1, width, y-1); XDrawLine(dpy, win, Scr.BlackGC, x, y+height, width, y+height); } if( context==C_SBAR_H ){ XDrawLine(dpy, win, Scr.BlackGC, x-1, y, x-1, height); XDrawLine(dpy, win, Scr.BlackGC, x+width, y, x+width, height); } } else{ mask = GCForeground; attributes.background_pixel = WhitePixel( dpy, Scr.screen ); attributes.cursor = Scr.MlvwmCursors[DEFAULT]; valuemask = CWBackPixel | CWCursor; XChangeWindowAttributes( dpy, win, valuemask, &attributes ); XClearWindow( dpy, win ); } } void DrawFrameShadow( MlvwmWindow *t, Bool on ) { XSegment lines[4]; int lp; unsigned long valuemask; XSetWindowAttributes attributes; if( on ) attributes.cursor = Scr.MlvwmCursors[TITLE_CURSOR]; else attributes.cursor = Scr.MlvwmCursors[DEFAULT]; valuemask = CWCursor; XChangeWindowAttributes( dpy, t->frame, valuemask, &attributes ); if( t->flags&( TITLE | SBARV | SBARH | RESIZER )){ for( lp=0; lp<2; lp++ ) SetSegment(0,t->frame_w,t->frame_h-lp-1, t->frame_h-lp-1,lines+lp); for( lp=0; lp<2; lp++ ) SetSegment(t->frame_w-lp-1,t->frame_w-lp-1,0, t->frame_h,lines+lp+2); XDrawSegments( dpy, t->frame, Scr.BlackGC, lines, 4 ); if( Scr.flags&SYSTEM8 ){ if( on ){ DrawShadowBox( 0, 0, t->frame_w-2, t->frame_h-2, t->frame, 5, Scr.WhiteGC, Scr.WhiteGC, SHADOW_LEFT|SHADOW_BOTTOM|SHADOW_RIGHT ); DrawShadowBox( 0, 0, t->frame_w-2, t->frame_h-2, t->frame, 2, Scr.WhiteGC, Scr.Gray3GC, SHADOW_LEFT|SHADOW_BOTTOM|SHADOW_RIGHT ); DrawShadowBox( 2, 0, t->frame_w-6, t->frame_h-4, t->frame, 2, Scr.Gray4GC, Scr.Gray4GC, SHADOW_LEFT|SHADOW_BOTTOM|SHADOW_RIGHT ); XDrawLine( dpy, t->frame, Scr.Gray2GC, 4, 0, 4, t->frame_h-7 ); DrawShadowBox( t->frame_w-SBAR_WH-8, t->frame_h-SBAR_WH-8, SBAR_WH+1, SBAR_WH+1, t->frame, 1, Scr.WhiteGC, Scr.Gray4GC, SHADOW_LEFT|SHADOW_TOP ); } else{ DrawShadowBox( 0, 0, t->frame_w-2, t->frame_h-2, t->frame, 5, Scr.Gray4GC, Scr.Gray4GC, SHADOW_ALL ); DrawShadowBox( t->frame_w-SBAR_WH-8, t->frame_h-SBAR_WH-8, SBAR_WH+1, SBAR_WH+1, t->frame, 1, Scr.Gray4GC, Scr.Gray4GC, SHADOW_LEFT|SHADOW_TOP ); } } } else{ DrawShadowBox( 0, 0, t->frame_w, t->frame_h, t->frame, 2, Scr.WhiteGC, Scr.Gray3GC, SHADOW_ALL ); DrawShadowBox( 3, 3, t->frame_w-6, t->frame_h-6, t->frame, 2, Scr.Gray3GC, Scr.WhiteGC, SHADOW_ALL ); if( Scr.flags&SYSTEM8 ) DrawShadowBox( 2, 2, t->frame_w-4, t->frame_h-4, t->frame, 2, Scr.Gray4GC, Scr.Gray4GC, SHADOW_ALL ); } } void DrawResizeBox( MlvwmWindow *t, Bool on_off ) { unsigned long mask, valuemask; XSetWindowAttributes attributes; XGCValues xgcv; int point, scale, lp; mask = GCForeground; if( on_off || Scr.flags&SYSTEM8 ){ if( !XGetGCValues( dpy, Scr.Gray4GC, mask, &xgcv ) ){ fprintf( stderr, "Sorry Can not get GC Values 4\n"); xgcv.foreground = WhitePixel( dpy, Scr.screen ); } attributes.background_pixel = xgcv.foreground; } else attributes.background_pixel = WhitePixel( dpy, Scr.screen ); if( on_off ) attributes.cursor = Scr.MlvwmCursors[RESIZE]; else attributes.cursor = Scr.MlvwmCursors[DEFAULT]; valuemask = CWBackPixel | CWCursor; XChangeWindowAttributes( dpy, t->resize_b, valuemask, &attributes ); XClearWindow( dpy, t->resize_b ); if( on_off ){ if( Scr.flags&SYSTEM8 ){ for(lp=0; lp<3; lp++ ){ XDrawLine( dpy, t->resize_b, Scr.WhiteGC, 2+lp*3, 9+lp*3, 8+lp*3, 3+lp*3 ); XDrawLine( dpy, t->resize_b, Scr.BlackGC, 4+lp*3, 8+lp*3, 9+lp*3, 3+lp*3 ); } } else{ point = 6*SBAR_WH/19.+0.5; scale = 9*SBAR_WH/19.+0.5; DrawShadowBox( point, point, scale, scale, t->resize_b, 1, Scr.WhiteGC, Scr.BlackGC, SHADOW_ALL ); DrawShadowBox( point-1, point-1, scale+2, scale+2, t->resize_b, 1, Scr.BlackGC, Scr.WhiteGC, SHADOW_ALL ); point = 3*SBAR_WH/19.+0.5; scale = 8*SBAR_WH/19.+0.5; XFillRectangle( dpy, t->resize_b, Scr.Gray4GC, point, point, scale, scale ); point = 4*SBAR_WH/19.+0.5; scale = 7*SBAR_WH/19.+0.5; DrawShadowBox( point, point, scale, scale, t->resize_b, 1, Scr.WhiteGC, Scr.BlackGC, SHADOW_ALL ); DrawShadowBox( point-1, point-1, scale+2, scale+2, t->resize_b, 1, Scr.BlackGC, Scr.WhiteGC, SHADOW_ALL ); } } if( Scr.flags&SYSTEM8 && !(t->flags&(SBARV|SBARH)) ){ DrawShadowBox( 0, 0, SBAR_WH, SBAR_WH, t->resize_b, 1, Scr.BlackGC, Scr.BlackGC, SHADOW_TOP|SHADOW_LEFT ); if( on_off ) DrawShadowBox( 1, 1, SBAR_WH-1, SBAR_WH-1, t->resize_b, 1, Scr.WhiteGC, Scr.WhiteGC, SHADOW_TOP|SHADOW_LEFT ); } } void DrawAllDecorations( MlvwmWindow *t, Bool on_off ) { if( t->flags&SBARV ){ DrawSbarBar( t, C_SBAR_V, on_off ); DrawSbarAnk( t, C_SBAR_V_AN, on_off ); DrawSbarArrow( t, C_SBAR_UP, on_off ); DrawSbarArrow( t, C_SBAR_DOWN, on_off ); } if( t->flags&SBARH ){ DrawSbarBar( t, C_SBAR_H, on_off ); DrawSbarAnk( t, C_SBAR_H_AN, on_off ); DrawSbarArrow( t, C_SBAR_LEFT, on_off ); DrawSbarArrow( t, C_SBAR_RIGHT, on_off ); } if( t->flags&RESIZER ) DrawResizeBox( t, on_off ); if( t->flags&TITLE ) SetTitleBar( t, on_off ); if( Scr.flags&SYSTEM8 ) DrawFrameShadow( t, on_off ); XSync( dpy, 0 ); } void SetFocus( MlvwmWindow *t ) { char *str, action[24], *winname; unsigned long mask, valuemask; XSetWindowAttributes attributes; XGCValues xgcv; mask = GCForeground; if( Scr.ActiveWin==t ) return; if( Scr.ActiveWin ){ DrawAllDecorations( Scr.ActiveWin, False ); if( Scr.ActiveWin->flags&(SBARV|SBARH) && !(Scr.ActiveWin->flags&RESIZER) && !(Scr.flags&SYSTEM8) ){ attributes.background_pixel = WhitePixel( dpy, Scr.screen ); valuemask = CWBackPixel; XChangeWindowAttributes( dpy, Scr.ActiveWin->frame, valuemask, &attributes ); XClearArea( dpy, Scr.ActiveWin->frame, Scr.ActiveWin->frame_w-2-SBAR_WH, Scr.ActiveWin->frame_h-2-SBAR_WH, SBAR_WH, SBAR_WH, False ); } if( !(Scr.flags&FOLLOWTOMOUSE) ){ XSync(dpy,0); XGrabButton(dpy, AnyButton, AnyModifier, Scr.ActiveWin->frame, True, ButtonPressMask, GrabModeSync,GrabModeAsync,None, Scr.MlvwmCursors[DEFAULT]); } winname = WinListName( Scr.ActiveWin ); sprintf( action, "Select %lX", (unsigned long)Scr.ActiveWin ); ChangeMenuItemLabel( "ICON", winname, winname, action, ~CHECKON, M_AND ); free( winname ); } Scr.ActiveWin=t; MapMenuBar( Scr.ActiveWin ); if( t==NULL || t->flags&TRANSIENT ){ ChangeMenuLabel( &(Scr.IconMenu), NULL, Scr.SystemIcon ); ChangeMenuItemLabel( "ICON", Scr.IconMenu.m_item->label, Scr.IconMenu.m_item->label, NULL, STRGRAY, M_COPY); ChangeMenuItemLabel( "ICON", "Hide Others", "Hide Others", NULL, STRGRAY, M_COPY ); XSetInputFocus( dpy, Scr.NoFocusWin, RevertToParent, CurrentTime ); if( t==NULL ) return; } ChangeMenuLabel( &(Scr.IconMenu), NULL, t->miniicon==NULL?Scr.SystemIcon:t->miniicon ); if( !(t->flags&TRANSIENT) ){ str = calloc( strlen(t->name)+6, 1 ); sprintf( str, "Hide %s", t->name ); ChangeMenuItemLabel( "ICON", Scr.IconMenu.m_item->label, str, NULL, SELECTON, M_COPY ); ChangeMenuItemLabel( "ICON", "Hide Others", "Hide Others", NULL, SELECTON, M_COPY ); sprintf( action, "Select %lX", (unsigned long)t ); winname = WinListName( t ); ChangeMenuItemLabel( "ICON", winname, winname, action, SELECTON|CHECKON, M_COPY ); free( winname ); free( str ); } DrawAllDecorations( t, True ); if( t->flags&(SBARV|SBARH) && !(t->flags&RESIZER) ){ if( !XGetGCValues( dpy, Scr.Gray4GC, mask, &xgcv ) ){ fprintf( stderr, "Sorry Can not get GC Values 4\n"); xgcv.foreground = WhitePixel( dpy, Scr.screen ); } attributes.background_pixel = xgcv.foreground; valuemask = CWBackPixel; XChangeWindowAttributes( dpy, t->frame, valuemask, &attributes ); XClearArea( dpy, t->frame, t->frame_w-2-SBAR_WH-1-(Scr.flags&SYSTEM8?6:0), t->frame_h-2-SBAR_WH-1-(Scr.flags&SYSTEM8?6:0), SBAR_WH+(Scr.flags&SYSTEM8?2:0), SBAR_WH+(Scr.flags&SYSTEM8?2:0), False ); } if( !(Scr.flags&FOLLOWTOMOUSE) ) XUngrabButton( dpy, AnyButton, AnyModifier, t->frame ); if( !(t->flags&SHADE) ) XSetInputFocus( dpy, t->w, RevertToParent, CurrentTime ); else XSetInputFocus( dpy, Scr.NoFocusWin, RevertToParent, CurrentTime ); }