X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/7e085304e81028d44c4670b4020662f3f0af97fd..761e1e0702fb50aca31fb7a38dcb0f00ae4d2ac6:/src/x11/window.cpp diff --git a/src/x11/window.cpp b/src/x11/window.cpp index 3d7a05a6b2..0ddb715476 100644 --- a/src/x11/window.cpp +++ b/src/x11/window.cpp @@ -125,6 +125,7 @@ bool wxWindowX11::Create(wxWindow *parent, wxWindowID id, Display *xdisplay = (Display*) wxGlobalDisplay(); int xscreen = DefaultScreen( xdisplay ); + Visual *xvisual = DefaultVisual( xdisplay, xscreen ); Colormap cm = DefaultColormap( xdisplay, xscreen ); m_backgroundColour = wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE); @@ -133,35 +134,40 @@ bool wxWindowX11::Create(wxWindow *parent, wxWindowID id, m_foregroundColour = *wxBLACK; m_foregroundColour.CalcPixel( (WXColormap) cm ); - Window parentWindow = (Window) parent->GetMainWindow(); + Window xparent = (Window) parent->GetMainWindow(); + XSetWindowAttributes xattributes; + + long xattributes_mask = + CWEventMask | + CWBorderPixel | CWBackPixel; + + xattributes.background_pixel = m_backgroundColour.GetPixel(); + xattributes.border_pixel = BlackPixel( xdisplay, xscreen ); + + xattributes.event_mask = + ExposureMask | KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask | + ButtonMotionMask | EnterWindowMask | LeaveWindowMask | PointerMotionMask | + KeymapStateMask | FocusChangeMask | ColormapChangeMask | StructureNotifyMask | + PropertyChangeMask; + wxSize size2(size); if (size2.x == -1) - size2.x = 100; + size2.x = 20; if (size2.y == -1) - size2.y = 100; + size2.y = 20; wxPoint pos2(pos); if (pos2.x == -1) - pos2.x = 100; + pos2.x = 0; if (pos2.y == -1) - pos2.y = 100; + pos2.y = 0; - Window xwindow = XCreateSimpleWindow( - xdisplay, parentWindow, - pos2.x, pos2.y, size2.x, size2.y, 0, - m_backgroundColour.GetPixel(), - m_backgroundColour.GetPixel() ); + Window xwindow = XCreateWindow( xdisplay, xparent, pos2.x, pos2.y, size2.x, size2.y, + 0, DefaultDepth(xdisplay,xscreen), InputOutput, xvisual, xattributes_mask, &xattributes ); m_mainWidget = (WXWindow) xwindow; - // Select event types wanted - XSelectInput( xdisplay, xwindow, - ExposureMask | KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask | - ButtonMotionMask | EnterWindowMask | LeaveWindowMask | PointerMotionMask | - KeymapStateMask | FocusChangeMask | ColormapChangeMask | StructureNotifyMask | - PropertyChangeMask); - wxAddWindowToTable( xwindow, (wxWindow*) this ); // Is a subwindow, so map immediately @@ -193,12 +199,7 @@ wxWindowX11::~wxWindowX11() m_isBeingDeleted = TRUE; // X11-specific actions first - Window main = (Window) m_mainWidget; - if ( main ) - { - // Removes event handlers - //DetachWidget(main); - } + Window xwindow = (Window) m_mainWidget; if (m_parent) m_parent->RemoveChild( this ); @@ -206,11 +207,11 @@ wxWindowX11::~wxWindowX11() DestroyChildren(); // Destroy the window - if (main) + if (xwindow) { - XSelectInput( wxGlobalDisplay(), main, NoEventMask); - wxDeleteWindowFromTable( main ); - XDestroyWindow( wxGlobalDisplay(), main ); + XSelectInput( wxGlobalDisplay(), xwindow, NoEventMask); + wxDeleteWindowFromTable( xwindow ); + XDestroyWindow( wxGlobalDisplay(), xwindow ); m_mainWidget = NULL; } } @@ -253,6 +254,19 @@ wxWindow *wxWindowBase::FindFocus() return NULL; } +wxWindow *wxWindowX11::GetFocusWidget() +{ + wxWindow *win = (wxWindow*) this; + while (!win->IsTopLevel()) + { + win = win->GetParent(); + if (!win) + return (wxWindow*) NULL; + } + + return win; +} + // Enabling/disabling handled by event loop, and not sending events // if disabled. bool wxWindowX11::Enable(bool enable) @@ -271,17 +285,13 @@ bool wxWindowX11::Show(bool show) Display *xdisp = (Display*) GetXDisplay(); if (show) { - wxString msg; - msg.Printf("Mapping window of type %s", GetClassInfo()->GetClassName()); - wxLogDebug(msg); + // wxLogDebug( "Mapping window of type %s", GetName().c_str() ); XMapWindow(xdisp, xwin); - XSync(xdisp, False); + XSync(xdisp, False); } else { - wxString msg; - msg.Printf("Unmapping window of type %s", GetClassInfo()->GetClassName()); - wxLogDebug(msg); + // wxLogDebug( "Unmapping window of type %s", GetName().c_str() ); XUnmapWindow(xdisp, xwin); } @@ -347,7 +357,7 @@ void wxWindowX11::DoCaptureMouse() return; } - wxLogDebug("Grabbed pointer"); + /// wxLogDebug("Grabbed pointer"); #if 0 res = XGrabButton(wxGlobalDisplay(), AnyButton, AnyModifier, @@ -406,7 +416,8 @@ void wxWindowX11::DoReleaseMouse() XUngrabKeyboard( wxGlobalDisplay(), CurrentTime ); #endif } - wxLogDebug("Ungrabbed pointer"); + + // wxLogDebug("Ungrabbed pointer"); m_winCaptured = FALSE; } @@ -460,6 +471,29 @@ void wxWindowX11::WarpPointer (int x, int y) // Does a physical scroll void wxWindowX11::ScrollWindow(int dx, int dy, const wxRect *rect) { + // No scrolling requested. + if ((dx == 0) && (dy == 0)) return; + + if (!m_updateRegion.IsEmpty()) + { + m_updateRegion.Offset( dx, dy ); + + int cw = 0; + int ch = 0; + GetSize( &cw, &ch ); // GetClientSize() ?? + m_updateRegion.Intersect( 0, 0, cw, ch ); + } + + if (!m_clearRegion.IsEmpty()) + { + m_clearRegion.Offset( dx, dy ); + + int cw = 0; + int ch = 0; + GetSize( &cw, &ch ); // GetClientSize() ?? + m_clearRegion.Intersect( 0, 0, cw, ch ); + } + Window xwindow = (Window) GetMainWindow(); wxCHECK_RET( xwindow, wxT("invalid window") ); @@ -469,34 +503,55 @@ void wxWindowX11::ScrollWindow(int dx, int dy, const wxRect *rect) GC xgc = XCreateGC( xdisplay, xwindow, 0, NULL ); XSetGraphicsExposures( xdisplay, xgc, True ); - int cw = 0; - int ch = 0; - GetClientSize( &cw, &ch ); + int s_x; + int s_y; + int cw; + int ch; + if (rect) + { + s_x = rect->x; + s_y = rect->y; + cw = rect->width; + ch = rect->height; + } + else + { + s_x = 0; + s_y = 0; + GetClientSize( &cw, &ch ); + } + + wxPoint offset = GetClientAreaOrigin(); + s_x += offset.x; + s_y += offset.y; + int w = cw - abs(dx); int h = ch - abs(dy); - + if ((h < 0) || (w < 0)) { Refresh(); } else { - int s_x = 0; - int s_y = 0; - if (dx < 0) s_x = -dx; - if (dy < 0) s_y = -dy; - int d_x = 0; - int d_y = 0; + wxRect rect; + if (dx < 0) rect.x = cw+dx; else rect.x = s_x; + if (dy < 0) rect.y = ch+dy; else rect.y = s_y; + if (dy != 0) rect.width = cw; else rect.width = abs(dx); + if (dx != 0) rect.height = ch; else rect.height = abs(dy); + + int d_x = s_x; + int d_y = s_y; + if (dx < 0) s_x += -dx; + if (dy < 0) s_y += -dy; if (dx > 0) d_x = dx; if (dy > 0) d_y = dy; XCopyArea( xdisplay, xwindow, xwindow, xgc, s_x, s_y, w, h, d_x, d_y ); + + // printf( "s_x %d s_y %d w %d h %d d_x %d d_y %d\n", s_x, s_y, w, h, d_x, d_y ); - wxRect rect; - if (dx < 0) rect.x = cw+dx; else rect.x = 0; - if (dy < 0) rect.y = ch+dy; else rect.y = 0; - if (dy != 0) rect.width = cw; else rect.width = abs(dx); - if (dx != 0) rect.height = ch; else rect.height = abs(dy); + // printf( "rect %d %d %d %d\n", rect.x, rect.y, rect.width, rect.height ); m_updateRegion.Union( rect ); m_clearRegion.Union( rect ); @@ -554,6 +609,7 @@ void wxWindowX11::DoGetSize(int *x, int *y) const wxCHECK_RET( xwindow, wxT("invalid window") ); XSync(wxGlobalDisplay(), False); + XWindowAttributes attr; Status status = XGetWindowAttributes( wxGlobalDisplay(), xwindow, &attr ); wxASSERT(status); @@ -624,7 +680,7 @@ void wxWindowX11::DoGetClientSize(int *x, int *y) const if (window) { - XSync(wxGlobalDisplay(), False); + XSync(wxGlobalDisplay(), False); // Is this really a good idea? XWindowAttributes attr; Status status = XGetWindowAttributes( wxGlobalDisplay(), window, &attr ); wxASSERT(status); @@ -639,72 +695,70 @@ void wxWindowX11::DoGetClientSize(int *x, int *y) const void wxWindowX11::DoSetSize(int x, int y, int width, int height, int sizeFlags) { - if (!GetMainWindow()) - return; + Window xwindow = (Window) GetMainWindow(); - XWindowChanges windowChanges; - windowChanges.x = 0; - windowChanges.y = 0; - windowChanges.width = 0; - windowChanges.height = 0; - windowChanges.stack_mode = 0; - int valueMask = 0; + wxCHECK_RET( xwindow, wxT("invalid window") ); + + XWindowAttributes attr; + Status status = XGetWindowAttributes( wxGlobalDisplay(), xwindow, &attr ); + wxCHECK_RET( status, wxT("invalid window attributes") ); + + int new_x = attr.x; + int new_y = attr.y; + int new_w = attr.width; + int new_h = attr.height; + if (x != -1 || (sizeFlags & wxSIZE_ALLOW_MINUS_ONE)) { - int yy = 0; + int yy = 0; AdjustForParentClientOrigin( x, yy, sizeFlags); - windowChanges.x = x; - valueMask |= CWX; + new_x = x; } if (y != -1 || (sizeFlags & wxSIZE_ALLOW_MINUS_ONE)) { - int xx = 0; + int xx = 0; AdjustForParentClientOrigin( xx, y, sizeFlags); - windowChanges.y = y; - valueMask |= CWY; + new_y = y; } - if (width != -1 || (sizeFlags & wxSIZE_ALLOW_MINUS_ONE)) + if (width != -1) { - windowChanges.width = width /* - m_borderSize*2 */; - if (windowChanges.width == 0) - windowChanges.width = 1; - valueMask |= CWWidth; + new_w = width; + if (new_w <= 0) + new_w = 20; } - if (height != -1 || (sizeFlags & wxSIZE_ALLOW_MINUS_ONE)) + if (height != -1) { - windowChanges.height = height /* -m_borderSize*2*/; - if (windowChanges.height == 0) - windowChanges.height = 1; - valueMask |= CWHeight; + new_h = height; + if (new_h <= 0) + new_h = 20; } - - XConfigureWindow(wxGlobalDisplay(), (Window) GetMainWindow(), - valueMask, & windowChanges); - XSync(wxGlobalDisplay(), False); + + DoMoveWindow( new_x, new_y, new_w, new_h ); } void wxWindowX11::DoSetClientSize(int width, int height) { - if (!GetMainWindow()) - return; + Window xwindow = (Window) GetMainWindow(); - XWindowChanges windowChanges; - int valueMask = 0; + wxCHECK_RET( xwindow, wxT("invalid window") ); + XWindowAttributes attr; + Status status = XGetWindowAttributes( wxGlobalDisplay(), xwindow, &attr ); + wxCHECK_RET( status, wxT("invalid window attributes") ); + + int new_x = attr.x; + int new_y = attr.y; + int new_w = attr.width; + int new_h = attr.height; + if (width != -1) - { - windowChanges.width = width ; - valueMask |= CWWidth; - } + new_w = width; + if (height != -1) - { - windowChanges.height = height ; - valueMask |= CWHeight; - } - XConfigureWindow(wxGlobalDisplay(), (Window) GetMainWindow(), - valueMask, & windowChanges); - XSync(wxGlobalDisplay(), False); + new_h = height; + + DoMoveWindow( new_x, new_y, new_w, new_h ); } // For implementation purposes - sometimes decorations make the client area @@ -759,7 +813,19 @@ void wxWindowX11::SetSizeHints(int minW, int minH, int maxW, int maxH, int incW, void wxWindowX11::DoMoveWindow(int x, int y, int width, int height) { - DoSetSize(x, y, width, height); + Window xwindow = (Window) GetMainWindow(); + + wxCHECK_RET( xwindow, wxT("invalid window") ); + + XWindowChanges windowChanges; + windowChanges.x = x; + windowChanges.y = y; + windowChanges.width = width; + windowChanges.height = height; + windowChanges.stack_mode = 0; + int valueMask = CWX | CWY | CWWidth | CWHeight; + + XConfigureWindow( wxGlobalDisplay(), xwindow, valueMask, &windowChanges ); } // --------------------------------------------------------------------------- @@ -875,8 +941,11 @@ void wxWindowX11::Update() { if (!m_updateRegion.IsEmpty()) { - // Actually send erase and paint events. - X11SendPaintEvents(); + // Actually send erase events. + SendEraseEvents(); + + // Actually send paint events. + SendPaintEvents(); } } @@ -888,12 +957,12 @@ void wxWindowX11::Clear() dc.Clear(); } -void wxWindowX11::X11SendPaintEvents() +void wxWindowX11::SendEraseEvents() { - m_clipPaintRegion = TRUE; - if (!m_clearRegion.IsEmpty()) { + m_clipPaintRegion = TRUE; + wxWindowDC dc( (wxWindow*)this ); dc.SetClippingRegion( m_clearRegion ); @@ -902,7 +971,6 @@ void wxWindowX11::X11SendPaintEvents() if (!GetEventHandler()->ProcessEvent(erase_event)) { - printf( "Hallo!\n" ); Window xwindow = (Window) GetMainWindow(); Display *xdisplay = wxGlobalDisplay(); GC xgc = XCreateGC( xdisplay, xwindow, 0, NULL ); @@ -915,9 +983,18 @@ void wxWindowX11::X11SendPaintEvents() upd.GetX(), upd.GetY(), upd.GetWidth(), upd.GetHeight() ); upd ++; } + XFreeGC( xdisplay, xgc ); } m_clearRegion.Clear(); + + m_clipPaintRegion = FALSE; } +} + + +void wxWindowX11::SendPaintEvents() +{ + m_clipPaintRegion = TRUE; wxNcPaintEvent nc_paint_event( GetId() ); nc_paint_event.SetEventObject( this );