6 #include <exec/types.h>
7 #include <exec/memory.h>
8 #include <dos/dostags.h>
9 #include <graphics/gfx.h>
10 #include <graphics/text.h>
11 #include <intuition/intuition.h>
12 #include <libraries/mcpgfx.h>
13 #include <libraries/gadtools.h>
14 #include <libraries/ttengine.h>
15 #include <utility/tagitem.h>
16 #include <workbench/startup.h>
17 #include <datatypes/pictureclass.h>
24 #include <proto/dos.h>
25 #include <proto/exec.h>
26 #include <proto/gadtools.h>
27 #include <proto/graphics.h>
28 #include <proto/intuition.h>
29 #include <proto/datatypes.h>
30 #include <proto/layers.h>
31 #include <proto/diskfont.h>
33 #include <proto/scalos.h>
34 #include <proto/scalosplugin.h>
36 #include <clib/alib_protos.h>
39 #include <Year.h> // +jmc+
40 #include <ScalosMcpGfx.h>
42 #include <scalos/scalos.h>
44 #include "scalos_structures.h"
45 #include "functions.h"
46 #include "Variables.h"
50 #include "DtImageClass.h"
52 //----------------------------------------------------------------------------
54 #define ABOUT_BITMAP_HEIGHT 150
57 * 0 = Font: n = normal, b =bold, i = italic, j = bold+italic
58 * 1 = DRIPen: 0..9 (ascii)
59 * 2 = Justify: l = left, r = right, c = centered
60 * 3-5 = SkipLines: 3 digits (decimal) = height in pixels to skip after this textline
62 #define FmtHeader_Length 6
64 #define ABOUT_GADGET_IMAGE_BASENAME "THEME:About"
66 #define ABOUT_NUMBER_OF_GADGETS 5
68 //----------------------------------------------------------------------------
70 /* Note: the only good thing I can think of about the underscores being there
71 * is that we won't have any name conflicts even if we give them the same name
72 * in the C files, cos they'll all have underscores added :)
75 static CONST_STRPTR bSysinfomodule
= "SystemInfo.module";
77 static STRPTR bAboutname
= "Scalos_About"; /* Name of the task & command which gets run for the about window */
78 static const STRPTR bCopyright
= "© Copyright 2000" CURRENTYEAR
"The Scalos Team";
82 ABOUT_GADGETID_OK
= 100,
84 ABOUT_GADGETID_SYSINFO
,
89 //----------------------------------------------------------------------------
91 static LONG
RunAbout(struct internalScaWindowTask
*iwt
, LONG lOkenabled
, struct MsgPort
*mp_Replyport
);
92 static ULONG
NewAbout(APTR dummy
, struct SM_RunProcess
*msg
);
93 static BOOL
ReadAboutBackground(struct DatatypesImage
**Logo
);
94 static void GenerateLogo(struct AboutInfo
*abi
);
95 static STRPTR
ExpandText(CONST_STRPTR Text
);
96 static void FreeExpandedText(STRPTR Text
);
97 static struct ttDef
*CreateDiskPluginList(struct AboutInfo
*abi
);
98 static struct ttDef
*CreateAboutText(struct AboutInfo
*abi_About
, ULONG MsgId
);
99 static BOOL
InitAboutBitMap(struct AboutBitMap
*abm
, LONG Width
, LONG Height
, struct BitMap
*windowBM
);
100 static void CleanupAboutBitMap(struct AboutBitMap
*abm
);
101 static struct AboutGadgetInfo
*AboutCreateButton(const struct AboutGadgetDef
*agd
, struct Gadget
*PrevGadget
);
102 static void AboutFreeButton(struct AboutGadgetInfo
*agi
);
103 static struct IntuiMessage
*ScrollUp(struct AboutInfo
*abi_Scroll
, LONG lLines
, LONG lXoffset
, LONG lWidth
, LONG ttHeight
);
104 static void FillRegInfo(STRPTR deststring
, size_t MaxLen
);
105 static void ScaFlush(void);
106 static void ScaReboot(struct Window
*win_Parent
);
107 static void SystemInfo(void);
108 static void InitialShowAbout(struct AboutInfo
*abi
, LONG lXoffset
, LONG lWidth
);
109 static SAVEDS(CONST_STRPTR
) AboutGadgetTextHookFunc(struct Hook
*hook
, Object
*o
, LONG GadgetID
);
110 static void AboutBackfill(struct AboutInfo
*abi
);
111 static void AboutInfoCleanup(struct AboutInfo
*ab
);
113 //----------------------------------------------------------------------------
115 static struct Hook AboutGadgetTextHook
=
118 HOOKFUNC_DEF(AboutGadgetTextHookFunc
), // h_Entry + h_SubEntry
122 //----------------------------------------------------------------------------
124 /* Simply a stub function for things like the about menu item
125 * to call the run the code for the about requester with no
128 void AboutProg(struct internalScaWindowTask
*iwt
, const struct MenuCmdArg
*mcArg
)
130 RunAbout(iwt
, 0, NULL
);
136 * Parameters LONG ok_enabled = flag to show whether the OK button in the about requester is enabled or not
137 * struct MsgPort *replyport = the message port to send any replies to when finished
138 * Returns LONG = success
140 static LONG
RunAbout(struct internalScaWindowTask
*iwt
, LONG lOkenabled
, struct MsgPort
*mp_Replyport
)
142 struct SM_RunProcess
*smrp_Message
; /* Message allocated for running procedure */
144 d1(kprintf("%s/%s/%ld: \n", __FILE__
, __FUNC__
, __LINE__
));
146 if (NULL
!= (smrp_Message
= (struct SM_RunProcess
*) SCA_AllocMessage(MTYP_RunProcess
, 4)) )
148 smrp_Message
->ScalosMessage
.sm_Message
.mn_ReplyPort
= mp_Replyport
;
149 smrp_Message
->EntryPoint
= NewAbout
;
150 smrp_Message
->Flags
= lOkenabled
;
151 smrp_Message
->WindowTask
= &iwt
->iwt_WindowTask
;
153 d1(kprintf("%s/%s/%ld: \n", __FILE__
, __FUNC__
, __LINE__
));
156 &smrp_Message
->ScalosMessage
,
158 NP_CommandName
, (IPTR
) bAboutname
,
159 NP_Name
, (IPTR
) bAboutname
,
162 d1(kprintf("%s/%s/%ld: \n", __FILE__
, __FUNC__
, __LINE__
));
172 * Description The code for the embedded task which opens the About window
173 * and scrolls the text
175 static ULONG
NewAbout(APTR dummy
, struct SM_RunProcess
*msg
)
177 struct AboutInfo
*abi
; /* information for about requester */
178 LONG lWidest
; /* Pixel width of widest string for gadgets */
179 LONG lScrollwidth
; /* Width of the scrolling area of the window */
180 LONG lScrollheight
; /* Height of the amount of scrolling that will take place */
181 UWORD lastGadgetID
= 0;
183 struct Gadget
*StopGadget
= NULL
;
184 struct Region
*rg_Region
; /* new region that we want to install for clipping the drawing commands */
185 struct Region
*rg_Oldregion
; /* region which was previously set in the window */
186 struct Rectangle ra_Regionsize
; /* size of the above regions */
187 struct AboutGadgetInfo
*agi
;
188 static const ULONG IDCMPFlags
= IDCMP_GADGETUP
| IDCMP_GADGETHELP
| IDCMP_MOUSEBUTTONS
;
192 static const struct AboutGadgetDef AboutGadgets
[] =
194 { "ButtonOkNormal", "ButtonOkSelected", "ButtonOkDisabled", MSGID_OKNAME
, ABOUT_GADGETID_OK
, LEFTIMAGE
},
195 { "ButtonStopNormal", "ButtonStopSelected", "ButtonStopDisabled", MSGID_ABOUTHOLDSCROLLNAME
, ABOUT_GADGETID_STOP
, LEFTIMAGE
},
196 { "ButtonInfoNormal", "ButtonInfoSelected", "ButtonInfoDisabled", MSGID_SYSINFONAME
, ABOUT_GADGETID_SYSINFO
, LEFTIMAGE
},
197 { "ButtonFlushNormal", "ButtonFlushSelected", "ButtonFlushDisabled", MSGID_FLUSHNAME
, ABOUT_GADGETID_FLUSH
, LEFTIMAGE
},
198 { "ButtonRebootNormal", "ButtonRebootSelected", "ButtonRebootDisabled", MSGID_REBOOTNAME
, ABOUT_GADGETID_REBOOT
, LEFTIMAGE
},
200 int iQuit
; /* Flag to show whether to quit secondary event loop or not */
205 struct Gadget
*PrevGadget
= NULL
;
207 LONG MaxButtonHeight
;
208 LONG GadgetLeft
, GadgetTop
;
210 BOOL DisableSysInfo
= TRUE
; // only enable SysInfo Gadget if sysinfo modules available
211 BPTR ModsDirLock
= LockScaModsDir();
213 d1(kprintf("%s/%s/%ld: \n", __FILE__
, __FUNC__
, __LINE__
));
215 /* Try to allocate memory to hold ABoutInfo structure (which is where everything to
216 * do with the about window is stored.
218 abi
= ScalosAlloc(sizeof(struct AboutInfo
));
222 memset(abi
, 0, sizeof(struct AboutInfo
));
224 NewList(&abi
->abi_GadgetList
);
226 d1(KPrintF("%s/%s/%ld: pref_UseScreenTTFont=%ld FontDesc=<%s>\n", \
227 __FILE__
, __FUNC__
, __LINE__
, CurrentPrefs
.pref_UseScreenTTFont
, \
228 CurrentPrefs
.pref_ScreenTTFontDescriptor
));
230 if (CurrentPrefs
.pref_UseScreenTTFont
)
231 abi
->abi_ttDesc
= CurrentPrefs
.pref_ScreenTTFontDescriptor
;
233 abi
->abi_ttDesc
= NULL
;
235 /* Create a BitMap to hold the Scalos logo. Decode logo from executable
240 ReadAboutBackground(&abi
->abi_Background
);
242 abi
->abi_ttd
= CreateAboutText(abi
, MSGID_ABOUT_TESTTEXT
);
243 if (NULL
== abi
->abi_ttd
)
246 abi
->abi_Font
= OpenDiskFont(iInfos
.xii_iinfos
.ii_Screen
->Font
);
248 for (n
= 0; n
< Sizeof(AboutGadgets
); n
++)
250 agi
= AboutCreateButton(&AboutGadgets
[n
], PrevGadget
);
253 AddTail(&abi
->abi_GadgetList
, &agi
->agi_Node
);
254 PrevGadget
= agi
->agi_Gadget
;
260 /* Collect width of the generated gadgets */
262 MaxButtonWidth
= MaxButtonHeight
= 0;
263 for (agi
= (struct AboutGadgetInfo
*) abi
->abi_GadgetList
.lh_Head
;
264 agi
!= (struct AboutGadgetInfo
*) &abi
->abi_GadgetList
.lh_Tail
;
265 agi
= (struct AboutGadgetInfo
*) agi
->agi_Node
.ln_Succ
)
267 lWidest
+= 20 + agi
->agi_Width
;
268 MaxButtonHeight
= max(MaxButtonHeight
, agi
->agi_Height
);
269 MaxButtonWidth
= max(MaxButtonWidth
, 5 + agi
->agi_Width
);
270 d1(KPrintF("%s/%s/%ld: agi_Width=%lu agi_Height=%lu\n", __FILE__
, __FUNC__
, __LINE__
, agi
->agi_Width
, agi
->agi_Height
));
273 Scalos_InitRastPort(&rp
);
275 TTLayout(&rp
, abi
->abi_ttd
, &ttBox
, TTL_Vertical
, NULL
);
277 d1(KPrintF("%s/%s/%ld: Width=%lu Height=%lu\n", __FILE__
, __FUNC__
, __LINE__
, ttBox
.Width
, ttBox
.Height
));
279 lWidest
= max(lWidest
, ttBox
.Width
);
281 /* Get widest width of formatted scroller strings and add some extra space to it */
282 lScrollwidth
= lWidest
;
283 lWidest
+= (iInfos
.xii_iinfos
.ii_Screen
->WBorLeft
+ iInfos
.xii_iinfos
.ii_Screen
->WBorRight
+ 14);
284 lScrollheight
= abi
->abi_Font
->tf_YSize
* 20;
285 lScrollheight
+= (lScrollheight
/10 + iInfos
.xii_iinfos
.ii_Screen
->WBorBottom
+ iInfos
.xii_iinfos
.ii_Screen
->WBorTop
);
287 WindowHeight
= lScrollheight
+ (2 * MaxButtonHeight
);
289 d1(kprintf("%s/%s/%ld: \n", __FILE__
, __FUNC__
, __LINE__
));
291 /* Try to open about window */
292 abi
->abi_Window
= LockedOpenWindowTags(NULL
,
293 WA_Title
, (IPTR
) GetLocString(MSGID_ABOUTNAME
),
294 WA_CustomScreen
, (IPTR
) iInfos
.xii_iinfos
.ii_Screen
,
295 WA_IDCMP
, IDCMPFlags
,
298 WA_DepthGadget
, TRUE
,
300 WA_HelpGroup
, HelpGroupID
,
301 WA_Height
, WindowHeight
,
303 WA_Top
, (iInfos
.xii_iinfos
.ii_Screen
->Height
- WindowHeight
+ 1)/2,
304 WA_Left
, (iInfos
.xii_iinfos
.ii_Screen
->Width
- lWidest
+ 1)/2,
305 WA_SCA_Opaqueness
, SCALOS_OPAQUENESS(0),
308 if (NULL
== abi
->abi_Window
)
311 Scalos_SetFont(abi
->abi_Window
->RPort
, abi
->abi_Font
, NULL
);
313 d1(kprintf("%s/%s/%ld: \n", __FILE__
, __FUNC__
, __LINE__
));
315 /* Store various dimensions about the window */
316 abi
->abi_wInnerleft
= abi
->abi_Window
->BorderLeft
;
317 abi
->abi_wInnerright
= abi
->abi_Window
->BorderRight
;
318 abi
->abi_wInnertop
= abi
->abi_Window
->BorderTop
;
319 abi
->abi_wInnerbottom
= abi
->abi_Window
->BorderBottom
;
320 abi
->abi_wInnerwidth
= abi
->abi_Window
->Width
- (abi
->abi_wInnerleft
+ abi
->abi_wInnerright
);
321 abi
->abi_wInnerheight
= abi
->abi_Window
->Height
- (abi
->abi_wInnertop
+ abi
->abi_wInnerbottom
);
323 // Check if SysInfo module is available
327 BPTR oldDir
= CurrentDir(ModsDirLock
);
329 siLock
= Lock((STRPTR
) bSysinfomodule
, ACCESS_READ
);
332 DisableSysInfo
= FALSE
;
340 GadgetLeft
= abi
->abi_Window
->Width
/ (2 * Sizeof(AboutGadgets
));
341 GadgetTop
= abi
->abi_wInnertop
+ abi
->abi_wInnerheight
- (5 + MaxButtonHeight
);
343 for (agi
= (struct AboutGadgetInfo
*) abi
->abi_GadgetList
.lh_Head
;
344 agi
!= (struct AboutGadgetInfo
*) &abi
->abi_GadgetList
.lh_Tail
;
345 agi
= (struct AboutGadgetInfo
*) agi
->agi_Node
.ln_Succ
)
347 SetAttrs(agi
->agi_Gadget
,
348 GA_Left
, GadgetLeft
- (agi
->agi_Width
/ 2),
352 if (ABOUT_GADGETID_STOP
== agi
->agi_Gadget
->GadgetID
)
354 StopGadget
= agi
->agi_Gadget
;
355 SetAttrs(agi
->agi_Gadget
,
356 GA_ToggleSelect
, TRUE
,
360 else if (ABOUT_GADGETID_SYSINFO
== agi
->agi_Gadget
->GadgetID
)
362 SetAttrs(agi
->agi_Gadget
,
363 GA_Disabled
, DisableSysInfo
,
367 GadgetLeft
+= abi
->abi_Window
->Width
/ Sizeof(AboutGadgets
);
370 d1(KPrintF("%s/%s/%ld: StopGadget=%08lx\n", __FILE__
, __FUNC__
, __LINE__
, StopGadget
));
372 /* Try to allocate a new region, which will be used to clip the
373 * drawing of the backfill pattern on the window.
376 rg_Region
= NewRegion();
377 if (NULL
== rg_Region
)
380 /* Set size of region to be used for clipping */
381 ra_Regionsize
.MinX
= 0; ra_Regionsize
.MinY
= 0;
382 ra_Regionsize
.MaxX
= abi
->abi_Window
->Width
;
383 ra_Regionsize
.MaxY
= abi
->abi_Window
->Height
;
385 /* Draw a rectangle on the region which drawing will be enabled through it */
386 if (!OrRectRegion(rg_Region
, &ra_Regionsize
))
389 /* Set up another rectangular area for clipping */
390 ra_Regionsize
.MinX
= abi
->abi_wInnerleft
+ 5;
391 ra_Regionsize
.MinY
= abi
->abi_wInnertop
+ 5;
392 ra_Regionsize
.MaxX
= abi
->abi_wInnerleft
+ abi
->abi_wInnerwidth
- 6;
393 ra_Regionsize
.MaxY
= abi
->abi_wInnertop
+ abi
->abi_wInnerheight
- (6 + 14) - Scalos_GetFontHeight(abi
->abi_Window
->RPort
);
395 /* Clear the rectangle so that all drawing will be clipped inside it */
396 if (!ClearRectRegion(rg_Region
, &ra_Regionsize
))
399 /* Put the new region into the window and get pointer to the current one */
400 rg_Oldregion
= InstallClipRegion(abi
->abi_Window
->WLayer
, rg_Region
);
404 /* restore the original clipping region. we don't check the return value
405 * since it should just be a pointer to the region which we created
406 * (rg_Region) and are now going to free.
408 InstallClipRegion(abi
->abi_Window
->WLayer
, rg_Oldregion
);
409 DisposeRegion(rg_Region
);
411 /* Re-use co-ordinates that were used for the last clipping mask (the one
412 * through which all drawing was clipped)
414 ra_Regionsize
.MaxX
++; ra_Regionsize
.MaxY
++;
415 McpGfxDrawFrame(abi
->abi_Window
->RPort
, ra_Regionsize
.MinX
, ra_Regionsize
.MinY
,
416 ra_Regionsize
.MaxX
, ra_Regionsize
.MaxY
,
417 IA_ShadowPen
, iInfos
.xii_iinfos
.ii_DrawInfo
->dri_Pens
[SHADOWPEN
],
418 IA_HighlightPen
, iInfos
.xii_iinfos
.ii_DrawInfo
->dri_Pens
[SHINEPEN
],
420 IA_FrameType
, MF_FRAME_BUTTON
,
423 d1(kprintf("%s/%s/%ld: \n", __FILE__
, __FUNC__
, __LINE__
));
425 /* Attach gadgets to window and refresh them */
426 AddGList(abi
->abi_Window
,
427 ((struct AboutGadgetInfo
*) abi
->abi_GadgetList
.lh_Head
)->agi_Gadget
,
431 RefreshGList(((struct AboutGadgetInfo
*) abi
->abi_GadgetList
.lh_Head
)->agi_Gadget
,
434 Sizeof(AboutGadgets
));
436 d1(kprintf("%s/%s/%ld: \n", __FILE__
, __FUNC__
, __LINE__
));
439 if (!InitAboutBitMap(&abi
->abi_Bitmap
,
440 lScrollwidth
, min(ttBox
.Height
, ABOUT_BITMAP_HEIGHT
),
441 abi
->abi_Window
->RPort
->BitMap
))
444 abi
->abi_Initial
= TRUE
;
445 abi
->abi_DoScroll
= TRUE
;
447 /* Set the dimensions of the scroll area in the about info */
448 abi
->abi_lScrollsize
.MinX
= abi
->abi_wInnerleft
+ 7;
449 abi
->abi_lScrollsize
.MinY
= abi
->abi_wInnertop
+ 7;
450 abi
->abi_lScrollsize
.MaxX
= abi
->abi_wInnerleft
+ abi
->abi_wInnerwidth
- 8;
451 abi
->abi_lScrollsize
.MaxY
= abi
->abi_wInnertop
+ abi
->abi_wInnerheight
- (8 + 14) - Scalos_GetFontHeight(abi
->abi_Window
->RPort
);
453 innerWidth
= 1 + abi
->abi_lScrollsize
.MaxX
- abi
->abi_lScrollsize
.MinX
;
455 abi
->abi_XOffset
= (innerWidth
- ttBox
.Width
) / 2;
456 abi
->abi_bmOffset
= 0;
457 abi
->abi_lCurrentline
= INT_MAX
;
459 d1(kprintf("%s/%s/%ld: w=%ld ttBox.Width=%ld abi_XOffset=%ld\n", \
460 __FILE__
, __FUNC__
, __LINE__
, (1 + abi
->abi_lScrollsize
.MaxX
- abi
->abi_lScrollsize
.MinX
),\
461 ttBox
.Width
, abi
->abi_XOffset
));
463 FillBackground(abi
->abi_Window
->RPort
, abi
->abi_Background
,
464 abi
->abi_lScrollsize
.MinX
, abi
->abi_lScrollsize
.MinY
,
465 abi
->abi_lScrollsize
.MaxX
, abi
->abi_lScrollsize
.MaxY
,
468 HelpControl(abi
->abi_Window
, HC_GADGETHELP
); // Turn on gadget help
470 WindowFadeIn(abi
->abi_Window
);
473 LONG ScrollWidth
= ttBox
.Width
;
476 if (ScrollWidth
> innerWidth
)
477 ScrollWidth
= innerWidth
;
479 ScrollXOffset
= abi
->abi_lScrollsize
.MinX
+ (innerWidth
- ScrollWidth
)/2;
484 ULONG lClass
; /* type of intuimessage */
486 APTR pIaddress
; /* a copy of the IntuiMessage.IAddress field */
487 struct IntuiMessage
*im_Msg
; /* Message from window IDCMP port */
489 im_Msg
= ScrollUp(abi
, ttBox
.Height
, ScrollXOffset
, ScrollWidth
, ttBox
.Height
);
494 /* This is an IDCMP message, so we find out the information we want
495 * from it, reply to it and then call a function depending on what
496 * gadget had been pressed.
498 lClass
= im_Msg
->Class
;
499 iCode
= im_Msg
->Code
;
500 pIaddress
= im_Msg
->IAddress
;
501 ReplyMsg(&im_Msg
->ExecMessage
);
505 case IDCMP_MOUSEBUTTONS
:
506 d1(KPrintF("%s/%s/%ld: IDCMP_MOUSEBUTTONS abi=%08lx\n", __FILE__
, __FUNC__
, __LINE__
, abi
));
507 if (SELECTDOWN
== iCode
)
509 abi
->abi_DoScroll
= !abi
->abi_DoScroll
;
511 SetGadgetAttrs(StopGadget
, abi
->abi_Window
, NULL
,
512 GA_Selected
, !abi
->abi_DoScroll
,
515 RefreshGList(StopGadget
, abi
->abi_Window
, NULL
, 1);
519 case IDCMP_INTUITICKS
:
520 d1(KPrintF("%s/%s/%ld: IDCMP_INTUITICKS abi=%08lx\n", __FILE__
, __FUNC__
, __LINE__
, abi
));
521 if (++TickCount
> 10)
523 d1(KPrintF("%s/%s/%ld: \n", __FILE__
, __FUNC__
, __LINE__
));
524 ModifyIDCMP(abi
->abi_Window
, IDCMPFlags
);
526 IconWinShowGadgetToolTip((struct internalScaWindowTask
*) msg
->WindowTask
,
527 lastGadgetID
, &AboutGadgetTextHook
);
531 case IDCMP_GADGETHELP
:
532 d1(KPrintF("%s/%s/%ld: IDCMP_GADGETHELP abi=%08lx\n", __FILE__
, __FUNC__
, __LINE__
, abi
));
535 struct Gadget
*gad
= (struct Gadget
*) pIaddress
;
536 d1(KPrintF("%s/%s/%ld: IDCMP_GADGETHELP GadgetID=%ld\n", __FILE__
, __FUNC__
, __LINE__
, gad
->GadgetID
));
538 if (lastGadgetID
!= gad
->GadgetID
)
540 d1(KPrintF("%s/%s/%ld: \n", __FILE__
, __FUNC__
, __LINE__
));
541 lastGadgetID
= gad
->GadgetID
;
543 ModifyIDCMP(abi
->abi_Window
, IDCMPFlags
| IDCMP_INTUITICKS
);
548 d1(KPrintF("%s/%s/%ld: \n", __FILE__
, __FUNC__
, __LINE__
));
556 struct Gadget
*gad
= (struct Gadget
*) pIaddress
;
558 d1(KPrintF("%s/%s/%ld: IDCMP_GADGETUP GadgetID=%ld\n", __FILE__
, __FUNC__
, __LINE__
, gad
->GadgetID
));
560 switch(gad
->GadgetID
)
562 case ABOUT_GADGETID_OK
: /* OK gadget */
563 iQuit
= 1; /* Simply quit the about window */
566 case ABOUT_GADGETID_STOP
: // Scroll Gadget
567 abi
->abi_DoScroll
= !abi
->abi_DoScroll
;
570 case ABOUT_GADGETID_SYSINFO
: /* System Info gadget */
575 case ABOUT_GADGETID_FLUSH
: /* Flush gadget */
580 case ABOUT_GADGETID_REBOOT
: /* Reboot gadget */
582 ScaReboot(abi
->abi_Window
);
585 default: /* Any other(??!?!?!) gadget */
588 } /* if IDCMP_GADGETUP */
592 d1(KPrintF("%s/%s/%ld: lClass=%08lx\n", __FILE__
, __FUNC__
, __LINE__
, lClass
));
599 Scalos_DoneRastPort(&rp
);
602 ResetToolTips((struct internalScaWindowTask
*) msg
->WindowTask
);
604 d1(KPrintF("%s/%s/%ld: abi=%08lx\n", __FILE__
, __FUNC__
, __LINE__
, abi
));
606 AboutInfoCleanup(abi
);
616 * Description Causes memory to be flushed of all unused items
618 static void ScaFlush(void)
620 APTR pPtr
; /* Pointer to some allocated memory. Don't care, as we free it immediately */
622 if (NULL
!= (pPtr
= AllocVec(0x7FFFFFF0L
, MEMF_PUBLIC
)) )
631 * Parameters Pointer to the window which the requester should use as a parent
633 * Description Asks if the user wants to reboot then reboots if the user selects OK
635 static void ScaReboot(struct Window
*win_Parent
)
637 #if (defined(__MORPHOS__) && defined(ShutdownA)) || defined(__AROS__)
638 #if defined(__MORPHOS__)
639 if (DOSBase
->dl_lib
.lib_Version
>= 51)
640 #elif defined(__AROS__)
644 // On MorphOS 2.x, there is an API to shutdown the machine, so we support both shutdown and reboot
645 switch (UseRequest(win_Parent
, MSGID_ABOUT_SHUTDOWN_REBOOT_CONFIRM
,
646 MSGID_ABOUT_CONFIRM_GADGETS
, NULL
))
659 #endif /* __MORPHOS__ || __AROS__*/
660 if (UseRequest(win_Parent
, MSGID_SUREREBOOTNAME
, MSGID_OKCANCELNAME
, NULL
))
671 * Description Tries to run the systeminfo.module
673 static void SystemInfo(void)
675 struct WBArg wa_Module
; /* A WBArg to run the (systeminfo) module from */
677 if ((BPTR
)NULL
!= (wa_Module
.wa_Lock
= LockScaModsDir()) )
679 wa_Module
.wa_Name
= (STRPTR
) bSysinfomodule
;
681 SCA_WBStartTags(&wa_Module
, 1,
682 SCA_Stacksize
, 16384,
684 /* Should probably check the return code for this and unlock it if the
685 * call fails (depending on whether LockScaModsDir actually keeps the
686 * lock in the first place)
694 * Parameters struct AboutInfo *abi_Scroll - the window to scroll
695 * LONG lLines - number of lines to scroll up
696 * LONG lXoffset - x position offset to be scrolling from
697 * LONG lWidth - width of area to scroll
698 * Returns Pointer to an IntuiMessage if any gadgets pressed
699 * Description Scrolls an area of the window up while blitting new data to the window
701 static struct IntuiMessage
*ScrollUp(struct AboutInfo
*abi
, LONG lLines
, LONG lXoffset
, LONG lWidth
, LONG ttHeight
)
703 struct IntuiMessage
*im_Msg
; /* IntuiMessage we receive when gadgets pressed */
704 LONG bmWidth
= GetBitMapAttr(abi
->abi_Bitmap
.abm_RastPort
.BitMap
, BMA_WIDTH
);
705 LONG bmHeight
= GetBitMapAttr(abi
->abi_Bitmap
.abm_RastPort
.BitMap
, BMA_HEIGHT
);
707 abi
->abi_LineCount
= 0;
709 d1(kprintf("%s/%s/%ld: bmWidth=%ld bmHeight=%ld\n", __FILE__
, __FUNC__
, __LINE__
, bmWidth
, bmHeight
));
711 if (abi
->abi_Initial
)
712 InitialShowAbout(abi
, lXoffset
, lWidth
);
715 im_Msg
= (struct IntuiMessage
*) GetMsg(abi
->abi_Window
->UserPort
);
718 if (abi
->abi_lCurrentline
>= bmHeight
)
720 d1(kprintf("%s/%s/%ld: abi->abi_bmOffset=%ld\n", __FILE__
, __FUNC__
, __LINE__
, abi
->abi_bmOffset
));
722 SetDrMd(&abi
->abi_Bitmap
.abm_RastPort
, JAM1
);
723 FillBackground(&abi
->abi_Bitmap
.abm_RastPort
, abi
->abi_Background
,
725 bmWidth
- 1, bmHeight
- 1,
726 abi
->abi_XOffset
, 1 - abi
->abi_bmOffset
);
727 TTRender(&abi
->abi_Bitmap
.abm_RastPort
, abi
->abi_ttd
, 0, -abi
->abi_bmOffset
);
729 abi
->abi_lCurrentline
= 0;
734 if (abi
->abi_DoScroll
)
736 WaitBOVP(&iInfos
.xii_iinfos
.ii_Screen
->ViewPort
);
737 ScrollRaster(abi
->abi_Window
->RPort
, 0, SCROLLSPEED
,
738 abi
->abi_lScrollsize
.MinX
,
739 abi
->abi_lScrollsize
.MinY
,
740 abi
->abi_lScrollsize
.MaxX
,
741 abi
->abi_lScrollsize
.MaxY
);
743 abi
->abi_LineCount
+= SCROLLSPEED
;
745 FillBackground(abi
->abi_Window
->RPort
, abi
->abi_Background
,
746 abi
->abi_lScrollsize
.MinX
, abi
->abi_lScrollsize
.MaxY
- SCROLLSPEED
+ 1,
747 abi
->abi_lScrollsize
.MaxX
, abi
->abi_lScrollsize
.MaxY
,
748 0, abi
->abi_LineCount
);
750 ClipBlit(&abi
->abi_Bitmap
.abm_RastPort
,
751 0, abi
->abi_lCurrentline
,
752 abi
->abi_Window
->RPort
,
753 lXoffset
, abi
->abi_lScrollsize
.MaxY
- SCROLLSPEED
+ 1,
757 abi
->abi_lCurrentline
+= SCROLLSPEED
;
758 abi
->abi_bmOffset
+= SCROLLSPEED
;
763 /* If the message we receive is the iorequest, we enable gadgets and carry on */
764 switch (im_Msg
->Class
)
767 case IDCMP_MOUSEBUTTONS
:
768 case IDCMP_GADGETHELP
:
769 case IDCMP_INTUITICKS
:
773 ReplyMsg(&im_Msg
->ExecMessage
);
778 // Check if we have reached the bottom of the scrolling contents
779 if (abi
->abi_bmOffset
> ttHeight
)
782 abi
->abi_bmOffset
= 0;
783 abi
->abi_lCurrentline
= INT_MAX
;
785 } while (abi
->abi_LineCount
< lLines
);
790 //----------------------------------------------------------------------------
792 static struct AboutGadgetInfo
*AboutCreateButton(const struct AboutGadgetDef
*agd
, struct Gadget
*PrevGadget
)
795 STRPTR ImageNameSel
= NULL
;
796 STRPTR ImageNameDisabled
= NULL
;
797 struct AboutGadgetInfo
*agi
= NULL
;
798 BOOL Success
= FALSE
;
801 ImageNameNrm
= AllocPathBuffer();
802 if (NULL
== ImageNameNrm
)
805 ImageNameSel
= AllocPathBuffer();
806 if (NULL
== ImageNameSel
)
809 ImageNameDisabled
= AllocPathBuffer();
810 if (NULL
== ImageNameDisabled
)
813 agi
= ScalosAlloc(sizeof(struct AboutGadgetInfo
));
817 d1(KPrintF("%s/%s/%ld: ImageNameNrm=<%s>\n", __FILE__
, __FUNC__
, __LINE__
, ImageNameNrm
));
819 memset(agi
, 0, sizeof(struct AboutGadgetInfo
));
821 stccpy(ImageNameNrm
, ABOUT_GADGET_IMAGE_BASENAME
, Max_PathLen
);
822 AddPart(ImageNameNrm
, agd
->agd_ImageNameNormal
, Max_PathLen
);
824 stccpy(ImageNameSel
, ABOUT_GADGET_IMAGE_BASENAME
, Max_PathLen
);
825 AddPart(ImageNameSel
, agd
->agd_ImageNameSelected
, Max_PathLen
);
827 stccpy(ImageNameDisabled
, ABOUT_GADGET_IMAGE_BASENAME
, Max_PathLen
);
828 AddPart(ImageNameDisabled
, agd
->agd_ImageNameDisabled
, Max_PathLen
);
830 // imgNormal is always required
831 agi
->agi_Image
= NewObject(DtImageClass
, NULL
,
832 DTIMG_ImageName
, (IPTR
) ImageNameNrm
,
833 DTIMG_SelImageName
, (IPTR
) ImageNameSel
,
834 DTIMG_DisabledImageName
, (IPTR
) ImageNameDisabled
,
836 d1(KPrintF("%s/%s/%ld: agi_Image=%08lx\n", __FILE__
, __FUNC__
, __LINE__
, agi
->agi_Image
));
837 if (NULL
== agi
->agi_Image
)
840 struct TextExtent Extent
;
841 struct TextFont
*font
= NULL
;
842 CONST_STRPTR GadgetText
= GetLocString(agd
->agd_GadgetTextID
);
844 memset(&Extent
, 0, sizeof(Extent
));
847 font
= OpenDiskFont(iInfos
.xii_iinfos
.ii_Screen
->Font
);
849 Scalos_SetFont(&rp
, font
, NULL
);
851 Scalos_TextExtent(&rp
, GadgetText
, strlen(GadgetText
), &Extent
);
853 Scalos_CloseFont(&font
, NULL
);
855 d1(KPrintF("%s/%s/%ld: te_Width=%ld te_height=%ld\n", __FILE__
, __FUNC__
, __LINE__
, Extent
.te_Width
, Extent
.te_Height
));
857 agi
->agi_Width
= 10 + Extent
.te_Width
;
858 agi
->agi_Height
= 6 + Extent
.te_Height
;
860 agi
->agi_Themed
= FALSE
;
862 // no Theme image could be found - fall back to sys image
863 agi
->agi_Image
= NewObject(NULL
, FRAMEICLASS
,
864 IA_Width
, agi
->agi_Width
,
865 IA_Height
, agi
->agi_Height
,
866 SYSIA_DrawInfo
, (IPTR
) iInfos
.xii_iinfos
.ii_DrawInfo
,
867 IA_FrameType
, FRAME_BUTTON
,
869 d1(KPrintF("%s/%s/%ld: agi_Image=%08lx\n", __FILE__
, __FUNC__
, __LINE__
, agi
->agi_Image
));
870 if (NULL
== agi
->agi_Image
)
873 agi
->agi_Gadget
= (struct Gadget
*) NewObject(NULL
, FRBUTTONCLASS
,
874 GA_Width
, agi
->agi_Width
,
875 GA_Height
, agi
->agi_Height
,
876 GA_ID
, agd
->agd_GadgetID
,
880 GA_Image
, (IPTR
) agi
->agi_Image
,
881 PrevGadget
? GA_Previous
: TAG_IGNORE
, (IPTR
) PrevGadget
,
882 #if defined(GA_LabelPlace)
883 GA_LabelPlace
, GV_LabelPlace_In
,
884 #endif //defined(GA_LabelPlace)
886 d1(KPrintF("%s/%s/%ld: agi_Gadget=%08lx\n", __FILE__
, __FUNC__
, __LINE__
, agi
->agi_Gadget
));
891 agi
->agi_Themed
= FALSE
;
893 GetAttr(IA_Width
, agi
->agi_Image
, &val
); agi
->agi_Width
= val
;
894 GetAttr(IA_Height
, agi
->agi_Image
, &val
); agi
->agi_Height
= val
;
896 agi
->agi_Gadget
= (struct Gadget
*) SCA_NewScalosObjectTags("ButtonGadget.sca",
897 GA_ID
, agd
->agd_GadgetID
,
900 GA_Image
, (IPTR
) agi
->agi_Image
,
901 PrevGadget
? GA_Previous
: TAG_IGNORE
, (IPTR
) PrevGadget
,
904 d1(KPrintF("%s/%s/%ld: agi_Gadget=%08lx\n", __FILE__
, __FUNC__
, __LINE__
, agi
->agi_Gadget
));
905 if (NULL
== agi
->agi_Gadget
)
912 FreePathBuffer(ImageNameNrm
);
914 FreePathBuffer(ImageNameSel
);
915 if (ImageNameDisabled
)
916 FreePathBuffer(ImageNameDisabled
);
919 AboutFreeButton(agi
);
927 static void AboutFreeButton(struct AboutGadgetInfo
*agi
)
933 DisposeObject(agi
->agi_Image
);
934 agi
->agi_Image
= NULL
;
939 SCA_DisposeScalosObject((Object
*) agi
->agi_Gadget
);
941 DisposeObject((Object
*) agi
->agi_Gadget
);
942 agi
->agi_Gadget
= NULL
;
949 /* Name GenerateLogo()
950 * Parameters struct AboutInfo *abi - pointer to about info structure for this window
951 * Description Generates a properly remapped bitmap with the scalos logo on it
953 static void GenerateLogo(struct AboutInfo
*abi
)
955 ReadScalosLogo(&abi
->abi_Logo
);
960 /* Name FillRegInfo()
961 * Parameters Pointer to area of memory to store the registration string in
962 * maximum length of memory area
964 * Description Extracts the user information from the keyfile and stores it in
965 * the string to be displayed.
967 static void FillRegInfo(STRPTR bRegString
, size_t MaxLen
)
969 strcpy(bRegString
, GetLocString(MSGID_ABOUT_UNREGTEXT
));
970 strcat(bRegString
, "\n");
973 if (pKeyfileaddr
!= NULL
)
976 STRPTR bStartstring
; /* Pointer to the start of the current line */
977 CONST_STRPTR bReguser
; /* Pointer to start of name string for registered user */
978 BYTE bRegchar
; /* Current character from the registered owner name */
980 strcpy(bRegString
, "\n");
981 MaxLen
-= strlen(bRegString
);
982 bRegString
+= strlen(bRegString
);
985 bReguser
= pKeyfileaddr
;
988 bReguser
= GetLocString(MSGID_ABOUT_COMREGINFO
);
991 d1(kprintf("%s/%s/%ld: bRegUser=<%s>\n", __FILE__
, __FUNC__
, __LINE__
, bReguser
));
993 strcpy(bRegString
, GetLocString(MSGID_ABOUT_REGTOTEXT
));
994 strcat(bRegString
, "\n");
995 MaxLen
-= strlen(bRegString
);
996 bRegString
+= strlen(bRegString
);
1000 bStartstring
= bRegString
;
1002 strcpy(bRegString
, "n2c000");
1003 MaxLen
-= strlen(bRegString
);
1004 bRegString
+= strlen(bRegString
);
1008 bRegchar
= *bReguser
++;
1009 if ((UBYTE
)bRegchar
> '\n')
1011 *bRegString
++ = bRegchar
;
1014 else if (bRegchar
== 1)
1016 *bRegString
++ = ' ';
1019 } while (((UBYTE
)bRegchar
> '\n' || bRegchar
== 1) && MaxLen
> 1);
1021 *bRegString
++ = '\n';
1024 d1(kprintf("%s/%s/%ld: bStartstring=<%s>\n", __FILE__
, __FUNC__
, __LINE__
, bStartstring
));
1026 } while (bRegchar
!= '\n' && bRegchar
&& MaxLen
> 1);
1028 strncpy(bStartstring
, "n2c004", 6);
1030 strcpy(bRegString
, GetLocString(MSGID_ABOUT_REGTEXT
));
1032 d1(kprintf("%s/%s/%ld: remaining MaxLen=%ld\n", __FILE__
, __FUNC__
, __LINE__
, MaxLen
));
1037 BOOL
ReadScalosLogo(struct DatatypesImage
**Logo
)
1039 *Logo
= CreateDatatypesImage("THEME:ScalosAboutLogo", 0);
1041 *Logo
= CreateDatatypesImage("THEME:ScalosLogo", 0);
1043 return (BOOL
) (NULL
!= *Logo
);
1048 static BOOL
ReadAboutBackground(struct DatatypesImage
**Logo
)
1050 *Logo
= CreateDatatypesImage("THEME:AboutBackground", 0);
1052 return (BOOL
) (NULL
!= *Logo
);
1056 static STRPTR
ExpandText(CONST_STRPTR Text
)
1058 size_t Length
= strlen(Text
);
1060 STRPTR TextCopy
, dlp
;
1062 for (lp
=Text
; *lp
; )
1070 case 'b': // Build nr
1071 Length
+= strlen(ScalosBuildNr
);
1074 case 'r': // Revision
1075 Length
+= strlen(ScalosRevision
);
1078 case 'v': // Version
1079 Length
+= 8; // room for "999.9999"
1082 case 'c': // COMPILER_STRING
1083 Length
+= strlen(COMPILER_STRING
);
1086 case 'p': // Plugin list
1089 case 'l': // Scalos Logo
1092 case 'R': // Registration info
1096 case 'C': // Copyright +jmc+
1097 Length
+= strlen(bCopyright
);
1108 TextCopy
= ScalosAlloc(Length
);
1109 if (NULL
== TextCopy
)
1112 for (lp
=Text
, dlp
=TextCopy
; *lp
; )
1124 case 'b': // Build Nr.
1125 strcpy(dlp
, ScalosBuildNr
);
1129 case 'r': // Revision
1130 strcpy(dlp
, ScalosBase
->scb_Revision
);
1134 case 'v': // Version
1135 d1(KPrintF("%s/%s/%ld: Version: %ld\n", __FILE__
, __FUNC__
, __LINE__
, ScalosBase
->scb_LibNode
.lib_Version
));
1136 ScaFormatString(dlp
, "%ld.%ld",
1137 (LONG
) ScalosBase
->scb_LibNode
.lib_Version
, (LONG
) ScalosBase
->scb_LibNode
.lib_Revision
);
1141 case 'c': // COMPILER_STRING
1142 strcpy(dlp
, COMPILER_STRING
);
1146 case 'p': // Plugin list
1151 case 'l': // Scalos Logo
1156 case 'R': // Registration info
1160 lpc
= ScalosAlloc(1024);
1163 FillRegInfo(lpc
, 1024);
1171 case 'C': // Copyright +jmc+
1172 strcpy(dlp
, bCopyright
);
1192 static void FreeExpandedText(STRPTR Text
)
1199 static struct ttDef
*CreateDiskPluginList(struct AboutInfo
*abi
)
1201 struct ttDef
*ttd
= NULL
;
1202 struct ttDef
*ttdLeft
= NULL
, *ttdCenter
=NULL
, *ttdRight
= NULL
;
1203 struct ScalosTagList stl
;
1204 struct PluginClass
*plug
;
1206 d1(kprintf("%s/%s/%ld: \n", __FILE__
, __FUNC__
, __LINE__
));
1209 if (RETURN_OK
!= ScalosTagListInit(&stl
))
1212 d1(kprintf("%s/%s/%ld: TagList=%08lx\n", __FILE__
, __FUNC__
, __LINE__
, stl
.stl_TagList
));
1214 ScalosTagListNewEntry(&stl
, TTSpace(2));
1215 for (plug
=ScalosPluginList
; plug
; plug
= (struct PluginClass
*) plug
->plug_Node
.mln_Succ
)
1217 if (plug
->plug_base
&& plug
->plug_filename
)
1219 ScalosTagListNewEntry(&stl
,
1221 (IPTR
) TT_CreateItem(TT_Title
, FilePart(plug
->plug_filename
),
1222 TT_HAlign
, GTJ_LEFT
,
1223 TT_TextPen
, iInfos
.xii_iinfos
.ii_DrawInfo
->dri_Pens
[TEXTPEN
],
1224 TT_Font
, (IPTR
) iInfos
.xii_iinfos
.ii_Screen
->Font
,
1225 TT_TTFont
, abi
->abi_ttDesc
,
1231 ScalosTagListNewEntry(&stl
, TTSpace(2));
1232 ScalosTagListEnd(&stl
);
1234 ttdLeft
= TT_CreateItem(TTVert
,
1235 TT_Members
, TT_CreateItemA(stl
.stl_TagList
),
1239 if (NULL
== ttdLeft
)
1244 ScalosTagListNewEntry(&stl
, TTSpace(2));
1245 for (plug
=ScalosPluginList
; plug
; plug
= (struct PluginClass
*) plug
->plug_Node
.mln_Succ
)
1247 if (plug
->plug_base
)
1249 struct ScaOOPPluginBase
*ScalosPluginBase
;
1251 struct ScalosPluginIFace
*IScalosPlugin
;
1253 const struct ScaClassInfo
*ci
;
1255 ScalosPluginBase
= (struct ScaOOPPluginBase
*) plug
->plug_base
;
1257 IScalosPlugin
= (struct ScalosPluginIFace
*) plug
->plug_iface
;
1259 ci
= SCAGetClassInfo();
1262 ScalosTagListNewEntry(&stl
,
1264 (IPTR
) TT_CreateItem(TT_Title
, ci
->ci_name
,
1265 TT_HAlign
, GTJ_LEFT
,
1266 TT_TextPen
, iInfos
.xii_iinfos
.ii_DrawInfo
->dri_Pens
[TEXTPEN
],
1267 TT_Font
, (IPTR
) iInfos
.xii_iinfos
.ii_Screen
->Font
,
1268 TT_TTFont
, abi
->abi_ttDesc
,
1274 ScalosTagListNewEntry(&stl
, TTSpace(2));
1275 ScalosTagListEnd(&stl
);
1277 ttdCenter
= TT_CreateItem(TTVert
,
1278 TT_Members
, TT_CreateItemA(stl
.stl_TagList
),
1282 if (NULL
== ttdCenter
)
1288 ScalosTagListNewEntry(&stl
, TTSpace(2));
1289 for (plug
=ScalosPluginList
; plug
; plug
= (struct PluginClass
*) plug
->plug_Node
.mln_Succ
)
1291 if (plug
->plug_base
)
1293 struct ScaOOPPluginBase
*ScalosPluginBase
;
1295 struct ScalosPluginIFace
*IScalosPlugin
;
1297 const struct ScaClassInfo
*ci
;
1299 ScalosPluginBase
= (struct ScaOOPPluginBase
*) plug
->plug_base
;
1301 IScalosPlugin
= (struct ScalosPluginIFace
*) plug
->plug_iface
;
1303 ci
= SCAGetClassInfo();
1308 ScaFormatStringMaxLength(text
, sizeof(text
),
1310 (ULONG
) ScalosPluginBase
->soob_Library
.lib_Version
,
1311 (ULONG
) ScalosPluginBase
->soob_Library
.lib_Revision
);
1313 d1(kprintf("%s/%s/%ld: text=<%s> TTDesc=<%s>\n", \
1314 __FILE__
, __FUNC__
, __LINE__
, text
, abi
->abi_ttDesc
));
1316 ScalosTagListNewEntry(&stl
,
1318 (IPTR
) TT_CreateItem(TT_Title
, text
,
1319 TT_HAlign
, GTJ_LEFT
,
1321 TT_Font
, (IPTR
) iInfos
.xii_iinfos
.ii_Screen
->Font
,
1322 TT_TTFont
, abi
->abi_ttDesc
,
1323 TT_TextPen
, iInfos
.xii_iinfos
.ii_DrawInfo
->dri_Pens
[TEXTPEN
],
1329 ScalosTagListNewEntry(&stl
, TTSpace(2));
1330 ScalosTagListEnd(&stl
);
1332 ttdRight
= TT_CreateItem(TTVert
,
1333 TT_Members
, TT_CreateItemA(stl
.stl_TagList
),
1337 if (NULL
== ttdRight
)
1341 d1(kprintf("%s/%s/%ld: TagList=%08lx\n", __FILE__
, __FUNC__
, __LINE__
, stl
.stl_TagList
));
1343 if (stl
.stl_TagList
)
1345 ttd
= TT_CreateItem(TTHoriz
,
1346 TT_Members
, TT_CreateItem(
1351 TT_DrawFrame
, MF_FRAME_XEN
,
1355 d1(kprintf("%s/%s/%ld: ttd=%08lx\n", __FILE__
, __FUNC__
, __LINE__
, ttd
));
1358 ScalosTagListCleanup(&stl
);
1363 TTDisposeItem(ttdLeft
);
1365 TTDisposeItem(ttdCenter
);
1367 TTDisposeItem(ttdRight
);
1370 d1(kprintf("%s/%s/%ld: ttd=%08lx\n", __FILE__
, __FUNC__
, __LINE__
, ttd
));
1376 static struct ttDef
*CreateAboutText(struct AboutInfo
*abi
, ULONG MsgId
)
1378 struct ttDef
*ttd
= NULL
;
1379 struct ScalosTagList stl
;
1380 STRPTR MsgStart
, lp
;
1382 memset(&stl
, 0, sizeof(stl
));
1385 MsgStart
= lp
= ExpandText(GetLocString(MsgId
));
1386 if (NULL
== MsgStart
)
1389 if (RETURN_OK
!= ScalosTagListInit(&stl
))
1397 char cFontstyle
; /* Font style of the text string */
1398 ULONG textStyle
; /* Font style as passed parameter for TT_TextStyle */
1399 ULONG Justification
; // Text justification for TT_HAlign
1400 BYTE bPennum
; /* Pen number to render text in */
1401 char cJustify
; /* Justify location of the string */
1409 textStyle
= FS_NORMAL
;
1413 textStyle
= FSF_BOLD
;
1417 textStyle
= FSF_ITALIC
;
1421 textStyle
= FSF_ITALIC
| FSF_BOLD
;
1425 /* Read pen number from format section (second byte) and set it as the colour to use */
1426 bPennum
= *lp
++ - 48;
1428 /* Read justification and extra lines to skip (3rd and 4th-7th bytes) from the format specifier */
1430 lSkipline
= (lp
[0] - '0') * 100 + (lp
[1] - '0') * 10 + (lp
[2] - '0');
1436 Justification
= GTJ_LEFT
;
1439 Justification
= GTJ_RIGHT
;
1442 Justification
= GTJ_CENTER
;
1446 d1(kprintf("%s/%s/%ld: Pen=%ld Justification=%ld skipLine=%ld\n", \
1447 __FILE__
, __FUNC__
, __LINE__
, bPennum
, Justification
, lSkipline
));
1449 d1(kprintf("%s/%s/%ld: lp=<%s>\n", __FILE__
, __FUNC__
, __LINE__
, lp
));
1453 d1(kprintf("%s/%s/%ld: lp=<%s>\n", __FILE__
, __FUNC__
, __LINE__
, lp
));
1457 case 'p': // Plugin List
1458 ScalosTagListNewEntry(&stl
, TT_Item
, (IPTR
) CreateDiskPluginList(abi
));
1460 case 'l': // Scalos Logo
1461 ScalosTagListNewEntry(&stl
,
1463 (IPTR
) TT_CreateItem(TT_Image
, abi
->abi_Logo
,
1464 TT_HAlign
, Justification
,
1470 while (*lp
&& '\n' != *lp
)
1478 STRPTR lp3Start
, lp3
;
1480 for (lp2
= lp
, Length
= 0; *lp2
&& '\n' != *lp2
; lp2
++, Length
++)
1483 lp3Start
= lp3
= ScalosAlloc(1 + Length
);
1487 while (*lp
&& '\n' != *lp
)
1494 d1(kprintf("%s/%s/%ld: lp=<%s> TTDesc=<%s>\n", __FILE__
, __FUNC__
, __LINE__
, lp3Start
, abi
->abi_ttDesc
));
1496 ScalosTagListNewEntry(&stl
,
1498 (IPTR
) TT_CreateItem(TT_LayoutMode
, TTL_Horizontal
,
1499 TT_Members
, TT_CreateItem(TT_Title
, lp3Start
,
1500 TT_HAlign
, Justification
,
1501 TT_TextStyle
, textStyle
,
1502 TT_Font
, (IPTR
) iInfos
.xii_iinfos
.ii_Screen
->Font
,
1503 TT_TTFont
, abi
->abi_ttDesc
,
1504 TT_TextPen
, (IPTR
) iInfos
.xii_iinfos
.ii_DrawInfo
->dri_Pens
[bPennum
],
1509 ScalosFree(lp3Start
);
1514 d1(kprintf("%s/%s/%ld: Skipline=%lu\n", __FILE__
, __FUNC__
, __LINE__
, lSkipline
));
1516 ScalosTagListNewEntry(&stl
,
1518 (IPTR
) TT_CreateItem(TT_Space
, lSkipline
,
1524 ScalosTagListEnd(&stl
);
1528 FreeExpandedText(MsgStart
);
1530 if (stl
.stl_TagList
)
1532 ttd
= TT_CreateItemA(stl
.stl_TagList
);
1534 ScalosTagListCleanup(&stl
);
1541 static BOOL
InitAboutBitMap(struct AboutBitMap
*abm
, LONG Width
, LONG Height
, struct BitMap
*windowBM
)
1543 d1(kprintf("%s/%s/%ld: About RastPort=%08lx\n", __FILE__
, __FUNC__
, __LINE__
, &abm
->abm_RastPort
));
1545 /* Set up rastport structure in the AboutInfo structure */
1546 Scalos_InitRastPort(&abm
->abm_RastPort
);
1548 /* +dm+ friend bitmap set to NULL */
1549 abm
->abm_BitMap
= abm
->abm_RastPort
.BitMap
= AllocBitMap(Width
, Height
,
1551 BMF_MINPLANES
|BMF_CLEAR
,
1552 (GetBitMapAttr(iInfos
.xii_iinfos
.ii_Screen
->RastPort
.BitMap
, BMA_DEPTH
) <= 8 ? NULL
: windowBM
));
1554 if (NULL
== abm
->abm_BitMap
)
1557 abm
->abm_LayerInfo
= NewLayerInfo();
1558 d1(kprintf("%s/%s/%ld: LayerInfo=%08lx\n", __FILE__
, __FUNC__
, __LINE__
, abm
->abm_LayerInfo
));
1559 if (NULL
== abm
->abm_LayerInfo
)
1562 abm
->abm_Layer
= abm
->abm_RastPort
.Layer
= CreateUpfrontLayer(abm
->abm_LayerInfo
,
1563 abm
->abm_RastPort
.BitMap
,
1564 0, 0, Width
- 1, Height
- 1,
1567 d1(kprintf("%s/%s/%ld: layer=%08lx\n", __FILE__
, __FUNC__
, __LINE__
, abm
->abm_Layer
));
1568 if (NULL
== abm
->abm_Layer
)
1571 d1(kprintf("%s/%s/%ld: Text bitmap bytes per row=%ld\n", __FILE__
, __FUNC__
, __LINE__
, (LONG
)abm
->abm_BitMap
->BytesPerRow
));
1577 static void CleanupAboutBitMap(struct AboutBitMap
*abm
)
1585 DeleteLayer(0, abm
->abm_Layer
);
1586 abm
->abm_Layer
= NULL
;
1588 if (abm
->abm_LayerInfo
)
1590 DisposeLayerInfo(abm
->abm_LayerInfo
);
1591 abm
->abm_LayerInfo
= NULL
;
1593 if (abm
->abm_BitMap
)
1595 FreeBitMap(abm
->abm_BitMap
);
1596 abm
->abm_BitMap
= NULL
;
1599 Scalos_DoneRastPort(&abm
->abm_RastPort
);
1603 //----------------------------------------------------------------------------
1605 static void InitialShowAbout(struct AboutInfo
*abi
, LONG lXoffset
, LONG lWidth
)
1607 LONG bmWidth
= GetBitMapAttr(abi
->abi_Bitmap
.abm_RastPort
.BitMap
, BMA_WIDTH
);
1608 LONG bmHeight
= GetBitMapAttr(abi
->abi_Bitmap
.abm_RastPort
.BitMap
, BMA_HEIGHT
);
1609 LONG Height
= abi
->abi_lScrollsize
.MaxY
- abi
->abi_lScrollsize
.MinY
+ 1;
1610 LONG y
= abi
->abi_lScrollsize
.MinY
;
1612 SetDrMd(&abi
->abi_Bitmap
.abm_RastPort
, JAM1
);
1616 LONG UseHeight
= min(Height
, bmHeight
);
1618 d1(kprintf("%s/%s/%ld: abi->abi_bmOffset=%ld\n", __FILE__
, __FUNC__
, __LINE__
, abi
->abi_bmOffset
));
1620 FillBackground(&abi
->abi_Bitmap
.abm_RastPort
, abi
->abi_Background
,
1622 bmWidth
- 1, bmHeight
- 1,
1623 abi
->abi_XOffset
, 1 - abi
->abi_bmOffset
);
1624 TTRender(&abi
->abi_Bitmap
.abm_RastPort
, abi
->abi_ttd
, 0, -abi
->abi_bmOffset
);
1626 abi
->abi_lCurrentline
= 0;
1628 ClipBlit(&abi
->abi_Bitmap
.abm_RastPort
,
1629 0, abi
->abi_lCurrentline
,
1630 abi
->abi_Window
->RPort
,
1636 abi
->abi_lCurrentline
+= UseHeight
;
1637 abi
->abi_bmOffset
+= UseHeight
;
1640 Height
-= UseHeight
;
1643 abi
->abi_Initial
= FALSE
;
1646 //----------------------------------------------------------------------------
1648 static SAVEDS(CONST_STRPTR
) AboutGadgetTextHookFunc(struct Hook
*hook
, Object
*o
, LONG GadgetID
)
1650 CONST_STRPTR Result
= NULL
;
1652 d1(KPrintF("%s/%s/%ld: hook=%08lx o=%08lx GadgetID=%ld\n", __FILE__
, __FUNC__
, __LINE__
, hook
, o
, GadgetID
));
1656 case ABOUT_GADGETID_OK
:
1657 d1(KPrintF("%s/%s/%ld: ABOUT_GADGETID_OK\n", __FILE__
, __FUNC__
, __LINE__
));
1658 Result
= GetLocString(MSGID_ABOUT_OK_SHORTHELP
);
1660 case ABOUT_GADGETID_STOP
:
1661 d1(KPrintF("%s/%s/%ld: ABOUT_GADGETID_STOP\n", __FILE__
, __FUNC__
, __LINE__
));
1662 Result
= GetLocString(MSGID_ABOUT_STOP_SHORTHELP
);
1664 case ABOUT_GADGETID_SYSINFO
:
1665 d1(KPrintF("%s/%s/%ld: ABOUT_GADGETID_SYSINFO\n", __FILE__
, __FUNC__
, __LINE__
));
1666 Result
= GetLocString(MSGID_ABOUT_SYSINFO_SHORTHELP
);
1668 case ABOUT_GADGETID_FLUSH
:
1669 d1(KPrintF("%s/%s/%ld: ABOUT_GADGETID_FLUSH\n", __FILE__
, __FUNC__
, __LINE__
));
1670 Result
= GetLocString(MSGID_ABOUT_FLUSH_SHORTHELP
);
1672 case ABOUT_GADGETID_REBOOT
:
1673 d1(KPrintF("%s/%s/%ld: ABOUT_GADGETID_REBOOT\n", __FILE__
, __FUNC__
, __LINE__
));
1674 Result
= GetLocString(MSGID_ABOUT_REBOOT_SHORTHELP
);
1683 //----------------------------------------------------------------------------
1685 // Draw something to the window through the clipping mask we created in our region
1686 static void AboutBackfill(struct AboutInfo
*abi
)
1688 abi
->abi_BackfillImage
= CreateDatatypesImage(ABOUT_GADGET_IMAGE_BASENAME
"/" "Backfill", 0);
1690 if (abi
->abi_BackfillImage
)
1692 FillBackground(abi
->abi_Window
->RPort
,
1693 abi
->abi_BackfillImage
,
1694 abi
->abi_wInnerleft
, abi
->abi_wInnertop
,
1695 abi
->abi_wInnerleft
+ abi
->abi_wInnerwidth
- 1,
1696 abi
->abi_wInnertop
+ abi
->abi_wInnerheight
- 1,
1697 abi
->abi_wInnerleft
, abi
->abi_wInnertop
);
1701 static UWORD wAboutpattern
[] = { 0xAAAA, 0x5555 }; /* Pattern to fill the background of the about window */
1703 McpGfxRectFill(abi
->abi_Window
->RPort
,
1704 abi
->abi_wInnerleft
, abi
->abi_wInnertop
,
1705 abi
->abi_wInnerleft
+ abi
->abi_wInnerwidth
- 1,
1706 abi
->abi_wInnertop
+ abi
->abi_wInnerheight
- 1,
1708 IA_APattern
, (IPTR
) wAboutpattern
,
1709 IA_FGPen
, iInfos
.xii_iinfos
.ii_DrawInfo
->dri_Pens
[SHINEPEN
],
1714 //----------------------------------------------------------------------------
1716 static void AboutInfoCleanup(struct AboutInfo
*abi
)
1720 struct AboutGadgetInfo
*agi
;
1722 CleanupAboutBitMap(&abi
->abi_Bitmap
);
1724 if (abi
->abi_Window
)
1726 WindowFadeOut(abi
->abi_Window
);
1727 LockedCloseWindow(abi
->abi_Window
);
1730 while ((agi
= (struct AboutGadgetInfo
*) RemHead(&abi
->abi_GadgetList
)))
1732 AboutFreeButton(agi
);
1735 d1(kprintf("%s/%s/%ld: \n", __FILE__
, __FUNC__
, __LINE__
));
1738 TTDisposeItem(abi
->abi_ttd
);
1740 /* Free logo datatypes object */
1741 DisposeDatatypesImage(&abi
->abi_Logo
);
1743 // free Window backfill
1744 DisposeDatatypesImage(&abi
->abi_BackfillImage
);
1746 // free about scrolling area background
1747 DisposeDatatypesImage(&abi
->abi_Background
);
1750 Scalos_CloseFont(&abi
->abi_Font
, NULL
);
1752 /* Free memory allocated for AboutInfo structure */
1753 ScalosFree((APTR
)abi
);
1757 //----------------------------------------------------------------------------