summaryrefslogtreecommitdiff
path: root/vcl/unx/source/window
diff options
context:
space:
mode:
Diffstat (limited to 'vcl/unx/source/window')
-rw-r--r--vcl/unx/source/window/FWS.cxx314
-rw-r--r--vcl/unx/source/window/FWS.hxx98
-rw-r--r--vcl/unx/source/window/makefile.mk97
-rw-r--r--vcl/unx/source/window/salframe.cxx2614
-rw-r--r--vcl/unx/source/window/salobj.cxx447
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;
+}