unixsite.cpp
上传用户:zhongxx05
上传日期:2007-06-06
资源大小:33641k
文件大小:70k
源码类别:

Symbian

开发平台:

C/C++

  1. /* ***** BEGIN LICENSE BLOCK ***** 
  2.  * Version: RCSL 1.0/RPSL 1.0 
  3.  *  
  4.  * Portions Copyright (c) 1995-2002 RealNetworks, Inc. All Rights Reserved. 
  5.  *      
  6.  * The contents of this file, and the files included with this file, are 
  7.  * subject to the current version of the RealNetworks Public Source License 
  8.  * Version 1.0 (the "RPSL") available at 
  9.  * http://www.helixcommunity.org/content/rpsl unless you have licensed 
  10.  * the file under the RealNetworks Community Source License Version 1.0 
  11.  * (the "RCSL") available at http://www.helixcommunity.org/content/rcsl, 
  12.  * in which case the RCSL will apply. You may also obtain the license terms 
  13.  * directly from RealNetworks.  You may not use this file except in 
  14.  * compliance with the RPSL or, if you have a valid RCSL with RealNetworks 
  15.  * applicable to this file, the RCSL.  Please see the applicable RPSL or 
  16.  * RCSL for the rights, obligations and limitations governing use of the 
  17.  * contents of the file.  
  18.  *  
  19.  * This file is part of the Helix DNA Technology. RealNetworks is the 
  20.  * developer of the Original Code and owns the copyrights in the portions 
  21.  * it created. 
  22.  *  
  23.  * This file, and the files included with this file, is distributed and made 
  24.  * available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 
  25.  * EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL SUCH WARRANTIES, 
  26.  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS 
  27.  * FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 
  28.  * 
  29.  * Technology Compatibility Kit Test Suite(s) Location: 
  30.  *    http://www.helixcommunity.org/content/tck 
  31.  * 
  32.  * Contributor(s): 
  33.  *                 Phil Dibowitz
  34.  *  
  35.  * ***** END LICENSE BLOCK ***** */ 
  36. #ifndef _UNIX
  37. #error This is the UNIX platform specific implementation.
  38. #endif
  39. //
  40. // System includes...
  41. //
  42. #include <stdio.h>
  43. #include "hlxclib/string.h"
  44. #include <X11/Intrinsic.h>
  45. #include <X11/Shell.h>
  46. #include <X11/Xlib.h>
  47. #include <X11/Xutil.h>
  48. #include <X11/keysym.h>
  49. #include <X11/Xos.h>
  50. #include <X11/cursorfont.h>
  51. #include <X11/extensions/XShm.h>
  52. //
  53. // RMA includes...
  54. //
  55. #include "hxcom.h"
  56. #include "hxcore.h"
  57. #include "hxevent.h"
  58. #include "hxwintyp.h"
  59. #include "hxwin.h"
  60. #include "hxsite2.h"
  61. #include "hxtypes.h"
  62. #include "unixsite.h"
  63. #include "unixcmap.h"
  64. #include "visuals.h"
  65. #include "region.h"
  66. #include "basesurf.h"
  67. #include "unixroot.h"
  68. #include "hxthread.h"
  69. #include "hxtick.h"
  70. #include "sitetext.h"
  71. #include "unixsurf.h"
  72. #include "hxprefs.h"
  73. //
  74. // Global & Static global/member data....
  75. //
  76. Display *CHXUnixSite::zm_display = NULL;
  77. static CHXMapPtrToPtr z_mapSiteToWindow;
  78. //
  79. // Scroll bar support
  80. //
  81. #define SCROLL_BAR_WIDTH 13        //Width of scroll bar.
  82. //#define _ARROWS_SIDE_BY_SIDE 1   //Regular or side by side arrows?
  83. //
  84. // CHXUnixSite only Methods...
  85. //
  86. CHXUnixSite::CHXUnixSite( IUnknown* pContext, IUnknown* pUnkOuter, INT32 lInitialZorder)
  87.    : CHXBaseSite( pContext, pUnkOuter, lInitialZorder )
  88.    , m_pUnixEventHandler(NULL)
  89.    , m_ScrollHorizButtonL(0)
  90.    , m_ScrollHorizButtonR(0)
  91.    , m_ScrollVertButtonT(0)
  92.    , m_ScrollVertButtonB(0)
  93.    , m_winFullScreenWindow(0)
  94.    , m_winOldParent(0)
  95.    , m_bScrollingInProgress(FALSE)
  96.    , m_nScrollDir(0)
  97.    , m_bLastPointInSite(FALSE)
  98.    , m_bDamaged(FALSE)
  99.    , m_bIgnoreFocusOutInFS(FALSE)
  100. {
  101.    m_ptScrollVertPosT.x   = m_ptScrollVertPosT.y   = 0;
  102.    m_ptScrollVertPosB.x   = m_ptScrollVertPosB.y   = 0;
  103.    m_ptScrollHorizPosR.x  = m_ptScrollHorizPosR.y  = 0;
  104.    m_ptScrollHorizPosL.x  = m_ptScrollHorizPosL.y  = 0;
  105.    m_ptFullScreenOffset.x = m_ptFullScreenOffset.y = 0;
  106.    memset( &m_PreFullScreenSize, 0, sizeof( m_PreFullScreenSize ) );
  107.    
  108.    HX_ASSERT( m_pContext );
  109.    IHXPreferences* pPreferences = NULL;   
  110.    if( m_pContext && HXR_OK == m_pContext->QueryInterface( IID_IHXPreferences, (void **) &pPreferences))
  111.    { 
  112.        IHXBuffer *pBuffer = NULL;
  113.        pPreferences->ReadPref("IgnoreFocusOutInFS", pBuffer);
  114.        if(pBuffer)
  115.        {
  116.            m_bIgnoreFocusOutInFS = (::atoi((const char*)pBuffer->GetBuffer()) == 1);
  117.            HX_RELEASE(pBuffer);
  118.        }
  119.    }
  120. }
  121. CHXUnixSite::~CHXUnixSite()
  122. {
  123.    void* pDummy; 
  124.    if (z_mapSiteToWindow.Lookup((void*)this, pDummy))
  125.    {
  126.       z_mapSiteToWindow.RemoveKey((void*)this);
  127.    }
  128.    
  129.    if( m_pUnixEventHandler )
  130.    {
  131.       m_pUnixEventHandler->CancelCallback();
  132.       HX_RELEASE(m_pUnixEventHandler);
  133.    }
  134. }
  135. HX_RESULT CHXUnixSite::_OpenXDisplay(char* pszDisplayString)
  136. {
  137.    HX_RESULT retVal = HXR_OK;
  138.     
  139.    //Is the connection open already?
  140.    if( NULL==zm_display )
  141.    {
  142.       zm_display = XOpenDisplay(pszDisplayString);
  143.       
  144.       //If you can't open the display your done.
  145.       if(NULL == zm_display )
  146.       {
  147.          HX_ASSERT("Can't open X Display..."==NULL);
  148.          retVal = HXR_FAIL;
  149.       }
  150.       else
  151.       {
  152.          HX_ASSERT(m_pScheduler);
  153.          if( m_pScheduler )
  154.          {
  155.             //UnixEventHandler scheduls itself for init callback
  156.             //in the ctor.
  157.             m_pUnixEventHandler = new UnixEventHandler(this);
  158.             m_pUnixEventHandler->AddRef();
  159.          }
  160.       }
  161.    }
  162.    return retVal;
  163. }
  164. Window CHXUnixSite::CreateXWindow( Window win )
  165. {
  166.    Window     parentWindow;
  167.    HXxWindow* pWindow = NULL;
  168.    //If parentWin is NULL then we belong to the root window.    
  169.    if( win )
  170.    {
  171.       parentWindow = win;
  172.    }
  173.    else
  174.    {
  175.       HX_ASSERT(zm_display);
  176.       parentWindow = RootWindow(zm_display, DefaultScreen(zm_display));
  177.    }
  178.     
  179.    //Find the best visual to use on this display.
  180.    Visual* visual = GetBestVisual(zm_display);
  181.    //Get the visual info.
  182.    int         nNotUsed=0;
  183.    XVisualInfo stVisInfo;
  184.     
  185.    memset(&stVisInfo, 0, sizeof(XVisualInfo));
  186.    stVisInfo.visualid = XVisualIDFromVisual(visual);
  187.    XVisualInfo* pVisual = XGetVisualInfo( zm_display,
  188.                                           VisualIDMask,
  189.                                           &stVisInfo,
  190.                                           &nNotUsed );
  191.    // Set up attributes of the window.
  192.    int                  attrMask = CWBackPixel | CWBorderPixel;
  193.    XSetWindowAttributes attr;
  194.     
  195.    memset(&attr, 0, sizeof(XSetWindowAttributes));
  196.    attr.background_pixel = BlackPixel(zm_display, DefaultScreen(zm_display));
  197.    attr.border_pixel     = BlackPixel(zm_display, DefaultScreen(zm_display));
  198.    
  199.    //See if the default visaul of hte screen is the same one we Want
  200.    //to use. If not, create a new one and install it.
  201.    Colormap cmap;
  202.    Visual*  defVisual = DefaultVisual(zm_display, DefaultScreen(zm_display));
  203.    if( defVisual->visualid != stVisInfo.visualid )
  204.    {
  205.       //XXXgfw Are we leaking this colormap????
  206.       cmap = XCreateColormap(zm_display, parentWindow, visual, AllocNone);
  207.       attr.colormap = cmap;
  208.       attrMask |= CWColormap;
  209.    }
  210.    // Set the size/position of the window before creating.
  211.    XSizeHints size_hints;
  212.    size_hints.flags  = PPosition | PSize;
  213.    size_hints.x      = m_position.x;
  214.    size_hints.y      = m_position.y;
  215.    size_hints.width  = 1;
  216.    size_hints.height = 1;
  217.    //Create it.
  218.    Window window = XCreateWindow(zm_display, 
  219.                                  parentWindow,
  220.                                  size_hints.x,
  221.                                  size_hints.y,
  222.                                  size_hints.width,
  223.                                  size_hints.height, 
  224.                                  0,
  225.                                  pVisual->depth,
  226.                                  InputOutput,
  227.                                  visual,
  228.                                  attrMask,
  229.                                  &attr);
  230.    XFree(pVisual);
  231.    //Tell the WM about this window.
  232. #if 0
  233.    XSetStandardProperties( zm_display,
  234.                            window,
  235.                            "CHXUnixSite",
  236.                            "CHXUnixSite",
  237.                            None,
  238.                            NULL, 0,
  239.                            &size_hints
  240.                            );
  241. #endif
  242.    //Select all input events on the window since the other platforms
  243.    //we work with have no concept of event masks
  244.    int result = XSelectInput( zm_display, window,
  245.                               ButtonPressMask   | ButtonReleaseMask | KeyPressMask    |
  246.                               KeyReleaseMask    | EnterWindowMask   | LeaveWindowMask |
  247.                               PointerMotionMask | ButtonMotionMask  | KeymapStateMask |
  248.                               ExposureMask      | StructureNotifyMask | FocusChangeMask
  249.                               );
  250.    if( BadWindow == result )
  251.    {
  252. #ifdef _DEBUG
  253.       fprintf( stderr, "Can select events.n" );
  254. #endif      
  255.    }
  256.    
  257.    //Map the window.
  258.    XMapWindow(zm_display, window);
  259.    //Flush event queue.
  260.    XFlush(zm_display);
  261.    return window;
  262. }
  263. void CHXUnixSite::_MapHorzScroll()
  264. {
  265.    if( GetWindow() && GetWindow()->display && m_ScrollHorizButtonL)
  266.    {
  267.       XMapWindow( (Display*)GetWindow()->display, m_ScrollHorizButtonL );
  268.       XMapWindow( (Display*)GetWindow()->display, m_ScrollHorizButtonR ); 
  269.    }
  270.    _DrawArrows();
  271. }
  272. void CHXUnixSite::_MapVertScroll()
  273. {
  274.    if( GetWindow() && GetWindow()->display && m_ScrollVertButtonT)
  275.    {
  276.       XMapWindow( (Display*)GetWindow()->display, m_ScrollVertButtonT );
  277.       XMapWindow( (Display*)GetWindow()->display, m_ScrollVertButtonB );
  278.    }
  279.    _DrawArrows();
  280. }
  281. void CHXUnixSite::_MapScrollButtons()
  282. {
  283.    _MapHorzScroll();
  284.    _MapVertScroll();
  285. }
  286. void CHXUnixSite::_UnmapHorzScroll()
  287. {
  288.    HX_ASSERT( GetWindow() );
  289.    if( m_ScrollHorizButtonL && GetWindow()->display )
  290.    {
  291.       XUnmapWindow( (Display*)GetWindow()->display, m_ScrollHorizButtonL );
  292.       XUnmapWindow( (Display*)GetWindow()->display, m_ScrollHorizButtonR );
  293.    }
  294. }
  295. void CHXUnixSite::_UnmapVertScroll()
  296. {
  297.    HX_ASSERT( GetWindow() );
  298.    if( m_ScrollVertButtonT && GetWindow()->display )
  299.    {
  300.       XUnmapWindow( (Display*)GetWindow()->display, m_ScrollVertButtonT );
  301.       XUnmapWindow( (Display*)GetWindow()->display, m_ScrollVertButtonB ); 
  302.    }
  303. }
  304. void CHXUnixSite::_UnmapScrollButtons()
  305. {
  306.    if( GetWindow() )
  307.    {
  308.       _UnmapVertScroll();
  309.       _UnmapHorzScroll();
  310.    }
  311. }
  312. void CHXUnixSite::_DestroyScrollButtons()
  313. {
  314.    if( m_ScrollHorizButtonL && GetWindow()->display )
  315.    {
  316.       XDestroyWindow( (Display*)GetWindow()->display, m_ScrollHorizButtonL );
  317.       m_ScrollHorizButtonL = 0;
  318.       XDestroyWindow( (Display*)GetWindow()->display, m_ScrollHorizButtonR );
  319.       m_ScrollHorizButtonR = 0;
  320.    }
  321.    if( m_ScrollVertButtonT && GetWindow()->display)
  322.    {
  323.       XDestroyWindow( (Display*)GetWindow()->display, m_ScrollVertButtonT );
  324.       m_ScrollVertButtonT = 0;
  325.       XDestroyWindow( (Display*)GetWindow()->display, m_ScrollVertButtonB );
  326.       m_ScrollVertButtonB = 0;
  327.    }
  328.    m_ptScrollVertPosT.x = m_ptScrollVertPosT.y = 0;
  329.    m_ptScrollVertPosB.x = m_ptScrollVertPosB.y = 0;
  330.    m_ptScrollHorizPosR.x = m_ptScrollHorizPosR.y = 0;
  331.    m_ptScrollHorizPosL.x = m_ptScrollHorizPosL.y = 0;
  332. }
  333. void CHXUnixSite::_DrawArrows()
  334. {
  335.    //only do the work if our site is visible.
  336.    if( !IsSiteVisible() )
  337.       return;
  338.     
  339.     //Draw an arrow on this window.
  340.    XPoint points[4];
  341.    int offset = SCROLL_BAR_WIDTH/10;
  342.    GC tmpGC;
  343.    XGCValues values;
  344.    Display* dis = (Display*)GetWindow()->display;
  345.    if( m_ScrollVertButtonB )
  346.    {
  347.       tmpGC = XCreateGC( dis, m_ScrollVertButtonB, 0, &values );
  348.    }
  349.    else if( m_ScrollHorizButtonL )
  350.    {
  351.       tmpGC = XCreateGC( dis, m_ScrollHorizButtonL, 0, &values );
  352.    }
  353.    else
  354.    {
  355.       //We don't have any scroll bars to draw....
  356.       return;
  357.    }
  358.    
  359.    
  360.    XSetForeground( dis, tmpGC, WhitePixel(dis, 0 ));
  361.    XSetBackground( dis, tmpGC, BlackPixel(dis, 0 ));
  362.    Colormap cmap = HXGetXColormap((Display*)GetWindow()->display,
  363.                                    (Window)GetWindow()->window);
  364.    XColor color;
  365.     
  366.    memset(&color, 0, sizeof(XColor));
  367.    XParseColor(dis, cmap, "blue", &color);
  368.    HXFindBestXColor(dis, cmap, &color);
  369.    XSetForeground( dis, tmpGC, color.pixel);
  370.    XSetLineAttributes(dis, tmpGC, 1, LineSolid, CapRound, JoinRound );
  371.    //Draw up Vertical arrow.
  372.    if( m_ScrollVertButtonT )
  373.    {
  374.       points[0].x = offset;
  375.       points[0].y = SCROLL_BAR_WIDTH-offset;
  376.       points[1].x = SCROLL_BAR_WIDTH/2;
  377.       points[1].y = offset;
  378.       points[2].x = SCROLL_BAR_WIDTH-offset;
  379.       points[2].y = SCROLL_BAR_WIDTH-offset;
  380.       points[3].x = points[0].x;
  381.       points[3].y = points[0].y;
  382.       XFillPolygon( dis, m_ScrollVertButtonT, tmpGC, points, 4, Convex, CoordModeOrigin);
  383.    }
  384.     
  385.    //Draw down Vertical arrow.
  386.    if( m_ScrollVertButtonB )
  387.    {
  388.       points[0].x = offset;
  389.       points[0].y = offset;
  390.       points[1].x = SCROLL_BAR_WIDTH-offset;
  391.       points[1].y = offset;
  392.       points[2].x = SCROLL_BAR_WIDTH/2;
  393.       points[2].y = SCROLL_BAR_WIDTH-offset;
  394.       points[3].x = points[0].x;
  395.       points[3].y = points[0].y;
  396.       XFillPolygon( dis, m_ScrollVertButtonB, tmpGC, points, 4, Convex, CoordModeOrigin);
  397.    }
  398.     
  399.    //Draw Left Horizontal arrow.
  400.    if( m_ScrollHorizButtonL )
  401.    {
  402.       points[0].x = SCROLL_BAR_WIDTH-offset;
  403.       points[0].y = offset;
  404.       points[1].x = SCROLL_BAR_WIDTH-offset;
  405.       points[1].y = SCROLL_BAR_WIDTH-offset;
  406.       points[2].x = offset;
  407.       points[2].y = SCROLL_BAR_WIDTH/2;
  408.       points[3].x = points[0].x;
  409.       points[3].y = points[0].y;
  410.       XFillPolygon( dis, m_ScrollHorizButtonL, tmpGC, points, 4, Convex, CoordModeOrigin);
  411.    }
  412.     
  413.    //Draw Right Horizontal arrow.
  414.    if( m_ScrollHorizButtonR )
  415.    {
  416.       points[0].x = offset;
  417.       points[0].y = SCROLL_BAR_WIDTH-offset;
  418.       points[1].x = offset;
  419.       points[1].y = offset;
  420.       points[2].x = SCROLL_BAR_WIDTH-offset;
  421.       points[2].y = SCROLL_BAR_WIDTH/2;
  422.       points[3].x = points[0].x;
  423.       points[3].y = points[0].y;
  424.       XFillPolygon( dis, m_ScrollHorizButtonR, tmpGC, points, 4, Convex, CoordModeOrigin);
  425.    }
  426.     
  427.    //Free the GC and go.
  428.    XFreeGC( dis, tmpGC );
  429. }
  430. BOOL CHXUnixSite::_InButton( HXxPoint& pt, int x, int y )
  431. {
  432.    BOOL retVal =FALSE;
  433.    if( x>= pt.x && x< pt.x+SCROLL_BAR_WIDTH && y>=pt.y && y<pt.y+SCROLL_BAR_WIDTH )
  434.       retVal=TRUE;
  435.    else
  436.       retVal=FALSE;
  437.    return retVal;
  438. }
  439. void CHXUnixSite::_CreateHorizScrollBar()
  440. {
  441.    HX_ASSERT( m_ScrollHorizButtonL == 0 );
  442.    HX_ASSERT( m_ScrollHorizButtonR == 0 );
  443.     
  444.    HXxSize  mySize;
  445.    HXxWindow* pParentWindow = NULL;
  446.    if(GetParentSite())
  447.    {
  448.       pParentWindow = GetParentSite()->GetWindow();
  449.    }
  450.    if(pParentWindow)
  451.    {
  452.       GetParentSite()->GetSize(mySize);
  453.    }
  454.    HX_ASSERT( pParentWindow );
  455.    HX_ASSERT( pParentWindow->window != 0 );
  456.     
  457.    if( m_ScrollVertButtonB )
  458.    {
  459.       // if the other bar already exists, don't overlap it!
  460.       mySize.cx -= SCROLL_BAR_WIDTH;
  461.    }
  462.    m_ptScrollHorizPosL.x = m_topleft.x;
  463.    m_ptScrollHorizPosL.y = m_topleft.y+mySize.cy-SCROLL_BAR_WIDTH;
  464. #ifndef _ARROWS_SIDE_BY_SIDE    
  465.    m_ptScrollHorizPosR.x = m_topleft.x+mySize.cx-SCROLL_BAR_WIDTH;
  466. #else    
  467.    m_ptScrollHorizPosR.x = m_topleft.x+SCROLL_BAR_WIDTH;
  468. #endif
  469.    m_ptScrollHorizPosR.y = m_topleft.y+mySize.cy-SCROLL_BAR_WIDTH;
  470.    Display* dis     = (Display*)GetWindow()->display;
  471.    Pixel blackPixel = BlackPixel( dis, DefaultScreen(dis) );
  472.    Pixel greyPixel  = blackPixel;
  473.    Colormap cmap = HXGetXColormap((Display*)GetWindow()->display,
  474.                                    (Window)GetWindow()->window);
  475.    XColor color;
  476.     
  477.    XParseColor(dis, cmap, "gray", &color);
  478.    HXFindBestXColor(dis, cmap, &color);
  479.    greyPixel = color.pixel;
  480.    m_ScrollHorizButtonL = XCreateSimpleWindow( (Display*)GetWindow()->display,
  481.                                                (Window)pParentWindow->window,
  482.                                                m_ptScrollHorizPosL.x, m_ptScrollHorizPosL.y,
  483.                                                SCROLL_BAR_WIDTH, SCROLL_BAR_WIDTH,
  484.                                                1,
  485.                                                blackPixel,
  486.                                                greyPixel
  487.                                                );
  488.    m_ScrollHorizButtonR = XCreateSimpleWindow( (Display*)GetWindow()->display,
  489.                                                (Window)pParentWindow->window,
  490.                                                m_ptScrollHorizPosR.x, m_ptScrollHorizPosR.y,
  491.                                                SCROLL_BAR_WIDTH, SCROLL_BAR_WIDTH,
  492.                                                1,
  493.                                                blackPixel,
  494.                                                greyPixel
  495.                                                );
  496.    HX_ASSERT( m_ScrollHorizButtonR && m_ScrollHorizButtonL );
  497.     
  498. }
  499. void CHXUnixSite::_CreateVertScrollBar()
  500. {
  501.    HX_ASSERT( m_ScrollVertButtonB == 0 );
  502.    HX_ASSERT( m_ScrollVertButtonT == 0 );
  503.     
  504.    HXxSize  mySize;
  505.    HXxWindow* pParentWindow = NULL;
  506.    if(GetParentSite())
  507.    {
  508.       pParentWindow = GetParentSite()->GetWindow();
  509.    }
  510.    if(pParentWindow)
  511.    {
  512.       GetParentSite()->GetSize(mySize);
  513.    }
  514.    HX_ASSERT( pParentWindow );
  515.    HX_ASSERT( pParentWindow->window != 0 );
  516.     
  517.    if( m_ScrollHorizButtonR )
  518.    {
  519.       // if the other bar already exists, don't overlap it!
  520.       mySize.cy -= SCROLL_BAR_WIDTH;
  521.    }
  522.     
  523.     
  524.    m_ptScrollVertPosT.x = m_topleft.x+mySize.cx-SCROLL_BAR_WIDTH;
  525.    m_ptScrollVertPosT.y = m_topleft.y;
  526.    m_ptScrollVertPosB.x = m_topleft.x+mySize.cx-SCROLL_BAR_WIDTH;
  527. #ifndef _ARROWS_SIDE_BY_SIDE    
  528.    m_ptScrollVertPosB.y = m_topleft.y+mySize.cy-SCROLL_BAR_WIDTH;
  529. #else
  530.    m_ptScrollVertPosB.y = m_topleft.y+SCROLL_BAR_WIDTH;
  531. #endif    
  532.    Display* dis     = (Display*)GetWindow()->display;
  533.    Pixel blackPixel = BlackPixel( dis, DefaultScreen(dis) );
  534.    Pixel greyPixel  = blackPixel;
  535.    Colormap cmap = HXGetXColormap((Display*)GetWindow()->display,
  536.                                    (Window)GetWindow()->window);
  537.    XColor color;
  538.     
  539.    XParseColor(dis, cmap, "gray", &color);
  540.    HXFindBestXColor(dis, cmap, &color);
  541.    greyPixel = color.pixel;
  542.     
  543.    HX_ASSERT( GetWindow() );
  544.    m_ScrollVertButtonT = XCreateSimpleWindow( (Display*)GetWindow()->display,
  545.                                               (Window)pParentWindow->window,
  546.                                               m_ptScrollVertPosT.x, m_ptScrollVertPosT.y,
  547.                                               SCROLL_BAR_WIDTH, SCROLL_BAR_WIDTH,
  548.                                               1,
  549.                                               blackPixel,
  550.                                               greyPixel
  551.                                               );
  552.    m_ScrollVertButtonB = XCreateSimpleWindow( (Display*)GetWindow()->display,
  553.                                               (Window)pParentWindow->window,
  554.                                               m_ptScrollVertPosB.x, m_ptScrollVertPosB.y,
  555.                                               SCROLL_BAR_WIDTH, SCROLL_BAR_WIDTH,
  556.                                               1,
  557.                                               blackPixel,
  558.                                               greyPixel
  559.                                               );
  560.    HX_ASSERT( m_ScrollVertButtonB && m_ScrollVertButtonT );
  561. }
  562. //
  563. // Inherited CHXBaseSite methods.
  564. //
  565. void CHXUnixSite::_NeedWindowedSite()
  566. {
  567. #ifdef _DEBUG   
  568.    fprintf( stderr, "CHXUnixSite::_NeedWindowedSite do something here....n" );
  569. #endif   
  570.    //Nothing to do on unix....
  571. }
  572. void CHXUnixSite::_AttachWindow()
  573. {
  574.    void* pDummy=NULL; 
  575.    if(!z_mapSiteToWindow.Lookup((void*)this, pDummy))
  576.    {
  577.       z_mapSiteToWindow.SetAt((void*)this, (void*)m_pWindow);
  578.    }
  579.    
  580.    //Set the display variable.
  581.    if( m_pWindow->display == NULL )
  582.    {
  583.       HX_ASSERT(zm_display);
  584.       m_pWindow->display = zm_display;
  585.    }
  586.    
  587.    //Now that we have a window be sure to init the CUnixRootSurf.
  588.    //this lets it set up the display, colormap, etc.
  589.    ((CUnixRootSurf*)m_pRootSurface)->Init();
  590. }
  591. void CHXUnixSite::_DetachWindow()
  592. {
  593.    //Nothing to do on unix....
  594. }
  595. void* CHXUnixSite::_Create(void* pParentWindow, UINT32 style)
  596. {
  597.    HRESULT result = HXR_OK;
  598.    if( m_pWindow && m_pWindow->window )
  599.    {
  600.       HX_ASSERT( "We already have created a window"==NULL);
  601.       return NULL;
  602.    }
  603.    if (pParentWindow==NULL || style)
  604.    {
  605.       m_bIsChildWindow = FALSE;
  606.    }
  607.    else
  608.    {
  609.       m_bIsChildWindow = TRUE;
  610.    }
  611.    if( _OpenXDisplay(NULL) != HXR_OK )
  612.    {
  613.       return NULL;
  614.    }
  615.    return (void*)CreateXWindow((Window)pParentWindow);
  616. }
  617. void CHXUnixSite::_Destroy(HXxWindow* pWindow)
  618. {
  619.    _DestroySliders();
  620.    XDestroyWindow( (Display*)pWindow->display, (Window)pWindow->window );
  621. }
  622. void CHXUnixSite::_SetSize(HXxSize size)
  623. {
  624.    HX_ASSERT( m_pWindow && m_pWindow->display && m_pWindow->window);
  625.    //The scroll bars get resized also...
  626.    _DestroySliders();
  627.    XResizeWindow((Display*) m_pWindow->display,
  628.                  (Window) m_pWindow->window,
  629.                  size.cx,
  630.                  size.cy);
  631. }
  632. void CHXUnixSite::_SetPosition(HXxPoint position)
  633. {
  634.    HX_ASSERT( m_pWindow && m_pWindow->display && m_pWindow->window);
  635.    _DestroyScrollButtons();
  636.    XMoveWindow((Display*)m_pWindow->display,
  637.                (Window)m_pWindow->window,
  638.                position.x,
  639.                position.y);
  640. }
  641. void CHXUnixSite::_DamageRect(HXxRect rect)
  642. {
  643.    if(GetWindow())
  644.    {    
  645.       m_bDamaged = TRUE;
  646.    }
  647.    return;
  648. }
  649. void CHXUnixSite::_DamageRegion(HXxRegion rect)
  650. {
  651.    if(GetWindow())
  652.    {    
  653.       m_bDamaged = TRUE;
  654.    }
  655.    return;
  656. }
  657. void CHXUnixSite::_SendOSUpdateMessage()
  658. {
  659.    //We need to redraw our window here, m_pWindow.
  660. }
  661. void CHXUnixSite::_ShowSite(BOOL bShow)
  662. {
  663.    if( bShow )
  664.    {
  665.       _MapScrollButtons();
  666.    }
  667.    else
  668.    {
  669.       _UnmapScrollButtons();
  670.    }
  671.    //do nothing....
  672. }
  673. BOOL CHXUnixSite::_AtSystemTime()
  674. {
  675.    return TRUE;
  676. }
  677. void CHXUnixSite::_GetDeviceCaps( void* hdc,
  678.                                   UINT16& uBitsPerPixel,
  679.                                   UINT16& uHorzRes,
  680.                                   UINT16& uVertRes )
  681. {
  682.    Screen* pScreen = NULL;
  683.    HXxWindow* pWin = GetWindow();
  684.    HX_ASSERT( pWin );
  685.    if( pWin )
  686.    {
  687.        Display* dis = (Display*)pWin->display;
  688.        HX_ASSERT( dis );
  689.        if( dis )
  690.        {
  691.            pScreen = DefaultScreenOfDisplay((Display*)GetWindow()->display);
  692.            
  693.            uBitsPerPixel = pScreen->root_depth;
  694.            uHorzRes      = pScreen->width;
  695.            uVertRes      = pScreen->height;   
  696.        }
  697.    }
  698. }
  699. void CHXUnixSite::_GetWindowRect(HXxRect* destRect)
  700. {
  701.    HX_ASSERT( "Doesn't seem to be used anywhere"==NULL );
  702. }
  703. void CHXUnixSite::_DestroySliders()
  704. {
  705.    _DestroyScrollButtons();
  706. }
  707. void CHXUnixSite::_ForwardUpdateEvent(HXxEvent* pEvent)
  708. {
  709.    GC gc = NULL;
  710.    AddRef();
  711.    HX_ASSERT(GetWindow()->window);
  712.    HX_ASSERT(m_pUser);
  713.    if(m_bIsChildWindow)
  714.    {
  715.       //Create a clip region that excludes our higher z-order
  716.       //siblings and is clipped to our parent.
  717.       if( !m_bRegionIsValid )
  718.       {
  719.          RecomputeClip();
  720.       }
  721.       // The problem is that regions are locked to the origin so we
  722.       // will need to reverse shift the region before we set the
  723.       // origin of the graph port! get the GC from the video surface
  724.       gc = ((CUnixRootSurf*)m_pRootSurface)->GetGC();
  725.       HX_ASSERT( gc );
  726.         
  727.       //Actually setup our clip region
  728.       XSetRegion( (Display*)GetWindow()->display, gc, (Region) m_Region );
  729.    }
  730.    XEvent* pXEvent = (XEvent*) pEvent->param2; 
  731.    XExposeEvent* exposeEvent = (XExposeEvent*) pXEvent;
  732.    
  733.    // get the rect for this site with respect to our parent
  734.    HXRECTANGLE exposedRect = { exposeEvent->x,
  735.                              exposeEvent->y,
  736.                              exposeEvent->width,
  737.                              exposeEvent->height };
  738.    HXREGION* exposedRegion = HXCreateRegion();
  739.    HXUnionRectWithRegion(&exposedRect, exposedRegion,  exposedRegion);
  740.    
  741.    // does the site intersect the current clipping region?
  742.    HXREGION* resultRegion = HXCreateRegion();
  743.    HXIntersectRegion(exposedRegion, m_Region, resultRegion);
  744.    BOOL bSiteIntersectsExposed = (HXEmptyRegion(resultRegion)==FALSE);
  745.    
  746.    HXDestroyRegion(resultRegion);
  747.    HXDestroyRegion(exposedRegion);
  748.    
  749.    // if the exposed region intersects the sites clipping region
  750.    if(bSiteIntersectsExposed)
  751.    {
  752.       m_pUser->HandleEvent(pEvent);
  753.    }
  754.    
  755.    //If the user doesn't handle the standard update event then send
  756.    //them the cross platform HX_SURFACE_UPDATE event don't damage the
  757.    //original event structure
  758.    if(!pEvent->handled && m_pUser )
  759.    {
  760.       HX_ASSERT(GetWindow());
  761.       HXxEvent event;
  762.       event.event   = HX_SURFACE_UPDATE;
  763.       event.window  = GetWindow()->window;
  764.       event.param1  = m_pVideoSurface;
  765.       event.param2  = GetWindow();
  766.       event.result  = 0;
  767.       event.handled = FALSE;
  768.       m_pUser->HandleEvent(&event);
  769.       pEvent->handled = event.handled;
  770.    }
  771.    
  772.    //reset the gc to use no region
  773.    if(m_bIsChildWindow && gc)
  774.    {
  775.       XSetClipMask((Display*) GetWindow()->display, gc, None);
  776.    }
  777.    //Handle the drawing of our arrows...
  778.    _DrawArrows();
  779.    //Now do all our children.... 
  780.    CHXMapPtrToPtr::Iterator i = m_ChildrenMap.Begin();
  781.    for(;i!=m_ChildrenMap.End();++i)
  782.    {
  783.       CHXUnixSite* pSite = (CHXUnixSite*) *i;
  784.       pSite->_ForwardUpdateEvent(pEvent);
  785.    }
  786.    
  787.    Release();
  788. }
  789. UINT32 CHXUnixSite::_MapKeySymToHXVK(KeySym sym, UINT32& uFlags )
  790. {
  791.    //XXXgfw if we add the extended flag in the HX_KEYBOARD event
  792.    //structure then we can modify the flags here to show that these
  793.    //keys are 'extended' in the windows sense.
  794.    UINT32 ulRet = 0;
  795.    switch( sym )
  796.    {
  797.       case XK_Shift_R:
  798.          ulRet = XK_Shift_L;
  799.          break;
  800.       case XK_Alt_R:
  801.          ulRet = XK_Alt_L;
  802.          break;
  803.       case XK_KP_Home:
  804.          ulRet = XK_Home;
  805.          break;
  806.       case XK_KP_Next:
  807.          ulRet = XK_Next;
  808.          break;
  809.       case XK_KP_Prior:
  810.          ulRet = XK_Prior;
  811.          break;
  812.       case XK_KP_Enter:
  813.          ulRet = XK_Return;
  814.          break;
  815.       case XK_KP_End:
  816.          ulRet = XK_End;
  817.          break;
  818.       case XK_KP_Begin:
  819.          ulRet = XK_Begin;
  820.          break;
  821.       case XK_KP_Left:
  822.          ulRet = XK_Left;
  823.          break;
  824.       case XK_KP_Up:
  825.          ulRet = XK_Up;
  826.          break;
  827.       case XK_Control_R:
  828.          ulRet = XK_Control_L;
  829.          break;
  830.       case XK_KP_Right:
  831.          ulRet = XK_Right;
  832.          break;
  833.       case XK_KP_Down:
  834.          ulRet = XK_Down;
  835.          break;
  836.       case XK_KP_Insert:
  837.          ulRet = XK_Insert;
  838.          break;
  839.       case XK_KP_Delete:
  840.          ulRet = XK_Delete;
  841.          break;
  842.       default:
  843.          ulRet = sym;
  844.          break;
  845.    }
  846.    if( ulRet != sym )
  847.    {
  848.       //We have mapped a key from Right hand side, keypad, arrows
  849.       //or other parts of an extended keyboard. Set the flag.
  850.       uFlags |= HX_EXTENDED_KEY_MASK;
  851.    }
  852.    return ulRet;
  853. }
  854. BOOL CHXUnixSite::_ConvertToHXEvent(HXxEvent* pEvent )
  855. {
  856.    // get original events info from pEvent
  857.    XEvent* pXEvent = (XEvent*) pEvent->param2;
  858.    XButtonEvent* buttonEvent = (XButtonEvent*) pXEvent;
  859.    
  860.    //===============================================================
  861.    //   Convert all other event to RMA generic events and pass back.
  862.    //===============================================================
  863.    if( ((pEvent->event == ButtonPress)   ||
  864.         (pEvent->event == ButtonRelease) ||
  865.         (pEvent->event == MotionNotify ) ||
  866.         (pEvent->event == EnterNotify)   ||
  867.         (pEvent->event == FocusIn)       ||
  868.         (pEvent->event == FocusOut)      ||
  869.         (pEvent->event == KeyPress)      ||
  870.         (pEvent->event == KeyRelease)    ||
  871.         (pEvent->event == LeaveNotify))
  872.        )
  873.    {
  874.       // set modifier flags for all events....
  875.       UINT32 flags = 0;
  876.       // create new HXxEvent
  877.       HXxEvent theEvent;
  878.       //XXXgfw ouch....
  879.       static HXxPoint realPt = {0,0};
  880.       //Init certain members. 
  881.       memset(&theEvent, 0, sizeof(HXxEvent));
  882.       theEvent.window  = pEvent->window;
  883.       theEvent.handled = FALSE;
  884.       //
  885.       // NOTE:
  886.       //
  887.       // theEvent must be filled in by *ALL* event types.
  888.       // theEvent will be memcopied into the pEvent passed
  889.       // back to the basesite at the end of the method.
  890.       // 
  891.       //==================================================
  892.       // LEAVE NOTIFY EVENT
  893.       //==================================================            
  894.       if( pEvent->event==LeaveNotify)
  895.       {
  896.          if( m_pTopLevelSite->m_pMouseInSite )
  897.          {
  898.             HXxPoint oobPoint;
  899.             oobPoint.x = -1;
  900.             oobPoint.y = -1;
  901.             HXxEvent Outevent = { HX_MOUSE_LEAVE,
  902.                                   m_pWindow->window,
  903.                                   (void*)&oobPoint,
  904.                                   0, 0,
  905.                                   FALSE };
  906.             m_pTopLevelSite->m_pMouseInSite->EventOccurred(&Outevent);
  907.             m_pTopLevelSite->m_pMouseInSite = NULL;
  908.          }
  909.          pEvent->handled=TRUE;
  910.          return TRUE;
  911.       }
  912.       //==================================================
  913.       // ENTER NOTIFY EVENT
  914.       //==================================================
  915.       if( pEvent->event==EnterNotify)
  916.       {
  917.          pEvent->handled=TRUE;
  918.          return TRUE;
  919.       }
  920.       //==================================================
  921.       // KEY PRESS/RELEASE EVENT
  922.       //==================================================
  923.       if ( pEvent->event == KeyPress || pEvent->event==KeyRelease )
  924.       {
  925.          XKeyEvent* pKeyEvent = (XKeyEvent*)pEvent->param2;
  926.          //
  927.          //Set the event type
  928.          //
  929.          theEvent.event = pEvent->event==KeyPress?HX_KEY_DOWN:HX_KEY_UP;
  930.          //
  931.          // Fill in the scan/key code.
  932.          //
  933.          flags =  pKeyEvent->keycode;
  934.          flags &= 0x000000ff; //the scan code only gets bits 0-7
  935.                
  936.          //
  937.          // build key modifier list...
  938.          //
  939.          if( pKeyEvent->state & ShiftMask )
  940.             flags |= HX_SHIFT_MASK;
  941.                
  942.          if( pKeyEvent->state & ControlMask )
  943.             flags |= HX_CTRL_MASK;
  944.                
  945.          if( pKeyEvent->state & LockMask )
  946.             flags |= HX_CAPS_LOCK_MASK;
  947.          if( pKeyEvent->state & Mod1Mask)
  948.             flags |= HX_ALT_MASK;
  949.                   
  950.          if( pKeyEvent->state & Mod2Mask)
  951.             flags |= HX_NUM_LOCK_MASK;
  952.                   
  953.          if( pKeyEvent->state & Mod5Mask)
  954.             flags |= HX_SCROLL_LOCK_MASK;
  955.          //
  956.          //Store the char pressed.
  957.          //
  958.          KeySym sym;
  959.          char   szBuf[10]; /* Flawfinder: ignore */
  960.          int    nNum;
  961.                   
  962.          //Save the state of the keys...
  963.          unsigned int unSave = pKeyEvent->state;
  964.          pKeyEvent->state=0;
  965.          //Lookup the key without any state.
  966.          nNum = XLookupString( pKeyEvent, szBuf, 10, &sym, NULL );
  967.          if( nNum > 0 )
  968.          {
  969.             theEvent.param1 = (void*)*szBuf;
  970.          }
  971.          else
  972.          {
  973.             theEvent.param1 = (void*)_MapKeySymToHXVK(sym, flags);
  974.             flags |= HX_VIRTUAL_KEY_MASK;
  975.          }
  976.          //restore the state of the event
  977.          pKeyEvent->state = unSave;
  978.                
  979.          //Set the flags...
  980.          theEvent.param2 = (void*)flags;
  981.          //Check for HX_CHAR needed or not.
  982.          if( theEvent.event == HX_KEY_DOWN )
  983.          {
  984.             //We have to send an extra HX_CHAR event
  985.             HXxEvent extraEvent;
  986.             memcpy( &extraEvent, &theEvent, sizeof( extraEvent ) ); /* Flawfinder: ignore */
  987.             //Change the type.
  988.             extraEvent.event = HX_CHAR;
  989.                   
  990.             //
  991.             //Change the keycode to an translated ascii char.
  992.             //
  993.             KeySym sym;
  994.             char   szBuf[10]; /* Flawfinder: ignore */
  995.             int    nNum;
  996.                   
  997.             nNum = XLookupString( pKeyEvent, szBuf, 10, &sym, NULL );
  998.                   
  999.             if( nNum > 0 )
  1000.             {
  1001.                extraEvent.param1 = (void*)*szBuf;
  1002.             }
  1003.             else
  1004.             {
  1005.                extraEvent.param1 = (void*)_MapKeySymToHXVK(sym, flags);
  1006.                flags |= HX_VIRTUAL_KEY_MASK;
  1007.             }
  1008.             extraEvent.param2 = (void*)flags;
  1009.             //
  1010.             // Now send the extra event....
  1011.             //
  1012.             CHXBaseSite::EventOccurred(&extraEvent);
  1013.          }
  1014.       }
  1015.             
  1016.       //==================================================
  1017.       // FOCUS OUT EVENT
  1018.       //==================================================            
  1019.       if ( pEvent->event == FocusOut )
  1020.       {
  1021.          theEvent.event = HX_LOSE_FOCUS;
  1022.       }
  1023.       if ( pEvent->event == FocusIn )
  1024.       {
  1025.          theEvent.event = HX_SET_FOCUS;
  1026.       }
  1027.       //==================================================
  1028.       // MOUSE MOVE EVENT
  1029.       //==================================================            
  1030.       if( pEvent->event == MotionNotify )
  1031.       {
  1032.          XMotionEvent* pp = (XMotionEvent*)pEvent->param2;
  1033.          theEvent.event = HX_MOUSE_MOVE; 
  1034.                
  1035.          if( pp->state&Button1Mask )
  1036.             flags |= HX_PRIMARY_BUTTON;
  1037.                
  1038.          if( pp->state&Button2Mask )
  1039.             flags |= HX_CONTEXT_BUTTON;
  1040.                
  1041.          if( pp->state&Button3Mask )
  1042.             flags |= HX_THIRD_BUTTON;
  1043.                
  1044.          if(pp->state & ShiftMask)
  1045.             flags |= HX_SHIFT_KEY;
  1046.                
  1047.          if(pp->state & ControlMask)
  1048.             flags |= HX_CTRL_KEY;
  1049.                
  1050.          if(pp->state & Mod1Mask)
  1051.             flags |= HX_ALT_COMMAND_KEY;
  1052.                
  1053.          theEvent.param2 = (void*) flags;
  1054.                
  1055.          //Grab the X and Y.
  1056.          theEvent.param1 = (void*) &realPt;
  1057.          realPt.x = pp->x;
  1058.          realPt.y = pp->y;
  1059.       }
  1060.             
  1061.       //==================================================
  1062.       // BUTTON PRESS/RELEASE EVENT
  1063.       //==================================================            
  1064.       if((pEvent->event == ButtonPress) || (pEvent->event == ButtonRelease))
  1065.       {
  1066.          // remap event
  1067.          if (pEvent->event == ButtonPress)
  1068.          {
  1069.             if (buttonEvent->button == Button3)
  1070.                theEvent.event = HX_CONTEXT_BUTTON_DOWN;
  1071.             else
  1072.                theEvent.event = HX_PRIMARY_BUTTON_DOWN;
  1073.          }
  1074.          else if (pEvent->event == ButtonRelease)
  1075.          {
  1076.             if (buttonEvent->button == Button3)
  1077.                theEvent.event = HX_CONTEXT_BUTTON_UP;
  1078.             else
  1079.                theEvent.event = HX_PRIMARY_BUTTON_UP;
  1080.          }
  1081.             
  1082.          if(buttonEvent->state & ShiftMask)
  1083.             flags |= HX_SHIFT_KEY;
  1084.                
  1085.          if(buttonEvent->state & ControlMask)
  1086.             flags |= HX_CTRL_KEY;
  1087.                
  1088.          theEvent.param2 = (void*) flags;
  1089.                
  1090.          //Grab the X and Y.
  1091.          theEvent.param1 = (void*) &realPt;
  1092.          realPt.x = buttonEvent->x;
  1093.          realPt.y = buttonEvent->y;
  1094.       }
  1095.             
  1096.       //Copy the new event back into the passed in one for
  1097.       //all events that fall through here...
  1098.       memcpy( pEvent, &theEvent, sizeof(HXxEvent) ); /* Flawfinder: ignore */
  1099. #if defined(_DEBUG)
  1100.       //If the users presses control-primary button
  1101.       //dump info on all sites. If shift-context, then
  1102.       //just this site.
  1103.       if( (buttonEvent->state&ControlMask)&&
  1104.           (theEvent.event==HX_PRIMARY_BUTTON_DOWN))
  1105.       {
  1106.          DisplayAllSiteData();
  1107.       }
  1108.       if( (buttonEvent->state&ShiftMask)&&
  1109.           (theEvent.event==HX_PRIMARY_BUTTON_DOWN))
  1110.       {
  1111.          DisplaySiteData("");
  1112.       }
  1113. #endif            
  1114.    }
  1115.    return pEvent->handled;
  1116. }
  1117. //
  1118. // OK, here it is. Take care of any OS specific duties, like scrollbar
  1119. // stuff and expose events. Then, if the event isn't handled, convert
  1120. // to an RMA event and return.
  1121. BOOL CHXUnixSite::_HandleOSEvents(HXxEvent* pEvent)
  1122. {
  1123.    HXxPoint position = {0, 0};
  1124.    HXxPoint point;
  1125.    if( NULL==pEvent )
  1126.    {
  1127.       return FALSE;
  1128.    }
  1129.    
  1130. #if defined(_DEBUG) && 0
  1131. //   fprintf( stderr, "this: %p m_pUser: %p ", this, m_pUser );
  1132.    switch( pEvent->event )
  1133.    {
  1134.       case HX_MOUSE_LEAVE:
  1135.          fprintf( stderr, "HX_MOUSE_LEAVEn" );
  1136.          break;
  1137. //        case HX_MOUSE_MOVE:
  1138. //           point.x = ((HXxPoint*)pEvent->param1)->x;
  1139. //           point.y = ((HXxPoint*)pEvent->param1)->y;
  1140. //           fprintf( stderr, "HX_MOUSE_MOVE: %d %dn", point.x, point.y );
  1141. //           break;
  1142.       case HX_MOUSE_ENTER:
  1143.          fprintf( stderr, "HX_MOUSE_ENTERn" );
  1144.          break;
  1145. //        case MotionNotify:
  1146. //           point.x = ((XMotionEvent*)pEvent->param2)->x;
  1147. //           point.y = ((XMotionEvent*)pEvent->param2)->y;
  1148. //           fprintf( stderr, "MotionNotify: %d %dn", point.x, point.y );
  1149. //           break;
  1150.       case Expose:
  1151.          fprintf( stderr, "Exposen" );
  1152.          break;
  1153.       case EnterNotify :
  1154.          fprintf( stderr, "EnterNotifyn" );
  1155.          break;
  1156.       case LeaveNotify:
  1157.          fprintf( stderr, "LeaveNotifyn" );
  1158.          break;
  1159.       case KeyPress:
  1160.          fprintf( stderr, "this: %p m_pUser: %p ", this, m_pUser );
  1161.          fprintf( stderr, "Keypressnn" );
  1162.          break;
  1163.       case KeyRelease:
  1164.          fprintf( stderr, "this: %p m_pUser: %p ", this, m_pUser );
  1165.          fprintf( stderr, "KeyReleasen" );
  1166.          break;
  1167.       default:
  1168.          fprintf( stderr, "Othern" );         
  1169.          break;
  1170.    }
  1171. #endif
  1172.    //Find the ConfigureNotify events so we can drop to RGB from
  1173.    //overlay while we move....
  1174. //     if( pEvent->event == ConfigureNotify && this==m_pTopLevelSite )
  1175. //     {
  1176. //        XConfigureEvent* pev = (XConfigureEvent*)pEvent->param2;
  1177. //        if( m_pWindow && pev->window == (Window)m_pWindow->window )
  1178. //        {
  1179. //           HXxPoint p;
  1180. //           _GetPositionRelativeToActualWindow( p );
  1181. //  //           fprintf( stderr, "wint %p  -- x,y width, height: %d %d %d %d n",
  1182. //  //                    pev->window,
  1183. //  //                    pev->x, pev->y, pev->width, pev->height);
  1184. //  //           fprintf( stderr, "size of site: %d %dn", m_size.cx, m_size.cy); 
  1185. //  //           fprintf( stderr, "pos of site: %d %dn", m_topleft.x, m_topleft.y); 
  1186. //           m_pTopLevelSite->m_pMutex->Lock();
  1187. //           m_pTopLevelSite->SiteMoving(0, 0);
  1188. //           m_pTopLevelSite->m_nLastMoveTime = HX_GET_TICKCOUNT();
  1189. //           m_pTopLevelSite->ScheduleCallback(MOUSE, 100);
  1190. //           m_pTopLevelSite->m_pMutex->Unlock();
  1191. //        }
  1192. //     }
  1193.    //See if we should drop out of full screen
  1194.    if( pEvent->event == FocusOut && IsFullScreen() && !m_bIgnoreFocusOutInFS )
  1195.    {
  1196. //         fprintf( stderr, "_HandleOSEvents: focus out: " );
  1197. //         XEvent* pXEvent = (XEvent*) pEvent->param2;
  1198. //         XFocusChangeEvent* event = (XFocusChangeEvent*) pXEvent;
  1199. //         switch( event->mode )
  1200. //         {
  1201. //            case NotifyAncestor:
  1202. //                fprintf( stderr, "NotifyAncestorn" );
  1203. //                break;
  1204. //            case NotifyVirtual:
  1205. //                fprintf( stderr, "NotifyVirtualn" );
  1206. //                break;
  1207. //            case NotifyInferior:
  1208. //                fprintf( stderr, "NotifyInferiorn" );
  1209. //                break;
  1210. //            case NotifyNonlinear:
  1211. //                fprintf( stderr, "NotifyNonlinearn" );
  1212. //                break;
  1213. //            case NotifyNonlinearVirtual:
  1214. //                fprintf( stderr, "NotifyNonlinearVirtualn" );
  1215. //                break;
  1216. //            case NotifyPointer:
  1217. //                fprintf( stderr, "NotifyPointern" );
  1218. //                break;
  1219. //            case NotifyPointerRoot:
  1220. //                fprintf( stderr, "NotifyPointerRootn" );
  1221. //                break;
  1222. //            case NotifyDetailNone:
  1223. //                fprintf( stderr, "NotifyDetailNonen" );
  1224. //                break;
  1225. //            default:
  1226. //                fprintf( stderr, "screwed.....n" ); 
  1227. //         }
  1228.        ExitFullScreen();
  1229.    }
  1230. #if defined(_DEBUG) && defined(TEST_FULL_SCREEN)
  1231.    if( pEvent->event == KeyPress )
  1232.    {
  1233.       KeySym sym;
  1234.       char   szBuf[10]; /* Flawfinder: ignore */
  1235.       int    nNum;
  1236.       
  1237.       //Lookup the key without any state.
  1238.       nNum = XLookupString( (XKeyEvent*)(pEvent->param2), szBuf, 10, &sym, NULL );
  1239.       if( nNum > 0 )
  1240.       {
  1241.          if( 'f' == szBuf[0] && IsFullScreen() )
  1242.          {
  1243.             //Exit full screen if 'f' is pressed.....
  1244.             m_pTopLevelSite->ExitFullScreen();
  1245.          }
  1246.          else if( 'f' == szBuf[0] && !IsFullScreen() )
  1247.          {
  1248.             //Enter full screen if 'f' is pressed.....
  1249.             m_pTopLevelSite->EnterFullScreen();
  1250.          }
  1251.          
  1252.       }
  1253.       
  1254.    }
  1255. #endif
  1256.    //Exit full screen on ESC pressed......
  1257.    if( pEvent->event == KeyPress )
  1258.    {
  1259.       KeySym sym;
  1260.       char   szBuf[10]; /* Flawfinder: ignore */
  1261.       int    nNum;
  1262.       
  1263.       //Lookup the key without any state.
  1264.       nNum = XLookupString( (XKeyEvent*)(pEvent->param2), szBuf, 10, &sym, NULL );
  1265.       if( nNum > 0 )
  1266.       {
  1267.          if( 27 == (int)szBuf[0] && IsFullScreen() )
  1268.          {
  1269.             //Exit full screen if esc is pressed.....
  1270.             m_pTopLevelSite->ExitFullScreen();
  1271.          }
  1272.       }
  1273.    }
  1274.    
  1275.    //Find out if this is an event we are interested in.  Make sure we
  1276.    //are visible, it isn't a button, expose or FocusIn event and also
  1277.    //make sure it is headed for our window.
  1278.    if (!_ShouldProcess(pEvent))
  1279.    {
  1280.       return FALSE;
  1281.    }
  1282.    
  1283.    if(m_pUser && GetWindow() && GetWindow()->window)
  1284.    {
  1285.       //Do not send an update event to a hidden site.
  1286.       if( pEvent->event == Expose ||
  1287.           pEvent->event == FocusIn  ||
  1288.           pEvent->event == HX_SURFACE_UPDATE )
  1289.       {
  1290.          if( (m_ScrollVertButtonT || m_ScrollHorizButtonR) && IsSiteVisible() )
  1291.          {
  1292.             _DrawArrows();
  1293.          }
  1294.          _ForwardUpdateEvent(pEvent);
  1295.          return TRUE;
  1296.       }
  1297.       else
  1298.       {
  1299.          // get original events info from pEvent
  1300.          XEvent* pXEvent = (XEvent*) pEvent->param2;
  1301.          XButtonEvent* buttonEvent = (XButtonEvent*) pXEvent;
  1302.          
  1303.          //XXXgfw all this code sucks! It really need to be written
  1304.          //for just native events or RMA events. With the change to a
  1305.          //common site it is all screwed up. I am leaving it for now
  1306.          //so we can get on with transparancy but get back to it!
  1307.          //If the user clicks MB1 on a scroll button, handle it here and
  1308.          //don't pass it up or let the user handle the event.
  1309.          //Hit detection here.
  1310.          ////////////////////////////////////////////////////////
  1311.          // BEGIN SCROLLING GARBAGE
  1312.          ////////////////////////////////////////////////////////
  1313.          if(
  1314.             ((pEvent->event==ButtonPress || pEvent->event==ButtonRelease) &&
  1315.              buttonEvent->button==Button1) &&
  1316.             (m_ScrollHorizButtonL || m_ScrollVertButtonB )
  1317.              )
  1318.          {
  1319.             int buttonX=0;
  1320.             int buttonY=0;
  1321.             if( pEvent->event==ButtonRelease )
  1322.             {
  1323.                if( m_bScrollingInProgress )
  1324.                {
  1325.                   m_bScrollingInProgress = FALSE;
  1326.                   m_nScrollDir = 0;
  1327.                   return TRUE ;
  1328.                }
  1329.             }
  1330.             else
  1331.             {
  1332.                 buttonX = buttonEvent->x;
  1333.                 buttonY = buttonEvent->y;
  1334.                
  1335.                BOOL bPointInSite = FALSE;
  1336.                if( m_Region )
  1337.                    bPointInSite = HXPointInRegion(m_Region, buttonX, buttonY);
  1338.                     
  1339.                if( bPointInSite )
  1340.                {
  1341.                   if( m_ScrollHorizButtonL )
  1342.                   {
  1343.                      if( _InButton( m_ptScrollHorizPosL, buttonX, buttonY ))
  1344.                      {
  1345.                         m_bScrollingInProgress = TRUE;
  1346.                         m_nScrollDir = 1;
  1347.                      }
  1348.                      if( _InButton( m_ptScrollHorizPosR, buttonX, buttonY ))
  1349.                      {
  1350.                         m_bScrollingInProgress = TRUE;
  1351.                         m_nScrollDir = 2;
  1352.                      }
  1353.                   }
  1354.                   if( m_ScrollVertButtonT )
  1355.                   {
  1356.                      if( _InButton( m_ptScrollVertPosT, buttonX, buttonY ))
  1357.                      {
  1358.                         m_bScrollingInProgress = TRUE;
  1359.                         m_nScrollDir = 3;
  1360.                      }
  1361.                      if( _InButton( m_ptScrollVertPosB, buttonX, buttonY ))
  1362.                      {
  1363.                         m_bScrollingInProgress = TRUE;
  1364.                         m_nScrollDir = 4;
  1365.                      }                        
  1366.                   }
  1367.                }
  1368.             }
  1369.             if( (m_ScrollHorizButtonL||m_ScrollVertButtonT) && m_bScrollingInProgress)
  1370.             {
  1371.                int xx=0;
  1372.                int yy=0;
  1373.                HXxWindow* pParentWindow = GetParentSite()->GetWindow();
  1374.                //Make it scroll 10% of the parent window each click.
  1375.                HXxSize sizeTmp;
  1376.                GetParentSite()->GetSize(sizeTmp);
  1377.                //Set it to a percentage of the slider range.
  1378.                int incX = sizeTmp.cx/10;
  1379.                int incY = sizeTmp.cy/10;
  1380.                 
  1381.                HX_ASSERT( pParentWindow );
  1382.                 
  1383.                xx = m_XSliderPos;
  1384.                yy = m_YSliderPos;
  1385.                if( m_nScrollDir == 1 )
  1386.                   xx-=incX;
  1387.                if( m_nScrollDir == 2 )
  1388.                   xx+=incX;
  1389.                if( m_nScrollDir == 3 )
  1390.                   yy-=incY;
  1391.                if( m_nScrollDir == 4 )
  1392.                   yy+=incY;
  1393.                
  1394.                if( xx > m_size.cx-sizeTmp.cx )
  1395.                   xx = m_size.cx-sizeTmp.cx;
  1396.                if( yy > m_size.cy-sizeTmp.cy)
  1397.                   yy = m_size.cy-sizeTmp.cy;
  1398.                
  1399.                if( xx < 0 )
  1400.                   xx = 0;
  1401.                if( yy < 0 )
  1402.                   yy = 0;
  1403.                m_XSliderPos = xx;
  1404.                m_YSliderPos = yy;
  1405.                
  1406.                HXxRect rect;
  1407.                DamageRect(rect);
  1408.                
  1409.                InternalForceRedraw();
  1410.             }
  1411.             //Only throw away the event if it had something to do with
  1412.             //scolling.
  1413.             if( m_bScrollingInProgress )
  1414.             {
  1415.                 m_bScrollingInProgress = FALSE;
  1416.                 m_nScrollDir = 0;
  1417.                return TRUE;
  1418.             }
  1419.          }
  1420.          ////////////////////////////////////////////////////////
  1421.          // END SCROLLING GARBAGE
  1422.          ////////////////////////////////////////////////////////
  1423.          point.x = -1;
  1424.          point.y = -1;
  1425.          if( pEvent->event == MotionNotify)
  1426.          {
  1427.             point.x = ((XMotionEvent*)pXEvent)->x;
  1428.             point.y = ((XMotionEvent*)pXEvent)->y;
  1429.          }
  1430.          else if( pEvent->event == ButtonPress )
  1431.          {
  1432.             point.x = ((XMotionEvent*)pXEvent)->x;
  1433.             point.y = ((XMotionEvent*)pXEvent)->y;
  1434.          }
  1435.          //
  1436.          //Give the user a chance at the native event.
  1437.          //
  1438.          if( m_RegionWithoutChildren && HXPointInRegion(m_RegionWithoutChildren, point.x, point.y ))
  1439.          {
  1440.             if( m_Region && HXPointInRegion(m_Region, point.x, point.y) )
  1441.             {
  1442.                 if (m_pUser)
  1443.                     m_pUser->HandleEvent(pEvent);
  1444.             }
  1445.             else
  1446.             {
  1447.                INT32 handledCount = 0;
  1448.                INT32 mapCount     = 0;
  1449.                
  1450.                //try send this to all of our children
  1451.               _unixsitecpp1: 
  1452.                mapCount = m_ChildrenMap.GetCount();
  1453.                CHXMapPtrToPtr::Iterator i;
  1454.                for(i=m_ChildrenMap.Begin() ; i!=m_ChildrenMap.End() ; ++i)
  1455.                {
  1456.                   CHXBaseSite* pSite = (CHXBaseSite*) *i;
  1457.                   pSite->_HandleOSEvents(pEvent);
  1458.                   if (pEvent->handled)
  1459.                   {                      
  1460.                      break;
  1461.                   }
  1462.                   handledCount+=pEvent->handled;
  1463.                   pEvent->handled=0;
  1464.                   
  1465.                   if (m_ChildrenMap.GetCount() != mapCount)
  1466.                   {
  1467.                      goto _unixsitecpp1;
  1468.                   }
  1469.                }
  1470.                if (handledCount)
  1471.                {
  1472.                   pEvent->handled = 1;
  1473.                }
  1474.                HX_ASSERT(handledCount<2);
  1475.             }
  1476.          }
  1477.          pEvent->handled=FALSE;
  1478.       }
  1479.    }
  1480.    
  1481.    return FALSE;
  1482. }
  1483. void CHXUnixSite::_GenerateOSEvent(HXxEvent* pEvent, HXxEvent* pEvent2)
  1484. {
  1485.    //XXXgfw Not needed on UNIX I guess???
  1486. }
  1487. void CHXUnixSite::_GenerateSetCursorEvent()
  1488. {
  1489. #ifdef _DEBUG   
  1490.    fprintf( stderr, "CHXUnixSite::_GenerateSetCursorEventn" );
  1491. #endif   
  1492.    //XXXgfw do we need this??
  1493. }
  1494. void CHXUnixSite::_TryCreateXSlider()
  1495. {
  1496.    if( !m_ScrollHorizButtonL && IsSiteVisible() )
  1497.       _CreateHorizScrollBar();
  1498. }
  1499. void CHXUnixSite::_SetXSliderValues(INT32 range, INT32 pageSize)
  1500. {
  1501.    //XXXgfw this is a do nothing as long as we only have
  1502.    //scroll buttons on unix and not real scroll bars.
  1503. }
  1504. void CHXUnixSite::_TryCreateYSlider()
  1505. {
  1506.    if( !m_ScrollVertButtonT && IsSiteVisible() )
  1507.       _CreateVertScrollBar();
  1508. }
  1509. void CHXUnixSite::_SetYSliderValues(INT32 range, INT32 pageSize)
  1510. {
  1511.    //XXXgfw this is a do nothing as long as we only have
  1512.    //scroll buttons on unix and not real scroll bars.
  1513. }
  1514. void CHXUnixSite::_GetSystemSizeOfSliders(INT32* pWidth, INT32* pHeight)
  1515. {
  1516.    *pWidth = *pHeight = SCROLL_BAR_WIDTH;
  1517. }
  1518. BOOL CHXUnixSite::_IsWindowVisible()
  1519. {
  1520.    HX_RESULT retVal = FALSE;
  1521.    //XXXgfw do this for now...
  1522.    retVal = IsSiteVisible();
  1523.    return retVal;
  1524. }
  1525. void CHXUnixSite::_ShowXSlider(BOOL bShow)
  1526. {
  1527.    if( GetWindow() )
  1528.    {
  1529.       if( bShow )
  1530.          _MapHorzScroll();
  1531.       else
  1532.          _UnmapHorzScroll();
  1533.    }
  1534. }
  1535. void CHXUnixSite::_MoveXSlider( INT32 left,
  1536.                                 INT32 top,
  1537.                                 INT32 right,
  1538.                                 INT32 bottom,
  1539.                                 BOOL bRedraw )
  1540. {
  1541.    //Do nothing right now....
  1542. }
  1543. void CHXUnixSite::_ShowYSlider(BOOL bShow)
  1544. {
  1545.    if( GetWindow() )
  1546.    {
  1547.       if( bShow )
  1548.          _MapVertScroll();
  1549.       else
  1550.          _UnmapVertScroll();
  1551.    }
  1552. }
  1553. void CHXUnixSite::_MoveYSlider( INT32 left,
  1554.                                 INT32 top,
  1555.                                 INT32 right,
  1556.                                 INT32 bottom,
  1557.                                 BOOL bRedraw)
  1558. {
  1559.    //do nothing right now...
  1560. }
  1561. BOOL CHXUnixSite::_DoesXSliderExist()
  1562. {
  1563.    return (m_ScrollHorizButtonL!=0);
  1564. }
  1565. void* CHXUnixSite::_GetContainingWindow()
  1566. {
  1567.    //XXXgfw Do we need this???
  1568.    return NULL;
  1569. }
  1570. void CHXUnixSite::_GetCursorPos(HXxPoint* pPoint)
  1571. {
  1572.    //Return the cursor pos in screen coords.
  1573.    Window rootWin;
  1574.    Window childWin;
  1575.    int rootX=0;
  1576.    int rootY=0;
  1577.    int childX=0;
  1578.    int childY=0;
  1579.    unsigned int mask=0;
  1580.    Bool ret=FALSE;
  1581.    
  1582.    HX_ASSERT(GetWindow());
  1583.    ret = XQueryPointer((Display*)GetWindow()->display,
  1584.                        (Window)GetWindow()->window,
  1585.                        &rootWin,
  1586.                        &childWin,
  1587.                        &rootX, &rootY,
  1588.                        &childX, &childY,
  1589.                        &mask);
  1590.    if(ret)
  1591.    {
  1592.       pPoint->x = rootX;
  1593.       pPoint->y = rootY;
  1594.    }
  1595. }
  1596. void* CHXUnixSite::_GetWindowWithCursor()
  1597. {
  1598.    //Return the cursor pos in screen coords.
  1599.    void*        pRet  = NULL;
  1600.    int          rootX = 0;
  1601.    int          rootY = 0;
  1602.    int          childX= 0;
  1603.    int          childY= 0;
  1604.    unsigned int mask  = 0;
  1605.    Bool         ret   = FALSE;
  1606.    Window       rootWin;
  1607.    Window       childWin;
  1608.    
  1609.    HX_ASSERT(GetWindow());
  1610.    ret = XQueryPointer((Display*)GetWindow()->display,
  1611.                        (Window)GetWindow()->window,
  1612.                        &rootWin,
  1613.                        &childWin,
  1614.                        &rootX, &rootY,
  1615.                        &childX, &childY,
  1616.                        &mask);
  1617.    if(ret)
  1618.    {
  1619.       pRet = (void*)childWin;
  1620.    }
  1621.    return pRet;
  1622. }
  1623. void CHXUnixSite::_MapPointToOSWindow(HXxPoint* pPt, void** pWindowHandle)
  1624. {
  1625.    //XXXgfw we could query the window tree and traverse down but that
  1626.    //is really slow and this isn't used right now.
  1627.    HX_ASSERT( "Not implemented..." == NULL );
  1628. }
  1629. void CHXUnixSite::_ReInitPrimarySurface()
  1630. {
  1631.    //Nothing to do in unix here right?
  1632. }
  1633. BOOL CHXUnixSite::_MoveWindow( void* win,
  1634.                                INT32 X,
  1635.                                INT32 Y,
  1636.                                INT32 nWidth,
  1637.                                INT32 nHeight,
  1638.                                BOOL bRepaint)
  1639. {
  1640.    //XXXgfw we still have to do bRepaint....
  1641.    HX_ASSERT( m_pWindow && m_pWindow->window && m_pWindow->display);
  1642.    _DestroyScrollButtons();
  1643.    XMoveResizeWindow( (Display*)m_pWindow->display,
  1644.                       (Window)m_pWindow->window,
  1645.                       X,
  1646.                       Y,
  1647.                       nWidth,
  1648.                       nHeight
  1649.                       );
  1650.    return TRUE;
  1651. }
  1652. BOOL CHXUnixSite::_UpdateWindow(void* hWnd)
  1653. {
  1654.    //We need to generate a repaint here of the window....
  1655.    return TRUE;
  1656. }
  1657. BOOL CHXUnixSite::_ShowWindow(void* hWnd, INT32 nCmdShow)
  1658. {
  1659.    HX_ASSERT( nCmdShow==HX_SHOW_WINDOW || nCmdShow==HX_HIDE_WINDOW);
  1660.    if( !m_pWindow || !m_pWindow->window || !m_pWindow->display )
  1661.       return FALSE;
  1662.    if( nCmdShow == HX_SHOW_WINDOW )
  1663.    {
  1664.       _MapScrollButtons();
  1665.       XMapWindow( (Display*)m_pWindow->display, (Window)m_pWindow->window );
  1666.    }
  1667.    else
  1668.    {
  1669.       _UnmapScrollButtons();
  1670.       XUnmapWindow( (Display*)m_pWindow->display, (Window)m_pWindow->window );
  1671.    }
  1672.    return TRUE;
  1673. }
  1674. BOOL CHXUnixSite::_SetWindowPos(void* hWnd,
  1675.                                 void* hWndInsertAfter,
  1676.                                 INT32 X,
  1677.                                 INT32 Y,
  1678.                                 INT32 cx,
  1679.                                 INT32 cy,
  1680.                                 INT32 uFlags)
  1681. {
  1682. #ifdef _DEBUG
  1683.    fprintf( stderr, "Now what on earth is this suppose to do??n" );
  1684. #endif
  1685.    return TRUE;
  1686. }
  1687. BOOL CHXUnixSite::_SetWindowRgn(void* hWnd, HXREGION* hRgn, BOOL bRedraw)
  1688. {
  1689.    HX_ASSERT( GetWindow() );
  1690.    XSetRegion( (Display*)GetWindow()->display,
  1691.                (GC)m_pVideoSurface->_GetDC(NULL),
  1692.                (Region)hRgn
  1693.                );
  1694.    if( bRedraw )
  1695.    {
  1696.       HX_ASSERT("Redraw asked for here"==NULL );
  1697.    }
  1698.    
  1699.    return TRUE;
  1700. }
  1701. void CHXUnixSite::_SetFocus(void* pWindow)
  1702. {
  1703.    XWindowAttributes attr;
  1704.    HXxWindow*        pWin = GetWindow();
  1705.    
  1706.    HX_ASSERT(pWin);
  1707.    HX_ASSERT(pWindow);
  1708.    
  1709.    XGetWindowAttributes((Display*)pWin->display, (Window)pWindow, &attr);
  1710.    if( attr.map_state == IsViewable )
  1711.    {
  1712.       XSetInputFocus( (Display*)pWin->display,
  1713.                       (Window)pWindow,
  1714.                       RevertToParent,
  1715.                       CurrentTime
  1716.                       );
  1717.    }
  1718.    
  1719.    return;
  1720. }
  1721. HX_RESULT CHXUnixSite::_EnterFullScreen()
  1722. {
  1723.    HXxWindow* pWin = GetWindow();
  1724.    HX_ASSERT( pWin && pWin->display && pWin->display);
  1725.    HX_ASSERT( this == m_pTopLevelSite );
  1726.    if( 0 != m_winFullScreenWindow || IsFullScreen() )
  1727.    {
  1728.       //We are already in full screen
  1729.       return HXR_FAIL;
  1730.    }
  1731.    
  1732.    //Create a override redirect window to fill the root.
  1733.    XSizeHints           size_hints;
  1734.    Screen*              pScreen = XDefaultScreenOfDisplay((Display*)pWin->display);
  1735.    UINT16               uHorzRes = WidthOfScreen(pScreen);
  1736.    UINT16               uVertRes = HeightOfScreen(pScreen);
  1737.    int                  attrMask = 0;
  1738.    XSetWindowAttributes attr;
  1739.     
  1740.    memset(&attr, 0, sizeof(XSetWindowAttributes));
  1741.    attrMask = CWOverrideRedirect | CWBorderPixel |
  1742.       CWBackPixel | CWCursor;
  1743.    attr.cursor = None;
  1744.    attr.override_redirect = True;
  1745.    attr.background_pixel = BlackPixel((Display*)pWin->display,
  1746.                                       DefaultScreen((Display*)pWin->display));
  1747.    attr.border_pixel     = BlackPixel((Display*)pWin->display,
  1748.                                       DefaultScreen((Display*)pWin->display));
  1749.    size_hints.flags  = PPosition | PSize;
  1750.    size_hints.x      = 0;
  1751.    size_hints.y      = 0;
  1752.    size_hints.width  = uHorzRes;
  1753.    size_hints.height = uVertRes;
  1754.    //Create it.
  1755.    Window window = XCreateWindow((Display*)pWin->display, 
  1756.                                  DefaultRootWindow((Display*)pWin->display),
  1757.                                  size_hints.x,
  1758.                                  size_hints.y,
  1759.                                  size_hints.width,
  1760.                                  size_hints.height, 
  1761.                                  0,
  1762.                                  CopyFromParent,
  1763.                                  InputOutput,
  1764.                                  CopyFromParent,
  1765.                                  attrMask,
  1766.                                  &attr);
  1767.    
  1768.    //Tell the WM about this window.
  1769.    XSetStandardProperties( (Display*)pWin->display,
  1770.                            window,
  1771.                            "unixfullscreen",
  1772.                            "unixfullscreen",
  1773.                            None,
  1774.                            NULL, 0,
  1775.                            &size_hints
  1776.                            );
  1777.    
  1778.    int result = XSelectInput( zm_display, window,
  1779.                               ButtonPressMask   | ButtonReleaseMask | KeyPressMask    |
  1780.                               KeyReleaseMask    | EnterWindowMask   | LeaveWindowMask |
  1781.                               PointerMotionMask | ButtonMotionMask  | KeymapStateMask |
  1782.                               ExposureMask      | StructureNotifyMask | FocusChangeMask
  1783.                               );
  1784.    //Map the window.
  1785.    XMapWindow((Display*)pWin->display, window);
  1786.    //Get ready to resize the presentation....
  1787.    m_pTopLevelSite->m_bDisableForceRedraw = TRUE;
  1788.    //Maintain aspect ratio and Scale it.
  1789.    float fXScale   = (float)uHorzRes/(float)(m_size.cx);
  1790.    float fYScale   = (float)uVertRes/(float)(m_size.cy);
  1791.    float fScale    = (fXScale<fYScale) ? fXScale : fYScale;
  1792.    int nWidth      = (int)(fScale*m_size.cx+.5);
  1793.    int nHeight     = (int)(fScale*m_size.cy+.5);
  1794.    //Center the presentation and save the old size
  1795.    memcpy( &m_PreFullScreenSize, &m_size, sizeof( HXxSize) ); /* Flawfinder: ignore */
  1796.    HXxSize size = {nWidth, nHeight};
  1797.    
  1798.    if( nWidth<uHorzRes )
  1799.       m_ptFullScreenOffset.x = (uHorzRes-nWidth)/2;
  1800.    
  1801.    if( nHeight<uVertRes )
  1802.       m_ptFullScreenOffset.y = (uVertRes-nHeight)/2;
  1803.    //Reparent our main window.......
  1804.    Window       winRootParent = 0;
  1805.    Window       winParent     = 0;
  1806.    Window*      pwinChildren  = NULL;
  1807.    unsigned int nNumChildren  = 0;
  1808.    XQueryTree( (Display*)pWin->display,
  1809.                (Window)pWin->window,
  1810.                &winRootParent,
  1811.                &winParent,
  1812.                &pwinChildren,
  1813.                &nNumChildren
  1814.                );
  1815.    //Free unused children list.
  1816.    XFree( pwinChildren );
  1817.    HX_ASSERT( winParent );
  1818.    m_winOldParent = winParent;
  1819.    XReparentWindow( (Display*)pWin->display,
  1820.                     (Window)pWin->window,
  1821.                     window,
  1822.                     m_ptFullScreenOffset.x,
  1823.                     m_ptFullScreenOffset.y
  1824.                     );
  1825.    
  1826.    //Flush event queue.
  1827.    XSync((Display*)pWin->display, False);
  1828.    //Save it
  1829.    m_winFullScreenWindow = window;
  1830.    m_bInFullScreen = TRUE;
  1831.       //Now resize it...
  1832.    SetSize(m_size);
  1833.    //Redraw the presentation....
  1834.    m_pTopLevelSite->m_bDisableForceRedraw = FALSE;
  1835.    _ForceRedrawAll();
  1836.    //Give it focus....
  1837.    _SetFocus( (void*)pWin->window );
  1838.    
  1839.    // now eat all the focusouts that came as a result of this reparent...
  1840.    XEvent event;
  1841.    while (m_bWindowCreatedByCreate && 
  1842.   XCheckTypedWindowEvent((Display*)pWin->display,
  1843.  (Window)pWin->window,
  1844.  FocusOut,
  1845.  &event))
  1846.    {
  1847.        // just discarding these
  1848.    }
  1849.    //Update the status text...
  1850.    if(m_pStatusText)
  1851.    {
  1852.       m_pStatusText->ParentChangedSize();
  1853.       m_pStatusText->Show();
  1854.    }
  1855.    return HXR_OK;
  1856. }
  1857. HX_RESULT CHXUnixSite::_ExitFullScreen()
  1858. {
  1859.    HX_ASSERT( this == m_pTopLevelSite );
  1860.    HXxWindow* pWin = GetWindow();
  1861.    HX_ASSERT( pWin && pWin->display && pWin->window );
  1862.    //Give the window back to the TLC.
  1863.    XReparentWindow( (Display*)pWin->display,
  1864.                     (Window)pWin->window,
  1865.                     m_winOldParent,
  1866.                     m_position.x, m_position.y
  1867.                     );
  1868.    //Just kill our window and take us out of full screen....
  1869.    if( 0 != m_winFullScreenWindow )
  1870.    {
  1871.       XDestroyWindow( (Display*)pWin->display, m_winFullScreenWindow );
  1872.       m_winFullScreenWindow = 0;
  1873.    }
  1874.    m_bDisableForceRedraw = TRUE;
  1875.    m_bInFullScreen = FALSE;
  1876.    HXxSize size = {0,0};
  1877.    memcpy( &size, &m_PreFullScreenSize, sizeof(HXxSize) ); /* Flawfinder: ignore */
  1878.    m_PreFullScreenSize.cx = m_PreFullScreenSize.cy = 0;
  1879.    SetSize(size);
  1880.    _SetFocus( (void*)pWin->window );
  1881.    m_ptFullScreenOffset.x = 0;
  1882.    m_ptFullScreenOffset.y = 0;
  1883.    
  1884.    m_bDisableForceRedraw = FALSE;
  1885.    _ForceRedrawAll();
  1886.    
  1887.    if(m_pStatusText)
  1888.    {
  1889.       m_pStatusText->ParentChangedSize();
  1890.       m_pStatusText->Hide();
  1891.    }
  1892.    //move the site back to where it was.
  1893.    if( m_pTopLevelSite )
  1894.    {
  1895.        m_pTopLevelSite->_SetPosition(m_CreateWindowPos);
  1896.    }
  1897.    
  1898.    return HXR_OK;
  1899. }
  1900. HX_RESULT CHXUnixSite::_EventOccurred(HXxEvent* pEvent)
  1901. {
  1902.    return HXR_OK;
  1903. }
  1904. HX_RESULT CHXUnixSite::_TestFullScreen( void* hTestBitmap,
  1905.                                         const char* pszStatusText )
  1906. {
  1907. #ifdef _DEBUG   
  1908.    fprintf( stderr, "Going to test full screen....n" );
  1909. #endif   
  1910.    return HXR_OK;
  1911. }
  1912. void CHXUnixSite::ProcessEvent(HXxEvent* pEvent)
  1913. {
  1914.    if(NULL==pEvent)
  1915.    {
  1916.       return;
  1917.    }
  1918.    //Expose event compression. Combine all outstanding expose events
  1919.    //into one big region.
  1920.    if(Expose==pEvent->event)
  1921.    {  
  1922.       _CollapseExposeEvents((XEvent*)pEvent->param2);
  1923.    }
  1924.    //Send the event to each registered UnixSite.
  1925.    void* pSite   = NULL; 
  1926.    void* pWindow = NULL;
  1927.    POSITION  pos = z_mapSiteToWindow.GetStartPosition();
  1928.    while( pos )
  1929.    {
  1930.       z_mapSiteToWindow.GetNextAssoc(pos, pSite, pWindow);
  1931.       CHXUnixSite* pSiteWindowed = (CHXUnixSite*)pSite;
  1932.       HX_ASSERT(pSiteWindowed);
  1933.       pSiteWindowed->AddRef();
  1934.       //Call back into the basesite's event loop.
  1935.       (pSiteWindowed->GetTopLevelSite())->EventOccurred(pEvent);
  1936.       pSiteWindowed->Release();
  1937.    }   
  1938. }
  1939. void CHXUnixSite::_CollapseExposeEvents(XEvent* xevent)
  1940. {
  1941.    Display*      display = xevent->xany.display;
  1942.    Window        window  = xevent->xany.window;
  1943.    XExposeEvent* expose_event = (XExposeEvent*)xevent;
  1944.    XEvent        new_event;
  1945.    XExposeEvent* new_expose_event = (XExposeEvent*)&new_event;
  1946.    ushort        x1;
  1947.    ushort        y1;
  1948.    ushort        x2;
  1949.    ushort        y2;
  1950.    ushort        x3;
  1951.    ushort        y3;
  1952.    x1 = expose_event->x;
  1953.    y1 = expose_event->y;
  1954.    x2 = x1 + expose_event->width;
  1955.    y2 = y1 + expose_event->height;
  1956.             
  1957.    while( XCheckWindowEvent(display, window, ExposureMask, &new_event) )
  1958.    { 
  1959.       if (new_expose_event->x < x1)
  1960.          x1 = new_expose_event->x;
  1961.         
  1962.       if (new_expose_event->y < y1)
  1963.          y1 = new_expose_event->y;
  1964.                 
  1965.       x3 = new_expose_event->x + new_expose_event->width;
  1966.       if (x3 > x2)
  1967.          x2 = x3;
  1968.                 
  1969.       y3 = new_expose_event->y + new_expose_event->height;
  1970.       if (y3 > y2)
  1971.          y2 = y3;
  1972.    }
  1973.             
  1974.    expose_event->x = x1;
  1975.    expose_event->y = y1;
  1976.    expose_event->width = x2 - x1;
  1977.    expose_event->height = y2 - y1;
  1978.    expose_event->count = new_expose_event->count;
  1979. }
  1980. BOOL CHXUnixSite::_ShouldProcess(HXxEvent* pEvent)
  1981. {
  1982.    BOOL bShouldProcessThisEvent = TRUE;
  1983.    
  1984.    if( !IsSiteVisible() )
  1985.    {
  1986.       switch (pEvent->event)
  1987.       {
  1988.          case ButtonPress:
  1989.          case ButtonRelease:
  1990.          case Expose:
  1991.          case FocusIn:
  1992.             bShouldProcessThisEvent = FALSE;
  1993.             break;
  1994.          default:
  1995.             break;
  1996.       }
  1997.    }
  1998.    if(m_pWindow && m_pWindow->window!=pEvent->window)
  1999.    {
  2000.       bShouldProcessThisEvent = FALSE;
  2001.    }
  2002.    return bShouldProcessThisEvent;
  2003. }
  2004. ///////////////////////////////////////////////////////
  2005. //
  2006. // UnixEventHandler methods...
  2007. //
  2008. CHXUnixSite::UnixEventHandler::UnixEventHandler(CHXUnixSite* pParent)
  2009.    : m_pParent(pParent),
  2010.      m_lRefCount(0),
  2011.      m_cbHandle(0)
  2012. {
  2013.    HX_ASSERT(m_pParent);
  2014.    HX_ASSERT(m_pParent->m_pScheduler);
  2015.    m_cbHandle = m_pParent->m_pScheduler->RelativeEnter((IHXCallback*)this, 30);
  2016. }
  2017. CHXUnixSite::UnixEventHandler::~UnixEventHandler()
  2018. {
  2019.     CancelCallback();
  2020. }
  2021. void
  2022. CHXUnixSite::UnixEventHandler::CancelCallback()
  2023. {
  2024.    if( m_cbHandle && m_pParent && m_pParent->m_pScheduler )
  2025.    {
  2026.       UINT32 tempHandle = m_cbHandle;
  2027.       m_cbHandle = 0;
  2028.       m_pParent->m_pScheduler->Remove(tempHandle);
  2029.    }
  2030. }
  2031.     
  2032. HX_RESULT CHXUnixSite::UnixEventHandler::QueryInterface(REFIID riid, void** ppvObj)
  2033. {
  2034.    if (IsEqualIID(riid, IID_IHXCallback))
  2035.    {
  2036.       AddRef();
  2037.       *ppvObj = (IHXCallback*)this;
  2038.       return HXR_OK;
  2039.    }
  2040.    else if (IsEqualIID(riid, IID_IUnknown))
  2041.    {
  2042.       AddRef();
  2043.       *ppvObj = this;
  2044.       return HXR_OK;
  2045.    }
  2046.     
  2047.    *ppvObj = NULL;
  2048.    return HXR_NOINTERFACE;
  2049. }
  2050. ULONG32 CHXUnixSite::UnixEventHandler::AddRef()
  2051. {
  2052.    return InterlockedIncrement(&m_lRefCount);
  2053. }
  2054. ULONG32 CHXUnixSite::UnixEventHandler::Release()
  2055. {
  2056.    HX_ASSERT(m_lRefCount>0);
  2057.    if( InterlockedDecrement(&m_lRefCount)>0 )
  2058.    {
  2059.       return m_lRefCount;
  2060.    }
  2061.    delete this;
  2062.    return 0;
  2063. }
  2064. //IHXCallback methods
  2065. HX_RESULT CHXUnixSite::UnixEventHandler::Func()
  2066. {
  2067.     XEvent xevent;
  2068.     static HXxEvent pnevent;
  2069.     
  2070.     m_cbHandle = 0;
  2071.     while(XPending(m_pParent->zm_display))
  2072.     {
  2073.         XNextEvent(m_pParent->zm_display, &xevent);
  2074.         
  2075.         // package native event in HXxEvent and send to dispatcher
  2076.         pnevent.event = xevent.type;
  2077.         pnevent.window = (void *)xevent.xany.window;
  2078.         pnevent.param1 = xevent.xany.display;
  2079.         pnevent.param2 = &xevent;
  2080.         m_pParent->ProcessEvent(&pnevent);
  2081.     }
  2082.     //XXXgfw As a workaround for the overlay not moving while the
  2083.     //player is paused, we will check it here and update it if needed.
  2084.     if( m_pParent && m_pParent->m_pTopLevelSite )
  2085.     {
  2086.         CHXUnixSite* pSite = (CHXUnixSite*)m_pParent->m_pTopLevelSite;
  2087.         pSite->_UpdateOverlayIfNeeded();
  2088.     }
  2089.     
  2090.     if (m_pParent && m_pParent->m_pScheduler)
  2091.     {
  2092.         m_cbHandle = m_pParent->m_pScheduler->RelativeEnter((IHXCallback*)this, 30);
  2093.     }
  2094.     return HXR_OK;
  2095. }
  2096. void CHXUnixSite::_UpdateOverlayIfNeeded()
  2097. {
  2098.     if( m_pVideoSurface )
  2099.     {
  2100.         if( m_pVideoSurface->m_nBltMode == HX_OVERLAY_BLT )
  2101.         {
  2102.             ULONG32 ulNow = HX_GET_BETTERTICKCOUNT();
  2103.             CUnixSurf* pSurf = (CUnixSurf*)m_pVideoSurface;
  2104.             if( ulNow- pSurf->m_ulLastOverlayUpdateTime > 50 )
  2105.             {
  2106.                 SiteMoving(0,0);
  2107.             }
  2108.         }
  2109.     }
  2110.     LISTPOSITION pos = m_ChildrenInZOrder.GetHeadPosition();
  2111.     while(pos)
  2112.     {
  2113.         CHXUnixSite* pSite = (CHXUnixSite*)m_ChildrenInZOrder.GetNext(pos);
  2114.         pSite->_UpdateOverlayIfNeeded();
  2115.     }
  2116. }
  2117. BOOL  CHXUnixSite::_ShouldEnterForceRedraw()
  2118. {
  2119.    if( !m_bDamaged || !m_pUser || !IsSiteVisible() )
  2120.    {
  2121.       return FALSE;
  2122.    }
  2123.    if(InterlockedIncrement(&m_lBltEntryCount)>1)
  2124.    {
  2125.       InterlockedDecrement(&m_lBltEntryCount);
  2126.       return FALSE;
  2127.    }
  2128.          
  2129.    return TRUE;
  2130. }
  2131. void  CHXUnixSite::_ExitForceRedraw()
  2132. {
  2133.    InterlockedDecrement(&m_lBltEntryCount);
  2134. }
  2135. /////////////////////////////////////////////////////////
  2136. //
  2137. // CHXSiteEventHandler
  2138. //
  2139. /////////////////////////////////////////////////////////
  2140. CHXSiteEventHandler::CHXSiteEventHandler(IUnknown* pContext)
  2141.    : m_lRefCount(0)
  2142.    , m_pContext(NULL)
  2143. {
  2144.    if (pContext)
  2145.    {
  2146.       m_pContext = pContext;
  2147.       m_pContext->AddRef();
  2148.    }
  2149. CHXSiteEventHandler::~CHXSiteEventHandler()
  2150. {
  2151.    HX_RELEASE(m_pContext);
  2152. }
  2153. HX_RESULT CHXSiteEventHandler::QueryInterface(REFIID riid, void** ppvObj)
  2154. {
  2155.    if (IsEqualIID(riid, IID_IUnknown))
  2156.    {
  2157.       AddRef();
  2158.       *ppvObj = (IUnknown*)(IHXSiteEventHandler*)this;
  2159.       return HXR_OK;
  2160.    }
  2161.    else if (IsEqualIID(riid, IID_IHXSiteEventHandler))
  2162.    {
  2163.       AddRef();
  2164.       *ppvObj = (IHXSiteEventHandler*)this;
  2165.       return HXR_OK;
  2166.    }
  2167.    *ppvObj = NULL;
  2168.    return HXR_NOINTERFACE;
  2169. }
  2170. ULONG32 CHXSiteEventHandler::AddRef()
  2171. {
  2172.    return InterlockedIncrement(&m_lRefCount);
  2173. }
  2174. ULONG32 CHXSiteEventHandler::Release()
  2175. {
  2176.    if (InterlockedDecrement(&m_lRefCount) > 0)
  2177.    {
  2178.       return m_lRefCount;
  2179.    }
  2180.    delete this;
  2181.    return 0;
  2182. }
  2183. HX_RESULT CHXSiteEventHandler::EventOccurred(HXxEvent* pEvent)
  2184. {
  2185.    CHXUnixSite::ProcessEvent(pEvent);
  2186.    return HXR_OK;
  2187. }