using kprintf to output debug, which may be redirected to serial, is not a good idea...
[AROS-Contrib.git] / scalos / main / about.c
blob72e9732d7a89aa20a5abc77532b93271f305d24f
1 // about.c
2 // $Date$
3 // $Revision$
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>
18 #include <string.h>
19 #include <stdio.h>
20 #include <limits.h>
22 #define __USE_SYSBASE
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>
32 #include "debug.h"
33 #include <proto/scalos.h>
34 #include <proto/scalosplugin.h>
36 #include <clib/alib_protos.h>
38 #include <defs.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"
47 #include "locale.h"
48 #include "about.h"
49 #include "TTLayout.h"
50 #include "DtImageClass.h"
52 //----------------------------------------------------------------------------
54 #define ABOUT_BITMAP_HEIGHT 150
56 /* text: first bytes:
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";
80 enum AboutGadgetID
82 ABOUT_GADGETID_OK = 100,
83 ABOUT_GADGETID_STOP,
84 ABOUT_GADGETID_SYSINFO,
85 ABOUT_GADGETID_FLUSH,
86 ABOUT_GADGETID_REBOOT
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 =
117 { NULL, NULL },
118 HOOKFUNC_DEF(AboutGadgetTextHookFunc), // h_Entry + h_SubEntry
119 NULL, // h_Data
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
126 * reply port
128 void AboutProg(struct internalScaWindowTask *iwt, const struct MenuCmdArg *mcArg)
130 RunAbout(iwt, 0, NULL);
135 /* Name runabout()
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__));
155 ChildProcessRun(iwt,
156 &smrp_Message->ScalosMessage,
157 NP_Priority, -5,
158 NP_CommandName, (IPTR) bAboutname,
159 NP_Name, (IPTR) bAboutname,
160 TAG_DONE);
162 d1(kprintf("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__));
164 return(0);
169 /* Name NewAbout()
170 * Parameters None
171 * Returns always 0
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;
182 ULONG TickCount = 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;
191 do {
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 */
201 struct RastPort rp;
202 struct IBox ttBox;
203 ULONG n;
204 LONG innerWidth;
205 struct Gadget *PrevGadget = NULL;
206 LONG MaxButtonWidth;
207 LONG MaxButtonHeight;
208 LONG GadgetLeft, GadgetTop;
209 LONG WindowHeight;
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));
219 if (NULL == abi)
220 break;
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;
232 else
233 abi->abi_ttDesc = NULL;
235 /* Create a BitMap to hold the Scalos logo. Decode logo from executable
236 * into this bitmap.
238 GenerateLogo(abi);
240 ReadAboutBackground(&abi->abi_Background);
242 abi->abi_ttd = CreateAboutText(abi, MSGID_ABOUT_TESTTEXT);
243 if (NULL == abi->abi_ttd)
244 break;
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);
251 if (agi)
253 AddTail(&abi->abi_GadgetList, &agi->agi_Node);
254 PrevGadget = agi->agi_Gadget;
256 else
257 break;
260 /* Collect width of the generated gadgets */
261 lWidest = 0;
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);
274 SetDrMd(&rp, JAM1);
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,
296 WA_Activate, TRUE,
297 WA_RMBTrap, TRUE,
298 WA_DepthGadget, TRUE,
299 WA_DragBar, TRUE,
300 WA_HelpGroup, HelpGroupID,
301 WA_Height, WindowHeight,
302 WA_Width, lWidest,
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),
306 TAG_DONE);
308 if (NULL == abi->abi_Window)
309 break;
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
324 if (ModsDirLock)
326 BPTR siLock;
327 BPTR oldDir = CurrentDir(ModsDirLock);
329 siLock = Lock((STRPTR) bSysinfomodule, ACCESS_READ);
330 if (siLock)
332 DisableSysInfo = FALSE;
333 UnLock(siLock);
336 CurrentDir(oldDir);
337 UnLock(ModsDirLock);
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),
349 GA_Top, GadgetTop,
350 TAG_END);
352 if (ABOUT_GADGETID_STOP == agi->agi_Gadget->GadgetID)
354 StopGadget = agi->agi_Gadget;
355 SetAttrs(agi->agi_Gadget,
356 GA_ToggleSelect, TRUE,
357 GA_Selected, FALSE,
358 TAG_END);
360 else if (ABOUT_GADGETID_SYSINFO == agi->agi_Gadget->GadgetID)
362 SetAttrs(agi->agi_Gadget,
363 GA_Disabled, DisableSysInfo,
364 TAG_END);
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)
378 break;
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))
387 break;
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))
397 break;
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);
402 AboutBackfill(abi);
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],
419 IA_Recessed, 1,
420 IA_FrameType, MF_FRAME_BUTTON,
421 TAG_END);
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,
430 NULL);
431 RefreshGList(((struct AboutGadgetInfo *) abi->abi_GadgetList.lh_Head)->agi_Gadget,
432 abi->abi_Window,
433 NULL,
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))
442 break;
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,
466 0, 0);
468 HelpControl(abi->abi_Window, HC_GADGETHELP); // Turn on gadget help
470 WindowFadeIn(abi->abi_Window);
472 do {
473 LONG ScrollWidth = ttBox.Width;
474 LONG ScrollXOffset;
476 if (ScrollWidth > innerWidth)
477 ScrollWidth = innerWidth;
479 ScrollXOffset = abi->abi_lScrollsize.MinX + (innerWidth - ScrollWidth)/2;
481 iQuit = 0;
483 do {
484 ULONG lClass; /* type of intuimessage */
485 UWORD iCode;
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);
491 if (! im_Msg)
492 continue;
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);
503 switch (lClass)
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,
513 TAG_END);
515 RefreshGList(StopGadget, abi->abi_Window, NULL, 1);
517 break;
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);
525 TickCount = 0;
526 IconWinShowGadgetToolTip((struct internalScaWindowTask *) msg->WindowTask,
527 lastGadgetID, &AboutGadgetTextHook);
529 break;
531 case IDCMP_GADGETHELP:
532 d1(KPrintF("%s/%s/%ld: IDCMP_GADGETHELP abi=%08lx\n", __FILE__, __FUNC__, __LINE__, abi));
533 if (pIaddress)
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;
542 TickCount = 0;
543 ModifyIDCMP(abi->abi_Window, IDCMPFlags | IDCMP_INTUITICKS);
546 else
548 d1(KPrintF("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__));
549 lastGadgetID = 0;
550 TickCount = 0;
552 break;
554 case IDCMP_GADGETUP:
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 */
564 break;
566 case ABOUT_GADGETID_STOP: // Scroll Gadget
567 abi->abi_DoScroll = !abi->abi_DoScroll;
568 break;
570 case ABOUT_GADGETID_SYSINFO: /* System Info gadget */
571 iQuit = 1;
572 SystemInfo();
573 break;
575 case ABOUT_GADGETID_FLUSH: /* Flush gadget */
576 iQuit = 1;
577 ScaFlush();
578 break;
580 case ABOUT_GADGETID_REBOOT: /* Reboot gadget */
581 iQuit = 1;
582 ScaReboot(abi->abi_Window);
583 break;
585 default: /* Any other(??!?!?!) gadget */
586 break;
588 } /* if IDCMP_GADGETUP */
589 break;
591 default:
592 d1(KPrintF("%s/%s/%ld: lClass=%08lx\n", __FILE__, __FUNC__, __LINE__, lClass));
593 break;
596 } while (!iQuit);
597 } while (!iQuit);
599 Scalos_DoneRastPort(&rp);
600 } while (0);
602 ResetToolTips((struct internalScaWindowTask *) msg->WindowTask);
604 d1(KPrintF("%s/%s/%ld: abi=%08lx\n", __FILE__, __FUNC__, __LINE__, abi));
606 AboutInfoCleanup(abi);
608 return 0;
613 /* Name ScaFlush()
614 * Parameters None
615 * Returns Nothing
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)) )
624 FreeVec(pPtr);
630 /* Name ScaReboot()
631 * Parameters Pointer to the window which the requester should use as a parent
632 * Returns Nothing
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__)
641 if (1)
642 #endif
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))
648 case 1: // Reboot
649 ColdReboot();
650 break;
651 case 2: // Shutdown
652 ShutdownA(0);
653 break;
654 default: // Cancel
655 return;
656 break;
659 #endif /* __MORPHOS__ || __AROS__*/
660 if (UseRequest(win_Parent, MSGID_SUREREBOOTNAME, MSGID_OKCANCELNAME, NULL))
662 ColdReboot();
668 /* Name SystemInfo()
669 * Parameters None
670 * Returns Nothing
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,
683 TAG_END);
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)
693 /* Name ScrollUp
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);
714 do {
715 im_Msg = (struct IntuiMessage *) GetMsg(abi->abi_Window->UserPort);
716 if (NULL == im_Msg)
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,
724 0, 0,
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;
732 Delay(1);
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,
754 lWidth, SCROLLSPEED,
755 ABC | ABNC);
757 abi->abi_lCurrentline += SCROLLSPEED;
758 abi->abi_bmOffset += SCROLLSPEED;
761 else
763 /* If the message we receive is the iorequest, we enable gadgets and carry on */
764 switch (im_Msg->Class)
766 case IDCMP_GADGETUP:
767 case IDCMP_MOUSEBUTTONS:
768 case IDCMP_GADGETHELP:
769 case IDCMP_INTUITICKS:
770 return(im_Msg);
771 break;
772 default:
773 ReplyMsg(&im_Msg->ExecMessage);
774 break;
778 // Check if we have reached the bottom of the scrolling contents
779 if (abi->abi_bmOffset > ttHeight)
781 // Restart from top
782 abi->abi_bmOffset = 0;
783 abi->abi_lCurrentline = INT_MAX;
785 } while (abi->abi_LineCount < lLines);
787 return im_Msg;
790 //----------------------------------------------------------------------------
792 static struct AboutGadgetInfo *AboutCreateButton(const struct AboutGadgetDef *agd, struct Gadget *PrevGadget)
794 STRPTR ImageNameNrm;
795 STRPTR ImageNameSel = NULL;
796 STRPTR ImageNameDisabled = NULL;
797 struct AboutGadgetInfo *agi = NULL;
798 BOOL Success = FALSE;
800 do {
801 ImageNameNrm = AllocPathBuffer();
802 if (NULL == ImageNameNrm)
803 break;
805 ImageNameSel= AllocPathBuffer();
806 if (NULL == ImageNameSel)
807 break;
809 ImageNameDisabled = AllocPathBuffer();
810 if (NULL == ImageNameDisabled)
811 break;
813 agi = ScalosAlloc(sizeof(struct AboutGadgetInfo));
814 if (NULL == agi)
815 break;
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,
835 TAG_END);
836 d1(KPrintF("%s/%s/%ld: agi_Image=%08lx\n", __FILE__, __FUNC__, __LINE__, agi->agi_Image));
837 if (NULL == agi->agi_Image)
839 struct RastPort rp;
840 struct TextExtent Extent;
841 struct TextFont *font = NULL;
842 CONST_STRPTR GadgetText = GetLocString(agd->agd_GadgetTextID);
844 memset(&Extent, 0, sizeof(Extent));
846 InitRastPort(&rp);
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,
868 TAG_END);
869 d1(KPrintF("%s/%s/%ld: agi_Image=%08lx\n", __FILE__, __FUNC__, __LINE__, agi->agi_Image));
870 if (NULL == agi->agi_Image)
871 break;
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,
877 GA_Text, GadgetText,
878 GA_RelVerify, TRUE,
879 GA_GadgetHelp, TRUE,
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)
885 TAG_END);
886 d1(KPrintF("%s/%s/%ld: agi_Gadget=%08lx\n", __FILE__, __FUNC__, __LINE__, agi->agi_Gadget));
888 else
890 IPTR val;
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,
898 GA_RelVerify, TRUE,
899 GA_GadgetHelp, TRUE,
900 GA_Image, (IPTR) agi->agi_Image,
901 PrevGadget ? GA_Previous : TAG_IGNORE, (IPTR) PrevGadget,
902 TAG_END);
904 d1(KPrintF("%s/%s/%ld: agi_Gadget=%08lx\n", __FILE__, __FUNC__, __LINE__, agi->agi_Gadget));
905 if (NULL == agi->agi_Gadget)
906 break;
908 Success = TRUE;
909 } while (0);
911 if (ImageNameNrm)
912 FreePathBuffer(ImageNameNrm);
913 if (ImageNameSel)
914 FreePathBuffer(ImageNameSel);
915 if (ImageNameDisabled)
916 FreePathBuffer(ImageNameDisabled);
917 if (!Success)
919 AboutFreeButton(agi);
920 agi = NULL;
923 return agi;
927 static void AboutFreeButton(struct AboutGadgetInfo *agi)
929 if (agi)
931 if (agi->agi_Image)
933 DisposeObject(agi->agi_Image);
934 agi->agi_Image = NULL;
936 if (agi->agi_Gadget)
938 if (agi->agi_Themed)
939 SCA_DisposeScalosObject((Object *) agi->agi_Gadget);
940 else
941 DisposeObject((Object *) agi->agi_Gadget);
942 agi->agi_Gadget = NULL;
944 ScalosFree(agi);
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
963 * Returns Nothing
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");
972 #ifdef COMMERCIAL
973 if (pKeyfileaddr != NULL)
974 #endif
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);
984 #ifdef COMMERCIAL
985 bReguser = pKeyfileaddr;
986 bReguser += 28;
987 #else
988 bReguser = GetLocString(MSGID_ABOUT_COMREGINFO);
989 #endif
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;
1012 MaxLen--;
1014 else if (bRegchar == 1)
1016 *bRegString++ = ' ';
1017 MaxLen--;
1019 } while (((UBYTE)bRegchar > '\n' || bRegchar == 1) && MaxLen > 1);
1021 *bRegString++ = '\n';
1022 MaxLen--;
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);
1040 if (NULL == *Logo)
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);
1059 CONST_STRPTR lp;
1060 STRPTR TextCopy, dlp;
1062 for (lp=Text; *lp; )
1064 if ('%' == *lp)
1066 lp++;
1068 switch (*lp)
1070 case 'b': // Build nr
1071 Length += strlen(ScalosBuildNr);
1072 lp++;
1073 break;
1074 case 'r': // Revision
1075 Length += strlen(ScalosRevision);
1076 lp++;
1077 break;
1078 case 'v': // Version
1079 Length += 8; // room for "999.9999"
1080 lp++;
1081 break;
1082 case 'c': // COMPILER_STRING
1083 Length += strlen(COMPILER_STRING);
1084 lp++;
1085 break;
1086 case 'p': // Plugin list
1087 lp++;
1088 break;
1089 case 'l': // Scalos Logo
1090 lp++;
1091 break;
1092 case 'R': // Registration info
1093 Length += 1024;
1094 lp++;
1095 break;
1096 case 'C': // Copyright +jmc+
1097 Length += strlen(bCopyright);
1098 lp++;
1099 break;
1100 default:
1101 break;
1104 else
1105 lp++;
1108 TextCopy = ScalosAlloc(Length);
1109 if (NULL == TextCopy)
1110 return NULL;
1112 for (lp=Text, dlp=TextCopy; *lp; )
1114 if ('%' == *lp)
1116 lp++;
1118 switch (*lp)
1120 case '%':
1121 *dlp++ = '%';
1122 lp++;
1123 break;
1124 case 'b': // Build Nr.
1125 strcpy(dlp, ScalosBuildNr);
1126 dlp += strlen(dlp);
1127 lp++;
1128 break;
1129 case 'r': // Revision
1130 strcpy(dlp, ScalosBase->scb_Revision);
1131 dlp += strlen(dlp);
1132 lp++;
1133 break;
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);
1138 dlp += strlen(dlp);
1139 lp++;
1140 break;
1141 case 'c': // COMPILER_STRING
1142 strcpy(dlp, COMPILER_STRING);
1143 dlp += strlen(dlp);
1144 lp++;
1145 break;
1146 case 'p': // Plugin list
1147 *dlp++ = '%';
1148 *dlp++ = 'p';
1149 lp++;
1150 break;
1151 case 'l': // Scalos Logo
1152 *dlp++ = '%';
1153 *dlp++ = 'l';
1154 lp++;
1155 break;
1156 case 'R': // Registration info
1158 STRPTR lpc;
1160 lpc = ScalosAlloc(1024);
1161 if (lpc)
1163 FillRegInfo(lpc, 1024);
1164 strcpy(dlp, lpc);
1165 dlp += strlen(dlp);
1166 ScalosFree(lpc);
1168 lp++;
1170 break;
1171 case 'C': // Copyright +jmc+
1172 strcpy(dlp, bCopyright);
1173 dlp += strlen(dlp);
1174 lp++;
1175 break;
1176 case '\0':
1177 break;
1178 default:
1179 *dlp++ = *lp++;
1180 break;
1183 else
1184 *dlp++ = *lp++;
1186 *dlp = '\0';
1188 return TextCopy;
1192 static void FreeExpandedText(STRPTR Text)
1194 if (Text)
1195 ScalosFree(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__));
1208 do {
1209 if (RETURN_OK != ScalosTagListInit(&stl))
1210 break;
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,
1220 TT_Item,
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,
1226 TT_SpaceLeft, 5,
1231 ScalosTagListNewEntry(&stl, TTSpace(2));
1232 ScalosTagListEnd(&stl);
1234 ttdLeft = TT_CreateItem(TTVert,
1235 TT_Members, TT_CreateItemA(stl.stl_TagList),
1236 End,
1237 End;
1239 if (NULL == ttdLeft)
1240 break;
1243 stl.stl_Index = 0;
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;
1250 #ifdef __amigaos4__
1251 struct ScalosPluginIFace *IScalosPlugin;
1252 #endif
1253 const struct ScaClassInfo *ci;
1255 ScalosPluginBase = (struct ScaOOPPluginBase *) plug->plug_base;
1256 #ifdef __amigaos4__
1257 IScalosPlugin = (struct ScalosPluginIFace *) plug->plug_iface;
1258 #endif
1259 ci = SCAGetClassInfo();
1260 if (ci)
1262 ScalosTagListNewEntry(&stl,
1263 TT_Item,
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),
1279 End,
1280 End;
1282 if (NULL == ttdCenter)
1283 break;
1287 stl.stl_Index = 0;
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;
1294 #ifdef __amigaos4__
1295 struct ScalosPluginIFace *IScalosPlugin;
1296 #endif
1297 const struct ScaClassInfo *ci;
1299 ScalosPluginBase = (struct ScaOOPPluginBase *) plug->plug_base;
1300 #ifdef __amigaos4__
1301 IScalosPlugin = (struct ScalosPluginIFace *) plug->plug_iface;
1302 #endif
1303 ci = SCAGetClassInfo();
1304 if (ci)
1306 char text[20];
1308 ScaFormatStringMaxLength(text, sizeof(text),
1309 "%3lu.%-3lu",
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,
1317 TT_Item,
1318 (IPTR) TT_CreateItem(TT_Title, text,
1319 TT_HAlign, GTJ_LEFT,
1320 TT_SpaceRight, 5,
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),
1334 End,
1335 End;
1337 if (NULL == ttdRight)
1338 break;
1339 } while (0);
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(
1347 TT_Item, ttdLeft,
1348 TT_Item, ttdCenter,
1349 TT_Item, ttdRight,
1350 End,
1351 TT_DrawFrame, MF_FRAME_XEN,
1352 End,
1353 End;
1355 d1(kprintf("%s/%s/%ld: ttd=%08lx\n", __FILE__, __FUNC__, __LINE__, ttd));
1358 ScalosTagListCleanup(&stl);
1360 if (NULL == ttd)
1362 if (ttdLeft)
1363 TTDisposeItem(ttdLeft);
1364 if (ttdCenter)
1365 TTDisposeItem(ttdCenter);
1366 if (ttdRight)
1367 TTDisposeItem(ttdRight);
1370 d1(kprintf("%s/%s/%ld: ttd=%08lx\n", __FILE__, __FUNC__, __LINE__, ttd));
1372 return 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));
1384 do {
1385 MsgStart = lp = ExpandText(GetLocString(MsgId));
1386 if (NULL == MsgStart)
1387 break;
1389 if (RETURN_OK != ScalosTagListInit(&stl))
1390 break;
1392 lp = MsgStart;
1393 while (*lp)
1395 CONST_STRPTR lp2;
1396 size_t Length;
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 */
1402 LONG lSkipline;
1404 cFontstyle = *lp++;
1406 switch (cFontstyle)
1408 case 'n':
1409 textStyle = FS_NORMAL;
1410 break;
1412 case 'b':
1413 textStyle = FSF_BOLD;
1414 break;
1416 case 'i':
1417 textStyle = FSF_ITALIC;
1418 break;
1420 default:
1421 textStyle = FSF_ITALIC | FSF_BOLD;
1422 break;
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 */
1429 cJustify = *lp++;
1430 lSkipline = (lp[0] - '0') * 100 + (lp[1] - '0') * 10 + (lp[2] - '0');
1431 lp += 3;
1433 switch (cJustify)
1435 case 'l':
1436 Justification = GTJ_LEFT;
1437 break;
1438 case 'r':
1439 Justification = GTJ_RIGHT;
1440 break;
1441 default:
1442 Justification = GTJ_CENTER;
1443 break;
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));
1451 if ('%' == *lp)
1453 d1(kprintf("%s/%s/%ld: lp=<%s>\n", __FILE__, __FUNC__, __LINE__, lp));
1455 switch (lp[1])
1457 case 'p': // Plugin List
1458 ScalosTagListNewEntry(&stl, TT_Item, (IPTR) CreateDiskPluginList(abi));
1459 break;
1460 case 'l': // Scalos Logo
1461 ScalosTagListNewEntry(&stl,
1462 TT_Item,
1463 (IPTR) TT_CreateItem(TT_Image, abi->abi_Logo,
1464 TT_HAlign, Justification,
1465 TAG_END)
1467 break;
1470 while (*lp && '\n' != *lp)
1471 lp++;
1473 if ('\n' == *lp)
1474 lp++;
1476 else
1478 STRPTR lp3Start, lp3;
1480 for (lp2 = lp, Length = 0; *lp2 && '\n' != *lp2; lp2++, Length++)
1483 lp3Start = lp3 = ScalosAlloc(1 + Length);
1484 if (NULL == lp3)
1485 break;
1487 while (*lp && '\n' != *lp)
1488 *lp3++ = *lp++;
1489 *lp3 = '\0';
1491 if ('\n' == *lp)
1492 lp++;
1494 d1(kprintf("%s/%s/%ld: lp=<%s> TTDesc=<%s>\n", __FILE__, __FUNC__, __LINE__, lp3Start, abi->abi_ttDesc));
1496 ScalosTagListNewEntry(&stl,
1497 TT_Item,
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],
1505 TAG_END),
1506 TAG_END)
1509 ScalosFree(lp3Start);
1512 if (lSkipline)
1514 d1(kprintf("%s/%s/%ld: Skipline=%lu\n", __FILE__, __FUNC__, __LINE__, lSkipline));
1516 ScalosTagListNewEntry(&stl,
1517 TT_Item,
1518 (IPTR) TT_CreateItem(TT_Space, lSkipline,
1519 TAG_END)
1524 ScalosTagListEnd(&stl);
1525 } while (0);
1527 if (MsgStart)
1528 FreeExpandedText(MsgStart);
1530 if (stl.stl_TagList)
1532 ttd = TT_CreateItemA(stl.stl_TagList);
1534 ScalosTagListCleanup(&stl);
1537 return ttd;
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,
1550 windowBM->Depth,
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)
1555 return FALSE;
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)
1560 return FALSE;
1562 abm->abm_Layer = abm->abm_RastPort.Layer = CreateUpfrontLayer(abm->abm_LayerInfo,
1563 abm->abm_RastPort.BitMap,
1564 0, 0, Width - 1, Height - 1,
1565 LAYERSIMPLE,
1566 NULL);
1567 d1(kprintf("%s/%s/%ld: layer=%08lx\n", __FILE__, __FUNC__, __LINE__, abm->abm_Layer));
1568 if (NULL == abm->abm_Layer)
1569 return FALSE;
1571 d1(kprintf("%s/%s/%ld: Text bitmap bytes per row=%ld\n", __FILE__, __FUNC__, __LINE__, (LONG)abm->abm_BitMap->BytesPerRow));
1573 return TRUE;
1577 static void CleanupAboutBitMap(struct AboutBitMap *abm)
1579 if (abm)
1581 WaitBlit();
1583 if (abm->abm_Layer)
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);
1614 while (Height)
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,
1621 0, 0,
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,
1631 lXoffset, y,
1632 lWidth,
1633 UseHeight,
1634 ABC | ABNC);
1636 abi->abi_lCurrentline += UseHeight;
1637 abi->abi_bmOffset += UseHeight;
1638 y += 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));
1654 switch (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);
1659 break;
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);
1663 break;
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);
1667 break;
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);
1671 break;
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);
1675 break;
1676 default:
1677 break;
1680 return Result;
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);
1699 else
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,
1707 IA_APatSize, 1,
1708 IA_APattern, (IPTR) wAboutpattern,
1709 IA_FGPen, iInfos.xii_iinfos.ii_DrawInfo->dri_Pens[SHINEPEN],
1710 TAG_END);
1714 //----------------------------------------------------------------------------
1716 static void AboutInfoCleanup(struct AboutInfo *abi)
1718 if (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__));
1737 if (abi->abi_ttd)
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);
1749 if (abi->abi_Font)
1750 Scalos_CloseFont(&abi->abi_Font, NULL);
1752 /* Free memory allocated for AboutInfo structure */
1753 ScalosFree((APTR)abi);
1757 //----------------------------------------------------------------------------