2 Copyright © 1995-2018, The AROS Development Team. All rights reserved.
6 #include <exec/libraries.h>
7 #include <graphics/gfxbase.h>
8 #include <graphics/modeid.h>
10 #include <proto/exec.h>
11 #include <proto/graphics.h>
12 #include <proto/intuition.h>
14 #include "intuition_intern.h"
15 #include "monitorclass_private.h"
16 #include "shutdown_image.h"
18 static VOID
ShowShutdownScreen();
19 static struct Screen
*OpenFinalScreen(BYTE MinDepth
, BOOL squarePixels
,
20 struct IntuitionBase
*IntuitionBase
);
21 static VOID
ShowPic(struct Screen
*scr
, struct IntuitionBase
*IntuitionBase
);
22 static const UBYTE
*UnpackByterun(const UBYTE
* source
, UBYTE
* dest
,
25 static const UWORD empty_pointer
[1] = { 0 };
27 /* This reset handler is called if software power-off or reboot has not
29 AROS_INTH1(ShutdownScreenHandler
, struct Interrupt
*, handler
)
40 static VOID
ShowShutdownScreen()
42 struct IntuitionBase
*IntuitionBase
=
43 (void *)TaggedOpenLibrary(TAGGEDOPEN_INTUITION
);
45 struct Screen
*scr
= OpenFinalScreen(4, TRUE
, IntuitionBase
);
48 ShowPic(scr
, IntuitionBase
);
53 static struct Screen
*OpenFinalScreen(BYTE MinDepth
, BOOL squarePixels
,
54 struct IntuitionBase
*IntuitionBase
)
56 struct GfxBase
*GfxBase
= GetPrivIBase(IntuitionBase
)->GfxBase
;
59 struct Screen
*scr
= NULL
;
61 struct SharedPointer
*shared_pointer
;
64 mode
= BestModeID(BIDTAG_DesiredWidth
, 640, BIDTAG_DesiredHeight
, height
,
65 BIDTAG_Depth
, MinDepth
, TAG_DONE
);
66 if (mode
== INVALID_ID
)
67 Alert(AN_SysScrnType
);
69 /* Set PAL or NTSC default height if we are running on Amiga(tm) hardware.
70 * We also need to check if this is really PAL or NTSC mode because we
71 * have to use PC 640x480 mode if user has Amiga hardware + RTG board.
72 * Check DisplayFlags first because non-Amiga mode IDs use different format.
74 if (GfxBase
->DisplayFlags
& (NTSC
| PAL
))
76 if ((mode
& MONITOR_ID_MASK
) == NTSC_MONITOR_ID
)
77 height
= squarePixels
? 400 : 200;
78 else if ((mode
& MONITOR_ID_MASK
) == PAL_MONITOR_ID
)
79 height
= squarePixels
? 512 : 256;
82 /* We want the screen to occupy the whole display, so we find the best
83 matching mode ID and then open a screen with that mode */
84 mode
= BestModeID(BIDTAG_DesiredWidth
, 640, BIDTAG_DesiredHeight
, height
,
85 BIDTAG_Depth
, MinDepth
, TAG_DONE
);
87 /* Reset to default decorator. The one installed by C:Decoration may try
88 * to load images from disk while opening the screen, which isn't a good
89 * idea when the system is partly shut down */
90 GetPrivIBase(IntuitionBase
)->Decorator
= NULL
;
91 GetPrivIBase(IntuitionBase
)->ScrDecorClass
= FindClass(SCRDECORCLASS
);
92 GetPrivIBase(IntuitionBase
)->ScrDecorTags
= NULL
;
93 GetPrivIBase(IntuitionBase
)->MenuDecorClass
= FindClass(MENUDECORCLASS
);
94 GetPrivIBase(IntuitionBase
)->MenuDecorTags
= NULL
;
95 GetPrivIBase(IntuitionBase
)->WinDecorClass
= FindClass(WINDECORCLASS
);
96 GetPrivIBase(IntuitionBase
)->WinDecorTags
= NULL
;
98 if (mode
!= INVALID_ID
)
100 scr
= OpenScreenTags(NULL
, SA_DisplayID
, mode
, SA_Draggable
, FALSE
,
101 SA_Quiet
, TRUE
, SA_Depth
, MinDepth
, TAG_DONE
);
103 /* Hide mouse pointer */
106 pointer
= MakePointerFromData(IntuitionBase
, empty_pointer
,
108 GetAttr(POINTERA_SharedPointer
, pointer
,
109 (IPTR
*) & shared_pointer
);
110 DoMethod(GetPrivScreen(scr
)->IMonitorNode
, MM_SetPointerShape
,
118 static VOID
ShowPic(struct Screen
*scr
, struct IntuitionBase
*IntuitionBase
)
120 struct GfxBase
*GfxBase
= GetPrivIBase(IntuitionBase
)->GfxBase
;
124 if ((scr
->Width
>= SHUTDOWN_WIDTH
) && (scr
->Height
>= SHUTDOWN_HEIGHT
)
125 && (scr
->RastPort
.BitMap
->Depth
>= SHUTDOWN_PLANES
))
127 ULONG size
= SHUTDOWN_WIDTH
* SHUTDOWN_HEIGHT
;
129 picture
= AllocVec(size
, MEMF_ANY
);
135 UnpackByterun(shutdown_data
, picture
, size
);
137 for (i
= 0; i
< SHUTDOWN_COLORS
; i
++)
138 SetRGB32(&scr
->ViewPort
, i
,
139 (shutdown_pal
[i
] << 8) & 0xFF000000,
140 (shutdown_pal
[i
] << 16) & 0xFF000000,
141 (shutdown_pal
[i
] << 24) & 0xFF000000);
143 SetAPen(&scr
->RastPort
, 0);
144 RectFill(&scr
->RastPort
, 0, 0, scr
->Width
, scr
->Height
);
146 x
= (scr
->Width
- SHUTDOWN_WIDTH
) >> 1;
147 y
= (scr
->Height
- SHUTDOWN_HEIGHT
) >> 1;
148 WriteChunkyPixels(&scr
->RastPort
, x
, y
,
149 x
+ SHUTDOWN_WIDTH
- 1, y
+ SHUTDOWN_HEIGHT
- 1,
150 picture
, SHUTDOWN_WIDTH
);
158 static const UBYTE
*UnpackByterun(const UBYTE
* source
, UBYTE
* dest
,
166 c
= (BYTE
) (*source
++);
172 if (--unpackedsize
<= 0)
184 if (--unpackedsize
<= 0)