revert between 56095 -> 55830 in arch
[AROS.git] / workbench / libs / datatypes / class.c
blobdf9195e6e0d688dc975545fbb1ed5db8e7984836
1 /*
2 Copyright © 1995-2001, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc: Implementation of datatype rootclass
6 Lang: English
7 */
9 #define USE_BOOPSI_STUBS
10 #include <exec/types.h>
11 #include <exec/memory.h>
12 #include <exec/tasks.h>
13 #include <intuition/classes.h>
14 #include <intuition/gadgetclass.h>
15 #include <intuition/icclass.h>
16 #include <intuition/cghooks.h>
17 #include <intuition/intuition.h>
18 #include <graphics/rastport.h>
19 #include <proto/exec.h>
20 #include <proto/dos.h>
21 #include <proto/utility.h>
22 #include <proto/iffparse.h>
23 #include <proto/graphics.h>
24 #include <proto/intuition.h>
25 #include <proto/exec.h>
26 #include <proto/alib.h>
27 #include <string.h>
28 #include <datatypes/datatypesclass.h>
29 #include <datatypes/datatypes.h>
30 #include "datatypes_intern.h"
32 #include <clib/boopsistubs.h>
34 #include <aros/debug.h>
36 /* #include <devices/printer.h> -- No printer stuff yet... */
38 /*****************************************************************************/
40 void DrawBox(struct Library *DataTypesBase, struct RastPort *rp,
41 LONG x1, LONG y1, LONG x2, LONG y2);
44 /****** datatypes.library/SetAttributes ***************************************
46 * NAME
47 * SetAttributes - set a DTObject's attributes given an opSet structure
49 * SYNOPSIS
51 * FUNCTION
53 * INPUTS
55 * RETURNS
57 * EXAMPLE
59 * SEE ALSO
61 ******************************************************************************
65 IPTR SetAttributes(struct Library *DataTypesBase, Class *class, Object *object,
66 Msg msg)
68 IPTR result = 0;
69 struct DTObject *dto = INST_DATA(class, object);
70 struct DTSpecialInfo *dtsi = ((struct Gadget *)object)->SpecialInfo;
72 LONG TopVert = dtsi->si_TopVert;
73 LONG VisVert = dtsi->si_VisVert;
74 LONG TotVert = dtsi->si_TotVert;
75 LONG TopHoriz = dtsi->si_TopHoriz;
76 LONG VisHoriz = dtsi->si_VisHoriz;
77 LONG TotHoriz = dtsi->si_TotHoriz;
79 struct TagItem *tstate = ((struct opSet *)msg)->ops_AttrList;
80 struct TagItem *tag;
82 while ((tag = NextTagItem(&tstate)) != NULL)
84 SIPTR data = tag->ti_Data;
86 switch(tag->ti_Tag)
88 case DTA_TopVert: TopVert = data; break;
89 case DTA_VisibleVert: VisVert = data; break;
90 case DTA_TotalVert: TotVert = data; break;
91 case DTA_VertUnit: dtsi->si_VertUnit = data; break;
93 case DTA_TopHoriz: TopHoriz = data; break;
94 case DTA_VisibleHoriz: VisHoriz = data; break;
95 case DTA_TotalHoriz: TotHoriz = data; break;
96 case DTA_HorizUnit: dtsi->si_HorizUnit = data; break;
98 case DTA_PrinterProc: dto->dto_PrinterProc = (struct Process *)data;
99 break;
100 case DTA_LayoutProc: dto->dto_LayoutProc = (struct Process *)data;
101 break;
103 case DTA_ObjName:
104 if(dto->dto_ObjName)
106 FreeVec(dto->dto_ObjName);
107 dto->dto_ObjName = NULL;
110 if((APTR)data != NULL)
111 if((dto->dto_ObjName = AllocVec((ULONG)strlen((UBYTE *)data) + 1,
112 MEMF_PUBLIC | MEMF_CLEAR)))
113 strcpy(dto->dto_ObjName,(UBYTE *)data);
115 break;
117 case DTA_ObjAuthor:
118 if(dto->dto_ObjAuthor != NULL)
120 FreeVec(dto->dto_ObjAuthor);
121 dto->dto_ObjAuthor = NULL;
124 if((APTR)data != NULL)
125 if((dto->dto_ObjAuthor = AllocVec((ULONG)strlen((UBYTE *)data)+1,
126 MEMF_PUBLIC | MEMF_CLEAR)))
127 strcpy(dto->dto_ObjAuthor, (UBYTE *)data);
129 break;
131 case DTA_ObjAnnotation:
132 if(dto->dto_ObjAnnotation != NULL)
134 FreeVec(dto->dto_ObjAnnotation);
135 dto->dto_ObjAnnotation = NULL;
138 if((APTR)data != NULL)
139 if((dto->dto_ObjAnnotation = AllocVec((ULONG)strlen((UBYTE*)data) + 1,
140 MEMF_PUBLIC | MEMF_CLEAR)))
141 strcpy(dto->dto_ObjAnnotation, (UBYTE *)data);
143 break;
145 case DTA_ObjCopyright:
146 if(dto->dto_ObjCopyright != NULL)
148 FreeVec(dto->dto_ObjCopyright);
149 dto->dto_ObjCopyright=NULL;
152 if((APTR)data != NULL)
153 if((dto->dto_ObjCopyright = AllocVec((ULONG)strlen((UBYTE*)data) + 1,
154 MEMF_PUBLIC | MEMF_CLEAR)))
155 strcpy(dto->dto_ObjCopyright, (UBYTE *)data);
157 break;
159 case DTA_ObjVersion:
160 if(dto->dto_ObjVersion != NULL)
162 FreeVec(dto->dto_ObjVersion);
163 dto->dto_ObjVersion = NULL;
166 if((APTR)data != NULL)
167 if((dto->dto_ObjVersion = AllocVec((ULONG)strlen((UBYTE*)data) + 1,
168 MEMF_PUBLIC | MEMF_CLEAR)))
169 strcpy(dto->dto_ObjVersion, (UBYTE *)data);
171 break;
173 case DTA_ObjectID:
174 dto->dto_ObjectID = data;
175 break;
177 case DTA_UserData:
178 dto->dto_UserData = data;
179 break;
181 case DTA_SelectDomain:
182 dto->dto_SelectDomain = *((struct IBox *)data);
183 break;
185 case DTA_NominalVert:
186 dto->dto_NominalVert = data;
187 break;
189 case DTA_NominalHoriz:
190 dto->dto_NominalHoriz = data;
191 break;
195 if(TopVert < 0)
196 TopVert = 0;
198 if(VisVert > TotVert)
199 TopVert = 0;
200 else if(TopVert + VisVert > TotVert)
201 TopVert = TotVert-VisVert;
203 if(TopVert != dtsi->si_TopVert)
205 dtsi->si_TopVert = TopVert;
206 result = TRUE;
209 if(VisVert != dtsi->si_VisVert)
211 dtsi->si_VisVert = VisVert;
212 result = TRUE;
215 if(TotVert != dtsi->si_TotVert)
217 dtsi->si_TotVert = TotVert;
218 result = TRUE;
221 if(TopHoriz < 0)
222 TopHoriz = 0;
224 if(VisHoriz > TotHoriz)
225 TopHoriz = 0;
226 else if(TopHoriz + VisHoriz > TotHoriz)
227 TopHoriz = TotHoriz - VisHoriz;
229 if(TopHoriz != dtsi->si_TopHoriz)
231 dtsi->si_TopHoriz = TopHoriz;
232 result = TRUE;
235 if(VisHoriz != dtsi->si_VisHoriz)
237 dtsi->si_VisHoriz = VisHoriz;
238 result = TRUE;
241 if(TotHoriz != dtsi->si_TotHoriz)
243 dtsi->si_TotHoriz = TotHoriz;
244 result = TRUE;
247 return result;
251 /****** datatypes.library/Dispatcher ******************************************
253 * NAME
254 * Dispatcher - datatypesclass dispatcher code
256 * SYNOPSIS
258 * FUNCTION
260 * INPUTS
262 * RETURNS
264 * EXAMPLE
266 * SEE ALSO
268 ******************************************************************************
272 AROS_UFH3(IPTR, Dispatcher,
273 AROS_UFHA(Class *, class, A0),
274 AROS_UFHA(Object *, object, A2),
275 AROS_UFHA(Msg, msg, A1))
277 AROS_USERFUNC_INIT
279 struct DataTypesBase *DataTypesBase = (struct DataTypesBase *)class->cl_UserData;
280 struct DTObject *dto = INST_DATA(class,object);
281 struct DTSpecialInfo *dtsi = ((struct Gadget *)object)->SpecialInfo;
283 IPTR retval = 0;
285 switch(msg->MethodID)
287 case OM_NEW:
289 struct Gadget *newobject;
290 struct DTObject *newdto;
292 D(bug("datatypes.library/class/OM_NEW\n"));
294 if(!(newobject = (struct Gadget *)DoSuperMethodA(class, object,
295 msg)))
296 SetIoErr(ERROR_NO_FREE_STORE);
297 else
299 struct TagItem *attrs = ((struct opSet *)msg)->ops_AttrList;
300 struct TagItem *nametag;
301 BOOL Success = FALSE;
302 APTR handle;
304 D(bug("datatypes.library/class/OM_NEW: DoSuperMethod succeeded\n"));
306 newdto = INST_DATA(class, newobject);
308 newobject->Flags |= GFLG_RELSPECIAL;
309 newobject->SpecialInfo = &newdto->dto_DTSpecialInfo;
311 InitSemaphore(&newdto->dto_DTSpecialInfo.si_Lock);
313 newdto->dto_SourceType = GetTagData(DTA_SourceType, DTST_FILE,
314 attrs);
315 handle = (APTR)GetTagData(DTA_Handle, (IPTR)NULL, attrs);
317 if(!(nametag = FindTagItem(DTA_Name, attrs)))
318 SetIoErr(ERROR_REQUIRED_ARG_MISSING);
319 else
321 LONG namelen = 2;
323 D(bug("datatypes.library/class/OM_NEW: DTA_Name tag found\n"));
325 if (newdto->dto_SourceType == DTST_FILE)
327 namelen = (ULONG)strlen((UBYTE *)nametag->ti_Data) + 1;
330 if (!(newdto->dto_Name = AllocVec(namelen, MEMF_PUBLIC | MEMF_CLEAR)))
331 SetIoErr(ERROR_NO_FREE_STORE);
332 else
334 D(bug("datatypes.library/class/OM_NEW: Namelen allocation succeeded\n"));
336 switch(newdto->dto_SourceType)
338 case DTST_FILE:
339 strcpy(newdto->dto_Name, (UBYTE *)nametag->ti_Data);
340 break;
342 case DTST_CLIPBOARD:
343 newdto->dto_Name[0] = '0' + (UBYTE)nametag->ti_Data;
344 break;
347 if(!(newdto->dto_DataType = (struct DataType *)GetTagData(DTA_DataType, (IPTR)NULL, attrs)))
348 Success = TRUE;
349 else
351 D(bug("datatypes.library/class/OM_NEW: DTA_DataType tag value okay\n"));
353 switch(newdto->dto_SourceType)
355 case DTST_FILE:
356 D(bug("datatypes.library/class/OM_NEW: SourceType = DTST_FILE\n"));
358 switch(newdto->dto_DataType->dtn_Header->dth_Flags & DTF_TYPE_MASK)
360 case DTF_IFF:
361 if((newdto->dto_Handle = (APTR)AllocIFF()))
363 if((((struct IFFHandle *)newdto->dto_Handle)->iff_Stream = (IPTR)NewOpen((struct Library *)DataTypesBase, newdto->dto_Name, DTST_FILE, 0)))
365 InitIFFasDOS((struct IFFHandle*)newdto->dto_Handle);
367 if(!OpenIFF((struct IFFHandle *)newdto->dto_Handle, IFFF_READ))
368 Success = TRUE;
372 UnLock((BPTR)handle);
373 break;
375 case DTF_MISC:
376 newdto->dto_Handle = handle;
377 Success = TRUE;
378 break;
380 default:
381 D(bug("datatypes.library/class/OM_NEW: calling NewOpen()\n"));
383 if((newdto->dto_Handle = (APTR)NewOpen((struct Library *)DataTypesBase, newdto->dto_Name, DTST_FILE, 0)))
384 Success = TRUE;
386 D(bug("datatypes.library/class/OM_NEW: NewOpened() returned %s\n", Success ? "success" : "failure"));
388 UnLock((BPTR)handle);
389 break;
390 } /* switch(... & DTF_TYPE_MASK) */
391 break;
393 case DTST_CLIPBOARD:
394 D(bug("datatypes.library/class/OM_NEW: SourceType = DTST_CLIPBOARD\n"));
396 newdto->dto_Handle = handle;
397 Success = TRUE;
398 break;
399 } /* switch(sourcetype) */
404 if(Success)
406 SetAttributes((struct Library *)DataTypesBase, class,
407 (Object *)newobject, msg);
408 retval = (IPTR)newobject;
410 else
411 CoerceMethod(class, (Object *)newobject, OM_DISPOSE);
414 D(bug("datatypes.library/class/OM_NEW: returning %x handle = %x\n", retval, newdto->dto_Handle));
416 break;
417 } /* case OM_NEW: */
419 case OM_UPDATE:
420 /* Avoid update loops */
421 /* if(DoMethod(object, ICM_CHECKLOOP))
422 break; */
424 /* Fall through */
425 case OM_SET:
426 /* Let superclass see the new attributes... */
427 retval = DoSuperMethodA(class, object, msg);
428 /* ...and set our own new attributes. */
429 retval += SetAttributes((struct Library *)DataTypesBase, class, object, msg);
430 break;
432 case OM_GET:
433 D(bug("datatypes.library/class/OM_GET: tag = %x\n", ((struct opGet*)msg)->opg_AttrID));
435 IPTR *store = ((struct opGet *)msg)->opg_Storage;
436 retval = 1;
438 switch(((struct opGet*)msg)->opg_AttrID)
440 case DTA_TopVert: *store = dtsi->si_TopVert; break;
441 case DTA_VisibleVert: *store = dtsi->si_VisVert; break;
442 case DTA_TotalVert: *store = dtsi->si_TotVert; break;
443 case DTA_VertUnit: *store = dtsi->si_VertUnit; break;
445 case DTA_TopHoriz: *store = dtsi->si_TopHoriz; break;
446 case DTA_VisibleHoriz: *store = dtsi->si_VisHoriz; break;
447 case DTA_TotalHoriz: *store = dtsi->si_TotHoriz; break;
448 case DTA_HorizUnit: *store = dtsi->si_HorizUnit; break;
450 case DTA_PrinterProc: *store = (IPTR)dto->dto_PrinterProc; break;
451 case DTA_LayoutProc: *store = (IPTR)dto->dto_LayoutProc; break;
453 case DTA_Name: *store = (IPTR)dto->dto_Name; break;
454 case DTA_SourceType: *store = dto->dto_SourceType; break;
455 case DTA_Handle: *store = (IPTR)dto->dto_Handle; break;
456 case DTA_DataType: *store = (IPTR)dto->dto_DataType; break;
457 case DTA_Domain: *store = (IPTR)&dto->dto_Domain; break;
459 case DTA_ObjName: *store = (IPTR)dto->dto_ObjName; break;
460 case DTA_ObjAuthor: *store = (IPTR)dto->dto_ObjAuthor; break;
461 case DTA_ObjAnnotation: *store = (IPTR)dto->dto_ObjAnnotation; break;
462 case DTA_ObjCopyright: *store = (IPTR)dto->dto_ObjCopyright; break;
463 case DTA_ObjVersion: *store = (IPTR)dto->dto_ObjVersion; break;
464 case DTA_ObjectID: *store = dto->dto_ObjectID; break;
465 case DTA_UserData: *store = dto->dto_UserData; break;
466 case DTA_FrameInfo: *store = (IPTR)&dto->dto_FrameInfo; break;
468 case DTA_SelectDomain:
469 if (dtsi->si_Flags & DTSIF_HIGHLIGHT)
470 *store = (IPTR)&dto->dto_SelectDomain;
471 else
472 *store = (IPTR)NULL;
473 break;
475 case DTA_TotalPVert: *store = dto->dto_TotalPVert; break;
476 case DTA_TotalPHoriz: *store = dto->dto_TotalPHoriz; break;
477 case DTA_NominalVert: *store = dto->dto_NominalVert; break;
478 case DTA_NominalHoriz: *store = dto->dto_NominalHoriz; break;
479 case DTA_Data: *store = (IPTR)object; break;
481 default:
482 retval = DoSuperMethodA(class, object, msg);
483 break;
484 } /* switch(AttrId) */
485 } /* case OM_GET: */
486 break;
488 case GM_HITTEST:
489 /* A datatypes gadget is hit everywhere */
490 retval = GMR_GADGETHIT;
491 break;
493 case GM_GOACTIVE:
494 /* Calculate printable dimensions */
495 dto->dto_TotalPHoriz = (dtsi->si_HorizUnit) ?
496 dtsi->si_HorizUnit*dtsi->si_TotHoriz : dto->dto_Domain.Width;
498 dto->dto_TotalPVert = (dtsi->si_VertUnit ) ?
499 dtsi->si_VertUnit*dtsi->si_TotVert : dto->dto_Domain.Height;
501 /* Fall through */
503 case GM_HANDLEINPUT:
505 struct InputEvent *ievent = ((struct gpInput *)msg)->gpi_IEvent;
507 if((msg->MethodID == GM_GOACTIVE && (!ievent) ) ||
508 (dtsi->si_Flags & DTSIF_LAYOUT))
509 retval=GMR_NOREUSE;
510 else
512 if(!AttemptSemaphoreShared(&dtsi->si_Lock))
513 retval = GMR_NOREUSE;
514 else
516 struct RastPort *rp;
517 struct IBox *domain;
518 ULONG hunit;
519 ULONG vunit;
521 if((rp = ObtainGIRPort(((struct gpInput *)msg)->gpi_GInfo)))
523 SetDrMd(rp, COMPLEMENT);
524 SetAPen(rp, -1);
526 GetAttr(DTA_Domain, object, (IPTR *)&domain);
528 hunit = (dtsi->si_HorizUnit) ? (dtsi->si_HorizUnit) : 1;
529 vunit = (dtsi->si_VertUnit ) ? (dtsi->si_VertUnit ) : 1;
531 switch(ievent->ie_Class)
533 case IECLASS_RAWMOUSE:
535 switch(ievent->ie_Code)
537 case IECODE_LBUTTON:
539 ((struct Gadget *)object)->Flags |= GFLG_SELECTED;
541 dto->dto_OldTopHoriz = dtsi->si_TopHoriz;
542 dto->dto_OldTopVert = dtsi->si_TopVert;
544 if(dtsi->si_Flags & DTSIF_DRAGSELECT)
546 struct IBox *sdomain;
548 if(GetAttr(DTA_SelectDomain, object, (IPTR *)&sdomain))
550 if(sdomain)
552 dtsi->si_Flags &= ~DTSIF_HIGHLIGHT;
554 DoMethod(object, DTM_CLEARSELECTED,
555 (IPTR)((struct gpInput *)msg)->gpi_GInfo);
559 dtsi->si_Flags |= (DTSIF_DRAGGING | DTSIF_DRAGSELECT);
561 dto->dto_MouseX = ((struct gpInput *)msg)->gpi_Mouse.X;
562 dto->dto_MouseY = ((struct gpInput *)msg)->gpi_Mouse.Y;
564 if(dto->dto_MouseX >= dto->dto_TotalPHoriz)
565 dto->dto_MouseX = dto->dto_TotalPHoriz - 1;
567 if(hunit>1)
568 dto->dto_MouseX = dto->dto_MouseX / hunit * hunit;
570 dto->dto_SelectRect.MinX = dto->dto_MouseX + dtsi->si_TopHoriz*hunit;
571 dto->dto_StartX = dto->dto_MouseX = dto->dto_MouseX + ((struct Gadget *)object)->LeftEdge;
573 if(dto->dto_MouseY >= dto->dto_TotalPVert)
574 dto->dto_MouseY = dto->dto_TotalPVert - 1;
576 if(vunit > 1)
577 dto->dto_MouseY = dto->dto_MouseY/vunit*vunit;
578 dto->dto_SelectRect.MinY = dto->dto_MouseY + dtsi->si_TopVert*vunit;
579 dto->dto_StartY = dto->dto_MouseY = dto->dto_MouseY + ((struct Gadget *)object)->TopEdge;
581 dto->dto_LinePtrn = rp->LinePtrn = 0xff00;
582 DrawBox((struct Library *)DataTypesBase, rp, (LONG)dto->dto_StartX, (LONG)dto->dto_StartY, (LONG)dto->dto_MouseX, (LONG)dto->dto_MouseY);
583 } /* if(DRAGSELECT) */
584 } /* if(IECODE_LBUTTON) */
585 break;
587 case (IECODE_LBUTTON | IECODE_UP_PREFIX):
588 retval = GMR_VERIFY | GMR_NOREUSE;
589 break;
591 case IECODE_RBUTTON:
593 ((struct Gadget *)object)->Flags &= ~GFLG_SELECTED;
595 dtsi->si_TopHoriz = dto->dto_OldTopHoriz;
596 dtsi->si_TopVert = dto->dto_OldTopVert;
598 retval = GMR_NOREUSE;
600 break;
602 default:
603 if(dtsi->si_Flags & DTSIF_DRAGSELECT)
605 rp->LinePtrn = dto->dto_LinePtrn;
606 DrawBox((struct Library *)DataTypesBase, rp, (LONG)dto->dto_StartX, (LONG)dto->dto_StartY, (LONG)dto->dto_MouseX, (LONG)dto->dto_MouseY);
608 dto->dto_MouseX=((struct gpInput *)msg)->gpi_Mouse.X;
609 dto->dto_MouseY=((struct gpInput *)msg)->gpi_Mouse.Y;
611 if(dto->dto_MouseX < 0)
612 dto->dto_MouseX = 0;
614 if(dto->dto_MouseX >= domain->Width)
615 dto->dto_MouseX = domain->Width - 1;
617 if(dto->dto_MouseX >= dto->dto_TotalPHoriz)
618 dto->dto_MouseX = dto->dto_TotalPHoriz - 1;
620 if(hunit > 1)
621 dto->dto_MouseX = dto->dto_MouseX / hunit * hunit - 1;
623 dto->dto_SelectRect.MaxX = dto->dto_MouseX + dtsi->si_TopHoriz * hunit;
624 dto->dto_MouseX = dto->dto_MouseX + ((struct Gadget*)object)->LeftEdge;
626 if(dto->dto_MouseY < 0)
627 dto->dto_MouseY = 0;
629 if(dto->dto_MouseY >= domain->Height)
630 dto->dto_MouseY = domain->Height - 1;
632 if(dto->dto_MouseY >= dto->dto_TotalPVert)
633 dto->dto_MouseY = dto->dto_TotalPVert - 1;
635 if(vunit > 1)
636 dto->dto_MouseY = dto->dto_MouseY / vunit * vunit - 1;
638 dto->dto_SelectRect.MaxY = dto->dto_MouseY + dtsi->si_TopVert * vunit;
639 dto->dto_MouseY = dto->dto_MouseY + ((struct Gadget*)object)->TopEdge;
641 DrawBox((struct Library *)DataTypesBase, rp, (LONG)dto->dto_StartX, (LONG)dto->dto_StartY, (LONG)dto->dto_MouseX, (LONG)dto->dto_MouseY);
642 } /* if(DRAGSELECT) */
643 break;
644 } /* switch(ievent->ie_Code) */
645 } /* case IECLASS_RAWMOUSE */
646 break;
648 case IECLASS_TIMER:
650 LONG NewTopHoriz, NewTopVert;
651 LONG OldTopHoriz, OldTopVert;
652 WORD MouseX, MouseY;
654 NewTopHoriz = OldTopHoriz = dtsi->si_TopHoriz;
655 NewTopVert = OldTopVert = dtsi->si_TopVert;
657 MouseX = ((struct gpInput *)msg)->gpi_Mouse.X;
658 MouseY = ((struct gpInput *)msg)->gpi_Mouse.Y;
660 if(MouseX < 0)
661 NewTopHoriz += MouseX / hunit;
662 else if(MouseX >= domain->Width )
663 NewTopHoriz += (MouseX - domain->Width - 1) / hunit;
665 if(MouseY < 0)
666 NewTopVert += MouseY / vunit;
667 else if(MouseY >= domain->Height)
668 NewTopVert += (MouseY - domain->Height - 1) / vunit;
670 if(NewTopHoriz > (dtsi->si_TotHoriz-dtsi->si_VisHoriz))
671 NewTopHoriz = dtsi->si_TotHoriz-dtsi->si_VisHoriz;
673 if(NewTopHoriz < 0)
674 NewTopHoriz = 0;
676 if(NewTopVert > (dtsi->si_TotVert - dtsi->si_VisVert ))
677 NewTopVert = dtsi->si_TotVert - dtsi->si_VisVert;
679 if(NewTopVert < 0)
680 NewTopVert = 0;
682 if((NewTopVert != OldTopVert) || (NewTopHoriz != OldTopHoriz))
684 dto->dto_Flags |= DTOFLGF_HAS_MOVED;
686 if (dtsi->si_Flags & DTSIF_DRAGSELECT)
688 rp->LinePtrn = dto->dto_LinePtrn;
689 DrawBox((struct Library *)DataTypesBase, rp, (LONG)dto->dto_StartX, (LONG)dto->dto_StartY, (LONG)dto->dto_MouseX, (LONG)dto->dto_MouseY);
692 dtsi->si_TopHoriz = NewTopHoriz;
693 dtsi->si_TopVert = NewTopVert;
695 DoMethod(object, GM_RENDER, (IPTR)((struct gpInput *)msg)->gpi_GInfo, (IPTR)rp, GREDRAW_UPDATE);
697 if (dtsi->si_Flags & DTSIF_DRAGSELECT)
699 dto->dto_StartX = domain->Left + dto->dto_SelectRect.MinX - dtsi->si_TopHoriz;
701 if(dto->dto_StartX < domain->Left)
702 dto->dto_StartX = domain->Left;
703 else if(dto->dto_StartX >= (domain->Left + domain->Width))
704 dto->dto_StartX = domain->Left + domain->Width - 1;
706 dto->dto_StartY = domain->Top + dto->dto_SelectRect.MinY - dtsi->si_TopVert;
708 if(dto->dto_StartY < domain->Top )
709 dto->dto_StartY = domain->Top;
710 else if(dto->dto_StartY >= (domain->Top + domain->Height))
711 dto->dto_StartY = domain->Top + domain->Height - 1;
713 DrawBox((struct Library *)DataTypesBase, rp, (LONG)dto->dto_StartX, (LONG)dto->dto_StartY, (LONG)dto->dto_MouseX, (LONG)dto->dto_MouseY);
714 } /* if(DRAGSELECT) */
715 } /* if(vert or horiz have changed) */
717 if(dtsi->si_Flags & DTSIF_DRAGSELECT)
719 UWORD pattern = (dto->dto_LinePtrn << 4) | ((dto->dto_LinePtrn & 0xf000) >> 12);
720 rp->LinePtrn = dto->dto_LinePtrn ^ pattern;
721 DrawBox((struct Library *)DataTypesBase, rp, (LONG)dto->dto_StartX, (LONG)dto->dto_StartY, (LONG)dto->dto_MouseX, (LONG)dto->dto_MouseY);
722 dto->dto_LinePtrn = pattern;
724 } /* case IECLASS_TIMER: */
725 break;
726 } /* switch(ievent->ie_Class) */
728 ReleaseGIRPort(rp);
729 } /* if(we got GIRPort) */
731 ReleaseSemaphore(&dtsi->si_Lock);
734 } /* case GM_HANDLEINPUT */
735 break;
737 case GM_GOINACTIVE:
739 struct RastPort *rp;
741 if((rp = ObtainGIRPort(((struct gpInput *)msg)->gpi_GInfo)))
743 if(dtsi->si_Flags & DTSIF_DRAGSELECT)
745 SetDrMd(rp, COMPLEMENT);
746 SetAPen(rp, -1);
748 rp->LinePtrn = dto->dto_LinePtrn;
749 DrawBox((struct Library *)DataTypesBase, rp,
750 (LONG)dto->dto_StartX, (LONG)dto->dto_StartY,
751 (LONG)dto->dto_MouseX, (LONG)dto->dto_MouseY);
753 if(((struct Gadget *)object)->Flags & GFLG_SELECTED)
755 struct dtSelect dts;
756 WORD temp;
758 if (dto->dto_SelectRect.MinX > dto->dto_SelectRect.MaxX)
760 temp = dto->dto_SelectRect.MinX;
761 dto->dto_SelectRect.MinX = dto->dto_SelectRect.MaxX;
762 dto->dto_SelectRect.MaxX = temp;
765 if (dto->dto_SelectRect.MinY > dto->dto_SelectRect.MaxY)
767 temp = dto->dto_SelectRect.MinY;
768 dto->dto_SelectRect.MinY = dto->dto_SelectRect.MaxY;
769 dto->dto_SelectRect.MaxY = temp;
772 dto->dto_SelectDomain.Left = dto->dto_SelectRect.MinX;
773 dto->dto_SelectDomain.Top = dto->dto_SelectRect.MinY;
774 dto->dto_SelectDomain.Width = dto->dto_SelectRect.MaxX - dto->dto_SelectRect.MinX + 1;
775 dto->dto_SelectDomain.Height = dto->dto_SelectRect.MaxY - dto->dto_SelectRect.MinY + 1;
777 dtsi->si_Flags |= DTSIF_HIGHLIGHT;
779 dts.MethodID = DTM_SELECT;
780 dts.dts_GInfo = ((struct gpInput *)msg)->gpi_GInfo;
781 dts.dts_Select = dto->dto_SelectRect;
782 DoMethodA(object, (Msg)&dts);
785 Do_OM_NOTIFY((struct Library *)DataTypesBase, object,
786 ((struct gpInput *)msg)->gpi_GInfo, 0, GA_ID,
787 (ULONG)((struct Gadget *)object)->GadgetID,
788 DTA_Busy, FALSE, TAG_DONE );
789 } /* if(DRAGSELECT) */
791 if (dto->dto_Flags & DTOFLGF_HAS_MOVED)
793 Do_OM_NOTIFY((struct Library *)DataTypesBase, object,
794 ((struct gpInput *)msg)->gpi_GInfo, 0, GA_ID,
795 (ULONG)((struct Gadget *)object)->GadgetID,
796 DTA_Sync, TRUE,
797 DTA_TopVert, dtsi->si_TopVert,
798 DTA_TopHoriz, dtsi->si_TopHoriz,
799 TAG_DONE );
801 dto->dto_Flags &= ~DTOFLGF_HAS_MOVED;
804 ReleaseGIRPort(rp);
807 dtsi->si_Flags &= ~(DTSIF_DRAGGING | DTSIF_DRAGSELECT);
808 ((struct Gadget *)object)->Flags &= ~(GFLG_SELECTED | GFLG_RELSPECIAL);
809 } /* case GM_GOINACTIVE */
810 break;
812 case GM_DOMAIN:
813 if(object == NULL)
814 break;
816 if(dtsi != NULL)
818 ; /* TODO */
821 break;
823 /* GM_LAYOUT and DTM_PROCLAYOUT have the same semantics; DTM_PROCLAYOUT
824 must be in the process context, GM_LAYOUT must not. */
825 case GM_LAYOUT:
826 case DTM_PROCLAYOUT:
828 struct GadgetInfo *ginfo;
830 dto->dto_Domain= *((struct IBox *)(&((struct Gadget*)object)->LeftEdge));
832 if((ginfo = ((struct gpLayout *)msg)->gpl_GInfo))
834 struct Window *window;
836 if((window = ginfo->gi_Window))
838 if(dto->dto_Domain.Left < 0)
839 dto->dto_Domain.Left += window->Width - 1;
841 if(dto->dto_Domain.Top < 0)
842 dto->dto_Domain.Top += window->Height - 1;
844 if(dto->dto_Domain.Width < 0)
845 dto->dto_Domain.Width += window->Width;
847 if(dto->dto_Domain.Height < 0)
848 dto->dto_Domain.Height += window->Height;
852 /* Calculate printable dimensions */
853 dto->dto_TotalPHoriz = (dtsi->si_HorizUnit) ?
854 dtsi->si_HorizUnit*dtsi->si_TotHoriz : dto->dto_Domain.Width;
855 dto->dto_TotalPVert = (dtsi->si_VertUnit ) ?
856 dtsi->si_VertUnit*dtsi->si_TotVert : dto->dto_Domain.Height;
858 retval = TRUE;
860 } /* Fall through */ /* case DTM_PROCLAYOUT: */
862 case DTM_FRAMEBOX:
863 if(dto->dto_SourceType == DTST_CLIPBOARD)
865 if(dto->dto_Handle != NULL)
867 CloseIFF((struct IFFHandle *)dto->dto_Handle);
868 CloseClipboard((struct ClipboardHandle *)((struct IFFHandle *)dto->dto_Handle)->iff_Stream);
869 FreeIFF((struct IFFHandle *)dto->dto_Handle);
870 dto->dto_Handle = NULL;
874 break;
876 case DTM_ABORTPRINT:
877 Forbid();
879 if(dto->dto_PrinterProc != NULL)
880 Signal((struct Task *)dto->dto_PrinterProc, SIGBREAKF_CTRL_C);
882 Permit();
884 break;
886 case DTM_PRINT:
887 /* retval = PDERR_CANCEL; -- No printer stuff yet... */
888 SetIoErr(ERROR_NOT_IMPLEMENTED);
889 break;
891 case DTM_REMOVEDTOBJECT: /* TODO... */
892 break;
894 case DTM_WRITE:
895 retval = 0;
896 SetIoErr(ERROR_NOT_IMPLEMENTED);
897 break;
899 case OM_DISPOSE:
900 retval = IoErr();
902 if(dto->dto_DataType != NULL)
904 APTR handle;
906 if((handle = dto->dto_Handle))
908 switch(dto->dto_SourceType)
910 case DTST_FILE:
911 switch(dto->dto_DataType->dtn_Header->dth_Flags & DTF_TYPE_MASK)
913 case DTF_IFF:
914 if(((struct IFFHandle*)handle)->iff_Stream != (IPTR)NULL)
916 CloseIFF((struct IFFHandle *)handle);
917 Close((BPTR)((struct IFFHandle *)handle)->iff_Stream);
920 FreeIFF((struct IFFHandle *)handle);
922 break;
924 case DTF_MISC:
925 UnLock((BPTR)handle);
926 break;
928 default:
929 Close((BPTR)handle);
930 break;
932 break;
934 case DTST_CLIPBOARD:
935 if(dto->dto_Handle != NULL)
937 CloseIFF((struct IFFHandle *)handle);
938 CloseClipboard((struct ClipboardHandle *)((struct IFFHandle *)handle)->iff_Stream);
939 FreeIFF((struct IFFHandle *)handle);
942 break;
943 } /* switch(sourcetype) */
944 } /* if(got handle) */
945 } /* if(datatype != NULL) */
947 if(dto->dto_Name)
948 FreeVec(dto->dto_Name);
950 if(dto->dto_ObjName)
951 FreeVec(dto->dto_ObjName);
953 if(dto->dto_ObjAuthor)
954 FreeVec(dto->dto_ObjAuthor);
956 if(dto->dto_ObjAnnotation)
957 FreeVec(dto->dto_ObjAnnotation);
959 if(dto->dto_ObjCopyright)
960 FreeVec(dto->dto_ObjCopyright);
962 if(dto->dto_ObjVersion)
963 FreeVec(dto->dto_ObjVersion);
965 /* Redirect error to the DataTypes error codes */
966 if(retval == ERROR_OBJECT_NOT_FOUND)
967 retval = DTERROR_COULDNT_OPEN;
969 SetIoErr(retval);
971 /* Fall through so the superclass can free its resources */
972 default:
973 retval = DoSuperMethodA(class, object, msg);
974 break;
977 return retval;
979 AROS_USERFUNC_EXIT
983 /****** datatypes.library/DrawBox *********************************************
985 * NAME
986 * DrawBox - draw a box for area marking
988 * SYNOPSIS
990 * FUNCTION
992 * INPUTS
994 * RETURNS
996 * EXAMPLE
998 * SEE ALSO
1000 ******************************************************************************
1004 void DrawBox(struct Library *DataTypesBase, struct RastPort *rp,
1005 LONG x1, LONG y1, LONG x2, LONG y2)
1007 rp->Flags |= FRST_DOT;
1008 rp->linpatcnt = 15;
1010 SetWriteMask(rp, 0x03);
1012 if(x1 != x2)
1014 Move(rp,x1,y1);
1015 Draw(rp,x2,y1);
1017 Move(rp,x2,y2);
1018 Draw(rp,x1,y2);
1021 if(y1 != y2)
1023 Move(rp,x2,y1);
1024 Draw(rp,x2,y2);
1026 Move(rp,x1,y2);
1027 Draw(rp,x1,y1);
1030 SetWriteMask(rp, 0xff);