dfreerdp: started integrating DirectFB client

This commit is contained in:
Marc-André Moreau 2011-07-28 13:46:36 -04:00
parent 67dca12b77
commit 24ba845f04
13 changed files with 394 additions and 10 deletions

1
.gitignore vendored
View File

@ -26,3 +26,4 @@ docs/api
*.dylib *.dylib
cunit/test_freerdp cunit/test_freerdp
client/test/freerdp-test client/test/freerdp-test
client/DirectFB/dfreerdp

View File

@ -19,3 +19,9 @@
# User Interfaces # User Interfaces
add_subdirectory(test) add_subdirectory(test)
# Build DirectFB Client
find_package(DirectFB)
if(DIRECTFB_FOUND)
add_subdirectory(DirectFB)
endif()

View File

@ -0,0 +1,31 @@
# FreeRDP: A Remote Desktop Protocol Client
# FreeRDP DirectFB Client
#
# Copyright 2011 O.S. Systems Software Ltda.
# Copyright 2011 Otavio Salvador <otavio@ossystems.com.br>
# Copyright 2011 Marc-Andre Moreau <marcandre.moreau@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_directories(../../libfreerdp-gdi)
include_directories(../../libfreerdp-core)
include_directories(${DIRECTFB_INCLUDE_DIRS})
add_executable(dfreerdp
dfreerdp.c
dfreerdp.h)
target_link_libraries(dfreerdp freerdp-core)
target_link_libraries(dfreerdp freerdp-gdi)
target_link_libraries(dfreerdp freerdp-utils)
target_link_libraries(dfreerdp ${DIRECTFB_LIBRARIES})

203
client/DirectFB/dfreerdp.c Normal file
View File

