revert between 56095 -> 55830 in arch
[AROS.git] / workbench / libs / reqtools / general.c
blob956ac9dacc83c7848f08592b9e2ec17b2489674a
2 /* INCLUDES */
4 #include <exec/types.h>
5 #include <exec/memory.h>
6 #include <exec/execbase.h>
7 #include <libraries/dos.h>
8 #include <libraries/dosextens.h>
9 #include <graphics/gfxmacros.h>
10 #include <graphics/videocontrol.h>
11 #include <graphics/view.h>
12 #include <graphics/gfxbase.h>
13 #include <libraries/gadtools.h>
14 #include <intuition/intuition.h>
15 #include <intuition/intuitionbase.h>
16 #include <intuition/imageclass.h>
17 #include <proto/graphics.h>
18 #include <proto/exec.h>
19 #include <proto/intuition.h>
20 #include <proto/dos.h>
21 #include <proto/gadtools.h>
22 #include <proto/utility.h>
23 #include <clib/macros.h>
24 #include <string.h>
26 #include <libraries/reqtools.h>
27 #include <proto/reqtools.h>
29 #ifdef __AROS__
30 #include <aros/asmcall.h>
31 #endif
33 #include "filereq.h"
35 /****************************************************************************************/
37 /* Use ColorMap.Count to find out number of palette entried on screen */
38 //#define DO_CM_DEPTH
40 /****************************************************************************************/
42 UWORD CHIP waitpointer[] =
44 0x0000,0x0000,
45 0x0400,0x07C0,0x0000,0x07C0,0x0100,0x0380,0x0000,0x07E0,
46 0x07C0,0x1FF8,0x1FF0,0x3FEC,0x3FF8,0x7FDE,0x3FF8,0x7FBE,
47 0x7FFC,0xFF7F,0x7EFC,0xFFFF,0x7FFC,0xFFFF,0x3FF8,0x7FFE,
48 0x3FF8,0x7FFE,0x1FF0,0x3FFC,0x07C0,0x1FF8,0x0000,0x07E0,
49 0x0000,0x0000,
52 /****************************************************************************************/
54 extern struct Library *GadToolsBase;
55 extern struct DosLibrary *DOSBase;
56 extern struct IntuitionBase *IntuitionBase;
57 extern struct GfxBase *GfxBase;
58 extern struct ReqToolsBase *ReqToolsBase;
59 #if defined(__AROS__) || defined(__GNUC__)
60 extern struct UtilityBase *UtilityBase;
61 #else
62 extern struct Library *UtilityBase;
63 #endif
65 /****************************************************************************************/
67 int ASM SAVEDS GetVScreenSize (
68 REGPARAM(a0, struct Screen *, scr),
69 REGPARAM(a1, int *, width),
70 REGPARAM(a2, int *, height))
72 struct ViewPortExtra *vpe;
73 struct Rectangle dispclip, *clip;
74 IPTR getvpetags[3];
75 int ht;
76 #ifndef USE_FORBID
77 struct Screen *pubscr;
78 ULONG ilock = 0L;
79 BOOL isfirst;
80 #endif
83 getvpetags[0] = VTAG_VIEWPORTEXTRA_GET;
84 getvpetags[1] = (IPTR)&vpe;
85 getvpetags[2] = TAG_END;
87 #ifdef USE_FORBID
89 Forbid();
91 if (IntuitionBase->FirstScreen == scr &&
92 VideoControl (scr->ViewPort.ColorMap, (struct TagItem *)getvpetags) == 0)
94 clip = &((struct ViewPortExtra *)getvpetags[1])->DisplayClip;
96 else
98 QueryOverscan (GetVPModeID (&scr->ViewPort), &dispclip, OSCAN_TEXT);
99 clip = &dispclip;
102 Permit();
104 #else
106 if ((pubscr = LockPubScreenByAddr(scr)))
108 /* Cool, we got a lock on the screen, we don't need to Forbid() */
109 ilock = LockIBase(0);
111 else
113 /* damn it, not a pubscreen, Forbid() as a last resort */
114 Forbid();
117 isfirst = (IntuitionBase->FirstScreen == scr);
119 if (pubscr)
121 UnlockIBase(ilock);
124 if (isfirst &&
125 VideoControl (scr->ViewPort.ColorMap, (struct TagItem *)getvpetags) == 0)
127 clip = &((struct ViewPortExtra *)getvpetags[1])->DisplayClip;
129 else
131 QueryOverscan (GetVPModeID (&scr->ViewPort), &dispclip, OSCAN_TEXT);
132 clip = &dispclip;
134 if (pubscr)
136 UnlockPubScreen(NULL, pubscr);
138 else
140 Permit();
143 #endif
145 *width = clip->MaxX - clip->MinX + 1;
146 *height = ht = clip->MaxY - clip->MinY + 1;
148 if (scr->Width < *width) *width = scr->Width;
149 if (scr->Height < *height) *height = scr->Height;
151 return ((ht >= 400) ? 4 : 2);
154 /****************************************************************************************/
156 struct Screen *REGARGS LockPubScreenByAddr (struct Screen *scr)
158 struct List *pubscreenlist;
159 struct PubScreenNode *pubscreennode;
160 UBYTE pubscreenname[MAXPUBSCREENNAME + 1];
162 pubscreenname[0] = '\0';
164 pubscreenlist = LockPubScreenList();
165 pubscreennode = (struct PubScreenNode *) pubscreenlist->lh_Head;
166 while (pubscreennode->psn_Node.ln_Succ)
168 if (pubscreennode->psn_Screen == scr)
170 strcpy(pubscreenname, pubscreennode->psn_Node.ln_Name);
171 break;
173 pubscreennode = (struct PubScreenNode *) pubscreennode->psn_Node.ln_Succ;
175 UnlockPubScreenList();
177 /* If we found a matching pubscreen try to lock it (note: can fail) */
178 if (pubscreenname[0])
180 scr = LockPubScreen(pubscreenname);
182 else
184 scr = NULL;
187 return scr;
190 /****************************************************************************************/
193 #undef ThisProcess
194 #define ThisProcess() ( ( APTR ) FindTask( NULL ) )
196 /****************************************************************************************/
198 struct Screen *REGARGS GetReqScreen (
199 struct NewWindow *nw, struct Window **prwin, struct Screen *scr, char *pubname)
201 struct Window *win = *prwin;
202 struct Process *proc;
204 if (!pubname && !scr && !win)
206 proc = ThisProcess();
207 if (proc->pr_Task.tc_Node.ln_Type == NT_PROCESS) win = proc->pr_WindowPtr;
210 nw->Type = CUSTOMSCREEN;
211 if (scr && !win)
213 struct Screen *pubscr;
215 /* Try to lock the screen as a public screen */
216 if ((pubscr = LockPubScreenByAddr(scr)))
218 scr = pubscr;
219 nw->Type = PUBLICSCREEN;
221 /* FIXME: probably should do something smart if the locking fail.
222 RT_Screen is more than dangerous if you ask me... - Piru */
224 else
226 if (win && (IPTR)win != ~0) scr = win->WScreen;
227 else
229 if (!(scr = LockPubScreen (pubname)))
230 if (!(scr = LockPubScreen (NULL))) return (NULL);
232 nw->Type = PUBLICSCREEN;
233 win = NULL;
236 *prwin = win;
237 return (nw->Screen = scr);
240 /****************************************************************************************/
242 #ifndef DO_CM_DEPTH
243 static int VpDepth (struct ViewPort *vp)
245 ULONG modeid = GetVPModeID (vp);
246 int depth;
248 depth = vp->RasInfo->BitMap->Depth;
250 if (modeid & HAM_KEY) depth -= 2;
251 if (modeid & EXTRAHALFBRITE_KEY) depth = 5;
253 if( depth > 8 )
255 depth = 8;
258 return (depth);
260 #endif
262 /****************************************************************************************/
264 int REGARGS
265 GetVpCM( struct ViewPort *vp, APTR *cmap)
268 #ifdef DO_CM_DEPTH
269 int numcols;
271 if( !vp->ColorMap )
273 return( 0 );
276 numcols = vp->ColorMap->Count;
277 #else
278 int depth, numcols;
280 if( !vp->ColorMap )
282 return( 0 );
285 depth = VpDepth (vp);
286 numcols = (1 << depth);
287 #endif
288 if( GfxBase->LibNode.lib_Version >= 39 )
290 if( ( *cmap = AllocVec( ( numcols * 3 + 2 ) * 4, MEMF_PUBLIC | MEMF_CLEAR ) ) )
292 ( ( UWORD * ) ( *cmap ) )[ 0 ] = numcols;
295 else
297 *cmap = AllocVec( numcols * 2, MEMF_PUBLIC | MEMF_CLEAR );
300 if( *cmap )
302 RefreshVpCM( vp, *cmap );
303 return( depth );
305 else
307 return( 0 );
311 /****************************************************************************************/
313 void REGARGS
314 RefreshVpCM( struct ViewPort *vp, APTR cmap )
316 #ifdef DO_CM_DEPTH
317 int numcols, i;
319 numcols = vp->ColorMap->Count;
320 #else
321 int i, depth, numcols;
323 depth = VpDepth( vp );
324 numcols = ( 1 << depth );
325 #endif
326 if( GfxBase->LibNode.lib_Version >= 39 )
328 GetRGB32( vp->ColorMap, 0, numcols, ( ( ULONG * ) cmap ) + 1 );
330 else
332 for( i = 0; i < numcols; i++ )
334 ( ( UWORD * ) cmap )[ i ] = GetRGB4( vp->ColorMap, i );
339 /****************************************************************************************/
341 void REGARGS LoadCMap (struct ViewPort *vp, APTR cmap)
343 if (GfxBase->LibNode.lib_Version >= 39) LoadRGB32 (vp, cmap);
344 #ifdef DO_CM_DEPTH
345 else LoadRGB4 (vp, cmap, vp->ColorMap->Count);
346 #else
347 else LoadRGB4 (vp, cmap, (1 << VpDepth (vp)));
348 #endif
351 /****************************************************************************************/
353 void REGARGS FreeVpCM (struct ViewPort *vp, APTR cmap, BOOL restore)
355 if (restore && cmap) LoadCMap (vp, cmap);
356 FreeVec (cmap);
359 /****************************************************************************************/
361 void REGARGS InitNewGadget (struct NewGadget *ng,
362 int x, int y, int w, int h, char *s, UWORD id)
364 ng->ng_LeftEdge = x; ng->ng_TopEdge = y; ng->ng_Width = w; ng->ng_Height = h;
365 ng->ng_GadgetText = s; ng->ng_GadgetID = id;
368 /****************************************************************************************/
370 struct TextFont * REGARGS GetReqFont (struct TextAttr *attr,
371 struct TextFont *deffont, int *fontheight, int *fontwidth, int allowprop)
373 struct TextFont *ft;
374 int forcedef;
376 forcedef = (rtLockPrefs()->Flags & RTPRF_DEFAULTFONT);
377 rtUnlockPrefs();
379 ft = OpenFont (attr);
380 if (!ft || forcedef || (!allowprop && (ft->tf_Flags & FPF_PROPORTIONAL)))
382 if (ft) CloseFont (ft);
383 if (deffont) ft = deffont;
384 else ft = GfxBase->DefaultFont;
386 attr->ta_Name = ft->tf_Message.mn_Node.ln_Name;
387 attr->ta_YSize = ft->tf_YSize;
388 attr->ta_Style = ft->tf_Style;
389 attr->ta_Flags = ft->tf_Flags;
390 ft = OpenFont (attr);
393 if (ft)
395 *fontheight = ft->tf_YSize;
396 *fontwidth = ft->tf_XSize;
399 return (ft);
402 /****************************************************************************************/
404 struct IntuiMessage *REGARGS GetWin_GT_Msg (struct Window *win,
405 struct Hook *hook, APTR req)
407 struct IntuiMessage *imsg, *reqmsg;
409 while ((imsg = (struct IntuiMessage *)GetMsg (win->UserPort)))
410 if ((reqmsg = ProcessWin_Msg (win, imsg, hook, req))) return (reqmsg);
412 return (NULL);
415 /****************************************************************************************/
417 struct IntuiMessage *REGARGS ProcessWin_Msg (struct Window *win,
418 struct IntuiMessage *imsg, struct Hook *hook, APTR req)
420 struct IntuiMessage *reqmsg;
422 if (imsg->IDCMPWindow == win)
424 reqmsg = GT_FilterIMsg (imsg);
425 if (reqmsg) return (reqmsg);
426 ReplyMsg ((struct Message *)imsg);
428 else
430 if (hook) CallHookPkt (hook, req, imsg);
431 ReplyMsg ((struct Message *)imsg);
434 return (NULL);
437 /****************************************************************************************/
439 void REGARGS Reply_GT_Msg (struct IntuiMessage *reqmsg)
441 ReplyMsg ((struct Message *)GT_PostFilterIMsg (reqmsg));
444 /****************************************************************************************/
446 void REGARGS DoScreenToFront (struct Screen *scr, int nopop, int popup)
448 ULONG noscrtofront;
450 if (nopop) return;
452 noscrtofront = (rtLockPrefs()->Flags & RTPRF_NOSCRTOFRONT);
453 rtUnlockPrefs();
455 if (noscrtofront) return;
456 if (popup)
457 ScreenToFront (scr);
458 else
459 rtScreenToFrontSafely (scr);
463 /****************************************************************************************/
465 void REGARGS DoCloseWindow (struct Window *win, int idcmpshared)
467 if (idcmpshared) rtCloseWindowSafely (win);
468 else CloseWindow (win);
471 /****************************************************************************************/
473 struct BackFillMsg
475 struct Layer *layer;
476 struct Rectangle bounds;
477 LONG offsetx;
478 LONG offsety;
481 /****************************************************************************************/
483 #ifdef __AROS__
484 AROS_UFH3(void, WinBackFill,
485 AROS_UFHA(struct Hook *, hook, A0),
486 AROS_UFHA(struct RastPort *, the_rp, A2),
487 AROS_UFHA(struct BackFillMsg *, msg, A1))
489 AROS_USERFUNC_INIT
490 #else
491 void SAVEDS ASM WinBackFill (
492 REGPARAM(a0, struct Hook *, hook),
493 REGPARAM(a2, struct RastPort *, the_rp),
494 REGPARAM(a1, struct BackFillMsg *, msg))
496 #endif
497 struct RastPort rp;
499 memcpy( &rp, the_rp, sizeof( rp ) );
500 rp.Layer = NULL;
501 SetAPen (&rp, ((UWORD *)hook->h_Data)[BACKGROUNDPEN]);
502 mySetWriteMask (&rp, ~0);
503 RectFill (&rp, msg->bounds.MinX, msg->bounds.MinY,
504 msg->bounds.MaxX, msg->bounds.MaxY);
506 #ifdef __AROS__
507 AROS_USERFUNC_EXIT
508 #endif
511 /****************************************************************************************/
513 #ifdef __AROS__
515 AROS_UFH3(void, PatternWinBackFill,
516 AROS_UFHA(struct Hook *, hook, A0),
517 AROS_UFHA(struct RastPort *, the_rp, A2),
518 AROS_UFHA(struct BackFillMsg *, msg, A1))
520 AROS_USERFUNC_INIT
522 struct RastPort rp;
523 UWORD pattern[] = {0xAAAA,0x5555};
525 memcpy( &rp, the_rp, sizeof( rp ) );
526 rp.Layer = NULL;
528 SetAPen (&rp, ((UWORD *)hook->h_Data)[BACKGROUNDPEN]);
529 SetBPen (&rp, ((UWORD *)hook->h_Data)[SHINEPEN]);
530 SetDrMd (&rp, JAM2);
532 mySetWriteMask (&rp, ~0);
534 SetAfPt(&rp, pattern, 1);
536 RectFill (&rp, msg->bounds.MinX, msg->bounds.MinY,
537 msg->bounds.MaxX, msg->bounds.MaxY);
539 SetAfPt(&rp, NULL, 0);
541 AROS_USERFUNC_EXIT
544 #endif
546 /****************************************************************************************/
548 void REGARGS mySetWriteMask (struct RastPort *rp, ULONG mask)
550 if (GfxBase->LibNode.lib_Version >= 39) SetWriteMask (rp, mask);
551 else SetWrMsk (rp, (UBYTE)mask);
554 /****************************************************************************************/
556 struct Window *REGARGS OpenWindowBF (struct NewWindow *nw,
557 struct Hook *hook, UWORD *pens, ULONG *maskptr, WORD *zoom,
558 BOOL backfillpattern)
560 struct RastPort *rp;
561 struct Window *win;
562 IPTR tags[5], mask;
563 UWORD maxpen = 0;
564 int i;
566 #ifdef __AROS__
567 if (backfillpattern)
569 hook->h_Entry = (HOOKFUNC)PatternWinBackFill;
570 } else
571 #endif
572 hook->h_Entry = (HOOKFUNC)WinBackFill;
574 hook->h_Data = (void *)pens;
576 tags[0] = WA_BackFill;
577 tags[1] = (IPTR)hook;
578 tags[2] = WA_Zoom;
579 tags[3] = (IPTR)zoom;
580 tags[4] = TAG_END;
582 if( zoom )
584 if (IntuitionBase->LibNode.lib_Version >= 39)
585 zoom[0] = zoom[1] = ~0;
586 else
588 zoom[0] = nw->LeftEdge;
589 zoom[1] = nw->TopEdge;
592 else
594 tags[2] = TAG_IGNORE;
597 if ((win = OpenWindowTagList (nw, (struct TagItem *)tags)))
599 rp = win->RPort;
600 for (i = 0; i <= HIGHLIGHTTEXTPEN; i++)
601 if (pens[i] > maxpen) maxpen = pens[i];
603 mask = 1;
604 while (mask < maxpen)
606 mask <<= 1;
607 mask |= 1;
610 mySetWriteMask (rp, mask);
611 if (maskptr) *maskptr = mask;
614 return (win);
618 /****************************************************************************************/
620 int CheckReqPos (int reqpos, int reqdefnum, struct NewWindow *newwin)
622 struct ReqDefaults *reqdefs;
624 if (reqpos == REQPOS_DEFAULT)
626 reqdefs = &rtLockPrefs()->ReqDefaults[reqdefnum];
627 reqpos = reqdefs->ReqPos;
629 if (reqpos <= REQPOS_CENTERSCR)
631 newwin->LeftEdge = 0;
632 newwin->TopEdge = 0;
634 else
636 newwin->LeftEdge = reqdefs->LeftOffset;
637 newwin->TopEdge = reqdefs->TopOffset;
640 rtUnlockPrefs();
643 return (reqpos);
646 /****************************************************************************************/
648 /*********
649 * Layout *
650 *********/
652 /****************************************************************************************/
654 int REGARGS StrWidth_noloc (struct IntuiText *itxt, UBYTE *str)
656 char labstr[100], *l;
658 if (!str) return (0);
660 /* Copy string, remove underscore */
661 l = labstr;
662 while (*str && *str != '_') *l++ = *str++;
664 if (*str) while ((*l++ = *++str)); else *l = 0;
666 itxt->IText = labstr;
668 return (IntuiTextLength (itxt));
671 /****************************************************************************************/
673 static int ObjectWidth (struct NewGadget *ng, int normalw, int normalh)
675 if ((GadToolsBase->lib_Version >= 39) && (ng->ng_TextAttr->ta_YSize > normalh))
676 return (normalw + (ng->ng_TextAttr->ta_YSize - normalh) * 2);
678 return (normalw);
681 /****************************************************************************************/
683 static int ObjectHeight (struct NewGadget *ng, int normalh)
685 if ((GadToolsBase->lib_Version >= 39) && (ng->ng_TextAttr->ta_YSize > normalh))
686 return (ng->ng_TextAttr->ta_YSize);
688 return (normalh);
691 /****************************************************************************************/
693 int CheckBoxWidth (struct NewGadget *ng)
695 return (ObjectWidth (ng, CHECKBOX_WIDTH, CHECKBOX_HEIGHT));
698 /****************************************************************************************/
700 int CheckBoxHeight (struct NewGadget *ng)
702 return (ObjectHeight (ng, CHECKBOX_HEIGHT));
705 /****************************************************************************************/
708 * SIZEGAD HEIGHT
710 LONG BottomBorderHeight (struct Screen *scr)
712 struct DrawInfo *dri;
713 APTR obj;
714 LONG h = 10;
716 if ((dri = GetScreenDrawInfo (scr)))
718 if((obj = NewObject (NULL, "sysiclass", SYSIA_DrawInfo, (IPTR) dri,
719 /* Must be SYSISIZE_MEDRES! */
720 SYSIA_Size, SYSISIZE_MEDRES,
721 SYSIA_Which, SIZEIMAGE,
722 TAG_DONE)))
724 if (!GetAttr (IA_Height, obj, (IPTR *)&h))
725 h = 10; // Probably not needed.. Or?
726 DisposeObject( obj );
728 FreeScreenDrawInfo (scr, dri);
730 return (h);
733 /****************************************************************************************/