diff --git a/server/Mac/CMakeLists.txt b/server/Mac/CMakeLists.txt index 3714e1e18..39a43a7a4 100644 --- a/server/Mac/CMakeLists.txt +++ b/server/Mac/CMakeLists.txt @@ -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} diff --git a/server/Mac/mf_info.c b/server/Mac/mf_info.c index fbeafe0b8..881e09ec3 100644 --- a/server/Mac/mf_info.c +++ b/server/Mac/mf_info.c @@ -26,6 +26,7 @@ #include #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) diff --git a/server/Mac/mf_mountain_lion.c b/server/Mac/mf_mountain_lion.c new file mode 100644 index 000000000..6ddecdd4c --- /dev/null +++ b/server/Mac/mf_mountain_lion.c @@ -0,0 +1,180 @@ +/** + * FreeRDP: A Remote Desktop Protocol Implementation + * OS X Server Event Handling + * + * 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. + */ + +#include +#include + +#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; +} \ No newline at end of file diff --git a/server/Mac/mf_mountain_lion.h b/server/Mac/mf_mountain_lion.h new file mode 100644 index 000000000..197a8c74e --- /dev/null +++ b/server/Mac/mf_mountain_lion.h @@ -0,0 +1,34 @@ +/** + * FreeRDP: A Remote Desktop Protocol Implementation + * OS X Server Event Handling + * + * 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_MLION_H +#define MF_MLION_H + +#include + + +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 \ No newline at end of file