Initial import of the CDE 2.1.30 sources from the Open Group.
This commit is contained in:
654
cde/programs/dtwm/WmCPlace.c
Normal file
654
cde/programs/dtwm/WmCPlace.c
Normal file
@@ -0,0 +1,654 @@
|
||||
/*
|
||||
* (c) Copyright 1989, 1990, 1991, 1992 OPEN SOFTWARE FOUNDATION, INC.
|
||||
* ALL RIGHTS RESERVED
|
||||
*/
|
||||
/*
|
||||
* Motif Release 1.2
|
||||
*/
|
||||
#ifdef REV_INFO
|
||||
#ifndef lint
|
||||
static char rcsid[] = "$XConsortium: WmCPlace.c /main/5 1996/08/09 15:18:04 rswiston $"
|
||||
#endif
|
||||
#endif
|
||||
/*
|
||||
* (c) Copyright 1987, 1988, 1989, 1990 HEWLETT-PACKARD COMPANY */
|
||||
|
||||
/*
|
||||
* Included Files:
|
||||
*/
|
||||
#include "WmGlobal.h"
|
||||
#define XK_MISCELLANY
|
||||
#define XK_LATIN1
|
||||
#include <X11/keysymdef.h>
|
||||
|
||||
/* absolute value macro */
|
||||
#ifndef ABS
|
||||
#define ABS(x) (((x) > 0) ? (x) : (-(x)))
|
||||
#endif
|
||||
|
||||
#define GRAB_MASK (KeyPressMask | ButtonPressMask | ButtonReleaseMask |\
|
||||
PointerMotionMask)
|
||||
#define PGRAB_MASK (ButtonPressMask | ButtonReleaseMask |\
|
||||
PointerMotionMask | PointerMotionHintMask)
|
||||
|
||||
#define NOFRZ_GRAB_MASK (KeyPressMask | ButtonPressMask |\
|
||||
ButtonReleaseMask)
|
||||
#define NOFRZ_PGRAB_MASK (ButtonPressMask | ButtonReleaseMask)
|
||||
|
||||
/*
|
||||
* include extern functions
|
||||
*/
|
||||
#include "WmCDInfo.h"
|
||||
#include "WmCDecor.h"
|
||||
#include "WmFeedback.h"
|
||||
#include "WmWinConf.h"
|
||||
|
||||
/*
|
||||
* Global Variables:
|
||||
*/
|
||||
static int placeX;
|
||||
static int placeY;
|
||||
static unsigned int placeWidth;
|
||||
static unsigned int placeHeight;
|
||||
|
||||
static Boolean placeResize;
|
||||
static Boolean placementDone;
|
||||
static int placePointerX;
|
||||
static int placePointerY;
|
||||
static int placeKeyMultiplier;
|
||||
|
||||
static int placeOffsetX;
|
||||
static int placeOffsetY;
|
||||
|
||||
|
||||
|
||||
/*************************************<->*************************************
|
||||
*
|
||||
* SetupPlacement (pcd)
|
||||
*
|
||||
*
|
||||
* Description:
|
||||
* -----------
|
||||
* Perform the initialization for interactive placement
|
||||
*
|
||||
*
|
||||
* Inputs:
|
||||
* ------
|
||||
* pcd - pointer to client data
|
||||
*
|
||||
* Outputs:
|
||||
* -------
|
||||
*
|
||||
*
|
||||
* Comments:
|
||||
* --------
|
||||
* o sets up global data and puts initial display on the screen
|
||||
*
|
||||
*************************************<->***********************************/
|
||||
void SetupPlacement (ClientData *pcd)
|
||||
{
|
||||
int cX, cY, junk;
|
||||
Window junk_win;
|
||||
|
||||
/*
|
||||
* Restore the state of the last "depressed" frame gadget
|
||||
*/
|
||||
|
||||
if (wmGD.gadgetClient && wmGD.gadgetDepressed)
|
||||
{
|
||||
PopGadgetOut(wmGD.gadgetClient, wmGD.gadgetDepressed);
|
||||
|
||||
}
|
||||
|
||||
/* get offset of frame origin from window origin */
|
||||
placeOffsetX = pcd->clientOffset.x;
|
||||
placeOffsetY = pcd->clientOffset.y;
|
||||
|
||||
XQueryPointer (DISPLAY, ACTIVE_ROOT,
|
||||
&junk_win, &junk_win,
|
||||
&cX, &cY, &junk, &junk, (unsigned int *)&junk);
|
||||
|
||||
/* convert to frame coordinates */
|
||||
placePointerX = placeX = cX;
|
||||
placePointerY = placeY = cY;
|
||||
placeWidth = pcd->clientWidth;
|
||||
placeHeight = pcd->clientHeight;
|
||||
ClientToFrame (pcd, &cX, &cY, &placeWidth, &placeHeight);
|
||||
|
||||
/* in "position" mode to start with */
|
||||
placeResize = FALSE;
|
||||
wmGD.preMove = FALSE;
|
||||
|
||||
/* normal window being dealt with, not icon */
|
||||
wmGD.movingIcon = FALSE;
|
||||
|
||||
if (wmGD.showFeedback & WM_SHOW_FB_PLACEMENT)
|
||||
{
|
||||
DoFeedback (pcd, placeX, placeY, placeWidth, placeHeight,
|
||||
(FB_SIZE | FB_POSITION), placeResize);
|
||||
}
|
||||
|
||||
/* set up initial visual feedback */
|
||||
MoveOutline (placeX, placeY, placeWidth, placeHeight);
|
||||
|
||||
} /* END OF FUNCTION SetupPlacement */
|
||||
|
||||
|
||||
/*************************************<->*************************************
|
||||
*
|
||||
* IsRepeatedKeyEvent (dpy, pEvent, pOldEvent)
|
||||
*
|
||||
*
|
||||
* Description:
|
||||
* -----------
|
||||
* Returns TRUE if the event passed in is a repeat of the key event
|
||||
* indicated in pOldEvent
|
||||
*
|
||||
*
|
||||
* Inputs:
|
||||
* ------
|
||||
* dpy - display
|
||||
* pEvent - pointer to this event
|
||||
* pOldEvent - pointer to previous event (cast to the correct type)
|
||||
*
|
||||
*
|
||||
* Outputs:
|
||||
* -------
|
||||
* IsRepeatedKeyEvent - True if the events are "the same,"
|
||||
* False otherwise.
|
||||
*
|
||||
*
|
||||
* Comments:
|
||||
* --------
|
||||
*
|
||||
*************************************<->***********************************/
|
||||
Bool IsRepeatedKeyEvent (Display *dpy, XEvent *pEvent, char *pOldEvent)
|
||||
{
|
||||
XEvent *pOld = (XEvent *) pOldEvent;
|
||||
|
||||
if ((pEvent->type == KeyPress) && /* key press event */
|
||||
(pEvent->type == pOld->type) && /* same event type */
|
||||
(pEvent->xkey.keycode == pOld->xkey.keycode) && /* same key code */
|
||||
(pEvent->xkey.state == pOld->xkey.state) && /* same modifiers */
|
||||
(pEvent->xkey.window == pOld->xkey.window) && /* same window */
|
||||
(pEvent->xkey.root == pOld->xkey.root)) /* same root */
|
||||
{
|
||||
return (True);
|
||||
}
|
||||
else
|
||||
{
|
||||
return (False);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*************************************<->*************************************
|
||||
*
|
||||
* StartInteractiveSizing (pcd, time)
|
||||
*
|
||||
*
|
||||
* Description:
|
||||
* -----------
|
||||
* Switch from "position" mode to "resize" mode
|
||||
*
|
||||
*
|
||||
* Inputs:
|
||||
* ------
|
||||
* pcd - pointer to client data
|
||||
* time - time stamp of event for pointer regrab
|
||||
*
|
||||
*
|
||||
* Outputs:
|
||||
* -------
|
||||
*
|
||||
*
|
||||
* Comments:
|
||||
* --------
|
||||
*
|
||||
*************************************<->***********************************/
|
||||
void StartInteractiveSizing (ClientData *pcd, Time time)
|
||||
{
|
||||
unsigned int gmask;
|
||||
|
||||
/* regrab pointer to change cursor */
|
||||
gmask = (wmGD.freezeOnConfig)? PGRAB_MASK : NOFRZ_PGRAB_MASK;
|
||||
XChangeActivePointerGrab (DISPLAY, gmask,
|
||||
wmGD.sizePlacementCursor, time);
|
||||
|
||||
/* put cursor at lower-right corner */
|
||||
if (wmGD.enableWarp)
|
||||
{
|
||||
XWarpPointer (DISPLAY, None, ACTIVE_ROOT, 0, 0, 0, 0,
|
||||
(int) (placeX+placeWidth-1), (int) (placeY+placeHeight-1));
|
||||
}
|
||||
|
||||
/*
|
||||
* Don't go into resize mode if resize is turned off.
|
||||
*/
|
||||
if (pcd->clientFunctions & MWM_FUNC_RESIZE)
|
||||
{
|
||||
/* update flags */
|
||||
placeResize = TRUE;
|
||||
wmGD.preMove = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*************************************<->*************************************
|
||||
*
|
||||
* HandlePlacementKeyEvent (pcd, pev)
|
||||
*
|
||||
*
|
||||
* Description:
|
||||
* -----------
|
||||
* Handle key presses during interactive placement
|
||||
*
|
||||
*
|
||||
* Inputs:
|
||||
* ------
|
||||
* pcd - pointer to client data
|
||||
* pev - pointer to key press event
|
||||
*
|
||||
* Outputs:
|
||||
* -------
|
||||
*
|
||||
*
|
||||
* Comments:
|
||||
* --------
|
||||
*
|
||||
*************************************<->***********************************/
|
||||
|
||||
void HandlePlacementKeyEvent (ClientData *pcd, XKeyEvent *pev)
|
||||
{
|
||||
XEvent KeyEvent;
|
||||
KeySym keysym;
|
||||
Boolean control, valid;
|
||||
int big_inc;
|
||||
int tmpX = 0;
|
||||
int tmpY = 0;
|
||||
int warpX, warpY, newX, newY;
|
||||
int keyPlaceX = placeX;
|
||||
int keyPlaceY = placeY;
|
||||
unsigned int keyPlaceWidth = placeWidth;
|
||||
unsigned int keyPlaceHeight = placeHeight;
|
||||
|
||||
/* filter out repeating keys */
|
||||
placeKeyMultiplier = 1;
|
||||
if (pev->type == KeyPress)
|
||||
{
|
||||
while (placeKeyMultiplier <= 10 &&
|
||||
XCheckIfEvent (DISPLAY, &KeyEvent, IsRepeatedKeyEvent,
|
||||
(char *) pev))
|
||||
{
|
||||
placeKeyMultiplier++;
|
||||
}
|
||||
}
|
||||
|
||||
/* convert event data to useful key data */
|
||||
keysym = XKeycodeToKeysym (DISPLAY, pev->keycode, 0);
|
||||
control = (pev->state & ControlMask) != 0;
|
||||
big_inc = DisplayWidth(DISPLAY, ACTIVE_PSD->screen) / 20;
|
||||
|
||||
/* interpret key data */
|
||||
valid = FALSE;
|
||||
switch (keysym)
|
||||
{
|
||||
case XK_Left:
|
||||
tmpX = (control) ? (-big_inc) : -1;
|
||||
valid = TRUE;
|
||||
break;
|
||||
|
||||
case XK_Up:
|
||||
tmpY = (control) ? (-big_inc) : -1;
|
||||
valid = TRUE;
|
||||
break;
|
||||
|
||||
case XK_Right:
|
||||
tmpX = (control) ? (big_inc) : 1;
|
||||
valid = TRUE;
|
||||
break;
|
||||
|
||||
case XK_Down:
|
||||
tmpY = (control) ? (big_inc) : 1;
|
||||
valid = TRUE;
|
||||
break;
|
||||
|
||||
case XK_space:
|
||||
StartInteractiveSizing(pcd, pev->time);
|
||||
break;
|
||||
|
||||
case XK_Return:
|
||||
placementDone = TRUE; /* global "done" flag */
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
/* if a valid key was pressed, then react to it */
|
||||
if (valid) {
|
||||
tmpX *= placeKeyMultiplier;
|
||||
tmpY *= placeKeyMultiplier;
|
||||
|
||||
if (placeResize)
|
||||
{
|
||||
keyPlaceWidth += tmpX; /* change size of outline */
|
||||
keyPlaceHeight += tmpY;
|
||||
|
||||
FixFrameValues(pcd, &keyPlaceX, &keyPlaceY, &keyPlaceWidth,
|
||||
&keyPlaceHeight, placeResize);
|
||||
|
||||
warpX = keyPlaceX+keyPlaceWidth-1;
|
||||
warpY = keyPlaceY+keyPlaceHeight-1;
|
||||
|
||||
SetPointerPosition (warpX, warpY, &newX, &newY);
|
||||
|
||||
if ((warpX == newX) && (warpY == newY))
|
||||
{
|
||||
placeWidth = keyPlaceWidth;
|
||||
placeHeight = keyPlaceHeight;
|
||||
}
|
||||
else
|
||||
{
|
||||
placeWidth = newX - keyPlaceX + 1;
|
||||
placeHeight = newY - keyPlaceY + 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
keyPlaceX += tmpX; /* change position of outline */
|
||||
keyPlaceY += tmpY;
|
||||
|
||||
FixFrameValues(pcd, &keyPlaceX, &keyPlaceY, &keyPlaceWidth,
|
||||
&keyPlaceHeight, placeResize);
|
||||
|
||||
warpX = keyPlaceX;
|
||||
warpY = keyPlaceY;
|
||||
|
||||
SetPointerPosition (warpX, warpY, &newX, &newY);
|
||||
|
||||
placeX = newX;
|
||||
placeY = newY;
|
||||
}
|
||||
placePointerX = newX;
|
||||
placePointerY = newY;
|
||||
}
|
||||
FixFrameValues (pcd, &placeX, &placeY, &placeWidth, &placeHeight,
|
||||
placeResize);
|
||||
|
||||
MoveOutline (placeX, placeY, placeWidth, placeHeight);
|
||||
|
||||
if (wmGD.showFeedback & WM_SHOW_FB_PLACEMENT)
|
||||
{
|
||||
DoFeedback (pcd, placeX, placeY, placeWidth, placeHeight,
|
||||
0, placeResize);
|
||||
}
|
||||
} /* END OF FUNCTION HandlePlacementKeyEvent */
|
||||
|
||||
|
||||
/*************************************<->*************************************
|
||||
*
|
||||
* HandlePlacementButtonEvent (pev)
|
||||
*
|
||||
*
|
||||
* Description:
|
||||
* -----------
|
||||
* XXDescription ...
|
||||
*
|
||||
*
|
||||
* Inputs:
|
||||
* ------
|
||||
* pev - pointer to button event
|
||||
*
|
||||
* Outputs:
|
||||
* -------
|
||||
*
|
||||
*
|
||||
* Comments:
|
||||
* --------
|
||||
*
|
||||
*************************************<->***********************************/
|
||||
|
||||
void HandlePlacementButtonEvent (XButtonEvent *pev)
|
||||
{
|
||||
/*
|
||||
* Only listen to button 1
|
||||
*/
|
||||
if (pev->button == 1)
|
||||
{
|
||||
/*
|
||||
* Complete interactive placement on button release
|
||||
*/
|
||||
if (pev->type == ButtonRelease)
|
||||
{
|
||||
placementDone = TRUE; /* global done flag */
|
||||
}
|
||||
|
||||
else if (pev->type == ButtonPress)
|
||||
{
|
||||
|
||||
/*
|
||||
* Button press, go to pre-resize mode
|
||||
*/
|
||||
wmGD.preMoveX = pev->x_root;
|
||||
wmGD.preMoveY = pev->y_root;
|
||||
wmGD.preMove = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*************************************<->*************************************
|
||||
*
|
||||
* HandlePlacementMotionEvent (pcd, pev)
|
||||
*
|
||||
*
|
||||
* Description:
|
||||
* -----------
|
||||
* Handles pointer motion events during interactive placement
|
||||
*
|
||||
*
|
||||
* Inputs:
|
||||
* ------
|
||||
* pcd - pointer to client data
|
||||
* pev - pointer to mouse motion event
|
||||
*
|
||||
*
|
||||
* Outputs:
|
||||
* -------
|
||||
*
|
||||
*
|
||||
* Comments:
|
||||
* --------
|
||||
*
|
||||
*************************************<->***********************************/
|
||||
|
||||
void HandlePlacementMotionEvent (ClientData *pcd, XMotionEvent *pev)
|
||||
{
|
||||
int diffx, diffy;
|
||||
|
||||
/*
|
||||
* If in pre-resize mode, check for motion crossing threshhold before
|
||||
* switching modes
|
||||
*/
|
||||
if (wmGD.preMove) {
|
||||
diffx = pev->x_root - wmGD.preMoveX;
|
||||
diffy = pev->y_root - wmGD.preMoveY;
|
||||
if ((ABS(diffx) > wmGD.moveThreshold) ||
|
||||
(ABS(diffy) > wmGD.moveThreshold))
|
||||
{
|
||||
StartInteractiveSizing(pcd, pev->time);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (placeResize) {
|
||||
/*
|
||||
* Track lower right corner
|
||||
*/
|
||||
if (pev->x_root > placeX)
|
||||
placeWidth = pev->x_root - placeX + 1;
|
||||
if (pev->y_root > placeY)
|
||||
placeHeight = pev->y_root - placeY + 1;
|
||||
}
|
||||
else {
|
||||
/*
|
||||
* track window position
|
||||
*/
|
||||
placeX = pev->x_root;
|
||||
placeY = pev->y_root;
|
||||
}
|
||||
|
||||
placePointerX = pev->x_root;
|
||||
placePointerY = pev->y_root;
|
||||
|
||||
FixFrameValues (pcd, &placeX, &placeY, &placeWidth, &placeHeight,
|
||||
placeResize);
|
||||
|
||||
MoveOutline (placeX, placeY, placeWidth, placeHeight);
|
||||
|
||||
if (wmGD.showFeedback & WM_SHOW_FB_PLACEMENT)
|
||||
{
|
||||
DoFeedback (pcd, placeX, placeY, placeWidth, placeHeight,
|
||||
0, placeResize);
|
||||
}
|
||||
} /* END OF FUNCTION HandlePlacementMotionEvent */
|
||||
|
||||
|
||||
|
||||
/*************************************<->*************************************
|
||||
*
|
||||
* DoPlacement (pcd)
|
||||
*
|
||||
*
|
||||
* Description:
|
||||
* -----------
|
||||
* Gets window configuration from the user via pointer/keyboard interaction
|
||||
*
|
||||
*
|
||||
* Inputs:
|
||||
* ------
|
||||
* pcd - pointer to client data
|
||||
*
|
||||
*
|
||||
* Outputs:
|
||||
* -------
|
||||
* pcd - clientX, clientY, clientWidth, and clientHeight members
|
||||
* could be changed
|
||||
*
|
||||
* Comments:
|
||||
* --------
|
||||
* We try to be careful only to remove events that we need from the
|
||||
* event queue while we're in our own event processing loop.
|
||||
*
|
||||
*************************************<->***********************************/
|
||||
void DoPlacement (ClientData *pcd)
|
||||
{
|
||||
XEvent event;
|
||||
|
||||
/*
|
||||
* Initialization
|
||||
*/
|
||||
SetupPlacement (pcd);
|
||||
|
||||
/*
|
||||
* Process events
|
||||
*/
|
||||
placementDone = FALSE;
|
||||
while (!placementDone)
|
||||
{
|
||||
GetConfigEvent (DISPLAY, ACTIVE_ROOT, GRAB_MASK,
|
||||
placePointerX, placePointerY, placeX, placeY,
|
||||
placeWidth, placeHeight, &event);
|
||||
|
||||
switch (event.type) {
|
||||
case KeyPress:
|
||||
HandlePlacementKeyEvent(pcd, (XKeyEvent *)&event);
|
||||
break;
|
||||
|
||||
case ButtonPress:
|
||||
HandlePlacementButtonEvent((XButtonEvent *)&event);
|
||||
break;
|
||||
|
||||
case ButtonRelease:
|
||||
HandlePlacementButtonEvent((XButtonEvent *)&event);
|
||||
break;
|
||||
|
||||
case MotionNotify:
|
||||
HandlePlacementMotionEvent(pcd, (XMotionEvent *)&event);
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/* copy back the configuration information */
|
||||
pcd->clientX = placeX + placeOffsetX;
|
||||
pcd->clientY = placeY + placeOffsetY;
|
||||
pcd->clientWidth = placeWidth - 2*placeOffsetX;
|
||||
pcd->clientHeight = placeHeight - placeOffsetX - placeOffsetY;
|
||||
|
||||
/* clean up */
|
||||
MoveOutline (0,0,0,0);
|
||||
HideFeedbackWindow(pcd->pSD);
|
||||
|
||||
} /* END OF FUNCTION DoPlacement */
|
||||
|
||||
|
||||
|
||||
/*************************************<->*************************************
|
||||
*
|
||||
* PlaceWindowInteractively(pcd)
|
||||
*
|
||||
*
|
||||
* Description:
|
||||
* -----------
|
||||
* Gets the clients size and position information interactively from the
|
||||
* user.
|
||||
*
|
||||
*
|
||||
* Inputs:
|
||||
* ------
|
||||
* pcd - pointer to client data
|
||||
*
|
||||
*
|
||||
* Outputs:
|
||||
* -------
|
||||
*
|
||||
*
|
||||
* Comments:
|
||||
* --------
|
||||
*
|
||||
*************************************<->***********************************/
|
||||
void PlaceWindowInteractively (ClientData *pcd)
|
||||
{
|
||||
unsigned int gmask;
|
||||
|
||||
gmask = (wmGD.freezeOnConfig)? PGRAB_MASK : NOFRZ_PGRAB_MASK;
|
||||
|
||||
/*
|
||||
* Return if config is in progress or if grabs fail
|
||||
*/
|
||||
if (!DoGrabs (ACTIVE_ROOT, wmGD.movePlacementCursor,
|
||||
gmask, CurrentTime, pcd, True))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the size and position of the window from the user.
|
||||
* Do our own event processing until a button-up event occurs
|
||||
*/
|
||||
DoPlacement(pcd);
|
||||
|
||||
/*
|
||||
* Finish up and return the data
|
||||
*/
|
||||
UndoGrabs();
|
||||
wmGD.preMove = FALSE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user