/* The following example shows the use of the layers library call ** InstallClipRegion(), as well as simple use of the graphics library ** regions functions. Be aware that it uses Release 2 functions for ** opening and closing Intuition windows. ** ** clipping.c ** ** SAS/C 5.10a ** lc -b1 -cfist -v -y clipping ** blink FROM LIB:c.o clipping.o TO clipping LIB LIB:lc.lib LIB:amiga.lib */ /* Force use of new variable names to help prevent errors */ #define INTUI_V36_NAMES_ONLY #include <exec/types.h> #include <intuition/intuition.h> #include <intuition/intuitionbase.h> #include <graphics/displayinfo.h> #include <clib/exec_protos.h> #include <clib/dos_protos.h> #include <clib/intuition_protos.h> #include <clib/graphics_protos.h> #include <clib/layers_protos.h> #include <stdio.h> #ifdef LATTICE int CXBRK(void) { return(0); } /* Disable Lattice CTRL/C handling */ int chkabort(void) { return(0); } /* really */ #endif #define MY_WIN_WIDTH (300) #define MY_WIN_HEIGHT (100) struct IntuitionBase *IntuitionBase; struct GfxBase *GfxBase; struct Library *LayersBase; /* ** unclipWindow() ** ** Used to remove a clipping region installed by clipWindow() or ** clipWindowToBorders(), disposing of the installed region and ** reinstalling the region removed. */ void unclipWindow(struct Window *win) { struct Region *old_region; /* Remove any old region by installing a NULL region, ** then dispose of the old region if one was installed. */ if (NULL != (old_region = InstallClipRegion(win->WLayer, NULL))) DisposeRegion(old_region); } /* ** clipWindow() ** Clip a window to a specified rectangle (given by upper left and ** lower right corner.) the removed region is returned so that it ** may be re-installed later. */ struct Region *clipWindow(struct Window *win, LONG minX, LONG minY, LONG maxX, LONG maxY) { struct Region *new_region; struct Rectangle my_rectangle; /* set up the limits for the clip */ my_rectangle.MinX = minX; my_rectangle.MinY = minY; my_rectangle.MaxX = maxX; my_rectangle.MaxY = maxY; /* get a new region and OR in the limits. */ if (NULL != (new_region = NewRegion())) { if (FALSE == OrRectRegion(new_region, &my_rectangle)) { DisposeRegion(new_region); new_region = NULL; } } /* Install the new region, and return any existing region. ** If the above allocation and region processing failed, then ** new_region will be NULL and no clip region will be installed. */ return(InstallClipRegion(win->WLayer, new_region)); } /* ** clipWindowToBorders() ** clip a window to its borders. ** The removed region is returned so that it may be re-installed later. */ struct Region *clipWindowToBorders(struct Window *win) { return(clipWindow(win, win->BorderLeft, win->BorderTop, win->Width - win->BorderRight - 1, win->Height - win->BorderBottom - 1)); } /* ** Wait for the user to select the close gadget. */ VOID wait_for_close(struct Window *win) { struct IntuiMessage *msg; SHORT done; done = FALSE; while (FALSE == done) { /* we only have one signal bit, so we do not have to check which ** bit broke the Wait(). */ Wait(1L << win->UserPort->mp_SigBit); while ( (FALSE == done) && (NULL != (msg = (struct IntuiMessage *)GetMsg(win->UserPort)))) { /* use a switch statement if looking for multiple event types */ if (msg->Class == IDCMP_CLOSEWINDOW) done = TRUE; ReplyMsg((struct Message *)msg); } } } /* ** Simple routine to blast all bits in a window with color three to show ** where the window is clipped. After a delay, flush back to color zero ** and refresh the window borders. */ VOID draw_in_window(struct Window *win, UBYTE *message) { printf("%s...", message); fflush(stdout); SetRast(win->RPort, 3); Delay(200); SetRast(win->RPort, 0); RefreshWindowFrame(win); printf("done\n"); } /* ** Show drawing into an unclipped window, a window clipped to the ** borders and a window clipped to a random rectangle. It is possible ** to clip more complex shapes by AND'ing, OR'ing and exclusive-OR'ing ** regions and rectangles to build a user clip region. ** ** This example assumes that old regions are not going to be re-used, ** so it simply throws them away. */ VOID clip_test(struct Window *win) { struct Region *old_region; draw_in_window(win,"Window with no clipping"); /* if the application has never installed a user clip region, ** then old_region will be NULL here. Otherwise, delete the ** old region (you could save it and re-install it later...) */ if (NULL != (old_region = clipWindowToBorders(win))) DisposeRegion(old_region); draw_in_window(win,"Window clipped to window borders"); unclipWindow(win); /* here we know old_region will be NULL, as that is what we ** installed with unclipWindow()... */ if (NULL != (old_region = clipWindow(win,20,20,100,50))) DisposeRegion(old_region); draw_in_window(win,"Window clipped from (20,20) to (100,50)"); unclipWindow(win); wait_for_close(win); } /* ** Open and close resources, call the test routine when ready. */ VOID main(int argc, char **argv) { struct Window *win; if (NULL != (IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library",37))) { if (NULL != (GfxBase = (struct GfxBase *)OpenLibrary("graphics.library",37))) { if (NULL != (LayersBase = OpenLibrary("layers.library",37))) { if (NULL != (win = OpenWindowTags(NULL, WA_Width, MY_WIN_WIDTH, WA_Height, MY_WIN_HEIGHT, WA_IDCMP, IDCMP_CLOSEWINDOW, WA_CloseGadget, TRUE, WA_DragBar, TRUE, WA_Activate, TRUE, TAG_END))) { clip_test(win); CloseWindow(win); } CloseLibrary(LayersBase); } CloseLibrary((struct Library *)GfxBase); } CloseLibrary((struct Library *)IntuitionBase); } }