JNIEXPORT void JNICALL jni_freerdp_set_clipboard_redirection(JNIEnv *env, jclass cls, jint instance, jboolean enable) { freerdp* inst = (freerdp*)instance; rdpSettings * settings = inst->settings; DEBUG_ANDROID("clipboard redirect: %s", enable ? "TRUE" : "FALSE"); settings->RedirectClipboard = enable ? TRUE : FALSE; }
void* android_thread_func(void* param) { struct thread_data* data; data = (struct thread_data*) param; assert(data); assert(data->instance); DEBUG_ANDROID("Start."); freerdp* instance = data->instance; android_freerdp_run(instance); free(data); DEBUG_ANDROID("Quit."); ExitThread(0); return NULL; }
static void* jni_input_thread(void* arg) { HANDLE event[3]; wMessageQueue* queue; freerdp* instance = (freerdp*) arg; androidContext *aCtx = (androidContext*)instance->context; assert(NULL != instance); assert(NULL != aCtx); DEBUG_ANDROID("Start."); queue = freerdp_get_message_queue(instance, FREERDP_INPUT_MESSAGE_QUEUE); event[0] = CreateFileDescriptorEvent(NULL, FALSE, FALSE, aCtx->event_queue->pipe_fd[0]); event[1] = CreateFileDescriptorEvent(NULL, FALSE, FALSE, aCtx->event_queue->pipe_fd[1]); event[2] = freerdp_get_message_queue_event_handle(instance, FREERDP_INPUT_MESSAGE_QUEUE); do { DWORD rc = WaitForMultipleObjects(3, event, FALSE, INFINITE); if ((rc < WAIT_OBJECT_0) || (rc > WAIT_OBJECT_0 + 2)) continue; if (rc == WAIT_OBJECT_0 + 2) { wMessage msg; MessageQueue_Peek(queue, &msg, FALSE); if (msg.id == WMQ_QUIT) break; } if (android_check_fds(instance) != TRUE) break; } while(1); DEBUG_ANDROID("Quit."); MessageQueue_PostQuit(queue, 0); ExitThread(0); return NULL; }
static BOOL android_end_paint(rdpContext* context) { int i; int ninvalid; HGDI_RGN cinvalid; int x1, y1, x2, y2; androidContext *ctx = (androidContext*)context; rdpSettings* settings = context->instance->settings; assert(ctx); assert(settings); assert(context->instance); ninvalid = ctx->rdpCtx.gdi->primary->hdc->hwnd->ninvalid; if (ninvalid == 0) { DEBUG_ANDROID("ui_update: ninvalid=%d", ninvalid); return TRUE; } cinvalid = ctx->rdpCtx.gdi->primary->hdc->hwnd->cinvalid; x1 = cinvalid[0].x; y1 = cinvalid[0].y; x2 = cinvalid[0].x + cinvalid[0].w; y2 = cinvalid[0].y + cinvalid[0].h; for (i = 0; i < ninvalid; i++) { x1 = MIN(x1, cinvalid[i].x); y1 = MIN(y1, cinvalid[i].y); x2 = MAX(x2, cinvalid[i].x + cinvalid[i].w); y2 = MAX(y2, cinvalid[i].y + cinvalid[i].h); } DEBUG_ANDROID("ui_update: ninvalid=%d x=%d, y=%d, width=%d, height=%d, bpp=%d", ninvalid, x1, y1, x2 - x1, y2 - y1, settings->ColorDepth); freerdp_callback("OnGraphicsUpdate", "(IIIII)V", context->instance, x1, y1, x2 - x1, y2 - y1); return TRUE; }
JNIEXPORT void JNICALL jni_freerdp_set_advanced_settings(JNIEnv *env, jclass cls, jint instance, jstring jRemoteProgram, jstring jWorkDir) { freerdp* inst = (freerdp*)instance; rdpSettings * settings = inst->settings; const jbyte *remote_program = (*env)->GetStringUTFChars(env, jRemoteProgram, NULL); const jbyte *work_dir = (*env)->GetStringUTFChars(env, jWorkDir, NULL); DEBUG_ANDROID("Remote Program: %s", (char*) remote_program); DEBUG_ANDROID("Work Dir: %s", (char*) work_dir); if(remote_program && strlen(remote_program) > 0) settings->AlternateShell = strdup(remote_program); if(work_dir && strlen(work_dir) > 0) settings->ShellWorkingDirectory = strdup(work_dir); (*env)->ReleaseStringUTFChars(env, jRemoteProgram, remote_program); (*env)->ReleaseStringUTFChars(env, jWorkDir, work_dir); }
JNIEXPORT void JNICALL jni_freerdp_send_unicodekey_event( JNIEnv *env, jclass cls, jint instance, jint keycode) { ANDROID_EVENT* event; freerdp* inst = (freerdp*)instance; event = (ANDROID_EVENT*) android_event_unicodekey_new(keycode); android_push_event(inst, event); DEBUG_ANDROID("send_unicodekey_event: %d", keycode); }
JNIEXPORT void JNICALL jni_freerdp_send_cursor_event( JNIEnv *env, jclass cls, jint instance, jint x, jint y, jint flags) { ANDROID_EVENT* event; freerdp* inst = (freerdp*)instance; event = (ANDROID_EVENT*) android_event_cursor_new(flags, x, y); android_push_event(inst, event); DEBUG_ANDROID("send_cursor_event: (%d, %d), %d", x, y, flags); }
svg_status_t _svg_android_push_state (svg_android_t *svg_android, jobject offscreen_bitmap) { DEBUG_ENTRY("push_state"); if (!svg_android->state) { DEBUG_ANDROID("P S 1"); if((svg_android->state = _svg_android_state_push (svg_android, svg_android->state)) == NULL) return SVG_STATUS_NO_MEMORY; DEBUG_ANDROID("P S 2"); svg_android->state->viewport_width = svg_android->viewport_width; svg_android->state->viewport_height = svg_android->viewport_height; DEBUG_ANDROID("P S 3"); } else { DEBUG_ANDROID("P S 4"); if (offscreen_bitmap) { jobject new_canvas = ANDROID_CANVAS_CREATE(svg_android, offscreen_bitmap); DEBUG_ANDROID("P S 5"); svg_android->state->saved_canvas = svg_android->canvas; svg_android->canvas = new_canvas; DEBUG_ANDROID("P S 6"); _svg_android_copy_canvas_state (svg_android); DEBUG_ANDROID("P S 7"); } DEBUG_ANDROID("P S 8"); if((svg_android->state = _svg_android_state_push (svg_android, svg_android->state)) == NULL) return SVG_STATUS_NO_MEMORY; DEBUG_ANDROID("P S 9"); } DEBUG_ANDROID("P S 10"); DEBUG_EXIT("push_state"); return SVG_STATUS_SUCCESS; }
void android_desktop_resize(rdpContext* context) { DEBUG_ANDROID("ui_desktop_resize"); assert(context); assert(context->settings); assert(context->instance); freerdp_callback("OnGraphicsResize", "(IIII)V", context->instance, context->settings->DesktopWidth, context->settings->DesktopHeight, context->settings->ColorDepth); }
BOOL android_authenticate(freerdp* instance, char** username, char** password, char** domain) { DEBUG_ANDROID("Authenticate user:"******" Username: %s", *username); DEBUG_ANDROID(" Domain: %s", *domain); JNIEnv* env; jboolean attached = jni_attach_thread(&env); jobject jstr1 = create_string_builder(env, *username); jobject jstr2 = create_string_builder(env, *domain); jobject jstr3 = create_string_builder(env, *password); jboolean res = freerdp_callback_bool_result("OnAuthenticate", "(ILjava/lang/StringBuilder;Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;)Z", instance, jstr1, jstr2, jstr3); if (res == JNI_TRUE) { // read back string values if (*username != NULL) free(*username); *username = get_string_from_string_builder(env, jstr1); if (*domain != NULL) free(*domain); *domain = get_string_from_string_builder(env, jstr2); if (*password == NULL) free(*password); *password = get_string_from_string_builder(env, jstr3); } if (attached == JNI_TRUE) jni_detach_thread(); return ((res == JNI_TRUE) ? TRUE : FALSE); }
static BOOL android_verify_certificate(freerdp* instance, char* subject, char* issuer, char* fingerprint) { DEBUG_ANDROID("Certificate details:"); DEBUG_ANDROID("\tSubject: %s", subject); DEBUG_ANDROID("\tIssuer: %s", issuer); DEBUG_ANDROID("\tThumbprint: %s", fingerprint); DEBUG_ANDROID("The above X.509 certificate could not be verified, possibly because you do not have " "the CA certificate in your certificate store, or the certificate has expired." "Please look at the documentation on how to create local certificate store for a private CA.\n"); JNIEnv* env; jboolean attached = jni_attach_thread(&env); jstring jstr1 = (*env)->NewStringUTF(env, subject); jstring jstr2 = (*env)->NewStringUTF(env, issuer); jstring jstr3 = (*env)->NewStringUTF(env, fingerprint); jboolean res = freerdp_callback_bool_result("OnVerifyCertificate", "(ILjava/lang/String;Ljava/lang/String;Ljava/lang/String;)Z", instance, jstr1, jstr2, jstr3); if (attached == JNI_TRUE) jni_detach_thread(); return ((res == JNI_TRUE) ? TRUE : FALSE); }
JNIEXPORT void JNICALL jni_freerdp_set_performance_flags( JNIEnv *env, jclass cls, jint instance, jboolean remotefx, jboolean disableWallpaper, jboolean disableFullWindowDrag, jboolean disableMenuAnimations, jboolean disableTheming, jboolean enableFontSmoothing, jboolean enableDesktopComposition) { freerdp* inst = (freerdp*)instance; rdpSettings * settings = inst->settings; DEBUG_ANDROID("remotefx: %d", (remotefx == JNI_TRUE) ? 1 : 0); if (remotefx == JNI_TRUE) { settings->RemoteFxCodec = TRUE; settings->FastPathOutput = TRUE; settings->ColorDepth = 32; settings->LargePointerFlag = TRUE; settings->FrameMarkerCommandEnabled = TRUE; } else { /* enable NSCodec if we don't use remotefx */ settings->NSCodec = TRUE; } /* store performance settings */ settings->DisableWallpaper = (disableWallpaper == JNI_TRUE) ? TRUE : FALSE; settings->DisableFullWindowDrag = (disableFullWindowDrag == JNI_TRUE) ? TRUE : FALSE; settings->DisableMenuAnims = (disableMenuAnimations == JNI_TRUE) ? TRUE : FALSE; settings->DisableThemes = (disableTheming == JNI_TRUE) ? TRUE : FALSE; settings->AllowFontSmoothing = (enableFontSmoothing == JNI_TRUE) ? TRUE : FALSE; settings->AllowDesktopComposition = (enableDesktopComposition == JNI_TRUE) ? TRUE : FALSE; /* Create performance flags from settings */ freerdp_performance_flags_make(settings); DEBUG_ANDROID("performance_flags: %04X", settings->PerformanceFlags); }
JNIEXPORT void JNICALL jni_freerdp_set_drive_redirection(JNIEnv *env, jclass cls, jint instance, jstring jpath) { freerdp* inst = (freerdp*)instance; rdpSettings * settings = inst->settings; char* args[] = {"drive", "Android", ""}; const jbyte *path = (*env)->GetStringUTFChars(env, jpath, NULL); DEBUG_ANDROID("drive redirect: %s", (char*)path); args[2] = (char*)path; freerdp_client_add_device_channel(settings, 3, args); settings->DeviceRedirection = TRUE; (*env)->ReleaseStringUTFChars(env, jpath, path); }
JNIEXPORT void JNICALL jni_freerdp_send_clipboard_data(JNIEnv *env, jclass cls, jint instance, jstring jdata) { ANDROID_EVENT* event; freerdp* inst = (freerdp*)instance; const jbyte *data = jdata != NULL ? (*env)->GetStringUTFChars(env, jdata, NULL) : NULL; int data_length = data ? strlen(data) : 0; event = (ANDROID_EVENT*) android_event_clipboard_new((void*)data, data_length); android_push_event(inst, event); DEBUG_ANDROID("send_clipboard_data: (%s)", data); if (data) (*env)->ReleaseStringUTFChars(env, jdata, data); }
svg_android_status_t _svg_android_state_init_copy (svg_android_state_t *state, const svg_android_state_t *other) { if(other == NULL) // Nothing to copy => don't copy return SVG_ANDROID_STATUS_SUCCESS; // copy all fields as-is *state = *other; /* We don't need our own child_surface or saved cr at this point. */ state->offscreen_bitmap = NULL; state->saved_canvas = NULL; // copy paint state->paint = ANDROID_PAINT_COPY(state->instance, other->paint); state->paint = (*(state->instance->env))->NewGlobalRef( state->instance->env, state->paint); // copy matrix state->matrix = ANDROID_MATRIX_COPY(state->instance, other->matrix); state->matrix = (*(state->instance->env))->NewGlobalRef( state->instance->env, state->matrix); DEBUG_ANDROID("-----------------------------"); DEBUG_ANDROID1("COPY created global refs for paint at %p", state->paint); DEBUG_ANDROID1("COPY created global refs for paint at %p", state->matrix); // We need to duplicate the string if (other->font_family) state->font_family = strdup ((char *) other->font_family); // XXX anton: are these not copied already?! state->viewport_width = other->viewport_width; state->viewport_height = other->viewport_height; // Create a copy of the dash if (other->dash) { state->dash = malloc (state->num_dashes * sizeof(double)); if (state->dash == NULL) return SVG_ANDROID_STATUS_NO_MEMORY; memcpy (state->dash, other->dash, state->num_dashes * sizeof(double)); } return SVG_ANDROID_STATUS_SUCCESS; }
JNIEXPORT void JNICALL jni_freerdp_send_key_event( JNIEnv *env, jclass cls, jint instance, jint keycode, jboolean down) { DWORD scancode; ANDROID_EVENT* event; freerdp* inst = (freerdp*)instance; scancode = GetVirtualScanCodeFromVirtualKeyCode(keycode, 4); int flags = (down == JNI_TRUE) ? KBD_FLAGS_DOWN : KBD_FLAGS_RELEASE; flags |= (scancode & KBDEXT) ? KBD_FLAGS_EXTENDED : 0; event = (ANDROID_EVENT*) android_event_key_new(flags, scancode & 0xFF); android_push_event(inst, event); DEBUG_ANDROID("send_key_event: %d, %d", (int)scancode, flags); }
static BOOL android_pre_connect(freerdp* instance) { DEBUG_ANDROID("android_pre_connect"); rdpSettings* settings = instance->settings; BOOL bitmap_cache = settings->BitmapCacheEnabled; settings->OrderSupport[NEG_DSTBLT_INDEX] = TRUE; settings->OrderSupport[NEG_PATBLT_INDEX] = TRUE; settings->OrderSupport[NEG_SCRBLT_INDEX] = TRUE; settings->OrderSupport[NEG_OPAQUE_RECT_INDEX] = TRUE; settings->OrderSupport[NEG_DRAWNINEGRID_INDEX] = FALSE; settings->OrderSupport[NEG_MULTIDSTBLT_INDEX] = FALSE; settings->OrderSupport[NEG_MULTIPATBLT_INDEX] = FALSE; settings->OrderSupport[NEG_MULTISCRBLT_INDEX] = FALSE; settings->OrderSupport[NEG_MULTIOPAQUERECT_INDEX] = TRUE; settings->OrderSupport[NEG_MULTI_DRAWNINEGRID_INDEX] = FALSE; settings->OrderSupport[NEG_LINETO_INDEX] = TRUE; settings->OrderSupport[NEG_POLYLINE_INDEX] = TRUE; settings->OrderSupport[NEG_MEMBLT_INDEX] = bitmap_cache; settings->OrderSupport[NEG_MEM3BLT_INDEX] = TRUE; settings->OrderSupport[NEG_MEMBLT_V2_INDEX] = bitmap_cache; settings->OrderSupport[NEG_MEM3BLT_V2_INDEX] = FALSE; settings->OrderSupport[NEG_SAVEBITMAP_INDEX] = FALSE; settings->OrderSupport[NEG_GLYPH_INDEX_INDEX] = TRUE; settings->OrderSupport[NEG_FAST_INDEX_INDEX] = TRUE; settings->OrderSupport[NEG_FAST_GLYPH_INDEX] = TRUE; settings->OrderSupport[NEG_POLYGON_SC_INDEX] = FALSE; settings->OrderSupport[NEG_POLYGON_CB_INDEX] = FALSE; settings->OrderSupport[NEG_ELLIPSE_SC_INDEX] = FALSE; settings->OrderSupport[NEG_ELLIPSE_CB_INDEX] = FALSE; settings->FrameAcknowledge = 10; PubSub_SubscribeChannelConnected(instance->context->pubSub, (pChannelConnectedEventHandler) android_OnChannelConnectedEventHandler); PubSub_SubscribeChannelDisconnected(instance->context->pubSub, (pChannelDisconnectedEventHandler) android_OnChannelDisconnectedEventHandler); freerdp_register_addin_provider(freerdp_channels_load_static_addin_entry, 0); freerdp_client_load_addins(instance->context->channels, instance->settings); freerdp_channels_pre_connect(instance->context->channels, instance); return TRUE; }
JNIEXPORT jboolean JNICALL jni_freerdp_send_unicodekey_event( JNIEnv *env, jclass cls, jint instance, jint keycode) { ANDROID_EVENT* event; freerdp* inst = (freerdp*)instance; event = (ANDROID_EVENT*) android_event_unicodekey_new(keycode); if (!event) return JNI_FALSE; if (!android_push_event(inst, event)) { android_event_unicodekey_free((ANDROID_EVENT_KEY *)event); return JNI_FALSE; } DEBUG_ANDROID("send_unicodekey_event: %d", keycode); return JNI_TRUE; }
static void android_OnChannelDisconnectedEventHandler(rdpContext* context, ChannelDisconnectedEventArgs* e) { rdpSettings* settings = context->settings; androidContext* afc = (androidContext*) context; if (strcmp(e->name, RDPEI_DVC_CHANNEL_NAME) == 0) { DEBUG_ANDROID("Unhandled case.. RDPEI_DVC_CHANNEL_NAME"); } else if (strcmp(e->name, RDPGFX_DVC_CHANNEL_NAME) == 0) { if (settings->SoftwareGdi) gdi_graphics_pipeline_uninit(context->gdi, (RdpgfxClientContext*) e->pInterface); } else if (strcmp(e->name, CLIPRDR_SVC_CHANNEL_NAME) == 0) { android_cliprdr_uninit(afc, (CliprdrClientContext*) e->pInterface); } }
JNIEXPORT jboolean JNICALL jni_freerdp_send_cursor_event( JNIEnv *env, jclass cls, jint instance, jint x, jint y, jint flags) { ANDROID_EVENT* event; freerdp* inst = (freerdp*)instance; event = (ANDROID_EVENT*) android_event_cursor_new(flags, x, y); if (!event) return JNI_FALSE; if (!android_push_event(inst, event)) { android_event_cursor_free((ANDROID_EVENT_CURSOR *)event); return JNI_FALSE; } DEBUG_ANDROID("send_cursor_event: (%d, %d), %d", x, y, flags); return JNI_TRUE; }
JNIEXPORT void JNICALL jni_freerdp_set_microphone_redirection(JNIEnv *env, jclass cls, jint instance, jboolean enable) { char** p; int count = 1; freerdp* inst = (freerdp*)instance; rdpSettings * settings = inst->settings; DEBUG_ANDROID("microphone redirect: %s", enable ? "TRUE" : "FALSE"); settings->AudioCapture = enable; if (enable) { p = malloc(sizeof(char*)); p[0] = "audin"; freerdp_client_add_dynamic_channel(settings, count, p); free(p); } }
JNIEXPORT void JNICALL jni_freerdp_set_sound_redirection(JNIEnv *env, jclass cls, jint instance, jint redirect) { char** p; int count = 1; freerdp* inst = (freerdp*)instance; rdpSettings * settings = inst->settings; DEBUG_ANDROID("sound: %s", redirect ? ((redirect == 1) ? "Server" : "Redirect") : "None"); settings->AudioPlayback = (redirect == 2) ? TRUE : FALSE; settings->RemoteConsoleAudio = (redirect == 1) ? TRUE : FALSE; if (settings->AudioPlayback) { p = malloc(sizeof(char*)); p[0] = "rdpsnd"; freerdp_client_add_static_channel(settings, count, p); free(p); } }
BOOL android_post_connect(freerdp* instance) { DEBUG_ANDROID("android_post_connect"); freerdp_callback("OnSettingsChanged", "(IIII)V", instance, instance->settings->DesktopWidth, instance->settings->DesktopHeight, instance->settings->ColorDepth); instance->context->cache = cache_new(instance->settings); gdi_init(instance, CLRCONV_ALPHA | ((instance->settings->ColorDepth > 16) ? CLRBUF_32BPP : CLRBUF_16BPP), NULL); instance->update->BeginPaint = android_begin_paint; instance->update->EndPaint = android_end_paint; instance->update->DesktopResize = android_desktop_resize; android_cliprdr_init(instance); freerdp_channels_post_connect(instance->context->channels, instance); // send notifications freerdp_callback("OnConnectionSuccess", "(I)V", instance); return TRUE; }
static void android_process_channel_event(rdpChannels* channels, freerdp* instance) { wMessage* event; event = freerdp_channels_pop_event(channels); if (event) { int ev = GetMessageClass(event->id); switch(ev) { case CliprdrChannel_Class: android_process_cliprdr_event(instance, event); break; default: DEBUG_ANDROID("Unsupported channel event %08X", ev); break; } freerdp_event_free(event); } }
JNIEXPORT jboolean JNICALL jni_freerdp_set_microphone_redirection(JNIEnv *env, jclass cls, jint instance, jboolean enable) { freerdp* inst = (freerdp*)instance; rdpSettings * settings = inst->settings; DEBUG_ANDROID("microphone redirect: %s", enable ? "TRUE" : "FALSE"); settings->AudioCapture = enable; if (enable) { int ret; char* p[1] = {"audin"}; int count = 1; ret = freerdp_client_add_dynamic_channel(settings, count, p); if (ret == -1) return JNI_FALSE; } return JNI_TRUE; }
svg_android_status_t _svg_android_state_init (svg_android_state_t *state) { state->path = ANDROID_PATH_CREATE(state->instance); state->path = (*(state->instance->env))->NewGlobalRef( state->instance->env, state->path); if(state->paint == NULL) { state->paint = ANDROID_PAINT_CREATE(state->instance); state->paint = (*(state->instance->env))->NewGlobalRef( state->instance->env, state->paint); } if(state->matrix == NULL) { state->matrix = ANDROID_IDENTITY_MATRIX(state->instance); state->matrix = (*(state->instance->env))->NewGlobalRef( state->instance->env, state->matrix); } DEBUG_ANDROID("-----------------------------"); DEBUG_ANDROID1("Created global refs for path at %p", state->path); DEBUG_ANDROID1("Created global refs for paint at %p", state->paint); DEBUG_ANDROID1("Created global refs for matrix at %p", state->matrix); ANDROID_SET_ANTIALIAS(state->instance, state->paint, state->instance->do_antialias); // this might already be set by copy if(state->font_family == NULL) { state->font_family = strdup (SVG_ANDROID_FONT_FAMILY_DEFAULT); if (state->font_family == NULL) return SVG_ANDROID_STATUS_NO_MEMORY; } return SVG_ANDROID_STATUS_SUCCESS; }
static BOOL android_post_connect(freerdp* instance) { UINT32 gdi_flags; rdpSettings *settings = instance->settings; DEBUG_ANDROID("android_post_connect"); assert(instance); assert(settings); freerdp_callback("OnSettingsChanged", "(IIII)V", instance, settings->DesktopWidth, settings->DesktopHeight, settings->ColorDepth); if (!(instance->context->cache = cache_new(settings))) return FALSE; if (instance->settings->ColorDepth > 16) gdi_flags = CLRBUF_32BPP | CLRCONV_ALPHA | CLRCONV_INVERT; else gdi_flags = CLRBUF_16BPP; if (!gdi_init(instance, gdi_flags, NULL)) return FALSE; instance->update->BeginPaint = android_begin_paint; instance->update->EndPaint = android_end_paint; instance->update->DesktopResize = android_desktop_resize; if (freerdp_channels_post_connect(instance->context->channels, instance) < 0) return FALSE; freerdp_callback("OnConnectionSuccess", "(I)V", instance); return TRUE; }
JNIEXPORT jboolean JNICALL jni_freerdp_set_sound_redirection(JNIEnv *env, jclass cls, jint instance, jint redirect) { freerdp* inst = (freerdp*)instance; rdpSettings * settings = inst->settings; DEBUG_ANDROID("sound: %s", redirect ? ((redirect == 1) ? "Server" : "Redirect") : "None"); settings->AudioPlayback = (redirect == 2) ? TRUE : FALSE; if (settings->AudioPlayback) { int ret; char* p[1] = {"rdpsnd"}; int count = 1; ret = freerdp_client_add_static_channel(settings, count, p); if(ret == -1) return JNI_FALSE; } settings->RemoteConsoleAudio = (redirect == 1) ? TRUE : FALSE; return JNI_TRUE; }
JNIEXPORT jboolean JNICALL jni_freerdp_set_connection_info(JNIEnv *env, jclass cls, jint instance, jstring jhostname, jstring jusername, jstring jpassword, jstring jdomain, jint width, jint height, jint color_depth, jint port, jboolean console, jint security, jstring jcertname) { freerdp* inst = (freerdp*)instance; rdpSettings * settings = inst->settings; const jbyte *hostname; const jbyte *username; const jbyte *password; const jbyte *domain; const jbyte *certname; if(!(hostname = (*env)->GetStringUTFChars(env, jhostname, NULL))) return JNI_FALSE; if (!(username = (*env)->GetStringUTFChars(env, jusername, NULL))) goto out_fail_username; if (!(password = (*env)->GetStringUTFChars(env, jpassword, NULL))) goto out_fail_password; if (!(domain = (*env)->GetStringUTFChars(env, jdomain, NULL))) goto out_fail_domain; if (!(certname = (*env)->GetStringUTFChars(env, jcertname, NULL))) goto out_fail_certname; DEBUG_ANDROID("hostname: %s", (char*) hostname); DEBUG_ANDROID("username: %s", (char*) username); DEBUG_ANDROID("password: %s", (char*) password); DEBUG_ANDROID("domain: %s", (char*) domain); DEBUG_ANDROID("width: %d", width); DEBUG_ANDROID("height: %d", height); DEBUG_ANDROID("color depth: %d", color_depth); DEBUG_ANDROID("port: %d", port); DEBUG_ANDROID("security: %d", security); settings->DesktopWidth = width; settings->DesktopHeight = height; settings->ColorDepth = color_depth; settings->ServerPort = port; // Hack for 16 bit RDVH connections: // In this case we get screen corruptions when we have an odd screen resolution width ... need to investigate what is causing this... if (color_depth <= 16) settings->DesktopWidth &= (~1); if (!(settings->ServerHostname = strdup(hostname))) goto out_fail_strdup; if (username && strlen(username) > 0) { if (!(settings->Username = strdup(username))) goto out_fail_strdup; } if (password && strlen(password) > 0) { if (!(settings->Password = strdup(password))) goto out_fail_strdup; settings->AutoLogonEnabled = TRUE; } if (!(settings->Domain = strdup(domain))) goto out_fail_strdup; if (certname && strlen(certname) > 0) { if (!(settings->CertificateName = strdup(certname))) goto out_fail_strdup; } settings->ConsoleSession = (console == JNI_TRUE) ? TRUE : FALSE; settings->SoftwareGdi = TRUE; settings->BitmapCacheV3Enabled = TRUE; switch ((int) security) { case 1: /* Standard RDP */ settings->RdpSecurity = TRUE; settings->TlsSecurity = FALSE; settings->NlaSecurity = FALSE; settings->ExtSecurity = FALSE; settings->UseRdpSecurityLayer = TRUE; break; case 2: /* TLS */ settings->NlaSecurity = FALSE; settings->TlsSecurity = TRUE; settings->RdpSecurity = FALSE; settings->ExtSecurity = FALSE; break; case 3: /* NLA */ settings->NlaSecurity = TRUE; settings->TlsSecurity = FALSE; settings->RdpSecurity = FALSE; settings->ExtSecurity = FALSE; break; default: break; } // set US keyboard layout settings->KeyboardLayout = 0x0409; (*env)->ReleaseStringUTFChars(env, jhostname, hostname); (*env)->ReleaseStringUTFChars(env, jusername, username); (*env)->ReleaseStringUTFChars(env, jpassword, password); (*env)->ReleaseStringUTFChars(env, jdomain, domain); (*env)->ReleaseStringUTFChars(env, jcertname, certname); return JNI_TRUE; out_fail_strdup: (*env)->ReleaseStringUTFChars(env, jcertname, certname); out_fail_certname: (*env)->ReleaseStringUTFChars(env, jdomain, domain); out_fail_domain: (*env)->ReleaseStringUTFChars(env, jpassword, password); out_fail_password: (*env)->ReleaseStringUTFChars(env, jusername, username); out_fail_username: (*env)->ReleaseStringUTFChars(env, jhostname, hostname); return JNI_FALSE; }
static int android_freerdp_run(freerdp* instance) { int i; int fds; int max_fds; int rcount; int wcount; int fd_input_event; HANDLE input_event = NULL; void* rfds[32]; void* wfds[32]; fd_set rfds_set; fd_set wfds_set; int select_status; struct timeval timeout; const rdpSettings* settings = instance->context->settings; HANDLE input_thread = NULL; HANDLE channels_thread = NULL; BOOL async_input = settings->AsyncInput; BOOL async_channels = settings->AsyncChannels; BOOL async_transport = settings->AsyncTransport; DEBUG_ANDROID("AsyncUpdate=%d", settings->AsyncUpdate); DEBUG_ANDROID("AsyncInput=%d", settings->AsyncInput); DEBUG_ANDROID("AsyncChannels=%d", settings->AsyncChannels); DEBUG_ANDROID("AsyncTransport=%d", settings->AsyncTransport); memset(rfds, 0, sizeof(rfds)); memset(wfds, 0, sizeof(wfds)); if (!freerdp_connect(instance)) { freerdp_callback("OnConnectionFailure", "(I)V", instance); return 0; } if (async_input) { if (!(input_thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) jni_input_thread, instance, 0, NULL))) { DEBUG_ANDROID("Failed to create async input thread\n"); goto disconnect; } } if (async_channels) { if (!(channels_thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) jni_channels_thread, instance, 0, NULL))) { DEBUG_ANDROID("Failed to create async channels thread\n"); goto disconnect; } } ((androidContext*)instance->context)->is_connected = TRUE; while (!freerdp_shall_disconnect(instance)) { rcount = 0; wcount = 0; if (!async_transport) { if (freerdp_get_fds(instance, rfds, &rcount, wfds, &wcount) != TRUE) { DEBUG_ANDROID("Failed to get FreeRDP file descriptor\n"); break; } } if (!async_channels) { if (freerdp_channels_get_fds(instance->context->channels, instance, rfds, &rcount, wfds, &wcount) != TRUE) { DEBUG_ANDROID("Failed to get channel manager file descriptor\n"); break; } } if (!async_input) { if (android_get_fds(instance, rfds, &rcount, wfds, &wcount) != TRUE) { DEBUG_ANDROID("Failed to get android file descriptor\n"); break; } } else { input_event = freerdp_get_message_queue_event_handle(instance, FREERDP_INPUT_MESSAGE_QUEUE); fd_input_event = GetEventFileDescriptor(input_event); rfds[rcount++] = (void*) (long) fd_input_event; } max_fds = 0; FD_ZERO(&rfds_set); FD_ZERO(&wfds_set); for (i = 0; i < rcount; i++) { fds = (int)(long)(rfds[i]); if (fds > max_fds) max_fds = fds; FD_SET(fds, &rfds_set); } if (max_fds == 0) break; timeout.tv_sec = 1; timeout.tv_usec = 0; select_status = select(max_fds + 1, &rfds_set, NULL, NULL, &timeout); if (select_status == 0) continue; else if (select_status == -1) { /* these are not really errors */ if (!((errno == EAGAIN) || (errno == EWOULDBLOCK) || (errno == EINPROGRESS) || (errno == EINTR))) /* signal occurred */ { DEBUG_ANDROID("android_run: select failed\n"); break; } } if (freerdp_shall_disconnect(instance)) break; if (!async_transport) { if (freerdp_check_fds(instance) != TRUE) { DEBUG_ANDROID("Failed to check FreeRDP file descriptor\n"); break; } } if (!async_input) { if (android_check_fds(instance) != TRUE) { DEBUG_ANDROID("Failed to check android file descriptor\n"); break; } } else if (input_event) { if (WaitForSingleObject(input_event, 0) == WAIT_OBJECT_0) { if (!freerdp_message_queue_process_pending_messages(instance, FREERDP_INPUT_MESSAGE_QUEUE)) { DEBUG_ANDROID("User Disconnect"); break; } } } if (!async_channels) { if (freerdp_channels_check_fds(instance->context->channels, instance) != TRUE) { DEBUG_ANDROID("Failed to check channel manager file descriptor\n"); break; } } } disconnect: DEBUG_ANDROID("Prepare shutdown..."); // issue another OnDisconnecting here in case the disconnect was initiated by the server and not our client freerdp_callback("OnDisconnecting", "(I)V", instance); DEBUG_ANDROID("Close channels..."); freerdp_channels_disconnect(instance->context->channels, instance); DEBUG_ANDROID("Cleanup threads..."); if (async_channels && channels_thread) { WaitForSingleObject(channels_thread, INFINITE); CloseHandle(channels_thread); } if (async_input && input_thread) { wMessageQueue* input_queue = freerdp_get_message_queue(instance, FREERDP_INPUT_MESSAGE_QUEUE); if (input_queue) { if (MessageQueue_PostQuit(input_queue, 0)) WaitForSingleObject(input_thread, INFINITE); } CloseHandle(input_thread); } DEBUG_ANDROID("run Disconnecting..."); freerdp_disconnect(instance); freerdp_callback("OnDisconnected", "(I)V", instance); DEBUG_ANDROID("run Quit."); return 0; }