@ -0,0 +1,203 @@
/**
* FreeRDP: A Remote Desktop Protocol Client
* DirectFB Client
*
* Copyright 2011 Marc-Andre Moreau <marcandre.moreau@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 "gdi.h"
#include <pthread.h>
#include <freerdp/freerdp.h>
#include <freerdp/utils/args.h>
#include <freerdp/utils/memory.h>
#include <freerdp/utils/semaphore.h>
#include "dfreerdp.h"
freerdp_sem g_sem;
static int g_thread_count = 0;
struct thread_data
{
freerdp* instance;
};
int df_begin_paint(rdpUpdate* update)
{
GDI* gdi;
gdi = GET_GDI(update);
gdi->primary->hdc->hwnd->invalid->null = 1;
return 0;
}
int df_end_paint(rdpUpdate* update)
{
GDI* gdi;
dfInfo* dfi;
gdi = GET_GDI(update);
dfi = GET_DFI(update);
if (gdi->primary->hdc->hwnd->invalid->null)
return 0;
dfi->update_rect.x = gdi->primary->hdc->hwnd->invalid->x;
dfi->update_rect.y = gdi->primary->hdc->hwnd->invalid->y;
dfi->update_rect.w = gdi->primary->hdc->hwnd->invalid->w;
dfi->update_rect.h = gdi->primary->hdc->hwnd->invalid->h;
dfi->primary->Blit(dfi->primary, dfi->surface, &(dfi->update_rect), dfi->update_rect.x, dfi->update_rect.y);
return 0;
}
boolean df_get_fds(freerdp* instance, void** rfds, int* rcount, void** wfds, int* wcount)
{
return True;
}
boolean df_check_fds(freerdp* instance)
{
return True;
}
boolean df_pre_connect(freerdp* instance)
{
dfInfo* dfi;
dfi = (dfInfo*) xzalloc(sizeof(dfInfo));
SET_DFI(instance, dfi);
return True;
}
boolean df_post_connect(freerdp* instance)
{
GDI* gdi;
dfInfo* dfi;
dfi = GET_DFI(instance);
SET_DFI(instance->update, dfi);
gdi_init(instance, CLRCONV_ALPHA | CLRBUF_16BPP | CLRBUF_32BPP);
gdi = GET_GDI(instance->update);
dfi->err = DirectFBCreate(&(dfi->dfb));
dfi->dsc.flags = DSDESC_CAPS;
dfi->dsc.caps = DSCAPS_PRIMARY;
dfi->err = dfi->dfb->CreateSurface(dfi->dfb, &(dfi->dsc), &(dfi->primary));
dfi->err = dfi->primary->GetSize(dfi->primary, &(gdi->width), &(gdi->height));
dfi->dfb->SetVideoMode(dfi->dfb, gdi->width, gdi->height, gdi->dstBpp);
dfi->dfb->CreateInputEventBuffer(dfi->dfb, DICAPS_ALL, DFB_TRUE, &(dfi->event_buffer));
dfi->event_buffer->CreateFileDescriptor(dfi->event_buffer, &(dfi->read_fds));
dfi->dfb->GetDisplayLayer(dfi->dfb, 0, &(dfi->layer));
dfi->layer->EnableCursor(dfi->layer, 1);
dfi->dsc.flags = DSDESC_CAPS | DSDESC_WIDTH | DSDESC_HEIGHT | DSDESC_PREALLOCATED | DSDESC_PIXELFORMAT;
dfi->dsc.caps = DSCAPS_SYSTEMONLY;
dfi->dsc.width = gdi->width;
dfi->dsc.height = gdi->height;
if (gdi->dstBpp == 32 || gdi->dstBpp == 24)
dfi->dsc.pixelformat = DSPF_AiRGB;
else if (gdi->dstBpp == 16 || gdi->dstBpp == 15)
dfi->dsc.pixelformat = DSPF_RGB16;
else if (gdi->dstBpp == 8)
dfi->dsc.pixelformat = DSPF_RGB332;
else
dfi->dsc.pixelformat = DSPF_AiRGB;
dfi->dsc.preallocated[0].data = gdi->primary_buffer;
dfi->dsc.preallocated[0].pitch = gdi->width * gdi->bytesPerPixel;
dfi->dfb->CreateSurface(dfi->dfb, &(dfi->dsc), &(dfi->surface));
instance->update->BeginPaint = df_begin_paint;
instance->update->EndPaint = df_end_paint;
return True;
}
int dfreerdp_run(freerdp* instance)
{
int rcount;
int wcount;
void* rfds[32];
void* wfds[32];
fd_set rfds_set;
fd_set wfds_set;
memset(rfds, 0, sizeof(rfds));
memset(wfds, 0, sizeof(wfds));
printf("DirectFB Run\n");
instance->Connect(instance);
freerdp_free(instance);
return 0;
}
void* thread_func(void* param)
{
struct thread_data* data;
data = (struct thread_data*) param;
dfreerdp_run(data->instance);
xfree(data);
pthread_detach(pthread_self());
g_thread_count--;
if (g_thread_count < 1)
freerdp_sem_signal(&g_sem);
return NULL;
}
int main(int argc, char* argv[])
{
pthread_t thread;
freerdp* instance;
struct thread_data* data;
g_sem = freerdp_sem_new(1);
instance = freerdp_new();
instance->PreConnect = df_pre_connect;
instance->PostConnect = df_post_connect;
DirectFBInit(&argc, &argv);
freerdp_parse_args(instance->settings, argc, argv, NULL, NULL, NULL, NULL);
data = (struct thread_data*) xzalloc(sizeof(struct thread_data));
data->instance = instance;
g_thread_count++;
pthread_create(&thread, 0, thread_func, data);
while (g_thread_count > 0)
{
freerdp_sem_wait(g_sem);
}
return 0;
}

View File

@ -0,0 +1,45 @@
/**
* FreeRDP: A Remote Desktop Protocol Client
* DirectFB Client
*
* Copyright 2011 Marc-Andre Moreau <marcandre.moreau@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 __DFREERDP_H
#define __DFREERDP_H
#include <stdio.h>
#include <unistd.h>
#include <directfb.h>
#define SET_DFI(_instance, _dfi) (_instance)->param1 = _dfi
#define GET_DFI(_instance) ((dfInfo *) ((_instance)->param1))
struct df_info
{
int read_fds;
DFBResult err;
IDirectFB* dfb;
DFBEvent event;
DFBRectangle update_rect;
DFBSurfaceDescription dsc;
IDirectFBSurface* primary;
IDirectFBSurface* surface;
IDirectFBDisplayLayer* layer;
IDirectFBEventBuffer* event_buffer;
};
typedef struct df_info dfInfo;
#endif /* __DFREERDP_H */

49
cmake/FindDirectFB.cmake Normal file
View File

