?? skl_drv_x11.cpp
字號(hào):
/******************************************************** * Some code. Copyright (C) 2003 by Pascal Massimino. * * All Rights Reserved. (http://skal.planet-d.net) * * For Educational/Academic use ONLY. See 'LICENSE.TXT'.* ********************************************************//* * skl_drv_x11.cpp * * X11 (/SHM) video main driver ********************************************************/#include "skl_video.h"#ifndef SKL_NO_VIDEO#ifdef SKL_USE_X11#include "skl_syst/skl_dyn_load.h"#include "./skl_drv_x11.h"#if defined(__IRIX__)// #define COMPLETION_BUG#endif#if defined(__SUN__) || defined(__IRIX__)#define DONT_DETACH_FIRST#endif//////////////////////////////////////////////////////////// SKL_X11_VIDEO_I//////////////////////////////////////////////////////////SKL_X11_VIDEO_I::SKL_X11_VIDEO_I(SKL_MEM_I *Mem, SKL_CST_STRING Name, SKL_CST_STRING Dsp_Name) : SKL_VIDEO_I(Mem, Name) , _Screen(-1) , _XDisplay(0) , _Display_Name(Dsp_Name) , _Use_Shm(0), _Use_DGA(0) , _Has_Shm(0), _Has_DGA(0) , _VSync(1){ _Caps = (CAPS)( HAS_BACKBUFFER );#if defined(SKL_USE_SHM) Set_Param(USE_SHM, 0, 1);#endif#if defined(SKL_USE_DGA) Set_Param(USE_DGA, 0, 1); _Caps = (CAPS)(_Caps|HAS_FULLSCREEN);#endif Ping();}SKL_X11_VIDEO_I::~SKL_X11_VIDEO_I(){ Cleanup();}void SKL_X11_VIDEO_I::Cleanup(){ Clear_Modes(); if (_XDisplay!=0) XCloseDisplay(_XDisplay); _Screen = -1; _XDisplay = 0; Set_Not_Ok();}//////////////////////////////////////////////////////////SKL_FORMAT SKL_X11_VIDEO_I::Get_Visual_Format(XVisualInfo *Info) const{ int Dsp_Depth; SKL_FORMAT Fmt; Visual *v = Info->visual; // Ackward method to get the exact Pixel_Depth of display XImage *XImg = XCreateImage( _XDisplay, v, Info->depth, ZPixmap, 0, 0, 16, 16, BitmapPad(_XDisplay), 0 ); if (XImg!=0) { Dsp_Depth = XImg->bytes_per_line / 16; XDestroyImage( XImg ); } else { Dsp_Depth = (Info->depth+7)/8; // geee!!! finger crossing } if (v->c_class==PseudoColor) Fmt = 0x00000 | (Dsp_Depth<<16); // cmapped format else Fmt = SKL_FORMAT(v->red_mask, v->green_mask, v->blue_mask, 0, Dsp_Depth); return Fmt;}int SKL_X11_VIDEO_I::Scan_Modes(SKL_FORMAT Fmt){ int Nb_Modes; XVisualInfo Template; Template.screen = DefaultScreen(_XDisplay); // _Screen; Template.c_class = TrueColor; XVisualInfo *Info = XGetVisualInfo( _XDisplay, VisualClassMask | VisualScreenMask, &Template, &Nb_Modes ); if (Info==0) { fprintf( stderr, "Can't get X visual\n" ); return 0; } int Depth = -1; if (Fmt.Raw_Depth()!=0) Depth = 8 * Fmt.Raw_Depth(); int Nb=0; for( int i=0; i<Nb_Modes; i++) { // Get rid of Visual with depth<8 and skip bad visuals if (Depth!=-1 && Info[i].depth!=Depth) continue; else if (Info[i].depth<8) continue; else if ( Info[i].c_class==StaticColor || Info[i].c_class==StaticGray || Info[i].c_class==GrayScale ) continue; SKL_X11_WIN *Mode = new (Get_Mem()) SKL_X11_WIN(this); Mode->Init( &Info[i] ); if (Fmt.Bits()==0x0 || Mode->Format().Bits()==Fmt.Bits()) { Add_Mode( Mode ); Nb++; } else delete Mode; } XFree( Info ); return Nb;}int SKL_X11_VIDEO_I::Ping(){ Cleanup(); if (_Display_Name==0) _Display_Name = XDisplayName(0); _XDisplay = XOpenDisplay(_Display_Name); if (_XDisplay==0) return 0; _Screen = DefaultScreen(_XDisplay); // TODO: should it be an option? _Has_Shm = 0;#ifdef SKL_USE_SHM if ( (XShmQueryExtension(_XDisplay)!=0) && (_Display_Name[0]!=':')) fprintf( stderr, "Can't use SHM when display is redirected.\n" ); else _Has_Shm = 1;#endif _Has_DGA = 0;#ifdef SKL_USE_DGA _Has_DGA = _DGA_Infos.Init(_XDisplay, _Screen);#endif Clear_Modes(); Scan_Modes(); Set_Ok(); return 1;}//////////////////////////////////////////////////////////// Params//////////////////////////////////////////////////////////int SKL_X11_VIDEO_I::Set_Param(PARAM Opt, SKL_CST_STRING SValue, int IValue){ switch(Opt) { case USE_DISPLAY: _Display_Name = SValue; return Ping(); case USE_SHM: _Use_Shm = (IValue!=0); break; case USE_DGA: _Use_DGA = (IValue!=0); break; case VSYNC: _VSync = (IValue!=0); break; default: return 0; } return 1;}int SKL_X11_VIDEO_I::Get_Param(PARAM Opt, SKL_CST_STRING *SValue, int *IValue) const{ switch(Opt) { case USE_DISPLAY: *SValue = _Display_Name; return 1; case USE_SHM: *IValue = ((_Has_Shm&_Use_Shm)!=0); return 1; case USE_DGA: *IValue = ((_Has_DGA&_Use_DGA)!=0); return 1; case VSYNC: *IValue = _VSync; return 1; default: break; } return 0;}//////////////////////////////////////////////////////////// Fullscreen API//////////////////////////////////////////////////////////SKL_WINDOW *SKL_X11_VIDEO_I::Set_Fullscreen_Mode(const SKL_BTM *FMode, int Show){ const SKL_X11_WIN *Mode = (const SKL_X11_WIN *)FMode; SKL_X11_RAW_WIN *Win;#ifdef SKL_USE_SHM if (_Has_Shm & _Use_Shm) { Win = new (Get_Mem()) SKL_X11_SHM_WIN( Mode ); } else #endif Win = new (Get_Mem()) SKL_X11_RAW_WIN( Mode ); if (!Win->Create_Window(Show)) { delete Win; // Argh! return 0; } return Win;}void SKL_X11_VIDEO_I::Shutdown_Fullscreen() {}//////////////////////////////////////////////////////////// Window API//////////////////////////////////////////////////////////SKL_WINDOW *SKL_X11_VIDEO_I::Open_Window(int W, int H, SKL_FORMAT Fmt, int With_Backbuffer, int Show){ const SKL_X11_WIN *Mode = (const SKL_X11_WIN *)Get_Fullscreen_Mode(); if (!Is_Fullscreen()) Mode = (const SKL_X11_WIN *)Get_Mode_Infos(Search_Best_Mode(W, H, Fmt)); SKL_X11_RAW_WIN *Win;#ifdef SKL_USE_SHM if (_Has_Shm&_Use_Shm) { Win = new (Get_Mem()) SKL_X11_SHM_WIN( Mode, W, H ); } else #endif Win = new (Get_Mem()) SKL_X11_RAW_WIN( Mode, W, H ); if (!Win->Create_Window(Show)) { delete Win; // Argh! return 0; } return Win;}int SKL_X11_VIDEO_I::Needs_Conversion(const SKL_WINDOW *Win, SKL_FORMAT Fmt) const{ SKL_ASSERT(Win!=0); return !Win->Format().Is_Compatible_With(Fmt);}//////////////////////////////////////////////////////////// -- external symbol exported//////////////////////////////////////////////////////////#include "skl_syst/skl_dyn_load.h"SKL_DYN_FACTORY(SKL_X11_VIDEO_I) { return (SKL_ANY)::new SKL_X11_VIDEO_I(SKL_MEM, "Drv X11");}//////////////////////////////////////////////////////////// SKL_X11_WIN//////////////////////////////////////////////////////////SKL_X11_WIN::SKL_X11_WIN(SKL_X11_VIDEO_I *Drv) : SKL_WINDOW(Drv->Get_Mem()) , _Drv(Drv) , _Depth(0) , _Visual(0){}SKL_X11_WIN::~SKL_X11_WIN() { SKL_ASSERT(_Drv!=0);}void SKL_X11_WIN::Init(XVisualInfo *Info){ Display *Dsp = Get_XDisplay(); int Screen = Get_Screen(); _Depth = Info->depth; _Visual = Info->visual; SKL_FORMAT Fmt = _Drv->Get_Visual_Format(Info); int W = DisplayWidth( Dsp, Screen ); int H = DisplayHeight( Dsp, Screen ); Set_Virtual( W, H, Fmt );}void SKL_X11_WIN::Print_Infos() const{ SKL_BTM::Print_Infos(); printf( " [Depth=%d Q=%d Visual=0x%8p]", _Depth, Quantum(), (SKL_BYTE*)_Visual ); if (_Visual) printf( " (id=%d c=%d cmapsize=%d b/rgb=%d)", (int)_Visual->visualid, (int)_Visual->c_class, (int)_Visual->map_entries, (int)_Visual->bits_per_rgb ); printf( "\n");}//////////////////////////////////////////////////////////// -- Raw X11 calls. It's time for the Real Stuff :) -- ////////////////////////////////////////////////////////////#define X11_MASKS StructureNotifyMask| ExposureMask | \ KeyReleaseMask | KeyPressMask | \ ButtonPressMask | ButtonReleaseMask | \ ButtonMotionMask | PointerMotionMask//////////////////////////////////////////////////////////// SKL_X11_RAW_WIN//////////////////////////////////////////////////////////SKL_X11_RAW_WIN::SKL_X11_RAW_WIN(const SKL_X11_WIN *w, int W, int H) : SKL_X11_WIN(w->Drv()) , _XImg(0) , _Win(0) , _Pixels(0) , _XCMap(None) , _Root_CMap(None) , _Cells(0){ _Depth = w->Get_Depth(); _Visual = w->Get_Visual(); if (W==0) W = w->Width(); if (H==0) H = w->Height(); int BpS = ( W*w->Quantum() + 7) & ~7; // pad to 8 Set_Virtual( W, H, w->Format(), 0, BpS, 0);// Display *Dsp = Get_XDisplay();// int Screen = Get_Screen();// _XCMap = (Colormap)DefaultColormap( Dsp, Screen );}SKL_X11_RAW_WIN::~SKL_X11_RAW_WIN(){ Hide(); Cleanup();}void SKL_X11_RAW_WIN::Cleanup(){ Display *Dsp = Get_XDisplay(); if ( _XImg!=0 ) { XDestroyImage( _XImg ); _XImg = 0; } if (_Root_CMap!=None) { XFreeColormap( Dsp, _Root_CMap ); _Root_CMap = None; } if ( _Win!=(Window)0 ) { if (_Cells) XFreeColors( Dsp, _XCMap, _Pixels, 256, 0 ); if (_XCMap!=None) XFreeColormap( Dsp, _XCMap ); if (_Pixels) Get_Mem()->Delete( _Pixels, 256*sizeof(*_Pixels) ); XFreeGC( Dsp, _GC ); XDestroyWindow( Dsp, _Win ); _Win = (Window)0; _XCMap = None; _Cells = 0; _Pixels = 0; }}void SKL_X11_RAW_WIN::Set_Name(SKL_CST_STRING Name) { SKL_WINDOW::Set_Name( Name ); if (_Win!=0 && _Drv!=0) XStoreName( _Drv->Get_XDisplay(), _Win, Name );}//////////////////////////////////////////////////////////int SKL_X11_RAW_WIN::Create_XCMap(){ SKL_ASSERT( _XCMap == (Colormap)None && _Pixels == 0 ); Display *Dsp = Get_XDisplay(); if ( Format().Depth()==1 ) { _Pixels = (unsigned long*)Get_Mem()->New( 256*sizeof(unsigned long) ); _XCMap = XCreateColormap( Dsp, _Win, _Visual, AllocNone ); if (_Visual->c_class==PseudoColor) { _Cells = XAllocColorCells( Dsp, _XCMap, 0, 0, 0, _Pixels, 256 ); if ( _Cells==0 ) return 0;
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -