diff options
Diffstat (limited to 'vcl/unx/source/window')
-rw-r--r-- | vcl/unx/source/window/FWS.cxx | 314 | ||||
-rw-r--r-- | vcl/unx/source/window/FWS.hxx | 98 | ||||
-rw-r--r-- | vcl/unx/source/window/makefile.mk | 97 | ||||
-rw-r--r-- | vcl/unx/source/window/salframe.cxx | 2614 | ||||
-rw-r--r-- | vcl/unx/source/window/salobj.cxx | 447 |
5 files changed, 3570 insertions, 0 deletions
diff --git a/vcl/unx/source/window/FWS.cxx b/vcl/unx/source/window/FWS.cxx new file mode 100644 index 000000000000..3e340b104145 --- /dev/null +++ b/vcl/unx/source/window/FWS.cxx @@ -0,0 +1,314 @@ +/************************************************************************* + * + * $RCSfile: FWS.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 17:05:48 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#include <X11/Xlib.h> +#include <X11/Xutil.h> +#include <X11/Xatom.h> + +#ifndef _FOREIGN_WINDOW_SYSTEM_HXX +#include "FWS.hxx" +#endif + +static Atom fwsIconAtom; + +static Atom FWS_CLIENT; +static Atom FWS_COMM_WINDOW; +static Atom FWS_PROTOCOLS; +static Atom FWS_STACK_UNDER; +static Atom FWS_PARK_ICONS; +static Atom FWS_PASS_ALL_INPUT; +static Atom FWS_PASSES_INPUT; +static Atom FWS_HANDLES_FOCUS; + +static Atom FWS_REGISTER_WINDOW; +static Atom FWS_STATE_CHANGE; +static Atom FWS_UNSEEN_STATE; +static Atom FWS_NORMAL_STATE; +static Atom WM_PROTOCOLS; +static Atom WM_CHANGE_STATE; + +static Bool fwsStackUnder; +static Bool fwsParkIcons; +static Bool fwsPassesInput; +static Bool fwsHandlesFocus; + +static Window fwsCommWindow; + +/*************************************<->*********************************** + * + * WMSupportsFWS() - + * + * Initialize our atoms and determine if the current window manager is + * providing FWS extension support. + * + *************************************<->***********************************/ + +Bool +WMSupportsFWS (Display *display, int screen) +{ + int i; + Atom protocol; + Atom propType; + int propFormat; + unsigned long propItems; + unsigned long propBytesAfter; + unsigned char *propData; + char propName[30]; + + FWS_CLIENT = XInternAtom(display, "_SUN_FWS_CLIENT", False); + FWS_COMM_WINDOW = XInternAtom(display, "_SUN_FWS_COMM_WINDOW", False); + FWS_PROTOCOLS = XInternAtom(display, "_SUN_FWS_PROTOCOLS", False); + FWS_STACK_UNDER = XInternAtom(display, "_SUN_FWS_STACK_UNDER", False); + FWS_PARK_ICONS = XInternAtom(display, "_SUN_FWS_PARK_ICONS", False); + FWS_PASS_ALL_INPUT = XInternAtom(display, "_SUN_FWS_PASS_ALL_INPUT", False); + FWS_PASSES_INPUT = XInternAtom(display, "_SUN_FWS_PASSES_INPUT", False); + FWS_HANDLES_FOCUS = XInternAtom(display, "_SUN_FWS_HANDLES_FOCUS", False); + FWS_REGISTER_WINDOW= XInternAtom(display, "_SUN_FWS_REGISTER_WINDOW",False); + FWS_STATE_CHANGE = XInternAtom(display, "_SUN_FWS_STATE_CHANGE", False); + FWS_UNSEEN_STATE = XInternAtom(display, "_SUN_FWS_UNSEEN_STATE", False); + FWS_NORMAL_STATE = XInternAtom(display, "_SUN_FWS_NORMAL_STATE", False); + WM_PROTOCOLS = XInternAtom(display, "WM_PROTOCOLS", False); + WM_CHANGE_STATE = XInternAtom(display, "WM_CHANGE_STATE", False); + + sprintf (propName, "_SUN_FWS_NEXT_ICON_%d", screen); + fwsIconAtom = XInternAtom(display, propName, False); + + if (XGetWindowProperty (display, DefaultRootWindow (display), + FWS_COMM_WINDOW, 0, 1, + False, AnyPropertyType, &propType, + &propFormat, &propItems, + &propBytesAfter, &propData) != Success) + return False; + + if (propFormat != 32 || + propItems != 1 || + propBytesAfter != 0) + { + #ifdef DEBUG + fprintf (stderr, "Bad FWS_COMM_WINDOW property on root window.\n"); + #endif + XFree (propData); + return False; + } + + fwsCommWindow = *(Window *) propData; + #ifdef DEBUG + fprintf (stderr, "Using fwsCommWindow = 0x%lx.\n", fwsCommWindow); + #endif + XFree (propData); + + + if (XGetWindowProperty (display, DefaultRootWindow (display), + FWS_PROTOCOLS, 0, 10, + False, AnyPropertyType, &propType, + &propFormat, &propItems, + &propBytesAfter, &propData) != Success) + { + return False; + } + + if (propFormat != 32 || + propBytesAfter != 0) + { + #ifdef DEBUG + fprintf (stderr, "Bad FWS_PROTOCOLS property on root window.\n"); + #endif + XFree (propData); + return False; + } + + for (i = 0; i < propItems; ++i) + { + protocol = ((Atom *) propData)[i]; + if (protocol == FWS_STACK_UNDER) + { + fwsStackUnder = True; + #ifdef DEBUG + fprintf (stderr, "Using fwsStackUnder.\n"); + #endif + } + else + if (protocol == FWS_PARK_ICONS) + { + fwsParkIcons = True; + #ifdef DEBUG + fprintf (stderr, "Using fwsParkIcons.\n"); + #endif + } + else + if (protocol == FWS_PASSES_INPUT) + { + fwsPassesInput = True; + #ifdef DEBUG + fprintf (stderr, "Using fwsPassesInput.\n"); + #endif + } + else + if (protocol == FWS_HANDLES_FOCUS) + { + fwsHandlesFocus = True; + #ifdef DEBUG + fprintf (stderr, "Using fwsHandlesFocus.\n"); + #endif + } + } + + XFree (propData); + return True; +} + +/*************************************<->*********************************** + * + * newHandler() - + * + * Handle X errors (temporarily) to record the occurance of BadWindow + * errors without crashing. Used to detect the FWS_COMM_WINDOW root window + * property containing an old or obsolete window id. + * + *************************************<->***********************************/ + +extern "C" { + +static Bool badWindowFound; +static int (* oldHandler) (Display *, XErrorEvent *); + +static int +newHandler (Display *display, XErrorEvent *xerror) +{ + if (xerror->error_code != BadWindow) + (*oldHandler)(display, xerror); + else + badWindowFound = True; + + return 0; +} + +} + +/*************************************<->*********************************** + * + * RegisterFwsWindow() - + * + * Send a client message to the FWS_COMM_WINDOW indicating the existance + * of a new FWS client window. Be careful to avoid BadWindow errors on + * the XSendEvent in case the FWS_COMM_WINDOW root window property had + * old/obsolete junk in it. + * + *************************************<->***********************************/ + +Bool +RegisterFwsWindow (Display *display, Window window) +{ + XClientMessageEvent msg; + + msg.type = ClientMessage; + msg.window = fwsCommWindow; + msg.message_type = FWS_REGISTER_WINDOW; + msg.format = 32; + msg.data.l[0] = window; + + XSync (display, False); + badWindowFound = False; + oldHandler = XSetErrorHandler (newHandler); + + XSendEvent (display, fwsCommWindow, False, NoEventMask, + (XEvent *) &msg); + XSync (display, False); + + XSetErrorHandler (oldHandler); + #ifdef DEBUG + if (badWindowFound) + fprintf (stderr, "No FWS client window to register with.\n"); + #endif + + return !badWindowFound; +} + +/*************************************<->*********************************** + * + * AddFwsProtocols - + * + * Add the FWS protocol atoms to the WMProtocols property for the window. + * + *************************************<->***********************************/ + +void +AddFwsProtocols (Display *display, Window window) +{ + #define MAX_FWS_PROTOS 10 + + Atom fwsProtocols[ MAX_FWS_PROTOS ]; + int nProtos = 0; + + fwsProtocols[ nProtos++ ] = FWS_CLIENT; + fwsProtocols[ nProtos++ ] = FWS_STACK_UNDER; + fwsProtocols[ nProtos++ ] = FWS_STATE_CHANGE; + fwsProtocols[ nProtos++ ] = FWS_PASS_ALL_INPUT; + XChangeProperty (display, window, WM_PROTOCOLS, + XA_ATOM, 32, PropModeAppend, + (unsigned char *) fwsProtocols, nProtos); +} + diff --git a/vcl/unx/source/window/FWS.hxx b/vcl/unx/source/window/FWS.hxx new file mode 100644 index 000000000000..b70997ff7c96 --- /dev/null +++ b/vcl/unx/source/window/FWS.hxx @@ -0,0 +1,98 @@ +/************************************************************************* + * + * $RCSfile: FWS.hxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 17:05:48 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#ifndef _FOREIGN_WINDOW_SYSTEM_HXX +#define _FOREIGN_WINDOW_SYSTEM_HXX + +#include <X11/Xlib.h> + +#if defined(__cplusplus) +extern "C" { +#endif + +/* Initialize our atoms and determine if the current window manager is + * providing FWS extension support. + */ + +Bool +WMSupportsFWS (Display *display, int screen); + +/* Send a client message to the FWS_COMM_WINDOW indicating the existance + * of a new FWS client window. Be careful to avoid BadWindow errors on + * the XSendEvent in case the FWS_COMM_WINDOW root window property had + * old/obsolete junk in it. + */ + +Bool +RegisterFwsWindow (Display *display, Window window); + +/* Add the FWS protocol atoms to the WMProtocols property for the window. + */ + +void +AddFwsProtocols (Display *display, Window window); + +#if defined(__cplusplus) +} /* extern "C" */ +#endif + +#endif _FOREIGN_WINDOW_SYSTEM_HXX + diff --git a/vcl/unx/source/window/makefile.mk b/vcl/unx/source/window/makefile.mk new file mode 100644 index 000000000000..69d4cf6196dd --- /dev/null +++ b/vcl/unx/source/window/makefile.mk @@ -0,0 +1,97 @@ +#************************************************************************* +# +# $RCSfile: makefile.mk,v $ +# +# $Revision: 1.1.1.1 $ +# +# last change: $Author: hr $ $Date: 2000-09-18 17:05:48 $ +# +# The Contents of this file are made available subject to the terms of +# either of the following licenses +# +# - GNU Lesser General Public License Version 2.1 +# - Sun Industry Standards Source License Version 1.1 +# +# Sun Microsystems Inc., October, 2000 +# +# GNU Lesser General Public License Version 2.1 +# ============================================= +# Copyright 2000 by Sun Microsystems, Inc. +# 901 San Antonio Road, Palo Alto, CA 94303, USA +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License version 2.1, as published by the Free Software Foundation. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# +# +# Sun Industry Standards Source License Version 1.1 +# ================================================= +# The contents of this file are subject to the Sun Industry Standards +# Source License Version 1.1 (the "License"); You may not use this file +# except in compliance with the License. You may obtain a copy of the +# License at http://www.openoffice.org/license.html. +# +# Software provided under this License is provided on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, +# WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, +# MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. +# See the License for the specific provisions governing your rights and +# obligations concerning the Software. +# +# The Initial Developer of the Original Code is: Sun Microsystems, Inc. +# +# Copyright: 2000 by Sun Microsystems, Inc. +# +# All Rights Reserved. +# +# Contributor(s): _______________________________________ +# +# +# +#************************************************************************* + +PRJ=..$/..$/.. + +PRJNAME=vcl +TARGET=salwin +.INCLUDE : $(PRJ)$/util$/makefile.pmk + +ENABLE_EXCEPTIONS=TRUE + +# --- Settings ----------------------------------------------------- + +.INCLUDE : svpre.mk +.INCLUDE : settings.mk +.INCLUDE : sv.mk + +# --- Files -------------------------------------------------------- + +.IF "$(OS)"=="MACOSX" + +dummy: + @echo "Nothing to build for Mac OS X" + +.ELSE # "$(OS)"=="MACOSX" + +.IF "$(remote)" +SLOFILES= \ + $(SLO)/FWS.obj $(SLO)/salframe.obj $(SLO)/salobj.obj +.ENDIF + +.ENDIF # "$(OS)"=="MACOSX" + +# --- Targets ------------------------------------------------------ + +.INCLUDE : target.mk + +.INCLUDE : $(PRJ)$/util$/target.pmk diff --git a/vcl/unx/source/window/salframe.cxx b/vcl/unx/source/window/salframe.cxx new file mode 100644 index 000000000000..bde3233e1699 --- /dev/null +++ b/vcl/unx/source/window/salframe.cxx @@ -0,0 +1,2614 @@ +/************************************************************************* + * + * $RCSfile: salframe.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 17:05:48 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#define _SV_SALFRAME_CXX + +// -=-= #includes =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +#include <string.h> +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <alloca.h> + +#include <prex.h> +#include <X11/Xatom.h> +#include <X11/keysym.h> + +#ifndef _FOREIGN_WINDOW_SYSTEM_HXX +#include "FWS.hxx" +#endif + +#include <postx.h> + +#include <salunx.h> + +#ifndef _TOOLS_DEBUG_HXX +#include <tools/debug.hxx> +#endif +#ifndef _SV_SALDATA_HXX +#include <saldata.hxx> +#endif +#ifndef _SV_SALDISP_HXX +#include <saldisp.hxx> +#endif +#ifndef _SV_SALINST_HXX +#include <salinst.hxx> +#endif +#ifndef _SV_SALGDI_HXX +#include <salgdi.hxx> +#endif +#ifndef _SV_SALFRAME_HXX +#include <salframe.hxx> +#endif +#ifndef _SV_KEYCOES_HXX +#include <keycodes.hxx> +#endif +#ifndef _SV_SOICON_HXX +#include <soicon.hxx> +#endif +#ifndef _SV_SYSDATA_HXX +#include <sysdata.hxx> +#endif +#ifndef _SV_DTINT_HXX +#include <dtint.hxx> +#endif +#ifndef _VCL_SM_HXX +#include <sm.hxx> +#endif +#ifndef _SV_SETTINGS_HXX +#include <settings.hxx> +#endif + +#include <svapp.hxx> + +#ifndef _SAL_I18N_INPUTCONTEXT_HXX +#include "i18n_ic.hxx" +#endif + +// -=-= #defines -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +#define SHOWSTATE_UNKNOWN -1 +#define SHOWSTATE_MINIMIZED 0 +#define SHOWSTATE_NORMAL 1 + +// | KeymapStateMask +#define CLIENT_EVENTS StructureNotifyMask \ + | SubstructureNotifyMask \ + | KeyPressMask \ + | KeyReleaseMask \ + | ButtonPressMask \ + | ButtonReleaseMask \ + | PointerMotionMask \ + | EnterWindowMask \ + | LeaveWindowMask \ + | FocusChangeMask \ + | ExposureMask \ + | VisibilityChangeMask \ + | PropertyChangeMask \ + | ColormapChangeMask + +// | ButtonPressMask | ButtonRelaseMask +//#define NC_EVENTS KeyPressMask \ +// | KeyReleaseMask \ +// | PointerMotionMask \ +// | EnterWindowMask \ +// | LeaveWindowMask \ +// | ExposureMask + +// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +#define _GetDrawable() maFrameData.GetDrawable() +#define _GetDisplay() maFrameData.pDisplay_ +#define _GetXDisplay() maFrameData.GetXDisplay() +#define _GetColormap() maFrameData.GetColormap() +#define _GetPaintRegion() maFrameData.GetPaintRegion() +#define _GetStyle() maFrameData.nStyle_ +#define _IsMapped() maFrameData.bMapped_ + +// -=-= C++ statics =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +static long sal_CallbackDummy( void*, SalFrame*, USHORT, const void* ) +{ return 0; } + +// -=-= SalInstance =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +SalFrame *SalInstance::CreateFrame( SalFrame *pParent, + ULONG nSalFrameStyle ) +{ + SalFrame *pFrame = new SalFrame; + + pFrame->maFrameData.mpParent = pParent; + if( pParent ) + pParent->maFrameData.maChildren.Insert( pFrame ); + pFrame->maFrameData.Init( nSalFrameStyle ); + + return pFrame; +} + +SalFrame* SalInstance::CreateChildFrame( SystemParentData* pParentData, ULONG nStyle ) +{ + SalFrame* pFrame = new SalFrame; + pFrame->maFrameData.mpParent = NULL; + pFrame->maFrameData.Init( nStyle, pParentData ); + + return pFrame; +} + +void SalInstance::DestroyFrame( SalFrame* pFrame ) +{ + delete pFrame; +} + +// -=-= SalGraphics / SalGraphicsData =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +void SalGraphicsData::Init( SalFrame *pFrame ) +{ + xColormap_ = &pFrame->_GetColormap(); + hDrawable_ = pFrame->_GetDrawable(); + + bWindow_ = TRUE; + + nPenPixel_ = GetPixel( nPenColor_ ); + nTextPixel_ = GetPixel( nTextColor_ ); + nBrushPixel_ = GetPixel( nBrushColor_ ); +} + +// -=-= SalFrame / SalFrameData =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +void SalFrameData::Init( USHORT nSalFrameStyle, SystemParentData* pParentData ) +{ + nStyle_ = nSalFrameStyle; + + XWMHints Hints; + Hints.flags = 0; + + if( nSalFrameStyle & SAL_FRAME_STYLE_DEFAULT ) + { + hShell_ = pDisplay_->GetShellWidget(); + hComposite_ = pDisplay_->GetWidget(); + + XSelectInput( GetXDisplay(), XtWindow( hShell_ ), CLIENT_EVENTS ); + XSelectInput( GetXDisplay(), XtWindow( hComposite_ ), CLIENT_EVENTS ); + + Hints.flags |= InputHint|IconPixmapHint; + Hints.input = True; + Hints.icon_pixmap = GetAppIconPixmap( pDisplay_ ); + Hints.icon_mask = GetAppIconMask( pDisplay_ ); + if( Hints.icon_mask ) + Hints.flags |= IconMaskHint; + } + else if( nSalFrameStyle & SAL_FRAME_STYLE_FLOAT ) + { + Arg aArgs[10]; + int nArgs = 0; + + SalVisual* pVis = GetDisplay()->GetVisual(); + XtSetArg( aArgs[nArgs], XtNvisual, pVis->GetVisual() ); nArgs++; + XtSetArg( aArgs[nArgs], XtNdepth, pVis->GetDepth() ); nArgs++; + XtSetArg( aArgs[nArgs], XtNcolormap, + GetDisplay()->GetColormap().GetXColormap() ); nArgs++; + XtSetArg( aArgs[nArgs], XtNwidth, 10 ); nArgs++; + XtSetArg( aArgs[nArgs], XtNheight, 10 ); nArgs++; + + hShell_ = XtAppCreateShell( NULL, NULL, + overrideShellWidgetClass, + pDisplay_->GetDisplay(), + aArgs, nArgs ); + + XtSetMappedWhenManaged( hShell_, FALSE ); + XtRealizeWidget( hShell_ ); + + hComposite_ = XtVaCreateManagedWidget( + "ShellComposite", + SAL_COMPOSITE_WIDGET, + hShell_, + NULL ); + XtRealizeWidget( hComposite_ ); +#ifdef DEBUG + fprintf( stderr, "created new FLOAT style shell\n" ); +#endif + } + else if( nSalFrameStyle & SAL_FRAME_STYLE_CHILD && pParentData ) + { + int x_ret, y_ret; + unsigned int w, h, bw, d; + XLIB_Window aRoot; + XLIB_Window aParent; + + XGetGeometry( GetDisplay()->GetDisplay(), pParentData->aWindow, + &aRoot, &x_ret, &y_ret, &w, &h, &bw, &d ); + + Arg aArgs[10]; + int nArgs = 0; + + SalVisual* pVis = GetDisplay()->GetVisual(); + XtSetArg( aArgs[nArgs], XtNvisual, pVis->GetVisual() ); nArgs++; + XtSetArg( aArgs[nArgs], XtNdepth, pVis->GetDepth() ); nArgs++; + XtSetArg( aArgs[nArgs], XtNcolormap, + GetDisplay()->GetColormap().GetXColormap() ); nArgs++; + XtSetArg( aArgs[nArgs], XtNwidth, w ); nArgs++; + XtSetArg( aArgs[nArgs], XtNheight, h ); nArgs++; + + hShell_ = XtAppCreateShell( NULL, NULL, + overrideShellWidgetClass, + pDisplay_->GetDisplay(), + aArgs, nArgs ); + + XtSetMappedWhenManaged( hShell_, FALSE ); + XtRealizeWidget( hShell_ ); + + XEvent aEvent; + XReparentWindow( GetDisplay()->GetDisplay(), XtWindow( hShell_ ), + pParentData->aWindow, 0, 0 ); + GetDisplay()->GetXLib()->SetIgnoreXErrors( TRUE ); // hack for plugin + XSync( GetDisplay()->GetDisplay(), False ); + + while( ! XCheckTypedWindowEvent( GetDisplay()->GetDisplay(), + XtWindow( hShell_ ), + ReparentNotify, + &aEvent ) ) + { + usleep(10000); + } + + hComposite_ = XtVaCreateManagedWidget( + "ShellComposite", + SAL_COMPOSITE_WIDGET, + hShell_, + NULL ); + XtRealizeWidget( hComposite_ ); + + hForeignParent_ = pParentData->aWindow; + // get foreign top level window + // we need the ConfigureNotifies of this window + // to update the positions of this frame's children of + // type SAL_FRAME_STYLE_FLOAT + aParent = hForeignParent_; + hForeignTopLevelWindow_ = hForeignParent_; + XLIB_Window* pChildren; + unsigned int nChildren; + do + { + XQueryTree( GetDisplay()->GetDisplay(), hForeignTopLevelWindow_, + &aRoot, &aParent, &pChildren, &nChildren ); + XFree( pChildren ); + if( aParent != aRoot ) + hForeignTopLevelWindow_ = aParent; + } while( aParent != aRoot ); + + // check if this is really one of our own frames + // do not change the input mask in that case + SalFrame* pFrame = GetSalData()->pFirstFrame_; + while( pFrame && + hForeignParent_ != pFrame->maFrameData.GetWindow() && + hForeignParent_ != pFrame->maFrameData.GetShellWindow() ) + pFrame = pFrame->maFrameData.pNextFrame_; + + if( ! pFrame ) + { + XSelectInput( GetDisplay()->GetDisplay(), hForeignParent_, StructureNotifyMask ); + XSelectInput( GetDisplay()->GetDisplay(), hForeignTopLevelWindow_, StructureNotifyMask ); + } + + SetPosSize( Rectangle( Point( 0, 0 ), Size( w, h ) ) ); + } + else + { + SalVisual *pVisual = pDisplay_->GetVisual(); + + int w = 500; + int h = 400; + if( pDisplay_->GetProperties() & PROPERTY_FEATURE_Maximize ) + { + w = pDisplay_->GetScreenSize().Width(); + h = pDisplay_->GetScreenSize().Height(); + } + + Arg aArgs[10]; + int nArgs=0; + SalVisual* pVis = GetDisplay()->GetVisual(); + XtSetArg( aArgs[nArgs], XtNvisual, pVis->GetVisual() ); nArgs++; + XtSetArg( aArgs[nArgs], XtNdepth, pVis->GetDepth() ); nArgs++; + XtSetArg( aArgs[nArgs], XtNcolormap, + GetDisplay()->GetColormap().GetXColormap() ); nArgs++; + XtSetArg( aArgs[nArgs], XtNwidth, w ); nArgs++; + XtSetArg( aArgs[nArgs], XtNheight, h ); nArgs++; + if( mpParent ) + XtSetArg( aArgs[nArgs], XtNtransientFor, mpParent->maFrameData.GetShellWidget() ), nArgs++; + if( ! ( nStyle_ & ~SAL_FRAME_STYLE_DEFAULT ) ) + { + XtSetArg( aArgs[nArgs], XtNoverrideRedirect, True ); nArgs++; + } + + hShell_ = XtAppCreateShell( "", "VCLSalFrame", + mpParent + ? transientShellWidgetClass : + applicationShellWidgetClass, + GetXDisplay(), + aArgs, nArgs ); + + // X-Window erzeugen + XtSetMappedWhenManaged( hShell_, FALSE ); + XtRealizeWidget( hShell_ ); + + hComposite_ = XtVaCreateManagedWidget( + "ShellComposite", + SAL_COMPOSITE_WIDGET, + hShell_, + NULL ); + XtRealizeWidget( hComposite_ ); + + XWMHints *pHints = XGetWMHints( GetXDisplay(), + pDisplay_->GetWindow() ); + + if( pHints + && pHints->flags & IconMaskHint + && pHints->flags & IconPixmapHint ) + { + Hints.flags |= IconMaskHint|IconPixmapHint; + Hints.icon_pixmap = pHints->icon_pixmap; + Hints.icon_mask = pHints->icon_mask; + XFree( pHints ); + } + else + { + Hints.flags |= IconPixmapHint; + Hints.icon_pixmap = GetAppIconPixmap( pDisplay_ ); + Hints.icon_mask = GetAppIconMask( pDisplay_ ); + if( Hints.icon_mask ) + Hints.flags |= IconMaskHint; + } + + Hints.flags |= WindowGroupHint; + Hints.window_group = pDisplay_->GetShellWindow(); + + } + + if( hShell_ ) + XSetWindowBackgroundPixmap( pDisplay_->GetDisplay(), XtWindow( hShell_ ), None ); + if( hComposite_ ) + XSetWindowBackgroundPixmap( pDisplay_->GetDisplay(), XtWindow( hComposite_ ), None ); + + if( ! ( nSalFrameStyle & SAL_FRAME_STYLE_CHILD && pParentData ) ) + { + XSetWMHints( GetXDisplay(), XtWindow( hShell_ ), &Hints ); + + + // WM Protocols && internals + Atom a[4]; + int n = 0; + + a[n++] = pDisplay_->GetICCCM().aWM_DeleteWindow_; + a[n++] = pDisplay_->GetICCCM().aWM_SaveYourself_; + + XSetWMProtocols( GetXDisplay(), XtWindow( hShell_ ), a, n ); + } + + // Pointer + pFrame_->SetPointer( POINTER_ARROW ); + + // Setup for use of InputMethod + if ( nSalFrameStyle & SAL_FRAME_STYLE_MOVEABLE + && nSalFrameStyle & SAL_FRAME_STYLE_SIZEABLE ) + { + mpInputContext = new SalI18N_InputContext( pFrame_ ); + if ( mpInputContext->UseContext() ) + { + mpInputContext->ExtendEventMask( XtWindow( hShell_ ) ); + mpInputContext->Unmap(); + } + } + else + { + mpInputContext = NULL; + } +} + +// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +inline SalFrameData::SalFrameData( SalFrame *pFrame ) +{ + SalData* pSalData = GetSalData(); + + // insert frame in framelist + pNextFrame_ = pSalData->pFirstFrame_; + pSalData->pFirstFrame_ = pFrame; + pFrame_ = pFrame; + + pProc_ = sal_CallbackDummy; + pInst_ = (void*)ILLEGAL_POINTER; + + pDisplay_ = pSalData->GetCurDisp(); + hShell_ = NULL; + hComposite_ = NULL; + hForeignParent_ = None; + hNoFullscreenShell_ = NULL; + hNoFullscreenComposite_ = NULL; + + pGraphics_ = NULL; + pFreeGraphics_ = NULL; + pPaintRegion_ = NULL; + + hCursor_ = None; + nCaptured_ = 0; + + nReleaseTime_ = 0; + nKeyCode_ = 0; + nKeyState_ = 0; + nCompose_ = -1; + + nShowState_ = SHOWSTATE_UNKNOWN; + nLeft_ = 0; + nTop_ = 0; + nRight_ = 0; + nBottom_ = 0; + nMaxWidth_ = 0; + nMaxHeight_ = 0; + nWidth_ = 0; + nHeight_ = 0; + nStyle_ = 0; + bAlwaysOnTop_ = FALSE; + // #58928# fake to be mapped on startup, because the sclient may be + // resized before mapping and the + // SetPosSize / call(salevent_resize) / GetClientSize + // stuff will not work in that (unmapped) case + bViewable_ = TRUE; + bMapped_ = FALSE; + bDefaultPosition_ = TRUE; + nVisibility_ = VisibilityFullyObscured; + + nScreenSaversTimeout_ = 0; + + mpInputContext = NULL; +} + +SalFrame::SalFrame() : maFrameData( this ) {} + +// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +inline SalFrameData::~SalFrameData() +{ + if ( mpInputContext != NULL ) + delete mpInputContext; + + if( pGraphics_ ) + { + stderr0( "SalFrameData::~SalFrameData pGraphics_\n" ); + pGraphics_->maGraphicsData.DeInit(); + delete pGraphics_; + } + + if( pFreeGraphics_ ) + { + pFreeGraphics_->maGraphicsData.DeInit(); + delete pFreeGraphics_; + } + + if( hShell_ != pDisplay_->GetWidget() ) + XtDestroyWidget( hShell_ ); + + SalData* pSalData = GetSalData(); + + if( pFrame_ == pSalData->pFirstFrame_ ) + pSalData->pFirstFrame_ = GetNextFrame(); + else + { + SalFrameData *pTemp = &pSalData->pFirstFrame_->maFrameData; + while( pTemp->GetNextFrame() != pFrame_ ) + pTemp = &pTemp->GetNextFrame()->maFrameData; + + pTemp->pNextFrame_ = GetNextFrame(); + } +} + +SalFrame::~SalFrame() +{ + // aus papis child liste entfernen + if( maFrameData.mpParent ) + maFrameData.mpParent->maFrameData.maChildren.Remove( this ); + // einige kommen trotzdem immer noch durch + XSelectInput( _GetXDisplay(), maFrameData.GetShellWindow(), 0 ); + XSelectInput( _GetXDisplay(), maFrameData.GetWindow(), 0 ); + + ShowFullScreen( FALSE ); + + if( _IsMapped() ) + Show( FALSE ); +} + +// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +// irgendwann auf Liste umstellen + +const SystemChildData* SalFrame::GetSystemData() const +{ + SalFrame *pFrame = const_cast<SalFrame*>(this); + pFrame->maFrameData.maSystemChildData.nSize = sizeof( SystemChildData ); + pFrame->maFrameData.maSystemChildData.pDisplay = _GetXDisplay(); + pFrame->maFrameData.maSystemChildData.aWindow = pFrame->maFrameData.GetWindow(); + pFrame->maFrameData.maSystemChildData.pSalFrame = pFrame; + pFrame->maFrameData.maSystemChildData.pWidget = pFrame->maFrameData.GetWidget(); + pFrame->maFrameData.maSystemChildData.pVisual = _GetDisplay()->GetVisual()->GetVisual(); + pFrame->maFrameData.maSystemChildData.nDepth = _GetDisplay()->GetVisual()->GetDepth(); + pFrame->maFrameData.maSystemChildData.aColormap = _GetDisplay()->GetColormap().GetXColormap(); + pFrame->maFrameData.maSystemChildData.pAppContext = _GetDisplay()->GetXLib()->GetAppContext(); + return &maFrameData.maSystemChildData; +} + +SalGraphics *SalFrameData::GetGraphics() +{ + if( pGraphics_ ) + return NULL; + + if( pFreeGraphics_ ) + { + pGraphics_ = pFreeGraphics_; + pFreeGraphics_ = NULL; + } + else + { + pGraphics_ = new SalGraphics; + pGraphics_->maGraphicsData.Init( pFrame_ ); + } + + return pGraphics_; +} + +SalGraphics *SalFrame::GetGraphics() +{ return maFrameData.GetGraphics(); } + +void SalFrame::ReleaseGraphics( SalGraphics *pGraphics ) +{ + if( pGraphics != maFrameData.pGraphics_ ) + { + stderr0( "SalFrame::ReleaseGraphics pGraphics!=pGraphics_" ); + return; + } + + maFrameData.pFreeGraphics_ = pGraphics; + maFrameData.pGraphics_ = NULL; +} + +// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +void SalFrame::Enable( BOOL bEnable ) +{ + // NYI: enable/disable frame +} + +// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +void SalFrame::SetIcon( USHORT nIcon ) +{ + // NYI: set a specific icon +} + +// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +void SalFrame::SetMinClientSize( long nWidth, long nHeight ) +{ + if( maFrameData.hShell_ ) + { + Arg args[10]; + int n = 0; + XtSetArg( args[n++], XtNminWidth, nWidth ); + XtSetArg( args[n++], XtNminHeight, nHeight ); + XtSetValues( maFrameData.hShell_, args, n ); + } +} + +// Show + Pos (x,y,z) + Size (width,height) +// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +void SalFrame::Show( BOOL bVisible ) +{ + maFrameData.bMapped_ = bVisible; + maFrameData.bViewable_ = bVisible; + if( bVisible ) + { + if( maFrameData.nStyle_ & ( SAL_FRAME_STYLE_CHILD | SAL_FRAME_STYLE_FLOAT ) ) + XtPopup( maFrameData.hShell_, XtGrabNone ); + else + XtMapWidget( maFrameData.hShell_ ); + // Manch ein WM verschluckt Key Events im Fullscreenmode ... + XSelectInput( _GetXDisplay(), maFrameData.GetShellWindow(), CLIENT_EVENTS ); + XSelectInput( _GetXDisplay(), maFrameData.GetWindow(), CLIENT_EVENTS ); + + if( !maFrameData.aPosSize_.IsEmpty() + && (maFrameData.nWidth_ != maFrameData.aPosSize_.GetWidth() + || maFrameData.nHeight_ != maFrameData.aPosSize_.GetHeight()) ) + { + maFrameData.nWidth_ = maFrameData.aPosSize_.GetWidth(); + maFrameData.nHeight_ = maFrameData.aPosSize_.GetHeight(); + + maFrameData.Call( SALEVENT_RESIZE, NULL ); + } + + if( !_GetStyle() || maFrameData.hNoFullscreenShell_ ) + { + XSync( _GetXDisplay(), False ); + XSetInputFocus( _GetXDisplay(), maFrameData.GetShellWindow(), RevertToNone, CurrentTime ); + } + + XSync( _GetXDisplay(), False ); + maFrameData.Call( SALEVENT_RESIZE, NULL ); + } + else + { + if( maFrameData.nStyle_ & ( SAL_FRAME_STYLE_CHILD | SAL_FRAME_STYLE_FLOAT ) ) + XtPopdown( maFrameData.hShell_ ); + else + XtUnmapWidget( maFrameData.hShell_ ); + + if( !_GetStyle() || maFrameData.hNoFullscreenShell_ ) + { + SalFrameData *pTemp = &GetSalData()->pFirstFrame_->maFrameData; + while( pTemp ) + { + if( &maFrameData != pTemp + && _GetDisplay() == pTemp->pDisplay_ + && SHOWSTATE_NORMAL == pTemp->nShowState_ + && pTemp->bMapped_ ) + { + /* #62634# */ + XWindowAttributes window_attributes; + XGetWindowAttributes( _GetXDisplay(), + XtWindow( pTemp->hShell_ ), &window_attributes); + /* racing condition, we called ::Show(1), but the + * window may not be ready (i.e. bMapped_ != map_state) */ + if ( window_attributes.map_state != IsViewable ) + { + XtMapWidget( pTemp->hShell_ ); + XSync( _GetXDisplay(), False ); + } + + /* #69412# double check whether the window is successfully mapped, + since fvwm2 prohibits the mapping of the initial frame, depending + on its window positioning policy for new windows */ + XGetWindowAttributes( _GetXDisplay(), XtWindow( pTemp->hShell_ ), &window_attributes); + if ( window_attributes.map_state == IsViewable ) + { + XSetInputFocus( _GetXDisplay(), XtWindow( pTemp->hShell_ ) , + RevertToNone, CurrentTime ); + } + break; + } + pTemp = &pTemp->pNextFrame_->maFrameData; + } + } + } +} + +// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +beta void SalFrame::ToTop( USHORT nFlags ) +{ + int i; + // if one of our children is in fullscreen mode, ignore the to top + // and raise it instead. This will not work for grandchildren + // #58714# + for( i = 0; i < maFrameData.maChildren.Count(); i++ ) + { + Widget pChild = maFrameData.maChildren.GetObject( i )-> + maFrameData.hNoFullscreenShell_; + if( pChild ) + { + XRaiseWindow( _GetXDisplay(), XtWindow( pChild ) ); + return; + } + } + + if( nFlags & SAL_FRAME_TOTOP_RESTOREWHENMIN ) + XtMapWidget( maFrameData.hShell_ ); + + XRaiseWindow( _GetXDisplay(), maFrameData.GetShellWindow() ); + for( i=0; i < maFrameData.maChildren.Count(); i++ ) + maFrameData.maChildren.GetObject( i )->ToTop( nFlags ); + //XSetInputFocus( _GetXDisplay(), _GetShellWindow(), RevertToNone, CurrentTime ); +} + +// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +void SalFrame::GetClientSize( long &rWidth, long &rHeight ) +{ + if( ! maFrameData.bViewable_ && ! maFrameData.hNoFullscreenShell_ ) + { + rWidth = rHeight = 0; + return; + } + + rWidth = maFrameData.aPosSize_.GetWidth(); + rHeight = maFrameData.aPosSize_.GetHeight(); + + if( !rWidth || !rHeight ) + { + if( SHOWSTATE_UNKNOWN != maFrameData.nShowState_ ) abort(); + + XWindowAttributes aAttrib; + + XGetWindowAttributes( _GetXDisplay(), maFrameData.GetShellWindow(), &aAttrib ); + + rWidth = aAttrib.width; + rHeight = aAttrib.height; + } +} + +// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +void SalFrame::SetClientSize( long nWidth, long nHeight ) +{ + if( maFrameData.nStyle_ & SAL_FRAME_STYLE_CHILD ) + return; + + if( maFrameData.nStyle_ & SAL_FRAME_STYLE_FLOAT ) + { + maFrameData.SetPosSize( Rectangle( + Point( maFrameData.aPosSize_.Left(), maFrameData.aPosSize_.Top() ), + Size( nWidth, nHeight ) ) ); + return; + } + + XLIB_Window aDummy; + int nX, nY, nScreenWidth, nScreenHeight; + + nScreenWidth = _GetDisplay()->GetScreenSize().Width(); + nScreenHeight = _GetDisplay()->GetScreenSize().Height(); + + XTranslateCoordinates ( _GetXDisplay(), maFrameData.GetShellWindow(), + _GetDisplay()->GetRootWindow(), 0, 0, &nX, &nY, + &aDummy ); + + if ( maFrameData.bDefaultPosition_ ) + { + // center the application window + + nX = (nScreenWidth - nWidth ) / 2; + nY = (nScreenHeight - nHeight) / 2; + + maFrameData.bDefaultPosition_ = False; + } + else + { + // once centered, we leave the window where it is with new size + // but only if it does not run out of screen + + if ( nX + nWidth > nScreenWidth ) nX = nScreenWidth - nWidth; + if ( nY + nHeight > nScreenHeight ) nY = nScreenHeight - nHeight; + if ( nX < 0 ) nX = 0; + if ( nY < 20 ) nY = 20;// guess size of top window + // decoration is 20 + } + + Size aSize ( nWidth, nHeight ); + Point aPoint ( nX, nY ); + maFrameData.SetPosSize( Rectangle ( aPoint, aSize ) ); +} + +#if 0 +void SalFrame::SetClientPosSize( const Rectangle& rRect ) +{ + if( maFrameData.nStyle_ & SAL_FRAME_STYLE_CHILD ) + return; + + maFrameData.SetPosSize( rRect ); +} +#endif + +// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +void SalFrame::SetAlwaysOnTop( BOOL bOnTop ) +{ + // #74406# do not raise fullscreenwindow since it may override the + // screenlocker + // maFrameData.bAlwaysOnTop_ = bOnTop; + if( bOnTop ) + XRaiseWindow( _GetXDisplay(), maFrameData.GetShellWindow() ); +} + +// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +void SalFrame::SetWindowState( const SalFrameState *pState ) +{ + int nWidth = pState->mnWidth > 0 ? pState->mnWidth - 1 : 0 ; + int nHeight = pState->mnHeight > 0 ? pState->mnHeight - 1 : 0 ; + + Rectangle aPosSize = Rectangle( pState->mnX, + pState->mnY, + pState->mnX + nWidth, + pState->mnY + nHeight ); + + maFrameData.SetPosSize( aPosSize ); + + if( pState->mnState & SAL_FRAMESTATE_MAXIMIZED ) + { + maFrameData.nShowState_ = SHOWSTATE_NORMAL; + maFrameData.Maximize(); + } + if( pState->mnState & SAL_FRAMESTATE_MINIMIZED ) + { + if ( maFrameData.nShowState_ == SHOWSTATE_UNKNOWN ) + maFrameData.nShowState_ = SHOWSTATE_NORMAL; + maFrameData.Minimize(); + } +} + +// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +BOOL SalFrame::GetWindowState( SalFrameState* pState ) +{ + if( SHOWSTATE_MINIMIZED == maFrameData.nShowState_ ) + pState->mnState = SAL_FRAMESTATE_MINIMIZED; + else + pState->mnState = 0; + + Rectangle aPosSize; + if( !maFrameData.aRestoreMaximize_.IsEmpty() ) + { + aPosSize = maFrameData.aRestoreMaximize_; + pState->mnState |= SAL_FRAMESTATE_MAXIMIZED; + } + else + maFrameData.GetPosSize( aPosSize ); + + pState->mnX = aPosSize.Left(); + pState->mnY = aPosSize.Top(); + pState->mnWidth = aPosSize.GetWidth(); + pState->mnHeight = aPosSize.GetHeight(); + + return TRUE; +} + +// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +void SalFrameData::GetPosSize( Rectangle &rPosSize ) +{ + if( aPosSize_.IsEmpty() ) + { + long w = nMaxWidth_ + ? nMaxWidth_ + : pDisplay_->GetScreenSize().Width() - nLeft_ - nRight_; + long h = nMaxHeight_ + ? nMaxHeight_ + : pDisplay_->GetScreenSize().Height() - nTop_ - nBottom_; + + rPosSize = Rectangle( Point( nLeft_, nTop_ ), Size( w, h ) ); + } + else + rPosSize = aPosSize_; +} + +// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +void SalFrameData::SetSize( const Size &rSize ) +{ + XWindowChanges values; + values.width = rSize.Width(); + values.height = rSize.Height(); + if (values.width > 0 && values.height > 0) + { + Arg args[10]; + int n = 0; + XtSetArg(args[n], XtNheight, rSize.Height()); n++; + XtSetArg(args[n], XtNwidth, rSize.Width()); n++; + XtSetValues( hShell_, args, n ); + + if( ! ( nStyle_ & ( SAL_FRAME_STYLE_CHILD | SAL_FRAME_STYLE_FLOAT ) ) ) + MarkWindowAsGoodPositioned( XtWindow( hShell_ ) ); + + aPosSize_.Right() = aPosSize_.Left() + rSize.Width() - 1; + aPosSize_.Bottom() = aPosSize_.Top() + rSize.Height() - 1; + } +} + +// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +void SalFrameData::SetPosSize( const Rectangle &rPosSize ) +{ + XWindowChanges values; + values.x = rPosSize.Left(); + values.y = rPosSize.Top(); + values.width = rPosSize.GetWidth(); + values.height = rPosSize.GetHeight(); + + if ( !values.width || !values.height ) + return; + + if( ! ( nStyle_ & ( SAL_FRAME_STYLE_CHILD | SAL_FRAME_STYLE_FLOAT ) ) ) + { + MarkWindowAsGoodPositioned( XtWindow( hShell_ ) ); + + if( !(pDisplay_->GetProperties() & PROPERTY_SUPPORT_WM_ClientPos) ) + { + values.x -= nLeft_; + values.y -= nTop_; + } + } + if( ( nStyle_ & SAL_FRAME_STYLE_FLOAT ) && mpParent ) + { + XLIB_Window aChild; + // coordinates are relative to parent, so translate to root coordinates + XTranslateCoordinates( GetDisplay()->GetDisplay(), + mpParent->maFrameData.GetWindow(), + GetDisplay()->GetRootWindow(), + values.x, values.y, + &values.x, &values.y, + & aChild ); + } + + Arg args[10]; + int n = 0; + XtSetArg(args[n], XtNheight, values.height); n++; + XtSetArg(args[n], XtNwidth, values.width); n++; + XtSetArg(args[n], XtNx, values.x); n++; + XtSetArg(args[n], XtNy, values.y); n++; + XtSetValues( hShell_, args, n ); + + if ( aPosSize_ != rPosSize ) + { + aPosSize_ = rPosSize; + Call ( SALEVENT_RESIZE, NULL ); + } +} + +// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +void SalFrameData::Minimize() +{ + if( SHOWSTATE_UNKNOWN == nShowState_ ) + { + stderr0( "SalFrameData::Minimize SHOWSTATE_UNKNOWN\n" ); + return; + } + + if( hNoFullscreenShell_ ) + XtUnmapWidget( hNoFullscreenShell_ ); + if( XIconifyWindow( GetXDisplay(), + XtWindow( hShell_ ), + pDisplay_->GetScreenNumber() ) ) + nShowState_ = SHOWSTATE_MINIMIZED; +} + +// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +void SalFrameData::Maximize() +{ + if( SHOWSTATE_UNKNOWN == nShowState_ ) + { + stderr0( "SalFrameData::Maximize SHOWSTATE_UNKNOWN\n" ); + return; + } + + if( SHOWSTATE_MINIMIZED == nShowState_ ) + { + if( hNoFullscreenShell_ ) + XtMapWidget( hNoFullscreenShell_ ); + XtMapWidget( hShell_ ); + nShowState_ = SHOWSTATE_NORMAL; + } + + if( aRestoreMaximize_.IsEmpty() ) + aRestoreMaximize_ = aPosSize_; + + if( pDisplay_->GetProperties() & PROPERTY_SUPPORT_WM_Screen ) + { + long w = nMaxWidth_ + ? nMaxWidth_ + : pDisplay_->GetScreenSize().Width() - nLeft_ - nRight_; + long h = nMaxHeight_ + ? nMaxHeight_ + : pDisplay_->GetScreenSize().Height() - nTop_ - nBottom_; + + SetPosSize( Rectangle( Point( nLeft_, nTop_), Size( w, h ) ) ); + } + else + { + Display *pDisplay = GetXDisplay(); + XLIB_Window hRoot = pDisplay_->GetRootWindow(); + XLIB_Window *Children, hDummy; + unsigned int nChildren, n; + + // simulate WM-Maximize: clip iconbars + int nW = pDisplay_->GetScreenSize().Width(); + int nH = pDisplay_->GetScreenSize().Height(); + + XRectangle aRect; + XLIB_Region pXRegA = XCreateRegion(); + + aRect.x = 0; + aRect.y = 0; + aRect.width = nW; + aRect.height = nH; + + XUnionRectWithRegion( &aRect, pXRegA, pXRegA ); + + XQueryTree( pDisplay, + hRoot, + &hRoot, + &hDummy, + &Children, + &nChildren ); + + SalXLib *pXLib = GetSalData()->GetLib(); + BOOL bOld = pXLib->GetIgnoreXErrors(); + + for( n = 0; n < nChildren; n++ ) + { + XWindowAttributes aAttrib; + + pXLib->SetIgnoreXErrors( TRUE ); // reset WasXError + + XGetWindowAttributes( pDisplay, Children[n], &aAttrib ); + + aRect.x = aAttrib.x; + aRect.y = aAttrib.y; + aRect.width = aAttrib.width; + aRect.height = aAttrib.height; + + if( !pXLib->WasXError() + && aAttrib.map_state == IsViewable + && (!aRect.x + || !aRect.y + || aRect.x + aRect.width == nW + || aRect.y + aRect.height == nH) + && aRect.width * aRect.height < (nW * nH) / 5 ) + { + XLIB_Region pXRegB = XCreateRegion(); + + XUnionRectWithRegion( &aRect, pXRegB, pXRegB ); + XSubtractRegion( pXRegA, pXRegB, pXRegA ); + + XDestroyRegion( pXRegB ); + } + } + + pXLib->SetIgnoreXErrors( bOld ); + + XClipBox( pXRegA, &aRect ); + + XDestroyRegion( pXRegA ); + + if( aRect.width * aRect.height > (nW * nH) / 2 ) + { + Rectangle aPosSize( aRect.x + nLeft_, + aRect.y + nTop_, + aRect.x + aRect.width - 1 - nRight_, + aRect.y + aRect.height - 1 - nBottom_ ); + + SetPosSize( aPosSize ); + } + } +} + +// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +void SalFrameData::Restore() +{ + if( SHOWSTATE_UNKNOWN == nShowState_ ) + { + stderr0( "SalFrameData::Restore SHOWSTATE_UNKNOWN\n" ); + return; + } + + if( SHOWSTATE_MINIMIZED == nShowState_ ) + { + if( hNoFullscreenShell_ ) + XtMapWidget( hNoFullscreenShell_ ); + XtMapWidget( hShell_ ); + nShowState_ = SHOWSTATE_NORMAL; + } + + if( !aRestoreMaximize_.IsEmpty() ) + { + SetPosSize( aRestoreMaximize_ ); + aRestoreMaximize_ = Rectangle(); + } +} + +// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +void SalFrameData::ShowFullScreen( BOOL bFullScreen ) +{ + if( aRestoreFullScreen_.IsEmpty() == !bFullScreen ) + return; + + const Size &aScreenSize( pDisplay_->GetScreenSize() ); + + long supplied; + XSizeHints hints; + if( !XGetWMNormalHints( GetXDisplay(), XtWindow( hShell_ ), &hints, &supplied ) ) + hints.flags = supplied = 0; + + if( bFullScreen ) + { + GetPosSize( aRestoreFullScreen_ ); + + SalVisual *pVisual = pDisplay_->GetVisual(); + + hNoFullscreenShell_ = hShell_; + hNoFullscreenComposite_ = hComposite_; + + XWithdrawWindow( GetXDisplay(), XtWindow( hNoFullscreenShell_ ), + GetDisplay()->GetScreenNumber() ); + + Arg aArgs[10]; + int nArgs=0; + SalVisual* pVis = GetDisplay()->GetVisual(); + XtSetArg( aArgs[nArgs], XtNvisual, pVis->GetVisual() ); nArgs++; + XtSetArg( aArgs[nArgs], XtNdepth, pVis->GetDepth() ); nArgs++; + XtSetArg( aArgs[nArgs], XtNcolormap, + GetDisplay()->GetColormap().GetXColormap() ); nArgs++; + XtSetArg( aArgs[nArgs], XtNx, 0 ); nArgs++; + XtSetArg( aArgs[nArgs], XtNy, 0 ); nArgs++; + XtSetArg( aArgs[nArgs], XtNwidth, aScreenSize.Width() ); nArgs++; + XtSetArg( aArgs[nArgs], XtNheight, aScreenSize.Height() ); nArgs++; + XtSetArg( aArgs[nArgs], XtNoverrideRedirect, True ); nArgs++; + hShell_ = XtAppCreateShell( + "VCLFullScreenShell", "VCLFullScreenFrame", + applicationShellWidgetClass, + GetXDisplay(), + aArgs, nArgs ); + XtRealizeWidget( hShell_ ); + + hComposite_ = XtVaCreateManagedWidget( + "ShellComposite", + SAL_COMPOSITE_WIDGET, + hShell_, + NULL ); + XtRealizeWidget( hComposite_ ); + + if( pGraphics_ ) + pGraphics_->maGraphicsData.SetDrawable( XtWindow( hComposite_ ) ); + + delete pFreeGraphics_; + pFreeGraphics_ = NULL; + + if( bMapped_ ) + { + pFrame_->Show( TRUE ); + XSetInputFocus( GetXDisplay(), XtWindow( hShell_ ), + RevertToNone, CurrentTime ); + } + + if ( WMSupportsFWS(GetXDisplay(), pDisplay_->GetRootWindow()) ) + { + AddFwsProtocols( GetXDisplay(), XtWindow(hShell_) ); + RegisterFwsWindow( GetXDisplay(), XtWindow(hShell_) ); + } + + aPosSize_ = Rectangle( Point( 0, 0 ), aScreenSize ); + nWidth_ = aPosSize_.GetWidth(); + nHeight_ = aPosSize_.GetHeight(); + + if ( mpInputContext != NULL ) + { + delete mpInputContext; + mpInputContext = new SalI18N_InputContext( pFrame_ ); + } + Call( SALEVENT_RESIZE, NULL ); + } + else + { + if( pGraphics_ ) + pGraphics_->maGraphicsData.SetDrawable( XtWindow( hNoFullscreenComposite_ ) ); + + delete pFreeGraphics_; + pFreeGraphics_ = NULL; + + if ( mpInputContext != NULL ) + delete mpInputContext; + + XtDestroyWidget( hComposite_ ); + XtDestroyWidget( hShell_ ); + + hComposite_ = hNoFullscreenComposite_; + hShell_ = hNoFullscreenShell_; + + hNoFullscreenShell_ = None; + hNoFullscreenComposite_ = None; + + if( bMapped_ ) + pFrame_->Show( TRUE ); + if ( mpInputContext != NULL ) + { + mpInputContext = new SalI18N_InputContext( pFrame_ ); + if ( bMapped_ ) + mpInputContext->SetICFocus(); + else + mpInputContext->Unmap(); + } + + SetPosSize( aRestoreFullScreen_ ); + // SetPosSize macht Call( SALEVENT_RESIZE ); + aRestoreFullScreen_ = Rectangle(); + nWidth_ = aPosSize_.GetWidth(); + nHeight_ = aPosSize_.GetHeight(); + } +} + +void SalFrame::ShowFullScreen( BOOL bFullScreen ) +{ maFrameData.ShowFullScreen( bFullScreen ); } + +/* --------------------------------------------------------------------- + the xautolock pseudo screen saver needs special treatment since it + doesn't cooperate with XxxxScreenSaver settings + ------------------------------------------------------------------- */ + +static Bool +IsRunningXAutoLock( Display *p_display, XLIB_Window a_window ) +{ + const char *p_atomname = "XAUTOLOCK_SEMAPHORE_PID"; + Atom a_pidatom; + + // xautolock interns this atom + a_pidatom = XInternAtom( p_display, p_atomname, True ); + if ( a_pidatom == None ) + return False; + + Atom a_type; + int n_format; + unsigned long n_items; + unsigned long n_bytes_after; + pid_t *p_pid; + pid_t n_pid; + // get pid of running xautolock + XGetWindowProperty (p_display, a_window, a_pidatom, 0L, 2L, False, + AnyPropertyType, &a_type, &n_format, &n_items, &n_bytes_after, + (unsigned char**) &p_pid ); + n_pid = *p_pid; + XFree( p_pid ); + + if ( a_type == XA_INTEGER ) + { + // check if xautolock pid points to a running process + if ( kill(n_pid, 0) == -1 ) + return False; + else + return True; + } + + return False; +} + +/* definitions from xautolock.c (pl15) */ +#define XAUTOLOCK_DISABLE 1 +#define XAUTOLOCK_ENABLE 2 + +static Bool +MessageToXAutoLock( Display *p_display, int n_message ) +{ + const char *p_atomname = "XAUTOLOCK_MESSAGE" ; + Atom a_messageatom; + XLIB_Window a_rootwindow; + + a_rootwindow = RootWindowOfScreen( ScreenOfDisplay(p_display, 0) ); + if ( ! IsRunningXAutoLock(p_display, a_rootwindow) ) + { + // remove any pending messages + a_messageatom = XInternAtom( p_display, p_atomname, True ); + if ( a_messageatom != None ) + XDeleteProperty( p_display, a_rootwindow, a_messageatom ); + return False; + } + + a_messageatom = XInternAtom( p_display, p_atomname, False ); + XChangeProperty (p_display, a_rootwindow, a_messageatom, XA_INTEGER, + 8, PropModeReplace, (unsigned char*)&n_message, sizeof(n_message) ); + + return True; +} + +// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +void SalFrame::StartPresentation( BOOL bStart ) +{ + if ( bStart ) + MessageToXAutoLock( _GetXDisplay(), XAUTOLOCK_DISABLE ); + else + MessageToXAutoLock( _GetXDisplay(), XAUTOLOCK_ENABLE ); + + if( bStart || maFrameData.nScreenSaversTimeout_ ) + { + int timeout, interval, prefer_blanking, allow_exposures; + XGetScreenSaver( _GetXDisplay(), + &timeout, + &interval, + &prefer_blanking, + &allow_exposures ); + if( !bStart ) + { + XSetScreenSaver( _GetXDisplay(), + maFrameData.nScreenSaversTimeout_, + interval, + prefer_blanking, + allow_exposures ); + maFrameData.nScreenSaversTimeout_ = 0; + } + else if( timeout ) + { + maFrameData.nScreenSaversTimeout_ = timeout; + XResetScreenSaver( _GetXDisplay() ); + XSetScreenSaver( _GetXDisplay(), + 0, + interval, + prefer_blanking, + allow_exposures ); + } + } +} + +// Pointer +// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +inline void SalFrameData::SetPointer( PointerStyle ePointerStyle ) +{ + hCursor_ = pDisplay_->GetPointer( ePointerStyle ); + XDefineCursor( GetXDisplay(), XtWindow( hComposite_ ), hCursor_ ); + + if( IsCaptured() ) + XChangeActivePointerGrab( GetXDisplay(), + PointerMotionMask|ButtonPressMask|ButtonReleaseMask, + hCursor_, + CurrentTime ); +} + +void SalFrame::SetPointer( PointerStyle ePointerStyle ) +{ maFrameData.SetPointer( ePointerStyle ); } + +void SalFrame::CaptureMouse( BOOL bCapture ) +{ maFrameData.CaptureMouse( bCapture ); } + +void SalFrame::SetPointerPos( long nX, long nY ) +{ XWarpPointer( _GetXDisplay(), None, maFrameData.GetShellWindow(), 0, 0, 0, 0, nX, nY ); } + +// PostEvent +// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +BOOL SalFrame::PostEvent( void *pData ) +{ + _GetDisplay()->SendEvent( _GetDisplay()->GetICCCM().aUserEvent_, + pData, + maFrameData.GetWindow() ); + return TRUE; +} + +// Title +// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +void SalFrame::SetTitle( const XubString& rTitle ) +{ + ByteString aByteTitle( rTitle, gsl_getSystemTextEncoding() ); + + char* pTitle = (char*)aByteTitle.GetBuffer(); + XTextProperty aTitle; + + if( !XStringListToTextProperty( &pTitle, 1, &aTitle ) ) + { + fprintf( stderr, "SalFrame::SetTitle !XStringListToTextProperty(%s)\n", + pTitle ); + abort(); + } + + XSetWMName ( _GetXDisplay(), maFrameData.GetShellWindow(), &aTitle ); + XSetWMIconName( _GetXDisplay(), maFrameData.GetShellWindow(), &aTitle ); + + XFree( aTitle.value ); +} + +// ----------------------------------------------------------------------- + +void SalFrame::Flush() +{ + XFlush( _GetDisplay()->GetDisplay() ); +} + +// ----------------------------------------------------------------------- + +void SalFrame::Sync() +{ + XSync( _GetDisplay()->GetDisplay(), False ); +} + +// Keyboard +// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +// ----------------------------------------------------------------------- + +void SalFrame::SetInputContext( SalInputContext* pContext ) +{ +} + +// ----------------------------------------------------------------------- + +void SalFrame::UpdateExtTextInputArea() +{ +} + +// ----------------------------------------------------------------------- + +void SalFrame::EndExtTextInput( USHORT nFlags ) +{ + maFrameData.mpInputContext->EndExtTextInput( nFlags ); +} + +// ----------------------------------------------------------------------- + +XubString SalFrame::GetKeyName( USHORT nKeyCode ) +{ + return _GetDisplay()->GetKeyName( nKeyCode ); +} + +XubString SalFrame::GetSymbolKeyName( const XubString&, USHORT nKeyCode ) +{ + return GetKeyName( nKeyCode ); +} + +// Settings +// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +inline Color getColorFromLong( long nColor ) +{ + return Color( (nColor & 0xff), (nColor & 0xff00)>>8, (nColor & 0xff0000)>>16); +} + +void SalFrame::UpdateSettings( AllSettings& rSettings ) +{ + + static SystemLookInfo aInfo; + static BOOL bHaveInfo = FALSE; + static BOOL bInit = FALSE; + + if( ! bInit ) + { + bInit = TRUE; + DtIntegrator* pIntegrator = DtIntegrator::CreateDtIntegrator( this ); + if( pIntegrator ) + bHaveInfo = pIntegrator->GetSystemLook( aInfo ); + } + + if( bHaveInfo ) + { + StyleSettings aStyleSettings = rSettings.GetStyleSettings(); + if( aInfo.windowActiveStart.GetColor() != COL_TRANSPARENT ) + { + aStyleSettings.SetActiveColor( aInfo.windowActiveStart ); + if( aInfo.windowActiveEnd.GetColor() != COL_TRANSPARENT ) + aStyleSettings.SetActiveColor2( aInfo.windowActiveEnd ); + } + if( aInfo.windowInactiveStart.GetColor() != COL_TRANSPARENT ) + { + aStyleSettings.SetDeactiveColor( aInfo.windowInactiveStart ); + if( aInfo.windowInactiveEnd.GetColor() != COL_TRANSPARENT ) + aStyleSettings.SetDeactiveColor2( aInfo.windowInactiveEnd ); + } + if( aInfo.activeBorder.GetColor() != COL_TRANSPARENT ) + aStyleSettings.SetActiveBorderColor( aInfo.activeBorder ); + if( aInfo.inactiveBorder.GetColor() != COL_TRANSPARENT ) + aStyleSettings.SetDeactiveBorderColor( aInfo.inactiveBorder ); + if( aInfo.activeForeground.GetColor() != COL_TRANSPARENT ) + aStyleSettings.SetActiveTextColor( aInfo.activeForeground ); + if( aInfo.inactiveForeground.GetColor() != COL_TRANSPARENT ) + aStyleSettings.SetDeactiveTextColor( aInfo.inactiveForeground ); + if( aInfo.selectForeground.GetColor() != COL_TRANSPARENT ) + aStyleSettings.SetHighlightTextColor( aInfo.selectForeground ); + if( aInfo.selectBackground.GetColor() != COL_TRANSPARENT ) + aStyleSettings.SetHighlightColor( aInfo.selectBackground ); + if( aInfo.foreground.GetColor() != COL_TRANSPARENT ) + { + aStyleSettings.SetDialogTextColor( aInfo.foreground ); + aStyleSettings.SetMenuTextColor( aInfo.foreground ); + aStyleSettings.SetButtonTextColor( aInfo.foreground ); + aStyleSettings.SetRadioCheckTextColor( aInfo.foreground ); + aStyleSettings.SetGroupTextColor( aInfo.foreground ); + aStyleSettings.SetLabelTextColor( aInfo.foreground ); + aStyleSettings.SetInfoTextColor( aInfo.foreground ); + } + if( aInfo.background.GetColor() != COL_TRANSPARENT ) + { + aStyleSettings.Set3DColors( aInfo.background ); + aStyleSettings.SetFaceColor( aInfo.background ); + aStyleSettings.SetDialogColor( aInfo.background ); + aStyleSettings.SetMenuColor( aInfo.background ); + if ( aStyleSettings.GetFaceColor() == COL_LIGHTGRAY ) + aStyleSettings.SetCheckedColor( Color( 0xCC, 0xCC, 0xCC ) ); + else + { + // calculate Checked color + Color aColor2 = aStyleSettings.GetLightColor(); + BYTE nRed = (BYTE)(((USHORT)aInfo.background.GetRed() + (USHORT)aColor2.GetRed())/2); + BYTE nGreen = (BYTE)(((USHORT)aInfo.background.GetGreen() + (USHORT)aColor2.GetGreen())/2); + BYTE nBlue = (BYTE)(((USHORT)aInfo.background.GetBlue() + (USHORT)aColor2.GetBlue())/2); + aStyleSettings.SetCheckedColor( Color( nRed, nGreen, nBlue ) ); + } + } + + if( aInfo.windowFont.Len() ) + { + Font aWindowFont = aStyleSettings.GetTitleFont(); + aWindowFont.SetName( aInfo.windowFont ); + aStyleSettings.SetTitleFont( aWindowFont ); + } + + rSettings.SetStyleSettings( aStyleSettings ); + } +} + +// Sound +// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +void SalFrame::Beep( SoundType eSoundType ) // not fully suported +{ _GetDisplay()->Beep(); } + +// Callback +// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +void SalFrame::SetCallback( void* pInst, SALFRAMEPROC pProc ) +{ + maFrameData.pInst_ = pInst; + maFrameData.pProc_ = pProc ? pProc : sal_CallbackDummy; +} + +// Event Handling +// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +static USHORT sal_GetCode( int state ) +{ + USHORT nCode = 0; + + if( state & Button1Mask ) + nCode |= MOUSE_LEFT; + if( state & Button2Mask ) + nCode |= MOUSE_MIDDLE; + if( state & Button3Mask ) + nCode |= MOUSE_RIGHT; + + if( state & ShiftMask ) + nCode |= KEY_SHIFT; + if( state & ControlMask ) + nCode |= KEY_MOD1; + if( state & Mod1Mask ) + nCode |= KEY_MOD2; + + return nCode; +} + +long SalFrameData::HandleMouseEvent( XEvent *pEvent ) +{ + SalMouseEvent aMouseEvt; + USHORT nEvent; + static ULONG nLines = 0; + + // Solaris X86: clicking the right button on a two-button mouse + // generates a button2 event not a button3 event + if (pDisplay_->GetProperties() & PROPERTY_SUPPORT_3ButtonMouse ) + { + switch (pEvent->type) + { + case EnterNotify: + case LeaveNotify: + if ( pEvent->xcrossing.state & Button2Mask ) + { + pEvent->xcrossing.state &= ~Button2Mask; + pEvent->xcrossing.state |= Button3Mask; + } + break; + + case MotionNotify: + if ( pEvent->xmotion.state & Button2Mask ) + { + pEvent->xmotion.state &= ~Button2Mask; + pEvent->xmotion.state |= Button3Mask; + } + break; + + default: + if ( Button2 == pEvent->xbutton.button ) + { + pEvent->xbutton.state &= ~Button2Mask; + pEvent->xbutton.state |= Button3Mask; + pEvent->xbutton.button = Button3; + } + break; + } + } + + + if( LeaveNotify == pEvent->type || EnterNotify == pEvent->type ) + { + aMouseEvt.mnX = pEvent->xcrossing.x; + aMouseEvt.mnY = pEvent->xcrossing.y; + aMouseEvt.mnTime = pEvent->xcrossing.time; + aMouseEvt.mnCode = sal_GetCode( pEvent->xcrossing.state ); + + aMouseEvt.mnButton = 0; + + nEvent = LeaveNotify == pEvent->type + ? SALEVENT_MOUSELEAVE + : SALEVENT_MOUSEMOVE; + } + else if( pEvent->type == MotionNotify ) + { + aMouseEvt.mnX = pEvent->xmotion.x; + aMouseEvt.mnY = pEvent->xmotion.y; + aMouseEvt.mnTime = pEvent->xmotion.time; + aMouseEvt.mnCode = sal_GetCode( pEvent->xmotion.state ); + + aMouseEvt.mnButton = 0; + + nEvent = SALEVENT_MOUSEMOVE; + } + else + { + // get input focus on SAL_FRAME_STYLE_CHILD windows + // because the focus handling in this case (running as plugin) + // is "a little tricky" + if( nStyle_ & SAL_FRAME_STYLE_CHILD ) + XSetInputFocus( GetDisplay()->GetDisplay(), GetWindow(), RevertToParent, CurrentTime ); + if( pEvent->xbutton.button == Button1 || + pEvent->xbutton.button == Button2 || + pEvent->xbutton.button == Button3 ) + { + aMouseEvt.mnX = pEvent->xbutton.x; + aMouseEvt.mnY = pEvent->xbutton.y; + aMouseEvt.mnTime = pEvent->xbutton.time; + aMouseEvt.mnCode = sal_GetCode( pEvent->xbutton.state ); + + if( Button1 == pEvent->xbutton.button ) + aMouseEvt.mnButton = MOUSE_LEFT; + else if( Button2 == pEvent->xbutton.button ) + aMouseEvt.mnButton = MOUSE_MIDDLE; + else if( Button3 == pEvent->xbutton.button ) + aMouseEvt.mnButton = MOUSE_RIGHT; + + nEvent = ButtonPress == pEvent->type + ? SALEVENT_MOUSEBUTTONDOWN + : SALEVENT_MOUSEBUTTONUP; + } + else if( pEvent->xbutton.button == Button4 || + pEvent->xbutton.button == Button5 ) + { + if( ! nLines ) + { + char* pEnv = getenv( "SAL_WHEELLINES" ); + nLines = pEnv ? atoi( pEnv ) : 3; + if( nLines > 10 ) + nLines = SAL_WHEELMOUSE_EVENT_PAGESCROLL; + } + + SalWheelMouseEvent aWheelEvt; + aWheelEvt.mnTime = pEvent->xbutton.time; + aWheelEvt.mnX = pEvent->xbutton.x; + aWheelEvt.mnY = pEvent->xbutton.y; + aWheelEvt.mnDelta = + pEvent->xbutton.button == Button4 ? 120 : -120; + aWheelEvt.mnNotchDelta = + pEvent->xbutton.button == Button4 ? 1 : -1; + aWheelEvt.mnScrollLines = nLines; + aWheelEvt.mnCode = sal_GetCode( pEvent->xbutton.state ); + aWheelEvt.mbHorz = FALSE; + + nEvent = SALEVENT_WHEELMOUSE; + + return Call( nEvent, &aWheelEvt ); + } + } + + if( nEvent == SALEVENT_MOUSELEAVE + || ( aMouseEvt.mnX < nWidth_ && aMouseEvt.mnX > -1 && + aMouseEvt.mnY < nHeight_ && aMouseEvt.mnY > -1 ) + || pDisplay_->MouseCaptured( this ) ) + return Call( nEvent, &aMouseEvt ); + +#ifdef DBG_UTIL + fprintf( stderr, "SalFrameData::HandleMouseEvent %d size=%d*%d event=%d.%d\n", + pEvent->type, nWidth_, nHeight_, aMouseEvt.mnX, aMouseEvt.mnY ); +#endif + return 0; +} + + +// F10 means either KEY_F10 or KEY_MENU, which has to be decided +// in the independent part. +struct KeyAlternate +{ + USHORT nKeyCode; + sal_Unicode nCharCode; + KeyAlternate() : nKeyCode( 0 ), nCharCode( 0 ) {} + KeyAlternate( USHORT nKey, sal_Unicode nChar = 0 ) : nKeyCode( nKey ), nCharCode( nChar ) {} +}; + +inline KeyAlternate +GetAlternateKeyCode( const USHORT nKeyCode ) +{ + KeyAlternate aAlternate; + + switch( nKeyCode ) + { + case KEY_F10: aAlternate = KeyAlternate( KEY_MENU );break; + case KEY_F24: aAlternate = KeyAlternate( KEY_SUBTRACT, '-' );break; + } + + return aAlternate; +} + +// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +long SalFrameData::HandleKeyEvent( XKeyEvent *pEvent ) +{ + int nLen = 16; + unsigned char *pPrintable = (unsigned char*)alloca( nLen ); + KeySym nKeySym; + + // if we haven't got an input context yet then it's time to build it + if ( mpInputContext == NULL ) + { + mpInputContext = new SalI18N_InputContext( pFrame_ ); + if ( mpInputContext->UseContext() ) + mpInputContext->ExtendEventMask( XtWindow( hShell_ ) ); + } + // singlebyte code composed by input method, the new default + if ( mpInputContext->UseContext() ) + { + Status nStatus; + nKeySym = pDisplay_->GetKeySym( pEvent, pPrintable, &nLen, + &nStatus, mpInputContext->GetContext() ); + if ( nStatus == XBufferOverflow ) + { + nLen += 1; + pPrintable = (unsigned char*)alloca( nLen ); + nKeySym = pDisplay_->GetKeySym( pEvent, pPrintable, &nLen, + &nStatus, mpInputContext->GetContext() ); + } + } + else + { + // fallback, this should never ever be called + Status nStatus = 0; + nKeySym = pDisplay_->GetKeySym( pEvent, pPrintable, &nLen, &nStatus ); + if( !nLen ) + pPrintable[0] = 0; + } + + USHORT nModCode = 0; + if( pEvent->state & ShiftMask ) + nModCode |= KEY_SHIFT; + if( pEvent->state & ControlMask ) + nModCode |= KEY_MOD1; + if( pEvent->state & Mod1Mask ) + { + nModCode |= KEY_MOD2; + if ( !(nModCode & KEY_MOD1) ) + nModCode |= KEY_CONTROLMOD; + } + + if( nKeySym == XK_Shift_L || nKeySym == XK_Shift_R + || nKeySym == XK_Control_L || nKeySym == XK_Control_R + || nKeySym == XK_Alt_L || nKeySym == XK_Alt_R + || nKeySym == XK_Meta_L || nKeySym == XK_Meta_R ) + { + SalKeyModEvent aModEvt; + + // pressing just the ctrl key leads to a keysym of XK_Control but + // the event state does not contain ControlMask. In the release + // event its the other way round: it does contain the Control mask. + // The modifier mode therefor has to be adapted manually. + if (pEvent->type == KeyRelease) + { + if ( (nKeySym == XK_Control_L) || (nKeySym == XK_Control_R) ) + nModCode &= ~KEY_MOD1; + if ( (nKeySym == XK_Shift_L) || (nKeySym == XK_Shift_R) ) + nModCode &= ~KEY_SHIFT; + if ( (nKeySym == XK_Alt_L) || (nKeySym == XK_Alt_R) ) + nModCode &= ~KEY_MOD2; + } + else + { + if ( (nKeySym == XK_Control_L) || (nKeySym == XK_Control_R) ) + nModCode |= KEY_MOD1; + if ( (nKeySym == XK_Shift_L) || (nKeySym == XK_Shift_R) ) + nModCode |= KEY_SHIFT; + if ( (nKeySym == XK_Alt_L) || (nKeySym == XK_Alt_R) ) + nModCode |= KEY_MOD2; + } + + aModEvt.mnCode = nModCode; + aModEvt.mnTime = pEvent->time; + + return Call( SALEVENT_KEYMODCHANGE, &aModEvt ); + } + + SalKeyEvent aKeyEvt; + USHORT nKeyCode; + + nKeyCode = pDisplay_->GetKeyCode( nKeySym, (char*)pPrintable ); + if( !nKeyCode && !pPrintable[0] ) + return 0; + + rtl_TextEncoding nEncoding = gsl_getSystemTextEncoding(); + sal_Unicode *pBuffer; + sal_Size nSize; + if ( nEncoding != RTL_TEXTENCODING_UNICODE ) + { + // create text converter + rtl_TextToUnicodeConverter aConverter = + rtl_createTextToUnicodeConverter( nEncoding ); + rtl_TextToUnicodeContext aContext = + rtl_createTextToUnicodeContext( aConverter ); + + sal_Size nBufferSize = nLen * 2; + sal_uInt32 nConversionInfo; + sal_Size nConvertedChars; + + pBuffer = (sal_Unicode*) alloca( nBufferSize + 1); + + // convert to single byte text stream + nSize = rtl_convertTextToUnicode( + aConverter, aContext, + (char*)pPrintable, nLen, + pBuffer, nBufferSize, + RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_IGNORE + | RTL_TEXTTOUNICODE_FLAGS_INVALID_IGNORE, + &nConversionInfo, &nConvertedChars ); + + // destroy converter + rtl_destroyTextToUnicodeContext( aConverter, aContext ); + rtl_destroyTextToUnicodeConverter( aConverter ); + } + else + { + pBuffer = (sal_Unicode*)pPrintable; + nSize = nLen; + } + + // XXX it shouldn't be possible to create a keyrelease event with + // more than a single character in the event, but check it anyway + // as well it shouldn't be possible to generate more than a single + // char without an input method + if ( nSize > 1 + && mpInputContext->UseContext() + && KeyRelease != pEvent->type ) + { + mpInputContext->CommitStringCallback( pBuffer, nSize ); + } + else + { + aKeyEvt.mnCode = nKeyCode | nModCode; + aKeyEvt.mnRepeat = 0; + aKeyEvt.mnTime = pEvent->time; + aKeyEvt.mnCharCode = pBuffer[ 0 ]; + + if( KeyRelease == pEvent->type ) + { + Call( SALEVENT_KEYUP, &aKeyEvt ); + } + else + { + if ( ! Call(SALEVENT_KEYINPUT, &aKeyEvt) ) + { + // independent layer doesnt want to handle key-event, so check + // whether the keycode may have an alternate meaning + KeyAlternate aAlternate = GetAlternateKeyCode( nKeyCode ); + if ( aAlternate.nKeyCode != 0 ) + { + aKeyEvt.mnCode = aAlternate.nKeyCode | nModCode; + if( aAlternate.nCharCode ) + aKeyEvt.mnCharCode = aAlternate.nCharCode; + Call(SALEVENT_KEYINPUT, &aKeyEvt); + } + } + } + } + + return True; +} + + +// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +long SalFrameData::HandleFocusEvent( XFocusChangeEvent *pEvent ) +{ + /* #55691# ignore focusout resulting from keyboard grabs + * we do not grab it and are not interested when + * someone else does CDE e.g. does a XGrabKey on arrow keys + * #73179# handle focus events with mode NotifyWhileGrabbed + * because with CDE alt-tab focus changing we do not get + * normal focus events + * #71791# cast focus event to the input context, otherwise the + * status window does not follow the application frame + */ + if ( mpInputContext != NULL ) + { + if( FocusIn == pEvent->type ) + mpInputContext->SetICFocus(); + else + mpInputContext->UnsetICFocus(); + } + + if ( pEvent->mode == NotifyNormal || pEvent->mode == NotifyWhileGrabbed ) + { + if( FocusIn == pEvent->type ) + { + return Call( SALEVENT_GETFOCUS, 0 ); + } + else + { + return Call( SALEVENT_LOSEFOCUS, 0 ); + } + } + + return 0; +} + +// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +class SalPeekExpose +{ + XEvent aEvent_; + XEvent *pEvent_; + USHORT nEvent_; + +public: + inline Bool Callback() + { + if( aEvent_.type != pEvent_->type + || aEvent_.xany.window != pEvent_->xany.window ) + return !--nEvent_; + pEvent_->xexpose.count++; + return True; + } + inline SalPeekExpose( XEvent *p ); +}; + +extern "C" Bool +sal_PeekExpose( Display*, XEvent*, char *p ) +{ + return ((SalPeekExpose*)p)->Callback(); +} + +inline SalPeekExpose::SalPeekExpose( XEvent *p ) : pEvent_( p ) +{ +#ifdef DBG_UTIL + memset( &aEvent_, 0, sizeof( aEvent_ ) ); +#endif + nEvent_ = QLength( p->xany.display ); + XPeekIfEvent( p->xany.display, &aEvent_, sal_PeekExpose, (char*)this ); +} + +// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +long SalFrameData::HandleExposeEvent( XEvent *pEvent ) +{ + XRectangle aRect; + USHORT nCount; + + if( pEvent->type == Expose ) + { + aRect.x = pEvent->xexpose.x; + aRect.y = pEvent->xexpose.y; + aRect.width = pEvent->xexpose.width; + aRect.height = pEvent->xexpose.height; + nCount = pEvent->xexpose.count; + } + else if( pEvent->type == GraphicsExpose ) + { + aRect.x = pEvent->xgraphicsexpose.x; + aRect.y = pEvent->xgraphicsexpose.y; + aRect.width = pEvent->xgraphicsexpose.width; + aRect.height = pEvent->xgraphicsexpose.height; + nCount = pEvent->xgraphicsexpose.count; + } + + if( hNoFullscreenShell_ != None ) + // we are in fullscreen mode -> override redirect + // focus is probably lost, so reget it + XSetInputFocus( GetXDisplay(), XtWindow( hShell_ ), RevertToNone, CurrentTime ); + + if( !IsWaitingForExpose() ) + { + // complete painting + if( !nCount + && !aRect.x + && !aRect.y + && aRect.width == nWidth_ + && aRect.height == nHeight_ ) + { + SalPaintEvent aPEvt; + + aPEvt.mnBoundX = 0; + aPEvt.mnBoundY = 0; + aPEvt.mnBoundWidth = nWidth_; + aPEvt.mnBoundHeight = nHeight_; + + Call( SALEVENT_PAINT, &aPEvt ); + + return 1; + } + + pPaintRegion_ = XCreateRegion(); + } + + XUnionRectWithRegion( &aRect, pPaintRegion_, pPaintRegion_ ); + + if( nCount ) // wait for last expose rectangle + return 1; + + if( QLength( pEvent->xany.display ) ) + { + SalPeekExpose Peek( pEvent ); + + if( pEvent->xexpose.count ) + { + stderr1( "SalFrameData::HandleExposeEvent %s\n", + ServerVendor(GetXDisplay()) ); + return 1; + } + } + + SalPaintEvent aPEvt; + + XClipBox( pPaintRegion_, &aRect ); + + aPEvt.mnBoundX = aRect.x; + aPEvt.mnBoundY = aRect.y; + aPEvt.mnBoundWidth = aRect.width; + aPEvt.mnBoundHeight = aRect.height; + + Call( SALEVENT_PAINT, &aPEvt ); + + XDestroyRegion( pPaintRegion_ ); + pPaintRegion_ = NULL; + + return 1; +} + +void SalFrameData::RepositionFloatChildren() +{ + // move SAL_FRAME_STYLE_FLOAT children to new position + for( int nChild = 0; nChild < maChildren.Count(); nChild++ ) + { + SalFrameData* pData = &maChildren.GetObject( nChild )->maFrameData; + if( pData->nStyle_ & SAL_FRAME_STYLE_FLOAT ) + { +#ifdef DEBUG + fprintf( stderr, "moving FLOAT child\n" ); +#endif + pData->SetPosSize( pData->aPosSize_ ); + } + } +} + +// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +long SalFrameData::HandleSizeEvent( XConfigureEvent *pEvent ) +{ + if ( pEvent->window != XtWindow( hShell_ ) + && pEvent->window != XtWindow( hComposite_ ) + && pEvent->window != hForeignParent_ + && pEvent->window != hForeignTopLevelWindow_ ) + { + // could be as well a sys-child window (aka SalObject) + return 1; + } + + // ignore for now + if( nStyle_ & SAL_FRAME_STYLE_FLOAT ) + return 1; + + if( pEvent->window == hForeignTopLevelWindow_ ) + { + // just update the children's positions + RepositionFloatChildren(); + return 1; + } + + if( pEvent->window == hForeignParent_ ) + { + Arg args[10]; + int n = 0; + XtSetArg(args[n], XtNheight, pEvent->height); n++; + XtSetArg(args[n], XtNwidth, pEvent->width); n++; + XtSetValues( hShell_, args, n ); + } + if( SHOWSTATE_UNKNOWN == nShowState_ ) + { + nShowState_ = SHOWSTATE_NORMAL; + + XSizeHints hints; + long supplied; + if( XGetWMNormalHints( pEvent->display, + pEvent->window, + &hints, + &supplied ) ) + { + if( hints.flags & PMaxSize ) // supplied + { + nMaxWidth_ = hints.max_width; + nMaxHeight_ = hints.max_height; + DBG_ASSERT( nMaxWidth_ && nMaxHeight_, "!MaxWidth^!MaxHeight" ) + } + } + } + + if( !pEvent->send_event ) + { + XLIB_Window hDummy; + XTranslateCoordinates( GetXDisplay(), + XtWindow( hShell_ ), + pDisplay_->GetRootWindow(), + 0, 0, + &pEvent->x, &pEvent->y, + &hDummy ); + } + + if( nMaxWidth_ || nMaxHeight_ ) + { + if( nMaxWidth_ != pEvent->width || nMaxHeight_ != pEvent->height ) + aRestoreMaximize_ = Rectangle(); + else if( aRestoreMaximize_.IsEmpty() ) + { + stderr0( "SalFrameData::HandleSizeEvent zoomed\n" ); + GetPosSize( aRestoreMaximize_ ); + } + } + else + if( pEvent->x != nLeft_ || pEvent->y != nTop_ ) + aRestoreMaximize_ = Rectangle(); + else + { + Size aSize( pEvent->width + nLeft_ + nRight_, + pEvent->height + nTop_ + nBottom_ ); + + if( aSize != pDisplay_->GetScreenSize() ) + aRestoreMaximize_ = Rectangle(); + else + if( aRestoreMaximize_.IsEmpty() ) + { + stderr0( "SalFrameData::HandleSizeEvent zoomed\n" ); + GetPosSize( aRestoreMaximize_ ); + } + } + + aPosSize_.Left() = pEvent->x; + aPosSize_.Top() = pEvent->y; + aPosSize_.Right() = aPosSize_.Left() + pEvent->width - 1; + aPosSize_.Bottom() = aPosSize_.Top() + pEvent->height - 1; + + // update children's position + RepositionFloatChildren(); + + if( nWidth_ != pEvent->width || nHeight_ != pEvent->height ) + { + nWidth_ = pEvent->width; + nHeight_ = pEvent->height; + + if( pEvent->window != XtWindow( hComposite_ ) ) + { + XtResizeWidget(hComposite_, nWidth_, nHeight_, 0); + + Arg args[4]; + int n = 0; + XtSetArg(args[n], XtNheight, pEvent->height); n++; + XtSetArg(args[n], XtNwidth, pEvent->width); n++; + // XtSetValues(hComposite_, args, n); + } + Call( SALEVENT_RESIZE, NULL ); + } + return 1; +} + +// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +long SalFrameData::HandleReparentEvent( XReparentEvent *pEvent ) +{ + Display *pDisplay = pEvent->display; + XLIB_Window hWM_Parent = pEvent->parent; + XLIB_Window hRoot, *Children, hDummy; + unsigned int nChildren, n; + BOOL bNone = pDisplay_->GetProperties() + & PROPERTY_SUPPORT_WM_Parent_Pixmap_None; + + if( hWM_Parent == pDisplay_->GetRootWindow() + || hWM_Parent == hForeignParent_ + || ( nStyle_ & SAL_FRAME_STYLE_FLOAT ) ) + { + // Reparenting before Destroy + return 0; + } + + if( !pEvent->x && !pEvent->y ) + { + if( bNone ) + XSetWindowBackgroundPixmap( pDisplay, hWM_Parent, None ); + + XQueryTree( GetXDisplay(), + hWM_Parent, + &hRoot, + &hWM_Parent, + &Children, + &nChildren ); + + XFree( Children ); + } + + if( hWM_Parent == hRoot ) + hWM_Parent = pEvent->parent; + else if( bNone ) + XSetWindowBackgroundPixmap( pDisplay, hWM_Parent, None ); + + XQueryTree( pDisplay, + hWM_Parent, + &hRoot, + &hDummy, + &Children, + &nChildren ); + +#ifdef DBG_UTIL + if( hDummy != hRoot ) + { + fprintf( stderr, + "SalFrameData::HandleReparentEvent hDummy!=hRoot" + " r=%ld d=%ld p=%ld n=%d\n", + hRoot, hDummy, hWM_Parent, nChildren ); + pDisplay_->PrintEvent( "HandleReparentEvent", (XEvent*)pEvent ); + } +#endif +#ifdef NC_EVENTS + for( n = 0; n < nChildren; n++ ) + if( Children[n] != hShell_ && Children[n] != pEvent->parent ) + XSelectInput( pDisplay, Children[n], NC_EVENTS ); +#endif + XFree( Children ); + if( !XTranslateCoordinates( GetXDisplay(), + XtWindow( hShell_ ), + hWM_Parent, + 0, 0, + &nLeft_, &nTop_, + &hDummy ) ) + { + fprintf( stderr, "SalFramaData::HandleReparentEvent !XTranslateCoordinates\n" ); + abort(); + } + + nRight_ = nLeft_; // ??? + nBottom_ = nLeft_; // ??? + + // hack: maximize if vendor is XFREE (why? MB!), only remote client + + if( (aPosSize_.IsEmpty() || WindowNeedGoodPosition( XtWindow( hShell_ ) ) ) + && pDisplay_->GetProperties() & PROPERTY_FEATURE_Maximize ) + { + nShowState_ = SHOWSTATE_NORMAL; + Maximize(); + aRestoreMaximize_ = Rectangle(); // not a real maximize + } + else + { + // limit width and height if we are too large: #47757 + // olwm and fvwm need this, it doesnt harm the rest + + int nScreenWidth = pDisplay_->GetScreenSize().Width(); + int nScreenHeight = pDisplay_->GetScreenSize().Height(); + int nFrameWidth = aPosSize_.GetWidth() + nLeft_ + nRight_; + int nFrameHeight = aPosSize_.GetHeight() + nTop_ + nBottom_; + + if ((nFrameWidth > nScreenWidth) || (nFrameHeight > nScreenHeight)) + { + Size aSize(aPosSize_.GetWidth(), aPosSize_.GetHeight()); + + if (nFrameWidth > nScreenWidth) + aSize.Width() = nScreenWidth - nRight_ - nLeft_; + if (nFrameHeight > nScreenHeight) + aSize.Height() = nScreenHeight - nBottom_ - nTop_; + + SetSize (aSize); + } + } + + + return 1; +} + +// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +alpha long SalFrameData::HandleColormapEvent( XColormapEvent *pEvent ) +{ + return 0; +} + +// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +long SalFrameData::HandleStateEvent( XPropertyEvent *pEvent ) +{ + Atom actual_type; + int actual_format; + unsigned long nitems, bytes_after; + unsigned char *prop = NULL; + + if( 0 != XGetWindowProperty( GetXDisplay(), + XtWindow( hShell_ ), + pEvent->atom, // property + 0, // long_offset (32bit) + 2, // long_length (32bit) + False, // delete + pEvent->atom, // req_type + &actual_type, + &actual_format, + &nitems, + &bytes_after, + &prop ) + || ! prop + ) + return 0; + + DBG_ASSERT( actual_type = pEvent->atom + && 32 == actual_format + && 2 == nitems + && 0 == bytes_after, "HandleStateEvent" ) + + if( *(unsigned long*)prop == NormalState ) + nShowState_ = SHOWSTATE_NORMAL; + else if( *(unsigned long*)prop == IconicState ) + nShowState_ = SHOWSTATE_MINIMIZED; + + XFree( prop ); + return 1; +} + +// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +long SalFrameData::HandleClientMessage( XClientMessageEvent *pEvent ) +{ + SalICCCM &rICCCM = pDisplay_->GetICCCM(); + + if( rICCCM.IsUserEvent( pEvent->message_type ) ) + { +#if __SIZEOFLONG > 4 + void* pData = (void*) + ( (pEvent->data.l[0] & 0xffffffff) | (pEvent->data.l[1] << 32) ); +#else + void* pData = (void*)(pEvent->data.l[0]); +#endif + Call( SALEVENT_USEREVENT, pData ); + return 1; + } + else if( rICCCM.IsQuitEvent( pEvent->message_type ) ) + { + stderr0( "SalFrameData::Dispatch Quit\n" ); + Close(); // ??? + return 1; + } + else if( rICCCM.IsWM_Protocols( pEvent->message_type ) ) + { + if( rICCCM.IsWM_DeleteWindow( pEvent->data.l[0] ) ) + { + stderr0( "SalFrameData::Dispatch DeleteWindow\n" ); + Close(); + return 1; + } + else if( rICCCM.IsWM_SaveYourself( pEvent->data.l[0] ) ) + { + SalFrame* pLast = GetSalData()->pFirstFrame_; + while( pLast->maFrameData.pNextFrame_ ) + pLast = pLast->maFrameData.pNextFrame_; + if( pLast == pFrame_ ) + { + ByteString aExec( SessionManagerClient::getExecName(), gsl_getSystemTextEncoding() ); + char* argv[2]; + argv[0] = "/bin/sh"; + argv[1] = const_cast<char*>(aExec.GetBuffer()); + XSetCommand( GetXDisplay(), XtWindow( hShell_ ), argv, 2 ); + } + else + XDeleteProperty( GetXDisplay(), XtWindow( hShell_ ), rICCCM.aWM_Command_ ); + } + } + return 0; +} + +// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +Bool SalFrameData::checkKeyReleaseForRepeat( Display* pDisplay, XEvent* pCheck, XPointer pSalFrameData ) +{ + SalFrameData* pThis = (SalFrameData*)pSalFrameData; + return + pCheck->type == XLIB_KeyPress && + pCheck->xkey.state == pThis->nKeyState_ && + pCheck->xkey.keycode == pThis->nKeyCode_ && + pCheck->xkey.time == pThis->nReleaseTime_ ? True : False; +} + +long SalFrameData::Dispatch( XEvent *pEvent ) +{ + long nRet = 0; + + if( -1 == nCaptured_ ) + { + CaptureMouse( TRUE ); +#ifdef DBG_UTIL + if( -1 != nCaptured_ ) + pDisplay_->PrintEvent( "Captured", pEvent ); +#endif + } + + if( pEvent->xany.window == XtWindow( hShell_ ) || pEvent->xany.window == XtWindow( hComposite_ ) ) + { + switch( pEvent->type ) + { + case XLIB_KeyPress: + nKeyCode_ = pEvent->xkey.keycode; + nKeyState_ = pEvent->xkey.state; + nRet = HandleKeyEvent( &pEvent->xkey ); + break; + + case KeyRelease: + if( -1 == nCompose_ ) + { + nReleaseTime_ = pEvent->xkey.time; + XEvent aEvent; + if( XCheckIfEvent( pEvent->xkey.display, &aEvent, checkKeyReleaseForRepeat, (XPointer)this ) ) + XPutBackEvent( pEvent->xkey.display, &aEvent ); + else + nRet = HandleKeyEvent( &pEvent->xkey ); + } + break; + + case ButtonPress: + // #74406# if we loose the focus in presentation mode + // there are good chances that we never get it back + // since the WM ignores us + if( hNoFullscreenShell_ != None ) + { + XSetInputFocus( GetXDisplay(), GetShellWindow(), + RevertToNone, CurrentTime ); + } + + case ButtonRelease: + case MotionNotify: + case EnterNotify: + case LeaveNotify: + nRet = HandleMouseEvent( pEvent ); + break; + + case FocusIn: + case FocusOut: + nRet = HandleFocusEvent( &pEvent->xfocus ); + break; + + case Expose: + case GraphicsExpose: + nRet = HandleExposeEvent( pEvent ); + break; + + case MapNotify: + if( pEvent->xmap.window == XtWindow( hShell_ ) || + pEvent->xmap.window == XtWindow( hComposite_ ) ) + { + bMapped_ = TRUE; + bViewable_ = TRUE; + nRet = TRUE; + if ( mpInputContext != NULL ) + mpInputContext->Map( pFrame_ ); + Call( SALEVENT_RESIZE, NULL ); + } + break; + + case UnmapNotify: + if( pEvent->xunmap.window == XtWindow( hShell_ ) ) + { + bMapped_ = FALSE; + bViewable_ = FALSE; + nRet = TRUE; + if ( mpInputContext != NULL ) + mpInputContext->Unmap(); + Call( SALEVENT_RESIZE, NULL ); + } + break; + + case ConfigureNotify: + if( pEvent->xconfigure.window == XtWindow( hShell_ ) || + pEvent->xconfigure.window == XtWindow( hComposite_ ) ) + nRet = HandleSizeEvent( &pEvent->xconfigure ); + break; + + case VisibilityNotify: + nVisibility_ = pEvent->xvisibility.state; + nRet = TRUE; + break; + + case ReparentNotify: + nRet = HandleReparentEvent( &pEvent->xreparent ); + break; + + case MappingNotify: + if( MappingPointer != pEvent->xmapping.request ) + nRet = Call( SALEVENT_KEYBOARDCHANGED, 0 ); + break; + + case ColormapNotify: + nRet = HandleColormapEvent( &pEvent->xcolormap ); + break; + + case PropertyNotify: + { + SalICCCM &rICCCM = pDisplay_->GetICCCM(); + + if( rICCCM.IsWM_State( pEvent->xproperty.atom ) ) + nRet = HandleStateEvent( &pEvent->xproperty ); + else + nRet = 1; + break; + } + + case ClientMessage: + nRet = HandleClientMessage( &pEvent->xclient ); + break; + } + } + else + { + switch( pEvent->type ) + { +#ifdef NC_EVENTS + case XLIB_KeyPress: + case KeyRelease: + nRet = HandleNCKeyEvent() + break; + + case ButtonPress: + case ButtonRelease: + case MotionNotify: + case EnterNotify: + case LeaveNotify: + nRet = HandleNCMouseEvent( pEvent ); + break; + + case Expose: + nRet = HandleNCExposeEvent( pEvent ); + break; +#endif + case ConfigureNotify: + if( pEvent->xconfigure.window == hForeignParent_ || + pEvent->xconfigure.window == hForeignTopLevelWindow_ ) + nRet = HandleSizeEvent( &pEvent->xconfigure ); + break; + } + } + + // #74406# do not raise fullscreenwindow as it may override the + // screenlocker +#if 0 + if( bAlwaysOnTop_ + && nVisibility_ != VisibilityUnobscured + && pEvent->type != ConfigureNotify + && pEvent->type != MotionNotify ) + { + XRaiseWindow( GetXDisplay(), XtWindow( hShell_ ) ); + } +#endif + + + return nRet; +} + diff --git a/vcl/unx/source/window/salobj.cxx b/vcl/unx/source/window/salobj.cxx new file mode 100644 index 000000000000..56d2383d8928 --- /dev/null +++ b/vcl/unx/source/window/salobj.cxx @@ -0,0 +1,447 @@ +/************************************************************************* + * + * $RCSfile: salobj.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 17:05:48 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#define _SV_SALOBJ_CXX + +#include <prex.h> +#include <X11/Xlib.h> +#include <X11/extensions/shape.h> +#ifdef USE_MOTIF +#include <Xm/DrawingA.h> +#else +#include <X11/Xaw/Label.h> +#endif +#include <postx.h> + +#include <salunx.h> +#include <salstd.hxx> + +#ifndef _SV_SALDATA_HXX +#include <saldata.hxx> +#endif +#ifndef _SV_SALINST_HXX +#include <salinst.hxx> +#endif +#ifndef _SV_SALDISP_HXX +#include <saldisp.hxx> +#endif +#ifndef _SV_SALFRAME_HXX +#include <salframe.hxx> +#endif +#ifndef _SV_SALOBJ_HXX +#include <salobj.hxx> +#endif + +#ifdef USE_MOTIF +#define OBJECT_WIDGET_CLASS xmDrawingAreaWidgetClass +#else +#define OBJECT_WIDGET_CLASS labelWidgetClass +#endif + +SalObjectList SalObjectData::aAllObjects; + +// ======================================================================= + +long ImplSalObjCallbackDummy( void*, SalObject*, USHORT, const void* ) +{ + return 0; +} + +// ======================================================================= +// SalInstance memberfkts to create and destroy a SalObject + +SalObject* SalInstance::CreateObject( SalFrame* pParent ) +{ + int error_base, event_base; + SalObject* pObject = new SalObject; + SystemChildData* pObjData = const_cast<SystemChildData*>(pObject->GetSystemData()); + + if ( ! XShapeQueryExtension( (Display*)pObjData->pDisplay, + &event_base, &error_base ) ) + { + delete pObject; + return NULL; + } + + SalDisplay* pSalDisp = pParent->maFrameData.GetDisplay(); + Widget pWidgetParent = pParent->maFrameData.GetWidget(); + + pObject->maObjectData.maPrimary = + XtVaCreateManagedWidget( "salobject primary", + OBJECT_WIDGET_CLASS, + pWidgetParent, + NULL ); + pObject->maObjectData.maSecondary = + XtVaCreateManagedWidget( "salobject secondary", + OBJECT_WIDGET_CLASS, + pObject->maObjectData.maPrimary, + NULL ); + XtRealizeWidget( pObject->maObjectData.maPrimary ); + XtRealizeWidget( pObject->maObjectData.maSecondary ); + + pObjData->pDisplay = XtDisplay( pObject->maObjectData.maPrimary ); + pObjData->aWindow = XtWindow( pObject->maObjectData.maSecondary ); + pObjData->pWidget = pObject->maObjectData.maSecondary; + pObjData->pVisual = pSalDisp->GetVisual()->GetVisual(); + pObjData->nDepth = pSalDisp->GetVisual()->GetDepth(); + pObjData->aColormap = pSalDisp->GetColormap().GetXColormap(); + pObjData->pAppContext = pSalDisp->GetXLib()->GetAppContext(); + return pObject; +} + + +void SalInstance::DestroyObject( SalObject* pObject ) +{ + delete pObject; +} + + +// ====================================================================== +// SalClipRegion is a member of SalObject +// definition of SalClipRegion my be found in unx/inc/salobj.h + + +SalClipRegion::SalClipRegion() +{ + ClipRectangleList = NULL; + numClipRectangles = 0; + maxClipRectangles = 0; + nClipRegionType = SAL_OBJECT_CLIP_INCLUDERECTS; +} + + +SalClipRegion::~SalClipRegion() +{ + if ( ClipRectangleList ) + delete ClipRectangleList; +} + + +void +SalClipRegion::BeginSetClipRegion( ULONG nRects ) +{ + if (ClipRectangleList) + delete ClipRectangleList; + + ClipRectangleList = new XRectangle[nRects]; + numClipRectangles = 0; + maxClipRectangles = nRects; +} + + +void +SalClipRegion::UnionClipRegion( long nX, long nY, long nWidth, long nHeight ) +{ + if ( nWidth && nHeight && (numClipRectangles < maxClipRectangles) ) + { + XRectangle *aRect = ClipRectangleList + numClipRectangles; + + aRect->x = (short) nX; + aRect->y = (short) nY; + aRect->width = (unsigned short) nWidth; + aRect->height= (unsigned short) nHeight; + + numClipRectangles++; + } +} + + +// ======================================================================= +// SalObject Implementation + + +SalObject::SalObject() +{ + maObjectData.maSystemChildData.nSize = sizeof( SystemChildData ); + maObjectData.maSystemChildData.pDisplay = GetSalData()->GetDefDisp()->GetDisplay(); + maObjectData.maSystemChildData.aWindow = None; + maObjectData.maSystemChildData.pSalFrame = 0; + maObjectData.maSystemChildData.pWidget = 0; + maObjectData.maSystemChildData.pVisual = 0; + maObjectData.maSystemChildData.nDepth = 0; + maObjectData.maSystemChildData.aColormap = 0; + + maObjectData.mpInst = NULL; + maObjectData.mpProc = ImplSalObjCallbackDummy; + maObjectData.maPrimary = NULL; + maObjectData.maSecondary = NULL; + + SalObjectData::aAllObjects.Insert( this, LIST_APPEND ); +} + + +SalObject::~SalObject() +{ + SalObjectData::aAllObjects.Remove( this ); + if ( maObjectData.maPrimary ) + XtDestroyWidget ( maObjectData.maPrimary ); + if ( maObjectData.maSecondary ) + XtDestroyWidget ( maObjectData.maSecondary ); +} + + +void +SalObject::ResetClipRegion() +{ + maObjectData.maClipRegion.ResetClipRegion(); + + const int dest_kind = ShapeBounding; + const int op = ShapeSet; + const int ordering = YSorted; + + XWindowAttributes win_attrib; + XRectangle win_size; + + XGetWindowAttributes ( (Display*)maObjectData.maSystemChildData.pDisplay, + maObjectData.maSystemChildData.aWindow, + &win_attrib ); + + win_size.x = 0; + win_size.y = 0; + win_size.width = win_attrib.width; + win_size.height = win_attrib.width; + + XShapeCombineRectangles ( (Display*)maObjectData.maSystemChildData.pDisplay, + maObjectData.maSystemChildData.aWindow, + dest_kind, + 0, 0, // x_off, y_off + &win_size, // list of rectangles + 1, // number of rectangles + op, ordering ); +} + + +void +SalObject::BeginSetClipRegion( ULONG nRectCount ) +{ + maObjectData.maClipRegion.BeginSetClipRegion ( nRectCount ); +} + + +void +SalObject::UnionClipRegion( long nX, long nY, long nWidth, long nHeight ) +{ + maObjectData.maClipRegion.UnionClipRegion ( nX, nY, nWidth, nHeight ); +} + + +void +SalObject::EndSetClipRegion() +{ + XRectangle *pRectangles = maObjectData.maClipRegion.EndSetClipRegion (); + const int nType = maObjectData.maClipRegion.GetClipRegionType(); + const int nRectangles = maObjectData.maClipRegion.GetRectangleCount(); + + const int dest_kind = ShapeBounding; + const int ordering = YSorted; + int op; + + switch ( nType ) + { + case SAL_OBJECT_CLIP_INCLUDERECTS : + op = ShapeSet; + break; + case SAL_OBJECT_CLIP_EXCLUDERECTS : + op = ShapeSubtract; + break; + case SAL_OBJECT_CLIP_ABSOLUTE : + op = ShapeSet; + break; + default : + op = ShapeUnion; + } + + XShapeCombineRectangles ( (Display*)maObjectData.maSystemChildData.pDisplay, + maObjectData.maSystemChildData.aWindow, + dest_kind, + 0, 0, // x_off, y_off + pRectangles, + nRectangles, + op, ordering ); +} + + +USHORT +SalObject::GetClipRegionType() +{ + return maObjectData.maClipRegion.GetClipRegionType(); +} + +// ----------------------------------------------------------------------- + +void +SalObject::SetPosSize( long nX, long nY, long nWidth, long nHeight ) +{ + if ( maObjectData.maPrimary && maObjectData.maSecondary && nWidth && nHeight ) + { + XtConfigureWidget( maObjectData.maPrimary, + nX, nY, nWidth, nHeight, 0 ); + XtConfigureWidget( maObjectData.maSecondary, + 0, 0, nWidth, nHeight, 0 ); + } +} + + +void +SalObject::Show( BOOL bVisible ) +{ + if ( ! maObjectData.maSystemChildData.aWindow ) + return; + + if ( bVisible ) + XtMapWidget( (Widget)maObjectData.maPrimary ); + else + XtUnmapWidget( (Widget)maObjectData.maPrimary ); + + maObjectData.mbVisible = bVisible; +} + +// ----------------------------------------------------------------------- + +void SalObject::Enable( BOOL bEnable ) +{ +} + +// ----------------------------------------------------------------------- + +void SalObject::GrabFocus() +{ + if( maObjectData.mbVisible ) + XSetInputFocus( (Display*)maObjectData.maSystemChildData.pDisplay, + maObjectData.maSystemChildData.aWindow, + RevertToNone, + CurrentTime ); +} + +// ----------------------------------------------------------------------- + +void SalObject::SetBackground() +{ +} + +// ----------------------------------------------------------------------- + +void SalObject::SetBackground( SalColor nSalColor ) +{ +} + +// ----------------------------------------------------------------------- + +const SystemChildData* SalObject::GetSystemData() const +{ + return &maObjectData.maSystemChildData; +} + +// ----------------------------------------------------------------------- + +void SalObject::SetCallback( void* pInst, SALOBJECTPROC pProc ) +{ + maObjectData.mpInst = pInst; + if ( pProc ) + maObjectData.mpProc = pProc; + else + maObjectData.mpProc = ImplSalObjCallbackDummy; +} + +long SalObjectData::Dispatch( XEvent* pEvent ) +{ + for( int n= 0; n < aAllObjects.Count(); n++ ) + { + SalObject* pObject = aAllObjects.GetObject( n ); + if( pEvent->xany.window == XtWindow( pObject->maObjectData.maPrimary ) || + pEvent->xany.window == XtWindow( pObject->maObjectData.maSecondary ) ) + { + switch( pEvent->type ) + { + case UnmapNotify: + pObject->maObjectData.mbVisible = FALSE; + return 1; + case MapNotify: + pObject->maObjectData.mbVisible = TRUE; + return 1; + case ButtonPress: + pObject->maObjectData.mpProc( + pObject->maObjectData.mpInst, + pObject, + SALOBJ_EVENT_TOTOP, + NULL ); + return 1; + case FocusIn: + pObject->maObjectData.mpProc( + pObject->maObjectData.mpInst, + pObject, + SALOBJ_EVENT_GETFOCUS, + NULL ); + return 1; + case FocusOut: + pObject->maObjectData.mpProc( + pObject->maObjectData.mpInst, + pObject, + SALOBJ_EVENT_LOSEFOCUS, + NULL ); + return 1; + default: break; + } + return 0; + } + } + return 0; +} |