Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openjdk-multiarch-jdk8u
Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/windows/native/sun/awt/splashscreen/splashscreen_sys.c
32288 views
1
/*
2
* Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
3
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
*
5
* This code is free software; you can redistribute it and/or modify it
6
* under the terms of the GNU General Public License version 2 only, as
7
* published by the Free Software Foundation. Oracle designates this
8
* particular file as subject to the "Classpath" exception as provided
9
* by Oracle in the LICENSE file that accompanied this code.
10
*
11
* This code is distributed in the hope that it will be useful, but WITHOUT
12
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14
* version 2 for more details (a copy is included in the LICENSE file that
15
* accompanied this code).
16
*
17
* You should have received a copy of the GNU General Public License version
18
* 2 along with this work; if not, write to the Free Software Foundation,
19
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20
*
21
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22
* or visit www.oracle.com if you need additional information or have any
23
* questions.
24
*/
25
26
// copy from awt.h
27
#ifndef _WIN32_WINNT
28
#define _WIN32_WINNT 0x0600
29
#endif
30
31
// copy from awt.h
32
#ifndef _WIN32_IE
33
#define _WIN32_IE 0x0600
34
#endif
35
36
#include "splashscreen_impl.h"
37
#include <windowsx.h>
38
#include <windows.h>
39
#include <winuser.h>
40
#include "sizecalc.h"
41
42
#ifndef WS_EX_LAYERED
43
#define WS_EX_LAYERED 0x80000
44
#endif
45
46
#ifndef ULW_ALPHA
47
#define ULW_ALPHA 0x00000002
48
#endif
49
50
#ifndef AC_SRC_OVER
51
#define AC_SRC_OVER 0x00
52
#endif
53
54
#ifndef AC_SRC_ALPHA
55
#define AC_SRC_ALPHA 0x01
56
#endif
57
58
#define WM_SPLASHUPDATE WM_USER+1
59
#define WM_SPLASHRECONFIGURE WM_USER+2
60
61
/* Could use npt but decided to cut down on linked code size */
62
char* SplashConvertStringAlloc(const char* in, int *size) {
63
int len, outChars, rc;
64
WCHAR* buf;
65
if (!in) {
66
return NULL;
67
}
68
len = strlen(in);
69
outChars = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, in, len,
70
NULL, 0);
71
buf = (WCHAR*) SAFE_SIZE_ARRAY_ALLOC(malloc, outChars, sizeof(WCHAR));
72
if (!buf) {
73
return NULL;
74
}
75
rc = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, in, len,
76
buf, outChars);
77
if (rc==0) {
78
free(buf);
79
return NULL;
80
} else {
81
if (size) {
82
*size = rc;
83
}
84
return (char*)buf;
85
}
86
}
87
88
unsigned
89
SplashTime(void)
90
{
91
return GetTickCount();
92
}
93
94
void
95
SplashInitFrameShape(Splash * splash, int imageIndex)
96
{
97
RGNDATA *pRgnData;
98
RGNDATAHEADER *pRgnHdr;
99
ImageRect maskRect;
100
101
if (!splash->maskRequired)
102
return;
103
104
/* reserving memory for the worst case */
105
if (!IS_SAFE_SIZE_MUL(splash->width / 2 + 1, splash->height)) {
106
return;
107
}
108
pRgnData = (RGNDATA *) SAFE_SIZE_STRUCT_ALLOC(malloc, sizeof(RGNDATAHEADER),
109
sizeof(RECT), (splash->width / 2 + 1) * splash->height);
110
if (!pRgnData) {
111
return;
112
}
113
pRgnHdr = (RGNDATAHEADER *) pRgnData;
114
initRect(&maskRect, 0, 0, splash->width, splash->height, 1,
115
splash->width * splash->imageFormat.depthBytes,
116
splash->frames[imageIndex].bitmapBits, &splash->imageFormat);
117
118
pRgnHdr->dwSize = sizeof(RGNDATAHEADER);
119
pRgnHdr->iType = RDH_RECTANGLES;
120
pRgnHdr->nRgnSize = 0;
121
pRgnHdr->rcBound.top = 0;
122
pRgnHdr->rcBound.left = 0;
123
pRgnHdr->rcBound.bottom = splash->height;
124
pRgnHdr->rcBound.right = splash->width;
125
126
pRgnHdr->nCount = BitmapToYXBandedRectangles(&maskRect,
127
(RECT *) (((BYTE *) pRgnData) + sizeof(RGNDATAHEADER)));
128
129
splash->frames[imageIndex].hRgn = ExtCreateRegion(NULL,
130
sizeof(RGNDATAHEADER) + sizeof(RECT) * pRgnHdr->nCount, pRgnData);
131
132
free(pRgnData);
133
}
134
135
/* paint current splash screen frame to hdc
136
this function is unused in layered window mode */
137
138
void
139
SplashPaint(Splash * splash, HDC hdc)
140
{
141
unsigned numColors = splash->screenFormat.colorMap ?
142
splash->screenFormat.numColors : 0;
143
BITMAPV4HEADER *pBmi;
144
HPALETTE hOldPal = NULL;
145
146
if (!splash->frames)
147
return;
148
if (splash->currentFrame < 0 || splash->currentFrame >= splash->frameCount)
149
return;
150
pBmi = (BITMAPV4HEADER *) SAFE_SIZE_STRUCT_ALLOC(alloca, sizeof(BITMAPV4HEADER),
151
sizeof(RGBQUAD), numColors);
152
if (!pBmi) {
153
return;
154
}
155
memset(pBmi, 0, sizeof(BITMAPV4HEADER));
156
if (splash->screenFormat.colorMap)
157
memcpy(((BYTE *) pBmi) + sizeof(BITMAPV4HEADER),
158
splash->screenFormat.colorMap, sizeof(RGBQUAD) * numColors);
159
160
pBmi->bV4Size = sizeof(BITMAPV4HEADER);
161
pBmi->bV4Width = splash->width;
162
pBmi->bV4Height = -splash->height;
163
pBmi->bV4Planes = 1;
164
pBmi->bV4BitCount = (WORD) (splash->screenFormat.depthBytes * 8);
165
/* we're ALWAYS using BGRA in screenFormat */
166
pBmi->bV4V4Compression = BI_RGB;
167
pBmi->bV4ClrUsed = numColors;
168
pBmi->bV4ClrImportant = numColors;
169
pBmi->bV4AlphaMask = splash->screenFormat.mask[3];
170
pBmi->bV4RedMask = splash->screenFormat.mask[2];
171
pBmi->bV4GreenMask = splash->screenFormat.mask[1];
172
pBmi->bV4BlueMask = splash->screenFormat.mask[0];
173
174
/* creating the palette in SplashInitPlatform does not work, so I'm creating it
175
here on demand */
176
if (!splash->hPalette) {
177
unsigned i;
178
LOGPALETTE *pLogPal = (LOGPALETTE *) SAFE_SIZE_STRUCT_ALLOC(malloc,
179
sizeof(LOGPALETTE), sizeof(PALETTEENTRY), numColors);
180
if (!pLogPal) {
181
return;
182
}
183
184
pLogPal->palVersion = 0x300;
185
pLogPal->palNumEntries = (WORD) numColors;
186
for (i = 0; i < numColors; i++) {
187
pLogPal->palPalEntry[i].peRed = (BYTE)
188
QUAD_RED(splash->colorMap[i]);
189
pLogPal->palPalEntry[i].peGreen = (BYTE)
190
QUAD_GREEN(splash->colorMap[i]);
191
pLogPal->palPalEntry[i].peBlue = (BYTE)
192
QUAD_BLUE(splash->colorMap[i]);
193
pLogPal->palPalEntry[i].peFlags = PC_NOCOLLAPSE;
194
}
195
splash->hPalette = CreatePalette(pLogPal);
196
free(pLogPal);
197
}
198
if (splash->hPalette) {
199
hOldPal = SelectPalette(hdc, splash->hPalette, FALSE);
200
RealizePalette(hdc);
201
}
202
203
StretchDIBits(hdc, 0, 0, splash->width, splash->height, 0, 0,
204
splash->width, splash->height, splash->screenData,
205
(BITMAPINFO *) pBmi, DIB_RGB_COLORS, SRCCOPY);
206
if (hOldPal)
207
SelectPalette(hdc, hOldPal, FALSE);
208
}
209
210
211
/* The function makes the window visible if it is hidden
212
or is not yet shown. */
213
void
214
SplashRedrawWindow(Splash * splash)
215
{
216
if (!SplashIsStillLooping(splash)) {
217
KillTimer(splash->hWnd, 0);
218
}
219
220
if (splash->currentFrame < 0) {
221
return;
222
}
223
224
SplashUpdateScreenData(splash);
225
if (splash->isLayered) {
226
BLENDFUNCTION bf;
227
POINT ptSrc;
228
HDC hdcSrc = CreateCompatibleDC(NULL), hdcDst;
229
BITMAPINFOHEADER bmi;
230
void *bitmapBits;
231
HBITMAP hBitmap, hOldBitmap;
232
RECT rect;
233
POINT ptDst;
234
SIZE size;
235
236
bf.BlendOp = AC_SRC_OVER;
237
bf.BlendFlags = 0;
238
bf.AlphaFormat = AC_SRC_ALPHA;
239
bf.SourceConstantAlpha = 0xFF;
240
ptSrc.x = ptSrc.y = 0;
241
242
memset(&bmi, 0, sizeof(bmi));
243
bmi.biSize = sizeof(BITMAPINFOHEADER);
244
bmi.biWidth = splash->width;
245
bmi.biHeight = -splash->height;
246
bmi.biPlanes = 1;
247
bmi.biBitCount = 32;
248
bmi.biCompression = BI_RGB;
249
250
// FIXME: this is somewhat ineffective
251
// maybe if we allocate memory for all frames as DIBSections,
252
// then we could select the frames into the DC directly
253
254
hBitmap = CreateDIBSection(NULL, (BITMAPINFO *) & bmi, DIB_RGB_COLORS,
255
&bitmapBits, NULL, 0);
256
memcpy(bitmapBits, splash->screenData,
257
splash->screenStride * splash->height);
258
hOldBitmap = (HBITMAP) SelectObject(hdcSrc, hBitmap);
259
hdcDst = GetDC(splash->hWnd);
260
261
GetWindowRect(splash->hWnd, &rect);
262
263
ptDst.x = rect.left;
264
ptDst.y = rect.top;
265
266
size.cx = splash->width;
267
size.cy = splash->height;
268
269
UpdateLayeredWindow(splash->hWnd, hdcDst, &ptDst, &size,
270
hdcSrc, &ptSrc, 0, &bf, ULW_ALPHA);
271
272
ReleaseDC(splash->hWnd, hdcDst);
273
SelectObject(hdcSrc, hOldBitmap);
274
DeleteObject(hBitmap);
275
DeleteDC(hdcSrc);
276
}
277
else {
278
InvalidateRect(splash->hWnd, NULL, FALSE);
279
if (splash->maskRequired) {
280
HRGN hRgn = CreateRectRgn(0, 0, 0, 0);
281
282
CombineRgn(hRgn, splash->frames[splash->currentFrame].hRgn,
283
splash->frames[splash->currentFrame].hRgn, RGN_COPY);
284
SetWindowRgn(splash->hWnd, hRgn, TRUE);
285
} else {
286
SetWindowRgn(splash->hWnd, NULL, TRUE);
287
}
288
UpdateWindow(splash->hWnd);
289
}
290
if (!IsWindowVisible(splash->hWnd)) {
291
POINT cursorPos;
292
ShowWindow(splash->hWnd, SW_SHOW);
293
// Windows won't update the cursor after the window is shown,
294
// if the cursor is already above the window. need to do this manually.
295
GetCursorPos(&cursorPos);
296
if (WindowFromPoint(cursorPos) == splash->hWnd) {
297
// unfortunately Windows fail to understand that the window
298
// thread should own the cursor, even though the mouse pointer
299
// is over the window, until the mouse has been moved.
300
// we're using SetCursorPos here to fake the mouse movement
301
// and enable proper update of the cursor.
302
SetCursorPos(cursorPos.x, cursorPos.y);
303
SetCursor(LoadCursor(NULL, IDC_WAIT));
304
}
305
}
306
if (SplashIsStillLooping(splash)) {
307
int time = splash->time +
308
splash->frames[splash->currentFrame].delay - SplashTime();
309
310
if (time < 0)
311
time = 0;
312
SetTimer(splash->hWnd, 0, time, NULL);
313
}
314
}
315
316
void SplashReconfigureNow(Splash * splash) {
317
splash->x = (GetSystemMetrics(SM_CXSCREEN) - splash->width) / 2;
318
splash->y = (GetSystemMetrics(SM_CYSCREEN) - splash->height) / 2;
319
if (splash->hWnd) {
320
//Fixed 6474657: splash screen image jumps towards left while
321
// setting the new image using setImageURL()
322
// We may safely hide the splash window because SplashRedrawWindow()
323
// will show the window again.
324
ShowWindow(splash->hWnd, SW_HIDE);
325
MoveWindow(splash->hWnd, splash->x, splash->y, splash->width, splash->height, FALSE);
326
}
327
SplashRedrawWindow(splash);
328
}
329
330
static LRESULT CALLBACK
331
SplashWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
332
{
333
PAINTSTRUCT ps;
334
HDC hdc;
335
336
337
switch (message) {
338
339
case WM_ERASEBKGND:
340
return TRUE; // to avoid flicker
341
342
case WM_SYSCOMMAND:
343
if (wParam==SC_CLOSE||wParam==SC_DEFAULT||wParam==SC_HOTKEY||
344
wParam==SC_KEYMENU||wParam==SC_MAXIMIZE||
345
wParam==SC_MINIMIZE||wParam==SC_MOUSEMENU||wParam==SC_MOVE||
346
wParam==SC_RESTORE||wParam==SC_SIZE)
347
{
348
return 0;
349
}
350
351
/* double switch to avoid prologue/epilogue duplication */
352
case WM_TIMER:
353
case WM_SPLASHUPDATE:
354
case WM_PAINT:
355
case WM_SPLASHRECONFIGURE:
356
{
357
Splash *splash = (Splash *) GetWindowLongPtr(hWnd, GWLP_USERDATA);
358
359
SplashLock(splash);
360
if (splash->isVisible>0) {
361
switch(message) {
362
case WM_TIMER:
363
SplashNextFrame(splash);
364
SplashRedrawWindow(splash);
365
break;
366
case WM_SPLASHUPDATE:
367
SplashRedrawWindow(splash);
368
break;
369
case WM_PAINT:
370
hdc = BeginPaint(hWnd, &ps);
371
SplashPaint(splash, hdc);
372
EndPaint(hWnd, &ps);
373
break;
374
case WM_SPLASHRECONFIGURE:
375
SplashReconfigureNow(splash);
376
break;
377
}
378
}
379
SplashUnlock(splash);
380
break;
381
}
382
case WM_DESTROY:
383
PostQuitMessage(0);
384
break;
385
default:
386
return DefWindowProc(hWnd, message, wParam, lParam);
387
388
}
389
return 0;
390
}
391
392
HWND
393
SplashCreateWindow(Splash * splash)
394
{
395
WNDCLASSEX wcex;
396
ATOM wndClass;
397
DWORD style, exStyle;
398
HWND hWnd;
399
400
ZeroMemory(&wcex, sizeof(WNDCLASSEX));
401
402
wcex.cbSize = sizeof(WNDCLASSEX);
403
wcex.style = CS_HREDRAW | CS_VREDRAW;
404
wcex.lpfnWndProc = (WNDPROC) SplashWndProc;
405
wcex.hInstance = GetModuleHandle(NULL);
406
wcex.lpszClassName = "JavaSplash";
407
wcex.hCursor = LoadCursor(NULL, IDC_WAIT);
408
409
wndClass = RegisterClassEx(&wcex);
410
if (!wndClass) {
411
return 0;
412
}
413
414
splash->x = (GetSystemMetrics(SM_CXSCREEN) - splash->width) / 2;
415
splash->y = (GetSystemMetrics(SM_CYSCREEN) - splash->height) / 2;
416
exStyle = splash->isLayered ? WS_EX_LAYERED : 0;
417
exStyle |= WS_EX_TOOLWINDOW; /* don't show the window on taskbar */
418
style = WS_POPUP;
419
hWnd = CreateWindowEx(exStyle, (LPCSTR) wndClass, "", style,
420
splash->x, splash->y, splash->width, splash->height, NULL, NULL,
421
wcex.hInstance, NULL);
422
SetWindowLongPtr(hWnd, GWLP_USERDATA, (LONG_PTR) splash);
423
return hWnd;
424
}
425
426
void
427
SplashLock(Splash * splash)
428
{
429
EnterCriticalSection(&splash->lock);
430
}
431
432
void
433
SplashUnlock(Splash * splash)
434
{
435
LeaveCriticalSection(&splash->lock);
436
}
437
438
void
439
SplashInitPlatform(Splash * splash)
440
{
441
HDC hdc;
442
int paletteMode;
443
444
InitializeCriticalSection(&splash->lock);
445
splash->isLayered = FALSE;
446
hdc = GetDC(NULL);
447
paletteMode = (GetDeviceCaps(hdc, RASTERCAPS) & RC_PALETTE) != 0;
448
if (UpdateLayeredWindow && !paletteMode) {
449
splash->isLayered = TRUE;
450
}
451
splash->byteAlignment = 4;
452
if (splash->isLayered) {
453
initFormat(&splash->screenFormat,
454
0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000);
455
splash->screenFormat.premultiplied = 1;
456
splash->maskRequired = 0;
457
}
458
else {
459
splash->maskRequired = 1;
460
if (paletteMode) {
461
int numColors = GetDeviceCaps(hdc, SIZEPALETTE) -
462
GetDeviceCaps(hdc, NUMRESERVED);
463
int i;
464
int numComponents[3];
465
466
initFormat(&splash->screenFormat, 0, 0, 0, 0);
467
/* FIXME: maybe remapping to non-reserved colors would improve performance */
468
for (i = 0; i < numColors; i++) {
469
splash->colorIndex[i] = i;
470
}
471
numColors = quantizeColors(numColors, numComponents);
472
initColorCube(numComponents, splash->colorMap, splash->dithers,
473
splash->colorIndex);
474
splash->screenFormat.colorIndex = splash->colorIndex;
475
splash->screenFormat.depthBytes = 1;
476
splash->screenFormat.colorMap = splash->colorMap;
477
splash->screenFormat.dithers = splash->dithers;
478
splash->screenFormat.numColors = numColors;
479
splash->hPalette = NULL;
480
}
481
else {
482
initFormat(&splash->screenFormat,
483
0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000);
484
}
485
}
486
ReleaseDC(NULL, hdc);
487
}
488
489
void
490
SplashCleanupPlatform(Splash * splash)
491
{
492
int i;
493
494
if (splash->frames) {
495
for (i = 0; i < splash->frameCount; i++) {
496
if (splash->frames[i].hRgn) {
497
DeleteObject(splash->frames[i].hRgn);
498
splash->frames[i].hRgn = NULL;
499
}
500
}
501
}
502
if (splash->hPalette)
503
DeleteObject(splash->hPalette);
504
splash->maskRequired = !splash->isLayered;
505
}
506
507
void
508
SplashDonePlatform(Splash * splash)
509
{
510
if (splash->hWnd)
511
DestroyWindow(splash->hWnd);
512
}
513
514
void
515
SplashMessagePump()
516
{
517
MSG msg;
518
519
while (GetMessage(&msg, NULL, 0, 0)) {
520
TranslateMessage(&msg);
521
DispatchMessage(&msg);
522
}
523
}
524
525
DWORD WINAPI
526
SplashScreenThread(LPVOID param)
527
{
528
Splash *splash = (Splash *) param;
529
530
splash->currentFrame = 0;
531
SplashLock(splash);
532
splash->time = SplashTime();
533
splash->hWnd = SplashCreateWindow(splash);
534
if (splash->hWnd) {
535
SplashRedrawWindow(splash);
536
SplashUnlock(splash);
537
SplashMessagePump();
538
SplashLock(splash);
539
}
540
SplashDone(splash);
541
splash->isVisible = -1;
542
SplashUnlock(splash);
543
return 0;
544
}
545
546
void
547
SplashCreateThread(Splash * splash)
548
{
549
DWORD threadId;
550
551
CreateThread(NULL, 0, SplashScreenThread, (LPVOID) splash, 0, &threadId);
552
}
553
554
void
555
SplashClosePlatform(Splash * splash)
556
{
557
PostMessage(splash->hWnd, WM_QUIT, 0, 0);
558
}
559
560
void
561
SplashUpdate(Splash * splash)
562
{
563
PostMessage(splash->hWnd, WM_SPLASHUPDATE, 0, 0);
564
}
565
566
void
567
SplashReconfigure(Splash * splash)
568
{
569
PostMessage(splash->hWnd, WM_SPLASHRECONFIGURE, 0, 0);
570
}
571
572
SPLASHEXPORT char*
573
SplashGetScaledImageName(const char* jarName, const char* fileName,
574
float *scaleFactor)
575
{
576
*scaleFactor = 1;
577
return NULL;
578
}
579
580