Changed installation directories.
[AROS-Contrib.git] / bgui / blitter.c
blob67f8ec4e900ff43da5830d185ebdbacdbdbc7a89
1 /*
2 * @(#) $Header$
4 * BGUI library
5 * blitter.c
7 * (C) Copyright 1998 Manuel Lemos.
8 * (C) Copyright 1996-1997 Ian J. Einman.
9 * (C) Copyright 1993-1996 Jaba Development.
10 * (C) Copyright 1993-1996 Jan van den Baard.
11 * All Rights Reserved.
13 * $Log$
14 * Revision 42.6 2004/06/16 20:16:48 verhaegs
15 * Use METHODPROTO, METHOD_END and REGFUNCPROTOn where needed.
17 * Revision 42.5 2003/01/18 19:09:55 chodorowski
18 * Instead of using the _AROS or __AROS preprocessor symbols, use __AROS__.
20 * Revision 42.4 2000/07/03 21:21:00 bergers
21 * Replaced stch_l & stcu_d and had to make a few changes in other places because of that.
23 * Revision 42.3 2000/07/02 06:08:33 bergers
24 * Compiles library alright (except that I took stch_l & stcu_d out) and seems to create the right type of object. Test1 also compiles alright but crashes somewhere...
26 * Revision 42.2 2000/05/15 19:27:00 stegerg
27 * another hundreds of REG() macro replacements in func headers/protos.
29 * Revision 42.1 2000/05/14 23:32:46 stegerg
30 * changed over 200 function headers which all use register
31 * parameters (oh boy ...), because the simple REG() macro
32 * doesn't work with AROS. And there are still hundreds
33 * of headers left to be fixed :(
35 * Many of these functions would also work with stack
36 * params, but since i have fixed every single one
37 * I encountered up to now, I guess will have to do
38 * the same for the rest.
40 * Revision 42.0 2000/05/09 22:08:29 mlemos
41 * Bumped to revision 42.0 before handing BGUI to AROS team
43 * Revision 41.11 2000/05/09 19:53:58 mlemos
44 * Merged with the branch Manuel_Lemos_fixes.
46 * Revision 41.10.2.3 1999/08/03 05:11:03 mlemos
47 * Ensured that the creation of the drag and drop screen buffer bitmap is
48 * allocated and friend of the screen's bitmap.
50 * Revision 41.10.2.2 1999/07/26 16:36:58 mlemos
51 * Prevented that a drag session starts before the previous one ends
52 * completely.
54 * Revision 41.10.2.1 1998/03/02 23:46:18 mlemos
55 * Switched vector allocation functions calls to BGUI allocation functions.
57 * Revision 41.10 1998/02/25 21:11:40 mlemos
58 * Bumping to 41.10
60 * Revision 1.1 1998/02/25 17:07:39 mlemos
61 * Ian sources
66 #include "include/classdefs.h"
68 makeproto VOID ASM EraseBMO(REG(a0) BMO *bmo)
70 struct Screen *s = bmo->bmo_Screen;
72 ObtainSemaphore(&bmo->bmo_Lock);
74 if (bmo->bmo_BMWindow)
77 * Signal to kill layer.
79 Signal((struct Task *)bmo->bmo_Process, SIGBREAKF_CTRL_E);
82 if (bmo->bmo_Locked)
84 BltBitMap(bmo->bmo_ScreenBuffer, 0, 0, s->RastPort.BitMap,
85 bmo->bmo_LX, bmo->bmo_LY, bmo->bmo_CW, bmo->bmo_CH, 0xC0, 0xFF, NULL);
86 UnlockLayerInfo(&s->LayerInfo);
87 bmo->bmo_Locked = FALSE;
90 ReleaseSemaphore(&bmo->bmo_Lock);
93 //STATIC VOID ASM SAVEDS backfill_func(REG(a0) struct Hook *hook, REG(a2) struct RastPort *rp, REG(a1) BFINFO *bf)
94 STATIC SAVEDS ASM REGFUNC3(VOID, backfill_func,
95 REGPARAM(A0, struct Hook *, hook),
96 REGPARAM(A2, struct RastPort *, rp),
97 REGPARAM(A1, BFINFO *, bf))
99 BMO *bmo = (BMO *)hook->h_Data;
101 int x = bf->bf_Rect.MinX;
102 int y = bf->bf_Rect.MinY;
103 int w = bf->bf_Rect.MaxX - x + 1;
104 int h = bf->bf_Rect.MaxY - y + 1;
106 BltBitMap(bmo->bmo_ObjectBuffer, bf->bf_X, bf->bf_Y, rp->BitMap, x, y, w, h, 0xC0, 0xFF, NULL);
108 REGFUNC_END
110 static struct Hook bf_hook = { {NULL, NULL}, (HOOKFUNC)backfill_func, NULL, NULL };
112 makeproto VOID ASM LayerBMO(REG(a0) BMO *bmo)
114 if (!bmo->bmo_BMWindow)
116 EraseBMO(bmo);
118 bf_hook.h_Data = bmo;
120 * Signal to open layer.
122 Signal((struct Task *)bmo->bmo_Process, SIGBREAKF_CTRL_F);
126 makeproto VOID ASM DrawBMO(REG(a0) BMO *bmo)
128 struct Screen *s = bmo->bmo_Screen;
129 struct BitMap *bm = bmo->bmo_ObjectBuffer;
130 struct RastPort *r = &s->RastPort;
132 int x, y, w, h;
134 ObtainSemaphore(&bmo->bmo_Lock);
136 if (!bmo->bmo_BMWindow)
138 w = bmo->bmo_CW;
139 h = bmo->bmo_CH;
141 if (bmo->bmo_Locked)
143 BltBitMap(bmo->bmo_ScreenBuffer, 0, 0, r->BitMap,
144 bmo->bmo_LX, bmo->bmo_LY, w, h, 0xC0, 0xFF, NULL);
146 else
148 bmo->bmo_Locked = TRUE;
149 LockLayerInfo(&s->LayerInfo);
152 x = bmo->bmo_LX = bmo->bmo_CX;
153 y = bmo->bmo_LY = bmo->bmo_CY;
155 BltBitMap(r->BitMap, x, y, bmo->bmo_ScreenBuffer, 0, 0, w, h, 0xC0, 0xFF, NULL);
156 BltBitMap(bm, 0, 0, r->BitMap, x, y, w, h, 0xC0, 0xFF, NULL);
159 ReleaseSemaphore(&bmo->bmo_Lock);
162 static void KillDragObject(BMO *bmo)
164 struct bmFreeDragObject bmfo;
166 if (bmo)
168 BGUI_FreeBitMap(bmo->bmo_ScreenBuffer);
170 bmfo.MethodID = BASE_FREEDRAGOBJECT;
172 if ((bmfo.bmfo_ObjBitMap = bmo->bmo_ObjectBuffer))
173 BGUI_DoGadgetMethodA(bmo->bmo_Object, bmo->bmo_Window, NULL, (Msg)&bmfo);
176 * Nuke the structure.
178 BGUI_FreePoolMem(bmo);
182 static void openwin(BMO *bmo)
184 if (bmo->bmo_BMWindow)
186 ChangeWindowBox(bmo->bmo_BMWindow, bmo->bmo_CX, bmo->bmo_CY, bmo->bmo_CW, bmo->bmo_CH);
188 else
190 bmo->bmo_BMWindow = OpenWindowTags(NULL,
191 WA_Left, bmo->bmo_CX, WA_Top, bmo->bmo_CY,
192 WA_Width, bmo->bmo_CW, WA_Height, bmo->bmo_CH,
193 WA_CustomScreen, bmo->bmo_Screen, WA_BackFill, &bf_hook,
194 WA_Borderless, TRUE, TAG_DONE);
198 static void killwin(BMO *bmo)
200 if (bmo->bmo_BMWindow)
202 CloseWindow(bmo->bmo_BMWindow);
203 bmo->bmo_BMWindow = NULL;
207 static BMO *last_bmo=NULL;
209 __saveds void Mover(void)
211 BMO *bmo;
212 ULONG sigs;
213 BOOL go;
214 struct IBox *db;
215 Object *obj = NULL, *wo, *g;
216 struct Window *w;
217 struct Screen *s = NULL;
218 struct bmDragPoint bmd;
220 #ifdef __AROS__
221 if (0 == sscanf(((struct Process *)FindTask(NULL))->pr_Arguments, "%p", &bmo))
222 #else
223 if (stch_l(((struct Process *)FindTask(NULL))->pr_Arguments, (long *)&bmo) == 0)
224 #endif
226 go = FALSE;
228 else
230 go = TRUE;
231 obj = bmo->bmo_Object;
232 s = bmo->bmo_Screen;
234 bmd.MethodID = BASE_DRAGQUERY;
235 bmd.bmdp_GInfo = NULL;
236 bmd.bmdp_Source = obj;
239 while (go)
241 sigs = Wait(SIGBREAKF_CTRL_C|SIGBREAKF_CTRL_D|SIGBREAKF_CTRL_E|SIGBREAKF_CTRL_F);
243 if (sigs & SIGBREAKF_CTRL_F) /* Make layer */
245 openwin(bmo);
247 if (sigs & SIGBREAKF_CTRL_E) /* Kill layer */
249 killwin(bmo);
251 if (sigs & SIGBREAKF_CTRL_D) /* Move object */
253 killwin(bmo);
255 * When we still have an active target
256 * we do not change the window.
258 if (!bmo->bmo_ActRec)
261 * Did the window change?
263 if ((wo = WhichWindow(s)) != bmo->bmo_ActWin)
266 * Unlock the previous window.
268 if (bmo->bmo_ActWin) AsmDoMethod(bmo->bmo_ActWin, WM_UNLOCK);
271 * Setup new window object and window pointer.
273 bmo->bmo_ActWin = wo;
274 bmo->bmo_ActPtr = NULL;
275 if (wo)
277 AsmDoMethod(wo, WM_LOCK);
278 Get_Attr(wo, WINDOW_Window, (IPTR *)&bmo->bmo_ActPtr);
284 * Are we located on a BGUI window?
286 if ((wo = bmo->bmo_ActWin))
288 w = bmo->bmo_ActPtr;
291 * Do we have a target?
293 if (!bmo->bmo_ActRec)
296 * Get the object under the mouse.
298 g = (Object *)AsmDoMethod(wo, WM_WHICHOBJECT);
301 * Deactive any active receiver which might
302 * still exist.
304 if (bmo->bmo_ActRec)
306 if (!bmo->bmo_BMWindow) EraseBMO(bmo);
307 myDoGadgetMethod(bmo->bmo_ActRec, w, NULL, BASE_DRAGINACTIVE, NULL, obj);
308 bmo->bmo_ActRec = NULL;
312 * Is the new object valid?
314 if (g)
317 * Get the hitbox bounds of the
318 * receiver.
320 Get_Attr(g, BT_HitBox, (IPTR *)&db);
323 * Get mouse coords relative to the
324 * receiver hitbox.
326 bmd.bmdp_Mouse.X = s->MouseX - (w->LeftEdge + db->Left);
327 bmd.bmdp_Mouse.Y = s->MouseY - (w->TopEdge + db->Top);
330 * Ask if it is willing to receive us.
332 if (BGUI_DoGadgetMethodA(g, w, NULL, (Msg)&bmd) == BQR_ACCEPT)
335 * Yes. Tell it to go active.
337 if (!bmo->bmo_BMWindow) EraseBMO(bmo);
338 bmo->bmo_ActRec = g;
339 myDoGadgetMethod(g, w, NULL, BASE_DRAGACTIVE, NULL, obj);
344 DrawBMO(bmo);
346 if (sigs & SIGBREAKF_CTRL_C) /* Kill object */
348 killwin(bmo);
349 EraseBMO(bmo);
350 go = FALSE;
355 * Tell the object to dispose of the
356 * created object bitmap.
358 KillDragObject(bmo);
359 last_bmo=NULL;
363 * Setup everything to move a chunk of the screen
364 * around on the screen.
367 makeproto ASM BMO *CreateBMO(REG(a0) Object *obj, REG(a1) struct GadgetInfo * gi)
369 struct Screen *scr = gi->gi_Screen;
370 struct Window *win = gi->gi_Window;
371 struct RastPort *rp = &scr->RastPort;
372 BMO *bmo;
373 int w, h, depth;
374 struct IBox bounds;
375 char args[10];
377 if (last_bmo==NULL
378 && (bmo=last_bmo= BGUI_AllocPoolMem(sizeof(BMO))))
380 if ((bmo->bmo_ObjectBuffer = (struct BitMap *)AsmDoMethod(obj, BASE_GETDRAGOBJECT, gi, &bounds)))
382 depth = FGetDepth(rp);
384 bmo->bmo_CW = w = bounds.Width;
385 bmo->bmo_CH = h = bounds.Height;
388 * Setup mouse position.
390 bmo->bmo_CX = scr->MouseX;
391 bmo->bmo_CY = scr->MouseY;
393 bmo->bmo_IX = bmo->bmo_CX - bounds.Left - win->LeftEdge;
394 bmo->bmo_IY = bmo->bmo_CY - bounds.Top - win->TopEdge;
397 * Maximum mouse positions in which a move is still performed.
399 bmo->bmo_MaxX = scr->Width - w;
400 bmo->bmo_MaxY = scr->Height - h;
402 bmo->bmo_Screen = scr;
403 bmo->bmo_Window = win;
404 bmo->bmo_Object = obj;
406 if ((bmo->bmo_ScreenBuffer = BGUI_AllocBitMap(w, h, depth, 0, scr->RastPort.BitMap)))
408 InitSemaphore(&bmo->bmo_Lock);
409 #ifdef __AROS__
410 sprintf(args, "%p\n", bmo);
411 #else
412 sprintf(args, "%08lx\n", bmo);
413 #endif
415 if ((bmo->bmo_Process = CreateNewProcTags(NP_Entry, Mover, NP_Priority, 5,
416 NP_Name, "BGUI Process", NP_Arguments, args, TAG_DONE)))
418 return bmo;
422 KillDragObject(bmo);
423 last_bmo=NULL;
425 return NULL;
429 * Cleanup the mess we made.
431 makeproto ASM VOID DeleteBMO(REG(a0) BMO *bmo)
434 * Signal termination.
436 Signal((struct Task *)bmo->bmo_Process, SIGBREAKF_CTRL_C);
440 * Move the chunk to a new location.
443 makeproto ASM VOID MoveBMO(REG(a0) BMO *bmo, REG(D0) WORD x, REG(D1) WORD y)
446 * Make sure we stay inside the
447 * screen range.
449 bmo->bmo_CX = range(x - bmo->bmo_IX, 0, bmo->bmo_MaxX);
450 bmo->bmo_CY = range(y - bmo->bmo_IY, 0, bmo->bmo_MaxY);
453 * Signal motion.
455 Signal((struct Task *)bmo->bmo_Process, SIGBREAKF_CTRL_D);