{
}
+#if wxUSE_NANOX
+void wxWindowDC::DoDrawBitmap( const wxBitmap &bitmap,
+ wxCoord x, wxCoord y,
+ bool useMask )
+{
+ wxCHECK_RET( Ok(), wxT("invalid window dc") );
+
+ wxCHECK_RET( bitmap.Ok(), wxT("invalid bitmap") );
+
+ bool is_mono = (bitmap.GetBitmap() != NULL);
+
+ /* scale/translate size and position */
+ int xx = XLOG2DEV(x);
+ int yy = YLOG2DEV(y);
+
+ int w = bitmap.GetWidth();
+ int h = bitmap.GetHeight();
+
+ CalcBoundingBox( x, y );
+ CalcBoundingBox( x + w, y + h );
+
+ if (!m_window) return;
+
+ int ww = XLOG2DEVREL(w);
+ int hh = YLOG2DEVREL(h);
+
+ /* compare to current clipping region */
+ if (!m_currentClippingRegion.IsNull())
+ {
+ wxRegion tmp( xx,yy,ww,hh );
+ tmp.Intersect( m_currentClippingRegion );
+ if (tmp.IsEmpty())
+ return;
+ }
+
+ /* scale bitmap if required */
+ wxBitmap use_bitmap;
+ if ((w != ww) || (h != hh))
+ {
+ wxImage image( bitmap );
+ image.Rescale( ww, hh );
+#if 0
+ if (is_mono)
+ use_bitmap = image.ConvertToMonoBitmap(255,255,255);
+ else
+#endif
+ use_bitmap = image.ConvertToBitmap();
+ }
+ else
+ {
+ use_bitmap = bitmap;
+ }
+
+ /* apply mask if any */
+ WXPixmap mask = NULL;
+ if (use_bitmap.GetMask())
+ mask = use_bitmap.GetMask()->GetBitmap();
+
+ if (useMask && mask)
+ {
+ Pixmap pixmap = (Pixmap) use_bitmap.GetPixmap() ;
+ Pixmap maskPixmap = (Pixmap) use_bitmap.GetMask()->GetBitmap() ;
+ Pixmap bufPixmap = GrNewPixmap(w, h, 0);
+ GC gc = GrNewGC();
+ GrSetGCUseBackground(gc, FALSE);
+ GrSetGCMode(gc, GR_MODE_COPY);
+
+ // This code assumes that background and foreground
+ // colours are used in ROPs, like in MSW.
+ // Not sure if this is true.
+
+ // Copy destination to buffer.
+ // In DoBlit, we need this step because Blit has
+ // a ROP argument. Here, we don't need it.
+ // In DoBlit, we may be able to eliminate this step
+ // if we check if the rop = copy
+#if 0
+ GrCopyArea(bufPixmap, gc, 0, 0, w, h, (Window) m_window,
+ 0, 0, GR_MODE_COPY);
+#endif
+
+ // Copy src to buffer using selected raster op (none selected
+ // in DrawBitmap, so just use Gxcopy)
+ GrCopyArea(bufPixmap, gc, 0, 0, w, h, pixmap,
+ 0, 0, GR_MODE_COPY);
+
+ // Set masked area in buffer to BLACK (pixel value 0)
+ GrSetGCBackground(gc, WHITE);
+ GrSetGCForeground(gc, BLACK);
+ GrCopyArea(bufPixmap, gc, 0, 0, w, h, maskPixmap,
+ 0, 0, GR_MODE_AND);
+
+ // set unmasked area in dest to BLACK
+ GrSetGCBackground(gc, BLACK);
+ GrSetGCForeground(gc, WHITE);
+ GrCopyArea((Window) m_window, gc, xx, yy, w, h, maskPixmap,
+ 0, 0, GR_MODE_AND);
+
+ // OR buffer to dest
+ GrCopyArea((Window) m_window, gc, xx, yy, w, h, bufPixmap,
+ 0, 0, GR_MODE_OR);
+
+ GrDestroyGC(gc);
+ GrDestroyWindow(bufPixmap);
+ }
+ else
+ XCopyArea( (Display*) m_display, (Pixmap) use_bitmap.GetPixmap(), (Window) m_window,
+ (GC) m_penGC, 0, 0, w, h, xx, yy );
+
+ /* remove mask again if any */
+ if (useMask && mask)
+ {
+ if (!m_currentClippingRegion.IsNull())
+ XSetRegion( (Display*) m_display, (GC) m_penGC, (Region) m_currentClippingRegion.GetX11Region() );
+ }
+}
+
+#else
+
+// Normal X11
void wxWindowDC::DoDrawBitmap( const wxBitmap &bitmap,
wxCoord x, wxCoord y,
bool useMask )
}
}
}
+#endif
+ // wxUSE_NANOX/!wxUSE_NANOX
bool wxWindowDC::DoBlit( wxCoord xdest, wxCoord ydest, wxCoord width, wxCoord height,
wxDC *source, wxCoord xsrc, wxCoord ysrc, int rop, bool useMask,
--- /dev/null
+/////////////////////////////////////////////////////////////////////////////
+// Name: reparent.cpp
+// Purpose: wxWindow
+// Author: Julian Smart
+// Modified by:
+// Created: 2002-03-09
+// RCS-ID: $Id$
+// Copyright: (c) Julian Smart
+// Licence: wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+// ============================================================================
+// declarations
+// ============================================================================
+
+// ----------------------------------------------------------------------------
+// headers
+// ----------------------------------------------------------------------------
+
+#ifdef __GNUG__
+ #pragma implementation "reparent.h"
+#endif
+
+#include "wx/x11/reparent.h"
+#include "wx/evtloop.h"
+#include "wx/log.h"
+#include "wx/app.h"
+#include "wx/timer.h"
+
+#include "wx/x11/private.h"
+#include "X11/Xatom.h"
+
+/*
+
+ Adapted from code by Mike Yang, as follows.
+
+From: Mike Yang (mikey@eukanuba.wpd.sgi.com)
+Subject: Re: Wrapping new widget around existing windows
+Newsgroups: comp.windows.x
+View: Complete Thread (17 articles) | Original Format
+Date: 1991-08-09 09:45:48 PST
+
+
+Enough people asked, so here's my test program which reparents another
+window. It's a single file (reparent.c), and will work with Motif or
+Xaw. Xaw users should comment out the "#define MOTIF" line.
+
+The reparent program first prompts for the application name of the
+client that it will reparent. If you're going to start the
+application override_redirect (e.g. -xrm "*overrideRedirect: true"),
+then this name is ignored and the first override_redirect window is
+assumed to be the one.
+
+Input focus is supposed to be correctly handled, as is resizing with
+window manager hints. If you have input focus problems, try launching
+your application override_redirect instead. This method is preferred
+anyway, since you can map it off-screen and then avoid the "window
+flash" effect as the application's top-level window is reparented.
+
+-----------------------------------------------------------------------
+ Mike Yang Silicon Graphics, Inc.
+ mikey@sgi.com 415/335-1786
+
+
+------------------------------- cut here ------------------------------
+*/
+
+/*
+
+Copyright 1991 by Mike Yang, mikey@sgi.com, Silicon Graphics, Inc.
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation, and that the name of SGI not be used in advertising or
+publicity pertaining to distribution of the software without specific,
+written prior permission. SGI makes no representations about the
+suitability of this software for any purpose. It is provided "as is"
+without express or implied warranty.
+
+*/
+
+/*
+ * wxAdoptedWindow
+ */
+
+wxAdoptedWindow::wxAdoptedWindow()
+{
+}
+
+wxAdoptedWindow::wxAdoptedWindow(WXWindow window)
+{
+ m_mainWidget = window;
+}
+
+wxAdoptedWindow::~wxAdoptedWindow()
+{
+}
+/*
+ * wxReparenter
+ */
+
+static bool Xerror;
+static Atom WM_STATE = 0;
+bool wxReparenter::sm_done = FALSE;
+wxAdoptedWindow* wxReparenter::sm_toReparent = NULL;
+wxWindow* wxReparenter::sm_newParent = NULL;
+wxString wxReparenter::sm_name;
+bool wxReparenter::sm_exactMatch = FALSE;
+
+static int
+ErrorHandler(Display* dpy, XErrorEvent* event)
+{
+ Xerror = True;
+ return False;
+}
+
+// We assume that toReparent has had its X window set
+// appropriately.
+bool wxReparenter::Reparent(wxWindow* newParent, wxAdoptedWindow* toReparent)
+{
+ XWindowAttributes xwa;
+ Window *children;
+ unsigned int numchildren, each;
+ Window returnroot, returnparent;
+ XErrorHandler old;
+ int parentOffset = 0;
+
+ old = XSetErrorHandler(ErrorHandler);
+ XReparentWindow((Display*) newParent->GetXDisplay(),
+ (Window) toReparent->GetXWindow(),
+ (Window) newParent->GetXWindow(),
+ 0, 0);
+
+ if (!XQueryTree((Display*) newParent->GetXDisplay(),
+ (Window) toReparent->GetXWindow(),
+ &returnroot, &returnparent,
+ &children, &numchildren) || Xerror)
+ {
+ XSetErrorHandler(old);
+ return TRUE;
+ }
+
+ if (numchildren > 0)
+ {
+ fprintf(stderr, "Reparenting %d children.\n", numchildren);
+ /* Stacking order is preserved since XQueryTree returns its children in
+ bottommost to topmost order
+ */
+ for (each=0; each<numchildren; each++)
+ {
+ XGetWindowAttributes((Display*) newParent->GetXDisplay(),
+ children[each], &xwa);
+ fprintf(stderr,
+ "Reparenting child at offset %d and position %d, %d.\n",
+ parentOffset, parentOffset+xwa.x, parentOffset+xwa.y);
+ XReparentWindow((Display*) newParent->GetXDisplay(),
+ children[each], (Window) newParent->GetXWindow(),
+ xwa.x, xwa.y);
+ }
+ }
+
+ XSetErrorHandler(old);
+ return TRUE;
+}
+
+// Wait for an appropriate window to be created.
+// If exactMatch is FALSE, a substring match is OK.
+// If windowName is empty, then wait for the next overrideRedirect window.
+bool wxReparenter::WaitAndReparent(wxWindow* newParent, wxAdoptedWindow* toReparent,
+ const wxString& windowName,
+ bool exactMatch)
+{
+ sm_newParent = newParent;
+ sm_toReparent = toReparent;
+ sm_exactMatch = exactMatch;
+ sm_name = windowName;
+
+ Display* display = (Display*) newParent->GetXDisplay() ;
+ XSelectInput(display,
+ RootWindowOfScreen(DefaultScreenOfDisplay(display)),
+ SubstructureNotifyMask);
+
+ if (!WM_STATE)
+ WM_STATE = XInternAtom(display, "WM_STATE", False);
+
+#ifdef __WXDEBUG__
+ if (!windowName.IsEmpty())
+ wxLogDebug(_T("Waiting for window %s"), windowName.c_str());
+#endif
+
+ sm_done = FALSE;
+
+ wxEventLoop eventLoop;
+ while (!sm_done)
+ {
+ if (eventLoop.Pending())
+ {
+ XEvent xevent;
+ XNextEvent(display, & xevent);
+ if (!wxTheApp->ProcessXEvent((WXEvent*) & xevent))
+ {
+ // Do the local event processing
+ ProcessXEvent((WXEvent*) & xevent);
+ }
+ }
+ else
+ {
+#if wxUSE_TIMER
+ wxTimer::NotifyTimers();
+ wxTheApp->SendIdleEvents();
+#endif
+ }
+ }
+ return TRUE;
+}
+
+bool wxReparenter::ProcessXEvent(WXEvent* event)
+{
+ XEvent* xevent = (XEvent*) event;
+ Window client;
+
+ if (!sm_done)
+ {
+ if (xevent->type == MapNotify)
+ {
+ wxLogDebug(_T("Window was mapped"));
+ }
+
+ if (xevent->type == MapNotify && !xevent->xmap.override_redirect &&
+ (client = (Window) FindAClientWindow((WXWindow) xevent->xmap.window, sm_name)))
+ {
+ wxLogDebug(_T("Found a client window, about to reparent"));
+ wxASSERT(sm_toReparent->GetParent() == NULL);
+
+ sm_toReparent->SetHandle((WXWindow) client);
+ sm_newParent->AddChild(sm_toReparent);
+ sm_done = Reparent(sm_newParent, sm_toReparent);
+ return sm_done;
+ } else if (xevent->type == MapNotify &&
+ xevent->xmap.override_redirect &&
+ xevent->xmap.window)
+ {
+ wxLogDebug(_T("Found an override redirect window, about to reparent"));
+ sm_toReparent->SetHandle((WXWindow) xevent->xmap.window);
+ sm_newParent->AddChild(sm_toReparent);
+ wxASSERT(sm_toReparent->GetParent() == NULL);
+
+ sm_done = Reparent(sm_newParent, sm_toReparent);
+ return sm_done;
+ }
+ }
+ return FALSE;
+}
+
+WXWindow wxReparenter::FindAClientWindow(WXWindow window, const wxString& name)
+{
+ int rvalue, i;
+ Atom actualtype;
+ int actualformat;
+ unsigned long nitems, bytesafter;
+ unsigned char *propreturn;
+ Window *children;
+ unsigned int numchildren;
+ Window returnroot, returnparent;
+ Window result = 0;
+ XErrorHandler old;
+ char *clientName;
+
+ Xerror = False;
+ old = XSetErrorHandler(ErrorHandler);
+ rvalue = XGetWindowProperty((Display*) wxGetDisplay(),
+ (Window) window, WM_STATE,
+ 0, 1, False,
+ AnyPropertyType, &actualtype, &actualformat,
+ &nitems, &bytesafter, &propreturn);
+ XSetErrorHandler(old);
+ if (!Xerror && rvalue == Success && actualtype != None)
+ {
+ if (rvalue == Success)
+ {
+ XFree((char *) propreturn);
+ }
+ XFetchName((Display*) wxGetDisplay(), (Window) window, &clientName);
+
+ wxString str1(name);
+ wxString str2(clientName);
+ str1.Lower();
+ str2.Lower();
+
+ bool matches;
+ if (sm_exactMatch)
+ matches = (name == clientName);
+ else
+ matches = (str1.Contains(str2) || str2.Contains(str1));
+
+ XFree(clientName);
+
+ if (matches)
+ return (WXWindow) window;
+ else
+ return NULL;
+ }
+
+ old = XSetErrorHandler(ErrorHandler);
+ if (!XQueryTree((Display*) wxGetDisplay(), (Window) window, &returnroot, &returnparent,
+ &children, &numchildren) || Xerror) {
+ XSetErrorHandler(old);
+ return NULL;
+ }
+ XSetErrorHandler(old);
+
+ result = 0;
+ for (i=0; i<(int)numchildren && !result ;i++) {
+ result = (Window) FindAClientWindow((WXWindow) children[i], name);
+ }
+ if (numchildren) {
+ XFree((char *) children);
+ } return (WXWindow) result;
+}
+