freerdp: merge with master
This commit is contained in:
commit
863b51f938
@ -329,8 +329,9 @@ if(APPLE)
|
||||
set(DIRECTFB_FEATURE_TYPE "DISABLED")
|
||||
set(FFMPEG_FEATURE_TYPE "OPTIONAL")
|
||||
set(GSTREAMER_FEATURE_TYPE "OPTIONAL")
|
||||
set(X11_FEATURE_TYPE "DISABLED")
|
||||
set(X11_FEATURE_TYPE "OPTIONAL")
|
||||
if(IOS)
|
||||
set(X11_FEATURE_TYPE "DISABLED")
|
||||
set(ALSA_FEATURE_TYPE "DISABLED")
|
||||
set(PULSE_FEATURE_TYPE "DISABLED")
|
||||
set(CUPS_FEATURE_TYPE "DISABLED")
|
||||
@ -353,6 +354,11 @@ endif()
|
||||
|
||||
find_feature(X11 ${X11_FEATURE_TYPE} ${X11_FEATURE_PURPOSE} ${X11_FEATURE_DESCRIPTION})
|
||||
find_feature(DirectFB ${DIRECTFB_FEATURE_TYPE} ${DIRECTFB_FEATURE_PURPOSE} ${DIRECTFB_FEATURE_DESCRIPTION})
|
||||
if (${WITH_DIRECTFB})
|
||||
message(WARNING "
|
||||
DIRECTFB is orphaned and not maintained see docs/README.directfb for details
|
||||
")
|
||||
endif()
|
||||
|
||||
find_feature(ZLIB ${ZLIB_FEATURE_TYPE} ${ZLIB_FEATURE_PURPOSE} ${ZLIB_FEATURE_DESCRIPTION})
|
||||
find_feature(OpenSSL ${OPENSSL_FEATURE_TYPE} ${OPENSSL_FEATURE_PURPOSE} ${OPENSSL_FEATURE_DESCRIPTION})
|
||||
|
@ -376,16 +376,13 @@ int dvcman_create_channel(IWTSVirtualChannelManager* pChannelMgr, UINT32 Channel
|
||||
{
|
||||
DEBUG_WARN("channel rejected by plugin");
|
||||
|
||||
channel->status = 1;
|
||||
ArrayList_Add(dvcman->channels, channel);
|
||||
free(channel);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
channel->status = 1;
|
||||
ArrayList_Add(dvcman->channels, channel);
|
||||
|
||||
free(channel);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -40,7 +40,7 @@ set_complex_link_libraries(VARIABLE ${MODULE_PREFIX}_LIBS
|
||||
set_complex_link_libraries(VARIABLE ${MODULE_PREFIX}_LIBS
|
||||
MONOLITHIC ${MONOLITHIC_BUILD}
|
||||
MODULE winpr
|
||||
MODULES winpr-crt winpr-synch winpr-interlocked)
|
||||
MODULES winpr-crt winpr-synch winpr-interlocked winpr-error)
|
||||
|
||||
set(${MODULE_PREFIX}_SRCS ${${MODULE_PREFIX}_SRCS} PARENT_SCOPE)
|
||||
set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} PARENT_SCOPE)
|
||||
|
@ -669,7 +669,6 @@ static BOOL tsmf_gstreamer_set_format(ITSMFDecoder * decoder, TS_AM_MEDIA_TYPE *
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@ -1133,12 +1132,12 @@ static BOOL tsmf_gstreamer_decodeEx(ITSMFDecoder * decoder, const BYTE * data, U
|
||||
|
||||
if (mdecoder->media_type == TSMF_MAJOR_TYPE_VIDEO)
|
||||
{
|
||||
DEBUG_DVC("tsmf_gstreamer_decodeEx_VIDEO. Start:(%llu) End:(%llu) Duration:(%llu) Last End:(%llu)",
|
||||
DEBUG_DVC("tsmf_gstreamer_decodeEx_VIDEO. Start:(%"PRIu64") End:(%"PRIu64") Duration:(%"PRIu64") Last End:(%"PRIu64")",
|
||||
start_time, end_time, duration, mdecoder->last_sample_end_time);
|
||||
}
|
||||
else
|
||||
{
|
||||
DEBUG_DVC("tsmf_gstreamer_decodeEX_AUDIO. Start:(%llu) End:(%llu) Duration:(%llu) Last End:(%llu)",
|
||||
DEBUG_DVC("tsmf_gstreamer_decodeEx_AUDIO. Start:(%"PRIu64") End:(%"PRIu64") Duration:(%"PRIu64") Last End:(%"PRIu64")",
|
||||
start_time, end_time, duration, mdecoder->last_sample_end_time);
|
||||
}
|
||||
|
||||
@ -1176,7 +1175,7 @@ static BOOL tsmf_gstreamer_decodeEx(ITSMFDecoder * decoder, const BYTE * data, U
|
||||
*/
|
||||
if (start_time > (mdecoder->last_sample_end_time + 10000000) || (end_time + 10000000) < mdecoder->last_sample_end_time)
|
||||
{
|
||||
DEBUG_DVC("tsmf_gstreamer_decodeEx: start_time=[%llu] > last_sample_end_time=[%llu]", start_time, mdecoder->last_sample_end_time);
|
||||
DEBUG_DVC("tsmf_gstreamer_decodeEx: start_time=[%"PRIu64"] > last_sample_end_time=[%"PRIu64"]", start_time, mdecoder->last_sample_end_time);
|
||||
DEBUG_DVC("tsmf_gstreamer_decodeEx: Stream seek detected - flushing element.");
|
||||
tsmf_gstreamer_pipeline_set_state(mdecoder, GST_STATE_NULL);
|
||||
gst_object_unref(mdecoder->pipe);
|
||||
@ -1205,7 +1204,7 @@ static BOOL tsmf_gstreamer_decodeEx(ITSMFDecoder * decoder, const BYTE * data, U
|
||||
|
||||
if (fout)
|
||||
{
|
||||
fprintf(fout, "%"PRIu64"\n", (long unsigned int) start_time);
|
||||
fprintf(fout, "%"PRIu64"\n", start_time);
|
||||
fclose(fout);
|
||||
}
|
||||
|
||||
@ -1231,7 +1230,7 @@ static BOOL tsmf_gstreamer_decodeEx(ITSMFDecoder * decoder, const BYTE * data, U
|
||||
if (fin)
|
||||
{
|
||||
UINT64 AStartTime = 0;
|
||||
fscanf(fin, "%"PRIu64, (long unsigned int*) &AStartTime);
|
||||
fscanf(fin, "%"PRIu64, &AStartTime);
|
||||
fclose(fin);
|
||||
if (start_time > AStartTime)
|
||||
{
|
||||
@ -1265,7 +1264,7 @@ static BOOL tsmf_gstreamer_decodeEx(ITSMFDecoder * decoder, const BYTE * data, U
|
||||
if (fin)
|
||||
{
|
||||
UINT64 VStartTime = 0;
|
||||
fscanf(fin, "%"PRIu64, (long unsigned int*) &VStartTime);
|
||||
fscanf(fin, "%"PRIu64, &VStartTime);
|
||||
fclose(fin);
|
||||
if (start_time > VStartTime)
|
||||
{
|
||||
@ -1325,20 +1324,21 @@ static void tsmf_gstreamer_change_volume(ITSMFDecoder * decoder, UINT32 newVolum
|
||||
if (mdecoder->shutdown)
|
||||
return;
|
||||
|
||||
if (!mdecoder->aVolume)
|
||||
if (mdecoder->media_type == TSMF_MAJOR_TYPE_VIDEO)
|
||||
return;
|
||||
|
||||
if (mdecoder->media_type == TSMF_MAJOR_TYPE_VIDEO)
|
||||
mdecoder->gstMuted = (BOOL) muted;
|
||||
DEBUG_DVC("tsmf_gstreamer_change_volume: mute=[%d]", mdecoder->gstMuted);
|
||||
mdecoder->gstVolume = (double) newVolume / (double) 10000;
|
||||
DEBUG_DVC("tsmf_gstreamer_change_volume: gst_new_vol=[%f]", mdecoder->gstVolume);
|
||||
|
||||
if (!mdecoder->aVolume)
|
||||
return;
|
||||
|
||||
if (!G_IS_OBJECT(mdecoder->aVolume))
|
||||
return;
|
||||
|
||||
mdecoder->gstMuted = (BOOL) muted;
|
||||
DEBUG_DVC("tsmf_gstreamer_change_volume: mute=[%d]", mdecoder->gstMuted);
|
||||
g_object_set(mdecoder->aVolume, "mute", mdecoder->gstMuted, NULL);
|
||||
mdecoder->gstVolume = (double) newVolume / (double) 10000;
|
||||
DEBUG_DVC("tsmf_gstreamer_change_volume: gst_new_vol=[%f]", mdecoder->gstVolume);
|
||||
g_object_set(mdecoder->aVolume, "volume", mdecoder->gstVolume, NULL);
|
||||
}
|
||||
|
||||
@ -1482,7 +1482,7 @@ static UINT64 tsmf_gstreamer_get_running_time(ITSMFDecoder * decoder)
|
||||
GstFormat fmt = GST_FORMAT_TIME;
|
||||
gint64 pos = 0;
|
||||
gst_element_query_position (mdecoder->outsink, &fmt, &pos);
|
||||
DEBUG_DVC("tsmf_gstreamer_current_pos=[%llu]", pos);
|
||||
DEBUG_DVC("tsmf_gstreamer_current_pos=[%"PRIu64"]", pos);
|
||||
return pos/100;
|
||||
}
|
||||
|
||||
@ -1524,13 +1524,14 @@ static void tsmf_gstreamer_update_rendering_area(ITSMFDecoder * decoder, int new
|
||||
{
|
||||
if (info->noutput > 0)
|
||||
{
|
||||
if (info->outputs[0] == primary_output)
|
||||
if (info->outputs[0] == primary_output || i == 0)
|
||||
{
|
||||
mdecoder->xOffset = info->x;
|
||||
mdecoder->yOffset = info->y;
|
||||
}
|
||||
DEBUG_DVC("output %d ID: %lu (x,y): (%d,%d) (w,h): (%d,%d) primary: %d", i, info->outputs[0], info->x, info->y, info->width, info->height, (info->outputs[0] == primary_output));
|
||||
}
|
||||
XRRFreeCrtcInfo(info);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1545,7 +1546,12 @@ static void tsmf_gstreamer_update_rendering_area(ITSMFDecoder * decoder, int new
|
||||
if(mdecoder->subwin)
|
||||
{
|
||||
XMoveWindow(mdecoder->disp, mdecoder->subwin, anewX, anewY);
|
||||
if(newWidth > 0 && newHeight > 0) {
|
||||
XResizeWindow(mdecoder->disp, mdecoder->subwin, newWidth, newHeight);
|
||||
} else {
|
||||
XResizeWindow(mdecoder->disp, mdecoder->subwin, 1, 1);
|
||||
}
|
||||
|
||||
XSync(mdecoder->disp, FALSE);
|
||||
XShapeCombineRectangles (mdecoder->disp, mdecoder->subwin, ShapeBounding, 0, 0,(XRectangle*) rectangles, numRectangles, ShapeSet, Unsorted);
|
||||
XSync(mdecoder->disp, FALSE);
|
||||
@ -1599,7 +1605,7 @@ ITSMFDecoder* freerdp_tsmf_client_decoder_subsystem_entry(void)
|
||||
decoder->xOffset = 0;
|
||||
decoder->yOffset = 0;
|
||||
decoder->offsetObtained = FALSE;
|
||||
decoder->gstVolume = 1.0;
|
||||
decoder->gstVolume = 0.5;
|
||||
decoder->gstMuted = FALSE;
|
||||
decoder->state = GST_STATE_VOID_PENDING; /* No real state yet */
|
||||
pthread_mutex_init(&decoder->gst_mutex, NULL);
|
||||
|
@ -127,8 +127,6 @@ int tsmf_ifman_check_format_support_request(TSMF_IFMAN* ifman)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static TSMF_PRESENTATION* pexisted = 0;
|
||||
|
||||
int tsmf_ifman_on_new_presentation(TSMF_IFMAN* ifman)
|
||||
{
|
||||
int status = 0;
|
||||
@ -136,15 +134,16 @@ int tsmf_ifman_on_new_presentation(TSMF_IFMAN* ifman)
|
||||
|
||||
DEBUG_DVC("");
|
||||
|
||||
if (pexisted)
|
||||
presentation = tsmf_presentation_find_by_id(Stream_Pointer(ifman->input));
|
||||
if (presentation)
|
||||
{
|
||||
DEBUG_DVC("Presentation already exists");
|
||||
ifman->output_pending = FALSE;
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
presentation = tsmf_presentation_new(Stream_Pointer(ifman->input), ifman->channel_callback);
|
||||
pexisted = presentation;
|
||||
|
||||
if (presentation == NULL)
|
||||
status = 1;
|
||||
@ -283,8 +282,8 @@ int tsmf_ifman_shutdown_presentation(TSMF_IFMAN* ifman)
|
||||
|
||||
if (presentation)
|
||||
tsmf_presentation_free(presentation);
|
||||
|
||||
pexisted = 0;
|
||||
else
|
||||
DEBUG_WARN("unknown presentation id");
|
||||
|
||||
Stream_EnsureRemainingCapacity(ifman->output, 4);
|
||||
Stream_Write_UINT32(ifman->output, 0); /* Result */
|
||||
|
@ -84,6 +84,9 @@ struct _TSMF_PRESENTATION
|
||||
UINT64 audio_start_time;
|
||||
UINT64 audio_end_time;
|
||||
|
||||
UINT32 volume;
|
||||
UINT32 muted;
|
||||
|
||||
HANDLE mutex;
|
||||
HANDLE thread;
|
||||
|
||||
@ -282,6 +285,9 @@ TSMF_PRESENTATION* tsmf_presentation_new(const BYTE* guid, IWTSVirtualChannelCal
|
||||
memcpy(presentation->presentation_id, guid, GUID_SIZE);
|
||||
presentation->channel_callback = pChannelCallback;
|
||||
|
||||
presentation->volume = 5000; /* 50% */
|
||||
presentation->muted = 0;
|
||||
|
||||
presentation->mutex = CreateMutex(NULL, FALSE, NULL);
|
||||
presentation->stream_list = list_new();
|
||||
|
||||
@ -786,6 +792,9 @@ void tsmf_presentation_volume_changed(TSMF_PRESENTATION* presentation, UINT32 ne
|
||||
LIST_ITEM* item;
|
||||
TSMF_STREAM* stream;
|
||||
|
||||
presentation->volume = newVolume;
|
||||
presentation->muted = muted;
|
||||
|
||||
for (item = presentation->stream_list->head; item; item = item->next)
|
||||
{
|
||||
stream = (TSMF_STREAM*) item->data;
|
||||
@ -964,7 +973,10 @@ TSMF_STREAM* tsmf_stream_new(TSMF_PRESENTATION* presentation, UINT32 stream_id)
|
||||
stream->thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) tsmf_stream_playback_func, stream, CREATE_SUSPENDED, NULL);
|
||||
|
||||
stream->sample_list = Queue_New(TRUE, -1, -1);
|
||||
stream->sample_list->object.fnObjectFree = free;
|
||||
|
||||
stream->sample_ack_list = Queue_New(TRUE, -1, -1);
|
||||
stream->sample_ack_list->object.fnObjectFree = free;
|
||||
|
||||
WaitForSingleObject(presentation->mutex, INFINITE);
|
||||
list_enqueue(presentation->stream_list, stream);
|
||||
@ -1026,6 +1038,7 @@ void tsmf_stream_set_format(TSMF_STREAM* stream, const char* name, wStream* s)
|
||||
stream->width = mediatype.Width;
|
||||
stream->height = mediatype.Height;
|
||||
stream->decoder = tsmf_load_decoder(name, &mediatype);
|
||||
tsmf_stream_change_volume(stream, stream->presentation->volume, stream->presentation->muted);
|
||||
}
|
||||
|
||||
void tsmf_stream_end(TSMF_STREAM* stream)
|
||||
|
@ -248,6 +248,9 @@ public class SessionActivity extends Activity
|
||||
{
|
||||
Log.v(TAG, "OnConnectionFailure");
|
||||
|
||||
// remove pending move events
|
||||
uiHandler.removeMessages(UIHandler.SEND_MOVE_EVENT);
|
||||
|
||||
if(progressDialog != null)
|
||||
{
|
||||
progressDialog.dismiss();
|
||||
@ -265,6 +268,9 @@ public class SessionActivity extends Activity
|
||||
{
|
||||
Log.v(TAG, "OnDisconnected");
|
||||
|
||||
// remove pending move events
|
||||
uiHandler.removeMessages(UIHandler.SEND_MOVE_EVENT);
|
||||
|
||||
if(progressDialog != null)
|
||||
{
|
||||
progressDialog.dismiss();
|
||||
@ -434,6 +440,7 @@ public class SessionActivity extends Activity
|
||||
|
||||
keyboardMapper = new KeyboardMapper();
|
||||
keyboardMapper.init(this);
|
||||
keyboardMapper.reset(this);
|
||||
|
||||
modifiersKeyboard = new Keyboard(getApplicationContext(), R.xml.modifiers_keyboard);
|
||||
specialkeysKeyboard = new Keyboard(getApplicationContext(), R.xml.specialkeys_keyboard);
|
||||
|
@ -65,7 +65,9 @@ public abstract class ClipboardManagerProxy {
|
||||
String data = null;
|
||||
|
||||
if (clip != null && clip.getItemCount() > 0) {
|
||||
data = clip.getItemAt(0).getText().toString();
|
||||
CharSequence cs = clip.getItemAt(0).getText();
|
||||
if (cs != null)
|
||||
data = cs.toString();
|
||||
}
|
||||
if (mListener != null) {
|
||||
mListener.onClipboardChanged(data);
|
||||
|
@ -131,7 +131,7 @@ void xf_Bitmap_Decompress(rdpContext* context, rdpBitmap* bitmap,
|
||||
RFX_MESSAGE* msg;
|
||||
xfContext* xfc = (xfContext*) context;
|
||||
|
||||
size = width * height * (bpp + 7) / 8;
|
||||
size = width * height * ((bpp + 7) / 8);
|
||||
|
||||
if (bitmap->data == NULL)
|
||||
bitmap->data = (BYTE*) malloc(size);
|
||||
|
@ -134,6 +134,8 @@ COMMAND_LINE_ARGUMENT_A args[] =
|
||||
{ "wm-class", COMMAND_LINE_VALUE_REQUIRED, "<class name>", NULL, NULL, -1, NULL, "set the WM_CLASS hint for the window instance" },
|
||||
{ "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" },
|
||||
{ "play-rfx", COMMAND_LINE_VALUE_REQUIRED, "<pcap file>", NULL, NULL, -1, NULL, "Replay rfx pcap file" },
|
||||
{ "auth-only", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueFalse, NULL, -1, NULL, "Authenticate only." },
|
||||
{ NULL, 0, NULL, NULL, NULL, -1, NULL, NULL }
|
||||
};
|
||||
|
||||
@ -1598,6 +1600,15 @@ int freerdp_client_parse_command_line_arguments(int argc, char** argv, rdpSettin
|
||||
{
|
||||
settings->WmClass = _strdup(arg->Value);
|
||||
}
|
||||
CommandLineSwitchCase(arg, "play-rfx")
|
||||
{
|
||||
settings->PlayRemoteFxFile = _strdup(arg->Value);
|
||||
settings->PlayRemoteFx = TRUE;
|
||||
}
|
||||
CommandLineSwitchCase(arg, "auth-only")
|
||||
{
|
||||
settings->AuthenticationOnly = arg->Value ? TRUE : FALSE;
|
||||
}
|
||||
CommandLineSwitchDefault(arg)
|
||||
{
|
||||
|
||||
|
3
docs/README.directfb
Normal file
3
docs/README.directfb
Normal file
@ -0,0 +1,3 @@
|
||||
The dfreerdp FreeRDP client is currently orphaned and unmaintained so please don't expect it to build and work without problems.
|
||||
|
||||
If you are interested to update and maintain the dfreerdp client please let us know.
|
@ -61,6 +61,7 @@ FREERDP_API int tls_write_all(rdpTls* tls, BYTE* data, int length);
|
||||
FREERDP_API int tls_wait_read(rdpTls* tls);
|
||||
FREERDP_API int tls_wait_write(rdpTls* tls);
|
||||
|
||||
FREERDP_API BOOL tls_match_hostname(char *pattern, int pattern_length, char *hostname);
|
||||
FREERDP_API BOOL tls_verify_certificate(rdpTls* tls, CryptoCert cert, char* hostname);
|
||||
FREERDP_API void tls_print_certificate_error(char* hostname, char* fingerprint, char* hosts_file);
|
||||
FREERDP_API void tls_print_certificate_name_mismatch_error(char* hostname, char* common_name, char** alt_names, int alt_names_count);
|
||||
|
@ -20,17 +20,15 @@
|
||||
#ifndef FREERDP_UTILS_STOPWATCH_H
|
||||
#define FREERDP_UTILS_STOPWATCH_H
|
||||
|
||||
#include <time.h>
|
||||
|
||||
#include <freerdp/api.h>
|
||||
#include <freerdp/types.h>
|
||||
|
||||
struct _STOPWATCH
|
||||
{
|
||||
clock_t start;
|
||||
clock_t end;
|
||||
double elapsed;
|
||||
clock_t count;
|
||||
UINT64 start;
|
||||
UINT64 end;
|
||||
UINT64 elapsed;
|
||||
UINT32 count;
|
||||
};
|
||||
typedef struct _STOPWATCH STOPWATCH;
|
||||
|
||||
|
2
libfreerdp/cache/glyph.c
vendored
2
libfreerdp/cache/glyph.c
vendored
@ -500,6 +500,7 @@ void glyph_cache_free(rdpGlyphCache* glyph_cache)
|
||||
Glyph_Free(glyph_cache->context, glyph);
|
||||
free(glyph->aj);
|
||||
free(glyph);
|
||||
glyph_cache->glyphCache[i].entries[j] = NULL;
|
||||
}
|
||||
}
|
||||
free(glyph_cache->glyphCache[i].entries);
|
||||
@ -509,6 +510,7 @@ void glyph_cache_free(rdpGlyphCache* glyph_cache)
|
||||
{
|
||||
fragment = glyph_cache->fragCache.entries[i].fragment;
|
||||
free(fragment);
|
||||
glyph_cache->fragCache.entries[i].fragment = NULL;
|
||||
}
|
||||
|
||||
free(glyph_cache->fragCache.entries);
|
||||
|
16
libfreerdp/cache/pointer.c
vendored
16
libfreerdp/cache/pointer.c
vendored
@ -68,9 +68,18 @@ void update_pointer_color(rdpContext* context, POINTER_COLOR_UPDATE* pointer_col
|
||||
pointer->height = pointer_color->height;
|
||||
pointer->lengthAndMask = pointer_color->lengthAndMask;
|
||||
pointer->lengthXorMask = pointer_color->lengthXorMask;
|
||||
pointer->xorMaskData = pointer_color->xorMaskData;
|
||||
pointer->andMaskData = pointer_color->andMaskData;
|
||||
|
||||
if (pointer->lengthAndMask && pointer_color->xorMaskData)
|
||||
{
|
||||
pointer->andMaskData = (BYTE*) malloc(pointer->lengthAndMask);
|
||||
CopyMemory(pointer->andMaskData, pointer_color->andMaskData, pointer->lengthAndMask);
|
||||
}
|
||||
|
||||
if (pointer->lengthXorMask && pointer_color->xorMaskData)
|
||||
{
|
||||
pointer->xorMaskData = (BYTE*) malloc(pointer->lengthXorMask);
|
||||
CopyMemory(pointer->xorMaskData, pointer_color->xorMaskData, pointer->lengthXorMask);
|
||||
}
|
||||
pointer->New(context, pointer);
|
||||
pointer_cache_put(cache->pointer, pointer_color->cacheIndex, pointer);
|
||||
Pointer_Set(context, pointer);
|
||||
@ -202,7 +211,10 @@ void pointer_cache_free(rdpPointerCache* pointer_cache)
|
||||
pointer = pointer_cache->entries[i];
|
||||
|
||||
if (pointer != NULL)
|
||||
{
|
||||
Pointer_Free(pointer_cache->update->context, pointer);
|
||||
pointer_cache->entries[i] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
free(pointer_cache->entries);
|
||||
|
@ -196,6 +196,8 @@ RFX_CONTEXT* rfx_context_new(void)
|
||||
|
||||
if (status == ERROR_SUCCESS)
|
||||
{
|
||||
dwSize = sizeof(dwValue);
|
||||
|
||||
if (RegQueryValueEx(hKey, _T("UseThreads"), NULL, &dwType, (BYTE*) &dwValue, &dwSize) == ERROR_SUCCESS)
|
||||
context->priv->UseThreads = dwValue ? 1 : 0;
|
||||
|
||||
@ -257,6 +259,9 @@ void rfx_context_free(RFX_CONTEXT* context)
|
||||
{
|
||||
CloseThreadpool(context->priv->ThreadPool);
|
||||
DestroyThreadpoolEnvironment(&context->priv->ThreadPoolEnv);
|
||||
#ifdef WITH_PROFILER
|
||||
fprintf(stderr, "\nWARNING: Profiling results probably unusable with multithreaded RemoteFX codec!\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
BufferPool_Free(context->priv->BufferPool);
|
||||
@ -739,7 +744,10 @@ static BOOL rfx_process_message_tileset(RFX_CONTEXT* context, RFX_MESSAGE* messa
|
||||
if (context->priv->UseThreads)
|
||||
{
|
||||
for (i = 0; i < message->num_tiles; i++)
|
||||
{
|
||||
WaitForThreadpoolWorkCallbacks(work_objects[i], FALSE);
|
||||
CloseThreadpoolWork(work_objects[i]);
|
||||
}
|
||||
|
||||
free(work_objects);
|
||||
free(params);
|
||||
|
@ -218,8 +218,10 @@ BOOL rfx_decode_rgb(RFX_CONTEXT* context, wStream* data_in,
|
||||
Stream_Seek(data_in, cr_size);
|
||||
}
|
||||
|
||||
PROFILER_ENTER(context->priv->prof_rfx_ycbcr_to_rgb);
|
||||
prims->yCbCrToRGB_16s16s_P3P3((const INT16**) pSrcDst, 64 * sizeof(INT16),
|
||||
pSrcDst, 64 * sizeof(INT16), &roi_64x64);
|
||||
PROFILER_EXIT(context->priv->prof_rfx_ycbcr_to_rgb);
|
||||
|
||||
PROFILER_ENTER(context->priv->prof_rfx_decode_format_rgb);
|
||||
rfx_decode_format_rgb(pSrcDst[0], pSrcDst[1], pSrcDst[2],
|
||||
|
@ -1207,7 +1207,7 @@ int freerdp_set_param_bool(rdpSettings* settings, int id, BOOL param)
|
||||
|
||||
EventArgsInit(&e, "freerdp");
|
||||
e.id = id;
|
||||
PubSub_OnParamChange(context->pubSub, context->instance, &e);
|
||||
PubSub_OnParamChange(context->pubSub, context, &e);
|
||||
|
||||
return -1;
|
||||
}
|
||||
@ -1256,7 +1256,7 @@ int freerdp_set_param_int(rdpSettings* settings, int id, int param)
|
||||
|
||||
EventArgsInit(&e, "freerdp");
|
||||
e.id = id;
|
||||
PubSub_OnParamChange(context->pubSub, context->instance, &e);
|
||||
PubSub_OnParamChange(context->pubSub, context, &e);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -1898,7 +1898,7 @@ int freerdp_set_param_uint32(rdpSettings* settings, int id, UINT32 param)
|
||||
|
||||
EventArgsInit(&e, "freerdp");
|
||||
e.id = id;
|
||||
PubSub_OnParamChange(context->pubSub, context->instance, &e);
|
||||
PubSub_OnParamChange(context->pubSub, context, &e);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -1940,7 +1940,7 @@ int freerdp_set_param_uint64(rdpSettings* settings, int id, UINT64 param)
|
||||
|
||||
EventArgsInit(&e, "freerdp");
|
||||
e.id = id;
|
||||
PubSub_OnParamChange(context->pubSub, context->instance, &e);
|
||||
PubSub_OnParamChange(context->pubSub, context, &e);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -2278,7 +2278,7 @@ int freerdp_set_param_string(rdpSettings* settings, int id, char* param)
|
||||
|
||||
EventArgsInit(&e, "freerdp");
|
||||
e.id = id;
|
||||
PubSub_OnParamChange(context->pubSub, context->instance, &e);
|
||||
PubSub_OnParamChange(context->pubSub, context, &e);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -2319,7 +2319,7 @@ int freerdp_set_param_double(rdpSettings* settings, int id, double param)
|
||||
|
||||
EventArgsInit(&e, "freerdp");
|
||||
e.id = id;
|
||||
PubSub_OnParamChange(context->pubSub, context->instance, &e);
|
||||
PubSub_OnParamChange(context->pubSub, context, &e);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -279,6 +279,14 @@ BOOL rdp_recv_deactivate_all(rdpRdp* rdp, wStream* s)
|
||||
{
|
||||
UINT16 lengthSourceDescriptor;
|
||||
|
||||
if (rdp->state == CONNECTION_STATE_ACTIVE)
|
||||
{
|
||||
rdp->deactivation_reactivation = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
rdp->deactivation_reactivation = FALSE;
|
||||
}
|
||||
/*
|
||||
* Windows XP can send short DEACTIVATE_ALL PDU that doesn't contain
|
||||
* the following fields.
|
||||
|
@ -587,6 +587,13 @@ BOOL rdp_client_connect_finalize(rdpRdp* rdp)
|
||||
return FALSE;
|
||||
if (!rdp_send_client_control_pdu(rdp, CTRLACTION_REQUEST_CONTROL))
|
||||
return FALSE;
|
||||
/**
|
||||
* [MS-RDPBCGR] 2.2.1.17
|
||||
* Client persistent key list must be sent if a bitmap is
|
||||
* stored in persistent bitmap cache or the server has advertised support for bitmap
|
||||
* host cache and a deactivation reactivation sequence is *not* in progress.
|
||||
*/
|
||||
if (!rdp->deactivation_reactivation && rdp->settings->BitmapCachePersistEnabled)
|
||||
if (!rdp_send_client_persistent_key_list_pdu(rdp))
|
||||
return FALSE;
|
||||
if (!rdp_send_client_font_list_pdu(rdp, FONTLIST_FIRST | FONTLIST_LAST))
|
||||
|
@ -31,6 +31,7 @@
|
||||
#include "message.h"
|
||||
|
||||
#include <winpr/crt.h>
|
||||
#include <winpr/stream.h>
|
||||
|
||||
#include <freerdp/freerdp.h>
|
||||
#include <freerdp/error.h>
|
||||
@ -127,28 +128,30 @@ BOOL freerdp_connect(freerdp* instance)
|
||||
|
||||
update = instance->update;
|
||||
|
||||
s = StreamPool_Take(rdp->transport->ReceivePool, 0);
|
||||
instance->update->pcap_rfx = pcap_open(settings->PlayRemoteFxFile, FALSE);
|
||||
update->pcap_rfx = pcap_open(settings->PlayRemoteFxFile, FALSE);
|
||||
|
||||
if (update->pcap_rfx)
|
||||
if (!update->pcap_rfx)
|
||||
return FALSE;
|
||||
else
|
||||
update->play_rfx = TRUE;
|
||||
|
||||
while (update->play_rfx && pcap_has_next_record(update->pcap_rfx))
|
||||
while (pcap_has_next_record(update->pcap_rfx))
|
||||
{
|
||||
|
||||
pcap_get_next_record_header(update->pcap_rfx, &record);
|
||||
|
||||
Stream_EnsureCapacity(s, record.length);
|
||||
s = StreamPool_Take(rdp->transport->ReceivePool, record.length);
|
||||
record.data = Stream_Buffer(s);
|
||||
|
||||
pcap_get_next_record_content(update->pcap_rfx, &record);
|
||||
Stream_SetLength(s,record.length);
|
||||
Stream_SetPosition(s, 0);
|
||||
|
||||
update->BeginPaint(update->context);
|
||||
update_recv_surfcmds(update, Stream_Capacity(s), s);
|
||||
update_recv_surfcmds(update, Stream_Length(s) , s);
|
||||
update->EndPaint(update->context);
|
||||
}
|
||||
|
||||
Stream_Release(s);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@ -394,7 +397,10 @@ void freerdp_context_free(freerdp* instance)
|
||||
IFCALL(instance->ContextFree, instance, instance->context);
|
||||
|
||||
rdp_free(instance->context->rdp);
|
||||
instance->context->rdp = NULL;
|
||||
|
||||
graphics_free(instance->context->graphics);
|
||||
instance->context->graphics = NULL;
|
||||
|
||||
PubSub_Free(instance->context->pubSub);
|
||||
|
||||
|
@ -117,10 +117,16 @@ void Pointer_Free(rdpContext* context, rdpPointer* pointer)
|
||||
pointer->Free(context, pointer);
|
||||
|
||||
if (pointer->xorMaskData)
|
||||
{
|
||||
free(pointer->xorMaskData);
|
||||
pointer->xorMaskData = NULL;
|
||||
}
|
||||
|
||||
if (pointer->andMaskData)
|
||||
{
|
||||
free(pointer->andMaskData);
|
||||
pointer->andMaskData = NULL;
|
||||
}
|
||||
|
||||
free(pointer);
|
||||
}
|
||||
|
@ -157,6 +157,7 @@ struct rdp_rdp
|
||||
UINT32 finalize_sc_pdus;
|
||||
BOOL disconnect;
|
||||
BOOL resendFocus;
|
||||
BOOL deactivation_reactivation;
|
||||
};
|
||||
|
||||
BOOL rdp_read_security_header(wStream* s, UINT16* flags);
|
||||
|
@ -58,15 +58,6 @@ static int update_recv_surfcmd_surface_bits(rdpUpdate* update, wStream* s, UINT3
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void update_send_frame_acknowledge(rdpRdp* rdp, UINT32 frameId)
|
||||
{
|
||||
wStream* s;
|
||||
|
||||
s = rdp_data_pdu_init(rdp);
|
||||
Stream_Write_UINT32(s, frameId);
|
||||
rdp_send_data_pdu(rdp, s, DATA_PDU_TYPE_FRAME_ACKNOWLEDGE, rdp->mcs->user_id);
|
||||
}
|
||||
|
||||
static int update_recv_surfcmd_frame_marker(rdpUpdate* update, wStream* s, UINT32 *length)
|
||||
{
|
||||
SURFACE_FRAME_MARKER* marker = &update->surface_frame_marker;
|
||||
@ -79,13 +70,6 @@ static int update_recv_surfcmd_frame_marker(rdpUpdate* update, wStream* s, UINT3
|
||||
|
||||
IFCALL(update->SurfaceFrameMarker, update->context, marker);
|
||||
|
||||
if (update->context->rdp->settings->ReceivedCapabilities[CAPSET_TYPE_FRAME_ACKNOWLEDGE] &&
|
||||
(update->context->rdp->settings->FrameAcknowledge > 0) &&
|
||||
(marker->frameAction == SURFACECMD_FRAMEACTION_END))
|
||||
{
|
||||
update_send_frame_acknowledge(update->context->rdp, marker->frameId);
|
||||
}
|
||||
|
||||
*length = 6;
|
||||
|
||||
return 0;
|
||||
|
@ -677,6 +677,7 @@ static void update_send_refresh_rect(rdpContext* context, BYTE count, RECTANGLE_
|
||||
update_write_refresh_rect(s, count, areas);
|
||||
|
||||
rdp_send_data_pdu(rdp, s, DATA_PDU_TYPE_REFRESH_RECT, rdp->mcs->user_id);
|
||||
Stream_Release(s);
|
||||
}
|
||||
}
|
||||
|
||||
@ -705,6 +706,7 @@ static void update_send_suppress_output(rdpContext* context, BYTE allow, RECTANG
|
||||
update_write_suppress_output(s, allow, area);
|
||||
|
||||
rdp_send_data_pdu(rdp, s, DATA_PDU_TYPE_SUPPRESS_OUTPUT, rdp->mcs->user_id);
|
||||
Stream_Release(s);
|
||||
}
|
||||
}
|
||||
|
||||
@ -717,6 +719,7 @@ static void update_send_surface_command(rdpContext* context, wStream* s)
|
||||
Stream_EnsureRemainingCapacity(update, Stream_GetPosition(s));
|
||||
Stream_Write(update, Stream_Buffer(s), Stream_GetPosition(s));
|
||||
fastpath_send_update_pdu(rdp->fastpath, FASTPATH_UPDATETYPE_SURFCMDS, update);
|
||||
Stream_Release(update);
|
||||
}
|
||||
|
||||
static void update_send_surface_bits(rdpContext* context, SURFACE_BITS_COMMAND* surface_bits_command)
|
||||
@ -733,6 +736,8 @@ static void update_send_surface_bits(rdpContext* context, SURFACE_BITS_COMMAND*
|
||||
fastpath_send_update_pdu(rdp->fastpath, FASTPATH_UPDATETYPE_SURFCMDS, s);
|
||||
|
||||
update_force_flush(context);
|
||||
|
||||
Stream_Release(s);
|
||||
}
|
||||
|
||||
static void update_send_surface_frame_marker(rdpContext* context, SURFACE_FRAME_MARKER* surface_frame_marker)
|
||||
@ -747,6 +752,8 @@ static void update_send_surface_frame_marker(rdpContext* context, SURFACE_FRAME_
|
||||
fastpath_send_update_pdu(rdp->fastpath, FASTPATH_UPDATETYPE_SURFCMDS, s);
|
||||
|
||||
update_force_flush(context);
|
||||
|
||||
Stream_Release(s);
|
||||
}
|
||||
|
||||
static void update_send_frame_acknowledge(rdpContext* context, UINT32 frameId)
|
||||
@ -759,6 +766,7 @@ static void update_send_frame_acknowledge(rdpContext* context, UINT32 frameId)
|
||||
s = rdp_data_pdu_init(rdp);
|
||||
Stream_Write_UINT32(s, frameId);
|
||||
rdp_send_data_pdu(rdp, s, DATA_PDU_TYPE_FRAME_ACKNOWLEDGE, rdp->mcs->user_id);
|
||||
Stream_Release(s);
|
||||
}
|
||||
}
|
||||
|
||||
@ -770,6 +778,7 @@ static void update_send_synchronize(rdpContext* context)
|
||||
s = fastpath_update_pdu_init(rdp->fastpath);
|
||||
Stream_Zero(s, 2); /* pad2Octets (2 bytes) */
|
||||
fastpath_send_update_pdu(rdp->fastpath, FASTPATH_UPDATETYPE_SYNCHRONIZE, s);
|
||||
Stream_Release(s);
|
||||
}
|
||||
|
||||
static void update_send_desktop_resize(rdpContext* context)
|
||||
@ -1311,6 +1320,7 @@ static void update_send_pointer_system(rdpContext* context, POINTER_SYSTEM_UPDAT
|
||||
updateCode = FASTPATH_UPDATETYPE_PTR_DEFAULT;
|
||||
|
||||
fastpath_send_update_pdu(rdp->fastpath, updateCode, s);
|
||||
Stream_Release(s);
|
||||
}
|
||||
|
||||
static void update_write_pointer_color(wStream* s, POINTER_COLOR_UPDATE* pointer_color)
|
||||
@ -1342,6 +1352,7 @@ static void update_send_pointer_color(rdpContext* context, POINTER_COLOR_UPDATE*
|
||||
s = fastpath_update_pdu_init(rdp->fastpath);
|
||||
update_write_pointer_color(s, pointer_color);
|
||||
fastpath_send_update_pdu(rdp->fastpath, FASTPATH_UPDATETYPE_COLOR, s);
|
||||
Stream_Release(s);
|
||||
}
|
||||
|
||||
static void update_send_pointer_new(rdpContext* context, POINTER_NEW_UPDATE* pointer_new)
|
||||
@ -1353,6 +1364,7 @@ static void update_send_pointer_new(rdpContext* context, POINTER_NEW_UPDATE* poi
|
||||
Stream_Write_UINT16(s, pointer_new->xorBpp); /* xorBpp (2 bytes) */
|
||||
update_write_pointer_color(s, &pointer_new->colorPtrAttr);
|
||||
fastpath_send_update_pdu(rdp->fastpath, FASTPATH_UPDATETYPE_POINTER, s);
|
||||
Stream_Release(s);
|
||||
}
|
||||
|
||||
static void update_send_pointer_cached(rdpContext* context, POINTER_CACHED_UPDATE* pointer_cached)
|
||||
@ -1363,6 +1375,7 @@ static void update_send_pointer_cached(rdpContext* context, POINTER_CACHED_UPDAT
|
||||
s = fastpath_update_pdu_init(rdp->fastpath);
|
||||
Stream_Write_UINT16(s, pointer_cached->cacheIndex); /* cacheIndex (2 bytes) */
|
||||
fastpath_send_update_pdu(rdp->fastpath, FASTPATH_UPDATETYPE_CACHED, s);
|
||||
Stream_Release(s);
|
||||
}
|
||||
|
||||
BOOL update_read_refresh_rect(rdpUpdate* update, wStream* s)
|
||||
|
@ -100,6 +100,7 @@ BOOL tls_connect(rdpTls* tls)
|
||||
CryptoCert cert;
|
||||
long options = 0;
|
||||
int connection_status;
|
||||
char *hostname;
|
||||
|
||||
tls->ctx = SSL_CTX_new(TLSv1_client_method());
|
||||
|
||||
@ -183,7 +184,12 @@ BOOL tls_connect(rdpTls* tls)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!tls_verify_certificate(tls, cert, tls->settings->ServerHostname))
|
||||
if (tls->settings->GatewayUsageMethod)
|
||||
hostname = tls->settings->GatewayHostname;
|
||||
else
|
||||
hostname = tls->settings->ServerHostname;
|
||||
|
||||
if (!tls_verify_certificate(tls, cert, hostname))
|
||||
{
|
||||
fprintf(stderr, "tls_connect: certificate not trusted, aborting.\n");
|
||||
tls_disconnect(tls);
|
||||
@ -513,6 +519,26 @@ BOOL tls_print_error(char* func, SSL* connection, int value)
|
||||
}
|
||||
}
|
||||
|
||||
BOOL tls_match_hostname(char *pattern, int pattern_length, char *hostname)
|
||||
{
|
||||
if (strlen(hostname) == pattern_length)
|
||||
{
|
||||
if (memcmp((void*) hostname, (void*) pattern, pattern_length) == 0)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (pattern_length > 2 && pattern[0] == '*' && pattern[1] == '.' && strlen(hostname) >= pattern_length)
|
||||
{
|
||||
char *check_hostname = &hostname[ strlen(hostname) - pattern_length+1 ];
|
||||
if (memcmp((void*) check_hostname, (void*) &pattern[1], pattern_length - 1) == 0 )
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL tls_verify_certificate(rdpTls* tls, CryptoCert cert, char* hostname)
|
||||
{
|
||||
int match;
|
||||
@ -549,12 +575,9 @@ BOOL tls_verify_certificate(rdpTls* tls, CryptoCert cert, char* hostname)
|
||||
|
||||
if (common_name != NULL)
|
||||
{
|
||||
if (strlen(hostname) == common_name_length)
|
||||
{
|
||||
if (memcmp((void*) hostname, (void*) common_name, common_name_length) == 0)
|
||||
if (tls_match_hostname(common_name, common_name_length, hostname))
|
||||
hostname_match = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
/* compare against alternative names */
|
||||
|
||||
@ -562,10 +585,10 @@ BOOL tls_verify_certificate(rdpTls* tls, CryptoCert cert, char* hostname)
|
||||
{
|
||||
for (index = 0; index < alt_names_count; index++)
|
||||
{
|
||||
if (strlen(hostname) == alt_names_lengths[index])
|
||||
if (tls_match_hostname(alt_names[index], alt_names_lengths[index], hostname))
|
||||
{
|
||||
if (memcmp((void*) hostname, (void*) alt_names[index], alt_names_lengths[index]) == 0)
|
||||
hostname_match = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -107,7 +107,7 @@ void gdi_Bitmap_Decompress(rdpContext* context, rdpBitmap* bitmap,
|
||||
rdpGdi* gdi;
|
||||
BOOL status;
|
||||
|
||||
size = width * height * (bpp + 7) / 8;
|
||||
size = width * height * ((bpp + 7) / 8);
|
||||
|
||||
if (bitmap->data == NULL)
|
||||
bitmap->data = (BYTE*) malloc(size);
|
||||
|
@ -175,7 +175,7 @@ char* gdi_convert_postfix_to_infix(char* postfix)
|
||||
|
||||
dl = al + bl + cl + 3;
|
||||
|
||||
d = malloc(cl + 1);
|
||||
d = malloc(dl + 1);
|
||||
sprintf_s(d, dl, "(%s%s%s)", b ? b : "", c, a);
|
||||
|
||||
Stack_Push(stack, d);
|
||||
|
@ -154,6 +154,7 @@ XKB_KEY_NAME_SCANCODE XKB_KEY_NAME_SCANCODE_TABLE[] =
|
||||
{ "LWIN", RDP_SCANCODE_LWIN},
|
||||
{ "RWIN", RDP_SCANCODE_RWIN},
|
||||
{ "COMP", RDP_SCANCODE_APPS},
|
||||
{ "MENU", RDP_SCANCODE_APPS}, // WinMenu in xfree86 layout
|
||||
{ "KPDV", RDP_SCANCODE_DIVIDE}, // KP!
|
||||
{ "RCTL", RDP_SCANCODE_RCONTROL},
|
||||
{ "RALT", RDP_SCANCODE_RMENU},
|
||||
|
@ -158,7 +158,7 @@ rdpPcap* pcap_open(char* name, BOOL write)
|
||||
{
|
||||
rdpPcap* pcap;
|
||||
|
||||
FILE* pcap_fp = fopen(name, write ? "w+" : "r");
|
||||
FILE* pcap_fp = fopen(name, write ? "w+b" : "rb");
|
||||
|
||||
if (pcap_fp == NULL)
|
||||
{
|
||||
|
@ -70,7 +70,7 @@ 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| %'10lu | %'9f | %'9f |\n", profiler->name, profiler->stopwatch->count, elapsed_sec, avg_sec);
|
||||
fprintf(stderr, "| %-30.30s| %10lu | %9f | %9f |\n", profiler->name, profiler->stopwatch->count, elapsed_sec, avg_sec);
|
||||
}
|
||||
|
||||
void profiler_print_footer()
|
||||
|
@ -26,9 +26,33 @@
|
||||
|
||||
#include <freerdp/utils/stopwatch.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
LARGE_INTEGER stopwatch_freq = { 0, 0 };
|
||||
#else
|
||||
#include <sys/time.h>
|
||||
#endif
|
||||
|
||||
void stopwatch_set_time(UINT64* usecs)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
LARGE_INTEGER perfcount;
|
||||
QueryPerformanceCounter(&perfcount);
|
||||
*usecs = (perfcount.QuadPart * 1000000) / stopwatch_freq.QuadPart;
|
||||
#else
|
||||
struct timeval tv;
|
||||
gettimeofday(&tv, NULL);
|
||||
*usecs = tv.tv_sec * 1000000 + tv.tv_usec;
|
||||
#endif
|
||||
}
|
||||
|
||||
STOPWATCH* stopwatch_create()
|
||||
{
|
||||
STOPWATCH* sw;
|
||||
#ifdef _WIN32
|
||||
if (stopwatch_freq.QuadPart == 0) {
|
||||
QueryPerformanceFrequency(&stopwatch_freq);
|
||||
}
|
||||
#endif
|
||||
|
||||
sw = (STOPWATCH*) malloc(sizeof(STOPWATCH));
|
||||
stopwatch_reset(sw);
|
||||
@ -43,13 +67,13 @@ void stopwatch_free(STOPWATCH* stopwatch)
|
||||
|
||||
void stopwatch_start(STOPWATCH* stopwatch)
|
||||
{
|
||||
stopwatch->start = clock();
|
||||
stopwatch_set_time(&stopwatch->start);
|
||||
stopwatch->count++;
|
||||
}
|
||||
|
||||
void stopwatch_stop(STOPWATCH* stopwatch)
|
||||
{
|
||||
stopwatch->end = clock();
|
||||
stopwatch_set_time(&stopwatch->end);
|
||||
stopwatch->elapsed += (stopwatch->end - stopwatch->start);
|
||||
}
|
||||
|
||||
@ -63,22 +87,12 @@ void stopwatch_reset(STOPWATCH* stopwatch)
|
||||
|
||||
double stopwatch_get_elapsed_time_in_seconds(STOPWATCH* stopwatch)
|
||||
{
|
||||
return ((double) stopwatch->elapsed) / CLOCKS_PER_SEC;
|
||||
return (stopwatch->elapsed/1000000.0);
|
||||
}
|
||||
|
||||
void stopwatch_get_elapsed_time_in_useconds(STOPWATCH* stopwatch, UINT32* sec, UINT32* usec)
|
||||
{
|
||||
double uelapsed;
|
||||
double clocks_per_usec;
|
||||
|
||||
*sec = ((UINT32) stopwatch->elapsed) / CLOCKS_PER_SEC;
|
||||
uelapsed = stopwatch->elapsed - ((double)(*sec) * CLOCKS_PER_SEC);
|
||||
|
||||
clocks_per_usec = (CLOCKS_PER_SEC / 1000000);
|
||||
|
||||
if (clocks_per_usec > 0.0)
|
||||
*usec = (UINT32)(uelapsed / clocks_per_usec);
|
||||
else
|
||||
*usec = 0;
|
||||
*sec = stopwatch->elapsed / 1000000;
|
||||
*usec = stopwatch->elapsed % 1000000;
|
||||
}
|
||||
|
||||
|
@ -19,11 +19,11 @@
|
||||
|
||||
add_subdirectory(common)
|
||||
|
||||
if(NOT WIN32)
|
||||
if(WITH_SAMPLE)
|
||||
add_subdirectory(Sample)
|
||||
endif()
|
||||
|
||||
if(NOT WIN32)
|
||||
if(WITH_X11)
|
||||
add_subdirectory(X11)
|
||||
endif()
|
||||
|
@ -26,14 +26,13 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <pthread.h>
|
||||
#include <signal.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#include <winpr/crt.h>
|
||||
#include <winpr/synch.h>
|
||||
|
||||
#include <freerdp/constants.h>
|
||||
#include <freerdp/utils/tcp.h>
|
||||
#include <freerdp/server/rdpsnd.h>
|
||||
|
||||
#include "sf_audin.h"
|
||||
@ -41,6 +40,10 @@
|
||||
|
||||
#include "sfreerdp.h"
|
||||
|
||||
#define SAMPLE_SERVER_USE_CLIENT_RESOLUTION 1
|
||||
#define SAMPLE_SERVER_DEFAULT_WIDTH 1024
|
||||
#define SAMPLE_SERVER_DEFAULT_HEIGHT 768
|
||||
|
||||
static char* test_pcap_file = NULL;
|
||||
static BOOL test_dump_rfx_realtime = TRUE;
|
||||
|
||||
@ -48,8 +51,8 @@ void test_peer_context_new(freerdp_peer* client, testPeerContext* context)
|
||||
{
|
||||
context->rfx_context = rfx_context_new();
|
||||
context->rfx_context->mode = RLGR3;
|
||||
context->rfx_context->width = client->settings->DesktopWidth;
|
||||
context->rfx_context->height = client->settings->DesktopHeight;
|
||||
context->rfx_context->width = SAMPLE_SERVER_DEFAULT_WIDTH;
|
||||
context->rfx_context->height = SAMPLE_SERVER_DEFAULT_HEIGHT;
|
||||
rfx_context_set_pixel_format(context->rfx_context, RDP_PIXEL_FORMAT_R8G8B8);
|
||||
|
||||
context->nsc_context = nsc_context_new();
|
||||
@ -473,6 +476,17 @@ BOOL tf_peer_post_connect(freerdp_peer* client)
|
||||
printf("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");
|
||||
#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);
|
||||
client->update->DesktopResize(client->update->context);
|
||||
#endif
|
||||
|
||||
/* A real server should tag the peer as activated here and start sending updates in main loop. */
|
||||
test_peer_load_icon(client);
|
||||
|
||||
@ -554,9 +568,11 @@ void tf_peer_keyboard_event(rdpInput* input, UINT16 flags, UINT16 code)
|
||||
}
|
||||
else
|
||||
{
|
||||
client->settings->DesktopWidth = 640;
|
||||
client->settings->DesktopHeight = 480;
|
||||
client->settings->DesktopWidth = SAMPLE_SERVER_DEFAULT_WIDTH;
|
||||
client->settings->DesktopHeight = SAMPLE_SERVER_DEFAULT_HEIGHT;
|
||||
}
|
||||
context->rfx_context->width = client->settings->DesktopWidth;
|
||||
context->rfx_context->height = client->settings->DesktopHeight;
|
||||
update->DesktopResize(update->context);
|
||||
context->activated = FALSE;
|
||||
}
|
||||
@ -667,6 +683,8 @@ static void* test_peer_mainloop(void* arg)
|
||||
client->update->RefreshRect = tf_peer_refresh_rect;
|
||||
client->update->SuppressOutput = tf_peer_suppress_output;
|
||||
|
||||
client->settings->MultifragMaxRequestSize = 0xFFFFFF; /* FIXME */
|
||||
|
||||
client->Initialize(client);
|
||||
context = (testPeerContext*) client->context;
|
||||
|
||||
@ -681,7 +699,11 @@ static void* test_peer_mainloop(void* arg)
|
||||
printf("Failed to get FreeRDP file descriptor\n");
|
||||
break;
|
||||
}
|
||||
|
||||
#ifndef _WIN32
|
||||
/* winsock's select() only works with sockets ! */
|
||||
WTSVirtualChannelManagerGetFileDescriptor(context->vcm, rfds, &rcount);
|
||||
#endif
|
||||
|
||||
max_fds = 0;
|
||||
FD_ZERO(&rfds_set);
|
||||
@ -701,15 +723,27 @@ static void* test_peer_mainloop(void* arg)
|
||||
|
||||
if (select(max_fds + 1, &rfds_set, NULL, NULL, NULL) == -1)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
/* error codes set by windows sockets are not made available through errno ! */
|
||||
int wsa_error = WSAGetLastError();
|
||||
if (!((wsa_error == WSAEWOULDBLOCK) ||
|
||||
(wsa_error == WSAEINPROGRESS) ||
|
||||
(wsa_error == WSAEINTR)))
|
||||
{
|
||||
printf("select failed (WSAGetLastError: %d)\n", wsa_error);
|
||||
break;
|
||||
}
|
||||
#else
|
||||
/* these are not really errors */
|
||||
if (!((errno == EAGAIN) ||
|
||||
(errno == EWOULDBLOCK) ||
|
||||
(errno == EINPROGRESS) ||
|
||||
(errno == EINTR))) /* signal occurred */
|
||||
{
|
||||
printf("select failed\n");
|
||||
printf("select failed (errno: %d)\n", errno);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if (client->CheckFileDescriptor(client) != TRUE)
|
||||
@ -730,10 +764,10 @@ static void* test_peer_mainloop(void* arg)
|
||||
|
||||
static void test_peer_accepted(freerdp_listener* instance, freerdp_peer* client)
|
||||
{
|
||||
pthread_t th;
|
||||
|
||||
pthread_create(&th, 0, test_peer_mainloop, client);
|
||||
pthread_detach(th);
|
||||
HANDLE hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) test_peer_mainloop, (void*) client, 0, NULL);
|
||||
if (hThread != NULL) {
|
||||
CloseHandle(hThread);
|
||||
}
|
||||
}
|
||||
|
||||
static void test_server_mainloop(freerdp_listener* instance)
|
||||
@ -800,9 +834,6 @@ int main(int argc, char* argv[])
|
||||
{
|
||||
freerdp_listener* instance;
|
||||
|
||||
/* Ignore SIGPIPE, otherwise an SSL_write failure could crash your server */
|
||||
signal(SIGPIPE, SIG_IGN);
|
||||
|
||||
instance = freerdp_listener_new();
|
||||
|
||||
instance->PeerAccepted = test_peer_accepted;
|
||||
@ -814,12 +845,14 @@ int main(int argc, char* argv[])
|
||||
test_dump_rfx_realtime = FALSE;
|
||||
|
||||
/* Open the server socket and start listening. */
|
||||
freerdp_wsa_startup();
|
||||
if (instance->Open(instance, NULL, 3389) &&
|
||||
instance->OpenLocal(instance, "/tmp/tfreerdp-server.0"))
|
||||
{
|
||||
/* Entering the server main loop. In a real server the listener can be run in its own thread. */
|
||||
test_server_mainloop(instance);
|
||||
}
|
||||
freerdp_wsa_cleanup();
|
||||
|
||||
freerdp_listener_free(instance);
|
||||
|
||||
|
Binary file not shown.
@ -52,5 +52,6 @@ int xf_cursor_init(xfInfo* xfi)
|
||||
|
||||
XFixesSelectCursorInput(xfi->display, DefaultRootWindow(xfi->display), XFixesDisplayCursorNotifyMask);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -35,32 +35,20 @@
|
||||
#include <malloc.h>
|
||||
#endif
|
||||
|
||||
struct _aligned_meminfo {
|
||||
size_t size;
|
||||
void *base_addr;
|
||||
};
|
||||
|
||||
|
||||
void* _aligned_malloc(size_t size, size_t alignment)
|
||||
{
|
||||
void* memptr;
|
||||
|
||||
/* alignment must be a power of 2 */
|
||||
|
||||
if (alignment % 2 == 1)
|
||||
return NULL;
|
||||
|
||||
#ifdef ANDROID
|
||||
memptr = memalign(alignment, size);
|
||||
#else
|
||||
if (posix_memalign(&memptr, alignment, size) != 0)
|
||||
return NULL;
|
||||
#endif
|
||||
|
||||
return memptr;
|
||||
return _aligned_offset_malloc(size, alignment, 0);
|
||||
}
|
||||
|
||||
void* _aligned_realloc(void* memblock, size_t size, size_t alignment)
|
||||
{
|
||||
void* memptr = NULL;
|
||||
|
||||
memptr = realloc(memblock, size);
|
||||
|
||||
return memptr;
|
||||
return _aligned_offset_realloc(memblock, size, alignment, 0);
|
||||
}
|
||||
|
||||
void* _aligned_recalloc(void* memblock, size_t num, size_t size, size_t alignment)
|
||||
@ -70,37 +58,60 @@ void* _aligned_recalloc(void* memblock, size_t num, size_t size, size_t alignmen
|
||||
|
||||
void* _aligned_offset_malloc(size_t size, size_t alignment, size_t offset)
|
||||
{
|
||||
void* memptr;
|
||||
void* memptr, *tmpptr;
|
||||
struct _aligned_meminfo *ameminfo;
|
||||
|
||||
/* alignment must be a power of 2 */
|
||||
|
||||
if (alignment % 2 == 1)
|
||||
return NULL;
|
||||
|
||||
/* offset must be less than size */
|
||||
|
||||
if (offset >= size)
|
||||
return NULL;
|
||||
|
||||
/* minimum alignment is pointer size */
|
||||
|
||||
if (alignment < sizeof(void*))
|
||||
alignment = sizeof(void*);
|
||||
|
||||
#ifdef ANDROID
|
||||
memptr = memalign(alignment, size);
|
||||
#else
|
||||
if (posix_memalign(&memptr, alignment, size) != 0)
|
||||
/* malloc size + alignment to make sure we can align afterwards */
|
||||
tmpptr = malloc(size + alignment + sizeof(struct _aligned_meminfo));
|
||||
if (!tmpptr)
|
||||
return NULL;
|
||||
#endif
|
||||
|
||||
|
||||
memptr = (void *)((((size_t)((PBYTE)tmpptr + alignment + offset + sizeof(struct _aligned_meminfo)) & ~(alignment - 1)) - offset));
|
||||
|
||||
ameminfo = (struct _aligned_meminfo *) (((size_t)((PBYTE)memptr - sizeof(struct _aligned_meminfo))));
|
||||
ameminfo->base_addr = tmpptr;
|
||||
ameminfo->size = size;
|
||||
|
||||
return memptr;
|
||||
}
|
||||
|
||||
void* _aligned_offset_realloc(void* memblock, size_t size, size_t alignment, size_t offset)
|
||||
{
|
||||
struct _aligned_meminfo *ameminfo;
|
||||
void *newmem;
|
||||
|
||||
if (!memblock)
|
||||
return _aligned_offset_malloc(size, alignment, offset);
|
||||
|
||||
if (size == 0)
|
||||
{
|
||||
_aligned_free(memblock);
|
||||
return NULL;
|
||||
}
|
||||
/* The following is not very performant but a simple and working solution */
|
||||
newmem = _aligned_offset_malloc(size, alignment, offset);
|
||||
|
||||
if (!newmem)
|
||||
return NULL;
|
||||
|
||||
ameminfo = (struct _aligned_meminfo *) (((size_t)((PBYTE)memblock - sizeof(struct _aligned_meminfo))));
|
||||
memcpy(newmem, memblock, ameminfo->size);
|
||||
_aligned_free(memblock);
|
||||
return newmem;
|
||||
}
|
||||
|
||||
void* _aligned_offset_recalloc(void* memblock, size_t num, size_t size, size_t alignment, size_t offset)
|
||||
{
|
||||
@ -114,7 +125,13 @@ size_t _aligned_msize(void* memblock, size_t alignment, size_t offset)
|
||||
|
||||
void _aligned_free(void* memblock)
|
||||
{
|
||||
free(memblock);
|
||||
struct _aligned_meminfo *ameminfo;
|
||||
if (!memblock)
|
||||
return;
|
||||
|
||||
ameminfo = (struct _aligned_meminfo *) (((size_t)((PBYTE)memblock - sizeof(struct _aligned_meminfo))));
|
||||
|
||||
free(ameminfo->base_addr);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -47,6 +47,9 @@ static inline BOOL winpr_Handle_GetInfo(HANDLE handle, ULONG* pType, PVOID* pObj
|
||||
{
|
||||
WINPR_HANDLE* wHandle;
|
||||
|
||||
if (handle == NULL)
|
||||
return FALSE;
|
||||
|
||||
wHandle = (WINPR_HANDLE*) handle;
|
||||
|
||||
*pType = wHandle->Type;
|
||||
|
@ -52,17 +52,23 @@ VOID USleep(DWORD dwMicroseconds)
|
||||
#ifndef _WIN32
|
||||
usleep(dwMicroseconds);
|
||||
#else
|
||||
UINT64 t1;
|
||||
UINT64 t2;
|
||||
UINT64 freq;
|
||||
static LARGE_INTEGER freq = { 0, 0 };
|
||||
LARGE_INTEGER t1 = { 0, 0 };
|
||||
LARGE_INTEGER t2 = { 0, 0 };
|
||||
|
||||
QueryPerformanceCounter((LARGE_INTEGER*) &t1);
|
||||
QueryPerformanceCounter((LARGE_INTEGER*) &freq);
|
||||
QueryPerformanceCounter(&t1);
|
||||
|
||||
do
|
||||
{
|
||||
QueryPerformanceCounter((LARGE_INTEGER*) &t2);
|
||||
if (freq.QuadPart == 0) {
|
||||
QueryPerformanceFrequency(&freq);
|
||||
}
|
||||
while ((t2 - t1) < dwMicroseconds);
|
||||
|
||||
// in order to save cpu cyles we use Sleep() for the large share ...
|
||||
if (dwMicroseconds >= 1000) {
|
||||
Sleep(dwMicroseconds/1000);
|
||||
}
|
||||
// ... and busy loop until all the requested micro seconds have passed
|
||||
do {
|
||||
QueryPerformanceCounter(&t2);
|
||||
} while (((t2.QuadPart - t1.QuadPart)*1000000)/freq.QuadPart < dwMicroseconds);
|
||||
#endif
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user