10bbfda8aSnia/* 20bbfda8aSnia * Copyright 1988 by Evans & Sutherland Computer Corporation, 30bbfda8aSnia * Salt Lake City, Utah 40bbfda8aSnia * Portions Copyright 1989 by the Massachusetts Institute of Technology 50bbfda8aSnia * Cambridge, Massachusetts 60bbfda8aSnia * 70bbfda8aSnia * Copyright 1992 Claude Lecommandeur. 80bbfda8aSnia */ 90bbfda8aSnia 100bbfda8aSnia/*********************************************************************** 110bbfda8aSnia * 120bbfda8aSnia * $XConsortium: resize.c,v 1.80 91/05/11 17:35:42 dave Exp $ 130bbfda8aSnia * 140bbfda8aSnia * window resizing borrowed from the "wm" window manager 150bbfda8aSnia * 160bbfda8aSnia * 11-Dec-87 Thomas E. LaStrange File created 170bbfda8aSnia * 180bbfda8aSnia * Do the necessary modification to be integrated in ctwm. 190bbfda8aSnia * Can no longer be used for the standard twm. 200bbfda8aSnia * 210bbfda8aSnia * 22-April-92 Claude Lecommandeur. 220bbfda8aSnia * 230bbfda8aSnia * 240bbfda8aSnia ***********************************************************************/ 250bbfda8aSnia 260bbfda8aSnia#include "ctwm.h" 270bbfda8aSnia 280bbfda8aSnia#include <stdio.h> 290bbfda8aSnia#include <stdlib.h> 300bbfda8aSnia 310bbfda8aSnia#include "events.h" 320bbfda8aSnia#include "util.h" 330bbfda8aSnia#include "otp.h" 340bbfda8aSnia#include "functions_defs.h" 350bbfda8aSnia#include "add_window.h" 360bbfda8aSnia#include "colormaps.h" 370bbfda8aSnia#include "screen.h" 380bbfda8aSnia#include "drawing.h" 39b18c2d1eSnia#include "r_area.h" 40b18c2d1eSnia#include "r_area_list.h" 41b18c2d1eSnia#include "r_layout.h" 420bbfda8aSnia#include "win_decorations.h" 430bbfda8aSnia#include "win_ops.h" 440bbfda8aSnia#include "win_resize.h" 450bbfda8aSnia#include "win_utils.h" 460bbfda8aSnia#include "workspace_manager.h" 470bbfda8aSnia#include "iconmgr.h" 480bbfda8aSnia 490bbfda8aSnia#define MINHEIGHT 0 /* had been 32 */ 500bbfda8aSnia#define MINWIDTH 0 /* had been 60 */ 510bbfda8aSnia 520bbfda8aSniastatic int dragx; /* all these variables are used */ 530bbfda8aSniastatic int dragy; /* in resize operations */ 540bbfda8aSniastatic unsigned int dragWidth; 550bbfda8aSniastatic unsigned int dragHeight; 560bbfda8aSnia 570bbfda8aSniastatic int origx; 580bbfda8aSniastatic int origy; 590bbfda8aSniastatic int origWidth; 600bbfda8aSniastatic int origHeight; 610bbfda8aSnia 620bbfda8aSniastatic int clampTop; 630bbfda8aSniastatic int clampBottom; 640bbfda8aSniastatic int clampLeft; 650bbfda8aSniastatic int clampRight; 660bbfda8aSniastatic int clampDX; 670bbfda8aSniastatic int clampDY; 680bbfda8aSnia 690bbfda8aSniastatic int last_width; 700bbfda8aSniastatic int last_height; 710bbfda8aSnia 720bbfda8aSniastatic unsigned int resizeGrabMask; 730bbfda8aSnia 740bbfda8aSniastatic void DisplaySize(TwmWindow *tmp_win, int width, int height); 750bbfda8aSnia 760bbfda8aSniastatic void do_auto_clamp(TwmWindow *tmp_win, XEvent *evp) 770bbfda8aSnia{ 780bbfda8aSnia Window junkRoot; 790bbfda8aSnia int x, y, h, v, junkbw; 800bbfda8aSnia unsigned int junkMask; 810bbfda8aSnia 820bbfda8aSnia switch(evp->type) { 830bbfda8aSnia case ButtonPress: 840bbfda8aSnia x = evp->xbutton.x_root; 850bbfda8aSnia y = evp->xbutton.y_root; 860bbfda8aSnia break; 870bbfda8aSnia case KeyPress: 880bbfda8aSnia x = evp->xkey.x_root; 890bbfda8aSnia y = evp->xkey.y_root; 900bbfda8aSnia break; 910bbfda8aSnia default: 920bbfda8aSnia if(!XQueryPointer(dpy, Scr->Root, &junkRoot, &junkRoot, 930bbfda8aSnia &x, &y, &junkbw, &junkbw, &junkMask)) { 940bbfda8aSnia return; 950bbfda8aSnia } 960bbfda8aSnia } 970bbfda8aSnia 980bbfda8aSnia /* 990bbfda8aSnia * Determine in which of the 9 "quadrants" of the window we are. 1000bbfda8aSnia * Cast the values to signed int: if the numerator is negative 1010bbfda8aSnia * we don't want them converted to unsigned due to the default 1020bbfda8aSnia * promotion rules: that would produce a very large quotient. 1030bbfda8aSnia */ 1040bbfda8aSnia h = (int)(x - dragx) / (int)(dragWidth < 3 ? 1 : (dragWidth / 3)); 1050bbfda8aSnia v = (int)(y - dragy - tmp_win->title_height) / 1060bbfda8aSnia (int)(dragHeight < 3 ? 1 : (dragHeight / 3)); 1070bbfda8aSnia 1080bbfda8aSnia if(h <= 0) { 1090bbfda8aSnia clampLeft = 1; 1100bbfda8aSnia clampDX = (x - dragx); 1110bbfda8aSnia } 1120bbfda8aSnia else if(h >= 2) { 1130bbfda8aSnia clampRight = 1; 1140bbfda8aSnia clampDX = (x - dragx - dragWidth); 1150bbfda8aSnia } 1160bbfda8aSnia 1170bbfda8aSnia if(v <= 0) { 1180bbfda8aSnia clampTop = 1; 1190bbfda8aSnia clampDY = (y - dragy); 1200bbfda8aSnia } 1210bbfda8aSnia else if(v >= 2) { 1220bbfda8aSnia clampBottom = 1; 1230bbfda8aSnia clampDY = (y - dragy - dragHeight); 1240bbfda8aSnia } 1250bbfda8aSnia} 1260bbfda8aSnia 1270bbfda8aSnia/*********************************************************************** 1280bbfda8aSnia * 1290bbfda8aSnia * Procedure: 1300bbfda8aSnia * OpaqueResizeSize - determine if window should be resized opaquely. 1310bbfda8aSnia * 1320bbfda8aSnia * Inputs: 1330bbfda8aSnia * tmp_win - the TwmWindow pointer 1340bbfda8aSnia * 1350bbfda8aSnia *********************************************************************** 1360bbfda8aSnia */ 1370bbfda8aSnia 1380bbfda8aSniavoid OpaqueResizeSize(TwmWindow *tmp_win) 1390bbfda8aSnia{ 1400bbfda8aSnia if(tmp_win->OpaqueResize) { 1410bbfda8aSnia /* 1420bbfda8aSnia * OpaqueResize defaults to a thousand. Assume that any number 1430bbfda8aSnia * >= 1000 is "infinity" and don't bother calculating. 1440bbfda8aSnia */ 1450bbfda8aSnia if(Scr->OpaqueResizeThreshold >= 1000) { 1460bbfda8aSnia Scr->OpaqueResize = true; 1470bbfda8aSnia } 1480bbfda8aSnia else { 1490bbfda8aSnia /* 1500bbfda8aSnia * scrsz will hold the number of pixels in your resolution, 1510bbfda8aSnia * which can get big. [signed] int may not cut it. 1520bbfda8aSnia */ 1530bbfda8aSnia const unsigned long winsz = tmp_win->frame_width 1540bbfda8aSnia * tmp_win->frame_height; 1550bbfda8aSnia const unsigned long scrsz = Scr->rootw * Scr->rooth; 1560bbfda8aSnia if(winsz > (scrsz * (Scr->OpaqueResizeThreshold / 100.0))) { 1570bbfda8aSnia Scr->OpaqueResize = false; 1580bbfda8aSnia } 1590bbfda8aSnia else { 1600bbfda8aSnia Scr->OpaqueResize = true; 1610bbfda8aSnia } 1620bbfda8aSnia } 1630bbfda8aSnia } 1640bbfda8aSnia else { 1650bbfda8aSnia Scr->OpaqueResize = false; 1660bbfda8aSnia } 1670bbfda8aSnia} 1680bbfda8aSnia 1690bbfda8aSnia 1700bbfda8aSnia/*********************************************************************** 1710bbfda8aSnia * 1720bbfda8aSnia * Procedure: 1730bbfda8aSnia * StartResize - begin a window resize operation 1740bbfda8aSnia * 1750bbfda8aSnia * Inputs: 1760bbfda8aSnia * ev - the event structure (button press) 1770bbfda8aSnia * tmp_win - the TwmWindow pointer 1780bbfda8aSnia * fromtitlebar - action invoked from titlebar button 1790bbfda8aSnia * 1800bbfda8aSnia *********************************************************************** 1810bbfda8aSnia */ 1820bbfda8aSnia 1830bbfda8aSniavoid StartResize(XEvent *evp, TwmWindow *tmp_win, 1840bbfda8aSnia bool fromtitlebar, bool from3dborder) 1850bbfda8aSnia{ 1860bbfda8aSnia Window junkRoot, grabwin; 1870bbfda8aSnia unsigned int junkbw, junkDepth; 1880bbfda8aSnia Cursor cursor; 1890bbfda8aSnia 1900bbfda8aSnia cursor = (Scr->BorderCursors 1910bbfda8aSnia && tmp_win->curcurs) ? tmp_win->curcurs : Scr->ResizeCursor; 1920bbfda8aSnia ResizeWindow = tmp_win->frame; 1930bbfda8aSnia if(! Scr->OpaqueResize || resizeWhenAdd) { 1940bbfda8aSnia XGrabServer(dpy); 1950bbfda8aSnia } 1960bbfda8aSnia resizeGrabMask = ButtonPressMask | ButtonReleaseMask | 1970bbfda8aSnia ButtonMotionMask | PointerMotionHintMask; 1980bbfda8aSnia 1990bbfda8aSnia grabwin = Scr->Root; 200b18c2d1eSnia#ifdef WINBOX 2010bbfda8aSnia if(tmp_win->winbox) { 2020bbfda8aSnia grabwin = tmp_win->winbox->window; 2030bbfda8aSnia } 204b18c2d1eSnia#endif 2050bbfda8aSnia XGrabPointer(dpy, grabwin, True, resizeGrabMask, 2060bbfda8aSnia GrabModeAsync, GrabModeAsync, grabwin, cursor, CurrentTime); 2070bbfda8aSnia 2080bbfda8aSnia XGetGeometry(dpy, (Drawable) tmp_win->frame, &junkRoot, 2090bbfda8aSnia &dragx, &dragy, &dragWidth, &dragHeight, &junkbw, 2100bbfda8aSnia &junkDepth); 2110bbfda8aSnia dragx += tmp_win->frame_bw; 2120bbfda8aSnia dragy += tmp_win->frame_bw; 2130bbfda8aSnia origx = dragx; 2140bbfda8aSnia origy = dragy; 2150bbfda8aSnia origWidth = dragWidth; 2160bbfda8aSnia origHeight = dragHeight; 2170bbfda8aSnia clampTop = clampBottom = clampLeft = clampRight = clampDX = clampDY = 0; 2180bbfda8aSnia 2190bbfda8aSnia if(Scr->AutoRelativeResize && (from3dborder || !fromtitlebar)) { 2200bbfda8aSnia do_auto_clamp(tmp_win, evp); 2210bbfda8aSnia } 2220bbfda8aSnia 2230bbfda8aSnia Scr->SizeStringOffset = SIZE_HINDENT; 224b18c2d1eSnia MoveResizeSizeWindow(evp->xbutton.x_root, evp->xbutton.y_root, 225b18c2d1eSnia Scr->SizeStringWidth + SIZE_HINDENT * 2, 226b18c2d1eSnia Scr->SizeFont.height + SIZE_VINDENT * 2); 2270bbfda8aSnia XMapRaised(dpy, Scr->SizeWindow); 2280bbfda8aSnia InstallRootColormap(); 2290bbfda8aSnia last_width = 0; 2300bbfda8aSnia last_height = 0; 2310bbfda8aSnia DisplaySize(tmp_win, origWidth, origHeight); 2320bbfda8aSnia 2330bbfda8aSnia if(! Scr->OpaqueResize || resizeWhenAdd) 2340bbfda8aSnia MoveOutline(Scr->Root, dragx - tmp_win->frame_bw, 2350bbfda8aSnia dragy - tmp_win->frame_bw, dragWidth + 2 * tmp_win->frame_bw, 2360bbfda8aSnia dragHeight + 2 * tmp_win->frame_bw, 2370bbfda8aSnia tmp_win->frame_bw, tmp_win->title_height + tmp_win->frame_bw3D); 2380bbfda8aSnia} 2390bbfda8aSnia 2400bbfda8aSnia 2410bbfda8aSniavoid MenuStartResize(TwmWindow *tmp_win, int x, int y, int w, int h) 2420bbfda8aSnia{ 2430bbfda8aSnia if(! Scr->OpaqueResize) { 2440bbfda8aSnia XGrabServer(dpy); 2450bbfda8aSnia } 2460bbfda8aSnia resizeGrabMask = ButtonPressMask | ButtonMotionMask | PointerMotionMask; 2470bbfda8aSnia XGrabPointer(dpy, Scr->Root, True, resizeGrabMask, 2480bbfda8aSnia GrabModeAsync, GrabModeAsync, 2490bbfda8aSnia Scr->Root, Scr->ResizeCursor, CurrentTime); 2500bbfda8aSnia dragx = x + tmp_win->frame_bw; 2510bbfda8aSnia dragy = y + tmp_win->frame_bw; 2520bbfda8aSnia origx = dragx; 2530bbfda8aSnia origy = dragy; 2540bbfda8aSnia dragWidth = origWidth = w; 2550bbfda8aSnia dragHeight = origHeight = h; 2560bbfda8aSnia clampTop = clampBottom = clampLeft = clampRight = clampDX = clampDY = 0; 2570bbfda8aSnia last_width = 0; 2580bbfda8aSnia last_height = 0; 2590bbfda8aSnia Scr->SizeStringOffset = SIZE_HINDENT; 260b18c2d1eSnia MoveResizeSizeWindow(dragx, dragy, 261b18c2d1eSnia Scr->SizeStringWidth + SIZE_HINDENT * 2, 262b18c2d1eSnia Scr->SizeFont.height + SIZE_VINDENT * 2); 2630bbfda8aSnia XMapRaised(dpy, Scr->SizeWindow); 2640bbfda8aSnia DisplaySize(tmp_win, origWidth, origHeight); 2650bbfda8aSnia if(! Scr->OpaqueResize) 2660bbfda8aSnia MoveOutline(Scr->Root, dragx - tmp_win->frame_bw, 2670bbfda8aSnia dragy - tmp_win->frame_bw, 2680bbfda8aSnia dragWidth + 2 * tmp_win->frame_bw, 2690bbfda8aSnia dragHeight + 2 * tmp_win->frame_bw, 2700bbfda8aSnia tmp_win->frame_bw, tmp_win->title_height + tmp_win->frame_bw3D); 2710bbfda8aSnia} 2720bbfda8aSnia 2730bbfda8aSnia/*********************************************************************** 2740bbfda8aSnia * 2750bbfda8aSnia * Procedure: 2760bbfda8aSnia * AddStartResize - begin a windorew resize operation from AddWindow 2770bbfda8aSnia * 2780bbfda8aSnia * Inputs: 2790bbfda8aSnia * tmp_win - the TwmWindow pointer 2800bbfda8aSnia * 2810bbfda8aSnia *********************************************************************** 2820bbfda8aSnia */ 2830bbfda8aSnia 2840bbfda8aSniavoid AddStartResize(TwmWindow *tmp_win, int x, int y, int w, int h) 2850bbfda8aSnia{ 2860bbfda8aSnia XGrabServer(dpy); 2870bbfda8aSnia resizeGrabMask = ButtonReleaseMask | ButtonMotionMask | PointerMotionHintMask; 2880bbfda8aSnia XGrabPointer(dpy, Scr->Root, True, resizeGrabMask, 2890bbfda8aSnia GrabModeAsync, GrabModeAsync, 2900bbfda8aSnia Scr->Root, Scr->ResizeCursor, CurrentTime); 2910bbfda8aSnia 2920bbfda8aSnia dragx = x + tmp_win->frame_bw; 2930bbfda8aSnia dragy = y + tmp_win->frame_bw; 2940bbfda8aSnia origx = dragx; 2950bbfda8aSnia origy = dragy; 2960bbfda8aSnia dragWidth = origWidth = w - 2 * tmp_win->frame_bw; 2970bbfda8aSnia dragHeight = origHeight = h - 2 * tmp_win->frame_bw; 2980bbfda8aSnia clampTop = clampBottom = clampLeft = clampRight = clampDX = clampDY = 0; 2990bbfda8aSnia last_width = 0; 3000bbfda8aSnia last_height = 0; 3010bbfda8aSnia DisplaySize(tmp_win, origWidth, origHeight); 3020bbfda8aSnia} 3030bbfda8aSnia 3040bbfda8aSnia 3050bbfda8aSniavoid MenuDoResize(int x_root, int y_root, TwmWindow *tmp_win) 3060bbfda8aSnia{ 3070bbfda8aSnia int action; 3080bbfda8aSnia Cursor cursor = 0; 3090bbfda8aSnia 3100bbfda8aSnia action = 0; 3110bbfda8aSnia 3120bbfda8aSnia x_root -= clampDX; 3130bbfda8aSnia y_root -= clampDY; 3140bbfda8aSnia 3150bbfda8aSnia if(clampTop) { 3160bbfda8aSnia int delta = y_root - dragy; 3170bbfda8aSnia if((int)(dragHeight - delta) < MINHEIGHT) { 3180bbfda8aSnia delta = dragHeight - MINHEIGHT; 3190bbfda8aSnia clampTop = 0; 3200bbfda8aSnia } 3210bbfda8aSnia dragy += delta; 3220bbfda8aSnia dragHeight -= delta; 3230bbfda8aSnia action = 1; 3240bbfda8aSnia cursor = TopCursor; 3250bbfda8aSnia } 3260bbfda8aSnia else if(y_root <= dragy) { 3270bbfda8aSnia dragy = y_root; 3280bbfda8aSnia dragHeight = origy + origHeight - 3290bbfda8aSnia y_root; 3300bbfda8aSnia clampBottom = 0; 3310bbfda8aSnia clampTop = 1; 3320bbfda8aSnia clampDY = 0; 3330bbfda8aSnia action = 1; 3340bbfda8aSnia cursor = TopCursor; 3350bbfda8aSnia } 3360bbfda8aSnia if(clampLeft) { 3370bbfda8aSnia int delta = x_root - dragx; 3380bbfda8aSnia if((int)(dragWidth - delta) < MINWIDTH) { 3390bbfda8aSnia delta = dragWidth - MINWIDTH; 3400bbfda8aSnia clampLeft = 0; 3410bbfda8aSnia } 3420bbfda8aSnia dragx += delta; 3430bbfda8aSnia dragWidth -= delta; 3440bbfda8aSnia action = 1; 3450bbfda8aSnia cursor = clampTop ? TopLeftCursor : LeftCursor; 3460bbfda8aSnia } 3470bbfda8aSnia else if(x_root <= dragx) { 3480bbfda8aSnia dragx = x_root; 3490bbfda8aSnia dragWidth = origx + origWidth - 3500bbfda8aSnia x_root; 3510bbfda8aSnia clampRight = 0; 3520bbfda8aSnia clampLeft = 1; 3530bbfda8aSnia clampDX = 0; 3540bbfda8aSnia action = 1; 3550bbfda8aSnia cursor = clampTop ? TopLeftCursor : LeftCursor; 3560bbfda8aSnia } 3570bbfda8aSnia if(clampBottom) { 3580bbfda8aSnia int delta = y_root - dragy - dragHeight; 3590bbfda8aSnia if((int)(dragHeight + delta) < MINHEIGHT) { 3600bbfda8aSnia delta = MINHEIGHT - dragHeight; 3610bbfda8aSnia clampBottom = 0; 3620bbfda8aSnia } 3630bbfda8aSnia dragHeight += delta; 3640bbfda8aSnia action = 1; 3650bbfda8aSnia cursor = clampLeft ? BottomLeftCursor : BottomCursor; 3660bbfda8aSnia } 3670bbfda8aSnia else if(y_root >= dragy + dragHeight) { 3680bbfda8aSnia dragy = origy; 3690bbfda8aSnia dragHeight = 1 + y_root - dragy; 3700bbfda8aSnia clampTop = 0; 3710bbfda8aSnia clampBottom = 1; 3720bbfda8aSnia clampDY = 0; 3730bbfda8aSnia action = 1; 3740bbfda8aSnia cursor = clampLeft ? BottomLeftCursor : BottomCursor; 3750bbfda8aSnia } 3760bbfda8aSnia if(clampRight) { 3770bbfda8aSnia int delta = x_root - dragx - dragWidth; 3780bbfda8aSnia if((int)(dragWidth + delta) < MINWIDTH) { 3790bbfda8aSnia delta = MINWIDTH - dragWidth; 3800bbfda8aSnia clampRight = 0; 3810bbfda8aSnia } 3820bbfda8aSnia dragWidth += delta; 3830bbfda8aSnia action = 1; 3840bbfda8aSnia cursor = clampBottom ? BottomRightCursor : RightCursor; 3850bbfda8aSnia cursor = clampTop ? TopRightCursor : cursor; 3860bbfda8aSnia } 3870bbfda8aSnia else if(x_root >= dragx + dragWidth) { 3880bbfda8aSnia dragx = origx; 3890bbfda8aSnia dragWidth = 1 + x_root - origx; 3900bbfda8aSnia clampLeft = 0; 3910bbfda8aSnia clampRight = 1; 3920bbfda8aSnia clampDX = 0; 3930bbfda8aSnia action = 1; 3940bbfda8aSnia cursor = clampBottom ? BottomRightCursor : RightCursor; 3950bbfda8aSnia cursor = clampTop ? TopRightCursor : cursor; 3960bbfda8aSnia } 3970bbfda8aSnia 3980bbfda8aSnia if(action) { 3990bbfda8aSnia ConstrainSize(tmp_win, &dragWidth, &dragHeight); 4000bbfda8aSnia if(clampLeft) { 4010bbfda8aSnia dragx = origx + origWidth - dragWidth; 4020bbfda8aSnia } 4030bbfda8aSnia if(clampTop) { 4040bbfda8aSnia dragy = origy + origHeight - dragHeight; 4050bbfda8aSnia } 4060bbfda8aSnia if(Scr->OpaqueResize) 4070bbfda8aSnia SetupWindow(tmp_win, dragx - tmp_win->frame_bw, dragy - tmp_win->frame_bw, 4080bbfda8aSnia dragWidth, dragHeight, -1); 4090bbfda8aSnia else 4100bbfda8aSnia MoveOutline(Scr->Root, 4110bbfda8aSnia dragx - tmp_win->frame_bw, 4120bbfda8aSnia dragy - tmp_win->frame_bw, 4130bbfda8aSnia dragWidth + 2 * tmp_win->frame_bw, 4140bbfda8aSnia dragHeight + 2 * tmp_win->frame_bw, 4150bbfda8aSnia tmp_win->frame_bw, tmp_win->title_height + tmp_win->frame_bw3D); 4160bbfda8aSnia if(Scr->BorderCursors && (cursor != tmp_win->curcurs)) { 4170bbfda8aSnia tmp_win->curcurs = cursor; 4180bbfda8aSnia XChangeActivePointerGrab(dpy, resizeGrabMask, cursor, CurrentTime); 4190bbfda8aSnia } 4200bbfda8aSnia } 4210bbfda8aSnia 4220bbfda8aSnia DisplaySize(tmp_win, dragWidth, dragHeight); 4230bbfda8aSnia} 4240bbfda8aSnia 4250bbfda8aSnia/*********************************************************************** 4260bbfda8aSnia * 4270bbfda8aSnia * Procedure: 4280bbfda8aSnia * DoResize - move the rubberband around. This is called for 4290bbfda8aSnia * each motion event when we are resizing 4300bbfda8aSnia * 4310bbfda8aSnia * Inputs: 4320bbfda8aSnia * x_root - the X corrdinate in the root window 4330bbfda8aSnia * y_root - the Y corrdinate in the root window 4340bbfda8aSnia * tmp_win - the current twm window 4350bbfda8aSnia * 4360bbfda8aSnia *********************************************************************** 4370bbfda8aSnia */ 4380bbfda8aSnia 4390bbfda8aSniavoid DoResize(int x_root, int y_root, TwmWindow *tmp_win) 4400bbfda8aSnia{ 4410bbfda8aSnia int action; 4420bbfda8aSnia Cursor cursor = 0; 4430bbfda8aSnia 4440bbfda8aSnia action = 0; 4450bbfda8aSnia 4460bbfda8aSnia x_root -= clampDX; 4470bbfda8aSnia y_root -= clampDY; 4480bbfda8aSnia 4490bbfda8aSnia if(clampTop) { 4500bbfda8aSnia int delta = y_root - dragy; 4510bbfda8aSnia if((int)(dragHeight - delta) < MINHEIGHT) { 4520bbfda8aSnia delta = dragHeight - MINHEIGHT; 4530bbfda8aSnia clampTop = 0; 4540bbfda8aSnia } 4550bbfda8aSnia dragy += delta; 4560bbfda8aSnia dragHeight -= delta; 4570bbfda8aSnia action = 1; 4580bbfda8aSnia cursor = TopCursor; 4590bbfda8aSnia } 4600bbfda8aSnia else if(y_root <= dragy) { 4610bbfda8aSnia dragy = y_root; 4620bbfda8aSnia dragHeight = origy + origHeight - 4630bbfda8aSnia y_root; 4640bbfda8aSnia clampBottom = 0; 4650bbfda8aSnia clampTop = 1; 4660bbfda8aSnia clampDY = 0; 4670bbfda8aSnia action = 1; 4680bbfda8aSnia cursor = TopCursor; 4690bbfda8aSnia } 4700bbfda8aSnia if(clampLeft) { 4710bbfda8aSnia int delta = x_root - dragx; 4720bbfda8aSnia if((int)(dragWidth - delta) < MINWIDTH) { 4730bbfda8aSnia delta = dragWidth - MINWIDTH; 4740bbfda8aSnia clampLeft = 0; 4750bbfda8aSnia } 4760bbfda8aSnia dragx += delta; 4770bbfda8aSnia dragWidth -= delta; 4780bbfda8aSnia action = 1; 4790bbfda8aSnia cursor = clampTop ? TopLeftCursor : LeftCursor; 4800bbfda8aSnia } 4810bbfda8aSnia else if(x_root <= dragx) { 4820bbfda8aSnia dragx = x_root; 4830bbfda8aSnia dragWidth = origx + origWidth - 4840bbfda8aSnia x_root; 4850bbfda8aSnia clampRight = 0; 4860bbfda8aSnia clampLeft = 1; 4870bbfda8aSnia clampDX = 0; 4880bbfda8aSnia action = 1; 4890bbfda8aSnia cursor = clampTop ? TopLeftCursor : LeftCursor; 4900bbfda8aSnia } 4910bbfda8aSnia if(clampBottom) { 4920bbfda8aSnia int delta = y_root - dragy - dragHeight; 4930bbfda8aSnia if((int)(dragHeight + delta) < MINHEIGHT) { 4940bbfda8aSnia delta = MINHEIGHT - dragHeight; 4950bbfda8aSnia clampBottom = 0; 4960bbfda8aSnia } 4970bbfda8aSnia dragHeight += delta; 4980bbfda8aSnia action = 1; 4990bbfda8aSnia cursor = clampLeft ? BottomLeftCursor : BottomCursor; 5000bbfda8aSnia } 5010bbfda8aSnia else if(y_root >= dragy + dragHeight - 1) { 5020bbfda8aSnia dragy = origy; 5030bbfda8aSnia dragHeight = 1 + y_root - dragy; 5040bbfda8aSnia clampTop = 0; 5050bbfda8aSnia clampBottom = 1; 5060bbfda8aSnia clampDY = 0; 5070bbfda8aSnia action = 1; 5080bbfda8aSnia cursor = clampLeft ? BottomLeftCursor : BottomCursor; 5090bbfda8aSnia } 5100bbfda8aSnia if(clampRight) { 5110bbfda8aSnia int delta = x_root - dragx - dragWidth; 5120bbfda8aSnia if((int)(dragWidth + delta) < MINWIDTH) { 5130bbfda8aSnia delta = MINWIDTH - dragWidth; 5140bbfda8aSnia clampRight = 0; 5150bbfda8aSnia } 5160bbfda8aSnia dragWidth += delta; 5170bbfda8aSnia action = 1; 5180bbfda8aSnia cursor = clampBottom ? BottomRightCursor : RightCursor; 5190bbfda8aSnia cursor = clampTop ? TopRightCursor : cursor; 5200bbfda8aSnia } 5210bbfda8aSnia else if(x_root >= dragx + dragWidth - 1) { 5220bbfda8aSnia dragx = origx; 5230bbfda8aSnia dragWidth = 1 + x_root - origx; 5240bbfda8aSnia clampLeft = 0; 5250bbfda8aSnia clampRight = 1; 5260bbfda8aSnia clampDX = 0; 5270bbfda8aSnia action = 1; 5280bbfda8aSnia cursor = clampBottom ? BottomRightCursor : RightCursor; 5290bbfda8aSnia cursor = clampTop ? TopRightCursor : cursor; 5300bbfda8aSnia } 5310bbfda8aSnia 5320bbfda8aSnia if(action) { 5330bbfda8aSnia ConstrainSize(tmp_win, &dragWidth, &dragHeight); 5340bbfda8aSnia if(clampLeft) { 5350bbfda8aSnia dragx = origx + origWidth - dragWidth; 5360bbfda8aSnia } 5370bbfda8aSnia if(clampTop) { 5380bbfda8aSnia dragy = origy + origHeight - dragHeight; 5390bbfda8aSnia } 5400bbfda8aSnia if(Scr->OpaqueResize && ! resizeWhenAdd) { 5410bbfda8aSnia SetupWindow(tmp_win, dragx - tmp_win->frame_bw, dragy - tmp_win->frame_bw, 5420bbfda8aSnia dragWidth, dragHeight, -1); 5430bbfda8aSnia } 5440bbfda8aSnia else { 5450bbfda8aSnia MoveOutline(Scr->Root, 5460bbfda8aSnia dragx - tmp_win->frame_bw, 5470bbfda8aSnia dragy - tmp_win->frame_bw, 5480bbfda8aSnia dragWidth + 2 * tmp_win->frame_bw, 5490bbfda8aSnia dragHeight + 2 * tmp_win->frame_bw, 5500bbfda8aSnia tmp_win->frame_bw, tmp_win->title_height + tmp_win->frame_bw3D); 5510bbfda8aSnia } 5520bbfda8aSnia if(Scr->BorderCursors && (cursor != tmp_win->curcurs)) { 5530bbfda8aSnia tmp_win->curcurs = cursor; 5540bbfda8aSnia XChangeActivePointerGrab(dpy, resizeGrabMask, cursor, CurrentTime); 5550bbfda8aSnia } 5560bbfda8aSnia } 5570bbfda8aSnia 5580bbfda8aSnia DisplaySize(tmp_win, dragWidth, dragHeight); 5590bbfda8aSnia} 5600bbfda8aSnia 5610bbfda8aSnia/*********************************************************************** 5620bbfda8aSnia * 5630bbfda8aSnia * Procedure: 5640bbfda8aSnia * DisplaySize - display the size in the dimensions window 5650bbfda8aSnia * 5660bbfda8aSnia * Inputs: 5670bbfda8aSnia * tmp_win - the current twm window 5680bbfda8aSnia * width - the width of the rubber band 5690bbfda8aSnia * height - the height of the rubber band 5700bbfda8aSnia * 5710bbfda8aSnia *********************************************************************** 5720bbfda8aSnia */ 5730bbfda8aSnia 5740bbfda8aSniastatic void DisplaySize(TwmWindow *tmp_win, int width, int height) 5750bbfda8aSnia{ 5760bbfda8aSnia char str[100]; 5770bbfda8aSnia int dwidth; 5780bbfda8aSnia int dheight; 5790bbfda8aSnia 5800bbfda8aSnia if(last_width == width && last_height == height) { 5810bbfda8aSnia return; 5820bbfda8aSnia } 5830bbfda8aSnia 5840bbfda8aSnia last_width = width; 5850bbfda8aSnia last_height = height; 5860bbfda8aSnia 5870bbfda8aSnia dheight = height - tmp_win->title_height - 2 * tmp_win->frame_bw3D; 5880bbfda8aSnia dwidth = width - 2 * tmp_win->frame_bw3D; 5890bbfda8aSnia 5900bbfda8aSnia /* 5910bbfda8aSnia * ICCCM says that PMinSize is the default is no PBaseSize is given, 5920bbfda8aSnia * and vice-versa. 5930bbfda8aSnia */ 5940bbfda8aSnia if(tmp_win->hints.flags & (PMinSize | PBaseSize) 5950bbfda8aSnia && tmp_win->hints.flags & PResizeInc) { 5960bbfda8aSnia if(tmp_win->hints.flags & PBaseSize) { 5970bbfda8aSnia dwidth -= tmp_win->hints.base_width; 5980bbfda8aSnia dheight -= tmp_win->hints.base_height; 5990bbfda8aSnia } 6000bbfda8aSnia else { 6010bbfda8aSnia dwidth -= tmp_win->hints.min_width; 6020bbfda8aSnia dheight -= tmp_win->hints.min_height; 6030bbfda8aSnia } 6040bbfda8aSnia } 6050bbfda8aSnia 6060bbfda8aSnia if(tmp_win->hints.flags & PResizeInc) { 6070bbfda8aSnia dwidth /= tmp_win->hints.width_inc; 6080bbfda8aSnia dheight /= tmp_win->hints.height_inc; 6090bbfda8aSnia } 6100bbfda8aSnia 6110bbfda8aSnia sprintf(str, " %4d x %-4d ", dwidth, dheight); 6120bbfda8aSnia XRaiseWindow(dpy, Scr->SizeWindow); 6130bbfda8aSnia 6140bbfda8aSnia Draw3DBorder(Scr->SizeWindow, 0, 0, 6150bbfda8aSnia Scr->SizeStringOffset + Scr->SizeStringWidth + SIZE_HINDENT, 6160bbfda8aSnia Scr->SizeFont.height + SIZE_VINDENT * 2, 6170bbfda8aSnia 2, Scr->DefaultC, off, false, false); 6180bbfda8aSnia 6190bbfda8aSnia FB(Scr->DefaultC.fore, Scr->DefaultC.back); 6200bbfda8aSnia XmbDrawImageString(dpy, Scr->SizeWindow, Scr->SizeFont.font_set, 6210bbfda8aSnia Scr->NormalGC, Scr->SizeStringOffset, 6220bbfda8aSnia Scr->SizeFont.ascent + SIZE_VINDENT, str, 13); 6230bbfda8aSnia} 6240bbfda8aSnia 6250bbfda8aSnia/*********************************************************************** 6260bbfda8aSnia * 6270bbfda8aSnia * Procedure: 6280bbfda8aSnia * EndResize - finish the resize operation 6290bbfda8aSnia * 6300bbfda8aSnia *********************************************************************** 6310bbfda8aSnia */ 6320bbfda8aSnia 6330bbfda8aSniavoid EndResize(void) 6340bbfda8aSnia{ 6350bbfda8aSnia TwmWindow *tmp_win; 6360bbfda8aSnia 6370bbfda8aSnia#ifdef DEBUG 6380bbfda8aSnia fprintf(stderr, "EndResize\n"); 6390bbfda8aSnia#endif 6400bbfda8aSnia 6410bbfda8aSnia MoveOutline(Scr->Root, 0, 0, 0, 0, 0, 0); 6420bbfda8aSnia XUnmapWindow(dpy, Scr->SizeWindow); 6430bbfda8aSnia 6440bbfda8aSnia tmp_win = GetTwmWindow(ResizeWindow); 6450bbfda8aSnia if(!tmp_win) { 6460bbfda8aSnia return; 6470bbfda8aSnia } 6480bbfda8aSnia 6490bbfda8aSnia ConstrainSize(tmp_win, &dragWidth, &dragHeight); 6500bbfda8aSnia 6510bbfda8aSnia if(dragWidth != tmp_win->frame_width || 6520bbfda8aSnia dragHeight != tmp_win->frame_height) { 6530bbfda8aSnia unzoom(tmp_win); 6540bbfda8aSnia } 6550bbfda8aSnia 6560bbfda8aSnia SetupWindow(tmp_win, dragx - tmp_win->frame_bw, dragy - tmp_win->frame_bw, 6570bbfda8aSnia dragWidth, dragHeight, -1); 6580bbfda8aSnia 6590bbfda8aSnia if(tmp_win->isiconmgr) { 6600bbfda8aSnia int ncols = tmp_win->iconmgrp->cur_columns; 6610bbfda8aSnia if(ncols == 0) { 6620bbfda8aSnia ncols = 1; 6630bbfda8aSnia } 6640bbfda8aSnia 6650bbfda8aSnia tmp_win->iconmgrp->width = (int)(((dragWidth - 2 * tmp_win->frame_bw3D) * 6660bbfda8aSnia (long) tmp_win->iconmgrp->columns) 6670bbfda8aSnia / ncols); 6680bbfda8aSnia PackIconManager(tmp_win->iconmgrp); 6690bbfda8aSnia } 6700bbfda8aSnia 6710bbfda8aSnia if(!Scr->NoRaiseResize) { 6720bbfda8aSnia OtpRaise(tmp_win, WinWin); 6730bbfda8aSnia WMapRaise(tmp_win); 6740bbfda8aSnia } 6750bbfda8aSnia 6760bbfda8aSnia UninstallRootColormap(); 6770bbfda8aSnia 6780bbfda8aSnia ResizeWindow = None; 6790bbfda8aSnia} 6800bbfda8aSnia 6810bbfda8aSniavoid MenuEndResize(TwmWindow *tmp_win) 6820bbfda8aSnia{ 6830bbfda8aSnia MoveOutline(Scr->Root, 0, 0, 0, 0, 0, 0); 6840bbfda8aSnia XUnmapWindow(dpy, Scr->SizeWindow); 6850bbfda8aSnia ConstrainSize(tmp_win, &dragWidth, &dragHeight); 6860bbfda8aSnia AddingX = dragx - tmp_win->frame_bw; 6870bbfda8aSnia AddingY = dragy - tmp_win->frame_bw; 6880bbfda8aSnia AddingW = dragWidth; 6890bbfda8aSnia AddingH = dragHeight; 6900bbfda8aSnia SetupWindow(tmp_win, AddingX, AddingY, AddingW, AddingH, -1); 6910bbfda8aSnia} 6920bbfda8aSnia 6930bbfda8aSnia 6940bbfda8aSnia/*********************************************************************** 6950bbfda8aSnia * 6960bbfda8aSnia * Procedure: 6970bbfda8aSnia * AddEndResize - finish the resize operation for AddWindo<w 6980bbfda8aSnia * 6990bbfda8aSnia *********************************************************************** 7000bbfda8aSnia */ 7010bbfda8aSnia 7020bbfda8aSniavoid AddEndResize(TwmWindow *tmp_win) 7030bbfda8aSnia{ 7040bbfda8aSnia 7050bbfda8aSnia#ifdef DEBUG 7060bbfda8aSnia fprintf(stderr, "AddEndResize\n"); 7070bbfda8aSnia#endif 7080bbfda8aSnia 7090bbfda8aSnia ConstrainSize(tmp_win, &dragWidth, &dragHeight); 7100bbfda8aSnia AddingX = dragx; 7110bbfda8aSnia AddingY = dragy; 7120bbfda8aSnia AddingW = dragWidth + (2 * tmp_win->frame_bw); 7130bbfda8aSnia AddingH = dragHeight + (2 * tmp_win->frame_bw); 7140bbfda8aSnia} 7150bbfda8aSnia 7160bbfda8aSnia/*********************************************************************** 7170bbfda8aSnia * 7180bbfda8aSnia * Procedure: 7190bbfda8aSnia * ConstrainSize - adjust the given width and height to account for the 7200bbfda8aSnia * constraints imposed by size hints 7210bbfda8aSnia * 7220bbfda8aSnia * The general algorithm, especially the aspect ratio stuff, is 7230bbfda8aSnia * borrowed from uwm's CheckConsistency routine. 7240bbfda8aSnia * 7250bbfda8aSnia ***********************************************************************/ 7260bbfda8aSnia 7270bbfda8aSniavoid ConstrainSize(TwmWindow *tmp_win, 7280bbfda8aSnia unsigned int *widthp, unsigned int *heightp) 7290bbfda8aSnia{ 7300bbfda8aSnia#define makemult(a,b) ((b==1) ? (a) : (((int)((a)/(b))) * (b)) ) 7310bbfda8aSnia 7320bbfda8aSnia int minWidth, minHeight, maxWidth, maxHeight, xinc, yinc, delta; 7330bbfda8aSnia int baseWidth, baseHeight; 7340bbfda8aSnia int dwidth = *widthp, dheight = *heightp; 7350bbfda8aSnia 7360bbfda8aSnia 7370bbfda8aSnia dwidth -= 2 * tmp_win->frame_bw3D; 7380bbfda8aSnia dheight -= (tmp_win->title_height + 2 * tmp_win->frame_bw3D); 7390bbfda8aSnia 7400bbfda8aSnia if(tmp_win->hints.flags & PMinSize) { 7410bbfda8aSnia minWidth = tmp_win->hints.min_width; 7420bbfda8aSnia minHeight = tmp_win->hints.min_height; 7430bbfda8aSnia } 7440bbfda8aSnia else if(tmp_win->hints.flags & PBaseSize) { 7450bbfda8aSnia minWidth = tmp_win->hints.base_width; 7460bbfda8aSnia minHeight = tmp_win->hints.base_height; 7470bbfda8aSnia } 7480bbfda8aSnia else { 7490bbfda8aSnia minWidth = minHeight = 1; 7500bbfda8aSnia } 7510bbfda8aSnia 7520bbfda8aSnia if(tmp_win->hints.flags & PBaseSize) { 7530bbfda8aSnia baseWidth = tmp_win->hints.base_width; 7540bbfda8aSnia baseHeight = tmp_win->hints.base_height; 7550bbfda8aSnia } 7560bbfda8aSnia else if(tmp_win->hints.flags & PMinSize) { 7570bbfda8aSnia baseWidth = tmp_win->hints.min_width; 7580bbfda8aSnia baseHeight = tmp_win->hints.min_height; 7590bbfda8aSnia } 7600bbfda8aSnia else { 7610bbfda8aSnia baseWidth = baseHeight = 0; 7620bbfda8aSnia } 7630bbfda8aSnia 7640bbfda8aSnia 7650bbfda8aSnia if(tmp_win->hints.flags & PMaxSize) { 766b18c2d1eSnia maxWidth = min(Scr->MaxWindowWidth, tmp_win->hints.max_width); 767b18c2d1eSnia maxHeight = min(Scr->MaxWindowHeight, tmp_win->hints.max_height); 7680bbfda8aSnia } 7690bbfda8aSnia else { 7700bbfda8aSnia maxWidth = Scr->MaxWindowWidth; 7710bbfda8aSnia maxHeight = Scr->MaxWindowHeight; 7720bbfda8aSnia } 7730bbfda8aSnia 7740bbfda8aSnia if(tmp_win->hints.flags & PResizeInc) { 7750bbfda8aSnia xinc = tmp_win->hints.width_inc; 7760bbfda8aSnia yinc = tmp_win->hints.height_inc; 7770bbfda8aSnia if(xinc == 0) { 7780bbfda8aSnia xinc = 1; 7790bbfda8aSnia } 7800bbfda8aSnia if(yinc == 0) { 7810bbfda8aSnia yinc = 1; 7820bbfda8aSnia } 7830bbfda8aSnia } 7840bbfda8aSnia else { 7850bbfda8aSnia xinc = yinc = 1; 7860bbfda8aSnia } 7870bbfda8aSnia 7880bbfda8aSnia /* 7890bbfda8aSnia * First, clamp to min and max values 7900bbfda8aSnia */ 7910bbfda8aSnia if(dwidth < minWidth) { 7920bbfda8aSnia dwidth = minWidth; 7930bbfda8aSnia } 7940bbfda8aSnia if(dheight < minHeight) { 7950bbfda8aSnia dheight = minHeight; 7960bbfda8aSnia } 7970bbfda8aSnia 7980bbfda8aSnia if(dwidth > maxWidth) { 7990bbfda8aSnia dwidth = maxWidth; 8000bbfda8aSnia } 8010bbfda8aSnia if(dheight > maxHeight) { 8020bbfda8aSnia dheight = maxHeight; 8030bbfda8aSnia } 8040bbfda8aSnia 8050bbfda8aSnia 8060bbfda8aSnia /* 8070bbfda8aSnia * Second, fit to base + N * inc 8080bbfda8aSnia */ 8090bbfda8aSnia dwidth = ((dwidth - baseWidth) / xinc * xinc) + baseWidth; 8100bbfda8aSnia dheight = ((dheight - baseHeight) / yinc * yinc) + baseHeight; 8110bbfda8aSnia 8120bbfda8aSnia 8130bbfda8aSnia /* 8140bbfda8aSnia * Third, adjust for aspect ratio 8150bbfda8aSnia */ 8160bbfda8aSnia /* 8170bbfda8aSnia * The math looks like this: 8180bbfda8aSnia * 8190bbfda8aSnia * minAspectX dwidth maxAspectX 8200bbfda8aSnia * ---------- <= ------- <= ---------- 8210bbfda8aSnia * minAspectY dheight maxAspectY 8220bbfda8aSnia * 8230bbfda8aSnia * If that is multiplied out, then the width and height are 8240bbfda8aSnia * invalid in the following situations: 8250bbfda8aSnia * 8260bbfda8aSnia * minAspectX * dheight > minAspectY * dwidth 8270bbfda8aSnia * maxAspectX * dheight < maxAspectY * dwidth 8280bbfda8aSnia * 8290bbfda8aSnia */ 8300bbfda8aSnia 8310bbfda8aSnia if(tmp_win->hints.flags & PAspect) { 8320bbfda8aSnia int minAspectX = tmp_win->hints.min_aspect.x; 8330bbfda8aSnia int minAspectY = tmp_win->hints.min_aspect.y; 8340bbfda8aSnia int maxAspectX = tmp_win->hints.max_aspect.x; 8350bbfda8aSnia int maxAspectY = tmp_win->hints.max_aspect.y; 8360bbfda8aSnia 8370bbfda8aSnia if(minAspectX && minAspectY && maxAspectX && maxAspectY) { 8380bbfda8aSnia if(minAspectX * dheight > minAspectY * dwidth) { 8390bbfda8aSnia delta = makemult(minAspectX * dheight / minAspectY - dwidth, 8400bbfda8aSnia xinc); 8410bbfda8aSnia if(dwidth + delta <= maxWidth) { 8420bbfda8aSnia dwidth += delta; 8430bbfda8aSnia } 8440bbfda8aSnia else { 8450bbfda8aSnia delta = makemult(dheight - dwidth * minAspectY / minAspectX, 8460bbfda8aSnia yinc); 8470bbfda8aSnia if(dheight - delta >= minHeight) { 8480bbfda8aSnia dheight -= delta; 8490bbfda8aSnia } 8500bbfda8aSnia } 8510bbfda8aSnia } 8520bbfda8aSnia 8530bbfda8aSnia if(maxAspectX * dheight < maxAspectY * dwidth) { 8540bbfda8aSnia delta = makemult(dwidth * maxAspectY / maxAspectX - dheight, 8550bbfda8aSnia yinc); 8560bbfda8aSnia if(dheight + delta <= maxHeight) { 8570bbfda8aSnia dheight += delta; 8580bbfda8aSnia } 8590bbfda8aSnia else { 8600bbfda8aSnia delta = makemult(dwidth - maxAspectX * dheight / maxAspectY, 8610bbfda8aSnia xinc); 8620bbfda8aSnia if(dwidth - delta >= minWidth) { 8630bbfda8aSnia dwidth -= delta; 8640bbfda8aSnia } 8650bbfda8aSnia } 8660bbfda8aSnia } 8670bbfda8aSnia } 8680bbfda8aSnia } 8690bbfda8aSnia 8700bbfda8aSnia 8710bbfda8aSnia /* 8720bbfda8aSnia * Fourth, account for border width and title height 8730bbfda8aSnia */ 8740bbfda8aSnia *widthp = dwidth + 2 * tmp_win->frame_bw3D; 8750bbfda8aSnia *heightp = dheight + tmp_win->title_height + 2 * tmp_win->frame_bw3D; 8760bbfda8aSnia} 8770bbfda8aSnia 8780bbfda8aSnia 8790bbfda8aSnia 8800bbfda8aSnia 8810bbfda8aSnia/********************************************************************** 8820bbfda8aSnia * Rutgers mod #1 - rocky. 8830bbfda8aSnia * Procedure: 8840bbfda8aSnia * fullzoom - zooms window to full height of screen or 8850bbfda8aSnia * to full height and width of screen. (Toggles 8860bbfda8aSnia * so that it can undo the zoom - even when switching 8870bbfda8aSnia * between fullzoom and vertical zoom.) 8880bbfda8aSnia * 8890bbfda8aSnia * Inputs: 8900bbfda8aSnia * tmp_win - the TwmWindow pointer 8910bbfda8aSnia * 8920bbfda8aSnia * 8930bbfda8aSnia ********************************************************************** 8940bbfda8aSnia */ 8950bbfda8aSnia 8960bbfda8aSniavoid fullzoom(TwmWindow *tmp_win, int func) 8970bbfda8aSnia{ 8980bbfda8aSnia Window junkRoot; 8990bbfda8aSnia unsigned int junkbw, junkDepth; 9000bbfda8aSnia int tmpX, tmpY, tmpW, tmpH; 9010bbfda8aSnia 9020bbfda8aSnia /* 9030bbfda8aSnia * All our callers [need to] do this, so moving it here saves a few 9040bbfda8aSnia * lines in some places around the calling, and when redundant it 9050bbfda8aSnia * just wastes a comparison, so it's cheap. 9060bbfda8aSnia */ 9070bbfda8aSnia if(tmp_win->squeezed) { 9080bbfda8aSnia XBell(dpy, 0); 9090bbfda8aSnia return; 9100bbfda8aSnia } 9110bbfda8aSnia 9120bbfda8aSnia 9130bbfda8aSnia XGetGeometry(dpy, (Drawable) tmp_win->frame, &junkRoot, 9140bbfda8aSnia &dragx, &dragy, (unsigned int *)&dragWidth, (unsigned int *)&dragHeight, 9150bbfda8aSnia &junkbw, 9160bbfda8aSnia &junkDepth); 9170bbfda8aSnia 9180bbfda8aSnia /* 9190bbfda8aSnia * Guard; if it was already not zoomed, and we're asking to unzoom 9200bbfda8aSnia * it, just finish right away. This saves us work, but also avoids 9210bbfda8aSnia * really bad side effects in some cases. e.g., if we try to 9220bbfda8aSnia * ZOOM_NONE a window that's never been ZOOM'd, tmp_win->save_* will 9230bbfda8aSnia * all be 0, so we'd wind up resizing it to a point. It's possible 9240bbfda8aSnia * for that to happen via e.g. an EWMH message removing a _FULLSCREEN 9250bbfda8aSnia * or similar attribute; that can then call into us telling us not to 9260bbfda8aSnia * zoom, on a window that's never been zoomed. 9270bbfda8aSnia * 9280bbfda8aSnia * This wouldn't protect us if somehow it was zoomed but hadn't set 9290bbfda8aSnia * that data, but I don't see how that can happen. Worry about that 9300bbfda8aSnia * when it does. 9310bbfda8aSnia */ 9320bbfda8aSnia if(func == ZOOM_NONE && tmp_win->zoomed == ZOOM_NONE) { 9330bbfda8aSnia return; 9340bbfda8aSnia } 9350bbfda8aSnia 9360bbfda8aSnia if(tmp_win->zoomed == func) { 9370bbfda8aSnia /* It was already zoomed this way, unzoom it */ 9380bbfda8aSnia dragHeight = tmp_win->save_frame_height; 9390bbfda8aSnia dragWidth = tmp_win->save_frame_width; 9400bbfda8aSnia dragx = tmp_win->save_frame_x; 9410bbfda8aSnia dragy = tmp_win->save_frame_y; 9420bbfda8aSnia 9430bbfda8aSnia unzoom(tmp_win); 9440bbfda8aSnia 9450bbfda8aSnia /* XXX _should_ it be falling through here? */ 9460bbfda8aSnia } 9470bbfda8aSnia else { 948b18c2d1eSnia RLayout *borderedLayout = NULL; 949b18c2d1eSnia RArea area, finalArea = RAreaInvalid(); 950b18c2d1eSnia int frame_bw_times_2; 951b18c2d1eSnia 952b18c2d1eSnia#ifdef WINBOX 953b18c2d1eSnia if(tmp_win->winbox) { 954b18c2d1eSnia XWindowAttributes winattrs; 955b18c2d1eSnia if(XGetWindowAttributes(dpy, tmp_win->winbox->window, &winattrs)) { 956b18c2d1eSnia borderedLayout = RLayoutNew( 957b18c2d1eSnia RAreaListNew(1, 958b18c2d1eSnia RAreaNew(winattrs.x, 959b18c2d1eSnia winattrs.y, 960b18c2d1eSnia winattrs.width, 961b18c2d1eSnia winattrs.height), 962b18c2d1eSnia NULL)); 963b18c2d1eSnia } 964b18c2d1eSnia } 965b18c2d1eSnia#endif 966b18c2d1eSnia if(borderedLayout == NULL) { 967b18c2d1eSnia borderedLayout = Scr->BorderedLayout; 968b18c2d1eSnia } 969b18c2d1eSnia 9700bbfda8aSnia if(tmp_win->zoomed == ZOOM_NONE) { 9710bbfda8aSnia tmp_win->save_frame_x = dragx; 9720bbfda8aSnia tmp_win->save_frame_y = dragy; 9730bbfda8aSnia tmp_win->save_frame_width = dragWidth; 9740bbfda8aSnia tmp_win->save_frame_height = dragHeight; 9750bbfda8aSnia } 9760bbfda8aSnia tmp_win->zoomed = func; 9770bbfda8aSnia 9780bbfda8aSnia frame_bw_times_2 = 2 * tmp_win->frame_bw; 9790bbfda8aSnia 980b18c2d1eSnia area = RAreaNew(dragx, dragy, dragWidth, dragHeight); 981b18c2d1eSnia 9820bbfda8aSnia switch(func) { 9830bbfda8aSnia case ZOOM_NONE: 9840bbfda8aSnia break; 985b18c2d1eSnia case F_XZOOM: 986b18c2d1eSnia finalArea = RLayoutFullVert(borderedLayout, &area); 987b18c2d1eSnia /* fall through */ 9880bbfda8aSnia case F_ZOOM: 989b18c2d1eSnia if(!RAreaIsValid(&finalArea)) { 990b18c2d1eSnia finalArea = RLayoutFullVert1(borderedLayout, &area); 991b18c2d1eSnia } 992b18c2d1eSnia dragy = finalArea.y; 993b18c2d1eSnia dragHeight = finalArea.height - frame_bw_times_2; 9940bbfda8aSnia break; 995b18c2d1eSnia case F_XHORIZOOM: 996b18c2d1eSnia finalArea = RLayoutFullHoriz(borderedLayout, &area); 997b18c2d1eSnia /* fall through */ 9980bbfda8aSnia case F_HORIZOOM: 999b18c2d1eSnia if(!RAreaIsValid(&finalArea)) { 1000b18c2d1eSnia finalArea = RLayoutFullHoriz1(borderedLayout, &area); 1001b18c2d1eSnia } 1002b18c2d1eSnia dragx = finalArea.x; 1003b18c2d1eSnia dragWidth = finalArea.width - frame_bw_times_2; 10040bbfda8aSnia break; 1005b18c2d1eSnia case F_XFULLZOOM: 1006b18c2d1eSnia finalArea = RLayoutFull(borderedLayout, &area); 1007b18c2d1eSnia /* fall through */ 10080bbfda8aSnia case F_FULLZOOM: 1009b18c2d1eSnia if(!RAreaIsValid(&finalArea)) { 1010b18c2d1eSnia finalArea = RLayoutFull1(borderedLayout, &area); 1011b18c2d1eSnia } 1012b18c2d1eSnia dragx = finalArea.x; 1013b18c2d1eSnia dragy = finalArea.y; 1014b18c2d1eSnia dragWidth = finalArea.width - frame_bw_times_2; 1015b18c2d1eSnia dragHeight = finalArea.height - frame_bw_times_2; 1016b18c2d1eSnia break; 1017b18c2d1eSnia case F_XLEFTZOOM: 1018b18c2d1eSnia dragx = RLayoutFindLeftEdge(borderedLayout, &area); 1019b18c2d1eSnia dragWidth += area.x - dragx; 1020b18c2d1eSnia // TODO make it visible if hidden 10210bbfda8aSnia break; 10220bbfda8aSnia case F_LEFTZOOM: 1023b18c2d1eSnia dragx = RLayoutFindMonitorLeftEdge(borderedLayout, &area); 1024b18c2d1eSnia dragWidth += area.x - dragx; 1025b18c2d1eSnia // TODO make it visible if hidden 10260bbfda8aSnia break; 1027b18c2d1eSnia case F_XRIGHTZOOM: { 1028b18c2d1eSnia int limit = RLayoutFindRightEdge(borderedLayout, &area); 1029b18c2d1eSnia dragWidth = limit - area.x + 1 - frame_bw_times_2; 1030b18c2d1eSnia // TODO make it visible if hidden 1031b18c2d1eSnia } 1032b18c2d1eSnia break; 1033b18c2d1eSnia case F_RIGHTZOOM: { 1034b18c2d1eSnia int limit = RLayoutFindMonitorRightEdge(borderedLayout, &area); 1035b18c2d1eSnia dragWidth = limit - area.x + 1 - frame_bw_times_2; 1036b18c2d1eSnia // TODO make it visible if hidden 1037b18c2d1eSnia } 1038b18c2d1eSnia break; 1039b18c2d1eSnia case F_XTOPZOOM: 1040b18c2d1eSnia dragy = RLayoutFindTopEdge(borderedLayout, &area); 1041b18c2d1eSnia dragHeight += area.y - dragy; 1042b18c2d1eSnia // TODO make it visible if hidden 10430bbfda8aSnia break; 10440bbfda8aSnia case F_TOPZOOM: 1045b18c2d1eSnia dragy = RLayoutFindMonitorTopEdge(borderedLayout, &area); 1046b18c2d1eSnia dragHeight += area.y - dragy; 1047b18c2d1eSnia // TODO make it visible if hidden 10480bbfda8aSnia break; 1049b18c2d1eSnia case F_XBOTTOMZOOM: { 1050b18c2d1eSnia int limit = RLayoutFindBottomEdge(borderedLayout, &area); 1051b18c2d1eSnia dragHeight = limit - area.y + 1 - frame_bw_times_2; 1052b18c2d1eSnia // TODO make it visible if hidden 1053b18c2d1eSnia } 1054b18c2d1eSnia break; 1055b18c2d1eSnia case F_BOTTOMZOOM: { 1056b18c2d1eSnia int limit = RLayoutFindMonitorBottomEdge(borderedLayout, &area); 1057b18c2d1eSnia dragHeight = limit - area.y + 1 - frame_bw_times_2; 1058b18c2d1eSnia // TODO make it visible if hidden 1059b18c2d1eSnia } 1060b18c2d1eSnia break; 1061b18c2d1eSnia case F_FULLSCREENZOOM: 1062b18c2d1eSnia case F_XFULLSCREENZOOM: { 10630bbfda8aSnia int bw3D = tmp_win->frame_bw3D; 10640bbfda8aSnia int bw3D_times_2 = 2 * bw3D; 10650bbfda8aSnia int bw = tmp_win->frame_bw + bw3D; 10660bbfda8aSnia 1067b18c2d1eSnia finalArea = func == F_XFULLSCREENZOOM 1068b18c2d1eSnia ? RLayoutFull(borderedLayout, &area) 1069b18c2d1eSnia : RLayoutFull1(borderedLayout, &area); 1070b18c2d1eSnia dragx = finalArea.x - bw; 1071b18c2d1eSnia dragy = finalArea.y - tmp_win->title_height - bw; 1072b18c2d1eSnia dragWidth = finalArea.width + bw3D_times_2; 1073b18c2d1eSnia dragHeight = finalArea.height + tmp_win->title_height + bw3D_times_2; 10740bbfda8aSnia 10750bbfda8aSnia /* and should ignore aspect ratio and size increments... */ 10760bbfda8aSnia#ifdef EWMH 10770bbfda8aSnia /* x-ref HandleFocusIn() comments for why we need this */ 10780bbfda8aSnia OtpSetAflag(tmp_win, OTP_AFLAG_FULLSCREEN); 10790bbfda8aSnia OtpRestackWindow(tmp_win); 10800bbfda8aSnia /* the OtpRaise below is effectively already done here... */ 10810bbfda8aSnia#endif 10820bbfda8aSnia } 10830bbfda8aSnia } 1084b18c2d1eSnia 1085b18c2d1eSnia /* Temporary built layout? */ 1086b18c2d1eSnia if(borderedLayout != Scr->BorderedLayout) { 1087b18c2d1eSnia RLayoutFree(borderedLayout); 1088b18c2d1eSnia } 10890bbfda8aSnia } 10900bbfda8aSnia 10910bbfda8aSnia if(!Scr->NoRaiseResize && func != F_FULLSCREENZOOM) { 10920bbfda8aSnia OtpRaise(tmp_win, WinWin); 10930bbfda8aSnia } 10940bbfda8aSnia 10950bbfda8aSnia if(func != F_FULLSCREENZOOM) { 10960bbfda8aSnia ConstrainSize(tmp_win, &dragWidth, &dragHeight); 10970bbfda8aSnia } 10980bbfda8aSnia#ifdef BETTERZOOM 10990bbfda8aSnia if(func == F_ZOOM) { 11000bbfda8aSnia if(dragy + dragHeight < tmp_win->save_frame_y + tmp_win->save_frame_height) { 11010bbfda8aSnia dragy = tmp_win->save_frame_y + tmp_win->save_frame_height - dragHeight; 11020bbfda8aSnia } 11030bbfda8aSnia } 11040bbfda8aSnia#endif 11050bbfda8aSnia SetupWindow(tmp_win, dragx, dragy, dragWidth, dragHeight, -1); 11060bbfda8aSnia /* I don't understand the reason of this. Claude. 11070bbfda8aSnia XUngrabPointer (dpy, CurrentTime); 11080bbfda8aSnia */ 11090bbfda8aSnia XUngrabServer(dpy); 11100bbfda8aSnia 11110bbfda8aSnia XQueryPointer(dpy, 11120bbfda8aSnia tmp_win->w, 11130bbfda8aSnia &junkRoot, &junkRoot, 11140bbfda8aSnia &tmpX, &tmpY, &tmpW, &tmpH, &junkDepth); 11150bbfda8aSnia if(tmp_win->frame_x > tmpX || 11160bbfda8aSnia tmp_win->frame_x + tmp_win->frame_width < tmpX || 11170bbfda8aSnia tmp_win->frame_y > tmpY || 11180bbfda8aSnia tmp_win->frame_y + tmp_win->frame_height < tmpY) { 11190bbfda8aSnia XWarpPointer(dpy, Scr->Root, tmp_win->w, 0, 0, 0, 0, 0, 0); 11200bbfda8aSnia } 11210bbfda8aSnia 11220bbfda8aSnia#ifdef EWMH 11230bbfda8aSnia /* 11240bbfda8aSnia * Reset _NET_WM_STATE prop on the window. It sets whichever state 11250bbfda8aSnia * applies, not always the _MAXIMIZED_VERT we specify here. 11260bbfda8aSnia */ 11270bbfda8aSnia EwmhSet_NET_WM_STATE(tmp_win, EWMH_STATE_MAXIMIZED_VERT); 11280bbfda8aSnia#endif 11290bbfda8aSnia} 11300bbfda8aSnia 11310bbfda8aSnia/* 11320bbfda8aSnia * Forget about a window being zoomed. 11330bbfda8aSnia * This also needs to undo the special effects of F_FULLSCREENZOOM. 11340bbfda8aSnia */ 11350bbfda8aSniavoid unzoom(TwmWindow *tmp_win) 11360bbfda8aSnia{ 11370bbfda8aSnia if(tmp_win->zoomed != ZOOM_NONE) { 11380bbfda8aSnia#ifdef EWMH 11390bbfda8aSnia if(tmp_win->zoomed == F_FULLSCREENZOOM) { 11400bbfda8aSnia OtpClearAflag(tmp_win, OTP_AFLAG_FULLSCREEN); 11410bbfda8aSnia OtpRestackWindow(tmp_win); 11420bbfda8aSnia } 11430bbfda8aSnia#endif 11440bbfda8aSnia 11450bbfda8aSnia tmp_win->zoomed = ZOOM_NONE; 11460bbfda8aSnia } 11470bbfda8aSnia} 11480bbfda8aSnia 11490bbfda8aSniavoid savegeometry(TwmWindow *tmp_win) 11500bbfda8aSnia{ 11510bbfda8aSnia if(!tmp_win) { 11520bbfda8aSnia return; 11530bbfda8aSnia } 11540bbfda8aSnia tmp_win->savegeometry.x = tmp_win->frame_x; 11550bbfda8aSnia tmp_win->savegeometry.y = tmp_win->frame_y; 11560bbfda8aSnia tmp_win->savegeometry.width = tmp_win->frame_width; 11570bbfda8aSnia tmp_win->savegeometry.height = tmp_win->frame_height; 11580bbfda8aSnia} 11590bbfda8aSnia 11600bbfda8aSniavoid restoregeometry(TwmWindow *tmp_win) 11610bbfda8aSnia{ 11620bbfda8aSnia int x, y; 11630bbfda8aSnia unsigned int w, h; 11640bbfda8aSnia 11650bbfda8aSnia if(!tmp_win) { 11660bbfda8aSnia return; 11670bbfda8aSnia } 11680bbfda8aSnia if(tmp_win->savegeometry.width == (unsigned int) - 1) { 11690bbfda8aSnia return; 11700bbfda8aSnia } 11710bbfda8aSnia x = tmp_win->savegeometry.x; 11720bbfda8aSnia y = tmp_win->savegeometry.y; 11730bbfda8aSnia w = tmp_win->savegeometry.width; 11740bbfda8aSnia h = tmp_win->savegeometry.height; 11750bbfda8aSnia SetupWindow(tmp_win, x, y, w, h, -1); 11760bbfda8aSnia} 11770bbfda8aSnia 11780bbfda8aSnia 11790bbfda8aSniavoid ChangeSize(char *in_string, TwmWindow *tmp_win) 11800bbfda8aSnia{ 11810bbfda8aSnia int change = 0, size = 0; 11820bbfda8aSnia char *endptr; 11830bbfda8aSnia int rx, ry, wx, wy, mr; 11840bbfda8aSnia Window rr, cr; 11850bbfda8aSnia 11860bbfda8aSnia if(Isdigit(in_string[0])) { 11870bbfda8aSnia /* Handle the case f.changesize "640x480" */ 11880bbfda8aSnia wx = strtol(in_string, &endptr, 10); 11890bbfda8aSnia if(*endptr++ != 'x') { 11900bbfda8aSnia fprintf(stderr, 11910bbfda8aSnia "%s: Bad argument to f.changesize: \"%s\" (pattern \"640x480\")\n", 11920bbfda8aSnia ProgramName, in_string); 11930bbfda8aSnia return; 11940bbfda8aSnia } 11950bbfda8aSnia wy = strtol(endptr, &endptr, 10); 11960bbfda8aSnia 11970bbfda8aSnia if(wy < tmp_win->title_height + 1) { 11980bbfda8aSnia wy = tmp_win->title_height + 1; 11990bbfda8aSnia } 12000bbfda8aSnia 12010bbfda8aSnia SetupWindow(tmp_win, tmp_win->frame_x, tmp_win->frame_y, 12020bbfda8aSnia wx, wy + tmp_win->title_height, -1); 12030bbfda8aSnia } 12040bbfda8aSnia else { 12050bbfda8aSnia /* Handle the cases like f.changesize "right +10" */ 12060bbfda8aSnia int cmdlen = 0; 12070bbfda8aSnia 12080bbfda8aSnia while(in_string[cmdlen] != ' ' && in_string[cmdlen] != '\0') { 12090bbfda8aSnia cmdlen++; 12100bbfda8aSnia } 12110bbfda8aSnia 12120bbfda8aSnia if(in_string[cmdlen] != ' ') { 12130bbfda8aSnia fprintf(stderr, 12140bbfda8aSnia "%s: Bad argument to f.changesize: \"%s\" (sizechange missing)\n", 12150bbfda8aSnia ProgramName, in_string); 12160bbfda8aSnia return; 12170bbfda8aSnia } 12180bbfda8aSnia 12190bbfda8aSnia change = strtol(in_string + cmdlen + 1, &endptr, 10); 12200bbfda8aSnia if(*endptr != 0) { 12210bbfda8aSnia fprintf(stderr, 12220bbfda8aSnia "%s: Bad argument to f.changesize: \"%s\" (sizechange not a number)\n", 12230bbfda8aSnia ProgramName, in_string); 12240bbfda8aSnia return; 12250bbfda8aSnia } 12260bbfda8aSnia 12270bbfda8aSnia if(strncmp("bottom", in_string, cmdlen) == 0) { 12280bbfda8aSnia size = tmp_win->frame_height + change; 12290bbfda8aSnia 12300bbfda8aSnia if(size < (tmp_win->title_height + 1)) { 12310bbfda8aSnia size = tmp_win->title_height + 1; 12320bbfda8aSnia } 12330bbfda8aSnia 12340bbfda8aSnia SetupWindow(tmp_win, tmp_win->frame_x, tmp_win->frame_y, 12350bbfda8aSnia tmp_win->frame_width, size, 12360bbfda8aSnia -1); 12370bbfda8aSnia 12380bbfda8aSnia XQueryPointer(dpy, tmp_win->w, &rr, &cr, &rx, &ry, &wx, &wy, 12390bbfda8aSnia (unsigned int *)&mr); 12400bbfda8aSnia 12410bbfda8aSnia if((wy + tmp_win->title_height) > size) { 12420bbfda8aSnia XWarpPointer(dpy, None, tmp_win->w, 0, 0, 0, 0, 0, 0); 12430bbfda8aSnia } 12440bbfda8aSnia } 12450bbfda8aSnia else if(strncmp("top", in_string, cmdlen) == 0) { 12460bbfda8aSnia size = tmp_win->frame_height + change; 12470bbfda8aSnia 12480bbfda8aSnia if(size < (tmp_win->title_height + 1)) { 12490bbfda8aSnia size = tmp_win->title_height + 1; 12500bbfda8aSnia } 12510bbfda8aSnia 12520bbfda8aSnia SetupWindow(tmp_win, tmp_win->frame_x, (tmp_win->frame_y - change), 12530bbfda8aSnia tmp_win->frame_width, size, 12540bbfda8aSnia -1); 12550bbfda8aSnia 12560bbfda8aSnia XQueryPointer(dpy, tmp_win->w, &rr, &cr, &rx, &ry, &wx, &wy, 12570bbfda8aSnia (unsigned int *)&mr); 12580bbfda8aSnia 12590bbfda8aSnia if((wy + tmp_win->title_height) > size) { 12600bbfda8aSnia XWarpPointer(dpy, None, tmp_win->w, 0, 0, 0, 0, 0, 0); 12610bbfda8aSnia } 12620bbfda8aSnia 12630bbfda8aSnia 12640bbfda8aSnia } 12650bbfda8aSnia else if(strncmp("left", in_string, cmdlen) == 0) { 12660bbfda8aSnia size = tmp_win->frame_width + change; 12670bbfda8aSnia 12680bbfda8aSnia if(size < 1) { 12690bbfda8aSnia size = 1; 12700bbfda8aSnia } 12710bbfda8aSnia 12720bbfda8aSnia SetupWindow(tmp_win, (tmp_win->frame_x - change), tmp_win->frame_y, 12730bbfda8aSnia size, tmp_win->frame_height, 12740bbfda8aSnia -1); 12750bbfda8aSnia 12760bbfda8aSnia XQueryPointer(dpy, tmp_win->w, &rr, &cr, &rx, &ry, &wx, &wy, 12770bbfda8aSnia (unsigned int *)&mr); 12780bbfda8aSnia 12790bbfda8aSnia if(wx > size) { 12800bbfda8aSnia XWarpPointer(dpy, None, tmp_win->w, 0, 0, 0, 0, 0, 0); 12810bbfda8aSnia } 12820bbfda8aSnia 12830bbfda8aSnia 12840bbfda8aSnia } 12850bbfda8aSnia else if(strncmp("right", in_string, cmdlen) == 0) { 12860bbfda8aSnia size = tmp_win->frame_width + change; 12870bbfda8aSnia 12880bbfda8aSnia if(size < 1) { 12890bbfda8aSnia size = 1; 12900bbfda8aSnia } 12910bbfda8aSnia 12920bbfda8aSnia SetupWindow(tmp_win, tmp_win->frame_x, tmp_win->frame_y, 12930bbfda8aSnia size, tmp_win->frame_height, 12940bbfda8aSnia -1); 12950bbfda8aSnia 12960bbfda8aSnia XQueryPointer(dpy, tmp_win->w, &rr, &cr, &rx, &ry, &wx, &wy, 12970bbfda8aSnia (unsigned int *)&mr); 12980bbfda8aSnia 12990bbfda8aSnia if(wx > size) { 13000bbfda8aSnia XWarpPointer(dpy, None, tmp_win->w, 0, 0, 0, 0, 0, 0); 13010bbfda8aSnia } 13020bbfda8aSnia 13030bbfda8aSnia } 13040bbfda8aSnia else { 13050bbfda8aSnia /* error */ 13060bbfda8aSnia fprintf(stderr, "%s: Bad argument to f.changesize: \"%s\"\n (unknown border)", 13070bbfda8aSnia ProgramName, in_string); 13080bbfda8aSnia return; 13090bbfda8aSnia } 13100bbfda8aSnia } 13110bbfda8aSnia} 13120bbfda8aSnia 13130bbfda8aSnia 13140bbfda8aSnia/*********************************************************************** 13150bbfda8aSnia * 13160bbfda8aSnia * Procedure: 13170bbfda8aSnia * resizeFromCenter - 13180bbfda8aSnia * 13190bbfda8aSnia *********************************************************************** 13200bbfda8aSnia */ 13210bbfda8aSniavoid 13220bbfda8aSniaresizeFromCenter(Window w, TwmWindow *tmp_win) 13230bbfda8aSnia{ 13240bbfda8aSnia int lastx, lasty, bw2; 13250bbfda8aSnia 13260bbfda8aSnia bw2 = tmp_win->frame_bw * 2; 13270bbfda8aSnia AddingW = tmp_win->attr.width + bw2 + 2 * tmp_win->frame_bw3D; 13280bbfda8aSnia AddingH = tmp_win->attr.height + tmp_win->title_height + bw2 + 2 * 13290bbfda8aSnia tmp_win->frame_bw3D; 13300bbfda8aSnia 13310bbfda8aSnia XGetGeometry(dpy, w, &JunkRoot, &origDragX, &origDragY, 13320bbfda8aSnia &DragWidth, &DragHeight, 13330bbfda8aSnia &JunkBW, &JunkDepth); 13340bbfda8aSnia 13350bbfda8aSnia XWarpPointer(dpy, None, w, 13360bbfda8aSnia 0, 0, 0, 0, DragWidth / 2, DragHeight / 2); 13370bbfda8aSnia XQueryPointer(dpy, Scr->Root, &JunkRoot, 13380bbfda8aSnia &JunkChild, &JunkX, &JunkY, 13390bbfda8aSnia &AddingX, &AddingY, &JunkMask); 13400bbfda8aSnia 13410bbfda8aSnia lastx = -10000; 13420bbfda8aSnia lasty = -10000; 13430bbfda8aSnia 13440bbfda8aSnia MenuStartResize(tmp_win, origDragX, origDragY, DragWidth, DragHeight); 13450bbfda8aSnia while(1) { 13460bbfda8aSnia XMaskEvent(dpy, 13470bbfda8aSnia ButtonPressMask | PointerMotionMask | ExposureMask, &Event); 13480bbfda8aSnia 13490bbfda8aSnia if(Event.type == MotionNotify) { 13500bbfda8aSnia /* discard any extra motion events before a release */ 13510bbfda8aSnia while(XCheckMaskEvent(dpy, 13520bbfda8aSnia ButtonMotionMask | ButtonPressMask, &Event)) 13530bbfda8aSnia if(Event.type == ButtonPress) { 13540bbfda8aSnia break; 13550bbfda8aSnia } 13560bbfda8aSnia } 13570bbfda8aSnia 13580bbfda8aSnia if(Event.type == ButtonPress) { 13590bbfda8aSnia MenuEndResize(tmp_win); 13600bbfda8aSnia // Next line should be unneeded, done by MenuEndResize() ? 13610bbfda8aSnia XMoveResizeWindow(dpy, w, AddingX, AddingY, AddingW, AddingH); 13620bbfda8aSnia break; 13630bbfda8aSnia } 13640bbfda8aSnia 13650bbfda8aSnia if(Event.type != MotionNotify) { 13660bbfda8aSnia DispatchEvent2(); 13670bbfda8aSnia if(Cancel) { 13680bbfda8aSnia // ... 13690bbfda8aSnia MenuEndResize(tmp_win); 13700bbfda8aSnia return; 13710bbfda8aSnia } 13720bbfda8aSnia continue; 13730bbfda8aSnia } 13740bbfda8aSnia 13750bbfda8aSnia /* 13760bbfda8aSnia * XXX - if we are going to do a loop, we ought to consider 13770bbfda8aSnia * using multiple GXxor lines so that we don't need to 13780bbfda8aSnia * grab the server. 13790bbfda8aSnia */ 13800bbfda8aSnia XQueryPointer(dpy, Scr->Root, &JunkRoot, &JunkChild, 13810bbfda8aSnia &JunkX, &JunkY, &AddingX, &AddingY, &JunkMask); 13820bbfda8aSnia 13830bbfda8aSnia if(lastx != AddingX || lasty != AddingY) { 13840bbfda8aSnia MenuDoResize(AddingX, AddingY, tmp_win); 13850bbfda8aSnia 13860bbfda8aSnia lastx = AddingX; 13870bbfda8aSnia lasty = AddingY; 13880bbfda8aSnia } 13890bbfda8aSnia 13900bbfda8aSnia } 13910bbfda8aSnia} 1392