diff --git a/CMakeLists.txt b/CMakeLists.txt index 1a19ad718..a50723f86 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -263,6 +263,7 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DWINPR_EXPORTS -DFREERDP_EXPORTS") if(NOT IOS) check_include_files(fcntl.h HAVE_FCNTL_H) check_include_files(unistd.h HAVE_UNISTD_H) + check_include_files(execinfo.h HAVE_EXECINFO_H) check_include_files(stdint.h HAVE_STDINT_H) check_include_files(inttypes.h HAVE_INTTYPES_H) check_include_files(sys/modem.h HAVE_SYS_MODEM_H) diff --git a/channels/audin/client/alsa/audin_alsa.c b/channels/audin/client/alsa/audin_alsa.c index e8b7259a7..1b7c3b3e9 100644 --- a/channels/audin/client/alsa/audin_alsa.c +++ b/channels/audin/client/alsa/audin_alsa.c @@ -72,7 +72,7 @@ static BOOL audin_alsa_set_params(AudinALSADevice* alsa, snd_pcm_t* capture_hand if ((error = snd_pcm_hw_params_malloc(&hw_params)) < 0) { - DEBUG_WARN("snd_pcm_hw_params_malloc (%s)", + CLOG_ERR("snd_pcm_hw_params_malloc (%s)", snd_strerror(error)); return FALSE; } @@ -206,7 +206,7 @@ static void* audin_alsa_thread_func(void* arg) { if ((error = snd_pcm_open(&capture_handle, alsa->device_name, SND_PCM_STREAM_CAPTURE, 0)) < 0) { - DEBUG_WARN("snd_pcm_open (%s)", snd_strerror(error)); + CLOG_ERR("snd_pcm_open (%s)", snd_strerror(error)); break; } @@ -226,7 +226,7 @@ static void* audin_alsa_thread_func(void* arg) } else if (error < 0) { - DEBUG_WARN("snd_pcm_readi (%s)", snd_strerror(error)); + CLOG_ERR("snd_pcm_readi (%s)", snd_strerror(error)); break; } diff --git a/channels/audin/client/audin_main.c b/channels/audin/client/audin_main.c index 38e7625bd..c2b366a4d 100644 --- a/channels/audin/client/audin_main.c +++ b/channels/audin/client/audin_main.c @@ -133,7 +133,7 @@ static int audin_process_formats(IWTSVirtualChannelCallback* pChannelCallback, w DEBUG_DVC("NumFormats %d", NumFormats); if ((NumFormats < 1) || (NumFormats > 1000)) { - DEBUG_WARN("bad NumFormats %d", NumFormats); + CLOG_ERR("bad NumFormats %d", NumFormats); return 1; } Stream_Seek_UINT32(s); /* cbSizeFormatsPacket */ @@ -262,7 +262,7 @@ static int audin_process_open(IWTSVirtualChannelCallback* pChannelCallback, wStr if (initialFormat >= (UINT32) callback->formats_count) { - DEBUG_WARN("invalid format index %d (total %d)", + CLOG_ERR("invalid format index %d (total %d)", initialFormat, callback->formats_count); return 1; } @@ -293,7 +293,7 @@ static int audin_process_format_change(IWTSVirtualChannelCallback* pChannelCallb if (NewFormat >= (UINT32) callback->formats_count) { - DEBUG_WARN("invalid format index %d (total %d)", + CLOG_ERR("invalid format index %d (total %d)", NewFormat, callback->formats_count); return 1; } @@ -340,7 +340,7 @@ static int audin_on_data_received(IWTSVirtualChannelCallback* pChannelCallback, break; default: - DEBUG_WARN("unknown MessageId=0x%x", MessageId); + CLOG_ERR("unknown MessageId=0x%x", MessageId); error = 1; break; } @@ -429,7 +429,7 @@ static void audin_register_device_plugin(IWTSPlugin* pPlugin, IAudinDevice* devi if (audin->device) { - DEBUG_WARN("existing device, abort."); + CLOG_ERR("existing device, abort."); return; } @@ -454,7 +454,7 @@ static BOOL audin_load_device_plugin(IWTSPlugin* pPlugin, const char* name, ADDI if (entry(&entryPoints) != 0) { - DEBUG_WARN("%s entry returns error.", name); + CLOG_ERR("%s entry returns error.", name); return FALSE; } @@ -613,7 +613,7 @@ int DVCPluginEntry(IDRDYNVC_ENTRY_POINTS* pEntryPoints) if (audin->device == NULL) { - DEBUG_WARN("no sound device."); + CLOG_ERR("no sound device."); } return error; diff --git a/channels/audin/client/audin_main.h b/channels/audin/client/audin_main.h index 985532b54..53c82b289 100644 --- a/channels/audin/client/audin_main.h +++ b/channels/audin/client/audin_main.h @@ -27,13 +27,13 @@ #include #include #include -#include +#include #include #ifdef WITH_DEBUG_DVC -#define DEBUG_DVC(fmt, ...) DEBUG_CLASS(DVC, fmt, ## __VA_ARGS__) +#define DEBUG_DVC(fmt, ...) CLOG_CLASS(DVC, fmt, ## __VA_ARGS__) #else -#define DEBUG_DVC(fmt, ...) DEBUG_NULL(fmt, ## __VA_ARGS__) +#define DEBUG_DVC(fmt, ...) CLOG_NULL(fmt, ## __VA_ARGS__) #endif #endif /* FREERDP_AUDIN_CLIENT_MAIN_H */ diff --git a/channels/audin/client/opensles/audin_opensl_es.c b/channels/audin/client/opensles/audin_opensl_es.c index 50dbc19d8..936e453f8 100644 --- a/channels/audin/client/opensles/audin_opensl_es.c +++ b/channels/audin/client/opensles/audin_opensl_es.c @@ -96,7 +96,7 @@ static void* audin_opensles_thread_func(void* arg) int rc = android_RecIn(opensles->stream, buffer.s, raw_size); if (rc < 0) { - DEBUG_WARN("android_RecIn %d", rc); + CLOG_ERR("android_RecIn %d", rc); continue; } @@ -250,7 +250,7 @@ static void audin_opensles_set_format(IAudinDevice* device, break; default: - DEBUG_WARN("Encoding '%d' [%08X] not supported", + CLOG_ERR("Encoding '%d' [%08X] not supported", (format->wFormatTag), format->wFormatTag); return; @@ -309,7 +309,7 @@ static void audin_opensles_close(IAudinDevice* device) * ignore duplicate requests. */ if (!opensles->stopEvent) { - DEBUG_WARN("[ERROR] function called without matching open."); + CLOG_ERR("[ERROR] function called without matching open."); return; } diff --git a/channels/audin/client/opensles/opensl_io.c b/channels/audin/client/opensles/opensl_io.c index dda834b69..970ee8265 100644 --- a/channels/audin/client/opensles/opensl_io.c +++ b/channels/audin/client/opensles/opensl_io.c @@ -362,7 +362,7 @@ int android_RecIn(OPENSL_STREAM *p,short *buffer,int size) e = Queue_Dequeue(p->queue); if (!e) { - DEBUG_WARN("[ERROR] got e=%p from queue", e); + CLOG_ERR("[ERROR] got e=%p from queue", e); return -1; } diff --git a/channels/audin/client/pulse/audin_pulse.c b/channels/audin/client/pulse/audin_pulse.c index b731c2246..6642b4701 100644 --- a/channels/audin/client/pulse/audin_pulse.c +++ b/channels/audin/client/pulse/audin_pulse.c @@ -94,7 +94,7 @@ static BOOL audin_pulse_connect(IAudinDevice* device) if (pa_context_connect(pulse->context, NULL, 0, NULL)) { - DEBUG_WARN("pa_context_connect failed (%d)", + CLOG_ERR("pa_context_connect failed (%d)", pa_context_errno(pulse->context)); return FALSE; } @@ -102,7 +102,7 @@ static BOOL audin_pulse_connect(IAudinDevice* device) if (pa_threaded_mainloop_start(pulse->mainloop) < 0) { pa_threaded_mainloop_unlock(pulse->mainloop); - DEBUG_WARN("pa_threaded_mainloop_start failed (%d)", + CLOG_ERR("pa_threaded_mainloop_start failed (%d)", pa_context_errno(pulse->context)); return FALSE; } @@ -113,7 +113,7 @@ static BOOL audin_pulse_connect(IAudinDevice* device) break; if (!PA_CONTEXT_IS_GOOD(state)) { - DEBUG_WARN("bad context state (%d)", + CLOG_ERR("bad context state (%d)", pa_context_errno(pulse->context)); break; } @@ -297,7 +297,7 @@ static void audin_pulse_stream_request_callback(pa_stream* stream, size_t length */ if (pulse->buffer == NULL) { - /* fprintf(stderr, "%s: ignoring input, pulse buffer not ready.\n", __func__); */ + /* CLOG_ERR( "%s: ignoring input, pulse buffer not ready.\n", __func__); */ return; } @@ -415,7 +415,7 @@ static void audin_pulse_open(IAudinDevice* device, AudinReceive receive, void* u &buffer_attr, PA_STREAM_ADJUST_LATENCY) < 0) { pa_threaded_mainloop_unlock(pulse->mainloop); - DEBUG_WARN("pa_stream_connect_playback failed (%d)", + CLOG_ERR("pa_stream_connect_playback failed (%d)", pa_context_errno(pulse->context)); return; } @@ -427,7 +427,7 @@ static void audin_pulse_open(IAudinDevice* device, AudinReceive receive, void* u break; if (!PA_STREAM_IS_GOOD(state)) { - DEBUG_WARN("bad stream state (%d)", + CLOG_ERR("bad stream state (%d)", pa_context_errno(pulse->context)); break; } @@ -512,7 +512,7 @@ int freerdp_audin_client_subsystem_entry(PFREERDP_AUDIN_DEVICE_ENTRY_POINTS pEnt if (!pulse->mainloop) { - DEBUG_WARN("pa_threaded_mainloop_new failed"); + CLOG_ERR("pa_threaded_mainloop_new failed"); audin_pulse_free((IAudinDevice*) pulse); return 1; } @@ -521,7 +521,7 @@ int freerdp_audin_client_subsystem_entry(PFREERDP_AUDIN_DEVICE_ENTRY_POINTS pEnt if (!pulse->context) { - DEBUG_WARN("pa_context_new failed"); + CLOG_ERR("pa_context_new failed"); audin_pulse_free((IAudinDevice*) pulse); return 1; } diff --git a/channels/audin/server/audin.c b/channels/audin/server/audin.c index 31b3943f0..67f2e4c8f 100644 --- a/channels/audin/server/audin.c +++ b/channels/audin/server/audin.c @@ -34,6 +34,7 @@ #include #include #include +#include #define MSG_SNDIN_VERSION 0x01 #define MSG_SNDIN_FORMATS 0x02 @@ -385,7 +386,7 @@ static void* audin_server_thread_func(void* arg) break; default: - fprintf(stderr, "audin_server_thread_func: unknown MessageId %d\n", MessageId); + CLOG_ERR( "audin_server_thread_func: unknown MessageId %d\n", MessageId); break; } } diff --git a/channels/cliprdr/client/cliprdr_format.c b/channels/cliprdr/client/cliprdr_format.c index 4389f5f58..1453f1cda 100644 --- a/channels/cliprdr/client/cliprdr_format.c +++ b/channels/cliprdr/client/cliprdr_format.c @@ -140,7 +140,7 @@ void cliprdr_process_short_format_names(cliprdrPlugin* cliprdr, wStream* s, UINT } if (num_formats * 36 != length) - DEBUG_WARN("dataLen %d not divided by 36!", length); + CLOG_ERR("dataLen %d not divided by 36!", length); ascii = (flags & CB_ASCII_NAMES) ? TRUE : FALSE; diff --git a/channels/cliprdr/client/cliprdr_main.c b/channels/cliprdr/client/cliprdr_main.c index 7a7907021..2c57fe2e9 100644 --- a/channels/cliprdr/client/cliprdr_main.c +++ b/channels/cliprdr/client/cliprdr_main.c @@ -36,6 +36,7 @@ #include "cliprdr_main.h" #include "cliprdr_format.h" +#ifdef WITH_DEBUG_CLIPRDR static const char* const CB_MSG_TYPE_STRINGS[] = { "", @@ -51,6 +52,7 @@ static const char* const CB_MSG_TYPE_STRINGS[] = "CB_LOCK_CLIPDATA" "CB_UNLOCK_CLIPDATA" }; +#endif CliprdrClientContext* cliprdr_get_client_interface(cliprdrPlugin* cliprdr) { @@ -85,7 +87,7 @@ void cliprdr_packet_send(cliprdrPlugin* cliprdr, wStream* s) Stream_SetPosition(s, pos); #ifdef WITH_DEBUG_CLIPRDR - printf("Cliprdr Sending (%d bytes)\n", dataLen + 8); + CLOG_DBG("Cliprdr Sending (%d bytes)\n", dataLen + 8); winpr_HexDump(Stream_Buffer(s), dataLen + 8); #endif @@ -99,18 +101,18 @@ static void cliprdr_process_connect(rdpSvcPlugin* plugin) void cliprdr_print_general_capability_flags(UINT32 flags) { - fprintf(stderr, "generalFlags (0x%08X) {\n", flags); + CLOG_ERR( "generalFlags (0x%08X) {\n", flags); if (flags & CB_USE_LONG_FORMAT_NAMES) - fprintf(stderr, "\tCB_USE_LONG_FORMAT_NAMES\n"); + CLOG_ERR( "\tCB_USE_LONG_FORMAT_NAMES\n"); if (flags & CB_STREAM_FILECLIP_ENABLED) - fprintf(stderr, "\tCB_STREAM_FILECLIP_ENABLED\n"); + CLOG_ERR( "\tCB_STREAM_FILECLIP_ENABLED\n"); if (flags & CB_FILECLIP_NO_FILE_PATHS) - fprintf(stderr, "\tCB_FILECLIP_NO_FILE_PATHS\n"); + CLOG_ERR( "\tCB_FILECLIP_NO_FILE_PATHS\n"); if (flags & CB_CAN_LOCK_CLIPDATA) - fprintf(stderr, "\tCB_CAN_LOCK_CLIPDATA\n"); + CLOG_ERR( "\tCB_CAN_LOCK_CLIPDATA\n"); - fprintf(stderr, "}\n"); + CLOG_ERR( "}\n"); } static void cliprdr_process_general_capability(cliprdrPlugin* cliprdr, wStream* s) @@ -196,7 +198,7 @@ static void cliprdr_process_clip_caps(cliprdrPlugin* cliprdr, wStream* s, UINT16 break; default: - DEBUG_WARN("unknown cliprdr capability set: %d", capabilitySetType); + CLOG_ERR("unknown cliprdr capability set: %d", capabilitySetType); break; } } @@ -378,7 +380,7 @@ static void cliprdr_process_receive(rdpSvcPlugin* plugin, wStream* s) break; default: - DEBUG_WARN("unknown msgType %d", msgType); + CLOG_ERR("unknown msgType %d", msgType); break; } } @@ -494,7 +496,7 @@ static void cliprdr_process_event(rdpSvcPlugin* plugin, wMessage* event) break; default: - DEBUG_WARN("unknown event type %d", GetMessageType(event->id)); + CLOG_ERR("unknown event type %d", GetMessageType(event->id)); break; } diff --git a/channels/cliprdr/client/cliprdr_main.h b/channels/cliprdr/client/cliprdr_main.h index 9aec3348a..29cc9b08d 100644 --- a/channels/cliprdr/client/cliprdr_main.h +++ b/channels/cliprdr/client/cliprdr_main.h @@ -23,7 +23,7 @@ #include -#include +#include #include struct cliprdr_plugin @@ -45,9 +45,9 @@ void cliprdr_packet_send(cliprdrPlugin* cliprdr, wStream* data_out); CliprdrClientContext* cliprdr_get_client_interface(cliprdrPlugin* cliprdr); #ifdef WITH_DEBUG_CLIPRDR -#define DEBUG_CLIPRDR(fmt, ...) DEBUG_CLASS(CLIPRDR, fmt, ## __VA_ARGS__) +#define DEBUG_CLIPRDR(fmt, ...) CLOG_CLASS(CLIPRDR, fmt, ## __VA_ARGS__) #else -#define DEBUG_CLIPRDR(fmt, ...) DEBUG_NULL(fmt, ## __VA_ARGS__) +#define DEBUG_CLIPRDR(fmt, ...) CLOG_NULL(fmt, ## __VA_ARGS__) #endif #endif /* __CLIPRDR_MAIN_H */ diff --git a/channels/cliprdr/server/cliprdr_main.c b/channels/cliprdr/server/cliprdr_main.c index 1a701e8a1..a72f014a4 100644 --- a/channels/cliprdr/server/cliprdr_main.c +++ b/channels/cliprdr/server/cliprdr_main.c @@ -25,6 +25,7 @@ #include #include +#include #include "cliprdr_main.h" /** @@ -70,7 +71,7 @@ static int cliprdr_server_send_capabilities(CliprdrServerContext* context) CLIPRDR_HEADER header; ULONG written; - printf("CliprdrServerSendCapabilities\n"); + CLOG_DBG("CliprdrServerSendCapabilities\n"); header.msgType = CB_CLIP_CAPS; header.msgFlags = 0; @@ -111,7 +112,7 @@ static int cliprdr_server_send_monitor_ready(CliprdrServerContext* context) CLIPRDR_HEADER header; ULONG written; - printf("CliprdrServerSendMonitorReady\n"); + CLOG_DBG("CliprdrServerSendMonitorReady\n"); header.msgType = CB_MONITOR_READY; header.msgFlags = 0; @@ -139,7 +140,7 @@ static int cliprdr_server_send_format_list_response(CliprdrServerContext* contex CLIPRDR_HEADER header; ULONG written; - printf("CliprdrServerSendFormatListResponse\n"); + CLOG_DBG("CliprdrServerSendFormatListResponse\n"); header.msgType = CB_FORMAT_LIST_RESPONSE; header.msgFlags = CB_RESPONSE_OK; @@ -207,7 +208,7 @@ static int cliprdr_server_receive_temporary_directory(CliprdrServerContext* cont ConvertFromUnicode(CP_UTF8, 0, wszTempDir, -1, &(context->priv->ClientTemporaryDirectory), 0, NULL, NULL); - printf("ClientTemporaryDirectory: %s\n", context->priv->ClientTemporaryDirectory); + CLOG_DBG("ClientTemporaryDirectory: %s\n", context->priv->ClientTemporaryDirectory); return 0; } @@ -252,7 +253,7 @@ static int cliprdr_server_receive_long_format_list(CliprdrServerContext* context int length; int position; - printf("%s\n", __FUNCTION__); + CLOG_DBG("%s\n", __FUNCTION__); position = Stream_GetPosition(s); Stream_SetPosition(s, Stream_Length(s)); @@ -305,7 +306,7 @@ static int cliprdr_server_receive_long_format_list(CliprdrServerContext* context for (i = 0; i < context->priv->ClientFormatNameCount; i++) { - printf("Format %d: Id: 0x%04X Name: %s Length: %d\n", i, + CLOG_DBG("Format %d: Id: 0x%04X Name: %s Length: %d\n", i, context->priv->ClientFormatNames[i].id, context->priv->ClientFormatNames[i].name, context->priv->ClientFormatNames[i].length); @@ -316,7 +317,7 @@ static int cliprdr_server_receive_long_format_list(CliprdrServerContext* context static int cliprdr_server_receive_short_format_list(CliprdrServerContext* context, wStream* s, CLIPRDR_HEADER* header) { - printf("%s: unimplemented\n", __FUNCTION__); + CLOG_DBG("%s: unimplemented\n", __FUNCTION__); return 0; } @@ -340,7 +341,7 @@ static int cliprdr_server_receive_format_list(CliprdrServerContext* context, wSt static int cliprdr_server_receive_pdu(CliprdrServerContext* context, wStream* s, CLIPRDR_HEADER* header) { - printf("CliprdrServerReceivePdu: msgType: %d msgFlags: 0x%08X dataLen: %d\n", + CLOG_DBG("CliprdrServerReceivePdu: msgType: %d msgFlags: 0x%08X dataLen: %d\n", header->msgType, header->msgFlags, header->dataLen); switch (header->msgType) @@ -379,7 +380,7 @@ static int cliprdr_server_receive_pdu(CliprdrServerContext* context, wStream* s, break; default: - printf("Unexpected clipboard PDU type: %d\n", header->msgType); + CLOG_DBG("Unexpected clipboard PDU type: %d\n", header->msgType); break; } diff --git a/channels/disp/client/disp_main.c b/channels/disp/client/disp_main.c index 3682449fe..283ef4b9d 100644 --- a/channels/disp/client/disp_main.c +++ b/channels/disp/client/disp_main.c @@ -101,7 +101,7 @@ int disp_send_display_control_monitor_layout_pdu(DISP_CHANNEL_CALLBACK* callback Stream_Write_UINT32(s, NumMonitors); /* NumMonitors (4 bytes) */ - //fprintf(stderr, "NumMonitors: %d\n", NumMonitors); + //CLOG_ERR( "NumMonitors: %d\n", NumMonitors); for (index = 0; index < NumMonitors; index++) { @@ -125,14 +125,14 @@ int disp_send_display_control_monitor_layout_pdu(DISP_CHANNEL_CALLBACK* callback Stream_Write_UINT32(s, Monitors[index].DeviceScaleFactor); /* DeviceScaleFactor (4 bytes) */ #if 0 - fprintf(stderr, "\t: Flags: 0x%04X\n", Monitors[index].Flags); - fprintf(stderr, "\t: Left: %d\n", Monitors[index].Left); - fprintf(stderr, "\t: Top: %d\n", Monitors[index].Top); - fprintf(stderr, "\t: Width: %d\n", Monitors[index].Width); - fprintf(stderr, "\t: Height: %d\n", Monitors[index].Height); - fprintf(stderr, "\t: PhysicalWidth: %d\n", Monitors[index].PhysicalWidth); - fprintf(stderr, "\t: PhysicalHeight: %d\n", Monitors[index].PhysicalHeight); - fprintf(stderr, "\t: Orientation: %d\n", Monitors[index].Orientation); + CLOG_ERR( "\t: Flags: 0x%04X\n", Monitors[index].Flags); + CLOG_ERR( "\t: Left: %d\n", Monitors[index].Left); + CLOG_ERR( "\t: Top: %d\n", Monitors[index].Top); + CLOG_ERR( "\t: Width: %d\n", Monitors[index].Width); + CLOG_ERR( "\t: Height: %d\n", Monitors[index].Height); + CLOG_ERR( "\t: PhysicalWidth: %d\n", Monitors[index].PhysicalWidth); + CLOG_ERR( "\t: PhysicalHeight: %d\n", Monitors[index].PhysicalHeight); + CLOG_ERR( "\t: Orientation: %d\n", Monitors[index].Orientation); #endif } @@ -158,8 +158,8 @@ int disp_recv_display_control_caps_pdu(DISP_CHANNEL_CALLBACK* callback, wStream* Stream_Read_UINT32(s, disp->MaxMonitorAreaFactorA); /* MaxMonitorAreaFactorA (4 bytes) */ Stream_Read_UINT32(s, disp->MaxMonitorAreaFactorB); /* MaxMonitorAreaFactorB (4 bytes) */ - //fprintf(stderr, "DisplayControlCapsPdu: MaxNumMonitors: %d MaxMonitorAreaFactorA: %d MaxMonitorAreaFactorB: %d\n", - // disp->MaxNumMonitors, disp->MaxMonitorAreaFactorA, disp->MaxMonitorAreaFactorB); + //CLOG_ERR( "DisplayControlCapsPdu: MaxNumMonitors: %d MaxMonitorWidth: %d MaxMonitorHeight: %d\n", + // disp->MaxNumMonitors, disp->MaxMonitorWidth, disp->MaxMonitorHeight); return 0; } @@ -175,7 +175,7 @@ int disp_recv_pdu(DISP_CHANNEL_CALLBACK* callback, wStream* s) Stream_Read_UINT32(s, type); /* Type (4 bytes) */ Stream_Read_UINT32(s, length); /* Length (4 bytes) */ - //fprintf(stderr, "Type: %d Length: %d\n", type, length); + //CLOG_ERR( "Type: %d Length: %d\n", type, length); switch (type) { diff --git a/channels/disp/client/disp_main.h b/channels/disp/client/disp_main.h index 2cb9156f8..23fdc2ce5 100644 --- a/channels/disp/client/disp_main.h +++ b/channels/disp/client/disp_main.h @@ -27,7 +27,7 @@ #include #include #include -#include +#include #include diff --git a/channels/drdynvc/client/drdynvc_main.c b/channels/drdynvc/client/drdynvc_main.c index 3cfda4d53..3b885097d 100644 --- a/channels/drdynvc/client/drdynvc_main.c +++ b/channels/drdynvc/client/drdynvc_main.c @@ -130,7 +130,7 @@ int drdynvc_write_data(drdynvcPlugin* drdynvc, UINT32 ChannelId, BYTE* data, UIN if (status != CHANNEL_RC_OK) { drdynvc->channel_error = status; - DEBUG_WARN("VirtualChannelWrite failed %d", status); + CLOG_ERR("VirtualChannelWrite failed %d", status); return 1; } @@ -145,7 +145,7 @@ int drdynvc_push_event(drdynvcPlugin* drdynvc, wMessage* event) if (status != CHANNEL_RC_OK) { - DEBUG_WARN("pVirtualChannelEventPush failed %d", status); + CLOG_ERR("pVirtualChannelEventPush failed %d", status); return 1; } @@ -165,7 +165,7 @@ static int drdynvc_send_capability_response(drdynvcPlugin* drdynvc) if (status != CHANNEL_RC_OK) { - DEBUG_WARN("VirtualChannelWrite failed %d", status); + CLOG_ERR("VirtualChannelWrite failed %d", status); return 1; } @@ -270,7 +270,7 @@ static int drdynvc_process_create_request(drdynvcPlugin* drdynvc, int Sp, int cb if (status != CHANNEL_RC_OK) { - DEBUG_WARN("VirtualChannelWrite failed %d", status); + CLOG_ERR("VirtualChannelWrite failed %d", status); return 1; } @@ -329,7 +329,7 @@ static int drdynvc_process_close_request(drdynvcPlugin* drdynvc, int Sp, int cbC if (error != CHANNEL_RC_OK) { - DEBUG_WARN("VirtualChannelWrite failed %d", error); + CLOG_ERR("VirtualChannelWrite failed %d", error); return 1; } @@ -376,7 +376,7 @@ static void drdynvc_process_receive(rdpSvcPlugin* plugin, wStream* s) break; default: - DEBUG_WARN("unknown drdynvc cmd 0x%x", Cmd); + CLOG_ERR("unknown drdynvc cmd 0x%x", Cmd); break; } } diff --git a/channels/drdynvc/client/drdynvc_types.h b/channels/drdynvc/client/drdynvc_types.h index b7b629dcc..2010cab65 100644 --- a/channels/drdynvc/client/drdynvc_types.h +++ b/channels/drdynvc/client/drdynvc_types.h @@ -26,12 +26,12 @@ #include #include -#include +#include #ifdef WITH_DEBUG_DVC -#define DEBUG_DVC(fmt, ...) DEBUG_CLASS(DVC, fmt, ## __VA_ARGS__) +#define DEBUG_DVC(fmt, ...) CLOG_CLASS(DVC, fmt, ## __VA_ARGS__) #else -#define DEBUG_DVC(fmt, ...) DEBUG_NULL(fmt, ## __VA_ARGS__) +#define DEBUG_DVC(fmt, ...) CLOG_NULL(fmt, ## __VA_ARGS__) #endif #endif diff --git a/channels/drdynvc/client/dvcman.c b/channels/drdynvc/client/dvcman.c index b8834f103..001717e14 100644 --- a/channels/drdynvc/client/dvcman.c +++ b/channels/drdynvc/client/dvcman.c @@ -71,7 +71,7 @@ static int dvcman_create_listener(IWTSVirtualChannelManager* pChannelMgr, } else { - DEBUG_WARN("Maximum DVC listener number reached."); + CLOG_ERR("Maximum DVC listener number reached."); return 1; } } @@ -89,7 +89,7 @@ static int dvcman_push_event(IWTSVirtualChannelManager* pChannelMgr, wMessage* p } else { - DEBUG_WARN("event_type %d push failed.", GetMessageType(pEvent->id)); + CLOG_ERR("event_type %d push failed.", GetMessageType(pEvent->id)); } return status; @@ -108,7 +108,7 @@ static int dvcman_register_plugin(IDRDYNVC_ENTRY_POINTS* pEntryPoints, const cha } else { - DEBUG_WARN("Maximum DVC plugin number reached."); + CLOG_ERR("Maximum DVC plugin number reached."); return 1; } } @@ -218,7 +218,7 @@ int dvcman_load_addin(IWTSVirtualChannelManager* pChannelMgr, ADDIN_ARGV* args, DVCMAN_ENTRY_POINTS entryPoints; PDVC_PLUGIN_ENTRY pDVCPluginEntry = NULL; - fprintf(stderr, "Loading Dynamic Virtual Channel %s\n", args->argv[0]); + CLOG_ERR( "Loading Dynamic Virtual Channel %s\n", args->argv[0]); pDVCPluginEntry = (PDVC_PLUGIN_ENTRY) freerdp_load_channel_addin_entry(args->argv[0], NULL, NULL, FREERDP_ADDIN_CHANNEL_DYNAMIC); @@ -388,7 +388,7 @@ int dvcman_create_channel(IWTSVirtualChannelManager* pChannelMgr, UINT32 Channel } else { - DEBUG_WARN("channel rejected by plugin"); + CLOG_ERR("channel rejected by plugin"); free(channel); return 1; @@ -409,7 +409,7 @@ int dvcman_open_channel(IWTSVirtualChannelManager* pChannelMgr, UINT32 ChannelId if (!channel) { - DEBUG_WARN("ChannelId %d not found!", ChannelId); + CLOG_ERR("ChannelId %d not found!", ChannelId); return 1; } @@ -434,7 +434,7 @@ int dvcman_close_channel(IWTSVirtualChannelManager* pChannelMgr, UINT32 ChannelI if (!channel) { - DEBUG_WARN("ChannelId %d not found!", ChannelId); + CLOG_ERR("ChannelId %d not found!", ChannelId); return 1; } @@ -468,7 +468,7 @@ int dvcman_receive_channel_data_first(IWTSVirtualChannelManager* pChannelMgr, UI if (!channel) { - DEBUG_WARN("ChannelId %d not found!", ChannelId); + CLOG_ERR("ChannelId %d not found!", ChannelId); return 1; } @@ -476,6 +476,7 @@ int dvcman_receive_channel_data_first(IWTSVirtualChannelManager* pChannelMgr, UI Stream_Release(channel->dvc_data); channel->dvc_data = StreamPool_Take(channel->dvcman->pool, length); + channel->dvc_data_length = length; return 0; } @@ -491,7 +492,7 @@ int dvcman_receive_channel_data(IWTSVirtualChannelManager* pChannelMgr, UINT32 C if (!channel) { - DEBUG_WARN("ChannelId %d not found!", ChannelId); + CLOG_ERR("ChannelId %d not found!", ChannelId); return 1; } @@ -500,7 +501,7 @@ int dvcman_receive_channel_data(IWTSVirtualChannelManager* pChannelMgr, UINT32 C /* Fragmented data */ if (Stream_GetPosition(channel->dvc_data) + dataSize > (UINT32) Stream_Length(channel->dvc_data)) { - DEBUG_WARN("data exceeding declared length!"); + CLOG_ERR("data exceeding declared length!"); Stream_Release(channel->dvc_data); channel->dvc_data = NULL; return 1; @@ -508,7 +509,7 @@ int dvcman_receive_channel_data(IWTSVirtualChannelManager* pChannelMgr, UINT32 C Stream_Write(channel->dvc_data, Stream_Pointer(data), dataSize); - if (((size_t) Stream_GetPosition(channel->dvc_data)) >= Stream_Length(channel->dvc_data)) + if (((size_t) Stream_GetPosition(channel->dvc_data)) >= channel->dvc_data_length) { Stream_SealLength(channel->dvc_data); Stream_SetPosition(channel->dvc_data, 0); diff --git a/channels/drdynvc/client/dvcman.h b/channels/drdynvc/client/dvcman.h index 04781deab..20f0edeb0 100644 --- a/channels/drdynvc/client/dvcman.h +++ b/channels/drdynvc/client/dvcman.h @@ -82,6 +82,7 @@ struct _DVCMAN_CHANNEL IWTSVirtualChannelCallback* channel_callback; wStream* dvc_data; + UINT32 dvc_data_length; CRITICAL_SECTION lock; }; typedef struct _DVCMAN_CHANNEL DVCMAN_CHANNEL; diff --git a/channels/drive/client/drive_file.c b/channels/drive/client/drive_file.c index d7b3852fc..5f3aa4718 100644 --- a/channels/drive/client/drive_file.c +++ b/channels/drive/client/drive_file.c @@ -49,7 +49,14 @@ #endif #ifdef HAVE_FCNTL_H +#define __USE_GNU /* for O_PATH */ #include +#undef __USE_GNU +#endif + +#ifdef _WIN32 +#pragma comment(lib, "Shlwapi.lib") +#include #endif #include "drive_file.h" @@ -187,6 +194,11 @@ static BOOL drive_file_init(DRIVE_FILE* file, UINT32 DesiredAccess, UINT32 Creat if (STAT(file->fullpath, &st) == 0) { file->is_dir = (S_ISDIR(st.st_mode) ? TRUE : FALSE); + if (!file->is_dir && !S_ISREG(st.st_mode)) + { + file->err = EPERM; + return TRUE; + } #ifndef WIN32 if (st.st_size > (unsigned long) 0x07FFFFFFF) largeFile = TRUE; @@ -301,6 +313,25 @@ DRIVE_FILE* drive_file_new(const char* base_path, const char* path, UINT32 id, return NULL; } +#if defined(__linux__) && defined(O_PATH) + if (file->fd < 0 && file->err == EACCES) + { + /** + * We have no access permissions for the file or directory but if the + * peer is only interested in reading the object's attributes we can try + * to obtain a file descriptor who's only purpose is to perform + * operations that act purely at the file descriptor level. + * See open(2) + **/ + { + if ((file->fd = OPEN(file->fullpath, O_PATH)) >= 0) + { + file->err = 0; + } + } + } +#endif + return file; } @@ -425,6 +456,29 @@ BOOL drive_file_query_information(DRIVE_FILE* file, UINT32 FsInformationClass, w return TRUE; } +int dir_empty(const char *path) +{ +#ifdef _WIN32 + return PathIsDirectoryEmptyA(path); +#else + struct dirent *dp; + int empty = 1; + + DIR *dir = opendir(path); + if (dir == NULL) //Not a directory or doesn't exist + return 1; + + while ((dp = readdir(dir)) != NULL) { + if (strcmp(dp->d_name, ".") == 0 || strcmp(dp->d_name, "..") == 0) + continue; /* Skip . and .. */ + + empty = 0; + break; + } + closedir(dir); + return empty; +#endif +} BOOL drive_file_set_information(DRIVE_FILE* file, UINT32 FsInformationClass, UINT32 Length, wStream* input) { char* s = NULL; @@ -433,7 +487,11 @@ BOOL drive_file_set_information(DRIVE_FILE* file, UINT32 FsInformationClass, UIN int status; char* fullpath; struct STAT st; +#if defined(__linux__) && !defined(ANDROID) + struct timespec tv[2]; +#else struct timeval tv[2]; +#endif UINT64 LastWriteTime; UINT32 FileAttributes; UINT32 FileNameLength; @@ -454,14 +512,20 @@ BOOL drive_file_set_information(DRIVE_FILE* file, UINT32 FsInformationClass, UIN return FALSE; tv[0].tv_sec = st.st_atime; - tv[0].tv_usec = 0; tv[1].tv_sec = (LastWriteTime > 0 ? FILE_TIME_RDP_TO_SYSTEM(LastWriteTime) : st.st_mtime); - tv[1].tv_usec = 0; #ifndef WIN32 /* TODO on win32 */ #ifdef ANDROID + tv[0].tv_usec = 0; + tv[1].tv_usec = 0; utimes(file->fullpath, tv); +#elif defined (__linux__) + tv[0].tv_nsec = 0; + tv[1].tv_nsec = 0; + futimens(file->fd, tv); #else + tv[0].tv_usec = 0; + tv[1].tv_usec = 0; futimes(file->fd, tv); #endif @@ -492,6 +556,9 @@ BOOL drive_file_set_information(DRIVE_FILE* file, UINT32 FsInformationClass, UIN case FileDispositionInformation: /* http://msdn.microsoft.com/en-us/library/cc232098.aspx */ /* http://msdn.microsoft.com/en-us/library/cc241371.aspx */ + if (file->is_dir && !dir_empty(file->fullpath)) + break; + if (Length) Stream_Read_UINT8(input, file->delete_pending); else diff --git a/channels/drive/client/drive_file.h b/channels/drive/client/drive_file.h index 28ac5780a..36b869c72 100644 --- a/channels/drive/client/drive_file.h +++ b/channels/drive/client/drive_file.h @@ -117,6 +117,7 @@ BOOL drive_file_query_information(DRIVE_FILE* file, UINT32 FsInformationClass, w BOOL drive_file_set_information(DRIVE_FILE* file, UINT32 FsInformationClass, UINT32 Length, wStream* input); BOOL drive_file_query_directory(DRIVE_FILE* file, UINT32 FsInformationClass, BYTE InitialQuery, const char* path, wStream* output); +int dir_empty(const char *path); extern UINT sys_code_page; diff --git a/channels/drive/client/drive_main.c b/channels/drive/client/drive_main.c index 0363b6b41..36dd232d4 100644 --- a/channels/drive/client/drive_main.c +++ b/channels/drive/client/drive_main.c @@ -346,6 +346,9 @@ static void drive_process_irp_set_information(DRIVE_DEVICE* drive, IRP* irp) } + if (file->is_dir && !dir_empty(file->fullpath)) + irp->IoStatus = STATUS_DIRECTORY_NOT_EMPTY; + Stream_Write_UINT32(irp->output, Length); irp->Complete(irp); diff --git a/channels/echo/client/echo_main.h b/channels/echo/client/echo_main.h index e63eea768..fc7d88de6 100644 --- a/channels/echo/client/echo_main.h +++ b/channels/echo/client/echo_main.h @@ -27,12 +27,12 @@ #include #include #include -#include +#include #ifdef WITH_DEBUG_DVC -#define DEBUG_DVC(fmt, ...) DEBUG_CLASS(DVC, fmt, ## __VA_ARGS__) +#define DEBUG_DVC(fmt, ...) CLOG_CLASS(DVC, fmt, ## __VA_ARGS__) #else -#define DEBUG_DVC(fmt, ...) DEBUG_NULL(fmt, ## __VA_ARGS__) +#define DEBUG_DVC(fmt, ...) CLOG_NULL(fmt, ## __VA_ARGS__) #endif #endif /* __ECHO_MAIN_H */ diff --git a/channels/echo/server/echo_main.c b/channels/echo/server/echo_main.c index 37d42cb61..979294d28 100644 --- a/channels/echo/server/echo_main.c +++ b/channels/echo/server/echo_main.c @@ -29,6 +29,7 @@ #include #include #include +#include #include @@ -166,7 +167,7 @@ static void* echo_server_thread_func(void* arg) break; } - IFCALL(echo->context.Response, &echo->context, (PCHAR) Stream_Buffer(s), BytesReturned); + IFCALL(echo->context.Response, &echo->context, (BYTE *) Stream_Buffer(s), BytesReturned); } Stream_Free(s, TRUE); diff --git a/channels/encomsp/client/CMakeLists.txt b/channels/encomsp/client/CMakeLists.txt index 7e96cbd0c..8842e5969 100644 --- a/channels/encomsp/client/CMakeLists.txt +++ b/channels/encomsp/client/CMakeLists.txt @@ -17,6 +17,8 @@ define_channel_client("encomsp") +include_directories(..) + set(${MODULE_PREFIX}_SRCS encomsp_main.c encomsp_main.h) diff --git a/channels/encomsp/client/encomsp_main.c b/channels/encomsp/client/encomsp_main.c index 1ed31296f..4752c028d 100644 --- a/channels/encomsp/client/encomsp_main.c +++ b/channels/encomsp/client/encomsp_main.c @@ -24,10 +24,50 @@ #include #include +#include #include #include "encomsp_main.h" +static int encomsp_read_header(wStream* s, ENCOMSP_ORDER_HEADER* header) +{ + if (Stream_GetRemainingLength(s) < ENCOMSP_ORDER_HEADER_SIZE) + return -1; + + Stream_Read_UINT16(s, header->Type); /* Type (2 bytes) */ + Stream_Read_UINT16(s, header->Length); /* Length (2 bytes) */ + + return 1; +} + +static int encomsp_write_header(wStream* s, ENCOMSP_ORDER_HEADER* header) +{ + Stream_Write_UINT16(s, header->Type); /* Type (2 bytes) */ + Stream_Write_UINT16(s, header->Length); /* Length (2 bytes) */ + + return 1; +} + +static int encomsp_read_unicode_string(wStream* s, ENCOMSP_UNICODE_STRING* str) +{ + ZeroMemory(str, sizeof(ENCOMSP_UNICODE_STRING)); + + if (Stream_GetRemainingLength(s) < 2) + return -1; + + Stream_Read_UINT16(s, str->cchString); /* cchString (2 bytes) */ + + if (str->cchString > 1024) + return -1; + + if (Stream_GetRemainingLength(s) < (size_t) (str->cchString * 2)) + return -1; + + Stream_Read(s, &(str->wString), (str->cchString * 2)); /* String (variable) */ + + return 1; +} + EncomspClientContext* encomsp_get_client_interface(encomspPlugin* encomsp) { EncomspClientContext* pInterface; @@ -59,46 +99,7 @@ int encomsp_virtual_channel_write(encomspPlugin* encomsp, wStream* s) return 1; } -int encomsp_read_header(wStream* s, ENCOMSP_ORDER_HEADER* header) -{ - if (Stream_GetRemainingLength(s) < ENCOMSP_ORDER_HEADER_SIZE) - return -1; - - Stream_Read_UINT16(s, header->Type); /* Type (2 bytes) */ - Stream_Read_UINT16(s, header->Length); /* Length (2 bytes) */ - - return 1; -} - -int encomsp_write_header(wStream* s, ENCOMSP_ORDER_HEADER* header) -{ - Stream_Write_UINT16(s, header->Type); /* Type (2 bytes) */ - Stream_Write_UINT16(s, header->Length); /* Length (2 bytes) */ - - return 1; -} - -int encomsp_read_unicode_string(wStream* s, ENCOMSP_UNICODE_STRING* str) -{ - ZeroMemory(str, sizeof(ENCOMSP_UNICODE_STRING)); - - if (Stream_GetRemainingLength(s) < 2) - return -1; - - Stream_Read_UINT16(s, str->cchString); /* cchString (2 bytes) */ - - if (str->cchString > 1024) - return -1; - - if (Stream_GetRemainingLength(s) < (str->cchString * 2)) - return -1; - - Stream_Read(s, &(str->wString), (str->cchString * 2)); /* String (variable) */ - - return 1; -} - -int encomsp_recv_filter_updated_pdu(encomspPlugin* encomsp, wStream* s, ENCOMSP_ORDER_HEADER* header) +static int encomsp_recv_filter_updated_pdu(encomspPlugin* encomsp, wStream* s, ENCOMSP_ORDER_HEADER* header) { int beg, end; EncomspClientContext* context; @@ -125,7 +126,7 @@ int encomsp_recv_filter_updated_pdu(encomspPlugin* encomsp, wStream* s, ENCOMSP_ if ((beg + header->Length) > end) { - if (Stream_GetRemainingLength(s) < ((beg + header->Length) - end)) + if (Stream_GetRemainingLength(s) < (size_t) ((beg + header->Length) - end)) return -1; Stream_SetPosition(s, (beg + header->Length)); @@ -139,7 +140,7 @@ int encomsp_recv_filter_updated_pdu(encomspPlugin* encomsp, wStream* s, ENCOMSP_ return 1; } -int encomsp_recv_application_created_pdu(encomspPlugin* encomsp, wStream* s, ENCOMSP_ORDER_HEADER* header) +static int encomsp_recv_application_created_pdu(encomspPlugin* encomsp, wStream* s, ENCOMSP_ORDER_HEADER* header) { int beg, end; EncomspClientContext* context; @@ -170,7 +171,7 @@ int encomsp_recv_application_created_pdu(encomspPlugin* encomsp, wStream* s, ENC if ((beg + header->Length) > end) { - if (Stream_GetRemainingLength(s) < ((beg + header->Length) - end)) + if (Stream_GetRemainingLength(s) < (size_t) ((beg + header->Length) - end)) return -1; Stream_SetPosition(s, (beg + header->Length)); @@ -184,7 +185,7 @@ int encomsp_recv_application_created_pdu(encomspPlugin* encomsp, wStream* s, ENC return 1; } -int encomsp_recv_application_removed_pdu(encomspPlugin* encomsp, wStream* s, ENCOMSP_ORDER_HEADER* header) +static int encomsp_recv_application_removed_pdu(encomspPlugin* encomsp, wStream* s, ENCOMSP_ORDER_HEADER* header) { int beg, end; EncomspClientContext* context; @@ -211,7 +212,7 @@ int encomsp_recv_application_removed_pdu(encomspPlugin* encomsp, wStream* s, ENC if ((beg + header->Length) > end) { - if (Stream_GetRemainingLength(s) < ((beg + header->Length) - end)) + if (Stream_GetRemainingLength(s) < (size_t) ((beg + header->Length) - end)) return -1; Stream_SetPosition(s, (beg + header->Length)); @@ -225,7 +226,7 @@ int encomsp_recv_application_removed_pdu(encomspPlugin* encomsp, wStream* s, ENC return 1; } -int encomsp_recv_window_created_pdu(encomspPlugin* encomsp, wStream* s, ENCOMSP_ORDER_HEADER* header) +static int encomsp_recv_window_created_pdu(encomspPlugin* encomsp, wStream* s, ENCOMSP_ORDER_HEADER* header) { int beg, end; EncomspClientContext* context; @@ -257,7 +258,7 @@ int encomsp_recv_window_created_pdu(encomspPlugin* encomsp, wStream* s, ENCOMSP_ if ((beg + header->Length) > end) { - if (Stream_GetRemainingLength(s) < ((beg + header->Length) - end)) + if (Stream_GetRemainingLength(s) < (size_t) ((beg + header->Length) - end)) return -1; Stream_SetPosition(s, (beg + header->Length)); @@ -271,7 +272,7 @@ int encomsp_recv_window_created_pdu(encomspPlugin* encomsp, wStream* s, ENCOMSP_ return 1; } -int encomsp_recv_window_removed_pdu(encomspPlugin* encomsp, wStream* s, ENCOMSP_ORDER_HEADER* header) +static int encomsp_recv_window_removed_pdu(encomspPlugin* encomsp, wStream* s, ENCOMSP_ORDER_HEADER* header) { int beg, end; EncomspClientContext* context; @@ -298,7 +299,7 @@ int encomsp_recv_window_removed_pdu(encomspPlugin* encomsp, wStream* s, ENCOMSP_ if ((beg + header->Length) > end) { - if (Stream_GetRemainingLength(s) < ((beg + header->Length) - end)) + if (Stream_GetRemainingLength(s) < (size_t) ((beg + header->Length) - end)) return -1; Stream_SetPosition(s, (beg + header->Length)); @@ -312,7 +313,7 @@ int encomsp_recv_window_removed_pdu(encomspPlugin* encomsp, wStream* s, ENCOMSP_ return 1; } -int encomsp_recv_show_window_pdu(encomspPlugin* encomsp, wStream* s, ENCOMSP_ORDER_HEADER* header) +static int encomsp_recv_show_window_pdu(encomspPlugin* encomsp, wStream* s, ENCOMSP_ORDER_HEADER* header) { int beg, end; EncomspClientContext* context; @@ -339,7 +340,7 @@ int encomsp_recv_show_window_pdu(encomspPlugin* encomsp, wStream* s, ENCOMSP_ORD if ((beg + header->Length) > end) { - if (Stream_GetRemainingLength(s) < ((beg + header->Length) - end)) + if (Stream_GetRemainingLength(s) < (size_t) ((beg + header->Length) - end)) return -1; Stream_SetPosition(s, (beg + header->Length)); @@ -353,7 +354,7 @@ int encomsp_recv_show_window_pdu(encomspPlugin* encomsp, wStream* s, ENCOMSP_ORD return 1; } -int encomsp_recv_participant_created_pdu(encomspPlugin* encomsp, wStream* s, ENCOMSP_ORDER_HEADER* header) +static int encomsp_recv_participant_created_pdu(encomspPlugin* encomsp, wStream* s, ENCOMSP_ORDER_HEADER* header) { int beg, end; EncomspClientContext* context; @@ -385,7 +386,7 @@ int encomsp_recv_participant_created_pdu(encomspPlugin* encomsp, wStream* s, ENC if ((beg + header->Length) > end) { - if (Stream_GetRemainingLength(s) < ((beg + header->Length) - end)) + if (Stream_GetRemainingLength(s) < (size_t) ((beg + header->Length) - end)) return -1; Stream_SetPosition(s, (beg + header->Length)); @@ -399,7 +400,7 @@ int encomsp_recv_participant_created_pdu(encomspPlugin* encomsp, wStream* s, ENC return 1; } -int encomsp_recv_participant_removed_pdu(encomspPlugin* encomsp, wStream* s, ENCOMSP_ORDER_HEADER* header) +static int encomsp_recv_participant_removed_pdu(encomspPlugin* encomsp, wStream* s, ENCOMSP_ORDER_HEADER* header) { int beg, end; EncomspClientContext* context; @@ -428,7 +429,7 @@ int encomsp_recv_participant_removed_pdu(encomspPlugin* encomsp, wStream* s, ENC if ((beg + header->Length) > end) { - if (Stream_GetRemainingLength(s) < ((beg + header->Length) - end)) + if (Stream_GetRemainingLength(s) < (size_t) ((beg + header->Length) - end)) return -1; Stream_SetPosition(s, (beg + header->Length)); @@ -442,7 +443,7 @@ int encomsp_recv_participant_removed_pdu(encomspPlugin* encomsp, wStream* s, ENC return 1; } -int encomsp_recv_change_participant_control_level_pdu(encomspPlugin* encomsp, wStream* s, ENCOMSP_ORDER_HEADER* header) +static int encomsp_recv_change_participant_control_level_pdu(encomspPlugin* encomsp, wStream* s, ENCOMSP_ORDER_HEADER* header) { int beg, end; EncomspClientContext* context; @@ -470,7 +471,7 @@ int encomsp_recv_change_participant_control_level_pdu(encomspPlugin* encomsp, wS if ((beg + header->Length) > end) { - if (Stream_GetRemainingLength(s) < ((beg + header->Length) - end)) + if (Stream_GetRemainingLength(s) < (size_t) ((beg + header->Length) - end)) return -1; Stream_SetPosition(s, (beg + header->Length)); @@ -484,7 +485,7 @@ int encomsp_recv_change_participant_control_level_pdu(encomspPlugin* encomsp, wS return 1; } -int encomsp_send_change_participant_control_level_pdu(EncomspClientContext* context, ENCOMSP_CHANGE_PARTICIPANT_CONTROL_LEVEL_PDU* pdu) +static int encomsp_send_change_participant_control_level_pdu(EncomspClientContext* context, ENCOMSP_CHANGE_PARTICIPANT_CONTROL_LEVEL_PDU* pdu) { wStream* s; encomspPlugin* encomsp; @@ -508,7 +509,7 @@ int encomsp_send_change_participant_control_level_pdu(EncomspClientContext* cont return 1; } -int encomsp_recv_graphics_stream_paused_pdu(encomspPlugin* encomsp, wStream* s, ENCOMSP_ORDER_HEADER* header) +static int encomsp_recv_graphics_stream_paused_pdu(encomspPlugin* encomsp, wStream* s, ENCOMSP_ORDER_HEADER* header) { int beg, end; EncomspClientContext* context; @@ -530,7 +531,7 @@ int encomsp_recv_graphics_stream_paused_pdu(encomspPlugin* encomsp, wStream* s, if ((beg + header->Length) > end) { - if (Stream_GetRemainingLength(s) < ((beg + header->Length) - end)) + if (Stream_GetRemainingLength(s) < (size_t) ((beg + header->Length) - end)) return -1; Stream_SetPosition(s, (beg + header->Length)); @@ -544,7 +545,7 @@ int encomsp_recv_graphics_stream_paused_pdu(encomspPlugin* encomsp, wStream* s, return 1; } -int encomsp_recv_graphics_stream_resumed_pdu(encomspPlugin* encomsp, wStream* s, ENCOMSP_ORDER_HEADER* header) +static int encomsp_recv_graphics_stream_resumed_pdu(encomspPlugin* encomsp, wStream* s, ENCOMSP_ORDER_HEADER* header) { int beg, end; EncomspClientContext* context; @@ -566,7 +567,7 @@ int encomsp_recv_graphics_stream_resumed_pdu(encomspPlugin* encomsp, wStream* s, if ((beg + header->Length) > end) { - if (Stream_GetRemainingLength(s) < ((beg + header->Length) - end)) + if (Stream_GetRemainingLength(s) < (size_t) ((beg + header->Length) - end)) return -1; Stream_SetPosition(s, (beg + header->Length)); @@ -590,7 +591,7 @@ static int encomsp_process_receive(encomspPlugin* encomsp, wStream* s) if (encomsp_read_header(s, &header) < 0) return -1; - //printf("EncomspReceive: Type: %d Length: %d\n", header.Type, header.Length); + //CLOG_DBG("EncomspReceive: Type: %d Length: %d\n", header.Type, header.Length); switch (header.Type) { @@ -722,7 +723,7 @@ int encomsp_send(encomspPlugin* encomsp, wStream* s) if (status != CHANNEL_RC_OK) { Stream_Free(s, TRUE); - fprintf(stderr, "encomsp_send: VirtualChannelWrite failed %d\n", status); + CLOG_ERR( "encomsp_send: VirtualChannelWrite failed %d\n", status); } return status; @@ -754,7 +755,7 @@ static void encomsp_virtual_channel_event_data_received(encomspPlugin* encomsp, { if (Stream_Capacity(data_in) != Stream_GetPosition(data_in)) { - fprintf(stderr, "encomsp_plugin_process_received: read error\n"); + CLOG_ERR( "encomsp_plugin_process_received: read error\n"); } encomsp->data_in = NULL; @@ -774,7 +775,7 @@ static VOID VCAPITYPE encomsp_virtual_channel_open_event(DWORD openHandle, UINT if (!encomsp) { - fprintf(stderr, "encomsp_virtual_channel_open_event: error no match\n"); + CLOG_ERR( "encomsp_virtual_channel_open_event: error no match\n"); return; } @@ -834,7 +835,7 @@ static void encomsp_virtual_channel_event_connected(encomspPlugin* encomsp, LPVO if (status != CHANNEL_RC_OK) { - fprintf(stderr, "encomsp_virtual_channel_event_connected: open failed: status: %d\n", status); + CLOG_ERR( "encomsp_virtual_channel_event_connected: open failed: status: %d\n", status); return; } @@ -872,7 +873,7 @@ static VOID VCAPITYPE encomsp_virtual_channel_init_event(LPVOID pInitHandle, UIN if (!encomsp) { - fprintf(stderr, "encomsp_virtual_channel_init_event: error no match\n"); + CLOG_ERR( "encomsp_virtual_channel_init_event: error no match\n"); return; } diff --git a/channels/encomsp/server/CMakeLists.txt b/channels/encomsp/server/CMakeLists.txt index 90c4e8f31..4cb47966e 100644 --- a/channels/encomsp/server/CMakeLists.txt +++ b/channels/encomsp/server/CMakeLists.txt @@ -17,6 +17,8 @@ define_channel_server("encomsp") +include_directories(..) + set(${MODULE_PREFIX}_SRCS encomsp_main.c encomsp_main.h) diff --git a/channels/encomsp/server/encomsp_main.c b/channels/encomsp/server/encomsp_main.c index 5f2ef2c71..18e8c44bf 100644 --- a/channels/encomsp/server/encomsp_main.c +++ b/channels/encomsp/server/encomsp_main.c @@ -27,9 +27,113 @@ #include "encomsp_main.h" +static int encomsp_read_header(wStream* s, ENCOMSP_ORDER_HEADER* header) +{ + if (Stream_GetRemainingLength(s) < ENCOMSP_ORDER_HEADER_SIZE) + return -1; + + Stream_Read_UINT16(s, header->Type); /* Type (2 bytes) */ + Stream_Read_UINT16(s, header->Length); /* Length (2 bytes) */ + + return 1; +} + +#if 0 + +static int encomsp_write_header(wStream* s, ENCOMSP_ORDER_HEADER* header) +{ + Stream_Write_UINT16(s, header->Type); /* Type (2 bytes) */ + Stream_Write_UINT16(s, header->Length); /* Length (2 bytes) */ + + return 1; +} + +static int encomsp_read_unicode_string(wStream* s, ENCOMSP_UNICODE_STRING* str) +{ + ZeroMemory(str, sizeof(ENCOMSP_UNICODE_STRING)); + + if (Stream_GetRemainingLength(s) < 2) + return -1; + + Stream_Read_UINT16(s, str->cchString); /* cchString (2 bytes) */ + + if (str->cchString > 1024) + return -1; + + if (Stream_GetRemainingLength(s) < (str->cchString * 2)) + return -1; + + Stream_Read(s, &(str->wString), (str->cchString * 2)); /* String (variable) */ + + return 1; +} + +#endif + +static int encomsp_recv_change_participant_control_level_pdu(EncomspServerContext* context, wStream* s, ENCOMSP_ORDER_HEADER* header) +{ + int beg, end; + ENCOMSP_CHANGE_PARTICIPANT_CONTROL_LEVEL_PDU pdu; + + beg = ((int) Stream_GetPosition(s)) - ENCOMSP_ORDER_HEADER_SIZE; + + CopyMemory(&pdu, header, sizeof(ENCOMSP_ORDER_HEADER)); + + if (Stream_GetRemainingLength(s) < 6) + return -1; + + Stream_Read_UINT16(s, pdu.Flags); /* Flags (2 bytes) */ + Stream_Read_UINT32(s, pdu.ParticipantId); /* ParticipantId (4 bytes) */ + + end = (int) Stream_GetPosition(s); + + if ((beg + header->Length) < end) + return -1; + + if ((beg + header->Length) > end) + { + if (Stream_GetRemainingLength(s) < ((beg + header->Length) - end)) + return -1; + + Stream_SetPosition(s, (beg + header->Length)); + } + + if (context->ChangeParticipantControlLevel) + { + return context->ChangeParticipantControlLevel(context, &pdu); + } + + return 1; +} + static int encomsp_server_receive_pdu(EncomspServerContext* context, wStream* s) { - return 0; + int status = 1; + ENCOMSP_ORDER_HEADER header; + + while (Stream_GetRemainingLength(s) > 0) + { + if (encomsp_read_header(s, &header) < 0) + return -1; + + printf("EncomspReceive: Type: %d Length: %d\n", header.Type, header.Length); + + switch (header.Type) + { + case ODTYPE_PARTICIPANT_CTRL_CHANGED: + status = encomsp_recv_change_participant_control_level_pdu(context, s, &header); + break; + + default: + status = -1; + break; + } + + if (status < 0) + return -1; + } + + return status; } static void* encomsp_server_thread(void* arg) @@ -41,6 +145,7 @@ static void* encomsp_server_thread(void* arg) HANDLE events[8]; HANDLE ChannelEvent; DWORD BytesReturned; + ENCOMSP_ORDER_HEADER* header; EncomspServerContext* context; context = (EncomspServerContext*) arg; @@ -82,9 +187,17 @@ static void* encomsp_server_thread(void* arg) break; } - if (0) + if (Stream_GetPosition(s) >= ENCOMSP_ORDER_HEADER_SIZE) { - encomsp_server_receive_pdu(context, s); + header = (ENCOMSP_ORDER_HEADER*) Stream_Buffer(s); + + if (header->Length >= Stream_GetPosition(s)) + { + Stream_SealLength(s); + Stream_SetPosition(s, 0); + encomsp_server_receive_pdu(context, s); + Stream_SetPosition(s, 0); + } } } diff --git a/channels/printer/client/printer_win.h b/channels/printer/client/printer_win.h index eecbb17ba..68c9e7995 100644 --- a/channels/printer/client/printer_win.h +++ b/channels/printer/client/printer_win.h @@ -23,9 +23,9 @@ rdpPrinterDriver* printer_win_get_driver(void); #ifdef WITH_DEBUG_WINPR -#define DEBUG_WINPR(fmt, ...) DEBUG_CLASS(WINPR, fmt, ## __VA_ARGS__) +#define DEBUG_WINPR(fmt, ...) CLOG_CLASS(WINPR, fmt, ## __VA_ARGS__) #else -#define DEBUG_WINPR(fmt, ...) DEBUG_NULL(fmt, ## __VA_ARGS__) +#define DEBUG_WINPR(fmt, ...) CLOG_NULL(fmt, ## __VA_ARGS__) #endif #endif diff --git a/channels/rail/client/rail_orders.c b/channels/rail/client/rail_orders.c index 3096f543b..6e5e0428c 100644 --- a/channels/rail/client/rail_orders.c +++ b/channels/rail/client/rail_orders.c @@ -28,6 +28,7 @@ #include #include +#include #include "rail_orders.h" @@ -522,7 +523,7 @@ BOOL rail_order_recv(railPlugin* rail, wStream* s) } default: - fprintf(stderr, "Unknown RAIL PDU order reveived."); + CLOG_ERR( "Unknown RAIL PDU order reveived."); break; } diff --git a/channels/rdpdr/client/devman.c b/channels/rdpdr/client/devman.c index 75778fe01..784117499 100644 --- a/channels/rdpdr/client/devman.c +++ b/channels/rdpdr/client/devman.c @@ -32,6 +32,7 @@ #include #include #include +#include #include "rdpdr_main.h" @@ -122,7 +123,7 @@ BOOL devman_load_device_service(DEVMAN* devman, RDPDR_DEVICE* device) if (!ServiceName) return FALSE; - fprintf(stderr, "Loading device service %s (static)\n", ServiceName); + CLOG_ERR( "Loading device service %s (static)\n", ServiceName); entry = (PDEVICE_SERVICE_ENTRY) freerdp_load_channel_addin_entry(ServiceName, NULL, "DeviceServiceEntry", 0); if (!entry) diff --git a/channels/rdpdr/client/rdpdr_main.c b/channels/rdpdr/client/rdpdr_main.c index c1b4975c2..4d053c14e 100644 --- a/channels/rdpdr/client/rdpdr_main.c +++ b/channels/rdpdr/client/rdpdr_main.c @@ -31,6 +31,7 @@ #include #include +#include #include #ifdef _WIN32 @@ -451,7 +452,7 @@ static void* drive_hotplug_thread_func(void* arg) if (mfd < 0) { - fprintf(stderr, "ERROR: Unable to open /proc/mounts."); + CLOG_ERR( "ERROR: Unable to open /proc/mounts."); return NULL; } @@ -662,7 +663,7 @@ static void rdpdr_send_device_list_announce_request(rdpdrPlugin* rdpdr, BOOL use count++; - fprintf(stderr, "registered device #%d: %s (type=%d id=%d)\n", + CLOG_ERR( "registered device #%d: %s (type=%d id=%d)\n", count, device->name, device->type, device->id); } } @@ -845,7 +846,7 @@ int rdpdr_send(rdpdrPlugin* rdpdr, wStream* s) if (status != CHANNEL_RC_OK) { Stream_Free(s, TRUE); - fprintf(stderr, "rdpdr_send: VirtualChannelWrite failed %d\n", status); + CLOG_ERR( "rdpdr_send: VirtualChannelWrite failed %d\n", status); } return status; @@ -883,7 +884,7 @@ static void rdpdr_virtual_channel_event_data_received(rdpdrPlugin* rdpdr, { if (Stream_Capacity(data_in) != Stream_GetPosition(data_in)) { - fprintf(stderr, "svc_plugin_process_received: read error\n"); + CLOG_ERR( "svc_plugin_process_received: read error\n"); } rdpdr->data_in = NULL; @@ -903,7 +904,7 @@ static VOID VCAPITYPE rdpdr_virtual_channel_open_event(DWORD openHandle, UINT ev if (!rdpdr) { - fprintf(stderr, "rdpdr_virtual_channel_open_event: error no match\n"); + CLOG_ERR( "rdpdr_virtual_channel_open_event: error no match\n"); return; } @@ -963,7 +964,7 @@ static void rdpdr_virtual_channel_event_connected(rdpdrPlugin* rdpdr, LPVOID pDa if (status != CHANNEL_RC_OK) { - fprintf(stderr, "rdpdr_virtual_channel_event_connected: open failed: status: %d\n", status); + CLOG_ERR( "rdpdr_virtual_channel_event_connected: open failed: status: %d\n", status); return; } @@ -1009,7 +1010,7 @@ static VOID VCAPITYPE rdpdr_virtual_channel_init_event(LPVOID pInitHandle, UINT if (!rdpdr) { - fprintf(stderr, "rdpdr_virtual_channel_init_event: error no match\n"); + CLOG_ERR( "rdpdr_virtual_channel_init_event: error no match\n"); return; } diff --git a/channels/rdpdr/server/rdpdr_main.c b/channels/rdpdr/server/rdpdr_main.c index 09d768413..a3333eb42 100644 --- a/channels/rdpdr/server/rdpdr_main.c +++ b/channels/rdpdr/server/rdpdr_main.c @@ -25,6 +25,7 @@ #include #include +#include #include "rdpdr_main.h" static UINT32 g_ClientId = 0; @@ -36,7 +37,7 @@ static int rdpdr_server_send_announce_request(RdpdrServerContext* context) RDPDR_HEADER header; ULONG written; - printf("RdpdrServerSendAnnounceRequest\n"); + CLOG_DBG("RdpdrServerSendAnnounceRequest\n"); header.Component = RDPDR_CTYP_CORE; header.PacketId = PAKID_CORE_SERVER_ANNOUNCE; @@ -69,7 +70,7 @@ static int rdpdr_server_receive_announce_response(RdpdrServerContext* context, w Stream_Read_UINT16(s, VersionMinor); /* VersionMinor (2 bytes) */ Stream_Read_UINT32(s, ClientId); /* ClientId (4 bytes) */ - printf("Client Announce Response: VersionMajor: 0x%04X VersionMinor: 0x%04X ClientId: 0x%04X\n", + CLOG_DBG("Client Announce Response: VersionMajor: 0x%04X VersionMinor: 0x%04X ClientId: 0x%04X\n", VersionMajor, VersionMinor, ClientId); context->priv->ClientId = ClientId; @@ -109,7 +110,7 @@ static int rdpdr_server_receive_client_name_request(RdpdrServerContext* context, Stream_Seek(s, ComputerNameLen); - printf("ClientComputerName: %s\n", context->priv->ClientComputerName); + CLOG_DBG("ClientComputerName: %s\n", context->priv->ClientComputerName); return 0; } @@ -298,7 +299,7 @@ static int rdpdr_server_send_core_capability_request(RdpdrServerContext* context UINT16 numCapabilities; ULONG written; - printf("RdpdrServerSendCoreCapabilityRequest\n"); + CLOG_DBG("RdpdrServerSendCoreCapabilityRequest\n"); header.Component = RDPDR_CTYP_CORE; header.PacketId = PAKID_CORE_SERVER_CAPABILITY; @@ -364,7 +365,7 @@ static int rdpdr_server_receive_core_capability_response(RdpdrServerContext* con break; default: - printf("Unknown capabilityType %d\n", capabilityHeader.CapabilityType); + CLOG_DBG("Unknown capabilityType %d\n", capabilityHeader.CapabilityType); Stream_Seek(s, capabilityHeader.CapabilityLength - RDPDR_CAPABILITY_HEADER_LENGTH); break; } @@ -380,7 +381,7 @@ static int rdpdr_server_send_client_id_confirm(RdpdrServerContext* context) RDPDR_HEADER header; ULONG written; - printf("RdpdrServerSendClientIdConfirm\n"); + CLOG_DBG("RdpdrServerSendClientIdConfirm\n"); header.Component = RDPDR_CTYP_CORE; header.PacketId = PAKID_CORE_CLIENTID_CONFIRM; @@ -416,7 +417,7 @@ static int rdpdr_server_receive_device_list_announce_request(RdpdrServerContext* Stream_Read_UINT32(s, DeviceCount); /* DeviceCount (4 bytes) */ - printf("%s: DeviceCount: %d\n", __FUNCTION__, DeviceCount); + CLOG_DBG("%s: DeviceCount: %d\n", __FUNCTION__, DeviceCount); for (i = 0; i < DeviceCount; i++) { @@ -425,7 +426,7 @@ static int rdpdr_server_receive_device_list_announce_request(RdpdrServerContext* Stream_Read(s, PreferredDosName, 8); /* PreferredDosName (8 bytes) */ Stream_Read_UINT32(s, DeviceDataLength); /* DeviceDataLength (4 bytes) */ - printf("Device %d Name: %s Id: 0x%04X DataLength: %d\n", + CLOG_DBG("Device %d Name: %s Id: 0x%04X DataLength: %d\n", i, PreferredDosName, DeviceId, DeviceDataLength); switch (DeviceId) @@ -462,7 +463,7 @@ static int rdpdr_server_send_user_logged_on(RdpdrServerContext* context) RDPDR_HEADER header; ULONG written; - printf("%s\n", __FUNCTION__); + CLOG_DBG("%s\n", __FUNCTION__); header.Component = RDPDR_CTYP_CORE; header.PacketId = PAKID_CORE_USER_LOGGEDON; @@ -483,7 +484,7 @@ static int rdpdr_server_send_user_logged_on(RdpdrServerContext* context) static int rdpdr_server_receive_pdu(RdpdrServerContext* context, wStream* s, RDPDR_HEADER* header) { - printf("RdpdrServerReceivePdu: Component: 0x%04X PacketId: 0x%04X\n", + CLOG_DBG("RdpdrServerReceivePdu: Component: 0x%04X PacketId: 0x%04X\n", header->Component, header->PacketId); winpr_HexDump(Stream_Buffer(s), Stream_Length(s)); @@ -545,7 +546,7 @@ static int rdpdr_server_receive_pdu(RdpdrServerContext* context, wStream* s, RDP } else { - printf("Unknown RDPDR_HEADER.Component: 0x%04X\n", header->Component); + CLOG_DBG("Unknown RDPDR_HEADER.Component: 0x%04X\n", header->Component); return -1; } diff --git a/channels/rdpei/client/rdpei_main.c b/channels/rdpei/client/rdpei_main.c index cd837669f..46729f028 100644 --- a/channels/rdpei/client/rdpei_main.c +++ b/channels/rdpei/client/rdpei_main.c @@ -201,7 +201,7 @@ int rdpei_send_pdu(RDPEI_CHANNEL_CALLBACK* callback, wStream* s, UINT16 eventId, status = callback->channel->Write(callback->channel, (UINT32) Stream_Length(s), Stream_Buffer(s), NULL); #ifdef WITH_DEBUG_RDPEI - fprintf(stderr, "rdpei_send_pdu: eventId: %d (%s) length: %d status: %d\n", + CLOG_ERR( "rdpei_send_pdu: eventId: %d (%s) length: %d status: %d\n", eventId, RDPEI_EVENTID_STRINGS[eventId], pduLength, status); #endif @@ -239,17 +239,17 @@ int rdpei_send_cs_ready_pdu(RDPEI_CHANNEL_CALLBACK* callback) void rdpei_print_contact_flags(UINT32 contactFlags) { if (contactFlags & CONTACT_FLAG_DOWN) - printf(" CONTACT_FLAG_DOWN"); + CLOG_DBG(" CONTACT_FLAG_DOWN"); if (contactFlags & CONTACT_FLAG_UPDATE) - printf(" CONTACT_FLAG_UPDATE"); + CLOG_DBG(" CONTACT_FLAG_UPDATE"); if (contactFlags & CONTACT_FLAG_UP) - printf(" CONTACT_FLAG_UP"); + CLOG_DBG(" CONTACT_FLAG_UP"); if (contactFlags & CONTACT_FLAG_INRANGE) - printf(" CONTACT_FLAG_INRANGE"); + CLOG_DBG(" CONTACT_FLAG_INRANGE"); if (contactFlags & CONTACT_FLAG_INCONTACT) - printf(" CONTACT_FLAG_INCONTACT"); + CLOG_DBG(" CONTACT_FLAG_INCONTACT"); if (contactFlags & CONTACT_FLAG_CANCELED) - printf(" CONTACT_FLAG_CANCELED"); + CLOG_DBG(" CONTACT_FLAG_CANCELED"); } int rdpei_write_touch_frame(wStream* s, RDPINPUT_TOUCH_FRAME* frame) @@ -259,8 +259,8 @@ int rdpei_write_touch_frame(wStream* s, RDPINPUT_TOUCH_FRAME* frame) RDPINPUT_CONTACT_DATA* contact; #ifdef WITH_DEBUG_RDPEI - printf("contactCount: %d\n", frame->contactCount); - printf("frameOffset: 0x%08X\n", (UINT32) frame->frameOffset); + CLOG_DBG("contactCount: %d\n", frame->contactCount); + CLOG_DBG("frameOffset: 0x%08X\n", (UINT32) frame->frameOffset); #endif rdpei_write_2byte_unsigned(s, frame->contactCount); /* contactCount (TWO_BYTE_UNSIGNED_INTEGER) */ @@ -284,13 +284,13 @@ int rdpei_write_touch_frame(wStream* s, RDPINPUT_TOUCH_FRAME* frame) contact->contactRectBottom = contact->y + rectSize; #ifdef WITH_DEBUG_RDPEI - printf("contact[%d].contactId: %d\n", index, contact->contactId); - printf("contact[%d].fieldsPresent: %d\n", index, contact->fieldsPresent); - printf("contact[%d].x: %d\n", index, contact->x); - printf("contact[%d].y: %d\n", index, contact->y); - printf("contact[%d].contactFlags: 0x%04X", index, contact->contactFlags); + CLOG_DBG("contact[%d].contactId: %d\n", index, contact->contactId); + CLOG_DBG("contact[%d].fieldsPresent: %d\n", index, contact->fieldsPresent); + CLOG_DBG("contact[%d].x: %d\n", index, contact->x); + CLOG_DBG("contact[%d].y: %d\n", index, contact->y); + CLOG_DBG("contact[%d].contactFlags: 0x%04X", index, contact->contactFlags); rdpei_print_contact_flags(contact->contactFlags); - printf("\n"); + CLOG_DBG("\n"); #endif Stream_Write_UINT8(s, contact->contactId); /* contactId (1 byte) */ @@ -371,7 +371,7 @@ int rdpei_recv_sc_ready_pdu(RDPEI_CHANNEL_CALLBACK* callback, wStream* s) #if 0 if (protocolVersion != RDPINPUT_PROTOCOL_V10) { - fprintf(stderr, "Unknown [MS-RDPEI] protocolVersion: 0x%08X\n", protocolVersion); + CLOG_ERR( "Unknown [MS-RDPEI] protocolVersion: 0x%08X\n", protocolVersion); return -1; } #endif @@ -408,7 +408,7 @@ int rdpei_recv_pdu(RDPEI_CHANNEL_CALLBACK* callback, wStream* s) Stream_Read_UINT32(s, pduLength); /* pduLength (4 bytes) */ #ifdef WITH_DEBUG_RDPEI - fprintf(stderr, "rdpei_recv_pdu: eventId: %d (%s) length: %d\n", + CLOG_ERR( "rdpei_recv_pdu: eventId: %d (%s) length: %d\n", eventId, RDPEI_EVENTID_STRINGS[eventId], pduLength); #endif diff --git a/channels/rdpei/client/rdpei_main.h b/channels/rdpei/client/rdpei_main.h index cf4dccee0..509517bb6 100644 --- a/channels/rdpei/client/rdpei_main.h +++ b/channels/rdpei/client/rdpei_main.h @@ -27,7 +27,7 @@ #include #include #include -#include +#include #include @@ -100,9 +100,9 @@ struct _RDPINPUT_CONTACT_POINT typedef struct _RDPINPUT_CONTACT_POINT RDPINPUT_CONTACT_POINT; #ifdef WITH_DEBUG_DVC -#define DEBUG_DVC(fmt, ...) DEBUG_CLASS(DVC, fmt, ## __VA_ARGS__) +#define DEBUG_DVC(fmt, ...) CLOG_CLASS(DVC, fmt, ## __VA_ARGS__) #else -#define DEBUG_DVC(fmt, ...) DEBUG_NULL(fmt, ## __VA_ARGS__) +#define DEBUG_DVC(fmt, ...) CLOG_NULL(fmt, ## __VA_ARGS__) #endif #endif /* FREERDP_CHANNEL_RDPEI_CLIENT_MAIN_H */ diff --git a/channels/rdpgfx/client/rdpgfx_main.c b/channels/rdpgfx/client/rdpgfx_main.c index 970640612..3b75fa789 100644 --- a/channels/rdpgfx/client/rdpgfx_main.c +++ b/channels/rdpgfx/client/rdpgfx_main.c @@ -37,6 +37,7 @@ #include #include +#include #include "rdpgfx_common.h" #include "rdpgfx_codec.h" @@ -204,7 +205,7 @@ int rdpgfx_recv_reset_graphics_pdu(RDPGFX_CHANNEL_CALLBACK* callback, wStream* s pad = 340 - (RDPGFX_HEADER_SIZE + 12 + (pdu.monitorCount * 20)); - if (Stream_GetRemainingLength(s) < pad) + if (Stream_GetRemainingLength(s) < (size_t) pad) return -1; Stream_Seek(s, pad); /* pad (total size is 340 bytes) */ @@ -255,7 +256,7 @@ int rdpgfx_recv_cache_import_reply_pdu(RDPGFX_CHANNEL_CALLBACK* callback, wStrea Stream_Read_UINT16(s, pdu.importedEntriesCount); /* cacheSlot (2 bytes) */ - if (Stream_GetRemainingLength(s) < (pdu.importedEntriesCount * 2)) + if (Stream_GetRemainingLength(s) < (size_t) (pdu.importedEntriesCount * 2)) return -1; pdu.cacheSlots = (UINT16*) calloc(pdu.importedEntriesCount, sizeof(UINT16)); @@ -526,7 +527,7 @@ int rdpgfx_recv_solid_fill_pdu(RDPGFX_CHANNEL_CALLBACK* callback, wStream* s) rdpgfx_read_color32(s, &(pdu.fillPixel)); /* fillPixel (4 bytes) */ Stream_Read_UINT16(s, pdu.fillRectCount); /* fillRectCount (2 bytes) */ - if (Stream_GetRemainingLength(s) < (pdu.fillRectCount * 8)) + if (Stream_GetRemainingLength(s) < (size_t) (pdu.fillRectCount * 8)) return -1; pdu.fillRects = (RDPGFX_RECT16*) calloc(pdu.fillRectCount, sizeof(RDPGFX_RECT16)); @@ -569,7 +570,7 @@ int rdpgfx_recv_surface_to_surface_pdu(RDPGFX_CHANNEL_CALLBACK* callback, wStrea rdpgfx_read_rect16(s, &(pdu.rectSrc)); /* rectSrc (8 bytes ) */ Stream_Read_UINT16(s, pdu.destPtsCount); /* destPtsCount (2 bytes) */ - if (Stream_GetRemainingLength(s) < (pdu.destPtsCount * 4)) + if (Stream_GetRemainingLength(s) < (size_t) (pdu.destPtsCount * 4)) return -1; pdu.destPts = (RDPGFX_POINT16*) calloc(pdu.destPtsCount, sizeof(RDPGFX_POINT16)); @@ -642,7 +643,7 @@ int rdpgfx_recv_cache_to_surface_pdu(RDPGFX_CHANNEL_CALLBACK* callback, wStream* Stream_Read_UINT16(s, pdu.surfaceId); /* surfaceId (2 bytes) */ Stream_Read_UINT16(s, pdu.destPtsCount); /* destPtsCount (2 bytes) */ - if (Stream_GetRemainingLength(s) < (pdu.destPtsCount * 4)) + if (Stream_GetRemainingLength(s) < (size_t) (pdu.destPtsCount * 4)) return -1; pdu.destPts = (RDPGFX_POINT16*) calloc(pdu.destPtsCount, sizeof(RDPGFX_POINT16)); @@ -815,7 +816,7 @@ int rdpgfx_recv_pdu(RDPGFX_CHANNEL_CALLBACK* callback, wStream* s) if (status < 0) { - fprintf(stderr, "Error while parsing GFX cmdId: %s (0x%04X)\n", + CLOG_ERR( "Error while parsing GFX cmdId: %s (0x%04X)\n", rdpgfx_get_cmd_id_string(header.cmdId), header.cmdId); return -1; } @@ -824,7 +825,7 @@ int rdpgfx_recv_pdu(RDPGFX_CHANNEL_CALLBACK* callback, wStream* s) if (end != (beg + header.pduLength)) { - fprintf(stderr, "Unexpected gfx pdu end: Actual: %d, Expected: %d\n", + CLOG_ERR( "Unexpected gfx pdu end: Actual: %d, Expected: %d\n", end, (beg + header.pduLength)); Stream_SetPosition(s, (beg + header.pduLength)); @@ -846,13 +847,13 @@ static int rdpgfx_on_data_received(IWTSVirtualChannelCallback* pChannelCallback, if (status < 0) { - printf("zgfx_decompress failure! status: %d\n", status); + CLOG_DBG("zgfx_decompress failure! status: %d\n", status); return 0; } s = Stream_New(pDstData, DstSize); - while (Stream_GetPosition(s) < Stream_Length(s)) + while (((size_t) Stream_GetPosition(s)) < Stream_Length(s)) { status = rdpgfx_recv_pdu(callback, s); diff --git a/channels/rdpsnd/client/alsa/rdpsnd_alsa.c b/channels/rdpsnd/client/alsa/rdpsnd_alsa.c index 0edc08d93..70ad41c76 100644 --- a/channels/rdpsnd/client/alsa/rdpsnd_alsa.c +++ b/channels/rdpsnd/client/alsa/rdpsnd_alsa.c @@ -35,7 +35,7 @@ #include #include -#include +#include #include "rdpsnd_main.h" @@ -68,7 +68,7 @@ struct rdpsnd_alsa_plugin #define SND_PCM_CHECK(_func, _status) \ if (_status < 0) \ { \ - fprintf(stderr, "%s: %d\n", _func, _status); \ + CLOG_ERR( "%s: %d\n", _func, _status); \ return -1; \ } @@ -106,7 +106,7 @@ static int rdpsnd_alsa_set_hw_params(rdpsndAlsaPlugin* alsa) if (alsa->buffer_size > buffer_size_max) { - fprintf(stderr, "Warning: requested sound buffer size %d, got %d instead\n", + CLOG_ERR( "Warning: requested sound buffer size %d, got %d instead\n", (int) alsa->buffer_size, (int) buffer_size_max); alsa->buffer_size = buffer_size_max; } @@ -262,7 +262,7 @@ static void rdpsnd_alsa_open_mixer(rdpsndAlsaPlugin* alsa) if (status < 0) { - DEBUG_WARN("snd_mixer_open failed"); + CLOG_ERR("snd_mixer_open failed"); return; } @@ -270,7 +270,7 @@ static void rdpsnd_alsa_open_mixer(rdpsndAlsaPlugin* alsa) if (status < 0) { - DEBUG_WARN("snd_mixer_attach failed"); + CLOG_ERR("snd_mixer_attach failed"); snd_mixer_close(alsa->mixer_handle); return; } @@ -279,7 +279,7 @@ static void rdpsnd_alsa_open_mixer(rdpsndAlsaPlugin* alsa) if (status < 0) { - DEBUG_WARN("snd_mixer_selem_register failed"); + CLOG_ERR("snd_mixer_selem_register failed"); snd_mixer_close(alsa->mixer_handle); return; } @@ -288,7 +288,7 @@ static void rdpsnd_alsa_open_mixer(rdpsndAlsaPlugin* alsa) if (status < 0) { - DEBUG_WARN("snd_mixer_load failed"); + CLOG_ERR("snd_mixer_load failed"); snd_mixer_close(alsa->mixer_handle); return; } @@ -310,7 +310,7 @@ static void rdpsnd_alsa_open(rdpsndDevicePlugin* device, AUDIO_FORMAT* format, i if (status < 0) { - DEBUG_WARN("snd_pcm_open failed"); + CLOG_ERR("snd_pcm_open failed"); } else { @@ -579,7 +579,7 @@ static void rdpsnd_alsa_wave_play(rdpsndDevicePlugin* device, RDPSND_WAVE* wave) } else if (status < 0) { - fprintf(stderr, "status: %d\n", status); + CLOG_ERR( "status: %d\n", status); snd_pcm_close(alsa->pcm_handle); alsa->pcm_handle = NULL; rdpsnd_alsa_open((rdpsndDevicePlugin*) alsa, NULL, alsa->latency); @@ -600,7 +600,7 @@ static void rdpsnd_alsa_wave_play(rdpsndDevicePlugin* device, RDPSND_WAVE* wave) wave->wLatency = (UINT16) (wave->wLocalTimeB - wave->wLocalTimeA); wave->wTimeStampB = wave->wTimeStampA + wave->wLatency; - //fprintf(stderr, "wTimeStampA: %d wTimeStampB: %d wLatency: %d\n", wave->wTimeStampA, wave->wTimeStampB, wave->wLatency); + //CLOG_ERR( "wTimeStampA: %d wTimeStampB: %d wLatency: %d\n", wave->wTimeStampA, wave->wTimeStampB, wave->wLatency); } static COMMAND_LINE_ARGUMENT_A rdpsnd_alsa_args[] = diff --git a/channels/rdpsnd/client/ios/TPCircularBuffer.c b/channels/rdpsnd/client/ios/TPCircularBuffer.c index 1dcf47190..44949e2e8 100644 --- a/channels/rdpsnd/client/ios/TPCircularBuffer.c +++ b/channels/rdpsnd/client/ios/TPCircularBuffer.c @@ -37,7 +37,7 @@ #define reportResult(result,operation) (_reportResult((result),(operation),__FILE__,__LINE__)) static inline bool _reportResult(kern_return_t result, const char *operation, const char* file, int line) { if ( result != ERR_SUCCESS ) { - printf("%s:%d: %s: %s\n", file, line, operation, mach_error_string(result)); + CLOG_DBG("%s:%d: %s: %s\n", file, line, operation, mach_error_string(result)); return false; } return true; @@ -108,7 +108,7 @@ bool TPCircularBufferInit(TPCircularBuffer *buffer, int length) { if ( virtualAddress != bufferAddress+buffer->length ) { // If the memory is not contiguous, clean up both allocated buffers and try again if ( retries-- == 0 ) { - printf("Couldn't map buffer memory to end of buffer\n"); + CLOG_DBG("Couldn't map buffer memory to end of buffer\n"); return false; } diff --git a/channels/rdpsnd/client/mac/rdpsnd_mac.c b/channels/rdpsnd/client/mac/rdpsnd_mac.c index 96ffacd89..8bff23b0f 100644 --- a/channels/rdpsnd/client/mac/rdpsnd_mac.c +++ b/channels/rdpsnd/client/mac/rdpsnd_mac.c @@ -121,7 +121,7 @@ static void rdpsnd_mac_open(rdpsndDevicePlugin* device, AUDIO_FORMAT* format, in if (status != 0) { - fprintf(stderr, "AudioQueueNewOutput failure\n"); + CLOG_ERR( "AudioQueueNewOutput failure\n"); return; } @@ -135,7 +135,7 @@ static void rdpsnd_mac_open(rdpsndDevicePlugin* device, AUDIO_FORMAT* format, in if (status != 0) { - printf("AudioQueueGetProperty failure: kAudioQueueProperty_DecodeBufferSizeFrames\n"); + CLOG_DBG("AudioQueueGetProperty failure: kAudioQueueProperty_DecodeBufferSizeFrames\n"); } for (index = 0; index < MAC_AUDIO_QUEUE_NUM_BUFFERS; index++) @@ -144,7 +144,7 @@ static void rdpsnd_mac_open(rdpsndDevicePlugin* device, AUDIO_FORMAT* format, in if (status != 0) { - fprintf(stderr, "AudioQueueAllocateBuffer failed\n"); + CLOG_ERR( "AudioQueueAllocateBuffer failed\n"); } } @@ -219,7 +219,7 @@ static void rdpsnd_mac_set_volume(rdpsndDevicePlugin* device, UINT32 value) if (status != 0) { - fprintf(stderr, "AudioQueueSetParameter kAudioQueueParam_Volume failed: %f\n", fVolume); + CLOG_ERR( "AudioQueueSetParameter kAudioQueueParam_Volume failed: %f\n", fVolume); } } @@ -238,7 +238,7 @@ static void rdpsnd_mac_start(rdpsndDevicePlugin* device) if (status != 0) { - fprintf(stderr, "AudioQueueStart failed\n"); + CLOG_ERR( "AudioQueueStart failed\n"); } mac->isPlaying = TRUE; diff --git a/channels/rdpsnd/client/opensles/rdpsnd_opensles.c b/channels/rdpsnd/client/opensles/rdpsnd_opensles.c index d836afa33..7047e46e2 100644 --- a/channels/rdpsnd/client/opensles/rdpsnd_opensles.c +++ b/channels/rdpsnd/client/opensles/rdpsnd_opensles.c @@ -35,7 +35,7 @@ #include #include -#include +#include #include "opensl_io.h" #include "rdpsnd_main.h" @@ -187,7 +187,7 @@ static void rdpsnd_opensles_open(rdpsndDevicePlugin* device, assert(opensles->stream); if (!opensles->stream) - DEBUG_WARN("android_OpenAudioDevice failed"); + CLOG_ERR("android_OpenAudioDevice failed"); else rdpsnd_opensles_set_volume(device, opensles->volume); @@ -364,7 +364,7 @@ static void rdpsnd_opensles_play(rdpsndDevicePlugin* device, ret = android_AudioOut(opensles->stream, src.s, size / 2); if (ret < 0) - DEBUG_WARN("android_AudioOut failed (%d)", ret); + CLOG_ERR("android_AudioOut failed (%d)", ret); } static void rdpsnd_opensles_start(rdpsndDevicePlugin* device) diff --git a/channels/rdpsnd/client/rdpsnd_main.c b/channels/rdpsnd/client/rdpsnd_main.c index c4fc84637..b7e9eaef5 100644 --- a/channels/rdpsnd/client/rdpsnd_main.c +++ b/channels/rdpsnd/client/rdpsnd_main.c @@ -45,7 +45,7 @@ #include #include #include -#include +#include #include #include "rdpsnd_main.h" @@ -195,13 +195,13 @@ void rdpsnd_select_supported_audio_formats(rdpsndPlugin* rdpsnd) } #if 0 - fprintf(stderr, "Server "); + CLOG_ERR( "Server "); rdpsnd_print_audio_formats(rdpsnd->ServerFormats, rdpsnd->NumberOfServerFormats); - fprintf(stderr, "\n"); + CLOG_ERR( "\n"); - fprintf(stderr, "Client "); + CLOG_ERR( "Client "); rdpsnd_print_audio_formats(rdpsnd->ClientFormats, rdpsnd->NumberOfClientFormats); - fprintf(stderr, "\n"); + CLOG_ERR( "\n"); #endif } @@ -544,7 +544,7 @@ static void rdpsnd_recv_pdu(rdpsndPlugin* rdpsnd, wStream* s) Stream_Seek_UINT8(s); /* bPad */ Stream_Read_UINT16(s, BodySize); - //fprintf(stderr, "msgType %d BodySize %d\n", msgType, BodySize); + //CLOG_ERR( "msgType %d BodySize %d\n", msgType, BodySize); switch (msgType) { @@ -569,7 +569,7 @@ static void rdpsnd_recv_pdu(rdpsndPlugin* rdpsnd, wStream* s) break; default: - DEBUG_WARN("unknown msgType %d", msgType); + CLOG_ERR("unknown msgType %d", msgType); break; } @@ -580,7 +580,7 @@ static void rdpsnd_register_device_plugin(rdpsndPlugin* rdpsnd, rdpsndDevicePlug { if (rdpsnd->device) { - DEBUG_WARN("existing device, abort."); + CLOG_ERR("existing device, abort."); return; } @@ -606,7 +606,7 @@ static BOOL rdpsnd_load_device_plugin(rdpsndPlugin* rdpsnd, const char* name, AD if (entry(&entryPoints) != 0) { - DEBUG_WARN("%s entry returns error.", name); + CLOG_ERR("%s entry returns error.", name); return FALSE; } @@ -795,7 +795,7 @@ static void rdpsnd_process_connect(rdpsndPlugin* rdpsnd) if (!rdpsnd->device) { - DEBUG_WARN("no sound device."); + CLOG_ERR("no sound device."); return; } @@ -875,7 +875,7 @@ int rdpsnd_virtual_channel_write(rdpsndPlugin* rdpsnd, wStream* s) if (status != CHANNEL_RC_OK) { Stream_Free(s, TRUE); - fprintf(stderr, "rdpdr_virtual_channel_write: VirtualChannelWrite failed %d\n", status); + CLOG_ERR( "rdpdr_virtual_channel_write: VirtualChannelWrite failed %d\n", status); } return status; @@ -907,7 +907,7 @@ static void rdpsnd_virtual_channel_event_data_received(rdpsndPlugin* plugin, { if (Stream_Capacity(s) != Stream_GetPosition(s)) { - fprintf(stderr, "rdpsnd_virtual_channel_event_data_received: read error\n"); + CLOG_ERR( "rdpsnd_virtual_channel_event_data_received: read error\n"); } plugin->data_in = NULL; @@ -927,7 +927,7 @@ static VOID VCAPITYPE rdpsnd_virtual_channel_open_event(DWORD openHandle, UINT e if (!plugin) { - fprintf(stderr, "rdpsnd_virtual_channel_open_event: error no match\n"); + CLOG_ERR( "rdpsnd_virtual_channel_open_event: error no match\n"); return; } @@ -987,7 +987,7 @@ static void rdpsnd_virtual_channel_event_connected(rdpsndPlugin* plugin, LPVOID if (status != CHANNEL_RC_OK) { - fprintf(stderr, "rdpsnd_virtual_channel_event_connected: open failed: status: %d\n", status); + CLOG_ERR( "rdpsnd_virtual_channel_event_connected: open failed: status: %d\n", status); return; } @@ -1040,7 +1040,7 @@ static VOID VCAPITYPE rdpsnd_virtual_channel_init_event(LPVOID pInitHandle, UINT if (!plugin) { - fprintf(stderr, "rdpsnd_virtual_channel_init_event: error no match\n"); + CLOG_ERR( "rdpsnd_virtual_channel_init_event: error no match\n"); return; } diff --git a/channels/rdpsnd/client/rdpsnd_main.h b/channels/rdpsnd/client/rdpsnd_main.h index 84508a1d5..4b7cb472c 100644 --- a/channels/rdpsnd/client/rdpsnd_main.h +++ b/channels/rdpsnd/client/rdpsnd_main.h @@ -27,7 +27,7 @@ #include #if defined(WITH_DEBUG_SND) -#define DEBUG_SND(fmt, ...) DEBUG_CLASS("rdpsnd", fmt, ## __VA_ARGS__) +#define DEBUG_SND(fmt, ...) CLOG_CLASS("rdpsnd", fmt, ## __VA_ARGS__) #else #define DEBUG_SND(fmt, ...) do { } while (0) #endif diff --git a/channels/rdpsnd/client/winmm/rdpsnd_winmm.c b/channels/rdpsnd/client/winmm/rdpsnd_winmm.c index 961b95e83..cb69098c8 100644 --- a/channels/rdpsnd/client/winmm/rdpsnd_winmm.c +++ b/channels/rdpsnd/client/winmm/rdpsnd_winmm.c @@ -34,6 +34,7 @@ #include #include +#include #include "rdpsnd_main.h" @@ -101,11 +102,11 @@ static void CALLBACK rdpsnd_winmm_callback_function(HWAVEOUT hwo, UINT uMsg, DWO switch (uMsg) { case MM_WOM_OPEN: - fprintf(stderr, "MM_WOM_OPEN\n"); + CLOG_ERR( "MM_WOM_OPEN\n"); break; case MM_WOM_CLOSE: - fprintf(stderr, "MM_WOM_CLOSE\n"); + CLOG_ERR( "MM_WOM_CLOSE\n"); break; case MM_WOM_DONE: @@ -121,7 +122,7 @@ static void CALLBACK rdpsnd_winmm_callback_function(HWAVEOUT hwo, UINT uMsg, DWO if (!wave) return; - fprintf(stderr, "MM_WOM_DONE: dwBufferLength: %d cBlockNo: %d\n", + CLOG_ERR( "MM_WOM_DONE: dwBufferLength: %d cBlockNo: %d\n", lpWaveHdr->dwBufferLength, wave->cBlockNo); wave->wLocalTimeB = GetTickCount(); @@ -155,7 +156,7 @@ static void rdpsnd_winmm_open(rdpsndDevicePlugin* device, AUDIO_FORMAT* format, if (mmResult != MMSYSERR_NOERROR) { - fprintf(stderr, "waveOutOpen failed: %d\n", mmResult); + CLOG_ERR( "waveOutOpen failed: %d\n", mmResult); } } @@ -172,7 +173,7 @@ static void rdpsnd_winmm_close(rdpsndDevicePlugin* device) if (mmResult != MMSYSERR_NOERROR) { - fprintf(stderr, "waveOutClose failure: %d\n", mmResult); + CLOG_ERR( "waveOutClose failure: %d\n", mmResult); } winmm->hWaveOut = NULL; @@ -299,7 +300,7 @@ void rdpsnd_winmm_wave_play(rdpsndDevicePlugin* device, RDPSND_WAVE* wave) if (mmResult != MMSYSERR_NOERROR) { - fprintf(stderr, "waveOutPrepareHeader failure: %d\n", mmResult); + CLOG_ERR( "waveOutPrepareHeader failure: %d\n", mmResult); return; } @@ -307,7 +308,7 @@ void rdpsnd_winmm_wave_play(rdpsndDevicePlugin* device, RDPSND_WAVE* wave) if (mmResult != MMSYSERR_NOERROR) { - fprintf(stderr, "waveOutWrite failure: %d\n", mmResult); + CLOG_ERR( "waveOutWrite failure: %d\n", mmResult); waveOutUnprepareHeader(winmm->hWaveOut, lpWaveHdr, sizeof(WAVEHDR)); return; } diff --git a/channels/rdpsnd/server/rdpsnd_main.c b/channels/rdpsnd/server/rdpsnd_main.c index 74fe4ec14..f830a0ffc 100644 --- a/channels/rdpsnd/server/rdpsnd_main.c +++ b/channels/rdpsnd/server/rdpsnd_main.c @@ -29,6 +29,8 @@ #include #include +#include + #include "rdpsnd_main.h" BOOL rdpsnd_server_send_formats(RdpsndServerContext* context, wStream* s) @@ -108,7 +110,7 @@ static BOOL rdpsnd_server_recv_quality_mode(RdpsndServerContext* context, wStrea Stream_Read_UINT16(s, quality); Stream_Seek_UINT16(s); // reserved - fprintf(stderr, "Client requested sound quality: %#0X\n", quality); + CLOG_ERR( "Client requested sound quality: %#0X\n", quality); return TRUE; } @@ -137,7 +139,7 @@ static BOOL rdpsnd_server_recv_formats(RdpsndServerContext* context, wStream* s) if (!context->num_client_formats) { - fprintf(stderr, "%s: client doesn't support any format!\n", __FUNCTION__); + CLOG_ERR( "%s: client doesn't support any format!\n", __FUNCTION__); return FALSE; } @@ -174,7 +176,7 @@ static BOOL rdpsnd_server_recv_formats(RdpsndServerContext* context, wStream* s) if (!context->num_client_formats) { - fprintf(stderr, "%s: client doesn't support any known format!\n", __FUNCTION__); + CLOG_ERR( "%s: client doesn't support any known format!\n", __FUNCTION__); goto out_free; } @@ -230,7 +232,7 @@ static BOOL rdpsnd_server_select_format(RdpsndServerContext* context, int client if (client_format_index < 0 || client_format_index >= context->num_client_formats) { - fprintf(stderr, "%s: index %d is not correct.\n", __FUNCTION__, client_format_index); + CLOG_ERR( "%s: index %d is not correct.\n", __FUNCTION__, client_format_index); return FALSE; } @@ -242,7 +244,7 @@ static BOOL rdpsnd_server_select_format(RdpsndServerContext* context, int client if (format->nSamplesPerSec == 0) { - fprintf(stderr, "%s: invalid Client Sound Format!!\n", __FUNCTION__); + CLOG_ERR( "%s: invalid Client Sound Format!!\n", __FUNCTION__); return FALSE; } @@ -475,7 +477,7 @@ static int rdpsnd_server_start(RdpsndServerContext* context) if (!WTSVirtualChannelQuery(priv->ChannelHandle, WTSVirtualEventHandle, &buffer, &bytesReturned) || (bytesReturned != sizeof(HANDLE))) { - fprintf(stderr, "%s: error during WTSVirtualChannelQuery(WTSVirtualEventHandle) or invalid returned size(%d)\n", + CLOG_ERR( "%s: error during WTSVirtualChannelQuery(WTSVirtualEventHandle) or invalid returned size(%d)\n", __FUNCTION__, bytesReturned); if (buffer) WTSFreeMemory(buffer); @@ -631,7 +633,7 @@ BOOL rdpsnd_server_handle_messages(RdpsndServerContext *context) if (GetLastError() == ERROR_NO_DATA) return TRUE; - fprintf(stderr, "%s: channel connection closed\n", __FUNCTION__); + CLOG_ERR( "%s: channel connection closed\n", __FUNCTION__); return FALSE; } priv->expectedBytes -= bytesReturned; @@ -659,7 +661,7 @@ BOOL rdpsnd_server_handle_messages(RdpsndServerContext *context) /* when here we have the header + the body */ #ifdef WITH_DEBUG_SND - fprintf(stderr, "%s: message type %d\n", __FUNCTION__, priv->msgType); + CLOG_ERR( "%s: message type %d\n", __FUNCTION__, priv->msgType); #endif priv->expectedBytes = 4; priv->waitingHeader = TRUE; @@ -685,7 +687,7 @@ BOOL rdpsnd_server_handle_messages(RdpsndServerContext *context) break; default: - fprintf(stderr, "%s: UNKOWN MESSAGE TYPE!! (%#0X)\n\n", __FUNCTION__, priv->msgType); + CLOG_ERR( "%s: UNKOWN MESSAGE TYPE!! (%#0X)\n\n", __FUNCTION__, priv->msgType); ret = FALSE; break; } diff --git a/channels/remdesk/client/remdesk_main.c b/channels/remdesk/client/remdesk_main.c index 8527b59c8..c81e6eaaf 100644 --- a/channels/remdesk/client/remdesk_main.c +++ b/channels/remdesk/client/remdesk_main.c @@ -26,6 +26,7 @@ #include +#include #include #include "remdesk_main.h" @@ -49,7 +50,7 @@ int remdesk_virtual_channel_write(remdeskPlugin* remdesk, wStream* s) if (status != CHANNEL_RC_OK) { - fprintf(stderr, "remdesk_virtual_channel_write: VirtualChannelWrite failed %d\n", status); + CLOG_ERR( "remdesk_virtual_channel_write: VirtualChannelWrite failed %d\n", status); return -1; } @@ -98,7 +99,7 @@ int remdesk_generate_expert_blob(remdeskPlugin* remdesk) return 1; } -int remdesk_read_channel_header(wStream* s, REMDESK_CHANNEL_HEADER* header) +static int remdesk_read_channel_header(wStream* s, REMDESK_CHANNEL_HEADER* header) { int status; UINT32 ChannelNameLen; @@ -133,7 +134,7 @@ int remdesk_read_channel_header(wStream* s, REMDESK_CHANNEL_HEADER* header) return 1; } -int remdesk_write_channel_header(wStream* s, REMDESK_CHANNEL_HEADER* header) +static int remdesk_write_channel_header(wStream* s, REMDESK_CHANNEL_HEADER* header) { int index; UINT32 ChannelNameLen; @@ -156,14 +157,14 @@ int remdesk_write_channel_header(wStream* s, REMDESK_CHANNEL_HEADER* header) return 1; } -int remdesk_write_ctl_header(wStream* s, REMDESK_CTL_HEADER* ctlHeader) +static int remdesk_write_ctl_header(wStream* s, REMDESK_CTL_HEADER* ctlHeader) { remdesk_write_channel_header(s, (REMDESK_CHANNEL_HEADER*) ctlHeader); Stream_Write_UINT32(s, ctlHeader->msgType); /* msgType (4 bytes) */ return 1; } -int remdesk_prepare_ctl_header(REMDESK_CTL_HEADER* ctlHeader, UINT32 msgType, UINT32 msgSize) +static int remdesk_prepare_ctl_header(REMDESK_CTL_HEADER* ctlHeader, UINT32 msgType, UINT32 msgSize) { ctlHeader->msgType = msgType; strcpy(ctlHeader->ChannelName, REMDESK_CHANNEL_CTL_NAME); @@ -171,12 +172,12 @@ int remdesk_prepare_ctl_header(REMDESK_CTL_HEADER* ctlHeader, UINT32 msgType, UI return 1; } -int remdesk_recv_ctl_server_announce_pdu(remdeskPlugin* remdesk, wStream* s, REMDESK_CHANNEL_HEADER* header) +static int remdesk_recv_ctl_server_announce_pdu(remdeskPlugin* remdesk, wStream* s, REMDESK_CHANNEL_HEADER* header) { return 1; } -int remdesk_recv_ctl_version_info_pdu(remdeskPlugin* remdesk, wStream* s, REMDESK_CHANNEL_HEADER* header) +static int remdesk_recv_ctl_version_info_pdu(remdeskPlugin* remdesk, wStream* s, REMDESK_CHANNEL_HEADER* header) { UINT32 versionMajor; UINT32 versionMinor; @@ -190,7 +191,7 @@ int remdesk_recv_ctl_version_info_pdu(remdeskPlugin* remdesk, wStream* s, REMDES return 1; } -int remdesk_send_ctl_version_info_pdu(remdeskPlugin* remdesk) +static int remdesk_send_ctl_version_info_pdu(remdeskPlugin* remdesk) { wStream* s; REMDESK_CTL_VERSION_INFO_PDU pdu; @@ -214,7 +215,7 @@ int remdesk_send_ctl_version_info_pdu(remdeskPlugin* remdesk) return 1; } -int remdesk_recv_result_pdu(remdeskPlugin* remdesk, wStream* s, REMDESK_CHANNEL_HEADER* header, UINT32 *pResult) +static int remdesk_recv_ctl_result_pdu(remdeskPlugin* remdesk, wStream* s, REMDESK_CHANNEL_HEADER* header, UINT32 *pResult) { UINT32 result; @@ -225,12 +226,12 @@ int remdesk_recv_result_pdu(remdeskPlugin* remdesk, wStream* s, REMDESK_CHANNEL_ *pResult = result; - //printf("RemdeskRecvResult: 0x%04X\n", result); + //CLOG_DBG("RemdeskRecvResult: 0x%04X\n", result); return 1; } -int remdesk_send_ctl_authenticate_pdu(remdeskPlugin* remdesk) +static int remdesk_send_ctl_authenticate_pdu(remdeskPlugin* remdesk) { int status; wStream* s; @@ -282,7 +283,7 @@ int remdesk_send_ctl_authenticate_pdu(remdeskPlugin* remdesk) return 1; } -int remdesk_send_ctl_remote_control_desktop_pdu(remdeskPlugin* remdesk) +static int remdesk_send_ctl_remote_control_desktop_pdu(remdeskPlugin* remdesk) { int status; wStream* s; @@ -316,7 +317,7 @@ int remdesk_send_ctl_remote_control_desktop_pdu(remdeskPlugin* remdesk) return 1; } -int remdesk_send_ctl_verify_password_pdu(remdeskPlugin* remdesk) +static int remdesk_send_ctl_verify_password_pdu(remdeskPlugin* remdesk) { int status; wStream* s; @@ -355,7 +356,7 @@ int remdesk_send_ctl_verify_password_pdu(remdeskPlugin* remdesk) return 1; } -int remdesk_send_ctl_expert_on_vista_pdu(remdeskPlugin* remdesk) +static int remdesk_send_ctl_expert_on_vista_pdu(remdeskPlugin* remdesk) { int status; wStream* s; @@ -385,7 +386,7 @@ int remdesk_send_ctl_expert_on_vista_pdu(remdeskPlugin* remdesk) return 1; } -int remdesk_recv_ctl_pdu(remdeskPlugin* remdesk, wStream* s, REMDESK_CHANNEL_HEADER* header) +static int remdesk_recv_ctl_pdu(remdeskPlugin* remdesk, wStream* s, REMDESK_CHANNEL_HEADER* header) { int status = 1; UINT32 msgType = 0; @@ -396,7 +397,7 @@ int remdesk_recv_ctl_pdu(remdeskPlugin* remdesk, wStream* s, REMDESK_CHANNEL_HEA Stream_Read_UINT32(s, msgType); /* msgType (4 bytes) */ - //printf("msgType: %d\n", msgType); + //CLOG_DBG("msgType: %d\n", msgType); switch (msgType) { @@ -404,7 +405,7 @@ int remdesk_recv_ctl_pdu(remdeskPlugin* remdesk, wStream* s, REMDESK_CHANNEL_HEA break; case REMDESK_CTL_RESULT: - status = remdesk_recv_result_pdu(remdesk, s, header, &result); + status = remdesk_recv_ctl_result_pdu(remdesk, s, header, &result); break; case REMDESK_CTL_AUTHENTICATE: @@ -461,7 +462,7 @@ int remdesk_recv_ctl_pdu(remdeskPlugin* remdesk, wStream* s, REMDESK_CHANNEL_HEA break; default: - fprintf(stderr, "remdesk_recv_control_pdu: unknown msgType: %d\n", msgType); + CLOG_ERR( "remdesk_recv_control_pdu: unknown msgType: %d\n", msgType); status = -1; break; } @@ -469,13 +470,13 @@ int remdesk_recv_ctl_pdu(remdeskPlugin* remdesk, wStream* s, REMDESK_CHANNEL_HEA return status; } -int remdesk_process_receive(remdeskPlugin* remdesk, wStream* s) +static int remdesk_process_receive(remdeskPlugin* remdesk, wStream* s) { int status = 1; REMDESK_CHANNEL_HEADER header; #if 0 - printf("RemdeskReceive: %d\n", Stream_GetRemainingLength(s)); + CLOG_DBG("RemdeskReceive: %d\n", Stream_GetRemainingLength(s)); winpr_HexDump(Stream_Pointer(s), Stream_GetRemainingLength(s)); #endif @@ -585,7 +586,7 @@ int remdesk_send(remdeskPlugin* remdesk, wStream* s) if (status != CHANNEL_RC_OK) { Stream_Free(s, TRUE); - fprintf(stderr, "remdesk_send: VirtualChannelWrite failed %d\n", status); + CLOG_ERR( "remdesk_send: VirtualChannelWrite failed %d\n", status); } return status; @@ -617,7 +618,7 @@ static void remdesk_virtual_channel_event_data_received(remdeskPlugin* remdesk, { if (Stream_Capacity(data_in) != Stream_GetPosition(data_in)) { - fprintf(stderr, "remdesk_plugin_process_received: read error\n"); + CLOG_ERR( "remdesk_plugin_process_received: read error\n"); } remdesk->data_in = NULL; @@ -637,7 +638,7 @@ static VOID VCAPITYPE remdesk_virtual_channel_open_event(DWORD openHandle, UINT if (!remdesk) { - fprintf(stderr, "remdesk_virtual_channel_open_event: error no match\n"); + CLOG_ERR( "remdesk_virtual_channel_open_event: error no match\n"); return; } @@ -697,7 +698,7 @@ static void remdesk_virtual_channel_event_connected(remdeskPlugin* remdesk, LPVO if (status != CHANNEL_RC_OK) { - fprintf(stderr, "remdesk_virtual_channel_event_connected: open failed: status: %d\n", status); + CLOG_ERR( "remdesk_virtual_channel_event_connected: open failed: status: %d\n", status); return; } @@ -735,7 +736,7 @@ static VOID VCAPITYPE remdesk_virtual_channel_init_event(LPVOID pInitHandle, UIN if (!remdesk) { - fprintf(stderr, "remdesk_virtual_channel_init_event: error no match\n"); + CLOG_ERR( "remdesk_virtual_channel_init_event: error no match\n"); return; } diff --git a/channels/remdesk/server/remdesk_main.c b/channels/remdesk/server/remdesk_main.c index 3cd00ad63..8c193e0fc 100644 --- a/channels/remdesk/server/remdesk_main.c +++ b/channels/remdesk/server/remdesk_main.c @@ -27,9 +27,391 @@ #include "remdesk_main.h" +int remdesk_virtual_channel_write(RemdeskServerContext* context, wStream* s) +{ + BOOL status; + ULONG BytesWritten = 0; + + status = WTSVirtualChannelWrite(context->priv->ChannelHandle, + (PCHAR) Stream_Buffer(s), Stream_Length(s), &BytesWritten); + + return (status) ? 1 : -1; +} + +static int remdesk_read_channel_header(wStream* s, REMDESK_CHANNEL_HEADER* header) +{ + int status; + UINT32 ChannelNameLen; + char* pChannelName = NULL; + + if (Stream_GetRemainingLength(s) < 8) + return -1; + + Stream_Read_UINT32(s, ChannelNameLen); /* ChannelNameLen (4 bytes) */ + Stream_Read_UINT32(s, header->DataLength); /* DataLen (4 bytes) */ + + if (ChannelNameLen > 64) + return -1; + + if ((ChannelNameLen % 2) != 0) + return -1; + + if (Stream_GetRemainingLength(s) < ChannelNameLen) + return -1; + + ZeroMemory(header->ChannelName, sizeof(header->ChannelName)); + + pChannelName = (char*) header->ChannelName; + status = ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) Stream_Pointer(s), + ChannelNameLen / 2, &pChannelName, 32, NULL, NULL); + + Stream_Seek(s, ChannelNameLen); + + if (status <= 0) + return -1; + + return 1; +} + +static int remdesk_write_channel_header(wStream* s, REMDESK_CHANNEL_HEADER* header) +{ + int index; + UINT32 ChannelNameLen; + WCHAR ChannelNameW[32]; + + ZeroMemory(ChannelNameW, sizeof(ChannelNameW)); + + for (index = 0; index < 32; index++) + { + ChannelNameW[index] = (WCHAR) header->ChannelName[index]; + } + + ChannelNameLen = (strlen(header->ChannelName) + 1) * 2; + + Stream_Write_UINT32(s, ChannelNameLen); /* ChannelNameLen (4 bytes) */ + Stream_Write_UINT32(s, header->DataLength); /* DataLen (4 bytes) */ + + Stream_Write(s, ChannelNameW, ChannelNameLen); /* ChannelName (variable) */ + + return 1; +} + +static int remdesk_write_ctl_header(wStream* s, REMDESK_CTL_HEADER* ctlHeader) +{ + remdesk_write_channel_header(s, (REMDESK_CHANNEL_HEADER*) ctlHeader); + Stream_Write_UINT32(s, ctlHeader->msgType); /* msgType (4 bytes) */ + return 1; +} + +static int remdesk_prepare_ctl_header(REMDESK_CTL_HEADER* ctlHeader, UINT32 msgType, UINT32 msgSize) +{ + ctlHeader->msgType = msgType; + strcpy(ctlHeader->ChannelName, REMDESK_CHANNEL_CTL_NAME); + ctlHeader->DataLength = 4 + msgSize; + return 1; +} + +static int remdesk_send_ctl_result_pdu(RemdeskServerContext* context, UINT32 result) +{ + wStream* s; + REMDESK_CTL_RESULT_PDU pdu; + + pdu.result = result; + + remdesk_prepare_ctl_header(&(pdu.ctlHeader), REMDESK_CTL_RESULT, 4); + + s = Stream_New(NULL, REMDESK_CHANNEL_CTL_SIZE + pdu.ctlHeader.DataLength); + + remdesk_write_ctl_header(s, &(pdu.ctlHeader)); + + Stream_Write_UINT32(s, pdu.result); /* result (4 bytes) */ + + Stream_SealLength(s); + + remdesk_virtual_channel_write(context, s); + + Stream_Free(s, TRUE); + + return 1; +} + +static int remdesk_send_ctl_version_info_pdu(RemdeskServerContext* context) +{ + wStream* s; + REMDESK_CTL_VERSION_INFO_PDU pdu; + + remdesk_prepare_ctl_header(&(pdu.ctlHeader), REMDESK_CTL_VERSIONINFO, 8); + + pdu.versionMajor = 1; + pdu.versionMinor = 2; + + s = Stream_New(NULL, REMDESK_CHANNEL_CTL_SIZE + pdu.ctlHeader.DataLength); + + remdesk_write_ctl_header(s, &(pdu.ctlHeader)); + + Stream_Write_UINT32(s, pdu.versionMajor); /* versionMajor (4 bytes) */ + Stream_Write_UINT32(s, pdu.versionMinor); /* versionMinor (4 bytes) */ + + Stream_SealLength(s); + + remdesk_virtual_channel_write(context, s); + + return 1; +} + +static int remdesk_recv_ctl_version_info_pdu(RemdeskServerContext* context, wStream* s, REMDESK_CHANNEL_HEADER* header) +{ + UINT32 versionMajor; + UINT32 versionMinor; + + if (Stream_GetRemainingLength(s) < 8) + return -1; + + Stream_Read_UINT32(s, versionMajor); /* versionMajor (4 bytes) */ + Stream_Read_UINT32(s, versionMinor); /* versionMinor (4 bytes) */ + + return 1; +} + +static int remdesk_recv_ctl_remote_control_desktop_pdu(RemdeskServerContext* context, wStream* s, REMDESK_CHANNEL_HEADER* header) +{ + int status; + int cchStringW; + WCHAR* pStringW; + UINT32 msgLength; + int cbRaConnectionStringW = 0; + WCHAR* raConnectionStringW = NULL; + REMDESK_CTL_REMOTE_CONTROL_DESKTOP_PDU pdu; + + msgLength = header->DataLength - 4; + + pStringW = (WCHAR*) Stream_Pointer(s); + raConnectionStringW = pStringW; + cchStringW = 0; + + while ((msgLength > 0) && pStringW[cchStringW]) + { + msgLength -= 2; + cchStringW++; + } + + if (pStringW[cchStringW] || !cchStringW) + return -1; + + cchStringW++; + cbRaConnectionStringW = cchStringW * 2; + + pdu.raConnectionString = NULL; + + status = ConvertFromUnicode(CP_UTF8, 0, raConnectionStringW, + cbRaConnectionStringW / 2, &pdu.raConnectionString, 0, NULL, NULL); + + if (status <= 0) + return -1; + + printf("RaConnectionString: %s\n", + pdu.raConnectionString); + + free(pdu.raConnectionString); + + remdesk_send_ctl_result_pdu(context, 0); + + return 1; +} + +static int remdesk_recv_ctl_authenticate_pdu(RemdeskServerContext* context, wStream* s, REMDESK_CHANNEL_HEADER* header) +{ + int status; + int cchStringW; + WCHAR* pStringW; + UINT32 msgLength; + int cbExpertBlobW = 0; + WCHAR* expertBlobW = NULL; + int cbRaConnectionStringW = 0; + WCHAR* raConnectionStringW = NULL; + REMDESK_CTL_AUTHENTICATE_PDU pdu; + + msgLength = header->DataLength - 4; + + pStringW = (WCHAR*) Stream_Pointer(s); + raConnectionStringW = pStringW; + cchStringW = 0; + + while ((msgLength > 0) && pStringW[cchStringW]) + { + msgLength -= 2; + cchStringW++; + } + + if (pStringW[cchStringW] || !cchStringW) + return -1; + + cchStringW++; + cbRaConnectionStringW = cchStringW * 2; + + pStringW += cchStringW; + expertBlobW = pStringW; + cchStringW = 0; + + while ((msgLength > 0) && pStringW[cchStringW]) + { + msgLength -= 2; + cchStringW++; + } + + if (pStringW[cchStringW] || !cchStringW) + return -1; + + cchStringW++; + cbExpertBlobW = cchStringW * 2; + + pdu.raConnectionString = NULL; + + status = ConvertFromUnicode(CP_UTF8, 0, raConnectionStringW, + cbRaConnectionStringW / 2, &pdu.raConnectionString, 0, NULL, NULL); + + if (status <= 0) + return -1; + + pdu.expertBlob = NULL; + + status = ConvertFromUnicode(CP_UTF8, 0, expertBlobW, + cbExpertBlobW / 2, &pdu.expertBlob, 0, NULL, NULL); + + if (status <= 0) + return -1; + + printf("RaConnectionString: %s ExpertBlob: %s\n", + pdu.raConnectionString, pdu.expertBlob); + + free(pdu.raConnectionString); + free(pdu.expertBlob); + + return 1; +} + +static int remdesk_recv_ctl_verify_password_pdu(RemdeskServerContext* context, wStream* s, REMDESK_CHANNEL_HEADER* header) +{ + int status; + int cbExpertBlobW = 0; + WCHAR* expertBlobW = NULL; + REMDESK_CTL_VERIFY_PASSWORD_PDU pdu; + + if (Stream_GetRemainingLength(s) < 8) + return -1; + + pdu.expertBlob = NULL; + expertBlobW = (WCHAR*) Stream_Pointer(s); + cbExpertBlobW = header->DataLength - 4; + + status = ConvertFromUnicode(CP_UTF8, 0, expertBlobW, cbExpertBlobW / 2, &pdu.expertBlob, 0, NULL, NULL); + + printf("ExpertBlob: %s\n", pdu.expertBlob); + + remdesk_send_ctl_result_pdu(context, 0); + + return 1; +} + +static int remdesk_recv_ctl_pdu(RemdeskServerContext* context, wStream* s, REMDESK_CHANNEL_HEADER* header) +{ + int status = 1; + UINT32 msgType = 0; + + if (Stream_GetRemainingLength(s) < 4) + return -1; + + Stream_Read_UINT32(s, msgType); /* msgType (4 bytes) */ + + printf("msgType: %d\n", msgType); + + switch (msgType) + { + case REMDESK_CTL_REMOTE_CONTROL_DESKTOP: + status = remdesk_recv_ctl_remote_control_desktop_pdu(context, s, header); + break; + + case REMDESK_CTL_AUTHENTICATE: + status = remdesk_recv_ctl_authenticate_pdu(context, s, header); + break; + + case REMDESK_CTL_DISCONNECT: + break; + + case REMDESK_CTL_VERSIONINFO: + status = remdesk_recv_ctl_version_info_pdu(context, s, header); + break; + + case REMDESK_CTL_ISCONNECTED: + break; + + case REMDESK_CTL_VERIFY_PASSWORD: + status = remdesk_recv_ctl_verify_password_pdu(context, s, header); + break; + + case REMDESK_CTL_EXPERT_ON_VISTA: + break; + + case REMDESK_CTL_RANOVICE_NAME: + break; + + case REMDESK_CTL_RAEXPERT_NAME: + break; + + case REMDESK_CTL_TOKEN: + break; + + default: + fprintf(stderr, "remdesk_recv_control_pdu: unknown msgType: %d\n", msgType); + status = -1; + break; + } + + return status; +} + static int remdesk_server_receive_pdu(RemdeskServerContext* context, wStream* s) { - return 0; + int status = 1; + REMDESK_CHANNEL_HEADER header; + +#if 0 + printf("RemdeskReceive: %d\n", Stream_GetRemainingLength(s)); + winpr_HexDump(Stream_Pointer(s), Stream_GetRemainingLength(s)); +#endif + + remdesk_read_channel_header(s, &header); + + if (strcmp(header.ChannelName, "RC_CTL") == 0) + { + status = remdesk_recv_ctl_pdu(context, s, &header); + } + else if (strcmp(header.ChannelName, "70") == 0) + { + + } + else if (strcmp(header.ChannelName, "71") == 0) + { + + } + else if (strcmp(header.ChannelName, ".") == 0) + { + + } + else if (strcmp(header.ChannelName, "1000.") == 0) + { + + } + else if (strcmp(header.ChannelName, "RA_FX") == 0) + { + + } + else + { + + } + + return 1; } static void* remdesk_server_thread(void* arg) @@ -38,6 +420,8 @@ static void* remdesk_server_thread(void* arg) DWORD status; DWORD nCount; void* buffer; + UINT32* pHeader; + UINT32 PduLength; HANDLE events[8]; HANDLE ChannelEvent; DWORD BytesReturned; @@ -63,6 +447,8 @@ static void* remdesk_server_thread(void* arg) events[nCount++] = ChannelEvent; events[nCount++] = context->priv->StopEvent; + remdesk_send_ctl_version_info_pdu(context); + while (1) { status = WaitForMultipleObjects(nCount, events, FALSE, INFINITE); @@ -83,9 +469,18 @@ static void* remdesk_server_thread(void* arg) Stream_EnsureRemainingCapacity(s, BytesReturned); } - if (0) + if (Stream_GetPosition(s) >= 8) { - remdesk_server_receive_pdu(context, s); + pHeader = (UINT32*) Stream_Buffer(s); + PduLength = pHeader[0] + pHeader[1] + 8; + + if (PduLength >= Stream_GetPosition(s)) + { + Stream_SealLength(s); + Stream_SetPosition(s, 0); + remdesk_server_receive_pdu(context, s); + Stream_SetPosition(s, 0); + } } } @@ -106,7 +501,7 @@ static int remdesk_server_start(RemdeskServerContext* context) context->priv->Thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) remdesk_server_thread, (void*) context, 0, NULL); - return 0; + return 1; } static int remdesk_server_stop(RemdeskServerContext* context) @@ -116,7 +511,7 @@ static int remdesk_server_stop(RemdeskServerContext* context) WaitForSingleObject(context->priv->Thread, INFINITE); CloseHandle(context->priv->Thread); - return 0; + return 1; } RemdeskServerContext* remdesk_server_context_new(HANDLE vcm) @@ -136,7 +531,7 @@ RemdeskServerContext* remdesk_server_context_new(HANDLE vcm) if (context->priv) { - + context->priv->Version = 1; } } diff --git a/channels/remdesk/server/remdesk_main.h b/channels/remdesk/server/remdesk_main.h index 42b504c1a..94184aeb9 100644 --- a/channels/remdesk/server/remdesk_main.h +++ b/channels/remdesk/server/remdesk_main.h @@ -31,6 +31,8 @@ struct _remdesk_server_private HANDLE Thread; HANDLE StopEvent; void* ChannelHandle; + + UINT32 Version; }; #endif /* FREERDP_CHANNEL_SERVER_REMDESK_MAIN_H */ diff --git a/channels/smartcard/client/smartcard_main.c b/channels/smartcard/client/smartcard_main.c index e60926ab6..9baf16355 100644 --- a/channels/smartcard/client/smartcard_main.c +++ b/channels/smartcard/client/smartcard_main.c @@ -372,7 +372,7 @@ void smartcard_process_irp(SMARTCARD_DEVICE* smartcard, IRP* irp) } else { - fprintf(stderr, "Unexpected SmartCard IRP: MajorFunction 0x%08X MinorFunction: 0x%08X", + CLOG_ERR( "Unexpected SmartCard IRP: MajorFunction 0x%08X MinorFunction: 0x%08X", irp->MajorFunction, irp->MinorFunction); irp->IoStatus = STATUS_NOT_SUPPORTED; diff --git a/channels/smartcard/client/smartcard_main.h b/channels/smartcard/client/smartcard_main.h index e0172d424..c2ef362f8 100644 --- a/channels/smartcard/client/smartcard_main.h +++ b/channels/smartcard/client/smartcard_main.h @@ -21,7 +21,7 @@ #ifndef FREERDP_CHANNEL_SMARTCARD_CLIENT_MAIN_H #define FREERDP_CHANNEL_SMARTCARD_CLIENT_MAIN_H -#include +#include #include #include diff --git a/channels/smartcard/client/smartcard_operations.c b/channels/smartcard/client/smartcard_operations.c index 0e9fad24e..9d043d1fd 100644 --- a/channels/smartcard/client/smartcard_operations.c +++ b/channels/smartcard/client/smartcard_operations.c @@ -1142,7 +1142,7 @@ UINT32 smartcard_irp_device_control_decode(SMARTCARD_DEVICE* smartcard, SMARTCAR smartcard_get_ioctl_string(ioControlCode, TRUE), ioControlCode, irp->FileId, irp->CompletionId); #if 0 - printf("%s (0x%08X) FileId: %d CompletionId: %d\n", + CLOG_DBG("%s (0x%08X) FileId: %d CompletionId: %d\n", smartcard_get_ioctl_string(ioControlCode, TRUE), ioControlCode, irp->FileId, irp->CompletionId); #endif diff --git a/channels/tsmf/client/alsa/tsmf_alsa.c b/channels/tsmf/client/alsa/tsmf_alsa.c index d442dca8c..8c95b337c 100644 --- a/channels/tsmf/client/alsa/tsmf_alsa.c +++ b/channels/tsmf/client/alsa/tsmf_alsa.c @@ -56,7 +56,7 @@ static BOOL tsmf_alsa_open_device(TSMFAlsaAudioDevice *alsa) error = snd_pcm_open(&alsa->out_handle, alsa->device, SND_PCM_STREAM_PLAYBACK, 0); if(error < 0) { - DEBUG_WARN("failed to open device %s", alsa->device); + CLOG_ERR("failed to open device %s", alsa->device); return FALSE; } DEBUG_TSMF("open device %s", alsa->device); @@ -95,7 +95,7 @@ static BOOL tsmf_alsa_set_format(ITSMFAudioDevice *audio, error = snd_pcm_hw_params_malloc(&hw_params); if(error < 0) { - DEBUG_WARN("snd_pcm_hw_params_malloc failed"); + CLOG_ERR("snd_pcm_hw_params_malloc failed"); return FALSE; } snd_pcm_hw_params_any(alsa->out_handle, hw_params); @@ -115,7 +115,7 @@ static BOOL tsmf_alsa_set_format(ITSMFAudioDevice *audio, error = snd_pcm_sw_params_malloc(&sw_params); if(error < 0) { - DEBUG_WARN("snd_pcm_sw_params_malloc"); + CLOG_ERR("snd_pcm_sw_params_malloc"); return FALSE; } snd_pcm_sw_params_current(alsa->out_handle, sw_params); diff --git a/channels/tsmf/client/ffmpeg/tsmf_ffmpeg.c b/channels/tsmf/client/ffmpeg/tsmf_ffmpeg.c index e2c9da2c5..428ceaa97 100644 --- a/channels/tsmf/client/ffmpeg/tsmf_ffmpeg.c +++ b/channels/tsmf/client/ffmpeg/tsmf_ffmpeg.c @@ -27,10 +27,12 @@ #include +#include #include #include #include +#include #include "tsmf_constants.h" #include "tsmf_decoder.h" @@ -47,6 +49,20 @@ #define MAX_AUDIO_FRAME_SIZE 192000 #endif +#if LIBAVCODEC_VERSION_MAJOR < 55 +#define AV_CODEC_ID_VC1 CODEC_ID_VC1 +#define AV_CODEC_ID_WMAV2 CODEC_ID_WMAV2 +#define AV_CODEC_ID_WMAPRO CODEC_ID_WMAPRO +#define AV_CODEC_ID_MP3 CODEC_ID_MP3 +#define AV_CODEC_ID_MP2 CODEC_ID_MP2 +#define AV_CODEC_ID_MPEG2VIDEO CODEC_ID_MPEG2VIDEO +#define AV_CODEC_ID_WMV3 CODEC_ID_WMV3 +#define AV_CODEC_ID_AAC CODEC_ID_AAC +#define AV_CODEC_ID_H264 CODEC_ID_H264 +#define AV_CODEC_ID_AC3 CODEC_ID_AC3 +#endif + + typedef struct _TSMFFFmpegDecoder { ITSMFDecoder iface; @@ -73,7 +89,7 @@ static BOOL tsmf_ffmpeg_init_context(ITSMFDecoder *decoder) mdecoder->codec_context = avcodec_alloc_context3(NULL); if(!mdecoder->codec_context) { - DEBUG_WARN("avcodec_alloc_context failed."); + CLOG_ERR("avcodec_alloc_context failed."); return FALSE; } return TRUE; @@ -127,7 +143,7 @@ static BOOL tsmf_ffmpeg_init_stream(ITSMFDecoder *decoder, const TS_AM_MEDIA_TYP mdecoder->codec = avcodec_find_decoder(mdecoder->codec_id); if(!mdecoder->codec) { - DEBUG_WARN("avcodec_find_decoder failed."); + CLOG_ERR("avcodec_find_decoder failed."); return FALSE; } mdecoder->codec_context->codec_id = mdecoder->codec_id; @@ -189,7 +205,7 @@ static BOOL tsmf_ffmpeg_prepare(ITSMFDecoder *decoder) TSMFFFmpegDecoder *mdecoder = (TSMFFFmpegDecoder *) decoder; if(avcodec_open2(mdecoder->codec_context, mdecoder->codec, NULL) < 0) { - DEBUG_WARN("avcodec_open2 failed."); + CLOG_ERR("avcodec_open2 failed."); return FALSE; } mdecoder->prepared = 1; @@ -213,28 +229,28 @@ static BOOL tsmf_ffmpeg_set_format(ITSMFDecoder *decoder, TS_AM_MEDIA_TYPE *medi switch(media_type->SubType) { case TSMF_SUB_TYPE_WVC1: - mdecoder->codec_id = CODEC_ID_VC1; + mdecoder->codec_id = AV_CODEC_ID_VC1; break; case TSMF_SUB_TYPE_WMA2: - mdecoder->codec_id = CODEC_ID_WMAV2; + mdecoder->codec_id = AV_CODEC_ID_WMAV2; break; case TSMF_SUB_TYPE_WMA9: - mdecoder->codec_id = CODEC_ID_WMAPRO; + mdecoder->codec_id = AV_CODEC_ID_WMAPRO; break; case TSMF_SUB_TYPE_MP3: - mdecoder->codec_id = CODEC_ID_MP3; + mdecoder->codec_id = AV_CODEC_ID_MP3; break; case TSMF_SUB_TYPE_MP2A: - mdecoder->codec_id = CODEC_ID_MP2; + mdecoder->codec_id = AV_CODEC_ID_MP2; break; case TSMF_SUB_TYPE_MP2V: - mdecoder->codec_id = CODEC_ID_MPEG2VIDEO; + mdecoder->codec_id = AV_CODEC_ID_MPEG2VIDEO; break; case TSMF_SUB_TYPE_WMV3: - mdecoder->codec_id = CODEC_ID_WMV3; + mdecoder->codec_id = AV_CODEC_ID_WMV3; break; case TSMF_SUB_TYPE_AAC: - mdecoder->codec_id = CODEC_ID_AAC; + mdecoder->codec_id = AV_CODEC_ID_AAC; /* For AAC the pFormat is a HEAACWAVEINFO struct, and the codec data is at the end of it. See http://msdn.microsoft.com/en-us/library/dd757806.aspx */ @@ -246,10 +262,10 @@ static BOOL tsmf_ffmpeg_set_format(ITSMFDecoder *decoder, TS_AM_MEDIA_TYPE *medi break; case TSMF_SUB_TYPE_H264: case TSMF_SUB_TYPE_AVC1: - mdecoder->codec_id = CODEC_ID_H264; + mdecoder->codec_id = AV_CODEC_ID_H264; break; case TSMF_SUB_TYPE_AC3: - mdecoder->codec_id = CODEC_ID_AC3; + mdecoder->codec_id = AV_CODEC_ID_AC3; break; default: return FALSE; @@ -285,13 +301,13 @@ static BOOL tsmf_ffmpeg_decode_video(ITSMFDecoder *decoder, const BYTE *data, UI #endif if(len < 0) { - DEBUG_WARN("data_size %d, avcodec_decode_video failed (%d)", data_size, len); + CLOG_ERR("data_size %d, avcodec_decode_video failed (%d)", data_size, len); ret = FALSE; } else if(!decoded) { - DEBUG_WARN("data_size %d, no frame is decoded.", data_size); + CLOG_ERR("data_size %d, no frame is decoded.", data_size); ret = FALSE; } else @@ -387,7 +403,7 @@ static BOOL tsmf_ffmpeg_decode_audio(ITSMFDecoder *decoder, const BYTE *data, UI #endif if(len <= 0 || frame_size <= 0) { - DEBUG_WARN("error decoding"); + CLOG_ERR("error decoding"); break; } src += len; @@ -427,7 +443,7 @@ static BOOL tsmf_ffmpeg_decode(ITSMFDecoder *decoder, const BYTE *data, UINT32 d case AVMEDIA_TYPE_AUDIO: return tsmf_ffmpeg_decode_audio(decoder, data, data_size, extensions); default: - DEBUG_WARN("unknown media type."); + CLOG_ERR("unknown media type."); return FALSE; } } @@ -451,7 +467,7 @@ static UINT32 tsmf_ffmpeg_get_decoded_format(ITSMFDecoder *decoder) case PIX_FMT_YUV420P: return RDP_PIXFMT_I420; default: - DEBUG_WARN("unsupported pixel format %u", + CLOG_ERR("unsupported pixel format %u", mdecoder->codec_context->pix_fmt); return (UINT32) -1; } @@ -504,7 +520,7 @@ ITSMFDecoder *freerdp_tsmf_client_decoder_subsystem_entry(void) avcodec_register_all(); initialized = TRUE; } - fprintf(stderr, "TSMFDecoderEntry FFMPEG\n"); + CLOG_ERR( "TSMFDecoderEntry FFMPEG\n"); decoder = (TSMFFFmpegDecoder *) malloc(sizeof(TSMFFFmpegDecoder)); ZeroMemory(decoder, sizeof(TSMFFFmpegDecoder)); decoder->iface.SetFormat = tsmf_ffmpeg_set_format; diff --git a/channels/tsmf/client/gstreamer/tsmf_X11.c b/channels/tsmf/client/gstreamer/tsmf_X11.c index 6acc6eeb3..8db874b12 100644 --- a/channels/tsmf/client/gstreamer/tsmf_X11.c +++ b/channels/tsmf/client/gstreamer/tsmf_X11.c @@ -87,7 +87,7 @@ int tsmf_platform_create(TSMFGstreamerDecoder *decoder) if (!hdl) { - DEBUG_WARN("%s: Could not allocate handle.", __func__); + CLOG_ERR("%s: Could not allocate handle.", __func__); return -1; } @@ -97,7 +97,7 @@ int tsmf_platform_create(TSMFGstreamerDecoder *decoder) if (hdl->shmid < 0) { - DEBUG_WARN("%s: failed to get access to shared memory - shmget()", + CLOG_ERR("%s: failed to get access to shared memory - shmget()", __func__); return -2; } @@ -106,7 +106,7 @@ int tsmf_platform_create(TSMFGstreamerDecoder *decoder) if (hdl->xfwin == (int *)-1) { - DEBUG_WARN("%s: shmat failed!", __func__); + CLOG_ERR("%s: shmat failed!", __func__); return -3; } @@ -114,7 +114,7 @@ int tsmf_platform_create(TSMFGstreamerDecoder *decoder) if (!hdl->disp) { - DEBUG_WARN("Failed to open display"); + CLOG_ERR("Failed to open display"); return -4; } @@ -140,7 +140,7 @@ int tsmf_platform_register_handler(TSMFGstreamerDecoder *decoder) if (!bus) { - DEBUG_WARN("gst_pipeline_get_bus failed!"); + CLOG_ERR("gst_pipeline_get_bus failed!"); return 1; } @@ -193,7 +193,7 @@ int tsmf_window_create(TSMFGstreamerDecoder *decoder) if (!hdl->subwin) { - DEBUG_WARN("Could not create subwindow!"); + CLOG_ERR("Could not create subwindow!"); } XMapWindow(hdl->disp, hdl->subwin); @@ -238,14 +238,14 @@ int tsmf_window_resize(TSMFGstreamerDecoder *decoder, int x, int y, int width, if (!gst_video_overlay_set_render_rectangle(overlay, 0, 0, width, height)) { - DEBUG_WARN("Could not resize overlay!"); + CLOG_ERR("Could not resize overlay!"); } gst_video_overlay_expose(overlay); #else if (!gst_x_overlay_set_render_rectangle(overlay, 0, 0, width, height)) { - DEBUG_WARN("Could not resize overlay!"); + CLOG_ERR("Could not resize overlay!"); } gst_x_overlay_expose(overlay); diff --git a/channels/tsmf/client/gstreamer/tsmf_gstreamer.c b/channels/tsmf/client/gstreamer/tsmf_gstreamer.c index 33a609bef..b4c8635d2 100644 --- a/channels/tsmf/client/gstreamer/tsmf_gstreamer.c +++ b/channels/tsmf/client/gstreamer/tsmf_gstreamer.c @@ -120,10 +120,10 @@ int tsmf_gstreamer_pipeline_set_state(TSMFGstreamerDecoder *mdecoder, GstState d state_change = gst_element_set_state(mdecoder->pipe, desired_state); if (state_change == GST_STATE_CHANGE_FAILURE) - DEBUG_WARN("%s: (%s) GST_STATE_CHANGE_FAILURE.", sname, name); + CLOG_ERR("%s: (%s) GST_STATE_CHANGE_FAILURE.", sname, name); else if (state_change == GST_STATE_CHANGE_ASYNC) { - DEBUG_WARN("%s: (%s) GST_STATE_CHANGE_ASYNC.", sname, name); + CLOG_ERR("%s: (%s) GST_STATE_CHANGE_ASYNC.", sname, name); mdecoder->state = desired_state; } else @@ -142,7 +142,7 @@ static GstBuffer *tsmf_get_buffer_from_data(const void *raw_data, gsize size) if (!data) { - DEBUG_WARN("Could not allocate %"G_GSIZE_FORMAT" bytes of data.", size); + CLOG_ERR("Could not allocate %"G_GSIZE_FORMAT" bytes of data.", size); return NULL; } @@ -154,7 +154,7 @@ static GstBuffer *tsmf_get_buffer_from_data(const void *raw_data, gsize size) if (!buffer) { - DEBUG_WARN("Could not create GstBuffer"); + CLOG_ERR("Could not create GstBuffer"); free(data); return NULL; } @@ -346,7 +346,7 @@ static BOOL tsmf_gstreamer_set_format(ITSMFDecoder *decoder, TS_AM_MEDIA_TYPE *m NULL); break; default: - DEBUG_WARN("unknown format:(%d).", media_type->SubType); + CLOG_ERR("unknown format:(%d).", media_type->SubType); return FALSE; } @@ -358,7 +358,7 @@ static BOOL tsmf_gstreamer_set_format(ITSMFDecoder *decoder, TS_AM_MEDIA_TYPE *m if (!buffer) { - DEBUG_WARN("could not allocate GstBuffer!"); + CLOG_ERR("could not allocate GstBuffer!"); return FALSE; } @@ -416,7 +416,7 @@ BOOL tsmf_gstreamer_pipeline_build(TSMFGstreamerDecoder *mdecoder) if (!mdecoder->pipe) { - DEBUG_WARN("Failed to create new pipe"); + CLOG_ERR("Failed to create new pipe"); return FALSE; } @@ -424,7 +424,7 @@ BOOL tsmf_gstreamer_pipeline_build(TSMFGstreamerDecoder *mdecoder) if (!mdecoder->src) { - DEBUG_WARN("Failed to get appsrc"); + CLOG_ERR("Failed to get appsrc"); return FALSE; } @@ -432,7 +432,7 @@ BOOL tsmf_gstreamer_pipeline_build(TSMFGstreamerDecoder *mdecoder) if (!mdecoder->outsink) { - DEBUG_WARN("Failed to get sink"); + CLOG_ERR("Failed to get sink"); return FALSE; } @@ -442,7 +442,7 @@ BOOL tsmf_gstreamer_pipeline_build(TSMFGstreamerDecoder *mdecoder) if (!mdecoder->volume) { - DEBUG_WARN("Failed to get volume"); + CLOG_ERR("Failed to get volume"); return FALSE; } } @@ -482,7 +482,7 @@ static BOOL tsmf_gstreamer_decodeEx(ITSMFDecoder *decoder, const BYTE *data, UIN if (!mdecoder) { - DEBUG_WARN("Decoder not initialized!"); + CLOG_ERR("Decoder not initialized!"); return FALSE; } @@ -498,13 +498,13 @@ static BOOL tsmf_gstreamer_decodeEx(ITSMFDecoder *decoder, const BYTE *data, UIN if (mdecoder->gst_caps == NULL) { - DEBUG_WARN("tsmf_gstreamer_set_format not called or invalid format."); + CLOG_ERR("tsmf_gstreamer_set_format not called or invalid format."); return FALSE; } if (!mdecoder->src) { - DEBUG_WARN("failed to construct pipeline correctly. Unable to push buffer to source element."); + CLOG_ERR("failed to construct pipeline correctly. Unable to push buffer to source element."); return FALSE; } @@ -512,7 +512,7 @@ static BOOL tsmf_gstreamer_decodeEx(ITSMFDecoder *decoder, const BYTE *data, UIN if (gst_buf == NULL) { - DEBUG_WARN("tsmf_get_buffer_from_data(%p, %d) failed.", data, data_size); + CLOG_ERR("tsmf_get_buffer_from_data(%p, %d) failed.", data, data_size); return FALSE; } @@ -534,7 +534,7 @@ static BOOL tsmf_gstreamer_decodeEx(ITSMFDecoder *decoder, const BYTE *data, UIN GST_SEEK_TYPE_SET, sample_time, GST_SEEK_TYPE_NONE, GST_CLOCK_TIME_NONE)) { - DEBUG_WARN("seek failed"); + CLOG_ERR("seek failed"); } mdecoder->pipeline_start_time_valid = 0; @@ -608,7 +608,7 @@ static void tsmf_gstreamer_control(ITSMFDecoder *decoder, ITSMFControlMsg contro if (mdecoder->paused) { - DEBUG_WARN("%s: Ignoring control PAUSE, already received!", get_type(mdecoder)); + CLOG_ERR("%s: Ignoring control PAUSE, already received!", get_type(mdecoder)); return; } @@ -624,7 +624,7 @@ static void tsmf_gstreamer_control(ITSMFDecoder *decoder, ITSMFControlMsg contro if (!mdecoder->paused && !mdecoder->shutdown) { - DEBUG_WARN("%s: Ignoring control RESUME, already received!", get_type(mdecoder)); + CLOG_ERR("%s: Ignoring control RESUME, already received!", get_type(mdecoder)); return; } @@ -642,7 +642,7 @@ static void tsmf_gstreamer_control(ITSMFDecoder *decoder, ITSMFControlMsg contro if (mdecoder->shutdown) { - DEBUG_WARN("%s: Ignoring control STOP, already received!", get_type(mdecoder)); + CLOG_ERR("%s: Ignoring control STOP, already received!", get_type(mdecoder)); return; } @@ -656,7 +656,7 @@ static void tsmf_gstreamer_control(ITSMFDecoder *decoder, ITSMFControlMsg contro gst_app_src_end_of_stream((GstAppSrc *)mdecoder->src); } else - DEBUG_WARN("Unknown control message %08x", control_msg); + CLOG_ERR("Unknown control message %08x", control_msg); } static BOOL tsmf_gstreamer_buffer_filled(ITSMFDecoder *decoder) diff --git a/channels/tsmf/client/pulse/tsmf_pulse.c b/channels/tsmf/client/pulse/tsmf_pulse.c index 8b476eb23..c04c5b3ea 100644 --- a/channels/tsmf/client/pulse/tsmf_pulse.c +++ b/channels/tsmf/client/pulse/tsmf_pulse.c @@ -72,7 +72,7 @@ static BOOL tsmf_pulse_connect(TSMFPulseAudioDevice *pulse) return FALSE; if(pa_context_connect(pulse->context, NULL, 0, NULL)) { - DEBUG_WARN("pa_context_connect failed (%d)", + CLOG_ERR("pa_context_connect failed (%d)", pa_context_errno(pulse->context)); return FALSE; } @@ -80,7 +80,7 @@ static BOOL tsmf_pulse_connect(TSMFPulseAudioDevice *pulse) if(pa_threaded_mainloop_start(pulse->mainloop) < 0) { pa_threaded_mainloop_unlock(pulse->mainloop); - DEBUG_WARN("pa_threaded_mainloop_start failed (%d)", + CLOG_ERR("pa_threaded_mainloop_start failed (%d)", pa_context_errno(pulse->context)); return FALSE; } @@ -120,19 +120,19 @@ static BOOL tsmf_pulse_open(ITSMFAudioDevice *audio, const char *device) pulse->mainloop = pa_threaded_mainloop_new(); if(!pulse->mainloop) { - DEBUG_WARN("pa_threaded_mainloop_new failed"); + CLOG_ERR("pa_threaded_mainloop_new failed"); return FALSE; } pulse->context = pa_context_new(pa_threaded_mainloop_get_api(pulse->mainloop), "freerdp"); if(!pulse->context) { - DEBUG_WARN("pa_context_new failed"); + CLOG_ERR("pa_context_new failed"); return FALSE; } pa_context_set_state_callback(pulse->context, tsmf_pulse_context_state_callback, pulse); if(tsmf_pulse_connect(pulse)) { - DEBUG_WARN("tsmf_pulse_connect failed"); + CLOG_ERR("tsmf_pulse_connect failed"); return FALSE; } DEBUG_TSMF("open device %s", pulse->device); @@ -214,7 +214,7 @@ static BOOL tsmf_pulse_open_stream(TSMFPulseAudioDevice *pulse) if(!pulse->stream) { pa_threaded_mainloop_unlock(pulse->mainloop); - DEBUG_WARN("pa_stream_new failed (%d)", + CLOG_ERR("pa_stream_new failed (%d)", pa_context_errno(pulse->context)); return FALSE; } @@ -233,7 +233,7 @@ static BOOL tsmf_pulse_open_stream(TSMFPulseAudioDevice *pulse) NULL, NULL) < 0) { pa_threaded_mainloop_unlock(pulse->mainloop); - DEBUG_WARN("pa_stream_connect_playback failed (%d)", + CLOG_ERR("pa_stream_connect_playback failed (%d)", pa_context_errno(pulse->context)); return FALSE; } @@ -244,7 +244,7 @@ static BOOL tsmf_pulse_open_stream(TSMFPulseAudioDevice *pulse) break; if(!PA_STREAM_IS_GOOD(state)) { - DEBUG_WARN("bad stream state (%d)", + CLOG_ERR("bad stream state (%d)", pa_context_errno(pulse->context)); break; } diff --git a/channels/tsmf/client/tsmf_audio.c b/channels/tsmf/client/tsmf_audio.c index 6c7ab2ed6..4e43ba80f 100644 --- a/channels/tsmf/client/tsmf_audio.c +++ b/channels/tsmf/client/tsmf_audio.c @@ -41,7 +41,7 @@ static ITSMFAudioDevice* tsmf_load_audio_device_by_name(const char* name, const if (audio == NULL) { - DEBUG_WARN("failed to call export function in %s", name); + CLOG_ERR("failed to call export function in %s", name); return NULL; } diff --git a/channels/tsmf/client/tsmf_codec.c b/channels/tsmf/client/tsmf_codec.c index 5fac84991..e56400aea 100644 --- a/channels/tsmf/client/tsmf_codec.c +++ b/channels/tsmf/client/tsmf_codec.c @@ -264,21 +264,21 @@ static void tsmf_print_guid(const BYTE *guid) #ifdef WITH_DEBUG_TSMF int i; for(i = 3; i >= 0; i--) - fprintf(stderr, "%02X", guid[i]); - fprintf(stderr, "-"); + CLOG_ERR( "%02X", guid[i]); + CLOG_ERR( "-"); for(i = 5; i >= 4; i--) - fprintf(stderr, "%02X", guid[i]); - fprintf(stderr, "-"); + CLOG_ERR( "%02X", guid[i]); + CLOG_ERR( "-"); for(i = 7; i >= 6; i--) - fprintf(stderr, "%02X", guid[i]); - fprintf(stderr, "-"); + CLOG_ERR( "%02X", guid[i]); + CLOG_ERR( "-"); for(i = 8; i < 16; i++) { - fprintf(stderr, "%02X", guid[i]); + CLOG_ERR( "%02X", guid[i]); if(i == 9) - fprintf(stderr, "-"); + CLOG_ERR( "-"); } - fprintf(stderr, "\n"); + CLOG_ERR( "\n"); #endif } diff --git a/channels/tsmf/client/tsmf_decoder.c b/channels/tsmf/client/tsmf_decoder.c index 3d17c60d0..59262508c 100644 --- a/channels/tsmf/client/tsmf_decoder.c +++ b/channels/tsmf/client/tsmf_decoder.c @@ -42,7 +42,7 @@ static ITSMFDecoder *tsmf_load_decoder_by_name(const char *name, TS_AM_MEDIA_TYP decoder = entry(); if(decoder == NULL) { - DEBUG_WARN("failed to call export function in %s", name); + CLOG_ERR("failed to call export function in %s", name); return NULL; } if(!decoder->SetFormat(decoder, media_type)) diff --git a/channels/tsmf/client/tsmf_ifman.c b/channels/tsmf/client/tsmf_ifman.c index 40e89e439..6c2d99b9b 100644 --- a/channels/tsmf/client/tsmf_ifman.c +++ b/channels/tsmf/client/tsmf_ifman.c @@ -80,7 +80,7 @@ int tsmf_ifman_exchange_capability_request(TSMF_IFMAN *ifman) MMREDIR_CAPABILITY_PLATFORM_MF | MMREDIR_CAPABILITY_PLATFORM_DSHOW); break; default: - DEBUG_WARN("unknown capability type %d", CapabilityType); + CLOG_ERR("unknown capability type %d", CapabilityType); break; } Stream_SetPosition(ifman->output, pos + cbCapabilityLength); @@ -236,7 +236,7 @@ int tsmf_ifman_shutdown_presentation(TSMF_IFMAN *ifman) if(presentation) tsmf_presentation_free(presentation); else - DEBUG_WARN("unknown presentation id"); + CLOG_ERR("unknown presentation id"); Stream_EnsureRemainingCapacity(ifman->output, 4); Stream_Write_UINT32(ifman->output, 0); /* Result */ ifman->output_interface_id = TSMF_INTERFACE_DEFAULT | STREAM_ID_STUB; @@ -261,7 +261,7 @@ int tsmf_ifman_on_stream_volume(TSMF_IFMAN *ifman) } else { - DEBUG_WARN("unknown presentation id"); + CLOG_ERR("unknown presentation id"); } ifman->output_pending = TRUE; return 0; @@ -393,13 +393,13 @@ int tsmf_ifman_on_sample(TSMF_IFMAN *ifman) presentation = tsmf_presentation_find_by_id(ifman->presentation_id); if(presentation == NULL) { - DEBUG_WARN("unknown presentation id"); + CLOG_ERR("unknown presentation id"); return 1; } stream = tsmf_stream_find_by_id(presentation, StreamId); if(stream == NULL) { - DEBUG_WARN("unknown stream id"); + CLOG_ERR("unknown stream id"); return 1; } tsmf_stream_push_sample(stream, ifman->channel_callback, @@ -420,7 +420,7 @@ int tsmf_ifman_on_flush(TSMF_IFMAN *ifman) presentation = tsmf_presentation_find_by_id(ifman->presentation_id); if(presentation == NULL) { - DEBUG_WARN("unknown presentation id"); + CLOG_ERR("unknown presentation id"); return 1; } tsmf_presentation_flush(presentation); @@ -460,7 +460,7 @@ int tsmf_ifman_on_playback_started(TSMF_IFMAN *ifman) if(presentation) tsmf_presentation_start(presentation); else - DEBUG_WARN("unknown presentation id"); + CLOG_ERR("unknown presentation id"); Stream_EnsureRemainingCapacity(ifman->output, 16); Stream_Write_UINT32(ifman->output, CLIENT_EVENT_NOTIFICATION); /* FunctionId */ Stream_Write_UINT32(ifman->output, 0); /* StreamId */ @@ -480,7 +480,7 @@ int tsmf_ifman_on_playback_paused(TSMF_IFMAN *ifman) if(presentation) tsmf_presentation_paused(presentation); else - DEBUG_WARN("unknown presentation id"); + CLOG_ERR("unknown presentation id"); return 0; } @@ -494,7 +494,7 @@ int tsmf_ifman_on_playback_restarted(TSMF_IFMAN *ifman) if(presentation) tsmf_presentation_restarted(presentation); else - DEBUG_WARN("unknown presentation id"); + CLOG_ERR("unknown presentation id"); return 0; } @@ -506,7 +506,7 @@ int tsmf_ifman_on_playback_stopped(TSMF_IFMAN *ifman) if(presentation) tsmf_presentation_stop(presentation); else - DEBUG_WARN("unknown presentation id"); + CLOG_ERR("unknown presentation id"); Stream_EnsureRemainingCapacity(ifman->output, 16); Stream_Write_UINT32(ifman->output, CLIENT_EVENT_NOTIFICATION); /* FunctionId */ Stream_Write_UINT32(ifman->output, 0); /* StreamId */ diff --git a/channels/tsmf/client/tsmf_main.c b/channels/tsmf/client/tsmf_main.c index e6fd20530..76b0a7c32 100644 --- a/channels/tsmf/client/tsmf_main.c +++ b/channels/tsmf/client/tsmf_main.c @@ -89,14 +89,14 @@ void tsmf_playback_ack(IWTSVirtualChannelCallback *pChannelCallback, Stream_Write_UINT64(s, data_size); /* cbData */ DEBUG_TSMF("response size %d", (int) Stream_GetPosition(s)); if(!callback || !callback->channel || !callback->channel->Write) - DEBUG_WARN("callback=%p, channel=%p, write=%p", callback, + CLOG_ERR("callback=%p, channel=%p, write=%p", callback, callback->channel, callback->channel->Write); else status = callback->channel->Write(callback->channel, Stream_GetPosition(s), Stream_Buffer(s), NULL); if(status) { - DEBUG_WARN("response error %d", status); + CLOG_ERR("response error %d", status); } Stream_Free(s, TRUE); } @@ -108,7 +108,7 @@ BOOL tsmf_push_event(IWTSVirtualChannelCallback *pChannelCallback, wMessage *eve status = callback->channel_mgr->PushEvent(callback->channel_mgr, event); if(status) { - DEBUG_WARN("response error %d", status); + CLOG_ERR("response error %d", status); return FALSE; } return TRUE; @@ -130,7 +130,7 @@ static int tsmf_on_data_received(IWTSVirtualChannelCallback* pChannelCallback, w /* 2.2.1 Shared Message Header (SHARED_MSG_HEADER) */ if(cbSize < 12) { - DEBUG_WARN("invalid size. cbSize=%d", cbSize); + CLOG_ERR("invalid size. cbSize=%d", cbSize); return 1; } @@ -272,7 +272,7 @@ static int tsmf_on_data_received(IWTSVirtualChannelCallback* pChannelCallback, w } if(status == -1) { - DEBUG_WARN("InterfaceId 0x%X FunctionId 0x%X not processed.", + CLOG_ERR("InterfaceId 0x%X FunctionId 0x%X not processed.", InterfaceId, FunctionId); /* When a request is not implemented we return empty response indicating error */ } @@ -289,7 +289,7 @@ static int tsmf_on_data_received(IWTSVirtualChannelCallback* pChannelCallback, w status = callback->channel->Write(callback->channel, length, Stream_Buffer(output), NULL); if(status) { - DEBUG_WARN("response error %d", status); + CLOG_ERR("response error %d", status); } } Stream_Free(output, TRUE); diff --git a/channels/tsmf/client/tsmf_media.c b/channels/tsmf/client/tsmf_media.c index 51465554b..611f80365 100644 --- a/channels/tsmf/client/tsmf_media.c +++ b/channels/tsmf/client/tsmf_media.c @@ -271,7 +271,7 @@ TSMF_PRESENTATION *tsmf_presentation_new(const BYTE *guid, IWTSVirtualChannelCal if (!presentation) { - DEBUG_WARN("calloc failed"); + CLOG_ERR("calloc failed"); return NULL; } @@ -320,7 +320,7 @@ TSMF_PRESENTATION *tsmf_presentation_find_by_id(const BYTE *guid) ArrayList_Unlock(presentation_list); if (!found) - DEBUG_WARN("presentation id %s not found", guid_to_string(guid, guid_str, sizeof(guid_str))); + CLOG_ERR("presentation id %s not found", guid_to_string(guid, guid_str, sizeof(guid_str))); return (found) ? presentation : NULL; } @@ -902,7 +902,7 @@ TSMF_STREAM *tsmf_stream_new(TSMF_PRESENTATION *presentation, UINT32 stream_id) if (stream) { - DEBUG_WARN("duplicated stream id %d!", stream_id); + CLOG_ERR("duplicated stream id %d!", stream_id); return NULL; } @@ -910,7 +910,7 @@ TSMF_STREAM *tsmf_stream_new(TSMF_PRESENTATION *presentation, UINT32 stream_id) if (!stream) { - DEBUG_WARN("Calloc failed"); + CLOG_ERR("Calloc failed"); return NULL; } @@ -966,7 +966,7 @@ void tsmf_stream_set_format(TSMF_STREAM *stream, const char *name, wStream *s) if (stream->decoder) { - DEBUG_WARN("duplicated call"); + CLOG_ERR("duplicated call"); return; } @@ -1071,7 +1071,7 @@ void tsmf_stream_push_sample(TSMF_STREAM *stream, IWTSVirtualChannelCallback *pC if (!sample) { - DEBUG_WARN("calloc failed!"); + CLOG_ERR("calloc failed!"); return; } @@ -1087,7 +1087,7 @@ void tsmf_stream_push_sample(TSMF_STREAM *stream, IWTSVirtualChannelCallback *pC if (!sample->data) { - DEBUG_WARN("calloc failed!"); + CLOG_ERR("calloc failed!"); free(sample); return; } diff --git a/channels/tsmf/client/tsmf_types.h b/channels/tsmf/client/tsmf_types.h index 4911209d4..4afbd1434 100644 --- a/channels/tsmf/client/tsmf_types.h +++ b/channels/tsmf/client/tsmf_types.h @@ -26,12 +26,12 @@ #include #include -#include +#include #ifdef WITH_DEBUG_TSMF -#define DEBUG_TSMF(fmt, ...) DEBUG_CLASS(TSMF, fmt, ## __VA_ARGS__) +#define DEBUG_TSMF(fmt, ...) CLOG_CLASS(TSMF, fmt, ## __VA_ARGS__) #else -#define DEBUG_TSMF(fmt, ...) DEBUG_NULL(fmt, ## __VA_ARGS__) +#define DEBUG_TSMF(fmt, ...) CLOG_NULL(fmt, ## __VA_ARGS__) #endif typedef struct _TS_AM_MEDIA_TYPE diff --git a/channels/urbdrc/client/data_transfer.c b/channels/urbdrc/client/data_transfer.c index f0aa961d1..dec8e547e 100644 --- a/channels/urbdrc/client/data_transfer.c +++ b/channels/urbdrc/client/data_transfer.c @@ -237,7 +237,7 @@ static int urbdrc_process_io_control(URBDRC_CHANNEL_CALLBACK* callback, BYTE* da { case IOCTL_INTERNAL_USB_SUBMIT_URB: /** 0x00220003 */ LLOGLN(urbdrc_debug, ("ioctl: IOCTL_INTERNAL_USB_SUBMIT_URB")); - fprintf(stderr, " Function IOCTL_INTERNAL_USB_SUBMIT_URB: Unchecked\n"); + CLOG_ERR( " Function IOCTL_INTERNAL_USB_SUBMIT_URB: Unchecked\n"); break; case IOCTL_INTERNAL_USB_RESET_PORT: /** 0x00220007 */ @@ -269,12 +269,12 @@ static int urbdrc_process_io_control(URBDRC_CHANNEL_CALLBACK* callback, BYTE* da case IOCTL_INTERNAL_USB_CYCLE_PORT: /** 0x0022001F */ LLOGLN(urbdrc_debug, ("ioctl: IOCTL_INTERNAL_USB_CYCLE_PORT")); - fprintf(stderr, " Function IOCTL_INTERNAL_USB_CYCLE_PORT: Unchecked\n"); + CLOG_ERR( " Function IOCTL_INTERNAL_USB_CYCLE_PORT: Unchecked\n"); break; case IOCTL_INTERNAL_USB_SUBMIT_IDLE_NOTIFICATION: /** 0x00220027 */ LLOGLN(urbdrc_debug, ("ioctl: IOCTL_INTERNAL_USB_SUBMIT_IDLE_NOTIFICATION")); - fprintf(stderr, " Function IOCTL_INTERNAL_USB_SUBMIT_IDLE_NOTIFICATION: Unchecked\n"); + CLOG_ERR( " Function IOCTL_INTERNAL_USB_SUBMIT_IDLE_NOTIFICATION: Unchecked\n"); break; default: @@ -448,7 +448,7 @@ static int urb_select_configuration(URBDRC_CHANNEL_CALLBACK* callback, BYTE* dat if (transferDir == 0) { - fprintf(stderr, "urb_select_configuration: not support transfer out\n"); + CLOG_ERR( "urb_select_configuration: not support transfer out\n"); return -1; } @@ -540,7 +540,7 @@ static int urb_select_interface(URBDRC_CHANNEL_CALLBACK* callback, BYTE* data, U if (transferDir == 0) { - fprintf(stderr, "urb_select_interface: not support transfer out\n"); + CLOG_ERR( "urb_select_interface: not support transfer out\n"); return -1; } @@ -1297,7 +1297,7 @@ static int urb_os_feature_descriptor_request(URBDRC_CHANNEL_CALLBACK * callback, switch (transferDir) { case USBD_TRANSFER_DIRECTION_OUT: - fprintf(stderr, "Function urb_os_feature_descriptor_request: OUT Unchecked\n"); + CLOG_ERR( "Function urb_os_feature_descriptor_request: OUT Unchecked\n"); memcpy(buffer, data + offset, OutputBufferSize); break; case USBD_TRANSFER_DIRECTION_IN: @@ -1700,7 +1700,7 @@ static int urb_control_feature_request(URBDRC_CHANNEL_CALLBACK * callback, BYTE switch (transferDir) { case USBD_TRANSFER_DIRECTION_OUT: - fprintf(stderr, "Function urb_control_feature_request: OUT Unchecked\n"); + CLOG_ERR( "Function urb_control_feature_request: OUT Unchecked\n"); memcpy(buffer, data + offset, OutputBufferSize); bmRequestType |= 0x00; break; @@ -1718,7 +1718,7 @@ static int urb_control_feature_request(URBDRC_CHANNEL_CALLBACK * callback, BYTE bmRequest = 0x01; /* REQUEST_CLEAR_FEATURE */ break; default: - fprintf(stderr, "urb_control_feature_request: Error Command %x\n", command); + CLOG_ERR( "urb_control_feature_request: Error Command %x\n", command); zfree(out_data); return -1; } diff --git a/channels/urbdrc/client/libusb/libusb_udevice.c b/channels/urbdrc/client/libusb/libusb_udevice.c index 82775fffb..bb1ead0ca 100644 --- a/channels/urbdrc/client/libusb/libusb_udevice.c +++ b/channels/urbdrc/client/libusb/libusb_udevice.c @@ -201,7 +201,7 @@ static void func_iso_callback(struct libusb_transfer *transfer) } else { - //fprintf(stderr, "actual length %d \n", act_len); + //CLOG_ERR( "actual length %d \n", act_len); //exit(EXIT_FAILURE); } } @@ -362,7 +362,7 @@ static int func_config_release_all_interface(LIBUSB_DEVICE_HANDLE* libusb_handle if (ret < 0) { - fprintf(stderr, "config_release_all_interface: error num %d\n", ret); + CLOG_ERR( "config_release_all_interface: error num %d\n", ret); return -1; } } @@ -380,7 +380,7 @@ static int func_claim_all_interface(LIBUSB_DEVICE_HANDLE* libusb_handle, int Num if (ret < 0) { - fprintf(stderr, "claim_all_interface: error num %d\n", ret); + CLOG_ERR( "claim_all_interface: error num %d\n", ret); return -1; } } @@ -394,28 +394,28 @@ static void* print_transfer_status(enum libusb_transfer_status status) switch (status) { case LIBUSB_TRANSFER_COMPLETED: - //fprintf(stderr, "Transfer Status: LIBUSB_TRANSFER_COMPLETED\n"); + //CLOG_ERR( "Transfer Status: LIBUSB_TRANSFER_COMPLETED\n"); break; case LIBUSB_TRANSFER_ERROR: - fprintf(stderr, "Transfer Status: LIBUSB_TRANSFER_ERROR\n"); + CLOG_ERR( "Transfer Status: LIBUSB_TRANSFER_ERROR\n"); break; case LIBUSB_TRANSFER_TIMED_OUT: - fprintf(stderr, "Transfer Status: LIBUSB_TRANSFER_TIMED_OUT\n"); + CLOG_ERR( "Transfer Status: LIBUSB_TRANSFER_TIMED_OUT\n"); break; case LIBUSB_TRANSFER_CANCELLED: - fprintf(stderr, "Transfer Status: LIBUSB_TRANSFER_CANCELLED\n"); + CLOG_ERR( "Transfer Status: LIBUSB_TRANSFER_CANCELLED\n"); break; case LIBUSB_TRANSFER_STALL: - fprintf(stderr, "Transfer Status: LIBUSB_TRANSFER_STALL\n"); + CLOG_ERR( "Transfer Status: LIBUSB_TRANSFER_STALL\n"); break; case LIBUSB_TRANSFER_NO_DEVICE: - fprintf(stderr, "Transfer Status: LIBUSB_TRANSFER_NO_DEVICE\n"); + CLOG_ERR( "Transfer Status: LIBUSB_TRANSFER_NO_DEVICE\n"); break; case LIBUSB_TRANSFER_OVERFLOW: - fprintf(stderr, "Transfer Status: LIBUSB_TRANSFER_OVERFLOW\n"); + CLOG_ERR( "Transfer Status: LIBUSB_TRANSFER_OVERFLOW\n"); break; default: - fprintf(stderr, "Transfer Status: Get unknow error num %d (0x%x)\n", + CLOG_ERR( "Transfer Status: Get unknow error num %d (0x%x)\n", status, status); } return 0; @@ -426,28 +426,28 @@ static void print_status(enum libusb_transfer_status status) switch (status) { case LIBUSB_TRANSFER_COMPLETED: - fprintf(stderr, "Transfer status: LIBUSB_TRANSFER_COMPLETED\n"); + CLOG_ERR( "Transfer status: LIBUSB_TRANSFER_COMPLETED\n"); break; case LIBUSB_TRANSFER_ERROR: - fprintf(stderr, "Transfer status: LIBUSB_TRANSFER_ERROR\n"); + CLOG_ERR( "Transfer status: LIBUSB_TRANSFER_ERROR\n"); break; case LIBUSB_TRANSFER_TIMED_OUT: - fprintf(stderr, "Transfer status: LIBUSB_TRANSFER_TIMED_OUT\n"); + CLOG_ERR( "Transfer status: LIBUSB_TRANSFER_TIMED_OUT\n"); break; case LIBUSB_TRANSFER_CANCELLED: - fprintf(stderr, "Transfer status: LIBUSB_TRANSFER_CANCELLED\n"); + CLOG_ERR( "Transfer status: LIBUSB_TRANSFER_CANCELLED\n"); break; case LIBUSB_TRANSFER_STALL: - fprintf(stderr, "Transfer status: LIBUSB_TRANSFER_STALL\n"); + CLOG_ERR( "Transfer status: LIBUSB_TRANSFER_STALL\n"); break; case LIBUSB_TRANSFER_NO_DEVICE: - fprintf(stderr, "Transfer status: LIBUSB_TRANSFER_NO_DEVICE\n"); + CLOG_ERR( "Transfer status: LIBUSB_TRANSFER_NO_DEVICE\n"); break; case LIBUSB_TRANSFER_OVERFLOW: - fprintf(stderr, "Transfer status: LIBUSB_TRANSFER_OVERFLOW\n"); + CLOG_ERR( "Transfer status: LIBUSB_TRANSFER_OVERFLOW\n"); break; default: - fprintf(stderr, "Transfer status: unknow status %d(0x%x)\n", status, status); + CLOG_ERR( "Transfer status: unknow status %d(0x%x)\n", status, status); break; } } @@ -484,7 +484,7 @@ static LIBUSB_DEVICE_DESCRIPTOR* udev_new_descript(LIBUSB_DEVICE* libusb_dev) if (ret < 0) { - fprintf(stderr, "libusb_get_device_descriptor: ERROR!!\n"); + CLOG_ERR( "libusb_get_device_descriptor: ERROR!!\n"); free(descriptor); return NULL; } @@ -654,7 +654,7 @@ static int libusb_udev_select_interface(IUDEVICE* idev, BYTE InterfaceNumber, BY if (error < 0) { - fprintf(stderr, "%s: Set interface altsetting get error num %d\n", + CLOG_ERR( "%s: Set interface altsetting get error num %d\n", __func__, error); } } @@ -681,7 +681,7 @@ static MSUSB_CONFIG_DESCRIPTOR* libusb_udev_complete_msconfig_setup(IUDEVICE* id LibusbConfig = pdev->LibusbConfig; if (LibusbConfig->bNumInterfaces != MsConfig->NumInterfaces) { - fprintf(stderr, "Select Configuration: Libusb NumberInterfaces(%d) is different " + CLOG_ERR( "Select Configuration: Libusb NumberInterfaces(%d) is different " "with MsConfig NumberInterfaces(%d)\n", LibusbConfig->bNumInterfaces, MsConfig->NumInterfaces); } @@ -827,7 +827,7 @@ static int libusb_udev_select_configuration(IUDEVICE* idev, UINT32 bConfiguratio ret = libusb_set_configuration(libusb_handle, bConfigurationValue); if (ret < 0){ - fprintf(stderr, "libusb_set_configuration: ERROR number %d!!\n", ret); + CLOG_ERR( "libusb_set_configuration: ERROR number %d!!\n", ret); func_claim_all_interface(libusb_handle, (*LibusbConfig)->bNumInterfaces); return -1; } @@ -835,7 +835,7 @@ static int libusb_udev_select_configuration(IUDEVICE* idev, UINT32 bConfiguratio { ret = libusb_get_active_config_descriptor (libusb_dev, LibusbConfig); if (ret < 0){ - fprintf(stderr, "libusb_get_config_descriptor_by_value: ERROR number %d!!\n", ret); + CLOG_ERR( "libusb_get_config_descriptor_by_value: ERROR number %d!!\n", ret); func_claim_all_interface(libusb_handle, (*LibusbConfig)->bNumInterfaces); return -1; } @@ -885,7 +885,7 @@ static int libusb_udev_control_pipe_request(IUDEVICE* idev, UINT32 RequestId, *UsbdStatus = 0; /* if(pdev->request_queue->unregister_request(pdev->request_queue, RequestId)) - fprintf(stderr, "request_queue_unregister_request: not fount request 0x%x\n", RequestId); + CLOG_ERR( "request_queue_unregister_request: not fount request 0x%x\n", RequestId); */ return error; } @@ -980,12 +980,12 @@ static int libusb_udev_os_feature_descriptor_request(IUDEVICE* idev, UINT32 Requ ms_string_desc, 0x12, Timeout); - //fprintf(stderr, "Get ms string: result number %d", error); + //CLOG_ERR( "Get ms string: result number %d", error); if (error > 0) { BYTE bMS_Vendorcode; data_read_BYTE(ms_string_desc + 16, bMS_Vendorcode); - //fprintf(stderr, "bMS_Vendorcode:0x%x", bMS_Vendorcode); + //CLOG_ERR( "bMS_Vendorcode:0x%x", bMS_Vendorcode); /** get os descriptor */ error = libusb_control_transfer(pdev->libusb_handle, LIBUSB_ENDPOINT_IN |LIBUSB_REQUEST_TYPE_VENDOR | Recipient, @@ -1004,7 +1004,7 @@ static int libusb_udev_os_feature_descriptor_request(IUDEVICE* idev, UINT32 Requ *UsbdStatus = USBD_STATUS_SUCCESS; /* if(pdev->request_queue->unregister_request(pdev->request_queue, RequestId)) - fprintf(stderr, "request_queue_unregister_request: not fount request 0x%x\n", RequestId); + CLOG_ERR( "request_queue_unregister_request: not fount request 0x%x\n", RequestId); */ return error; } @@ -1263,7 +1263,7 @@ static int libusb_udev_isoch_transfer(IUDEVICE* idev, UINT32 RequestId, UINT32 E if (iso_transfer == NULL) { - fprintf(stderr, "Error: libusb_alloc_transfer.\n"); + CLOG_ERR( "Error: libusb_alloc_transfer.\n"); status = -1; } @@ -1368,7 +1368,7 @@ static int libusb_udev_bulk_or_interrupt_transfer(IUDEVICE* idev, UINT32 Request if (!ep_desc) { - fprintf(stderr, "func_get_ep_desc: endpoint 0x%x is not found!!\n", EndpointAddress); + CLOG_ERR( "func_get_ep_desc: endpoint 0x%x is not found!!\n", EndpointAddress); return -1; } transfer_type = (ep_desc->bmAttributes) & 0x3; @@ -1494,7 +1494,7 @@ static int libusb_udev_bulk_or_interrupt_transfer(IUDEVICE* idev, UINT32 Request if (request) { if(pdev->request_queue->unregister_request(pdev->request_queue, RequestId)) - fprintf(stderr, "request_queue_unregister_request: not fount request 0x%x\n", RequestId); + CLOG_ERR( "request_queue_unregister_request: not fount request 0x%x\n", RequestId); } libusb_free_transfer(transfer); @@ -1704,7 +1704,7 @@ static IUDEVICE* udev_init(UDEVICE* pdev, UINT16 bus_number, UINT16 dev_number) if (status < 0) { - fprintf(stderr, "USB init: Error to get HUB handle!!\n"); + CLOG_ERR( "USB init: Error to get HUB handle!!\n"); pdev->hub_handle = NULL; } @@ -1712,7 +1712,7 @@ static IUDEVICE* udev_init(UDEVICE* pdev, UINT16 bus_number, UINT16 dev_number) if (!pdev->devDescriptor) { - fprintf(stderr, "USB init: Error to get device descriptor!!\n"); + CLOG_ERR( "USB init: Error to get device descriptor!!\n"); zfree(pdev); return NULL; } @@ -1723,7 +1723,7 @@ static IUDEVICE* udev_init(UDEVICE* pdev, UINT16 bus_number, UINT16 dev_number) if (status < 0) { - fprintf(stderr, "libusb_get_descriptor: ERROR!!ret:%d\n", status); + CLOG_ERR( "libusb_get_descriptor: ERROR!!ret:%d\n", status); zfree(pdev); return NULL; } @@ -1752,7 +1752,7 @@ static IUDEVICE* udev_init(UDEVICE* pdev, UINT16 bus_number, UINT16 dev_number) case CLASS_CONTENT_SECURITY: //case CLASS_WIRELESS_CONTROLLER: //case CLASS_ELSE_DEVICE: - fprintf(stderr, " Device is not supported!!\n"); + CLOG_ERR( " Device is not supported!!\n"); zfree(pdev); return NULL; default: @@ -1818,7 +1818,7 @@ int udev_new_by_id(UINT16 idVendor, UINT16 idProduct, IUDEVICE*** devArray) ssize_t total_device; int i, status, num = 0; - fprintf(stderr, "VID: 0x%04X PID: 0x%04X\n", idVendor, idProduct); + CLOG_ERR( "VID: 0x%04X PID: 0x%04X\n", idVendor, idProduct); array = (UDEVICE**) malloc(16 * sizeof(UDEVICE*)); @@ -1839,7 +1839,7 @@ int udev_new_by_id(UINT16 idVendor, UINT16 idProduct, IUDEVICE*** devArray) if (status < 0) { - fprintf(stderr, "libusb_open: (by id) error: 0x%08X (%d)\n", status, status); + CLOG_ERR( "libusb_open: (by id) error: 0x%08X (%d)\n", status, status); zfree(descriptor); zfree(array[num]); continue; @@ -1876,7 +1876,7 @@ IUDEVICE* udev_new_by_addr(int bus_number, int dev_number) if (pDev->libusb_dev == NULL) { - fprintf(stderr, "libusb_device_new: ERROR!!\n"); + CLOG_ERR( "libusb_device_new: ERROR!!\n"); zfree(pDev); return NULL; } @@ -1885,7 +1885,7 @@ IUDEVICE* udev_new_by_addr(int bus_number, int dev_number) if (status < 0) { - fprintf(stderr, "libusb_open: (by addr) ERROR!!\n"); + CLOG_ERR( "libusb_open: (by addr) ERROR!!\n"); zfree(pDev); return NULL; } diff --git a/channels/urbdrc/client/libusb/libusb_udevman.c b/channels/urbdrc/client/libusb/libusb_udevman.c index ebf5e4b5a..c395b3c37 100644 --- a/channels/urbdrc/client/libusb/libusb_udevman.c +++ b/channels/urbdrc/client/libusb/libusb_udevman.c @@ -206,7 +206,7 @@ static int udevman_register_udevice(IUDEVMAN* idevman, int bus_number, int dev_n } else { - fprintf(stderr, "udevman_register_udevice: function error!!"); + CLOG_ERR( "udevman_register_udevice: function error!!"); return 0; } diff --git a/channels/urbdrc/client/libusb/request_queue.c b/channels/urbdrc/client/libusb/request_queue.c index e5ebfef71..5709faef2 100644 --- a/channels/urbdrc/client/libusb/request_queue.c +++ b/channels/urbdrc/client/libusb/request_queue.c @@ -100,7 +100,7 @@ TRANSFER_REQUEST* request_queue_get_request_by_endpoint(REQUEST_QUEUE* queue, BY } } pthread_mutex_unlock(&queue->request_loading); - fprintf(stderr, "request_queue_get_request_by_id: ERROR!!\n"); + CLOG_ERR( "request_queue_get_request_by_id: ERROR!!\n"); return NULL; } diff --git a/channels/urbdrc/client/searchman.c b/channels/urbdrc/client/searchman.c index 18fc5b73e..bdf103890 100644 --- a/channels/urbdrc/client/searchman.c +++ b/channels/urbdrc/client/searchman.c @@ -156,16 +156,16 @@ static void searchman_list_show(USB_SEARCHMAN* self) int num = 0; USB_SEARCHDEV* usb; - fprintf(stderr, "=========== Usb Search List ========= \n"); + CLOG_ERR( "=========== Usb Search List ========= \n"); self->rewind(self); while (self->has_next(self)) { usb = self->get_next(self); - fprintf(stderr, " USB %d: \n", num++); - fprintf(stderr, " idVendor: 0x%04X \n", usb->idVendor); - fprintf(stderr, " idProduct: 0x%04X \n", usb->idProduct); + CLOG_ERR( " USB %d: \n", num++); + CLOG_ERR( " idVendor: 0x%04X \n", usb->idVendor); + CLOG_ERR( " idProduct: 0x%04X \n", usb->idProduct); } - fprintf(stderr, "================= END =============== \n"); + CLOG_ERR( "================= END =============== \n"); } void searchman_free(USB_SEARCHMAN* self) @@ -202,7 +202,7 @@ USB_SEARCHMAN* searchman_new(void * urbdrc, UINT32 UsbDevice) if (ret != 0) { - fprintf(stderr, "searchman mutex initialization: searchman->mutex failed"); + CLOG_ERR( "searchman mutex initialization: searchman->mutex failed"); exit(EXIT_FAILURE); } diff --git a/channels/urbdrc/client/urbdrc_main.c b/channels/urbdrc/client/urbdrc_main.c index e010bba10..568d0d5c6 100644 --- a/channels/urbdrc/client/urbdrc_main.c +++ b/channels/urbdrc/client/urbdrc_main.c @@ -32,6 +32,7 @@ #include #include +#include #include "urbdrc_types.h" #include "urbdrc_main.h" @@ -468,7 +469,7 @@ static void* urbdrc_search_usb_device(void* arg) if (!udev) { - fprintf(stderr, "Can't create udev\n"); + CLOG_ERR( "Can't create udev\n"); return 0; } @@ -652,7 +653,7 @@ static void* urbdrc_search_usb_device(void* arg) } else { - fprintf(stderr, "No Device from receive_device(). An error occured.\n"); + CLOG_ERR( "No Device from receive_device(). An error occured.\n"); } } } @@ -835,7 +836,7 @@ static int urbdrc_on_data_received(IWTSVirtualChannelCallback* pChannelCallback, if (transfer_data == NULL) { - fprintf(stderr, "transfer_data is NULL!!"); + CLOG_ERR( "transfer_data is NULL!!"); return 0; } @@ -1000,7 +1001,7 @@ static void urbdrc_register_udevman_addin(IWTSPlugin* pPlugin, IUDEVMAN* udevman if (urbdrc->udevman) { - DEBUG_WARN("existing device, abort."); + CLOG_ERR("existing device, abort."); return; } @@ -1025,7 +1026,7 @@ static int urbdrc_load_udevman_addin(IWTSPlugin* pPlugin, const char* name, ADDI if (entry(&entryPoints) != 0) { - DEBUG_WARN("%s entry returns error.", name); + CLOG_ERR("%s entry returns error.", name); return FALSE; } diff --git a/channels/urbdrc/client/urbdrc_types.h b/channels/urbdrc/client/urbdrc_types.h index 3b83cee02..fc5a8b4c6 100644 --- a/channels/urbdrc/client/urbdrc_types.h +++ b/channels/urbdrc/client/urbdrc_types.h @@ -27,7 +27,7 @@ #include #include -#include +#include #include #include @@ -37,9 +37,9 @@ #include #ifdef WITH_DEBUG_DVC -#define DEBUG_DVC(fmt, ...) DEBUG_CLASS(DVC, fmt, ## __VA_ARGS__) +#define DEBUG_DVC(fmt, ...) CLOG_CLASS(DVC, fmt, ## __VA_ARGS__) #else -#define DEBUG_DVC(fmt, ...) DEBUG_NULL(fmt, ## __VA_ARGS__) +#define DEBUG_DVC(fmt, ...) CLOG_NULL(fmt, ## __VA_ARGS__) #endif #define CAPABILITIES_NEGOTIATOR 0x00000000 @@ -316,10 +316,10 @@ enum device_descriptor_table #define MAX_URB_REQUSET_NUM 0x80 #define LOG_LEVEL 1 -#define LLOG(_level, _args) \ - do { if (_level < LOG_LEVEL) { printf _args ; } } while (0) -#define LLOGLN(_level, _args) \ - do { if (_level < LOG_LEVEL) { printf _args ; printf("\n"); } } while (0) +#define LLOG(_level, args) \ + do { if (_level < LOG_LEVEL) { CLOG_DBG args ; } } while (0) +#define LLOGLN(_level, args) \ + do { if (_level < LOG_LEVEL) { CLOG_DBG args ; } } while (0) #define dummy_wait_obj(void) do{ sleep(5); } while(0) #define dummy_wait_s_obj(_s) do{ sleep(_s); } while(0) diff --git a/client/Android/FreeRDPCore/jni/android_freerdp.c b/client/Android/FreeRDPCore/jni/android_freerdp.c index 5f75ce40e..4d75b5236 100644 --- a/client/Android/FreeRDPCore/jni/android_freerdp.c +++ b/client/Android/FreeRDPCore/jni/android_freerdp.c @@ -141,6 +141,7 @@ BOOL android_pre_connect(freerdp* instance) static BOOL android_post_connect(freerdp* instance) { + UINT32 gdi_flags; rdpSettings *settings = instance->settings; DEBUG_ANDROID("android_post_connect"); @@ -154,9 +155,12 @@ static BOOL android_post_connect(freerdp* instance) instance->context->cache = cache_new(settings); - gdi_init(instance, CLRCONV_ALPHA | CLRCONV_INVERT | - ((instance->settings->ColorDepth > 16) ? CLRBUF_32BPP : CLRBUF_16BPP), - NULL); + if (instance->settings->ColorDepth > 16) + gdi_flags = CLRBUF_32BPP | CLRCONV_ALPHA | CLRCONV_INVERT; + else + gdi_flags = CLRBUF_16BPP; + + gdi_init(instance, gdi_flags, NULL); instance->update->BeginPaint = android_begin_paint; instance->update->EndPaint = android_end_paint; @@ -270,40 +274,6 @@ static void android_process_channel_event(rdpChannels* channels, freerdp* instan } } -static void *jni_update_thread(void *arg) -{ - int status; - wMessage message; - wMessageQueue* queue; - freerdp* instance = (freerdp*) arg; - - assert( NULL != instance); - - DEBUG_ANDROID("Start."); - - status = 1; - queue = freerdp_get_message_queue(instance, FREERDP_UPDATE_MESSAGE_QUEUE); - - while (MessageQueue_Wait(queue)) - { - while (MessageQueue_Peek(queue, &message, TRUE)) - { - status = freerdp_message_queue_process_message(instance, FREERDP_UPDATE_MESSAGE_QUEUE, &message); - - if (!status) - break; - } - - if (!status) - break; - } - - DEBUG_ANDROID("Quit."); - - ExitThread(0); - return NULL; -} - static void* jni_input_thread(void* arg) { HANDLE event[3]; @@ -394,11 +364,9 @@ static int android_freerdp_run(freerdp* instance) const rdpSettings* settings = instance->context->settings; - HANDLE update_thread; HANDLE input_thread; HANDLE channels_thread; - BOOL async_update = settings->AsyncUpdate; BOOL async_input = settings->AsyncInput; BOOL async_channels = settings->AsyncChannels; BOOL async_transport = settings->AsyncTransport; @@ -417,12 +385,6 @@ static int android_freerdp_run(freerdp* instance) return 0; } - if (async_update) - { - update_thread = CreateThread(NULL, 0, - (LPTHREAD_START_ROUTINE) jni_update_thread, instance, 0, NULL); - } - if (async_input) { input_thread = CreateThread(NULL, 0, @@ -571,15 +533,7 @@ static int android_freerdp_run(freerdp* instance) WaitForSingleObject(channels_thread, INFINITE); CloseHandle(channels_thread); } - - if (async_update) - { - wMessageQueue* update_queue = freerdp_get_message_queue(instance, FREERDP_UPDATE_MESSAGE_QUEUE); - MessageQueue_PostQuit(update_queue, 0); - WaitForSingleObject(update_thread, INFINITE); - CloseHandle(update_thread); - } - + if (async_input) { wMessageQueue* input_queue = freerdp_get_message_queue(instance, FREERDP_INPUT_MESSAGE_QUEUE); @@ -836,44 +790,15 @@ JNIEXPORT void JNICALL jni_freerdp_set_performance_flags( } /* store performance settings */ - if (disableWallpaper == JNI_TRUE) - settings->DisableWallpaper = TRUE; - - if (disableFullWindowDrag == JNI_TRUE) - settings->DisableFullWindowDrag = TRUE; - - if (disableMenuAnimations == JNI_TRUE) - settings->DisableMenuAnims = TRUE; - - if (disableTheming == JNI_TRUE) - settings->DisableThemes = TRUE; - - if (enableFontSmoothing == JNI_TRUE) - settings->AllowFontSmoothing = TRUE; - - if(enableDesktopComposition == JNI_TRUE) - settings->AllowDesktopComposition = TRUE; - + 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 */ - settings->PerformanceFlags = PERF_FLAG_NONE; - if (settings->AllowFontSmoothing) - settings->PerformanceFlags |= PERF_ENABLE_FONT_SMOOTHING; - - if (settings->AllowDesktopComposition) - settings->PerformanceFlags |= PERF_ENABLE_DESKTOP_COMPOSITION; - - if (settings->DisableWallpaper) - settings->PerformanceFlags |= PERF_DISABLE_WALLPAPER; - - if (settings->DisableFullWindowDrag) - settings->PerformanceFlags |= PERF_DISABLE_FULLWINDOWDRAG; - - if (settings->DisableMenuAnims) - settings->PerformanceFlags |= PERF_DISABLE_MENUANIMATIONS; - - if (settings->DisableThemes) - settings->PerformanceFlags |= PERF_DISABLE_THEMING; + freerdp_performance_flags_make(settings); DEBUG_ANDROID("performance_flags: %04X", settings->PerformanceFlags); } @@ -1014,7 +939,7 @@ JNIEXPORT void JNICALL jni_freerdp_set_gateway_info(JNIEnv *env, jclass cls, jin static void copy_pixel_buffer(UINT8* dstBuf, UINT8* srcBuf, int x, int y, int width, int height, int wBuf, int hBuf, int bpp) { - int i, j; + int i; int length; int scanline; UINT8 *dstp, *srcp; @@ -1025,31 +950,11 @@ static void copy_pixel_buffer(UINT8* dstBuf, UINT8* srcBuf, int x, int y, int wi srcp = (UINT8*) &srcBuf[(scanline * y) + (x * bpp)]; dstp = (UINT8*) &dstBuf[(scanline * y) + (x * bpp)]; - if (bpp == 4) + for (i = 0; i < height; i++) { - for (i = 0; i < height; i++) - { - for (j = 0; j < width * 4; j += 4) - { - // ARGB <-> ABGR - dstp[j + 0] = srcp[j + 2]; - dstp[j + 1] = srcp[j + 1]; - dstp[j + 2] = srcp[j + 0]; - dstp[j + 3] = srcp[j + 3]; - } - - srcp += scanline; - dstp += scanline; - } - } - else - { - for (i = 0; i < height; i++) - { - memcpy(dstp, srcp, length); - srcp += scanline; - dstp += scanline; - } + memcpy(dstp, srcp, length); + srcp += scanline; + dstp += scanline; } } diff --git a/client/Android/FreeRDPCore/res/drawable-hdpi/icon_button_add.png b/client/Android/FreeRDPCore/res/drawable-hdpi/icon_button_add.png index 6e028b20b..19104c8e9 100644 Binary files a/client/Android/FreeRDPCore/res/drawable-hdpi/icon_button_add.png and b/client/Android/FreeRDPCore/res/drawable-hdpi/icon_button_add.png differ diff --git a/client/Android/FreeRDPCore/res/drawable-hdpi/icon_edittext_clear.png b/client/Android/FreeRDPCore/res/drawable-hdpi/icon_edittext_clear.png index 90db01b5b..ae185579e 100644 Binary files a/client/Android/FreeRDPCore/res/drawable-hdpi/icon_edittext_clear.png and b/client/Android/FreeRDPCore/res/drawable-hdpi/icon_edittext_clear.png differ diff --git a/client/Android/FreeRDPCore/res/drawable-hdpi/icon_edittext_search.png b/client/Android/FreeRDPCore/res/drawable-hdpi/icon_edittext_search.png index 0a91eabcc..2283a9194 100644 Binary files a/client/Android/FreeRDPCore/res/drawable-hdpi/icon_edittext_search.png and b/client/Android/FreeRDPCore/res/drawable-hdpi/icon_edittext_search.png differ diff --git a/client/Android/FreeRDPCore/res/drawable-hdpi/icon_launcher_freerdp.png b/client/Android/FreeRDPCore/res/drawable-hdpi/icon_launcher_freerdp.png index 45ed86123..ff31f2576 100644 Binary files a/client/Android/FreeRDPCore/res/drawable-hdpi/icon_launcher_freerdp.png and b/client/Android/FreeRDPCore/res/drawable-hdpi/icon_launcher_freerdp.png differ diff --git a/client/Android/FreeRDPCore/res/drawable-hdpi/icon_menu_about.png b/client/Android/FreeRDPCore/res/drawable-hdpi/icon_menu_about.png index 6b3f7fd15..43cf97ccf 100644 Binary files a/client/Android/FreeRDPCore/res/drawable-hdpi/icon_menu_about.png and b/client/Android/FreeRDPCore/res/drawable-hdpi/icon_menu_about.png differ diff --git a/client/Android/FreeRDPCore/res/drawable-hdpi/icon_menu_add.png b/client/Android/FreeRDPCore/res/drawable-hdpi/icon_menu_add.png index 7b0dfc5e1..46b50d6ed 100644 Binary files a/client/Android/FreeRDPCore/res/drawable-hdpi/icon_menu_add.png and b/client/Android/FreeRDPCore/res/drawable-hdpi/icon_menu_add.png differ diff --git a/client/Android/FreeRDPCore/res/drawable-hdpi/icon_menu_close.png b/client/Android/FreeRDPCore/res/drawable-hdpi/icon_menu_close.png index 4683f6193..82d41702e 100644 Binary files a/client/Android/FreeRDPCore/res/drawable-hdpi/icon_menu_close.png and b/client/Android/FreeRDPCore/res/drawable-hdpi/icon_menu_close.png differ diff --git a/client/Android/FreeRDPCore/res/drawable-hdpi/icon_menu_disconnect.png b/client/Android/FreeRDPCore/res/drawable-hdpi/icon_menu_disconnect.png index 172ae5f3d..192c57bb3 100644 Binary files a/client/Android/FreeRDPCore/res/drawable-hdpi/icon_menu_disconnect.png and b/client/Android/FreeRDPCore/res/drawable-hdpi/icon_menu_disconnect.png differ diff --git a/client/Android/FreeRDPCore/res/drawable-hdpi/icon_menu_ext_keyboard.png b/client/Android/FreeRDPCore/res/drawable-hdpi/icon_menu_ext_keyboard.png index 53319e291..2ed035200 100644 Binary files a/client/Android/FreeRDPCore/res/drawable-hdpi/icon_menu_ext_keyboard.png and b/client/Android/FreeRDPCore/res/drawable-hdpi/icon_menu_ext_keyboard.png differ diff --git a/client/Android/FreeRDPCore/res/drawable-hdpi/icon_menu_help.png b/client/Android/FreeRDPCore/res/drawable-hdpi/icon_menu_help.png index a5b4a2f60..8ba27516d 100644 Binary files a/client/Android/FreeRDPCore/res/drawable-hdpi/icon_menu_help.png and b/client/Android/FreeRDPCore/res/drawable-hdpi/icon_menu_help.png differ diff --git a/client/Android/FreeRDPCore/res/drawable-hdpi/icon_menu_preferences.png b/client/Android/FreeRDPCore/res/drawable-hdpi/icon_menu_preferences.png index 039c72174..d6ea16c37 100644 Binary files a/client/Android/FreeRDPCore/res/drawable-hdpi/icon_menu_preferences.png and b/client/Android/FreeRDPCore/res/drawable-hdpi/icon_menu_preferences.png differ diff --git a/client/Android/FreeRDPCore/res/drawable-hdpi/icon_menu_settings.png b/client/Android/FreeRDPCore/res/drawable-hdpi/icon_menu_settings.png index c08e64f91..8dcef3e76 100644 Binary files a/client/Android/FreeRDPCore/res/drawable-hdpi/icon_menu_settings.png and b/client/Android/FreeRDPCore/res/drawable-hdpi/icon_menu_settings.png differ diff --git a/client/Android/FreeRDPCore/res/drawable-hdpi/icon_menu_sys_keyboard.png b/client/Android/FreeRDPCore/res/drawable-hdpi/icon_menu_sys_keyboard.png index 5b14130e3..3d824d30a 100644 Binary files a/client/Android/FreeRDPCore/res/drawable-hdpi/icon_menu_sys_keyboard.png and b/client/Android/FreeRDPCore/res/drawable-hdpi/icon_menu_sys_keyboard.png differ diff --git a/client/Android/FreeRDPCore/res/drawable-hdpi/icon_menu_touch_pointer.png b/client/Android/FreeRDPCore/res/drawable-hdpi/icon_menu_touch_pointer.png index 3f5142012..121b545a1 100644 Binary files a/client/Android/FreeRDPCore/res/drawable-hdpi/icon_menu_touch_pointer.png and b/client/Android/FreeRDPCore/res/drawable-hdpi/icon_menu_touch_pointer.png differ diff --git a/client/Android/FreeRDPCore/res/drawable-hdpi/icon_star_off.png b/client/Android/FreeRDPCore/res/drawable-hdpi/icon_star_off.png index 4be0f5df2..eeebc098a 100644 Binary files a/client/Android/FreeRDPCore/res/drawable-hdpi/icon_star_off.png and b/client/Android/FreeRDPCore/res/drawable-hdpi/icon_star_off.png differ diff --git a/client/Android/FreeRDPCore/res/drawable-hdpi/icon_star_on.png b/client/Android/FreeRDPCore/res/drawable-hdpi/icon_star_on.png index 421305087..e6fef76f2 100644 Binary files a/client/Android/FreeRDPCore/res/drawable-hdpi/icon_star_on.png and b/client/Android/FreeRDPCore/res/drawable-hdpi/icon_star_on.png differ diff --git a/client/Android/FreeRDPCore/res/drawable-hdpi/search_plate.9.png b/client/Android/FreeRDPCore/res/drawable-hdpi/search_plate.9.png index 32c6dc370..8ab6ad770 100644 Binary files a/client/Android/FreeRDPCore/res/drawable-hdpi/search_plate.9.png and b/client/Android/FreeRDPCore/res/drawable-hdpi/search_plate.9.png differ diff --git a/client/Android/FreeRDPCore/res/drawable-hdpi/sym_keyboard_delete.png b/client/Android/FreeRDPCore/res/drawable-hdpi/sym_keyboard_delete.png index 59d78bec0..104c1b922 100644 Binary files a/client/Android/FreeRDPCore/res/drawable-hdpi/sym_keyboard_delete.png and b/client/Android/FreeRDPCore/res/drawable-hdpi/sym_keyboard_delete.png differ diff --git a/client/Android/FreeRDPCore/res/drawable-hdpi/sym_keyboard_feedback_delete.png b/client/Android/FreeRDPCore/res/drawable-hdpi/sym_keyboard_feedback_delete.png index ca7637552..a6d87337d 100644 Binary files a/client/Android/FreeRDPCore/res/drawable-hdpi/sym_keyboard_feedback_delete.png and b/client/Android/FreeRDPCore/res/drawable-hdpi/sym_keyboard_feedback_delete.png differ diff --git a/client/Android/FreeRDPCore/res/drawable-hdpi/sym_keyboard_feedback_return.png b/client/Android/FreeRDPCore/res/drawable-hdpi/sym_keyboard_feedback_return.png index ae57299e4..19b33da5f 100644 Binary files a/client/Android/FreeRDPCore/res/drawable-hdpi/sym_keyboard_feedback_return.png and b/client/Android/FreeRDPCore/res/drawable-hdpi/sym_keyboard_feedback_return.png differ diff --git a/client/Android/FreeRDPCore/res/drawable-hdpi/sym_keyboard_return.png b/client/Android/FreeRDPCore/res/drawable-hdpi/sym_keyboard_return.png index 58505c5e0..cf2b963ea 100644 Binary files a/client/Android/FreeRDPCore/res/drawable-hdpi/sym_keyboard_return.png and b/client/Android/FreeRDPCore/res/drawable-hdpi/sym_keyboard_return.png differ diff --git a/client/Android/FreeRDPCore/res/drawable-ldpi/icon_button_add.png b/client/Android/FreeRDPCore/res/drawable-ldpi/icon_button_add.png index 7afaeded1..312f5f9f4 100644 Binary files a/client/Android/FreeRDPCore/res/drawable-ldpi/icon_button_add.png and b/client/Android/FreeRDPCore/res/drawable-ldpi/icon_button_add.png differ diff --git a/client/Android/FreeRDPCore/res/drawable-ldpi/icon_edittext_search.png b/client/Android/FreeRDPCore/res/drawable-ldpi/icon_edittext_search.png index bdefbf5c6..421c3e88c 100644 Binary files a/client/Android/FreeRDPCore/res/drawable-ldpi/icon_edittext_search.png and b/client/Android/FreeRDPCore/res/drawable-ldpi/icon_edittext_search.png differ diff --git a/client/Android/FreeRDPCore/res/drawable-ldpi/icon_launcher_freerdp.png b/client/Android/FreeRDPCore/res/drawable-ldpi/icon_launcher_freerdp.png index b57651bed..49726f4f0 100644 Binary files a/client/Android/FreeRDPCore/res/drawable-ldpi/icon_launcher_freerdp.png and b/client/Android/FreeRDPCore/res/drawable-ldpi/icon_launcher_freerdp.png differ diff --git a/client/Android/FreeRDPCore/res/drawable-ldpi/icon_menu_about.png b/client/Android/FreeRDPCore/res/drawable-ldpi/icon_menu_about.png index 55c57d5c5..d0c26e223 100644 Binary files a/client/Android/FreeRDPCore/res/drawable-ldpi/icon_menu_about.png and b/client/Android/FreeRDPCore/res/drawable-ldpi/icon_menu_about.png differ diff --git a/client/Android/FreeRDPCore/res/drawable-ldpi/icon_menu_add.png b/client/Android/FreeRDPCore/res/drawable-ldpi/icon_menu_add.png index 89620af8c..2eaa36966 100644 Binary files a/client/Android/FreeRDPCore/res/drawable-ldpi/icon_menu_add.png and b/client/Android/FreeRDPCore/res/drawable-ldpi/icon_menu_add.png differ diff --git a/client/Android/FreeRDPCore/res/drawable-ldpi/icon_menu_disconnect.png b/client/Android/FreeRDPCore/res/drawable-ldpi/icon_menu_disconnect.png index 606cce4a7..99c1ad45c 100644 Binary files a/client/Android/FreeRDPCore/res/drawable-ldpi/icon_menu_disconnect.png and b/client/Android/FreeRDPCore/res/drawable-ldpi/icon_menu_disconnect.png differ diff --git a/client/Android/FreeRDPCore/res/drawable-ldpi/icon_menu_exit.png b/client/Android/FreeRDPCore/res/drawable-ldpi/icon_menu_exit.png index 760b9254d..90a813e0f 100644 Binary files a/client/Android/FreeRDPCore/res/drawable-ldpi/icon_menu_exit.png and b/client/Android/FreeRDPCore/res/drawable-ldpi/icon_menu_exit.png differ diff --git a/client/Android/FreeRDPCore/res/drawable-ldpi/icon_menu_ext_keyboard.png b/client/Android/FreeRDPCore/res/drawable-ldpi/icon_menu_ext_keyboard.png index 425d904ca..02aeed3ca 100644 Binary files a/client/Android/FreeRDPCore/res/drawable-ldpi/icon_menu_ext_keyboard.png and b/client/Android/FreeRDPCore/res/drawable-ldpi/icon_menu_ext_keyboard.png differ diff --git a/client/Android/FreeRDPCore/res/drawable-ldpi/icon_menu_help.png b/client/Android/FreeRDPCore/res/drawable-ldpi/icon_menu_help.png index f93a4e640..5e4e17a6d 100644 Binary files a/client/Android/FreeRDPCore/res/drawable-ldpi/icon_menu_help.png and b/client/Android/FreeRDPCore/res/drawable-ldpi/icon_menu_help.png differ diff --git a/client/Android/FreeRDPCore/res/drawable-ldpi/icon_menu_preferences.png b/client/Android/FreeRDPCore/res/drawable-ldpi/icon_menu_preferences.png index efc2f3e45..34beda8b2 100644 Binary files a/client/Android/FreeRDPCore/res/drawable-ldpi/icon_menu_preferences.png and b/client/Android/FreeRDPCore/res/drawable-ldpi/icon_menu_preferences.png differ diff --git a/client/Android/FreeRDPCore/res/drawable-ldpi/icon_menu_settings.png b/client/Android/FreeRDPCore/res/drawable-ldpi/icon_menu_settings.png index b137b8c6e..61a2fdd3a 100644 Binary files a/client/Android/FreeRDPCore/res/drawable-ldpi/icon_menu_settings.png and b/client/Android/FreeRDPCore/res/drawable-ldpi/icon_menu_settings.png differ diff --git a/client/Android/FreeRDPCore/res/drawable-ldpi/icon_menu_sys_keyboard.png b/client/Android/FreeRDPCore/res/drawable-ldpi/icon_menu_sys_keyboard.png index 49837f290..2fb688787 100644 Binary files a/client/Android/FreeRDPCore/res/drawable-ldpi/icon_menu_sys_keyboard.png and b/client/Android/FreeRDPCore/res/drawable-ldpi/icon_menu_sys_keyboard.png differ diff --git a/client/Android/FreeRDPCore/res/drawable-ldpi/icon_menu_touch_pointer.png b/client/Android/FreeRDPCore/res/drawable-ldpi/icon_menu_touch_pointer.png index 4e3b7d7a6..066ce3f63 100644 Binary files a/client/Android/FreeRDPCore/res/drawable-ldpi/icon_menu_touch_pointer.png and b/client/Android/FreeRDPCore/res/drawable-ldpi/icon_menu_touch_pointer.png differ diff --git a/client/Android/FreeRDPCore/res/drawable-ldpi/icon_star_off.png b/client/Android/FreeRDPCore/res/drawable-ldpi/icon_star_off.png index f0f1eb845..b0dce0e66 100644 Binary files a/client/Android/FreeRDPCore/res/drawable-ldpi/icon_star_off.png and b/client/Android/FreeRDPCore/res/drawable-ldpi/icon_star_off.png differ diff --git a/client/Android/FreeRDPCore/res/drawable-ldpi/icon_star_on.png b/client/Android/FreeRDPCore/res/drawable-ldpi/icon_star_on.png index cf5ed353b..b09dec7ae 100644 Binary files a/client/Android/FreeRDPCore/res/drawable-ldpi/icon_star_on.png and b/client/Android/FreeRDPCore/res/drawable-ldpi/icon_star_on.png differ diff --git a/client/Android/FreeRDPCore/res/drawable-ldpi/search_plate.9.png b/client/Android/FreeRDPCore/res/drawable-ldpi/search_plate.9.png index 2fa21299f..834763550 100644 Binary files a/client/Android/FreeRDPCore/res/drawable-ldpi/search_plate.9.png and b/client/Android/FreeRDPCore/res/drawable-ldpi/search_plate.9.png differ diff --git a/client/Android/FreeRDPCore/res/drawable-ldpi/sym_keyboard_delete.png b/client/Android/FreeRDPCore/res/drawable-ldpi/sym_keyboard_delete.png index d9d565391..07f95d5dc 100644 Binary files a/client/Android/FreeRDPCore/res/drawable-ldpi/sym_keyboard_delete.png and b/client/Android/FreeRDPCore/res/drawable-ldpi/sym_keyboard_delete.png differ diff --git a/client/Android/FreeRDPCore/res/drawable-ldpi/sym_keyboard_feedback_delete.png b/client/Android/FreeRDPCore/res/drawable-ldpi/sym_keyboard_feedback_delete.png index 8922bf92c..064a2c298 100644 Binary files a/client/Android/FreeRDPCore/res/drawable-ldpi/sym_keyboard_feedback_delete.png and b/client/Android/FreeRDPCore/res/drawable-ldpi/sym_keyboard_feedback_delete.png differ diff --git a/client/Android/FreeRDPCore/res/drawable-ldpi/sym_keyboard_feedback_return.png b/client/Android/FreeRDPCore/res/drawable-ldpi/sym_keyboard_feedback_return.png index c5f324752..7e7b3de27 100644 Binary files a/client/Android/FreeRDPCore/res/drawable-ldpi/sym_keyboard_feedback_return.png and b/client/Android/FreeRDPCore/res/drawable-ldpi/sym_keyboard_feedback_return.png differ diff --git a/client/Android/FreeRDPCore/res/drawable-ldpi/sym_keyboard_return.png b/client/Android/FreeRDPCore/res/drawable-ldpi/sym_keyboard_return.png index 1c7c58d5d..1d8a4eac0 100644 Binary files a/client/Android/FreeRDPCore/res/drawable-ldpi/sym_keyboard_return.png and b/client/Android/FreeRDPCore/res/drawable-ldpi/sym_keyboard_return.png differ diff --git a/client/Android/FreeRDPCore/res/drawable-mdpi/icon_button_add.png b/client/Android/FreeRDPCore/res/drawable-mdpi/icon_button_add.png index af637b3be..33c42e0eb 100644 Binary files a/client/Android/FreeRDPCore/res/drawable-mdpi/icon_button_add.png and b/client/Android/FreeRDPCore/res/drawable-mdpi/icon_button_add.png differ diff --git a/client/Android/FreeRDPCore/res/drawable-mdpi/icon_edittext_clear.png b/client/Android/FreeRDPCore/res/drawable-mdpi/icon_edittext_clear.png index 90db01b5b..ae185579e 100644 Binary files a/client/Android/FreeRDPCore/res/drawable-mdpi/icon_edittext_clear.png and b/client/Android/FreeRDPCore/res/drawable-mdpi/icon_edittext_clear.png differ diff --git a/client/Android/FreeRDPCore/res/drawable-mdpi/icon_edittext_search.png b/client/Android/FreeRDPCore/res/drawable-mdpi/icon_edittext_search.png index 3f8913e2a..60112c109 100644 Binary files a/client/Android/FreeRDPCore/res/drawable-mdpi/icon_edittext_search.png and b/client/Android/FreeRDPCore/res/drawable-mdpi/icon_edittext_search.png differ diff --git a/client/Android/FreeRDPCore/res/drawable-mdpi/icon_launcher_freerdp.png b/client/Android/FreeRDPCore/res/drawable-mdpi/icon_launcher_freerdp.png index 55335c869..6b18c0ae3 100644 Binary files a/client/Android/FreeRDPCore/res/drawable-mdpi/icon_launcher_freerdp.png and b/client/Android/FreeRDPCore/res/drawable-mdpi/icon_launcher_freerdp.png differ diff --git a/client/Android/FreeRDPCore/res/drawable-mdpi/icon_menu_about.png b/client/Android/FreeRDPCore/res/drawable-mdpi/icon_menu_about.png index 1f8a7cd47..04442c8e4 100644 Binary files a/client/Android/FreeRDPCore/res/drawable-mdpi/icon_menu_about.png and b/client/Android/FreeRDPCore/res/drawable-mdpi/icon_menu_about.png differ diff --git a/client/Android/FreeRDPCore/res/drawable-mdpi/icon_menu_add.png b/client/Android/FreeRDPCore/res/drawable-mdpi/icon_menu_add.png index 57a4099bb..014ad5927 100644 Binary files a/client/Android/FreeRDPCore/res/drawable-mdpi/icon_menu_add.png and b/client/Android/FreeRDPCore/res/drawable-mdpi/icon_menu_add.png differ diff --git a/client/Android/FreeRDPCore/res/drawable-mdpi/icon_menu_disconnect.png b/client/Android/FreeRDPCore/res/drawable-mdpi/icon_menu_disconnect.png index c1aa860da..9a78d64ce 100644 Binary files a/client/Android/FreeRDPCore/res/drawable-mdpi/icon_menu_disconnect.png and b/client/Android/FreeRDPCore/res/drawable-mdpi/icon_menu_disconnect.png differ diff --git a/client/Android/FreeRDPCore/res/drawable-mdpi/icon_menu_exit.png b/client/Android/FreeRDPCore/res/drawable-mdpi/icon_menu_exit.png index 04a76b589..7213223f8 100644 Binary files a/client/Android/FreeRDPCore/res/drawable-mdpi/icon_menu_exit.png and b/client/Android/FreeRDPCore/res/drawable-mdpi/icon_menu_exit.png differ diff --git a/client/Android/FreeRDPCore/res/drawable-mdpi/icon_menu_ext_keyboard.png b/client/Android/FreeRDPCore/res/drawable-mdpi/icon_menu_ext_keyboard.png index 9ae25ff2e..f8a055bba 100644 Binary files a/client/Android/FreeRDPCore/res/drawable-mdpi/icon_menu_ext_keyboard.png and b/client/Android/FreeRDPCore/res/drawable-mdpi/icon_menu_ext_keyboard.png differ diff --git a/client/Android/FreeRDPCore/res/drawable-mdpi/icon_menu_help.png b/client/Android/FreeRDPCore/res/drawable-mdpi/icon_menu_help.png index 4f65a619d..36041a529 100644 Binary files a/client/Android/FreeRDPCore/res/drawable-mdpi/icon_menu_help.png and b/client/Android/FreeRDPCore/res/drawable-mdpi/icon_menu_help.png differ diff --git a/client/Android/FreeRDPCore/res/drawable-mdpi/icon_menu_preferences.png b/client/Android/FreeRDPCore/res/drawable-mdpi/icon_menu_preferences.png index 2f34c7695..3a297aaa7 100644 Binary files a/client/Android/FreeRDPCore/res/drawable-mdpi/icon_menu_preferences.png and b/client/Android/FreeRDPCore/res/drawable-mdpi/icon_menu_preferences.png differ diff --git a/client/Android/FreeRDPCore/res/drawable-mdpi/icon_menu_settings.png b/client/Android/FreeRDPCore/res/drawable-mdpi/icon_menu_settings.png index a96bb0c4c..f78c41f96 100644 Binary files a/client/Android/FreeRDPCore/res/drawable-mdpi/icon_menu_settings.png and b/client/Android/FreeRDPCore/res/drawable-mdpi/icon_menu_settings.png differ diff --git a/client/Android/FreeRDPCore/res/drawable-mdpi/icon_menu_sys_keyboard.png b/client/Android/FreeRDPCore/res/drawable-mdpi/icon_menu_sys_keyboard.png index bcd3eba42..a7d5585ae 100644 Binary files a/client/Android/FreeRDPCore/res/drawable-mdpi/icon_menu_sys_keyboard.png and b/client/Android/FreeRDPCore/res/drawable-mdpi/icon_menu_sys_keyboard.png differ diff --git a/client/Android/FreeRDPCore/res/drawable-mdpi/icon_menu_touch_pointer.png b/client/Android/FreeRDPCore/res/drawable-mdpi/icon_menu_touch_pointer.png index e37e1dbbe..b76585af8 100644 Binary files a/client/Android/FreeRDPCore/res/drawable-mdpi/icon_menu_touch_pointer.png and b/client/Android/FreeRDPCore/res/drawable-mdpi/icon_menu_touch_pointer.png differ diff --git a/client/Android/FreeRDPCore/res/drawable-mdpi/icon_star_off.png b/client/Android/FreeRDPCore/res/drawable-mdpi/icon_star_off.png index 7e9342b5c..f2cafb532 100644 Binary files a/client/Android/FreeRDPCore/res/drawable-mdpi/icon_star_off.png and b/client/Android/FreeRDPCore/res/drawable-mdpi/icon_star_off.png differ diff --git a/client/Android/FreeRDPCore/res/drawable-mdpi/icon_star_on.png b/client/Android/FreeRDPCore/res/drawable-mdpi/icon_star_on.png index a9bdb052a..f203ce2a7 100644 Binary files a/client/Android/FreeRDPCore/res/drawable-mdpi/icon_star_on.png and b/client/Android/FreeRDPCore/res/drawable-mdpi/icon_star_on.png differ diff --git a/client/Android/FreeRDPCore/res/drawable-mdpi/search_plate.9.png b/client/Android/FreeRDPCore/res/drawable-mdpi/search_plate.9.png index 1cad9020d..144481cb1 100644 Binary files a/client/Android/FreeRDPCore/res/drawable-mdpi/search_plate.9.png and b/client/Android/FreeRDPCore/res/drawable-mdpi/search_plate.9.png differ diff --git a/client/Android/FreeRDPCore/res/drawable-mdpi/sym_keyboard_delete.png b/client/Android/FreeRDPCore/res/drawable-mdpi/sym_keyboard_delete.png index 43a033ead..98a2bc2ca 100644 Binary files a/client/Android/FreeRDPCore/res/drawable-mdpi/sym_keyboard_delete.png and b/client/Android/FreeRDPCore/res/drawable-mdpi/sym_keyboard_delete.png differ diff --git a/client/Android/FreeRDPCore/res/drawable-mdpi/sym_keyboard_feedback_delete.png b/client/Android/FreeRDPCore/res/drawable-mdpi/sym_keyboard_feedback_delete.png index 1edb10b4e..617d4e96e 100644 Binary files a/client/Android/FreeRDPCore/res/drawable-mdpi/sym_keyboard_feedback_delete.png and b/client/Android/FreeRDPCore/res/drawable-mdpi/sym_keyboard_feedback_delete.png differ diff --git a/client/Android/FreeRDPCore/res/drawable-mdpi/sym_keyboard_feedback_return.png b/client/Android/FreeRDPCore/res/drawable-mdpi/sym_keyboard_feedback_return.png index 03d9c9b2d..af0fea3f5 100644 Binary files a/client/Android/FreeRDPCore/res/drawable-mdpi/sym_keyboard_feedback_return.png and b/client/Android/FreeRDPCore/res/drawable-mdpi/sym_keyboard_feedback_return.png differ diff --git a/client/Android/FreeRDPCore/res/drawable-mdpi/sym_keyboard_return.png b/client/Android/FreeRDPCore/res/drawable-mdpi/sym_keyboard_return.png index 17f257439..27e26fcbb 100644 Binary files a/client/Android/FreeRDPCore/res/drawable-mdpi/sym_keyboard_return.png and b/client/Android/FreeRDPCore/res/drawable-mdpi/sym_keyboard_return.png differ diff --git a/client/Android/FreeRDPCore/res/drawable/icon_button_cancel.png b/client/Android/FreeRDPCore/res/drawable/icon_button_cancel.png index 606cce4a7..99c1ad45c 100644 Binary files a/client/Android/FreeRDPCore/res/drawable/icon_button_cancel.png and b/client/Android/FreeRDPCore/res/drawable/icon_button_cancel.png differ diff --git a/client/Android/FreeRDPCore/res/drawable/icon_launcher_freerdp.png b/client/Android/FreeRDPCore/res/drawable/icon_launcher_freerdp.png index ad325d46e..53c5b36e1 100644 Binary files a/client/Android/FreeRDPCore/res/drawable/icon_launcher_freerdp.png and b/client/Android/FreeRDPCore/res/drawable/icon_launcher_freerdp.png differ diff --git a/client/Android/FreeRDPCore/res/drawable/sym_keyboard_arrows.png b/client/Android/FreeRDPCore/res/drawable/sym_keyboard_arrows.png index 3ad31caba..ec6959cbe 100644 Binary files a/client/Android/FreeRDPCore/res/drawable/sym_keyboard_arrows.png and b/client/Android/FreeRDPCore/res/drawable/sym_keyboard_arrows.png differ diff --git a/client/Android/FreeRDPCore/res/drawable/sym_keyboard_arrows_black.png b/client/Android/FreeRDPCore/res/drawable/sym_keyboard_arrows_black.png index 3e9168240..53dc89293 100644 Binary files a/client/Android/FreeRDPCore/res/drawable/sym_keyboard_arrows_black.png and b/client/Android/FreeRDPCore/res/drawable/sym_keyboard_arrows_black.png differ diff --git a/client/Android/FreeRDPCore/res/drawable/sym_keyboard_down_arrow.png b/client/Android/FreeRDPCore/res/drawable/sym_keyboard_down_arrow.png index 9039b78e9..331fea5dc 100644 Binary files a/client/Android/FreeRDPCore/res/drawable/sym_keyboard_down_arrow.png and b/client/Android/FreeRDPCore/res/drawable/sym_keyboard_down_arrow.png differ diff --git a/client/Android/FreeRDPCore/res/drawable/sym_keyboard_down_arrow_black.png b/client/Android/FreeRDPCore/res/drawable/sym_keyboard_down_arrow_black.png index c01ef09ed..a17bcd78c 100644 Binary files a/client/Android/FreeRDPCore/res/drawable/sym_keyboard_down_arrow_black.png and b/client/Android/FreeRDPCore/res/drawable/sym_keyboard_down_arrow_black.png differ diff --git a/client/Android/FreeRDPCore/res/drawable/sym_keyboard_left_arrow.png b/client/Android/FreeRDPCore/res/drawable/sym_keyboard_left_arrow.png index 471e42171..0e67f890e 100644 Binary files a/client/Android/FreeRDPCore/res/drawable/sym_keyboard_left_arrow.png and b/client/Android/FreeRDPCore/res/drawable/sym_keyboard_left_arrow.png differ diff --git a/client/Android/FreeRDPCore/res/drawable/sym_keyboard_left_arrow_black.png b/client/Android/FreeRDPCore/res/drawable/sym_keyboard_left_arrow_black.png index b43956dd5..afc2b5cbd 100644 Binary files a/client/Android/FreeRDPCore/res/drawable/sym_keyboard_left_arrow_black.png and b/client/Android/FreeRDPCore/res/drawable/sym_keyboard_left_arrow_black.png differ diff --git a/client/Android/FreeRDPCore/res/drawable/sym_keyboard_menu.png b/client/Android/FreeRDPCore/res/drawable/sym_keyboard_menu.png index c92d6f225..b296f3339 100644 Binary files a/client/Android/FreeRDPCore/res/drawable/sym_keyboard_menu.png and b/client/Android/FreeRDPCore/res/drawable/sym_keyboard_menu.png differ diff --git a/client/Android/FreeRDPCore/res/drawable/sym_keyboard_menu_black.png b/client/Android/FreeRDPCore/res/drawable/sym_keyboard_menu_black.png index a24081b1c..fe5c072d8 100644 Binary files a/client/Android/FreeRDPCore/res/drawable/sym_keyboard_menu_black.png and b/client/Android/FreeRDPCore/res/drawable/sym_keyboard_menu_black.png differ diff --git a/client/Android/FreeRDPCore/res/drawable/sym_keyboard_right_arrow.png b/client/Android/FreeRDPCore/res/drawable/sym_keyboard_right_arrow.png index c82f696a6..d44ae11ab 100644 Binary files a/client/Android/FreeRDPCore/res/drawable/sym_keyboard_right_arrow.png and b/client/Android/FreeRDPCore/res/drawable/sym_keyboard_right_arrow.png differ diff --git a/client/Android/FreeRDPCore/res/drawable/sym_keyboard_right_arrow_black.png b/client/Android/FreeRDPCore/res/drawable/sym_keyboard_right_arrow_black.png index 19208ec0f..25c011b06 100644 Binary files a/client/Android/FreeRDPCore/res/drawable/sym_keyboard_right_arrow_black.png and b/client/Android/FreeRDPCore/res/drawable/sym_keyboard_right_arrow_black.png differ diff --git a/client/Android/FreeRDPCore/res/drawable/sym_keyboard_up_arrow.png b/client/Android/FreeRDPCore/res/drawable/sym_keyboard_up_arrow.png index ca187b5ca..ca62134a1 100644 Binary files a/client/Android/FreeRDPCore/res/drawable/sym_keyboard_up_arrow.png and b/client/Android/FreeRDPCore/res/drawable/sym_keyboard_up_arrow.png differ diff --git a/client/Android/FreeRDPCore/res/drawable/sym_keyboard_up_arrow_black.png b/client/Android/FreeRDPCore/res/drawable/sym_keyboard_up_arrow_black.png index 4240b5928..96577f487 100644 Binary files a/client/Android/FreeRDPCore/res/drawable/sym_keyboard_up_arrow_black.png and b/client/Android/FreeRDPCore/res/drawable/sym_keyboard_up_arrow_black.png differ diff --git a/client/Android/FreeRDPCore/res/drawable/sym_keyboard_winkey.png b/client/Android/FreeRDPCore/res/drawable/sym_keyboard_winkey.png index 6196b7246..8abbd6c32 100644 Binary files a/client/Android/FreeRDPCore/res/drawable/sym_keyboard_winkey.png and b/client/Android/FreeRDPCore/res/drawable/sym_keyboard_winkey.png differ diff --git a/client/Android/FreeRDPCore/res/drawable/sym_keyboard_winkey_black.png b/client/Android/FreeRDPCore/res/drawable/sym_keyboard_winkey_black.png index 8173d5c9c..778ad4fa6 100644 Binary files a/client/Android/FreeRDPCore/res/drawable/sym_keyboard_winkey_black.png and b/client/Android/FreeRDPCore/res/drawable/sym_keyboard_winkey_black.png differ diff --git a/client/Android/FreeRDPCore/res/drawable/touch_pointer_active.png b/client/Android/FreeRDPCore/res/drawable/touch_pointer_active.png index 9f91b2465..ac498e470 100644 Binary files a/client/Android/FreeRDPCore/res/drawable/touch_pointer_active.png and b/client/Android/FreeRDPCore/res/drawable/touch_pointer_active.png differ diff --git a/client/Android/FreeRDPCore/res/drawable/touch_pointer_default.png b/client/Android/FreeRDPCore/res/drawable/touch_pointer_default.png index 273e21114..98f9f5a33 100644 Binary files a/client/Android/FreeRDPCore/res/drawable/touch_pointer_default.png and b/client/Android/FreeRDPCore/res/drawable/touch_pointer_default.png differ diff --git a/client/Android/FreeRDPCore/res/drawable/touch_pointer_extkeyboard.png b/client/Android/FreeRDPCore/res/drawable/touch_pointer_extkeyboard.png index c82bdea37..f1fff6d4c 100644 Binary files a/client/Android/FreeRDPCore/res/drawable/touch_pointer_extkeyboard.png and b/client/Android/FreeRDPCore/res/drawable/touch_pointer_extkeyboard.png differ diff --git a/client/Android/FreeRDPCore/res/drawable/touch_pointer_keyboard.png b/client/Android/FreeRDPCore/res/drawable/touch_pointer_keyboard.png index cd58c87ee..08880bb5f 100644 Binary files a/client/Android/FreeRDPCore/res/drawable/touch_pointer_keyboard.png and b/client/Android/FreeRDPCore/res/drawable/touch_pointer_keyboard.png differ diff --git a/client/Android/FreeRDPCore/res/drawable/touch_pointer_lclick.png b/client/Android/FreeRDPCore/res/drawable/touch_pointer_lclick.png index f0a7afa93..90f2b1b9e 100644 Binary files a/client/Android/FreeRDPCore/res/drawable/touch_pointer_lclick.png and b/client/Android/FreeRDPCore/res/drawable/touch_pointer_lclick.png differ diff --git a/client/Android/FreeRDPCore/res/drawable/touch_pointer_rclick.png b/client/Android/FreeRDPCore/res/drawable/touch_pointer_rclick.png index 2129a1f33..dcb690489 100644 Binary files a/client/Android/FreeRDPCore/res/drawable/touch_pointer_rclick.png and b/client/Android/FreeRDPCore/res/drawable/touch_pointer_rclick.png differ diff --git a/client/Android/FreeRDPCore/res/drawable/touch_pointer_reset.png b/client/Android/FreeRDPCore/res/drawable/touch_pointer_reset.png index 3c1289474..b34b02e79 100644 Binary files a/client/Android/FreeRDPCore/res/drawable/touch_pointer_reset.png and b/client/Android/FreeRDPCore/res/drawable/touch_pointer_reset.png differ diff --git a/client/Android/FreeRDPCore/res/drawable/touch_pointer_scroll.png b/client/Android/FreeRDPCore/res/drawable/touch_pointer_scroll.png index b6205da61..c5275a4ce 100644 Binary files a/client/Android/FreeRDPCore/res/drawable/touch_pointer_scroll.png and b/client/Android/FreeRDPCore/res/drawable/touch_pointer_scroll.png differ diff --git a/client/Android/aFreeRDP/assets/FreeRDP_Logo.png b/client/Android/aFreeRDP/assets/FreeRDP_Logo.png index 3b2d02f1d..1e272627b 100644 Binary files a/client/Android/aFreeRDP/assets/FreeRDP_Logo.png and b/client/Android/aFreeRDP/assets/FreeRDP_Logo.png differ diff --git a/client/Android/aFreeRDP/assets/about_page/background_transparent.png b/client/Android/aFreeRDP/assets/about_page/background_transparent.png index 0eba5b5d2..d9d377bdf 100644 Binary files a/client/Android/aFreeRDP/assets/about_page/background_transparent.png and b/client/Android/aFreeRDP/assets/about_page/background_transparent.png differ diff --git a/client/Android/aFreeRDP/assets/background.jpg b/client/Android/aFreeRDP/assets/background.jpg index 3bf3455bf..fd4e1d364 100644 Binary files a/client/Android/aFreeRDP/assets/background.jpg and b/client/Android/aFreeRDP/assets/background.jpg differ diff --git a/client/Android/aFreeRDP/assets/de_about_page/background_transparent.png b/client/Android/aFreeRDP/assets/de_about_page/background_transparent.png index 0eba5b5d2..d9d377bdf 100644 Binary files a/client/Android/aFreeRDP/assets/de_about_page/background_transparent.png and b/client/Android/aFreeRDP/assets/de_about_page/background_transparent.png differ diff --git a/client/Android/aFreeRDP/assets/de_help_page/gestures.png b/client/Android/aFreeRDP/assets/de_help_page/gestures.png index e49a45b8f..78b3e7b34 100644 Binary files a/client/Android/aFreeRDP/assets/de_help_page/gestures.png and b/client/Android/aFreeRDP/assets/de_help_page/gestures.png differ diff --git a/client/Android/aFreeRDP/assets/de_help_page/gestures_phone.png b/client/Android/aFreeRDP/assets/de_help_page/gestures_phone.png index 1b90a1f65..4eea33ef4 100644 Binary files a/client/Android/aFreeRDP/assets/de_help_page/gestures_phone.png and b/client/Android/aFreeRDP/assets/de_help_page/gestures_phone.png differ diff --git a/client/Android/aFreeRDP/assets/de_help_page/nav_gestures.png b/client/Android/aFreeRDP/assets/de_help_page/nav_gestures.png index ab1b36fba..50bfaa232 100644 Binary files a/client/Android/aFreeRDP/assets/de_help_page/nav_gestures.png and b/client/Android/aFreeRDP/assets/de_help_page/nav_gestures.png differ diff --git a/client/Android/aFreeRDP/assets/de_help_page/nav_toolbar.png b/client/Android/aFreeRDP/assets/de_help_page/nav_toolbar.png index 703c0013a..f66b24d21 100644 Binary files a/client/Android/aFreeRDP/assets/de_help_page/nav_toolbar.png and b/client/Android/aFreeRDP/assets/de_help_page/nav_toolbar.png differ diff --git a/client/Android/aFreeRDP/assets/de_help_page/nav_touch_pointer.png b/client/Android/aFreeRDP/assets/de_help_page/nav_touch_pointer.png index 30e04568e..930fc9cbf 100644 Binary files a/client/Android/aFreeRDP/assets/de_help_page/nav_touch_pointer.png and b/client/Android/aFreeRDP/assets/de_help_page/nav_touch_pointer.png differ diff --git a/client/Android/aFreeRDP/assets/de_help_page/toolbar.png b/client/Android/aFreeRDP/assets/de_help_page/toolbar.png index 10c23b62b..42f055b9f 100644 Binary files a/client/Android/aFreeRDP/assets/de_help_page/toolbar.png and b/client/Android/aFreeRDP/assets/de_help_page/toolbar.png differ diff --git a/client/Android/aFreeRDP/assets/de_help_page/toolbar_phone.png b/client/Android/aFreeRDP/assets/de_help_page/toolbar_phone.png index a01279ce0..278cd3a9d 100644 Binary files a/client/Android/aFreeRDP/assets/de_help_page/toolbar_phone.png and b/client/Android/aFreeRDP/assets/de_help_page/toolbar_phone.png differ diff --git a/client/Android/aFreeRDP/assets/de_help_page/touch_pointer.png b/client/Android/aFreeRDP/assets/de_help_page/touch_pointer.png index f06e3889f..af3ebcab0 100644 Binary files a/client/Android/aFreeRDP/assets/de_help_page/touch_pointer.png and b/client/Android/aFreeRDP/assets/de_help_page/touch_pointer.png differ diff --git a/client/Android/aFreeRDP/assets/de_help_page/touch_pointer_phone.png b/client/Android/aFreeRDP/assets/de_help_page/touch_pointer_phone.png index 168749fd0..ab7c59896 100644 Binary files a/client/Android/aFreeRDP/assets/de_help_page/touch_pointer_phone.png and b/client/Android/aFreeRDP/assets/de_help_page/touch_pointer_phone.png differ diff --git a/client/Android/aFreeRDP/assets/help_page/gestures.png b/client/Android/aFreeRDP/assets/help_page/gestures.png index e49a45b8f..78b3e7b34 100644 Binary files a/client/Android/aFreeRDP/assets/help_page/gestures.png and b/client/Android/aFreeRDP/assets/help_page/gestures.png differ diff --git a/client/Android/aFreeRDP/assets/help_page/gestures_phone.png b/client/Android/aFreeRDP/assets/help_page/gestures_phone.png index 1b90a1f65..4eea33ef4 100644 Binary files a/client/Android/aFreeRDP/assets/help_page/gestures_phone.png and b/client/Android/aFreeRDP/assets/help_page/gestures_phone.png differ diff --git a/client/Android/aFreeRDP/assets/help_page/nav_gestures.png b/client/Android/aFreeRDP/assets/help_page/nav_gestures.png index ab1b36fba..50bfaa232 100644 Binary files a/client/Android/aFreeRDP/assets/help_page/nav_gestures.png and b/client/Android/aFreeRDP/assets/help_page/nav_gestures.png differ diff --git a/client/Android/aFreeRDP/assets/help_page/nav_toolbar.png b/client/Android/aFreeRDP/assets/help_page/nav_toolbar.png index 703c0013a..f66b24d21 100644 Binary files a/client/Android/aFreeRDP/assets/help_page/nav_toolbar.png and b/client/Android/aFreeRDP/assets/help_page/nav_toolbar.png differ diff --git a/client/Android/aFreeRDP/assets/help_page/nav_touch_pointer.png b/client/Android/aFreeRDP/assets/help_page/nav_touch_pointer.png index 30e04568e..930fc9cbf 100644 Binary files a/client/Android/aFreeRDP/assets/help_page/nav_touch_pointer.png and b/client/Android/aFreeRDP/assets/help_page/nav_touch_pointer.png differ diff --git a/client/Android/aFreeRDP/assets/help_page/toolbar.png b/client/Android/aFreeRDP/assets/help_page/toolbar.png index 10c23b62b..42f055b9f 100644 Binary files a/client/Android/aFreeRDP/assets/help_page/toolbar.png and b/client/Android/aFreeRDP/assets/help_page/toolbar.png differ diff --git a/client/Android/aFreeRDP/assets/help_page/toolbar_phone.png b/client/Android/aFreeRDP/assets/help_page/toolbar_phone.png index a01279ce0..278cd3a9d 100644 Binary files a/client/Android/aFreeRDP/assets/help_page/toolbar_phone.png and b/client/Android/aFreeRDP/assets/help_page/toolbar_phone.png differ diff --git a/client/Android/aFreeRDP/assets/help_page/touch_pointer.png b/client/Android/aFreeRDP/assets/help_page/touch_pointer.png index f06e3889f..af3ebcab0 100644 Binary files a/client/Android/aFreeRDP/assets/help_page/touch_pointer.png and b/client/Android/aFreeRDP/assets/help_page/touch_pointer.png differ diff --git a/client/Android/aFreeRDP/assets/help_page/touch_pointer_phone.png b/client/Android/aFreeRDP/assets/help_page/touch_pointer_phone.png index 168749fd0..ab7c59896 100644 Binary files a/client/Android/aFreeRDP/assets/help_page/touch_pointer_phone.png and b/client/Android/aFreeRDP/assets/help_page/touch_pointer_phone.png differ diff --git a/client/Android/aFreeRDP/res/drawable-hdpi/icon_launcher_freerdp.png b/client/Android/aFreeRDP/res/drawable-hdpi/icon_launcher_freerdp.png index 45ed86123..ff31f2576 100644 Binary files a/client/Android/aFreeRDP/res/drawable-hdpi/icon_launcher_freerdp.png and b/client/Android/aFreeRDP/res/drawable-hdpi/icon_launcher_freerdp.png differ diff --git a/client/Android/aFreeRDP/res/drawable-ldpi/icon_launcher_freerdp.png b/client/Android/aFreeRDP/res/drawable-ldpi/icon_launcher_freerdp.png index b57651bed..49726f4f0 100644 Binary files a/client/Android/aFreeRDP/res/drawable-ldpi/icon_launcher_freerdp.png and b/client/Android/aFreeRDP/res/drawable-ldpi/icon_launcher_freerdp.png differ diff --git a/client/Android/aFreeRDP/res/drawable-mdpi/icon_launcher_freerdp.png b/client/Android/aFreeRDP/res/drawable-mdpi/icon_launcher_freerdp.png index 55335c869..6b18c0ae3 100644 Binary files a/client/Android/aFreeRDP/res/drawable-mdpi/icon_launcher_freerdp.png and b/client/Android/aFreeRDP/res/drawable-mdpi/icon_launcher_freerdp.png differ diff --git a/client/Android/aFreeRDP/res/drawable/icon_launcher_freerdp.png b/client/Android/aFreeRDP/res/drawable/icon_launcher_freerdp.png index ad325d46e..53c5b36e1 100644 Binary files a/client/Android/aFreeRDP/res/drawable/icon_launcher_freerdp.png and b/client/Android/aFreeRDP/res/drawable/icon_launcher_freerdp.png differ diff --git a/client/DirectFB/dfreerdp.c b/client/DirectFB/dfreerdp.c index df68a1d6c..c231cd583 100644 --- a/client/DirectFB/dfreerdp.c +++ b/client/DirectFB/dfreerdp.c @@ -292,7 +292,7 @@ static void df_process_channel_event(rdpChannels* channels, freerdp* instance) break; default: - fprintf(stderr, "df_process_channel_event: unknown event type %d\n", GetMessageType(event->id)); + DEBUG_WARN( "df_process_channel_event: unknown event type %d\n", GetMessageType(event->id)); break; } @@ -339,17 +339,17 @@ int dfreerdp_run(freerdp* instance) if (freerdp_get_fds(instance, rfds, &rcount, wfds, &wcount) != TRUE) { - fprintf(stderr, "Failed to get FreeRDP file descriptor\n"); + DEBUG_WARN( "Failed to get FreeRDP file descriptor\n"); break; } if (freerdp_channels_get_fds(channels, instance, rfds, &rcount, wfds, &wcount) != TRUE) { - fprintf(stderr, "Failed to get channel manager file descriptor\n"); + DEBUG_WARN( "Failed to get channel manager file descriptor\n"); break; } if (df_get_fds(instance, rfds, &rcount, wfds, &wcount) != TRUE) { - fprintf(stderr, "Failed to get dfreerdp file descriptor\n"); + DEBUG_WARN( "Failed to get dfreerdp file descriptor\n"); break; } @@ -378,24 +378,24 @@ int dfreerdp_run(freerdp* instance) (errno == EINPROGRESS) || (errno == EINTR))) /* signal occurred */ { - fprintf(stderr, "dfreerdp_run: select failed\n"); + DEBUG_WARN( "dfreerdp_run: select failed\n"); break; } } if (freerdp_check_fds(instance) != TRUE) { - fprintf(stderr, "Failed to check FreeRDP file descriptor\n"); + DEBUG_WARN( "Failed to check FreeRDP file descriptor\n"); break; } if (df_check_fds(instance, &rfds_set) != TRUE) { - fprintf(stderr, "Failed to check dfreerdp file descriptor\n"); + DEBUG_WARN( "Failed to check dfreerdp file descriptor\n"); break; } if (freerdp_channels_check_fds(channels, instance) != TRUE) { - fprintf(stderr, "Failed to check channel manager file descriptor\n"); + DEBUG_WARN( "Failed to check channel manager file descriptor\n"); break; } df_process_channel_event(channels, instance); diff --git a/client/Mac/MRDPView.m b/client/Mac/MRDPView.m index 5de0da47f..c298efe23 100644 --- a/client/Mac/MRDPView.m +++ b/client/Mac/MRDPView.m @@ -617,7 +617,7 @@ DWORD fixKeyCode(DWORD keyCode, unichar keyChar, enum APPLE_KEYBOARD_TYPE type) vkcode &= 0xFF; #if 0 - fprintf(stderr, "keyDown: keyCode: 0x%04X scancode: 0x%04X vkcode: 0x%04X keyFlags: %d name: %s\n", + DEBUG_WARN( "keyDown: keyCode: 0x%04X scancode: 0x%04X vkcode: 0x%04X keyFlags: %d name: %s\n", keyCode, scancode, vkcode, keyFlags, GetVirtualKeyName(vkcode)); #endif @@ -654,7 +654,7 @@ DWORD fixKeyCode(DWORD keyCode, unichar keyChar, enum APPLE_KEYBOARD_TYPE type) vkcode &= 0xFF; #if 0 - fprintf(stderr, "keyUp: key: 0x%04X scancode: 0x%04X vkcode: 0x%04X keyFlags: %d name: %s\n", + DEBUG_WARN( "keyUp: key: 0x%04X scancode: 0x%04X vkcode: 0x%04X keyFlags: %d name: %s\n", keyCode, scancode, vkcode, keyFlags, GetVirtualKeyName(vkcode)); #endif @@ -683,29 +683,29 @@ DWORD fixKeyCode(DWORD keyCode, unichar keyChar, enum APPLE_KEYBOARD_TYPE type) vkcode &= 0xFF; #if 0 - fprintf(stderr, "flagsChanged: key: 0x%04X scancode: 0x%04X vkcode: 0x%04X extended: %d name: %s modFlags: 0x%04X\n", + DEBUG_WARN( "flagsChanged: key: 0x%04X scancode: 0x%04X vkcode: 0x%04X extended: %d name: %s modFlags: 0x%04X\n", key - 8, scancode, vkcode, keyFlags, GetVirtualKeyName(vkcode), modFlags); if (modFlags & NSAlphaShiftKeyMask) - fprintf(stderr, "NSAlphaShiftKeyMask\n"); + DEBUG_WARN( "NSAlphaShiftKeyMask\n"); if (modFlags & NSShiftKeyMask) - fprintf(stderr, "NSShiftKeyMask\n"); + DEBUG_WARN( "NSShiftKeyMask\n"); if (modFlags & NSControlKeyMask) - fprintf(stderr, "NSControlKeyMask\n"); + DEBUG_WARN( "NSControlKeyMask\n"); if (modFlags & NSAlternateKeyMask) - fprintf(stderr, "NSAlternateKeyMask\n"); + DEBUG_WARN( "NSAlternateKeyMask\n"); if (modFlags & NSCommandKeyMask) - fprintf(stderr, "NSCommandKeyMask\n"); + DEBUG_WARN( "NSCommandKeyMask\n"); if (modFlags & NSNumericPadKeyMask) - fprintf(stderr, "NSNumericPadKeyMask\n"); + DEBUG_WARN( "NSNumericPadKeyMask\n"); if (modFlags & NSHelpKeyMask) - fprintf(stderr, "NSHelpKeyMask\n"); + DEBUG_WARN( "NSHelpKeyMask\n"); #endif if ((modFlags & NSAlphaShiftKeyMask) && !(kbdModFlags & NSAlphaShiftKeyMask)) @@ -832,7 +832,7 @@ BOOL mac_pre_connect(freerdp* instance) if (!settings->ServerHostname) { - fprintf(stderr, "error: server hostname was not specified with /v:[:port]\n"); + DEBUG_WARN( "error: server hostname was not specified with /v:[:port]\n"); [NSApp terminate:nil]; return -1; } @@ -1200,7 +1200,7 @@ static void update_activity_cb(freerdp* instance) } else { - fprintf(stderr, "update_activity_cb: No queue!\n"); + DEBUG_WARN( "update_activity_cb: No queue!\n"); } } @@ -1225,7 +1225,7 @@ static void input_activity_cb(freerdp* instance) } else { - fprintf(stderr, "input_activity_cb: No queue!\n"); + DEBUG_WARN( "input_activity_cb: No queue!\n"); } } @@ -1238,7 +1238,7 @@ static void channel_activity_cb(freerdp* instance) if (event) { - fprintf(stderr, "channel_activity_cb: message %d\n", event->id); + DEBUG_WARN( "channel_activity_cb: message %d\n", event->id); switch (GetMessageClass(event->id)) { diff --git a/client/Sample/freerdp.c b/client/Sample/freerdp.c index 4495bf9a9..cedc3dc98 100644 --- a/client/Sample/freerdp.c +++ b/client/Sample/freerdp.c @@ -294,6 +294,7 @@ void* thread_func(void* param) if (g_thread_count < 1) ReleaseSemaphore(g_sem, 1, NULL); + ExitThread(0); return NULL; } diff --git a/client/Windows/resource/bg.bmp b/client/Windows/resource/bg.bmp index c97ef5d99..7e90ec6ef 100644 Binary files a/client/Windows/resource/bg.bmp and b/client/Windows/resource/bg.bmp differ diff --git a/client/Windows/resource/close.bmp b/client/Windows/resource/close.bmp index 8fce91657..f9bf31eb0 100644 Binary files a/client/Windows/resource/close.bmp and b/client/Windows/resource/close.bmp differ diff --git a/client/Windows/resource/close_active.bmp b/client/Windows/resource/close_active.bmp index 2c58a3de6..43dc5b2ba 100644 Binary files a/client/Windows/resource/close_active.bmp and b/client/Windows/resource/close_active.bmp differ diff --git a/client/Windows/resource/lock.bmp b/client/Windows/resource/lock.bmp index 91d7384d9..685778735 100644 Binary files a/client/Windows/resource/lock.bmp and b/client/Windows/resource/lock.bmp differ diff --git a/client/Windows/resource/lock_active.bmp b/client/Windows/resource/lock_active.bmp index 78e2ed45e..b4fa35f22 100644 Binary files a/client/Windows/resource/lock_active.bmp and b/client/Windows/resource/lock_active.bmp differ diff --git a/client/Windows/resource/minimize.bmp b/client/Windows/resource/minimize.bmp index f4c5f6c7a..7fce92d08 100644 Binary files a/client/Windows/resource/minimize.bmp and b/client/Windows/resource/minimize.bmp differ diff --git a/client/Windows/resource/minimize_active.bmp b/client/Windows/resource/minimize_active.bmp index 152fad298..6f0b74db7 100644 Binary files a/client/Windows/resource/minimize_active.bmp and b/client/Windows/resource/minimize_active.bmp differ diff --git a/client/Windows/resource/restore.bmp b/client/Windows/resource/restore.bmp index d74eddf23..b2ae47b67 100644 Binary files a/client/Windows/resource/restore.bmp and b/client/Windows/resource/restore.bmp differ diff --git a/client/Windows/resource/restore_active.bmp b/client/Windows/resource/restore_active.bmp index f88bc4d9a..a0516afd0 100644 Binary files a/client/Windows/resource/restore_active.bmp and b/client/Windows/resource/restore_active.bmp differ diff --git a/client/Windows/resource/unlock.bmp b/client/Windows/resource/unlock.bmp index 8359ae7cc..f59b72a01 100644 Binary files a/client/Windows/resource/unlock.bmp and b/client/Windows/resource/unlock.bmp differ diff --git a/client/Windows/resource/unlock_active.bmp b/client/Windows/resource/unlock_active.bmp index 59d730d6e..a5d9c3818 100644 Binary files a/client/Windows/resource/unlock_active.bmp and b/client/Windows/resource/unlock_active.bmp differ diff --git a/client/Windows/wf_cliprdr.c b/client/Windows/wf_cliprdr.c index d319c83de..a98ab613d 100644 --- a/client/Windows/wf_cliprdr.c +++ b/client/Windows/wf_cliprdr.c @@ -20,7 +20,6 @@ #ifdef HAVE_CONFIG_H #include "config.h" #endif - #include #include @@ -32,6 +31,9 @@ #include "wf_cliprdr.h" +extern BOOL WINAPI AddClipboardFormatListener(_In_ HWND hwnd); +extern BOOL WINAPI RemoveClipboardFormatListener(_In_ HWND hwnd); + #define WM_CLIPRDR_MESSAGE (WM_USER + 156) #define OLE_SETCLIPBOARD 1 @@ -129,7 +131,14 @@ static void clear_format_map(cliprdrContext *cliprdr) cliprdr->map_size= 0; } - +/* +2.2.2.3 Client Temporary Directory PDU (CLIPRDR_TEMP_DIRECTORY) + The Temporary Directory PDU is an optional PDU sent from the client to the server. + This PDU informs the server of a location on the client file system that MUST be + used to deposit files being copied to the client. The location MUST be accessible + by the server to be useful. Section 3.1.1.3 specifies how direct file access + impacts file copy and paste. +*/ int cliprdr_send_tempdir(cliprdrContext *cliprdr) { RDP_CB_TEMPDIR_EVENT *cliprdr_event; @@ -140,6 +149,9 @@ int cliprdr_send_tempdir(cliprdrContext *cliprdr) if (!cliprdr_event) return -1; + /* Sending the TEMP path would only be valid iff the path is accessible from the server. + This should perhaps to change to a command line parameter value + */ GetEnvironmentVariableW(L"TEMP", (LPWSTR)cliprdr_event->dirname, 260); return freerdp_channels_send_event(cliprdr->channels, (wMessage *)cliprdr_event); @@ -367,32 +379,21 @@ static LRESULT CALLBACK cliprdr_proc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM switch (Msg) { case WM_CREATE: + DEBUG_CLIPRDR("info: %s - WM_CREATE", __FUNCTION__); cliprdr = (cliprdrContext *)((CREATESTRUCT *)lParam)->lpCreateParams; - cliprdr->hwndNextViewer = SetClipboardViewer(hWnd); - - if (cliprdr->hwndNextViewer == NULL && GetLastError() != 0) - { - DEBUG_CLIPRDR("error: SetClipboardViewer failed with 0x%0x.", GetLastError()); + if (!AddClipboardFormatListener(hWnd)) { + DEBUG_CLIPRDR("error: AddClipboardFormatListener failed with %#x.", GetLastError()); } cliprdr->hwndClipboard = hWnd; break; case WM_CLOSE: - ChangeClipboardChain(hWnd, cliprdr->hwndNextViewer); + DEBUG_CLIPRDR("info: %s - WM_CLOSE", __FUNCTION__); + RemoveClipboardFormatListener(hWnd); break; - case WM_CHANGECBCHAIN: - if (cliprdr->hwndNextViewer == (HWND)wParam) - { - cliprdr->hwndNextViewer = (HWND)lParam; - } - else if (cliprdr->hwndNextViewer != NULL) - { - SendMessage(cliprdr->hwndNextViewer, Msg, wParam, lParam); - } - break; - - case WM_DRAWCLIPBOARD: + case WM_CLIPBOARDUPDATE: + DEBUG_CLIPRDR("info: %s - WM_CLIPBOARDUPDATE", __FUNCTION__); if (cliprdr->channel_initialized) { if ((GetClipboardOwner() != cliprdr->hwndClipboard) && (S_FALSE == OleIsCurrentClipboard(cliprdr->data_obj))) @@ -404,11 +405,10 @@ static LRESULT CALLBACK cliprdr_proc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM cliprdr_send_format_list(cliprdr); } } - if (cliprdr->hwndNextViewer != NULL && cliprdr->hwndNextViewer != hWnd) - SendMessage(cliprdr->hwndNextViewer, Msg, wParam, lParam); break; case WM_RENDERALLFORMATS: + DEBUG_CLIPRDR("info: %s - WM_RENDERALLFORMATS", __FUNCTION__); /* discard all contexts in clipboard */ if (!OpenClipboard(cliprdr->hwndClipboard)) { @@ -420,6 +420,7 @@ static LRESULT CALLBACK cliprdr_proc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM break; case WM_RENDERFORMAT: + DEBUG_CLIPRDR("info: %s - WM_RENDERFORMAT", __FUNCTION__); if (cliprdr_send_data_request(cliprdr, (UINT32)wParam) != 0) { DEBUG_CLIPRDR("error: cliprdr_send_data_request failed."); @@ -435,9 +436,11 @@ static LRESULT CALLBACK cliprdr_proc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM break; case WM_CLIPRDR_MESSAGE: + DEBUG_CLIPRDR("info: %s - WM_CLIPRDR_MESSAGE", __FUNCTION__); switch (wParam) { case OLE_SETCLIPBOARD: + DEBUG_CLIPRDR("info: %s - OLE_SETCLIPBOARD", __FUNCTION__); if (wf_create_file_obj(cliprdr, &cliprdr->data_obj)) if (OleSetClipboard(cliprdr->data_obj) != S_OK) wf_destroy_file_obj(cliprdr->data_obj); @@ -448,7 +451,6 @@ static LRESULT CALLBACK cliprdr_proc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM } break; - case WM_CLIPBOARDUPDATE: case WM_DESTROYCLIPBOARD: case WM_ASKCBFORMATNAME: case WM_HSCROLLCLIPBOARD: @@ -568,7 +570,7 @@ void wf_cliprdr_init(wfContext* wfc, rdpChannels* channels) if (!wfc->instance->settings->RedirectClipboard) { wfc->cliprdr_context = NULL; - fprintf(stderr, "clipboard is not redirected.\n"); + DEBUG_WARN( "clipboard is not redirected.\n"); return; } @@ -643,9 +645,12 @@ static void wf_cliprdr_process_cb_clip_caps_event(wfContext *wfc, RDP_CB_CLIP_CA static void wf_cliprdr_process_cb_monitor_ready_event(wfContext *wfc, RDP_CB_MONITOR_READY_EVENT *ready_event) { cliprdrContext *cliprdr = (cliprdrContext *)wfc->cliprdr_context; - +#if 0 + /*Disabled since the current function only sends the temp directory which is not + guaranteed to be accessible to the server + */ cliprdr_send_tempdir(cliprdr); - +#endif cliprdr->channel_initialized = TRUE; cliprdr_send_format_list(wfc->cliprdr_context); @@ -658,7 +663,7 @@ static BOOL wf_cliprdr_get_file_contents(wchar_t *file_name, BYTE *buffer, int p if (file_name == NULL || buffer == NULL || puSize == NULL) { - fprintf(stderr, "get file contents Invalid Arguments.\n"); + DEBUG_WARN( "get file contents Invalid Arguments.\n"); return FALSE; } hFile = CreateFileW(file_name, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_BACKUP_SEMANTICS, NULL); @@ -1175,7 +1180,7 @@ static void wf_cliprdr_process_cb_filecontents_request_event(wfContext *wfc, RDP hRet = OleGetClipboard(&pDataObj); if (!SUCCEEDED(hRet)) { - fprintf(stderr, "filecontents: get ole clipboard failed.\n"); + DEBUG_WARN( "filecontents: get ole clipboard failed.\n"); goto error; } @@ -1273,7 +1278,7 @@ static void wf_cliprdr_process_cb_filecontents_request_event(wfContext *wfc, RDP event->nPositionLow, event->nPositionHigh, event->cbRequested, &uSize); if (bRet == FALSE) { - fprintf(stderr, "get file contents failed.\n"); + DEBUG_WARN( "get file contents failed.\n"); uSize = 0; goto error; } @@ -1304,7 +1309,7 @@ error: IDataObject_Release(pDataObj); pDataObj = NULL; } - fprintf(stderr, "filecontents: send failed response.\n"); + DEBUG_WARN( "filecontents: send failed response.\n"); cliprdr_send_response_filecontents(cliprdr, event->streamId, 0, NULL); return; } diff --git a/client/Windows/wf_cliprdr.h b/client/Windows/wf_cliprdr.h index c286bcce1..e967b02e3 100644 --- a/client/Windows/wf_cliprdr.h +++ b/client/Windows/wf_cliprdr.h @@ -53,7 +53,6 @@ struct cliprdr_context { BOOL channel_initialized; HWND hwndClipboard; - HWND hwndNextViewer; HANDLE cliprdr_thread; HANDLE hmem; diff --git a/client/Windows/wf_event.c b/client/Windows/wf_event.c index cc54df906..941ff5234 100644 --- a/client/Windows/wf_event.c +++ b/client/Windows/wf_event.c @@ -255,7 +255,10 @@ LRESULT CALLBACK wf_event_proc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam // Set maximum window size for resizing minmax = (MINMAXINFO*) lParam; - wf_update_canvas_diff(wfc); + + //always use the last determined canvas diff, because it could be + //that the window is minimized when this gets called + //wf_update_canvas_diff(wfc); if (!wfc->fullscreen) { @@ -281,11 +284,14 @@ LRESULT CALLBACK wf_event_proc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam wfc->client_y = windowRect.top; } - wf_size_scrollbars(wfc, LOWORD(lParam), HIWORD(lParam)); + if (wfc->client_width && wfc->client_height) + { + wf_size_scrollbars(wfc, LOWORD(lParam), HIWORD(lParam)); - // Workaround: when the window is maximized, the call to "ShowScrollBars" returns TRUE but has no effect. - if (wParam == SIZE_MAXIMIZED && !wfc->fullscreen) - SetWindowPos(wfc->hwnd, HWND_TOP, 0, 0, windowRect.right - windowRect.left, windowRect.bottom - windowRect.top, SWP_NOMOVE | SWP_FRAMECHANGED); + // Workaround: when the window is maximized, the call to "ShowScrollBars" returns TRUE but has no effect. + if (wParam == SIZE_MAXIMIZED && !wfc->fullscreen) + SetWindowPos(wfc->hwnd, HWND_TOP, 0, 0, windowRect.right - windowRect.left, windowRect.bottom - windowRect.top, SWP_NOMOVE | SWP_FRAMECHANGED); + } break; diff --git a/client/Windows/wf_gdi.c b/client/Windows/wf_gdi.c index 1c87072c4..183401632 100644 --- a/client/Windows/wf_gdi.c +++ b/client/Windows/wf_gdi.c @@ -63,7 +63,7 @@ BOOL wf_set_rop2(HDC hdc, int rop2) { if ((rop2 < 0x01) || (rop2 > 0x10)) { - fprintf(stderr, "Unsupported ROP2: %d\n", rop2); + DEBUG_WARN( "Unsupported ROP2: %d\n", rop2); return FALSE; } @@ -643,7 +643,7 @@ void wf_gdi_surface_bits(wfContext* wfc, SURFACE_BITS_COMMAND* surface_bits_comm } else { - fprintf(stderr, "Unsupported codecID %d\n", surface_bits_command->codecID); + DEBUG_WARN( "Unsupported codecID %d\n", surface_bits_command->codecID); } if (tile_bitmap != NULL) diff --git a/client/Windows/wf_graphics.c b/client/Windows/wf_graphics.c index a3b40f291..c33f14a82 100644 --- a/client/Windows/wf_graphics.c +++ b/client/Windows/wf_graphics.c @@ -161,7 +161,7 @@ void wf_Bitmap_Decompress(wfContext* wfc, rdpBitmap* bitmap, if (status != TRUE) { - fprintf(stderr, "Bitmap Decompression Failed\n"); + DEBUG_WARN( "Bitmap Decompression Failed\n"); } } else diff --git a/client/Windows/wf_interface.c b/client/Windows/wf_interface.c index ec7c70db2..3fb115d43 100644 --- a/client/Windows/wf_interface.c +++ b/client/Windows/wf_interface.c @@ -65,7 +65,7 @@ int wf_create_console(void) freopen("CONOUT$", "w", stdout); freopen("CONOUT$", "w", stderr); - fprintf(stderr, "Debug console created.\n"); + DEBUG_WARN( "Debug console created.\n"); return 0; } @@ -202,7 +202,7 @@ BOOL wf_pre_connect(freerdp* instance) wfc->connectionRdpFile = freerdp_client_rdp_file_new(); - fprintf(stderr, "Using connection file: %s\n", settings->ConnectionFile); + DEBUG_WARN( "Using connection file: %s\n", settings->ConnectionFile); freerdp_client_parse_rdp_file(wfc->connectionRdpFile, settings->ConnectionFile); freerdp_client_populate_settings_from_rdp_file(wfc->connectionRdpFile, settings); @@ -291,7 +291,7 @@ BOOL wf_pre_connect(freerdp* instance) if ((settings->DesktopWidth < 64) || (settings->DesktopHeight < 64) || (settings->DesktopWidth > 4096) || (settings->DesktopHeight > 4096)) { - fprintf(stderr, "wf_pre_connect: invalid dimensions %d %d\n", settings->DesktopWidth, settings->DesktopHeight); + DEBUG_WARN( "wf_pre_connect: invalid dimensions %d %d\n", settings->DesktopWidth, settings->DesktopHeight); return 1; } @@ -394,10 +394,12 @@ BOOL wf_post_connect(freerdp* instance) if (settings->EmbeddedWindow) settings->Decorations = FALSE; - if (!settings->Decorations) + if (wfc->fullscreen) + dwStyle = WS_POPUP; + else if (!settings->Decorations) dwStyle = WS_CHILD | WS_BORDER; else - dwStyle = 0; + dwStyle = WS_CAPTION | WS_OVERLAPPED | WS_SYSMENU | WS_MINIMIZEBOX | WS_SIZEBOX | WS_MAXIMIZEBOX; if (!wfc->hwnd) { @@ -487,7 +489,7 @@ BOOL wf_authenticate(freerdp* instance, char** username, char** password, char** if (status != NO_ERROR) { - fprintf(stderr, "CredUIPromptForCredentials unexpected status: 0x%08X\n", status); + DEBUG_WARN( "CredUIPromptForCredentials unexpected status: 0x%08X\n", status); return FALSE; } @@ -496,7 +498,7 @@ BOOL wf_authenticate(freerdp* instance, char** username, char** password, char** status = CredUIParseUserNameA(UserName, User, sizeof(User), Domain, sizeof(Domain)); - //fprintf(stderr, "User: %s Domain: %s Password: %s\n", User, Domain, Password); + //DEBUG_WARN( "User: %s Domain: %s Password: %s\n", User, Domain, Password); *username = _strdup(User); @@ -590,7 +592,7 @@ static BOOL wf_auto_reconnect(freerdp* instance) return FALSE; /* A network disconnect was detected */ - fprintf(stderr, "Network disconnect!\n"); + DEBUG_WARN( "Network disconnect!\n"); if (!instance->settings->AutoReconnectionEnabled) { /* No auto-reconnect - just quit */ @@ -605,7 +607,7 @@ static BOOL wf_auto_reconnect(freerdp* instance) return FALSE; /* Attempt the next reconnect */ - fprintf(stderr, "Attempting reconnect (%u of %u)\n", num_retries, max_retries); + DEBUG_WARN( "Attempting reconnect (%u of %u)\n", num_retries, max_retries); if (freerdp_reconnect(instance)) { return TRUE; @@ -614,7 +616,7 @@ static BOOL wf_auto_reconnect(freerdp* instance) Sleep(5000); } - fprintf(stderr, "Maximum reconnect retries exceeded\n"); + DEBUG_WARN( "Maximum reconnect retries exceeded\n"); return FALSE; } @@ -652,39 +654,6 @@ void* wf_input_thread(void* arg) return NULL; } -void* wf_update_thread(void* arg) -{ - int status; - wMessage message; - wMessageQueue* queue; - freerdp* instance = (freerdp*) arg; - - assert( NULL != instance); - - status = 1; - queue = freerdp_get_message_queue(instance, - FREERDP_UPDATE_MESSAGE_QUEUE); - - while (MessageQueue_Wait(queue)) - { - while (MessageQueue_Peek(queue, &message, TRUE)) - { - status = freerdp_message_queue_process_message(instance, - FREERDP_UPDATE_MESSAGE_QUEUE, &message); - - if (!status) - break; - } - - if (!status) - break; - } - - ExitThread(0); - - return NULL; -} - void* wf_channels_thread(void* arg) { int status; @@ -728,11 +697,9 @@ DWORD WINAPI wf_client_thread(LPVOID lpParam) rdpChannels* channels; rdpSettings* settings; - BOOL async_update; BOOL async_input; BOOL async_channels; BOOL async_transport; - HANDLE update_thread; HANDLE input_thread; HANDLE channels_thread; @@ -751,18 +718,10 @@ DWORD WINAPI wf_client_thread(LPVOID lpParam) channels = instance->context->channels; settings = instance->context->settings; - async_update = settings->AsyncUpdate; async_input = settings->AsyncInput; async_channels = settings->AsyncChannels; async_transport = settings->AsyncTransport; - if (async_update) - { - update_thread = CreateThread(NULL, 0, - (LPTHREAD_START_ROUTINE) wf_update_thread, - instance, 0, NULL); - } - if (async_input) { input_thread = CreateThread(NULL, 0, @@ -784,13 +743,13 @@ DWORD WINAPI wf_client_thread(LPVOID lpParam) { if (freerdp_get_fds(instance, rfds, &rcount, wfds, &wcount) != TRUE) { - fprintf(stderr, "Failed to get FreeRDP file descriptor\n"); + DEBUG_WARN( "Failed to get FreeRDP file descriptor\n"); break; } } if (wf_get_fds(instance, rfds, &rcount, wfds, &wcount) != TRUE) { - fprintf(stderr, "Failed to get wfreerdp file descriptor\n"); + DEBUG_WARN( "Failed to get wfreerdp file descriptor\n"); break; } @@ -798,7 +757,7 @@ DWORD WINAPI wf_client_thread(LPVOID lpParam) { if (freerdp_channels_get_fds(channels, instance, rfds, &rcount, wfds, &wcount) != TRUE) { - fprintf(stderr, "Failed to get channel manager file descriptor\n"); + DEBUG_WARN( "Failed to get channel manager file descriptor\n"); break; } } @@ -816,14 +775,14 @@ DWORD WINAPI wf_client_thread(LPVOID lpParam) /* exit if nothing to do */ if (fds_count == 0) { - fprintf(stderr, "wfreerdp_run: fds_count is zero\n"); + DEBUG_WARN( "wfreerdp_run: fds_count is zero\n"); //break; } /* do the wait */ if (MsgWaitForMultipleObjects(fds_count, fds, FALSE, 1000, QS_ALLINPUT) == WAIT_FAILED) { - fprintf(stderr, "wfreerdp_run: WaitForMultipleObjects failed: 0x%04X\n", GetLastError()); + DEBUG_WARN( "wfreerdp_run: WaitForMultipleObjects failed: 0x%04X\n", GetLastError()); break; } @@ -834,7 +793,7 @@ DWORD WINAPI wf_client_thread(LPVOID lpParam) if (wf_auto_reconnect(instance)) continue; - fprintf(stderr, "Failed to check FreeRDP file descriptor\n"); + DEBUG_WARN( "Failed to check FreeRDP file descriptor\n"); break; } } @@ -844,7 +803,7 @@ DWORD WINAPI wf_client_thread(LPVOID lpParam) } if (wf_check_fds(instance) != TRUE) { - fprintf(stderr, "Failed to check wfreerdp file descriptor\n"); + DEBUG_WARN( "Failed to check wfreerdp file descriptor\n"); break; } @@ -852,7 +811,7 @@ DWORD WINAPI wf_client_thread(LPVOID lpParam) { if (freerdp_channels_check_fds(channels, instance) != TRUE) { - fprintf(stderr, "Failed to check channel manager file descriptor\n"); + DEBUG_WARN( "Failed to check channel manager file descriptor\n"); break; } @@ -905,17 +864,6 @@ DWORD WINAPI wf_client_thread(LPVOID lpParam) /* cleanup */ freerdp_channels_close(channels, instance); - if (async_update) - { - wMessageQueue* update_queue; - - update_queue = freerdp_get_message_queue(instance, - FREERDP_UPDATE_MESSAGE_QUEUE); - MessageQueue_PostQuit(update_queue, 0); - WaitForSingleObject(update_thread, INFINITE); - CloseHandle(update_thread); - } - if (async_input) { wMessageQueue* input_queue; @@ -960,7 +908,7 @@ DWORD WINAPI wf_keyboard_thread(LPVOID lpParam) { if (status == -1) { - fprintf(stderr, "keyboard thread error getting message\n"); + DEBUG_WARN( "keyboard thread error getting message\n"); break; } else @@ -974,7 +922,7 @@ DWORD WINAPI wf_keyboard_thread(LPVOID lpParam) } else { - fprintf(stderr, "failed to install keyboard hook\n"); + DEBUG_WARN( "failed to install keyboard hook\n"); } printf("Keyboard thread exited.\n"); @@ -1002,7 +950,7 @@ int freerdp_client_focus_out(wfContext* wfc) int freerdp_client_set_window_size(wfContext* wfc, int width, int height) { - fprintf(stderr, "freerdp_client_set_window_size %d, %d", width, height); + DEBUG_WARN( "freerdp_client_set_window_size %d, %d", width, height); if ((width != wfc->client_width) || (height != wfc->client_height)) { @@ -1027,7 +975,7 @@ int freerdp_client_load_settings_from_rdp_file(wfContext* wfc, char* filename) freerdp_client_rdp_file_free(wfc->connectionRdpFile); wfc->connectionRdpFile = freerdp_client_rdp_file_new(); - fprintf(stderr, "Using connection file: %s\n", settings->ConnectionFile); + DEBUG_WARN( "Using connection file: %s\n", settings->ConnectionFile); if (!freerdp_client_parse_rdp_file(wfc->connectionRdpFile, settings->ConnectionFile)) { diff --git a/client/X11/generate_argument_docbook.c b/client/X11/generate_argument_docbook.c index 4b49f34da..c1a3035e7 100644 --- a/client/X11/generate_argument_docbook.c +++ b/client/X11/generate_argument_docbook.c @@ -26,7 +26,7 @@ LPSTR tr_esc_str(LPCSTR arg) tmp = (LPSTR)realloc(tmp, ds * sizeof(CHAR)); if(NULL == tmp) { - fprintf(stderr, "Could not allocate string buffer."); + DEBUG_WARN( "Could not allocate string buffer."); exit(-2); } /* Copy character for character and check, if it is necessary to escape. */ @@ -40,7 +40,7 @@ LPSTR tr_esc_str(LPCSTR arg) tmp = (LPSTR)realloc(tmp, ds * sizeof(CHAR)); if(NULL == tmp) { - fprintf(stderr, "Could not reallocate string buffer."); + DEBUG_WARN( "Could not reallocate string buffer."); exit(-3); } tmp[cs++] = '&'; @@ -53,7 +53,7 @@ LPSTR tr_esc_str(LPCSTR arg) tmp = (LPSTR)realloc(tmp, ds * sizeof(CHAR)); if(NULL == tmp) { - fprintf(stderr, "Could not reallocate string buffer."); + DEBUG_WARN( "Could not reallocate string buffer."); exit(-4); } tmp[cs++] = '&'; @@ -66,7 +66,7 @@ LPSTR tr_esc_str(LPCSTR arg) tmp = (LPSTR)realloc(tmp, ds * sizeof(CHAR)); if(NULL == tmp) { - fprintf(stderr, "Could not reallocate string buffer."); + DEBUG_WARN( "Could not reallocate string buffer."); exit(-5); } tmp[cs++] = '&'; @@ -81,7 +81,7 @@ LPSTR tr_esc_str(LPCSTR arg) tmp = (LPSTR)realloc(tmp, ds * sizeof(CHAR)); if(NULL == tmp) { - fprintf(stderr, "Could not reallocate string buffer."); + DEBUG_WARN( "Could not reallocate string buffer."); exit(-6); } tmp[cs++] = '&'; @@ -96,7 +96,7 @@ LPSTR tr_esc_str(LPCSTR arg) tmp = (LPSTR)realloc(tmp, ds * sizeof(CHAR)); if(NULL == tmp) { - fprintf(stderr, "Could not reallocate string buffer."); + DEBUG_WARN( "Could not reallocate string buffer."); exit(-7); } tmp[cs++] = '&'; @@ -125,7 +125,7 @@ int main(int argc, char *argv[]) fp = fopen(fname, "w"); if(NULL == fp) { - fprintf(stderr, "Could not open '%s' for writing.", fname); + DEBUG_WARN( "Could not open '%s' for writing.", fname); return -1; } /* The tag used as header in the manpage */ @@ -136,7 +136,7 @@ int main(int argc, char *argv[]) * compatible XML */ if(elements < 2) { - fprintf(stderr, "The argument array 'args' is empty, writing an empty file."); + DEBUG_WARN( "The argument array 'args' is empty, writing an empty file."); elements = 1; } for(x=0; xgdi; + rdpGdi* gdi = context->gdi; gdi->primary->hdc->hwnd->invalid->null = 1; gdi->primary->hdc->hwnd->ninvalid = 0; } void xf_sw_end_paint(rdpContext *context) { - rdpGdi *gdi; + int i; INT32 x, y; UINT32 w, h; - xfContext *xfc = (xfContext *) context; - gdi = context->gdi; - if(!xfc->remote_app) + int ninvalid; + HGDI_RGN cinvalid; + xfContext* xfc = (xfContext*) context; + rdpGdi* gdi = context->gdi; + + x = gdi->primary->hdc->hwnd->invalid->x; + y = gdi->primary->hdc->hwnd->invalid->y; + w = gdi->primary->hdc->hwnd->invalid->w; + h = gdi->primary->hdc->hwnd->invalid->h; + + ninvalid = gdi->primary->hdc->hwnd->ninvalid; + cinvalid = gdi->primary->hdc->hwnd->cinvalid; + + if (!xfc->remote_app) { - if(!xfc->complex_regions) + if (!xfc->complex_regions) { - if(gdi->primary->hdc->hwnd->invalid->null) + if (gdi->primary->hdc->hwnd->invalid->null) return; - x = gdi->primary->hdc->hwnd->invalid->x; - y = gdi->primary->hdc->hwnd->invalid->y; - w = gdi->primary->hdc->hwnd->invalid->w; - h = gdi->primary->hdc->hwnd->invalid->h; + xf_lock_x11(xfc, FALSE); + XPutImage(xfc->display, xfc->primary, xfc->gc, xfc->image, x, y, x, y, w, h); - if((xfc->settings->ScalingFactor != 1.0) || (xfc->offset_x) || (xfc->offset_y)) + + if ((xfc->settings->ScalingFactor != 1.0) || (xfc->offset_x) || (xfc->offset_y)) { xf_draw_screen_scaled(xfc, x, y, w, h, TRUE); } @@ -212,27 +222,27 @@ void xf_sw_end_paint(rdpContext *context) { XCopyArea(xfc->display, xfc->primary, xfc->window->handle, xfc->gc, x, y, w, h, x, y); } + xf_unlock_x11(xfc, FALSE); } else { - int i; - int ninvalid; - HGDI_RGN cinvalid; - if(gdi->primary->hdc->hwnd->ninvalid < 1) + if (gdi->primary->hdc->hwnd->ninvalid < 1) return; - ninvalid = gdi->primary->hdc->hwnd->ninvalid; - cinvalid = gdi->primary->hdc->hwnd->cinvalid; + xf_lock_x11(xfc, FALSE); - for(i = 0; i < ninvalid; i++) + + for (i = 0; i < ninvalid; i++) { x = cinvalid[i].x; y = cinvalid[i].y; w = cinvalid[i].w; h = cinvalid[i].h; + //combine xfc->primary with xfc->image XPutImage(xfc->display, xfc->primary, xfc->gc, xfc->image, x, y, x, y, w, h); - if((xfc->settings->ScalingFactor != 1.0) || (xfc->offset_x) || (xfc->offset_y)) + + if ((xfc->settings->ScalingFactor != 1.0) || (xfc->offset_x) || (xfc->offset_y)) { xf_draw_screen_scaled(xfc, x, y, w, h, TRUE); } @@ -241,20 +251,21 @@ void xf_sw_end_paint(rdpContext *context) XCopyArea(xfc->display, xfc->primary, xfc->window->handle, xfc->gc, x, y, w, h, x, y); } } + XFlush(xfc->display); + xf_unlock_x11(xfc, FALSE); } } else { - if(gdi->primary->hdc->hwnd->invalid->null) + if (gdi->primary->hdc->hwnd->invalid->null) return; - x = gdi->primary->hdc->hwnd->invalid->x; - y = gdi->primary->hdc->hwnd->invalid->y; - w = gdi->primary->hdc->hwnd->invalid->w; - h = gdi->primary->hdc->hwnd->invalid->h; + xf_lock_x11(xfc, FALSE); + xf_rail_paint(xfc, context->rail, x, y, x + w - 1, y + h - 1); + xf_unlock_x11(xfc, FALSE); } } @@ -264,12 +275,15 @@ void xf_sw_desktop_resize(rdpContext *context) rdpSettings *settings; xfContext *xfc = (xfContext *) context; settings = xfc->instance->settings; + xf_lock_x11(xfc, TRUE); - if(!xfc->fullscreen) + + if (!xfc->fullscreen) { rdpGdi *gdi = context->gdi; gdi_resize(gdi, xfc->width, xfc->height); - if(xfc->image) + + if (xfc->image) { xfc->image->data = NULL; XDestroyImage(xfc->image); @@ -277,6 +291,7 @@ void xf_sw_desktop_resize(rdpContext *context) (char *) gdi->primary_buffer, gdi->width, gdi->height, xfc->scanline_pad, 0); } } + xf_unlock_x11(xfc, TRUE); } @@ -573,7 +588,7 @@ BOOL xf_get_pixmap_info(xfContext *xfc) pfs = XListPixmapFormats(xfc->display, &pf_count); if(pfs == NULL) { - fprintf(stderr, "xf_get_pixmap_info: XListPixmapFormats failed\n"); + DEBUG_WARN( "xf_get_pixmap_info: XListPixmapFormats failed\n"); return 1; } for(i = 0; i < pf_count; i++) @@ -592,13 +607,13 @@ BOOL xf_get_pixmap_info(xfContext *xfc) template.screen = xfc->screen_number; if(XGetWindowAttributes(xfc->display, RootWindowOfScreen(xfc->screen), &window_attributes) == 0) { - fprintf(stderr, "xf_get_pixmap_info: XGetWindowAttributes failed\n"); + DEBUG_WARN( "xf_get_pixmap_info: XGetWindowAttributes failed\n"); return FALSE; } vis = XGetVisualInfo(xfc->display, VisualClassMask | VisualScreenMask, &template, &vi_count); if(vis == NULL) { - fprintf(stderr, "xf_get_pixmap_info: XGetVisualInfo failed\n"); + DEBUG_WARN( "xf_get_pixmap_info: XGetVisualInfo failed\n"); return FALSE; } vi = NULL; @@ -637,7 +652,7 @@ int xf_error_handler(Display *d, XErrorEvent *ev) char buf[256]; int do_abort = TRUE; XGetErrorText(d, ev->error_code, buf, sizeof(buf)); - fprintf(stderr, "%s", buf); + DEBUG_WARN( "%s", buf); if(do_abort) abort(); _def_error_handler(d, ev); @@ -721,20 +736,20 @@ BOOL xf_pre_connect(freerdp *instance) { if(!XInitThreads()) { - fprintf(stderr, "warning: XInitThreads() failure\n"); + DEBUG_WARN( "warning: XInitThreads() failure\n"); xfc->UseXThreads = FALSE; } } xfc->display = XOpenDisplay(NULL); if(!xfc->display) { - fprintf(stderr, "xf_pre_connect: failed to open display: %s\n", XDisplayName(NULL)); - fprintf(stderr, "Please check that the $DISPLAY environment variable is properly set.\n"); + DEBUG_WARN( "xf_pre_connect: failed to open display: %s\n", XDisplayName(NULL)); + DEBUG_WARN( "Please check that the $DISPLAY environment variable is properly set.\n"); return FALSE; } if(xfc->debug) { - fprintf(stderr, "Enabling X11 debug mode.\n"); + DEBUG_WARN( "Enabling X11 debug mode.\n"); XSynchronize(xfc->display, TRUE); _def_error_handler = XSetErrorHandler(_xf_error_handler); } @@ -750,15 +765,15 @@ BOOL xf_pre_connect(freerdp *instance) /* Check --authonly has a username and password. */ if(settings->Username == NULL) { - fprintf(stderr, "--authonly, but no -u username. Please provide one.\n"); + DEBUG_WARN( "--authonly, but no -u username. Please provide one.\n"); return FALSE; } if(settings->Password == NULL) { - fprintf(stderr, "--authonly, but no -p password. Please provide one.\n"); + DEBUG_WARN( "--authonly, but no -p password. Please provide one.\n"); return FALSE; } - fprintf(stderr, "Authentication only. Don't connect to X.\n"); + DEBUG_WARN( "Authentication only. Don't connect to X.\n"); /* Avoid XWindows initialization and configuration below. */ return TRUE; } @@ -794,6 +809,8 @@ BOOL xf_pre_connect(freerdp *instance) xfc->grab_keyboard = settings->GrabKeyboard; xfc->fullscreen_toggle = settings->ToggleFullscreen; xf_detect_monitors(xfc, settings); + xfc->colormap = DefaultColormap(xfc->display, xfc->screen_number); + return TRUE; } @@ -885,9 +902,9 @@ BOOL xf_post_connect(freerdp *instance) XFillRectangle(xfc->display, xfc->primary, xfc->gc, 0, 0, xfc->width, xfc->height); XFlush(xfc->display); xfc->image = XCreateImage(xfc->display, xfc->visual, xfc->depth, ZPixmap, 0, - (char *) xfc->primary_buffer, xfc->width, xfc->height, xfc->scanline_pad, 0); + (char*) xfc->primary_buffer, xfc->width, xfc->height, xfc->scanline_pad, 0); xfc->bmp_codec_none = (BYTE *) malloc(64 * 64 * 4); - + if (xfc->settings->SoftwareGdi) { instance->update->BeginPaint = xf_sw_begin_paint; @@ -1128,30 +1145,6 @@ void xf_window_free(xfContext *xfc) } } -void* xf_update_thread(void *arg) -{ - int status; - wMessage message; - wMessageQueue *queue; - freerdp *instance = (freerdp *) arg; - assert(NULL != instance); - status = 1; - queue = freerdp_get_message_queue(instance, FREERDP_UPDATE_MESSAGE_QUEUE); - while(MessageQueue_Wait(queue)) - { - while(MessageQueue_Peek(queue, &message, TRUE)) - { - status = freerdp_message_queue_process_message(instance, FREERDP_UPDATE_MESSAGE_QUEUE, &message); - if(!status) - break; - } - if(!status) - break; - } - ExitThread(0); - return NULL; -} - void *xf_input_thread(void *arg) { xfContext *xfc; @@ -1225,7 +1218,7 @@ BOOL xf_auto_reconnect(freerdp *instance) if(freerdp_error_info(instance) != 0) return FALSE; /* A network disconnect was detected */ - fprintf(stderr, "Network disconnect!\n"); + DEBUG_WARN( "Network disconnect!\n"); if(!instance->settings->AutoReconnectionEnabled) { /* No auto-reconnect - just quit */ @@ -1240,7 +1233,7 @@ BOOL xf_auto_reconnect(freerdp *instance) return FALSE; } /* Attempt the next reconnect */ - fprintf(stderr, "Attempting reconnect (%u of %u)\n", num_retries, max_retries); + DEBUG_WARN( "Attempting reconnect (%u of %u)\n", num_retries, max_retries); if(freerdp_reconnect(instance)) { xfc->disconnect = FALSE; @@ -1248,7 +1241,7 @@ BOOL xf_auto_reconnect(freerdp *instance) } sleep(5); } - fprintf(stderr, "Maximum reconnect retries exceeded\n"); + DEBUG_WARN( "Maximum reconnect retries exceeded\n"); return FALSE; } @@ -1277,11 +1270,9 @@ void *xf_thread(void *param) int fd_input_event; HANDLE input_event; int select_status; - BOOL async_update; BOOL async_input; BOOL async_channels; BOOL async_transport; - HANDLE update_thread; HANDLE input_thread; HANDLE channels_thread; rdpChannels *channels; @@ -1301,7 +1292,7 @@ void *xf_thread(void *param) if(instance->settings->AuthenticationOnly) { freerdp_disconnect(instance); - fprintf(stderr, "Authentication only, exit status %d\n", !status); + DEBUG_WARN( "Authentication only, exit status %d\n", !status); ExitThread(exit_code); } if(!status) @@ -1318,14 +1309,10 @@ void *xf_thread(void *param) } channels = instance->context->channels; settings = instance->context->settings; - async_update = settings->AsyncUpdate; async_input = settings->AsyncInput; async_channels = settings->AsyncChannels; async_transport = settings->AsyncTransport; - if(async_update) - { - update_thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) xf_update_thread, instance, 0, NULL); - } + if(async_input) { input_thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) xf_input_thread, instance, 0, NULL); @@ -1352,7 +1339,7 @@ void *xf_thread(void *param) { if(freerdp_get_fds(instance, rfds, &rcount, wfds, &wcount) != TRUE) { - fprintf(stderr, "Failed to get FreeRDP file descriptor\n"); + DEBUG_WARN( "Failed to get FreeRDP file descriptor\n"); exit_code = XF_EXIT_CONN_FAILED; break; } @@ -1361,7 +1348,7 @@ void *xf_thread(void *param) { if(freerdp_channels_get_fds(channels, instance, rfds, &rcount, wfds, &wcount) != TRUE) { - fprintf(stderr, "Failed to get channel manager file descriptor\n"); + DEBUG_WARN( "Failed to get channel manager file descriptor\n"); exit_code = XF_EXIT_CONN_FAILED; break; } @@ -1370,7 +1357,7 @@ void *xf_thread(void *param) { if(xf_get_fds(instance, rfds, &rcount, wfds, &wcount) != TRUE) { - fprintf(stderr, "Failed to get xfreerdp file descriptor\n"); + DEBUG_WARN( "Failed to get xfreerdp file descriptor\n"); exit_code = XF_EXIT_CONN_FAILED; break; } @@ -1407,7 +1394,7 @@ void *xf_thread(void *param) if(!((errno == EAGAIN) || (errno == EWOULDBLOCK) || (errno == EINPROGRESS) || (errno == EINTR))) /* signal occurred */ { - fprintf(stderr, "xfreerdp_run: select failed\n"); + DEBUG_WARN( "xfreerdp_run: select failed\n"); break; } } @@ -1417,7 +1404,7 @@ void *xf_thread(void *param) { if(xf_auto_reconnect(instance)) continue; - fprintf(stderr, "Failed to check FreeRDP file descriptor\n"); + DEBUG_WARN( "Failed to check FreeRDP file descriptor\n"); break; } } @@ -1425,7 +1412,7 @@ void *xf_thread(void *param) { if(freerdp_channels_check_fds(channels, instance) != TRUE) { - fprintf(stderr, "Failed to check channel manager file descriptor\n"); + DEBUG_WARN( "Failed to check channel manager file descriptor\n"); break; } xf_process_channel_event(channels, instance); @@ -1434,7 +1421,7 @@ void *xf_thread(void *param) { if(xf_process_x_events(instance) != TRUE) { - fprintf(stderr, "Closed from X11\n"); + DEBUG_WARN( "Closed from X11\n"); break; } } @@ -1444,7 +1431,7 @@ void *xf_thread(void *param) { if(!freerdp_message_queue_process_pending_messages(instance, FREERDP_INPUT_MESSAGE_QUEUE)) { - fprintf(stderr, "User Disconnect\n"); + DEBUG_WARN( "User Disconnect\n"); xfc->disconnect = TRUE; break; } @@ -1454,13 +1441,7 @@ void *xf_thread(void *param) /* Close the channels first. This will signal the internal message pipes * that the threads should quit. */ freerdp_channels_close(channels, instance); - if(async_update) - { - wMessageQueue *update_queue = freerdp_get_message_queue(instance, FREERDP_UPDATE_MESSAGE_QUEUE); - MessageQueue_PostQuit(update_queue, 0); - WaitForSingleObject(update_thread, INFINITE); - CloseHandle(update_thread); - } + if(async_input) { wMessageQueue *input_queue = freerdp_get_message_queue(instance, FREERDP_INPUT_MESSAGE_QUEUE); @@ -1559,7 +1540,7 @@ static int xfreerdp_client_start(rdpContext *context) rdpSettings *settings = context->settings; if(!settings->ServerHostname) { - fprintf(stderr, "error: server hostname was not specified with /v:[:port]\n"); + DEBUG_WARN( "error: server hostname was not specified with /v:[:port]\n"); return -1; } xfc->thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) xf_thread, diff --git a/client/X11/xf_cliprdr.c b/client/X11/xf_cliprdr.c index eabdac19e..b37fa6f80 100644 --- a/client/X11/xf_cliprdr.c +++ b/client/X11/xf_cliprdr.c @@ -143,15 +143,15 @@ void xf_cliprdr_init(xfContext* xfc, rdpChannels* channels) } else { - fprintf(stderr, "%s: Error querying X Fixes extension version\n", __FUNCTION__); + DEBUG_WARN( "%s: Error querying X Fixes extension version\n", __FUNCTION__); } } else { - fprintf(stderr, "%s: Error loading X Fixes extension\n", __FUNCTION__); + DEBUG_WARN( "%s: Error loading X Fixes extension\n", __FUNCTION__); } #else - fprintf(stderr, "Warning: Using clipboard redirection without XFIXES extension is strongly discouraged!\n"); + DEBUG_WARN( "Warning: Using clipboard redirection without XFIXES extension is strongly discouraged!\n"); #endif n = 0; @@ -970,7 +970,7 @@ static BOOL xf_cliprdr_process_dib(clipboardContext* cb, BYTE* data, int size) Stream_Read_UINT16(s, bpp); if ((bpp < 1) || (bpp > 32)) { - fprintf(stderr, "%s: invalid bpp value %d", __FUNCTION__, bpp); + DEBUG_WARN( "%s: invalid bpp value %d", __FUNCTION__, bpp); return FALSE; } diff --git a/client/X11/xf_gdi.c b/client/X11/xf_gdi.c index 1ab20af06..c18846370 100644 --- a/client/X11/xf_gdi.c +++ b/client/X11/xf_gdi.c @@ -68,7 +68,7 @@ BOOL xf_set_rop2(xfContext* xfc, int rop2) { if ((rop2 < 0x01) || (rop2 > 0x10)) { - fprintf(stderr, "Unsupported ROP2: %d\n", rop2); + DEBUG_WARN( "Unsupported ROP2: %d\n", rop2); return FALSE; } @@ -204,7 +204,7 @@ BOOL xf_set_rop3(xfContext* xfc, int rop3) if (function < 0) { - fprintf(stderr, "Unsupported ROP3: 0x%08X\n", rop3); + DEBUG_WARN( "Unsupported ROP3: 0x%08X\n", rop3); XSetFunction(xfc->display, xfc->gc, GXclear); return FALSE; } @@ -214,6 +214,28 @@ BOOL xf_set_rop3(xfContext* xfc, int rop3) return TRUE; } +unsigned long xf_gdi_get_color(xfContext* xfc, GDI_COLOR color) +{ + XColor x11_color; + + x11_color.flags = DoRed | DoGreen | DoBlue; + GetRGB32(x11_color.red, x11_color.green, x11_color.blue, color); + x11_color.red = x11_color.red << 8; + x11_color.green = x11_color.green << 8; + x11_color.blue = x11_color.blue << 8; + + if (XAllocColor(xfc->display, xfc->colormap, &x11_color) != 0) + { + XFreeColors(xfc->display, xfc->colormap, &x11_color.pixel, 1, 0); + } + else + { + x11_color.pixel = BlackPixel(xfc->display, xfc->screen_number); + } + + return x11_color.pixel; +} + Pixmap xf_brush_new(xfContext* xfc, int width, int height, int bpp, BYTE* data) { Pixmap bitmap; @@ -337,8 +359,10 @@ void xf_gdi_patblt(rdpContext* context, PATBLT_ORDER* patblt) brush = &patblt->brush; xf_set_rop3(xfc, gdi_rop3_code(patblt->bRop)); - foreColor = freerdp_color_convert_var(patblt->foreColor, context->settings->ColorDepth, xfc->bpp, xfc->clrconv); - backColor = freerdp_color_convert_var(patblt->backColor, context->settings->ColorDepth, xfc->bpp, xfc->clrconv); + foreColor = freerdp_color_convert_drawing_order_color_to_gdi_color(patblt->foreColor, context->settings->ColorDepth, xfc->clrconv); + foreColor = xf_gdi_get_color(xfc, foreColor); + backColor = freerdp_color_convert_drawing_order_color_to_gdi_color(patblt->backColor, context->settings->ColorDepth, xfc->clrconv); + backColor = xf_gdi_get_color(xfc, backColor); if (brush->style == GDI_BS_SOLID) { @@ -398,7 +422,7 @@ void xf_gdi_patblt(rdpContext* context, PATBLT_ORDER* patblt) } else { - fprintf(stderr, "unimplemented brush style:%d\n", brush->style); + DEBUG_WARN( "unimplemented brush style:%d\n", brush->style); } if (xfc->drawing == xfc->primary) @@ -457,7 +481,8 @@ void xf_gdi_opaque_rect(rdpContext* context, OPAQUE_RECT_ORDER* opaque_rect) xf_lock_x11(xfc, FALSE); - color = freerdp_color_convert_var(opaque_rect->color, context->settings->ColorDepth, xfc->bpp, xfc->clrconv); + color = freerdp_color_convert_drawing_order_color_to_gdi_color(opaque_rect->color, context->settings->ColorDepth, xfc->clrconv); + color = xf_gdi_get_color(xfc, color); XSetFunction(xfc->display, xfc->gc, GXcopy); XSetFillStyle(xfc->display, xfc->gc, FillSolid); @@ -491,7 +516,8 @@ void xf_gdi_multi_opaque_rect(rdpContext* context, MULTI_OPAQUE_RECT_ORDER* mult xf_lock_x11(xfc, FALSE); - color = freerdp_color_convert_var(multi_opaque_rect->color, context->settings->ColorDepth, xfc->bpp, xfc->clrconv); + color = freerdp_color_convert_drawing_order_color_to_gdi_color(multi_opaque_rect->color, context->settings->ColorDepth, xfc->clrconv); + color = xf_gdi_get_color(xfc, color); XSetFunction(xfc->display, xfc->gc, GXcopy); XSetFillStyle(xfc->display, xfc->gc, FillSolid); @@ -522,7 +548,7 @@ void xf_gdi_multi_opaque_rect(rdpContext* context, MULTI_OPAQUE_RECT_ORDER* mult void xf_gdi_draw_nine_grid(rdpContext* context, DRAW_NINE_GRID_ORDER* draw_nine_grid) { - fprintf(stderr, "DrawNineGrid\n"); + DEBUG_WARN( "DrawNineGrid\n"); } void xf_gdi_line_to(rdpContext* context, LINE_TO_ORDER* line_to) @@ -533,7 +559,8 @@ void xf_gdi_line_to(rdpContext* context, LINE_TO_ORDER* line_to) xf_lock_x11(xfc, FALSE); xf_set_rop2(xfc, line_to->bRop2); - color = freerdp_color_convert_var(line_to->penColor, context->settings->ColorDepth, xfc->bpp, xfc->clrconv); + color = freerdp_color_convert_drawing_order_color_to_gdi_color(line_to->penColor, context->settings->ColorDepth, xfc->clrconv); + color = xf_gdi_get_color(xfc, color); XSetFillStyle(xfc->display, xfc->gc, FillSolid); XSetForeground(xfc->display, xfc->gc, color); @@ -583,7 +610,8 @@ void xf_gdi_polyline(rdpContext* context, POLYLINE_ORDER* polyline) xf_lock_x11(xfc, FALSE); xf_set_rop2(xfc, polyline->bRop2); - color = freerdp_color_convert_var(polyline->penColor, context->settings->ColorDepth, xfc->bpp, xfc->clrconv); + color = freerdp_color_convert_drawing_order_color_to_gdi_color(polyline->penColor, context->settings->ColorDepth, xfc->clrconv); + color = xf_gdi_get_color(xfc, color); XSetFillStyle(xfc->display, xfc->gc, FillSolid); XSetForeground(xfc->display, xfc->gc, color); @@ -679,8 +707,10 @@ void xf_gdi_mem3blt(rdpContext* context, MEM3BLT_ORDER* mem3blt) brush = &mem3blt->brush; bitmap = (xfBitmap*) mem3blt->bitmap; xf_set_rop3(xfc, gdi_rop3_code(mem3blt->bRop)); - foreColor = freerdp_color_convert_var(mem3blt->foreColor, context->settings->ColorDepth, xfc->bpp, xfc->clrconv); - backColor = freerdp_color_convert_var(mem3blt->backColor, context->settings->ColorDepth, xfc->bpp, xfc->clrconv); + foreColor = freerdp_color_convert_drawing_order_color_to_gdi_color(mem3blt->foreColor, context->settings->ColorDepth, xfc->clrconv); + foreColor = xf_gdi_get_color(xfc, foreColor); + backColor = freerdp_color_convert_drawing_order_color_to_gdi_color(mem3blt->backColor, context->settings->ColorDepth, xfc->clrconv); + backColor = xf_gdi_get_color(xfc, backColor); if (brush->style == GDI_BS_PATTERN) { @@ -713,7 +743,7 @@ void xf_gdi_mem3blt(rdpContext* context, MEM3BLT_ORDER* mem3blt) } else { - fprintf(stderr, "Mem3Blt unimplemented brush style:%d\n", brush->style); + DEBUG_WARN( "Mem3Blt unimplemented brush style:%d\n", brush->style); } XCopyArea(xfc->display, bitmap->pixmap, xfc->drawing, xfc->gc, @@ -752,7 +782,8 @@ void xf_gdi_polygon_sc(rdpContext* context, POLYGON_SC_ORDER* polygon_sc) xf_lock_x11(xfc, FALSE); xf_set_rop2(xfc, polygon_sc->bRop2); - brush_color = freerdp_color_convert_var(polygon_sc->brushColor, context->settings->ColorDepth, xfc->bpp, xfc->clrconv); + brush_color = freerdp_color_convert_drawing_order_color_to_gdi_color(polygon_sc->brushColor, context->settings->ColorDepth, xfc->clrconv); + brush_color = xf_gdi_get_color(xfc, brush_color); npoints = polygon_sc->numPoints + 1; points = malloc(sizeof(XPoint) * npoints); @@ -777,7 +808,7 @@ void xf_gdi_polygon_sc(rdpContext* context, POLYGON_SC_ORDER* polygon_sc) break; default: - fprintf(stderr, "PolygonSC unknown fillMode: %d\n", polygon_sc->fillMode); + DEBUG_WARN( "PolygonSC unknown fillMode: %d\n", polygon_sc->fillMode); break; } @@ -813,8 +844,10 @@ void xf_gdi_polygon_cb(rdpContext* context, POLYGON_CB_ORDER* polygon_cb) brush = &(polygon_cb->brush); xf_set_rop2(xfc, polygon_cb->bRop2); - foreColor = freerdp_color_convert_var(polygon_cb->foreColor, context->settings->ColorDepth, xfc->bpp, xfc->clrconv); - backColor = freerdp_color_convert_var(polygon_cb->backColor, context->settings->ColorDepth, xfc->bpp, xfc->clrconv); + foreColor = freerdp_color_convert_drawing_order_color_to_gdi_color(polygon_cb->foreColor, context->settings->ColorDepth, xfc->clrconv); + foreColor = xf_gdi_get_color(xfc, foreColor); + backColor = freerdp_color_convert_drawing_order_color_to_gdi_color(polygon_cb->backColor, context->settings->ColorDepth, xfc->clrconv); + backColor = xf_gdi_get_color(xfc, backColor); npoints = polygon_cb->numPoints + 1; points = malloc(sizeof(XPoint) * npoints); @@ -839,7 +872,7 @@ void xf_gdi_polygon_cb(rdpContext* context, POLYGON_CB_ORDER* polygon_cb) break; default: - fprintf(stderr, "PolygonCB unknown fillMode: %d\n", polygon_cb->fillMode); + DEBUG_WARN( "PolygonCB unknown fillMode: %d\n", polygon_cb->fillMode); break; } @@ -897,7 +930,7 @@ void xf_gdi_polygon_cb(rdpContext* context, POLYGON_CB_ORDER* polygon_cb) } else { - fprintf(stderr, "PolygonCB unimplemented brush style:%d\n", brush->style); + DEBUG_WARN( "PolygonCB unimplemented brush style:%d\n", brush->style); } XSetFunction(xfc->display, xfc->gc, GXcopy); @@ -908,12 +941,17 @@ void xf_gdi_polygon_cb(rdpContext* context, POLYGON_CB_ORDER* polygon_cb) void xf_gdi_ellipse_sc(rdpContext* context, ELLIPSE_SC_ORDER* ellipse_sc) { - fprintf(stderr, "EllipseSC\n"); + DEBUG_WARN( "EllipseSC\n"); } void xf_gdi_ellipse_cb(rdpContext* context, ELLIPSE_CB_ORDER* ellipse_cb) { - fprintf(stderr, "EllipseCB\n"); + DEBUG_WARN( "EllipseCB\n"); +} + +void xf_gdi_frame_marker(rdpContext* context, FRAME_MARKER_ORDER* frameMarker) +{ + } void xf_gdi_surface_frame_marker(rdpContext* context, SURFACE_FRAME_MARKER* surface_frame_marker) @@ -1111,12 +1149,12 @@ void xf_gdi_surface_bits(rdpContext* context, SURFACE_BITS_COMMAND* surface_bits } else { - fprintf(stderr, "Invalid bitmap size - data is %d bytes for %dx%d\n update", surface_bits_command->bitmapDataLength, surface_bits_command->width, surface_bits_command->height); + DEBUG_WARN( "Invalid bitmap size - data is %d bytes for %dx%d\n update", surface_bits_command->bitmapDataLength, surface_bits_command->width, surface_bits_command->height); } } else { - fprintf(stderr, "Unsupported codecID %d\n", surface_bits_command->codecID); + DEBUG_WARN( "Unsupported codecID %d\n", surface_bits_command->codecID); } xf_unlock_x11(xfc, FALSE); @@ -1154,5 +1192,7 @@ void xf_gdi_register_update_callbacks(rdpUpdate* update) update->SurfaceBits = xf_gdi_surface_bits; update->SurfaceFrameMarker = xf_gdi_surface_frame_marker; + + update->altsec->FrameMarker = xf_gdi_frame_marker; } diff --git a/client/X11/xf_gfx.c b/client/X11/xf_gfx.c index 0cac1e316..c54ff6201 100644 --- a/client/X11/xf_gfx.c +++ b/client/X11/xf_gfx.c @@ -425,20 +425,34 @@ int xf_SurfaceCommand_Alpha(xfContext* xfc, RdpgfxClientContext* context, RDPGFX int xf_SurfaceCommand_Progressive(xfContext* xfc, RdpgfxClientContext* context, RDPGFX_SURFACE_COMMAND* cmd) { - int status = 0; - BYTE* DstData = NULL; + int i, j; + int status; + BYTE* DstData; + RFX_RECT* rect; + int nXDst, nYDst; + int nXSrc, nYSrc; + int nWidth, nHeight; + int nbUpdateRects; xfGfxSurface* surface; - RECTANGLE_16 invalidRect; + REGION16 updateRegion; + RECTANGLE_16 updateRect; + RECTANGLE_16* updateRects; + REGION16 clippingRects; + RECTANGLE_16 clippingRect; + RFX_PROGRESSIVE_TILE* tile; + PROGRESSIVE_BLOCK_REGION* region; surface = (xfGfxSurface*) context->GetSurfaceData(context, cmd->surfaceId); if (!surface) return -1; + progressive_create_surface_context(xfc->progressive, cmd->surfaceId, surface->width, surface->height); + DstData = surface->data; status = progressive_decompress(xfc->progressive, cmd->data, cmd->length, &DstData, - PIXEL_FORMAT_XRGB32, surface->scanline, cmd->left, cmd->top, cmd->width, cmd->height); + PIXEL_FORMAT_XRGB32, surface->scanline, cmd->left, cmd->top, cmd->width, cmd->height, cmd->surfaceId); if (status < 0) { @@ -446,19 +460,54 @@ int xf_SurfaceCommand_Progressive(xfContext* xfc, RdpgfxClientContext* context, return -1; } - printf("xf_SurfaceCommand_Progressive: status: %d\n", status); + region = &(xfc->progressive->region); - /* fill with blue for now to distinguish from the rest */ + region16_init(&clippingRects); - freerdp_image_fill(surface->data, PIXEL_FORMAT_XRGB32, surface->scanline, - cmd->left, cmd->top, cmd->width, cmd->height, 0x0000FF); + for (i = 0; i < region->numRects; i++) + { + rect = &(region->rects[i]); - invalidRect.left = cmd->left; - invalidRect.top = cmd->top; - invalidRect.right = cmd->right; - invalidRect.bottom = cmd->bottom; + clippingRect.left = cmd->left + rect->x; + clippingRect.top = cmd->top + rect->y; + clippingRect.right = clippingRect.left + rect->width; + clippingRect.bottom = clippingRect.top + rect->height; - region16_union_rect(&(xfc->invalidRegion), &(xfc->invalidRegion), &invalidRect); + region16_union_rect(&clippingRects, &clippingRects, &clippingRect); + } + + for (i = 0; i < region->numTiles; i++) + { + tile = region->tiles[i]; + + updateRect.left = cmd->left + tile->x; + updateRect.top = cmd->top + tile->y; + updateRect.right = updateRect.left + 64; + updateRect.bottom = updateRect.top + 64; + + region16_init(&updateRegion); + region16_intersect_rect(&updateRegion, &clippingRects, &updateRect); + updateRects = (RECTANGLE_16*) region16_rects(&updateRegion, &nbUpdateRects); + + for (j = 0; j < nbUpdateRects; j++) + { + nXDst = updateRects[j].left; + nYDst = updateRects[j].top; + nWidth = updateRects[j].right - updateRects[j].left; + nHeight = updateRects[j].bottom - updateRects[j].top; + + nXSrc = nXDst - (cmd->left + tile->x); + nYSrc = nYDst - (cmd->top + tile->y); + + freerdp_image_copy(surface->data, PIXEL_FORMAT_XRGB32, + surface->scanline, nXDst, nYDst, nWidth, nHeight, + tile->data, PIXEL_FORMAT_XRGB32, 64 * 4, nXSrc, nYSrc); + + region16_union_rect(&(xfc->invalidRegion), &(xfc->invalidRegion), &updateRects[j]); + } + + region16_uninit(&updateRegion); + } if (!xfc->inGfxFrame) xf_OutputUpdate(xfc); @@ -545,6 +594,7 @@ int xf_CreateSurface(RdpgfxClientContext* context, RDPGFX_CREATE_SURFACE_PDU* cr int xf_DeleteSurface(RdpgfxClientContext* context, RDPGFX_DELETE_SURFACE_PDU* deleteSurface) { xfGfxSurface* surface = NULL; + xfContext* xfc = (xfContext*) context->custom; surface = (xfGfxSurface*) context->GetSurfaceData(context, deleteSurface->surfaceId); @@ -557,6 +607,8 @@ int xf_DeleteSurface(RdpgfxClientContext* context, RDPGFX_DELETE_SURFACE_PDU* de context->SetSurfaceData(context, deleteSurface->surfaceId, NULL); + progressive_delete_surface_context(xfc->progressive, deleteSurface->surfaceId); + return 1; } diff --git a/client/X11/xf_graphics.c b/client/X11/xf_graphics.c index 83e815cbf..330977684 100644 --- a/client/X11/xf_graphics.c +++ b/client/X11/xf_graphics.c @@ -141,7 +141,7 @@ void xf_Bitmap_Decompress(rdpContext* context, rdpBitmap* bitmap, switch (codec_id) { case RDP_CODEC_ID_NSCODEC: - fprintf(stderr, "xf_Bitmap_Decompress: nsc not done\n"); + DEBUG_WARN( "xf_Bitmap_Decompress: nsc not done\n"); break; case RDP_CODEC_ID_REMOTEFX: @@ -150,7 +150,7 @@ void xf_Bitmap_Decompress(rdpContext* context, rdpBitmap* bitmap, if (!msg) { - fprintf(stderr, "xf_Bitmap_Decompress: rfx Decompression Failed\n"); + DEBUG_WARN( "xf_Bitmap_Decompress: rfx Decompression Failed\n"); } else { @@ -173,7 +173,7 @@ void xf_Bitmap_Decompress(rdpContext* context, rdpBitmap* bitmap, case RDP_CODEC_ID_JPEG: if (!jpeg_decompress(data, bitmap->data, width, height, length, bpp)) { - fprintf(stderr, "xf_Bitmap_Decompress: jpeg Decompression Failed\n"); + DEBUG_WARN( "xf_Bitmap_Decompress: jpeg Decompression Failed\n"); } break; @@ -184,7 +184,7 @@ void xf_Bitmap_Decompress(rdpContext* context, rdpBitmap* bitmap, if (!status) { - fprintf(stderr, "xf_Bitmap_Decompress: Bitmap Decompression Failed\n"); + DEBUG_WARN( "xf_Bitmap_Decompress: Bitmap Decompression Failed\n"); } } else @@ -389,19 +389,17 @@ void xf_Glyph_Draw(rdpContext* context, rdpGlyph* glyph, int x, int y) void xf_Glyph_BeginDraw(rdpContext* context, int x, int y, int width, int height, UINT32 bgcolor, UINT32 fgcolor) { - xfContext* context_ = (xfContext*) context; xfContext* xfc = (xfContext*) context; - bgcolor = (xfc->clrconv->invert)? - freerdp_color_convert_var_bgr(bgcolor, context_->settings->ColorDepth, xfc->bpp, xfc->clrconv): - freerdp_color_convert_var_rgb(bgcolor, context_->settings->ColorDepth, xfc->bpp, xfc->clrconv); + bgcolor = freerdp_color_convert_drawing_order_color_to_gdi_color(bgcolor, context->settings->ColorDepth, xfc->clrconv); - fgcolor = (xfc->clrconv->invert)? - freerdp_color_convert_var_bgr(fgcolor, context_->settings->ColorDepth, xfc->bpp, xfc->clrconv): - freerdp_color_convert_var_rgb(fgcolor, context_->settings->ColorDepth, xfc->bpp, xfc->clrconv); + fgcolor = freerdp_color_convert_drawing_order_color_to_gdi_color(fgcolor, context->settings->ColorDepth, xfc->clrconv); xf_lock_x11(xfc, FALSE); + fgcolor = xf_gdi_get_color(xfc, fgcolor); + bgcolor = xf_gdi_get_color(xfc, bgcolor); + XSetFunction(xfc->display, xfc->gc, GXcopy); XSetFillStyle(xfc->display, xfc->gc, FillSolid); XSetForeground(xfc->display, xfc->gc, fgcolor); diff --git a/client/X11/xf_input.c b/client/X11/xf_input.c index 9549bdb3a..067c0e780 100644 --- a/client/X11/xf_input.c +++ b/client/X11/xf_input.c @@ -624,7 +624,7 @@ int xf_input_touch_remote(xfContext* xfc, XIDeviceEvent* event, int evtype) } else if (evtype == XI_TouchUpdate) { - printf("TouchUpdate: %d\n", touchId); + DEBUG_MSG("TouchUpdate: %d\n", touchId); contactId = rdpei->TouchUpdate(rdpei, touchId, x, y); } else if (evtype == XI_TouchEnd) diff --git a/client/X11/xf_keyboard.c b/client/X11/xf_keyboard.c index 175e83643..699cf7682 100644 --- a/client/X11/xf_keyboard.c +++ b/client/X11/xf_keyboard.c @@ -191,18 +191,18 @@ void xf_keyboard_send_key(xfContext* xfc, BOOL down, BYTE keycode) if (rdp_scancode == RDP_SCANCODE_UNKNOWN) { - fprintf(stderr, "Unknown key with X keycode 0x%02x\n", keycode); + DEBUG_WARN( "Unknown key with X keycode 0x%02x\n", keycode); } else if (rdp_scancode == RDP_SCANCODE_PAUSE && !xf_keyboard_key_pressed(xfc, XK_Control_L) && !xf_keyboard_key_pressed(xfc, XK_Control_R)) { - /* Pause without Ctrl has to be sent as Ctrl + NumLock. */ + /* Pause without Ctrl has to be sent as a series of keycodes + * in a single input PDU. Pause only happens on "press"; + * no code is sent on "release". + */ if (down) { - freerdp_input_send_keyboard_event_ex(input, TRUE, RDP_SCANCODE_LCONTROL); - freerdp_input_send_keyboard_event_ex(input, TRUE, RDP_SCANCODE_NUMLOCK); - freerdp_input_send_keyboard_event_ex(input, FALSE, RDP_SCANCODE_LCONTROL); - freerdp_input_send_keyboard_event_ex(input, FALSE, RDP_SCANCODE_NUMLOCK); + freerdp_input_send_keyboard_pause_event(input); } } else @@ -405,14 +405,17 @@ BOOL xf_keyboard_handle_special_keys(xfContext* xfc, KeySym keysym) return TRUE; } - if (keysym == XK_Return) + if(xfc->fullscreen_toggle) { - if (mod.Ctrl && mod.Alt) - { - /* Ctrl-Alt-Enter: toggle full screen */ - xf_toggle_fullscreen(xfc); - return TRUE; - } + if (keysym == XK_Return) + { + if (mod.Ctrl && mod.Alt) + { + /* Ctrl-Alt-Enter: toggle full screen */ + xf_toggle_fullscreen(xfc); + return TRUE; + } + } } if ((keysym == XK_c) || (keysym == XK_C)) diff --git a/client/X11/xf_rail.c b/client/X11/xf_rail.c index 8b9318768..039f74ef6 100644 --- a/client/X11/xf_rail.c +++ b/client/X11/xf_rail.c @@ -497,7 +497,7 @@ void xf_process_rail_exec_result_event(xfContext* xfc, rdpChannels* channels, wM if (exec_result->execResult != RAIL_EXEC_S_OK) { - fprintf(stderr, "RAIL exec error: execResult=%s NtError=0x%X\n", + DEBUG_WARN( "RAIL exec error: execResult=%s NtError=0x%X\n", error_code_names[exec_result->execResult], exec_result->rawResult); xfc->disconnect = True; } @@ -660,7 +660,7 @@ void xf_process_rail_appid_resp_event(xfContext* xfc, rdpChannels* channels, wMe RAIL_GET_APPID_RESP_ORDER* appid_resp = (RAIL_GET_APPID_RESP_ORDER*) event->wParam; - fprintf(stderr, "Server Application ID Response PDU: windowId=0x%X " + DEBUG_WARN( "Server Application ID Response PDU: windowId=0x%X " "applicationId=(length=%d dump)\n", appid_resp->windowId, 512); @@ -672,7 +672,7 @@ void xf_process_rail_langbarinfo_event(xfContext* xfc, rdpChannels* channels, wM RAIL_LANGBAR_INFO_ORDER* langbar = (RAIL_LANGBAR_INFO_ORDER*) event->wParam; - fprintf(stderr, "Language Bar Information PDU: languageBarStatus=0x%X\n", + DEBUG_WARN( "Language Bar Information PDU: languageBarStatus=0x%X\n", langbar->languageBarStatus); } diff --git a/client/X11/xf_tsmf.c b/client/X11/xf_tsmf.c index 131d2ea2b..72acb48cb 100644 --- a/client/X11/xf_tsmf.c +++ b/client/X11/xf_tsmf.c @@ -140,7 +140,7 @@ void xf_tsmf_init(xfContext* xfc, long xv_port) XFree(attr); #ifdef WITH_DEBUG_XV - fprintf(stderr, "xf_tsmf_init: pixel format "); + DEBUG_WARN( "xf_tsmf_init: pixel format "); #endif fo = XvListImageFormats(xfc->display, xv->xv_port, &ret); if (ret > 0) @@ -152,7 +152,7 @@ void xf_tsmf_init(xfContext* xfc, long xv_port) { xv->xv_pixfmts[i] = fo[i].id; #ifdef WITH_DEBUG_XV - fprintf(stderr, "%c%c%c%c ", ((char*)(xv->xv_pixfmts + i))[0], ((char*)(xv->xv_pixfmts + i))[1], + DEBUG_WARN( "%c%c%c%c ", ((char*)(xv->xv_pixfmts + i))[0], ((char*)(xv->xv_pixfmts + i))[1], ((char*)(xv->xv_pixfmts + i))[2], ((char*)(xv->xv_pixfmts + i))[3]); #endif } @@ -160,7 +160,7 @@ void xf_tsmf_init(xfContext* xfc, long xv_port) } XFree(fo); #ifdef WITH_DEBUG_XV - fprintf(stderr, "\n"); + DEBUG_WARN( "\n"); #endif } diff --git a/client/X11/xf_window.c b/client/X11/xf_window.c index 7df1f8768..51779905a 100644 --- a/client/X11/xf_window.c +++ b/client/X11/xf_window.c @@ -114,6 +114,8 @@ void xf_SendClientEvent(xfContext *xfc, xfWindow *window, Atom atom, unsigned in unsigned int i; va_list argp; va_start(argp, numArgs); + + ZeroMemory(&xevent, sizeof(XEvent)); xevent.xclient.type = ClientMessage; xevent.xclient.serial = 0; xevent.xclient.send_event = False; diff --git a/client/X11/xfreerdp.h b/client/X11/xfreerdp.h index 6a4718d35..a2d89b0df 100644 --- a/client/X11/xfreerdp.h +++ b/client/X11/xfreerdp.h @@ -245,6 +245,8 @@ void xf_unlock_x11(xfContext* xfc, BOOL display); void xf_draw_screen_scaled(xfContext* xfc, int x, int y, int w, int h, BOOL scale); void xf_transform_window(xfContext* xfc); +unsigned long xf_gdi_get_color(xfContext* xfc, GDI_COLOR color); + FREERDP_API DWORD xf_exit_code_from_disconnect_reason(DWORD reason); #endif /* __XFREERDP_H */ diff --git a/client/common/cmdline.c b/client/common/cmdline.c index b05864db8..345e11cde 100644 --- a/client/common/cmdline.c +++ b/client/common/cmdline.c @@ -32,6 +32,7 @@ #include #include +#include #include #include @@ -43,7 +44,7 @@ COMMAND_LINE_ARGUMENT_A args[] = { "port", COMMAND_LINE_VALUE_REQUIRED, "", NULL, NULL, -1, NULL, "Server port" }, { "w", COMMAND_LINE_VALUE_REQUIRED, "", "1024", NULL, -1, NULL, "Width" }, { "h", COMMAND_LINE_VALUE_REQUIRED, "", "768", NULL, -1, NULL, "Height" }, - { "size", COMMAND_LINE_VALUE_REQUIRED, "x", "1024x768", NULL, -1, NULL, "Screen size" }, + { "size", COMMAND_LINE_VALUE_REQUIRED, "x or %", "1024x768", NULL, -1, NULL, "Screen size" }, { "f", COMMAND_LINE_VALUE_FLAG, NULL, NULL, NULL, -1, NULL, "Fullscreen mode" }, { "bpp", COMMAND_LINE_VALUE_REQUIRED, "", "16", NULL, -1, NULL, "Session bpp (color depth)" }, { "kbd", COMMAND_LINE_VALUE_REQUIRED, "0x or ", NULL, NULL, -1, NULL, "Keyboard layout" }, @@ -815,21 +816,12 @@ int freerdp_parse_username(char* username, char** user, char** domain) } else { - p = strchr(username, '@'); - - if (p) - { - length = (int) (p - username); - *user = (char*) malloc(length + 1); - strncpy(*user, username, length); - (*user)[length] = '\0'; - *domain = _strdup(&p[1]); - } - else - { - *user = _strdup(username); - *domain = NULL; - } + /* Do not break up the name for '@'; both credSSP and the + * ClientInfo PDU expect 'user@corp.net' to be transmitted + * as username 'user@corp.net', domain empty. + */ + *user = _strdup(username); + *domain = NULL; } return 0; @@ -1190,7 +1182,7 @@ int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings, if (compatibility) { - fprintf(stderr, "WARNING: Using deprecated command-line interface!\n"); + DEBUG_WARN( "WARNING: Using deprecated command-line interface!\n"); return freerdp_client_parse_old_command_line_arguments(argc, argv, settings); } else @@ -1271,6 +1263,14 @@ int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings, settings->DesktopWidth = atoi(str); settings->DesktopHeight = atoi(&p[1]); } + else + { + p = strchr(str, '%'); + if(p) + { + settings->PercentScreen = atoi(str); + } + } free(str); } @@ -1360,25 +1360,25 @@ int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings, } CommandLineSwitchCase(arg, "kbd") { - int id; + unsigned long int id; char* pEnd; - id = strtol(arg->Value, &pEnd, 16); + id = strtoul(arg->Value, &pEnd, 16); if (pEnd != (arg->Value + strlen(arg->Value))) id = 0; if (id == 0) { - id = freerdp_map_keyboard_layout_name_to_id(arg->Value); + id = (unsigned long int) freerdp_map_keyboard_layout_name_to_id(arg->Value); if (!id) { - fprintf(stderr, "Could not identify keyboard layout: %s\n", arg->Value); + DEBUG_WARN( "Could not identify keyboard layout: %s\n", arg->Value); } } - settings->KeyboardLayout = id; + settings->KeyboardLayout = (UINT32) id; } CommandLineSwitchCase(arg, "kbd-type") { @@ -1733,7 +1733,7 @@ int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings, } else { - fprintf(stderr, "unknown protocol security: %s\n", arg->Value); + DEBUG_WARN( "unknown protocol security: %s\n", arg->Value); } } CommandLineSwitchCase(arg, "sec-rdp") @@ -1879,7 +1879,7 @@ int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings, } else { - fprintf(stderr, "reconnect-cookie: invalid base64 '%s'\n", + DEBUG_WARN( "reconnect-cookie: invalid base64 '%s'\n", arg->Value); } } @@ -1944,7 +1944,7 @@ int freerdp_client_load_static_channel_addin(rdpChannels* channels, rdpSettings* { if (freerdp_channels_client_load(channels, settings, entry, data) == 0) { - fprintf(stderr, "loading channel %s\n", name); + DEBUG_WARN( "loading channel %s\n", name); return 0; } } @@ -2092,6 +2092,9 @@ int freerdp_client_load_addins(rdpChannels* channels, rdpSettings* settings) } if (settings->DynamicChannelCount) + settings->SupportDynamicChannels = TRUE; + + if (settings->SupportDynamicChannels) { freerdp_client_load_static_channel_addin(channels, settings, "drdynvc", settings); } diff --git a/client/common/compatibility.c b/client/common/compatibility.c index aeda88a2e..1c68c3d7f 100644 --- a/client/common/compatibility.c +++ b/client/common/compatibility.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include @@ -121,7 +122,7 @@ int freerdp_client_old_process_plugin(rdpSettings* settings, ADDIN_ARGV* args) if (strcmp(args->argv[0], "cliprdr") == 0) { settings->RedirectClipboard = TRUE; - fprintf(stderr, "--plugin cliprdr -> +clipboard\n"); + DEBUG_WARN( "--plugin cliprdr -> +clipboard\n"); } else if (strcmp(args->argv[0], "rdpdr") == 0) { @@ -437,37 +438,37 @@ int freerdp_client_parse_old_command_line_arguments(int argc, char** argv, rdpSe CommandLineSwitchCase(arg, "0") { settings->ConsoleSession = TRUE; - fprintf(stderr, "-0 -> /admin\n"); + DEBUG_WARN( "-0 -> /admin\n"); } CommandLineSwitchCase(arg, "a") { settings->ColorDepth = atoi(arg->Value); - fprintf(stderr, "-a %s -> /bpp:%s\n", arg->Value, arg->Value); + DEBUG_WARN( "-a %s -> /bpp:%s\n", arg->Value, arg->Value); } CommandLineSwitchCase(arg, "c") { settings->ShellWorkingDirectory = _strdup(arg->Value); - fprintf(stderr, "-c %s -> /shell-dir:%s\n", arg->Value, arg->Value); + DEBUG_WARN( "-c %s -> /shell-dir:%s\n", arg->Value, arg->Value); } CommandLineSwitchCase(arg, "D") { settings->Decorations = FALSE; - fprintf(stderr, "-D -> -decorations\n"); + DEBUG_WARN( "-D -> -decorations\n"); } CommandLineSwitchCase(arg, "T") { settings->WindowTitle = _strdup(arg->Value); - fprintf(stderr, "-T %s -> /title:%s\n", arg->Value, arg->Value); + DEBUG_WARN( "-T %s -> /title:%s\n", arg->Value, arg->Value); } CommandLineSwitchCase(arg, "d") { settings->Domain = _strdup(arg->Value); - fprintf(stderr, "-d %s -> /d:%s\n", arg->Value, arg->Value); + DEBUG_WARN( "-d %s -> /d:%s\n", arg->Value, arg->Value); } CommandLineSwitchCase(arg, "f") { settings->Fullscreen = TRUE; - fprintf(stderr, "-f -> /f\n"); + DEBUG_WARN( "-f -> /f\n"); } CommandLineSwitchCase(arg, "g") { @@ -484,50 +485,50 @@ int freerdp_client_parse_old_command_line_arguments(int argc, char** argv, rdpSe free(str); - fprintf(stderr, "-g %s -> /size:%s or /w:%d /h:%d\n", arg->Value, arg->Value, + DEBUG_WARN( "-g %s -> /size:%s or /w:%d /h:%d\n", arg->Value, arg->Value, settings->DesktopWidth, settings->DesktopHeight); } CommandLineSwitchCase(arg, "k") { sscanf(arg->Value, "%X", &(settings->KeyboardLayout)); - fprintf(stderr, "-k %s -> /kbd:%s\n", arg->Value, arg->Value); + DEBUG_WARN( "-k %s -> /kbd:%s\n", arg->Value, arg->Value); } CommandLineSwitchCase(arg, "K") { settings->GrabKeyboard = FALSE; - fprintf(stderr, "-K -> -grab-keyboard\n"); + DEBUG_WARN( "-K -> -grab-keyboard\n"); } CommandLineSwitchCase(arg, "n") { settings->ClientHostname = _strdup(arg->Value); - fprintf(stderr, "-n -> /client-hostname:%s\n", arg->Value); + DEBUG_WARN( "-n -> /client-hostname:%s\n", arg->Value); } CommandLineSwitchCase(arg, "o") { settings->RemoteConsoleAudio = TRUE; - fprintf(stderr, "-o -> /audio-mode:1\n"); + DEBUG_WARN( "-o -> /audio-mode:1\n"); } CommandLineSwitchCase(arg, "p") { settings->Password = _strdup(arg->Value); - fprintf(stderr, "-p ****** -> /p:******\n"); + DEBUG_WARN( "-p ****** -> /p:******\n"); /* Hide the value from 'ps'. */ FillMemory(arg->Value, strlen(arg->Value), '*'); } CommandLineSwitchCase(arg, "s") { settings->AlternateShell = _strdup(arg->Value); - fprintf(stderr, "-s %s -> /shell:%s\n", arg->Value, arg->Value); + DEBUG_WARN( "-s %s -> /shell:%s\n", arg->Value, arg->Value); } CommandLineSwitchCase(arg, "t") { settings->ServerPort = atoi(arg->Value); - fprintf(stderr, "-t %s -> /port:%s\n", arg->Value, arg->Value); + DEBUG_WARN( "-t %s -> /port:%s\n", arg->Value, arg->Value); } CommandLineSwitchCase(arg, "u") { settings->Username = _strdup(arg->Value); - fprintf(stderr, "-u %s -> /u:%s\n", arg->Value, arg->Value); + DEBUG_WARN( "-u %s -> /u:%s\n", arg->Value, arg->Value); } CommandLineSwitchCase(arg, "x") { @@ -555,31 +556,31 @@ int freerdp_client_parse_old_command_line_arguments(int argc, char** argv, rdpSe freerdp_performance_flags_split(settings); } - fprintf(stderr, "-x %s -> /network:", arg->Value); + DEBUG_WARN( "-x %s -> /network:", arg->Value); if (type == CONNECTION_TYPE_MODEM) - fprintf(stderr, "modem"); + DEBUG_WARN( "modem"); else if (CONNECTION_TYPE_BROADBAND_HIGH) - fprintf(stderr, "broadband"); + DEBUG_WARN( "broadband"); else if (CONNECTION_TYPE_LAN) - fprintf(stderr, "lan"); + DEBUG_WARN( "lan"); - fprintf(stderr, "\n"); + DEBUG_WARN( "\n"); } CommandLineSwitchCase(arg, "X") { settings->ParentWindowId = strtol(arg->Value, NULL, 0); - fprintf(stderr, "-X %s -> /parent-window:%s\n", arg->Value, arg->Value); + DEBUG_WARN( "-X %s -> /parent-window:%s\n", arg->Value, arg->Value); } CommandLineSwitchCase(arg, "z") { settings->CompressionEnabled = TRUE; - fprintf(stderr, "-z -> /compression\n"); + DEBUG_WARN( "-z -> /compression\n"); } CommandLineSwitchCase(arg, "app") { settings->RemoteApplicationMode = TRUE; - fprintf(stderr, "--app -> /app: + program name or alias\n"); + DEBUG_WARN( "--app -> /app: + program name or alias\n"); } CommandLineSwitchCase(arg, "ext") { @@ -588,7 +589,7 @@ int freerdp_client_parse_old_command_line_arguments(int argc, char** argv, rdpSe CommandLineSwitchCase(arg, "no-auth") { settings->Authentication = FALSE; - fprintf(stderr, "--no-auth -> -authentication\n"); + DEBUG_WARN( "--no-auth -> -authentication\n"); } CommandLineSwitchCase(arg, "authonly") { @@ -602,12 +603,12 @@ int freerdp_client_parse_old_command_line_arguments(int argc, char** argv, rdpSe { settings->FastPathInput = FALSE; settings->FastPathOutput = FALSE; - fprintf(stderr, "--no-fastpath -> -fast-path\n"); + DEBUG_WARN( "--no-fastpath -> -fast-path\n"); } CommandLineSwitchCase(arg, "no-motion") { settings->MouseMotion = FALSE; - fprintf(stderr, "--no-motion -> -mouse-motion\n"); + DEBUG_WARN( "--no-motion -> -mouse-motion\n"); } CommandLineSwitchCase(arg, "gdi") { @@ -616,26 +617,26 @@ int freerdp_client_parse_old_command_line_arguments(int argc, char** argv, rdpSe else if (strcmp(arg->Value, "hw") == 0) settings->SoftwareGdi = FALSE; - fprintf(stderr, "--gdi %s -> /gdi:%s\n", arg->Value, arg->Value); + DEBUG_WARN( "--gdi %s -> /gdi:%s\n", arg->Value, arg->Value); } CommandLineSwitchCase(arg, "no-osb") { settings->OffscreenSupportLevel = FALSE; - fprintf(stderr, "--no-osb -> -offscreen-cache\n"); + DEBUG_WARN( "--no-osb -> -offscreen-cache\n"); } CommandLineSwitchCase(arg, "no-bmp-cache") { settings->BitmapCacheEnabled = FALSE; - fprintf(stderr, "--no-bmp-cache -> -bitmap-cache\n"); + DEBUG_WARN( "--no-bmp-cache -> -bitmap-cache\n"); } CommandLineSwitchCase(arg, "plugin") { - fprintf(stderr, "--plugin -> /a, /vc, /dvc and channel-specific options\n"); + DEBUG_WARN( "--plugin -> /a, /vc, /dvc and channel-specific options\n"); } CommandLineSwitchCase(arg, "rfx") { settings->RemoteFxCodec = TRUE; - fprintf(stderr, "--rfx -> /rfx\n"); + DEBUG_WARN( "--rfx -> /rfx\n"); } CommandLineSwitchCase(arg, "rfx-mode") { @@ -644,37 +645,37 @@ int freerdp_client_parse_old_command_line_arguments(int argc, char** argv, rdpSe else if (arg->Value[0] == 'i') settings->RemoteFxCodecMode = 0x02; - fprintf(stderr, "--rfx-mode -> /rfx-mode:%s\n", settings->RemoteFxCodecMode ? "image" : "video"); + DEBUG_WARN( "--rfx-mode -> /rfx-mode:%s\n", settings->RemoteFxCodecMode ? "image" : "video"); } CommandLineSwitchCase(arg, "nsc") { settings->NSCodec = TRUE; - fprintf(stderr, "--nsc -> /nsc\n"); + DEBUG_WARN( "--nsc -> /nsc\n"); } CommandLineSwitchCase(arg, "disable-wallpaper") { settings->DisableWallpaper = TRUE; - fprintf(stderr, "--disable-wallpaper -> -wallpaper\n"); + DEBUG_WARN( "--disable-wallpaper -> -wallpaper\n"); } CommandLineSwitchCase(arg, "composition") { settings->AllowDesktopComposition = TRUE; - fprintf(stderr, "--composition -> +composition\n"); + DEBUG_WARN( "--composition -> +composition\n"); } CommandLineSwitchCase(arg, "disable-full-window-drag") { settings->DisableFullWindowDrag = TRUE; - fprintf(stderr, "--disable-full-window-drag -> -window-drag\n"); + DEBUG_WARN( "--disable-full-window-drag -> -window-drag\n"); } CommandLineSwitchCase(arg, "disable-menu-animations") { settings->DisableMenuAnims = TRUE; - fprintf(stderr, "--disable-menu-animations -> -menu-anims\n"); + DEBUG_WARN( "--disable-menu-animations -> -menu-anims\n"); } CommandLineSwitchCase(arg, "disable-theming") { settings->DisableThemes = TRUE; - fprintf(stderr, "--disable-theming -> -themes\n"); + DEBUG_WARN( "--disable-theming -> -themes\n"); } CommandLineSwitchCase(arg, "ntlm") { @@ -683,7 +684,7 @@ int freerdp_client_parse_old_command_line_arguments(int argc, char** argv, rdpSe CommandLineSwitchCase(arg, "ignore-certificate") { settings->IgnoreCertificate = TRUE; - fprintf(stderr, "--ignore-certificate -> /cert-ignore\n"); + DEBUG_WARN( "--ignore-certificate -> /cert-ignore\n"); } CommandLineSwitchCase(arg, "sec") { @@ -709,22 +710,22 @@ int freerdp_client_parse_old_command_line_arguments(int argc, char** argv, rdpSe settings->NlaSecurity = TRUE; } - fprintf(stderr, "--sec %s -> /sec:%s\n", arg->Value, arg->Value); + DEBUG_WARN( "--sec %s -> /sec:%s\n", arg->Value, arg->Value); } CommandLineSwitchCase(arg, "no-rdp") { settings->RdpSecurity = FALSE; - fprintf(stderr, "--no-rdp -> -sec-rdp\n"); + DEBUG_WARN( "--no-rdp -> -sec-rdp\n"); } CommandLineSwitchCase(arg, "no-tls") { settings->TlsSecurity = FALSE; - fprintf(stderr, "--no-tls -> -sec-tls\n"); + DEBUG_WARN( "--no-tls -> -sec-tls\n"); } CommandLineSwitchCase(arg, "no-nla") { settings->NlaSecurity = FALSE; - fprintf(stderr, "--no-nla -> -sec-nla\n"); + DEBUG_WARN( "--no-nla -> -sec-nla\n"); } CommandLineSwitchCase(arg, "secure-checksum") { @@ -739,12 +740,12 @@ int freerdp_client_parse_old_command_line_arguments(int argc, char** argv, rdpSe } while ((arg = CommandLineFindNextArgumentA(arg)) != NULL); - fprintf(stderr, "%s -> /v:%s", settings->ServerHostname, settings->ServerHostname); + DEBUG_WARN( "%s -> /v:%s", settings->ServerHostname, settings->ServerHostname); if (settings->ServerPort != 3389) - fprintf(stderr, " /port:%d", settings->ServerPort); + DEBUG_WARN( " /port:%d", settings->ServerPort); - fprintf(stderr, "\n"); + DEBUG_WARN( "\n"); return 1; } diff --git a/client/common/file.c b/client/common/file.c index 0642384b0..6a646d0d9 100644 --- a/client/common/file.c +++ b/client/common/file.c @@ -21,6 +21,7 @@ #include "config.h" #endif +#include #include #include @@ -54,7 +55,7 @@ BOOL freerdp_client_rdp_file_set_integer(rdpFile* file, const char* name, int va BOOL bStandard = TRUE; #ifdef DEBUG_CLIENT_FILE - fprintf(stderr, "%s:i:%d\n", name, value); + DEBUG_WARN( "%s:i:%d\n", name, value); #endif if (_stricmp(name, "use multimon") == 0) @@ -240,7 +241,7 @@ BOOL freerdp_client_rdp_file_set_string(rdpFile* file, const char* name, const c BOOL bStandard = TRUE; #ifdef DEBUG_CLIENT_FILE - fprintf(stderr, "%s:s:%s\n", name, value); + DEBUG_WARN( "%s:s:%s\n", name, value); #endif if (_stricmp(name, "username") == 0) @@ -665,7 +666,7 @@ BOOL freerdp_client_write_rdp_file(const rdpFile* file, const char* name, BOOL u if (length < 0) { - fprintf(stderr, "freerdp_client_write_rdp_file: error determining buffer size.\n"); + DEBUG_WARN( "freerdp_client_write_rdp_file: error determining buffer size.\n"); return FALSE; } @@ -673,7 +674,7 @@ BOOL freerdp_client_write_rdp_file(const rdpFile* file, const char* name, BOOL u if (freerdp_client_write_rdp_file_buffer(file, buffer, length + 1) != length) { - fprintf(stderr, "freerdp_client_write_rdp_file: error writing to output buffer\n"); + DEBUG_WARN( "freerdp_client_write_rdp_file: error writing to output buffer\n"); free(buffer); return FALSE; } diff --git a/client/iOS/Resources/Default-568h@2x.png b/client/iOS/Resources/Default-568h@2x.png index bc2676bd8..9537b26d8 100644 Binary files a/client/iOS/Resources/Default-568h@2x.png and b/client/iOS/Resources/Default-568h@2x.png differ diff --git a/client/iOS/Resources/Default-Landscape@2x~ipad.png b/client/iOS/Resources/Default-Landscape@2x~ipad.png index fe643b1bb..572927401 100644 Binary files a/client/iOS/Resources/Default-Landscape@2x~ipad.png and b/client/iOS/Resources/Default-Landscape@2x~ipad.png differ diff --git a/client/iOS/Resources/Default-Landscape~ipad.png b/client/iOS/Resources/Default-Landscape~ipad.png index fe4be748b..9d341cdd4 100644 Binary files a/client/iOS/Resources/Default-Landscape~ipad.png and b/client/iOS/Resources/Default-Landscape~ipad.png differ diff --git a/client/iOS/Resources/Default-Portrait@2x~ipad.png b/client/iOS/Resources/Default-Portrait@2x~ipad.png index db4a788a8..8f5229902 100644 Binary files a/client/iOS/Resources/Default-Portrait@2x~ipad.png and b/client/iOS/Resources/Default-Portrait@2x~ipad.png differ diff --git a/client/iOS/Resources/Default-Portrait~ipad.png b/client/iOS/Resources/Default-Portrait~ipad.png index 94b50ec39..bf15ee27e 100644 Binary files a/client/iOS/Resources/Default-Portrait~ipad.png and b/client/iOS/Resources/Default-Portrait~ipad.png differ diff --git a/client/iOS/Resources/Default.png b/client/iOS/Resources/Default.png index 86fe48377..0a221638c 100644 Binary files a/client/iOS/Resources/Default.png and b/client/iOS/Resources/Default.png differ diff --git a/client/iOS/Resources/Default@2x.png b/client/iOS/Resources/Default@2x.png index ba63bf054..74af0a3cb 100644 Binary files a/client/iOS/Resources/Default@2x.png and b/client/iOS/Resources/Default@2x.png differ diff --git a/client/iOS/Resources/Icon-72.png b/client/iOS/Resources/Icon-72.png index 94951e167..d5be47ff7 100644 Binary files a/client/iOS/Resources/Icon-72.png and b/client/iOS/Resources/Icon-72.png differ diff --git a/client/iOS/Resources/Icon-72@2x.png b/client/iOS/Resources/Icon-72@2x.png index e0278b8c6..db3c695ec 100644 Binary files a/client/iOS/Resources/Icon-72@2x.png and b/client/iOS/Resources/Icon-72@2x.png differ diff --git a/client/iOS/Resources/Icon.png b/client/iOS/Resources/Icon.png index 0d09cdd14..535ed700c 100644 Binary files a/client/iOS/Resources/Icon.png and b/client/iOS/Resources/Icon.png differ diff --git a/client/iOS/Resources/Icon@2x.png b/client/iOS/Resources/Icon@2x.png index 9b7fae26c..c00b5f0f4 100644 Binary files a/client/iOS/Resources/Icon@2x.png and b/client/iOS/Resources/Icon@2x.png differ diff --git a/client/iOS/Resources/about_page/FreeRDP_Logo.png b/client/iOS/Resources/about_page/FreeRDP_Logo.png index 3b2d02f1d..1e272627b 100644 Binary files a/client/iOS/Resources/about_page/FreeRDP_Logo.png and b/client/iOS/Resources/about_page/FreeRDP_Logo.png differ diff --git a/client/iOS/Resources/about_page/back.jpg b/client/iOS/Resources/about_page/back.jpg index 3bf3455bf..fd4e1d364 100644 Binary files a/client/iOS/Resources/about_page/back.jpg and b/client/iOS/Resources/about_page/back.jpg differ diff --git a/client/iOS/Resources/about_page/background_transparent.png b/client/iOS/Resources/about_page/background_transparent.png index 0eba5b5d2..d9d377bdf 100644 Binary files a/client/iOS/Resources/about_page/background_transparent.png and b/client/iOS/Resources/about_page/background_transparent.png differ diff --git a/client/iOS/Resources/alert-black-button.png b/client/iOS/Resources/alert-black-button.png index d06b66df1..998139788 100644 Binary files a/client/iOS/Resources/alert-black-button.png and b/client/iOS/Resources/alert-black-button.png differ diff --git a/client/iOS/Resources/alert-black-button@2x.png b/client/iOS/Resources/alert-black-button@2x.png index 4caec8ea3..234bda42f 100644 Binary files a/client/iOS/Resources/alert-black-button@2x.png and b/client/iOS/Resources/alert-black-button@2x.png differ diff --git a/client/iOS/Resources/alert-gray-button.png b/client/iOS/Resources/alert-gray-button.png index 06548df51..3696a67ac 100644 Binary files a/client/iOS/Resources/alert-gray-button.png and b/client/iOS/Resources/alert-gray-button.png differ diff --git a/client/iOS/Resources/alert-gray-button@2x.png b/client/iOS/Resources/alert-gray-button@2x.png index 8333e6cfb..b1393c099 100644 Binary files a/client/iOS/Resources/alert-gray-button@2x.png and b/client/iOS/Resources/alert-gray-button@2x.png differ diff --git a/client/iOS/Resources/alert-red-button.png b/client/iOS/Resources/alert-red-button.png index 896742f9c..bdf3028b8 100644 Binary files a/client/iOS/Resources/alert-red-button.png and b/client/iOS/Resources/alert-red-button.png differ diff --git a/client/iOS/Resources/alert-red-button@2x.png b/client/iOS/Resources/alert-red-button@2x.png index 852bd3f4b..1c513773b 100644 Binary files a/client/iOS/Resources/alert-red-button@2x.png and b/client/iOS/Resources/alert-red-button@2x.png differ diff --git a/client/iOS/Resources/alert-window-landscape.png b/client/iOS/Resources/alert-window-landscape.png index 1149b28cd..13c598585 100644 Binary files a/client/iOS/Resources/alert-window-landscape.png and b/client/iOS/Resources/alert-window-landscape.png differ diff --git a/client/iOS/Resources/alert-window-landscape@2x.png b/client/iOS/Resources/alert-window-landscape@2x.png index 3bb3b8aab..aeb030832 100644 Binary files a/client/iOS/Resources/alert-window-landscape@2x.png and b/client/iOS/Resources/alert-window-landscape@2x.png differ diff --git a/client/iOS/Resources/alert-window.png b/client/iOS/Resources/alert-window.png index e4907cf53..ea192d57a 100644 Binary files a/client/iOS/Resources/alert-window.png and b/client/iOS/Resources/alert-window.png differ diff --git a/client/iOS/Resources/alert-window@2x.png b/client/iOS/Resources/alert-window@2x.png index 2ecd13855..6de36ea03 100644 Binary files a/client/iOS/Resources/alert-window@2x.png and b/client/iOS/Resources/alert-window@2x.png differ diff --git a/client/iOS/Resources/cancel_button_background.png b/client/iOS/Resources/cancel_button_background.png index ae12d407d..5061279c0 100644 Binary files a/client/iOS/Resources/cancel_button_background.png and b/client/iOS/Resources/cancel_button_background.png differ diff --git a/client/iOS/Resources/help_page/back.jpg b/client/iOS/Resources/help_page/back.jpg index 3bf3455bf..fd4e1d364 100644 Binary files a/client/iOS/Resources/help_page/back.jpg and b/client/iOS/Resources/help_page/back.jpg differ diff --git a/client/iOS/Resources/help_page/gestures.png b/client/iOS/Resources/help_page/gestures.png index e49a45b8f..78b3e7b34 100644 Binary files a/client/iOS/Resources/help_page/gestures.png and b/client/iOS/Resources/help_page/gestures.png differ diff --git a/client/iOS/Resources/help_page/gestures_phone.png b/client/iOS/Resources/help_page/gestures_phone.png index 1b90a1f65..4eea33ef4 100644 Binary files a/client/iOS/Resources/help_page/gestures_phone.png and b/client/iOS/Resources/help_page/gestures_phone.png differ diff --git a/client/iOS/Resources/help_page/nav_gestures.png b/client/iOS/Resources/help_page/nav_gestures.png index ab1b36fba..50bfaa232 100644 Binary files a/client/iOS/Resources/help_page/nav_gestures.png and b/client/iOS/Resources/help_page/nav_gestures.png differ diff --git a/client/iOS/Resources/help_page/nav_toolbar.png b/client/iOS/Resources/help_page/nav_toolbar.png index 703c0013a..f66b24d21 100644 Binary files a/client/iOS/Resources/help_page/nav_toolbar.png and b/client/iOS/Resources/help_page/nav_toolbar.png differ diff --git a/client/iOS/Resources/help_page/nav_touch_pointer.png b/client/iOS/Resources/help_page/nav_touch_pointer.png index 30e04568e..930fc9cbf 100644 Binary files a/client/iOS/Resources/help_page/nav_touch_pointer.png and b/client/iOS/Resources/help_page/nav_touch_pointer.png differ diff --git a/client/iOS/Resources/help_page/toolbar.png b/client/iOS/Resources/help_page/toolbar.png index 10c23b62b..42f055b9f 100644 Binary files a/client/iOS/Resources/help_page/toolbar.png and b/client/iOS/Resources/help_page/toolbar.png differ diff --git a/client/iOS/Resources/help_page/toolbar_phone.png b/client/iOS/Resources/help_page/toolbar_phone.png index a01279ce0..278cd3a9d 100644 Binary files a/client/iOS/Resources/help_page/toolbar_phone.png and b/client/iOS/Resources/help_page/toolbar_phone.png differ diff --git a/client/iOS/Resources/help_page/touch_pointer.png b/client/iOS/Resources/help_page/touch_pointer.png index f06e3889f..af3ebcab0 100644 Binary files a/client/iOS/Resources/help_page/touch_pointer.png and b/client/iOS/Resources/help_page/touch_pointer.png differ diff --git a/client/iOS/Resources/help_page/touch_pointer_phone.png b/client/iOS/Resources/help_page/touch_pointer_phone.png index 168749fd0..ab7c59896 100644 Binary files a/client/iOS/Resources/help_page/touch_pointer_phone.png and b/client/iOS/Resources/help_page/touch_pointer_phone.png differ diff --git a/client/iOS/Resources/icon_accessory_star_off.png b/client/iOS/Resources/icon_accessory_star_off.png index f0f1eb845..b0dce0e66 100644 Binary files a/client/iOS/Resources/icon_accessory_star_off.png and b/client/iOS/Resources/icon_accessory_star_off.png differ diff --git a/client/iOS/Resources/icon_accessory_star_on.png b/client/iOS/Resources/icon_accessory_star_on.png index cf5ed353b..b09dec7ae 100644 Binary files a/client/iOS/Resources/icon_accessory_star_on.png and b/client/iOS/Resources/icon_accessory_star_on.png differ diff --git a/client/iOS/Resources/icon_key_arrow_down.png b/client/iOS/Resources/icon_key_arrow_down.png index 3baf19cab..b003e1295 100644 Binary files a/client/iOS/Resources/icon_key_arrow_down.png and b/client/iOS/Resources/icon_key_arrow_down.png differ diff --git a/client/iOS/Resources/icon_key_arrow_left.png b/client/iOS/Resources/icon_key_arrow_left.png index 4c0c8eb14..7cd1ed3d4 100644 Binary files a/client/iOS/Resources/icon_key_arrow_left.png and b/client/iOS/Resources/icon_key_arrow_left.png differ diff --git a/client/iOS/Resources/icon_key_arrow_right.png b/client/iOS/Resources/icon_key_arrow_right.png index 10c7d8e27..9a5815730 100644 Binary files a/client/iOS/Resources/icon_key_arrow_right.png and b/client/iOS/Resources/icon_key_arrow_right.png differ diff --git a/client/iOS/Resources/icon_key_arrow_up.png b/client/iOS/Resources/icon_key_arrow_up.png index b8e3f2820..248c7f617 100644 Binary files a/client/iOS/Resources/icon_key_arrow_up.png and b/client/iOS/Resources/icon_key_arrow_up.png differ diff --git a/client/iOS/Resources/icon_key_arrows.png b/client/iOS/Resources/icon_key_arrows.png index 56c915369..e92ef461a 100644 Binary files a/client/iOS/Resources/icon_key_arrows.png and b/client/iOS/Resources/icon_key_arrows.png differ diff --git a/client/iOS/Resources/icon_key_backspace.png b/client/iOS/Resources/icon_key_backspace.png index 7e9d29541..730d3e16b 100644 Binary files a/client/iOS/Resources/icon_key_backspace.png and b/client/iOS/Resources/icon_key_backspace.png differ diff --git a/client/iOS/Resources/icon_key_menu.png b/client/iOS/Resources/icon_key_menu.png index 0b4445263..61e12ed2a 100644 Binary files a/client/iOS/Resources/icon_key_menu.png and b/client/iOS/Resources/icon_key_menu.png differ diff --git a/client/iOS/Resources/icon_key_return.png b/client/iOS/Resources/icon_key_return.png index 9311ad171..bf6a7da20 100644 Binary files a/client/iOS/Resources/icon_key_return.png and b/client/iOS/Resources/icon_key_return.png differ diff --git a/client/iOS/Resources/icon_key_win.png b/client/iOS/Resources/icon_key_win.png index 1ab7b2b46..bd43d8241 100644 Binary files a/client/iOS/Resources/icon_key_win.png and b/client/iOS/Resources/icon_key_win.png differ diff --git a/client/iOS/Resources/keyboard_button_background.png b/client/iOS/Resources/keyboard_button_background.png index c6cd5795b..cfb229ec4 100644 Binary files a/client/iOS/Resources/keyboard_button_background.png and b/client/iOS/Resources/keyboard_button_background.png differ diff --git a/client/iOS/Resources/tabbar_icon_about.png b/client/iOS/Resources/tabbar_icon_about.png index 8d03924a8..01709a5a1 100644 Binary files a/client/iOS/Resources/tabbar_icon_about.png and b/client/iOS/Resources/tabbar_icon_about.png differ diff --git a/client/iOS/Resources/tabbar_icon_help.png b/client/iOS/Resources/tabbar_icon_help.png index 0732b7d15..4e66e5bcb 100644 Binary files a/client/iOS/Resources/tabbar_icon_help.png and b/client/iOS/Resources/tabbar_icon_help.png differ diff --git a/client/iOS/Resources/tabbar_icon_settings.png b/client/iOS/Resources/tabbar_icon_settings.png index 04578f02c..7cf0380f3 100644 Binary files a/client/iOS/Resources/tabbar_icon_settings.png and b/client/iOS/Resources/tabbar_icon_settings.png differ diff --git a/client/iOS/Resources/toolbar_icon_disconnect.png b/client/iOS/Resources/toolbar_icon_disconnect.png index cb823d4ec..e78510910 100644 Binary files a/client/iOS/Resources/toolbar_icon_disconnect.png and b/client/iOS/Resources/toolbar_icon_disconnect.png differ diff --git a/client/iOS/Resources/toolbar_icon_extkeyboad.png b/client/iOS/Resources/toolbar_icon_extkeyboad.png index 9436c07c3..463d70172 100644 Binary files a/client/iOS/Resources/toolbar_icon_extkeyboad.png and b/client/iOS/Resources/toolbar_icon_extkeyboad.png differ diff --git a/client/iOS/Resources/toolbar_icon_home.png b/client/iOS/Resources/toolbar_icon_home.png index afcd9e4a9..b9152c05b 100644 Binary files a/client/iOS/Resources/toolbar_icon_home.png and b/client/iOS/Resources/toolbar_icon_home.png differ diff --git a/client/iOS/Resources/toolbar_icon_keyboard.png b/client/iOS/Resources/toolbar_icon_keyboard.png index c2a068531..622c9ec10 100644 Binary files a/client/iOS/Resources/toolbar_icon_keyboard.png and b/client/iOS/Resources/toolbar_icon_keyboard.png differ diff --git a/client/iOS/Resources/toolbar_icon_touchpointer.png b/client/iOS/Resources/toolbar_icon_touchpointer.png index fc44508c9..4c738d4ab 100644 Binary files a/client/iOS/Resources/toolbar_icon_touchpointer.png and b/client/iOS/Resources/toolbar_icon_touchpointer.png differ diff --git a/client/iOS/Resources/toolbar_icon_win.png b/client/iOS/Resources/toolbar_icon_win.png index 73328db1a..5c224971f 100644 Binary files a/client/iOS/Resources/toolbar_icon_win.png and b/client/iOS/Resources/toolbar_icon_win.png differ diff --git a/client/iOS/Resources/touch_pointer_active.png b/client/iOS/Resources/touch_pointer_active.png index c153de484..9966590ed 100644 Binary files a/client/iOS/Resources/touch_pointer_active.png and b/client/iOS/Resources/touch_pointer_active.png differ diff --git a/client/iOS/Resources/touch_pointer_default.png b/client/iOS/Resources/touch_pointer_default.png index ba16a47c8..5f419eefd 100644 Binary files a/client/iOS/Resources/touch_pointer_default.png and b/client/iOS/Resources/touch_pointer_default.png differ diff --git a/client/iOS/Resources/touch_pointer_extkeyboard.png b/client/iOS/Resources/touch_pointer_extkeyboard.png index 6f0c8cd10..bbc9752c4 100644 Binary files a/client/iOS/Resources/touch_pointer_extkeyboard.png and b/client/iOS/Resources/touch_pointer_extkeyboard.png differ diff --git a/client/iOS/Resources/touch_pointer_keyboard.png b/client/iOS/Resources/touch_pointer_keyboard.png index 1a6d60dbd..d5cf2033a 100644 Binary files a/client/iOS/Resources/touch_pointer_keyboard.png and b/client/iOS/Resources/touch_pointer_keyboard.png differ diff --git a/client/iOS/Resources/touch_pointer_lclick.png b/client/iOS/Resources/touch_pointer_lclick.png index 447d8abae..69d721501 100644 Binary files a/client/iOS/Resources/touch_pointer_lclick.png and b/client/iOS/Resources/touch_pointer_lclick.png differ diff --git a/client/iOS/Resources/touch_pointer_rclick.png b/client/iOS/Resources/touch_pointer_rclick.png index ad3ca8543..dc3c173b7 100644 Binary files a/client/iOS/Resources/touch_pointer_rclick.png and b/client/iOS/Resources/touch_pointer_rclick.png differ diff --git a/client/iOS/Resources/touch_pointer_reset.png b/client/iOS/Resources/touch_pointer_reset.png index 41ef8402a..b42b3fa59 100644 Binary files a/client/iOS/Resources/touch_pointer_reset.png and b/client/iOS/Resources/touch_pointer_reset.png differ diff --git a/client/iOS/Resources/touch_pointer_scroll.png b/client/iOS/Resources/touch_pointer_scroll.png index 2855e0165..b4d7e24de 100644 Binary files a/client/iOS/Resources/touch_pointer_scroll.png and b/client/iOS/Resources/touch_pointer_scroll.png differ diff --git a/config.h.in b/config.h.in index e0da60c6a..b196cc5ae 100644 --- a/config.h.in +++ b/config.h.in @@ -27,7 +27,7 @@ #cmakedefine HAVE_POLL_H #cmakedefine HAVE_PTHREAD_GNU_EXT #cmakedefine HAVE_VALGRIND_MEMCHECK_H - +#cmakedefine HAVE_EXECINFO_H /* Options */ #cmakedefine WITH_PROFILER diff --git a/include/freerdp/assistance.h b/include/freerdp/assistance.h index a2fe426d6..050f93363 100644 --- a/include/freerdp/assistance.h +++ b/include/freerdp/assistance.h @@ -59,6 +59,10 @@ extern "C" { FREERDP_API BYTE* freerdp_assistance_hex_string_to_bin(const char* str, int* size); FREERDP_API char* freerdp_assistance_bin_to_hex_string(const BYTE* data, int size); +FREERDP_API int freerdp_assistance_parse_connection_string1(rdpAssistanceFile* file); +FREERDP_API int freerdp_assistance_parse_connection_string2(rdpAssistanceFile* file); + +FREERDP_API char* freerdp_assistance_generate_pass_stub(DWORD flags); FREERDP_API char* freerdp_assistance_construct_expert_blob(const char* name, const char* pass); FREERDP_API BYTE* freerdp_assistance_encrypt_pass_stub(const char* password, const char* passStub, int* pEncryptedSize); diff --git a/include/freerdp/channels/log.h b/include/freerdp/channels/log.h new file mode 100644 index 000000000..f2125a68c --- /dev/null +++ b/include/freerdp/channels/log.h @@ -0,0 +1,58 @@ +/** + * FreeRDP: A Remote Desktop Protocol Implementation + * Channel log defines + * + * Copyright 2014 Armin Novak + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef FREERDP_CHANNELS_LOG_H +#define FREERDP_CHANNELS_LOG_H + +#include + +#define CLOG_PRINT(level, file, fkt, line, dbg_str, fmt, ...) \ + do { \ + char tag[1024] = { 0 }; \ + wLogMessage msg; \ + wLog *log; \ + \ + strncat(tag, "com.freerdp.channels.", sizeof(tag) - 1); \ + strncat(tag, dbg_str, sizeof(tag) - 1 - sizeof("com.freerdp.channels.")); \ + log = WLog_Get(tag); \ + \ + msg.Type = WLOG_MESSAGE_TEXT; \ + msg.Level = level; \ + msg.FormatString = fmt; \ + msg.LineNumber = line; \ + msg.FileName = file; \ + msg.FunctionName = fkt; \ + WLog_PrintMessage(log, &msg, ##__VA_ARGS__); \ + } while (0 ) + +#define CLOG_NULL(fmt, ...) do { } while (0) +#define CLOG_CLASS(_dbg_class, fmt, ...) CLOG_PRINT(WLOG_ERROR, __FILE__, \ + __FUNCTION__, __LINE__, #_dbg_class, fmt, ## __VA_ARGS__) +#define CLOG_DBG(fmt, ...) CLOG_PRINT(WLOG_DEBUG, __FILE__, __FUNCTION__, \ + __LINE__, __FUNCTION__, fmt, ## __VA_ARGS__) +#define CLOG_INFO(fmt, ...) CLOG_PRINT(WLOG_INFO, __FILE__, __FUNCTION__, \ + __LINE__, __FUNCTION__, fmt, ## __VA_ARGS__) +#define CLOG_WARN(fmt, ...) CLOG_PRINT(WLOG_WARN, __FILE__, __FUNCTION__, \ + __LINE__, __FUNCTION__, fmt, ## __VA_ARGS__) +#define CLOG_ERR(fmt, ...) CLOG_PRINT(WLOG_ERROR, __FILE__, __FUNCTION__, \ + __LINE__, __FUNCTION__, fmt, ## __VA_ARGS__) +#define CLOG_FATAL(fmt, ...) CLOG_PRINT(WLOG_FATAL, __FILE__, __FUNCTION__, \ + __LINE__, __FUNCTION__, fmt, ## __VA_ARGS__) + +#endif /* FREERDP_UTILS_DEBUG_H */ diff --git a/include/freerdp/channels/remdesk.h b/include/freerdp/channels/remdesk.h index a3fa55ac2..22b6f6db4 100644 --- a/include/freerdp/channels/remdesk.h +++ b/include/freerdp/channels/remdesk.h @@ -25,6 +25,55 @@ #define REMDESK_SVC_CHANNEL_NAME "remdesk" +#define REMDESK_ERROR_NOERROR 0 +#define REMDESK_ERROR_NOINFO 1 +#define REMDESK_ERROR_LOCALNOTERROR 3 +#define REMDESK_ERROR_REMOTEBYUSER 4 +#define REMDESK_ERROR_BYSERVER 5 +#define REMDESK_ERROR_DNSLOOKUPFAILED 6 +#define REMDESK_ERROR_OUTOFMEMORY 7 +#define REMDESK_ERROR_CONNECTIONTIMEDOUT 8 +#define REMDESK_ERROR_SOCKETCONNECTFAILED 9 +#define REMDESK_ERROR_HOSTNOTFOUND 11 +#define REMDESK_ERROR_WINSOCKSENDFAILED 12 +#define REMDESK_ERROR_INVALIDIPADDR 14 +#define REMDESK_ERROR_SOCKETRECVFAILED 15 +#define REMDESK_ERROR_INVALIDENCRYPTION 18 +#define REMDESK_ERROR_GETHOSTBYNAMEFAILED 20 +#define REMDESK_ERROR_LICENSINGFAILED 21 +#define REMDESK_ERROR_ENCRYPTIONERROR 22 +#define REMDESK_ERROR_DECRYPTIONERROR 23 +#define REMDESK_ERROR_INVALIDPARAMETERSTRING 24 +#define REMDESK_ERROR_HELPSESSIONNOTFOUND 25 +#define REMDESK_ERROR_INVALIDPASSWORD 26 +#define REMDESK_ERROR_HELPSESSIONEXPIRED 27 +#define REMDESK_ERROR_CANTOPENRESOLVER 28 +#define REMDESK_ERROR_UNKNOWNSESSMGRERROR 29 +#define REMDESK_ERROR_CANTFORMLINKTOUSERSESSION 30 +#define REMDESK_ERROR_RCPROTOCOLERROR 32 +#define REMDESK_ERROR_RCUNKNOWNERROR 33 +#define REMDESK_ERROR_INTERNALERROR 34 +#define REMDESK_ERROR_HELPEERESPONSEPENDING 35 +#define REMDESK_ERROR_HELPEESAIDYES 36 +#define REMDESK_ERROR_HELPEEALREADYBEINGHELPED 37 +#define REMDESK_ERROR_HELPEECONSIDERINGHELP 38 +#define REMDESK_ERROR_HELPEENEVERRESPONDED 40 +#define REMDESK_ERROR_HELPEESAIDNO 41 +#define REMDESK_ERROR_HELPSESSIONACCESSDENIED 42 +#define REMDESK_ERROR_USERNOTFOUND 43 +#define REMDESK_ERROR_SESSMGRERRORNOTINIT 44 +#define REMDESK_ERROR_SELFHELPNOTSUPPORTED 45 +#define REMDESK_ERROR_INCOMPATIBLEVERSION 47 +#define REMDESK_ERROR_SESSIONNOTCONNECTED 48 +#define REMDESK_ERROR_SYSTEMSHUTDOWN 50 +#define REMDESK_ERROR_STOPLISTENBYUSER 51 +#define REMDESK_ERROR_WINSOCK_FAILED 52 +#define REMDESK_ERROR_MISMATCHPARMS 53 +#define REMDESK_ERROR_PASSWORDS_DONT_MATCH 61 +#define REMDESK_ERROR_SHADOWEND_BASE 300 +#define REMDESK_ERROR_SHADOWEND_CONFIGCHANGE 301 +#define REMDESK_ERROR_SHADOWEND_UNKNOWN 302 + struct _REMDESK_CHANNEL_HEADER { UINT32 DataLength; @@ -57,6 +106,14 @@ typedef struct _REMDESK_CTL_HEADER REMDESK_CTL_HEADER; #define REMDESK_CTL_RAEXPERT_NAME 11 #define REMDESK_CTL_TOKEN 12 +struct _REMDESK_CTL_RESULT_PDU +{ + REMDESK_CTL_HEADER ctlHeader; + + UINT32 result; +}; +typedef struct _REMDESK_CTL_RESULT_PDU REMDESK_CTL_RESULT_PDU; + struct _REMDESK_CTL_VERSION_INFO_PDU { REMDESK_CTL_HEADER ctlHeader; diff --git a/include/freerdp/codec/color.h b/include/freerdp/codec/color.h index 4fdaf8aa9..47c6126e3 100644 --- a/include/freerdp/codec/color.h +++ b/include/freerdp/codec/color.h @@ -373,6 +373,14 @@ typedef CLRCONV* HCLRCONV; typedef BYTE* (*p_freerdp_image_convert)(BYTE* srcData, BYTE* dstData, int width, int height, int srcBpp, int dstBpp, HCLRCONV clrconv); +static INLINE UINT32 RGB32_to_BGR32(UINT32 pixel) +{ + UINT32 temp; + + temp = (pixel ^ (pixel >> 16)) & ((1 << 8) - 1); + return (pixel ^ (temp | (temp << 16))); +} + FREERDP_API int freerdp_get_pixel(BYTE* data, int x, int y, int width, int height, int bpp); FREERDP_API void freerdp_set_pixel(BYTE* data, int x, int y, int width, int height, int bpp, int pixel); @@ -392,6 +400,7 @@ FREERDP_API UINT32 freerdp_color_convert_rgb_bgr(UINT32 srcColor, int srcBpp, in FREERDP_API UINT32 freerdp_color_convert_bgr_rgb(UINT32 srcColor, int srcBpp, int dstBpp, HCLRCONV clrconv); FREERDP_API UINT32 freerdp_color_convert_var_rgb(UINT32 srcColor, int srcBpp, int dstBpp, HCLRCONV clrconv); FREERDP_API UINT32 freerdp_color_convert_var_bgr(UINT32 srcColor, int srcBpp, int dstBpp, HCLRCONV clrconv); +FREERDP_API UINT32 freerdp_color_convert_drawing_order_color_to_gdi_color(UINT32 color, int bpp, HCLRCONV clrconv); FREERDP_API HCLRCONV freerdp_clrconv_new(UINT32 flags); FREERDP_API void freerdp_clrconv_free(HCLRCONV clrconv); diff --git a/include/freerdp/codec/h264.h b/include/freerdp/codec/h264.h index ccc37be9e..d29a9e243 100644 --- a/include/freerdp/codec/h264.h +++ b/include/freerdp/codec/h264.h @@ -24,21 +24,22 @@ #include #include -#ifdef WITH_LIBAVCODEC -#ifdef WITH_OPENH264 -#undef WITH_OPENH264 -#endif -#endif +typedef struct _H264_CONTEXT H264_CONTEXT; -#ifdef WITH_OPENH264 -#include "wels/codec_def.h" -#include "wels/codec_api.h" -#endif +typedef BOOL (*pfnH264SubsystemInit)(H264_CONTEXT* h264); +typedef void (*pfnH264SubsystemUninit)(H264_CONTEXT* h264); -#ifdef WITH_LIBAVCODEC -#include -#include -#endif +typedef int (*pfnH264SubsystemDecompress)(H264_CONTEXT* h264, BYTE* pSrcData, UINT32 SrcSize, + BYTE* pDstData, DWORD DstFormat, int nDstStep, int nXDst, int nYDst, int nWidth, int nHeight); + +struct _H264_CONTEXT_SUBSYSTEM +{ + const char* name; + pfnH264SubsystemInit Init; + pfnH264SubsystemUninit Uninit; + pfnH264SubsystemDecompress Decompress; +}; +typedef struct _H264_CONTEXT_SUBSYSTEM H264_CONTEXT_SUBSYSTEM; struct _H264_CONTEXT { @@ -50,6 +51,8 @@ struct _H264_CONTEXT UINT32 height; //int scanline; +/* +<<<<<<< HEAD #ifdef WITH_OPENH264 ISVCDecoder* pDecoder; BYTE* pYUVData[3]; @@ -62,8 +65,11 @@ struct _H264_CONTEXT AVCodecParserContext* codecParser; AVFrame* videoFrame; #endif +======= +*/ + void* pSystemData; + H264_CONTEXT_SUBSYSTEM* subsystem; }; -typedef struct _H264_CONTEXT H264_CONTEXT; #ifdef __cplusplus extern "C" { @@ -74,8 +80,6 @@ FREERDP_API int h264_compress(H264_CONTEXT* h264, BYTE* pSrcData, UINT32 SrcSize FREERDP_API int h264_decompress(H264_CONTEXT* h264, BYTE* pSrcData, UINT32 SrcSize, BYTE** ppDstData, DWORD DstFormat, int nDstStep, int nDstHeight, RDPGFX_RECT16* regionRects, int numRegionRect); -FREERDP_API void h264_context_reset(H264_CONTEXT* h264); - FREERDP_API H264_CONTEXT* h264_context_new(BOOL Compressor); FREERDP_API void h264_context_free(H264_CONTEXT* h264); diff --git a/include/freerdp/codec/progressive.h b/include/freerdp/codec/progressive.h index e22ab10fc..e18310ed8 100644 --- a/include/freerdp/codec/progressive.h +++ b/include/freerdp/codec/progressive.h @@ -23,6 +23,7 @@ #include #include +#include #include #include @@ -47,15 +48,6 @@ #define PROGRESSIVE_BLOCKS_REGION 0x0002 #define PROGRESSIVE_BLOCKS_TILE 0x0004 -struct _RFX_PROGRESSIVE_CODEC_QUANT -{ - BYTE quality; - BYTE yQuantValues[5]; - BYTE cbQuantValues[5]; - BYTE crQuantValues[5]; -}; -typedef struct _RFX_PROGRESSIVE_CODEC_QUANT RFX_PROGRESSIVE_CODEC_QUANT; - struct _RFX_COMPONENT_CODEC_QUANT { BYTE LL3; @@ -71,6 +63,15 @@ struct _RFX_COMPONENT_CODEC_QUANT }; typedef struct _RFX_COMPONENT_CODEC_QUANT RFX_COMPONENT_CODEC_QUANT; +struct _RFX_PROGRESSIVE_CODEC_QUANT +{ + BYTE quality; + RFX_COMPONENT_CODEC_QUANT yQuantValues; + RFX_COMPONENT_CODEC_QUANT cbQuantValues; + RFX_COMPONENT_CODEC_QUANT crQuantValues; +}; +typedef struct _RFX_PROGRESSIVE_CODEC_QUANT RFX_PROGRESSIVE_CODEC_QUANT; + struct _PROGRESSIVE_BLOCK { UINT16 blockType; @@ -205,6 +206,25 @@ struct _RFX_PROGRESSIVE_TILE BYTE* cbRawData; BYTE* crSrlData; BYTE* crRawData; + + int x; + int y; + int width; + int height; + BYTE* data; + BYTE* current; + + int pass; + BYTE* sign; + RFX_COMPONENT_CODEC_QUANT yBitPos; + RFX_COMPONENT_CODEC_QUANT cbBitPos; + RFX_COMPONENT_CODEC_QUANT crBitPos; + RFX_COMPONENT_CODEC_QUANT yQuant; + RFX_COMPONENT_CODEC_QUANT cbQuant; + RFX_COMPONENT_CODEC_QUANT crQuant; + RFX_COMPONENT_CODEC_QUANT yProgQuant; + RFX_COMPONENT_CODEC_QUANT cbProgQuant; + RFX_COMPONENT_CODEC_QUANT crProgQuant; }; typedef struct _RFX_PROGRESSIVE_TILE RFX_PROGRESSIVE_TILE; @@ -223,7 +243,7 @@ struct _PROGRESSIVE_BLOCK_REGION RFX_RECT* rects; RFX_COMPONENT_CODEC_QUANT* quantVals; RFX_PROGRESSIVE_CODEC_QUANT* quantProgVals; - RFX_PROGRESSIVE_TILE* tiles; + RFX_PROGRESSIVE_TILE** tiles; }; typedef struct _PROGRESSIVE_BLOCK_REGION PROGRESSIVE_BLOCK_REGION; @@ -245,17 +265,30 @@ struct _PROGRESSIVE_BLOCK_FRAME_END }; typedef struct _PROGRESSIVE_BLOCK_FRAME_END PROGRESSIVE_BLOCK_FRAME_END; +struct _PROGRESSIVE_SURFACE_CONTEXT +{ + UINT16 id; + UINT32 width; + UINT32 height; + UINT32 gridWidth; + UINT32 gridHeight; + UINT32 gridSize; + RFX_PROGRESSIVE_TILE* tiles; +}; +typedef struct _PROGRESSIVE_SURFACE_CONTEXT PROGRESSIVE_SURFACE_CONTEXT; + struct _PROGRESSIVE_CONTEXT { BOOL Compressor; + wLog* log; wBufferPool* bufferPool; UINT32 cRects; RFX_RECT* rects; UINT32 cTiles; - RFX_PROGRESSIVE_TILE* tiles; + RFX_PROGRESSIVE_TILE** tiles; UINT32 cQuant; RFX_COMPONENT_CODEC_QUANT* quantVals; @@ -265,6 +298,8 @@ struct _PROGRESSIVE_CONTEXT PROGRESSIVE_BLOCK_REGION region; RFX_PROGRESSIVE_CODEC_QUANT quantProgValFull; + + wHashTable* SurfaceContexts; }; typedef struct _PROGRESSIVE_CONTEXT PROGRESSIVE_CONTEXT; @@ -275,7 +310,10 @@ extern "C" { FREERDP_API int progressive_compress(PROGRESSIVE_CONTEXT* progressive, BYTE* pSrcData, UINT32 SrcSize, BYTE** ppDstData, UINT32* pDstSize); FREERDP_API int progressive_decompress(PROGRESSIVE_CONTEXT* progressive, BYTE* pSrcData, UINT32 SrcSize, - BYTE** ppDstData, DWORD DstFormat, int nDstStep, int nXDst, int nYDst, int nWidth, int nHeight); + BYTE** ppDstData, DWORD DstFormat, int nDstStep, int nXDst, int nYDst, int nWidth, int nHeight, UINT16 surfaceId); + +FREERDP_API int progressive_create_surface_context(PROGRESSIVE_CONTEXT* progressive, UINT16 surfaceId, UINT32 width, UINT32 height); +FREERDP_API int progressive_delete_surface_context(PROGRESSIVE_CONTEXT* progressive, UINT16 surfaceId); FREERDP_API void progressive_context_reset(PROGRESSIVE_CONTEXT* progressive); diff --git a/include/freerdp/input.h b/include/freerdp/input.h index 87324f0ab..0ee3ee188 100644 --- a/include/freerdp/input.h +++ b/include/freerdp/input.h @@ -64,6 +64,7 @@ typedef struct rdp_input_proxy rdpInputProxy; typedef void (*pSynchronizeEvent)(rdpInput* input, UINT32 flags); typedef void (*pKeyboardEvent)(rdpInput* input, UINT16 flags, UINT16 code); +typedef void (*pKeyboardPauseEvent)(rdpInput* input); typedef void (*pUnicodeKeyboardEvent)(rdpInput* input, UINT16 flags, UINT16 code); typedef void (*pMouseEvent)(rdpInput* input, UINT16 flags, UINT16 x, UINT16 y); typedef void (*pExtendedMouseEvent)(rdpInput* input, UINT16 flags, UINT16 x, UINT16 y); @@ -81,8 +82,9 @@ struct rdp_input pMouseEvent MouseEvent; /* 19 */ pExtendedMouseEvent ExtendedMouseEvent; /* 20 */ pFocusInEvent FocusInEvent; /*21 */ + pKeyboardPauseEvent KeyboardPauseEvent; /* 22 */ - UINT32 paddingB[32 - 22]; /* 22 */ + UINT32 paddingB[32 - 23]; /* 23 */ /* Internal */ @@ -98,6 +100,7 @@ extern "C" { FREERDP_API void freerdp_input_send_synchronize_event(rdpInput* input, UINT32 flags); FREERDP_API void freerdp_input_send_keyboard_event(rdpInput* input, UINT16 flags, UINT16 code); FREERDP_API void freerdp_input_send_keyboard_event_ex(rdpInput* input, BOOL down, UINT32 rdp_scancode); +FREERDP_API void freerdp_input_send_keyboard_pause_event(rdpInput* input); FREERDP_API void freerdp_input_send_unicode_keyboard_event(rdpInput* input, UINT16 flags, UINT16 code); FREERDP_API void freerdp_input_send_mouse_event(rdpInput* input, UINT16 flags, UINT16 x, UINT16 y); FREERDP_API void freerdp_input_send_extended_mouse_event(rdpInput* input, UINT16 flags, UINT16 x, UINT16 y); diff --git a/include/freerdp/peer.h b/include/freerdp/peer.h index 4fbe75bfc..1fba9906e 100644 --- a/include/freerdp/peer.h +++ b/include/freerdp/peer.h @@ -58,6 +58,7 @@ struct rdp_freerdp_peer rdpUpdate* update; rdpSettings* settings; + void* ContextExtra; size_t ContextSize; psPeerContextNew ContextNew; psPeerContextFree ContextFree; diff --git a/include/freerdp/primitives.h b/include/freerdp/primitives.h index bb518c2d6..d47300c01 100644 --- a/include/freerdp/primitives.h +++ b/include/freerdp/primitives.h @@ -136,6 +136,10 @@ typedef pstatus_t (*__sign_16s_t)( const INT16 *pSrc, INT16 *pDst, INT32 len); +typedef pstatus_t (*__yCbCrToRGB_16s8u_P3AC4R_t)( + const INT16* pSrc[3], INT32 srcStep, + BYTE* pDst, INT32 dstStep, + const prim_size_t* roi); typedef pstatus_t (*__yCbCrToRGB_16s16s_P3P3_t)( const INT16 *pSrc[3], INT32 srcStep, INT16 *pDst[3], INT32 dstStep, @@ -148,7 +152,7 @@ typedef pstatus_t (*__RGBToRGB_16s8u_P3AC4R_t)( const INT16 *pSrc[3], INT32 srcStep, BYTE *pDst, INT32 dstStep, const prim_size_t *roi); -typedef pstatus_t (*__YCoCgRToRGB_8u_AC4R_t)( +typedef pstatus_t (*__YCoCgToRGB_8u_AC4R_t)( const BYTE *pSrc, INT32 srcStep, BYTE *pDst, INT32 dstStep, UINT32 width, UINT32 height, @@ -160,6 +164,10 @@ typedef pstatus_t (*__RGB565ToARGB_16u32u_C3C4_t)( UINT32* pDst, INT32 dstStep, UINT32 width, UINT32 height, BOOL alpha, BOOL invert); +typedef pstatus_t (*__YUV420ToRGB_8u_P3AC4R_t)( + const BYTE* pSrc[3], INT32 srcStep[3], + BYTE* pDst, INT32 dstStep, + const prim_size_t* roi); typedef pstatus_t (*__andC_32u_t)( const UINT32 *pSrc, UINT32 val, @@ -199,11 +207,13 @@ typedef struct /* Sign */ __sign_16s_t sign_16s; /* Color conversions */ + __yCbCrToRGB_16s8u_P3AC4R_t yCbCrToRGB_16s8u_P3AC4R; __yCbCrToRGB_16s16s_P3P3_t yCbCrToRGB_16s16s_P3P3; __RGBToYCbCr_16s16s_P3P3_t RGBToYCbCr_16s16s_P3P3; __RGBToRGB_16s8u_P3AC4R_t RGBToRGB_16s8u_P3AC4R; - __YCoCgRToRGB_8u_AC4R_t YCoCgRToRGB_8u_AC4R; + __YCoCgToRGB_8u_AC4R_t YCoCgToRGB_8u_AC4R; __RGB565ToARGB_16u32u_C3C4_t RGB565ToARGB_16u32u_C3C4; + __YUV420ToRGB_8u_P3AC4R_t YUV420ToRGB_8u_P3AC4R; } primitives_t; #ifdef __cplusplus diff --git a/include/freerdp/rail.h b/include/freerdp/rail.h index d0520c244..ca9521e06 100644 --- a/include/freerdp/rail.h +++ b/include/freerdp/rail.h @@ -21,6 +21,8 @@ #ifndef FREERDP_RAIL_GLOBAL_H #define FREERDP_RAIL_GLOBAL_H +#include + #include /* RAIL PDU flags */ @@ -93,14 +95,6 @@ enum SPI_MASK /* Client Notify Event PDU */ #ifndef _WIN32 -#define WM_LBUTTONDOWN 0x00000201 -#define WM_LBUTTONUP 0x00000202 -#define WM_RBUTTONDOWN 0x00000204 -#define WM_RBUTTONUP 0x00000205 -#define WM_CONTEXTMENU 0x0000007B -#define WM_LBUTTONDBLCLK 0x00000203 -#define WM_RBUTTONDBLCLK 0x00000206 - #define NIN_SELECT 0x00000400 #define NIN_KEYSELECT 0x00000401 #define NIN_BALLOONSHOW 0x00000402 diff --git a/include/freerdp/server/encomsp.h b/include/freerdp/server/encomsp.h index f692073b8..dd1f9eba9 100644 --- a/include/freerdp/server/encomsp.h +++ b/include/freerdp/server/encomsp.h @@ -24,7 +24,7 @@ #include #include -#include +#include /** * Server Interface @@ -36,13 +36,38 @@ typedef struct _encomsp_server_private EncomspServerPrivate; typedef int (*psEncomspStart)(EncomspServerContext* context); typedef int (*psEncomspStop)(EncomspServerContext* context); +typedef int (*psEncomspFilterUpdated)(EncomspServerContext* context, ENCOMSP_FILTER_UPDATED_PDU* filterUpdated); +typedef int (*psEncomspApplicationCreated)(EncomspServerContext* context, ENCOMSP_APPLICATION_CREATED_PDU* applicationCreated); +typedef int (*psEncomspApplicationRemoved)(EncomspServerContext* context, ENCOMSP_APPLICATION_REMOVED_PDU* applicationRemoved); +typedef int (*psEncomspWindowCreated)(EncomspServerContext* context, ENCOMSP_WINDOW_CREATED_PDU* windowCreated); +typedef int (*psEncomspWindowRemoved)(EncomspServerContext* context, ENCOMSP_WINDOW_REMOVED_PDU* windowRemoved); +typedef int (*psEncomspShowWindow)(EncomspServerContext* context, ENCOMSP_SHOW_WINDOW_PDU* showWindow); +typedef int (*psEncomspParticipantCreated)(EncomspServerContext* context, ENCOMSP_PARTICIPANT_CREATED_PDU* participantCreated); +typedef int (*psEncomspParticipantRemoved)(EncomspServerContext* context, ENCOMSP_PARTICIPANT_REMOVED_PDU* participantRemoved); +typedef int (*psEncomspChangeParticipantControlLevel)(EncomspServerContext* context, ENCOMSP_CHANGE_PARTICIPANT_CONTROL_LEVEL_PDU* changeParticipantControlLevel); +typedef int (*psEncomspGraphicsStreamPaused)(EncomspServerContext* context, ENCOMSP_GRAPHICS_STREAM_PAUSED_PDU* graphicsStreamPaused); +typedef int (*psEncomspGraphicsStreamResumed)(EncomspServerContext* context, ENCOMSP_GRAPHICS_STREAM_RESUMED_PDU* graphicsStreamResumed); + struct _encomsp_server_context { HANDLE vcm; + void* custom; psEncomspStart Start; psEncomspStop Stop; + psEncomspFilterUpdated FilterUpdated; + psEncomspApplicationCreated ApplicationCreated; + psEncomspApplicationRemoved ApplicationRemoved; + psEncomspWindowCreated WindowCreated; + psEncomspWindowRemoved WindowRemoved; + psEncomspShowWindow ShowWindow; + psEncomspParticipantCreated ParticipantCreated; + psEncomspParticipantRemoved ParticipantRemoved; + psEncomspChangeParticipantControlLevel ChangeParticipantControlLevel; + psEncomspGraphicsStreamPaused GraphicsStreamPaused; + psEncomspGraphicsStreamResumed GraphicsStreamResumed; + EncomspServerPrivate* priv; }; diff --git a/include/freerdp/server/remdesk.h b/include/freerdp/server/remdesk.h index 75b1e0a93..b2c3f118c 100644 --- a/include/freerdp/server/remdesk.h +++ b/include/freerdp/server/remdesk.h @@ -39,6 +39,7 @@ typedef int (*psRemdeskStop)(RemdeskServerContext* context); struct _remdesk_server_context { HANDLE vcm; + void* custom; psRemdeskStart Start; psRemdeskStop Stop; diff --git a/include/freerdp/server/shadow.h b/include/freerdp/server/shadow.h new file mode 100644 index 000000000..0620cf626 --- /dev/null +++ b/include/freerdp/server/shadow.h @@ -0,0 +1,143 @@ +/** + * FreeRDP: A Remote Desktop Protocol Implementation + * Session Shadowing + * + * Copyright 2014 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef FREERDP_SERVER_SHADOW_H +#define FREERDP_SERVER_SHADOW_H + +#include +#include + +#include +#include + +#include +#include + +#include +#include + +#include +#include + +#include +#include +#include + +typedef struct rdp_shadow_client rdpShadowClient; +typedef struct rdp_shadow_server rdpShadowServer; +typedef struct rdp_shadow_screen rdpShadowScreen; +typedef struct rdp_shadow_surface rdpShadowSurface; +typedef struct rdp_shadow_encoder rdpShadowEncoder; +typedef struct rdp_shadow_capture rdpShadowCapture; +typedef struct rdp_shadow_subsystem rdpShadowSubsystem; + +typedef rdpShadowSubsystem* (*pfnShadowCreateSubsystem)(rdpShadowServer* server); + +typedef int (*pfnShadowSubsystemInit)(rdpShadowSubsystem* subsystem); +typedef int (*pfnShadowSubsystemUninit)(rdpShadowSubsystem* subsystem); +typedef int (*pfnShadowSubsystemStart)(rdpShadowSubsystem* subsystem); +typedef int (*pfnShadowSubsystemStop)(rdpShadowSubsystem* subsystem); +typedef void (*pfnShadowSubsystemFree)(rdpShadowSubsystem* subsystem); + +typedef int (*pfnShadowSurfaceCopy)(rdpShadowSubsystem* subsystem); +typedef int (*pfnShadowSurfaceUpdate)(rdpShadowSubsystem* subsystem, REGION16* region); + +typedef int (*pfnShadowSynchronizeEvent)(rdpShadowSubsystem* subsystem, UINT32 flags); +typedef int (*pfnShadowKeyboardEvent)(rdpShadowSubsystem* subsystem, UINT16 flags, UINT16 code); +typedef int (*pfnShadowUnicodeKeyboardEvent)(rdpShadowSubsystem* subsystem, UINT16 flags, UINT16 code); +typedef int (*pfnShadowMouseEvent)(rdpShadowSubsystem* subsystem, UINT16 flags, UINT16 x, UINT16 y); +typedef int (*pfnShadowExtendedMouseEvent)(rdpShadowSubsystem* subsystem, UINT16 flags, UINT16 x, UINT16 y); + +struct rdp_shadow_client +{ + rdpContext context; + + HANDLE thread; + BOOL activated; + BOOL inLobby; + BOOL mayView; + BOOL mayInteract; + HANDLE StopEvent; + CRITICAL_SECTION lock; + REGION16 invalidRegion; + rdpShadowServer* server; + rdpShadowSurface* lobby; + rdpShadowEncoder* encoder; + + HANDLE vcm; + EncomspServerContext* encomsp; + RemdeskServerContext* remdesk; +}; + +struct rdp_shadow_server +{ + void* ext; + HANDLE thread; + HANDLE StopEvent; + wArrayList* clients; + rdpShadowScreen* screen; + rdpShadowSurface* surface; + rdpShadowCapture* capture; + rdpShadowSubsystem* subsystem; + + DWORD port; + BOOL mayView; + BOOL mayInteract; + char* ipcSocket; + char* ConfigPath; + char* CertificateFile; + char* PrivateKeyFile; + CRITICAL_SECTION lock; + freerdp_listener* listener; + pfnShadowCreateSubsystem CreateSubsystem; +}; + +#define RDP_SHADOW_SUBSYSTEM_COMMON() \ + HANDLE event; \ + int monitorCount; \ + MONITOR_DEF monitors[16]; \ + MONITOR_DEF virtualScreen; \ + HANDLE updateEvent; \ + REGION16 invalidRegion; \ + SYNCHRONIZATION_BARRIER barrier; \ + \ + pfnShadowSubsystemInit Init; \ + pfnShadowSubsystemUninit Uninit; \ + pfnShadowSubsystemStart Start; \ + pfnShadowSubsystemStop Stop; \ + pfnShadowSubsystemFree Free; \ + \ + pfnShadowSurfaceCopy SurfaceCopy; \ + pfnShadowSurfaceUpdate SurfaceUpdate; \ + \ + pfnShadowSynchronizeEvent SynchronizeEvent; \ + pfnShadowKeyboardEvent KeyboardEvent; \ + pfnShadowUnicodeKeyboardEvent UnicodeKeyboardEvent; \ + pfnShadowMouseEvent MouseEvent; \ + pfnShadowExtendedMouseEvent ExtendedMouseEvent; \ + \ + rdpShadowServer* server + +struct rdp_shadow_subsystem +{ + RDP_SHADOW_SUBSYSTEM_COMMON(); +}; + +#endif /* FREERDP_SERVER_SHADOW_H */ + diff --git a/include/freerdp/settings.h b/include/freerdp/settings.h index ba05c81c0..f1002e1ce 100644 --- a/include/freerdp/settings.h +++ b/include/freerdp/settings.h @@ -536,6 +536,8 @@ typedef struct _RDPDR_PARALLEL RDPDR_PARALLEL; #define FreeRDP_ServerRandomLength 197 #define FreeRDP_ServerCertificate 198 #define FreeRDP_ServerCertificateLength 199 +#define FreeRDP_ClientRandom 200 +#define FreeRDP_ClientRandomLength 201 #define FreeRDP_ChannelCount 256 #define FreeRDP_ChannelDefArraySize 257 #define FreeRDP_ChannelDefArray 258 @@ -851,11 +853,12 @@ struct rdp_settings ALIGN64 UINT32 ExtEncryptionMethods; /* 194 */ ALIGN64 UINT32 EncryptionLevel; /* 195 */ ALIGN64 BYTE* ServerRandom; /* 196 */ - ALIGN64 DWORD ServerRandomLength; /* 197 */ + ALIGN64 UINT32 ServerRandomLength; /* 197 */ ALIGN64 BYTE* ServerCertificate; /* 198 */ - ALIGN64 DWORD ServerCertificateLength; /* 199 */ + ALIGN64 UINT32 ServerCertificateLength; /* 199 */ ALIGN64 BYTE* ClientRandom; /* 200 */ - UINT64 padding0256[256 - 201]; /* 201 */ + ALIGN64 UINT32 ClientRandomLength; /* 201 */ + UINT64 padding0256[256 - 202]; /* 202 */ /* Client Network Data */ ALIGN64 UINT32 ChannelCount; /* 256 */ @@ -1014,7 +1017,7 @@ struct rdp_settings /* Credentials Cache */ ALIGN64 BYTE* Password51; /* 1280 */ - ALIGN64 DWORD Password51Length; /* 1281 */ + ALIGN64 UINT32 Password51Length; /* 1281 */ UINT64 padding1344[1344 - 1282]; /* 1282 */ /* Kerberos Authentication */ @@ -1120,8 +1123,8 @@ struct rdp_settings ALIGN64 char* RemoteApplicationFile; /* 2116 */ ALIGN64 char* RemoteApplicationGuid; /* 2117 */ ALIGN64 char* RemoteApplicationCmdLine; /* 2118 */ - ALIGN64 DWORD RemoteApplicationExpandCmdLine; /* 2119 */ - ALIGN64 DWORD RemoteApplicationExpandWorkingDir; /* 2120 */ + ALIGN64 UINT32 RemoteApplicationExpandCmdLine; /* 2119 */ + ALIGN64 UINT32 RemoteApplicationExpandWorkingDir; /* 2120 */ ALIGN64 BOOL DisableRemoteAppCapsCheck; /* 2121 */ ALIGN64 UINT32 RemoteAppNumIconCaches; /* 2122 */ ALIGN64 UINT32 RemoteAppNumIconCacheEntries; /* 2123 */ @@ -1356,7 +1359,8 @@ struct rdp_settings ALIGN64 UINT32 DynamicChannelCount; /* 5056 */ ALIGN64 UINT32 DynamicChannelArraySize; /* 5057 */ ALIGN64 ADDIN_ARGV** DynamicChannelArray; /* 5058 */ - UINT64 padding5184[5184 - 5059]; /* 5059 */ + ALIGN64 BOOL SupportDynamicChannels; /* 5059 */ + UINT64 padding5184[5184 - 5060]; /* 5060 */ /** * WARNING: End of ABI stable zone! diff --git a/include/freerdp/utils/debug.h b/include/freerdp/utils/debug.h index ba79ed6d1..dde132dd4 100644 --- a/include/freerdp/utils/debug.h +++ b/include/freerdp/utils/debug.h @@ -20,41 +20,28 @@ #ifndef FREERDP_UTILS_DEBUG_H #define FREERDP_UTILS_DEBUG_H +#include + +#define DEBUG_PRINT(level, file, fkt, line, dbg_str, fmt, ...) \ + do { \ + wLog *log = WLog_Get("com.freerdp." dbg_str); \ + wLogMessage msg; \ + \ + msg.Type = WLOG_MESSAGE_TEXT; \ + msg.Level = level; \ + msg.FormatString = fmt; \ + msg.LineNumber = line; \ + msg.FileName = file; \ + msg.FunctionName = fkt; \ + WLog_PrintMessage(log, &msg, ##__VA_ARGS__); \ + } while (0 ) + #define DEBUG_NULL(fmt, ...) do { } while (0) - -/* When building for android redirect all debug messages - * to logcat. */ -#if defined(ANDROID) -#include - -#define APP_NAME "freerdp-debug" - -#define ANDROID_DEBUG_PRINT(_dbg_str, fmt, ...) do { \ - __android_log_print(_dbg_str, fmt, ##__VA_ARGS__); \ - } while( 0 ) - -#define DEBUG_CLASS(_dbg_class, fmt, ...) \ - ANDROID_DEBUG_PRINT(ANDROID_LOG_DEBUG, APP_NAME, \ - "DBG_" #_dbg_class " %s (%s:%d): " \ - fmt, __FUNCTION__, __FILE__, __LINE__, ## __VA_ARGS__) - -#define DEBUG_WARN(fmt, ...) \ - ANDROID_DEBUG_PRINT(ANDROID_LOG_WARN, APP_NAME, "Warning %s (%s:%d): " \ - fmt, __FUNCTION__, __FILE__, __LINE__, ## __VA_ARGS__) - -#else -/* By default all log messages are written to stdout */ -#include - -#define DEBUG_PRINT(_dbg_str, fmt, ...) do { \ - fprintf(stderr, _dbg_str, __FUNCTION__, __FILE__, __LINE__); \ - fprintf(stderr, fmt, ## __VA_ARGS__); \ - fprintf(stderr, "\n"); \ - } while( 0 ) - - -#define DEBUG_CLASS(_dbg_class, fmt, ...) DEBUG_PRINT("DBG_" #_dbg_class " %s (%s:%d): ", fmt, ## __VA_ARGS__) -#define DEBUG_WARN(fmt, ...) DEBUG_PRINT("Warning %s (%s:%d): ", fmt, ## __VA_ARGS__) -#endif +#define DEBUG_CLASS(_dbg_class, fmt, ...) DEBUG_PRINT(WLOG_ERROR, __FILE__, \ + __FUNCTION__, __LINE__, #_dbg_class, fmt, ## __VA_ARGS__) +#define DEBUG_MSG(fmt, ...) DEBUG_PRINT(WLOG_DEBUG, __FILE__, __FUNCTION__, \ + __LINE__, "freerdp", fmt, ## __VA_ARGS__) +#define DEBUG_WARN(fmt, ...) DEBUG_PRINT(WLOG_ERROR, __FILE__, __FUNCTION__, \ + __LINE__, "freerdp", fmt, ## __VA_ARGS__) #endif /* FREERDP_UTILS_DEBUG_H */ diff --git a/libfreerdp/cache/bitmap.c b/libfreerdp/cache/bitmap.c index ec78af491..480ead2f6 100644 --- a/libfreerdp/cache/bitmap.c +++ b/libfreerdp/cache/bitmap.c @@ -29,6 +29,7 @@ #include #include +#include #include void update_gdi_memblt(rdpContext* context, MEMBLT_ORDER* memblt) @@ -222,7 +223,7 @@ rdpBitmap* bitmap_cache_get(rdpBitmapCache* bitmapCache, UINT32 id, UINT32 index if (id > bitmapCache->maxCells) { - fprintf(stderr, "get invalid bitmap cell id: %d\n", id); + DEBUG_WARN( "get invalid bitmap cell id: %d\n", id); return NULL; } @@ -232,7 +233,7 @@ rdpBitmap* bitmap_cache_get(rdpBitmapCache* bitmapCache, UINT32 id, UINT32 index } else if (index > bitmapCache->cells[id].number) { - fprintf(stderr, "get invalid bitmap index %d in cell id: %d\n", index, id); + DEBUG_WARN( "get invalid bitmap index %d in cell id: %d\n", index, id); return NULL; } @@ -245,7 +246,7 @@ void bitmap_cache_put(rdpBitmapCache* bitmapCache, UINT32 id, UINT32 index, rdpB { if (id > bitmapCache->maxCells) { - fprintf(stderr, "put invalid bitmap cell id: %d\n", id); + DEBUG_WARN( "put invalid bitmap cell id: %d\n", id); return; } @@ -255,7 +256,7 @@ void bitmap_cache_put(rdpBitmapCache* bitmapCache, UINT32 id, UINT32 index, rdpB } else if (index > bitmapCache->cells[id].number) { - fprintf(stderr, "put invalid bitmap index %d in cell id: %d\n", index, id); + DEBUG_WARN( "put invalid bitmap index %d in cell id: %d\n", index, id); return; } diff --git a/libfreerdp/cache/brush.c b/libfreerdp/cache/brush.c index 6c3fa81d0..13342cecf 100644 --- a/libfreerdp/cache/brush.c +++ b/libfreerdp/cache/brush.c @@ -28,6 +28,7 @@ #include #include +#include #include void update_gdi_patblt(rdpContext* context, PATBLT_ORDER* patblt) @@ -100,7 +101,7 @@ void* brush_cache_get(rdpBrushCache* brushCache, UINT32 index, UINT32* bpp) { if (index >= brushCache->maxMonoEntries) { - fprintf(stderr, "invalid brush (%d bpp) index: 0x%04X\n", *bpp, index); + DEBUG_WARN( "invalid brush (%d bpp) index: 0x%04X\n", *bpp, index); return NULL; } @@ -111,7 +112,7 @@ void* brush_cache_get(rdpBrushCache* brushCache, UINT32 index, UINT32* bpp) { if (index >= brushCache->maxEntries) { - fprintf(stderr, "invalid brush (%d bpp) index: 0x%04X\n", *bpp, index); + DEBUG_WARN( "invalid brush (%d bpp) index: 0x%04X\n", *bpp, index); return NULL; } @@ -121,7 +122,7 @@ void* brush_cache_get(rdpBrushCache* brushCache, UINT32 index, UINT32* bpp) if (entry == NULL) { - fprintf(stderr, "invalid brush (%d bpp) at index: 0x%04X\n", *bpp, index); + DEBUG_WARN( "invalid brush (%d bpp) at index: 0x%04X\n", *bpp, index); return NULL; } @@ -136,7 +137,7 @@ void brush_cache_put(rdpBrushCache* brushCache, UINT32 index, void* entry, UINT3 { if (index >= brushCache->maxMonoEntries) { - fprintf(stderr, "invalid brush (%d bpp) index: 0x%04X\n", bpp, index); + DEBUG_WARN( "invalid brush (%d bpp) index: 0x%04X\n", bpp, index); if (entry) free(entry); @@ -156,7 +157,7 @@ void brush_cache_put(rdpBrushCache* brushCache, UINT32 index, void* entry, UINT3 { if (index >= brushCache->maxEntries) { - fprintf(stderr, "invalid brush (%d bpp) index: 0x%04X\n", bpp, index); + DEBUG_WARN( "invalid brush (%d bpp) index: 0x%04X\n", bpp, index); if (entry) free(entry); diff --git a/libfreerdp/cache/glyph.c b/libfreerdp/cache/glyph.c index ac4303228..8bbd0b017 100644 --- a/libfreerdp/cache/glyph.c +++ b/libfreerdp/cache/glyph.c @@ -28,6 +28,7 @@ #include #include +#include #include void update_process_glyph(rdpContext* context, BYTE* data, int* index, @@ -367,20 +368,20 @@ rdpGlyph* glyph_cache_get(rdpGlyphCache* glyphCache, UINT32 id, UINT32 index) if (id > 9) { - fprintf(stderr, "invalid glyph cache id: %d\n", id); + DEBUG_WARN( "invalid glyph cache id: %d\n", id); return NULL; } if (index > glyphCache->glyphCache[id].number) { - fprintf(stderr, "index %d out of range for cache id: %d\n", index, id); + DEBUG_WARN( "index %d out of range for cache id: %d\n", index, id); return NULL; } glyph = glyphCache->glyphCache[id].entries[index]; if (!glyph) - fprintf(stderr, "no glyph found at cache index: %d in cache id: %d\n", index, id); + DEBUG_WARN( "no glyph found at cache index: %d in cache id: %d\n", index, id); return glyph; } @@ -391,13 +392,13 @@ void glyph_cache_put(rdpGlyphCache* glyphCache, UINT32 id, UINT32 index, rdpGlyp if (id > 9) { - fprintf(stderr, "invalid glyph cache id: %d\n", id); + DEBUG_WARN( "invalid glyph cache id: %d\n", id); return; } if (index > glyphCache->glyphCache[id].number) { - fprintf(stderr, "invalid glyph cache index: %d in cache id: %d\n", index, id); + DEBUG_WARN( "invalid glyph cache index: %d in cache id: %d\n", index, id); return; } @@ -423,7 +424,7 @@ void* glyph_cache_fragment_get(rdpGlyphCache* glyphCache, UINT32 index, UINT32* if (index > 255) { - fprintf(stderr, "invalid glyph cache fragment index: %d\n", index); + DEBUG_WARN( "invalid glyph cache fragment index: %d\n", index); return NULL; } @@ -433,7 +434,7 @@ void* glyph_cache_fragment_get(rdpGlyphCache* glyphCache, UINT32 index, UINT32* WLog_Print(glyphCache->log, WLOG_DEBUG, "GlyphCacheFragmentGet: index: %d size: %d", index, *size); if (!fragment) - fprintf(stderr, "invalid glyph fragment at index:%d\n", index); + DEBUG_WARN( "invalid glyph fragment at index:%d\n", index); return fragment; } @@ -444,7 +445,7 @@ void glyph_cache_fragment_put(rdpGlyphCache* glyphCache, UINT32 index, UINT32 si if (index > 255) { - fprintf(stderr, "invalid glyph cache fragment index: %d\n", index); + DEBUG_WARN( "invalid glyph cache fragment index: %d\n", index); return; } diff --git a/libfreerdp/cache/nine_grid.c b/libfreerdp/cache/nine_grid.c index 47245c8a8..ed2502f7a 100644 --- a/libfreerdp/cache/nine_grid.c +++ b/libfreerdp/cache/nine_grid.c @@ -29,6 +29,7 @@ #include #include +#include #include void update_gdi_draw_nine_grid(rdpContext* context, DRAW_NINE_GRID_ORDER* draw_nine_grid) @@ -60,7 +61,7 @@ void* nine_grid_cache_get(rdpNineGridCache* nine_grid, UINT32 index) if (index >= nine_grid->maxEntries) { - fprintf(stderr, "invalid NineGrid index: 0x%04X\n", index); + DEBUG_WARN( "invalid NineGrid index: 0x%04X\n", index); return NULL; } @@ -68,7 +69,7 @@ void* nine_grid_cache_get(rdpNineGridCache* nine_grid, UINT32 index) if (entry == NULL) { - fprintf(stderr, "invalid NineGrid at index: 0x%04X\n", index); + DEBUG_WARN( "invalid NineGrid at index: 0x%04X\n", index); return NULL; } @@ -81,7 +82,7 @@ void nine_grid_cache_put(rdpNineGridCache* nine_grid, UINT32 index, void* entry) if (index >= nine_grid->maxEntries) { - fprintf(stderr, "invalid NineGrid index: 0x%04X\n", index); + DEBUG_WARN( "invalid NineGrid index: 0x%04X\n", index); return; } diff --git a/libfreerdp/cache/offscreen.c b/libfreerdp/cache/offscreen.c index c735f96d3..3a2b18bb4 100644 --- a/libfreerdp/cache/offscreen.c +++ b/libfreerdp/cache/offscreen.c @@ -27,6 +27,7 @@ #include +#include #include void update_gdi_create_offscreen_bitmap(rdpContext* context, CREATE_OFFSCREEN_BITMAP_ORDER* createOffscreenBitmap) @@ -80,7 +81,7 @@ rdpBitmap* offscreen_cache_get(rdpOffscreenCache* offscreenCache, UINT32 index) if (index >= offscreenCache->maxEntries) { - fprintf(stderr, "invalid offscreen bitmap index: 0x%04X\n", index); + DEBUG_WARN( "invalid offscreen bitmap index: 0x%04X\n", index); return NULL; } @@ -88,7 +89,7 @@ rdpBitmap* offscreen_cache_get(rdpOffscreenCache* offscreenCache, UINT32 index) if (!bitmap) { - fprintf(stderr, "invalid offscreen bitmap at index: 0x%04X\n", index); + DEBUG_WARN( "invalid offscreen bitmap at index: 0x%04X\n", index); return NULL; } @@ -99,7 +100,7 @@ void offscreen_cache_put(rdpOffscreenCache* offscreenCache, UINT32 index, rdpBit { if (index >= offscreenCache->maxEntries) { - fprintf(stderr, "invalid offscreen bitmap index: 0x%04X\n", index); + DEBUG_WARN( "invalid offscreen bitmap index: 0x%04X\n", index); return; } @@ -113,7 +114,7 @@ void offscreen_cache_delete(rdpOffscreenCache* offscreenCache, UINT32 index) if (index >= offscreenCache->maxEntries) { - fprintf(stderr, "invalid offscreen bitmap index (delete): 0x%04X\n", index); + DEBUG_WARN( "invalid offscreen bitmap index (delete): 0x%04X\n", index); return; } diff --git a/libfreerdp/cache/palette.c b/libfreerdp/cache/palette.c index 3436a686d..e472aee1e 100644 --- a/libfreerdp/cache/palette.c +++ b/libfreerdp/cache/palette.c @@ -25,6 +25,7 @@ #include +#include #include static void update_gdi_cache_color_table(rdpContext* context, CACHE_COLOR_TABLE_ORDER* cacheColorTable) @@ -44,7 +45,7 @@ void* palette_cache_get(rdpPaletteCache* paletteCache, UINT32 index) if (index >= paletteCache->maxEntries) { - fprintf(stderr, "invalid color table index: 0x%04X\n", index); + DEBUG_WARN( "invalid color table index: 0x%04X\n", index); return NULL; } @@ -52,7 +53,7 @@ void* palette_cache_get(rdpPaletteCache* paletteCache, UINT32 index) if (!entry) { - fprintf(stderr, "invalid color table at index: 0x%04X\n", index); + DEBUG_WARN( "invalid color table at index: 0x%04X\n", index); return NULL; } @@ -63,7 +64,7 @@ void palette_cache_put(rdpPaletteCache* paletteCache, UINT32 index, void* entry) { if (index >= paletteCache->maxEntries) { - fprintf(stderr, "invalid color table index: 0x%04X\n", index); + DEBUG_WARN( "invalid color table index: 0x%04X\n", index); if (entry) free(entry); diff --git a/libfreerdp/cache/pointer.c b/libfreerdp/cache/pointer.c index 57bc3a4ef..227322d25 100644 --- a/libfreerdp/cache/pointer.c +++ b/libfreerdp/cache/pointer.c @@ -28,6 +28,7 @@ #include #include +#include void update_pointer_position(rdpContext* context, POINTER_POSITION_UPDATE* pointer_position) { @@ -47,7 +48,7 @@ void update_pointer_system(rdpContext* context, POINTER_SYSTEM_UPDATE* pointer_s break; default: - fprintf(stderr, "Unknown system pointer type (0x%08X)\n", pointer_system->type); + DEBUG_WARN( "Unknown system pointer type (0x%08X)\n", pointer_system->type); break; } } @@ -140,7 +141,7 @@ rdpPointer* pointer_cache_get(rdpPointerCache* pointer_cache, UINT32 index) if (index >= pointer_cache->cacheSize) { - fprintf(stderr, "invalid pointer index:%d\n", index); + DEBUG_WARN( "invalid pointer index:%d\n", index); return NULL; } @@ -155,7 +156,7 @@ void pointer_cache_put(rdpPointerCache* pointer_cache, UINT32 index, rdpPointer* if (index >= pointer_cache->cacheSize) { - fprintf(stderr, "invalid pointer index:%d\n", index); + DEBUG_WARN( "invalid pointer index:%d\n", index); return; } diff --git a/libfreerdp/codec/audio.c b/libfreerdp/codec/audio.c index 751885e78..06f96ae0d 100644 --- a/libfreerdp/codec/audio.c +++ b/libfreerdp/codec/audio.c @@ -23,6 +23,7 @@ #include +#include #include UINT32 rdpsnd_compute_audio_time_length(AUDIO_FORMAT* format, int size) @@ -57,12 +58,12 @@ UINT32 rdpsnd_compute_audio_time_length(AUDIO_FORMAT* format, int size) } else { - fprintf(stderr, "rdpsnd_compute_audio_time_length: invalid WAVE_FORMAT_GSM610 format\n"); + DEBUG_WARN( "rdpsnd_compute_audio_time_length: invalid WAVE_FORMAT_GSM610 format\n"); } } else { - fprintf(stderr, "rdpsnd_compute_audio_time_length: unknown format %d\n", format->wFormatTag); + DEBUG_WARN( "rdpsnd_compute_audio_time_length: unknown format %d\n", format->wFormatTag); } } @@ -109,7 +110,7 @@ char* rdpsnd_get_audio_tag_string(UINT16 wFormatTag) void rdpsnd_print_audio_format(AUDIO_FORMAT* format) { - fprintf(stderr, "%s:\t wFormatTag: 0x%04X nChannels: %d nSamplesPerSec: %d nAvgBytesPerSec: %d " + DEBUG_WARN( "%s:\t wFormatTag: 0x%04X nChannels: %d nSamplesPerSec: %d nAvgBytesPerSec: %d " "nBlockAlign: %d wBitsPerSample: %d cbSize: %d\n", rdpsnd_get_audio_tag_string(format->wFormatTag), format->wFormatTag, format->nChannels, format->nSamplesPerSec, format->nAvgBytesPerSec, @@ -123,17 +124,17 @@ void rdpsnd_print_audio_formats(AUDIO_FORMAT* formats, UINT16 count) if (formats) { - fprintf(stderr, "AUDIO_FORMATS (%d) =\n{\n", count); + DEBUG_WARN( "AUDIO_FORMATS (%d) =\n{\n", count); for (index = 0; index < (int) count; index++) { format = &formats[index]; - fprintf(stderr, "\t"); + DEBUG_WARN( "\t"); rdpsnd_print_audio_format(format); } - fprintf(stderr, "}\n"); + DEBUG_WARN( "}\n"); } } diff --git a/libfreerdp/codec/clear.c b/libfreerdp/codec/clear.c index ed7ada5d7..35b6c04a5 100644 --- a/libfreerdp/codec/clear.c +++ b/libfreerdp/codec/clear.c @@ -135,14 +135,14 @@ int clear_decompress(CLEAR_CONTEXT* clear, BYTE* pSrcData, UINT32 SrcSize, if (!glyphData) return -1010; - if ((nWidth * nHeight) > glyphEntry->count) + if ((nWidth * nHeight) > (int) glyphEntry->count) return -1011; nSrcStep = nWidth * 4; pSrcPixel8 = glyphData; pDstPixel8 = &pDstData[(nYDst * nDstStep) + (nXDst * 4)]; - for (y = 0; y < nHeight; y++) + for (y = 0; y < (UINT32) nHeight; y++) { CopyMemory(pDstPixel8, pSrcPixel8, nSrcStep); pSrcPixel8 += nSrcStep; @@ -163,7 +163,7 @@ int clear_decompress(CLEAR_CONTEXT* clear, BYTE* pSrcData, UINT32 SrcSize, subcodecByteCount = *((UINT32*) &pSrcData[offset + 8]); offset += 12; - //printf("residualByteCount: %d bandsByteCount: %d subcodecByteCount: %d\n", + //DEBUG_MSG("residualByteCount: %d bandsByteCount: %d subcodecByteCount: %d\n", // residualByteCount, bandsByteCount, subcodecByteCount); if (residualByteCount > 0) @@ -177,7 +177,7 @@ int clear_decompress(CLEAR_CONTEXT* clear, BYTE* pSrcData, UINT32 SrcSize, suboffset = 0; residualData = &pSrcData[offset]; - if ((nWidth * nHeight * 4) > clear->TempSize) + if ((nWidth * nHeight * 4) > (int) clear->TempSize) { clear->TempSize = (nWidth * nHeight * 4); clear->TempBuffer = (BYTE*) realloc(clear->TempBuffer, clear->TempSize); @@ -238,7 +238,7 @@ int clear_decompress(CLEAR_CONTEXT* clear, BYTE* pSrcData, UINT32 SrcSize, if (pixelIndex != pixelCount) return -1019; - for (y = 0; y < nHeight; y++) + for (y = 0; y < (UINT32) nHeight; y++) { CopyMemory(pDstPixel8, pSrcPixel8, nSrcStep); pSrcPixel8 += nSrcStep; @@ -528,7 +528,7 @@ int clear_decompress(CLEAR_CONTEXT* clear, BYTE* pSrcData, UINT32 SrcSize, subcodecId = subcodecs[suboffset + 12]; suboffset += 13; - //printf("bitmapDataByteCount: %d subcodecByteCount: %d suboffset: %d subCodecId: %d\n", + //DEBUG_MSG("bitmapDataByteCount: %d subcodecByteCount: %d suboffset: %d subCodecId: %d\n", // bitmapDataByteCount, subcodecByteCount, suboffset, subcodecId); if ((subcodecByteCount - suboffset) < bitmapDataByteCount) @@ -543,7 +543,7 @@ int clear_decompress(CLEAR_CONTEXT* clear, BYTE* pSrcData, UINT32 SrcSize, if (height > nHeight) return -1043; - if ((width * height * 4) > clear->TempSize) + if (((UINT32) (width * height * 4)) > clear->TempSize) { clear->TempSize = (width * height * 4); clear->TempBuffer = (BYTE*) realloc(clear->TempBuffer, clear->TempSize); @@ -732,7 +732,7 @@ int clear_decompress(CLEAR_CONTEXT* clear, BYTE* pSrcData, UINT32 SrcSize, pDstPixel8 = glyphData; pSrcPixel8 = &pDstData[(nYDst * nDstStep) + (nXDst * 4)]; - for (y = 0; y < nHeight; y++) + for (y = 0; y < (UINT32) nHeight; y++) { CopyMemory(pDstPixel8, pSrcPixel8, nSrcStep); pDstPixel8 += nSrcStep; diff --git a/libfreerdp/codec/color.c b/libfreerdp/codec/color.c index 8b2578a8b..2c1c8c2d8 100644 --- a/libfreerdp/codec/color.c +++ b/libfreerdp/codec/color.c @@ -379,6 +379,43 @@ UINT32 freerdp_color_convert_var_bgr(UINT32 srcColor, int srcBpp, int dstBpp, HC return freerdp_color_convert_rgb_bgr(srcColor, srcBpp, dstBpp, clrconv); } +UINT32 freerdp_color_convert_drawing_order_color_to_gdi_color(UINT32 color, int bpp, HCLRCONV clrconv) +{ + UINT32 r, g, b; + + switch (bpp) + { + case 16: + color = (color & (UINT32) 0xFF00) | ((color >> 16) & (UINT32) 0xFF); + GetRGB16(r, g, b, color); + break; + + case 15: + color = (color & (UINT32) 0xFF00) | ((color >> 16) & (UINT32) 0xFF); + GetRGB15(r, g, b, color); + break; + + case 8: + color = (color >> 16) & (UINT32) 0xFF; + r = clrconv->palette->entries[color].red; + g = clrconv->palette->entries[color].green; + b = clrconv->palette->entries[color].blue; + break; + + case 1: + r = g = b = 0; + if (color != 0) + r = g = b = 0xFF; + break; + + default: + return color; + break; + } + + return RGB32(r, g, b); +} + BYTE* freerdp_image_convert_8bpp(BYTE* srcData, BYTE* dstData, int width, int height, int srcBpp, int dstBpp, HCLRCONV clrconv) { int i; @@ -470,11 +507,11 @@ BYTE* freerdp_image_convert_8bpp(BYTE* srcData, BYTE* dstData, int width, int he blue = clrconv->palette->entries[pixel].blue; if (clrconv->alpha) { - pixel = (clrconv->invert) ? ARGB32(0xFF, red, green, blue) : ABGR32(0xFF, red, green, blue); + pixel = (clrconv->invert) ? ABGR32(0xFF, red, green, blue) : ARGB32(0xFF, red, green, blue); } else { - pixel = (clrconv->invert) ? RGB32(red, green, blue) : BGR32(red, green, blue); + pixel = (clrconv->invert) ? BGR32(red, green, blue) : RGB32(red, green, blue); } *dst32 = pixel; dst32++; @@ -668,7 +705,9 @@ BYTE* freerdp_image_convert_24bpp(BYTE* srcData, BYTE* dstData, int width, int h if (dstBpp == 32) { - BYTE* dstp; + UINT32 pixel, alpha_mask, temp; + UINT32* srcp; + UINT32* dstp; if (!dstData) dstData = (BYTE*) _aligned_malloc(width * height * 4, 16); @@ -676,14 +715,81 @@ BYTE* freerdp_image_convert_24bpp(BYTE* srcData, BYTE* dstData, int width, int h if (!dstData) return NULL; - dstp = dstData; + alpha_mask = clrconv->alpha ? 0xFF000000 : 0; - for (i = width * height; i > 0; i--) + srcp = (UINT32*) srcData; + dstp = (UINT32*) dstData; + + if (clrconv->invert) { - *(dstp++) = *(srcData++); - *(dstp++) = *(srcData++); - *(dstp++) = *(srcData++); - *(dstp++) = 0xFF; + /* Each iteration handles four pixels using 32-bit load and + store operations. */ + for (i = ((width * height) / 4); i > 0; i--) + { + temp = 0; + + pixel = temp; + temp = *srcp++; + pixel |= temp & 0x00FFFFFF; + temp = temp >> 24; + *dstp++ = alpha_mask | RGB32_to_BGR32(pixel); + + pixel = temp; + temp = *srcp++; + pixel |= (temp & 0x0000FFFF) << 8; + temp = temp >> 16; + *dstp++ = alpha_mask | RGB32_to_BGR32(pixel); + + pixel = temp; + temp = *srcp++; + pixel |= (temp & 0x000000FF) << 16; + temp = temp >> 8; + *dstp++ = alpha_mask | RGB32_to_BGR32(pixel); + + *dstp++ = alpha_mask | RGB32_to_BGR32(temp); + } + + /* Handle any remainder. */ + for (i = (width * height) % 4; i > 0; i--) + { + pixel = ABGR32(alpha_mask, srcData[2], srcData[1], srcData[0]); + *dstp++ = pixel; + srcData += 3; + } + } + else + { + for (i = ((width * height) / 4); i > 0; i--) + { + temp = 0; + + pixel = temp; + temp = *srcp++; + pixel |= temp & 0x00FFFFFF; + temp = temp >> 24; + *dstp++ = alpha_mask | pixel; + + pixel = temp; + temp = *srcp++; + pixel |= (temp & 0x0000FFFF) << 8; + temp = temp >> 16; + *dstp++ = alpha_mask | pixel; + + pixel = temp; + temp = *srcp++; + pixel |= (temp & 0x000000FF) << 16; + temp = temp >> 8; + *dstp++ = alpha_mask | pixel; + + *dstp++ = alpha_mask | temp; + } + + for (i = (width * height) % 4; i > 0; i--) + { + pixel = ARGB32(alpha_mask, srcData[2], srcData[1], srcData[0]); + *dstp++ = pixel; + srcData += 3; + } } return dstData; @@ -760,33 +866,47 @@ BYTE* freerdp_image_convert_32bpp(BYTE* srcData, BYTE* dstData, int width, int h } else if (dstBpp == 32) { + int i; + UINT32 pixel; + UINT32 alpha_mask; + UINT32* srcp; + UINT32* dstp; + BYTE red, green, blue; + if (!dstData) dstData = (BYTE*) _aligned_malloc(width * height * 4, 16); if (!dstData) return NULL; - if (clrconv->alpha) + alpha_mask = clrconv->alpha ? 0xFF000000 : 0; + + srcp = (UINT32*) srcData; + dstp = (UINT32*) dstData; + + if (clrconv->invert) { - int x, y; - BYTE* dstp; - - CopyMemory(dstData, srcData, width * height * 4); - - dstp = dstData; - for (y = 0; y < height; y++) + for (i = width * height; i > 0; i--) { - for (x = 0; x < width * 4; x += 4) - { - dstp += 3; - *dstp = 0xFF; - dstp++; - } + pixel = *srcp; + srcp++; + GetRGB32(red, green, blue, pixel); + pixel = alpha_mask | BGR32(red, green, blue); + *dstp = pixel; + dstp++; } } else { - CopyMemory(dstData, srcData, width * height * 4); + for (i = width * height; i > 0; i--) + { + pixel = *srcp; + srcp++; + GetRGB32(red, green, blue, pixel); + pixel = alpha_mask | RGB32(red, green, blue); + *dstp = pixel; + dstp++; + } } return dstData; @@ -995,58 +1115,12 @@ BYTE* freerdp_mono_image_convert(BYTE* srcData, int width, int height, int srcBp int bitIndex; BYTE redBg, greenBg, blueBg; BYTE redFg, greenFg, blueFg; - - switch (srcBpp) - { - case 8: - bgcolor &= 0xFF; - redBg = clrconv->palette->entries[bgcolor].red; - greenBg = clrconv->palette->entries[bgcolor].green; - blueBg = clrconv->palette->entries[bgcolor].blue; - - fgcolor &= 0xFF; - redFg = clrconv->palette->entries[fgcolor].red; - greenFg = clrconv->palette->entries[fgcolor].green; - blueFg = clrconv->palette->entries[fgcolor].blue; - break; - - case 16: - GetRGB16(redBg, greenBg, blueBg, bgcolor); - GetRGB16(redFg, greenFg, blueFg, fgcolor); - break; - - case 15: - GetRGB15(redBg, greenBg, blueBg, bgcolor); - GetRGB15(redFg, greenFg, blueFg, fgcolor); - break; - - default: - GetRGB32(redBg, greenBg, blueBg, bgcolor); - GetRGB32(redFg, greenFg, blueFg, fgcolor); - break; - } + + GetRGB32(redBg, greenBg, blueBg, bgcolor); + GetRGB32(redFg, greenFg, blueFg, fgcolor); if (dstBpp == 16) { - if (clrconv->rgb555) - { - if (srcBpp == 16) - { - /* convert 15-bit colors to 16-bit colors */ - RGB16_RGB15(redBg, greenBg, blueBg, bgcolor); - RGB16_RGB15(redFg, greenFg, blueFg, fgcolor); - } - } - else - { - if (srcBpp == 15) - { - /* convert 15-bit colors to 16-bit colors */ - RGB15_RGB16(redBg, greenBg, blueBg, bgcolor); - RGB15_RGB16(redFg, greenFg, blueFg, fgcolor); - } - } - dstData = (BYTE*) _aligned_malloc(width * height * 2, 16); if (!dstData) @@ -1054,6 +1128,17 @@ BYTE* freerdp_mono_image_convert(BYTE* srcData, int width, int height, int srcBp dst16 = (UINT16*) dstData; + if (clrconv->rgb555) + { + bgcolor = clrconv->invert ? BGR15(redBg, greenBg, blueBg) : RGB15(redBg, greenBg, blueBg); + fgcolor = clrconv->invert ? BGR15(redFg, greenFg, blueFg) : RGB15(redFg, greenFg, blueFg); + } + else + { + bgcolor = clrconv->invert ? BGR16(redBg, greenBg, blueBg) : RGB16(redBg, greenBg, blueBg); + fgcolor = clrconv->invert ? BGR16(redFg, greenFg, blueFg) : RGB16(redFg, greenFg, blueFg); + } + for (index = height; index > 0; index--) { /* each bit encodes a pixel */ @@ -1092,11 +1177,25 @@ BYTE* freerdp_mono_image_convert(BYTE* srcData, int width, int height, int srcBp { if ((bitMask >> bitIndex) & 0x01) { - *dst32 = (clrconv->invert) ? BGR32(redBg, greenBg, blueBg) : RGB32(redBg, greenBg, blueBg); + if (clrconv->alpha) + { + *dst32 = (clrconv->invert) ? ABGR32(0xFF, redBg, greenBg, blueBg) : ARGB32(0xFF, redBg, greenBg, blueBg); + } + else + { + *dst32 = (clrconv->invert) ? BGR32(redBg, greenBg, blueBg) : RGB32(redBg, greenBg, blueBg); + } } else { - *dst32 = (clrconv->invert) ? BGR32(redFg, greenFg, blueFg) : RGB32(redFg, greenFg, blueFg); + if (clrconv->alpha) + { + *dst32 = (clrconv->invert) ? ABGR32(0xFF, redFg, greenFg, blueFg) : ARGB32(0xFF, redFg, greenFg, blueFg); + } + else + { + *dst32 = (clrconv->invert) ? BGR32(redFg, greenFg, blueFg) : RGB32(redFg, greenFg, blueFg); + } } dst32++; } diff --git a/libfreerdp/codec/h264.c b/libfreerdp/codec/h264.c index 4322231e7..77527a4de 100644 --- a/libfreerdp/codec/h264.c +++ b/libfreerdp/codec/h264.c @@ -25,181 +25,9 @@ #include #include -#include +#include #include -#include - -#ifdef WITH_H264_SSSE3 -extern int freerdp_check_ssse3(); -extern int freerdp_image_yuv420p_to_xrgb_ssse3(BYTE *pDstData,BYTE **pSrcData,int nWidth,int nHeight,int *iStride,int scanline); -#endif - -#define USE_GRAY_SCALE 0 -#define USE_UPCONVERT 0 - -static BYTE clip(int x) -{ - if (x < 0) return 0; - if (x > 255) return 255; - return (BYTE)x; -} - -static UINT32 YUV_to_RGB(BYTE Y, BYTE U, BYTE V) -{ - BYTE R, G, B; - -#if USE_GRAY_SCALE - /* - * Displays the Y plane as a gray-scale image. - */ - R = Y; - G = Y; - B = Y; -#else - int C, D, E; - -#if 0 - /* - * Documented colorspace conversion from YUV to RGB. - * See http://msdn.microsoft.com/en-us/library/ms893078.aspx - */ - - C = Y - 16; - D = U - 128; - E = V - 128; - - R = clip(( 298 * C + 409 * E + 128) >> 8); - G = clip(( 298 * C - 100 * D - 208 * E + 128) >> 8); - B = clip(( 298 * C + 516 * D + 128) >> 8); -#endif - -#if 0 - /* - * These coefficients produce better results. - * See http://www.microchip.com/forums/m599060.aspx - */ - - C = Y; - D = U - 128; - E = V - 128; - - R = clip(( 256 * C + 359 * E + 128) >> 8); - G = clip(( 256 * C - 88 * D - 183 * E + 128) >> 8); - B = clip(( 256 * C + 454 * D + 128) >> 8); -#endif - -#if 1 - /* - * These coefficients produce excellent results. - */ - - C = Y; - D = U - 128; - E = V - 128; - - R = clip(( 256 * C + 403 * E + 128) >> 8); - G = clip(( 256 * C - 48 * D - 120 * E + 128) >> 8); - B = clip(( 256 * C + 475 * D + 128) >> 8); -#endif - -#endif - - return RGB32(R, G, B); -} - -#if USE_UPCONVERT -static BYTE* h264_convert_420_to_444(BYTE* chroma420, int chroma420Width, int chroma420Height, int chroma420Stride) -{ - BYTE *chroma444, *src, *dst; - int chroma444Width; - int chroma444Height; - int i, j; - - chroma444Width = chroma420Width * 2; - chroma444Height = chroma420Height * 2; - - chroma444 = (BYTE*) malloc(chroma444Width * chroma444Height); - - if (!chroma444) - return NULL; - - /* Upconvert in the horizontal direction. */ - - for (j = 0; j < chroma420Height; j++) - { - src = chroma420 + j * chroma420Stride; - dst = chroma444 + j * chroma444Width; - dst[0] = src[0]; - for (i = 1; i < chroma420Width; i++) - { - dst[2*i-1] = (3 * src[i-1] + src[i] + 2) >> 2; - dst[2*i] = (src[i-1] + 3 * src[i] + 2) >> 2; - } - dst[chroma444Width-1] = src[chroma420Width-1]; - } - - /* Upconvert in the vertical direction (in-place, bottom-up). */ - - for (i = 0; i < chroma444Width; i++) - { - src = chroma444 + i + (chroma420Height-2) * chroma444Width; - dst = chroma444 + i + (2*(chroma420Height-2)+1) * chroma444Width; - dst[2*chroma444Width] = src[chroma444Width]; - for (j = chroma420Height - 2; j >= 0; j--) - { - dst[chroma444Width] = (src[0] + 3 * src[chroma444Width] + 2) >> 2; - dst[0] = (3 * src[0] + src[chroma444Width] + 2) >> 2; - dst -= 2 * chroma444Width; - src -= chroma444Width; - } - } - - return chroma444; -} -#endif - -static int g_H264FrameId = 0; -static BOOL g_H264DumpFrames = FALSE; - -static void h264_dump_h264_data(BYTE* data, int size) -{ - FILE* fp; - char buf[4096]; - - sprintf_s(buf, sizeof(buf), "/tmp/wlog/bs_%d.h264", g_H264FrameId); - fp = fopen(buf, "wb"); - fwrite(data, 1, size, fp); - fflush(fp); - fclose(fp); -} - -void h264_dump_yuv_data(BYTE* yuv[], int width, int height, int stride[]) -{ - FILE* fp; - BYTE* srcp; - char buf[4096]; - int j; - - sprintf_s(buf, sizeof(buf), "/tmp/wlog/H264_%d.ppm", g_H264FrameId); - fp = fopen(buf, "wb"); - fwrite("P5\n", 1, 3, fp); - sprintf_s(buf, sizeof(buf), "%d %d\n", width, height); - fwrite(buf, 1, strlen(buf), fp); - fwrite("255\n", 1, 4, fp); - - srcp = yuv[0]; - - for (j = 0; j < height; j++) - { - fwrite(srcp, 1, width, fp); - srcp += stride[0]; - } - - fflush(fp); - fclose(fp); -} - #ifdef WITH_LIBAVCODEC int h264_prepare_rgb_buffer(H264_CONTEXT* h264, int width, int height) { @@ -213,7 +41,11 @@ int h264_prepare_rgb_buffer(H264_CONTEXT* h264, int width, int height) if (size > h264->size) { h264->size = size; - h264->data = (BYTE*) _aligned_realloc(h264->data, h264->size,16); + + if (!h264->data) + h264->data = (BYTE*) _aligned_malloc(h264->size, 16); + else + h264->data = (BYTE*) _aligned_realloc(h264->data, h264->size, 16); } if (!h264->data) @@ -223,117 +55,49 @@ int h264_prepare_rgb_buffer(H264_CONTEXT* h264, int width, int height) } #endif -int freerdp_image_copy_yuv420p_to_xrgb(BYTE* pDstData, int nDstStep, int nXDst, int nYDst, - int nWidth, int nHeight, BYTE* pSrcData[3], int nSrcStep[2], int nXSrc, int nYSrc) +/** + * Dummy subsystem + */ + +static int dummy_decompress(H264_CONTEXT* h264, BYTE* pSrcData, UINT32 SrcSize, + BYTE* pDstData, DWORD DstFormat, int nDstStep, int nXDst, int nYDst, int nWidth, int nHeight) { - int x, y; - BYTE* pDstPixel8; - BYTE *pY, *pU, *pV; - int shift = 1; - -#if USE_UPCONVERT - /* Convert 4:2:0 YUV to 4:4:4 YUV. */ - pSrcData[1] = h264_convert_420_to_444(pSrcData[1], nWidth / 2, nHeight / 2, nSrcStep[1]); - pSrcData[2] = h264_convert_420_to_444(pSrcData[2], nWidth / 2, nHeight / 2, nSrcStep[1]); - - nSrcStep[1] = nWidth; - - shift = 0; -#endif - - pY = pSrcData[0] + (nYSrc * nSrcStep[0]) + nXSrc; - - pDstPixel8 = &pDstData[(nYDst * nDstStep) + (nXDst * 4)]; - - for (y = 0; y < nHeight; y++) - { - pU = pSrcData[1] + ((nYSrc + y) >> shift) * nSrcStep[1]; - pV = pSrcData[2] + ((nYSrc + y) >> shift) * nSrcStep[1]; - - for (x = 0; x < nWidth; x++) - { - BYTE Y, U, V; - - Y = *pY; - U = pU[(nXSrc + x) >> shift]; - V = pV[(nXSrc + x) >> shift]; - - *((UINT32*) pDstPixel8) = YUV_to_RGB(Y, U, V); - - pDstPixel8 += 4; - pY++; - } - - pDstPixel8 += (nDstStep - (nWidth * 4)); - pY += (nSrcStep[0] - nWidth); - } - -#if USE_UPCONVERT - free(pSrcData[1]); - free(pSrcData[2]); -#endif - - return 1; + return -1; } -BYTE* h264_strip_nal_unit_au_delimiter(BYTE* pSrcData, UINT32* pSrcSize) +static void dummy_uninit(H264_CONTEXT* h264) { - BYTE* data = pSrcData; - UINT32 size = *pSrcSize; - BYTE forbidden_zero_bit = 0; - BYTE nal_ref_idc = 0; - BYTE nal_unit_type = 0; - /* ITU-T H.264 B.1.1 Byte stream NAL unit syntax */ - - while (size > 0) - { - if (*data) - break; - - data++; - size--; - } - - if (*data != 1) - return pSrcData; - - data++; - size--; - - forbidden_zero_bit = (data[0] >> 7); - nal_ref_idc = (data[0] >> 5); - nal_unit_type = (data[0] & 0x1F); - - if (forbidden_zero_bit) - return pSrcData; /* invalid */ - - if (nal_unit_type == 9) - { - /* NAL Unit AU Delimiter */ - - printf("NAL Unit AU Delimiter: idc: %d\n", nal_ref_idc); - - data += 2; - size -= 2; - - *pSrcSize = size; - return data; - } - - return pSrcData; } +static BOOL dummy_init(H264_CONTEXT* h264) +{ + return TRUE; +} +static H264_CONTEXT_SUBSYSTEM g_Subsystem_dummy = +{ + "dummy", + dummy_init, + dummy_uninit, + dummy_decompress +}; -/************************************************* - * - * OpenH264 Implementation - * - ************************************************/ +/** + * OpenH264 subsystem + */ #ifdef WITH_OPENH264 +#include "wels/codec_def.h" +#include "wels/codec_api.h" + +struct _H264_CONTEXT_OPENH264 +{ + ISVCDecoder* pDecoder; +}; +typedef struct _H264_CONTEXT_OPENH264 H264_CONTEXT_OPENH264; + static BOOL g_openh264_trace_enabled = FALSE; static void openh264_trace_callback(H264_CONTEXT* h264, int level, const char* message) @@ -343,13 +107,18 @@ static void openh264_trace_callback(H264_CONTEXT* h264, int level, const char* m static int openh264_decompress(H264_CONTEXT* h264, BYTE* pSrcData, UINT32 SrcSize) { + int srcStep[3]; + prim_size_t roi; + BYTE* pYUVData[3]; DECODING_STATE state; SBufferInfo sBufferInfo; SSysMEMBuffer* pSystemBuffer; - + primitives_t* prims = primitives_get(); + H264_CONTEXT_OPENH264* sys = (H264_CONTEXT_OPENH264*) h264->pSystemData; + struct timeval T1,T2; - if (!h264->pDecoder) + if (!sys->pDecoder) return -1; /* @@ -363,8 +132,8 @@ static int openh264_decompress(H264_CONTEXT* h264, BYTE* pSrcData, UINT32 SrcSiz ZeroMemory(&sBufferInfo, sizeof(sBufferInfo)); gettimeofday(&T1,NULL); - state = (*h264->pDecoder)->DecodeFrame2( - h264->pDecoder, + state = (*sys->pDecoder)->DecodeFrame2( + sys->pDecoder, pSrcData, SrcSize, h264->pYUVData, @@ -378,7 +147,7 @@ static int openh264_decompress(H264_CONTEXT* h264, BYTE* pSrcData, UINT32 SrcSiz */ if (sBufferInfo.iBufferStatus != 1) - state = (*h264->pDecoder)->DecodeFrame2(h264->pDecoder, NULL, 0, h264->pYUVData, &sBufferInfo); + state = (*sys->pDecoder)->DecodeFrame2(sys->pDecoder, NULL, 0, pYUVData, &sBufferInfo); gettimeofday(&T2,NULL); printf("OpenH264: decoding took: %u sec %u usec\n",(unsigned int)(T2.tv_sec-T1.tv_sec),(unsigned int)(T2.tv_usec-T1.tv_usec)); @@ -404,46 +173,53 @@ static int openh264_decompress(H264_CONTEXT* h264, BYTE* pSrcData, UINT32 SrcSiz if (pSystemBuffer->iFormat != videoFormatI420) return -1; - - if (g_H264DumpFrames) - { - h264_dump_yuv_data(h264->pYUVData, pSystemBuffer->iWidth, pSystemBuffer->iHeight, pSystemBuffer->iStride); - } - - g_H264FrameId++; - h264->iStride[0] = pSystemBuffer->iStride[0]; h264->iStride[1] = pSystemBuffer->iStride[1]; h264->width = pSystemBuffer->iWidth; h264->height = pSystemBuffer->iHeight; - return 1; } -static void openh264_free(H264_CONTEXT* h264) +static void openh264_uninit(H264_CONTEXT* h264) { - if (h264->pDecoder) + H264_CONTEXT_OPENH264* sys = (H264_CONTEXT_OPENH264*) h264->pSystemData; + + if (sys) { - (*h264->pDecoder)->Uninitialize(h264->pDecoder); - WelsDestroyDecoder(h264->pDecoder); - h264->pDecoder = NULL; + if (sys->pDecoder) + { + (*sys->pDecoder)->Uninitialize(sys->pDecoder); + WelsDestroyDecoder(sys->pDecoder); + sys->pDecoder = NULL; + } + + free(sys); + h264->pSystemData = NULL; } } static BOOL openh264_init(H264_CONTEXT* h264) { - static EVideoFormatType videoFormat = videoFormatI420; - + long status; + SDecodingParam sDecParam; + H264_CONTEXT_OPENH264* sys; static int traceLevel = WELS_LOG_DEBUG; + static EVideoFormatType videoFormat = videoFormatI420; static WelsTraceCallback traceCallback = (WelsTraceCallback) openh264_trace_callback; - SDecodingParam sDecParam; - long status; + sys = (H264_CONTEXT_OPENH264*) calloc(1, sizeof(H264_CONTEXT_OPENH264)); - WelsCreateDecoder(&h264->pDecoder); + if (!sys) + { + goto EXCEPTION; + } - if (!h264->pDecoder) + h264->pSystemData = (void*) sys; + + WelsCreateDecoder(&sys->pDecoder); + + if (!sys->pDecoder) { printf("Failed to create OpenH264 decoder\n"); goto EXCEPTION; @@ -451,10 +227,10 @@ static BOOL openh264_init(H264_CONTEXT* h264) ZeroMemory(&sDecParam, sizeof(sDecParam)); sDecParam.iOutputColorFormat = videoFormatI420; - sDecParam.uiEcActiveFlag = 1; + sDecParam.uiEcActiveFlag = 1; sDecParam.sVideoProperty.eVideoBsType = VIDEO_BITSTREAM_DEFAULT; - status = (*h264->pDecoder)->Initialize(h264->pDecoder, &sDecParam); + status = (*sys->pDecoder)->Initialize(sys->pDecoder, &sDecParam); if (status != 0) { @@ -462,7 +238,7 @@ static BOOL openh264_init(H264_CONTEXT* h264) goto EXCEPTION; } - status = (*h264->pDecoder)->SetOption(h264->pDecoder, DECODER_OPTION_DATAFORMAT, &videoFormat); + status = (*sys->pDecoder)->SetOption(sys->pDecoder, DECODER_OPTION_DATAFORMAT, &videoFormat); if (status != 0) { @@ -471,19 +247,22 @@ static BOOL openh264_init(H264_CONTEXT* h264) if (g_openh264_trace_enabled) { - status = (*h264->pDecoder)->SetOption(h264->pDecoder, DECODER_OPTION_TRACE_LEVEL, &traceLevel); + status = (*sys->pDecoder)->SetOption(sys->pDecoder, DECODER_OPTION_TRACE_LEVEL, &traceLevel); + if (status != 0) { printf("Failed to set trace level option on OpenH264 decoder (status=%ld)\n", status); } - status = (*h264->pDecoder)->SetOption(h264->pDecoder, DECODER_OPTION_TRACE_CALLBACK, &traceCallback); + status = (*sys->pDecoder)->SetOption(sys->pDecoder, DECODER_OPTION_TRACE_CALLBACK, &traceCallback); + if (status != 0) { printf("Failed to set trace callback option on OpenH264 decoder (status=%ld)\n", status); } - status = (*h264->pDecoder)->SetOption(h264->pDecoder, DECODER_OPTION_TRACE_CALLBACK_CONTEXT, &h264); + status = (*sys->pDecoder)->SetOption(sys->pDecoder, DECODER_OPTION_TRACE_CALLBACK_CONTEXT, &h264); + if (status != 0) { printf("Failed to set trace callback context option on OpenH264 decoder (status=%ld)\n", status); @@ -493,30 +272,51 @@ static BOOL openh264_init(H264_CONTEXT* h264) return TRUE; EXCEPTION: - openh264_free(h264); + openh264_uninit(h264); return FALSE; } +static H264_CONTEXT_SUBSYSTEM g_Subsystem_OpenH264 = +{ + "OpenH264", + openh264_init, + openh264_uninit, + openh264_decompress +}; + #endif - - -/************************************************* - * - * libavcodec Implementation - * - ************************************************/ +/** + * libavcodec subsystem + */ #ifdef WITH_LIBAVCODEC +#include +#include + +struct _H264_CONTEXT_LIBAVCODEC +{ + AVCodec* codec; + AVCodecContext* codecContext; + AVCodecParserContext* codecParser; + AVFrame* videoFrame; +}; +typedef struct _H264_CONTEXT_LIBAVCODEC H264_CONTEXT_LIBAVCODEC; + static int libavcodec_decompress(H264_CONTEXT* h264, BYTE* pSrcData, UINT32 SrcSize, BYTE* pDstData, DWORD DstFormat, int nDstStep, int nXDst, int nYDst, int nWidth, int nHeight) { - AVPacket packet; - int gotFrame = 0; int status; - + int srcStep[3]; + int gotFrame = 0; + AVPacket packet; + prim_size_t roi; + const BYTE* pSrc[3]; + primitives_t* prims = primitives_get(); + H264_CONTEXT_LIBAVCODEC* sys = (H264_CONTEXT_LIBAVCODEC*) h264->pSystemData; + struct timeval T1,T2; av_init_packet(&packet); @@ -525,7 +325,7 @@ static int libavcodec_decompress(H264_CONTEXT* h264, BYTE* pSrcData, UINT32 SrcS packet.size = SrcSize; gettimeofday(&T1,NULL); - status = avcodec_decode_video2(h264->codecContext, h264->videoFrame, &gotFrame, &packet); + status = avcodec_decode_video2(sys->codecContext, sys->videoFrame, &gotFrame, &packet); gettimeofday(&T2,NULL); printf("libavcodec: decoding took: %u sec %u usec\n",(unsigned int)(T2.tv_sec-T1.tv_sec),(unsigned int)(T2.tv_usec-T1.tv_usec)); @@ -536,98 +336,116 @@ static int libavcodec_decompress(H264_CONTEXT* h264, BYTE* pSrcData, UINT32 SrcS return -1; } +#if 0 printf("libavcodec_decompress: frame decoded (status=%d, gotFrame=%d, width=%d, height=%d, Y=[%p,%d], U=[%p,%d], V=[%p,%d])\n", - status, gotFrame, h264->videoFrame->width, h264->videoFrame->height, - h264->videoFrame->data[0], h264->videoFrame->linesize[0], - h264->videoFrame->data[1], h264->videoFrame->linesize[1], - h264->videoFrame->data[2], h264->videoFrame->linesize[2]); - fflush(stdout); + status, gotFrame, sys->videoFrame->width, sys->videoFrame->height, + sys->videoFrame->data[0], sys->videoFrame->linesize[0], + sys->videoFrame->data[1], sys->videoFrame->linesize[1], + sys->videoFrame->data[2], sys->videoFrame->linesize[2]); +#endif if (gotFrame) { - if (g_H264DumpFrames) - { - h264_dump_yuv_data(h264->videoFrame->data, h264->videoFrame->width, h264->videoFrame->height, h264->videoFrame->linesize); - } - - if (h264_prepare_rgb_buffer(h264, h264->videoFrame->width, h264->videoFrame->height) < 0) + if (h264_prepare_rgb_buffer(h264, sys->videoFrame->width, sys->videoFrame->height) < 0) return -1; - gettimeofday(&T1,NULL); -#ifdef WITH_H264_SSSE3 - freerdp_image_yuv420p_to_xrgb(h264->data,h264->videoFrame->data,h264->width,h264->height,h264->videoFrame->linesize[0],h264->videoFrame->linesize[1]); -#else -#ifdef WITH_H264_ASM - freerdp_image_yuv_to_xrgb_asm(h264->data,h264->videoFrame->data,h264->width,h264->height,h264->videoFrame->linesize[0],h264->videoFrame->linesize[1]); -#else - freerdp_image_copy_yuv420p_to_xrgb(h264->data, h264->scanline, 0, 0, - h264->width, h264->height, h264->videoFrame->data, h264->videoFrame->linesize, 0, 0); -#endif -#endif - gettimeofday(&T2,NULL); - printf("\tconverting took %u sec %u usec\n",(unsigned int)(T2.tv_sec-T1.tv_sec),(unsigned int)(T2.tv_usec-T1.tv_usec)); + roi.width = h264->width; + roi.height = h264->height; + + pSrc[0] = sys->videoFrame->data[0]; + pSrc[1] = sys->videoFrame->data[1]; + pSrc[2] = sys->videoFrame->data[2]; + + srcStep[0] = sys->videoFrame->linesize[0]; + srcStep[1] = sys->videoFrame->linesize[1]; + srcStep[2] = sys->videoFrame->linesize[2]; + + prims->YUV420ToRGB_8u_P3AC4R(pSrc, srcStep, h264->data, h264->scanline, &roi); } return 1; } -static void libavcodec_free(H264_CONTEXT* h264) +static void libavcodec_uninit(H264_CONTEXT* h264) { - if (h264->videoFrame) + H264_CONTEXT_LIBAVCODEC* sys = (H264_CONTEXT_LIBAVCODEC*) h264->pSystemData; + + if (!sys) + return; + + if (sys->videoFrame) { - av_free(h264->videoFrame); + av_free(sys->videoFrame); } - if (h264->codecParser) + if (sys->codecParser) { - av_parser_close(h264->codecParser); + av_parser_close(sys->codecParser); } - if (h264->codecContext) + if (sys->codecContext) { - avcodec_close(h264->codecContext); - av_free(h264->codecContext); + avcodec_close(sys->codecContext); + av_free(sys->codecContext); } + + free(sys); + h264->pSystemData = NULL; } static BOOL libavcodec_init(H264_CONTEXT* h264) { + H264_CONTEXT_LIBAVCODEC* sys; + + sys = (H264_CONTEXT_LIBAVCODEC*) calloc(1, sizeof(H264_CONTEXT_LIBAVCODEC)); + + if (!sys) + { + goto EXCEPTION; + } + + h264->pSystemData = (void*) sys; + avcodec_register_all(); - h264->codec = avcodec_find_decoder(CODEC_ID_H264); - if (!h264->codec) + sys->codec = avcodec_find_decoder(CODEC_ID_H264); + + if (!sys->codec) { printf("Failed to find libav H.264 codec\n"); goto EXCEPTION; } - h264->codecContext = avcodec_alloc_context3(h264->codec); - if (!h264->codecContext) + sys->codecContext = avcodec_alloc_context3(sys->codec); + + if (!sys->codecContext) { printf("Failed to allocate libav codec context\n"); goto EXCEPTION; } - if (h264->codec->capabilities & CODEC_CAP_TRUNCATED) + if (sys->codec->capabilities & CODEC_CAP_TRUNCATED) { - h264->codecContext->flags |= CODEC_FLAG_TRUNCATED; + sys->codecContext->flags |= CODEC_FLAG_TRUNCATED; } - if (avcodec_open2(h264->codecContext, h264->codec, NULL) < 0) + if (avcodec_open2(sys->codecContext, sys->codec, NULL) < 0) { printf("Failed to open libav codec\n"); goto EXCEPTION; } - h264->codecParser = av_parser_init(CODEC_ID_H264); - if (!h264->codecParser) + sys->codecParser = av_parser_init(CODEC_ID_H264); + + if (!sys->codecParser) { printf("Failed to initialize libav parser\n"); goto EXCEPTION; } - h264->videoFrame = avcodec_alloc_frame(); - if (!h264->videoFrame) + sys->videoFrame = avcodec_alloc_frame(); + + if (!sys->videoFrame) { printf("Failed to allocate libav frame\n"); goto EXCEPTION; @@ -636,19 +454,24 @@ static BOOL libavcodec_init(H264_CONTEXT* h264) return TRUE; EXCEPTION: - libavcodec_free(h264); + libavcodec_uninit(h264); return FALSE; } +static H264_CONTEXT_SUBSYSTEM g_Subsystem_libavcodec = +{ + "libavcodec", + libavcodec_init, + libavcodec_uninit, + libavcodec_decompress +}; + #endif - - int h264_decompress(H264_CONTEXT* h264, BYTE* pSrcData, UINT32 SrcSize, BYTE** ppDstData, DWORD DstFormat, int nDstStep, int nDstHeight, RDPGFX_RECT16* regionRects, int numRegionRects) { - UINT32 UncompressedSize; BYTE* pDstData; BYTE* pDstPoint; @@ -658,6 +481,7 @@ int h264_decompress(H264_CONTEXT* h264, BYTE* pSrcData, UINT32 SrcSize, RDPGFX_RECT16* rect; int* iStride; int ret, i, cx, cy; + int UncompressedSize; struct timeval T1,T2; @@ -665,42 +489,20 @@ int h264_decompress(H264_CONTEXT* h264, BYTE* pSrcData, UINT32 SrcSize, return -1; #if 0 - pSrcData = h264_strip_nal_unit_au_delimiter(pSrcData, &SrcSize); -#endif - -#if 0 - printf("h264_decompress: pSrcData=%p, SrcSize=%u, pDstData=%p, nDstStep=%d, numRegionRects=%d\n", - pSrcData, SrcSize, *ppDstData, nDstStep, numRegionRects); + printf("h264_decompress: pSrcData=%p, SrcSize=%u, pDstData=%p, nDstStep=%d, nXDst=%d, nYDst=%d, nWidth=%d, nHeight=%d)\n", + pSrcData, SrcSize, *ppDstData, nDstStep, nXDst, nYDst, nWidth, nHeight); #endif if (!(pDstData = *ppDstData)) return -1; - if (g_H264DumpFrames) - { - h264_dump_h264_data(pSrcData, SrcSize); - } +<<<<<<< HEAD + if (h264->subsystem->Decompress(h264, pSrcData, SrcSize, + pDstData, DstFormat, nDstStep, nXDst, nYDst, nWidth, nHeight)) + return -1; -#ifdef WITH_OPENH264 - ret = openh264_decompress(h264, pSrcData, SrcSize); - if (ret != 1) - return ret; - - pYUVData = h264->pYUVData; - iStride = h264->iStride; -#endif - -#ifdef WITH_LIBAVCODEC - return libavcodec_decompress( - h264, pSrcData, SrcSize, - pDstData, DstFormat, nDstStep, - nXDst, nYDst, nWidth, nHeight); -#endif - - - /* Convert I420 (same as IYUV) to XRGB. */ UncompressedSize = h264->width * h264->height * 4; if (UncompressedSize > (nDstStep * nDstHeight)) return -1; @@ -727,8 +529,19 @@ int h264_decompress(H264_CONTEXT* h264, BYTE* pSrcData, UINT32 SrcSize, #ifdef WITH_H264_SSSE3 freerdp_image_yuv420p_to_xrgb_ssse3(pDstPoint, pYUVPoint, cx, cy, iStride, nDstStep); #else - freerdp_image_copy_yuv420p_to_xrgb(pDstPoint, nDstStep, 0, 0, - cx, cy, pYUVPoint, iStride, 0, 0); +/* roi.width = h264->width; + roi.height = h264->height; + + pSrc[0] = sys->videoFrame->data[0]; + pSrc[1] = sys->videoFrame->data[1]; + pSrc[2] = sys->videoFrame->data[2]; + + srcStep[0] = sys->videoFrame->linesize[0]; + srcStep[1] = sys->videoFrame->linesize[1]; + srcStep[2] = sys->videoFrame->linesize[2]; + + prims->YUV420ToRGB_8u_P3AC4R(pSrc, srcStep, h264->data, h264->scanline, &roi) + */ #endif } gettimeofday(&T2,NULL); @@ -742,8 +555,25 @@ int h264_compress(H264_CONTEXT* h264, BYTE* pSrcData, UINT32 SrcSize, BYTE** ppD return 1; } -void h264_context_reset(H264_CONTEXT* h264) +BOOL h264_context_init(H264_CONTEXT* h264) { +#ifdef WITH_LIBAVCODEC + if (g_Subsystem_libavcodec.Init(h264)) + { + h264->subsystem = &g_Subsystem_libavcodec; + return TRUE; + } +#endif + +#ifdef WITH_OPENH264 + if (g_Subsystem_OpenH264.Init(h264)) + { + h264->subsystem = &g_Subsystem_OpenH264; + return TRUE; + } +#endif + + return FALSE; } H264_CONTEXT* h264_context_new(BOOL Compressor) @@ -763,23 +593,18 @@ H264_CONTEXT* h264_context_new(BOOL Compressor) { h264->Compressor = Compressor; -#ifdef WITH_OPENH264 - if (!openh264_init(h264)) - { - free(h264); - return NULL; - } -#endif + h264->subsystem = &g_Subsystem_dummy; #ifdef WITH_LIBAVCODEC - if (!libavcodec_init(h264)) + if (h264_prepare_rgb_buffer(h264, 256, 256) < 0) + return NULL; +#endif + + if (!h264_context_init(h264)) { free(h264); return NULL; } -#endif - - h264_context_reset(h264); } return h264; @@ -789,15 +614,12 @@ void h264_context_free(H264_CONTEXT* h264) { if (h264) { -#ifdef WITH_OPENH264 - openh264_free(h264); -#endif - #ifdef WITH_LIBAVCODEC - libavcodec_free(h264); _aligned_free(h264->data); #endif + h264->subsystem->Uninit(h264); + free(h264); } } diff --git a/libfreerdp/codec/mppc.c b/libfreerdp/codec/mppc.c index 410277f0e..89c18db42 100644 --- a/libfreerdp/codec/mppc.c +++ b/libfreerdp/codec/mppc.c @@ -413,7 +413,7 @@ int mppc_decompress(MPPC_CONTEXT* mppc, BYTE* pSrcData, UINT32 SrcSize, BYTE** p } #ifdef DEBUG_MPPC - printf("<%d,%d>\n", (int) CopyOffset, (int) LengthOfMatch); + DEBUG_MSG("<%d,%d>\n", (int) CopyOffset, (int) LengthOfMatch); #endif SrcPtr = HistoryPtr - CopyOffset; @@ -555,7 +555,7 @@ int mppc_compress(MPPC_CONTEXT* mppc, BYTE* pSrcData, UINT32 SrcSize, BYTE** ppD accumulator = Sym1; #ifdef DEBUG_MPPC - printf("%c", accumulator); + DEBUG_MSG("%c", accumulator); #endif if (accumulator < 0x80) @@ -589,7 +589,7 @@ int mppc_compress(MPPC_CONTEXT* mppc, BYTE* pSrcData, UINT32 SrcSize, BYTE** ppD } #ifdef DEBUG_MPPC - printf("<%d,%d>", (int) CopyOffset, (int) LengthOfMatch); + DEBUG_MSG("<%d,%d>", (int) CopyOffset, (int) LengthOfMatch); #endif /* Encode CopyOffset */ @@ -764,7 +764,7 @@ int mppc_compress(MPPC_CONTEXT* mppc, BYTE* pSrcData, UINT32 SrcSize, BYTE** ppD accumulator = *pSrcPtr; #ifdef DEBUG_MPPC - printf("%c", accumulator); + DEBUG_MSG("%c", accumulator); #endif if (accumulator < 0x80) @@ -799,7 +799,7 @@ int mppc_compress(MPPC_CONTEXT* mppc, BYTE* pSrcData, UINT32 SrcSize, BYTE** ppD mppc->HistoryOffset = HistoryPtr - HistoryBuffer; #ifdef DEBUG_MPPC - printf("\n"); + DEBUG_MSG("\n"); #endif return 1; diff --git a/libfreerdp/codec/ncrush.c b/libfreerdp/codec/ncrush.c index e57ecf259..f8faab292 100644 --- a/libfreerdp/codec/ncrush.c +++ b/libfreerdp/codec/ncrush.c @@ -25,6 +25,7 @@ #include #include +#include #include UINT16 HuffTableLEC[8192] = @@ -1847,7 +1848,7 @@ int ncrush_decompress(NCRUSH_CONTEXT* ncrush, BYTE* pSrcData, UINT32 SrcSize, BY if (HistoryPtr >= HistoryBufferEnd) { - fprintf(stderr, "ncrush_decompress error: HistoryPtr (%p) >= HistoryBufferEnd (%p)\n", + DEBUG_WARN( "ncrush_decompress error: HistoryPtr (%p) >= HistoryBufferEnd (%p)\n", HistoryPtr, HistoryBufferEnd); return -1003; } @@ -2021,7 +2022,7 @@ int ncrush_decompress(NCRUSH_CONTEXT* ncrush, BYTE* pSrcData, UINT32 SrcSize, BY if (ncrush->HistoryBufferFence != 0xABABABAB) { - fprintf(stderr, "NCrushDecompress: history buffer fence was overwritten, potential buffer overflow detected!\n"); + DEBUG_WARN( "NCrushDecompress: history buffer fence was overwritten, potential buffer overflow detected!\n"); return -1007; } @@ -2695,7 +2696,7 @@ NCRUSH_CONTEXT* ncrush_context_new(BOOL Compressor) ncrush->HistoryPtr = &(ncrush->HistoryBuffer[ncrush->HistoryOffset]); if (ncrush_generate_tables(ncrush) < 0) - printf("ncrush_context_new: failed to initialize tables\n"); + DEBUG_MSG("ncrush_context_new: failed to initialize tables\n"); ncrush_context_reset(ncrush, FALSE); } diff --git a/libfreerdp/codec/planar.c b/libfreerdp/codec/planar.c index 2777460b7..37ce3ed7e 100644 --- a/libfreerdp/codec/planar.c +++ b/libfreerdp/codec/planar.c @@ -24,16 +24,66 @@ #include #include -#include #include +#include +#include #include "planar.h" -static int planar_decompress_plane_rle(BYTE* pSrcData, UINT32 SrcSize, BYTE* pDstData, +static int planar_skip_plane_rle(const BYTE* pSrcData, UINT32 SrcSize, int nWidth, int nHeight) +{ + int x, y; + int cRawBytes; + int nRunLength; + BYTE controlByte; + const BYTE* pRLE = pSrcData; + const BYTE* pEnd = &pSrcData[SrcSize]; + + for (y = 0; y < nHeight; y++) + { + for (x = 0; x < nWidth; ) + { + if (pRLE >= pEnd) + return -1; + + controlByte = *pRLE++; + + nRunLength = PLANAR_CONTROL_BYTE_RUN_LENGTH(controlByte); + cRawBytes = PLANAR_CONTROL_BYTE_RAW_BYTES(controlByte); + + if (nRunLength == 1) + { + nRunLength = cRawBytes + 16; + cRawBytes = 0; + } + else if (nRunLength == 2) + { + nRunLength = cRawBytes + 32; + cRawBytes = 0; + } + + pRLE += cRawBytes; + x += cRawBytes; + cRawBytes = 0; + + x += nRunLength; + nRunLength = 0; + + if (x > nWidth) + return -1; + + if (pRLE > pEnd) + return -1; + } + } + + return (int) (pRLE - pSrcData); +} + +static int planar_decompress_plane_rle(const BYTE* pSrcData, UINT32 SrcSize, BYTE* pDstData, int nDstStep, int nXDst, int nYDst, int nWidth, int nHeight, int nChannel, BOOL vFlip) { int x, y; - BYTE* srcp; BYTE* dstp; UINT32 pixel; int cRawBytes; @@ -43,8 +93,8 @@ static int planar_decompress_plane_rle(BYTE* pSrcData, UINT32 SrcSize, BYTE* pDs BYTE controlByte; BYTE* currentScanline; BYTE* previousScanline; + const BYTE* srcp = pSrcData; - srcp = pSrcData; dstp = pDstData; previousScanline = NULL; @@ -75,7 +125,7 @@ static int planar_decompress_plane_rle(BYTE* pSrcData, UINT32 SrcSize, BYTE* pDs if ((srcp - pSrcData) > SrcSize) { - fprintf(stderr, "planar_decompress_plane_rle: error reading input buffer\n"); + DEBUG_WARN( "planar_decompress_plane_rle: error reading input buffer\n"); return -1; } @@ -95,7 +145,7 @@ static int planar_decompress_plane_rle(BYTE* pSrcData, UINT32 SrcSize, BYTE* pDs if (((dstp + (cRawBytes + nRunLength)) - currentScanline) > nWidth * 4) { - fprintf(stderr, "planar_decompress_plane_rle: too many pixels in scanline\n"); + DEBUG_WARN( "planar_decompress_plane_rle: too many pixels in scanline\n"); return -1; } @@ -167,13 +217,16 @@ static int planar_decompress_plane_rle(BYTE* pSrcData, UINT32 SrcSize, BYTE* pDs return (int) (srcp - pSrcData); } -static int planar_decompress_plane_raw(BYTE* pSrcData, UINT32 SrcSize, BYTE* pDstData, - int nDstStep, int nXDst, int nYDst, int nWidth, int nHeight, int nChannel, BOOL vFlip) +static int planar_decompress_planes_raw(const BYTE* pSrcData[4], int nSrcStep, BYTE* pDstData, + int nDstStep, int nXDst, int nYDst, int nWidth, int nHeight, BOOL alpha, BOOL vFlip) { int x, y; int beg, end, inc; - BYTE* dstp = NULL; - BYTE* srcp = pSrcData; + BYTE* pRGB = pDstData; + const BYTE* pR = pSrcData[0]; + const BYTE* pG = pSrcData[1]; + const BYTE* pB = pSrcData[2]; + const BYTE* pA = pSrcData[3]; if (vFlip) { @@ -188,30 +241,63 @@ static int planar_decompress_plane_raw(BYTE* pSrcData, UINT32 SrcSize, BYTE* pDs inc = 1; } - for (y = beg; y != end; y += inc) + if (alpha) { - dstp = &pDstData[((nYDst + y) * nDstStep) + (nXDst * 4) + nChannel]; - - for (x = 0; x < nWidth; x++) + for (y = beg; y != end; y += inc) { - *dstp = *srcp; - dstp += 4; - srcp++; + pRGB = &pDstData[((nYDst + y) * nDstStep) + (nXDst * 4)]; + + for (x = 0; x < nWidth; x++) + { + *pRGB++ = *pB++; + *pRGB++ = *pG++; + *pRGB++ = *pR++; + *pRGB++ = *pA++; + } + } + } + else + { + for (y = beg; y != end; y += inc) + { + pRGB = &pDstData[((nYDst + y) * nDstStep) + (nXDst * 4)]; + + for (x = 0; x < nWidth; x++) + { + *pRGB++ = *pB++; + *pRGB++ = *pG++; + *pRGB++ = *pR++; + *pRGB++ = 0xFF; + } } } - return (int) (srcp - pSrcData); + return 1; } int planar_decompress(BITMAP_PLANAR_CONTEXT* planar, BYTE* pSrcData, UINT32 SrcSize, BYTE** ppDstData, DWORD DstFormat, int nDstStep, int nXDst, int nYDst, int nWidth, int nHeight) { + BOOL cs; + BOOL rle; + UINT32 cll; + BOOL alpha; int status; BYTE* srcp; BOOL vFlip; + int subSize; + int subWidth; + int subHeight; + int planeSize; + BYTE* pDstData; + int rleSizes[4]; + int rawSizes[4]; + int rawWidths[4]; + int rawHeights[4]; BYTE FormatHeader; - BYTE* pDstData = NULL; + const BYTE* planes[4]; UINT32 UncompressedSize; + const primitives_t* prims = primitives_get(); if ((nWidth * nHeight) <= 0) return -1; @@ -233,124 +319,262 @@ int planar_decompress(BITMAP_PLANAR_CONTEXT* planar, BYTE* pSrcData, UINT32 SrcS *ppDstData = pDstData; } - FormatHeader = *srcp; - srcp++; + FormatHeader = *srcp++; - /* AlphaPlane */ + cll = (FormatHeader & PLANAR_FORMAT_HEADER_CLL_MASK); + cs = (FormatHeader & PLANAR_FORMAT_HEADER_CS) ? TRUE : FALSE; + rle = (FormatHeader & PLANAR_FORMAT_HEADER_RLE) ? TRUE : FALSE; + alpha = (FormatHeader & PLANAR_FORMAT_HEADER_NA) ? FALSE : TRUE; - if (!(FormatHeader & PLANAR_FORMAT_HEADER_NA)) + //printf("CLL: %d CS: %d RLE: %d ALPHA: %d\n", cll, cs, rle, alpha); + + if (!cll && cs) + return -1; /* Chroma subsampling requires YCoCg */ + + subWidth = (nWidth / 2) + (nWidth % 2); + subHeight = (nHeight / 2) + (nHeight % 2); + + planeSize = nWidth * nHeight; + subSize = subWidth * subHeight; + + if (!cs) { - if (FormatHeader & PLANAR_FORMAT_HEADER_RLE) + rawSizes[0] = planeSize; /* LumaOrRedPlane */ + rawWidths[0] = nWidth; + rawHeights[0] = nHeight; + + rawSizes[1] = planeSize; /* OrangeChromaOrGreenPlane */ + rawWidths[1] = nWidth; + rawHeights[1] = nHeight; + + rawSizes[2] = planeSize; /* GreenChromaOrBluePlane */ + rawWidths[2] = nWidth; + rawHeights[2] = nHeight; + + rawSizes[3] = planeSize; /* AlphaPlane */ + rawWidths[3] = nWidth; + rawHeights[3] = nHeight; + } + else /* Chroma Subsampling */ + { + rawSizes[0] = planeSize; /* LumaOrRedPlane */ + rawWidths[0] = nWidth; + rawHeights[0] = nHeight; + + rawSizes[1] = subSize; /* OrangeChromaOrGreenPlane */ + rawWidths[1] = subWidth; + rawHeights[1] = subHeight; + + rawSizes[2] = subSize; /* GreenChromaOrBluePlane */ + rawWidths[2] = subWidth; + rawHeights[2] = subHeight; + + rawSizes[3] = planeSize; /* AlphaPlane */ + rawWidths[3] = nWidth; + rawHeights[3] = nHeight; + } + + if (!rle) /* RAW */ + { + if (alpha) { - status = planar_decompress_plane_rle(srcp, SrcSize - (srcp - pSrcData), - pDstData, nDstStep, nXDst, nYDst, nWidth, nHeight, 3, vFlip); + planes[3] = srcp; /* AlphaPlane */ + planes[0] = planes[3] + rawSizes[3]; /* LumaOrRedPlane */ + planes[1] = planes[0] + rawSizes[0]; /* OrangeChromaOrGreenPlane */ + planes[2] = planes[1] + rawSizes[1]; /* GreenChromaOrBluePlane */ - if (status < 0) + if ((planes[2] + rawSizes[2]) > &pSrcData[SrcSize]) return -1; - - srcp += status; } else { - status = planar_decompress_plane_raw(srcp, SrcSize - (srcp - pSrcData), - pDstData, nDstStep, nXDst, nYDst, nWidth, nHeight, 3, vFlip); - - if (status < 0) + if ((SrcSize - (srcp - pSrcData)) < (planeSize * 3)) return -1; - srcp += status; + planes[0] = srcp; /* LumaOrRedPlane */ + planes[1] = planes[0] + rawSizes[0]; /* OrangeChromaOrGreenPlane */ + planes[2] = planes[1] + rawSizes[1]; /* GreenChromaOrBluePlane */ + + if ((planes[2] + rawSizes[2]) > &pSrcData[SrcSize]) + return -1; } } - - if (FormatHeader & PLANAR_FORMAT_HEADER_RLE) + else /* RLE */ { - /* LumaOrRedPlane */ - - status = planar_decompress_plane_rle(srcp, SrcSize - (srcp - pSrcData), - pDstData, nDstStep, nXDst, nYDst, nWidth, nHeight, 2, vFlip); - - if (status < 0) - return -1; - - srcp += status; - - /* OrangeChromaOrGreenPlane */ - - status = planar_decompress_plane_rle(srcp, SrcSize - (srcp - pSrcData), - pDstData, nDstStep, nXDst, nYDst, nWidth, nHeight, 1, vFlip); - - if (status < 0) - return -1; - - srcp += status; - - /* GreenChromeOrBluePlane */ - - status = planar_decompress_plane_rle(srcp, SrcSize - (srcp - pSrcData), - pDstData, nDstStep, nXDst, nYDst, nWidth, nHeight, 0, vFlip); - - if (status < 0) - return -1; - - srcp += status; - } - else - { - /* LumaOrRedPlane */ - - status = planar_decompress_plane_raw(srcp, SrcSize - (srcp - pSrcData), - pDstData, nDstStep, nXDst, nYDst, nWidth, nHeight, 2, vFlip); - - if (status < 0) - return -1; - - srcp += status; - - /* OrangeChromaOrGreenPlane */ - - status = planar_decompress_plane_raw(srcp, SrcSize - (srcp - pSrcData), - pDstData, nDstStep, nXDst, nYDst, nWidth, nHeight, 1, vFlip); - - if (status < 0) - return -1; - - srcp += status; - - /* GreenChromeOrBluePlane */ - - status = planar_decompress_plane_raw(srcp, SrcSize - (srcp - pSrcData), - pDstData, nDstStep, nXDst, nYDst, nWidth, nHeight, 0, vFlip); - - if (status < 0) - return -1; - - srcp += status; - srcp++; - } - - if (FormatHeader & PLANAR_FORMAT_HEADER_CLL_MASK) - { - /* The data is in YCoCg colorspace rather than RGB. */ - if (FormatHeader & PLANAR_FORMAT_HEADER_CS) + if (alpha) { - static BOOL been_warned = FALSE; - if (!been_warned) - fprintf(stderr, "Chroma-Subsampling is not implemented.\n"); - been_warned = TRUE; + planes[3] = srcp; + rleSizes[3] = planar_skip_plane_rle(planes[3], SrcSize - (planes[3] - pSrcData), + rawWidths[3], rawHeights[3]); /* AlphaPlane */ + + if (rleSizes[3] < 0) + return -1; + + planes[0] = planes[3] + rleSizes[3]; + rleSizes[0] = planar_skip_plane_rle(planes[0], SrcSize - (planes[0] - pSrcData), + rawWidths[0], rawHeights[0]); /* RedPlane */ + + if (rleSizes[0] < 0) + return -1; + + planes[1] = planes[0] + rleSizes[0]; + rleSizes[1] = planar_skip_plane_rle(planes[1], SrcSize - (planes[1] - pSrcData), + rawWidths[1], rawHeights[1]); /* GreenPlane */ + + if (rleSizes[1] < 1) + return -1; + + planes[2] = planes[1] + rleSizes[1]; + rleSizes[2] = planar_skip_plane_rle(planes[2], SrcSize - (planes[2] - pSrcData), + rawWidths[2], rawHeights[2]); /* BluePlane */ + + if (rleSizes[2] < 1) + return -1; } else { - BOOL alpha; - int cll; + planes[0] = srcp; + rleSizes[0] = planar_skip_plane_rle(planes[0], SrcSize - (planes[0] - pSrcData), + rawWidths[0], rawHeights[0]); /* RedPlane */ - alpha = (FormatHeader & PLANAR_FORMAT_HEADER_NA) ? FALSE : TRUE; - cll = FormatHeader & PLANAR_FORMAT_HEADER_CLL_MASK; - primitives_get()->YCoCgRToRGB_8u_AC4R( - pDstData, nDstStep, pDstData, nDstStep, - nWidth, nHeight, cll, alpha, FALSE); + if (rleSizes[0] < 0) + return -1; + + planes[1] = planes[0] + rleSizes[0]; + rleSizes[1] = planar_skip_plane_rle(planes[1], SrcSize - (planes[1] - pSrcData), + rawWidths[1], rawHeights[1]); /* GreenPlane */ + + if (rleSizes[1] < 1) + return -1; + + planes[2] = planes[1] + rleSizes[1]; + rleSizes[2] = planar_skip_plane_rle(planes[2], SrcSize - (planes[2] - pSrcData), + rawWidths[2], rawHeights[2]); /* BluePlane */ + + if (rleSizes[2] < 1) + return -1; } } + if (!cll) /* RGB */ + { + if (!rle) /* RAW */ + { + if (alpha) + { + planar_decompress_planes_raw(planes, nWidth, pDstData, nDstStep, + nXDst, nYDst, nWidth, nHeight, alpha, vFlip); + + srcp += rawSizes[0] + rawSizes[1] + rawSizes[2] + rawSizes[3]; + } + else /* NoAlpha */ + { + planar_decompress_planes_raw(planes, nWidth, pDstData, nDstStep, + nXDst, nYDst, nWidth, nHeight, alpha, vFlip); + + srcp += rawSizes[0] + rawSizes[1] + rawSizes[2]; + } + + if ((SrcSize - (srcp - pSrcData)) == 1) + srcp++; /* pad */ + } + else /* RLE */ + { + if (alpha) + { + status = planar_decompress_plane_rle(planes[3], rleSizes[3], + pDstData, nDstStep, nXDst, nYDst, nWidth, nHeight, 3, vFlip); /* AlphaPlane */ + + status = planar_decompress_plane_rle(planes[0], rleSizes[0], + pDstData, nDstStep, nXDst, nYDst, nWidth, nHeight, 2, vFlip); /* RedPlane */ + + status = planar_decompress_plane_rle(planes[1], rleSizes[1], + pDstData, nDstStep, nXDst, nYDst, nWidth, nHeight, 1, vFlip); /* GreenPlane */ + + status = planar_decompress_plane_rle(planes[2], rleSizes[2], + pDstData, nDstStep, nXDst, nYDst, nWidth, nHeight, 0, vFlip); /* BluePlane */ + + srcp += rleSizes[0] + rleSizes[1] + rleSizes[2] + rleSizes[3]; + } + else /* NoAlpha */ + { + status = planar_decompress_plane_rle(planes[0], rleSizes[0], + pDstData, nDstStep, nXDst, nYDst, nWidth, nHeight, 2, vFlip); /* RedPlane */ + + status = planar_decompress_plane_rle(planes[1], rleSizes[1], + pDstData, nDstStep, nXDst, nYDst, nWidth, nHeight, 1, vFlip); /* GreenPlane */ + + status = planar_decompress_plane_rle(planes[2], rleSizes[2], + pDstData, nDstStep, nXDst, nYDst, nWidth, nHeight, 0, vFlip); /* BluePlane */ + + srcp += rleSizes[0] + rleSizes[1] + rleSizes[2]; + } + } + } + else /* YCoCg */ + { + if (cs) + { + fprintf(stderr, "Chroma subsampling unimplemented\n"); + return -1; + } + + if (!rle) /* RAW */ + { + if (alpha) + { + planar_decompress_planes_raw(planes, nWidth, pDstData, nDstStep, + nXDst, nYDst, nWidth, nHeight, alpha, vFlip); + + srcp += rawSizes[0] + rawSizes[1] + rawSizes[2] + rawSizes[3]; + } + else /* NoAlpha */ + { + planar_decompress_planes_raw(planes, nWidth, pDstData, nDstStep, + nXDst, nYDst, nWidth, nHeight, alpha, vFlip); + + srcp += rawSizes[0] + rawSizes[1] + rawSizes[2]; + } + + if ((SrcSize - (srcp - pSrcData)) == 1) + srcp++; /* pad */ + } + else /* RLE */ + { + if (alpha) + { + status = planar_decompress_plane_rle(planes[3], rleSizes[3], + pDstData, nDstStep, nXDst, nYDst, nWidth, nHeight, 3, vFlip); /* AlphaPlane */ + + status = planar_decompress_plane_rle(planes[0], rleSizes[0], + pDstData, nDstStep, nXDst, nYDst, nWidth, nHeight, 2, vFlip); /* LumaPlane */ + + status = planar_decompress_plane_rle(planes[1], rleSizes[1], + pDstData, nDstStep, nXDst, nYDst, nWidth, nHeight, 1, vFlip); /* OrangeChromaPlane */ + + status = planar_decompress_plane_rle(planes[2], rleSizes[2], + pDstData, nDstStep, nXDst, nYDst, nWidth, nHeight, 0, vFlip); /* GreenChromaPlane */ + + srcp += rleSizes[0] + rleSizes[1] + rleSizes[2] + rleSizes[3]; + } + else /* NoAlpha */ + { + status = planar_decompress_plane_rle(planes[0], rleSizes[0], + pDstData, nDstStep, nXDst, nYDst, nWidth, nHeight, 2, vFlip); /* LumaPlane */ + + status = planar_decompress_plane_rle(planes[1], rleSizes[1], + pDstData, nDstStep, nXDst, nYDst, nWidth, nHeight, 1, vFlip); /* OrangeChromaPlane */ + + status = planar_decompress_plane_rle(planes[2], rleSizes[2], + pDstData, nDstStep, nXDst, nYDst, nWidth, nHeight, 0, vFlip); /* GreenChromaPlane */ + + srcp += rleSizes[0] + rleSizes[1] + rleSizes[2]; + } + } + + prims->YCoCgToRGB_8u_AC4R(pDstData, nDstStep, pDstData, nDstStep, nWidth, nHeight, cll, alpha, FALSE); + } + status = (SrcSize == (srcp - pSrcData)) ? 1 : -1; return status; @@ -781,7 +1005,7 @@ BYTE* freerdp_bitmap_compress_planar(BITMAP_PLANAR_CONTEXT* context, BYTE* data, context->rlePlanes[3] = &context->rlePlanesBuffer[offset]; offset += dstSizes[3]; - //printf("R: [%d/%d] G: [%d/%d] B: [%d/%d]\n", + //DEBUG_MSG("R: [%d/%d] G: [%d/%d] B: [%d/%d]\n", // dstSizes[1], planeSize, dstSizes[2], planeSize, dstSizes[3], planeSize); } } diff --git a/libfreerdp/codec/progressive.c b/libfreerdp/codec/progressive.c index 24d9493eb..69092d161 100644 --- a/libfreerdp/codec/progressive.c +++ b/libfreerdp/codec/progressive.c @@ -25,9 +25,13 @@ #include #include +#include #include #include +#include "rfx_differential.h" +#include "rfx_quantization.h" + const char* progressive_get_block_type_string(UINT16 blockType) { switch (blockType) @@ -72,31 +76,622 @@ const char* progressive_get_block_type_string(UINT16 blockType) return "PROGRESSIVE_WBT_UNKNOWN"; } -int progressive_rfx_decode_component(PROGRESSIVE_CONTEXT* progressive, - RFX_COMPONENT_CODEC_QUANT* quant, const BYTE* data, int length, INT16* buffer) +void progressive_component_codec_quant_read(BYTE* block, RFX_COMPONENT_CODEC_QUANT* quantVal) +{ + quantVal->LL3 = block[0] & 0x0F; + quantVal->HL3 = block[0] >> 4; + quantVal->LH3 = block[1] & 0x0F; + quantVal->HH3 = block[1] >> 4; + quantVal->HL2 = block[2] & 0x0F; + quantVal->LH2 = block[2] >> 4; + quantVal->HH2 = block[3] & 0x0F; + quantVal->HL1 = block[3] >> 4; + quantVal->LH1 = block[4] & 0x0F; + quantVal->HH1 = block[4] >> 4; +} + +void progressive_rfx_quant_ladd(RFX_COMPONENT_CODEC_QUANT* q, int val) +{ + q->HL1 += val; /* HL1 */ + q->LH1 += val; /* LH1 */ + q->HH1 += val; /* HH1 */ + q->HL2 += val; /* HL2 */ + q->LH2 += val; /* LH2 */ + q->HH2 += val; /* HH2 */ + q->HL3 += val; /* HL3 */ + q->LH3 += val; /* LH3 */ + q->HH3 += val; /* HH3 */ + q->LL3 += val; /* LL3 */ +} + +void progressive_rfx_quant_add(RFX_COMPONENT_CODEC_QUANT* q1, RFX_COMPONENT_CODEC_QUANT* q2, RFX_COMPONENT_CODEC_QUANT* dst) +{ + dst->HL1 = q1->HL1 + q2->HL1; /* HL1 */ + dst->LH1 = q1->LH1 + q2->LH1; /* LH1 */ + dst->HH1 = q1->HH1 + q2->HH1; /* HH1 */ + dst->HL2 = q1->HL2 + q2->HL2; /* HL2 */ + dst->LH2 = q1->LH2 + q2->LH2; /* LH2 */ + dst->HH2 = q1->HH2 + q2->HH2; /* HH2 */ + dst->HL3 = q1->HL3 + q2->HL3; /* HL3 */ + dst->LH3 = q1->LH3 + q2->LH3; /* LH3 */ + dst->HH3 = q1->HH3 + q2->HH3; /* HH3 */ + dst->LL3 = q1->LL3 + q2->LL3; /* LL3 */ +} + +void progressive_rfx_quant_lsub(RFX_COMPONENT_CODEC_QUANT* q, int val) +{ + q->HL1 -= val; /* HL1 */ + q->LH1 -= val; /* LH1 */ + q->HH1 -= val; /* HH1 */ + q->HL2 -= val; /* HL2 */ + q->LH2 -= val; /* LH2 */ + q->HH2 -= val; /* HH2 */ + q->HL3 -= val; /* HL3 */ + q->LH3 -= val; /* LH3 */ + q->HH3 -= val; /* HH3 */ + q->LL3 -= val; /* LL3 */ +} + +void progressive_rfx_quant_sub(RFX_COMPONENT_CODEC_QUANT* q1, RFX_COMPONENT_CODEC_QUANT* q2, RFX_COMPONENT_CODEC_QUANT* dst) +{ + dst->HL1 = q1->HL1 - q2->HL1; /* HL1 */ + dst->LH1 = q1->LH1 - q2->LH1; /* LH1 */ + dst->HH1 = q1->HH1 - q2->HH1; /* HH1 */ + dst->HL2 = q1->HL2 - q2->HL2; /* HL2 */ + dst->LH2 = q1->LH2 - q2->LH2; /* LH2 */ + dst->HH2 = q1->HH2 - q2->HH2; /* HH2 */ + dst->HL3 = q1->HL3 - q2->HL3; /* HL3 */ + dst->LH3 = q1->LH3 - q2->LH3; /* LH3 */ + dst->HH3 = q1->HH3 - q2->HH3; /* HH3 */ + dst->LL3 = q1->LL3 - q2->LL3; /* LL3 */ +} + +BOOL progressive_rfx_quant_lcmp_less_equal(RFX_COMPONENT_CODEC_QUANT* q, int val) +{ + if (q->HL1 > val) return FALSE; /* HL1 */ + if (q->LH1 > val) return FALSE; /* LH1 */ + if (q->HH1 > val) return FALSE; /* HH1 */ + if (q->HL2 > val) return FALSE; /* HL2 */ + if (q->LH2 > val) return FALSE; /* LH2 */ + if (q->HH2 > val) return FALSE; /* HH2 */ + if (q->HL3 > val) return FALSE; /* HL3 */ + if (q->LH3 > val) return FALSE; /* LH3 */ + if (q->HH3 > val) return FALSE; /* HH3 */ + if (q->LL3 > val) return FALSE; /* LL3 */ + return TRUE; +} + +BOOL progressive_rfx_quant_cmp_less_equal(RFX_COMPONENT_CODEC_QUANT* q1, RFX_COMPONENT_CODEC_QUANT* q2) +{ + if (q1->HL1 > q2->HL1) return FALSE; /* HL1 */ + if (q1->LH1 > q2->LH1) return FALSE; /* LH1 */ + if (q1->HH1 > q2->HH1) return FALSE; /* HH1 */ + if (q1->HL2 > q2->HL2) return FALSE; /* HL2 */ + if (q1->LH2 > q2->LH2) return FALSE; /* LH2 */ + if (q1->HH2 > q2->HH2) return FALSE; /* HH2 */ + if (q1->HL3 > q2->HL3) return FALSE; /* HL3 */ + if (q1->LH3 > q2->LH3) return FALSE; /* LH3 */ + if (q1->HH3 > q2->HH3) return FALSE; /* HH3 */ + if (q1->LL3 > q2->LL3) return FALSE; /* LL3 */ + return TRUE; +} + +BOOL progressive_rfx_quant_lcmp_greater_equal(RFX_COMPONENT_CODEC_QUANT* q, int val) +{ + if (q->HL1 < val) return FALSE; /* HL1 */ + if (q->LH1 < val) return FALSE; /* LH1 */ + if (q->HH1 < val) return FALSE; /* HH1 */ + if (q->HL2 < val) return FALSE; /* HL2 */ + if (q->LH2 < val) return FALSE; /* LH2 */ + if (q->HH2 < val) return FALSE; /* HH2 */ + if (q->HL3 < val) return FALSE; /* HL3 */ + if (q->LH3 < val) return FALSE; /* LH3 */ + if (q->HH3 < val) return FALSE; /* HH3 */ + if (q->LL3 < val) return FALSE; /* LL3 */ + return TRUE; +} + +BOOL progressive_rfx_quant_cmp_greater_equal(RFX_COMPONENT_CODEC_QUANT* q1, RFX_COMPONENT_CODEC_QUANT* q2) +{ + if (q1->HL1 < q2->HL1) return FALSE; /* HL1 */ + if (q1->LH1 < q2->LH1) return FALSE; /* LH1 */ + if (q1->HH1 < q2->HH1) return FALSE; /* HH1 */ + if (q1->HL2 < q2->HL2) return FALSE; /* HL2 */ + if (q1->LH2 < q2->LH2) return FALSE; /* LH2 */ + if (q1->HH2 < q2->HH2) return FALSE; /* HH2 */ + if (q1->HL3 < q2->HL3) return FALSE; /* HL3 */ + if (q1->LH3 < q2->LH3) return FALSE; /* LH3 */ + if (q1->HH3 < q2->HH3) return FALSE; /* HH3 */ + if (q1->LL3 < q2->LL3) return FALSE; /* LL3 */ + return TRUE; +} + +BOOL progressive_rfx_quant_cmp_equal(RFX_COMPONENT_CODEC_QUANT* q1, RFX_COMPONENT_CODEC_QUANT* q2) +{ + if (q1->HL1 != q2->HL1) return FALSE; /* HL1 */ + if (q1->LH1 != q2->LH1) return FALSE; /* LH1 */ + if (q1->HH1 != q2->HH1) return FALSE; /* HH1 */ + if (q1->HL2 != q2->HL2) return FALSE; /* HL2 */ + if (q1->LH2 != q2->LH2) return FALSE; /* LH2 */ + if (q1->HH2 != q2->HH2) return FALSE; /* HH2 */ + if (q1->HL3 != q2->HL3) return FALSE; /* HL3 */ + if (q1->LH3 != q2->LH3) return FALSE; /* LH3 */ + if (q1->HH3 != q2->HH3) return FALSE; /* HH3 */ + if (q1->LL3 != q2->LL3) return FALSE; /* LL3 */ + return TRUE; +} + +int progressive_set_surface_data(PROGRESSIVE_CONTEXT* progressive, UINT16 surfaceId, void* pData) +{ + ULONG_PTR key; + + key = ((ULONG_PTR) surfaceId) + 1; + + if (pData) + HashTable_Add(progressive->SurfaceContexts, (void*) key, pData); + else + HashTable_Remove(progressive->SurfaceContexts, (void*) key); + + return 1; +} + +void* progressive_get_surface_data(PROGRESSIVE_CONTEXT* progressive, UINT16 surfaceId) +{ + ULONG_PTR key; + void* pData = NULL; + + key = ((ULONG_PTR) surfaceId) + 1; + + pData = HashTable_GetItemValue(progressive->SurfaceContexts, (void*) key); + + return pData; +} + +int progressive_create_surface_context(PROGRESSIVE_CONTEXT* progressive, UINT16 surfaceId, UINT32 width, UINT32 height) +{ + PROGRESSIVE_SURFACE_CONTEXT* surface; + + surface = (PROGRESSIVE_SURFACE_CONTEXT*) progressive_get_surface_data(progressive, surfaceId); + + if (!surface) + { + surface = (PROGRESSIVE_SURFACE_CONTEXT*) malloc(sizeof(PROGRESSIVE_SURFACE_CONTEXT)); + + if (!surface) + return -1; + + surface->id = surfaceId; + surface->width = width; + surface->height = height; + surface->gridWidth = (width + (width % 64)) / 64; + surface->gridHeight = (height + (height % 64)) / 64; + surface->gridSize = surface->gridWidth * surface->gridHeight; + + surface->tiles = (RFX_PROGRESSIVE_TILE*) calloc(surface->gridSize, sizeof(RFX_PROGRESSIVE_TILE)); + + if (!surface->tiles) + return -1; + + progressive_set_surface_data(progressive, surfaceId, (void*) surface); + } + + return 1; +} + +int progressive_delete_surface_context(PROGRESSIVE_CONTEXT* progressive, UINT16 surfaceId) +{ + PROGRESSIVE_SURFACE_CONTEXT* surface; + + surface = (PROGRESSIVE_SURFACE_CONTEXT*) progressive_get_surface_data(progressive, surfaceId); + + if (surface) + { + progressive_set_surface_data(progressive, surfaceId, NULL); + + free(surface->tiles); + free(surface); + } + + return 1; +} + +/* + * Band Offset Dimensions Size + * + * HL1 0 31x33 1023 + * LH1 1023 33x31 1023 + * HH1 2046 31x31 961 + * + * HL2 3007 16x17 272 + * LH2 3279 17x16 272 + * HH2 3551 16x16 256 + * + * HL3 3807 8x9 72 + * LH3 3879 9x8 72 + * HH3 3951 8x8 64 + * + * LL3 4015 9x9 81 + */ + +static void progressive_rfx_idwt_x(INT16* pLowBand, int nLowStep, INT16* pHighBand, int nHighStep, + INT16* pDstBand, int nDstStep, int nLowCount, int nHighCount, int nDstCount) +{ + int i, j; + INT16 L0; + INT16 H0, H1; + INT16 X0, X1, X2; + INT16 *pL, *pH, *pX; + + for (i = 0; i < nDstCount; i++) + { + pL = pLowBand; + pH = pHighBand; + pX = pDstBand; + + H0 = *pH; + pH++; + + L0 = *pL; + pL++; + + X0 = L0 - H0; + X2 = L0 - H0; + + for (j = 0; j < (nHighCount - 1); j++) + { + H1 = *pH; + pH++; + + L0 = *pL; + pL++; + + X2 = L0 - ((H0 + H1) / 2); + X1 = ((X0 + X2) / 2) + (2 * H0); + + pX[0] = X0; + pX[1] = X1; + pX += 2; + + X0 = X2; + H0 = H1; + } + + if (nLowCount <= (nHighCount + 1)) + { + if (nLowCount <= nHighCount) + { + pX[0] = X2; + pX[1] = X2 + (2 * H0); + } + else + { + L0 = *pL; + pL++; + + X0 = L0 - H0; + + pX[0] = X2; + pX[1] = ((X0 + X2) / 2) + (2 * H0); + pX[2] = X0; + } + } + else + { + L0 = *pL; + pL++; + + X0 = L0 - (H0 / 2); + + pX[0] = X2; + pX[1] = ((X0 + X2) / 2) + (2 * H0); + pX[2] = X0; + + L0 = *pL; + pL++; + + pX[3] = (X0 + L0) / 2; + } + + pLowBand += nLowStep; + pHighBand += nHighStep; + pDstBand += nDstStep; + } +} + +static void progressive_rfx_idwt_y(INT16* pLowBand, int nLowStep, INT16* pHighBand, int nHighStep, + INT16* pDstBand, int nDstStep, int nLowCount, int nHighCount, int nDstCount) +{ + int i, j; + INT16 L0; + INT16 H0, H1; + INT16 X0, X1, X2; + INT16 *pL, *pH, *pX; + + for (i = 0; i < nDstCount; i++) + { + pL = pLowBand; + pH = pHighBand; + pX = pDstBand; + + H0 = *pH; + pH += nHighStep; + + L0 = *pL; + pL += nLowStep; + + X0 = L0 - H0; + X2 = L0 - H0; + + for (j = 0; j < (nHighCount - 1); j++) + { + H1 = *pH; + pH += nHighStep; + + L0 = *pL; + pL += nLowStep; + + X2 = L0 - ((H0 + H1) / 2); + X1 = ((X0 + X2) / 2) + (2 * H0); + + *pX = X0; + pX += nDstStep; + + *pX = X1; + pX += nDstStep; + + X0 = X2; + H0 = H1; + } + + if (nLowCount <= (nHighCount + 1)) + { + if (nLowCount <= nHighCount) + { + *pX = X2; + pX += nDstStep; + + *pX = X2 + (2 * H0); + pX += nDstStep; + } + else + { + L0 = *pL; + pL += nLowStep; + + X0 = L0 - H0; + + *pX = X2; + pX += nDstStep; + + *pX = ((X0 + X2) / 2) + (2 * H0); + pX += nDstStep; + + *pX = X0; + pX += nDstStep; + } + } + else + { + L0 = *pL; + pL += nLowStep; + + X0 = L0 - (H0 / 2); + + *pX = X2; + pX += nDstStep; + + *pX = ((X0 + X2) / 2) + (2 * H0); + pX += nDstStep; + + *pX = X0; + pX += nDstStep; + + L0 = *pL; + pL += nLowStep; + + *pX = (X0 + L0) / 2; + pX += nDstStep; + } + + pLowBand++; + pHighBand++; + pDstBand++; + } +} + +static int progressive_rfx_get_band_l_count(int level) +{ + return (64 >> level) + 1; +} + +static int progressive_rfx_get_band_h_count(int level) +{ + if (level == 1) + return (64 >> 1) - 1; + else + return (64 + (1 << (level - 1))) >> level; +} + +static void progressive_rfx_dwt_2d_decode_block(INT16* buffer, INT16* temp, int level) +{ + int offset; + int nBandL; + int nBandH; + int nDstStepX; + int nDstStepY; + INT16 *HL, *LH; + INT16 *HH, *LL; + INT16 *L, *H, *LLx; + INT16* pLowBand[3]; + INT16* pHighBand[3]; + INT16* pDstBand[3]; + int nLowStep[3]; + int nHighStep[3]; + int nDstStep[3]; + int nLowCount[3]; + int nHighCount[3]; + int nDstCount[3]; + + nBandL = progressive_rfx_get_band_l_count(level); + nBandH = progressive_rfx_get_band_h_count(level); + + offset = 0; + + HL = &buffer[offset]; + offset += (nBandH * nBandL); + + LH = &buffer[offset]; + offset += (nBandL * nBandH); + + HH = &buffer[offset]; + offset += (nBandH * nBandH); + + LL = &buffer[offset]; + offset += (nBandL * nBandL); + + nDstStepX = (nBandL + nBandH); + nDstStepY = (nBandL + nBandH); + + offset = 0; + + L = &temp[offset]; + offset += (nBandL * nDstStepX); + + H = &temp[offset]; + offset += (nBandH * nDstStepX); + + LLx = &buffer[0]; + + /* horizontal (LL + HL -> L) */ + + pLowBand[0] = LL; + nLowStep[0] = nBandL; + pHighBand[0] = HL; + nHighStep[0] = nBandH; + pDstBand[0] = L; + nDstStep[0] = nDstStepX; + nLowCount[0] = nBandL; + nHighCount[0] = nBandH; + nDstCount[0] = nBandL; + + progressive_rfx_idwt_x(pLowBand[0], nLowStep[0], pHighBand[0], nHighStep[0], pDstBand[0], nDstStep[0], nLowCount[0], nHighCount[0], nDstCount[0]); + + /* horizontal (LH + HH -> H) */ + + pLowBand[1] = LH; + nLowStep[1] = nBandL; + pHighBand[1] = HH; + nHighStep[1] = nBandH; + pDstBand[1] = H; + nDstStep[1] = nDstStepX; + nLowCount[1] = nBandL; + nHighCount[1] = nBandH; + nDstCount[1] = nBandH; + + progressive_rfx_idwt_x(pLowBand[1], nLowStep[1], pHighBand[1], nHighStep[1], pDstBand[1], nDstStep[1], nLowCount[1], nHighCount[1], nDstCount[1]); + + /* vertical (L + H -> LL) */ + + pLowBand[2] = pDstBand[0]; + nLowStep[2] = nDstStep[0]; + pHighBand[2] = pDstBand[1]; + nHighStep[2] = nDstStep[1]; + pDstBand[2] = LLx; + nDstStep[2] = nDstStepY; + nLowCount[2] = nBandL; + nHighCount[2] = nBandH; + nDstCount[2] = nBandL + nBandH; + + progressive_rfx_idwt_y(pLowBand[2], nLowStep[2], pHighBand[2], nHighStep[2], pDstBand[2], nDstStep[2], nLowCount[2], nHighCount[2], nDstCount[2]); +} + +void progressive_rfx_dwt_2d_decode(INT16* buffer, INT16* temp, INT16* current, INT16* sign, BOOL diff) +{ + const primitives_t* prims = primitives_get(); + + if (diff) + prims->add_16s(buffer, current, buffer, 4096); + + CopyMemory(current, buffer, 4096 * 2); + + progressive_rfx_dwt_2d_decode_block(&buffer[3807], temp, 3); + progressive_rfx_dwt_2d_decode_block(&buffer[3007], temp, 2); + progressive_rfx_dwt_2d_decode_block(&buffer[0], temp, 1); +} + +void progressive_rfx_decode_block(const primitives_t* prims, INT16* buffer, int length, UINT32 shift) +{ + if (!shift) + return; + + prims->lShiftC_16s(buffer, shift, buffer, length); +} + +int progressive_rfx_decode_component(PROGRESSIVE_CONTEXT* progressive, RFX_COMPONENT_CODEC_QUANT* shift, + const BYTE* data, int length, INT16* buffer, INT16* current, INT16* sign, BOOL diff) { int status; + INT16* temp; + const primitives_t* prims = primitives_get(); status = rfx_rlgr_decode(data, length, buffer, 4096, 1); if (status < 0) return status; + CopyMemory(sign, buffer, 4096 * 2); + + rfx_differential_decode(&buffer[4015], 81); /* LL3 */ + + progressive_rfx_decode_block(prims, &buffer[0], 1023, shift->HL1); /* HL1 */ + progressive_rfx_decode_block(prims, &buffer[1023], 1023, shift->LH1); /* LH1 */ + progressive_rfx_decode_block(prims, &buffer[2046], 961, shift->HH1); /* HH1 */ + progressive_rfx_decode_block(prims, &buffer[3007], 272, shift->HL2); /* HL2 */ + progressive_rfx_decode_block(prims, &buffer[3279], 272, shift->LH2); /* LH2 */ + progressive_rfx_decode_block(prims, &buffer[3551], 256, shift->HH2); /* HH2 */ + progressive_rfx_decode_block(prims, &buffer[3807], 72, shift->HL3); /* HL3 */ + progressive_rfx_decode_block(prims, &buffer[3879], 72, shift->LH3); /* LH3 */ + progressive_rfx_decode_block(prims, &buffer[3951], 64, shift->HH3); /* HH3 */ + progressive_rfx_decode_block(prims, &buffer[4015], 81, shift->LL3); /* LL3 */ + + temp = (INT16*) BufferPool_Take(progressive->bufferPool, -1); /* DWT buffer */ + + progressive_rfx_dwt_2d_decode(buffer, temp, current, sign, diff); + + BufferPool_Return(progressive->bufferPool, temp); + return 1; } int progressive_decompress_tile_first(PROGRESSIVE_CONTEXT* progressive, RFX_PROGRESSIVE_TILE* tile) { + BOOL diff; BYTE* pBuffer; + INT16* pSign[3]; INT16* pSrcDst[3]; + INT16* pCurrent[3]; PROGRESSIVE_BLOCK_REGION* region; + RFX_COMPONENT_CODEC_QUANT shiftY; + RFX_COMPONENT_CODEC_QUANT shiftCb; + RFX_COMPONENT_CODEC_QUANT shiftCr; RFX_COMPONENT_CODEC_QUANT* quantY; RFX_COMPONENT_CODEC_QUANT* quantCb; RFX_COMPONENT_CODEC_QUANT* quantCr; + RFX_COMPONENT_CODEC_QUANT* quantProgY; + RFX_COMPONENT_CODEC_QUANT* quantProgCb; + RFX_COMPONENT_CODEC_QUANT* quantProgCr; RFX_PROGRESSIVE_CODEC_QUANT* quantProgVal; + static const prim_size_t roi_64x64 = { 64, 64 }; + const primitives_t* prims = primitives_get(); - printf("ProgressiveTileFirst: quantIdx Y: %d Cb: %d Cr: %d xIdx: %d yIdx: %d flags: %d quality: %d yLen: %d cbLen: %d crLen: %d tailLen: %d\n", + tile->pass = 1; + + diff = tile->flags & RFX_TILE_DIFFERENCE; + +#if 0 + printf("ProgressiveTileFirst: quantIdx Y: %d Cb: %d Cr: %d xIdx: %d yIdx: %d flags: 0x%02X quality: %d yLen: %d cbLen: %d crLen: %d tailLen: %d\n", tile->quantIdxY, tile->quantIdxCb, tile->quantIdxCr, tile->xIdx, tile->yIdx, tile->flags, tile->quality, tile->yLen, tile->cbLen, tile->crLen, tile->tailLen); +#endif region = &(progressive->region); @@ -127,30 +722,368 @@ int progressive_decompress_tile_first(PROGRESSIVE_CONTEXT* progressive, RFX_PROG quantProgVal = &(region->quantProgVals[tile->quality]); } + quantProgY = &(quantProgVal->yQuantValues); + quantProgCb = &(quantProgVal->cbQuantValues); + quantProgCr = &(quantProgVal->crQuantValues); + + CopyMemory(&(tile->yQuant), quantY, sizeof(RFX_COMPONENT_CODEC_QUANT)); + CopyMemory(&(tile->cbQuant), quantCb, sizeof(RFX_COMPONENT_CODEC_QUANT)); + CopyMemory(&(tile->crQuant), quantCr, sizeof(RFX_COMPONENT_CODEC_QUANT)); + + CopyMemory(&(tile->yProgQuant), quantProgY, sizeof(RFX_COMPONENT_CODEC_QUANT)); + CopyMemory(&(tile->cbProgQuant), quantProgCb, sizeof(RFX_COMPONENT_CODEC_QUANT)); + CopyMemory(&(tile->crProgQuant), quantProgCr, sizeof(RFX_COMPONENT_CODEC_QUANT)); + + progressive_rfx_quant_add(quantY, quantProgY, &(tile->yBitPos)); + progressive_rfx_quant_add(quantCb, quantProgCb, &(tile->cbBitPos)); + progressive_rfx_quant_add(quantCr, quantProgCr, &(tile->crBitPos)); + + progressive_rfx_quant_add(quantY, quantProgY, &shiftY); + progressive_rfx_quant_lsub(&shiftY, 1); /* -6 + 5 = -1 */ + progressive_rfx_quant_add(quantCb, quantProgCb, &shiftCb); + progressive_rfx_quant_lsub(&shiftCb, 1); /* -6 + 5 = -1 */ + progressive_rfx_quant_add(quantCr, quantProgCr, &shiftCr); + progressive_rfx_quant_lsub(&shiftCr, 1); /* -6 + 5 = -1 */ + + if (!tile->data) + { + tile->data = (BYTE*) _aligned_malloc(64 * 64 * 4, 16); + } + + if (!tile->sign) + { + tile->sign = (BYTE*) _aligned_malloc((8192 + 32) * 3, 16); + } + + if (!tile->current) + { + tile->current = (BYTE*) _aligned_malloc((8192 + 32) * 3, 16); + } + + pBuffer = tile->sign; + pSign[0] = (INT16*)((BYTE*)(&pBuffer[((8192 + 32) * 0) + 16])); /* Y/R buffer */ + pSign[1] = (INT16*)((BYTE*)(&pBuffer[((8192 + 32) * 1) + 16])); /* Cb/G buffer */ + pSign[2] = (INT16*)((BYTE*)(&pBuffer[((8192 + 32) * 2) + 16])); /* Cr/B buffer */ + + pBuffer = tile->current; + pCurrent[0] = (INT16*)((BYTE*)(&pBuffer[((8192 + 32) * 0) + 16])); /* Y/R buffer */ + pCurrent[1] = (INT16*)((BYTE*)(&pBuffer[((8192 + 32) * 1) + 16])); /* Cb/G buffer */ + pCurrent[2] = (INT16*)((BYTE*)(&pBuffer[((8192 + 32) * 2) + 16])); /* Cr/B buffer */ + pBuffer = (BYTE*) BufferPool_Take(progressive->bufferPool, -1); pSrcDst[0] = (INT16*)((BYTE*)(&pBuffer[((8192 + 32) * 0) + 16])); /* Y/R buffer */ pSrcDst[1] = (INT16*)((BYTE*)(&pBuffer[((8192 + 32) * 1) + 16])); /* Cb/G buffer */ pSrcDst[2] = (INT16*)((BYTE*)(&pBuffer[((8192 + 32) * 2) + 16])); /* Cr/B buffer */ - progressive_rfx_decode_component(progressive, quantY, tile->yData, tile->yLen, pSrcDst[0]); /* Y */ - progressive_rfx_decode_component(progressive, quantCb, tile->cbData, tile->cbLen, pSrcDst[1]); /* Cb */ - progressive_rfx_decode_component(progressive, quantCr, tile->crData, tile->crLen, pSrcDst[2]); /* Cr */ + progressive_rfx_decode_component(progressive, &shiftY, tile->yData, tile->yLen, pSrcDst[0], pCurrent[0], pSign[0], diff); /* Y */ + progressive_rfx_decode_component(progressive, &shiftCb, tile->cbData, tile->cbLen, pSrcDst[1], pCurrent[1], pSign[1], diff); /* Cb */ + progressive_rfx_decode_component(progressive, &shiftCr, tile->crData, tile->crLen, pSrcDst[2], pCurrent[2], pSign[2], diff); /* Cr */ + + prims->yCbCrToRGB_16s8u_P3AC4R((const INT16**) pSrcDst, 64 * 2, + tile->data, 64 * 4, &roi_64x64); BufferPool_Return(progressive->bufferPool, pBuffer); + //WLog_Image(progressive->log, WLOG_TRACE, tile->data, 64, 64, 32); + + return 1; +} + +struct _RFX_PROGRESSIVE_UPGRADE_STATE +{ + BOOL nonLL; + wBitStream* srl; + wBitStream* raw; + + /* SRL state */ + + int kp; + int nz; + BOOL mode; +}; +typedef struct _RFX_PROGRESSIVE_UPGRADE_STATE RFX_PROGRESSIVE_UPGRADE_STATE; + +INT16 progressive_rfx_srl_read(RFX_PROGRESSIVE_UPGRADE_STATE* state, UINT32 numBits) +{ + int k; + UINT32 bit; + UINT32 max; + UINT32 mag; + UINT32 sign; + wBitStream* bs = state->srl; + + if (state->nz) + { + state->nz--; + return 0; + } + + k = state->kp / 8; + + if (!state->mode) + { + /* zero encoding */ + + bit = (bs->accumulator & 0x80000000) ? 1 : 0; + BitStream_Shift(bs, 1); + + if (!bit) + { + /* '0' bit, nz >= (1 << k), nz = (1 << k) */ + + state->nz = (1 << k); + + state->kp += 4; + + if (state->kp > 80) + state->kp = 80; + + state->nz--; + return 0; + } + else + { + /* '1' bit, nz < (1 << k), nz = next k bits */ + + state->nz = 0; + state->mode = 1; /* unary encoding is next */ + + if (k) + { + bs->mask = ((1 << k) - 1); + state->nz = ((bs->accumulator >> (32 - k)) & bs->mask); + BitStream_Shift(bs, k); + } + + if (state->nz) + { + state->nz--; + return 0; + } + } + } + + state->mode = 0; /* zero encoding is next */ + + /* unary encoding */ + + /* read sign bit */ + + sign = (bs->accumulator & 0x80000000) ? 1 : 0; + BitStream_Shift(bs, 1); + + state->kp -= 6; + + if (state->kp < 0) + state->kp = 0; + + if (numBits == 1) + return sign ? -1 : 1; + + mag = 1; + max = (1 << numBits) - 1; + + while (mag < max) + { + bit = (bs->accumulator & 0x80000000) ? 1 : 0; + BitStream_Shift(bs, 1); + + if (bit) + break; + + mag++; + } + + return sign ? -mag : mag; +} + +int progressive_rfx_upgrade_block(RFX_PROGRESSIVE_UPGRADE_STATE* state, INT16* buffer, + INT16* sign, int length, UINT32 shift, UINT32 bitPos, UINT32 numBits) +{ + int pad; + int index; + INT16 input; + wBitStream* srl; + wBitStream* raw; + + if (!numBits) + return 1; + + srl = state->srl; + raw = state->raw; + + if (!state->nonLL) + { + for (index = 0; index < length; index++) + { + raw->mask = ((1 << numBits) - 1); + input = (INT16) ((raw->accumulator >> (32 - numBits)) & raw->mask); + BitStream_Shift(raw, numBits); + + buffer[index] += (input << shift); + } + + /* This is the last band, read padding bits from RAW and SRL bit streams */ + + pad = (raw->position % 8) ? (8 - (raw->position % 8)) : 0; + + if (pad) + BitStream_Shift(raw, pad); + + pad = (srl->position % 8) ? (8 - (srl->position % 8)) : 0; + + if (pad) + BitStream_Shift(srl, pad); + + if (BitStream_GetRemainingLength(srl) == 8) + BitStream_Shift(srl, 8); + + return 1; + } + + for (index = 0; index < length; index++) + { + if (sign[index] > 0) + { + /* sign > 0, read from raw */ + + raw->mask = ((1 << numBits) - 1); + input = (INT16) ((raw->accumulator >> (32 - numBits)) & raw->mask); + BitStream_Shift(raw, numBits); + } + else if (sign[index] < 0) + { + /* sign < 0, read from raw */ + + raw->mask = ((1 << numBits) - 1); + input = (INT16) ((raw->accumulator >> (32 - numBits)) & raw->mask); + BitStream_Shift(raw, numBits); + + input *= -1; + } + else + { + /* sign == 0, read from srl */ + + input = progressive_rfx_srl_read(state, numBits); + } + + buffer[index] += (input << shift); + sign[index] = input; + } + + return 1; +} + +int progressive_rfx_upgrade_component(PROGRESSIVE_CONTEXT* progressive, RFX_COMPONENT_CODEC_QUANT* shift, + RFX_COMPONENT_CODEC_QUANT* bitPos, RFX_COMPONENT_CODEC_QUANT* numBits, INT16* buffer, + INT16* current, INT16* sign, const BYTE* srlData, int srlLen, const BYTE* rawData, int rawLen) +{ + INT16* temp; + int aRawLen; + int aSrlLen; + wBitStream s_srl; + wBitStream s_raw; + RFX_PROGRESSIVE_UPGRADE_STATE state; + + ZeroMemory(&s_srl, sizeof(wBitStream)); + ZeroMemory(&s_raw, sizeof(wBitStream)); + ZeroMemory(&state, sizeof(RFX_PROGRESSIVE_UPGRADE_STATE)); + + state.kp = 8; + state.mode = 0; + state.srl = &s_srl; + state.raw = &s_raw; + + BitStream_Attach(state.srl, srlData, srlLen); + BitStream_Fetch(state.srl); + + BitStream_Attach(state.raw, rawData, rawLen); + BitStream_Fetch(state.raw); + + state.nonLL = TRUE; + progressive_rfx_upgrade_block(&state, ¤t[0], &sign[0], 1023, shift->HL1, bitPos->HL1, numBits->HL1); /* HL1 */ + progressive_rfx_upgrade_block(&state, ¤t[1023], &sign[1023], 1023, shift->LH1, bitPos->LH1, numBits->LH1); /* LH1 */ + progressive_rfx_upgrade_block(&state, ¤t[2046], &sign[2046], 961, shift->HH1, bitPos->HH1, numBits->HH1); /* HH1 */ + progressive_rfx_upgrade_block(&state, ¤t[3007], &sign[3007], 272, shift->HL2, bitPos->HL2, numBits->HL2); /* HL2 */ + progressive_rfx_upgrade_block(&state, ¤t[3279], &sign[3279], 272, shift->LH2, bitPos->LH2, numBits->LH2); /* LH2 */ + progressive_rfx_upgrade_block(&state, ¤t[3551], &sign[3551], 256, shift->HH2, bitPos->HH2, numBits->HH2); /* HH2 */ + progressive_rfx_upgrade_block(&state, ¤t[3807], &sign[3807], 72, shift->HL3, bitPos->HL3, numBits->HL3); /* HL3 */ + progressive_rfx_upgrade_block(&state, ¤t[3879], &sign[3879], 72, shift->LH3, bitPos->LH3, numBits->LH3); /* LH3 */ + progressive_rfx_upgrade_block(&state, ¤t[3951], &sign[3951], 64, shift->HH3, bitPos->HH3, numBits->HH3); /* HH3 */ + + state.nonLL = FALSE; + progressive_rfx_upgrade_block(&state, ¤t[4015], &sign[4015], 81, shift->LL3, bitPos->LL3, numBits->LL3); /* LL3 */ + + aRawLen = (state.raw->position + 7) / 8; + aSrlLen = (state.srl->position + 7) / 8; + + if ((aRawLen != rawLen) || (aSrlLen != srlLen)) + { + int pRawLen = 0; + int pSrlLen = 0; + + if (rawLen) + pRawLen = (int) ((((float) aRawLen) / ((float) rawLen)) * 100.0f); + + if (srlLen) + pSrlLen = (int) ((((float) aSrlLen) / ((float) srlLen)) * 100.0f); + + printf("RAW: %d/%d %d%% (%d/%d:%d)\tSRL: %d/%d %d%% (%d/%d:%d)\n", + aRawLen, rawLen, pRawLen, state.raw->position, rawLen * 8, + (rawLen * 8) - state.raw->position, + aSrlLen, srlLen, pSrlLen, state.srl->position, srlLen * 8, + (srlLen * 8) - state.srl->position); + + return -1; + } + + temp = (INT16*) BufferPool_Take(progressive->bufferPool, -1); /* DWT buffer */ + + CopyMemory(buffer, current, 4096 * 2); + + progressive_rfx_dwt_2d_decode_block(&buffer[3807], temp, 3); + progressive_rfx_dwt_2d_decode_block(&buffer[3007], temp, 2); + progressive_rfx_dwt_2d_decode_block(&buffer[0], temp, 1); + + BufferPool_Return(progressive->bufferPool, temp); + return 1; } int progressive_decompress_tile_upgrade(PROGRESSIVE_CONTEXT* progressive, RFX_PROGRESSIVE_TILE* tile) { + int status; + BYTE* pBuffer; + INT16* pSign[3]; + INT16* pSrcDst[3]; + INT16* pCurrent[3]; PROGRESSIVE_BLOCK_REGION* region; + RFX_COMPONENT_CODEC_QUANT shiftY; + RFX_COMPONENT_CODEC_QUANT shiftCb; + RFX_COMPONENT_CODEC_QUANT shiftCr; + RFX_COMPONENT_CODEC_QUANT yBitPos; + RFX_COMPONENT_CODEC_QUANT cbBitPos; + RFX_COMPONENT_CODEC_QUANT crBitPos; + RFX_COMPONENT_CODEC_QUANT yNumBits; + RFX_COMPONENT_CODEC_QUANT cbNumBits; + RFX_COMPONENT_CODEC_QUANT crNumBits; RFX_COMPONENT_CODEC_QUANT* quantY; RFX_COMPONENT_CODEC_QUANT* quantCb; RFX_COMPONENT_CODEC_QUANT* quantCr; - RFX_PROGRESSIVE_CODEC_QUANT* quantProgVal; + RFX_COMPONENT_CODEC_QUANT* quantProgY; + RFX_COMPONENT_CODEC_QUANT* quantProgCb; + RFX_COMPONENT_CODEC_QUANT* quantProgCr; + RFX_PROGRESSIVE_CODEC_QUANT* quantProg; + static const prim_size_t roi_64x64 = { 64, 64 }; + const primitives_t* prims = primitives_get(); - printf("ProgressiveTileUpgrade: quantIdx Y: %d Cb: %d Cr: %d xIdx: %d yIdx: %d quality: %d ySrlLen: %d yRawLen: %d cbSrlLen: %d cbRawLen: %d crSrlLen: %d crRawLen: %d\n", - tile->quantIdxY, tile->quantIdxCb, tile->quantIdxCr, tile->xIdx, tile->yIdx, tile->quality, tile->ySrlLen, tile->yRawLen, tile->cbSrlLen, tile->cbRawLen, tile->crSrlLen, tile->crRawLen); + tile->pass++; + +#if 0 + printf("ProgressiveTileUpgrade: pass: %d quantIdx Y: %d Cb: %d Cr: %d xIdx: %d yIdx: %d quality: %d ySrlLen: %d yRawLen: %d cbSrlLen: %d cbRawLen: %d crSrlLen: %d crRawLen: %d\n", + tile->pass, tile->quantIdxY, tile->quantIdxCb, tile->quantIdxCr, tile->xIdx, tile->yIdx, tile->quality, tile->ySrlLen, tile->yRawLen, tile->cbSrlLen, tile->cbRawLen, tile->crSrlLen, tile->crRawLen); +#endif region = &(progressive->region); @@ -171,28 +1104,112 @@ int progressive_decompress_tile_upgrade(PROGRESSIVE_CONTEXT* progressive, RFX_PR if (tile->quality == 0xFF) { - quantProgVal = &(progressive->quantProgValFull); + quantProg = &(progressive->quantProgValFull); } else { if (tile->quality >= region->numProgQuant) return -1; - quantProgVal = &(region->quantProgVals[tile->quality]); + quantProg = &(region->quantProgVals[tile->quality]); } + quantProgY = &(quantProg->yQuantValues); + quantProgCb = &(quantProg->cbQuantValues); + quantProgCr = &(quantProg->crQuantValues); + + if (!progressive_rfx_quant_cmp_equal(quantY, &(tile->yQuant))) + printf("warning: non-progressive quantY has changed!\n"); + if (!progressive_rfx_quant_cmp_equal(quantCb, &(tile->cbQuant))) + printf("warning: non-progressive quantCb has changed!\n"); + if (!progressive_rfx_quant_cmp_equal(quantCr, &(tile->crQuant))) + printf("warning: non-progressive quantCr has changed!\n"); + + progressive_rfx_quant_add(quantY, quantProgY, &yBitPos); + progressive_rfx_quant_add(quantCb, quantProgCb, &cbBitPos); + progressive_rfx_quant_add(quantCr, quantProgCr, &crBitPos); + + progressive_rfx_quant_sub(&(tile->yBitPos), &yBitPos, &yNumBits); + progressive_rfx_quant_sub(&(tile->cbBitPos), &cbBitPos, &cbNumBits); + progressive_rfx_quant_sub(&(tile->crBitPos), &crBitPos, &crNumBits); + + progressive_rfx_quant_add(quantY, quantProgY, &shiftY); + progressive_rfx_quant_lsub(&shiftY, 1); /* -6 + 5 = -1 */ + progressive_rfx_quant_add(quantCb, quantProgCb, &shiftCb); + progressive_rfx_quant_lsub(&shiftCb, 1); /* -6 + 5 = -1 */ + progressive_rfx_quant_add(quantCr, quantProgCr, &shiftCr); + progressive_rfx_quant_lsub(&shiftCr, 1); /* -6 + 5 = -1 */ + + CopyMemory(&(tile->yBitPos), &yBitPos, sizeof(RFX_COMPONENT_CODEC_QUANT)); + CopyMemory(&(tile->cbBitPos), &cbBitPos, sizeof(RFX_COMPONENT_CODEC_QUANT)); + CopyMemory(&(tile->crBitPos), &crBitPos, sizeof(RFX_COMPONENT_CODEC_QUANT)); + + CopyMemory(&(tile->yQuant), quantY, sizeof(RFX_COMPONENT_CODEC_QUANT)); + CopyMemory(&(tile->cbQuant), quantCb, sizeof(RFX_COMPONENT_CODEC_QUANT)); + CopyMemory(&(tile->crQuant), quantCr, sizeof(RFX_COMPONENT_CODEC_QUANT)); + + CopyMemory(&(tile->yProgQuant), quantProgY, sizeof(RFX_COMPONENT_CODEC_QUANT)); + CopyMemory(&(tile->cbProgQuant), quantProgCb, sizeof(RFX_COMPONENT_CODEC_QUANT)); + CopyMemory(&(tile->crProgQuant), quantProgCr, sizeof(RFX_COMPONENT_CODEC_QUANT)); + + pBuffer = tile->sign; + pSign[0] = (INT16*)((BYTE*)(&pBuffer[((8192 + 32) * 0) + 16])); /* Y/R buffer */ + pSign[1] = (INT16*)((BYTE*)(&pBuffer[((8192 + 32) * 1) + 16])); /* Cb/G buffer */ + pSign[2] = (INT16*)((BYTE*)(&pBuffer[((8192 + 32) * 2) + 16])); /* Cr/B buffer */ + + pBuffer = tile->current; + pCurrent[0] = (INT16*)((BYTE*)(&pBuffer[((8192 + 32) * 0) + 16])); /* Y/R buffer */ + pCurrent[1] = (INT16*)((BYTE*)(&pBuffer[((8192 + 32) * 1) + 16])); /* Cb/G buffer */ + pCurrent[2] = (INT16*)((BYTE*)(&pBuffer[((8192 + 32) * 2) + 16])); /* Cr/B buffer */ + + pBuffer = (BYTE*) BufferPool_Take(progressive->bufferPool, -1); + pSrcDst[0] = (INT16*)((BYTE*)(&pBuffer[((8192 + 32) * 0) + 16])); /* Y/R buffer */ + pSrcDst[1] = (INT16*)((BYTE*)(&pBuffer[((8192 + 32) * 1) + 16])); /* Cb/G buffer */ + pSrcDst[2] = (INT16*)((BYTE*)(&pBuffer[((8192 + 32) * 2) + 16])); /* Cr/B buffer */ + + status = progressive_rfx_upgrade_component(progressive, &shiftY, quantProgY, &yNumBits, + pSrcDst[0], pCurrent[0], pSign[0], tile->ySrlData, tile->ySrlLen, tile->yRawData, tile->yRawLen); /* Y */ + + if (status < 0) + return -1; + + status = progressive_rfx_upgrade_component(progressive, &shiftCb, quantProgCb, &cbNumBits, + pSrcDst[1], pCurrent[1], pSign[1], tile->cbSrlData, tile->cbSrlLen, tile->cbRawData, tile->cbRawLen); /* Cb */ + + if (status < 0) + return -1; + + status = progressive_rfx_upgrade_component(progressive, &shiftCr, quantProgCr, &crNumBits, + pSrcDst[2], pCurrent[2], pSign[2], tile->crSrlData, tile->crSrlLen, tile->crRawData, tile->crRawLen); /* Cr */ + + if (status < 0) + return -1; + + prims->yCbCrToRGB_16s8u_P3AC4R((const INT16**) pSrcDst, 64 * 2, + tile->data, 64 * 4, &roi_64x64); + + BufferPool_Return(progressive->bufferPool, pBuffer); + + //WLog_Image(progressive->log, WLOG_TRACE, tile->data, 64, 64, 32); + return 1; } -int progressive_process_tiles(PROGRESSIVE_CONTEXT* progressive, BYTE* blocks, UINT32 blocksLen) +int progressive_process_tiles(PROGRESSIVE_CONTEXT* progressive, BYTE* blocks, UINT32 blocksLen, PROGRESSIVE_SURFACE_CONTEXT* surface) { + int status; BYTE* block; + UINT16 xIdx; + UINT16 yIdx; + UINT16 zIdx; UINT16 index; UINT32 boffset; + UINT16 blockType; + UINT32 blockLen; UINT32 count = 0; UINT32 offset = 0; RFX_PROGRESSIVE_TILE* tile; - RFX_PROGRESSIVE_TILE* tiles; + RFX_PROGRESSIVE_TILE** tiles; PROGRESSIVE_BLOCK_REGION* region; region = &(progressive->region); @@ -204,24 +1221,35 @@ int progressive_process_tiles(PROGRESSIVE_CONTEXT* progressive, BYTE* blocks, UI boffset = 0; block = &blocks[offset]; - tile = &tiles[count]; - - tile->blockType = *((UINT16*) &block[boffset + 0]); /* blockType (2 bytes) */ - tile->blockLen = *((UINT32*) &block[boffset + 2]); /* blockLen (4 bytes) */ + blockType = *((UINT16*) &block[boffset + 0]); /* blockType (2 bytes) */ + blockLen = *((UINT32*) &block[boffset + 2]); /* blockLen (4 bytes) */ boffset += 6; - printf("%s\n", progressive_get_block_type_string(tile->blockType)); + //printf("%s\n", progressive_get_block_type_string(blockType)); - if ((blocksLen - offset) < tile->blockLen) + if ((blocksLen - offset) < blockLen) return -1003; - switch (tile->blockType) + switch (blockType) { case PROGRESSIVE_WBT_TILE_SIMPLE: - if ((tile->blockLen - boffset) < 16) + if ((blockLen - boffset) < 16) return -1022; + xIdx = *((UINT16*) &block[boffset + 3]); /* xIdx (2 bytes) */ + yIdx = *((UINT16*) &block[boffset + 5]); /* yIdx (2 bytes) */ + + zIdx = (yIdx * surface->gridWidth) + xIdx; + + if (zIdx >= surface->gridSize) + return -1; + + tiles[count] = tile = &(surface->tiles[zIdx]); + + tile->blockType = blockType; + tile->blockLen = blockLen; + tile->quality = 0xFF; /* simple tiles use no progressive techniques */ tile->quantIdxY = block[boffset + 0]; /* quantIdxY (1 byte) */ @@ -229,7 +1257,7 @@ int progressive_process_tiles(PROGRESSIVE_CONTEXT* progressive, BYTE* blocks, UI tile->quantIdxCr = block[boffset + 2]; /* quantIdxCr (1 byte) */ tile->xIdx = *((UINT16*) &block[boffset + 3]); /* xIdx (2 bytes) */ tile->yIdx = *((UINT16*) &block[boffset + 5]); /* yIdx (2 bytes) */ - tile->flags = block[boffset + 7]; /* flags (1 byte) */ + tile->flags = block[boffset + 7] & 1; /* flags (1 byte) */ tile->yLen = *((UINT16*) &block[boffset + 8]); /* yLen (2 bytes) */ tile->cbLen = *((UINT16*) &block[boffset + 10]); /* cbLen (2 bytes) */ tile->crLen = *((UINT16*) &block[boffset + 12]); /* crLen (2 bytes) */ @@ -260,19 +1288,39 @@ int progressive_process_tiles(PROGRESSIVE_CONTEXT* progressive, BYTE* blocks, UI tile->tailData = &block[boffset]; boffset += tile->tailLen; + tile->width = 64; + tile->height = 64; + tile->x = tile->xIdx * 64; + tile->y = tile->yIdx * 64; + + tile->flags &= 1; + break; case PROGRESSIVE_WBT_TILE_FIRST: - if ((tile->blockLen - boffset) < 17) + if ((blockLen - boffset) < 17) return -1027; + xIdx = *((UINT16*) &block[boffset + 3]); /* xIdx (2 bytes) */ + yIdx = *((UINT16*) &block[boffset + 5]); /* yIdx (2 bytes) */ + + zIdx = (yIdx * surface->gridWidth) + xIdx; + + if (zIdx >= surface->gridSize) + return -1; + + tiles[count] = tile = &(surface->tiles[zIdx]); + + tile->blockType = blockType; + tile->blockLen = blockLen; + tile->quantIdxY = block[boffset + 0]; /* quantIdxY (1 byte) */ tile->quantIdxCb = block[boffset + 1]; /* quantIdxCb (1 byte) */ tile->quantIdxCr = block[boffset + 2]; /* quantIdxCr (1 byte) */ tile->xIdx = *((UINT16*) &block[boffset + 3]); /* xIdx (2 bytes) */ tile->yIdx = *((UINT16*) &block[boffset + 5]); /* yIdx (2 bytes) */ - tile->flags = block[boffset + 7]; /* flags (1 byte) */ + tile->flags = block[boffset + 7] & 1; /* flags (1 byte) */ tile->quality = block[boffset + 8]; /* quality (1 byte) */ tile->yLen = *((UINT16*) &block[boffset + 9]); /* yLen (2 bytes) */ tile->cbLen = *((UINT16*) &block[boffset + 11]); /* cbLen (2 bytes) */ @@ -304,13 +1352,33 @@ int progressive_process_tiles(PROGRESSIVE_CONTEXT* progressive, BYTE* blocks, UI tile->tailData = &block[boffset]; boffset += tile->tailLen; + tile->width = 64; + tile->height = 64; + tile->x = tile->xIdx * 64; + tile->y = tile->yIdx * 64; + break; case PROGRESSIVE_WBT_TILE_UPGRADE: - if ((tile->blockLen - boffset) < 20) + if ((blockLen - boffset) < 20) return -1032; + xIdx = *((UINT16*) &block[boffset + 3]); /* xIdx (2 bytes) */ + yIdx = *((UINT16*) &block[boffset + 5]); /* yIdx (2 bytes) */ + + zIdx = (yIdx * surface->gridWidth) + xIdx; + + if (zIdx >= surface->gridSize) + return -1; + + tiles[count] = tile = &(surface->tiles[zIdx]); + + tile->blockType = blockType; + tile->blockLen = blockLen; + + tile->flags = 0; + tile->quantIdxY = block[boffset + 0]; /* quantIdxY (1 byte) */ tile->quantIdxCb = block[boffset + 1]; /* quantIdxCb (1 byte) */ tile->quantIdxCr = block[boffset + 2]; /* quantIdxCr (1 byte) */ @@ -361,6 +1429,11 @@ int progressive_process_tiles(PROGRESSIVE_CONTEXT* progressive, BYTE* blocks, UI tile->crRawData = &block[boffset]; boffset += tile->crRawLen; + tile->width = 64; + tile->height = 64; + tile->x = tile->xIdx * 64; + tile->y = tile->yIdx * 64; + break; default: @@ -368,10 +1441,10 @@ int progressive_process_tiles(PROGRESSIVE_CONTEXT* progressive, BYTE* blocks, UI break; } - if (boffset != tile->blockLen) + if (boffset != blockLen) return -1040; - offset += tile->blockLen; + offset += blockLen; count++; } @@ -380,26 +1453,29 @@ int progressive_process_tiles(PROGRESSIVE_CONTEXT* progressive, BYTE* blocks, UI for (index = 0; index < region->numTiles; index++) { - tile = &tiles[index]; + tile = tiles[index]; switch (tile->blockType) { case PROGRESSIVE_WBT_TILE_SIMPLE: case PROGRESSIVE_WBT_TILE_FIRST: - progressive_decompress_tile_first(progressive, tile); + status = progressive_decompress_tile_first(progressive, tile); break; case PROGRESSIVE_WBT_TILE_UPGRADE: - progressive_decompress_tile_upgrade(progressive, tile); + status = progressive_decompress_tile_upgrade(progressive, tile); break; } + + if (status < 0) + return -1; } return (int) offset; } int progressive_decompress(PROGRESSIVE_CONTEXT* progressive, BYTE* pSrcData, UINT32 SrcSize, - BYTE** ppDstData, DWORD DstFormat, int nDstStep, int nXDst, int nYDst, int nWidth, int nHeight) + BYTE** ppDstData, DWORD DstFormat, int nDstStep, int nXDst, int nYDst, int nWidth, int nHeight, UINT16 surfaceId) { int status; BYTE* block; @@ -417,9 +1493,15 @@ int progressive_decompress(PROGRESSIVE_CONTEXT* progressive, BYTE* pSrcData, UIN PROGRESSIVE_BLOCK_CONTEXT context; PROGRESSIVE_BLOCK_FRAME_BEGIN frameBegin; PROGRESSIVE_BLOCK_FRAME_END frameEnd; + PROGRESSIVE_SURFACE_CONTEXT* surface; RFX_COMPONENT_CODEC_QUANT* quantVal; RFX_PROGRESSIVE_CODEC_QUANT* quantProgVal; + surface = (PROGRESSIVE_SURFACE_CONTEXT*) progressive_get_surface_data(progressive, surfaceId); + + if (!surface) + return -1001; + blocks = pSrcData; blocksLen = SrcSize; @@ -434,7 +1516,7 @@ int progressive_decompress(PROGRESSIVE_CONTEXT* progressive, BYTE* pSrcData, UIN blockLen = *((UINT32*) &block[boffset + 2]); /* blockLen (4 bytes) */ boffset += 6; - printf("%s\n", progressive_get_block_type_string(blockType)); + //printf("%s\n", progressive_get_block_type_string(blockType)); if ((blocksLen - offset) < blockLen) return -1003; @@ -577,17 +1659,14 @@ int progressive_decompress(PROGRESSIVE_CONTEXT* progressive, BYTE* pSrcData, UIN for (index = 0; index < region->numQuant; index++) { quantVal = &(region->quantVals[index]); - quantVal->LL3 = block[boffset + 0] & 0x0F; - quantVal->HL3 = block[boffset + 0] >> 4; - quantVal->LH3 = block[boffset + 1] & 0x0F; - quantVal->HH3 = block[boffset + 1] >> 4; - quantVal->HL2 = block[boffset + 2] & 0x0F; - quantVal->LH2 = block[boffset + 2] >> 4; - quantVal->HH2 = block[boffset + 3] & 0x0F; - quantVal->HL1 = block[boffset + 3] >> 4; - quantVal->LH1 = block[boffset + 4] & 0x0F; - quantVal->HH1 = block[boffset + 4] >> 4; + progressive_component_codec_quant_read(&block[boffset], quantVal); boffset += 5; + + if (!progressive_rfx_quant_lcmp_greater_equal(quantVal, 6)) + return -1; + + if (!progressive_rfx_quant_lcmp_less_equal(quantVal, 15)) + return -1; } if ((blockLen - boffset) < (region->numProgQuant * 16)) @@ -609,9 +1688,10 @@ int progressive_decompress(PROGRESSIVE_CONTEXT* progressive, BYTE* pSrcData, UIN { quantProgVal = &(region->quantProgVals[index]); quantProgVal->quality = block[boffset + 0]; - CopyMemory(quantProgVal->yQuantValues, &block[boffset + 1], 5); - CopyMemory(quantProgVal->cbQuantValues, &block[boffset + 6], 5); - CopyMemory(quantProgVal->crQuantValues, &block[boffset + 11], 5); + + progressive_component_codec_quant_read(&block[boffset + 1], &(quantProgVal->yQuantValues)); + progressive_component_codec_quant_read(&block[boffset + 6], &(quantProgVal->cbQuantValues)); + progressive_component_codec_quant_read(&block[boffset + 11], &(quantProgVal->crQuantValues)); boffset += 16; } @@ -620,8 +1700,8 @@ int progressive_decompress(PROGRESSIVE_CONTEXT* progressive, BYTE* pSrcData, UIN if (region->numTiles > progressive->cTiles) { - progressive->tiles = (RFX_PROGRESSIVE_TILE*) realloc(progressive->tiles, - region->numTiles * sizeof(RFX_PROGRESSIVE_TILE)); + progressive->tiles = (RFX_PROGRESSIVE_TILE**) realloc(progressive->tiles, + region->numTiles * sizeof(RFX_PROGRESSIVE_TILE*)); progressive->cTiles = region->numTiles; } @@ -630,10 +1710,10 @@ int progressive_decompress(PROGRESSIVE_CONTEXT* progressive, BYTE* pSrcData, UIN if (!region->tiles) return -1; - printf("numRects: %d numTiles: %d numQuant: %d numProgQuant: %d\n", - region->numRects, region->numTiles, region->numQuant, region->numProgQuant); + //printf("numRects: %d numTiles: %d numQuant: %d numProgQuant: %d\n", + // region->numRects, region->numTiles, region->numQuant, region->numProgQuant); - status = progressive_process_tiles(progressive, &block[boffset], region->tileDataSize); + status = progressive_process_tiles(progressive, &block[boffset], region->tileDataSize, surface); if (status < 0) return status; @@ -680,6 +1760,8 @@ PROGRESSIVE_CONTEXT* progressive_context_new(BOOL Compressor) { progressive->Compressor = Compressor; + progressive->log = WLog_Get("com.freerdp.codec.progressive"); + progressive->bufferPool = BufferPool_New(TRUE, (8192 + 32) * 3, 16); progressive->cRects = 64; @@ -689,7 +1771,7 @@ PROGRESSIVE_CONTEXT* progressive_context_new(BOOL Compressor) return NULL; progressive->cTiles = 64; - progressive->tiles = (RFX_PROGRESSIVE_TILE*) malloc(progressive->cTiles * sizeof(RFX_PROGRESSIVE_TILE)); + progressive->tiles = (RFX_PROGRESSIVE_TILE**) malloc(progressive->cTiles * sizeof(RFX_PROGRESSIVE_TILE*)); if (!progressive->tiles) return NULL; @@ -709,6 +1791,8 @@ PROGRESSIVE_CONTEXT* progressive_context_new(BOOL Compressor) ZeroMemory(&(progressive->quantProgValFull), sizeof(RFX_PROGRESSIVE_CODEC_QUANT)); progressive->quantProgValFull.quality = 100; + progressive->SurfaceContexts = HashTable_New(TRUE); + progressive_context_reset(progressive); } @@ -727,6 +1811,8 @@ void progressive_context_free(PROGRESSIVE_CONTEXT* progressive) free(progressive->quantVals); free(progressive->quantProgVals); + HashTable_Free(progressive->SurfaceContexts); + free(progressive); } diff --git a/libfreerdp/codec/region.c b/libfreerdp/codec/region.c index b8a24e136..b2afb0de5 100644 --- a/libfreerdp/codec/region.c +++ b/libfreerdp/codec/region.c @@ -19,6 +19,7 @@ #include #include +#include #include /* @@ -219,20 +220,20 @@ void region16_print(const REGION16 *region) int currentBandY = -1; rects = region16_rects(region, &nbRects); - fprintf(stderr, "nrects=%d", nbRects); + DEBUG_WARN( "nrects=%d", nbRects); for (i = 0; i < nbRects; i++, rects++) { if (rects->top != currentBandY) { currentBandY = rects->top; - fprintf(stderr, "\nband %d: ", currentBandY); + DEBUG_WARN( "\nband %d: ", currentBandY); } - fprintf(stderr, "(%d,%d-%d,%d)", rects->left, rects->top, rects->right, rects->bottom); + DEBUG_WARN( "(%d,%d-%d,%d)", rects->left, rects->top, rects->right, rects->bottom); } - fprintf(stderr, "\n"); + DEBUG_WARN( "\n"); } void region16_copy_band_with_union(RECTANGLE_16 *dst, diff --git a/libfreerdp/codec/rfx.c b/libfreerdp/codec/rfx.c index 1fa7c0034..3f23c6818 100644 --- a/libfreerdp/codec/rfx.c +++ b/libfreerdp/codec/rfx.c @@ -376,7 +376,7 @@ void rfx_context_free(RFX_CONTEXT* context) free(priv->tileWorkParams); #ifdef WITH_PROFILER - fprintf(stderr, "\nWARNING: Profiling results probably unusable with multithreaded RemoteFX codec!\n"); + DEBUG_WARN( "\nWARNING: Profiling results probably unusable with multithreaded RemoteFX codec!\n"); #endif } @@ -1426,7 +1426,7 @@ out_clean_tiles: free(message->tiles); region16_uninit(&tilesRegion); out_free_message: - fprintf(stderr, "remoteFx error\n"); + DEBUG_WARN( "remoteFx error\n"); region16_uninit(&rectsRegion); free(message); return 0; diff --git a/libfreerdp/codec/rfx_decode.c b/libfreerdp/codec/rfx_decode.c index d3baf5462..d14aff8a2 100644 --- a/libfreerdp/codec/rfx_decode.c +++ b/libfreerdp/codec/rfx_decode.c @@ -38,7 +38,7 @@ #include "rfx_decode.h" /* stride is bytes between rows in the output buffer. */ -static void rfx_decode_format_rgb(INT16* r_buf, INT16* g_buf, INT16* b_buf, +void rfx_decode_format_rgb(INT16* r_buf, INT16* g_buf, INT16* b_buf, RDP_PIXEL_FORMAT pixel_format, BYTE* dst_buf, int stride) { primitives_t *prims = primitives_get(); @@ -146,9 +146,7 @@ BOOL rfx_decode_rgb(RFX_CONTEXT* context, RFX_TILE* tile, BYTE* rgb_buffer, int pSrcDst[2] = (INT16*)((BYTE*)(&pBuffer[((8192 + 32) * 2) + 16])); /* cr_b_buffer */ rfx_decode_component(context, y_quants, tile->YData, tile->YLen, pSrcDst[0]); /* YData */ - rfx_decode_component(context, cb_quants, tile->CbData, tile->CbLen, pSrcDst[1]); /* CbData */ - rfx_decode_component(context, cr_quants, tile->CrData, tile->CrLen, pSrcDst[2]); /* CrData */ PROFILER_ENTER(context->priv->prof_rfx_ycbcr_to_rgb); diff --git a/libfreerdp/codec/rfx_differential.c b/libfreerdp/codec/rfx_differential.c index e80aa98f3..4429fb8c0 100644 --- a/libfreerdp/codec/rfx_differential.c +++ b/libfreerdp/codec/rfx_differential.c @@ -27,23 +27,24 @@ #include "rfx_differential.h" -void rfx_differential_decode(INT16* buffer, int buffer_size) +void rfx_differential_decode(INT16* buffer, int size) { - INT16* src; - INT16* dst; + INT16* ptr = buffer; + INT16* end = &buffer[size - 1]; - for (src = buffer, dst = buffer + 1; buffer_size > 1; src++, dst++, buffer_size--) + while (ptr != end) { - *dst += *src; + ptr[1] += ptr[0]; + ptr++; } } -void rfx_differential_encode(INT16* buffer, int buffer_size) +void rfx_differential_encode(INT16* buffer, int size) { INT16 n1, n2; INT16* dst; - for (n1 = *buffer, dst = buffer + 1; buffer_size > 1; dst++, buffer_size--) + for (n1 = *buffer, dst = buffer + 1; size > 1; dst++, size--) { n2 = *dst; *dst -= n1; diff --git a/libfreerdp/codec/rfx_differential.h b/libfreerdp/codec/rfx_differential.h index 3f6dbf623..47e1a4241 100644 --- a/libfreerdp/codec/rfx_differential.h +++ b/libfreerdp/codec/rfx_differential.h @@ -22,7 +22,7 @@ #include -void rfx_differential_decode(INT16* buffer, int buffer_size); -void rfx_differential_encode(INT16* buffer, int buffer_size); +void rfx_differential_decode(INT16* buffer, int size); +void rfx_differential_encode(INT16* buffer, int size); #endif /* __RFX_DIFFERENTIAL_H */ diff --git a/libfreerdp/codec/rfx_dwt.c b/libfreerdp/codec/rfx_dwt.c index 0b8448b9e..7e3b3ccc4 100644 --- a/libfreerdp/codec/rfx_dwt.c +++ b/libfreerdp/codec/rfx_dwt.c @@ -110,9 +110,9 @@ static void rfx_dwt_2d_decode_block(INT16* buffer, INT16* idwt, int subband_widt void rfx_dwt_2d_decode(INT16* buffer, INT16* dwt_buffer) { - rfx_dwt_2d_decode_block(buffer + 3840, dwt_buffer, 8); - rfx_dwt_2d_decode_block(buffer + 3072, dwt_buffer, 16); - rfx_dwt_2d_decode_block(buffer, dwt_buffer, 32); + rfx_dwt_2d_decode_block(&buffer[3840], dwt_buffer, 8); + rfx_dwt_2d_decode_block(&buffer[3072], dwt_buffer, 16); + rfx_dwt_2d_decode_block(&buffer[0], dwt_buffer, 32); } static void rfx_dwt_2d_encode_block(INT16* buffer, INT16* dwt, int subband_width) @@ -192,7 +192,7 @@ static void rfx_dwt_2d_encode_block(INT16* buffer, INT16* dwt, int subband_width void rfx_dwt_2d_encode(INT16* buffer, INT16* dwt_buffer) { - rfx_dwt_2d_encode_block(buffer, dwt_buffer, 32); - rfx_dwt_2d_encode_block(buffer + 3072, dwt_buffer, 16); - rfx_dwt_2d_encode_block(buffer + 3840, dwt_buffer, 8); + rfx_dwt_2d_encode_block(&buffer[0], dwt_buffer, 32); + rfx_dwt_2d_encode_block(&buffer[3072], dwt_buffer, 16); + rfx_dwt_2d_encode_block(&buffer[3840], dwt_buffer, 8); } diff --git a/libfreerdp/codec/rfx_neon.c b/libfreerdp/codec/rfx_neon.c index 6fe8ec83d..1632f983a 100644 --- a/libfreerdp/codec/rfx_neon.c +++ b/libfreerdp/codec/rfx_neon.c @@ -51,21 +51,18 @@ rfx_quantization_decode_block_NEON(INT16 * buffer, const int buffer_size, const while(buf < buf_end); } -void -rfx_quantization_decode_NEON(INT16 * buffer, const UINT32 * quantization_values) +void rfx_quantization_decode_NEON(INT16 * buffer, const UINT32 * quantVals) { - rfx_quantization_decode_block_NEON(buffer, 4096, 5); - - rfx_quantization_decode_block_NEON(buffer, 1024, quantization_values[8] - 6); /* HL1 */ - rfx_quantization_decode_block_NEON(buffer + 1024, 1024, quantization_values[7] - 6); /* LH1 */ - rfx_quantization_decode_block_NEON(buffer + 2048, 1024, quantization_values[9] - 6); /* HH1 */ - rfx_quantization_decode_block_NEON(buffer + 3072, 256, quantization_values[5] - 6); /* HL2 */ - rfx_quantization_decode_block_NEON(buffer + 3328, 256, quantization_values[4] - 6); /* LH2 */ - rfx_quantization_decode_block_NEON(buffer + 3584, 256, quantization_values[6] - 6); /* HH2 */ - rfx_quantization_decode_block_NEON(buffer + 3840, 64, quantization_values[2] - 6); /* HL3 */ - rfx_quantization_decode_block_NEON(buffer + 3904, 64, quantization_values[1] - 6); /* LH3 */ - rfx_quantization_decode_block_NEON(buffer + 3968, 64, quantization_values[3] - 6); /* HH3 */ - rfx_quantization_decode_block_NEON(buffer + 4032, 64, quantization_values[0] - 6); /* LL3 */ + rfx_quantization_decode_block_NEON(&buffer[0], 1024, quantVals[8] - 1); /* HL1 */ + rfx_quantization_decode_block_NEON(&buffer[1024], 1024, quantVals[7] - 1); /* LH1 */ + rfx_quantization_decode_block_NEON(&buffer[2048], 1024, quantVals[9] - 1); /* HH1 */ + rfx_quantization_decode_block_NEON(&buffer[3072], 256, quantVals[5] - 1); /* HL2 */ + rfx_quantization_decode_block_NEON(&buffer[3328], 256, quantVals[4] - 1); /* LH2 */ + rfx_quantization_decode_block_NEON(&buffer[3584], 256, quantVals[6] - 1); /* HH2 */ + rfx_quantization_decode_block_NEON(&buffer[3840], 64, quantVals[2] - 1); /* HL3 */ + rfx_quantization_decode_block_NEON(&buffer[3904], 64, quantVals[1] - 1); /* LH3 */ + rfx_quantization_decode_block_NEON(&buffer[3968], 64, quantVals[3] - 1); /* HH3 */ + rfx_quantization_decode_block_NEON(&buffer[4032], 64, quantVals[0] - 1); /* LL3 */ } diff --git a/libfreerdp/codec/rfx_quantization.c b/libfreerdp/codec/rfx_quantization.c index 2cedfd91d..6c497a65a 100644 --- a/libfreerdp/codec/rfx_quantization.c +++ b/libfreerdp/codec/rfx_quantization.c @@ -22,9 +22,28 @@ #endif #include + #include "rfx_quantization.h" -static void rfx_quantization_decode_block(const primitives_t *prims, INT16* buffer, int buffer_size, UINT32 factor) +/* + * Band Offset Dimensions Size + * + * HL1 0 32x32 1024 + * LH1 1024 32x32 1024 + * HH1 2048 32x32 1024 + * + * HL2 3072 16x16 256 + * LH2 3328 16x16 256 + * HH2 3584 16x16 256 + * + * HL3 3840 8x8 64 + * LH3 3904 8x8 64 + * HH3 3968 8x8 64 + * + * LL3 4032 8x8 64 + */ + +void rfx_quantization_decode_block(const primitives_t *prims, INT16* buffer, int buffer_size, UINT32 factor) { if (factor == 0) return; @@ -32,23 +51,20 @@ static void rfx_quantization_decode_block(const primitives_t *prims, INT16* buff prims->lShiftC_16s(buffer, factor, buffer, buffer_size); } -void rfx_quantization_decode(INT16* buffer, const UINT32* quantization_values) +void rfx_quantization_decode(INT16* buffer, const UINT32* quantVals) { - const primitives_t *prims = primitives_get(); + const primitives_t* prims = primitives_get(); - /* Scale the values so that they are represented as 11.5 fixed-point number */ - rfx_quantization_decode_block(prims, buffer, 4096, 5); - - rfx_quantization_decode_block(prims, buffer, 1024, quantization_values[8] - 6); /* HL1 */ - rfx_quantization_decode_block(prims, buffer + 1024, 1024, quantization_values[7] - 6); /* LH1 */ - rfx_quantization_decode_block(prims, buffer + 2048, 1024, quantization_values[9] - 6); /* HH1 */ - rfx_quantization_decode_block(prims, buffer + 3072, 256, quantization_values[5] - 6); /* HL2 */ - rfx_quantization_decode_block(prims, buffer + 3328, 256, quantization_values[4] - 6); /* LH2 */ - rfx_quantization_decode_block(prims, buffer + 3584, 256, quantization_values[6] - 6); /* HH2 */ - rfx_quantization_decode_block(prims, buffer + 3840, 64, quantization_values[2] - 6); /* HL3 */ - rfx_quantization_decode_block(prims, buffer + 3904, 64, quantization_values[1] - 6); /* LH3 */ - rfx_quantization_decode_block(prims, buffer + 3968, 64, quantization_values[3] - 6); /* HH3 */ - rfx_quantization_decode_block(prims, buffer + 4032, 64, quantization_values[0] - 6); /* LL3 */ + rfx_quantization_decode_block(prims, &buffer[0], 1024, quantVals[8] - 1); /* HL1 */ + rfx_quantization_decode_block(prims, &buffer[1024], 1024, quantVals[7] - 1); /* LH1 */ + rfx_quantization_decode_block(prims, &buffer[2048], 1024, quantVals[9] - 1); /* HH1 */ + rfx_quantization_decode_block(prims, &buffer[3072], 256, quantVals[5] - 1); /* HL2 */ + rfx_quantization_decode_block(prims, &buffer[3328], 256, quantVals[4] - 1); /* LH2 */ + rfx_quantization_decode_block(prims, &buffer[3584], 256, quantVals[6] - 1); /* HH2 */ + rfx_quantization_decode_block(prims, &buffer[3840], 64, quantVals[2] - 1); /* HL3 */ + rfx_quantization_decode_block(prims, &buffer[3904], 64, quantVals[1] - 1); /* LH3 */ + rfx_quantization_decode_block(prims, &buffer[3968], 64, quantVals[3] - 1); /* HH3 */ + rfx_quantization_decode_block(prims, &buffer[4032], 64, quantVals[0] - 1); /* LL3 */ } static void rfx_quantization_encode_block(INT16* buffer, int buffer_size, UINT32 factor) diff --git a/libfreerdp/codec/rfx_quantization.h b/libfreerdp/codec/rfx_quantization.h index b10aa729f..e446a098a 100644 --- a/libfreerdp/codec/rfx_quantization.h +++ b/libfreerdp/codec/rfx_quantization.h @@ -25,4 +25,6 @@ void rfx_quantization_decode(INT16* buffer, const UINT32* quantization_values); void rfx_quantization_encode(INT16* buffer, const UINT32* quantization_values); +void rfx_quantization_decode_block(const primitives_t *prims, INT16* buffer, int buffer_size, UINT32 factor); + #endif /* __RFX_QUANTIZATION_H */ diff --git a/libfreerdp/codec/rfx_rlgr.c b/libfreerdp/codec/rfx_rlgr.c index 1571dec20..b625f45c9 100644 --- a/libfreerdp/codec/rfx_rlgr.c +++ b/libfreerdp/codec/rfx_rlgr.c @@ -32,6 +32,7 @@ #include #include +#include #include #include "rfx_bitstream.h" @@ -72,6 +73,28 @@ _k = (_param >> LSGR); \ } +static BOOL g_LZCNT = FALSE; + +static INLINE UINT32 lzcnt_s(UINT32 x) +{ + if (!x) + return 32; + + if (!g_LZCNT) + { + UINT32 y; + int n = 32; + y = x >> 16; if (y != 0) { n = n - 16; x = y; } + y = x >> 8; if (y != 0) { n = n - 8; x = y; } + y = x >> 4; if (y != 0) { n = n - 4; x = y; } + y = x >> 2; if (y != 0) { n = n - 2; x = y; } + y = x >> 1; if (y != 0) return n - 2; + return n - x; + } + + return __lzcnt(x); +} + int rfx_rlgr_decode(const BYTE* pSrcData, UINT32 SrcSize, INT16* pDstData, UINT32 DstSize, int mode) { int vk; @@ -92,6 +115,8 @@ int rfx_rlgr_decode(const BYTE* pSrcData, UINT32 SrcSize, INT16* pDstData, UINT3 wBitStream* bs; wBitStream s_bs; + g_LZCNT = IsProcessorFeaturePresentEx(PF_EX_LZCNT); + k = 1; kp = k << LSGR; @@ -124,7 +149,7 @@ int rfx_rlgr_decode(const BYTE* pSrcData, UINT32 SrcSize, INT16* pDstData, UINT3 /* count number of leading 0s */ - cnt = __lzcnt(bs->accumulator); + cnt = lzcnt_s(bs->accumulator); nbits = BitStream_GetRemainingLength(bs); @@ -137,7 +162,7 @@ int rfx_rlgr_decode(const BYTE* pSrcData, UINT32 SrcSize, INT16* pDstData, UINT3 { BitStream_Shift32(bs); - cnt = __lzcnt(bs->accumulator); + cnt = lzcnt_s(bs->accumulator); nbits = BitStream_GetRemainingLength(bs); @@ -187,7 +212,7 @@ int rfx_rlgr_decode(const BYTE* pSrcData, UINT32 SrcSize, INT16* pDstData, UINT3 /* count number of leading 1s */ - cnt = __lzcnt(~(bs->accumulator)); + cnt = lzcnt_s(~(bs->accumulator)); nbits = BitStream_GetRemainingLength(bs); @@ -200,7 +225,7 @@ int rfx_rlgr_decode(const BYTE* pSrcData, UINT32 SrcSize, INT16* pDstData, UINT3 { BitStream_Shift32(bs); - cnt = __lzcnt(~(bs->accumulator)); + cnt = lzcnt_s(~(bs->accumulator)); nbits = BitStream_GetRemainingLength(bs); @@ -295,7 +320,7 @@ int rfx_rlgr_decode(const BYTE* pSrcData, UINT32 SrcSize, INT16* pDstData, UINT3 /* count number of leading 1s */ - cnt = __lzcnt(~(bs->accumulator)); + cnt = lzcnt_s(~(bs->accumulator)); nbits = BitStream_GetRemainingLength(bs); @@ -308,7 +333,7 @@ int rfx_rlgr_decode(const BYTE* pSrcData, UINT32 SrcSize, INT16* pDstData, UINT3 { BitStream_Shift32(bs); - cnt = __lzcnt(~(bs->accumulator)); + cnt = lzcnt_s(~(bs->accumulator)); nbits = BitStream_GetRemainingLength(bs); @@ -411,7 +436,7 @@ int rfx_rlgr_decode(const BYTE* pSrcData, UINT32 SrcSize, INT16* pDstData, UINT3 if (code) { mag = (UINT32) code; - nIdx = 32 - __lzcnt(mag); + nIdx = 32 - lzcnt_s(mag); } if (BitStream_GetRemainingLength(bs) < nIdx) diff --git a/libfreerdp/codec/rfx_sse2.c b/libfreerdp/codec/rfx_sse2.c index 47dbac32f..f89efe81e 100644 --- a/libfreerdp/codec/rfx_sse2.c +++ b/libfreerdp/codec/rfx_sse2.c @@ -82,22 +82,20 @@ rfx_quantization_decode_block_sse2(INT16* buffer, const int buffer_size, const U } while(ptr < buf_end); } -static void rfx_quantization_decode_sse2(INT16* buffer, const UINT32* quantization_values) +static void rfx_quantization_decode_sse2(INT16* buffer, const UINT32* quantVals) { _mm_prefetch_buffer((char*) buffer, 4096 * sizeof(INT16)); - rfx_quantization_decode_block_sse2(buffer, 4096, 5); - - rfx_quantization_decode_block_sse2(buffer, 1024, quantization_values[8] - 6); /* HL1 */ - rfx_quantization_decode_block_sse2(buffer + 1024, 1024, quantization_values[7] - 6); /* LH1 */ - rfx_quantization_decode_block_sse2(buffer + 2048, 1024, quantization_values[9] - 6); /* HH1 */ - rfx_quantization_decode_block_sse2(buffer + 3072, 256, quantization_values[5] - 6); /* HL2 */ - rfx_quantization_decode_block_sse2(buffer + 3328, 256, quantization_values[4] - 6); /* LH2 */ - rfx_quantization_decode_block_sse2(buffer + 3584, 256, quantization_values[6] - 6); /* HH2 */ - rfx_quantization_decode_block_sse2(buffer + 3840, 64, quantization_values[2] - 6); /* HL3 */ - rfx_quantization_decode_block_sse2(buffer + 3904, 64, quantization_values[1] - 6); /* LH3 */ - rfx_quantization_decode_block_sse2(buffer + 3968, 64, quantization_values[3] - 6); /* HH3 */ - rfx_quantization_decode_block_sse2(buffer + 4032, 64, quantization_values[0] - 6); /* LL3 */ + rfx_quantization_decode_block_sse2(&buffer[0], 1024, quantVals[8] - 1); /* HL1 */ + rfx_quantization_decode_block_sse2(&buffer[1024], 1024, quantVals[7] - 1); /* LH1 */ + rfx_quantization_decode_block_sse2(&buffer[2048], 1024, quantVals[9] - 1); /* HH1 */ + rfx_quantization_decode_block_sse2(&buffer[3072], 256, quantVals[5] - 1); /* HL2 */ + rfx_quantization_decode_block_sse2(&buffer[3328], 256, quantVals[4] - 1); /* LH2 */ + rfx_quantization_decode_block_sse2(&buffer[3584], 256, quantVals[6] - 1); /* HH2 */ + rfx_quantization_decode_block_sse2(&buffer[3840], 64, quantVals[2] - 1); /* HL3 */ + rfx_quantization_decode_block_sse2(&buffer[3904], 64, quantVals[1] - 1); /* LH3 */ + rfx_quantization_decode_block_sse2(&buffer[3968], 64, quantVals[3] - 1); /* HH3 */ + rfx_quantization_decode_block_sse2(&buffer[4032], 64, quantVals[0] - 1); /* LL3 */ } static __inline void __attribute__((ATTRIBUTES)) @@ -342,9 +340,9 @@ static void rfx_dwt_2d_decode_sse2(INT16* buffer, INT16* dwt_buffer) { _mm_prefetch_buffer((char*) buffer, 4096 * sizeof(INT16)); - rfx_dwt_2d_decode_block_sse2(buffer + 3840, dwt_buffer, 8); - rfx_dwt_2d_decode_block_sse2(buffer + 3072, dwt_buffer, 16); - rfx_dwt_2d_decode_block_sse2(buffer, dwt_buffer, 32); + rfx_dwt_2d_decode_block_sse2(&buffer[3840], dwt_buffer, 8); + rfx_dwt_2d_decode_block_sse2(&buffer[3072], dwt_buffer, 16); + rfx_dwt_2d_decode_block_sse2(&buffer[0], dwt_buffer, 32); } static __inline void __attribute__((ATTRIBUTES)) diff --git a/libfreerdp/codec/test/TestFreeRDPCodecProgressive.c b/libfreerdp/codec/test/TestFreeRDPCodecProgressive.c index 320329300..03533d2c1 100644 --- a/libfreerdp/codec/test/TestFreeRDPCodecProgressive.c +++ b/libfreerdp/codec/test/TestFreeRDPCodecProgressive.c @@ -1,10 +1,1032 @@ #include +#include +#include #include +#include + #include -int TestFreeRDPCodecProgressive(int argc, char* argv[]) +/** + * Microsoft Progressive Codec Sample Data + * (available under NDA only) + * + * ____. + * + * readme.pdf + * + * bitmaps/ + * 1920by1080-SampleImage1.bmp + * 1920by1080-SampleImage2.bmp + * 1920by1080-SampleImage3.bmp + * + * compress/ + * enc_0_0_025_sampleimage1.bin + * enc_0_0_050_sampleimage1.bin + * enc_0_0_075_sampleimage1.bin + * enc_0_0_100_sampleimage1.bin + * enc_0_1_025_sampleimage1.bin + * enc_0_1_050_sampleimage1.bin + * enc_0_1_075_sampleimage1.bin + * enc_0_1_100_sampleimage1.bin + * enc_0_2_025_sampleimage1.bin + * enc_0_2_050_sampleimage1.bin + * enc_0_2_075_sampleimage1.bin + * enc_0_2_100_sampleimage1.bin + * enc_0_3_025_sampleimage1.bin + * enc_0_3_050_sampleimage1.bin + * enc_0_3_075_sampleimage1.bin + * enc_0_3_100_sampleimage1.bin + * enc_1_0_025_sampleimage2.bin + * enc_1_0_050_sampleimage2.bin + * enc_1_0_075_sampleimage2.bin + * enc_1_0_100_sampleimage2.bin + * enc_1_1_025_sampleimage2.bin + * enc_1_1_050_sampleimage2.bin + * enc_1_1_075_sampleimage2.bin + * enc_1_1_100_sampleimage2.bin + * enc_1_2_025_sampleimage2.bin + * enc_1_2_050_sampleimage2.bin + * enc_1_2_075_sampleimage2.bin + * enc_1_2_100_sampleimage2.bin + * enc_1_3_025_sampleimage2.bin + * enc_1_3_050_sampleimage2.bin + * enc_1_3_075_sampleimage2.bin + * enc_1_3_100_sampleimage2.bin + * enc_2_0_025_sampleimage3.bin + * enc_2_0_050_sampleimage3.bin + * enc_2_0_075_sampleimage3.bin + * enc_2_0_100_sampleimage3.bin + * enc_2_1_025_sampleimage3.bin + * enc_2_1_050_sampleimage3.bin + * enc_2_1_075_sampleimage3.bin + * enc_2_1_100_sampleimage3.bin + * enc_2_2_025_sampleimage3.bin + * enc_2_2_050_sampleimage3.bin + * enc_2_2_075_sampleimage3.bin + * enc_2_2_100_sampleimage3.bin + * enc_2_3_025_sampleimage3.bin + * enc_2_3_050_sampleimage3.bin + * enc_2_3_075_sampleimage3.bin + * enc_2_3_100_sampleimage3.bin + * + * decompress/ + * dec_0_0_025_sampleimage1.bmp + * dec_0_0_050_sampleimage1.bmp + * dec_0_0_075_sampleimage1.bmp + * dec_0_0_100_sampleimage1.bmp + * dec_0_1_025_sampleimage1.bmp + * dec_0_1_050_sampleimage1.bmp + * dec_0_1_075_sampleimage1.bmp + * dec_0_1_100_sampleimage1.bmp + * dec_0_2_025_sampleimage1.bmp + * dec_0_2_050_sampleimage1.bmp + * dec_0_2_075_sampleimage1.bmp + * dec_0_2_100_sampleimage1.bmp + * dec_0_3_025_sampleimage1.bmp + * dec_0_3_050_sampleimage1.bmp + * dec_0_3_075_sampleimage1.bmp + * dec_0_3_100_sampleimage1.bmp + * dec_1_0_025_sampleimage2.bmp + * dec_1_0_050_sampleimage2.bmp + * dec_1_0_075_sampleimage2.bmp + * dec_1_0_100_sampleimage2.bmp + * dec_1_1_025_sampleimage2.bmp + * dec_1_1_050_sampleimage2.bmp + * dec_1_1_075_sampleimage2.bmp + * dec_1_1_100_sampleimage2.bmp + * dec_1_2_025_sampleimage2.bmp + * dec_1_2_050_sampleimage2.bmp + * dec_1_2_075_sampleimage2.bmp + * dec_1_2_100_sampleimage2.bmp + * dec_1_3_025_sampleimage2.bmp + * dec_1_3_050_sampleimage2.bmp + * dec_1_3_075_sampleimage2.bmp + * dec_1_3_100_sampleimage2.bmp + * dec_2_0_025_sampleimage3.bmp + * dec_2_0_050_sampleimage3.bmp + * dec_2_0_075_sampleimage3.bmp + * dec_2_0_100_sampleimage3.bmp + * dec_2_1_025_sampleimage3.bmp + * dec_2_1_050_sampleimage3.bmp + * dec_2_1_075_sampleimage3.bmp + * dec_2_1_100_sampleimage3.bmp + * dec_2_2_025_sampleimage3.bmp + * dec_2_2_050_sampleimage3.bmp + * dec_2_2_075_sampleimage3.bmp + * dec_2_2_100_sampleimage3.bmp + * dec_2_3_025_sampleimage3.bmp + * dec_2_3_050_sampleimage3.bmp + * dec_2_3_075_sampleimage3.bmp + * dec_2_3_100_sampleimage3.bmp + */ + +struct _EGFX_SAMPLE_FILE { + BYTE* buffer; + UINT32 size; +}; +typedef struct _EGFX_SAMPLE_FILE EGFX_SAMPLE_FILE; + +static int g_Width = 0; +static int g_Height = 0; +static int g_DstStep = 0; +static BYTE* g_DstData = NULL; + +static void test_fill_image_alpha_channel(BYTE* data, int width, int height, BYTE value) +{ + int i, j; + UINT32* pixel; + + for (i = 0; i < height; i++) + { + for (j = 0; j < width; j++) + { + pixel = (UINT32*) &data[((i * width) + j) * 4]; + *pixel = ((*pixel & 0x00FFFFFF) | (value << 24)); + } + } +} + +static void* test_image_memset32(UINT32* ptr, UINT32 fill, size_t length) +{ + while (length--) + { + *ptr++ = fill; + } + + return (void*) ptr; +} + +static int test_image_fill(BYTE* pDstData, int nDstStep, int nXDst, int nYDst, int nWidth, int nHeight, UINT32 color) +{ + int y; + UINT32* pDstPixel; + + if (nDstStep < 0) + nDstStep = 4 * nWidth; + + for (y = 0; y < nHeight; y++) + { + pDstPixel = (UINT32*) &pDstData[((nYDst + y) * nDstStep) + (nXDst * 4)]; + test_image_memset32(pDstPixel, color, nWidth); + } + + return 1; +} + +static int test_image_fill_quarter(BYTE* pDstData, int nDstStep, int nWidth, int nHeight, UINT32 color, int quarter) +{ + int x = 0; + int y = 0; + int width = 0; + int height = 0; + + switch (quarter) + { + case 0: + x = 0; + y = 0; + width = nWidth / 2; + height = nHeight /2; + break; + + case 1: + x = nWidth / 2; + y = nHeight / 2; + width = nWidth; + height = nHeight; + break; + + case 2: + x = nWidth / 2; + y = 0; + width = nWidth; + height = nHeight / 2; + break; + + case 3: + x = 0; + y = nHeight / 2; + width = nWidth / 2; + height = nHeight; + break; + } + + test_image_fill(pDstData, nDstStep, x, y, width, height, 0xFF000000); + + return 1; +} + +static int test_image_fill_unused_quarters(BYTE* pDstData, int nDstStep, int nWidth, int nHeight, UINT32 color, int quarter) +{ + if (quarter == 0) + { + test_image_fill_quarter(pDstData, nDstStep, nWidth, nHeight, color, 1); + test_image_fill_quarter(pDstData, nDstStep, nWidth, nHeight, color, 2); + test_image_fill_quarter(pDstData, nDstStep, nWidth, nHeight, color, 3); + } + else if (quarter == 1) + { + test_image_fill_quarter(pDstData, nDstStep, nWidth, nHeight, color, 0); + test_image_fill_quarter(pDstData, nDstStep, nWidth, nHeight, color, 2); + test_image_fill_quarter(pDstData, nDstStep, nWidth, nHeight, color, 3); + } + else if (quarter == 2) + { + test_image_fill_quarter(pDstData, nDstStep, nWidth, nHeight, color, 0); + test_image_fill_quarter(pDstData, nDstStep, nWidth, nHeight, color, 1); + test_image_fill_quarter(pDstData, nDstStep, nWidth, nHeight, color, 3); + } + else if (quarter == 3) + { + test_image_fill_quarter(pDstData, nDstStep, nWidth, nHeight, color, 0); + test_image_fill_quarter(pDstData, nDstStep, nWidth, nHeight, color, 1); + test_image_fill_quarter(pDstData, nDstStep, nWidth, nHeight, color, 2); + } + + return 1; +} + +BYTE* test_progressive_load_file(char* path, char* file, UINT32* size) +{ + FILE* fp; + BYTE* buffer; + char* filename; + + filename = GetCombinedPath(path, file); + + fp = fopen(filename, "r"); + + if (!fp) + return NULL; + + fseek(fp, 0, SEEK_END); + *size = ftell(fp); + fseek(fp, 0, SEEK_SET); + + buffer = (BYTE*) malloc(*size); + + if (!buffer) + return NULL; + + if (fread(buffer, *size, 1, fp) != 1) + return NULL; + + free(filename); + fclose(fp); + + return buffer; +} + +int test_progressive_load_files(char* ms_sample_path, EGFX_SAMPLE_FILE files[3][4][4]) +{ + int imageNo = 0; + int quarterNo = 0; + int passNo = 0; + + /* image 1 */ + + files[imageNo][quarterNo][passNo].buffer = test_progressive_load_file(ms_sample_path, + "compress/enc_0_0_025_sampleimage1.bin", &(files[imageNo][quarterNo][passNo].size)); + passNo = (passNo + 1) % 4; + + files[imageNo][quarterNo][passNo].buffer = test_progressive_load_file(ms_sample_path, + "compress/enc_0_0_050_sampleimage1.bin", &(files[imageNo][quarterNo][passNo].size)); + passNo = (passNo + 1) % 4; + + files[imageNo][quarterNo][passNo].buffer = test_progressive_load_file(ms_sample_path, + "compress/enc_0_0_075_sampleimage1.bin", &(files[imageNo][quarterNo][passNo].size)); + passNo = (passNo + 1) % 4; + + files[imageNo][quarterNo][passNo].buffer = test_progressive_load_file(ms_sample_path, + "compress/enc_0_0_100_sampleimage1.bin", &(files[imageNo][quarterNo][passNo].size)); + passNo = (passNo + 1) % 4; + + quarterNo = (quarterNo + 1) % 4; + + files[imageNo][quarterNo][passNo].buffer = test_progressive_load_file(ms_sample_path, + "compress/enc_0_1_025_sampleimage1.bin", &(files[imageNo][quarterNo][passNo].size)); + passNo = (passNo + 1) % 4; + + files[imageNo][quarterNo][passNo].buffer = test_progressive_load_file(ms_sample_path, + "compress/enc_0_1_050_sampleimage1.bin", &(files[imageNo][quarterNo][passNo].size)); + passNo = (passNo + 1) % 4; + + files[imageNo][quarterNo][passNo].buffer = test_progressive_load_file(ms_sample_path, + "compress/enc_0_1_075_sampleimage1.bin", &(files[imageNo][quarterNo][passNo].size)); + passNo = (passNo + 1) % 4; + + files[imageNo][quarterNo][passNo].buffer = test_progressive_load_file(ms_sample_path, + "compress/enc_0_1_100_sampleimage1.bin", &(files[imageNo][quarterNo][passNo].size)); + passNo = (passNo + 1) % 4; + + quarterNo = (quarterNo + 1) % 4; + + files[imageNo][quarterNo][passNo].buffer = test_progressive_load_file(ms_sample_path, + "compress/enc_0_2_025_sampleimage1.bin", &(files[imageNo][quarterNo][passNo].size)); + passNo = (passNo + 1) % 4; + + files[imageNo][quarterNo][passNo].buffer = test_progressive_load_file(ms_sample_path, + "compress/enc_0_2_050_sampleimage1.bin", &(files[imageNo][quarterNo][passNo].size)); + passNo = (passNo + 1) % 4; + + files[imageNo][quarterNo][passNo].buffer = test_progressive_load_file(ms_sample_path, + "compress/enc_0_2_075_sampleimage1.bin", &(files[imageNo][quarterNo][passNo].size)); + passNo = (passNo + 1) % 4; + + files[imageNo][quarterNo][passNo].buffer = test_progressive_load_file(ms_sample_path, + "compress/enc_0_2_100_sampleimage1.bin", &(files[imageNo][quarterNo][passNo].size)); + passNo = (passNo + 1) % 4; + + quarterNo = (quarterNo + 1) % 4; + + files[imageNo][quarterNo][passNo].buffer = test_progressive_load_file(ms_sample_path, + "compress/enc_0_3_025_sampleimage1.bin", &(files[imageNo][quarterNo][passNo].size)); + passNo = (passNo + 1) % 4; + + files[imageNo][quarterNo][passNo].buffer = test_progressive_load_file(ms_sample_path, + "compress/enc_0_3_050_sampleimage1.bin", &(files[imageNo][quarterNo][passNo].size)); + passNo = (passNo + 1) % 4; + + files[imageNo][quarterNo][passNo].buffer = test_progressive_load_file(ms_sample_path, + "compress/enc_0_3_075_sampleimage1.bin", &(files[imageNo][quarterNo][passNo].size)); + passNo = (passNo + 1) % 4; + + files[imageNo][quarterNo][passNo].buffer = test_progressive_load_file(ms_sample_path, + "compress/enc_0_3_100_sampleimage1.bin", &(files[imageNo][quarterNo][passNo].size)); + passNo = (passNo + 1) % 4; + + imageNo++; + + /* image 2 */ + + files[imageNo][quarterNo][passNo].buffer = test_progressive_load_file(ms_sample_path, + "compress/enc_1_0_025_sampleimage2.bin", &(files[imageNo][quarterNo][passNo].size)); + passNo = (passNo + 1) % 4; + + files[imageNo][quarterNo][passNo].buffer = test_progressive_load_file(ms_sample_path, + "compress/enc_1_0_050_sampleimage2.bin", &(files[imageNo][quarterNo][passNo].size)); + passNo = (passNo + 1) % 4; + + files[imageNo][quarterNo][passNo].buffer = test_progressive_load_file(ms_sample_path, + "compress/enc_1_0_075_sampleimage2.bin", &(files[imageNo][quarterNo][passNo].size)); + passNo = (passNo + 1) % 4; + + files[imageNo][quarterNo][passNo].buffer = test_progressive_load_file(ms_sample_path, + "compress/enc_1_0_100_sampleimage2.bin", &(files[imageNo][quarterNo][passNo].size)); + passNo = (passNo + 1) % 4; + + quarterNo = (quarterNo + 1) % 4; + + files[imageNo][quarterNo][passNo].buffer = test_progressive_load_file(ms_sample_path, + "compress/enc_1_1_025_sampleimage2.bin", &(files[imageNo][quarterNo][passNo].size)); + passNo = (passNo + 1) % 4; + + files[imageNo][quarterNo][passNo].buffer = test_progressive_load_file(ms_sample_path, + "compress/enc_1_1_050_sampleimage2.bin", &(files[imageNo][quarterNo][passNo].size)); + passNo = (passNo + 1) % 4; + + files[imageNo][quarterNo][passNo].buffer = test_progressive_load_file(ms_sample_path, + "compress/enc_1_1_075_sampleimage2.bin", &(files[imageNo][quarterNo][passNo].size)); + passNo = (passNo + 1) % 4; + + files[imageNo][quarterNo][passNo].buffer = test_progressive_load_file(ms_sample_path, + "compress/enc_1_1_100_sampleimage2.bin", &(files[imageNo][quarterNo][passNo].size)); + passNo = (passNo + 1) % 4; + + quarterNo = (quarterNo + 1) % 4; + + files[imageNo][quarterNo][passNo].buffer = test_progressive_load_file(ms_sample_path, + "compress/enc_1_2_025_sampleimage2.bin", &(files[imageNo][quarterNo][passNo].size)); + passNo = (passNo + 1) % 4; + + files[imageNo][quarterNo][passNo].buffer = test_progressive_load_file(ms_sample_path, + "compress/enc_1_2_050_sampleimage2.bin", &(files[imageNo][quarterNo][passNo].size)); + passNo = (passNo + 1) % 4; + + files[imageNo][quarterNo][passNo].buffer = test_progressive_load_file(ms_sample_path, + "compress/enc_1_2_075_sampleimage2.bin", &(files[imageNo][quarterNo][passNo].size)); + passNo = (passNo + 1) % 4; + + files[imageNo][quarterNo][passNo].buffer = test_progressive_load_file(ms_sample_path, + "compress/enc_1_2_100_sampleimage2.bin", &(files[imageNo][quarterNo][passNo].size)); + passNo = (passNo + 1) % 4; + + quarterNo = (quarterNo + 1) % 4; + + files[imageNo][quarterNo][passNo].buffer = test_progressive_load_file(ms_sample_path, + "compress/enc_1_3_025_sampleimage2.bin", &(files[imageNo][quarterNo][passNo].size)); + passNo = (passNo + 1) % 4; + + files[imageNo][quarterNo][passNo].buffer = test_progressive_load_file(ms_sample_path, + "compress/enc_1_3_050_sampleimage2.bin", &(files[imageNo][quarterNo][passNo].size)); + passNo = (passNo + 1) % 4; + + files[imageNo][quarterNo][passNo].buffer = test_progressive_load_file(ms_sample_path, + "compress/enc_1_3_075_sampleimage2.bin", &(files[imageNo][quarterNo][passNo].size)); + passNo = (passNo + 1) % 4; + + files[imageNo][quarterNo][passNo].buffer = test_progressive_load_file(ms_sample_path, + "compress/enc_1_3_100_sampleimage2.bin", &(files[imageNo][quarterNo][passNo].size)); + passNo = (passNo + 1) % 4; + + imageNo++; + + /* image 3 */ + + files[imageNo][quarterNo][passNo].buffer = test_progressive_load_file(ms_sample_path, + "compress/enc_2_0_025_sampleimage3.bin", &(files[imageNo][quarterNo][passNo].size)); + passNo = (passNo + 1) % 4; + + files[imageNo][quarterNo][passNo].buffer = test_progressive_load_file(ms_sample_path, + "compress/enc_2_0_050_sampleimage3.bin", &(files[imageNo][quarterNo][passNo].size)); + passNo = (passNo + 1) % 4; + + files[imageNo][quarterNo][passNo].buffer = test_progressive_load_file(ms_sample_path, + "compress/enc_2_0_075_sampleimage3.bin", &(files[imageNo][quarterNo][passNo].size)); + passNo = (passNo + 1) % 4; + + files[imageNo][quarterNo][passNo].buffer = test_progressive_load_file(ms_sample_path, + "compress/enc_2_0_100_sampleimage3.bin", &(files[imageNo][quarterNo][passNo].size)); + passNo = (passNo + 1) % 4; + + quarterNo = (quarterNo + 1) % 4; + + files[imageNo][quarterNo][passNo].buffer = test_progressive_load_file(ms_sample_path, + "compress/enc_2_1_025_sampleimage3.bin", &(files[imageNo][quarterNo][passNo].size)); + passNo = (passNo + 1) % 4; + + files[imageNo][quarterNo][passNo].buffer = test_progressive_load_file(ms_sample_path, + "compress/enc_2_1_050_sampleimage3.bin", &(files[imageNo][quarterNo][passNo].size)); + passNo = (passNo + 1) % 4; + + files[imageNo][quarterNo][passNo].buffer = test_progressive_load_file(ms_sample_path, + "compress/enc_2_1_075_sampleimage3.bin", &(files[imageNo][quarterNo][passNo].size)); + passNo = (passNo + 1) % 4; + + files[imageNo][quarterNo][passNo].buffer = test_progressive_load_file(ms_sample_path, + "compress/enc_2_1_100_sampleimage3.bin", &(files[imageNo][quarterNo][passNo].size)); + passNo = (passNo + 1) % 4; + + quarterNo = (quarterNo + 1) % 4; + + files[imageNo][quarterNo][passNo].buffer = test_progressive_load_file(ms_sample_path, + "compress/enc_2_2_025_sampleimage3.bin", &(files[imageNo][quarterNo][passNo].size)); + passNo = (passNo + 1) % 4; + + files[imageNo][quarterNo][passNo].buffer = test_progressive_load_file(ms_sample_path, + "compress/enc_2_2_050_sampleimage3.bin", &(files[imageNo][quarterNo][passNo].size)); + passNo = (passNo + 1) % 4; + + files[imageNo][quarterNo][passNo].buffer = test_progressive_load_file(ms_sample_path, + "compress/enc_2_2_075_sampleimage3.bin", &(files[imageNo][quarterNo][passNo].size)); + passNo = (passNo + 1) % 4; + + files[imageNo][quarterNo][passNo].buffer = test_progressive_load_file(ms_sample_path, + "compress/enc_2_2_100_sampleimage3.bin", &(files[imageNo][quarterNo][passNo].size)); + passNo = (passNo + 1) % 4; + + quarterNo = (quarterNo + 1) % 4; + + files[imageNo][quarterNo][passNo].buffer = test_progressive_load_file(ms_sample_path, + "compress/enc_2_3_025_sampleimage3.bin", &(files[imageNo][quarterNo][passNo].size)); + passNo = (passNo + 1) % 4; + + files[imageNo][quarterNo][passNo].buffer = test_progressive_load_file(ms_sample_path, + "compress/enc_2_3_050_sampleimage3.bin", &(files[imageNo][quarterNo][passNo].size)); + passNo = (passNo + 1) % 4; + + files[imageNo][quarterNo][passNo].buffer = test_progressive_load_file(ms_sample_path, + "compress/enc_2_3_075_sampleimage3.bin", &(files[imageNo][quarterNo][passNo].size)); + passNo = (passNo + 1) % 4; + + files[imageNo][quarterNo][passNo].buffer = test_progressive_load_file(ms_sample_path, + "compress/enc_2_3_100_sampleimage3.bin", &(files[imageNo][quarterNo][passNo].size)); + passNo = (passNo + 1) % 4; + + /* check if all test data has been loaded */ + + for (imageNo = 0; imageNo < 3; imageNo++) + { + for (quarterNo = 0; quarterNo < 4; quarterNo++) + { + for (passNo = 0; passNo < 4; passNo++) + { + if (!files[imageNo][quarterNo][passNo].buffer) + return -1; + } + } + } + + return 1; +} + +BYTE* test_progressive_load_bitmap(char* path, char* file, UINT32* size, int quarter) +{ + int status; + BYTE* buffer; + wImage* image; + char* filename; + + filename = GetCombinedPath(path, file); + + if (!filename) + return NULL; + + image = winpr_image_new(); + + if (!image) + return NULL; + + status = winpr_image_read(image, filename); + + if (status < 0) + return NULL; + + buffer = image->data; + *size = image->height * image->scanline; + + test_fill_image_alpha_channel(image->data, image->width, image->height, 0xFF); + test_image_fill_unused_quarters(image->data, image->scanline, image->width, image->height, quarter, 0xFF000000); + + winpr_image_free(image, FALSE); + free(filename); + + return buffer; +} + +int test_progressive_load_bitmaps(char* ms_sample_path, EGFX_SAMPLE_FILE bitmaps[3][4][4]) +{ + int imageNo = 0; + int quarterNo = 0; + int passNo = 0; + + /* image 1 */ + + bitmaps[imageNo][quarterNo][passNo].buffer = test_progressive_load_bitmap(ms_sample_path, + "decompress/dec_0_0_025_sampleimage1.bmp", &(bitmaps[imageNo][quarterNo][passNo].size), quarterNo); + passNo = (passNo + 1) % 4; + + bitmaps[imageNo][quarterNo][passNo].buffer = test_progressive_load_bitmap(ms_sample_path, + "decompress/dec_0_0_050_sampleimage1.bmp", &(bitmaps[imageNo][quarterNo][passNo].size), quarterNo); + passNo = (passNo + 1) % 4; + + bitmaps[imageNo][quarterNo][passNo].buffer = test_progressive_load_bitmap(ms_sample_path, + "decompress/dec_0_0_075_sampleimage1.bmp", &(bitmaps[imageNo][quarterNo][passNo].size), quarterNo); + passNo = (passNo + 1) % 4; + + bitmaps[imageNo][quarterNo][passNo].buffer = test_progressive_load_bitmap(ms_sample_path, + "decompress/dec_0_0_100_sampleimage1.bmp", &(bitmaps[imageNo][quarterNo][passNo].size), quarterNo); + passNo = (passNo + 1) % 4; + + quarterNo = (quarterNo + 1) % 4; + + bitmaps[imageNo][quarterNo][passNo].buffer = test_progressive_load_bitmap(ms_sample_path, + "decompress/dec_0_1_025_sampleimage1.bmp", &(bitmaps[imageNo][quarterNo][passNo].size), quarterNo); + passNo = (passNo + 1) % 4; + + bitmaps[imageNo][quarterNo][passNo].buffer = test_progressive_load_bitmap(ms_sample_path, + "decompress/dec_0_1_050_sampleimage1.bmp", &(bitmaps[imageNo][quarterNo][passNo].size), quarterNo); + passNo = (passNo + 1) % 4; + + bitmaps[imageNo][quarterNo][passNo].buffer = test_progressive_load_bitmap(ms_sample_path, + "decompress/dec_0_1_075_sampleimage1.bmp", &(bitmaps[imageNo][quarterNo][passNo].size), quarterNo); + passNo = (passNo + 1) % 4; + + bitmaps[imageNo][quarterNo][passNo].buffer = test_progressive_load_bitmap(ms_sample_path, + "decompress/dec_0_1_100_sampleimage1.bmp", &(bitmaps[imageNo][quarterNo][passNo].size), quarterNo); + passNo = (passNo + 1) % 4; + + quarterNo = (quarterNo + 1) % 4; + + bitmaps[imageNo][quarterNo][passNo].buffer = test_progressive_load_bitmap(ms_sample_path, + "decompress/dec_0_2_025_sampleimage1.bmp", &(bitmaps[imageNo][quarterNo][passNo].size), quarterNo); + passNo = (passNo + 1) % 4; + + bitmaps[imageNo][quarterNo][passNo].buffer = test_progressive_load_bitmap(ms_sample_path, + "decompress/dec_0_2_050_sampleimage1.bmp", &(bitmaps[imageNo][quarterNo][passNo].size), quarterNo); + passNo = (passNo + 1) % 4; + + bitmaps[imageNo][quarterNo][passNo].buffer = test_progressive_load_bitmap(ms_sample_path, + "decompress/dec_0_2_075_sampleimage1.bmp", &(bitmaps[imageNo][quarterNo][passNo].size), quarterNo); + passNo = (passNo + 1) % 4; + + bitmaps[imageNo][quarterNo][passNo].buffer = test_progressive_load_bitmap(ms_sample_path, + "decompress/dec_0_2_100_sampleimage1.bmp", &(bitmaps[imageNo][quarterNo][passNo].size), quarterNo); + passNo = (passNo + 1) % 4; + + quarterNo = (quarterNo + 1) % 4; + + bitmaps[imageNo][quarterNo][passNo].buffer = test_progressive_load_bitmap(ms_sample_path, + "decompress/dec_0_3_025_sampleimage1.bmp", &(bitmaps[imageNo][quarterNo][passNo].size), quarterNo); + passNo = (passNo + 1) % 4; + + bitmaps[imageNo][quarterNo][passNo].buffer = test_progressive_load_bitmap(ms_sample_path, + "decompress/dec_0_3_050_sampleimage1.bmp", &(bitmaps[imageNo][quarterNo][passNo].size), quarterNo); + passNo = (passNo + 1) % 4; + + bitmaps[imageNo][quarterNo][passNo].buffer = test_progressive_load_bitmap(ms_sample_path, + "decompress/dec_0_3_075_sampleimage1.bmp", &(bitmaps[imageNo][quarterNo][passNo].size), quarterNo); + passNo = (passNo + 1) % 4; + + bitmaps[imageNo][quarterNo][passNo].buffer = test_progressive_load_bitmap(ms_sample_path, + "decompress/dec_0_3_100_sampleimage1.bmp", &(bitmaps[imageNo][quarterNo][passNo].size), quarterNo); + passNo = (passNo + 1) % 4; + + imageNo++; + + /* image 2 */ + + bitmaps[imageNo][quarterNo][passNo].buffer = test_progressive_load_bitmap(ms_sample_path, + "decompress/dec_1_0_025_sampleimage2.bmp", &(bitmaps[imageNo][quarterNo][passNo].size), quarterNo); + passNo = (passNo + 1) % 4; + + bitmaps[imageNo][quarterNo][passNo].buffer = test_progressive_load_bitmap(ms_sample_path, + "decompress/dec_1_0_050_sampleimage2.bmp", &(bitmaps[imageNo][quarterNo][passNo].size), quarterNo); + passNo = (passNo + 1) % 4; + + bitmaps[imageNo][quarterNo][passNo].buffer = test_progressive_load_bitmap(ms_sample_path, + "decompress/dec_1_0_075_sampleimage2.bmp", &(bitmaps[imageNo][quarterNo][passNo].size), quarterNo); + passNo = (passNo + 1) % 4; + + bitmaps[imageNo][quarterNo][passNo].buffer = test_progressive_load_bitmap(ms_sample_path, + "decompress/dec_1_0_100_sampleimage2.bmp", &(bitmaps[imageNo][quarterNo][passNo].size), quarterNo); + passNo = (passNo + 1) % 4; + + quarterNo = (quarterNo + 1) % 4; + + bitmaps[imageNo][quarterNo][passNo].buffer = test_progressive_load_bitmap(ms_sample_path, + "decompress/dec_1_1_025_sampleimage2.bmp", &(bitmaps[imageNo][quarterNo][passNo].size), quarterNo); + passNo = (passNo + 1) % 4; + + bitmaps[imageNo][quarterNo][passNo].buffer = test_progressive_load_bitmap(ms_sample_path, + "decompress/dec_1_1_050_sampleimage2.bmp", &(bitmaps[imageNo][quarterNo][passNo].size), quarterNo); + passNo = (passNo + 1) % 4; + + bitmaps[imageNo][quarterNo][passNo].buffer = test_progressive_load_bitmap(ms_sample_path, + "decompress/dec_1_1_075_sampleimage2.bmp", &(bitmaps[imageNo][quarterNo][passNo].size), quarterNo); + passNo = (passNo + 1) % 4; + + bitmaps[imageNo][quarterNo][passNo].buffer = test_progressive_load_bitmap(ms_sample_path, + "decompress/dec_1_1_100_sampleimage2.bmp", &(bitmaps[imageNo][quarterNo][passNo].size), quarterNo); + passNo = (passNo + 1) % 4; + + quarterNo = (quarterNo + 1) % 4; + + bitmaps[imageNo][quarterNo][passNo].buffer = test_progressive_load_bitmap(ms_sample_path, + "decompress/dec_1_2_025_sampleimage2.bmp", &(bitmaps[imageNo][quarterNo][passNo].size), quarterNo); + passNo = (passNo + 1) % 4; + + bitmaps[imageNo][quarterNo][passNo].buffer = test_progressive_load_bitmap(ms_sample_path, + "decompress/dec_1_2_050_sampleimage2.bmp", &(bitmaps[imageNo][quarterNo][passNo].size), quarterNo); + passNo = (passNo + 1) % 4; + + bitmaps[imageNo][quarterNo][passNo].buffer = test_progressive_load_bitmap(ms_sample_path, + "decompress/dec_1_2_075_sampleimage2.bmp", &(bitmaps[imageNo][quarterNo][passNo].size), quarterNo); + passNo = (passNo + 1) % 4; + + bitmaps[imageNo][quarterNo][passNo].buffer = test_progressive_load_bitmap(ms_sample_path, + "decompress/dec_1_2_100_sampleimage2.bmp", &(bitmaps[imageNo][quarterNo][passNo].size), quarterNo); + passNo = (passNo + 1) % 4; + + quarterNo = (quarterNo + 1) % 4; + + bitmaps[imageNo][quarterNo][passNo].buffer = test_progressive_load_bitmap(ms_sample_path, + "decompress/dec_1_3_025_sampleimage2.bmp", &(bitmaps[imageNo][quarterNo][passNo].size), quarterNo); + passNo = (passNo + 1) % 4; + + bitmaps[imageNo][quarterNo][passNo].buffer = test_progressive_load_bitmap(ms_sample_path, + "decompress/dec_1_3_050_sampleimage2.bmp", &(bitmaps[imageNo][quarterNo][passNo].size), quarterNo); + passNo = (passNo + 1) % 4; + + bitmaps[imageNo][quarterNo][passNo].buffer = test_progressive_load_bitmap(ms_sample_path, + "decompress/dec_1_3_075_sampleimage2.bmp", &(bitmaps[imageNo][quarterNo][passNo].size), quarterNo); + passNo = (passNo + 1) % 4; + + bitmaps[imageNo][quarterNo][passNo].buffer = test_progressive_load_bitmap(ms_sample_path, + "decompress/dec_1_3_100_sampleimage2.bmp", &(bitmaps[imageNo][quarterNo][passNo].size), quarterNo); + passNo = (passNo + 1) % 4; + + imageNo++; + + /* image 3 */ + + bitmaps[imageNo][quarterNo][passNo].buffer = test_progressive_load_bitmap(ms_sample_path, + "decompress/dec_2_0_025_sampleimage3.bmp", &(bitmaps[imageNo][quarterNo][passNo].size), quarterNo); + passNo = (passNo + 1) % 4; + + bitmaps[imageNo][quarterNo][passNo].buffer = test_progressive_load_bitmap(ms_sample_path, + "decompress/dec_2_0_050_sampleimage3.bmp", &(bitmaps[imageNo][quarterNo][passNo].size), quarterNo); + passNo = (passNo + 1) % 4; + + bitmaps[imageNo][quarterNo][passNo].buffer = test_progressive_load_bitmap(ms_sample_path, + "decompress/dec_2_0_075_sampleimage3.bmp", &(bitmaps[imageNo][quarterNo][passNo].size), quarterNo); + passNo = (passNo + 1) % 4; + + bitmaps[imageNo][quarterNo][passNo].buffer = test_progressive_load_bitmap(ms_sample_path, + "decompress/dec_2_0_100_sampleimage3.bmp", &(bitmaps[imageNo][quarterNo][passNo].size), quarterNo); + passNo = (passNo + 1) % 4; + + quarterNo = (quarterNo + 1) % 4; + + bitmaps[imageNo][quarterNo][passNo].buffer = test_progressive_load_bitmap(ms_sample_path, + "decompress/dec_2_1_025_sampleimage3.bmp", &(bitmaps[imageNo][quarterNo][passNo].size), quarterNo); + passNo = (passNo + 1) % 4; + + bitmaps[imageNo][quarterNo][passNo].buffer = test_progressive_load_bitmap(ms_sample_path, + "decompress/dec_2_1_050_sampleimage3.bmp", &(bitmaps[imageNo][quarterNo][passNo].size), quarterNo); + passNo = (passNo + 1) % 4; + + bitmaps[imageNo][quarterNo][passNo].buffer = test_progressive_load_bitmap(ms_sample_path, + "decompress/dec_2_1_075_sampleimage3.bmp", &(bitmaps[imageNo][quarterNo][passNo].size), quarterNo); + passNo = (passNo + 1) % 4; + + bitmaps[imageNo][quarterNo][passNo].buffer = test_progressive_load_bitmap(ms_sample_path, + "decompress/dec_2_1_100_sampleimage3.bmp", &(bitmaps[imageNo][quarterNo][passNo].size), quarterNo); + passNo = (passNo + 1) % 4; + + quarterNo = (quarterNo + 1) % 4; + + bitmaps[imageNo][quarterNo][passNo].buffer = test_progressive_load_bitmap(ms_sample_path, + "decompress/dec_2_2_025_sampleimage3.bmp", &(bitmaps[imageNo][quarterNo][passNo].size), quarterNo); + passNo = (passNo + 1) % 4; + + bitmaps[imageNo][quarterNo][passNo].buffer = test_progressive_load_bitmap(ms_sample_path, + "decompress/dec_2_2_050_sampleimage3.bmp", &(bitmaps[imageNo][quarterNo][passNo].size), quarterNo); + passNo = (passNo + 1) % 4; + + bitmaps[imageNo][quarterNo][passNo].buffer = test_progressive_load_bitmap(ms_sample_path, + "decompress/dec_2_2_075_sampleimage3.bmp", &(bitmaps[imageNo][quarterNo][passNo].size), quarterNo); + passNo = (passNo + 1) % 4; + + bitmaps[imageNo][quarterNo][passNo].buffer = test_progressive_load_bitmap(ms_sample_path, + "decompress/dec_2_2_100_sampleimage3.bmp", &(bitmaps[imageNo][quarterNo][passNo].size), quarterNo); + passNo = (passNo + 1) % 4; + + quarterNo = (quarterNo + 1) % 4; + + bitmaps[imageNo][quarterNo][passNo].buffer = test_progressive_load_bitmap(ms_sample_path, + "decompress/dec_2_3_025_sampleimage3.bmp", &(bitmaps[imageNo][quarterNo][passNo].size), quarterNo); + passNo = (passNo + 1) % 4; + + bitmaps[imageNo][quarterNo][passNo].buffer = test_progressive_load_bitmap(ms_sample_path, + "decompress/dec_2_3_050_sampleimage3.bmp", &(bitmaps[imageNo][quarterNo][passNo].size), quarterNo); + passNo = (passNo + 1) % 4; + + bitmaps[imageNo][quarterNo][passNo].buffer = test_progressive_load_bitmap(ms_sample_path, + "decompress/dec_2_3_075_sampleimage3.bmp", &(bitmaps[imageNo][quarterNo][passNo].size), quarterNo); + passNo = (passNo + 1) % 4; + + bitmaps[imageNo][quarterNo][passNo].buffer = test_progressive_load_bitmap(ms_sample_path, + "decompress/dec_2_3_100_sampleimage3.bmp", &(bitmaps[imageNo][quarterNo][passNo].size), quarterNo); + passNo = (passNo + 1) % 4; + + /* check if all test data has been loaded */ + + for (imageNo = 0; imageNo < 3; imageNo++) + { + for (quarterNo = 0; quarterNo < 4; quarterNo++) + { + for (passNo = 0; passNo < 4; passNo++) + { + if (!bitmaps[imageNo][quarterNo][passNo].buffer) + return -1; + } + } + } + + return 1; +} + +static int test_memcmp_offset(const BYTE* mem1, const BYTE* mem2, int size) +{ + int index = 0; + + while ((index < size) && (*mem1 == *mem2)) + { + mem1++; + mem2++; + index++; + } + + return (index == size) ? 1 : -index; +} + +static int test_memcmp_count(const BYTE* mem1, const BYTE* mem2, int size) +{ + int count = 0; + int index = 0; + + for (index = 0; index < size; index++) + { + if (*mem1 != *mem2) + count++; + + mem1++; + mem2++; + } + + return count; +} + +int test_progressive_decode(PROGRESSIVE_CONTEXT* progressive, EGFX_SAMPLE_FILE files[4], EGFX_SAMPLE_FILE bitmaps[4], int quarter, int count) +{ + int cmp; + int cnt; + int pass; + int size; + int index; + int status; + int nXSrc, nYSrc; + int nXDst, nYDst; + int nWidth, nHeight; + RECTANGLE_16 tileRect; + RECTANGLE_16 updateRect; + RECTANGLE_16 clippingRect; + RFX_PROGRESSIVE_TILE* tile; + PROGRESSIVE_BLOCK_REGION* region; + + clippingRect.left = 0; + clippingRect.top = 0; + clippingRect.right = g_Width; + clippingRect.bottom = g_Height; + + for (pass = 0; pass < count; pass++) + { + status = progressive_decompress(progressive, files[pass].buffer, files[pass].size, + &g_DstData, PIXEL_FORMAT_XRGB32, g_DstStep, 0, 0, g_Width, g_Height, 0); + + printf("ProgressiveDecompress: status: %d pass: %d\n", status, pass + 1); + + region = &(progressive->region); + + switch (quarter) + { + case 0: + clippingRect.left = 0; + clippingRect.top = 0; + clippingRect.right = g_Width / 2; + clippingRect.bottom = g_Height /2; + break; + + case 1: + clippingRect.left = g_Width / 2; + clippingRect.top = g_Height / 2; + clippingRect.right = g_Width; + clippingRect.bottom = g_Height; + break; + + case 2: + clippingRect.left = g_Width / 2; + clippingRect.top = 0; + clippingRect.right = g_Width; + clippingRect.bottom = g_Height / 2; + break; + + case 3: + clippingRect.left = 0; + clippingRect.top = g_Height / 2; + clippingRect.right = g_Width / 2; + clippingRect.bottom = g_Height; + break; + } + + for (index = 0; index < region->numTiles; index++) + { + tile = region->tiles[index]; + + tileRect.left = tile->x; + tileRect.top = tile->y; + tileRect.right = tile->x + tile->width; + tileRect.bottom = tile->y + tile->height; + + rectangles_intersection(&tileRect, &clippingRect, &updateRect); + + nXDst = updateRect.left; + nYDst = updateRect.top; + nWidth = updateRect.right - updateRect.left; + nHeight = updateRect.bottom - updateRect.top; + + if ((nWidth <= 0) || (nHeight <= 0)) + continue; + + nXSrc = nXDst - tile->x; + nYSrc = nYDst - tile->y; + + freerdp_image_copy(g_DstData, PIXEL_FORMAT_XRGB32, g_DstStep, + nXDst, nYDst, nWidth, nHeight, tile->data, + PIXEL_FORMAT_XRGB32, 64 * 4, nXSrc, nYSrc); + } + + size = bitmaps[pass].size; + cmp = test_memcmp_offset(g_DstData, bitmaps[pass].buffer, size); + cnt = test_memcmp_count(g_DstData, bitmaps[pass].buffer, size); + + if (cmp <= 0) + { + float rate = ((float) cnt) / ((float) size) * 100.0f; + + cmp *= -1; + + printf("Progressive RemoteFX decompression failure\n"); + + printf("Actual, Expected (offset: %d diff: %d/%d = %.3f%%):\n", + cmp, cnt, size, rate); + + winpr_HexDump(&g_DstData[cmp], 16); + winpr_HexDump(&bitmaps[pass].buffer[cmp], 16); + } + + //WLog_Image(progressive->log, WLOG_TRACE, g_DstData, g_Width, g_Height, 32); + } + + return 1; +} + +int test_progressive_ms_sample(char* ms_sample_path) +{ + int count; + int status; + EGFX_SAMPLE_FILE files[3][4][4]; + EGFX_SAMPLE_FILE bitmaps[3][4][4]; + PROGRESSIVE_CONTEXT* progressive; + + g_Width = 1920; + g_Height = 1080; + g_DstStep = g_Width * 4; + + status = test_progressive_load_files(ms_sample_path, files); + + if (status < 0) + return -1; + + status = test_progressive_load_bitmaps(ms_sample_path, bitmaps); + + if (status < 0) + return -1; + + count = 1; + + progressive = progressive_context_new(FALSE); + + g_DstData = _aligned_malloc(g_DstStep * g_Height, 16); + + progressive_create_surface_context(progressive, 0, g_Width, g_Height); + + /* image 1 */ + + if (1) + { + printf("Sample Image 1\n"); + test_image_fill(g_DstData, g_DstStep, 0, 0, g_Width, g_Height, 0xFF000000); + test_progressive_decode(progressive, files[0][0], bitmaps[0][0], 0, count); + test_progressive_decode(progressive, files[0][1], bitmaps[0][1], 1, count); + test_progressive_decode(progressive, files[0][2], bitmaps[0][2], 2, count); + test_progressive_decode(progressive, files[0][3], bitmaps[0][3], 3, count); + } + + /* image 2 (incorrect) */ + + if (0) + { + printf("Sample Image 2\n"); + test_image_fill(g_DstData, g_DstStep, 0, 0, g_Width, g_Height, 0xFF000000); + test_progressive_decode(progressive, files[1][0], bitmaps[1][0], 0, count); + test_progressive_decode(progressive, files[1][1], bitmaps[1][1], 1, count); + test_progressive_decode(progressive, files[1][2], bitmaps[1][2], 2, count); + test_progressive_decode(progressive, files[1][3], bitmaps[1][3], 3, count); + } + + /* image 3 */ + + if (0) + { + printf("Sample Image 3\n"); + test_image_fill(g_DstData, g_DstStep, 0, 0, g_Width, g_Height, 0xFF000000); + test_progressive_decode(progressive, files[2][0], bitmaps[2][0], 0, count); + test_progressive_decode(progressive, files[2][1], bitmaps[2][1], 1, count); + test_progressive_decode(progressive, files[2][2], bitmaps[2][2], 2, count); + test_progressive_decode(progressive, files[2][3], bitmaps[2][3], 3, count); + } + + progressive_context_free(progressive); + + _aligned_free(g_DstData); + return 0; } +int TestFreeRDPCodecProgressive(int argc, char* argv[]) +{ + char* ms_sample_path; + + ms_sample_path = _strdup("/tmp/EGFX_PROGRESSIVE_MS_SAMPLE"); + + if (PathFileExistsA(ms_sample_path)) + return test_progressive_ms_sample(ms_sample_path); + + free(ms_sample_path); + + return 0; +} diff --git a/libfreerdp/codec/xcrush.c b/libfreerdp/codec/xcrush.c index e32285d71..cc7142d24 100644 --- a/libfreerdp/codec/xcrush.c +++ b/libfreerdp/codec/xcrush.c @@ -990,7 +990,7 @@ int xcrush_compress(XCRUSH_CONTEXT* xcrush, BYTE* pSrcData, UINT32 SrcSize, BYTE OriginalData[1] = (BYTE) Level2ComprFlags; #if 0 - printf("XCrushCompress: Level1ComprFlags: %s Level2ComprFlags: %s\n", + DEBUG_MSG("XCrushCompress: Level1ComprFlags: %s Level2ComprFlags: %s\n", xcrush_get_level_1_compression_flags_string(Level1ComprFlags), xcrush_get_level_2_compression_flags_string(Level2ComprFlags)); #endif diff --git a/libfreerdp/common/assistance.c b/libfreerdp/common/assistance.c index efeadaf08..7f2e9566e 100644 --- a/libfreerdp/common/assistance.c +++ b/libfreerdp/common/assistance.c @@ -34,6 +34,7 @@ #include #include +#include #include #include @@ -273,6 +274,7 @@ int freerdp_assistance_parse_connection_string2(rdpAssistanceFile* file) { char* p; char* q; + int port; char* str; size_t length; @@ -344,6 +346,52 @@ int freerdp_assistance_parse_connection_string2(rdpAssistanceFile* file) p += length; } + p = strstr(p, " 8) + { + if (strncmp(p, "169.254.", 8) != 0) + { + file->MachineAddress = _strdup(p); + file->MachinePort = (UINT32) port; + break; + } + } + + p = strstr(q, " #include +#include int freerdp_addin_set_argument(ADDIN_ARGV* args, char* argument) { @@ -339,7 +340,7 @@ out_parallel_name_error: } - fprintf(stderr, "%s: unknown device type %d\n", __FUNCTION__, device->Type); + DEBUG_WARN( "%s: unknown device type %d\n", __FUNCTION__, device->Type); return NULL; } @@ -657,507 +658,380 @@ BOOL freerdp_get_param_bool(rdpSettings* settings, int id) { case FreeRDP_ServerMode: return settings->ServerMode; - break; case FreeRDP_NetworkAutoDetect: return settings->NetworkAutoDetect; - break; case FreeRDP_SupportAsymetricKeys: return settings->SupportAsymetricKeys; - break; case FreeRDP_SupportErrorInfoPdu: return settings->SupportErrorInfoPdu; - break; case FreeRDP_SupportStatusInfoPdu: return settings->SupportStatusInfoPdu; - break; case FreeRDP_SupportMonitorLayoutPdu: return settings->SupportMonitorLayoutPdu; - break; case FreeRDP_SupportGraphicsPipeline: return settings->SupportGraphicsPipeline; - break; case FreeRDP_SupportDynamicTimeZone: return settings->SupportDynamicTimeZone; - break; case FreeRDP_DisableEncryption: return settings->DisableEncryption; - break; case FreeRDP_ConsoleSession: return settings->ConsoleSession; - break; case FreeRDP_SpanMonitors: return settings->SpanMonitors; - break; case FreeRDP_UseMultimon: return settings->UseMultimon; - break; case FreeRDP_ForceMultimon: return settings->ForceMultimon; - break; case FreeRDP_AutoLogonEnabled: return settings->AutoLogonEnabled; - break; case FreeRDP_CompressionEnabled: return settings->CompressionEnabled; - break; case FreeRDP_DisableCtrlAltDel: return settings->DisableCtrlAltDel; - break; case FreeRDP_EnableWindowsKey: return settings->EnableWindowsKey; - break; case FreeRDP_MaximizeShell: return settings->MaximizeShell; - break; case FreeRDP_LogonNotify: return settings->LogonNotify; - break; case FreeRDP_LogonErrors: return settings->LogonErrors; - break; case FreeRDP_MouseAttached: return settings->MouseAttached; - break; case FreeRDP_MouseHasWheel: return settings->MouseHasWheel; - break; case FreeRDP_RemoteConsoleAudio: return settings->RemoteConsoleAudio; - break; case FreeRDP_AudioPlayback: return settings->AudioPlayback; - break; case FreeRDP_AudioCapture: return settings->AudioCapture; - break; case FreeRDP_VideoDisable: return settings->VideoDisable; - break; case FreeRDP_PasswordIsSmartcardPin: return settings->PasswordIsSmartcardPin; - break; case FreeRDP_UsingSavedCredentials: return settings->UsingSavedCredentials; - break; case FreeRDP_ForceEncryptedCsPdu: return settings->ForceEncryptedCsPdu; - break; case FreeRDP_HiDefRemoteApp: return settings->HiDefRemoteApp; - break; case FreeRDP_IPv6Enabled: return settings->IPv6Enabled; - break; case FreeRDP_AutoReconnectionEnabled: return settings->AutoReconnectionEnabled; - break; case FreeRDP_DynamicDaylightTimeDisabled: return settings->DynamicDaylightTimeDisabled; - break; case FreeRDP_AllowFontSmoothing: return settings->AllowFontSmoothing; - break; case FreeRDP_DisableWallpaper: return settings->DisableWallpaper; - break; case FreeRDP_DisableFullWindowDrag: return settings->DisableFullWindowDrag; - break; case FreeRDP_DisableMenuAnims: return settings->DisableMenuAnims; - break; case FreeRDP_DisableThemes: return settings->DisableThemes; - break; case FreeRDP_DisableCursorShadow: return settings->DisableCursorShadow; - break; case FreeRDP_DisableCursorBlinking: return settings->DisableCursorBlinking; - break; case FreeRDP_AllowDesktopComposition: return settings->AllowDesktopComposition; - break; case FreeRDP_RemoteAssistanceMode: return settings->RemoteAssistanceMode; - break; case FreeRDP_TlsSecurity: return settings->TlsSecurity; - break; case FreeRDP_NlaSecurity: return settings->NlaSecurity; - break; case FreeRDP_RdpSecurity: return settings->RdpSecurity; - break; case FreeRDP_ExtSecurity: return settings->ExtSecurity; - break; case FreeRDP_Authentication: return settings->Authentication; - break; case FreeRDP_NegotiateSecurityLayer: return settings->NegotiateSecurityLayer; - break; case FreeRDP_RestrictedAdminModeRequired: return settings->RestrictedAdminModeRequired; - break; case FreeRDP_DisableCredentialsDelegation: return settings->DisableCredentialsDelegation; - break; case FreeRDP_AuthenticationLevel: return settings->AuthenticationLevel; - break; case FreeRDP_MstscCookieMode: return settings->MstscCookieMode; - break; case FreeRDP_SendPreconnectionPdu: return settings->SendPreconnectionPdu; - break; case FreeRDP_IgnoreCertificate: return settings->IgnoreCertificate; - break; case FreeRDP_ExternalCertificateManagement: return settings->ExternalCertificateManagement; - break; case FreeRDP_Workarea: return settings->Workarea; - break; case FreeRDP_Fullscreen: return settings->Fullscreen; - break; case FreeRDP_GrabKeyboard: return settings->GrabKeyboard; - break; case FreeRDP_Decorations: return settings->Decorations; - break; case FreeRDP_SmartSizing: return settings->SmartSizing; - break; case FreeRDP_MouseMotion: return settings->MouseMotion; - break; case FreeRDP_AsyncInput: return settings->AsyncInput; - break; case FreeRDP_AsyncUpdate: return settings->AsyncUpdate; - break; case FreeRDP_AsyncChannels: return settings->AsyncChannels; - break; case FreeRDP_AsyncTransport: return settings->AsyncTransport; - break; case FreeRDP_ToggleFullscreen: return settings->ToggleFullscreen; - break; case FreeRDP_SoftwareGdi: return settings->SoftwareGdi; - break; case FreeRDP_LocalConnection: return settings->LocalConnection; - break; case FreeRDP_AuthenticationOnly: return settings->AuthenticationOnly; - break; case FreeRDP_CredentialsFromStdin: return settings->CredentialsFromStdin; - break; case FreeRDP_DumpRemoteFx: return settings->DumpRemoteFx; - break; case FreeRDP_PlayRemoteFx: return settings->PlayRemoteFx; - break; case FreeRDP_GatewayUseSameCredentials: return settings->GatewayUseSameCredentials; - break; case FreeRDP_GatewayEnabled: return settings->GatewayEnabled; - break; case FreeRDP_GatewayBypassLocal: return settings->GatewayBypassLocal; - break; case FreeRDP_RemoteApplicationMode: return settings->RemoteApplicationMode; - break; case FreeRDP_DisableRemoteAppCapsCheck: return settings->DisableRemoteAppCapsCheck; - break; case FreeRDP_RemoteAppLanguageBarSupported: return settings->RemoteAppLanguageBarSupported; - break; case FreeRDP_RefreshRect: return settings->RefreshRect; - break; case FreeRDP_SuppressOutput: return settings->SuppressOutput; - break; case FreeRDP_FastPathOutput: return settings->FastPathOutput; - break; case FreeRDP_SaltedChecksum: return settings->SaltedChecksum; - break; case FreeRDP_LongCredentialsSupported: return settings->LongCredentialsSupported; - break; case FreeRDP_NoBitmapCompressionHeader: return settings->NoBitmapCompressionHeader; - break; case FreeRDP_BitmapCompressionDisabled: return settings->BitmapCompressionDisabled; - break; case FreeRDP_DesktopResize: return settings->DesktopResize; - break; case FreeRDP_DrawAllowDynamicColorFidelity: return settings->DrawAllowDynamicColorFidelity; - break; case FreeRDP_DrawAllowColorSubsampling: return settings->DrawAllowColorSubsampling; - break; case FreeRDP_DrawAllowSkipAlpha: return settings->DrawAllowSkipAlpha; - break; case FreeRDP_BitmapCacheV3Enabled: return settings->BitmapCacheV3Enabled; - break; case FreeRDP_AltSecFrameMarkerSupport: return settings->AltSecFrameMarkerSupport; - break; case FreeRDP_BitmapCacheEnabled: return settings->BitmapCacheEnabled; - break; case FreeRDP_AllowCacheWaitingList: return settings->AllowCacheWaitingList; - break; case FreeRDP_BitmapCachePersistEnabled: return settings->BitmapCachePersistEnabled; - break; case FreeRDP_ColorPointerFlag: return settings->ColorPointerFlag; - break; case FreeRDP_UnicodeInput: return settings->UnicodeInput; - break; case FreeRDP_FastPathInput: return settings->FastPathInput; - break; case FreeRDP_MultiTouchInput: return settings->MultiTouchInput; - break; case FreeRDP_MultiTouchGestures: return settings->MultiTouchGestures; - break; case FreeRDP_SoundBeepsEnabled: return settings->SoundBeepsEnabled; - break; case FreeRDP_SurfaceCommandsEnabled: return settings->SurfaceCommandsEnabled; - break; case FreeRDP_FrameMarkerCommandEnabled: return settings->FrameMarkerCommandEnabled; - break; case FreeRDP_RemoteFxOnly: return settings->RemoteFxOnly; - break; case FreeRDP_RemoteFxCodec: return settings->RemoteFxCodec; - break; case FreeRDP_RemoteFxImageCodec: return settings->RemoteFxImageCodec; - break; case FreeRDP_NSCodec: return settings->NSCodec; - break; case FreeRDP_FrameAcknowledge: return settings->FrameAcknowledge; - break; case FreeRDP_JpegCodec: return settings->JpegCodec; - break; case FreeRDP_GfxThinClient: return settings->GfxThinClient; - break; case FreeRDP_GfxSmallCache: return settings->GfxSmallCache; - break; case FreeRDP_GfxProgressive: return settings->GfxProgressive; - break; case FreeRDP_GfxProgressiveV2: return settings->GfxProgressiveV2; - break; case FreeRDP_GfxH264: return settings->GfxH264; - break; case FreeRDP_DrawNineGridEnabled: return settings->DrawNineGridEnabled; - break; case FreeRDP_DrawGdiPlusEnabled: return settings->DrawGdiPlusEnabled; - break; case FreeRDP_DrawGdiPlusCacheEnabled: return settings->DrawGdiPlusCacheEnabled; - break; case FreeRDP_DeviceRedirection: return settings->DeviceRedirection; - break; case FreeRDP_RedirectDrives: return settings->RedirectDrives; - break; case FreeRDP_RedirectHomeDrive: return settings->RedirectHomeDrive; - break; case FreeRDP_RedirectSmartCards: return settings->RedirectSmartCards; - break; case FreeRDP_RedirectPrinters: return settings->RedirectPrinters; - break; case FreeRDP_RedirectSerialPorts: return settings->RedirectSerialPorts; - break; case FreeRDP_RedirectParallelPorts: return settings->RedirectParallelPorts; - break; case FreeRDP_RedirectClipboard: return settings->RedirectClipboard; - break; default: - fprintf(stderr, "freerdp_get_param_bool: unknown id: %d\n", id); + DEBUG_WARN( "freerdp_get_param_bool: unknown id: %d\n", id); return -1; - break; } - - return -1; } int freerdp_set_param_bool(rdpSettings* settings, int id, BOOL param) @@ -1661,9 +1535,8 @@ int freerdp_set_param_bool(rdpSettings* settings, int id, BOOL param) break; default: - fprintf(stderr, "freerdp_set_param_bool: unknown id %d (param = %d)\n", id, param); + DEBUG_WARN( "freerdp_set_param_bool: unknown id %d (param = %d)\n", id, param); return -1; - break; } /* Mark field as modified */ @@ -1678,19 +1551,14 @@ int freerdp_get_param_int(rdpSettings* settings, int id) { case FreeRDP_XPan: return settings->XPan; - break; case FreeRDP_YPan: return settings->YPan; - break; default: - fprintf(stderr, "freerdp_get_param_int: unknown id: %d\n", id); + DEBUG_WARN( "freerdp_get_param_int: unknown id: %d\n", id); return 0; - break; } - - return 0; } int freerdp_set_param_int(rdpSettings* settings, int id, int param) @@ -1706,9 +1574,8 @@ int freerdp_set_param_int(rdpSettings* settings, int id, int param) break; default: - fprintf(stderr, "freerdp_set_param_int: unknown id %d (param = %d)\n", id, param); + DEBUG_WARN( "freerdp_set_param_int: unknown id %d (param = %d)\n", id, param); return -1; - break; } settings->SettingsModified[id] = 1; @@ -1722,203 +1589,159 @@ UINT32 freerdp_get_param_uint32(rdpSettings* settings, int id) { case FreeRDP_ShareId: return settings->ShareId; - break; case FreeRDP_PduSource: return settings->PduSource; - break; case FreeRDP_ServerPort: return settings->ServerPort; - break; case FreeRDP_RdpVersion: return settings->RdpVersion; - break; case FreeRDP_DesktopWidth: return settings->DesktopWidth; - break; case FreeRDP_DesktopHeight: return settings->DesktopHeight; - break; case FreeRDP_ColorDepth: return settings->ColorDepth; - break; case FreeRDP_ConnectionType: return settings->ConnectionType; - break; case FreeRDP_ClientBuild: return settings->ClientBuild; - break; case FreeRDP_EarlyCapabilityFlags: return settings->EarlyCapabilityFlags; - break; case FreeRDP_EncryptionMethods: return settings->EncryptionMethods; - break; case FreeRDP_ExtEncryptionMethods: return settings->ExtEncryptionMethods; - break; case FreeRDP_EncryptionLevel: return settings->EncryptionLevel; - break; + + case FreeRDP_ServerRandomLength: + return settings->ServerRandomLength; + + case FreeRDP_ClientRandomLength: + return settings->ClientRandomLength; case FreeRDP_ChannelCount: return settings->ChannelCount; - break; case FreeRDP_ChannelDefArraySize: return settings->ChannelDefArraySize; - break; case FreeRDP_ClusterInfoFlags: return settings->ClusterInfoFlags; - break; case FreeRDP_RedirectedSessionId: return settings->RedirectedSessionId; - break; case FreeRDP_MonitorDefArraySize: return settings->MonitorDefArraySize; - break; case FreeRDP_DesktopPosX: return settings->DesktopPosX; - break; case FreeRDP_DesktopPosY: return settings->DesktopPosY; - break; case FreeRDP_MultitransportFlags: return settings->MultitransportFlags; - break; case FreeRDP_CompressionLevel: return settings->CompressionLevel; - break; case FreeRDP_AutoReconnectMaxRetries: return settings->AutoReconnectMaxRetries; - break; case FreeRDP_PerformanceFlags: return settings->PerformanceFlags; - break; case FreeRDP_RequestedProtocols: return settings->RequestedProtocols; - break; case FreeRDP_SelectedProtocol: return settings->SelectedProtocol; - break; case FreeRDP_NegotiationFlags: return settings->NegotiationFlags; - break; case FreeRDP_CookieMaxLength: return settings->CookieMaxLength; - break; case FreeRDP_PreconnectionId: return settings->PreconnectionId; - break; case FreeRDP_RedirectionFlags: return settings->RedirectionFlags; - break; case FreeRDP_LoadBalanceInfoLength: return settings->LoadBalanceInfoLength; - break; case FreeRDP_RedirectionPasswordLength: return settings->RedirectionPasswordLength; - break; case FreeRDP_RedirectionTsvUrlLength: return settings->RedirectionTsvUrlLength; - break; case FreeRDP_TargetNetAddressCount: return settings->TargetNetAddressCount; - break; case FreeRDP_PercentScreen: return settings->PercentScreen; - break; case FreeRDP_GatewayUsageMethod: return settings->GatewayUsageMethod; - break; case FreeRDP_GatewayPort: return settings->GatewayPort; - break; case FreeRDP_GatewayCredentialsSource: return settings->GatewayCredentialsSource; - break; case FreeRDP_RemoteAppNumIconCaches: return settings->RemoteAppNumIconCaches; - break; case FreeRDP_RemoteAppNumIconCacheEntries: return settings->RemoteAppNumIconCacheEntries; - break; case FreeRDP_ReceivedCapabilitiesSize: return settings->ReceivedCapabilitiesSize; - break; case FreeRDP_OsMajorType: return settings->OsMajorType; - break; case FreeRDP_OsMinorType: return settings->OsMinorType; - break; case FreeRDP_BitmapCacheVersion: return settings->BitmapCacheVersion; - break; case FreeRDP_BitmapCacheV2NumCells: return settings->BitmapCacheV2NumCells; - break; case FreeRDP_PointerCacheSize: return settings->PointerCacheSize; - break; case FreeRDP_KeyboardLayout: return settings->KeyboardLayout; - break; case FreeRDP_KeyboardType: return settings->KeyboardType; - break; case FreeRDP_KeyboardSubType: return settings->KeyboardSubType; - break; case FreeRDP_KeyboardFunctionKey: return settings->KeyboardFunctionKey; - break; case FreeRDP_KeyboardHook: return settings->KeyboardHook; @@ -1926,107 +1749,80 @@ UINT32 freerdp_get_param_uint32(rdpSettings* settings, int id) case FreeRDP_BrushSupportLevel: return settings->BrushSupportLevel; - break; case FreeRDP_GlyphSupportLevel: return settings->GlyphSupportLevel; - break; case FreeRDP_OffscreenSupportLevel: return settings->OffscreenSupportLevel; - break; case FreeRDP_OffscreenCacheSize: return settings->OffscreenCacheSize; - break; case FreeRDP_OffscreenCacheEntries: return settings->OffscreenCacheEntries; - break; case FreeRDP_VirtualChannelCompressionFlags: return settings->VirtualChannelCompressionFlags; - break; case FreeRDP_VirtualChannelChunkSize: return settings->VirtualChannelChunkSize; - break; case FreeRDP_MultifragMaxRequestSize: return settings->MultifragMaxRequestSize; - break; case FreeRDP_LargePointerFlag: return settings->LargePointerFlag; - break; case FreeRDP_CompDeskSupportLevel: return settings->CompDeskSupportLevel; - break; case FreeRDP_RemoteFxCodecId: return settings->RemoteFxCodecId; - break; case FreeRDP_RemoteFxCodecMode: return settings->RemoteFxCodecMode; - break; case FreeRDP_NSCodecId: return settings->NSCodecId; - break; case FreeRDP_JpegCodecId: return settings->JpegCodecId; - break; case FreeRDP_JpegQuality: return settings->JpegQuality; - break; case FreeRDP_BitmapCacheV3CodecId: return settings->BitmapCacheV3CodecId; - break; case FreeRDP_DrawNineGridCacheSize: return settings->DrawNineGridCacheSize; - break; case FreeRDP_DrawNineGridCacheEntries: return settings->DrawNineGridCacheEntries; - break; case FreeRDP_DeviceCount: return settings->DeviceCount; - break; case FreeRDP_DeviceArraySize: return settings->DeviceArraySize; - break; case FreeRDP_StaticChannelCount: return settings->StaticChannelCount; - break; case FreeRDP_StaticChannelArraySize: return settings->StaticChannelArraySize; - break; case FreeRDP_DynamicChannelCount: return settings->DynamicChannelCount; - break; case FreeRDP_DynamicChannelArraySize: return settings->DynamicChannelArraySize; - break; default: - fprintf(stderr, "freerdp_get_param_uint32: unknown id: %d\n", id); + DEBUG_WARN( "freerdp_get_param_uint32: unknown id: %d\n", id); return 0; - break; } - - return 0; } int freerdp_set_param_uint32(rdpSettings* settings, int id, UINT32 param) @@ -2085,6 +1881,14 @@ int freerdp_set_param_uint32(rdpSettings* settings, int id, UINT32 param) settings->EncryptionLevel = param; break; + case FreeRDP_ServerRandomLength: + settings->ServerRandomLength = param; + break; + + case FreeRDP_ClientRandomLength: + settings->ClientRandomLength = param; + break; + case FreeRDP_ChannelCount: settings->ChannelCount = param; break; @@ -2334,9 +2138,8 @@ int freerdp_set_param_uint32(rdpSettings* settings, int id, UINT32 param) break; default: - fprintf(stderr, "freerdp_set_param_uint32: unknown id %d (param = %u)\n", id, param); + DEBUG_WARN( "freerdp_set_param_uint32: unknown id %d (param = %u)\n", id, param); return -1; - break; } /* Mark field as modified */ @@ -2351,15 +2154,11 @@ UINT64 freerdp_get_param_uint64(rdpSettings* settings, int id) { case FreeRDP_ParentWindowId: return settings->ParentWindowId; - break; default: - fprintf(stderr, "freerdp_get_param_uint64: unknown id: %d\n", id); + DEBUG_WARN( "freerdp_get_param_uint64: unknown id: %d\n", id); return -1; - break; } - - return 0; } int freerdp_set_param_uint64(rdpSettings* settings, int id, UINT64 param) @@ -2371,9 +2170,8 @@ int freerdp_set_param_uint64(rdpSettings* settings, int id, UINT64 param) break; default: - fprintf(stderr, "freerdp_set_param_uint64: unknown id %d (param = %u)\n", id, (UINT32) param); + DEBUG_WARN( "freerdp_set_param_uint64: unknown id %d (param = %u)\n", id, (UINT32) param); return -1; - break; } /* Mark field as modified */ @@ -2388,191 +2186,143 @@ char* freerdp_get_param_string(rdpSettings* settings, int id) { case FreeRDP_ServerHostname: return settings->ServerHostname; - break; case FreeRDP_Username: return settings->Username; - break; case FreeRDP_Password: return settings->Password; - break; case FreeRDP_Domain: return settings->Domain; - break; case FreeRDP_PasswordHash: return settings->PasswordHash; - break; case FreeRDP_ClientHostname: return settings->ClientHostname; - break; case FreeRDP_ClientProductId: return settings->ClientProductId; - break; case FreeRDP_AlternateShell: return settings->AlternateShell; - break; case FreeRDP_ShellWorkingDirectory: return settings->ShellWorkingDirectory; - break; case FreeRDP_ClientAddress: return settings->ClientAddress; - break; case FreeRDP_ClientDir: return settings->ClientDir; - break; case FreeRDP_DynamicDSTTimeZoneKeyName: return settings->DynamicDSTTimeZoneKeyName; - break; case FreeRDP_RemoteAssistanceSessionId: return settings->RemoteAssistanceSessionId; - break; case FreeRDP_RemoteAssistancePassStub: return settings->RemoteAssistancePassStub; - break; case FreeRDP_RemoteAssistancePassword: return settings->RemoteAssistancePassword; - break; case FreeRDP_RemoteAssistanceRCTicket: return settings->RemoteAssistanceRCTicket; - break; case FreeRDP_AuthenticationServiceClass: return settings->AuthenticationServiceClass; - break; case FreeRDP_PreconnectionBlob: return settings->PreconnectionBlob; - break; case FreeRDP_KerberosKdc: return settings->KerberosKdc; - break; case FreeRDP_KerberosRealm: return settings->KerberosRealm; - break; case FreeRDP_CertificateName: return settings->CertificateName; - break; case FreeRDP_CertificateFile: return settings->CertificateFile; - break; case FreeRDP_PrivateKeyFile: return settings->PrivateKeyFile; - break; case FreeRDP_RdpKeyFile: return settings->RdpKeyFile; - break; case FreeRDP_WindowTitle: return settings->WindowTitle; - break; case FreeRDP_ComputerName: return settings->ComputerName; - break; case FreeRDP_ConnectionFile: return settings->ConnectionFile; - break; case FreeRDP_AssistanceFile: return settings->AssistanceFile; - break; case FreeRDP_HomePath: return settings->HomePath; - break; case FreeRDP_ConfigPath: return settings->ConfigPath; - break; case FreeRDP_CurrentPath: return settings->CurrentPath; - break; case FreeRDP_DumpRemoteFxFile: return settings->DumpRemoteFxFile; - break; case FreeRDP_PlayRemoteFxFile: return settings->PlayRemoteFxFile; - break; case FreeRDP_GatewayHostname: return settings->GatewayHostname; - break; case FreeRDP_GatewayUsername: return settings->GatewayUsername; - break; case FreeRDP_GatewayPassword: return settings->GatewayPassword; - break; case FreeRDP_GatewayDomain: return settings->GatewayDomain; - break; case FreeRDP_RemoteApplicationName: return settings->RemoteApplicationName; - break; case FreeRDP_RemoteApplicationIcon: return settings->RemoteApplicationIcon; - break; case FreeRDP_RemoteApplicationProgram: return settings->RemoteApplicationProgram; - break; case FreeRDP_RemoteApplicationFile: return settings->RemoteApplicationFile; - break; case FreeRDP_RemoteApplicationGuid: return settings->RemoteApplicationGuid; - break; case FreeRDP_RemoteApplicationCmdLine: return settings->RemoteApplicationCmdLine; - break; case FreeRDP_ImeFileName: return settings->ImeFileName; - break; case FreeRDP_DrivesToRedirect: return settings->DrivesToRedirect; - break; default: - fprintf(stderr, "freerdp_get_param_string: unknown id: %d\n", id); + DEBUG_WARN( "freerdp_get_param_string: unknown id: %d\n", id); return NULL; - break; } - - return NULL; } int freerdp_set_param_string(rdpSettings* settings, int id, const char* param) @@ -2805,9 +2555,8 @@ int freerdp_set_param_string(rdpSettings* settings, int id, const char* param) break; default: - fprintf(stderr, "freerdp_set_param_string: unknown id %d (param = %s)\n", id, param); + DEBUG_WARN( "freerdp_set_param_string: unknown id %d (param = %s)\n", id, param); return -1; - break; } /* Mark field as modified */ @@ -2822,15 +2571,11 @@ double freerdp_get_param_double(rdpSettings* settings, int id) { case FreeRDP_ScalingFactor: return settings->ScalingFactor; - break; default: - fprintf(stderr, "freerdp_get_param_double: unknown id: %d\n", id); + DEBUG_WARN( "freerdp_get_param_double: unknown id: %d\n", id); return 0; - break; } - - return 0; } int freerdp_set_param_double(rdpSettings* settings, int id, double param) @@ -2843,7 +2588,6 @@ int freerdp_set_param_double(rdpSettings* settings, int id, double param) default: return -1; - break; } /* Mark field as modified */ diff --git a/libfreerdp/core/bulk.c b/libfreerdp/core/bulk.c index c79fbc4d9..7569d94ed 100644 --- a/libfreerdp/core/bulk.c +++ b/libfreerdp/core/bulk.c @@ -85,25 +85,25 @@ int bulk_compress_validate(rdpBulk* bulk, BYTE* pSrcData, UINT32 SrcSize, BYTE** if (status < 0) { - printf("compression/decompression failure\n"); + DEBUG_MSG("compression/decompression failure\n"); return status; } if (_DstSize != SrcSize) { - printf("compression/decompression size mismatch: Actual: %d, Expected: %d\n", _DstSize, SrcSize); + DEBUG_MSG("compression/decompression size mismatch: Actual: %d, Expected: %d\n", _DstSize, SrcSize); return -1; } if (memcmp(_pDstData, pSrcData, SrcSize) != 0) { - printf("compression/decompression input/output mismatch! flags: 0x%04X\n", _Flags); + DEBUG_MSG("compression/decompression input/output mismatch! flags: 0x%04X\n", _Flags); #if 1 - printf("Actual:\n"); + DEBUG_MSG("Actual:\n"); winpr_HexDump(_pDstData, SrcSize); - printf("Expected:\n"); + DEBUG_MSG("Expected:\n"); winpr_HexDump(pSrcData, SrcSize); #endif @@ -170,7 +170,7 @@ int bulk_decompress(rdpBulk* bulk, BYTE* pSrcData, UINT32 SrcSize, BYTE** ppDstD #ifdef WITH_BULK_DEBUG { - printf("Decompress Type: %d Flags: %s (0x%04X) Compression Ratio: %f (%d / %d), Total: %f (%u / %u)\n", + DEBUG_MSG("Decompress Type: %d Flags: %s (0x%04X) Compression Ratio: %f (%d / %d), Total: %f (%u / %u)\n", type, bulk_get_compression_flags_string(flags), flags, CompressionRatio, CompressedBytes, UncompressedBytes, metrics->TotalCompressionRatio, (UINT32) metrics->TotalCompressedBytes, @@ -180,7 +180,7 @@ int bulk_decompress(rdpBulk* bulk, BYTE* pSrcData, UINT32 SrcSize, BYTE** ppDstD } else { - fprintf(stderr, "Decompression failure!\n"); + DEBUG_WARN( "Decompression failure!\n"); } return status; @@ -237,7 +237,7 @@ int bulk_compress(rdpBulk* bulk, BYTE* pSrcData, UINT32 SrcSize, BYTE** ppDstDat #ifdef WITH_BULK_DEBUG { - printf("Compress Type: %d Flags: %s (0x%04X) Compression Ratio: %f (%d / %d), Total: %f (%u / %u)\n", + DEBUG_MSG("Compress Type: %d Flags: %s (0x%04X) Compression Ratio: %f (%d / %d), Total: %f (%u / %u)\n", bulk->CompressionLevel, bulk_get_compression_flags_string(*pFlags), *pFlags, CompressionRatio, CompressedBytes, UncompressedBytes, metrics->TotalCompressionRatio, (UINT32) metrics->TotalCompressedBytes, diff --git a/libfreerdp/core/capabilities.c b/libfreerdp/core/capabilities.c index c3725353d..91bc8a931 100644 --- a/libfreerdp/core/capabilities.c +++ b/libfreerdp/core/capabilities.c @@ -262,7 +262,7 @@ BOOL rdp_print_general_capability_set(wStream* s, UINT16 length) if (length < 24) return FALSE; - fprintf(stderr, "GeneralCapabilitySet (length %d):\n", length); + DEBUG_WARN( "GeneralCapabilitySet (length %d):\n", length); Stream_Read_UINT16(s, osMajorType); /* osMajorType (2 bytes) */ Stream_Read_UINT16(s, osMinorType); /* osMinorType (2 bytes) */ @@ -276,17 +276,17 @@ BOOL rdp_print_general_capability_set(wStream* s, UINT16 length) Stream_Read_UINT8(s, refreshRectSupport); /* refreshRectSupport (1 byte) */ Stream_Read_UINT8(s, suppressOutputSupport); /* suppressOutputSupport (1 byte) */ - fprintf(stderr, "\tosMajorType: 0x%04X\n", osMajorType); - fprintf(stderr, "\tosMinorType: 0x%04X\n", osMinorType); - fprintf(stderr, "\tprotocolVersion: 0x%04X\n", protocolVersion); - fprintf(stderr, "\tpad2OctetsA: 0x%04X\n", pad2OctetsA); - fprintf(stderr, "\tgeneralCompressionTypes: 0x%04X\n", generalCompressionTypes); - fprintf(stderr, "\textraFlags: 0x%04X\n", extraFlags); - fprintf(stderr, "\tupdateCapabilityFlag: 0x%04X\n", updateCapabilityFlag); - fprintf(stderr, "\tremoteUnshareFlag: 0x%04X\n", remoteUnshareFlag); - fprintf(stderr, "\tgeneralCompressionLevel: 0x%04X\n", generalCompressionLevel); - fprintf(stderr, "\trefreshRectSupport: 0x%02X\n", refreshRectSupport); - fprintf(stderr, "\tsuppressOutputSupport: 0x%02X\n", suppressOutputSupport); + DEBUG_WARN( "\tosMajorType: 0x%04X\n", osMajorType); + DEBUG_WARN( "\tosMinorType: 0x%04X\n", osMinorType); + DEBUG_WARN( "\tprotocolVersion: 0x%04X\n", protocolVersion); + DEBUG_WARN( "\tpad2OctetsA: 0x%04X\n", pad2OctetsA); + DEBUG_WARN( "\tgeneralCompressionTypes: 0x%04X\n", generalCompressionTypes); + DEBUG_WARN( "\textraFlags: 0x%04X\n", extraFlags); + DEBUG_WARN( "\tupdateCapabilityFlag: 0x%04X\n", updateCapabilityFlag); + DEBUG_WARN( "\tremoteUnshareFlag: 0x%04X\n", remoteUnshareFlag); + DEBUG_WARN( "\tgeneralCompressionLevel: 0x%04X\n", generalCompressionLevel); + DEBUG_WARN( "\trefreshRectSupport: 0x%02X\n", refreshRectSupport); + DEBUG_WARN( "\tsuppressOutputSupport: 0x%02X\n", suppressOutputSupport); return TRUE; } @@ -361,7 +361,15 @@ void rdp_write_bitmap_capability_set(wStream* s, rdpSettings* settings) header = rdp_capability_set_start(s); - drawingFlags |= DRAW_ALLOW_SKIP_ALPHA; + if (settings->DrawAllowSkipAlpha) + drawingFlags |= DRAW_ALLOW_SKIP_ALPHA; + + if (settings->DrawAllowColorSubsampling) + drawingFlags |= DRAW_ALLOW_DYNAMIC_COLOR_FIDELITY; + + if (settings->DrawAllowDynamicColorFidelity) + drawingFlags |= DRAW_ALLOW_COLOR_SUBSAMPLING; /* currently unimplemented */ + /* While bitmap_decode.c now implements YCoCg, in turning it * on we have found Microsoft is inconsistent on whether to invert R & B. * And it's not only from one server to another; on Win7/2008R2, it appears @@ -370,9 +378,6 @@ void rdp_write_bitmap_capability_set(wStream* s, rdpSettings* settings) * will not send it. YCoCg is still needed for EGFX, but it at least * appears consistent in its use. */ - /* drawingFlags |= DRAW_ALLOW_DYNAMIC_COLOR_FIDELITY; */ - /* YCoCg with chroma subsampling is not implemented in bitmap_decode.c. */ - /* drawingFlags |= DRAW_ALLOW_COLOR_SUBSAMPLING; */ if (settings->RdpVersion > 5) preferredBitsPerPixel = settings->ColorDepth; @@ -414,7 +419,7 @@ BOOL rdp_print_bitmap_capability_set(wStream* s, UINT16 length) UINT16 multipleRectangleSupport; UINT16 pad2OctetsB; - fprintf(stderr, "BitmapCapabilitySet (length %d):\n", length); + DEBUG_WARN( "BitmapCapabilitySet (length %d):\n", length); if (length < 28) return FALSE; @@ -433,19 +438,19 @@ BOOL rdp_print_bitmap_capability_set(wStream* s, UINT16 length) Stream_Read_UINT16(s, multipleRectangleSupport); /* multipleRectangleSupport (2 bytes) */ Stream_Read_UINT16(s, pad2OctetsB); /* pad2OctetsB (2 bytes) */ - fprintf(stderr, "\tpreferredBitsPerPixel: 0x%04X\n", preferredBitsPerPixel); - fprintf(stderr, "\treceive1BitPerPixel: 0x%04X\n", receive1BitPerPixel); - fprintf(stderr, "\treceive4BitsPerPixel: 0x%04X\n", receive4BitsPerPixel); - fprintf(stderr, "\treceive8BitsPerPixel: 0x%04X\n", receive8BitsPerPixel); - fprintf(stderr, "\tdesktopWidth: 0x%04X\n", desktopWidth); - fprintf(stderr, "\tdesktopHeight: 0x%04X\n", desktopHeight); - fprintf(stderr, "\tpad2Octets: 0x%04X\n", pad2Octets); - fprintf(stderr, "\tdesktopResizeFlag: 0x%04X\n", desktopResizeFlag); - fprintf(stderr, "\tbitmapCompressionFlag: 0x%04X\n", bitmapCompressionFlag); - fprintf(stderr, "\thighColorFlags: 0x%02X\n", highColorFlags); - fprintf(stderr, "\tdrawingFlags: 0x%02X\n", drawingFlags); - fprintf(stderr, "\tmultipleRectangleSupport: 0x%04X\n", multipleRectangleSupport); - fprintf(stderr, "\tpad2OctetsB: 0x%04X\n", pad2OctetsB); + DEBUG_WARN( "\tpreferredBitsPerPixel: 0x%04X\n", preferredBitsPerPixel); + DEBUG_WARN( "\treceive1BitPerPixel: 0x%04X\n", receive1BitPerPixel); + DEBUG_WARN( "\treceive4BitsPerPixel: 0x%04X\n", receive4BitsPerPixel); + DEBUG_WARN( "\treceive8BitsPerPixel: 0x%04X\n", receive8BitsPerPixel); + DEBUG_WARN( "\tdesktopWidth: 0x%04X\n", desktopWidth); + DEBUG_WARN( "\tdesktopHeight: 0x%04X\n", desktopHeight); + DEBUG_WARN( "\tpad2Octets: 0x%04X\n", pad2Octets); + DEBUG_WARN( "\tdesktopResizeFlag: 0x%04X\n", desktopResizeFlag); + DEBUG_WARN( "\tbitmapCompressionFlag: 0x%04X\n", bitmapCompressionFlag); + DEBUG_WARN( "\thighColorFlags: 0x%02X\n", highColorFlags); + DEBUG_WARN( "\tdrawingFlags: 0x%02X\n", drawingFlags); + DEBUG_WARN( "\tmultipleRectangleSupport: 0x%04X\n", multipleRectangleSupport); + DEBUG_WARN( "\tpad2OctetsB: 0x%04X\n", pad2OctetsB); return TRUE; } @@ -591,7 +596,7 @@ BOOL rdp_print_order_capability_set(wStream* s, UINT16 length) UINT16 textANSICodePage; UINT16 pad2OctetsE; - fprintf(stderr, "OrderCapabilitySet (length %d):\n", length); + DEBUG_WARN( "OrderCapabilitySet (length %d):\n", length); if (length < 88) return FALSE; @@ -614,56 +619,56 @@ BOOL rdp_print_order_capability_set(wStream* s, UINT16 length) Stream_Read_UINT16(s, textANSICodePage); /* textANSICodePage (2 bytes) */ Stream_Read_UINT16(s, pad2OctetsE); /* pad2OctetsE (2 bytes) */ - fprintf(stderr, "\tpad4OctetsA: 0x%08X\n", pad4OctetsA); - fprintf(stderr, "\tdesktopSaveXGranularity: 0x%04X\n", desktopSaveXGranularity); - fprintf(stderr, "\tdesktopSaveYGranularity: 0x%04X\n", desktopSaveYGranularity); - fprintf(stderr, "\tpad2OctetsA: 0x%04X\n", pad2OctetsA); - fprintf(stderr, "\tmaximumOrderLevel: 0x%04X\n", maximumOrderLevel); - fprintf(stderr, "\tnumberFonts: 0x%04X\n", numberFonts); - fprintf(stderr, "\torderFlags: 0x%04X\n", orderFlags); + DEBUG_WARN( "\tpad4OctetsA: 0x%08X\n", pad4OctetsA); + DEBUG_WARN( "\tdesktopSaveXGranularity: 0x%04X\n", desktopSaveXGranularity); + DEBUG_WARN( "\tdesktopSaveYGranularity: 0x%04X\n", desktopSaveYGranularity); + DEBUG_WARN( "\tpad2OctetsA: 0x%04X\n", pad2OctetsA); + DEBUG_WARN( "\tmaximumOrderLevel: 0x%04X\n", maximumOrderLevel); + DEBUG_WARN( "\tnumberFonts: 0x%04X\n", numberFonts); + DEBUG_WARN( "\torderFlags: 0x%04X\n", orderFlags); - fprintf(stderr, "\torderSupport:\n"); - fprintf(stderr, "\t\tDSTBLT: %d\n", orderSupport[NEG_DSTBLT_INDEX]); - fprintf(stderr, "\t\tPATBLT: %d\n", orderSupport[NEG_PATBLT_INDEX]); - fprintf(stderr, "\t\tSCRBLT: %d\n", orderSupport[NEG_SCRBLT_INDEX]); - fprintf(stderr, "\t\tMEMBLT: %d\n", orderSupport[NEG_MEMBLT_INDEX]); - fprintf(stderr, "\t\tMEM3BLT: %d\n", orderSupport[NEG_MEM3BLT_INDEX]); - fprintf(stderr, "\t\tATEXTOUT: %d\n", orderSupport[NEG_ATEXTOUT_INDEX]); - fprintf(stderr, "\t\tAEXTTEXTOUT: %d\n", orderSupport[NEG_AEXTTEXTOUT_INDEX]); - fprintf(stderr, "\t\tDRAWNINEGRID: %d\n", orderSupport[NEG_DRAWNINEGRID_INDEX]); - fprintf(stderr, "\t\tLINETO: %d\n", orderSupport[NEG_LINETO_INDEX]); - fprintf(stderr, "\t\tMULTI_DRAWNINEGRID: %d\n", orderSupport[NEG_MULTI_DRAWNINEGRID_INDEX]); - fprintf(stderr, "\t\tOPAQUE_RECT: %d\n", orderSupport[NEG_OPAQUE_RECT_INDEX]); - fprintf(stderr, "\t\tSAVEBITMAP: %d\n", orderSupport[NEG_SAVEBITMAP_INDEX]); - fprintf(stderr, "\t\tWTEXTOUT: %d\n", orderSupport[NEG_WTEXTOUT_INDEX]); - fprintf(stderr, "\t\tMEMBLT_V2: %d\n", orderSupport[NEG_MEMBLT_V2_INDEX]); - fprintf(stderr, "\t\tMEM3BLT_V2: %d\n", orderSupport[NEG_MEM3BLT_V2_INDEX]); - fprintf(stderr, "\t\tMULTIDSTBLT: %d\n", orderSupport[NEG_MULTIDSTBLT_INDEX]); - fprintf(stderr, "\t\tMULTIPATBLT: %d\n", orderSupport[NEG_MULTIPATBLT_INDEX]); - fprintf(stderr, "\t\tMULTISCRBLT: %d\n", orderSupport[NEG_MULTISCRBLT_INDEX]); - fprintf(stderr, "\t\tMULTIOPAQUERECT: %d\n", orderSupport[NEG_MULTIOPAQUERECT_INDEX]); - fprintf(stderr, "\t\tFAST_INDEX: %d\n", orderSupport[NEG_FAST_INDEX_INDEX]); - fprintf(stderr, "\t\tPOLYGON_SC: %d\n", orderSupport[NEG_POLYGON_SC_INDEX]); - fprintf(stderr, "\t\tPOLYGON_CB: %d\n", orderSupport[NEG_POLYGON_CB_INDEX]); - fprintf(stderr, "\t\tPOLYLINE: %d\n", orderSupport[NEG_POLYLINE_INDEX]); - fprintf(stderr, "\t\tUNUSED23: %d\n", orderSupport[NEG_UNUSED23_INDEX]); - fprintf(stderr, "\t\tFAST_GLYPH: %d\n", orderSupport[NEG_FAST_GLYPH_INDEX]); - fprintf(stderr, "\t\tELLIPSE_SC: %d\n", orderSupport[NEG_ELLIPSE_SC_INDEX]); - fprintf(stderr, "\t\tELLIPSE_CB: %d\n", orderSupport[NEG_ELLIPSE_CB_INDEX]); - fprintf(stderr, "\t\tGLYPH_INDEX: %d\n", orderSupport[NEG_GLYPH_INDEX_INDEX]); - fprintf(stderr, "\t\tGLYPH_WEXTTEXTOUT: %d\n", orderSupport[NEG_GLYPH_WEXTTEXTOUT_INDEX]); - fprintf(stderr, "\t\tGLYPH_WLONGTEXTOUT: %d\n", orderSupport[NEG_GLYPH_WLONGTEXTOUT_INDEX]); - fprintf(stderr, "\t\tGLYPH_WLONGEXTTEXTOUT: %d\n", orderSupport[NEG_GLYPH_WLONGEXTTEXTOUT_INDEX]); - fprintf(stderr, "\t\tUNUSED31: %d\n", orderSupport[NEG_UNUSED31_INDEX]); + DEBUG_WARN( "\torderSupport:\n"); + DEBUG_WARN( "\t\tDSTBLT: %d\n", orderSupport[NEG_DSTBLT_INDEX]); + DEBUG_WARN( "\t\tPATBLT: %d\n", orderSupport[NEG_PATBLT_INDEX]); + DEBUG_WARN( "\t\tSCRBLT: %d\n", orderSupport[NEG_SCRBLT_INDEX]); + DEBUG_WARN( "\t\tMEMBLT: %d\n", orderSupport[NEG_MEMBLT_INDEX]); + DEBUG_WARN( "\t\tMEM3BLT: %d\n", orderSupport[NEG_MEM3BLT_INDEX]); + DEBUG_WARN( "\t\tATEXTOUT: %d\n", orderSupport[NEG_ATEXTOUT_INDEX]); + DEBUG_WARN( "\t\tAEXTTEXTOUT: %d\n", orderSupport[NEG_AEXTTEXTOUT_INDEX]); + DEBUG_WARN( "\t\tDRAWNINEGRID: %d\n", orderSupport[NEG_DRAWNINEGRID_INDEX]); + DEBUG_WARN( "\t\tLINETO: %d\n", orderSupport[NEG_LINETO_INDEX]); + DEBUG_WARN( "\t\tMULTI_DRAWNINEGRID: %d\n", orderSupport[NEG_MULTI_DRAWNINEGRID_INDEX]); + DEBUG_WARN( "\t\tOPAQUE_RECT: %d\n", orderSupport[NEG_OPAQUE_RECT_INDEX]); + DEBUG_WARN( "\t\tSAVEBITMAP: %d\n", orderSupport[NEG_SAVEBITMAP_INDEX]); + DEBUG_WARN( "\t\tWTEXTOUT: %d\n", orderSupport[NEG_WTEXTOUT_INDEX]); + DEBUG_WARN( "\t\tMEMBLT_V2: %d\n", orderSupport[NEG_MEMBLT_V2_INDEX]); + DEBUG_WARN( "\t\tMEM3BLT_V2: %d\n", orderSupport[NEG_MEM3BLT_V2_INDEX]); + DEBUG_WARN( "\t\tMULTIDSTBLT: %d\n", orderSupport[NEG_MULTIDSTBLT_INDEX]); + DEBUG_WARN( "\t\tMULTIPATBLT: %d\n", orderSupport[NEG_MULTIPATBLT_INDEX]); + DEBUG_WARN( "\t\tMULTISCRBLT: %d\n", orderSupport[NEG_MULTISCRBLT_INDEX]); + DEBUG_WARN( "\t\tMULTIOPAQUERECT: %d\n", orderSupport[NEG_MULTIOPAQUERECT_INDEX]); + DEBUG_WARN( "\t\tFAST_INDEX: %d\n", orderSupport[NEG_FAST_INDEX_INDEX]); + DEBUG_WARN( "\t\tPOLYGON_SC: %d\n", orderSupport[NEG_POLYGON_SC_INDEX]); + DEBUG_WARN( "\t\tPOLYGON_CB: %d\n", orderSupport[NEG_POLYGON_CB_INDEX]); + DEBUG_WARN( "\t\tPOLYLINE: %d\n", orderSupport[NEG_POLYLINE_INDEX]); + DEBUG_WARN( "\t\tUNUSED23: %d\n", orderSupport[NEG_UNUSED23_INDEX]); + DEBUG_WARN( "\t\tFAST_GLYPH: %d\n", orderSupport[NEG_FAST_GLYPH_INDEX]); + DEBUG_WARN( "\t\tELLIPSE_SC: %d\n", orderSupport[NEG_ELLIPSE_SC_INDEX]); + DEBUG_WARN( "\t\tELLIPSE_CB: %d\n", orderSupport[NEG_ELLIPSE_CB_INDEX]); + DEBUG_WARN( "\t\tGLYPH_INDEX: %d\n", orderSupport[NEG_GLYPH_INDEX_INDEX]); + DEBUG_WARN( "\t\tGLYPH_WEXTTEXTOUT: %d\n", orderSupport[NEG_GLYPH_WEXTTEXTOUT_INDEX]); + DEBUG_WARN( "\t\tGLYPH_WLONGTEXTOUT: %d\n", orderSupport[NEG_GLYPH_WLONGTEXTOUT_INDEX]); + DEBUG_WARN( "\t\tGLYPH_WLONGEXTTEXTOUT: %d\n", orderSupport[NEG_GLYPH_WLONGEXTTEXTOUT_INDEX]); + DEBUG_WARN( "\t\tUNUSED31: %d\n", orderSupport[NEG_UNUSED31_INDEX]); - fprintf(stderr, "\ttextFlags: 0x%04X\n", textFlags); - fprintf(stderr, "\torderSupportExFlags: 0x%04X\n", orderSupportExFlags); - fprintf(stderr, "\tpad4OctetsB: 0x%08X\n", pad4OctetsB); - fprintf(stderr, "\tdesktopSaveSize: 0x%08X\n", desktopSaveSize); - fprintf(stderr, "\tpad2OctetsC: 0x%04X\n", pad2OctetsC); - fprintf(stderr, "\tpad2OctetsD: 0x%04X\n", pad2OctetsD); - fprintf(stderr, "\ttextANSICodePage: 0x%04X\n", textANSICodePage); - fprintf(stderr, "\tpad2OctetsE: 0x%04X\n", pad2OctetsE); + DEBUG_WARN( "\ttextFlags: 0x%04X\n", textFlags); + DEBUG_WARN( "\torderSupportExFlags: 0x%04X\n", orderSupportExFlags); + DEBUG_WARN( "\tpad4OctetsB: 0x%08X\n", pad4OctetsB); + DEBUG_WARN( "\tdesktopSaveSize: 0x%08X\n", desktopSaveSize); + DEBUG_WARN( "\tpad2OctetsC: 0x%04X\n", pad2OctetsC); + DEBUG_WARN( "\tpad2OctetsD: 0x%04X\n", pad2OctetsD); + DEBUG_WARN( "\ttextANSICodePage: 0x%04X\n", textANSICodePage); + DEBUG_WARN( "\tpad2OctetsE: 0x%04X\n", pad2OctetsE); return TRUE; } @@ -749,7 +754,7 @@ BOOL rdp_print_bitmap_cache_capability_set(wStream* s, UINT16 length) UINT16 Cache2Entries; UINT16 Cache2MaximumCellSize; - fprintf(stderr, "BitmapCacheCapabilitySet (length %d):\n", length); + DEBUG_WARN( "BitmapCacheCapabilitySet (length %d):\n", length); if (length < 40) return FALSE; @@ -767,18 +772,18 @@ BOOL rdp_print_bitmap_cache_capability_set(wStream* s, UINT16 length) Stream_Read_UINT16(s, Cache2Entries); /* Cache2Entries (2 bytes) */ Stream_Read_UINT16(s, Cache2MaximumCellSize); /* Cache2MaximumCellSize (2 bytes) */ - fprintf(stderr, "\tpad1: 0x%08X\n", pad1); - fprintf(stderr, "\tpad2: 0x%08X\n", pad2); - fprintf(stderr, "\tpad3: 0x%08X\n", pad3); - fprintf(stderr, "\tpad4: 0x%08X\n", pad4); - fprintf(stderr, "\tpad5: 0x%08X\n", pad5); - fprintf(stderr, "\tpad6: 0x%08X\n", pad6); - fprintf(stderr, "\tCache0Entries: 0x%04X\n", Cache0Entries); - fprintf(stderr, "\tCache0MaximumCellSize: 0x%04X\n", Cache0MaximumCellSize); - fprintf(stderr, "\tCache1Entries: 0x%04X\n", Cache1Entries); - fprintf(stderr, "\tCache1MaximumCellSize: 0x%04X\n", Cache1MaximumCellSize); - fprintf(stderr, "\tCache2Entries: 0x%04X\n", Cache2Entries); - fprintf(stderr, "\tCache2MaximumCellSize: 0x%04X\n", Cache2MaximumCellSize); + DEBUG_WARN( "\tpad1: 0x%08X\n", pad1); + DEBUG_WARN( "\tpad2: 0x%08X\n", pad2); + DEBUG_WARN( "\tpad3: 0x%08X\n", pad3); + DEBUG_WARN( "\tpad4: 0x%08X\n", pad4); + DEBUG_WARN( "\tpad5: 0x%08X\n", pad5); + DEBUG_WARN( "\tpad6: 0x%08X\n", pad6); + DEBUG_WARN( "\tCache0Entries: 0x%04X\n", Cache0Entries); + DEBUG_WARN( "\tCache0MaximumCellSize: 0x%04X\n", Cache0MaximumCellSize); + DEBUG_WARN( "\tCache1Entries: 0x%04X\n", Cache1Entries); + DEBUG_WARN( "\tCache1MaximumCellSize: 0x%04X\n", Cache1MaximumCellSize); + DEBUG_WARN( "\tCache2Entries: 0x%04X\n", Cache2Entries); + DEBUG_WARN( "\tCache2MaximumCellSize: 0x%04X\n", Cache2MaximumCellSize); return TRUE; } @@ -834,7 +839,7 @@ BOOL rdp_print_control_capability_set(wStream* s, UINT16 length) UINT16 controlInterest; UINT16 detachInterest; - fprintf(stderr, "ControlCapabilitySet (length %d):\n", length); + DEBUG_WARN( "ControlCapabilitySet (length %d):\n", length); if (length < 12) return FALSE; @@ -844,10 +849,10 @@ BOOL rdp_print_control_capability_set(wStream* s, UINT16 length) Stream_Read_UINT16(s, controlInterest); /* controlInterest (2 bytes) */ Stream_Read_UINT16(s, detachInterest); /* detachInterest (2 bytes) */ - fprintf(stderr, "\tcontrolFlags: 0x%04X\n", controlFlags); - fprintf(stderr, "\tremoteDetachFlag: 0x%04X\n", remoteDetachFlag); - fprintf(stderr, "\tcontrolInterest: 0x%04X\n", controlInterest); - fprintf(stderr, "\tdetachInterest: 0x%04X\n", detachInterest); + DEBUG_WARN( "\tcontrolFlags: 0x%04X\n", controlFlags); + DEBUG_WARN( "\tremoteDetachFlag: 0x%04X\n", remoteDetachFlag); + DEBUG_WARN( "\tcontrolInterest: 0x%04X\n", controlInterest); + DEBUG_WARN( "\tdetachInterest: 0x%04X\n", detachInterest); return TRUE; } @@ -903,7 +908,7 @@ BOOL rdp_print_window_activation_capability_set(wStream* s, UINT16 length) UINT16 helpExtendedKeyFlag; UINT16 windowManagerKeyFlag; - fprintf(stderr, "WindowActivationCapabilitySet (length %d):\n", length); + DEBUG_WARN( "WindowActivationCapabilitySet (length %d):\n", length); if (length < 12) return FALSE; @@ -913,10 +918,10 @@ BOOL rdp_print_window_activation_capability_set(wStream* s, UINT16 length) Stream_Read_UINT16(s, helpExtendedKeyFlag); /* helpExtendedKeyFlag (2 bytes) */ Stream_Read_UINT16(s, windowManagerKeyFlag); /* windowManagerKeyFlag (2 bytes) */ - fprintf(stderr, "\thelpKeyFlag: 0x%04X\n", helpKeyFlag); - fprintf(stderr, "\thelpKeyIndexFlag: 0x%04X\n", helpKeyIndexFlag); - fprintf(stderr, "\thelpExtendedKeyFlag: 0x%04X\n", helpExtendedKeyFlag); - fprintf(stderr, "\twindowManagerKeyFlag: 0x%04X\n", windowManagerKeyFlag); + DEBUG_WARN( "\thelpKeyFlag: 0x%04X\n", helpKeyFlag); + DEBUG_WARN( "\thelpKeyIndexFlag: 0x%04X\n", helpKeyIndexFlag); + DEBUG_WARN( "\thelpExtendedKeyFlag: 0x%04X\n", helpExtendedKeyFlag); + DEBUG_WARN( "\twindowManagerKeyFlag: 0x%04X\n", windowManagerKeyFlag); return TRUE; } @@ -990,15 +995,15 @@ BOOL rdp_print_pointer_capability_set(wStream* s, UINT16 length) if (length < 10) return FALSE; - fprintf(stderr, "PointerCapabilitySet (length %d):\n", length); + DEBUG_WARN( "PointerCapabilitySet (length %d):\n", length); Stream_Read_UINT16(s, colorPointerFlag); /* colorPointerFlag (2 bytes) */ Stream_Read_UINT16(s, colorPointerCacheSize); /* colorPointerCacheSize (2 bytes) */ Stream_Read_UINT16(s, pointerCacheSize); /* pointerCacheSize (2 bytes) */ - fprintf(stderr, "\tcolorPointerFlag: 0x%04X\n", colorPointerFlag); - fprintf(stderr, "\tcolorPointerCacheSize: 0x%04X\n", colorPointerCacheSize); - fprintf(stderr, "\tpointerCacheSize: 0x%04X\n", pointerCacheSize); + DEBUG_WARN( "\tcolorPointerFlag: 0x%04X\n", colorPointerFlag); + DEBUG_WARN( "\tcolorPointerCacheSize: 0x%04X\n", colorPointerCacheSize); + DEBUG_WARN( "\tpointerCacheSize: 0x%04X\n", pointerCacheSize); return TRUE; } @@ -1051,7 +1056,7 @@ BOOL rdp_print_share_capability_set(wStream* s, UINT16 length) UINT16 nodeId; UINT16 pad2Octets; - fprintf(stderr, "ShareCapabilitySet (length %d):\n", length); + DEBUG_WARN( "ShareCapabilitySet (length %d):\n", length); if (length < 8) return FALSE; @@ -1059,8 +1064,8 @@ BOOL rdp_print_share_capability_set(wStream* s, UINT16 length) Stream_Read_UINT16(s, nodeId); /* nodeId (2 bytes) */ Stream_Read_UINT16(s, pad2Octets); /* pad2Octets (2 bytes) */ - fprintf(stderr, "\tnodeId: 0x%04X\n", nodeId); - fprintf(stderr, "\tpad2Octets: 0x%04X\n", pad2Octets); + DEBUG_WARN( "\tnodeId: 0x%04X\n", nodeId); + DEBUG_WARN( "\tpad2Octets: 0x%04X\n", pad2Octets); return TRUE; } @@ -1110,7 +1115,7 @@ BOOL rdp_print_color_cache_capability_set(wStream* s, UINT16 length) UINT16 colorTableCacheSize; UINT16 pad2Octets; - fprintf(stderr, "ColorCacheCapabilitySet (length %d):\n", length); + DEBUG_WARN( "ColorCacheCapabilitySet (length %d):\n", length); if (length < 8) return FALSE; @@ -1118,8 +1123,8 @@ BOOL rdp_print_color_cache_capability_set(wStream* s, UINT16 length) Stream_Read_UINT16(s, colorTableCacheSize); /* colorTableCacheSize (2 bytes) */ Stream_Read_UINT16(s, pad2Octets); /* pad2Octets (2 bytes) */ - fprintf(stderr, "\tcolorTableCacheSize: 0x%04X\n", colorTableCacheSize); - fprintf(stderr, "\tpad2Octets: 0x%04X\n", pad2Octets); + DEBUG_WARN( "\tcolorTableCacheSize: 0x%04X\n", colorTableCacheSize); + DEBUG_WARN( "\tpad2Octets: 0x%04X\n", pad2Octets); return TRUE; } @@ -1176,7 +1181,7 @@ BOOL rdp_print_sound_capability_set(wStream* s, UINT16 length) UINT16 soundFlags; UINT16 pad2OctetsA; - fprintf(stderr, "SoundCapabilitySet (length %d):\n", length); + DEBUG_WARN( "SoundCapabilitySet (length %d):\n", length); if (length < 8) return FALSE; @@ -1184,8 +1189,8 @@ BOOL rdp_print_sound_capability_set(wStream* s, UINT16 length) Stream_Read_UINT16(s, soundFlags); /* soundFlags (2 bytes) */ Stream_Read_UINT16(s, pad2OctetsA); /* pad2OctetsA (2 bytes) */ - fprintf(stderr, "\tsoundFlags: 0x%04X\n", soundFlags); - fprintf(stderr, "\tpad2OctetsA: 0x%04X\n", pad2OctetsA); + DEBUG_WARN( "\tsoundFlags: 0x%04X\n", soundFlags); + DEBUG_WARN( "\tpad2OctetsA: 0x%04X\n", pad2OctetsA); return TRUE; } @@ -1288,7 +1293,7 @@ BOOL rdp_print_input_capability_set(wStream* s, UINT16 length) UINT32 keyboardSubType; UINT32 keyboardFunctionKey; - fprintf(stderr, "InputCapabilitySet (length %d)\n", length); + DEBUG_WARN( "InputCapabilitySet (length %d)\n", length); if (length < 88) return FALSE; @@ -1301,12 +1306,12 @@ BOOL rdp_print_input_capability_set(wStream* s, UINT16 length) Stream_Read_UINT32(s, keyboardFunctionKey); /* keyboardFunctionKeys (4 bytes) */ Stream_Seek(s, 64); /* imeFileName (64 bytes) */ - fprintf(stderr, "\tinputFlags: 0x%04X\n", inputFlags); - fprintf(stderr, "\tpad2OctetsA: 0x%04X\n", pad2OctetsA); - fprintf(stderr, "\tkeyboardLayout: 0x%08X\n", keyboardLayout); - fprintf(stderr, "\tkeyboardType: 0x%08X\n", keyboardType); - fprintf(stderr, "\tkeyboardSubType: 0x%08X\n", keyboardSubType); - fprintf(stderr, "\tkeyboardFunctionKey: 0x%08X\n", keyboardFunctionKey); + DEBUG_WARN( "\tinputFlags: 0x%04X\n", inputFlags); + DEBUG_WARN( "\tpad2OctetsA: 0x%04X\n", pad2OctetsA); + DEBUG_WARN( "\tkeyboardLayout: 0x%08X\n", keyboardLayout); + DEBUG_WARN( "\tkeyboardType: 0x%08X\n", keyboardType); + DEBUG_WARN( "\tkeyboardSubType: 0x%08X\n", keyboardSubType); + DEBUG_WARN( "\tkeyboardFunctionKey: 0x%08X\n", keyboardFunctionKey); return TRUE; } @@ -1356,7 +1361,7 @@ BOOL rdp_print_font_capability_set(wStream* s, UINT16 length) UINT16 fontSupportFlags = 0; UINT16 pad2Octets = 0; - fprintf(stderr, "FontCapabilitySet (length %d):\n", length); + DEBUG_WARN( "FontCapabilitySet (length %d):\n", length); if (length > 4) Stream_Read_UINT16(s, fontSupportFlags); /* fontSupportFlags (2 bytes) */ @@ -1364,8 +1369,8 @@ BOOL rdp_print_font_capability_set(wStream* s, UINT16 length) if (length > 6) Stream_Read_UINT16(s, pad2Octets); /* pad2Octets (2 bytes) */ - fprintf(stderr, "\tfontSupportFlags: 0x%04X\n", fontSupportFlags); - fprintf(stderr, "\tpad2Octets: 0x%04X\n", pad2Octets); + DEBUG_WARN( "\tfontSupportFlags: 0x%04X\n", fontSupportFlags); + DEBUG_WARN( "\tpad2Octets: 0x%04X\n", pad2Octets); return TRUE; } @@ -1412,14 +1417,14 @@ BOOL rdp_print_brush_capability_set(wStream* s, UINT16 length) { UINT32 brushSupportLevel; - fprintf(stderr, "BrushCapabilitySet (length %d):\n", length); + DEBUG_WARN( "BrushCapabilitySet (length %d):\n", length); if (length < 8) return FALSE; Stream_Read_UINT32(s, brushSupportLevel); /* brushSupportLevel (4 bytes) */ - fprintf(stderr, "\tbrushSupportLevel: 0x%08X\n", brushSupportLevel); + DEBUG_WARN( "\tbrushSupportLevel: 0x%08X\n", brushSupportLevel); return TRUE; } @@ -1521,7 +1526,7 @@ BOOL rdp_print_glyph_cache_capability_set(wStream* s, UINT16 length) UINT16 glyphSupportLevel; UINT16 pad2Octets; - fprintf(stderr, "GlyphCacheCapabilitySet (length %d):\n", length); + DEBUG_WARN( "GlyphCacheCapabilitySet (length %d):\n", length); if (length < 52) return FALSE; @@ -1542,19 +1547,19 @@ BOOL rdp_print_glyph_cache_capability_set(wStream* s, UINT16 length) Stream_Read_UINT16(s, glyphSupportLevel); /* glyphSupportLevel (2 bytes) */ Stream_Read_UINT16(s, pad2Octets); /* pad2Octets (2 bytes) */ - fprintf(stderr, "\tglyphCache0: Entries: %d MaximumCellSize: %d\n", glyphCache[0].cacheEntries, glyphCache[0].cacheMaximumCellSize); - fprintf(stderr, "\tglyphCache1: Entries: %d MaximumCellSize: %d\n", glyphCache[1].cacheEntries, glyphCache[1].cacheMaximumCellSize); - fprintf(stderr, "\tglyphCache2: Entries: %d MaximumCellSize: %d\n", glyphCache[2].cacheEntries, glyphCache[2].cacheMaximumCellSize); - fprintf(stderr, "\tglyphCache3: Entries: %d MaximumCellSize: %d\n", glyphCache[3].cacheEntries, glyphCache[3].cacheMaximumCellSize); - fprintf(stderr, "\tglyphCache4: Entries: %d MaximumCellSize: %d\n", glyphCache[4].cacheEntries, glyphCache[4].cacheMaximumCellSize); - fprintf(stderr, "\tglyphCache5: Entries: %d MaximumCellSize: %d\n", glyphCache[5].cacheEntries, glyphCache[5].cacheMaximumCellSize); - fprintf(stderr, "\tglyphCache6: Entries: %d MaximumCellSize: %d\n", glyphCache[6].cacheEntries, glyphCache[6].cacheMaximumCellSize); - fprintf(stderr, "\tglyphCache7: Entries: %d MaximumCellSize: %d\n", glyphCache[7].cacheEntries, glyphCache[7].cacheMaximumCellSize); - fprintf(stderr, "\tglyphCache8: Entries: %d MaximumCellSize: %d\n", glyphCache[8].cacheEntries, glyphCache[8].cacheMaximumCellSize); - fprintf(stderr, "\tglyphCache9: Entries: %d MaximumCellSize: %d\n", glyphCache[9].cacheEntries, glyphCache[9].cacheMaximumCellSize); - fprintf(stderr, "\tfragCache: Entries: %d MaximumCellSize: %d\n", fragCache.cacheEntries, fragCache.cacheMaximumCellSize); - fprintf(stderr, "\tglyphSupportLevel: 0x%04X\n", glyphSupportLevel); - fprintf(stderr, "\tpad2Octets: 0x%04X\n", pad2Octets); + DEBUG_WARN( "\tglyphCache0: Entries: %d MaximumCellSize: %d\n", glyphCache[0].cacheEntries, glyphCache[0].cacheMaximumCellSize); + DEBUG_WARN( "\tglyphCache1: Entries: %d MaximumCellSize: %d\n", glyphCache[1].cacheEntries, glyphCache[1].cacheMaximumCellSize); + DEBUG_WARN( "\tglyphCache2: Entries: %d MaximumCellSize: %d\n", glyphCache[2].cacheEntries, glyphCache[2].cacheMaximumCellSize); + DEBUG_WARN( "\tglyphCache3: Entries: %d MaximumCellSize: %d\n", glyphCache[3].cacheEntries, glyphCache[3].cacheMaximumCellSize); + DEBUG_WARN( "\tglyphCache4: Entries: %d MaximumCellSize: %d\n", glyphCache[4].cacheEntries, glyphCache[4].cacheMaximumCellSize); + DEBUG_WARN( "\tglyphCache5: Entries: %d MaximumCellSize: %d\n", glyphCache[5].cacheEntries, glyphCache[5].cacheMaximumCellSize); + DEBUG_WARN( "\tglyphCache6: Entries: %d MaximumCellSize: %d\n", glyphCache[6].cacheEntries, glyphCache[6].cacheMaximumCellSize); + DEBUG_WARN( "\tglyphCache7: Entries: %d MaximumCellSize: %d\n", glyphCache[7].cacheEntries, glyphCache[7].cacheMaximumCellSize); + DEBUG_WARN( "\tglyphCache8: Entries: %d MaximumCellSize: %d\n", glyphCache[8].cacheEntries, glyphCache[8].cacheMaximumCellSize); + DEBUG_WARN( "\tglyphCache9: Entries: %d MaximumCellSize: %d\n", glyphCache[9].cacheEntries, glyphCache[9].cacheMaximumCellSize); + DEBUG_WARN( "\tfragCache: Entries: %d MaximumCellSize: %d\n", fragCache.cacheEntries, fragCache.cacheMaximumCellSize); + DEBUG_WARN( "\tglyphSupportLevel: 0x%04X\n", glyphSupportLevel); + DEBUG_WARN( "\tpad2Octets: 0x%04X\n", pad2Octets); return TRUE; } @@ -1616,7 +1621,7 @@ BOOL rdp_print_offscreen_bitmap_cache_capability_set(wStream* s, UINT16 length) UINT16 offscreenCacheSize; UINT16 offscreenCacheEntries; - fprintf(stderr, "OffscreenBitmapCacheCapabilitySet (length %d):\n", length); + DEBUG_WARN( "OffscreenBitmapCacheCapabilitySet (length %d):\n", length); if (length < 12) return FALSE; @@ -1625,9 +1630,9 @@ BOOL rdp_print_offscreen_bitmap_cache_capability_set(wStream* s, UINT16 length) Stream_Read_UINT16(s, offscreenCacheSize); /* offscreenCacheSize (2 bytes) */ Stream_Read_UINT16(s, offscreenCacheEntries); /* offscreenCacheEntries (2 bytes) */ - fprintf(stderr, "\toffscreenSupportLevel: 0x%08X\n", offscreenSupportLevel); - fprintf(stderr, "\toffscreenCacheSize: 0x%04X\n", offscreenCacheSize); - fprintf(stderr, "\toffscreenCacheEntries: 0x%04X\n", offscreenCacheEntries); + DEBUG_WARN( "\toffscreenSupportLevel: 0x%08X\n", offscreenSupportLevel); + DEBUG_WARN( "\toffscreenCacheSize: 0x%04X\n", offscreenCacheSize); + DEBUG_WARN( "\toffscreenCacheEntries: 0x%04X\n", offscreenCacheEntries); return TRUE; } @@ -1685,7 +1690,7 @@ BOOL rdp_print_bitmap_cache_host_support_capability_set(wStream* s, UINT16 lengt BYTE pad1; UINT16 pad2; - fprintf(stderr, "BitmapCacheHostSupportCapabilitySet (length %d):\n", length); + DEBUG_WARN( "BitmapCacheHostSupportCapabilitySet (length %d):\n", length); if (length < 8) return FALSE; @@ -1694,9 +1699,9 @@ BOOL rdp_print_bitmap_cache_host_support_capability_set(wStream* s, UINT16 lengt Stream_Read_UINT8(s, pad1); /* pad1 (1 byte) */ Stream_Read_UINT16(s, pad2); /* pad2 (2 bytes) */ - fprintf(stderr, "\tcacheVersion: 0x%02X\n", cacheVersion); - fprintf(stderr, "\tpad1: 0x%02X\n", pad1); - fprintf(stderr, "\tpad2: 0x%04X\n", pad2); + DEBUG_WARN( "\tcacheVersion: 0x%02X\n", cacheVersion); + DEBUG_WARN( "\tpad1: 0x%02X\n", pad1); + DEBUG_WARN( "\tpad2: 0x%04X\n", pad2); return TRUE; } @@ -1796,7 +1801,7 @@ BOOL rdp_print_bitmap_cache_v2_capability_set(wStream* s, UINT16 length) BYTE numCellCaches; BITMAP_CACHE_V2_CELL_INFO bitmapCacheV2CellInfo[5]; - fprintf(stderr, "BitmapCacheV2CapabilitySet (length %d):\n", length); + DEBUG_WARN( "BitmapCacheV2CapabilitySet (length %d):\n", length); if (length < 40) return FALSE; @@ -1811,14 +1816,14 @@ BOOL rdp_print_bitmap_cache_v2_capability_set(wStream* s, UINT16 length) rdp_read_bitmap_cache_cell_info(s, &bitmapCacheV2CellInfo[4]); /* bitmapCache4CellInfo (4 bytes) */ Stream_Seek(s, 12); /* pad3 (12 bytes) */ - fprintf(stderr, "\tcacheFlags: 0x%04X\n", cacheFlags); - fprintf(stderr, "\tpad2: 0x%02X\n", pad2); - fprintf(stderr, "\tnumCellCaches: 0x%02X\n", numCellCaches); - fprintf(stderr, "\tbitmapCache0CellInfo: numEntries: %d persistent: %d\n", bitmapCacheV2CellInfo[0].numEntries, bitmapCacheV2CellInfo[0].persistent); - fprintf(stderr, "\tbitmapCache1CellInfo: numEntries: %d persistent: %d\n", bitmapCacheV2CellInfo[1].numEntries, bitmapCacheV2CellInfo[1].persistent); - fprintf(stderr, "\tbitmapCache2CellInfo: numEntries: %d persistent: %d\n", bitmapCacheV2CellInfo[2].numEntries, bitmapCacheV2CellInfo[2].persistent); - fprintf(stderr, "\tbitmapCache3CellInfo: numEntries: %d persistent: %d\n", bitmapCacheV2CellInfo[3].numEntries, bitmapCacheV2CellInfo[3].persistent); - fprintf(stderr, "\tbitmapCache4CellInfo: numEntries: %d persistent: %d\n", bitmapCacheV2CellInfo[4].numEntries, bitmapCacheV2CellInfo[4].persistent); + DEBUG_WARN( "\tcacheFlags: 0x%04X\n", cacheFlags); + DEBUG_WARN( "\tpad2: 0x%02X\n", pad2); + DEBUG_WARN( "\tnumCellCaches: 0x%02X\n", numCellCaches); + DEBUG_WARN( "\tbitmapCache0CellInfo: numEntries: %d persistent: %d\n", bitmapCacheV2CellInfo[0].numEntries, bitmapCacheV2CellInfo[0].persistent); + DEBUG_WARN( "\tbitmapCache1CellInfo: numEntries: %d persistent: %d\n", bitmapCacheV2CellInfo[1].numEntries, bitmapCacheV2CellInfo[1].persistent); + DEBUG_WARN( "\tbitmapCache2CellInfo: numEntries: %d persistent: %d\n", bitmapCacheV2CellInfo[2].numEntries, bitmapCacheV2CellInfo[2].persistent); + DEBUG_WARN( "\tbitmapCache3CellInfo: numEntries: %d persistent: %d\n", bitmapCacheV2CellInfo[3].numEntries, bitmapCacheV2CellInfo[3].persistent); + DEBUG_WARN( "\tbitmapCache4CellInfo: numEntries: %d persistent: %d\n", bitmapCacheV2CellInfo[4].numEntries, bitmapCacheV2CellInfo[4].persistent); return TRUE; } @@ -1881,7 +1886,7 @@ BOOL rdp_print_virtual_channel_capability_set(wStream* s, UINT16 length) UINT32 flags; UINT32 VCChunkSize; - fprintf(stderr, "VirtualChannelCapabilitySet (length %d):\n", length); + DEBUG_WARN( "VirtualChannelCapabilitySet (length %d):\n", length); if (length < 8) return FALSE; @@ -1893,8 +1898,8 @@ BOOL rdp_print_virtual_channel_capability_set(wStream* s, UINT16 length) else VCChunkSize = 1600; - fprintf(stderr, "\tflags: 0x%08X\n", flags); - fprintf(stderr, "\tVCChunkSize: 0x%08X\n", VCChunkSize); + DEBUG_WARN( "\tflags: 0x%08X\n", flags); + DEBUG_WARN( "\tVCChunkSize: 0x%08X\n", VCChunkSize); return TRUE; } @@ -1980,7 +1985,7 @@ BOOL rdp_print_draw_nine_grid_cache_capability_set(wStream* s, UINT16 length) UINT16 DrawNineGridCacheSize; UINT16 DrawNineGridCacheEntries; - fprintf(stderr, "DrawNineGridCacheCapabilitySet (length %d):\n", length); + DEBUG_WARN( "DrawNineGridCacheCapabilitySet (length %d):\n", length); if (length < 12) return FALSE; @@ -2060,7 +2065,7 @@ BOOL rdp_print_draw_gdiplus_cache_capability_set(wStream* s, UINT16 length) UINT32 GdipVersion; UINT32 drawGdiplusCacheLevel; - fprintf(stderr, "DrawGdiPlusCacheCapabilitySet (length %d):\n", length); + DEBUG_WARN( "DrawGdiPlusCacheCapabilitySet (length %d):\n", length); if (length < 40) return FALSE; @@ -2133,14 +2138,14 @@ BOOL rdp_print_remote_programs_capability_set(wStream* s, UINT16 length) { UINT32 railSupportLevel; - fprintf(stderr, "RemoteProgramsCapabilitySet (length %d):\n", length); + DEBUG_WARN( "RemoteProgramsCapabilitySet (length %d):\n", length); if (length < 8) return FALSE; Stream_Read_UINT32(s, railSupportLevel); /* railSupportLevel (4 bytes) */ - fprintf(stderr, "\trailSupportLevel: 0x%08X\n", railSupportLevel); + DEBUG_WARN( "\trailSupportLevel: 0x%08X\n", railSupportLevel); return TRUE; } @@ -2196,7 +2201,7 @@ BOOL rdp_print_window_list_capability_set(wStream* s, UINT16 length) BYTE numIconCaches; UINT16 numIconCacheEntries; - fprintf(stderr, "WindowListCapabilitySet (length %d):\n", length); + DEBUG_WARN( "WindowListCapabilitySet (length %d):\n", length); if (length < 11) return FALSE; @@ -2205,9 +2210,9 @@ BOOL rdp_print_window_list_capability_set(wStream* s, UINT16 length) Stream_Read_UINT8(s, numIconCaches); /* numIconCaches (1 byte) */ Stream_Read_UINT16(s, numIconCacheEntries); /* numIconCacheEntries (2 bytes) */ - fprintf(stderr, "\twndSupportLevel: 0x%08X\n", wndSupportLevel); - fprintf(stderr, "\tnumIconCaches: 0x%02X\n", numIconCaches); - fprintf(stderr, "\tnumIconCacheEntries: 0x%04X\n", numIconCacheEntries); + DEBUG_WARN( "\twndSupportLevel: 0x%08X\n", wndSupportLevel); + DEBUG_WARN( "\tnumIconCaches: 0x%02X\n", numIconCaches); + DEBUG_WARN( "\tnumIconCacheEntries: 0x%04X\n", numIconCacheEntries); return TRUE; } @@ -2257,14 +2262,14 @@ BOOL rdp_print_desktop_composition_capability_set(wStream* s, UINT16 length) { UINT16 compDeskSupportLevel; - fprintf(stderr, "DesktopCompositionCapabilitySet (length %d):\n", length); + DEBUG_WARN( "DesktopCompositionCapabilitySet (length %d):\n", length); if (length < 6) return FALSE; Stream_Read_UINT16(s, compDeskSupportLevel); /* compDeskSupportLevel (2 bytes) */ - fprintf(stderr, "\tcompDeskSupportLevel: 0x%04X\n", compDeskSupportLevel); + DEBUG_WARN( "\tcompDeskSupportLevel: 0x%04X\n", compDeskSupportLevel); return TRUE; } @@ -2386,14 +2391,14 @@ BOOL rdp_print_multifragment_update_capability_set(wStream* s, UINT16 length) { UINT32 maxRequestSize; - fprintf(stderr, "MultifragmentUpdateCapabilitySet (length %d):\n", length); + DEBUG_WARN( "MultifragmentUpdateCapabilitySet (length %d):\n", length); if (length < 8) return FALSE; Stream_Read_UINT32(s, maxRequestSize); /* maxRequestSize (4 bytes) */ - fprintf(stderr, "\tmaxRequestSize: 0x%04X\n", maxRequestSize); + DEBUG_WARN( "\tmaxRequestSize: 0x%04X\n", maxRequestSize); return TRUE; } @@ -2447,14 +2452,14 @@ BOOL rdp_print_large_pointer_capability_set(wStream* s, UINT16 length) { UINT16 largePointerSupportFlags; - fprintf(stderr, "LargePointerCapabilitySet (length %d):\n", length); + DEBUG_WARN( "LargePointerCapabilitySet (length %d):\n", length); if (length < 6) return FALSE; Stream_Read_UINT16(s, largePointerSupportFlags); /* largePointerSupportFlags (2 bytes) */ - fprintf(stderr, "\tlargePointerSupportFlags: 0x%04X\n", largePointerSupportFlags); + DEBUG_WARN( "\tlargePointerSupportFlags: 0x%04X\n", largePointerSupportFlags); return TRUE; } @@ -2514,7 +2519,7 @@ BOOL rdp_print_surface_commands_capability_set(wStream* s, UINT16 length) UINT32 cmdFlags; UINT32 reserved; - fprintf(stderr, "SurfaceCommandsCapabilitySet (length %d):\n", length); + DEBUG_WARN( "SurfaceCommandsCapabilitySet (length %d):\n", length); if (length < 12) return FALSE; @@ -2522,8 +2527,8 @@ BOOL rdp_print_surface_commands_capability_set(wStream* s, UINT16 length) Stream_Read_UINT32(s, cmdFlags); /* cmdFlags (4 bytes) */ Stream_Read_UINT32(s, reserved); /* reserved (4 bytes) */ - fprintf(stderr, "\tcmdFlags: 0x%08X\n", cmdFlags); - fprintf(stderr, "\treserved: 0x%08X\n", reserved); + DEBUG_WARN( "\tcmdFlags: 0x%08X\n", cmdFlags); + DEBUG_WARN( "\treserved: 0x%08X\n", reserved); return TRUE; } @@ -2573,7 +2578,7 @@ void rdp_write_bitmap_codec_guid(wStream* s, GUID* guid) void rdp_print_bitmap_codec_guid(GUID* guid) { - fprintf(stderr, "%08X%04X%04X%02X%02X%02X%02X%02X%02X%02X%02X", + DEBUG_WARN( "%08X%04X%04X%02X%02X%02X%02X%02X%02X%02X%02X", guid->Data1, guid->Data2, guid->Data3, guid->Data4[0], guid->Data4[1], guid->Data4[2], guid->Data4[3], guid->Data4[4], guid->Data4[5], guid->Data4[6], guid->Data4[7]); @@ -2906,7 +2911,7 @@ BOOL rdp_print_bitmap_codecs_capability_set(wStream* s, UINT16 length) UINT16 codecPropertiesLength; UINT16 remainingLength; - fprintf(stderr, "BitmapCodecsCapabilitySet (length %d):\n", length); + DEBUG_WARN( "BitmapCodecsCapabilitySet (length %d):\n", length); if (length < 5) return FALSE; @@ -2914,7 +2919,7 @@ BOOL rdp_print_bitmap_codecs_capability_set(wStream* s, UINT16 length) Stream_Read_UINT8(s, bitmapCodecCount); /* bitmapCodecCount (1 byte) */ remainingLength = length - 5; - fprintf(stderr, "\tbitmapCodecCount: %d\n", bitmapCodecCount); + DEBUG_WARN( "\tbitmapCodecCount: %d\n", bitmapCodecCount); while (bitmapCodecCount > 0) { @@ -2924,14 +2929,14 @@ BOOL rdp_print_bitmap_codecs_capability_set(wStream* s, UINT16 length) rdp_read_bitmap_codec_guid(s, &codecGuid); /* codecGuid (16 bytes) */ Stream_Read_UINT8(s, codecId); /* codecId (1 byte) */ - fprintf(stderr, "\tcodecGuid: 0x"); + DEBUG_WARN( "\tcodecGuid: 0x"); rdp_print_bitmap_codec_guid(&codecGuid); - fprintf(stderr, " (%s)\n", rdp_get_bitmap_codec_guid_name(&codecGuid)); + DEBUG_WARN( " (%s)\n", rdp_get_bitmap_codec_guid_name(&codecGuid)); - fprintf(stderr, "\tcodecId: %d\n", codecId); + DEBUG_WARN( "\tcodecId: %d\n", codecId); Stream_Read_UINT16(s, codecPropertiesLength); /* codecPropertiesLength (2 bytes) */ - fprintf(stderr, "\tcodecPropertiesLength: %d\n", codecPropertiesLength); + DEBUG_WARN( "\tcodecPropertiesLength: %d\n", codecPropertiesLength); remainingLength -= 19; @@ -2994,14 +2999,14 @@ BOOL rdp_print_frame_acknowledge_capability_set(wStream* s, UINT16 length) { UINT32 frameAcknowledge; - fprintf(stderr, "FrameAcknowledgeCapabilitySet (length %d):\n", length); + DEBUG_WARN( "FrameAcknowledgeCapabilitySet (length %d):\n", length); if (length < 8) return FALSE; Stream_Read_UINT32(s, frameAcknowledge); /* frameAcknowledge (4 bytes) */ - fprintf(stderr, "\tframeAcknowledge: 0x%08X\n", frameAcknowledge); + DEBUG_WARN( "\tframeAcknowledge: 0x%08X\n", frameAcknowledge); return TRUE; } @@ -3034,14 +3039,14 @@ BOOL rdp_print_bitmap_cache_v3_codec_id_capability_set(wStream* s, UINT16 length { BYTE bitmapCacheV3CodecId; - fprintf(stderr, "BitmapCacheV3CodecIdCapabilitySet (length %d):\n", length); + DEBUG_WARN( "BitmapCacheV3CodecIdCapabilitySet (length %d):\n", length); if (length < 5) return FALSE; Stream_Read_UINT8(s, bitmapCacheV3CodecId); /* bitmapCacheV3CodecId (1 byte) */ - fprintf(stderr, "\tbitmapCacheV3CodecId: 0x%02X\n", bitmapCacheV3CodecId); + DEBUG_WARN( "\tbitmapCacheV3CodecId: 0x%02X\n", bitmapCacheV3CodecId); return TRUE; } @@ -3058,13 +3063,13 @@ BOOL rdp_print_capability_sets(wStream* s, UINT16 numberCapabilities, BOOL recei rdp_read_capability_set_header(s, &length, &type); - fprintf(stderr, "%s ", receiving ? "Receiving" : "Sending"); + DEBUG_WARN( "%s ", receiving ? "Receiving" : "Sending"); em = bm + length; if (Stream_GetRemainingLength(s) < (size_t) (length - 4)) { - fprintf(stderr, "error processing stream\n"); + DEBUG_WARN( "error processing stream\n"); return FALSE; } @@ -3216,13 +3221,13 @@ BOOL rdp_print_capability_sets(wStream* s, UINT16 numberCapabilities, BOOL recei break; default: - fprintf(stderr, "unknown capability type %d\n", type); + DEBUG_WARN( "unknown capability type %d\n", type); break; } if (s->pointer != em) { - fprintf(stderr, "incorrect offset, type:0x%02X actual:%d expected:%d\n", + DEBUG_WARN( "incorrect offset, type:0x%02X actual:%d expected:%d\n", type, (int) (s->pointer - bm), (int) (em - bm)); } @@ -3256,14 +3261,14 @@ BOOL rdp_read_capability_sets(wStream* s, rdpSettings* settings, UINT16 numberCa } else { - fprintf(stderr, "%s: not handling capability type %d yet\n", __FUNCTION__, type); + DEBUG_WARN( "%s: not handling capability type %d yet\n", __FUNCTION__, type); } em = bm + length; if (Stream_GetRemainingLength(s) < ((size_t) length - 4)) { - fprintf(stderr, "error processing stream\n"); + DEBUG_WARN( "error processing stream\n"); return FALSE; } @@ -3415,13 +3420,13 @@ BOOL rdp_read_capability_sets(wStream* s, rdpSettings* settings, UINT16 numberCa break; default: - fprintf(stderr, "unknown capability type %d\n", type); + DEBUG_WARN( "unknown capability type %d\n", type); break; } if (s->pointer != em) { - fprintf(stderr, "incorrect offset, type:0x%02X actual:%d expected:%d\n", + DEBUG_WARN( "incorrect offset, type:0x%02X actual:%d expected:%d\n", type, (int) (s->pointer - bm), (int) (em - bm)); } @@ -3431,7 +3436,7 @@ BOOL rdp_read_capability_sets(wStream* s, rdpSettings* settings, UINT16 numberCa if (numberCapabilities) { - fprintf(stderr, "%s: strange we haven't read the number of announced capacity sets, read=%d expected=%d\n", + DEBUG_WARN( "%s: strange we haven't read the number of announced capacity sets, read=%d expected=%d\n", __FUNCTION__, count-numberCapabilities, count); } @@ -3466,7 +3471,7 @@ BOOL rdp_recv_get_active_header(rdpRdp* rdp, wStream* s, UINT16* pChannelId) { if (!rdp_decrypt(rdp, s, length - 4, securityFlags)) { - fprintf(stderr, "rdp_decrypt failed\n"); + DEBUG_WARN( "rdp_decrypt failed\n"); return FALSE; } } @@ -3478,7 +3483,7 @@ BOOL rdp_recv_get_active_header(rdpRdp* rdp, wStream* s, UINT16* pChannelId) if ((mcsMessageChannelId == 0) || (*pChannelId != mcsMessageChannelId)) { - fprintf(stderr, "unexpected MCS channel id %04x received\n", *pChannelId); + DEBUG_WARN( "unexpected MCS channel id %04x received\n", *pChannelId); return FALSE; } } @@ -3504,14 +3509,14 @@ BOOL rdp_recv_demand_active(rdpRdp* rdp, wStream* s) if (!rdp_read_share_control_header(s, &pduLength, &pduType, &pduSource)) { - fprintf(stderr, "rdp_read_share_control_header failed\n"); + DEBUG_WARN( "rdp_read_share_control_header failed\n"); return FALSE; } if (pduType != PDU_TYPE_DEMAND_ACTIVE) { if (pduType != PDU_TYPE_SERVER_REDIRECTION) - fprintf(stderr, "expected PDU_TYPE_DEMAND_ACTIVE %04x, got %04x\n", PDU_TYPE_DEMAND_ACTIVE, pduType); + DEBUG_WARN( "expected PDU_TYPE_DEMAND_ACTIVE %04x, got %04x\n", PDU_TYPE_DEMAND_ACTIVE, pduType); return FALSE; } @@ -3534,7 +3539,7 @@ BOOL rdp_recv_demand_active(rdpRdp* rdp, wStream* s) /* capabilitySets */ if (!rdp_read_capability_sets(s, rdp->settings, numberCapabilities)) { - fprintf(stderr, "rdp_read_capability_sets failed\n"); + DEBUG_WARN( "rdp_read_capability_sets failed\n"); return FALSE; } diff --git a/libfreerdp/core/certificate.c b/libfreerdp/core/certificate.c index fcc3f01bf..0ec409592 100644 --- a/libfreerdp/core/certificate.c +++ b/libfreerdp/core/certificate.c @@ -279,7 +279,7 @@ error2: free(info->Modulus); info->Modulus = 0; error1: - fprintf(stderr, "error reading when reading certificate: part=%s error=%d\n", certificate_read_errors[error], error); + DEBUG_WARN( "error reading when reading certificate: part=%s error=%d\n", certificate_read_errors[error], error); Stream_Free(s, FALSE); return FALSE; } @@ -344,7 +344,7 @@ static BOOL certificate_process_server_public_key(rdpCertificate* certificate, w if (memcmp(magic, "RSA1", 4) != 0) { - fprintf(stderr, "%s: magic error\n", __FUNCTION__); + DEBUG_WARN( "%s: magic error\n", __FUNCTION__); return FALSE; } @@ -391,7 +391,7 @@ static BOOL certificate_process_server_public_signature(rdpCertificate* certific if (sum != 0) { - fprintf(stderr, "%s: invalid signature\n", __FUNCTION__); + DEBUG_WARN( "%s: invalid signature\n", __FUNCTION__); //return FALSE; } @@ -403,7 +403,7 @@ static BOOL certificate_process_server_public_signature(rdpCertificate* certific /* Verify signature. */ if (memcmp(md5hash, sig, sizeof(md5hash)) != 0) { - fprintf(stderr, "%s: invalid signature\n", __FUNCTION__); + DEBUG_WARN( "%s: invalid signature\n", __FUNCTION__); //return FALSE; } @@ -419,7 +419,7 @@ static BOOL certificate_process_server_public_signature(rdpCertificate* certific if (sig[16] != 0x00 || sum != 0xFF * (62 - 17) || sig[62] != 0x01) { - fprintf(stderr, "%s: invalid signature\n", __FUNCTION__); + DEBUG_WARN( "%s: invalid signature\n", __FUNCTION__); //return FALSE; } @@ -453,7 +453,7 @@ BOOL certificate_read_server_proprietary_certificate(rdpCertificate* certificate if (!(dwSigAlgId == SIGNATURE_ALG_RSA && dwKeyAlgId == KEY_EXCHANGE_ALG_RSA)) { - fprintf(stderr, "%s: unsupported signature or key algorithm, dwSigAlgId=%d dwKeyAlgId=%d\n", + DEBUG_WARN( "%s: unsupported signature or key algorithm, dwSigAlgId=%d dwKeyAlgId=%d\n", __FUNCTION__, dwSigAlgId, dwKeyAlgId); return FALSE; } @@ -462,7 +462,7 @@ BOOL certificate_read_server_proprietary_certificate(rdpCertificate* certificate if (wPublicKeyBlobType != BB_RSA_KEY_BLOB) { - fprintf(stderr, "%s: unsupported public key blob type %d\n", __FUNCTION__, wPublicKeyBlobType); + DEBUG_WARN( "%s: unsupported public key blob type %d\n", __FUNCTION__, wPublicKeyBlobType); return FALSE; } @@ -472,7 +472,7 @@ BOOL certificate_read_server_proprietary_certificate(rdpCertificate* certificate if (!certificate_process_server_public_key(certificate, s, wPublicKeyBlobLen)) { - fprintf(stderr, "%s: error in server public key\n", __FUNCTION__); + DEBUG_WARN( "%s: error in server public key\n", __FUNCTION__); return FALSE; } @@ -484,26 +484,26 @@ BOOL certificate_read_server_proprietary_certificate(rdpCertificate* certificate if (wSignatureBlobType != BB_RSA_SIGNATURE_BLOB) { - fprintf(stderr, "%s: unsupported blob signature %d\n", __FUNCTION__, wSignatureBlobType); + DEBUG_WARN( "%s: unsupported blob signature %d\n", __FUNCTION__, wSignatureBlobType); return FALSE; } Stream_Read_UINT16(s, wSignatureBlobLen); if (Stream_GetRemainingLength(s) < wSignatureBlobLen) { - fprintf(stderr, "%s: not enought bytes for signature(len=%d)\n", __FUNCTION__, wSignatureBlobLen); + DEBUG_WARN( "%s: not enought bytes for signature(len=%d)\n", __FUNCTION__, wSignatureBlobLen); return FALSE; } if (wSignatureBlobLen != 72) { - fprintf(stderr, "%s: invalid signature length (got %d, expected %d)\n", __FUNCTION__, wSignatureBlobLen, 64); + DEBUG_WARN( "%s: invalid signature length (got %d, expected %d)\n", __FUNCTION__, wSignatureBlobLen, 64); return FALSE; } if (!certificate_process_server_public_signature(certificate, sigdata, sigdatalen, s, wSignatureBlobLen)) { - fprintf(stderr, "%s: unable to parse server public signature\n", __FUNCTION__); + DEBUG_WARN( "%s: unable to parse server public signature\n", __FUNCTION__); return FALSE; } @@ -560,7 +560,7 @@ BOOL certificate_read_server_x509_certificate_chain(rdpCertificate* certificate, if (cert_info.Modulus) free(cert_info.Modulus); if (!ret) { - fprintf(stderr, "failed to read License Server, content follows:\n"); + DEBUG_WARN( "failed to read License Server, content follows:\n"); winpr_HexDump(certificate->x509_cert_chain->array[i].data, certificate->x509_cert_chain->array[i].length); return FALSE; } @@ -608,7 +608,7 @@ BOOL certificate_read_server_certificate(rdpCertificate* certificate, BYTE* serv break; default: - fprintf(stderr, "invalid certificate chain version:%d\n", dwVersion & CERT_CHAIN_VERSION_MASK); + DEBUG_WARN( "invalid certificate chain version:%d\n", dwVersion & CERT_CHAIN_VERSION_MASK); ret = FALSE; break; } @@ -631,14 +631,14 @@ rdpRsaKey* key_new(const char* keyfile) fp = fopen(keyfile, "r"); if (fp == NULL) { - fprintf(stderr, "%s: unable to open RSA key file %s: %s.", __FUNCTION__, keyfile, strerror(errno)); + DEBUG_WARN( "%s: unable to open RSA key file %s: %s.", __FUNCTION__, keyfile, strerror(errno)); goto out_free; } rsa = PEM_read_RSAPrivateKey(fp, NULL, NULL, NULL); if (rsa == NULL) { - fprintf(stderr, "%s: unable to load RSA key from %s: %s.", __FUNCTION__, keyfile, strerror(errno)); + DEBUG_WARN( "%s: unable to load RSA key from %s: %s.", __FUNCTION__, keyfile, strerror(errno)); ERR_print_errors_fp(stderr); fclose(fp); goto out_free; @@ -649,7 +649,7 @@ rdpRsaKey* key_new(const char* keyfile) switch (RSA_check_key(rsa)) { case 0: - fprintf(stderr, "%s: invalid RSA key in %s\n", __FUNCTION__, keyfile); + DEBUG_WARN( "%s: invalid RSA key in %s\n", __FUNCTION__, keyfile); goto out_free_rsa; case 1: @@ -657,14 +657,14 @@ rdpRsaKey* key_new(const char* keyfile) break; default: - fprintf(stderr, "%s: unexpected error when checking RSA key from %s: %s.", __FUNCTION__, keyfile, strerror(errno)); + DEBUG_WARN( "%s: unexpected error when checking RSA key from %s: %s.", __FUNCTION__, keyfile, strerror(errno)); ERR_print_errors_fp(stderr); goto out_free_rsa; } if (BN_num_bytes(rsa->e) > 4) { - fprintf(stderr, "%s: RSA public exponent too large in %s\n", __FUNCTION__, keyfile); + DEBUG_WARN( "%s: RSA public exponent too large in %s\n", __FUNCTION__, keyfile); goto out_free_rsa; } diff --git a/libfreerdp/core/channels.c b/libfreerdp/core/channels.c index 54cfa99cf..943b0e913 100644 --- a/libfreerdp/core/channels.c +++ b/libfreerdp/core/channels.c @@ -67,7 +67,7 @@ BOOL freerdp_channel_send(rdpRdp* rdp, UINT16 channelId, BYTE* data, int size) if (!channel) { - fprintf(stderr, "freerdp_channel_send: unknown channelId %d\n", channelId); + DEBUG_WARN( "freerdp_channel_send: unknown channelId %d\n", channelId); return FALSE; } diff --git a/libfreerdp/core/client.c b/libfreerdp/core/client.c index 5f4aec1e6..87dee69d2 100644 --- a/libfreerdp/core/client.c +++ b/libfreerdp/core/client.c @@ -715,7 +715,7 @@ int freerdp_channels_client_load(rdpChannels* channels, rdpSettings* settings, v if (channels->clientDataCount + 1 >= CHANNEL_MAX_COUNT) { - fprintf(stderr, "error: too many channels\n"); + DEBUG_WARN( "error: too many channels\n"); return 1; } @@ -754,7 +754,7 @@ int freerdp_channels_client_load(rdpChannels* channels, rdpSettings* settings, v if (!status) { - fprintf(stderr, "error: channel export function call failed\n"); + DEBUG_WARN( "error: channel export function call failed\n"); return 1; } diff --git a/libfreerdp/core/connection.c b/libfreerdp/core/connection.c index eeba652bf..52947636a 100644 --- a/libfreerdp/core/connection.c +++ b/libfreerdp/core/connection.c @@ -266,7 +266,7 @@ BOOL rdp_client_connect(rdpRdp* rdp) freerdp_set_last_error(rdp->context, FREERDP_ERROR_SECURITY_NEGO_CONNECT_FAILED); } - fprintf(stderr, "Error: protocol security negotiation or connection failure\n"); + DEBUG_WARN( "Error: protocol security negotiation or connection failure\n"); return FALSE; } @@ -294,7 +294,7 @@ BOOL rdp_client_connect(rdpRdp* rdp) freerdp_set_last_error(rdp->context, FREERDP_ERROR_MCS_CONNECT_INITIAL_ERROR); } - fprintf(stderr, "Error: unable to send MCS Connect Initial\n"); + DEBUG_WARN( "Error: unable to send MCS Connect Initial\n"); return FALSE; } @@ -388,11 +388,14 @@ static BOOL rdp_client_establish_keys(rdpRdp* rdp) wStream* s; UINT32 length; UINT32 key_len; - BYTE *crypt_client_random = NULL; - BOOL ret = FALSE; int status = 0; + BOOL ret = FALSE; + rdpSettings* settings; + BYTE* crypt_client_random = NULL; - if (!rdp->settings->DisableEncryption) + settings = rdp->settings; + + if (!settings->DisableEncryption) { /* no RDP encryption */ return TRUE; @@ -400,27 +403,30 @@ static BOOL rdp_client_establish_keys(rdpRdp* rdp) /* encrypt client random */ - if (rdp->settings->ClientRandom) - free(rdp->settings->ClientRandom); + if (settings->ClientRandom) + free(settings->ClientRandom); - rdp->settings->ClientRandom = malloc(CLIENT_RANDOM_LENGTH); + settings->ClientRandomLength = CLIENT_RANDOM_LENGTH; + settings->ClientRandom = malloc(settings->ClientRandomLength); - if (!rdp->settings->ClientRandom) + if (!settings->ClientRandom) return FALSE; + crypto_nonce(settings->ClientRandom, settings->ClientRandomLength); + key_len = settings->RdpServerCertificate->cert_info.ModulusLength; + mod = settings->RdpServerCertificate->cert_info.Modulus; + exp = settings->RdpServerCertificate->cert_info.exponent; - crypto_nonce(rdp->settings->ClientRandom, CLIENT_RANDOM_LENGTH); - key_len = rdp->settings->RdpServerCertificate->cert_info.ModulusLength; - mod = rdp->settings->RdpServerCertificate->cert_info.Modulus; - exp = rdp->settings->RdpServerCertificate->cert_info.exponent; /* * client random must be (bitlen / 8) + 8 - see [MS-RDPBCGR] 5.3.4.1 * for details */ - crypt_client_random = calloc(1,key_len+8); + crypt_client_random = calloc(1, key_len + 8); + if (!crypt_client_random) return FALSE; - crypto_rsa_public_encrypt(rdp->settings->ClientRandom, CLIENT_RANDOM_LENGTH, key_len, mod, exp, crypt_client_random); + + crypto_rsa_public_encrypt(settings->ClientRandom, settings->ClientRandomLength, key_len, mod, exp, crypt_client_random); /* send crypt client random to server */ length = RDP_PACKET_HEADER_MAX_LENGTH + RDP_SECURITY_HEADER_LENGTH + 4 + key_len + 8; @@ -441,33 +447,33 @@ static BOOL rdp_client_establish_keys(rdpRdp* rdp) goto end; /* now calculate encrypt / decrypt and update keys */ - if (!security_establish_keys(rdp->settings->ClientRandom, rdp)) + if (!security_establish_keys(settings->ClientRandom, rdp)) goto end; rdp->do_crypt = TRUE; - if (rdp->settings->SaltedChecksum) + if (settings->SaltedChecksum) rdp->do_secure_checksum = TRUE; - if (rdp->settings->EncryptionMethods == ENCRYPTION_METHOD_FIPS) + if (settings->EncryptionMethods == ENCRYPTION_METHOD_FIPS) { rdp->fips_encrypt = crypto_des3_encrypt_init(rdp->fips_encrypt_key, fips_ivec); if (!rdp->fips_encrypt) { - fprintf(stderr, "%s: unable to allocate des3 encrypt key\n", __FUNCTION__); + DEBUG_WARN( "%s: unable to allocate des3 encrypt key\n", __FUNCTION__); goto end; } rdp->fips_decrypt = crypto_des3_decrypt_init(rdp->fips_decrypt_key, fips_ivec); if (!rdp->fips_decrypt) { - fprintf(stderr, "%s: unable to allocate des3 decrypt key\n", __FUNCTION__); + DEBUG_WARN( "%s: unable to allocate des3 decrypt key\n", __FUNCTION__); goto end; } rdp->fips_hmac = crypto_hmac_new(); if (!rdp->fips_hmac) { - fprintf(stderr, "%s: unable to allocate fips hmac\n", __FUNCTION__); + DEBUG_WARN( "%s: unable to allocate fips hmac\n", __FUNCTION__); goto end; } ret = TRUE; @@ -477,14 +483,14 @@ static BOOL rdp_client_establish_keys(rdpRdp* rdp) rdp->rc4_decrypt_key = crypto_rc4_init(rdp->decrypt_key, rdp->rc4_key_len); if (!rdp->rc4_decrypt_key) { - fprintf(stderr, "%s: unable to allocate rc4 decrypt key\n", __FUNCTION__); + DEBUG_WARN( "%s: unable to allocate rc4 decrypt key\n", __FUNCTION__); goto end; } rdp->rc4_encrypt_key = crypto_rc4_init(rdp->encrypt_key, rdp->rc4_key_len); if (!rdp->rc4_encrypt_key) { - fprintf(stderr, "%s: unable to allocate rc4 encrypt key\n", __FUNCTION__); + DEBUG_WARN( "%s: unable to allocate rc4 encrypt key\n", __FUNCTION__); goto end; } ret = TRUE; @@ -512,19 +518,19 @@ BOOL rdp_server_establish_keys(rdpRdp* rdp, wStream* s) if (!rdp_read_header(rdp, s, &length, &channel_id)) { - fprintf(stderr, "%s: invalid RDP header\n", __FUNCTION__); + DEBUG_WARN( "%s: invalid RDP header\n", __FUNCTION__); return FALSE; } if (!rdp_read_security_header(s, &sec_flags)) { - fprintf(stderr, "%s: invalid security header\n", __FUNCTION__); + DEBUG_WARN( "%s: invalid security header\n", __FUNCTION__); return FALSE; } if ((sec_flags & SEC_EXCHANGE_PKT) == 0) { - fprintf(stderr, "%s: missing SEC_EXCHANGE_PKT in security header\n", __FUNCTION__); + DEBUG_WARN( "%s: missing SEC_EXCHANGE_PKT in security header\n", __FUNCTION__); return FALSE; } @@ -544,7 +550,7 @@ BOOL rdp_server_establish_keys(rdpRdp* rdp, wStream* s) if (rand_len != key_len + 8) { - fprintf(stderr, "%s: invalid encrypted client random length\n", __FUNCTION__); + DEBUG_WARN( "%s: invalid encrypted client random length\n", __FUNCTION__); goto end2; } @@ -573,21 +579,21 @@ BOOL rdp_server_establish_keys(rdpRdp* rdp, wStream* s) rdp->fips_encrypt = crypto_des3_encrypt_init(rdp->fips_encrypt_key, fips_ivec); if (!rdp->fips_encrypt) { - fprintf(stderr, "%s: unable to allocate des3 encrypt key\n", __FUNCTION__); + DEBUG_WARN( "%s: unable to allocate des3 encrypt key\n", __FUNCTION__); goto end; } rdp->fips_decrypt = crypto_des3_decrypt_init(rdp->fips_decrypt_key, fips_ivec); if (!rdp->fips_decrypt) { - fprintf(stderr, "%s: unable to allocate des3 decrypt key\n", __FUNCTION__); + DEBUG_WARN( "%s: unable to allocate des3 decrypt key\n", __FUNCTION__); goto end; } rdp->fips_hmac = crypto_hmac_new(); if (!rdp->fips_hmac) { - fprintf(stderr, "%s: unable to allocate fips hmac\n", __FUNCTION__); + DEBUG_WARN( "%s: unable to allocate fips hmac\n", __FUNCTION__); goto end; } ret = TRUE; @@ -597,14 +603,14 @@ BOOL rdp_server_establish_keys(rdpRdp* rdp, wStream* s) rdp->rc4_decrypt_key = crypto_rc4_init(rdp->decrypt_key, rdp->rc4_key_len); if (!rdp->rc4_decrypt_key) { - fprintf(stderr, "%s: unable to allocate rc4 decrypt key\n", __FUNCTION__); + DEBUG_WARN( "%s: unable to allocate rc4 decrypt key\n", __FUNCTION__); goto end; } rdp->rc4_encrypt_key = crypto_rc4_init(rdp->encrypt_key, rdp->rc4_key_len); if (!rdp->rc4_encrypt_key) { - fprintf(stderr, "%s: unable to allocate rc4 encrypt key\n", __FUNCTION__); + DEBUG_WARN( "%s: unable to allocate rc4 encrypt key\n", __FUNCTION__); goto end; } ret = TRUE; @@ -622,7 +628,7 @@ BOOL rdp_client_connect_mcs_connect_response(rdpRdp* rdp, wStream* s) { if (!mcs_recv_connect_response(rdp->mcs, s)) { - fprintf(stderr, "rdp_client_connect_mcs_connect_response: mcs_recv_connect_response failed\n"); + DEBUG_WARN( "rdp_client_connect_mcs_connect_response: mcs_recv_connect_response failed\n"); return FALSE; } @@ -786,7 +792,7 @@ int rdp_client_connect_license(rdpRdp* rdp, wStream* s) if (rdp->license->state == LICENSE_STATE_ABORTED) { - fprintf(stderr, "license connection sequence aborted.\n"); + DEBUG_WARN( "license connection sequence aborted.\n"); return -1; } @@ -966,13 +972,13 @@ BOOL rdp_server_accept_nego(rdpRdp* rdp, wStream* s) nego->selected_protocol = 0; - fprintf(stderr, "Client Security: NLA:%d TLS:%d RDP:%d\n", + DEBUG_WARN( "Client Security: NLA:%d TLS:%d RDP:%d\n", (nego->requested_protocols & PROTOCOL_NLA) ? 1 : 0, (nego->requested_protocols & PROTOCOL_TLS) ? 1 : 0, (nego->requested_protocols == PROTOCOL_RDP) ? 1 : 0 ); - fprintf(stderr, "Server Security: NLA:%d TLS:%d RDP:%d\n", + DEBUG_WARN( "Server Security: NLA:%d TLS:%d RDP:%d\n", settings->NlaSecurity, settings->TlsSecurity, settings->RdpSecurity); if ((settings->NlaSecurity) && (nego->requested_protocols & PROTOCOL_NLA)) @@ -989,10 +995,10 @@ BOOL rdp_server_accept_nego(rdpRdp* rdp, wStream* s) } else { - fprintf(stderr, "Protocol security negotiation failure\n"); + DEBUG_WARN( "Protocol security negotiation failure\n"); } - fprintf(stderr, "Negotiated Security: NLA:%d TLS:%d RDP:%d\n", + DEBUG_WARN( "Negotiated Security: NLA:%d TLS:%d RDP:%d\n", (nego->selected_protocol & PROTOCOL_NLA) ? 1 : 0, (nego->selected_protocol & PROTOCOL_TLS) ? 1 : 0, (nego->selected_protocol == PROTOCOL_RDP) ? 1: 0 @@ -1028,14 +1034,14 @@ BOOL rdp_server_accept_mcs_connect_initial(rdpRdp* rdp, wStream* s) if (!mcs_recv_connect_initial(mcs, s)) return FALSE; - fprintf(stderr, "Accepted client: %s\n", rdp->settings->ClientHostname); - fprintf(stderr, "Accepted channels:"); + DEBUG_WARN( "Accepted client: %s\n", rdp->settings->ClientHostname); + DEBUG_WARN( "Accepted channels:"); for (i = 0; i < mcs->channelCount; i++) { - fprintf(stderr, " %s", mcs->channels[i].Name); + DEBUG_WARN( " %s", mcs->channels[i].Name); } - fprintf(stderr, "\n"); + DEBUG_WARN( "\n"); if (!mcs_send_connect_response(mcs)) return FALSE; diff --git a/libfreerdp/core/errinfo.c b/libfreerdp/core/errinfo.c index 739dc18e4..cb99558f2 100644 --- a/libfreerdp/core/errinfo.c +++ b/libfreerdp/core/errinfo.c @@ -23,6 +23,8 @@ #include +#include + #include "errinfo.h" int connectErrorCode; @@ -563,12 +565,12 @@ void rdp_print_errinfo(UINT32 code) { if (code == errInfo->code) { - fprintf(stderr, "%s (0x%08X):\n%s\n", errInfo->name, code, errInfo->info); + DEBUG_WARN( "%s (0x%08X):\n%s\n", errInfo->name, code, errInfo->info); return; } errInfo++; } - fprintf(stderr, "ERRINFO_UNKNOWN 0x%08X: Unknown error.\n", code); + DEBUG_WARN( "ERRINFO_UNKNOWN 0x%08X: Unknown error.\n", code); } diff --git a/libfreerdp/core/fastpath.c b/libfreerdp/core/fastpath.c index 417770cdc..d3543ef88 100644 --- a/libfreerdp/core/fastpath.c +++ b/libfreerdp/core/fastpath.c @@ -271,7 +271,7 @@ static int fastpath_recv_update(rdpFastPath* fastpath, BYTE updateCode, UINT32 s case FASTPATH_UPDATETYPE_SYNCHRONIZE: if (!fastpath_recv_update_synchronize(fastpath, s)) - fprintf(stderr, "fastpath_recv_update_synchronize failure but we continue\n"); + DEBUG_WARN( "fastpath_recv_update_synchronize failure but we continue\n"); else IFCALL(update->Synchronize, context); break; @@ -377,7 +377,7 @@ static int fastpath_recv_update_data(rdpFastPath* fastpath, wStream* s) if (bulkStatus < 0) { - fprintf(stderr, "bulk_decompress() failed\n"); + DEBUG_WARN( "bulk_decompress() failed\n"); return -1; } @@ -398,7 +398,7 @@ static int fastpath_recv_update_data(rdpFastPath* fastpath, wStream* s) { if (fastpath->fragmentation != -1) { - fprintf(stderr, "Unexpected FASTPATH_FRAGMENT_SINGLE\n"); + DEBUG_WARN( "Unexpected FASTPATH_FRAGMENT_SINGLE\n"); return -1; } @@ -414,7 +414,7 @@ static int fastpath_recv_update_data(rdpFastPath* fastpath, wStream* s) { if (fastpath->fragmentation != -1) { - fprintf(stderr, "Unexpected FASTPATH_FRAGMENT_FIRST\n"); + DEBUG_WARN( "Unexpected FASTPATH_FRAGMENT_FIRST\n"); return -1; } @@ -424,7 +424,7 @@ static int fastpath_recv_update_data(rdpFastPath* fastpath, wStream* s) if (totalSize > transport->settings->MultifragMaxRequestSize) { - fprintf(stderr, "Total size (%d) exceeds MultifragMaxRequestSize (%d)\n", + DEBUG_WARN( "Total size (%d) exceeds MultifragMaxRequestSize (%d)\n", totalSize, transport->settings->MultifragMaxRequestSize); return -1; } @@ -439,7 +439,7 @@ static int fastpath_recv_update_data(rdpFastPath* fastpath, wStream* s) if ((fastpath->fragmentation != FASTPATH_FRAGMENT_FIRST) && (fastpath->fragmentation != FASTPATH_FRAGMENT_NEXT)) { - fprintf(stderr, "Unexpected FASTPATH_FRAGMENT_NEXT\n"); + DEBUG_WARN( "Unexpected FASTPATH_FRAGMENT_NEXT\n"); return -1; } @@ -449,7 +449,7 @@ static int fastpath_recv_update_data(rdpFastPath* fastpath, wStream* s) if (totalSize > transport->settings->MultifragMaxRequestSize) { - fprintf(stderr, "Total size (%d) exceeds MultifragMaxRequestSize (%d)\n", + DEBUG_WARN( "Total size (%d) exceeds MultifragMaxRequestSize (%d)\n", totalSize, transport->settings->MultifragMaxRequestSize); return -1; } @@ -463,7 +463,7 @@ static int fastpath_recv_update_data(rdpFastPath* fastpath, wStream* s) if ((fastpath->fragmentation != FASTPATH_FRAGMENT_FIRST) && (fastpath->fragmentation != FASTPATH_FRAGMENT_NEXT)) { - fprintf(stderr, "Unexpected FASTPATH_FRAGMENT_LAST\n"); + DEBUG_WARN( "Unexpected FASTPATH_FRAGMENT_LAST\n"); return -1; } @@ -473,7 +473,7 @@ static int fastpath_recv_update_data(rdpFastPath* fastpath, wStream* s) if (totalSize > transport->settings->MultifragMaxRequestSize) { - fprintf(stderr, "Total size (%d) exceeds MultifragMaxRequestSize (%d)\n", + DEBUG_WARN( "Total size (%d) exceeds MultifragMaxRequestSize (%d)\n", totalSize, transport->settings->MultifragMaxRequestSize); return -1; } @@ -661,7 +661,7 @@ static BOOL fastpath_recv_input_event(rdpFastPath* fastpath, wStream* s) break; default: - fprintf(stderr, "Unknown eventCode %d\n", eventCode); + DEBUG_WARN( "Unknown eventCode %d\n", eventCode); break; } @@ -768,7 +768,7 @@ BOOL fastpath_send_multiple_input_pdu(rdpFastPath* fastpath, wStream* s, int iNu if (length >= (2 << 14)) { - fprintf(stderr, "Maximum FastPath PDU length is 32767\n"); + DEBUG_WARN( "Maximum FastPath PDU length is 32767\n"); return FALSE; } diff --git a/libfreerdp/core/fastpath.h b/libfreerdp/core/fastpath.h index 7f1c59cab..05e96422f 100644 --- a/libfreerdp/core/fastpath.h +++ b/libfreerdp/core/fastpath.h @@ -108,7 +108,8 @@ enum FASTPATH_INPUT_EVENT_CODE enum FASTPATH_INPUT_KBDFLAGS { FASTPATH_INPUT_KBDFLAGS_RELEASE = 0x01, - FASTPATH_INPUT_KBDFLAGS_EXTENDED = 0x02 + FASTPATH_INPUT_KBDFLAGS_EXTENDED = 0x02, + FASTPATH_INPUT_KBDFLAGS_PREFIX_E1 = 0x04 /* for pause sequence */ }; struct _FASTPATH_UPDATE_PDU_HEADER diff --git a/libfreerdp/core/freerdp.c b/libfreerdp/core/freerdp.c index f40bd6a28..eeec2a7ae 100644 --- a/libfreerdp/core/freerdp.c +++ b/libfreerdp/core/freerdp.c @@ -90,7 +90,7 @@ BOOL freerdp_connect(freerdp* instance) freerdp_set_last_error(instance->context, FREERDP_ERROR_PRE_CONNECT_FAILED); } - fprintf(stderr, "freerdp_pre_connect failed\n"); + DEBUG_WARN( "freerdp_pre_connect failed\n"); goto freerdp_connect_finally; } @@ -100,7 +100,7 @@ BOOL freerdp_connect(freerdp* instance) /* --authonly tests the connection without a UI */ if (instance->settings->AuthenticationOnly) { - fprintf(stderr, "Authentication only, exit status %d\n", !status); + DEBUG_WARN( "Authentication only, exit status %d\n", !status); goto freerdp_connect_finally; } @@ -118,7 +118,7 @@ BOOL freerdp_connect(freerdp* instance) if (!status) { - fprintf(stderr, "freerdp_post_connect failed\n"); + DEBUG_WARN( "freerdp_post_connect failed\n"); if (!connectErrorCode) { @@ -317,6 +317,7 @@ BOOL freerdp_disconnect(freerdp* instance) rdp = instance->context->rdp; transport_disconnect(rdp->transport); + update_post_disconnect(instance->update); IFCALL(instance->PostDisconnect, instance); if (instance->update->pcap_rfx) @@ -482,7 +483,7 @@ UINT32 freerdp_get_last_error(rdpContext* context) void freerdp_set_last_error(rdpContext* context, UINT32 lastError) { if (lastError) - fprintf(stderr, "freerdp_set_last_error 0x%04X\n", lastError); + DEBUG_WARN( "freerdp_set_last_error 0x%04X\n", lastError); context->LastError = lastError; } diff --git a/libfreerdp/core/gateway/http.c b/libfreerdp/core/gateway/http.c index 610b23091..94608858a 100644 --- a/libfreerdp/core/gateway/http.c +++ b/libfreerdp/core/gateway/http.c @@ -26,6 +26,8 @@ #include #include +#include + #ifdef HAVE_VALGRIND_MEMCHECK_H #include #endif @@ -457,9 +459,9 @@ void http_response_print(HttpResponse* http_response) for (i = 0; i < http_response->count; i++) { - fprintf(stderr, "%s\n", http_response->lines[i]); + DEBUG_WARN( "%s\n", http_response->lines[i]); } - fprintf(stderr, "\n"); + DEBUG_WARN( "\n"); } HttpResponse* http_response_recv(rdpTls* tls) @@ -513,7 +515,7 @@ HttpResponse* http_response_recv(rdpTls* tls) if (!header_end) { - fprintf(stderr, "%s: invalid response:\n", __FUNCTION__); + DEBUG_WARN( "%s: invalid response:\n", __FUNCTION__); winpr_HexDump(buffer, status); goto out_error; } diff --git a/libfreerdp/core/gateway/ntlm.c b/libfreerdp/core/gateway/ntlm.c index 549726ca4..44f77a6b2 100644 --- a/libfreerdp/core/gateway/ntlm.c +++ b/libfreerdp/core/gateway/ntlm.c @@ -71,7 +71,7 @@ BOOL ntlm_client_init(rdpNtlm* ntlm, BOOL http, char* user, char* domain, char* if (status != SEC_E_OK) { - fprintf(stderr, "QuerySecurityPackageInfo status: 0x%08X\n", status); + DEBUG_WARN( "QuerySecurityPackageInfo status: 0x%08X\n", status); return FALSE; } @@ -82,7 +82,7 @@ BOOL ntlm_client_init(rdpNtlm* ntlm, BOOL http, char* user, char* domain, char* if (status != SEC_E_OK) { - fprintf(stderr, "AcquireCredentialsHandle status: 0x%08X\n", status); + DEBUG_WARN( "AcquireCredentialsHandle status: 0x%08X\n", status); return FALSE; } @@ -235,7 +235,7 @@ BOOL ntlm_authenticate(rdpNtlm* ntlm) if ((!ntlm) || (!ntlm->table)) { - fprintf(stderr, "ntlm_authenticate: invalid ntlm context\n"); + DEBUG_WARN( "ntlm_authenticate: invalid ntlm context\n"); return FALSE; } @@ -254,7 +254,7 @@ BOOL ntlm_authenticate(rdpNtlm* ntlm) if (ntlm->table->QueryContextAttributes(&ntlm->context, SECPKG_ATTR_SIZES, &ntlm->ContextSizes) != SEC_E_OK) { - fprintf(stderr, "QueryContextAttributes SECPKG_ATTR_SIZES failure\n"); + DEBUG_WARN( "QueryContextAttributes SECPKG_ATTR_SIZES failure\n"); return FALSE; } diff --git a/libfreerdp/core/gateway/rpc.c b/libfreerdp/core/gateway/rpc.c index ad177fe65..fd13e48c2 100644 --- a/libfreerdp/core/gateway/rpc.c +++ b/libfreerdp/core/gateway/rpc.c @@ -92,45 +92,45 @@ const RPC_SECURITY_PROVIDER_INFO RPC_SECURITY_PROVIDER_INFO_TABLE[] = void rpc_pdu_header_print(rpcconn_hdr_t* header) { - fprintf(stderr, "rpc_vers: %d\n", header->common.rpc_vers); - fprintf(stderr, "rpc_vers_minor: %d\n", header->common.rpc_vers_minor); + DEBUG_WARN( "rpc_vers: %d\n", header->common.rpc_vers); + DEBUG_WARN( "rpc_vers_minor: %d\n", header->common.rpc_vers_minor); if (header->common.ptype > PTYPE_RTS) - fprintf(stderr, "ptype: %s (%d)\n", "PTYPE_UNKNOWN", header->common.ptype); + DEBUG_WARN( "ptype: %s (%d)\n", "PTYPE_UNKNOWN", header->common.ptype); else - fprintf(stderr, "ptype: %s (%d)\n", PTYPE_STRINGS[header->common.ptype], header->common.ptype); + DEBUG_WARN( "ptype: %s (%d)\n", PTYPE_STRINGS[header->common.ptype], header->common.ptype); - fprintf(stderr, "pfc_flags (0x%02X) = {", header->common.pfc_flags); + DEBUG_WARN( "pfc_flags (0x%02X) = {", header->common.pfc_flags); if (header->common.pfc_flags & PFC_FIRST_FRAG) - fprintf(stderr, " PFC_FIRST_FRAG"); + DEBUG_WARN( " PFC_FIRST_FRAG"); if (header->common.pfc_flags & PFC_LAST_FRAG) - fprintf(stderr, " PFC_LAST_FRAG"); + DEBUG_WARN( " PFC_LAST_FRAG"); if (header->common.pfc_flags & PFC_PENDING_CANCEL) - fprintf(stderr, " PFC_PENDING_CANCEL"); + DEBUG_WARN( " PFC_PENDING_CANCEL"); if (header->common.pfc_flags & PFC_RESERVED_1) - fprintf(stderr, " PFC_RESERVED_1"); + DEBUG_WARN( " PFC_RESERVED_1"); if (header->common.pfc_flags & PFC_CONC_MPX) - fprintf(stderr, " PFC_CONC_MPX"); + DEBUG_WARN( " PFC_CONC_MPX"); if (header->common.pfc_flags & PFC_DID_NOT_EXECUTE) - fprintf(stderr, " PFC_DID_NOT_EXECUTE"); + DEBUG_WARN( " PFC_DID_NOT_EXECUTE"); if (header->common.pfc_flags & PFC_OBJECT_UUID) - fprintf(stderr, " PFC_OBJECT_UUID"); - fprintf(stderr, " }\n"); + DEBUG_WARN( " PFC_OBJECT_UUID"); + DEBUG_WARN( " }\n"); - fprintf(stderr, "packed_drep[4]: %02X %02X %02X %02X\n", + DEBUG_WARN( "packed_drep[4]: %02X %02X %02X %02X\n", header->common.packed_drep[0], header->common.packed_drep[1], header->common.packed_drep[2], header->common.packed_drep[3]); - fprintf(stderr, "frag_length: %d\n", header->common.frag_length); - fprintf(stderr, "auth_length: %d\n", header->common.auth_length); - fprintf(stderr, "call_id: %d\n", header->common.call_id); + DEBUG_WARN( "frag_length: %d\n", header->common.frag_length); + DEBUG_WARN( "auth_length: %d\n", header->common.auth_length); + DEBUG_WARN( "call_id: %d\n", header->common.call_id); if (header->common.ptype == PTYPE_RESPONSE) { - fprintf(stderr, "alloc_hint: %d\n", header->response.alloc_hint); - fprintf(stderr, "p_cont_id: %d\n", header->response.p_cont_id); - fprintf(stderr, "cancel_count: %d\n", header->response.cancel_count); - fprintf(stderr, "reserved: %d\n", header->response.reserved); + DEBUG_WARN( "alloc_hint: %d\n", header->response.alloc_hint); + DEBUG_WARN( "p_cont_id: %d\n", header->response.p_cont_id); + DEBUG_WARN( "cancel_count: %d\n", header->response.cancel_count); + DEBUG_WARN( "reserved: %d\n", header->response.reserved); } } @@ -265,7 +265,7 @@ BOOL rpc_get_stub_data_info(rdpRpc* rpc, BYTE* buffer, UINT32* offset, UINT32* l *offset += 4; break; default: - fprintf(stderr, "%s: unknown ptype=0x%x\n", __FUNCTION__, header->common.ptype); + DEBUG_WARN( "%s: unknown ptype=0x%x\n", __FUNCTION__, header->common.ptype); return FALSE; } @@ -290,7 +290,7 @@ BOOL rpc_get_stub_data_info(rdpRpc* rpc, BYTE* buffer, UINT32* offset, UINT32* l auth_pad_length = sec_trailer->auth_pad_length; #if 0 - fprintf(stderr, "sec_trailer: type: %d level: %d pad_length: %d reserved: %d context_id: %d\n", + DEBUG_WARN( "sec_trailer: type: %d level: %d pad_length: %d reserved: %d context_id: %d\n", sec_trailer->auth_type, sec_trailer->auth_level, sec_trailer->auth_pad_length, @@ -306,7 +306,7 @@ BOOL rpc_get_stub_data_info(rdpRpc* rpc, BYTE* buffer, UINT32* offset, UINT32* l if ((frag_length - (sec_trailer_offset + 8)) != auth_length) { - fprintf(stderr, "invalid auth_length: actual: %d, expected: %d\n", auth_length, + DEBUG_WARN( "invalid auth_length: actual: %d, expected: %d\n", auth_length, (frag_length - (sec_trailer_offset + 8))); } @@ -347,10 +347,10 @@ int rpc_in_write(rdpRpc* rpc, const BYTE* data, int length) int status; #ifdef WITH_DEBUG_TSG - fprintf(stderr, "Sending PDU (length: %d)\n", length); + DEBUG_WARN( "Sending PDU (length: %d)\n", length); rpc_pdu_header_print((rpcconn_hdr_t*) data); winpr_HexDump(data, length); - fprintf(stderr, "\n"); + DEBUG_WARN( "\n"); #endif status = tls_write_all(rpc->TlsIn, data, length); @@ -374,13 +374,13 @@ int rpc_write(rdpRpc* rpc, BYTE* data, int length, UINT16 opnum) if (!ntlm || !ntlm->table) { - fprintf(stderr, "%s: invalid ntlm context\n", __FUNCTION__); + DEBUG_WARN( "%s: invalid ntlm context\n", __FUNCTION__); return -1; } if (ntlm->table->QueryContextAttributes(&ntlm->context, SECPKG_ATTR_SIZES, &ntlm->ContextSizes) != SEC_E_OK) { - fprintf(stderr, "%s: QueryContextAttributes SECPKG_ATTR_SIZES failure\n", __FUNCTION__); + DEBUG_WARN( "%s: QueryContextAttributes SECPKG_ATTR_SIZES failure\n", __FUNCTION__); return -1; } @@ -456,7 +456,7 @@ int rpc_write(rdpRpc* rpc, BYTE* data, int length, UINT16 opnum) encrypt_status = ntlm->table->EncryptMessage(&ntlm->context, 0, &Message, rpc->SendSeqNum++); if (encrypt_status != SEC_E_OK) { - fprintf(stderr, "EncryptMessage status: 0x%08X\n", encrypt_status); + DEBUG_WARN( "EncryptMessage status: 0x%08X\n", encrypt_status); free(request_pdu); return -1; } @@ -486,7 +486,7 @@ BOOL rpc_connect(rdpRpc* rpc) if (!rts_connect(rpc)) { - fprintf(stderr, "rts_connect error!\n"); + DEBUG_WARN( "rts_connect error!\n"); return FALSE; } @@ -494,7 +494,7 @@ BOOL rpc_connect(rdpRpc* rpc) if (rpc_secure_bind(rpc) != 0) { - fprintf(stderr, "rpc_secure_bind error!\n"); + DEBUG_WARN( "rpc_secure_bind error!\n"); return FALSE; } diff --git a/libfreerdp/core/gateway/rpc_bind.c b/libfreerdp/core/gateway/rpc_bind.c index ceae95159..b7674ee02 100644 --- a/libfreerdp/core/gateway/rpc_bind.c +++ b/libfreerdp/core/gateway/rpc_bind.c @@ -391,7 +391,7 @@ int rpc_secure_bind(rdpRpc* rpc) if (status <= 0) { - fprintf(stderr, "rpc_secure_bind: error sending bind pdu!\n"); + DEBUG_WARN( "rpc_secure_bind: error sending bind pdu!\n"); return -1; } @@ -403,13 +403,13 @@ int rpc_secure_bind(rdpRpc* rpc) if (!pdu) { - fprintf(stderr, "rpc_secure_bind: error receiving bind ack pdu!\n"); + DEBUG_WARN( "rpc_secure_bind: error receiving bind ack pdu!\n"); return -1; } if (rpc_recv_bind_ack_pdu(rpc, Stream_Buffer(pdu->s), Stream_Length(pdu->s)) <= 0) { - fprintf(stderr, "rpc_secure_bind: error receiving bind ack pdu!\n"); + DEBUG_WARN( "rpc_secure_bind: error receiving bind ack pdu!\n"); return -1; } @@ -417,7 +417,7 @@ int rpc_secure_bind(rdpRpc* rpc) if (rpc_send_rpc_auth_3_pdu(rpc) <= 0) { - fprintf(stderr, "rpc_secure_bind: error sending rpc_auth_3 pdu!\n"); + DEBUG_WARN( "rpc_secure_bind: error sending rpc_auth_3 pdu!\n"); return -1; } @@ -425,7 +425,7 @@ int rpc_secure_bind(rdpRpc* rpc) } else { - fprintf(stderr, "rpc_secure_bind: invalid state: %d\n", rpc->State); + DEBUG_WARN( "rpc_secure_bind: invalid state: %d\n", rpc->State); return -1; } } diff --git a/libfreerdp/core/gateway/rpc_client.c b/libfreerdp/core/gateway/rpc_client.c index c3613f6be..d04403d5d 100644 --- a/libfreerdp/core/gateway/rpc_client.c +++ b/libfreerdp/core/gateway/rpc_client.c @@ -134,10 +134,10 @@ int rpc_client_on_fragment_received_event(rdpRpc* rpc) case PTYPE_RTS: if (rpc->VirtualConnection->State < VIRTUAL_CONNECTION_STATE_OPENED) { - fprintf(stderr, "%s: warning: unhandled RTS PDU\n", __FUNCTION__); + DEBUG_WARN( "%s: warning: unhandled RTS PDU\n", __FUNCTION__); return 0; } - fprintf(stderr, "%s: Receiving Out-of-Sequence RTS PDU\n", __FUNCTION__); + DEBUG_WARN( "%s: Receiving Out-of-Sequence RTS PDU\n", __FUNCTION__); rts_recv_out_of_sequence_pdu(rpc, buffer, header->common.frag_length); rpc_client_fragment_pool_return(rpc, fragment); return 0; @@ -149,7 +149,7 @@ int rpc_client_on_fragment_received_event(rdpRpc* rpc) case PTYPE_RESPONSE: break; default: - fprintf(stderr, "%s: unexpected RPC PDU type %d\n", __FUNCTION__, header->common.ptype); + DEBUG_WARN( "%s: unexpected RPC PDU type %d\n", __FUNCTION__, header->common.ptype); Queue_Enqueue(rpc->client->ReceiveQueue, NULL); return -1; } @@ -159,15 +159,15 @@ int rpc_client_on_fragment_received_event(rdpRpc* rpc) if (!rpc_get_stub_data_info(rpc, buffer, &StubOffset, &StubLength)) { - fprintf(stderr, "%s: expected stub\n", __FUNCTION__); + DEBUG_WARN( "%s: expected stub\n", __FUNCTION__); Queue_Enqueue(rpc->client->ReceiveQueue, NULL); return -1; } if (StubLength == 4) { - //fprintf(stderr, "Ignoring TsProxySendToServer Response\n"); - //printf("Got stub length 4 with flags %d and callid %d\n", header->common.pfc_flags, header->common.call_id); + //DEBUG_WARN( "Ignoring TsProxySendToServer Response\n"); + //DEBUG_MSG("Got stub length 4 with flags %d and callid %d\n", header->common.pfc_flags, header->common.call_id); /* received a disconnect request from the server? */ if ((header->common.call_id == rpc->PipeCallId) && (header->common.pfc_flags & PFC_LAST_FRAG)) @@ -195,7 +195,7 @@ int rpc_client_on_fragment_received_event(rdpRpc* rpc) if (rpc->StubCallId != header->common.call_id) { - fprintf(stderr, "%s: invalid call_id: actual: %d, expected: %d, frag_count: %d\n", __FUNCTION__, + DEBUG_WARN( "%s: invalid call_id: actual: %d, expected: %d, frag_count: %d\n", __FUNCTION__, rpc->StubCallId, header->common.call_id, rpc->StubFragCount); } @@ -206,7 +206,7 @@ int rpc_client_on_fragment_received_event(rdpRpc* rpc) if (rpc->VirtualConnection->DefaultOutChannel->ReceiverAvailableWindow < (rpc->ReceiveWindow / 2)) { - //fprintf(stderr, "Sending Flow Control Ack PDU\n"); + //DEBUG_WARN( "Sending Flow Control Ack PDU\n"); rts_send_flow_control_ack_pdu(rpc); } @@ -256,7 +256,7 @@ int rpc_client_on_read_event(rdpRpc* rpc) if (status < 0) { - fprintf(stderr, "rpc_client_frag_read: error reading header\n"); + DEBUG_WARN( "rpc_client_frag_read: error reading header\n"); return -1; } @@ -274,7 +274,7 @@ int rpc_client_on_read_event(rdpRpc* rpc) if (header->frag_length > rpc->max_recv_frag) { - fprintf(stderr, "rpc_client_frag_read: invalid fragment size: %d (max: %d)\n", + DEBUG_WARN( "rpc_client_frag_read: invalid fragment size: %d (max: %d)\n", header->frag_length, rpc->max_recv_frag); winpr_HexDump(Stream_Buffer(rpc->client->RecvFrag), Stream_GetPosition(rpc->client->RecvFrag)); return -1; @@ -287,7 +287,7 @@ int rpc_client_on_read_event(rdpRpc* rpc) if (status < 0) { - fprintf(stderr, "%s: error reading fragment body\n", __FUNCTION__); + DEBUG_WARN( "%s: error reading fragment body\n", __FUNCTION__); return -1; } @@ -390,7 +390,7 @@ int rpc_send_enqueue_pdu(rdpRpc* rpc, BYTE* buffer, UINT32 length) status = WaitForSingleObject(rpc->client->PduSentEvent, SYNCHRONOUS_TIMEOUT); if (status == WAIT_TIMEOUT) { - fprintf(stderr, "%s: timed out waiting for pdu sent event %p\n", __FUNCTION__, rpc->client->PduSentEvent); + DEBUG_WARN( "%s: timed out waiting for pdu sent event %p\n", __FUNCTION__, rpc->client->PduSentEvent); return -1; } @@ -462,7 +462,7 @@ RPC_PDU* rpc_recv_dequeue_pdu(rdpRpc* rpc) result = WaitForSingleObject(Queue_Event(rpc->client->ReceiveQueue), dwMilliseconds); if (result == WAIT_TIMEOUT) { - fprintf(stderr, "%s: timed out waiting for receive event\n", __FUNCTION__); + DEBUG_WARN( "%s: timed out waiting for receive event\n", __FUNCTION__); return NULL; } @@ -474,13 +474,13 @@ RPC_PDU* rpc_recv_dequeue_pdu(rdpRpc* rpc) #ifdef WITH_DEBUG_TSG if (pdu) { - fprintf(stderr, "Receiving PDU (length: %d, CallId: %d)\n", pdu->s->length, pdu->CallId); + DEBUG_WARN( "Receiving PDU (length: %d, CallId: %d)\n", pdu->s->length, pdu->CallId); winpr_HexDump(Stream_Buffer(pdu->s), Stream_Length(pdu->s)); - fprintf(stderr, "\n"); + DEBUG_WARN( "\n"); } else { - fprintf(stderr, "Receiving a NULL PDU\n"); + DEBUG_WARN( "Receiving a NULL PDU\n"); } #endif @@ -527,7 +527,7 @@ static void* rpc_client_thread(void* arg) */ if (rpc_client_on_read_event(rpc) < 0) { - fprintf(stderr, "%s: an error occured when treating first packet\n", __FUNCTION__); + DEBUG_WARN( "%s: an error occured when treating first packet\n", __FUNCTION__); goto out; } diff --git a/libfreerdp/core/gateway/rpc_fault.c b/libfreerdp/core/gateway/rpc_fault.c index 925efc6e8..a1cf9a44c 100644 --- a/libfreerdp/core/gateway/rpc_fault.c +++ b/libfreerdp/core/gateway/rpc_fault.c @@ -315,7 +315,7 @@ int rpc_recv_fault_pdu(rpcconn_hdr_t* header) int index; UINT32 code; - fprintf(stderr, "RPC Fault PDU:\n"); + DEBUG_WARN( "RPC Fault PDU:\n"); code = rpc_map_status_code_to_win32_error_code(header->fault.status); @@ -323,7 +323,7 @@ int rpc_recv_fault_pdu(rpcconn_hdr_t* header) { if (RPC_FAULT_CODES[index].code == code) { - fprintf(stderr, "status: %s (0x%08X)\n", RPC_FAULT_CODES[index].name, code); + DEBUG_WARN( "status: %s (0x%08X)\n", RPC_FAULT_CODES[index].name, code); return 0; } } @@ -332,12 +332,12 @@ int rpc_recv_fault_pdu(rpcconn_hdr_t* header) { if (RPC_TSG_FAULT_CODES[index].code == code) { - fprintf(stderr, "status: %s (0x%08X)\n", RPC_TSG_FAULT_CODES[index].name, code); + DEBUG_WARN( "status: %s (0x%08X)\n", RPC_TSG_FAULT_CODES[index].name, code); return 0; } } - fprintf(stderr, "status: %s (0x%08X)\n", "UNKNOWN", code); + DEBUG_WARN( "status: %s (0x%08X)\n", "UNKNOWN", code); return 0; } diff --git a/libfreerdp/core/gateway/rts.c b/libfreerdp/core/gateway/rts.c index d57a4240d..29105558c 100644 --- a/libfreerdp/core/gateway/rts.c +++ b/libfreerdp/core/gateway/rts.c @@ -93,25 +93,25 @@ BOOL rts_connect(rdpRpc* rpc) if (!rpc_ntlm_http_out_connect(rpc)) { - fprintf(stderr, "%s: rpc_out_connect_http error!\n", __FUNCTION__); + DEBUG_WARN( "%s: rpc_out_connect_http error!\n", __FUNCTION__); return FALSE; } if (rts_send_CONN_A1_pdu(rpc) != 0) { - fprintf(stderr, "%s: rpc_send_CONN_A1_pdu error!\n", __FUNCTION__); + DEBUG_WARN( "%s: rpc_send_CONN_A1_pdu error!\n", __FUNCTION__); return FALSE; } if (!rpc_ntlm_http_in_connect(rpc)) { - fprintf(stderr, "%s: rpc_in_connect_http error!\n", __FUNCTION__); + DEBUG_WARN( "%s: rpc_in_connect_http error!\n", __FUNCTION__); return FALSE; } if (rts_send_CONN_B1_pdu(rpc) < 0) { - fprintf(stderr, "%s: rpc_send_CONN_B1_pdu error!\n", __FUNCTION__); + DEBUG_WARN( "%s: rpc_send_CONN_B1_pdu error!\n", __FUNCTION__); return FALSE; } @@ -149,13 +149,13 @@ BOOL rts_connect(rdpRpc* rpc) http_response = http_response_recv(rpc->TlsOut); if (!http_response) { - fprintf(stderr, "%s: unable to retrieve OUT Channel Response!\n", __FUNCTION__); + DEBUG_WARN( "%s: unable to retrieve OUT Channel Response!\n", __FUNCTION__); return FALSE; } if (http_response->StatusCode != HTTP_STATUS_OK) { - fprintf(stderr, "%s: error! Status Code: %d\n", __FUNCTION__, http_response->StatusCode); + DEBUG_WARN( "%s: error! Status Code: %d\n", __FUNCTION__, http_response->StatusCode); http_response_print(http_response); http_response_free(http_response); @@ -215,7 +215,7 @@ BOOL rts_connect(rdpRpc* rpc) if (!rts_match_pdu_signature(rpc, &RTS_PDU_CONN_A3_SIGNATURE, rts)) { - fprintf(stderr, "%s: unexpected RTS PDU: Expected CONN/A3\n", __FUNCTION__); + DEBUG_WARN( "%s: unexpected RTS PDU: Expected CONN/A3\n", __FUNCTION__); return FALSE; } @@ -255,7 +255,7 @@ BOOL rts_connect(rdpRpc* rpc) if (!rts_match_pdu_signature(rpc, &RTS_PDU_CONN_C2_SIGNATURE, rts)) { - fprintf(stderr, "%s: unexpected RTS PDU: Expected CONN/C2\n", __FUNCTION__); + DEBUG_WARN( "%s: unexpected RTS PDU: Expected CONN/C2\n", __FUNCTION__); return FALSE; } @@ -880,9 +880,9 @@ int rts_recv_flow_control_ack_pdu(rdpRpc* rpc, BYTE* buffer, UINT32 length) &BytesReceived, &AvailableWindow, (BYTE*) &ChannelCookie) + 4; #if 0 - fprintf(stderr, "BytesReceived: %d AvailableWindow: %d\n", + DEBUG_WARN( "BytesReceived: %d AvailableWindow: %d\n", BytesReceived, AvailableWindow); - fprintf(stderr, "ChannelCookie: " RPC_UUID_FORMAT_STRING "\n", RPC_UUID_FORMAT_ARGUMENTS(ChannelCookie)); + DEBUG_WARN( "ChannelCookie: " RPC_UUID_FORMAT_STRING "\n", RPC_UUID_FORMAT_ARGUMENTS(ChannelCookie)); #endif rpc->VirtualConnection->DefaultInChannel->SenderAvailableWindow = @@ -921,9 +921,9 @@ int rts_recv_flow_control_ack_with_destination_pdu(rdpRpc* rpc, BYTE* buffer, UI &BytesReceived, &AvailableWindow, (BYTE*) &ChannelCookie) + 4; #if 0 - fprintf(stderr, "Destination: %d BytesReceived: %d AvailableWindow: %d\n", + DEBUG_WARN( "Destination: %d BytesReceived: %d AvailableWindow: %d\n", Destination, BytesReceived, AvailableWindow); - fprintf(stderr, "ChannelCookie: " RPC_UUID_FORMAT_STRING "\n", RPC_UUID_FORMAT_ARGUMENTS(ChannelCookie)); + DEBUG_WARN( "ChannelCookie: " RPC_UUID_FORMAT_STRING "\n", RPC_UUID_FORMAT_ARGUMENTS(ChannelCookie)); #endif rpc->VirtualConnection->DefaultInChannel->SenderAvailableWindow = @@ -1027,7 +1027,7 @@ int rts_command_length(rdpRpc* rpc, UINT32 CommandType, BYTE* buffer, UINT32 len break; default: - fprintf(stderr, "Error: Unknown RTS Command Type: 0x%x\n", CommandType); + DEBUG_WARN( "Error: Unknown RTS Command Type: 0x%x\n", CommandType); return -1; break; } @@ -1055,7 +1055,7 @@ int rts_recv_out_of_sequence_pdu(rdpRpc* rpc, BYTE* buffer, UINT32 length) case RTS_PDU_PING: return rts_send_ping_pdu(rpc); default: - fprintf(stderr, "%s: unimplemented signature id: 0x%08X\n", __FUNCTION__, SignatureId); + DEBUG_WARN( "%s: unimplemented signature id: 0x%08X\n", __FUNCTION__, SignatureId); rts_print_pdu_signature(rpc, &signature); break; } diff --git a/libfreerdp/core/gateway/rts_signature.c b/libfreerdp/core/gateway/rts_signature.c index 47242ca63..e52e09b1a 100644 --- a/libfreerdp/core/gateway/rts_signature.c +++ b/libfreerdp/core/gateway/rts_signature.c @@ -318,13 +318,13 @@ int rts_print_pdu_signature(rdpRpc* rpc, RtsPduSignature* signature) UINT32 SignatureId; RTS_PDU_SIGNATURE_ENTRY* entry; - fprintf(stderr, "RTS PDU Signature: Flags: 0x%04X NumberOfCommands: %d\n", + DEBUG_WARN( "RTS PDU Signature: Flags: 0x%04X NumberOfCommands: %d\n", signature->Flags, signature->NumberOfCommands); SignatureId = rts_identify_pdu_signature(rpc, signature, &entry); if (SignatureId) - fprintf(stderr, "Identified %s RTS PDU\n", entry->PduName); + DEBUG_WARN( "Identified %s RTS PDU\n", entry->PduName); return 0; } diff --git a/libfreerdp/core/gateway/tsg.c b/libfreerdp/core/gateway/tsg.c index 5491fe8af..accef1ff1 100644 --- a/libfreerdp/core/gateway/tsg.c +++ b/libfreerdp/core/gateway/tsg.c @@ -131,7 +131,7 @@ DWORD TsProxySendToServer(handle_t IDL_handle, byte pRpcMessage[], UINT32 count, if (status <= 0) { - fprintf(stderr, "rpc_write failed!\n"); + DEBUG_WARN( "rpc_write failed!\n"); return -1; } @@ -303,7 +303,7 @@ BOOL TsProxyCreateTunnelReadResponse(rdpTsg* tsg, RPC_PDU* pdu) if (versionCaps->tsgHeader.ComponentId != TS_GATEWAY_TRANSPORT) { - fprintf(stderr, "Unexpected ComponentId: 0x%04X, Expected TS_GATEWAY_TRANSPORT\n", + DEBUG_WARN( "Unexpected ComponentId: 0x%04X, Expected TS_GATEWAY_TRANSPORT\n", versionCaps->tsgHeader.ComponentId); free(packetCapsResponse); free(versionCaps); @@ -334,7 +334,7 @@ BOOL TsProxyCreateTunnelReadResponse(rdpTsg* tsg, RPC_PDU* pdu) if ((SwitchValue != TSG_CAPABILITY_TYPE_NAP) || (tsgCaps->capabilityType != TSG_CAPABILITY_TYPE_NAP)) { - fprintf(stderr, "Unexpected CapabilityType: 0x%08X, Expected TSG_CAPABILITY_TYPE_NAP\n", + DEBUG_WARN( "Unexpected CapabilityType: 0x%08X, Expected TSG_CAPABILITY_TYPE_NAP\n", tsgCaps->capabilityType); free(tsgCaps); free(versionCaps); @@ -365,7 +365,7 @@ BOOL TsProxyCreateTunnelReadResponse(rdpTsg* tsg, RPC_PDU* pdu) if (MsgBytes > TSG_MESSAGING_MAX_MESSAGE_LENGTH) { - fprintf(stderr, "Out of Spec Message Length %d", MsgBytes); + DEBUG_WARN( "Out of Spec Message Length %d", MsgBytes); free(tsgCaps); free(versionCaps); free(packetCapsResponse); @@ -382,7 +382,7 @@ BOOL TsProxyCreateTunnelReadResponse(rdpTsg* tsg, RPC_PDU* pdu) break; default: - fprintf(stderr, "Unexpected Message Type: 0x%X\n", (int) MessageSwitchValue); + DEBUG_WARN( "Unexpected Message Type: 0x%X\n", (int) MessageSwitchValue); free(tsgCaps); free(versionCaps); free(packetCapsResponse); @@ -401,9 +401,9 @@ BOOL TsProxyCreateTunnelReadResponse(rdpTsg* tsg, RPC_PDU* pdu) // HRESULT ReturnValue #ifdef WITH_DEBUG_TSG - fprintf(stderr, "TSG TunnelContext:\n"); + DEBUG_WARN( "TSG TunnelContext:\n"); winpr_HexDump((void*) &tsg->TunnelContext, 20); - fprintf(stderr, "\n"); + DEBUG_WARN( "\n"); #endif free(tsgCaps); @@ -461,7 +461,7 @@ BOOL TsProxyCreateTunnelReadResponse(rdpTsg* tsg, RPC_PDU* pdu) if (versionCaps->tsgHeader.ComponentId != TS_GATEWAY_TRANSPORT) { - fprintf(stderr, "Unexpected ComponentId: 0x%04X, Expected TS_GATEWAY_TRANSPORT\n", + DEBUG_WARN( "Unexpected ComponentId: 0x%04X, Expected TS_GATEWAY_TRANSPORT\n", versionCaps->tsgHeader.ComponentId); free(versionCaps); free(packetQuarEncResponse); @@ -491,9 +491,9 @@ BOOL TsProxyCreateTunnelReadResponse(rdpTsg* tsg, RPC_PDU* pdu) offset += 20; #ifdef WITH_DEBUG_TSG - fprintf(stderr, "TSG TunnelContext:\n"); + DEBUG_WARN( "TSG TunnelContext:\n"); winpr_HexDump((void*) &tsg->TunnelContext, 20); - fprintf(stderr, "\n"); + DEBUG_WARN( "\n"); #endif free(versionCaps); @@ -501,7 +501,7 @@ BOOL TsProxyCreateTunnelReadResponse(rdpTsg* tsg, RPC_PDU* pdu) } else { - fprintf(stderr, "Unexpected PacketId: 0x%08X, Expected TSG_PACKET_TYPE_CAPS_RESPONSE " + DEBUG_WARN( "Unexpected PacketId: 0x%08X, Expected TSG_PACKET_TYPE_CAPS_RESPONSE " "or TSG_PACKET_TYPE_QUARENC_RESPONSE\n", packet->packetId); free(packet); return FALSE; @@ -531,7 +531,7 @@ BOOL TsProxyCreateTunnel(rdpTsg* tsg, PTSG_PACKET tsgPacket, PTSG_PACKET* tsgPac if (!TsProxyCreateTunnelWriteRequest(tsg)) { - fprintf(stderr, "TsProxyCreateTunnel: error writing request\n"); + DEBUG_WARN( "TsProxyCreateTunnel: error writing request\n"); return FALSE; } @@ -633,15 +633,15 @@ BOOL TsProxyAuthorizeTunnelReadResponse(rdpTsg* tsg, RPC_PDU* pdu) if (packet->packetId == E_PROXY_NAP_ACCESSDENIED) { - fprintf(stderr, "status: E_PROXY_NAP_ACCESSDENIED (0x%08X)\n", E_PROXY_NAP_ACCESSDENIED); - fprintf(stderr, "Ensure that the Gateway Connection Authorization Policy is correct\n"); + DEBUG_WARN( "status: E_PROXY_NAP_ACCESSDENIED (0x%08X)\n", E_PROXY_NAP_ACCESSDENIED); + DEBUG_WARN( "Ensure that the Gateway Connection Authorization Policy is correct\n"); free(packet); return FALSE; } if ((packet->packetId != TSG_PACKET_TYPE_RESPONSE) || (SwitchValue != TSG_PACKET_TYPE_RESPONSE)) { - fprintf(stderr, "Unexpected PacketId: 0x%08X, Expected TSG_PACKET_TYPE_RESPONSE\n", + DEBUG_WARN( "Unexpected PacketId: 0x%08X, Expected TSG_PACKET_TYPE_RESPONSE\n", packet->packetId); free(packet); return FALSE; @@ -656,7 +656,7 @@ BOOL TsProxyAuthorizeTunnelReadResponse(rdpTsg* tsg, RPC_PDU* pdu) if (packetResponse->flags != TSG_PACKET_TYPE_QUARREQUEST) { - fprintf(stderr, "Unexpected Packet Response Flags: 0x%08X, Expected TSG_PACKET_TYPE_QUARREQUEST\n", + DEBUG_WARN( "Unexpected Packet Response Flags: 0x%08X, Expected TSG_PACKET_TYPE_QUARREQUEST\n", packetResponse->flags); free(packet); free(packetResponse); @@ -682,7 +682,7 @@ BOOL TsProxyAuthorizeTunnelReadResponse(rdpTsg* tsg, RPC_PDU* pdu) if (SizeValue != packetResponse->responseDataLen) { - fprintf(stderr, "Unexpected size value: %d, expected: %d\n", + DEBUG_WARN( "Unexpected size value: %d, expected: %d\n", SizeValue, packetResponse->responseDataLen); free(packetResponse); free(packet); @@ -716,7 +716,7 @@ BOOL TsProxyAuthorizeTunnel(rdpTsg* tsg, PTUNNEL_CONTEXT_HANDLE_NOSERIALIZE tunn if (!TsProxyAuthorizeTunnelWriteRequest(tsg, tunnelContext)) { - fprintf(stderr, "TsProxyAuthorizeTunnel: error writing request\n"); + DEBUG_WARN( "TsProxyAuthorizeTunnel: error writing request\n"); return FALSE; } @@ -797,7 +797,7 @@ BOOL TsProxyMakeTunnelCallReadResponse(rdpTsg* tsg, RPC_PDU* pdu) if ((packet->packetId != TSG_PACKET_TYPE_MESSAGE_PACKET) || (SwitchValue != TSG_PACKET_TYPE_MESSAGE_PACKET)) { - fprintf(stderr, "Unexpected PacketId: 0x%08X, Expected TSG_PACKET_TYPE_MESSAGE_PACKET\n", + DEBUG_WARN( "Unexpected PacketId: 0x%08X, Expected TSG_PACKET_TYPE_MESSAGE_PACKET\n", packet->packetId); free(packet); return FALSE; @@ -832,7 +832,7 @@ BOOL TsProxyMakeTunnelCallReadResponse(rdpTsg* tsg, RPC_PDU* pdu) ActualCount = *((UINT32*) &buffer[offset + 56]); /* ActualCount */ ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) &buffer[offset + 60], ActualCount, &messageText, 0, NULL, NULL); - fprintf(stderr, "Consent Message: %s\n", messageText); + DEBUG_WARN( "Consent Message: %s\n", messageText); free(messageText); break; @@ -853,7 +853,7 @@ BOOL TsProxyMakeTunnelCallReadResponse(rdpTsg* tsg, RPC_PDU* pdu) ActualCount = *((UINT32*) &buffer[offset + 56]); /* ActualCount */ ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) &buffer[offset + 60], ActualCount, &messageText, 0, NULL, NULL); - fprintf(stderr, "Service Message: %s\n", messageText); + DEBUG_WARN( "Service Message: %s\n", messageText); free(messageText); break; @@ -867,7 +867,7 @@ BOOL TsProxyMakeTunnelCallReadResponse(rdpTsg* tsg, RPC_PDU* pdu) break; default: - fprintf(stderr, "TsProxyMakeTunnelCallReadResponse: unexpected message type: %d\n", + DEBUG_WARN( "TsProxyMakeTunnelCallReadResponse: unexpected message type: %d\n", SwitchValue); rc = FALSE; break; @@ -905,7 +905,7 @@ BOOL TsProxyMakeTunnelCall(rdpTsg* tsg, PTUNNEL_CONTEXT_HANDLE_NOSERIALIZE tunne if (!TsProxyMakeTunnelCallWriteRequest(tsg, tunnelContext, procId)) { - fprintf(stderr, "TsProxyMakeTunnelCall: error writing request\n"); + DEBUG_WARN( "TsProxyMakeTunnelCall: error writing request\n"); return FALSE; } @@ -924,9 +924,9 @@ BOOL TsProxyCreateChannelWriteRequest(rdpTsg* tsg, PTUNNEL_CONTEXT_HANDLE_NOSERI count = _wcslen(tsg->Hostname) + 1; #ifdef WITH_DEBUG_TSG - fprintf(stderr, "ResourceName:\n"); + DEBUG_WARN( "ResourceName:\n"); winpr_HexDump((BYTE*) tsg->Hostname, (count - 1) * 2); - fprintf(stderr, "\n"); + DEBUG_WARN( "\n"); #endif length = 60 + (count * 2); @@ -992,9 +992,9 @@ BOOL TsProxyCreateChannelReadResponse(rdpTsg* tsg, RPC_PDU* pdu) CopyMemory(tsg->ChannelContext.ContextUuid, &buffer[offset + 4], 16); /* ContextUuid (16 bytes) */ #ifdef WITH_DEBUG_TSG - fprintf(stderr, "ChannelContext:\n"); + DEBUG_WARN( "ChannelContext:\n"); winpr_HexDump((void*) &tsg->ChannelContext, 20); - fprintf(stderr, "\n"); + DEBUG_WARN( "\n"); #endif rpc_client_receive_pool_return(rpc, pdu); @@ -1020,7 +1020,7 @@ BOOL TsProxyCreateChannel(rdpTsg* tsg, PTUNNEL_CONTEXT_HANDLE_NOSERIALIZE tunnel if (!TsProxyCreateChannelWriteRequest(tsg, tunnelContext)) { - fprintf(stderr, "TsProxyCreateChannel: error writing request\n"); + DEBUG_WARN( "TsProxyCreateChannel: error writing request\n"); return FALSE; } @@ -1090,13 +1090,13 @@ HRESULT TsProxyCloseChannel(rdpTsg* tsg, PCHANNEL_CONTEXT_HANDLE_NOSERIALIZE* co if (!TsProxyCloseChannelWriteRequest(tsg, context)) { - fprintf(stderr, "TsProxyCloseChannel: error writing request\n"); + DEBUG_WARN( "TsProxyCloseChannel: error writing request\n"); return FALSE; } if (!TsProxyCloseChannelReadResponse(tsg, pdu)) { - fprintf(stderr, "TsProxyCloseChannel: error reading response\n"); + DEBUG_WARN( "TsProxyCloseChannel: error reading response\n"); return FALSE; } @@ -1166,13 +1166,13 @@ HRESULT TsProxyCloseTunnel(rdpTsg* tsg, PTUNNEL_CONTEXT_HANDLE_SERIALIZE* contex if (!TsProxyCloseTunnelWriteRequest(tsg, context)) { - fprintf(stderr, "TsProxyCloseTunnel: error writing request\n"); + DEBUG_WARN( "TsProxyCloseTunnel: error writing request\n"); return FALSE; } if (!TsProxyCloseTunnelReadResponse(tsg, pdu)) { - fprintf(stderr, "TsProxyCloseTunnel: error reading response\n"); + DEBUG_WARN( "TsProxyCloseTunnel: error reading response\n"); return FALSE; } @@ -1227,7 +1227,7 @@ BOOL TsProxySetupReceivePipe(handle_t IDL_handle, BYTE* pRpcMessage) if (!TsProxySetupReceivePipeWriteRequest(tsg)) { - fprintf(stderr, "TsProxySetupReceivePipe: error writing request\n"); + DEBUG_WARN( "TsProxySetupReceivePipe: error writing request\n"); return FALSE; } @@ -1247,7 +1247,7 @@ BOOL tsg_connect(rdpTsg* tsg, const char* hostname, UINT16 port) if (!rpc_connect(rpc)) { - fprintf(stderr, "rpc_connect failed!\n"); + DEBUG_WARN( "rpc_connect failed!\n"); return FALSE; } @@ -1310,7 +1310,7 @@ BOOL tsg_connect(rdpTsg* tsg, const char* hostname, UINT16 port) if (!TsProxyCreateTunnelReadResponse(tsg, pdu)) { - fprintf(stderr, "TsProxyCreateTunnel: error reading response\n"); + DEBUG_WARN( "TsProxyCreateTunnel: error reading response\n"); return FALSE; } @@ -1356,7 +1356,7 @@ BOOL tsg_connect(rdpTsg* tsg, const char* hostname, UINT16 port) if (!TsProxyAuthorizeTunnelReadResponse(tsg, pdu)) { - fprintf(stderr, "TsProxyAuthorizeTunnel: error reading response\n"); + DEBUG_WARN( "TsProxyAuthorizeTunnel: error reading response\n"); return FALSE; } @@ -1394,7 +1394,7 @@ BOOL tsg_connect(rdpTsg* tsg, const char* hostname, UINT16 port) pdu = rpc_recv_dequeue_pdu(rpc); if (!pdu) { - fprintf(stderr, "TsProxyCreateChannel: error reading response\n"); + DEBUG_WARN( "TsProxyCreateChannel: error reading response\n"); return FALSE; } @@ -1404,7 +1404,7 @@ BOOL tsg_connect(rdpTsg* tsg, const char* hostname, UINT16 port) { if (!TsProxyMakeTunnelCallReadResponse(tsg, pdu)) { - fprintf(stderr, "TsProxyMakeTunnelCall: error reading response\n"); + DEBUG_WARN( "TsProxyMakeTunnelCall: error reading response\n"); return FALSE; } @@ -1413,7 +1413,7 @@ BOOL tsg_connect(rdpTsg* tsg, const char* hostname, UINT16 port) if (!TsProxyCreateChannelReadResponse(tsg, pdu)) { - fprintf(stderr, "TsProxyCreateChannel: error reading response\n"); + DEBUG_WARN( "TsProxyCreateChannel: error reading response\n"); return FALSE; } @@ -1445,7 +1445,7 @@ BOOL tsg_connect(rdpTsg* tsg, const char* hostname, UINT16 port) if (!TsProxySetupReceivePipeReadResponse(tsg, pdu)) { - fprintf(stderr, "TsProxySetupReceivePipe: error reading response\n"); + DEBUG_WARN( "TsProxySetupReceivePipe: error reading response\n"); return FALSE; } #endif @@ -1453,7 +1453,7 @@ BOOL tsg_connect(rdpTsg* tsg, const char* hostname, UINT16 port) rpc->client->SynchronousSend = TRUE; rpc->client->SynchronousReceive = TRUE; - fprintf(stderr, "TS Gateway Connection Success\n"); + DEBUG_WARN( "TS Gateway Connection Success\n"); return TRUE; } @@ -1516,7 +1516,7 @@ int tsg_read(rdpTsg* tsg, BYTE* data, UINT32 length) if (rpc->transport->layer == TRANSPORT_LAYER_CLOSED) { - fprintf(stderr, "tsg_read error: connection lost\n"); + DEBUG_WARN( "tsg_read error: connection lost\n"); return -1; } @@ -1576,7 +1576,7 @@ int tsg_write(rdpTsg* tsg, BYTE* data, UINT32 length) if (tsg->rpc->transport->layer == TRANSPORT_LAYER_CLOSED) { - fprintf(stderr, "%s: error, connection lost\n", __FUNCTION__); + DEBUG_WARN( "%s: error, connection lost\n", __FUNCTION__); return -1; } diff --git a/libfreerdp/core/gcc.c b/libfreerdp/core/gcc.c index d9c6fe67a..ac75bc4ba 100644 --- a/libfreerdp/core/gcc.c +++ b/libfreerdp/core/gcc.c @@ -274,7 +274,7 @@ BOOL gcc_read_conference_create_response(wStream* s, rdpMcs* mcs) if (!gcc_read_server_data_blocks(s, mcs, length)) { - fprintf(stderr, "gcc_read_conference_create_response: gcc_read_server_data_blocks failed\n"); + DEBUG_WARN( "gcc_read_conference_create_response: gcc_read_server_data_blocks failed\n"); return FALSE; } @@ -374,7 +374,7 @@ BOOL gcc_read_client_data_blocks(wStream* s, rdpMcs* mcs, int length) break; default: - fprintf(stderr, "Unknown GCC client data block: 0x%04X\n", type); + DEBUG_WARN( "Unknown GCC client data block: 0x%04X\n", type); Stream_Seek(s, blockLength - 4); break; } @@ -383,7 +383,7 @@ BOOL gcc_read_client_data_blocks(wStream* s, rdpMcs* mcs, int length) if (endPos != (begPos + blockLength)) { - fprintf(stderr, "Error parsing GCC client data block 0x%04X: Actual Offset: %d Expected Offset: %d\n", + DEBUG_WARN( "Error parsing GCC client data block 0x%04X: Actual Offset: %d Expected Offset: %d\n", type, endPos, begPos + blockLength); } @@ -419,16 +419,16 @@ void gcc_write_client_data_blocks(wStream* s, rdpMcs* mcs) { if (settings->UseMultimon && !settings->SpanMonitors) { - fprintf(stderr, "WARNING: true multi monitor support was not advertised by server!\n"); + DEBUG_WARN( "WARNING: true multi monitor support was not advertised by server!\n"); if (settings->ForceMultimon) { - fprintf(stderr, "Sending multi monitor information anyway (may break connectivity!)\n"); + DEBUG_WARN( "Sending multi monitor information anyway (may break connectivity!)\n"); gcc_write_client_monitor_data(s, mcs); } else { - fprintf(stderr, "Use /multimon:force to force sending multi monitor information\n"); + DEBUG_WARN( "Use /multimon:force to force sending multi monitor information\n"); } } } @@ -447,7 +447,7 @@ BOOL gcc_read_server_data_blocks(wStream* s, rdpMcs* mcs, int length) if (!gcc_read_user_data_header(s, &type, &blockLength)) { - fprintf(stderr, "gcc_read_server_data_blocks: gcc_read_user_data_header failed\n"); + DEBUG_WARN( "gcc_read_server_data_blocks: gcc_read_user_data_header failed\n"); return FALSE; } @@ -456,7 +456,7 @@ BOOL gcc_read_server_data_blocks(wStream* s, rdpMcs* mcs, int length) case SC_CORE: if (!gcc_read_server_core_data(s, mcs)) { - fprintf(stderr, "gcc_read_server_data_blocks: gcc_read_server_core_data failed\n"); + DEBUG_WARN( "gcc_read_server_data_blocks: gcc_read_server_core_data failed\n"); return FALSE; } break; @@ -464,7 +464,7 @@ BOOL gcc_read_server_data_blocks(wStream* s, rdpMcs* mcs, int length) case SC_SECURITY: if (!gcc_read_server_security_data(s, mcs)) { - fprintf(stderr, "gcc_read_server_data_blocks: gcc_read_server_security_data failed\n"); + DEBUG_WARN( "gcc_read_server_data_blocks: gcc_read_server_security_data failed\n"); return FALSE; } break; @@ -472,7 +472,7 @@ BOOL gcc_read_server_data_blocks(wStream* s, rdpMcs* mcs, int length) case SC_NET: if (!gcc_read_server_network_data(s, mcs)) { - fprintf(stderr, "gcc_read_server_data_blocks: gcc_read_server_network_data failed\n"); + DEBUG_WARN( "gcc_read_server_data_blocks: gcc_read_server_network_data failed\n"); return FALSE; } break; @@ -480,7 +480,7 @@ BOOL gcc_read_server_data_blocks(wStream* s, rdpMcs* mcs, int length) case SC_MCS_MSGCHANNEL: if (!gcc_read_server_message_channel_data(s, mcs)) { - fprintf(stderr, "gcc_read_server_data_blocks: gcc_read_server_message_channel_data failed\n"); + DEBUG_WARN( "gcc_read_server_data_blocks: gcc_read_server_message_channel_data failed\n"); return FALSE; } break; @@ -488,13 +488,13 @@ BOOL gcc_read_server_data_blocks(wStream* s, rdpMcs* mcs, int length) case SC_MULTITRANSPORT: if (!gcc_read_server_multitransport_channel_data(s, mcs)) { - fprintf(stderr, "gcc_read_server_data_blocks: gcc_read_server_multitransport_channel_data failed\n"); + DEBUG_WARN( "gcc_read_server_data_blocks: gcc_read_server_multitransport_channel_data failed\n"); return FALSE; } break; default: - fprintf(stderr, "gcc_read_server_data_blocks: ignoring type=%hu\n", type); + DEBUG_WARN( "gcc_read_server_data_blocks: ignoring type=%hu\n", type); break; } offset += blockLength; @@ -1174,7 +1174,7 @@ void gcc_write_server_security_data(wStream* s, rdpMcs* mcs) md5 = crypto_md5_init(); if (!md5) { - fprintf(stderr, "%s: unable to allocate a md5\n", __FUNCTION__); + DEBUG_WARN( "%s: unable to allocate a md5\n", __FUNCTION__); return; } @@ -1269,7 +1269,7 @@ BOOL gcc_read_server_network_data(wStream* s, rdpMcs* mcs) if (channelCount != mcs->channelCount) { - fprintf(stderr, "requested %d channels, got %d instead\n", + DEBUG_WARN( "requested %d channels, got %d instead\n", mcs->channelCount, channelCount); /* we ensure that the response is not bigger than the request */ diff --git a/libfreerdp/core/graphics.c b/libfreerdp/core/graphics.c index 58de46834..7f991bb81 100644 --- a/libfreerdp/core/graphics.c +++ b/libfreerdp/core/graphics.c @@ -37,7 +37,8 @@ rdpBitmap* Bitmap_Alloc(rdpContext* context) if (bitmap) { - CopyMemory(bitmap, context->graphics->Bitmap_Prototype, sizeof(rdpBitmap)); + ZeroMemory(bitmap, graphics->Bitmap_Prototype->size); + CopyMemory(bitmap, graphics->Bitmap_Prototype, sizeof(rdpBitmap)); bitmap->data = NULL; } @@ -99,7 +100,8 @@ rdpPointer* Pointer_Alloc(rdpContext* context) if (pointer) { - CopyMemory(pointer, context->graphics->Pointer_Prototype, sizeof(rdpPointer)); + ZeroMemory(pointer, graphics->Pointer_Prototype->size); + CopyMemory(pointer, graphics->Pointer_Prototype, sizeof(rdpPointer)); } return pointer; @@ -165,7 +167,8 @@ rdpGlyph* Glyph_Alloc(rdpContext* context) if (glyph) { - CopyMemory(glyph, context->graphics->Glyph_Prototype, sizeof(rdpGlyph)); + ZeroMemory(glyph, graphics->Glyph_Prototype->size); + CopyMemory(glyph, graphics->Glyph_Prototype, sizeof(rdpGlyph)); } return glyph; diff --git a/libfreerdp/core/info.c b/libfreerdp/core/info.c index c5bc9173e..217b3ff21 100644 --- a/libfreerdp/core/info.c +++ b/libfreerdp/core/info.c @@ -67,7 +67,7 @@ BOOL rdp_read_server_auto_reconnect_cookie(wStream* s, rdpSettings* settings) char *base64; base64 = crypto_base64_encode((BYTE *) autoReconnectCookie, sizeof(ARC_SC_PRIVATE_PACKET)); - fprintf(stderr, "Reconnect-cookie: %s\n", base64); + DEBUG_WARN( "Reconnect-cookie: %s\n", base64); free(base64); } return TRUE; @@ -105,13 +105,31 @@ BOOL rdp_read_client_auto_reconnect_cookie(wStream* s, rdpSettings* settings) void rdp_write_client_auto_reconnect_cookie(wStream* s, rdpSettings* settings) { + CryptoHmac hmac; + BYTE nullRandom[32]; + BYTE cryptSecurityVerifier[16]; ARC_CS_PRIVATE_PACKET* autoReconnectCookie; autoReconnectCookie = settings->ClientAutoReconnectCookie; + /* SecurityVerifier = HMAC(AutoReconnectRandom, ClientRandom) */ + + hmac = crypto_hmac_new(); + ZeroMemory(nullRandom, sizeof(nullRandom)); + + crypto_hmac_md5_init(hmac, autoReconnectCookie->securityVerifier, 16); + + if (settings->ClientRandomLength > 0) + crypto_hmac_update(hmac, settings->ClientRandom, settings->ClientRandomLength); + else + crypto_hmac_update(hmac, nullRandom, sizeof(nullRandom)); + + crypto_hmac_final(hmac, cryptSecurityVerifier, 16); + crypto_hmac_free(hmac); + Stream_Write_UINT32(s, autoReconnectCookie->cbLen); /* cbLen (4 bytes) */ Stream_Write_UINT32(s, autoReconnectCookie->version); /* version (4 bytes) */ Stream_Write_UINT32(s, autoReconnectCookie->logonId); /* LogonId (4 bytes) */ - Stream_Write(s, autoReconnectCookie->securityVerifier, 16); /* SecurityVerifier */ + Stream_Write(s, cryptSecurityVerifier, 16); /* SecurityVerifier */ } /** @@ -239,7 +257,7 @@ void rdp_write_extended_info_packet(wStream* s, rdpSettings* settings) ARC_SC_PRIVATE_PACKET* serverCookie; ARC_CS_PRIVATE_PACKET* clientCookie; - printf("Sending auto reconnect\n"); + DEBUG_MSG("Sending auto reconnect\n"); serverCookie = settings->ServerAutoReconnectCookie; clientCookie = settings->ClientAutoReconnectCookie; @@ -250,7 +268,7 @@ void rdp_write_extended_info_packet(wStream* s, rdpSettings* settings) hmac = crypto_hmac_new(); if (!hmac) { - fprintf(stderr, "%s: unable to allocate hmac\n", __FUNCTION__); + DEBUG_WARN( "%s: unable to allocate hmac\n", __FUNCTION__); goto out_free; } @@ -485,8 +503,16 @@ void rdp_write_info_packet(wStream* s, rdpSettings* settings) } else { - /* This field MUST be filled with "*" */ - cbAlternateShell = ConvertToUnicode(CP_UTF8, 0, "*", -1, &alternateShellW, 0) * 2; + if (settings->RemoteAssistancePassStub) + { + /* This field MUST be filled with "*" */ + cbAlternateShell = ConvertToUnicode(CP_UTF8, 0, "*", -1, &alternateShellW, 0) * 2; + } + else + { + /* This field must contain the remote assistance password */ + cbAlternateShell = ConvertToUnicode(CP_UTF8, 0, settings->RemoteAssistancePassword, -1, &alternateShellW, 0) * 2; + } } if (!settings->RemoteAssistanceMode) @@ -566,7 +592,7 @@ BOOL rdp_recv_client_info(rdpRdp* rdp, wStream* s) { if (securityFlags & SEC_REDIRECTION_PKT) { - fprintf(stderr, "Error: SEC_REDIRECTION_PKT unsupported\n"); + DEBUG_WARN( "Error: SEC_REDIRECTION_PKT unsupported\n"); return FALSE; } @@ -574,7 +600,7 @@ BOOL rdp_recv_client_info(rdpRdp* rdp, wStream* s) { if (!rdp_decrypt(rdp, s, length - 4, securityFlags)) { - fprintf(stderr, "rdp_decrypt failed\n"); + DEBUG_WARN( "rdp_decrypt failed\n"); return FALSE; } } @@ -727,7 +753,7 @@ BOOL rdp_recv_save_session_info(rdpRdp* rdp, wStream* s) return FALSE; Stream_Read_UINT32(s, infoType); /* infoType (4 bytes) */ - //fprintf(stderr, "%s\n", INFO_TYPE_LOGON_STRINGS[infoType]); + //DEBUG_WARN( "%s\n", INFO_TYPE_LOGON_STRINGS[infoType]); switch (infoType) { diff --git a/libfreerdp/core/input.c b/libfreerdp/core/input.c index a929b0d96..904bce130 100644 --- a/libfreerdp/core/input.c +++ b/libfreerdp/core/input.c @@ -166,6 +166,27 @@ void input_send_focus_in_event(rdpInput* input, UINT16 toggleStates, UINT16 x, U input_send_mouse_event(input, PTR_FLAGS_MOVE, x, y); } +static void input_send_keyboard_pause_event(rdpInput* input) +{ + /* In ancient days, pause-down without control sent E1 1D 45 E1 9D C5, + * and pause-up sent nothing. However, reverse engineering mstsc shows + * it sending the following sequence: + */ + + /* Control down (0x1D) */ + input_send_keyboard_event(input, 0, + RDP_SCANCODE_CODE(RDP_SCANCODE_LCONTROL)); + /* Numlock down (0x45) */ + input_send_keyboard_event(input, 0, + RDP_SCANCODE_CODE(RDP_SCANCODE_NUMLOCK)); + /* Control up (0x1D) */ + input_send_keyboard_event(input, KBD_FLAGS_RELEASE, + RDP_SCANCODE_CODE(RDP_SCANCODE_LCONTROL)); + /* Numlock up (0x45) */ + input_send_keyboard_event(input, KBD_FLAGS_RELEASE, + RDP_SCANCODE_CODE(RDP_SCANCODE_NUMLOCK)); +} + void input_send_fastpath_synchronize_event(rdpInput* input, UINT32 flags) { wStream* s; @@ -250,6 +271,39 @@ void input_send_fastpath_focus_in_event(rdpInput* input, UINT16 toggleStates, UI fastpath_send_multiple_input_pdu(rdp->fastpath, s, 4); } +static void input_send_fastpath_keyboard_pause_event(rdpInput* input) +{ + /* In ancient days, pause-down without control sent E1 1D 45 E1 9D C5, + * and pause-up sent nothing. However, reverse engineering mstsc shows + * it sending the following sequence: + */ + wStream* s; + rdpRdp* rdp = input->context->rdp; + const BYTE keyDownEvent = FASTPATH_INPUT_EVENT_SCANCODE << 5; + const BYTE keyUpEvent = (FASTPATH_INPUT_EVENT_SCANCODE << 5) + | FASTPATH_INPUT_KBDFLAGS_RELEASE; + + s = fastpath_input_pdu_init_header(rdp->fastpath); + + /* Control down (0x1D) */ + Stream_Write_UINT8(s, keyDownEvent | FASTPATH_INPUT_KBDFLAGS_PREFIX_E1); + Stream_Write_UINT8(s, RDP_SCANCODE_CODE(RDP_SCANCODE_LCONTROL)); + + /* Numlock down (0x45) */ + Stream_Write_UINT8(s, keyDownEvent); + Stream_Write_UINT8(s, RDP_SCANCODE_CODE(RDP_SCANCODE_NUMLOCK)); + + /* Control up (0x1D) */ + Stream_Write_UINT8(s, keyUpEvent | FASTPATH_INPUT_KBDFLAGS_PREFIX_E1); + Stream_Write_UINT8(s, RDP_SCANCODE_CODE(RDP_SCANCODE_LCONTROL)); + + /* Numlock down (0x45) */ + Stream_Write_UINT8(s, keyUpEvent); + Stream_Write_UINT8(s, RDP_SCANCODE_CODE(RDP_SCANCODE_NUMLOCK)); + + fastpath_send_multiple_input_pdu(rdp->fastpath, s, 4); +} + static BOOL input_recv_sync_event(rdpInput* input, wStream* s) { UINT32 toggleFlags; @@ -380,7 +434,7 @@ static BOOL input_recv_event(rdpInput* input, wStream* s) break; default: - fprintf(stderr, "Unknown messageType %u\n", messageType); + DEBUG_WARN( "Unknown messageType %u\n", messageType); /* Each input event uses 6 bytes. */ Stream_Seek(s, 6); break; @@ -420,6 +474,7 @@ void input_register_client_callbacks(rdpInput* input) { input->SynchronizeEvent = input_send_fastpath_synchronize_event; input->KeyboardEvent = input_send_fastpath_keyboard_event; + input->KeyboardPauseEvent = input_send_fastpath_keyboard_pause_event; input->UnicodeKeyboardEvent = input_send_fastpath_unicode_keyboard_event; input->MouseEvent = input_send_fastpath_mouse_event; input->ExtendedMouseEvent = input_send_fastpath_extended_mouse_event; @@ -429,6 +484,7 @@ void input_register_client_callbacks(rdpInput* input) { input->SynchronizeEvent = input_send_synchronize_event; input->KeyboardEvent = input_send_keyboard_event; + input->KeyboardPauseEvent = input_send_keyboard_pause_event; input->UnicodeKeyboardEvent = input_send_unicode_keyboard_event; input->MouseEvent = input_send_mouse_event; input->ExtendedMouseEvent = input_send_extended_mouse_event; @@ -481,6 +537,11 @@ void freerdp_input_send_focus_in_event(rdpInput* input, UINT16 toggleStates, UIN IFCALL(input->FocusInEvent, input, toggleStates, x, y); } +void freerdp_input_send_keyboard_pause_event(rdpInput* input) +{ + IFCALL(input->KeyboardPauseEvent, input); +} + int input_process_events(rdpInput* input) { return input_message_queue_process_pending_messages(input); diff --git a/libfreerdp/core/license.c b/libfreerdp/core/license.c index 4d3a53a0f..d6f09a000 100644 --- a/libfreerdp/core/license.c +++ b/libfreerdp/core/license.c @@ -89,10 +89,10 @@ void license_print_product_info(LICENSE_PRODUCT_INFO* productInfo) ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) productInfo->pbProductId, productInfo->cbProductId / 2, &ProductId, 0, NULL, NULL); - fprintf(stderr, "ProductInfo:\n"); - fprintf(stderr, "\tdwVersion: 0x%08X\n", productInfo->dwVersion); - fprintf(stderr, "\tCompanyName: %s\n", CompanyName); - fprintf(stderr, "\tProductId: %s\n", ProductId); + DEBUG_WARN( "ProductInfo:\n"); + DEBUG_WARN( "\tdwVersion: 0x%08X\n", productInfo->dwVersion); + DEBUG_WARN( "\tCompanyName: %s\n", CompanyName); + DEBUG_WARN( "\tProductId: %s\n", ProductId); free(CompanyName); free(ProductId); @@ -103,12 +103,12 @@ void license_print_scope_list(SCOPE_LIST* scopeList) int index; LICENSE_BLOB* scope; - fprintf(stderr, "ScopeList (%d):\n", scopeList->count); + DEBUG_WARN( "ScopeList (%d):\n", scopeList->count); for (index = 0; index < scopeList->count; index++) { scope = &scopeList->array[index]; - fprintf(stderr, "\t%s\n", (char*) scope->data); + DEBUG_WARN( "\t%s\n", (char*) scope->data); } } @@ -210,7 +210,7 @@ BOOL license_send(rdpLicense* license, wStream* s, BYTE type) license_write_preamble(s, type, flags, wMsgSize); #ifdef WITH_DEBUG_LICENSE - fprintf(stderr, "Sending %s Packet, length %d\n", LICENSE_MESSAGE_STRINGS[type & 0x1F], wMsgSize); + DEBUG_WARN( "Sending %s Packet, length %d\n", LICENSE_MESSAGE_STRINGS[type & 0x1F], wMsgSize); winpr_HexDump(Stream_Pointer(s) - LICENSE_PREAMBLE_LENGTH, wMsgSize); #endif @@ -241,7 +241,7 @@ int license_recv(rdpLicense* license, wStream* s) if (!rdp_read_header(license->rdp, s, &length, &channelId)) { - fprintf(stderr, "%s: Incorrect RDP header.\n", __FUNCTION__); + DEBUG_WARN( "%s: Incorrect RDP header.\n", __FUNCTION__); return -1; } @@ -252,7 +252,7 @@ int license_recv(rdpLicense* license, wStream* s) { if (!rdp_decrypt(license->rdp, s, length - 4, securityFlags)) { - fprintf(stderr, "%s: rdp_decrypt failed\n", __FUNCTION__); + DEBUG_WARN( "%s: rdp_decrypt failed\n", __FUNCTION__); return -1; } } @@ -268,7 +268,7 @@ int license_recv(rdpLicense* license, wStream* s) if (status < 0) { - fprintf(stderr, "%s: unexpected license packet.\n", __FUNCTION__); + DEBUG_WARN( "%s: unexpected license packet.\n", __FUNCTION__); return status; } @@ -308,7 +308,7 @@ int license_recv(rdpLicense* license, wStream* s) break; default: - fprintf(stderr, "%s: invalid bMsgType:%d\n", __FUNCTION__, bMsgType); + DEBUG_WARN( "%s: invalid bMsgType:%d\n", __FUNCTION__, bMsgType); return FALSE; } @@ -349,33 +349,33 @@ void license_generate_keys(rdpLicense* license) license->ServerRandom, license->LicensingEncryptionKey); /* LicensingEncryptionKey */ #ifdef WITH_DEBUG_LICENSE - fprintf(stderr, "ClientRandom:\n"); + DEBUG_WARN( "ClientRandom:\n"); winpr_HexDump(license->ClientRandom, CLIENT_RANDOM_LENGTH); - fprintf(stderr, "\n"); + DEBUG_WARN( "\n"); - fprintf(stderr, "ServerRandom:\n"); + DEBUG_WARN( "ServerRandom:\n"); winpr_HexDump(license->ServerRandom, SERVER_RANDOM_LENGTH); - fprintf(stderr, "\n"); + DEBUG_WARN( "\n"); - fprintf(stderr, "PremasterSecret:\n"); + DEBUG_WARN( "PremasterSecret:\n"); winpr_HexDump(license->PremasterSecret, PREMASTER_SECRET_LENGTH); - fprintf(stderr, "\n"); + DEBUG_WARN( "\n"); - fprintf(stderr, "MasterSecret:\n"); + DEBUG_WARN( "MasterSecret:\n"); winpr_HexDump(license->MasterSecret, MASTER_SECRET_LENGTH); - fprintf(stderr, "\n"); + DEBUG_WARN( "\n"); - fprintf(stderr, "SessionKeyBlob:\n"); + DEBUG_WARN( "SessionKeyBlob:\n"); winpr_HexDump(license->SessionKeyBlob, SESSION_KEY_BLOB_LENGTH); - fprintf(stderr, "\n"); + DEBUG_WARN( "\n"); - fprintf(stderr, "MacSaltKey:\n"); + DEBUG_WARN( "MacSaltKey:\n"); winpr_HexDump(license->MacSaltKey, MAC_SALT_KEY_LENGTH); - fprintf(stderr, "\n"); + DEBUG_WARN( "\n"); - fprintf(stderr, "LicensingEncryptionKey:\n"); + DEBUG_WARN( "LicensingEncryptionKey:\n"); winpr_HexDump(license->LicensingEncryptionKey, LICENSING_ENCRYPTION_KEY_LENGTH); - fprintf(stderr, "\n"); + DEBUG_WARN( "\n"); #endif } @@ -395,7 +395,7 @@ void license_generate_hwid(rdpLicense* license) md5 = crypto_md5_init(); if (!md5) { - fprintf(stderr, "%s: unable to allocate a md5\n", __FUNCTION__); + DEBUG_WARN( "%s: unable to allocate a md5\n", __FUNCTION__); return; } @@ -434,13 +434,13 @@ void license_encrypt_premaster_secret(rdpLicense* license) license_get_server_rsa_public_key(license); #ifdef WITH_DEBUG_LICENSE - fprintf(stderr, "Modulus (%d bits):\n", license->ModulusLength * 8); + DEBUG_WARN( "Modulus (%d bits):\n", license->ModulusLength * 8); winpr_HexDump(license->Modulus, license->ModulusLength); - fprintf(stderr, "\n"); + DEBUG_WARN( "\n"); - fprintf(stderr, "Exponent:\n"); + DEBUG_WARN( "Exponent:\n"); winpr_HexDump(license->Exponent, 4); - fprintf(stderr, "\n"); + DEBUG_WARN( "\n"); #endif EncryptedPremasterSecret = (BYTE*) malloc(license->ModulusLength); @@ -467,7 +467,7 @@ void license_decrypt_platform_challenge(rdpLicense* license) rc4 = crypto_rc4_init(license->LicensingEncryptionKey, LICENSING_ENCRYPTION_KEY_LENGTH); if (!rc4) { - fprintf(stderr, "%s: unable to allocate a rc4\n", __FUNCTION__); + DEBUG_WARN( "%s: unable to allocate a rc4\n", __FUNCTION__); return; } @@ -582,7 +582,7 @@ BOOL license_read_binary_blob(wStream* s, LICENSE_BLOB* blob) if ((blob->type != wBlobType) && (blob->type != BB_ANY_BLOB)) { - fprintf(stderr, "license binary blob type (%x) does not match expected type (%x).\n", wBlobType, blob->type); + DEBUG_WARN( "license binary blob type (%x) does not match expected type (%x).\n", wBlobType, blob->type); } blob->type = wBlobType; @@ -618,7 +618,7 @@ void license_write_encrypted_premaster_secret_blob(wStream* s, LICENSE_BLOB* blo if (blob->length > ModulusLength) { - fprintf(stderr, "license_write_encrypted_premaster_secret_blob: invalid blob\n"); + DEBUG_WARN( "license_write_encrypted_premaster_secret_blob: invalid blob\n"); return; } @@ -783,15 +783,15 @@ BOOL license_read_license_request_packet(rdpLicense* license, wStream* s) license_encrypt_premaster_secret(license); #ifdef WITH_DEBUG_LICENSE - fprintf(stderr, "ServerRandom:\n"); + DEBUG_WARN( "ServerRandom:\n"); winpr_HexDump(license->ServerRandom, 32); - fprintf(stderr, "\n"); + DEBUG_WARN( "\n"); license_print_product_info(license->ProductInfo); - fprintf(stderr, "\n"); + DEBUG_WARN( "\n"); license_print_scope_list(license->ScopeList); - fprintf(stderr, "\n"); + DEBUG_WARN( "\n"); #endif return TRUE; @@ -829,20 +829,20 @@ BOOL license_read_platform_challenge_packet(rdpLicense* license, wStream* s) license_decrypt_platform_challenge(license); #ifdef WITH_DEBUG_LICENSE - fprintf(stderr, "ConnectFlags: 0x%08X\n", ConnectFlags); - fprintf(stderr, "\n"); + DEBUG_WARN( "ConnectFlags: 0x%08X\n", ConnectFlags); + DEBUG_WARN( "\n"); - fprintf(stderr, "EncryptedPlatformChallenge:\n"); + DEBUG_WARN( "EncryptedPlatformChallenge:\n"); winpr_HexDump(license->EncryptedPlatformChallenge->data, license->EncryptedPlatformChallenge->length); - fprintf(stderr, "\n"); + DEBUG_WARN( "\n"); - fprintf(stderr, "PlatformChallenge:\n"); + DEBUG_WARN( "PlatformChallenge:\n"); winpr_HexDump(license->PlatformChallenge->data, license->PlatformChallenge->length); - fprintf(stderr, "\n"); + DEBUG_WARN( "\n"); - fprintf(stderr, "MacData:\n"); + DEBUG_WARN( "MacData:\n"); winpr_HexDump(MacData, 16); - fprintf(stderr, "\n"); + DEBUG_WARN( "\n"); #endif return TRUE; @@ -896,7 +896,7 @@ BOOL license_read_error_alert_packet(rdpLicense* license, wStream* s) return FALSE; #ifdef WITH_DEBUG_LICENSE - fprintf(stderr, "dwErrorCode: %s, dwStateTransition: %s\n", + DEBUG_WARN( "dwErrorCode: %s, dwStateTransition: %s\n", error_codes[dwErrorCode], state_transitions[dwStateTransition]); #endif @@ -952,22 +952,22 @@ void license_write_new_license_request_packet(rdpLicense* license, wStream* s) license_write_binary_blob(s, license->ClientMachineName); /* ClientMachineName */ #ifdef WITH_DEBUG_LICENSE - fprintf(stderr, "PreferredKeyExchangeAlg: 0x%08X\n", PreferredKeyExchangeAlg); - fprintf(stderr, "\n"); + DEBUG_WARN( "PreferredKeyExchangeAlg: 0x%08X\n", PreferredKeyExchangeAlg); + DEBUG_WARN( "\n"); - fprintf(stderr, "ClientRandom:\n"); + DEBUG_WARN( "ClientRandom:\n"); winpr_HexDump(license->ClientRandom, 32); - fprintf(stderr, "\n"); + DEBUG_WARN( "\n"); - fprintf(stderr, "EncryptedPremasterSecret\n"); + DEBUG_WARN( "EncryptedPremasterSecret\n"); winpr_HexDump(license->EncryptedPremasterSecret->data, license->EncryptedPremasterSecret->length); - fprintf(stderr, "\n"); + DEBUG_WARN( "\n"); - fprintf(stderr, "ClientUserName (%d): %s\n", license->ClientUserName->length, (char*) license->ClientUserName->data); - fprintf(stderr, "\n"); + DEBUG_WARN( "ClientUserName (%d): %s\n", license->ClientUserName->length, (char*) license->ClientUserName->data); + DEBUG_WARN( "\n"); - fprintf(stderr, "ClientMachineName (%d): %s\n", license->ClientMachineName->length, (char*) license->ClientMachineName->data); - fprintf(stderr, "\n"); + DEBUG_WARN( "ClientMachineName (%d): %s\n", license->ClientMachineName->length, (char*) license->ClientMachineName->data); + DEBUG_WARN( "\n"); #endif } @@ -1056,7 +1056,7 @@ void license_send_platform_challenge_response_packet(rdpLicense* license) rc4 = crypto_rc4_init(license->LicensingEncryptionKey, LICENSING_ENCRYPTION_KEY_LENGTH); if (!rc4) { - fprintf(stderr, "%s: unable to allocate a rc4\n", __FUNCTION__); + DEBUG_WARN( "%s: unable to allocate a rc4\n", __FUNCTION__); free(buffer); return; } @@ -1068,17 +1068,17 @@ void license_send_platform_challenge_response_packet(rdpLicense* license) license->EncryptedHardwareId->length = HWID_LENGTH; #ifdef WITH_DEBUG_LICENSE - fprintf(stderr, "LicensingEncryptionKey:\n"); + DEBUG_WARN( "LicensingEncryptionKey:\n"); winpr_HexDump(license->LicensingEncryptionKey, 16); - fprintf(stderr, "\n"); + DEBUG_WARN( "\n"); - fprintf(stderr, "HardwareId:\n"); + DEBUG_WARN( "HardwareId:\n"); winpr_HexDump(license->HardwareId, HWID_LENGTH); - fprintf(stderr, "\n"); + DEBUG_WARN( "\n"); - fprintf(stderr, "EncryptedHardwareId:\n"); + DEBUG_WARN( "EncryptedHardwareId:\n"); winpr_HexDump(license->EncryptedHardwareId->data, HWID_LENGTH); - fprintf(stderr, "\n"); + DEBUG_WARN( "\n"); #endif license_write_platform_challenge_response_packet(license, s, mac_data); diff --git a/libfreerdp/core/listener.c b/libfreerdp/core/listener.c index e37c4c89f..4073b10ca 100644 --- a/libfreerdp/core/listener.c +++ b/libfreerdp/core/listener.c @@ -104,7 +104,7 @@ static BOOL freerdp_listener_open(freerdp_listener* instance, const char* bind_a #ifdef _WIN32 _tprintf(_T("getaddrinfo error: %s\n"), gai_strerror(status)); #else - perror("getaddrinfo"); + DEBUG_WARN("getaddrinfo"); #endif return FALSE; } @@ -118,14 +118,14 @@ static BOOL freerdp_listener_open(freerdp_listener* instance, const char* bind_a if (sockfd == -1) { - perror("socket"); + DEBUG_WARN("socket"); continue; } option_value = 1; if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (void*) &option_value, sizeof(option_value)) == -1) - perror("setsockopt"); + DEBUG_WARN("setsockopt"); #ifndef _WIN32 fcntl(sockfd, F_SETFL, O_NONBLOCK); @@ -142,7 +142,7 @@ static BOOL freerdp_listener_open(freerdp_listener* instance, const char* bind_a _tprintf(L"bind() failed with error: %u\n", WSAGetLastError()); WSACleanup(); #else - perror("bind"); + DEBUG_WARN("bind"); close(sockfd); #endif continue; @@ -152,11 +152,13 @@ static BOOL freerdp_listener_open(freerdp_listener* instance, const char* bind_a if (status != 0) { - perror("listen"); + DEBUG_WARN("listen"); close(sockfd); continue; } + /* FIXME: these file descriptors do not work on Windows */ + listener->sockfds[listener->num_sockfds] = sockfd; listener->events[listener->num_sockfds] = CreateFileDescriptorEvent(NULL, FALSE, FALSE, sockfd); listener->num_sockfds++; @@ -166,7 +168,7 @@ static BOOL freerdp_listener_open(freerdp_listener* instance, const char* bind_a else sin_addr = &(((struct sockaddr_in6*) ai->ai_addr)->sin6_addr); - fprintf(stderr, "Listening on %s port %s.\n", inet_ntop(ai->ai_family, sin_addr, buf, sizeof(buf)), servname); + DEBUG_WARN( "Listening on %s port %s.\n", inet_ntop(ai->ai_family, sin_addr, buf, sizeof(buf)), servname); } freeaddrinfo(res); @@ -186,7 +188,7 @@ static BOOL freerdp_listener_open_local(freerdp_listener* instance, const char* if (sockfd == -1) { - perror("socket"); + DEBUG_WARN("socket"); return FALSE; } @@ -200,7 +202,7 @@ static BOOL freerdp_listener_open_local(freerdp_listener* instance, const char* if (status != 0) { - perror("bind"); + DEBUG_WARN("bind"); close(sockfd); return FALSE; } @@ -209,7 +211,7 @@ static BOOL freerdp_listener_open_local(freerdp_listener* instance, const char* if (status != 0) { - perror("listen"); + DEBUG_WARN("listen"); close(sockfd); return FALSE; } @@ -218,7 +220,7 @@ static BOOL freerdp_listener_open_local(freerdp_listener* instance, const char* listener->events[listener->num_sockfds] = CreateFileDescriptorEvent(NULL, FALSE, FALSE, sockfd); listener->num_sockfds++; - fprintf(stderr, "Listening on socket %s.\n", addr.sun_path); + DEBUG_WARN( "Listening on socket %s.\n", addr.sun_path); return TRUE; #else @@ -306,7 +308,7 @@ static BOOL freerdp_listener_check_fds(freerdp_listener* instance) if (errno == EAGAIN || errno == EWOULDBLOCK) continue; #endif - perror("accept"); + DEBUG_WARN("accept"); if (client) free(client); return FALSE; @@ -346,8 +348,10 @@ freerdp_listener* freerdp_listener_new(void) freerdp_listener* instance; rdpListener* listener; - instance = (freerdp_listener*) malloc(sizeof(freerdp_listener)); - ZeroMemory(instance, sizeof(freerdp_listener)); + instance = (freerdp_listener*) calloc(1, sizeof(freerdp_listener)); + + if (!instance) + return NULL; instance->Open = freerdp_listener_open; instance->OpenLocal = freerdp_listener_open_local; @@ -356,8 +360,10 @@ freerdp_listener* freerdp_listener_new(void) instance->CheckFileDescriptor = freerdp_listener_check_fds; instance->Close = freerdp_listener_close; - listener = (rdpListener*) malloc(sizeof(rdpListener)); - ZeroMemory(listener, sizeof(rdpListener)); + listener = (rdpListener*) calloc(1, sizeof(rdpListener)); + + if (!listener) + return NULL; listener->instance = instance; diff --git a/libfreerdp/core/mcs.c b/libfreerdp/core/mcs.c index c47660f19..326622116 100644 --- a/libfreerdp/core/mcs.c +++ b/libfreerdp/core/mcs.c @@ -328,16 +328,16 @@ void mcs_write_domain_parameters(wStream* s, DomainParameters* domainParameters) void mcs_print_domain_parameters(DomainParameters* domainParameters) { - fprintf(stderr, "DomainParameters {\n"); - fprintf(stderr, "\tmaxChannelIds:%d\n", domainParameters->maxChannelIds); - fprintf(stderr, "\tmaxUserIds:%d\n", domainParameters->maxUserIds); - fprintf(stderr, "\tmaxTokenIds:%d\n", domainParameters->maxTokenIds); - fprintf(stderr, "\tnumPriorities:%d\n", domainParameters->numPriorities); - fprintf(stderr, "\tminThroughput:%d\n", domainParameters->minThroughput); - fprintf(stderr, "\tmaxHeight:%d\n", domainParameters->maxHeight); - fprintf(stderr, "\tmaxMCSPDUsize:%d\n", domainParameters->maxMCSPDUsize); - fprintf(stderr, "\tprotocolVersion:%d\n", domainParameters->protocolVersion); - fprintf(stderr, "}\n"); + DEBUG_WARN( "DomainParameters {\n"); + DEBUG_WARN( "\tmaxChannelIds:%d\n", domainParameters->maxChannelIds); + DEBUG_WARN( "\tmaxUserIds:%d\n", domainParameters->maxUserIds); + DEBUG_WARN( "\tmaxTokenIds:%d\n", domainParameters->maxTokenIds); + DEBUG_WARN( "\tnumPriorities:%d\n", domainParameters->numPriorities); + DEBUG_WARN( "\tminThroughput:%d\n", domainParameters->minThroughput); + DEBUG_WARN( "\tmaxHeight:%d\n", domainParameters->maxHeight); + DEBUG_WARN( "\tmaxMCSPDUsize:%d\n", domainParameters->maxMCSPDUsize); + DEBUG_WARN( "\tprotocolVersion:%d\n", domainParameters->protocolVersion); + DEBUG_WARN( "}\n"); } /** @@ -661,7 +661,7 @@ BOOL mcs_recv_connect_response(rdpMcs* mcs, wStream* s) if (!gcc_read_conference_create_response(s, mcs)) { - fprintf(stderr, "mcs_recv_connect_response: gcc_read_conference_create_response failed\n"); + DEBUG_WARN( "mcs_recv_connect_response: gcc_read_conference_create_response failed\n"); return FALSE; } diff --git a/libfreerdp/core/message.c b/libfreerdp/core/message.c index 10e2bd637..62c66f647 100644 --- a/libfreerdp/core/message.c +++ b/libfreerdp/core/message.c @@ -762,7 +762,7 @@ static void update_message_WindowIcon(rdpContext* context, WINDOW_ORDER_INFO* or lParam = (WINDOW_ICON_ORDER*) malloc(sizeof(WINDOW_ICON_ORDER)); CopyMemory(lParam, windowIcon, sizeof(WINDOW_ICON_ORDER)); - fprintf(stderr, "update_message_WindowIcon\n"); + DEBUG_WARN( "update_message_WindowIcon\n"); if (windowIcon->iconInfo->cbBitsColor > 0) { @@ -1871,7 +1871,7 @@ static int update_message_free_class(wMessage*msg, int msgClass, int msgType) } if (status < 0) - fprintf(stderr, "Unknown message: class: %d type: %d\n", msgClass, msgType); + DEBUG_WARN( "Unknown message: class: %d type: %d\n", msgClass, msgType); return status; } @@ -1912,7 +1912,7 @@ static int update_message_process_class(rdpUpdateProxy* proxy, wMessage* msg, in } if (status < 0) - fprintf(stderr, "Unknown message: class: %d type: %d\n", msgClass, msgType); + DEBUG_WARN( "Unknown message: class: %d type: %d\n", msgClass, msgType); return status; } @@ -2159,11 +2159,37 @@ void update_message_register_interface(rdpUpdateProxy* message, rdpUpdate* updat pointer->PointerCached = update_message_PointerCached; } -rdpUpdateProxy* update_message_proxy_new(rdpUpdate* update) +static void *update_message_proxy_thread(void *arg) { - rdpUpdateProxy* message; + rdpUpdate *update = (rdpUpdate *)arg; + wMessage message; - message = (rdpUpdateProxy*) malloc(sizeof(rdpUpdateProxy)); + if (!update || !update->queue) + { + DEBUG_WARN("update=%p, update->queue=%p", update, update ? update->queue : NULL); + ExitThread(-1); + return NULL; + } + + while (MessageQueue_Wait(update->queue)) + { + int status = 0; + + if (MessageQueue_Peek(update->queue, &message, TRUE)) + status = update_message_queue_process_message(update, &message); + + if (!status) + break; + } + + ExitThread(0); + return NULL; +} + +rdpUpdateProxy *update_message_proxy_new(rdpUpdate *update) +{ + rdpUpdateProxy *message; + message = (rdpUpdateProxy *) malloc(sizeof(rdpUpdateProxy)); if (message) { @@ -2171,6 +2197,7 @@ rdpUpdateProxy* update_message_proxy_new(rdpUpdate* update) message->update = update; update_message_register_interface(message, update); + message->thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) update_message_proxy_thread, update, 0, NULL); } return message; @@ -2180,6 +2207,9 @@ void update_message_proxy_free(rdpUpdateProxy* message) { if (message) { + MessageQueue_PostQuit(message->update->queue, 0); + WaitForSingleObject(message->thread, INFINITE); + CloseHandle(message->thread); free(message); } } @@ -2318,7 +2348,7 @@ static int input_message_free_class(wMessage* msg, int msgClass, int msgType) } if (status < 0) - fprintf(stderr, "Unknown event: class: %d type: %d\n", msgClass, msgType); + DEBUG_WARN( "Unknown event: class: %d type: %d\n", msgClass, msgType); return status; } @@ -2339,7 +2369,7 @@ static int input_message_process_class(rdpInputProxy* proxy, wMessage* msg, int } if (status < 0) - fprintf(stderr, "Unknown event: class: %d type: %d\n", msgClass, msgType); + DEBUG_WARN( "Unknown event: class: %d type: %d\n", msgClass, msgType); return status; } diff --git a/libfreerdp/core/message.h b/libfreerdp/core/message.h index fad0e15ce..c303382df 100644 --- a/libfreerdp/core/message.h +++ b/libfreerdp/core/message.h @@ -120,6 +120,8 @@ struct rdp_update_proxy pPointerColor PointerColor; pPointerNew PointerNew; pPointerCached PointerCached; + + HANDLE thread; }; int update_message_queue_process_message(rdpUpdate* update, wMessage* message); diff --git a/libfreerdp/core/nego.c b/libfreerdp/core/nego.c index 09d63065a..d5c98ef29 100644 --- a/libfreerdp/core/nego.c +++ b/libfreerdp/core/nego.c @@ -32,6 +32,7 @@ #include "transport.h" +#ifdef WITH_DEBUG_NEGO static const char* const NEGO_STATE_STRINGS[] = { "NEGO_STATE_INITIAL", @@ -55,6 +56,7 @@ static const char PROTOCOL_SECURITY_STRINGS[9][4] = "UNK", "EXT" }; +#endif /* WITH_DEBUG_NEGO */ BOOL nego_security_connect(rdpNego* nego); @@ -593,7 +595,7 @@ int nego_recv(rdpTransport* transport, wStream* s, void* extra) } else { - fprintf(stderr, "invalid negotiation response\n"); + DEBUG_WARN( "invalid negotiation response\n"); nego->state = NEGO_STATE_FAIL; } @@ -619,7 +621,7 @@ BOOL nego_read_request(rdpNego* nego, wStream* s) if (li != Stream_GetRemainingLength(s) + 6) { - fprintf(stderr, "Incorrect TPDU length indicator.\n"); + DEBUG_WARN( "Incorrect TPDU length indicator.\n"); return FALSE; } @@ -651,7 +653,7 @@ BOOL nego_read_request(rdpNego* nego, wStream* s) if (type != TYPE_RDP_NEG_REQ) { - fprintf(stderr, "Incorrect negotiation request type %d\n", type); + DEBUG_WARN( "Incorrect negotiation request type %d\n", type); return FALSE; } @@ -890,36 +892,38 @@ BOOL nego_send_negotiation_response(rdpNego* nego) bm = Stream_GetPosition(s); Stream_Seek(s, length); - if (nego->selected_protocol > PROTOCOL_RDP) - { - flags = EXTENDED_CLIENT_DATA_SUPPORTED; - - if (settings->SupportGraphicsPipeline) - flags |= DYNVC_GFX_PROTOCOL_SUPPORTED; - - /* RDP_NEG_DATA must be present for TLS and NLA */ - Stream_Write_UINT8(s, TYPE_RDP_NEG_RSP); - Stream_Write_UINT8(s, flags); /* flags */ - Stream_Write_UINT16(s, 8); /* RDP_NEG_DATA length (8) */ - Stream_Write_UINT32(s, nego->selected_protocol); /* selectedProtocol */ - length += 8; - } - else if (!settings->RdpSecurity) + if ((nego->selected_protocol == PROTOCOL_RDP) && !settings->RdpSecurity) { flags = 0; Stream_Write_UINT8(s, TYPE_RDP_NEG_FAILURE); Stream_Write_UINT8(s, flags); /* flags */ Stream_Write_UINT16(s, 8); /* RDP_NEG_DATA length (8) */ + /* * TODO: Check for other possibilities, * like SSL_NOT_ALLOWED_BY_SERVER. */ - fprintf(stderr, "%s: client supports only Standard RDP Security\n", __FUNCTION__); + DEBUG_WARN( "%s: client supports only Standard RDP Security\n", __FUNCTION__); + Stream_Write_UINT32(s, SSL_REQUIRED_BY_SERVER); length += 8; status = FALSE; } + else + { + flags = EXTENDED_CLIENT_DATA_SUPPORTED; + + if (settings->SupportGraphicsPipeline) + flags |= DYNVC_GFX_PROTOCOL_SUPPORTED; + + /* RDP_NEG_DATA must be present for TLS, NLA, and RDP */ + Stream_Write_UINT8(s, TYPE_RDP_NEG_RSP); + Stream_Write_UINT8(s, flags); /* flags */ + Stream_Write_UINT16(s, 8); /* RDP_NEG_DATA length (8) */ + Stream_Write_UINT32(s, nego->selected_protocol); /* selectedProtocol */ + length += 8; + } em = Stream_GetPosition(s); Stream_SetPosition(s, bm); @@ -951,13 +955,22 @@ BOOL nego_send_negotiation_response(rdpNego* nego) if (!settings->LocalConnection) { - settings->DisableEncryption = TRUE; + settings->DisableEncryption = FALSE; settings->EncryptionMethods = ENCRYPTION_METHOD_40BIT | ENCRYPTION_METHOD_56BIT | ENCRYPTION_METHOD_128BIT | ENCRYPTION_METHOD_FIPS; settings->EncryptionLevel = ENCRYPTION_LEVEL_CLIENT_COMPATIBLE; } - if (settings->DisableEncryption && !settings->RdpServerRsaKey && !settings->RdpKeyFile) + if (settings->DisableEncryption) + { + fprintf(stderr, "Encryption is disabled.\n"); return FALSE; + } + + if (!settings->RdpServerRsaKey && !settings->RdpKeyFile) + { + fprintf(stderr, "Missing server certificate\n"); + return FALSE; + } } else if (settings->SelectedProtocol == PROTOCOL_TLS) { diff --git a/libfreerdp/core/nla.c b/libfreerdp/core/nla.c index 5b7a77a18..8d247c637 100644 --- a/libfreerdp/core/nla.c +++ b/libfreerdp/core/nla.c @@ -186,7 +186,7 @@ int credssp_ntlm_client_init(rdpCredssp* credssp) #endif #ifdef WITH_DEBUG_NLA - _tprintf(_T("User: %s Domain: %s Password: %s\n"), + DEBUG_MSG("User: %s Domain: %s Password: %s\n", (char*) credssp->identity.User, (char*) credssp->identity.Domain, (char*) credssp->identity.Password); #endif @@ -200,7 +200,7 @@ int credssp_ntlm_client_init(rdpCredssp* credssp) } else { - fprintf(stderr, "Unknown NLA transport layer\n"); + DEBUG_WARN( "Unknown NLA transport layer\n"); return 0; } @@ -269,7 +269,7 @@ int credssp_client_authenticate(rdpCredssp* credssp) if (status != SEC_E_OK) { - fprintf(stderr, "QuerySecurityPackageInfo status: 0x%08X\n", status); + DEBUG_WARN( "QuerySecurityPackageInfo status: 0x%08X\n", status); return 0; } @@ -280,7 +280,7 @@ int credssp_client_authenticate(rdpCredssp* credssp) if (status != SEC_E_OK) { - fprintf(stderr, "AcquireCredentialsHandle status: 0x%08X\n", status); + DEBUG_WARN( "AcquireCredentialsHandle status: 0x%08X\n", status); return 0; } @@ -339,7 +339,7 @@ int credssp_client_authenticate(rdpCredssp* credssp) if (credssp->table->QueryContextAttributes(&credssp->context, SECPKG_ATTR_SIZES, &credssp->ContextSizes) != SEC_E_OK) { - fprintf(stderr, "QueryContextAttributes SECPKG_ATTR_SIZES failure\n"); + DEBUG_WARN( "QueryContextAttributes SECPKG_ATTR_SIZES failure\n"); return 0; } @@ -354,7 +354,7 @@ int credssp_client_authenticate(rdpCredssp* credssp) credssp->negoToken.cbBuffer = output_buffer.cbBuffer; #ifdef WITH_DEBUG_CREDSSP - fprintf(stderr, "Sending Authentication Token\n"); + DEBUG_WARN( "Sending Authentication Token\n"); winpr_HexDump(credssp->negoToken.pvBuffer, credssp->negoToken.cbBuffer); #endif @@ -376,7 +376,7 @@ int credssp_client_authenticate(rdpCredssp* credssp) return -1; #ifdef WITH_DEBUG_CREDSSP - fprintf(stderr, "Receiving Authentication Token (%d)\n", (int) credssp->negoToken.cbBuffer); + DEBUG_WARN( "Receiving Authentication Token (%d)\n", (int) credssp->negoToken.cbBuffer); winpr_HexDump(credssp->negoToken.pvBuffer, credssp->negoToken.cbBuffer); #endif @@ -398,7 +398,7 @@ int credssp_client_authenticate(rdpCredssp* credssp) if (status != SEC_E_OK) { - fprintf(stderr, "Could not verify public key echo!\n"); + DEBUG_WARN( "Could not verify public key echo!\n"); return -1; } @@ -408,7 +408,7 @@ int credssp_client_authenticate(rdpCredssp* credssp) if (status != SEC_E_OK) { - fprintf(stderr, "credssp_encrypt_ts_credentials status: 0x%08X\n", status); + DEBUG_WARN( "credssp_encrypt_ts_credentials status: 0x%08X\n", status); return 0; } @@ -460,7 +460,7 @@ int credssp_server_authenticate(rdpCredssp* credssp) if (!hSSPI) { - _tprintf(_T("Failed to load SSPI module: %s\n"), credssp->SspiModule); + DEBUG_WARN("Failed to load SSPI module: %s\n", credssp->SspiModule); return 0; } @@ -481,7 +481,7 @@ int credssp_server_authenticate(rdpCredssp* credssp) if (status != SEC_E_OK) { - fprintf(stderr, "QuerySecurityPackageInfo status: 0x%08X\n", status); + DEBUG_WARN( "QuerySecurityPackageInfo status: 0x%08X\n", status); return 0; } @@ -492,7 +492,7 @@ int credssp_server_authenticate(rdpCredssp* credssp) if (status != SEC_E_OK) { - fprintf(stderr, "AcquireCredentialsHandle status: 0x%08X\n", status); + DEBUG_WARN( "AcquireCredentialsHandle status: 0x%08X\n", status); return 0; } @@ -542,7 +542,7 @@ int credssp_server_authenticate(rdpCredssp* credssp) return -1; #ifdef WITH_DEBUG_CREDSSP - fprintf(stderr, "Receiving Authentication Token\n"); + DEBUG_WARN( "Receiving Authentication Token\n"); credssp_buffer_print(credssp); #endif @@ -551,7 +551,7 @@ int credssp_server_authenticate(rdpCredssp* credssp) if (credssp->negoToken.cbBuffer < 1) { - fprintf(stderr, "CredSSP: invalid negoToken!\n"); + DEBUG_WARN( "CredSSP: invalid negoToken!\n"); return -1; } @@ -587,13 +587,13 @@ int credssp_server_authenticate(rdpCredssp* credssp) if (credssp->table->QueryContextAttributes(&credssp->context, SECPKG_ATTR_SIZES, &credssp->ContextSizes) != SEC_E_OK) { - fprintf(stderr, "QueryContextAttributes SECPKG_ATTR_SIZES failure\n"); + DEBUG_WARN( "QueryContextAttributes SECPKG_ATTR_SIZES failure\n"); return 0; } if (credssp_decrypt_public_key_echo(credssp) != SEC_E_OK) { - fprintf(stderr, "Error: could not verify client's public key echo\n"); + DEBUG_WARN( "Error: could not verify client's public key echo\n"); return -1; } @@ -606,14 +606,14 @@ int credssp_server_authenticate(rdpCredssp* credssp) if ((status != SEC_E_OK) && (status != SEC_I_CONTINUE_NEEDED)) { - fprintf(stderr, "AcceptSecurityContext status: 0x%08X\n", status); + DEBUG_WARN( "AcceptSecurityContext status: 0x%08X\n", status); return -1; /* Access Denied */ } /* send authentication token */ #ifdef WITH_DEBUG_CREDSSP - fprintf(stderr, "Sending Authentication Token\n"); + DEBUG_WARN( "Sending Authentication Token\n"); credssp_buffer_print(credssp); #endif @@ -633,13 +633,13 @@ int credssp_server_authenticate(rdpCredssp* credssp) if (credssp_decrypt_ts_credentials(credssp) != SEC_E_OK) { - fprintf(stderr, "Could not decrypt TSCredentials status: 0x%08X\n", status); + DEBUG_WARN( "Could not decrypt TSCredentials status: 0x%08X\n", status); return 0; } if (status != SEC_E_OK) { - fprintf(stderr, "AcceptSecurityContext status: 0x%08X\n", status); + DEBUG_WARN( "AcceptSecurityContext status: 0x%08X\n", status); return 0; } @@ -647,7 +647,7 @@ int credssp_server_authenticate(rdpCredssp* credssp) if (status != SEC_E_OK) { - fprintf(stderr, "ImpersonateSecurityContext status: 0x%08X\n", status); + DEBUG_WARN( "ImpersonateSecurityContext status: 0x%08X\n", status); return 0; } else @@ -656,7 +656,7 @@ int credssp_server_authenticate(rdpCredssp* credssp) if (status != SEC_E_OK) { - fprintf(stderr, "RevertSecurityContext status: 0x%08X\n", status); + DEBUG_WARN( "RevertSecurityContext status: 0x%08X\n", status); return 0; } } @@ -753,7 +753,7 @@ SECURITY_STATUS credssp_encrypt_public_key_echo(rdpCredssp* credssp) if (status != SEC_E_OK) { - fprintf(stderr, "EncryptMessage status: 0x%08X\n", status); + DEBUG_WARN( "EncryptMessage status: 0x%08X\n", status); return status; } @@ -774,7 +774,7 @@ SECURITY_STATUS credssp_decrypt_public_key_echo(rdpCredssp* credssp) if (credssp->PublicKey.cbBuffer + credssp->ContextSizes.cbMaxSignature != credssp->pubKeyAuth.cbBuffer) { - fprintf(stderr, "unexpected pubKeyAuth buffer size:%d\n", (int) credssp->pubKeyAuth.cbBuffer); + DEBUG_WARN( "unexpected pubKeyAuth buffer size:%d\n", (int) credssp->pubKeyAuth.cbBuffer); return SEC_E_INVALID_TOKEN; } @@ -801,7 +801,7 @@ SECURITY_STATUS credssp_decrypt_public_key_echo(rdpCredssp* credssp) if (status != SEC_E_OK) { - fprintf(stderr, "DecryptMessage failure: 0x%08X\n", status); + DEBUG_WARN( "DecryptMessage failure: 0x%08X\n", status); return status; } @@ -816,12 +816,12 @@ SECURITY_STATUS credssp_decrypt_public_key_echo(rdpCredssp* credssp) if (memcmp(public_key1, public_key2, public_key_length) != 0) { - fprintf(stderr, "Could not verify server's public key echo\n"); + DEBUG_WARN( "Could not verify server's public key echo\n"); - fprintf(stderr, "Expected (length = %d):\n", public_key_length); + DEBUG_WARN( "Expected (length = %d):\n", public_key_length); winpr_HexDump(public_key1, public_key_length); - fprintf(stderr, "Actual (length = %d):\n", public_key_length); + DEBUG_WARN( "Actual (length = %d):\n", public_key_length); winpr_HexDump(public_key2, public_key_length); return SEC_E_MESSAGE_ALTERED; /* DO NOT SEND CREDENTIALS! */ @@ -1047,7 +1047,7 @@ SECURITY_STATUS credssp_decrypt_ts_credentials(rdpCredssp* credssp) if (credssp->authInfo.cbBuffer < 1) { - fprintf(stderr, "credssp_decrypt_ts_credentials missing authInfo buffer\n"); + DEBUG_WARN( "credssp_decrypt_ts_credentials missing authInfo buffer\n"); return SEC_E_INVALID_TOKEN; } @@ -1202,7 +1202,7 @@ int credssp_recv(rdpCredssp* credssp) if (status < 0) { - fprintf(stderr, "credssp_recv() error: %d\n", status); + DEBUG_WARN( "credssp_recv() error: %d\n", status); Stream_Free(s, TRUE); return -1; } @@ -1270,19 +1270,19 @@ void credssp_buffer_print(rdpCredssp* credssp) { if (credssp->negoToken.cbBuffer > 0) { - fprintf(stderr, "CredSSP.negoToken (length = %d):\n", (int) credssp->negoToken.cbBuffer); + DEBUG_WARN( "CredSSP.negoToken (length = %d):\n", (int) credssp->negoToken.cbBuffer); winpr_HexDump(credssp->negoToken.pvBuffer, credssp->negoToken.cbBuffer); } if (credssp->pubKeyAuth.cbBuffer > 0) { - fprintf(stderr, "CredSSP.pubKeyAuth (length = %d):\n", (int) credssp->pubKeyAuth.cbBuffer); + DEBUG_WARN( "CredSSP.pubKeyAuth (length = %d):\n", (int) credssp->pubKeyAuth.cbBuffer); winpr_HexDump(credssp->pubKeyAuth.pvBuffer, credssp->pubKeyAuth.cbBuffer); } if (credssp->authInfo.cbBuffer > 0) { - fprintf(stderr, "CredSSP.authInfo (length = %d):\n", (int) credssp->authInfo.cbBuffer); + DEBUG_WARN( "CredSSP.authInfo (length = %d):\n", (int) credssp->authInfo.cbBuffer); winpr_HexDump(credssp->authInfo.pvBuffer, credssp->authInfo.cbBuffer); } } @@ -1397,7 +1397,7 @@ rdpCredssp* credssp_new(freerdp* instance, rdpTransport* transport, rdpSettings* if (status == ERROR_SUCCESS) { - _tprintf(_T("Using SSPI Module: %s\n"), credssp->SspiModule); + DEBUG_WARN("Using SSPI Module: %s\n", credssp->SspiModule); RegCloseKey(hKey); } } diff --git a/libfreerdp/core/orders.c b/libfreerdp/core/orders.c index 98b177f67..8a9b98997 100644 --- a/libfreerdp/core/orders.c +++ b/libfreerdp/core/orders.c @@ -223,11 +223,11 @@ static INLINE BOOL update_read_color(wStream* s, UINT32* color) return FALSE; Stream_Read_UINT8(s, byte); - *color = byte; + *color = (UINT32) byte << 16; Stream_Read_UINT8(s, byte); - *color |= (byte << 8); + *color |= ((UINT32) byte << 8); Stream_Read_UINT8(s, byte); - *color |= (byte << 16); + *color |= (UINT32) byte; return TRUE; } @@ -749,7 +749,7 @@ static INLINE BOOL update_read_delta_points(wStream* s, DELTA_POINT* points, int if (orderInfo->fieldFlags & (1 << (NO-1))) \ { \ if (Stream_GetRemainingLength(s) < 1) {\ - fprintf(stderr, "%s: error reading %s\n", __FUNCTION__, #TARGET); \ + DEBUG_WARN( "%s: error reading %s\n", __FUNCTION__, #TARGET); \ return FALSE; \ } \ Stream_Read_UINT8(s, TARGET); \ @@ -761,7 +761,7 @@ static INLINE BOOL update_read_delta_points(wStream* s, DELTA_POINT* points, int if (orderInfo->fieldFlags & (1 << (NO-1))) \ { \ if (Stream_GetRemainingLength(s) < 2) { \ - fprintf(stderr, "%s: error reading %s or %s\n", __FUNCTION__, #TARGET1, #TARGET2); \ + DEBUG_WARN( "%s: error reading %s or %s\n", __FUNCTION__, #TARGET1, #TARGET2); \ return FALSE; \ } \ Stream_Read_UINT8(s, TARGET1); \ @@ -774,7 +774,7 @@ static INLINE BOOL update_read_delta_points(wStream* s, DELTA_POINT* points, int if (orderInfo->fieldFlags & (1 << (NO-1))) \ { \ if (Stream_GetRemainingLength(s) < 2) { \ - fprintf(stderr, "%s: error reading %s\n", __FUNCTION__, #TARGET); \ + DEBUG_WARN( "%s: error reading %s\n", __FUNCTION__, #TARGET); \ return FALSE; \ } \ Stream_Read_UINT16(s, TARGET); \ @@ -785,7 +785,7 @@ static INLINE BOOL update_read_delta_points(wStream* s, DELTA_POINT* points, int if (orderInfo->fieldFlags & (1 << (NO-1))) \ { \ if (Stream_GetRemainingLength(s) < 4) { \ - fprintf(stderr, "%s: error reading %s\n", __FUNCTION__, #TARGET); \ + DEBUG_WARN( "%s: error reading %s\n", __FUNCTION__, #TARGET); \ return FALSE; \ } \ Stream_Read_UINT32(s, TARGET); \ @@ -795,14 +795,14 @@ static INLINE BOOL update_read_delta_points(wStream* s, DELTA_POINT* points, int #define ORDER_FIELD_COORD(NO, TARGET) \ do { \ if ((orderInfo->fieldFlags & (1 << (NO-1))) && !update_read_coord(s, &TARGET, orderInfo->deltaCoordinates)) { \ - fprintf(stderr, "%s: error reading %s\n", __FUNCTION__, #TARGET); \ + DEBUG_WARN( "%s: error reading %s\n", __FUNCTION__, #TARGET); \ return FALSE; \ } \ } while(0) #define ORDER_FIELD_COLOR(NO, TARGET) \ do { \ if ((orderInfo->fieldFlags & (1 << (NO-1))) && !update_read_color(s, &TARGET)) { \ - fprintf(stderr, "%s: error reading %s\n", __FUNCTION__, #TARGET); \ + DEBUG_WARN( "%s: error reading %s\n", __FUNCTION__, #TARGET); \ return FALSE; \ } \ } while(0) @@ -811,12 +811,12 @@ static INLINE BOOL update_read_delta_points(wStream* s, DELTA_POINT* points, int #define FIELD_SKIP_BUFFER16(s, TARGET_LEN) \ do { \ if (Stream_GetRemainingLength(s) < 2) {\ - fprintf(stderr, "%s: error reading length %s\n", __FUNCTION__, #TARGET_LEN); \ + DEBUG_WARN( "%s: error reading length %s\n", __FUNCTION__, #TARGET_LEN); \ return FALSE; \ }\ Stream_Read_UINT16(s, TARGET_LEN); \ if (!Stream_SafeSeek(s, TARGET_LEN)) { \ - fprintf(stderr, "%s: error skipping %d bytes\n", __FUNCTION__, TARGET_LEN); \ + DEBUG_WARN( "%s: error skipping %d bytes\n", __FUNCTION__, TARGET_LEN); \ return FALSE; \ } \ } while(0) @@ -979,7 +979,7 @@ BOOL update_read_opaque_rect_order(wStream* s, ORDER_INFO* orderInfo, OPAQUE_REC return FALSE; Stream_Read_UINT8(s, byte); - opaque_rect->color = (opaque_rect->color & 0xFFFFFF00) | byte; + opaque_rect->color = (opaque_rect->color & 0xFF00FFFF) | ((UINT32) byte << 16); } if (orderInfo->fieldFlags & ORDER_FIELD_06) @@ -988,7 +988,7 @@ BOOL update_read_opaque_rect_order(wStream* s, ORDER_INFO* orderInfo, OPAQUE_REC return FALSE; Stream_Read_UINT8(s, byte); - opaque_rect->color = (opaque_rect->color & 0xFFFF00FF) | (byte << 8); + opaque_rect->color = (opaque_rect->color & 0xFFFF00FF) | ((UINT32) byte << 8); } if (orderInfo->fieldFlags & ORDER_FIELD_07) @@ -997,7 +997,7 @@ BOOL update_read_opaque_rect_order(wStream* s, ORDER_INFO* orderInfo, OPAQUE_REC return FALSE; Stream_Read_UINT8(s, byte); - opaque_rect->color = (opaque_rect->color & 0xFF00FFFF) | (byte << 16); + opaque_rect->color = (opaque_rect->color & 0xFFFFFF00) | (UINT32) byte; } return TRUE; @@ -1178,7 +1178,7 @@ BOOL update_read_multi_opaque_rect_order(wStream* s, ORDER_INFO* orderInfo, MULT return FALSE; Stream_Read_UINT8(s, byte); - multi_opaque_rect->color = (multi_opaque_rect->color & 0xFFFFFF00) | byte; + multi_opaque_rect->color = (multi_opaque_rect->color & 0xFF00FFFF) | ((UINT32) byte << 16); } if (orderInfo->fieldFlags & ORDER_FIELD_06) @@ -1187,7 +1187,7 @@ BOOL update_read_multi_opaque_rect_order(wStream* s, ORDER_INFO* orderInfo, MULT return FALSE; Stream_Read_UINT8(s, byte); - multi_opaque_rect->color = (multi_opaque_rect->color & 0xFFFF00FF) | (byte << 8); + multi_opaque_rect->color = (multi_opaque_rect->color & 0xFFFF00FF) | ((UINT32) byte << 8); } if (orderInfo->fieldFlags & ORDER_FIELD_07) @@ -1196,7 +1196,7 @@ BOOL update_read_multi_opaque_rect_order(wStream* s, ORDER_INFO* orderInfo, MULT return FALSE; Stream_Read_UINT8(s, byte); - multi_opaque_rect->color = (multi_opaque_rect->color & 0xFF00FFFF) | (byte << 16); + multi_opaque_rect->color = (multi_opaque_rect->color & 0xFFFFFF00) | (UINT32) byte; } ORDER_FIELD_BYTE(8, multi_opaque_rect->numRectangles); @@ -1842,7 +1842,7 @@ BOOL update_read_cache_bitmap_order(wStream* s, CACHE_BITMAP_ORDER* cache_bitmap Stream_Read_UINT8(s, cache_bitmap->bitmapBpp); /* bitmapBpp (1 byte) */ if ((cache_bitmap->bitmapBpp < 1) || (cache_bitmap->bitmapBpp > 32)) { - fprintf(stderr, "%s: invalid bitmap bpp %d\n", __FUNCTION__, cache_bitmap->bitmapBpp); + DEBUG_WARN( "%s: invalid bitmap bpp %d\n", __FUNCTION__, cache_bitmap->bitmapBpp); return FALSE; } Stream_Read_UINT16(s, cache_bitmap->bitmapLength); /* bitmapLength (2 bytes) */ @@ -2085,7 +2085,7 @@ BOOL update_read_cache_bitmap_v3_order(wStream* s, CACHE_BITMAP_V3_ORDER* cache_ Stream_Read_UINT8(s, bitmapData->bpp); if ((bitmapData->bpp < 1) || (bitmapData->bpp > 32)) { - fprintf(stderr, "%s: invalid bpp value %d", __FUNCTION__, bitmapData->bpp); + DEBUG_WARN( "%s: invalid bpp value %d", __FUNCTION__, bitmapData->bpp); return FALSE; } Stream_Seek_UINT8(s); /* reserved1 (1 byte) */ @@ -2447,7 +2447,7 @@ BOOL update_read_cache_brush_order(wStream* s, CACHE_BRUSH_ORDER* cache_brush, U { if (cache_brush->length != 8) { - fprintf(stderr, "incompatible 1bpp brush of length:%d\n", cache_brush->length); + DEBUG_WARN( "incompatible 1bpp brush of length:%d\n", cache_brush->length); return TRUE; // should be FALSE ? } @@ -2526,7 +2526,7 @@ BOOL update_write_cache_brush_order(wStream* s, CACHE_BRUSH_ORDER* cache_brush, { if (cache_brush->length != 8) { - fprintf(stderr, "incompatible 1bpp brush of length:%d\n", cache_brush->length); + DEBUG_WARN( "incompatible 1bpp brush of length:%d\n", cache_brush->length); return FALSE; } @@ -2694,7 +2694,7 @@ BOOL update_read_create_nine_grid_bitmap_order(wStream* s, CREATE_NINE_GRID_BITM Stream_Read_UINT8(s, create_nine_grid_bitmap->bitmapBpp); /* bitmapBpp (1 byte) */ if ((create_nine_grid_bitmap->bitmapBpp < 1) || (create_nine_grid_bitmap->bitmapBpp > 32)) { - fprintf(stderr, "%s: invalid bpp value %d", __FUNCTION__, create_nine_grid_bitmap->bitmapBpp); + DEBUG_WARN( "%s: invalid bpp value %d", __FUNCTION__, create_nine_grid_bitmap->bitmapBpp); return FALSE; } Stream_Read_UINT16(s, create_nine_grid_bitmap->bitmapId); /* bitmapId (2 bytes) */ @@ -2734,7 +2734,7 @@ BOOL update_read_stream_bitmap_first_order(wStream* s, STREAM_BITMAP_FIRST_ORDER Stream_Read_UINT8(s, stream_bitmap_first->bitmapBpp); /* bitmapBpp (1 byte) */ if ((stream_bitmap_first->bitmapBpp < 1) || (stream_bitmap_first->bitmapBpp > 32)) { - fprintf(stderr, "%s: invalid bpp value %d", __FUNCTION__, stream_bitmap_first->bitmapBpp); + DEBUG_WARN( "%s: invalid bpp value %d", __FUNCTION__, stream_bitmap_first->bitmapBpp); return FALSE; } @@ -3076,7 +3076,7 @@ BOOL update_recv_primary_order(rdpUpdate* update, wStream* s, BYTE flags) if (orderInfo->orderType >= PRIMARY_DRAWING_ORDER_COUNT) { - fprintf(stderr, "Invalid Primary Drawing Order (0x%02X)\n", orderInfo->orderType); + DEBUG_WARN( "Invalid Primary Drawing Order (0x%02X)\n", orderInfo->orderType); return FALSE; } @@ -3098,7 +3098,7 @@ BOOL update_recv_primary_order(rdpUpdate* update, wStream* s, BYTE flags) orderInfo->deltaCoordinates = (flags & ORDER_DELTA_COORDINATES) ? TRUE : FALSE; #ifdef WITH_DEBUG_ORDERS - fprintf(stderr, "%s Primary Drawing Order (0x%02X)\n", PRIMARY_DRAWING_ORDER_STRINGS[orderInfo->orderType], orderInfo->orderType); + DEBUG_WARN( "%s Primary Drawing Order (0x%02X)\n", PRIMARY_DRAWING_ORDER_STRINGS[orderInfo->orderType], orderInfo->orderType); #endif switch (orderInfo->orderType) @@ -3289,9 +3289,9 @@ BOOL update_recv_secondary_order(rdpUpdate* update, wStream* s, BYTE flags) #ifdef WITH_DEBUG_ORDERS if (orderType < SECONDARY_DRAWING_ORDER_COUNT) - fprintf(stderr, "%s Secondary Drawing Order (0x%02X)\n", SECONDARY_DRAWING_ORDER_STRINGS[orderType], orderType); + DEBUG_WARN( "%s Secondary Drawing Order (0x%02X)\n", SECONDARY_DRAWING_ORDER_STRINGS[orderType], orderType); else - fprintf(stderr, "Unknown Secondary Drawing Order (0x%02X)\n", orderType); + DEBUG_WARN( "Unknown Secondary Drawing Order (0x%02X)\n", orderType); #endif switch (orderType) @@ -3381,9 +3381,9 @@ BOOL update_recv_altsec_order(rdpUpdate* update, wStream* s, BYTE flags) #ifdef WITH_DEBUG_ORDERS if (orderType < ALTSEC_DRAWING_ORDER_COUNT) - fprintf(stderr, "%s Alternate Secondary Drawing Order (0x%02X)\n", ALTSEC_DRAWING_ORDER_STRINGS[orderType], orderType); + DEBUG_WARN( "%s Alternate Secondary Drawing Order (0x%02X)\n", ALTSEC_DRAWING_ORDER_STRINGS[orderType], orderType); else - fprintf(stderr, "Unknown Alternate Secondary Drawing Order: 0x%02X\n", orderType); + DEBUG_WARN( "Unknown Alternate Secondary Drawing Order: 0x%02X\n", orderType); #endif switch (orderType) diff --git a/libfreerdp/core/peer.c b/libfreerdp/core/peer.c index 8b5ac3ce9..e2f3f48f2 100644 --- a/libfreerdp/core/peer.c +++ b/libfreerdp/core/peer.c @@ -36,27 +36,28 @@ extern const char* DATA_PDU_TYPE_STRINGS[80]; static BOOL freerdp_peer_initialize(freerdp_peer* client) { - rdpRdp *rdp = client->context->rdp; - rdpSettings *settings = rdp->settings; + rdpRdp* rdp = client->context->rdp; + rdpSettings* settings = rdp->settings; settings->ServerMode = TRUE; settings->FrameAcknowledge = 0; settings->LocalConnection = client->local; rdp->state = CONNECTION_STATE_INITIAL; - if (settings->RdpKeyFile != NULL) + if (settings->RdpKeyFile) { settings->RdpServerRsaKey = key_new(settings->RdpKeyFile); + if (!settings->RdpServerRsaKey) { - fprintf(stderr, "%s: inavlid RDP key file %s\n", __FUNCTION__, settings->RdpKeyFile); + DEBUG_WARN( "%s: inavlid RDP key file %s\n", __FUNCTION__, settings->RdpKeyFile); return FALSE; } if (settings->RdpServerRsaKey->ModulusLength > 256) { - fprintf(stderr, "%s: Key sizes > 2048 are currently not supported for RDP security.\n", __FUNCTION__); - fprintf(stderr, "%s: Set a different key file than %s\n", __FUNCTION__, settings->RdpKeyFile); + DEBUG_WARN( "%s: Key sizes > 2048 are currently not supported for RDP security.\n", __FUNCTION__); + DEBUG_WARN( "%s: Set a different key file than %s\n", __FUNCTION__, settings->RdpKeyFile); exit(1); } } @@ -77,7 +78,6 @@ static HANDLE freerdp_peer_get_event_handle(freerdp_peer* client) return client->context->rdp->transport->TcpIn->event; } - static BOOL freerdp_peer_check_fds(freerdp_peer* peer) { int status; @@ -105,7 +105,7 @@ static BOOL peer_recv_data_pdu(freerdp_peer* client, wStream* s) return FALSE; #ifdef WITH_DEBUG_RDP - printf("recv %s Data PDU (0x%02X), length: %d\n", + DEBUG_MSG("recv %s Data PDU (0x%02X), length: %d\n", type < ARRAYSIZE(DATA_PDU_TYPE_STRINGS) ? DATA_PDU_TYPE_STRINGS[type] : "???", type, length); #endif @@ -159,7 +159,7 @@ static BOOL peer_recv_data_pdu(freerdp_peer* client, wStream* s) break; default: - fprintf(stderr, "Data PDU type %d\n", type); + DEBUG_WARN( "Data PDU type %d\n", type); break; } @@ -180,10 +180,13 @@ static int peer_recv_tpkt_pdu(freerdp_peer* client, wStream* s) if (!rdp_read_header(rdp, s, &length, &channelId)) { - fprintf(stderr, "Incorrect RDP header.\n"); + DEBUG_WARN( "Incorrect RDP header.\n"); return -1; } + if (rdp->disconnect) + return 0; + if (rdp->settings->DisableEncryption) { if (!rdp_read_security_header(s, &securityFlags)) @@ -193,7 +196,7 @@ static int peer_recv_tpkt_pdu(freerdp_peer* client, wStream* s) { if (!rdp_decrypt(rdp, s, length - 4, securityFlags)) { - fprintf(stderr, "rdp_decrypt failed\n"); + DEBUG_WARN( "rdp_decrypt failed\n"); return -1; } } @@ -224,7 +227,7 @@ static int peer_recv_tpkt_pdu(freerdp_peer* client, wStream* s) break; default: - fprintf(stderr, "Client sent pduType %d\n", pduType); + DEBUG_WARN( "Client sent pduType %d\n", pduType); return -1; } } @@ -245,7 +248,7 @@ static int peer_recv_fastpath_pdu(freerdp_peer* client, wStream* s) if ((length == 0) || (length > Stream_GetRemainingLength(s))) { - fprintf(stderr, "incorrect FastPath PDU header length %d\n", length); + DEBUG_WARN( "incorrect FastPath PDU header length %d\n", length); return -1; } @@ -384,7 +387,7 @@ static int peer_recv_callback(rdpTransport* transport, wStream* s, void* extra) break; default: - fprintf(stderr, "Invalid state %d\n", rdp->state); + DEBUG_WARN( "Invalid state %d\n", rdp->state); return -1; } @@ -431,7 +434,7 @@ void freerdp_peer_context_new(freerdp_peer* client) { rdpRdp* rdp; - client->context = (rdpContext *)calloc(1, client->ContextSize); + client->context = (rdpContext*) calloc(1, client->ContextSize); client->context->ServerMode = TRUE; diff --git a/libfreerdp/core/rdp.c b/libfreerdp/core/rdp.c index 0059f8b4d..170b93b60 100644 --- a/libfreerdp/core/rdp.c +++ b/libfreerdp/core/rdp.c @@ -320,7 +320,7 @@ BOOL rdp_read_header(rdpRdp* rdp, wStream* s, UINT16* length, UINT16* channelId) rdp_set_error_info(rdp, ERRINFO_RPC_INITIATED_DISCONNECT); } - fprintf(stderr, "DisconnectProviderUltimatum: reason: %d\n", reason); + DEBUG_WARN( "DisconnectProviderUltimatum: reason: %d\n", reason); rdp->disconnect = TRUE; @@ -731,7 +731,7 @@ int rdp_recv_data_pdu(rdpRdp* rdp, wStream* s) if (Stream_GetRemainingLength(s) < (size_t) SrcSize) { - fprintf(stderr, "bulk_decompress: not enough bytes for compressedLength %d\n", compressedLength); + DEBUG_WARN( "bulk_decompress: not enough bytes for compressedLength %d\n", compressedLength); return -1; } @@ -746,7 +746,7 @@ int rdp_recv_data_pdu(rdpRdp* rdp, wStream* s) } else { - fprintf(stderr, "bulk_decompress() failed\n"); + DEBUG_WARN( "bulk_decompress() failed\n"); return -1; } @@ -754,7 +754,7 @@ int rdp_recv_data_pdu(rdpRdp* rdp, wStream* s) } #ifdef WITH_DEBUG_RDP - printf("recv %s Data PDU (0x%02X), length: %d\n", + DEBUG_MSG("recv %s Data PDU (0x%02X), length: %d\n", type < ARRAYSIZE(DATA_PDU_TYPE_STRINGS) ? DATA_PDU_TYPE_STRINGS[type] : "???", type, length); #endif @@ -923,13 +923,13 @@ BOOL rdp_decrypt(rdpRdp* rdp, wStream* s, int length, UINT16 securityFlags) if (!security_fips_decrypt(Stream_Pointer(s), length, rdp)) { - fprintf(stderr, "FATAL: cannot decrypt\n"); + DEBUG_WARN( "FATAL: cannot decrypt\n"); return FALSE; /* TODO */ } if (!security_fips_check_signature(Stream_Pointer(s), length - pad, sig, rdp)) { - fprintf(stderr, "FATAL: invalid packet signature\n"); + DEBUG_WARN( "FATAL: invalid packet signature\n"); return FALSE; /* TODO */ } @@ -953,7 +953,7 @@ BOOL rdp_decrypt(rdpRdp* rdp, wStream* s, int length, UINT16 securityFlags) if (memcmp(wmac, cmac, sizeof(wmac)) != 0) { - fprintf(stderr, "WARNING: invalid packet signature\n"); + DEBUG_WARN( "WARNING: invalid packet signature\n"); /* * Because Standard RDP Security is totally broken, * and cannot protect against MITM, don't treat signature @@ -985,10 +985,13 @@ static int rdp_recv_tpkt_pdu(rdpRdp* rdp, wStream* s) if (!rdp_read_header(rdp, s, &length, &channelId)) { - fprintf(stderr, "Incorrect RDP header.\n"); + DEBUG_WARN( "Incorrect RDP header.\n"); return -1; } + if (rdp->disconnect) + return 0; + if (rdp->settings->DisableEncryption) { if (!rdp_read_security_header(s, &securityFlags)) @@ -998,7 +1001,7 @@ static int rdp_recv_tpkt_pdu(rdpRdp* rdp, wStream* s) { if (!rdp_decrypt(rdp, s, length - 4, securityFlags)) { - fprintf(stderr, "rdp_decrypt failed\n"); + DEBUG_WARN( "rdp_decrypt failed\n"); return -1; } } @@ -1033,7 +1036,7 @@ static int rdp_recv_tpkt_pdu(rdpRdp* rdp, wStream* s) case PDU_TYPE_DATA: if (rdp_recv_data_pdu(rdp, s) < 0) { - fprintf(stderr, "rdp_recv_data_pdu failed\n"); + DEBUG_WARN( "rdp_recv_data_pdu failed\n"); return -1; } break; @@ -1048,7 +1051,7 @@ static int rdp_recv_tpkt_pdu(rdpRdp* rdp, wStream* s) break; default: - fprintf(stderr, "incorrect PDU type: 0x%04X\n", pduType); + DEBUG_WARN( "incorrect PDU type: 0x%04X\n", pduType); break; } @@ -1080,7 +1083,7 @@ static int rdp_recv_fastpath_pdu(rdpRdp* rdp, wStream* s) if ((length == 0) || (length > Stream_GetRemainingLength(s))) { - fprintf(stderr, "incorrect FastPath PDU header length %d\n", length); + DEBUG_WARN( "incorrect FastPath PDU header length %d\n", length); return -1; } @@ -1158,7 +1161,7 @@ static int rdp_recv_callback(rdpTransport* transport, wStream* s, void* extra) break; default: - fprintf(stderr, "Invalid state %d\n", rdp->state); + DEBUG_WARN( "Invalid state %d\n", rdp->state); status = -1; break; } diff --git a/libfreerdp/core/redirection.c b/libfreerdp/core/redirection.c index 37470d580..dfce3c10e 100644 --- a/libfreerdp/core/redirection.c +++ b/libfreerdp/core/redirection.c @@ -29,36 +29,36 @@ void rdp_print_redirection_flags(UINT32 flags) { - fprintf(stderr, "redirectionFlags = {\n"); + DEBUG_WARN( "redirectionFlags = {\n"); if (flags & LB_TARGET_NET_ADDRESS) - fprintf(stderr, "\tLB_TARGET_NET_ADDRESS\n"); + DEBUG_WARN( "\tLB_TARGET_NET_ADDRESS\n"); if (flags & LB_LOAD_BALANCE_INFO) - fprintf(stderr, "\tLB_LOAD_BALANCE_INFO\n"); + DEBUG_WARN( "\tLB_LOAD_BALANCE_INFO\n"); if (flags & LB_USERNAME) - fprintf(stderr, "\tLB_USERNAME\n"); + DEBUG_WARN( "\tLB_USERNAME\n"); if (flags & LB_DOMAIN) - fprintf(stderr, "\tLB_DOMAIN\n"); + DEBUG_WARN( "\tLB_DOMAIN\n"); if (flags & LB_PASSWORD) - fprintf(stderr, "\tLB_PASSWORD\n"); + DEBUG_WARN( "\tLB_PASSWORD\n"); if (flags & LB_DONTSTOREUSERNAME) - fprintf(stderr, "\tLB_DONTSTOREUSERNAME\n"); + DEBUG_WARN( "\tLB_DONTSTOREUSERNAME\n"); if (flags & LB_SMARTCARD_LOGON) - fprintf(stderr, "\tLB_SMARTCARD_LOGON\n"); + DEBUG_WARN( "\tLB_SMARTCARD_LOGON\n"); if (flags & LB_NOREDIRECT) - fprintf(stderr, "\tLB_NOREDIRECT\n"); + DEBUG_WARN( "\tLB_NOREDIRECT\n"); if (flags & LB_TARGET_FQDN) - fprintf(stderr, "\tLB_TARGET_FQDN\n"); + DEBUG_WARN( "\tLB_TARGET_FQDN\n"); if (flags & LB_TARGET_NETBIOS_NAME) - fprintf(stderr, "\tLB_TARGET_NETBIOS_NAME\n"); + DEBUG_WARN( "\tLB_TARGET_NETBIOS_NAME\n"); if (flags & LB_TARGET_NET_ADDRESSES) - fprintf(stderr, "\tLB_TARGET_NET_ADDRESSES\n"); + DEBUG_WARN( "\tLB_TARGET_NET_ADDRESSES\n"); if (flags & LB_CLIENT_TSV_URL) - fprintf(stderr, "\tLB_CLIENT_TSV_URL\n"); + DEBUG_WARN( "\tLB_CLIENT_TSV_URL\n"); if (flags & LB_SERVER_TSV_CAPABLE) - fprintf(stderr, "\tLB_SERVER_TSV_CAPABLE\n"); + DEBUG_WARN( "\tLB_SERVER_TSV_CAPABLE\n"); - fprintf(stderr, "}\n"); + DEBUG_WARN( "}\n"); } BOOL rdp_redirection_read_string(wStream* s, char** str) @@ -67,7 +67,7 @@ BOOL rdp_redirection_read_string(wStream* s, char** str) if (Stream_GetRemainingLength(s) < 4) { - fprintf(stderr, "rdp_redirection_read_string failure: cannot read length\n"); + DEBUG_WARN( "rdp_redirection_read_string failure: cannot read length\n"); return FALSE; } @@ -75,7 +75,7 @@ BOOL rdp_redirection_read_string(wStream* s, char** str) if (Stream_GetRemainingLength(s) < length) { - fprintf(stderr, "rdp_redirection_read_string failure: incorrect length %d\n", length); + DEBUG_WARN( "rdp_redirection_read_string failure: incorrect length %d\n", length); return FALSE; } diff --git a/libfreerdp/core/security.c b/libfreerdp/core/security.c index ccc6344f0..4bd8427c9 100644 --- a/libfreerdp/core/security.c +++ b/libfreerdp/core/security.c @@ -132,7 +132,7 @@ static void security_salted_hash(const BYTE* salt, const BYTE* input, int length sha1 = crypto_sha1_init(); if (!sha1) { - fprintf(stderr, "%s: unable to allocate a sha1\n", __FUNCTION__); + DEBUG_WARN( "%s: unable to allocate a sha1\n", __FUNCTION__); return; } crypto_sha1_update(sha1, input, length); /* Input */ @@ -145,7 +145,7 @@ static void security_salted_hash(const BYTE* salt, const BYTE* input, int length md5 = crypto_md5_init(); if (!md5) { - fprintf(stderr, "%s: unable to allocate a md5\n", __FUNCTION__); + DEBUG_WARN( "%s: unable to allocate a md5\n", __FUNCTION__); return; } crypto_md5_update(md5, salt, 48); /* Salt (48 bytes) */ @@ -198,7 +198,7 @@ void security_md5_16_32_32(const BYTE* in0, const BYTE* in1, const BYTE* in2, BY md5 = crypto_md5_init(); if (!md5) { - fprintf(stderr, "%s: unable to allocate a md5\n", __FUNCTION__); + DEBUG_WARN( "%s: unable to allocate a md5\n", __FUNCTION__); return; } crypto_md5_update(md5, in0, 16); @@ -238,7 +238,7 @@ void security_mac_data(const BYTE* mac_salt_key, const BYTE* data, UINT32 length sha1 = crypto_sha1_init(); if (!sha1) { - fprintf(stderr, "%s: unable to allocate a sha1\n", __FUNCTION__); + DEBUG_WARN( "%s: unable to allocate a sha1\n", __FUNCTION__); return; } crypto_sha1_update(sha1, mac_salt_key, 16); /* MacSaltKey */ @@ -251,7 +251,7 @@ void security_mac_data(const BYTE* mac_salt_key, const BYTE* data, UINT32 length md5 = crypto_md5_init(); if (!md5) { - fprintf(stderr, "%s: unable to allocate a md5\n", __FUNCTION__); + DEBUG_WARN( "%s: unable to allocate a md5\n", __FUNCTION__); return; } crypto_md5_update(md5, mac_salt_key, 16); /* MacSaltKey */ @@ -274,7 +274,7 @@ void security_mac_signature(rdpRdp *rdp, const BYTE* data, UINT32 length, BYTE* sha1 = crypto_sha1_init(); if (!sha1) { - fprintf(stderr, "%s: unable to allocate a sha1\n", __FUNCTION__); + DEBUG_WARN( "%s: unable to allocate a sha1\n", __FUNCTION__); return; } crypto_sha1_update(sha1, rdp->sign_key, rdp->rc4_key_len); /* MacKeyN */ @@ -287,7 +287,7 @@ void security_mac_signature(rdpRdp *rdp, const BYTE* data, UINT32 length, BYTE* md5 = crypto_md5_init(); if (!md5) { - fprintf(stderr, "%s: unable to allocate a md5\n", __FUNCTION__); + DEBUG_WARN( "%s: unable to allocate a md5\n", __FUNCTION__); return; } crypto_md5_update(md5, rdp->sign_key, rdp->rc4_key_len); /* MacKeyN */ @@ -327,7 +327,7 @@ void security_salted_mac_signature(rdpRdp *rdp, const BYTE* data, UINT32 length, sha1 = crypto_sha1_init(); if (!sha1) { - fprintf(stderr, "%s: unable to allocate a sha1\n", __FUNCTION__); + DEBUG_WARN( "%s: unable to allocate a sha1\n", __FUNCTION__); return; } crypto_sha1_update(sha1, rdp->sign_key, rdp->rc4_key_len); /* MacKeyN */ @@ -341,7 +341,7 @@ void security_salted_mac_signature(rdpRdp *rdp, const BYTE* data, UINT32 length, md5 = crypto_md5_init(); if (!md5) { - fprintf(stderr, "%s: unable to allocate a md5\n", __FUNCTION__); + DEBUG_WARN( "%s: unable to allocate a md5\n", __FUNCTION__); return; } crypto_md5_update(md5, rdp->sign_key, rdp->rc4_key_len); /* MacKeyN */ @@ -419,12 +419,12 @@ BOOL security_establish_keys(const BYTE* client_random, rdpRdp* rdp) BYTE client_encrypt_key_t[CRYPTO_SHA1_DIGEST_LENGTH + 1]; BYTE client_decrypt_key_t[CRYPTO_SHA1_DIGEST_LENGTH + 1]; - fprintf(stderr, "FIPS Compliant encryption level.\n"); + DEBUG_WARN( "FIPS Compliant encryption level.\n"); sha1 = crypto_sha1_init(); if (!sha1) { - fprintf(stderr, "%s: unable to allocate a sha1\n", __FUNCTION__); + DEBUG_WARN( "%s: unable to allocate a sha1\n", __FUNCTION__); return FALSE; } crypto_sha1_update(sha1, client_random + 16, 16); @@ -435,7 +435,7 @@ BOOL security_establish_keys(const BYTE* client_random, rdpRdp* rdp) sha1 = crypto_sha1_init(); if (!sha1) { - fprintf(stderr, "%s: unable to allocate a sha1\n", __FUNCTION__); + DEBUG_WARN( "%s: unable to allocate a sha1\n", __FUNCTION__); return FALSE; } crypto_sha1_update(sha1, client_random, 16); @@ -446,7 +446,7 @@ BOOL security_establish_keys(const BYTE* client_random, rdpRdp* rdp) sha1 = crypto_sha1_init(); if (!sha1) { - fprintf(stderr, "%s: unable to allocate a sha1\n", __FUNCTION__); + DEBUG_WARN( "%s: unable to allocate a sha1\n", __FUNCTION__); return FALSE; } crypto_sha1_update(sha1, client_decrypt_key_t, 20); @@ -528,7 +528,7 @@ BOOL security_key_update(BYTE* key, BYTE* update_key, int key_len, rdpRdp* rdp) sha1 = crypto_sha1_init(); if (!sha1) { - fprintf(stderr, "%s: unable to allocate a sha1\n", __FUNCTION__); + DEBUG_WARN( "%s: unable to allocate a sha1\n", __FUNCTION__); return FALSE; } crypto_sha1_update(sha1, update_key, key_len); @@ -539,7 +539,7 @@ BOOL security_key_update(BYTE* key, BYTE* update_key, int key_len, rdpRdp* rdp) md5 = crypto_md5_init(); if (!md5) { - fprintf(stderr, "%s: unable to allocate a md5\n", __FUNCTION__); + DEBUG_WARN( "%s: unable to allocate a md5\n", __FUNCTION__); return FALSE; } crypto_md5_update(md5, update_key, key_len); @@ -550,7 +550,7 @@ BOOL security_key_update(BYTE* key, BYTE* update_key, int key_len, rdpRdp* rdp) rc4 = crypto_rc4_init(key, key_len); if (!rc4) { - fprintf(stderr, "%s: unable to allocate a rc4\n", __FUNCTION__); + DEBUG_WARN( "%s: unable to allocate a rc4\n", __FUNCTION__); return FALSE; } crypto_rc4(rc4, key_len, key, key); @@ -573,7 +573,7 @@ BOOL security_encrypt(BYTE* data, int length, rdpRdp* rdp) rdp->rc4_encrypt_key = crypto_rc4_init(rdp->encrypt_key, rdp->rc4_key_len); if (!rdp->rc4_encrypt_key) { - fprintf(stderr, "%s: unable to allocate rc4 encrypt key\n", __FUNCTION__); + DEBUG_WARN( "%s: unable to allocate rc4 encrypt key\n", __FUNCTION__); return FALSE; } rdp->encrypt_use_count = 0; @@ -595,7 +595,7 @@ BOOL security_decrypt(BYTE* data, int length, rdpRdp* rdp) rdp->rc4_decrypt_key = crypto_rc4_init(rdp->decrypt_key, rdp->rc4_key_len); if (!rdp->rc4_decrypt_key) { - fprintf(stderr, "%s: unable to allocate rc4 decrypt key\n", __FUNCTION__); + DEBUG_WARN( "%s: unable to allocate rc4 decrypt key\n", __FUNCTION__); return FALSE; } diff --git a/libfreerdp/core/server.c b/libfreerdp/core/server.c index 5f128de83..6c84922d4 100644 --- a/libfreerdp/core/server.c +++ b/libfreerdp/core/server.c @@ -195,7 +195,7 @@ static void wts_read_drdynvc_data(rdpPeerChannel* channel, wStream* s, UINT32 le if (Stream_GetPosition(channel->receiveData) + length > channel->dvc_total_length) { channel->dvc_total_length = 0; - fprintf(stderr, "wts_read_drdynvc_data: incorrect fragment data, discarded.\n"); + DEBUG_WARN( "wts_read_drdynvc_data: incorrect fragment data, discarded.\n"); return; } @@ -279,7 +279,7 @@ static void wts_read_drdynvc_pdu(rdpPeerChannel* channel) break; default: - fprintf(stderr, "wts_read_drdynvc_pdu: Cmd %d not recognized.\n", Cmd); + DEBUG_WARN( "wts_read_drdynvc_pdu: Cmd %d not recognized.\n", Cmd); break; } } @@ -290,7 +290,7 @@ static void wts_read_drdynvc_pdu(rdpPeerChannel* channel) } else { - fprintf(stderr, "wts_read_drdynvc_pdu: received Cmd %d but channel is not ready.\n", Cmd); + DEBUG_WARN( "wts_read_drdynvc_pdu: received Cmd %d but channel is not ready.\n", Cmd); } } @@ -352,7 +352,7 @@ static void WTSProcessChannelData(rdpPeerChannel* channel, UINT16 channelId, BYT { if (Stream_GetPosition(channel->receiveData) != totalSize) { - fprintf(stderr, "WTSProcessChannelData: read error\n"); + DEBUG_WARN( "WTSProcessChannelData: read error\n"); } if (channel == channel->vcm->drdynvc_channel) { diff --git a/libfreerdp/core/settings.c b/libfreerdp/core/settings.c index f112ad452..3c070827d 100644 --- a/libfreerdp/core/settings.c +++ b/libfreerdp/core/settings.c @@ -321,7 +321,11 @@ rdpSettings* freerdp_settings_new(DWORD flags) settings->DrawGdiPlusEnabled = FALSE; - settings->FrameMarkerCommandEnabled = FALSE; + settings->DrawAllowSkipAlpha = TRUE; + settings->DrawAllowColorSubsampling = FALSE; + settings->DrawAllowDynamicColorFidelity = FALSE; + + settings->FrameMarkerCommandEnabled = TRUE; settings->SurfaceFrameMarkerEnabled = TRUE; settings->BitmapCacheV3Enabled = FALSE; @@ -522,6 +526,7 @@ rdpSettings* freerdp_settings_clone(rdpSettings* settings) _settings->EncryptionLevel = settings->EncryptionLevel; /* 195 */ _settings->ServerRandomLength = settings->ServerRandomLength; /* 197 */ _settings->ServerCertificateLength = settings->ServerCertificateLength; /* 199 */ + _settings->ClientRandomLength = settings->ClientRandomLength; /* 201 */ _settings->ChannelCount = settings->ChannelCount; /* 256 */ _settings->ChannelDefArraySize = settings->ChannelDefArraySize; /* 257 */ _settings->ClusterInfoFlags = settings->ClusterInfoFlags; /* 320 */ @@ -725,6 +730,18 @@ rdpSettings* freerdp_settings_clone(rdpSettings* settings) * Manual Code */ + if (_settings->ServerRandomLength) + { + _settings->ServerRandom = (BYTE*) malloc(_settings->ServerRandomLength); + CopyMemory(_settings->ServerRandom, settings->ServerRandom, _settings->ServerRandomLength); + } + + if (_settings->ClientRandomLength) + { + _settings->ClientRandom = (BYTE*) malloc(_settings->ClientRandomLength); + CopyMemory(_settings->ClientRandom, settings->ClientRandom, _settings->ClientRandomLength); + } + _settings->ChannelCount = settings->ChannelCount; _settings->ChannelDefArraySize = settings->ChannelDefArraySize; _settings->ChannelDefArray = (CHANNEL_DEF*) malloc(sizeof(CHANNEL_DEF) * settings->ChannelDefArraySize); @@ -836,7 +853,7 @@ void freerdp_settings_free(rdpSettings* settings) free(settings->ClientHostname); free(settings->ClientProductId); free(settings->ServerRandom); - if (settings->ClientRandom) free(settings->ClientRandom); + free(settings->ClientRandom); free(settings->ServerCertificate); free(settings->RdpKeyFile); certificate_free(settings->RdpServerCertificate); diff --git a/libfreerdp/core/surface.c b/libfreerdp/core/surface.c index 4a7ed716c..1019f13f9 100644 --- a/libfreerdp/core/surface.c +++ b/libfreerdp/core/surface.c @@ -40,7 +40,7 @@ static int update_recv_surfcmd_surface_bits(rdpUpdate* update, wStream* s, UINT3 Stream_Read_UINT8(s, cmd->bpp); if ((cmd->bpp < 1) || (cmd->bpp > 32)) { - fprintf(stderr, "%s: invalid bpp value %d", __FUNCTION__, cmd->bpp); + DEBUG_WARN( "%s: invalid bpp value %d", __FUNCTION__, cmd->bpp); return FALSE; } diff --git a/libfreerdp/core/tcp.c b/libfreerdp/core/tcp.c index 21a875150..66029fca8 100644 --- a/libfreerdp/core/tcp.c +++ b/libfreerdp/core/tcp.c @@ -65,6 +65,7 @@ #endif +#include #include #include #include @@ -276,7 +277,7 @@ static int transport_bio_buffered_write(BIO* bio, const char* buf, int num) */ if (buf && num && !ringbuffer_write(&tcp->xmitBuffer, (const BYTE*) buf, num)) { - fprintf(stderr, "%s: an error occured when writing(toWrite=%d)\n", __FUNCTION__, num); + DEBUG_WARN( "%s: an error occured when writing(toWrite=%d)\n", __FUNCTION__, num); return -1; } @@ -475,14 +476,14 @@ void tcp_get_mac_address(rdpTcp* tcp) if (ioctl(tcp->sockfd, SIOCGIFHWADDR, &if_req) != 0) { - fprintf(stderr, "failed to obtain MAC address\n"); + DEBUG_WARN( "failed to obtain MAC address\n"); return; } memmove((void*) mac, (void*) &if_req.ifr_ifru.ifru_hwaddr.sa_data[0], 6); #endif - /* fprintf(stderr, "MAC: %02X:%02X:%02X:%02X:%02X:%02X\n", + /* DEBUG_WARN( "MAC: %02X:%02X:%02X:%02X:%02X:%02X\n", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); */ } @@ -496,16 +497,21 @@ BOOL tcp_connect(rdpTcp* tcp, const char* hostname, int port, int timeout) return FALSE; if (hostname[0] == '/') + tcp->ipcSocket = TRUE; + + if (tcp->ipcSocket) { tcp->sockfd = freerdp_uds_connect(hostname); if (tcp->sockfd < 0) return FALSE; - tcp->socketBio = BIO_new_fd(tcp->sockfd, 1); + tcp->socketBio = BIO_new(BIO_s_simple_socket()); if (!tcp->socketBio) return FALSE; + + BIO_set_fd(tcp->socketBio, tcp->sockfd, BIO_CLOSE); } else { @@ -562,13 +568,13 @@ BOOL tcp_connect(rdpTcp* tcp, const char* hostname, int port, int timeout) } } - BIO_set_close(tcp->socketBio, BIO_NOCLOSE); + (void)BIO_set_close(tcp->socketBio, BIO_NOCLOSE); BIO_free(tcp->socketBio); tcp->socketBio = BIO_new(BIO_s_simple_socket()); if (!tcp->socketBio) - return -1; + return FALSE; BIO_set_fd(tcp->socketBio, tcp->sockfd, BIO_CLOSE); } @@ -581,8 +587,11 @@ BOOL tcp_connect(rdpTcp* tcp, const char* hostname, int port, int timeout) option_value = 1; option_len = sizeof(option_value); - if (setsockopt(tcp->sockfd, IPPROTO_TCP, TCP_NODELAY, (void*) &option_value, option_len) < 0) - fprintf(stderr, "%s: unable to set TCP_NODELAY\n", __FUNCTION__); + if (!tcp->ipcSocket) + { + if (setsockopt(tcp->sockfd, IPPROTO_TCP, TCP_NODELAY, (void*) &option_value, option_len) < 0) + fprintf(stderr, "%s: unable to set TCP_NODELAY\n", __FUNCTION__); + } /* receive buffer must be a least 32 K */ if (getsockopt(tcp->sockfd, SOL_SOCKET, SO_RCVBUF, (void*) &option_value, &option_len) == 0) @@ -594,14 +603,17 @@ BOOL tcp_connect(rdpTcp* tcp, const char* hostname, int port, int timeout) if (setsockopt(tcp->sockfd, SOL_SOCKET, SO_RCVBUF, (void*) &option_value, option_len) < 0) { - fprintf(stderr, "%s: unable to set receive buffer len\n", __FUNCTION__); + DEBUG_WARN( "%s: unable to set receive buffer len\n", __FUNCTION__); return FALSE; } } } - if (!tcp_set_keep_alive_mode(tcp)) - return FALSE; + if (!tcp->ipcSocket) + { + if (!tcp_set_keep_alive_mode(tcp)) + return FALSE; + } tcp->bufferedBio = BIO_new(BIO_s_buffered_socket()); @@ -631,7 +643,7 @@ BOOL tcp_set_blocking_mode(rdpTcp* tcp, BOOL blocking) if (flags == -1) { - fprintf(stderr, "%s: fcntl failed, %s.\n", __FUNCTION__, strerror(errno)); + DEBUG_WARN( "%s: fcntl failed, %s.\n", __FUNCTION__, strerror(errno)); return FALSE; } @@ -640,16 +652,31 @@ BOOL tcp_set_blocking_mode(rdpTcp* tcp, BOOL blocking) else fcntl(tcp->sockfd, F_SETFL, flags | O_NONBLOCK); #else - int status; - u_long arg = blocking; + /** + * ioctlsocket function: + * msdn.microsoft.com/en-ca/library/windows/desktop/ms738573/ + * + * The WSAAsyncSelect and WSAEventSelect functions automatically set a socket to nonblocking mode. + * If WSAAsyncSelect or WSAEventSelect has been issued on a socket, then any attempt to use + * ioctlsocket to set the socket back to blocking mode will fail with WSAEINVAL. + * + * To set the socket back to blocking mode, an application must first disable WSAAsyncSelect + * by calling WSAAsyncSelect with the lEvent parameter equal to zero, or disable WSAEventSelect + * by calling WSAEventSelect with the lNetworkEvents parameter equal to zero. + */ - status = ioctlsocket(tcp->sockfd, FIONBIO, &arg); + if (blocking == TRUE) + { + if (tcp->event) + WSAEventSelect(tcp->sockfd, tcp->event, 0); + } + else + { + if (!tcp->event) + tcp->event = WSACreateEvent(); - if (status != NO_ERROR) - fprintf(stderr, "ioctlsocket() failed with error: %ld\n", status); - - tcp->wsa_event = WSACreateEvent(); - WSAEventSelect(tcp->sockfd, tcp->wsa_event, FD_READ); + WSAEventSelect(tcp->sockfd, tcp->event, FD_READ); + } #endif return TRUE; @@ -666,7 +693,7 @@ BOOL tcp_set_keep_alive_mode(rdpTcp* tcp) if (setsockopt(tcp->sockfd, SOL_SOCKET, SO_KEEPALIVE, (void*) &option_value, option_len) < 0) { - perror("setsockopt() SOL_SOCKET, SO_KEEPALIVE:"); + DEBUG_WARN("setsockopt() SOL_SOCKET, SO_KEEPALIVE:"); return FALSE; } @@ -676,7 +703,7 @@ BOOL tcp_set_keep_alive_mode(rdpTcp* tcp) if (setsockopt(tcp->sockfd, IPPROTO_TCP, TCP_KEEPIDLE, (void*) &option_value, option_len) < 0) { - perror("setsockopt() IPPROTO_TCP, TCP_KEEPIDLE:"); + DEBUG_WARN("setsockopt() IPPROTO_TCP, TCP_KEEPIDLE:"); return FALSE; } #endif @@ -687,7 +714,7 @@ BOOL tcp_set_keep_alive_mode(rdpTcp* tcp) if (setsockopt(tcp->sockfd, SOL_TCP, TCP_KEEPCNT, (void *) &option_value, option_len) < 0) { - perror("setsockopt() SOL_TCP, TCP_KEEPCNT:"); + DEBUG_WARN("setsockopt() SOL_TCP, TCP_KEEPCNT:"); return FALSE; } #endif @@ -698,7 +725,7 @@ BOOL tcp_set_keep_alive_mode(rdpTcp* tcp) if (setsockopt(tcp->sockfd, SOL_TCP, TCP_KEEPINTVL, (void *) &option_value, option_len) < 0) { - perror("setsockopt() SOL_TCP, TCP_KEEPINTVL:"); + DEBUG_WARN("setsockopt() SOL_TCP, TCP_KEEPINTVL:"); return FALSE; } #endif @@ -709,7 +736,7 @@ BOOL tcp_set_keep_alive_mode(rdpTcp* tcp) option_len = sizeof(option_value); if (setsockopt(tcp->sockfd, SOL_SOCKET, SO_NOSIGPIPE, (void *) &option_value, option_len) < 0) { - perror("setsockopt() SOL_SOCKET, SO_NOSIGPIPE:"); + DEBUG_WARN("setsockopt() SOL_SOCKET, SO_NOSIGPIPE:"); } #endif return TRUE; @@ -757,14 +784,9 @@ HANDLE tcp_get_event_handle(rdpTcp* tcp) if (!tcp) return NULL; -#ifndef _WIN32 return tcp->event; -#else - return (HANDLE) tcp->wsa_event; -#endif } - int tcp_wait_read(rdpTcp* tcp, DWORD dwMilliSeconds) { int status; diff --git a/libfreerdp/core/tcp.h b/libfreerdp/core/tcp.h index 4d87e3b01..bfb0f8d00 100644 --- a/libfreerdp/core/tcp.h +++ b/libfreerdp/core/tcp.h @@ -46,12 +46,10 @@ typedef struct rdp_tcp rdpTcp; struct rdp_tcp { int sockfd; + BOOL ipcSocket; char ip_address[32]; BYTE mac_address[6]; rdpSettings* settings; -#ifdef _WIN32 - WSAEVENT wsa_event; -#endif BIO* socketBio; BIO* bufferedBio; RingBuffer xmitBuffer; diff --git a/libfreerdp/core/tpdu.c b/libfreerdp/core/tpdu.c index 310c35f52..0f49ffe29 100644 --- a/libfreerdp/core/tpdu.c +++ b/libfreerdp/core/tpdu.c @@ -24,6 +24,8 @@ #include #include +#include + #include "tpdu.h" /** @@ -130,7 +132,7 @@ BOOL tpdu_read_connection_request(wStream* s, BYTE* li) if (code != X224_TPDU_CONNECTION_REQUEST) { - fprintf(stderr, "Error: expected X224_TPDU_CONNECTION_REQUEST\n"); + DEBUG_WARN( "Error: expected X224_TPDU_CONNECTION_REQUEST\n"); return FALSE; } @@ -168,7 +170,7 @@ BOOL tpdu_read_connection_confirm(wStream* s, BYTE* li) if (code != X224_TPDU_CONNECTION_CONFIRM) { - fprintf(stderr, "Error: expected X224_TPDU_CONNECTION_CONFIRM\n"); + DEBUG_WARN( "Error: expected X224_TPDU_CONNECTION_CONFIRM: 0x%02X\n", code); return FALSE; } /* @@ -180,7 +182,7 @@ BOOL tpdu_read_connection_confirm(wStream* s, BYTE* li) */ bytes_read = (Stream_GetPosition(s) - position) - 1; - return (Stream_GetRemainingLength(s) >= (*li - bytes_read)); + return (Stream_GetRemainingLength(s) >= (size_t) (*li - bytes_read)); } /** diff --git a/libfreerdp/core/transport.c b/libfreerdp/core/transport.c index bacf194d5..a7c0c938d 100644 --- a/libfreerdp/core/transport.c +++ b/libfreerdp/core/transport.c @@ -292,7 +292,7 @@ BOOL transport_connect_tls(rdpTransport* transport) transport->frontBio = targetTls->bio; if (!transport->frontBio) { - fprintf(stderr, "%s: unable to prepend a filtering TLS bio", __FUNCTION__); + DEBUG_WARN( "%s: unable to prepend a filtering TLS bio", __FUNCTION__); return FALSE; } @@ -344,7 +344,7 @@ BOOL transport_connect_nla(rdpTransport* transport) freerdp_set_last_error(instance->context, FREERDP_ERROR_AUTHENTICATION_FAILED); } - fprintf(stderr, "Authentication failure, check credentials.\n" + DEBUG_WARN( "Authentication failure, check credentials.\n" "If credentials are valid, the NTLMSSP implementation may be to blame.\n"); transport_set_nla_mode(transport, FALSE); @@ -559,7 +559,7 @@ BOOL transport_accept_nla(rdpTransport* transport) if (credssp_authenticate(transport->credssp) < 0) { - fprintf(stderr, "client authentication failure\n"); + DEBUG_WARN( "client authentication failure\n"); transport_set_nla_mode(transport, FALSE); credssp_free(transport->credssp); @@ -643,7 +643,7 @@ int transport_read_layer(rdpTransport* transport, BYTE* data, int bytes) * requested bytes */ if (transport_wait_for_read(transport) < 0) { - fprintf(stderr, "%s: error when selecting for read\n", __FUNCTION__); + DEBUG_WARN( "%s: error when selecting for read\n", __FUNCTION__); return -1; } continue; @@ -756,7 +756,7 @@ int transport_read_pdu(rdpTransport* transport, wStream* s) } else { - fprintf(stderr, "Error reading TSRequest!\n"); + DEBUG_WARN( "Error reading TSRequest!\n"); return -1; } } @@ -780,7 +780,7 @@ int transport_read_pdu(rdpTransport* transport, wStream* s) /* min and max values according to ITU-T Rec. T.123 (01/2007) section 8 */ if (pduLength < 7 || pduLength > 0xFFFF) { - fprintf(stderr, "%s: tpkt - invalid pduLength: %d\n", __FUNCTION__, pduLength); + DEBUG_WARN( "%s: tpkt - invalid pduLength: %d\n", __FUNCTION__, pduLength); return -1; } } @@ -803,7 +803,7 @@ int transport_read_pdu(rdpTransport* transport, wStream* s) */ if (pduLength < 3 || pduLength > 0x8000) { - fprintf(stderr, "%s: fast path - invalid pduLength: %d\n", __FUNCTION__, pduLength); + DEBUG_WARN( "%s: fast path - invalid pduLength: %d\n", __FUNCTION__, pduLength); return -1; } } @@ -821,7 +821,7 @@ int transport_read_pdu(rdpTransport* transport, wStream* s) /* dump when whole PDU is read */ if (Stream_GetPosition(s) >= pduLength) { - fprintf(stderr, "Local < Remote\n"); + DEBUG_WARN( "Local < Remote\n"); winpr_HexDump(Stream_Buffer(s), pduLength); } #endif @@ -849,7 +849,7 @@ int transport_write(rdpTransport* transport, wStream* s) #ifdef WITH_DEBUG_TRANSPORT if (length > 0) { - fprintf(stderr, "Local > Remote\n"); + DEBUG_WARN( "Local > Remote\n"); winpr_HexDump(Stream_Buffer(s), length); } #endif @@ -878,7 +878,7 @@ int transport_write(rdpTransport* transport, wStream* s) if (transport_wait_for_write(transport) < 0) { - fprintf(stderr, "%s: error when selecting for write\n", __FUNCTION__); + DEBUG_WARN( "%s: error when selecting for write\n", __FUNCTION__); return -1; } continue; @@ -893,13 +893,13 @@ int transport_write(rdpTransport* transport, wStream* s) { if (transport_wait_for_write(transport) < 0) { - fprintf(stderr, "%s: error when selecting for write\n", __FUNCTION__); + DEBUG_WARN( "%s: error when selecting for write\n", __FUNCTION__); return -1; } if (!transport_bio_buffered_drain(out->bufferedBio)) { - fprintf(stderr, "%s: error when draining outputBuffer\n", __FUNCTION__); + DEBUG_WARN( "%s: error when draining outputBuffer\n", __FUNCTION__); return -1; } } @@ -928,12 +928,12 @@ void transport_get_fds(rdpTransport* transport, void** rfds, int* rcount) void* pfd; #ifdef _WIN32 - rfds[*rcount] = transport->TcpIn->wsa_event; + rfds[*rcount] = transport->TcpIn->event; (*rcount)++; if (transport->SplitInputOutput) { - rfds[*rcount] = transport->TcpOut->wsa_event; + rfds[*rcount] = transport->TcpOut->event; (*rcount)++; } #else @@ -1033,7 +1033,7 @@ int transport_check_fds(rdpTransport* transport) return -1; #ifdef _WIN32 - WSAResetEvent(transport->TcpIn->wsa_event); + WSAResetEvent(transport->TcpIn->event); #endif ResetEvent(transport->ReceiveEvent); diff --git a/libfreerdp/core/update.c b/libfreerdp/core/update.c index 9f8343d56..11ff7c0a7 100644 --- a/libfreerdp/core/update.c +++ b/libfreerdp/core/update.c @@ -164,6 +164,8 @@ BOOL update_read_bitmap_update(rdpUpdate* update, wStream* s, BITMAP_UPDATE* bit Stream_Read_UINT16(s, bitmapUpdate->number); /* numberRectangles (2 bytes) */ + WLog_Print(update->log, WLOG_DEBUG, "BitmapUpdate: %d", bitmapUpdate->number); + if (bitmapUpdate->number > bitmapUpdate->count) { UINT16 count; @@ -230,9 +232,9 @@ BOOL update_read_palette(rdpUpdate* update, wStream* s, PALETTE_UPDATE* palette_ { entry = &palette_update->entries[i]; - Stream_Read_UINT8(s, entry->blue); - Stream_Read_UINT8(s, entry->green); Stream_Read_UINT8(s, entry->red); + Stream_Read_UINT8(s, entry->green); + Stream_Read_UINT8(s, entry->blue); } return TRUE; } @@ -346,7 +348,7 @@ BOOL update_read_pointer_color(wStream* s, POINTER_COLOR_UPDATE* pointer_color, scanlineSize = ((scanlineSize + 1) / 2) * 2; if (scanlineSize * pointer_color->height != pointer_color->lengthXorMask) { - fprintf(stderr, "%s: invalid lengthXorMask: width=%d height=%d, %d instead of %d\n", __FUNCTION__, + DEBUG_WARN( "%s: invalid lengthXorMask: width=%d height=%d, %d instead of %d\n", __FUNCTION__, pointer_color->width, pointer_color->height, pointer_color->lengthXorMask, scanlineSize * pointer_color->height); return FALSE; @@ -377,7 +379,7 @@ BOOL update_read_pointer_color(wStream* s, POINTER_COLOR_UPDATE* pointer_color, scanlineSize = ((1 + scanlineSize) / 2) * 2; if (scanlineSize * pointer_color->height != pointer_color->lengthAndMask) { - fprintf(stderr, "%s: invalid lengthAndMask: %d instead of %d\n", __FUNCTION__, + DEBUG_WARN( "%s: invalid lengthAndMask: %d instead of %d\n", __FUNCTION__, pointer_color->lengthAndMask, scanlineSize * pointer_color->height); return FALSE; } @@ -405,7 +407,7 @@ BOOL update_read_pointer_new(wStream* s, POINTER_NEW_UPDATE* pointer_new) Stream_Read_UINT16(s, pointer_new->xorBpp); /* xorBpp (2 bytes) */ if ((pointer_new->xorBpp < 1) || (pointer_new->xorBpp > 32)) { - fprintf(stderr, "%s: invalid xorBpp %d\n", __FUNCTION__, pointer_new->xorBpp); + DEBUG_WARN( "%s: invalid xorBpp %d\n", __FUNCTION__, pointer_new->xorBpp); return FALSE; } return update_read_pointer_color(s, &pointer_new->colorPtrAttr, pointer_new->xorBpp); /* colorPtrAttr */ @@ -480,7 +482,7 @@ BOOL update_recv(rdpUpdate* update, wStream* s) Stream_Read_UINT16(s, updateType); /* updateType (2 bytes) */ - //printf("%s Update Data PDU\n", UPDATE_TYPE_STRINGS[updateType]); + //DEBUG_MSG("%s Update Data PDU\n", UPDATE_TYPE_STRINGS[updateType]); IFCALL(update->BeginPaint, context); @@ -568,6 +570,14 @@ void update_post_connect(rdpUpdate* update) update->initialState = FALSE; } +void update_post_disconnect(rdpUpdate* update) +{ + update->asynchronous = update->context->settings->AsyncUpdate; + + if (update->asynchronous) + update_message_proxy_free(update->proxy); +} + static void update_begin_paint(rdpContext* context) { wStream* s; @@ -604,7 +614,7 @@ static void update_end_paint(rdpContext* context) if (update->numberOrders > 0) { - fprintf(stderr, "%s: sending %d orders\n", __FUNCTION__, update->numberOrders); + DEBUG_WARN( "%s: sending %d orders\n", __FUNCTION__, update->numberOrders); fastpath_send_update_pdu(context->rdp->fastpath, FASTPATH_UPDATETYPE_ORDERS, s); } @@ -1703,9 +1713,6 @@ void update_free(rdpUpdate* update) free(update->altsec); free(update->window); - if (update->asynchronous) - update_message_proxy_free(update->proxy); - MessageQueue_Free(update->queue); free(update); diff --git a/libfreerdp/core/update.h b/libfreerdp/core/update.h index c67d04fc3..c0b266f64 100644 --- a/libfreerdp/core/update.h +++ b/libfreerdp/core/update.h @@ -44,6 +44,7 @@ void update_free_bitmap(BITMAP_UPDATE* bitmap_update); void update_reset_state(rdpUpdate* update); void update_post_connect(rdpUpdate* update); +void update_post_disconnect(rdpUpdate* update); BOOL update_read_bitmap_update(rdpUpdate* update, wStream* s, BITMAP_UPDATE* bitmapUpdate); BOOL update_read_palette(rdpUpdate* update, wStream* s, PALETTE_UPDATE* palette_update); diff --git a/libfreerdp/core/window.c b/libfreerdp/core/window.c index 2eefe2361..84c34ccc7 100644 --- a/libfreerdp/core/window.c +++ b/libfreerdp/core/window.c @@ -39,7 +39,7 @@ BOOL update_read_icon_info(wStream* s, ICON_INFO* iconInfo) Stream_Read_UINT8(s, iconInfo->bpp); /* bpp (1 byte) */ if ((iconInfo->bpp < 1) || (iconInfo->bpp > 32)) { - fprintf(stderr, "%s: invalid bpp value %d", __FUNCTION__, iconInfo->bpp); + DEBUG_WARN( "%s: invalid bpp value %d", __FUNCTION__, iconInfo->bpp); return FALSE; } diff --git a/libfreerdp/crypto/ber.c b/libfreerdp/crypto/ber.c index 74ce23190..a983849bf 100644 --- a/libfreerdp/crypto/ber.c +++ b/libfreerdp/crypto/ber.c @@ -24,6 +24,7 @@ #include #include +#include #include BOOL ber_read_length(wStream* s, int* length) @@ -399,12 +400,12 @@ BOOL ber_read_integer(wStream* s, UINT32* value) } else if (length == 8) { - fprintf(stderr, "%s: should implement reading an 8 bytes integer\n", __FUNCTION__); + DEBUG_WARN( "%s: should implement reading an 8 bytes integer\n", __FUNCTION__); return FALSE; } else { - fprintf(stderr, "%s: should implement reading an integer with length=%d\n", __FUNCTION__, length); + DEBUG_WARN( "%s: should implement reading an integer with length=%d\n", __FUNCTION__, length); return FALSE; } diff --git a/libfreerdp/crypto/certificate.c b/libfreerdp/crypto/certificate.c index d65796ace..fa9533d99 100644 --- a/libfreerdp/crypto/certificate.c +++ b/libfreerdp/crypto/certificate.c @@ -37,9 +37,10 @@ static const char certificate_store_dir[] = "certs"; static const char certificate_server_dir[] = "server"; static const char certificate_known_hosts_file[] = "known_hosts"; +#include #include -void certificate_store_init(rdpCertificateStore* certificate_store) +int certificate_store_init(rdpCertificateStore* certificate_store) { char* server_path; rdpSettings* settings; @@ -49,37 +50,46 @@ void certificate_store_init(rdpCertificateStore* certificate_store) if (!PathFileExistsA(settings->ConfigPath)) { CreateDirectoryA(settings->ConfigPath, 0); - fprintf(stderr, "creating directory %s\n", settings->ConfigPath); + DEBUG_WARN( "creating directory %s\n", settings->ConfigPath); } certificate_store->path = GetCombinedPath(settings->ConfigPath, (char*) certificate_store_dir); + if (!certificate_store->path) + return -1; + if (!PathFileExistsA(certificate_store->path)) { CreateDirectoryA(certificate_store->path, 0); - fprintf(stderr, "creating directory %s\n", certificate_store->path); + DEBUG_WARN( "creating directory %s\n", certificate_store->path); } server_path = GetCombinedPath(settings->ConfigPath, (char*) certificate_server_dir); + if (!server_path) + return -1; + if (!PathFileExistsA(server_path)) { CreateDirectoryA(server_path, 0); - fprintf(stderr, "creating directory %s\n", server_path); + DEBUG_WARN( "creating directory %s\n", server_path); } free(server_path); certificate_store->file = GetCombinedPath(settings->ConfigPath, (char*) certificate_known_hosts_file); + if (!certificate_store->file) + return -1; + if (PathFileExistsA(certificate_store->file) == FALSE) { certificate_store->fp = fopen((char*) certificate_store->file, "w+"); - if (certificate_store->fp == NULL) + if (!certificate_store->fp) { - fprintf(stderr, "certificate_store_open: error opening [%s] for writing\n", certificate_store->file); - return; + DEBUG_WARN( "certificate_store_open: error opening [%s] for writing\n", certificate_store->file); + return -1; } fflush(certificate_store->fp); @@ -88,6 +98,8 @@ void certificate_store_init(rdpCertificateStore* certificate_store) { certificate_store->fp = fopen((char*) certificate_store->file, "r+"); } + + return 1; } int certificate_data_match(rdpCertificateStore* certificate_store, rdpCertificateData* certificate_data) @@ -264,14 +276,14 @@ rdpCertificateStore* certificate_store_new(rdpSettings* settings) { rdpCertificateStore* certificate_store; - certificate_store = (rdpCertificateStore *)calloc(1, sizeof(rdpCertificateStore)); + certificate_store = (rdpCertificateStore*) calloc(1, sizeof(rdpCertificateStore)); if (!certificate_store) return NULL; certificate_store->settings = settings; + certificate_store_init(certificate_store); - /* TODO: certificate_store_init should not fail silently */ return certificate_store; } diff --git a/libfreerdp/crypto/crypto.c b/libfreerdp/crypto/crypto.c index b3d3fbb21..b75e4eb6a 100644 --- a/libfreerdp/crypto/crypto.c +++ b/libfreerdp/crypto/crypto.c @@ -23,6 +23,7 @@ #include +#include #include CryptoSha1 crypto_sha1_init(void) @@ -202,7 +203,7 @@ BOOL crypto_cert_get_public_key(CryptoCert cert, BYTE** PublicKey, DWORD* Public pkey = X509_get_pubkey(cert->px509); if (!pkey) { - fprintf(stderr, "%s: X509_get_pubkey() failed\n", __FUNCTION__); + DEBUG_WARN( "%s: X509_get_pubkey() failed\n", __FUNCTION__); status = FALSE; goto exit; } @@ -210,7 +211,7 @@ BOOL crypto_cert_get_public_key(CryptoCert cert, BYTE** PublicKey, DWORD* Public length = i2d_PublicKey(pkey, NULL); if (length < 1) { - fprintf(stderr, "%s: i2d_PublicKey() failed\n", __FUNCTION__); + DEBUG_WARN( "%s: i2d_PublicKey() failed\n", __FUNCTION__); status = FALSE; goto exit; } @@ -569,15 +570,15 @@ void crypto_cert_print_info(X509* xcert) fp = crypto_cert_fingerprint(xcert); if (!fp) { - fprintf(stderr, "%s: error computing fingerprint\n", __FUNCTION__); + DEBUG_WARN( "%s: error computing fingerprint\n", __FUNCTION__); goto out_free_issuer; } - fprintf(stderr, "Certificate details:\n"); - fprintf(stderr, "\tSubject: %s\n", subject); - fprintf(stderr, "\tIssuer: %s\n", issuer); - fprintf(stderr, "\tThumbprint: %s\n", fp); - fprintf(stderr, "The above X.509 certificate could not be verified, possibly because you do not have " + DEBUG_WARN( "Certificate details:\n"); + DEBUG_WARN( "\tSubject: %s\n", subject); + DEBUG_WARN( "\tIssuer: %s\n", issuer); + DEBUG_WARN( "\tThumbprint: %s\n", fp); + DEBUG_WARN( "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"); diff --git a/libfreerdp/crypto/tls.c b/libfreerdp/crypto/tls.c index fd857b9b0..b48a1d024 100644 --- a/libfreerdp/crypto/tls.c +++ b/libfreerdp/crypto/tls.c @@ -31,6 +31,7 @@ #include #include +#include #include #include "../core/tcp.h" @@ -510,7 +511,7 @@ static CryptoCert tls_get_certificate(rdpTls* tls, BOOL peer) if (!remote_cert) { - fprintf(stderr, "%s: failed to get the server TLS certificate\n", __FUNCTION__); + DEBUG_WARN( "%s: failed to get the server TLS certificate\n", __FUNCTION__); return NULL; } @@ -583,7 +584,7 @@ BOOL tls_prepare(rdpTls* tls, BIO *underlying, const SSL_METHOD *method, int opt tls->ctx = SSL_CTX_new(method); if (!tls->ctx) { - fprintf(stderr, "%s: SSL_CTX_new failed\n", __FUNCTION__); + DEBUG_WARN( "%s: SSL_CTX_new failed\n", __FUNCTION__); return FALSE; } @@ -594,7 +595,7 @@ BOOL tls_prepare(rdpTls* tls, BIO *underlying, const SSL_METHOD *method, int opt if (tls->settings->PermittedTLSCiphers) { if(!SSL_CTX_set_cipher_list(tls->ctx, tls->settings->PermittedTLSCiphers)) { - fprintf(stderr, "SSL_CTX_set_cipher_list %s failed\n", tls->settings->PermittedTLSCiphers); + DEBUG_WARN( "SSL_CTX_set_cipher_list %s failed\n", tls->settings->PermittedTLSCiphers); return FALSE; } } @@ -603,7 +604,7 @@ BOOL tls_prepare(rdpTls* tls, BIO *underlying, const SSL_METHOD *method, int opt if (BIO_get_ssl(tls->bio, &tls->ssl) < 0) { - fprintf(stderr, "%s: unable to retrieve the SSL of the connection\n", __FUNCTION__); + DEBUG_WARN( "%s: unable to retrieve the SSL of the connection\n", __FUNCTION__); return FALSE; } @@ -641,7 +642,7 @@ int tls_do_handshake(rdpTls* tls, BOOL clientMode) if (fd < 0) { - fprintf(stderr, "%s: unable to retrieve BIO fd\n", __FUNCTION__); + DEBUG_WARN( "%s: unable to retrieve BIO fd\n", __FUNCTION__); return -1; } @@ -665,7 +666,7 @@ int tls_do_handshake(rdpTls* tls, BOOL clientMode) #endif if (status < 0) { - fprintf(stderr, "%s: error during select()\n", __FUNCTION__); + DEBUG_WARN( "%s: error during select()\n", __FUNCTION__); return -1; } } @@ -674,21 +675,21 @@ int tls_do_handshake(rdpTls* tls, BOOL clientMode) cert = tls_get_certificate(tls, clientMode); if (!cert) { - fprintf(stderr, "%s: tls_get_certificate failed to return the server certificate.\n", __FUNCTION__); + DEBUG_WARN( "%s: tls_get_certificate failed to return the server certificate.\n", __FUNCTION__); return -1; } tls->Bindings = tls_get_channel_bindings(cert->px509); if (!tls->Bindings) { - fprintf(stderr, "%s: unable to retrieve bindings\n", __FUNCTION__); + DEBUG_WARN( "%s: unable to retrieve bindings\n", __FUNCTION__); verify_status = -1; goto out; } if (!crypto_cert_get_public_key(cert, &tls->PublicKey, &tls->PublicKeyLength)) { - fprintf(stderr, "%s: crypto_cert_get_public_key failed to return the server public key.\n", __FUNCTION__); + DEBUG_WARN( "%s: crypto_cert_get_public_key failed to return the server public key.\n", __FUNCTION__); verify_status = -1; goto out; } @@ -703,7 +704,7 @@ int tls_do_handshake(rdpTls* tls, BOOL clientMode) if (verify_status < 1) { - fprintf(stderr, "%s: certificate not trusted, aborting.\n", __FUNCTION__); + DEBUG_WARN( "%s: certificate not trusted, aborting.\n", __FUNCTION__); tls_disconnect(tls); verify_status = 0; } @@ -802,14 +803,14 @@ BOOL tls_accept(rdpTls* tls, BIO *underlying, const char* cert_file, const char* if (SSL_use_RSAPrivateKey_file(tls->ssl, privatekey_file, SSL_FILETYPE_PEM) <= 0) { - fprintf(stderr, "%s: SSL_CTX_use_RSAPrivateKey_file failed\n", __FUNCTION__); - fprintf(stderr, "PrivateKeyFile: %s\n", privatekey_file); + DEBUG_WARN( "%s: SSL_CTX_use_RSAPrivateKey_file failed\n", __FUNCTION__); + DEBUG_WARN( "PrivateKeyFile: %s\n", privatekey_file); return FALSE; } if (SSL_use_certificate_file(tls->ssl, cert_file, SSL_FILETYPE_PEM) <= 0) { - fprintf(stderr, "%s: SSL_use_certificate_file failed\n", __FUNCTION__); + DEBUG_WARN( "%s: SSL_use_certificate_file failed\n", __FUNCTION__); return FALSE; } @@ -891,7 +892,7 @@ int tls_write_all(rdpTls* tls, const BYTE* data, int length) if (!bufferedBio) { - fprintf(stderr, "%s: error unable to retrieve the bufferedBio in the BIO chain\n", __FUNCTION__); + DEBUG_WARN( "%s: error unable to retrieve the bufferedBio in the BIO chain\n", __FUNCTION__); return -1; } @@ -921,7 +922,7 @@ int tls_write_all(rdpTls* tls, const BYTE* data, int length) } else { - fprintf(stderr, "%s: weird we're blocked but the underlying is not read or write blocked !\n", __FUNCTION__); + DEBUG_WARN( "%s: weird we're blocked but the underlying is not read or write blocked !\n", __FUNCTION__); USleep(10); continue; } @@ -949,7 +950,7 @@ int tls_write_all(rdpTls* tls, const BYTE* data, int length) } else { - fprintf(stderr, "%s: weird we're blocked but the underlying is not read or write blocked !\n", __FUNCTION__); + DEBUG_WARN( "%s: weird we're blocked but the underlying is not read or write blocked !\n", __FUNCTION__); USleep(10); continue; } @@ -1080,7 +1081,7 @@ int tls_verify_certificate(rdpTls* tls, CryptoCert cert, char* hostname, int por if (!bio) { - fprintf(stderr, "%s: BIO_new() failure\n", __FUNCTION__); + DEBUG_WARN( "%s: BIO_new() failure\n", __FUNCTION__); return -1; } @@ -1088,7 +1089,7 @@ int tls_verify_certificate(rdpTls* tls, CryptoCert cert, char* hostname, int por if (status < 0) { - fprintf(stderr, "%s: PEM_write_bio_X509 failure: %d\n", __FUNCTION__, status); + DEBUG_WARN( "%s: PEM_write_bio_X509 failure: %d\n", __FUNCTION__, status); return -1; } @@ -1100,7 +1101,7 @@ int tls_verify_certificate(rdpTls* tls, CryptoCert cert, char* hostname, int por if (status < 0) { - fprintf(stderr, "%s: failed to read certificate\n", __FUNCTION__); + DEBUG_WARN( "%s: failed to read certificate\n", __FUNCTION__); return -1; } @@ -1121,7 +1122,7 @@ int tls_verify_certificate(rdpTls* tls, CryptoCert cert, char* hostname, int por if (status < 0) { - fprintf(stderr, "%s: failed to read certificate\n", __FUNCTION__); + DEBUG_WARN( "%s: failed to read certificate\n", __FUNCTION__); return -1; } @@ -1135,7 +1136,7 @@ int tls_verify_certificate(rdpTls* tls, CryptoCert cert, char* hostname, int por status = instance->VerifyX509Certificate(instance, pemCert, length, hostname, port, tls->isGatewayTransport); } - fprintf(stderr, "%s: (length = %d) status: %d\n%s\n", __FUNCTION__, length, status, pemCert); + DEBUG_WARN( "%s: (length = %d) status: %d\n%s\n", __FUNCTION__, length, status, pemCert); free(pemCert); BIO_free(bio); @@ -1295,18 +1296,18 @@ int tls_verify_certificate(rdpTls* tls, CryptoCert cert, char* hostname, int por void tls_print_certificate_error(char* hostname, char* fingerprint, char *hosts_file) { - fprintf(stderr, "The host key for %s has changed\n", hostname); - fprintf(stderr, "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n"); - fprintf(stderr, "@ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @\n"); - fprintf(stderr, "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n"); - fprintf(stderr, "IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!\n"); - fprintf(stderr, "Someone could be eavesdropping on you right now (man-in-the-middle attack)!\n"); - fprintf(stderr, "It is also possible that a host key has just been changed.\n"); - fprintf(stderr, "The fingerprint for the host key sent by the remote host is\n%s\n", fingerprint); - fprintf(stderr, "Please contact your system administrator.\n"); - fprintf(stderr, "Add correct host key in %s to get rid of this message.\n", hosts_file); - fprintf(stderr, "Host key for %s has changed and you have requested strict checking.\n", hostname); - fprintf(stderr, "Host key verification failed.\n"); + DEBUG_WARN( "The host key for %s has changed\n", hostname); + DEBUG_WARN( "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n"); + DEBUG_WARN( "@ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @\n"); + DEBUG_WARN( "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n"); + DEBUG_WARN( "IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!\n"); + DEBUG_WARN( "Someone could be eavesdropping on you right now (man-in-the-middle attack)!\n"); + DEBUG_WARN( "It is also possible that a host key has just been changed.\n"); + DEBUG_WARN( "The fingerprint for the host key sent by the remote host is\n%s\n", fingerprint); + DEBUG_WARN( "Please contact your system administrator.\n"); + DEBUG_WARN( "Add correct host key in %s to get rid of this message.\n", hosts_file); + DEBUG_WARN( "Host key for %s has changed and you have requested strict checking.\n", hostname); + DEBUG_WARN( "Host key verification failed.\n"); } void tls_print_certificate_name_mismatch_error(char* hostname, char* common_name, char** alt_names, int alt_names_count) @@ -1315,24 +1316,24 @@ void tls_print_certificate_name_mismatch_error(char* hostname, char* common_name assert(NULL != hostname); - fprintf(stderr, "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n"); - fprintf(stderr, "@ WARNING: CERTIFICATE NAME MISMATCH! @\n"); - fprintf(stderr, "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n"); - fprintf(stderr, "The hostname used for this connection (%s) \n", hostname); - fprintf(stderr, "does not match %s given in the certificate:\n", alt_names_count < 1 ? "the name" : "any of the names"); - fprintf(stderr, "Common Name (CN):\n"); - fprintf(stderr, "\t%s\n", common_name ? common_name : "no CN found in certificate"); + DEBUG_WARN( "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n"); + DEBUG_WARN( "@ WARNING: CERTIFICATE NAME MISMATCH! @\n"); + DEBUG_WARN( "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n"); + DEBUG_WARN( "The hostname used for this connection (%s) \n", hostname); + DEBUG_WARN( "does not match %s given in the certificate:\n", alt_names_count < 1 ? "the name" : "any of the names"); + DEBUG_WARN( "Common Name (CN):\n"); + DEBUG_WARN( "\t%s\n", common_name ? common_name : "no CN found in certificate"); if (alt_names_count > 0) { assert(NULL != alt_names); - fprintf(stderr, "Alternative names:\n"); + DEBUG_WARN( "Alternative names:\n"); for (index = 0; index < alt_names_count; index++) { assert(alt_names[index]); - fprintf(stderr, "\t %s\n", alt_names[index]); + DEBUG_WARN( "\t %s\n", alt_names[index]); } } - fprintf(stderr, "A valid certificate for the wrong name should NOT be trusted!\n"); + DEBUG_WARN( "A valid certificate for the wrong name should NOT be trusted!\n"); } rdpTls* tls_new(rdpSettings* settings) @@ -1347,10 +1348,14 @@ rdpTls* tls_new(rdpSettings* settings) winpr_InitializeSSL(WINPR_SSL_INIT_DEFAULT); tls->settings = settings; - tls->certificate_store = certificate_store_new(settings); - if (!tls->certificate_store) - goto out_free; + if (!settings->ServerMode) + { + tls->certificate_store = certificate_store_new(settings); + + if (!tls->certificate_store) + goto out_free; + } tls->alertLevel = TLS_ALERT_LEVEL_WARNING; tls->alertDescription = TLS_ALERT_DESCRIPTION_CLOSE_NOTIFY; @@ -1386,8 +1391,11 @@ void tls_free(rdpTls* tls) tls->Bindings = NULL; } - certificate_store_free(tls->certificate_store); - tls->certificate_store = NULL; + if (tls->certificate_store) + { + certificate_store_free(tls->certificate_store); + tls->certificate_store = NULL; + } free(tls); } diff --git a/libfreerdp/gdi/16bpp.c b/libfreerdp/gdi/16bpp.c index 3f96425e6..fb9dfd26c 100644 --- a/libfreerdp/gdi/16bpp.c +++ b/libfreerdp/gdi/16bpp.c @@ -43,7 +43,7 @@ UINT16 gdi_get_color_16bpp(HGDI_DC hdc, GDI_COLOR color) BYTE r, g, b; UINT16 color16; - GetBGR32(r, g, b, color); + GetRGB32(r, g, b, color); if (hdc->rgb555) { @@ -412,7 +412,7 @@ static int BitBlt_DSPDxax_16bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWi if (hdcSrc->bytesPerPixel != 1) { - fprintf(stderr, "BitBlt_DSPDxax expects 1 bpp, unimplemented for %d\n", hdcSrc->bytesPerPixel); + DEBUG_WARN( "BitBlt_DSPDxax expects 1 bpp, unimplemented for %d\n", hdcSrc->bytesPerPixel); return 0; } @@ -894,7 +894,7 @@ int BitBlt_16bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeigh break; } - fprintf(stderr, "BitBlt: unknown rop: 0x%08X\n", rop); + DEBUG_WARN( "BitBlt: unknown rop: 0x%08X\n", rop); return 1; } @@ -939,7 +939,7 @@ int PatBlt_16bpp(HGDI_DC hdc, int nXLeft, int nYLeft, int nWidth, int nHeight, i break; } - fprintf(stderr, "PatBlt: unknown rop: 0x%08X\n", rop); + DEBUG_WARN( "PatBlt: unknown rop: 0x%08X\n", rop); return 1; } diff --git a/libfreerdp/gdi/32bpp.c b/libfreerdp/gdi/32bpp.c index 33e1d19d9..ed20b675f 100644 --- a/libfreerdp/gdi/32bpp.c +++ b/libfreerdp/gdi/32bpp.c @@ -44,7 +44,7 @@ UINT32 gdi_get_color_32bpp(HGDI_DC hdc, GDI_COLOR color) BYTE a, r, g, b; a = 0xFF; - GetBGR32(r, g, b, color); + GetRGB32(r, g, b, color); if (hdc->invert) { @@ -997,7 +997,7 @@ int BitBlt_32bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeigh break; } - fprintf(stderr, "BitBlt: unknown rop: 0x%08X\n", rop); + DEBUG_WARN( "BitBlt: unknown rop: 0x%08X\n", rop); return 1; } @@ -1042,7 +1042,7 @@ int PatBlt_32bpp(HGDI_DC hdc, int nXLeft, int nYLeft, int nWidth, int nHeight, i break; } - fprintf(stderr, "PatBlt: unknown rop: 0x%08X\n", rop); + DEBUG_WARN( "PatBlt: unknown rop: 0x%08X\n", rop); return 1; } diff --git a/libfreerdp/gdi/8bpp.c b/libfreerdp/gdi/8bpp.c index 0999cedcb..85a00e7a9 100644 --- a/libfreerdp/gdi/8bpp.c +++ b/libfreerdp/gdi/8bpp.c @@ -807,7 +807,7 @@ int BitBlt_8bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight break; } - fprintf(stderr, "BitBlt: unknown rop: 0x%08X\n", rop); + DEBUG_WARN( "BitBlt: unknown rop: 0x%08X\n", rop); return 1; } @@ -852,7 +852,7 @@ int PatBlt_8bpp(HGDI_DC hdc, int nXLeft, int nYLeft, int nWidth, int nHeight, in break; } - fprintf(stderr, "PatBlt: unknown rop: 0x%08X\n", rop); + DEBUG_WARN( "PatBlt: unknown rop: 0x%08X\n", rop); return 1; } diff --git a/libfreerdp/gdi/gdi.c b/libfreerdp/gdi/gdi.c index 86fbb7e7b..140bad8e4 100644 --- a/libfreerdp/gdi/gdi.c +++ b/libfreerdp/gdi/gdi.c @@ -26,11 +26,11 @@ #include #include +#include #include #include #include -#include #include #include #include @@ -342,7 +342,7 @@ INLINE BYTE* gdi_get_bitmap_pointer(HGDI_DC hdcBmp, int x, int y) } else { - fprintf(stderr, "gdi_get_bitmap_pointer: requesting invalid pointer: (%d,%d) in %dx%d\n", x, y, hBmp->width, hBmp->height); + DEBUG_WARN( "gdi_get_bitmap_pointer: requesting invalid pointer: (%d,%d) in %dx%d\n", x, y, hBmp->width, hBmp->height); return 0; } } @@ -495,8 +495,8 @@ void gdi_patblt(rdpContext* context, PATBLT_ORDER* patblt) brush = &patblt->brush; - foreColor = freerdp_color_convert_rgb(patblt->foreColor, gdi->srcBpp, 24, gdi->clrconv); - backColor = freerdp_color_convert_rgb(patblt->backColor, gdi->srcBpp, 24, gdi->clrconv); + foreColor = freerdp_color_convert_drawing_order_color_to_gdi_color(patblt->foreColor, gdi->srcBpp, gdi->clrconv); + backColor = freerdp_color_convert_drawing_order_color_to_gdi_color(patblt->backColor, gdi->srcBpp, gdi->clrconv); originalColor = gdi_SetTextColor(gdi->drawing->hdc, foreColor); @@ -517,7 +517,7 @@ void gdi_patblt(rdpContext* context, PATBLT_ORDER* patblt) HGDI_BITMAP hBmp; data = freerdp_mono_image_convert(GDI_BS_HATCHED_PATTERNS + 8 * brush->hatch, 8, 8, 1, - gdi->dstBpp, patblt->backColor, patblt->foreColor, gdi->clrconv); + gdi->dstBpp, backColor, foreColor, gdi->clrconv); hBmp = gdi_CreateBitmap(8, 8, gdi->drawing->hdc->bitsPerPixel, data); @@ -541,7 +541,7 @@ void gdi_patblt(rdpContext* context, PATBLT_ORDER* patblt) else { data = freerdp_mono_image_convert(brush->data, 8, 8, gdi->srcBpp, gdi->dstBpp, - patblt->backColor, patblt->foreColor, gdi->clrconv); + backColor, foreColor, gdi->clrconv); } hBmp = gdi_CreateBitmap(8, 8, gdi->drawing->hdc->bitsPerPixel, data); @@ -557,7 +557,7 @@ void gdi_patblt(rdpContext* context, PATBLT_ORDER* patblt) } else { - fprintf(stderr, "unimplemented brush style:%d\n", brush->style); + DEBUG_WARN( "unimplemented brush style:%d\n", brush->style); } gdi_SetTextColor(gdi->drawing->hdc, originalColor); @@ -582,7 +582,8 @@ void gdi_opaque_rect(rdpContext* context, OPAQUE_RECT_ORDER* opaque_rect) gdi_CRgnToRect(opaque_rect->nLeftRect, opaque_rect->nTopRect, opaque_rect->nWidth, opaque_rect->nHeight, &rect); - brush_color = freerdp_color_convert_var_bgr(opaque_rect->color, gdi->srcBpp, 32, gdi->clrconv); + brush_color = freerdp_color_convert_drawing_order_color_to_gdi_color( + opaque_rect->color, gdi->srcBpp, gdi->clrconv); hBrush = gdi_CreateSolidBrush(brush_color); gdi_FillRect(gdi->drawing->hdc, &rect, hBrush); @@ -606,7 +607,8 @@ void gdi_multi_opaque_rect(rdpContext* context, MULTI_OPAQUE_RECT_ORDER* multi_o gdi_CRgnToRect(rectangle->left, rectangle->top, rectangle->width, rectangle->height, &rect); - brush_color = freerdp_color_convert_var_bgr(multi_opaque_rect->color, gdi->srcBpp, 32, gdi->clrconv); + brush_color = freerdp_color_convert_drawing_order_color_to_gdi_color( + multi_opaque_rect->color, gdi->srcBpp, gdi->clrconv); hBrush = gdi_CreateSolidBrush(brush_color); gdi_FillRect(gdi->drawing->hdc, &rect, hBrush); @@ -621,7 +623,8 @@ void gdi_line_to(rdpContext* context, LINE_TO_ORDER* lineTo) HGDI_PEN hPen; rdpGdi* gdi = context->gdi; - color = freerdp_color_convert_rgb(lineTo->penColor, gdi->srcBpp, 32, gdi->clrconv); + color = freerdp_color_convert_drawing_order_color_to_gdi_color( + lineTo->penColor, gdi->srcBpp, gdi->clrconv); hPen = gdi_CreatePen(lineTo->penStyle, lineTo->penWidth, (GDI_COLOR) color); gdi_SelectObject(gdi->drawing->hdc, (HGDIOBJECT) hPen); gdi_SetROP2(gdi->drawing->hdc, lineTo->bRop2); @@ -642,7 +645,8 @@ void gdi_polyline(rdpContext* context, POLYLINE_ORDER* polyline) DELTA_POINT* points; rdpGdi* gdi = context->gdi; - color = freerdp_color_convert_rgb(polyline->penColor, gdi->srcBpp, 32, gdi->clrconv); + color = freerdp_color_convert_drawing_order_color_to_gdi_color( + polyline->penColor, gdi->srcBpp, gdi->clrconv); hPen = gdi_CreatePen(GDI_PS_SOLID, 1, (GDI_COLOR) color); gdi_SelectObject(gdi->drawing->hdc, (HGDIOBJECT) hPen); gdi_SetROP2(gdi->drawing->hdc, polyline->bRop2); @@ -689,8 +693,8 @@ void gdi_mem3blt(rdpContext* context, MEM3BLT_ORDER* mem3blt) brush = &mem3blt->brush; bitmap = (gdiBitmap*) mem3blt->bitmap; - foreColor = freerdp_color_convert_rgb(mem3blt->foreColor, gdi->srcBpp, 24, gdi->clrconv); - backColor = freerdp_color_convert_rgb(mem3blt->backColor, gdi->srcBpp, 24, gdi->clrconv); + foreColor = freerdp_color_convert_drawing_order_color_to_gdi_color(mem3blt->foreColor, gdi->srcBpp, gdi->clrconv); + backColor = freerdp_color_convert_drawing_order_color_to_gdi_color(mem3blt->backColor, gdi->srcBpp, gdi->clrconv); originalColor = gdi_SetTextColor(gdi->drawing->hdc, foreColor); @@ -717,7 +721,7 @@ void gdi_mem3blt(rdpContext* context, MEM3BLT_ORDER* mem3blt) else { data = freerdp_mono_image_convert(brush->data, 8, 8, gdi->srcBpp, gdi->dstBpp, - mem3blt->backColor, mem3blt->foreColor, gdi->clrconv); + backColor, foreColor, gdi->clrconv); } hBmp = gdi_CreateBitmap(8, 8, gdi->drawing->hdc->bitsPerPixel, data); @@ -734,7 +738,7 @@ void gdi_mem3blt(rdpContext* context, MEM3BLT_ORDER* mem3blt) } else { - fprintf(stderr, "Mem3Blt unimplemented brush style:%d\n", brush->style); + DEBUG_WARN( "Mem3Blt unimplemented brush style:%d\n", brush->style); } gdi_SetTextColor(gdi->drawing->hdc, originalColor); @@ -742,22 +746,27 @@ void gdi_mem3blt(rdpContext* context, MEM3BLT_ORDER* mem3blt) void gdi_polygon_sc(rdpContext* context, POLYGON_SC_ORDER* polygon_sc) { - fprintf(stderr, "PolygonSC\n"); + DEBUG_WARN( "PolygonSC\n"); } void gdi_polygon_cb(rdpContext* context, POLYGON_CB_ORDER* polygon_cb) { - fprintf(stderr, "PolygonCB\n"); + DEBUG_WARN( "PolygonCB\n"); } void gdi_ellipse_sc(rdpContext* context, ELLIPSE_SC_ORDER* ellipse_sc) { - fprintf(stderr, "EllipseSC\n"); + DEBUG_WARN( "EllipseSC\n"); } void gdi_ellipse_cb(rdpContext* context, ELLIPSE_CB_ORDER* ellipse_cb) { - fprintf(stderr, "EllipseCB\n"); + DEBUG_WARN( "EllipseCB\n"); +} + +void gdi_frame_marker(rdpContext* context, FRAME_MARKER_ORDER* frameMarker) +{ + } void gdi_surface_frame_marker(rdpContext* context, SURFACE_FRAME_MARKER* surface_frame_marker) @@ -824,7 +833,7 @@ void gdi_surface_bits(rdpContext* context, SURFACE_BITS_COMMAND* surface_bits_co #ifdef DUMP_REMOTEFX_TILES sprintf(tile_bitmap, "/tmp/rfx/tile_%d.bmp", tilenum++); - freerdp_bitmap_write(tile_bitmap, gdi->tile->bitmap->data, 64, 64, 32); + winpr_bitmap_write(tile_bitmap, gdi->tile->bitmap->data, 64, 64, 32); #endif @@ -851,7 +860,10 @@ void gdi_surface_bits(rdpContext* context, SURFACE_BITS_COMMAND* surface_bits_co gdi->image->bitmap->bitsPerPixel = surface_bits_command->bpp; gdi->image->bitmap->bytesPerPixel = gdi->image->bitmap->bitsPerPixel / 8; gdi->image->bitmap->data = (BYTE*) _aligned_realloc(gdi->image->bitmap->data, gdi->image->bitmap->width * gdi->image->bitmap->height * 4, 16); - freerdp_image_flip(nsc_context->BitmapData, gdi->image->bitmap->data, gdi->image->bitmap->width, gdi->image->bitmap->height, 32); + freerdp_image_convert(nsc_context->BitmapData, gdi->image->bitmap->data, + surface_bits_command->width, surface_bits_command->height, + surface_bits_command->bpp, gdi->dstBpp, gdi->clrconv); + freerdp_image_flip(gdi->image->bitmap->data, gdi->image->bitmap->data, gdi->image->bitmap->width, gdi->image->bitmap->height, gdi->dstBpp); gdi_BitBlt(gdi->primary->hdc, surface_bits_command->destLeft, surface_bits_command->destTop, surface_bits_command->width, surface_bits_command->height, gdi->image->hdc, 0, 0, GDI_SRCCOPY); } else if (surface_bits_command->codecID == RDP_CODEC_ID_NONE) @@ -891,7 +903,7 @@ void gdi_surface_bits(rdpContext* context, SURFACE_BITS_COMMAND* surface_bits_co } else { - fprintf(stderr, "Unsupported codecID %d\n", surface_bits_command->codecID); + DEBUG_WARN( "Unsupported codecID %d\n", surface_bits_command->codecID); } if (tile_bitmap) @@ -936,6 +948,8 @@ void gdi_register_update_callbacks(rdpUpdate* update) update->SurfaceBits = gdi_surface_bits; update->SurfaceFrameMarker = gdi_surface_frame_marker; + + update->altsec->FrameMarker = gdi_frame_marker; } void gdi_init_primary(rdpGdi* gdi) @@ -981,6 +995,7 @@ void gdi_resize(rdpGdi* gdi, int width, int height) gdi->width = width; gdi->height = height; gdi_bitmap_free_ex(gdi->primary); + gdi->primary_buffer = NULL; gdi_init_primary(gdi); } } diff --git a/libfreerdp/gdi/graphics.c b/libfreerdp/gdi/graphics.c index 9f502fae8..f68e62c11 100644 --- a/libfreerdp/gdi/graphics.c +++ b/libfreerdp/gdi/graphics.c @@ -128,7 +128,7 @@ void gdi_Bitmap_Decompress(rdpContext* context, rdpBitmap* bitmap, msg = rfx_process_message(gdi->rfx_context, data, length); if (!msg) { - fprintf(stderr, "gdi_Bitmap_Decompress: rfx Decompression Failed\n"); + DEBUG_WARN( "gdi_Bitmap_Decompress: rfx Decompression Failed\n"); } else { @@ -151,7 +151,7 @@ void gdi_Bitmap_Decompress(rdpContext* context, rdpBitmap* bitmap, #ifdef WITH_JPEG if (!jpeg_decompress(data, bitmap->data, width, height, length, bpp)) { - fprintf(stderr, "gdi_Bitmap_Decompress: jpeg Decompression Failed\n"); + DEBUG_WARN( "gdi_Bitmap_Decompress: jpeg Decompression Failed\n"); } #endif break; @@ -162,7 +162,7 @@ void gdi_Bitmap_Decompress(rdpContext* context, rdpBitmap* bitmap, if (!status) { - fprintf(stderr, "gdi_Bitmap_Decompress: Bitmap Decompression Failed\n"); + DEBUG_WARN( "gdi_Bitmap_Decompress: Bitmap Decompression Failed\n"); } } else @@ -242,8 +242,10 @@ void gdi_Glyph_BeginDraw(rdpContext* context, int x, int y, int width, int heigh HGDI_BRUSH brush; rdpGdi* gdi = context->gdi; - bgcolor = freerdp_color_convert_var_bgr(bgcolor, gdi->srcBpp, 32, gdi->clrconv); - fgcolor = freerdp_color_convert_var_bgr(fgcolor, gdi->srcBpp, 32, gdi->clrconv); + bgcolor = freerdp_color_convert_drawing_order_color_to_gdi_color( + bgcolor, gdi->srcBpp, gdi->clrconv); + fgcolor = freerdp_color_convert_drawing_order_color_to_gdi_color( + fgcolor, gdi->srcBpp, gdi->clrconv); gdi_CRgnToRect(x, y, width, height, &rect); @@ -258,7 +260,8 @@ void gdi_Glyph_EndDraw(rdpContext* context, int x, int y, int width, int height, { rdpGdi* gdi = context->gdi; - bgcolor = freerdp_color_convert_var_bgr(bgcolor, gdi->srcBpp, 32, gdi->clrconv); + bgcolor = freerdp_color_convert_drawing_order_color_to_gdi_color( + bgcolor, gdi->srcBpp, gdi->clrconv); gdi->textColor = gdi_SetTextColor(gdi->drawing->hdc, bgcolor); } diff --git a/libfreerdp/locale/timezone.c b/libfreerdp/locale/timezone.c index b83471a82..76353a987 100644 --- a/libfreerdp/locale/timezone.c +++ b/libfreerdp/locale/timezone.c @@ -1565,7 +1565,7 @@ char* freerdp_get_unix_timezone_identifier() return tzid; } - fprintf(stderr, "Unable to detect time zone\n"); + DEBUG_WARN( "Unable to detect time zone\n"); return tzid; #else return 0; @@ -1626,7 +1626,7 @@ TIME_ZONE_ENTRY* freerdp_detect_windows_time_zone(UINT32 bias) } } - fprintf(stderr, "Unable to find a match for unix timezone: %s\n", tzid); + DEBUG_WARN( "Unable to find a match for unix timezone: %s\n", tzid); free(tzid); return NULL; } @@ -1642,12 +1642,12 @@ TIME_ZONE_RULE_ENTRY* freerdp_get_current_time_zone_rule(TIME_ZONE_RULE_ENTRY* r { if ((rules[i].TicksStart >= windows_time) && (windows_time >= rules[i].TicksEnd)) { - /*fprintf(stderr, "Got rule %d from table at %p with count %u\n", i, rules, count);*/ + /*DEBUG_WARN( "Got rule %d from table at %p with count %u\n", i, rules, count);*/ return &rules[i]; } } - fprintf(stderr, "Unable to get current timezone rule\n"); + DEBUG_WARN( "Unable to get current timezone rule\n"); return NULL; } diff --git a/libfreerdp/primitives/CMakeLists.txt b/libfreerdp/primitives/CMakeLists.txt index f544b350e..2c4ef7414 100644 --- a/libfreerdp/primitives/CMakeLists.txt +++ b/libfreerdp/primitives/CMakeLists.txt @@ -26,6 +26,7 @@ set(${MODULE_PREFIX}_SRCS prim_set.c prim_shift.c prim_sign.c + prim_YUV.c prim_YCoCg.c primitives.c prim_internal.h) @@ -100,6 +101,6 @@ endif() set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "FreeRDP/libfreerdp") if(BUILD_TESTING AND ((NOT WIN32) AND (NOT APPLE))) -# add_subdirectory(test) + add_subdirectory(test) endif() diff --git a/libfreerdp/primitives/prim_YCoCg.c b/libfreerdp/primitives/prim_YCoCg.c index 3e7505676..ca6484795 100644 --- a/libfreerdp/primitives/prim_YCoCg.c +++ b/libfreerdp/primitives/prim_YCoCg.c @@ -33,7 +33,7 @@ #endif /* !MINMAX */ /* ------------------------------------------------------------------------- */ -pstatus_t general_YCoCgRToRGB_8u_AC4R( +pstatus_t general_YCoCgToRGB_8u_AC4R( const BYTE *pSrc, INT32 srcStep, BYTE *pDst, INT32 dstStep, UINT32 width, UINT32 height, @@ -41,75 +41,85 @@ pstatus_t general_YCoCgRToRGB_8u_AC4R( BOOL withAlpha, BOOL invert) { - const BYTE *sptr = pSrc; + BYTE A; + int x, y; BYTE *dptr = pDst; + const BYTE *sptr = pSrc; + INT16 Cg, Co, Y, T, R, G, B; int cll = shift - 1; /* -1 builds in the /2's */ - int x,y; - int srcRowBump = srcStep - width*sizeof(UINT32); - int dstRowBump = dstStep - width*sizeof(UINT32); + int srcPad = srcStep - (width * 4); + int dstPad = dstStep - (width * 4); + if (invert) { - for (y=0; yINT16 */ - a = *sptr++; - if (!withAlpha) a = 0xFFU; - t = y - cg; - r = t + co; - g = y + cg; - b = t - co; - *dptr++ = (BYTE) MINMAX(r, 0, 255); - *dptr++ = (BYTE) MINMAX(g, 0, 255); - *dptr++ = (BYTE) MINMAX(b, 0, 255); - *dptr++ = a; + Cg = (INT16) ((INT8) ((*sptr++) << cll)); + Co = (INT16) ((INT8) ((*sptr++) << cll)); + Y = (INT16) (*sptr++); /* UINT8->INT16 */ + + A = *sptr++; + + if (!withAlpha) + A = 0xFFU; + + T = Y - Cg; + R = T + Co; + G = Y + Cg; + B = T - Co; + + *dptr++ = (BYTE) MINMAX(R, 0, 255); + *dptr++ = (BYTE) MINMAX(G, 0, 255); + *dptr++ = (BYTE) MINMAX(B, 0, 255); + *dptr++ = A; } - sptr += srcRowBump; - dptr += dstRowBump; + + sptr += srcPad; + dptr += dstPad; } } else { - for (y=0; yINT16 */ - a = *sptr++; - if (!withAlpha) a = 0xFFU; - t = y - cg; - r = t + co; - g = y + cg; - b = t - co; - *dptr++ = (BYTE) MINMAX(b, 0, 255); - *dptr++ = (BYTE) MINMAX(g, 0, 255); - *dptr++ = (BYTE) MINMAX(r, 0, 255); - *dptr++ = a; + Cg = (INT16) ((INT8) ((*sptr++) << cll)); + Co = (INT16) ((INT8) ((*sptr++) << cll)); + Y = (INT16) (*sptr++); /* UINT8->INT16 */ + + A = *sptr++; + + if (!withAlpha) + A = 0xFFU; + + T = Y - Cg; + R = T + Co; + G = Y + Cg; + B = T - Co; + + *dptr++ = (BYTE) MINMAX(B, 0, 255); + *dptr++ = (BYTE) MINMAX(G, 0, 255); + *dptr++ = (BYTE) MINMAX(R, 0, 255); + *dptr++ = A; } - sptr += srcRowBump; - dptr += dstRowBump; + + sptr += srcPad; + dptr += dstPad; } } + return PRIMITIVES_SUCCESS; } /* ------------------------------------------------------------------------- */ void primitives_init_YCoCg(primitives_t* prims) { - prims->YCoCgRToRGB_8u_AC4R = general_YCoCgRToRGB_8u_AC4R; + prims->YCoCgToRGB_8u_AC4R = general_YCoCgToRGB_8u_AC4R; primitives_init_YCoCg_opt(prims); } diff --git a/libfreerdp/primitives/prim_YCoCg.h b/libfreerdp/primitives/prim_YCoCg.h index aa3929aff..c03715bda 100644 --- a/libfreerdp/primitives/prim_YCoCg.h +++ b/libfreerdp/primitives/prim_YCoCg.h @@ -24,7 +24,7 @@ #ifndef __PRIM_YCOCG_H_INCLUDED__ #define __PRIM_YCOCG_H_INCLUDED__ -pstatus_t general_YCoCgRToRGB_8u_AC4R(const BYTE *pSrc, INT32 srcStep, BYTE *pDst, INT32 dstStep, UINT32 width, UINT32 height, UINT8 shift, BOOL withAlpha, BOOL invert); +pstatus_t general_YCoCgToRGB_8u_AC4R(const BYTE *pSrc, INT32 srcStep, BYTE *pDst, INT32 dstStep, UINT32 width, UINT32 height, UINT8 shift, BOOL withAlpha, BOOL invert); void primitives_init_YCoCg_opt(primitives_t* prims); diff --git a/libfreerdp/primitives/prim_YCoCg_opt.c b/libfreerdp/primitives/prim_YCoCg_opt.c index 51fce1fc3..e022662b3 100644 --- a/libfreerdp/primitives/prim_YCoCg_opt.c +++ b/libfreerdp/primitives/prim_YCoCg_opt.c @@ -69,7 +69,7 @@ static pstatus_t ssse3_YCoCgRToRGB_8u_AC4R_invert( if ((width < 8) || (ULONG_PTR) dptr & 0x03) { /* Too small, or we'll never hit a 16-byte boundary. Punt. */ - return general_YCoCgRToRGB_8u_AC4R(pSrc, srcStep, + return general_YCoCgToRGB_8u_AC4R(pSrc, srcStep, pDst, dstStep, width, height, shift, withAlpha, TRUE); } @@ -83,7 +83,7 @@ static pstatus_t ssse3_YCoCgRToRGB_8u_AC4R_invert( { int startup = (16 - ((ULONG_PTR) dptr & 0x0f)) / 4; if (startup > width) startup = width; - general_YCoCgRToRGB_8u_AC4R(sptr, srcStep, dptr, dstStep, + general_YCoCgToRGB_8u_AC4R(sptr, srcStep, dptr, dstStep, startup, 1, shift, withAlpha, TRUE); sptr += startup * sizeof(UINT32); dptr += startup * sizeof(UINT32); @@ -185,7 +185,7 @@ static pstatus_t ssse3_YCoCgRToRGB_8u_AC4R_invert( /* Handle any remainder pixels. */ if (w > 0) { - general_YCoCgRToRGB_8u_AC4R(sptr, srcStep, dptr, dstStep, + general_YCoCgToRGB_8u_AC4R(sptr, srcStep, dptr, dstStep, w, 1, shift, withAlpha, TRUE); sptr += w * sizeof(UINT32); dptr += w * sizeof(UINT32); @@ -228,7 +228,7 @@ static pstatus_t ssse3_YCoCgRToRGB_8u_AC4R_no_invert( if ((width < 8) || (ULONG_PTR) dptr & 0x03) { /* Too small, or we'll never hit a 16-byte boundary. Punt. */ - return general_YCoCgRToRGB_8u_AC4R(pSrc, srcStep, + return general_YCoCgToRGB_8u_AC4R(pSrc, srcStep, pDst, dstStep, width, height, shift, withAlpha, FALSE); } @@ -242,7 +242,7 @@ static pstatus_t ssse3_YCoCgRToRGB_8u_AC4R_no_invert( { int startup = (16 - ((ULONG_PTR) dptr & 0x0f)) / 4; if (startup > width) startup = width; - general_YCoCgRToRGB_8u_AC4R(sptr, srcStep, dptr, dstStep, + general_YCoCgToRGB_8u_AC4R(sptr, srcStep, dptr, dstStep, startup, 1, shift, withAlpha, FALSE); sptr += startup * sizeof(UINT32); dptr += startup * sizeof(UINT32); @@ -348,7 +348,7 @@ static pstatus_t ssse3_YCoCgRToRGB_8u_AC4R_no_invert( /* Handle any remainder pixels. */ if (w > 0) { - general_YCoCgRToRGB_8u_AC4R(sptr, srcStep, dptr, dstStep, + general_YCoCgToRGB_8u_AC4R(sptr, srcStep, dptr, dstStep, w, 1, shift, withAlpha, FALSE); sptr += w * sizeof(UINT32); dptr += w * sizeof(UINT32); @@ -393,7 +393,7 @@ void primitives_init_YCoCg_opt(primitives_t* prims) if (IsProcessorFeaturePresentEx(PF_EX_SSSE3) && IsProcessorFeaturePresent(PF_SSE3_INSTRUCTIONS_AVAILABLE)) { - prims->YCoCgRToRGB_8u_AC4R = ssse3_YCoCgRToRGB_8u_AC4R; + prims->YCoCgToRGB_8u_AC4R = ssse3_YCoCgRToRGB_8u_AC4R; } #endif /* WITH_SSE2 */ } diff --git a/libfreerdp/primitives/prim_YUV.c b/libfreerdp/primitives/prim_YUV.c new file mode 100644 index 000000000..c57b122b8 --- /dev/null +++ b/libfreerdp/primitives/prim_YUV.c @@ -0,0 +1,231 @@ +/** + * FreeRDP: A Remote Desktop Protocol Implementation + * + * Copyright 2014 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include + +#include "prim_internal.h" +#include "prim_YUV.h" + +pstatus_t general_YUV420ToRGB_8u_P3AC4R(const BYTE* pSrc[3], int srcStep[3], + BYTE* pDst, int dstStep, const prim_size_t* roi) +{ + int x, y; + int dstPad; + int srcPad[3]; + BYTE Y, U, V; + int halfWidth; + int halfHeight; + const BYTE* pY; + const BYTE* pU; + const BYTE* pV; + int R, G, B; + int Yp, Up, Vp; + int Up48, Up475; + int Vp403, Vp120; + BYTE* pRGB = pDst; + + pY = pSrc[0]; + pU = pSrc[1]; + pV = pSrc[2]; + + halfWidth = roi->width / 2; + halfHeight = roi->height / 2; + + srcPad[0] = (srcStep[0] - roi->width); + srcPad[1] = (srcStep[1] - halfWidth); + srcPad[2] = (srcStep[2] - halfWidth); + + dstPad = (dstStep - (roi->width * 4)); + + for (y = 0; y < halfHeight; y++) + { + for (x = 0; x < halfWidth; x++) + { + U = *pU++; + V = *pV++; + + Up = U - 128; + Vp = V - 128; + + Up48 = 48 * Up; + Up475 = 475 * Up; + + Vp403 = Vp * 403; + Vp120 = Vp * 120; + + /* 1st pixel */ + + Y = *pY++; + Yp = Y << 8; + + R = (Yp + Vp403) >> 8; + G = (Yp - Up48 - Vp120) >> 8; + B = (Yp + Up475) >> 8; + + if (R < 0) + R = 0; + else if (R > 255) + R = 255; + + if (G < 0) + G = 0; + else if (G > 255) + G = 255; + + if (B < 0) + B = 0; + else if (B > 255) + B = 255; + + *pRGB++ = (BYTE) B; + *pRGB++ = (BYTE) G; + *pRGB++ = (BYTE) R; + *pRGB++ = 0xFF; + + /* 2nd pixel */ + + Y = *pY++; + Yp = Y << 8; + + R = (Yp + Vp403) >> 8; + G = (Yp - Up48 - Vp120) >> 8; + B = (Yp + Up475) >> 8; + + if (R < 0) + R = 0; + else if (R > 255) + R = 255; + + if (G < 0) + G = 0; + else if (G > 255) + G = 255; + + if (B < 0) + B = 0; + else if (B > 255) + B = 255; + + *pRGB++ = (BYTE) B; + *pRGB++ = (BYTE) G; + *pRGB++ = (BYTE) R; + *pRGB++ = 0xFF; + } + + pY += srcPad[0]; + pU -= halfWidth; + pV -= halfWidth; + pRGB += dstPad; + + for (x = 0; x < halfWidth; x++) + { + U = *pU++; + V = *pV++; + + Up = U - 128; + Vp = V - 128; + + Up48 = 48 * Up; + Up475 = 475 * Up; + + Vp403 = Vp * 403; + Vp120 = Vp * 120; + + /* 3rd pixel */ + + Y = *pY++; + Yp = Y << 8; + + R = (Yp + Vp403) >> 8; + G = (Yp - Up48 - Vp120) >> 8; + B = (Yp + Up475) >> 8; + + if (R < 0) + R = 0; + else if (R > 255) + R = 255; + + if (G < 0) + G = 0; + else if (G > 255) + G = 255; + + if (B < 0) + B = 0; + else if (B > 255) + B = 255; + + *pRGB++ = (BYTE) B; + *pRGB++ = (BYTE) G; + *pRGB++ = (BYTE) R; + *pRGB++ = 0xFF; + + /* 4th pixel */ + + Y = *pY++; + Yp = Y << 8; + + R = (Yp + Vp403) >> 8; + G = (Yp - Up48 - Vp120) >> 8; + B = (Yp + Up475) >> 8; + + if (R < 0) + R = 0; + else if (R > 255) + R = 255; + + if (G < 0) + G = 0; + else if (G > 255) + G = 255; + + if (B < 0) + B = 0; + else if (B > 255) + B = 255; + + *pRGB++ = (BYTE) B; + *pRGB++ = (BYTE) G; + *pRGB++ = (BYTE) R; + *pRGB++ = 0xFF; + } + + pY += srcPad[0]; + pU += srcPad[1]; + pV += srcPad[2]; + pRGB += dstPad; + } + + return PRIMITIVES_SUCCESS; +} + +void primitives_init_YUV(primitives_t* prims) +{ + prims->YUV420ToRGB_8u_P3AC4R = general_YUV420ToRGB_8u_P3AC4R; +} + +void primitives_deinit_YUV(primitives_t* prims) +{ + +} diff --git a/server/X11/xf_update.h b/libfreerdp/primitives/prim_YUV.h similarity index 61% rename from server/X11/xf_update.h rename to libfreerdp/primitives/prim_YUV.h index 9e3c27342..12f796b61 100644 --- a/server/X11/xf_update.h +++ b/libfreerdp/primitives/prim_YUV.h @@ -1,8 +1,7 @@ /** * FreeRDP: A Remote Desktop Protocol Implementation - * X11 Server Graphical Updates * - * Copyright 2013 Marc-Andre Moreau + * Copyright 2014 Marc-Andre Moreau * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,12 +16,12 @@ * limitations under the License. */ -#ifndef __XF_UPDATE_H -#define __XF_UPDATE_H +#ifndef FREERDP_PRIMITIVES_YUV_H +#define FREERDP_PRIMITIVES_YUV_H -#include "xfreerdp.h" +pstatus_t general_yCbCrToRGB_16s8u_P3AC4R(const INT16* pSrc[3], int srcStep, BYTE* pDst, int dstStep, const prim_size_t* roi); -void* xf_update_thread(void* param); - -#endif /* __XF_UPDATE_H */ +void primitives_init_YUV(primitives_t* prims); +void primitives_deinit_YUV(primitives_t* prims); +#endif /* FREERDP_PRIMITIVES_YUV_H */ diff --git a/libfreerdp/primitives/prim_colors.c b/libfreerdp/primitives/prim_colors.c index a7de64339..7478fceee 100644 --- a/libfreerdp/primitives/prim_colors.c +++ b/libfreerdp/primitives/prim_colors.c @@ -33,6 +33,64 @@ #endif /* !MINMAX */ /* ------------------------------------------------------------------------- */ + +pstatus_t general_yCbCrToRGB_16s8u_P3AC4R(const INT16* pSrc[3], int srcStep, + BYTE* pDst, int dstStep, const prim_size_t* roi) +{ + int x, y; + INT16 R, G, B; + double Y, Cb, Cr; + BYTE* pRGB = pDst; + const INT16* pY = pSrc[0]; + const INT16* pCb = pSrc[1]; + const INT16* pCr = pSrc[2]; + int srcPad = (srcStep - (roi->width * 2)) / 2; + int dstPad = (dstStep - (roi->width * 4)) / 4; + + for (y = 0; y < roi->height; y++) + { + for (x = 0; x < roi->width; x++) + { + Y = (double) ((*pY++ >> 1) + 2048); + Cb = (double) (*pCb++ >> 1); + Cr = (double) (*pCr++ >> 1); + + R = (INT16) (((int) (Y + (1.402524948120117L * Cr) + 8.0L)) >> 4); + G = (INT16) (((int) (Y - (0.3437300026416779L * Cb) - (0.7144010066986084L * Cr) + 8.0L)) >> 4); + B = (INT16) (((int) (Y + (1.769904971122742L * Cb) + 8.0L)) >> 4); + + if (R < 0) + R = 0; + else if (R > 255) + R = 255; + + if (G < 0) + G = 0; + else if (G > 255) + G = 255; + + if (B < 0) + B = 0; + else if (B > 255) + B = 255; + + *pRGB++ = (BYTE) B; + *pRGB++ = (BYTE) G; + *pRGB++ = (BYTE) R; + *pRGB++ = 0xFF; + } + + pY += srcPad; + pCb += srcPad; + pCr += srcPad; + pRGB += dstPad; + } + + return PRIMITIVES_SUCCESS; +} + +/* ------------------------------------------------------------------------- */ + pstatus_t general_yCbCrToRGB_16s16s_P3P3( const INT16 *pSrc[3], INT32 srcStep, INT16 *pDst[3], INT32 dstStep, @@ -217,9 +275,10 @@ pstatus_t general_RGBToRGB_16s8u_P3AC4R( /* ------------------------------------------------------------------------- */ void primitives_init_colors(primitives_t* prims) { - prims->RGBToRGB_16s8u_P3AC4R = general_RGBToRGB_16s8u_P3AC4R; + prims->yCbCrToRGB_16s8u_P3AC4R = general_yCbCrToRGB_16s8u_P3AC4R; prims->yCbCrToRGB_16s16s_P3P3 = general_yCbCrToRGB_16s16s_P3P3; prims->RGBToYCbCr_16s16s_P3P3 = general_RGBToYCbCr_16s16s_P3P3; + prims->RGBToRGB_16s8u_P3AC4R = general_RGBToRGB_16s8u_P3AC4R; primitives_init_colors_opt(prims); } diff --git a/libfreerdp/primitives/prim_colors.h b/libfreerdp/primitives/prim_colors.h index 15b76d997..773bbaeeb 100644 --- a/libfreerdp/primitives/prim_colors.h +++ b/libfreerdp/primitives/prim_colors.h @@ -22,6 +22,7 @@ #ifndef __PRIM_COLORS_H_INCLUDED__ #define __PRIM_COLORS_H_INCLUDED__ +pstatus_t general_yCbCrToRGB_16s8u_P3AC4R(const INT16* pSrc[3], int srcStep, BYTE* pDst, int dstStep, const prim_size_t* roi); pstatus_t general_yCbCrToRGB_16s16s_P3P3(const INT16 *pSrc[3], INT32 srcStep, INT16 *pDst[3], INT32 dstStep, const prim_size_t *roi); pstatus_t general_RGBToYCbCr_16s16s_P3P3(const INT16 *pSrc[3], INT32 srcStep, INT16 *pDst[3], INT32 dstStep, const prim_size_t *roi); pstatus_t general_RGBToRGB_16s8u_P3AC4R(const INT16 *pSrc[3], int srcStep, BYTE *pDst, int dstStep, const prim_size_t *roi); diff --git a/libfreerdp/primitives/prim_internal.h b/libfreerdp/primitives/prim_internal.h index e1a248c69..04c830a1c 100644 --- a/libfreerdp/primitives/prim_internal.h +++ b/libfreerdp/primitives/prim_internal.h @@ -35,54 +35,37 @@ : _mm_load_si128((__m128i *) (_ptr_))) /* Function prototypes for all the init/deinit routines. */ -extern void primitives_init_copy( - primitives_t *prims); -extern void primitives_deinit_copy( - primitives_t *prims); +extern void primitives_init_copy(primitives_t *prims); +extern void primitives_deinit_copy(primitives_t *prims); -extern void primitives_init_set( - primitives_t *prims); -extern void primitives_deinit_set( - primitives_t *prims); +extern void primitives_init_set(primitives_t *prims); +extern void primitives_deinit_set(primitives_t *prims); -extern void primitives_init_add( - primitives_t *prims); -extern void primitives_deinit_add( - primitives_t *prims); +extern void primitives_init_add(primitives_t *prims); +extern void primitives_deinit_add(primitives_t *prims); -extern void primitives_init_andor( - primitives_t *prims); -extern void primitives_deinit_andor( - primitives_t *prims); +extern void primitives_init_andor(primitives_t *prims); +extern void primitives_deinit_andor(primitives_t *prims); -extern void primitives_init_shift( - primitives_t *prims); -extern void primitives_deinit_shift( - primitives_t *prims); +extern void primitives_init_shift(primitives_t *prims); +extern void primitives_deinit_shift(primitives_t *prims); -extern void primitives_init_sign( - primitives_t *prims); -extern void primitives_deinit_sign( - primitives_t *prims); +extern void primitives_init_sign(primitives_t *prims); +extern void primitives_deinit_sign(primitives_t *prims); -extern void primitives_init_alphaComp( - primitives_t *prims); -extern void primitives_deinit_alphaComp( - primitives_t *prims); +extern void primitives_init_alphaComp(primitives_t *prims); +extern void primitives_deinit_alphaComp(primitives_t *prims); -extern void primitives_init_colors( - primitives_t *prims); -extern void primitives_deinit_colors( - primitives_t *prims); +extern void primitives_init_colors(primitives_t *prims); +extern void primitives_deinit_colors(primitives_t *prims); -extern void primitives_init_YCoCg( - primitives_t *prims); -extern void primitives_deinit_YCoCg( - primitives_t *prims); +extern void primitives_init_YCoCg(primitives_t *prims); +extern void primitives_deinit_YCoCg(primitives_t *prims); -extern void primitives_init_16to32bpp( - primitives_t *prims); -extern void primitives_deinit_16to32bpp( - primitives_t *prims); +extern void primitives_init_YUV(primitives_t *prims); +extern void primitives_deinit_YUV(primitives_t *prims); + +extern void primitives_init_16to32bpp(primitives_t *prims); +extern void primitives_deinit_16to32bpp(primitives_t *prims); #endif /* !__PRIM_INTERNAL_H_INCLUDED__ */ diff --git a/libfreerdp/primitives/primitives.c b/libfreerdp/primitives/primitives.c index dc8d038b9..dcdd5941a 100644 --- a/libfreerdp/primitives/primitives.c +++ b/libfreerdp/primitives/primitives.c @@ -32,11 +32,11 @@ static primitives_t* pPrimitives = NULL; /* ------------------------------------------------------------------------- */ void primitives_init(void) { - if (pPrimitives == NULL) + if (!pPrimitives) { pPrimitives = calloc(1, sizeof(primitives_t)); - if (pPrimitives == NULL) + if (!pPrimitives) return; } @@ -50,13 +50,14 @@ void primitives_init(void) primitives_init_sign(pPrimitives); primitives_init_colors(pPrimitives); primitives_init_YCoCg(pPrimitives); + primitives_init_YUV(pPrimitives); primitives_init_16to32bpp(pPrimitives); } /* ------------------------------------------------------------------------- */ primitives_t* primitives_get(void) { - if (pPrimitives == NULL) + if (!pPrimitives) primitives_init(); return pPrimitives; @@ -65,7 +66,7 @@ primitives_t* primitives_get(void) /* ------------------------------------------------------------------------- */ void primitives_deinit(void) { - if (pPrimitives == NULL) + if (!pPrimitives) return; /* Call each section's de-initialization routine. */ @@ -78,6 +79,7 @@ void primitives_deinit(void) primitives_deinit_sign(pPrimitives); primitives_deinit_colors(pPrimitives); primitives_deinit_YCoCg(pPrimitives); + primitives_deinit_YUV(pPrimitives); primitives_deinit_16to32bpp(pPrimitives); free((void*) pPrimitives); diff --git a/libfreerdp/primitives/test/.gitignore b/libfreerdp/primitives/test/.gitignore index 082fee1c1..f25c3eed1 100644 --- a/libfreerdp/primitives/test/.gitignore +++ b/libfreerdp/primitives/test/.gitignore @@ -1,2 +1,3 @@ prim_test +TestPrimitives.c diff --git a/libfreerdp/primitives/test/CMakeLists.txt b/libfreerdp/primitives/test/CMakeLists.txt index 972cee3b8..8b7162455 100644 --- a/libfreerdp/primitives/test/CMakeLists.txt +++ b/libfreerdp/primitives/test/CMakeLists.txt @@ -1,155 +1,50 @@ -# FreeRDP: A Remote Desktop Protocol Client -# primitives test makefile builder -# vi:ts=4 sw=4: -# -# (c) Copyright 2012 Hewlett-Packard Development Company, L.P. -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at http://www.apache.org/licenses/LICENSE-2.0. -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -# implied. See the License for the specific language governing permissions -# and limitations under the License. -# -# TODO: Integrate this into the testing framework, in some form. -# Right now this produces a standalone test that covers both functionality -# and performance of the primitives library entrypoints. +set(MODULE_NAME "TestPrimitives") +set(MODULE_PREFIX "TEST_FREERDP_PRIMITIVES") -cmake_minimum_required(VERSION 2.8) -set(MODULE_NAME "prim_test") -set(MODULE_PREFIX "PRIMITIVES_LIBRARY_TEST") +set(${MODULE_PREFIX}_DRIVER ${MODULE_NAME}.c) -set(PRIMITIVE_TEST_CFILES +set(${MODULE_PREFIX}_TESTS + TestPrimitives16to32bpp.c + TestPrimitivesAdd.c + TestPrimitivesAlphaComp.c + TestPrimitivesAndOr.c + TestPrimitivesColors.c + TestPrimitivesCopy.c + TestPrimitivesSet.c + TestPrimitivesShift.c + TestPrimitivesSign.c + TestPrimitivesYCbCr.c + TestPrimitivesYCoCg.c) + +create_test_sourcelist(${MODULE_PREFIX}_SRCS + ${${MODULE_PREFIX}_DRIVER} + ${${MODULE_PREFIX}_TESTS}) + +set(${MODULE_PREFIX}_EXTRA_SRCS prim_test.c - test_16to32bpp.c - test_add.c - test_alphaComp.c - test_andor.c - test_colors.c - test_copy.c - test_set.c - test_shift.c - test_sign.c - test_YCoCg.c - ../prim_16to32bpp.c - ../prim_add.c - ../prim_andor.c - ../prim_alphaComp.c - ../prim_colors.c - ../prim_copy.c - ../prim_set.c - ../prim_shift.c - ../prim_sign.c - ../prim_YCoCg.c - ../prim_16to32bpp_opt.c - ../prim_add_opt.c - ../prim_alphaComp_opt.c - ../prim_andor_opt.c - ../prim_colors_opt.c - ../prim_set_opt.c - ../prim_shift_opt.c - ../prim_sign_opt.c - ../prim_YCoCg_opt.c - ../primitives.c - ) - -set(PRIMITIVE_TEST_HEADERS - measure.h prim_test.h - ../prim_internal.h -) + measure.h) -set(PRIMITIVE_TEST_SRCS - ${PRIMITIVE_TEST_CFILES} - ${PRIMITIVE_TEST_HEADERS} - ) +add_executable(${MODULE_NAME} ${${MODULE_PREFIX}_SRCS} ${${MODULE_PREFIX}_EXTRA_SRCS}) -include_directories(. ../../.. ../../../include ../../../winpr/include) -add_definitions(-DPRIM_STATIC=auto -DALL_PRIMITIVES_VERSIONS -DHAVE_CONFIG_H) +set_complex_link_libraries(VARIABLE ${MODULE_PREFIX}_LIBS + MONOLITHIC ${MONOLITHIC_BUILD} + MODULE freerdp + MODULES freerdp-primitives) + +set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} winpr) -# If these haven't been set by the caller, set them now to defaults. -if(NOT DEFINED WITH_IPP) - set(WITH_IPP FALSE) -endif() -if(NOT DEFINED WITH_SSE2) - if (CMAKE_SYSTEM_PROCESSOR MATCHES "arm*") - set(WITH_SSE2 FALSE) - else() - set(WITH_SSE2 TRUE) - endif() -endif() -if(NOT DEFINED WITH_NEON) - if (CMAKE_SYSTEM_PROCESSOR MATCHES "arm*") - set(WITH_NEON TRUE) - else() - set(WITH_NEON FALSE) - endif() -endif() +target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS}) -if(WITH_SSE2) - if(CMAKE_COMPILER_IS_GNUCC) - set(OPTFLAGS "${OPTFLAGS} -msse2 -mssse3 -O2 -Wdeclaration-after-statement") - endif() +add_definitions(-DPRIM_STATIC=auto -DALL_PRIMITIVES_VERSIONS) - if(MSVC) - set(OPTFLAGS "${OPTFLAGS} /arch:SSE2") - endif() -elseif(WITH_NEON) - if(CMAKE_COMPILER_IS_GNUCC) - set(OPTFLAGS "${OPTFLAGS} -mfpu=neon -mfloat-abi=${ARM_FP_ABI} -O2") - endif() - # TODO: Add MSVC equivalent -endif() +set_target_properties(${MODULE_NAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${TESTING_OUTPUT_DIRECTORY}") -add_executable(prim_test ${PRIMITIVE_TEST_SRCS}) - -if(WITH_IPP) - if(NOT DEFINED IPP_FOUND) - include(../../../cmake/FindIPP.cmake) - endif() - - # IPP PATH debugging messages - message(IPP_FOUND=${IPP_FOUND}) - message(IPP_VERSION_STR=${IPP_VERSION_STR}) - message(IPP_VERSION_MAJOR=${IPP_VERSION_MAJOR}) - message(IPP_VERSION_MINOR=${IPP_VERSION_MINOR}) - message(IPP_VERSION_BUILD=${IPP_VERSION_BUILD}) - message(IPP_ROOT_DIR=${IPP_ROOT_DIR}) - message(IPP_INCLUDE_DIRS=${IPP_INCLUDE_DIRS}) - message(IPP_LIBRARY_DIRS=${IPP_LIBRARY_DIRS}) - message(IPP_LIBRARIES=${IPP_LIBRARIES}) - message(IPP_COMPILER_LIBRARY_DIRS=${IPP_COMPILER_LIBRARY_DIRS}) - message(IPP_COMPILER_LIBRARIES=${IPP_COMPILER_LIBRARIES}) - message(IPP_LIBRARY_LIST=${IPP_LIBRARY_LIST}) - message(IPP_LIB_PREFIX=${IPP_LIB_PREFIX}) - message(IPP_LIB_SUFFIX=${IPP_LIB_SUFFIX}) - message(IPP_PREFIX=${IPP_PREFIX}) - message(IPP_SUFFIX=${IPP_SUFFIX}) - message(IPPCORE=${IPPCORE}) - message(IPPS=${IPPS}) - message(IPPI=${IPPI}) - message(IPPCC=${IPPCC}) - message(IPPCV=${IPPCV}) - message(IPPVM=${IPPVM}) - - if(CMAKE_COMPILER_IS_GNUCC) - foreach(INCLDIR ${IPP_INCLUDE_DIRS}) - set(OPTFLAGS "${OPTFLAGS} -I${INCLDIR}") - endforeach(INCLDIR) - endif() - target_link_libraries(prim_test ${IPP_LIBRARY_LIST}) -endif() - -set_property(SOURCE ${PRIMITIVE_TEST_CFILES} PROPERTY COMPILE_FLAGS ${OPTFLAGS}) - -find_library(WINPR_SYSINFO NAMES winpr-sysinfo HINTS ../../../winpr/libwinpr/sysinfo) -target_link_libraries(prim_test rt ${WINPR_SYSINFO}) - -if(NOT TESTING_OUTPUT_DIRECTORY) - set(TESTING_OUTPUT_DIRECTORY .) -endif() -add_test(prim_test ${TESTING_OUTPUT_DIRECTORY}/prim_test functionality) +foreach(test ${${MODULE_PREFIX}_TESTS}) + get_filename_component(TestName ${test} NAME_WE) + add_test(${TestName} ${TESTING_OUTPUT_DIRECTORY}/${MODULE_NAME} ${TestName}) +endforeach() set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "FreeRDP/Test") + diff --git a/libfreerdp/primitives/test/test_16to32bpp.c b/libfreerdp/primitives/test/TestPrimitives16to32bpp.c similarity index 94% rename from libfreerdp/primitives/test/test_16to32bpp.c rename to libfreerdp/primitives/test/TestPrimitives16to32bpp.c index dc0c60317..03a070e40 100644 --- a/libfreerdp/primitives/test/test_16to32bpp.c +++ b/libfreerdp/primitives/test/TestPrimitives16to32bpp.c @@ -28,6 +28,8 @@ static const int RGB_TRIAL_ITERATIONS = 1000; static const float TEST_TIME = 4.0; +extern BOOL g_TestPrimitivesPerformance; + extern pstatus_t general_RGB565ToARGB_16u32u_C3C4( const UINT16* pSrc, INT32 srcStep, UINT32* pDst, INT32 dstStep, @@ -134,7 +136,7 @@ static BOOL try_16To32( /* ------------------------------------------------------------------------- */ int test_RGB565ToARGB_16u32u_C3C4_func(void) { - INT16 ALIGN(data16[4096+3]); + UINT16 ALIGN(data16[4096+3]); BOOL success; success = TRUE; @@ -176,7 +178,6 @@ int test_RGB565ToARGB_16u32u_C3C4_speed(void) { UINT16 ALIGN(src[4096]); UINT32 ALIGN(dst[4096]); - int i; int size_array[] = { 64 }; get_random_data(src, sizeof(src)); @@ -186,3 +187,23 @@ int test_RGB565ToARGB_16u32u_C3C4_speed(void) size_array, 1, RGB_TRIAL_ITERATIONS, TEST_TIME); return SUCCESS; } + +int TestPrimitives16to32bpp(int argc, char* argv[]) +{ + int status; + + status = test_RGB565ToARGB_16u32u_C3C4_func(); + + if (status != SUCCESS) + return 1; + + if (g_TestPrimitivesPerformance) + { + status = test_RGB565ToARGB_16u32u_C3C4_speed(); + + if (status != SUCCESS) + return 1; + } + + return 0; +} diff --git a/libfreerdp/primitives/test/test_add.c b/libfreerdp/primitives/test/TestPrimitivesAdd.c similarity index 92% rename from libfreerdp/primitives/test/test_add.c rename to libfreerdp/primitives/test/TestPrimitivesAdd.c index 453e2a7de..08ab41ff4 100644 --- a/libfreerdp/primitives/test/test_add.c +++ b/libfreerdp/primitives/test/TestPrimitivesAdd.c @@ -23,6 +23,8 @@ static const int ADD16S_PRETEST_ITERATIONS = 300000*64; static const int TEST_TIME = 2.0; // seconds +extern BOOL g_TestPrimitivesPerformance; + extern pstatus_t general_add_16s( const INT16 *pSrc1, const INT16 *pSrc2, INT16 *pDst, int len); extern pstatus_t sse3_add_16s( @@ -112,3 +114,23 @@ int test_add16s_speed(void) test_sizes, NUM_TEST_SIZES, ADD16S_PRETEST_ITERATIONS, TEST_TIME); return SUCCESS; } + +int TestPrimitivesAdd(int argc, char* argv[]) +{ + int status; + + status = test_add16s_func(); + + if (status != SUCCESS) + return 1; + + if (g_TestPrimitivesPerformance) + { + status = test_add16s_speed(); + + if (status != SUCCESS) + return 1; + } + + return 0; +} diff --git a/libfreerdp/primitives/test/test_alphaComp.c b/libfreerdp/primitives/test/TestPrimitivesAlphaComp.c similarity index 95% rename from libfreerdp/primitives/test/test_alphaComp.c rename to libfreerdp/primitives/test/TestPrimitivesAlphaComp.c index c3b5e9ca1..18332dcb5 100644 --- a/libfreerdp/primitives/test/test_alphaComp.c +++ b/libfreerdp/primitives/test/TestPrimitivesAlphaComp.c @@ -22,6 +22,8 @@ static const int ALPHA_PRETEST_ITERATIONS = 5000000; static const float TEST_TIME = 5.0; +extern BOOL g_TestPrimitivesPerformance; + static const int block_size[] = { 4, 64, 256 }; #define NUM_BLOCK_SIZES (sizeof(block_size)/sizeof(int)) #define MAX_BLOCK_SIZE 256 @@ -233,3 +235,23 @@ int test_alphaComp_speed(void) return SUCCESS; } + +int TestPrimitivesAlphaComp(int argc, char* argv[]) +{ + int status; + + status = test_alphaComp_func(); + + if (status != SUCCESS) + return 1; + + if (g_TestPrimitivesPerformance) + { + status = test_alphaComp_speed(); + + if (status != SUCCESS) + return 1; + } + + return 0; +} diff --git a/libfreerdp/primitives/test/test_andor.c b/libfreerdp/primitives/test/TestPrimitivesAndOr.c similarity index 92% rename from libfreerdp/primitives/test/test_andor.c rename to libfreerdp/primitives/test/TestPrimitivesAndOr.c index d82991408..24d73d43a 100644 --- a/libfreerdp/primitives/test/test_andor.c +++ b/libfreerdp/primitives/test/TestPrimitivesAndOr.c @@ -23,6 +23,8 @@ static const int ANDOR_PRETEST_ITERATIONS = 100000; static const int TEST_TIME = 2.0; // seconds +extern BOOL g_TestPrimitivesPerformance; + extern pstatus_t general_andC_32u(const UINT32 *pSrc, UINT32 val, UINT32 *pDst, int len); extern pstatus_t sse3_andC_32u(const UINT32 *pSrc, UINT32 val, @@ -185,3 +187,36 @@ int test_or_32u_speed(void) test_sizes, NUM_TEST_SIZES, ANDOR_PRETEST_ITERATIONS, TEST_TIME); return SUCCESS; } + +int TestPrimitivesAndOr(int argc, char* argv[]) +{ + int status; + + status = test_and_32u_func(); + + if (status != SUCCESS) + return 1; + + if (g_TestPrimitivesPerformance) + { + status = test_and_32u_speed(); + + if (status != SUCCESS) + return 1; + } + + status = test_or_32u_func(); + + if (status != SUCCESS) + return 1; + + if (g_TestPrimitivesPerformance) + { + status = test_or_32u_speed(); + + if (status != SUCCESS) + return 1; + } + + return 0; +} diff --git a/libfreerdp/primitives/test/test_colors.c b/libfreerdp/primitives/test/TestPrimitivesColors.c similarity index 92% rename from libfreerdp/primitives/test/test_colors.c rename to libfreerdp/primitives/test/TestPrimitivesColors.c index 628cb5d5e..717328246 100644 --- a/libfreerdp/primitives/test/test_colors.c +++ b/libfreerdp/primitives/test/TestPrimitivesColors.c @@ -23,6 +23,8 @@ static const int RGB_TRIAL_ITERATIONS = 1000; static const int YCBCR_TRIAL_ITERATIONS = 1000; static const float TEST_TIME = 4.0; +extern BOOL g_TestPrimitivesPerformance; + extern pstatus_t general_RGBToRGB_16s8u_P3AC4R(const INT16 *pSrc[3], int srcStep, BYTE *pDst, int dstStep, const prim_size_t *roi); extern pstatus_t sse2_RGBToRGB_16s8u_P3AC4R(const INT16 *pSrc[3], @@ -241,3 +243,36 @@ int test_yCbCrToRGB_16s16s_P3P3_speed(void) size_array, 1, YCBCR_TRIAL_ITERATIONS, TEST_TIME); return SUCCESS; } + +int TestPrimitivesColors(int argc, char* argv[]) +{ + int status; + + status = test_RGBToRGB_16s8u_P3AC4R_func(); + + if (status != SUCCESS) + return 1; + + if (g_TestPrimitivesPerformance) + { + status = test_RGBToRGB_16s8u_P3AC4R_speed(); + + if (status != SUCCESS) + return 1; + } + + status = test_yCbCrToRGB_16s16s_P3P3_func(); + + if (status != SUCCESS) + return 1; + + if (g_TestPrimitivesPerformance) + { + status = test_yCbCrToRGB_16s16s_P3P3_speed(); + + if (status != SUCCESS) + return 1; + } + + return 0; +} diff --git a/libfreerdp/primitives/test/test_copy.c b/libfreerdp/primitives/test/TestPrimitivesCopy.c similarity index 89% rename from libfreerdp/primitives/test/test_copy.c rename to libfreerdp/primitives/test/TestPrimitivesCopy.c index 13b4f57f2..189969d7c 100644 --- a/libfreerdp/primitives/test/test_copy.c +++ b/libfreerdp/primitives/test/TestPrimitivesCopy.c @@ -26,6 +26,8 @@ static const int TEST_TIME = 1.0; // seconds extern pstatus_t sse3_copy_8u(const BYTE *pSrc, BYTE *pDst, int len); #endif +extern BOOL g_TestPrimitivesPerformance; + /* ------------------------------------------------------------------------- */ int test_copy8u_func(void) { @@ -84,3 +86,23 @@ int test_copy8u_speed(void) test_sizes, NUM_TEST_SIZES, MEMCPY_PRETEST_ITERATIONS, TEST_TIME); return SUCCESS; } + +int TestPrimitivesCopy(int argc, char* argv[]) +{ + int status; + + status = test_copy8u_func(); + + if (status != SUCCESS) + return 1; + + if (g_TestPrimitivesPerformance) + { + status = test_copy8u_speed(); + + if (status != SUCCESS) + return 1; + } + + return 0; +} diff --git a/libfreerdp/primitives/test/test_set.c b/libfreerdp/primitives/test/TestPrimitivesSet.c similarity index 92% rename from libfreerdp/primitives/test/test_set.c rename to libfreerdp/primitives/test/TestPrimitivesSet.c index 32d22c71d..3d689eeff 100644 --- a/libfreerdp/primitives/test/test_set.c +++ b/libfreerdp/primitives/test/TestPrimitivesSet.c @@ -23,6 +23,8 @@ static const int MEMSET8_PRETEST_ITERATIONS = 100000000; static const int MEMSET32_PRETEST_ITERATIONS = 40000000; static const float TEST_TIME = 1.0; +extern BOOL g_TestPrimitivesPerformance; + extern pstatus_t general_set_8u(BYTE val, BYTE *pDst, int len); extern pstatus_t sse2_set_8u(BYTE val, BYTE *pDst, int len); extern pstatus_t general_set_32s(INT32 val, INT32 *pDst, int len); @@ -303,3 +305,49 @@ int test_set32s_speed(void) #endif return SUCCESS; } + +int TestPrimitivesSet(int argc, char* argv[]) +{ + int status; + + status = test_set8u_func(); + + if (status != SUCCESS) + return 1; + + if (g_TestPrimitivesPerformance) + { + status = test_set8u_speed(); + + if (status != SUCCESS) + return 1; + } + + status = test_set32s_func(); + + if (status != SUCCESS) + return 1; + + if (g_TestPrimitivesPerformance) + { + status = test_set32s_speed(); + + if (status != SUCCESS) + return 1; + } + + status = test_set32u_func(); + + if (status != SUCCESS) + return 1; + + if (g_TestPrimitivesPerformance) + { + status = test_set32u_speed(); + + if (status != SUCCESS) + return 1; + } + + return 0; +} diff --git a/libfreerdp/primitives/test/test_shift.c b/libfreerdp/primitives/test/TestPrimitivesShift.c similarity index 88% rename from libfreerdp/primitives/test/test_shift.c rename to libfreerdp/primitives/test/TestPrimitivesShift.c index 588187a4b..693c12b34 100644 --- a/libfreerdp/primitives/test/test_shift.c +++ b/libfreerdp/primitives/test/TestPrimitivesShift.c @@ -23,6 +23,8 @@ static const int SHIFT_PRETEST_ITERATIONS = 50000; static const float TEST_TIME = 1.0; +extern BOOL g_TestPrimitivesPerformance; + extern pstatus_t general_lShiftC_16s( const INT16 *pSrc, int val, INT16 *pDst, int len); extern pstatus_t general_rShiftC_16s( @@ -187,3 +189,62 @@ int test_rShift_16u_speed(void) test_sizes, NUM_TEST_SIZES, SHIFT_PRETEST_ITERATIONS, TEST_TIME); return SUCCESS; } + +int TestPrimitivesShift(int argc, char* argv[]) +{ + int status; + + status = test_lShift_16s_func(); + + if (status != SUCCESS) + return 1; + + if (g_TestPrimitivesPerformance) + { + status = test_lShift_16s_speed(); + + if (status != SUCCESS) + return 1; + } + + status = test_lShift_16u_func(); + + if (status != SUCCESS) + return 1; + + if (g_TestPrimitivesPerformance) + { + status = test_lShift_16u_speed(); + + if (status != SUCCESS) + return 1; + } + + status = test_rShift_16s_func(); + + if (status != SUCCESS) + return 1; + + if (g_TestPrimitivesPerformance) + { + status = test_rShift_16s_speed(); + + if (status != SUCCESS) + return 1; + } + + status = test_rShift_16u_func(); + + if (status != SUCCESS) + return 1; + + if (g_TestPrimitivesPerformance) + { + status = test_rShift_16u_speed(); + + if (status != SUCCESS) + return 1; + } + + return 0; +} diff --git a/libfreerdp/primitives/test/test_sign.c b/libfreerdp/primitives/test/TestPrimitivesSign.c similarity index 90% rename from libfreerdp/primitives/test/test_sign.c rename to libfreerdp/primitives/test/TestPrimitivesSign.c index beb22ee1d..0d06d64bc 100644 --- a/libfreerdp/primitives/test/test_sign.c +++ b/libfreerdp/primitives/test/TestPrimitivesSign.c @@ -22,6 +22,8 @@ static const int SIGN_PRETEST_ITERATIONS = 100000; static const float TEST_TIME = 1.0; +extern BOOL g_TestPrimitivesPerformance; + extern pstatus_t general_sign_16s(const INT16 *pSrc, INT16 *pDst, int len); #ifdef WITH_SSE2 extern pstatus_t ssse3_sign_16s(const INT16 *pSrc, INT16 *pDst, int len); @@ -101,3 +103,23 @@ int test_sign16s_speed(void) test_sizes, NUM_TEST_SIZES, SIGN_PRETEST_ITERATIONS, TEST_TIME); return SUCCESS; } + +int TestPrimitivesSign(int argc, char* argv[]) +{ + int status; + + status = test_sign16s_func(); + + if (status != SUCCESS) + return 1; + + if (g_TestPrimitivesPerformance) + { + status = test_sign16s_speed(); + + if (status != SUCCESS) + return 1; + } + + return 0; +} diff --git a/libfreerdp/primitives/test/TestPrimitivesYCbCr.c b/libfreerdp/primitives/test/TestPrimitivesYCbCr.c new file mode 100644 index 000000000..0a1301ec5 --- /dev/null +++ b/libfreerdp/primitives/test/TestPrimitivesYCbCr.c @@ -0,0 +1,2183 @@ + +#include "prim_test.h" + +#include + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +static INT16 TEST_Y_COMPONENT[4096] = +{ + -32, +16, +64, +272, -32, -16, +0, -16, + -32, -24, -16, -8, +0, -24, -48, -72, + -96, -90, -84, -78, -72, -98, -124, -150, + -176, -192, -208, -224, -240, -256, -272, -288, + -304, -304, -304, -304, -304, -336, -368, -400, + -432, -450, -468, -486, -504, -522, -540, -558, + -576, -598, -620, -642, -664, -686, -708, -730, + -752, -768, -784, -800, -816, -816, -816, -816, + +68, +120, +172, +240, +53, +55, +57, +43, + +30, +32, +34, +36, +38, +20, +2, -16, + -34, -36, -38, -40, -42, -68, -94, -120, + -146, -148, -151, -186, -220, -227, -233, -240, + -247, -254, -261, -268, -275, -302, -329, -356, + -384, -403, -423, -443, -463, -484, -506, -528, + -550, -572, -594, -616, -639, -673, -707, -709, + -712, -733, -754, -775, -796, -796, -796, -796, + +168, +224, +281, +209, +138, +126, +115, +103, + +92, +88, +84, +80, +76, +64, +52, +40, + +28, +18, +8, -2, -12, -38, -64, -90, + -116, -105, -95, -148, -201, -198, -195, -192, + -190, -204, -218, -232, -247, -269, -291, -313, + -336, -357, -379, -400, -422, -447, -473, -498, + -524, -546, -569, -591, -614, -660, -707, -689, + -672, -698, -724, -750, -776, -776, -776, -776, + +268, +312, +357, +273, +191, +181, +172, +162, + +154, +144, +134, +124, +114, +108, +102, +80, + +58, +56, +54, +52, +50, +24, -2, -44, + -86, -61, -38, -93, -149, -137, -124, -144, + -165, -170, -175, -196, -218, -235, -252, -269, + -288, -310, -334, -357, -381, -409, -439, -468, + -498, -520, -543, -565, -589, -647, -706, -668, + -632, -663, -694, -725, -756, -756, -756, -756, + +368, +401, +434, +339, +244, +237, +230, +223, + +216, +200, +184, +168, +152, +152, +152, +120, + +88, +94, +100, +106, +112, +86, +60, +2, + -56, -18, +19, -39, -98, -76, -55, -97, + -140, -136, -133, -161, -190, -202, -215, -227, + -240, -265, -290, -315, -340, -373, -406, -439, + -472, -495, -518, -541, -564, -635, -706, -649, + -592, -628, -664, -700, -736, -736, -736, -736, + +404, +556, +454, +383, +313, +531, +239, +282, + +326, +304, +282, +260, +238, +246, +254, +118, + +238, +196, +154, +32, -90, -88, -86, +76, + +238, +243, +247, +29, -191, -232, -272, -121, + +29, -62, -153, -149, -145, -162, -180, -197, + -216, -240, -265, -289, -315, -345, -376, -406, + -438, -446, -456, -497, -539, -595, -653, -502, + -608, -625, -642, -675, -708, -708, -708, -708, + +440, +713, +475, +428, +382, +827, +249, +342, + +436, +408, +380, +352, +324, +340, +356, -140, + -124, +42, +208, +214, +220, +250, +280, +406, + +532, +504, +476, +352, +229, +125, +22, -146, + -314, -244, -175, -138, -101, -123, -146, -169, + -192, -216, -241, -265, -290, -318, -347, -375, + -404, -399, -395, -454, -514, -557, -601, -356, + -624, -622, -620, -650, -680, -680, -680, -680, + +604, +677, +495, +457, +419, +770, +354, +386, + +418, +416, +414, +380, +346, +258, -342, -302, + -6, +288, +582, +604, +626, +588, +550, +688, + +826, +829, +833, +724, +616, +481, +348, +181, + +15, -139, -292, -175, -56, -83, -112, -139, + -168, -192, -216, -240, -265, -291, -317, -343, + -370, -351, -333, -411, -489, -486, -484, -402, + -576, -587, -598, -625, -652, -652, -652, -652, + +1280, +1154, +1028, +998, +968, +970, +460, +430, + +400, +424, +448, +408, +368, +432, -528, -208, + +112, +534, +956, +994, +1032, +926, +820, +970, + +1120, +1155, +1190, +1097, +1004, +839, +674, +509, + +344, +223, +102, +45, -12, -45, -78, -111, + -144, -168, -192, -216, -240, -264, -288, -312, + -336, -304, -272, -368, -464, -416, -368, -448, + -528, -552, -576, -600, -624, -624, -624, -624, + +770, +671, +573, +554, +536, +629, +467, +464, + +462, +492, +523, +490, +457, +281, -405, -101, + +204, +599, +995, +1310, +1370, +1297, +1225, +1296, + +1368, +1432, +1498, +1402, +1308, +1184, +1062, +874, + +688, +586, +485, +303, +123, -82, -32, -76, + -122, -174, -226, -199, -171, -193, -216, -238, + -261, -314, -368, -325, -283, -360, -438, -451, + -465, -515, -565, -583, -601, -617, -633, -633, + +772, +701, +630, +623, +616, +545, +474, +499, + +524, +561, +599, +572, +546, +131, -283, +6, + +296, +665, +1034, +1627, +1708, +1669, +1630, +1623, + +1616, +1711, +1806, +1709, +1612, +1531, +1450, +1241, + +1032, +950, +869, +563, +258, -120, +15, -42, + -100, -180, -261, -182, -103, -123, -144, -165, + -186, -325, -464, -283, -102, -305, -508, -455, + -402, -478, -554, -566, -578, -610, -642, -642, + +774, +730, +687, +675, +664, +620, +577, +581, + +586, +597, +610, +590, +571, -147, -96, +209, + +516, +794, +1073, +1575, +1822, +1976, +1875, +1869, + +1864, +1988, +2114, +2014, +1916, +1876, +1838, +1606, + +1376, +1266, +1156, +902, +137, -61, -3, -120, + -238, -122, -7, -69, -130, -164, -200, -219, + -239, -271, -304, -128, -209, -297, -386, -426, + -467, -937, -895, -549, -459, -667, -619, -619, + +776, +760, +744, +728, +712, +696, +680, +664, + +648, +635, +622, +609, +596, -425, +90, +413, + +736, +924, +1112, +1524, +1936, +2284, +2120, +2116, + +2112, +2267, +2422, +2321, +2220, +2223, +2226, +1973, + +1720, +1582, +1444, +1242, +16, -2, -20, +58, + +136, -65, -267, -212, -158, -207, -257, -274, + -292, -218, -144, +26, -316, -290, -264, -142, + -20, +2956, +2860, -788, -852, -980, -596, -596, + +826, +807, +789, +770, +752, +749, +747, +744, + +742, +677, +613, +516, +421, -285, +288, +573, + +860, +1081, +1303, +1668, +2034, +2313, +2337, +2344, + +2352, +2452, +2554, +2574, +2596, +2506, +2418, +2248, + +2080, +1961, +1843, +925, +7, +40, +74, +748, + +654, +453, +251, +48, -154, -107, -61, -111, + -161, -28, +104, +45, -271, -274, -278, -842, + +1411, +3007, +3323, +327, -1389, -1197, -493, -493, + +876, +855, +834, +813, +792, +803, +814, +825, + +836, +720, +605, +681, +758, +110, +487, +735, + +984, +1239, +1494, +1813, +2132, +2343, +2554, +2573, + +2592, +2639, +2686, +2829, +2972, +2791, +2610, +2525, + +2440, +2341, +2243, +608, -2, +83, +169, +1438, + +1172, +970, +768, +565, +363, +249, +135, +52, + -30, -95, -160, -193, -226, -259, -292, +763, + -742, +2290, +1738, -1118, -902, -902, -390, -390, + +926, +902, +879, +855, +832, +824, +817, +809, + +802, +763, +724, +397, +2375, +970, +589, +848, + +1108, +1396, +1685, +1941, +2198, +2468, +2739, +2785, + +2832, +2888, +2946, +3178, +2900, +3058, +2962, +2848, + +2736, +2896, +2546, -364, +309, +205, +871, +1760, + +1626, +1471, +1317, +1145, +975, +844, +714, +599, + +485, +351, +216, +146, +75, -355, +750, +2687, + +529, -1067, -615, -835, -799, -847, -383, -383, + +976, +950, +924, +898, +872, +846, +820, +794, + +768, +806, +844, +882, +1432, +2598, +692, +962, + +1232, +1554, +1876, +2070, +2264, +2594, +2924, +2998, + +3072, +3139, +3206, +3273, +2316, +3071, +3314, +3173, + +3032, +2941, +1826, -57, +108, +73, +1574, +2083, + +2080, +1973, +1866, +1727, +1588, +1441, +1294, +1147, + +1000, +796, +592, +484, +376, +828, +256, +772, + -248, -72, -408, +984, -184, -536, -376, -376, + +1026, +997, +969, +941, +913, +888, +864, +840, + +816, +762, +709, +768, +1339, +2269, +2176, +1411, + +1414, +1677, +1941, +2188, +2436, +2730, +3023, +3157, + +3291, +3349, +3409, +3420, +2152, +3000, +3594, +3403, + +3213, +3233, +951, +12, +97, -303, +2883, +2755, + +2373, +2312, +2252, +2143, +2036, +1861, +1687, +1544, + +1403, +1254, +1106, +974, +842, +1229, +1105, +21, + +217, +46, -381, +1912, +3181, +2765, +301, -723, + +1076, +1045, +1015, +984, +954, +931, +909, +886, + +864, +719, +575, +654, +1246, +1685, +3149, +1604, + +1596, +1801, +2006, +2307, +2609, +2866, +3123, +3316, + +3510, +3561, +3613, +3568, +1988, +2931, +3875, +3634, + +3394, +3527, +76, +81, +86, +859, +3168, +2917, + +2666, +2652, +2639, +2561, +2484, +2282, +2081, +1943, + +1806, +1713, +1621, +1464, +1308, +1119, +931, +550, + +170, -92, -354, +1560, +3986, +1970, -558, -558, + +1126, +1092, +1060, +1027, +995, +973, +953, +932, + +912, +899, +888, -340, +1249, +1756, +2521, +2421, + +1810, +2036, +2263, +2521, +2781, +3066, +3350, +3443, + +3537, +3612, +3688, +3476, +2496, +3021, +3803, +3833, + +3863, +2843, +33, +133, -21, +2099, +3197, +3061, + +2927, +2944, +2961, +2882, +2804, +2607, +2410, +2309, + +2209, +2139, +2071, +1842, +1614, +1328, +1044, +663, + +283, +10, -263, -488, -201, -201, -457, -457, + +1176, +1141, +1106, +1071, +1036, +1017, +998, +979, + +960, +825, +690, +203, +740, +1573, +1894, +3239, + +2024, +2272, +2521, +2737, +2954, +3010, +3067, +3315, + +3564, +3664, +3764, +3384, +3004, +3112, +3732, +3776, + +3820, +1905, -10, +187, -128, +3341, +3226, +3207, + +3188, +3236, +3284, +3204, +3124, +2932, +2740, +2676, + +2612, +2567, +2522, +2221, +1920, +1539, +1158, +777, + +396, +112, -172, -488, -292, -324, -356, -356, + +1194, +1162, +1131, +1099, +1069, +1047, +1026, +972, + +920, +969, +507, +380, +767, +1428, +1834, +2799, + +2486, +2347, +2721, +2919, +3118, +3290, +3462, +3266, + +3071, +3157, +3243, +3521, +3800, +3674, +3548, +3710, + +3873, +874, +179, +91, +517, +3439, +3291, +3333, + +3377, +3403, +3430, +3361, +3292, +3174, +3057, +3004, + +2951, +2761, +2572, +2222, +1874, +1554, +1235, +883, + +533, +220, -93, -470, -335, -319, -303, -303, + +1212, +1184, +1157, +1129, +1102, +1078, +1055, +967, + +880, +1114, +325, +559, +794, +1284, +1775, +2361, + +2948, +2423, +2923, +3103, +3283, +3314, +3346, +3474, + +3602, +3674, +3747, +3659, +3572, +3980, +3877, +3901, + +3926, -157, +368, +253, +1674, +3795, +3356, +3461, + +3566, +3571, +3577, +3518, +3460, +3417, +3375, +3332, + +3290, +2956, +2623, +2225, +1828, +1570, +1313, +991, + +670, +328, -14, -452, -378, -314, -250, -250, + +1230, +1206, +1182, +1158, +1135, +1109, +1083, +1025, + +968, +779, +78, +481, +885, +1284, +1939, +2466, + +3250, +2626, +2772, +3157, +3543, +3514, +3486, +3729, + +3717, +3775, +3834, +3780, +3728, +3934, +3885, +3915, + +2667, +92, +333, +173, +2831, +3701, +3549, +3587, + +3627, +3642, +3659, +3643, +3628, +3675, +3724, +3436, + +3149, +2847, +2545, +2275, +2006, +1730, +1454, +1114, + +775, +388, +1, -402, -293, -309, -325, -325, + +1248, +1228, +1208, +1188, +1168, +1140, +1112, +1084, + +1056, +700, +344, +660, +976, +1284, +2104, +2316, + +3040, +2319, +2110, +2189, +2268, +2691, +3114, +3729, + +3832, +3877, +3922, +3903, +3884, +3889, +3894, +3931, + +1408, +341, +298, +95, +3988, +3609, +3742, +3715, + +3688, +3715, +3742, +3769, +3796, +3679, +3562, +3285, + +3008, +2738, +2468, +2326, +2184, +1890, +1596, +1238, + +880, +448, +16, -352, -208, -304, -400, -400, + +1296, +1284, +1272, +1260, +1249, +1165, +1081, +1093, + +1106, +232, +382, +677, +971, +973, +1232, +834, + +693, +537, +639, +564, +490, +563, +637, -106, + +944, +2358, +3773, +3795, +4074, +3964, +3855, +4337, + +212, +204, +197, +1341, +4023, +3813, +3860, +3810, + +3762, +3766, +3771, +3776, +3781, +3603, +3427, +3201, + +2977, +2838, +2699, +2400, +2101, +1982, +1607, +1280, + +954, +545, -120, -321, -266, -314, -362, -362, + +1344, +1340, +1337, +1333, +1330, +1190, +1051, +1103, + +1156, +20, +933, +950, +967, +919, +872, +889, + +906, +805, +705, +733, +761, +740, +720, +668, + +616, +328, +40, +1640, +3752, +3784, +3816, +3208, + +40, +581, +97, +2589, +4058, +4018, +3979, +3907, + +3836, +3818, +3801, +3784, +3767, +3529, +3292, +3375, + +3458, +3706, +3954, +3754, +3555, +2843, +1619, +1067, + +516, +386, -256, -290, -324, -324, -324, -324, + +1392, +1364, +1337, +1309, +1283, +1247, +1212, +968, + +982, +1424, +1099, +1079, +1058, +1072, +1088, +815, + +799, +1056, +802, +772, +743, +645, +547, +769, + +736, +649, +563, +332, +102, +1939, +4033, +1982, + +444, +332, -36, +4076, +4093, +4047, +4001, +3955, + +3910, +3870, +3830, +3791, +3752, +3806, +3861, +3835, + +3811, +3678, +3545, +3380, +3216, +3639, +3806, +2341, + +1134, +1091, +24, -387, -286, -286, -286, -286, + +1440, +1389, +1338, +1287, +1236, +1305, +1374, +1091, + +1320, +1037, +1267, +1208, +1150, +715, +281, +486, + +1204, +1564, +901, +1325, +1750, +1830, +1911, +1383, + +344, +459, +574, +817, +548, +351, +666, +757, + +336, +340, +856, +4028, +4128, +4076, +4024, +4004, + +3984, +3922, +3861, +3799, +3738, +3828, +3919, +3785, + +3652, +3394, +3137, +3007, +2878, +2900, +2923, +3105, + +3800, +1284, +1328, +28, -248, -248, -248, -248, + +1456, +1406, +1358, +1309, +1261, +1209, +1159, +1444, + +1218, +1265, +33, -654, -1342, -977, -356, +394, + +1401, +1753, +1338, +1738, +2140, +2575, +3009, +3524, + +3784, +2536, +1033, +265, +522, +440, +615, +629, + +388, +403, +2211, +4051, +4099, +4078, +4058, +3990, + +3922, +3910, +3898, +3886, +3875, +3805, +3735, +3553, + +3373, +3126, +2879, +2585, +2291, +2026, +1762, +2649, + +3026, +2303, +2092, +665, -250, -250, -250, -250, + +1472, +1425, +1379, +1332, +1286, +1371, +1457, +1030, + -932, -1834, -1712, -1237, -763, -621, +33, +815, + +1598, +1943, +1776, +2153, +2531, +2808, +3085, +3362, + +3640, +4102, +4052, +3042, +496, +530, +564, +502, + +440, +211, +3055, +3818, +4070, +4081, +4093, +3976, + +3860, +3898, +3936, +3974, +4013, +3783, +3553, +3323, + +3094, +2858, +2623, +2420, +2217, +1921, +1626, +915, + +2764, +250, +296, +22, -252, -252, -252, -252, + +1488, +1443, +1399, +1371, +1343, +1308, +1530, -408, + -1834, -1589, -1089, -811, -535, -281, +485, +1171, + +1859, +2132, +2150, +2503, +2857, +3105, +3352, +3536, + +3720, +3875, +3775, +4298, +4054, +2123, +449, +502, + +556, +546, +26, +2113, +3945, +4115, +4031, +3946, + +3862, +3838, +3814, +3982, +3894, +3488, +3338, +3140, + +2943, +2622, +2302, +2030, +1758, +1495, +1234, +1259, + +774, -347, -188, -189, -190, -222, -254, -254, + +1504, +1462, +1420, +1410, +1400, +1246, +1604, -1334, + -1712, -1089, -978, -643, -308, +59, +938, +1529, + +2120, +2322, +2524, +2854, +3184, +3402, +3620, +3710, + +3800, +3905, +4010, +4019, +4028, +3973, +334, +503, + +672, +627, +582, +409, +236, +2359, +3970, +3917, + +3864, +3778, +3692, +3990, +3776, +3194, +3124, +2958, + +2792, +2387, +1982, +1641, +1300, +1071, +842, +69, + -192, -176, -160, -144, -128, -192, -256, -256, + +1546, +1496, +1447, +1430, +1413, +1627, +1330, -2102, + -1184, -819, -712, -395, -80, +405, +1148, +1713, + +2280, +2486, +2692, +2995, +3297, +3467, +3638, +3712, + +3787, +3915, +4045, +3917, +4047, +3097, +357, +655, + +699, +198, +466, +381, +297, +376, +200, +1815, + +3431, +3568, +3961, +4114, +3755, +3310, +3121, +2804, + +2487, +2208, +1931, +1189, +447, +37, -116, -254, + -136, -111, -86, -109, -132, -196, -260, -260, + +1588, +1531, +1475, +1450, +1426, +1497, +33, -1591, + -1168, -807, -446, -149, +148, +753, +1358, +1899, + +2440, +2650, +2861, +3136, +3411, +3533, +3656, +3715, + +3774, +3927, +4080, +3817, +4066, +2223, +380, +553, + +214, +3610, +350, +354, +358, +442, +526, +226, + -74, +286, +1158, +1678, +1686, +1634, +1582, +1114, + +646, +239, -168, -31, +107, -228, -51, -65, + -80, -46, -12, -74, -136, -200, -264, -264, + +1630, +1565, +1502, +1470, +1439, +1590, -817, -1399, + -960, -633, -308, -14, +280, +875, +1472, +1971, + +2472, +2718, +2965, +3229, +3492, +3582, +3674, +3701, + +3729, +3793, +3859, +4147, +4181, +707, +563, +417, + +1297, +3917, +4234, +2198, +163, +267, +372, +348, + +325, +108, +147, +186, -31, +38, +107, +96, + +85, +61, +38, -162, -106, -126, +111, +876, + -152, -93, -34, -87, -140, -204, -268, -268, + +1672, +1601, +1530, +1491, +1452, +1685, -1666, -1209, + -752, -461, -170, +121, +412, +999, +1586, +2045, + +2504, +2787, +3071, +3322, +3574, +3633, +3693, +3688, + +3684, +3661, +3638, +3711, +2760, +473, +746, +283, + +2380, +4225, +4022, +4043, +4064, +2141, +218, +215, + +212, +186, +160, +230, +300, +234, +168, +102, + +36, -117, -269, +218, +1218, +2025, +2833, +1048, + -224, -140, -56, -100, -144, -208, -272, -272, + +1626, +1607, +1589, +1458, +1585, +692, -1479, -1107, + -736, -451, -168, +115, +400, +805, +1468, +1937, + +2408, +2703, +2999, +3327, +3655, +3568, +3482, +3620, + +3759, +3439, +3121, +1601, +851, +819, +533, +437, + +3415, +4252, +4066, +4055, +4045, +4084, +4124, +2995, + +1867, +1068, +269, +62, -145, -38, +69, +704, + +1339, +2183, +3028, +2816, +2861, +2953, +2790, -349, + +96, -19, -134, -137, -140, -204, -268, -268, + +1580, +1614, +1649, +1427, +1718, -300, -1293, -1006, + -720, -443, -166, +111, +388, +613, +1350, +1831, + +2312, +2620, +2928, +3076, +3225, +3249, +3273, +3297, + +3322, +3475, +3628, +3333, +1502, +655, +832, +593, + +3938, +4024, +4110, +4068, +4026, +3980, +3934, +3984, + +4034, +3998, +3962, +3990, +4018, +3786, +3554, +3610, + +3666, +3459, +3253, +3111, +2969, +2858, +2236, -210, + -96, -154, -212, -174, -136, -200, -264, -264, + +1662, +1653, +1644, +1619, +1851, -988, -1266, -985, + -704, -401, -100, +9, +120, +403, +944, +1579, + +2216, +2504, +2793, +2873, +2954, +2976, +2999, +3085, + +3173, +3237, +3303, +3575, +521, +553, +587, +1771, + +3981, +4019, +4058, +4032, +4007, +3971, +3936, +3948, + +3961, +3920, +3879, +3806, +3989, +3866, +3743, +3636, + +3529, +3375, +3222, +3069, +2916, +2907, +1362, -119, + -64, -113, -162, -147, -132, -196, -260, -260, + +1744, +1692, +1640, +1556, +1472, -1932, -1240, -964, + -688, -361, -34, +165, +364, +707, +1050, +1585, + +2120, +2389, +2658, +2671, +2684, +2705, +2726, +2875, + +3024, +3001, +2978, +2283, +564, +965, +342, +2951, + +4024, +4015, +4006, +3997, +3988, +3963, +3938, +3913, + +3888, +3842, +3796, +3622, +3960, +3946, +3932, +3662, + +3392, +3292, +3192, +3028, +2864, +2956, +488, -28, + -32, -72, -112, -120, -128, -192, -256, -256, + +1834, +1635, +1692, +1718, +208, -1663, -1229, -924, + -619, -283, +50, +256, +719, +705, +948, +1126, + +1562, +1845, +2129, +2236, +2344, +2447, +2551, +2654, + +2759, +2738, +2719, +1562, +663, +623, +327, +4207, + +3992, +4012, +4034, +3990, +3948, +3922, +3898, +3872, + +3848, +3774, +3701, +3484, +3523, +3726, +3929, +3812, + +3695, +3604, +3513, +3407, +3300, +3350, -440, -231, + -22, -48, -74, -100, -126, -174, -222, -222, + +1924, +1578, +1745, +1880, -1057, -1394, -1219, -884, + -550, -207, +135, +93, +563, +449, +847, +669, + +1004, +1302, +1600, +1802, +2005, +2191, +2377, +2435, + +2494, +2477, +2460, +843, +763, +794, +1337, +3928, + +3960, +4011, +4062, +3985, +3908, +3883, +3858, +3833, + +3808, +3707, +3607, +3603, +3599, +3506, +3414, +3706, + +3998, +3916, +3835, +3786, +3737, +2208, -345, +78, + -12, -24, -36, -80, -124, -156, -188, -188, + +1598, +1585, +1829, +2154, -1873, -1413, -1208, -556, + -417, -514, -102, +440, +214, +191, +681, +435, + +702, +870, +1039, +1224, +1409, +1709, +2010, +2039, + +2069, +2086, +1849, +795, +766, +596, +2474, +3953, + +3896, +3928, +3962, +3914, +3868, +3842, +3818, +3792, + +3768, +3687, +3608, +3577, +3546, +3462, +3379, +3312, + +3245, +3364, +3484, +3189, +2893, +858, -154, +35, + -34, -48, -62, -108, -154, -154, -154, -154, + +1784, +1849, +1915, +892, -1666, -1176, -1711, -741, + -796, -822, +175, -748, +378, +191, +517, +202, + +400, +439, +479, +646, +814, +1229, +1645, +1644, + +1644, +1697, +1239, +748, +770, +399, +3613, +3978, + +3832, +3847, +3862, +3845, +3828, +3803, +3778, +3753, + +3728, +3669, +3611, +3552, +3494, +3419, +3345, +3174, + +3004, +2813, +2623, +2592, +2562, -237, +37, -9, + -56, -72, -88, -136, -184, -152, -120, -120, + +1802, +1900, +2255, -286, -1290, -1129, -712, -391, + -327, -385, -445, +201, -178, +436, +27, -45, + -118, +204, +270, +384, +498, +685, +874, +998, + +1123, +1252, +1127, +794, +717, +1161, +3654, +3843, + +3776, +3788, +3802, +3782, +3764, +3616, +3726, +3690, + +3656, +3595, +3536, +3476, +3417, +3341, +3265, +3078, + +2891, +2687, +2484, +2617, +1982, -28, +8, +14, + +18, -18, -54, +6, +66, -30, -126, -126, + +1820, +1696, +2084, -2232, -1939, -570, -1762, -1834, + -1394, -461, -552, -387, -223, -1110, -462, -37, + -124, -31, -451, -134, +183, +143, +104, +353, + +602, +809, +1017, +841, +665, +1924, +3696, +3708, + +3720, +3731, +3742, +3721, +3700, +3431, +3674, +3629, + +3584, +3523, +3462, +3401, +3341, +3264, +3187, +2982, + +2778, +2562, +2346, +2386, +891, -77, -20, +36, + +92, +36, -20, -108, -196, -164, -132, -132, + +1710, +1955, +1177, -2833, -955, -2075, -2172, -364, + -1885, -1352, -820, -1599, -843, -1249, -887, -652, + -674, -554, -435, -636, -325, -304, -282, -101, + -175, +493, +906, +871, +580, +2767, +3674, +3653, + +3632, +3656, +3682, +3626, +3572, +3436, +3558, +3534, + +3512, +3449, +3388, +3325, +3264, +3186, +3108, +2902, + +2697, +2500, +2304, +2219, +343, +179, +271, +154, + +38, -6, -50, -110, -170, -154, -138, -138, + +1600, +1959, -242, -2667, -2020, -2557, -2582, -1455, + +696, +316, +960, +2052, +2120, +1940, +1760, +1292, + +824, -310, -932, -1394, -832, -750, -668, -298, + -440, +434, +796, +902, +496, +3610, +3652, +3598, + +3544, +3583, +3622, +3533, +3444, +3443, +3442, +3441, + +3440, +3377, +3314, +3251, +3188, +3109, +3030, +2823, + +2616, +2439, +2262, +2053, -204, +179, +50, +17, + -16, -48, -80, -112, -144, -144, -144, -144, + +1956, +1852, -2091, -3025, -1145, +322, +2045, +1672, + +1555, +1328, +1614, +1916, +1706, +1622, +1282, +1502, + +1466, +1301, +1393, +940, -792, -1548, -768, -820, + -617, +926, +934, +909, +1397, +3323, +3456, +3446, + +3436, +3393, +3351, +3388, +3426, +3373, +3321, +3444, + +3313, +3264, +3217, +3153, +3090, +2997, +2906, +2686, + +2467, +2290, +2115, +1282, -61, +136, +79, +36, + -5, -37, -69, -101, -133, -133, -133, -133, + +1800, +1746, +669, +1992, +1779, +1665, +1552, +1727, + +1390, +1317, +1245, +1269, +1293, +1560, +1316, +1456, + +1084, +1121, +1158, +971, +1297, +726, -869, -1343, + -794, +1419, +1072, +917, +2299, +3036, +3261, +3294, + +3328, +3204, +3080, +3244, +3409, +3305, +3201, +3449, + +3186, +3153, +3121, +3056, +2992, +2887, +2783, +2550, + +2318, +2143, +1968, +513, +82, +95, +108, +57, + +6, -26, -58, -90, -122, -122, -122, -122, + +1516, +1832, +1636, +1905, +1406, +1344, +1283, +1589, + +1641, +1465, +1291, +1277, +1263, +1386, +1254, +1314, + +1118, +1116, +1115, +905, +953, +1160, +1111, +118, + -363, +807, +698, +700, +2240, +3325, +2361, +2934, + +3252, +2998, +2745, +2924, +3103, +3155, +2952, +3277, + +3091, +3057, +3024, +2959, +2894, +2776, +2659, +2414, + +2169, +2074, +1981, +255, +65, +68, +73, +44, + +17, -15, -47, -79, -111, -111, -111, -111, + +1744, +1662, +1581, +1563, +1546, +1536, +1527, +1453, + +1380, +1359, +1339, +1286, +1234, +1213, +1193, +1172, + +1152, +1112, +1073, +1097, +1122, +826, +1043, +1067, + +1092, +964, +837, +741, +2182, +2078, +2487, +2831, + +2664, +2793, +2923, +2860, +2798, +3007, +2705, +3106, + +2996, +2962, +2928, +2862, +2796, +2666, +2536, +2278, + +2020, +1751, +1482, -259, +48, +43, +38, +33, + +28, -4, -36, -68, -100, -100, -100, -100, + +1684, +1640, +1596, +1584, +1573, +1543, +1513, +1451, + +1391, +1359, +1329, +1282, +1236, +1213, +1190, +1168, + +1146, +1107, +1069, +1063, +1058, +920, +1038, +996, + +955, +924, +894, +880, +1635, +1679, +2235, +2439, + +2132, +2451, +2771, +2580, +2644, +2713, +2528, +2742, + +2701, +2828, +2699, +2570, +2442, +2383, +2324, +2105, + +1887, +1732, +811, -79, +55, +62, +71, +46, + +23, -7, -37, -67, -97, -113, -129, -129, + +1624, +1618, +1612, +1606, +1601, +1551, +1501, +1451, + +1402, +1361, +1320, +1279, +1239, +1214, +1189, +1164, + +1140, +1103, +1067, +1031, +995, +1014, +1034, +926, + +818, +885, +953, +1021, +1089, +1024, +1472, +2048, + +2112, +2110, +2109, +2044, +2491, +2421, +2352, +2379, + +2406, +2694, +2471, +2279, +2088, +2100, +2113, +1933, + +1754, +1715, +140, +101, +62, +83, +104, +61, + +18, -10, -38, -66, -94, -126, -158, -158, + +1724, +1788, +1852, +1692, +1532, +1494, +1456, +1418, + +1381, +1345, +1311, +1275, +1241, +1214, +1187, +1160, + +1134, +1098, +1064, +1029, +995, +996, +998, +935, + +873, +877, +883, +792, +702, +657, +1125, +1832, + +2284, +1193, +1638, +1796, +2209, +2320, +2176, +2239, + +2047, +2560, +2562, +1891, +1734, +1673, +1613, +1744, + +1621, +1152, -83, -8, +69, +70, +73, +42, + +13, -13, -39, -65, -91, -139, -187, -187, + +1824, +1702, +1580, +1522, +1464, +1438, +1412, +1386, + +1360, +1331, +1302, +1273, +1244, +1215, +1186, +1157, + +1128, +1095, +1062, +1029, +996, +979, +962, +945, + +928, +871, +814, +821, +828, +803, +1290, +1617, + +1944, +2068, +1168, +1292, +1416, +1708, +1488, +1844, + +1688, +2171, +2142, +1249, +1380, +1503, +1626, +1045, + -48, +79, +206, +141, +76, +59, +42, +25, + +8, -16, -40, -64, -88, -152, -216, -216, + +1688, +1615, +1542, +1501, +1460, +1429, +1398, +1367, + +1336, +1309, +1284, +1257, +1232, +1205, +1180, +1153, + +1128, +1092, +1058, +1022, +988, +968, +950, +930, + +912, +861, +812, +793, +776, +595, +672, +971, + +1272, +330, +924, +1038, +1152, +1298, +1444, +1910, + +1608, +1531, +1200, +515, +344, +259, +176, +251, + +72, +122, +174, +128, +84, +64, +46, +26, + +8, -18, -44, -70, -96, -144, -192, -192, + +1552, +1528, +1504, +1480, +1456, +1420, +1384, +1348, + +1312, +1289, +1266, +1243, +1220, +1197, +1174, +1151, + +1128, +1091, +1054, +1017, +980, +959, +938, +917, + +896, +853, +810, +767, +724, +645, +566, +583, + +600, +640, +680, +528, +376, +376, +888, +1464, + +1016, +637, +258, +295, +332, +297, +262, +227, + +192, +167, +142, +117, +92, +71, +50, +29, + +8, -20, -48, -76, -104, -136, -168, -168, + +1544, +1521, +1498, +1475, +1452, +1411, +1370, +1329, + +1288, +1267, +1248, +1227, +1208, +1187, +1168, +1147, + +1128, +1088, +1050, +1010, +972, +948, +926, +902, + +880, +843, +808, +771, +736, +677, +620, +609, + +600, +614, +628, +546, +464, +238, +2060, +1690, + +1576, +1709, +308, +313, +320, +285, +252, +217, + +184, +162, +142, +120, +100, +76, +54, +30, + +8, -22, -52, -82, -112, -128, -144, -144, + +1536, +1514, +1492, +1470, +1448, +1402, +1356, +1310, + +1264, +1247, +1230, +1213, +1196, +1179, +1162, +1145, + +1128, +1087, +1046, +1005, +964, +939, +914, +889, + +864, +835, +806, +777, +748, +711, +674, +637, + +600, +588, +576, +564, +552, +612, +160, +1916, + +1112, +223, +358, +333, +308, +275, +242, +209, + +176, +159, +142, +125, +108, +83, +58, +33, + +8, -24, -56, -88, -120, -120, -120, -120, + +1536, +1514, +1492, +1470, +1448, +1402, +1356, +1310, + +1264, +1246, +1230, +1212, +1196, +1178, +1162, +1144, + +1128, +1086, +1046, +1004, +964, +938, +914, +888, + +864, +834, +806, +776, +748, +710, +674, +636, + +600, +588, +576, +564, +552, +644, +480, +108, + +504, +158, +326, +316, +308, +274, +242, +208, + +176, +158, +142, +124, +108, +82, +58, +32, + +8, -24, -56, -88, -120, -120, -120, -120, + +1536, +1514, +1492, +1470, +1448, +1402, +1356, +1310, + +1264, +1247, +1230, +1213, +1196, +1179, +1162, +1145, + +1128, +1087, +1046, +1005, +964, +939, +914, +889, + +864, +835, +806, +777, +748, +711, +674, +637, + +600, +588, +576, +564, +552, +420, +288, +348, + +408, +351, +294, +301, +308, +275, +242, +209, + +176, +159, +142, +125, +108, +83, +58, +33, + +8, -24, -56, -88, -120, -120, -120, -120, + +1536, +1514, +1492, +1470, +1448, +1402, +1356, +1310, + +1264, +1246, +1230, +1212, +1196, +1178, +1162, +1144, + +1128, +1086, +1046, +1004, +964, +938, +914, +888, + +864, +834, +806, +776, +748, +710, +674, +636, + +600, +588, +576, +564, +552, +420, +288, +348, + +408, +350, +294, +300, +308, +274, +242, +208, + +176, +158, +142, +124, +108, +82, +58, +32, + +8, -24, -56, -88, -120, -120, -120, -120 +}; + +static INT16 TEST_CB_COMPONENT[4096] = +{ + +1728, +1730, +1732, +1734, +1736, +1738, +1740, +1742, + +1744, +1740, +1736, +1732, +1728, +1796, +1864, +1804, + +1744, +1754, +1764, +1774, +1784, +1794, +1804, +1814, + +1824, +1774, +1724, +1802, +1880, +1814, +1748, +1810, + +1872, +1878, +1884, +1890, +1896, +1910, +1924, +1938, + +1952, +1938, +1924, +1910, +1896, +1914, +1932, +1950, + +1968, +1974, +1980, +1986, +1992, +1998, +2004, +2010, + +2016, +2016, +2016, +2016, +2016, +2016, +2016, +2016, + +1710, +1697, +1684, +1704, +1723, +1726, +1730, +1733, + +1737, +1738, +1740, +1741, +1743, +1758, +1774, +1757, + +1741, +1762, +1783, +1788, +1793, +1774, +1755, +1784, + +1813, +1817, +1821, +1825, +1829, +1857, +1885, +1881, + +1877, +1849, +1821, +1857, +1894, +1904, +1914, +1924, + +1935, +1928, +1922, +1915, +1909, +1922, +1936, +1949, + +1963, +1974, +1985, +1997, +2008, +2009, +2011, +2012, + +2014, +2017, +2020, +2023, +2026, +2026, +2026, +2026, + +1692, +1664, +1637, +1674, +1711, +1715, +1720, +1725, + +1730, +1737, +1744, +1751, +1758, +1721, +1684, +1711, + +1738, +1770, +1802, +1802, +1802, +1754, +1706, +1754, + +1802, +1860, +1918, +1848, +1778, +1900, +2022, +1952, + +1882, +1820, +1759, +1825, +1892, +1898, +1905, +1911, + +1918, +1919, +1920, +1921, +1922, +1931, +1940, +1949, + +1958, +1974, +1991, +2008, +2025, +2021, +2018, +2015, + +2012, +2018, +2024, +2030, +2036, +2036, +2036, +2036, + +1674, +1631, +1589, +1644, +1698, +1703, +1710, +1716, + +1723, +1735, +1748, +1760, +1773, +1763, +1754, +1760, + +1767, +1794, +1821, +1800, +1779, +1830, +1881, +1900, + +1919, +2047, +2175, +2015, +1855, +1879, +1903, +1927, + +1951, +1759, +1824, +1856, +1890, +1892, +1895, +1897, + +1901, +1909, +1918, +1926, +1935, +1939, +1944, +1948, + +1953, +1974, +1996, +2019, +2041, +2032, +2025, +2017, + +2010, +2019, +2028, +2037, +2046, +2046, +2046, +2046, + +1656, +1599, +1543, +1614, +1686, +1693, +1701, +1708, + +1716, +1734, +1752, +1770, +1788, +1806, +1824, +1810, + +1796, +1818, +1840, +2054, +2268, +1650, +1032, +510, + -12, -70, -128, +390, +908, +1602, +2296, +2158, + +2020, +1699, +1890, +1889, +1888, +1887, +1886, +1885, + +1884, +1900, +1916, +1932, +1948, +1948, +1948, +1948, + +1948, +1975, +2003, +2030, +2058, +2045, +2033, +2020, + +2008, +2020, +2032, +2044, +2056, +2056, +2056, +2056, + +1590, +1570, +1551, +1612, +1673, +1579, +1742, +1713, + +1685, +1672, +1660, +1711, +1763, +1694, +1626, +1941, + +2001, +2060, +583, -654, -1891, -2046, -2201, -2084, + -1967, -2049, -2131, -2053, -1975, -1751, -1527, +41, + +1609, +2374, +1859, +2000, +1886, +1898, +1912, +1909, + +1907, +1900, +1894, +1919, +1945, +1944, +1944, +1943, + +1943, +1967, +1992, +2017, +2042, +2032, +2023, +2014, + +2006, +2017, +2028, +2039, +2050, +2050, +2050, +2050, + +1524, +1542, +1560, +1610, +1661, +1467, +1785, +1719, + +1654, +1611, +1568, +1653, +1738, +1839, +1940, +793, + -866, -2050, -2210, -2082, -1954, -1902, -1850, -1862, + -1874, -1980, -2086, -1936, -1786, -1776, -1766, -1820, + -1874, -534, +1829, +2112, +1884, +1911, +1939, +1934, + +1930, +1901, +1872, +1907, +1942, +1941, +1940, +1939, + +1938, +1960, +1982, +2004, +2027, +2021, +2015, +2009, + +2004, +2014, +2024, +2034, +2044, +2044, +2044, +2044, + +1586, +1641, +1697, +1704, +1712, +1577, +1699, +1660, + +1623, +1613, +1604, +1642, +1681, +1791, -402, -2036, + -1877, -2144, -1899, -1942, -1985, -1918, -1851, -1880, + -1909, -1959, -2009, -1931, -1853, -1801, -1749, -1617, + -1485, -1939, -1882, +96, +2074, +1971, +1869, +1895, + +1921, +1885, +1850, +1894, +1939, +1937, +1936, +1934, + +1933, +1952, +1972, +1991, +2011, +2008, +2006, +2003, + +2002, +2011, +2020, +2029, +2038, +2038, +2038, +2038, + +1136, +1229, +1322, +1287, +1252, +1433, +1614, +1603, + +1592, +1616, +1640, +1632, +1624, +2256, -1720, -1792, + -1864, -1982, -2100, -2058, -2016, -1934, -1852, -1898, + -1944, -1938, -1932, -1926, -1920, -1826, -1732, -1670, + -1608, -1552, -1496, -1664, -1320, +2288, +1800, +1856, + +1912, +1870, +1828, +1882, +1936, +1934, +1932, +1930, + +1928, +1945, +1962, +1979, +1996, +1997, +1998, +1999, + +2000, +2008, +2016, +2024, +2032, +2032, +2032, +2032, + +1552, +1624, +1698, +1674, +1652, +1644, +1638, +1614, + +1592, +1611, +1630, +1681, +1733, +1146, -2000, -1787, + -1830, -1924, -2019, -2049, -2080, -1986, -1893, -1895, + -1898, -1896, -1894, -1860, -1827, -1779, -1731, -1667, + -1604, -1615, -1626, -1878, -594, +2063, +1903, +2016, + +1873, +2132, +1880, +1884, +1888, +1921, +1955, +1941, + +1927, +1925, +1925, +1955, +1987, +2005, +2025, +2043, + +2063, +1995, +1927, +2099, +2015, +2095, +2175, +2175, + +1456, +1509, +1562, +1551, +1540, +1601, +1662, +1627, + +1592, +1606, +1621, +1731, +1842, +37, -2281, -1782, + -1796, -1867, -1938, -2041, -2144, -2039, -1934, -1893, + -1852, -1854, -1857, -1795, -1734, -1732, -1731, -1665, + -1600, -1678, -1757, -1836, +645, +2094, +2007, +1920, + +1322, +2139, +1933, +1886, +1840, +1909, +1979, +1952, + +1926, +1907, +1888, +1933, +1978, +2015, +2052, +2089, + +2126, +1982, +1838, +2174, +1998, +2158, +2318, +2318, + +1488, +1520, +1554, +1554, +1556, +1588, +1622, +1606, + +1592, +1569, +1547, +1700, +1855, -993, -2049, -1825, + -1858, -1905, -1953, -2016, -2080, -1995, -1911, -1858, + -1806, -1812, -1819, -1729, -1641, -1685, -1730, -1678, + -1628, -1677, -1727, -2194, +1947, +2125, +2046, +945, + -2205, +114, +2177, +2144, +1856, +1912, +1970, +1963, + +1957, +1935, +1915, +1925, +1937, +1991, +2047, +2181, + +2061, +2337, +2613, +1817, +2301, +2157, +2269, +2397, + +1520, +1533, +1546, +1559, +1572, +1577, +1582, +1587, + +1592, +1533, +1474, +1671, +1868, -2023, -1818, -1869, + -1920, -1944, -1968, -1992, -2016, -1952, -1888, -1824, + -1760, -1771, -1782, -1665, -1548, -1639, -1730, -1693, + -1656, -1677, -1699, -1017, +2226, +1644, +2087, -286, + -2148, -2167, -1674, +611, +2384, +2173, +1962, +1975, + +1988, +1965, +1942, +1919, +1896, +1969, +2042, +2019, + +1484, -1916, -1220, +2484, +1068, -916, +1708, +1964, + +1504, +1514, +1526, +1536, +1548, +1550, +1554, +1556, + +1560, +1581, +1604, +1786, +689, -2138, -1894, -1905, + -1918, -1926, -1935, -1943, -1952, -1878, -1805, -1731, + -1658, -1626, -1596, -1549, -1503, -1507, -1513, -1518, + -1524, -1526, -1785, +148, +2080, +1995, +2422, -2094, + -2003, -2033, -1809, -1665, -1776, -189, +1398, +2536, + +2139, +2122, +2105, +2327, +2295, +2204, +2113, +2870, + -213, -1669, -1077, -1237, -1653, -1589, +2059, +1931, + +1488, +1497, +1506, +1515, +1524, +1525, +1526, +1527, + +1528, +1631, +1735, +1902, -490, -2254, -1971, -1943, + -1916, -1909, -1902, -1895, -1888, -1805, -1722, -1639, + -1556, -1483, -1411, -1434, -1458, -1377, -1297, -1344, + -1392, -1376, -1872, +1312, +1935, +1834, +1734, -2622, + -2370, -2157, -1945, -1892, -1840, -2039, -2239, -2022, + -782, -281, +220, +433, +134, -377, -888, -1655, + -1398, -1166, -934, -1374, -1302, -726, +2410, +1898, + +1472, +1478, +1486, +1492, +1500, +1498, +1498, +1496, + +1496, +1600, +1705, +1666, -933, -1474, -2015, -1964, + -1914, -1891, -1869, -1846, -1824, -1731, -1639, -1546, + -1454, -1387, -1321, -1191, -1317, -1150, -1240, -1250, + -1260, -1545, -1575, +2459, +1885, +2057, +182, -2429, + -2225, -2088, -1952, -1928, -1904, -1905, -1907, -2149, + -1879, -1835, -1793, -1670, -1803, -1645, -1489, -1491, + -1239, -1335, -1431, -1335, -1495, +681, +2345, +2089, + +1456, +1461, +1466, +1471, +1476, +1473, +1470, +1467, + +1464, +1570, +1676, +1174, -1888, -950, -2060, -1986, + -1912, -1874, -1836, -1798, -1760, -1658, -1556, -1454, + -1352, -1292, -1232, -1204, -1688, -1180, -1184, -1156, + -1128, -1203, -254, +2071, +1836, +2281, -1370, -2237, + -2080, -2020, -1960, -1964, -1968, -2028, -2088, -2020, + -1952, -1855, -1758, -1725, -1692, -1635, -1578, -1329, + -1592, -1504, -1416, -1040, -1688, +2088, +2280, +2280, + +1428, +1438, +1450, +1460, +1472, +1463, +1454, +1493, + +1533, +1512, +1748, -160, -2068, -1346, -1137, -1775, + -1902, -1848, -1794, -1708, -1622, -1544, -1466, -1356, + -1247, -1198, -1149, -1196, -1755, -1246, -993, -1012, + -1032, -1202, +930, +2023, +1837, +2238, -2480, -2286, + -1838, -1799, -1761, -1835, -1909, -1954, -2000, -1982, + -1964, -1908, -1853, -1829, -1807, -1749, -1692, -1538, + -1642, -1526, -1410, -638, -122, +774, +1926, +1926, + +1400, +1417, +1434, +1451, +1469, +1454, +1439, +1520, + +1602, +1455, +1820, -1239, -1737, -1743, -726, -1821, + -1892, -1822, -1752, -1618, -1485, -1431, -1377, -1259, + -1142, -1104, -1066, -1188, -1823, -1313, -803, -869, + -936, -1203, +2115, +1976, +1838, +916, -2055, -1569, + -1596, -1579, -1563, -1706, -1850, -1881, -1913, -1944, + -1976, -1962, -1949, -1935, -1922, -1864, -1807, -1749, + -1692, -1548, -1404, -1004, -92, +996, +2084, +2084, + +1372, +1394, +1418, +1441, +1465, +1444, +1423, +1483, + +1543, +1765, +1732, -2204, -1533, -1611, -1179, -1274, + -1882, -1764, -1646, -1560, -1475, -1301, -1127, -1113, + -1101, -994, -887, -1052, -1730, -1395, -804, -709, + -872, -306, +2051, +1929, +2063, -151, -1597, -1347, + -1354, -1326, -1300, -1417, -1535, -1599, -1665, -1730, + -1796, -1824, -1852, -1880, -1909, -1883, -1857, -1767, + -1678, -1570, -1462, -1434, +1154, +2402, +1858, +1858, + +1344, +1373, +1403, +1432, +1462, +1435, +1409, +1446, + +1484, +1564, +621, -1890, -1842, -1737, -1633, -728, + -1872, -1706, -1541, -1503, -1466, -1428, -1391, -1225, + -1060, -884, -709, -917, -1638, -1478, -807, -551, + -808, +590, +1988, +1882, +2288, -1218, -1140, -1126, + -1112, -1075, -1038, -1129, -1220, -1319, -1418, -1517, + -1616, -1686, -1756, -1826, -1896, -1902, -1908, -1786, + -1664, -1592, -1520, -1864, +2400, +2016, +2144, +2144, + +1348, +1372, +1398, +1424, +1450, +1463, +1477, +1491, + +1505, +1729, -607, -1838, -1790, -1735, -1681, -1003, + -1350, -1710, -1558, -1519, -1480, -1382, -1285, -1379, + -1475, -1208, -941, -611, -793, -796, -800, -611, + -680, +1364, +1872, +1932, +1481, -1150, -966, -926, + -886, -868, -851, -929, -1009, -1061, -1114, -1230, + -1348, -1521, -1695, -1805, -1915, -1900, -1886, -1792, + -1698, -1604, -1766, -744, +2326, +2134, +2198, +2198, + +1352, +1373, +1395, +1417, +1439, +1492, +1546, +1536, + +1526, +1894, -1835, -1787, -1739, -1735, -1731, -1279, + -828, -1714, -1577, -1536, -1495, -1337, -1180, -1023, + -866, -764, -663, -562, -973, -371, -282, -417, + -552, +2138, +1757, +1983, +674, -1083, -793, -726, + -660, -662, -665, -731, -798, -804, -811, -945, + -1080, -1357, -1635, -1784, -1934, -1899, -1865, -1798, + -1732, -1616, -2012, +376, +2252, +2252, +2252, +2252, + +1356, +1373, +1391, +1409, +1427, +1425, +1423, +1501, + +1579, +907, -1814, -1702, -1847, -1909, -1716, -1634, + -786, -1686, -1819, -1712, -1605, -1371, -1139, -921, + -705, -656, -608, -384, -416, -233, -308, -477, + +376, +1968, +1769, +2033, -5, -839, -651, -606, + -562, -584, -606, -660, -715, -739, -763, -963, + -1164, -1432, -1702, -1843, -1985, -1977, -1971, -1884, + -1798, -2012, -2226, +2152, +2178, +2194, +2210, +2210, + +1360, +1374, +1388, +1402, +1416, +1358, +1300, +1466, + +1632, -81, -1794, -1619, -1956, -2085, -1702, -1991, + -744, -891, -526, -353, -180, -383, -586, -821, + -1056, -805, -554, -463, -372, -353, -334, -539, + +1304, +1799, +1782, +2085, -684, -597, -510, -487, + -464, -506, -548, -590, -632, -674, -716, -982, + -1248, -1509, -1770, -1903, -2036, -2057, -2078, -1971, + -1864, -1896, -1416, +2392, +2104, +2136, +2168, +2168, + +1346, +1358, +1371, +1383, +1396, +1395, +1393, +1552, + +1711, -1177, -1762, -2203, -1364, -465, +690, +1942, + +1913, +1747, +1837, +1816, +1794, +1889, +1983, +1774, + +1564, +548, -468, -299, -386, -391, -398, -147, + +1895, +1920, +1946, +1284, -401, -397, -393, -421, + -450, -478, -507, -568, -629, -722, -815, -1068, + -1321, -1697, -2074, -2082, -2091, -2129, -2168, -2030, + -1894, -2028, +142, +2280, +2114, +2082, +2050, +2050, + +1332, +1343, +1354, +1365, +1377, +1432, +1487, +1382, + +1278, -1763, -195, +1308, +1788, +1667, +1547, +1522, + +1498, +1569, +1641, +1681, +1721, +1600, +1480, +1552, + +1624, +1901, +2179, +1145, -401, -431, -462, -12, + +1974, +1786, +2111, +484, -119, -198, -277, -356, + -436, -451, -467, -547, -627, -770, -914, -898, + -882, -606, -330, -470, -611, -1435, -2259, -2091, + -1924, -2160, +1700, +2168, +2124, +2028, +1932, +1932, + +1318, +1327, +1337, +1346, +1357, +1405, +1452, +1420, + +1389, +1381, +1629, +1748, +1356, +1495, +1635, +1631, + +1627, +1551, +1732, +1689, +1647, +1728, +1809, +1730, + +1652, +1686, +1721, +1948, +1921, +874, -430, +363, + +1925, +1764, +1859, +148, -28, -95, -160, -291, + -422, -423, -426, -557, -688, -370, -309, -280, + -251, -570, -890, -858, -826, -563, -301, -1079, + -1858, -1636, +2170, +2296, +2166, +2118, +2070, +2070, + +1304, +1312, +1321, +1329, +1338, +1378, +1419, +1459, + +1500, +1452, +1404, +1420, +1436, +1580, +1724, +1484, + +1244, +1022, +1313, +1187, +1062, +1088, +1115, +1397, + +1680, +1728, +1777, +1729, +1682, +1922, +1651, +1763, + +1876, +1742, +1609, -189, +62, +8, -45, -226, + -408, -397, -387, -568, -750, -227, -217, -430, + -644, -1047, -1451, -1502, -1554, -1229, -905, -580, + -256, -856, +1616, +1912, +2208, +2208, +2208, +2208, + +1290, +1304, +1319, +1334, +1350, +1377, +1404, +1271, + +1395, +1525, +1655, +1769, +1884, +1802, +1720, +1430, + +1141, +1026, +1168, +1037, +908, +700, +491, +331, + +172, +873, +1575, +1524, +1731, +1991, +1738, +1774, + +1811, +1914, +993, -119, +48, -74, -196, -271, + -346, -407, -470, -324, -179, -213, -503, -810, + -1117, -1273, -1430, -1636, -1841, -1823, -1551, -1246, + -686, +1194, +1026, +1610, +2194, +2194, +2194, +2194, + +1276, +1297, +1319, +1341, +1363, +1376, +1390, +1340, + +1802, +1854, +1907, +1863, +1820, +1768, +1717, +1377, + +1038, +1031, +1024, +889, +755, +568, +381, +290, + +200, +19, -162, +553, +1781, +2060, +1827, +1786, + +1746, +2086, +378, -50, +35, -156, -348, -316, + -284, -419, -554, -337, -121, -456, -791, -934, + -1078, -1244, -1411, -1514, -1617, -1907, -1686, -1657, + -1116, +1964, +1972, +2076, +2180, +2180, +2180, +2180, + +1262, +1289, +1318, +1346, +1375, +1359, +1344, +1632, + +1921, +1927, +1934, +1876, +1820, +1702, +1585, +1259, + +935, +907, +880, +724, +569, +436, +302, +217, + +132, +44, -43, -99, +102, +801, +2011, +1878, + +1745, +1426, +2131, +916, -43, -191, -340, -393, + -446, -461, -478, -237, -254, -522, -790, -962, + -1135, -1519, -1647, -1760, -1872, -1446, -2045, -1827, + -1354, +2254, +2278, +2222, +2166, +2166, +2166, +2166, + +1248, +1283, +1318, +1353, +1388, +1343, +1298, +1925, + +2040, +2001, +1962, +1891, +1820, +1637, +1454, +1143, + +832, +784, +736, +560, +384, +304, +224, +144, + +64, +70, +76, +18, -40, +54, +1684, +1714, + +1744, +1790, +1836, +1882, +1928, +798, -332, -470, + -608, -505, -402, -139, -388, -589, -790, -991, + -1192, -1794, -1884, -2006, -2128, -2266, -868, +818, + +2504, +2288, +2072, +2112, +2152, +2152, +2152, +2152, + +1238, +1263, +1290, +1332, +1375, +1301, +1484, +2002, + +2009, +1973, +1939, +1871, +1805, +1608, +1411, +1118, + +826, +751, +676, +505, +334, +273, +212, +151, + +91, +69, +48, +11, -26, +482, +1758, +1771, + +1784, +2033, +1771, +1860, +1950, +1989, +2029, +884, + -260, -1156, -261, -309, -614, -922, -975, -1411, + -1848, -2062, -2019, -697, +626, +2060, +2471, +2273, + +2076, +2051, +2026, +2081, +2136, +2136, +2136, +2136, + +1228, +1245, +1263, +1313, +1363, +1260, +1670, +2080, + +1978, +1947, +1916, +1853, +1791, +1580, +1369, +1094, + +820, +718, +616, +450, +285, +243, +201, +159, + +118, +69, +20, +4, -13, +910, +1833, +1828, + +1824, +229, +1706, +1839, +1972, +1901, +1830, +1983, + +2136, +2032, +1416, +1056, +696, +280, +376, +728, + +1080, +1767, +2454, +2405, +2356, +2035, +2226, +2193, + +2160, +2070, +1980, +2050, +2120, +2120, +2120, +2120, + +1218, +1226, +1235, +1292, +1350, +1235, +1888, +2061, + +1979, +1935, +1893, +1834, +1776, +1551, +1326, +1070, + +814, +685, +556, +395, +235, +212, +189, +166, + +145, +116, +88, -68, +33, +1306, +1811, +1949, + +1576, -200, -183, +905, +1994, +1956, +1919, +1881, + +1844, +2004, +1909, +2005, +2102, +2042, +2239, +2195, + +2152, +2043, +1935, +2370, +2038, +2697, +1821, +368, + +2244, +2121, +1998, +2051, +2104, +2104, +2104, +2104, + +1208, +1208, +1209, +1273, +1338, +1210, +2107, +2043, + +1980, +1925, +1871, +1816, +1762, +1523, +1285, +1046, + +808, +652, +497, +341, +186, +182, +179, +175, + +172, +164, +157, +117, +590, +1958, +1791, +1815, + +816, +140, -24, -28, -32, +988, +2008, +2036, + +2064, +1977, +1890, +1931, +1972, +2013, +2054, +2127, + +2200, +2320, +2440, +2080, +184, -1760, -3192, +336, + +2328, +2172, +2016, +2052, +2088, +2088, +2088, +2088, + +1222, +1215, +1209, +1266, +1325, +1459, +2104, +2046, + +1989, +1945, +1903, +1861, +1819, +1612, +1406, +1136, + +866, +715, +564, +446, +328, +295, +263, +230, + +199, +481, +764, +711, +1427, +2086, +1721, +1692, + +128, -37, +55, -14, -82, -108, -135, +335, + +804, +1293, +1783, +2272, +2250, +2197, +1889, +1356, + +568, -763, -2095, -3010, -2646, -2931, -2705, +2305, + +2196, +2159, +2122, +2117, +2112, +2112, +2112, +2112, + +1236, +1223, +1210, +1261, +1313, +1708, +2103, +2050, + +1998, +1967, +1937, +1907, +1877, +1702, +1528, +1226, + +924, +778, +633, +552, +471, +409, +348, +287, + +226, +287, +349, +283, +1241, +1702, +1652, +1826, + -48, +43, +134, +1, -132, -181, -230, -343, + -456, -670, -884, -202, -544, -946, -1860, -1718, + -2088, -2311, -2534, -2469, -2404, -2311, -1706, +2483, + +2064, +2146, +2228, +2182, +2136, +2136, +2136, +2136, + +1250, +1230, +1211, +1255, +1300, +1957, +2101, +2054, + +2007, +1956, +1906, +1856, +1806, +1696, +1586, +1284, + +982, +841, +701, +657, +613, +554, +497, +438, + +381, +412, +445, +717, +1758, +1782, +1807, +1095, + -128, -70, -11, -97, -182, -253, -325, -428, + -532, -761, -991, -580, -170, -1033, -873, -1976, + -1800, -2018, -2237, -2343, -2450, -2650, -35, +2308, + +2092, +2117, +2142, +2151, +2160, +2160, +2160, +2160, + +1264, +1238, +1212, +1250, +1288, +2206, +2100, +2058, + +2016, +1946, +1876, +1806, +1736, +1690, +1644, +1342, + +1040, +905, +770, +763, +756, +701, +646, +591, + +536, +539, +542, +897, +1764, +1607, +1962, +365, + -208, -182, -156, -194, -232, -326, -420, -514, + -608, -853, -1098, -1471, -820, -97, -910, -955, + -2024, -2238, -2452, -2474, -2496, -2990, +1636, +2134, + +2120, +2088, +2056, +2120, +2184, +2184, +2184, +2184, + +1198, +1191, +1185, +1227, +1525, +2065, +2093, +2009, + +1925, +1887, +1850, +1781, +1712, +1682, +1653, +1464, + +1275, +1130, +986, +937, +889, +840, +792, +743, + +696, +684, +674, +1335, +1741, +1839, +1939, +54, + -294, -295, -297, -298, -300, -414, -527, -641, + -755, -947, -1140, -1732, -1813, -733, -166, -1038, + -887, -1234, -1581, -1609, -1636, -1158, +2392, +2279, + +2166, +2119, +2072, +2121, +2170, +2170, +2170, +2170, + +1132, +1145, +1159, +1205, +1763, +1924, +2086, +1960, + +1834, +1829, +1825, +1756, +1688, +1675, +1663, +1586, + +1510, +1356, +1202, +1112, +1023, +981, +939, +897, + +856, +831, +807, +1774, +1718, +1817, +1405, -512, + -380, -409, -438, -403, -369, -502, -635, -768, + -902, -1042, -1182, -1482, -1782, -2138, -1982, -610, + -262, -486, -711, -744, -777, +162, +2125, +1912, + +2212, +2150, +2088, +2122, +2156, +2156, +2156, +2156, + +1194, +1146, +1100, +1182, +1776, +1927, +2079, +1863, + +1903, +1978, +1799, +1843, +1632, +1619, +1608, +1612, + +1617, +1517, +1418, +1351, +1284, +1216, +1149, +1098, + +1048, +945, +1099, +1781, +1695, +1954, +422, -566, + -530, -554, -579, -571, -565, -686, -806, -927, + -1049, -1232, -1416, -1679, -1943, -2342, -2486, -2501, + -2773, -2074, -1376, -1671, -2221, +458, +2369, +2137, + +2162, +2133, +2104, +2123, +2142, +2142, +2142, +2142, + +1256, +1149, +1043, +1160, +1790, +1931, +2073, +1766, + +1972, +2129, +1774, +1931, +1576, +1565, +1554, +1639, + +1724, +1679, +1635, +1590, +1546, +1453, +1361, +1300, + +1240, +1060, +1392, +1788, +1672, +2092, -560, -620, + -680, -700, -721, -741, -762, -870, -979, -1087, + -1196, -1423, -1650, -1877, -2104, -2291, -2478, -2857, + -2724, -2895, -3067, -3110, -3666, +2547, +2103, +2107, + +2112, +2116, +2120, +2124, +2128, +2128, +2128, +2128, + +1214, +1170, +1128, +1453, +1779, +1692, +1861, +1807, + +1753, +1732, +1712, +1803, +1640, +1759, +1623, +1710, + +1799, +1666, +1790, +1755, +1719, +1628, +1539, +1497, + +1456, +1352, +1504, +1752, +1745, +1445, -902, -898, + -894, -907, -921, -935, -950, -1070, -1190, -1310, + -1431, -1641, -1852, -2062, -2273, -2431, -2590, -2812, + -2779, -2929, -3080, -3279, -2198, +2298, +2187, +2124, + +2062, +2081, +2100, +2119, +2138, +2138, +2138, +2138, + +1172, +1193, +1214, +1747, +1769, +1710, +2163, +2360, + +2046, +1592, +1651, +1677, +1704, +1954, +1693, +1783, + +1874, +1654, +1947, +1920, +1893, +1805, +1718, +1695, + +1672, +1644, +1617, +1717, +1818, +798, -1245, -1176, + -1108, -1115, -1123, -1131, -1139, -1270, -1402, -1534, + -1666, -1860, -2054, -2248, -2442, -2572, -2702, -2768, + -2834, -2964, -3094, -3192, -219, +2306, +2272, +2142, + +2012, +2046, +2080, +2114, +2148, +2148, +2148, +2148, + +1194, +1150, +1364, +1784, +1694, +1983, +2272, +1441, + +2147, +1980, +1813, +1838, +1864, +1909, +1698, +1823, + +1949, +1818, +1943, +1989, +2034, +1933, +1833, +1812, + +1792, +1712, +1633, +1649, +1923, -536, -1459, -1390, + -1322, -1354, -1388, -1421, -1455, -1566, -1678, -1789, + -1901, -2078, -2256, -2433, -2611, -2744, -2878, -2915, + -2953, -2998, -3044, -3777, +1633, +2298, +1941, +2015, + +2090, +2107, +2124, +2141, +2158, +2158, +2158, +2158, + +1216, +1109, +1514, +1823, +1620, +2001, +1870, +1803, + +1224, +1600, +1464, +1232, +1000, +1096, +1192, +1352, + +1512, +1726, +1940, +2058, +2176, +2062, +1948, +1930, + +1912, +1781, +1650, +1583, +2028, -1871, -1674, -1605, + -1536, -1595, -1654, -1713, -1772, -1863, -1954, -2045, + -2136, -2297, -2458, -2619, -2780, -2917, -3054, -3063, + -3072, -3033, -2994, -2827, +2460, +2035, +2122, +2145, + +2168, +2168, +2168, +2168, +2168, +2168, +2168, +2168, + +1190, +1271, +1610, +1756, +1647, +1523, +1144, +1324, + +1249, +1364, +1224, +1211, +1199, +1255, +1566, +1430, + +1294, +1404, +1514, +1800, +2087, +2075, +2063, +2003, + +1944, +1654, +1621, +1811, +979, -1997, -1903, -1888, + -1874, -1927, -1982, -2036, -2091, -2163, -2236, -2308, + -2381, -2513, -2646, -2778, -2911, -3005, -3100, -3114, + -3129, -3039, -3206, -1084, +2317, +2104, +2148, +2159, + +2171, +2175, +2179, +2183, +2187, +2187, +2187, +2187, + +1164, +1179, +1195, +1179, +1163, +1302, +1442, +1358, + +1274, +1385, +1496, +1447, +1399, +1158, +1429, +1508, + +1588, +1594, +1601, +1543, +1486, +1832, +2179, +2077, + +1976, +1528, +1593, +1785, -582, -2381, -2133, -2172, + -2212, -2261, -2311, -2361, -2411, -2464, -2518, -2572, + -2626, -2730, -2834, -2938, -3042, -3094, -3146, -3166, + -3186, -3046, -3418, +658, +2174, +2174, +2174, +2174, + +2174, +2182, +2190, +2198, +2206, +2206, +2206, +2206, + +1202, +1230, +1259, +1272, +1286, +1321, +1356, +1343, + +1331, +1405, +1480, +1474, +1470, +1349, +1483, +1522, + +1562, +1576, +1591, +1573, +1557, +1589, +1622, +1718, + +1816, +1690, +1820, +1694, -2015, -2556, -2330, -2376, + -2422, -2610, -2799, -2700, -2602, -2669, -2736, -2803, + -2871, -2946, -3022, -3097, -3173, -3182, -3192, -3153, + -3115, -3324, -3278, +2256, +2159, +2147, +2136, +2156, + +2177, +2189, +2201, +2213, +2225, +2225, +2225, +2225, + +1240, +1282, +1325, +1367, +1410, +1340, +1271, +1329, + +1388, +1426, +1465, +1503, +1542, +1540, +1539, +1537, + +1536, +1559, +1582, +1605, +1628, +1603, +1578, +1617, + +1656, +1596, +1536, +1604, -2936, -2476, -2528, -2580, + -2632, -2704, -2777, -2785, -2794, -2874, -2955, -3035, + -3116, -3163, -3210, -3257, -3304, -3271, -3238, -3141, + -3044, -3091, -2114, +2319, +2144, +2121, +2098, +2139, + +2180, +2196, +2212, +2228, +2244, +2244, +2244, +2244, + +1230, +1255, +1281, +1306, +1333, +1303, +1272, +1338, + +1405, +1436, +1468, +1500, +1533, +1535, +1537, +1539, + +1542, +1562, +1584, +1605, +1627, +1601, +1577, +1616, + +1656, +1807, +1959, -417, -2793, -2797, -2545, -2581, + -2618, -2687, -2757, -2794, -2833, -2901, -2968, -3036, + -3105, -3145, -3186, -3178, -3171, -3149, -3128, -3058, + -2989, -3221, -126, +2281, +2129, +2084, +2040, +2107, + +2175, +2189, +2203, +2217, +2231, +2231, +2231, +2231, + +1220, +1229, +1238, +1247, +1257, +1266, +1275, +1348, + +1422, +1447, +1473, +1499, +1525, +1530, +1536, +1542, + +1548, +1567, +1587, +1606, +1626, +1601, +1577, +1616, + +1656, +1763, +1871, +1658, -2138, -2862, -2563, -2583, + -2604, -2671, -2738, -2805, -2873, -2928, -2983, -3038, + -3094, -3128, -3162, -3100, -3038, -3028, -3018, -2976, + -2934, -3352, +1862, +2244, +2114, +2048, +1982, +2076, + +2170, +2182, +2194, +2206, +2218, +2218, +2218, +2218, + +1210, +1234, +1259, +1283, +1308, +1325, +1341, +1390, + +1439, +1457, +1477, +1496, +1516, +1525, +1535, +1544, + +1554, +1571, +1589, +1607, +1625, +1616, +1608, +1632, + +1656, +1718, +1782, +1685, +1845, +528, -2836, -2728, + -2622, -2654, -2687, -2719, -2752, -2763, -2773, -2992, + -2955, -3030, -3106, -2813, -2777, -3226, -2908, -3134, + -3359, -971, +2186, +2270, +2099, +2075, +2052, +2108, + +2165, +2175, +2185, +2195, +2205, +2205, +2205, +2205, + +1200, +1240, +1280, +1320, +1360, +1384, +1408, +1432, + +1456, +1469, +1482, +1495, +1508, +1521, +1534, +1547, + +1560, +1576, +1592, +1608, +1624, +1632, +1640, +1648, + +1656, +1675, +1694, +1713, +1732, +1871, +986, -827, + -2640, -2638, -2636, -2634, -2632, -2598, -2564, -2946, + -2816, -2933, -3050, -2783, -3028, -3169, -1774, +293, + +2360, +2179, +1998, +2041, +2084, +2103, +2122, +2141, + +2160, +2168, +2176, +2184, +2192, +2192, +2192, +2192, + +1232, +1266, +1300, +1334, +1368, +1390, +1412, +1434, + +1456, +1468, +1482, +1494, +1508, +1520, +1534, +1546, + +1560, +1578, +1596, +1614, +1632, +1640, +1648, +1656, + +1664, +1645, +1628, +1705, +1784, +2101, +1908, +1298, + +688, +1071, -594, -1587, -2580, -2891, -3202, -2281, + -2640, -2058, -1476, -94, +1032, +2278, +2244, +2209, + +2176, +2131, +2088, +2091, +2096, +2111, +2128, +2143, + +2160, +2168, +2176, +2184, +2192, +2192, +2192, +2192, + +1264, +1292, +1320, +1348, +1376, +1396, +1416, +1436, + +1456, +1469, +1482, +1495, +1508, +1521, +1534, +1547, + +1560, +1580, +1600, +1620, +1640, +1648, +1656, +1664, + +1672, +1617, +1562, +1699, +1836, +1821, +1806, +1887, + +1968, +1964, +1960, +2020, +2080, +1936, +1792, +1200, + +1632, +1889, +2146, +2083, +2020, +2093, +2166, +2079, + +1992, +2085, +2178, +2143, +2108, +2121, +2134, +2147, + +2160, +2168, +2176, +2184, +2192, +2192, +2192, +2192, + +1296, +1318, +1340, +1362, +1384, +1402, +1420, +1438, + +1456, +1468, +1482, +1494, +1508, +1520, +1534, +1546, + +1560, +1582, +1604, +1626, +1648, +1656, +1664, +1672, + +1680, +1667, +1656, +1739, +1824, +1811, +1800, +1835, + +1872, +1881, +1890, +1819, +1748, +1995, +450, +937, + +912, +715, +2056, +2019, +1984, +2035, +2088, +2059, + +2032, +2085, +2140, +2129, +2120, +2129, +2140, +2149, + +2160, +2168, +2176, +2184, +2192, +2192, +2192, +2192, + +1328, +1344, +1360, +1376, +1392, +1408, +1424, +1440, + +1456, +1469, +1482, +1495, +1508, +1521, +1534, +1547, + +1560, +1584, +1608, +1632, +1656, +1664, +1672, +1680, + +1688, +1719, +1750, +1781, +1812, +1803, +1794, +1785, + +1776, +1798, +1820, +1874, +1928, +1798, +2180, +674, + +1216, +2103, +1966, +1957, +1948, +1979, +2010, +2041, + +2072, +2087, +2102, +2117, +2132, +2139, +2146, +2153, + +2160, +2168, +2176, +2184, +2192, +2192, +2192, +2192, + +1328, +1344, +1360, +1376, +1392, +1408, +1424, +1440, + +1456, +1468, +1482, +1494, +1508, +1520, +1534, +1546, + +1560, +1584, +1608, +1632, +1656, +1664, +1672, +1680, + +1688, +1718, +1750, +1780, +1812, +1802, +1794, +1784, + +1776, +1798, +1820, +1858, +1896, +1750, +1860, +2338, + +1792, +2134, +1966, +1956, +1948, +1978, +2010, +2040, + +2072, +2086, +2102, +2116, +2132, +2138, +2146, +2152, + +2160, +2168, +2176, +2184, +2192, +2192, +2192, +2192, + +1328, +1344, +1360, +1376, +1392, +1408, +1424, +1440, + +1456, +1469, +1482, +1495, +1508, +1521, +1534, +1547, + +1560, +1584, +1608, +1632, +1656, +1664, +1672, +1680, + +1688, +1719, +1750, +1781, +1812, +1803, +1794, +1785, + +1776, +1798, +1820, +1842, +1864, +1958, +2052, +1954, + +1856, +1911, +1966, +1957, +1948, +1979, +2010, +2041, + +2072, +2087, +2102, +2117, +2132, +2139, +2146, +2153, + +2160, +2168, +2176, +2184, +2192, +2192, +2192, +2192, + +1328, +1344, +1360, +1376, +1392, +1408, +1424, +1440, + +1456, +1468, +1482, +1494, +1508, +1520, +1534, +1546, + +1560, +1584, +1608, +1632, +1656, +1664, +1672, +1680, + +1688, +1718, +1750, +1780, +1812, +1802, +1794, +1784, + +1776, +1798, +1820, +1842, +1864, +1958, +2052, +1954, + +1856, +1910, +1966, +1956, +1948, +1978, +2010, +2040, + +2072, +2086, +2102, +2116, +2132, +2138, +2146, +2152, + +2160, +2168, +2176, +2184, +2192, +2192, +2192, +2192 +}; + +static INT16 TEST_CR_COMPONENT[4096] = +{ + -2112, -2114, -2116, -2118, -2120, -2122, -2124, -2126, + -2128, -2118, -2108, -2098, -2088, -2150, -2212, -2146, + -2080, -2100, -2120, -2140, -2160, -2164, -2168, -2172, + -2176, -2092, -2008, -2052, -2096, -2132, -2168, -2076, + -1984, -2088, -2192, -2168, -2144, -2136, -2128, -2120, + -2112, -2126, -2140, -2154, -2168, -2150, -2132, -2114, + -2096, -2096, -2096, -2096, -2096, -2096, -2096, -2096, + -2096, -2080, -2064, -2048, -2032, -2032, -2032, -2032, + -2128, -2113, -2098, -2115, -2132, -2133, -2134, -2135, + -2137, -2127, -2117, -2107, -2097, -2117, -2137, -2125, + -2114, -2134, -2154, -2159, -2163, -2135, -2108, -2128, + -2149, -2132, -2116, -2116, -2115, -2115, -2114, -2098, + -2082, -2112, -2142, -2141, -2139, -2133, -2128, -2122, + -2117, -2127, -2137, -2147, -2158, -2146, -2134, -2122, + -2111, -2108, -2106, -2104, -2102, -2101, -2101, -2101, + -2101, -2087, -2073, -2059, -2045, -2045, -2045, -2045, + -2144, -2112, -2080, -2112, -2145, -2145, -2145, -2145, + -2146, -2136, -2126, -2116, -2107, -2085, -2063, -2105, + -2148, -2168, -2189, -2178, -2167, -2107, -2048, -2085, + -2122, -2173, -2225, -2180, -2135, -2098, -2061, -2120, + -2180, -2136, -2093, -2114, -2135, -2131, -2128, -2125, + -2122, -2128, -2135, -2141, -2148, -2142, -2137, -2131, + -2126, -2121, -2117, -2112, -2108, -2107, -2107, -2106, + -2106, -2094, -2082, -2070, -2058, -2058, -2058, -2058, + -2160, -2111, -2062, -2109, -2157, -2156, -2155, -2154, + -2155, -2145, -2135, -2125, -2116, -2132, -2148, -2132, + -2118, -2154, -2191, -2181, -2170, -2494, -2308, -2393, + -2479, -2470, -2461, -2243, -2282, -2353, -2167, -2174, + -2182, -2160, -2139, -2135, -2130, -2128, -2128, -2127, + -2127, -2129, -2132, -2134, -2138, -2138, -2139, -2139, + -2141, -2133, -2127, -2120, -2114, -2112, -2112, -2111, + -2111, -2101, -2091, -2081, -2071, -2071, -2071, -2071, + -2176, -2110, -2045, -2107, -2170, -2168, -2167, -2165, + -2164, -2154, -2145, -2135, -2126, -2180, -2235, -2161, + -2088, -2141, -2195, -2440, -2686, -2371, -1033, -398, + +236, +305, +375, -3, -894, -2096, -2787, -2485, + -2184, -2185, -2187, -2156, -2126, -2127, -2129, -2130, + -2132, -2131, -2130, -2129, -2128, -2135, -2142, -2149, + -2156, -2147, -2138, -2129, -2120, -2119, -2118, -2117, + -2116, -2108, -2100, -2092, -2084, -2084, -2084, -2084, + -2112, -2085, -2058, -2112, -2166, -2067, -2225, -2190, + -2157, -2107, -2057, -2104, -2151, -2119, -2088, -2632, + -2666, -2263, -837, +844, +2526, +3327, +2847, +2847, + +2847, +2726, +2606, +2967, +3070, +2968, +2867, +397, + -2074, -2745, -2137, -2281, -2169, -2202, -2236, -2190, + -2145, -2145, -2147, -2148, -2150, -2152, -2156, -2159, + -2163, -2159, -2156, -2152, -2150, -2130, -2111, -2123, + -2137, -2127, -2117, -2107, -2097, -2097, -2097, -2097, + -2048, -2060, -2073, -2118, -2163, -1967, -2284, -2217, + -2150, -2060, -1971, -2074, -2177, -2315, -2454, -1057, + +1364, +2990, +2568, +2593, +2619, +2369, +2631, +2508, + +2386, +2332, +2278, +2352, +2427, +2913, +2888, +3022, + +3156, +1302, -2088, -2406, -2213, -2279, -2345, -2251, + -2158, -2161, -2165, -2168, -2172, -2171, -2171, -2170, + -2170, -2172, -2175, -2177, -2180, -2142, -2105, -2131, + -2158, -2146, -2134, -2122, -2110, -2110, -2110, -2110, + -2112, -2163, -2215, -2235, -2255, -1994, -2247, -2194, + -2143, -2109, -2076, -2123, -2170, -2270, +700, +3527, + +2770, +2035, +2325, +2293, +2263, +2178, +2350, +2265, + +2181, +2129, +2078, +2154, +2231, +2521, +2557, +2559, + +2562, +3221, +3113, +140, -2832, -2034, -2261, -2199, + -2139, -2160, -2182, -2188, -2194, -2189, -2185, -2181, + -2177, -2185, -2193, -2201, -2210, -2154, -2098, -2138, + -2179, -2165, -2151, -2137, -2123, -2123, -2123, -2123, + -1664, -1755, -1846, -1841, -1836, -1767, -2210, -2173, + -2136, -2159, -2182, -2173, -2164, -2739, +2830, +2735, + +2640, +2361, +2082, +1995, +1908, +1989, +2070, +2023, + +1976, +1927, +1878, +1957, +2036, +2131, +2226, +2353, + +2480, +2581, +2682, +2943, +2692, -2815, -2178, -2149, + -2120, -2160, -2200, -2208, -2216, -2208, -2200, -2192, + -2184, -2198, -2212, -2226, -2240, -2166, -2092, -2146, + -2200, -2184, -2168, -2152, -2136, -2136, -2136, -2136, + -2096, -2166, -2238, -2228, -2220, -2087, -2210, -2173, + -2137, -2189, -2243, -2152, -2318, -2031, +3375, +2861, + +2605, +2305, +2007, +1851, +1697, +1756, +1815, +1810, + +1806, +1756, +1707, +1754, +1801, +1911, +2023, +2149, + +2277, +2299, +2323, +2729, +1345, -2439, -2129, -2217, + -2307, -2349, -2136, -2179, -2222, -2223, -2224, -2193, + -2162, -2171, -2180, -2190, -2199, -2198, -2198, -2213, + -2229, -2172, -2115, -2170, -2225, -2113, -2257, -2257, + -2016, -2067, -2118, -2105, -2093, -2152, -2211, -2174, + -2138, -2221, -2305, -2132, -2472, +212, +2897, +2477, + +2570, +2251, +1932, +1709, +1487, +1524, +1561, +1598, + +1636, +1586, +1537, +1552, +1567, +1693, +1820, +1947, + +2074, +2019, +1964, +2261, -514, -2321, -2080, -2031, + -1982, -2283, -2073, -2151, -2229, -2238, -2248, -2194, + -2140, -2144, -2149, -2154, -2159, -2231, -2304, -2281, + -2258, -2160, -2062, -2188, -2314, -2090, -2378, -2378, + -2064, -2094, -2126, -2125, -2125, -2152, -2179, -2159, + -2139, -2204, -2270, -2144, -2530, +1688, +2834, +2460, + +2343, +2147, +1953, +1678, +1404, +1387, +1370, +1418, + +1466, +1416, +1366, +1349, +1332, +1442, +1553, +1663, + +1775, +1817, +1861, +2415, -2405, -2457, -1999, -2035, + -281, -1464, -2393, -2378, -2363, -2301, -2240, -2195, + -2150, -2165, -2181, -2182, -2182, -2199, -2218, -2188, + -2159, -2756, -2329, -1934, -2307, -2627, -2179, -2307, + -2112, -2123, -2135, -2146, -2158, -2153, -2149, -2144, + -2140, -2188, -2236, -2156, -2588, +3164, +2772, +2444, + +2116, +2045, +1975, +1648, +1322, +1251, +1181, +1238, + +1296, +1246, +1197, +1147, +1098, +1192, +1287, +1381, + +1476, +1617, +1758, +1291, -2760, -2083, -2430, -1273, + -628, -647, -667, -1582, -2498, -2365, -2233, -2196, + -2160, -2187, -2215, -2210, -2206, -2169, -2133, -2096, + -2060, -280, -548, -2448, -1788, -860, -1980, -2236, + -2112, -2120, -2130, -2140, -2150, -2145, -2141, -2137, + -2133, -2147, -2161, -2079, -718, +3207, +2525, +2291, + +2057, +1941, +1827, +1553, +1279, +1174, +1070, +1094, + +1118, +1044, +970, +976, +983, +1001, +1019, +1165, + +1313, +1305, +1555, -212, -2491, -2189, -2401, -867, + -615, -642, -671, -603, -536, -1354, -2172, -2271, + -2370, -2340, -2311, -2330, -2349, -2315, -2282, -2697, + -1321, -420, -543, -394, -757, -741, -2261, -2261, + -2112, -2119, -2127, -2135, -2143, -2138, -2134, -2130, + -2126, -2106, -2087, -2259, +640, +2995, +2279, +2138, + +1998, +1839, +1681, +1459, +1237, +1098, +960, +950, + +940, +842, +744, +806, +869, +811, +753, +951, + +1150, +995, +1352, -1715, -2222, -2297, -2372, -463, + -602, -639, -676, -649, -623, -600, -577, -810, + -1044, -1214, -1384, -1426, -1469, -1183, -897, -483, + -582, -560, -538, -900, -750, -1134, -2542, -2286, + -2112, -2117, -2123, -2129, -2135, -2131, -2127, -2123, + -2119, -2017, -1916, -2886, +1262, +2014, +2256, +2097, + +1939, +1736, +1534, +1364, +1194, +1022, +850, +806, + +762, +736, +710, +508, +818, +604, +646, +752, + +859, +1131, +1149, -2865, -2273, -2339, -1639, -425, + -493, -522, -553, -566, -581, -677, -773, -661, + -550, -567, -585, -586, -588, -657, -727, -572, + -675, -668, -661, -798, -679, -1799, -2407, -2151, + -2112, -2116, -2120, -2124, -2128, -2124, -2120, -2116, + -2112, -2185, -2258, -1723, +1884, +1035, +2234, +2057, + +1880, +1634, +1388, +1270, +1152, +946, +740, +662, + +584, +630, +676, +466, +1280, +654, +540, +554, + +568, +757, -78, -2481, -2324, -2383, -906, -389, + -384, -407, -430, -485, -540, -499, -458, -513, + -568, -689, -810, -771, -732, -645, -558, -663, + -768, -776, -784, -696, -608, -2464, -2272, -2016, + -2104, -2110, -2116, -2122, -2129, -2105, -2081, -2105, + -2130, -2204, -2536, -84, +1856, +1148, +1209, +1701, + +1683, +1507, +1332, +1188, +1045, +837, +630, +518, + +407, +489, +572, +398, +1249, +662, +330, +383, + +436, +589, -1304, -2350, -2117, -2615, +213, -12, + -239, -265, -293, -320, -348, -377, -407, -484, + -562, -626, -691, -675, -661, -625, -590, -682, + -776, -804, -832, -540, -248, -664, -1848, -2616, + -2096, -2104, -2113, -2121, -2130, -2086, -2043, -2095, + -2148, -2225, -2815, +1555, +1829, +1519, +697, +1603, + +1486, +1381, +1276, +1107, +938, +729, +520, +375, + +230, +349, +468, +331, +1219, +670, +121, +212, + +304, +423, -2531, -2477, -2423, -1569, +309, -149, + -94, -125, -157, -157, -157, -256, -356, -456, + -556, -564, -573, -581, -590, -606, -623, -703, + -784, -832, -880, -384, +112, -1424, -2448, -2192, + -2088, -2098, -2109, -2119, -2131, -2099, -2068, -2100, + -2134, -2485, -2325, +2921, +2025, +1536, +1048, +1088, + +1385, +1270, +1156, +993, +831, +700, +570, +407, + +245, +256, +268, +343, +932, +662, +135, +185, + +236, -337, -2445, -2346, -2504, -793, +149, -75, + -45, -64, -84, -88, -93, -183, -273, -363, + -454, -454, -454, -518, -583, -619, -655, -723, + -792, -796, -800, -868, -1960, -2296, -2376, -2248, + -2080, -2093, -2106, -2119, -2132, -2113, -2094, -2107, + -2120, -2234, -813, +2752, +2222, +1555, +1401, +574, + +1284, +1160, +1036, +880, +724, +672, +620, +440, + +260, +164, +69, +357, +646, +654, +151, +159, + +168, -1096, -2361, -2217, -2586, -18, -11, -3, + +4, -4, -13, -21, -30, -110, -191, -271, + -352, -344, -336, -456, -576, -632, -688, -744, + -800, -760, -720, -584, -2496, -2400, -2304, -2304, + -2072, -2086, -2102, -2117, -2133, -2171, -2211, -2170, + -2130, -2462, +1045, +2615, +2138, +1656, +1432, +807, + +951, +1193, +924, +734, +545, +397, +250, +486, + +723, +569, +416, +311, +207, +384, +305, +242, + +180, -1825, -2295, -2348, -1891, +69, -19, -10, + -3, -7, -12, -16, -22, -65, -107, -182, + -258, -309, -361, -477, -593, -640, -688, -736, + -784, -752, -720, -1200, -2448, -2384, -2320, -2320, + -2064, -2081, -2099, -2116, -2134, -2231, -2329, -2234, + -2140, -2691, +2902, +2478, +2055, +1759, +1464, +1041, + +618, +1227, +812, +589, +366, +379, +392, +277, + +162, +207, +253, +267, +281, +114, -52, +70, + +192, -2555, -2230, -2481, -1197, +156, -28, -19, + -10, -11, -12, -13, -15, -20, -25, -94, + -164, -275, -387, -498, -610, -649, -689, -728, + -768, -744, -720, -1816, -2400, -2368, -2336, -2336, + -2056, -2075, -2095, -2115, -2135, -2178, -2222, -2138, + -2310, -1319, +2743, +2293, +2099, +1893, +1432, +1242, + +541, +1036, +1020, +699, +379, +376, +374, +275, + +177, +196, +217, +189, +162, +100, +39, +153, + -756, -2420, -2293, -2549, -502, +131, -4, -10, + -17, -14, -12, -9, -7, -7, -6, -102, + -198, -320, -444, -519, -595, -641, -689, -720, + -752, -768, -784, -2192, -2320, -2336, -2352, -2352, + -2048, -2070, -2092, -2114, -2136, -2126, -2116, -2042, + -2480, +52, +2584, +2108, +2144, +2028, +1400, +1444, + +464, +78, -308, -470, -632, -394, -156, +18, + +192, +187, +182, +113, +44, +87, +130, +237, + -1704, -2286, -2356, -2618, +192, +106, +20, -2, + -24, -18, -12, -6, +0, +6, +12, -110, + -232, -367, -502, -541, -580, -635, -690, -713, + -736, -792, -848, -2568, -2240, -2304, -2368, -2368, + -2046, -2068, -2091, -2113, -2136, -2121, -2105, -2186, + -2523, +1999, +2681, +2740, +1518, +117, -1541, -2639, + -2457, -2465, -2474, -2466, -2459, -2498, -2536, -2303, + -2070, -995, +81, -76, +24, +35, +47, -150, + -2394, -2422, -2450, -1806, +117, +85, +53, +21, + -11, -11, -11, -11, -11, -11, -11, -107, + -203, -404, -606, -615, -625, -610, -596, -693, + -791, -757, -1491, -2401, -2287, -2303, -2319, -2319, + -2044, -2067, -2090, -2113, -2137, -2116, -2095, -2074, + -2054, +2923, +219, -1748, -2692, -2563, -2435, -2114, + -2306, -2193, -2080, -2159, -2239, -2298, -2357, -2320, + -2284, -2432, -2580, -1544, +4, -16, -36, -280, + -2572, -2302, -2544, -994, +43, +64, +86, +44, + +2, -4, -10, -16, -22, -28, -34, -104, + -174, -186, -198, -178, -158, -330, -502, -674, + -846, -722, -2134, -2234, -2334, -2302, -2270, -2270, + -2042, -2065, -2089, -2112, -2137, -2159, -2180, -2154, + -2129, -2458, -2532, -2604, -2166, -2218, -2272, -2293, + -2315, -2000, -2198, -2219, -2242, -2322, -2401, -2385, + -2370, -2285, -2201, -2452, -2704, -1411, +137, -1402, + -2174, -2502, -2830, +250, +0, +28, +55, +35, + +15, +3, -9, -21, -33, -45, -57, -101, + -145, -175, -206, -220, -235, -177, -120, -414, + -709, -191, -2489, -2547, -2349, -2349, -2349, -2349, + -2040, -2064, -2089, -2113, -2138, -2202, -2267, -2235, + -2204, -2207, -2210, -2181, -2152, -2131, -2110, -2217, + -1812, -1552, -2317, -2025, -1734, -1578, -1423, -1939, + -2456, -2395, -2334, -2081, -2340, -2551, -2250, -2013, + -2288, -2446, -2093, -43, -42, -8, +25, +26, + +28, +10, -8, -26, -44, -62, -80, -98, + -116, -165, -214, -263, -312, -281, -250, -155, + -60, -940, -1820, -2348, -2364, -2396, -2428, -2428, + -2038, -2058, -2079, -2100, -2122, -2123, -2124, -2285, + -2191, -2065, -1940, -1910, -1882, -2232, -2327, -2149, + -1717, -1485, -2022, -1759, -1497, -1242, -987, -716, + -446, -1226, -2007, -2723, -2160, -2330, -2245, -2175, + -2362, -2338, -1034, +109, -28, -19, -10, +15, + +41, +19, -3, -25, -47, -89, -131, -141, + -151, -208, -266, -355, -445, -458, -472, -405, + -83, -1135, -1163, -1895, -2371, -2387, -2403, -2403, + -2036, -2053, -2071, -2089, -2107, -2044, -1982, -2080, + -1666, -1668, -1671, -1897, -2124, -2590, -2545, -2083, + -1622, -1419, -1729, -1495, -1261, -1162, -1064, -774, + -484, -314, -144, -806, -2492, -2366, -2240, -2338, + -2436, -2486, -489, +4, -15, -30, -45, +4, + +54, +28, +2, -24, -50, -116, -182, -184, + -186, -252, -318, -448, -578, -636, -694, -656, + -106, -2098, -2042, -2210, -2378, -2378, -2378, -2378, + -2034, -2047, -2062, -2076, -2091, -2093, -2096, -1650, + -1461, -1687, -1913, -2155, -2398, -2676, -2442, -2016, + -1591, -1448, -1563, -1341, -1120, -986, -853, -623, + -394, -265, -137, +200, +24, -1554, -2363, -2324, + -2286, -2122, -2727, -1220, +31, +136, -15, +25, + +67, +37, +7, -7, -21, -111, -201, -211, + -221, -295, -370, -460, -551, -509, -468, -634, + -545, -2805, -2249, -2301, -2353, -2353, -2353, -2353, + -2032, -2043, -2054, -2065, -2076, -2143, -2210, -1477, + -1768, -1962, -2156, -2414, -2672, -2762, -2340, -1950, + -1560, -1479, -1398, -1189, -980, -811, -642, -473, + -304, -217, -130, -75, -20, +27, -2486, -2311, + -2136, -2527, -2406, -2445, -2484, -979, +14, +47, + +80, +46, +12, +10, +8, -106, -220, -238, + -256, -339, -422, -473, -524, -639, -754, -1637, + -2520, -2232, -2456, -2392, -2328, -2328, -2328, -2328, + -2012, -2030, -2049, -2052, -2055, -2191, -2073, -1585, + -1867, -2081, -2296, -2526, -2757, -2653, -2294, -1886, + -1479, -1380, -1282, -1087, -893, -748, -604, -491, + -379, -243, -109, -181, +1, -606, -2493, -2283, + -2331, -2481, -2376, -2413, -2452, -2308, -2421, -1350, + -278, -124, +30, +88, +145, +127, +109, +27, + -56, -278, -501, -1107, -1714, -2162, -2612, -2532, + -2453, -2297, -2397, -2369, -2341, -2341, -2341, -2341, + -1992, -2018, -2045, -2040, -2035, -2241, -1936, -1695, + -1966, -2201, -2436, -2639, -2842, -2545, -2248, -1823, + -1398, -1282, -1166, -986, -806, -686, -566, -510, + -454, -271, -88, -289, +22, -1239, -2500, -2257, + -2526, -388, -2346, -2383, -2421, -2358, -2296, -2490, + -2684, -2342, -2001, -1627, -1254, -1176, -1099, -1501, + -1904, -2266, -2628, -2510, -2393, -2407, -2422, -2404, + -2386, -2362, -2338, -2346, -2354, -2354, -2354, -2354, + -1972, -2006, -2040, -2043, -2046, -2194, -1831, -1835, + -2097, -2336, -2576, -2735, -2895, -2564, -2234, -1839, + -1445, -1279, -1114, -916, -719, -623, -528, -528, + -529, -425, -323, -59, -53, -2527, -2443, -2517, + -2081, +170, -140, -1312, -2485, -2440, -2395, -2382, + -2370, -2400, -2431, -2509, -2589, -2559, -2530, -2500, + -2472, -2429, -2387, -2489, -2335, -2939, -2008, -1331, + -2447, -2395, -2343, -2355, -2367, -2367, -2367, -2367, + -1952, -1994, -2037, -2047, -2058, -2148, -1727, -1977, + -2228, -2472, -2716, -2832, -2948, -2584, -2220, -1856, + -1492, -1277, -1062, -847, -632, -561, -490, -547, + -604, -581, -558, -343, -1152, -2281, -2386, -2523, + -1124, -40, +19, +15, +10, -1242, -2495, -2531, + -2568, -2459, -2350, -2369, -2388, -2407, -2426, -2477, + -2528, -2593, -2659, -2212, -1254, +369, +967, -1026, + -2508, -2428, -2348, -2364, -2380, -2380, -2380, -2380, + -1948, -1996, -2044, -2060, -2077, -1957, -1837, -2069, + -2303, -2545, -2788, -2918, -3049, -2873, -2442, -2026, + -1611, -1374, -1138, -965, -793, -732, -672, -707, + -743, -847, -953, -2017, -2059, -2441, -2313, -2327, + -295, +99, -19, +23, +65, +26, -13, -629, + -1246, -1795, -2345, -2509, -2675, -2540, -2406, -1887, + -1368, -467, +434, +439, +699, +1162, +856, -2695, + -2409, -2413, -2417, -2389, -2361, -2361, -2361, -2361, + -1944, -1998, -2052, -2074, -2097, -1767, -1949, -2163, + -2378, -2619, -2860, -3005, -3150, -3163, -2664, -2197, + -1730, -1472, -1214, -1084, -954, -904, -854, -868, + -882, -859, -836, -877, -1942, -2091, -2240, -2389, + +22, -18, -57, +32, +121, +14, -93, -9, + +76, +149, +221, +166, +110, +143, +175, +239, + +304, +379, +455, +530, +605, +676, +235, -2573, + -2310, -2398, -2486, -2414, -2342, -2342, -2342, -2342, + -1940, -2000, -2060, -2072, -2084, -1640, -1964, -2144, + -2325, -2532, -2740, -2899, -3059, -3052, -2790, -2319, + -1849, -1569, -1290, -1202, -1115, -1075, -1036, -1028, + -1021, -1077, -1135, -503, -2689, -2395, -2359, -1553, + +19, -6, -30, +25, +80, +34, -12, +37, + +86, +124, +162, +137, +111, +137, +163, +237, + +312, +393, +475, +525, +574, +654, -803, -2466, + -2339, -2383, -2427, -2375, -2323, -2323, -2323, -2323, + -1936, -2002, -2068, -2070, -2072, -1514, -1980, -2126, + -2272, -2446, -2620, -2794, -2968, -2942, -2916, -2442, + -1968, -1667, -1366, -1321, -1276, -1247, -1218, -1189, + -1160, -1041, -922, -1411, -2412, -2189, -2478, -719, + +16, +6, -4, +18, +40, +54, +68, +82, + +96, +100, +104, +108, +112, +132, +152, +236, + +320, +408, +496, +520, +544, +632, -1840, -2360, + -2368, -2368, -2368, -2336, -2304, -2304, -2304, -2304, + -1898, -1921, -1944, -2111, -1766, -1551, -1848, -1985, + -2122, -2318, -2515, -2664, -2813, -3074, -3079, -2828, + -2321, -2024, -1729, -1608, -1489, -1457, -1425, -1393, + -1362, -1246, -1131, -1879, -2372, -2532, -2693, +331, + +25, +40, +55, +54, +54, +71, +88, +105, + +123, +151, +180, +208, +237, +83, -70, +48, + +167, +248, +329, +346, +363, +733, -2738, -2577, + -2416, -2395, -2374, -2353, -2332, -2332, -2332, -2332, + -1860, -1840, -1820, -2152, -1460, -1588, -1716, -1844, + -1972, -2191, -2411, -2535, -2659, -2950, -2730, -2958, + -2674, -2383, -2092, -1897, -1703, -1668, -1633, -1598, + -1564, -1452, -1340, -2348, -2333, -2365, -1885, -157, + +34, +74, +115, +91, +68, +88, +109, +129, + +150, +203, +256, +309, +362, +291, +220, +117, + +14, +88, +162, +172, +183, -702, -2612, -2282, + -2464, -2422, -2380, -2370, -2360, -2360, -2360, -2360, + -2110, -1967, -1824, -1953, -1314, -1513, -1712, -1815, + -1918, -2207, -2242, -2453, -2408, -2602, -2541, -2752, + -2707, -2692, -2679, -2409, -2140, -2054, -1968, -1867, + -1766, -1721, -1677, -2369, -2293, -2516, -948, -53, + +75, +92, +110, +95, +82, +105, +129, +152, + +177, +222, +268, +313, +359, +354, +350, +441, + +533, +472, +411, +414, +674, -1689, -2518, -2339, + -2416, -2401, -2386, -2387, -2388, -2388, -2388, -2388, + -1848, -1838, -1828, -1754, -1168, -1438, -1708, -1786, + -1864, -2225, -2075, -2372, -2158, -2255, -2353, -2546, + -2740, -2747, -2755, -2666, -2578, -2441, -2305, -2136, + -1968, -1991, -2015, -2390, -2254, -2669, -13, +51, + +116, +111, +106, +101, +96, +123, +150, +177, + +204, +242, +280, +318, +356, +418, +480, +510, + +540, +600, +661, +657, +1166, -2677, -2425, -2396, + -2368, -2380, -2392, -2404, -2416, -2416, -2416, -2416, + -1882, -1711, -1796, -1369, -1198, -1419, -1640, -1749, + -1858, -1977, -1842, -2058, -2019, -2113, -2207, -2366, + -2525, -2478, -2689, -2836, -2983, -2759, -2536, -2393, + -2250, -2194, -2139, -2357, -2318, -2018, +72, +113, + +157, +150, +145, +139, +134, +159, +186, +212, + +239, +273, +308, +342, +377, +439, +502, +548, + +595, +632, +669, +931, +170, -2666, -2430, -2403, + -2376, -2385, -2394, -2403, -2412, -2412, -2412, -2412, + -1916, -1840, -2276, -1240, -1228, -1400, -1572, -1712, + -1852, -1731, -1610, -1745, -1881, -1972, -2063, -2186, + -2310, -2211, -2625, -2751, -2877, -2822, -2768, -2650, + -2532, -2398, -2265, -2324, -2383, -1369, +156, +177, + +198, +191, +185, +178, +172, +197, +223, +248, + +274, +305, +336, +367, +398, +461, +524, +587, + +650, +664, +679, +1206, -827, -2656, -2437, -2410, + -2384, -2390, -2396, -2402, -2408, -2408, -2408, -2408, + -1950, -1953, -1956, -1063, -1194, -1317, -1440, -1435, + -1430, -1499, -1314, -1431, -1550, -1638, -1726, -1798, + -1871, -1927, -2240, -2409, -2578, -2597, -2616, -2731, + -2846, -2554, -2262, -2259, -2511, -527, +176, +207, + +239, +231, +224, +217, +210, +234, +259, +284, + +309, +336, +364, +391, +419, +482, +546, +609, + +673, +744, +816, +936, -2015, -2485, -2187, -2289, + -2392, -2395, -2398, -2401, -2404, -2404, -2404, -2404, + -1984, -2066, -1636, -886, -1160, -1234, -1308, -1414, + -1520, -2037, -2042, -1887, -1732, -1817, -1902, -1923, + -1944, -1900, -1856, -2068, -2280, -2372, -2464, -2556, + -2648, -2454, -2260, -2194, -2640, +314, +196, +238, + +280, +272, +264, +256, +248, +272, +296, +320, + +344, +368, +392, +416, +440, +504, +568, +632, + +696, +825, +954, +923, -2692, -2315, -2450, -2425, + -2400, -2400, -2400, -2400, -2400, -2400, -2400, -2400, + -2252, -1953, -1142, -1035, -1441, -1826, -2211, -2244, + -2278, -2220, -1908, -1914, -1922, -2001, -2336, -2095, + -2111, -2171, -2231, -2131, -2031, -2143, -2255, -2303, + -2352, -2306, -2260, -2359, -1689, +442, +269, +305, + +341, +333, +325, +317, +309, +329, +349, +369, + +389, +415, +441, +468, +494, +536, +579, +669, + +760, +797, +1091, -248, -2610, -2406, -2459, -2431, + -2404, -2400, -2396, -2392, -2388, -2388, -2388, -2388, + -2008, -2096, -1673, -1953, -2234, -2162, -2091, -2051, + -2012, -2149, -2286, -2199, -2113, -1930, -2259, -2012, + -2278, -2186, -2094, -2194, -2295, -2171, -2047, -2051, + -2056, -2158, -2261, -2524, -739, +570, +343, +372, + +402, +394, +386, +378, +370, +386, +402, +418, + +434, +462, +491, +520, +549, +569, +590, +707, + +824, +770, +1228, -1418, -2528, -2498, -2468, -2438, + -2408, -2400, -2392, -2384, -2376, -2376, -2376, -2376, + -1988, -2191, -2139, -2150, -2163, -2130, -2098, -2081, + -2066, -2140, -2216, -2179, -2143, -2066, -2245, -2137, + -2285, -2233, -2181, -2225, -2270, -2326, -2382, -2166, + -1952, -2250, -2549, -2465, +180, +394, +352, +407, + +463, +455, +447, +423, +399, +523, +391, +547, + +447, +493, +540, +572, +603, +633, +665, +792, + +920, +1094, +1269, -2764, -2446, -2429, -2413, -2412, + -2412, -2400, -2388, -2376, -2364, -2364, -2364, -2364, + -1968, -2031, -2094, -2093, -2092, -2099, -2106, -2113, + -2120, -2133, -2147, -2160, -2174, -2203, -2233, -2262, + -2292, -2280, -2269, -2257, -2246, -2226, -2207, -2283, + -2360, -2343, -2327, -2406, +586, -38, +363, +443, + +524, +516, +508, +468, +428, +660, +380, +676, + +460, +525, +591, +624, +658, +699, +741, +878, + +1016, +907, +286, -2575, -2364, -2361, -2358, -2387, + -2416, -2400, -2384, -2368, -2352, -2352, -2352, -2352, + -2020, -2071, -2124, -2080, -2037, -2062, -2089, -2115, + -2142, -2152, -2164, -2176, -2188, -2211, -2235, -2259, + -2283, -2275, -2267, -2260, -2253, -2249, -2246, -2290, + -2336, -2337, -2339, -1205, -71, -16, +296, +496, + +441, +469, +497, +381, +521, +635, +493, +735, + +465, +544, +624, +640, +656, +747, +839, +899, + +960, +1115, -1033, -2493, -2418, -2378, -2339, -2379, + -2420, -2408, -2396, -2384, -2372, -2372, -2372, -2372, + -2072, -2113, -2155, -2068, -1982, -2027, -2073, -2118, + -2164, -2173, -2183, -2193, -2203, -2220, -2238, -2256, + -2274, -2270, -2267, -2264, -2261, -2273, -2286, -2299, + -2312, -2332, -2352, -2052, -729, +7, +230, +550, + +358, +422, +486, +294, +614, +610, +606, +794, + +470, +564, +658, +656, +655, +797, +939, +921, + +904, +1324, -2352, -2412, -2472, -2396, -2320, -2372, + -2424, -2416, -2408, -2400, -2392, -2392, -2392, -2392, + -1996, -1930, -1865, -1960, -2055, -2087, -2120, -2153, + -2186, -2193, -2201, -2209, -2217, -2229, -2241, -2253, + -2265, -2265, -2266, -2267, -2268, -2280, -2294, -2306, + -2320, -2342, -2365, -2707, -2538, -1491, -188, +172, + +275, +327, +379, +287, +451, +505, +559, +773, + +475, +551, +628, +512, +653, +909, +654, +1007, + +1104, -739, -2583, -2506, -2430, -2397, -2365, -2396, + -2428, -2424, -2420, -2416, -2412, -2412, -2412, -2412, + -1920, -2004, -2088, -2108, -2128, -2148, -2168, -2188, + -2208, -2214, -2220, -2226, -2232, -2238, -2244, -2250, + -2256, -2261, -2266, -2271, -2276, -2289, -2302, -2315, + -2328, -2353, -2378, -2339, -2300, -2477, -1630, -719, + +192, +232, +272, +280, +288, +400, +512, +752, + +480, +539, +598, +369, +652, +767, -142, -1211, + -2792, -2547, -2302, -2345, -2388, -2399, -2410, -2421, + -2432, -2432, -2432, -2432, -2432, -2432, -2432, -2432, + -2024, -2070, -2116, -2130, -2144, -2164, -2184, -2204, + -2224, -2228, -2232, -2236, -2240, -2244, -2248, -2252, + -2256, -2262, -2270, -2276, -2284, -2296, -2310, -2322, + -2336, -2319, -2304, -2287, -2272, -2559, -2336, -1855, + -1376, -2264, -1104, -520, +64, +384, +704, +704, + +192, -44, -280, -1236, -1936, -3018, -2564, -2349, + -2392, -2390, -2390, -2388, -2388, -2398, -2410, -2420, + -2432, -2432, -2432, -2432, -2432, -2432, -2432, -2432, + -2128, -2136, -2144, -2152, -2160, -2180, -2200, -2220, + -2240, -2242, -2244, -2246, -2248, -2250, -2252, -2254, + -2256, -2265, -2274, -2283, -2292, -2305, -2318, -2331, + -2344, -2287, -2230, -2237, -2244, -2387, -2530, -2481, + -2432, -2456, -2480, -2600, -2720, -2448, -2176, -1904, + -2144, -2419, -2694, -2585, -2476, -2451, -2426, -2465, + -2504, -2491, -2478, -2433, -2388, -2399, -2410, -2421, + -2432, -2432, -2432, -2432, -2432, -2432, -2432, -2432, + -2104, -2122, -2140, -2158, -2176, -2196, -2216, -2236, + -2256, -2256, -2256, -2256, -2256, -2256, -2256, -2256, + -2256, -2266, -2278, -2288, -2300, -2312, -2326, -2338, + -2352, -2317, -2284, -2281, -2280, -2357, -2436, -2417, + -2400, -2408, -2416, -2360, -2304, -2480, -864, -1648, + -1408, -1225, -2580, -2509, -2440, -2427, -2416, -2435, + -2456, -2446, -2438, -2412, -2388, -2398, -2410, -2420, + -2432, -2432, -2432, -2432, -2432, -2432, -2432, -2432, + -2080, -2108, -2136, -2164, -2192, -2212, -2232, -2252, + -2272, -2270, -2268, -2266, -2264, -2262, -2260, -2258, + -2256, -2269, -2282, -2295, -2308, -2321, -2334, -2347, + -2360, -2349, -2338, -2327, -2316, -2329, -2342, -2355, + -2368, -2360, -2352, -2376, -2400, -2256, -2624, -1392, + -1696, -2593, -2466, -2435, -2404, -2405, -2406, -2407, + -2408, -2403, -2398, -2393, -2388, -2399, -2410, -2421, + -2432, -2432, -2432, -2432, -2432, -2432, -2432, -2432, + -2080, -2108, -2136, -2164, -2192, -2212, -2232, -2252, + -2272, -2270, -2268, -2266, -2264, -2262, -2260, -2258, + -2256, -2268, -2282, -2294, -2308, -2320, -2334, -2346, + -2360, -2348, -2338, -2326, -2316, -2328, -2342, -2354, + -2368, -2360, -2352, -2360, -2368, -2352, -2592, -2192, + -2560, -2768, -2466, -2434, -2404, -2404, -2406, -2406, + -2408, -2402, -2398, -2392, -2388, -2398, -2410, -2420, + -2432, -2432, -2432, -2432, -2432, -2432, -2432, -2432, + -2080, -2108, -2136, -2164, -2192, -2212, -2232, -2252, + -2272, -2270, -2268, -2266, -2264, -2262, -2260, -2258, + -2256, -2269, -2282, -2295, -2308, -2321, -2334, -2347, + -2360, -2349, -2338, -2327, -2316, -2329, -2342, -2355, + -2368, -2360, -2352, -2344, -2336, -2448, -2560, -2480, + -2400, -2433, -2466, -2435, -2404, -2405, -2406, -2407, + -2408, -2403, -2398, -2393, -2388, -2399, -2410, -2421, + -2432, -2432, -2432, -2432, -2432, -2432, -2432, -2432, + -2080, -2108, -2136, -2164, -2192, -2212, -2232, -2252, + -2272, -2270, -2268, -2266, -2264, -2262, -2260, -2258, + -2256, -2268, -2282, -2294, -2308, -2320, -2334, -2346, + -2360, -2348, -2338, -2326, -2316, -2328, -2342, -2354, + -2368, -2360, -2352, -2344, -2336, -2448, -2560, -2480, + -2400, -2432, -2466, -2434, -2404, -2404, -2406, -2406, + -2408, -2402, -2398, -2392, -2388, -2398, -2410, -2420, + -2432, -2432, -2432, -2432, -2432, -2432, -2432, -2432 +}; + +/** + * 64x64 XRGB Image + */ + +static UINT32 TEST_XRGB_IMAGE[4096] = +{ + 0xFF229cdf, 0xFF249de0, 0xFF259fe2, 0xFF2ca5e8, 0xFF229cdf, 0xFF229ce0, 0xFF239de0, 0xFF229ce0, + 0xFF229cdf, 0xFF229cdf, 0xFF239ce0, 0xFF249ce0, 0xFF249ce0, 0xFF219ce3, 0xFF1e9ce6, 0xFF209ae2, + 0xFF2299dd, 0xFF2199de, 0xFF209adf, 0xFF209ae0, 0xFF1f9be0, 0xFF1e9ae0, 0xFF1d99e0, 0xFF1c98e0, + 0xFF1b97df, 0xFF1e96dc, 0xFF2194d9, 0xFF1f93dd, 0xFF1d93e0, 0xFF1b94dc, 0xFF1895d8, 0xFF1c92db, + 0xFF208fde, 0xFF1b91de, 0xFF1693df, 0xFF1793df, 0xFF1992df, 0xFF1891df, 0xFF178fdf, 0xFF178edf, + 0xFF168dde, 0xFF158cdd, 0xFF148cdc, 0xFF128cda, 0xFF118cd9, 0xFF118bd9, 0xFF128ada, 0xFF1289da, + 0xFF1288db, 0xFF1187da, 0xFF1186da, 0xFF1085da, 0xFF0f85d9, 0xFF0f84d9, 0xFF0e83d9, 0xFF0d82d8, + 0xFF0d82d8, 0xFF0d81d8, 0xFF0d80d7, 0xFF0d7fd7, 0xFF0d7ed6, 0xFF0d7ed6, 0xFF0d7ed6, 0xFF0d7ed6, + 0xFF259fe1, 0xFF27a1e2, 0xFF29a2e3, 0xFF2ba4e6, 0xFF249fe1, 0xFF249fe1, 0xFF249fe1, 0xFF249ee1, + 0xFF239ee1, 0xFF249ee1, 0xFF249ee1, 0xFF259de1, 0xFF259de2, 0xFF249de2, 0xFF229de2, 0xFF229ce1, + 0xFF229bdf, 0xFF219ce0, 0xFF209ce1, 0xFF209ce2, 0xFF209ce2, 0xFF209ae0, 0xFF2199de, 0xFF1f99df, + 0xFF1d98e0, 0xFF1e97e0, 0xFF1f97e0, 0xFF1d96df, 0xFF1c95de, 0xFF1c94e0, 0xFF1c94e1, 0xFF1d93e1, + 0xFF1d92e0, 0xFF1b93de, 0xFF1a94dc, 0xFF1a93de, 0xFF1a93e0, 0xFF1992e0, 0xFF1891df, 0xFF188fdf, + 0xFF178edf, 0xFF168ede, 0xFF158edd, 0xFF148ddc, 0xFF138ddb, 0xFF138cdb, 0xFF138bdb, 0xFF128adb, + 0xFF1289db, 0xFF1288db, 0xFF1187db, 0xFF1186db, 0xFF1085db, 0xFF0f84da, 0xFF0e83d9, 0xFF0e83d9, + 0xFF0e83d9, 0xFF0e82d9, 0xFF0e81d8, 0xFF0e80d8, 0xFF0d7fd7, 0xFF0d7fd7, 0xFF0d7fd7, 0xFF0d7fd7, + 0xFF27a3e3, 0xFF2aa4e3, 0xFF2ea6e3, 0xFF2aa4e3, 0xFF26a2e3, 0xFF26a1e3, 0xFF25a1e3, 0xFF25a0e3, + 0xFF25a0e3, 0xFF25a0e3, 0xFF259fe3, 0xFF269fe3, 0xFF269ee4, 0xFF279ee1, 0xFF279edf, 0xFF259ee0, + 0xFF239ee1, 0xFF219ee2, 0xFF209ee4, 0xFF209de4, 0xFF219de3, 0xFF229be0, 0xFF2499dc, 0xFF2299de, + 0xFF1f98e0, 0xFF1d99e4, 0xFF1b9ae7, 0xFF1c98e2, 0xFF1c96dc, 0xFF1e94e3, 0xFF2092ea, 0xFF1d94e6, + 0xFF1a96e2, 0xFF1c96de, 0xFF1d95da, 0xFF1c94de, 0xFF1b94e1, 0xFF1a93e0, 0xFF1a92e0, 0xFF1991e0, + 0xFF1890e0, 0xFF1790df, 0xFF178fde, 0xFF168fde, 0xFF158edd, 0xFF148ddd, 0xFF138cdc, 0xFF138bdc, + 0xFF128adc, 0xFF1289dc, 0xFF1188dc, 0xFF1187dd, 0xFF1086dd, 0xFF0f85db, 0xFF0e83d9, 0xFF0e84da, + 0xFF0f84da, 0xFF0e83da, 0xFF0e82d9, 0xFF0e81d9, 0xFF0e80d8, 0xFF0e80d8, 0xFF0e80d8, 0xFF0e80d8, + 0xFF2aa7e5, 0xFF2da7e4, 0xFF31a8e3, 0xFF2ca6e3, 0xFF27a4e4, 0xFF27a3e4, 0xFF27a3e4, 0xFF27a3e4, + 0xFF26a2e4, 0xFF26a2e4, 0xFF27a1e5, 0xFF27a0e5, 0xFF27a0e6, 0xFF26a0e5, 0xFF25a0e4, 0xFF259fe4, + 0xFF259ee3, 0xFF239ee5, 0xFF229fe6, 0xFF229fe5, 0xFF229fe4, 0xFF13a5e6, 0xFF1b9fe8, 0xFF16a0e8, + 0xFF11a0e7, 0xFF129fef, 0xFF139ef7, 0xFF1b99ec, 0xFF179ae2, 0xFF149ce4, 0xFF1d98e5, 0xFF1c97e6, + 0xFF1b96e7, 0xFF1c98dc, 0xFF1d97df, 0xFF1c96e1, 0xFF1c94e2, 0xFF1b94e1, 0xFF1b93e1, 0xFF1a93e0, + 0xFF1a92e0, 0xFF1991e0, 0xFF1890e0, 0xFF1790df, 0xFF168fdf, 0xFF158ede, 0xFF158dde, 0xFF148cdd, + 0xFF138bdc, 0xFF128add, 0xFF1289dd, 0xFF1188de, 0xFF1187de, 0xFF0f85dc, 0xFF0d83da, 0xFF0f85db, + 0xFF1086db, 0xFF0f84db, 0xFF0f83da, 0xFF0e82da, 0xFF0e81da, 0xFF0e81da, 0xFF0e81da, 0xFF0e81da, + 0xFF2caae7, 0xFF30aae5, 0xFF34abe3, 0xFF2ea8e4, 0xFF29a6e5, 0xFF28a6e5, 0xFF28a5e5, 0xFF28a5e5, + 0xFF28a5e6, 0xFF28a4e6, 0xFF28a3e7, 0xFF28a2e7, 0xFF28a1e8, 0xFF25a2e9, 0xFF23a3ea, 0xFF25a0e8, + 0xFF279ee6, 0xFF259fe7, 0xFF23a0e9, 0xFF18a4f5, 0xFF0ea7ff, 0xFF1ba6de, 0xFF558ebb, 0xFF6f839c, + 0xFF89797e, 0xFF8d797c, 0xFF917979, 0xFF7f7b94, 0xFF5687af, 0xFF229bd6, 0xFF04a4fd, 0xFF109df4, + 0xFF1c97eb, 0xFF1c9ada, 0xFF1c98e4, 0xFF1c97e3, 0xFF1d95e2, 0xFF1c95e2, 0xFF1c94e2, 0xFF1c94e1, + 0xFF1b94e1, 0xFF1a93e1, 0xFF1a92e1, 0xFF1991e1, 0xFF1890e1, 0xFF178fe0, 0xFF158edf, 0xFF148dde, + 0xFF138cdd, 0xFF128bde, 0xFF128adf, 0xFF1289df, 0xFF1188e0, 0xFF0f85dd, 0xFF0d83da, 0xFF0f85db, + 0xFF1187dd, 0xFF1086dc, 0xFF0f84dc, 0xFF0e83db, 0xFF0e81db, 0xFF0e81db, 0xFF0e81db, 0xFF0e81db, + 0xFF30abe5, 0xFF36afe8, 0xFF34abe4, 0xFF2faae5, 0xFF2ba8e6, 0xFF36aee8, 0xFF26a6e8, 0xFF29a7e7, + 0xFF2ca8e7, 0xFF2da7e6, 0xFF2fa5e5, 0xFF2ca5e7, 0xFF29a4e9, 0xFF2ba5e5, 0xFF2ca5e2, 0xFF10aaef, + 0xFF13adf6, 0xFF23a3f8, 0xFF6091a5, 0xFFa6755d, 0xFFec5915, 0xFFff490c, 0xFFfa5504, 0xFFff590f, + 0xFFff5d1b, 0xFFff6116, 0xFFfa6412, 0xFFff550f, 0xFFff4b0d, 0xFFfb4918, 0xFFf54823, 0xFF8e737e, + 0xFF269eda, 0xFF06a2ff, 0xFF1d97e2, 0xFF1799ea, 0xFF1c97e4, 0xFF1a98e4, 0xFF1898e4, 0xFF1a96e3, + 0xFF1b95e3, 0xFF1a94e2, 0xFF1a93e0, 0xFF1992e1, 0xFF1891e2, 0xFF1790e1, 0xFF168fe0, 0xFF158fdf, + 0xFF138ede, 0xFF138ddf, 0xFF138ce0, 0xFF128be0, 0xFF1189e0, 0xFF1087de, 0xFF0f85db, 0xFF138ae0, + 0xFF0f87dc, 0xFF0f86dc, 0xFF0f85dc, 0xFF0f84dc, 0xFF0e83db, 0xFF0e83db, 0xFF0e83db, 0xFF0e83db, + 0xFF34abe2, 0xFF3cb4ec, 0xFF34ace5, 0xFF31abe6, 0xFF2daae8, 0xFF44b6eb, 0xFF24a7ea, 0xFF29aaea, + 0xFF2face9, 0xFF32a9e6, 0xFF35a7e3, 0xFF30a7e6, 0xFF2ba8ea, 0xFF25aaf0, 0xFF20adf6, 0xFF4d8ba7, + 0xFFb8674c, 0xFFff5510, 0xFFf7650c, 0xFFf86313, 0xFFfa611b, 0xFFf0671f, 0xFFfc6222, 0xFFfb6926, + 0xFFf96f29, 0xFFf67122, 0xFFf3721b, 0xFFf26b20, 0xFFf16424, 0xFFff5622, 0xFFff531f, 0xFFff4b17, + 0xFFff440e, 0xFFb1615b, 0xFF1f95e0, 0xFF129bf0, 0xFF1c9ae5, 0xFF189ae6, 0xFF159be7, 0xFF1898e6, + 0xFF1b95e5, 0xFF1b95e2, 0xFF1995e0, 0xFF1994e1, 0xFF1892e2, 0xFF1792e1, 0xFF1691e0, 0xFF1590df, + 0xFF148fdf, 0xFF148fe0, 0xFF148fe1, 0xFF128de1, 0xFF108be0, 0xFF1189de, 0xFF1186dd, 0xFF178fe4, + 0xFF0e87db, 0xFF0e87dc, 0xFF0f87dd, 0xFF0f85dc, 0xFF0e84dc, 0xFF0e84dc, 0xFF0e84dc, 0xFF0e84dc, + 0xFF36b1eb, 0xFF36b4f0, 0xFF2eafed, 0xFF2caeec, 0xFF2aadec, 0xFF41b4ef, 0xFF29abe9, 0xFF2cabe8, + 0xFF2fabe7, 0xFF31abe6, 0xFF32aae6, 0xFF2faae7, 0xFF2ca9e8, 0xFF25a7eb, 0xFF946a5f, 0xFFff3e06, + 0xFFf95618, 0xFFe27312, 0xFFf87329, 0xFFf77427, 0xFFf77626, 0xFFf27628, 0xFFf8712b, 0xFFf9772e, + 0xFFf97e30, 0xFFf77f2e, 0xFFf5812b, 0xFFf57b2c, 0xFFf5752d, 0xFFfd6a2b, 0xFFfb652a, 0xFFf65e2c, + 0xFFf1572e, 0xFFff4810, 0xFFff460f, 0xFF817680, 0xFF02a7f1, 0xFF2496ea, 0xFF199be4, 0xFF1b98e4, + 0xFF1d96e5, 0xFF1b96e2, 0xFF1a96e0, 0xFF1995e1, 0xFF1794e3, 0xFF1793e2, 0xFF1692e1, 0xFF1691e0, + 0xFF1590df, 0xFF1591e1, 0xFF1591e3, 0xFF138fe1, 0xFF108ce0, 0xFF128be0, 0xFF158ae0, 0xFF168de2, + 0xFF0f89dd, 0xFF0f88dd, 0xFF0f88dd, 0xFF0f86dd, 0xFF0f85dc, 0xFF0f85dc, 0xFF0f85dc, 0xFF0f85dc, + 0xFF5fc1e7, 0xFF57bee8, 0xFF4fbbe9, 0xFF4ebae6, 0xFF4ebae3, 0xFF51b6ee, 0xFF2eaee8, 0xFF2eade6, + 0xFF2fabe5, 0xFF2face7, 0xFF2eade9, 0xFF2eace7, 0xFF2daae5, 0xFF15b2ff, 0xFFec4310, 0xFFf15016, + 0xFFf75d1c, 0xFFf87123, 0xFFf9862a, 0xFFf6882d, 0xFFf48b31, 0xFFf48532, 0xFFf47f33, 0xFFf78535, + 0xFFfa8c37, 0xFFf88e39, 0xFFf7903a, 0xFFf88b38, 0xFFf98635, 0xFFf87e35, 0xFFf77635, 0xFFf76d34, + 0xFFf76532, 0xFFf85e31, 0xFFf95730, 0xFFff5125, 0xFFf65237, 0xFF03a5fd, 0xFF1e9be1, 0xFF1e98e3, + 0xFF1f96e5, 0xFF1c97e2, 0xFF1a97df, 0xFF1896e1, 0xFF1795e4, 0xFF1794e3, 0xFF1793e2, 0xFF1692e1, + 0xFF1692e0, 0xFF1693e2, 0xFF1794e4, 0xFF1391e2, 0xFF0f8ee0, 0xFF148ee1, 0xFF198ee3, 0xFF148ce1, + 0xFF0f8bde, 0xFF0f8ade, 0xFF0f89de, 0xFF0f88dd, 0xFF0f86dd, 0xFF0f86dd, 0xFF0f86dd, 0xFF0f86dd, + 0xFF3cb6ee, 0xFF36b4ef, 0xFF30b2f0, 0xFF30b1ee, 0xFF2fb1ec, 0xFF38b0ef, 0xFF2eaee9, 0xFF2faee8, + 0xFF31ade6, 0xFF2fafe8, 0xFF2eb1ea, 0xFF31adec, 0xFF29afee, 0xFF30aac8, 0xFFff3d05, 0xFFfa501a, + 0xFFf96021, 0xFFf87428, 0xFFf7882f, 0xFFfa9638, 0xFFf59b38, 0xFFf5973b, 0xFFf6923e, 0xFFf89440, + 0xFFfa9742, 0xFFfa9a44, 0xFFfa9d46, 0xFFf99845, 0xFFf89444, 0xFFf98d43, 0xFFfa8641, 0xFFf97d3f, + 0xFFf9743d, 0xFFf77039, 0xFFf56d35, 0xFFff6122, 0xFFbf6c63, 0xFF129eef, 0xFF229ae8, 0xFF1c99ed, + 0xFF179ce4, 0xFF1498f0, 0xFF1b94e1, 0xFF1a96e2, 0xFF1998e3, 0xFF1897e4, 0xFF1896e5, 0xFF1895e4, + 0xFF1993e2, 0xFF1792e1, 0xFF1590df, 0xFF1692e2, 0xFF1793e5, 0xFF1490e4, 0xFF128ee2, 0xFF118de3, + 0xFF108de3, 0xFF118bde, 0xFF1289d9, 0xFF0f88e2, 0xFF0c89dd, 0xFF1085e0, 0xFF0987e4, 0xFF0987e4, + 0xFF40b5e9, 0xFF3bb4e9, 0xFF37b2ea, 0xFF37b2e9, 0xFF38b1e8, 0xFF33b0ea, 0xFF2eaeeb, 0xFF30afe9, + 0xFF33afe8, 0xFF30b2ea, 0xFF2eb5ec, 0xFF34aff2, 0xFF25b4f7, 0xFF8d7f86, 0xFFf64f00, 0xFFed5c1e, + 0xFFfa6326, 0xFFf7762d, 0xFFf58a35, 0xFFfea242, 0xFFf7ab3f, 0xFFf7a843, 0xFFf7a548, 0xFFf9a34a, + 0xFFfaa24c, 0xFFfba64f, 0xFFfcaa52, 0xFFf9a652, 0xFFf7a252, 0xFFfa9c50, 0xFFfd974e, 0xFFfc8d4b, + 0xFFfb8348, 0xFFf68341, 0xFFf1823a, 0xFFf5732c, 0xFF718cac, 0xFF179af0, 0xFF2599ef, 0xFF2697e9, + 0xFF269bc6, 0xFF1696f1, 0xFF1d91e3, 0xFF1c96e3, 0xFF1b9be3, 0xFF1a99e6, 0xFF1998e9, 0xFF1b97e7, + 0xFF1c95e5, 0xFF1891df, 0xFF138dda, 0xFF1992e2, 0xFF1e98ea, 0xFF1592e6, 0xFF0b8de2, 0xFF0e8ee5, + 0xFF108fe9, 0xFF128cdf, 0xFF1489d4, 0xFF0e88e6, 0xFF088cdc, 0xFF1184e4, 0xFF0488ec, 0xFF0488ec, + 0xFF3eb6ea, 0xFF3bb5eb, 0xFF38b4eb, 0xFF38b4eb, 0xFF38b3eb, 0xFF35b2eb, 0xFF33b1ec, 0xFF34b1eb, + 0xFF35b1ea, 0xFF32b3e9, 0xFF30b5e9, 0xFF34b0f0, 0xFF23b6f8, 0xFFc56044, 0xFFf9540c, 0xFFf26322, + 0xFFf77029, 0xFFf77d2f, 0xFFf78b35, 0xFFfba142, 0xFFf6b046, 0xFFfbb44f, 0xFFf7b051, 0xFFf9af54, + 0xFFfbad56, 0xFFfcb25a, 0xFFfeb75d, 0xFFfab35f, 0xFFf6b061, 0xFFfaac5d, 0xFFfda95a, 0xFFfb9f55, + 0xFFf99551, 0xFFf7914b, 0xFFf68d45, 0xFFff7e23, 0xFF1ba5f0, 0xFF129ef4, 0xFF2896f1, 0xFF239fb1, + 0xFF6c9600, 0xFF3c9c82, 0xFF179ef8, 0xFF169cf4, 0xFF149de3, 0xFF169ae5, 0xFF1897e7, 0xFF1995e6, + 0xFF1a93e5, 0xFF1993e3, 0xFF1793e0, 0xFF1c98e6, 0xFF1a95e5, 0xFF1692e5, 0xFF138fe5, 0xFF138ceb, + 0xFF138be3, 0xFF0087e4, 0xFF007cf5, 0xFF1a86d3, 0xFF0d8cf1, 0xFF008fe2, 0xFF0d85ea, 0xFF0886f1, + 0xFF3cb7ec, 0xFF3bb7ed, 0xFF3ab6ed, 0xFF39b6ed, 0xFF38b5ed, 0xFF37b5ed, 0xFF37b4ed, 0xFF37b3ed, + 0xFF36b3ec, 0xFF34b4e9, 0xFF31b5e5, 0xFF35b1ef, 0xFF21b8fa, 0xFFfd4203, 0xFFfc581e, 0xFFf86a26, + 0xFFf47c2d, 0xFFf78431, 0xFFf98c36, 0xFFf8a041, 0xFFf6b54d, 0xFFfec05b, 0xFFf6bc5a, 0xFFf8ba5d, + 0xFFfbb861, 0xFFfdbe65, 0xFFffc469, 0xFFfbc16c, 0xFFf5bd70, 0xFFfabc6b, 0xFFfebb66, 0xFFfab160, + 0xFFf6a75a, 0xFFf89f55, 0xFFfa984f, 0xFFdf956f, 0xFF08a6fc, 0xFF259ddb, 0xFF159ff3, 0xFF4aa172, + 0xFF69a90d, 0xFF62a406, 0xFF5a981b, 0xFF34969b, 0xFF0e99ff, 0xFF1297f2, 0xFF1695e4, 0xFF1793e5, + 0xFF1892e5, 0xFF1995e6, 0xFF1a98e7, 0xFF209deb, 0xFF1593df, 0xFF1892e4, 0xFF1a91e9, 0xFF2095eb, + 0xFF259dd1, 0xFFd0f772, 0xFFc1f396, 0xFF0083f1, 0xFF1782a0, 0xFF3c7e2f, 0xFF1787cc, 0xFF0b8ada, + 0xFF3db9ed, 0xFF3cb8ed, 0xFF3bb8ed, 0xFF3ab7ed, 0xFF39b7ed, 0xFF39b7ed, 0xFF39b6ed, 0xFF3ab6ed, + 0xFF3ab6ed, 0xFF37b4ed, 0xFF34b2ec, 0xFF35abf3, 0xFF6e96b3, 0xFFff4601, 0xFFf86520, 0xFFf67329, + 0xFFf58131, 0xFFf78b37, 0xFFf9953e, 0xFFf8a649, 0xFFf8b854, 0xFFfcc260, 0xFFf8c465, 0xFFf9c36a, + 0xFFfac26e, 0xFFfac773, 0xFFfacb77, 0xFFfbcb7b, 0xFFfccb7e, 0xFFfac87b, 0xFFf8c578, 0xFFf9bc72, + 0xFFfbb46d, 0xFFf6b069, 0xFFfeaa57, 0xFF94a0a5, 0xFF13a1f3, 0xFF219df0, 0xFF199eff, 0xFF71c124, + 0xFF79b826, 0xFF72b21e, 0xFF6aaa24, 0xFF67a125, 0xFF649a19, 0xFF419d72, 0xFF1f9fcb, 0xFF1994ff, + 0xFF1399f1, 0xFF199cf4, 0xFF1ea0f8, 0xFF1b9cff, 0xFF1193f6, 0xFF1293f1, 0xFF1393ec, 0xFF0083ff, + 0xFF72cca0, 0xFFcbf982, 0xFFd0ffac, 0xFF79a046, 0xFF337700, 0xFF3a7c03, 0xFF0d8de2, 0xFF0d8edb, + 0xFF3fbbee, 0xFF3ebaed, 0xFF3db9ed, 0xFF3cb9ed, 0xFF3bb8ed, 0xFF3bb8ed, 0xFF3cb9ee, 0xFF3cb9ee, + 0xFF3db9ef, 0xFF3ab4f1, 0xFF37aff3, 0xFF32b3fe, 0xFFb48f7d, 0xFFff5907, 0xFFf37122, 0xFFf57c2b, + 0xFFf68735, 0xFFf7923d, 0xFFf89d45, 0xFFf9ac50, 0xFFf9bb5a, 0xFFf9c465, 0xFFfacd71, 0xFFfacd76, + 0xFFfacd7b, 0xFFf7cf80, 0xFFf4d286, 0xFFfcd689, 0xFFffd98c, 0xFFfbd48b, 0xFFf3cf8a, 0xFFf9c885, + 0xFFffc17f, 0xFFf5c27d, 0xFFffbc5e, 0xFF48abdc, 0xFF1e9deb, 0xFF1ea2e8, 0xFF1da8e5, 0xFF99d31c, + 0xFF8acb22, 0xFF82c427, 0xFF7abc2c, 0xFF75b429, 0xFF70ad25, 0xFF6dab17, 0xFF6ba908, 0xFF5ea912, + 0xFF519f54, 0xFF489b6d, 0xFF3e9887, 0xFF3b9592, 0xFF389880, 0xFF449663, 0xFF509446, 0xFF83b43c, + 0xFF4f851b, 0xFFafe187, 0xFF9fcc83, 0xFF368011, 0xFF43821c, 0xFF32853c, 0xFF0492f9, 0xFF1092dd, + 0xFF40bcee, 0xFF3fbcee, 0xFF3ebbee, 0xFF3dbaed, 0xFF3cbaed, 0xFF3cb9ed, 0xFF3cb9ec, 0xFF3cb9ec, + 0xFF3cb8ec, 0xFF3fb4f0, 0xFF43aff5, 0xFF0ebbe9, 0xFFffb897, 0xFFf7814d, 0xFFf57623, 0xFFf6812e, + 0xFFf88c39, 0xFFf89943, 0xFFf8a64d, 0xFFf8b257, 0xFFf9bd60, 0xFFfac96d, 0xFFfbd47b, 0xFFfad681, + 0xFFfad788, 0xFFfbd98e, 0xFFfbda93, 0xFFfae5a1, 0xFFfed692, 0xFFfadea0, 0xFFf9db98, 0xFFfad694, + 0xFFfbd090, 0xFFffd285, 0xFFffc778, 0xFF009afd, 0xFF26a8f2, 0xFF20a4f8, 0xFF53bea5, 0xFFa4da31, + 0xFF9dd638, 0xFF97d03a, 0xFF91ca3d, 0xFF8bc539, 0xFF85c035, 0xFF7dbe31, 0xFF74bc2d, 0xFF76b81c, + 0xFF77b027, 0xFF72ab25, 0xFF6da724, 0xFF6ba328, 0xFF68a31f, 0xFF58951a, 0xFF78b745, 0xFFbbf181, + 0xFF73ad4c, 0xFF417c15, 0xFF508b1e, 0xFF43861c, 0xFF498614, 0xFF17868b, 0xFF0b90f6, 0xFF168ee8, + 0xFF42beef, 0xFF41bdee, 0xFF40bcee, 0xFF3fbced, 0xFF3ebbed, 0xFF3dbaec, 0xFF3db9eb, 0xFF3cb8ea, + 0xFF3bb7e9, 0xFF39b9f0, 0xFF37bbf7, 0xFF50b5dc, 0xFFff9744, 0xFFfec49d, 0xFFf87a24, 0xFFf88530, + 0xFFf9913d, 0xFFf8a049, 0xFFf7af55, 0xFFf8b85d, 0xFFf9c065, 0xFFface75, 0xFFfcdb85, 0xFFfbde8d, + 0xFFfae195, 0xFFfee29b, 0xFFffe2a0, 0xFFfbe9a4, 0xFFffbe6b, 0xFFfdde9f, 0xFFffe8a6, 0xFFfbe3a3, + 0xFFf8dea0, 0xFFfdd899, 0xFFb6bdab, 0xFF119ff1, 0xFF1ea4e9, 0xFF1a9fff, 0xFF89d465, 0xFFb0e245, + 0xFFb0e04e, 0xFFacdc4e, 0xFFa7d94e, 0xFFa1d649, 0xFF9ad345, 0xFF97ce3d, 0xFF94c935, 0xFF8dc534, + 0xFF86c133, 0xFF7bbc32, 0xFF6fb731, 0xFF6db330, 0xFF6cae2e, 0xFF7eba3f, 0xFF70a531, 0xFF7bb54f, + 0xFF579a20, 0xFF5c9f2b, 0xFF519425, 0xFF80b965, 0xFF609a1d, 0xFF0390e3, 0xFF118ef2, 0xFF1c89f2, + 0xFF44c0ef, 0xFF43bfef, 0xFF42beee, 0xFF40bdee, 0xFF3fbcee, 0xFF3fbbed, 0xFF40baeb, 0xFF3eb9ed, + 0xFF3cb9ee, 0xFF37b9eb, 0xFF27bcf7, 0xFF949c8f, 0xFFfb9637, 0xFFf9bc7c, 0xFFf9b585, 0xFFf7994a, + 0xFFf69b43, 0xFFf6a64e, 0xFFf7b259, 0xFFf8bc66, 0xFFfac672, 0xFFfad380, 0xFFfae08d, 0xFFf9e698, + 0xFFf9eba2, 0xFFfeeaa6, 0xFFffeaab, 0xFFfcefa9, 0xFFfaba62, 0xFFfbdc99, 0xFFfff4b9, 0xFFfbecb2, + 0xFFf7e6ab, 0xFFffe5a3, 0xFF64b1d1, 0xFF199ff0, 0xFF269fe9, 0xFF0499f2, 0xFFe3f051, 0xFFd5ef58, + 0xFFc0e364, 0xFFbde165, 0xFFbae065, 0xFFb5de5d, 0xFFb0dc56, 0xFFaad74e, 0xFFa3d346, 0xFF9bd043, + 0xFF93cd3f, 0xFF8cc93e, 0xFF84c63c, 0xFF81c139, 0xFF7dbc36, 0xFF8bc746, 0xFF89c245, 0xFF63a02c, + 0xFF65aa2c, 0xFF5ea42d, 0xFF509626, 0xFFa4cf98, 0xFFd9eadd, 0xFFb9ddff, 0xFF389ef4, 0xFF008fd4, + 0xFF46c1ef, 0xFF44c0ef, 0xFF43bfef, 0xFF42beef, 0xFF40bdef, 0xFF42bced, 0xFF43baec, 0xFF40baf0, + 0xFF3dbaf4, 0xFF35b8e7, 0xFF17bdf7, 0xFFd97f50, 0xFFf79147, 0xFFf7a554, 0xFFffdbba, 0xFFf8a24d, + 0xFFf3a549, 0xFFf5ad53, 0xFFf7b55e, 0xFFf9c16f, 0xFFfbcc7f, 0xFFf9d88a, 0xFFf8e595, 0xFFf8eda2, + 0xFFf8f5ae, 0xFFfff3b2, 0xFFfff2b6, 0xFFfef5ae, 0xFFf4b659, 0xFFf9db93, 0xFFfeffcd, 0xFFfbf6c1, + 0xFFf7edb6, 0xFFfff2ac, 0xFF13a4f7, 0xFF16a5f0, 0xFF18a5e8, 0xFF56b4cd, 0xFFf1f271, 0xFFd5ef84, + 0xFFcfe67b, 0xFFcde77c, 0xFFcbe77c, 0xFFc9e672, 0xFFc7e567, 0xFFbce15f, 0xFFb1dd57, 0xFFa9dc51, + 0xFFa0da4b, 0xFF9dd749, 0xFF9ad447, 0xFF94cf43, 0xFF8fcb3f, 0xFF88c43c, 0xFF82be39, 0xFF72b430, + 0xFF63a928, 0xFF59a028, 0xFF4e9827, 0xFFa0c479, 0xFFfffbf7, 0xFF7fd3f5, 0xFF038fe2, 0xFF0e89e2, + 0xFF48c3ef, 0xFF46c2ef, 0xFF45c1f0, 0xFF43c0f0, 0xFF42bff0, 0xFF42beee, 0xFF43bdec, 0xFF41bcef, + 0xFF3fbcf2, 0xFF2fc0fe, 0xFF36bdfc, 0xFFf54c00, 0xFFff8a52, 0xFFfaa65e, 0xFFfdc48e, 0xFFfbc185, + 0xFFf5ae50, 0xFFf7b65e, 0xFFf9be6c, 0xFFfac978, 0xFFfbd485, 0xFFfede98, 0xFFffe8aa, 0xFFfdeeae, + 0xFFf9f5b2, 0xFFfcf6ba, 0xFFfff7c2, 0xFFfcf0b2, 0xFFf7cc6e, 0xFFfbde91, 0xFFfdfcca, 0xFFfffbd1, + 0xFFfffdc8, 0xFFcae4c8, 0xFF16a1f2, 0xFF1da4ef, 0xFF12a1f1, 0xFF9fd5b9, 0xFFeaf28c, 0xFFdcf095, + 0xFFd9eb90, 0xFFd9ec93, 0xFFd9ec95, 0xFFd6eb8c, 0xFFd4ea83, 0xFFc9e779, 0xFFbfe36f, 0xFFb8e368, + 0xFFb1e262, 0xFFafe05e, 0xFFaddf5a, 0xFFa3d952, 0xFF99d449, 0xFF8ecb41, 0xFF84c33a, 0xFF75b833, + 0xFF66ac2c, 0xFF5da329, 0xFF559927, 0xFF4b9421, 0xFF2499b9, 0xFF1593fe, 0xFF0993d8, 0xFF0f90d8, + 0xFF4ac5ef, 0xFF48c4f0, 0xFF46c2f0, 0xFF45c1f1, 0xFF43c0f1, 0xFF43bfef, 0xFF43bfed, 0xFF42beee, + 0xFF41bdf0, 0xFF38bbf0, 0xFF72a1b8, 0xFFff5d1e, 0xFFf97931, 0xFFf5a151, 0xFFf9ad61, 0xFFfee0bd, + 0xFFf8b758, 0xFFfabf69, 0xFFfcc87a, 0xFFfcd282, 0xFFfcdc8b, 0xFFfbde8f, 0xFFfbe193, 0xFFfbeba4, + 0xFFfbf5b5, 0xFFfaf8c2, 0xFFf9fcce, 0xFFf9ecb7, 0xFFfae183, 0xFFfee290, 0xFFfbfac8, 0xFFfdf8d8, + 0xFFfffccb, 0xFF8bcedc, 0xFF189fee, 0xFF25a3ee, 0xFF0b9dfb, 0xFFe8f6a5, 0xFFe4f1a6, 0xFFe4f0a6, + 0xFFe4efa6, 0xFFe5f1aa, 0xFFe6f2ad, 0xFFe3f1a6, 0xFFe0ef9e, 0xFFd7ec93, 0xFFcde987, 0xFFc8ea80, + 0xFFc2eb78, 0xFFc1ea73, 0xFFc0e96e, 0xFFb1e360, 0xFFa3dd53, 0xFF94d247, 0xFF86c83b, 0xFF78bc35, + 0xFF69b030, 0xFF62a52b, 0xFF5b9b27, 0xFF57920a, 0xFF0995fc, 0xFF0d96e5, 0xFF1091eb, 0xFF1091eb, + 0xFF4ac5f0, 0xFF49c4f0, 0xFF47c3f1, 0xFF45c2f1, 0xFF44c1f2, 0xFF41c1f2, 0xFF3fc1f2, 0xFF3fbff1, + 0xFF3fbcf0, 0xFF32c3fe, 0xFFbe7f6e, 0xFFfe6526, 0xFFf67b35, 0xFFf59a4d, 0xFFf8ab5c, 0xFFfbd0a0, + 0xFFf7c783, 0xFFfec16b, 0xFFfdd17f, 0xFFfbdb87, 0xFFf9e590, 0xFFf8ed9a, 0xFFf7f4a5, 0xFFfbea9a, + 0xFFffdf8e, 0xFFfce3a0, 0xFFf7e6b1, 0xFFfceecc, 0xFFfffbcb, 0xFFfff3c7, 0xFFfcf1c3, 0xFFfef5d2, + 0xFFfffcd3, 0xFF4bb5e7, 0xFF21a5ed, 0xFF1ca2ee, 0xFF3daae2, 0xFFeef6ac, 0xFFe6f2b1, 0xFFe8f2b5, + 0xFFe9f3b8, 0xFFeaf4ba, 0xFFebf5bc, 0xFFe8f3b6, 0xFFe6f2af, 0xFFe0f0a8, 0xFFdbeea2, 0xFFd6ef9a, + 0xFFd1f092, 0xFFc9ed82, 0xFFc1eb73, 0xFFb0e362, 0xFFa1dc51, 0xFF94d347, 0xFF88ca3e, 0xFF7bbf38, + 0xFF6eb433, 0xFF66a92e, 0xFF5da01b, 0xFF3d9448, 0xFF0a93f6, 0xFF0e94ec, 0xFF1193f0, 0xFF1193f0, + 0xFF4bc5f1, 0xFF4ac5f1, 0xFF48c4f1, 0xFF47c3f2, 0xFF45c3f2, 0xFF40c3f4, 0xFF3bc4f6, 0xFF3cbff3, + 0xFF3ebbf0, 0xFF2dcaff, 0xFFff5d25, 0xFFfe6d2f, 0xFFf37d39, 0xFFf59348, 0xFFf8a958, 0xFFf7c083, + 0xFFf7d7ae, 0xFFffc36d, 0xFFffda84, 0xFFfbe48c, 0xFFf7ee94, 0xFFf8ed9e, 0xFFfaeca7, 0xFFf9f1b4, + 0xFFf8f6c1, 0xFFfcf6c8, 0xFFfff6d0, 0xFFfef2d3, 0xFFfcf4ba, 0xFFfffee8, 0xFFf7fdea, 0xFFfdfde3, + 0xFFfffcdc, 0xFF0b9df1, 0xFF2aaaed, 0xFF1baaf6, 0xFF80c8da, 0xFFfdffbb, 0xFFe8f2bd, 0xFFebf4c4, + 0xFFeff7cb, 0xFFeff7cb, 0xFFeff7cb, 0xFFedf6c5, 0xFFebf5c0, 0xFFeaf4be, 0xFFe8f3bd, 0xFFe4f4b4, + 0xFFe0f6ab, 0xFFd0f191, 0xFFc1ec77, 0xFFb0e463, 0xFF9edb4e, 0xFF95d448, 0xFF8bcc42, 0xFF7fc23b, + 0xFF73b935, 0xFF6aac31, 0xFF60a510, 0xFF229687, 0xFF0b91f1, 0xFF0e93f3, 0xFF1294f5, 0xFF1294f5, + 0xFF4cc6f1, 0xFF4bc5f2, 0xFF49c5f2, 0xFF47c4f2, 0xFF46c4f2, 0xFF43c4f1, 0xFF40c4f0, 0xFF42c0f3, + 0xFF39c1f6, 0xFF5eacca, 0xFFfb591e, 0xFFf36e31, 0xFFf88135, 0xFFfb923f, 0xFFfbaf5e, 0xFFffc373, + 0xFFfde2ba, 0xFFffcd75, 0xFFffd372, 0xFFffe584, 0xFFfff796, 0xFFfef4a2, 0xFFfdf1ae, 0xFFfff8c2, + 0xFFfcf8cd, 0xFFfef8d2, 0xFFfff9d6, 0xFFfef6e1, 0xFFfcf5dd, 0xFFfffbee, 0xFFfbfce8, 0xFFfffce0, + 0xFFb2e0e8, 0xFF19a4f0, 0xFF26abec, 0xFF16a8f6, 0xFFc2e4d8, 0xFFf9fac5, 0xFFeff6cb, 0xFFf0f7ce, + 0xFFf1f8d2, 0xFFf1f8d1, 0xFFf2f9d1, 0xFFf1f9cd, 0xFFf1f9ca, 0xFFf2fbca, 0xFFf4fdca, 0xFFe7f8b6, + 0xFFdaf3a2, 0xFFcbef8a, 0xFFbcec71, 0xFFb0e661, 0xFFa5e151, 0xFF9ad949, 0xFF8fd240, 0xFF83c73b, + 0xFF77bc35, 0xFF6ab31d, 0xFF5ea905, 0xFF138dea, 0xFF1193ef, 0xFF1093f0, 0xFF0f93f0, 0xFF0f93f0, + 0xFF4dc6f2, 0xFF4cc6f2, 0xFF4ac5f3, 0xFF48c5f3, 0xFF47c5f3, 0xFF46c4ef, 0xFF46c4eb, 0xFF48c0f3, + 0xFF34c7fb, 0xFF989591, 0xFFfc6428, 0xFFf1773b, 0xFFfc8432, 0xFFff9135, 0xFFffb564, 0xFFffbe5a, + 0xFFf3ddb6, 0xFFccd097, 0xFFb4cea5, 0xFFb0d3b1, 0xFFabd7bd, 0xFFc3e1bf, 0xFFdaebc1, 0xFFf5fdc7, + 0xFFffffbd, 0xFFfffecd, 0xFFfffcdc, 0xFFfffce0, 0xFFfbfce5, 0xFFfdfbe6, 0xFFfffae7, 0xFFfffbdd, + 0xFF61c4f4, 0xFF26aaee, 0xFF22abec, 0xFF10a7f6, 0xFFffffd7, 0xFFf5f5d0, 0xFFf6fad9, 0xFFf4f9d9, + 0xFFf2f9da, 0xFFf3fad8, 0xFFf4fbd7, 0xFFf5fcd5, 0xFFf7fdd4, 0xFFf3face, 0xFFf0f7c8, 0xFFe2f4b0, + 0xFFd4f199, 0xFFc5ee82, 0xFFb7eb6b, 0xFFb1e95f, 0xFFabe754, 0xFF9fdf49, 0xFF94d83f, 0xFF87cc3a, + 0xFF7bc034, 0xFF6bb425, 0xFF5ba332, 0xFF0495f9, 0xFF1795ee, 0xFF1293ed, 0xFF0c91eb, 0xFF0c91eb, + 0xFF4fc8f3, 0xFF4dc8f3, 0xFF4cc8f4, 0xFF4bc8f4, 0xFF49c8f4, 0xFF47c5f2, 0xFF45c2ef, 0xFF42c2f8, + 0xFF34c8ff, 0xFFdf6746, 0xFFff632a, 0xFFff701b, 0xFFe18b53, 0xFFa4a185, 0xFF63c1cd, 0xFF26c0ff, + 0xFF2ab8ff, 0xFF25b5f1, 0xFF27b7f9, 0xFF26b5f6, 0xFF23b3f2, 0xFF24b5fa, 0xFF25b7ff, 0xFF189ddf, + 0xFF43bbf4, 0xFF9edae8, 0xFFf9f9dc, 0xFFf3fbe6, 0xFFffffea, 0xFFfdffe6, 0xFFfafce2, 0xFFffffff, + 0xFF1ea8ef, 0xFF1ca8f1, 0xFF1ba8f2, 0xFF5bc4f1, 0xFFffffe7, 0xFFfbf9e1, 0xFFfbfce3, 0xFFf8fbe0, + 0xFFf5fadd, 0xFFf5fbdb, 0xFFf5fbda, 0xFFf6fcd7, 0xFFf6fdd3, 0xFFf0f8c9, 0xFFebf4be, 0xFFdff2a9, + 0xFFd4f094, 0xFFc7f47b, 0xFFbaf862, 0xFFb0ef58, 0xFFa6e64e, 0xFFa3e248, 0xFF98d73a, 0xFF8acd38, + 0xFF7bc435, 0xFF70b821, 0xFF3b9c84, 0xFF0d93f4, 0xFF1394ed, 0xFF1193e9, 0xFF0f92e6, 0xFF0f92e6, + 0xFF50c9f4, 0xFF4fcaf4, 0xFF4ecaf5, 0xFF4dcaf5, 0xFF4ccaf6, 0xFF48c5f4, 0xFF45c0f3, 0xFF47c2ef, + 0xFF4ac4eb, 0xFFff521f, 0xFFa79a92, 0xFF51b7e6, 0xFF28c7ff, 0xFF2cc4f9, 0xFF31c1f1, 0xFF3fbbf0, + 0xFF37c0ef, 0xFF39b9f0, 0xFF3bb3f1, 0xFF38b5f4, 0xFF36b7f7, 0xFF32b9f0, 0xFF2fbbe8, 0xFF2fb8eb, + 0xFF2fb5ed, 0xFF20acf3, 0xFF10a3fa, 0xFF70c9f3, 0xFFf5f9df, 0xFFf6fbde, 0xFFf6fdde, 0xFFd8ebe4, + 0xFF11a5ee, 0xFF2db2f5, 0xFF14a5f8, 0xFFa5e2ec, 0xFFfffff8, 0xFFfffef3, 0xFFfffded, 0xFFfcfde6, + 0xFFf8fce0, 0xFFf7fcde, 0xFFf6fcdd, 0xFFf6fcd8, 0xFFf5fdd3, 0xFFedf7c4, 0xFFe5f1b4, 0xFFe5f5b8, + 0xFFe4f9bb, 0xFFecfed2, 0xFFf3ffe9, 0xFFedfedb, 0xFFe8f9cd, 0xFFcaef89, 0xFF9cd636, 0xFF84c72e, + 0xFF6bb826, 0xFF6cb315, 0xFF1a95d6, 0xFF1591ef, 0xFF1093eb, 0xFF1193e6, 0xFF1294e1, 0xFF1294e1, + 0xFF52cbf4, 0xFF50caf4, 0xFF4ecaf4, 0xFF4ccaf3, 0xFF4ac9f3, 0xFF48c8f5, 0xFF46c7f6, 0xFF40bfed, + 0xFF41bfeb, 0xFF41d4f9, 0xFF33c9fc, 0xFF2fc9ff, 0xFF42c3ec, 0xFF40c3f4, 0xFF3ec3fc, 0xFF35bbf4, + 0xFF33bbf3, 0xFF49bdf7, 0xFF39b7f9, 0xFF37b7f6, 0xFF35b7f2, 0xFF2eb5f4, 0xFF28b3f5, 0xFF2fbbf8, + 0xFF2fbaf2, 0xFF30b5f2, 0xFF31b0f1, 0xFF1facf6, 0xFF0dabed, 0xFF7fd2ed, 0xFFffffe6, 0xFF80d9d2, + 0xFF2faaf8, 0xFF1dafec, 0xFF03aae6, 0xFFfff8ff, 0xFFfffffe, 0xFFfffff9, 0xFFfffdf4, 0xFFfdfeeb, + 0xFFfbfee3, 0xFFf9fde1, 0xFFf7fce0, 0xFFf5fdd8, 0xFFf4fdcf, 0xFFf5fce2, 0xFFf6fde8, 0xFFf3fde8, + 0xFFf1fde9, 0xFFebfdd3, 0xFFe6fdbe, 0xFFe0f8ba, 0xFFdaf2b7, 0xFFeafcd2, 0xFFf2fde6, 0xFFb7de8d, + 0xFF84c73d, 0xFF9ab848, 0xFF14a1f9, 0xFF0494f3, 0xFF1094ef, 0xFF1095ec, 0xFF1095e9, 0xFF1095e9, + 0xFF54ccf5, 0xFF51cbf4, 0xFF4ecaf3, 0xFF4cc9f2, 0xFF49c8f1, 0xFF48cbf5, 0xFF48cef9, 0xFF40c4f3, + 0xFF49cafc, 0xFF40c2f1, 0xFF47caf5, 0xFF46c7f4, 0xFF46c4f3, 0xFF39b5ee, 0xFF2ca5e8, 0xFF2eb1e1, + 0xFF56c1ea, 0xFF6dc9e9, 0xFF37c2e5, 0xFF51caeb, 0xFF6bd2f1, 0xFF74d1f5, 0xFF7dcff9, 0xFF56c7f8, + 0xFF1fafe8, 0xFF25b1ee, 0xFF2cb3f4, 0xFF3eb5f9, 0xFF2bb3ee, 0xFF1baff5, 0xFF32b5f0, 0xFF3fb2f9, + 0xFF26a9f2, 0xFF1faeeb, 0xFF3fb8f4, 0xFFfcfff3, 0xFFffffff, 0xFFffffff, 0xFFfffefb, 0xFFfefff1, + 0xFFfeffe6, 0xFFfbffe5, 0xFFf8fde3, 0xFFf5fdd7, 0xFFf3fecb, 0xFFf5fbeb, 0xFFf7feee, 0xFFf2fdde, + 0xFFedfccf, 0xFFe3f9b0, 0xFFd9f692, 0xFFd2f48b, 0xFFccf184, 0xFFceee97, 0xFFd0eaa9, 0xFFdaebc1, + 0xFFf4fbe9, 0xFF7fc679, 0xFF5ac1ff, 0xFF1aa1eb, 0xFF1195f2, 0xFF0f96f2, 0xFF0e97f2, 0xFF0e97f2, + 0xFF54cdf5, 0xFF52ccf4, 0xFF4fcbf3, 0xFF4dc9f3, 0xFF4ac8f2, 0xFF49c6f2, 0xFF47c4f2, 0xFF49d2f3, + 0xFF46c8f3, 0xFF4dc5fc, 0xFF2c9add, 0xFF1883cd, 0xFF046cbe, 0xFF0080c5, 0xFF0f96d4, 0xFF2eaddb, + 0xFF60c6eb, 0xFF76cdef, 0xFF51caea, 0xFF69d2f0, 0xFF81daf5, 0xFF9ae4f7, 0xFFb3eff9, 0xFFcffaff, + 0xFFe3feff, 0xFF9ae1ff, 0xFF48bcf7, 0xFF11b5dd, 0xFF32aef0, 0xFF28acfc, 0xFF31b2f3, 0xFF34b1f6, + 0xFF25adf0, 0xFF26acf6, 0xFF98d1fc, 0xFFfffdf8, 0xFFffffff, 0xFFfffffb, 0xFFfefff4, 0xFFfdffee, + 0xFFfcfde7, 0xFFfbfee4, 0xFFfaffe0, 0xFFf8fde7, 0xFFf7fcef, 0xFFf3fbeb, 0xFFeffdd9, 0xFFe9fbc2, + 0xFFe3f9ac, 0xFFd9f49b, 0xFFceef8b, 0xFFc1ea76, 0xFFb4e562, 0xFFabdd5a, 0xFFa2d261, 0xFFc1e98e, + 0xFFdbe8b9, 0xFF96d4ff, 0xFF8ed0fa, 0xFF42aeee, 0xFF1095f1, 0xFF1096f1, 0xFF0f96f1, 0xFF0f96f1, + 0xFF55cef5, 0xFF53ccf4, 0xFF50cbf4, 0xFF4ecaf4, 0xFF4cc8f4, 0xFF51caf7, 0xFF57cbfa, 0xFF45c0ea, + 0xFF1a75c7, 0xFF0058ad, 0xFF015bb4, 0xFF066fc0, 0xFF0b84cd, 0xFF0093ce, 0xFF11a7e0, 0xFF3eb9e6, + 0xFF6bcbeb, 0xFF7ed1f6, 0xFF6cd3f0, 0xFF82dbf4, 0xFF98e3f9, 0xFFa5ecf7, 0xFFb2f4f5, 0xFFc7f7f9, + 0xFFddfafd, 0xFFf2ffff, 0xFFf8fff6, 0xFFbcebfe, 0xFF22b4f2, 0xFF29afff, 0xFF2fb0f7, 0xFF29b1f2, + 0xFF23b1ee, 0xFF1aa7fa, 0xFFcae6f4, 0xFFf7f8f4, 0xFFfeffff, 0xFFfefff7, 0xFFfeffed, 0xFFfcffeb, + 0xFFfbfae9, 0xFFfbfee3, 0xFFfbffdc, 0xFFfbffe9, 0xFFfbfff7, 0xFFf1fedd, 0xFFe7fbc3, 0xFFe0f6b4, + 0xFFd8f0a5, 0xFFceec94, 0xFFc4e884, 0xFFb8e678, 0xFFace36c, 0xFFa0df53, 0xFF94d455, 0xFF80bd41, + 0xFFd2e599, 0xFF2ca1f4, 0xFF30a2f6, 0xFF209cf3, 0xFF1096f1, 0xFF1096f1, 0xFF1096f1, 0xFF1096f1, + 0xFF55cef4, 0xFF53cdf4, 0xFF51cbf5, 0xFF50cbf5, 0xFF4ecaf6, 0xFF4dc9f4, 0xFF54d0fa, 0xFF2b86ce, + 0xFF0752b1, 0xFF045fb9, 0xFF0a74c9, 0xFF0882ce, 0xFF0691d4, 0xFF02a0d5, 0xFF24b5e7, 0xFF4cc4ea, + 0xFF74d3ee, 0xFF83d9f5, 0xFF7fddf4, 0xFF93e4f6, 0xFFa8ecf9, 0xFFb6f2f9, 0xFFc3f9f9, 0xFFd3fafb, + 0xFFe3fcfc, 0xFFedfefb, 0xFFf0f9f3, 0xFFffffff, 0xFFfffdff, 0xFF7edcef, 0xFF26adfd, 0xFF2aaff7, + 0xFF2db2f2, 0xFF34b1e0, 0xFF09a7f7, 0xFF8dd3f5, 0xFFfdfbf9, 0xFFfffff6, 0xFFfdffeb, 0xFFfcffe6, + 0xFFfcfce0, 0xFFf9fcde, 0xFFf7fcdd, 0xFFfcffef, 0xFFf9fdec, 0xFFe8f5d0, 0xFFdff5bd, 0xFFd9f1ad, + 0xFFd2ed9d, 0xFFc5e97e, 0xFFb8e26d, 0xFFabdd5e, 0xFF9fd74f, 0xFF98c95f, 0xFF92c735, 0xFF8bc942, + 0xFF80b34d, 0xFF009bf2, 0xFF1894f8, 0xFF1595f5, 0xFF1397f2, 0xFF1296f1, 0xFF1195f0, 0xFF1195f0, + 0xFF56cff4, 0xFF54cdf5, 0xFF52ccf5, 0xFF51cbf7, 0xFF51cbf9, 0xFF49c8f1, 0xFF51d5fa, 0xFF1662c1, + 0xFF005cbb, 0xFF0874cd, 0xFF037cce, 0xFF028dd4, 0xFF019edb, 0xFF09aedc, 0xFF37c2ee, 0xFF5acfef, + 0xFF7edcf0, 0xFF88e1f4, 0xFF92e6f8, 0xFFa5eef8, 0xFFb9f5f9, 0xFFc7f9fb, 0xFFd5fdfe, 0xFFdffdfc, + 0xFFe9fdfa, 0xFFf0fefe, 0xFFf8ffff, 0xFFfafffe, 0xFFfdfffc, 0xFFfdfbff, 0xFF1db0e8, 0xFF2ab1ee, + 0xFF37b2f5, 0xFF25b9f7, 0xFF29b4f8, 0xFF22aff5, 0xFF1baaf2, 0xFF9fd7f6, 0xFFfdffea, 0xFFfcfee0, + 0xFFfcfdd7, 0xFFf8fada, 0xFFf4f7dd, 0xFFfdfef5, 0xFFf6fae1, 0xFFdfecc3, 0xFFd8efb6, 0xFFd2eca6, + 0xFFccea95, 0xFFbce567, 0xFFabdb56, 0xFF9fd344, 0xFF92cb33, 0xFF85c824, 0xFF79b46a, 0xFF3a9eaf, + 0xFF0c97ff, 0xFF1994f9, 0xFF0f9bee, 0xFF139af0, 0xFF1699f3, 0xFF1497f1, 0xFF1295ef, 0xFF1295ef, + 0xFF58d0f5, 0xFF56cef5, 0xFF53cdf4, 0xFF53ccf6, 0xFF52cbf8, 0xFF53d6fb, 0xFF4fc8fc, 0xFF004cad, + 0xFF096fca, 0xFF0b80d4, 0xFF0588d5, 0xFF0598db, 0xFF05a8e1, 0xFF18b6e6, 0xFF3fc8f2, 0xFF63d3f3, + 0xFF86dff5, 0xFF91e4f7, 0xFF9ce9fa, 0xFFaef0f9, 0xFFc0f7f9, 0xFFcbfafb, 0xFFd7fdfd, 0xFFdefdfc, + 0xFFe6fefb, 0xFFf0fffe, 0xFFfaffff, 0xFFf2fefb, 0xFFfefffd, 0xFFc6e9fb, 0xFF1eb0ec, 0xFF30b4f6, + 0xFF30b7f8, 0xFF19a8f7, 0xFF26b0f0, 0xFF22aef3, 0xFF1eabf5, 0xFF27aafa, 0xFF1ca6f6, 0xFF7dcdea, + 0xFFdff4dd, 0xFFeaffb0, 0xFFfdfeed, 0xFFffffef, 0xFFfcf9d3, 0xFFedeeb4, 0xFFe6e9ac, 0xFFd9e68a, + 0xFFcbe367, 0xFFb9e153, 0xFFa6dd4d, 0xFF75c57f, 0xFF43adb0, 0xFF229bf3, 0xFF0a9cff, 0xFF0998f6, + 0xFF109cef, 0xFF189aee, 0xFF149ded, 0xFF159bf0, 0xFF1599f2, 0xFF1397f0, 0xFF1195ee, 0xFF1195ee, + 0xFF5ad1f6, 0xFF57cff5, 0xFF54cef4, 0xFF54cdf6, 0xFF53cbf8, 0xFF4dd3f4, 0xFF2c9add, 0xFF045ec1, + 0xFF0572c9, 0xFF0683d2, 0xFF0794dc, 0xFF08a2e2, 0xFF08b1e8, 0xFF28bfef, 0xFF48cef6, 0xFF6bd8f8, + 0xFF8fe3fa, 0xFF9be8fa, 0xFFa6edfb, 0xFFb7f3fb, 0xFFc7f9fa, 0xFFd0fbfc, 0xFFd9fdfd, 0xFFdefefd, + 0xFFe2fffc, 0xFFeffffe, 0xFFfcffff, 0xFFebfef7, 0xFFfffffe, 0xFF8fd7f8, 0xFF1eb0f1, 0xFF2eb0f6, + 0xFF18abec, 0xFFe0f7fd, 0xFF24ade9, 0xFF23acf1, 0xFF21acf8, 0xFF26aef7, 0xFF2cb0f6, 0xFF1aa9f5, + 0xFF08a3f4, 0xFF22a7f9, 0xFF4cc2f2, 0xFF6dcdef, 0xFF7ec9db, 0xFF7fcac2, 0xFF81c6c6, 0xFF61bccb, + 0xFF41b3d0, 0xFF24a7e9, 0xFF089bff, 0xFF119dff, 0xFF1a9fff, 0xFF0f99e9, 0xFF149cf9, 0xFF159cf7, + 0xFF159cf5, 0xFF179df1, 0xFF199eed, 0xFF179cef, 0xFF1599f1, 0xFF1397ef, 0xFF1195ed, 0xFF1195ed, + 0xFF5cd2f6, 0xFF59d0f5, 0xFF55cff3, 0xFF54cdf5, 0xFF53ccf8, 0xFF51d5f6, 0xFF167bcf, 0xFF0467c6, + 0xFF067bcf, 0xFF068bd7, 0xFF059cdf, 0xFF08a9e5, 0xFF0ab6eb, 0xFF2bc4f1, 0xFF4cd2f7, 0xFF6ddbf9, + 0xFF8ee5fa, 0xFF9deafb, 0xFFaceffb, 0xFFbdf5fb, 0xFFcefbfa, 0xFFd5fbfc, 0xFFdcfcfd, 0xFFdcfefd, + 0xFFddfffd, 0xFFe4fffd, 0xFFeafffd, 0xFFfffffe, 0xFFffffff, 0xFF27c0de, 0xFF26b5f6, 0xFF1fb0f9, + 0xFF4dc6ff, 0xFFfff9ef, 0xFFfefffa, 0xFF8bd8f7, 0xFF18a7f3, 0xFF1daaf4, 0xFF23acf6, 0xFF22acf3, + 0xFF22abf0, 0xFF1aa3f2, 0xFF1aa6ee, 0xFF18a8f5, 0xFF0ea2f3, 0xFF11a4f2, 0xFF14a4ff, 0xFF15a3fc, + 0xFF16a3fa, 0xFF17a2f3, 0xFF19a2ec, 0xFF0e99fe, 0xFF169bed, 0xFF00a1ff, 0xFF2b9de8, 0xFF61b5b0, + 0xFF109af7, 0xFF149cf2, 0xFF189eed, 0xFF169cef, 0xFF149af0, 0xFF1298ee, 0xFF1096ec, 0xFF1096ec, + 0xFF5fd3f7, 0xFF5bd2f5, 0xFF56d0f3, 0xFF55cef5, 0xFF53cdf7, 0xFF56d8f8, 0xFF005cc0, 0xFF0370cb, + 0xFF0785d6, 0xFF0594dc, 0xFF04a3e2, 0xFF08afe8, 0xFF0cbcee, 0xFF2ec8f3, 0xFF50d5f9, 0xFF6fdefa, + 0xFF8de7fb, 0xFF9fecfb, 0xFFb1f2fb, 0xFFc3f7fb, 0xFFd4fcfa, 0xFFd9fcfc, 0xFFdefcfd, 0xFFdbfdfd, + 0xFFd9fffd, 0xFFd9fdfb, 0xFFd9fcfa, 0xFFe5fafa, 0xFFa4eaf7, 0xFF2badfb, 0xFF2fb9fa, 0xFF1aaeed, + 0xFF99dbf8, 0xFFffffff, 0xFFfefdfc, 0xFFfffefd, 0xFFfffffd, 0xFF8cd4fa, 0xFF19a9f6, 0xFF18a9f7, + 0xFF16aaf9, 0xFF1aa7f3, 0xFF1ea5ee, 0xFF1fa7f2, 0xFF21a9f6, 0xFF1ea7f7, 0xFF1ba5f7, 0xFF17a4f9, + 0xFF12a2fb, 0xFF0b9dfd, 0xFF0399fe, 0xFF26a2fa, 0xFF6fc0b0, 0xFFcfca5e, 0xFFffe528, 0xFF74b4b3, + 0xFF0b98fa, 0xFF119af4, 0xFF179dee, 0xFF159cee, 0xFF139aef, 0xFF1198ed, 0xFF0f96eb, 0xFF0f96eb, + 0xFF5dd1f6, 0xFF5bd2f5, 0xFF58d2f4, 0xFF53cef4, 0xFF56d2fb, 0xFF40b2e6, 0xFF0164c6, 0xFF0376cf, + 0xFF0487d7, 0xFF0296dd, 0xFF01a4e4, 0xFF04b1ea, 0xFF07bdf1, 0xFF1bc8f2, 0xFF43d5fc, 0xFF64ddfb, + 0xFF85e6fb, 0xFF98ebfc, 0xFFacf1fd, 0xFFbef9ff, 0xFFcfffff, 0xFFcffdff, 0xFFcff9fb, 0xFFd2fefe, + 0xFFd5ffff, 0xFFc6f9ff, 0xFFb8efff, 0xFF5ad7d9, 0xFF40b9e9, 0xFF2fb9ff, 0xFF2bb2f0, 0xFF28afeb, + 0xFFdef0f2, 0xFFffffff, 0xFFfeffff, 0xFFfffefe, 0xFFfffefa, 0xFFfffffa, 0xFFfffff9, 0xFFc2e8f0, + 0xFF84cde7, 0xFF53bbe9, 0xFF22a9eb, 0xFF14a1ff, 0xFF069ff8, 0xFF0fa0f8, 0xFF19a3eb, 0xFF43b1e1, + 0xFF6ec2c9, 0xFFb0d79a, 0xFFf2eb6b, 0xFFebee32, 0xFFf8e647, 0xFFffe23a, 0xFFfde142, 0xFF0098f4, + 0xFF19a1fc, 0xFF169ef7, 0xFF129bf1, 0xFF139af1, 0xFF149af0, 0xFF1298ee, 0xFF1096ec, 0xFF1096ec, + 0xFF5ccff6, 0xFF5bd2f6, 0xFF5ad4f6, 0xFF52cdf2, 0xFF5ad6fe, 0xFF298cd5, 0xFF026ccc, 0xFF027bd2, + 0xFF0189d8, 0xFF0097df, 0xFF00a6e6, 0xFF00b2ed, 0xFF02bef4, 0xFF09c7f1, 0xFF35d5ff, 0xFF59ddfd, + 0xFF7ce5fb, 0xFF91eafd, 0xFFa6f0ff, 0xFFb1f2ff, 0xFFbbf5ff, 0xFFbef5fc, 0xFFc1f6f9, 0xFFc1f7f7, + 0xFFc1f9f4, 0xFFc7fdfc, 0xFFcdffff, 0xFFc2f9f8, 0xFF5acdf4, 0xFF39b1f3, 0xFF38baf5, 0xFF2ab4f7, + 0xFFfcfbf8, 0xFFfdfeff, 0xFFfeffff, 0xFFfffeff, 0xFFfffcf6, 0xFFfdfef2, 0xFFf7ffee, 0xFFfcffea, + 0xFFffffe5, 0xFFffffd8, 0xFFffffcb, 0xFFfffbf1, 0xFFffffdf, 0xFFfdfdc2, 0xFFf7ff88, 0xFFfbfe92, + 0xFFffff7f, 0xFFfdfc6c, 0xFFfaf759, 0xFFf8f059, 0xFFf7e958, 0xFFf7e359, 0xFFd0d368, 0xFF0998ff, + 0xFF189aef, 0xFF129af2, 0xFF0c99f5, 0xFF1199f3, 0xFF1599f2, 0xFF1397f0, 0xFF1195ee, 0xFF1195ee, + 0xFF5fd2f9, 0xFF5cd3f8, 0xFF59d4f6, 0xFF58d3f8, 0xFF5edaff, 0xFF1971cd, 0xFF026ecd, 0xFF037bd3, + 0xFF0488d9, 0xFF0497e0, 0xFF05a6e6, 0xFF01ade7, 0xFF00b5e8, 0xFF07beea, 0xFF23cbf5, 0xFF4cd7f8, + 0xFF74e4fc, 0xFF89e8fd, 0xFF9fecfe, 0xFFa5edfe, 0xFFabeffe, 0xFFaeeffc, 0xFFb0eff9, 0xFFb3f3f9, + 0xFFb6f6f8, 0xFFb6f9fc, 0xFFb5fcff, 0xFFdaf3ff, 0xFF1ab9f1, 0xFF28b3f4, 0xFF2bb3f6, 0xFF73cef4, + 0xFFfdfdf5, 0xFFfdfefa, 0xFFfdfffe, 0xFFfffef9, 0xFFfffdf3, 0xFFfdfeee, 0xFFfaffe9, 0xFFfdffe4, + 0xFFffffde, 0xFFffffd0, 0xFFffffc2, 0xFFfdfad7, 0xFFfffcf3, 0xFFffffc0, 0xFFfcfbc5, 0xFFfcff84, + 0xFFfcfb8b, 0xFFfbf67a, 0xFFf9f269, 0xFFf7ed5e, 0xFFf4e954, 0xFFf7e948, 0xFF87bda9, 0xFF109afc, + 0xFF179cf2, 0xFF149bf1, 0xFF119af1, 0xFF1399f2, 0xFF1698f3, 0xFF1496f1, 0xFF1294ef, 0xFF1294ef, + 0xFF62d4fc, 0xFF5dd4f9, 0xFF59d4f6, 0xFF56d1f6, 0xFF53cef5, 0xFF014ebe, 0xFF026fcd, 0xFF057bd4, + 0xFF0787da, 0xFF0996e0, 0xFF0ca5e7, 0xFF0bb0e9, 0xFF09bbeb, 0xFF15c5f3, 0xFF21d0fc, 0xFF46dafc, + 0xFF6ce3fc, 0xFF82e6fd, 0xFF97e9fe, 0xFF99e9fe, 0xFF9ce8fe, 0xFF9ee9fb, 0xFFa0e9f9, 0xFFa6eefa, + 0xFFacf3fc, 0xFFb0effc, 0xFFb5ecfb, 0xFF89ddf9, 0xFF28b4f3, 0xFF3ebef7, 0xFF1eadf7, 0xFFbde8f0, + 0xFFfefff2, 0xFFfefff3, 0xFFfdfff4, 0xFFfefef2, 0xFFfefef0, 0xFFfefeea, 0xFFfefee4, 0xFFfefede, + 0xFFfefed8, 0xFFfcffc9, 0xFFfbffba, 0xFFf6fea0, 0xFFffffce, 0xFFfff9f6, 0xFFffffc9, 0xFFfdf7be, + 0xFFf8f87a, 0xFFf9f66b, 0xFFf9f35c, 0xFFf5ee56, 0xFFf1e84f, 0xFFf8ee37, 0xFF3fa7ea, 0xFF189df5, + 0xFF179df4, 0xFF169cf1, 0xFF159bee, 0xFF169af2, 0xFF1798f5, 0xFF1596f3, 0xFF1394f1, 0xFF1394f1, + 0xFF66d7fc, 0xFF5fd1f5, 0xFF60d4f6, 0xFF59d8f9, 0xFF399ddb, 0xFF0858be, 0xFF096ccd, 0xFF0c7ad2, + 0xFF1087d7, 0xFF1296df, 0xFF13a6e8, 0xFF13b0eb, 0xFF1bc3f5, 0xFF0fc8f3, 0xFF17d0f9, 0xFF27d3f4, + 0xFF4bd7f7, 0xFF61dbf8, 0xFF77def9, 0xFF7fe0fa, 0xFF88e1fa, 0xFF8de4fb, 0xFF91e7fb, 0xFF96eafc, + 0xFF9aedfd, 0xFF9feafb, 0xFFa3e7fa, 0xFF5eccfb, 0xFF2db7f5, 0xFF24b8f9, 0xFF14b1f5, 0xFFfffbff, + 0xFFfeffec, 0xFFffffed, 0xFFffffee, 0xFFffffec, 0xFFfefdeb, 0xFFfefde4, 0xFFfefddd, 0xFFfefed6, + 0xFFfefece, 0xFFfcfdc1, 0xFFfcfcb5, 0xFFf6fb8d, 0xFFf8fc8a, 0xFFf8facc, 0xFFf8fef2, 0xFFf9ffbe, + 0xFFfbf9c2, 0xFFfbf8ac, 0xFFfcf796, 0xFFfaf491, 0xFFf7f18d, 0xFFffe5a9, 0xFF0096f7, 0xFF089af7, + 0xFF159ef7, 0xFF169df4, 0xFF169cf0, 0xFF169bf2, 0xFF1699f4, 0xFF1497f3, 0xFF1396f1, 0xFF1396f1, + 0xFF6bd9fb, 0xFF61cef1, 0xFF67d3f7, 0xFF5cdefd, 0xFF1f6cc0, 0xFF0f63bf, 0xFF0f6acd, 0xFF1478d1, + 0xFF1887d4, 0xFF1997df, 0xFF1aa6e9, 0xFF14a9e4, 0xFF1dbbef, 0xFF0dbeeb, 0xFF23c5f6, 0xFF13c6ed, + 0xFF2acbf3, 0xFF40cff4, 0xFF56d4f4, 0xFF65d7f6, 0xFF74daf7, 0xFF7bdffb, 0xFF83e5fe, 0xFF86e6fe, + 0xFF89e8fd, 0xFF8ee5fb, 0xFF92e2fa, 0xFF33bcfc, 0xFF32b9f7, 0xFF31bafd, 0xFF57c5f7, 0xFFf4ffde, + 0xFFfdffe7, 0xFFffffe7, 0xFFffffe7, 0xFFffffe6, 0xFFfdfce6, 0xFFfdfddd, 0xFFfdfdd5, 0xFFfdfdcd, + 0xFFfefdc5, 0xFFfdfaba, 0xFFfcf8af, 0xFFfef99f, 0xFFfffb8e, 0xFFfafe77, 0xFFf4fb7d, 0xFFf9f8d2, + 0xFFfdffee, 0xFFfefedf, 0xFFfffcd0, 0xFFfefacd, 0xFFfdf9ca, 0xFFa6d3ce, 0xFF0399eb, 0xFF1ea1ec, + 0xFF149ffa, 0xFF159ef6, 0xFF179ef2, 0xFF169cf3, 0xFF159af3, 0xFF1499f2, 0xFF1398f1, 0xFF1398f1, + 0xFF55d4f4, 0xFF5bd1f1, 0xFF69d6f6, 0xFF6ee2ff, 0xFF0c50a8, 0xFF1161be, 0xFF0f6acd, 0xFF1f83d6, + 0xFF1f89dc, 0xFF0f8cdd, 0xFF1a9be0, 0xFF22b1f4, 0xFF1dabe1, 0xFF14aedf, 0xFF26bdee, 0xFF15bae7, + 0xFF1fc1ef, 0xFF25c7ef, 0xFF2bcdef, 0xFF3dcdf1, 0xFF4ecef3, 0xFF5bd6f9, 0xFF68defe, 0xFF6eddfc, + 0xFF73ddfb, 0xFF76ddf5, 0xFF70d3f7, 0xFF31bafb, 0xFF33b9f6, 0xFF24b6ff, 0xFFa4dee5, 0xFFf9ffdc, + 0xFFfdfedc, 0xFFffffdc, 0xFFffffdc, 0xFFfefedb, 0xFFfcfdda, 0xFFfdfdd2, 0xFFfdfdcb, 0xFFfdfdc3, + 0xFFfefdbc, 0xFFfdfbaf, 0xFFfcfaa2, 0xFFfdfb93, 0xFFfefb83, 0xFFfcfd6b, 0xFFf9fc60, 0xFFfbf85d, + 0xFFfdf74c, 0xFFfef576, 0xFFfff2a1, 0xFFf6ec87, 0xFFf8e360, 0xFF51bbb4, 0xFF0d9afe, 0xFF1a9ef7, + 0xFF159ef6, 0xFF159df4, 0xFF159df2, 0xFF149bf2, 0xFF1299f2, 0xFF1299f2, 0xFF1299f2, 0xFF1299f2, + 0xFF67d4fd, 0xFF69d6f9, 0xFF6cd9f5, 0xFF4fb7dc, 0xFF1953af, 0xFF1c67c6, 0xFF005abd, 0xFF1a7eca, + 0xFF157bd4, 0xFF0581dc, 0xFF2aa1e7, 0xFF0189d3, 0xFF2dabe3, 0xFF23a7dc, 0xFF29b4e6, 0xFF17ade1, + 0xFF14b7ec, 0xFF15b9ea, 0xFF16bbe9, 0xFF1fbfec, 0xFF28c2ef, 0xFF3bcdf7, 0xFF4ed8ff, 0xFF56d5fb, + 0xFF5dd2f8, 0xFF5ed6f0, 0xFF4ec5f4, 0xFF2fb9fa, 0xFF35b8f4, 0xFF17b1ff, 0xFFf0f7d2, 0xFFfeffda, + 0xFFfdfcd2, 0xFFfdfdd1, 0xFFfdfed1, 0xFFfdfecf, 0xFFfcfecd, 0xFFfcfdc7, 0xFFfdfdc0, 0xFFfdfdb9, + 0xFFfdfdb2, 0xFFfdfca4, 0xFFfdfc95, 0xFFfdfc87, 0xFFfdfc79, 0xFFfdfa6c, 0xFFfef85f, 0xFFf9f645, + 0xFFf6ef47, 0xFFf2e938, 0xFFefe428, 0xFFeee425, 0xFFffdd05, 0xFF0399ff, 0xFF17a1f5, 0xFF179ef4, + 0xFF169cf3, 0xFF159cf3, 0xFF149cf3, 0xFF129bf1, 0xFF1099f0, 0xFF119af1, 0xFF129bf2, 0xFF129bf2, + 0xFF66d5fb, 0xFF70d5fc, 0xFF78e2ff, 0xFF3b86c7, 0xFF235fba, 0xFF1e6aba, 0xFF227ad1, 0xFF2787d8, + 0xFF248cd7, 0xFF1d8dd4, 0xFF2189d1, 0xFF2ca1ea, 0xFF2296d5, 0xFF31aaef, 0xFF20a1db, 0xFF17a1dd, + 0xFF0ea1e0, 0xFF1aace3, 0xFF13b1eb, 0xFF10b8ed, 0xFF0dc0ef, 0xFF1cc1ef, 0xFF2cc3f0, 0xFF36c4f2, + 0xFF40c5f4, 0xFF47c9f2, 0xFF45c3f6, 0xFF31bafa, 0xFF31b7f7, 0xFF4cc2f4, 0xFFf5fac0, 0xFFfdffc6, + 0xFFfdfcc5, 0xFFfdfdc4, 0xFFfdfdc4, 0xFFfcfdc2, 0xFFfbfdc1, 0xFFf8f9b6, 0xFFfdfdb3, 0xFFfdfdab, + 0xFFfdfca3, 0xFFfcfc95, 0xFFfcfb88, 0xFFfcfb7b, 0xFFfbfb6d, 0xFFfcf962, 0xFFfcf757, 0xFFf8f245, + 0xFFf4eb41, 0xFFf0e532, 0xFFebe023, 0xFFfbe01c, 0xFFc5d244, 0xFF0aa2fe, 0xFF169ff9, 0xFF179ff6, + 0xFF189ff3, 0xFF179ef2, 0xFF159df2, 0xFF179ff5, 0xFF18a1f8, 0xFF159ef5, 0xFF129bf2, 0xFF129bf2, + 0xFF65d7fa, 0xFF64d1f7, 0xFF5de7ff, 0xFF04439b, 0xFF0e4ca5, 0xFF317bcd, 0xFF0455c1, 0xFF0053c9, + 0xFF0368c6, 0xFF2687ca, 0xFF2881ca, 0xFF2789d1, 0xFF2791d7, 0xFF0774c9, 0xFF178dcf, 0xFF1f9ce1, + 0xFF179be4, 0xFF1e9eda, 0xFF0097de, 0xFF03a5e6, 0xFF08b1ee, 0xFF09b0e8, 0xFF0aafe2, 0xFF17b4e9, + 0xFF24b9ef, 0xFF30bdf4, 0xFF3cc1f9, 0xFF34bcf9, 0xFF2cb6f9, 0xFF80d2e8, 0xFFfafdaf, 0xFFfcfdb3, + 0xFFfdfcb7, 0xFFfdfcb7, 0xFFfdfdb7, 0xFFfcfcb6, 0xFFfbfcb5, 0xFFf4f4a5, 0xFFfdfda5, 0xFFfcfc9d, + 0xFFfcfc94, 0xFFfbfb87, 0xFFfbfb7b, 0xFFfafa6e, 0xFFfafa61, 0xFFfaf758, 0xFFfaf54e, 0xFFf7ee44, + 0xFFf3e73a, 0xFFede12c, 0xFFe7db1e, 0xFFffd21a, 0xFF78b090, 0xFF09a0fd, 0xFF159dfd, 0xFF18a0f8, + 0xFF1aa2f2, 0xFF18a0f2, 0xFF169ef2, 0xFF139bf2, 0xFF1099f1, 0xFF119af2, 0xFF129bf3, 0xFF129bf3, + 0xFF60d4f7, 0xFF67dcfd, 0xFF4fc2f0, 0xFF002c8a, 0xFF2e6bc0, 0xFF0547ad, 0xFF0044ba, 0xFF3685c4, + 0xFF064ebc, 0xFF1462c3, 0xFF2d70cb, 0xFF0f5ab4, 0xFF2274cd, 0xFF1169c2, 0xFF1979c2, 0xFF1d80d0, + 0xFF1980d7, 0xFF1a86d3, 0xFF1090de, 0xFF038dda, 0xFF0599e6, 0xFF059ce1, 0xFF049edd, 0xFF05a6e1, + 0xFF00a7de, 0xFF1fb6ee, 0xFF39bdf7, 0xFF38bcf6, 0xFF24b5fc, 0xFFbfe8b9, 0xFFfafea2, 0xFFfbfca5, + 0xFFfcfaa8, 0xFFfcfca7, 0xFFfdfda6, 0xFFfbfca3, 0xFFf9fb9f, 0xFFf6f795, 0xFFfafb92, 0xFFfbfb8b, + 0xFFfbfb85, 0xFFfafa79, 0xFFfafa6d, 0xFFf9f961, 0xFFf8f956, 0xFFf9f64c, 0xFFf9f442, 0xFFf5ec39, + 0xFFf2e531, 0xFFefde28, 0xFFecd620, 0xFFeed900, 0xFF32a6e5, 0xFF19a4ff, 0xFF29a4f4, 0xFF20a2f4, + 0xFF18a0f5, 0xFF179ef4, 0xFF159df4, 0xFF139bf3, 0xFF1199f2, 0xFF129af2, 0xFF129af3, 0xFF129af3, + 0xFF5bd1f5, 0xFF63dffa, 0xFF318dcc, 0xFF062d91, 0xFF0e499a, 0xFF00369f, 0xFF003897, 0xFF155fb6, + 0xFF53aad9, 0xFF31a6e2, 0xFF45bcef, 0xFF6dddff, 0xFF76defa, 0xFF6dd9f9, 0xFF64d5f9, 0xFF54c5f3, + 0xFF45b5ed, 0xFF238ed6, 0xFF1277ce, 0xFF006cc6, 0xFF0282de, 0xFF0187db, 0xFF008dd7, 0xFF079be1, + 0xFF0099dc, 0xFF22b1f0, 0xFF36baf4, 0xFF3cbcf4, 0xFF1cb5ff, 0xFFfffe89, 0xFFfbff96, 0xFFfbfc98, + 0xFFfbf99a, 0xFFfcfb98, 0xFFfdfd96, 0xFFfafb90, 0xFFf6f98a, 0xFFf7f984, 0xFFf8fa7f, 0xFFfafa7a, + 0xFFfbfb75, 0xFFfafa6a, 0xFFf9f960, 0xFFf8f855, 0xFFf7f84a, 0xFFf7f540, 0xFFf8f336, 0xFFf4eb2f, + 0xFFf0e328, 0xFFf0da24, 0xFFf0d121, 0xFFe9ca24, 0xFF049bff, 0xFF20a3f6, 0xFF16a1f7, 0xFF16a0f7, + 0xFF169ef7, 0xFF159df6, 0xFF149cf5, 0xFF139bf4, 0xFF129af3, 0xFF129af3, 0xFF129af3, 0xFF129af3, + 0xFF5ae3ff, 0xFF64d8ff, 0xFF0d4798, 0xFF002682, 0xFF1d6bb7, 0xFF3aa2de, 0xFF5fe5ff, 0xFF52d8fd, + 0xFF4dd6f6, 0xFF48ccf5, 0xFF5fd0f6, 0xFF68d9ff, 0xFF61d3f8, 0xFF5bd2f8, 0xFF42cbff, 0xFF53cefe, + 0xFF51cff5, 0xFF49caf6, 0xFF4acdff, 0xFF40baff, 0xFF0e7edb, 0xFF0069c2, 0xFF0584da, 0xFF0184d5, + 0xFF068cd8, 0xFF38bef8, 0xFF3abef7, 0xFF35beff, 0xFF62c7e2, 0xFFfbf379, 0xFFf8fa83, 0xFFf9f983, + 0xFFfaf884, 0xFFf9f77f, 0xFFf7f77b, 0xFFf8f979, 0xFFf9fa77, 0xFFf8f972, 0xFFf7f86c, 0xFFfcfc6c, + 0xFFf9f864, 0xFFf8f85b, 0xFFf8f752, 0xFFf7f649, 0xFFf6f53f, 0xFFf5f237, 0xFFf4ef2f, 0xFFf1e628, + 0xFFeede20, 0xFFead61f, 0xFFf2cc11, 0xFF9db96c, 0xFF0c9ffe, 0xFF1ba3f9, 0xFF17a2f9, 0xFF17a0f9, + 0xFF169ef8, 0xFF169df7, 0xFF159cf6, 0xFF149bf5, 0xFF139af5, 0xFF139af5, 0xFF139af5, 0xFF139af5, + 0xFF60d8f9, 0xFF5bd9f8, 0xFF4cadd7, 0xFF69ddff, 0xFF56ddf8, 0xFF55d6fc, 0xFF55d0ff, 0xFF5cd5ff, + 0xFF53cbf2, 0xFF4bcaf6, 0xFF43cafa, 0xFF47c9f8, 0xFF4cc8f6, 0xFF5ccff1, 0xFF46ccf8, 0xFF55caff, + 0xFF3ec4fa, 0xFF43c3fb, 0xFF48c2fd, 0xFF3ebff4, 0xFF44ccfb, 0xFF37b3fc, 0xFF0b7bdd, 0xFF006dc9, + 0xFF0d80d4, 0xFF4eccff, 0xFF3ec3fa, 0xFF2ec2ff, 0xFFa7dea8, 0xFFf8ec5b, 0xFFf5f570, 0xFFf7f66f, + 0xFFfaf76e, 0xFFf5f467, 0xFFf1f060, 0xFFf6f663, 0xFFfbfc65, 0xFFf8f95f, 0xFFf6f659, 0xFFfefe5d, + 0xFFf7f652, 0xFFf7f54c, 0xFFf7f545, 0xFFf6f33d, 0xFFf6f235, 0xFFf3ef2f, 0xFFf1eb29, 0xFFefe221, + 0xFFecd818, 0xFFe5d21a, 0xFFf3c700, 0xFF52a9b4, 0xFF14a4fb, 0xFF15a3fb, 0xFF17a3fc, 0xFF17a1fa, + 0xFF179ff8, 0xFF169df8, 0xFF159cf7, 0xFF159bf7, 0xFF1499f6, 0xFF1499f6, 0xFF1499f6, 0xFF1499f6, + 0xFF58cff2, 0xFF59ddfd, 0xFF55d5f9, 0xFF5ddeff, 0xFF4dcef3, 0xFF4dcbf3, 0xFF4cc8f3, 0xFF56d2fc, + 0xFF59d3fd, 0xFF50cefb, 0xFF47cafa, 0xFF48c9f9, 0xFF49c7f9, 0xFF51cbf6, 0xFF45c9f9, 0xFF4bc8fd, + 0xFF3fc5f9, 0xFF41c4fa, 0xFF43c2fb, 0xFF3bbdf3, 0xFF3ac0f4, 0xFF3ec7fc, 0xFF3ac6fc, 0xFF25a1e3, + 0xFF1f8dd9, 0xFF37b9f7, 0xFF26bbfa, 0xFF2abbf4, 0xFFced857, 0xFFf9fa5b, 0xFFd9db49, 0xFFedec58, + 0xFFfaf560, 0xFFf2ef4d, 0xFFe9ea3b, 0xFFeeef46, 0xFFf2f451, 0xFFf9f34f, 0xFFedf145, 0xFFfef84b, + 0xFFf4f542, 0xFFf5f43d, 0xFFf6f337, 0xFFf5f131, 0xFFf5ef2b, 0xFFf2eb27, 0xFFf0e622, 0xFFeedb1d, + 0xFFecd117, 0xFFf1cc09, 0xFFf5c509, 0xFF0fadff, 0xFF17a1f9, 0xFF18a1f9, 0xFF18a1f8, 0xFF18a0f9, + 0xFF179ff9, 0xFF169df9, 0xFF169cf8, 0xFF159bf8, 0xFF1599f8, 0xFF1599f8, 0xFF1599f8, 0xFF1599f8, + 0xFF60d5fb, 0xFF5bd3fb, 0xFF56d2fb, 0xFF55d1fc, 0xFF55d0fe, 0xFF54d0fa, 0xFF53d1f6, 0xFF51cef7, + 0xFF4ecbf8, 0xFF4dcbf9, 0xFF4ccafb, 0xFF49c8fb, 0xFF47c6fc, 0xFF45c6fb, 0xFF43c6fa, 0xFF41c6fa, + 0xFF40c7f9, 0xFF3fc5f9, 0xFF3ec3f9, 0xFF3fc3fb, 0xFF41c4fd, 0xFF38baf2, 0xFF40c1f8, 0xFF3dc3fb, + 0xFF3bc5fe, 0xFF37c1f6, 0xFF34beef, 0xFF2ebcf0, 0xFFded722, 0xFFbfdc38, 0xFFdee142, 0xFFecea4a, + 0xFFeae442, 0xFFeee942, 0xFFf2ee42, 0xFFeeed3f, 0xFFeaec3d, 0xFFfbee3f, 0xFFe5ec31, 0xFFfff239, + 0xFFf2f531, 0xFFf4f32e, 0xFFf5f12a, 0xFFf5ee25, 0xFFf4ec21, 0xFFf2e71e, 0xFFf0e11c, 0xFFeed519, + 0xFFecc917, 0xFFdec40c, 0xFFbbbe39, 0xFF0798f8, 0xFF1a9ff8, 0xFF1a9ff7, 0xFF1a9ff5, 0xFF189ff7, + 0xFF179ff9, 0xFF179ef9, 0xFF169cf9, 0xFF169bf9, 0xFF1699f9, 0xFF1699f9, 0xFF1699f9, 0xFF1699f9, + 0xFF5cd4f9, 0xFF58d4f9, 0xFF55d3f9, 0xFF56d2fa, 0xFF58d0fb, 0xFF56d0f8, 0xFF54d0f6, 0xFF51cef7, + 0xFF4dccf9, 0xFF4ccbfa, 0xFF4bcafb, 0xFF49c8fb, 0xFF47c7fb, 0xFF45c7fb, 0xFF43c6fa, 0xFF41c6fa, + 0xFF40c6f9, 0xFF3fc4f9, 0xFF3ec3f9, 0xFF3ec2fa, 0xFF3ec2fb, 0xFF3abef5, 0xFF3ec2f8, 0xFF3bc1f9, + 0xFF37c0f9, 0xFF36beff, 0xFF35bbff, 0xFF67bb84, 0xFFb0d219, 0xFFb4d31a, 0xFFd3da39, 0xFFe2dd3d, + 0xFFd6d532, 0xFFe1df38, 0xFFece93e, 0xFFe1e636, 0xFFe9e536, 0xFFf1e634, 0xFFe5e42b, 0xFFf6e62e, + 0xFFe9eb29, 0xFFf0ee2a, 0xFFf0e824, 0xFFece420, 0xFFe9e01d, 0xFFebdb1c, 0xFFedd71c, 0xFFe9ce19, + 0xFFe5c516, 0xFFe7c004, 0xFF6cb292, 0xFF109dfc, 0xFF18a1f7, 0xFF1aa0f5, 0xFF1ca0f3, 0xFF19a0f6, + 0xFF179ff9, 0xFF169ef9, 0xFF169cf9, 0xFF159bf8, 0xFF159af8, 0xFF1499f8, 0xFF1499f7, 0xFF1499f7, + 0xFF58d4f6, 0xFF56d4f6, 0xFF54d5f7, 0xFF57d3f7, 0xFF5bd1f8, 0xFF58d0f6, 0xFF54cff5, 0xFF50cef8, + 0xFF4dcdfa, 0xFF4bcbfb, 0xFF4acafb, 0xFF48c9fb, 0xFF46c7fb, 0xFF45c7fa, 0xFF43c7fa, 0xFF42c6fa, + 0xFF40c6f9, 0xFF3fc4f9, 0xFF3ec3f9, 0xFF3dc1f9, 0xFF3cc0f9, 0xFF3cc1f8, 0xFF3cc2f7, 0xFF38bff6, + 0xFF34bbf5, 0xFF35bdfd, 0xFF37beff, 0xFF46bcfc, 0xFF82c92c, 0xFFa0be02, 0xFFb8c420, 0xFFd8cf31, + 0xFFd2d632, 0xFFd4d52e, 0xFFd7d42a, 0xFFcdd725, 0xFFe9df2f, 0xFFe6dd2a, 0xFFe4dc25, 0xFFedd922, + 0xFFe0e220, 0xFFede927, 0xFFeae01e, 0xFFe4da1c, 0xFFded319, 0xFFe5d01a, 0xFFebcd1b, 0xFFe5c818, + 0xFFdec214, 0xFFf0bc00, 0xFF1da5eb, 0xFF19a1ff, 0xFF16a2f7, 0xFF19a2f4, 0xFF1ea2f1, 0xFF1aa0f5, + 0xFF169ff9, 0xFF169ef8, 0xFF159df8, 0xFF159cf8, 0xFF149bf8, 0xFF139af7, 0xFF1299f6, 0xFF1299f6, + 0xFF5ed5f9, 0xFF63d6fc, 0xFF68d6ff, 0xFF5fd3fc, 0xFF56d0f8, 0xFF53cff8, 0xFF51cef8, 0xFF4ecdf9, + 0xFF4bccfb, 0xFF4acbfb, 0xFF48cafb, 0xFF47c9fa, 0xFF46c8fb, 0xFF44c7fa, 0xFF43c7fa, 0xFF42c6fa, + 0xFF40c5f9, 0xFF3fc4f9, 0xFF3ec3f9, 0xFF3dc1f9, 0xFF3cc0f9, 0xFF3bc1f9, 0xFF3bc1f8, 0xFF38bff7, + 0xFF36bdf7, 0xFF35bdfa, 0xFF34bdfe, 0xFF22c3f6, 0xFF27bbfc, 0xFF53b0b2, 0xFF9bc606, 0xFFc1d322, + 0xFFd3dd36, 0xFFb4ba12, 0xFFc4c71f, 0xFFc5cf22, 0xFFd9d82d, 0xFFdfdb30, 0xFFdcd52b, 0xFFe8d520, + 0xFFd5d51c, 0xFFe8e428, 0xFFece324, 0xFFd1ce1f, 0xFFd3c51d, 0xFFdcc302, 0xFFcfc312, 0xFFe3c209, + 0xFFe3be00, 0xFF84bf6e, 0xFF0ca0f6, 0xFF129ffd, 0xFF18a2f6, 0xFF19a1f5, 0xFF1ba1f4, 0xFF18a0f6, + 0xFF169ff8, 0xFF159ef8, 0xFF159df8, 0xFF149cf7, 0xFF139bf7, 0xFF129af6, 0xFF1098f4, 0xFF1098f4, + 0xFF65d7fb, 0xFF5dd4fa, 0xFF56d2f8, 0xFF53d0f9, 0xFF50cff9, 0xFF4fcef9, 0xFF4dcdfa, 0xFF4bcdfa, + 0xFF4accfb, 0xFF48cbfb, 0xFF47cafb, 0xFF46c9fa, 0xFF45c8fa, 0xFF44c7fa, 0xFF43c7fa, 0xFF42c6fa, + 0xFF40c5fa, 0xFF3fc4f9, 0xFF3ec3f9, 0xFF3dc1f9, 0xFF3bc0f9, 0xFF3ac0f9, 0xFF39c0f9, 0xFF38bff9, + 0xFF37bff9, 0xFF34bef8, 0xFF31bcf7, 0xFF33bbf8, 0xFF35bbfa, 0xFF2cbcff, 0xFF61c2df, 0xFF93cb85, + 0xFFc5d52b, 0xFFcbd82f, 0xFFb0bb13, 0xFFb5be17, 0xFFb9c21b, 0xFFc7c826, 0xFFc5bf21, 0xFFdbc817, + 0xFFcac819, 0xFFdbd722, 0xFFddd61a, 0xFFb7bd0d, 0xFFc8bd04, 0xFFd0c000, 0xFFadc951, 0xFF6cb8b1, + 0xFF04a3ff, 0xFF13a4fb, 0xFF21a4f5, 0xFF1ea3f5, 0xFF1aa1f6, 0xFF19a1f6, 0xFF18a0f7, 0xFF17a0f7, + 0xFF169ff8, 0xFF159ef7, 0xFF149ef7, 0xFF139df7, 0xFF139cf6, 0xFF119af4, 0xFF0f98f2, 0xFF0f98f2, + 0xFF5cd5f9, 0xFF58d3f8, 0xFF53d1f8, 0xFF52d0f9, 0xFF50cff9, 0xFF4ecefa, 0xFF4ccdfa, 0xFF4accfa, + 0xFF48ccfa, 0xFF47cbfa, 0xFF46cafa, 0xFF45c9fa, 0xFF44c8fa, 0xFF43c7fa, 0xFF42c7fa, 0xFF41c6fa, + 0xFF40c5fa, 0xFF3fc4f9, 0xFF3ec2f9, 0xFF3cc1f9, 0xFF3bc0f9, 0xFF3ac0f9, 0xFF38bff9, 0xFF37bff9, + 0xFF36bff9, 0xFF35bdf6, 0xFF34bbf3, 0xFF35b9f7, 0xFF35b8fb, 0xFF22b5ff, 0xFF2fb5ff, 0xFF4dbae6, + 0xFF6bbfce, 0xFF27b1c5, 0xFF6cbc7c, 0xFF8abd49, 0xFFa7be15, 0xFFb9bf09, 0xFFccc000, 0xFFdac43d, + 0xFFbbca20, 0xFFaec73e, 0xFF99bc54, 0xFF5aad8b, 0xFF36abc4, 0xFF04b3ff, 0xFF15a7ff, 0xFF21a4ff, + 0xFF19a0fb, 0xFF1ba2fa, 0xFF1da4f9, 0xFF1ba3f8, 0xFF1aa1f7, 0xFF19a1f7, 0xFF18a0f7, 0xFF17a0f7, + 0xFF169ff8, 0xFF159ef7, 0xFF149ef7, 0xFF139df7, 0xFF129cf6, 0xFF119af5, 0xFF0f99f3, 0xFF0f99f3, + 0xFF53d2f6, 0xFF52d1f7, 0xFF51d1f8, 0xFF50d0f9, 0xFF4fcffa, 0xFF4dcefa, 0xFF4bcdfa, 0xFF49ccfa, + 0xFF47cbfa, 0xFF46caf9, 0xFF45caf9, 0xFF44c9f9, 0xFF44c8fa, 0xFF43c7fa, 0xFF42c6f9, 0xFF41c6f9, + 0xFF40c5fa, 0xFF3fc4f9, 0xFF3dc2f9, 0xFF3cc1f9, 0xFF3ac0f9, 0xFF39c0f9, 0xFF38bff9, 0xFF36bff9, + 0xFF35bef8, 0xFF36bcf4, 0xFF38baf0, 0xFF36b8f6, 0xFF34b5fc, 0xFF2cb6f9, 0xFF23b7f6, 0xFF25b5fa, + 0xFF28b4ff, 0xFF28b6ff, 0xFF29b7ff, 0xFF1fb5ff, 0xFF15b2ff, 0xFF20aef7, 0xFF3cb9ff, 0xFF5acbf0, + 0xFF42befa, 0xFF2ab6fc, 0xFF12adff, 0xFF18acfc, 0xFF1eacfa, 0xFF1ea9fd, 0xFF1ea7ff, 0xFF1ba8fa, + 0xFF18a8f4, 0xFF18a6f8, 0xFF18a4fd, 0xFF19a3fa, 0xFF1aa1f7, 0xFF19a1f7, 0xFF18a0f8, 0xFF17a0f8, + 0xFF169ff8, 0xFF159ef7, 0xFF149df7, 0xFF139cf6, 0xFF129bf6, 0xFF119af5, 0xFF1099f4, 0xFF1099f4, + 0xFF54d1f8, 0xFF52d1f8, 0xFF51d0f9, 0xFF4fcff9, 0xFF4ecffa, 0xFF4ccefa, 0xFF4acdf9, 0xFF48ccf9, + 0xFF45cbf9, 0xFF45caf9, 0xFF44c9f9, 0xFF43c8f9, 0xFF43c8f9, 0xFF42c7f9, 0xFF42c6f9, 0xFF41c5f9, + 0xFF40c5fa, 0xFF3fc4f9, 0xFF3dc2f9, 0xFF3bc1f9, 0xFF3ac0fa, 0xFF38bff9, 0xFF37bff9, 0xFF36bef9, + 0xFF34bef8, 0xFF35bcf6, 0xFF35baf5, 0xFF34b8f8, 0xFF33b6fc, 0xFF2eb6f9, 0xFF29b6f7, 0xFF29b5f8, + 0xFF2ab4fa, 0xFF2ab5fb, 0xFF2ab5fc, 0xFF2ab2f6, 0xFF2aafef, 0xFF1ba9f6, 0xFF9bcfd9, 0xFF6dcfe9, + 0xFF74c7e4, 0xFF80c9dd, 0xFF19adfb, 0xFF1cacf9, 0xFF1fabf8, 0xFF1fa9f9, 0xFF1ea7fb, 0xFF1ca7f9, + 0xFF1aa7f6, 0xFF1aa5f8, 0xFF1aa4fb, 0xFF1aa3fa, 0xFF1aa2f8, 0xFF19a1f8, 0xFF18a0f8, 0xFF17a0f8, + 0xFF169ff8, 0xFF159ef7, 0xFF149df7, 0xFF139cf6, 0xFF129bf6, 0xFF119bf5, 0xFF119af5, 0xFF119af5, + 0xFF55d0f9, 0xFF53d0fa, 0xFF51d0fa, 0xFF4fcffa, 0xFF4dcffa, 0xFF4bcefa, 0xFF49cdf9, 0xFF46ccf9, + 0xFF44caf8, 0xFF43caf8, 0xFF43c9f8, 0xFF43c8f9, 0xFF42c8f9, 0xFF42c7f9, 0xFF41c6f9, 0xFF41c6f9, + 0xFF40c5fa, 0xFF3ec3f9, 0xFF3dc2fa, 0xFF3bc1fa, 0xFF39c0fa, 0xFF38bff9, 0xFF36bff9, 0xFF35bef9, + 0xFF34bdf8, 0xFF33bcf9, 0xFF33bafa, 0xFF32b9fb, 0xFF32b8fc, 0xFF30b7fa, 0xFF2eb6f8, 0xFF2db5f7, + 0xFF2bb4f5, 0xFF2bb4f6, 0xFF2bb3f7, 0xFF29b2f9, 0xFF28b2fc, 0xFF30b2f7, 0xFF12a8fe, 0xFF7fd4e1, + 0xFF58bbe6, 0xFF15aafb, 0xFF1fadf8, 0xFF20acf7, 0xFF20aaf5, 0xFF1fa9f6, 0xFF1ea8f7, 0xFF1da6f7, + 0xFF1ca5f8, 0xFF1ca4f8, 0xFF1ba3f9, 0xFF1ba3f9, 0xFF1ba2f9, 0xFF19a1f9, 0xFF18a0f8, 0xFF17a0f8, + 0xFF169ff8, 0xFF159ef7, 0xFF149df7, 0xFF139cf6, 0xFF129bf5, 0xFF129bf5, 0xFF129bf5, 0xFF129bf5, + 0xFF55d0f9, 0xFF53d0fa, 0xFF51d0fa, 0xFF4fcffa, 0xFF4dcffa, 0xFF4bcefa, 0xFF49cdf9, 0xFF46ccf9, + 0xFF44caf8, 0xFF43caf8, 0xFF43c9f8, 0xFF43c8f9, 0xFF42c8f9, 0xFF42c7f9, 0xFF41c6f9, 0xFF41c6f9, + 0xFF40c5fa, 0xFF3ec3f9, 0xFF3dc2fa, 0xFF3bc1fa, 0xFF39c0fa, 0xFF38bff9, 0xFF36bff9, 0xFF35bef9, + 0xFF34bdf8, 0xFF33bcf9, 0xFF33bafa, 0xFF32b9fb, 0xFF32b8fc, 0xFF30b7fa, 0xFF2eb6f8, 0xFF2db5f7, + 0xFF2bb4f5, 0xFF2bb4f6, 0xFF2bb3f7, 0xFF2ab2f8, 0xFF29b2fa, 0xFF2db6f5, 0xFF1db5f6, 0xFF239bff, + 0xFF20b6f3, 0xFF0cacfb, 0xFF1eacf7, 0xFF1fabf6, 0xFF20aaf5, 0xFF1fa9f6, 0xFF1ea8f7, 0xFF1da6f7, + 0xFF1ca5f8, 0xFF1ca4f8, 0xFF1ba3f9, 0xFF1ba3f9, 0xFF1ba2f9, 0xFF19a1f9, 0xFF18a0f8, 0xFF17a0f8, + 0xFF169ff8, 0xFF159ef7, 0xFF149df7, 0xFF139cf6, 0xFF129bf5, 0xFF129bf5, 0xFF129bf5, 0xFF129bf5, + 0xFF55d0f9, 0xFF53d0fa, 0xFF51d0fa, 0xFF4fcffa, 0xFF4dcffa, 0xFF4bcefa, 0xFF49cdf9, 0xFF46ccf9, + 0xFF44caf8, 0xFF43caf8, 0xFF43c9f8, 0xFF43c8f9, 0xFF42c8f9, 0xFF42c7f9, 0xFF41c6f9, 0xFF41c6f9, + 0xFF40c5fa, 0xFF3ec3f9, 0xFF3dc2fa, 0xFF3bc1fa, 0xFF39c0fa, 0xFF38bff9, 0xFF36bff9, 0xFF35bef9, + 0xFF34bdf8, 0xFF33bcf9, 0xFF33bafa, 0xFF32b9fb, 0xFF32b8fc, 0xFF30b7fa, 0xFF2eb6f8, 0xFF2db5f7, + 0xFF2bb4f5, 0xFF2bb4f6, 0xFF2bb3f7, 0xFF2bb2f8, 0xFF2bb1f8, 0xFF22aff9, 0xFF19acfa, 0xFF1eadf7, + 0xFF24aef3, 0xFF20adf5, 0xFF1dabf6, 0xFF1fabf6, 0xFF20aaf5, 0xFF1fa9f6, 0xFF1ea8f7, 0xFF1da6f7, + 0xFF1ca5f8, 0xFF1ca4f8, 0xFF1ba3f9, 0xFF1ba3f9, 0xFF1ba2f9, 0xFF19a1f9, 0xFF18a0f8, 0xFF17a0f8, + 0xFF169ff8, 0xFF159ef7, 0xFF149df7, 0xFF139cf6, 0xFF129bf5, 0xFF129bf5, 0xFF129bf5, 0xFF129bf5, + 0xFF55d0f9, 0xFF53d0fa, 0xFF51d0fa, 0xFF4fcffa, 0xFF4dcffa, 0xFF4bcefa, 0xFF49cdf9, 0xFF46ccf9, + 0xFF44caf8, 0xFF43caf8, 0xFF43c9f8, 0xFF43c8f9, 0xFF42c8f9, 0xFF42c7f9, 0xFF41c6f9, 0xFF41c6f9, + 0xFF40c5fa, 0xFF3ec3f9, 0xFF3dc2fa, 0xFF3bc1fa, 0xFF39c0fa, 0xFF38bff9, 0xFF36bff9, 0xFF35bef9, + 0xFF34bdf8, 0xFF33bcf9, 0xFF33bafa, 0xFF32b9fb, 0xFF32b8fc, 0xFF30b7fa, 0xFF2eb6f8, 0xFF2db5f7, + 0xFF2bb4f5, 0xFF2bb4f6, 0xFF2bb3f7, 0xFF2bb2f8, 0xFF2bb1f8, 0xFF22aff9, 0xFF19acfa, 0xFF1eadf7, + 0xFF24aef3, 0xFF20adf5, 0xFF1dabf6, 0xFF1fabf6, 0xFF20aaf5, 0xFF1fa9f6, 0xFF1ea8f7, 0xFF1da6f7, + 0xFF1ca5f8, 0xFF1ca4f8, 0xFF1ba3f9, 0xFF1ba3f9, 0xFF1ba2f9, 0xFF19a1f9, 0xFF18a0f8, 0xFF17a0f8, + 0xFF169ff8, 0xFF159ef7, 0xFF149df7, 0xFF139cf6, 0xFF129bf5, 0xFF129bf5, 0xFF129bf5, 0xFF129bf5 +}; + +static int test_memcmp_offset(const BYTE* mem1, const BYTE* mem2, int size) +{ + int index = 0; + + while ((index < size) && (*mem1 == *mem2)) + { + mem1++; + mem2++; + index++; + } + + return (index == size) ? 1 : -index; +} + +static int test_memcmp_count(const BYTE* mem1, const BYTE* mem2, int size) +{ + int count = 0; + int index = 0; + + for (index = 0; index < size; index++) + { + if (*mem1 != *mem2) + count++; + + mem1++; + mem2++; + } + + return count; +} + +int TestPrimitivesYCbCr(int argc, char* argv[]) +{ + int cmp; + int cnt; + int size; + BYTE* actual; + BYTE* expected; + INT16* pYCbCr[3]; + const primitives_t* prims = primitives_get(); + static const prim_size_t roi_64x64 = { 64, 64 }; + + expected = (BYTE*) TEST_XRGB_IMAGE; + + size = 64 * 64 * 4; + actual = _aligned_malloc(size, 16); + + if (!actual) + return 1; + + ZeroMemory(actual, size); + + pYCbCr[0] = TEST_Y_COMPONENT; + pYCbCr[1] = TEST_CB_COMPONENT; + pYCbCr[2] = TEST_CR_COMPONENT; + + if (1) + { + prims->yCbCrToRGB_16s8u_P3AC4R((const INT16**) pYCbCr, 64 * 2, + actual, 64 * 4, &roi_64x64); + } + else + { + INT16* pSrcDst[3]; + + pSrcDst[0] = _aligned_malloc(4096 * 2, 16); + pSrcDst[1] = _aligned_malloc(4096 * 2, 16); + pSrcDst[2] = _aligned_malloc(4096 * 2, 16); + + CopyMemory(pSrcDst[0], pYCbCr[0], 4096 * 2); + CopyMemory(pSrcDst[1], pYCbCr[1], 4096 * 2); + CopyMemory(pSrcDst[2], pYCbCr[2], 4096 * 2); + + prims->yCbCrToRGB_16s16s_P3P3((const INT16**) pSrcDst, 64 * 2, + pSrcDst, 64 * 2, &roi_64x64); + + prims->RGBToRGB_16s8u_P3AC4R((const INT16**) pSrcDst, 64 * 2, + actual, 64 * 4, &roi_64x64); + + _aligned_free(pSrcDst[0]); + _aligned_free(pSrcDst[1]); + _aligned_free(pSrcDst[2]); + } + + cmp = test_memcmp_offset(actual, expected, size); + cnt = test_memcmp_count(actual, expected, size); + + if (cmp <= 0) + { + cmp *= -1; + float rate = ((float) cnt) / ((float) size) * 100.0f; + + printf("YCbCr to RGB conversion failure\n"); + + printf("Actual, Expected (offset: %d diff: %d/%d = %d%%):\n", + cmp, cnt, size, (int) rate); + + winpr_HexDump(&actual[cmp], 16); + winpr_HexDump(&expected[cmp], 16); + } + + _aligned_free(actual); + + return 0; +} + diff --git a/libfreerdp/primitives/test/test_YCoCg.c b/libfreerdp/primitives/test/TestPrimitivesYCoCg.c similarity index 83% rename from libfreerdp/primitives/test/test_YCoCg.c rename to libfreerdp/primitives/test/TestPrimitivesYCoCg.c index f09acd5de..c280b5be3 100644 --- a/libfreerdp/primitives/test/test_YCoCg.c +++ b/libfreerdp/primitives/test/TestPrimitivesYCoCg.c @@ -26,7 +26,9 @@ static const int YCOCG_TRIAL_ITERATIONS = 20000; static const float TEST_TIME = 4.0; -extern pstatus_t general_YCoCgRToRGB_8u_AC4R(const BYTE *pSrc, INT32 srcStep, +extern BOOL g_TestPrimitivesPerformance; + +extern pstatus_t general_YCoCgToRGB_8u_AC4R(const BYTE *pSrc, INT32 srcStep, BYTE *pDst, INT32 dstStep, UINT32 width, UINT32 height, UINT8 shift, BOOL withAlpha, BOOL invert); extern pstatus_t ssse3_YCoCgRToRGB_8u_AC4R(const BYTE *pSrc, INT32 srcStep, @@ -46,9 +48,9 @@ int test_YCoCgRToRGB_8u_AC4R_func(void) testStr[0] = '\0'; get_random_data(in, sizeof(in)); - general_YCoCgRToRGB_8u_AC4R((const BYTE *) (in+1), 63*4, + general_YCoCgToRGB_8u_AC4R((const BYTE *) (in+1), 63*4, (BYTE *) out_c, 63*4, 63, 61, 2, TRUE, FALSE); - general_YCoCgRToRGB_8u_AC4R((const BYTE *) (in+1), 63*4, + general_YCoCgToRGB_8u_AC4R((const BYTE *) (in+1), 63*4, (BYTE *) out_c_inv, 63*4, 63, 61, 2, TRUE, TRUE); #ifdef WITH_SSE2 if (IsProcessorFeaturePresentEx(PF_EX_SSSE3)) @@ -84,7 +86,7 @@ int test_YCoCgRToRGB_8u_AC4R_func(void) /* ------------------------------------------------------------------------- */ STD_SPEED_TEST( ycocg_to_rgb_speed, const BYTE, BYTE, PRIM_NOP, - TRUE, general_YCoCgRToRGB_8u_AC4R(src1, 64*4, dst, 64*4, 64, 64, 2, FALSE, FALSE), + TRUE, general_YCoCgToRGB_8u_AC4R(src1, 64*4, dst, 64*4, 64, 64, 2, FALSE, FALSE), #ifdef WITH_SSE2 TRUE, ssse3_YCoCgRToRGB_8u_AC4R(src1, 64*4, dst, 64*4, 64, 64, 2, FALSE, FALSE), PF_EX_SSSE3, TRUE, @@ -97,7 +99,6 @@ int test_YCoCgRToRGB_8u_AC4R_speed(void) { INT32 ALIGN(in[4096]); INT32 ALIGN(out[4096]); - int i; int size_array[] = { 64 }; get_random_data(in, sizeof(in)); @@ -107,3 +108,23 @@ int test_YCoCgRToRGB_8u_AC4R_speed(void) size_array, 1, YCOCG_TRIAL_ITERATIONS, TEST_TIME); return SUCCESS; } + +int TestPrimitivesYCoCg(int argc, char* argv[]) +{ + int status; + + status = test_YCoCgRToRGB_8u_AC4R_func(); + + if (status != SUCCESS) + return 1; + + if (g_TestPrimitivesPerformance) + { + status = test_YCoCgRToRGB_8u_AC4R_speed(); + + if (status != SUCCESS) + return 1; + } + + return 0; +} diff --git a/libfreerdp/primitives/test/prim_test.c b/libfreerdp/primitives/test/prim_test.c index e9824a181..a19b5f64b 100644 --- a/libfreerdp/primitives/test/prim_test.c +++ b/libfreerdp/primitives/test/prim_test.c @@ -18,108 +18,22 @@ #include "prim_test.h" +#include #include #include -#include -#include + #include +#include #ifdef HAVE_UNISTD_H #include #endif -#include -#include - +BOOL g_TestPrimitivesPerformance = FALSE; int test_sizes[] = { 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096 }; -int Quiet = 0; - - /* ------------------------------------------------------------------------- */ -typedef struct -{ - UINT32 flag; - const char *str; -} flagpair_t; - -static const flagpair_t flags[] = -{ -#ifdef _M_IX86_AMD64 - { PF_MMX_INSTRUCTIONS_AVAILABLE, "MMX" }, - { PF_3DNOW_INSTRUCTIONS_AVAILABLE, "3DNow" }, - { PF_SSE_INSTRUCTIONS_AVAILABLE, "SSE" }, - { PF_SSE2_INSTRUCTIONS_AVAILABLE, "SSE2" }, - { PF_SSE3_INSTRUCTIONS_AVAILABLE, "SSE3" }, -#elif defined(_M_ARM) - { PF_ARM_VFP3, "VFP3" }, - { PF_ARM_INTEL_WMMX, "IWMMXT" }, - { PF_ARM_NEON_INSTRUCTIONS_AVAILABLE, "NEON" }, -#endif -}; - -static const flagpair_t flags_extended[] = -{ -#ifdef _M_IX86_AMD64 - { PF_EX_3DNOW_PREFETCH, "3DNow-PF" }, - { PF_EX_SSSE3, "SSSE3" }, - { PF_EX_SSE41, "SSE4.1" }, - { PF_EX_SSE42, "SSE4.2" }, - { PF_EX_AVX, "AVX" }, - { PF_EX_FMA, "FMA" }, - { PF_EX_AVX_AES, "AVX-AES" }, - { PF_EX_AVX2, "AVX2" }, -#elif defined(_M_ARM) - { PF_EX_ARM_VFP1, "VFP1"}, - { PF_EX_ARM_VFP4, "VFP4" }, -#endif -}; - -void primitives_flags_str(char* str, size_t len) -{ - int i; - - *str = '\0'; - --len; /* for the '/0' */ - - for (i = 0; i < sizeof(flags) / sizeof(flagpair_t); ++i) - { - if (IsProcessorFeaturePresent(flags[i].flag)) - { - int slen = strlen(flags[i].str) + 1; - - if (len < slen) - break; - - if (*str != '\0') - strcat(str, " "); - - strcat(str, flags[i].str); - len -= slen; - } - } - for (i = 0; i < sizeof(flags_extended) / sizeof(flagpair_t); ++i) - { - if (IsProcessorFeaturePresentEx(flags_extended[i].flag)) - { - int slen = strlen(flags_extended[i].str) + 1; - - if (len < slen) - break; - - if (*str != '\0') - strcat(str, " "); - - strcat(str, flags_extended[i].str); - len -= slen; - } - } -} - -/* ------------------------------------------------------------------------- */ -static void get_random_data_lrand( - void *buffer, - size_t size) +static void get_random_data_lrand(void *buffer, size_t size) { static int seeded = 0; long int *ptr = (long int *) buffer; @@ -145,11 +59,9 @@ static void get_random_data_lrand( } /* ------------------------------------------------------------------------- */ -void get_random_data( - void *buffer, - size_t size) +void get_random_data(void *buffer, size_t size) { -#ifdef linux +#ifdef __linux__ size_t offset = 0; int fd = open("/dev/urandom", O_RDONLY); if (fd < 0) @@ -171,373 +83,39 @@ void get_random_data( } /* ------------------------------------------------------------------------- */ -float _delta_time( - const struct timespec *t0, - const struct timespec *t1) +float _delta_time(const struct timespec *t0, const struct timespec *t1) { - INT64 secs = (INT64) (t1->tv_sec) - (INT64) (t0->tv_sec); - long nsecs = t1->tv_nsec - t0->tv_nsec; + INT64 secs = (INT64) (t1->tv_sec) - (INT64) (t0->tv_sec); + long nsecs = t1->tv_nsec - t0->tv_nsec; double retval; - if (nsecs < 0) + if (nsecs < 0) { - --secs; - nsecs += 1000000000; - } - retval = (double) secs + (double) nsecs / (double) 1000000000.0; - return (retval < 0.0) ? 0.0 : (float) retval; + --secs; + nsecs += 1000000000; + } + + retval = (double) secs + (double) nsecs / (double) 1000000000.0; + return (retval < 0.0) ? 0.0 : (float) retval; } /* ------------------------------------------------------------------------- */ -void _floatprint( - float t, - char *output) +void _floatprint(float t, char *output) { - /* I don't want to link against -lm, so avoid log,exp,... */ - float f = 10.0; + /* I don't want to link against -lm, so avoid log,exp,... */ + float f = 10.0; int i; - while (t > f) f *= 10.0; - f /= 1000.0; - i = ((int) (t/f+0.5)) * (int) f; - if (t < 0.0) sprintf(output, "%f", t); - else if (i == 0) sprintf(output, "%d", (int) (t+0.5)); - else if (t < 1e+3) sprintf(output, "%3d", i); - else if (t < 1e+6) sprintf(output, "%3d,%03d", - i/1000, i % 1000); - else if (t < 1e+9) sprintf(output, "%3d,%03d,000", - i/1000000, (i % 1000000) / 1000); - else if (t < 1e+12) sprintf(output, "%3d,%03d,000,000", - i/1000000000, (i % 1000000000) / 1000000); - else sprintf(output, "%f", t); -} - -/* ------------------------------------------------------------------------- */ -/* Specific areas to test: */ -#define TEST_COPY8 (1<<0) -#define TEST_SET8 (1<<1) -#define TEST_SET32S (1<<2) -#define TEST_SET32U (1<<3) -#define TEST_SIGN16S (1<<4) -#define TEST_ADD16S (1<<5) -#define TEST_LSHIFT16S (1<<6) -#define TEST_LSHIFT16U (1<<7) -#define TEST_RSHIFT16S (1<<8) -#define TEST_RSHIFT16U (1<<9) -#define TEST_RGB (1<<10) -#define TEST_ALPHA (1<<11) -#define TEST_AND (1<<12) -#define TEST_OR (1<<13) -#define TEST_YCOCG (1<<14) -#define TEST_16TO32 (1<<15) - -/* Specific types of testing: */ -#define TEST_FUNCTIONALITY (1<<0) -#define TEST_PERFORMANCE (1<<1) - -/* ------------------------------------------------------------------------- */ - -typedef struct -{ - const char *testStr; - UINT32 bits; -} test_t; - -static const test_t testList[] = -{ - { "all", 0xFFFFFFFFU }, - { "copy", TEST_COPY8 }, - { "copy8", TEST_COPY8 }, - { "set", TEST_SET8|TEST_SET32S|TEST_SET32U }, - { "set8", TEST_SET8 }, - { "set32", TEST_SET32S|TEST_SET32U }, - { "set32s", TEST_SET32S }, - { "set32u", TEST_SET32U }, - { "sign", TEST_SIGN16S }, - { "sign16s", TEST_SIGN16S }, - { "add", TEST_ADD16S }, - { "add16s", TEST_ADD16S }, - { "lshift", TEST_LSHIFT16S|TEST_LSHIFT16U }, - { "rshift", TEST_RSHIFT16S|TEST_RSHIFT16U }, - { "shift", TEST_LSHIFT16S|TEST_LSHIFT16U|TEST_RSHIFT16S|TEST_RSHIFT16U }, - { "lshift16s", TEST_LSHIFT16S }, - { "lshift16u", TEST_LSHIFT16U }, - { "rshift16s", TEST_RSHIFT16S }, - { "rshift16u", TEST_RSHIFT16U }, - { "rgb", TEST_RGB }, - { "color", TEST_RGB }, - { "colors", TEST_RGB }, - { "ycocg", TEST_YCOCG }, - { "alpha", TEST_ALPHA }, - { "and", TEST_AND }, - { "or", TEST_OR }, - { "16to32", TEST_16TO32 } -}; - -#define NUMTESTS (sizeof(testList)/sizeof(test_t)) - -static const test_t testTypeList[] = -{ - { "functionality", TEST_FUNCTIONALITY }, - { "performance", TEST_PERFORMANCE }, -}; - -#define NUMTESTTYPES (sizeof(testTypeList)/sizeof(test_t)) - -int main(int argc, char** argv) -{ - int i; - char hints[1024]; - UINT32 testSet = 0; - UINT32 testTypes = 0; - int results = SUCCESS; - - /* Parse command line for the test set. */ - - for (i = 1; i < argc; ++i) - { - int j; - BOOL found = 0; - - for (j=0; j f) f *= 10.0; + f /= 1000.0; + i = ((int) (t/f+0.5)) * (int) f; + if (t < 0.0) sprintf(output, "%f", t); + else if (i == 0) sprintf(output, "%d", (int) (t+0.5)); + else if (t < 1e+3) sprintf(output, "%3d", i); + else if (t < 1e+6) sprintf(output, "%3d,%03d", + i/1000, i % 1000); + else if (t < 1e+9) sprintf(output, "%3d,%03d,000", + i/1000000, (i % 1000000) / 1000); + else if (t < 1e+12) sprintf(output, "%3d,%03d,000,000", + i/1000000000, (i % 1000000000) / 1000000); + else sprintf(output, "%f", t); } diff --git a/libfreerdp/primitives/test/prim_test.h b/libfreerdp/primitives/test/prim_test.h index e336e3eb5..42f8777c9 100644 --- a/libfreerdp/primitives/test/prim_test.h +++ b/libfreerdp/primitives/test/prim_test.h @@ -20,31 +20,22 @@ #ifndef __PRIMTEST_H_INCLUDED__ #define __PRIMTEST_H_INCLUDED__ -#include -#include +#include +#include #include - -#include -#include -#include +#include #include -#include + +#include "measure.h" #ifdef WITH_IPP #include #include #endif -#define BLOCK_ALIGNMENT 16 -#ifdef __GNUC__ -#define ALIGN(x) x __attribute((aligned(BLOCK_ALIGNMENT))) -#define POSSIBLY_UNUSED(x) x __attribute((unused)) -#else -/* TODO: Someone needs to finish this for non-GNU C */ -#define ALIGN(x) x -#define POSSIBLY_UNUSED(x) x -#endif +#define ALIGN(x) x DECLSPEC_ALIGN(MEMORY_ALLOCATION_ALIGNMENT) + #define ABS(_x_) ((_x_) < 0 ? (-(_x_)) : (_x_)) #define MAX_TEST_SIZE 4096 diff --git a/libfreerdp/rail/icon.c b/libfreerdp/rail/icon.c index 4f7365413..fd8240298 100644 --- a/libfreerdp/rail/icon.c +++ b/libfreerdp/rail/icon.c @@ -26,6 +26,7 @@ #include +#include #include ICON_INFO* icon_cache_get(rdpIconCache* cache, BYTE id, UINT16 index, void** extra) @@ -34,13 +35,13 @@ ICON_INFO* icon_cache_get(rdpIconCache* cache, BYTE id, UINT16 index, void** ext if (id >= cache->numCaches) { - fprintf(stderr, "invalid window icon cache id:%d\n", id); + DEBUG_WARN( "invalid window icon cache id:%d\n", id); return (ICON_INFO*) NULL; } if (index >= cache->numCacheEntries) { - fprintf(stderr, "invalid window icon cache index:%d in cache id:%d\n", index, id); + DEBUG_WARN( "invalid window icon cache index:%d in cache id:%d\n", index, id); return (ICON_INFO*) NULL; } @@ -56,13 +57,13 @@ void icon_cache_put(rdpIconCache* cache, BYTE id, UINT16 index, ICON_INFO* entry { if (id >= cache->numCaches) { - fprintf(stderr, "invalid window icon cache id:%d\n", id); + DEBUG_WARN( "invalid window icon cache id:%d\n", id); return; } if (index >= cache->numCacheEntries) { - fprintf(stderr, "invalid window icon cache index:%d in cache id:%d\n", index, id); + DEBUG_WARN( "invalid window icon cache index:%d in cache id:%d\n", index, id); return; } diff --git a/libfreerdp/rail/window.c b/libfreerdp/rail/window.c index 9dd3d3c72..51c15c7f8 100644 --- a/libfreerdp/rail/window.c +++ b/libfreerdp/rail/window.c @@ -100,7 +100,7 @@ void print_window_styles(UINT32 style) { int i; - fprintf(stderr, "Window Styles:\n{\n"); + DEBUG_WARN( "Window Styles:\n{\n"); for (i = 0; i < ARRAYSIZE(WINDOW_STYLES); i++) { if (style & WINDOW_STYLES[i].style) @@ -111,17 +111,17 @@ void print_window_styles(UINT32 style) continue; } - fprintf(stderr, "\t%s\n", WINDOW_STYLES[i].name); + DEBUG_WARN( "\t%s\n", WINDOW_STYLES[i].name); } } - fprintf(stderr, "}\n"); + DEBUG_WARN( "}\n"); } void print_extended_window_styles(UINT32 style) { int i; - fprintf(stderr, "Extended Window Styles:\n{\n"); + DEBUG_WARN( "Extended Window Styles:\n{\n"); for (i = 0; i < ARRAYSIZE(EXTENDED_WINDOW_STYLES); i++) { if (style & EXTENDED_WINDOW_STYLES[i].style) @@ -132,10 +132,10 @@ void print_extended_window_styles(UINT32 style) continue; } - fprintf(stderr, "\t%s\n", EXTENDED_WINDOW_STYLES[i].name); + DEBUG_WARN( "\t%s\n", EXTENDED_WINDOW_STYLES[i].name); } } - fprintf(stderr, "}\n"); + DEBUG_WARN( "}\n"); } void window_state_update(rdpWindow* window, WINDOW_ORDER_INFO* orderInfo, WINDOW_STATE_ORDER* window_state) diff --git a/libfreerdp/utils/CMakeLists.txt b/libfreerdp/utils/CMakeLists.txt index 1db46f1a0..ad2a419ee 100644 --- a/libfreerdp/utils/CMakeLists.txt +++ b/libfreerdp/utils/CMakeLists.txt @@ -20,7 +20,6 @@ set(MODULE_PREFIX "FREERDP_UTILS") set(${MODULE_PREFIX}_SRCS event.c - bitmap.c passphrase.c pcap.c profiler.c diff --git a/libfreerdp/utils/bitmap.c b/libfreerdp/utils/bitmap.c deleted file mode 100644 index bc49d6d00..000000000 --- a/libfreerdp/utils/bitmap.c +++ /dev/null @@ -1,109 +0,0 @@ -/** - * FreeRDP: A Remote Desktop Protocol Implementation - * Bitmap File Format Utils - * - * Copyright 2011 Marc-Andre Moreau - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include - -#include - -#include - -typedef struct -{ - BYTE magic[2]; -} BITMAP_MAGIC; - -typedef struct -{ - UINT32 filesz; - UINT16 creator1; - UINT16 creator2; - UINT32 bmp_offset; -} BITMAP_CORE_HEADER; - -typedef struct -{ - UINT32 header_sz; - INT32 width; - INT32 height; - UINT16 nplanes; - UINT16 bitspp; - UINT32 compress_type; - UINT32 bmp_bytesz; - INT32 hres; - INT32 vres; - UINT32 ncolors; - UINT32 nimpcolors; -} BITMAP_INFO_HEADER; - -void freerdp_bitmap_write(char* filename, void* data, int width, int height, int bpp) -{ - FILE* fp; - BITMAP_MAGIC magic; - BITMAP_CORE_HEADER header; - BITMAP_INFO_HEADER info_header; - - fp = fopen(filename, "w+b"); - - if (fp == NULL) - { - fprintf(stderr, "failed to open file %s\n", filename); - return; - } - - magic.magic[0] = 'B'; - magic.magic[1] = 'M'; - - header.creator1 = 0; - header.creator2 = 0; - - header.bmp_offset = - sizeof(BITMAP_MAGIC) + - sizeof(BITMAP_CORE_HEADER) + - sizeof(BITMAP_INFO_HEADER); - - info_header.bmp_bytesz = width * height * (bpp / 8); - - header.filesz = - header.bmp_offset + - info_header.bmp_bytesz; - - info_header.width = width; - info_header.height = (-1) * height; - info_header.nplanes = 1; - info_header.bitspp = bpp; - info_header.compress_type = 0; - info_header.hres = width; - info_header.vres = height; - info_header.ncolors = 0; - info_header.nimpcolors = 0; - info_header.header_sz = sizeof(BITMAP_INFO_HEADER); - - fwrite((void*) &magic, sizeof(BITMAP_MAGIC), 1, fp); - fwrite((void*) &header, sizeof(BITMAP_CORE_HEADER), 1, fp); - fwrite((void*) &info_header, sizeof(BITMAP_INFO_HEADER), 1, fp); - fwrite((void*) data, info_header.bmp_bytesz, 1, fp); - - fclose(fp); -} - diff --git a/libfreerdp/utils/msusb.c b/libfreerdp/utils/msusb.c index 3bf5957ba..651bf8308 100644 --- a/libfreerdp/utils/msusb.c +++ b/libfreerdp/utils/msusb.c @@ -322,41 +322,41 @@ void msusb_msconfig_dump(MSUSB_CONFIG_DESCRIPTOR* MsConfig) MSUSB_PIPE_DESCRIPTOR * MsPipe; int inum = 0, pnum = 0; - fprintf(stderr, "=================MsConfig:========================\n"); - fprintf(stderr, "wTotalLength:%d\n", MsConfig->wTotalLength); - fprintf(stderr, "bConfigurationValue:%d\n", MsConfig->bConfigurationValue); - fprintf(stderr, "ConfigurationHandle:0x%x\n", MsConfig->ConfigurationHandle); - fprintf(stderr, "InitCompleted:%d\n", MsConfig->InitCompleted); - fprintf(stderr, "MsOutSize:%d\n", MsConfig->MsOutSize); - fprintf(stderr, "NumInterfaces:%d\n\n", MsConfig->NumInterfaces); + DEBUG_WARN( "=================MsConfig:========================\n"); + DEBUG_WARN( "wTotalLength:%d\n", MsConfig->wTotalLength); + DEBUG_WARN( "bConfigurationValue:%d\n", MsConfig->bConfigurationValue); + DEBUG_WARN( "ConfigurationHandle:0x%x\n", MsConfig->ConfigurationHandle); + DEBUG_WARN( "InitCompleted:%d\n", MsConfig->InitCompleted); + DEBUG_WARN( "MsOutSize:%d\n", MsConfig->MsOutSize); + DEBUG_WARN( "NumInterfaces:%d\n\n", MsConfig->NumInterfaces); MsInterfaces = MsConfig->MsInterfaces; for(inum = 0; inum < MsConfig->NumInterfaces; inum++) { MsInterface = MsInterfaces[inum]; - fprintf(stderr, " Interfase: %d\n", MsInterface->InterfaceNumber); - fprintf(stderr, " Length: %d\n", MsInterface->Length); - fprintf(stderr, " NumberOfPipesExpected: %d\n", MsInterface->NumberOfPipesExpected); - fprintf(stderr, " AlternateSetting: %d\n", MsInterface->AlternateSetting); - fprintf(stderr, " NumberOfPipes: %d\n", MsInterface->NumberOfPipes); - fprintf(stderr, " InterfaceHandle: 0x%x\n", MsInterface->InterfaceHandle); - fprintf(stderr, " bInterfaceClass: 0x%x\n", MsInterface->bInterfaceClass); - fprintf(stderr, " bInterfaceSubClass: 0x%x\n", MsInterface->bInterfaceSubClass); - fprintf(stderr, " bInterfaceProtocol: 0x%x\n", MsInterface->bInterfaceProtocol); - fprintf(stderr, " InitCompleted: %d\n\n", MsInterface->InitCompleted); + DEBUG_WARN( " Interfase: %d\n", MsInterface->InterfaceNumber); + DEBUG_WARN( " Length: %d\n", MsInterface->Length); + DEBUG_WARN( " NumberOfPipesExpected: %d\n", MsInterface->NumberOfPipesExpected); + DEBUG_WARN( " AlternateSetting: %d\n", MsInterface->AlternateSetting); + DEBUG_WARN( " NumberOfPipes: %d\n", MsInterface->NumberOfPipes); + DEBUG_WARN( " InterfaceHandle: 0x%x\n", MsInterface->InterfaceHandle); + DEBUG_WARN( " bInterfaceClass: 0x%x\n", MsInterface->bInterfaceClass); + DEBUG_WARN( " bInterfaceSubClass: 0x%x\n", MsInterface->bInterfaceSubClass); + DEBUG_WARN( " bInterfaceProtocol: 0x%x\n", MsInterface->bInterfaceProtocol); + DEBUG_WARN( " InitCompleted: %d\n\n", MsInterface->InitCompleted); MsPipes = MsInterface->MsPipes; for (pnum = 0; pnum < MsInterface->NumberOfPipes; pnum++) { MsPipe = MsPipes[pnum]; - fprintf(stderr, " Pipe: %d\n", pnum); - fprintf(stderr, " MaximumPacketSize: 0x%x\n", MsPipe->MaximumPacketSize); - fprintf(stderr, " MaximumTransferSize: 0x%x\n", MsPipe->MaximumTransferSize); - fprintf(stderr, " PipeFlags: 0x%x\n", MsPipe->PipeFlags); - fprintf(stderr, " PipeHandle: 0x%x\n", MsPipe->PipeHandle); - fprintf(stderr, " bEndpointAddress: 0x%x\n", MsPipe->bEndpointAddress); - fprintf(stderr, " bInterval: %d\n", MsPipe->bInterval); - fprintf(stderr, " PipeType: 0x%x\n", MsPipe->PipeType); - fprintf(stderr, " InitCompleted: %d\n\n", MsPipe->InitCompleted); + DEBUG_WARN( " Pipe: %d\n", pnum); + DEBUG_WARN( " MaximumPacketSize: 0x%x\n", MsPipe->MaximumPacketSize); + DEBUG_WARN( " MaximumTransferSize: 0x%x\n", MsPipe->MaximumTransferSize); + DEBUG_WARN( " PipeFlags: 0x%x\n", MsPipe->PipeFlags); + DEBUG_WARN( " PipeHandle: 0x%x\n", MsPipe->PipeHandle); + DEBUG_WARN( " bEndpointAddress: 0x%x\n", MsPipe->bEndpointAddress); + DEBUG_WARN( " bInterval: %d\n", MsPipe->bInterval); + DEBUG_WARN( " PipeType: 0x%x\n", MsPipe->PipeType); + DEBUG_WARN( " InitCompleted: %d\n\n", MsPipe->InitCompleted); } } - fprintf(stderr, "==================================================\n"); + DEBUG_WARN( "==================================================\n"); } diff --git a/libfreerdp/utils/pcap.c b/libfreerdp/utils/pcap.c index 5e174a847..347c67f8d 100644 --- a/libfreerdp/utils/pcap.c +++ b/libfreerdp/utils/pcap.c @@ -26,6 +26,7 @@ #include #include +#include #ifndef _WIN32 #include @@ -162,7 +163,7 @@ rdpPcap* pcap_open(char* name, BOOL write) if (pcap_fp == NULL) { - perror("opening pcap dump"); + DEBUG_WARN("opening pcap dump"); return NULL; } diff --git a/libfreerdp/utils/profiler.c b/libfreerdp/utils/profiler.c index d735dba77..306c94513 100644 --- a/libfreerdp/utils/profiler.c +++ b/libfreerdp/utils/profiler.c @@ -25,6 +25,7 @@ #include #include +#include PROFILER* profiler_create(char* name) { @@ -57,12 +58,12 @@ void profiler_exit(PROFILER* profiler) void profiler_print_header() { - fprintf(stderr, "\n"); - fprintf(stderr, " |-----------------------|\n" ); - fprintf(stderr, " PROFILER | elapsed seconds |\n" ); - fprintf(stderr, "|--------------------------------------------|-----------------------|\n" ); - fprintf(stderr, "| code section | iterations | total | avg. |\n" ); - fprintf(stderr, "|-------------------------------|------------|-----------|-----------|\n" ); + DEBUG_WARN( "\n"); + DEBUG_WARN( " |-----------------------|\n" ); + DEBUG_WARN( " PROFILER | elapsed seconds |\n" ); + DEBUG_WARN( "|--------------------------------------------|-----------------------|\n" ); + DEBUG_WARN( "| code section | iterations | total | avg. |\n" ); + DEBUG_WARN( "|-------------------------------|------------|-----------|-----------|\n" ); } void profiler_print(PROFILER* profiler) @@ -70,11 +71,11 @@ void profiler_print(PROFILER* profiler) double elapsed_sec = stopwatch_get_elapsed_time_in_seconds(profiler->stopwatch); double avg_sec = elapsed_sec / (double) profiler->stopwatch->count; - fprintf(stderr, "| %-30.30s| %10du | %9f | %9f |\n", + DEBUG_WARN( "| %-30.30s| %10du | %9f | %9f |\n", profiler->name, profiler->stopwatch->count, elapsed_sec, avg_sec); } void profiler_print_footer() { - fprintf(stderr, "|--------------------------------------------------------------------|\n" ); + DEBUG_WARN( "|--------------------------------------------------------------------|\n" ); } diff --git a/libfreerdp/utils/rail.c b/libfreerdp/utils/rail.c index ebfb8e7a1..b0d01ab40 100644 --- a/libfreerdp/utils/rail.c +++ b/libfreerdp/utils/rail.c @@ -143,7 +143,7 @@ void* rail_clone_order(UINT32 event_type, void* order) new_order = malloc(order_size); CopyMemory(new_order, order, order_size); - //fprintf(stderr, "rail_clone_order: type=%d order=%p\n", event_type, new_order); + //DEBUG_WARN( "rail_clone_order: type=%d order=%p\n", event_type, new_order); // Create copy of variable data for some orders if ((event_type == RailChannel_GetSystemParam) || @@ -183,7 +183,7 @@ void* rail_clone_order(UINT32 event_type, void* order) void rail_free_cloned_order(UINT32 event_type, void* order) { - //fprintf(stderr, "rail_free_cloned_order: type=%d order=%p\n", event_type, order); + //DEBUG_WARN( "rail_free_cloned_order: type=%d order=%p\n", event_type, order); if ((event_type == RailChannel_GetSystemParam) || (event_type == RailChannel_ClientSystemParam)) { diff --git a/libfreerdp/utils/signal.c b/libfreerdp/utils/signal.c index 1fd62a28e..fe3b3c6f8 100644 --- a/libfreerdp/utils/signal.c +++ b/libfreerdp/utils/signal.c @@ -26,6 +26,7 @@ #include #include +#include #ifdef _WIN32 @@ -49,7 +50,7 @@ static void fatal_handler(int signum) struct sigaction default_sigaction; sigset_t this_mask; - printf("fatal_handler: signum=%d\n", signum); + DEBUG_MSG("fatal_handler: signum=%d\n", signum); if (terminal_needs_reset) tcsetattr(terminal_fildes, TCSAFLUSH, &orig_flags); diff --git a/libfreerdp/utils/svc_plugin.c b/libfreerdp/utils/svc_plugin.c index 66dca1199..a5a7d5913 100644 --- a/libfreerdp/utils/svc_plugin.c +++ b/libfreerdp/utils/svc_plugin.c @@ -106,7 +106,6 @@ static void svc_plugin_process_received(rdpSvcPlugin* plugin, void* pData, UINT3 Stream_Release(plugin->data_in); plugin->data_in = StreamPool_Take(plugin->pool, totalLength); - //Stream_AddRef(plugin->data_in); } s = plugin->data_in; @@ -115,11 +114,6 @@ static void svc_plugin_process_received(rdpSvcPlugin* plugin, void* pData, UINT3 if (dataFlags & CHANNEL_FLAG_LAST) { - if (Stream_Length(s) != Stream_GetPosition(s)) - { - fprintf(stderr, "svc_plugin_process_received: read error\n"); - } - plugin->data_in = NULL; Stream_SealLength(s); Stream_SetPosition(s, 0); @@ -145,7 +139,7 @@ static VOID VCAPITYPE svc_plugin_open_event(DWORD openHandle, UINT event, LPVOID if (!plugin) { - fprintf(stderr, "svc_plugin_open_event: error no match\n"); + DEBUG_WARN( "svc_plugin_open_event: error no match\n"); return; } @@ -220,7 +214,7 @@ static void svc_plugin_process_connected(rdpSvcPlugin* plugin, LPVOID pData, UIN if (status != CHANNEL_RC_OK) { - fprintf(stderr, "svc_plugin_process_connected: open failed: status: %d\n", status); + DEBUG_WARN( "svc_plugin_process_connected: open failed: status: %d\n", status); return; } @@ -270,7 +264,7 @@ static VOID VCAPITYPE svc_plugin_init_event(LPVOID pInitHandle, UINT event, LPVO if (!plugin) { - fprintf(stderr, "svc_plugin_init_event: error no match\n"); + DEBUG_WARN( "svc_plugin_init_event: error no match\n"); return; } @@ -339,7 +333,7 @@ int svc_plugin_send(rdpSvcPlugin* plugin, wStream* data_out) if (status != CHANNEL_RC_OK) { Stream_Free(data_out, TRUE); - fprintf(stderr, "svc_plugin_send: VirtualChannelWrite failed %d\n", status); + DEBUG_WARN( "svc_plugin_send: VirtualChannelWrite failed %d\n", status); } return status; @@ -355,7 +349,7 @@ int svc_plugin_send_event(rdpSvcPlugin* plugin, wMessage* event) status = plugin->channel_entry_points.pVirtualChannelEventPush(plugin->OpenHandle, event); if (status != CHANNEL_RC_OK) - fprintf(stderr, "svc_plugin_send_event: VirtualChannelEventPush failed %d\n", status); + DEBUG_WARN( "svc_plugin_send_event: VirtualChannelEventPush failed %d\n", status); return status; } diff --git a/libfreerdp/utils/tcp.c b/libfreerdp/utils/tcp.c index 4cc95ec06..1e9aba90a 100644 --- a/libfreerdp/utils/tcp.c +++ b/libfreerdp/utils/tcp.c @@ -26,6 +26,7 @@ #include #include +#include #include #include @@ -96,7 +97,7 @@ int freerdp_tcp_connect(const char* hostname, int port) if (status != 0) { - //fprintf(stderr, "tcp_connect: getaddrinfo (%s)\n", gai_strerror(status)); + //DEBUG_WARN( "tcp_connect: getaddrinfo (%s)\n", gai_strerror(status)); return -1; } @@ -111,7 +112,7 @@ int freerdp_tcp_connect(const char* hostname, int port) if (connect(sockfd, ai->ai_addr, ai->ai_addrlen) == 0) { - fprintf(stderr, "connected to %s:%s\n", hostname, servname); + DEBUG_WARN( "connected to %s:%s\n", hostname, servname); break; } @@ -123,7 +124,7 @@ int freerdp_tcp_connect(const char* hostname, int port) if (sockfd == -1) { - fprintf(stderr, "unable to connect to %s:%s\n", hostname, servname); + DEBUG_WARN( "unable to connect to %s:%s\n", hostname, servname); return -1; } @@ -149,13 +150,13 @@ int freerdp_tcp_read(int sockfd, BYTE* data, int length) if (wsa_error == WSAEWOULDBLOCK) return 0; - fprintf(stderr, "recv() error: %d\n", wsa_error); + DEBUG_WARN( "recv() error: %d\n", wsa_error); #else /* No data available */ if (errno == EAGAIN || errno == EWOULDBLOCK) return 0; - perror("recv"); + DEBUG_WARN("recv"); #endif return -1; } @@ -178,12 +179,12 @@ int freerdp_tcp_write(int sockfd, BYTE* data, int length) if (wsa_error == WSAEWOULDBLOCK) status = 0; else - perror("send"); + DEBUG_WARN("send"); #else if (errno == EAGAIN || errno == EWOULDBLOCK) status = 0; else - perror("send"); + DEBUG_WARN("send"); #endif } @@ -203,7 +204,7 @@ int freerdp_tcp_wait_read(int sockfd) if (sockfd < 1) { - fprintf(stderr, "Invalid socket to watch: %d\n", sockfd); + DEBUG_WARN( "Invalid socket to watch: %d\n", sockfd); return 0 ; } @@ -240,7 +241,7 @@ int freerdp_tcp_wait_write(int sockfd) if (sockfd < 1) { - fprintf(stderr, "Invalid socket to watch: %d\n", sockfd); + DEBUG_WARN( "Invalid socket to watch: %d\n", sockfd); return 0 ; } diff --git a/libfreerdp/utils/test/TestRingBuffer.c b/libfreerdp/utils/test/TestRingBuffer.c index 1f4e3f504..dd128f44e 100644 --- a/libfreerdp/utils/test/TestRingBuffer.c +++ b/libfreerdp/utils/test/TestRingBuffer.c @@ -111,7 +111,7 @@ int TestRingBuffer(int argc, char* argv[]) if (ringbuffer_used(&ringBuffer) != 15) { - fprintf(stderr, "invalid used size got %d when i would expect 15\n", ringbuffer_used(&ringBuffer)); + fprintf(stderr, "invalid used size got %ld when i would expect 15\n", ringbuffer_used(&ringBuffer)); return -1; } @@ -134,7 +134,7 @@ int TestRingBuffer(int argc, char* argv[]) if (ringbuffer_used(&ringBuffer) != 5) { - fprintf(stderr, "invalid used size after read got %d when i would expect 5\n", ringbuffer_used(&ringBuffer)); + fprintf(stderr, "invalid used size after read got %ld when i would expect 5\n", ringbuffer_used(&ringBuffer)); return -1; } @@ -189,7 +189,7 @@ int TestRingBuffer(int argc, char* argv[]) if (ringbuffer_capacity(&ringBuffer) != 10) { - fprintf(stderr, "not the expected capacity, have %d and expects 10\n", ringbuffer_capacity(&ringBuffer)); + fprintf(stderr, "not the expected capacity, have %ld and expects 10\n", ringbuffer_capacity(&ringBuffer)); return -1; } fprintf(stderr, "ok\n"); @@ -213,7 +213,7 @@ int TestRingBuffer(int argc, char* argv[]) fprintf(stderr, "%d: specific overlaps test...", ++testNo); if (!test_overlaps()) { - fprintf(stderr, "ko\n", i); + fprintf(stderr, "ko\n"); return -1; } fprintf(stderr, "ok\n"); diff --git a/libfreerdp/utils/uds.c b/libfreerdp/utils/uds.c index d05f6ff32..6c872a6f1 100644 --- a/libfreerdp/utils/uds.c +++ b/libfreerdp/utils/uds.c @@ -22,6 +22,7 @@ #endif #include +#include #include #include @@ -54,7 +55,7 @@ int freerdp_uds_connect(const char* path) sockfd = socket(AF_UNIX, SOCK_STREAM, 0); if (sockfd == -1) { - perror("socket"); + DEBUG_WARN("socket"); return -1; } @@ -63,7 +64,7 @@ int freerdp_uds_connect(const char* path) status = connect(sockfd, (struct sockaddr *) &addr, sizeof(addr)); if (status < 0) { - perror("connect"); + DEBUG_WARN("connect"); close(sockfd); return -1; } diff --git a/resources/FreeRDP_Icon.png b/resources/FreeRDP_Icon.png index 40792cc1a..397e62d8f 100644 Binary files a/resources/FreeRDP_Icon.png and b/resources/FreeRDP_Icon.png differ diff --git a/resources/FreeRDP_Icon_256px.png b/resources/FreeRDP_Icon_256px.png index b43d8c5cd..66489e1a1 100644 Binary files a/resources/FreeRDP_Icon_256px.png and b/resources/FreeRDP_Icon_256px.png differ diff --git a/resources/FreeRDP_Logo.png b/resources/FreeRDP_Logo.png index 3b2d02f1d..1e272627b 100644 Binary files a/resources/FreeRDP_Logo.png and b/resources/FreeRDP_Logo.png differ diff --git a/server/.gitignore b/server/.gitignore index b5581fbbc..ef902f781 100644 --- a/server/.gitignore +++ b/server/.gitignore @@ -4,4 +4,5 @@ !/Sample !/Windows !/X11 +!/shadow !/CmakeLists.txt diff --git a/server/CMakeLists.txt b/server/CMakeLists.txt index a361a8b63..266fe93cf 100644 --- a/server/CMakeLists.txt +++ b/server/CMakeLists.txt @@ -18,6 +18,7 @@ # Servers add_subdirectory(common) +add_subdirectory(shadow) if(FREERDP_VENDOR) if(WITH_SAMPLE) @@ -25,15 +26,11 @@ if(FREERDP_VENDOR) endif() if(NOT WIN32) - if(WITH_X11) - add_subdirectory(X11) - endif() - if(APPLE AND (NOT IOS)) add_subdirectory(Mac) endif() else() - add_subdirectory(Windows) + #add_subdirectory(Windows) endif() if(IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/FreeRDS") @@ -62,3 +59,4 @@ endforeach() foreach(FREERDP_SERVER ${FREERDP_EXTRA_SERVERS}) add_subdirectory(${FREERDP_SERVER}) endforeach() + diff --git a/server/Mac/mf_audin.c b/server/Mac/mf_audin.c index 94de80984..c4b2d8f39 100644 --- a/server/Mac/mf_audin.c +++ b/server/Mac/mf_audin.c @@ -34,19 +34,19 @@ static const AUDIO_FORMAT supported_audio_formats[] = static void mf_peer_audin_opening(audin_server_context* context) { - fprintf(stderr, "AUDIN opening.\n"); + DEBUG_WARN( "AUDIN opening.\n"); /* Simply choose the first format supported by the client. */ context->SelectFormat(context, 0); } static void mf_peer_audin_open_result(audin_server_context* context, UINT32 result) { - fprintf(stderr, "AUDIN open result %d.\n", result); + DEBUG_WARN( "AUDIN open result %d.\n", result); } static void mf_peer_audin_receive_samples(audin_server_context* context, const void* buf, int nframes) { - fprintf(stderr, "AUDIN receive %d frames.\n", nframes); + DEBUG_WARN( "AUDIN receive %d frames.\n", nframes); } void mf_peer_audin_init(mfPeerContext* context) diff --git a/server/Mac/mf_audin.h b/server/Mac/mf_audin.h index 188cdaefa..d3e172b97 100644 --- a/server/Mac/mf_audin.h +++ b/server/Mac/mf_audin.h @@ -1,34 +1,34 @@ -/** - * FreeRDP: A Remote Desktop Protocol Implementation - * FreeRDP Mac OS X Server (Audio Input) - * - * Copyright 2012 Marc-Andre Moreau - * Copyright 2013 Corey Clayton - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef MF_AUDIN_H -#define MF_AUDIN_H - -#include -#include - -#include "mf_interface.h" -#include "mfreerdp.h" - - -void mf_peer_audin_init(mfPeerContext* context); - -#endif /* MF_AUDIN_H */ - +/** + * FreeRDP: A Remote Desktop Protocol Implementation + * FreeRDP Mac OS X Server (Audio Input) + * + * Copyright 2012 Marc-Andre Moreau + * Copyright 2013 Corey Clayton + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MF_AUDIN_H +#define MF_AUDIN_H + +#include +#include + +#include "mf_interface.h" +#include "mfreerdp.h" + + +void mf_peer_audin_init(mfPeerContext* context); + +#endif /* MF_AUDIN_H */ + diff --git a/server/Mac/mf_event.c b/server/Mac/mf_event.c index 6e68e6b85..a2e2e1a40 100644 --- a/server/Mac/mf_event.c +++ b/server/Mac/mf_event.c @@ -51,7 +51,7 @@ void mf_signal_event(mfEventQueue* event_queue) length = write(event_queue->pipe_fd[1], "sig", 4); if (length != 4) - fprintf(stderr, "mf_signal_event: error\n"); + DEBUG_WARN( "mf_signal_event: error\n"); } void mf_set_event(mfEventQueue* event_queue) @@ -61,7 +61,7 @@ void mf_set_event(mfEventQueue* event_queue) length = write(event_queue->pipe_fd[1], "sig", 4); if (length != 4) - fprintf(stderr, "mf_set_event: error\n"); + DEBUG_WARN( "mf_set_event: error\n"); } void mf_clear_events(mfEventQueue* event_queue) @@ -73,7 +73,7 @@ void mf_clear_events(mfEventQueue* event_queue) length = read(event_queue->pipe_fd[0], &length, 4); if (length != 4) - fprintf(stderr, "mf_clear_event: error\n"); + DEBUG_WARN( "mf_clear_event: error\n"); } } @@ -84,7 +84,7 @@ void mf_clear_event(mfEventQueue* event_queue) length = read(event_queue->pipe_fd[0], &length, 4); if (length != 4) - fprintf(stderr, "mf_clear_event: error\n"); + DEBUG_WARN( "mf_clear_event: error\n"); } void mf_event_push(mfEventQueue* event_queue, mfEvent* event) @@ -188,7 +188,7 @@ mfEventQueue* mf_event_queue_new() event_queue->events = (mfEvent**) malloc(sizeof(mfEvent*) * event_queue->size); if (pipe(event_queue->pipe_fd) < 0) - fprintf(stderr, "mf_event_queue_new: pipe failed\n"); + DEBUG_WARN( "mf_event_queue_new: pipe failed\n"); pthread_mutex_init(&(event_queue->mutex), NULL); } diff --git a/server/Mac/mf_event.h b/server/Mac/mf_event.h index edf648332..a9111a67f 100644 --- a/server/Mac/mf_event.h +++ b/server/Mac/mf_event.h @@ -18,7 +18,7 @@ */ #ifndef __MF_EVENT_H -#define __XMF_EVENT_H +#define __MF_EVENT_H typedef struct mf_event mfEvent; typedef struct mf_event_queue mfEventQueue; diff --git a/server/Mac/mf_info.c b/server/Mac/mf_info.c index 7c79eb335..dfa686a5f 100644 --- a/server/Mac/mf_info.c +++ b/server/Mac/mf_info.c @@ -43,7 +43,7 @@ int mf_info_lock(mfInfo* mfi) break; default: - printf("mf_info_lock failed with %#X\n", status); + DEBUG_MSG("mf_info_lock failed with %#X\n", status); return -1; break; } @@ -65,7 +65,7 @@ int mf_info_try_lock(mfInfo* mfi, UINT32 ms) break; default: - printf("mf_info_try_lock failed with %#X\n", status); + DEBUG_MSG("mf_info_try_lock failed with %#X\n", status); return -1; break; } @@ -82,7 +82,7 @@ int mf_info_unlock(mfInfo* mfi) break; default: - printf("mf_info_unlock failed with %#X\n", status); + DEBUG_MSG("mf_info_unlock failed with %#X\n", status); return -1; break; } @@ -110,7 +110,7 @@ mfInfo* mf_info_init() if (mutexInitStatus != 0) { - printf(_T("CreateMutex error: %#X\n"), mutexInitStatus); + DEBUG_MSG(_T("CreateMutex error: %#X\n"), mutexInitStatus); } mfi->peers = (freerdp_peer**) malloc(sizeof(freerdp_peer*) * MF_INFO_MAXPEERS); @@ -163,7 +163,7 @@ void mf_info_peer_register(mfInfo* mfi, mfPeerContext* context) int peerId; if (mfi->peerCount == MF_INFO_MAXPEERS) { - printf("TODO: socketClose on OS X\n"); + DEBUG_MSG("TODO: socketClose on OS X\n"); //context->socketClose = TRUE; mf_info_unlock(mfi); return; diff --git a/server/Mac/mf_info.h b/server/Mac/mf_info.h index ba2a58ed3..da420c3f5 100644 --- a/server/Mac/mf_info.h +++ b/server/Mac/mf_info.h @@ -1,50 +1,50 @@ -/** - * FreeRDP: A Remote Desktop Protocol Implementation - * FreeRDP Mac OS X Server - * - * Copyright 2012 Corey Clayton - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef MF_INFO_H -#define MF_INFO_H - -#define MF_INFO_DEFAULT_FPS 1 -#define MF_INFO_MAXPEERS 1 - - - -#include -#include - -#include "mf_interface.h" - -int mf_info_lock(mfInfo* mfi); -int mf_info_try_lock(mfInfo* mfi, UINT32 ms); -int mf_info_unlock(mfInfo* mfi); - -mfInfo* mf_info_get_instance(void); -void mf_info_peer_register(mfInfo* mfi, mfPeerContext* context); -void mf_info_peer_unregister(mfInfo* mfi, mfPeerContext* context); - -BOOL mf_info_have_updates(mfInfo* mfi); -void mf_info_update_changes(mfInfo* mfi); -void mf_info_find_invalid_region(mfInfo* mfi); -void mf_info_clear_invalid_region(mfInfo* mfi); -void mf_info_invalidate_full_screen(mfInfo* mfi); -BOOL mf_info_have_invalid_region(mfInfo* mfi); -void mf_info_getScreenData(mfInfo* mfi, long* width, long* height, BYTE** pBits, int* pitch); -//BOOL CALLBACK mf_info_monEnumCB(HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMonitor, LPARAM dwData); - -#endif /* mf_info_H */ +/** + * FreeRDP: A Remote Desktop Protocol Implementation + * FreeRDP Mac OS X Server + * + * Copyright 2012 Corey Clayton + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MF_INFO_H +#define MF_INFO_H + +#define MF_INFO_DEFAULT_FPS 1 +#define MF_INFO_MAXPEERS 1 + + + +#include +#include + +#include "mf_interface.h" + +int mf_info_lock(mfInfo* mfi); +int mf_info_try_lock(mfInfo* mfi, UINT32 ms); +int mf_info_unlock(mfInfo* mfi); + +mfInfo* mf_info_get_instance(void); +void mf_info_peer_register(mfInfo* mfi, mfPeerContext* context); +void mf_info_peer_unregister(mfInfo* mfi, mfPeerContext* context); + +BOOL mf_info_have_updates(mfInfo* mfi); +void mf_info_update_changes(mfInfo* mfi); +void mf_info_find_invalid_region(mfInfo* mfi); +void mf_info_clear_invalid_region(mfInfo* mfi); +void mf_info_invalidate_full_screen(mfInfo* mfi); +BOOL mf_info_have_invalid_region(mfInfo* mfi); +void mf_info_getScreenData(mfInfo* mfi, long* width, long* height, BYTE** pBits, int* pitch); +//BOOL CALLBACK mf_info_monEnumCB(HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMonitor, LPARAM dwData); + +#endif /* mf_info_H */ diff --git a/server/Mac/mf_input.c b/server/Mac/mf_input.c index ce58f5476..d74cd9c26 100644 --- a/server/Mac/mf_input.c +++ b/server/Mac/mf_input.c @@ -356,8 +356,8 @@ void mf_input_keyboard_event(rdpInput* input, UINT16 flags, UINT16 code) /* if (flags & KBD_FLAGS_EXTENDED) - fprintf(stderr, "extended "); - fprintf(stderr, "keypress: down = %d, SCAN=%#0X, VK=%#0X\n", keyDown, code, keymap[code]); + DEBUG_WARN( "extended "); + DEBUG_WARN( "keypress: down = %d, SCAN=%#0X, VK=%#0X\n", keyDown, code, keymap[code]); */ } @@ -548,7 +548,7 @@ void mf_input_mouse_event(rdpInput* input, UINT16 flags, UINT16 x, UINT16 y) void mf_input_extended_mouse_event(rdpInput* input, UINT16 flags, UINT16 x, UINT16 y) { - fprintf(stderr, "Unhandled mouse event!!!\n"); + DEBUG_WARN( "Unhandled mouse event!!!\n"); /* if ((flags & PTR_XFLAGS_BUTTON1) || (flags & PTR_XFLAGS_BUTTON2)) { diff --git a/server/Mac/mf_mountain_lion.c b/server/Mac/mf_mountain_lion.c index 88d59033a..f9777a261 100644 --- a/server/Mac/mf_mountain_lion.c +++ b/server/Mac/mf_mountain_lion.c @@ -86,7 +86,7 @@ void (^streamHandler)(CGDisplayStreamFrameStatus, uint64_t, IOSurfaceRef, CGDisp switch(status) { case kCGDisplayStreamFrameStatusFrameIdle: - printf("kCGDisplayStreamFrameStatusFrameIdle\n"); + DEBUG_MSG("kCGDisplayStreamFrameStatusFrameIdle\n"); break; case kCGDisplayStreamFrameStatusStopped: @@ -95,11 +95,11 @@ void (^streamHandler)(CGDisplayStreamFrameStatus, uint64_t, IOSurfaceRef, CGDisp break; case kCGDisplayStreamFrameStatusFrameBlank: - printf("kCGDisplayStreamFrameStatusFrameBlank\n"); + DEBUG_MSG("kCGDisplayStreamFrameStatusFrameBlank\n"); break; default: - printf("Unhandled Frame Status!!!\n"); + DEBUG_MSG("Unhandled Frame Status!!!\n"); } } @@ -193,7 +193,7 @@ int mf_mlion_start_getting_screen_updates() err = CGDisplayStreamStart(stream); if(err != kCGErrorSuccess) { - printf("Failed to start displaystream!! err = %d\n", err); + DEBUG_MSG("Failed to start displaystream!! err = %d\n", err); return 1; } @@ -207,7 +207,7 @@ int mf_mlion_stop_getting_screen_updates() err = CGDisplayStreamStop(stream); if(err != kCGErrorSuccess) { - printf("Failed to stop displaystream!! err = %d\n", err); + DEBUG_MSG("Failed to stop displaystream!! err = %d\n", err); return 1; } diff --git a/server/Mac/mf_peer.c b/server/Mac/mf_peer.c index 93ab74e6e..6eee3d892 100644 --- a/server/Mac/mf_peer.c +++ b/server/Mac/mf_peer.c @@ -83,7 +83,7 @@ BOOL mf_peer_check_fds(freerdp_peer* client) { if (event->type == MF_EVENT_TYPE_REGION) { - fprintf(stderr, "unhandled event\n"); + DEBUG_WARN( "unhandled event\n"); } else if (event->type == MF_EVENT_TYPE_FRAME_TICK) { @@ -237,10 +237,10 @@ void mf_peer_init(freerdp_peer* client) if(info_timer) { - //fprintf(stderr, "created timer\n"); + //DEBUG_WARN( "created timer\n"); dispatch_source_set_timer(info_timer, DISPATCH_TIME_NOW, 42ull * NSEC_PER_MSEC, 100ull * NSEC_PER_MSEC); dispatch_source_set_event_handler(info_timer, ^{ - //fprintf(stderr, "dispatch\n"); + //DEBUG_WARN( "dispatch\n"); mfEvent* event = mf_event_new(MF_EVENT_TYPE_FRAME_TICK); mf_event_push(info_event_queue, (mfEvent*) event);} ); @@ -253,17 +253,17 @@ BOOL mf_peer_post_connect(freerdp_peer* client) mfPeerContext* context = (mfPeerContext*) client->context; rdpSettings* settings = client->settings; - fprintf(stderr, "Client %s post connect\n", client->hostname); + DEBUG_WARN( "Client %s post connect\n", client->hostname); if (client->settings->AutoLogonEnabled) { - fprintf(stderr, " and wants to login automatically as %s\\%s", + DEBUG_WARN( " and wants to login automatically as %s\\%s", client->settings->Domain ? client->settings->Domain : "", client->settings->Username); /* A real server may perform OS login here if NLA is not executed previously. */ } - fprintf(stderr, "\n"); + DEBUG_WARN( "\n"); mfInfo* mfi = mf_info_get_instance(); mfi->scale = 1; @@ -274,7 +274,7 @@ BOOL mf_peer_post_connect(freerdp_peer* client) if ((settings->DesktopWidth != mfi->servscreen_width) || (settings->DesktopHeight != mfi->servscreen_height)) { - fprintf(stderr, "Client requested resolution %dx%d, but will resize to %dx%d\n", + DEBUG_WARN( "Client requested resolution %dx%d, but will resize to %dx%d\n", settings->DesktopWidth, settings->DesktopHeight, mfi->servscreen_width, mfi->servscreen_height); } @@ -314,12 +314,12 @@ BOOL mf_peer_activate(freerdp_peer* client) void mf_peer_synchronize_event(rdpInput* input, UINT32 flags) { - fprintf(stderr, "Client sent a synchronize event (flags:0x%08X)\n", flags); + DEBUG_WARN( "Client sent a synchronize event (flags:0x%08X)\n", flags); } void mf_peer_keyboard_event(rdpInput* input, UINT16 flags, UINT16 code) { - fprintf(stderr, "Client sent a keyboard event (flags:0x%04X code:0x%04X)\n", flags, code); + DEBUG_WARN( "Client sent a keyboard event (flags:0x%04X code:0x%04X)\n", flags, code); UINT16 down = 0x4000; //UINT16 up = 0x8000; @@ -341,28 +341,28 @@ void mf_peer_keyboard_event(rdpInput* input, UINT16 flags, UINT16 code) void mf_peer_unicode_keyboard_event(rdpInput* input, UINT16 flags, UINT16 code) { - fprintf(stderr, "Client sent a unicode keyboard event (flags:0x%04X code:0x%04X)\n", flags, code); + DEBUG_WARN( "Client sent a unicode keyboard event (flags:0x%04X code:0x%04X)\n", flags, code); } /*void mf_peer_mouse_event(rdpInput* input, UINT16 flags, UINT16 x, UINT16 y) { - //fprintf(stderr, "Client sent a mouse event (flags:0x%04X pos: %d,%d)\n", flags, x, y); + //DEBUG_WARN( "Client sent a mouse event (flags:0x%04X pos: %d,%d)\n", flags, x, y); } void mf_peer_extended_mouse_event(rdpInput* input, UINT16 flags, UINT16 x, UINT16 y) { - //fprintf(stderr, "Client sent an extended mouse event (flags:0x%04X pos: %d,%d)\n", flags, x, y); + //DEBUG_WARN( "Client sent an extended mouse event (flags:0x%04X pos: %d,%d)\n", flags, x, y); } */ /*static void mf_peer_refresh_rect(rdpContext* context, BYTE count, RECTANGLE_16* areas) { BYTE i; - fprintf(stderr, "Client requested to refresh:\n"); + DEBUG_WARN( "Client requested to refresh:\n"); for (i = 0; i < count; i++) { - fprintf(stderr, " (%d, %d) (%d, %d)\n", areas[i].left, areas[i].top, areas[i].right, areas[i].bottom); + DEBUG_WARN( " (%d, %d) (%d, %d)\n", areas[i].left, areas[i].top, areas[i].right, areas[i].bottom); } }*/ @@ -370,11 +370,11 @@ static void mf_peer_suppress_output(rdpContext* context, BYTE allow, RECTANGLE_1 { if (allow > 0) { - fprintf(stderr, "Client restore output (%d, %d) (%d, %d).\n", area->left, area->top, area->right, area->bottom); + DEBUG_WARN( "Client restore output (%d, %d) (%d, %d).\n", area->left, area->top, area->right, area->bottom); } else { - fprintf(stderr, "Client minimized and suppress output.\n"); + DEBUG_WARN( "Client minimized and suppress output.\n"); } } @@ -425,7 +425,7 @@ void* mf_peer_main_loop(void* arg) client->Initialize(client); context = (mfPeerContext*) client->context; - fprintf(stderr, "We've got a client %s\n", client->local ? "(local)" : client->hostname); + DEBUG_WARN( "We've got a client %s\n", client->local ? "(local)" : client->hostname); while (1) { @@ -433,12 +433,12 @@ void* mf_peer_main_loop(void* arg) if (client->GetFileDescriptor(client, rfds, &rcount) != TRUE) { - fprintf(stderr, "Failed to get FreeRDP file descriptor\n"); + DEBUG_WARN( "Failed to get FreeRDP file descriptor\n"); break; } if (mf_peer_get_fds(client, rfds, &rcount) != TRUE) { - fprintf(stderr, "Failed to get mfreerdp file descriptor\n"); + DEBUG_WARN( "Failed to get mfreerdp file descriptor\n"); break; } @@ -468,20 +468,20 @@ void* mf_peer_main_loop(void* arg) (errno == EINPROGRESS) || (errno == EINTR))) /* signal occurred */ { - fprintf(stderr, "select failed\n"); + DEBUG_WARN( "select failed\n"); break; } } if (client->CheckFileDescriptor(client) != TRUE) { - fprintf(stderr, "Failed to check freerdp file descriptor\n"); + DEBUG_WARN( "Failed to check freerdp file descriptor\n"); break; } if ((mf_peer_check_fds(client)) != TRUE) { - fprintf(stderr, "Failed to check mfreerdp file descriptor\n"); + DEBUG_WARN( "Failed to check mfreerdp file descriptor\n"); break; } @@ -491,7 +491,7 @@ void* mf_peer_main_loop(void* arg) } } - fprintf(stderr, "Client %s disconnected.\n", client->local ? "(local)" : client->hostname); + DEBUG_WARN( "Client %s disconnected.\n", client->local ? "(local)" : client->hostname); client->Disconnect(client); freerdp_peer_context_free(client); diff --git a/server/Mac/mf_peer.h b/server/Mac/mf_peer.h index 5c3f71572..f5249affe 100644 --- a/server/Mac/mf_peer.h +++ b/server/Mac/mf_peer.h @@ -1,44 +1,44 @@ -/** - * FreeRDP: A Remote Desktop Protocol Implementation - * FreeRDP Mac OS X Server - * - * Copyright 2012 Corey Clayton - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef WF_PEER_H -#define WF_PEER_H - -#include "mf_interface.h" - -BOOL mf_peer_get_fds(freerdp_peer* client, void** rfds, int* rcount); -BOOL mf_peer_check_fds(freerdp_peer* client); - -void mf_peer_rfx_update(freerdp_peer* client); - -int mf_peer_context_new(freerdp_peer* client, mfPeerContext* context); -void mf_peer_context_free(freerdp_peer* client, mfPeerContext* context); - -void mf_peer_init(freerdp_peer* client); - -BOOL mf_peer_post_connect(freerdp_peer* client); -BOOL mf_peer_activate(freerdp_peer* client); - -void mf_peer_synchronize_event(rdpInput* input, UINT32 flags); - -void mf_peer_accepted(freerdp_listener* instance, freerdp_peer* client); - -void* mf_peer_main_loop(void* arg); - -#endif /* MF_PEER_H */ +/** + * FreeRDP: A Remote Desktop Protocol Implementation + * FreeRDP Mac OS X Server + * + * Copyright 2012 Corey Clayton + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef WF_PEER_H +#define WF_PEER_H + +#include "mf_interface.h" + +BOOL mf_peer_get_fds(freerdp_peer* client, void** rfds, int* rcount); +BOOL mf_peer_check_fds(freerdp_peer* client); + +void mf_peer_rfx_update(freerdp_peer* client); + +int mf_peer_context_new(freerdp_peer* client, mfPeerContext* context); +void mf_peer_context_free(freerdp_peer* client, mfPeerContext* context); + +void mf_peer_init(freerdp_peer* client); + +BOOL mf_peer_post_connect(freerdp_peer* client); +BOOL mf_peer_activate(freerdp_peer* client); + +void mf_peer_synchronize_event(rdpInput* input, UINT32 flags); + +void mf_peer_accepted(freerdp_listener* instance, freerdp_peer* client); + +void* mf_peer_main_loop(void* arg); + +#endif /* MF_PEER_H */ diff --git a/server/Mac/mf_rdpsnd.c b/server/Mac/mf_rdpsnd.c index 3333795af..5278713ac 100644 --- a/server/Mac/mf_rdpsnd.c +++ b/server/Mac/mf_rdpsnd.c @@ -21,6 +21,9 @@ #include "config.h" #endif +#include +#include + #include #include "mf_info.h" @@ -30,8 +33,8 @@ AQRecorderState recorderState; static const AUDIO_FORMAT supported_audio_formats[] = { - { WAVE_FORMAT_PCM, 2, 44100, 176400, 4, 16, NULL }, - { WAVE_FORMAT_ALAW, 2, 22050, 44100, 2, 8, NULL } + { WAVE_FORMAT_PCM, 2, 44100, 176400, 4, 16, 0, NULL }, + { WAVE_FORMAT_ALAW, 2, 22050, 44100, 2, 8, 0, NULL } }; static void mf_peer_rdpsnd_activated(RdpsndServerContext* context) @@ -44,7 +47,7 @@ static void mf_peer_rdpsnd_activated(RdpsndServerContext* context) //we should actually loop through the list of client formats here //and see if we can send the client something that it supports... - printf("Client supports the following %d formats: \n", context->num_client_formats); + DEBUG_MSG("Client supports the following %d formats: \n", context->num_client_formats); for (i = 0; i < context->num_client_formats; i++) { @@ -55,7 +58,7 @@ static void mf_peer_rdpsnd_activated(RdpsndServerContext* context) (context->client_formats[i].nChannels == context->server_formats[j].nChannels) && (context->client_formats[i].nSamplesPerSec == context->server_formats[j].nSamplesPerSec)) { - printf("agreed on format!\n"); + DEBUG_MSG("agreed on format!\n"); formatAgreed = TRUE; agreedFormat = (AUDIO_FORMAT*)&context->server_formats[j]; break; @@ -68,7 +71,7 @@ static void mf_peer_rdpsnd_activated(RdpsndServerContext* context) if (formatAgreed == FALSE) { - printf("Could not agree on a audio format with the server\n"); + DEBUG_MSG("Could not agree on a audio format with the server\n"); return; } @@ -111,7 +114,7 @@ static void mf_peer_rdpsnd_activated(RdpsndServerContext* context) if (status != noErr) { - printf("Failed to create a new Audio Queue. Status code: %d\n", status); + DEBUG_MSG("Failed to create a new Audio Queue. Status code: %d\n", status); } @@ -161,7 +164,7 @@ BOOL mf_peer_rdpsnd_init(mfPeerContext* context) context->rdpsnd->Activated = mf_peer_rdpsnd_activated; - context->rdpsnd->Initialize(context->rdpsnd); + context->rdpsnd->Initialize(context->rdpsnd, TRUE); return TRUE; } @@ -208,7 +211,7 @@ void mf_peer_rdpsnd_input_callback (void *inUserD if (status != noErr) { - printf("AudioQueueEnqueueBuffer() returned status = %d\n", status); + DEBUG_MSG("AudioQueueEnqueueBuffer() returned status = %d\n", status); } } diff --git a/server/Mac/mf_rdpsnd.h b/server/Mac/mf_rdpsnd.h index 2c3c6de2d..dedc09d24 100644 --- a/server/Mac/mf_rdpsnd.h +++ b/server/Mac/mf_rdpsnd.h @@ -1,66 +1,66 @@ -/** - * FreeRDP: A Remote Desktop Protocol Implementation - * FreeRDP Mac OS X Server (Audio Output) - * - * Copyright 2012 Marc-Andre Moreau - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef MF_RDPSND_H -#define MF_RDPSND_H - -#include -#include - -#include -#include -#include - -#include "mf_interface.h" -#include "mfreerdp.h" - -void mf_rdpsnd_derive_buffer_size (AudioQueueRef audioQueue, - AudioStreamBasicDescription *ASBDescription, - Float64 seconds, - UInt32 *outBufferSize); - -void mf_peer_rdpsnd_input_callback (void *inUserData, - AudioQueueRef inAQ, - AudioQueueBufferRef inBuffer, - const AudioTimeStamp *inStartTime, - UInt32 inNumberPacketDescriptions, - const AudioStreamPacketDescription *inPacketDescs); - - -#define SND_NUMBUFFERS 3 -struct _AQRecorderState -{ - AudioStreamBasicDescription dataFormat; - AudioQueueRef queue; - AudioQueueBufferRef buffers[SND_NUMBUFFERS]; - AudioFileID audioFile; - UInt32 bufferByteSize; - SInt64 currentPacket; - bool isRunning; - RdpsndServerContext* snd_context; - -}; - -typedef struct _AQRecorderState AQRecorderState; - -BOOL mf_peer_rdpsnd_init(mfPeerContext* context); -BOOL mf_peer_rdpsnd_stop(void); - -#endif /* MF_RDPSND_H */ - +/** + * FreeRDP: A Remote Desktop Protocol Implementation + * FreeRDP Mac OS X Server (Audio Output) + * + * Copyright 2012 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MF_RDPSND_H +#define MF_RDPSND_H + +#include +#include + +#include +#include +#include + +#include "mf_interface.h" +#include "mfreerdp.h" + +void mf_rdpsnd_derive_buffer_size (AudioQueueRef audioQueue, + AudioStreamBasicDescription *ASBDescription, + Float64 seconds, + UInt32 *outBufferSize); + +void mf_peer_rdpsnd_input_callback (void *inUserData, + AudioQueueRef inAQ, + AudioQueueBufferRef inBuffer, + const AudioTimeStamp *inStartTime, + UInt32 inNumberPacketDescriptions, + const AudioStreamPacketDescription *inPacketDescs); + + +#define SND_NUMBUFFERS 3 +struct _AQRecorderState +{ + AudioStreamBasicDescription dataFormat; + AudioQueueRef queue; + AudioQueueBufferRef buffers[SND_NUMBUFFERS]; + AudioFileID audioFile; + UInt32 bufferByteSize; + SInt64 currentPacket; + bool isRunning; + RdpsndServerContext* snd_context; + +}; + +typedef struct _AQRecorderState AQRecorderState; + +BOOL mf_peer_rdpsnd_init(mfPeerContext* context); +BOOL mf_peer_rdpsnd_stop(void); + +#endif /* MF_RDPSND_H */ + diff --git a/server/Mac/mfreerdp.c b/server/Mac/mfreerdp.c index 2ac3122a2..1a1092964 100644 --- a/server/Mac/mfreerdp.c +++ b/server/Mac/mfreerdp.c @@ -60,7 +60,7 @@ static void mf_server_main_loop(freerdp_listener* instance) if (instance->GetFileDescriptor(instance, rfds, &rcount) != TRUE) { - fprintf(stderr, "Failed to get FreeRDP file descriptor\n"); + DEBUG_WARN( "Failed to get FreeRDP file descriptor\n"); break; } @@ -88,14 +88,14 @@ static void mf_server_main_loop(freerdp_listener* instance) (errno == EINPROGRESS) || (errno == EINTR))) /* signal occurred */ { - fprintf(stderr, "select failed\n"); + DEBUG_WARN( "select failed\n"); break; } } if (instance->CheckFileDescriptor(instance) != TRUE) { - fprintf(stderr, "Failed to check FreeRDP file descriptor\n"); + DEBUG_WARN( "Failed to check FreeRDP file descriptor\n"); break; } } diff --git a/server/Mac/mfreerdp.h b/server/Mac/mfreerdp.h index 153485cb2..2008b2581 100644 --- a/server/Mac/mfreerdp.h +++ b/server/Mac/mfreerdp.h @@ -1,28 +1,28 @@ -/** - * FreeRDP: A Remote Desktop Protocol Implementation - * FreeRDP Mac OS X Server - * - * Copyright 2012 Marc-Andre Moreau - * Copyright 2012 Corey Clayton - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef MFREERDP_SERVER_H -#define MFREERDP_SERVER_H - -#include -#include -#include - -#endif /* MFREERDP_SERVER_H */ +/** + * FreeRDP: A Remote Desktop Protocol Implementation + * FreeRDP Mac OS X Server + * + * Copyright 2012 Marc-Andre Moreau + * Copyright 2012 Corey Clayton + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MFREERDP_SERVER_H +#define MFREERDP_SERVER_H + +#include +#include +#include + +#endif /* MFREERDP_SERVER_H */ diff --git a/server/Sample/sf_audin.c b/server/Sample/sf_audin.c index 3d2a5538d..5edc16357 100644 --- a/server/Sample/sf_audin.c +++ b/server/Sample/sf_audin.c @@ -21,6 +21,8 @@ #include "config.h" #endif +#include + #include "sfreerdp.h" #include "sf_audin.h" @@ -33,19 +35,19 @@ static const AUDIO_FORMAT test_audio_formats[] = static void sf_peer_audin_opening(audin_server_context* context) { - printf("AUDIN opening.\n"); + DEBUG_MSG("AUDIN opening.\n"); /* Simply choose the first format supported by the client. */ context->SelectFormat(context, 0); } static void sf_peer_audin_open_result(audin_server_context* context, UINT32 result) { - printf("AUDIN open result %d.\n", result); + DEBUG_MSG("AUDIN open result %d.\n", result); } static void sf_peer_audin_receive_samples(audin_server_context* context, const void* buf, int nframes) { - printf("AUDIN receive %d frames.\n", nframes); + DEBUG_MSG("AUDIN receive %d frames.\n", nframes); } void sf_peer_audin_init(testPeerContext* context) diff --git a/server/Sample/sf_audin.h b/server/Sample/sf_audin.h index 51ec4b31a..db762fc55 100644 --- a/server/Sample/sf_audin.h +++ b/server/Sample/sf_audin.h @@ -1,32 +1,32 @@ -/** - * FreeRDP: A Remote Desktop Protocol Implementation - * FreeRDP Sample Server (Audio Input) - * - * Copyright 2012 Marc-Andre Moreau - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef SF_AUDIN_H -#define SF_AUDIN_H - -#include -#include -#include - -#include "sfreerdp.h" - -void sf_peer_audin_init(testPeerContext* context); - -#endif /* WF_AUDIN_H */ - +/** + * FreeRDP: A Remote Desktop Protocol Implementation + * FreeRDP Sample Server (Audio Input) + * + * Copyright 2012 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SF_AUDIN_H +#define SF_AUDIN_H + +#include +#include +#include + +#include "sfreerdp.h" + +void sf_peer_audin_init(testPeerContext* context); + +#endif /* WF_AUDIN_H */ + diff --git a/server/Sample/sf_encomsp.h b/server/Sample/sf_encomsp.h index f2abd3116..27703145d 100644 --- a/server/Sample/sf_encomsp.h +++ b/server/Sample/sf_encomsp.h @@ -1,31 +1,31 @@ -/** - * FreeRDP: A Remote Desktop Protocol Implementation - * FreeRDP Sample Server (Lync Multiparty) - * - * Copyright 2014 Marc-Andre Moreau - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef SF_ENCOMSP_H -#define SF_ENCOMSP_H - -#include -#include -#include - -#include "sfreerdp.h" - -BOOL sf_peer_encomsp_init(testPeerContext* context); - -#endif /* SF_ENCOMSP_H */ +/** + * FreeRDP: A Remote Desktop Protocol Implementation + * FreeRDP Sample Server (Lync Multiparty) + * + * Copyright 2014 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SF_ENCOMSP_H +#define SF_ENCOMSP_H + +#include +#include +#include + +#include "sfreerdp.h" + +BOOL sf_peer_encomsp_init(testPeerContext* context); + +#endif /* SF_ENCOMSP_H */ diff --git a/server/Sample/sf_rdpsnd.c b/server/Sample/sf_rdpsnd.c index 4f42fa946..3b5ee0126 100644 --- a/server/Sample/sf_rdpsnd.c +++ b/server/Sample/sf_rdpsnd.c @@ -22,6 +22,7 @@ #endif #include +#include #include "sf_rdpsnd.h" @@ -33,7 +34,7 @@ static const AUDIO_FORMAT test_audio_formats[] = static void sf_peer_rdpsnd_activated(RdpsndServerContext* context) { - printf("RDPSND Activated\n"); + DEBUG_MSG("RDPSND Activated\n"); } BOOL sf_peer_rdpsnd_init(testPeerContext* context) diff --git a/server/Sample/sf_rdpsnd.h b/server/Sample/sf_rdpsnd.h index ce2875f17..78e7c9bbd 100644 --- a/server/Sample/sf_rdpsnd.h +++ b/server/Sample/sf_rdpsnd.h @@ -1,32 +1,32 @@ -/** - * FreeRDP: A Remote Desktop Protocol Implementation - * FreeRDP Sample Server (Audio Output) - * - * Copyright 2012 Marc-Andre Moreau - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef SF_RDPSND_H -#define SF_RDPSND_H - -#include -#include -#include - -#include "sfreerdp.h" - -BOOL sf_peer_rdpsnd_init(testPeerContext* context); - -#endif /* SF_RDPSND_H */ - +/** + * FreeRDP: A Remote Desktop Protocol Implementation + * FreeRDP Sample Server (Audio Output) + * + * Copyright 2012 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SF_RDPSND_H +#define SF_RDPSND_H + +#include +#include +#include + +#include "sfreerdp.h" + +BOOL sf_peer_rdpsnd_init(testPeerContext* context); + +#endif /* SF_RDPSND_H */ + diff --git a/server/Sample/sfreerdp.c b/server/Sample/sfreerdp.c index a990d4a73..784bba1e2 100644 --- a/server/Sample/sfreerdp.c +++ b/server/Sample/sfreerdp.c @@ -33,6 +33,7 @@ #include #include +#include #include #include @@ -341,7 +342,7 @@ static BOOL test_sleep_tsdiff(UINT32 *old_sec, UINT32 *old_usec, UINT32 new_sec, if ((sec < 0) || ((sec == 0) && (usec < 0))) { - printf("Invalid time stamp detected.\n"); + DEBUG_MSG("Invalid time stamp detected.\n"); return FALSE; } @@ -451,7 +452,7 @@ static void* tf_debug_channel_thread_func(void* arg) Stream_SetPosition(s, BytesReturned); - printf("got %lu bytes\n", BytesReturned); + DEBUG_MSG("got %lu bytes\n", BytesReturned); } Stream_Free(s, TRUE); @@ -470,30 +471,30 @@ BOOL tf_peer_post_connect(freerdp_peer* client) * callback returns. */ - printf("Client %s is activated (osMajorType %d osMinorType %d)", client->local ? "(local)" : client->hostname, + DEBUG_MSG("Client %s is activated (osMajorType %d osMinorType %d)", client->local ? "(local)" : client->hostname, client->settings->OsMajorType, client->settings->OsMinorType); if (client->settings->AutoLogonEnabled) { - printf(" and wants to login automatically as %s\\%s", + DEBUG_MSG(" and wants to login automatically as %s\\%s", client->settings->Domain ? client->settings->Domain : "", client->settings->Username); /* A real server may perform OS login here if NLA is not executed previously. */ } - printf("\n"); + DEBUG_MSG("\n"); - printf("Client requested desktop: %dx%dx%d\n", + DEBUG_MSG("Client requested desktop: %dx%dx%d\n", client->settings->DesktopWidth, client->settings->DesktopHeight, client->settings->ColorDepth); #if (SAMPLE_SERVER_USE_CLIENT_RESOLUTION == 1) context->rfx_context->width = client->settings->DesktopWidth; context->rfx_context->height = client->settings->DesktopHeight; - printf("Using resolution requested by client.\n"); + DEBUG_MSG("Using resolution requested by client.\n"); #else client->settings->DesktopWidth = context->rfx_context->width; client->settings->DesktopHeight = context->rfx_context->height; - printf("Resizing client to %dx%d\n", client->settings->DesktopWidth, client->settings->DesktopHeight); + DEBUG_MSG("Resizing client to %dx%d\n", client->settings->DesktopWidth, client->settings->DesktopHeight); client->update->DesktopResize(client->update->context); #endif @@ -506,7 +507,7 @@ BOOL tf_peer_post_connect(freerdp_peer* client) if (context->debug_channel != NULL) { - printf("Open channel rdpdbg.\n"); + DEBUG_MSG("Open channel rdpdbg.\n"); context->stopEvent = CreateEvent(NULL, TRUE, FALSE, NULL); @@ -561,7 +562,7 @@ BOOL tf_peer_activate(freerdp_peer* client) void tf_peer_synchronize_event(rdpInput* input, UINT32 flags) { - printf("Client sent a synchronize event (flags:0x%X)\n", flags); + DEBUG_MSG("Client sent a synchronize event (flags:0x%X)\n", flags); } void tf_peer_keyboard_event(rdpInput* input, UINT16 flags, UINT16 code) @@ -570,7 +571,7 @@ void tf_peer_keyboard_event(rdpInput* input, UINT16 flags, UINT16 code) rdpUpdate* update = client->update; testPeerContext* context = (testPeerContext*) input->context; - printf("Client sent a keyboard event (flags:0x%X code:0x%X)\n", flags, code); + DEBUG_MSG("Client sent a keyboard event (flags:0x%X code:0x%X)\n", flags, code); if ((flags & 0x4000) && code == 0x22) /* 'g' key */ { @@ -622,7 +623,7 @@ void tf_peer_keyboard_event(rdpInput* input, UINT16 flags, UINT16 code) void tf_peer_unicode_keyboard_event(rdpInput* input, UINT16 flags, UINT16 code) { - printf("Client sent a unicode keyboard event (flags:0x%X code:0x%X)\n", flags, code); + DEBUG_MSG("Client sent a unicode keyboard event (flags:0x%X code:0x%X)\n", flags, code); } void tf_peer_mouse_event(rdpInput* input, UINT16 flags, UINT16 x, UINT16 y) @@ -641,11 +642,11 @@ static void tf_peer_refresh_rect(rdpContext* context, BYTE count, RECTANGLE_16* { BYTE i; - printf("Client requested to refresh:\n"); + DEBUG_MSG("Client requested to refresh:\n"); for (i = 0; i < count; i++) { - printf(" (%d, %d) (%d, %d)\n", areas[i].left, areas[i].top, areas[i].right, areas[i].bottom); + DEBUG_MSG(" (%d, %d) (%d, %d)\n", areas[i].left, areas[i].top, areas[i].right, areas[i].bottom); } } @@ -653,11 +654,11 @@ static void tf_peer_suppress_output(rdpContext* context, BYTE allow, RECTANGLE_1 { if (allow > 0) { - printf("Client restore output (%d, %d) (%d, %d).\n", area->left, area->top, area->right, area->bottom); + DEBUG_MSG("Client restore output (%d, %d) (%d, %d).\n", area->left, area->top, area->right, area->bottom); } else { - printf("Client minimized and suppress output.\n"); + DEBUG_MSG("Client minimized and suppress output.\n"); } } @@ -700,7 +701,7 @@ static void* test_peer_mainloop(void* arg) client->Initialize(client); context = (testPeerContext*) client->context; - printf("We've got a client %s\n", client->local ? "(local)" : client->hostname); + DEBUG_MSG("We've got a client %s\n", client->local ? "(local)" : client->hostname); while (1) { @@ -709,7 +710,7 @@ static void* test_peer_mainloop(void* arg) memset(rfds, 0, sizeof(rfds)); if (client->GetFileDescriptor(client, rfds, &rcount) != TRUE) { - printf("Failed to get FreeRDP file descriptor\n"); + DEBUG_MSG("Failed to get FreeRDP file descriptor\n"); break; } @@ -743,7 +744,7 @@ static void* test_peer_mainloop(void* arg) (wsa_error == WSAEINPROGRESS) || (wsa_error == WSAEINTR))) { - printf("select failed (WSAGetLastError: %d)\n", wsa_error); + DEBUG_MSG("select failed (WSAGetLastError: %d)\n", wsa_error); break; } #else @@ -753,7 +754,7 @@ static void* test_peer_mainloop(void* arg) (errno == EINPROGRESS) || (errno == EINTR))) /* signal occurred */ { - printf("select failed (errno: %d)\n", errno); + DEBUG_MSG("select failed (errno: %d)\n", errno); break; } #endif @@ -766,7 +767,7 @@ static void* test_peer_mainloop(void* arg) break; } - printf("Client %s disconnected.\n", client->local ? "(local)" : client->hostname); + DEBUG_MSG("Client %s disconnected.\n", client->local ? "(local)" : client->hostname); client->Disconnect(client); freerdp_peer_context_free(client); @@ -799,7 +800,7 @@ static void test_server_mainloop(freerdp_listener* instance) memset(rfds, 0, sizeof(rfds)); if (instance->GetFileDescriptor(instance, rfds, &rcount) != TRUE) { - printf("Failed to get FreeRDP file descriptor\n"); + DEBUG_MSG("Failed to get FreeRDP file descriptor\n"); break; } @@ -827,14 +828,14 @@ static void test_server_mainloop(freerdp_listener* instance) (errno == EINPROGRESS) || (errno == EINTR))) /* signal occurred */ { - printf("select failed\n"); + DEBUG_MSG("select failed\n"); break; } } if (instance->CheckFileDescriptor(instance) != TRUE) { - printf("Failed to check FreeRDP file descriptor\n"); + DEBUG_MSG("Failed to check FreeRDP file descriptor\n"); break; } } diff --git a/server/Sample/sfreerdp.h b/server/Sample/sfreerdp.h index 0c0e1cf13..1b81d82a4 100644 --- a/server/Sample/sfreerdp.h +++ b/server/Sample/sfreerdp.h @@ -1,64 +1,64 @@ -/** - * FreeRDP: A Remote Desktop Protocol Implementation - * FreeRDP Sample Server - * - * Copyright 2012 Marc-Andre Moreau - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef SFREERDP_SERVER_H -#define SFREERDP_SERVER_H - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -struct test_peer_context -{ - rdpContext _p; - - RFX_CONTEXT* rfx_context; - NSC_CONTEXT* nsc_context; - wStream* s; - BYTE* icon_data; - BYTE* bg_data; - int icon_width; - int icon_height; - int icon_x; - int icon_y; - BOOL activated; - HANDLE event; - HANDLE stopEvent; - HANDLE vcm; - void* debug_channel; - HANDLE debug_channel_thread; - audin_server_context* audin; - BOOL audin_open; - UINT32 frame_id; - RdpsndServerContext* rdpsnd; - EncomspServerContext* encomsp; -}; -typedef struct test_peer_context testPeerContext; - -#endif /* SFREERDP_SERVER_H */ - +/** + * FreeRDP: A Remote Desktop Protocol Implementation + * FreeRDP Sample Server + * + * Copyright 2012 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SFREERDP_SERVER_H +#define SFREERDP_SERVER_H + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +struct test_peer_context +{ + rdpContext _p; + + RFX_CONTEXT* rfx_context; + NSC_CONTEXT* nsc_context; + wStream* s; + BYTE* icon_data; + BYTE* bg_data; + int icon_width; + int icon_height; + int icon_x; + int icon_y; + BOOL activated; + HANDLE event; + HANDLE stopEvent; + HANDLE vcm; + void* debug_channel; + HANDLE debug_channel_thread; + audin_server_context* audin; + BOOL audin_open; + UINT32 frame_id; + RdpsndServerContext* rdpsnd; + EncomspServerContext* encomsp; +}; +typedef struct test_peer_context testPeerContext; + +#endif /* SFREERDP_SERVER_H */ + diff --git a/server/Windows/CMakeLists.txt b/server/Windows/CMakeLists.txt index ae9ed7c92..013c2a797 100644 --- a/server/Windows/CMakeLists.txt +++ b/server/Windows/CMakeLists.txt @@ -60,17 +60,17 @@ endif() if(WITH_SERVER_INTERFACE) add_library(${MODULE_NAME} ${${MODULE_PREFIX}_SRCS}) - if (WITH_LIBRARY_VERSIONING) - set_target_properties(${MODULE_NAME} PROPERTIES VERSION ${FREERDP_VERSION} SOVERSION ${FREERDP_API_VERSION}) - endif() + if (WITH_LIBRARY_VERSIONING) + set_target_properties(${MODULE_NAME} PROPERTIES VERSION ${FREERDP_VERSION} SOVERSION ${FREERDP_API_VERSION}) + endif() set_target_properties(${MODULE_NAME} PROPERTIES PREFIX "lib") else() set(${MODULE_PREFIX}_SRCS ${${MODULE_PREFIX}_SRCS} cli/wfreerdp.c cli/wfreerdp.h) add_executable(${MODULE_NAME} ${${MODULE_PREFIX}_SRCS}) endif() - -if(WITH_WIN8) + +if(CMAKE_WINDOWS_VERSION STREQUAL "WIN8") set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} d3d11 dxgi dxguid) endif() diff --git a/server/Windows/cli/wfreerdp.c b/server/Windows/cli/wfreerdp.c index 0e28c4398..48a5cd900 100644 --- a/server/Windows/cli/wfreerdp.c +++ b/server/Windows/cli/wfreerdp.c @@ -36,7 +36,7 @@ int IDcount = 0; BOOL CALLBACK moncb(HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMonitor, LPARAM dwData) { - printf("%d\t(%d, %d), (%d, %d)\n", + DEBUG_MSG("%d\t(%d, %d), (%d, %d)\n", IDcount, lprcMonitor->left, lprcMonitor->top, lprcMonitor->right, lprcMonitor->bottom); @@ -93,10 +93,10 @@ int main(int argc, char* argv[]) vscreen_w = GetSystemMetrics(SM_CXVIRTUALSCREEN); vscreen_h = GetSystemMetrics(SM_CYVIRTUALSCREEN); - printf("\n"); + DEBUG_MSG("\n"); EnumDisplayMonitors(NULL, NULL, moncb, 0); IDcount = 0; - printf("\nVirtual Screen = %dx%d\n", vscreen_w, vscreen_h); + DEBUG_MSG("\nVirtual Screen = %dx%d\n", vscreen_w, vscreen_h); } return 0; @@ -108,7 +108,7 @@ int main(int argc, char* argv[]) index++; if (index == argc) { - printf("missing screen id parameter\n"); + DEBUG_MSG("missing screen id parameter\n"); return 0; } @@ -154,13 +154,13 @@ int main(int argc, char* argv[]) } } - printf("Starting server\n"); + DEBUG_MSG("Starting server\n"); wfreerdp_server_start(server); WaitForSingleObject(server->thread, INFINITE); - printf("Stopping server\n"); + DEBUG_MSG("Stopping server\n"); wfreerdp_server_stop(server); wfreerdp_server_free(server); diff --git a/server/Windows/wf_directsound.c b/server/Windows/wf_directsound.c index 22190c96f..74c66adb9 100644 --- a/server/Windows/wf_directsound.c +++ b/server/Windows/wf_directsound.c @@ -35,7 +35,7 @@ int wf_directsound_activate(RdpsndServerContext* context) wfi = wf_info_get_instance(); - printf("RDPSND (direct sound) Activated\n"); + DEBUG_MSG("RDPSND (direct sound) Activated\n"); hr = DirectSoundCaptureCreate8(NULL, &cap, NULL); diff --git a/server/Windows/wf_dxgi.c b/server/Windows/wf_dxgi.c index dd5ac3421..fdaacca2d 100644 --- a/server/Windows/wf_dxgi.c +++ b/server/Windows/wf_dxgi.c @@ -23,7 +23,7 @@ #include "wf_interface.h" -#ifdef WITH_WIN8 +#ifdef WITH_DXGI_1_2 #define CINTERFACE @@ -67,7 +67,6 @@ DXGI_OUTDUPL_FRAME_INFO FrameInfo; int wf_dxgi_init(wfInfo* wfi) { - //not sure if needed gAcquiredDesktopImage = NULL; if (wf_dxgi_createDevice(wfi) != 0) @@ -81,7 +80,6 @@ int wf_dxgi_init(wfInfo* wfi) } return 0; - } int wf_dxgi_createDevice(wfInfo* wfi) diff --git a/server/Windows/wf_info.c b/server/Windows/wf_info.c index c49d352df..4300c5513 100644 --- a/server/Windows/wf_info.c +++ b/server/Windows/wf_info.c @@ -52,7 +52,7 @@ int wf_info_lock(wfInfo* wfi) break; case WAIT_FAILED: - printf("wf_info_lock failed with 0x%08X\n", GetLastError()); + DEBUG_WARN("wf_info_lock failed with 0x%08X\n", GetLastError()); return -1; break; } @@ -78,7 +78,7 @@ int wf_info_try_lock(wfInfo* wfi, DWORD dwMilliseconds) break; case WAIT_FAILED: - printf("wf_info_try_lock failed with 0x%08X\n", GetLastError()); + DEBUG_WARN("wf_info_try_lock failed with 0x%08X\n", GetLastError()); return -1; break; } @@ -90,7 +90,7 @@ int wf_info_unlock(wfInfo* wfi) { if (ReleaseMutex(wfi->mutex) == 0) { - printf("wf_info_unlock failed with 0x%08X\n", GetLastError()); + DEBUG_WARN("wf_info_unlock failed with 0x%08X\n", GetLastError()); return -1; } @@ -188,7 +188,7 @@ void wf_info_peer_register(wfInfo* wfi, wfPeerContext* context) EnumDisplayMonitors(NULL, NULL, wf_info_monEnumCB, 0); _IDcount = 0; -#ifdef WITH_WIN8 +#ifdef WITH_DXGI_1_2 if (wfi->peerCount == 0) wf_dxgi_init(wfi); #else @@ -213,7 +213,7 @@ void wf_info_peer_register(wfInfo* wfi, wfPeerContext* context) wfi->peers[peerId] = ((rdpContext*) context)->peer; wfi->peers[peerId]->pId = peerId; wfi->peerCount++; - printf("Registering Peer: id=%d #=%d\n", peerId, wfi->peerCount); + DEBUG_WARN("Registering Peer: id=%d #=%d\n", peerId, wfi->peerCount); wf_info_unlock(wfi); @@ -232,9 +232,9 @@ void wf_info_peer_unregister(wfInfo* wfi, wfPeerContext* context) wfi->peerCount--; CloseHandle(context->updateEvent); - printf("Unregistering Peer: id=%d, #=%d\n", peerId, wfi->peerCount); + DEBUG_WARN("Unregistering Peer: id=%d, #=%d\n", peerId, wfi->peerCount); -#ifdef WITH_WIN8 +#ifdef WITH_DXGI_1_2 if (wfi->peerCount == 0) wf_dxgi_cleanup(wfi); #endif @@ -247,7 +247,7 @@ void wf_info_peer_unregister(wfInfo* wfi, wfPeerContext* context) BOOL wf_info_have_updates(wfInfo* wfi) { -#ifdef WITH_WIN8 +#ifdef WITH_DXGI_1_2 if(wfi->framesWaiting == 0) return FALSE; #else @@ -259,7 +259,7 @@ BOOL wf_info_have_updates(wfInfo* wfi) void wf_info_update_changes(wfInfo* wfi) { -#ifdef WITH_WIN8 +#ifdef WITH_DXGI_1_2 wf_dxgi_nextFrame(wfi, wfi->framesPerSecond * 1000); #else GETCHANGESBUF* buf; @@ -271,7 +271,7 @@ void wf_info_update_changes(wfInfo* wfi) void wf_info_find_invalid_region(wfInfo* wfi) { -#ifdef WITH_WIN8 +#ifdef WITH_DXGI_1_2 wf_dxgi_getInvalidRegion(&wfi->invalid); #else int i; @@ -334,7 +334,7 @@ void wf_info_getScreenData(wfInfo* wfi, long* width, long* height, BYTE** pBits, *width = (wfi->invalid.right - wfi->invalid.left); *height = (wfi->invalid.bottom - wfi->invalid.top); -#ifdef WITH_WIN8 +#ifdef WITH_DXGI_1_2 wf_dxgi_getPixelData(wfi, pBits, pitch, &wfi->invalid); #else { diff --git a/server/Windows/wf_info.h b/server/Windows/wf_info.h index d1dc44f2b..38a3ae6c6 100644 --- a/server/Windows/wf_info.h +++ b/server/Windows/wf_info.h @@ -1,45 +1,45 @@ -/** - * FreeRDP: A Remote Desktop Protocol Implementation - * FreeRDP Windows Server - * - * Copyright 2012 Corey Clayton - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef WF_INFO_H -#define WF_INFO_H - -#include "wf_interface.h" - -#define WF_INFO_DEFAULT_FPS 24 -#define WF_INFO_MAXPEERS 32 - -int wf_info_lock(wfInfo* wfi); -int wf_info_try_lock(wfInfo* wfi, DWORD dwMilliseconds); -int wf_info_unlock(wfInfo* wfi); - -wfInfo* wf_info_get_instance(void); -void wf_info_peer_register(wfInfo* wfi, wfPeerContext* context); -void wf_info_peer_unregister(wfInfo* wfi, wfPeerContext* context); - -BOOL wf_info_have_updates(wfInfo* wfi); -void wf_info_update_changes(wfInfo* wfi); -void wf_info_find_invalid_region(wfInfo* wfi); -void wf_info_clear_invalid_region(wfInfo* wfi); -void wf_info_invalidate_full_screen(wfInfo* wfi); -BOOL wf_info_have_invalid_region(wfInfo* wfi); -void wf_info_getScreenData(wfInfo* wfi, long* width, long* height, BYTE** pBits, int* pitch); -BOOL CALLBACK wf_info_monEnumCB(HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMonitor, LPARAM dwData); - -#endif /* WF_INFO_H */ +/** + * FreeRDP: A Remote Desktop Protocol Implementation + * FreeRDP Windows Server + * + * Copyright 2012 Corey Clayton + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef WF_INFO_H +#define WF_INFO_H + +#include "wf_interface.h" + +#define WF_INFO_DEFAULT_FPS 24 +#define WF_INFO_MAXPEERS 32 + +int wf_info_lock(wfInfo* wfi); +int wf_info_try_lock(wfInfo* wfi, DWORD dwMilliseconds); +int wf_info_unlock(wfInfo* wfi); + +wfInfo* wf_info_get_instance(void); +void wf_info_peer_register(wfInfo* wfi, wfPeerContext* context); +void wf_info_peer_unregister(wfInfo* wfi, wfPeerContext* context); + +BOOL wf_info_have_updates(wfInfo* wfi); +void wf_info_update_changes(wfInfo* wfi); +void wf_info_find_invalid_region(wfInfo* wfi); +void wf_info_clear_invalid_region(wfInfo* wfi); +void wf_info_invalidate_full_screen(wfInfo* wfi); +BOOL wf_info_have_invalid_region(wfInfo* wfi); +void wf_info_getScreenData(wfInfo* wfi, long* width, long* height, BYTE** pBits, int* pitch); +BOOL CALLBACK wf_info_monEnumCB(HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMonitor, LPARAM dwData); + +#endif /* WF_INFO_H */ diff --git a/server/Windows/wf_input.c b/server/Windows/wf_input.c index 06b9f5350..7c70748fa 100644 --- a/server/Windows/wf_input.c +++ b/server/Windows/wf_input.c @@ -158,8 +158,6 @@ void wf_peer_extended_mouse_event(rdpInput* input, UINT16 flags, UINT16 x, UINT1 x += wfi->servscreen_xoffset; y += wfi->servscreen_yoffset; - //mouse_event.mi.dx = x * (0xFFFF / width); - //mouse_event.mi.dy = y * (0xFFFF / height); mouse_event.mi.dx = (LONG) ((float) x * (65535.0f / width)); mouse_event.mi.dy = (LONG) ((float) y * (65535.0f / height)); mouse_event.mi.dwFlags = MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE; diff --git a/server/Windows/wf_interface.c b/server/Windows/wf_interface.c index ea0e98d46..80262649d 100644 --- a/server/Windows/wf_interface.c +++ b/server/Windows/wf_interface.c @@ -102,7 +102,7 @@ DWORD WINAPI wf_server_main_loop(LPVOID lpParam) if (instance->GetFileDescriptor(instance, rfds, &rcount) != TRUE) { - printf("Failed to get FreeRDP file descriptor\n"); + DEBUG_WARN("Failed to get FreeRDP file descriptor\n"); break; } @@ -127,12 +127,12 @@ DWORD WINAPI wf_server_main_loop(LPVOID lpParam) if (instance->CheckFileDescriptor(instance) != TRUE) { - printf("Failed to check FreeRDP file descriptor\n"); + DEBUG_WARN("Failed to check FreeRDP file descriptor\n"); break; } } - printf("wf_server_main_loop terminating\n"); + DEBUG_WARN("wf_server_main_loop terminating\n"); instance->Close(instance); @@ -164,7 +164,7 @@ BOOL wfreerdp_server_stop(wfServer* server) wfi = wf_info_get_instance(); - printf("Stopping server\n"); + DEBUG_WARN("Stopping server\n"); wfi->force_all_disconnect = TRUE; server->instance->Close(server->instance); return TRUE; @@ -210,7 +210,7 @@ FREERDP_API BOOL wfreerdp_server_is_running(wfServer* server) bRet = GetExitCodeThread(server->thread, &tStatus); if (bRet == 0) { - printf("Error in call to GetExitCodeThread\n"); + DEBUG_WARN("Error in call to GetExitCodeThread\n"); return FALSE; } @@ -245,7 +245,7 @@ FREERDP_API UINT32 wfreerdp_server_get_peer_hostname(int pId, wchar_t * dstStr) } else { - printf("nonexistent peer id=%d\n", pId); + DEBUG_WARN("nonexistent peer id=%d\n", pId); return 0; } } diff --git a/server/Windows/wf_interface.h b/server/Windows/wf_interface.h index dc3af1c7f..9a2c72215 100644 --- a/server/Windows/wf_interface.h +++ b/server/Windows/wf_interface.h @@ -29,9 +29,14 @@ #include #include +#include #include +#if _WIN32_WINNT >= 0x0602 +#define WITH_DXGI_1_2 1 +#endif + #define WF_SRV_CALLBACK_EVENT_CONNECT 1 #define WF_SRV_CALLBACK_EVENT_DISCONNECT 2 #define WF_SRV_CALLBACK_EVENT_ACTIVATE 4 @@ -52,8 +57,6 @@ struct wf_info int servscreen_height; int servscreen_xoffset; int servscreen_yoffset; - //int width; - //int height; int frame_idx; int bitsPerPixel; diff --git a/server/Windows/wf_mirage.c b/server/Windows/wf_mirage.c index baafd031f..be1fedca1 100644 --- a/server/Windows/wf_mirage.c +++ b/server/Windows/wf_mirage.c @@ -92,9 +92,9 @@ BOOL wf_mirror_driver_display_device_attach(wfInfo* wfi, DWORD mode) if (status != ERROR_SUCCESS) { - printf("Error opening RegKey: status=%0X\n", status); + DEBUG_WARN("Error opening RegKey: status=%0X\n", status); if (status == ERROR_ACCESS_DENIED) - printf("access denied. Do you have admin privleges?\n"); + DEBUG_WARN("access denied. Do you have admin privleges?\n"); return FALSE; } @@ -104,9 +104,9 @@ BOOL wf_mirror_driver_display_device_attach(wfInfo* wfi, DWORD mode) if (status != ERROR_SUCCESS) { - printf("Error querying RegKey: status=%0X\n", status); + DEBUG_WARN("Error querying RegKey: status=%0X\n", status); if (status == ERROR_ACCESS_DENIED) - printf("access denied. Do you have admin privleges?\n"); + DEBUG_WARN("access denied. Do you have admin privleges?\n"); return FALSE; } @@ -120,10 +120,10 @@ BOOL wf_mirror_driver_display_device_attach(wfInfo* wfi, DWORD mode) if (status != ERROR_SUCCESS) { - printf("Error writing registry key: %d ", status); + DEBUG_WARN("Error writing registry key: %d ", status); if (status == ERROR_ACCESS_DENIED) - printf("access denied. Do you have admin privleges?"); - printf("\n"); + DEBUG_WARN("access denied. Do you have admin privleges?"); + DEBUG_WARN("\n"); return FALSE; } } @@ -199,7 +199,7 @@ BOOL wf_mirror_driver_update(wfInfo* wfi, int mode) if ( (mode != MIRROR_LOAD) && (mode != MIRROR_UNLOAD) ) { - printf("Invalid mirror mode!\n"); + DEBUG_WARN("Invalid mirror mode!\n"); return FALSE; } @@ -321,29 +321,29 @@ BOOL wf_mirror_driver_activate(wfInfo* wfi) { if (!wfi->mirrorDriverActive) { - printf("Activating Mirror Driver\n"); + DEBUG_WARN("Activating Mirror Driver\n"); if (wf_mirror_driver_find_display_device(wfi) == FALSE) { - printf("Could not find dfmirage mirror driver! Is it installed?\n"); + DEBUG_WARN("Could not find dfmirage mirror driver! Is it installed?\n"); return FALSE; } if (wf_mirror_driver_display_device_attach(wfi, 1) == FALSE) { - printf("Could not attach display device!\n"); + DEBUG_WARN("Could not attach display device!\n"); return FALSE; } if (wf_mirror_driver_update(wfi, MIRROR_LOAD) == FALSE) { - printf("could not update system with new display settings!\n"); + DEBUG_WARN("could not update system with new display settings!\n"); return FALSE; } if (wf_mirror_driver_map_memory(wfi) == FALSE) { - printf("Unable to map memory for mirror driver!\n"); + DEBUG_WARN("Unable to map memory for mirror driver!\n"); return FALSE; } wfi->mirrorDriverActive = TRUE; @@ -356,7 +356,7 @@ void wf_mirror_driver_deactivate(wfInfo* wfi) { if (wfi->mirrorDriverActive) { - printf("Deactivating Mirror Driver\n"); + DEBUG_WARN("Deactivating Mirror Driver\n"); wf_mirror_driver_cleanup(wfi); wf_mirror_driver_display_device_attach(wfi, 0); diff --git a/server/Windows/wf_mirage.h b/server/Windows/wf_mirage.h index 9ddfb8096..372e02bbe 100644 --- a/server/Windows/wf_mirage.h +++ b/server/Windows/wf_mirage.h @@ -1,221 +1,221 @@ -/** - * FreeRDP: A Remote Desktop Protocol Implementation - * FreeRDP Windows Server - * - * Copyright 2012 Marc-Andre Moreau - * Copyright 2012-2013 Corey Clayton - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef WF_MIRAGE_H -#define WF_MIRAGE_H - -#include "wf_interface.h" - -enum -{ - MIRROR_LOAD = 0, - MIRROR_UNLOAD = 1 -}; - - - -enum -{ - DMF_ESCAPE_BASE_1_VB = 1030, - DMF_ESCAPE_BASE_2_VB = 1026, - DMF_ESCAPE_BASE_3_VB = 24 -}; - -#ifdef _WIN64 - -#define CLIENT_64BIT 0x8000 - -enum -{ - DMF_ESCAPE_BASE_1 = CLIENT_64BIT | DMF_ESCAPE_BASE_1_VB, - DMF_ESCAPE_BASE_2 = CLIENT_64BIT | DMF_ESCAPE_BASE_2_VB, - DMF_ESCAPE_BASE_3 = CLIENT_64BIT | DMF_ESCAPE_BASE_3_VB, -}; - -#else - -enum -{ - DMF_ESCAPE_BASE_1 = DMF_ESCAPE_BASE_1_VB, - DMF_ESCAPE_BASE_2 = DMF_ESCAPE_BASE_2_VB, - DMF_ESCAPE_BASE_3 = DMF_ESCAPE_BASE_3_VB, -}; - -#endif - -typedef enum -{ - dmf_esc_qry_ver_info = DMF_ESCAPE_BASE_2 + 0, - dmf_esc_usm_pipe_map = DMF_ESCAPE_BASE_1 + 0, - dmf_esc_usm_pipe_unmap = DMF_ESCAPE_BASE_1 + 1, - dmf_esc_test = DMF_ESCAPE_BASE_1 + 20, - dmf_esc_usm_pipe_mapping_test = DMF_ESCAPE_BASE_1 + 21, - dmf_esc_pointer_shape_get = DMF_ESCAPE_BASE_3, - -} dmf_escape; - -#define CLIP_LIMIT 50 -#define MAXCHANGES_BUF 20000 - -typedef enum -{ - dmf_dfo_IGNORE = 0, - dmf_dfo_FROM_SCREEN = 1, - dmf_dfo_FROM_DIB = 2, - dmf_dfo_TO_SCREEN = 3, - dmf_dfo_SCREEN_SCREEN = 11, - dmf_dfo_BLIT = 12, - dmf_dfo_SOLIDFILL = 13, - dmf_dfo_BLEND = 14, - dmf_dfo_TRANS = 15, - dmf_dfo_PLG = 17, - dmf_dfo_TEXTOUT = 18, - dmf_dfo_Ptr_Shape = 19, - dmf_dfo_Ptr_Engage = 48, - dmf_dfo_Ptr_Avert = 49, - dmf_dfn_assert_on = 64, - dmf_dfn_assert_off = 65, -} dmf_UpdEvent; - -#define NOCACHE 1 -#define OLDCACHE 2 -#define NEWCACHE 3 - -typedef struct -{ - ULONG type; - RECT rect; -#ifndef DFMIRAGE_LEAN - RECT origrect; - POINT point; - ULONG color; - ULONG refcolor; -#endif -} CHANGES_RECORD; - -typedef CHANGES_RECORD* PCHANGES_RECORD; - -typedef struct -{ - ULONG counter; - CHANGES_RECORD pointrect[MAXCHANGES_BUF]; -} CHANGES_BUF; - -#define EXT_DEVMODE_SIZE_MAX 3072 -#define DMF_PIPE_SEC_SIZE_DEFAULT ALIGN64K(sizeof(CHANGES_BUF)) - -typedef struct -{ - CHANGES_BUF* buffer; - PVOID Userbuffer; -} GETCHANGESBUF; - -#define dmf_sprb_ERRORMASK 0x07FF -#define dmf_sprb_STRICTSESSION_AFF 0x1FFF - -typedef enum -{ - dmf_sprb_internal_error = 0x0001, - dmf_sprb_miniport_gen_error = 0x0004, - dmf_sprb_memory_alloc_failed = 0x0008, - dmf_sprb_pipe_buff_overflow = 0x0010, - dmf_sprb_pipe_buff_insufficient = 0x0020, - dmf_sprb_pipe_not_ready = 0x0040, - dmf_sprb_gdi_err = 0x0100, - dmf_sprb_owner_died = 0x0400, - dmf_sprb_tgtwnd_gone = 0x0800, - dmf_sprb_pdev_detached = 0x2000, -} dmf_session_prob_status; - -#define DMF_ESC_RET_FAILF 0x80000000 -#define DMF_ESC_RET_SSTMASK 0x0000FFFF -#define DMF_ESC_RET_IMMMASK 0x7FFF0000 - -typedef enum -{ - dmf_escret_generic_ok = 0x00010000, - dmf_escret_bad_state = 0x00100000, - dmf_escret_access_denied = 0x00200000, - dmf_escret_bad_buffer_size = 0x00400000, - dmf_escret_internal_err = 0x00800000, - dmf_escret_out_of_memory = 0x02000000, - dmf_escret_already_connected = 0x04000000, - dmf_escret_oh_boy_too_late = 0x08000000, - dmf_escret_bad_window = 0x10000000, - dmf_escret_drv_ver_higher = 0x20000000, - dmf_escret_drv_ver_lower = 0x40000000, -} dmf_esc_retcode; - -typedef struct -{ - ULONG cbSize; - ULONG app_actual_version; - ULONG display_minreq_version; - ULONG connect_options; -} Esc_dmf_Qvi_IN; - -enum -{ - esc_qvi_prod_name_max = 16, -}; - -#define ESC_QVI_PROD_MIRAGE "MIRAGE" -#define ESC_QVI_PROD_QUASAR "QUASAR" - -typedef struct -{ - ULONG cbSize; - ULONG display_actual_version; - ULONG miniport_actual_version; - ULONG app_minreq_version; - ULONG display_buildno; - ULONG miniport_buildno; - char prod_name[esc_qvi_prod_name_max]; -} Esc_dmf_Qvi_OUT; - -typedef struct -{ - ULONG cbSize; - char* pDstBmBuf; - ULONG nDstBmBufSize; -} Esc_dmf_pointer_shape_get_IN; - -typedef struct -{ - ULONG cbSize; - POINTL BmSize; - char* pMaskBm; - ULONG nMaskBmSize; - char* pColorBm; - ULONG nColorBmSize; - char* pColorBmPal; - ULONG nColorBmPalEntries; -} Esc_dmf_pointer_shape_get_OUT; - -BOOL wf_mirror_driver_find_display_device(wfInfo* wfi); -BOOL wf_mirror_driver_display_device_attach(wfInfo* wfi, DWORD mode); -BOOL wf_mirror_driver_update(wfInfo* wfi, int mode); -BOOL wf_mirror_driver_map_memory(wfInfo* wfi); -BOOL wf_mirror_driver_cleanup(wfInfo* wfi); - -BOOL wf_mirror_driver_activate(wfInfo* wfi); -void wf_mirror_driver_deactivate(wfInfo* wfi); - -#endif /* WF_MIRAGE_H */ +/** + * FreeRDP: A Remote Desktop Protocol Implementation + * FreeRDP Windows Server + * + * Copyright 2012 Marc-Andre Moreau + * Copyright 2012-2013 Corey Clayton + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef WF_MIRAGE_H +#define WF_MIRAGE_H + +#include "wf_interface.h" + +enum +{ + MIRROR_LOAD = 0, + MIRROR_UNLOAD = 1 +}; + + + +enum +{ + DMF_ESCAPE_BASE_1_VB = 1030, + DMF_ESCAPE_BASE_2_VB = 1026, + DMF_ESCAPE_BASE_3_VB = 24 +}; + +#ifdef _WIN64 + +#define CLIENT_64BIT 0x8000 + +enum +{ + DMF_ESCAPE_BASE_1 = CLIENT_64BIT | DMF_ESCAPE_BASE_1_VB, + DMF_ESCAPE_BASE_2 = CLIENT_64BIT | DMF_ESCAPE_BASE_2_VB, + DMF_ESCAPE_BASE_3 = CLIENT_64BIT | DMF_ESCAPE_BASE_3_VB, +}; + +#else + +enum +{ + DMF_ESCAPE_BASE_1 = DMF_ESCAPE_BASE_1_VB, + DMF_ESCAPE_BASE_2 = DMF_ESCAPE_BASE_2_VB, + DMF_ESCAPE_BASE_3 = DMF_ESCAPE_BASE_3_VB, +}; + +#endif + +typedef enum +{ + dmf_esc_qry_ver_info = DMF_ESCAPE_BASE_2 + 0, + dmf_esc_usm_pipe_map = DMF_ESCAPE_BASE_1 + 0, + dmf_esc_usm_pipe_unmap = DMF_ESCAPE_BASE_1 + 1, + dmf_esc_test = DMF_ESCAPE_BASE_1 + 20, + dmf_esc_usm_pipe_mapping_test = DMF_ESCAPE_BASE_1 + 21, + dmf_esc_pointer_shape_get = DMF_ESCAPE_BASE_3, + +} dmf_escape; + +#define CLIP_LIMIT 50 +#define MAXCHANGES_BUF 20000 + +typedef enum +{ + dmf_dfo_IGNORE = 0, + dmf_dfo_FROM_SCREEN = 1, + dmf_dfo_FROM_DIB = 2, + dmf_dfo_TO_SCREEN = 3, + dmf_dfo_SCREEN_SCREEN = 11, + dmf_dfo_BLIT = 12, + dmf_dfo_SOLIDFILL = 13, + dmf_dfo_BLEND = 14, + dmf_dfo_TRANS = 15, + dmf_dfo_PLG = 17, + dmf_dfo_TEXTOUT = 18, + dmf_dfo_Ptr_Shape = 19, + dmf_dfo_Ptr_Engage = 48, + dmf_dfo_Ptr_Avert = 49, + dmf_dfn_assert_on = 64, + dmf_dfn_assert_off = 65, +} dmf_UpdEvent; + +#define NOCACHE 1 +#define OLDCACHE 2 +#define NEWCACHE 3 + +typedef struct +{ + ULONG type; + RECT rect; +#ifndef DFMIRAGE_LEAN + RECT origrect; + POINT point; + ULONG color; + ULONG refcolor; +#endif +} CHANGES_RECORD; + +typedef CHANGES_RECORD* PCHANGES_RECORD; + +typedef struct +{ + ULONG counter; + CHANGES_RECORD pointrect[MAXCHANGES_BUF]; +} CHANGES_BUF; + +#define EXT_DEVMODE_SIZE_MAX 3072 +#define DMF_PIPE_SEC_SIZE_DEFAULT ALIGN64K(sizeof(CHANGES_BUF)) + +typedef struct +{ + CHANGES_BUF* buffer; + PVOID Userbuffer; +} GETCHANGESBUF; + +#define dmf_sprb_ERRORMASK 0x07FF +#define dmf_sprb_STRICTSESSION_AFF 0x1FFF + +typedef enum +{ + dmf_sprb_internal_error = 0x0001, + dmf_sprb_miniport_gen_error = 0x0004, + dmf_sprb_memory_alloc_failed = 0x0008, + dmf_sprb_pipe_buff_overflow = 0x0010, + dmf_sprb_pipe_buff_insufficient = 0x0020, + dmf_sprb_pipe_not_ready = 0x0040, + dmf_sprb_gdi_err = 0x0100, + dmf_sprb_owner_died = 0x0400, + dmf_sprb_tgtwnd_gone = 0x0800, + dmf_sprb_pdev_detached = 0x2000, +} dmf_session_prob_status; + +#define DMF_ESC_RET_FAILF 0x80000000 +#define DMF_ESC_RET_SSTMASK 0x0000FFFF +#define DMF_ESC_RET_IMMMASK 0x7FFF0000 + +typedef enum +{ + dmf_escret_generic_ok = 0x00010000, + dmf_escret_bad_state = 0x00100000, + dmf_escret_access_denied = 0x00200000, + dmf_escret_bad_buffer_size = 0x00400000, + dmf_escret_internal_err = 0x00800000, + dmf_escret_out_of_memory = 0x02000000, + dmf_escret_already_connected = 0x04000000, + dmf_escret_oh_boy_too_late = 0x08000000, + dmf_escret_bad_window = 0x10000000, + dmf_escret_drv_ver_higher = 0x20000000, + dmf_escret_drv_ver_lower = 0x40000000, +} dmf_esc_retcode; + +typedef struct +{ + ULONG cbSize; + ULONG app_actual_version; + ULONG display_minreq_version; + ULONG connect_options; +} Esc_dmf_Qvi_IN; + +enum +{ + esc_qvi_prod_name_max = 16, +}; + +#define ESC_QVI_PROD_MIRAGE "MIRAGE" +#define ESC_QVI_PROD_QUASAR "QUASAR" + +typedef struct +{ + ULONG cbSize; + ULONG display_actual_version; + ULONG miniport_actual_version; + ULONG app_minreq_version; + ULONG display_buildno; + ULONG miniport_buildno; + char prod_name[esc_qvi_prod_name_max]; +} Esc_dmf_Qvi_OUT; + +typedef struct +{ + ULONG cbSize; + char* pDstBmBuf; + ULONG nDstBmBufSize; +} Esc_dmf_pointer_shape_get_IN; + +typedef struct +{ + ULONG cbSize; + POINTL BmSize; + char* pMaskBm; + ULONG nMaskBmSize; + char* pColorBm; + ULONG nColorBmSize; + char* pColorBmPal; + ULONG nColorBmPalEntries; +} Esc_dmf_pointer_shape_get_OUT; + +BOOL wf_mirror_driver_find_display_device(wfInfo* wfi); +BOOL wf_mirror_driver_display_device_attach(wfInfo* wfi, DWORD mode); +BOOL wf_mirror_driver_update(wfInfo* wfi, int mode); +BOOL wf_mirror_driver_map_memory(wfInfo* wfi); +BOOL wf_mirror_driver_cleanup(wfInfo* wfi); + +BOOL wf_mirror_driver_activate(wfInfo* wfi); +void wf_mirror_driver_deactivate(wfInfo* wfi); + +#endif /* WF_MIRAGE_H */ diff --git a/server/Windows/wf_peer.c b/server/Windows/wf_peer.c index e214a007d..4a03d1bf9 100644 --- a/server/Windows/wf_peer.c +++ b/server/Windows/wf_peer.c @@ -92,7 +92,7 @@ BOOL wf_peer_post_connect(freerdp_peer* client) if ((settings->DesktopWidth != wfi->servscreen_width) || (settings->DesktopHeight != wfi->servscreen_height)) { /* - printf("Client requested resolution %dx%d, but will resize to %dx%d\n", + DEBUG_WARN("Client requested resolution %dx%d, but will resize to %dx%d\n", settings->DesktopWidth, settings->DesktopHeight, wfi->servscreen_width, wfi->servscreen_height); */ @@ -127,14 +127,6 @@ BOOL wf_peer_activate(freerdp_peer* client) BOOL wf_peer_logon(freerdp_peer* client, SEC_WINNT_AUTH_IDENTITY* identity, BOOL automatic) { - /* - if (automatic) - { - _tprintf(_T("Logon: User:%s Domain:%s Password:%s\n"), - identity->User, identity->Domain, identity->Password); - } - */ - wfreerdp_server_peer_callback_event(((rdpContext*) client->context)->peer->pId, WF_SRV_CALLBACK_EVENT_AUTH); return TRUE; } @@ -256,7 +248,7 @@ DWORD WINAPI wf_peer_main_loop(LPVOID lpParam) if (wfi->input_disabled) { - printf("client input is disabled\n"); + DEBUG_WARN("client input is disabled\n"); client->input->KeyboardEvent = wf_peer_keyboard_event_dummy; client->input->UnicodeKeyboardEvent = wf_peer_unicode_keyboard_event_dummy; client->input->MouseEvent = wf_peer_mouse_event_dummy; @@ -268,7 +260,7 @@ DWORD WINAPI wf_peer_main_loop(LPVOID lpParam) context->socketSemaphore = CreateSemaphore(NULL, 0, 1, NULL); context->socketThread = CreateThread(NULL, 0, wf_peer_socket_listener, client, 0, NULL); - printf("We've got a client %s\n", client->local ? "(local)" : client->hostname); + DEBUG_WARN("We've got a client %s\n", client->local ? "(local)" : client->hostname); nCount = 0; handles[nCount++] = context->updateEvent; @@ -280,7 +272,7 @@ DWORD WINAPI wf_peer_main_loop(LPVOID lpParam) if ((status == WAIT_FAILED) || (status == WAIT_TIMEOUT)) { - printf("WaitForMultipleObjects failed\n"); + DEBUG_WARN("WaitForMultipleObjects failed\n"); break; } @@ -311,7 +303,7 @@ DWORD WINAPI wf_peer_main_loop(LPVOID lpParam) //force disconnect if (wfi->force_all_disconnect == TRUE) { - printf("Forcing Disconnect -> "); + DEBUG_WARN("Forcing Disconnect -> "); break; } @@ -320,7 +312,7 @@ DWORD WINAPI wf_peer_main_loop(LPVOID lpParam) break; } - printf("Client %s disconnected.\n", client->local ? "(local)" : client->hostname); + DEBUG_WARN("Client %s disconnected.\n", client->local ? "(local)" : client->hostname); if (WaitForSingleObject(context->updateEvent, 0) == 0) { diff --git a/server/Windows/wf_peer.h b/server/Windows/wf_peer.h index a825b9652..7d96d9146 100644 --- a/server/Windows/wf_peer.h +++ b/server/Windows/wf_peer.h @@ -1,51 +1,51 @@ -/** - * FreeRDP: A Remote Desktop Protocol Implementation - * FreeRDP Windows Server - * - * Copyright 2012 Marc-Andre Moreau - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef WF_PEER_H -#define WF_PEER_H - -#include "wf_interface.h" - -#include - - - -void wf_peer_context_new(freerdp_peer* client, wfPeerContext* context); -void wf_peer_context_free(freerdp_peer* client, wfPeerContext* context); - -void wf_peer_init(freerdp_peer* client); - -void wf_dxgi_encode(freerdp_peer* client, UINT timeout); -void wf_rfx_encode(freerdp_peer* client); - -BOOL wf_peer_post_connect(freerdp_peer* client); -BOOL wf_peer_activate(freerdp_peer* client); - -void wf_peer_synchronize_event(rdpInput* input, UINT32 flags); - -void wf_peer_send_changes(freerdp_peer* client); - -void wf_detect_win_ver(void); - -void wf_peer_accepted(freerdp_listener* instance, freerdp_peer* client); - -DWORD WINAPI wf_peer_main_loop(LPVOID lpParam); - - -#endif /* WF_PEER_H */ +/** + * FreeRDP: A Remote Desktop Protocol Implementation + * FreeRDP Windows Server + * + * Copyright 2012 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef WF_PEER_H +#define WF_PEER_H + +#include "wf_interface.h" + +#include + + + +void wf_peer_context_new(freerdp_peer* client, wfPeerContext* context); +void wf_peer_context_free(freerdp_peer* client, wfPeerContext* context); + +void wf_peer_init(freerdp_peer* client); + +void wf_dxgi_encode(freerdp_peer* client, UINT timeout); +void wf_rfx_encode(freerdp_peer* client); + +BOOL wf_peer_post_connect(freerdp_peer* client); +BOOL wf_peer_activate(freerdp_peer* client); + +void wf_peer_synchronize_event(rdpInput* input, UINT32 flags); + +void wf_peer_send_changes(freerdp_peer* client); + +void wf_detect_win_ver(void); + +void wf_peer_accepted(freerdp_listener* instance, freerdp_peer* client); + +DWORD WINAPI wf_peer_main_loop(LPVOID lpParam); + + +#endif /* WF_PEER_H */ diff --git a/server/Windows/wf_rdpsnd.c b/server/Windows/wf_rdpsnd.c index c37ab0570..004de3e1e 100644 --- a/server/Windows/wf_rdpsnd.c +++ b/server/Windows/wf_rdpsnd.c @@ -54,7 +54,7 @@ static void wf_peer_rdpsnd_activated(RdpsndServerContext* context) wfi = wf_info_get_instance(); wfi->agreed_format = NULL; - printf("Client supports the following %d formats: \n", context->num_client_formats); + DEBUG_WARN("Client supports the following %d formats: \n", context->num_client_formats); for(i = 0; i < context->num_client_formats; i++) { //TODO: improve the way we agree on a format @@ -64,7 +64,7 @@ static void wf_peer_rdpsnd_activated(RdpsndServerContext* context) (context->client_formats[i].nChannels == context->server_formats[j].nChannels) && (context->client_formats[i].nSamplesPerSec == context->server_formats[j].nSamplesPerSec)) { - printf("agreed on format!\n"); + DEBUG_WARN("agreed on format!\n"); wfi->agreed_format = (AUDIO_FORMAT*) &context->server_formats[j]; break; } @@ -76,7 +76,7 @@ static void wf_peer_rdpsnd_activated(RdpsndServerContext* context) if (wfi->agreed_format == NULL) { - printf("Could not agree on a audio format with the server\n"); + DEBUG_WARN("Could not agree on a audio format with the server\n"); return; } @@ -116,7 +116,7 @@ int wf_rdpsnd_lock() break; case WAIT_FAILED: - printf("wf_rdpsnd_lock failed with 0x%08X\n", GetLastError()); + DEBUG_WARN("wf_rdpsnd_lock failed with 0x%08X\n", GetLastError()); return -1; break; } @@ -132,7 +132,7 @@ int wf_rdpsnd_unlock() if (ReleaseMutex(wfi->snd_mutex) == 0) { - printf("wf_rdpsnd_unlock failed with 0x%08X\n", GetLastError()); + DEBUG_WARN("wf_rdpsnd_unlock failed with 0x%08X\n", GetLastError()); return -1; } diff --git a/server/Windows/wf_update.c b/server/Windows/wf_update.c index a8488557f..f03763150 100644 --- a/server/Windows/wf_update.c +++ b/server/Windows/wf_update.c @@ -176,7 +176,7 @@ void wf_update_peer_send(wfInfo* wfi, wfPeerContext* context) /* This is an unexpected error condition */ - printf("Unexpected Frame Index: Actual: %d Expected: %d\n", + DEBUG_WARN("Unexpected Frame Index: Actual: %d Expected: %d\n", wfi->frame_idx, context->frame_idx + 1); } @@ -189,7 +189,7 @@ void wf_update_encoder_reset(wfInfo* wfi) { if (wf_info_lock(wfi) > 0) { - printf("Resetting encoder\n"); + DEBUG_WARN("Resetting encoder\n"); if (wfi->rfx_context) { @@ -217,7 +217,7 @@ void wf_update_peer_activate(wfInfo* wfi, wfPeerContext* context) { if (wfi->activePeerCount < 1) { -#ifndef WITH_WIN8 +#ifndef WITH_DXGI_1_2 wf_mirror_driver_activate(wfi); #endif ResumeThread(wfi->updateThread); @@ -226,7 +226,7 @@ void wf_update_peer_activate(wfInfo* wfi, wfPeerContext* context) wf_update_encoder_reset(wfi); wfi->activePeerCount++; - printf("Activating Peer Updates: %d\n", wfi->activePeerCount); + DEBUG_WARN("Activating Peer Updates: %d\n", wfi->activePeerCount); wf_info_unlock(wfi); } @@ -248,7 +248,7 @@ void wf_update_peer_deactivate(wfInfo* wfi, wfPeerContext* context) client->activated = FALSE; wfi->activePeerCount--; - printf("Deactivating Peer Updates: %d\n", wfi->activePeerCount); + DEBUG_WARN("Deactivating Peer Updates: %d\n", wfi->activePeerCount); } wf_info_unlock(wfi); diff --git a/server/Windows/wf_wasapi.c b/server/Windows/wf_wasapi.c index 722ac71f8..a0e1c0137 100644 --- a/server/Windows/wf_wasapi.c +++ b/server/Windows/wf_wasapi.c @@ -45,7 +45,7 @@ int wf_wasapi_activate(RdpsndServerContext* context) return 1; } - printf("RDPSND (WASAPI) Activated\n"); + DEBUG_WARN("RDPSND (WASAPI) Activated\n"); CreateThread(NULL, 0, wf_rdpsnd_wasapi_thread, latestPeer, 0, NULL); diff --git a/server/X11/CMakeLists.txt b/server/X11/CMakeLists.txt deleted file mode 100644 index d60ac3162..000000000 --- a/server/X11/CMakeLists.txt +++ /dev/null @@ -1,167 +0,0 @@ -# FreeRDP: A Remote Desktop Protocol Implementation -# FreeRDP X11 Server cmake build script -# -# Copyright 2012 Marc-Andre Moreau -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -set(MODULE_NAME "xfreerdp-server") -set(MODULE_PREFIX "FREERDP_SERVER_X11_CONTROL") - -include_directories(${X11_INCLUDE_DIRS}) -include_directories("../../winpr/tools/makecert") - -set(${MODULE_PREFIX}_SRCS - xf_peer.c - xf_peer.h - xf_input.c - xf_input.h - xf_encode.c - xf_encode.h - xf_update.c - xf_update.h - xf_cursor.c - xf_cursor.h - xf_monitors.c - xf_monitors.h - xf_interface.c - xf_interface.h - xfreerdp.h) - -if(WITH_SERVER_INTERFACE) - if(SERVER_INTERFACE_SHARED) - add_library(${MODULE_NAME} SHARED ${${MODULE_PREFIX}_SRCS}) - else() - add_library(${MODULE_NAME} ${${MODULE_PREFIX}_SRCS}) - endif() - if (WITH_LIBRARY_VERSIONING) - set_target_properties(${MODULE_NAME} PROPERTIES VERSION ${FREERDP_VERSION} SOVERSION ${FREERDP_API_VERSION}) - endif() - set_target_properties(${MODULE_NAME} PROPERTIES PREFIX "lib") -else() - set(${MODULE_PREFIX}_SRCS ${${MODULE_PREFIX}_SRCS} cli/xfreerdp.c) - add_executable(${MODULE_NAME} ${${MODULE_PREFIX}_SRCS}) - set_target_properties(${MODULE_NAME} PROPERTIES OUTPUT_NAME "xfreerdp-server") -endif() - -set(XEXT_FEATURE_TYPE "RECOMMENDED") -set(XEXT_FEATURE_PURPOSE "X11 extension") -set(XEXT_FEATURE_DESCRIPTION "X11 core extensions") - -set(XSHM_FEATURE_TYPE "RECOMMENDED") -set(XSHM_FEATURE_PURPOSE "X11 shared memory") -set(XSHM_FEATURE_DESCRIPTION "X11 shared memory extension") - -set(XINERAMA_FEATURE_TYPE "RECOMMENDED") -set(XINERAMA_FEATURE_PURPOSE "multi-monitor") -set(XINERAMA_FEATURE_DESCRIPTION "X11 multi-monitor extension") - -set(XTEST_FEATURE_TYPE "RECOMMENDED") -set(XTEST_FEATURE_PURPOSE "X11 input event injection") -set(XTEST_FEATURE_DESCRIPTION "X11 input event injection extension") - -set(XCURSOR_FEATURE_TYPE "RECOMMENDED") -set(XCURSOR_FEATURE_PURPOSE "cursor") -set(XCURSOR_FEATURE_DESCRIPTION "X11 cursor extension") - -set(XFIXES_FEATURE_TYPE "RECOMMENDED") -set(XFIXES_FEATURE_PURPOSE "X11 region") -set(XFIXES_FEATURE_DESCRIPTION "X11 region fix extension") - -set(XRANDR_FEATURE_TYPE "RECOMMENDED") -set(XRANDR_FEATURE_PURPOSE "X11 resize, rotate and reflect") -set(XRANDR_FEATURE_DESCRIPTION "X11 resize, rotate and reflect extension") - -set(XDAMAGE_FEATURE_TYPE "RECOMMENDED") -set(XDAMAGE_FEATURE_PURPOSE "X11 region damage") -set(XDAMAGE_FEATURE_DESCRIPTION "X11 region damage extension") - -find_feature(Xext ${XEXT_FEATURE_TYPE} ${XEXT_FEATURE_PURPOSE} ${XEXT_FEATURE_DESCRIPTION}) -find_feature(XShm ${XSHM_FEATURE_TYPE} ${XSHM_FEATURE_PURPOSE} ${XSHM_FEATURE_DESCRIPTION}) -find_feature(XTest ${XTEST_FEATURE_TYPE} ${XTEST_FEATURE_PURPOSE} ${XTEST_FEATURE_DESCRIPTION}) -find_feature(Xfixes ${XFIXES_FEATURE_TYPE} ${XFIXES_FEATURE_PURPOSE} ${XFIXES_FEATURE_DESCRIPTION}) -find_feature(XRandR ${XRANDR_FEATURE_TYPE} ${XRANDR_FEATURE_PURPOSE} ${XRANDR_FEATURE_DESCRIPTION}) -find_feature(Xdamage ${XDAMAGE_FEATURE_TYPE} ${XDAMAGE_FEATURE_PURPOSE} ${XDAMAGE_FEATURE_DESCRIPTION}) -find_feature(Xcursor ${XCURSOR_FEATURE_TYPE} ${XCURSOR_FEATURE_PURPOSE} ${XCURSOR_FEATURE_DESCRIPTION}) -find_feature(Xinerama ${XINERAMA_FEATURE_TYPE} ${XINERAMA_FEATURE_PURPOSE} ${XINERAMA_FEATURE_DESCRIPTION}) - -if(WITH_XSHM) - add_definitions(-DWITH_XSHM) - include_directories(${XSHM_INCLUDE_DIRS}) -endif() - -if(WITH_XEXT) - add_definitions(-DWITH_XEXT) - include_directories(${XEXT_INCLUDE_DIRS}) - set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} ${XEXT_LIBRARIES}) -endif() - -if(WITH_XINERAMA) - add_definitions(-DWITH_XINERAMA) - include_directories(${XINERAMA_INCLUDE_DIRS}) - set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} ${XINERAMA_LIBRARIES}) -endif() - -if(WITH_XCURSOR) - add_definitions(-DWITH_XCURSOR) - include_directories(${XCURSOR_INCLUDE_DIRS}) - set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} ${XCURSOR_LIBRARIES}) -endif() - -if(WITH_XDAMAGE) - add_definitions(-DWITH_XDAMAGE) - include_directories(${XDAMAGE_INCLUDE_DIRS}) - set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} ${XDAMAGE_LIBRARIES}) -endif() - -if(WITH_XFIXES) - add_definitions(-DWITH_XFIXES) - include_directories(${XFIXES_INCLUDE_DIRS}) - target_link_libraries(${MODULE_NAME} ${XFIXES_LIBRARIES}) - set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} ${XFIXES_LIBRARIES}) -endif() - -if(WITH_XTEST) - add_definitions(-DWITH_XTEST) - include_directories(${XTEST_INCLUDE_DIRS}) - set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} ${XTEST_LIBRARIES}) -endif() - -if(WITH_XRANDR) - add_definitions(-DWITH_XRANDR) - include_directories(${XRANDR_INCLUDE_DIRS}) - set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} ${XRANDR_LIBRARIES}) -endif() - -set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} ${X11_LIBRARIES}) - -set_complex_link_libraries(VARIABLE ${MODULE_PREFIX}_LIBS - MONOLITHIC ${MONOLITHIC_BUILD} - MODULE freerdp - MODULES freerdp-core freerdp-common freerdp-codec freerdp-primitives freerdp-utils freerdp-gdi freerdp-crypto freerdp-locale) - -set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} winpr) - -set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} winpr-makecert-tool) - -target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS}) - -if(WITH_SERVER_INTERFACE) - install(TARGETS ${MODULE_NAME} DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT libraries) - add_subdirectory(cli) -else() - install(TARGETS ${MODULE_NAME} DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT server) -endif() - -set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "Server/X11") - diff --git a/server/X11/ModuleOptions.cmake b/server/X11/ModuleOptions.cmake deleted file mode 100644 index fcba05934..000000000 --- a/server/X11/ModuleOptions.cmake +++ /dev/null @@ -1,4 +0,0 @@ - -set(FREERDP_SERVER_NAME "xfreerdp-server") -set(FREERDP_SERVER_PLATFORM "X11") -set(FREERDP_SERVER_VENDOR "FreeRDP") diff --git a/server/X11/cli/CMakeLists.txt b/server/X11/cli/CMakeLists.txt deleted file mode 100644 index 6d0d45ff3..000000000 --- a/server/X11/cli/CMakeLists.txt +++ /dev/null @@ -1,36 +0,0 @@ -# FreeRDP: A Remote Desktop Protocol Implementation -# FreeRDP X11 cmake build script -# -# Copyright 2012 Marc-Andre Moreau -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -set(MODULE_NAME "xfreerdp-server-cli") -set(MODULE_PREFIX "FREERDP_SERVER_X11") - -include_directories(..) - -set(${MODULE_PREFIX}_SRCS - xfreerdp.c) - -add_executable(${MODULE_NAME} ${${MODULE_PREFIX}_SRCS}) -set_target_properties(${MODULE_NAME} PROPERTIES OUTPUT_NAME "xfreerdp-server" RUNTIME_OUTPUT_DIRECTORY "..") - -set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} xfreerdp-server) - -target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS}) - -install(TARGETS ${MODULE_NAME} RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT server) - -set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "Server/X11") - diff --git a/server/X11/rfx_test.pcap b/server/X11/rfx_test.pcap deleted file mode 100644 index 768c3960f..000000000 Binary files a/server/X11/rfx_test.pcap and /dev/null differ diff --git a/server/X11/server.crt b/server/X11/server.crt deleted file mode 100644 index 7ce931c26..000000000 --- a/server/X11/server.crt +++ /dev/null @@ -1,17 +0,0 @@ ------BEGIN CERTIFICATE----- -MIICyzCCAbOgAwIBAgIJANbqtAWwlQZuMA0GCSqGSIb3DQEBBQUAMBIxEDAOBgNV -BAMTB0ZyZWVSRFAwHhcNMDkxMDI5MDA0MTQ5WhcNMDkxMTI4MDA0MTQ5WjASMRAw -DgYDVQQDEwdGcmVlUkRQMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA -q7mxFgRbS2FYJZX7BzpNd4T/n4nEVDBY6YaObLjGpaB1TptzXTcmfDrDslTGwcEY -hTFAC4ZvY6yOURExqbph4LSgvkoa6J722RjVPfshGa4mlh2SXvTiaV26VPPxddGb -o6fbs2u029lbtBlpIVbhx5RN9vstNkll26oSZ6wfEdBNHQJLd2SU4ItWHj8zjz1f -eGxjgChHihUlwcBYKDJsKFkzHZmLrMgB37KsGlXi/WV+eEsjgvz4yP7I3TL8+GsN -MjV8fRGVEKTbKSmgunO67d5u+IaqUQb0Ad1ha1jzDQ+a6hdymrulJSIhoOVfKkwi -ptTe43FgwxVRIygJP9HjHQIDAQABoyQwIjATBgNVHSUEDDAKBggrBgEFBQcDATAL -BgNVHQ8EBAMCBDAwDQYJKoZIhvcNAQEFBQADggEBAIOdEDhOX2kbl02znltd9hCr -nV4kRPKm979RKwBNkrEuwYSlcsjAHg5MZ5itH3wFOUo2s5pjt7/vMOAg+6rOBbIa -nqr22/gKBtOmuaJLG1yjxDC2vfez7f3B26pKgxa/krM8oxiFdT9n8QbdxdkN7/D9 -3RLU/aCfgrMzXxRus7eq3kR00jnSs6ggnAfE1E9gric3vFgr1wCzdcriRXmXDfUb -hRq+4VG+ZWk16TwCofV5GVU39XWCv5HNO2swAdjkNXgI5e3tQbV3wWLZLqqYzBco -iWulAXtoCGmE81+u1Ms7hLLzpXitLZSGPu1r+sDdkKPLCmOvkAaljDQ4nBz7fIA= ------END CERTIFICATE----- diff --git a/server/X11/server.key b/server/X11/server.key deleted file mode 100644 index 5c2f2c803..000000000 --- a/server/X11/server.key +++ /dev/null @@ -1,27 +0,0 @@ ------BEGIN RSA PRIVATE KEY----- -MIIEogIBAAKCAQEAq7mxFgRbS2FYJZX7BzpNd4T/n4nEVDBY6YaObLjGpaB1Tptz -XTcmfDrDslTGwcEYhTFAC4ZvY6yOURExqbph4LSgvkoa6J722RjVPfshGa4mlh2S -XvTiaV26VPPxddGbo6fbs2u029lbtBlpIVbhx5RN9vstNkll26oSZ6wfEdBNHQJL -d2SU4ItWHj8zjz1feGxjgChHihUlwcBYKDJsKFkzHZmLrMgB37KsGlXi/WV+eEsj -gvz4yP7I3TL8+GsNMjV8fRGVEKTbKSmgunO67d5u+IaqUQb0Ad1ha1jzDQ+a6hdy -mrulJSIhoOVfKkwiptTe43FgwxVRIygJP9HjHQIDAQABAoIBAAVv5K54xtc1JtBR -1lfdPbSqDlnjx8aOnVIPg5TnqMp3sR8jBt0NsPc/+RA9ZOmfjoIxFAEJaZ9zSDJC -5BqmnxC5R1mfCQkSd2haQ+4pdFvWyrv4Bblh8YU6hXrJGn0LfO0KlIcywtAvKpsi -LtTyZkWmaW2HeF/+pO32jYygw38R1wd8Tl6GwjOXwTF6lFACJXOT4YAzcfp3FKSB -AiKBIGuMzozoSND7KPFNRrhGhNumJpdS5A8Fb8D2c/ZMv6Cq5IbwOgTfKun+Bz+s -mFbnzeb1uWRqQbsVXOBBW/zHfuG3SU5qeZsaAyuu4DTy+LE1oAHF9uhBSHuT5C6i -vCJ8A8ECgYEA1iaOmiEJYBrs25iAc4SjCKqhY0mwR3wtu3I06vmgUoML5fhPMv36 -SvYQIqDyNw3p7TE6mZtw9+G+kK3PqhuJhogwSwg0a6o51RdKnhXH3/68oNWtKCLC -1AmR8q/Gd3FwAR3b49CuOIZ9uOiJrc/ejzKdFEJTDR1/TX1frWfZznECgYEAzUiz -XxFf7YrGel7JgmfRD2eZRYngOoteFlg5Tee42UjeAY2Pt2aiDLk+2TqQEdI9+Xg7 -LcFdBqcSNd8bh33xSzgNthIkX+lTDzx0SmKGfyxfFBJcY8nzsLvvnNt3YeuMeaJQ -CPszwoZ0jcD46jTCjbrKhaLyEWmUkDp1O71NTW0CgYAXKF49Xpsz8FVyvcAOPeaf -dkwzf3F3mX8ciRId4taqdY9g1AREgGCDoK5IAF2RBIkqZCtxFvUVaS0BWjpdq9Ko -YKvQQVfh2KueVoF0LOjLWTGutsydzXyCD3Lf6pAstHCnPkJcFWHxrOGFkGfrCtKH -a7K+0RlIDsuIZqllCBjukQKBgA31+MTpYJW+D1t5IMkumEgs6n6RLt+sZLyuSU9k -B+03CGogn3qAj1rAKmcJlYywuKhDpfqpoNL3/8QMJUokpYlRCZWtTC39pzltCheY -9b6mXNz3lrLupBUL4vLO9iKBq28GO90wgEelbz3ItuTuq6CJ6IYIG+BVRtY8M4bZ -i+1NAoGANXZjYnJYDnh8Je9SDxDSc5byzK7ddkQoId64RCIfNHqNKH63P81vjgnH -YBIPtagY75ZVVNxujCF7m8Rety+d8tEFwfQKDin2EVI7PD2rOJra385/izp7HuBR -vqxvLzG9Xv3cNOU2l7PttVw4Pa2i5E37atKi3V3Zp2kMW+KaKPQ= ------END RSA PRIVATE KEY----- diff --git a/server/X11/xf_cursor.c b/server/X11/xf_cursor.c deleted file mode 100644 index 00e4abb3c..000000000 --- a/server/X11/xf_cursor.c +++ /dev/null @@ -1,57 +0,0 @@ -/** - * FreeRDP: A Remote Desktop Protocol Implementation - * X11 Server Cursor - * - * Copyright 2013 Marc-Andre Moreau - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include - -#ifdef WITH_XCURSOR -#include -#endif - -#ifdef WITH_XFIXES -#include -#endif - -#include - -#include "xf_cursor.h" - -int xf_cursor_init(xfInfo* xfi) -{ -#ifdef WITH_XFIXES - int event; - int error; - - if (!XFixesQueryExtension(xfi->display, &event, &error)) - { - fprintf(stderr, "XFixesQueryExtension failed\n"); - return -1; - } - - xfi->xfixes_notify_event = event + XFixesCursorNotify; - - XFixesSelectCursorInput(xfi->display, DefaultRootWindow(xfi->display), XFixesDisplayCursorNotifyMask); -#endif - - return 0; -} diff --git a/server/X11/xf_encode.c b/server/X11/xf_encode.c deleted file mode 100644 index 54830f5cf..000000000 --- a/server/X11/xf_encode.c +++ /dev/null @@ -1,149 +0,0 @@ -/** - * FreeRDP: A Remote Desktop Protocol Implementation - * X11 RemoteFX Encoder - * - * Copyright 2011 Marc-Andre Moreau - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include - -#include -#include - -#include - -#include "xf_encode.h" - -XImage* xf_snapshot(xfPeerContext* xfp, int x, int y, int width, int height) -{ - XImage* image; - xfInfo* xfi = xfp->info; - - if (xfi->use_xshm) - { - XCopyArea(xfi->display, xfi->root_window, xfi->fb_pixmap, xfi->xdamage_gc, x, y, width, height, x, y); - image = xfi->fb_image; - } - else - { - image = XGetImage(xfi->display, xfi->root_window, x, y, width, height, AllPlanes, ZPixmap); - } - - return image; -} - -void xf_xdamage_subtract_region(xfPeerContext* xfp, int x, int y, int width, int height) -{ - XRectangle region; - xfInfo* xfi = xfp->info; - - region.x = x; - region.y = y; - region.width = width; - region.height = height; - -#ifdef WITH_XFIXES - XFixesSetRegion(xfi->display, xfi->xdamage_region, ®ion, 1); - XDamageSubtract(xfi->display, xfi->xdamage, xfi->xdamage_region, None); -#endif -} - -int xf_update_encode(freerdp_peer* client, int x, int y, int width, int height) -{ - wStream* s; - BYTE* data; - xfInfo* xfi; - RFX_RECT rect; - XImage* image; - rdpUpdate* update; - xfPeerContext* xfp; - SURFACE_BITS_COMMAND* cmd; - - update = client->update; - xfp = (xfPeerContext*) client->context; - cmd = &update->surface_bits_command; - xfi = xfp->info; - - if (width * height <= 0) - { - cmd->bitmapDataLength = 0; - return -1; - } - - s = xfp->s; - Stream_Clear(s); - Stream_SetPosition(s, 0); - - if (xfi->use_xshm) - { - /** - * Passing an offset source rectangle to rfx_compose_message() - * leads to protocol errors, so offset the data pointer instead. - */ - - rect.x = 0; - rect.y = 0; - rect.width = width; - rect.height = height; - - image = xf_snapshot(xfp, x, y, width, height); - - data = (BYTE*) image->data; - data = &data[(y * image->bytes_per_line) + (x * image->bits_per_pixel / 8)]; - - rfx_compose_message(xfp->rfx_context, s, &rect, 1, data, - width, height, image->bytes_per_line); - - cmd->destLeft = x; - cmd->destTop = y; - cmd->destRight = x + width; - cmd->destBottom = y + height; - } - else - { - rect.x = 0; - rect.y = 0; - rect.width = width; - rect.height = height; - - image = xf_snapshot(xfp, x, y, width, height); - - data = (BYTE*) image->data; - - rfx_compose_message(xfp->rfx_context, s, &rect, 1, data, - width, height, image->bytes_per_line); - - cmd->destLeft = x; - cmd->destTop = y; - cmd->destRight = x + width; - cmd->destBottom = y + height; - - XDestroyImage(image); - } - - cmd->bpp = 32; - cmd->codecID = client->settings->RemoteFxCodecId; - cmd->width = width; - cmd->height = height; - cmd->bitmapDataLength = Stream_GetPosition(s); - cmd->bitmapData = Stream_Buffer(s); - - return 0; -} diff --git a/server/X11/xf_input.c b/server/X11/xf_input.c deleted file mode 100644 index c47e996da..000000000 --- a/server/X11/xf_input.c +++ /dev/null @@ -1,155 +0,0 @@ -/** - * FreeRDP: A Remote Desktop Protocol Implementation - * X11 Server Input - * - * Copyright 2011 Marc-Andre Moreau - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include - -#include - -#include -#include - -#include "xf_peer.h" - -#include "xf_input.h" - -void xf_input_synchronize_event(rdpInput* input, UINT32 flags) -{ - fprintf(stderr, "Client sent a synchronize event (flags:0x%X)\n", flags); -} - -void xf_input_keyboard_event(rdpInput* input, UINT16 flags, UINT16 code) -{ -#ifdef WITH_XTEST - DWORD vkcode; - DWORD keycode; - BOOL extended = FALSE; - xfPeerContext* xfp = (xfPeerContext*) input->context; - xfInfo* xfi = xfp->info; - - if (flags & KBD_FLAGS_EXTENDED) - extended = TRUE; - - if (extended) - code |= KBDEXT; - - vkcode = GetVirtualKeyCodeFromVirtualScanCode(code, 4); - keycode = GetKeycodeFromVirtualKeyCode(vkcode, KEYCODE_TYPE_EVDEV); - - if (keycode != 0) - { - XTestGrabControl(xfi->display, True); - - if (flags & KBD_FLAGS_DOWN) - XTestFakeKeyEvent(xfi->display, keycode, True, 0); - else if (flags & KBD_FLAGS_RELEASE) - XTestFakeKeyEvent(xfi->display, keycode, False, 0); - - XTestGrabControl(xfi->display, False); - } -#endif -} - -void xf_input_unicode_keyboard_event(rdpInput* input, UINT16 flags, UINT16 code) -{ - fprintf(stderr, "Client sent a unicode keyboard event (flags:0x%X code:0x%X)\n", flags, code); -} - -void xf_input_mouse_event(rdpInput* input, UINT16 flags, UINT16 x, UINT16 y) -{ -#ifdef WITH_XTEST - xfPeerContext* xfp = (xfPeerContext*) input->context; - int button = 0; - BOOL down = FALSE; - xfInfo* xfi = xfp->info; - - XTestGrabControl(xfi->display, True); - - if (flags & PTR_FLAGS_WHEEL) - { - BOOL negative = FALSE; - - if (flags & PTR_FLAGS_WHEEL_NEGATIVE) - negative = TRUE; - - button = (negative) ? 5 : 4; - - XTestFakeButtonEvent(xfi->display, button, True, 0); - XTestFakeButtonEvent(xfi->display, button, False, 0); - } - else - { - if (flags & PTR_FLAGS_MOVE) - XTestFakeMotionEvent(xfi->display, 0, x, y, 0); - - if (flags & PTR_FLAGS_BUTTON1) - button = 1; - else if (flags & PTR_FLAGS_BUTTON2) - button = 3; - else if (flags & PTR_FLAGS_BUTTON3) - button = 2; - - if (flags & PTR_FLAGS_DOWN) - down = TRUE; - - if (button != 0) - XTestFakeButtonEvent(xfi->display, button, down, 0); - } - - XTestGrabControl(xfi->display, False); -#endif -} - -void xf_input_extended_mouse_event(rdpInput* input, UINT16 flags, UINT16 x, UINT16 y) -{ -#ifdef WITH_XTEST - xfPeerContext* xfp = (xfPeerContext*) input->context; - int button = 0; - BOOL down = FALSE; - xfInfo* xfi = xfp->info; - - XTestGrabControl(xfi->display, True); - XTestFakeMotionEvent(xfi->display, 0, x, y, CurrentTime); - - if (flags & PTR_XFLAGS_BUTTON1) - button = 8; - else if (flags & PTR_XFLAGS_BUTTON2) - button = 9; - - if (flags & PTR_XFLAGS_DOWN) - down = TRUE; - - if (button != 0) - XTestFakeButtonEvent(xfi->display, button, down, 0); - - XTestGrabControl(xfi->display, False); -#endif -} - -void xf_input_register_callbacks(rdpInput* input) -{ - input->SynchronizeEvent = xf_input_synchronize_event; - input->KeyboardEvent = xf_input_keyboard_event; - input->UnicodeKeyboardEvent = xf_input_unicode_keyboard_event; - input->MouseEvent = xf_input_mouse_event; - input->ExtendedMouseEvent = xf_input_extended_mouse_event; -} diff --git a/server/X11/xf_input.h b/server/X11/xf_input.h deleted file mode 100644 index 201b21b53..000000000 --- a/server/X11/xf_input.h +++ /dev/null @@ -1,34 +0,0 @@ -/** - * FreeRDP: A Remote Desktop Protocol Implementation - * X11 Server Input - * - * Copyright 2011 Marc-Andre Moreau - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef __XF_INPUT_H -#define __XF_INPUT_H - -#include - -#include "xfreerdp.h" - -void xf_input_synchronize_event(rdpInput* input, UINT32 flags); -void xf_input_keyboard_event(rdpInput* input, UINT16 flags, UINT16 code); -void xf_input_unicode_keyboard_event(rdpInput* input, UINT16 flags, UINT16 code); -void xf_input_mouse_event(rdpInput* input, UINT16 flags, UINT16 x, UINT16 y); -void xf_input_extended_mouse_event(rdpInput* input, UINT16 flags, UINT16 x, UINT16 y); -void xf_input_register_callbacks(rdpInput* input); - -#endif /* __XF_INPUT_H */ diff --git a/server/X11/xf_interface.c b/server/X11/xf_interface.c deleted file mode 100644 index c251b3297..000000000 --- a/server/X11/xf_interface.c +++ /dev/null @@ -1,173 +0,0 @@ -/** - * FreeRDP: A Remote Desktop Protocol Implementation - * FreeRDP X11 Server Interface - * - * Copyright 2013 Marc-Andre Moreau - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "xf_peer.h" -#include "xfreerdp.h" - -#include "xf_interface.h" - -void* xf_server_thread(void* param) -{ - int i; - int fds; - int max_fds; - int rcount; - void* rfds[32]; - fd_set rfds_set; - xfServer* server; - freerdp_listener* listener; - - server = (xfServer*) param; - listener = server->listener; - - while (1) - { - rcount = 0; - - ZeroMemory(rfds, sizeof(rfds)); - if (listener->GetFileDescriptor(listener, rfds, &rcount) != TRUE) - { - fprintf(stderr, "Failed to get FreeRDP file descriptor\n"); - break; - } - - max_fds = 0; - FD_ZERO(&rfds_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; - - if (select(max_fds + 1, &rfds_set, NULL, NULL, NULL) == -1) - { - /* these are not really errors */ - if (!((errno == EAGAIN) || - (errno == EWOULDBLOCK) || - (errno == EINPROGRESS) || - (errno == EINTR))) /* signal occurred */ - { - fprintf(stderr, "select failed\n"); - break; - } - } - - if (listener->CheckFileDescriptor(listener) != TRUE) - { - fprintf(stderr, "Failed to check FreeRDP file descriptor\n"); - break; - } - } - - ExitThread(0); - - return NULL; -} - -int freerdp_server_global_init() -{ - /* - * ignore SIGPIPE, otherwise an SSL_write failure could crash the server - */ - signal(SIGPIPE, SIG_IGN); - - return 0; -} - -int freerdp_server_global_uninit() -{ - return 0; -} - -int freerdp_server_start(xfServer* server) -{ - assert(NULL != server); - - server->thread = NULL; - if (server->listener->Open(server->listener, NULL, 3389)) - { - server->thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) - xf_server_thread, (void*) server, 0, NULL); - } - - return 0; -} - -int freerdp_server_stop(xfServer* server) -{ - if (server->thread) - { - /* ATTENTION: Terminate thread kills a thread, assure - * no resources are allocated during thread execution, - * as they will not be freed! */ - TerminateThread(server->thread, 0); - WaitForSingleObject(server->thread, INFINITE); - CloseHandle(server->thread); - - server->listener->Close(server->listener); - } - return 0; -} - -HANDLE freerdp_server_get_thread(xfServer* server) -{ - return server->thread; -} - -xfServer* freerdp_server_new(int argc, char** argv) -{ - xfServer* server; - - server = (xfServer*) malloc(sizeof(xfServer)); - - if (server) - { - server->listener = freerdp_listener_new(); - server->listener->PeerAccepted = xf_peer_accepted; - } - - return server; -} - -void freerdp_server_free(xfServer* server) -{ - if (server) - { - freerdp_listener_free(server->listener); - free(server); - } -} diff --git a/server/X11/xf_interface.h b/server/X11/xf_interface.h deleted file mode 100644 index f62d36450..000000000 --- a/server/X11/xf_interface.h +++ /dev/null @@ -1,54 +0,0 @@ -/** - * FreeRDP: A Remote Desktop Protocol Implementation - * FreeRDP X11 Server Interface - * - * Copyright 2013 Marc-Andre Moreau - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef XFREERDP_SERVER_INTERFACE_H -#define XFREERDP_SERVER_INTERFACE_H - -#include - -#include -#include - -typedef struct xf_info xfInfo; -typedef struct xf_server xfServer; - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * Server Interface - */ - -FREERDP_API int freerdp_server_global_init(); -FREERDP_API int freerdp_server_global_uninit(); - -FREERDP_API int freerdp_server_start(xfServer* server); -FREERDP_API int freerdp_server_stop(xfServer* server); - -FREERDP_API HANDLE freerdp_server_get_thread(xfServer* server); - -FREERDP_API xfServer* freerdp_server_new(int argc, char** argv); -FREERDP_API void freerdp_server_free(xfServer* server); - -#ifdef __cplusplus -} -#endif - -#endif /* XFREERDP_SERVER_INTERFACE_H */ diff --git a/server/X11/xf_monitors.c b/server/X11/xf_monitors.c deleted file mode 100644 index 2bf5d51f1..000000000 --- a/server/X11/xf_monitors.c +++ /dev/null @@ -1,68 +0,0 @@ -/** - * FreeRDP: A Remote Desktop Protocol Implementation - * X11 Server Monitors - * - * Copyright 2013 Marc-Andre Moreau - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include - -#include -#include - -#ifdef WITH_XINERAMA -#include -#endif - -#include "xf_monitors.h" - -int xf_list_monitors(xfInfo* xfi) -{ -#ifdef WITH_XINERAMAZ - int i, nmonitors = 0; - int ignored, ignored2; - XineramaScreenInfo* screen = NULL; - - if (XineramaQueryExtension(xfi->display, &ignored, &ignored2)) - { - if (XineramaIsActive(xfi->display)) - { - screen = XineramaQueryScreens(xfi->display, &nmonitors); - - for (i = 0; i < nmonitors; i++) - { - printf(" %s [%d] %dx%d\t+%d+%d\n", - (i == 0) ? "*" : " ", i, - screen[i].width, screen[i].height, - screen[i].x_org, screen[i].y_org); - } - - XFree(screen); - } - } -#else - Screen* screen; - - screen = ScreenOfDisplay(xfi->display, DefaultScreen(xfi->display)); - printf(" * [0] %dx%d\t+%d+%d\n", WidthOfScreen(screen), HeightOfScreen(screen), 0, 0); -#endif - - return 0; -} - diff --git a/server/X11/xf_peer.c b/server/X11/xf_peer.c deleted file mode 100644 index 140dcd662..000000000 --- a/server/X11/xf_peer.c +++ /dev/null @@ -1,634 +0,0 @@ -/** - * FreeRDP: A Remote Desktop Protocol Implementation - * X11 Peer - * - * Copyright 2011 Marc-Andre Moreau - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include -#include -#include - -#include "xf_input.h" -#include "xf_cursor.h" -#include "xf_encode.h" -#include "xf_update.h" -#include "xf_monitors.h" - -#include - -#include "xf_peer.h" - -#ifdef WITH_XDAMAGE - -void xf_xdamage_init(xfInfo* xfi) -{ - int damage_event; - int damage_error; - int major, minor; - XGCValues values; - - if (XDamageQueryExtension(xfi->display, &damage_event, &damage_error) == 0) - { - fprintf(stderr, "XDamageQueryExtension failed\n"); - return; - } - - XDamageQueryVersion(xfi->display, &major, &minor); - - if (XDamageQueryVersion(xfi->display, &major, &minor) == 0) - { - fprintf(stderr, "XDamageQueryVersion failed\n"); - return; - } - else if (major < 1) - { - fprintf(stderr, "XDamageQueryVersion failed: major:%d minor:%d\n", major, minor); - return; - } - - xfi->xdamage_notify_event = damage_event + XDamageNotify; - xfi->xdamage = XDamageCreate(xfi->display, xfi->root_window, XDamageReportDeltaRectangles); - - if (xfi->xdamage == None) - { - fprintf(stderr, "XDamageCreate failed\n"); - return; - } - -#ifdef WITH_XFIXES - xfi->xdamage_region = XFixesCreateRegion(xfi->display, NULL, 0); - - if (xfi->xdamage_region == None) - { - fprintf(stderr, "XFixesCreateRegion failed\n"); - XDamageDestroy(xfi->display, xfi->xdamage); - xfi->xdamage = None; - return; - } -#endif - - values.subwindow_mode = IncludeInferiors; - xfi->xdamage_gc = XCreateGC(xfi->display, xfi->root_window, GCSubwindowMode, &values); - XSetFunction(xfi->display, xfi->xdamage_gc, GXcopy); -} - -#endif - -int xf_xshm_init(xfInfo* xfi) -{ - Bool pixmaps; - int major, minor; - - if (XShmQueryExtension(xfi->display) != False) - { - XShmQueryVersion(xfi->display, &major, &minor, &pixmaps); - - if (pixmaps != True) - { - fprintf(stderr, "XShmQueryVersion failed\n"); - return -1; - } - } - else - { - fprintf(stderr, "XShmQueryExtension failed\n"); - return -1; - } - - xfi->fb_shm_info.shmid = -1; - xfi->fb_shm_info.shmaddr = (char*) -1; - - xfi->fb_image = XShmCreateImage(xfi->display, xfi->visual, xfi->depth, - ZPixmap, NULL, &(xfi->fb_shm_info), xfi->width, xfi->height); - - if (!xfi->fb_image) - { - fprintf(stderr, "XShmCreateImage failed\n"); - return -1; - } - - xfi->fb_shm_info.shmid = shmget(IPC_PRIVATE, - xfi->fb_image->bytes_per_line * xfi->fb_image->height, IPC_CREAT | 0600); - - if (xfi->fb_shm_info.shmid == -1) - { - fprintf(stderr, "shmget failed\n"); - return -1; - } - - xfi->fb_shm_info.readOnly = False; - xfi->fb_shm_info.shmaddr = shmat(xfi->fb_shm_info.shmid, 0, 0); - xfi->fb_image->data = xfi->fb_shm_info.shmaddr; - - if (xfi->fb_shm_info.shmaddr == ((char*) -1)) - { - fprintf(stderr, "shmat failed\n"); - return -1; - } - - XShmAttach(xfi->display, &(xfi->fb_shm_info)); - XSync(xfi->display, False); - - shmctl(xfi->fb_shm_info.shmid, IPC_RMID, 0); - - fprintf(stderr, "display: %p root_window: %p width: %d height: %d depth: %d\n", - xfi->display, (void*) xfi->root_window, xfi->fb_image->width, xfi->fb_image->height, xfi->fb_image->depth); - - xfi->fb_pixmap = XShmCreatePixmap(xfi->display, - xfi->root_window, xfi->fb_image->data, &(xfi->fb_shm_info), - xfi->fb_image->width, xfi->fb_image->height, xfi->fb_image->depth); - - return 0; -} - -void xf_info_free(xfInfo *info) -{ - assert(NULL != info); - - if (info->display) - XCloseDisplay(info->display); - - freerdp_clrconv_free(info->clrconv); - free(info); -} - -xfInfo* xf_info_init() -{ - int i; - xfInfo* xfi; - int pf_count; - int vi_count; - XVisualInfo* vi; - XVisualInfo* vis; - XVisualInfo template; - XPixmapFormatValues* pf; - XPixmapFormatValues* pfs; - - xfi = (xfInfo*) malloc(sizeof(xfInfo)); - ZeroMemory(xfi, sizeof(xfInfo)); - - /** - * Recent X11 servers drop support for shared pixmaps - * To see if your X11 server supports shared pixmaps, use: - * xdpyinfo -ext MIT-SHM | grep "shared pixmaps" - */ - xfi->use_xshm = TRUE; - - setenv("DISPLAY", ":0", 1); /* Set DISPLAY variable if not already set */ - - if (!XInitThreads()) - fprintf(stderr, "warning: XInitThreads() failure\n"); - - xfi->display = XOpenDisplay(NULL); - - if (!xfi->display) - { - fprintf(stderr, "failed to open display: %s\n", XDisplayName(NULL)); - exit(1); - } - - xf_list_monitors(xfi); - - xfi->xfds = ConnectionNumber(xfi->display); - xfi->number = DefaultScreen(xfi->display); - xfi->screen = ScreenOfDisplay(xfi->display, xfi->number); - xfi->depth = DefaultDepthOfScreen(xfi->screen); - xfi->width = WidthOfScreen(xfi->screen); - xfi->height = HeightOfScreen(xfi->screen); - xfi->root_window = DefaultRootWindow(xfi->display); - - pfs = XListPixmapFormats(xfi->display, &pf_count); - - if (!pfs) - { - fprintf(stderr, "XListPixmapFormats failed\n"); - exit(1); - } - - for (i = 0; i < pf_count; i++) - { - pf = pfs + i; - - if (pf->depth == xfi->depth) - { - xfi->bpp = pf->bits_per_pixel; - xfi->scanline_pad = pf->scanline_pad; - break; - } - } - XFree(pfs); - - ZeroMemory(&template, sizeof(template)); - template.class = TrueColor; - template.screen = xfi->number; - - vis = XGetVisualInfo(xfi->display, VisualClassMask | VisualScreenMask, &template, &vi_count); - - if (!vis) - { - fprintf(stderr, "XGetVisualInfo failed\n"); - exit(1); - } - - for (i = 0; i < vi_count; i++) - { - vi = vis + i; - - if (vi->depth == xfi->depth) - { - xfi->visual = vi->visual; - break; - } - } - XFree(vis); - - xfi->clrconv = freerdp_clrconv_new(CLRCONV_ALPHA | CLRCONV_INVERT); - - XSelectInput(xfi->display, xfi->root_window, SubstructureNotifyMask); - - if (xfi->use_xshm) - { - if (xf_xshm_init(xfi) < 0) - xfi->use_xshm = FALSE; - } - - if (xfi->use_xshm) - printf("Using X Shared Memory Extension (XShm)\n"); - -#ifdef WITH_XDAMAGE - xf_xdamage_init(xfi); -#endif - - xf_cursor_init(xfi); - - xfi->bytesPerPixel = 4; - xfi->activePeerCount = 0; - - freerdp_keyboard_init(0); - - return xfi; -} - -void xf_peer_context_new(freerdp_peer* client, xfPeerContext* context) -{ - context->info = xf_info_init(); - context->rfx_context = rfx_context_new(TRUE); - context->rfx_context->mode = RLGR3; - context->rfx_context->width = context->info->width; - context->rfx_context->height = context->info->height; - - rfx_context_set_pixel_format(context->rfx_context, RDP_PIXEL_FORMAT_B8G8R8A8); - - context->s = Stream_New(NULL, 65536); - Stream_Clear(context->s); - - context->updateReadyEvent = CreateEvent(NULL, TRUE, FALSE, NULL); - context->updateSentEvent = CreateEvent(NULL, TRUE, FALSE, NULL); -} - -void xf_peer_context_free(freerdp_peer* client, xfPeerContext* context) -{ - if (context) - { - xf_info_free(context->info); - - CloseHandle(context->updateReadyEvent); - CloseHandle(context->updateSentEvent); - - Stream_Free(context->s, TRUE); - rfx_context_free(context->rfx_context); - } -} - -void xf_peer_init(freerdp_peer* client) -{ - xfInfo* xfi; - xfPeerContext* xfp; - - client->ContextSize = sizeof(xfPeerContext); - client->ContextNew = (psPeerContextNew) xf_peer_context_new; - client->ContextFree = (psPeerContextFree) xf_peer_context_free; - freerdp_peer_context_new(client); - - xfp = (xfPeerContext*) client->context; - - xfp->fps = 16; - xfi = xfp->info; - - xfp->mutex = CreateMutex(NULL, FALSE, NULL); -} - -void xf_peer_send_update(freerdp_peer* client) -{ - rdpUpdate* update; - SURFACE_BITS_COMMAND* cmd; - - update = client->update; - cmd = &update->surface_bits_command; - - if (cmd->bitmapDataLength) - update->SurfaceBits(update->context, cmd); -} - -BOOL xf_peer_get_fds(freerdp_peer* client, void** rfds, int* rcount) -{ - int fds; - HANDLE event; - xfPeerContext* xfp = (xfPeerContext*) client->context; - - event = xfp->updateReadyEvent; - fds = GetEventFileDescriptor(event); - rfds[*rcount] = (void*) (long) fds; - (*rcount)++; - - return TRUE; -} - -BOOL xf_peer_check_fds(freerdp_peer* client) -{ - xfInfo* xfi; - xfPeerContext* xfp; - - xfp = (xfPeerContext*) client->context; - xfi = xfp->info; - - if (WaitForSingleObject(xfp->updateReadyEvent, 0) == WAIT_OBJECT_0) - { - if (!xfp->activated) - return TRUE; - - xf_peer_send_update(client); - - ResetEvent(xfp->updateReadyEvent); - SetEvent(xfp->updateSentEvent); - } - - return TRUE; -} - -BOOL xf_peer_capabilities(freerdp_peer* client) -{ - return TRUE; -} - -BOOL xf_peer_post_connect(freerdp_peer* client) -{ - xfInfo* xfi; - xfPeerContext* xfp; - - xfp = (xfPeerContext*) client->context; - xfi = (xfInfo*) xfp->info; - - /** - * This callback is called when the entire connection sequence is done, i.e. we've received the - * Font List PDU from the client and sent out the Font Map PDU. - * The server may start sending graphics output and receiving keyboard/mouse input after this - * callback returns. - */ - fprintf(stderr, "Client %s is activated", client->hostname); - if (client->settings->AutoLogonEnabled) - { - fprintf(stderr, " and wants to login automatically as %s\\%s", - client->settings->Domain ? client->settings->Domain : "", - client->settings->Username); - - /* A real server may perform OS login here if NLA is not executed previously. */ - } - fprintf(stderr, "\n"); - - fprintf(stderr, "Client requested desktop: %dx%dx%d\n", - client->settings->DesktopWidth, client->settings->DesktopHeight, client->settings->ColorDepth); - - if (!client->settings->RemoteFxCodec) - { - fprintf(stderr, "Client does not support RemoteFX\n"); - return FALSE; - } - - /* A real server should tag the peer as activated here and start sending updates in main loop. */ - - client->settings->DesktopWidth = xfi->width; - client->settings->DesktopHeight = xfi->height; - - client->update->DesktopResize(client->update->context); - - /* Return FALSE here would stop the execution of the peer main loop. */ - return TRUE; -} - -BOOL xf_peer_activate(freerdp_peer* client) -{ - xfPeerContext* xfp = (xfPeerContext*) client->context; - - rfx_context_reset(xfp->rfx_context); - xfp->activated = TRUE; - - xfp->info->activePeerCount++; - - xfp->monitorThread = CreateThread(NULL, 0, - (LPTHREAD_START_ROUTINE) xf_update_thread, (void*) client, 0, NULL); - - return TRUE; -} - -const char* makecert_argv[4] = -{ - "makecert", - "-rdp", - "-live", - "-silent" -}; - -int makecert_argc = (sizeof(makecert_argv) / sizeof(char*)); - -int xf_generate_certificate(rdpSettings* settings) -{ - char* server_file_path; - MAKECERT_CONTEXT* context; - - server_file_path = GetCombinedPath(settings->ConfigPath, "server"); - - if (!PathFileExistsA(server_file_path)) - CreateDirectoryA(server_file_path, 0); - - settings->CertificateFile = GetCombinedPath(server_file_path, "server.crt"); - settings->PrivateKeyFile = GetCombinedPath(server_file_path, "server.key"); - - if ((!PathFileExistsA(settings->CertificateFile)) || - (!PathFileExistsA(settings->PrivateKeyFile))) - { - context = makecert_context_new(); - - makecert_context_process(context, makecert_argc, (char**) makecert_argv); - - makecert_context_set_output_file_name(context, "server"); - - if (!PathFileExistsA(settings->CertificateFile)) - makecert_context_output_certificate_file(context, server_file_path); - - if (!PathFileExistsA(settings->PrivateKeyFile)) - makecert_context_output_private_key_file(context, server_file_path); - - makecert_context_free(context); - } - - free(server_file_path); - - return 0; -} - -static void* xf_peer_main_loop(void* arg) -{ - int i; - int fds; - int max_fds; - int rcount; - void* rfds[32]; - fd_set rfds_set; - rdpSettings* settings; - xfPeerContext* xfp; - struct timeval timeout; - freerdp_peer* client = (freerdp_peer*) arg; - - assert(NULL != client); - - ZeroMemory(rfds, sizeof(rfds)); - ZeroMemory(&timeout, sizeof(struct timeval)); - - fprintf(stderr, "We've got a client %s\n", client->hostname); - - xf_peer_init(client); - xfp = (xfPeerContext*) client->context; - settings = client->settings; - - xf_generate_certificate(settings); - - settings->RemoteFxCodec = TRUE; - settings->ColorDepth = 32; - - settings->NlaSecurity = FALSE; - settings->TlsSecurity = TRUE; - settings->RdpSecurity = FALSE; - - client->Capabilities = xf_peer_capabilities; - client->PostConnect = xf_peer_post_connect; - client->Activate = xf_peer_activate; - - xf_input_register_callbacks(client->input); - - client->Initialize(client); - - while (1) - { - rcount = 0; - - if (client->GetFileDescriptor(client, rfds, &rcount) != TRUE) - { - fprintf(stderr, "Failed to get FreeRDP file descriptor\n"); - break; - } - - if (xf_peer_get_fds(client, rfds, &rcount) != TRUE) - { - fprintf(stderr, "Failed to get xfreerdp file descriptor\n"); - break; - } - - max_fds = 0; - FD_ZERO(&rfds_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 = 0; - timeout.tv_usec = 100; - - if (select(max_fds + 1, &rfds_set, NULL, NULL, &timeout) == -1) - { - /* these are not really errors */ - if (!((errno == EAGAIN) || - (errno == EWOULDBLOCK) || - (errno == EINPROGRESS) || - (errno == EINTR))) /* signal occurred */ - { - fprintf(stderr, "select failed\n"); - break; - } - } - - if (client->CheckFileDescriptor(client) != TRUE) - { - fprintf(stderr, "Failed to check freerdp file descriptor\n"); - break; - } - - if ((xf_peer_check_fds(client)) != TRUE) - { - fprintf(stderr, "Failed to check xfreerdp file descriptor\n"); - break; - } - } - - fprintf(stderr, "Client %s disconnected.\n", client->hostname); - - client->Disconnect(client); - - freerdp_peer_context_free(client); - freerdp_peer_free(client); - - ExitThread(0); - - return NULL; -} - -void xf_peer_accepted(freerdp_listener* instance, freerdp_peer* client) -{ - HANDLE thread; - - thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) xf_peer_main_loop, client, 0, NULL); -} diff --git a/server/X11/xf_peer.h b/server/X11/xf_peer.h deleted file mode 100644 index e6febd68d..000000000 --- a/server/X11/xf_peer.h +++ /dev/null @@ -1,63 +0,0 @@ -/** - * FreeRDP: A Remote Desktop Protocol Implementation - * X11 Peer - * - * Copyright 2011 Marc-Andre Moreau - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef __XF_PEER_H -#define __XF_PEER_H - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -typedef struct xf_peer_context xfPeerContext; - -#include "xfreerdp.h" - -#define PeerEvent_Base 0 - -#define PeerEvent_Class (PeerEvent_Base + 1) - -#define PeerEvent_EncodeRegion 1 - -struct xf_peer_context -{ - rdpContext _p; - - int fps; - wStream* s; - xfInfo* info; - HANDLE mutex; - BOOL activated; - HANDLE monitorThread; - HANDLE updateReadyEvent; - HANDLE updateSentEvent; - RFX_CONTEXT* rfx_context; -}; - -void xf_peer_accepted(freerdp_listener* instance, freerdp_peer* client); - -#endif /* __XF_PEER_H */ diff --git a/server/X11/xf_update.c b/server/X11/xf_update.c deleted file mode 100644 index 67addb550..000000000 --- a/server/X11/xf_update.c +++ /dev/null @@ -1,100 +0,0 @@ -/** - * FreeRDP: A Remote Desktop Protocol Implementation - * X11 Server Graphical Updates - * - * Copyright 2013 Marc-Andre Moreau - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include - -#include -#include -#include - -#include "xf_peer.h" -#include "xf_encode.h" - -#include "xf_update.h" - -void* xf_update_thread(void* param) -{ - xfInfo* xfi; - HANDLE event; - XEvent xevent; - DWORD beg, end; - DWORD diff, rate; - xfPeerContext* xfp; - freerdp_peer* client; - int x, y, width, height; - XDamageNotifyEvent* notify; - - client = (freerdp_peer*) param; - xfp = (xfPeerContext*) client->context; - xfi = xfp->info; - - rate = 1000 / xfp->fps; - - event = CreateFileDescriptorEvent(NULL, FALSE, FALSE, xfi->xfds); - - while (WaitForSingleObject(event, INFINITE) == WAIT_OBJECT_0) - { - beg = GetTickCount(); - - while (XPending(xfi->display) > 0) - { - ZeroMemory(&xevent, sizeof(xevent)); - XNextEvent(xfi->display, &xevent); - - if (xevent.type == xfi->xdamage_notify_event) - { - notify = (XDamageNotifyEvent*) &xevent; - - x = notify->area.x; - y = notify->area.y; - width = notify->area.width; - height = notify->area.height; - - if (xf_update_encode(client, x, y, width, height) >= 0) - { - xf_xdamage_subtract_region(xfp, x, y, width, height); - - SetEvent(xfp->updateReadyEvent); - - WaitForSingleObject(xfp->updateSentEvent, INFINITE); - ResetEvent(xfp->updateSentEvent); - } - } -#ifdef WITH_XFIXES - else if (xevent.type == xfi->xfixes_notify_event) - { - XFixesCursorImage* ci = XFixesGetCursorImage(xfi->display); - XFree(ci); - } -#endif - } - - end = GetTickCount(); - diff = end - beg; - - if (diff < rate) - Sleep(rate - diff); - } - - return NULL; -} diff --git a/server/shadow/.gitignore b/server/shadow/.gitignore new file mode 100644 index 000000000..662d7d541 --- /dev/null +++ b/server/shadow/.gitignore @@ -0,0 +1,2 @@ +freerdp-shadow + diff --git a/server/shadow/CMakeLists.txt b/server/shadow/CMakeLists.txt new file mode 100644 index 000000000..e68c84589 --- /dev/null +++ b/server/shadow/CMakeLists.txt @@ -0,0 +1,201 @@ +# FreeRDP: A Remote Desktop Protocol Implementation +# FreeRDP Shadow Server cmake build script +# +# Copyright 2014 Marc-Andre Moreau +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +set(MODULE_NAME "freerdp-shadow") +set(MODULE_PREFIX "FREERDP_SERVER_SHADOW") + +if(WITH_X11) + set(XEXT_FEATURE_TYPE "RECOMMENDED") + set(XEXT_FEATURE_PURPOSE "X11 extension") + set(XEXT_FEATURE_DESCRIPTION "X11 core extensions") + + set(XSHM_FEATURE_TYPE "RECOMMENDED") + set(XSHM_FEATURE_PURPOSE "X11 shared memory") + set(XSHM_FEATURE_DESCRIPTION "X11 shared memory extension") + + set(XINERAMA_FEATURE_TYPE "RECOMMENDED") + set(XINERAMA_FEATURE_PURPOSE "multi-monitor") + set(XINERAMA_FEATURE_DESCRIPTION "X11 multi-monitor extension") + + set(XTEST_FEATURE_TYPE "RECOMMENDED") + set(XTEST_FEATURE_PURPOSE "X11 input event injection") + set(XTEST_FEATURE_DESCRIPTION "X11 input event injection extension") + + set(XCURSOR_FEATURE_TYPE "RECOMMENDED") + set(XCURSOR_FEATURE_PURPOSE "cursor") + set(XCURSOR_FEATURE_DESCRIPTION "X11 cursor extension") + + set(XFIXES_FEATURE_TYPE "RECOMMENDED") + set(XFIXES_FEATURE_PURPOSE "X11 region") + set(XFIXES_FEATURE_DESCRIPTION "X11 region fix extension") + + set(XRANDR_FEATURE_TYPE "RECOMMENDED") + set(XRANDR_FEATURE_PURPOSE "X11 resize, rotate and reflect") + set(XRANDR_FEATURE_DESCRIPTION "X11 resize, rotate and reflect extension") + + set(XDAMAGE_FEATURE_TYPE "RECOMMENDED") + set(XDAMAGE_FEATURE_PURPOSE "X11 region damage") + set(XDAMAGE_FEATURE_DESCRIPTION "X11 region damage extension") + + find_feature(Xext ${XEXT_FEATURE_TYPE} ${XEXT_FEATURE_PURPOSE} ${XEXT_FEATURE_DESCRIPTION}) + find_feature(XShm ${XSHM_FEATURE_TYPE} ${XSHM_FEATURE_PURPOSE} ${XSHM_FEATURE_DESCRIPTION}) + find_feature(XTest ${XTEST_FEATURE_TYPE} ${XTEST_FEATURE_PURPOSE} ${XTEST_FEATURE_DESCRIPTION}) + find_feature(Xfixes ${XFIXES_FEATURE_TYPE} ${XFIXES_FEATURE_PURPOSE} ${XFIXES_FEATURE_DESCRIPTION}) + find_feature(XRandR ${XRANDR_FEATURE_TYPE} ${XRANDR_FEATURE_PURPOSE} ${XRANDR_FEATURE_DESCRIPTION}) + find_feature(Xdamage ${XDAMAGE_FEATURE_TYPE} ${XDAMAGE_FEATURE_PURPOSE} ${XDAMAGE_FEATURE_DESCRIPTION}) + find_feature(Xcursor ${XCURSOR_FEATURE_TYPE} ${XCURSOR_FEATURE_PURPOSE} ${XCURSOR_FEATURE_DESCRIPTION}) + find_feature(Xinerama ${XINERAMA_FEATURE_TYPE} ${XINERAMA_FEATURE_PURPOSE} ${XINERAMA_FEATURE_DESCRIPTION}) + + if(WITH_X11) + add_definitions(-DWITH_X11) + include_directories(${X11_INCLUDE_DIRS}) + list(APPEND ${MODULE_PREFIX}_X11_LIBS ${X11_LIBRARIES}) + endif() + + if(WITH_XSHM) + add_definitions(-DWITH_XSHM) + include_directories(${XSHM_INCLUDE_DIRS}) + list(APPEND ${MODULE_PREFIX}_X11_LIBS ${XSHM_LIBRARIES}) + endif() + + if(WITH_XEXT) + add_definitions(-DWITH_XEXT) + include_directories(${XEXT_INCLUDE_DIRS}) + list(APPEND ${MODULE_PREFIX}_X11_LIBS ${XEXT_LIBRARIES}) + endif() + + if(WITH_XINERAMA) + add_definitions(-DWITH_XINERAMA) + include_directories(${XINERAMA_INCLUDE_DIRS}) + list(APPEND ${MODULE_PREFIX}_X11_LIBS ${XINERAMA_LIBRARIES}) + endif() + + if(WITH_XCURSOR) + add_definitions(-DWITH_XCURSOR) + include_directories(${XCURSOR_INCLUDE_DIRS}) + list(APPEND ${MODULE_PREFIX}_X11_LIBS ${XCURSOR_LIBRARIES}) + endif() + + if(WITH_XDAMAGE) + add_definitions(-DWITH_XDAMAGE) + include_directories(${XDAMAGE_INCLUDE_DIRS}) + list(APPEND ${MODULE_PREFIX}_X11_LIBS ${XDAMAGE_LIBRARIES}) + endif() + + if(WITH_XFIXES) + add_definitions(-DWITH_XFIXES) + include_directories(${XFIXES_INCLUDE_DIRS}) + list(APPEND ${MODULE_PREFIX}_X11_LIBS ${XFIXES_LIBRARIES}) + endif() + + if(WITH_XTEST) + add_definitions(-DWITH_XTEST) + include_directories(${XTEST_INCLUDE_DIRS}) + list(APPEND ${MODULE_PREFIX}_X11_LIBS ${XTEST_LIBRARIES}) + endif() + + if(WITH_XRANDR) + add_definitions(-DWITH_XRANDR) + include_directories(${XRANDR_INCLUDE_DIRS}) + list(APPEND ${MODULE_PREFIX}_X11_LIBS ${XRANDR_LIBRARIES}) + endif() +endif() + +include_directories(${OPENSSL_INCLUDE_DIR}) + +set(${MODULE_PREFIX}_SRCS + shadow_client.c + shadow_client.h + shadow_input.c + shadow_input.h + shadow_screen.c + shadow_screen.h + shadow_surface.c + shadow_surface.h + shadow_encoder.c + shadow_encoder.h + shadow_capture.c + shadow_capture.h + shadow_channels.c + shadow_channels.h + shadow_encomsp.c + shadow_encomsp.h + shadow_remdesk.c + shadow_remdesk.h + shadow_server.c + shadow.h) + +set(${MODULE_PREFIX}_WIN_SRCS + Win/win_rdp.c + Win/win_rdp.h + Win/win_wds.c + Win/win_wds.h + Win/win_dxgi.c + Win/win_dxgi.h + Win/win_shadow.c + Win/win_shadow.h) + +set(${MODULE_PREFIX}_X11_SRCS + X11/x11_shadow.c + X11/x11_shadow.h) + +set(${MODULE_PREFIX}_MAC_SRCS + Mac/mac_shadow.c + Mac/mac_shadow.h) + +if(WIN32) + set(WITH_SHADOW_WIN 1) +elseif(X11_FOUND AND NOT APPLE) + set(WITH_SHADOW_X11 1) +elseif(APPLE AND NOT IOS) + set(WITH_SHADOW_MAC 1) +endif() + +if(WITH_SHADOW_WIN) + add_definitions(-DWITH_SHADOW_WIN) + list(APPEND ${MODULE_PREFIX}_SRCS ${${MODULE_PREFIX}_WIN_SRCS}) + list(APPEND ${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_WIN_LIBS}) +elseif(WITH_SHADOW_X11) + add_definitions(-DWITH_SHADOW_X11) + list(APPEND ${MODULE_PREFIX}_SRCS ${${MODULE_PREFIX}_X11_SRCS}) + list(APPEND ${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_X11_LIBS}) +elseif(WITH_SHADOW_MAC) + add_definitions(-DWITH_SHADOW_MAC) + list(APPEND ${MODULE_PREFIX}_SRCS ${${MODULE_PREFIX}_MAC_SRCS}) + list(APPEND ${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_MAC_LIBS}) +endif() + +add_executable(${MODULE_NAME} ${${MODULE_PREFIX}_SRCS}) + +set_target_properties(${MODULE_NAME} PROPERTIES OUTPUT_NAME "freerdp-shadow") + +list(APPEND ${MODULE_PREFIX}_LIBS freerdp-server) + +set_complex_link_libraries(VARIABLE ${MODULE_PREFIX}_LIBS + MONOLITHIC ${MONOLITHIC_BUILD} + MODULE freerdp + MODULES freerdp-core freerdp-common freerdp-codec freerdp-primitives freerdp-utils freerdp-gdi freerdp-crypto freerdp-locale) + +list(APPEND ${MODULE_PREFIX}_LIBS freerdp-client) +list(APPEND ${MODULE_PREFIX}_LIBS winpr-makecert-tool winpr) + +target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS}) + +install(TARGETS ${MODULE_NAME} DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT server) + +set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "Server/shadow") + diff --git a/server/shadow/Mac/mac_shadow.c b/server/shadow/Mac/mac_shadow.c new file mode 100644 index 000000000..a303277b2 --- /dev/null +++ b/server/shadow/Mac/mac_shadow.c @@ -0,0 +1,163 @@ +/** + * FreeRDP: A Remote Desktop Protocol Implementation + * + * Copyright 2011-2014 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include + +#include +#include + +#include "../shadow_screen.h" +#include "../shadow_surface.h" + +#include "mac_shadow.h" + +void mac_shadow_input_synchronize_event(macShadowSubsystem* subsystem, UINT32 flags) +{ + +} + +void mac_shadow_input_keyboard_event(macShadowSubsystem* subsystem, UINT16 flags, UINT16 code) +{ + +} + +void mac_shadow_input_unicode_keyboard_event(macShadowSubsystem* subsystem, UINT16 flags, UINT16 code) +{ + +} + +void mac_shadow_input_mouse_event(macShadowSubsystem* subsystem, UINT16 flags, UINT16 x, UINT16 y) +{ + +} + +void mac_shadow_input_extended_mouse_event(macShadowSubsystem* subsystem, UINT16 flags, UINT16 x, UINT16 y) +{ + +} + +int mac_shadow_surface_copy(macShadowSubsystem* subsystem) +{ + return 1; +} + +void* mac_shadow_subsystem_thread(macShadowSubsystem* subsystem) +{ + DWORD status; + DWORD nCount; + HANDLE events[32]; + HANDLE StopEvent; + + StopEvent = subsystem->server->StopEvent; + + nCount = 0; + events[nCount++] = StopEvent; + + while (1) + { + status = WaitForMultipleObjects(nCount, events, FALSE, INFINITE); + + if (WaitForSingleObject(StopEvent, 0) == WAIT_OBJECT_0) + { + break; + } + } + + ExitThread(0); + return NULL; +} + +int mac_shadow_subsystem_init(macShadowSubsystem* subsystem) +{ + return 1; +} + +int mac_shadow_subsystem_uninit(macShadowSubsystem* subsystem) +{ + if (!subsystem) + return -1; + + return 1; +} + +int mac_shadow_subsystem_start(macShadowSubsystem* subsystem) +{ + HANDLE thread; + + if (!subsystem) + return -1; + + thread = CreateThread(NULL, 0, + (LPTHREAD_START_ROUTINE) mac_shadow_subsystem_thread, + (void*) subsystem, 0, NULL); + + return 1; +} + +int mac_shadow_subsystem_stop(macShadowSubsystem* subsystem) +{ + if (!subsystem) + return -1; + + return 1; +} + +void mac_shadow_subsystem_free(macShadowSubsystem* subsystem) +{ + if (!subsystem) + return; + + mac_shadow_subsystem_uninit(subsystem); + + free(subsystem); +} + +macShadowSubsystem* mac_shadow_subsystem_new(rdpShadowServer* server) +{ + macShadowSubsystem* subsystem; + + subsystem = (macShadowSubsystem*) calloc(1, sizeof(macShadowSubsystem)); + + if (!subsystem) + return NULL; + + subsystem->server = server; + + subsystem->Init = (pfnShadowSubsystemInit) mac_shadow_subsystem_init; + subsystem->Uninit = (pfnShadowSubsystemInit) mac_shadow_subsystem_uninit; + subsystem->Start = (pfnShadowSubsystemStart) mac_shadow_subsystem_start; + subsystem->Stop = (pfnShadowSubsystemStop) mac_shadow_subsystem_stop; + subsystem->Free = (pfnShadowSubsystemFree) mac_shadow_subsystem_free; + + subsystem->SurfaceCopy = (pfnShadowSurfaceCopy) mac_shadow_surface_copy; + + subsystem->SynchronizeEvent = (pfnShadowSynchronizeEvent) mac_shadow_input_synchronize_event; + subsystem->KeyboardEvent = (pfnShadowKeyboardEvent) mac_shadow_input_keyboard_event; + subsystem->UnicodeKeyboardEvent = (pfnShadowUnicodeKeyboardEvent) mac_shadow_input_unicode_keyboard_event; + subsystem->MouseEvent = (pfnShadowMouseEvent) mac_shadow_input_mouse_event; + subsystem->ExtendedMouseEvent = (pfnShadowExtendedMouseEvent) mac_shadow_input_extended_mouse_event; + + return subsystem; +} + +rdpShadowSubsystem* Mac_ShadowCreateSubsystem(rdpShadowServer* server) +{ + return (rdpShadowSubsystem*) mac_shadow_subsystem_new(server); +} diff --git a/server/shadow/Mac/mac_shadow.h b/server/shadow/Mac/mac_shadow.h new file mode 100644 index 000000000..88dbf2593 --- /dev/null +++ b/server/shadow/Mac/mac_shadow.h @@ -0,0 +1,49 @@ +/** + * FreeRDP: A Remote Desktop Protocol Implementation + * + * Copyright 2011-2014 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef FREERDP_SHADOW_SERVER_MAC_H +#define FREERDP_SHADOW_SERVER_MAC_H + +#include + +typedef struct mac_shadow_subsystem macShadowSubsystem; + +#include +#include +#include +#include +#include + +struct mac_shadow_subsystem +{ + RDP_SHADOW_SUBSYSTEM_COMMON(); + + +}; + +#ifdef __cplusplus +extern "C" { +#endif + + + +#ifdef __cplusplus +} +#endif + +#endif /* FREERDP_SHADOW_SERVER_MAC_H */ diff --git a/server/shadow/Win/win_dxgi.c b/server/shadow/Win/win_dxgi.c new file mode 100644 index 000000000..bb4c71a99 --- /dev/null +++ b/server/shadow/Win/win_dxgi.c @@ -0,0 +1,724 @@ +/** + * FreeRDP: A Remote Desktop Protocol Implementation + * + * Copyright 2014 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include + +#include "win_dxgi.h" + +#ifdef WITH_DXGI_1_2 + +static D3D_DRIVER_TYPE DriverTypes[] = +{ + D3D_DRIVER_TYPE_HARDWARE, + D3D_DRIVER_TYPE_WARP, + D3D_DRIVER_TYPE_REFERENCE, +}; + +static UINT NumDriverTypes = ARRAYSIZE(DriverTypes); + +static D3D_FEATURE_LEVEL FeatureLevels[] = +{ + D3D_FEATURE_LEVEL_11_0, + D3D_FEATURE_LEVEL_10_1, + D3D_FEATURE_LEVEL_10_0, + D3D_FEATURE_LEVEL_9_1 +}; + +static UINT NumFeatureLevels = ARRAYSIZE(FeatureLevels); + +static HMODULE d3d11_module = NULL; + +typedef HRESULT (WINAPI * fnD3D11CreateDevice)( + IDXGIAdapter* pAdapter, D3D_DRIVER_TYPE DriverType, HMODULE Software, UINT Flags, + CONST D3D_FEATURE_LEVEL* pFeatureLevels, UINT FeatureLevels, UINT SDKVersion, + ID3D11Device** ppDevice, D3D_FEATURE_LEVEL* pFeatureLevel, ID3D11DeviceContext** ppImmediateContext); + +static fnD3D11CreateDevice pfnD3D11CreateDevice = NULL; + +#undef DEFINE_GUID +#define INITGUID + +#include + +/* d3d11.h GUIDs */ + +DEFINE_GUID(IID_ID3D11DeviceChild,0x1841e5c8,0x16b0,0x489b,0xbc,0xc8,0x44,0xcf,0xb0,0xd5,0xde,0xae); +DEFINE_GUID(IID_ID3D11DepthStencilState,0x03823efb,0x8d8f,0x4e1c,0x9a,0xa2,0xf6,0x4b,0xb2,0xcb,0xfd,0xf1); +DEFINE_GUID(IID_ID3D11BlendState,0x75b68faa,0x347d,0x4159,0x8f,0x45,0xa0,0x64,0x0f,0x01,0xcd,0x9a); +DEFINE_GUID(IID_ID3D11RasterizerState,0x9bb4ab81,0xab1a,0x4d8f,0xb5,0x06,0xfc,0x04,0x20,0x0b,0x6e,0xe7); +DEFINE_GUID(IID_ID3D11Resource,0xdc8e63f3,0xd12b,0x4952,0xb4,0x7b,0x5e,0x45,0x02,0x6a,0x86,0x2d); +DEFINE_GUID(IID_ID3D11Buffer,0x48570b85,0xd1ee,0x4fcd,0xa2,0x50,0xeb,0x35,0x07,0x22,0xb0,0x37); +DEFINE_GUID(IID_ID3D11Texture1D,0xf8fb5c27,0xc6b3,0x4f75,0xa4,0xc8,0x43,0x9a,0xf2,0xef,0x56,0x4c); +DEFINE_GUID(IID_ID3D11Texture2D,0x6f15aaf2,0xd208,0x4e89,0x9a,0xb4,0x48,0x95,0x35,0xd3,0x4f,0x9c); +DEFINE_GUID(IID_ID3D11Texture3D,0x037e866e,0xf56d,0x4357,0xa8,0xaf,0x9d,0xab,0xbe,0x6e,0x25,0x0e); +DEFINE_GUID(IID_ID3D11View,0x839d1216,0xbb2e,0x412b,0xb7,0xf4,0xa9,0xdb,0xeb,0xe0,0x8e,0xd1); +DEFINE_GUID(IID_ID3D11ShaderResourceView,0xb0e06fe0,0x8192,0x4e1a,0xb1,0xca,0x36,0xd7,0x41,0x47,0x10,0xb2); +DEFINE_GUID(IID_ID3D11RenderTargetView,0xdfdba067,0x0b8d,0x4865,0x87,0x5b,0xd7,0xb4,0x51,0x6c,0xc1,0x64); +DEFINE_GUID(IID_ID3D11DepthStencilView,0x9fdac92a,0x1876,0x48c3,0xaf,0xad,0x25,0xb9,0x4f,0x84,0xa9,0xb6); +DEFINE_GUID(IID_ID3D11UnorderedAccessView,0x28acf509,0x7f5c,0x48f6,0x86,0x11,0xf3,0x16,0x01,0x0a,0x63,0x80); +DEFINE_GUID(IID_ID3D11VertexShader,0x3b301d64,0xd678,0x4289,0x88,0x97,0x22,0xf8,0x92,0x8b,0x72,0xf3); +DEFINE_GUID(IID_ID3D11HullShader,0x8e5c6061,0x628a,0x4c8e,0x82,0x64,0xbb,0xe4,0x5c,0xb3,0xd5,0xdd); +DEFINE_GUID(IID_ID3D11DomainShader,0xf582c508,0x0f36,0x490c,0x99,0x77,0x31,0xee,0xce,0x26,0x8c,0xfa); +DEFINE_GUID(IID_ID3D11GeometryShader,0x38325b96,0xeffb,0x4022,0xba,0x02,0x2e,0x79,0x5b,0x70,0x27,0x5c); +DEFINE_GUID(IID_ID3D11PixelShader,0xea82e40d,0x51dc,0x4f33,0x93,0xd4,0xdb,0x7c,0x91,0x25,0xae,0x8c); +DEFINE_GUID(IID_ID3D11ComputeShader,0x4f5b196e,0xc2bd,0x495e,0xbd,0x01,0x1f,0xde,0xd3,0x8e,0x49,0x69); +DEFINE_GUID(IID_ID3D11InputLayout,0xe4819ddc,0x4cf0,0x4025,0xbd,0x26,0x5d,0xe8,0x2a,0x3e,0x07,0xb7); +DEFINE_GUID(IID_ID3D11SamplerState,0xda6fea51,0x564c,0x4487,0x98,0x10,0xf0,0xd0,0xf9,0xb4,0xe3,0xa5); +DEFINE_GUID(IID_ID3D11Asynchronous,0x4b35d0cd,0x1e15,0x4258,0x9c,0x98,0x1b,0x13,0x33,0xf6,0xdd,0x3b); +DEFINE_GUID(IID_ID3D11Query,0xd6c00747,0x87b7,0x425e,0xb8,0x4d,0x44,0xd1,0x08,0x56,0x0a,0xfd); +DEFINE_GUID(IID_ID3D11Predicate,0x9eb576dd,0x9f77,0x4d86,0x81,0xaa,0x8b,0xab,0x5f,0xe4,0x90,0xe2); +DEFINE_GUID(IID_ID3D11Counter,0x6e8c49fb,0xa371,0x4770,0xb4,0x40,0x29,0x08,0x60,0x22,0xb7,0x41); +DEFINE_GUID(IID_ID3D11ClassInstance,0xa6cd7faa,0xb0b7,0x4a2f,0x94,0x36,0x86,0x62,0xa6,0x57,0x97,0xcb); +DEFINE_GUID(IID_ID3D11ClassLinkage,0xddf57cba,0x9543,0x46e4,0xa1,0x2b,0xf2,0x07,0xa0,0xfe,0x7f,0xed); +DEFINE_GUID(IID_ID3D11CommandList,0xa24bc4d1,0x769e,0x43f7,0x80,0x13,0x98,0xff,0x56,0x6c,0x18,0xe2); +DEFINE_GUID(IID_ID3D11DeviceContext,0xc0bfa96c,0xe089,0x44fb,0x8e,0xaf,0x26,0xf8,0x79,0x61,0x90,0xda); +DEFINE_GUID(IID_ID3D11VideoDecoder,0x3C9C5B51,0x995D,0x48d1,0x9B,0x8D,0xFA,0x5C,0xAE,0xDE,0xD6,0x5C); +DEFINE_GUID(IID_ID3D11VideoProcessorEnumerator,0x31627037,0x53AB,0x4200,0x90,0x61,0x05,0xFA,0xA9,0xAB,0x45,0xF9); +DEFINE_GUID(IID_ID3D11VideoProcessor,0x1D7B0652,0x185F,0x41c6,0x85,0xCE,0x0C,0x5B,0xE3,0xD4,0xAE,0x6C); +DEFINE_GUID(IID_ID3D11AuthenticatedChannel,0x3015A308,0xDCBD,0x47aa,0xA7,0x47,0x19,0x24,0x86,0xD1,0x4D,0x4A); +DEFINE_GUID(IID_ID3D11CryptoSession,0x9B32F9AD,0xBDCC,0x40a6,0xA3,0x9D,0xD5,0xC8,0x65,0x84,0x57,0x20); +DEFINE_GUID(IID_ID3D11VideoDecoderOutputView,0xC2931AEA,0x2A85,0x4f20,0x86,0x0F,0xFB,0xA1,0xFD,0x25,0x6E,0x18); +DEFINE_GUID(IID_ID3D11VideoProcessorInputView,0x11EC5A5F,0x51DC,0x4945,0xAB,0x34,0x6E,0x8C,0x21,0x30,0x0E,0xA5); +DEFINE_GUID(IID_ID3D11VideoProcessorOutputView,0xA048285E,0x25A9,0x4527,0xBD,0x93,0xD6,0x8B,0x68,0xC4,0x42,0x54); +DEFINE_GUID(IID_ID3D11VideoContext,0x61F21C45,0x3C0E,0x4a74,0x9C,0xEA,0x67,0x10,0x0D,0x9A,0xD5,0xE4); +DEFINE_GUID(IID_ID3D11VideoDevice,0x10EC4D5B,0x975A,0x4689,0xB9,0xE4,0xD0,0xAA,0xC3,0x0F,0xE3,0x33); +DEFINE_GUID(IID_ID3D11Device,0xdb6f6ddb,0xac77,0x4e88,0x82,0x53,0x81,0x9d,0xf9,0xbb,0xf1,0x40); + +/* dxgi.h GUIDs */ + +DEFINE_GUID(IID_IDXGIObject, 0xaec22fb8, 0x76f3, 0x4639, 0x9b, 0xe0, 0x28, 0xeb, 0x43, 0xa6, 0x7a, 0x2e); +DEFINE_GUID(IID_IDXGIDeviceSubObject, 0x3d3e0379, 0xf9de, 0x4d58, 0xbb, 0x6c, 0x18, 0xd6, 0x29, 0x92, 0xf1, 0xa6); +DEFINE_GUID(IID_IDXGIResource, 0x035f3ab4, 0x482e, 0x4e50, 0xb4, 0x1f, 0x8a, 0x7f, 0x8b, 0xd8, 0x96, 0x0b); +DEFINE_GUID(IID_IDXGIKeyedMutex, 0x9d8e1289, 0xd7b3, 0x465f, 0x81, 0x26, 0x25, 0x0e, 0x34, 0x9a, 0xf8, 0x5d); +DEFINE_GUID(IID_IDXGISurface, 0xcafcb56c, 0x6ac3, 0x4889, 0xbf, 0x47, 0x9e, 0x23, 0xbb, 0xd2, 0x60, 0xec); +DEFINE_GUID(IID_IDXGISurface1, 0x4AE63092, 0x6327, 0x4c1b, 0x80, 0xAE, 0xBF, 0xE1, 0x2E, 0xA3, 0x2B, 0x86); +DEFINE_GUID(IID_IDXGIAdapter, 0x2411e7e1, 0x12ac, 0x4ccf, 0xbd, 0x14, 0x97, 0x98, 0xe8, 0x53, 0x4d, 0xc0); +DEFINE_GUID(IID_IDXGIOutput, 0xae02eedb, 0xc735, 0x4690, 0x8d, 0x52, 0x5a, 0x8d, 0xc2, 0x02, 0x13, 0xaa); +DEFINE_GUID(IID_IDXGISwapChain, 0x310d36a0, 0xd2e7, 0x4c0a, 0xaa, 0x04, 0x6a, 0x9d, 0x23, 0xb8, 0x88, 0x6a); +DEFINE_GUID(IID_IDXGIFactory, 0x7b7166ec, 0x21c7, 0x44ae, 0xb2, 0x1a, 0xc9, 0xae, 0x32, 0x1a, 0xe3, 0x69); +DEFINE_GUID(IID_IDXGIDevice, 0x54ec77fa, 0x1377, 0x44e6, 0x8c, 0x32, 0x88, 0xfd, 0x5f, 0x44, 0xc8, 0x4c); +DEFINE_GUID(IID_IDXGIFactory1, 0x770aae78, 0xf26f, 0x4dba, 0xa8, 0x29, 0x25, 0x3c, 0x83, 0xd1, 0xb3, 0x87); +DEFINE_GUID(IID_IDXGIAdapter1, 0x29038f61, 0x3839, 0x4626, 0x91, 0xfd, 0x08, 0x68, 0x79, 0x01, 0x1a, 0x05); +DEFINE_GUID(IID_IDXGIDevice1, 0x77db970f, 0x6276, 0x48ba, 0xba, 0x28, 0x07, 0x01, 0x43, 0xb4, 0x39, 0x2c); + +/* dxgi1_2.h GUIDs */ + +DEFINE_GUID(IID_IDXGIDisplayControl, 0xea9dbf1a, 0xc88e, 0x4486, 0x85, 0x4a, 0x98, 0xaa, 0x01, 0x38, 0xf3, 0x0c); +DEFINE_GUID(IID_IDXGIOutputDuplication, 0x191cfac3, 0xa341, 0x470d, 0xb2, 0x6e, 0xa8, 0x64, 0xf4, 0x28, 0x31, 0x9c); +DEFINE_GUID(IID_IDXGISurface2, 0xaba496dd, 0xb617, 0x4cb8, 0xa8, 0x66, 0xbc, 0x44, 0xd7, 0xeb, 0x1f, 0xa2); +DEFINE_GUID(IID_IDXGIResource1, 0x30961379, 0x4609, 0x4a41, 0x99, 0x8e, 0x54, 0xfe, 0x56, 0x7e, 0xe0, 0xc1); +DEFINE_GUID(IID_IDXGIDevice2, 0x05008617, 0xfbfd, 0x4051, 0xa7, 0x90, 0x14, 0x48, 0x84, 0xb4, 0xf6, 0xa9); +DEFINE_GUID(IID_IDXGISwapChain1, 0x790a45f7, 0x0d42, 0x4876, 0x98, 0x3a, 0x0a, 0x55, 0xcf, 0xe6, 0xf4, 0xaa); +DEFINE_GUID(IID_IDXGIFactory2, 0x50c83a1c, 0xe072, 0x4c48, 0x87, 0xb0, 0x36, 0x30, 0xfa, 0x36, 0xa6, 0xd0); +DEFINE_GUID(IID_IDXGIAdapter2, 0x0AA1AE0A, 0xFA0E, 0x4B84, 0x86, 0x44, 0xE0, 0x5F, 0xF8, 0xE5, 0xAC, 0xB5); +DEFINE_GUID(IID_IDXGIOutput1, 0x00cddea8, 0x939b, 0x4b83, 0xa3, 0x40, 0xa6, 0x85, 0x22, 0x66, 0x66, 0xcc); + +const char* GetDxgiErrorString(HRESULT hr) +{ + switch (hr) + { + case DXGI_STATUS_OCCLUDED: + return "DXGI_STATUS_OCCLUDED"; + case DXGI_STATUS_CLIPPED: + return "DXGI_STATUS_CLIPPED"; + case DXGI_STATUS_NO_REDIRECTION: + return "DXGI_STATUS_NO_REDIRECTION"; + case DXGI_STATUS_NO_DESKTOP_ACCESS: + return "DXGI_STATUS_NO_DESKTOP_ACCESS"; + case DXGI_STATUS_GRAPHICS_VIDPN_SOURCE_IN_USE: + return "DXGI_STATUS_GRAPHICS_VIDPN_SOURCE_IN_USE"; + case DXGI_STATUS_MODE_CHANGED: + return "DXGI_STATUS_MODE_CHANGED"; + case DXGI_STATUS_MODE_CHANGE_IN_PROGRESS: + return "DXGI_STATUS_MODE_CHANGE_IN_PROGRESS"; + case DXGI_ERROR_INVALID_CALL: + return "DXGI_ERROR_INVALID_CALL"; + case DXGI_ERROR_NOT_FOUND: + return "DXGI_ERROR_NOT_FOUND"; + case DXGI_ERROR_MORE_DATA: + return "DXGI_ERROR_MORE_DATA"; + case DXGI_ERROR_UNSUPPORTED: + return "DXGI_ERROR_UNSUPPORTED"; + case DXGI_ERROR_DEVICE_REMOVED: + return "DXGI_ERROR_DEVICE_REMOVED"; + case DXGI_ERROR_DEVICE_HUNG: + return "DXGI_ERROR_DEVICE_HUNG"; + case DXGI_ERROR_DEVICE_RESET: + return "DXGI_ERROR_DEVICE_RESET"; + case DXGI_ERROR_WAS_STILL_DRAWING: + return "DXGI_ERROR_WAS_STILL_DRAWING"; + case DXGI_ERROR_FRAME_STATISTICS_DISJOINT: + return "DXGI_ERROR_FRAME_STATISTICS_DISJOINT"; + case DXGI_ERROR_GRAPHICS_VIDPN_SOURCE_IN_USE: + return "DXGI_ERROR_GRAPHICS_VIDPN_SOURCE_IN_USE"; + case DXGI_ERROR_DRIVER_INTERNAL_ERROR: + return "DXGI_ERROR_DRIVER_INTERNAL_ERROR"; + case DXGI_ERROR_NONEXCLUSIVE: + return "DXGI_ERROR_NONEXCLUSIVE"; + case DXGI_ERROR_NOT_CURRENTLY_AVAILABLE: + return "DXGI_ERROR_NOT_CURRENTLY_AVAILABLE"; + case DXGI_ERROR_REMOTE_CLIENT_DISCONNECTED: + return "DXGI_ERROR_REMOTE_CLIENT_DISCONNECTED"; + case DXGI_ERROR_REMOTE_OUTOFMEMORY: + return "DXGI_ERROR_REMOTE_OUTOFMEMORY"; + case DXGI_ERROR_ACCESS_LOST: + return "DXGI_ERROR_ACCESS_LOST"; + case DXGI_ERROR_WAIT_TIMEOUT: + return "DXGI_ERROR_WAIT_TIMEOUT"; + case DXGI_ERROR_SESSION_DISCONNECTED: + return "DXGI_ERROR_SESSION_DISCONNECTED"; + case DXGI_ERROR_RESTRICT_TO_OUTPUT_STALE: + return "DXGI_ERROR_RESTRICT_TO_OUTPUT_STALE"; + case DXGI_ERROR_CANNOT_PROTECT_CONTENT: + return "DXGI_ERROR_CANNOT_PROTECT_CONTENT"; + case DXGI_ERROR_ACCESS_DENIED: + return "DXGI_ERROR_ACCESS_DENIED"; + case DXGI_ERROR_NAME_ALREADY_EXISTS: + return "DXGI_ERROR_NAME_ALREADY_EXISTS"; + case DXGI_ERROR_SDK_COMPONENT_MISSING: + return "DXGI_ERROR_SDK_COMPONENT_MISSING"; + case DXGI_STATUS_UNOCCLUDED: + return "DXGI_STATUS_UNOCCLUDED"; + case DXGI_STATUS_DDA_WAS_STILL_DRAWING: + return "DXGI_STATUS_DDA_WAS_STILL_DRAWING"; + case DXGI_ERROR_MODE_CHANGE_IN_PROGRESS: + return "DXGI_ERROR_MODE_CHANGE_IN_PROGRESS"; + case DXGI_DDI_ERR_WASSTILLDRAWING: + return "DXGI_DDI_ERR_WASSTILLDRAWING"; + case DXGI_DDI_ERR_UNSUPPORTED: + return "DXGI_DDI_ERR_UNSUPPORTED"; + case DXGI_DDI_ERR_NONEXCLUSIVE: + return "DXGI_DDI_ERR_NONEXCLUSIVE"; + case 0x80070005: + return "DXGI_ERROR_ACCESS_DENIED"; + } + + return "DXGI_ERROR_UNKNOWN"; +} + +static void win_shadow_d3d11_module_init() +{ + if (d3d11_module) + return; + + d3d11_module = LoadLibraryA("d3d11.dll"); + + if (!d3d11_module) + return; + + pfnD3D11CreateDevice = (fnD3D11CreateDevice) GetProcAddress(d3d11_module, "D3D11CreateDevice"); +} + +int win_shadow_dxgi_init_duplication(winShadowSubsystem* subsystem) +{ + HRESULT hr; + UINT dTop, i = 0; + IDXGIOutput* pOutput; + DXGI_OUTPUT_DESC outputDesc; + DXGI_OUTPUT_DESC* pOutputDesc; + D3D11_TEXTURE2D_DESC textureDesc; + IDXGIDevice* dxgiDevice = NULL; + IDXGIAdapter* dxgiAdapter = NULL; + IDXGIOutput* dxgiOutput = NULL; + IDXGIOutput1* dxgiOutput1 = NULL; + + hr = subsystem->dxgiDevice->lpVtbl->QueryInterface(subsystem->dxgiDevice, + &IID_IDXGIDevice, (void**) &dxgiDevice); + + if (FAILED(hr)) + { + fprintf(stderr, "ID3D11Device::QueryInterface(IDXGIDevice) failure: %s (0x%04X)\n", + GetDxgiErrorString(hr), hr); + return -1; + } + + hr = dxgiDevice->lpVtbl->GetParent(dxgiDevice, &IID_IDXGIAdapter, (void**) &dxgiAdapter); + + if (dxgiDevice) + { + dxgiDevice->lpVtbl->Release(dxgiDevice); + dxgiDevice = NULL; + } + + if (FAILED(hr)) + { + fprintf(stderr, "IDXGIDevice::GetParent(IDXGIAdapter) failure: %s (0x%04X)\n", + GetDxgiErrorString(hr), hr); + return -1; + } + + pOutput = NULL; + ZeroMemory(&outputDesc, sizeof(outputDesc)); + + while (dxgiAdapter->lpVtbl->EnumOutputs(dxgiAdapter, i, &pOutput) != DXGI_ERROR_NOT_FOUND) + { + pOutputDesc = &outputDesc; + + hr = pOutput->lpVtbl->GetDesc(pOutput, pOutputDesc); + + if (FAILED(hr)) + { + fprintf(stderr, "IDXGIOutput::GetDesc failure: %s (0x%04X)\n", + GetDxgiErrorString(hr), hr); + return -1; + } + + if (pOutputDesc->AttachedToDesktop) + dTop = i; + + pOutput->lpVtbl->Release(pOutput); + i++; + } + + dTop = 0; /* screen id */ + + hr = dxgiAdapter->lpVtbl->EnumOutputs(dxgiAdapter, dTop, &dxgiOutput); + + if (dxgiAdapter) + { + dxgiAdapter->lpVtbl->Release(dxgiAdapter); + dxgiAdapter = NULL; + } + + if (FAILED(hr)) + { + fprintf(stderr, "IDXGIAdapter::EnumOutputs failure: %s (0x%04X)\n", + GetDxgiErrorString(hr), hr); + return -1; + } + + hr = dxgiOutput->lpVtbl->QueryInterface(dxgiOutput, &IID_IDXGIOutput1, (void**) &dxgiOutput1); + + if (dxgiOutput) + { + dxgiOutput->lpVtbl->Release(dxgiOutput); + dxgiOutput = NULL; + } + + if (FAILED(hr)) + { + fprintf(stderr, "IDXGIOutput::QueryInterface(IDXGIOutput1) failure: %s (0x%04X)\n", + GetDxgiErrorString(hr), hr); + return -1; + } + + hr = dxgiOutput1->lpVtbl->DuplicateOutput(dxgiOutput1, (IUnknown*) subsystem->dxgiDevice, + &(subsystem->dxgiOutputDuplication)); + + if (dxgiOutput1) + { + dxgiOutput1->lpVtbl->Release(dxgiOutput1); + dxgiOutput1 = NULL; + } + + if (FAILED(hr)) + { + fprintf(stderr, "IDXGIOutput1::DuplicateOutput failure: %s (0x%04X)\n", + GetDxgiErrorString(hr), hr); + return -1; + } + + textureDesc.Width = subsystem->width; + textureDesc.Height = subsystem->height; + textureDesc.MipLevels = 1; + textureDesc.ArraySize = 1; + textureDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM; + textureDesc.SampleDesc.Count = 1; + textureDesc.SampleDesc.Quality = 0; + textureDesc.Usage = D3D11_USAGE_STAGING; + textureDesc.BindFlags = 0; + textureDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ; + textureDesc.MiscFlags = 0; + + hr = subsystem->dxgiDevice->lpVtbl->CreateTexture2D(subsystem->dxgiDevice, + &textureDesc, NULL, &(subsystem->dxgiStage)); + + if (FAILED(hr)) + { + fprintf(stderr, "ID3D11Device::CreateTexture2D failure: %s (0x%04X)\n", + GetDxgiErrorString(hr), hr); + return -1; + } + + return 1; +} + +int win_shadow_dxgi_init(winShadowSubsystem* subsystem) +{ + UINT i = 0; + HRESULT hr; + int status; + UINT DriverTypeIndex; + IDXGIDevice* DxgiDevice = NULL; + IDXGIAdapter* DxgiAdapter = NULL; + IDXGIOutput* DxgiOutput = NULL; + IDXGIOutput1* DxgiOutput1 = NULL; + + win_shadow_d3d11_module_init(); + + if (!pfnD3D11CreateDevice) + return -1; + + for (DriverTypeIndex = 0; DriverTypeIndex < NumDriverTypes; ++DriverTypeIndex) + { + hr = pfnD3D11CreateDevice(NULL, DriverTypes[DriverTypeIndex], NULL, 0, FeatureLevels, + NumFeatureLevels, D3D11_SDK_VERSION, &(subsystem->dxgiDevice), &(subsystem->featureLevel), + &(subsystem->dxgiDeviceContext)); + + if (SUCCEEDED(hr)) + break; + } + + if (FAILED(hr)) + { + fprintf(stderr, "D3D11CreateDevice failure: 0x%04X\n", hr); + return -1; + } + + status = win_shadow_dxgi_init_duplication(subsystem); + + return status; +} + +int win_shadow_dxgi_uninit(winShadowSubsystem* subsystem) +{ + if (subsystem->dxgiStage) + { + subsystem->dxgiStage->lpVtbl->Release(subsystem->dxgiStage); + subsystem->dxgiStage = NULL; + } + + if (subsystem->dxgiDesktopImage) + { + subsystem->dxgiDesktopImage->lpVtbl->Release(subsystem->dxgiDesktopImage); + subsystem->dxgiDesktopImage = NULL; + } + + if (subsystem->dxgiOutputDuplication) + { + subsystem->dxgiOutputDuplication->lpVtbl->Release(subsystem->dxgiOutputDuplication); + subsystem->dxgiOutputDuplication = NULL; + } + + if (subsystem->dxgiDeviceContext) + { + subsystem->dxgiDeviceContext->lpVtbl->Release(subsystem->dxgiDeviceContext); + subsystem->dxgiDeviceContext = NULL; + } + + if (subsystem->dxgiDevice) + { + subsystem->dxgiDevice->lpVtbl->Release(subsystem->dxgiDevice); + subsystem->dxgiDevice = NULL; + } + + return 1; +} + +int win_shadow_dxgi_fetch_frame_data(winShadowSubsystem* subsystem, + BYTE** ppDstData, int* pnDstStep, int x, int y, int width, int height) +{ + int status; + HRESULT hr; + D3D11_BOX Box; + DXGI_MAPPED_RECT mappedRect; + + if ((width * height) < 1) + return 0; + + Box.top = x; + Box.left = y; + Box.right = x + width; + Box.bottom = y + height; + Box.front = 0; + Box.back = 1; + + subsystem->dxgiDeviceContext->lpVtbl->CopySubresourceRegion(subsystem->dxgiDeviceContext, + (ID3D11Resource*) subsystem->dxgiStage, 0, 0, 0, 0, (ID3D11Resource*) subsystem->dxgiDesktopImage, 0, &Box); + + hr = subsystem->dxgiStage->lpVtbl->QueryInterface(subsystem->dxgiStage, + &IID_IDXGISurface, (void**) &(subsystem->dxgiSurface)); + + if (FAILED(hr)) + { + fprintf(stderr, "ID3D11Texture2D::QueryInterface(IDXGISurface) failure: %s 0x%04X\n", + GetDxgiErrorString(hr), hr); + return -1; + } + + hr = subsystem->dxgiSurface->lpVtbl->Map(subsystem->dxgiSurface, &mappedRect, DXGI_MAP_READ); + + if (FAILED(hr)) + { + fprintf(stderr, "IDXGISurface::Map failure: %s 0x%04X\n", + GetDxgiErrorString(hr), hr); + + if (hr == DXGI_ERROR_DEVICE_REMOVED) + { + win_shadow_dxgi_uninit(subsystem); + + status = win_shadow_dxgi_init(subsystem); + + if (status < 0) + return -1; + + return 0; + } + + return -1; + } + + subsystem->dxgiSurfaceMapped = TRUE; + + *ppDstData = mappedRect.pBits; + *pnDstStep = mappedRect.Pitch; + + return 1; +} + +int win_shadow_dxgi_release_frame_data(winShadowSubsystem* subsystem) +{ + if (subsystem->dxgiSurface) + { + if (subsystem->dxgiSurfaceMapped) + { + subsystem->dxgiSurface->lpVtbl->Unmap(subsystem->dxgiSurface); + subsystem->dxgiSurfaceMapped = FALSE; + } + + subsystem->dxgiSurface->lpVtbl->Release(subsystem->dxgiSurface); + subsystem->dxgiSurface = NULL; + } + + if (subsystem->dxgiOutputDuplication) + { + if (subsystem->dxgiFrameAcquired) + { + subsystem->dxgiOutputDuplication->lpVtbl->ReleaseFrame(subsystem->dxgiOutputDuplication); + subsystem->dxgiFrameAcquired = FALSE; + } + } + + subsystem->pendingFrames = 0; + + return 1; +} + +int win_shadow_dxgi_get_next_frame(winShadowSubsystem* subsystem) +{ + UINT i = 0; + int status; + HRESULT hr = 0; + UINT timeout = 15; + UINT DataBufferSize = 0; + BYTE* DataBuffer = NULL; + + if (subsystem->dxgiFrameAcquired) + { + win_shadow_dxgi_release_frame_data(subsystem); + } + + if (subsystem->dxgiDesktopImage) + { + subsystem->dxgiDesktopImage->lpVtbl->Release(subsystem->dxgiDesktopImage); + subsystem->dxgiDesktopImage = NULL; + } + + hr = subsystem->dxgiOutputDuplication->lpVtbl->AcquireNextFrame(subsystem->dxgiOutputDuplication, + timeout, &(subsystem->dxgiFrameInfo), &(subsystem->dxgiResource)); + + if (SUCCEEDED(hr)) + { + subsystem->dxgiFrameAcquired = TRUE; + subsystem->pendingFrames = subsystem->dxgiFrameInfo.AccumulatedFrames; + } + + if (hr == DXGI_ERROR_WAIT_TIMEOUT) + return 0; + + if (FAILED(hr)) + { + fprintf(stderr, "IDXGIOutputDuplication::AcquireNextFrame failure: %s (0x%04X)\n", + GetDxgiErrorString(hr), hr); + + if (hr == DXGI_ERROR_ACCESS_LOST) + { + win_shadow_dxgi_release_frame_data(subsystem); + + if (subsystem->dxgiDesktopImage) + { + subsystem->dxgiDesktopImage->lpVtbl->Release(subsystem->dxgiDesktopImage); + subsystem->dxgiDesktopImage = NULL; + } + + if (subsystem->dxgiOutputDuplication) + { + subsystem->dxgiOutputDuplication->lpVtbl->Release(subsystem->dxgiOutputDuplication); + subsystem->dxgiOutputDuplication = NULL; + } + + status = win_shadow_dxgi_init_duplication(subsystem); + + if (status < 0) + return -1; + + return 0; + } + else if (hr == DXGI_ERROR_INVALID_CALL) + { + win_shadow_dxgi_uninit(subsystem); + + status = win_shadow_dxgi_init(subsystem); + + if (status < 0) + return -1; + + return 0; + } + + return -1; + } + + hr = subsystem->dxgiResource->lpVtbl->QueryInterface(subsystem->dxgiResource, + &IID_ID3D11Texture2D, (void**) &(subsystem->dxgiDesktopImage)); + + if (subsystem->dxgiResource) + { + subsystem->dxgiResource->lpVtbl->Release(subsystem->dxgiResource); + subsystem->dxgiResource = NULL; + } + + if (FAILED(hr)) + { + fprintf(stderr, "IDXGIResource::QueryInterface(ID3D11Texture2D) failure: %s (0x%04X)\n", + GetDxgiErrorString(hr), hr); + return -1; + } + + return 1; +} + +int win_shadow_dxgi_get_invalid_region(winShadowSubsystem* subsystem) +{ + UINT i; + HRESULT hr; + POINT* pSrcPt; + RECT* pDstRect; + RECT* pDirtyRect; + UINT numMoveRects; + UINT numDirtyRects; + UINT UsedBufferSize; + RECTANGLE_16 invalidRect; + UINT MetadataBufferSize; + UINT MoveRectsBufferSize; + UINT DirtyRectsBufferSize; + RECT* pDirtyRectsBuffer; + DXGI_OUTDUPL_MOVE_RECT* pMoveRect; + DXGI_OUTDUPL_MOVE_RECT* pMoveRectBuffer; + + if (subsystem->dxgiFrameInfo.AccumulatedFrames == 0) + return 0; + + if (subsystem->dxgiFrameInfo.TotalMetadataBufferSize == 0) + return 0; + + MetadataBufferSize = subsystem->dxgiFrameInfo.TotalMetadataBufferSize; + + if (MetadataBufferSize > subsystem->MetadataBufferSize) + { + subsystem->MetadataBuffer = (BYTE*) realloc(subsystem->MetadataBuffer, MetadataBufferSize); + + if (!subsystem->MetadataBuffer) + return -1; + + subsystem->MetadataBufferSize = MetadataBufferSize; + } + + /* GetFrameMoveRects */ + + UsedBufferSize = 0; + + MoveRectsBufferSize = MetadataBufferSize - UsedBufferSize; + pMoveRectBuffer = (DXGI_OUTDUPL_MOVE_RECT*) &(subsystem->MetadataBuffer[UsedBufferSize]); + + hr = subsystem->dxgiOutputDuplication->lpVtbl->GetFrameMoveRects(subsystem->dxgiOutputDuplication, + MoveRectsBufferSize, pMoveRectBuffer, &MoveRectsBufferSize); + + if (FAILED(hr)) + { + fprintf(stderr, "IDXGIOutputDuplication::GetFrameMoveRects failure: %s (0x%04X) Size: %d Total %d Used: %d\n", + GetDxgiErrorString(hr), hr, MoveRectsBufferSize, MetadataBufferSize, UsedBufferSize); + return -1; + } + + /* GetFrameDirtyRects */ + + UsedBufferSize += MoveRectsBufferSize; + + DirtyRectsBufferSize = MetadataBufferSize - UsedBufferSize; + pDirtyRectsBuffer = (RECT*) &(subsystem->MetadataBuffer[UsedBufferSize]); + + hr = subsystem->dxgiOutputDuplication->lpVtbl->GetFrameDirtyRects(subsystem->dxgiOutputDuplication, + DirtyRectsBufferSize, pDirtyRectsBuffer, &DirtyRectsBufferSize); + + if (FAILED(hr)) + { + fprintf(stderr, "IDXGIOutputDuplication::GetFrameDirtyRects failure: %s (0x%04X) Size: %d Total %d Used: %d\n", + GetDxgiErrorString(hr), hr, DirtyRectsBufferSize, MetadataBufferSize, UsedBufferSize); + return -1; + } + + numMoveRects = MoveRectsBufferSize / sizeof(DXGI_OUTDUPL_MOVE_RECT); + + for (i = 0; i < numMoveRects; i++) + { + pMoveRect = &pMoveRectBuffer[i]; + pSrcPt = &(pMoveRect->SourcePoint); + pDstRect = &(pMoveRect->DestinationRect); + + invalidRect.left = (UINT16) pDstRect->left; + invalidRect.top = (UINT16) pDstRect->top; + invalidRect.right = (UINT16) pDstRect->right; + invalidRect.bottom = (UINT16) pDstRect->bottom; + + region16_union_rect(&(subsystem->invalidRegion), &(subsystem->invalidRegion), &invalidRect); + } + + numDirtyRects = DirtyRectsBufferSize / sizeof(RECT); + + for (i = 0; i < numDirtyRects; i++) + { + pDirtyRect = &pDirtyRectsBuffer[i]; + + invalidRect.left = (UINT16) pDirtyRect->left; + invalidRect.top = (UINT16) pDirtyRect->top; + invalidRect.right = (UINT16) pDirtyRect->right; + invalidRect.bottom = (UINT16) pDirtyRect->bottom; + + region16_union_rect(&(subsystem->invalidRegion), &(subsystem->invalidRegion), &invalidRect); + } + + return 1; +} + +#endif diff --git a/server/shadow/Win/win_dxgi.h b/server/shadow/Win/win_dxgi.h new file mode 100644 index 000000000..1dcdf7ac8 --- /dev/null +++ b/server/shadow/Win/win_dxgi.h @@ -0,0 +1,60 @@ +/** + * FreeRDP: A Remote Desktop Protocol Implementation + * + * Copyright 2014 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef FREERDP_SHADOW_SERVER_WIN_DXGI_H +#define FREERDP_SHADOW_SERVER_WIN_DXGI_H + +#if _WIN32_WINNT >= 0x0602 +//#define WITH_DXGI_1_2 1 +#endif + +#ifdef WITH_DXGI_1_2 + +#ifndef CINTERFACE +#define CINTERFACE +#endif + +#include +#include + +#endif + +#include "win_shadow.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef WITH_DXGI_1_2 + +int win_shadow_dxgi_init(winShadowSubsystem* subsystem); +int win_shadow_dxgi_uninit(winShadowSubsystem* subsystem); + +int win_shadow_dxgi_fetch_frame_data(winShadowSubsystem* subsystem, + BYTE** ppDstData, int* pnDstStep, int x, int y, int width, int height); + +int win_shadow_dxgi_get_next_frame(winShadowSubsystem* subsystem); +int win_shadow_dxgi_get_invalid_region(winShadowSubsystem* subsystem); + +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* FREERDP_SHADOW_SERVER_WIN_DXGI_H */ diff --git a/server/shadow/Win/win_rdp.c b/server/shadow/Win/win_rdp.c new file mode 100644 index 000000000..eef6fd724 --- /dev/null +++ b/server/shadow/Win/win_rdp.c @@ -0,0 +1,428 @@ +/** + * FreeRDP: A Remote Desktop Protocol Implementation + * + * Copyright 2014 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include + +#include "win_rdp.h" + +void shw_OnChannelConnectedEventHandler(rdpContext* context, ChannelConnectedEventArgs* e) +{ + shwContext* shw = (shwContext*) context; + + printf("OnChannelConnected: %s\n", e->name); +} + +void shw_OnChannelDisconnectedEventHandler(rdpContext* context, ChannelDisconnectedEventArgs* e) +{ + shwContext* shw = (shwContext*) context; + + printf("OnChannelDisconnected: %s\n", e->name); +} + +void shw_begin_paint(rdpContext* context) +{ + shwContext* shw; + rdpGdi* gdi = context->gdi; + + shw = (shwContext*) context; + + gdi->primary->hdc->hwnd->invalid->null = 1; + gdi->primary->hdc->hwnd->ninvalid = 0; +} + +void shw_end_paint(rdpContext* context) +{ + int index; + int ninvalid; + HGDI_RGN cinvalid; + RECTANGLE_16 invalidRect; + rdpGdi* gdi = context->gdi; + shwContext* shw = (shwContext*) context; + winShadowSubsystem* subsystem = shw->subsystem; + + ninvalid = gdi->primary->hdc->hwnd->ninvalid; + cinvalid = gdi->primary->hdc->hwnd->cinvalid; + + for (index = 0; index < ninvalid; index++) + { + invalidRect.left = cinvalid[index].x; + invalidRect.top = cinvalid[index].y; + invalidRect.right = cinvalid[index].x + cinvalid[index].w; + invalidRect.bottom = cinvalid[index].y + cinvalid[index].h; + + region16_union_rect(&(subsystem->invalidRegion), &(subsystem->invalidRegion), &invalidRect); + } + + SetEvent(subsystem->RdpUpdateEnterEvent); + WaitForSingleObject(subsystem->RdpUpdateLeaveEvent, INFINITE); + ResetEvent(subsystem->RdpUpdateLeaveEvent); +} + +void shw_desktop_resize(rdpContext* context) +{ + +} + +void shw_surface_frame_marker(rdpContext* context, SURFACE_FRAME_MARKER* surfaceFrameMarker) +{ + shwContext* shw = (shwContext*) context; +} + +BOOL shw_authenticate(freerdp* instance, char** username, char** password, char** domain) +{ + return TRUE; +} + +BOOL shw_verify_certificate(freerdp* instance, char* subject, char* issuer, char* fingerprint) +{ + return TRUE; +} + +int shw_verify_x509_certificate(freerdp* instance, BYTE* data, int length, const char* hostname, int port, DWORD flags) +{ + return 1; +} + +void shw_OnConnectionResultEventHandler(rdpContext* context, ConnectionResultEventArgs* e) +{ + shwContext* shw = (shwContext*) context; + printf("OnConnectionResult: %d\n", e->result); +} + +BOOL shw_pre_connect(freerdp* instance) +{ + shwContext* shw; + rdpContext* context = instance->context; + + shw = (shwContext*) context; + + PubSub_SubscribeConnectionResult(context->pubSub, + (pConnectionResultEventHandler) shw_OnConnectionResultEventHandler); + + PubSub_SubscribeChannelConnected(context->pubSub, + (pChannelConnectedEventHandler) shw_OnChannelConnectedEventHandler); + + PubSub_SubscribeChannelDisconnected(context->pubSub, + (pChannelDisconnectedEventHandler) shw_OnChannelDisconnectedEventHandler); + + freerdp_client_load_addins(context->channels, instance->settings); + + freerdp_channels_pre_connect(context->channels, instance); + + return TRUE; +} + +BOOL shw_post_connect(freerdp* instance) +{ + rdpGdi* gdi; + shwContext* shw; + rdpSettings* settings; + + shw = (shwContext*) instance->context; + settings = instance->settings; + + gdi_init(instance, CLRBUF_32BPP, NULL); + gdi = instance->context->gdi; + + instance->update->BeginPaint = shw_begin_paint; + instance->update->EndPaint = shw_end_paint; + instance->update->DesktopResize = shw_desktop_resize; + instance->update->SurfaceFrameMarker = shw_surface_frame_marker; + + freerdp_channels_post_connect(instance->context->channels, instance); + + return TRUE; +} + +void* shw_client_thread(void* arg) +{ + int index; + int rcount; + int wcount; + BOOL bSuccess; + void* rfds[32]; + void* wfds[32]; + int fds_count; + HANDLE fds[64]; + shwContext* shw; + rdpContext* context; + rdpChannels* channels; + freerdp* instance = (freerdp*) arg; + + ZeroMemory(rfds, sizeof(rfds)); + ZeroMemory(wfds, sizeof(wfds)); + + context = (rdpContext*) instance->context; + shw = (shwContext*) context; + + bSuccess = freerdp_connect(instance); + + printf("freerdp_connect: %d\n", bSuccess); + + if (!bSuccess) + { + ExitThread(0); + return NULL; + } + + channels = instance->context->channels; + + while (1) + { + rcount = 0; + wcount = 0; + + if (!freerdp_get_fds(instance, rfds, &rcount, wfds, &wcount)) + { + fprintf(stderr, "Failed to get FreeRDP file descriptor\n"); + break; + } + + if (!freerdp_channels_get_fds(channels, instance, rfds, &rcount, wfds, &wcount)) + { + fprintf(stderr, "Failed to get channels file descriptor\n"); + break; + } + + fds_count = 0; + + for (index = 0; index < rcount; index++) + fds[fds_count++] = rfds[index]; + + for (index = 0; index < wcount; index++) + fds[fds_count++] = wfds[index]; + + if (MsgWaitForMultipleObjects(fds_count, fds, FALSE, 1000, QS_ALLINPUT) == WAIT_FAILED) + { + fprintf(stderr, "MsgWaitForMultipleObjects failure: 0x%08X", GetLastError()); + break; + } + + if (!freerdp_check_fds(instance)) + { + fprintf(stderr, "Failed to check FreeRDP file descriptor\n"); + break; + } + + if (freerdp_shall_disconnect(instance)) + { + break; + } + + if (!freerdp_channels_check_fds(channels, instance)) + { + fprintf(stderr, "Failed to check channels file descriptor\n"); + break; + } + } + + freerdp_free(instance); + + ExitThread(0); + return NULL; +} + +/** + * Client Interface + */ + +void shw_freerdp_client_global_init(void) +{ + +} + +void shw_freerdp_client_global_uninit(void) +{ + +} + +int shw_freerdp_client_start(rdpContext* context) +{ + shwContext* shw; + freerdp* instance = context->instance; + + shw = (shwContext*) context; + + shw->thread = CreateThread(NULL, 0, + (LPTHREAD_START_ROUTINE) shw_client_thread, + instance, 0, NULL); + + return 0; +} + +int shw_freerdp_client_stop(rdpContext* context) +{ + shwContext* shw = (shwContext*) context; + + SetEvent(shw->StopEvent); + + return 0; +} + +int shw_freerdp_client_new(freerdp* instance, rdpContext* context) +{ + shwContext* shw; + rdpSettings* settings; + + shw = (shwContext*) instance->context; + + instance->PreConnect = shw_pre_connect; + instance->PostConnect = shw_post_connect; + instance->Authenticate = shw_authenticate; + instance->VerifyCertificate = shw_verify_certificate; + instance->VerifyX509Certificate = shw_verify_x509_certificate; + + context->channels = freerdp_channels_new(); + + shw->StopEvent = CreateEvent(NULL, TRUE, FALSE, NULL); + + settings = instance->settings; + shw->settings = instance->context->settings; + + settings->AsyncTransport = FALSE; + settings->AsyncChannels = FALSE; + settings->AsyncUpdate = FALSE; + settings->AsyncInput = FALSE; + + settings->IgnoreCertificate = TRUE; + settings->ExternalCertificateManagement = TRUE; + + settings->RdpSecurity = TRUE; + settings->TlsSecurity = TRUE; + settings->NlaSecurity = FALSE; + + settings->BitmapCacheEnabled = FALSE; + settings->BitmapCacheV3Enabled = FALSE; + settings->OffscreenSupportLevel = FALSE; + settings->GlyphSupportLevel = GLYPH_SUPPORT_NONE; + settings->BrushSupportLevel = FALSE; + + ZeroMemory(settings->OrderSupport, 32); + + settings->FrameMarkerCommandEnabled = TRUE; + settings->SurfaceFrameMarkerEnabled = TRUE; + settings->AltSecFrameMarkerSupport = TRUE; + + settings->ColorDepth = 32; + settings->NSCodec = TRUE; + settings->RemoteFxCodec = TRUE; + settings->FastPathInput = TRUE; + settings->FastPathOutput = TRUE; + settings->LargePointerFlag = TRUE; + + settings->CompressionEnabled = FALSE; + + settings->AutoReconnectionEnabled = FALSE; + settings->NetworkAutoDetect = FALSE; + settings->SupportHeartbeatPdu = FALSE; + settings->SupportMultitransport = FALSE; + settings->ConnectionType = CONNECTION_TYPE_LAN; + + settings->AllowFontSmoothing = TRUE; + settings->AllowDesktopComposition = TRUE; + settings->DisableWallpaper = FALSE; + settings->DisableFullWindowDrag = TRUE; + settings->DisableMenuAnims = TRUE; + settings->DisableThemes = FALSE; + + settings->DeviceRedirection = TRUE; + settings->RedirectClipboard = TRUE; + settings->SupportDynamicChannels = TRUE; + + return 0; +} + +void shw_freerdp_client_free(freerdp* instance, rdpContext* context) +{ + shwContext* shw = (shwContext*) instance->context; +} + +int shw_RdpClientEntry(RDP_CLIENT_ENTRY_POINTS* pEntryPoints) +{ + pEntryPoints->Version = 1; + pEntryPoints->Size = sizeof(RDP_CLIENT_ENTRY_POINTS_V1); + + pEntryPoints->settings = NULL; + + pEntryPoints->ContextSize = sizeof(shwContext); + pEntryPoints->GlobalInit = shw_freerdp_client_global_init; + pEntryPoints->GlobalUninit = shw_freerdp_client_global_uninit; + pEntryPoints->ClientNew = shw_freerdp_client_new; + pEntryPoints->ClientFree = shw_freerdp_client_free; + pEntryPoints->ClientStart = shw_freerdp_client_start; + pEntryPoints->ClientStop = shw_freerdp_client_stop; + + return 0; +} + +int win_shadow_rdp_init(winShadowSubsystem* subsystem) +{ + rdpContext* context; + RDP_CLIENT_ENTRY_POINTS clientEntryPoints; + + ZeroMemory(&clientEntryPoints, sizeof(RDP_CLIENT_ENTRY_POINTS)); + clientEntryPoints.Size = sizeof(RDP_CLIENT_ENTRY_POINTS); + clientEntryPoints.Version = RDP_CLIENT_INTERFACE_VERSION; + + shw_RdpClientEntry(&clientEntryPoints); + + context = freerdp_client_context_new(&clientEntryPoints); + + subsystem->shw = (shwContext*) context; + subsystem->shw->settings = context->settings; + subsystem->shw->subsystem = subsystem; + + subsystem->RdpUpdateEnterEvent = CreateEvent(NULL, TRUE, FALSE, NULL); + subsystem->RdpUpdateLeaveEvent = CreateEvent(NULL, TRUE, FALSE, NULL); + + return 1; +} + +int win_shadow_rdp_start(winShadowSubsystem* subsystem) +{ + int status; + shwContext* shw = subsystem->shw; + rdpContext* context = (rdpContext*) shw; + + status = freerdp_client_start(context); + + return status; +} + +int win_shadow_rdp_stop(winShadowSubsystem* subsystem) +{ + int status; + shwContext* shw = subsystem->shw; + rdpContext* context = (rdpContext*) shw; + + status = freerdp_client_stop(context); + + return status; +} + +int win_shadow_rdp_uninit(winShadowSubsystem* subsystem) +{ + win_shadow_rdp_stop(subsystem); + + return 1; +} diff --git a/server/shadow/Win/win_rdp.h b/server/shadow/Win/win_rdp.h new file mode 100644 index 000000000..e48d46e6b --- /dev/null +++ b/server/shadow/Win/win_rdp.h @@ -0,0 +1,56 @@ +/** + * FreeRDP: A Remote Desktop Protocol Implementation + * + * Copyright 2014 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef FREERDP_SHADOW_SERVER_WIN_RDP_H +#define FREERDP_SHADOW_SERVER_WIN_RDP_H + +#include +#include +#include +#include + +typedef struct shw_context shwContext; + +#include "win_shadow.h" + +struct shw_context +{ + rdpContext context; + DEFINE_RDP_CLIENT_COMMON(); + + HANDLE StopEvent; + freerdp* instance; + rdpSettings* settings; + winShadowSubsystem* subsystem; +}; + +#ifdef __cplusplus +extern "C" { +#endif + +int win_shadow_rdp_init(winShadowSubsystem* subsystem); +int win_shadow_rdp_uninit(winShadowSubsystem* subsystem); + +int win_shadow_rdp_start(winShadowSubsystem* subsystem); +int win_shadow_rdp_stop(winShadowSubsystem* subsystem); + +#ifdef __cplusplus +} +#endif + +#endif /* FREERDP_SHADOW_SERVER_WIN_RDP_H */ diff --git a/server/shadow/Win/win_shadow.c b/server/shadow/Win/win_shadow.c new file mode 100644 index 000000000..a2299d808 --- /dev/null +++ b/server/shadow/Win/win_shadow.c @@ -0,0 +1,534 @@ +/** + * FreeRDP: A Remote Desktop Protocol Implementation + * + * Copyright 2011-2014 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include + +#include +#include + +#include "../shadow_screen.h" +#include "../shadow_surface.h" +#include "../shadow_capture.h" + +#include "win_shadow.h" + +void win_shadow_input_synchronize_event(winShadowSubsystem* subsystem, UINT32 flags) +{ + +} + +void win_shadow_input_keyboard_event(winShadowSubsystem* subsystem, UINT16 flags, UINT16 code) +{ + INPUT event; + + event.type = INPUT_KEYBOARD; + event.ki.wVk = 0; + event.ki.wScan = code; + event.ki.dwFlags = KEYEVENTF_SCANCODE; + event.ki.dwExtraInfo = 0; + event.ki.time = 0; + + if (flags & KBD_FLAGS_RELEASE) + event.ki.dwFlags |= KEYEVENTF_KEYUP; + + if (flags & KBD_FLAGS_EXTENDED) + event.ki.dwFlags |= KEYEVENTF_EXTENDEDKEY; + + SendInput(1, &event, sizeof(INPUT)); +} + +void win_shadow_input_unicode_keyboard_event(winShadowSubsystem* subsystem, UINT16 flags, UINT16 code) +{ + INPUT event; + + event.type = INPUT_KEYBOARD; + event.ki.wVk = 0; + event.ki.wScan = code; + event.ki.dwFlags = KEYEVENTF_UNICODE; + event.ki.dwExtraInfo = 0; + event.ki.time = 0; + + if (flags & KBD_FLAGS_RELEASE) + event.ki.dwFlags |= KEYEVENTF_KEYUP; + + SendInput(1, &event, sizeof(INPUT)); +} + +void win_shadow_input_mouse_event(winShadowSubsystem* subsystem, UINT16 flags, UINT16 x, UINT16 y) +{ + INPUT event; + float width; + float height; + + ZeroMemory(&event, sizeof(INPUT)); + + event.type = INPUT_MOUSE; + + if (flags & PTR_FLAGS_WHEEL) + { + event.mi.dwFlags = MOUSEEVENTF_WHEEL; + event.mi.mouseData = flags & WheelRotationMask; + + if (flags & PTR_FLAGS_WHEEL_NEGATIVE) + event.mi.mouseData *= -1; + + SendInput(1, &event, sizeof(INPUT)); + } + else + { + width = (float) GetSystemMetrics(SM_CXSCREEN); + height = (float) GetSystemMetrics(SM_CYSCREEN); + + event.mi.dx = (LONG) ((float) x * (65535.0f / width)); + event.mi.dy = (LONG) ((float) y * (65535.0f / height)); + event.mi.dwFlags = MOUSEEVENTF_ABSOLUTE; + + if (flags & PTR_FLAGS_MOVE) + { + event.mi.dwFlags |= MOUSEEVENTF_MOVE; + SendInput(1, &event, sizeof(INPUT)); + } + + event.mi.dwFlags = MOUSEEVENTF_ABSOLUTE; + + if (flags & PTR_FLAGS_BUTTON1) + { + if (flags & PTR_FLAGS_DOWN) + event.mi.dwFlags |= MOUSEEVENTF_LEFTDOWN; + else + event.mi.dwFlags |= MOUSEEVENTF_LEFTUP; + + SendInput(1, &event, sizeof(INPUT)); + } + else if (flags & PTR_FLAGS_BUTTON2) + { + if (flags & PTR_FLAGS_DOWN) + event.mi.dwFlags |= MOUSEEVENTF_RIGHTDOWN; + else + event.mi.dwFlags |= MOUSEEVENTF_RIGHTUP; + + SendInput(1, &event, sizeof(INPUT)); + } + else if (flags & PTR_FLAGS_BUTTON3) + { + if (flags & PTR_FLAGS_DOWN) + event.mi.dwFlags |= MOUSEEVENTF_MIDDLEDOWN; + else + event.mi.dwFlags |= MOUSEEVENTF_MIDDLEUP; + + SendInput(1, &event, sizeof(INPUT)); + } + } +} + +void win_shadow_input_extended_mouse_event(winShadowSubsystem* subsystem, UINT16 flags, UINT16 x, UINT16 y) +{ + INPUT event; + float width; + float height; + + ZeroMemory(&event, sizeof(INPUT)); + + if ((flags & PTR_XFLAGS_BUTTON1) || (flags & PTR_XFLAGS_BUTTON2)) + { + event.type = INPUT_MOUSE; + + if (flags & PTR_FLAGS_MOVE) + { + width = (float) GetSystemMetrics(SM_CXSCREEN); + height = (float) GetSystemMetrics(SM_CYSCREEN); + + event.mi.dx = (LONG)((float) x * (65535.0f / width)); + event.mi.dy = (LONG)((float) y * (65535.0f / height)); + event.mi.dwFlags = MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE; + + SendInput(1, &event, sizeof(INPUT)); + } + + event.mi.dx = event.mi.dy = event.mi.dwFlags = 0; + + if (flags & PTR_XFLAGS_DOWN) + event.mi.dwFlags |= MOUSEEVENTF_XDOWN; + else + event.mi.dwFlags |= MOUSEEVENTF_XUP; + + if (flags & PTR_XFLAGS_BUTTON1) + event.mi.mouseData = XBUTTON1; + else if (flags & PTR_XFLAGS_BUTTON2) + event.mi.mouseData = XBUTTON2; + + SendInput(1, &event, sizeof(INPUT)); + } +} + + +int win_shadow_invalidate_region(winShadowSubsystem* subsystem, int x, int y, int width, int height) +{ + rdpShadowServer* server; + rdpShadowScreen* screen; + RECTANGLE_16 invalidRect; + + server = subsystem->server; + screen = server->screen; + + invalidRect.left = x; + invalidRect.top = y; + invalidRect.right = x + width; + invalidRect.bottom = y + height; + + EnterCriticalSection(&(screen->lock)); + region16_union_rect(&(screen->invalidRegion), &(screen->invalidRegion), &invalidRect); + LeaveCriticalSection(&(screen->lock)); + + return 1; +} + +int win_shadow_surface_copy(winShadowSubsystem* subsystem) +{ + int x, y; + int width; + int height; + int count; + int status = 1; + int nDstStep = 0; + BYTE* pDstData = NULL; + rdpShadowServer* server; + rdpShadowSurface* surface; + RECTANGLE_16 surfaceRect; + RECTANGLE_16 invalidRect; + const RECTANGLE_16* extents; + + server = subsystem->server; + surface = server->surface; + + if (ArrayList_Count(server->clients) < 1) + { + region16_clear(&(subsystem->invalidRegion)); + return 1; + } + + surfaceRect.left = surface->x; + surfaceRect.top = surface->y; + surfaceRect.right = surface->x + surface->width; + surfaceRect.bottom = surface->y + surface->height; + + region16_intersect_rect(&(subsystem->invalidRegion), &(subsystem->invalidRegion), &surfaceRect); + + if (region16_is_empty(&(subsystem->invalidRegion))) + return 1; + + extents = region16_extents(&(subsystem->invalidRegion)); + CopyMemory(&invalidRect, extents, sizeof(RECTANGLE_16)); + + shadow_capture_align_clip_rect(&invalidRect, &surfaceRect); + + x = invalidRect.left; + y = invalidRect.top; + width = invalidRect.right - invalidRect.left; + height = invalidRect.bottom - invalidRect.top; + + if (0) + { + x = 0; + y = 0; + width = surface->width; + height = surface->height; + } + + printf("SurfaceCopy x: %d y: %d width: %d height: %d right: %d bottom: %d\n", + x, y, width, height, x + width, y + height); + +#if defined(WITH_WDS_API) + { + rdpGdi* gdi; + shwContext* shw; + rdpContext* context; + + shw = subsystem->shw; + context = (rdpContext*) shw; + gdi = context->gdi; + + pDstData = gdi->primary_buffer; + nDstStep = gdi->width * 4; + } +#elif defined(WITH_DXGI_1_2) + status = win_shadow_dxgi_fetch_frame_data(subsystem, &pDstData, &nDstStep, x, y, width, height); +#endif + + if (status <= 0) + return status; + + freerdp_image_copy(surface->data, PIXEL_FORMAT_XRGB32, + surface->scanline, x - surface->x, y - surface->y, width, height, + pDstData, PIXEL_FORMAT_XRGB32, nDstStep, 0, 0); + + ArrayList_Lock(server->clients); + + count = ArrayList_Count(server->clients); + + InitializeSynchronizationBarrier(&(subsystem->barrier), count + 1, -1); + + SetEvent(subsystem->updateEvent); + + EnterSynchronizationBarrier(&(subsystem->barrier), 0); + ResetEvent(subsystem->updateEvent); + + DeleteSynchronizationBarrier(&(subsystem->barrier)); + + ArrayList_Unlock(server->clients); + + region16_clear(&(subsystem->invalidRegion)); + + return 1; +} + +#if defined(WITH_WDS_API) + +void* win_shadow_subsystem_thread(winShadowSubsystem* subsystem) +{ + DWORD status; + DWORD nCount; + HANDLE events[32]; + HANDLE StopEvent; + + StopEvent = subsystem->server->StopEvent; + + nCount = 0; + events[nCount++] = StopEvent; + events[nCount++] = subsystem->RdpUpdateEnterEvent; + + while (1) + { + status = WaitForMultipleObjects(nCount, events, FALSE, INFINITE); + + if (WaitForSingleObject(StopEvent, 0) == WAIT_OBJECT_0) + { + break; + } + + if (WaitForSingleObject(subsystem->RdpUpdateEnterEvent, 0) == WAIT_OBJECT_0) + { + win_shadow_surface_copy(subsystem); + ResetEvent(subsystem->RdpUpdateEnterEvent); + SetEvent(subsystem->RdpUpdateLeaveEvent); + } + } + + ExitThread(0); + return NULL; +} + +#elif defined(WITH_DXGI_1_2) + +void* win_shadow_subsystem_thread(winShadowSubsystem* subsystem) +{ + int fps; + DWORD status; + DWORD nCount; + UINT64 cTime; + DWORD dwTimeout; + DWORD dwInterval; + UINT64 frameTime; + HANDLE events[32]; + HANDLE StopEvent; + + StopEvent = subsystem->server->StopEvent; + + nCount = 0; + events[nCount++] = StopEvent; + + fps = 16; + dwInterval = 1000 / fps; + frameTime = GetTickCount64() + dwInterval; + + while (1) + { + dwTimeout = INFINITE; + + cTime = GetTickCount64(); + dwTimeout = (DWORD) ((cTime > frameTime) ? 0 : frameTime - cTime); + + status = WaitForMultipleObjects(nCount, events, FALSE, dwTimeout); + + if (WaitForSingleObject(StopEvent, 0) == WAIT_OBJECT_0) + { + break; + } + + if ((status == WAIT_TIMEOUT) || (GetTickCount64() > frameTime)) + { + int dxgi_status; + + dxgi_status = win_shadow_dxgi_get_next_frame(subsystem); + + if (dxgi_status > 0) + dxgi_status = win_shadow_dxgi_get_invalid_region(subsystem); + + if (dxgi_status > 0) + win_shadow_surface_copy(subsystem); + + dwInterval = 1000 / fps; + frameTime += dwInterval; + } + } + + ExitThread(0); + return NULL; +} + +#endif + +int win_shadow_subsystem_init(winShadowSubsystem* subsystem) +{ + HDC hdc; + int status; + DWORD iDevNum = 0; + MONITOR_DEF* virtualScreen; + DISPLAY_DEVICE DisplayDevice; + + ZeroMemory(&DisplayDevice, sizeof(DISPLAY_DEVICE)); + DisplayDevice.cb = sizeof(DISPLAY_DEVICE); + + if (!EnumDisplayDevices(NULL, iDevNum, &DisplayDevice, 0)) + return -1; + + hdc = CreateDC(DisplayDevice.DeviceName, NULL, NULL, NULL); + + subsystem->width = GetDeviceCaps(hdc, HORZRES); + subsystem->height = GetDeviceCaps(hdc, VERTRES); + subsystem->bpp = GetDeviceCaps(hdc, BITSPIXEL); + + DeleteDC(hdc); + +#if defined(WITH_WDS_API) + status = win_shadow_wds_init(subsystem); +#elif defined(WITH_DXGI_1_2) + status = win_shadow_dxgi_init(subsystem); +#endif + + virtualScreen = &(subsystem->virtualScreen); + + virtualScreen->left = 0; + virtualScreen->top = 0; + virtualScreen->right = subsystem->width; + virtualScreen->bottom = subsystem->height; + virtualScreen->flags = 1; + + if (subsystem->monitorCount < 1) + { + subsystem->monitorCount = 1; + subsystem->monitors[0].left = virtualScreen->left; + subsystem->monitors[0].top = virtualScreen->top; + subsystem->monitors[0].right = virtualScreen->right; + subsystem->monitors[0].bottom = virtualScreen->bottom; + subsystem->monitors[0].flags = 1; + } + + printf("width: %d height: %d\n", subsystem->width, subsystem->height); + + return 1; +} + +int win_shadow_subsystem_uninit(winShadowSubsystem* subsystem) +{ + if (!subsystem) + return -1; + +#if defined(WITH_WDS_API) + win_shadow_wds_uninit(subsystem); +#elif defined(WITH_DXGI_1_2) + win_shadow_dxgi_uninit(subsystem); +#endif + + return 1; +} + +int win_shadow_subsystem_start(winShadowSubsystem* subsystem) +{ + HANDLE thread; + + if (!subsystem) + return -1; + + thread = CreateThread(NULL, 0, + (LPTHREAD_START_ROUTINE) win_shadow_subsystem_thread, + (void*) subsystem, 0, NULL); + + return 1; +} + +int win_shadow_subsystem_stop(winShadowSubsystem* subsystem) +{ + if (!subsystem) + return -1; + + return 1; +} + +void win_shadow_subsystem_free(winShadowSubsystem* subsystem) +{ + if (!subsystem) + return; + + win_shadow_subsystem_uninit(subsystem); + + region16_uninit(&(subsystem->invalidRegion)); + + CloseHandle(subsystem->updateEvent); + + free(subsystem); +} + +winShadowSubsystem* win_shadow_subsystem_new(rdpShadowServer* server) +{ + winShadowSubsystem* subsystem; + + subsystem = (winShadowSubsystem*) calloc(1, sizeof(winShadowSubsystem)); + + if (!subsystem) + return NULL; + + subsystem->server = server; + + subsystem->updateEvent = CreateEvent(NULL, TRUE, FALSE, NULL); + + region16_init(&(subsystem->invalidRegion)); + + subsystem->Init = (pfnShadowSubsystemInit) win_shadow_subsystem_init; + subsystem->Uninit = (pfnShadowSubsystemInit) win_shadow_subsystem_uninit; + subsystem->Start = (pfnShadowSubsystemStart) win_shadow_subsystem_start; + subsystem->Stop = (pfnShadowSubsystemStop) win_shadow_subsystem_stop; + subsystem->Free = (pfnShadowSubsystemFree) win_shadow_subsystem_free; + + subsystem->SurfaceCopy = (pfnShadowSurfaceCopy) win_shadow_surface_copy; + + subsystem->SynchronizeEvent = (pfnShadowSynchronizeEvent) win_shadow_input_synchronize_event; + subsystem->KeyboardEvent = (pfnShadowKeyboardEvent) win_shadow_input_keyboard_event; + subsystem->UnicodeKeyboardEvent = (pfnShadowUnicodeKeyboardEvent) win_shadow_input_unicode_keyboard_event; + subsystem->MouseEvent = (pfnShadowMouseEvent) win_shadow_input_mouse_event; + subsystem->ExtendedMouseEvent = (pfnShadowExtendedMouseEvent) win_shadow_input_extended_mouse_event; + + return subsystem; +} + +rdpShadowSubsystem* Win_ShadowCreateSubsystem(rdpShadowServer* server) +{ + return (rdpShadowSubsystem*) win_shadow_subsystem_new(server); +} diff --git a/server/shadow/Win/win_shadow.h b/server/shadow/Win/win_shadow.h new file mode 100644 index 000000000..c403bd6f1 --- /dev/null +++ b/server/shadow/Win/win_shadow.h @@ -0,0 +1,90 @@ +/** + * FreeRDP: A Remote Desktop Protocol Implementation + * + * Copyright 2011-2014 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef FREERDP_SHADOW_SERVER_WIN_H +#define FREERDP_SHADOW_SERVER_WIN_H + +#include + +#include + +typedef struct win_shadow_subsystem winShadowSubsystem; + +#include +#include +#include +#include +#include + +#include "win_rdp.h" +#include "win_wds.h" +#include "win_dxgi.h" + +struct win_shadow_subsystem +{ + RDP_SHADOW_SUBSYSTEM_COMMON(); + + int bpp; + int width; + int height; + +#ifdef WITH_WDS_API + HWND hWnd; + shwContext* shw; + HANDLE RdpUpdateEnterEvent; + HANDLE RdpUpdateLeaveEvent; + rdpAssistanceFile* pAssistanceFile; + _IRDPSessionEvents* pSessionEvents; + IRDPSRAPISharingSession* pSharingSession; + IRDPSRAPIInvitation* pInvitation; + IRDPSRAPIInvitationManager* pInvitationMgr; + IRDPSRAPISessionProperties* pSessionProperties; + IRDPSRAPIVirtualChannelManager* pVirtualChannelMgr; + IRDPSRAPIApplicationFilter* pApplicationFilter; + IRDPSRAPIAttendeeManager* pAttendeeMgr; +#endif + +#ifdef WITH_DXGI_1_2 + UINT pendingFrames; + BYTE* MetadataBuffer; + UINT MetadataBufferSize; + BOOL dxgiSurfaceMapped; + BOOL dxgiFrameAcquired; + ID3D11Device* dxgiDevice; + IDXGISurface* dxgiSurface; + ID3D11Texture2D* dxgiStage; + IDXGIResource* dxgiResource; + D3D_FEATURE_LEVEL featureLevel; + ID3D11Texture2D* dxgiDesktopImage; + DXGI_OUTDUPL_FRAME_INFO dxgiFrameInfo; + ID3D11DeviceContext* dxgiDeviceContext; + IDXGIOutputDuplication* dxgiOutputDuplication; +#endif +}; + +#ifdef __cplusplus +extern "C" { +#endif + + + +#ifdef __cplusplus +} +#endif + +#endif /* FREERDP_SHADOW_SERVER_WIN_H */ diff --git a/server/shadow/Win/win_wds.c b/server/shadow/Win/win_wds.c new file mode 100644 index 000000000..52e2d1cec --- /dev/null +++ b/server/shadow/Win/win_wds.c @@ -0,0 +1,882 @@ +/** + * FreeRDP: A Remote Desktop Protocol Implementation + * + * Copyright 2014 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include + +#include "win_rdp.h" + +#include "win_wds.h" + +/** + * Windows Desktop Sharing API: + * http://blogs.msdn.com/b/rds/archive/2007/03/08/windows-desktop-sharing-api.aspx + * + * Windows Desktop Sharing Interfaces: + * http://msdn.microsoft.com/en-us/library/aa373871%28v=vs.85%29.aspx + * + * Offer Remote Assistance Sample C: + * http://msdn.microsoft.com/en-us/library/ms811079.aspx#remoteassistanceapi_topic2b + * + * Remote Assistance in XP: Programmatically establish an RDP session: + * http://www.codeproject.com/Articles/29939/Remote-Assistance-in-XP-Programmatically-establish + */ + +#undef DEFINE_GUID +#define INITGUID + +#include + +DEFINE_GUID(CLSID_RDPSession,0x9B78F0E6,0x3E05,0x4A5B,0xB2,0xE8,0xE7,0x43,0xA8,0x95,0x6B,0x65); +DEFINE_GUID(DIID__IRDPSessionEvents,0x98a97042,0x6698,0x40e9,0x8e,0xfd,0xb3,0x20,0x09,0x90,0x00,0x4b); +DEFINE_GUID(IID_IRDPSRAPISharingSession,0xeeb20886,0xe470,0x4cf6,0x84,0x2b,0x27,0x39,0xc0,0xec,0x5c,0xfb); +DEFINE_GUID(IID_IRDPSRAPIAttendee,0xec0671b3,0x1b78,0x4b80,0xa4,0x64,0x91,0x32,0x24,0x75,0x43,0xe3); +DEFINE_GUID(IID_IRDPSRAPIAttendeeManager,0xba3a37e8,0x33da,0x4749,0x8d,0xa0,0x07,0xfa,0x34,0xda,0x79,0x44); +DEFINE_GUID(IID_IRDPSRAPISessionProperties,0x339b24f2,0x9bc0,0x4f16,0x9a,0xac,0xf1,0x65,0x43,0x3d,0x13,0xd4); +DEFINE_GUID(CLSID_RDPSRAPIApplicationFilter,0xe35ace89,0xc7e8,0x427e,0xa4,0xf9,0xb9,0xda,0x07,0x28,0x26,0xbd); +DEFINE_GUID(CLSID_RDPSRAPIInvitationManager,0x53d9c9db,0x75ab,0x4271,0x94,0x8a,0x4c,0x4e,0xb3,0x6a,0x8f,0x2b); + +static ULONG Shadow_IRDPSessionEvents_RefCount = 0; + +const char* GetRDPSessionEventString(DISPID id) +{ + switch (id) + { + case DISPID_RDPSRAPI_EVENT_ON_ATTENDEE_CONNECTED: + return "OnAttendeeConnected"; + break; + + case DISPID_RDPSRAPI_EVENT_ON_ATTENDEE_DISCONNECTED: + return "OnAttendeeDisconnected"; + break; + + case DISPID_RDPSRAPI_EVENT_ON_ATTENDEE_UPDATE: + return "OnAttendeeUpdate"; + break; + + case DISPID_RDPSRAPI_EVENT_ON_ERROR: + return "OnError"; + break; + + case DISPID_RDPSRAPI_EVENT_ON_VIEWER_CONNECTED: + return "OnConnectionEstablished"; + break; + + case DISPID_RDPSRAPI_EVENT_ON_VIEWER_DISCONNECTED: + return "OnConnectionTerminated"; + break; + + case DISPID_RDPSRAPI_EVENT_ON_VIEWER_AUTHENTICATED: + return "OnConnectionAuthenticated"; + break; + + case DISPID_RDPSRAPI_EVENT_ON_VIEWER_CONNECTFAILED: + return "OnConnectionFailed"; + break; + + case DISPID_RDPSRAPI_EVENT_ON_CTRLLEVEL_CHANGE_REQUEST: + return "OnControlLevelChangeRequest"; + break; + + case DISPID_RDPSRAPI_EVENT_ON_GRAPHICS_STREAM_PAUSED: + return "OnGraphicsStreamPaused"; + break; + + case DISPID_RDPSRAPI_EVENT_ON_GRAPHICS_STREAM_RESUMED: + return "OnGraphicsStreamResumed"; + break; + + case DISPID_RDPSRAPI_EVENT_ON_VIRTUAL_CHANNEL_JOIN: + return "OnChannelJoin"; + break; + + case DISPID_RDPSRAPI_EVENT_ON_VIRTUAL_CHANNEL_LEAVE: + return "OnChannelLeave"; + break; + + case DISPID_RDPSRAPI_EVENT_ON_VIRTUAL_CHANNEL_DATARECEIVED: + return "OnChannelDataReceived"; + break; + + case DISPID_RDPSRAPI_EVENT_ON_VIRTUAL_CHANNEL_SENDCOMPLETED: + return "OnChannelDataSent"; + break; + + case DISPID_RDPSRAPI_EVENT_ON_APPLICATION_OPEN: + return "OnApplicationOpen"; + break; + + case DISPID_RDPSRAPI_EVENT_ON_APPLICATION_CLOSE: + return "OnApplicationClose"; + break; + + case DISPID_RDPSRAPI_EVENT_ON_APPLICATION_UPDATE: + return "OnApplicationUpdate"; + break; + + case DISPID_RDPSRAPI_EVENT_ON_WINDOW_OPEN: + return "OnWindowOpen"; + break; + + case DISPID_RDPSRAPI_EVENT_ON_WINDOW_CLOSE: + return "OnWindowClose"; + break; + + case DISPID_RDPSRAPI_EVENT_ON_WINDOW_UPDATE: + return "OnWindowUpdate"; + break; + + case DISPID_RDPSRAPI_EVENT_ON_APPFILTER_UPDATE: + return "OnAppFilterUpdate"; + break; + + case DISPID_RDPSRAPI_EVENT_ON_SHARED_RECT_CHANGED: + return "OnSharedRectChanged"; + break; + + case DISPID_RDPSRAPI_EVENT_ON_FOCUSRELEASED: + return "OnFocusReleased"; + break; + + case DISPID_RDPSRAPI_EVENT_ON_SHARED_DESKTOP_SETTINGS_CHANGED: + return "OnSharedDesktopSettingsChanged"; + break; + + case DISPID_RDPAPI_EVENT_ON_BOUNDING_RECT_CHANGED: + return "OnViewingSizeChanged"; + break; + } + + return "OnUnknown"; +} + +static HRESULT STDMETHODCALLTYPE Shadow_IRDPSessionEvents_QueryInterface( + __RPC__in _IRDPSessionEvents * This, + /* [in] */ __RPC__in REFIID riid, + /* [annotation][iid_is][out] */ + _COM_Outptr_ void **ppvObject) +{ + *ppvObject = NULL; + + if (IsEqualIID(riid, &DIID__IRDPSessionEvents) || + IsEqualIID(riid, &IID_IDispatch) || IsEqualIID(riid, &IID_IUnknown)) + { + *ppvObject = This; + } + + if (!(*ppvObject)) + return E_NOINTERFACE; + + This->lpVtbl->AddRef(This); + + return S_OK; +} + +static ULONG STDMETHODCALLTYPE Shadow_IRDPSessionEvents_AddRef( + __RPC__in _IRDPSessionEvents * This) +{ + Shadow_IRDPSessionEvents_RefCount++; + return Shadow_IRDPSessionEvents_RefCount; +} + +static ULONG STDMETHODCALLTYPE Shadow_IRDPSessionEvents_Release( + __RPC__in _IRDPSessionEvents * This) +{ + if (!Shadow_IRDPSessionEvents_RefCount) + return 0; + + Shadow_IRDPSessionEvents_RefCount--; + + return Shadow_IRDPSessionEvents_RefCount; +} + +static HRESULT STDMETHODCALLTYPE Shadow_IRDPSessionEvents_GetTypeInfoCount( + __RPC__in _IRDPSessionEvents * This, + /* [out] */ __RPC__out UINT *pctinfo) +{ + printf("Shadow_IRDPSessionEvents_GetTypeInfoCount\n"); + *pctinfo = 1; + return S_OK; +} + +static HRESULT STDMETHODCALLTYPE Shadow_IRDPSessionEvents_GetTypeInfo( + __RPC__in _IRDPSessionEvents * This, + /* [in] */ UINT iTInfo, + /* [in] */ LCID lcid, + /* [out] */ __RPC__deref_out_opt ITypeInfo **ppTInfo) +{ + printf("Shadow_IRDPSessionEvents_GetTypeInfo\n"); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE Shadow_IRDPSessionEvents_GetIDsOfNames( + __RPC__in _IRDPSessionEvents * This, + /* [in] */ __RPC__in REFIID riid, + /* [size_is][in] */ __RPC__in_ecount_full(cNames) LPOLESTR *rgszNames, + /* [range][in] */ __RPC__in_range(0,16384) UINT cNames, + /* [in] */ LCID lcid, + /* [size_is][out] */ __RPC__out_ecount_full(cNames) DISPID *rgDispId) +{ + printf("Shadow_IRDPSessionEvents_GetIDsOfNames\n"); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE Shadow_IRDPSessionEvents_Invoke( + _IRDPSessionEvents * This, + /* [annotation][in] */ + _In_ DISPID dispIdMember, + /* [annotation][in] */ + _In_ REFIID riid, + /* [annotation][in] */ + _In_ LCID lcid, + /* [annotation][in] */ + _In_ WORD wFlags, + /* [annotation][out][in] */ + _In_ DISPPARAMS *pDispParams, + /* [annotation][out] */ + _Out_opt_ VARIANT *pVarResult, + /* [annotation][out] */ + _Out_opt_ EXCEPINFO *pExcepInfo, + /* [annotation][out] */ + _Out_opt_ UINT *puArgErr) +{ + HRESULT hr; + VARIANT vr; + UINT uArgErr; + + printf("%s (%d)\n", GetRDPSessionEventString(dispIdMember), dispIdMember); + + switch (dispIdMember) + { + case DISPID_RDPSRAPI_EVENT_ON_ATTENDEE_CONNECTED: + { + int level; + IDispatch* pDispatch; + IRDPSRAPIAttendee* pAttendee; + + vr.vt = VT_DISPATCH; + vr.pdispVal = NULL; + + hr = DispGetParam(pDispParams, 0, VT_DISPATCH, &vr, &uArgErr); + + if (FAILED(hr)) + { + printf("%s DispGetParam(0, VT_DISPATCH) failure: 0x%08X\n", + GetRDPSessionEventString(dispIdMember), hr); + return hr; + } + + pDispatch = vr.pdispVal; + + hr = pDispatch->lpVtbl->QueryInterface(pDispatch, &IID_IRDPSRAPIAttendee, (void**) &pAttendee); + + if (FAILED(hr)) + { + printf("%s IDispatch::QueryInterface(IRDPSRAPIAttendee) failure: 0x%08X\n", + GetRDPSessionEventString(dispIdMember), hr); + return hr; + } + + level = CTRL_LEVEL_VIEW; + //level = CTRL_LEVEL_INTERACTIVE; + + hr = pAttendee->lpVtbl->put_ControlLevel(pAttendee, level); + + if (FAILED(hr)) + { + printf("%s IRDPSRAPIAttendee::put_ControlLevel() failure: 0x%08X\n", + GetRDPSessionEventString(dispIdMember), hr); + return hr; + } + + pAttendee->lpVtbl->Release(pAttendee); + } + break; + + case DISPID_RDPSRAPI_EVENT_ON_ATTENDEE_DISCONNECTED: + break; + + case DISPID_RDPSRAPI_EVENT_ON_ATTENDEE_UPDATE: + break; + + case DISPID_RDPSRAPI_EVENT_ON_ERROR: + break; + + case DISPID_RDPSRAPI_EVENT_ON_VIEWER_CONNECTED: + break; + + case DISPID_RDPSRAPI_EVENT_ON_VIEWER_DISCONNECTED: + break; + + case DISPID_RDPSRAPI_EVENT_ON_VIEWER_AUTHENTICATED: + break; + + case DISPID_RDPSRAPI_EVENT_ON_VIEWER_CONNECTFAILED: + break; + + case DISPID_RDPSRAPI_EVENT_ON_CTRLLEVEL_CHANGE_REQUEST: + { + int level; + IDispatch* pDispatch; + IRDPSRAPIAttendee* pAttendee; + + vr.vt = VT_INT; + vr.pdispVal = NULL; + + hr = DispGetParam(pDispParams, 1, VT_INT, &vr, &uArgErr); + + if (FAILED(hr)) + { + printf("%s DispGetParam(1, VT_INT) failure: 0x%08X\n", + GetRDPSessionEventString(dispIdMember), hr); + return hr; + } + + level = vr.intVal; + + vr.vt = VT_DISPATCH; + vr.pdispVal = NULL; + + hr = DispGetParam(pDispParams, 0, VT_DISPATCH, &vr, &uArgErr); + + if (FAILED(hr)) + { + printf("%s DispGetParam(0, VT_DISPATCH) failure: 0x%08X\n", + GetRDPSessionEventString(dispIdMember), hr); + return hr; + } + + pDispatch = vr.pdispVal; + + hr = pDispatch->lpVtbl->QueryInterface(pDispatch, &IID_IRDPSRAPIAttendee, (void**) &pAttendee); + + if (FAILED(hr)) + { + printf("%s IDispatch::QueryInterface(IRDPSRAPIAttendee) failure: 0x%08X\n", + GetRDPSessionEventString(dispIdMember), hr); + return hr; + } + + hr = pAttendee->lpVtbl->put_ControlLevel(pAttendee, level); + + if (FAILED(hr)) + { + printf("%s IRDPSRAPIAttendee::put_ControlLevel() failure: 0x%08X\n", + GetRDPSessionEventString(dispIdMember), hr); + return hr; + } + + pAttendee->lpVtbl->Release(pAttendee); + } + break; + + case DISPID_RDPSRAPI_EVENT_ON_GRAPHICS_STREAM_PAUSED: + break; + + case DISPID_RDPSRAPI_EVENT_ON_GRAPHICS_STREAM_RESUMED: + break; + + case DISPID_RDPSRAPI_EVENT_ON_VIRTUAL_CHANNEL_JOIN: + break; + + case DISPID_RDPSRAPI_EVENT_ON_VIRTUAL_CHANNEL_LEAVE: + break; + + case DISPID_RDPSRAPI_EVENT_ON_VIRTUAL_CHANNEL_DATARECEIVED: + break; + + case DISPID_RDPSRAPI_EVENT_ON_VIRTUAL_CHANNEL_SENDCOMPLETED: + break; + + case DISPID_RDPSRAPI_EVENT_ON_APPLICATION_OPEN: + break; + + case DISPID_RDPSRAPI_EVENT_ON_APPLICATION_CLOSE: + break; + + case DISPID_RDPSRAPI_EVENT_ON_APPLICATION_UPDATE: + break; + + case DISPID_RDPSRAPI_EVENT_ON_WINDOW_OPEN: + break; + + case DISPID_RDPSRAPI_EVENT_ON_WINDOW_CLOSE: + break; + + case DISPID_RDPSRAPI_EVENT_ON_WINDOW_UPDATE: + break; + + case DISPID_RDPSRAPI_EVENT_ON_APPFILTER_UPDATE: + break; + + case DISPID_RDPSRAPI_EVENT_ON_SHARED_RECT_CHANGED: + break; + + case DISPID_RDPSRAPI_EVENT_ON_FOCUSRELEASED: + break; + + case DISPID_RDPSRAPI_EVENT_ON_SHARED_DESKTOP_SETTINGS_CHANGED: + break; + + case DISPID_RDPAPI_EVENT_ON_BOUNDING_RECT_CHANGED: + break; + } + + return S_OK; +} + +static _IRDPSessionEventsVtbl Shadow_IRDPSessionEventsVtbl = +{ + /* IUnknown */ + Shadow_IRDPSessionEvents_QueryInterface, + Shadow_IRDPSessionEvents_AddRef, + Shadow_IRDPSessionEvents_Release, + + /* IDispatch */ + Shadow_IRDPSessionEvents_GetTypeInfoCount, + Shadow_IRDPSessionEvents_GetTypeInfo, + Shadow_IRDPSessionEvents_GetIDsOfNames, + Shadow_IRDPSessionEvents_Invoke +}; + +static _IRDPSessionEvents Shadow_IRDPSessionEvents = +{ + &Shadow_IRDPSessionEventsVtbl +}; + +static LRESULT CALLBACK ShadowWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + switch (uMsg) + { + case WM_CLOSE: + DestroyWindow(hwnd); + break; + + case WM_DESTROY: + PostQuitMessage(0); + break; + + default: + return DefWindowProc(hwnd, uMsg, wParam, lParam); + break; + } + + return 0; +} + +int win_shadow_wds_wnd_init(winShadowSubsystem* subsystem) +{ + HMODULE hModule; + HINSTANCE hInstance; + WNDCLASSEX wndClassEx; + + hModule = GetModuleHandle(NULL); + + ZeroMemory(&wndClassEx, sizeof(WNDCLASSEX)); + wndClassEx.cbSize = sizeof(WNDCLASSEX); + wndClassEx.style = 0; + wndClassEx.lpfnWndProc = ShadowWndProc; + wndClassEx.cbClsExtra = 0; + wndClassEx.cbWndExtra = 0; + wndClassEx.hInstance = hModule; + wndClassEx.hIcon = NULL; + wndClassEx.hCursor = NULL; + wndClassEx.hbrBackground = NULL; + wndClassEx.lpszMenuName = _T("ShadowWndMenu"); + wndClassEx.lpszClassName = _T("ShadowWndClass"); + wndClassEx.hIconSm = NULL; + + if (!RegisterClassEx(&wndClassEx)) + { + printf("RegisterClassEx failure\n"); + return -1; + } + + hInstance = wndClassEx.hInstance; + + subsystem->hWnd = CreateWindowEx(0, wndClassEx.lpszClassName, + 0, 0, 0, 0, 0, 0, HWND_MESSAGE, 0, hInstance, NULL); + + if (!subsystem->hWnd) + { + printf("CreateWindowEx failure\n"); + return -1; + } + + return 1; +} + +int win_shadow_wds_init(winShadowSubsystem* subsystem) +{ + int status; + HRESULT hr; + DWORD dwCookie; + long left, top; + long right, bottom; + long width, height; + IUnknown* pUnknown; + rdpSettings* settings; + BSTR bstrAuthString; + BSTR bstrGroupName; + BSTR bstrPassword; + BSTR bstrConnectionString; + BSTR bstrPropertyName; + VARIANT varPropertyValue; + rdpAssistanceFile* file; + IConnectionPoint* pCP; + IConnectionPointContainer* pCPC; + + win_shadow_wds_wnd_init(subsystem); + + hr = OleInitialize(NULL); + + if (FAILED(hr)) + { + fprintf(stderr, "OleInitialize() failure\n"); + return -1; + } + + hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED); + + if (FAILED(hr)) + { + fprintf(stderr, "CoInitialize() failure\n"); + return -1; + } + + hr = CoCreateInstance(&CLSID_RDPSession, NULL, CLSCTX_ALL, + &IID_IRDPSRAPISharingSession, (void**) &(subsystem->pSharingSession)); + + if (FAILED(hr)) + { + fprintf(stderr, "CoCreateInstance(IRDPSRAPISharingSession) failure: 0x%08X\n", hr); + return -1; + } + + pUnknown = (IUnknown*) subsystem->pSharingSession; + hr = pUnknown->lpVtbl->QueryInterface(pUnknown, &IID_IConnectionPointContainer, (void**) &pCPC); + + if (FAILED(hr)) + { + fprintf(stderr, "QueryInterface(IID_IConnectionPointContainer) failure: 0x%08X\n", hr); + return -1; + } + + pCPC->lpVtbl->FindConnectionPoint(pCPC, &DIID__IRDPSessionEvents, &pCP); + + if (FAILED(hr)) + { + fprintf(stderr, "IConnectionPointContainer::FindConnectionPoint(_IRDPSessionEvents) failure: 0x%08X\n", hr); + return -1; + } + + dwCookie = 0; + subsystem->pSessionEvents = &Shadow_IRDPSessionEvents; + subsystem->pSessionEvents->lpVtbl->AddRef(subsystem->pSessionEvents); + + hr = pCP->lpVtbl->Advise(pCP, (IUnknown*) subsystem->pSessionEvents, &dwCookie); + + if (FAILED(hr)) + { + fprintf(stderr, "IConnectionPoint::Advise(Shadow_IRDPSessionEvents) failure: 0x%08X\n", hr); + return -1; + } + + hr = subsystem->pSharingSession->lpVtbl->put_ColorDepth(subsystem->pSharingSession, 32); + + if (FAILED(hr)) + { + fprintf(stderr, "IRDPSRAPISharingSession::put_ColorDepth() failure: 0x%08X\n", hr); + return -1; + } + + hr = subsystem->pSharingSession->lpVtbl->GetDesktopSharedRect(subsystem->pSharingSession, + &left, &top, &right, &bottom); + + if (FAILED(hr)) + { + fprintf(stderr, "IRDPSRAPISharingSession::GetDesktopSharedRect() failure: 0x%08X\n", hr); + return -1; + } + + width = right - left; + height = bottom - top; + + printf("GetDesktopSharedRect(): left: %d top: %d right: %d bottom: %d width: %d height: %d\n", + left, top, right, bottom, width, height); + + hr = subsystem->pSharingSession->lpVtbl->get_VirtualChannelManager(subsystem->pSharingSession, + &(subsystem->pVirtualChannelMgr)); + + if (FAILED(hr)) + { + fprintf(stderr, "IRDPSRAPISharingSession::get_VirtualChannelManager() failure: 0x%08X\n", hr); + return -1; + } + + hr = subsystem->pSharingSession->lpVtbl->get_ApplicationFilter(subsystem->pSharingSession, + &(subsystem->pApplicationFilter)); + + if (FAILED(hr)) + { + fprintf(stderr, "IRDPSRAPISharingSession::get_ApplicationFilter() failure: 0x%08X\n", hr); + return -1; + } + + hr = subsystem->pSharingSession->lpVtbl->get_Attendees(subsystem->pSharingSession, + &(subsystem->pAttendeeMgr)); + + if (FAILED(hr)) + { + fprintf(stderr, "IRDPSRAPISharingSession::get_Attendees() failure: 0x%08X\n", hr); + return -1; + } + + hr = subsystem->pSharingSession->lpVtbl->get_Properties(subsystem->pSharingSession, &(subsystem->pSessionProperties)); + + if (FAILED(hr)) + { + fprintf(stderr, "IRDPSRAPISharingSession::get_Properties() failure: 0x%08X\n", hr); + return -1; + } + + bstrPropertyName = SysAllocString(L"PortId"); + varPropertyValue.vt = VT_I4; + varPropertyValue.intVal = 40000; + + hr = subsystem->pSessionProperties->lpVtbl->put_Property(subsystem->pSessionProperties, + bstrPropertyName, varPropertyValue); + + SysFreeString(bstrPropertyName); + + if (FAILED(hr)) + { + fprintf(stderr, "IRDPSRAPISessionProperties::put_Property(PortId) failure: 0x%08X\n", hr); + return -1; + } + + bstrPropertyName = SysAllocString(L"DrvConAttach"); + varPropertyValue.vt = VT_BOOL; + varPropertyValue.boolVal = VARIANT_TRUE; + + hr = subsystem->pSessionProperties->lpVtbl->put_Property(subsystem->pSessionProperties, + bstrPropertyName, varPropertyValue); + + SysFreeString(bstrPropertyName); + + if (FAILED(hr)) + { + fprintf(stderr, "IRDPSRAPISessionProperties::put_Property(DrvConAttach) failure: 0x%08X\n", hr); + return -1; + } + + bstrPropertyName = SysAllocString(L"PortProtocol"); + varPropertyValue.vt = VT_I4; + + //varPropertyValue.intVal = 0; // AF_UNSPEC + varPropertyValue.intVal = 2; // AF_INET + //varPropertyValue.intVal = 23; // AF_INET6 + + hr = subsystem->pSessionProperties->lpVtbl->put_Property(subsystem->pSessionProperties, + bstrPropertyName, varPropertyValue); + + SysFreeString(bstrPropertyName); + + if (FAILED(hr)) + { + fprintf(stderr, "IRDPSRAPISessionProperties::put_Property(PortProtocol) failure: 0x%08X\n", hr); + return -1; + } + + hr = subsystem->pSharingSession->lpVtbl->Open(subsystem->pSharingSession); + + if (FAILED(hr)) + { + fprintf(stderr, "IRDPSRAPISharingSession::Open() failure: 0x%08X\n", hr); + return -1; + } + + hr = subsystem->pSharingSession->lpVtbl->get_Invitations(subsystem->pSharingSession, + &(subsystem->pInvitationMgr)); + + if (FAILED(hr)) + { + fprintf(stderr, "IRDPSRAPISharingSession::get_Invitations() failure\n"); + return -1; + } + + bstrAuthString = SysAllocString(L"Shadow"); + bstrGroupName = SysAllocString(L"ShadowGroup"); + bstrPassword = SysAllocString(L"Shadow123!"); + + hr = subsystem->pInvitationMgr->lpVtbl->CreateInvitation(subsystem->pInvitationMgr, bstrAuthString, + bstrGroupName, bstrPassword, 5, &(subsystem->pInvitation)); + + SysFreeString(bstrAuthString); + SysFreeString(bstrGroupName); + SysFreeString(bstrPassword); + + if (FAILED(hr)) + { + fprintf(stderr, "IRDPSRAPIInvitationManager::CreateInvitation() failure: 0x%08X\n", hr); + return -1; + } + + subsystem->pInvitation->lpVtbl->get_ConnectionString(subsystem->pInvitation, &bstrConnectionString); + + if (FAILED(hr)) + { + fprintf(stderr, "IRDPSRAPIInvitation::get_ConnectionString() failure: 0x%08X\n", hr); + return -1; + } + + file = subsystem->pAssistanceFile = freerdp_assistance_file_new(); + + ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) bstrConnectionString, + ((UINT32*) bstrConnectionString)[-1], &(file->ConnectionString2), 0, NULL, NULL); + + status = freerdp_assistance_parse_connection_string2(file); + + if (status < 0) + return -1; + + printf("ConnectionString: %s\n", file->ConnectionString2); + + if (0) + { + FILE* fp; + size_t size; + + fp = fopen("inv.xml", "w+b"); + + if (fp) + { + size = strlen(file->ConnectionString2); + fwrite(file->ConnectionString2, 1, size, fp); + fwrite("\r\n", 1, 2, fp); + fclose(fp); + } + } + + status = win_shadow_rdp_init(subsystem); + + if (status < 0) + { + printf("win_shadow_rdp_init() failure: %d\n", status); + return status; + } + + settings = subsystem->shw->settings; + + freerdp_set_param_bool(settings, FreeRDP_RemoteAssistanceMode, TRUE); + + freerdp_set_param_string(settings, FreeRDP_RemoteAssistanceSessionId, file->RASessionId); + + freerdp_set_param_string(settings, FreeRDP_RemoteAssistanceRCTicket, file->ConnectionString2); + + freerdp_set_param_string(settings, FreeRDP_Domain, "RDP"); + freerdp_set_param_string(settings, FreeRDP_Username, "Shadow"); + freerdp_set_param_string(settings, FreeRDP_RemoteAssistancePassword, "Shadow123!"); + freerdp_set_param_bool(settings, FreeRDP_AutoLogonEnabled, TRUE); + + freerdp_set_param_string(settings, FreeRDP_ServerHostname, file->MachineAddress); + freerdp_set_param_uint32(settings, FreeRDP_ServerPort, file->MachinePort); + + freerdp_set_param_uint32(settings, FreeRDP_DesktopWidth, width); + freerdp_set_param_uint32(settings, FreeRDP_DesktopHeight, height); + + status = win_shadow_rdp_start(subsystem); + + if (status < 0) + { + printf("win_shadow_rdp_start() failure: %d\n", status); + return status; + } + + return 1; +} + +int win_shadow_wds_uninit(winShadowSubsystem* subsystem) +{ + if (subsystem->pSharingSession) + { + subsystem->pSharingSession->lpVtbl->Close(subsystem->pSharingSession); + subsystem->pSharingSession->lpVtbl->Release(subsystem->pSharingSession); + subsystem->pSharingSession = NULL; + } + + if (subsystem->pVirtualChannelMgr) + { + subsystem->pVirtualChannelMgr->lpVtbl->Release(subsystem->pVirtualChannelMgr); + subsystem->pVirtualChannelMgr = NULL; + } + + if (subsystem->pApplicationFilter) + { + subsystem->pApplicationFilter->lpVtbl->Release(subsystem->pApplicationFilter); + subsystem->pApplicationFilter = NULL; + } + + if (subsystem->pAttendeeMgr) + { + subsystem->pAttendeeMgr->lpVtbl->Release(subsystem->pAttendeeMgr); + subsystem->pAttendeeMgr = NULL; + } + + if (subsystem->pSessionProperties) + { + subsystem->pSessionProperties->lpVtbl->Release(subsystem->pSessionProperties); + subsystem->pSessionProperties = NULL; + } + + if (subsystem->pInvitationMgr) + { + subsystem->pInvitationMgr->lpVtbl->Release(subsystem->pInvitationMgr); + subsystem->pInvitationMgr = NULL; + } + + if (subsystem->pInvitation) + { + subsystem->pInvitation->lpVtbl->Release(subsystem->pInvitation); + subsystem->pInvitation = NULL; + } + + if (subsystem->pAssistanceFile) + { + freerdp_assistance_file_free(subsystem->pAssistanceFile); + subsystem->pAssistanceFile = NULL; + } + + if (subsystem->hWnd) + { + DestroyWindow(subsystem->hWnd); + subsystem->hWnd = NULL; + } + + if (subsystem->shw) + { + win_shadow_rdp_uninit(subsystem); + subsystem->shw = NULL; + } + + return 1; +} diff --git a/server/shadow/Win/win_wds.h b/server/shadow/Win/win_wds.h new file mode 100644 index 000000000..d8859d706 --- /dev/null +++ b/server/shadow/Win/win_wds.h @@ -0,0 +1,47 @@ +/** + * FreeRDP: A Remote Desktop Protocol Implementation + * + * Copyright 2014 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef FREERDP_SHADOW_SERVER_WIN_WDS_H +#define FREERDP_SHADOW_SERVER_WIN_WDS_H + +#define WITH_WDS_API 1 + +#ifndef CINTERFACE +#define CINTERFACE +#endif + +#include + +#ifndef DISPID_RDPAPI_EVENT_ON_BOUNDING_RECT_CHANGED +#define DISPID_RDPAPI_EVENT_ON_BOUNDING_RECT_CHANGED 340 +#endif + +#include "win_shadow.h" + +#ifdef __cplusplus +extern "C" { +#endif + +int win_shadow_wds_init(winShadowSubsystem* subsystem); +int win_shadow_wds_uninit(winShadowSubsystem* subsystem); + +#ifdef __cplusplus +} +#endif + +#endif /* FREERDP_SHADOW_SERVER_WIN_WDS_H */ diff --git a/server/shadow/X11/x11_shadow.c b/server/shadow/X11/x11_shadow.c new file mode 100644 index 000000000..ffd068e60 --- /dev/null +++ b/server/shadow/X11/x11_shadow.c @@ -0,0 +1,782 @@ +/** + * FreeRDP: A Remote Desktop Protocol Implementation + * + * Copyright 2011-2014 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include + +#include +#include +#include + +#include +#include + +#include "../shadow_screen.h" +#include "../shadow_capture.h" +#include "../shadow_surface.h" + +#include "x11_shadow.h" + +void x11_shadow_input_synchronize_event(x11ShadowSubsystem* subsystem, UINT32 flags) +{ + +} + +void x11_shadow_input_keyboard_event(x11ShadowSubsystem* subsystem, UINT16 flags, UINT16 code) +{ +#ifdef WITH_XTEST + DWORD vkcode; + DWORD keycode; + BOOL extended = FALSE; + + if (flags & KBD_FLAGS_EXTENDED) + extended = TRUE; + + if (extended) + code |= KBDEXT; + + vkcode = GetVirtualKeyCodeFromVirtualScanCode(code, 4); + keycode = GetKeycodeFromVirtualKeyCode(vkcode, KEYCODE_TYPE_EVDEV); + + if (keycode != 0) + { + XTestGrabControl(subsystem->display, True); + + if (flags & KBD_FLAGS_DOWN) + XTestFakeKeyEvent(subsystem->display, keycode, True, 0); + else if (flags & KBD_FLAGS_RELEASE) + XTestFakeKeyEvent(subsystem->display, keycode, False, 0); + + XTestGrabControl(subsystem->display, False); + } +#endif +} + +void x11_shadow_input_unicode_keyboard_event(x11ShadowSubsystem* subsystem, UINT16 flags, UINT16 code) +{ + +} + +void x11_shadow_input_mouse_event(x11ShadowSubsystem* subsystem, UINT16 flags, UINT16 x, UINT16 y) +{ +#ifdef WITH_XTEST + int button = 0; + BOOL down = FALSE; + + XTestGrabControl(subsystem->display, True); + + if (flags & PTR_FLAGS_WHEEL) + { + BOOL negative = FALSE; + + if (flags & PTR_FLAGS_WHEEL_NEGATIVE) + negative = TRUE; + + button = (negative) ? 5 : 4; + + XTestFakeButtonEvent(subsystem->display, button, True, 0); + XTestFakeButtonEvent(subsystem->display, button, False, 0); + } + else + { + if (flags & PTR_FLAGS_MOVE) + XTestFakeMotionEvent(subsystem->display, 0, x, y, 0); + + if (flags & PTR_FLAGS_BUTTON1) + button = 1; + else if (flags & PTR_FLAGS_BUTTON2) + button = 3; + else if (flags & PTR_FLAGS_BUTTON3) + button = 2; + + if (flags & PTR_FLAGS_DOWN) + down = TRUE; + + if (button != 0) + XTestFakeButtonEvent(subsystem->display, button, down, 0); + } + + XTestGrabControl(subsystem->display, False); +#endif +} + +void x11_shadow_input_extended_mouse_event(x11ShadowSubsystem* subsystem, UINT16 flags, UINT16 x, UINT16 y) +{ +#ifdef WITH_XTEST + int button = 0; + BOOL down = FALSE; + + XTestGrabControl(subsystem->display, True); + XTestFakeMotionEvent(subsystem->display, 0, x, y, CurrentTime); + + if (flags & PTR_XFLAGS_BUTTON1) + button = 8; + else if (flags & PTR_XFLAGS_BUTTON2) + button = 9; + + if (flags & PTR_XFLAGS_DOWN) + down = TRUE; + + if (button != 0) + XTestFakeButtonEvent(subsystem->display, button, down, 0); + + XTestGrabControl(subsystem->display, False); +#endif +} + +void x11_shadow_validate_region(x11ShadowSubsystem* subsystem, int x, int y, int width, int height) +{ + XRectangle region; + + if (!subsystem->use_xfixes || !subsystem->use_xdamage) + return; + + region.x = x; + region.y = y; + region.width = width; + region.height = height; + +#ifdef WITH_XFIXES + XFixesSetRegion(subsystem->display, subsystem->xdamage_region, ®ion, 1); + XDamageSubtract(subsystem->display, subsystem->xdamage, subsystem->xdamage_region, None); +#endif +} + +int x11_shadow_invalidate_region(x11ShadowSubsystem* subsystem, int x, int y, int width, int height) +{ + rdpShadowServer* server; + RECTANGLE_16 invalidRect; + + server = subsystem->server; + + invalidRect.left = x; + invalidRect.top = y; + invalidRect.right = x + width; + invalidRect.bottom = y + height; + + region16_union_rect(&(subsystem->invalidRegion), &(subsystem->invalidRegion), &invalidRect); + + return 1; +} + +int x11_shadow_screen_grab(x11ShadowSubsystem* subsystem) +{ + int count; + int status; + int x, y; + int width, height; + XImage* image; + rdpShadowScreen* screen; + rdpShadowServer* server; + rdpShadowSurface* surface; + RECTANGLE_16 invalidRect; + + server = subsystem->server; + surface = server->surface; + screen = server->screen; + + if (subsystem->use_xshm) + { + XLockDisplay(subsystem->display); + + XCopyArea(subsystem->display, subsystem->root_window, subsystem->fb_pixmap, + subsystem->xshm_gc, 0, 0, subsystem->width, subsystem->height, 0, 0); + + XSync(subsystem->display, False); + + XUnlockDisplay(subsystem->display); + + image = subsystem->fb_image; + + status = shadow_capture_compare(surface->data, surface->scanline, surface->width, surface->height, + (BYTE*) image->data, image->bytes_per_line, &invalidRect); + + if (status > 0) + { + x = invalidRect.left; + y = invalidRect.top; + width = invalidRect.right - invalidRect.left; + height = invalidRect.bottom - invalidRect.top; + + freerdp_image_copy(surface->data, PIXEL_FORMAT_XRGB32, + surface->scanline, x - surface->x, y - surface->y, width, height, + (BYTE*) image->data, PIXEL_FORMAT_XRGB32, + image->bytes_per_line, x, y); + + region16_union_rect(&(subsystem->invalidRegion), &(subsystem->invalidRegion), &invalidRect); + + count = ArrayList_Count(server->clients); + + InitializeSynchronizationBarrier(&(subsystem->barrier), count + 1, -1); + + SetEvent(subsystem->updateEvent); + + EnterSynchronizationBarrier(&(subsystem->barrier), 0); + + DeleteSynchronizationBarrier(&(subsystem->barrier)); + + ResetEvent(subsystem->updateEvent); + + region16_clear(&(subsystem->invalidRegion)); + } + } + else + { + XLockDisplay(subsystem->display); + + image = XGetImage(subsystem->display, subsystem->root_window, + 0, 0, subsystem->width, subsystem->height, AllPlanes, ZPixmap); + + XUnlockDisplay(subsystem->display); + + status = shadow_capture_compare(surface->data, surface->scanline, surface->width, surface->height, + (BYTE*) image->data, image->bytes_per_line, &invalidRect); + + if (status > 0) + { + x = invalidRect.left; + y = invalidRect.top; + width = invalidRect.right - invalidRect.left; + height = invalidRect.bottom - invalidRect.top; + + freerdp_image_copy(surface->data, PIXEL_FORMAT_XRGB32, + surface->scanline, x - surface->x, y - surface->y, width, height, + (BYTE*) image->data, PIXEL_FORMAT_XRGB32, + image->bytes_per_line, x, y); + + region16_union_rect(&(subsystem->invalidRegion), &(subsystem->invalidRegion), &invalidRect); + + count = ArrayList_Count(server->clients); + + InitializeSynchronizationBarrier(&(subsystem->barrier), count + 1, -1); + + SetEvent(subsystem->updateEvent); + + EnterSynchronizationBarrier(&(subsystem->barrier), 0); + + DeleteSynchronizationBarrier(&(subsystem->barrier)); + + ResetEvent(subsystem->updateEvent); + + region16_clear(&(subsystem->invalidRegion)); + } + + XDestroyImage(image); + } + + return 1; +} + +void* x11_shadow_subsystem_thread(x11ShadowSubsystem* subsystem) +{ + int fps; + DWORD status; + DWORD nCount; + UINT64 cTime; + DWORD dwTimeout; + DWORD dwInterval; + UINT64 frameTime; + HANDLE events[32]; + HANDLE StopEvent; + + StopEvent = subsystem->server->StopEvent; + + nCount = 0; + events[nCount++] = StopEvent; + events[nCount++] = subsystem->event; + + fps = 16; + dwInterval = 1000 / fps; + frameTime = GetTickCount64() + dwInterval; + + while (1) + { + cTime = GetTickCount64(); + dwTimeout = (cTime > frameTime) ? 0 : frameTime - cTime; + + status = WaitForMultipleObjects(nCount, events, FALSE, dwTimeout); + + if (WaitForSingleObject(StopEvent, 0) == WAIT_OBJECT_0) + { + break; + } + + if ((status == WAIT_TIMEOUT) || (GetTickCount64() > frameTime)) + { + x11_shadow_screen_grab(subsystem); + + dwInterval = 1000 / fps; + frameTime += dwInterval; + } + } + + ExitThread(0); + return NULL; +} + +int x11_shadow_xfixes_init(x11ShadowSubsystem* subsystem) +{ +#ifdef WITH_XFIXES + int xfixes_event; + int xfixes_error; + int major, minor; + + if (!XFixesQueryExtension(subsystem->display, &xfixes_event, &xfixes_error)) + return -1; + + if (!XFixesQueryVersion(subsystem->display, &major, &minor)) + return -1; + + subsystem->xfixes_notify_event = xfixes_event + XFixesCursorNotify; + + XFixesSelectCursorInput(subsystem->display, DefaultRootWindow(subsystem->display), XFixesDisplayCursorNotifyMask); + + return 1; +#else + return -1; +#endif +} + +int x11_shadow_xinerama_init(x11ShadowSubsystem* subsystem) +{ +#ifdef WITH_XINERAMA + int index; + int numMonitors; + int major, minor; + int xinerama_event; + int xinerama_error; + MONITOR_DEF* monitor; + XineramaScreenInfo* screen; + XineramaScreenInfo* screens; + + if (!XineramaQueryExtension(subsystem->display, &xinerama_event, &xinerama_error)) + return -1; + + if (!XDamageQueryVersion(subsystem->display, &major, &minor)) + return -1; + + if (!XineramaIsActive(subsystem->display)) + return -1; + + screens = XineramaQueryScreens(subsystem->display, &numMonitors); + + if (numMonitors > 16) + numMonitors = 16; + + if (!screens || (numMonitors < 1)) + return -1; + + subsystem->monitorCount = numMonitors; + + for (index = 0; index < numMonitors; index++) + { + screen = &screens[index]; + monitor = &(subsystem->monitors[index]); + + monitor->left = screen->x_org; + monitor->top = screen->y_org; + monitor->right = monitor->left + screen->width; + monitor->bottom = monitor->top + screen->height; + monitor->flags = (index == 0) ? 1 : 0; + } + + XFree(screens); +#endif + + return 1; +} + +int x11_shadow_xdamage_init(x11ShadowSubsystem* subsystem) +{ +#ifdef WITH_XDAMAGE + int major, minor; + int damage_event; + int damage_error; + + if (!subsystem->use_xfixes) + return -1; + + if (!XDamageQueryExtension(subsystem->display, &damage_event, &damage_error)) + return -1; + + if (!XDamageQueryVersion(subsystem->display, &major, &minor)) + return -1; + + if (major < 1) + return -1; + + subsystem->xdamage_notify_event = damage_event + XDamageNotify; + subsystem->xdamage = XDamageCreate(subsystem->display, subsystem->root_window, XDamageReportDeltaRectangles); + + if (!subsystem->xdamage) + return -1; + +#ifdef WITH_XFIXES + subsystem->xdamage_region = XFixesCreateRegion(subsystem->display, NULL, 0); + + if (!subsystem->xdamage_region) + return -1; +#endif + + return 1; +#else + return -1; +#endif +} + +int x11_shadow_xshm_init(x11ShadowSubsystem* subsystem) +{ + Bool pixmaps; + int major, minor; + XGCValues values; + + if (!XShmQueryExtension(subsystem->display)) + return -1; + + if (!XShmQueryVersion(subsystem->display, &major, &minor, &pixmaps)) + return -1; + + if (!pixmaps) + return -1; + + subsystem->fb_shm_info.shmid = -1; + subsystem->fb_shm_info.shmaddr = (char*) -1; + subsystem->fb_shm_info.readOnly = False; + + subsystem->fb_image = XShmCreateImage(subsystem->display, subsystem->visual, subsystem->depth, + ZPixmap, NULL, &(subsystem->fb_shm_info), subsystem->width, subsystem->height); + + if (!subsystem->fb_image) + { + fprintf(stderr, "XShmCreateImage failed\n"); + return -1; + } + + subsystem->fb_shm_info.shmid = shmget(IPC_PRIVATE, + subsystem->fb_image->bytes_per_line * subsystem->fb_image->height, IPC_CREAT | 0600); + + if (subsystem->fb_shm_info.shmid == -1) + { + fprintf(stderr, "shmget failed\n"); + return -1; + } + + subsystem->fb_shm_info.shmaddr = shmat(subsystem->fb_shm_info.shmid, 0, 0); + subsystem->fb_image->data = subsystem->fb_shm_info.shmaddr; + + if (subsystem->fb_shm_info.shmaddr == ((char*) -1)) + { + fprintf(stderr, "shmat failed\n"); + return -1; + } + + if (!XShmAttach(subsystem->display, &(subsystem->fb_shm_info))) + return -1; + + XSync(subsystem->display, False); + + shmctl(subsystem->fb_shm_info.shmid, IPC_RMID, 0); + + subsystem->fb_pixmap = XShmCreatePixmap(subsystem->display, + subsystem->root_window, subsystem->fb_image->data, &(subsystem->fb_shm_info), + subsystem->fb_image->width, subsystem->fb_image->height, subsystem->fb_image->depth); + + XSync(subsystem->display, False); + + if (!subsystem->fb_pixmap) + return -1; + + values.subwindow_mode = IncludeInferiors; + values.graphics_exposures = False; + + subsystem->xshm_gc = XCreateGC(subsystem->display, subsystem->root_window, + GCSubwindowMode | GCGraphicsExposures, &values); + + XSetFunction(subsystem->display, subsystem->xshm_gc, GXcopy); + XSync(subsystem->display, False); + + return 1; +} + +int x11_shadow_subsystem_init(x11ShadowSubsystem* subsystem) +{ + int i; + int pf_count; + int vi_count; + int nextensions; + char** extensions; + XVisualInfo* vi; + XVisualInfo* vis; + XVisualInfo template; + XPixmapFormatValues* pf; + XPixmapFormatValues* pfs; + MONITOR_DEF* virtualScreen; + + /** + * To see if your X11 server supports shared pixmaps, use: + * xdpyinfo -ext MIT-SHM | grep "shared pixmaps" + */ + + if (!getenv("DISPLAY")) + { + /* Set DISPLAY variable if not already set */ + setenv("DISPLAY", ":0", 1); + } + + if (!XInitThreads()) + return -1; + + subsystem->display = XOpenDisplay(NULL); + + if (!subsystem->display) + { + fprintf(stderr, "failed to open display: %s\n", XDisplayName(NULL)); + return -1; + } + + extensions = XListExtensions(subsystem->display, &nextensions); + + if (!extensions || (nextensions < 0)) + return -1; + + for (i = 0; i < nextensions; i++) + { + if (strcmp(extensions[i], "Composite") == 0) + subsystem->composite = TRUE; + } + + XFreeExtensionList(extensions); + + if (subsystem->composite) + subsystem->use_xdamage = FALSE; + + if (!subsystem->use_xdamage) + subsystem->use_xfixes = FALSE; + + subsystem->xfds = ConnectionNumber(subsystem->display); + subsystem->number = DefaultScreen(subsystem->display); + subsystem->screen = ScreenOfDisplay(subsystem->display, subsystem->number); + subsystem->depth = DefaultDepthOfScreen(subsystem->screen); + subsystem->width = WidthOfScreen(subsystem->screen); + subsystem->height = HeightOfScreen(subsystem->screen); + subsystem->root_window = DefaultRootWindow(subsystem->display); + + pfs = XListPixmapFormats(subsystem->display, &pf_count); + + if (!pfs) + { + fprintf(stderr, "XListPixmapFormats failed\n"); + return -1; + } + + for (i = 0; i < pf_count; i++) + { + pf = pfs + i; + + if (pf->depth == subsystem->depth) + { + subsystem->bpp = pf->bits_per_pixel; + subsystem->scanline_pad = pf->scanline_pad; + break; + } + } + XFree(pfs); + + ZeroMemory(&template, sizeof(template)); + template.class = TrueColor; + template.screen = subsystem->number; + + vis = XGetVisualInfo(subsystem->display, VisualClassMask | VisualScreenMask, &template, &vi_count); + + if (!vis) + { + fprintf(stderr, "XGetVisualInfo failed\n"); + return -1; + } + + for (i = 0; i < vi_count; i++) + { + vi = vis + i; + + if (vi->depth == subsystem->depth) + { + subsystem->visual = vi->visual; + break; + } + } + XFree(vis); + + XSelectInput(subsystem->display, subsystem->root_window, SubstructureNotifyMask); + + if (subsystem->use_xfixes) + { + if (x11_shadow_xfixes_init(subsystem) < 0) + subsystem->use_xfixes = FALSE; + } + + if (subsystem->use_xinerama) + { + if (x11_shadow_xinerama_init(subsystem) < 0) + subsystem->use_xinerama = FALSE; + } + + if (subsystem->use_xshm) + { + if (x11_shadow_xshm_init(subsystem) < 0) + subsystem->use_xshm = FALSE; + } + + if (subsystem->use_xdamage) + { + if (x11_shadow_xdamage_init(subsystem) < 0) + subsystem->use_xdamage = FALSE; + } + + subsystem->event = CreateFileDescriptorEvent(NULL, FALSE, FALSE, subsystem->xfds); + + virtualScreen = &(subsystem->virtualScreen); + + virtualScreen->left = 0; + virtualScreen->top = 0; + virtualScreen->right = subsystem->width; + virtualScreen->bottom = subsystem->height; + virtualScreen->flags = 1; + + if (subsystem->monitorCount < 1) + { + subsystem->monitorCount = 1; + subsystem->monitors[0].left = virtualScreen->left; + subsystem->monitors[0].top = virtualScreen->top; + subsystem->monitors[0].right = virtualScreen->right; + subsystem->monitors[0].bottom = virtualScreen->bottom; + subsystem->monitors[0].flags = 1; + } + + printf("X11 Extensions: XFixes: %d Xinerama: %d XDamage: %d XShm: %d\n", + subsystem->use_xfixes, subsystem->use_xinerama, subsystem->use_xdamage, subsystem->use_xshm); + + return 1; +} + +int x11_shadow_subsystem_uninit(x11ShadowSubsystem* subsystem) +{ + if (!subsystem) + return -1; + + if (subsystem->display) + { + XCloseDisplay(subsystem->display); + subsystem->display = NULL; + } + + if (subsystem->event) + { + CloseHandle(subsystem->event); + subsystem->event = NULL; + } + + return 1; +} + +int x11_shadow_subsystem_start(x11ShadowSubsystem* subsystem) +{ + HANDLE thread; + + if (!subsystem) + return -1; + + thread = CreateThread(NULL, 0, + (LPTHREAD_START_ROUTINE) x11_shadow_subsystem_thread, + (void*) subsystem, 0, NULL); + + return 1; +} + +int x11_shadow_subsystem_stop(x11ShadowSubsystem* subsystem) +{ + if (!subsystem) + return -1; + + return 1; +} + +void x11_shadow_subsystem_free(x11ShadowSubsystem* subsystem) +{ + if (!subsystem) + return; + + x11_shadow_subsystem_uninit(subsystem); + + region16_uninit(&(subsystem->invalidRegion)); + + CloseHandle(subsystem->updateEvent); + + free(subsystem); +} + +x11ShadowSubsystem* x11_shadow_subsystem_new(rdpShadowServer* server) +{ + x11ShadowSubsystem* subsystem; + + subsystem = (x11ShadowSubsystem*) calloc(1, sizeof(x11ShadowSubsystem)); + + if (!subsystem) + return NULL; + + subsystem->server = server; + + subsystem->updateEvent = CreateEvent(NULL, TRUE, FALSE, NULL); + + region16_init(&(subsystem->invalidRegion)); + + subsystem->Init = (pfnShadowSubsystemInit) x11_shadow_subsystem_init; + subsystem->Uninit = (pfnShadowSubsystemInit) x11_shadow_subsystem_uninit; + subsystem->Start = (pfnShadowSubsystemStart) x11_shadow_subsystem_start; + subsystem->Stop = (pfnShadowSubsystemStop) x11_shadow_subsystem_stop; + subsystem->Free = (pfnShadowSubsystemFree) x11_shadow_subsystem_free; + + subsystem->SynchronizeEvent = (pfnShadowSynchronizeEvent) x11_shadow_input_synchronize_event; + subsystem->KeyboardEvent = (pfnShadowKeyboardEvent) x11_shadow_input_keyboard_event; + subsystem->UnicodeKeyboardEvent = (pfnShadowUnicodeKeyboardEvent) x11_shadow_input_unicode_keyboard_event; + subsystem->MouseEvent = (pfnShadowMouseEvent) x11_shadow_input_mouse_event; + subsystem->ExtendedMouseEvent = (pfnShadowExtendedMouseEvent) x11_shadow_input_extended_mouse_event; + + subsystem->composite = FALSE; + subsystem->use_xshm = TRUE; + subsystem->use_xfixes = TRUE; + subsystem->use_xdamage = FALSE; + subsystem->use_xinerama = TRUE; + + return subsystem; +} + +rdpShadowSubsystem* X11_ShadowCreateSubsystem(rdpShadowServer* server) +{ + return (rdpShadowSubsystem*) x11_shadow_subsystem_new(server); +} diff --git a/server/X11/xfreerdp.h b/server/shadow/X11/x11_shadow.h similarity index 65% rename from server/X11/xfreerdp.h rename to server/shadow/X11/x11_shadow.h index db6231893..1a6f6fa4d 100644 --- a/server/X11/xfreerdp.h +++ b/server/shadow/X11/x11_shadow.h @@ -1,8 +1,7 @@ /** * FreeRDP: A Remote Desktop Protocol Implementation - * FreeRDP X11 Server * - * Copyright 2011 Marc-Andre Moreau + * Copyright 2011-2014 Marc-Andre Moreau * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,15 +16,18 @@ * limitations under the License. */ -#ifndef __XFREERDP_H -#define __XFREERDP_H +#ifndef FREERDP_SHADOW_SERVER_X11_H +#define FREERDP_SHADOW_SERVER_X11_H -#include "xf_interface.h" +#include -#include -#include -#include -#include +typedef struct x11_shadow_subsystem x11ShadowSubsystem; + +#include +#include +#include +#include +#include #include @@ -45,8 +47,16 @@ #include #endif -struct xf_info +#ifdef WITH_XINERAMA +#include +#endif + +struct x11_shadow_subsystem { + RDP_SHADOW_SUBSYSTEM_COMMON(); + + HANDLE thread; + int bpp; int xfds; int depth; @@ -58,10 +68,12 @@ struct xf_info Visual* visual; Display* display; int scanline_pad; - int bytesPerPixel; - HCLRCONV clrconv; + BOOL composite; + BOOL use_xshm; - int activePeerCount; + BOOL use_xfixes; + BOOL use_xdamage; + BOOL use_xinerama; XImage* fb_image; Pixmap fb_pixmap; @@ -69,7 +81,7 @@ struct xf_info XShmSegmentInfo fb_shm_info; #ifdef WITH_XDAMAGE - GC xdamage_gc; + GC xshm_gc; Damage xdamage; int xdamage_notify_event; XserverRegion xdamage_region; @@ -80,13 +92,14 @@ struct xf_info #endif }; -struct xf_server -{ - DWORD port; - HANDLE thread; - freerdp_listener* listener; -}; +#ifdef __cplusplus +extern "C" { +#endif -void* xf_server_thread(void* param); -#endif /* __XFREERDP_H */ + +#ifdef __cplusplus +} +#endif + +#endif /* FREERDP_SHADOW_SERVER_X11_H */ diff --git a/server/X11/xf_encode.h b/server/shadow/shadow.h similarity index 57% rename from server/X11/xf_encode.h rename to server/shadow/shadow.h index fb7d98562..c6f3109bc 100644 --- a/server/X11/xf_encode.h +++ b/server/shadow/shadow.h @@ -1,8 +1,7 @@ /** * FreeRDP: A Remote Desktop Protocol Implementation - * X11 RemoteFX Encoder * - * Copyright 2011 Marc-Andre Moreau + * Copyright 2014 Marc-Andre Moreau * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,15 +16,28 @@ * limitations under the License. */ -#ifndef __XF_ENCODE_H -#define __XF_ENCODE_H +#ifndef FREERDP_SHADOW_SERVER_H +#define FREERDP_SHADOW_SERVER_H -#include "xfreerdp.h" +#include -#include "xf_peer.h" +#include "shadow_client.h" +#include "shadow_input.h" +#include "shadow_screen.h" +#include "shadow_surface.h" +#include "shadow_encoder.h" +#include "shadow_capture.h" +#include "shadow_channels.h" -XImage* xf_snapshot(xfPeerContext* xfp, int x, int y, int width, int height); -void xf_xdamage_subtract_region(xfPeerContext* xfp, int x, int y, int width, int height); -int xf_update_encode(freerdp_peer* client, int x, int y, int width, int height); +#ifdef __cplusplus +extern "C" { +#endif + + + +#ifdef __cplusplus +} +#endif + +#endif /* FREERDP_SHADOW_SERVER_H */ -#endif /* __XF_ENCODE_H */ diff --git a/server/shadow/shadow_capture.c b/server/shadow/shadow_capture.c new file mode 100644 index 000000000..9f07ac964 --- /dev/null +++ b/server/shadow/shadow_capture.c @@ -0,0 +1,237 @@ +/** + * FreeRDP: A Remote Desktop Protocol Implementation + * + * Copyright 2014 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include + +#include "shadow_surface.h" + +#include "shadow_capture.h" + +int shadow_capture_align_clip_rect(RECTANGLE_16* rect, RECTANGLE_16* clip) +{ + int dx, dy; + + dx = (rect->left % 16); + + if (dx != 0) + { + rect->left -= dx; + rect->right += dx; + } + + dx = (rect->right % 16); + + if (dx != 0) + { + rect->right += (16 - dx); + } + + dy = (rect->top % 16); + + if (dy != 0) + { + rect->top -= dy; + rect->bottom += dy; + } + + dy = (rect->bottom % 16); + + if (dy != 0) + { + rect->bottom += (16 - dy); + } + + if (rect->left < clip->left) + rect->left = clip->left; + + if (rect->top < clip->top) + rect->top = clip->top; + + if (rect->right > clip->right) + rect->right = clip->right; + + if (rect->bottom > clip->bottom) + rect->bottom = clip->bottom; + + return 1; +} + +int shadow_capture_compare(BYTE* pData1, int nStep1, int nWidth, int nHeight, BYTE* pData2, int nStep2, RECTANGLE_16* rect) +{ + BOOL equal; + BOOL allEqual; + int tw, th; + int tx, ty, k; + int nrow, ncol; + int l, t, r, b; + BYTE *p1, *p2; + BOOL rows[1024]; + BOOL cols[1024]; + BOOL grid[1024][1024]; + + allEqual = TRUE; + FillMemory(rows, sizeof(rows), 0xFF); + FillMemory(cols, sizeof(cols), 0xFF); + FillMemory(grid, sizeof(grid), 0xFF); + ZeroMemory(rect, sizeof(RECTANGLE_16)); + + nrow = (nHeight + 15) / 16; + ncol = (nWidth + 15) / 16; + + l = ncol + 1; + r = -1; + + t = nrow + 1; + b = -1; + + for (ty = 0; ty < nrow; ty++) + { + th = ((ty + 1) == nrow) ? (nHeight % 16) : 16; + + if (!th) + th = 16; + + for (tx = 0; tx < ncol; tx++) + { + equal = TRUE; + + tw = ((tx + 1) == ncol) ? (nWidth % 16) : 16; + + if (!tw) + tw = 16; + + p1 = &pData1[(ty * 16 * nStep1) + (tx * 16 * 4)]; + p2 = &pData2[(ty * 16 * nStep2) + (tx * 16 * 4)]; + + for (k = 0; k < th; k++) + { + if (memcmp(p1, p2, tw * 4) != 0) + { + equal = FALSE; + break; + } + + p1 += nStep1; + p2 += nStep2; + } + + if (!equal) + { + grid[ty][tx] = FALSE; + rows[ty] = FALSE; + cols[tx] = FALSE; + + if (l > tx) + l = tx; + + if (r < tx) + r = tx; + } + } + + if (!rows[ty]) + { + allEqual = FALSE; + + if (t > ty) + t = ty; + + if (b < ty) + b = ty; + } + } + + if (allEqual) + return 0; + + rect->left = l * 16; + rect->top = t * 16; + rect->right = (r + 1) * 16; + rect->bottom = (b + 1) * 16; + + if (rect->right > nWidth) + rect->right = nWidth; + + if (rect->bottom > nHeight) + rect->bottom = nHeight; + + if (0) + { + printf("\n"); + + for (tx = 0; tx < ncol; tx++) + printf("-"); + printf("\n"); + + for (tx = 0; tx < ncol; tx++) + printf("%s", cols[tx] ? "O" : "X"); + printf("\n"); + + for (tx = 0; tx < ncol; tx++) + printf("-"); + printf("\n"); + + for (ty = 0; ty < nrow; ty++) + { + for (tx = 0; tx < ncol; tx++) + { + printf("%s", grid[ty][tx] ? "O" : "X"); + } + + printf("|%s|\n", rows[ty] ? "O" : "X"); + } + + printf("left: %d top: %d right: %d bottom: %d ncol: %d nrow: %d\n", + l, t, r, b, ncol, nrow); + } + + return 1; +} + +rdpShadowCapture* shadow_capture_new(rdpShadowServer* server) +{ + rdpShadowCapture* capture; + + capture = (rdpShadowCapture*) calloc(1, sizeof(rdpShadowCapture)); + + if (!capture) + return NULL; + + capture->server = server; + + if (!InitializeCriticalSectionAndSpinCount(&(capture->lock), 4000)) + return NULL; + + return capture; +} + +void shadow_capture_free(rdpShadowCapture* capture) +{ + if (!capture) + return; + + DeleteCriticalSection(&(capture->lock)); + + free(capture); +} + diff --git a/server/shadow/shadow_capture.h b/server/shadow/shadow_capture.h new file mode 100644 index 000000000..3ce3cddb0 --- /dev/null +++ b/server/shadow/shadow_capture.h @@ -0,0 +1,51 @@ +/** + * FreeRDP: A Remote Desktop Protocol Implementation + * + * Copyright 2014 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef FREERDP_SHADOW_SERVER_CAPTURE_H +#define FREERDP_SHADOW_SERVER_CAPTURE_H + +#include + +#include +#include + +struct rdp_shadow_capture +{ + rdpShadowServer* server; + + int width; + int height; + + CRITICAL_SECTION lock; +}; + +#ifdef __cplusplus +extern "C" { +#endif + +int shadow_capture_align_clip_rect(RECTANGLE_16* rect, RECTANGLE_16* clip); +int shadow_capture_compare(BYTE* pData1, int nStep1, int nWidth, int nHeight, BYTE* pData2, int nStep2, RECTANGLE_16* rect); + +rdpShadowCapture* shadow_capture_new(rdpShadowServer* server); +void shadow_capture_free(rdpShadowCapture* capture); + +#ifdef __cplusplus +} +#endif + +#endif /* FREERDP_SHADOW_SERVER_CAPTURE_H */ diff --git a/server/X11/cli/xfreerdp.c b/server/shadow/shadow_channels.c similarity index 56% rename from server/X11/cli/xfreerdp.c rename to server/shadow/shadow_channels.c index bd3b27729..5a2e4bb03 100644 --- a/server/X11/cli/xfreerdp.c +++ b/server/shadow/shadow_channels.c @@ -1,8 +1,7 @@ /** * FreeRDP: A Remote Desktop Protocol Implementation - * FreeRDP X11 Server * - * Copyright 2011 Marc-Andre Moreau + * Copyright 2014 Marc-Andre Moreau * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,32 +20,21 @@ #include "config.h" #endif -#include "xf_interface.h" +#include "shadow.h" -int main(int argc, char* argv[]) +#include "shadow_channels.h" + +int shadow_client_channels_post_connect(rdpShadowClient* client) { - HANDLE thread; - xfServer* server; - DWORD dwExitCode; + if (WTSVirtualChannelManagerIsChannelJoined(client->vcm, ENCOMSP_SVC_CHANNEL_NAME)) + { + shadow_client_encomsp_init(client); + } - freerdp_server_global_init(); + if (WTSVirtualChannelManagerIsChannelJoined(client->vcm, REMDESK_SVC_CHANNEL_NAME)) + { + shadow_client_remdesk_init(client); + } - server = freerdp_server_new(argc, argv); - - if (!server) - return 0; - - freerdp_server_start(server); - - thread = freerdp_server_get_thread(server); - - WaitForSingleObject(thread, INFINITE); - - GetExitCodeThread(thread, &dwExitCode); - - freerdp_server_free(server); - - freerdp_server_global_uninit(); - - return 0; + return 1; } diff --git a/server/shadow/shadow_channels.h b/server/shadow/shadow_channels.h new file mode 100644 index 000000000..7c11eb84e --- /dev/null +++ b/server/shadow/shadow_channels.h @@ -0,0 +1,40 @@ +/** + * FreeRDP: A Remote Desktop Protocol Implementation + * + * Copyright 2014 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef FREERDP_SHADOW_SERVER_CHANNELS_H +#define FREERDP_SHADOW_SERVER_CHANNELS_H + +#include + +#include +#include + +#include "shadow_encomsp.h" +#include "shadow_remdesk.h" + +#ifdef __cplusplus +extern "C" { +#endif + +int shadow_client_channels_post_connect(rdpShadowClient* client); + +#ifdef __cplusplus +} +#endif + +#endif /* FREERDP_SHADOW_SERVER_CHANNELS_H */ diff --git a/server/shadow/shadow_client.c b/server/shadow/shadow_client.c new file mode 100644 index 000000000..5098a35ea --- /dev/null +++ b/server/shadow/shadow_client.c @@ -0,0 +1,747 @@ +/** + * FreeRDP: A Remote Desktop Protocol Implementation + * + * Copyright 2014 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#include +#include +#include + +#include "shadow.h" + +void shadow_client_context_new(freerdp_peer* peer, rdpShadowClient* client) +{ + rdpSettings* settings; + rdpShadowServer* server; + + server = (rdpShadowServer*) peer->ContextExtra; + client->server = server; + + settings = peer->settings; + + settings->ColorDepth = 32; + settings->NSCodec = TRUE; + settings->RemoteFxCodec = TRUE; + settings->BitmapCacheV3Enabled = TRUE; + settings->FrameMarkerCommandEnabled = TRUE; + settings->SurfaceFrameMarkerEnabled = TRUE; + + settings->RdpSecurity = TRUE; + settings->TlsSecurity = TRUE; + settings->NlaSecurity = FALSE; + + settings->CertificateFile = _strdup(server->CertificateFile); + settings->PrivateKeyFile = _strdup(server->PrivateKeyFile); + + settings->RdpKeyFile = _strdup(settings->PrivateKeyFile); + + client->inLobby = TRUE; + client->mayView = server->mayView; + client->mayInteract = server->mayInteract; + + InitializeCriticalSectionAndSpinCount(&(client->lock), 4000); + + region16_init(&(client->invalidRegion)); + + client->vcm = WTSOpenServerA((LPSTR) peer->context); + + client->StopEvent = CreateEvent(NULL, TRUE, FALSE, NULL); + + client->encoder = shadow_encoder_new(server); + + ArrayList_Add(server->clients, (void*) client); +} + +void shadow_client_context_free(freerdp_peer* peer, rdpShadowClient* client) +{ + rdpShadowServer* server = client->server; + + ArrayList_Remove(server->clients, (void*) client); + + DeleteCriticalSection(&(client->lock)); + + region16_uninit(&(client->invalidRegion)); + + WTSCloseServer((HANDLE) client->vcm); + + CloseHandle(client->StopEvent); + + if (client->lobby) + { + shadow_surface_free(client->lobby); + client->lobby = NULL; + } + + if (client->encoder) + { + shadow_encoder_free(client->encoder); + client->encoder = NULL; + } +} + +BOOL shadow_client_capabilities(freerdp_peer* peer) +{ + return TRUE; +} + +BOOL shadow_client_post_connect(freerdp_peer* peer) +{ + int width, height; + rdpSettings* settings; + rdpShadowClient* client; + rdpShadowSurface* lobby; + RECTANGLE_16 invalidRect; + + client = (rdpShadowClient*) peer->context; + settings = peer->settings; + + settings->DesktopWidth = client->server->screen->width; + settings->DesktopHeight = client->server->screen->height; + + if (settings->ColorDepth == 24) + settings->ColorDepth = 16; /* disable 24bpp */ + + fprintf(stderr, "Client from %s is activated (%dx%d@%d)\n", + peer->hostname, settings->DesktopWidth, settings->DesktopHeight, settings->ColorDepth); + + peer->update->DesktopResize(peer->update->context); + + shadow_client_channels_post_connect(client); + + width = settings->DesktopWidth; + height = settings->DesktopHeight; + + invalidRect.left = 0; + invalidRect.top = 0; + invalidRect.right = width; + invalidRect.bottom = height; + + region16_union_rect(&(client->invalidRegion), &(client->invalidRegion), &invalidRect); + + lobby = client->lobby = shadow_surface_new(client->server, 0, 0, width, height); + + if (!client->lobby) + return FALSE; + + freerdp_image_fill(lobby->data, PIXEL_FORMAT_XRGB32, lobby->scanline, + 0, 0, lobby->width, lobby->height, 0x3BB9FF); + + region16_union_rect(&(lobby->invalidRegion), &(lobby->invalidRegion), &invalidRect); + + return TRUE; +} + +BOOL shadow_client_activate(freerdp_peer* peer) +{ + rdpShadowClient* client; + + client = (rdpShadowClient*) peer->context; + + client->activated = TRUE; + client->inLobby = client->mayView ? FALSE : TRUE; + + shadow_encoder_reset(client->encoder); + + return TRUE; +} + +void shadow_client_surface_frame_acknowledge(rdpShadowClient* client, UINT32 frameId) +{ + SURFACE_FRAME* frame; + wListDictionary* frameList; + + frameList = client->encoder->frameList; + frame = (SURFACE_FRAME*) ListDictionary_GetItemValue(frameList, (void*) (size_t) frameId); + + if (frame) + { + ListDictionary_Remove(frameList, (void*) (size_t) frameId); + free(frame); + } +} + +void shadow_client_suppress_output(rdpShadowClient* client, BYTE allow, RECTANGLE_16* area) +{ + +} + +int shadow_client_send_surface_frame_marker(rdpShadowClient* client, UINT32 action, UINT32 id) +{ + SURFACE_FRAME_MARKER surfaceFrameMarker; + rdpContext* context = (rdpContext*) client; + rdpUpdate* update = context->update; + + surfaceFrameMarker.frameAction = action; + surfaceFrameMarker.frameId = id; + + IFCALL(update->SurfaceFrameMarker, context, &surfaceFrameMarker); + + return 1; +} + +int shadow_client_send_surface_bits(rdpShadowClient* client, rdpShadowSurface* surface, int nXSrc, int nYSrc, int nWidth, int nHeight) +{ + int i; + wStream* s; + int nSrcStep; + BYTE* pSrcData; + int numMessages; + UINT32 frameId = 0; + rdpUpdate* update; + rdpContext* context; + rdpSettings* settings; + rdpShadowServer* server; + rdpShadowEncoder* encoder; + SURFACE_BITS_COMMAND cmd; + + context = (rdpContext*) client; + update = context->update; + settings = context->settings; + + server = client->server; + encoder = client->encoder; + + pSrcData = surface->data; + nSrcStep = surface->scanline; + + if (encoder->frameAck) + { + frameId = (UINT32) shadow_encoder_create_frame_id(encoder); + shadow_client_send_surface_frame_marker(client, SURFACECMD_FRAMEACTION_BEGIN, frameId); + } + + if (settings->RemoteFxCodec) + { + RFX_RECT rect; + RFX_MESSAGE* messages; + + s = encoder->bs; + + rect.x = nXSrc; + rect.y = nYSrc; + rect.width = nWidth; + rect.height = nHeight; + + messages = rfx_encode_messages(encoder->rfx, &rect, 1, pSrcData, + surface->width, surface->height, nSrcStep, &numMessages, + settings->MultifragMaxRequestSize); + + cmd.codecID = settings->RemoteFxCodecId; + + cmd.destLeft = 0; + cmd.destTop = 0; + cmd.destRight = surface->width; + cmd.destBottom = surface->height; + + cmd.bpp = 32; + cmd.width = surface->width; + cmd.height = surface->height; + + for (i = 0; i < numMessages; i++) + { + Stream_SetPosition(s, 0); + rfx_write_message(encoder->rfx, s, &messages[i]); + rfx_message_free(encoder->rfx, &messages[i]); + + cmd.bitmapDataLength = Stream_GetPosition(s); + cmd.bitmapData = Stream_Buffer(s); + + IFCALL(update->SurfaceBits, update->context, &cmd); + } + + free(messages); + } + else if (settings->NSCodec) + { + NSC_MESSAGE* messages; + + s = encoder->bs; + + messages = nsc_encode_messages(encoder->nsc, pSrcData, + nXSrc, nYSrc, nWidth, nHeight, nSrcStep, + &numMessages, settings->MultifragMaxRequestSize); + + cmd.bpp = 32; + cmd.codecID = settings->NSCodecId; + + for (i = 0; i < numMessages; i++) + { + Stream_SetPosition(s, 0); + + nsc_write_message(encoder->nsc, s, &messages[i]); + nsc_message_free(encoder->nsc, &messages[i]); + + cmd.destLeft = messages[i].x; + cmd.destTop = messages[i].y; + cmd.destRight = messages[i].x + messages[i].width; + cmd.destBottom = messages[i].y + messages[i].height; + cmd.width = messages[i].width; + cmd.height = messages[i].height; + + cmd.bitmapDataLength = Stream_GetPosition(s); + cmd.bitmapData = Stream_Buffer(s); + + IFCALL(update->SurfaceBits, update->context, &cmd); + } + + free(messages); + } + + if (encoder->frameAck) + { + shadow_client_send_surface_frame_marker(client, SURFACECMD_FRAMEACTION_END, frameId); + } + + return 1; +} + +int shadow_client_send_bitmap_update(rdpShadowClient* client, rdpShadowSurface* surface, int nXSrc, int nYSrc, int nWidth, int nHeight) +{ + BYTE* data; + BYTE* buffer; + int i, j, k; + wStream* s; + wStream* ts; + int e, lines; + int rows, cols; + int nSrcStep; + BYTE* pSrcData; + rdpUpdate* update; + rdpContext* context; + rdpSettings* settings; + int MaxRegionWidth; + int MaxRegionHeight; + BITMAP_DATA* bitmapData; + BITMAP_UPDATE bitmapUpdate; + rdpShadowServer* server; + rdpShadowEncoder* encoder; + + context = (rdpContext*) client; + update = context->update; + settings = context->settings; + + server = client->server; + encoder = client->encoder; + + pSrcData = surface->data; + nSrcStep = surface->scanline; + + MaxRegionWidth = 64 * 4; + MaxRegionHeight = 64 * 1; + + if ((nXSrc % 4) != 0) + { + nWidth += (nXSrc % 4); + nXSrc -= (nXSrc % 4); + } + + if ((nYSrc % 4) != 0) + { + nHeight += (nYSrc % 4); + nYSrc -= (nYSrc % 4); + } + + if ((nWidth * nHeight) > (MaxRegionWidth * MaxRegionHeight)) + { + int nXSrcSub; + int nYSrcSub; + int nWidthSub; + int nHeightSub; + rows = (nWidth + (MaxRegionWidth - (nWidth % MaxRegionWidth))) / MaxRegionWidth; + cols = (nHeight + (MaxRegionHeight - (nHeight % MaxRegionHeight))) / MaxRegionHeight; + + for (i = 0; i < rows; i++) + { + for (j = 0; j < cols; j++) + { + nXSrcSub = nXSrc + (i * MaxRegionWidth); + nYSrcSub = nYSrc + (j * MaxRegionHeight); + + nWidthSub = (i < (rows - 1)) ? MaxRegionWidth : nWidth - (i * MaxRegionWidth); + nHeightSub = (j < (cols - 1)) ? MaxRegionHeight : nHeight - (j * MaxRegionHeight); + + if ((nWidthSub * nHeightSub) > 0) + { + shadow_client_send_bitmap_update(client, surface, nXSrcSub, nYSrcSub, nWidthSub, nHeightSub); + } + } + } + + return 1; + } + + rows = (nWidth + (64 - (nWidth % 64))) / 64; + cols = (nHeight + (64 - (nHeight % 64))) / 64; + + k = 0; + bitmapUpdate.count = bitmapUpdate.number = rows * cols; + bitmapData = (BITMAP_DATA*) malloc(sizeof(BITMAP_DATA) * bitmapUpdate.number); + bitmapUpdate.rectangles = bitmapData; + + if (!bitmapData) + return -1; + + if ((nWidth % 4) != 0) + { + nXSrc -= (nWidth % 4); + nWidth += (nWidth % 4); + } + + if ((nHeight % 4) != 0) + { + nYSrc -= (nHeight % 4); + nHeight += (nHeight % 4); + } + + for (i = 0; i < rows; i++) + { + for (j = 0; j < cols; j++) + { + nWidth = (i < (rows - 1)) ? 64 : nWidth - (i * 64); + nHeight = (j < (cols - 1)) ? 64 : nHeight - (j * 64); + + bitmapData[k].bitsPerPixel = 16; + bitmapData[k].width = nWidth; + bitmapData[k].height = nHeight; + bitmapData[k].destLeft = nXSrc + (i * 64); + bitmapData[k].destTop = nYSrc + (j * 64); + bitmapData[k].destRight = bitmapData[k].destLeft + nWidth - 1; + bitmapData[k].destBottom = bitmapData[k].destTop + nHeight - 1; + bitmapData[k].compressed = TRUE; + + if (((nWidth * nHeight) > 0) && (nWidth >= 4) && (nHeight >= 4)) + { + UINT32 srcFormat = PIXEL_FORMAT_RGB32; + + e = nWidth % 4; + + if (e != 0) + e = 4 - e; + + s = encoder->bs; + ts = encoder->bts; + + Stream_SetPosition(s, 0); + Stream_SetPosition(ts, 0); + + data = surface->data; + data = &data[(bitmapData[k].destTop * nSrcStep) + + (bitmapData[k].destLeft * 4)]; + + srcFormat = PIXEL_FORMAT_RGB32; + + if (settings->ColorDepth > 24) + { + int dstSize; + + buffer = encoder->grid[k]; + + buffer = freerdp_bitmap_compress_planar(encoder->planar, + data, srcFormat, nWidth, nHeight, nSrcStep, buffer, &dstSize); + + bitmapData[k].bitmapDataStream = buffer; + bitmapData[k].bitmapLength = dstSize; + + bitmapData[k].bitsPerPixel = 32; + bitmapData[k].cbScanWidth = nWidth * 4; + bitmapData[k].cbUncompressedSize = nWidth * nHeight * 4; + } + else + { + int bytesPerPixel = 2; + UINT32 dstFormat = PIXEL_FORMAT_RGB16; + + if (settings->ColorDepth == 15) + { + bytesPerPixel = 2; + dstFormat = PIXEL_FORMAT_RGB15; + } + else if (settings->ColorDepth == 24) + { + bytesPerPixel = 3; + dstFormat = PIXEL_FORMAT_XRGB32; + } + + buffer = encoder->grid[k]; + + freerdp_image_copy(buffer, dstFormat, -1, 0, 0, nWidth, nHeight, + data, srcFormat, nSrcStep, 0, 0); + + lines = freerdp_bitmap_compress((char*) buffer, nWidth, nHeight, s, + settings->ColorDepth, 64 * 64 * 4, nHeight - 1, ts, e); + + Stream_SealLength(s); + + bitmapData[k].bitmapDataStream = Stream_Buffer(s); + bitmapData[k].bitmapLength = Stream_Length(s); + + buffer = encoder->grid[k]; + CopyMemory(buffer, bitmapData[k].bitmapDataStream, bitmapData[k].bitmapLength); + bitmapData[k].bitmapDataStream = buffer; + + bitmapData[k].bitsPerPixel = settings->ColorDepth; + bitmapData[k].cbScanWidth = nWidth * bytesPerPixel; + bitmapData[k].cbUncompressedSize = nWidth * nHeight * bytesPerPixel; + } + + bitmapData[k].cbCompFirstRowSize = 0; + bitmapData[k].cbCompMainBodySize = bitmapData[k].bitmapLength; + + k++; + } + } + } + + bitmapUpdate.count = bitmapUpdate.number = k; + + IFCALL(update->BitmapUpdate, context, &bitmapUpdate); + + free(bitmapData); + + return 1; +} + +int shadow_client_send_surface_update(rdpShadowClient* client) +{ + int status = -1; + int nXSrc, nYSrc; + int nWidth, nHeight; + rdpContext* context; + rdpSettings* settings; + rdpShadowServer* server; + rdpShadowSurface* surface; + rdpShadowEncoder* encoder; + REGION16 invalidRegion; + RECTANGLE_16 surfaceRect; + const RECTANGLE_16* extents; + + context = (rdpContext*) client; + settings = context->settings; + server = client->server; + encoder = client->encoder; + + surface = client->inLobby ? client->lobby : server->surface; + + EnterCriticalSection(&(client->lock)); + + region16_init(&invalidRegion); + region16_copy(&invalidRegion, &(client->invalidRegion)); + region16_clear(&(client->invalidRegion)); + + LeaveCriticalSection(&(client->lock)); + + surfaceRect.left = surface->x; + surfaceRect.top = surface->y; + surfaceRect.right = surface->x + surface->width; + surfaceRect.bottom = surface->y + surface->height; + + region16_intersect_rect(&invalidRegion, &invalidRegion, &surfaceRect); + + if (region16_is_empty(&invalidRegion)) + { + region16_uninit(&invalidRegion); + return 1; + } + + extents = region16_extents(&invalidRegion); + + nXSrc = extents->left - surface->x; + nYSrc = extents->top - surface->y; + nWidth = extents->right - extents->left; + nHeight = extents->bottom - extents->top; + + //printf("shadow_client_send_surface_update: x: %d y: %d width: %d height: %d right: %d bottom: %d\n", + // nXSrc, nYSrc, nWidth, nHeight, nXSrc + nWidth, nYSrc + nHeight); + + if (settings->RemoteFxCodec || settings->NSCodec) + { + if (settings->RemoteFxCodec) + shadow_encoder_prepare(encoder, SHADOW_CODEC_REMOTEFX); + else if (settings->NSCodec) + shadow_encoder_prepare(encoder, SHADOW_CODEC_NSCODEC); + + status = shadow_client_send_surface_bits(client, surface, nXSrc, nYSrc, nWidth, nHeight); + } + else + { + shadow_encoder_prepare(encoder, SHADOW_CODEC_BITMAP); + + status = shadow_client_send_bitmap_update(client, surface, nXSrc, nYSrc, nWidth, nHeight); + } + + region16_uninit(&invalidRegion); + + return status; +} + +int shadow_client_surface_update(rdpShadowClient* client, REGION16* region) +{ + int index; + int numRects = 0; + const RECTANGLE_16* rects; + + EnterCriticalSection(&(client->lock)); + + rects = region16_rects(region, &numRects); + + for (index = 0; index < numRects; index++) + { + region16_union_rect(&(client->invalidRegion), &(client->invalidRegion), &rects[index]); + } + + LeaveCriticalSection(&(client->lock)); + + return 1; +} + +void* shadow_client_thread(rdpShadowClient* client) +{ + DWORD status; + DWORD nCount; + HANDLE events[32]; + HANDLE StopEvent; + HANDLE ClientEvent; + HANDLE ChannelEvent; + HANDLE UpdateEvent; + freerdp_peer* peer; + rdpSettings* settings; + rdpShadowServer* server; + rdpShadowScreen* screen; + rdpShadowEncoder* encoder; + rdpShadowSubsystem* subsystem; + + server = client->server; + screen = server->screen; + encoder = client->encoder; + subsystem = server->subsystem; + + peer = ((rdpContext*) client)->peer; + settings = peer->settings; + + peer->Capabilities = shadow_client_capabilities; + peer->PostConnect = shadow_client_post_connect; + peer->Activate = shadow_client_activate; + + shadow_input_register_callbacks(peer->input); + + peer->Initialize(peer); + + peer->update->SurfaceFrameAcknowledge = (pSurfaceFrameAcknowledge) + shadow_client_surface_frame_acknowledge; + peer->update->SuppressOutput = (pSuppressOutput) shadow_client_suppress_output; + + StopEvent = client->StopEvent; + UpdateEvent = subsystem->updateEvent; + ClientEvent = peer->GetEventHandle(peer); + ChannelEvent = WTSVirtualChannelManagerGetEventHandle(client->vcm); + + while (1) + { + nCount = 0; + events[nCount++] = StopEvent; + events[nCount++] = UpdateEvent; + events[nCount++] = ClientEvent; + events[nCount++] = ChannelEvent; + + status = WaitForMultipleObjects(nCount, events, FALSE, INFINITE); + + if (WaitForSingleObject(StopEvent, 0) == WAIT_OBJECT_0) + { + if (WaitForSingleObject(UpdateEvent, 0) == WAIT_OBJECT_0) + { + EnterSynchronizationBarrier(&(subsystem->barrier), 0); + } + + break; + } + + if (WaitForSingleObject(UpdateEvent, 0) == WAIT_OBJECT_0) + { + if (client->activated) + { + int index; + int numRects = 0; + const RECTANGLE_16* rects; + + rects = region16_rects(&(subsystem->invalidRegion), &numRects); + + for (index = 0; index < numRects; index++) + { + region16_union_rect(&(client->invalidRegion), &(client->invalidRegion), &rects[index]); + } + + shadow_client_send_surface_update(client); + } + + EnterSynchronizationBarrier(&(subsystem->barrier), 0); + + while (WaitForSingleObject(UpdateEvent, 0) == WAIT_OBJECT_0); + } + + if (WaitForSingleObject(ClientEvent, 0) == WAIT_OBJECT_0) + { + if (!peer->CheckFileDescriptor(peer)) + { + fprintf(stderr, "Failed to check FreeRDP file descriptor\n"); + break; + } + } + + if (WaitForSingleObject(ChannelEvent, 0) == WAIT_OBJECT_0) + { + if (WTSVirtualChannelManagerCheckFileDescriptor(client->vcm) != TRUE) + { + fprintf(stderr, "WTSVirtualChannelManagerCheckFileDescriptor failure\n"); + break; + } + } + } + + peer->Disconnect(peer); + + freerdp_peer_context_free(peer); + freerdp_peer_free(peer); + + ExitThread(0); + + return NULL; +} + +void shadow_client_accepted(freerdp_listener* listener, freerdp_peer* peer) +{ + rdpShadowClient* client; + rdpShadowServer* server; + + server = (rdpShadowServer*) listener->info; + + peer->ContextExtra = (void*) server; + peer->ContextSize = sizeof(rdpShadowClient); + peer->ContextNew = (psPeerContextNew) shadow_client_context_new; + peer->ContextFree = (psPeerContextFree) shadow_client_context_free; + freerdp_peer_context_new(peer); + + client = (rdpShadowClient*) peer->context; + + client->thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) + shadow_client_thread, client, 0, NULL); +} diff --git a/server/shadow/shadow_client.h b/server/shadow/shadow_client.h new file mode 100644 index 000000000..d067554f0 --- /dev/null +++ b/server/shadow/shadow_client.h @@ -0,0 +1,35 @@ +/** + * FreeRDP: A Remote Desktop Protocol Implementation + * + * Copyright 2014 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef FREERDP_SHADOW_SERVER_CLIENT_H +#define FREERDP_SHADOW_SERVER_CLIENT_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +int shadow_client_surface_update(rdpShadowClient* client, REGION16* region); +void shadow_client_accepted(freerdp_listener* instance, freerdp_peer* client); + +#ifdef __cplusplus +} +#endif + +#endif /* FREERDP_SHADOW_SERVER_CLIENT_H */ diff --git a/server/shadow/shadow_encoder.c b/server/shadow/shadow_encoder.c new file mode 100644 index 000000000..8388267a6 --- /dev/null +++ b/server/shadow/shadow_encoder.c @@ -0,0 +1,380 @@ +/** + * FreeRDP: A Remote Desktop Protocol Implementation + * + * Copyright 2014 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "shadow.h" + +#include "shadow_encoder.h" + +int shadow_encoder_create_frame_id(rdpShadowEncoder* encoder) +{ + UINT32 frameId; + int inFlightFrames; + SURFACE_FRAME* frame; + + inFlightFrames = ListDictionary_Count(encoder->frameList); + + if (inFlightFrames > encoder->frameAck) + { + encoder->fps = (100 / (inFlightFrames + 1) * encoder->maxFps) / 100; + } + else + { + encoder->fps += 2; + + if (encoder->fps > encoder->maxFps) + encoder->fps = encoder->maxFps; + } + + if (encoder->fps < 1) + encoder->fps = 1; + + frame = (SURFACE_FRAME*) malloc(sizeof(SURFACE_FRAME)); + + if (!frame) + return -1; + + frameId = frame->frameId = ++encoder->frameId; + ListDictionary_Add(encoder->frameList, (void*) (size_t) frame->frameId, frame); + + return (int) frame->frameId; +} + +int shadow_encoder_init_grid(rdpShadowEncoder* encoder) +{ + int i, j, k; + int tileSize; + int tileCount; + + encoder->gridWidth = ((encoder->width + (encoder->maxTileWidth - 1)) / encoder->maxTileWidth); + encoder->gridHeight = ((encoder->height + (encoder->maxTileHeight - 1)) / encoder->maxTileHeight); + + tileSize = encoder->maxTileWidth * encoder->maxTileHeight * 4; + tileCount = encoder->gridWidth * encoder->gridHeight; + + encoder->gridBuffer = (BYTE*) malloc(tileSize * tileCount); + + if (!encoder->gridBuffer) + return -1; + + encoder->grid = (BYTE**) malloc(tileCount * sizeof(BYTE*)); + + if (!encoder->grid) + return -1; + + for (i = 0; i < encoder->gridHeight; i++) + { + for (j = 0; j < encoder->gridWidth; j++) + { + k = (i * encoder->gridHeight) + j; + encoder->grid[k] = &(encoder->gridBuffer[k * tileSize]); + } + } + + return 0; +} + +int shadow_encoder_uninit_grid(rdpShadowEncoder* encoder) +{ + if (encoder->gridBuffer) + { + free(encoder->gridBuffer); + encoder->gridBuffer = NULL; + } + + if (encoder->grid) + { + free(encoder->grid); + encoder->grid = NULL; + } + + encoder->gridWidth = 0; + encoder->gridHeight = 0; + + return 0; +} + +int shadow_encoder_init_rfx(rdpShadowEncoder* encoder) +{ + if (!encoder->rfx) + encoder->rfx = rfx_context_new(TRUE); + + if (!encoder->rfx) + return -1; + + encoder->rfx->mode = RLGR3; + encoder->rfx->width = encoder->width; + encoder->rfx->height = encoder->height; + + rfx_context_set_pixel_format(encoder->rfx, RDP_PIXEL_FORMAT_B8G8R8A8); + + if (!encoder->frameList) + { + encoder->fps = 16; + encoder->maxFps = 32; + encoder->frameId = 0; + encoder->frameAck = TRUE; + encoder->frameList = ListDictionary_New(TRUE); + } + + encoder->codecs |= SHADOW_CODEC_REMOTEFX; + + return 1; +} + +int shadow_encoder_init_nsc(rdpShadowEncoder* encoder) +{ + if (!encoder->nsc) + encoder->nsc = nsc_context_new(); + + if (!encoder->nsc) + return -1; + + nsc_context_set_pixel_format(encoder->nsc, RDP_PIXEL_FORMAT_B8G8R8A8); + + if (!encoder->frameList) + { + encoder->fps = 16; + encoder->maxFps = 32; + encoder->frameId = 0; + encoder->frameAck = TRUE; + encoder->frameList = ListDictionary_New(TRUE); + } + + encoder->codecs |= SHADOW_CODEC_NSCODEC; + + return 1; +} + +int shadow_encoder_init_bitmap(rdpShadowEncoder* encoder) +{ + DWORD planarFlags; + + planarFlags = PLANAR_FORMAT_HEADER_NA; + planarFlags |= PLANAR_FORMAT_HEADER_RLE; + + if (!encoder->planar) + { + encoder->planar = freerdp_bitmap_planar_context_new(planarFlags, + encoder->maxTileWidth, encoder->maxTileHeight); + } + + if (!encoder->planar) + return -1; + + if (!encoder->bts) + encoder->bts = Stream_New(NULL, encoder->maxTileWidth * encoder->maxTileHeight * 4); + + if (!encoder->bts) + return -1; + + encoder->codecs |= SHADOW_CODEC_BITMAP; + + return 1; +} + +int shadow_encoder_init(rdpShadowEncoder* encoder) +{ + encoder->maxTileWidth = 64; + encoder->maxTileHeight = 64; + + shadow_encoder_init_grid(encoder); + + if (!encoder->bs) + encoder->bs = Stream_New(NULL, encoder->maxTileWidth * encoder->maxTileHeight * 4); + + if (!encoder->bs) + return -1; + + return 1; +} + +int shadow_encoder_uninit_rfx(rdpShadowEncoder* encoder) +{ + if (encoder->rfx) + { + rfx_context_free(encoder->rfx); + encoder->rfx = NULL; + } + + if (encoder->frameList) + { + ListDictionary_Free(encoder->frameList); + encoder->frameList = NULL; + } + + encoder->codecs &= ~SHADOW_CODEC_REMOTEFX; + + return 1; +} + +int shadow_encoder_uninit_nsc(rdpShadowEncoder* encoder) +{ + if (encoder->nsc) + { + nsc_context_free(encoder->nsc); + encoder->nsc = NULL; + } + + if (encoder->frameList) + { + ListDictionary_Free(encoder->frameList); + encoder->frameList = NULL; + } + + encoder->codecs &= ~SHADOW_CODEC_NSCODEC; + + return 1; +} + +int shadow_encoder_uninit_bitmap(rdpShadowEncoder* encoder) +{ + if (encoder->planar) + { + freerdp_bitmap_planar_context_free(encoder->planar); + encoder->planar = NULL; + } + + if (encoder->bts) + { + Stream_Free(encoder->bts, TRUE); + encoder->bts = NULL; + } + + encoder->codecs &= ~SHADOW_CODEC_BITMAP; + + return 1; +} + +int shadow_encoder_uninit(rdpShadowEncoder* encoder) +{ + shadow_encoder_uninit_grid(encoder); + + if (encoder->bs) + { + Stream_Free(encoder->bs, TRUE); + encoder->bs = NULL; + } + + if (encoder->codecs & SHADOW_CODEC_REMOTEFX) + { + shadow_encoder_uninit_rfx(encoder); + } + + if (encoder->codecs & SHADOW_CODEC_NSCODEC) + { + shadow_encoder_uninit_nsc(encoder); + } + + if (encoder->codecs & SHADOW_CODEC_BITMAP) + { + shadow_encoder_uninit_bitmap(encoder); + } + + return 1; +} + +int shadow_encoder_reset(rdpShadowEncoder* encoder) +{ + int status; + UINT32 codecs = encoder->codecs; + + status = shadow_encoder_uninit(encoder); + + if (status < 0) + return -1; + + status = shadow_encoder_init(encoder); + + if (status < 0) + return -1; + + status = shadow_encoder_prepare(encoder, codecs); + + if (status < 0) + return -1; + + return 1; +} + +int shadow_encoder_prepare(rdpShadowEncoder* encoder, UINT32 codecs) +{ + int status; + + if ((codecs & SHADOW_CODEC_REMOTEFX) && !(encoder->codecs & SHADOW_CODEC_REMOTEFX)) + { + status = shadow_encoder_init_rfx(encoder); + + if (status < 0) + return -1; + } + + if ((codecs & SHADOW_CODEC_NSCODEC) && !(encoder->codecs & SHADOW_CODEC_NSCODEC)) + { + status = shadow_encoder_init_nsc(encoder); + + if (status < 0) + return -1; + } + + if ((codecs & SHADOW_CODEC_BITMAP) && !(encoder->codecs & SHADOW_CODEC_BITMAP)) + { + status = shadow_encoder_init_bitmap(encoder); + + if (status < 0) + return -1; + } + + return 1; +} + +rdpShadowEncoder* shadow_encoder_new(rdpShadowServer* server) +{ + rdpShadowEncoder* encoder; + + encoder = (rdpShadowEncoder*) calloc(1, sizeof(rdpShadowEncoder)); + + if (!encoder) + return NULL; + + encoder->server = server; + + encoder->fps = 16; + encoder->maxFps = 32; + + encoder->width = server->screen->width; + encoder->height = server->screen->height; + + if (shadow_encoder_init(encoder) < 0) + return NULL; + + return encoder; +} + +void shadow_encoder_free(rdpShadowEncoder* encoder) +{ + if (!encoder) + return; + + shadow_encoder_uninit(encoder); + + free(encoder); +} diff --git a/server/shadow/shadow_encoder.h b/server/shadow/shadow_encoder.h new file mode 100644 index 000000000..d1ae552d7 --- /dev/null +++ b/server/shadow/shadow_encoder.h @@ -0,0 +1,80 @@ +/** + * FreeRDP: A Remote Desktop Protocol Implementation + * + * Copyright 2014 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef FREERDP_SHADOW_SERVER_ENCODER_H +#define FREERDP_SHADOW_SERVER_ENCODER_H + +#include +#include + +#include +#include +#include +#include + +#include + +#define SHADOW_CODEC_REMOTEFX 1 +#define SHADOW_CODEC_NSCODEC 2 +#define SHADOW_CODEC_BITMAP 4 + +struct rdp_shadow_encoder +{ + rdpShadowServer* server; + + int width; + int height; + UINT32 codecs; + + BYTE** grid; + int gridWidth; + int gridHeight; + BYTE* gridBuffer; + int maxTileWidth; + int maxTileHeight; + + wStream* bs; + wStream* bts; + + RFX_CONTEXT* rfx; + NSC_CONTEXT* nsc; + BITMAP_PLANAR_CONTEXT* planar; + + int fps; + int maxFps; + BOOL frameAck; + UINT32 frameId; + wListDictionary* frameList; +}; + +#ifdef __cplusplus +extern "C" { +#endif + +int shadow_encoder_reset(rdpShadowEncoder* encoder); +int shadow_encoder_prepare(rdpShadowEncoder* encoder, UINT32 codecs); +int shadow_encoder_create_frame_id(rdpShadowEncoder* encoder); + +rdpShadowEncoder* shadow_encoder_new(rdpShadowServer* server); +void shadow_encoder_free(rdpShadowEncoder* encoder); + +#ifdef __cplusplus +} +#endif + +#endif /* FREERDP_SHADOW_SERVER_ENCODER_H */ diff --git a/server/shadow/shadow_encomsp.c b/server/shadow/shadow_encomsp.c new file mode 100644 index 000000000..f0b1d48e3 --- /dev/null +++ b/server/shadow/shadow_encomsp.c @@ -0,0 +1,108 @@ +/** + * FreeRDP: A Remote Desktop Protocol Implementation + * + * Copyright 2014 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "shadow.h" + +#include "shadow_encomsp.h" + +static int encomsp_change_participant_control_level(EncomspServerContext* context, + ENCOMSP_CHANGE_PARTICIPANT_CONTROL_LEVEL_PDU* pdu) +{ + BOOL inLobby; + BOOL mayView; + BOOL mayInteract; + rdpShadowClient* client = (rdpShadowClient*) context->custom; + + printf("ChangeParticipantControlLevel: ParticipantId: %d Flags: 0x%04X\n", + pdu->ParticipantId, pdu->Flags); + + mayView = (pdu->Flags & ENCOMSP_MAY_VIEW) ? TRUE : FALSE; + mayInteract = (pdu->Flags & ENCOMSP_MAY_INTERACT) ? TRUE : FALSE; + + if (mayInteract && !mayView) + mayView = TRUE; /* may interact implies may view */ + + if (mayInteract) + { + if (!client->mayInteract) + { + /* request interact + view */ + client->mayInteract = TRUE; + client->mayView = TRUE; + } + } + else if (mayView) + { + if (client->mayInteract) + { + /* release interact */ + client->mayInteract = FALSE; + } + else if (!client->mayView) + { + /* request view */ + client->mayView = TRUE; + } + } + else + { + if (client->mayInteract) + { + /* release interact + view */ + client->mayView = FALSE; + client->mayInteract = FALSE; + } + else if (client->mayView) + { + /* release view */ + client->mayView = FALSE; + client->mayInteract = FALSE; + } + } + + inLobby = client->mayView ? FALSE : TRUE; + + if (inLobby != client->inLobby) + { + shadow_encoder_reset(client->encoder); + client->inLobby = inLobby; + } + + return 1; +} + +int shadow_client_encomsp_init(rdpShadowClient* client) +{ + EncomspServerContext* encomsp; + + encomsp = client->encomsp = encomsp_server_context_new(client->vcm); + + encomsp->custom = (void*) client; + + encomsp->ChangeParticipantControlLevel = encomsp_change_participant_control_level; + + if (client->encomsp) + client->encomsp->Start(client->encomsp); + + return 1; +} + diff --git a/server/X11/xf_monitors.h b/server/shadow/shadow_encomsp.h similarity index 61% rename from server/X11/xf_monitors.h rename to server/shadow/shadow_encomsp.h index 8487c3327..d7187b5cb 100644 --- a/server/X11/xf_monitors.h +++ b/server/shadow/shadow_encomsp.h @@ -1,8 +1,7 @@ /** * FreeRDP: A Remote Desktop Protocol Implementation - * X11 Server Monitors * - * Copyright 2013 Marc-Andre Moreau + * Copyright 2014 Marc-Andre Moreau * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,12 +16,22 @@ * limitations under the License. */ -#ifndef XFREERDP_SERVER_MONITORS_H -#define XFREERDP_SERVER_MONITORS_H +#ifndef FREERDP_SHADOW_SERVER_ENCOMSP_H +#define FREERDP_SHADOW_SERVER_ENCOMSP_H -#include "xfreerdp.h" +#include -int xf_list_monitors(xfInfo* xfi); +#include +#include -#endif /* XFREERDP_SERVER_MONITORS_H */ +#ifdef __cplusplus +extern "C" { +#endif +int shadow_client_encomsp_init(rdpShadowClient* client); + +#ifdef __cplusplus +} +#endif + +#endif /* FREERDP_SHADOW_SERVER_ENCOMSP_H */ diff --git a/server/shadow/shadow_input.c b/server/shadow/shadow_input.c new file mode 100644 index 000000000..4f28b0bc5 --- /dev/null +++ b/server/shadow/shadow_input.c @@ -0,0 +1,102 @@ +/** + * FreeRDP: A Remote Desktop Protocol Implementation + * + * Copyright 2014 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "shadow.h" + +void shadow_input_synchronize_event(rdpInput* input, UINT32 flags) +{ + rdpShadowClient* client = (rdpShadowClient*) input->context; + rdpShadowSubsystem* subsystem = client->server->subsystem; + + if (!client->mayInteract) + return; + + if (subsystem->SynchronizeEvent) + { + subsystem->SynchronizeEvent(subsystem, flags); + } +} + +void shadow_input_keyboard_event(rdpInput* input, UINT16 flags, UINT16 code) +{ + rdpShadowClient* client = (rdpShadowClient*) input->context; + rdpShadowSubsystem* subsystem = client->server->subsystem; + + if (!client->mayInteract) + return; + + if (subsystem->KeyboardEvent) + { + subsystem->KeyboardEvent(subsystem, flags, code); + } +} + +void shadow_input_unicode_keyboard_event(rdpInput* input, UINT16 flags, UINT16 code) +{ + rdpShadowClient* client = (rdpShadowClient*) input->context; + rdpShadowSubsystem* subsystem = client->server->subsystem; + + if (!client->mayInteract) + return; + + if (subsystem->UnicodeKeyboardEvent) + { + subsystem->UnicodeKeyboardEvent(subsystem, flags, code); + } +} + +void shadow_input_mouse_event(rdpInput* input, UINT16 flags, UINT16 x, UINT16 y) +{ + rdpShadowClient* client = (rdpShadowClient*) input->context; + rdpShadowSubsystem* subsystem = client->server->subsystem; + + if (!client->mayInteract) + return; + + if (subsystem->MouseEvent) + { + subsystem->MouseEvent(subsystem, flags, x, y); + } +} + +void shadow_input_extended_mouse_event(rdpInput* input, UINT16 flags, UINT16 x, UINT16 y) +{ + rdpShadowClient* client = (rdpShadowClient*) input->context; + rdpShadowSubsystem* subsystem = client->server->subsystem; + + if (!client->mayInteract) + return; + + if (subsystem->ExtendedMouseEvent) + { + subsystem->ExtendedMouseEvent(subsystem, flags, x, y); + } +} + +void shadow_input_register_callbacks(rdpInput* input) +{ + input->SynchronizeEvent = shadow_input_synchronize_event; + input->KeyboardEvent = shadow_input_keyboard_event; + input->UnicodeKeyboardEvent = shadow_input_unicode_keyboard_event; + input->MouseEvent = shadow_input_mouse_event; + input->ExtendedMouseEvent = shadow_input_extended_mouse_event; +} diff --git a/include/freerdp/utils/bitmap.h b/server/shadow/shadow_input.h similarity index 68% rename from include/freerdp/utils/bitmap.h rename to server/shadow/shadow_input.h index b9d4dcf94..cc87ffc6e 100644 --- a/include/freerdp/utils/bitmap.h +++ b/server/shadow/shadow_input.h @@ -1,8 +1,7 @@ /** * FreeRDP: A Remote Desktop Protocol Implementation - * Bitmap File Format Utils * - * Copyright 2011 Marc-Andre Moreau + * Copyright 2014 Marc-Andre Moreau * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,19 +16,19 @@ * limitations under the License. */ -#ifndef FREERDP_UTILS_BITMAP_H -#define FREERDP_UTILS_BITMAP_H +#ifndef FREERDP_SHADOW_SERVER_INPUT_H +#define FREERDP_SHADOW_SERVER_INPUT_H -#include +#include #ifdef __cplusplus extern "C" { #endif -FREERDP_API void freerdp_bitmap_write(char* filename, void* data, int width, int height, int bpp); +void shadow_input_register_callbacks(rdpInput* input); #ifdef __cplusplus } #endif -#endif /* FREERDP_UTILS_BITMAP_H */ +#endif /* FREERDP_SHADOW_SERVER_INPUT_H */ diff --git a/server/shadow/shadow_remdesk.c b/server/shadow/shadow_remdesk.c new file mode 100644 index 000000000..62af21729 --- /dev/null +++ b/server/shadow/shadow_remdesk.c @@ -0,0 +1,39 @@ +/** + * FreeRDP: A Remote Desktop Protocol Implementation + * + * Copyright 2014 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "shadow.h" + +#include "shadow_remdesk.h" + +int shadow_client_remdesk_init(rdpShadowClient* client) +{ + RemdeskServerContext* remdesk; + + remdesk = client->remdesk = remdesk_server_context_new(client->vcm); + + remdesk->custom = (void*) client; + + if (client->remdesk) + client->remdesk->Start(client->remdesk); + + return 1; +} diff --git a/server/X11/xf_cursor.h b/server/shadow/shadow_remdesk.h similarity index 61% rename from server/X11/xf_cursor.h rename to server/shadow/shadow_remdesk.h index 64c95c312..f99a42d24 100644 --- a/server/X11/xf_cursor.h +++ b/server/shadow/shadow_remdesk.h @@ -1,8 +1,7 @@ /** * FreeRDP: A Remote Desktop Protocol Implementation - * X11 Server Cursor * - * Copyright 2013 Marc-Andre Moreau + * Copyright 2014 Marc-Andre Moreau * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,11 +16,22 @@ * limitations under the License. */ -#ifndef XFREERDP_SERVER_CURSOR_H -#define XFREERDP_SERVER_CURSOR_H +#ifndef FREERDP_SHADOW_SERVER_REMDESK_H +#define FREERDP_SHADOW_SERVER_REMDESK_H -#include "xfreerdp.h" +#include -int xf_cursor_init(xfInfo* xfi); +#include +#include -#endif /* XFREERDP_SERVER_CURSOR_H */ +#ifdef __cplusplus +extern "C" { +#endif + +int shadow_client_remdesk_init(rdpShadowClient* client); + +#ifdef __cplusplus +} +#endif + +#endif /* FREERDP_SHADOW_SERVER_REMDESK_H */ diff --git a/server/shadow/shadow_screen.c b/server/shadow/shadow_screen.c new file mode 100644 index 000000000..0b4c87f93 --- /dev/null +++ b/server/shadow/shadow_screen.c @@ -0,0 +1,85 @@ +/** + * FreeRDP: A Remote Desktop Protocol Implementation + * + * Copyright 2014 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "shadow_surface.h" + +#include "shadow_screen.h" + +rdpShadowScreen* shadow_screen_new(rdpShadowServer* server) +{ + int x, y; + int width, height; + MONITOR_DEF* primary; + rdpShadowScreen* screen; + rdpShadowSubsystem* subsystem; + + screen = (rdpShadowScreen*) calloc(1, sizeof(rdpShadowScreen)); + + if (!screen) + return NULL; + + screen->server = server; + subsystem = server->subsystem; + + if (!InitializeCriticalSectionAndSpinCount(&(screen->lock), 4000)) + return NULL; + + region16_init(&(screen->invalidRegion)); + + primary = &(subsystem->monitors[0]); + + x = primary->left; + y = primary->top; + width = primary->right - primary->left; + height = primary->bottom - primary->top; + + screen->width = width; + screen->height = height; + + screen->primary = shadow_surface_new(server, x, y, width, height); + + if (!screen->primary) + return NULL; + + server->surface = screen->primary; + + return screen; +} + +void shadow_screen_free(rdpShadowScreen* screen) +{ + if (!screen) + return; + + DeleteCriticalSection(&(screen->lock)); + + region16_uninit(&(screen->invalidRegion)); + + if (screen->primary) + { + shadow_surface_free(screen->primary); + screen->primary = NULL; + } + + free(screen); +} + diff --git a/server/shadow/shadow_screen.h b/server/shadow/shadow_screen.h new file mode 100644 index 000000000..2b305e336 --- /dev/null +++ b/server/shadow/shadow_screen.h @@ -0,0 +1,51 @@ +/** + * FreeRDP: A Remote Desktop Protocol Implementation + * + * Copyright 2014 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef FREERDP_SHADOW_SERVER_SCREEN_H +#define FREERDP_SHADOW_SERVER_SCREEN_H + +#include + +#include +#include + +struct rdp_shadow_screen +{ + rdpShadowServer* server; + + int width; + int height; + + CRITICAL_SECTION lock; + REGION16 invalidRegion; + + rdpShadowSurface* primary; +}; + +#ifdef __cplusplus +extern "C" { +#endif + +rdpShadowScreen* shadow_screen_new(rdpShadowServer* server); +void shadow_screen_free(rdpShadowScreen* screen); + +#ifdef __cplusplus +} +#endif + +#endif /* FREERDP_SHADOW_SERVER_SCREEN_H */ diff --git a/server/shadow/shadow_server.c b/server/shadow/shadow_server.c new file mode 100644 index 000000000..c990d1fcf --- /dev/null +++ b/server/shadow/shadow_server.c @@ -0,0 +1,615 @@ +/** + * FreeRDP: A Remote Desktop Protocol Implementation + * + * Copyright 2014 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#include +#include +#include + +#include + +#include + +#ifdef _WIN32 +#include +#endif + +#ifndef _WIN32 +#include +#include +#endif + +#include "shadow.h" + +#ifdef _WIN32 +static BOOL g_MessagePump = TRUE; +#else +static BOOL g_MessagePump = FALSE; +#endif + +#ifdef WITH_SHADOW_X11 +extern rdpShadowSubsystem* X11_ShadowCreateSubsystem(rdpShadowServer* server); +#endif + +#ifdef WITH_SHADOW_MAC +extern rdpShadowSubsystem* Mac_ShadowCreateSubsystem(rdpShadowServer* server); +#endif + +#ifdef WITH_SHADOW_WIN +extern rdpShadowSubsystem* Win_ShadowCreateSubsystem(rdpShadowServer* server); +#endif + +static COMMAND_LINE_ARGUMENT_A shadow_args[] = +{ + { "port", COMMAND_LINE_VALUE_REQUIRED, "", NULL, NULL, -1, NULL, "Server port" }, + { "ipc-socket", COMMAND_LINE_VALUE_REQUIRED, "", NULL, NULL, -1, NULL, "Server IPC socket" }, + { "monitors", COMMAND_LINE_VALUE_OPTIONAL, "<0,1,2...>", NULL, NULL, -1, NULL, "Select or list monitors" }, + { "may-view", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueTrue, NULL, -1, NULL, "Clients may view without prompt" }, + { "may-interact", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueTrue, NULL, -1, NULL, "Clients may interact without prompt" }, + { "version", COMMAND_LINE_VALUE_FLAG | COMMAND_LINE_PRINT_VERSION, NULL, NULL, NULL, -1, NULL, "Print version" }, + { "help", COMMAND_LINE_VALUE_FLAG | COMMAND_LINE_PRINT_HELP, NULL, NULL, NULL, -1, "?", "Print help" }, + { NULL, 0, NULL, NULL, NULL, -1, NULL, NULL } +}; + +int shadow_server_print_command_line_help(int argc, char** argv) +{ + char* str; + int length; + COMMAND_LINE_ARGUMENT_A* arg; + + printf("Usage: %s [options]\n", argv[0]); + printf("\n"); + + printf("Syntax:\n"); + printf(" /flag (enables flag)\n"); + printf(" /option: (specifies option with value)\n"); + printf(" +toggle -toggle (enables or disables toggle, where '/' is a synonym of '+')\n"); + printf("\n"); + + arg = shadow_args; + + do + { + if (arg->Flags & COMMAND_LINE_VALUE_FLAG) + { + printf(" %s", "/"); + printf("%-20s", arg->Name); + printf("\t%s\n", arg->Text); + } + else if ((arg->Flags & COMMAND_LINE_VALUE_REQUIRED) || (arg->Flags & COMMAND_LINE_VALUE_OPTIONAL)) + { + printf(" %s", "/"); + + if (arg->Format) + { + length = (int) (strlen(arg->Name) + strlen(arg->Format) + 2); + str = (char*) malloc(length + 1); + sprintf_s(str, length + 1, "%s:%s", arg->Name, arg->Format); + printf("%-20s", str); + free(str); + } + else + { + printf("%-20s", arg->Name); + } + + printf("\t%s\n", arg->Text); + } + else if (arg->Flags & COMMAND_LINE_VALUE_BOOL) + { + length = (int) strlen(arg->Name) + 32; + str = (char*) malloc(length + 1); + sprintf_s(str, length + 1, "%s (default:%s)", arg->Name, + arg->Default ? "on" : "off"); + + printf(" %s", arg->Default ? "-" : "+"); + + printf("%-20s", str); + free(str); + + printf("\t%s\n", arg->Text); + } + } + while ((arg = CommandLineFindNextArgumentA(arg)) != NULL); + + return 1; +} + +int shadow_server_command_line_status_print(rdpShadowServer* server, int argc, char** argv, int status) +{ + if (status == COMMAND_LINE_STATUS_PRINT_VERSION) + { + printf("FreeRDP version %s (git %s)\n", FREERDP_VERSION_FULL, GIT_REVISION); + return COMMAND_LINE_STATUS_PRINT_VERSION; + } + else if (status == COMMAND_LINE_STATUS_PRINT) + { + return COMMAND_LINE_STATUS_PRINT; + } + else if (status < 0) + { + shadow_server_print_command_line_help(argc, argv); + return COMMAND_LINE_STATUS_PRINT_HELP; + } + + return 1; +} + +int shadow_server_parse_command_line(rdpShadowServer* server, int argc, char** argv) +{ + int status; + DWORD flags; + COMMAND_LINE_ARGUMENT_A* arg; + + if (argc < 2) + return 1; + + CommandLineClearArgumentsA(shadow_args); + + flags = COMMAND_LINE_SEPARATOR_COLON; + flags |= COMMAND_LINE_SIGIL_SLASH | COMMAND_LINE_SIGIL_PLUS_MINUS; + + status = CommandLineParseArgumentsA(argc, (const char**) argv, shadow_args, flags, server, NULL, NULL); + + if (status < 0) + return status; + + arg = shadow_args; + + do + { + if (!(arg->Flags & COMMAND_LINE_ARGUMENT_PRESENT)) + continue; + + CommandLineSwitchStart(arg) + + CommandLineSwitchCase(arg, "port") + { + server->port = (DWORD) atoi(arg->Value); + } + CommandLineSwitchCase(arg, "ipc-socket") + { + server->ipcSocket = _strdup(arg->Value); + } + CommandLineSwitchCase(arg, "may-view") + { + server->mayView = arg->Value ? TRUE : FALSE; + } + CommandLineSwitchCase(arg, "may-interact") + { + server->mayInteract = arg->Value ? TRUE : FALSE; + } + CommandLineSwitchDefault(arg) + { + + } + + CommandLineSwitchEnd(arg) + } + while ((arg = CommandLineFindNextArgumentA(arg)) != NULL); + + arg = CommandLineFindArgumentA(shadow_args, "monitors"); + + if (arg && (arg->Flags & COMMAND_LINE_ARGUMENT_PRESENT)) + { + if (arg->Flags & COMMAND_LINE_VALUE_PRESENT) + { + /* Select monitors */ + } + else + { + int index; + int width, height; + MONITOR_DEF* monitor; + rdpShadowSubsystem* subsystem = server->subsystem; + + /* List monitors */ + + for (index = 0; index < subsystem->monitorCount; index++) + { + monitor = &(subsystem->monitors[index]); + + width = monitor->right - monitor->left; + height = monitor->bottom - monitor->top; + + printf(" %s [%d] %dx%d\t+%d+%d\n", + (monitor->flags == 1) ? "*" : " ", index, + width, height, monitor->left, monitor->top); + } + + status = COMMAND_LINE_STATUS_PRINT; + } + } + + return status; +} + +int shadow_server_surface_update(rdpShadowSubsystem* subsystem, REGION16* region) +{ + int index; + int count; + wArrayList* clients; + rdpShadowServer* server; + rdpShadowClient* client; + + server = subsystem->server; + clients = server->clients; + + ArrayList_Lock(clients); + + count = ArrayList_Count(clients); + + for (index = 0; index < count; index++) + { + client = ArrayList_GetItem(clients, index); + shadow_client_surface_update(client, region); + } + + ArrayList_Unlock(clients); + + return 1; +} + +void* shadow_server_thread(rdpShadowServer* server) +{ + DWORD status; + DWORD nCount; + HANDLE events[32]; + HANDLE StopEvent; + freerdp_listener* listener; + rdpShadowSubsystem* subsystem; + + listener = server->listener; + StopEvent = server->StopEvent; + subsystem = server->subsystem; + + if (subsystem->Start) + { + subsystem->Start(subsystem); + } + + while (1) + { + nCount = 0; + + if (listener->GetEventHandles(listener, events, &nCount) < 0) + { + fprintf(stderr, "Failed to get FreeRDP file descriptor\n"); + break; + } + + events[nCount++] = server->StopEvent; + + status = WaitForMultipleObjects(nCount, events, FALSE, INFINITE); + + if (WaitForSingleObject(server->StopEvent, 0) == WAIT_OBJECT_0) + { + break; + } + + if (!listener->CheckFileDescriptor(listener)) + { + fprintf(stderr, "Failed to check FreeRDP file descriptor\n"); + break; + } + +#ifdef _WIN32 + Sleep(100); /* FIXME: listener event handles */ +#endif + } + + listener->Close(listener); + + if (subsystem->Stop) + { + subsystem->Stop(subsystem); + } + + ExitThread(0); + + return NULL; +} + +int shadow_server_start(rdpShadowServer* server) +{ + BOOL status; + WSADATA wsaData; + + if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) + return -1; + +#ifndef _WIN32 + signal(SIGPIPE, SIG_IGN); +#endif + + if (!server->ipcSocket) + status = server->listener->Open(server->listener, NULL, (UINT16) server->port); + else + status = server->listener->OpenLocal(server->listener, server->ipcSocket); + + if (status) + { + server->thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) + shadow_server_thread, (void*) server, 0, NULL); + } + + return 0; +} + +int shadow_server_stop(rdpShadowServer* server) +{ + if (server->thread) + { + SetEvent(server->StopEvent); + WaitForSingleObject(server->thread, INFINITE); + CloseHandle(server->thread); + server->thread = NULL; + + server->listener->Close(server->listener); + } + + return 0; +} + +int shadow_server_init_certificate(rdpShadowServer* server) +{ + char* filepath; + MAKECERT_CONTEXT* makecert; + + const char* makecert_argv[6] = + { + "makecert", + "-rdp", + "-live", + "-silent", + "-y", "5" + }; + + int makecert_argc = (sizeof(makecert_argv) / sizeof(char*)); + + if (!PathFileExistsA(server->ConfigPath)) + CreateDirectoryA(server->ConfigPath, 0); + + filepath = GetCombinedPath(server->ConfigPath, "shadow"); + + if (!filepath) + return -1; + + if (!PathFileExistsA(filepath)) + CreateDirectoryA(filepath, 0); + + server->CertificateFile = GetCombinedPath(filepath, "shadow.crt"); + server->PrivateKeyFile = GetCombinedPath(filepath, "shadow.key"); + + if ((!PathFileExistsA(server->CertificateFile)) || + (!PathFileExistsA(server->PrivateKeyFile))) + { + makecert = makecert_context_new(); + + makecert_context_process(makecert, makecert_argc, (char**) makecert_argv); + + makecert_context_set_output_file_name(makecert, "shadow"); + + if (!PathFileExistsA(server->CertificateFile)) + makecert_context_output_certificate_file(makecert, filepath); + + if (!PathFileExistsA(server->PrivateKeyFile)) + makecert_context_output_private_key_file(makecert, filepath); + + makecert_context_free(makecert); + } + + free(filepath); + + return 1; +} + +int shadow_server_init(rdpShadowServer* server) +{ + int status; + + winpr_InitializeSSL(WINPR_SSL_INIT_DEFAULT); + + WTSRegisterWtsApiFunctionTable(FreeRDP_InitWtsApi()); + + server->StopEvent = CreateEvent(NULL, TRUE, FALSE, NULL); + + status = shadow_server_init_certificate(server); + + if (status < 0) + return -1; + + server->listener = freerdp_listener_new(); + + if (!server->listener) + return -1; + + server->listener->info = (void*) server; + server->listener->PeerAccepted = shadow_client_accepted; + +#ifdef WITH_SHADOW_X11 + server->CreateSubsystem = X11_ShadowCreateSubsystem; +#endif + +#ifdef WITH_SHADOW_MAC + server->CreateSubsystem = Mac_ShadowCreateSubsystem; +#endif + +#ifdef WITH_SHADOW_WIN + server->CreateSubsystem = Win_ShadowCreateSubsystem; +#endif + + if (server->CreateSubsystem) + server->subsystem = server->CreateSubsystem(server); + + if (!server->subsystem) + return -1; + + server->subsystem->SurfaceUpdate = shadow_server_surface_update; + + if (server->subsystem->Init) + { + status = server->subsystem->Init(server->subsystem); + + if (status < 0) + fprintf(stderr, "subsystem init failure: %d\n", status); + } + + server->screen = shadow_screen_new(server); + + if (!server->screen) + return -1; + + server->capture = shadow_capture_new(server); + + if (!server->capture) + return -1; + + return 1; +} + +int shadow_server_uninit(rdpShadowServer* server) +{ + shadow_server_stop(server); + + if (server->listener) + { + freerdp_listener_free(server->listener); + server->listener = NULL; + } + + if (server->subsystem) + { + server->subsystem->Free(server->subsystem); + server->subsystem = NULL; + } + + if (server->CertificateFile) + { + free(server->CertificateFile); + server->CertificateFile = NULL; + } + + if (server->PrivateKeyFile) + { + free(server->PrivateKeyFile); + server->PrivateKeyFile = NULL; + } + + if (server->ipcSocket) + { + free(server->ipcSocket); + server->ipcSocket = NULL; + } + + return 1; +} + +rdpShadowServer* shadow_server_new() +{ + rdpShadowServer* server; + + server = (rdpShadowServer*) calloc(1, sizeof(rdpShadowServer)); + + if (!server) + return NULL; + + server->port = 3389; + server->mayView = TRUE; + server->mayInteract = TRUE; + +#ifdef _WIN32 + server->ConfigPath = GetEnvironmentSubPath("LOCALAPPDATA", "freerdp"); +#endif + + if (!server->ConfigPath) + server->ConfigPath = GetKnownSubPath(KNOWN_PATH_XDG_CONFIG_HOME, "freerdp"); + + InitializeCriticalSectionAndSpinCount(&(server->lock), 4000); + + server->clients = ArrayList_New(TRUE); + + return server; +} + +void shadow_server_free(rdpShadowServer* server) +{ + if (!server) + return; + + DeleteCriticalSection(&(server->lock)); + + if (server->clients) + { + ArrayList_Free(server->clients); + server->clients = NULL; + } + + shadow_server_uninit(server); + + free(server); +} + +int main(int argc, char** argv) +{ + MSG msg; + int status; + DWORD dwExitCode; + rdpShadowServer* server; + + server = shadow_server_new(); + + if (!server) + return 0; + + if (shadow_server_init(server) < 0) + return 0; + + status = shadow_server_parse_command_line(server, argc, argv); + + status = shadow_server_command_line_status_print(server, argc, argv, status); + + if (status < 0) + return 0; + + if (shadow_server_start(server) < 0) + return 0; + + if (g_MessagePump) + { + while (GetMessage(&msg, 0, 0, 0)) + { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + } + + WaitForSingleObject(server->thread, INFINITE); + + GetExitCodeThread(server->thread, &dwExitCode); + + shadow_server_free(server); + + return 0; +} diff --git a/server/shadow/shadow_surface.c b/server/shadow/shadow_surface.c new file mode 100644 index 000000000..9c581422b --- /dev/null +++ b/server/shadow/shadow_surface.c @@ -0,0 +1,71 @@ +/** + * FreeRDP: A Remote Desktop Protocol Implementation + * + * Copyright 2014 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "shadow.h" + +#include "shadow_surface.h" + +rdpShadowSurface* shadow_surface_new(rdpShadowServer* server, int x, int y, int width, int height) +{ + rdpShadowSurface* surface; + + surface = (rdpShadowSurface*) calloc(1, sizeof(rdpShadowSurface)); + + if (!surface) + return NULL; + + surface->server = server; + + surface->x = x; + surface->y = y; + surface->width = width; + surface->height = height; + surface->scanline = (surface->width + (surface->width % 4)) * 4; + + surface->data = (BYTE*) malloc(surface->scanline * surface->height); + + if (!surface->data) + return NULL; + + ZeroMemory(surface->data, surface->scanline * surface->height); + + if (!InitializeCriticalSectionAndSpinCount(&(surface->lock), 4000)) + return NULL; + + region16_init(&(surface->invalidRegion)); + + return surface; +} + +void shadow_surface_free(rdpShadowSurface* surface) +{ + if (!surface) + return; + + free(surface->data); + + DeleteCriticalSection(&(surface->lock)); + + region16_uninit(&(surface->invalidRegion)); + + free(surface); +} diff --git a/server/shadow/shadow_surface.h b/server/shadow/shadow_surface.h new file mode 100644 index 000000000..2f6bc8300 --- /dev/null +++ b/server/shadow/shadow_surface.h @@ -0,0 +1,53 @@ +/** + * FreeRDP: A Remote Desktop Protocol Implementation + * + * Copyright 2014 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef FREERDP_SHADOW_SERVER_SURFACE_H +#define FREERDP_SHADOW_SERVER_SURFACE_H + +#include + +#include +#include + +struct rdp_shadow_surface +{ + rdpShadowServer* server; + + int x; + int y; + int width; + int height; + int scanline; + BYTE* data; + + CRITICAL_SECTION lock; + REGION16 invalidRegion; +}; + +#ifdef __cplusplus +extern "C" { +#endif + +rdpShadowSurface* shadow_surface_new(rdpShadowServer* server, int x, int y, int width, int height); +void shadow_surface_free(rdpShadowSurface* surface); + +#ifdef __cplusplus +} +#endif + +#endif /* FREERDP_SHADOW_SERVER_SURFACE_H */ diff --git a/winpr/include/winpr/collections.h b/winpr/include/winpr/collections.h index f56a556d8..a18f1b5a4 100644 --- a/winpr/include/winpr/collections.h +++ b/winpr/include/winpr/collections.h @@ -247,10 +247,10 @@ WINPR_API void* LinkedList_Last(wLinkedList* list); WINPR_API BOOL LinkedList_Contains(wLinkedList* list, void* value); WINPR_API void LinkedList_Clear(wLinkedList* list); -WINPR_API void LinkedList_AddFirst(wLinkedList* list, void* value); -WINPR_API void LinkedList_AddLast(wLinkedList* list, void* value); +WINPR_API BOOL LinkedList_AddFirst(wLinkedList* list, void* value); +WINPR_API BOOL LinkedList_AddLast(wLinkedList* list, void* value); -WINPR_API void LinkedList_Remove(wLinkedList* list, void* value); +WINPR_API BOOL LinkedList_Remove(wLinkedList* list, void* value); WINPR_API void LinkedList_RemoveFirst(wLinkedList* list); WINPR_API void LinkedList_RemoveLast(wLinkedList* list); diff --git a/winpr/include/winpr/crt.h b/winpr/include/winpr/crt.h index ed136a2a0..4172be83f 100644 --- a/winpr/include/winpr/crt.h +++ b/winpr/include/winpr/crt.h @@ -104,10 +104,6 @@ static INLINE UINT16 __lzcnt16(UINT16 _val16) { return _val16 ? ((UINT16) (__builtin_clz((UINT32) _val16) - 16)) : 16; } -static INLINE UINT64 __lzcnt64(UINT64 _val64) { - return _val64 ? ((UINT64) __builtin_clzll(_val64)) : 64; -} - #else static INLINE UINT32 __lzcnt(UINT32 x) { @@ -125,10 +121,6 @@ static INLINE UINT16 __lzcnt16(UINT16 x) { return ((UINT16) __lzcnt((UINT32) x)); } -static INLINE UINT64 __lzcnt64(UINT64 x) { - return 0; /* TODO */ -} - #endif #endif diff --git a/winpr/include/winpr/debug.h b/winpr/include/winpr/debug.h new file mode 100644 index 000000000..1d1123a80 --- /dev/null +++ b/winpr/include/winpr/debug.h @@ -0,0 +1,40 @@ +/** + * WinPR: Windows Portable Runtime + * WinPR Debugging helpers + * + * Copyright 2014 Armin Novak + * Copyright 2014 Thincast Technologies GmbH + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef WINPR_DEBUG_H +#define WINPR_DEBUG_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +void *winpr_backtrace(DWORD size); +void winpr_backtrace_free(void *buffer); +char **winpr_backtrace_symbols(void *buffer, size_t *used); +void winpr_backtrace_symbols_fd(void *buffer, int fd); + +#ifdef __cplusplus +} +#endif + +#endif /* WINPR_WLOG_H */ + diff --git a/winpr/include/winpr/image.h b/winpr/include/winpr/image.h new file mode 100644 index 000000000..313200533 --- /dev/null +++ b/winpr/include/winpr/image.h @@ -0,0 +1,53 @@ +/** + * WinPR: Windows Portable Runtime + * Image Utils + * + * Copyright 2014 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef WINPR_IMAGE_H +#define WINPR_IMAGE_H + +#include +#include + +struct _wImage +{ + int width; + int height; + BYTE* data; + int scanline; + int bitsPerPixel; + int bytesPerPixel; +}; +typedef struct _wImage wImage; + +#ifdef __cplusplus +extern "C" { +#endif + +WINPR_API int winpr_bitmap_write(const char* filename, BYTE* data, int width, int height, int bpp); + +WINPR_API int winpr_image_write(wImage* image, const char* filename); +WINPR_API int winpr_image_read(wImage* image, const char* filename); + +WINPR_API wImage* winpr_image_new(); +WINPR_API void winpr_image_free(wImage* image, BOOL bFreeBuffer); + +#ifdef __cplusplus +} +#endif + +#endif /* WINPR_IMAGE_H */ diff --git a/winpr/include/winpr/path.h b/winpr/include/winpr/path.h index a69867d02..36333e9b6 100644 --- a/winpr/include/winpr/path.h +++ b/winpr/include/winpr/path.h @@ -281,10 +281,10 @@ extern "C" { WINPR_API char* GetKnownPath(int id); WINPR_API char* GetKnownSubPath(int id, const char* path); +WINPR_API char* GetEnvironmentPath(char* name); +WINPR_API char* GetEnvironmentSubPath(char* name, const char* path); WINPR_API char* GetCombinedPath(const char* basePath, const char* subPath); -//#ifndef _WIN32 - WINPR_API BOOL PathFileExistsA(LPCSTR pszPath); WINPR_API BOOL PathFileExistsW(LPCWSTR pszPath); @@ -298,6 +298,4 @@ WINPR_API BOOL PathFileExistsW(LPCWSTR pszPath); #define PathFileExists PathFileExistsA #endif -//#endif - #endif /* WINPR_PATH_H */ diff --git a/winpr/include/winpr/synch.h b/winpr/include/winpr/synch.h index 04f4268e4..88e37457e 100644 --- a/winpr/include/winpr/synch.h +++ b/winpr/include/winpr/synch.h @@ -162,15 +162,6 @@ WINPR_API VOID LeaveCriticalSection(LPCRITICAL_SECTION lpCriticalSection); WINPR_API VOID DeleteCriticalSection(LPCRITICAL_SECTION lpCriticalSection); -/* Synchronization Barrier */ - -typedef PVOID RTL_SYNCHRONIZATION_BARRIER; -typedef RTL_SYNCHRONIZATION_BARRIER SYNCHRONIZATION_BARRIER, *PSYNCHRONIZATION_BARRIER, *LPSYNCHRONIZATION_BARRIER; - -WINPR_API BOOL InitializeSynchronizationBarrier(LPSYNCHRONIZATION_BARRIER lpBarrier, LONG lTotalThreads, LONG lSpinCount); -WINPR_API BOOL EnterSynchronizationBarrier(LPSYNCHRONIZATION_BARRIER lpBarrier, DWORD dwFlags); -WINPR_API BOOL DeleteSynchronizationBarrier(LPSYNCHRONIZATION_BARRIER lpBarrier); - /* Sleep */ WINPR_API VOID Sleep(DWORD dwMilliseconds); @@ -313,6 +304,33 @@ WINPR_API VOID InitOnceInitialize(PINIT_ONCE InitOnce); #endif +/* Synchronization Barrier */ + +#if (!defined(_WIN32)) || (defined(_WIN32) && (_WIN32_WINNT < 0x0602)) + +typedef struct _RTL_BARRIER +{ + DWORD Reserved1; + DWORD Reserved2; + ULONG_PTR Reserved3[2]; + DWORD Reserved4; + DWORD Reserved5; +} RTL_BARRIER, *PRTL_BARRIER; + +typedef RTL_BARRIER SYNCHRONIZATION_BARRIER; +typedef PRTL_BARRIER PSYNCHRONIZATION_BARRIER; +typedef PRTL_BARRIER LPSYNCHRONIZATION_BARRIER; + +#define SYNCHRONIZATION_BARRIER_FLAGS_SPIN_ONLY 0x01 +#define SYNCHRONIZATION_BARRIER_FLAGS_BLOCK_ONLY 0x02 +#define SYNCHRONIZATION_BARRIER_FLAGS_NO_DELETE 0x04 + +WINPR_API BOOL WINAPI InitializeSynchronizationBarrier(LPSYNCHRONIZATION_BARRIER lpBarrier, LONG lTotalThreads, LONG lSpinCount); +WINPR_API BOOL WINAPI EnterSynchronizationBarrier(LPSYNCHRONIZATION_BARRIER lpBarrier, DWORD dwFlags); +WINPR_API BOOL WINAPI DeleteSynchronizationBarrier(LPSYNCHRONIZATION_BARRIER lpBarrier); + +#endif + /* Extended API */ WINPR_API VOID USleep(DWORD dwMicroseconds); diff --git a/winpr/include/winpr/sysinfo.h b/winpr/include/winpr/sysinfo.h index eca980a27..120009a08 100644 --- a/winpr/include/winpr/sysinfo.h +++ b/winpr/include/winpr/sysinfo.h @@ -298,20 +298,21 @@ WINPR_API ULONGLONG GetTickCount64(void); WINPR_API BOOL IsProcessorFeaturePresentEx(DWORD ProcessorFeature); /* extended flags */ -#define PF_EX_3DNOW_PREFETCH 1 -#define PF_EX_SSSE3 2 -#define PF_EX_SSE41 3 -#define PF_EX_SSE42 4 -#define PF_EX_AVX 5 -#define PF_EX_FMA 6 -#define PF_EX_AVX_AES 7 -#define PF_EX_AVX2 8 -#define PF_EX_ARM_VFP1 9 -#define PF_EX_ARM_VFP3D16 10 -#define PF_EX_ARM_VFP4 11 -#define PF_EX_ARM_IDIVA 12 -#define PF_EX_ARM_IDIVT 13 -#define PF_EX_AVX_PCLMULQDQ 14 +#define PF_EX_LZCNT 1 +#define PF_EX_3DNOW_PREFETCH 2 +#define PF_EX_SSSE3 3 +#define PF_EX_SSE41 4 +#define PF_EX_SSE42 5 +#define PF_EX_AVX 6 +#define PF_EX_FMA 7 +#define PF_EX_AVX_AES 8 +#define PF_EX_AVX2 9 +#define PF_EX_ARM_VFP1 10 +#define PF_EX_ARM_VFP3D16 11 +#define PF_EX_ARM_VFP4 12 +#define PF_EX_ARM_IDIVA 13 +#define PF_EX_ARM_IDIVT 14 +#define PF_EX_AVX_PCLMULQDQ 15 /* * some "aliases" for the standard defines diff --git a/winpr/libwinpr/comm/CMakeLists.txt b/winpr/libwinpr/comm/CMakeLists.txt index 58ff2fe1d..0fe9f566f 100644 --- a/winpr/libwinpr/comm/CMakeLists.txt +++ b/winpr/libwinpr/comm/CMakeLists.txt @@ -18,21 +18,23 @@ set(MODULE_NAME "winpr-comm") set(MODULE_PREFIX "WINPR_COMM") -set(${MODULE_PREFIX}_SRCS - comm.c - comm.h - comm_io.c - comm_ioctl.c - comm_ioctl.h - comm_serial_sys.c - comm_serial_sys.h - comm_sercx_sys.c - comm_sercx_sys.h - comm_sercx2_sys.c - comm_sercx2_sys.h) +if(UNIX AND NOT WIN32 AND NOT APPLE) + set(${MODULE_PREFIX}_SRCS + comm.c + comm.h + comm_io.c + comm_ioctl.c + comm_ioctl.h + comm_serial_sys.c + comm_serial_sys.h + comm_sercx_sys.c + comm_sercx_sys.h + comm_sercx2_sys.c + comm_sercx2_sys.h) -winpr_module_add(${${MODULE_PREFIX}_SRCS}) + winpr_module_add(${${MODULE_PREFIX}_SRCS}) -if(BUILD_TESTING AND UNIX AND NOT WIN32) - add_subdirectory(test) + if(BUILD_TESTING) + add_subdirectory(test) + endif() endif() diff --git a/winpr/libwinpr/comm/comm.c b/winpr/libwinpr/comm/comm.c index 93ea80ea4..5aa213894 100644 --- a/winpr/libwinpr/comm/comm.c +++ b/winpr/libwinpr/comm/comm.c @@ -1495,5 +1495,16 @@ BOOL CommCloseHandle(HANDLE handle) return TRUE; } +#ifdef __UCLIBC__ +int eventfd_read(int fd, eventfd_t* value) +{ + return (read(fd, value, sizeof(*value)) == sizeof(*value)) ? 0 : -1; +} + +int eventfd_write(int fd, eventfd_t value) +{ + return (write(fd, &value, sizeof(value)) == sizeof(value)) ? 0 : -1; +} +#endif #endif /* __linux__ */ diff --git a/winpr/libwinpr/comm/comm.h b/winpr/libwinpr/comm/comm.h index 5531f2d7c..7714f3b55 100644 --- a/winpr/libwinpr/comm/comm.h +++ b/winpr/libwinpr/comm/comm.h @@ -92,6 +92,11 @@ void CommLog_Print(int wlog_level, char *fmt, ...); BOOL CommIsHandled(HANDLE handle); BOOL CommCloseHandle(HANDLE handle); +#ifdef __UCLIBC__ +int eventfd_read(int fd, eventfd_t* value); +int eventfd_write(int fd, eventfd_t value); +#endif + #endif /* __linux__ */ #endif /* WINPR_COMM_PRIVATE_H */ diff --git a/winpr/libwinpr/comm/comm_serial_sys.c b/winpr/libwinpr/comm/comm_serial_sys.c index 5ed2b89a5..d32a22a73 100644 --- a/winpr/libwinpr/comm/comm_serial_sys.c +++ b/winpr/libwinpr/comm/comm_serial_sys.c @@ -30,6 +30,9 @@ #include #include "comm_serial_sys.h" +#ifdef __UCLIBC__ +#include "comm.h" +#endif #include #include diff --git a/winpr/libwinpr/comm/test/TestCommConfig.c b/winpr/libwinpr/comm/test/TestCommConfig.c index 093c44e24..4d667ee7e 100644 --- a/winpr/libwinpr/comm/test/TestCommConfig.c +++ b/winpr/libwinpr/comm/test/TestCommConfig.c @@ -78,7 +78,7 @@ int TestCommConfig(int argc, char* argv[]) if (!hComm || (hComm == INVALID_HANDLE_VALUE)) { - fprintf(stderr, "CreateFileA failure: %s GetLastError() = 0x%0.8x\n", lpFileName, GetLastError()); + fprintf(stderr, "CreateFileA failure: %s GetLastError() = 0x%08x\n", lpFileName, GetLastError()); return EXIT_FAILURE; } @@ -100,7 +100,7 @@ int TestCommConfig(int argc, char* argv[]) ZeroMemory(&commProp, sizeof(COMMPROP)); if (!GetCommProperties(hComm, &commProp)) { - fprintf(stderr, "GetCommProperties failure: GetLastError(): 0x0.8x\n", GetLastError()); + fprintf(stderr, "GetCommProperties failure: GetLastError(): 0x%08x\n", GetLastError()); return EXIT_FAILURE; } diff --git a/winpr/libwinpr/comm/test/TestControlSettings.c b/winpr/libwinpr/comm/test/TestControlSettings.c index becdae2d0..07b70117f 100644 --- a/winpr/libwinpr/comm/test/TestControlSettings.c +++ b/winpr/libwinpr/comm/test/TestControlSettings.c @@ -61,7 +61,7 @@ int TestControlSettings(int argc, char* argv[]) dcb.DCBlength = sizeof(DCB); if (!GetCommState(hComm, &dcb)) { - fprintf(stderr, "GetCommState failure; GetLastError(): %0.8x\n", GetLastError()); + fprintf(stderr, "GetCommState failure; GetLastError(): %08x\n", GetLastError()); return FALSE; } @@ -73,7 +73,7 @@ int TestControlSettings(int argc, char* argv[]) if (!SetCommState(hComm, &dcb)) { - fprintf(stderr, "SetCommState failure; GetLastError(): %0.8x\n", GetLastError()); + fprintf(stderr, "SetCommState failure; GetLastError(): %08x\n", GetLastError()); return FALSE; } @@ -81,7 +81,7 @@ int TestControlSettings(int argc, char* argv[]) dcb.DCBlength = sizeof(DCB); if (!GetCommState(hComm, &dcb)) { - fprintf(stderr, "GetCommState failure; GetLastError(): %0.8x\n", GetLastError()); + fprintf(stderr, "GetCommState failure; GetLastError(): %08x\n", GetLastError()); return FALSE; } @@ -100,7 +100,7 @@ int TestControlSettings(int argc, char* argv[]) if (!SetCommState(hComm, &dcb)) { - fprintf(stderr, "SetCommState failure; GetLastError(): %0.8x\n", GetLastError()); + fprintf(stderr, "SetCommState failure; GetLastError(): %08x\n", GetLastError()); return FALSE; } @@ -108,7 +108,7 @@ int TestControlSettings(int argc, char* argv[]) dcb.DCBlength = sizeof(DCB); if (!GetCommState(hComm, &dcb)) { - fprintf(stderr, "GetCommState failure; GetLastError(): %0.8x\n", GetLastError()); + fprintf(stderr, "GetCommState failure; GetLastError(): %08x\n", GetLastError()); return FALSE; } @@ -121,7 +121,7 @@ int TestControlSettings(int argc, char* argv[]) if (!CloseHandle(hComm)) { - fprintf(stderr, "CloseHandle failure, GetLastError()=%0.8x\n", GetLastError()); + fprintf(stderr, "CloseHandle failure, GetLastError()=%08x\n", GetLastError()); return EXIT_FAILURE; } diff --git a/winpr/libwinpr/comm/test/TestGetCommState.c b/winpr/libwinpr/comm/test/TestGetCommState.c index 3c9da67b5..2a80a5219 100644 --- a/winpr/libwinpr/comm/test/TestGetCommState.c +++ b/winpr/libwinpr/comm/test/TestGetCommState.c @@ -129,7 +129,7 @@ int TestGetCommState(int argc, char* argv[]) if (!CloseHandle(hComm)) { - fprintf(stderr, "CloseHandle failure, GetLastError()=%0.8x\n", GetLastError()); + fprintf(stderr, "CloseHandle failure, GetLastError()=%08x\n", GetLastError()); return EXIT_FAILURE; } diff --git a/winpr/libwinpr/comm/test/TestHandflow.c b/winpr/libwinpr/comm/test/TestHandflow.c index 6cdbfb673..10cb20a13 100644 --- a/winpr/libwinpr/comm/test/TestHandflow.c +++ b/winpr/libwinpr/comm/test/TestHandflow.c @@ -88,7 +88,7 @@ int TestHandflow(int argc, char* argv[]) if (!CloseHandle(hComm)) { - fprintf(stderr, "CloseHandle failure, GetLastError()=%0.8x\n", GetLastError()); + fprintf(stderr, "CloseHandle failure, GetLastError()=%08x\n", GetLastError()); return EXIT_FAILURE; } diff --git a/winpr/libwinpr/comm/test/TestSerialChars.c b/winpr/libwinpr/comm/test/TestSerialChars.c index d1a75c9c5..50912bb09 100644 --- a/winpr/libwinpr/comm/test/TestSerialChars.c +++ b/winpr/libwinpr/comm/test/TestSerialChars.c @@ -48,7 +48,7 @@ static BOOL test_SerCxSys(HANDLE hComm) dcb.DCBlength = sizeof(DCB); if (!GetCommState(hComm, &dcb)) { - fprintf(stderr, "GetCommState failure, GetLastError(): 0x%0.8x\n", GetLastError()); + fprintf(stderr, "GetCommState failure, GetLastError(): 0x%08x\n", GetLastError()); return FALSE; } @@ -74,7 +74,7 @@ static BOOL test_SerCxSys(HANDLE hComm) dcb.XoffChar = XonChar; if (!SetCommState(hComm, &dcb)) { - fprintf(stderr, "SetCommState failure, GetLastError(): 0x%0.8x\n", GetLastError()); + fprintf(stderr, "SetCommState failure, GetLastError(): 0x%08x\n", GetLastError()); return FALSE; } @@ -82,7 +82,7 @@ static BOOL test_SerCxSys(HANDLE hComm) dcb.DCBlength = sizeof(DCB); if (!GetCommState(hComm, &dcb)) { - fprintf(stderr, "GetCommState failure, GetLastError(): 0x%0.8x\n", GetLastError()); + fprintf(stderr, "GetCommState failure, GetLastError(): 0x%08x\n", GetLastError()); return FALSE; } @@ -117,7 +117,7 @@ static BOOL test_SerCx2Sys(HANDLE hComm) dcb.DCBlength = sizeof(DCB); if (!GetCommState(hComm, &dcb)) { - fprintf(stderr, "GetCommState failure; GetLastError(): %0.8x\n", GetLastError()); + fprintf(stderr, "GetCommState failure; GetLastError(): %08x\n", GetLastError()); return FALSE; } @@ -175,7 +175,7 @@ int TestSerialChars(int argc, char* argv[]) if (!CloseHandle(hComm)) { - fprintf(stderr, "CloseHandle failure, GetLastError()=%0.8x\n", GetLastError()); + fprintf(stderr, "CloseHandle failure, GetLastError()=%08x\n", GetLastError()); return EXIT_FAILURE; } diff --git a/winpr/libwinpr/comm/test/TestSetCommState.c b/winpr/libwinpr/comm/test/TestSetCommState.c index 63dbdfda8..b1e825a5a 100644 --- a/winpr/libwinpr/comm/test/TestSetCommState.c +++ b/winpr/libwinpr/comm/test/TestSetCommState.c @@ -137,7 +137,7 @@ static BOOL test_SerialSys(HANDLE hComm) result = SetCommState(hComm, &dcb); if (!result) { - fprintf(stderr, "SetCommState failure: 0x%0.8x\n", GetLastError()); + fprintf(stderr, "SetCommState failure: 0x%08x\n", GetLastError()); return FALSE; } @@ -207,7 +207,7 @@ static BOOL test_SerCxSys(HANDLE hComm) result = SetCommState(hComm, &dcb); if (!result) { - fprintf(stderr, "SetCommState failure: 0x%0.8x\n", GetLastError()); + fprintf(stderr, "SetCommState failure: 0x%08x\n", GetLastError()); return FALSE; } @@ -284,7 +284,7 @@ static BOOL test_generic(HANDLE hComm) result = SetCommState(hComm, &dcb); if (!result) { - fprintf(stderr, "SetCommState failure: 0x%0.8x\n", GetLastError()); + fprintf(stderr, "SetCommState failure: 0x%08x\n", GetLastError()); return FALSE; } @@ -389,7 +389,7 @@ int TestSetCommState(int argc, char* argv[]) if (!CloseHandle(hComm)) { - fprintf(stderr, "CloseHandle failure, GetLastError()=%0.8x\n", GetLastError()); + fprintf(stderr, "CloseHandle failure, GetLastError()=%08x\n", GetLastError()); return EXIT_FAILURE; } diff --git a/winpr/libwinpr/comm/test/TestTimeouts.c b/winpr/libwinpr/comm/test/TestTimeouts.c index 652bd47be..0ddf2775a 100644 --- a/winpr/libwinpr/comm/test/TestTimeouts.c +++ b/winpr/libwinpr/comm/test/TestTimeouts.c @@ -41,14 +41,14 @@ static BOOL test_generic(HANDLE hComm) if (!SetCommTimeouts(hComm, &timeouts)) { - fprintf(stderr, "SetCommTimeouts failure, GetLastError: 0x%0.8x\n", GetLastError()); + fprintf(stderr, "SetCommTimeouts failure, GetLastError: 0x%08x\n", GetLastError()); return FALSE; } ZeroMemory(&timeouts2, sizeof(COMMTIMEOUTS)); if (!GetCommTimeouts(hComm, &timeouts2)) { - fprintf(stderr, "GetCommTimeouts failure, GetLastError: 0x%0.8x\n", GetLastError()); + fprintf(stderr, "GetCommTimeouts failure, GetLastError: 0x%08x\n", GetLastError()); return FALSE; } @@ -63,13 +63,13 @@ static BOOL test_generic(HANDLE hComm) timeouts.ReadTotalTimeoutConstant = MAXULONG; if (SetCommTimeouts(hComm, &timeouts)) { - fprintf(stderr, "SetCommTimeouts succeeded with ReadIntervalTimeout and ReadTotalTimeoutConstant set to MAXULONG. GetLastError: 0x%0.8x\n", GetLastError()); + fprintf(stderr, "SetCommTimeouts succeeded with ReadIntervalTimeout and ReadTotalTimeoutConstant set to MAXULONG. GetLastError: 0x%08x\n", GetLastError()); return FALSE; } if (GetLastError() != ERROR_INVALID_PARAMETER) { - fprintf(stderr, "SetCommTimeouts failure, expected GetLastError to return ERROR_INVALID_PARAMETER and got: 0x%0.8x\n", GetLastError()); + fprintf(stderr, "SetCommTimeouts failure, expected GetLastError to return ERROR_INVALID_PARAMETER and got: 0x%08x\n", GetLastError()); return FALSE; } @@ -128,7 +128,7 @@ int TestTimeouts(int argc, char* argv[]) if (!CloseHandle(hComm)) { - fprintf(stderr, "CloseHandle failure, GetLastError()=%0.8x\n", GetLastError()); + fprintf(stderr, "CloseHandle failure, GetLastError()=%08x\n", GetLastError()); return EXIT_FAILURE; } diff --git a/winpr/libwinpr/crt/alignment.c b/winpr/libwinpr/crt/alignment.c index 47bb88e89..a4b870f94 100644 --- a/winpr/libwinpr/crt/alignment.c +++ b/winpr/libwinpr/crt/alignment.c @@ -139,7 +139,6 @@ void* _aligned_offset_realloc(void* memblock, size_t size, size_t alignment, siz void* _aligned_offset_recalloc(void* memblock, size_t num, size_t size, size_t alignment, size_t offset) { - size_t copySize; void* newMemblock; WINPR_ALIGNED_MEM* pMem; WINPR_ALIGNED_MEM* pNewMem; diff --git a/winpr/libwinpr/crt/string.c b/winpr/libwinpr/crt/string.c index 0ecdc6a42..37bd6ebec 100644 --- a/winpr/libwinpr/crt/string.c +++ b/winpr/libwinpr/crt/string.c @@ -54,7 +54,7 @@ WCHAR* _wcsdup(const WCHAR* strSource) if (strSource == NULL) return NULL; -#if sun +#if defined(sun) && sun strDestination = wsdup(strSource); #elif defined(__APPLE__) && defined(__MACH__) || defined(ANDROID) strDestination = malloc(wcslen((wchar_t*)strSource)); diff --git a/winpr/libwinpr/crt/test/TestIntrinsics.c b/winpr/libwinpr/crt/test/TestIntrinsics.c index bb1f07b05..5bbf915f9 100644 --- a/winpr/libwinpr/crt/test/TestIntrinsics.c +++ b/winpr/libwinpr/crt/test/TestIntrinsics.c @@ -1,36 +1,53 @@ -#include #include +#include #include +static BOOL g_LZCNT = FALSE; + +static INLINE UINT32 lzcnt_s(UINT32 x) +{ + if (!x) + return 32; + + if (!g_LZCNT) + { + UINT32 y; + int n = 32; + y = x >> 16; if (y != 0) { n = n - 16; x = y; } + y = x >> 8; if (y != 0) { n = n - 8; x = y; } + y = x >> 4; if (y != 0) { n = n - 4; x = y; } + y = x >> 2; if (y != 0) { n = n - 2; x = y; } + y = x >> 1; if (y != 0) return n - 2; + return n - x; + } + + return __lzcnt(x); +} + int test_lzcnt() { - if (__lzcnt(0x0) != 32) { - fprintf(stderr, "__lzcnt(0x0) != 32\n"); + if (lzcnt_s(0x1) != 31) { + fprintf(stderr, "__lzcnt(0x1) != 31: %d\n", __lzcnt(0x1)); return -1; } - if (__lzcnt(0x1) != 31) { - fprintf(stderr, "__lzcnt(0x1) != 31\n"); - return -1; - } - - if (__lzcnt(0xFF) != 24) { + if (lzcnt_s(0xFF) != 24) { fprintf(stderr, "__lzcnt(0xFF) != 24\n"); return -1; } - if (__lzcnt(0xFFFF) != 16) { + if (lzcnt_s(0xFFFF) != 16) { fprintf(stderr, "__lzcnt(0xFFFF) != 16\n"); return -1; } - if (__lzcnt(0xFFFFFF) != 8) { + if (lzcnt_s(0xFFFFFF) != 8) { fprintf(stderr, "__lzcnt(0xFFFFFF) != 8\n"); return -1; } - if (__lzcnt(0xFFFFFFFF) != 0) { + if (lzcnt_s(0xFFFFFFFF) != 0) { fprintf(stderr, "__lzcnt(0xFFFFFFFF) != 0\n"); return -1; } @@ -40,11 +57,6 @@ int test_lzcnt() int test_lzcnt16() { - if (__lzcnt16(0x0) != 16) { - fprintf(stderr, "__lzcnt16(0x0) != 16\n"); - return -1; - } - if (__lzcnt16(0x1) != 15) { fprintf(stderr, "__lzcnt16(0x1) != 15\n"); return -1; @@ -63,47 +75,14 @@ int test_lzcnt16() return 1; } -int test_lzcnt64() -{ - if (__lzcnt64(0x0) != 64) { - fprintf(stderr, "__lzcnt64(0x0) != 64\n"); - return -1; - } - - if (__lzcnt64(0x1) != 63) { - fprintf(stderr, "__lzcnt64(0x1) != 63\n"); - return -1; - } - - if (__lzcnt64(0xFF) != 56) { - fprintf(stderr, "__lzcnt64(0xFF) != 56\n"); - return -1; - } - - if (__lzcnt64(0xFFFF) != 48) { - fprintf(stderr, "__lzcnt64(0xFFFF) != 48\n"); - return -1; - } - - if (__lzcnt64(0xFFFFFF) != 40) { - fprintf(stderr, "__lzcnt64(0xFFFFFF) != 40\n"); - return -1; - } - - if (__lzcnt64(0xFFFFFFFF) != 32) { - fprintf(stderr, "__lzcnt64(0xFFFFFFFF) != 32\n"); - return -1; - } - - return 1; -} - int TestIntrinsics(int argc, char* argv[]) { + g_LZCNT = IsProcessorFeaturePresentEx(PF_EX_LZCNT); + + printf("LZCNT available: %d\n", g_LZCNT); + test_lzcnt(); - test_lzcnt16(); - test_lzcnt64(); + //test_lzcnt16(); return 0; } - diff --git a/winpr/libwinpr/handle/handle.h b/winpr/libwinpr/handle/handle.h index 819e7b3db..91a3e9452 100644 --- a/winpr/libwinpr/handle/handle.h +++ b/winpr/libwinpr/handle/handle.h @@ -50,7 +50,7 @@ typedef struct winpr_handle WINPR_HANDLE; #define WINPR_HANDLE_SET_TYPE(_handle, _type) \ _handle->Type = _type -static inline BOOL winpr_Handle_GetInfo(HANDLE handle, ULONG* pType, PVOID* pObject) +static INLINE BOOL winpr_Handle_GetInfo(HANDLE handle, ULONG* pType, PVOID* pObject) { WINPR_HANDLE* wHandle; @@ -65,7 +65,6 @@ static inline BOOL winpr_Handle_GetInfo(HANDLE handle, ULONG* pType, PVOID* pObj return TRUE; } - typedef BOOL (*pcIsHandled)(HANDLE handle); typedef BOOL (*pcCloseHandle)(HANDLE handle); diff --git a/winpr/libwinpr/interlocked/interlocked.c b/winpr/libwinpr/interlocked/interlocked.c index 0b8c0d45a..6490bb6f1 100644 --- a/winpr/libwinpr/interlocked/interlocked.c +++ b/winpr/libwinpr/interlocked/interlocked.c @@ -282,7 +282,7 @@ LONGLONG InterlockedCompareExchange64(LONGLONG volatile *Destination, LONGLONG E return previousValue; } -#elif ANDROID || (defined(__GNUC__) && !defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8)) +#elif (defined(ANDROID) && ANDROID) || (defined(__GNUC__) && !defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8)) #include diff --git a/winpr/libwinpr/path/shell.c b/winpr/libwinpr/path/shell.c index 10f7b7d9d..eae9a6539 100644 --- a/winpr/libwinpr/path/shell.c +++ b/winpr/libwinpr/path/shell.c @@ -271,6 +271,39 @@ char* GetKnownSubPath(int id, const char* path) return subPath; } +char* GetEnvironmentPath(char* name) +{ + char* env; + DWORD nSize; + + nSize = GetEnvironmentVariableA(name, NULL, 0); + + if (nSize) + { + env = (LPSTR) malloc(nSize); + nSize = GetEnvironmentVariableA(name, env, nSize); + } + + return env; +} + +char* GetEnvironmentSubPath(char* name, const char* path) +{ + char* env; + char* subpath; + + env = GetEnvironmentPath(name); + + if (!env) + return NULL; + + subpath = GetCombinedPath(env, path); + + free(env); + + return subpath; +} + char* GetCombinedPath(const char* basePath, const char* subPath) { int length; @@ -309,8 +342,6 @@ char* GetCombinedPath(const char* basePath, const char* subPath) return path; } -//#ifndef _WIN32 - BOOL PathFileExistsA(LPCSTR pszPath) { struct stat stat_info; @@ -326,4 +357,3 @@ BOOL PathFileExistsW(LPCWSTR pszPath) return FALSE; } -//#endif diff --git a/winpr/libwinpr/synch/barrier.c b/winpr/libwinpr/synch/barrier.c index 95fef076c..f8d75cb5d 100644 --- a/winpr/libwinpr/synch/barrier.c +++ b/winpr/libwinpr/synch/barrier.c @@ -23,26 +23,154 @@ #include -/** - * InitializeSynchronizationBarrier - * EnterSynchronizationBarrier - * DeleteSynchronizationBarrier - */ +#include "synch.h" -#ifndef _WIN32 +#include -BOOL InitializeSynchronizationBarrier(LPSYNCHRONIZATION_BARRIER lpBarrier, LONG lTotalThreads, LONG lSpinCount) +#if (!defined(_WIN32)) || (defined(_WIN32) && (_WIN32_WINNT < 0x0602)) + +#include +#include + +#ifdef _WIN32 + +static HMODULE g_Kernel32 = NULL; +static BOOL g_NativeBarrier = FALSE; +static INIT_ONCE g_InitOnce = INIT_ONCE_STATIC_INIT; + +typedef BOOL (WINAPI * fnInitializeSynchronizationBarrier)(LPSYNCHRONIZATION_BARRIER lpBarrier, LONG lTotalThreads, LONG lSpinCount); +typedef BOOL (WINAPI * fnEnterSynchronizationBarrier)(LPSYNCHRONIZATION_BARRIER lpBarrier, DWORD dwFlags); +typedef BOOL (WINAPI * fnDeleteSynchronizationBarrier)(LPSYNCHRONIZATION_BARRIER lpBarrier); + +static fnInitializeSynchronizationBarrier pfnInitializeSynchronizationBarrier = NULL; +static fnEnterSynchronizationBarrier pfnEnterSynchronizationBarrier = NULL; +static fnDeleteSynchronizationBarrier pfnDeleteSynchronizationBarrier = NULL; + +static BOOL CALLBACK InitOnce_Barrier(PINIT_ONCE once, PVOID param, PVOID *context) { - return TRUE; -} + g_Kernel32 = LoadLibraryA("kernel32.dll"); -BOOL EnterSynchronizationBarrier(LPSYNCHRONIZATION_BARRIER lpBarrier, DWORD dwFlags) -{ - return TRUE; -} + if (!g_Kernel32) + return TRUE; + + pfnInitializeSynchronizationBarrier = (fnInitializeSynchronizationBarrier) + GetProcAddress(g_Kernel32, "InitializeSynchronizationBarrier"); + + pfnEnterSynchronizationBarrier = (fnEnterSynchronizationBarrier) + GetProcAddress(g_Kernel32, "EnterSynchronizationBarrier"); + + pfnDeleteSynchronizationBarrier = (fnDeleteSynchronizationBarrier) + GetProcAddress(g_Kernel32, "DeleteSynchronizationBarrier"); + + if (pfnInitializeSynchronizationBarrier && pfnEnterSynchronizationBarrier + && pfnDeleteSynchronizationBarrier) + { + g_NativeBarrier = TRUE; + } + + return TRUE; +} + +#endif + +BOOL WINAPI InitializeSynchronizationBarrier(LPSYNCHRONIZATION_BARRIER lpBarrier, LONG lTotalThreads, LONG lSpinCount) +{ + WINPR_BARRIER* pBarrier; + +#ifdef _WIN32 + InitOnceExecuteOnce(&g_InitOnce, InitOnce_Barrier, NULL, NULL); + + if (g_NativeBarrier) + return pfnInitializeSynchronizationBarrier(lpBarrier, lTotalThreads, lSpinCount); +#endif + + if (!lpBarrier) + return FALSE; + + ZeroMemory(lpBarrier, sizeof(SYNCHRONIZATION_BARRIER)); + + pBarrier = (WINPR_BARRIER*) calloc(1, sizeof(WINPR_BARRIER)); + + if (!pBarrier) + return FALSE; + + if (lSpinCount < 0) + lSpinCount = 2000; + + pBarrier->lTotalThreads = lTotalThreads; + pBarrier->lSpinCount = lSpinCount; + pBarrier->count = 0; + + pBarrier->event = CreateEvent(NULL, TRUE, FALSE, NULL); + + if (!pBarrier->event) + { + free(pBarrier); + return FALSE; + } + + lpBarrier->Reserved3[0] = (ULONG_PTR) pBarrier; + + return TRUE; +} + +BOOL WINAPI EnterSynchronizationBarrier(LPSYNCHRONIZATION_BARRIER lpBarrier, DWORD dwFlags) +{ + LONG count; + BOOL status = FALSE; + WINPR_BARRIER* pBarrier; + +#ifdef _WIN32 + if (g_NativeBarrier) + return pfnEnterSynchronizationBarrier(lpBarrier, dwFlags); +#endif + + if (!lpBarrier) + return FALSE; + + pBarrier = (WINPR_BARRIER*) lpBarrier->Reserved3[0]; + + if (!pBarrier) + return FALSE; + + count = InterlockedIncrement(&(pBarrier->count)); + + if (count < pBarrier->lTotalThreads) + { + WaitForSingleObject(pBarrier->event, INFINITE); + } + else + { + SetEvent(pBarrier->event); + status = TRUE; + } + + return status; +} + +BOOL WINAPI DeleteSynchronizationBarrier(LPSYNCHRONIZATION_BARRIER lpBarrier) +{ + WINPR_BARRIER* pBarrier; + +#ifdef _WIN32 + if (g_NativeBarrier) + return pfnDeleteSynchronizationBarrier(lpBarrier); +#endif + + if (!lpBarrier) + return TRUE; + + pBarrier = (WINPR_BARRIER*) lpBarrier->Reserved3[0]; + + if (!pBarrier) + return TRUE; + + CloseHandle(pBarrier->event); + + free(pBarrier); + + ZeroMemory(lpBarrier, sizeof(SYNCHRONIZATION_BARRIER)); -BOOL DeleteSynchronizationBarrier(LPSYNCHRONIZATION_BARRIER lpBarrier) -{ return TRUE; } diff --git a/winpr/libwinpr/synch/critical.c b/winpr/libwinpr/synch/critical.c index f67c373a3..0ea0def34 100644 --- a/winpr/libwinpr/synch/critical.c +++ b/winpr/libwinpr/synch/critical.c @@ -101,7 +101,7 @@ DWORD SetCriticalSectionSpinCount(LPCRITICAL_SECTION lpCriticalSection, DWORD dw #endif } -VOID _WaitForCriticalSection(LPCRITICAL_SECTION lpCriticalSection) +static VOID _WaitForCriticalSection(LPCRITICAL_SECTION lpCriticalSection) { #if defined(__APPLE__) semaphore_wait(*((winpr_sem_t*) lpCriticalSection->LockSemaphore)); @@ -110,7 +110,7 @@ VOID _WaitForCriticalSection(LPCRITICAL_SECTION lpCriticalSection) #endif } -VOID _UnWaitCriticalSection(LPCRITICAL_SECTION lpCriticalSection) +static VOID _UnWaitCriticalSection(LPCRITICAL_SECTION lpCriticalSection) { #if defined __APPLE__ semaphore_signal(*((winpr_sem_t*) lpCriticalSection->LockSemaphore)); diff --git a/winpr/libwinpr/synch/event.c b/winpr/libwinpr/synch/event.c index 0bae21fa3..47c250952 100644 --- a/winpr/libwinpr/synch/event.c +++ b/winpr/libwinpr/synch/event.c @@ -121,6 +121,20 @@ HANDLE OpenEventA(DWORD dwDesiredAccess, BOOL bInheritHandle, LPCSTR lpName) return NULL; } +#ifdef HAVE_EVENTFD_H +#if defined(__UCLIBC__) +static int eventfd_read(int fd, eventfd_t* value) +{ + return (read(fd, value, sizeof(*value)) == sizeof(*value)) ? 0 : -1; +} + +static int eventfd_write(int fd, eventfd_t value) +{ + return (write(fd, &value, sizeof(value)) == sizeof(value)) ? 0 : -1; +} +#endif +#endif + BOOL SetEvent(HANDLE hEvent) { ULONG Type; diff --git a/winpr/libwinpr/synch/synch.h b/winpr/libwinpr/synch/synch.h index fbde1d4a8..51810237a 100644 --- a/winpr/libwinpr/synch/synch.h +++ b/winpr/libwinpr/synch/synch.h @@ -32,10 +32,10 @@ #define WITH_POSIX_TIMER 1 #endif -#ifndef _WIN32 - #include "../handle/handle.h" +#ifndef _WIN32 + #define WINPR_PIPE_SEMAPHORE 1 #if defined __APPLE__ @@ -144,4 +144,13 @@ struct winpr_timer_queue_timer #endif +struct winpr_barrier +{ + DECLSPEC_ALIGN(4) LONG count; + LONG lTotalThreads; + LONG lSpinCount; + HANDLE event; +}; +typedef struct winpr_barrier WINPR_BARRIER; + #endif /* WINPR_SYNCH_PRIVATE_H */ diff --git a/winpr/libwinpr/synch/test/CMakeLists.txt b/winpr/libwinpr/synch/test/CMakeLists.txt index 0309fb910..68b76faa0 100644 --- a/winpr/libwinpr/synch/test/CMakeLists.txt +++ b/winpr/libwinpr/synch/test/CMakeLists.txt @@ -8,6 +8,7 @@ set(${MODULE_PREFIX}_TESTS TestSynchInit.c TestSynchEvent.c TestSynchMutex.c + TestSynchBarrier.c TestSynchCritical.c TestSynchSemaphore.c TestSynchThread.c diff --git a/winpr/libwinpr/synch/test/TestSynchBarrier.c b/winpr/libwinpr/synch/test/TestSynchBarrier.c new file mode 100644 index 000000000..ebdcc7c6e --- /dev/null +++ b/winpr/libwinpr/synch/test/TestSynchBarrier.c @@ -0,0 +1,72 @@ + +#include +#include +#include + +static int g_Count; +static HANDLE g_Event; +static CRITICAL_SECTION g_Lock; +static SYNCHRONIZATION_BARRIER g_Barrier; + +static void* test_synch_barrier_thread_func(void* arg) +{ + BOOL status; + + status = EnterSynchronizationBarrier(&g_Barrier, 0); + + EnterCriticalSection(&g_Lock); + + printf("Thread #%d status: %s\n", g_Count++, + status ? "TRUE" : "FALSE"); + + LeaveCriticalSection(&g_Lock); + + if (status) + { + SetEvent(g_Event); + } + + return NULL; +} + +int TestSynchBarrier(int argc, char* argv[]) +{ + int index; + HANDLE threads[5]; + + g_Count = 0; + + g_Event = CreateEvent(NULL, TRUE, FALSE, NULL); + + InitializeCriticalSectionAndSpinCount(&g_Lock, 4000); + + if (!InitializeSynchronizationBarrier(&g_Barrier, 5, -1)) + return -1; + + for (index = 0; index < 5; index++) + { + threads[index] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) + test_synch_barrier_thread_func, NULL, 0, NULL); + } + + WaitForSingleObject(g_Event, INFINITE); + + if (g_Count != 5) + return -1; + + printf("All threads have reached the barrier\n"); + + for (index = 0; index < 5; index++) + { + CloseHandle(threads[index]); + } + + DeleteSynchronizationBarrier(&g_Barrier); + + DeleteCriticalSection(&g_Lock); + + CloseHandle(g_Event); + + return 0; +} + diff --git a/winpr/libwinpr/synch/timer.c b/winpr/libwinpr/synch/timer.c index 0f0c41572..3b715a74a 100644 --- a/winpr/libwinpr/synch/timer.c +++ b/winpr/libwinpr/synch/timer.c @@ -190,10 +190,14 @@ BOOL SetWaitableTimer(HANDLE hTimer, const LARGE_INTEGER* lpDueTime, LONG lPerio { ULONG Type; PVOID Object; - int status = 0; WINPR_TIMER* timer; - LONGLONG seconds = 0; +#ifdef WITH_POSIX_TIMER + LONGLONG seconds = 0; LONGLONG nanoseconds = 0; +#ifdef HAVE_TIMERFD_H + int status = 0; +#endif /* HAVE_TIMERFD_H */ +#endif /* WITH_POSIX_TIMER */ if (!winpr_Handle_GetInfo(hTimer, &Type, &Object)) return FALSE; diff --git a/winpr/libwinpr/synch/wait.c b/winpr/libwinpr/synch/wait.c index e55365398..bfc5f726b 100644 --- a/winpr/libwinpr/synch/wait.c +++ b/winpr/libwinpr/synch/wait.c @@ -317,6 +317,7 @@ DWORD WaitForSingleObject(HANDLE hHandle, DWORD dwMilliseconds) event = (WINPR_EVENT*) Object; status = waitOnFd(event->pipe_fd[0], dwMilliseconds); + if (status < 0) { fprintf(stderr, "WaitForSingleObject: event select() failure [%d] %s\n", errno, strerror(errno)); diff --git a/winpr/libwinpr/sysinfo/sysinfo.c b/winpr/libwinpr/sysinfo/sysinfo.c index 572916ca3..008420455 100644 --- a/winpr/libwinpr/sysinfo/sysinfo.c +++ b/winpr/libwinpr/sysinfo/sysinfo.c @@ -222,7 +222,6 @@ BOOL GetComputerNameExA(COMPUTER_NAME_FORMAT NameType, LPSTR lpBuffer, LPDWORD l default: return FALSE; - break; } return TRUE; @@ -439,6 +438,7 @@ ULONGLONG GetTickCount64(void) #define D_BIT_3DN (1<<30) #define C_BIT_SSE3 (1<<0) #define C_BIT_PCLMULQDQ (1<<1) +#define C_BIT_LZCNT (1<<5) #define C_BIT_3DNP (1<<8) #define C_BIT_3DNP (1<<8) #define C_BIT_SSSE3 (1<<9) @@ -692,6 +692,10 @@ BOOL IsProcessorFeaturePresentEx(DWORD ProcessorFeature) switch (ProcessorFeature) { + case PF_EX_LZCNT: + if (c & C_BIT_LZCNT) + ret = TRUE; + break; case PF_EX_3DNOW_PREFETCH: if (c & C_BIT_3DNP) ret = TRUE; diff --git a/winpr/libwinpr/utils/CMakeLists.txt b/winpr/libwinpr/utils/CMakeLists.txt index d8b758bbe..3b2839e68 100644 --- a/winpr/libwinpr/utils/CMakeLists.txt +++ b/winpr/libwinpr/utils/CMakeLists.txt @@ -75,11 +75,17 @@ set(${MODULE_PREFIX}_SRCS ini.c sam.c ntlm.c + image.c print.c stream.c + debug.c cmdline.c ssl.c) +if (ANDROID) + include_directories(${CMAKE_CURRENT_SOURCE_DIR}) +endif() + winpr_module_add(${${MODULE_PREFIX}_SRCS} ${${MODULE_PREFIX}_COLLECTIONS_SRCS} ${${MODULE_PREFIX}_TRIO_SRCS} diff --git a/winpr/libwinpr/utils/collections/ArrayList.c b/winpr/libwinpr/utils/collections/ArrayList.c index 478f26b74..47d9ee7ce 100644 --- a/winpr/libwinpr/utils/collections/ArrayList.c +++ b/winpr/libwinpr/utils/collections/ArrayList.c @@ -38,7 +38,7 @@ * Gets or sets the number of elements that the ArrayList can contain. */ -int ArrayList_Capacity(wArrayList* arrayList) +int ArrayList_Capacity(wArrayList *arrayList) { return arrayList->capacity; } @@ -47,7 +47,7 @@ int ArrayList_Capacity(wArrayList* arrayList) * Gets the number of elements actually contained in the ArrayList. */ -int ArrayList_Count(wArrayList* arrayList) +int ArrayList_Count(wArrayList *arrayList) { return arrayList->size; } @@ -56,7 +56,7 @@ int ArrayList_Count(wArrayList* arrayList) * Gets a value indicating whether the ArrayList has a fixed size. */ -BOOL ArrayList_IsFixedSized(wArrayList* arrayList) +BOOL ArrayList_IsFixedSized(wArrayList *arrayList) { return FALSE; } @@ -65,7 +65,7 @@ BOOL ArrayList_IsFixedSized(wArrayList* arrayList) * Gets a value indicating whether the ArrayList is read-only. */ -BOOL ArrayList_IsReadOnly(wArrayList* arrayList) +BOOL ArrayList_IsReadOnly(wArrayList *arrayList) { return FALSE; } @@ -74,7 +74,7 @@ BOOL ArrayList_IsReadOnly(wArrayList* arrayList) * Gets a value indicating whether access to the ArrayList is synchronized (thread safe). */ -BOOL ArrayList_IsSynchronized(wArrayList* arrayList) +BOOL ArrayList_IsSynchronized(wArrayList *arrayList) { return arrayList->synchronized; } @@ -83,7 +83,7 @@ BOOL ArrayList_IsSynchronized(wArrayList* arrayList) * Lock access to the ArrayList */ -void ArrayList_Lock(wArrayList* arrayList) +void ArrayList_Lock(wArrayList *arrayList) { EnterCriticalSection(&arrayList->lock); } @@ -92,7 +92,7 @@ void ArrayList_Lock(wArrayList* arrayList) * Unlock access to the ArrayList */ -void ArrayList_Unlock(wArrayList* arrayList) +void ArrayList_Unlock(wArrayList *arrayList) { LeaveCriticalSection(&arrayList->lock); } @@ -101,9 +101,9 @@ void ArrayList_Unlock(wArrayList* arrayList) * Gets the element at the specified index. */ -void* ArrayList_GetItem(wArrayList* arrayList, int index) +void *ArrayList_GetItem(wArrayList *arrayList, int index) { - void* obj = NULL; + void *obj = NULL; if ((index >= 0) && (index < arrayList->size)) { @@ -117,7 +117,7 @@ void* ArrayList_GetItem(wArrayList* arrayList, int index) * Sets the element at the specified index. */ -void ArrayList_SetItem(wArrayList* arrayList, int index, void* obj) +void ArrayList_SetItem(wArrayList *arrayList, int index, void *obj) { if ((index >= 0) && (index < arrayList->size)) { @@ -133,7 +133,7 @@ void ArrayList_SetItem(wArrayList* arrayList, int index, void* obj) * Shift a section of the list. */ -BOOL ArrayList_Shift(wArrayList* arrayList, int index, int count) +BOOL ArrayList_Shift(wArrayList *arrayList, int index, int count) { if (count > 0) { @@ -141,24 +141,28 @@ BOOL ArrayList_Shift(wArrayList* arrayList, int index, int count) { void **newArray; int newCapacity = arrayList->capacity * arrayList->growthFactor; + newArray = (void **)realloc(arrayList->array, sizeof(void *) * newCapacity); - newArray = (void **)realloc(arrayList->array, sizeof(void*) * newCapacity); if (!newArray) return FALSE; + arrayList->array = newArray; arrayList->capacity = newCapacity; } - MoveMemory(&arrayList->array[index + count], &arrayList->array[index], (arrayList->size - index) * sizeof(void*)); + MoveMemory(&arrayList->array[index + count], &arrayList->array[index], (arrayList->size - index) * sizeof(void *)); arrayList->size += count; } else if (count < 0) { int chunk = arrayList->size - index + count; + if (chunk > 0) - MoveMemory(&arrayList->array[index], &arrayList->array[index - count], chunk * sizeof(void*)); + MoveMemory(&arrayList->array[index], &arrayList->array[index - count], chunk * sizeof(void *)); + arrayList->size += count; } + return TRUE; } @@ -166,7 +170,7 @@ BOOL ArrayList_Shift(wArrayList* arrayList, int index, int count) * Removes all elements from the ArrayList. */ -void ArrayList_Clear(wArrayList* arrayList) +void ArrayList_Clear(wArrayList *arrayList) { int index; @@ -191,22 +195,33 @@ void ArrayList_Clear(wArrayList* arrayList) * Determines whether an element is in the ArrayList. */ -BOOL ArrayList_Contains(wArrayList* arrayList, void* obj) +BOOL ArrayList_Contains(wArrayList *arrayList, void *obj) { + DWORD index; + BOOL rc = FALSE; + if (arrayList->synchronized) EnterCriticalSection(&arrayList->lock); + for (index = 0; index < arrayList->size; index++) + { + rc = arrayList->object.fnObjectEquals(arrayList->array[index], obj); + + if (rc) + break; + } + if (arrayList->synchronized) LeaveCriticalSection(&arrayList->lock); - return FALSE; + return rc; } /** * Adds an object to the end of the ArrayList. */ -int ArrayList_Add(wArrayList* arrayList, void* obj) +int ArrayList_Add(wArrayList *arrayList, void *obj) { int index = -1; @@ -217,7 +232,8 @@ int ArrayList_Add(wArrayList* arrayList, void* obj) { void **newArray; int newCapacity = arrayList->capacity * arrayList->growthFactor; - newArray = (void **)realloc(arrayList->array, sizeof(void*) * newCapacity); + newArray = (void **)realloc(arrayList->array, sizeof(void *) * newCapacity); + if (!newArray) goto out; @@ -227,8 +243,8 @@ int ArrayList_Add(wArrayList* arrayList, void* obj) arrayList->array[arrayList->size++] = obj; index = arrayList->size; - out: + if (arrayList->synchronized) LeaveCriticalSection(&arrayList->lock); @@ -239,9 +255,10 @@ out: * Inserts an element into the ArrayList at the specified index. */ -BOOL ArrayList_Insert(wArrayList* arrayList, int index, void* obj) +BOOL ArrayList_Insert(wArrayList *arrayList, int index, void *obj) { BOOL ret = TRUE; + if (arrayList->synchronized) EnterCriticalSection(&arrayList->lock); @@ -259,6 +276,7 @@ BOOL ArrayList_Insert(wArrayList* arrayList, int index, void* obj) if (arrayList->synchronized) LeaveCriticalSection(&arrayList->lock); + return ret; } @@ -266,7 +284,7 @@ BOOL ArrayList_Insert(wArrayList* arrayList, int index, void* obj) * Removes the first occurrence of a specific object from the ArrayList. */ -BOOL ArrayList_Remove(wArrayList* arrayList, void* obj) +BOOL ArrayList_Remove(wArrayList *arrayList, void *obj) { int index; BOOL found = FALSE; @@ -285,14 +303,16 @@ BOOL ArrayList_Remove(wArrayList* arrayList, void* obj) } if (found) - { + { if (arrayList->object.fnObjectFree) arrayList->object.fnObjectFree(arrayList->array[index]); + ret = ArrayList_Shift(arrayList, index, -1); - } + } if (arrayList->synchronized) LeaveCriticalSection(&arrayList->lock); + return ret; } @@ -300,7 +320,7 @@ BOOL ArrayList_Remove(wArrayList* arrayList, void* obj) * Removes the element at the specified index of the ArrayList. */ -BOOL ArrayList_RemoveAt(wArrayList* arrayList, int index) +BOOL ArrayList_RemoveAt(wArrayList *arrayList, int index) { BOOL ret = TRUE; @@ -311,11 +331,13 @@ BOOL ArrayList_RemoveAt(wArrayList* arrayList, int index) { if (arrayList->object.fnObjectFree) arrayList->object.fnObjectFree(arrayList->array[index]); + ret = ArrayList_Shift(arrayList, index, -1); } if (arrayList->synchronized) LeaveCriticalSection(&arrayList->lock); + return ret; } @@ -329,7 +351,7 @@ BOOL ArrayList_RemoveAt(wArrayList* arrayList, int index) * in the ArrayList that contains the specified number of elements and ends at the specified index. */ -int ArrayList_IndexOf(wArrayList* arrayList, void* obj, int startIndex, int count) +int ArrayList_IndexOf(wArrayList *arrayList, void *obj, int startIndex, int count) { int index; BOOL found = FALSE; @@ -345,7 +367,7 @@ int ArrayList_IndexOf(wArrayList* arrayList, void* obj, int startIndex, int coun for (index = startIndex; index < startIndex + count; index++) { - if (arrayList->array[index] == obj) + if (arrayList->object.fnObjectEquals(arrayList->array[index], obj)) { found = TRUE; break; @@ -371,7 +393,7 @@ int ArrayList_IndexOf(wArrayList* arrayList, void* obj, int startIndex, int coun * in the ArrayList that contains the specified number of elements and ends at the specified index. */ -int ArrayList_LastIndexOf(wArrayList* arrayList, void* obj, int startIndex, int count) +int ArrayList_LastIndexOf(wArrayList *arrayList, void *obj, int startIndex, int count) { int index; BOOL found = FALSE; @@ -387,7 +409,7 @@ int ArrayList_LastIndexOf(wArrayList* arrayList, void* obj, int startIndex, int for (index = startIndex + count - 1; index >= startIndex; index--) { - if (arrayList->array[index] == obj) + if (arrayList->object.fnObjectEquals(arrayList->array[index], obj)) { found = TRUE; break; @@ -403,38 +425,42 @@ int ArrayList_LastIndexOf(wArrayList* arrayList, void* obj, int startIndex, int return index; } +static BOOL ArrayList_DefaultCompare(void *objA, void *objB) +{ + return objA == objB ? TRUE : FALSE; +} + /** * Construction, Destruction */ -wArrayList* ArrayList_New(BOOL synchronized) +wArrayList *ArrayList_New(BOOL synchronized) { - wArrayList* arrayList = NULL; - + wArrayList *arrayList = NULL; arrayList = (wArrayList *)calloc(1, sizeof(wArrayList)); + if (!arrayList) return NULL; arrayList->synchronized = synchronized; arrayList->capacity = 32; arrayList->growthFactor = 2; - + arrayList->object.fnObjectEquals = ArrayList_DefaultCompare; arrayList->array = (void **)malloc(arrayList->capacity * sizeof(void *)); + if (!arrayList->array) goto out_free; InitializeCriticalSectionAndSpinCount(&arrayList->lock, 4000); return arrayList; - out_free: free(arrayList); return NULL; } -void ArrayList_Free(wArrayList* arrayList) +void ArrayList_Free(wArrayList *arrayList) { ArrayList_Clear(arrayList); - DeleteCriticalSection(&arrayList->lock); free(arrayList->array); free(arrayList); diff --git a/winpr/libwinpr/utils/collections/BufferPool.c b/winpr/libwinpr/utils/collections/BufferPool.c index 3a0fda5b4..2b05263c6 100644 --- a/winpr/libwinpr/utils/collections/BufferPool.c +++ b/winpr/libwinpr/utils/collections/BufferPool.c @@ -34,7 +34,7 @@ * Methods */ -BOOL BufferPool_ShiftAvailable(wBufferPool* pool, int index, int count) +static BOOL BufferPool_ShiftAvailable(wBufferPool* pool, int index, int count) { if (count > 0) { @@ -61,7 +61,7 @@ BOOL BufferPool_ShiftAvailable(wBufferPool* pool, int index, int count) return TRUE; } -BOOL BufferPool_ShiftUsed(wBufferPool* pool, int index, int count) +static BOOL BufferPool_ShiftUsed(wBufferPool* pool, int index, int count) { if (count > 0) { diff --git a/winpr/libwinpr/utils/collections/LinkedList.c b/winpr/libwinpr/utils/collections/LinkedList.c index 5cac91bed..adb2af42f 100644 --- a/winpr/libwinpr/utils/collections/LinkedList.c +++ b/winpr/libwinpr/utils/collections/LinkedList.c @@ -124,11 +124,13 @@ void LinkedList_Clear(wLinkedList* list) * Adds a new node containing the specified value at the start of the LinkedList. */ -void LinkedList_AddFirst(wLinkedList* list, void* value) +BOOL LinkedList_AddFirst(wLinkedList* list, void* value) { wLinkedListNode* node; node = (wLinkedListNode*) malloc(sizeof(wLinkedListNode)); + if (!node) + return FALSE; node->prev = node->next = NULL; node->value = value; @@ -144,17 +146,20 @@ void LinkedList_AddFirst(wLinkedList* list, void* value) } list->count++; + return TRUE; } /** * Adds a new node containing the specified value at the end of the LinkedList. */ -void LinkedList_AddLast(wLinkedList* list, void* value) +BOOL LinkedList_AddLast(wLinkedList* list, void* value) { wLinkedListNode* node; node = (wLinkedListNode*) malloc(sizeof(wLinkedListNode)); + if (!node) + return FALSE; node->prev = node->next = NULL; node->value = value; @@ -170,13 +175,14 @@ void LinkedList_AddLast(wLinkedList* list, void* value) } list->count++; + return TRUE; } /** * Removes the first occurrence of the specified value from the LinkedList. */ -void LinkedList_Remove(wLinkedList* list, void* value) +BOOL LinkedList_Remove(wLinkedList* list, void* value) { wLinkedListNode* node; @@ -201,12 +207,12 @@ void LinkedList_Remove(wLinkedList* list, void* value) free(node); list->count--; - - break; + return TRUE; } node = node->next; } + return FALSE; } /** diff --git a/winpr/libwinpr/utils/corkscrew/backtrace.h b/winpr/libwinpr/utils/corkscrew/backtrace.h new file mode 100644 index 000000000..a24ac21aa --- /dev/null +++ b/winpr/libwinpr/utils/corkscrew/backtrace.h @@ -0,0 +1,118 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* A stack unwinder. */ + +#ifndef _CORKSCREW_BACKTRACE_H +#define _CORKSCREW_BACKTRACE_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include +#include + + /* + * Describes a single frame of a backtrace. + */ + typedef struct + { + uintptr_t absolute_pc; /* absolute PC offset */ + uintptr_t stack_top; /* top of stack for this frame */ + size_t stack_size; /* size of this stack frame */ + } backtrace_frame_t; + + /* + * Describes the symbols associated with a backtrace frame. + */ + typedef struct + { + uintptr_t relative_pc; /* relative frame PC offset from the start of the library, + or the absolute PC if the library is unknown */ + uintptr_t relative_symbol_addr; /* relative offset of the symbol from the start of the + library or 0 if the library is unknown */ + char *map_name; /* executable or library name, or NULL if unknown */ + char *symbol_name; /* symbol name, or NULL if unknown */ + char *demangled_name; /* demangled symbol name, or NULL if unknown */ + } backtrace_symbol_t; + + /* + * Unwinds the call stack for the current thread of execution. + * Populates the backtrace array with the program counters from the call stack. + * Returns the number of frames collected, or -1 if an error occurred. + */ + ssize_t unwind_backtrace(backtrace_frame_t *backtrace, size_t ignore_depth, size_t max_depth); + + /* + * Unwinds the call stack for a thread within this process. + * Populates the backtrace array with the program counters from the call stack. + * Returns the number of frames collected, or -1 if an error occurred. + * + * The task is briefly suspended while the backtrace is being collected. + */ + ssize_t unwind_backtrace_thread(pid_t tid, backtrace_frame_t *backtrace, + size_t ignore_depth, size_t max_depth); + + /* + * Unwinds the call stack of a task within a remote process using ptrace(). + * Populates the backtrace array with the program counters from the call stack. + * Returns the number of frames collected, or -1 if an error occurred. + */ + ssize_t unwind_backtrace_ptrace(pid_t tid, const ptrace_context_t *context, + backtrace_frame_t *backtrace, size_t ignore_depth, size_t max_depth); + + /* + * Gets the symbols for each frame of a backtrace. + * The symbols array must be big enough to hold one symbol record per frame. + * The symbols must later be freed using free_backtrace_symbols. + */ + void get_backtrace_symbols(const backtrace_frame_t *backtrace, size_t frames, + backtrace_symbol_t *backtrace_symbols); + + /* + * Gets the symbols for each frame of a backtrace from a remote process. + * The symbols array must be big enough to hold one symbol record per frame. + * The symbols must later be freed using free_backtrace_symbols. + */ + void get_backtrace_symbols_ptrace(const ptrace_context_t *context, + const backtrace_frame_t *backtrace, size_t frames, + backtrace_symbol_t *backtrace_symbols); + + /* + * Frees the storage associated with backtrace symbols. + */ + void free_backtrace_symbols(backtrace_symbol_t *backtrace_symbols, size_t frames); + + enum + { + // A hint for how big to make the line buffer for format_backtrace_line + MAX_BACKTRACE_LINE_LENGTH = 800, + }; + + /** + * Formats a line from a backtrace as a zero-terminated string into the specified buffer. + */ + void format_backtrace_line(unsigned frameNumber, const backtrace_frame_t *frame, + const backtrace_symbol_t *symbol, char *buffer, size_t bufferSize); + +#ifdef __cplusplus +} +#endif + +#endif // _CORKSCREW_BACKTRACE_H diff --git a/winpr/libwinpr/utils/corkscrew/demangle.h b/winpr/libwinpr/utils/corkscrew/demangle.h new file mode 100644 index 000000000..04b022554 --- /dev/null +++ b/winpr/libwinpr/utils/corkscrew/demangle.h @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* C++ symbol name demangling. */ + +#ifndef _CORKSCREW_DEMANGLE_H +#define _CORKSCREW_DEMANGLE_H + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Demangles a C++ symbol name. + * If name is NULL or if the name cannot be demangled, returns NULL. + * Otherwise, returns a newly allocated string that contains the demangled name. + * + * The caller must free the returned string using free(). + */ +char* demangle_symbol_name(const char* name); + +#ifdef __cplusplus +} +#endif + +#endif // _CORKSCREW_DEMANGLE_H diff --git a/winpr/libwinpr/utils/corkscrew/map_info.h b/winpr/libwinpr/utils/corkscrew/map_info.h new file mode 100644 index 000000000..14bfad67d --- /dev/null +++ b/winpr/libwinpr/utils/corkscrew/map_info.h @@ -0,0 +1,74 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* Process memory map. */ + +#ifndef _CORKSCREW_MAP_INFO_H +#define _CORKSCREW_MAP_INFO_H + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct map_info { + struct map_info* next; + uintptr_t start; + uintptr_t end; + bool is_readable; + bool is_writable; + bool is_executable; + void* data; // arbitrary data associated with the map by the user, initially NULL + char name[]; +} map_info_t; + +/* Loads memory map from /proc//maps. */ +map_info_t* load_map_info_list(pid_t tid); + +/* Frees memory map. */ +void free_map_info_list(map_info_t* milist); + +/* Finds the memory map that contains the specified address. */ +const map_info_t* find_map_info(const map_info_t* milist, uintptr_t addr); + +/* Returns true if the addr is in a readable map. */ +bool is_readable_map(const map_info_t* milist, uintptr_t addr); +/* Returns true if the addr is in a writable map. */ +bool is_writable_map(const map_info_t* milist, uintptr_t addr); +/* Returns true if the addr is in an executable map. */ +bool is_executable_map(const map_info_t* milist, uintptr_t addr); + +/* Acquires a reference to the memory map for this process. + * The result is cached and refreshed automatically. + * Make sure to release the map info when done. */ +map_info_t* acquire_my_map_info_list(); + +/* Releases a reference to the map info for this process that was + * previous acquired using acquire_my_map_info_list(). */ +void release_my_map_info_list(map_info_t* milist); + +/* Flushes the cached memory map so the next call to + * acquire_my_map_info_list() gets fresh data. */ +void flush_my_map_info_list(); + +#ifdef __cplusplus +} +#endif + +#endif // _CORKSCREW_MAP_INFO_H diff --git a/winpr/libwinpr/utils/corkscrew/ptrace.h b/winpr/libwinpr/utils/corkscrew/ptrace.h new file mode 100644 index 000000000..76276d89a --- /dev/null +++ b/winpr/libwinpr/utils/corkscrew/ptrace.h @@ -0,0 +1,134 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* Useful ptrace() utility functions. */ + +#ifndef _CORKSCREW_PTRACE_H +#define _CORKSCREW_PTRACE_H + +#include +#include + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* Stores information about a process that is used for several different + * ptrace() based operations. */ +typedef struct { + map_info_t* map_info_list; +} ptrace_context_t; + +/* Describes how to access memory from a process. */ +typedef struct { + pid_t tid; + const map_info_t* map_info_list; +} memory_t; + +#if __i386__ +/* ptrace() register context. */ +typedef struct pt_regs_x86 { + uint32_t ebx; + uint32_t ecx; + uint32_t edx; + uint32_t esi; + uint32_t edi; + uint32_t ebp; + uint32_t eax; + uint32_t xds; + uint32_t xes; + uint32_t xfs; + uint32_t xgs; + uint32_t orig_eax; + uint32_t eip; + uint32_t xcs; + uint32_t eflags; + uint32_t esp; + uint32_t xss; +} pt_regs_x86_t; +#endif + +#if __mips__ +/* ptrace() GET_REGS context. */ +typedef struct pt_regs_mips { + uint64_t regs[32]; + uint64_t lo; + uint64_t hi; + uint64_t cp0_epc; + uint64_t cp0_badvaddr; + uint64_t cp0_status; + uint64_t cp0_cause; +} pt_regs_mips_t; +#endif + +/* + * Initializes a memory structure for accessing memory from this process. + */ +void init_memory(memory_t* memory, const map_info_t* map_info_list); + +/* + * Initializes a memory structure for accessing memory from another process + * using ptrace(). + */ +void init_memory_ptrace(memory_t* memory, pid_t tid); + +/* + * Reads a word of memory safely. + * If the memory is local, ensures that the address is readable before dereferencing it. + * Returns false and a value of 0xffffffff if the word could not be read. + */ +bool try_get_word(const memory_t* memory, uintptr_t ptr, uint32_t* out_value); + +/* + * Reads a word of memory safely using ptrace(). + * Returns false and a value of 0xffffffff if the word could not be read. + */ +bool try_get_word_ptrace(pid_t tid, uintptr_t ptr, uint32_t* out_value); + +/* + * Loads information needed for examining a remote process using ptrace(). + * The caller must already have successfully attached to the process + * using ptrace(). + * + * The context can be used for any threads belonging to that process + * assuming ptrace() is attached to them before performing the actual + * unwinding. The context can continue to be used to decode backtraces + * even after ptrace() has been detached from the process. + */ +ptrace_context_t* load_ptrace_context(pid_t pid); + +/* + * Frees a ptrace context. + */ +void free_ptrace_context(ptrace_context_t* context); + +/* + * Finds a symbol using ptrace. + * Returns the containing map and information about the symbol, or + * NULL if one or the other is not available. + */ +void find_symbol_ptrace(const ptrace_context_t* context, + uintptr_t addr, const map_info_t** out_map_info, const symbol_t** out_symbol); + +#ifdef __cplusplus +} +#endif + +#endif // _CORKSCREW_PTRACE_H diff --git a/winpr/libwinpr/utils/corkscrew/symbol_table.h b/winpr/libwinpr/utils/corkscrew/symbol_table.h new file mode 100644 index 000000000..4998750bf --- /dev/null +++ b/winpr/libwinpr/utils/corkscrew/symbol_table.h @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _CORKSCREW_SYMBOL_TABLE_H +#define _CORKSCREW_SYMBOL_TABLE_H + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + uintptr_t start; + uintptr_t end; + char* name; +} symbol_t; + +typedef struct { + symbol_t* symbols; + size_t num_symbols; +} symbol_table_t; + +/* + * Loads a symbol table from a given file. + * Returns NULL on error. + */ +symbol_table_t* load_symbol_table(const char* filename); + +/* + * Frees a symbol table. + */ +void free_symbol_table(symbol_table_t* table); + +/* + * Finds a symbol associated with an address in the symbol table. + * Returns NULL if not found. + */ +const symbol_t* find_symbol(const symbol_table_t* table, uintptr_t addr); + +#ifdef __cplusplus +} +#endif + +#endif // _CORKSCREW_SYMBOL_TABLE_H diff --git a/winpr/libwinpr/utils/debug.c b/winpr/libwinpr/utils/debug.c new file mode 100644 index 000000000..d76f1ac8a --- /dev/null +++ b/winpr/libwinpr/utils/debug.c @@ -0,0 +1,340 @@ +/** + * WinPR: Windows Portable Runtime + * Debugging Utils + * + * Copyright 2014 Armin Novak + * Copyright 2014 Thincast Technologies GmbH + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#if defined(HAVE_EXECINFO_H) +#include +#endif + +#if defined(ANDROID) +#include +#endif + +#include +#include +#include + +#define TAG "com.winpr.utils.debug" +#define LOGT(...) do { WLog_Print(WLog_Get(TAG), WLOG_TRACE, __VA_ARGS__); } while(0) +#define LOGD(...) do { WLog_Print(WLog_Get(TAG), WLOG_DEBUG, __VA_ARGS__); } while(0) +#define LOGI(...) do { WLog_Print(WLog_Get(TAG), WLOG_INFO, __VA_ARGS__); } while(0) +#define LOGW(...) do { WLog_Print(WLog_Get(TAG), WLOG_WARN, __VA_ARGS__); } while(0) +#define LOGE(...) do { WLog_Print(WLog_Get(TAG), WLOG_ERROR, __VA_ARGS__); } while(0) +#define LOGF(...) do { WLog_Print(WLog_Get(TAG), WLOG_FATAL, __VA_ARGS__); } while(0) + +static const char *support_msg = "Invalid stacktrace buffer! check if platform is supported!"; + +#if defined(HAVE_EXECINFO_H) +typedef struct +{ + void **buffer; + size_t max; + size_t used; +} t_execinfo; +#endif + +#if defined(ANDROID) +#include +#include +#include + +typedef struct +{ + backtrace_frame_t *buffer; + size_t max; + size_t used; +} t_corkscrew_data; + +typedef struct +{ + void *hdl; + ssize_t (*unwind_backtrace)(backtrace_frame_t *backtrace, size_t ignore_depth, size_t max_depth); + ssize_t (*unwind_backtrace_thread)(pid_t tid, backtrace_frame_t *backtrace, + size_t ignore_depth, size_t max_depth); + ssize_t (*unwind_backtrace_ptrace)(pid_t tid, const ptrace_context_t *context, + backtrace_frame_t *backtrace, size_t ignore_depth, size_t max_depth); + void (*get_backtrace_symbols)(const backtrace_frame_t *backtrace, size_t frames, + backtrace_symbol_t *backtrace_symbols); + void (*get_backtrace_symbols_ptrace)(const ptrace_context_t *context, + const backtrace_frame_t *backtrace, size_t frames, + backtrace_symbol_t *backtrace_symbols); + void (*free_backtrace_symbols)(backtrace_symbol_t *backtrace_symbols, size_t frames); + void (*format_backtrace_line)(unsigned frameNumber, const backtrace_frame_t *frame, + const backtrace_symbol_t *symbol, char *buffer, size_t bufferSize); +} t_corkscrew; + +static pthread_once_t initialized = PTHREAD_ONCE_INIT; +static t_corkscrew *fkt = NULL; + +void load_library(void) +{ + static t_corkscrew lib; + { + lib.hdl = dlopen("libcorkscrew.so", RTLD_LAZY); + + if (!lib.hdl) + { + LOGF("dlopen error %s", dlerror()); + goto fail; + } + + lib.unwind_backtrace = dlsym(lib.hdl, "unwind_backtrace"); + + if (!lib.unwind_backtrace) + { + LOGF("dlsym error %s", dlerror()); + goto fail; + } + + lib.unwind_backtrace_thread = dlsym(lib.hdl, "unwind_backtrace_thread"); + + if (!lib.unwind_backtrace_thread) + { + LOGF("dlsym error %s", dlerror()); + goto fail; + } + + lib.unwind_backtrace_ptrace = dlsym(lib.hdl, "unwind_backtrace_ptrace"); + + if (!lib.unwind_backtrace_ptrace) + { + LOGF("dlsym error %s", dlerror()); + goto fail; + } + + lib.get_backtrace_symbols = dlsym(lib.hdl, "get_backtrace_symbols"); + + if (!lib.get_backtrace_symbols) + { + LOGF("dlsym error %s", dlerror()); + goto fail; + } + + lib.get_backtrace_symbols_ptrace = dlsym(lib.hdl, "get_backtrace_symbols_ptrace"); + + if (!lib.get_backtrace_symbols_ptrace) + { + LOGF("dlsym error %s", dlerror()); + goto fail; + } + + lib.free_backtrace_symbols = dlsym(lib.hdl, "free_backtrace_symbols"); + + if (!lib.free_backtrace_symbols) + { + LOGF("dlsym error %s", dlerror()); + goto fail; + } + + lib.format_backtrace_line = dlsym(lib.hdl, "format_backtrace_line"); + + if (!lib.format_backtrace_line) + { + LOGF("dlsym error %s", dlerror()); + goto fail; + } + + fkt = &lib; + return; + } +fail: + { + if (lib.hdl) + dlclose(lib.hdl); + + fkt = NULL; + } +} +#endif + +void winpr_backtrace_free(void *buffer) +{ + if (!buffer) + { + LOGF(support_msg); + return; + } + +#if defined(HAVE_EXECINFO_H) + t_execinfo *data = (t_execinfo *)buffer; + + if (data->buffer) + free(data->buffer); + + free(data); +#elif defined(ANDROID) + t_corkscrew_data *data = (t_corkscrew_data *)buffer; + + if (data->buffer) + free(data->buffer); + + free(data); +#else + LOGF(support_msg); +#endif +} + +void *winpr_backtrace(DWORD size) +{ +#if defined(HAVE_EXECINFO_H) + t_execinfo *data = calloc(1, sizeof(t_execinfo)); + + if (!data) + return NULL; + + data->buffer = calloc(size, sizeof(void *)); + + if (!data->buffer) + return NULL; + + data->max = size; + data->used = backtrace(data->buffer, size); + return data; +#elif defined(ANDROID) + t_corkscrew_data *data = calloc(1, sizeof(t_corkscrew_data)); + + if (!data) + return NULL; + + data->buffer = calloc(size, sizeof(backtrace_frame_t)); + + if (!data->buffer) + { + free(data); + return NULL; + } + + pthread_once(&initialized, load_library); + data->max = size; + data->used = fkt->unwind_backtrace(data->buffer, 0, size); + return data; +#else + LOGF(support_msg); + return NULL; +#endif +} + +char **winpr_backtrace_symbols(void *buffer, size_t *used) +{ + if (used) + *used = 0; + + if (!buffer) + { + LOGF(support_msg); + return NULL; + } + +#if defined(HAVE_EXECINFO_H) + t_execinfo *data = (t_execinfo *)buffer; + assert(data); + + if (used) + *used = data->used; + + return backtrace_symbols(data->buffer, data->used); +#elif defined(ANDROID) + t_corkscrew_data *data = (t_corkscrew_data *)buffer; + assert(data); + pthread_once(&initialized, load_library); + + if (!fkt) + { + LOGF(support_msg); + return NULL; + } + else + { + size_t line_len = (data->max > 1024) ? data->max : 1024; + size_t i; + char *lines = calloc(data->used + 1, sizeof(char *) * line_len); + char **vlines = (char **)lines; + backtrace_symbol_t *symbols = calloc(data->used, sizeof(backtrace_symbol_t));; + + if (!lines || !symbols) + { + if (lines) + free(lines); + + if (symbols) + free(symbols); + + return NULL; + } + + /* To allow a char** malloced array to be returned, allocate n+1 lines + * and fill in the first lines[i] char with the address of lines[(i+1) * 1024] */ + for (i=0; iused; i++) + vlines[i] = &lines[(i + 1) * line_len]; + + fkt->get_backtrace_symbols(data->buffer, data->used, symbols); + + for (i=0; iused; i++) + fkt->format_backtrace_line(i, &data->buffer[i], &symbols[i], vlines[i], line_len); + + fkt->free_backtrace_symbols(symbols, data->used); + + if (used) + *used = data->used; + + return (char **)lines; + } + +#else + LOGF(support_msg); + return NULL; +#endif +} + +void winpr_backtrace_symbols_fd(void *buffer, int fd) +{ + if (!buffer) + { + LOGF(support_msg); + return; + } + +#if defined(HAVE_EXECINFO_H) + t_execinfo *data = (t_execinfo *)buffer; + assert(data); + backtrace_symbols_fd(data->buffer, data->used, fd); +#elif defined(ANDROID) + size_t used; + t_corkscrew_data *data = (t_corkscrew_data *)buffer; + assert(data); + char **lines = winpr_backtrace_symbols(buffer, &used); + + if (lines) + { + DWORD i; + + for (i=0; i + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include + +/** + * Refer to "Compressed Image File Formats: JPEG, PNG, GIF, XBM, BMP" book + */ + +#if defined(__APPLE__) +#pragma pack(1) +#else +#pragma pack(push, 1) +#endif + +struct _WINPR_BITMAP_FILE_HEADER +{ + BYTE bfType[2]; + UINT32 bfSize; + UINT16 bfReserved1; + UINT16 bfReserved2; + UINT32 bfOffBits; +}; +typedef struct _WINPR_BITMAP_FILE_HEADER WINPR_BITMAP_FILE_HEADER; + +struct _WINPR_BITMAP_INFO_HEADER +{ + UINT32 biSize; + INT32 biWidth; + INT32 biHeight; + UINT16 biPlanes; + UINT16 biBitCount; + UINT32 biCompression; + UINT32 biSizeImage; + INT32 biXPelsPerMeter; + INT32 biYPelsPerMeter; + UINT32 biClrUsed; + UINT32 biClrImportant; +}; +typedef struct _WINPR_BITMAP_INFO_HEADER WINPR_BITMAP_INFO_HEADER; + +struct _WINPR_BITMAP_CORE_HEADER +{ + UINT32 bcSize; + UINT16 bcWidth; + UINT16 bcHeight; + UINT16 bcPlanes; + UINT16 bcBitCount; +}; +typedef struct _WINPR_BITMAP_CORE_HEADER WINPR_BITMAP_CORE_HEADER; + +#if defined(__APPLE__) +#pragma pack() +#else +#pragma pack(pop) +#endif + +int winpr_bitmap_write(const char* filename, BYTE* data, int width, int height, int bpp) +{ + FILE* fp; + WINPR_BITMAP_FILE_HEADER bf; + WINPR_BITMAP_INFO_HEADER bi; + + fp = fopen(filename, "w+b"); + + if (!fp) + { + fprintf(stderr, "failed to open file %s\n", filename); + return -1; + } + + bf.bfType[0] = 'B'; + bf.bfType[1] = 'M'; + bf.bfReserved1 = 0; + bf.bfReserved2 = 0; + bf.bfOffBits = sizeof(WINPR_BITMAP_FILE_HEADER) + sizeof(WINPR_BITMAP_INFO_HEADER); + bi.biSizeImage = width * height * (bpp / 8); + bf.bfSize = bf.bfOffBits + bi.biSizeImage; + + bi.biWidth = width; + bi.biHeight = -1 * height; + bi.biPlanes = 1; + bi.biBitCount = bpp; + bi.biCompression = 0; + bi.biXPelsPerMeter = width; + bi.biYPelsPerMeter = height; + bi.biClrUsed = 0; + bi.biClrImportant = 0; + bi.biSize = sizeof(WINPR_BITMAP_INFO_HEADER); + + fwrite((void*) &bf, sizeof(WINPR_BITMAP_FILE_HEADER), 1, fp); + fwrite((void*) &bi, sizeof(WINPR_BITMAP_INFO_HEADER), 1, fp); + fwrite((void*) data, bi.biSizeImage, 1, fp); + + fclose(fp); + + return 1; +} + +int winpr_image_write(wImage* image, const char* filename) +{ + return winpr_bitmap_write(filename, image->data, image->width, image->height, image->bitsPerPixel); +} + +int winpr_image_read(wImage* image, const char* filename) +{ + FILE* fp; + int index; + BOOL vFlip; + BYTE* pDstData; + WINPR_BITMAP_FILE_HEADER bf; + WINPR_BITMAP_INFO_HEADER bi; + + fp = fopen(filename, "r+b"); + + if (!fp) + { + fprintf(stderr, "failed to open file %s\n", filename); + return -1; + } + + fread((void*) &bf, sizeof(WINPR_BITMAP_FILE_HEADER), 1, fp); + + if ((bf.bfType[0] != 'B') || (bf.bfType[1] != 'M')) + return -1; + + fread((void*) &bi, sizeof(WINPR_BITMAP_INFO_HEADER), 1, fp); + + if (ftell(fp) != bf.bfOffBits) + { + fseek(fp, bf.bfOffBits, SEEK_SET); + } + + image->width = bi.biWidth; + + if (bi.biHeight < 0) + { + vFlip = FALSE; + image->height = -1 * bi.biHeight; + } + else + { + vFlip = TRUE; + image->height = bi.biHeight; + } + + image->bitsPerPixel = bi.biBitCount; + image->bytesPerPixel = (image->bitsPerPixel / 8); + image->scanline = (bi.biSizeImage / bi.biHeight); + + image->data = (BYTE*) malloc(bi.biSizeImage); + + if (!image->data) + return -1; + + if (!vFlip) + { + fread((void*) image->data, bi.biSizeImage, 1, fp); + } + else + { + pDstData = &(image->data[(image->height - 1) * image->scanline]); + + for (index = 0; index < image->height; index++) + { + fread((void*) pDstData, image->scanline, 1, fp); + pDstData -= image->scanline; + } + } + + fclose(fp); + + return 1; +} + +wImage* winpr_image_new() +{ + wImage* image; + + image = (wImage*) calloc(1, sizeof(wImage)); + + if (!image) + return NULL; + + return image; +} + +void winpr_image_free(wImage* image, BOOL bFreeBuffer) +{ + if (!image) + return; + + if (bFreeBuffer) + free(image->data); + + free(image); +} diff --git a/winpr/libwinpr/utils/sam.c b/winpr/libwinpr/utils/sam.c index 8c3b91764..cf28fa243 100644 --- a/winpr/libwinpr/utils/sam.c +++ b/winpr/libwinpr/utils/sam.c @@ -68,7 +68,7 @@ WINPR_SAM* SamOpen(BOOL read_only) return sam; } -BOOL SamLookupStart(WINPR_SAM* sam) +static BOOL SamLookupStart(WINPR_SAM* sam) { size_t read_size; long int file_size; @@ -105,7 +105,7 @@ BOOL SamLookupStart(WINPR_SAM* sam) return TRUE; } -void SamLookupFinish(WINPR_SAM* sam) +static void SamLookupFinish(WINPR_SAM* sam) { free(sam->buffer); @@ -113,7 +113,7 @@ void SamLookupFinish(WINPR_SAM* sam) sam->line = NULL; } -void HexStrToBin(char* str, BYTE* bin, int length) +static void HexStrToBin(char* str, BYTE* bin, int length) { int i; diff --git a/winpr/libwinpr/utils/ssl.c b/winpr/libwinpr/utils/ssl.c index 2a0463977..add22b12b 100644 --- a/winpr/libwinpr/utils/ssl.c +++ b/winpr/libwinpr/utils/ssl.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include @@ -36,7 +37,7 @@ struct CRYPTO_dynlock_value #if (OPENSSL_VERSION_NUMBER < 0x10000000L) -static unsigned long _winpr_openssl_id() +static unsigned long _winpr_openssl_id(void) { return (unsigned long)GetCurrentThreadId(); } @@ -84,7 +85,7 @@ static void _winpr_openssl_dynlock_destroy(struct CRYPTO_dynlock_value *dynlock, free(dynlock); } -static BOOL _winpr_openssl_initialize_locking() +static BOOL _winpr_openssl_initialize_locking(void) { int i, count; @@ -159,7 +160,7 @@ static BOOL _winpr_openssl_initialize_locking() return TRUE; } -static BOOL _winpr_openssl_cleanup_locking() +static BOOL _winpr_openssl_cleanup_locking(void) { /* undo our static locking modifications */ @@ -219,7 +220,7 @@ static BOOL CALLBACK _winpr_openssl_initialize(PINIT_ONCE once, PVOID param, PVO if (flags & WINPR_SSL_INIT_ENABLE_LOCKING) { - if (!_winpr_openssl_initialize_locking(FALSE)) + if (!_winpr_openssl_initialize_locking()) { return FALSE; } diff --git a/winpr/libwinpr/utils/trio/trio.c b/winpr/libwinpr/utils/trio/trio.c index 08b02240a..19cfdadd0 100644 --- a/winpr/libwinpr/utils/trio/trio.c +++ b/winpr/libwinpr/utils/trio/trio.c @@ -901,8 +901,8 @@ typedef struct _trio_userdef_t { * Internal Variables * *************************************************************************/ - -static TRIO_CONST char rcsid[] = "@(#)$Id: trio.c,v 1.131 2010/09/12 11:08:08 breese Exp $"; +/* Unused but kept for reference */ +/* static TRIO_CONST char rcsid[] = "@(#)$Id: trio.c,v 1.131 2010/09/12 11:08:08 breese Exp $"; */ #if TRIO_FEATURE_FLOAT /* diff --git a/winpr/libwinpr/utils/trio/triodef.h b/winpr/libwinpr/utils/trio/triodef.h index 11c14b9c4..ce2667b0a 100644 --- a/winpr/libwinpr/utils/trio/triodef.h +++ b/winpr/libwinpr/utils/trio/triodef.h @@ -168,9 +168,9 @@ #if defined(__cplusplus) # define PREDEF_STANDARD_CXX -#endif -#if __cplusplus - 0 >= 199711L -# define PREDEF_STANDARD_CXX89 +# if __cplusplus - 0 >= 199711L +# define PREDEF_STANDARD_CXX89 +# endif #endif #if defined(TRIO_PLATFORM_UNIX) diff --git a/winpr/libwinpr/utils/trio/trionan.c b/winpr/libwinpr/utils/trio/trionan.c index 301632257..d58246881 100644 --- a/winpr/libwinpr/utils/trio/trionan.c +++ b/winpr/libwinpr/utils/trio/trionan.c @@ -227,7 +227,8 @@ */ #if !defined(TRIO_EMBED_NAN) -static TRIO_CONST char rcsid[] = "@(#)$Id: trionan.c,v 1.33 2005/05/29 11:57:25 breese Exp $"; +/* Unused but kept for reference */ +/* static TRIO_CONST char rcsid[] = "@(#)$Id: trionan.c,v 1.33 2005/05/29 11:57:25 breese Exp $"; */ #endif #if defined(TRIO_FUNC_INTERNAL_MAKE_DOUBLE) \ diff --git a/winpr/libwinpr/utils/trio/triostr.c b/winpr/libwinpr/utils/trio/triostr.c index c471b4a1d..4425bcd21 100644 --- a/winpr/libwinpr/utils/trio/triostr.c +++ b/winpr/libwinpr/utils/trio/triostr.c @@ -160,7 +160,8 @@ struct _trio_string_t */ #if !defined(TRIO_EMBED_STRING) -static TRIO_CONST char rcsid[] = "@(#)$Id: triostr.c,v 1.36 2010/01/26 13:02:02 breese Exp $"; +/* Unused but kept for reference */ +/* static TRIO_CONST char rcsid[] = "@(#)$Id: triostr.c,v 1.36 2010/01/26 13:02:02 breese Exp $"; */ #endif /************************************************************************* diff --git a/winpr/libwinpr/utils/wlog/BinaryAppender.c b/winpr/libwinpr/utils/wlog/BinaryAppender.c index f0bd1ba5f..79395d506 100644 --- a/winpr/libwinpr/utils/wlog/BinaryAppender.c +++ b/winpr/libwinpr/utils/wlog/BinaryAppender.c @@ -21,6 +21,8 @@ #include "config.h" #endif +#include + #include #include #include @@ -71,6 +73,9 @@ int WLog_BinaryAppender_Open(wLog* log, wLogBinaryAppender* appender) ProcessId = GetCurrentProcessId(); + if (!log || !appender) + return -1; + if (!appender->FilePath) { appender->FilePath = GetKnownSubPath(KNOWN_PATH_TEMP, "wlog"); @@ -122,6 +127,9 @@ int WLog_BinaryAppender_WriteMessage(wLog* log, wLogBinaryAppender* appender, wL int FunctionNameLength; int TextStringLength; + if (!log || !appender || !message) + return -1; + fp = appender->FileDescriptor; if (!fp) diff --git a/winpr/libwinpr/utils/wlog/ConsoleAppender.c b/winpr/libwinpr/utils/wlog/ConsoleAppender.c index b7f4a985e..0383a823f 100644 --- a/winpr/libwinpr/utils/wlog/ConsoleAppender.c +++ b/winpr/libwinpr/utils/wlog/ConsoleAppender.c @@ -30,6 +30,10 @@ #include "wlog/ConsoleAppender.h" +#ifdef ANDROID +#include +#endif + /** * Console Appender */ @@ -84,11 +88,45 @@ int WLog_ConsoleAppender_WriteMessage(wLog* log, wLogConsoleAppender* appender, return 1; } #endif +#ifdef ANDROID + (void)fp; + android_LogPriority level; + switch(message->Level) + { + case WLOG_TRACE: + level = ANDROID_LOG_VERBOSE; + break; + case WLOG_DEBUG: + level = ANDROID_LOG_DEBUG; + break; + case WLOG_INFO: + level = ANDROID_LOG_INFO; + break; + case WLOG_WARN: + level = ANDROID_LOG_WARN; + break; + case WLOG_ERROR: + level = ANDROID_LOG_ERROR; + break; + case WLOG_FATAL: + level = ANDROID_LOG_FATAL; + break; + case WLOG_OFF: + level = ANDROID_LOG_SILENT; + break; + default: + level = ANDROID_LOG_FATAL; + break; + } + if (level != ANDROID_LOG_SILENT) + __android_log_print(level, log->Name, "%s%s", message->PrefixString, message->TextString); + +#else fp = (appender->outputStream == WLOG_CONSOLE_STDERR) ? stderr : stdout; fprintf(fp, "%s%s\n", message->PrefixString, message->TextString); - +#endif return 1; } @@ -143,8 +181,9 @@ int WLog_ConsoleAppender_WritePacketMessage(wLog* log, wLogConsoleAppender* appe free(FullFileName); } - WLog_PacketMessage_Write((wPcap*) appender->PacketMessageContext, - message->PacketData, message->PacketLength, message->PacketFlags); + if (appender->PacketMessageContext) + WLog_PacketMessage_Write((wPcap*) appender->PacketMessageContext, + message->PacketData, message->PacketLength, message->PacketFlags); return PacketId; } diff --git a/winpr/libwinpr/utils/wlog/FileAppender.c b/winpr/libwinpr/utils/wlog/FileAppender.c index 4e1feb006..90ce6cb56 100644 --- a/winpr/libwinpr/utils/wlog/FileAppender.c +++ b/winpr/libwinpr/utils/wlog/FileAppender.c @@ -70,6 +70,9 @@ int WLog_FileAppender_Open(wLog* log, wLogFileAppender* appender) ProcessId = GetCurrentProcessId(); + if (!log || !appender) + return -1; + if (!appender->FilePath) { appender->FilePath = GetKnownSubPath(KNOWN_PATH_TEMP, "wlog"); @@ -102,6 +105,9 @@ int WLog_FileAppender_Open(wLog* log, wLogFileAppender* appender) int WLog_FileAppender_Close(wLog* log, wLogFileAppender* appender) { + if (!log || !appender) + return -1; + if (!appender->FileDescriptor) return 0; @@ -117,6 +123,9 @@ int WLog_FileAppender_WriteMessage(wLog* log, wLogFileAppender* appender, wLogMe FILE* fp; char prefix[WLOG_MAX_PREFIX_SIZE]; + if (!log || !appender || !message) + return -1; + fp = appender->FileDescriptor; if (!fp) @@ -139,6 +148,9 @@ int WLog_FileAppender_WriteDataMessage(wLog* log, wLogFileAppender* appender, wL int DataId; char* FullFileName; + if (!log || !appender || !message) + return -1; + DataId = g_DataId++; FullFileName = WLog_Message_GetOutputFileName(DataId, "dat"); @@ -156,6 +168,9 @@ int WLog_FileAppender_WriteImageMessage(wLog* log, wLogFileAppender* appender, w int ImageId; char* FullFileName; + if (!log || !appender || !message) + return -1; + ImageId = g_ImageId++; FullFileName = WLog_Message_GetOutputFileName(ImageId, "bmp"); diff --git a/winpr/libwinpr/utils/wlog/ImageMessage.c b/winpr/libwinpr/utils/wlog/ImageMessage.c index 89af777c5..1866ed1de 100644 --- a/winpr/libwinpr/utils/wlog/ImageMessage.c +++ b/winpr/libwinpr/utils/wlog/ImageMessage.c @@ -23,88 +23,18 @@ #include +#include + #include "wlog/ImageMessage.h" -#include -#include - -typedef struct -{ - BYTE magic[2]; -} BITMAP_MAGIC; - -typedef struct -{ - UINT32 filesz; - UINT16 creator1; - UINT16 creator2; - UINT32 bmp_offset; -} BITMAP_CORE_HEADER; - -typedef struct -{ - UINT32 header_sz; - INT32 width; - INT32 height; - UINT16 nplanes; - UINT16 bitspp; - UINT32 compress_type; - UINT32 bmp_bytesz; - INT32 hres; - INT32 vres; - UINT32 ncolors; - UINT32 nimpcolors; -} BITMAP_INFO_HEADER; - int WLog_ImageMessage_Write(char* filename, void* data, int width, int height, int bpp) { - FILE* fp; - BITMAP_MAGIC magic; - BITMAP_CORE_HEADER header; - BITMAP_INFO_HEADER info_header; + int status; - fp = fopen(filename, "w+b"); + status = winpr_bitmap_write(filename, data, width, height, bpp); - if (!fp) - { - fprintf(stderr, "failed to open file %s\n", filename); + if (status < 0) return -1; - } - magic.magic[0] = 'B'; - magic.magic[1] = 'M'; - - header.creator1 = 0; - header.creator2 = 0; - - header.bmp_offset = - sizeof(BITMAP_MAGIC) + - sizeof(BITMAP_CORE_HEADER) + - sizeof(BITMAP_INFO_HEADER); - - info_header.bmp_bytesz = width * height * (bpp / 8); - - header.filesz = - header.bmp_offset + - info_header.bmp_bytesz; - - info_header.width = width; - info_header.height = (-1) * height; - info_header.nplanes = 1; - info_header.bitspp = bpp; - info_header.compress_type = 0; - info_header.hres = width; - info_header.vres = height; - info_header.ncolors = 0; - info_header.nimpcolors = 0; - info_header.header_sz = sizeof(BITMAP_INFO_HEADER); - - fwrite((void*) &magic, sizeof(BITMAP_MAGIC), 1, fp); - fwrite((void*) &header, sizeof(BITMAP_CORE_HEADER), 1, fp); - fwrite((void*) &info_header, sizeof(BITMAP_INFO_HEADER), 1, fp); - fwrite((void*) data, info_header.bmp_bytesz, 1, fp); - - fclose(fp); - - return 0; + return 1; } diff --git a/winpr/libwinpr/utils/wlog/Layout.c b/winpr/libwinpr/utils/wlog/Layout.c index fc1f6a1d1..43670d0d0 100644 --- a/winpr/libwinpr/utils/wlog/Layout.c +++ b/winpr/libwinpr/utils/wlog/Layout.c @@ -356,7 +356,13 @@ wLogLayout* WLog_Layout_New(wLog* log) if (env) layout->FormatString = env; else + { +#ifdef ANDROID + layout->FormatString = _strdup("[pid=%pid:tid=%tid] - "); +#else layout->FormatString = _strdup("[%hr:%mi:%se:%ml] [%pid:%tid] [%lv][%mn] - "); +#endif + } } return layout; diff --git a/winpr/libwinpr/utils/wlog/PacketMessage.c b/winpr/libwinpr/utils/wlog/PacketMessage.c index ad6472841..9f7e5648e 100644 --- a/winpr/libwinpr/utils/wlog/PacketMessage.c +++ b/winpr/libwinpr/utils/wlog/PacketMessage.c @@ -47,35 +47,43 @@ static int gettimeofday(struct timeval* tp, void* tz) void Pcap_Read_Header(wPcap* pcap, wPcapHeader* header) { - fread((void*) header, sizeof(wPcapHeader), 1, pcap->fp); + if (pcap && pcap->fp) + fread((void*) header, sizeof(wPcapHeader), 1, pcap->fp); } void Pcap_Write_Header(wPcap* pcap, wPcapHeader* header) { - fwrite((void*) header, sizeof(wPcapHeader), 1, pcap->fp); + if (pcap && pcap->fp) + fwrite((void*) header, sizeof(wPcapHeader), 1, pcap->fp); } void Pcap_Read_RecordHeader(wPcap* pcap, wPcapRecordHeader* record) { - fread((void*) record, sizeof(wPcapRecordHeader), 1, pcap->fp); + if (pcap && pcap->fp) + fread((void*) record, sizeof(wPcapRecordHeader), 1, pcap->fp); } void Pcap_Write_RecordHeader(wPcap* pcap, wPcapRecordHeader* record) { - fwrite((void*) record, sizeof(wPcapRecordHeader), 1, pcap->fp); + if (pcap && pcap->fp) + fwrite((void*) record, sizeof(wPcapRecordHeader), 1, pcap->fp); } void Pcap_Write_RecordContent(wPcap* pcap, wPcapRecord* record) { - fwrite(record->data, record->length, 1, pcap->fp); + if (pcap && pcap->fp) + fwrite(record->data, record->length, 1, pcap->fp); } void Pcap_Read_Record(wPcap* pcap, wPcapRecord* record) { - Pcap_Read_RecordHeader(pcap, &record->header); - record->length = record->header.incl_len; - record->data = malloc(record->length); - fread(record->data, record->length, 1, pcap->fp); + if (pcap && pcap->fp) + { + Pcap_Read_RecordHeader(pcap, &record->header); + record->length = record->header.incl_len; + record->data = malloc(record->length); + fread(record->data, record->length, 1, pcap->fp); + } } void Pcap_Write_Record(wPcap* pcap, wPcapRecord* record) @@ -141,8 +149,12 @@ BOOL Pcap_GetNext_RecordHeader(wPcap* pcap, wPcapRecord* record) BOOL Pcap_GetNext_RecordContent(wPcap* pcap, wPcapRecord* record) { - fread(record->data, record->length, 1, pcap->fp); - return TRUE; + if (pcap && pcap->fp) + { + fread(record->data, record->length, 1, pcap->fp); + return TRUE; + } + return FALSE; } BOOL Pcap_GetNext_Record(wPcap* pcap, wPcapRecord* record) @@ -189,7 +201,7 @@ wPcap* Pcap_Open(char* name, BOOL write) pcap->header.network = 1; /* ethernet */ Pcap_Write_Header(pcap, &pcap->header); } - else + else if (pcap->fp) { fseek(pcap->fp, 0, SEEK_END); pcap->file_size = (int) ftell(pcap->fp); @@ -203,22 +215,26 @@ wPcap* Pcap_Open(char* name, BOOL write) void Pcap_Flush(wPcap* pcap) { + if (!pcap || !pcap->fp) + return; + while (pcap->record) { Pcap_Write_Record(pcap, pcap->record); pcap->record = pcap->record->next; } - if (pcap->fp) - fflush(pcap->fp); + fflush(pcap->fp); } void Pcap_Close(wPcap* pcap) { + if (!pcap || !pcap->fp) + return; + Pcap_Flush(pcap); - if (pcap->fp) - fclose(pcap->fp); + fclose(pcap->fp); free(pcap); } @@ -228,6 +244,9 @@ int WLog_PacketMessage_Write_EthernetHeader(wPcap* pcap, wEthernetHeader* ethern wStream* s; BYTE buffer[14]; + if (!pcap || !pcap->fp || !ethernet) + return -1; + s = Stream_New(buffer, 14); Stream_Write(s, ethernet->Destination, 6); @@ -268,6 +287,9 @@ int WLog_PacketMessage_Write_IPv4Header(wPcap* pcap, wIPv4Header* ipv4) wStream* s; BYTE buffer[20]; + if (!pcap || !pcap->fp || !ipv4) + return -1; + s = Stream_New(buffer, 20); Stream_Write_UINT8(s, (ipv4->Version << 4) | ipv4->InternetHeaderLength); @@ -298,6 +320,9 @@ int WLog_PacketMessage_Write_TcpHeader(wPcap* pcap, wTcpHeader* tcp) wStream* s; BYTE buffer[20]; + if (!pcap || !pcap->fp || !tcp) + return -1; + s = Stream_New(buffer, 20); Stream_Write_UINT16_BE(s, tcp->SourcePort); @@ -310,7 +335,8 @@ int WLog_PacketMessage_Write_TcpHeader(wPcap* pcap, wTcpHeader* tcp) Stream_Write_UINT16_BE(s, tcp->Checksum); Stream_Write_UINT16_BE(s, tcp->UrgentPointer); - fwrite(buffer, 20, 1, pcap->fp); + if (pcap->fp) + fwrite(buffer, 20, 1, pcap->fp); Stream_Free(s, FALSE); @@ -330,6 +356,9 @@ int WLog_PacketMessage_Write(wPcap* pcap, void* data, DWORD length, DWORD flags) ethernet.Type = 0x0800; + if (!pcap || !pcap->fp) + return -1; + if (flags & WLOG_PACKET_OUTBOUND) { /* 00:15:5D:01:64:04 */ diff --git a/winpr/libwinpr/wtsapi/wtsapi.c b/winpr/libwinpr/wtsapi/wtsapi.c index 144927cde..c56bff72c 100644 --- a/winpr/libwinpr/wtsapi/wtsapi.c +++ b/winpr/libwinpr/wtsapi/wtsapi.c @@ -549,6 +549,7 @@ DWORD WINAPI WTSGetActiveConsoleSessionId(void) BOOL WTSRegisterWtsApiFunctionTable(PWtsApiFunctionTable table) { g_WtsApi = table; + g_Initialized = TRUE; return TRUE; }