From 0b30ec8c722d6e13d7981f57ce4c2ca96f37bb24 Mon Sep 17 00:00:00 2001 From: Gerasim Troeglazov <3dEyes@gmail.com> Date: Wed, 29 Aug 2018 21:51:04 +1000 Subject: Fix build diff --git a/channels/rdpsnd/client/rdpsnd_main.c b/channels/rdpsnd/client/rdpsnd_main.c index 4c327f7..ccd72ce 100644 --- a/channels/rdpsnd/client/rdpsnd_main.c +++ b/channels/rdpsnd/client/rdpsnd_main.c @@ -1513,7 +1513,7 @@ BOOL VCAPITYPE VirtualChannelEntryEx(PCHANNEL_ENTRY_POINTS pEntryPoints, PVOID p } rdpsnd->attached = TRUE; -#if !defined(_WIN32) && !defined(ANDROID) +#if !defined(_WIN32) && !defined(ANDROID) && !defined(__HAIKU__) { sigset_t mask; sigemptyset(&mask); diff --git a/client/CMakeLists.txt b/client/CMakeLists.txt index 166847e..02481d0 100644 --- a/client/CMakeLists.txt +++ b/client/CMakeLists.txt @@ -55,6 +55,11 @@ if(FREERDP_VENDOR AND WITH_CLIENT) message(STATUS "Adding Android client") add_subdirectory(Android) endif() + + if(HAIKU) + message(STATUS "Adding Haiku client") + add_subdirectory(Haiku) + endif() endif() # Pick up other clients diff --git a/winpr/include/winpr/winsock.h b/winpr/include/winpr/winsock.h index 5e04418..f4e1717 100644 --- a/winpr/include/winpr/winsock.h +++ b/winpr/include/winpr/winsock.h @@ -84,6 +84,10 @@ WINPR_API INT winpr_inet_pton(INT Family, PCSTR pszAddrString, PVOID pAddrBuf); #include #include #include +#ifdef __HAIKU__ +#include +#include +#endif #include #include diff --git a/winpr/libwinpr/synch/CMakeLists.txt b/winpr/libwinpr/synch/CMakeLists.txt index 7c86c34..a7fda31 100644 --- a/winpr/libwinpr/synch/CMakeLists.txt +++ b/winpr/libwinpr/synch/CMakeLists.txt @@ -30,7 +30,7 @@ winpr_module_add( timer.c wait.c) -if((NOT WIN32) AND (NOT APPLE) AND (NOT ANDROID) AND (NOT OPENBSD)) +if((NOT WIN32) AND (NOT APPLE) AND (NOT HAIKU) AND (NOT ANDROID) AND (NOT OPENBSD)) winpr_library_add(rt) endif() diff --git a/winpr/libwinpr/synch/timer.c b/winpr/libwinpr/synch/timer.c index dbd628f..f8a125a 100644 --- a/winpr/libwinpr/synch/timer.c +++ b/winpr/libwinpr/synch/timer.c @@ -768,7 +768,9 @@ static int StartTimerQueueThread(WINPR_TIMER_QUEUE* timerQueue) pthread_attr_init(&(timerQueue->attr)); timerQueue->param.sched_priority = sched_get_priority_max(SCHED_FIFO); pthread_attr_setschedparam(&(timerQueue->attr), &(timerQueue->param)); +#ifndef __HAIKU__ pthread_attr_setschedpolicy(&(timerQueue->attr), SCHED_FIFO); +#endif pthread_create(&(timerQueue->thread), &(timerQueue->attr), TimerQueueThread, timerQueue); return 0; } diff --git a/winpr/libwinpr/sysinfo/CMakeLists.txt b/winpr/libwinpr/sysinfo/CMakeLists.txt index f9b7f69..126eb48 100644 --- a/winpr/libwinpr/sysinfo/CMakeLists.txt +++ b/winpr/libwinpr/sysinfo/CMakeLists.txt @@ -21,10 +21,14 @@ endif() winpr_module_add(sysinfo.c) -if((NOT WIN32) AND (NOT APPLE) AND (NOT ANDROID) AND (NOT OPENBSD)) +if((NOT WIN32) AND (NOT APPLE) AND (NOT HAIKU) AND (NOT ANDROID) AND (NOT OPENBSD)) winpr_library_add(rt) endif() +if(HAIKU) + winpr_library_add(network) +endif() + if(BUILD_TESTING) add_subdirectory(test) endif() diff --git a/winpr/libwinpr/utils/CMakeLists.txt b/winpr/libwinpr/utils/CMakeLists.txt index abf4dc1..bf6d495 100644 --- a/winpr/libwinpr/utils/CMakeLists.txt +++ b/winpr/libwinpr/utils/CMakeLists.txt @@ -141,7 +141,7 @@ if(UNIX) winpr_library_add(m) endif() -if((FREEBSD) AND (NOT KFREEBSD)) +if(((FREEBSD) AND (NOT KFREEBSD)) OR (HAIKU)) winpr_library_add(execinfo) endif() diff --git a/winpr/libwinpr/winsock/winsock.c b/winpr/libwinpr/winsock/winsock.c index 50bf1eb..1ed7577 100644 --- a/winpr/libwinpr/winsock/winsock.c +++ b/winpr/libwinpr/winsock/winsock.c @@ -371,9 +371,11 @@ void WSASetLastError(int iError) case WSAEPROTONOSUPPORT: errno = EPROTONOSUPPORT; break; +#ifndef __HAIKU__ case WSAESOCKTNOSUPPORT: errno = ESOCKTNOSUPPORT; break; +#endif case WSAEOPNOTSUPP: errno = EOPNOTSUPP; break; @@ -416,9 +418,11 @@ void WSASetLastError(int iError) case WSAESHUTDOWN: errno = ESHUTDOWN; break; +#ifndef __HAIKU__ case WSAETOOMANYREFS: errno = ETOOMANYREFS; break; +#endif case WSAETIMEDOUT: errno = ETIMEDOUT; break; @@ -445,18 +449,22 @@ void WSASetLastError(int iError) errno = EPROCLIM; break; #endif +#ifndef __HAIKU__ case WSAEUSERS: errno = EUSERS; break; +#endif case WSAEDQUOT: errno = EDQUOT; break; case WSAESTALE: errno = ESTALE; break; +#ifndef __HAIKU__ case WSAEREMOTE: errno = EREMOTE; break; +#endif } } @@ -516,9 +524,11 @@ int WSAGetLastError(void) case EPROTONOSUPPORT: iError = WSAEPROTONOSUPPORT; break; +#ifndef __HAIKU__ case ESOCKTNOSUPPORT: iError = WSAESOCKTNOSUPPORT; break; +#endif case EOPNOTSUPP: iError = WSAEOPNOTSUPP; break; @@ -561,9 +571,11 @@ int WSAGetLastError(void) case ESHUTDOWN: iError = WSAESHUTDOWN; break; +#ifndef __HAIKU__ case ETOOMANYREFS: iError = WSAETOOMANYREFS; break; +#endif case ETIMEDOUT: iError = WSAETIMEDOUT; break; @@ -590,19 +602,22 @@ int WSAGetLastError(void) iError = WSAEPROCLIM; break; #endif +#ifndef __HAIKU__ case EUSERS: iError = WSAEUSERS; break; +#endif case EDQUOT: iError = WSAEDQUOT; break; case ESTALE: iError = WSAESTALE; break; +#ifndef __HAIKU__ case EREMOTE: iError = WSAEREMOTE; break; - +#endif /* Special cases */ #if (EAGAIN != EWOULDBLOCK) diff --git a/winpr/winpr.pc.in b/winpr/winpr.pc.in index 6b0c950..73aea67 100644 --- a/winpr/winpr.pc.in +++ b/winpr/winpr.pc.in @@ -11,5 +11,5 @@ Version: @WINPR_VERSION@ Requires: Requires.private: libssl Libs: -L${libdir} ${libs} -Libs.private: -ldl -lrt -lm -lpthread +Libs.private: -ldl -lnetwork -lbe Cflags: -I${includedir} -- 2.16.4 From bb4cf466631ce75df92b53c7478c7fe41f281b77 Mon Sep 17 00:00:00 2001 From: Gerasim Troeglazov <3dEyes@gmail.com> Date: Wed, 29 Aug 2018 21:53:34 +1000 Subject: Add Haiku support diff --git a/client/Haiku/App.cpp b/client/Haiku/App.cpp new file mode 100644 index 0000000..92874d0 --- /dev/null +++ b/client/Haiku/App.cpp @@ -0,0 +1,20 @@ +/* + * Copyright 2010 Your Name + * All rights reserved. Distributed under the terms of the MIT license. + */ + +#include "App.h" + +const char *APPSIGNATURE = "application/x-vnd.freerdp"; + +TestApplication::TestApplication() + :BApplication(APPSIGNATURE) +{ + +} + + +TestApplication::~TestApplication() +{ +} + diff --git a/client/Haiku/App.h b/client/Haiku/App.h new file mode 100644 index 0000000..828c3bc --- /dev/null +++ b/client/Haiku/App.h @@ -0,0 +1,16 @@ +#ifndef _TEST_APPLICATION_H +#define _TEST_APPLICATION_H + +#include +#include +#include +#include + +class TestApplication : public BApplication { + public: + TestApplication(); + virtual ~TestApplication(); +}; + +#endif + diff --git a/client/Haiku/CMakeLists.txt b/client/Haiku/CMakeLists.txt new file mode 100644 index 0000000..1441dc8 --- /dev/null +++ b/client/Haiku/CMakeLists.txt @@ -0,0 +1,36 @@ +# FreeRDP: A Remote Desktop Protocol Implementation +# FreeRDP Haiku UI cmake build script +# +# Copyright 2018 Gerasim Troeglazov <3dEyes@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. + +set(MODULE_NAME "FreeRDP") +set(MODULE_PREFIX "FREERDP_CLIENT_HAIKU") +set(CMAKE_POSITION_INDEPENDENT_CODE OFF) + +set(${MODULE_PREFIX}_SRCS + FreeRDP.cpp App.cpp MainWindow.cpp MainView.cpp) + +add_executable(${MODULE_NAME} ${${MODULE_PREFIX}_SRCS}) + +set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} ${CMAKE_DL_LIBS}) +set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} freerdp-client freerdp) +set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} be network media translation) +target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS}) + +ADD_CUSTOM_COMMAND(TARGET ${MODULE_NAME} COMMAND rc -o Resources.rsrc ${CMAKE_CURRENT_SOURCE_DIR}/Resources.rdef COMMENT "Compiling resources") +ADD_CUSTOM_COMMAND(TARGET ${MODULE_NAME} COMMAND xres -o ${MODULE_NAME} Resources.rsrc COMMENT "Adding resources to executable") +ADD_CUSTOM_COMMAND(TARGET ${MODULE_NAME} COMMAND mimeset --all ${MODULE_NAME} COMMENT "Adjusting MIME types") + +set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "Client/Haiku") diff --git a/client/Haiku/FreeRDP.cpp b/client/Haiku/FreeRDP.cpp new file mode 100644 index 0000000..a3fbb7b --- /dev/null +++ b/client/Haiku/FreeRDP.cpp @@ -0,0 +1,322 @@ +/** + * FreeRDP: A Remote Desktop Protocol Implementation + * FreeRDP Test UI + * + * Copyright 2011 Marc-Andre Moreau + * Copyright 2016 Armin Novak + * Copyright 2016 Thincast Technologies GmbH + * + * 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. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#include +#include +#include +#include + +#include "App.h" +#include "MainWindow.h" +#include "MainView.h" + +#include +#include +#include + +extern "C" { + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +} + +#define TAG CLIENT_TAG("haiku") + +MainWindow *wnd = NULL; + +struct tf_context +{ + rdpContext _p; +}; +typedef struct tf_context tfContext; + +static BOOL tf_context_new(freerdp* instance, rdpContext* context) +{ + return TRUE; +} + +static void tf_context_free(freerdp* instance, rdpContext* context) +{ +} + +static BOOL tf_begin_paint(rdpContext* context) +{ + rdpGdi* gdi = context->gdi; + gdi->primary->hdc->hwnd->invalid->null = TRUE; + return TRUE; +} + +static BOOL tf_end_paint(rdpContext* context) +{ + rdpGdi* gdi = context->gdi; + + if(wnd==NULL) + return TRUE; + + if (gdi->primary->hdc->hwnd->invalid->null) + return TRUE; + + char* data = (char*)wnd->fb->GetBuffer(); + + int x = gdi->primary->hdc->hwnd->invalid->x; + int y = gdi->primary->hdc->hwnd->invalid->y; + int w = gdi->primary->hdc->hwnd->invalid->w; + int h = gdi->primary->hdc->hwnd->invalid->h; + + for (int i = 0; i < h; i++) + { + memcpy(data + ((i + y) * (gdi->width * GetBytesPerPixel( + gdi->dstFormat))) + x * GetBytesPerPixel(gdi->dstFormat), + gdi->primary_buffer + ((i + y) * (gdi->width * GetBytesPerPixel( + gdi->dstFormat))) + x * GetBytesPerPixel(gdi->dstFormat), + w * GetBytesPerPixel(gdi->dstFormat)); + } + + wnd->fb->Paint(); + + return TRUE; +} + +static BOOL tf_pre_connect(freerdp* instance) +{ + rdpSettings* settings; + settings = instance->settings; + settings->OrderSupport[NEG_DSTBLT_INDEX] = TRUE; + settings->OrderSupport[NEG_PATBLT_INDEX] = TRUE; + settings->OrderSupport[NEG_SCRBLT_INDEX] = TRUE; + settings->OrderSupport[NEG_OPAQUE_RECT_INDEX] = TRUE; + settings->OrderSupport[NEG_DRAWNINEGRID_INDEX] = FALSE; + settings->OrderSupport[NEG_MULTIDSTBLT_INDEX] = FALSE; + settings->OrderSupport[NEG_MULTIPATBLT_INDEX] = FALSE; + settings->OrderSupport[NEG_MULTISCRBLT_INDEX] = FALSE; + settings->OrderSupport[NEG_MULTIOPAQUERECT_INDEX] = TRUE; + settings->OrderSupport[NEG_MULTI_DRAWNINEGRID_INDEX] = FALSE; + settings->OrderSupport[NEG_LINETO_INDEX] = TRUE; + settings->OrderSupport[NEG_POLYLINE_INDEX] = TRUE; + settings->OrderSupport[NEG_MEMBLT_INDEX] = TRUE; + settings->OrderSupport[NEG_MEM3BLT_INDEX] = FALSE; + settings->OrderSupport[NEG_SAVEBITMAP_INDEX] = FALSE; + settings->OrderSupport[NEG_GLYPH_INDEX_INDEX] = FALSE; + settings->OrderSupport[NEG_FAST_INDEX_INDEX] = FALSE; + settings->OrderSupport[NEG_FAST_GLYPH_INDEX] = FALSE; + settings->OrderSupport[NEG_POLYGON_SC_INDEX] = FALSE; + settings->OrderSupport[NEG_POLYGON_CB_INDEX] = FALSE; + settings->OrderSupport[NEG_ELLIPSE_SC_INDEX] = FALSE; + settings->OrderSupport[NEG_ELLIPSE_CB_INDEX] = FALSE; + + if (settings->Fullscreen) { + BScreen screen; + settings->DesktopWidth = (UINT32) screen.Frame().right + 1; + settings->DesktopHeight = (UINT32) screen.Frame().bottom + 1; + } + + return TRUE; +} + +static BOOL tf_post_connect(freerdp* instance) +{ + rdpGdi* gdi; + rdpContext* context; + rdpSettings* settings; + + context = ((rdpContext*) instance->context); + + if (!gdi_init(instance, PIXEL_FORMAT_BGRA32)) + return FALSE; + + gdi = instance->context->gdi; + settings = instance->settings; + + instance->update->BeginPaint = tf_begin_paint; + instance->update->EndPaint = tf_end_paint; + + if(wnd==NULL) { + char wndTitle[256]={"FreeRDP"}; + + BRect rect = BRect(50, 50, 50 + gdi->width, 50 + gdi->height); + if (settings->Fullscreen) { + rect = BRect(0, 0, gdi->width, gdi->height); + } + if (settings->WindowTitle != NULL) + snprintf(wndTitle, 255, "%s", settings->WindowTitle); + else if (settings->ServerPort == 3389) + snprintf(wndTitle, 255, "FreeRDP: %s", settings->ServerHostname); + else + snprintf(wndTitle, 255, "FreeRDP: %S:%u", settings->ServerHostname, settings->ServerPort); + + wnd = new MainWindow(rect, wndTitle, instance); + wnd->Show(); + } + + return TRUE; +} + +static void tf_post_disconnect(freerdp* instance) +{ + rdpContext* context; + + if (!instance) + return; + + if (!instance->context) + return; + + context = (rdpContext*) instance->context; + gdi_free(instance); + + if (wnd!=NULL) { + wnd->Lock(); + wnd->Quit(); + } +} + +static DWORD WINAPI tf_haiku_app_thread_proc(LPVOID arg) +{ + TestApplication app; + app.Run(); + + ExitThread(0); + return 0; +} + + +static DWORD WINAPI tf_client_thread_proc(LPVOID arg) +{ + freerdp* instance = (freerdp*)arg; + DWORD nCount; + DWORD status; + HANDLE handles[64]; + + if (!freerdp_connect(instance)) + { + WLog_ERR(TAG, "connection failure"); + return 0; + } + + while (!freerdp_shall_disconnect(instance)) + { + nCount = freerdp_get_event_handles(instance->context, &handles[0], 64); + + if (nCount == 0) + { + WLog_ERR(TAG, "%s: freerdp_get_event_handles failed", __FUNCTION__); + break; + } + + status = WaitForMultipleObjects(nCount, handles, FALSE, 100); + + if (status == WAIT_FAILED) + { + WLog_ERR(TAG, "%s: WaitForMultipleObjects failed with %"PRIu32"", __FUNCTION__, + status); + break; + } + + if (!freerdp_check_event_handles(instance->context)) + { + if (freerdp_get_last_error(instance->context) == FREERDP_ERROR_SUCCESS) + WLog_ERR(TAG, "Failed to check FreeRDP event handles"); + + break; + } + } + + freerdp_disconnect(instance); + ExitThread(0); + return 0; +} + +int main(int argc, char* argv[]) +{ + int status; + HANDLE thread; + freerdp* instance; + instance = freerdp_new(); + + if (!instance) + { + WLog_ERR(TAG, "Couldn't create instance"); + winpr_exit(1); + } + + instance->PreConnect = tf_pre_connect; + instance->PostConnect = tf_post_connect; + instance->PostDisconnect = tf_post_disconnect; + instance->ContextSize = sizeof(tfContext); + instance->ContextNew = tf_context_new; + instance->ContextFree = tf_context_free; + freerdp_register_addin_provider(freerdp_channels_load_static_addin_entry, 0); + + if (!freerdp_context_new(instance)) + { + WLog_ERR(TAG, "Couldn't create context"); + return winpr_exit(1); + } + + status = freerdp_client_settings_parse_command_line(instance->settings, argc, + argv, FALSE); + + if (status < 0) + { + return winpr_exit(0); + } + + if (!freerdp_client_load_addins(instance->context->channels, + instance->settings)) + return winpr_exit(-1); + + //if (!(thread = CreateThread(NULL, 0, tf_haiku_app_thread_proc, instance, 0, NULL))) + //{ +// WLog_ERR(TAG, "Failed to create app thread"); +// } + + if (!(thread = CreateThread(NULL, 0, tf_client_thread_proc, instance, 0, NULL))) + { + WLog_ERR(TAG, "Failed to create client thread"); + } + else + { + WaitForSingleObject(thread, INFINITE); + } + + freerdp_context_free(instance); + freerdp_free(instance); + return winpr_exit(0); +} diff --git a/client/Haiku/MainView.cpp b/client/Haiku/MainView.cpp new file mode 100644 index 0000000..00e70a0 --- /dev/null +++ b/client/Haiku/MainView.cpp @@ -0,0 +1,235 @@ +/* + * Copyright 2010 Your Name + * All rights reserved. Distributed under the terms of the MIT license. + */ + +#include "MainWindow.h" +#include "MainView.h" + + +FBView::FBView(BRect rect) : + BView(rect, "FBView", B_FOLLOW_ALL, B_WILL_DRAW|B_PULSE_NEEDED|B_FRAME_EVENTS), + showBar(false) +{ + FBView(rect, rect.IntegerWidth(), rect.IntegerHeight()); +} + +FBView::FBView(BRect rect, int width, int height) : + BView(rect, "FBView", B_FOLLOW_ALL, B_WILL_DRAW|B_PULSE_NEEDED|B_FRAME_EVENTS), + showBar(false) +{ + buffer_width = width; + buffer_height = height; + lastButtons = 0; + + BRect fbRect = BRect(0,0,buffer_width-1,buffer_height-1); + bufferView = new BView(fbRect, "bufferView", B_FOLLOW_ALL_SIDES, 0); + bufferBitmap = new BBitmap(fbRect, B_RGB32, true); + bufferBitmap->AddChild(bufferView); + + font = be_bold_font; + font.SetSize(14); + SetFont(&font, B_FONT_ALL); + + title = BString("FreeRDP"); + + //printf("BTranslationUtils::GetBitmap\n"); + //closeBitmap = BTranslationUtils::GetBitmapFile("/NoIndex64/Public/FreeRDP/client/Haiku/images/close.png"); + //printf("W:%f H:%f\n", closeBitmap->Bounds().Width(), closeBitmap->Bounds().Height()); + //zoomBitmap = new BBitmap(BRect(0,0,16,16),B_RGB32);//BTranslationUtils::GetBitmap(B_PNG_FORMAT, "zoom.png"); +} + +FBView::~FBView() +{ + //delete closeBitmap; + //delete zoomBitmap; +} + +void +FBView::AttachedToWindow(void) +{ + tickCount = 0; +} + +void +FBView::Pulse(void) +{ + uint32 dx = Bounds().Width() / 3; + uint32 h = showBar?20:2; + if (lastPos.y >= 0 && lastPos.y < h && lastPos.x > dx && lastPos.x < dx * 2 ) { + tickCount++; + if(tickCount > 5) { + showBar = true; + Invalidate(); + } + return; + } + if(showBar) { + showBar = false; + Invalidate(); + } + tickCount = 0; +} + +void +FBView::SetInstance(freerdp *inst) +{ + instance = inst; + title.SetTo(Window()->Title()); +} + +BPoint +FBView::GetLastMousePos() +{ + return lastPos; +} + +void FBView::MouseMoved(BPoint p, uint32 transit,const BMessage *message) +{ + rdpInput* input = instance->input; + switch(transit) + { + case B_INSIDE_VIEW: + case B_ENTERED_VIEW: + { + input->MouseEvent(input, PTR_FLAGS_MOVE, p.x, p.y); + tickCount = 0; + break; + } + case B_EXITED_VIEW: + break; + case B_OUTSIDE_VIEW: + break; + } + lastPos = p; +} + +void FBView::MouseDown(BPoint p) +{ + rdpInput* input = instance->input; + + uint32 dx = Bounds().Width() / 3; + uint32 h = showBar?20:2; + + uint32 buttons = Window()->CurrentMessage()->FindInt32("buttons"); + int32 clicks = Window()->CurrentMessage()->FindInt32("clicks"); + int flags = PTR_FLAGS_DOWN; + + if (buttons & B_PRIMARY_MOUSE_BUTTON) + flags |= PTR_FLAGS_BUTTON1; + if (buttons & B_SECONDARY_MOUSE_BUTTON) + flags |= PTR_FLAGS_BUTTON2; + if (buttons & B_TERTIARY_MOUSE_BUTTON) + flags |= PTR_FLAGS_BUTTON2; + + if (showBar && buttons & B_PRIMARY_MOUSE_BUTTON) { + BRect closeButtonRect(dx + 3, 3, dx + h - 3, h - 3); + if (closeButtonRect.Contains(p)) { + freerdp_abort_connect(instance); + } else if(clicks == 2) { + Window()->Minimize(true); + flags = 0; + } + } + + if (flags != 0) + input->MouseEvent(input, flags, p.x, p.y); + + lastPos = p; + lastButtons = buttons; +} + +void FBView::MouseUp(BPoint p) +{ + rdpInput* input = instance->input; + + uint32 buttons = Window()->CurrentMessage()->FindInt32("buttons"); + int flags = 0; + + if ((buttons ^ lastButtons) & B_PRIMARY_MOUSE_BUTTON) + flags |= PTR_FLAGS_BUTTON1; + if ((buttons ^ lastButtons) & B_SECONDARY_MOUSE_BUTTON) + flags |= PTR_FLAGS_BUTTON2; + if ((buttons ^lastButtons) & B_TERTIARY_MOUSE_BUTTON) + flags |= PTR_FLAGS_BUTTON2; + + if (flags != 0) + input->MouseEvent(input, flags, p.x, p.y); + + lastPos = p; + lastButtons = buttons; +} + +void +FBView::Draw(BRect r) +{ + uint32 dx = Bounds().Width() / 3; + uint32 h = showBar?20:2; + + DrawBitmap(bufferBitmap, r, r); + if (showBar) { + BRect r(dx, -1, dx * 2, h); + SetDrawingMode(B_OP_COPY); + + SetHighColor(255, 203, 0); + SetLowColor(255, 203, 0); + FillRect(r); + SetHighColor(179, 143, 0); + SetLowColor(179, 143, 0); + StrokeRect(r); + + SetDrawingMode(B_OP_ALPHA); + BRect closeButtonRect(dx + 3, 3, dx + h - 3, h - 3); + StrokeRect(closeButtonRect); + //DrawBitmap(closeBitmap, BPoint(dx + 3, 3)); + + SetHighColor(0, 0, 0); + SetLowColor(0, 0, 0); + float width = font.StringWidth(title); + DrawString(title, BPoint(Bounds().Width()/2 - width/2, 16)); + } +} + +void +FBView::Paint() +{ + if(LockLooper()) { + bufferView->LockLooper(); + SetDrawingMode(B_OP_COPY); + DrawBitmap(bufferBitmap);//, bufferView->Bounds(), Bounds()); + bufferView->UnlockLooper(); + UnlockLooper(); + } +} + +uint32 * +FBView::GetBuffer() +{ + if(bufferBitmap) { + return (uint32*)bufferBitmap->Bits(); + } + return NULL; +} + +uint32 +FBView::GetBufferSize() +{ + if(bufferBitmap) { + return bufferBitmap->BitsLength()/4; + } + return 0; +} + +int +FBView::Width() +{ + return buffer_width; +} + +int +FBView::Height() +{ + return buffer_height; +} + + diff --git a/client/Haiku/MainView.h b/client/Haiku/MainView.h new file mode 100644 index 0000000..8597c85 --- /dev/null +++ b/client/Haiku/MainView.h @@ -0,0 +1,74 @@ +#ifndef _H_FBVIEW_ +#define _H_FBVIEW_ + +#include +#include +#include + +extern "C" { + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +} + +#include +#include +#include +#include +#include +#include +#include +#include + +class FBView : public BView +{ + public: + FBView(BRect rect); + FBView(BRect rect, int width, int height); + ~FBView(); + + void Paint(); + void SetInstance(freerdp *instance); + uint32 *GetBuffer(); + uint32 GetBufferSize(); + BPoint GetLastMousePos(); + + int Width(); + int Height(); +protected: + virtual void Draw(BRect r); + virtual void MouseDown(BPoint p); + virtual void MouseUp(BPoint p); + virtual void MouseMoved(BPoint point, uint32 transit, const BMessage *message); + virtual void Pulse(void); + virtual void AttachedToWindow(void); + +private: + int buffer_width; + int buffer_height; + BView *bufferView; + BBitmap *bufferBitmap; + BBitmap *closeBitmap; + BBitmap *zoomBitmap; + uint32 lastButtons; + BPoint lastPos; + freerdp *instance; + uint32 tickCount; + bool showBar; + BFont font; + BString title; +}; + +#endif diff --git a/client/Haiku/MainWindow.cpp b/client/Haiku/MainWindow.cpp new file mode 100644 index 0000000..8228e34 --- /dev/null +++ b/client/Haiku/MainWindow.cpp @@ -0,0 +1,131 @@ +#include +#include +#include "MainWindow.h" + +BApplication app("application/x-vnd.freerdp"); + +static const uint32 be_to_scan_codes[] = { +VK_ESCAPE, VK_F1, VK_F2, VK_F3, VK_F4, VK_F5, +VK_F6, VK_F7, VK_F8, VK_F9, VK_F10, VK_F11, VK_F12, VK_PRINT, VK_SCROLL, 0, +////////// +VK_OEM_3,VK_KEY_1,VK_KEY_2,VK_KEY_3,VK_KEY_4,VK_KEY_5,VK_KEY_6,VK_KEY_7,VK_KEY_8, +VK_KEY_9,VK_KEY_0,VK_OEM_MINUS,VK_OEM_PLUS,VK_BACK,VK_INSERT|KBDEXT, +VK_HOME|KBDEXT,VK_PRIOR|KBDEXT,VK_NUMLOCK,VK_DIVIDE|KBDEXT,VK_MULTIPLY,VK_SUBTRACT, +////////// +VK_TAB,VK_KEY_Q,VK_KEY_W,VK_KEY_E,VK_KEY_R,VK_KEY_T,VK_KEY_Y,VK_KEY_U,VK_KEY_I, +VK_KEY_O,VK_KEY_P,VK_OEM_4,VK_OEM_6,VK_OEM_5,VK_DELETE|KBDEXT,VK_END|KBDEXT,VK_NEXT|KBDEXT, +VK_NUMPAD7,VK_NUMPAD8,VK_NUMPAD9,VK_ADD, +////////// +VK_CAPITAL,VK_KEY_A,VK_KEY_S,VK_KEY_D,VK_KEY_F,VK_KEY_G,VK_KEY_H,VK_KEY_J,VK_KEY_K,VK_KEY_L,VK_OEM_1,VK_OEM_7,VK_RETURN, +VK_NUMPAD4,VK_NUMPAD5,VK_NUMPAD6, +////////// +VK_LSHIFT,VK_KEY_Z,VK_KEY_X,VK_KEY_C,VK_KEY_V,VK_KEY_B,VK_KEY_N,VK_KEY_M,VK_OEM_COMMA,VK_OEM_PERIOD,VK_OEM_2, +VK_RSHIFT,VK_UP|KBDEXT,VK_NUMPAD1,VK_NUMPAD2,VK_NUMPAD3,VK_RETURN|KBDEXT, +////////// +VK_LCONTROL,VK_LMENU,VK_SPACE,VK_RMENU,VK_RCONTROL,VK_LEFT|KBDEXT,VK_DOWN|KBDEXT,VK_RIGHT|KBDEXT,VK_NUMPAD0,VK_DECIMAL, +VK_LWIN|KBDEXT,VK_RWIN|KBDEXT,127,0 +}; + + +MainWindow::MainWindow(BRect frame, const char* title, freerdp *inst) + : BWindow(frame, title, B_TITLED_WINDOW_LOOK,B_NORMAL_WINDOW_FEEL,B_NOT_RESIZABLE|B_NOT_ZOOMABLE) +{ + fb = new FBView(Bounds(), frame.Width(),frame.Height()); + AddChild(fb); + SetInstance(inst); + SetPulseRate(100000); +} + + +MainWindow::~MainWindow() +{ +} + +void +MainWindow::MessageReceived(BMessage *message) +{ + switch(message->what) { + case B_UNMAPPED_KEY_DOWN: + case B_KEY_DOWN: + { + rdpInput* input = instance->input; + + const char *bytes; + int32 key; + uint32 keycode; + message->FindInt32("key",&key); + keycode = be_to_scan_codes[(uint8)key-1]; + DWORD scancode = GetVirtualScanCodeFromVirtualKeyCode(keycode, input->context->settings->KeyboardType); + + if (scancode) + freerdp_input_send_keyboard_event_ex(input, TRUE, scancode); + + break; + } + case B_UNMAPPED_KEY_UP: + case B_KEY_UP: + { + rdpInput* input = instance->input; + + const char *bytes; + int32 key; + uint32 keycode; + message->FindInt32("key",&key); + keycode = be_to_scan_codes[(uint8)key-1]; + DWORD scancode = GetVirtualScanCodeFromVirtualKeyCode(keycode, input->context->settings->KeyboardType); + + if (scancode) + freerdp_input_send_keyboard_event_ex(input, FALSE, scancode); + + break; + } + case B_MOUSE_WHEEL_CHANGED: + { + rdpInput* input = instance->input; + BPoint pos = fb->GetLastMousePos(); + + float shift=0; + UINT16 flags; + + flags = PTR_FLAGS_WHEEL; + + if(message->FindFloat("be:wheel_delta_y",&shift)==B_OK) { + if(shift<0) { + flags |= 0x0078; + } + if(shift>0) { + flags |= PTR_FLAGS_WHEEL_NEGATIVE | 0x0088; + } + } + input->MouseEvent(input, flags, pos.x, pos.y); + break; + } +// case B_CLIPBOARD_CHANGED: +// { +// break; +// } + case B_WINDOW_ACTIVATED: + case B_WORKSPACE_ACTIVATED: + { + break; + } + default: + BWindow::MessageReceived(message); + break; + } +} + + +void +MainWindow::SetInstance(freerdp *inst) +{ + instance = inst; + fb->SetInstance(inst); +} + +bool +MainWindow::QuitRequested() +{ + freerdp_abort_connect(instance); + return false; +} diff --git a/client/Haiku/MainWindow.h b/client/Haiku/MainWindow.h new file mode 100644 index 0000000..709a2c0 --- /dev/null +++ b/client/Haiku/MainWindow.h @@ -0,0 +1,50 @@ +#ifndef _TEST_WINDOW_H +#define _TEST_WINDOW_H + +#include +#include +#include + +extern "C" { + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +} + +#include +#include +#include +#include + +#include "MainView.h" + +class MainWindow : public BWindow { + public: + MainWindow(BRect rect, const char* name, freerdp *instance); + virtual ~MainWindow(); + + virtual void MessageReceived(BMessage *message); + bool QuitRequested(); + + void SetInstance(freerdp *instance); + + FBView *fb; + private: + freerdp *instance; +}; + +#endif + + diff --git a/client/Haiku/ModuleOptions.cmake b/client/Haiku/ModuleOptions.cmake new file mode 100644 index 0000000..130bfa1 --- /dev/null +++ b/client/Haiku/ModuleOptions.cmake @@ -0,0 +1,4 @@ + +set(FREERDP_CLIENT_NAME "hfreerdp") +set(FREERDP_CLIENT_PLATFORM "Haiku") +set(FREERDP_CLIENT_VENDOR "FreeRDP") diff --git a/client/Haiku/Resources.rdef b/client/Haiku/Resources.rdef new file mode 100644 index 0000000..86dd149 --- /dev/null +++ b/client/Haiku/Resources.rdef @@ -0,0 +1,55 @@ +/* + * Resources.rdef + */ + +resource app_signature "application/x-vnd.freerdp"; + +resource app_flags B_MULTIPLE_LAUNCH; + +resource app_version { + major = 2, + middle = 0, + minor = 0, + variety = 0, + internal = 0, + short_info = "FreeRDP", + long_info = "FreeRDP" +}; + +resource(1, "close.png") #'PNG ' import "images/close.png"; +resource(2, "zoom.png") #'PNG ' import "images/zoom.png"; + +resource vector_icon { + $"6E6369662803010000020016023CC7ED389BBFBA16553E39AF4977C842ADC700" + $"FFFFD3020016023C529D3753A2B8966F3D9D074B6044496AAF0047FFA0020016" + $"02BC4E75BC411A3C90D9BCA00C47587D4ABA850090FFD40200160238313C3B5C" + $"F0BFCD953C7AAB4C13943FCAF901ECFFC3054B04016B020006033E2F99387F17" + $"BA42DC3FF5B84A0E32482C90001D1E2C3D454658FF010101020006023879063B" + $"8224BE2CC73B10D94A1F6F49B89400242222FF9A9A9A020006033C69A6000000" + $"0000003E186148800049800000D4CECE58F3F3F3FFD9D9D90389FF0005000500" + $"0500030100000500033A3A4303F46E0C03010000020016023CC7ED389BBFBA16" + $"553E39AF4977C842ADC700FFFFD3020006023C529D3753A2B8966F3D9D074B60" + $"44496AAF00474747FFA5A0A002001602BC4E75BC411A3C90D9BCA00C47587D4A" + $"BA850090FFD40200160238313C3B5CF0BFCD953C7AAB4C13943FCAF901ECFFC3" + $"054B04017E020006033E2F99387F17BA42DC3FF5B84A0E32482C90001D1E2C3D" + $"454658FF010101020006023879063B8224BE2CC73B10D94A1F6F49B894002422" + $"22FF9A9A9A020006033C69A60000000000003E186148800049800000D4CECE58" + $"F3F3F3FFD9D9D9038AFF01050005000500030100000500033A3A43033A3A4303" + $"0100000300AAFF0300FF0003FFAA002200000A062228224A485E525252302C22" + $"0A042228483852302C220A044838485E525252300A042228224A485E48380A04" + $"453A45572446242C0A04B560442446242CB569B8200A0445544557244626440A" + $"0438263D234E28492C080438263D234E284E2E0A03492C4E284E2E0802425843" + $"C9830A06486054606052CA1BC5B95C4D524800000A0430303050505050300000" + $"000000000A04B570B86DB57DC12FC17CC729C17CBD8F0A062228224A485E5252" + $"52302C220A062228224A485E525252302C220A042228483852302C220A044838" + $"485E525252300A042228224A485E48380A042228224A485E48380A04453A4557" + $"2446242C0A04B560442446242CB569B8200A04B560442446242CB569B8200A04" + $"45544557244626440A0438263D234E28492C080438263D234E284E2E0A03492C" + $"4E284E2E0802425843C9830A04B570B86DB57DC12FC17CC729C17CBD8F0F0A06" + $"010C000A0001091001178400040A040108000A05010A000A0001011001178400" + $"040A010102000A03020405000A080106000A090107000A0A010B1815FF011782" + $"20040A020103000A110112023E00150000000000003E260D42CEDE44B6B40A26" + $"0112023E21EE0000000000003E260D483363471B5A0A250112023E0015000000" + $"0000003E260D42CEDE482DAD0A270112023E21EE0000000000003E41BA483363" + $"4901E6" +}; diff --git a/client/Haiku/images/close.png b/client/Haiku/images/close.png new file mode 100644 index 0000000000000000000000000000000000000000..584d790923a6dc766842e4baa2227f64aadf8d69 GIT binary patch literal 163 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|S)MMAAsQ2>UNYosP~dTU*#5C1 z?&xHT3L*8qvmS)Rs^%_~Q2YFsS$|1!`it3(se32J%wO~`Wl79&Ge*bW6bJsAT;5qx zyj8p8Sia;7Tn;+p{rlF+C$9^_wg>sMZ`w6A=~t~(WG?TLi_iZua`!Yw+VW_I0BvRP MboFyt=akR{0P0ga`Tzg` literal 0 HcmV?d00001 diff --git a/client/Haiku/images/zoom.png b/client/Haiku/images/zoom.png new file mode 100644 index 0000000000000000000000000000000000000000..4b796324247432ac5b5a9c595daf97cf4c2e33ab GIT binary patch literal 248 zcmVT~(m?k3lv=wGL_)S2bcK<~Zn+v+O$JD4w z=7(6M7ckPgvJNZ)kve)5dRo^uk}R^|9$dN;gjfxLl)0OGO6v+p-R=0fr%y=TVb9RL y(0D?Gwt^cePMdcmQk({o_O=|SbiIe?JE