@ -0,0 +1,49 @@
# - Find DirectFB
# Find the DirectFB libraries
#
# This module defines the following variables:
# DIRECTFB_FOUND - True if DIRECTFB_INCLUDE_DIR & DIRECTFB_LIBRARY are found
# DIRECTFB_LIBRARIES - Set when DIRECTFB_LIBRARY is found
# DIRECTFB_INCLUDE_DIRS - Set when DIRECTFB_INCLUDE_DIR is found
#
# DIRECTFB_INCLUDE_DIR - where to find CUnit.h, etc.
# DIRECTFB_LIBRARY - the cunit library
#
#=============================================================================
# Copyright 2011 O.S. Systems Software Ltda.
# Copyright 2011 Otavio Salvador <otavio@ossystems.com.br>
# Copyright 2011 Marc-Andre Moreau <marcandre.moreau@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.
#=============================================================================
find_path(DIRECTFB_INCLUDE_DIR NAMES directfb.h
PATH_SUFFIXES directfb
DOC "The directfb include directory"
)
find_library(DIRECTFB_LIBRARY NAMES directfb
DOC "The DirectFB library"
)
include(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(DIRECTFB DEFAULT_MSG DIRECTFB_LIBRARY DIRECTFB_INCLUDE_DIR)
if(DIRECTFB_FOUND)
set( DIRECTFB_LIBRARIES ${DIRECTFB_LIBRARY} )
set( DIRECTFB_INCLUDE_DIRS ${DIRECTFB_INCLUDE_DIR} )
endif()
mark_as_advanced(DIRECTFB_INCLUDE_DIR DIRECTFB_LIBRARY)

View File

@ -38,6 +38,10 @@ FREERDP_API void freerdp_global_finish();
typedef struct rdp_freerdp freerdp; typedef struct rdp_freerdp freerdp;
typedef boolean (*pcConnect)(freerdp* freerdp); typedef boolean (*pcConnect)(freerdp* freerdp);
typedef boolean (*pcPreConnect)(freerdp* freerdp);
typedef boolean (*pcPostConnect)(freerdp* freerdp);
typedef boolean (*pcGetFileDescriptor)(freerdp* freerdp, void** rfds, int* rcount, void** wfds, int* wcount);
typedef boolean (*pcCheckFileDescriptor)(freerdp* freerdp);
typedef int (*pcChannelDataInput)(freerdp* freerdp, int channelId, uint8* data, int size); typedef int (*pcChannelDataInput)(freerdp* freerdp, int channelId, uint8* data, int size);
struct rdp_freerdp struct rdp_freerdp
@ -53,6 +57,10 @@ struct rdp_freerdp
rdpSettings* settings; rdpSettings* settings;
pcConnect Connect; pcConnect Connect;
pcPreConnect PreConnect;
pcPostConnect PostConnect;
pcGetFileDescriptor GetFileDescriptor;
pcCheckFileDescriptor CheckFileDescriptor;
pcChannelDataInput ChannelDataInput; pcChannelDataInput ChannelDataInput;
}; };

View File

@ -378,6 +378,8 @@ typedef struct
typedef struct rdp_update rdpUpdate; typedef struct rdp_update rdpUpdate;
typedef int (*pcBeginPaint)(rdpUpdate* update);
typedef int (*pcEndPaint)(rdpUpdate* update);
typedef int (*pcSynchronize)(rdpUpdate* update); typedef int (*pcSynchronize)(rdpUpdate* update);
typedef int (*pcBitmap)(rdpUpdate* update, BITMAP_UPDATE* bitmap); typedef int (*pcBitmap)(rdpUpdate* update, BITMAP_UPDATE* bitmap);
typedef int (*pcPalette)(rdpUpdate* update, PALETTE_UPDATE* palette); typedef int (*pcPalette)(rdpUpdate* update, PALETTE_UPDATE* palette);
@ -407,9 +409,12 @@ typedef int (*pcGlyphIndex)(rdpUpdate* update, GLYPH_INDEX_ORDER* glyph_index);
struct rdp_update struct rdp_update
{ {
void* rdp; void* rdp;
void* gdi;
void* param1; void* param1;
void* param2; void* param2;
pcBeginPaint BeginPaint;
pcEndPaint EndPaint;
pcSynchronize Synchronize; pcSynchronize Synchronize;
pcBitmap Bitmap; pcBitmap Bitmap;
pcPalette Palette; pcPalette Palette;

View File

@ -96,11 +96,6 @@ boolean rdp_client_connect(rdpRdp* rdp)
rdp_client_activate(rdp); rdp_client_activate(rdp);
while(1)
{
rdp_recv(rdp);
}
return True; return True;
} }

