Replaced System by SYS because on "native" the volume name of the system partition...
[AROS-Contrib.git] / bgui / blitter.c
blobb4552508032ede138e2edca09489c78dcdaa430d
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)
69 makeproto ASM REGFUNC1(VOID, EraseBMO,
70 REGPARAM(A0, BMO *, bmo))
72 struct Screen *s = bmo->bmo_Screen;
74 ObtainSemaphore(&bmo->bmo_Lock);
76 if (bmo->bmo_BMWindow)
79 * Signal to kill layer.
81 Signal((struct Task *)bmo->bmo_Process, SIGBREAKF_CTRL_E);
84 if (bmo->bmo_Locked)
86 BltBitMap(bmo->bmo_ScreenBuffer, 0, 0, s->RastPort.BitMap,
87 bmo->bmo_LX, bmo->bmo_LY, bmo->bmo_CW, bmo->bmo_CH, 0xC0, 0xFF, NULL);
88 UnlockLayerInfo(&s->LayerInfo);
89 bmo->bmo_Locked = FALSE;
92 ReleaseSemaphore(&bmo->bmo_Lock);
94 REGFUNC_END
96 //STATIC VOID ASM SAVEDS backfill_func(REG(a0) struct Hook *hook, REG(a2) struct RastPort *rp, REG(a1) BFINFO *bf)
97 STATIC SAVEDS ASM REGFUNC3(VOID, backfill_func,
98 REGPARAM(A0, struct Hook *, hook),
99 REGPARAM(A2, struct RastPort *, rp),
100 REGPARAM(A1, BFINFO *, bf))
102 BMO *bmo = (BMO *)hook->h_Data;
104 int x = bf->bf_Rect.MinX;
105 int y = bf->bf_Rect.MinY;
106 int w = bf->bf_Rect.MaxX - x + 1;
107 int h = bf->bf_Rect.MaxY - y + 1;
109 BltBitMap(bmo->bmo_ObjectBuffer, bf->bf_X, bf->bf_Y, rp->BitMap, x, y, w, h, 0xC0, 0xFF, NULL);
111 REGFUNC_END
113 static struct Hook bf_hook = { NULL, NULL, (FUNCPTR)backfill_func, NULL, NULL };
115 //makeproto VOID ASM LayerBMO(REG(a0) BMO *bmo)
116 makeproto ASM REGFUNC1(VOID, LayerBMO,
117 REGPARAM(A0, BMO *, bmo))
119 if (!bmo->bmo_BMWindow)
121 EraseBMO(bmo);
123 bf_hook.h_Data = bmo;
125 * Signal to open layer.
127 Signal((struct Task *)bmo->bmo_Process, SIGBREAKF_CTRL_F);
130 REGFUNC_END
132 //makeproto VOID ASM DrawBMO(REG(a0) BMO *bmo)
133 makeproto ASM REGFUNC1(VOID, DrawBMO,
134 REGPARAM(A0, BMO *, bmo))
136 struct Screen *s = bmo->bmo_Screen;
137 struct BitMap *bm = bmo->bmo_ObjectBuffer;
138 struct RastPort *r = &s->RastPort;
140 int x, y, w, h;
142 ObtainSemaphore(&bmo->bmo_Lock);
144 if (!bmo->bmo_BMWindow)
146 w = bmo->bmo_CW;
147 h = bmo->bmo_CH;
149 if (bmo->bmo_Locked)
151 BltBitMap(bmo->bmo_ScreenBuffer, 0, 0, r->BitMap,
152 bmo->bmo_LX, bmo->bmo_LY, w, h, 0xC0, 0xFF, NULL);
154 else
156 bmo->bmo_Locked = TRUE;
157 LockLayerInfo(&s->LayerInfo);
160 x = bmo->bmo_LX = bmo->bmo_CX;
161 y = bmo->bmo_LY = bmo->bmo_CY;
163 BltBitMap(r->BitMap, x, y, bmo->bmo_ScreenBuffer, 0, 0, w, h, 0xC0, 0xFF, NULL);
164 BltBitMap(bm, 0, 0, r->BitMap, x, y, w, h, 0xC0, 0xFF, NULL);
167 ReleaseSemaphore(&bmo->bmo_Lock);
169 REGFUNC_END
171 static void KillDragObject(BMO *bmo)
173 struct bmFreeDragObject bmfo;
175 if (bmo)
177 BGUI_FreeBitMap(bmo->bmo_ScreenBuffer);
179 bmfo.MethodID = BASE_FREEDRAGOBJECT;
181 if (bmfo.bmfo_ObjBitMap = bmo->bmo_ObjectBuffer)
182 BGUI_DoGadgetMethodA(bmo->bmo_Object, bmo->bmo_Window, NULL, (Msg)&bmfo);
185 * Nuke the structure.
187 BGUI_FreePoolMem(bmo);
191 static void openwin(BMO *bmo)
193 if (bmo->bmo_BMWindow)
195 ChangeWindowBox(bmo->bmo_BMWindow, bmo->bmo_CX, bmo->bmo_CY, bmo->bmo_CW, bmo->bmo_CH);
197 else
199 bmo->bmo_BMWindow = OpenWindowTags(NULL,
200 WA_Left, bmo->bmo_CX, WA_Top, bmo->bmo_CY,
201 WA_Width, bmo->bmo_CW, WA_Height, bmo->bmo_CH,
202 WA_CustomScreen, bmo->bmo_Screen, WA_BackFill, &bf_hook,
203 WA_Borderless, TRUE, TAG_DONE);
207 static void killwin(BMO *bmo)
209 if (bmo->bmo_BMWindow)
211 CloseWindow(bmo->bmo_BMWindow);
212 bmo->bmo_BMWindow = NULL;
216 static BMO *last_bmo=NULL;
218 __saveds void Mover(void)
220 BMO *bmo;
221 ULONG sigs;
222 BOOL go;
223 struct IBox *db;
224 Object *obj, *wo, *g;
225 struct Window *w;
226 struct Screen *s;
227 struct bmDragPoint bmd;
229 #ifdef __AROS__
230 if (0 == sscanf(((struct Process *)FindTask(NULL))->pr_Arguments, "%lx", &bmo))
231 #else
232 if (stch_l(((struct Process *)FindTask(NULL))->pr_Arguments, (long *)&bmo) == 0)
233 #endif
235 go = FALSE;
237 else
239 go = TRUE;
240 obj = bmo->bmo_Object;
241 s = bmo->bmo_Screen;
243 bmd.MethodID = BASE_DRAGQUERY;
244 bmd.bmdp_GInfo = NULL;
245 bmd.bmdp_Source = obj;
248 while (go)
250 sigs = Wait(SIGBREAKF_CTRL_C|SIGBREAKF_CTRL_D|SIGBREAKF_CTRL_E|SIGBREAKF_CTRL_F);
252 if (sigs & SIGBREAKF_CTRL_F) /* Make layer */
254 openwin(bmo);
256 if (sigs & SIGBREAKF_CTRL_E) /* Kill layer */
258 killwin(bmo);
260 if (sigs & SIGBREAKF_CTRL_D) /* Move object */
262 killwin(bmo);
264 * When we still have an active target
265 * we do not change the window.
267 if (!bmo->bmo_ActRec)
270 * Did the window change?
272 if ((wo = WhichWindow(s)) != bmo->bmo_ActWin)
275 * Unlock the previous window.
277 if (bmo->bmo_ActWin) AsmDoMethod(bmo->bmo_ActWin, WM_UNLOCK);
280 * Setup new window object and window pointer.
282 bmo->bmo_ActWin = wo;
283 bmo->bmo_ActPtr = NULL;
284 if (wo)
286 AsmDoMethod(wo, WM_LOCK);
287 Get_Attr(wo, WINDOW_Window, (ULONG *)&bmo->bmo_ActPtr);
293 * Are we located on a BGUI window?
295 if (wo = bmo->bmo_ActWin)
297 w = bmo->bmo_ActPtr;
300 * Do we have a target?
302 if (!bmo->bmo_ActRec)
305 * Get the object under the mouse.
307 g = (Object *)AsmDoMethod(wo, WM_WHICHOBJECT);
310 * Deactive any active receiver which might
311 * still exist.
313 if (bmo->bmo_ActRec)
315 if (!bmo->bmo_BMWindow) EraseBMO(bmo);
316 myDoGadgetMethod(bmo->bmo_ActRec, w, NULL, BASE_DRAGINACTIVE, NULL, obj);
317 bmo->bmo_ActRec = NULL;
321 * Is the new object valid?
323 if (g)
326 * Get the hitbox bounds of the
327 * receiver.
329 Get_Attr(g, BT_HitBox, &db);
332 * Get mouse coords relative to the
333 * receiver hitbox.
335 bmd.bmdp_Mouse.X = s->MouseX - (w->LeftEdge + db->Left);
336 bmd.bmdp_Mouse.Y = s->MouseY - (w->TopEdge + db->Top);
339 * Ask if it is willing to receive us.
341 if (BGUI_DoGadgetMethodA(g, w, NULL, (Msg)&bmd) == BQR_ACCEPT)
344 * Yes. Tell it to go active.
346 if (!bmo->bmo_BMWindow) EraseBMO(bmo);
347 bmo->bmo_ActRec = g;
348 myDoGadgetMethod(g, w, NULL, BASE_DRAGACTIVE, NULL, obj);
353 DrawBMO(bmo);
355 if (sigs & SIGBREAKF_CTRL_C) /* Kill object */
357 killwin(bmo);
358 EraseBMO(bmo);
359 go = FALSE;
364 * Tell the object to dispose of the
365 * created object bitmap.
367 KillDragObject(bmo);
368 last_bmo=NULL;
372 * Setup everything to move a chunk of the screen
373 * around on the screen.
376 //makeproto ASM BMO *CreateBMO(REG(a0) Object *obj, REG(a1) struct GadgetInfo * gi)
377 makeproto ASM REGFUNC2(BMO *, CreateBMO,
378 REGPARAM(A0, Object *, obj),
379 REGPARAM(A1, struct GadgetInfo *, gi))
381 struct Screen *scr = gi->gi_Screen;
382 struct Window *win = gi->gi_Window;
383 struct RastPort *rp = &scr->RastPort;
384 BMO *bmo;
385 int w, h, depth;
386 struct IBox bounds;
387 char args[10];
389 if (last_bmo==NULL
390 && (bmo=last_bmo= BGUI_AllocPoolMem(sizeof(BMO))))
392 if (bmo->bmo_ObjectBuffer = (struct BitMap *)AsmDoMethod(obj, BASE_GETDRAGOBJECT, gi, &bounds))
394 depth = FGetDepth(rp);
396 bmo->bmo_CW = w = bounds.Width;
397 bmo->bmo_CH = h = bounds.Height;
400 * Setup mouse position.
402 bmo->bmo_CX = scr->MouseX;
403 bmo->bmo_CY = scr->MouseY;
405 bmo->bmo_IX = bmo->bmo_CX - bounds.Left - win->LeftEdge;
406 bmo->bmo_IY = bmo->bmo_CY - bounds.Top - win->TopEdge;
409 * Maximum mouse positions in which a move is still performed.
411 bmo->bmo_MaxX = scr->Width - w;
412 bmo->bmo_MaxY = scr->Height - h;
414 bmo->bmo_Screen = scr;
415 bmo->bmo_Window = win;
416 bmo->bmo_Object = obj;
418 if (bmo->bmo_ScreenBuffer = BGUI_AllocBitMap(w, h, depth, 0, scr->RastPort.BitMap))
420 InitSemaphore(&bmo->bmo_Lock);
421 sprintf(args, "%08lx\n", bmo);
423 if (bmo->bmo_Process = CreateNewProcTags(NP_Entry, Mover, NP_Priority, 5,
424 NP_Name, "BGUI Process", NP_Arguments, args, TAG_DONE))
426 return bmo;
430 KillDragObject(bmo);
431 last_bmo=NULL;
433 return NULL;
435 REGFUNC_END
438 * Cleanup the mess we made.
440 //makeproto ASM VOID DeleteBMO(REG(a0) BMO *bmo)
441 makeproto ASM REGFUNC1(VOID, DeleteBMO,
442 REGPARAM(A0, BMO *, bmo))
445 * Signal termination.
447 Signal((struct Task *)bmo->bmo_Process, SIGBREAKF_CTRL_C);
449 REGFUNC_END
452 * Move the chunk to a new location.
455 //makeproto ASM VOID MoveBMO(REG(a0) BMO *bmo, REG(D0) WORD x, REG(D1) WORD y)
456 makeproto ASM REGFUNC3(VOID, MoveBMO,
457 REGPARAM(A0, BMO *, bmo),
458 REGPARAM(D0, WORD, x),
459 REGPARAM(d1, WORD, y))
462 * Make sure we stay inside the
463 * screen range.
465 bmo->bmo_CX = range(x - bmo->bmo_IX, 0, bmo->bmo_MaxX);
466 bmo->bmo_CY = range(y - bmo->bmo_IY, 0, bmo->bmo_MaxY);
469 * Signal motion.
471 Signal((struct Task *)bmo->bmo_Process, SIGBREAKF_CTRL_D);
473 REGFUNC_END