x11_window.cpp

来自「VLC媒体播放程序」· C++ 代码 · 共 621 行 · 第 1/2 页

CPP
621
字号
/***************************************************************************** * x11_window.cpp: X11 implementation of the Window class ***************************************************************************** * Copyright (C) 2003 VideoLAN * $Id: x11_window.cpp,v 1.30 2003/10/22 19:12:56 ipkiss Exp $ * * Authors: Cyril Deguet     <asmax@videolan.org> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, * USA. *****************************************************************************/#ifdef X11_SKINS//--- GENERAL ---------------------------------------------------------------//#include <math.h>//--- VLC -------------------------------------------------------------------#include <vlc/intf.h>//--- X11 -------------------------------------------------------------------#include <X11/Xlib.h>#include <X11/Xatom.h>#include <X11/extensions/shape.h>//--- SKIN ------------------------------------------------------------------#include "../os_api.h"#include "../src/anchor.h"#include "../controls/generic.h"#include "../src/window.h"#include "../os_window.h"#include "../src/event.h"#include "../os_event.h"#include "../src/graphics.h"#include "../os_graphics.h"#include "../src/skin_common.h"#include "../src/theme.h"#include "../os_theme.h"#include "x11_timer.h"static bool ToolTipCallback( void *data );static void DrawToolTipText( tooltip_t *tooltip );//---------------------------------------------------------------------------// Skinable Window//---------------------------------------------------------------------------X11Window::X11Window( intf_thread_t *p_intf, Window wnd, int x, int y,    bool visible, int transition, int normalalpha, int movealpha,    bool dragdrop, bool playondrop, string name )    : SkinWindow( p_intf, x, y, visible, transition, normalalpha, movealpha,              dragdrop  ){    // Set handles    Wnd         = wnd;    display     = p_intf->p_sys->display;    int screen  = DefaultScreen( display );    Name        = name;    LButtonDown = false;    RButtonDown = false;    // Creation of a graphic context that doesn't generate a GraphicsExpose    // event when using functions like XCopyArea    XGCValues gcVal;    gcVal.graphics_exposures = False;    XLOCK;    Gc = XCreateGC( display, wnd, GCGraphicsExposures, &gcVal );    XUNLOCK;    // Removing fading effect    Transition  = 0;    if( DragDrop )    {        // register the listview as a drop target        DropObject = new X11DropObject( p_intf, Wnd, playondrop );        Atom xdndAtom = XInternAtom( display, "XdndAware", False );        char xdndVersion = 4;        XLOCK;        XChangeProperty( display, wnd, xdndAtom, XA_ATOM, 32,                         PropModeReplace, (unsigned char *)&xdndVersion, 1);        XUNLOCK;    }    // Associate vlc icon to the window    XLOCK;    XWMHints *hints = XGetWMHints( display, Wnd );    if( !hints)    {        hints = XAllocWMHints();    }    if( p_intf->p_sys->iconPixmap != None )    {        hints->icon_pixmap = p_intf->p_sys->iconPixmap;        hints->flags |= IconPixmapHint;    }    if( p_intf->p_sys->iconMask != None )    {        hints->icon_mask = p_intf->p_sys->iconMask;        hints->flags |= IconMaskHint;    }    XSetWMHints( display, Wnd, hints );    XFree( hints );    XUNLOCK;    // Create Tool Tip window    XColor color;    color.red = 0xffff;    color.green = 0xffff;    color.blue = 0xa000;    Colormap cm = DefaultColormap( display, screen );    Window root = DefaultRootWindow( display );    XLOCK;    XAllocColor( display, cm, &color );    XSetWindowAttributes attr;    attr.background_pixel = color.pixel;    attr.override_redirect = True;    ToolTip.window = XCreateWindow( display, root, 0, 0, 1, 1, 1, 0,                                    InputOutput, CopyFromParent,                                    CWBackPixel|CWOverrideRedirect, &attr );    ToolTip.font = XLoadFont( display,                              "-*-helvetica-bold-r-*-*-*-80-*-*-*-*-*-*" );    gcVal.font = ToolTip.font;    gcVal.foreground = 0;    gcVal.background = color.pixel;    ToolTip.gc = XCreateGC( display, ToolTip.window,                             GCBackground|GCForeground|GCFont, &gcVal );    XUNLOCK;    ToolTip.display = display;    X11Timer *timer = new X11Timer( p_intf, 500000, ToolTipCallback, &ToolTip );    ToolTip.p_intf = p_intf;    ToolTip.timer = timer;    ToolTip.active = False;    // Double-click handling    ClickedX = 0;    ClickedY = 0;    ClickedTime = 0;    // TODO: can be retrieved somewhere ?    DblClickDelay = 400;}//---------------------------------------------------------------------------X11Window::~X11Window(){    if( DragDrop )    {        delete DropObject;    }    delete ToolTip.timer;    XLOCK;    XFreeGC( display, ToolTip.gc );    XFreeGC( display, Gc );    XDestroyWindow( display, ToolTip.window );    XDestroyWindow( display, Wnd );    XUNLOCK;}//---------------------------------------------------------------------------void X11Window::ToggleOnTop(){    XEvent ev;    ev.type = ClientMessage;    ev.xclient.display = display;    ev.xclient.window = Wnd;    ev.xclient.serial = 0;    ev.xclient.send_event = True;    ev.xclient.message_type = XInternAtom( display, "_NET_WM_STATE", True );    ev.xclient.format = 32;    ev.xclient.data.l[1] = XInternAtom( display, "_NET_WM_STATE_ABOVE", False);    ev.xclient.data.l[2] = 0;    ev.xclient.data.l[3] = 0;    ev.xclient.data.l[4] = 0;    if( !p_intf->p_sys->b_on_top )    {        // Set the window on top        ev.xclient.data.l[0] = 1; // _NET_WM_STATE_ADD    }    else    {        // Set the window not on top        ev.xclient.data.l[0] = 0; // _NET_WM_STATE_REMOVE    }    XLOCK;    XSendEvent( display, DefaultRootWindow( display ), False,                SubstructureRedirectMask | SubstructureNotifyMask, &ev );    XUNLOCK;    /* For KDE */    ev.xclient.data.l[1] = XInternAtom( display, "_NET_WM_STATE_STAYS_ON_TOP",                                        False);    XLOCK;    XSendEvent( display, DefaultRootWindow( display ), False,                SubstructureRedirectMask | SubstructureNotifyMask, &ev );    XUNLOCK;}//---------------------------------------------------------------------------void X11Window::OSShow( bool show ){    XLOCK;    XResizeWindow( display, Wnd, 1, 1 ); // Avoid flicker    XUNLOCK;    if( show )    {        // We do the call to XShapeCombineRegion() here because the window        // must be unmapped for this to work.        Drawable drawable = (( X11Graphics* )Image )->GetImage();        XLOCK;        XImage *image = XGetImage( display, drawable, 0, 0, Width, Height,                                    AllPlanes, ZPixmap );        if( image )        {            // Mask for transparency            Region region = XCreateRegion();            for( int line = 0; line < Height; line++ )            {                int start = 0, end = 0;                while( start < Width )                {                    while( start < Width && XGetPixel( image, start, line )                           == 0 )                    {                        start++;                    }                    end = start;                    while( end < Width && XGetPixel( image, end, line ) != 0)                    {                        end++;                    }                    XRectangle rect;                    rect.x = start;                    rect.y = line;                    rect.width = end - start + 1;                    rect.height = 1;                    Region newRegion = XCreateRegion();                    XUnionRectWithRegion( &rect, region, newRegion );                    XDestroyRegion( region );                    region = newRegion;                    start = end + 1;                }            }            XDestroyImage( image );            XShapeCombineRegion( display, Wnd, ShapeBounding, 0, 0, region,                                 ShapeSet );            XDestroyRegion( region );        }        else        {            msg_Err( p_intf, "X11Window::OSShow XShapeCombineRegion() failed");        }        XMapWindow( display, Wnd );        XMoveResizeWindow( display, Wnd, Left, Top, Width, Height );        XUNLOCK;    }    else    {        XLOCK;        XUnmapWindow( display, Wnd );        XUNLOCK;    }}//---------------------------------------------------------------------------bool X11Window::ProcessOSEvent( Event *evt ){    unsigned int msg = evt->GetMessage();    //unsigned int p1  = evt->GetParam1();    int          p2  = evt->GetParam2();    int          time;    int          posX, posY;    string       type;    int          button;    switch( msg )    {        case Expose:            RefreshFromImage( 0, 0, Width, Height );            return true;        case MotionNotify:            if( LButtonDown )                MouseMove( (int)( (XMotionEvent *)p2 )->x,                           (int)( (XMotionEvent *)p2 )->y, 1 );            else if( RButtonDown )                MouseMove( (int)( (XMotionEvent *)p2 )->x,                           (int)( (XMotionEvent *)p2 )->y, 2 );            else                MouseMove( (int)( (XMotionEvent *)p2 )->x,                           (int)( (XMotionEvent *)p2 )->y, 0 );            return true;

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?