View File

@ -20,6 +20,7 @@
#include "rdp.h" #include "rdp.h"
#include "input.h" #include "input.h"
#include "update.h" #include "update.h"
#include "transport.h"
#include "connection.h" #include "connection.h"
#include <freerdp/freerdp.h> #include <freerdp/freerdp.h>
@ -27,7 +28,41 @@
boolean freerdp_connect(freerdp* instance) boolean freerdp_connect(freerdp* instance)
{ {
return rdp_client_connect((rdpRdp*) instance->rdp); rdpRdp* rdp;
boolean status;
rdp = (rdpRdp*) instance->rdp;
IFCALL(instance->PreConnect, instance);
status = rdp_client_connect((rdpRdp*) instance->rdp);
IFCALL(instance->PostConnect, instance);
while(1)
{
rdp_recv(rdp);
}
return status;
}
boolean freerdp_get_fds(freerdp* instance, void** rfds, int* rcount, void** wfds, int* wcount)
{
rdpRdp* rdp;
rdp = (rdpRdp*) instance->rdp;
rfds[*rcount] = (void*)(long)(rdp->transport->tcp->sockfd);
(*rcount)++;
return True;
}
boolean freerdp_check_fds(freerdp* instance)
{
rdpRdp* rdp;
rdp = (rdpRdp*) instance->rdp;
return True;
} }
freerdp* freerdp_new() freerdp* freerdp_new()
@ -45,6 +80,8 @@ freerdp* freerdp_new()
instance->settings = rdp->settings; instance->settings = rdp->settings;
instance->Connect = freerdp_connect; instance->Connect = freerdp_connect;
instance->GetFileDescriptor = freerdp_get_fds;
instance->CheckFileDescriptor = freerdp_check_fds;
} }
return instance; return instance;

View File

@ -153,6 +153,8 @@ void update_recv(rdpUpdate* update, STREAM* s)
//printf("%s Update Data PDU\n", UPDATE_TYPE_STRINGS[updateType]); //printf("%s Update Data PDU\n", UPDATE_TYPE_STRINGS[updateType]);
IFCALL(update->BeginPaint, update);
switch (updateType) switch (updateType)
{ {
case UPDATE_TYPE_ORDERS: case UPDATE_TYPE_ORDERS:
@ -174,6 +176,8 @@ void update_recv(rdpUpdate* update, STREAM* s)
IFCALL(update->Synchronize, update); IFCALL(update->Synchronize, update);
break; break;
} }
IFCALL(update->EndPaint, update);
} }
rdpUpdate* update_new(rdpRdp* rdp) rdpUpdate* update_new(rdpRdp* rdp)

View File

@ -1195,7 +1195,7 @@ int gdi_init(freerdp* instance, uint32 flags)
void gdi_free(freerdp* instance) void gdi_free(freerdp* instance)
{ {
GDI *gdi = GET_GDI(instance); GDI *gdi = GET_GDI(instance->update);
if (gdi) if (gdi)
{ {
@ -1205,6 +1205,6 @@ void gdi_free(freerdp* instance)
free(gdi); free(gdi);
} }
SET_GDI(instance, NULL); SET_GDI(instance->update, NULL);
} }

View File

@ -256,8 +256,8 @@ void gdi_bitmap_free(GDI_IMAGE *gdi_bmp);
int gdi_init(freerdp* instance, uint32 flags); int gdi_init(freerdp* instance, uint32 flags);
void gdi_free(freerdp* instance); void gdi_free(freerdp* instance);
#define SET_GDI(_instance, _gdi) (_instance)->param1 = _gdi #define SET_GDI(_instance, _gdi) (_instance)->gdi = _gdi
#define GET_GDI(_instance) ((GDI*) ((_instance)->param1)) #define GET_GDI(_instance) ((GDI*) ((_instance)->gdi))
#ifdef WITH_DEBUG_GDI #ifdef WITH_DEBUG_GDI
#define DEBUG_GDI(fmt, ...) DEBUG_CLASS(GDI, fmt, ## __VA_ARGS__) #define DEBUG_GDI(fmt, ...) DEBUG_CLASS(GDI, fmt, ## __VA_ARGS__)