/* * Class: java_awt_SplashScreen * Method: _update * Signature: (J[IIIIII)V */ JNIEXPORT void JNICALL Java_java_awt_SplashScreen__1update(JNIEnv * env, jclass thisClass, jlong jsplash, jintArray data, jint x, jint y, jint width, jint height, jint stride) { Splash *splash = (Splash *) jlong_to_ptr(jsplash); int dataSize; if (!splash) { return; } SplashLock(splash); dataSize = (*env)->GetArrayLength(env, data); if (splash->overlayData) { free(splash->overlayData); } splash->overlayData = malloc(dataSize * sizeof(rgbquad_t)); if (splash->overlayData) { /* we need a copy anyway, so we'll be using GetIntArrayRegion */ (*env)->GetIntArrayRegion(env, data, 0, dataSize, (jint *) splash->overlayData); initFormat(&splash->overlayFormat, 0xFF0000, 0xFF00, 0xFF, 0xFF000000); initRect(&splash->overlayRect, x, y, width, height, 1, stride * sizeof(rgbquad_t), splash->overlayData, &splash->overlayFormat); SplashUpdate(splash); } SplashUnlock(splash); }
/* * Class: java_awt_SplashScreen * Method: _getBounds * Signature: (J)Ljava/awt/Rectangle; */ JNIEXPORT jobject JNICALL Java_java_awt_SplashScreen__1getBounds(JNIEnv * env, jclass thisClass, jlong jsplash) { Splash *splash = (Splash *) jlong_to_ptr(jsplash); static jclass clazz = NULL; static jmethodID mid = NULL; jobject bounds = NULL; if (!splash) { return NULL; } SplashLock(splash); if (!clazz) { clazz = (*env)->FindClass(env, "java/awt/Rectangle"); if (clazz) { clazz = (*env)->NewGlobalRef(env, clazz); } } if (clazz && !mid) { mid = (*env)->GetMethodID(env, clazz, "<init>", "(IIII)V"); } if (clazz && mid) { bounds = (*env)->NewObject(env, clazz, mid, splash->x, splash->y, splash->width, splash->height); if ((*env)->ExceptionOccurred(env)) { bounds = NULL; (*env)->ExceptionDescribe(env); (*env)->ExceptionClear(env); } } SplashUnlock(splash); return bounds; }
void * SplashScreenThread(void *param) { Splash *splash = (Splash *) param; // pthread_key_t key; // pthread_key_create(&key, SplashPThreadDestructor); // pthread_setspecific(key, splash); SplashLock(splash); pipe(splash->controlpipe); fcntl(splash->controlpipe[0], F_SETFL, fcntl(splash->controlpipe[0], F_GETFL, 0) | O_NONBLOCK); splash->time = SplashTime(); SplashCreateWindow(splash); fflush(stdout); if (splash->window) { SplashRemoveDecoration(splash); XStoreName(splash->display, splash->window, "Java"); XMapRaised(splash->display, splash->window); SplashUpdateShape(splash); SplashRedrawWindow(splash); SplashEventLoop(splash); } SplashUnlock(splash); SplashDone(splash); splash->isVisible=-1; return 0; }
static int SplashLoadStream(SplashStream * stream) { int success = 0; int c; size_t i; Splash *splash = SplashGetInstance(); if (splash->isVisible < 0) { return 0; } SplashLock(splash); /* the formats we support can be easily distinguished by the first byte */ c = stream->peek(stream); if (c != -1) { for (i = 0; i < sizeof(formats) / sizeof(FILEFORMAT); i++) { if (c == formats[i].sign) { success = formats[i].decodeStream(splash, stream); break; } } } stream->close(stream); if (!success) { // failed to decode if (splash->isVisible == 0) { SplashCleanup(splash); } SplashUnlock(splash); // SplashClose locks if (splash->isVisible == 0) { SplashClose(); } } else { splash->currentFrame = 0; if (splash->isVisible == 0) { SplashStart(splash); } else { SplashReconfigure(splash); splash->time = SplashTime(); } SplashUnlock(splash); } return success; }
DWORD WINAPI SplashScreenThread(LPVOID param) { Splash *splash = (Splash *) param; splash->currentFrame = 0; SplashLock(splash); splash->time = SplashTime(); splash->hWnd = SplashCreateWindow(splash); if (splash->hWnd) { SplashRedrawWindow(splash); SplashUnlock(splash); SplashMessagePump(); SplashLock(splash); } SplashDone(splash); splash->isVisible = -1; SplashUnlock(splash); return 0; }
SPLASHEXPORT void SplashClose() { Splash *splash = SplashGetInstance(); if (splash->isVisible > 0) { SplashLock(splash); splash->isVisible = -1; SplashClosePlatform(splash); SplashUnlock(splash); } }
/* * Class: java_awt_SplashScreen * Method: _close * Signature: (J)V */ JNIEXPORT void JNICALL Java_java_awt_SplashScreen__1close(JNIEnv * env, jclass thisClass, jlong jsplash) { Splash *splash = (Splash *) jlong_to_ptr(jsplash); if (!splash) { return; } SplashLock(splash); SplashClosePlatform(splash); SplashUnlock(splash); }
static LRESULT CALLBACK SplashWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { PAINTSTRUCT ps; HDC hdc; switch (message) { case WM_ERASEBKGND: return TRUE; // to avoid flicker case WM_SYSCOMMAND: if (wParam==SC_CLOSE||wParam==SC_DEFAULT||wParam==SC_HOTKEY|| wParam==SC_KEYMENU||wParam==SC_MAXIMIZE|| wParam==SC_MINIMIZE||wParam==SC_MOUSEMENU||wParam==SC_MOVE|| wParam==SC_RESTORE||wParam==SC_SIZE) { return 0; } /* double switch to avoid prologue/epilogue duplication */ case WM_TIMER: case WM_SPLASHUPDATE: case WM_PAINT: case WM_SPLASHRECONFIGURE: { Splash *splash = (Splash *) GetWindowLongPtr(hWnd, GWLP_USERDATA); SplashLock(splash); if (splash->isVisible>0) { switch(message) { case WM_TIMER: SplashNextFrame(splash); SplashRedrawWindow(splash); break; case WM_SPLASHUPDATE: SplashRedrawWindow(splash); break; case WM_PAINT: hdc = BeginPaint(hWnd, &ps); SplashPaint(splash, hdc); EndPaint(hWnd, &ps); break; case WM_SPLASHRECONFIGURE: SplashReconfigureNow(splash); break; } } SplashUnlock(splash); break; } case WM_DESTROY: PostQuitMessage(0); break; default: return DefWindowProc(hWnd, message, wParam, lParam); } return 0; }
void SplashEventLoop(Splash * splash) { /* Different from win32 implementation - this loop uses poll timeouts instead of a timer */ /* we should have splash _locked_ on entry!!! */ int xconn = XConnectionNumber(splash->display); while (1) { struct pollfd pfd[2]; int timeout = -1; int ctl = splash->controlpipe[0]; int rc; int pipes_empty; pfd[0].fd = xconn; pfd[0].events = POLLIN | POLLPRI; pfd[1].fd = ctl; pfd[1].events = POLLIN | POLLPRI; errno = 0; if (splash->isVisible>0 && SplashIsStillLooping(splash)) { timeout = splash->time + splash->frames[splash->currentFrame].delay - SplashTime(); if (timeout < 0) { timeout = 0; } } SplashUnlock(splash); rc = poll(pfd, 2, timeout); SplashLock(splash); if (splash->isVisible>0 && SplashTime() >= splash->time + splash->frames[splash->currentFrame].delay) { SplashNextFrame(splash); SplashUpdateShape(splash); SplashRedrawWindow(splash); } if (rc <= 0) { errno = 0; continue; } pipes_empty = 0; while(!pipes_empty) { char buf; pipes_empty = 1; if (read(ctl, &buf, sizeof(buf)) > 0) { pipes_empty = 0; switch (buf) { case SPLASHCTL_UPDATE: if (splash->isVisible>0) { SplashRedrawWindow(splash); } break; case SPLASHCTL_RECONFIGURE: if (splash->isVisible>0) { SplashReconfigureNow(splash); } break; case SPLASHCTL_QUIT: return; } } // we're not using "while(XPending)", processing one event // at a time to avoid control pipe starvation if (XPending(splash->display)) { XEvent evt; pipes_empty = 0; XNextEvent(splash->display, &evt); switch (evt.type) { case Expose: if (splash->isVisible>0) { // we're doing full redraw so we just // skip the remaining painting events in the queue while(XCheckTypedEvent(splash->display, Expose, &evt)); SplashRedrawWindow(splash); } break; /* ... */ } } } } }