dfreerdp: start working on file descriptors

This commit is contained in:
Marc-André Moreau
2011-07-28 17:44:09 -04:00
parent 97f8a022a9
commit 72b48585fb
11 changed files with 225 additions and 72 deletions

View File

@@ -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)

View File

@@ -0,0 +1,90 @@
/**
* FreeRDP: A Remote Desktop Protocol Client
* DirectFB Event Handling
*
* 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 "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;
}

View File

@@ -0,0 +1,27 @@
/**
* FreeRDP: A Remote Desktop Protocol Client
* DirectFB Event Handling
*
* 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 __DF_EVENT_H
#define __DF_EVENT_H
#include "dfreerdp.h"
boolean df_event_process(freerdp* instance, DFBEvent* event);
#endif /* __DF_EVENT_H */

View File

@@ -17,13 +17,14 @@
* limitations under the License.
*/
#include "gdi.h"
#include <errno.h>
#include <pthread.h>
#include <freerdp/freerdp.h>
#include <freerdp/utils/args.h>
#include <freerdp/utils/memory.h>
#include <freerdp/utils/semaphore.h>
#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;

View File

@@ -20,9 +20,11 @@
#ifndef __DFREERDP_H
#define __DFREERDP_H
#include "gdi.h"
#include <stdio.h>
#include <unistd.h>
#include <directfb.h>
#include <freerdp/freerdp.h>
#define SET_DFI(_instance, _dfi) (_instance)->param1 = _dfi
#define GET_DFI(_instance) ((dfInfo *) ((_instance)->param1))

View File

@@ -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);
}

View File

@@ -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);

View File

@@ -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) */
}

View File

@@ -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 */

View File

@@ -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;
}

View File

@@ -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;
}