Skip to content

Commit

Permalink
feat(cmdline): support set native window and sdl window to sdl render
Browse files Browse the repository at this point in the history
Signed-off-by: pingkai <pingkai010@gmail.com>
  • Loading branch information
pingkai committed Jun 5, 2020
1 parent 9a0c1f5 commit b68e37b
Show file tree
Hide file tree
Showing 6 changed files with 235 additions and 30 deletions.
7 changes: 6 additions & 1 deletion cmdline/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@ if (ENABLE_SDL)
list(APPEND SRC_FILE
SDLEventReceiver.cpp
SDLEventReceiver.h
)
nativeWindow/CocoaWindow.m
nativeWindow/X11Window.c)
endif ()

add_executable(cicadaPlayer
Expand Down Expand Up @@ -120,6 +121,10 @@ else ()
add_subdirectory(example)
endif ()

if (${CMAKE_SYSTEM_NAME} MATCHES "Linux")
target_link_libraries(cicadaPlayer PUBLIC X11)
endif()

if(MSVC AND NOT CMAKE_SIZEOF_VOID_P EQUAL 8)
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /SAFESEH:NO")
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} /SAFESEH:NO")
Expand Down
62 changes: 34 additions & 28 deletions cmdline/SDLEventReceiver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
//

#include "SDLEventReceiver.h"
#include "nativeWindow/nativeWindow.h"
#include <SDL2/SDL_syswm.h>
#include <utils/frame_work_log.h>
#include <utils/timer.h>
Expand All @@ -18,28 +19,30 @@ void SDLEventReceiver::poll(bool &exit) {
if (UserEvent) {
switch (UserEvent->getType()) {
case IEvent::TYPE_SET_VIEW: {
if (window == nullptr) {
if (SDL_WasInit(SDL_INIT_VIDEO) != SDL_INIT_VIDEO) {
SDL_Init(SDL_INIT_VIDEO);
}
Uint32 flags = 0;
flags |= SDL_WINDOW_ALLOW_HIGHDPI;
flags |= SDL_WINDOW_RESIZABLE;
window = SDL_CreateWindow("playerDemo", 0, 0, 1280, 720, flags);
}
SDL_SysWMinfo wminfo;
SDL_VERSION(&wminfo.version)
SDL_GetWindowWMInfo(window, &wminfo);
void* window_id = nullptr;
#if defined(SDL_VIDEO_DRIVER_WINDOWS)
window_id = wminfo.info.win.window;
#elif defined(SDL_VIDEO_DRIVER_X11)
window_id = wminfo.info.x11.window;
#elif defined(SDL_VIDEO_DRIVER_COCOA)
window_id = wminfo.info.cocoa.window;
#endif
mListener.onSetView(window_id);
break;
if (SDL_WasInit(SDL_INIT_VIDEO) != SDL_INIT_VIDEO) {
SDL_Init(SDL_INIT_VIDEO);
}
if (mView.view == nullptr) {
#if USE_NATIVE_WINDOW
if (getNativeFactor() != nullptr) {
mView.view = (getNativeFactor()->CreateNativeWindow(1280, 720));
if (mView.view) {
mView.type = CicadaSDLViewType_NATIVE_WINDOW;
}
}

#endif
if (mView.view == nullptr) {
Uint32 flags = 0;
flags |= SDL_WINDOW_ALLOW_HIGHDPI;
flags |= SDL_WINDOW_RESIZABLE;
SDL_Renderer *renderer;
SDL_CreateWindowAndRenderer(1280, 720, flags, reinterpret_cast<SDL_Window **>(&mView.view), &renderer);
mView.type = CicadaSDLViewType_SDL_WINDOW;
}
}
mListener.onSetView(&mView);
break;
}
case IEvent::TYPE_EXIT:
mListener.onExit();
Expand Down Expand Up @@ -100,13 +103,13 @@ void SDLEventReceiver::poll(bool &exit) {
}

case SDL_MOUSEBUTTONDOWN: {
if (event.button.button == SDL_BUTTON_LEFT) {
if (event.button.button == SDL_BUTTON_LEFT && mView.type == CicadaSDLViewType_SDL_WINDOW) {
static int64_t last_mouse_left_click = 0;
static bool is_full_screen = false;
if (af_gettime_relative() - last_mouse_left_click <= 500000) {
is_full_screen = !is_full_screen;
if (window) {
SDL_SetWindowFullscreen(window, is_full_screen ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0);
if (mView.view) {
SDL_SetWindowFullscreen((SDL_Window *) mView.view, is_full_screen ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0);
}
mListener.onFullScreen(is_full_screen);
last_mouse_left_click = 0;
Expand All @@ -121,9 +124,12 @@ void SDLEventReceiver::poll(bool &exit) {
break;
}
if (exit){
if (window != nullptr) {
SDL_DestroyWindow(window);
window = nullptr;
if (mView.view != nullptr) {
if (mView.type == CicadaSDLViewType_NATIVE_WINDOW) {
getNativeFactor()->DestroyNativeWindow(mView.view);
} else
SDL_DestroyWindow((SDL_Window *) mView.view);
mView.view = nullptr;
}
}
}
Expand Down
10 changes: 9 additions & 1 deletion cmdline/SDLEventReceiver.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,14 @@
#include <SDL2/SDL.h>
#endif
#include "IEventReceiver.h"
#define USE_NATIVE_WINDOW 0

enum CicadaSDLViewType { CicadaSDLViewType_SDL_WINDOW, CicadaSDLViewType_NATIVE_WINDOW };

typedef struct CicadaSDLView_t {
void *view;
CicadaSDLViewType type;
} CicadaSDLView;

class SDLEventReceiver : public IEventReceiver {

Expand All @@ -20,7 +28,7 @@ class SDLEventReceiver : public IEventReceiver {
private:
#ifdef ENABLE_SDL
SDL_Event event{};
SDL_Window *window = nullptr;
CicadaSDLView mView{};
#endif
};

Expand Down
91 changes: 91 additions & 0 deletions cmdline/nativeWindow/CocoaWindow.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@

#include "nativeWindow.h"

#ifdef TEST_NATIVE_COCOA

#include <Cocoa/Cocoa.h>

static void *CreateWindowCocoa(int w, int h);
static void DestroyWindowCocoa(void *window);

NativeWindowFactory CocoaWindowFactory = {"cocoa", CreateWindowCocoa, DestroyWindowCocoa};

static void *CreateWindowCocoa(int w, int h)
{
NSAutoreleasePool *pool;
NSWindow *nswindow;
NSRect rect;
unsigned int style;
NSArray *screens = [NSScreen screens];

pool = [[NSAutoreleasePool alloc] init];

rect.origin.x = 0;
rect.origin.y = 0;
rect.size.width = w;
rect.size.height = h;
rect.origin.y = CGDisplayPixelsHigh(kCGDirectMainDisplay) - rect.origin.y - rect.size.height;

style = (NSWindowStyleMaskTitled | NSWindowStyleMaskClosable | NSWindowStyleMaskMiniaturizable | NSWindowStyleMaskResizable);
// NSRect viewport = [contentView bounds];
// if ([contentView respondsToSelector:@selector(convertRectToBacking:)]) {
// viewport = [contentView convertRectToBacking:viewport];
// }
// rect.size.width = viewport.size.width;
// rect.size.height = viewport.size.height;

/* Figure out which screen to place this window */
NSScreen *screen = nil;
for (NSScreen *candidate in screens) {
NSRect screenRect = [candidate frame];
if (rect.origin.x >= screenRect.origin.x && rect.origin.x < screenRect.origin.x + screenRect.size.width &&
rect.origin.y >= screenRect.origin.y && rect.origin.y < screenRect.origin.y + screenRect.size.height) {
screen = candidate;
rect.origin.x -= screenRect.origin.x;
rect.origin.y -= screenRect.origin.y;
}
}

nswindow = [[NSWindow alloc] initWithContentRect:rect styleMask:style backing:NSBackingStoreBuffered defer:FALSE screen:screen];

#if MAC_OS_X_VERSION_MAX_ALLOWED >= 101200 /* Added in the 10.12.0 SDK. */
/* By default, don't allow users to make our window tabbed in 10.12 or later */
if ([nswindow respondsToSelector:@selector(setTabbingMode:)]) {
[nswindow setTabbingMode:NSWindowTabbingModeDisallowed];
}
#endif
[nswindow setCollectionBehavior:NSWindowCollectionBehaviorFullScreenPrimary];
rect = [nswindow contentRectForFrameRect:[nswindow frame]];
NSView *contentView = [[NSView alloc] initWithFrame:rect];
#ifdef __clang__
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
#endif
if ([contentView respondsToSelector:@selector(setWantsBestResolutionOpenGLSurface:)]) {
// BOOL highdpi = (window->flags & SDL_WINDOW_ALLOW_HIGHDPI) != 0;
[contentView setWantsBestResolutionOpenGLSurface:YES];
}
#ifdef __clang__
#pragma clang diagnostic pop
#endif


[nswindow makeKeyAndOrderFront:nil];
[nswindow setContentView:contentView];
[contentView release];

[pool release];

return nswindow;
}

static void DestroyWindowCocoa(void *window)
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSWindow *nswindow = (NSWindow *) window;

[nswindow close];
[pool release];
}

#endif
44 changes: 44 additions & 0 deletions cmdline/nativeWindow/X11Window.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
//
// Created by moqi on 2020/6/4.
//
#include "nativeWindow.h"
#ifdef TEST_NATIVE_X11

static void *CreateWindowX11(int w, int h);
static void DestroyWindowX11(void *window);

NativeWindowFactory X11WindowFactory = {
"x11",
CreateWindowX11,
DestroyWindowX11
};

static Display *dpy;

static void *
CreateWindowX11(int w, int h)
{
Window window = 0;

dpy = XOpenDisplay(NULL);
if (dpy) {
window =
XCreateSimpleWindow(dpy, DefaultRootWindow(dpy), 0, 0, w, h, 0, 0,
0);
XMapRaised(dpy, window);
XSync(dpy, False);
}
return (void *) window;
}

static void
DestroyWindowX11(void *window)
{
if (dpy) {
XDestroyWindow(dpy, (Window) window);
XCloseDisplay(dpy);
}
}

#endif

51 changes: 51 additions & 0 deletions cmdline/nativeWindow/nativeWindow.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
//
// Created by moqi on 2020/6/4.
//

#ifndef CICADAMEDIA_NATIVEWINDOW_H
#define CICADAMEDIA_NATIVEWINDOW_H
#include <SDL2/SDL.h>
#include <SDL2/SDL_syswm.h>

typedef struct {
const char *tag;
void *(*CreateNativeWindow)(int w, int h);
void (*DestroyNativeWindow)(void *window);
} NativeWindowFactory;

#ifdef SDL_VIDEO_DRIVER_WINDOWS
#define TEST_NATIVE_WINDOWS
extern NativeWindowFactory WindowsWindowFactory;
#endif

#ifdef SDL_VIDEO_DRIVER_X11
#define TEST_NATIVE_X11
extern NativeWindowFactory X11WindowFactory;
#endif

#ifdef SDL_VIDEO_DRIVER_COCOA
/* Actually, we don't really do this, since it involves adding Objective C
support to the build system, which is a little tricky. You can uncomment
it manually though and link testnativecocoa.m into the test application.
*/
#define TEST_NATIVE_COCOA
extern NativeWindowFactory CocoaWindowFactory;
#endif

static NativeWindowFactory *getNativeFactor()
{
#ifdef SDL_VIDEO_DRIVER_COCOA
return &CocoaWindowFactory;
#endif

#ifdef SDL_VIDEO_DRIVER_WINDOWS
return &WindowsWindowFactory;
#endif
#ifdef SDL_VIDEO_DRIVER_X11
return &X11WindowFactory;
#endif
return NULL;
}


#endif//CICADAMEDIA_NATIVEWINDOW_H

0 comments on commit b68e37b

Please sign in to comment.