/* * Class: sage_FreetypeFont * Method: loadFontFace0 * Signature: (JLjava/lang/String;I)J */ JNIEXPORT jlong JNICALL Java_sage_FreetypeFont_loadFontFace0 (JNIEnv *env, jobject jo, jlong ftLibPtr, jstring jstr, jint ptSize, jint style) { FT_Face face; FT_Library library = (FT_Library)(intptr_t) ftLibPtr; const char* cstr = (*env)->GetStringUTFChars(env, jstr, NULL); int error = FT_New_Face(library, cstr, 0, &face); (*env)->ReleaseStringUTFChars(env, jstr, cstr); if (error) { sysOutPrint(env, "Error loading freetype font of %d\r\n", error); return 0; } int scrnDPI = 72;//96; error = FT_Set_Char_Size( face, /* handle to face object */ 0, /* char_width in 1/64th of points */ (int)(ptSize*64 + 0.5f), /* char_height in 1/64th of points */ scrnDPI, /* horizontal device resolution */ scrnDPI ); /* vertical device resolution */ if (error) { sysOutPrint(env, "Error setting freetype char size of %d\r\n", error); return 0; } FTDataStruct* rv = (FTDataStruct*)malloc(sizeof(FTDataStruct)); rv->sizePtr = face->size; rv->facePtr = face; rv->style = 0; // Remove styles already applied to the TTF itself if ((style & sage_FreetypeFont_BOLD) != 0) { if ((face->style_flags & FT_STYLE_FLAG_BOLD) == 0) { rv->style = rv->style | FT_STYLE_FLAG_BOLD; } } if ((style & sage_FreetypeFont_ITALIC) != 0) { if ((face->style_flags & FT_STYLE_FLAG_ITALIC) == 0) { rv->style = rv->style | FT_STYLE_FLAG_ITALIC; } } return (jlong)(intptr_t) rv; }
jdouble CallDoubleMethod(JNIEnv *env, jobject obj, char *name, char *sig, ...) { jclass cls = env->GetObjectClass(obj); jmethodID mid; va_list args; jdouble result = 0; mid = env->GetMethodID(cls, name, sig); env->DeleteLocalRef(cls); if (mid == 0) { sysOutPrint(env, "CallDoubleMethod() failed: %s, %s\r\n", name, sig); return 0; } va_start(args, sig); result = env->CallDoubleMethodV(obj, mid, args); va_end(args); if(env->ExceptionOccurred()) { env->ExceptionDescribe(); env->ExceptionClear(); } return result; }
/* * Class: sage_FreetypeFont * Method: deriveFontFace0 * Signature: (JI)J */ JNIEXPORT jlong JNICALL Java_sage_FreetypeFont_deriveFontFace0 (JNIEnv *env, jobject jo, jlong fontPtr, jint ptSize, jint style) { FTDataStruct* fontData = (FTDataStruct*)(intptr_t) fontPtr; FT_Size newSize; int error = FT_New_Size(fontData->facePtr, &newSize); if (error) { sysOutPrint(env, "Error deriving freetype font of %d\r\n", error); return 0; } FT_Activate_Size(newSize); int scrnDPI = 72;//96; error = FT_Set_Char_Size( fontData->facePtr, /* handle to face object */ 0, /* char_width in 1/64th of points */ (int)(ptSize*64 + 0.5f), /* char_height in 1/64th of points */ scrnDPI, /* horizontal device resolution */ scrnDPI ); /* vertical device resolution */ if (error) { sysOutPrint(env, "Error setting freetype char size of %d\r\n", error); return 0; } FTDataStruct* rv = (FTDataStruct*)malloc(sizeof(FTDataStruct)); rv->sizePtr = newSize; rv->facePtr = fontData->facePtr; rv->style = 0; // Remove styles already applied to the TTF itself if ((style & sage_FreetypeFont_BOLD) != 0) { if ((fontData->facePtr->style_flags & FT_STYLE_FLAG_BOLD) == 0) { rv->style = rv->style | FT_STYLE_FLAG_BOLD; } } if ((style & sage_FreetypeFont_ITALIC) != 0) { if ((fontData->facePtr->style_flags & FT_STYLE_FLAG_ITALIC) == 0) { rv->style = rv->style | FT_STYLE_FLAG_ITALIC; } } return (jlong)(intptr_t) rv; }
jint GetStaticIntField(JNIEnv *env, jclass cls, char *field) { jfieldID fid = env->GetStaticFieldID(cls, field, "I"); if (fid == NULL) { sysOutPrint(env, "GetStatocIntField() failed: %s\r\n", field); return -1; } return env->GetStaticIntField(cls, fid); }
jboolean IsInstanceOf(JNIEnv *env, jobject obj, char *type) { jclass cls = env->FindClass(type); if (cls == NULL) { sysOutPrint(env, "IsInstanceOf() failed: no such class: %s\r\n", type); return 0; } return env->IsInstanceOf(obj, cls); }
void SetCharField(JNIEnv *env, jobject obj, char *field, jchar val) { jclass cls = env->GetObjectClass(obj); jfieldID fid = env->GetFieldID(cls, field, "C"); env->DeleteLocalRef(cls); if (fid == NULL) { sysOutPrint(env, "SetCharField() failed: %s\r\n", field); return; } env->SetCharField(obj, fid, val); }
jmethodID GetMethodID(JNIEnv *env, jobject obj, char *name, char *sig) { jclass cls = env->GetObjectClass(obj); jmethodID mid = env->GetMethodID(cls, name, sig); env->DeleteLocalRef(cls); if (mid == NULL) { sysOutPrint(env, "GetMethodID() failed: %s, %s\r\n", name, sig); return 0; } return mid; }
jint GetIntField(JNIEnv *env, jobject obj, char *field) { jclass cls = env->GetObjectClass(obj); jfieldID fid = env->GetFieldID(cls, field, "I"); env->DeleteLocalRef(cls); if (fid == NULL) { sysOutPrint(env, "GetIntField() failed: %s\r\n", field); return -1; } return env->GetIntField(obj, fid); }
/* * Class: sage_FreetypeFont * Method: loadFreetypeLib0 * Signature: ()J */ JNIEXPORT jlong JNICALL Java_sage_FreetypeFont_loadFreetypeLib0 (JNIEnv *env, jclass jc) { FT_Library library; int error = FT_Init_FreeType(&library); if (error) { sysOutPrint(env, "Error loading FreeType of %d\n", error); return 0; } return (jlong)(intptr_t) library; }
jobject GetObjectFieldX(JNIEnv *env, jobject obj, char *field, char *type) { if (!obj) return NULL; jclass cls = env->GetObjectClass(obj); jfieldID fid = env->GetFieldID(cls, field, type); env->DeleteLocalRef(cls); if (fid == NULL) { sysOutPrint(env, "GetObjectFieldX() failed: %s, %s\r\n", field, type); return 0; } return env->GetObjectField(obj, fid); }
jobject CallObjectMethod(JNIEnv *env, jobject obj, char *name, char *sig, ...) { jclass cls = env->GetObjectClass(obj); jmethodID mid; va_list args; jobject result = 0; mid = env->GetMethodID(cls, name, sig); env->DeleteLocalRef(cls); if (mid == 0) { sysOutPrint(env, "CallObjectMethod() failed: %s, %s\r\n", name, sig); return 0; } va_start(args, sig); result = env->CallObjectMethodV(obj, mid, args); va_end(args); return result; }
void CallStaticVoidMethod(JNIEnv *env, jclass cls, char *name, char *sig, ...) { jmethodID mid; va_list args; jint result = 0; mid = env->GetStaticMethodID(cls, name, sig); if (mid == 0) { sysOutPrint(env, "CallStaticVoidMethod() failed: %s, %s\r\n", name, sig); return; } va_start(args, sig); env->CallStaticVoidMethodV(cls, mid, args); va_end(args); if(env->ExceptionOccurred()) { env->ExceptionDescribe(); env->ExceptionClear(); } }
/* * Class: sage_FreetypeFont * Method: renderGlyphRaw0 * Signature: (JLsage/media/image/RawImage;IIII)Lsage/media/image/RawImage; */ JNIEXPORT jobject JNICALL Java_sage_FreetypeFont_renderGlyphRaw0 (JNIEnv *env, jobject jo, jlong fontPtr, jobject inRawImage, jint rawWidth, jint rawHeight, jint imageX, jint imageY) { static jclass rawImageClass = 0; static jmethodID rawImageConstruct = 0; static jmethodID getDataMeth = 0; if (!rawImageClass) { rawImageClass = (*env)->NewGlobalRef(env, (*env)->FindClass(env, "sage/media/image/RawImage")); if ((*env)->ExceptionOccurred(env)) { return NULL; } rawImageConstruct = (*env)->GetMethodID(env, rawImageClass, "<init>", "(IILjava/nio/ByteBuffer;ZI)V"); if ((*env)->ExceptionOccurred(env)) { return NULL; } getDataMeth = (*env)->GetMethodID(env, rawImageClass, "getData", "()Ljava/nio/ByteBuffer;"); if ((*env)->ExceptionOccurred(env)) { return NULL; } } jobject rv = inRawImage; unsigned char* myImageData = NULL; if (!rv) { sysOutPrint(env, "Creating new RawImage for font rendering w=%d h=%d\r\n", rawWidth, rawHeight); // Create the RawImage object and the native buffer for it if it doesn't exist yet myImageData = (unsigned char*) calloc(4*rawWidth*rawHeight, 1); jobject dbuf = (*env)->NewDirectByteBuffer(env, (void*)myImageData, 4*rawWidth*rawHeight); if ((*env)->ExceptionOccurred(env)) { free(myImageData); return NULL; } rv = (*env)->NewObject(env, rawImageClass, rawImageConstruct, rawWidth, rawHeight, dbuf, JNI_TRUE, 4*rawWidth); if ((*env)->ExceptionOccurred(env)) { free(myImageData); return NULL; } } else { // Get the address to the native image buffer so we can write to it jobject bb = (*env)->CallObjectMethod(env, rv, getDataMeth); if ((*env)->ExceptionOccurred(env)) { return NULL; } myImageData = (unsigned char*) (*env)->GetDirectBufferAddress(env, bb); } FTDataStruct* fontData = (FTDataStruct*)(intptr_t) fontPtr; FT_Face face = fontData->facePtr; FT_Activate_Size(fontData->sizePtr); // Render the glyph to a FT buffer int error = FT_Render_Glyph(face->glyph, ft_render_mode_normal); if (error) return NULL; int width = face->glyph->bitmap.width; int height = face->glyph->bitmap.rows; int x=0,y=0; imageX += face->glyph->bitmap_left; imageY -= face->glyph->bitmap_top; // imageY += (face->size->metrics.ascender >> 6); unsigned char* bufPtr = face->glyph->bitmap.buffer; int yOff, off; // Copy the glyph to our image buffer for (;y < height; y++, bufPtr += face->glyph->bitmap.pitch) { if (imageY + y < 0 || imageY + y >= rawHeight) continue; yOff = (imageY + y)*rawWidth*4; for (x = 0; x < width; x++) { if (imageX + x < 0 || imageX + x >= rawWidth) continue; off = yOff + (imageX + x)*4; unsigned char bv = *(bufPtr + x); myImageData[off] = bv; myImageData[off + 1] = bv; myImageData[off + 2] = bv; myImageData[off + 3] = bv; } } return rv; }
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { WNDCLASS wc; if( !hPrevInstance ) /*set up window class and register it */ { wc.lpszClassName = "SageApp"; wc.hInstance = hInstance; wc.lpfnWndProc = WndProc; wc.hCursor = LoadCursor( NULL, IDC_ARROW ); wc.hIcon = LoadIcon( NULL, IDI_APPLICATION ); wc.lpszMenuName = NULL; wc.hbrBackground = (HBRUSH)GetStockObject( WHITE_BRUSH ); wc.style = 0; wc.cbClsExtra = 0; wc.cbWndExtra = 0; if( !RegisterClass( &wc ) ) return FALSE; } HWND hWnd = CreateWindow( "SageApp", "SageWin", WS_OVERLAPPEDWINDOW | WS_CAPTION | WS_CLIPCHILDREN, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, (HWND)NULL, (HMENU)NULL, (HINSTANCE)hInstance, (LPSTR)NULL ); /* * Explicitly load jvm.dll by using the Windows Registry to locate the current version to use. */ HKEY rootKey = HKEY_LOCAL_MACHINE; char currVer[16]; HKEY myKey; DWORD readType; DWORD dwRead = 0; DWORD hsize = sizeof(dwRead); hsize = sizeof(currVer); HMODULE exeMod = GetModuleHandle(NULL); LPTSTR appPath = new TCHAR[512]; GetModuleFileName(exeMod, appPath, 512); int appLen = strlen(appPath); for (int i = appLen - 1; i > 0; i--) { if (appPath[i] == '\\') { appPath[i + 1] = 0; break; } } // See if we've got a JVM in our own directory to load TCHAR includedJRE[1024]; strcpy(includedJRE, appPath); strcat(includedJRE, "jre\\bin\\client\\jvm.dll"); HMODULE hLib = LoadLibrary(includedJRE); if(hLib == NULL) { // Failed, load the JVM from the registry instead if (RegOpenKeyEx(rootKey, "Software\\JavaSoft\\Java Runtime Environment", 0, KEY_QUERY_VALUE, &myKey) != ERROR_SUCCESS) { JVM_MISSING; return FALSE; } if (RegQueryValueEx(myKey, "CurrentVersion", 0, &readType, (LPBYTE)currVer, &hsize) != ERROR_SUCCESS) { RegCloseKey(myKey); JVM_MISSING; return FALSE; } RegCloseKey(myKey); char pathKey[1024]; strcpy(pathKey, "Software\\JavaSoft\\Java Runtime Environment\\"); strcat(pathKey, currVer); char jvmPath[1024]; if (RegOpenKeyEx(rootKey, pathKey, 0, KEY_QUERY_VALUE, &myKey) != ERROR_SUCCESS) { JVM_MISSING; return FALSE; } hsize = sizeof(jvmPath); if (RegQueryValueEx(myKey, "RuntimeLib", 0, &readType, (LPBYTE)jvmPath, &hsize) != ERROR_SUCCESS) { RegCloseKey(myKey); JVM_MISSING; return FALSE; } RegCloseKey(myKey); hLib = LoadLibrary(jvmPath); if(hLib == NULL) { errorMsg("Could not find jvm.dll.\nPlease install Java Runtime Environment 1.4", "Java Missing"); return FALSE; } } // Retrieve address of JNI_CreateJavaVM() typedef jint (JNICALL *P_JNI_CreateJavaVM) (JavaVM **pvm, void** penv, void *args); P_JNI_CreateJavaVM createJavaVM = (P_JNI_CreateJavaVM) GetProcAddress(hLib, "JNI_CreateJavaVM"); if (createJavaVM==NULL) { errorMsg("Could not execute jvm.dll.\nPlease install Java Runtime Environment 1.4", "Java Missing"); return FALSE; } // Set the current working directory to be the folder the EXE is in. chdir(appPath); LPTSTR jarPath = new TCHAR[1024]; LPTSTR libraryPath = new TCHAR[512]; JNIEnv *env; /* pointer to native method interface */ JavaVMInitArgs vm_args; JavaVMOption options[32]; vm_args.nOptions = 0; strcpy(jarPath, "-Djava.class.path="); strcat(jarPath, appPath); strcat(jarPath, "MiniClient.jar"); options[vm_args.nOptions++].optionString = jarPath; strcpy(libraryPath, "-Djava.library.path="); strcat(libraryPath, appPath); options[vm_args.nOptions++].optionString = libraryPath; /* set native library path */ // With the new animation surfaces that increaese mem usage by about 30MB so we need to bump it // up another 30 above the default of 64 char memString[32]; strcpy(memString, "-Xmx128m"); options[vm_args.nOptions++].optionString = memString; vm_args.version = JNI_VERSION_1_2; vm_args.options = options; vm_args.ignoreUnrecognized = true; /* Note that in the Java 2 SDK, there is no longer any need to call * JNI_GetDefaultJavaVMInitArgs. */ int res = (*createJavaVM)(&vm, (void**) &env, &vm_args); if (res != 0) { errorMsg("Could not create JVM.\nPlease reinstall Java Runtime Environment 1.4", "Java Missing"); return FALSE; } globalenv = env; /* invoke the Main.test method using the JNI */ jclass cls = env->FindClass("sage/miniclient/MiniClient"); jthrowable clsThrow =env->ExceptionOccurred(); if (clsThrow) { popupExceptionError(env, clsThrow, "Could not find JAR file."); return FALSE; } jmethodID mid = env->GetStaticMethodID(cls, "main", "([Ljava/lang/String;)V"); if (env->ExceptionCheck()) { errorMsg("Could not find main in class.\nPlease reinstall the Sage application", "Java Error"); return FALSE; } env->CallStaticVoidMethod(cls, mid, NULL); jthrowable mainThrow = env->ExceptionOccurred(); if (mainThrow != NULL) { env->ExceptionClear(); jmethodID toStr = env->GetMethodID(env->GetObjectClass(mainThrow), "toString", "()Ljava/lang/String;"); //env->ExceptionDescribe(); jstring throwStr = (jstring)env->CallObjectMethod(mainThrow, toStr); const char* cThrowStr = env->GetStringUTFChars(throwStr, 0); char *errStr = new char[env->GetStringLength(throwStr) + 64]; sprintf(errStr, "An exception occured in Java:\n%s", cThrowStr); errorMsg(errStr, "Java Exception"); delete errStr; return FALSE; } jclass miniConnClass = env->FindClass("sage/miniclient/MiniClientConnection"); if (env->ExceptionCheck()) { errorMsg("Could not find required class.\nPlease reinstall the SageTV application", "Java Error"); return FALSE; } jfieldID currConnField = env->GetStaticFieldID(miniConnClass, "currConnection", "Lsage/miniclient/MiniClientConnection;"); if (env->ExceptionCheck()) { errorMsg("Could not find required class.\nPlease reinstall the SageTV application", "Java Error"); return FALSE; } jmethodID recvCmdMeth = env->GetMethodID(miniConnClass, "postSageCommandEvent", "(I)V"); if (env->ExceptionCheck()) { errorMsg("Could not find required class.\nPlease reinstall the SageTV application", "Java Error"); return FALSE; } // Now setup the shell hooks so the MCE remote control works HMODULE sageLib = LoadLibrary("SageTVWin32.dll"); if (sageLib) { LPFNSetupHooks hookProc = (LPFNSetupHooks)GetProcAddress(sageLib, "_Java_sage_Sage_setupSystemHooks0@16"); if (hookProc) { hookProc(env, 0, (jlong)hWnd); } } MSG lpMsg; BOOL bRet; while((bRet = GetMessage( &lpMsg, NULL, 0, 0 )) != 0) /* begin the message loop */ { // sysOutPrint(env, "Kick! msg=%d lparam=%d wParam=%d\r\n", lpMsg.message - 0x400, // lpMsg.lParam, lpMsg.wParam); if (bRet == -1) { // Error receiving the message } else if (lpMsg.message - 0x400 == 234 && recvCmdMeth) { jobject currConn = env->GetStaticObjectField(miniConnClass, currConnField); if (currConn) { env->CallVoidMethod(currConn, recvCmdMeth, (jint) lpMsg.lParam); if (env->ExceptionOccurred()) { sysOutPrint(env, "Got exception during native callback 234\n"); env->ExceptionClear(); } } } else { TranslateMessage( &lpMsg ); DispatchMessage( &lpMsg ); } } // Java_sage_Sage_releaseSystemHooks0(env, 0, (jlong)hWnd); delete [] appPath; delete [] jarPath; delete [] libraryPath; FreeLibrary(hLib); return 0; }