From 72b48585fb80d79f6d5b42c0ceb6f36f6dff55db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Thu, 28 Jul 2011 17:44:09 -0400 Subject: [PATCH] dfreerdp: start working on file descriptors --- client/DirectFB/CMakeLists.txt | 2 + client/DirectFB/df_event.c | 90 ++++++++++++++++++++++++++++++++++ client/DirectFB/df_event.h | 27 ++++++++++ client/DirectFB/dfreerdp.c | 88 +++++++++++++++++++++++++++++++-- client/DirectFB/dfreerdp.h | 2 + libfreerdp-core/activation.c | 16 ++++++ libfreerdp-core/activation.h | 1 + libfreerdp-core/capabilities.c | 10 ---- libfreerdp-core/capabilities.h | 1 - libfreerdp-core/freerdp.c | 7 +-- libfreerdp-core/transport.c | 53 -------------------- 11 files changed, 225 insertions(+), 72 deletions(-) create mode 100644 client/DirectFB/df_event.c create mode 100644 client/DirectFB/df_event.h diff --git a/client/DirectFB/CMakeLists.txt b/client/DirectFB/CMakeLists.txt index 8a871402a..68336392f 100644 --- a/client/DirectFB/CMakeLists.txt +++ b/client/DirectFB/CMakeLists.txt @@ -22,6 +22,8 @@ include_directories(../../libfreerdp-core) include_directories(${DIRECTFB_INCLUDE_DIRS}) add_executable(dfreerdp + df_event.c + df_event.h dfreerdp.c dfreerdp.h) diff --git a/client/DirectFB/df_event.c b/client/DirectFB/df_event.c new file mode 100644 index 000000000..b68d1cd68 --- /dev/null +++ b/client/DirectFB/df_event.c @@ -0,0 +1,90 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * DirectFB Event Handling + * + * 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. + */ + +#include "df_event.h" + +boolean df_event_process(freerdp* instance, DFBEvent* event) +{ + GDI* gdi; + dfInfo* dfi; + int keycode; + int pointer_x; + int pointer_y; + int flags; + DFBInputEvent* input_event; + + dfi = GET_DFI(instance); + gdi = GET_GDI(instance->update); + + printf("process event\n"); + + dfi->layer->GetCursorPosition(dfi->layer, &pointer_x, &pointer_y); + + if (event->clazz == DFEC_INPUT) + { + flags = 0; + input_event = (DFBInputEvent *) event; + + switch (input_event->type) + { + case DIET_AXISMOTION: + + if (pointer_x > (gdi->width - 1)) + pointer_x = gdi->width - 1; + + if (pointer_y > (gdi->height - 1)) + pointer_y = gdi->height - 1; + + break; + + case DIET_BUTTONPRESS: + flags = PTR_FLAGS_DOWN; + /* fall */ + + case DIET_BUTTONRELEASE: + + if (input_event->button == DIBI_LEFT) + flags |= PTR_FLAGS_BUTTON1; + else if (input_event->button == DIBI_RIGHT) + flags |= PTR_FLAGS_BUTTON2; + else if (input_event->button == DIBI_MIDDLE) + flags |= PTR_FLAGS_BUTTON3; + + if (flags != 0) + instance->input->MouseEvent(instance->input, flags, pointer_x, pointer_y); + + break; + + case DIET_KEYPRESS: + keycode = input_event->key_id - DIKI_UNKNOWN; + + break; + + case DIET_KEYRELEASE: + keycode = input_event->key_id - DIKI_UNKNOWN; + + break; + + case DIET_UNKNOWN: + break; + } + } + + return True; +} diff --git a/client/DirectFB/df_event.h b/client/DirectFB/df_event.h new file mode 100644 index 000000000..9df1511b6 --- /dev/null +++ b/client/DirectFB/df_event.h @@ -0,0 +1,27 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * DirectFB Event Handling + * + * 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 __DF_EVENT_H +#define __DF_EVENT_H + +#include "dfreerdp.h" + +boolean df_event_process(freerdp* instance, DFBEvent* event); + +#endif /* __DF_EVENT_H */ diff --git a/client/DirectFB/dfreerdp.c b/client/DirectFB/dfreerdp.c index 651a5e942..41a577e05 100644 --- a/client/DirectFB/dfreerdp.c +++ b/client/DirectFB/dfreerdp.c @@ -17,13 +17,14 @@ * limitations under the License. */ -#include "gdi.h" +#include #include -#include #include #include #include +#include "df_event.h" + #include "dfreerdp.h" freerdp_sem g_sem; @@ -63,11 +64,28 @@ void df_end_paint(rdpUpdate* update) boolean df_get_fds(freerdp* instance, void** rfds, int* rcount, void** wfds, int* wcount) { + dfInfo* dfi; + + dfi = GET_DFI(instance); + + rfds[*rcount] = (void*)(long)(dfi->read_fds); + (*rcount)++; + return True; } -boolean df_check_fds(freerdp* instance) +boolean df_check_fds(freerdp* instance, fd_set* set) { + dfInfo* dfi; + + dfi = GET_DFI(instance); + + if (!FD_ISSET(dfi->read_fds, set)) + return True; + + if (read(dfi->read_fds, &(dfi->event), sizeof(dfi->event)) > 0) + df_event_process(instance, &(dfi->event)); + return True; } @@ -131,6 +149,9 @@ boolean df_post_connect(freerdp* instance) int dfreerdp_run(freerdp* instance) { + int i; + int fds; + int max_fds; int rcount; int wcount; void* rfds[32]; @@ -145,6 +166,67 @@ int dfreerdp_run(freerdp* instance) instance->Connect(instance); + int count = 0; + + while (1) + { + rcount = 0; + wcount = 0; + + printf("loop... %d\n", count++); + + if (instance->GetFileDescriptor(instance, rfds, &rcount, wfds, &wcount) != True) + { + printf("Failed to get FreeRDP file descriptor\n"); + break; + } + if (df_get_fds(instance, rfds, &rcount, wfds, &wcount) != True) + { + printf("Failed to get dfreerdp 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, &wfds_set); + } + + if (max_fds == 0) + break; + + if (select(max_fds + 1, &rfds_set, &wfds_set, NULL, NULL) == -1) + { + /* these are not really errors */ + if (!((errno == EAGAIN) || + (errno == EWOULDBLOCK) || + (errno == EINPROGRESS) || + (errno == EINTR))) /* signal occurred */ + { + printf("dfreerdp_run: select failed\n"); + break; + } + } + + if (instance->CheckFileDescriptor(instance) != True) + { + printf("Failed to check FreeRDP file descriptor\n"); + break; + } + if (df_check_fds(instance, &rfds_set) != True) + { + printf("Failed to check dfreerdp file descriptor\n"); + break; + } + } + freerdp_free(instance); return 0; diff --git a/client/DirectFB/dfreerdp.h b/client/DirectFB/dfreerdp.h index 3a3944fea..816006baf 100644 --- a/client/DirectFB/dfreerdp.h +++ b/client/DirectFB/dfreerdp.h @@ -20,9 +20,11 @@ #ifndef __DFREERDP_H #define __DFREERDP_H +#include "gdi.h" #include #include #include +#include #define SET_DFI(_instance, _dfi) (_instance)->param1 = _dfi #define GET_DFI(_instance) ((dfInfo *) ((_instance)->param1)) diff --git a/libfreerdp-core/activation.c b/libfreerdp-core/activation.c index 319f0fe69..95cf9d9da 100644 --- a/libfreerdp-core/activation.c +++ b/libfreerdp-core/activation.c @@ -170,4 +170,20 @@ void rdp_send_client_font_list_pdu(rdpRdp* rdp, uint16 flags) void rdp_recv_server_font_map_pdu(rdpRdp* rdp, STREAM* s, rdpSettings* settings) { rdp->activated = True; + rdp->transport->tcp->set_blocking_mode(rdp->transport->tcp, False); } + +void rdp_recv_deactivate_all(rdpRdp* rdp, STREAM* s) +{ + uint16 lengthSourceDescriptor; + + printf("Deactivate All PDU\n"); + + stream_read_uint32(s, rdp->settings->share_id); /* shareId (4 bytes) */ + stream_read_uint16(s, lengthSourceDescriptor); /* lengthSourceDescriptor (2 bytes) */ + stream_seek(s, lengthSourceDescriptor); /* sourceDescriptor (should be 0x00) */ + + rdp->activated = False; + rdp->transport->tcp->set_blocking_mode(rdp->transport->tcp, True); +} + diff --git a/libfreerdp-core/activation.h b/libfreerdp-core/activation.h index 4fc7fbf0b..ba8c741d4 100644 --- a/libfreerdp-core/activation.h +++ b/libfreerdp-core/activation.h @@ -39,6 +39,7 @@ #define FONTLIST_LAST 0x0002 boolean rdp_client_activate(rdpRdp* rdp); +void rdp_recv_deactivate_all(rdpRdp* rdp, STREAM* s); void rdp_recv_server_synchronize_pdu(rdpRdp* rdp, STREAM* s, rdpSettings* settings); void rdp_send_client_synchronize_pdu(rdpRdp* rdp); diff --git a/libfreerdp-core/capabilities.c b/libfreerdp-core/capabilities.c index 2485defab..8cd22ab32 100644 --- a/libfreerdp-core/capabilities.c +++ b/libfreerdp-core/capabilities.c @@ -1640,13 +1640,3 @@ void rdp_send_confirm_active(rdpRdp* rdp) rdp_send_pdu(rdp, s, PDU_TYPE_CONFIRM_ACTIVE, MCS_BASE_CHANNEL_ID + rdp->mcs->user_id); } -void rdp_recv_deactivate_all(rdpRdp* rdp, STREAM* s) -{ - uint16 lengthSourceDescriptor; - - printf("Deactivate All PDU\n"); - - stream_read_uint32(s, rdp->settings->share_id); /* shareId (4 bytes) */ - stream_read_uint16(s, lengthSourceDescriptor); /* lengthSourceDescriptor (2 bytes) */ - stream_seek(s, lengthSourceDescriptor); /* sourceDescriptor (should be 0x00) */ -} diff --git a/libfreerdp-core/capabilities.h b/libfreerdp-core/capabilities.h index cc2c5ed14..c2508aaed 100644 --- a/libfreerdp-core/capabilities.h +++ b/libfreerdp-core/capabilities.h @@ -183,6 +183,5 @@ void rdp_read_demand_active(STREAM* s, rdpSettings* settings); void rdp_recv_demand_active(rdpRdp* rdp, STREAM* s, rdpSettings* settings); void rdp_write_confirm_active(STREAM* s, rdpSettings* settings); void rdp_send_confirm_active(rdpRdp* rdp); -void rdp_recv_deactivate_all(rdpRdp* rdp, STREAM* s); #endif /* __CAPABILITIES_H */ diff --git a/libfreerdp-core/freerdp.c b/libfreerdp-core/freerdp.c index 5f33a185d..ce75572dc 100644 --- a/libfreerdp-core/freerdp.c +++ b/libfreerdp-core/freerdp.c @@ -37,11 +37,6 @@ boolean freerdp_connect(freerdp* instance) status = rdp_client_connect((rdpRdp*) instance->rdp); IFCALL(instance->PostConnect, instance); - while(1) - { - rdp_recv(rdp); - } - return status; } @@ -62,6 +57,8 @@ boolean freerdp_check_fds(freerdp* instance) rdp = (rdpRdp*) instance->rdp; + rdp_recv(rdp); + return True; } diff --git a/libfreerdp-core/transport.c b/libfreerdp-core/transport.c index aacd96221..45cebd77c 100644 --- a/libfreerdp-core/transport.c +++ b/libfreerdp-core/transport.c @@ -149,59 +149,6 @@ int transport_write(rdpTransport* transport, STREAM* s) int transport_check_fds(rdpTransport* transport) { - int pos; - int bytes; - uint16 length; - STREAM* received; - - bytes = transport_read(transport, transport->recv_buffer); - - if (bytes <= 0) - return bytes; - - while ((pos = stream_get_pos(transport->recv_buffer)) > 0) - { - /* Ensure the TPKT header is available. */ - if (pos <= 4) - return 0; - - stream_set_pos(transport->recv_buffer, 0); - length = tpkt_read_header(transport->recv_buffer); - - if (length == 0) - { - printf("transport_check_fds: protocol error, not a TPKT header.\n"); - return -1; - } - - if (pos < length) - { - stream_set_pos(transport->recv_buffer, pos); - return 0; /* Packet is not yet completely received. */ - } - - /* - * A complete packet has been received. In case there are trailing data - * for the next packet, we copy it to the new receive buffer. - */ - received = transport->recv_buffer; - transport->recv_buffer = stream_new(BUFFER_SIZE); - - if (pos > length) - { - stream_set_pos(received, length); - stream_check_size(transport->recv_buffer, pos - length); - stream_copy(transport->recv_buffer, received, pos - length); - } - - stream_set_pos(received, 0); - bytes = transport->recv_callback(transport, received, transport->recv_extra); - stream_free(received); - - if (bytes < 0) - return bytes; - } - return 0; }