diff --git a/server/X11/CMakeLists.txt b/server/X11/CMakeLists.txt index 799b58e18e8e..1aa0f94cfcb3 100644 --- a/server/X11/CMakeLists.txt +++ b/server/X11/CMakeLists.txt @@ -23,9 +23,15 @@ include_directories("../../winpr/tools/makecert") set(${MODULE_PREFIX}_SRCS xf_peer.c + xf_peer.h xf_input.c + xf_input.h xf_encode.c - xfreerdp.c) + xf_encode.h + xf_interface.c + xf_interface.h + xfreerdp.c + xfreerdp.h) add_executable(${MODULE_NAME} ${${MODULE_PREFIX}_SRCS}) diff --git a/server/X11/xf_interface.c b/server/X11/xf_interface.c new file mode 100644 index 000000000000..2d70b3c1c83f --- /dev/null +++ b/server/X11/xf_interface.c @@ -0,0 +1,153 @@ +/** + * FreeRDP: A Remote Desktop Protocol Implementation + * FreeRDP X11 Server Interface + * + * Copyright 2013 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 +#include +#include +#include +#include +#include +#include +#include + +#include "xf_peer.h" +#include "xfreerdp.h" + +#include "xf_interface.h" + +void* xf_server_thread(void* param) +{ + int i; + int fds; + int max_fds; + int rcount; + void* rfds[32]; + fd_set rfds_set; + xfServer* server; + freerdp_listener* listener; + + ZeroMemory(rfds, sizeof(rfds)); + + server = (xfServer*) param; + listener = server->listener; + + while (1) + { + rcount = 0; + + if (listener->GetFileDescriptor(listener, rfds, &rcount) != TRUE) + { + fprintf(stderr, "Failed to get FreeRDP 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, &rfds_set); + } + + if (max_fds == 0) + break; + + if (select(max_fds + 1, &rfds_set, NULL, NULL, NULL) == -1) + { + /* these are not really errors */ + if (!((errno == EAGAIN) || + (errno == EWOULDBLOCK) || + (errno == EINPROGRESS) || + (errno == EINTR))) /* signal occurred */ + { + fprintf(stderr, "select failed\n"); + break; + } + } + + if (listener->CheckFileDescriptor(listener) != TRUE) + { + fprintf(stderr, "Failed to check FreeRDP file descriptor\n"); + break; + } + } + + listener->Close(listener); + + return NULL; +} + +int freerdp_server_global_init() +{ + /* + * ignore SIGPIPE, otherwise an SSL_write failure could crash the server + */ + signal(SIGPIPE, SIG_IGN); + + return 0; +} + +int freerdp_server_global_uninit() +{ + return 0; +} + +int freerdp_server_start(xfServer* server) +{ + if (server->listener->Open(server->listener, NULL, 3389)) + { + server->thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) xf_thread, (void*) server, 0, NULL); + } + + return 0; +} + +int freerdp_server_stop(xfServer* server) +{ + return 0; +} + +xfServer* freerdp_server_new(int argc, char** argv) +{ + xfServer* server; + + server = (xfServer*) malloc(sizeof(xfServer)); + + if (server) + { + server->listener = freerdp_listener_new(); + server->listener->PeerAccepted = xf_peer_accepted; + } + + return server; +} + +void freerdp_server_free(xfServer* server) +{ + if (server) + { + freerdp_listener_free(server->listener); + free(server); + } +} diff --git a/server/X11/xf_interface.h b/server/X11/xf_interface.h new file mode 100644 index 000000000000..1fd07e47f4dd --- /dev/null +++ b/server/X11/xf_interface.h @@ -0,0 +1,50 @@ +/** + * FreeRDP: A Remote Desktop Protocol Implementation + * FreeRDP X11 Server Interface + * + * Copyright 2013 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 XFREERDP_SERVER_INTERFACE_H +#define XFREERDP_SERVER_INTERFACE_H + +#include +#include + +typedef struct xf_info xfInfo; +typedef struct xf_server xfServer; + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Server Interface + */ + +FREERDP_API int freerdp_server_global_init(); +FREERDP_API int freerdp_server_global_uninit(); + +FREERDP_API int freerdp_server_start(xfServer* server); +FREERDP_API int freerdp_server_stop(xfServer* server); + +FREERDP_API xfServer* freerdp_server_new(int argc, char** argv); +FREERDP_API void freerdp_server_free(xfServer* server); + +#ifdef __cplusplus +} +#endif + +#endif /* XFREERDP_SERVER_INTERFACE_H */ diff --git a/server/X11/xfreerdp.c b/server/X11/xfreerdp.c index ce89aba0de53..3f952f1c60f2 100644 --- a/server/X11/xfreerdp.c +++ b/server/X11/xfreerdp.c @@ -21,97 +21,30 @@ #include "config.h" #endif -#include -#include -#include -#include -#include -#include -#include -#include - #include "xf_peer.h" #include "xfreerdp.h" -void xf_server_main_loop(freerdp_listener* instance) +int main(int argc, char* argv[]) { - int i; - int fds; - int max_fds; - int rcount; - void* rfds[32]; - fd_set rfds_set; - - ZeroMemory(rfds, sizeof(rfds)); - - while (1) - { - rcount = 0; - - if (instance->GetFileDescriptor(instance, rfds, &rcount) != TRUE) - { - fprintf(stderr, "Failed to get FreeRDP file descriptor\n"); - break; - } - - max_fds = 0; - FD_ZERO(&rfds_set); - - for (i = 0; i < rcount; i++) - { - fds = (int)(long)(rfds[i]); + xfServer* server; + DWORD dwExitCode; - if (fds > max_fds) - max_fds = fds; + freerdp_server_global_init(); - FD_SET(fds, &rfds_set); - } + server = freerdp_server_new(argc, argv); - if (max_fds == 0) - break; + if (!server) + return 0; - if (select(max_fds + 1, &rfds_set, NULL, NULL, NULL) == -1) - { - /* these are not really errors */ - if (!((errno == EAGAIN) || - (errno == EWOULDBLOCK) || - (errno == EINPROGRESS) || - (errno == EINTR))) /* signal occurred */ - { - fprintf(stderr, "select failed\n"); - break; - } - } + freerdp_server_start(server); - if (instance->CheckFileDescriptor(instance) != TRUE) - { - fprintf(stderr, "Failed to check FreeRDP file descriptor\n"); - break; - } - } + WaitForSingleObject(server->thread, INFINITE); - instance->Close(instance); -} - -int main(int argc, char* argv[]) -{ - freerdp_listener* instance; + GetExitCodeThread(server->thread, &dwExitCode); - /* ignore SIGPIPE, otherwise an SSL_write failure could crash the server */ - signal(SIGPIPE, SIG_IGN); + freerdp_server_free(server); - instance = freerdp_listener_new(); - instance->PeerAccepted = xf_peer_accepted; - - /* Open the server socket and start listening. */ - if (instance->Open(instance, NULL, 3389)) - { - /* Entering the server main loop. In a real server the listener can be run in its own thread. */ - xf_server_main_loop(instance); - } - - freerdp_listener_free(instance); + freerdp_server_global_uninit(); return 0; } - diff --git a/server/X11/xfreerdp.h b/server/X11/xfreerdp.h index d2d4a8f41e86..f0ca84f19fad 100644 --- a/server/X11/xfreerdp.h +++ b/server/X11/xfreerdp.h @@ -20,6 +20,12 @@ #ifndef __XFREERDP_H #define __XFREERDP_H +#include "xf_interface.h" + +#include +#include +#include + #include #ifdef WITH_XSHM @@ -38,8 +44,6 @@ #include #endif -typedef struct xf_info xfInfo; - struct xf_info { int bpp; @@ -70,4 +74,13 @@ struct xf_info #endif }; +struct xf_server +{ + DWORD port; + HANDLE thread; + freerdp_listener* listener; +}; + +void* xf_server_thread(void* param); + #endif /* __XFREERDP_H */