Path: utzoo!attcan!uunet!husc6!purdue!i.cc.purdue.edu!j.cc.purdue.edu!ain
From: ain@j.cc.purdue.edu (Patrick White)
Newsgroups: comp.sources.amiga
Subject: vscreen (sources 2 of 2)
Keywords: virtuial, screen, superbitmap, uncompiled
Message-ID: <7278@j.cc.purdue.edu>
Date: 23 Jun 88 23:00:23 GMT
Organization: PUCC Land, USA
Lines: 1478
Approved: ain@j.cc.purdue.edu (Patrick White)
Submitted by: dpvc@tut.cc.rochester.edu (David P. Cervone)
Summary: Make virtual screens lager than will fit on monitor.
Poster Boy: Patrick White (ain@j.cc.purdue.edu)
Archive Name: sources/amiga/volume5/vscreen.s.sh.2of2.Z
tested but not compiled.
NOTES:
The source is for Lattice -- I didn't even try compiling it.
It is a bit messy when resizing in that it dosen't seem to send window
resize messages when you change the size of a window, or when you exit vscreen,
but it works otherwise.. I feel it might be useful despite these bugs so I'm
posting it anyway.
.
-- Pat White (co-moderator comp.sources/binaries.amiga)
ARPA/UUCP: j.cc.purdue.edu!ain BITNET: PATWHITE@PURCCVM PHONE: (317) 743-8421
U.S. Mail: 320 Brown St. apt. 406, West Lafayette, IN 47906
========================================
# This is a shell archive.
# Remove everything above and including the cut line.
# Then run the rest of the file through sh.
#----cut here-----cut here-----cut here-----cut here----#
#!/bin/sh
# shar: Shell Archiver
# Run the following text with /bin/sh to create:
# vScreen.c
# vScreenSetup.c
# wList.c
# wMax.c
# wMove.c
# wSize.c
# This archive created: Wed Jun 22 11:35:24 1988
# By: Patrick White (PUCC Land, USA)
echo shar: extracting vScreen.c '(14176 characters)'
cat << \SHAR_EOF > vScreen.c
/*
* VSCREEN.C Creates virtual screens that can be larger than
* the actual display area of your monitor. The virtual
* screen scrolls when the mouse moves off the edge of
* the display.
*
* Copyright 1988 by Davide P. Cervone, all rights reserved.
*
* You may may distibute this code as is, for non-commercial
* purposes, provided that this notice remains intact and the
* documentation file is distributed with it.
*
* You may not modify this code or incorporate it into your
* own programs without the permission of the author.
*/
/*
* WARNING: This code uses and even modifies the INTUITIONPRIVATE
* area of the IntuitionBase structure. Use it at your own risk. It is
* likely to break under a future release of Intuition.
*/
#include "vScreen.h"
static char *program = "vScreen"; /* the program name */
static char *author = COPYRIGHT; /* the copyright notice */
#define LOADVERS 1 /* this program's version */
static char *handler = "L:vScreen-Handler"; /* the name of the handler */
#define HANDLER &(handler[2]) /* same but in the current dir */
extern struct LayersBase *LayersBase; /* the Layers library */
struct vScreenInfo *vScreenData; /* data needed by the handler */
struct Screen *VScreen = NULL; /* the virtual screen */
static long Segment = NULL; /* the loaded handler */
SHORT ScreenWidth,ScreenHeight; /* the new screen sizes */
static struct MsgPort *NamedPort = NULL; /* used to find the handler later */
static struct MsgPort *InputPort = NULL; /* to talk to Input.Device */
static struct IOStdReq *InputBlock = NULL; /* IO block for Input.Device */
static short InputDevice = FALSE; /* is Input.Device open? */
static int Enlarged = FALSE; /* is screen changed? */
/*
* These routines are in vScreenSetup.c
*/
extern struct Screen *FindScreen();
extern void SetVariables();
extern void GetVariables();
extern int EnlargeScreen();
extern void RestoreScreen();
#ifndef PROTO
extern long SetFunction();
#endif
/*
* We trap these routines via SetFunction in order to make vSscreen work.
*/
#ifndef PROTO
extern void MoveSprite();
extern void LoadView();
extern void AutoRequest();
extern void BuildSysRequest();
extern void CloseScreen();
#endif
extern long LVOMoveSprite;
extern long LVOLoadView;
extern long LVOAutoRequest;
extern long LVOBuildSysRequest;
extern long LVOCloseScreen;
/*
* CreateNonSigPort()
*
* Creates a message port with signal type PA_IGNORE. Based on
* CreatePort() from the exec support functions documented in the RKM.
*/
struct MsgPort *CreateNonSigPort(name,pri)
char *name;
BYTE pri;
{
struct MsgPort *thePort;
thePort = (struct MsgPort *)AllocMem((ULONG)sizeof(struct MsgPort),
MEMF_PUBLIC | MEMF_CLEAR);
if (thePort)
{
thePort->mp_Node.ln_Name = name;
thePort->mp_Node.ln_Pri = pri;
thePort->mp_Node.ln_Type = NT_MSGPORT;
thePort->mp_Flags = PA_IGNORE;
thePort->mp_SigBit = 0;
thePort->mp_SigTask = NULL;
if (name)
AddPort(thePort);
else
NewList(&(thePort->mp_MsgList));
}
return(thePort);
}
/*
* DeleteNonSigPort()
*
* Deletes a message port with signal type PA_IGNORE. Based on
* DeletePort() from the exec support functions documented in the RKM
*/
void DeleteNonSigPort(thePort)
struct MsgPort *thePort;
{
if (thePort->mp_Node.ln_Name) RemPort(thePort);
thePort->mp_Node.ln_Type = 0xFF;
thePort->mp_MsgList.lh_Head = (struct Node *) -1;
FreeMem(thePort,(ULONG)sizeof(struct MsgPort));
}
/*
* DoExit()
*
* Exit with error status. Print a message with up to three parameters
* and then clean up everything (restore the screen if it is enlarged,
* unload the handler if it is loaded, close the Input.Device and free
* its IO blocks and ports, and close any open libraries). Return the
* error status.
*/
void DoExit(s,x1,x2,x3)
char *s, *x1,*x2,*x3;
{
int status = OK_EXIT;
if (s)
{
printf(s,x1,x2,x3);
printf("\n");
status = ERROR_EXIT;
}
if (Enlarged) RestoreScreen();
if (NamedPort) DeleteNonSigPort(NamedPort);
if (Segment) UnLoadSeg(Segment);
if (InputDevice) CloseDevice(InputBlock);
if (InputBlock) DeleteStdIO(InputBlock);
if (InputPort) DeletePort(InputPort);
if (IntuitionBase) CloseLibrary(IntuitionBase);
if (GfxBase) CloseLibrary(GfxBase);
if (LayersBase) CloseLibrary(LayersBase);
exit(status);
}
/*
* CheckLibOpen()
*
* Call OpenLibrary() for the specified library, and check that the
* open succeeded.
*/
void CheckLibOpen(lib,name,rev)
APTR *lib;
char *name;
int rev;
{
#ifndef PROTO
extern APTR OpenLibrary();
#endif
if ((*lib = OpenLibrary(name,(ULONG)rev)) == NULL)
DoExit("Can't open '%s'",name);
}
/*
* GetInt()
*
* Read the first integer from the given string variable (used to parse
* the command-line arguments). If no integer can be read, exit and
* show the usage string.
*/
static long GetInt(s)
char *s;
{
long i;
if (sscanf(s,"%ld",&i) != 1) DoExit("Usage: %s",USAGE);
return(i);
}
/*
* ParseArguments()
*
* Parse the command-line arguments. If there are too many or too few
* arguments, exit with an error message, otherwise get the width and height
* agruments. If there was a screen name specified, record that.
* Find the specified screen.
*/
static void ParseArguments(argc,argv)
int argc;
char *argv[];
{
char *ScreenName = NULL;
if (argc < 3) DoExit("Width and Height are required\nUsage: %s",USAGE);
if (argc > 4) DoExit("Too many arguments");
ScreenWidth = GetInt(argv[1]);
ScreenHeight = GetInt(argv[2]);
if (ScreenWidth <= 0 || ScreenHeight <= 0)
DoExit("Screen height and width must be positive");
if (ScreenWidth > 1024 || ScreenHeight > 1024)
printf("Warning: sizes greater than 1024 may cause Blitter problems\n");
if (argc > 3 && argv[3] && argv[3][0] != '\0') ScreenName = argv[3];
VScreen = FindScreen(ScreenName);
}
/*
* LoadHandler()
*
* Try to LoadSeg the handler from the current directory, and if it is not
* found, try the L: directory. If neither can be loaded, exit with a
* message. Once the handler is loaded, call its Setup routine passing it
* our version number. The handler will check the versions for compatability,
* and return NULL for version mismatch, or a pointer to its data structure
* with pointers to the variables that vScreen will initialize for it.
* LoadHandler() sets the pointer to the handlers SegList, and sets the
* loader version number
*/
static void LoadHandler()
{
struct vScreenInfo *(*Setup)();
if ((Segment = LoadSeg(HANDLER)) == NULL)
if ((Segment = LoadSeg(handler)) == NULL)
DoExit("Can't Load '%s'",handler);
Setup = (struct vScreenInfo *(*)()) ((Segment << 2) + 4);
vScreenData = (*Setup)(LOADVERS);
if (vScreenData)
{
if (var(MajVers) > 1) DoExit("version mismatch with '%s'",HANDLER);
} else {
DoExit("'%s' reports a version mismatch",HANDLER);
}
var(Segment) = Segment;
var(LoadVers) = LOADVERS;
}
/*
* TellInputDevice()
*
* Create a port and I/O block, then open the input device. Set up the
* I/O block to add or remove the input handler, and send the request
* to the input device. Finally, close the device and delete the
* I/O block and port.
*/
void TellInputDevice(function)
int function;
{
long status;
if ((InputPort = CreatePort(0,0)) == NULL) DoExit("Can't Create Port");
if ((InputBlock = CreateStdIO(InputPort)) == NULL)
DoExit("Can't Create Standard IO Block");
InputDevice = (OpenDevice("input.device",0,InputBlock,0) == 0);
if (InputDevice == FALSE) DoExit("Can't Open 'input.device'");
InputBlock->io_Command = (long) function;
InputBlock->io_Data = (APTR) vScreenData->HandlerInfo;
if (status = DoIO(InputBlock)) DoExit("Error from DoIO: %ld",status);
CloseDevice(InputBlock); InputDevice = FALSE;
DeleteStdIO(InputBlock); InputBlock = NULL;
DeletePort(InputPort); InputPort = NULL;
}
/*
* SetVectors()
*
* Call SetFunction() to replace the library vectores for the routines that
* we need to trap. Use the routines that the handler has supplied (they
* were passed to us in the vScreenData structure). Save the old vectors
* in the vScreenData strucutre so we can replace them later. Set the
* jump addresses so that the stub routines can call the old vectors.
* I Know this is a kludge, and is a form of self-modifying code, but I
* can't figure out a better method. The JSR (Ax) is only good when there
* is a free A register, which is not always the case.
*/
void SetVectors()
{
var(OldCloseScreen) =
SetFunction(IntuitionBase,&LVOCloseScreen,var(aCloseScreen));
var(CloseScreenJmpTarget)[-1] = (long) var(OldCloseScreen);
var(OldBuildSysRequest) =
SetFunction(IntuitionBase,&LVOBuildSysRequest,var(aBuildSysRequest));
var(BuildSysRequestJmpTarget)[-1] = (long) var(OldBuildSysRequest);
var(OldAutoRequest) =
SetFunction(IntuitionBase,&LVOAutoRequest,var(aAutoRequest));
var(AutoRequestJmpTarget)[-1] = (long) var(OldAutoRequest);
var(OldLoadView) = SetFunction(GfxBase,&LVOLoadView,var(aLoadView));
var(LoadViewJmpTarget)[-1] = (long) var(OldLoadView);
var(OldMoveSprite) = SetFunction(GfxBase,&LVOMoveSprite,var(aMoveSprite));
var(MoveSpriteJmpTarget)[-1] = (long) var(OldMoveSprite);
}
/*
* UnSetVectors()
*
* Put back the old jump vectors for the routines that we replaced.
* Make sure that no one else has replced them behind our backs, however.
* If they are not the same way we left them, return an error status.
*/
int UnSetVectors()
{
long NewCloseScreen,NewBuildSysRequest,NewAutoRequest,
NewLoadView,NewMoveSprite;
int status = TRUE;
NewCloseScreen =
SetFunction(IntuitionBase,&LVOCloseScreen,var(OldCloseScreen));
NewBuildSysRequest =
SetFunction(IntuitionBase,&LVOBuildSysRequest,var(OldBuildSysRequest));
NewAutoRequest =
SetFunction(IntuitionBase,&LVOAutoRequest,var(OldAutoRequest));
NewLoadView = SetFunction(GfxBase,&LVOLoadView,var(OldLoadView));
NewMoveSprite = SetFunction(GfxBase,&LVOMoveSprite,var(OldMoveSprite));
if (NewCloseScreen != (long) var(aCloseScreen) ||
NewBuildSysRequest != (long) var(aBuildSysRequest) ||
NewAutoRequest != (long) var(aAutoRequest) ||
NewLoadView != (long) var(aLoadView) ||
NewMoveSprite != (long) var(aMoveSprite))
{
SetFunction(IntuitionBase,&LVOCloseScreen,NewCloseScreen);
SetFunction(IntuitionBase,&LVOBuildSysRequest,NewBuildSysRequest);
SetFunction(IntuitionBase,&LVOAutoRequest,NewAutoRequest);
SetFunction(GfxBase,&LVOLoadView,NewLoadView);
SetFunction(GfxBase,&LVOMoveSprite,NewMoveSprite);
status = FALSE;
}
return(status);
}
/*
* main()
*
* Look for the vScreen port.
* If one does not exist then vScreen is not currently active, so
* open the intuition and graphics libraries.
* Parse the command-line arguments to get the width, height, and screen.
* Load the handler code, and check its version.
* Create the named port used to store information about the handler.
* Setup some of the variables needed by the handler, and save a pointer
* to the handler data in the named port.
* Try to enlarge the size of the screen bitmap, and set more variables.
* Add the input handler into the input chain.
* SetFunction the neede vectors. At this point vScreen is active.
* Print a message that reports the version numbers.
* Otherwise (the port already exists, so vScreen already is active)
* Get the pointer to the vScreenData structure from the port.
* If they user had supplied arguments, tell him vScreen already is running.
* Try to unset the routines we replaced earlier.
* If the vectors we removed successfully then
* Remove the input handler.
* Restore the screen to its original size.
* Delete the (no-longer-needed) named port.
* Unload the handler code.
* Tell the user that the code is removed.
* Close the libraries (note that these remained open between calls
* to vScreen, while the handler was active).
* Otherwise (we could not replce the function vectors)
* Report the problem, and leave the handler running.
*/
void main(argc,argv)
int argc;
char *argv[];
{
NamedPort = FindPort(PORTNAME);
if (NamedPort == NULL)
{
CheckLibOpen(&IntuitionBase,"intuition.library",INTUITION_REV);
CheckLibOpen(&GfxBase,"graphics.library",GRAPHICS_REV);
ParseArguments(argc,argv);
LoadHandler();
if ((NamedPort = CreateNonSigPort(var(PortName),0L)) == NULL)
DoExit("Can't Create Message Port '%s'",var(PortName));
SetVariables(NamedPort);
Enlarged = EnlargeScreen();
TellInputDevice(IND_ADDHANDLER);
SetVectors();
printf("%s v%d.%d.%d Installed\n",program,
var(MajVers),var(MinVers),var(LoadVers));
} else {
GetVariables(NamedPort);
if (argc > 1)
{
printf("%s already active on screen '%s'\n",program,VScreen->Title);
} else {
if (UnSetVectors())
{
TellInputDevice(IND_REMHANDLER);
RestoreScreen();
DeleteNonSigPort(NamedPort);
UnLoadSeg(var(Segment));
printf("%s Removed\n",program);
CloseLibrary(IntuitionBase);
CloseLibrary(GfxBase);
} else {
printf("SetFunction vectors have been changed!\n");
printf("%s Not Removed\n",program);
}
}
}
}
SHAR_EOF
if test 14176 -ne "`wc -c vScreen.c`"
then
echo shar: error transmitting vScreen.c '(should have been 14176 characters)'
fi
echo shar: extracting vScreenSetup.c '(14356 characters)'
cat << \SHAR_EOF > vScreenSetup.c
/*
* VSCREENSETUP.C Creates virtual screens that can be larger than
* the actual display area of your monitor. The virtual
* screen scrolls when the mouse moves off the edge of
* the display.
*
* Copyright 1988 by Davide P. Cervone, all rights reserved.
*
* You may may distibute this code as is for non-commercial
* purposes, provided that this notice remains intact and the
* documentation file is distributed with it.
*
* You may not modify this code or incorporate it into your
* own programs without the permission of the author.
*/
/*
* WARNING: This code uses and even modifies the INTUITIONPRIVATE
* area of the IntuitionBase structure. Use it at your own risk. It is
* likely to break under a future release of Intuition.
*/
#include "vScreen.h"
struct LayersBase *LayersBase = NULL; /* the Layers Library */
extern struct vScreenInfo *vScreenData; /* the data from the Handler */
extern struct Screen *VScreen; /* the virtual screen pointer */
extern SHORT ScreenWidth,ScreenHeight; /* the new width and height */
static UBYTE OldDepth; /* the screen depth */
extern void CheckLibOpen();
extern void DoExit();
#define BLT_COPY 0xC0 /* blitter copy function */
#define MIN(x,y) (((x)<(y))?(x):(y)) /* MIN macro */
/*
* FindScreen()
*
* If a screen name was specified, look through the Intuition screens
* for the first one that matches the specified name (case does not matter),
* otherwise, use the active screen.
* if the screen was not found, exit with an error message.
*/
struct Screen *FindScreen(ScreenName)
char *ScreenName;
{
struct Screen *theScreen;
Forbid();
if (ScreenName && ScreenName[0])
{
theScreen = IntuitionBase->FirstScreen;
while (theScreen && (theScreen->Title == NULL ||
stricmp(theScreen->Title,ScreenName) != 0))
theScreen = theScreen->NextScreen;
} else {
theScreen = IntuitionBase->ActiveScreen;
}
Permit();
if (theScreen == NULL) DoExit("Can't find screen '%s'",ScreenName);
return(theScreen);
}
/*
* CheckWindows()
*
* Make sure that all the windows on the virtual screen will fit on the
* screen when we reduce it to its original size.
*
* For each window on the screen,
* check that its right edge will be on the smaller-sized screen.
* if not, move it to the left so that it will be.
* if that would move the left egde off the screen, then
* shrink the window so that it fits.
* Check the the bottom edge will be on the smaller screen.
* if no, then move it up so that it will be.
* if that would move the top edge off the screen, then
* shrink the window so that it fits.
* If the window needs to change size or position, do so, and record
* the number of changes made.
*
* if any windows were changed, delay long enough for Intuition to update
* the windows before we actually restore the screen size. (This is a
* kludge, but I don't know a better method that this. You may need to
* adjust the timing factore for busier screens).
*/
static void CheckWindows(theScreen,theWidth,theHeight)
struct Screen *theScreen;
SHORT theWidth,theHeight;
{
struct Window *theWindow;
SHORT x,y, w,h;
SHORT Wx,Wy, Ww,Wh;
short wChanged = 0;
if (theScreen)
{
theWindow = theScreen->FirstWindow;
while (theWindow)
{
Wx = x = theWindow->LeftEdge;
Wy = y = theWindow->TopEdge;
Ww = w = theWindow->Width;
Wh = h = theWindow->Height;
if (x+w > theWidth)
{
x = theWidth - w;
if (x < 0)
{
x = 0;
w = theWidth;
}
}
if (y+h > theHeight)
{
y = theHeight - h;
if (y < 0)
{
y = 0;
h = theHeight;
}
}
if (x != Wx || y != Wy)
{
MoveWindow(theWindow,x-Wx,y-Wy);
wChanged++;
}
if (w != Ww || h != Wh)
{
SizeWindow(theWindow,w-Ww,h-Wh);
wChanged++;
}
theWindow = theWindow->NextWindow;
}
}
if (wChanged) Delay(wChanged * 30L);
}
/*
* GetPlane()
*
* Allocate a bitplane and copy one of the VScren bitplanes into it, then
* free the old bitplane and replace it with the new one.
*
* Two temporary bitmaps are used so that we can call BltBitMap. The
* new bitplane is cleared in case it is larger than the old one, then
* the old one is copied. Since BltBitMap is asynchronous, we call BltClear
* on a dummy section of memory to synchronize with the BltBitMap. That way
* we don't free the old raster until it is fully copied.
*
* GetPlane() is used to get the larger bitmap as well as the smaller one
* when we restore the original screen, so MIN() is used to determine
* the size of the BltBitMap() action.
*/
static int GetPlane(i,Map1,Map2,junk)
int i;
struct BitMap *Map1,*Map2;
UBYTE *junk;
{
int error = TRUE;
long w1 = (Map1->BytesPerRow) << 3;
long h1 = Map1->Rows;
long w2 = (Map2->BytesPerRow) << 3;
long h2 = Map2->Rows;
Map2->Planes[0] = VScreen->BitMap.Planes[i];
Map1->Planes[0] = AllocRaster(w1,h1);
if (Map1->Planes[0])
{
BltClear(Map1->Planes[0],RASSIZE(w1,h1),0L);
BltBitMap(Map2,0L,0L,Map1,0L,0L,MIN(w1,w2),MIN(h1,h2),BLT_COPY,0xFF,NULL);
BltClear(junk,8L,0L); /* synchronize with BltBitMap */
VScreen->BitMap.Planes[i] = Map1->Planes[0];
FreeRaster(Map2->Planes[0],w2,h2);
error = FALSE;
}
return(error);
}
/*
* GetBitMap()
*
* GetBitMap allocates and copies a new, larger bitmap for the virtual
* screen. It does so one plane at a time, however, in order avoid having
* the complete old screen and the complete new screen in memory at the
* same time. Two temporary bitmaps are used to perform the single-plane
* copies. The junk memory is used to synchronize the BltBitMap calls (see
* GetPlane() above).
*
* For each bitplane in the screen, get a new plane of the proper
* size. If the allocation fails, try to clean up (it's usually too
* late, however).
*
* Modify the screen's bitmap to reflect the changed size.
* Free the junk space.
*/
static void GetBitMap()
{
struct BitMap MyBitMap;
struct BitMap theBitMap;
int i;
UBYTE *junk;
junk = AllocMem(8L,MEMF_CHIP);
InitBitMap(&MyBitMap,1L,ScreenWidth,ScreenHeight);
InitBitMap(&theBitMap,1L,VAR(OldWidth),VAR(OldHeight));
for (i=0; iBitMap.BytesPerRow = MyBitMap.BytesPerRow;
VScreen->BitMap.Rows = MyBitMap.Rows;
FreeMem(junk,8L);
}
/*
* FreeBitMap()
*
* Similar to GetBitMap, except that FreeBitMap trys to allocate a bitmap
* the size of the original screen.
*/
static void FreeBitMap()
{
struct BitMap MyBitMap;
struct BitMap theBitMap;
short i;
UBYTE *junk;
junk = AllocMem(8L,MEMF_CHIP);
InitBitMap(&MyBitMap,1L,ScreenWidth,ScreenHeight);
InitBitMap(&theBitMap,1L,VAR(OldWidth),VAR(OldHeight));
for (i=0; iBitMap.BytesPerRow = theBitMap.BytesPerRow;
VScreen->BitMap.Rows = theBitMap.Rows;
FreeMem(junk,8L);
}
/*
* SetClipRects()
*
* Since the screen size is changing, we need to modify the ClipRects
* for the menubar's Layer. This allows the layer to update itself
* properly.
*
* Set the menubar bounds-rectangle size.
* For each ClipRect in the menubar layer,
* If the bounds-rectangle's right edge is at the edge of the old screen
* then set it to be the edge of the new screen.
*/
static void SetClipRects(OldX,NewX)
WORD OldX,NewX;
{
struct ClipRect *theClipRect = VScreen->BarLayer->ClipRect;
OldX--; NewX--;
VScreen->BarLayer->bounds.MaxX = NewX;
while (theClipRect)
{
if (theClipRect->bounds.MaxX == OldX)
theClipRect->bounds.MaxX = NewX;
theClipRect = theClipRect->Next;
}
}
/*
* EnlargeScreen()
*
* Store the current state of the screen and change what needs to be
* changed in order to make it bigger.
*
* Open the Layers Library so that we can call LockLayers().
* Lock the Layers for the screen. The Forbid() may not be necessary.
*
* Get the HIRES and LACE flags for the screen. Set up the Shift values
* needed to convert the screen's local coordinates to actual display
* coordinates (always considered 640 x 400 mode).
*
* Get the pointers to the RxOffset and RyOffset variables of the RasInfo
* for the ViewPort of the virtual Screen. These are what tell the
* graphics library which part of the bitmap to display. These are what
* make it possible to scroll the screen quickly and easily. Without them,
* vScreen would be impossible, but luckily, the graphics library knows how
* to use them. Unfortunately, Intuition does not, so we have to bend
* over backwards to fool intuition. See vScreen-Handler.c for details.
*
* Get the old width and height of the screen, and the depth.
* Get the new, larger bitplanes for the screen.
*
* Set the screen width and height, and repair the ClipRects in the
* menubar Layer.
*
* Get the old MaxDisplay values.
*
* Call the handler's SetVScreen() routine (it sets the MaxDisplay
* values, the Max and Min Mouse values, and some other stuff),
* and the FixView() routine, which calls MakeVPort() and MrgCop() to
* incorporate the screen changes into the Intuition View structure.
* Finally, load the new View so taht the larger screen will be displayed.
*
* Unlock the layers and close the library.
*
* Call ShowTitle, so that the menubar layer will be updated (so that
* it is as wide as the new screen).
*/
void EnlargeScreen()
{
CheckLibOpen(&LayersBase,"layers.library",LAYERS_REV);
LockLayers(&(VScreen->LayerInfo));
Forbid();
VAR(HiResScreen) = (VScreen->ViewPort.Modes & HIRES);
VAR(LaceScreen) = (VScreen->ViewPort.Modes & LACE);
VAR(HiResShift) = (VAR(HiResScreen))? 0: 1;
VAR(LaceShift) = (VAR(LaceScreen))? 0: 1;
VAR(RxOffset) = &(VScreen->ViewPort.RasInfo->RxOffset);
VAR(RyOffset) = &(VScreen->ViewPort.RasInfo->RyOffset);
VAR(RxOffset2) = (*(VAR(RxOffset))) << VAR(HiResShift);
VAR(RyOffset2) = (*(VAR(RyOffset))) << VAR(LaceShift);
VAR(OldWidth) = VScreen->Width;
VAR(OldHeight) = VScreen->Height;
OldDepth = VScreen->BitMap.Depth;
GetBitMap();
VScreen->Width = ScreenWidth;
VScreen->Height = ScreenHeight;
SetClipRects(VAR(OldWidth),ScreenWidth);
VAR(OldMaxDH) = IntuitionBase->MaxDisplayHeight;
VAR(OldMaxDR) = IntuitionBase->MaxDisplayRow;
VAR(OldMaxDW) = IntuitionBase->MaxDisplayWidth;
VAR(SetVScreen)();
VAR(FixView)(TRUE);
LoadView(&(IntuitionBase->ViewLord));
Permit();
UnlockLayers(&(VScreen->LayerInfo));
CloseLibrary(LayersBase); LayersBase = NULL;
ShowTitle(VScreen,(VScreen->Flags & SHOWTITLE)? TRUE: FALSE);
}
/*
* RestoreScreen()
*
* If the screen still exists (i.e.,it was not closed while vScreen was
* running), then check the windows to be sure that they all will fit on
* the original-sized screen.
* Open the Layers Library, and lock the screen layers.
* Reset the old screen size, and set the menubar ClipRects to the old size.
* Set the offsets to zero, and call the Handler's ResetVScreen() routine
* (which resets Intuitions MaxDisplay and Min and Max Mouse fields).
* Get the screen depth and restore the old bitmap.
* Finally, unlock the screen, and remake the Intuition display so that
* the new sized screen is displayed.
* update the title bar so that it is the right size.
*/
void RestoreScreen()
{
if (VScreen)
{
CheckWindows(VScreen,VAR(OldWidth),VAR(OldHeight));
CheckLibOpen(&LayersBase,"layers.library",LAYERS_REV);
LockLayers(&(VScreen->LayerInfo));
Forbid();
VScreen->Width = VAR(OldWidth);
VScreen->Height = VAR(OldHeight);
SetClipRects(ScreenWidth,VAR(OldWidth));
*(VAR(RxOffset)) = 0;
*(VAR(RyOffset)) = 0;
VAR(ResetVScreen)();
OldDepth = VScreen->BitMap.Depth;
FreeBitMap();
Permit();
UnlockLayers(&(VScreen->LayerInfo));
CloseLibrary(LayersBase); LayersBase = NULL;
RemakeDisplay();
ShowTitle(VScreen,(VScreen->Flags & SHOWTITLE)? TRUE: FALSE);
}
}
/*
* SetVariables()
*
* Store that vScreenData pointer in the MsgPort structure so we can look
* it up later (in order to remove the handler). Save the library pointers
* so that the handler can use them, and save the pointer to the virtual
* screen abd its new width and height.
*/
void SetVariables(NamedPort)
struct MsgPort *NamedPort;
{
NamedPort->mp_SigTask = (struct Task *) vScreenData;
VAR(IntuitionBase) = IntuitionBase;
VAR(GfxBase) = GfxBase;
VAR(VScreen) = VScreen;
VAR(ScreenWidth) = ScreenWidth;
VAR(ScreenHeight) = ScreenHeight;
}
/*
* GetVariables()
*
* Retrieve the vScreenData pointer from the MsgPort were we stored it
* earlier. Get back the library pointers so that we can use them and close
* them. Get back the pointer to the virtual screen and its new width
* and height.
*/
void GetVariables(NamedPort)
struct MsgPort *NamedPort;
{
vScreenData = (struct vScreenInfo *) (NamedPort->mp_SigTask);
IntuitionBase = VAR(IntuitionBase);
GfxBase = VAR(GfxBase);
VScreen = VAR(VScreen);
ScreenWidth = VAR(ScreenWidth);
ScreenHeight = VAR(ScreenHeight);
}
SHAR_EOF
if test 14356 -ne "`wc -c vScreenSetup.c`"
then
echo shar: error transmitting vScreenSetup.c '(should have been 14356 characters)'
fi
echo shar: extracting wList.c '(2260 characters)'
cat << \SHAR_EOF > wList.c
#include
#include
#include
#include
#include
#define INTUITION_REV 0L
extern struct IntuitionBase *IntuitionBase;
extern struct IntuitionBase *OpenLibrary();
static void ShowUsage()
{
printf("Usage: WLIST [screen]\n");
exit(10L);
}
static struct Screen *FindScreen(ScreenName)
char *ScreenName;
{
struct Screen *theScreen;
if (ScreenName && ScreenName[0])
{
Forbid();
theScreen = IntuitionBase->FirstScreen;
while (theScreen && (theScreen->Title == NULL ||
stricmp(theScreen->Title,ScreenName) != 0))
theScreen = theScreen->NextScreen;
Permit();
} else {
Forbid();
theScreen = IntuitionBase->FirstScreen;
Permit();
}
if (theScreen == NULL)
{
Permit();
printf("Can't find screen '%s'\n",ScreenName);
exit(10L);
}
return(theScreen);
}
static void PrintWindowTitle(theWindow)
struct Window *theWindow;
{
if (theWindow && theWindow->Title)
printf(" '%s'\n",theWindow->Title);
else
printf(" [No Title]\n");
}
static void PrintScreenTitle(theScreen)
struct Screen *theScreen;
{
if (theScreen && theScreen->Title)
printf("'%s'\n",theScreen->Title);
else
printf("[No Title]\n");
}
static void PrintScreenWindows(theScreen)
struct Screen *theScreen;
{
struct Window *theWindow = theScreen->FirstWindow;
while (theWindow)
{
PrintWindowTitle(theWindow);
theWindow = theWindow->NextWindow;
}
}
void main(argc,argv)
int argc;
char *argv[];
{
char *ScreenName = NULL;
struct Screen *theScreen;
if (argc > 2) ShowUsage();
if (argc > 1 && argv[1] && argv[1][0] != '\0') ScreenName = argv[1];
IntuitionBase = OpenLibrary("intuition.library",INTUITION_REV);
if (IntuitionBase)
{
theScreen = FindScreen(ScreenName);
printf("\n");
while (theScreen)
{
PrintScreenTitle(theScreen);
PrintScreenWindows(theScreen);
if (ScreenName)
theScreen = NULL;
else
theScreen = theScreen->NextScreen;
}
printf("\n");
CloseLibrary(IntuitionBase);
}
}
SHAR_EOF
if test 2260 -ne "`wc -c wList.c`"
then
echo shar: error transmitting wList.c '(should have been 2260 characters)'
fi
echo shar: extracting wMax.c '(2831 characters)'
cat << \SHAR_EOF > wMax.c
#include
#include
#include
#include
#include
#define INTUITION_REV 0L
extern struct IntuitionBase *IntuitionBase;
extern struct IntuitionBase *OpenLibrary();
static void ShowUsage()
{
printf("Usage: WMAX x y [window [screen]]\n");
exit(10L);
}
static void GetInt(i,s)
long *i;
char *s;
{
if (sscanf(s,"%ld",i) != 1) ShowUsage();
}
static struct Screen *FindScreen(ScreenName)
char *ScreenName;
{
struct Screen *theScreen;
if (ScreenName && ScreenName[0])
{
theScreen = IntuitionBase->FirstScreen;
while (theScreen && (theScreen->Title == NULL ||
stricmp(theScreen->Title,ScreenName) != 0))
theScreen = theScreen->NextScreen;
} else {
theScreen = IntuitionBase->ActiveScreen;
}
if (theScreen == NULL)
{
Permit();
printf("Can't find screen '%s'\n",ScreenName);
exit(10L);
}
return(theScreen);
}
static struct Window *FindWindow(WindowName,theScreen)
char *WindowName;
struct Screen *theScreen;
{
struct Window *theWindow;
if (WindowName && WindowName[0])
{
theWindow = theScreen->FirstWindow;
while (theWindow && (theWindow->Title == NULL ||
stricmp(theWindow->Title,WindowName) != 0))
theWindow = theWindow->NextWindow;
} else {
theWindow = IntuitionBase->ActiveWindow;
}
if (theWindow == NULL)
{
Permit();
printf("Can't find window '%s' on screen '%s'\n",
WindowName,theScreen->Title);
exit(10L);
}
Permit();
return(theWindow);
}
void main(argc,argv)
int argc;
char *argv[];
{
char *WindowName = NULL;
char *ScreenName = NULL;
long x,y;
struct Window *theWindow;
struct Screen *theScreen;
if (argc < 3 || argc > 5) ShowUsage();
GetInt(&x,argv[1]);
GetInt(&y,argv[2]);
if (argc > 3 && argv[3] && argv[3][0] != '\0') WindowName = argv[3];
if (argc > 4 && argv[4] && argv[4][0] != '\0') ScreenName = argv[4];
IntuitionBase = OpenLibrary("intuition.library",INTUITION_REV);
if (IntuitionBase)
{
Forbid();
theScreen = FindScreen(ScreenName);
theWindow = FindWindow(WindowName,theScreen);
Permit();
printf("\nWindow '%s' on Screen '%s'\n",
theWindow->Title,theWindow->WScreen->Title);
printf(" Old Max: (%d,%d) Old Min: (%d,%d)\n",
theWindow->MaxWidth,theWindow->MaxHeight,
theWindow->MinWidth,theWindow->MinHeight);
if (x || y)
{
Forbid();
theWindow->MaxWidth = x;
theWindow->MaxHeight = y;
Permit();
printf(" New Max: (%d,%d)\n\n",
theWindow->MaxWidth,theWindow->MaxHeight);
}
CloseLibrary(IntuitionBase);
}
}
SHAR_EOF
if test 2831 -ne "`wc -c wMax.c`"
then
echo shar: error transmitting wMax.c '(should have been 2831 characters)'
fi
echo shar: extracting wMove.c '(3182 characters)'
cat << \SHAR_EOF > wMove.c
#include
#include
#include
#include
#include
#define INTUITION_REV 0L
extern struct IntuitionBase *IntuitionBase;
extern struct IntuitionBase *OpenLibrary();
static void ShowUsage()
{
printf("Usage: WMOVE dx dy [window [screen]]\n");
exit(10L);
}
static void GetInt(i,s)
long *i;
char *s;
{
if (sscanf(s,"%ld",i) != 1) ShowUsage();
}
static struct Screen *FindScreen(ScreenName)
char *ScreenName;
{
struct Screen *theScreen;
if (ScreenName && ScreenName[0])
{
theScreen = IntuitionBase->FirstScreen;
while (theScreen && (theScreen->Title == NULL ||
stricmp(theScreen->Title,ScreenName) != 0))
theScreen = theScreen->NextScreen;
} else {
theScreen = IntuitionBase->ActiveScreen;
}
if (theScreen == NULL)
{
Permit();
printf("Can't find screen '%s'\n",ScreenName);
exit(10L);
}
return(theScreen);
}
static struct Window *FindWindow(WindowName,theScreen)
char *WindowName;
struct Screen *theScreen;
{
struct Window *theWindow;
if (WindowName && WindowName[0])
{
theWindow = theScreen->FirstWindow;
while (theWindow && (theWindow->Title == NULL ||
stricmp(theWindow->Title,WindowName) != 0))
theWindow = theWindow->NextWindow;
} else {
theWindow = IntuitionBase->ActiveWindow;
}
if (theWindow == NULL)
{
Permit();
printf("Can't find window '%s' on screen '%s'\n",
WindowName,theScreen->Title);
exit(10L);
}
Permit();
return(theWindow);
}
void main(argc,argv)
int argc;
char *argv[];
{
char *WindowName = NULL;
char *ScreenName = NULL;
long dx,dy;
struct Window *theWindow;
struct Screen *theScreen;
if (argc < 3 || argc > 5) ShowUsage();
GetInt(&dx,argv[1]);
GetInt(&dy,argv[2]);
if (argc > 3 && argv[3] && argv[3][0] != '\0') WindowName = argv[3];
if (argc > 4 && argv[4] && argv[4][0] != '\0') ScreenName = argv[4];
IntuitionBase = OpenLibrary("intuition.library",INTUITION_REV);
if (IntuitionBase)
{
Forbid();
theScreen = FindScreen(ScreenName);
theWindow = FindWindow(WindowName,theScreen);
Permit();
if (dx < -(theWindow->LeftEdge)) dx = -(theWindow->LeftEdge);
if (dy < -(theWindow->TopEdge)) dy = -(theWindow->TopEdge);
if (theWindow->LeftEdge + dx + theWindow->Width > theScreen->Width)
dx = theScreen->Width - theWindow->Width - theWindow->LeftEdge;
if (theWindow->TopEdge + dy + theWindow->Height > theScreen->Height)
dy = theScreen->Height - theWindow->Height - theWindow->TopEdge;
printf("\nWindow '%s' on Screen '%s'\n",
theWindow->Title,theWindow->WScreen->Title);
printf(" Old position: (%d,%d)\n",
theWindow->LeftEdge,theWindow->TopEdge);
if (dx || dy)
{
printf(" New position: (%d,%d)\n Changed: (%d,%d)\n\n",
theWindow->LeftEdge+dx,theWindow->TopEdge+dy,dx,dy);
MoveWindow(theWindow,dx,dy);
}
CloseLibrary(IntuitionBase);
}
}
SHAR_EOF
if test 3182 -ne "`wc -c wMove.c`"
then
echo shar: error transmitting wMove.c '(should have been 3182 characters)'
fi
echo shar: extracting wSize.c '(3542 characters)'
cat << \SHAR_EOF > wSize.c
#include
#include
#include
#include
#include
#define INTUITION_REV 0L
extern struct IntuitionBase *IntuitionBase;
extern struct IntuitionBase *OpenLibrary();
static void ShowUsage()
{
printf("Usage: WSIZE dx dy [window [screen [IGNOREMAX]]\n");
exit(10L);
}
static void GetInt(i,s)
long *i;
char *s;
{
if (sscanf(s,"%ld",i) != 1) ShowUsage();
}
static struct Screen *FindScreen(ScreenName)
char *ScreenName;
{
struct Screen *theScreen;
if (ScreenName && ScreenName[0])
{
theScreen = IntuitionBase->FirstScreen;
while (theScreen && (theScreen->Title == NULL ||
stricmp(theScreen->Title,ScreenName) != 0))
theScreen = theScreen->NextScreen;
} else {
theScreen = IntuitionBase->ActiveScreen;
}
if (theScreen == NULL)
{
Permit();
printf("Can't find screen '%s'\n",ScreenName);
exit(10L);
}
return(theScreen);
}
static struct Window *FindWindow(WindowName,theScreen)
char *WindowName;
struct Screen *theScreen;
{
struct Window *theWindow;
if (WindowName && WindowName[0])
{
theWindow = theScreen->FirstWindow;
while (theWindow && (theWindow->Title == NULL ||
stricmp(theWindow->Title,WindowName) != 0))
theWindow = theWindow->NextWindow;
} else {
theWindow = IntuitionBase->ActiveWindow;
}
if (theWindow == NULL)
{
Permit();
printf("Can't find window '%s' on screen '%s'\n",
WindowName,theScreen->Title);
exit(10L);
}
Permit();
return(theWindow);
}
void main(argc,argv)
int argc;
char *argv[];
{
char *WindowName = NULL;
char *ScreenName = NULL;
long dx,dy;
struct Window *theWindow;
struct Screen *theScreen;
long UseMax = TRUE;
if (argc < 3 || argc > 6) ShowUsage();
GetInt(&dx,argv[1]);
GetInt(&dy,argv[2]);
if (argc > 3 && argv[3] && argv[3][0] != '\0') WindowName = argv[3];
if (argc > 4 && argv[4] && argv[4][0] != '\0') ScreenName = argv[4];
if (argc > 5) UseMax = FALSE;
IntuitionBase = OpenLibrary("intuition.library",INTUITION_REV);
if (IntuitionBase)
{
Forbid();
theScreen = FindScreen(ScreenName);
theWindow = FindWindow(WindowName,theScreen);
Permit();
if (theWindow->LeftEdge + theWindow->Width + dx > theScreen->Width)
dx = theScreen->Width - theWindow->LeftEdge - theWindow->Width;
if (theWindow->Width + dx < theWindow->MinWidth)
dx = theWindow->MinWidth - theWindow->Width;
if (theWindow->Width + dx > theWindow->MaxWidth && UseMax)
dx = theWindow->MaxWidth - theWindow->Width;
if (theWindow->TopEdge + theWindow->Height + dy > theScreen->Height)
dy = theScreen->Height - theWindow->TopEdge - theWindow->Height;
if (theWindow->Height + dy < theWindow->MinHeight)
dy = theWindow->MinHeight - theWindow->Height;
if (theWindow->Height + dy > theWindow->MaxHeight && UseMax)
dy = theWindow->MaxHeight - theWindow->Height;
printf("\nWindow '%s' on Screen '%s'\n",
theWindow->Title,theWindow->WScreen->Title);
printf(" Old size: (%d,%d)\n",theWindow->Width,theWindow->Height);
if (dx || dy)
{
printf(" New size: (%d,%d)\n Changed: (%d,%d)\n\n",
theWindow->Width+dx,theWindow->Height+dy,dx,dy);
SizeWindow(theWindow,dx,dy);
}
CloseLibrary(IntuitionBase);
}
}
SHAR_EOF
if test 3542 -ne "`wc -c wSize.c`"
then
echo shar: error transmitting wSize.c '(should have been 3542 characters)'
fi
# End of shell archive
exit 0