mfreerdp-server: add displaystream functionality

This commit is contained in:
C-o-r-E 2012-11-15 18:09:20 -05:00
parent 7c84bdbed5
commit a05ccaa656
4 changed files with 230 additions and 6 deletions

View File

@ -32,7 +32,9 @@ set(${MODULE_PREFIX}_SRCS
mf_peer.c
mf_peer.h
mf_info.c
mf_info.h)
mf_info.h
mf_mountain_lion.c
mf_mountain_lion.h)
if(CHANNEL_AUDIN_SERVER)
set(${MODULE_PREFIX}_SRCS ${${MODULE_PREFIX}_SRCS}

View File

@ -26,6 +26,7 @@
#include <errno.h>
#include "mf_info.h"
#include "mf_mountain_lion.h"
//#include "mf_update.h"
static mfInfo* mfInfoInstance = NULL;
@ -244,23 +245,30 @@ void mf_info_update_changes(mfInfo* mfi)
void mf_info_find_invalid_region(mfInfo* mfi)
{
//fixme
mf_mlion_get_dirty_region(&mfi->invalid);
}
void mf_info_clear_invalid_region(mfInfo* mfi)
{
//mfi->lastUpdate = mfi->nextUpdate;
//SetRectEmpty(&mfi->invalid);
mf_mlion_clear_dirty_region();
mfi->invalid.height = 0;
mfi->invalid.width = 0;
}
void mf_info_invalidate_full_screen(mfInfo* mfi)
{
//SetRect(&mfi->invalid, 0, 0, mfi->servscreen_width, mfi->servscreen_height);
mfi->invalid.x = 0;
mfi->invalid.y = 0;
mfi->invalid.height = mfi->servscreen_height;
mfi->invalid.height = mfi->servscreen_width;
}
BOOL mf_info_have_invalid_region(mfInfo* mfi)
{
//return IsRectEmpty(&mfi->invalid);
if (mfi->invalid.width * mfi->invalid.height == 0) {
return FALSE;
}
return TRUE;
}
void mf_info_getScreenData(mfInfo* mfi, long* width, long* height, BYTE** pBits, int* pitch)

View File

@ -0,0 +1,180 @@
/**
* FreeRDP: A Remote Desktop Protocol Implementation
* OS X Server Event Handling
*
* Copyright 2012 Corey Clayton <can.of.tuna@gmail.com>
*
* 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 <dispatch/dispatch.h>
#include <CoreGraphics/CoreGraphics.h>
#include "mf_mountain_lion.h"
dispatch_semaphore_t region_sem;
dispatch_queue_t screen_update_q;
CGDisplayStreamRef stream;
bool clean;
CGRect dirtyRegion;
void (^streamHandler)(CGDisplayStreamFrameStatus, uint64_t, IOSurfaceRef, CGDisplayStreamUpdateRef) = ^(CGDisplayStreamFrameStatus status, uint64_t displayTime, IOSurfaceRef frameSurface, CGDisplayStreamUpdateRef updateRef)
{
/*
if(displayTime - last_time < 500000000)
return;
last_time = displayTime;
*/
/*
printf("\tstatus: ");
switch(status)
{
case kCGDisplayStreamFrameStatusFrameComplete:
printf("Complete\n");
break;
case kCGDisplayStreamFrameStatusFrameIdle:
printf("Idle\n");
break;
case kCGDisplayStreamFrameStatusFrameBlank:
printf("Blank\n");
break;
case kCGDisplayStreamFrameStatusStopped:
printf("Stopped\n");
break;
}
printf("\ttime: %lld\n", displayTime);
*/
const CGRect * rects;
size_t num_rects;
rects = CGDisplayStreamUpdateGetRects(updateRef, kCGDisplayStreamUpdateDirtyRects, &num_rects);
//printf("\trectangles: %zd\n", num_rects);
dispatch_semaphore_wait(region_sem, DISPATCH_TIME_FOREVER);
if(clean == TRUE)
dirtyRegion = *rects;
for (size_t i = 0; i < num_rects; i++)
{
/*
printf("\t\t(%f,%f),(%f,%f)\n\n",
(rects+i)->origin.x,
(rects+i)->origin.y,
(rects+i)->origin.x + (rects+i)->size.width,
(rects+i)->origin.y + (rects+i)->size.height);
*/
dirtyRegion = CGRectUnion(dirtyRegion, *(rects+i));
}
/*
printf("\t\tUnion: (%f,%f),(%f,%f)\n\n",
uRect.origin.x,
uRect.origin.y,
uRect.origin.x + uRect.size.width,
uRect.origin.y + uRect.size.height);
*/
clean = FALSE;
dispatch_semaphore_signal(region_sem);
};
int mf_mlion_screen_updates_init()
{
CGDirectDisplayID display_id;
display_id = CGMainDisplayID();
screen_update_q = dispatch_queue_create("mfreerdp.server.screenUpdate", NULL);
region_sem = dispatch_semaphore_create(1);
CGDisplayModeRef mode = CGDisplayCopyDisplayMode(display_id);
size_t pixelWidth = CGDisplayModeGetPixelWidth(mode);
size_t pixelHeight = CGDisplayModeGetPixelHeight(mode);
CGDisplayModeRelease(mode);
stream = CGDisplayStreamCreateWithDispatchQueue(display_id,
pixelWidth,
pixelHeight,
'BGRA',
NULL,
screen_update_q,
streamHandler);
clean = TRUE;
return 0;
}
int mf_mlion_start_getting_screen_updates()
{
CGDisplayStreamStart(stream);
return 0;
}
int mf_mlion_stop_getting_screen_updates()
{
CGDisplayStreamStop(stream);
return 0;
}
int mf_mlion_get_dirty_region(RFX_RECT* invalid)
{
//it may be faster to copy the cgrect and then convert....
dispatch_semaphore_wait(region_sem, DISPATCH_TIME_FOREVER);
invalid->x = dirtyRegion.origin.x;
invalid->y = dirtyRegion.origin.y;
invalid->height = dirtyRegion.size.height;
invalid->width = dirtyRegion.size.width;
dispatch_semaphore_signal(region_sem);
return 0;
}
int mf_mlion_clear_dirty_region()
{
dispatch_semaphore_wait(region_sem, DISPATCH_TIME_FOREVER);
clean = TRUE;
dirtyRegion.size.width = 0;
dirtyRegion.size.height = 0;
dispatch_semaphore_signal(region_sem);
return 0;
}

View File

@ -0,0 +1,34 @@
/**
* FreeRDP: A Remote Desktop Protocol Implementation
* OS X Server Event Handling
*
* Copyright 2012 Corey Clayton <can.of.tuna@gmail.com>
*
* 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_MLION_H
#define MF_MLION_H
#include <freerdp/codec/rfx.h>
int mf_mlion_screen_updates_init();
int mf_mlion_start_getting_screen_updates();
int mf_mlion_stop_getting_screen_updates();
int mf_mlion_get_dirty_region(RFX_RECT* invalid);
int mf_mlion_clear_dirty_region();
#endif