From fc2d1edea995f93c30a685c07e3aa0d757267b83 Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Wed, 19 Aug 2015 12:45:21 +0200 Subject: [PATCH] linux-dist/x11: Enable fullscreen toggling via F11 button --- core/linux-dist/x11.cpp | 82 ++++++++++++++------- core/rend/gles/gles.cpp | 156 ++++++++++++++++++++-------------------- 2 files changed, 133 insertions(+), 105 deletions(-) diff --git a/core/linux-dist/x11.cpp b/core/linux-dist/x11.cpp index 381f29303..4e77129e2 100644 --- a/core/linux-dist/x11.cpp +++ b/core/linux-dist/x11.cpp @@ -27,6 +27,16 @@ int x11_keyboard_input = 0; int ndcid = 0; void* x11_glc; +bool x11_fullscreen = false; +int x11_width; +int x11_height; + +enum +{ + _NET_WM_STATE_REMOVE =0, + _NET_WM_STATE_ADD = 1, + _NET_WM_STATE_TOGGLE =2 +}; #ifdef TARGET_PANDORA static Cursor CreateNullCursor(Display *display, Window root) @@ -51,6 +61,23 @@ void* x11_glc; } #endif +void x11_window_set_fullscreen(bool fullscreen) +{ + XEvent xev; + xev.xclient.type = ClientMessage; + xev.xclient.window = x11_win; + xev.xclient.message_type = XInternAtom(x11_disp, "_NET_WM_STATE", False); + xev.xclient.format = 32; + xev.xclient.data.l[0] = 2; // _NET_WM_STATE_TOGGLE + xev.xclient.data.l[1] = XInternAtom(x11_disp, "_NET_WM_STATE_FULLSCREEN", True); + xev.xclient.data.l[2] = 0; // no second property to toggle + xev.xclient.data.l[3] = 1; + xev.xclient.data.l[4] = 0; + + printf("x11: setting fullscreen to %d\n", fullscreen); + XSendEvent(x11_disp, DefaultRootWindow(x11_disp), False, SubstructureNotifyMask, &xev); +} + void input_x11_handle() { if (x11_win && x11_keyboard_input) @@ -64,28 +91,25 @@ void input_x11_handle() { case KeyPress: case KeyRelease: - { - int dc_key = x11_keymap[e.xkey.keycode]; - - if (e.type == KeyPress) + if (e.type == KeyRelease && e.xkey.keycode == 95) // F11 button { - kcode[0] &= ~dc_key; + x11_fullscreen = !x11_fullscreen; + x11_window_set_fullscreen(x11_fullscreen); } else { - kcode[0] |= dc_key; + int dc_key = x11_keymap[e.xkey.keycode]; + if (e.type == KeyPress) + { + kcode[0] &= ~dc_key; + } + else + { + kcode[0] |= dc_key; + } } - //printf("KEY: %d -> %d: %d\n",e.xkey.keycode, dc_key, x11_dc_buttons ); - } - break; - - - { - printf("KEYRELEASE\n"); - } - break; - + break; } } } @@ -218,31 +242,35 @@ void x11_window_create() ui32Mask = CWBackPixel | CWBorderPixel | CWEventMask | CWColormap; #ifdef TARGET_PANDORA - int width = 800; - int height = 480; + x11_width = 800; + x11_height = 480; #else - int width = cfgLoadInt("x11", "width", WINDOW_WIDTH); - int height = cfgLoadInt("x11", "height", WINDOW_HEIGHT); + x11_width = cfgLoadInt("x11", "width", WINDOW_WIDTH); + x11_height = cfgLoadInt("x11", "height", WINDOW_HEIGHT); #endif - if (width == -1) + if (x11_width < 0 || x11_height < 0) { - width = XDisplayWidth(x11Display, x11Screen); - height = XDisplayHeight(x11Display, x11Screen); + x11_width = XDisplayWidth(x11Display, x11Screen); + x11_height = XDisplayHeight(x11Display, x11Screen); } // Creates the X11 window - x11Window = XCreateWindow(x11Display, RootWindow(x11Display, x11Screen), (ndcid%3)*640, (ndcid/3)*480, width, height, + x11Window = XCreateWindow(x11Display, RootWindow(x11Display, x11Screen), (ndcid%3)*640, (ndcid/3)*480, x11_width, x11_height, 0, depth, InputOutput, x11Visual->visual, ui32Mask, &sWA); - #ifdef TARGET_PANDORA + if(x11_fullscreen) + { + // fullscreen Atom wmState = XInternAtom(x11Display, "_NET_WM_STATE", False); Atom wmFullscreen = XInternAtom(x11Display, "_NET_WM_STATE_FULLSCREEN", False); XChangeProperty(x11Display, x11Window, wmState, XA_ATOM, 32, PropModeReplace, (unsigned char *)&wmFullscreen, 1); XMapRaised(x11Display, x11Window); - #else + } + else + { XMapWindow(x11Display, x11Window); #if !defined(GLES) @@ -270,7 +298,7 @@ void x11_window_create() die("Failed to create GL3.1 context\n"); } #endif - #endif + } XFlush(x11Display); diff --git a/core/rend/gles/gles.cpp b/core/rend/gles/gles.cpp index f700ec384..601235f45 100755 --- a/core/rend/gles/gles.cpp +++ b/core/rend/gles/gles.cpp @@ -73,7 +73,7 @@ float fb_scale_x,fb_scale_y; //Fragment and vertex shaders code //pretty much 1:1 copy of the d3d ones for now -const char* VertexShaderSource = +const char* VertexShaderSource = #ifndef GLES "#version 140 \n" #endif @@ -112,7 +112,7 @@ void main() \n\ -const char* VertexShaderSource = +const char* VertexShaderSource = "" "/* Test Projection Matrix */" "" @@ -225,11 +225,11 @@ lowp float fog_mode2(highp float invW) \n\ #endif -const char* PixelPipelineShader = +const char* PixelPipelineShader = #ifndef GLES "#version 140 \n" "out vec4 FragColor; \n" -#endif +#endif "\ \ #define cp_AlphaTest %d \n\ @@ -318,7 +318,7 @@ void main() \n\ " FRAGCOL "=color; \n\ }"; -const char* ModifierVolumeShader = +const char* ModifierVolumeShader = #ifndef GLES "#version 140 \n" "out vec4 FragColor; \n" @@ -331,7 +331,7 @@ void main() \n\ " FRAGCOL "=vec4(0.0, 0.0, 0.0, sp_ShaderColor); \n\ }"; -const char* OSD_Shader = +const char* OSD_Shader = #ifndef GLES "#version 140 \n" "out vec4 FragColor; \n" @@ -370,7 +370,7 @@ int screen_height; if(gl.setup.display == EGL_NO_DISPLAY) gl.setup.display = eglGetDisplay((EGLNativeDisplayType) EGL_DEFAULT_DISPLAY); - + // Initialise EGL EGLint maj, min; if (!eglInitialize(gl.setup.display, &maj, &min)) @@ -385,7 +385,7 @@ int screen_height; EGLint pi32ConfigAttribs[] = { EGL_SURFACE_TYPE, EGL_WINDOW_BIT, EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT , EGL_DEPTH_SIZE, 24, EGL_STENCIL_SIZE, 8, EGL_NONE }; EGLint pi32ContextAttribs[] = { EGL_CONTEXT_CLIENT_VERSION, 2 , EGL_NONE }; - + int num_config; EGLConfig config; @@ -456,14 +456,14 @@ int screen_height; #ifdef TARGET_PANDORA eglMakeCurrent( gl.setup.display, NULL, NULL, EGL_NO_CONTEXT ); if (gl.setup.context) - eglDestroyContext(gl.setup.display, gl.setup.context); + eglDestroyContext(gl.setup.display, gl.setup.context); if (gl.setup.surface) eglDestroySurface(gl.setup.display, gl.setup.surface); if (gl.setup.display) eglTerminate(gl.setup.display); if (fbdev>=0) close( fbdev ); - + fbdev=-1; gl.setup.context=0; gl.setup.surface=0; @@ -497,9 +497,9 @@ int screen_height; #define WGL_CONTEXT_DEBUG_BIT_ARB 0x0001 #define WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x0002 #define ERROR_INVALID_VERSION_ARB 0x2095 - #define WGL_CONTEXT_CORE_PROFILE_BIT_ARB 0x00000001 + #define WGL_CONTEXT_CORE_PROFILE_BIT_ARB 0x00000001 - typedef BOOL (WINAPI * PFNWGLCHOOSEPIXELFORMATARBPROC) (HDC hdc, const int *piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats, + typedef BOOL (WINAPI * PFNWGLCHOOSEPIXELFORMATARBPROC) (HDC hdc, const int *piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats, int *piFormats, UINT *nNumFormats); typedef HGLRC (WINAPI * PFNWGLCREATECONTEXTATTRIBSARBPROC) (HDC hDC, HGLRC hShareContext, const int *attribList); typedef BOOL (WINAPI * PFNWGLSWAPINTERVALEXTPROC) (int interval); @@ -535,7 +535,7 @@ int screen_height; /*HDC*/ ourWindowHandleToDeviceContext = (HDC)hdc;//GetDC((HWND)hwnd); int letWindowsChooseThisPixelFormat; - letWindowsChooseThisPixelFormat = ChoosePixelFormat(ourWindowHandleToDeviceContext, &pfd); + letWindowsChooseThisPixelFormat = ChoosePixelFormat(ourWindowHandleToDeviceContext, &pfd); SetPixelFormat(ourWindowHandleToDeviceContext,letWindowsChooseThisPixelFormat, &pfd); HGLRC ourOpenGLRenderingContext = wglCreateContext(ourWindowHandleToDeviceContext); @@ -566,7 +566,7 @@ int screen_height; int attribs[] = { WGL_CONTEXT_MAJOR_VERSION_ARB, 3, - WGL_CONTEXT_MINOR_VERSION_ARB, 1, + WGL_CONTEXT_MINOR_VERSION_ARB, 1, WGL_CONTEXT_FLAGS_ARB, WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB, WGL_CONTEXT_PROFILE_MASK_ARB, WGL_CONTEXT_CORE_PROFILE_BIT_ARB, 0 @@ -614,8 +614,8 @@ int screen_height; { extern void* x11_glc; - glXMakeCurrent((Display*)libPvr_GetRenderSurface(), - (GLXDrawable)libPvr_GetRenderTarget(), + glXMakeCurrent((Display*)libPvr_GetRenderSurface(), + (GLXDrawable)libPvr_GetRenderTarget(), (GLXContext)x11_glc); screen_width = 640; @@ -672,19 +672,19 @@ struct ShaderUniforms_t { if (s->cp_AlphaTestValue!=-1) glUniform1f(s->cp_AlphaTestValue,PT_ALPHA); - + if (s->scale!=-1) glUniform4fv( s->scale, 1, scale_coefs); - + if (s->depth_scale!=-1) glUniform4fv( s->depth_scale, 1, depth_coefs); - + if (s->sp_FOG_DENSITY!=-1) glUniform1f( s->sp_FOG_DENSITY,fog_den_float); if (s->sp_FOG_COL_RAM!=-1) glUniform3fv( s->sp_FOG_COL_RAM, 1, ps_FOG_COL_RAM); - + if (s->sp_FOG_COL_VERT!=-1) glUniform3fv( s->sp_FOG_COL_VERT, 1, ps_FOG_COL_VERT); @@ -797,7 +797,7 @@ int GetProgramID(u32 cp_AlphaTest, u32 pp_ClipTestMode, bool CompilePipelineShader( PipelineShader* s) { char pshader[8192]; - + sprintf(pshader,PixelPipelineShader, s->cp_AlphaTest,s->pp_ClipTestMode,s->pp_UseAlpha, s->pp_Texture,s->pp_IgnoreTexA,s->pp_ShadInstr,s->pp_Offset,s->pp_FogCtrl); @@ -813,10 +813,10 @@ bool CompilePipelineShader( PipelineShader* s) //get the uniform locations s->scale = glGetUniformLocation(s->program, "scale"); s->depth_scale = glGetUniformLocation(s->program, "depth_scale"); - - + + s->pp_ClipTest = glGetUniformLocation(s->program, "pp_ClipTest"); - + s->sp_FOG_DENSITY = glGetUniformLocation(s->program, "sp_FOG_DENSITY"); s->cp_AlphaTestValue= glGetUniformLocation(s->program, "cp_AlphaTestValue"); @@ -907,13 +907,13 @@ bool gl_create_resources() } - + gl.modvol_shader.program=gl_CompileAndLink(VertexShaderSource,ModifierVolumeShader); gl.modvol_shader.scale = glGetUniformLocation(gl.modvol_shader.program, "scale"); gl.modvol_shader.sp_ShaderColor = glGetUniformLocation(gl.modvol_shader.program, "sp_ShaderColor"); gl.modvol_shader.depth_scale = glGetUniformLocation(gl.modvol_shader.program, "depth_scale"); - + gl.OSD_SHADER.program=gl_CompileAndLink(VertexShaderSource,OSD_Shader); printf("OSD: %d\n",gl.OSD_SHADER.program); gl.OSD_SHADER.scale=glGetUniformLocation(gl.OSD_SHADER.program, "scale"); @@ -987,7 +987,7 @@ float fog_coefs[]={0,0}; void tryfit(float* x,float* y) { //y=B*ln(x)+A - + double sylnx=0,sy=0,slnx=0,slnx2=0; u32 cnt=0; @@ -1002,14 +1002,14 @@ void tryfit(float* x,float* y) if (i>0 && y[i]==0 && y[i-1]==0) continue; - + //Add many samples for first and last value (fog-in, fog-out -> important) if (i>0 && y[i]!=1 && y[i-1]==1) rep=10000; if (i<128 && y[i]!=0 && y[i+1]==0) rep=10000; - + for (int j=0;j255) transparency=255; @@ -1171,26 +1171,26 @@ static void DrawCenteredText(float yy, float scale, int transparency, const char int c=text[i]; float u=float(c%16); float v=float(c/16); - + vtx.col[0]=vtx.col[1]=vtx.col[2]=255; vtx.col[3]=transparency; - + vtx.x=x; vtx.y=y; vtx.u=u*step+step2; vtx.v=v*step+step2; *pvrrc.verts.Append()=vtx; - + vtx.x=x+w; vtx.y=y; vtx.u=u*step+step-step2; vtx.v=v*step+step2; *pvrrc.verts.Append()=vtx; - + vtx.x=x; vtx.y=y+h; vtx.u=u*step+step2; vtx.v=v*step+step-step2; *pvrrc.verts.Append()=vtx; - + vtx.x=x+w; vtx.y=y+h; vtx.u=u*step+step-step2; vtx.v=v*step+step-step2; *pvrrc.verts.Append()=vtx; - + x+=w; osd_count+=4; @@ -1201,47 +1201,47 @@ static void DrawRightedText(float yy, float scale, int transparency, const char* // Transparency 255=opaque, 0=not visible { Vertex vtx; - + vtx.z=1; float w=float(strlen(text)*14)*scale; - + float x=640-w; float y=yy; float h=16.0f*scale; w=14.0f*scale; float step=32.0f/512.0f; float step2=4.0f/512.0f; - + if (transparency<0) transparency=0; if (transparency>255) transparency=255; - + for (int i=0; i too much to left ShaderUniforms.scale_coefs[0]=2.0f/(screen_width/dc2s_scale_h); ShaderUniforms.scale_coefs[1]=-2/dc_height; ShaderUniforms.scale_coefs[2]=1-2*ds2s_offs_x/(screen_width); ShaderUniforms.scale_coefs[3]=-1; - + glUniform4fv( gl.OSD_SHADER.scale, 1, ShaderUniforms.scale_coefs); */ glEnable(GL_BLEND); glDisable(GL_DEPTH_TEST); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - + glDepthMask(false); glDepthFunc(GL_ALWAYS); - + glDisable(GL_CULL_FACE); glDisable(GL_SCISSOR_TEST); - + int dfa=osd_count/4; @@ -1447,7 +1447,7 @@ bool RenderFrame() //if (FrameCount&7) return; //Setup the matrix - + //TODO: Make this dynamic float vtx_min_fZ=0.f; //pvrrc.fZ_min; float vtx_max_fZ=pvrrc.fZ_max; @@ -1481,7 +1481,7 @@ bool RenderFrame() Window space: translated NDC (viewport, glDepth) - Attributes: + Attributes: //this needs to be cleared up, been some time since I wrote my rasteriser and i'm starting //to forget/mixup stuff vaX -> VS output @@ -1513,7 +1513,7 @@ bool RenderFrame() zt_o=(-min_fz-1)/fz == (-min_fz-1)*W - x=fx/(fx_range/2)-1 //0 to max -> -1 to 1 + x=fx/(fx_range/2)-1 //0 to max -> -1 to 1 y=fy/(-fy_range/2)+1 //0 to max -> 1 to -1 z=-min_fz*W + (zt_s-1) //0 to +inf -> -1 to 1 @@ -1574,7 +1574,7 @@ bool RenderFrame() scale_x *= 0.5f; } } - + if (SCALER_CTL.hscale) { scale_x*=2; @@ -1629,7 +1629,7 @@ bool RenderFrame() //printf("scale: %f, %f, %f, %f\n",scale_coefs[0],scale_coefs[1],scale_coefs[2],scale_coefs[3]); - + //VERT and RAM fog color constants u8* fog_colvert_bgra=(u8*)&FOG_COL_VERT; u8* fog_colram_bgra=(u8*)&FOG_COL_RAM; @@ -1698,17 +1698,17 @@ bool RenderFrame() channels=GL_RGBA; format=GL_UNSIGNED_SHORT_5_5_5_1; break; - - case 1: //0x1 565 RGB 16 bit + + case 1: //0x1 565 RGB 16 bit channels=GL_RGB; format=GL_UNSIGNED_SHORT_5_6_5; break; - + case 2: //0x2 4444 ARGB 16 bit channels=GL_RGBA; format=GL_UNSIGNED_SHORT_5_5_5_1; break; - + case 3://0x3 1555 ARGB 16 bit The alpha value is determined by comparison with the value of fb_alpha_threshold. channels=GL_RGBA; format=GL_UNSIGNED_SHORT_5_5_5_1; @@ -1718,12 +1718,12 @@ bool RenderFrame() channels=GL_RGB; format=GL_UNSIGNED_SHORT_5_6_5; break; - + case 5: //0x5 0888 KRGB 32 bit K is the value of fk_kval. channels=GL_RGBA; format=GL_UNSIGNED_SHORT_4_4_4_4; break; - + case 6: //0x6 8888 ARGB 32 bit channels=GL_RGBA; format=GL_UNSIGNED_SHORT_4_4_4_4; @@ -1742,7 +1742,7 @@ bool RenderFrame() glBindFramebuffer(GL_FRAMEBUFFER,0); #endif } - + //Clear depth //Color is cleared by the bgp if (settings.rend.WideScreen) @@ -1776,7 +1776,7 @@ bool RenderFrame() int offs_x=ds2s_offs_x+0.5f; //this needs to be scaled - + //not all scaling affects pixel operations, scale to adjust for that scale_x *= scissoring_scale_x; @@ -1785,7 +1785,7 @@ bool RenderFrame() printf("SS: %dx%d\n", screen_width, screen_height); printf("SCI: %d, %f\n", pvrrc.fb_X_CLIP.max, dc2s_scale_h); printf("SCI: %f, %f, %f, %f\n", offs_x+pvrrc.fb_X_CLIP.min/scale_x,(pvrrc.fb_Y_CLIP.min/scale_y)*dc2s_scale_h,(pvrrc.fb_X_CLIP.max-pvrrc.fb_X_CLIP.min+1)/scale_x*dc2s_scale_h,(pvrrc.fb_Y_CLIP.max-pvrrc.fb_Y_CLIP.min+1)/scale_y*dc2s_scale_h); - #endif + #endif glScissor(offs_x+pvrrc.fb_X_CLIP.min/scale_x,(pvrrc.fb_Y_CLIP.min/scale_y)*dc2s_scale_h,(pvrrc.fb_X_CLIP.max-pvrrc.fb_X_CLIP.min+1)/scale_x*dc2s_scale_h,(pvrrc.fb_Y_CLIP.max-pvrrc.fb_Y_CLIP.min+1)/scale_y*dc2s_scale_h); if (settings.rend.WideScreen && pvrrc.fb_X_CLIP.min==0 && ((pvrrc.fb_X_CLIP.max+1)/scale_x==640) && (pvrrc.fb_Y_CLIP.min==0) && ((pvrrc.fb_Y_CLIP.max+1)/scale_y==480 ) ) @@ -1835,7 +1835,7 @@ bool rend_single_frame() bool do_swp=false; //if (kcode[0]&(1<<9)) { - + //clear up & free data .. tactx_Recycle(_pvrrc); @@ -1856,16 +1856,16 @@ struct glesrend : Renderer { bool Init() { return gles_init(); } void Resize(int w, int h) { screen_width=w; screen_height=h; } - void Term() { } + void Term() { } bool Process(TA_context* ctx) { return ProcessFrame(ctx); } bool Render() { return RenderFrame(); } - void Present() { gl_swap(); } + void Present() { gl_swap(); glViewport(0, 0, screen_width, screen_height); } void DrawOSD() { OSD_DRAW(); } - virtual u32 GetTexture(TSP tsp, TCW tcw) { + virtual u32 GetTexture(TSP tsp, TCW tcw) { return gl_GetTexture(tsp, tcw); } }; @@ -1987,7 +1987,7 @@ GLuint loadPNG(const string& fname, int &width, int &height) //row_pointers is for pointing to image_data for reading the png with libpng png_bytep *row_pointers = new png_bytep[height]; - if (!row_pointers) + if (!row_pointers) { //clean up memory and close stuff png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);