arosc.library: Centralized exit handling code in __arosc_startup.c
[AROS.git] / workbench / demos / lens.c
blobc43f38464e015ed62e9b53477e48931da5d22336
3 #include <dos/dos.h>
4 #include <intuition/intuition.h>
5 #include <graphics/gfx.h>
6 #include <graphics/scale.h>
7 #include <utility/hooks.h>
8 #include <dos/rdargs.h>
10 #include <proto/exec.h>
11 #include <proto/intuition.h>
12 #include <proto/graphics.h>
13 #include <proto/layers.h>
14 #include <proto/dos.h>
16 #include <aros/asmcall.h>
17 #include <aros/libcall.h>
19 #include <stdio.h>
20 #include <stdlib.h>
22 struct IntuitionBase *IntuitionBase;
23 struct GfxBase *GfxBase;
24 struct Library *LayersBase;
26 static struct Screen *scr;
27 static struct Window *win;
28 static struct DrawInfo *dri;
29 static struct BitMap *scalebitmap;
31 static BOOL follow = FALSE;
32 static BOOL do_lens = FALSE;
34 AROS_UFP3(void, LensCallback,
35 AROS_UFPA(struct Hook *, hook , A0),
36 AROS_UFPA(struct Layer *, l , A2),
37 AROS_UFPA(struct CollectPixelsLayerMsg *, cplm , A1));
40 struct LensParam
42 struct Window * win;
43 LONG dx,dy;
46 static void Cleanup(char *msg)
48 WORD rc;
50 if (msg)
52 printf("lens: %s\n",msg);
53 rc = RETURN_WARN;
54 } else {
55 rc = RETURN_OK;
58 if (scalebitmap) FreeBitMap(scalebitmap);
60 if (win) CloseWindow(win);
62 if (dri) FreeScreenDrawInfo(scr,dri);
63 UnlockPubScreen(0,scr);
66 if (LayersBase) CloseLibrary(LayersBase);
67 if (GfxBase) CloseLibrary((struct Library *)GfxBase);
68 if (IntuitionBase) CloseLibrary((struct Library *)IntuitionBase);
70 exit(rc);
73 static void OpenLibs(void)
75 if (!(IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library",39)))
77 Cleanup("Can't open intuition.library V39!");
80 if (!(GfxBase = (struct GfxBase *)OpenLibrary("graphics.library",39)))
82 Cleanup("Can't open graphics.library V39!");
85 if (!(LayersBase = OpenLibrary("layers.library",39)))
87 Cleanup("Can't open layers.library V39!");
92 static void GetVisual(void)
94 if (!(scr = LockPubScreen(0)))
96 Cleanup("Can't lock pub screen!");
99 if (!(dri = GetScreenDrawInfo(scr)))
101 Cleanup("Can't get drawinfo!");
106 * The ScaleLayer callback is doing the actul work of
107 * scaling the layer.
109 AROS_UFH3(void, LensCallback,
110 AROS_UFHA(struct Hook *, hook , A0),
111 AROS_UFHA(struct Layer *, l , A2),
112 AROS_UFHA(struct CollectPixelsLayerMsg *, cplm , A1))
114 AROS_USERFUNC_INIT
115 struct LensParam * lp = (struct LensParam *)hook->h_Data;
116 if (NULL != cplm->bm) {
118 if (FALSE == do_lens) {
120 * Does a 1:1 copying
122 BltBitMapRastPort(
123 cplm->bm,
124 cplm->xSrc,
125 cplm->ySrc,
126 win->RPort,
127 cplm->xDest - win->LeftEdge - lp->dx + win->Width/2,
128 cplm->yDest - win->TopEdge - lp->dy + win->Height/2,
129 cplm->width,
130 cplm->height,
131 cplm->minterm);
132 } else {
134 * This is just a hack for now...
135 * Need to adjust the destination x/y coordinates
136 * in accordance to the source x/y coordinates taken
137 * from the absolute coordinates of the source.
139 struct BitScaleArgs bsa;
140 bsa.bsa_SrcX = cplm->xSrc;
141 bsa.bsa_SrcY = cplm->ySrc;
142 bsa.bsa_SrcWidth = cplm->width;
143 bsa.bsa_SrcHeight = cplm->height;
144 bsa.bsa_DestX = 0;
145 bsa.bsa_DestY = 0;
146 bsa.bsa_DestWidth = cplm->width*2;
147 bsa.bsa_DestHeight = cplm->height*2;
148 bsa.bsa_XSrcFactor = cplm->width;
149 bsa.bsa_XDestFactor = cplm->width*2;
150 bsa.bsa_YSrcFactor = cplm->height;
151 bsa.bsa_YDestFactor = cplm->height*2;
152 bsa.bsa_SrcBitMap = cplm->bm;
153 bsa.bsa_DestBitMap = scalebitmap;
154 BitMapScale(&bsa);
157 * Display the scaled content.
159 BltBitMapRastPort(
160 scalebitmap,
161 bsa.bsa_DestX,
162 bsa.bsa_DestY,
163 win->RPort,
164 bsa.bsa_DestX,
165 bsa.bsa_DestY,
166 cplm->width*2,//bsa.bsa_DestWidth,
167 cplm->height*2,//bsa.bsa_DestHeight,
168 cplm->minterm);
171 AROS_USERFUNC_EXIT
175 static void DoLens(struct Window * win, LONG dx, LONG dy)
177 struct Region * r = NewRegion();
178 struct Rectangle rect;
179 struct Layer * l = win->RPort->Layer;
180 struct Hook h;
181 struct LensParam lp = {win,dx,dy};
182 ULONG QWidth = win->Width / 4;
183 ULONG QHeight = win->Height / 4;
184 ULONG HWidth = win->Width / 2;
185 ULONG HHeight = win->Height / 2;
186 h.h_Entry = (IPTR (*)())LensCallback;
187 h.h_Data = (void *)&lp;
189 rect.MinX = dx + win->LeftEdge + QWidth - HWidth;
190 rect.MinY = dy + win->TopEdge + QHeight - HHeight;
191 rect.MaxX = dx + win->LeftEdge + win->Width - 1 - QWidth - HWidth;
192 rect.MaxY = dy + win->TopEdge + win->Height - 1 - QHeight- HHeight;
194 if (rect.MinX < 0)
195 rect.MinX = 0;
197 if (rect.MinY < 0)
198 rect.MinY = 0;
200 OrRectRegion(r, &rect);
202 CollectPixelsLayer(l->back,
204 &h);
206 DisposeRegion(r);
210 static void MakeWin(void)
212 if (!(win = OpenWindowTags(0,WA_PubScreen,(IPTR)scr,
213 WA_Left,10,
214 WA_Top,10,
215 WA_Width,200,
216 WA_Height,100,
217 WA_AutoAdjust,TRUE,
218 WA_SmartRefresh,TRUE,
219 WA_CloseGadget,TRUE,
220 WA_DepthGadget,FALSE,
221 WA_DragBar,FALSE,
222 WA_IDCMP,IDCMP_REFRESHWINDOW | IDCMP_MOUSEMOVE | IDCMP_DELTAMOVE | IDCMP_CLOSEWINDOW,
223 WA_ReportMouse, TRUE,
224 TAG_DONE)))
226 Cleanup("Can't open window!");
228 scalebitmap = AllocBitMap(win->Width,
229 win->Height,
230 GetBitMapAttr(win->RPort->BitMap, BMA_DEPTH),
231 BMF_CLEAR,
232 scr->RastPort.BitMap
236 DoLens(win,0,0);
238 ScreenToFront(win->WScreen);
241 static void HandleAll(void)
243 struct IntuiMessage *msg;
245 BOOL quitme = FALSE;
247 while (!quitme)
249 WaitPort(win->UserPort);
251 while ((msg = (struct IntuiMessage *)GetMsg(win->UserPort)))
253 switch (msg->Class)
255 case IDCMP_CLOSEWINDOW:
256 quitme = TRUE;
257 break;
259 case IDCMP_REFRESHWINDOW:
260 BeginRefresh(win);
261 EndRefresh(win,TRUE);
262 break;
264 case IDCMP_MOUSEMOVE:
265 if (win == msg->IDCMPWindow) {
266 printf("mouse move %d/%d!\n",
267 msg->MouseX,
268 msg->MouseY);
269 if (TRUE == follow) {
270 MoveWindow(win,
271 win->MouseX, // - win->LeftEdge,
272 win->MouseY //- win->TopEdge
274 DoLens(win,0,0);
275 } else {
277 * Keep window still;
278 * this works, but center is a bit off.
280 DoLens(win,win->MouseX,win->MouseY);
283 break;
285 case IDCMP_DELTAMOVE:
286 printf("delta move!");
287 break;
290 ReplyMsg((struct Message *)msg);
295 void ParseArgs(void)
297 STRPTR args[2] = {(STRPTR)FALSE, (STRPTR)FALSE};
298 struct RDArgs * rda;
299 rda = ReadArgs("FOLLOW/S,LENS/S",(IPTR *)args, NULL);
300 if (TRUE == (IPTR)args[0]) {
301 follow = TRUE;
303 if (TRUE == (IPTR)args[1]) {
304 do_lens = TRUE;
307 if (rda) {
308 FreeArgs(rda);
313 int main(int argc, char **argv)
315 ParseArgs();
316 OpenLibs();
317 GetVisual();
318 MakeWin();
319 HandleAll();
320 Cleanup(0);
322 return 0;