dfreerdp: start working on file descriptors
authorMarc-André Moreau <marcandre.moreau@gmail.com>
Thu, 28 Jul 2011 21:44:09 +0000 (17:44 -0400)
committerMarc-André Moreau <marcandre.moreau@gmail.com>
Thu, 28 Jul 2011 21:44:09 +0000 (17:44 -0400)
client/DirectFB/CMakeLists.txt
client/DirectFB/df_event.c [new file with mode: 0644]
client/DirectFB/df_event.h [new file with mode: 0644]
client/DirectFB/dfreerdp.c
client/DirectFB/dfreerdp.h
libfreerdp-core/activation.c
libfreerdp-core/activation.h
libfreerdp-core/capabilities.c
libfreerdp-core/capabilities.h
libfreerdp-core/freerdp.c
libfreerdp-core/transport.c

index 8a87140..6833639 100644 (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)
 
diff --git a/client/DirectFB/df_event.c b/client/DirectFB/df_event.c
new file mode 100644 (file)
index 0000000..b68d1cd
--- /dev/null
@@ -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;
+}
diff --git a/client/DirectFB/df_event.h b/client/DirectFB/df_event.h
new file mode 100644 (file)
index 0000000..9df1511
--- /dev/null
@@ -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 */
index 651a5e9..41a577e 100644 (file)
  * 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;
index 3a3944f..816006b 100644 (file)
 #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))
index 319f0fe..95cf9d9 100644 (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);
+}
+
index 4fc7fbf..ba8c741 100644 (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);
index 2485def..8cd22ab 100644 (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) */
-}
index cc2c5ed..c2508aa 100644 (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 */
index 5f33a18..ce75572 100644 (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;
 }
 
index aacd962..45cebd7 100644 (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;
 }