summaryrefslogtreecommitdiff
path: root/vcl/win/source
diff options
context:
space:
mode:
Diffstat (limited to 'vcl/win/source')
-rw-r--r--vcl/win/source/app/MAKEFILE.MK40
-rw-r--r--vcl/win/source/app/saldata.cxx267
-rw-r--r--vcl/win/source/app/salinfo.cxx884
-rw-r--r--vcl/win/source/app/salinst.cxx897
-rw-r--r--vcl/win/source/app/salshl.cxx198
-rw-r--r--vcl/win/source/app/saltimer.cxx152
-rw-r--r--vcl/win/source/gdi/MAKEFILE.MK52
-rw-r--r--vcl/win/source/gdi/salbmp.cxx668
-rw-r--r--vcl/win/source/gdi/salgdi.cxx1449
-rw-r--r--vcl/win/source/gdi/salgdi2.cxx782
-rw-r--r--vcl/win/source/gdi/salgdi3.cxx1531
-rw-r--r--vcl/win/source/gdi/salogl.cxx329
-rw-r--r--vcl/win/source/gdi/salprn.cxx1424
-rw-r--r--vcl/win/source/gdi/salvd.cxx226
-rw-r--r--vcl/win/source/gdi/wntgdi.cxx92
-rw-r--r--vcl/win/source/src/50.bmpbin0 -> 94 bytes
-rw-r--r--vcl/win/source/src/MAKEFILE.MK106
-rw-r--r--vcl/win/source/src/airbrush.curbin0 -> 326 bytes
-rwxr-xr-xvcl/win/source/src/ase.curbin0 -> 326 bytes
-rwxr-xr-xvcl/win/source/src/asn.curbin0 -> 326 bytes
-rwxr-xr-xvcl/win/source/src/asne.curbin0 -> 326 bytes
-rwxr-xr-xvcl/win/source/src/asns.curbin0 -> 326 bytes
-rwxr-xr-xvcl/win/source/src/asnswe.curbin0 -> 326 bytes
-rwxr-xr-xvcl/win/source/src/asnw.curbin0 -> 326 bytes
-rwxr-xr-xvcl/win/source/src/ass.curbin0 -> 326 bytes
-rwxr-xr-xvcl/win/source/src/asse.curbin0 -> 326 bytes
-rwxr-xr-xvcl/win/source/src/assw.curbin0 -> 326 bytes
-rwxr-xr-xvcl/win/source/src/asw.curbin0 -> 326 bytes
-rwxr-xr-xvcl/win/source/src/aswe.curbin0 -> 326 bytes
-rwxr-xr-xvcl/win/source/src/chain.curbin0 -> 326 bytes
-rwxr-xr-xvcl/win/source/src/chainnot.curbin0 -> 326 bytes
-rw-r--r--vcl/win/source/src/chart.curbin0 -> 326 bytes
-rw-r--r--vcl/win/source/src/copydata.curbin0 -> 326 bytes
-rw-r--r--vcl/win/source/src/copydlnk.curbin0 -> 326 bytes
-rw-r--r--vcl/win/source/src/copyf.curbin0 -> 326 bytes
-rw-r--r--vcl/win/source/src/copyf2.curbin0 -> 326 bytes
-rw-r--r--vcl/win/source/src/copyflnk.curbin0 -> 326 bytes
-rw-r--r--vcl/win/source/src/crook.curbin0 -> 326 bytes
-rw-r--r--vcl/win/source/src/crop.curbin0 -> 326 bytes
-rw-r--r--vcl/win/source/src/cross.curbin0 -> 326 bytes
-rw-r--r--vcl/win/source/src/darc.curbin0 -> 326 bytes
-rw-r--r--vcl/win/source/src/dbezier.curbin0 -> 326 bytes
-rw-r--r--vcl/win/source/src/dcapt.curbin0 -> 326 bytes
-rw-r--r--vcl/win/source/src/dcirccut.curbin0 -> 326 bytes
-rw-r--r--vcl/win/source/src/dconnect.curbin0 -> 326 bytes
-rw-r--r--vcl/win/source/src/dellipse.curbin0 -> 326 bytes
-rw-r--r--vcl/win/source/src/detectiv.curbin0 -> 326 bytes
-rw-r--r--vcl/win/source/src/dfree.curbin0 -> 326 bytes
-rw-r--r--vcl/win/source/src/dline.curbin0 -> 326 bytes
-rw-r--r--vcl/win/source/src/dpie.curbin0 -> 326 bytes
-rw-r--r--vcl/win/source/src/dpolygon.curbin0 -> 326 bytes
-rw-r--r--vcl/win/source/src/drect.curbin0 -> 326 bytes
-rw-r--r--vcl/win/source/src/dtext.curbin0 -> 326 bytes
-rw-r--r--vcl/win/source/src/fill.curbin0 -> 326 bytes
-rw-r--r--vcl/win/source/src/hand.curbin0 -> 326 bytes
-rw-r--r--vcl/win/source/src/help.curbin0 -> 326 bytes
-rw-r--r--vcl/win/source/src/hshear.curbin0 -> 326 bytes
-rw-r--r--vcl/win/source/src/hsize.curbin0 -> 326 bytes
-rw-r--r--vcl/win/source/src/hsizebar.curbin0 -> 326 bytes
-rw-r--r--vcl/win/source/src/hsplit.curbin0 -> 326 bytes
-rw-r--r--vcl/win/source/src/linkdata.curbin0 -> 326 bytes
-rw-r--r--vcl/win/source/src/linkf.curbin0 -> 326 bytes
-rw-r--r--vcl/win/source/src/mirror.curbin0 -> 326 bytes
-rw-r--r--vcl/win/source/src/move.curbin0 -> 326 bytes
-rw-r--r--vcl/win/source/src/movebw.curbin0 -> 326 bytes
-rw-r--r--vcl/win/source/src/movedata.curbin0 -> 326 bytes
-rw-r--r--vcl/win/source/src/movedlnk.curbin0 -> 326 bytes
-rw-r--r--vcl/win/source/src/movef.curbin0 -> 326 bytes
-rw-r--r--vcl/win/source/src/movef2.curbin0 -> 326 bytes
-rw-r--r--vcl/win/source/src/moveflnk.curbin0 -> 326 bytes
-rw-r--r--vcl/win/source/src/movept.curbin0 -> 326 bytes
-rw-r--r--vcl/win/source/src/neswsize.curbin0 -> 326 bytes
-rw-r--r--vcl/win/source/src/notallow.curbin0 -> 326 bytes
-rw-r--r--vcl/win/source/src/nullptr.curbin0 -> 326 bytes
-rw-r--r--vcl/win/source/src/nwsesize.curbin0 -> 326 bytes
-rw-r--r--vcl/win/source/src/pen.curbin0 -> 326 bytes
-rw-r--r--vcl/win/source/src/refhand.curbin0 -> 326 bytes
-rw-r--r--vcl/win/source/src/rotate.curbin0 -> 326 bytes
-rw-r--r--vcl/win/source/src/salsrc.rc148
-rw-r--r--vcl/win/source/src/sd.icobin0 -> 3310 bytes
-rwxr-xr-xvcl/win/source/src/timemove.curbin0 -> 326 bytes
-rwxr-xr-xvcl/win/source/src/timesize.curbin0 -> 326 bytes
-rw-r--r--vcl/win/source/src/vshear.curbin0 -> 326 bytes
-rw-r--r--vcl/win/source/src/vsize.curbin0 -> 326 bytes
-rw-r--r--vcl/win/source/src/vsizebar.curbin0 -> 326 bytes
-rw-r--r--vcl/win/source/src/vsplit.curbin0 -> 326 bytes
-rw-r--r--vcl/win/source/window/MAKEFILE.MK38
-rw-r--r--vcl/win/source/window/salframe.cxx3901
-rw-r--r--vcl/win/source/window/salobj.cxx873
89 files changed, 14057 insertions, 0 deletions
diff --git a/vcl/win/source/app/MAKEFILE.MK b/vcl/win/source/app/MAKEFILE.MK
new file mode 100644
index 000000000000..f53f534b69a1
--- /dev/null
+++ b/vcl/win/source/app/MAKEFILE.MK
@@ -0,0 +1,40 @@
+#*************************************************************************
+#*
+#* $Workfile: makefile. $
+#*
+#* Ersterstellung TH 01.04.97
+#* Letzte Aenderung $Author: hr $ $Date: 2000-09-18 17:05:49 $
+#* $Revision: 1.1.1.1 $
+#*
+#* $Logfile: T:/sv2/win/source/app/makefile.__v $
+#*
+#* Copyright (c) 1990 - 2000, STAR DIVISION
+#*
+#*************************************************************************
+
+PRJ=..$/..$/..
+
+PRJNAME=vcl
+TARGET=salapp
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : svpre.mk
+.INCLUDE : settings.mk
+.INCLUDE : sv.mk
+
+# --- Files --------------------------------------------------------
+
+OBJFILES= $(OBJ)$/salmain.obj
+
+SLOFILES= $(SLO)$/salshl.obj \
+ $(SLO)$/saldata.obj \
+ $(SLO)$/salinst.obj \
+ $(SLO)$/saltimer.obj \
+ $(SLO)$/salsound.obj \
+ $(SLO)$/salinfo.obj \
+ $(SLO)$/salsys.obj
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
diff --git a/vcl/win/source/app/saldata.cxx b/vcl/win/source/app/saldata.cxx
new file mode 100644
index 000000000000..7142badf3a20
--- /dev/null
+++ b/vcl/win/source/app/saldata.cxx
@@ -0,0 +1,267 @@
+/*************************************************************************
+ *
+ * $RCSfile: saldata.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:49 $
+ *
+ * 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 _SVWIN_H
+#include <tools/svwin.h>
+#endif
+
+#define _SV_SALDATA_CXX
+
+#ifndef _SV_SALDATA_HXX
+#include <saldata.hxx>
+#endif
+
+// =======================================================================
+
+rtl_TextEncoding ImplSalGetSystemEncoding()
+{
+ static UINT nOldAnsiCodePage = 0;
+ static rtl_TextEncoding eEncoding = RTL_TEXTENCODING_MS_1252;
+
+ UINT nAnsiCodePage = GetACP();
+ if ( nAnsiCodePage != nOldAnsiCodePage )
+ {
+ switch ( nAnsiCodePage )
+ {
+ case 1252:
+ eEncoding = RTL_TEXTENCODING_MS_1252;
+ break;
+ case 1250:
+ eEncoding = RTL_TEXTENCODING_MS_1250;
+ break;
+ case 1251:
+ eEncoding = RTL_TEXTENCODING_MS_1251;
+ break;
+ case 1253:
+ eEncoding = RTL_TEXTENCODING_MS_1253;
+ break;
+ case 1254:
+ eEncoding = RTL_TEXTENCODING_MS_1254;
+ break;
+ case 1255:
+ eEncoding = RTL_TEXTENCODING_MS_1255;
+ break;
+ case 1256:
+ eEncoding = RTL_TEXTENCODING_MS_1256;
+ break;
+ case 1257:
+ eEncoding = RTL_TEXTENCODING_MS_1257;
+ break;
+ case 1258:
+ eEncoding = RTL_TEXTENCODING_MS_1258;
+ break;
+ case 874:
+ eEncoding = RTL_TEXTENCODING_MS_874;
+ break;
+ case 932:
+ eEncoding = RTL_TEXTENCODING_MS_932;
+ break;
+ case 936:
+ eEncoding = RTL_TEXTENCODING_MS_936;
+ break;
+ case 949:
+ eEncoding = RTL_TEXTENCODING_MS_949;
+ break;
+ case 950:
+ eEncoding = RTL_TEXTENCODING_MS_950;
+ break;
+// case 1381:
+// eEncoding = RTL_TEXTENCODING_MS_1381;
+// break;
+ }
+ }
+
+ return eEncoding;
+}
+
+// -----------------------------------------------------------------------
+
+ByteString ImplSalGetWinAnsiString( const UniString& rStr, BOOL bFileName )
+{
+ rtl_TextEncoding eEncoding = ImplSalGetSystemEncoding();
+ if ( bFileName )
+ {
+ return ByteString( rStr, eEncoding,
+ RTL_UNICODETOTEXT_FLAGS_UNDEFINED_UNDERLINE |
+ RTL_UNICODETOTEXT_FLAGS_INVALID_UNDERLINE |
+ RTL_UNICODETOTEXT_FLAGS_UNDEFINED_REPLACE |
+ RTL_UNICODETOTEXT_FLAGS_UNDEFINED_REPLACESTR |
+ RTL_UNICODETOTEXT_FLAGS_PRIVATE_MAPTO0 );
+ }
+ else
+ {
+ return ByteString( rStr, eEncoding,
+ RTL_UNICODETOTEXT_FLAGS_UNDEFINED_DEFAULT |
+ RTL_UNICODETOTEXT_FLAGS_INVALID_DEFAULT |
+ RTL_UNICODETOTEXT_FLAGS_UNDEFINED_REPLACE |
+ RTL_UNICODETOTEXT_FLAGS_UNDEFINED_REPLACESTR |
+ RTL_UNICODETOTEXT_FLAGS_PRIVATE_MAPTO0 );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+UniString ImplSalGetUniString( const sal_Char* pStr, xub_StrLen nLen )
+{
+ return UniString( pStr, nLen, ImplSalGetSystemEncoding(),
+ RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_DEFAULT |
+ RTL_TEXTTOUNICODE_FLAGS_MBUNDEFINED_DEFAULT |
+ RTL_TEXTTOUNICODE_FLAGS_INVALID_DEFAULT );
+}
+
+// =======================================================================
+
+int ImplSalWICompareAscii( const wchar_t* pStr1, const char* pStr2 )
+{
+ int nRet;
+ wchar_t c1;
+ char c2;
+ do
+ {
+ // Ist das Zeichen zwischen 'A' und 'Z' dann umwandeln
+ c1 = *pStr1;
+ c2 = *pStr2;
+ if ( (c1 >= 65) && (c1 <= 90) )
+ c1 += 32;
+ if ( (c2 >= 65) && (c2 <= 90) )
+ c2 += 32;
+ nRet = ((sal_Int32)c1)-((sal_Int32)((unsigned char)c2));
+ if ( nRet != 0 )
+ break;
+
+ pStr1++;
+ pStr2++;
+ }
+ while ( c2 );
+
+ return nRet;
+}
+
+// =======================================================================
+
+LONG ImplSetWindowLong( HWND hWnd, int nIndex, DWORD dwNewLong )
+{
+ if ( aSalShlData.mbWNT )
+ return SetWindowLongW( hWnd, nIndex, dwNewLong );
+ else
+ return SetWindowLongA( hWnd, nIndex, dwNewLong );
+}
+
+// -----------------------------------------------------------------------
+
+LONG ImplGetWindowLong( HWND hWnd, int nIndex )
+{
+ if ( aSalShlData.mbWNT )
+ return GetWindowLongW( hWnd, nIndex );
+ else
+ return GetWindowLongA( hWnd, nIndex );
+}
+
+// -----------------------------------------------------------------------
+
+WIN_BOOL ImplPostMessage( HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam )
+{
+ if ( aSalShlData.mbWNT )
+ return PostMessageW( hWnd, nMsg, wParam, lParam );
+ else
+ return PostMessageA( hWnd, nMsg, wParam, lParam );
+}
+
+// -----------------------------------------------------------------------
+
+WIN_BOOL ImplSendMessage( HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam )
+{
+ if ( aSalShlData.mbWNT )
+ return SendMessageW( hWnd, nMsg, wParam, lParam );
+ else
+ return SendMessageA( hWnd, nMsg, wParam, lParam );
+}
+
+// -----------------------------------------------------------------------
+
+WIN_BOOL ImplGetMessage( LPMSG lpMsg, HWND hWnd, UINT wMsgFilterMin, UINT wMsgFilterMax )
+{
+ if ( aSalShlData.mbWNT )
+ return GetMessageW( lpMsg, hWnd, wMsgFilterMin, wMsgFilterMax );
+ else
+ return GetMessageA( lpMsg, hWnd, wMsgFilterMin, wMsgFilterMax );
+}
+
+// -----------------------------------------------------------------------
+
+WIN_BOOL ImplPeekMessage( LPMSG lpMsg, HWND hWnd, UINT wMsgFilterMin, UINT wMsgFilterMax, UINT wRemoveMsg )
+{
+ if ( aSalShlData.mbWNT )
+ return PeekMessageW( lpMsg, hWnd, wMsgFilterMin, wMsgFilterMax, wRemoveMsg );
+ else
+ return PeekMessageA( lpMsg, hWnd, wMsgFilterMin, wMsgFilterMax, wRemoveMsg );
+}
+
+// -----------------------------------------------------------------------
+
+LONG ImplDispatchMessage( CONST MSG *lpMsg )
+{
+ if ( aSalShlData.mbWNT )
+ return DispatchMessageW( lpMsg );
+ else
+ return DispatchMessageA( lpMsg );
+}
+
diff --git a/vcl/win/source/app/salinfo.cxx b/vcl/win/source/app/salinfo.cxx
new file mode 100644
index 000000000000..97a3b0c97e35
--- /dev/null
+++ b/vcl/win/source/app/salinfo.cxx
@@ -0,0 +1,884 @@
+/*************************************************************************
+ *
+ * $RCSfile: salinfo.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:49 $
+ *
+ * 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): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef ENABLEUNICODE
+
+#define VCL_NEED_BASETSD
+
+#include <tools/presys.h>
+#include <windows.h>
+#include <imagehlp.h>
+#include <tools/postsys.h>
+
+#include <salsys.hxx>
+
+/* !!! UNICODE !!! */
+XubString SalSystem::GetSummarySystemInfos( ULONG nFlags )
+{
+ return XubString();
+}
+
+#else
+
+#define VCL_NEED_BASETSD
+
+#include <tools/presys.h>
+#include <windows.h>
+#include <imagehlp.h>
+#include <tools/postsys.h>
+
+#include <stdio.h>
+#include <tools/string.hxx>
+#include <salsys.hxx>
+
+// Wegen Stacktrace-Generierung
+#pragma optimize ("", off)
+
+// #include <tlhelp32.h>
+// ToolHelp32
+#define MAX_MODULE_NAME32 255
+#define TH32CS_SNAPMODULE 0x00000008
+
+typedef struct tagMODULEENTRY32
+{
+ DWORD dwSize;
+ DWORD th32ModuleID; // This module
+ DWORD th32ProcessID; // owning process
+ DWORD GlblcntUsage; // Global usage count on the module
+ DWORD ProccntUsage; // Module usage count in th32ProcessID's context
+ BYTE * modBaseAddr; // Base address of module in th32ProcessID's context
+ DWORD modBaseSize; // Size in bytes of module starting at modBaseAddr
+ HMODULE hModule; // The hModule of this module in th32ProcessID's context
+ char szModule[MAX_MODULE_NAME32 + 1];
+ char szExePath[MAX_PATH];
+} MODULEENTRY32;
+typedef MODULEENTRY32 * PMODULEENTRY32;
+typedef MODULEENTRY32 * LPMODULEENTRY32;
+
+// PSAPI functions - Windows NT only
+typedef struct _MODULEINFO {
+ LPVOID lpBaseOfDll;
+ DWORD SizeOfImage;
+ LPVOID EntryPoint;
+} MODULEINFO, *LPMODULEINFO;
+
+
+
+// PSAPI
+typedef BOOL (WINAPI *ENUMPROCESSMODULESPROC)( HANDLE hProcess, HMODULE* lphModule, DWORD cb, LPDWORD lpcbNeeded );
+typedef BOOL (WINAPI *GETMODULEINFORMATIONPROC)( HANDLE hProcess, HMODULE hModule, LPMODULEINFO lpmodinfo, DWORD cb );
+typedef DWORD (WINAPI *GETMODULEBASENAMEAPROC)( HANDLE hProcess, HMODULE hModule, LPSTR lpBaseName, DWORD nSize );
+typedef DWORD (WINAPI *GETMODULEFILENAMEEXAPROC)( HANDLE hProcess, HMODULE hModule, LPSTR lpFilename, DWORD nSize );
+typedef HANDLE (WINAPI *CREATESNAPSHOTPROC)(DWORD dwFlags, DWORD th32ProcessID);
+typedef BOOL (WINAPI *MODULE32FIRSTPROC)( HANDLE hSnapshot, LPMODULEENTRY32 lpme );
+typedef BOOL (WINAPI *MODULE32NEXTPROC)( HANDLE hSnapshot, LPMODULEENTRY32 lpme );
+
+
+// ImageHlp
+typedef int (__stdcall *STACKWALKPROC) ( DWORD, HANDLE, HANDLE, LPSTACKFRAME, PVOID, PREAD_PROCESS_MEMORY_ROUTINE,PFUNCTION_TABLE_ACCESS_ROUTINE, PGET_MODULE_BASE_ROUTINE, PTRANSLATE_ADDRESS_ROUTINE );
+typedef LPVOID (__stdcall *SYMFUNCTIONTABLEACCESSPROC)( HANDLE, DWORD );
+typedef DWORD (__stdcall *SYMGETMODULEBASEPROC)( HANDLE, DWORD );
+typedef DWORD (__stdcall *SYMSETOPTIONSPROC ) (DWORD dwSymOptions);
+typedef int (__stdcall *SYMINITIALIZEPROC ) ( HANDLE, LPSTR, int );
+typedef int (__stdcall *SYMCLEANUPPROC)( HANDLE );
+typedef DWORD (__stdcall WINAPI *UNDECORATESYMBOLNAMEPROC)( PCSTR, PSTR, DWORD, DWORD );
+typedef DWORD (__stdcall *SYMLOADMODULEPROC) ( HANDLE, HANDLE, LPSTR, LPSTR, DWORD, DWORD );
+typedef int (__stdcall *SYMGETSYMFROMADDR)( HANDLE, DWORD, PDWORD, PIMAGEHLP_SYMBOL );
+
+
+struct ModuleInfo
+{
+ struct ModuleInfo* pNext;
+
+ char szModBaseName[MAX_PATH];
+ char szModFileName[MAX_PATH];
+ unsigned long nBaseAddress;
+ unsigned long nSize;
+// unsigned long nEntryPoint;
+// HANDLE nHandle;
+// PIMAGE_DEBUG_INFORMATION pDebugInfos;
+};
+
+struct ModuleInfo* FindModuleContainingAddress( struct ModuleInfo* pStart, void* pAddr );
+
+
+
+struct SystemInfos
+{
+ DWORD nCurrentProcessId;
+ HANDLE hCurrentProcess;
+ DWORD nCurrentThreadId;
+ HANDLE hCurrentThread;
+
+ ModuleInfo* pModInfos;
+
+ String aStack;
+ String aModules;
+ String aSystemVersion;
+ String aCPUType;
+ String aMemoryInfo;
+ String aLocalVolumes;
+ String aSystemDirs;
+ String aMouseInfo;
+
+ SystemInfos()
+ {
+ nCurrentProcessId = 0;
+ hCurrentProcess = 0;
+ hCurrentThread = 0;
+ pModInfos = NULL;
+ }
+};
+
+void DebugThread( SystemInfos* pSysInfos );
+
+
+typedef struct _Thread
+{
+ DWORD dwThreadId;
+ HANDLE hThread;
+} Thread;
+
+
+struct ModuleInfo* WNT_CreateModuleInfos();
+
+String ImplCreateToken( const String& rToken )
+{
+ String aToken( '<' );
+ aToken += rToken;
+ aToken += ' ';
+ while ( aToken.Len() < 25 )
+ aToken += '-';
+ aToken += '>';
+ return aToken;
+}
+
+
+
+String WNT_CreateModulePath( struct ModuleInfo* pModInfos )
+{
+ String aPath;
+ struct ModuleInfo* pM = pModInfos;
+ while ( pM )
+ {
+ String aTmpPath = pM->szModFileName;
+ USHORT n = aTmpPath.SearchBackward( '\\' );
+ if ( n != STRING_NOTFOUND )
+ aTmpPath.Erase( n );
+ aTmpPath += ';';
+ aTmpPath.ToLower();
+ if ( aPath.Search( aTmpPath ) == STRING_NOTFOUND )
+ aPath += aTmpPath;
+
+ pM = pM->pNext;
+ }
+ return aPath;
+}
+
+
+struct ModuleInfo* WNT_CreateModuleInfos()
+{
+ struct ModuleInfo* pModInfos = NULL;
+
+ OSVERSIONINFO aOSVersion;
+ aOSVersion.dwOSVersionInfoSize = sizeof( OSVERSIONINFO );
+ if ( GetVersionEx( &aOSVersion ) )
+ {
+ if ( aOSVersion.dwPlatformId == VER_PLATFORM_WIN32_NT )
+ {
+ HINSTANCE hPSAPILib = LoadLibrary( "PSAPI.DLL" );
+ if( hPSAPILib )
+ {
+ ENUMPROCESSMODULESPROC _fpEnumProcessModules = (ENUMPROCESSMODULESPROC) GetProcAddress( hPSAPILib, "EnumProcessModules" );
+ GETMODULEINFORMATIONPROC _fpGetModuleInformation = (GETMODULEINFORMATIONPROC) GetProcAddress( hPSAPILib, "GetModuleInformation" );
+ GETMODULEBASENAMEAPROC _fpGetModuleBaseNameA = (GETMODULEBASENAMEAPROC) GetProcAddress( hPSAPILib, "GetModuleBaseNameA" );
+ GETMODULEFILENAMEEXAPROC _fpGetModuleFileNameExA = (GETMODULEFILENAMEEXAPROC) GetProcAddress( hPSAPILib, "GetModuleFileNameExA" );
+
+ HANDLE hProcess = GetCurrentProcess();
+ HMODULE hMods[1024];
+ DWORD cbNeeded;
+ if( _fpEnumProcessModules( hProcess, hMods, sizeof(hMods), &cbNeeded ) )
+ {
+ int nMods = cbNeeded / sizeof( HMODULE );
+ int nArrSz = nMods * sizeof( struct ModuleInfo );
+ pModInfos = (struct ModuleInfo*) malloc( nArrSz );
+ memset( pModInfos, 0, nArrSz );
+
+ for ( int i = 0; i < nMods; i++ )
+ {
+ pModInfos[i].pNext = 0;
+ if ( i )
+ pModInfos[i-1].pNext = &pModInfos[i];
+
+ _fpGetModuleBaseNameA( hProcess, hMods[i], pModInfos[i].szModBaseName, sizeof( pModInfos[i].szModBaseName ) );
+ _fpGetModuleFileNameExA( hProcess, hMods[i], pModInfos[i].szModFileName, sizeof( pModInfos[i].szModFileName ) );
+
+ MODULEINFO aInf;
+ if ( _fpGetModuleInformation( hProcess, hMods[i], &aInf, sizeof( aInf ) ) )
+ {
+ pModInfos[i].nBaseAddress = (unsigned long) aInf.lpBaseOfDll;
+ pModInfos[i].nSize = aInf.SizeOfImage;
+ // pModInfos[i].nEntryPoint = (unsigned long) aInf.EntryPoint;
+ }
+ }
+ }
+ FreeLibrary( hPSAPILib );
+ }
+ }
+ else if ( aOSVersion.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS )
+ {
+ HINSTANCE hToolHelpLib = LoadLibrary( "KERNEL32.DLL" );
+ if( hToolHelpLib )
+ {
+ CREATESNAPSHOTPROC _fpCreateSnapshot = (CREATESNAPSHOTPROC) GetProcAddress( hToolHelpLib, "CreateToolhelp32Snapshot" );
+ MODULE32FIRSTPROC _fpModule32First = (MODULE32FIRSTPROC) GetProcAddress( hToolHelpLib, "Module32First" );
+ MODULE32NEXTPROC _fpModule32Next = (MODULE32NEXTPROC) GetProcAddress( hToolHelpLib, "Module32Next" );
+
+ HANDLE hSnap = _fpCreateSnapshot( TH32CS_SNAPMODULE, 0 );
+ if ( hSnap )
+ {
+ MODULEENTRY32 aMod32Entry;
+ ZeroMemory( &aMod32Entry, sizeof( MODULEENTRY32 ) );
+ aMod32Entry.dwSize = sizeof( MODULEENTRY32 );
+ int nMods = 0;
+ BOOL bMod = _fpModule32First( hSnap, &aMod32Entry );
+ while ( bMod )
+ {
+ nMods++;
+ bMod = _fpModule32Next( hSnap, &aMod32Entry );
+ }
+
+ int nArrSz = nMods * sizeof( struct ModuleInfo );
+ pModInfos = (struct ModuleInfo*) malloc( nArrSz );
+ memset( pModInfos, 0, nArrSz );
+
+ int nMod = 0;
+ bMod = _fpModule32First( hSnap, &aMod32Entry );
+ while ( bMod )
+ {
+ pModInfos[nMod].pNext = 0;
+ if ( nMod )
+ pModInfos[nMod-1].pNext = &pModInfos[nMod];
+
+ strcpy( pModInfos[nMod].szModBaseName, aMod32Entry.szModule );
+ strcpy( pModInfos[nMod].szModFileName, aMod32Entry.szExePath );
+ pModInfos[nMod].nBaseAddress = (unsigned long) aMod32Entry.modBaseAddr;
+ pModInfos[nMod].nSize = aMod32Entry.modBaseSize;
+// pModInfos[nMod].nEntryPoint = 0xFFFFFFFF;
+
+ bMod = _fpModule32Next( hSnap, &aMod32Entry );
+ nMod++;
+ }
+
+ CloseHandle( hSnap );
+ }
+
+ FreeLibrary( hToolHelpLib );
+ }
+ }
+ }
+ return pModInfos;
+}
+
+BOOL WNT_GetLogicalAddress( PVOID addr, PTSTR szModule, DWORD len, DWORD& section, DWORD& offset )
+{
+ MEMORY_BASIC_INFORMATION mbi;
+
+ if( VirtualQuery( addr, &mbi, sizeof(mbi) ) && mbi.AllocationBase )
+ {
+ DWORD hMod = (DWORD)mbi.AllocationBase;
+
+ if ( !GetModuleFileName( (HMODULE)hMod, szModule, len ) )
+ return FALSE;
+
+ // Point to the DOS header in memory
+ PIMAGE_DOS_HEADER pDosHdr = (PIMAGE_DOS_HEADER)hMod;
+
+ // From the DOS header, find the NT (PE) header
+ PIMAGE_NT_HEADERS pNtHdr = (PIMAGE_NT_HEADERS)(hMod + pDosHdr->e_lfanew);
+
+ PIMAGE_SECTION_HEADER pSection = IMAGE_FIRST_SECTION( pNtHdr );
+
+ DWORD rva = (DWORD)addr - hMod; // RVA is offset from module load address
+
+ // Iterate through the section table, looking for the one that encompasses
+ // the linear address.
+ for ( unsigned i = 0;
+ i < pNtHdr->FileHeader.NumberOfSections;
+ i++, pSection++ )
+ {
+ DWORD sectionStart = pSection->VirtualAddress;
+ DWORD sectionEnd = sectionStart
+ + max(pSection->SizeOfRawData, pSection->Misc.VirtualSize);
+
+ // Is the address in this section???
+ if ( (rva >= sectionStart) && (rva <= sectionEnd) )
+ {
+ // Yes, address is in the section. Calculate section and offset,
+ // and store in the "section" & "offset" params, which were
+ // passed by reference.
+ section = i+1;
+ offset = rva - sectionStart;
+ return TRUE;
+ }
+ }
+ }
+ return FALSE;
+}
+
+
+struct ModuleInfo* FindModuleContainingAddress( struct ModuleInfo* pStart, void* pAddr )
+{
+ struct ModuleInfo* pRet = NULL;
+ struct ModuleInfo* pM = pStart;
+ unsigned long nAddr = (unsigned long) pAddr;
+
+ while ( pM && !pRet )
+ {
+ if ( ( nAddr >= pM->nBaseAddress ) &&
+ ( nAddr < ( pM->nBaseAddress + pM->nSize ) ) )
+ {
+ pRet = pM;
+ }
+ else
+ {
+ pM = pM->pNext;
+ }
+ }
+ return pRet;
+}
+
+String _OLD_GetStackInfo()
+{
+ // Try an other way...
+ String aTmpStack;
+ ModuleInfo* pMods = WNT_CreateModuleInfos();
+
+ ULONG* pBP;
+ __asm mov pBP, ebp;
+ char buffer[1024];
+
+ for ( int i = 0; i < 15; i++ )
+ {
+ ULONG nIP = pBP[1];
+ sprintf( buffer, "[%.2u] IP=%.8lx", i, nIP );
+ aTmpStack += buffer;
+
+ ModuleInfo* pI = FindModuleContainingAddress( pMods, (void*)nIP );
+ if ( pI )
+ {
+ sprintf( buffer, " (Rel=%.8lx) [%s, Base=%.8lx, Path=%s]", nIP-pI->nBaseAddress-0x1000, pI->szModBaseName, pI->nBaseAddress, pI->szModFileName );
+ aTmpStack += buffer;
+ }
+
+ if ( !pI || (pBP[0] & 3) || (ULONG)pBP > pBP[0] )
+ {
+ aTmpStack += "\nError!\n";
+ break;
+ }
+
+ aTmpStack += '\n';
+ pBP = (ULONG*) pBP[0];
+ }
+
+ // Modul-Infos zerstoeren...
+ return aTmpStack;
+}
+
+String SalSystem::GetSummarySystemInfos( ULONG nFlags)
+{
+ SystemInfos aSysInfos;
+ HANDLE nCurrentThreadPseudo = GetCurrentThread();
+ HANDLE nCurrentProcessPseudo = GetCurrentProcess();
+ aSysInfos.nCurrentThreadId = GetCurrentThreadId();
+ DuplicateHandle( nCurrentProcessPseudo, nCurrentThreadPseudo, nCurrentProcessPseudo,
+ &aSysInfos.hCurrentThread, PROCESS_ALL_ACCESS, TRUE, 0 );
+ aSysInfos.nCurrentProcessId = GetCurrentProcessId();
+ DuplicateHandle( nCurrentProcessPseudo, nCurrentProcessPseudo, nCurrentProcessPseudo,
+ &aSysInfos.hCurrentProcess, PROCESS_ALL_ACCESS, TRUE, 0 );
+
+ if ( nFlags & SALSYSTEM_GETSYSTEMINFO_STACK )
+ {
+ DWORD nDebugThreadId;
+ HANDLE hDebugThread = CreateThread(
+ NULL, 16000,
+ (LPTHREAD_START_ROUTINE)DebugThread, &aSysInfos,
+ 0, &nDebugThreadId );
+
+ WaitForSingleObject( hDebugThread, INFINITE );
+ CloseHandle( hDebugThread );
+ }
+ if ( nFlags & SALSYSTEM_GETSYSTEMINFO_MODULES )
+ {
+ aSysInfos.aModules = "<Modules>\n";
+ char buffer[1024];
+ if ( !aSysInfos.pModInfos )
+ aSysInfos.pModInfos = WNT_CreateModuleInfos();
+ struct ModuleInfo* pM = aSysInfos.pModInfos;
+ while ( pM )
+ {
+ aSysInfos.aModules += " <Module name=\"";
+ aSysInfos.aModules += pM->szModBaseName;
+ aSysInfos.aModules += "\" path=\"";
+ aSysInfos.aModules += pM->szModFileName;
+ aSysInfos.aModules += "\" >\n";
+ aSysInfos.aModules += " <ModuleInfo name=\"BASE\" value=\"";
+ sprintf( buffer, "%.8lx", pM->nBaseAddress );
+ aSysInfos.aModules += buffer;
+ aSysInfos.aModules += "\" />\n";
+ aSysInfos.aModules += " <ModuleInfo name=\"Size\" value=\"";
+ aSysInfos.aModules += pM->nSize;
+ aSysInfos.aModules += "\" />\n </Module>\n";
+ pM = pM->pNext;
+ }
+ aSysInfos.aModules += "</Modules>";
+ }
+ if ( nFlags & SALSYSTEM_GETSYSTEMINFO_SYSTEMVERSION )
+ {
+ aSysInfos.aSystemVersion = "<System name=\"";
+ OSVERSIONINFO aVersionInfos;
+ memset(&aVersionInfos, 0, sizeof( OSVERSIONINFO ) );
+ aVersionInfos.dwOSVersionInfoSize = sizeof( OSVERSIONINFO );
+ GetVersionEx( &aVersionInfos );
+ if ( aVersionInfos.dwPlatformId == VER_PLATFORM_WIN32s )
+ aSysInfos.aSystemVersion += "Microsoft Win32s";
+ else if ( aVersionInfos.dwPlatformId == VER_PLATFORM_WIN32_NT )
+ aSysInfos.aSystemVersion += "Microsoft Windows NT";
+ else if ( aVersionInfos.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS )
+ {
+ if ( !aVersionInfos.dwMinorVersion )
+ aSysInfos.aSystemVersion += "Microsoft Windows 95";
+ else
+ aSysInfos.aSystemVersion += "Microsoft Windows 98";
+ }
+ else
+ aSysInfos.aSystemVersion += "Unknown Windows";
+ aSysInfos.aSystemVersion += "\" version=\"";
+ aSysInfos.aSystemVersion += aVersionInfos.dwMajorVersion;
+ aSysInfos.aSystemVersion += '.';
+ aSysInfos.aSystemVersion += aVersionInfos.dwMinorVersion;
+ aSysInfos.aSystemVersion += "\" build=\"";
+ aSysInfos.aSystemVersion += aVersionInfos.dwBuildNumber&0xFFFF;
+ aSysInfos.aSystemVersion += "\" />";
+
+ // aSysInfos.aSystemVersion += aVersionInfos.szCSDVersion;
+ /*
+ Under both Windows NT and Windows 95, you can get the
+ language information in the FileVersionInfo of User.exe by
+ calling GetFileVersionInfo, and then
+ VerQueryValue (on \\VarFileInfo\\Translation") on the
+ VersionInfo block of the operating system's User.exe.
+ NOTE: This method is the most reliable. It works well under
+ both Windows NT and Windows 95. This method also works for
+ Windows 3.1
+ */
+// DWORD nDefInputLanguage;
+// if ( SystemParametersInfo( SPI_GETDEFAULTINPUTLANG, 0, &nDefInputLanguage, 0 ) )
+// {
+// aSysInfos.aSystemVersion += " default input language = ";
+// aSysInfos.aSystemVersion += nDefInputLanguage;
+// }
+ }
+ if ( nFlags & SALSYSTEM_GETSYSTEMINFO_CPUTYPE )
+ {
+ SYSTEM_INFO aSystemInfo;
+ memset( &aSystemInfo, 0, sizeof( SYSTEM_INFO ) );
+ GetSystemInfo( &aSystemInfo );
+ aSysInfos.aCPUType = "<CPU count=\"";
+ aSysInfos.aCPUType += aSystemInfo.dwNumberOfProcessors;
+ aSysInfos.aCPUType += "\" type=\"";
+ if ( aSystemInfo.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_INTEL )
+ aSysInfos.aCPUType += "X86";
+ else if ( aSystemInfo.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_INTEL )
+ aSysInfos.aCPUType += "MIPS";
+ else if ( aSystemInfo.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_INTEL )
+ aSysInfos.aCPUType += "ALPHA";
+ else if ( aSystemInfo.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_INTEL )
+ aSysInfos.aCPUType += "PPC";
+ else
+ aSysInfos.aCPUType += "unknown";
+ aSysInfos.aCPUType += "\"></CPU>";
+ }
+ if ( nFlags & SALSYSTEM_GETSYSTEMINFO_MEMORYINFO )
+ {
+ MEMORYSTATUS aMemStatus;
+ memset( &aMemStatus, 0, sizeof( MEMORYSTATUS ) );
+ GlobalMemoryStatus( &aMemStatus );
+ aSysInfos.aMemoryInfo = "<Memory>\n";
+ aSysInfos.aMemoryInfo += " <MemoryType name=\"Physical\" total=\"";
+ aSysInfos.aMemoryInfo += (aMemStatus.dwTotalPhys+512)/1024/1024+1;
+ aSysInfos.aMemoryInfo += " MB\" free=\"";
+ aSysInfos.aMemoryInfo += (aMemStatus.dwAvailPhys+512)/1024/1024+1;
+ aSysInfos.aMemoryInfo += " MB\" />\n";
+ aSysInfos.aMemoryInfo += " <MemoryType name=\"Swap\" total=\"";
+ aSysInfos.aMemoryInfo += (aMemStatus.dwTotalPageFile+512)/1024/1024+1;
+ aSysInfos.aMemoryInfo += " MB\" free=\"";
+ aSysInfos.aMemoryInfo += (aMemStatus.dwAvailPageFile+512)/1024/1024+1;
+ aSysInfos.aMemoryInfo += " MB\" />\n";
+ aSysInfos.aMemoryInfo += " <MemoryType name=\"Virtual\" total=\"";
+ aSysInfos.aMemoryInfo += (aMemStatus.dwTotalVirtual+512)/1024/1024+1;
+ aSysInfos.aMemoryInfo += " MB\" free=\"";
+ aSysInfos.aMemoryInfo += (aMemStatus.dwAvailVirtual+512)/1024/1024+1;
+ aSysInfos.aMemoryInfo += " MB\" />\n";
+ aSysInfos.aMemoryInfo += "</Memory>";
+ }
+ if ( nFlags & SALSYSTEM_GETSYSTEMINFO_LOCALVOLUMES )
+ {
+ aSysInfos.aLocalVolumes = "<LocalVolumes>\n";
+ char aDriveStrings[4096];
+ GetLogicalDriveStrings( 4096, aDriveStrings );
+ LPTSTR pDriveStr = aDriveStrings;
+ while ( *pDriveStr )
+ {
+ UINT nType = GetDriveType( pDriveStr );
+ if ( nType != DRIVE_REMOTE )
+ {
+ aSysInfos.aLocalVolumes += " <LocalVolume type=\"";
+
+ switch ( nType )
+ {
+ case DRIVE_REMOVABLE: aSysInfos.aLocalVolumes += "Removable"; break;
+ case DRIVE_FIXED: aSysInfos.aLocalVolumes += "Fixed"; break;
+ case DRIVE_REMOTE: aSysInfos.aLocalVolumes += "Remote"; break;
+ case DRIVE_CDROM: aSysInfos.aLocalVolumes += "CD-ROM"; break;
+ case DRIVE_RAMDISK: aSysInfos.aLocalVolumes += "RAM disk"; break;
+ default: aSysInfos.aLocalVolumes += "Unkown";
+ }
+ aSysInfos.aLocalVolumes += "\" path=\"";
+ aSysInfos.aLocalVolumes += pDriveStr;
+ aSysInfos.aLocalVolumes += "\"";
+ if( nType == DRIVE_FIXED )
+ {
+ DWORD nSectorsPerCluster;
+ DWORD nBytesPerSector;
+ DWORD nNumberFreeClusters;
+ DWORD nNumberTotalClusters;
+ if( GetDiskFreeSpace( pDriveStr, &nSectorsPerCluster, &nBytesPerSector, &nNumberFreeClusters, &nNumberTotalClusters ) )
+ {
+ DWORD nUnitsPerCluster = nSectorsPerCluster*nBytesPerSector;
+ DWORD nUnitDivi = 1;
+ String aUnit = "bytes";
+ if( ( nUnitsPerCluster % 1024 ) == 0 )
+ {
+ aUnit = "KB";
+ nUnitsPerCluster /= 1024;
+ }
+ else if( ( nUnitsPerCluster % 512 ) == 0 )
+ {
+ aUnit = "KB";
+ nUnitDivi = 1024;
+ }
+ DWORD nFree = nNumberFreeClusters*nUnitsPerCluster/nUnitDivi;
+ aSysInfos.aLocalVolumes += " free=\"";
+ aSysInfos.aLocalVolumes += nFree;
+ aSysInfos.aLocalVolumes += ' ';
+ aSysInfos.aLocalVolumes += aUnit;
+ aSysInfos.aLocalVolumes += "\"";
+ }
+ }
+ aSysInfos.aLocalVolumes += " />\n";
+ }
+ while ( *pDriveStr )
+ pDriveStr++;
+ pDriveStr++;
+ }
+ aSysInfos.aLocalVolumes += "</LocalVolumes>";
+ }
+ if ( nFlags & SALSYSTEM_GETSYSTEMINFO_SYSTEMDIRS )
+ {
+ aSysInfos.aSystemDirs = "<SystemDirs>\n";
+ char buffer[ MAX_PATH ];
+ aSysInfos.aSystemDirs += " <SystemDir envname=\"Windows\" path=\"";
+ if( GetWindowsDirectory( buffer, MAX_PATH ) )
+ aSysInfos.aSystemDirs += buffer;
+ aSysInfos.aSystemDirs += "\" />\n";
+
+ aSysInfos.aSystemDirs += " <SystemDir envname=\"System\" path=\"";
+ if( GetSystemDirectory( buffer, MAX_PATH ) )
+ aSysInfos.aSystemDirs += buffer;
+ aSysInfos.aSystemDirs += "\" />\n";
+
+ aSysInfos.aSystemDirs += " <SystemDir envname=\"Current\" path=\"";
+ if( GetCurrentDirectory( MAX_PATH, buffer ) )
+ aSysInfos.aSystemDirs += buffer;
+ aSysInfos.aSystemDirs += "\" />\n";
+
+ aSysInfos.aSystemDirs += " <SystemDir envname=\"Temp\" path=\"";
+ if( GetTempPath( MAX_PATH, buffer ) )
+ aSysInfos.aSystemDirs += buffer;
+ aSysInfos.aSystemDirs += "\" />\n";
+ aSysInfos.aSystemDirs += "</SystemDirs>";
+
+ }
+ if ( nFlags & SALSYSTEM_GETSYSTEMINFO_MOUSEINFO )
+ {
+ aSysInfos.aMouseInfo = "<Mouse ";
+ int nRet = GetSystemMetrics( SM_CMOUSEBUTTONS );
+ if ( nRet )
+ {
+ aSysInfos.aMouseInfo += "buttons=\"";
+ aSysInfos.aMouseInfo += nRet;
+ aSysInfos.aMouseInfo += "\" description=\"";
+ if( GetSystemMetrics( 75 /*SM_MOUSEWHEELPRESENT - missing in SDK from MSVC4.2 */ ) )
+ aSysInfos.aMouseInfo += "wheel mouse";
+ else
+ aSysInfos.aMouseInfo += "standard mouse";
+ aSysInfos.aMouseInfo += "\"";
+ }
+ else
+ {
+ aSysInfos.aMouseInfo += "description=\"Not installed.\"";
+ }
+ aSysInfos.aMouseInfo += " />";
+ }
+
+ CloseHandle( aSysInfos.hCurrentThread );
+ CloseHandle( aSysInfos.hCurrentProcess );
+
+ String aInfos;
+
+ aInfos += aSysInfos.aSystemVersion;
+ aInfos += "\n\n";
+
+ aInfos += aSysInfos.aCPUType;
+ aInfos += "\n\n";
+
+ aInfos += aSysInfos.aMouseInfo;
+ aInfos += "\n\n";
+
+ aInfos += aSysInfos.aMemoryInfo;
+ aInfos += "\n\n";
+
+ aInfos += aSysInfos.aStack;
+ aInfos += "\n\n";
+
+ aInfos += aSysInfos.aModules;
+ aInfos += "\n\n";
+
+ aInfos += aSysInfos.aLocalVolumes;
+ aInfos += "\n\n";
+
+ aInfos += aSysInfos.aSystemDirs;
+ aInfos += "\n\n";
+
+ return aInfos;
+}
+
+
+
+
+void DebugThread( SystemInfos* pSysInfos )
+{
+ HINSTANCE hImageHelpLib = LoadLibrary( "IMAGEHLP.DLL" );
+ if( hImageHelpLib )
+ {
+ if ( SuspendThread( pSysInfos->hCurrentThread ) != 0xFFFFFFFF )
+ {
+ STACKFRAME aStackFrame;
+ memset( &aStackFrame, 0, sizeof( aStackFrame ) );
+
+ CONTEXT aContext;
+ memset( &aContext, 0, sizeof( aContext ) );
+ aContext.ContextFlags = CONTEXT_FULL;
+ if ( GetThreadContext( pSysInfos->hCurrentThread, &aContext ) )
+ {
+ STACKWALKPROC _fpStackWalk = (STACKWALKPROC) GetProcAddress( hImageHelpLib, "StackWalk" );
+ SYMFUNCTIONTABLEACCESSPROC _fpSymFunctionTableAccess = (SYMFUNCTIONTABLEACCESSPROC) GetProcAddress( hImageHelpLib, "SymFunctionTableAccess" );
+ SYMGETMODULEBASEPROC _fpSymGetModuleBase = (SYMGETMODULEBASEPROC) GetProcAddress( hImageHelpLib, "SymGetModuleBase" );
+ SYMSETOPTIONSPROC _fpSymSetOptionsProc = (SYMSETOPTIONSPROC) GetProcAddress( hImageHelpLib, "SymGetOptions" );
+ SYMINITIALIZEPROC _fpSymInitializeProc = (SYMINITIALIZEPROC) GetProcAddress( hImageHelpLib, "SymInitialize" );
+ SYMCLEANUPPROC _fpSymCleanup = (SYMCLEANUPPROC) GetProcAddress( hImageHelpLib, "SymCleanup" );
+ UNDECORATESYMBOLNAMEPROC _fpUndecorateSymbolName = (UNDECORATESYMBOLNAMEPROC) GetProcAddress( hImageHelpLib, "UnDecorateSymbolName" );
+ SYMLOADMODULEPROC _fpSymLoadModule = ( SYMLOADMODULEPROC) GetProcAddress( hImageHelpLib, "SymLoadModule" );
+ SYMGETSYMFROMADDR _fpSymGetSymFromAddr = ( SYMGETSYMFROMADDR ) GetProcAddress( hImageHelpLib, "SymGetSymFromAddr" );
+
+ if ( !pSysInfos->pModInfos )
+ pSysInfos->pModInfos = WNT_CreateModuleInfos();
+
+ _fpSymSetOptionsProc( SYMOPT_DEFERRED_LOADS );
+
+ char buffer[1024];
+
+ // Initialize the imagehlp symbol handler
+ BOOL bAutoLoad = FALSE;
+// String aPath = WNT_CreateModulePath( pSysInfos->pModInfos );
+// USHORT nLen = aPath.Len();
+// memcpy( buffer, aPath.GetStr(), nLen );
+// buffer[nLen] = 0;
+// BOOL bSymbols = _fpSymInitializeProc( pSysInfos->hCurrentProcess, NULL, bAutoLoad );
+ // Path funktioniert nicht, also lade ich unten alle von Hand!
+ BOOL bSymbols = _fpSymInitializeProc( pSysInfos->hCurrentProcess, NULL, bAutoLoad );
+
+ // Load symbol modules for the current process
+ if ( bSymbols && !bAutoLoad )
+ {
+ // LoadModuleSymbols( pSysInfos->nCurrentProcessId, pSysInfos->hCurrentProcess );
+ struct ModuleInfo* pM = pSysInfos->pModInfos;
+ char buffer1[1024];
+ char buffer2[1024];
+
+ while ( pM )
+ {
+ strcpy( buffer1, pM->szModFileName );
+ strcpy( buffer2, pM->szModBaseName );
+
+ BOOL bDone = _fpSymLoadModule( pSysInfos->hCurrentProcess, 0, buffer1, buffer2, pM->nBaseAddress, pM->nSize );
+
+ pM = pM->pNext;
+ }
+ }
+
+ // Initialize the STACKFRAME structure for the first call. This is only
+ // necessary for Intel CPUs, and isn't mentioned in the documentation.
+ aStackFrame.AddrPC.Offset = aContext.Eip;
+ aStackFrame.AddrPC.Mode = AddrModeFlat;
+ aStackFrame.AddrStack.Offset = aContext.Esp;
+ aStackFrame.AddrStack.Mode = AddrModeFlat;
+ aStackFrame.AddrFrame.Offset = aContext.Ebp;
+ aStackFrame.AddrFrame.Mode = AddrModeFlat;
+
+
+ pSysInfos->aStack = "<Stack type=\"WIN32\" >\n";
+
+ for ( int nS = 0; nS < 20; nS++ )
+ {
+ SetLastError( 0 );
+ BOOL bStack = _fpStackWalk( IMAGE_FILE_MACHINE_I386,
+ pSysInfos->hCurrentProcess,
+ pSysInfos->hCurrentThread,
+ &aStackFrame,
+ &aContext,
+ NULL, // ReadProcessMemory,
+ _fpSymFunctionTableAccess,
+ _fpSymGetModuleBase,
+ NULL );
+
+ if ( !bStack || !aStackFrame.AddrReturn.Offset || !aStackFrame.AddrFrame.Offset )
+ break;
+
+ pSysInfos->aStack += " <StackInfo pos=\"";
+ pSysInfos->aStack += (USHORT)nS;
+ pSysInfos->aStack += "\" ip=\"";
+ ULONG nIP = aStackFrame.AddrReturn.Offset;
+ sprintf( buffer, "%.8lx", nIP );
+ pSysInfos->aStack += buffer;
+ pSysInfos->aStack += "\"";
+
+ TCHAR aModuleFileName[MAX_PATH];
+ DWORD section, offset;
+ if ( WNT_GetLogicalAddress( (void*)nIP, aModuleFileName, MAX_PATH, section, offset ) )
+ {
+ pSysInfos->aStack += " rel=\"";
+ sprintf( buffer, "%.8lx", offset );
+ pSysInfos->aStack += buffer;
+ pSysInfos->aStack += "\" file=\"";
+ char* pModName = strrchr( aModuleFileName, '\\' );
+ pSysInfos->aStack += pModName ? (pModName+1) : aModuleFileName;
+ pSysInfos->aStack += "\"";
+ }
+ else
+ {
+ pSysInfos->aStack += " rel=\"ERROR\"";
+ break;
+ }
+
+ if ( bSymbols )
+ {
+
+ BYTE symbolBuffer[ sizeof(IMAGEHLP_SYMBOL) + 512 ];
+ PIMAGEHLP_SYMBOL pSymbol = (PIMAGEHLP_SYMBOL)symbolBuffer;
+ memset( symbolBuffer, 0, sizeof(symbolBuffer) );
+ pSymbol->SizeOfStruct = sizeof(symbolBuffer);
+ pSymbol->MaxNameLength = sizeof(symbolBuffer) - sizeof(IMAGEHLP_SYMBOL) + 1;
+
+ DWORD symDisplacement = 0; // Displacement of the input address,
+ // relative to the start of the symbol
+
+ if ( _fpSymGetSymFromAddr( pSysInfos->hCurrentProcess, aStackFrame.AddrReturn.Offset,
+ &symDisplacement, pSymbol ) )
+ {
+ pSysInfos->aStack += " ordinal=\"";
+ _fpUndecorateSymbolName( pSymbol->Name, buffer, 1024, UNDNAME_NAME_ONLY );
+ pSysInfos->aStack += buffer;
+ pSysInfos->aStack += "\"";
+ // aStackLine += '<';
+ // _fpUndecorateSymbolName( pSymbol->Name, buffer, 1024, UNDNAME_COMPLETE );
+ // aStackLine += buffer;
+ // aStackLine += '>';
+ }
+ else // No symbol found. Print out the logical address instead.
+ {
+ pSysInfos->aStack += " ordinal=\"???\"";
+ }
+ }
+
+ pSysInfos->aStack += " />\n";
+ }
+ pSysInfos->aStack += "</Stack>";
+ _fpSymCleanup( pSysInfos->hCurrentProcess );
+ }
+ ResumeThread( pSysInfos->hCurrentThread );
+ }
+ FreeLibrary( hImageHelpLib );
+ }
+}
+
+#endif
diff --git a/vcl/win/source/app/salinst.cxx b/vcl/win/source/app/salinst.cxx
new file mode 100644
index 000000000000..bafb98e35bfa
--- /dev/null
+++ b/vcl/win/source/app/salinst.cxx
@@ -0,0 +1,897 @@
+/*************************************************************************
+ *
+ * $RCSfile: salinst.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:49 $
+ *
+ * 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 <string.h>
+#include <tools/svwin.h>
+#ifdef WNT
+#include <process.h>
+#endif
+
+#define _SV_SALINST_CXX
+
+#ifndef _VOS_MUTEX_HXX
+#include <vos/mutex.hxx>
+#endif
+
+#ifndef _TOOLS_DEBUG_HXX
+#include <tools/debug.hxx>
+#endif
+
+#ifndef _SV_WINCOMP_HXX
+#include <wincomp.hxx>
+#endif
+#ifndef _SV_SALIDS_HRC
+#include <salids.hrc>
+#endif
+#ifndef _SV_SALDATA_HXX
+#include <saldata.hxx>
+#endif
+#ifndef _SV_SALINST_HXX
+#include <salinst.hxx>
+#endif
+#ifndef _SV_SALFRAME_HXX
+#include <salframe.hxx>
+#endif
+#ifndef _SV_SALOBJ_HXX
+#include <salobj.hxx>
+#endif
+#ifndef _SV_SALSYS_HXX
+#include <salsys.hxx>
+#endif
+#ifndef _SV_SALTIMER_HXX
+#include <saltimer.hxx>
+#endif
+#ifndef _SV_SALSOUND_HXX
+#include <salsound.hxx>
+#endif
+#ifndef _SV_SALATYPE_HXX
+#include <salatype.hxx>
+#endif
+#ifndef _SV_SYSDATA_HXX
+#include <sysdata.hxx>
+#endif
+
+#ifndef _SV_TIMER_HXX
+#include <timer.hxx>
+#endif
+
+// =======================================================================
+
+void SalAbort( const XubString& rErrorText )
+{
+ ImplFreeSalGDI();
+
+ if ( !rErrorText.Len() )
+ FatalAppExit( 0, "Application Error" );
+ else
+ {
+ ByteString aErrorText( ImplSalGetWinAnsiString( rErrorText ) );
+ FatalAppExit( 0, aErrorText.GetBuffer() );
+ }
+}
+
+// =======================================================================
+
+LRESULT CALLBACK SalComWndProcA( HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam );
+LRESULT CALLBACK SalComWndProcW( HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam );
+
+// =======================================================================
+
+class SalYieldMutex : public NAMESPACE_VOS(OMutex)
+{
+public: // for ImplSalYield()
+ SalInstanceData* mpInstData;
+ ULONG mnCount;
+ DWORD mnThreadId;
+
+public:
+ SalYieldMutex( SalInstanceData* pInstData );
+
+ virtual void SAL_CALL acquire();
+ virtual void SAL_CALL release();
+ virtual sal_Bool SAL_CALL tryToAcquire();
+
+ ULONG GetAcquireCount( ULONG nThreadId );
+};
+
+// -----------------------------------------------------------------------
+
+SalYieldMutex::SalYieldMutex( SalInstanceData* pInstData )
+{
+ mpInstData = pInstData;
+ mnCount = 0;
+ mnThreadId = 0;
+}
+
+// -----------------------------------------------------------------------
+
+void SAL_CALL SalYieldMutex::acquire()
+{
+ OMutex::acquire();
+ mnCount++;
+ mnThreadId = GetCurrentThreadId();
+}
+
+// -----------------------------------------------------------------------
+
+void SAL_CALL SalYieldMutex::release()
+{
+ DWORD nThreadId = GetCurrentThreadId();
+ if ( mnThreadId != nThreadId )
+ OMutex::release();
+ else
+ {
+ // If we don't call these message, the Output from the
+ // Java clients doesn't come in the right order
+ GdiFlush();
+
+ SalData* pSalData = GetSalData();
+ if ( pSalData->mnAppThreadId != nThreadId )
+ {
+ if ( mnCount == 1 )
+ {
+ mpInstData->mpSalWaitMutex->acquire();
+ if ( mpInstData->mnYieldWaitCount )
+ ImplPostMessage( mpInstData->mhComWnd, SAL_MSG_RELEASEWAITYIELD, 0, 0 );
+ mnThreadId = 0;
+ mnCount--;
+ OMutex::release();
+ mpInstData->mpSalWaitMutex->release();
+ }
+ else
+ {
+ mnCount--;
+ OMutex::release();
+ }
+ }
+ else
+ {
+ if ( mnCount == 1 )
+ mnThreadId = 0;
+ mnCount--;
+ OMutex::release();
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+sal_Bool SAL_CALL SalYieldMutex::tryToAcquire()
+{
+ if( OMutex::tryToAcquire() )
+ {
+ mnCount++;
+ mnThreadId = GetCurrentThreadId();
+ return True;
+ }
+ else
+ return False;
+}
+
+// -----------------------------------------------------------------------
+
+ULONG SalYieldMutex::GetAcquireCount( ULONG nThreadId )
+{
+ if ( nThreadId == mnThreadId )
+ return mnCount;
+ else
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+void ImplSalYieldMutexAcquireWithWait()
+{
+ SalInstance* pInst = GetSalData()->mpFirstInstance;
+ if ( !pInst )
+ return;
+
+ // If we are the main thread, then we must wait with wait, because
+ // in if we don't reschedule, then we create deadlocks if a Windows
+ // Function is called from another thread. If we arn't the main thread,
+ // than we call qcquire directly.
+ DWORD nThreadId = GetCurrentThreadId();
+ SalData* pSalData = GetSalData();
+ if ( pSalData->mnAppThreadId == nThreadId )
+ {
+ // Wenn wir den Mutex nicht bekommen, muessen wir solange
+ // warten, bis wir Ihn bekommen
+ BOOL bAcquire = FALSE;
+ do
+ {
+ if ( pInst->maInstData.mpSalYieldMutex->tryToAcquire() )
+ bAcquire = TRUE;
+ else
+ {
+ pInst->maInstData.mpSalWaitMutex->acquire();
+ if ( pInst->maInstData.mpSalYieldMutex->tryToAcquire() )
+ {
+ bAcquire = TRUE;
+ pInst->maInstData.mpSalWaitMutex->release();
+ }
+ else
+ {
+ pInst->maInstData.mnYieldWaitCount++;
+ pInst->maInstData.mpSalWaitMutex->release();
+ MSG aTmpMsg;
+ ImplGetMessage( &aTmpMsg, pInst->maInstData.mhComWnd, SAL_MSG_RELEASEWAITYIELD, SAL_MSG_RELEASEWAITYIELD );
+ pInst->maInstData.mnYieldWaitCount--;
+ if ( pInst->maInstData.mnYieldWaitCount )
+ ImplPostMessage( pInst->maInstData.mhComWnd, SAL_MSG_RELEASEWAITYIELD, 0, 0 );
+ }
+ }
+ }
+ while ( !bAcquire );
+ }
+ else
+ pInst->maInstData.mpSalYieldMutex->acquire();
+}
+
+// -----------------------------------------------------------------------
+
+BOOL ImplSalYieldMutexTryToAcquire()
+{
+ SalInstance* pInst = GetSalData()->mpFirstInstance;
+ if ( pInst )
+ return pInst->maInstData.mpSalYieldMutex->tryToAcquire();
+ else
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+void ImplSalYieldMutexAcquire()
+{
+ SalInstance* pInst = GetSalData()->mpFirstInstance;
+ if ( pInst )
+ pInst->maInstData.mpSalYieldMutex->acquire();
+}
+
+// -----------------------------------------------------------------------
+
+void ImplSalYieldMutexRelease()
+{
+ SalInstance* pInst = GetSalData()->mpFirstInstance;
+ if ( pInst )
+ pInst->maInstData.mpSalYieldMutex->release();
+}
+
+// -----------------------------------------------------------------------
+
+ULONG ImplSalReleaseYieldMutex()
+{
+ SalInstance* pInst = GetSalData()->mpFirstInstance;
+ if ( !pInst )
+ return 0;
+
+ SalYieldMutex* pYieldMutex = pInst->maInstData.mpSalYieldMutex;
+ ULONG nCount = pYieldMutex->GetAcquireCount( GetCurrentThreadId() );
+ ULONG n = nCount;
+ while ( n )
+ {
+ pYieldMutex->release();
+ n--;
+ }
+
+ return nCount;
+}
+
+// -----------------------------------------------------------------------
+
+void ImplSalAcquireYieldMutex( ULONG nCount )
+{
+ SalInstance* pInst = GetSalData()->mpFirstInstance;
+ if ( !pInst )
+ return;
+
+ SalYieldMutex* pYieldMutex = pInst->maInstData.mpSalYieldMutex;
+ while ( nCount )
+ {
+ pYieldMutex->acquire();
+ nCount--;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+#ifdef DBG_UTIL
+
+void ImplDbgTestSolarMutex()
+{
+ SalData* pSalData = GetSalData();
+ DWORD nCurThreadId = GetCurrentThreadId();
+ if ( pSalData->mnAppThreadId != nCurThreadId )
+ {
+ if ( pSalData->mpFirstInstance )
+ {
+ SalYieldMutex* pYieldMutex = pSalData->mpFirstInstance->maInstData.mpSalYieldMutex;
+ if ( pYieldMutex->mnThreadId != nCurThreadId )
+ {
+ DBG_ERROR( "SolarMutex not locked, and not thread save code in VCL is called from outside of the main thread" );
+ }
+ }
+ }
+ else
+ {
+ if ( pSalData->mpFirstInstance )
+ {
+ SalYieldMutex* pYieldMutex = pSalData->mpFirstInstance->maInstData.mpSalYieldMutex;
+ if ( pYieldMutex->mnThreadId != nCurThreadId )
+ {
+ DBG_ERROR( "SolarMutex not locked in the main thread" );
+ }
+ }
+ }
+}
+
+#endif
+
+// =======================================================================
+
+static void InitSalShlData()
+{
+ aSalShlData.mnVKAdd = LOWORD( VkKeyScan( '+' ) );
+ aSalShlData.mnVKSubtract = LOWORD( VkKeyScan( '-' ) );
+ aSalShlData.mnVKMultiply = LOWORD( VkKeyScan( '*' ) );
+ aSalShlData.mnVKDivide = LOWORD( VkKeyScan( '/' ) );
+ aSalShlData.mnVKPoint = LOWORD( VkKeyScan( '.' ) );
+ aSalShlData.mnVKComma = LOWORD( VkKeyScan( ',' ) );
+ aSalShlData.mnVKLess = LOWORD( VkKeyScan( '<' ) );
+ aSalShlData.mnVKGreater = LOWORD( VkKeyScan( '>' ) );
+ aSalShlData.mnVKEqual = LOWORD( VkKeyScan( '=' ) );
+}
+
+// =======================================================================
+
+void InitSalData()
+{
+ SalData* pSalData = new SalData;
+ memset( pSalData, 0, sizeof( SalData ) );
+ SetSalData( pSalData );
+ CoInitialize(0);
+}
+
+// -----------------------------------------------------------------------
+
+void DeInitSalData()
+{
+ CoUninitialize();
+ SalData* pSalData = GetSalData();
+ delete pSalData;
+ SetSalData( NULL );
+}
+
+// -----------------------------------------------------------------------
+
+void SetFilterCallback( void* pCallback, void* pInst )
+{
+ SalData* pSalData = GetSalData();
+
+ pSalData->mpFirstInstance->maInstData.mpFilterCallback = pCallback;
+ pSalData->mpFirstInstance->maInstData.mpFilterInst = pInst;
+}
+
+// -----------------------------------------------------------------------
+
+SalInstance* CreateSalInstance()
+{
+ SalData* pSalData = GetSalData();
+
+ // determine the windows version
+ WORD nVer = (WORD)GetVersion();
+ aSalShlData.mnVersion = (((WORD)LOBYTE(nVer)) * 100) + HIBYTE(nVer);
+ if ( aSalShlData.mnVersion >= W95_VERSION )
+ aSalShlData.mbW40 = 1;
+ OSVERSIONINFO aVerInfo;
+ aVerInfo.dwOSVersionInfoSize = sizeof( aVerInfo );
+ if ( GetVersionEx( &aVerInfo ) )
+ {
+ if ( aVerInfo.dwPlatformId == VER_PLATFORM_WIN32_NT )
+ aSalShlData.mbWNT = 1;
+ }
+
+ pSalData->mnAppThreadId = GetCurrentThreadId();
+
+ // register frame class
+ if ( !pSalData->mhPrevInst )
+ {
+ if ( aSalShlData.mbWNT )
+ {
+ WNDCLASSEXW aWndClassEx;
+ aWndClassEx.cbSize = sizeof( aWndClassEx );
+ aWndClassEx.style = CS_OWNDC;
+ aWndClassEx.lpfnWndProc = SalFrameWndProcW;
+ aWndClassEx.cbClsExtra = 0;
+ aWndClassEx.cbWndExtra = SAL_FRAME_WNDEXTRA;
+ aWndClassEx.hInstance = pSalData->mhInst;
+ aWndClassEx.hCursor = 0;
+ aWndClassEx.hbrBackground = 0;
+ aWndClassEx.lpszMenuName = 0;
+ aWndClassEx.lpszClassName = SAL_FRAME_CLASSNAMEW;
+ ImplLoadSalIcon( SAL_RESID_ICON_DEFAULT, aWndClassEx.hIcon, aWndClassEx.hIconSm );
+ if ( !RegisterClassExW( &aWndClassEx ) )
+ return NULL;
+ aWndClassEx.style |= CS_SAVEBITS;
+ aWndClassEx.lpszClassName = SAL_FRAME_CLASSNAME_SBW;
+ if ( !RegisterClassExW( &aWndClassEx ) )
+ return NULL;
+
+ aWndClassEx.style = 0;
+ aWndClassEx.lpfnWndProc = SalComWndProcW;
+ aWndClassEx.cbWndExtra = 0;
+ aWndClassEx.hIcon = 0;
+ aWndClassEx.hIconSm = 0;
+ aWndClassEx.lpszClassName = SAL_COM_CLASSNAMEW;
+ if ( !RegisterClassExW( &aWndClassEx ) )
+ return NULL;
+ }
+ else
+ {
+ WNDCLASSEXA aWndClassEx;
+ aWndClassEx.cbSize = sizeof( aWndClassEx );
+ aWndClassEx.style = CS_OWNDC;
+ aWndClassEx.lpfnWndProc = SalFrameWndProcA;
+ aWndClassEx.cbClsExtra = 0;
+ aWndClassEx.cbWndExtra = SAL_FRAME_WNDEXTRA;
+ aWndClassEx.hInstance = pSalData->mhInst;
+ aWndClassEx.hCursor = 0;
+ aWndClassEx.hbrBackground = 0;
+ aWndClassEx.lpszMenuName = 0;
+ aWndClassEx.lpszClassName = SAL_FRAME_CLASSNAMEA;
+ ImplLoadSalIcon( SAL_RESID_ICON_DEFAULT, aWndClassEx.hIcon, aWndClassEx.hIconSm );
+ if ( !RegisterClassExA( &aWndClassEx ) )
+ return NULL;
+ aWndClassEx.style |= CS_SAVEBITS;
+ aWndClassEx.lpszClassName = SAL_FRAME_CLASSNAME_SBA;
+ if ( !RegisterClassExA( &aWndClassEx ) )
+ return NULL;
+
+ aWndClassEx.style = 0;
+ aWndClassEx.lpfnWndProc = SalComWndProcA;
+ aWndClassEx.cbWndExtra = 0;
+ aWndClassEx.hIcon = 0;
+ aWndClassEx.hIconSm = 0;
+ aWndClassEx.lpszClassName = SAL_COM_CLASSNAMEA;
+ if ( !RegisterClassExA( &aWndClassEx ) )
+ return NULL;
+ }
+ }
+
+ HWND hComWnd;
+ if ( aSalShlData.mbWNT )
+ {
+ hComWnd = CreateWindowExW( WS_EX_TOOLWINDOW, SAL_COM_CLASSNAMEW,
+ L"", WS_POPUP, 0, 0, 0, 0, 0, 0,
+ pSalData->mhInst, NULL );
+ }
+ else
+ {
+ hComWnd = CreateWindowExA( WS_EX_TOOLWINDOW, SAL_COM_CLASSNAMEA,
+ "", WS_POPUP, 0, 0, 0, 0, 0, 0,
+ pSalData->mhInst, NULL );
+ }
+ if ( !hComWnd )
+ return NULL;
+
+ SalInstance* pInst = new SalInstance;
+
+ // init shl data
+ InitSalShlData();
+
+ // init instance (only one instance in this version !!!)
+ pSalData->mpFirstInstance = pInst;
+ pInst->maInstData.mhInst = pSalData->mhInst;
+ pInst->maInstData.mhComWnd = hComWnd;
+
+ // init static GDI Data
+ ImplInitSalGDI();
+
+ return pInst;
+}
+
+// -----------------------------------------------------------------------
+
+void DestroySalInstance( SalInstance* pInst )
+{
+ SalData* pSalData = GetSalData();
+
+ // (only one instance in this version !!!)
+
+ ImplFreeSalGDI();
+
+ // reset instance
+ if ( pSalData->mpFirstInstance == pInst )
+ pSalData->mpFirstInstance = NULL;
+
+ delete pInst;
+}
+
+// -----------------------------------------------------------------------
+
+SalInstance::SalInstance()
+{
+ maInstData.mhComWnd = 0;
+ maInstData.mpFilterCallback = NULL;
+ maInstData.mpFilterInst = NULL;
+ maInstData.mpSalYieldMutex = new SalYieldMutex( &maInstData );
+ maInstData.mpSalWaitMutex = new NAMESPACE_VOS(OMutex);
+ maInstData.mnYieldWaitCount = 0;
+ maInstData.mpSalYieldMutex->acquire();
+}
+
+// -----------------------------------------------------------------------
+
+SalInstance::~SalInstance()
+{
+ maInstData.mpSalYieldMutex->release();
+ delete maInstData.mpSalYieldMutex;
+ delete maInstData.mpSalWaitMutex;
+ DestroyWindow( maInstData.mhComWnd );
+}
+
+// -----------------------------------------------------------------------
+
+#ifdef _VOS_NO_NAMESPACE
+IMutex* SalInstance::GetYieldMutex()
+#else
+vos::IMutex* SalInstance::GetYieldMutex()
+#endif
+{
+ return maInstData.mpSalYieldMutex;
+}
+
+// -----------------------------------------------------------------------
+
+ULONG SalInstance::ReleaseYieldMutex()
+{
+ return ImplSalReleaseYieldMutex();
+}
+
+// -----------------------------------------------------------------------
+
+void SalInstance::AcquireYieldMutex( ULONG nCount )
+{
+ ImplSalAcquireYieldMutex( nCount );
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplSalDispatchMessage( MSG* pMsg )
+{
+ SalData* pSalData = GetSalData();
+ if ( pSalData->mpFirstObject )
+ {
+ if ( ImplSalPreDispatchMsg( pMsg ) )
+ return;
+ }
+ LRESULT lResult = ImplDispatchMessage( pMsg );
+ if ( pSalData->mpFirstObject )
+ ImplSalPostDispatchMsg( pMsg, lResult );
+}
+
+// -----------------------------------------------------------------------
+
+void ImplSalYield( BOOL bWait )
+{
+ MSG aMsg;
+
+ if ( bWait )
+ {
+ if ( ImplGetMessage( &aMsg, 0, 0, 0 ) )
+ {
+ TranslateMessage( &aMsg );
+ ImplSalDispatchMessage( &aMsg );
+ }
+ }
+ else
+ {
+ if ( ImplPeekMessage( &aMsg, 0, 0, 0, PM_REMOVE ) )
+ {
+ TranslateMessage( &aMsg );
+ ImplSalDispatchMessage( &aMsg );
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void SalInstance::Yield( BOOL bWait )
+{
+ SalYieldMutex* pYieldMutex = maInstData.mpSalYieldMutex;
+ SalData* pSalData = GetSalData();
+ DWORD nCurThreadId = GetCurrentThreadId();
+ ULONG nCount = pYieldMutex->GetAcquireCount( nCurThreadId );
+ ULONG n = nCount;
+ while ( n )
+ {
+ pYieldMutex->release();
+ n--;
+ }
+ if ( pSalData->mnAppThreadId != nCurThreadId )
+ {
+ ImplSendMessage( maInstData.mhComWnd, SAL_MSG_THREADYIELD, (WPARAM)bWait, (LPARAM)0 );
+ n = nCount;
+ while ( n )
+ {
+ pYieldMutex->acquire();
+ n--;
+ }
+ }
+ else
+ {
+ ImplSalYield( bWait );
+
+ n = nCount;
+ while ( n )
+ {
+ ImplSalYieldMutexAcquireWithWait();
+ n--;
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+LRESULT CALLBACK SalComWndProc( HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam, int& rDef )
+{
+ LRESULT nRet = 0;
+
+ switch ( nMsg )
+ {
+ case SAL_MSG_PRINTABORTJOB:
+ ImplSalPrinterAbortJobAsync( (HDC)wParam );
+ rDef = FALSE;
+ break;
+ case SAL_MSG_THREADYIELD:
+ ImplSalYield( (BOOL)wParam );
+ rDef = FALSE;
+ break;
+ // If we get this message, because another GetMessage() call
+ // has recieved this message, we must post this message to
+ // us again, because in the other case we wait forever.
+ case SAL_MSG_RELEASEWAITYIELD:
+ {
+ SalInstance* pInst = GetSalData()->mpFirstInstance;
+ if ( pInst && pInst->maInstData.mnYieldWaitCount )
+ ImplPostMessage( hWnd, SAL_MSG_RELEASEWAITYIELD, wParam, lParam );
+ }
+ rDef = FALSE;
+ break;
+ case SAL_MSG_STARTTIMER:
+ ImplSalStartTimer( (ULONG) lParam, FALSE );
+ rDef = FALSE;
+ break;
+ case SAL_MSG_CREATEFRAME:
+ nRet = (LRESULT)ImplSalCreateFrame( GetSalData()->mpFirstInstance, (HWND)lParam, (ULONG)wParam );
+ rDef = FALSE;
+ break;
+ case SAL_MSG_DESTROYFRAME:
+ delete (SalFrame*)lParam;
+ rDef = FALSE;
+ break;
+ case SAL_MSG_CREATEOBJECT:
+ nRet = (LRESULT)ImplSalCreateObject( GetSalData()->mpFirstInstance, (SalFrame*)lParam );
+ rDef = FALSE;
+ break;
+ case SAL_MSG_DESTROYOBJECT:
+ delete (SalObject*)lParam;
+ rDef = FALSE;
+ break;
+ case SAL_MSG_CREATESOUND:
+ nRet = ((SalSound*)lParam)->ImplCreate();
+ rDef = FALSE;
+ break;
+ case SAL_MSG_DESTROYSOUND:
+ ((SalSound*)lParam)->ImplDestroy();
+ rDef = FALSE;
+ break;
+ }
+
+ return nRet;
+}
+
+LRESULT CALLBACK SalComWndProcA( HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam )
+{
+ int bDef = TRUE;
+ LRESULT nRet = SalComWndProc( hWnd, nMsg, wParam, lParam, bDef );
+ if ( bDef )
+ {
+ if ( !ImplHandleGlobalMsg( hWnd, nMsg, wParam, lParam, nRet ) )
+ nRet = DefWindowProcA( hWnd, nMsg, wParam, lParam );
+ }
+ return nRet;
+}
+
+LRESULT CALLBACK SalComWndProcW( HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam )
+{
+ int bDef = TRUE;
+ LRESULT nRet = SalComWndProc( hWnd, nMsg, wParam, lParam, bDef );
+ if ( bDef )
+ {
+ if ( !ImplHandleGlobalMsg( hWnd, nMsg, wParam, lParam, nRet ) )
+ nRet = DefWindowProcW( hWnd, nMsg, wParam, lParam );
+ }
+ return nRet;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL SalInstance::AnyInput( USHORT nType )
+{
+ MSG aMsg;
+
+ if ( (nType & (INPUT_ANY)) == (INPUT_ANY) )
+ {
+ // Any Input
+ if ( ImplPeekMessage( &aMsg, 0, 0, 0, PM_NOREMOVE | PM_NOYIELD ) )
+ return TRUE;
+ }
+ else
+ {
+ if ( nType & INPUT_MOUSE )
+ {
+ // Test auf Mouseinput
+ if ( ImplPeekMessage( &aMsg, 0, WM_MOUSEFIRST, WM_MOUSELAST,
+ PM_NOREMOVE | PM_NOYIELD ) )
+ return TRUE;
+ }
+
+ if ( nType & INPUT_KEYBOARD )
+ {
+ // Test auf Keyinput
+ if ( ImplPeekMessage( &aMsg, 0, WM_KEYDOWN, WM_KEYDOWN,
+ PM_NOREMOVE | PM_NOYIELD ) )
+ {
+ if ( (aMsg.wParam == VK_SHIFT) ||
+ (aMsg.wParam == VK_CONTROL) ||
+ (aMsg.wParam == VK_MENU) )
+ return FALSE;
+ else
+ return TRUE;
+ }
+ }
+
+ if ( nType & INPUT_PAINT )
+ {
+ // Test auf Paintinput
+ if ( ImplPeekMessage( &aMsg, 0, WM_PAINT, WM_PAINT,
+ PM_NOREMOVE | PM_NOYIELD ) )
+ return TRUE;
+ }
+
+ if ( nType & INPUT_TIMER )
+ {
+ // Test auf Timerinput
+ if ( ImplPeekMessage( &aMsg, 0, WM_TIMER, WM_TIMER,
+ PM_NOREMOVE | PM_NOYIELD ) )
+ return TRUE;
+ }
+
+ if ( nType & INPUT_OTHER )
+ {
+ // Test auf sonstigen Input
+ if ( ImplPeekMessage( &aMsg, 0, 0, 0, PM_NOREMOVE | PM_NOYIELD ) )
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+void SalTimer::Start( ULONG nMS )
+{
+ // Um auf Main-Thread umzuschalten
+ SalData* pSalData = GetSalData();
+ if ( pSalData->mpFirstInstance )
+ {
+ if ( pSalData->mnAppThreadId != GetCurrentThreadId() )
+ ImplPostMessage( pSalData->mpFirstInstance->maInstData.mhComWnd, SAL_MSG_STARTTIMER, 0, (LPARAM)nMS );
+ else
+ ImplSendMessage( pSalData->mpFirstInstance->maInstData.mhComWnd, SAL_MSG_STARTTIMER, 0, (LPARAM)nMS );
+ }
+ else
+ ImplSalStartTimer( nMS, FALSE );
+}
+
+// -----------------------------------------------------------------------
+
+SalFrame* SalInstance::CreateChildFrame( SystemParentData* pSystemParentData, ULONG nSalFrameStyle )
+{
+ // Um auf Main-Thread umzuschalten
+ return (SalFrame*)ImplSendMessage( maInstData.mhComWnd, SAL_MSG_CREATEFRAME, nSalFrameStyle, (LPARAM)pSystemParentData->hWnd );
+}
+
+// -----------------------------------------------------------------------
+
+SalFrame* SalInstance::CreateFrame( SalFrame* pParent, ULONG nSalFrameStyle )
+{
+ // Um auf Main-Thread umzuschalten
+ HWND hWndParent;
+ if ( pParent )
+ hWndParent = pParent->maFrameData.mhWnd;
+ else
+ hWndParent = 0;
+ return (SalFrame*)ImplSendMessage( maInstData.mhComWnd, SAL_MSG_CREATEFRAME, nSalFrameStyle, (LPARAM)hWndParent );
+}
+
+// -----------------------------------------------------------------------
+
+void SalInstance::DestroyFrame( SalFrame* pFrame )
+{
+ ImplSendMessage( maInstData.mhComWnd, SAL_MSG_DESTROYFRAME, 0, (LPARAM)pFrame );
+}
+
+// -----------------------------------------------------------------------
+
+SalObject* SalInstance::CreateObject( SalFrame* pParent )
+{
+ // Um auf Main-Thread umzuschalten
+ return (SalObject*)ImplSendMessage( maInstData.mhComWnd, SAL_MSG_CREATEOBJECT, 0, (LPARAM)pParent );
+}
+
+// -----------------------------------------------------------------------
+
+void SalInstance::DestroyObject( SalObject* pObject )
+{
+ ImplSendMessage( maInstData.mhComWnd, SAL_MSG_DESTROYOBJECT, 0, (LPARAM)pObject );
+}
diff --git a/vcl/win/source/app/salshl.cxx b/vcl/win/source/app/salshl.cxx
new file mode 100644
index 000000000000..3c026c053906
--- /dev/null
+++ b/vcl/win/source/app/salshl.cxx
@@ -0,0 +1,198 @@
+/*************************************************************************
+ *
+ * $RCSfile: salshl.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:49 $
+ *
+ * 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 _SVWIN_H
+#include <tools/svwin.h>
+#endif
+
+#define _SV_SALSHL_CXX
+
+#ifndef _SV_SALDATA_HXX
+#include <saldata.hxx>
+#endif
+
+#ifndef _DEBUG_HXX
+#include <tools/debug.hxx>
+#endif
+
+// =======================================================================
+
+SalShlData aSalShlData;
+
+// =======================================================================
+
+#ifdef WIN
+
+extern "C"
+{
+
+int CALLBACK LibMain( HINSTANCE hInst, WORD, WORD nHeap, LPSTR )
+{
+ if ( nHeap )
+ UnlockData( 0 );
+
+ aSalShlData.mhInst = hInst;
+
+ return 1;
+}
+
+// -----------------------------------------------------------------------
+
+int CALLBACK WEP( int )
+{
+ return 1;
+}
+
+}
+
+#endif
+
+// =======================================================================
+
+#ifdef WNT
+
+extern "C"
+{
+
+#ifdef ICC
+int _CRT_init(void);
+#else
+WIN_BOOL WINAPI _CRT_INIT( HINSTANCE hInst, DWORD nReason, LPVOID pReserved );
+#endif
+
+WIN_BOOL WINAPI LibMain( HINSTANCE hInst, DWORD nReason, LPVOID pReserved )
+{
+ // Unsere DLL-Initialisierung
+ if ( nReason == DLL_PROCESS_ATTACH )
+ aSalShlData.mhInst = hInst;
+
+#if !defined ( __BORLANDC__ )
+#ifdef ICC
+ if ( _CRT_init() == -1 )
+#else
+ if ( !_CRT_INIT( hInst, nReason, pReserved ) )
+#endif
+ return 0;
+#endif
+
+ return 1;
+}
+
+}
+
+#endif
+
+// =======================================================================
+
+HCURSOR ImplLoadSalCursor( int nId )
+{
+ DBG_ASSERT( aSalShlData.mhInst, "no DLL instance handle" );
+
+ HCURSOR hCursor = LoadCursor( aSalShlData.mhInst, MAKEINTRESOURCE( nId ) );
+
+ DBG_ASSERT( hCursor, "cursor not found in sal resource" );
+
+ return hCursor;
+}
+
+// -----------------------------------------------------------------------
+
+HBITMAP ImplLoadSalBitmap( int nId )
+{
+ DBG_ASSERT( aSalShlData.mhInst, "no DLL instance handle" );
+
+ HBITMAP hBitmap = LoadBitmap( aSalShlData.mhInst, MAKEINTRESOURCE( nId ) );
+
+ DBG_ASSERT( hBitmap, "bitmap not found in sal resource" );
+
+ return hBitmap;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL ImplLoadSalIcon( int nId, HICON& rIcon, HICON& rSmallIcon )
+{
+ DBG_ASSERT( aSalShlData.mhInst, "no DLL instance handle" );
+
+ // Try at first to load the icons from the application exe file
+ SalData* pSalData = GetSalData();
+ rIcon = LoadIcon( pSalData->mhInst, MAKEINTRESOURCE( nId ) );
+ if ( !rIcon )
+ {
+ // If the application don't provide these icons, then we try
+ // to load the icon from the VCL resource
+ rIcon = LoadIcon( aSalShlData.mhInst, MAKEINTRESOURCE( nId ) );
+ if ( rIcon )
+ {
+ rSmallIcon = (HICON)LoadImage( aSalShlData.mhInst, MAKEINTRESOURCE( nId ),
+ IMAGE_ICON, 16, 16, 0 );
+ }
+ else
+ rSmallIcon = 0;
+ }
+ else
+ {
+ rSmallIcon = (HICON)LoadImage( pSalData->mhInst, MAKEINTRESOURCE( nId ),
+ IMAGE_ICON, 16, 16, 0 );
+ }
+
+ return (rSmallIcon != 0);
+}
diff --git a/vcl/win/source/app/saltimer.cxx b/vcl/win/source/app/saltimer.cxx
new file mode 100644
index 000000000000..b051c72110bf
--- /dev/null
+++ b/vcl/win/source/app/saltimer.cxx
@@ -0,0 +1,152 @@
+/*************************************************************************
+ *
+ * $RCSfile: saltimer.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:49 $
+ *
+ * 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 _SVWIN_H
+#include <tools/svwin.h>
+#endif
+
+#define _SV_SALTIMER_CXX
+
+#ifndef _SV_SALDATA_HXX
+#include <saldata.hxx>
+#endif
+#ifndef _SV_SALTIMER_HXX
+#include <saltimer.hxx>
+#endif
+
+// =======================================================================
+
+// Maximale Periode
+#define MAX_SYSPERIOD 65533
+
+// =======================================================================
+
+void ImplSalStartTimer( ULONG nMS, BOOL bMutex )
+{
+ SalData* pSalData = GetSalData();
+
+ // Remenber the time of the timer
+ pSalData->mnTimerMS = nMS;
+ if ( !bMutex )
+ pSalData->mnTimerOrgMS = nMS;
+
+ // Periode darf nicht zu gross sein, da Windows mit USHORT arbeitet
+ if ( nMS > MAX_SYSPERIOD )
+ nMS = MAX_SYSPERIOD;
+
+ // Gibt es einen Timer, dann zerstoren
+ if ( pSalData->mnTimerId )
+ KillTimer( 0, pSalData->mnTimerId );
+
+ // Make a new timer with new period
+ pSalData->mnTimerId = SetTimer( 0, 0, (UINT)nMS, SalTimerProc );
+}
+
+// -----------------------------------------------------------------------
+
+void SalTimer::Stop()
+{
+ SalData* pSalData = GetSalData();
+
+ // If we have a timer, than
+ if ( pSalData->mnTimerId )
+ {
+ KillTimer( 0, pSalData->mnTimerId );
+ pSalData->mnTimerId = 0;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void SalTimer::SetCallback( SALTIMERPROC pProc )
+{
+ SalData* pSalData = GetSalData();
+ pSalData->mpTimerProc = pProc;
+}
+
+// -----------------------------------------------------------------------
+
+void CALLBACK SalTimerProc( HWND, UINT, UINT, DWORD )
+{
+ SalData* pSalData = GetSalData();
+
+ // Test for MouseLeave
+ SalTestMouseLeave();
+
+ if ( pSalData->mpTimerProc )
+ {
+ // Try to aquire the mutex. If we don't get the mutex then we
+ // try this a short time later again.
+ if ( ImplSalYieldMutexTryToAcquire() )
+ {
+ pSalData->mpTimerProc();
+ ImplSalYieldMutexRelease();
+
+ // Run the timer in the correct time, if we start this
+ // with a small timeout, because we don't get the mutex
+ if ( pSalData->mnTimerId &&
+ (pSalData->mnTimerMS != pSalData->mnTimerOrgMS) )
+ ImplSalStartTimer( pSalData->mnTimerOrgMS, FALSE );
+ }
+ else
+ ImplSalStartTimer( 10, TRUE );
+ }
+}
diff --git a/vcl/win/source/gdi/MAKEFILE.MK b/vcl/win/source/gdi/MAKEFILE.MK
new file mode 100644
index 000000000000..c63a3cdd19f4
--- /dev/null
+++ b/vcl/win/source/gdi/MAKEFILE.MK
@@ -0,0 +1,52 @@
+#*************************************************************************
+#*
+#* $Workfile: makefile. $
+#*
+#* Ersterstellung TH 01.04.97
+#* Letzte Aenderung $Author: hr $ $Date: 2000-09-18 17:05:49 $
+#* $Revision: 1.1.1.1 $
+#*
+#* $Logfile: T:/sv2/win/source/gdi/makefile.__v $
+#*
+#* Copyright (c) 1990 - 1997, STAR DIVISION
+#*
+#*************************************************************************
+
+PRJ=..$/..$/..
+
+PRJNAME=vcl
+TARGET=salgdi
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : svpre.mk
+.INCLUDE : settings.mk
+.INCLUDE : sv.mk
+
+# --- Files --------------------------------------------------------
+
+SLOFILES= $(SLO)$/salgdi.obj \
+ $(SLO)$/salgdi2.obj \
+ $(SLO)$/salgdi3.obj \
+ $(SLO)$/salvd.obj \
+ $(SLO)$/salprn.obj \
+ $(SLO)$/salbmp.obj \
+ $(SLO)$/salogl.obj
+
+.IF "$(GUI)" == "WNT"
+SLOFILES+=$(SLO)$/wntgdi.obj
+.ENDIF
+
+.IF "$(UPDATER)"=="YES"
+OBJFILES= $(OBJ)$/salgdi.obj \
+ $(OBJ)$/salgdi2.obj \
+ $(OBJ)$/salgdi3.obj \
+ $(OBJ)$/salvd.obj \
+ $(OBJ)$/salprn.obj \
+ $(OBJ)$/salbmp.obj \
+ $(OBJ)$/salogl.obj
+.ENDIF
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
diff --git a/vcl/win/source/gdi/salbmp.cxx b/vcl/win/source/gdi/salbmp.cxx
new file mode 100644
index 000000000000..ec0f9914b5ee
--- /dev/null
+++ b/vcl/win/source/gdi/salbmp.cxx
@@ -0,0 +1,668 @@
+/*************************************************************************
+ *
+ * $RCSfile: salbmp.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:49 $
+ *
+ * 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 _SVWIN_H
+#include <tools/svwin.h>
+#endif
+
+#define _SV_SALBMP_CXX
+
+#ifndef _SV_WINCOMP_HXX
+#include <wincomp.hxx>
+#endif
+#ifndef _SV_SALBTYPE_HXX
+#include <salbtype.hxx>
+#endif
+#ifndef _SV_SALGDI_HXX
+#include <salgdi.hxx>
+#endif
+#ifndef _SV_SALDATA_HXX
+#include <saldata.hxx>
+#endif
+#ifndef _SV_SALBMP_HXX
+#include <salbmp.hxx>
+#endif
+#include <string.h>
+
+#ifdef WIN
+#define BI_BITFIELDS 3
+#endif
+
+// -----------
+// - Inlines -
+// -----------
+
+inline void ImplSetPixel4( const HPBYTE pScanline, long nX, const BYTE cIndex )
+{
+ BYTE& rByte = pScanline[ nX >> 1 ];
+
+ ( nX & 1 ) ? ( rByte &= 0xf0, rByte |= ( cIndex & 0x0f ) ) :
+ ( rByte &= 0x0f, rByte |= ( cIndex << 4 ) );
+}
+
+// -------------
+// - SalBitmap -
+// -------------
+
+SalBitmap::SalBitmap() :
+ mhDIB ( 0 ),
+ mhDDB ( 0 ),
+ mnBitCount ( 0 )
+{
+}
+
+// ------------------------------------------------------------------
+
+SalBitmap::~SalBitmap()
+{
+ Destroy();
+}
+
+// ------------------------------------------------------------------
+
+BOOL SalBitmap::Create( HANDLE hBitmap, BOOL bDIB, BOOL bCopyHandle )
+{
+ BOOL bRet = TRUE;
+
+ if( bDIB )
+ mhDIB = (HGLOBAL) ( bCopyHandle ? ImplCopyDIBOrDDB( hBitmap, TRUE ) : hBitmap );
+ else
+ mhDDB = (HBITMAP) ( bCopyHandle ? ImplCopyDIBOrDDB( hBitmap, FALSE ) : hBitmap );
+
+ if( mhDIB )
+ {
+ PBITMAPINFOHEADER pBIH = (PBITMAPINFOHEADER) GlobalLock( mhDIB );
+
+ maSize = Size( pBIH->biWidth, pBIH->biHeight );
+ mnBitCount = pBIH->biBitCount;
+
+ if( mnBitCount )
+ mnBitCount = ( mnBitCount <= 1 ) ? 1 : ( mnBitCount <= 4 ) ? 4 : ( mnBitCount <= 8 ) ? 8 : 24;
+
+ GlobalUnlock( mhDIB );
+ }
+ else if( mhDDB )
+ {
+ BITMAP aDDBInfo;
+
+ if( WIN_GetObject( mhDDB, sizeof( BITMAP ), &aDDBInfo ) )
+ {
+ maSize = Size( aDDBInfo.bmWidth, aDDBInfo.bmHeight );
+ mnBitCount = aDDBInfo.bmPlanes * aDDBInfo.bmBitsPixel;
+
+ if( mnBitCount )
+ {
+ mnBitCount = ( mnBitCount <= 1 ) ? 1 :
+ ( mnBitCount <= 4 ) ? 4 :
+ ( mnBitCount <= 8 ) ? 8 : 24;
+ }
+ }
+ else
+ {
+ mhDDB = 0;
+ bRet = FALSE;
+ }
+ }
+ else
+ bRet = FALSE;
+
+ return bRet;
+}
+
+// ------------------------------------------------------------------
+
+BOOL SalBitmap::Create( const Size& rSize, USHORT nBitCount, const BitmapPalette& rPal )
+{
+ BOOL bRet = FALSE;
+
+ mhDIB = ImplCreateDIB( rSize, nBitCount, rPal );
+
+ if( mhDIB )
+ {
+ maSize = rSize;
+ mnBitCount = nBitCount;
+ bRet = TRUE;
+ }
+
+ return bRet;
+}
+
+// ------------------------------------------------------------------
+
+BOOL SalBitmap::Create( const SalBitmap& rSalBitmap )
+{
+ BOOL bRet = FALSE;
+
+ if ( rSalBitmap.mhDIB || rSalBitmap.mhDDB )
+ {
+ HANDLE hNewHdl = ImplCopyDIBOrDDB( rSalBitmap.mhDIB ? rSalBitmap.mhDIB : rSalBitmap.mhDDB,
+ rSalBitmap.mhDIB != 0 );
+
+ if ( hNewHdl )
+ {
+ if( rSalBitmap.mhDIB )
+ mhDIB = (HGLOBAL) hNewHdl;
+ else if( rSalBitmap.mhDDB )
+ mhDDB = (HBITMAP) hNewHdl;
+
+ maSize = rSalBitmap.maSize;
+ mnBitCount = rSalBitmap.mnBitCount;
+
+ bRet = TRUE;
+ }
+ }
+
+ return bRet;
+}
+
+// ------------------------------------------------------------------
+
+BOOL SalBitmap::Create( const SalBitmap& rSalBmp, SalGraphics* pGraphics )
+{
+ BOOL bRet = FALSE;
+
+ if( rSalBmp.mhDIB )
+ {
+ PBITMAPINFO pBI = (PBITMAPINFO) GlobalLock( rSalBmp.mhDIB );
+ PBITMAPINFOHEADER pBIH = (PBITMAPINFOHEADER) pBI;
+ HDC hDC = pGraphics->maGraphicsData.mhDC;
+ HBITMAP hNewDDB;
+ BITMAP aDDBInfo;
+ PBYTE pBits = (PBYTE) pBI + *(DWORD*) pBI +
+ ImplGetDIBColorCount( rSalBmp.mhDIB ) * sizeof( RGBQUAD );
+
+ if( pBIH->biBitCount == 1 )
+ {
+ hNewDDB = CreateBitmap( pBIH->biWidth, pBIH->biHeight, 1, 1, NULL );
+
+ if( hNewDDB )
+ SetDIBits( hDC, hNewDDB, 0, pBIH->biHeight, pBits, pBI, DIB_RGB_COLORS );
+ }
+ else
+ hNewDDB = CreateDIBitmap( hDC, (PBITMAPINFOHEADER) pBI, CBM_INIT, pBits, pBI, DIB_RGB_COLORS );
+
+ GlobalUnlock( rSalBmp.mhDIB );
+
+ if( hNewDDB && WIN_GetObject( hNewDDB, sizeof( BITMAP ), &aDDBInfo ) )
+ {
+ mhDDB = hNewDDB;
+ maSize = Size( aDDBInfo.bmWidth, aDDBInfo.bmHeight );
+ mnBitCount = aDDBInfo.bmPlanes * aDDBInfo.bmBitsPixel;
+
+ if( mnBitCount )
+ {
+ mnBitCount = ( mnBitCount <= 1 ) ? 1 :
+ ( mnBitCount <= 4 ) ? 4 :
+ ( mnBitCount <= 8 ) ? 8 : 24;
+ }
+
+ bRet = TRUE;
+ }
+ else if( hNewDDB )
+ DeleteObject( hNewDDB );
+ }
+
+ return bRet;
+}
+
+// ------------------------------------------------------------------
+
+BOOL SalBitmap::Create( const SalBitmap& rSalBmp, USHORT nNewBitCount )
+{
+ BOOL bRet = FALSE;
+
+ if( rSalBmp.mhDDB )
+ {
+ mhDIB = ImplCreateDIB( rSalBmp.maSize, nNewBitCount, BitmapPalette() );
+
+ if( mhDIB )
+ {
+ PBITMAPINFO pBI = (PBITMAPINFO) GlobalLock( mhDIB );
+ const int nLines = (int) rSalBmp.maSize.Height();
+ HDC hDC = GetDC( 0 );
+ PBYTE pBits = (PBYTE) pBI + *(DWORD*) pBI +
+ ImplGetDIBColorCount( mhDIB ) * sizeof( RGBQUAD );
+ SalData* pSalData = GetSalData();
+ HPALETTE hOldPal = 0;
+
+ if ( pSalData->mhDitherPal )
+ {
+ hOldPal = SelectPalette( hDC, pSalData->mhDitherPal, TRUE );
+ RealizePalette( hDC );
+ }
+
+ if( GetDIBits( hDC, rSalBmp.mhDDB, 0, nLines, pBits, pBI, DIB_RGB_COLORS ) == nLines )
+ {
+ GlobalUnlock( mhDIB );
+ maSize = rSalBmp.maSize;
+ mnBitCount = nNewBitCount;
+ bRet = TRUE;
+ }
+ else
+ {
+ GlobalUnlock( mhDIB );
+ GlobalFree( mhDIB );
+ mhDIB = 0;
+ }
+
+ if( hOldPal )
+ SelectPalette( hDC, hOldPal, TRUE );
+
+ ReleaseDC( 0, hDC );
+ }
+ }
+
+ return bRet;
+}
+
+// ------------------------------------------------------------------
+
+void SalBitmap::Destroy()
+{
+ if( mhDIB )
+ GlobalFree( mhDIB );
+ else if( mhDDB )
+ DeleteObject( mhDDB );
+
+ maSize = Size();
+ mnBitCount = 0;
+}
+
+// ------------------------------------------------------------------
+
+USHORT SalBitmap::ImplGetDIBColorCount( HGLOBAL hDIB )
+{
+ USHORT nColors = 0;
+
+ if( hDIB )
+ {
+ PBITMAPINFO pBI = (PBITMAPINFO) GlobalLock( hDIB );
+ PBITMAPINFOHEADER pBIH = (PBITMAPINFOHEADER) pBI;
+
+ if ( pBIH->biSize != sizeof( BITMAPCOREHEADER ) )
+ {
+ if( pBIH->biBitCount <= 8 )
+ {
+ if ( pBIH->biClrUsed )
+ nColors = (USHORT) pBIH->biClrUsed;
+ else
+ nColors = 1 << pBIH->biBitCount;
+ }
+ }
+ else if( ( (PBITMAPCOREHEADER) pBI )->bcBitCount <= 8 )
+ nColors = 1 << ( (PBITMAPCOREHEADER) pBI )->bcBitCount;
+
+ GlobalUnlock( hDIB );
+ }
+
+ return nColors;
+}
+
+// ------------------------------------------------------------------
+
+HGLOBAL SalBitmap::ImplCreateDIB( const Size& rSize, USHORT nBits, const BitmapPalette& rPal )
+{
+ DBG_ASSERT( nBits == 1 || nBits == 4 || nBits == 8 || nBits == 24, "Unsupported BitCount!" );
+
+ HGLOBAL hDIB = 0;
+
+ if ( rSize.Width() && rSize.Height() && ( nBits == 1 || nBits == 4 || nBits == 8 || nBits == 24 ) )
+ {
+ const ULONG nImageSize = AlignedWidth4Bytes( nBits * rSize.Width() ) * rSize.Height();
+ const USHORT nColors = ( nBits <= 8 ) ? ( 1 << nBits ) : 0;
+
+ hDIB = GlobalAlloc( GHND, sizeof( BITMAPINFOHEADER ) + nColors * sizeof( RGBQUAD ) + nImageSize );
+
+ if( hDIB )
+ {
+ PBITMAPINFO pBI = (PBITMAPINFO) GlobalLock( hDIB );
+ PBITMAPINFOHEADER pBIH = (PBITMAPINFOHEADER) pBI;
+
+ pBIH->biSize = sizeof( BITMAPINFOHEADER );
+ pBIH->biWidth = rSize.Width();
+ pBIH->biHeight = rSize.Height();
+ pBIH->biPlanes = 1;
+ pBIH->biBitCount = nBits;
+ pBIH->biCompression = BI_RGB;
+ pBIH->biSizeImage = nImageSize;
+ pBIH->biXPelsPerMeter = 0;
+ pBIH->biYPelsPerMeter = 0;
+ pBIH->biClrUsed = 0;
+ pBIH->biClrImportant = 0;
+
+ if ( nColors )
+ {
+ const USHORT nMinCount = Min( nColors, rPal.GetEntryCount() );
+
+ if( nMinCount )
+ HMEMCPY( pBI->bmiColors, rPal.ImplGetColorBuffer(), nMinCount * sizeof( RGBQUAD ) );
+ }
+
+ GlobalUnlock( hDIB );
+ }
+ }
+
+ return hDIB;
+}
+
+// ------------------------------------------------------------------
+
+HANDLE SalBitmap::ImplCopyDIBOrDDB( HANDLE hHdl, BOOL bDIB )
+{
+ HANDLE hCopy = 0;
+
+ if ( bDIB && hHdl )
+ {
+ const ULONG nSize = GlobalSize( hHdl );
+
+ if ( hCopy = GlobalAlloc( GHND, nSize ) )
+ {
+ HMEMCPY( (LPSTR) GlobalLock( hCopy ), (LPSTR) GlobalLock( hHdl ), nSize );
+
+ GlobalUnlock( hCopy );
+ GlobalUnlock( hHdl );
+ }
+ }
+ else if ( hHdl )
+ {
+ BITMAP aBmp;
+
+ // Source-Bitmap nach Groesse befragen
+ WIN_GetObject( hHdl, sizeof( BITMAP ), (LPSTR) &aBmp );
+
+ // Destination-Bitmap erzeugen
+ if ( hCopy = CreateBitmapIndirect( &aBmp ) )
+ {
+ HDC hBmpDC = CreateCompatibleDC( 0 );
+ HBITMAP hBmpOld = (HBITMAP) SelectObject( hBmpDC, hHdl );
+ HDC hCopyDC = CreateCompatibleDC( hBmpDC );
+ HBITMAP hCopyOld = (HBITMAP) SelectObject( hCopyDC, hCopy );
+
+ BitBlt( hCopyDC, 0, 0, aBmp.bmWidth, aBmp.bmHeight, hBmpDC, 0, 0, SRCCOPY );
+
+ SelectObject( hCopyDC, hCopyOld );
+ DeleteDC( hCopyDC );
+
+ SelectObject( hBmpDC, hBmpOld );
+ DeleteDC( hBmpDC );
+ }
+ }
+
+ return hCopy;
+}
+
+// ------------------------------------------------------------------
+
+BitmapBuffer* SalBitmap::AcquireBuffer( BOOL bReadOnly )
+{
+ BitmapBuffer* pBuffer = NULL;
+
+ if( mhDIB )
+ {
+ PBITMAPINFO pBI = (PBITMAPINFO) GlobalLock( mhDIB );
+ PBITMAPINFOHEADER pBIH = (PBITMAPINFOHEADER) pBI;
+
+ if( ( pBIH->biCompression == BI_RLE4 ) || ( pBIH->biCompression == BI_RLE8 ) )
+ {
+ Size aSizePix( pBIH->biWidth, pBIH->biHeight );
+ HGLOBAL hNewDIB = ImplCreateDIB( aSizePix, pBIH->biBitCount, BitmapPalette() );
+
+ if( hNewDIB )
+ {
+ PBITMAPINFO pNewBI = (PBITMAPINFO) GlobalLock( hNewDIB );
+ PBITMAPINFOHEADER pNewBIH = (PBITMAPINFOHEADER) pNewBI;
+ const USHORT nColorCount = ImplGetDIBColorCount( hNewDIB );
+ const ULONG nOffset = *(DWORD*) pBI + nColorCount * sizeof( RGBQUAD );
+ BYTE* pOldBits = (PBYTE) pBI + nOffset;
+ BYTE* pNewBits = (PBYTE) pNewBI + nOffset;
+
+ HMEMCPY( pNewBI, pBI, nOffset );
+ pNewBIH->biCompression = 0;
+ ImplDecodeRLEBuffer( pOldBits, pNewBits, aSizePix, pBIH->biCompression == BI_RLE4 );
+
+ GlobalUnlock( mhDIB );
+ GlobalFree( mhDIB );
+ mhDIB = hNewDIB;
+ pBI = pNewBI;
+ pBIH = pNewBIH;
+ }
+ }
+
+ if( pBIH->biPlanes == 1 )
+ {
+ pBuffer = new BitmapBuffer;
+
+ pBuffer->mnFormat = BMP_FORMAT_BOTTOM_UP |
+ ( pBIH->biBitCount == 1 ? BMP_FORMAT_1BIT_MSB_PAL :
+ pBIH->biBitCount == 4 ? BMP_FORMAT_4BIT_MSN_PAL :
+ pBIH->biBitCount == 8 ? BMP_FORMAT_8BIT_PAL :
+ pBIH->biBitCount == 16 ? BMP_FORMAT_16BIT_TC_MASK :
+ pBIH->biBitCount == 24 ? BMP_FORMAT_24BIT_TC_BGR :
+ pBIH->biBitCount == 32 ? BMP_FORMAT_32BIT_TC_MASK : 0UL );
+
+ if( BMP_SCANLINE_FORMAT( pBuffer->mnFormat ) )
+ {
+ pBuffer->mnWidth = maSize.Width();
+ pBuffer->mnHeight = maSize.Height();
+ pBuffer->mnScanlineSize = AlignedWidth4Bytes( maSize.Width() * pBIH->biBitCount );
+ pBuffer->mnBitCount = (USHORT) pBIH->biBitCount;
+
+ if( pBuffer->mnBitCount <= 8 )
+ {
+ const USHORT nPalCount = ImplGetDIBColorCount( mhDIB );
+
+ pBuffer->maPalette.SetEntryCount( nPalCount );
+ HMEMCPY( pBuffer->maPalette.ImplGetColorBuffer(), pBI->bmiColors, nPalCount * sizeof( RGBQUAD ) );
+ pBuffer->mpBits = (PBYTE) pBI + *(DWORD*) pBI + nPalCount * sizeof( RGBQUAD );
+ }
+ else if( ( pBIH->biBitCount == 16 ) || ( pBIH->biBitCount == 32 ) )
+ {
+ ULONG nOffset = 0UL;
+
+ if( pBIH->biCompression == BI_BITFIELDS )
+ {
+ nOffset = 3 * sizeof( RGBQUAD );
+ pBuffer->maColorMask = ColorMask( *(UINT32*) &pBI->bmiColors[ 0 ],
+ *(UINT32*) &pBI->bmiColors[ 1 ],
+ *(UINT32*) &pBI->bmiColors[ 2 ] );
+ }
+ else if( pBIH->biCompression == 16 )
+ pBuffer->maColorMask = ColorMask( 0x00007c00UL, 0x000003e0UL, 0x0000001fUL );
+ else
+ pBuffer->maColorMask = ColorMask( 0x00ff0000UL, 0x0000ff00UL, 0x000000ffUL );
+
+ pBuffer->mpBits = (PBYTE) pBI + *(DWORD*) pBI + nOffset;
+ }
+ else
+ pBuffer->mpBits = (PBYTE) pBI + *(DWORD*) pBI;
+ }
+ else
+ {
+ GlobalUnlock( mhDIB );
+ delete pBuffer;
+ pBuffer = NULL;
+ }
+ }
+ else
+ GlobalUnlock( mhDIB );
+ }
+
+ return pBuffer;
+}
+
+// ------------------------------------------------------------------
+
+void SalBitmap::ReleaseBuffer( BitmapBuffer* pBuffer, BOOL bReadOnly )
+{
+ if( pBuffer )
+ {
+ if( mhDIB )
+ {
+ if( !bReadOnly && !!pBuffer->maPalette )
+ {
+ PBITMAPINFO pBI = (PBITMAPINFO) GlobalLock( mhDIB );
+ const USHORT nCount = pBuffer->maPalette.GetEntryCount();
+
+ HMEMCPY( pBI->bmiColors, pBuffer->maPalette.ImplGetColorBuffer(), nCount * sizeof( RGBQUAD ) );
+ GlobalUnlock( mhDIB );
+ }
+
+ GlobalUnlock( mhDIB );
+ }
+
+ delete pBuffer;
+ }
+}
+
+// ------------------------------------------------------------------
+
+void SalBitmap::ImplDecodeRLEBuffer( const BYTE* pSrcBuf, BYTE* pDstBuf,
+ const Size& rSizePixel, BOOL bRLE4 )
+{
+ HPBYTE pRLE = (HPBYTE) pSrcBuf;
+ HPBYTE pDIB = (HPBYTE) pDstBuf;
+ HPBYTE pRow = (HPBYTE) pDstBuf;
+ ULONG nWidthAl = AlignedWidth4Bytes( rSizePixel.Width() * ( bRLE4 ? 4UL : 8UL ) );
+ HPBYTE pLast = pDIB + rSizePixel.Height() * nWidthAl - 1;
+ ULONG nCountByte;
+ ULONG nRunByte;
+ ULONG nX = 0;
+ ULONG i;
+ BYTE cTmp;
+ BOOL bEndDecoding = FALSE;
+
+ if( pRLE && pDIB )
+ {
+ do
+ {
+ if( !( nCountByte = *pRLE++ ) )
+ {
+ nRunByte = *pRLE++;
+
+ if( nRunByte > 2UL )
+ {
+ if( bRLE4 )
+ {
+ nCountByte = nRunByte >> 1UL;
+
+ for( i = 0; i < nCountByte; i++ )
+ {
+ cTmp = *pRLE++;
+ ImplSetPixel4( pDIB, nX++, cTmp >> 4 );
+ ImplSetPixel4( pDIB, nX++, cTmp & 0x0f );
+ }
+
+ if( nRunByte & 1 )
+ ImplSetPixel4( pDIB, nX++, *pRLE++ >> 4 );
+
+ if( ( ( nRunByte + 1 ) >> 1 ) & 1 )
+ pRLE++;
+ }
+ else
+ {
+ HMEMCPY( &pDIB[ nX ], pRLE, nRunByte );
+ pRLE += nRunByte;
+ nX += nRunByte;
+
+ if( nRunByte & 1 )
+ pRLE++;
+ }
+ }
+ else if( !nRunByte )
+ {
+ pDIB = ( pRow += nWidthAl );
+ nX = 0UL;
+ }
+ else if( nRunByte == 1 )
+ bEndDecoding = TRUE;
+ else
+ {
+ nX += *pRLE++;
+ pDIB = ( pRow += ( *pRLE++ ) * nWidthAl );
+ }
+ }
+ else
+ {
+ cTmp = *pRLE++;
+
+ if( bRLE4 )
+ {
+ nRunByte = nCountByte >> 1;
+
+ for( i = 0; i < nRunByte; i++ )
+ {
+ ImplSetPixel4( pDIB, nX++, cTmp >> 4 );
+ ImplSetPixel4( pDIB, nX++, cTmp & 0x0f );
+ }
+
+ if( nCountByte & 1 )
+ ImplSetPixel4( pDIB, nX++, cTmp >> 4 );
+ }
+ else
+ {
+ for( i = 0; i < nCountByte; i++ )
+ pDIB[ nX++ ] = cTmp;
+ }
+ }
+ }
+ while( !bEndDecoding && ( pDIB <= pLast ) );
+ }
+}
diff --git a/vcl/win/source/gdi/salgdi.cxx b/vcl/win/source/gdi/salgdi.cxx
new file mode 100644
index 000000000000..f8f5892add4e
--- /dev/null
+++ b/vcl/win/source/gdi/salgdi.cxx
@@ -0,0 +1,1449 @@
+/*************************************************************************
+ *
+ * $RCSfile: salgdi.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:49 $
+ *
+ * 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 <string.h>
+
+#ifndef _SVWIN_H
+#include <tools/svwin.h>
+#endif
+#define _SV_SALGDI_CXX
+
+#ifndef _SV_WINCOMP_HXX
+#include <wincomp.hxx>
+#endif
+#ifndef _SV_SALDATA_HXX
+#include <saldata.hxx>
+#endif
+#ifndef _SV_SALGDI_HXX
+#include <salgdi.hxx>
+#endif
+#ifndef _DEBUG_HXX
+#include <tools/debug.hxx>
+#endif
+
+// =======================================================================
+
+#define DITHER_PAL_DELTA 51
+#define DITHER_PAL_STEPS 6
+#define DITHER_PAL_COUNT (DITHER_PAL_STEPS*DITHER_PAL_STEPS*DITHER_PAL_STEPS)
+#define DITHER_MAX_SYSCOLOR 16
+#define DITHER_EXTRA_COLORS 1
+#define DMAP( _def_nVal, _def_nThres ) ((pDitherDiff[_def_nVal]>(_def_nThres))?pDitherHigh[_def_nVal]:pDitherLow[_def_nVal])
+
+// =======================================================================
+
+struct SysColorEntry
+{
+ DWORD nRGB;
+ SysColorEntry* pNext;
+};
+
+// =======================================================================
+
+static SysColorEntry* pFirstSysColor = NULL;
+static SysColorEntry* pActSysColor = NULL;
+
+// -----------------------------------------------------------------------------
+
+// Blue7
+static PALETTEENTRY aImplExtraColor1 =
+{
+ 0, 184, 255, 0
+};
+
+// -----------------------------------------------------------------------------
+
+static PALETTEENTRY aImplSalSysPalEntryAry[ DITHER_MAX_SYSCOLOR ] =
+{
+{ 0, 0, 0, 0 },
+{ 0, 0, 0x80, 0 },
+{ 0, 0x80, 0, 0 },
+{ 0, 0x80, 0x80, 0 },
+{ 0x80, 0, 0, 0 },
+{ 0x80, 0, 0x80, 0 },
+{ 0x80, 0x80, 0, 0 },
+{ 0x80, 0x80, 0x80, 0 },
+{ 0xC0, 0xC0, 0xC0, 0 },
+{ 0, 0, 0xFF, 0 },
+{ 0, 0xFF, 0, 0 },
+{ 0, 0xFF, 0xFF, 0 },
+{ 0xFF, 0, 0, 0 },
+{ 0xFF, 0, 0xFF, 0 },
+{ 0xFF, 0xFF, 0, 0 },
+{ 0xFF, 0xFF, 0xFF, 0 }
+};
+
+// -----------------------------------------------------------------------------
+
+static BYTE aOrdDither8Bit[8][8] =
+{
+ 0, 38, 9, 48, 2, 40, 12, 50,
+ 25, 12, 35, 22, 28, 15, 37, 24,
+ 6, 44, 3, 41, 8, 47, 5, 44,
+ 32, 19, 28, 16, 34, 21, 31, 18,
+ 1, 40, 11, 49, 0, 39, 10, 48,
+ 27, 14, 36, 24, 26, 13, 36, 23,
+ 8, 46, 4, 43, 7, 45, 4, 42,
+ 33, 20, 30, 17, 32, 20, 29, 16
+};
+
+// -----------------------------------------------------------------------------
+
+static BYTE aOrdDither16Bit[8][8] =
+{
+ 0, 6, 1, 7, 0, 6, 1, 7,
+ 4, 2, 5, 3, 4, 2, 5, 3,
+ 1, 7, 0, 6, 1, 7, 0, 6,
+ 5, 3, 4, 2, 5, 3, 4, 2,
+ 0, 6, 1, 7, 0, 6, 1, 7,
+ 4, 2, 5, 3, 4, 2, 5, 3,
+ 1, 7, 0, 6, 1, 7, 0, 6,
+ 5, 3, 4, 2, 5, 3, 4, 2
+};
+
+// =======================================================================
+
+// Pens muessen wir mit 1 Pixel-Breite erzeugen, da ansonsten die S3-Karte
+// viele Paintprobleme hat, wenn Polygone/PolyLines gezeichnet werden und
+// eine komplexe ClipRegion gesetzt ist
+#define GSL_PEN_WIDTH 1
+
+// =======================================================================
+
+#define SAL_POLYPOLYCOUNT_STACKBUF 8
+#define SAL_POLYPOLYPOINTS_STACKBUF 64
+
+// =======================================================================
+
+void ImplInitSalGDI()
+{
+ SalData* pSalData = GetSalData();
+
+ // init stock brushes
+ pSalData->maStockPenColorAry[0] = PALETTERGB( 0, 0, 0 );
+ pSalData->maStockPenColorAry[1] = PALETTERGB( 0xFF, 0xFF, 0xFF );
+ pSalData->maStockPenColorAry[2] = PALETTERGB( 0xC0, 0xC0, 0xC0 );
+ pSalData->maStockPenColorAry[3] = PALETTERGB( 0x80, 0x80, 0x80 );
+ pSalData->mhStockPenAry[0] = CreatePen( PS_SOLID, GSL_PEN_WIDTH, pSalData->maStockPenColorAry[0] );
+ pSalData->mhStockPenAry[1] = CreatePen( PS_SOLID, GSL_PEN_WIDTH, pSalData->maStockPenColorAry[1] );
+ pSalData->mhStockPenAry[2] = CreatePen( PS_SOLID, GSL_PEN_WIDTH, pSalData->maStockPenColorAry[2] );
+ pSalData->mhStockPenAry[3] = CreatePen( PS_SOLID, GSL_PEN_WIDTH, pSalData->maStockPenColorAry[3] );
+ pSalData->mnStockPenCount = 4;
+
+ pSalData->maStockBrushColorAry[0] = PALETTERGB( 0, 0, 0 );
+ pSalData->maStockBrushColorAry[1] = PALETTERGB( 0xFF, 0xFF, 0xFF );
+ pSalData->maStockBrushColorAry[2] = PALETTERGB( 0xC0, 0xC0, 0xC0 );
+ pSalData->maStockBrushColorAry[3] = PALETTERGB( 0x80, 0x80, 0x80 );
+ pSalData->mhStockBrushAry[0] = CreateSolidBrush( pSalData->maStockBrushColorAry[0] );
+ pSalData->mhStockBrushAry[1] = CreateSolidBrush( pSalData->maStockBrushColorAry[1] );
+ pSalData->mhStockBrushAry[2] = CreateSolidBrush( pSalData->maStockBrushColorAry[2] );
+ pSalData->mhStockBrushAry[3] = CreateSolidBrush( pSalData->maStockBrushColorAry[3] );
+ pSalData->mnStockBrushCount = 4;
+
+ // DC-Cache aufbauen
+ pSalData->mpHDCCache = new HDCCache[ CACHESIZE_HDC ];
+ memset( pSalData->mpHDCCache, 0, CACHESIZE_HDC * sizeof( HDCCache ) );
+
+ // Nur bei 256 Farben Displays, die Paletten unterstuetzen
+ HDC hDC = GetDC( 0 );
+ int nBitsPixel = GetDeviceCaps( hDC, BITSPIXEL );
+ int nPlanes = GetDeviceCaps( hDC, PLANES );
+ int nRasterCaps = GetDeviceCaps( hDC, RASTERCAPS );
+ int nBitCount = nBitsPixel * nPlanes;
+
+ if ( (nBitCount > 8) && (nBitCount < 24) )
+ {
+ // test, if we have to dither
+ HDC hMemDC = ::CreateCompatibleDC( hDC );
+ HBITMAP hMemBmp = ::CreateCompatibleBitmap( hDC, 8, 8 );
+ HBITMAP hBmpOld = (HBITMAP) ::SelectObject( hMemDC, hMemBmp );
+ HBRUSH hMemBrush = ::CreateSolidBrush( PALETTERGB( 175, 171, 169 ) );
+ HBRUSH hBrushOld = (HBRUSH) ::SelectObject( hMemDC, hMemBrush );
+ BOOL bDither16 = TRUE;
+
+ ::PatBlt( hMemDC, 0, 0, 8, 8, PATCOPY );
+ const COLORREF aCol( ::GetPixel( hMemDC, 0, 0 ) );
+
+ for( int nY = 0; ( nY < 8 ) && bDither16; nY++ )
+ for( int nX = 0; ( nX < 8 ) && bDither16; nX++ )
+ if( ::GetPixel( hMemDC, nX, nY ) != aCol )
+ bDither16 = FALSE;
+
+ ::SelectObject( hMemDC, hBrushOld ), ::DeleteObject( hMemBrush );
+ ::SelectObject( hMemDC, hBmpOld ), ::DeleteObject( hMemBmp );
+ ::DeleteDC( hMemDC );
+
+ if( bDither16 )
+ {
+ // create DIBPattern for 16Bit dithering
+ long n;
+
+ pSalData->mhDitherDIB = GlobalAlloc( GMEM_FIXED, sizeof( BITMAPINFOHEADER ) + 192 );
+ pSalData->mpDitherDIB = (BYTE*) GlobalLock( pSalData->mhDitherDIB );
+ pSalData->mpDitherDiff = new long[ 256 ];
+ pSalData->mpDitherLow = new BYTE[ 256 ];
+ pSalData->mpDitherHigh = new BYTE[ 256 ];
+ pSalData->mpDitherDIBData = pSalData->mpDitherDIB + sizeof( BITMAPINFOHEADER );
+ memset( pSalData->mpDitherDIB, 0, sizeof( BITMAPINFOHEADER ) );
+
+ BITMAPINFOHEADER* pBIH = (BITMAPINFOHEADER*) pSalData->mpDitherDIB;
+
+ pBIH->biSize = sizeof( BITMAPINFOHEADER );
+ pBIH->biWidth = 8;
+ pBIH->biHeight = 8;
+ pBIH->biPlanes = 1;
+ pBIH->biBitCount = 24;
+
+ for( n = 0; n < 256L; n++ )
+ pSalData->mpDitherDiff[ n ] = n - ( n & 248L );
+
+ for( n = 0; n < 256L; n++ )
+ pSalData->mpDitherLow[ n ] = (BYTE) ( n & 248 );
+
+ for( n = 0; n < 256L; n++ )
+ pSalData->mpDitherHigh[ n ] = (BYTE) Min( pSalData->mpDitherLow[ n ] + 8L, 255L );
+ }
+ }
+ else if ( (nRasterCaps & RC_PALETTE) && (nBitCount == 8) )
+ {
+ BYTE nRed, nGreen, nBlue;
+ BYTE nR, nG, nB;
+ PALETTEENTRY* pPalEntry;
+ LOGPALETTE* pLogPal;
+ const USHORT nDitherPalCount = DITHER_PAL_COUNT;
+ ULONG nTotalCount = DITHER_MAX_SYSCOLOR + nDitherPalCount + DITHER_EXTRA_COLORS;
+
+ // create logical palette
+ pLogPal = (LOGPALETTE*) new char[ sizeof( LOGPALETTE ) + ( nTotalCount * sizeof( PALETTEENTRY ) ) ];
+ pLogPal->palVersion = 0x0300;
+ pLogPal->palNumEntries = (USHORT) nTotalCount;
+ pPalEntry = pLogPal->palPalEntry;
+
+ // Standard colors
+ memcpy( pPalEntry, aImplSalSysPalEntryAry, DITHER_MAX_SYSCOLOR * sizeof( PALETTEENTRY ) );
+ pPalEntry += DITHER_MAX_SYSCOLOR;
+
+ // own palette (6/6/6)
+ for( nB=0, nBlue=0; nB < DITHER_PAL_STEPS; nB++, nBlue += DITHER_PAL_DELTA )
+ {
+ for( nG=0, nGreen=0; nG < DITHER_PAL_STEPS; nG++, nGreen += DITHER_PAL_DELTA )
+ {
+ for( nR=0, nRed=0; nR < DITHER_PAL_STEPS; nR++, nRed += DITHER_PAL_DELTA )
+ {
+ pPalEntry->peRed = nRed;
+ pPalEntry->peGreen = nGreen;
+ pPalEntry->peBlue = nBlue;
+ pPalEntry->peFlags = 0;
+ pPalEntry++;
+ }
+ }
+ }
+
+ // insert special 'Blue' as standard drawing color
+ *pPalEntry++ = aImplExtraColor1;
+
+ // create palette
+ pSalData->mhDitherPal = CreatePalette( pLogPal );
+ delete[] (char*) pLogPal;
+
+ if( pSalData->mhDitherPal )
+ {
+ // create DIBPattern for 8Bit dithering
+ long nSize = sizeof( BITMAPINFOHEADER ) + ( 256 * sizeof( short ) ) + 64;
+ long n;
+
+ pSalData->mhDitherDIB = GlobalAlloc( GMEM_FIXED, nSize );
+ pSalData->mpDitherDIB = (BYTE*) GlobalLock( pSalData->mhDitherDIB );
+ pSalData->mpDitherDiff = new long[ 256 ];
+ pSalData->mpDitherLow = new BYTE[ 256 ];
+ pSalData->mpDitherHigh = new BYTE[ 256 ];
+ pSalData->mpDitherDIBData = pSalData->mpDitherDIB + sizeof( BITMAPINFOHEADER ) + ( 256 * sizeof( short ) );
+ memset( pSalData->mpDitherDIB, 0, sizeof( BITMAPINFOHEADER ) );
+
+ BITMAPINFOHEADER* pBIH = (BITMAPINFOHEADER*) pSalData->mpDitherDIB;
+ short* pColors = (short*) ( pSalData->mpDitherDIB + sizeof( BITMAPINFOHEADER ) );
+
+ pBIH->biSize = sizeof( BITMAPINFOHEADER );
+ pBIH->biWidth = 8;
+ pBIH->biHeight = 8;
+ pBIH->biPlanes = 1;
+ pBIH->biBitCount = 8;
+
+ for( n = 0; n < nDitherPalCount; n++ )
+ pColors[ n ] = (short)( n + DITHER_MAX_SYSCOLOR );
+
+ for( n = 0; n < 256L; n++ )
+ pSalData->mpDitherDiff[ n ] = n % 51L;
+
+ for( n = 0; n < 256L; n++ )
+ pSalData->mpDitherLow[ n ] = (BYTE) ( n / 51L );
+
+ for( n = 0; n < 256L; n++ )
+ pSalData->mpDitherHigh[ n ] = Min( pSalData->mpDitherLow[ n ] + 1, 5 );
+ }
+
+ // get system color entries
+ ImplUpdateSysColorEntries();
+ }
+
+ ReleaseDC( 0, hDC );
+}
+
+// -----------------------------------------------------------------------
+
+void ImplFreeSalGDI()
+{
+ SalData* pSalData = GetSalData();
+ USHORT i;
+
+ // destroy stock objects
+ for ( i = 0; i < pSalData->mnStockPenCount; i++ )
+ DeletePen( pSalData->mhStockPenAry[i] );
+ for ( i = 0; i < pSalData->mnStockBrushCount; i++ )
+ DeleteBrush( pSalData->mhStockBrushAry[i] );
+
+ // 50% Brush loeschen
+ if ( pSalData->mh50Brush )
+ {
+ DeleteBrush( pSalData->mh50Brush );
+ pSalData->mh50Brush = 0;
+ }
+
+ // 50% Bitmap loeschen
+ if ( pSalData->mh50Bmp )
+ {
+ DeleteBitmap( pSalData->mh50Bmp );
+ pSalData->mh50Bmp = 0;
+ }
+
+ ImplClearHDCCache( pSalData );
+ delete[] pSalData->mpHDCCache;
+
+ // Ditherpalette loeschen, wenn vorhanden
+ if ( pSalData->mhDitherPal )
+ {
+ DeleteObject( pSalData->mhDitherPal );
+ pSalData->mhDitherPal = 0;
+ }
+
+ // delete buffers for dithering DIB patterns, if neccessary
+ if ( pSalData->mhDitherDIB )
+ {
+ GlobalUnlock( pSalData->mhDitherDIB );
+ GlobalFree( pSalData->mhDitherDIB );
+ pSalData->mhDitherDIB = 0;
+ delete[] pSalData->mpDitherDiff;
+ delete[] pSalData->mpDitherLow;
+ delete[] pSalData->mpDitherHigh;
+ }
+
+ // delete SysColorList
+ SysColorEntry* pEntry = pFirstSysColor;
+ while( pEntry )
+ {
+ SysColorEntry* pTmp = pEntry->pNext;
+ delete pEntry;
+ pEntry = pTmp;
+ }
+ pFirstSysColor = NULL;
+}
+
+// -----------------------------------------------------------------------
+
+static int ImplIsPaletteEntry( BYTE nRed, BYTE nGreen, BYTE nBlue )
+{
+ // dither color?
+ if ( !(nRed % DITHER_PAL_DELTA) && !(nGreen % DITHER_PAL_DELTA) && !(nBlue % DITHER_PAL_DELTA) )
+ return TRUE;
+
+ PALETTEENTRY* pPalEntry = aImplSalSysPalEntryAry;
+
+ // standard palette color?
+ for ( USHORT i = 0; i < DITHER_MAX_SYSCOLOR; i++, pPalEntry++ )
+ {
+ if( pPalEntry->peRed == nRed && pPalEntry->peGreen == nGreen && pPalEntry->peBlue == nBlue )
+ return TRUE;
+ }
+
+ // extra color?
+ if ( aImplExtraColor1.peRed == nRed &&
+ aImplExtraColor1.peGreen == nGreen &&
+ aImplExtraColor1.peBlue == nBlue )
+ {
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+// =======================================================================
+
+int ImplIsSysColorEntry( SalColor nSalColor )
+{
+ SysColorEntry* pEntry = pFirstSysColor;
+ const DWORD nTestRGB = (DWORD)RGB( SALCOLOR_RED( nSalColor ),
+ SALCOLOR_GREEN( nSalColor ),
+ SALCOLOR_BLUE( nSalColor ) );
+
+ while ( pEntry )
+ {
+ if ( pEntry->nRGB == nTestRGB )
+ return TRUE;
+ pEntry = pEntry->pNext;
+ }
+
+ return FALSE;
+}
+
+// =======================================================================
+
+static void ImplInsertSysColorEntry( int nSysIndex )
+{
+ const DWORD nRGB = GetSysColor( nSysIndex );
+
+ if ( !ImplIsPaletteEntry( GetRValue( nRGB ), GetGValue( nRGB ), GetBValue( nRGB ) ) )
+ {
+ if ( !pFirstSysColor )
+ {
+ pActSysColor = pFirstSysColor = new SysColorEntry;
+ pFirstSysColor->nRGB = nRGB;
+ pFirstSysColor->pNext = NULL;
+ }
+ else
+ {
+ pActSysColor = pActSysColor->pNext = new SysColorEntry;
+ pActSysColor->nRGB = nRGB;
+ pActSysColor->pNext = NULL;
+ }
+ }
+}
+
+// =======================================================================
+
+void ImplUpdateSysColorEntries()
+{
+ // delete old SysColorList
+ SysColorEntry* pEntry = pFirstSysColor;
+ while( pEntry )
+ {
+ SysColorEntry* pTmp = pEntry->pNext;
+ delete pEntry;
+ pEntry = pTmp;
+ }
+ pActSysColor = pFirstSysColor = NULL;
+
+ // create new sys color list
+ ImplInsertSysColorEntry( COLOR_ACTIVEBORDER );
+ ImplInsertSysColorEntry( COLOR_INACTIVEBORDER );
+ if( aSalShlData.mnVersion >= 410 )
+ {
+ ImplInsertSysColorEntry( COLOR_GRADIENTACTIVECAPTION );
+ ImplInsertSysColorEntry( COLOR_GRADIENTINACTIVECAPTION );
+ }
+ ImplInsertSysColorEntry( COLOR_3DFACE );
+ ImplInsertSysColorEntry( COLOR_3DHILIGHT );
+ ImplInsertSysColorEntry( COLOR_3DLIGHT );
+ ImplInsertSysColorEntry( COLOR_3DSHADOW );
+ ImplInsertSysColorEntry( COLOR_3DDKSHADOW );
+ ImplInsertSysColorEntry( COLOR_INFOBK );
+ ImplInsertSysColorEntry( COLOR_INFOTEXT );
+ ImplInsertSysColorEntry( COLOR_BTNTEXT );
+ ImplInsertSysColorEntry( COLOR_WINDOW );
+ ImplInsertSysColorEntry( COLOR_WINDOWTEXT );
+ ImplInsertSysColorEntry( COLOR_HIGHLIGHT );
+ ImplInsertSysColorEntry( COLOR_HIGHLIGHTTEXT );
+ ImplInsertSysColorEntry( COLOR_MENU );
+ ImplInsertSysColorEntry( COLOR_MENUTEXT );
+ ImplInsertSysColorEntry( COLOR_ACTIVECAPTION );
+ ImplInsertSysColorEntry( COLOR_CAPTIONTEXT );
+ ImplInsertSysColorEntry( COLOR_INACTIVECAPTION );
+ ImplInsertSysColorEntry( COLOR_INACTIVECAPTIONTEXT );
+}
+
+// -----------------------------------------------------------------------
+
+static SalColor ImplGetROPSalColor( SalROPColor nROPColor )
+{
+ SalColor nSalColor;
+ if ( nROPColor == SAL_ROP_0 )
+ nSalColor = MAKE_SALCOLOR( 0, 0, 0 );
+ else
+ nSalColor = MAKE_SALCOLOR( 255, 255, 255 );
+ return nSalColor;
+}
+
+// =======================================================================
+
+void ImplSalInitGraphics( SalGraphicsData* pData )
+{
+ // Beim Printer berechnen wir die minimale Linienstaerke
+ if ( pData->mbPrinter )
+ {
+ int nDPIX = GetDeviceCaps( pData->mhDC, LOGPIXELSX );
+ if ( nDPIX <= 300 )
+ pData->mnPenWidth = 0;
+ else
+ pData->mnPenWidth = nDPIX/300;
+ }
+
+ ::SetTextAlign( pData->mhDC, TA_BASELINE | TA_LEFT | TA_NOUPDATECP );
+ ::SetBkMode( pData->mhDC, TRANSPARENT );
+ ::SetROP2( pData->mhDC, R2_COPYPEN );
+}
+
+// -----------------------------------------------------------------------
+
+void ImplSalDeInitGraphics( SalGraphicsData* pData )
+{
+ // Default Objekte selektieren
+ if ( pData->mhDefPen )
+ SelectPen( pData->mhDC, pData->mhDefPen );
+ if ( pData->mhDefBrush )
+ SelectBrush( pData->mhDC, pData->mhDefBrush );
+ if ( pData->mhDefFont )
+ SelectFont( pData->mhDC, pData->mhDefFont );
+}
+
+// =======================================================================
+
+HDC ImplGetCachedDC( ULONG nID, HBITMAP hBmp )
+{
+ SalData* pSalData = GetSalData();
+ HDCCache* pC = &pSalData->mpHDCCache[ nID ];
+
+ if( !pC->mhDC )
+ {
+ HDC hDC = GetDC( 0 );
+
+ // neuen DC mit DefaultBitmap anlegen
+ pC->mhDC = CreateCompatibleDC( hDC );
+
+ if( pSalData->mhDitherPal )
+ {
+ pC->mhDefPal = SelectPalette( pC->mhDC, pSalData->mhDitherPal, TRUE );
+ RealizePalette( pC->mhDC );
+ }
+
+ pC->mhSelBmp = CreateCompatibleBitmap( hDC, CACHED_HDC_DEFEXT, CACHED_HDC_DEFEXT );
+ pC->mhDefBmp = (HBITMAP) SelectObject( pC->mhDC, pC->mhSelBmp );
+
+ ReleaseDC( 0, hDC );
+ }
+
+ if ( hBmp )
+ SelectObject( pC->mhDC, pC->mhActBmp = hBmp );
+ else
+ pC->mhActBmp = 0;
+
+ return pC->mhDC;
+}
+
+// =======================================================================
+
+void ImplReleaseCachedDC( ULONG nID )
+{
+ SalData* pSalData = GetSalData();
+ HDCCache* pC = &pSalData->mpHDCCache[ nID ];
+
+ if ( pC->mhActBmp )
+ SelectObject( pC->mhDC, pC->mhSelBmp );
+}
+
+// =======================================================================
+
+void ImplClearHDCCache( SalData* pData )
+{
+ for( ULONG i = 0; i < CACHESIZE_HDC; i++ )
+ {
+ HDCCache* pC = &pData->mpHDCCache[ i ];
+
+ if( pC->mhDC )
+ {
+ SelectObject( pC->mhDC, pC->mhDefBmp );
+
+ if( pC->mhDefPal )
+ SelectPalette( pC->mhDC, pC->mhDefPal, TRUE );
+
+ DeleteDC( pC->mhDC );
+ DeleteObject( pC->mhSelBmp );
+ }
+ }
+}
+
+// =======================================================================
+
+SalGraphics::SalGraphics()
+{
+ maGraphicsData.mhDC = 0;
+ maGraphicsData.mhPen = 0;
+ maGraphicsData.mhBrush = 0;
+ maGraphicsData.mhFont = 0;
+ maGraphicsData.mhRegion = 0;
+ maGraphicsData.mhDefPen = 0;
+ maGraphicsData.mhDefBrush = 0;
+ maGraphicsData.mhDefFont = 0;
+ maGraphicsData.mhDefPal = 0;
+ maGraphicsData.mpStdClipRgnData = NULL;
+ maGraphicsData.mpLogFont = NULL;
+ maGraphicsData.mpFontCharSets = NULL;
+ maGraphicsData.mnFontCharSetCount = 0;
+ maGraphicsData.mpFontKernPairs = NULL;
+ maGraphicsData.mnFontKernPairCount = 0;
+ maGraphicsData.mbFontKernInit = FALSE;
+ maGraphicsData.mnFontOverhang = 0;
+ maGraphicsData.mbXORMode = FALSE;
+ maGraphicsData.mnPenWidth = GSL_PEN_WIDTH;
+ maGraphicsData.mbCalcOverhang = TRUE;
+}
+
+// -----------------------------------------------------------------------
+
+SalGraphics::~SalGraphics()
+{
+ // Objekte zerstoeren
+ if ( maGraphicsData.mhPen )
+ {
+ if ( !maGraphicsData.mbStockPen )
+ DeletePen( maGraphicsData.mhPen );
+ }
+ if ( maGraphicsData.mhBrush )
+ {
+ if ( !maGraphicsData.mbStockBrush )
+ DeleteBrush( maGraphicsData.mhBrush );
+ }
+ if ( maGraphicsData.mhFont )
+ DeleteFont( maGraphicsData.mhFont );
+
+ if ( maGraphicsData.mhRegion )
+ {
+ DeleteRegion( maGraphicsData.mhRegion );
+ maGraphicsData.mhRegion = 0;
+ }
+
+ // Cache-Daten zerstoeren
+ if ( maGraphicsData.mpStdClipRgnData )
+ delete maGraphicsData.mpStdClipRgnData;
+
+ if ( maGraphicsData.mpLogFont )
+ delete maGraphicsData.mpLogFont;
+
+ if ( maGraphicsData.mpFontCharSets )
+ delete maGraphicsData.mpFontCharSets;
+
+ if ( maGraphicsData.mpFontKernPairs )
+ delete maGraphicsData.mpFontKernPairs;
+}
+
+// -----------------------------------------------------------------------
+
+void SalGraphics::GetResolution( long& rDPIX, long& rDPIY )
+{
+ rDPIX = GetDeviceCaps( maGraphicsData.mhDC, LOGPIXELSX );
+ rDPIY = GetDeviceCaps( maGraphicsData.mhDC, LOGPIXELSY );
+}
+
+// -----------------------------------------------------------------------
+
+void SalGraphics::GetScreenFontResolution( long& rDPIX, long& rDPIY )
+{
+ rDPIX = GetDeviceCaps( maGraphicsData.mhDC, LOGPIXELSX );
+ rDPIY = GetDeviceCaps( maGraphicsData.mhDC, LOGPIXELSY );
+}
+
+// -----------------------------------------------------------------------
+
+USHORT SalGraphics::GetBitCount()
+{
+ return (USHORT)GetDeviceCaps( maGraphicsData.mhDC, BITSPIXEL );
+}
+
+// -----------------------------------------------------------------------
+
+void SalGraphics::ResetClipRegion()
+{
+ if ( maGraphicsData.mhRegion )
+ {
+ DeleteRegion( maGraphicsData.mhRegion );
+ maGraphicsData.mhRegion = 0;
+ }
+
+ SelectClipRgn( maGraphicsData.mhDC, 0 );
+}
+
+// -----------------------------------------------------------------------
+
+void SalGraphics::BeginSetClipRegion( ULONG nRectCount )
+{
+ if ( maGraphicsData.mhRegion )
+ {
+ DeleteRegion( maGraphicsData.mhRegion );
+ maGraphicsData.mhRegion = 0;
+ }
+
+ ULONG nRectBufSize = sizeof(RECT)*nRectCount;
+ if ( nRectCount < SAL_CLIPRECT_COUNT )
+ {
+ if ( !maGraphicsData.mpStdClipRgnData )
+ maGraphicsData.mpStdClipRgnData = (RGNDATA*)new BYTE[sizeof(RGNDATA)-1+(SAL_CLIPRECT_COUNT*sizeof(RECT))];
+ maGraphicsData.mpClipRgnData = maGraphicsData.mpStdClipRgnData;
+ }
+ else
+ maGraphicsData.mpClipRgnData = (RGNDATA*)new BYTE[sizeof(RGNDATA)-1+nRectBufSize];
+ maGraphicsData.mpClipRgnData->rdh.dwSize = sizeof( RGNDATAHEADER );
+ maGraphicsData.mpClipRgnData->rdh.iType = RDH_RECTANGLES;
+ maGraphicsData.mpClipRgnData->rdh.nCount = nRectCount;
+ maGraphicsData.mpClipRgnData->rdh.nRgnSize = nRectBufSize;
+ SetRectEmpty( &(maGraphicsData.mpClipRgnData->rdh.rcBound) );
+ maGraphicsData.mpNextClipRect = (RECT*)(&(maGraphicsData.mpClipRgnData->Buffer));
+ maGraphicsData.mbFirstClipRect = TRUE;
+}
+
+
+// -----------------------------------------------------------------------
+
+BOOL SalGraphics::UnionClipRegion( long nX, long nY, long nWidth, long nHeight )
+{
+ if ( nWidth && nHeight )
+ {
+ RECT* pRect = maGraphicsData.mpNextClipRect;
+ RECT* pBoundRect = &(maGraphicsData.mpClipRgnData->rdh.rcBound);
+ long nRight = nX + nWidth;
+ long nBottom = nY + nHeight;
+
+ if ( maGraphicsData.mbFirstClipRect )
+ {
+ pBoundRect->left = nX;
+ pBoundRect->top = nY;
+ pBoundRect->right = nRight;
+ pBoundRect->bottom = nBottom;
+ maGraphicsData.mbFirstClipRect = FALSE;
+ }
+ else
+ {
+ if ( nX < pBoundRect->left )
+ pBoundRect->left = (int)nX;
+
+ if ( nY < pBoundRect->top )
+ pBoundRect->top = (int)nY;
+
+ if ( nRight > pBoundRect->right )
+ pBoundRect->right = (int)nRight;
+
+ if ( nBottom > pBoundRect->bottom )
+ pBoundRect->bottom = (int)nBottom;
+ }
+
+ pRect->left = (int)nX;
+ pRect->top = (int)nY;
+ pRect->right = (int)nRight;
+ pRect->bottom = (int)nBottom;
+ maGraphicsData.mpNextClipRect++;
+ }
+ else
+ {
+ maGraphicsData.mpClipRgnData->rdh.nCount--;
+ maGraphicsData.mpClipRgnData->rdh.nRgnSize -= sizeof( RECT );
+ }
+
+ return TRUE;
+}
+
+// -----------------------------------------------------------------------
+
+void SalGraphics::EndSetClipRegion()
+{
+ // Aus den Region-Daten muessen wir jetzt eine ClipRegion erzeugen
+ if ( maGraphicsData.mpClipRgnData->rdh.nCount == 1 )
+ {
+ RECT* pRect = &(maGraphicsData.mpClipRgnData->rdh.rcBound);
+ maGraphicsData.mhRegion = CreateRectRgn( pRect->left, pRect->top,
+ pRect->right, pRect->bottom );
+ }
+ else
+ {
+ ULONG nSize = maGraphicsData.mpClipRgnData->rdh.nRgnSize+sizeof(RGNDATAHEADER);
+ maGraphicsData.mhRegion = ExtCreateRegion( NULL, nSize, maGraphicsData.mpClipRgnData );
+
+ // if ExtCreateRegion(...) is not supported
+ if( !maGraphicsData.mhRegion )
+ {
+ RGNDATAHEADER* pHeader = (RGNDATAHEADER*) maGraphicsData.mpClipRgnData;
+
+ if( pHeader->nCount )
+ {
+ RECT* pRect = (RECT*) maGraphicsData.mpClipRgnData->Buffer;
+ maGraphicsData.mhRegion = CreateRectRgn( pRect->left, pRect->top, pRect->right, pRect->bottom );
+ pRect++;
+
+ for( ULONG n = 1; n < pHeader->nCount; n++, pRect++ )
+ {
+ HRGN hRgn = CreateRectRgn( pRect->left, pRect->top, pRect->right, pRect->bottom );
+ CombineRgn( maGraphicsData.mhRegion, maGraphicsData.mhRegion, hRgn, RGN_OR );
+ DeleteRegion( hRgn );
+ }
+ }
+ }
+
+ if ( maGraphicsData.mpClipRgnData != maGraphicsData.mpStdClipRgnData )
+ delete maGraphicsData.mpClipRgnData;
+ }
+
+ SelectClipRgn( maGraphicsData.mhDC, maGraphicsData.mhRegion );
+}
+
+// -----------------------------------------------------------------------
+
+void SalGraphics::SetLineColor()
+{
+ // create and select new pen
+ HPEN hNewPen = GetStockPen( NULL_PEN );
+ HPEN hOldPen = SelectPen( maGraphicsData.mhDC, hNewPen );
+
+ // destory or save old pen
+ if ( maGraphicsData.mhPen )
+ {
+ if ( !maGraphicsData.mbStockPen )
+ DeletePen( maGraphicsData.mhPen );
+ }
+ else
+ maGraphicsData.mhDefPen = hOldPen;
+
+ // set new data
+ maGraphicsData.mhPen = hNewPen;
+ maGraphicsData.mbPen = FALSE;
+ maGraphicsData.mbStockPen = TRUE;
+}
+
+// -----------------------------------------------------------------------
+
+void SalGraphics::SetLineColor( SalColor nSalColor )
+{
+ COLORREF nPenColor = PALETTERGB( SALCOLOR_RED( nSalColor ),
+ SALCOLOR_GREEN( nSalColor ),
+ SALCOLOR_BLUE( nSalColor ) );
+ HPEN hNewPen = 0;
+ BOOL bStockPen;
+
+ // search for stock pen (only screen, because printer have problems,
+ // when we use stock objects)
+ if ( !maGraphicsData.mbPrinter )
+ {
+ SalData* pSalData = GetSalData();
+ for ( USHORT i = 0; i < pSalData->mnStockPenCount; i++ )
+ {
+ if ( nPenColor == pSalData->maStockPenColorAry[i] )
+ {
+ hNewPen = pSalData->mhStockPenAry[i];
+ bStockPen = TRUE;
+ break;
+ }
+ }
+ }
+
+ // create new pen
+ if ( !hNewPen )
+ {
+ if ( !maGraphicsData.mbPrinter )
+ {
+ if ( GetSalData()->mhDitherPal && ImplIsSysColorEntry( nSalColor ) )
+ nPenColor = PALRGB_TO_RGB( nPenColor );
+ }
+
+ hNewPen = CreatePen( PS_SOLID, maGraphicsData.mnPenWidth, nPenColor );
+ bStockPen = FALSE;
+ }
+
+ // select new pen
+ HPEN hOldPen = SelectPen( maGraphicsData.mhDC, hNewPen );
+
+ // destory or save old pen
+ if ( maGraphicsData.mhPen )
+ {
+ if ( !maGraphicsData.mbStockPen )
+ DeletePen( maGraphicsData.mhPen );
+ }
+ else
+ maGraphicsData.mhDefPen = hOldPen;
+
+ // set new data
+ maGraphicsData.mnPenColor = nPenColor;
+ maGraphicsData.mhPen = hNewPen;
+ maGraphicsData.mbPen = TRUE;
+ maGraphicsData.mbStockPen = bStockPen;
+}
+
+// -----------------------------------------------------------------------
+
+void SalGraphics::SetFillColor()
+{
+ // create and select new brush
+ HBRUSH hNewBrush = GetStockBrush( NULL_BRUSH );
+ HBRUSH hOldBrush = SelectBrush( maGraphicsData.mhDC, hNewBrush );
+
+ // destory or save old brush
+ if ( maGraphicsData.mhBrush )
+ {
+ if ( !maGraphicsData.mbStockBrush )
+ DeleteBrush( maGraphicsData.mhBrush );
+ }
+ else
+ maGraphicsData.mhDefBrush = hOldBrush;
+
+ // set new data
+ maGraphicsData.mhBrush = hNewBrush;
+ maGraphicsData.mbBrush = FALSE;
+ maGraphicsData.mbStockBrush = TRUE;
+}
+
+// -----------------------------------------------------------------------
+
+void SalGraphics::SetFillColor( SalColor nSalColor )
+{
+ SalData* pSalData = GetSalData();
+ BYTE nRed = SALCOLOR_RED( nSalColor );
+ BYTE nGreen = SALCOLOR_GREEN( nSalColor );
+ BYTE nBlue = SALCOLOR_BLUE( nSalColor );
+ COLORREF nBrushColor = PALETTERGB( nRed, nGreen, nBlue );
+ HBRUSH hNewBrush = 0;
+ BOOL bStockBrush;
+
+ // search for stock brush (only screen, because printer have problems,
+ // when we use stock objects)
+ if ( !maGraphicsData.mbPrinter )
+ {
+ for ( USHORT i = 0; i < pSalData->mnStockBrushCount; i++ )
+ {
+ if ( nBrushColor == pSalData->maStockBrushColorAry[ i ] )
+ {
+ hNewBrush = pSalData->mhStockBrushAry[i];
+ bStockBrush = TRUE;
+ break;
+ }
+ }
+ }
+
+ // create new brush
+ if ( !hNewBrush )
+ {
+ if ( maGraphicsData.mbPrinter || !pSalData->mhDitherDIB )
+ hNewBrush = CreateSolidBrush( nBrushColor );
+ else
+ {
+ if ( 24 == ((BITMAPINFOHEADER*)pSalData->mpDitherDIB)->biBitCount )
+ {
+ BYTE* pTmp = pSalData->mpDitherDIBData;
+ long* pDitherDiff = pSalData->mpDitherDiff;
+ BYTE* pDitherLow = pSalData->mpDitherLow;
+ BYTE* pDitherHigh = pSalData->mpDitherHigh;
+
+ for( long nY = 0L; nY < 8L; nY++ )
+ {
+ for( long nX = 0L; nX < 8L; nX++ )
+ {
+ const long nThres = aOrdDither16Bit[ nY ][ nX ];
+ *pTmp++ = DMAP( nBlue, nThres );
+ *pTmp++ = DMAP( nGreen, nThres );
+ *pTmp++ = DMAP( nRed, nThres );
+ }
+ }
+
+ hNewBrush = CreateDIBPatternBrush( pSalData->mhDitherDIB, DIB_RGB_COLORS );
+ }
+ else if ( ImplIsSysColorEntry( nSalColor ) )
+ {
+ nBrushColor = PALRGB_TO_RGB( nBrushColor );
+ hNewBrush = CreateSolidBrush( nBrushColor );
+ }
+ else if ( ImplIsPaletteEntry( nRed, nGreen, nBlue ) )
+ hNewBrush = CreateSolidBrush( nBrushColor );
+ else
+ {
+ BYTE* pTmp = pSalData->mpDitherDIBData;
+ long* pDitherDiff = pSalData->mpDitherDiff;
+ BYTE* pDitherLow = pSalData->mpDitherLow;
+ BYTE* pDitherHigh = pSalData->mpDitherHigh;
+
+ for ( long nY = 0L; nY < 8L; nY++ )
+ {
+ for ( long nX = 0L; nX < 8L; nX++ )
+ {
+ const long nThres = aOrdDither8Bit[ nY ][ nX ];
+ *pTmp = DMAP( nRed, nThres ) + DMAP( nGreen, nThres ) * 6 + DMAP( nBlue, nThres ) * 36;
+ pTmp++;
+ }
+ }
+
+ hNewBrush = CreateDIBPatternBrush( pSalData->mhDitherDIB, DIB_PAL_COLORS );
+ }
+ }
+
+ bStockBrush = FALSE;
+ }
+
+ // select new brush
+ HBRUSH hOldBrush = SelectBrush( maGraphicsData.mhDC, hNewBrush );
+
+ // destory or save old brush
+ if ( maGraphicsData.mhBrush )
+ {
+ if ( !maGraphicsData.mbStockBrush )
+ DeleteBrush( maGraphicsData.mhBrush );
+ }
+ else
+ maGraphicsData.mhDefBrush = hOldBrush;
+
+ // set new data
+ maGraphicsData.mnBrushColor = nBrushColor;
+ maGraphicsData.mhBrush = hNewBrush;
+ maGraphicsData.mbBrush = FALSE;
+ maGraphicsData.mbStockBrush = bStockBrush;
+}
+
+// -----------------------------------------------------------------------
+
+void SalGraphics::SetXORMode( BOOL bSet )
+{
+ maGraphicsData.mbXORMode = bSet;
+ ::SetROP2( maGraphicsData.mhDC, bSet ? R2_XORPEN : R2_COPYPEN );
+}
+
+// -----------------------------------------------------------------------
+
+void SalGraphics::SetROPLineColor( SalROPColor nROPColor )
+{
+ SetLineColor( ImplGetROPSalColor( nROPColor ) );
+}
+
+// -----------------------------------------------------------------------
+
+void SalGraphics::SetROPFillColor( SalROPColor nROPColor )
+{
+ SetFillColor( ImplGetROPSalColor( nROPColor ) );
+}
+
+// -----------------------------------------------------------------------
+
+void SalGraphics::DrawPixel( long nX, long nY )
+{
+ if ( maGraphicsData.mbXORMode )
+ {
+ HBRUSH hBrush = CreateSolidBrush( maGraphicsData.mnPenColor );
+ HBRUSH hOldBrush = SelectBrush( maGraphicsData.mhDC, hBrush );
+ PatBlt( maGraphicsData.mhDC, (int)nX, (int)nY, (int)1, (int)1, PATINVERT );
+ SelectBrush( maGraphicsData.mhDC, hOldBrush );
+ DeleteBrush( hBrush );
+ }
+ else
+ SetPixel( maGraphicsData.mhDC, (int)nX, (int)nY, maGraphicsData.mnPenColor );
+}
+
+// -----------------------------------------------------------------------
+
+void SalGraphics::DrawPixel( long nX, long nY, SalColor nSalColor )
+{
+ COLORREF nCol = PALETTERGB( SALCOLOR_RED( nSalColor ),
+ SALCOLOR_GREEN( nSalColor ),
+ SALCOLOR_BLUE( nSalColor ) );
+
+ if ( !maGraphicsData.mbPrinter &&
+ GetSalData()->mhDitherPal &&
+ ImplIsSysColorEntry( nSalColor ) )
+ nCol = PALRGB_TO_RGB( nCol );
+
+ if ( maGraphicsData.mbXORMode )
+ {
+ HBRUSH hBrush = CreateSolidBrush( nCol );
+ HBRUSH hOldBrush = SelectBrush( maGraphicsData.mhDC, hBrush );
+ PatBlt( maGraphicsData.mhDC, (int)nX, (int)nY, (int)1, (int)1, PATINVERT );
+ SelectBrush( maGraphicsData.mhDC, hOldBrush );
+ DeleteBrush( hBrush );
+ }
+ else
+ ::SetPixel( maGraphicsData.mhDC, (int)nX, (int)nY, nCol );
+}
+
+// -----------------------------------------------------------------------
+
+void SalGraphics::DrawLine( long nX1, long nY1, long nX2, long nY2 )
+{
+ MoveToEx( maGraphicsData.mhDC, (int)nX1, (int)nY1, NULL );
+
+ // we must paint the endpoint
+ int bPaintEnd = TRUE;
+ if ( nX1 == nX2 )
+ {
+ bPaintEnd = FALSE;
+ if ( nY1 <= nY2 )
+ nY2++;
+ else
+ nY2--;
+ }
+ if ( nY1 == nY2 )
+ {
+ bPaintEnd = FALSE;
+ if ( nX1 <= nX2 )
+ nX2++;
+ else
+ nX2--;
+ }
+
+ LineTo( maGraphicsData.mhDC, (int)nX2, (int)nY2 );
+
+ if ( bPaintEnd && !maGraphicsData.mbPrinter )
+ {
+ if ( maGraphicsData.mbXORMode )
+ {
+ HBRUSH hBrush = CreateSolidBrush( maGraphicsData.mnPenColor );
+ HBRUSH hOldBrush = SelectBrush( maGraphicsData.mhDC, hBrush );
+ PatBlt( maGraphicsData.mhDC, (int)nX2, (int)nY2, (int)1, (int)1, PATINVERT );
+ SelectBrush( maGraphicsData.mhDC, hOldBrush );
+ DeleteBrush( hBrush );
+ }
+ else
+ SetPixel( maGraphicsData.mhDC, (int)nX2, (int)nY2, maGraphicsData.mnPenColor );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void SalGraphics::DrawRect( long nX, long nY, long nWidth, long nHeight )
+{
+ if ( !maGraphicsData.mbPen )
+ {
+ if ( !maGraphicsData.mbPrinter )
+ {
+ PatBlt( maGraphicsData.mhDC, (int)nX, (int)nY, (int)nWidth, (int)nHeight,
+ maGraphicsData.mbXORMode ? PATINVERT : PATCOPY );
+ }
+ else
+ {
+ RECT aWinRect;
+ aWinRect.left = nX;
+ aWinRect.top = nY;
+ aWinRect.right = nX+nWidth;
+ aWinRect.bottom = nY+nHeight;
+ ::FillRect( maGraphicsData.mhDC, &aWinRect, maGraphicsData.mhBrush );
+ }
+ }
+ else
+ WIN_Rectangle( maGraphicsData.mhDC, (int)nX, (int)nY, (int)(nX+nWidth), (int)(nY+nHeight) );
+}
+
+// -----------------------------------------------------------------------
+
+void SalGraphics::DrawPolyLine( ULONG nPoints, const SalPoint* pPtAry )
+{
+ // Unter NT koennen wir das Array direkt weiterreichen
+ DBG_ASSERT( sizeof( POINT ) == sizeof( SalPoint ),
+ "SalGraphics::DrawPolyLine(): POINT != SalPoint" );
+
+ POINT* pWinPtAry = (POINT*)pPtAry;
+ // Wegen Windows 95 und der Beschraenkung auf eine maximale Anzahl
+ // von Punkten
+ if ( !Polyline( maGraphicsData.mhDC, pWinPtAry, (int)nPoints ) && (nPoints > MAX_64KSALPOINTS) )
+ Polyline( maGraphicsData.mhDC, pWinPtAry, MAX_64KSALPOINTS );
+}
+
+// -----------------------------------------------------------------------
+
+void SalGraphics::DrawPolygon( ULONG nPoints, const SalPoint* pPtAry )
+{
+ // Unter NT koennen wir das Array direkt weiterreichen
+ DBG_ASSERT( sizeof( POINT ) == sizeof( SalPoint ),
+ "SalGraphics::DrawPolygon(): POINT != SalPoint" );
+
+ POINT* pWinPtAry = (POINT*)pPtAry;
+ // Wegen Windows 95 und der Beschraenkung auf eine maximale Anzahl
+ // von Punkten
+ if ( !WIN_Polygon( maGraphicsData.mhDC, pWinPtAry, (int)nPoints ) && (nPoints > MAX_64KSALPOINTS) )
+ WIN_Polygon( maGraphicsData.mhDC, pWinPtAry, MAX_64KSALPOINTS );
+}
+
+// -----------------------------------------------------------------------
+
+void SalGraphics::DrawPolyPolygon( ULONG nPoly, const ULONG* pPoints,
+ PCONSTSALPOINT* pPtAry )
+{
+ UINT aWinPointAry[SAL_POLYPOLYCOUNT_STACKBUF];
+ UINT* pWinPointAry;
+ UINT nPolyPolyPoints = 0;
+ UINT nPoints;
+ UINT i;
+
+ if ( nPoly <= SAL_POLYPOLYCOUNT_STACKBUF )
+ pWinPointAry = aWinPointAry;
+ else
+ pWinPointAry = new UINT[nPoly];
+
+ for ( i = 0; i < (UINT)nPoly; i++ )
+ {
+ nPoints = (UINT)pPoints[i]+1;
+ pWinPointAry[i] = nPoints;
+ nPolyPolyPoints += nPoints;
+ }
+
+ POINT aWinPointAryAry[SAL_POLYPOLYPOINTS_STACKBUF];
+ POINT* pWinPointAryAry;
+ if ( nPolyPolyPoints <= SAL_POLYPOLYPOINTS_STACKBUF )
+ pWinPointAryAry = aWinPointAryAry;
+ else
+ pWinPointAryAry = new POINT[nPolyPolyPoints];
+ // Unter NT koennen wir das Array direkt weiterreichen
+ DBG_ASSERT( sizeof( POINT ) == sizeof( SalPoint ),
+ "SalGraphics::DrawPolyPolygon(): POINT != SalPoint" );
+ const SalPoint* pPolyAry;
+ UINT n = 0;
+ for ( i = 0; i < (UINT)nPoly; i++ )
+ {
+ nPoints = pWinPointAry[i];
+ pPolyAry = pPtAry[i];
+ memcpy( pWinPointAryAry+n, pPolyAry, (nPoints-1)*sizeof(POINT) );
+ pWinPointAryAry[n+nPoints-1] = pWinPointAryAry[n];
+ n += nPoints;
+ }
+
+ if ( !WIN_PolyPolygon( maGraphicsData.mhDC, pWinPointAryAry, (int*)pWinPointAry, (UINT)nPoly ) &&
+ (nPolyPolyPoints > MAX_64KSALPOINTS) )
+ {
+ nPolyPolyPoints = 0;
+ nPoly = 0;
+ do
+ {
+ nPolyPolyPoints += pWinPointAry[(UINT)nPoly];
+ nPoly++;
+ }
+ while ( nPolyPolyPoints < MAX_64KSALPOINTS );
+ nPoly--;
+ if ( pWinPointAry[(UINT)nPoly] > MAX_64KSALPOINTS )
+ pWinPointAry[(UINT)nPoly] = MAX_64KSALPOINTS;
+ if ( nPoly == 1 )
+ WIN_Polygon( maGraphicsData.mhDC, pWinPointAryAry, *pWinPointAry );
+ else
+ WIN_PolyPolygon( maGraphicsData.mhDC, pWinPointAryAry, (int*)pWinPointAry, nPoly );
+ }
+
+ if ( pWinPointAry != aWinPointAry )
+ delete pWinPointAry;
+ if ( pWinPointAryAry != aWinPointAryAry )
+ delete pWinPointAryAry;
+}
+
+
+// -----------------------------------------------------------------------
+
+#define POSTSCRIPT_BUFSIZE 0x4000 // MAXIMUM BUFSIZE EQ 0xFFFF
+#define POSTSCRIPT_BOUNDINGSEARCH 0x1000 // we only try to get the BoundingBox
+ // in the first 4096 bytes
+
+static BYTE* ImplSearchEntry( BYTE* pSource, BYTE* pDest, ULONG nComp, ULONG nSize )
+{
+ while ( nComp-- >= nSize )
+ {
+ for ( ULONG i = 0; i < nSize; i++ )
+ {
+ if ( ( pSource[i]&~0x20 ) != ( pDest[i]&~0x20 ) )
+ break;
+ }
+ if ( i == nSize )
+ return pSource;
+ pSource++;
+ }
+ return NULL;
+}
+
+static BOOL ImplGetBoundingBox( double* nNumb, BYTE* pSource, ULONG nSize )
+{
+ BOOL bRetValue = FALSE;
+ ULONG nBytesRead;
+
+ if ( nSize < 256 ) // we assume that the file is greater than 256 bytes
+ return FALSE;
+
+ if ( nSize < POSTSCRIPT_BOUNDINGSEARCH )
+ nBytesRead = nSize;
+ else
+ nBytesRead = POSTSCRIPT_BOUNDINGSEARCH;
+
+ BYTE* pDest = ImplSearchEntry( pSource, (BYTE*)"%%BoundingBox:", nBytesRead, 14 );
+ if ( pDest )
+ {
+ int nSecurityCount = 100; // only 100 bytes following the bounding box will be checked
+ nNumb[0] = nNumb[1] = nNumb[2] = nNumb[3] = 0;
+ pDest += 14;
+ for ( int i = 0; ( i < 4 ) && nSecurityCount; i++ )
+ {
+ int nDivision = 1;
+ BOOL bDivision = FALSE;
+ BOOL bNegative = FALSE;
+ BOOL bValid = TRUE;
+
+ while ( ( --nSecurityCount ) && ( *pDest == ' ' ) || ( *pDest == 0x9 ) ) pDest++;
+ BYTE nByte = *pDest;
+ while ( nSecurityCount && ( nByte != ' ' ) && ( nByte != 0x9 ) && ( nByte != 0xd ) && ( nByte != 0xa ) )
+ {
+ switch ( nByte )
+ {
+ case '.' :
+ if ( bDivision )
+ bValid = FALSE;
+ else
+ bDivision = TRUE;
+ break;
+ case '-' :
+ bNegative = TRUE;
+ break;
+ default :
+ if ( ( nByte < '0' ) || ( nByte > '9' ) )
+ nSecurityCount = 1; // error parsing the bounding box values
+ else if ( bValid )
+ {
+ if ( bDivision )
+ nDivision*=10;
+ nNumb[i] *= 10;
+ nNumb[i] += nByte - '0';
+ }
+ break;
+ }
+ nSecurityCount--;
+ nByte = *(++pDest);
+ }
+ if ( bNegative )
+ nNumb[i] = -nNumb[i];
+ if ( bDivision && ( nDivision != 1 ) )
+ nNumb[i] /= nDivision;
+ }
+ if ( nSecurityCount)
+ bRetValue = TRUE;
+ }
+ return bRetValue;
+}
+
+inline void ImplWriteDouble( BYTE** pBuf, double nNumb )
+{
+ *pBuf += sprintf( (char*)*pBuf, "%f", nNumb );
+ *(*pBuf)++ = ' ';
+}
+
+inline void ImplWriteString( BYTE** pBuf, const char* sString )
+{
+ strcpy( (char*)*pBuf, sString );
+ *pBuf += strlen( sString );
+}
+
+BOOL SalGraphics::DrawEPS( long nX, long nY, long nWidth, long nHeight, void* pPtr, ULONG nSize )
+{
+ BOOL bRetValue = FALSE;
+
+ if ( maGraphicsData.mbPrinter )
+ {
+ int nEscape = POSTSCRIPT_PASSTHROUGH;
+
+ if ( Escape( maGraphicsData.mhDC, QUERYESCSUPPORT, sizeof( int ), ( LPSTR )&nEscape, 0 ) )
+ {
+ BYTE* pBuf = new BYTE[ POSTSCRIPT_BUFSIZE ];
+
+ double nBoundingBox[4];
+
+ if ( pBuf && ImplGetBoundingBox( nBoundingBox, (BYTE*)pPtr, nSize ) )
+ {
+ double dM11 = nWidth / ( nBoundingBox[2] - nBoundingBox[0] );
+ double dM22 = nHeight / (nBoundingBox[1] - nBoundingBox[3] );
+ BYTE* pTemp = pBuf + 2; // +2 because we want to insert the size later
+ ImplWriteString( &pTemp, "\n\nsave\n[ " );
+ ImplWriteDouble( &pTemp, dM11 );
+ ImplWriteDouble( &pTemp, 0 );
+ ImplWriteDouble( &pTemp, 0 );
+ ImplWriteDouble( &pTemp, dM22 );
+ ImplWriteDouble( &pTemp, nX - ( dM11 * nBoundingBox[0] ) );
+ ImplWriteDouble( &pTemp, nY - ( dM22 * nBoundingBox[3] ) );
+ ImplWriteString( &pTemp, "] concat /showpage {} def\n" );
+ ImplWriteString( &pTemp, "%%BeginDocument:\n" );
+ *((USHORT*)pBuf) = (USHORT)( pTemp - pBuf - 2 );
+ Escape ( maGraphicsData.mhDC, nEscape, pTemp - pBuf, (LPTSTR)((BYTE*)pBuf), 0 );
+
+ ULONG nToDo = nSize;
+ ULONG nDoNow;
+ while ( nToDo )
+ {
+ nDoNow = nToDo;
+ if ( nToDo > POSTSCRIPT_BUFSIZE - 2 )
+ nDoNow = POSTSCRIPT_BUFSIZE - 2;
+ *((USHORT*)pBuf) = (USHORT)nDoNow;
+ memcpy( pBuf + 2, (BYTE*)pPtr + nSize - nToDo, nDoNow );
+ ULONG nResult = Escape ( maGraphicsData.mhDC, nEscape, nDoNow + 2, (LPTSTR)((BYTE*)pBuf), 0 );
+ if (!nResult )
+ break;
+ nToDo -= nResult;
+ }
+ pTemp = pBuf + 2;
+ ImplWriteString( &pTemp, "%%EndDocument\n" );
+ ImplWriteString( &pTemp, "restore\n\n" );
+ *((USHORT*)pBuf) = (USHORT)( pTemp - pBuf - 2 );
+ Escape ( maGraphicsData.mhDC, nEscape, pTemp - pBuf, (LPTSTR)((BYTE*)pBuf), 0 );
+ bRetValue = TRUE;
+ }
+ delete pBuf;
+ }
+ }
+
+ return bRetValue;
+}
diff --git a/vcl/win/source/gdi/salgdi2.cxx b/vcl/win/source/gdi/salgdi2.cxx
new file mode 100644
index 000000000000..20252e35f31b
--- /dev/null
+++ b/vcl/win/source/gdi/salgdi2.cxx
@@ -0,0 +1,782 @@
+/*************************************************************************
+ *
+ * $RCSfile: salgdi2.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:49 $
+ *
+ * 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 <string.h>
+#include <stdlib.h>
+
+#ifndef _SVWIN_H
+#include <tools/svwin.h>
+#endif
+
+#ifndef _TOOLS_DEBUG_HXX
+#include <tools/debug.hxx>
+#endif
+
+#define _SV_SALGDI2_CXX
+
+#ifndef _SV_WINCOMP_HXX
+#include <wincomp.hxx>
+#endif
+#ifndef _SV_SALBMP_HXX
+#include <salbmp.hxx>
+#endif
+#ifndef _SV_SALDATA_HXX
+#include <saldata.hxx>
+#endif
+#ifndef _SV_SALIDS_HRC
+#include <salids.hrc>
+#endif
+#ifndef _SV_SALGDI_HXX
+#include <salgdi.hxx>
+#endif
+
+// =======================================================================
+
+BOOL bFastTransparent = FALSE;
+
+// =======================================================================
+
+void SalGraphics::CopyBits( const SalTwoRect* pPosAry, SalGraphics* pSrcGraphics )
+{
+ HDC hSrcDC;
+ DWORD nRop;
+
+ if ( pSrcGraphics )
+ hSrcDC = pSrcGraphics->maGraphicsData.mhDC;
+ else
+ hSrcDC = maGraphicsData.mhDC;
+
+ if ( maGraphicsData.mbXORMode )
+ nRop = SRCINVERT;
+ else
+ nRop = SRCCOPY;
+
+ if ( (pPosAry->mnSrcWidth == pPosAry->mnDestWidth) &&
+ (pPosAry->mnSrcHeight == pPosAry->mnDestHeight) )
+ {
+ BitBlt( maGraphicsData.mhDC,
+ (int)pPosAry->mnDestX, (int)pPosAry->mnDestY,
+ (int)pPosAry->mnDestWidth, (int)pPosAry->mnDestHeight,
+ hSrcDC,
+ (int)pPosAry->mnSrcX, (int)pPosAry->mnSrcY,
+ nRop );
+ }
+ else
+ {
+ int nOldStretchMode = SetStretchBltMode( maGraphicsData.mhDC, STRETCH_DELETESCANS );
+ StretchBlt( maGraphicsData.mhDC,
+ (int)pPosAry->mnDestX, (int)pPosAry->mnDestY,
+ (int)pPosAry->mnDestWidth, (int)pPosAry->mnDestHeight,
+ hSrcDC,
+ (int)pPosAry->mnSrcX, (int)pPosAry->mnSrcY,
+ (int)pPosAry->mnSrcWidth, (int)pPosAry->mnSrcHeight,
+ nRop );
+ SetStretchBltMode( maGraphicsData.mhDC, nOldStretchMode );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void ImplCalcOutSideRgn( const RECT& rSrcRect,
+ int nLeft, int nTop, int nRight, int nBottom,
+ HRGN& rhInvalidateRgn )
+{
+ HRGN hTempRgn;
+
+ // Bereiche ausserhalb des sichtbaren Bereiches berechnen
+ if ( rSrcRect.left < nLeft )
+ {
+ if ( !rhInvalidateRgn )
+ rhInvalidateRgn = CreateRectRgnIndirect( &rSrcRect );
+ hTempRgn = CreateRectRgn( -31999, 0, nLeft, 31999 );
+ CombineRgn( rhInvalidateRgn, rhInvalidateRgn, hTempRgn, RGN_DIFF );
+ DeleteRegion( hTempRgn );
+ }
+ if ( rSrcRect.top < nTop )
+ {
+ if ( !rhInvalidateRgn )
+ rhInvalidateRgn = CreateRectRgnIndirect( &rSrcRect );
+ hTempRgn = CreateRectRgn( 0, -31999, 31999, nTop );
+ CombineRgn( rhInvalidateRgn, rhInvalidateRgn, hTempRgn, RGN_DIFF );
+ DeleteRegion( hTempRgn );
+ }
+ if ( rSrcRect.right > nRight )
+ {
+ if ( !rhInvalidateRgn )
+ rhInvalidateRgn = CreateRectRgnIndirect( &rSrcRect );
+ hTempRgn = CreateRectRgn( nRight, 0, 31999, 31999 );
+ CombineRgn( rhInvalidateRgn, rhInvalidateRgn, hTempRgn, RGN_DIFF );
+ DeleteRegion( hTempRgn );
+ }
+ if ( rSrcRect.bottom > nBottom )
+ {
+ if ( !rhInvalidateRgn )
+ rhInvalidateRgn = CreateRectRgnIndirect( &rSrcRect );
+ hTempRgn = CreateRectRgn( 0, nBottom, 31999, 31999 );
+ CombineRgn( rhInvalidateRgn, rhInvalidateRgn, hTempRgn, RGN_DIFF );
+ DeleteRegion( hTempRgn );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void SalGraphics::CopyArea( long nDestX, long nDestY,
+ long nSrcX, long nSrcY,
+ long nSrcWidth, long nSrcHeight,
+ USHORT nFlags )
+{
+ BitBlt( maGraphicsData.mhDC,
+ (int)nDestX, (int)nDestY,
+ (int)nSrcWidth, (int)nSrcHeight,
+ maGraphicsData.mhDC,
+ (int)nSrcX, (int)nSrcY,
+ SRCCOPY );
+
+ // Muessen die ueberlappenden Bereiche auch invalidiert werden?
+ if ( (nFlags & SAL_COPYAREA_WINDOWINVALIDATE) && maGraphicsData.mbWindow )
+ {
+ // Overlap-Bereich berechnen und invalidieren
+ RECT aSrcRect;
+ RECT aClipRect;
+ RECT aTempRect;
+ RECT aTempRect2;
+ HRGN hInvalidateRgn;
+ HRGN hTempRgn;
+ HWND hWnd;
+ int nRgnType;
+
+ aSrcRect.left = (int)nSrcX;
+ aSrcRect.top = (int)nSrcY;
+ aSrcRect.right = aSrcRect.left+(int)nSrcWidth;
+ aSrcRect.bottom = aSrcRect.top+(int)nSrcHeight;
+ GetClientRect( maGraphicsData.mhWnd, &aClipRect );
+ if ( IntersectRect( &aSrcRect, &aSrcRect, &aClipRect ) )
+ {
+ // Rechteck in Screen-Koordinaaten umrechnen
+ POINT aPt;
+ int nScreenDX = GetSystemMetrics( SM_CXSCREEN );
+ int nScreenDY = GetSystemMetrics( SM_CYSCREEN );
+ aPt.x = 0;
+ aPt.y = 0;
+ ClientToScreen( maGraphicsData.mhWnd, &aPt );
+ aSrcRect.left += aPt.x;
+ aSrcRect.top += aPt.y;
+ aSrcRect.right += aPt.x;
+ aSrcRect.bottom += aPt.y;
+ hInvalidateRgn = 0;
+ // Bereiche ausserhalb des sichtbaren Bereiches berechnen
+ ImplCalcOutSideRgn( aSrcRect, 0, 0, nScreenDX, nScreenDY, hInvalidateRgn );
+
+ // Bereiche die von anderen Fenstern ueberlagert werden berechnen
+ HRGN hTempRgn2 = 0;
+ HWND hWndTopWindow = maGraphicsData.mhWnd;
+ // Find the TopLevel Window, because only Windows which are in
+ // in the foreground of our TopLevel window must be considered
+ if ( GetWindowStyle( hWndTopWindow ) & WS_CHILD )
+ {
+ RECT aTempRect3 = aSrcRect;
+ do
+ {
+ hWndTopWindow = ::GetParent( hWndTopWindow );
+
+ // Test, if the Parent clip our window
+ GetClientRect( hWndTopWindow, &aTempRect );
+ POINT aPt2;
+ aPt2.x = 0;
+ aPt2.y = 0;
+ ClientToScreen( hWndTopWindow, &aPt2 );
+ aTempRect.left += aPt2.x;
+ aTempRect.top += aPt2.y;
+ aTempRect.right += aPt2.x;
+ aTempRect.bottom += aPt2.y;
+ IntersectRect( &aTempRect3, &aTempRect3, &aTempRect );
+ }
+ while ( GetWindowStyle( hWndTopWindow ) & WS_CHILD );
+
+ // If one or more Parents clip our window, than we must
+ // calculate the outside area
+ if ( !EqualRect( &aSrcRect, &aTempRect3 ) )
+ {
+ ImplCalcOutSideRgn( aSrcRect,
+ aTempRect3.left, aTempRect3.top,
+ aTempRect3.right, aTempRect3.bottom,
+ hInvalidateRgn );
+ }
+ }
+ hWnd = GetWindow( GetDesktopWindow(), GW_CHILD );
+ while ( hWnd )
+ {
+ if ( hWnd == hWndTopWindow )
+ break;
+ if ( IsWindowVisible( hWnd ) && !IsIconic( hWnd ) )
+ {
+ GetWindowRect( hWnd, &aTempRect );
+ if ( IntersectRect( &aTempRect2, &aSrcRect, &aTempRect ) )
+ {
+ if ( !hInvalidateRgn )
+ hInvalidateRgn = CreateRectRgnIndirect( &aSrcRect );
+ hTempRgn = CreateRectRgnIndirect( &aTempRect );
+ if ( !hTempRgn2 )
+ hTempRgn2 = CreateRectRgn( 0, 0, 0, 0 );
+ nRgnType = GetWindowRgn( hWnd, hTempRgn2 );
+ if ( (nRgnType != ERROR) && (nRgnType != NULLREGION) )
+ {
+ OffsetRgn( hTempRgn2, aTempRect.left, aTempRect.top );
+ CombineRgn( hTempRgn, hTempRgn, hTempRgn2, RGN_AND );
+ }
+ CombineRgn( hInvalidateRgn, hInvalidateRgn, hTempRgn, RGN_DIFF );
+ DeleteRegion( hTempRgn );
+ }
+ }
+ hWnd = GetWindow( hWnd, GW_HWNDNEXT );
+ }
+ if ( hTempRgn2 )
+ DeleteRegion( hTempRgn2 );
+ if ( hInvalidateRgn )
+ {
+ hTempRgn = CreateRectRgnIndirect( &aSrcRect );
+ nRgnType = CombineRgn( hInvalidateRgn, hTempRgn, hInvalidateRgn, RGN_DIFF );
+ if ( (nRgnType != ERROR) && (nRgnType != NULLREGION) )
+ {
+ int nOffX = (int)(nDestX-nSrcX);
+ int nOffY = (int)(nDestY-nSrcY);
+ OffsetRgn( hInvalidateRgn, nOffX-aPt.x, nOffY-aPt.y );
+ // Combine Invalidate Region with existing ClipRegion
+ if ( GetClipRgn( maGraphicsData.mhDC, hTempRgn ) == 1 )
+ nRgnType = CombineRgn( hInvalidateRgn, hTempRgn, hInvalidateRgn, RGN_AND );
+ if ( (nRgnType != ERROR) && (nRgnType != NULLREGION) )
+ {
+ InvalidateRgn( maGraphicsData.mhWnd, hInvalidateRgn, TRUE );
+ // Hier loesen wir nur ein Update aus, wenn es der
+ // MainThread ist, damit es beim Bearbeiten der
+ // Paint-Message keinen Deadlock gibt, da der
+ // SolarMutex durch diesen Thread schon gelockt ist
+ SalData* pSalData = GetSalData();
+ DWORD nCurThreadId = GetCurrentThreadId();
+ if ( pSalData->mnAppThreadId == nCurThreadId )
+ UpdateWindow( maGraphicsData.mhWnd );
+ }
+ }
+ DeleteRegion( hTempRgn );
+ DeleteRegion( hInvalidateRgn );
+ }
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void ImplDrawBitmap( HDC hDC,
+ const SalTwoRect* pPosAry, const SalBitmap& rSalBitmap,
+ BOOL bPrinter, int nDrawMode )
+{
+ if( hDC )
+ {
+ HGLOBAL hDrawDIB;
+ HBITMAP hDrawDDB = rSalBitmap.ImplGethDDB();
+ SalBitmap* pTmpSalBmp;
+ BOOL bPrintDDB = ( bPrinter && hDrawDDB );
+
+ if( bPrintDDB )
+ {
+ pTmpSalBmp = new SalBitmap;
+ pTmpSalBmp->Create( rSalBitmap, rSalBitmap.GetBitCount() );
+ hDrawDIB = pTmpSalBmp->ImplGethDIB();
+ }
+ else
+ hDrawDIB = rSalBitmap.ImplGethDIB();
+
+ if( hDrawDIB )
+ {
+ PBITMAPINFO pBI = (PBITMAPINFO) GlobalLock( hDrawDIB );
+ PBITMAPINFOHEADER pBIH = (PBITMAPINFOHEADER) pBI;
+ PBYTE pBits = (PBYTE) pBI + *(DWORD*) pBI +
+ rSalBitmap.ImplGetDIBColorCount( hDrawDIB ) * sizeof( RGBQUAD );
+ const int nOldStretchMode = SetStretchBltMode( hDC, STRETCH_DELETESCANS );
+
+ int nCount = StretchDIBits( hDC,
+ (int)pPosAry->mnDestX, (int)pPosAry->mnDestY,
+ (int)pPosAry->mnDestWidth, (int)pPosAry->mnDestHeight,
+ (int)pPosAry->mnSrcX, (int)(pBIH->biHeight - pPosAry->mnSrcHeight - pPosAry->mnSrcY),
+ (int)pPosAry->mnSrcWidth, (int)pPosAry->mnSrcHeight,
+ pBits, pBI, DIB_RGB_COLORS, nDrawMode );
+
+ GlobalUnlock( hDrawDIB );
+ SetStretchBltMode( hDC, nOldStretchMode );
+ }
+ else if( hDrawDDB && !bPrintDDB )
+ {
+ HDC hBmpDC = ImplGetCachedDC( CACHED_HDC_DRAW, hDrawDDB );
+ COLORREF nOldBkColor;
+ COLORREF nOldTextColor;
+ BOOL bMono = ( rSalBitmap.GetBitCount() == 1 );
+
+ if( bMono )
+ {
+ nOldBkColor = SetBkColor( hDC, RGB( 0xFF, 0xFF, 0xFF ) );
+ nOldTextColor = ::SetTextColor( hDC, RGB( 0x00, 0x00, 0x00 ) );
+ }
+
+ if ( (pPosAry->mnSrcWidth == pPosAry->mnDestWidth) &&
+ (pPosAry->mnSrcHeight == pPosAry->mnDestHeight) )
+ {
+ BitBlt( hDC,
+ (int)pPosAry->mnDestX, (int)pPosAry->mnDestY,
+ (int)pPosAry->mnDestWidth, (int)pPosAry->mnDestHeight,
+ hBmpDC,
+ (int)pPosAry->mnSrcX, (int)pPosAry->mnSrcY,
+ nDrawMode );
+ }
+ else
+ {
+ const int nOldStretchMode = SetStretchBltMode( hDC, STRETCH_DELETESCANS );
+
+ StretchBlt( hDC,
+ (int)pPosAry->mnDestX, (int)pPosAry->mnDestY,
+ (int)pPosAry->mnDestWidth, (int)pPosAry->mnDestHeight,
+ hBmpDC,
+ (int)pPosAry->mnSrcX, (int)pPosAry->mnSrcY,
+ (int)pPosAry->mnSrcWidth, (int)pPosAry->mnSrcHeight,
+ nDrawMode );
+
+ SetStretchBltMode( hDC, nOldStretchMode );
+ }
+
+ if( bMono )
+ {
+ SetBkColor( hDC, nOldBkColor );
+ ::SetTextColor( hDC, nOldTextColor );
+ }
+
+ ImplReleaseCachedDC( CACHED_HDC_DRAW );
+ }
+
+ if( bPrintDDB )
+ delete pTmpSalBmp;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void SalGraphics::DrawBitmap( const SalTwoRect* pPosAry,
+ const SalBitmap& rSalBitmap )
+{
+ ImplDrawBitmap( maGraphicsData.mhDC, pPosAry, rSalBitmap,
+ maGraphicsData.mbPrinter,
+ maGraphicsData.mbXORMode ? SRCINVERT : SRCCOPY );
+}
+
+// -----------------------------------------------------------------------
+
+void SalGraphics::DrawBitmap( const SalTwoRect* pPosAry,
+ const SalBitmap& rSalBitmap,
+ SalColor nTransparentColor )
+{
+ DBG_ASSERT( !maGraphicsData.mbPrinter, "No transparency print possible!" );
+
+ SalBitmap* pMask = new SalBitmap;
+ HDC hDC = maGraphicsData.mhDC;
+ const Point aPoint;
+ const Size aSize( rSalBitmap.GetSize() );
+ HBITMAP hMaskBitmap = CreateBitmap( (int) aSize.Width(), (int) aSize.Height(), 1, 1, NULL );
+ HDC hMaskDC = ImplGetCachedDC( CACHED_HDC_1, hMaskBitmap );
+ const BYTE cRed = SALCOLOR_RED( nTransparentColor );
+ const BYTE cGreen = SALCOLOR_GREEN( nTransparentColor );
+ const BYTE cBlue = SALCOLOR_BLUE( nTransparentColor );
+
+ if( rSalBitmap.ImplGethDDB() )
+ {
+ HDC hSrcDC = ImplGetCachedDC( CACHED_HDC_2, rSalBitmap.ImplGethDDB() );
+ COLORREF aOldCol = SetBkColor( hSrcDC, RGB( cRed, cGreen, cBlue ) );
+
+ BitBlt( hMaskDC, 0, 0, (int) aSize.Width(), (int) aSize.Height(), hSrcDC, 0, 0, SRCCOPY );
+
+ SetBkColor( hSrcDC, aOldCol );
+ ImplReleaseCachedDC( CACHED_HDC_2 );
+ }
+ else
+ {
+ SalBitmap* pTmpSalBmp = new SalBitmap;
+
+ if( pTmpSalBmp->Create( rSalBitmap, this ) )
+ {
+ HDC hSrcDC = ImplGetCachedDC( CACHED_HDC_2, pTmpSalBmp->ImplGethDDB() );
+ COLORREF aOldCol = SetBkColor( hSrcDC, RGB( cRed, cGreen, cBlue ) );
+
+ BitBlt( hMaskDC, 0, 0, (int) aSize.Width(), (int) aSize.Height(), hSrcDC, 0, 0, SRCCOPY );
+
+ SetBkColor( hSrcDC, aOldCol );
+ ImplReleaseCachedDC( CACHED_HDC_2 );
+ }
+
+ delete pTmpSalBmp;
+ }
+
+ ImplReleaseCachedDC( CACHED_HDC_1 );
+
+ // hMaskBitmap is destroyed by new SalBitmap 'pMask' ( bDIB==FALSE, bCopy == FALSE )
+ if( pMask->Create( hMaskBitmap, FALSE, FALSE ) )
+ DrawBitmap( pPosAry, rSalBitmap, *pMask );
+
+ delete pMask;
+}
+
+// -----------------------------------------------------------------------
+
+void SalGraphics::DrawBitmap( const SalTwoRect* pPosAry,
+ const SalBitmap& rSalBitmap,
+ const SalBitmap& rTransparentBitmap )
+{
+ DBG_ASSERT( !maGraphicsData.mbPrinter, "No transparency print possible!" );
+
+ if( bFastTransparent )
+ {
+ // bei Paletten-Displays hat WIN/WNT offenbar ein kleines Problem,
+ // die Farben der Maske richtig auf die Palette abzubilden,
+ // wenn wir die DIB direkt ausgeben => DDB-Ausgabe
+ if( ( GetBitCount() <= 8 ) && rTransparentBitmap.ImplGethDIB() && rTransparentBitmap.GetBitCount() == 1 )
+ {
+ SalBitmap aTmp;
+ if( aTmp.Create( rTransparentBitmap, this ) )
+ ImplDrawBitmap( maGraphicsData.mhDC, pPosAry, aTmp, FALSE, SRCAND );
+ }
+ else
+ ImplDrawBitmap( maGraphicsData.mhDC, pPosAry, rTransparentBitmap, FALSE, SRCAND );
+
+ // bei Paletten-Displays hat WIN/WNT offenbar ein kleines Problem,
+ // die Farben der Maske richtig auf die Palette abzubilden,
+ // wenn wir die DIB direkt ausgeben => DDB-Ausgabe
+ if( ( GetBitCount() <= 8 ) && rSalBitmap.ImplGethDIB() && rSalBitmap.GetBitCount() == 1 )
+ {
+ SalBitmap aTmp;
+ if( aTmp.Create( rSalBitmap, this ) )
+ ImplDrawBitmap( maGraphicsData.mhDC, pPosAry, aTmp, FALSE, SRCPAINT );
+ }
+ else
+ ImplDrawBitmap( maGraphicsData.mhDC, pPosAry, rSalBitmap, FALSE, SRCPAINT );
+ }
+ else
+ {
+ SalTwoRect aPosAry = *pPosAry;
+ int nDstX = (int)aPosAry.mnDestX;
+ int nDstY = (int)aPosAry.mnDestY;
+ int nDstWidth = (int)aPosAry.mnDestWidth;
+ int nDstHeight = (int)aPosAry.mnDestHeight;
+ HDC hDC = maGraphicsData.mhDC;
+ HBITMAP hMemBitmap = 0;
+ HBITMAP hMaskBitmap = 0;
+
+ if( ( nDstWidth > CACHED_HDC_DEFEXT ) || ( nDstHeight > CACHED_HDC_DEFEXT ) )
+ {
+ hMemBitmap = CreateCompatibleBitmap( hDC, nDstWidth, nDstHeight );
+ hMaskBitmap = CreateCompatibleBitmap( hDC, nDstWidth, nDstHeight );
+ }
+
+ HDC hMemDC = ImplGetCachedDC( CACHED_HDC_1, hMemBitmap );
+ HDC hMaskDC = ImplGetCachedDC( CACHED_HDC_2, hMaskBitmap );
+
+ aPosAry.mnDestX = aPosAry.mnDestY = 0;
+ BitBlt( hMemDC, 0, 0, nDstWidth, nDstHeight, hDC, nDstX, nDstY, SRCCOPY );
+
+ // bei Paletten-Displays hat WIN/WNT offenbar ein kleines Problem,
+ // die Farben der Maske richtig auf die Palette abzubilden,
+ // wenn wir die DIB direkt ausgeben => DDB-Ausgabe
+ if( ( GetBitCount() <= 8 ) && rTransparentBitmap.ImplGethDIB() && rTransparentBitmap.GetBitCount() == 1 )
+ {
+ SalBitmap aTmp;
+
+ if( aTmp.Create( rTransparentBitmap, this ) )
+ ImplDrawBitmap( hMaskDC, &aPosAry, aTmp, FALSE, SRCCOPY );
+ }
+ else
+ ImplDrawBitmap( hMaskDC, &aPosAry, rTransparentBitmap, FALSE, SRCCOPY );
+
+ BitBlt( hMemDC, 0, 0, nDstWidth, nDstHeight, hMaskDC, 0, 0, SRCAND );
+ ImplDrawBitmap( hMaskDC, &aPosAry, rSalBitmap, FALSE, SRCERASE );
+ BitBlt( hMemDC, 0, 0, nDstWidth, nDstHeight, hMaskDC, 0, 0, SRCPAINT );
+ BitBlt( hDC, nDstX, nDstY, nDstWidth, nDstHeight, hMemDC, 0, 0, SRCCOPY );
+
+ ImplReleaseCachedDC( CACHED_HDC_1 );
+ ImplReleaseCachedDC( CACHED_HDC_2 );
+
+ // hMemBitmap != 0 ==> hMaskBitmap != 0
+ if( hMemBitmap )
+ {
+ DeleteObject( hMemBitmap );
+ DeleteObject( hMaskBitmap );
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void SalGraphics::DrawMask( const SalTwoRect* pPosAry,
+ const SalBitmap& rSalBitmap,
+ SalColor nMaskColor )
+{
+ DBG_ASSERT( !maGraphicsData.mbPrinter, "No transparency print possible!" );
+
+ SalTwoRect aPosAry = *pPosAry;
+ const BYTE cRed = SALCOLOR_RED( nMaskColor );
+ const BYTE cGreen = SALCOLOR_GREEN( nMaskColor );
+ const BYTE cBlue = SALCOLOR_BLUE( nMaskColor );
+ HDC hDC = maGraphicsData.mhDC;
+ HBRUSH hMaskBrush = CreateSolidBrush( RGB( cRed, cGreen, cBlue ) );
+ HBRUSH hOldBrush = SelectBrush( hDC, hMaskBrush );
+
+ // bei Paletten-Displays hat WIN/WNT offenbar ein kleines Problem,
+ // die Farben der Maske richtig auf die Palette abzubilden,
+ // wenn wir die DIB direkt ausgeben => DDB-Ausgabe
+ if( ( GetBitCount() <= 8 ) && rSalBitmap.ImplGethDIB() && rSalBitmap.GetBitCount() == 1 )
+ {
+ SalBitmap aTmp;
+
+ if( aTmp.Create( rSalBitmap, this ) )
+ ImplDrawBitmap( hDC, &aPosAry, aTmp, FALSE, 0x00B8074AUL );
+ }
+ else
+ ImplDrawBitmap( hDC, &aPosAry, rSalBitmap, FALSE, 0x00B8074AUL );
+
+ SelectBrush( hDC, hOldBrush );
+ DeleteBrush( hMaskBrush );
+}
+
+// -----------------------------------------------------------------------
+
+SalBitmap* SalGraphics::GetBitmap( long nX, long nY, long nDX, long nDY )
+{
+ DBG_ASSERT( !maGraphicsData.mbPrinter, "No ::GetBitmap() from printer possible!" );
+
+ SalBitmap* pSalBitmap = NULL;
+
+ nDX = labs( nDX );
+ nDY = labs( nDY );
+
+ HDC hDC = maGraphicsData.mhDC;
+ HBITMAP hBmpBitmap = CreateCompatibleBitmap( hDC, nDX, nDY );
+ HDC hBmpDC = ImplGetCachedDC( CACHED_HDC_1, hBmpBitmap );
+ BOOL bRet;
+
+ bRet = BitBlt( hBmpDC, 0, 0, (int) nDX, (int) nDY, hDC, (int) nX, (int) nY, SRCCOPY );
+ ImplReleaseCachedDC( CACHED_HDC_1 );
+
+ if( bRet )
+ {
+ pSalBitmap = new SalBitmap;
+
+ if( !pSalBitmap->Create( hBmpBitmap, FALSE, FALSE ) )
+ {
+ delete pSalBitmap;
+ pSalBitmap = NULL;
+ }
+ }
+
+ return pSalBitmap;
+}
+
+// -----------------------------------------------------------------------
+
+SalColor SalGraphics::GetPixel( long nX, long nY )
+{
+ COLORREF aWinCol = ::GetPixel( maGraphicsData.mhDC, (int) nX, (int) nY );
+
+#ifdef WIN
+ if ( -1 == aWinCol )
+#else
+ if ( CLR_INVALID == aWinCol )
+#endif
+ return MAKE_SALCOLOR( 0, 0, 0 );
+ else
+ return MAKE_SALCOLOR( GetRValue( aWinCol ),
+ GetGValue( aWinCol ),
+ GetBValue( aWinCol ) );
+}
+
+// -----------------------------------------------------------------------
+
+void SalGraphics::Invert( long nX, long nY, long nWidth, long nHeight, SalInvert nFlags )
+{
+ if ( nFlags & SAL_INVERT_TRACKFRAME )
+ {
+ HPEN hDotPen = CreatePen( PS_DOT, 0, 0 );
+ HPEN hOldPen = SelectPen( maGraphicsData.mhDC, hDotPen );
+ HBRUSH hOldBrush = SelectBrush( maGraphicsData.mhDC, GetStockBrush( NULL_BRUSH ) );
+ int nOldROP = SetROP2( maGraphicsData.mhDC, R2_NOT );
+
+ WIN_Rectangle( maGraphicsData.mhDC, (int)nX, (int)nY, (int)(nX+nWidth), (int)(nY+nHeight) );
+
+ SetROP2( maGraphicsData.mhDC, nOldROP );
+ SelectPen( maGraphicsData.mhDC, hOldPen );
+ SelectBrush( maGraphicsData.mhDC, hOldBrush );
+ DeletePen( hDotPen );
+ }
+ else if ( nFlags & SAL_INVERT_50 )
+ {
+ SalData* pSalData = GetSalData();
+ if ( !pSalData->mh50Brush )
+ {
+ if ( !pSalData->mh50Bmp )
+ pSalData->mh50Bmp = ImplLoadSalBitmap( SAL_RESID_BITMAP_50 );
+ pSalData->mh50Brush = CreatePatternBrush( pSalData->mh50Bmp );
+ }
+
+ COLORREF nOldTextColor = ::SetTextColor( maGraphicsData.mhDC, 0 );
+ HBRUSH hOldBrush = SelectBrush( maGraphicsData.mhDC, pSalData->mh50Brush );
+ PatBlt( maGraphicsData.mhDC, nX, nY, nWidth, nHeight, PATINVERT );
+ ::SetTextColor( maGraphicsData.mhDC, nOldTextColor );
+ SelectBrush( maGraphicsData.mhDC, hOldBrush );
+ }
+ else
+ {
+ RECT aRect;
+ aRect.left = (int)nX;
+ aRect.top = (int)nY;
+ aRect.right = (int)nX+nWidth;
+ aRect.bottom = (int)nY+nHeight;
+ ::InvertRect( maGraphicsData.mhDC, &aRect );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void SalGraphics::Invert( ULONG nPoints, const SalPoint* pPtAry, SalInvert nSalFlags )
+{
+ HPEN hPen;
+ HPEN hOldPen;
+ HBRUSH hBrush;
+ HBRUSH hOldBrush;
+ COLORREF nOldTextColor;
+ int nOldROP = SetROP2( maGraphicsData.mhDC, R2_NOT );
+
+ if ( nSalFlags & SAL_INVERT_TRACKFRAME )
+ hPen = CreatePen( PS_DOT, 0, 0 );
+ else
+ {
+
+ if ( nSalFlags & SAL_INVERT_50 )
+ {
+ SalData* pSalData = GetSalData();
+ if ( !pSalData->mh50Brush )
+ {
+ if ( !pSalData->mh50Bmp )
+ pSalData->mh50Bmp = ImplLoadSalBitmap( SAL_RESID_BITMAP_50 );
+ pSalData->mh50Brush = CreatePatternBrush( pSalData->mh50Bmp );
+ }
+
+ hBrush = pSalData->mh50Brush;
+ }
+ else
+ hBrush = GetStockBrush( BLACK_BRUSH );
+
+ hPen = GetStockPen( NULL_PEN );
+ nOldTextColor = ::SetTextColor( maGraphicsData.mhDC, 0 );
+ hOldBrush = SelectBrush( maGraphicsData.mhDC, hBrush );
+ }
+ hOldPen = SelectPen( maGraphicsData.mhDC, hPen );
+
+ POINT* pWinPtAry;
+#ifdef WIN
+ if ( nPoints > MAX_64KSALPOINTS )
+ nPoints = MAX_64KSALPOINTS;
+
+ pWinPtAry = new POINT[(USHORT)nPoints];
+ const SalPoint huge* pHugePtAry = (const SalPoint huge*)pPtAry;
+ for( USHORT i=0; i < (USHORT)nPoints ; i++ )
+ {
+ pWinPtAry[i].x = (int)pHugePtAry[i].mnX;
+ pWinPtAry[i].y = (int)pHugePtAry[i].mnY;
+ }
+ if ( nSalFlags & SAL_INVERT_TRACKFRAME )
+ Polyline( maGraphicsData.mhDC, pWinPtAry, (int)nPoints );
+ else
+ WIN_Polygon( maGraphicsData.mhDC, pWinPtAry, (int)nPoints );
+ delete pWinPtAry;
+#else
+ // Unter NT koennen wir das Array direkt weiterreichen
+ DBG_ASSERT( sizeof( POINT ) == sizeof( SalPoint ),
+ "SalGraphics::DrawPolyLine(): POINT != SalPoint" );
+
+ pWinPtAry = (POINT*)pPtAry;
+ // Wegen Windows 95 und der Beschraenkung auf eine maximale Anzahl
+ // von Punkten
+ if ( nSalFlags & SAL_INVERT_TRACKFRAME )
+ {
+ if ( !Polyline( maGraphicsData.mhDC, pWinPtAry, (int)nPoints ) && (nPoints > MAX_64KSALPOINTS) )
+ Polyline( maGraphicsData.mhDC, pWinPtAry, MAX_64KSALPOINTS );
+ }
+ else
+ {
+ if ( !WIN_Polygon( maGraphicsData.mhDC, pWinPtAry, (int)nPoints ) && (nPoints > MAX_64KSALPOINTS) )
+ WIN_Polygon( maGraphicsData.mhDC, pWinPtAry, MAX_64KSALPOINTS );
+ }
+#endif
+
+ SetROP2( maGraphicsData.mhDC, nOldROP );
+ SelectPen( maGraphicsData.mhDC, hOldPen );
+
+ if ( nSalFlags & SAL_INVERT_TRACKFRAME )
+ DeletePen( hPen );
+ else
+ {
+ ::SetTextColor( maGraphicsData.mhDC, nOldTextColor );
+ SelectBrush( maGraphicsData.mhDC, hOldBrush );
+ }
+}
diff --git a/vcl/win/source/gdi/salgdi3.cxx b/vcl/win/source/gdi/salgdi3.cxx
new file mode 100644
index 000000000000..aa6b4c347090
--- /dev/null
+++ b/vcl/win/source/gdi/salgdi3.cxx
@@ -0,0 +1,1531 @@
+/*************************************************************************
+ *
+ * $RCSfile: salgdi3.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:49 $
+ *
+ * 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 <string.h>
+
+#ifndef _SVWIN_H
+#include <tools/svwin.h>
+#endif
+
+#define _SV_SALGDI3_CXX
+
+#ifndef _RTL_TENCINFO_H
+#include <rtl/tencinfo.h>
+#endif
+
+#ifndef _SV_WINCOMP_HXX
+#include <wincomp.hxx>
+#endif
+#ifndef _SV_SALDATA_HXX
+#include <saldata.hxx>
+#endif
+#ifndef _SV_SALGDI_HXX
+#include <salgdi.hxx>
+#endif
+#ifndef _SV_OUTFONT_HXX
+#include <outfont.hxx>
+#endif
+#ifndef _SV_FONT_HXX
+#include <font.hxx>
+#endif
+
+#ifndef _DEBUG_HXX
+#include <tools/debug.hxx>
+#endif
+
+// -----------
+// - Defines -
+// -----------
+
+#ifdef WIN
+#define GDI_ERROR (0xFFFFFFFFUL)
+#endif
+
+#define GLYPH_INC (512UL)
+#define MAX_POLYCOUNT (2048UL)
+#define CHECKPOINTS( _def_nPnt ) \
+ if( (_def_nPnt) >= nPtSize ) \
+ nPtSize = ImplIncreaseArrays( nPtSize, &pPoints, &pFlags, GLYPH_INC )
+
+// -----------
+// - Inlines -
+// -----------
+
+inline FIXED FixedFromDouble( double d )
+{
+ const long l = (long) ( d * 65536. );
+ return *(FIXED*) &l;
+}
+
+// -----------------------------------------------------------------------
+
+inline int IntFromFixed(FIXED f)
+{
+ return( ( f.fract >= 0x8000 ) ? ( f.value + 1 ) : f.value );
+}
+
+// -----------------------------------------------------------------------
+
+inline FIXED fxDiv2( FIXED fxVal1, FIXED fxVal2 )
+{
+ const long l = (*((long far *)&(fxVal1)) + *((long far *)&(fxVal2))) >> 1;
+ return *(FIXED*) &l;
+}
+
+// =======================================================================
+
+#define SAL_DRAWTEXT_STACKBUF 128
+
+// =======================================================================
+
+// Diese Variablen koennen static sein, da systemweite Einstellungen
+// gemerkt werden
+static BOOL bImplSalCourierScalable = FALSE;
+static BOOL bImplSalCourierNew = FALSE;
+
+// =======================================================================
+
+struct ImplEnumInfo
+{
+ HDC mhDC;
+ ImplDevFontList* mpList;
+ XubString* mpName;
+ LOGFONTA* mpLogFontA;
+ LOGFONTW* mpLogFontW;
+ BOOL mbCourier;
+ BOOL mbImplSalCourierScalable;
+ BOOL mbImplSalCourierNew;
+ BOOL mbPrinter;
+};
+
+// =======================================================================
+
+static CharSet ImplCharSetToSal( BYTE nCharSet )
+{
+ if ( nCharSet == OEM_CHARSET )
+ {
+ UINT nCP = (USHORT)GetOEMCP();
+ return rtl_getTextEncodingFromPCCodePage( nCP );
+ }
+ else
+ return rtl_getTextEncodingFromWindowsCharset( nCharSet );
+}
+
+// -----------------------------------------------------------------------
+
+static BYTE ImplCharSetToWin( CharSet eCharSet )
+{
+ return rtl_getBestWindowsCharsetFromTextEncoding( eCharSet );
+}
+
+// -----------------------------------------------------------------------
+
+static FontFamily ImplFamilyToSal( BYTE nFamily )
+{
+ switch ( nFamily & 0xF0 )
+ {
+ case FF_DECORATIVE:
+ return FAMILY_DECORATIVE;
+
+ case FF_MODERN:
+ return FAMILY_MODERN;
+
+ case FF_ROMAN:
+ return FAMILY_ROMAN;
+
+ case FF_SCRIPT:
+ return FAMILY_SCRIPT;
+
+ case FF_SWISS:
+ return FAMILY_SWISS;
+ }
+
+ return FAMILY_DONTKNOW;
+}
+
+// -----------------------------------------------------------------------
+
+static BYTE ImplFamilyToWin( FontFamily eFamily )
+{
+ switch ( eFamily )
+ {
+ case FAMILY_DECORATIVE:
+ return FF_DECORATIVE;
+
+ case FAMILY_MODERN:
+ return FF_MODERN;
+
+ case FAMILY_ROMAN:
+ return FF_ROMAN;
+
+ case FAMILY_SCRIPT:
+ return FF_SCRIPT;
+
+ case FAMILY_SWISS:
+ return FF_SWISS;
+
+ case FAMILY_SYSTEM:
+ return FF_SWISS;
+ }
+
+ return FF_DONTCARE;
+}
+
+// -----------------------------------------------------------------------
+
+static FontWeight ImplWeightToSal( WinWeight nWeight )
+{
+ if ( nWeight <= FW_THIN )
+ return WEIGHT_THIN;
+ else if ( nWeight <= FW_ULTRALIGHT )
+ return WEIGHT_ULTRALIGHT;
+ else if ( nWeight <= FW_LIGHT )
+ return WEIGHT_LIGHT;
+ else if ( nWeight < FW_MEDIUM )
+ return WEIGHT_NORMAL;
+ else if ( nWeight == FW_MEDIUM )
+ return WEIGHT_MEDIUM;
+ else if ( nWeight <= FW_SEMIBOLD )
+ return WEIGHT_SEMIBOLD;
+ else if ( nWeight <= FW_BOLD )
+ return WEIGHT_BOLD;
+ else if ( nWeight <= FW_ULTRABOLD )
+ return WEIGHT_ULTRABOLD;
+ else
+ return WEIGHT_BLACK;
+}
+
+// -----------------------------------------------------------------------
+
+static WinWeight ImplWeightToWin( FontWeight eWeight )
+{
+ switch ( eWeight )
+ {
+ case WEIGHT_THIN:
+ return FW_THIN;
+
+ case WEIGHT_ULTRALIGHT:
+ return FW_ULTRALIGHT;
+
+ case WEIGHT_LIGHT:
+ return FW_LIGHT;
+
+ case WEIGHT_SEMILIGHT:
+ case WEIGHT_NORMAL:
+ return FW_NORMAL;
+
+ case WEIGHT_MEDIUM:
+ return FW_MEDIUM;
+
+ case WEIGHT_SEMIBOLD:
+ return FW_SEMIBOLD;
+
+ case WEIGHT_BOLD:
+ return FW_BOLD;
+
+ case WEIGHT_ULTRABOLD:
+ return FW_ULTRABOLD;
+
+ case WEIGHT_BLACK:
+ return FW_BLACK;
+ }
+
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+inline FontPitch ImplLogPitchToSal( BYTE nPitch )
+{
+ if ( nPitch & FIXED_PITCH )
+ return PITCH_FIXED;
+ else
+ return PITCH_VARIABLE;
+}
+
+// -----------------------------------------------------------------------
+
+inline FontPitch ImplMetricPitchToSal( BYTE nPitch )
+{
+ // Sausaecke bei MS !! siehe NT Hilfe
+ if ( !(nPitch & TMPF_FIXED_PITCH) )
+ return PITCH_FIXED;
+ else
+ return PITCH_VARIABLE;
+}
+
+// -----------------------------------------------------------------------
+
+inline BYTE ImplPitchToWin( FontPitch ePitch )
+{
+ if ( ePitch == PITCH_FIXED )
+ return FIXED_PITCH;
+ else if ( ePitch == PITCH_VARIABLE )
+ return VARIABLE_PITCH;
+ else
+ return DEFAULT_PITCH;
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplLogMetricToDevFontDataA( const LOGFONTA* pLogFont,
+ const NEWTEXTMETRICA* pMetric,
+ DWORD nFontType,
+ ImplFontData* pData )
+{
+ if ( !(nFontType & RASTER_FONTTYPE) )
+ {
+ pData->mnWidth = 0;
+ pData->mnHeight = 0;
+ }
+ else
+ {
+ pData->mnWidth = 0;
+ pData->mnHeight = pMetric->tmHeight-pMetric->tmInternalLeading;
+ }
+ pData->meFamily = ImplFamilyToSal( pLogFont->lfPitchAndFamily );
+ pData->meCharSet = ImplCharSetToSal( pLogFont->lfCharSet );
+ pData->meWidthType = WIDTH_DONTKNOW;
+ pData->meWeight = ImplWeightToSal( pLogFont->lfWeight );
+ pData->meItalic = (pLogFont->lfItalic) ? ITALIC_NORMAL : ITALIC_NONE;
+ pData->mePitch = ImplLogPitchToSal( pLogFont->lfPitchAndFamily );
+ if ( pMetric->tmPitchAndFamily & (TMPF_VECTOR | TMPF_TRUETYPE) )
+ pData->meType = TYPE_SCALABLE;
+ else
+ pData->meType = TYPE_RASTER;
+ pData->mbOrientation = (nFontType & RASTER_FONTTYPE) == 0;
+ pData->mbDevice = (pMetric->tmPitchAndFamily & TMPF_DEVICE) != 0;
+ pData->mnQuality = 0;
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplLogMetricToDevFontDataW( const LOGFONTW* pLogFont,
+ const NEWTEXTMETRICW* pMetric,
+ DWORD nFontType,
+ ImplFontData* pData )
+{
+ if ( !(nFontType & RASTER_FONTTYPE) )
+ {
+ pData->mnWidth = 0;
+ pData->mnHeight = 0;
+ }
+ else
+ {
+ pData->mnWidth = 0;
+ pData->mnHeight = pMetric->tmHeight-pMetric->tmInternalLeading;
+ }
+ pData->meFamily = ImplFamilyToSal( pLogFont->lfPitchAndFamily );
+ pData->meCharSet = ImplCharSetToSal( pLogFont->lfCharSet );
+ pData->meWidthType = WIDTH_DONTKNOW;
+ pData->meWeight = ImplWeightToSal( pLogFont->lfWeight );
+ pData->meItalic = (pLogFont->lfItalic) ? ITALIC_NORMAL : ITALIC_NONE;
+ pData->mePitch = ImplLogPitchToSal( pLogFont->lfPitchAndFamily );
+ if ( pMetric->tmPitchAndFamily & (TMPF_VECTOR | TMPF_TRUETYPE) )
+ pData->meType = TYPE_SCALABLE;
+ else
+ pData->meType = TYPE_RASTER;
+ pData->mbOrientation = (nFontType & RASTER_FONTTYPE) == 0;
+ pData->mbDevice = (pMetric->tmPitchAndFamily & TMPF_DEVICE) != 0;
+ pData->mnQuality = 0;
+}
+
+// -----------------------------------------------------------------------
+
+void ImplSalLogFontToFontA( const LOGFONTA& rLogFont, Font& rFont )
+{
+ XubString aFontName( ImplSalGetUniString( rLogFont.lfFaceName ) );
+ if ( aFontName.Len() )
+ {
+ rFont.SetName( aFontName );
+ long nFontHeight = rLogFont.lfHeight;
+ if ( nFontHeight < 0 )
+ nFontHeight = -nFontHeight;
+ HDC hDC = GetDC( 0 );
+ long nDPIY = GetDeviceCaps( hDC, LOGPIXELSY );
+ ReleaseDC( 0, hDC );
+ nFontHeight *= 72;
+ nFontHeight += nDPIY/2;
+ nFontHeight /= nDPIY;
+ rFont.SetSize( Size( 0, nFontHeight ) );
+ rFont.SetOrientation( (short)rLogFont.lfEscapement );
+ rFont.SetCharSet( ImplCharSetToSal( rLogFont.lfCharSet ) );
+ rFont.SetFamily( ImplFamilyToSal( rLogFont.lfPitchAndFamily ) );
+ rFont.SetPitch( ImplLogPitchToSal( rLogFont.lfPitchAndFamily ) );
+ rFont.SetWeight( ImplWeightToSal( rLogFont.lfWeight ) );
+ if ( rLogFont.lfItalic )
+ rFont.SetItalic( ITALIC_NORMAL );
+ else
+ rFont.SetItalic( ITALIC_NONE );
+ if ( rLogFont.lfUnderline )
+ rFont.SetUnderline( UNDERLINE_SINGLE );
+ else
+ rFont.SetUnderline( UNDERLINE_NONE );
+ if ( rLogFont.lfStrikeOut )
+ rFont.SetStrikeout( STRIKEOUT_SINGLE );
+ else
+ rFont.SetStrikeout( STRIKEOUT_NONE );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void ImplSalLogFontToFontW( const LOGFONTW& rLogFont, Font& rFont )
+{
+ XubString aFontName( rLogFont.lfFaceName );
+ if ( aFontName.Len() )
+ {
+ rFont.SetName( aFontName );
+ long nFontHeight = rLogFont.lfHeight;
+ if ( nFontHeight < 0 )
+ nFontHeight = -nFontHeight;
+ HDC hDC = GetDC( 0 );
+ long nDPIY = GetDeviceCaps( hDC, LOGPIXELSY );
+ ReleaseDC( 0, hDC );
+ nFontHeight *= 72;
+ nFontHeight += nDPIY/2;
+ nFontHeight /= nDPIY;
+ rFont.SetSize( Size( 0, nFontHeight ) );
+ rFont.SetOrientation( (short)rLogFont.lfEscapement );
+ rFont.SetCharSet( ImplCharSetToSal( rLogFont.lfCharSet ) );
+ rFont.SetFamily( ImplFamilyToSal( rLogFont.lfPitchAndFamily ) );
+ rFont.SetPitch( ImplLogPitchToSal( rLogFont.lfPitchAndFamily ) );
+ rFont.SetWeight( ImplWeightToSal( rLogFont.lfWeight ) );
+ if ( rLogFont.lfItalic )
+ rFont.SetItalic( ITALIC_NORMAL );
+ else
+ rFont.SetItalic( ITALIC_NONE );
+ if ( rLogFont.lfUnderline )
+ rFont.SetUnderline( UNDERLINE_SINGLE );
+ else
+ rFont.SetUnderline( UNDERLINE_NONE );
+ if ( rLogFont.lfStrikeOut )
+ rFont.SetStrikeout( STRIKEOUT_SINGLE );
+ else
+ rFont.SetStrikeout( STRIKEOUT_NONE );
+ }
+}
+
+// =======================================================================
+
+void SalGraphics::SetTextColor( SalColor nSalColor )
+{
+ COLORREF aCol = PALETTERGB( SALCOLOR_RED( nSalColor ),
+ SALCOLOR_GREEN( nSalColor ),
+ SALCOLOR_BLUE( nSalColor ) );
+
+ if( !maGraphicsData.mbPrinter &&
+ GetSalData()->mhDitherPal &&
+ ImplIsSysColorEntry( nSalColor ) )
+ {
+ aCol = PALRGB_TO_RGB( aCol );
+ }
+
+ ::SetTextColor( maGraphicsData.mhDC, aCol );
+}
+
+// -----------------------------------------------------------------------
+
+USHORT SalGraphics::SetFont( ImplFontSelectData* pFont )
+{
+ HFONT hNewFont;
+ if ( aSalShlData.mbWNT )
+ {
+ LOGFONTW aLogFont;
+ UniString aName;
+ if ( pFont->mpFontData )
+ aName = pFont->mpFontData->maName;
+ else
+ aName = pFont->maName.GetToken( 0 );
+
+ UINT nNameLen = aName.Len();
+ if ( nNameLen > (sizeof( aLogFont.lfFaceName )/sizeof( wchar_t ))-1 )
+ nNameLen = (sizeof( aLogFont.lfFaceName )/sizeof( wchar_t ))-1;
+ memcpy( aLogFont.lfFaceName, aName.GetBuffer(), nNameLen*sizeof( wchar_t ) );
+ aLogFont.lfFaceName[nNameLen] = 0;
+ if ( pFont->mpFontData &&
+ ((pFont->meCharSet == RTL_TEXTENCODING_DONTKNOW) ||
+ ((WIN_BYTE)(pFont->mpFontData->mpSysData) == OEM_CHARSET)) )
+ aLogFont.lfCharSet = (WIN_BYTE)(pFont->mpFontData->mpSysData);
+ else
+ aLogFont.lfCharSet = ImplCharSetToWin( pFont->meCharSet );
+ aLogFont.lfPitchAndFamily = ImplPitchToWin( pFont->mePitch );
+ aLogFont.lfPitchAndFamily |= ImplFamilyToWin( pFont->meFamily );
+ aLogFont.lfWeight = ImplWeightToWin( pFont->meWeight );
+ aLogFont.lfHeight = (int)-pFont->mnHeight;
+ aLogFont.lfWidth = (int)pFont->mnWidth;
+ aLogFont.lfUnderline = 0;
+ aLogFont.lfStrikeOut = 0;
+ aLogFont.lfItalic = (pFont->meItalic) != ITALIC_NONE;
+ aLogFont.lfEscapement = pFont->mnOrientation;
+ aLogFont.lfOrientation = 0;
+ aLogFont.lfClipPrecision = CLIP_DEFAULT_PRECIS;
+ aLogFont.lfQuality = DEFAULT_QUALITY;
+ if ( pFont->mnOrientation )
+ {
+ aLogFont.lfOutPrecision = OUT_TT_PRECIS;
+ aLogFont.lfClipPrecision |= CLIP_LH_ANGLES;
+ }
+ else
+ aLogFont.lfOutPrecision = OUT_DEFAULT_PRECIS;
+
+ // Auf dem Bildschirm nehmen wir Courier New, wenn Courier nicht
+ // skalierbar ist und wenn der Font skaliert oder rotiert werden
+ // muss
+ if ( maGraphicsData.mbScreen &&
+ (pFont->mnWidth || pFont->mnOrientation ||
+ !pFont->mpFontData || (pFont->mpFontData->mnHeight != pFont->mnHeight)) &&
+ !bImplSalCourierScalable && bImplSalCourierNew &&
+ (ImplSalWICompareAscii( aLogFont.lfFaceName, "Courier" ) == 0) )
+ lstrcpyW( aLogFont.lfFaceName, L"Courier New" );
+
+ hNewFont = CreateFontIndirectW( &aLogFont );
+ }
+ else
+ {
+ if ( !maGraphicsData.mpLogFont )
+ maGraphicsData.mpLogFont = new LOGFONTA;
+
+ ByteString aName;
+ if ( pFont->mpFontData )
+ aName = ImplSalGetWinAnsiString( pFont->mpFontData->maName );
+ else
+ aName = ImplSalGetWinAnsiString( pFont->maName.GetToken( 0 ) );
+ UINT nNameLen = aName.Len();
+ if ( nNameLen > sizeof( maGraphicsData.mpLogFont->lfFaceName )-1 )
+ nNameLen = sizeof( maGraphicsData.mpLogFont->lfFaceName )-1;
+ memcpy( maGraphicsData.mpLogFont->lfFaceName, aName.GetBuffer(), nNameLen );
+ maGraphicsData.mpLogFont->lfFaceName[nNameLen] = 0;
+ if ( pFont->mpFontData &&
+ ((pFont->meCharSet == RTL_TEXTENCODING_DONTKNOW) ||
+ ((WIN_BYTE)(pFont->mpFontData->mpSysData) == OEM_CHARSET)) )
+ maGraphicsData.mpLogFont->lfCharSet = (WIN_BYTE)(pFont->mpFontData->mpSysData);
+ else
+ maGraphicsData.mpLogFont->lfCharSet = ImplCharSetToWin( pFont->meCharSet );
+ maGraphicsData.mpLogFont->lfPitchAndFamily = ImplPitchToWin( pFont->mePitch );
+ maGraphicsData.mpLogFont->lfPitchAndFamily |= ImplFamilyToWin( pFont->meFamily );
+ maGraphicsData.mpLogFont->lfWeight = ImplWeightToWin( pFont->meWeight );
+ maGraphicsData.mpLogFont->lfHeight = (int)-pFont->mnHeight;
+ maGraphicsData.mpLogFont->lfWidth = (int)pFont->mnWidth;
+ maGraphicsData.mpLogFont->lfUnderline = 0;
+ maGraphicsData.mpLogFont->lfStrikeOut = 0;
+ maGraphicsData.mpLogFont->lfItalic = (pFont->meItalic) != ITALIC_NONE;
+ maGraphicsData.mpLogFont->lfEscapement = pFont->mnOrientation;
+ maGraphicsData.mpLogFont->lfOrientation = 0;
+ maGraphicsData.mpLogFont->lfClipPrecision = CLIP_DEFAULT_PRECIS;
+ maGraphicsData.mpLogFont->lfQuality = DEFAULT_QUALITY;
+ if ( pFont->mnOrientation )
+ {
+ maGraphicsData.mpLogFont->lfOutPrecision = OUT_TT_PRECIS;
+ maGraphicsData.mpLogFont->lfClipPrecision |= CLIP_LH_ANGLES;
+ }
+ else
+ maGraphicsData.mpLogFont->lfOutPrecision = OUT_DEFAULT_PRECIS;
+
+ // Auf dem Bildschirm nehmen wir Courier New, wenn Courier nicht
+ // skalierbar ist und wenn der Font skaliert oder rotiert werden
+ // muss
+ if ( maGraphicsData.mbScreen &&
+ (pFont->mnWidth || pFont->mnOrientation ||
+ !pFont->mpFontData || (pFont->mpFontData->mnHeight != pFont->mnHeight)) &&
+ !bImplSalCourierScalable && bImplSalCourierNew &&
+ (stricmp( maGraphicsData.mpLogFont->lfFaceName, "Courier" ) == 0) )
+ strcpy( maGraphicsData.mpLogFont->lfFaceName, "Courier New" );
+
+ hNewFont = CreateFontIndirectA( maGraphicsData.mpLogFont );
+ }
+
+ HFONT hOldFont = SelectFont( maGraphicsData.mhDC, hNewFont );
+
+ // destory or save old font
+ if ( maGraphicsData.mhFont )
+ DeleteFont( maGraphicsData.mhFont );
+ else
+ maGraphicsData.mhDefFont = hOldFont;
+
+ // set new data
+ maGraphicsData.mhFont = hNewFont;
+ maGraphicsData.mbCalcOverhang = TRUE;
+
+ maGraphicsData.mnFontCharSetCount = 0;
+ maGraphicsData.mbFontKernInit = TRUE;
+ if ( maGraphicsData.mpFontKernPairs )
+ {
+ delete maGraphicsData.mpFontKernPairs;
+ maGraphicsData.mpFontKernPairs = 0;
+ }
+ maGraphicsData.mnFontKernPairCount = 0;
+
+ // Auf dem Printer immer mit DrawTextArray arbeiten, da dort die
+ // Zeichenbreiten genauer als Pixel sein koennen
+ if ( maGraphicsData.mbPrinter )
+ return SAL_SETFONT_USEDRAWTEXTARRAY;
+ else
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+long SalGraphics::GetCharWidth( sal_Unicode nChar1, sal_Unicode nChar2, long* pWidthAry )
+{
+ SIZE aExtent;
+ SIZE aExtent2;
+ sal_Unicode nCharCount = nChar2-nChar1+1;
+ sal_Unicode i;
+ int* pWinWidthAry = (int*)pWidthAry;
+ DBG_ASSERT( sizeof( int ) == sizeof( long ), "SalGraphics::GetCharWidth(): int != long" );
+
+ // Da nicht bei allen Treibern diese Funktion funktioniert
+ if ( !GetCharWidthW( maGraphicsData.mhDC, nChar1, nChar2, pWinWidthAry ) )
+ {
+ for ( i = 0; i < nCharCount; i++ )
+ {
+ WCHAR c =i+nChar1;
+ if ( !GetTextExtentPointW( maGraphicsData.mhDC, &c, 1, &aExtent ) )
+ pWinWidthAry[i] = 0;
+ else
+ pWinWidthAry[i] = aExtent.cx;
+ }
+ }
+
+ // Ueberhang abziehen
+ if ( maGraphicsData.mbCalcOverhang )
+ {
+ WCHAR aAA[2] = { 'A', 'A' };
+ if ( GetTextExtentPointW( maGraphicsData.mhDC, aAA, 2, &aExtent ) &&
+ GetTextExtentPointW( maGraphicsData.mhDC, aAA, 1, &aExtent2 ) )
+ {
+ maGraphicsData.mbCalcOverhang = FALSE;
+ maGraphicsData.mnFontOverhang = (aExtent2.cx*2)-aExtent.cx;
+ }
+
+ int nOverhang = maGraphicsData.mnFontOverhang;
+ if ( nOverhang )
+ {
+ for ( i = 0; i < nCharCount; i++ )
+ pWinWidthAry[i] -= nOverhang;
+ }
+ }
+
+ return 1;
+}
+
+// -----------------------------------------------------------------------
+
+void SalGraphics::GetFontMetric( ImplFontMetricData* pMetric )
+{
+ if ( aSalShlData.mbWNT )
+ {
+ wchar_t aFaceName[LF_FACESIZE+60];
+ GetTextFaceW( maGraphicsData.mhDC, sizeof( aFaceName ), aFaceName );
+ pMetric->maName = aFaceName;
+
+ TEXTMETRICW aWinMetric;
+ GetTextMetricsW( maGraphicsData.mhDC, &aWinMetric );
+
+ pMetric->mnWidth = aWinMetric.tmAveCharWidth;
+ pMetric->meFamily = ImplFamilyToSal( aWinMetric.tmPitchAndFamily );;
+ pMetric->meCharSet = ImplCharSetToSal( aWinMetric.tmCharSet );
+ pMetric->meWeight = ImplWeightToSal( aWinMetric.tmWeight );
+ pMetric->mePitch = ImplMetricPitchToSal( aWinMetric.tmPitchAndFamily );
+ if ( aWinMetric.tmItalic )
+ pMetric->meItalic = ITALIC_NORMAL;
+ else
+ pMetric->meItalic = ITALIC_NONE;
+ if ( aWinMetric.tmPitchAndFamily & (TMPF_VECTOR | TMPF_TRUETYPE) )
+ pMetric->meType = TYPE_SCALABLE;
+ else
+ {
+ pMetric->meType = TYPE_RASTER;
+ pMetric->mnOrientation = 0;
+ }
+ pMetric->mbDevice = (aWinMetric.tmPitchAndFamily & TMPF_DEVICE) != 0;
+ pMetric->mnAscent = aWinMetric.tmAscent;
+ pMetric->mnDescent = aWinMetric.tmDescent;
+ pMetric->mnLeading = aWinMetric.tmInternalLeading;
+ pMetric->mnSlant = 0;
+ pMetric->mnFirstChar = 0;
+ pMetric->mnLastChar = 0xFF;
+ }
+ else
+ {
+ char aFaceName[LF_FACESIZE+60];
+ GetTextFaceA( maGraphicsData.mhDC, sizeof( aFaceName ), aFaceName );
+ pMetric->maName = ImplSalGetUniString( aFaceName );
+
+ TEXTMETRICA aWinMetric;
+ GetTextMetricsA( maGraphicsData.mhDC, &aWinMetric );
+
+ pMetric->mnWidth = aWinMetric.tmAveCharWidth;
+ pMetric->meFamily = ImplFamilyToSal( aWinMetric.tmPitchAndFamily );;
+ pMetric->meCharSet = ImplCharSetToSal( aWinMetric.tmCharSet );
+ pMetric->meWeight = ImplWeightToSal( aWinMetric.tmWeight );
+ pMetric->mePitch = ImplMetricPitchToSal( aWinMetric.tmPitchAndFamily );
+ if ( aWinMetric.tmItalic )
+ pMetric->meItalic = ITALIC_NORMAL;
+ else
+ pMetric->meItalic = ITALIC_NONE;
+ if ( aWinMetric.tmPitchAndFamily & (TMPF_VECTOR | TMPF_TRUETYPE) )
+ pMetric->meType = TYPE_SCALABLE;
+ else
+ {
+ pMetric->meType = TYPE_RASTER;
+ pMetric->mnOrientation = 0;
+ }
+ pMetric->mbDevice = (aWinMetric.tmPitchAndFamily & TMPF_DEVICE) != 0;
+ pMetric->mnAscent = aWinMetric.tmAscent;
+ pMetric->mnDescent = aWinMetric.tmDescent;
+ pMetric->mnLeading = aWinMetric.tmInternalLeading;
+ pMetric->mnSlant = 0;
+ pMetric->mnFirstChar = 0;
+ pMetric->mnLastChar = 0xFF;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+int CALLBACK SalEnumCharSetsProcExA( const ENUMLOGFONTEXA* pLogFont,
+ const NEWTEXTMETRICEXA* pMetric,
+ DWORD nFontType, LPARAM lParam )
+{
+ SalGraphicsData* pData = (SalGraphicsData*)lParam;
+ // Charset already in the list?
+ for ( BYTE i = 0; i < pData->mnFontCharSetCount; i++ )
+ {
+ if ( pData->mpFontCharSets[i] == pLogFont->elfLogFont.lfCharSet )
+ return 1;
+ }
+ pData->mpFontCharSets[pData->mnFontCharSetCount] = pLogFont->elfLogFont.lfCharSet;
+ pData->mnFontCharSetCount++;
+ return 1;
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplGetAllFontCharSets( SalGraphicsData* pData )
+{
+ if ( !pData->mpFontCharSets )
+ pData->mpFontCharSets = new BYTE[256];
+
+ LOGFONTA aLogFont;
+ memset( &aLogFont, 0, sizeof( aLogFont ) );
+ aLogFont.lfCharSet = DEFAULT_CHARSET;
+ GetTextFace( pData->mhDC, sizeof( aLogFont.lfFaceName ), aLogFont.lfFaceName );
+ EnumFontFamiliesExA( pData->mhDC, &aLogFont, (FONTENUMPROCA)SalEnumCharSetsProcExA,
+ (LPARAM)(void*)pData, 0 );
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplAddKerningPairs( SalGraphicsData* pData )
+{
+ ULONG nPairs = ::GetKerningPairsA( pData->mhDC, 0, NULL );
+ if ( !nPairs )
+ return;
+
+ CHARSETINFO aInfo;
+ if ( !TranslateCharsetInfo( (DWORD*)(ULONG)GetTextCharset( pData->mhDC ), &aInfo, TCI_SRCCHARSET ) )
+ return;
+
+ if ( !pData->mpFontKernPairs )
+ pData->mpFontKernPairs = new KERNINGPAIR[nPairs];
+ else
+ {
+ KERNINGPAIR* pOldPairs = pData->mpFontKernPairs;
+ pData->mpFontKernPairs = new KERNINGPAIR[nPairs+pData->mnFontKernPairCount];
+ memcpy( pData->mpFontKernPairs, pOldPairs,
+ pData->mnFontKernPairCount*sizeof( KERNINGPAIR ) );
+ delete pOldPairs;
+ }
+
+ UINT nCP = aInfo.ciACP;
+ ULONG nOldPairs = pData->mnFontKernPairCount;
+ KERNINGPAIR* pTempPair = pData->mpFontKernPairs+pData->mnFontKernPairCount;
+ nPairs = ::GetKerningPairsA( pData->mhDC, nPairs, pTempPair );
+ for ( ULONG i = 0; i < nPairs; i++ )
+ {
+ unsigned char aBuf[2];
+ wchar_t nChar;
+ int nLen;
+ BOOL bAdd = TRUE;
+
+ // None-ASCII?, then we must convert the char
+ if ( (pTempPair->wFirst > 125) || (pTempPair->wFirst == 92) )
+ {
+ if ( pTempPair->wFirst < 256 )
+ {
+ aBuf[0] = (unsigned char)pTempPair->wFirst;
+ nLen = 1;
+ }
+ else
+ {
+ aBuf[0] = (unsigned char)(pTempPair->wFirst >> 8);
+ aBuf[1] = (unsigned char)(pTempPair->wFirst & 0xFF);
+ nLen = 2;
+ }
+ if ( MultiByteToWideChar( nCP, MB_PRECOMPOSED | MB_USEGLYPHCHARS,
+ (const char*)aBuf, nLen, &nChar, 1 ) )
+ pTempPair->wFirst = nChar;
+ else
+ bAdd = FALSE;
+ }
+ if ( (pTempPair->wSecond > 125) || (pTempPair->wSecond == 92) )
+ {
+ if ( pTempPair->wSecond < 256 )
+ {
+ aBuf[0] = (unsigned char)pTempPair->wSecond;
+ nLen = 1;
+ }
+ else
+ {
+ aBuf[0] = (unsigned char)(pTempPair->wSecond >> 8);
+ aBuf[1] = (unsigned char)(pTempPair->wSecond & 0xFF);
+ nLen = 2;
+ }
+ if ( MultiByteToWideChar( nCP, MB_PRECOMPOSED | MB_USEGLYPHCHARS,
+ (const char*)aBuf, nLen, &nChar, 1 ) )
+ pTempPair->wSecond = nChar;
+ else
+ bAdd = FALSE;
+ }
+
+ KERNINGPAIR* pTempPair2 = pData->mpFontKernPairs;
+ for ( ULONG j = 0; j < nOldPairs; j++ )
+ {
+ if ( (pTempPair2->wFirst == pTempPair->wFirst) &&
+ (pTempPair2->wSecond == pTempPair->wSecond) )
+ {
+ bAdd = FALSE;
+ break;
+ }
+ pTempPair2++;
+ }
+
+ if ( bAdd )
+ {
+ KERNINGPAIR* pDestPair = pData->mpFontKernPairs+pData->mnFontKernPairCount;
+ if ( pDestPair != pTempPair )
+ memcpy( pDestPair, pTempPair, sizeof( KERNINGPAIR ) );
+ pData->mnFontKernPairCount++;
+ }
+
+ pTempPair++;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+ULONG SalGraphics::GetKernPairs( ULONG nPairs, ImplKernPairData* pKernPairs )
+{
+ DBG_ASSERT( sizeof( KERNINGPAIR ) == sizeof( ImplKernPairData ),
+ "SalGraphics::GetKernPairs(): KERNINGPAIR != ImplKernPairData" );
+
+ if ( aSalShlData.mbWNT )
+ {
+ if ( !pKernPairs )
+ return ::GetKerningPairsW( maGraphicsData.mhDC, 0, NULL );
+ else
+ return ::GetKerningPairsW( maGraphicsData.mhDC, nPairs, (KERNINGPAIR*)pKernPairs );
+ }
+ else
+ {
+ if ( maGraphicsData.mbFontKernInit )
+ {
+ if ( maGraphicsData.mpFontKernPairs )
+ {
+ delete maGraphicsData.mpFontKernPairs;
+ maGraphicsData.mpFontKernPairs = 0;
+ }
+ maGraphicsData.mnFontKernPairCount = 0;
+
+ if ( !maGraphicsData.mnFontCharSetCount )
+ ImplGetAllFontCharSets( &maGraphicsData );
+
+ if ( maGraphicsData.mnFontCharSetCount <= 1 )
+ ImplAddKerningPairs( &maGraphicsData );
+ else
+ {
+ // Query All Kerning Pairs from all possible CharSets
+ for ( BYTE i = 0; i < maGraphicsData.mnFontCharSetCount; i++ )
+ {
+ maGraphicsData.mpLogFont->lfCharSet = maGraphicsData.mpFontCharSets[i];
+ HFONT hNewFont = CreateFontIndirectA( maGraphicsData.mpLogFont );
+ HFONT hOldFont = SelectFont( maGraphicsData.mhDC, hNewFont );
+ ImplAddKerningPairs( &maGraphicsData );
+ SelectFont( maGraphicsData.mhDC, hOldFont );
+ DeleteFont( hNewFont );
+ }
+ }
+
+ maGraphicsData.mbFontKernInit = FALSE;
+ }
+
+ if ( !pKernPairs )
+ return maGraphicsData.mnFontKernPairCount;
+ else
+ {
+ if ( nPairs > maGraphicsData.mnFontKernPairCount )
+ nPairs = maGraphicsData.mnFontKernPairCount;
+ memcpy( pKernPairs, maGraphicsData.mpFontKernPairs,
+ nPairs*sizeof( ImplKernPairData ) );
+ return nPairs;
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+int CALLBACK SalEnumFontsProcExA( const ENUMLOGFONTEXA* pLogFont,
+ const NEWTEXTMETRICEXA* pMetric,
+ DWORD nFontType, LPARAM lParam )
+{
+ ImplEnumInfo* pInfo = (ImplEnumInfo*)(void*)lParam;
+ if ( !pInfo->mpName )
+ {
+ // Ignore vertical fonts
+ if ( pLogFont->elfLogFont.lfFaceName[0] != '@' )
+ {
+ if ( !pInfo->mbImplSalCourierNew )
+ pInfo->mbImplSalCourierNew = stricmp( pLogFont->elfLogFont.lfFaceName, "Courier New" ) == 0;
+ if ( !pInfo->mbImplSalCourierScalable )
+ pInfo->mbCourier = stricmp( pLogFont->elfLogFont.lfFaceName, "Courier" ) == 0;
+ else
+ pInfo->mbCourier = FALSE;
+ XubString aName( ImplSalGetUniString( pLogFont->elfLogFont.lfFaceName ) );
+ pInfo->mpName = &aName;
+ strcpy( pInfo->mpLogFontA->lfFaceName, pLogFont->elfLogFont.lfFaceName );
+ pInfo->mpLogFontA->lfCharSet = pLogFont->elfLogFont.lfCharSet;
+ EnumFontFamiliesExA( pInfo->mhDC, pInfo->mpLogFontA, (FONTENUMPROCA)SalEnumFontsProcExA,
+ (LPARAM)(void*)pInfo, 0 );
+ pInfo->mpLogFontA->lfFaceName[0] = '\0';
+ pInfo->mpLogFontA->lfCharSet = DEFAULT_CHARSET;
+ pInfo->mpName = NULL;
+ pInfo->mbCourier = FALSE;
+ }
+ }
+ else
+ {
+ ImplFontData* pData = new ImplFontData;
+ pData->maName = *(pInfo->mpName);
+
+ ImplLogMetricToDevFontDataA( &(pLogFont->elfLogFont), &(pMetric->ntmTm), nFontType, pData );
+ // StyleName nur bei TrueType uebernehmen, da sonst bei 3.1 Mist drinsteht
+ if ( pMetric->ntmTm.tmPitchAndFamily & TMPF_TRUETYPE )
+ pData->maStyleName = ImplSalGetUniString( (const char*)pLogFont->elfStyle );
+ pData->mpSysData = (void*)(pLogFont->elfLogFont.lfCharSet);
+ BOOL bAdd = TRUE;
+
+ // Wenn es sich um einen nicht skalierbaren Bildschirm-Font
+ // handelt, dann auf dem Drucker ignorieren
+ if ( pData->meType != TYPE_SCALABLE )
+ {
+ if ( pInfo->mbPrinter )
+ bAdd = pData->mbDevice;
+ }
+ else
+ {
+ // Feststellen, ob Courier skalierbar ist
+ if ( pInfo->mbCourier )
+ pInfo->mbImplSalCourierScalable = TRUE;
+ }
+
+ if ( bAdd )
+ pInfo->mpList->Add( pData );
+ else
+ delete pData;
+ }
+
+ return 1;
+}
+
+// -----------------------------------------------------------------------
+
+int CALLBACK SalEnumFontsProcExW( const ENUMLOGFONTEXW* pLogFont,
+ const NEWTEXTMETRICEXW* pMetric,
+ DWORD nFontType, LPARAM lParam )
+{
+ ImplEnumInfo* pInfo = (ImplEnumInfo*)(void*)lParam;
+ if ( !pInfo->mpName )
+ {
+ // Ignore vertical fonts
+ if ( pLogFont->elfLogFont.lfFaceName[0] != '@' )
+ {
+ if ( !pInfo->mbImplSalCourierNew )
+ pInfo->mbImplSalCourierNew = ImplSalWICompareAscii( pLogFont->elfLogFont.lfFaceName, "Courier New" ) == 0;
+ if ( !pInfo->mbImplSalCourierScalable )
+ pInfo->mbCourier = ImplSalWICompareAscii( pLogFont->elfLogFont.lfFaceName, "Courier" ) == 0;
+ else
+ pInfo->mbCourier = FALSE;
+ XubString aName( pLogFont->elfLogFont.lfFaceName );
+ pInfo->mpName = &aName;
+ memcpy( pInfo->mpLogFontW->lfFaceName, pLogFont->elfLogFont.lfFaceName, (aName.Len()+1)*sizeof( wchar_t ) );
+ pInfo->mpLogFontW->lfCharSet = pLogFont->elfLogFont.lfCharSet;
+ EnumFontFamiliesExW( pInfo->mhDC, pInfo->mpLogFontW, (FONTENUMPROCW)SalEnumFontsProcExW,
+ (LPARAM)(void*)pInfo, 0 );
+ pInfo->mpLogFontW->lfFaceName[0] = '\0';
+ pInfo->mpLogFontW->lfCharSet = DEFAULT_CHARSET;
+ pInfo->mpName = NULL;
+ pInfo->mbCourier = FALSE;
+ }
+ }
+ else
+ {
+ ImplFontData* pData = new ImplFontData;
+ pData->maName = *(pInfo->mpName);
+
+ ImplLogMetricToDevFontDataW( &(pLogFont->elfLogFont), &(pMetric->ntmTm), nFontType, pData );
+ // StyleName nur bei TrueType uebernehmen, da sonst bei 3.1 Mist drinsteht
+ if ( pMetric->ntmTm.tmPitchAndFamily & TMPF_TRUETYPE )
+ pData->maStyleName = pLogFont->elfStyle;
+ pData->mpSysData = (void*)(pLogFont->elfLogFont.lfCharSet);
+ BOOL bAdd = TRUE;
+
+ // Wenn es sich um einen nicht skalierbaren Bildschirm-Font
+ // handelt, dann auf dem Drucker ignorieren
+ if ( pData->meType != TYPE_SCALABLE )
+ {
+ if ( pInfo->mbPrinter )
+ bAdd = pData->mbDevice;
+ }
+ else
+ {
+ // Feststellen, ob Courier skalierbar ist
+ if ( pInfo->mbCourier )
+ pInfo->mbImplSalCourierScalable = TRUE;
+ }
+
+ if ( bAdd )
+ pInfo->mpList->Add( pData );
+ else
+ delete pData;
+ }
+
+ return 1;
+}
+
+// -----------------------------------------------------------------------
+
+void SalGraphics::GetDevFontList( ImplDevFontList* pList )
+{
+ ImplEnumInfo aInfo;
+ aInfo.mhDC = maGraphicsData.mhDC;
+ aInfo.mpList = pList;
+ aInfo.mpName = NULL;
+ aInfo.mpLogFontA = NULL;
+ aInfo.mpLogFontW = NULL;
+ aInfo.mbCourier = FALSE;
+ if ( !maGraphicsData.mbPrinter )
+ {
+ aInfo.mbImplSalCourierScalable = FALSE;
+ aInfo.mbImplSalCourierNew = FALSE;
+ aInfo.mbPrinter = FALSE;
+ }
+ else
+ {
+ aInfo.mbImplSalCourierScalable = TRUE;
+ aInfo.mbImplSalCourierNew = TRUE;
+ aInfo.mbPrinter = TRUE;
+ }
+
+ if ( aSalShlData.mbWNT )
+ {
+ LOGFONTW aLogFont;
+ memset( &aLogFont, 0, sizeof( aLogFont ) );
+ aLogFont.lfCharSet = DEFAULT_CHARSET;
+ aInfo.mpLogFontW = &aLogFont;
+ EnumFontFamiliesExW( maGraphicsData.mhDC, &aLogFont, (FONTENUMPROCW)SalEnumFontsProcExW,
+ (LPARAM)(void*)&aInfo, 0 );
+ }
+ else
+ {
+ LOGFONTA aLogFont;
+ memset( &aLogFont, 0, sizeof( aLogFont ) );
+ aLogFont.lfCharSet = DEFAULT_CHARSET;
+ aInfo.mpLogFontA = &aLogFont;
+ EnumFontFamiliesExA( maGraphicsData.mhDC, &aLogFont, (FONTENUMPROCA)SalEnumFontsProcExA,
+ (LPARAM)(void*)&aInfo, 0 );
+ }
+
+ // Feststellen, was es fuer Courier-Schriften auf dem Bildschirm gibt,
+ // um in SetFont() evt. Courier auf Courier New zu mappen
+ if ( !maGraphicsData.mbPrinter )
+ {
+ bImplSalCourierScalable = aInfo.mbImplSalCourierScalable;
+ bImplSalCourierNew = aInfo.mbImplSalCourierNew;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void SalGraphics::DrawText( long nX, long nY,
+ const xub_Unicode* pStr, xub_StrLen nLen )
+{
+ DBG_ASSERT( sizeof( WCHAR ) == sizeof( xub_Unicode ), "SalGraphics::DrawText(): WCHAR != sal_Unicode" );
+
+ ::ExtTextOutW( maGraphicsData.mhDC, (int)nX, (int)nY,
+ 0, NULL, pStr, nLen, NULL );
+}
+
+// -----------------------------------------------------------------------
+
+void SalGraphics::DrawTextArray( long nX, long nY,
+ const xub_Unicode* pStr, xub_StrLen nLen,
+ const long* pDXAry )
+{
+ DBG_ASSERT( sizeof( WCHAR ) == sizeof( xub_Unicode ), "SalGraphics::DrawText(): WCHAR != sal_Unicode" );
+
+ if ( nLen < 2 )
+ ::ExtTextOutW( maGraphicsData.mhDC, (int)nX, (int)nY, 0, NULL, pStr, nLen, NULL );
+ else
+ {
+ int aStackAry[SAL_DRAWTEXT_STACKBUF];
+ int* pWinDXAry;
+
+ if ( nLen <= SAL_DRAWTEXT_STACKBUF )
+ pWinDXAry = aStackAry;
+ else
+ pWinDXAry = new int[nLen];
+
+ pWinDXAry[0] = (int)pDXAry[0];
+ for ( xub_StrLen i = 1; i < nLen-1; i++ )
+ pWinDXAry[i] = (int)pDXAry[i]-pDXAry[i-1];
+
+ // Breite vom letzten Zeichen ermitteln, da wir dieses auch
+ // beim Windows-XArray in der richtigen Breite reingeben
+ // muessen, um nicht auf Probleme bei einigen
+ // Grafikkarten oder Druckertreibern zu stossen
+ SIZE aExtent;
+ if ( GetTextExtentPointW( maGraphicsData.mhDC, pStr+nLen-1, 1, &aExtent ) )
+ pWinDXAry[nLen-1] = aExtent.cx;
+ else
+ pWinDXAry[nLen-1] = 4095;
+
+ // Text ausgeben
+ ::ExtTextOutW( maGraphicsData.mhDC, (int)nX, (int)nY, 0, NULL, pStr, nLen, pWinDXAry );
+
+ if ( pWinDXAry != aStackAry )
+ delete pWinDXAry;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+static ULONG ImplIncreaseArrays( ULONG nSize, SalPoint** ppPoints, BYTE** ppFlags, ULONG nIncSize )
+{
+ const ULONG nOldSize = nSize;
+ SalPoint* pNewPoints = new SalPoint[ nSize += nIncSize ];
+ BYTE* pNewFlags = new BYTE[ nSize ];
+
+ if( *ppPoints )
+ {
+ memcpy( pNewPoints, *ppPoints, nOldSize * sizeof( SalPoint ) );
+ memset( pNewPoints + nOldSize, 0, nIncSize * sizeof( SalPoint ) );
+ delete[] *ppPoints;
+ }
+ else
+ memset( pNewPoints, 0, nSize * sizeof( SalPoint ) );
+
+ if( *ppFlags )
+ {
+ memcpy( pNewFlags, *ppFlags, nOldSize );
+ memset( pNewFlags + nOldSize, 0, nIncSize );
+ delete[] *ppFlags;
+ }
+ else
+ memset( pNewFlags, 0, nSize );
+
+ *ppPoints = pNewPoints;
+ *ppFlags = pNewFlags;
+
+ return nSize;
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplGetFamilyAndAscents( HDC hDC, BYTE& rPitch, long& rAscent )
+{
+ rPitch = 0;
+ rAscent = 0;
+
+ if ( aSalShlData.mbWNT )
+ {
+ TEXTMETRICW aTextMetricW;
+ if ( GetTextMetricsW( hDC, &aTextMetricW ) )
+ {
+ rPitch = aTextMetricW.tmPitchAndFamily;
+ rAscent = aTextMetricW.tmAscent;
+ }
+ }
+ else
+ {
+ TEXTMETRICA aTextMetricA;
+ if ( GetTextMetricsA( hDC, &aTextMetricA ) )
+ {
+ rPitch = aTextMetricA.tmPitchAndFamily;
+ rAscent = aTextMetricA.tmAscent;
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+static BOOL ImplGetGlyphChar( SalGraphicsData* pData, sal_Unicode c,
+ WORD& rByteChar, HFONT& rOldFont )
+{
+ rOldFont = 0;
+
+ if ( !pData->mnFontCharSetCount )
+ ImplGetAllFontCharSets( pData );
+
+ // Try at first the current charset
+ CHARSETINFO aInfo;
+ char aDestBuf[2];
+ int nLen = 0;
+ WIN_BOOL bDefault;
+ if ( TranslateCharsetInfo( (DWORD*)(ULONG)GetTextCharset( pData->mhDC ), &aInfo, TCI_SRCCHARSET ) )
+ {
+ bDefault = FALSE;
+ nLen = WideCharToMultiByte( aInfo.ciACP,
+ WC_COMPOSITECHECK | WC_DISCARDNS | WC_DEFAULTCHAR,
+ &c, 1,
+ aDestBuf, sizeof( aDestBuf ),
+ NULL, &bDefault );
+ }
+
+ // Try all possible charsets
+ if ( (nLen != 1) || bDefault )
+ {
+ // Query All Kerning Pairs from all possible CharSets
+ for ( BYTE i = 0; i < pData->mnFontCharSetCount; i++ )
+ {
+ if ( TranslateCharsetInfo( (DWORD*)(ULONG)pData->mpFontCharSets[i], &aInfo, TCI_SRCCHARSET ) )
+ {
+ bDefault = FALSE;
+ nLen = WideCharToMultiByte( aInfo.ciACP,
+ WC_COMPOSITECHECK | WC_DISCARDNS | WC_DEFAULTCHAR,
+ &c, 1,
+ aDestBuf, sizeof( aDestBuf ),
+ NULL, &bDefault );
+ if ( (nLen == 1) && !bDefault )
+ {
+ pData->mpLogFont->lfCharSet = pData->mpFontCharSets[i];
+ HFONT hNewFont = CreateFontIndirectA( pData->mpLogFont );
+ rOldFont = SelectFont( pData->mhDC, hNewFont );
+ break;
+ }
+ }
+ }
+ }
+
+ // GetGlyphOutline() only works for characters < 256. For all characters
+ // greater than 256 we use the default mechanismn in VCL to scan
+ // the printed Glyph
+ if ( (nLen == 1) && !bDefault )
+ {
+ rByteChar = (unsigned char)aDestBuf[0];
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL SalGraphics::GetGlyphBoundRect( xub_Unicode cChar, long* pX, long* pY,
+ long* pWidth, long* pHeight )
+{
+ HDC hDC = maGraphicsData.mhDC;
+ BYTE nPitchAndFamily;
+ long nAscent;
+
+ ImplGetFamilyAndAscents( hDC, nPitchAndFamily, nAscent );
+ if ( !(nPitchAndFamily & TMPF_TRUETYPE) )
+ return FALSE;
+
+ GLYPHMETRICS aGlyphMetrics;
+ MAT2 aMat;
+ DWORD nSize;
+ BOOL bOK;
+ HFONT hOldFont = 0;
+
+ // Einheitsmatrix erzeugen
+ aMat.eM11 = FixedFromDouble(1.);
+ aMat.eM12 = FixedFromDouble(0.);
+ aMat.eM21 = FixedFromDouble(0.);
+ aMat.eM22 = FixedFromDouble(1.);
+ if ( aSalShlData.mbWNT )
+ nSize = ::GetGlyphOutlineW( hDC, cChar, GGO_METRICS, &aGlyphMetrics, 0, NULL, &aMat );
+ else
+ {
+ WORD nChar;
+ if ( ImplGetGlyphChar( &maGraphicsData, cChar, nChar, hOldFont ) )
+ nSize = ::GetGlyphOutlineA( hDC, nChar, GGO_METRICS, &aGlyphMetrics, 0, NULL, &aMat );
+ else
+ nSize = 0;
+ }
+ bOK = (nSize != GDI_ERROR) && nSize;
+ if ( bOK )
+ {
+ *pX = aGlyphMetrics.gmptGlyphOrigin.x;
+ *pY = nAscent - aGlyphMetrics.gmptGlyphOrigin.y;
+ *pWidth = aGlyphMetrics.gmBlackBoxX;
+ *pHeight = aGlyphMetrics.gmBlackBoxY;
+ }
+
+ if ( hOldFont )
+ {
+ HFONT hNewFont = SelectFont( maGraphicsData.mhDC, hOldFont );
+ DeleteFont( hNewFont );
+ }
+
+ return bOK;
+}
+
+// -----------------------------------------------------------------------
+
+ULONG SalGraphics::GetGlyphOutline( xub_Unicode cChar, USHORT** ppPolySizes,
+ SalPoint** ppPoints, BYTE** ppFlags )
+{
+ HDC hDC = maGraphicsData.mhDC;
+ BYTE nPitchAndFamily;
+ long nAscent;
+
+ ImplGetFamilyAndAscents( hDC, nPitchAndFamily, nAscent );
+ if ( !(nPitchAndFamily & TMPF_TRUETYPE) )
+ return 0;
+
+ GLYPHMETRICS aGlyphMetrics;
+ MAT2 aMat;
+ DWORD nSize;
+ USHORT nChar = cChar;
+ HFONT hOldFont = 0;
+ ULONG nPolyCount = 0;
+
+ // Einheitsmatrix erzeugen
+ aMat.eM11 = FixedFromDouble(1.);
+ aMat.eM12 = FixedFromDouble(0.);
+ aMat.eM21 = FixedFromDouble(0.);
+ aMat.eM22 = FixedFromDouble(1.);
+
+ if ( aSalShlData.mbWNT )
+ nSize = ::GetGlyphOutlineW( hDC, nChar, GGO_NATIVE, &aGlyphMetrics, 0, NULL, &aMat );
+ else
+ {
+ if ( ImplGetGlyphChar( &maGraphicsData, cChar, nChar, hOldFont ) )
+ nSize = ::GetGlyphOutlineA( hDC, nChar, GGO_NATIVE, &aGlyphMetrics, 0, NULL, &aMat );
+ else
+ nSize = 0;
+ }
+
+ if ( (nSize != GDI_ERROR) && nSize )
+ {
+ BYTE* pData = new BYTE[ nSize ];
+ ULONG nTotalCount = 0;
+ DWORD nSize2;
+ if ( aSalShlData.mbWNT )
+ nSize2 = ::GetGlyphOutlineW( hDC, nChar, GGO_NATIVE, &aGlyphMetrics, nSize, pData, &aMat );
+ else
+ nSize2 = ::GetGlyphOutlineA( hDC, nChar, GGO_NATIVE, &aGlyphMetrics, nSize, pData, &aMat );
+ if ( nSize == nSize2 )
+ {
+ ULONG nPtSize = GLYPH_INC;
+ SalPoint* pPoints = new SalPoint[ GLYPH_INC ];
+ SalPoint* pTotalPoints = NULL;
+ BYTE* pFlags = new BYTE[ GLYPH_INC ];
+ BYTE* pTotalFlags = NULL;
+ TTPOLYGONHEADER* pHeader = (TTPOLYGONHEADER*)pData;
+ TTPOLYCURVE* pCurve;
+ *ppPolySizes = new USHORT[ MAX_POLYCOUNT ];
+ memset( *ppPolySizes, 0, MAX_POLYCOUNT * sizeof( USHORT ) );
+
+ while ( ((BYTE*)pHeader < pData+nSize) && (nPolyCount < (MAX_POLYCOUNT - 1)) )
+ {
+ if ( pHeader->dwType == TT_POLYGON_TYPE )
+ {
+ USHORT nPnt = 0;
+ USHORT i;
+
+ memset( pPoints, 0, nPtSize * sizeof( SalPoint ) );
+ memset( pFlags, 0, nPtSize );
+
+ // ersten Startpunkt holen; die folgenden Startpunkte sind
+ // die Endpunkte der vorhergehenden Kurven
+ pPoints[ nPnt ].mnX = IntFromFixed( pHeader->pfxStart.x );
+ pPoints[ nPnt++ ].mnY = IntFromFixed( pHeader->pfxStart.y );
+
+ pCurve = (TTPOLYCURVE*) ( pHeader + 1 );
+
+ while ( (BYTE*)pCurve < (BYTE*)pHeader+pHeader->cb )
+ {
+ if ( TT_PRIM_LINE == pCurve->wType )
+ {
+ for( i = 0; i < pCurve->cpfx; i++ )
+ {
+ CHECKPOINTS( nPnt );
+ pPoints[ nPnt ].mnX = IntFromFixed( pCurve->apfx[ i ].x );
+ pPoints[ nPnt++ ].mnY = IntFromFixed( pCurve->apfx[ i ].y );
+ }
+ }
+ else if ( pCurve->wType == TT_PRIM_QSPLINE )
+ {
+ for ( i = 0; i < pCurve->cpfx; )
+ {
+ // Punkt B, der Kontrollpunkt der Kurve
+ CHECKPOINTS( nPnt );
+ pPoints[ nPnt ].mnX = IntFromFixed( pCurve->apfx[ i ].x );
+ pPoints[ nPnt ].mnY = IntFromFixed( pCurve->apfx[ i++ ].y );
+
+ // Punkt verdoppeln fuer Bezier-Wandlung
+ CHECKPOINTS( nPnt + 1UL );
+ pPoints[ nPnt + 1 ] = pPoints[ nPnt ];
+ nPnt += 2;
+
+ // Endpunkt der Kurve bestimmen
+ if ( i == (pCurve->cpfx - 1) )
+ {
+ // entweder letzter Punkt
+ CHECKPOINTS( nPnt );
+ pPoints[ nPnt ].mnX = IntFromFixed( pCurve->apfx[ i ].x );
+ pPoints[ nPnt++].mnY = IntFromFixed( pCurve->apfx[ i++ ].y );
+ }
+ else
+ {
+ // oder die Mitte zwischen den Kontrollpunkten
+ // dieser und der naechsten Kurce
+ CHECKPOINTS( nPnt );
+ pPoints[ nPnt ].mnX = IntFromFixed( fxDiv2( pCurve->apfx[ i - 1 ].x,
+ pCurve->apfx[ i ].x ) );
+ pPoints[ nPnt++ ].mnY = IntFromFixed( fxDiv2( pCurve->apfx[ i - 1 ].y,
+ pCurve->apfx[ i ].y ) );
+ }
+
+ // Umrechnung in Bezier ( PQ = TrueType-Controlpunkt):
+ // P1 = 1/3 * (P0 + 2 * PQ) / P2 = 1/3 * (P3 + 2 * PQ)
+ pPoints[ nPnt - 3 ].mnX = ( pPoints[ nPnt - 4 ].mnX +
+ ( pPoints[ nPnt - 3 ].mnX << 1 ) ) / 3;
+ pPoints[ nPnt - 3 ].mnY = ( pPoints[ nPnt - 4 ].mnY +
+ ( pPoints[ nPnt - 3 ].mnY << 1 ) ) / 3;
+
+ pPoints[ nPnt - 2 ].mnX = ( pPoints[ nPnt - 1 ].mnX +
+ ( pPoints[ nPnt - 2 ].mnX << 1 ) ) / 3;
+ pPoints[ nPnt - 2 ].mnY = ( pPoints[ nPnt - 1 ].mnY +
+ ( pPoints[ nPnt - 2 ].mnY << 1 ) ) / 3;
+
+ pFlags[ nPnt - 3 ] = pFlags[ nPnt - 2 ] = 2;
+ }
+ }
+
+ // weiter mit naechstem Kurvensegment
+ pCurve = (TTPOLYCURVE*) &pCurve->apfx[ i ];
+ }
+
+ CHECKPOINTS( nPnt );
+ pPoints[nPnt++] = pPoints[0];
+
+ if ( nPnt )
+ {
+ (*ppPolySizes)[ nPolyCount++ ] = nPnt;
+ ImplIncreaseArrays( nTotalCount, &pTotalPoints, &pTotalFlags, nPnt );
+
+ // Polygon senkrecht kippen: TrueType-Y-Koordinaten verlaufen von unten nach oben
+ for ( i = 0; i < nPnt; i++ )
+ {
+ pTotalPoints[ nTotalCount ].mnX = pPoints[i].mnX;
+ pTotalPoints[ nTotalCount ].mnY = nAscent - pPoints[i].mnY;
+ pTotalFlags[ nTotalCount++ ] = pFlags[i];
+ }
+ }
+
+ // naechstes Polygon
+ pHeader = (TTPOLYGONHEADER*) ( (BYTE*) pHeader + pHeader->cb );
+ }
+ }
+
+ delete[] pPoints;
+ delete[] pFlags;
+
+ if ( !nPolyCount )
+ {
+ delete[] pTotalPoints;
+ *ppPoints = NULL;
+ delete[] pTotalFlags;
+ *ppFlags = NULL;
+ delete[] *ppPolySizes;
+ *ppPolySizes = NULL;
+ }
+ else
+ {
+ *ppPoints = pTotalPoints;
+ *ppFlags = pTotalFlags;
+ }
+ }
+
+ delete [] pData;
+ }
+
+ if ( hOldFont )
+ {
+ HFONT hNewFont = SelectFont( maGraphicsData.mhDC, hOldFont );
+ DeleteFont( hNewFont );
+ }
+
+ return nPolyCount;
+}
diff --git a/vcl/win/source/gdi/salogl.cxx b/vcl/win/source/gdi/salogl.cxx
new file mode 100644
index 000000000000..bdd5ccee00e8
--- /dev/null
+++ b/vcl/win/source/gdi/salogl.cxx
@@ -0,0 +1,329 @@
+/*************************************************************************
+ *
+ * $RCSfile: salogl.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:49 $
+ *
+ * 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 _SVWIN_H
+#include <tools/svwin.h>
+#endif
+
+#define _SV_SALOGL_CXX
+
+#ifndef _SV_SALOGL_HXX
+#include <salogl.hxx>
+#endif
+#ifndef _SV_SALGDI_HXX
+#include <salgdi.hxx>
+#endif
+
+// -------------------------------
+// - Additional typedefs for init.
+// -------------------------------
+
+typedef HGLRC ( *OGLFncCreateContext )( HDC hDC );
+typedef BOOL ( *OGLFncDeleteContext )( HGLRC hContext );
+typedef HGLRC ( *OGLFncGetCurrentContext )( VOID );
+typedef void ( *OGLFncMakeCurrent )( HDC hDC, HGLRC hContext );
+
+// ------------
+// - Lib-Name -
+// ------------
+
+#define OGL_LIBNAME "OPENGL32.DLL"
+
+// ----------
+// - Macros -
+// ----------
+
+#define INIT_OGLFNC_WGL( FncName ) static OGLFnc##FncName pImplOpenWGLFnc##FncName = NULL;
+#define GET_OGLFNC_WGL( FncName ) \
+pImplOpenWGLFnc##FncName = (OGLFnc##FncName##) GetProcAddress( hImplOGLLib, "wgl" #FncName ); \
+if( !pImplOpenWGLFnc##FncName ) bRet = FALSE;
+
+// -----------------
+// - Statics init. -
+// -----------------
+
+// Members
+static HINSTANCE hImplOGLLib;
+HGLRC SalOpenGL::mhOGLContext = 0;
+HDC SalOpenGL::mhOGLLastDC = 0;
+ULONG SalOpenGL::mnOGLState = OGL_STATE_UNLOADED;
+
+INIT_OGLFNC_WGL( CreateContext );
+INIT_OGLFNC_WGL( DeleteContext );
+INIT_OGLFNC_WGL( GetCurrentContext );
+INIT_OGLFNC_WGL( MakeCurrent );
+
+// -----------
+// - WndProc -
+// -----------
+
+LRESULT CALLBACK OpenGLWndProc( HWND hWnd,UINT nMsg, WPARAM nPar1, LPARAM nPar2 )
+{
+ return DefWindowProc( hWnd, nMsg, nPar1, nPar2 );
+}
+
+// -------------
+// - SalOpenGL -
+// -------------
+
+SalOpenGL::SalOpenGL( SalGraphics* pGraphics )
+{
+ // Set mhOGLLastDC only the first time a
+ // SalOpenGL object is created; we need
+ // this DC in SalOpenGL::Create();
+ if ( OGL_STATE_UNLOADED == mnOGLState )
+ mhOGLLastDC = pGraphics->maGraphicsData.mhDC;
+}
+
+// ------------------------------------------------------------------------
+
+SalOpenGL::~SalOpenGL()
+{
+}
+
+// ------------------------------------------------------------------------
+
+BOOL SalOpenGL::Create()
+{
+ BOOL bRet = FALSE;
+
+ if ( OGL_STATE_UNLOADED == mnOGLState )
+ {
+ if( ImplInitLib() )
+ {
+ USHORT nBitCount = GetDeviceCaps( mhOGLLastDC, BITSPIXEL );
+ PIXELFORMATDESCRIPTOR pfd =
+ {
+ sizeof( PIXELFORMATDESCRIPTOR ),
+ 1,
+ PFD_DRAW_TO_WINDOW | PFD_SUPPORT_GDI | PFD_SUPPORT_OPENGL,
+ PFD_TYPE_RGBA,
+ (BYTE) nBitCount,
+ 0, 0, 0, 0, 0, 0,
+ 0,
+ 0,
+ 0,
+ 0, 0, 0, 0,
+ 16,
+ 0,
+ 0,
+ PFD_MAIN_PLANE,
+ 0,
+ 0, 0, 0
+ };
+
+ const int nIndex = ChoosePixelFormat( mhOGLLastDC, &pfd );
+
+ if( nIndex && SetPixelFormat( mhOGLLastDC, nIndex, &pfd ) )
+ {
+ if ( (nBitCount > 8) && ImplInit() &&
+ (mhOGLContext = pImplOpenWGLFncCreateContext( mhOGLLastDC )) != 0 )
+ {
+ WNDCLASS aWc;
+ HWND hDummyWnd;
+
+ SaveDC( mhOGLLastDC );
+ SelectClipRgn( mhOGLLastDC, NULL );
+ pImplOpenWGLFncMakeCurrent( mhOGLLastDC, mhOGLContext );
+ RestoreDC( mhOGLLastDC, -1 );
+ mnOGLState = OGL_STATE_VALID;
+ bRet = TRUE;
+
+ memset( &aWc, 0, sizeof( aWc ) );
+ aWc.hInstance = GetModuleHandle( NULL );
+ aWc.lpfnWndProc = OpenGLWndProc;
+ aWc.lpszClassName = "OpenGLWnd";
+ RegisterClass( &aWc );
+ hDummyWnd = CreateWindow( aWc.lpszClassName, NULL, WS_OVERLAPPED, 0, -50, 1, 1, HWND_DESKTOP, NULL, aWc.hInstance, 0 );
+ ShowWindow( hDummyWnd, SW_SHOW );
+ DestroyWindow( hDummyWnd );
+ UnregisterClass( aWc.lpszClassName, aWc.hInstance );
+ }
+ else
+ {
+ ImplFreeLib();
+ mnOGLState = OGL_STATE_INVALID;
+ }
+ }
+ else
+ mnOGLState = OGL_STATE_INVALID;
+ }
+ else
+ mnOGLState = OGL_STATE_INVALID;
+ }
+ else if( OGL_STATE_VALID == mnOGLState )
+ bRet = TRUE;
+
+ return bRet;
+}
+
+// ------------------------------------------------------------------------
+
+void SalOpenGL::Release()
+{
+ ImplFreeLib();
+}
+
+// ------------------------------------------------------------------------
+
+void* SalOpenGL::GetOGLFnc( const char* pFncName )
+{
+ if ( hImplOGLLib )
+ return (void*)GetProcAddress( hImplOGLLib, pFncName );
+ else
+ return NULL;
+}
+
+// ------------------------------------------------------------------------
+
+typedef BOOL (WINAPI *MyFuncType)(HDC, HGLRC);
+
+void SalOpenGL::OGLEntry( SalGraphics* pGraphics )
+{
+ if ( pGraphics->maGraphicsData.mhDC != mhOGLLastDC )
+ {
+ PIXELFORMATDESCRIPTOR pfd =
+ {
+ sizeof( PIXELFORMATDESCRIPTOR ),
+ 1,
+ PFD_DRAW_TO_WINDOW | PFD_SUPPORT_GDI | PFD_SUPPORT_OPENGL,
+ PFD_TYPE_RGBA,
+ GetDeviceCaps( pGraphics->maGraphicsData.mhDC, BITSPIXEL ),
+ 0, 0, 0, 0, 0, 0,
+ 0,
+ 0,
+ 0,
+ 0, 0, 0, 0,
+ 16,
+ 0,
+ 0,
+ PFD_MAIN_PLANE,
+ 0,
+ 0, 0, 0
+ };
+
+ const int nIndex = ChoosePixelFormat( pGraphics->maGraphicsData.mhDC, &pfd );
+ if ( nIndex && SetPixelFormat( pGraphics->maGraphicsData.mhDC, nIndex, &pfd ) )
+ {
+ WNDCLASS aWc;
+ HWND hDummyWnd;
+
+ pImplOpenWGLFncDeleteContext( mhOGLContext );
+ mhOGLLastDC = pGraphics->maGraphicsData.mhDC;
+ mhOGLContext = pImplOpenWGLFncCreateContext( mhOGLLastDC );
+
+ SaveDC( mhOGLLastDC );
+ SelectClipRgn( mhOGLLastDC, NULL );
+ pImplOpenWGLFncMakeCurrent( mhOGLLastDC, mhOGLContext );
+ RestoreDC( mhOGLLastDC, -1 );
+
+ memset( &aWc, 0, sizeof( aWc ) );
+ aWc.hInstance = GetModuleHandle( NULL );
+ aWc.lpfnWndProc = OpenGLWndProc;
+ aWc.lpszClassName = "OpenGLWnd";
+ RegisterClass( &aWc );
+ hDummyWnd = CreateWindow( aWc.lpszClassName, NULL, WS_OVERLAPPED, 0, -50, 1, 1, HWND_DESKTOP, NULL, aWc.hInstance, 0 );
+ ShowWindow( hDummyWnd, SW_SHOW );
+ DestroyWindow( hDummyWnd );
+ UnregisterClass( aWc.lpszClassName, aWc.hInstance );
+ }
+ }
+}
+
+// ------------------------------------------------------------------------
+
+void SalOpenGL::OGLExit( SalGraphics* pGraphics )
+{
+}
+
+// ------------------------------------------------------------------------
+
+BOOL SalOpenGL::ImplInitLib()
+{
+ return ((hImplOGLLib = LoadLibrary( OGL_LIBNAME )) != NULL);
+}
+
+// ------------------------------------------------------------------------
+
+void SalOpenGL::ImplFreeLib()
+{
+ if ( hImplOGLLib )
+ {
+ FreeLibrary( hImplOGLLib );
+ hImplOGLLib = NULL;
+ mnOGLState = OGL_STATE_UNLOADED;
+ }
+}
+
+// ------------------------------------------------------------------------
+
+BOOL SalOpenGL::ImplInit()
+{
+ BOOL bRet = TRUE;
+
+ // Internal use
+ GET_OGLFNC_WGL( CreateContext );
+ GET_OGLFNC_WGL( DeleteContext );
+ GET_OGLFNC_WGL( GetCurrentContext );
+ GET_OGLFNC_WGL( MakeCurrent );
+
+ return bRet;
+}
diff --git a/vcl/win/source/gdi/salprn.cxx b/vcl/win/source/gdi/salprn.cxx
new file mode 100644
index 000000000000..e4ac38538b51
--- /dev/null
+++ b/vcl/win/source/gdi/salprn.cxx
@@ -0,0 +1,1424 @@
+/*************************************************************************
+ *
+ * $RCSfile: salprn.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:49 $
+ *
+ * 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 <string.h>
+#ifndef _SVWIN_H
+#include <tools/svwin.h>
+#endif
+
+#define _SV_SALPRN_CXX
+
+#ifndef _SV_WINCOMP_HXX
+#include <wincomp.hxx>
+#endif
+#ifndef _SV_SALDATA_HXX
+#include <saldata.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_SALPTYPE_HXX
+#include <salptype.hxx>
+#endif
+#ifndef _SV_SALPRN_HXX
+#include <salprn.hxx>
+#endif
+
+#ifndef _NEW_HXX
+#include <tools/new.hxx>
+#endif
+
+#ifndef _SV_PRINT_H
+#include <print.h>
+#endif
+#ifndef _SV_JOBSET_H
+#include <jobset.h>
+#endif
+
+// =======================================================================
+
+static char aImplWindows[] = "windows";
+static char aImplDevices[] = "devices";
+static char aImplDevice[] = "device";
+
+// =======================================================================
+
+static ULONG ImplWinQueueStatusToSal( DWORD nWinStatus )
+{
+ ULONG nStatus = 0;
+ if ( nWinStatus & PRINTER_STATUS_PAUSED )
+ nStatus |= QUEUE_STATUS_PAUSED;
+ if ( nWinStatus & PRINTER_STATUS_ERROR )
+ nStatus |= QUEUE_STATUS_ERROR;
+ if ( nWinStatus & PRINTER_STATUS_PENDING_DELETION )
+ nStatus |= QUEUE_STATUS_PENDING_DELETION;
+ if ( nWinStatus & PRINTER_STATUS_PAPER_JAM )
+ nStatus |= QUEUE_STATUS_PAPER_JAM;
+ if ( nWinStatus & PRINTER_STATUS_PAPER_OUT )
+ nStatus |= QUEUE_STATUS_PAPER_OUT;
+ if ( nWinStatus & PRINTER_STATUS_MANUAL_FEED )
+ nStatus |= QUEUE_STATUS_MANUAL_FEED;
+ if ( nWinStatus & PRINTER_STATUS_PAPER_PROBLEM )
+ nStatus |= QUEUE_STATUS_PAPER_PROBLEM;
+ if ( nWinStatus & PRINTER_STATUS_OFFLINE )
+ nStatus |= QUEUE_STATUS_OFFLINE;
+ if ( nWinStatus & PRINTER_STATUS_IO_ACTIVE )
+ nStatus |= QUEUE_STATUS_IO_ACTIVE;
+ if ( nWinStatus & PRINTER_STATUS_BUSY )
+ nStatus |= QUEUE_STATUS_BUSY;
+ if ( nWinStatus & PRINTER_STATUS_PRINTING )
+ nStatus |= QUEUE_STATUS_PRINTING;
+ if ( nWinStatus & PRINTER_STATUS_OUTPUT_BIN_FULL )
+ nStatus |= QUEUE_STATUS_OUTPUT_BIN_FULL;
+ if ( nWinStatus & PRINTER_STATUS_WAITING )
+ nStatus |= QUEUE_STATUS_WAITING;
+ if ( nWinStatus & PRINTER_STATUS_PROCESSING )
+ nStatus |= QUEUE_STATUS_PROCESSING;
+ if ( nWinStatus & PRINTER_STATUS_INITIALIZING )
+ nStatus |= QUEUE_STATUS_INITIALIZING;
+ if ( nWinStatus & PRINTER_STATUS_WARMING_UP )
+ nStatus |= QUEUE_STATUS_WARMING_UP;
+ if ( nWinStatus & PRINTER_STATUS_TONER_LOW )
+ nStatus |= QUEUE_STATUS_TONER_LOW;
+ if ( nWinStatus & PRINTER_STATUS_NO_TONER )
+ nStatus |= QUEUE_STATUS_NO_TONER;
+ if ( nWinStatus & PRINTER_STATUS_PAGE_PUNT )
+ nStatus |= QUEUE_STATUS_PAGE_PUNT;
+ if ( nWinStatus & PRINTER_STATUS_USER_INTERVENTION )
+ nStatus |= QUEUE_STATUS_USER_INTERVENTION;
+ if ( nWinStatus & PRINTER_STATUS_OUT_OF_MEMORY )
+ nStatus |= QUEUE_STATUS_OUT_OF_MEMORY;
+ if ( nWinStatus & PRINTER_STATUS_DOOR_OPEN )
+ nStatus |= QUEUE_STATUS_DOOR_OPEN;
+ if ( nWinStatus & PRINTER_STATUS_SERVER_UNKNOWN )
+ nStatus |= QUEUE_STATUS_SERVER_UNKNOWN;
+ if ( nWinStatus & PRINTER_STATUS_POWER_SAVE )
+ nStatus |= QUEUE_STATUS_POWER_SAVE;
+ if ( !nStatus && !(nWinStatus & PRINTER_STATUS_NOT_AVAILABLE) )
+ nStatus |= QUEUE_STATUS_READY;
+ return nStatus;
+}
+
+// -----------------------------------------------------------------------
+
+void SalInstance::GetPrinterQueueInfo( ImplPrnQueueList* pList )
+{
+// !!! UNICODE - NT Optimierung !!!
+ DWORD i;
+ DWORD n;
+ DWORD nBytes = 0;
+// DWORD nInfoRet;
+ DWORD nInfoPrn2;
+ BOOL bFound = FALSE;
+ PRINTER_INFO_2* pWinInfo2 = NULL;
+ PRINTER_INFO_2* pGetInfo2;
+ EnumPrintersA( PRINTER_ENUM_LOCAL, NULL, 2, NULL, 0, &nBytes, &nInfoPrn2 );
+ if ( nBytes )
+ {
+ pWinInfo2 = (PRINTER_INFO_2*)new BYTE[nBytes];
+ if ( EnumPrintersA( PRINTER_ENUM_LOCAL, NULL, 2, (LPBYTE)pWinInfo2, nBytes, &nBytes, &nInfoPrn2 ) )
+ {
+ pGetInfo2 = pWinInfo2;
+ for ( i = 0; i < nInfoPrn2; i++ )
+ {
+ SalPrinterQueueInfo* pInfo = new SalPrinterQueueInfo;
+ pInfo->maPrinterName = ImplSalGetUniString( pGetInfo2->pPrinterName );
+ pInfo->maDriver = ImplSalGetUniString( pGetInfo2->pDriverName );
+ XubString aPortName;
+ if ( pGetInfo2->pPortName )
+ aPortName = ImplSalGetUniString( pGetInfo2->pPortName );
+ // pLocation can be 0 (the Windows docu doesn't describe this)
+ if ( pGetInfo2->pLocation && strlen( pGetInfo2->pLocation ) )
+ pInfo->maLocation = ImplSalGetUniString( pGetInfo2->pLocation );
+ else
+ pInfo->maLocation = aPortName;
+ // pComment can be 0 (the Windows docu doesn't describe this)
+ if ( pGetInfo2->pComment )
+ pInfo->maComment = ImplSalGetUniString( pGetInfo2->pComment );
+ pInfo->mnStatus = ImplWinQueueStatusToSal( pGetInfo2->Status );
+ pInfo->mnJobs = pGetInfo2->cJobs;
+ pInfo->mpSysData = new XubString( aPortName );
+ pList->Add( pInfo );
+ pGetInfo2++;
+ }
+
+ bFound = TRUE;
+ }
+ }
+
+/* Siehe Kommentar unten !!!
+ EnumPrinters( PRINTER_ENUM_NETWORK | PRINTER_ENUM_REMOTE, NULL, 1, NULL, 0, &nBytes, &nInfoRet );
+ if ( nBytes )
+ {
+ PRINTER_INFO_1* pWinInfo1 = (PRINTER_INFO_1*)new BYTE[nBytes];
+ if ( EnumPrinters( PRINTER_ENUM_NETWORK | PRINTER_ENUM_REMOTE, NULL, 1, (LPBYTE)pWinInfo1, nBytes, &nBytes, &nInfoRet ) )
+ {
+ PRINTER_INFO_1* pGetInfo1 = pWinInfo1;
+ for ( i = 0; i < nInfoRet; i++ )
+ {
+ // Feststellen, ob Printer durch erste Abfrage schon gefunden
+ // wurde
+ BOOL bAdd = TRUE;
+ if ( pWinInfo2 )
+ {
+ pGetInfo2 = pWinInfo2;
+ for ( n = 0; n < nInfoPrn2; n++ )
+ {
+ if ( strcmp( pGetInfo1->pName, pGetInfo2->pPrinterName ) == 0 )
+ {
+ bAdd = FALSE;
+ break;
+ }
+ pGetInfo2++;
+ }
+ }
+ // Wenn neuer Printer, dann aufnehmen
+ if ( bAdd )
+ {
+ SalPrinterQueueInfo* pInfo = new SalPrinterQueueInfo;
+ XubString aPrnName( pGetInfo1->pName );
+ pInfo->maPrinterName = aPrnName;
+ pInfo->maDriver = "winspool";
+ pInfo->maComment = pGetInfo1->pComment;
+ pInfo->mnStatus = 0;
+ pInfo->mnJobs = QUEUE_JOBS_DONTKNOW;
+ pInfo->mpSysData = new String();
+ pList->Add( pInfo );
+ }
+ pGetInfo1++;
+ }
+
+ bFound = TRUE;
+ }
+
+ delete pWinInfo1;
+ }
+*/
+
+// if ( bFound )
+// return;
+
+// !!! UNICODE - NT Optimierung !!!
+ // Drucker aus WIN.INI lesen
+ UINT nSize = 4096;
+ char* pBuf = new char[nSize];
+ UINT nRead = GetProfileStringA( aImplDevices, NULL, "", pBuf, nSize );
+ while ( nRead >= nSize-2 )
+ {
+ nSize += 2048;
+ delete pBuf;
+ pBuf = new char[nSize];
+ nRead = GetProfileStringA( aImplDevices, NULL, "", pBuf, nSize );
+ }
+
+ // Druckernamen aus Buffer extrahieren und Liste aufbauen
+ char* pName = pBuf;
+ while ( *pName )
+ {
+ char* pPortName;
+ char* pTmp;
+ char aPortBuf[256];
+ GetProfileStringA( aImplDevices, pName, "", aPortBuf, sizeof( aPortBuf ) );
+
+ pPortName = aPortBuf;
+
+ // Namen anlegen
+ xub_StrLen nNameLen = strlen( pName );
+ XubString aName( ImplSalGetUniString( pName, nNameLen ) );
+
+ // Treibernamen rausfischen
+ pTmp = pPortName;
+ while ( *pTmp != ',' )
+ pTmp++;
+ XubString aDriver( ImplSalGetUniString( pPortName, (USHORT)(pTmp-pPortName) ) );
+ pPortName = pTmp;
+
+ // Alle Portnamen raussuchen
+ do
+ {
+ pPortName++;
+ pTmp = pPortName;
+ while ( *pTmp && (*pTmp != ',') )
+ pTmp++;
+
+ String aPortName( ImplSalGetUniString( pPortName, (USHORT)(pTmp-pPortName) ) );
+
+ // Neuen Eintrag anlegen
+ // !!! Da ich zu bloeb bin, die Netzwerk-Printer zur 5.0
+ // !!! richtig zu integrieren, gehen wir zusaetzlich
+ // !!! noch ueber das W16-Interface, da uns dort die
+ // !!! Drucker noch einfach und schnell geliefert werden
+ // !!! ohne das wir jetzt zu grossen Aufwand treiben muessen.
+ // !!! Somit sollten wir dann jedenfalls nicht schlechter sein
+ // !!! als in einer 4.0 SP2.
+ // Feststellen, ob Printer durch erste Abfrage schon gefunden
+ // wurde
+ BOOL bAdd = TRUE;
+ if ( pWinInfo2 )
+ {
+ pGetInfo2 = pWinInfo2;
+ for ( n = 0; n < nInfoPrn2; n++ )
+ {
+ if ( aName.EqualsIgnoreCaseAscii( pGetInfo2->pPrinterName ) )
+ {
+ bAdd = FALSE;
+ break;
+ }
+ pGetInfo2++;
+ }
+ }
+ // Wenn neuer Printer, dann aufnehmen
+ if ( bAdd )
+ {
+ SalPrinterQueueInfo* pInfo = new SalPrinterQueueInfo;
+ pInfo->maPrinterName = aName;
+ pInfo->maDriver = aDriver;
+ pInfo->maLocation = aPortName;
+ pInfo->mnStatus = 0;
+ pInfo->mnJobs = QUEUE_JOBS_DONTKNOW;
+ pInfo->mpSysData = new XubString( aPortName );
+ pList->Add( pInfo );
+ }
+ }
+ while ( *pTmp == ',' );
+
+ pName += nNameLen + 1;
+ }
+
+ delete pBuf;
+ delete pWinInfo2;
+}
+
+// -----------------------------------------------------------------------
+
+void SalInstance::GetPrinterQueueState( SalPrinterQueueInfo* pInfo )
+{
+// !!! UNICODE - NT Optimierung !!!
+ DWORD nBytes = 0;
+ DWORD nInfoRet;
+ PRINTER_INFO_2* pWinInfo2;
+ EnumPrintersA( PRINTER_ENUM_LOCAL, NULL, 2, NULL, 0, &nBytes, &nInfoRet );
+ if ( nBytes )
+ {
+ pWinInfo2 = (PRINTER_INFO_2*)new BYTE[nBytes];
+ if ( EnumPrintersA( PRINTER_ENUM_LOCAL, NULL, 2, (LPBYTE)pWinInfo2, nBytes, &nBytes, &nInfoRet ) )
+ {
+ PRINTER_INFO_2* pGetInfo2 = pWinInfo2;
+ for ( DWORD i = 0; i < nInfoRet; i++ )
+ {
+ if ( pInfo->maPrinterName.EqualsAscii( pGetInfo2->pPrinterName ) &&
+ pInfo->maDriver.EqualsAscii( pGetInfo2->pDriverName ) )
+ {
+ if ( pGetInfo2->pLocation && strlen( pGetInfo2->pLocation ) )
+ pInfo->maLocation = ImplSalGetUniString( pGetInfo2->pLocation );
+ else
+ pInfo->maLocation = ImplSalGetUniString( pGetInfo2->pPortName );
+ pInfo->mnStatus = ImplWinQueueStatusToSal( pGetInfo2->Status );
+ pInfo->mnJobs = pGetInfo2->cJobs;
+ break;
+ }
+
+ pGetInfo2++;
+ }
+ }
+
+ delete pWinInfo2;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void SalInstance::DeletePrinterQueueInfo( SalPrinterQueueInfo* pInfo )
+{
+ delete (String*)(pInfo->mpSysData);
+ delete pInfo;
+}
+
+// -----------------------------------------------------------------------
+
+// !!! UNICODE - NT Optimierung !!!
+XubString SalInstance::GetDefaultPrinter()
+{
+ // Default-Printer-String aus win.ini holen
+ char szBuffer[256];
+ GetProfileStringA( aImplWindows, aImplDevice, "", szBuffer, sizeof( szBuffer ) );
+ if ( szBuffer[0] )
+ {
+ // Printername suchen
+ char* pBuf = szBuffer;
+ char* pTmp = pBuf;
+ while ( *pTmp && (*pTmp != ',') )
+ pTmp++;
+ return ImplSalGetUniString( pBuf, (xub_StrLen)(pTmp-pBuf) );
+ }
+ else
+ return XubString();
+}
+
+// =======================================================================
+
+static DWORD ImplDeviceCaps( SalInfoPrinter* pPrinter, WORD nCaps,
+ LPTSTR pOutput, const ImplJobSetup* pSetupData )
+{
+ DEVMODE* pDevMode;
+ if ( !pSetupData || !pSetupData->mpDriverData )
+ pDevMode = NULL;
+ else
+ pDevMode = SAL_DEVMODE( pSetupData );
+
+// !!! UNICODE - NT Optimierung !!!
+ return DeviceCapabilitiesA( ImplSalGetWinAnsiString( pPrinter->maPrinterData.maDeviceName, TRUE ).GetBuffer(),
+ ImplSalGetWinAnsiString( pPrinter->maPrinterData.maPortName, TRUE ).GetBuffer(),
+ nCaps, (LPSTR)pOutput, pDevMode );
+}
+
+// -----------------------------------------------------------------------
+
+static BOOL ImplTestSalJobSetup( SalInfoPrinter* pPrinter,
+ ImplJobSetup* pSetupData, BOOL bDelete )
+{
+ if ( pSetupData && pSetupData->mpDriverData )
+ {
+ // Signature und Groesse muss uebereinstimmen, damit wir keine
+ // JobSetup's von anderen Systemen setzen
+ if ( (pSetupData->mnSystem == JOBSETUP_SYSTEM_WINDOWS) &&
+ (pSetupData->mnDriverDataLen > sizeof( SalDriverData )) &&
+ (((SalDriverData*)(pSetupData->mpDriverData))->mnSysSignature == SAL_DRIVERDATA_SYSSIGN) )
+ return TRUE;
+ else if ( bDelete )
+ {
+ delete pSetupData->mpDriverData;
+ pSetupData->mpDriverData = NULL;
+ pSetupData->mnDriverDataLen = 0;
+ }
+ }
+
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+static BOOL ImplUpdateSalJobSetup( SalInfoPrinter* pPrinter, ImplJobSetup* pSetupData,
+ BOOL bIn, SalFrame* pVisibleDlgParent )
+{
+ HANDLE hPrn;
+// !!! UNICODE - NT Optimierung !!!
+ if ( !OpenPrinterA( (LPSTR)ImplSalGetWinAnsiString( pPrinter->maPrinterData.maDeviceName, TRUE ).GetBuffer(), &hPrn, NULL ) )
+ return FALSE;
+
+ LONG nRet;
+ LONG nSysJobSize;
+ HWND hWnd = 0;
+ DWORD nMode = DM_OUT_BUFFER;
+ ULONG nDriverDataLen = 0;
+ SalDriverData* pOutBuffer = NULL;
+ DEVMODE* pInDevBuffer = NULL;
+ DEVMODE* pOutDevBuffer = NULL;
+
+// !!! UNICODE - NT Optimierung !!!
+ nSysJobSize = DocumentPropertiesA( hWnd, hPrn,
+ (LPSTR)ImplSalGetWinAnsiString( pPrinter->maPrinterData.maDeviceName, TRUE ).GetBuffer(),
+ NULL, NULL, 0 );
+ if ( nSysJobSize < 0 )
+ {
+ ClosePrinter( hPrn );
+ return FALSE;
+ }
+
+ // Outputbuffer anlegen
+ nDriverDataLen = sizeof(SalDriverData)+nSysJobSize-1;
+ pOutBuffer = (SalDriverData*)SvMemAlloc( nDriverDataLen );
+ memset( pOutBuffer, 0, nDriverDataLen );
+ pOutDevBuffer = (LPDEVMODE)(pOutBuffer->maDriverData);
+ pOutBuffer->mnSysSignature = SAL_DRIVERDATA_SYSSIGN;
+ pOutBuffer->mnVersion = SAL_DRIVERDATA_VERSION;
+ pOutBuffer->mnDriverOffset = (USHORT)(((SalDriverData*)NULL)->maDriverData);
+
+ // Testen, ob wir einen geeigneten Inputbuffer haben
+ if ( bIn && ImplTestSalJobSetup( pPrinter, pSetupData, FALSE ) )
+ {
+ pInDevBuffer = SAL_DEVMODE( pSetupData );
+ nMode |= DM_IN_BUFFER;
+ }
+
+ // Testen, ob Dialog angezeigt werden soll
+ if ( pVisibleDlgParent )
+ {
+ hWnd = pVisibleDlgParent->maFrameData.mhWnd;
+ nMode |= DM_IN_PROMPT;
+ }
+
+// !!! UNICODE - NT Optimierung !!!
+ // Release mutex, in the other case we don't get paints and so on
+ ULONG nMutexCount = ImplSalReleaseYieldMutex();
+ nRet = DocumentPropertiesA( hWnd, hPrn,
+ (LPSTR)ImplSalGetWinAnsiString( pPrinter->maPrinterData.maDeviceName, TRUE ).GetBuffer(),
+ pOutDevBuffer, pInDevBuffer, nMode );
+ ImplSalAcquireYieldMutex( nMutexCount );
+ ClosePrinter( hPrn );
+
+ if ( (nRet < 0) || (pVisibleDlgParent && (nRet == IDCANCEL)) )
+ {
+ SvMemFree( pOutBuffer );
+ return FALSE;
+ }
+
+ // String-Buffer am Ende immer mit 0 initialisieren, damit
+ // die JobSetups nach Moeglichkeit bei memcmp immer
+ // identisch sind
+ if ( pOutDevBuffer->dmSize >= 32 )
+ {
+ USHORT nLen = strlen( (const char*)pOutDevBuffer->dmDeviceName );
+ if ( nLen < sizeof( pOutDevBuffer->dmDeviceName ) )
+ memset( pOutDevBuffer->dmDeviceName+nLen, 0, sizeof( pOutDevBuffer->dmDeviceName )-nLen );
+ }
+ if ( pOutDevBuffer->dmSize >= 102 )
+ {
+ USHORT nLen = strlen( (const char*)pOutDevBuffer->dmFormName );
+ if ( nLen < sizeof( pOutDevBuffer->dmFormName ) )
+ memset( pOutDevBuffer->dmFormName+nLen, 0, sizeof( pOutDevBuffer->dmFormName )-nLen );
+ }
+
+ // Daten updaten
+ if ( pSetupData->mpDriverData )
+ delete pSetupData->mpDriverData;
+ pSetupData->mnDriverDataLen = nDriverDataLen;
+ pSetupData->mpDriverData = (BYTE*)pOutBuffer;
+ pSetupData->mnSystem = JOBSETUP_SYSTEM_WINDOWS;
+
+ return TRUE;
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplDevModeToJobSetup( SalInfoPrinter* pPrinter, ImplJobSetup* pSetupData, ULONG nFlags )
+{
+ if ( !pSetupData || !pSetupData->mpDriverData )
+ return;
+
+ DEVMODE* pDevMode = SAL_DEVMODE( pSetupData );
+
+ // Orientation
+ if ( nFlags & SAL_JOBSET_ORIENTATION )
+ {
+ if ( pDevMode->dmOrientation == DMORIENT_PORTRAIT )
+ pSetupData->meOrientation = ORIENTATION_PORTRAIT;
+ else if ( pDevMode->dmOrientation == DMORIENT_LANDSCAPE )
+ pSetupData->meOrientation = ORIENTATION_LANDSCAPE;
+ }
+
+ // PaperBin
+ if ( nFlags & SAL_JOBSET_PAPERBIN )
+ {
+ ULONG nCount = ImplDeviceCaps( pPrinter, DC_BINS, NULL, pSetupData );
+
+ if ( nCount && (nCount != ((ULONG)-1)) )
+ {
+ WORD* pBins = new WORD[nCount];
+ memset( (BYTE*)pBins, 0, nCount*sizeof(WORD) );
+ ImplDeviceCaps( pPrinter, DC_BINS, (LPTSTR)pBins, pSetupData );
+ pSetupData->mnPaperBin = 0;
+
+ // search the right bin and assign index to mnPaperBin
+ for( ULONG i = 0; i < nCount; i++ )
+ {
+ if( pDevMode->dmDefaultSource == pBins[ i ] )
+ {
+ pSetupData->mnPaperBin = (USHORT)i;
+ break;
+ }
+ }
+
+ delete[] pBins;
+ }
+ }
+
+ // PaperSize
+ if ( nFlags & SAL_JOBSET_PAPERSIZE )
+ {
+ pSetupData->mnPaperWidth = pDevMode->dmPaperWidth*10;
+ pSetupData->mnPaperHeight = pDevMode->dmPaperLength*10;
+ switch( pDevMode->dmPaperSize )
+ {
+ case( DMPAPER_A3 ):
+ pSetupData->mePaperFormat = PAPER_A3;
+ break;
+ case( DMPAPER_A4 ):
+ pSetupData->mePaperFormat = PAPER_A4;
+ break;
+ case( DMPAPER_A5 ):
+ pSetupData->mePaperFormat = PAPER_A5;
+ break;
+ case( DMPAPER_B4 ):
+ pSetupData->mePaperFormat = PAPER_B4;
+ break;
+ case( DMPAPER_B5 ):
+ pSetupData->mePaperFormat = PAPER_B5;
+ break;
+ case( DMPAPER_LETTER ):
+ pSetupData->mePaperFormat = PAPER_LETTER;
+ break;
+ case( DMPAPER_LEGAL ):
+ pSetupData->mePaperFormat = PAPER_LEGAL;
+ break;
+ case( DMPAPER_TABLOID ):
+ pSetupData->mePaperFormat = PAPER_TABLOID;
+ break;
+ default:
+ pSetupData->mePaperFormat = PAPER_USER;
+ break;
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+static BOOL ImplPaperSizeEqual( short nPaperWidth1, short nPaperHeight1,
+ short nPaperWidth2, short nPaperHeight2 )
+{
+ return (((nPaperWidth1 >= nPaperWidth2-1) && (nPaperWidth1 <= nPaperWidth2+1)) &&
+ ((nPaperHeight1 >= nPaperHeight2-1) && (nPaperHeight1 <= nPaperHeight2+1)));
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplJobSetupToDevMode( SalInfoPrinter* pPrinter, ImplJobSetup* pSetupData, ULONG nFlags )
+{
+ if ( !pSetupData || !pSetupData->mpDriverData )
+ return;
+
+ DEVMODE* pDevMode = SAL_DEVMODE( pSetupData );
+
+ // Orientation
+ if ( nFlags & SAL_JOBSET_ORIENTATION )
+ {
+ pDevMode->dmFields |= DM_ORIENTATION;
+ if ( pSetupData->meOrientation == ORIENTATION_PORTRAIT )
+ pDevMode->dmOrientation = DMORIENT_PORTRAIT;
+ else
+ pDevMode->dmOrientation = DMORIENT_LANDSCAPE;
+ }
+
+ // PaperBin
+ if ( nFlags & SAL_JOBSET_PAPERBIN )
+ {
+ ULONG nCount = ImplDeviceCaps( pPrinter, DC_BINS, NULL, pSetupData );
+
+ if ( nCount && (nCount != ((ULONG)-1)) )
+ {
+ WORD* pBins = new WORD[nCount];
+ memset( pBins, 0, nCount*sizeof(WORD) );
+ ImplDeviceCaps( pPrinter, DC_BINS, (LPTSTR)pBins, pSetupData );
+ pDevMode->dmFields |= DM_DEFAULTSOURCE;
+ pDevMode->dmDefaultSource = pBins[ pSetupData->mnPaperBin ];
+ delete[] pBins;
+ }
+ }
+
+ // PaperSize
+ if ( nFlags & SAL_JOBSET_PAPERSIZE )
+ {
+ pDevMode->dmFields |= DM_PAPERSIZE;
+ pDevMode->dmPaperWidth = 0;
+ pDevMode->dmPaperLength = 0;
+
+ switch( pDevMode->dmPaperSize )
+ {
+ case( PAPER_A3 ):
+ pDevMode->dmPaperSize = DMPAPER_A3;
+ break;
+ case( PAPER_A4 ):
+ pDevMode->dmPaperSize = DMPAPER_A4;
+ break;
+ case( PAPER_A5 ):
+ pDevMode->dmPaperSize = DMPAPER_A5;
+ break;
+ case( PAPER_B4 ):
+ pDevMode->dmPaperSize = DMPAPER_B4;
+ break;
+ case( PAPER_B5 ):
+ pDevMode->dmPaperSize = DMPAPER_B5;
+ break;
+ case( PAPER_LETTER ):
+ pDevMode->dmPaperSize = DMPAPER_LETTER;
+ break;
+ case( PAPER_LEGAL ):
+ pDevMode->dmPaperSize = DMPAPER_LEGAL;
+ break;
+ case( PAPER_TABLOID ):
+ pDevMode->dmPaperSize = DMPAPER_TABLOID;
+ break;
+ default:
+ {
+ short nPaper = 0;
+ ULONG nPaperCount = ImplDeviceCaps( pPrinter, DC_PAPERS, NULL, pSetupData );
+ WORD* pPapers = NULL;
+ ULONG nPaperSizeCount = ImplDeviceCaps( pPrinter, DC_PAPERSIZE, NULL, pSetupData );
+ POINT* pPaperSizes = NULL;
+ if ( nPaperCount && (nPaperCount != ((ULONG)-1)) )
+ {
+ pPapers = new WORD[nPaperCount];
+ memset( pPapers, 0, nPaperCount*sizeof(WORD) );
+ ImplDeviceCaps( pPrinter, DC_PAPERS, (LPTSTR)pPapers, pSetupData );
+ }
+ if ( nPaperSizeCount && (nPaperSizeCount != ((ULONG)-1)) )
+ {
+ pPaperSizes = new POINT[nPaperSizeCount];
+ memset( pPaperSizes, 0, nPaperSizeCount*sizeof(POINT) );
+ ImplDeviceCaps( pPrinter, DC_PAPERSIZE, (LPTSTR)pPaperSizes, pSetupData );
+ }
+ if ( (nPaperSizeCount == nPaperCount) && pPapers && pPaperSizes )
+ {
+ // Alle Papierformate vergleichen und ein passendes
+ // raussuchen
+ for ( ULONG i = 0; i < nPaperCount; i++ )
+ {
+ if ( ImplPaperSizeEqual( (short)(pSetupData->mnPaperWidth/10),
+ (short)(pSetupData->mnPaperHeight/10),
+ (short)pPaperSizes[i].x,
+ (short)pPaperSizes[i].y ) )
+ {
+ nPaper = pPapers[i];
+ break;
+ }
+ }
+ }
+ if ( pPapers )
+ delete pPapers;
+ if ( pPaperSizes )
+ delete pPaperSizes;
+
+ if ( nPaper )
+ pDevMode->dmPaperSize = nPaper;
+ else
+ {
+ pDevMode->dmFields |= DM_PAPERLENGTH | DM_PAPERWIDTH;
+ pDevMode->dmPaperSize = DMPAPER_USER;
+ pDevMode->dmPaperWidth = pSetupData->mnPaperWidth/10;
+ pDevMode->dmPaperLength = pSetupData->mnPaperHeight/10;
+ }
+ }
+ break;
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+static HDC ImplCreateSalPrnIC( SalInfoPrinter* pPrinter, ImplJobSetup* pSetupData )
+{
+ LPDEVMODE pDevMode;
+ if ( pSetupData && pSetupData->mpDriverData )
+ pDevMode = SAL_DEVMODE( pSetupData );
+ else
+ pDevMode = NULL;
+// !!! UNICODE - NT Optimierung !!!
+ HDC hDC = CreateICA( ImplSalGetWinAnsiString( pPrinter->maPrinterData.maDriverName, TRUE ).GetBuffer(),
+ ImplSalGetWinAnsiString( pPrinter->maPrinterData.maDeviceName, TRUE ).GetBuffer(),
+ 0,
+ (LPDEVMODE)pDevMode );
+ return hDC;
+}
+
+// -----------------------------------------------------------------------
+
+static SalGraphics* ImplCreateSalPrnGraphics( HDC hDC )
+{
+ SalGraphics* pGraphics = new SalGraphics;
+ pGraphics->maGraphicsData.mhDC = hDC;
+ pGraphics->maGraphicsData.mhWnd = 0;
+ pGraphics->maGraphicsData.mbPrinter = TRUE;
+ pGraphics->maGraphicsData.mbVirDev = FALSE;
+ pGraphics->maGraphicsData.mbWindow = FALSE;
+ pGraphics->maGraphicsData.mbScreen = FALSE;
+ ImplSalInitGraphics( &(pGraphics->maGraphicsData) );
+ return pGraphics;
+}
+
+// -----------------------------------------------------------------------
+
+static BOOL ImplUpdateSalPrnIC( SalInfoPrinter* pPrinter, ImplJobSetup* pSetupData )
+{
+ HDC hNewDC = ImplCreateSalPrnIC( pPrinter, pSetupData );
+ if ( !hNewDC )
+ return FALSE;
+
+ if ( pPrinter->maPrinterData.mpGraphics )
+ {
+ ImplSalDeInitGraphics( &(pPrinter->maPrinterData.mpGraphics->maGraphicsData) );
+ DeleteDC( pPrinter->maPrinterData.mpGraphics->maGraphicsData.mhDC );
+ delete pPrinter->maPrinterData.mpGraphics;
+ }
+
+ SalGraphics* pGraphics = ImplCreateSalPrnGraphics( hNewDC );
+ pPrinter->maPrinterData.mhDC = hNewDC;
+ pPrinter->maPrinterData.mpGraphics = pGraphics;
+
+ return TRUE;
+}
+
+// =======================================================================
+
+SalInfoPrinter* SalInstance::CreateInfoPrinter( SalPrinterQueueInfo* pQueueInfo,
+ ImplJobSetup* pSetupData )
+{
+ SalInfoPrinter* pPrinter = new SalInfoPrinter;
+ pPrinter->maPrinterData.maDriverName = pQueueInfo->maDriver;
+ pPrinter->maPrinterData.maDeviceName = pQueueInfo->maPrinterName;
+ pPrinter->maPrinterData.maPortName = *(String*)(pQueueInfo->mpSysData);
+
+ // Testen, ob Setupdaten zum Drucker gehoeren (erst aufrufen, nachdem
+ // die Member gesetzt sind, da diese in dieser Routine abgefragt werden)
+ ImplTestSalJobSetup( pPrinter, pSetupData, TRUE );
+
+ HDC hDC = ImplCreateSalPrnIC( pPrinter, pSetupData );
+ if ( !hDC )
+ {
+ delete pPrinter;
+ return NULL;
+ }
+
+ SalGraphics* pGraphics = ImplCreateSalPrnGraphics( hDC );
+ pPrinter->maPrinterData.mhDC = hDC;
+ pPrinter->maPrinterData.mpGraphics = pGraphics;
+ if ( !pSetupData->mpDriverData )
+ ImplUpdateSalJobSetup( pPrinter, pSetupData, FALSE, NULL );
+ ImplDevModeToJobSetup( pPrinter, pSetupData, SAL_JOBSET_ALL );
+ pSetupData->mnSystem = JOBSETUP_SYSTEM_WINDOWS;
+
+ return pPrinter;
+}
+
+// -----------------------------------------------------------------------
+
+void SalInstance::DestroyInfoPrinter( SalInfoPrinter* pPrinter )
+{
+ delete pPrinter;
+}
+
+// =======================================================================
+
+SalInfoPrinter::SalInfoPrinter()
+{
+ maPrinterData.mhDC = 0;
+ maPrinterData.mpGraphics = NULL;
+ maPrinterData.mbGraphics = FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+SalInfoPrinter::~SalInfoPrinter()
+{
+ if ( maPrinterData.mpGraphics )
+ {
+ ImplSalDeInitGraphics( &(maPrinterData.mpGraphics->maGraphicsData) );
+ DeleteDC( maPrinterData.mpGraphics->maGraphicsData.mhDC );
+ delete maPrinterData.mpGraphics;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+SalGraphics* SalInfoPrinter::GetGraphics()
+{
+ if ( maPrinterData.mbGraphics )
+ return NULL;
+
+ if ( maPrinterData.mpGraphics )
+ maPrinterData.mbGraphics = TRUE;
+
+ return maPrinterData.mpGraphics;
+}
+
+// -----------------------------------------------------------------------
+
+void SalInfoPrinter::ReleaseGraphics( SalGraphics* )
+{
+ maPrinterData.mbGraphics = FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL SalInfoPrinter::Setup( SalFrame* pFrame, ImplJobSetup* pSetupData )
+{
+ if ( ImplUpdateSalJobSetup( this, pSetupData, TRUE, pFrame ) )
+ {
+ ImplDevModeToJobSetup( this, pSetupData, SAL_JOBSET_ALL );
+ return ImplUpdateSalPrnIC( this, pSetupData );
+ }
+
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL SalInfoPrinter::SetPrinterData( ImplJobSetup* pSetupData )
+{
+ if ( !ImplTestSalJobSetup( this, pSetupData, FALSE ) )
+ return FALSE;
+ return ImplUpdateSalPrnIC( this, pSetupData );
+}
+
+// -----------------------------------------------------------------------
+
+BOOL SalInfoPrinter::SetData( ULONG nFlags, ImplJobSetup* pSetupData )
+{
+ ImplJobSetupToDevMode( this, pSetupData, nFlags );
+ if ( ImplUpdateSalJobSetup( this, pSetupData, TRUE, NULL ) )
+ {
+ ImplDevModeToJobSetup( this, pSetupData, nFlags );
+ return ImplUpdateSalPrnIC( this, pSetupData );
+ }
+
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+ULONG SalInfoPrinter::GetPaperBinCount( const ImplJobSetup* pSetupData )
+{
+ DWORD nRet = ImplDeviceCaps( this, DC_BINS, NULL, pSetupData );
+ if ( nRet && (nRet != ((ULONG)-1)) )
+ return nRet;
+ else
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+XubString SalInfoPrinter::GetPaperBinName( const ImplJobSetup* pSetupData, ULONG nPaperBin )
+{
+// !!! UNICODE - NT Optimierung !!!
+ XubString aPaperBinName;
+
+ DWORD nBins = ImplDeviceCaps( this, DC_BINNAMES, NULL, pSetupData );
+ if ( (nPaperBin < nBins) && (nBins != ((ULONG)-1)) )
+ {
+ char* pBuffer = new char[nBins*24];
+ DWORD nRet = ImplDeviceCaps( this, DC_BINNAMES, pBuffer, pSetupData );
+ if ( nRet && (nRet != ((ULONG)-1)) )
+ aPaperBinName = ImplSalGetUniString( (const char*)(pBuffer + (nPaperBin*24)) );
+ delete pBuffer;
+ }
+
+ return aPaperBinName;
+}
+
+// -----------------------------------------------------------------------
+
+ULONG SalInfoPrinter::GetCapabilities( const ImplJobSetup* pSetupData, USHORT nType )
+{
+ DWORD nRet;
+
+ switch ( nType )
+ {
+ case PRINTER_CAPABILITIES_SUPPORTDIALOG:
+ return TRUE;
+ case PRINTER_CAPABILITIES_COPIES:
+ nRet = ImplDeviceCaps( this, DC_COPIES, NULL, pSetupData );
+ if ( nRet && (nRet != ((ULONG)-1)) )
+ return nRet;
+ return 0;
+ case PRINTER_CAPABILITIES_COLLATECOPIES:
+ if ( aSalShlData.mbW40 )
+ {
+ nRet = ImplDeviceCaps( this, DC_COLLATE, NULL, pSetupData );
+ if ( nRet && (nRet != ((ULONG)-1)) )
+ {
+ nRet = ImplDeviceCaps( this, DC_COPIES, NULL, pSetupData );
+ if ( nRet && (nRet != ((ULONG)-1)) )
+ return nRet;
+ }
+ }
+ return 0;
+
+ case PRINTER_CAPABILITIES_SETORIENTATION:
+ nRet = ImplDeviceCaps( this, DC_ORIENTATION, NULL, pSetupData );
+ if ( nRet && (nRet != ((ULONG)-1)) )
+ return TRUE;
+ return FALSE;
+
+ case PRINTER_CAPABILITIES_SETPAPERBIN:
+ nRet = ImplDeviceCaps( this, DC_BINS, NULL, pSetupData );
+ if ( nRet && (nRet != ((ULONG)-1)) )
+ return TRUE;
+ return FALSE;
+
+ case PRINTER_CAPABILITIES_SETPAPERSIZE:
+ case PRINTER_CAPABILITIES_SETPAPER:
+ nRet = ImplDeviceCaps( this, DC_PAPERS, NULL, pSetupData );
+ if ( nRet && (nRet != ((ULONG)-1)) )
+ return TRUE;
+ return FALSE;
+ }
+
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+void SalInfoPrinter::GetPageInfo( const ImplJobSetup*,
+ long& rOutWidth, long& rOutHeight,
+ long& rPageOffX, long& rPageOffY,
+ long& rPageWidth, long& rPageHeight )
+{
+ HDC hDC = maPrinterData.mhDC;
+
+ rOutWidth = GetDeviceCaps( hDC, HORZRES );
+ rOutHeight = GetDeviceCaps( hDC, VERTRES );
+
+ rPageOffX = GetDeviceCaps( hDC, PHYSICALOFFSETX );
+ rPageOffY = GetDeviceCaps( hDC, PHYSICALOFFSETY );
+ rPageWidth = GetDeviceCaps( hDC, PHYSICALWIDTH );
+ rPageHeight = GetDeviceCaps( hDC, PHYSICALHEIGHT );
+}
+
+// =======================================================================
+
+SalPrinter* SalInstance::CreatePrinter( SalInfoPrinter* pInfoPrinter )
+{
+ SalPrinter* pPrinter = new SalPrinter;
+ pPrinter->maPrinterData.mpInfoPrinter = pInfoPrinter;
+ return pPrinter;
+}
+
+// -----------------------------------------------------------------------
+
+void SalInstance::DestroyPrinter( SalPrinter* pPrinter )
+{
+ delete pPrinter;
+}
+
+// =======================================================================
+
+WIN_BOOL CALLBACK SalPrintAbortProc( HDC hPrnDC, int /* nError */ )
+{
+ SalData* pSalData = GetSalData();
+ SalPrinter* pPrinter;
+ BOOL bWhile = TRUE;
+ int i = 0;
+
+ do
+ {
+ // Messages verarbeiten
+ MSG aMsg;
+ if ( ImplPeekMessage( &aMsg, 0, 0, 0, PM_REMOVE ) )
+ {
+ TranslateMessage( &aMsg );
+ ImplDispatchMessage( &aMsg );
+ i++;
+ if ( i > 15 )
+ bWhile = FALSE;
+ }
+ else
+ bWhile = FALSE;
+
+ pPrinter = pSalData->mpFirstPrinter;
+ while ( pPrinter )
+ {
+ if( pPrinter->maPrinterData.mhDC == hPrnDC )
+ break;
+
+ pPrinter = pPrinter->maPrinterData.mpNextPrinter;
+ }
+
+ if ( !pPrinter || pPrinter->maPrinterData.mbAbort )
+ return FALSE;
+ }
+ while ( bWhile );
+
+ return TRUE;
+}
+
+// -----------------------------------------------------------------------
+
+static LPDEVMODE ImplSalSetCopies( LPDEVMODE pDevMode, ULONG nCopies, BOOL bCollate )
+{
+ LPDEVMODE pNewDevMode = pDevMode;
+ if ( pDevMode && (nCopies > 1) )
+ {
+ if ( nCopies > 32765 )
+ nCopies = 32765;
+ ULONG nDevSize = pDevMode->dmSize+pDevMode->dmDriverExtra;
+ pNewDevMode = (LPDEVMODE)new BYTE[nDevSize];
+ memcpy( pNewDevMode, pDevMode, nDevSize );
+ pDevMode = pNewDevMode;
+ pDevMode->dmFields |= DM_COPIES;
+ pDevMode->dmCopies = (short)(USHORT)nCopies;
+ if ( aSalShlData.mbW40 )
+ {
+ pDevMode->dmFields |= DM_COLLATE;
+ if ( bCollate )
+ pDevMode->dmCollate = DMCOLLATE_TRUE;
+ else
+ pDevMode->dmCollate = DMCOLLATE_FALSE;
+ }
+ }
+
+ return pNewDevMode;
+}
+
+// -----------------------------------------------------------------------
+
+SalPrinter::SalPrinter()
+{
+ SalData* pSalData = GetSalData();
+
+ maPrinterData.mhDC = 0;
+ maPrinterData.mpGraphics = NULL;
+ maPrinterData.mbAbort = FALSE;
+ maPrinterData.mnCopies = 0;
+ maPrinterData.mbCollate = FALSE;
+
+ // insert frame in framelist
+ maPrinterData.mpNextPrinter = pSalData->mpFirstPrinter;
+ pSalData->mpFirstPrinter = this;
+}
+
+// -----------------------------------------------------------------------
+
+SalPrinter::~SalPrinter()
+{
+ SalData* pSalData = GetSalData();
+
+ // DC freigeben, wenn er noch durch ein AbortJob existiert
+ HDC hDC = maPrinterData.mhDC;
+ if ( hDC )
+ {
+ if ( maPrinterData.mpGraphics )
+ {
+ ImplSalDeInitGraphics( &(maPrinterData.mpGraphics->maGraphicsData) );
+ delete maPrinterData.mpGraphics;
+ }
+
+ DeleteDC( hDC );
+ }
+
+ // remove printer from printerlist
+ if ( this == pSalData->mpFirstPrinter )
+ pSalData->mpFirstPrinter = maPrinterData.mpNextPrinter;
+ else
+ {
+ SalPrinter* pTempPrinter = pSalData->mpFirstPrinter;
+
+ while( pTempPrinter->maPrinterData.mpNextPrinter != this )
+ pTempPrinter = pTempPrinter->maPrinterData.mpNextPrinter;
+
+ pTempPrinter->maPrinterData.mpNextPrinter = maPrinterData.mpNextPrinter;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+BOOL SalPrinter::StartJob( const XubString* pFileName,
+ const XubString& rJobName,
+ const XubString&,
+ ULONG nCopies, BOOL bCollate,
+ ImplJobSetup* pSetupData )
+{
+ maPrinterData.mnError = 0;
+ maPrinterData.mbAbort = FALSE;
+ maPrinterData.mnCopies = nCopies;
+ maPrinterData.mbCollate = bCollate;
+
+ LPDEVMODE pOrgDevMode = NULL;
+ LPDEVMODE pDevMode;
+ BOOL bOwnDevMode = FALSE;
+ if ( pSetupData && pSetupData->mpDriverData )
+ {
+ pOrgDevMode = SAL_DEVMODE( pSetupData );
+ pDevMode = ImplSalSetCopies( pOrgDevMode, nCopies, bCollate );
+ }
+ else
+ pDevMode = NULL;
+
+// !!! UNICODE - NT Optimierung !!!
+ HDC hDC = CreateDCA( ImplSalGetWinAnsiString( maPrinterData.mpInfoPrinter->maPrinterData.maDriverName, TRUE ).GetBuffer(),
+ ImplSalGetWinAnsiString( maPrinterData.mpInfoPrinter->maPrinterData.maDeviceName, TRUE ).GetBuffer(),
+ 0,
+ (LPDEVMODEA)pDevMode );
+
+ if ( pDevMode != pOrgDevMode )
+ delete pDevMode;
+
+ if ( !hDC )
+ {
+ maPrinterData.mnError = SAL_PRINTER_ERROR_GENERALERROR;
+ return FALSE;
+ }
+
+ if ( SetAbortProc( hDC, SalPrintAbortProc ) <= 0 )
+ {
+ maPrinterData.mnError = SAL_PRINTER_ERROR_GENERALERROR;
+ return FALSE;
+ }
+
+ maPrinterData.mnError = 0;
+ maPrinterData.mbAbort = FALSE;
+
+// !!! UNICODE - NT Optimierung !!!
+ // Both strings must be exist, if StartJob() is called
+ ByteString aJobName( ImplSalGetWinAnsiString( rJobName, TRUE ) );
+ ByteString aFileName;
+
+ DOCINFO aInfo;
+ memset( &aInfo, 0, sizeof( DOCINFO ) );
+ aInfo.cbSize = sizeof( aInfo );
+ aInfo.lpszDocName = (LPCSTR)aJobName.GetBuffer();
+ if ( pFileName )
+ {
+ if ( pFileName->Len() )
+ {
+ aFileName = ImplSalGetWinAnsiString( *pFileName, TRUE );
+ aInfo.lpszOutput = (LPCSTR)aFileName.GetBuffer();
+ }
+ else
+ aInfo.lpszOutput = "FILE:";
+ }
+ else
+ aInfo.lpszOutput = NULL;
+
+ // Wegen Telocom Balloon Fax-Treiber, der uns unsere Messages
+ // ansonsten oefters schickt, versuchen wir vorher alle
+ // zu verarbeiten und dann eine Dummy-Message reinstellen
+ BOOL bWhile = TRUE;
+ int i = 0;
+ do
+ {
+ // Messages verarbeiten
+ MSG aMsg;
+ if ( ImplPeekMessage( &aMsg, 0, 0, 0, PM_REMOVE ) )
+ {
+ TranslateMessage( &aMsg );
+ ImplDispatchMessage( &aMsg );
+ i++;
+ if ( i > 15 )
+ bWhile = FALSE;
+ }
+ else
+ bWhile = FALSE;
+ }
+ while ( bWhile );
+ ImplPostMessage( GetSalData()->mpFirstInstance->maInstData.mhComWnd, SAL_MSG_DUMMY, 0, 0 );
+
+ // Job starten
+ int nRet = ::StartDoc( hDC, &aInfo );
+ if ( nRet <= 0 )
+ {
+ if ( (nRet == SP_USERABORT) || (nRet == SP_APPABORT) || (GetLastError() == ERROR_PRINT_CANCELLED) )
+ maPrinterData.mnError = SAL_PRINTER_ERROR_ABORT;
+ else
+ maPrinterData.mnError = SAL_PRINTER_ERROR_GENERALERROR;
+ return FALSE;
+ }
+
+ maPrinterData.mhDC = hDC;
+ return TRUE;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL SalPrinter::EndJob()
+{
+ HDC hDC = maPrinterData.mhDC;
+ if ( hDC )
+ {
+ if ( maPrinterData.mpGraphics )
+ {
+ ImplSalDeInitGraphics( &(maPrinterData.mpGraphics->maGraphicsData) );
+ delete maPrinterData.mpGraphics;
+ maPrinterData.mpGraphics = NULL;
+ }
+
+ ::EndDoc( hDC );
+ DeleteDC( hDC );
+ }
+
+ return TRUE;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL SalPrinter::AbortJob()
+{
+ maPrinterData.mbAbort = TRUE;
+
+ // Abort asyncron ausloesen
+ HDC hDC = maPrinterData.mhDC;
+ if ( hDC )
+ {
+ SalData* pSalData = GetSalData();
+ ImplPostMessage( pSalData->mpFirstInstance->maInstData.mhComWnd,
+ SAL_MSG_PRINTABORTJOB, (WPARAM)hDC, 0 );
+ }
+
+ return TRUE;
+}
+
+// -----------------------------------------------------------------------
+
+void ImplSalPrinterAbortJobAsync( HDC hPrnDC )
+{
+ SalData* pSalData = GetSalData();
+ SalPrinter* pPrinter = pSalData->mpFirstPrinter;
+
+ // Feststellen, ob Printer noch existiert
+ while ( pPrinter )
+ {
+ if ( pPrinter->maPrinterData.mhDC == hPrnDC )
+ break;
+
+ pPrinter = pPrinter->maPrinterData.mpNextPrinter;
+ }
+
+ // Wenn Printer noch existiert, dann den Job abbrechen
+ if ( pPrinter )
+ {
+ HDC hDC = pPrinter->maPrinterData.mhDC;
+ if ( hDC )
+ {
+ if ( pPrinter->maPrinterData.mpGraphics )
+ {
+ ImplSalDeInitGraphics( &(pPrinter->maPrinterData.mpGraphics->maGraphicsData) );
+ delete pPrinter->maPrinterData.mpGraphics;
+ pPrinter->maPrinterData.mpGraphics = NULL;
+ }
+
+ ::AbortDoc( hDC );
+ DeleteDC( hDC );
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+SalGraphics* SalPrinter::StartPage( ImplJobSetup* pSetupData, BOOL bNewJobData )
+{
+ HDC hDC = maPrinterData.mhDC;
+ if ( pSetupData && pSetupData->mpDriverData && bNewJobData )
+ {
+ LPDEVMODE pOrgDevMode;
+ LPDEVMODE pDevMode;
+ pOrgDevMode = SAL_DEVMODE( pSetupData );
+ pDevMode = ImplSalSetCopies( pOrgDevMode, maPrinterData.mnCopies, maPrinterData.mbCollate );
+ ResetDC( hDC, pDevMode );
+ if ( pDevMode != pOrgDevMode )
+ delete pDevMode;
+ }
+ int nRet = ::StartPage( hDC );
+ if ( nRet <= 0 )
+ {
+ maPrinterData.mnError = SAL_PRINTER_ERROR_GENERALERROR;
+ return NULL;
+ }
+
+ // Hack, damit alte PS-Treiber Leerseiten nicht wegoptimieren
+ HPEN hTempPen = SelectPen( hDC, GetStockPen( NULL_PEN ) );
+ HBRUSH hTempBrush = SelectBrush( hDC, GetStockBrush( NULL_BRUSH ) );
+ WIN_Rectangle( hDC, -8000, -8000, -7999, -7999 );
+ SelectPen( hDC, hTempPen );
+ SelectBrush( hDC, hTempBrush );
+
+ SalGraphics* pGraphics = new SalGraphics;
+ pGraphics->maGraphicsData.mhDC = hDC;
+ pGraphics->maGraphicsData.mhWnd = 0;
+ pGraphics->maGraphicsData.mbPrinter = TRUE;
+ pGraphics->maGraphicsData.mbVirDev = FALSE;
+ pGraphics->maGraphicsData.mbWindow = FALSE;
+ pGraphics->maGraphicsData.mbScreen = FALSE;
+ ImplSalInitGraphics( &(pGraphics->maGraphicsData) );
+ maPrinterData.mpGraphics = pGraphics;
+ return pGraphics;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL SalPrinter::EndPage()
+{
+ HDC hDC = maPrinterData.mhDC;
+ if ( hDC && maPrinterData.mpGraphics )
+ {
+ ImplSalDeInitGraphics( &(maPrinterData.mpGraphics->maGraphicsData) );
+ delete maPrinterData.mpGraphics;
+ maPrinterData.mpGraphics = NULL;
+ }
+ int nRet = ::EndPage( hDC );
+ if ( nRet > 0 )
+ return TRUE;
+ else
+ {
+ maPrinterData.mnError = SAL_PRINTER_ERROR_GENERALERROR;
+ return FALSE;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+ULONG SalPrinter::GetErrorCode()
+{
+ return maPrinterData.mnError;
+}
diff --git a/vcl/win/source/gdi/salvd.cxx b/vcl/win/source/gdi/salvd.cxx
new file mode 100644
index 000000000000..d9f79ce479a8
--- /dev/null
+++ b/vcl/win/source/gdi/salvd.cxx
@@ -0,0 +1,226 @@
+/*************************************************************************
+ *
+ * $RCSfile: salvd.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:49 $
+ *
+ * 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 _SVWIN_H
+#include <tools/svwin.h>
+#endif
+
+#define _SV_SALVD_CXX
+
+#ifndef _SV_WINCOMP_HXX
+#include <wincomp.hxx>
+#endif
+#ifndef _SV_SALDATA_HXX
+#include <saldata.hxx>
+#endif
+#ifndef _SV_SALINST_HXX
+#include <salinst.hxx>
+#endif
+#ifndef _SV_SALGDI_HXX
+#include <salgdi.hxx>
+#endif
+#ifndef _SV_SALVD_HXX
+#include <salvd.hxx>
+#endif
+
+// =======================================================================
+
+static HBITMAP ImplCreateVirDevBitmap( HDC hDC, long nDX, long nDY,
+ USHORT nBitCount )
+{
+ HBITMAP hBitmap;
+
+ if ( nBitCount == 1 )
+ hBitmap = CreateBitmap( (int)nDX, (int)nDY, 1, 1, NULL );
+ else
+ hBitmap = CreateCompatibleBitmap( hDC, (int)nDX, (int)nDY );
+
+ return hBitmap;
+}
+
+// =======================================================================
+
+SalVirtualDevice* SalInstance::CreateVirtualDevice( SalGraphics* pGraphics,
+ long nDX, long nDY,
+ USHORT nBitCount )
+{
+ HDC hDC = CreateCompatibleDC( pGraphics->maGraphicsData.mhDC );
+ HBITMAP hBmp = ImplCreateVirDevBitmap( pGraphics->maGraphicsData.mhDC,
+ nDX, nDY, nBitCount );
+
+ if ( hDC && hBmp )
+ {
+ SalVirtualDevice* pVDev = new SalVirtualDevice;
+ SalData* pSalData = GetSalData();
+ SalGraphics* pVirGraphics = new SalGraphics;
+ pVirGraphics->maGraphicsData.mhDC = hDC;
+ pVirGraphics->maGraphicsData.mhWnd = 0;
+ pVirGraphics->maGraphicsData.mbPrinter = FALSE;
+ pVirGraphics->maGraphicsData.mbVirDev = TRUE;
+ pVirGraphics->maGraphicsData.mbWindow = FALSE;
+ pVirGraphics->maGraphicsData.mbScreen = pGraphics->maGraphicsData.mbScreen;
+ if ( pSalData->mhDitherPal && pVirGraphics->maGraphicsData.mbScreen )
+ {
+ pVirGraphics->maGraphicsData.mhDefPal = SelectPalette( hDC, pSalData->mhDitherPal, TRUE );
+ RealizePalette( hDC );
+ }
+ ImplSalInitGraphics( &(pVirGraphics->maGraphicsData) );
+
+ pVDev->maVirDevData.mhDC = hDC;
+ pVDev->maVirDevData.mhBmp = hBmp;
+ pVDev->maVirDevData.mhDefBmp = SelectBitmap( hDC, hBmp );
+ pVDev->maVirDevData.mpGraphics = pVirGraphics;
+ pVDev->maVirDevData.mnBitCount = nBitCount;
+ pVDev->maVirDevData.mbGraphics = FALSE;
+
+ // insert VirDev in VirDevList
+ pVDev->maVirDevData.mpNext = pSalData->mpFirstVD;
+ pSalData->mpFirstVD = pVDev;
+
+ return pVDev;
+ }
+ else
+ {
+ if ( hDC )
+ DeleteDC( hDC );
+ if ( hBmp )
+ DeleteBitmap( hBmp );
+ return NULL;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void SalInstance::DestroyVirtualDevice( SalVirtualDevice* pDevice )
+{
+ delete pDevice;
+}
+
+// =======================================================================
+
+SalVirtualDevice::SalVirtualDevice()
+{
+}
+
+// -----------------------------------------------------------------------
+
+SalVirtualDevice::~SalVirtualDevice()
+{
+ SalData* pSalData = GetSalData();
+
+ // destroy saved DC
+ if ( maVirDevData.mpGraphics->maGraphicsData.mhDefPal )
+ SelectPalette( maVirDevData.mpGraphics->maGraphicsData.mhDC, maVirDevData.mpGraphics->maGraphicsData.mhDefPal, TRUE );
+ ImplSalDeInitGraphics( &(maVirDevData.mpGraphics->maGraphicsData) );
+ SelectBitmap( maVirDevData.mpGraphics->maGraphicsData.mhDC, maVirDevData.mhDefBmp );
+ DeleteDC( maVirDevData.mpGraphics->maGraphicsData.mhDC );
+ DeleteBitmap( maVirDevData.mhBmp );
+ delete maVirDevData.mpGraphics;
+
+ // remove VirDev from VirDevList
+ if ( this == pSalData->mpFirstVD )
+ pSalData->mpFirstVD = maVirDevData.mpNext;
+ else
+ {
+ SalVirtualDevice* pTempVD = pSalData->mpFirstVD;
+ while ( pTempVD->maVirDevData.mpNext != this )
+ pTempVD = pTempVD->maVirDevData.mpNext;
+
+ pTempVD->maVirDevData.mpNext = maVirDevData.mpNext;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+SalGraphics* SalVirtualDevice::GetGraphics()
+{
+ if ( maVirDevData.mbGraphics )
+ return NULL;
+
+ if ( maVirDevData.mpGraphics )
+ maVirDevData.mbGraphics = TRUE;
+
+ return maVirDevData.mpGraphics;
+}
+
+// -----------------------------------------------------------------------
+
+void SalVirtualDevice::ReleaseGraphics( SalGraphics* )
+{
+ maVirDevData.mbGraphics = FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL SalVirtualDevice::SetSize( long nDX, long nDY )
+{
+ HBITMAP hNewBmp = ImplCreateVirDevBitmap( maVirDevData.mhDC, nDX, nDY,
+ maVirDevData.mnBitCount );
+ if ( hNewBmp )
+ {
+ SelectBitmap( maVirDevData.mhDC, hNewBmp );
+ DeleteBitmap( maVirDevData.mhBmp );
+ maVirDevData.mhBmp = hNewBmp;
+ return TRUE;
+ }
+ else
+ return FALSE;
+}
diff --git a/vcl/win/source/gdi/wntgdi.cxx b/vcl/win/source/gdi/wntgdi.cxx
new file mode 100644
index 000000000000..0bd7751c97e9
--- /dev/null
+++ b/vcl/win/source/gdi/wntgdi.cxx
@@ -0,0 +1,92 @@
+/*************************************************************************
+ *
+ * $RCSfile: wntgdi.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:49 $
+ *
+ * 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 <windows.h>
+
+// -----------------------------------------------------------------------
+
+extern "C"
+{
+BOOL WINAPI WIN_Rectangle( HDC hDC, int X1, int Y1, int X2, int Y2 )
+{
+ return Rectangle( hDC, X1, Y1, X2, Y2 );
+}
+}
+
+// -----------------------------------------------------------------------
+
+extern "C"
+{
+BOOL WINAPI WIN_Polygon( HDC hDC, CONST POINT * ppt, int ncnt )
+{
+ return Polygon( hDC, ppt, ncnt );
+}
+}
+
+// -----------------------------------------------------------------------
+
+extern "C"
+{
+BOOL WINAPI WIN_PolyPolygon( HDC hDC, CONST POINT * ppt, LPINT npcnt, int ncnt )
+{
+ return PolyPolygon( hDC, ppt, npcnt, ncnt );
+}
+}
diff --git a/vcl/win/source/src/50.bmp b/vcl/win/source/src/50.bmp
new file mode 100644
index 000000000000..b9d56fcd14c1
--- /dev/null
+++ b/vcl/win/source/src/50.bmp
Binary files differ
diff --git a/vcl/win/source/src/MAKEFILE.MK b/vcl/win/source/src/MAKEFILE.MK
new file mode 100644
index 000000000000..463741b23bb7
--- /dev/null
+++ b/vcl/win/source/src/MAKEFILE.MK
@@ -0,0 +1,106 @@
+#*************************************************************************
+#*
+#* $Workfile: makefile. $
+#*
+#* Ersterstellung TH 01.04.97
+#* Letzte Aenderung $Author: hr $ $Date: 2000-09-18 17:05:49 $
+#* $Revision: 1.1.1.1 $
+#*
+#* $Logfile: T:/vcl/win/source/src/makefile.__v $
+#*
+#* Copyright (c) 1990 - 2000, STAR DIVISION
+#*
+#*************************************************************************
+
+PRJ=..$/..$/..
+
+PRJNAME=vcl
+TARGET=salsrc
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : svpre.mk
+.INCLUDE : settings.mk
+.INCLUDE : sv.mk
+
+# --- Files --------------------------------------------------------
+
+RCDEPN= nullptr.cur \
+ help.cur \
+ hsize.cur \
+ vsize.cur \
+ neswsize.cur \
+ nwsesize.cur \
+ cross.cur \
+ move.cur \
+ hsplit.cur \
+ vsplit.cur \
+ hsizebar.cur \
+ vsizebar.cur \
+ hand.cur \
+ refhand.cur \
+ pen.cur \
+ magnify.cur \
+ fill.cur \
+ rotate.cur \
+ hshear.cur \
+ vshear.cur \
+ mirror.cur \
+ crook.cur \
+ crop.cur \
+ movept.cur \
+ movebw.cur \
+ movedata.cur \
+ copydata.cur \
+ linkdata.cur \
+ movedlnk.cur \
+ copydlnk.cur \
+ movef.cur \
+ copyf.cur \
+ linkf.cur \
+ moveflnk.cur \
+ copyflnk.cur \
+ movef2.cur \
+ copyf2.cur \
+ notallow.cur \
+ dline.cur \
+ drect.cur \
+ dpolygon.cur \
+ dbezier.cur \
+ darc.cur \
+ dpie.cur \
+ dcirccut.cur \
+ dellipse.cur \
+ dfree.cur \
+ dconnect.cur \
+ dtext.cur \
+ dcapt.cur \
+ chart.cur \
+ detectiv.cur \
+ pivotcol.cur \
+ pivotrow.cur \
+ pivotfld.cur \
+ chain.cur \
+ chainnot.cur \
+ timemove.cur \
+ timesize.cur \
+ asn.cur \
+ ass.cur \
+ asw.cur \
+ ase.cur \
+ asnw.cur \
+ asne.cur \
+ assw.cur \
+ asse.cur \
+ asns.cur \
+ aswe.cur \
+ asnswe.cur \
+ airbrush.cur \
+ 50.bmp \
+ sd.ico
+
+RCFILES= salsrc.rc
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
diff --git a/vcl/win/source/src/airbrush.cur b/vcl/win/source/src/airbrush.cur
new file mode 100644
index 000000000000..f6a684e6fcbd
--- /dev/null
+++ b/vcl/win/source/src/airbrush.cur
Binary files differ
diff --git a/vcl/win/source/src/ase.cur b/vcl/win/source/src/ase.cur
new file mode 100755
index 000000000000..7634a7d34a7b
--- /dev/null
+++ b/vcl/win/source/src/ase.cur
Binary files differ
diff --git a/vcl/win/source/src/asn.cur b/vcl/win/source/src/asn.cur
new file mode 100755
index 000000000000..e444e42bf37e
--- /dev/null
+++ b/vcl/win/source/src/asn.cur
Binary files differ
diff --git a/vcl/win/source/src/asne.cur b/vcl/win/source/src/asne.cur
new file mode 100755
index 000000000000..e92cc65e7eb1
--- /dev/null
+++ b/vcl/win/source/src/asne.cur
Binary files differ
diff --git a/vcl/win/source/src/asns.cur b/vcl/win/source/src/asns.cur
new file mode 100755
index 000000000000..04d0b09c353e
--- /dev/null
+++ b/vcl/win/source/src/asns.cur
Binary files differ
diff --git a/vcl/win/source/src/asnswe.cur b/vcl/win/source/src/asnswe.cur
new file mode 100755
index 000000000000..a0e25b16de1f
--- /dev/null
+++ b/vcl/win/source/src/asnswe.cur
Binary files differ
diff --git a/vcl/win/source/src/asnw.cur b/vcl/win/source/src/asnw.cur
new file mode 100755
index 000000000000..20322bc97b16
--- /dev/null
+++ b/vcl/win/source/src/asnw.cur
Binary files differ
diff --git a/vcl/win/source/src/ass.cur b/vcl/win/source/src/ass.cur
new file mode 100755
index 000000000000..7166636a1a77
--- /dev/null
+++ b/vcl/win/source/src/ass.cur
Binary files differ
diff --git a/vcl/win/source/src/asse.cur b/vcl/win/source/src/asse.cur
new file mode 100755
index 000000000000..8cb71234b0a9
--- /dev/null
+++ b/vcl/win/source/src/asse.cur
Binary files differ
diff --git a/vcl/win/source/src/assw.cur b/vcl/win/source/src/assw.cur
new file mode 100755
index 000000000000..fddaf3f57cbf
--- /dev/null
+++ b/vcl/win/source/src/assw.cur
Binary files differ
diff --git a/vcl/win/source/src/asw.cur b/vcl/win/source/src/asw.cur
new file mode 100755
index 000000000000..0ccac50f4596
--- /dev/null
+++ b/vcl/win/source/src/asw.cur
Binary files differ
diff --git a/vcl/win/source/src/aswe.cur b/vcl/win/source/src/aswe.cur
new file mode 100755
index 000000000000..c238b7e10aef
--- /dev/null
+++ b/vcl/win/source/src/aswe.cur
Binary files differ
diff --git a/vcl/win/source/src/chain.cur b/vcl/win/source/src/chain.cur
new file mode 100755
index 000000000000..02abb7ab714f
--- /dev/null
+++ b/vcl/win/source/src/chain.cur
Binary files differ
diff --git a/vcl/win/source/src/chainnot.cur b/vcl/win/source/src/chainnot.cur
new file mode 100755
index 000000000000..938ece03f329
--- /dev/null
+++ b/vcl/win/source/src/chainnot.cur
Binary files differ
diff --git a/vcl/win/source/src/chart.cur b/vcl/win/source/src/chart.cur
new file mode 100644
index 000000000000..25fe85b76039
--- /dev/null
+++ b/vcl/win/source/src/chart.cur
Binary files differ
diff --git a/vcl/win/source/src/copydata.cur b/vcl/win/source/src/copydata.cur
new file mode 100644
index 000000000000..d3c4bc93afd5
--- /dev/null
+++ b/vcl/win/source/src/copydata.cur
Binary files differ
diff --git a/vcl/win/source/src/copydlnk.cur b/vcl/win/source/src/copydlnk.cur
new file mode 100644
index 000000000000..495fd5e17776
--- /dev/null
+++ b/vcl/win/source/src/copydlnk.cur
Binary files differ
diff --git a/vcl/win/source/src/copyf.cur b/vcl/win/source/src/copyf.cur
new file mode 100644
index 000000000000..450c09443a84
--- /dev/null
+++ b/vcl/win/source/src/copyf.cur
Binary files differ
diff --git a/vcl/win/source/src/copyf2.cur b/vcl/win/source/src/copyf2.cur
new file mode 100644
index 000000000000..ac8de5da6ba5
--- /dev/null
+++ b/vcl/win/source/src/copyf2.cur
Binary files differ
diff --git a/vcl/win/source/src/copyflnk.cur b/vcl/win/source/src/copyflnk.cur
new file mode 100644
index 000000000000..e67f0539fa43
--- /dev/null
+++ b/vcl/win/source/src/copyflnk.cur
Binary files differ
diff --git a/vcl/win/source/src/crook.cur b/vcl/win/source/src/crook.cur
new file mode 100644
index 000000000000..c40cf591e261
--- /dev/null
+++ b/vcl/win/source/src/crook.cur
Binary files differ
diff --git a/vcl/win/source/src/crop.cur b/vcl/win/source/src/crop.cur
new file mode 100644
index 000000000000..327fb06976c2
--- /dev/null
+++ b/vcl/win/source/src/crop.cur
Binary files differ
diff --git a/vcl/win/source/src/cross.cur b/vcl/win/source/src/cross.cur
new file mode 100644
index 000000000000..8fd9762386b1
--- /dev/null
+++ b/vcl/win/source/src/cross.cur
Binary files differ
diff --git a/vcl/win/source/src/darc.cur b/vcl/win/source/src/darc.cur
new file mode 100644
index 000000000000..38504fa23c4a
--- /dev/null
+++ b/vcl/win/source/src/darc.cur
Binary files differ
diff --git a/vcl/win/source/src/dbezier.cur b/vcl/win/source/src/dbezier.cur
new file mode 100644
index 000000000000..f630b837ddf8
--- /dev/null
+++ b/vcl/win/source/src/dbezier.cur
Binary files differ
diff --git a/vcl/win/source/src/dcapt.cur b/vcl/win/source/src/dcapt.cur
new file mode 100644
index 000000000000..10dd5ba0d676
--- /dev/null
+++ b/vcl/win/source/src/dcapt.cur
Binary files differ
diff --git a/vcl/win/source/src/dcirccut.cur b/vcl/win/source/src/dcirccut.cur
new file mode 100644
index 000000000000..b19d3f8257f4
--- /dev/null
+++ b/vcl/win/source/src/dcirccut.cur
Binary files differ
diff --git a/vcl/win/source/src/dconnect.cur b/vcl/win/source/src/dconnect.cur
new file mode 100644
index 000000000000..5318d8f22d8b
--- /dev/null
+++ b/vcl/win/source/src/dconnect.cur
Binary files differ
diff --git a/vcl/win/source/src/dellipse.cur b/vcl/win/source/src/dellipse.cur
new file mode 100644
index 000000000000..c489a640335e
--- /dev/null
+++ b/vcl/win/source/src/dellipse.cur
Binary files differ
diff --git a/vcl/win/source/src/detectiv.cur b/vcl/win/source/src/detectiv.cur
new file mode 100644
index 000000000000..30e5685b64b2
--- /dev/null
+++ b/vcl/win/source/src/detectiv.cur
Binary files differ
diff --git a/vcl/win/source/src/dfree.cur b/vcl/win/source/src/dfree.cur
new file mode 100644
index 000000000000..3ff56d007648
--- /dev/null
+++ b/vcl/win/source/src/dfree.cur
Binary files differ
diff --git a/vcl/win/source/src/dline.cur b/vcl/win/source/src/dline.cur
new file mode 100644
index 000000000000..623c33ac2351
--- /dev/null
+++ b/vcl/win/source/src/dline.cur
Binary files differ
diff --git a/vcl/win/source/src/dpie.cur b/vcl/win/source/src/dpie.cur
new file mode 100644
index 000000000000..3b911cd01e43
--- /dev/null
+++ b/vcl/win/source/src/dpie.cur
Binary files differ
diff --git a/vcl/win/source/src/dpolygon.cur b/vcl/win/source/src/dpolygon.cur
new file mode 100644
index 000000000000..9467f1e286aa
--- /dev/null
+++ b/vcl/win/source/src/dpolygon.cur
Binary files differ
diff --git a/vcl/win/source/src/drect.cur b/vcl/win/source/src/drect.cur
new file mode 100644
index 000000000000..60a5242c203c
--- /dev/null
+++ b/vcl/win/source/src/drect.cur
Binary files differ
diff --git a/vcl/win/source/src/dtext.cur b/vcl/win/source/src/dtext.cur
new file mode 100644
index 000000000000..01e7d31eae7e
--- /dev/null
+++ b/vcl/win/source/src/dtext.cur
Binary files differ
diff --git a/vcl/win/source/src/fill.cur b/vcl/win/source/src/fill.cur
new file mode 100644
index 000000000000..78f5fad87ad0
--- /dev/null
+++ b/vcl/win/source/src/fill.cur
Binary files differ
diff --git a/vcl/win/source/src/hand.cur b/vcl/win/source/src/hand.cur
new file mode 100644
index 000000000000..fc0e53b474e2
--- /dev/null
+++ b/vcl/win/source/src/hand.cur
Binary files differ
diff --git a/vcl/win/source/src/help.cur b/vcl/win/source/src/help.cur
new file mode 100644
index 000000000000..e59ee97992b3
--- /dev/null
+++ b/vcl/win/source/src/help.cur
Binary files differ
diff --git a/vcl/win/source/src/hshear.cur b/vcl/win/source/src/hshear.cur
new file mode 100644
index 000000000000..5cf2211458c3
--- /dev/null
+++ b/vcl/win/source/src/hshear.cur
Binary files differ
diff --git a/vcl/win/source/src/hsize.cur b/vcl/win/source/src/hsize.cur
new file mode 100644
index 000000000000..571dd0ef703c
--- /dev/null
+++ b/vcl/win/source/src/hsize.cur
Binary files differ
diff --git a/vcl/win/source/src/hsizebar.cur b/vcl/win/source/src/hsizebar.cur
new file mode 100644
index 000000000000..dda3483bb5d4
--- /dev/null
+++ b/vcl/win/source/src/hsizebar.cur
Binary files differ
diff --git a/vcl/win/source/src/hsplit.cur b/vcl/win/source/src/hsplit.cur
new file mode 100644
index 000000000000..f2f0be363d3a
--- /dev/null
+++ b/vcl/win/source/src/hsplit.cur
Binary files differ
diff --git a/vcl/win/source/src/linkdata.cur b/vcl/win/source/src/linkdata.cur
new file mode 100644
index 000000000000..e47c1dea2cec
--- /dev/null
+++ b/vcl/win/source/src/linkdata.cur
Binary files differ
diff --git a/vcl/win/source/src/linkf.cur b/vcl/win/source/src/linkf.cur
new file mode 100644
index 000000000000..6cc498a02610
--- /dev/null
+++ b/vcl/win/source/src/linkf.cur
Binary files differ
diff --git a/vcl/win/source/src/mirror.cur b/vcl/win/source/src/mirror.cur
new file mode 100644
index 000000000000..e05eb836eb5d
--- /dev/null
+++ b/vcl/win/source/src/mirror.cur
Binary files differ
diff --git a/vcl/win/source/src/move.cur b/vcl/win/source/src/move.cur
new file mode 100644
index 000000000000..a407a1298ad5
--- /dev/null
+++ b/vcl/win/source/src/move.cur
Binary files differ
diff --git a/vcl/win/source/src/movebw.cur b/vcl/win/source/src/movebw.cur
new file mode 100644
index 000000000000..d079eb9fe20d
--- /dev/null
+++ b/vcl/win/source/src/movebw.cur
Binary files differ
diff --git a/vcl/win/source/src/movedata.cur b/vcl/win/source/src/movedata.cur
new file mode 100644
index 000000000000..4d67cbe47149
--- /dev/null
+++ b/vcl/win/source/src/movedata.cur
Binary files differ
diff --git a/vcl/win/source/src/movedlnk.cur b/vcl/win/source/src/movedlnk.cur
new file mode 100644
index 000000000000..1bb7b0306406
--- /dev/null
+++ b/vcl/win/source/src/movedlnk.cur
Binary files differ
diff --git a/vcl/win/source/src/movef.cur b/vcl/win/source/src/movef.cur
new file mode 100644
index 000000000000..6abee2381dcf
--- /dev/null
+++ b/vcl/win/source/src/movef.cur
Binary files differ
diff --git a/vcl/win/source/src/movef2.cur b/vcl/win/source/src/movef2.cur
new file mode 100644
index 000000000000..d044981a3ffd
--- /dev/null
+++ b/vcl/win/source/src/movef2.cur
Binary files differ
diff --git a/vcl/win/source/src/moveflnk.cur b/vcl/win/source/src/moveflnk.cur
new file mode 100644
index 000000000000..630fa1bc3e4e
--- /dev/null
+++ b/vcl/win/source/src/moveflnk.cur
Binary files differ
diff --git a/vcl/win/source/src/movept.cur b/vcl/win/source/src/movept.cur
new file mode 100644
index 000000000000..81d3af5a05c4
--- /dev/null
+++ b/vcl/win/source/src/movept.cur
Binary files differ
diff --git a/vcl/win/source/src/neswsize.cur b/vcl/win/source/src/neswsize.cur
new file mode 100644
index 000000000000..c38501ee15a8
--- /dev/null
+++ b/vcl/win/source/src/neswsize.cur
Binary files differ
diff --git a/vcl/win/source/src/notallow.cur b/vcl/win/source/src/notallow.cur
new file mode 100644
index 000000000000..90c1dfbb3a97
--- /dev/null
+++ b/vcl/win/source/src/notallow.cur
Binary files differ
diff --git a/vcl/win/source/src/nullptr.cur b/vcl/win/source/src/nullptr.cur
new file mode 100644
index 000000000000..28dbb2a903f2
--- /dev/null
+++ b/vcl/win/source/src/nullptr.cur
Binary files differ
diff --git a/vcl/win/source/src/nwsesize.cur b/vcl/win/source/src/nwsesize.cur
new file mode 100644
index 000000000000..570cbbb571cc
--- /dev/null
+++ b/vcl/win/source/src/nwsesize.cur
Binary files differ
diff --git a/vcl/win/source/src/pen.cur b/vcl/win/source/src/pen.cur
new file mode 100644
index 000000000000..040c5dc703e9
--- /dev/null
+++ b/vcl/win/source/src/pen.cur
Binary files differ
diff --git a/vcl/win/source/src/refhand.cur b/vcl/win/source/src/refhand.cur
new file mode 100644
index 000000000000..a654974c6f8b
--- /dev/null
+++ b/vcl/win/source/src/refhand.cur
Binary files differ
diff --git a/vcl/win/source/src/rotate.cur b/vcl/win/source/src/rotate.cur
new file mode 100644
index 000000000000..43c2a54a10ac
--- /dev/null
+++ b/vcl/win/source/src/rotate.cur
Binary files differ
diff --git a/vcl/win/source/src/salsrc.rc b/vcl/win/source/src/salsrc.rc
new file mode 100644
index 000000000000..d7785d3ee734
--- /dev/null
+++ b/vcl/win/source/src/salsrc.rc
@@ -0,0 +1,148 @@
+/*************************************************************************
+*
+* $RCSfile: salsrc.rc,v $
+*
+* $Revision: 1.1.1.1 $
+*
+* last change: $Author: hr $ $Date: 2000-09-18 17:05:50 $
+*
+* 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 WARRUNTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING,
+* WITHOUT LIMITATION, WARRUNTIES 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): _______________________________________
+*
+*
+*
+**************************************************************************/
+
+// for WINVER
+#include <windows.h>
+
+#ifndef _SV_SALIDS_HRC
+#include <salids.hrc>
+#endif
+
+SAL_RESID_POINTER_NULL CURSOR NULLPTR.CUR
+#if ( WINVER < 0x0400 )
+SAL_RESID_POINTER_HELP CURSOR HELP.CUR
+#endif
+#ifndef WNT
+SAL_RESID_POINTER_HSIZE CURSOR HSIZE.CUR
+SAL_RESID_POINTER_VSIZE CURSOR VSIZE.CUR
+SAL_RESID_POINTER_NESWSIZE CURSOR NESWSIZE.CUR
+SAL_RESID_POINTER_NWSESIZE CURSOR NWSESIZE.CUR
+#endif
+SAL_RESID_POINTER_CROSS CURSOR CROSS.CUR
+SAL_RESID_POINTER_MOVE CURSOR MOVE.CUR
+SAL_RESID_POINTER_HSPLIT CURSOR HSPLIT.CUR
+SAL_RESID_POINTER_VSPLIT CURSOR VSPLIT.CUR
+SAL_RESID_POINTER_HSIZEBAR CURSOR HSIZEBAR.CUR
+SAL_RESID_POINTER_VSIZEBAR CURSOR VSIZEBAR.CUR
+SAL_RESID_POINTER_HAND CURSOR HAND.CUR
+SAL_RESID_POINTER_REFHAND CURSOR REFHAND.CUR
+SAL_RESID_POINTER_PEN CURSOR PEN.CUR
+SAL_RESID_POINTER_MAGNIFY CURSOR MAGNIFY.CUR
+SAL_RESID_POINTER_FILL CURSOR FILL.CUR
+SAL_RESID_POINTER_ROTATE CURSOR ROTATE.CUR
+SAL_RESID_POINTER_HSHEAR CURSOR HSHEAR.CUR
+SAL_RESID_POINTER_VSHEAR CURSOR VSHEAR.CUR
+SAL_RESID_POINTER_MIRROR CURSOR MIRROR.CUR
+SAL_RESID_POINTER_CROOK CURSOR CROOK.CUR
+SAL_RESID_POINTER_CROP CURSOR CROP.CUR
+SAL_RESID_POINTER_MOVEPOINT CURSOR MOVEPT.CUR
+SAL_RESID_POINTER_MOVEBEZIERWEIGHT CURSOR MOVEBW.CUR
+SAL_RESID_POINTER_MOVEDATA CURSOR MOVEDATA.CUR
+SAL_RESID_POINTER_COPYDATA CURSOR COPYDATA.CUR
+SAL_RESID_POINTER_LINKDATA CURSOR LINKDATA.CUR
+SAL_RESID_POINTER_MOVEDATALINK CURSOR MOVEDLNK.CUR
+SAL_RESID_POINTER_COPYDATALINK CURSOR COPYDLNK.CUR
+SAL_RESID_POINTER_MOVEFILE CURSOR MOVEF.CUR
+SAL_RESID_POINTER_COPYFILE CURSOR COPYF.CUR
+SAL_RESID_POINTER_LINKFILE CURSOR LINKF.CUR
+SAL_RESID_POINTER_MOVEFILELINK CURSOR MOVEFLNK.CUR
+SAL_RESID_POINTER_COPYFILELINK CURSOR COPYFLNK.CUR
+SAL_RESID_POINTER_MOVEFILES CURSOR MOVEF2.CUR
+SAL_RESID_POINTER_COPYFILES CURSOR COPYF2.CUR
+SAL_RESID_POINTER_NOTALLOWED CURSOR NOTALLOW.CUR
+SAL_RESID_POINTER_DRAW_LINE CURSOR DLINE.CUR
+SAL_RESID_POINTER_DRAW_RECT CURSOR DRECT.CUR
+SAL_RESID_POINTER_DRAW_POLYGON CURSOR DPOLYGON.CUR
+SAL_RESID_POINTER_DRAW_BEZIER CURSOR DBEZIER.CUR
+SAL_RESID_POINTER_DRAW_ARC CURSOR DARC.CUR
+SAL_RESID_POINTER_DRAW_PIE CURSOR DPIE.CUR
+SAL_RESID_POINTER_DRAW_CIRCLECUT CURSOR DCIRCCUT.CUR
+SAL_RESID_POINTER_DRAW_ELLIPSE CURSOR DELLIPSE.CUR
+SAL_RESID_POINTER_DRAW_FREEHAND CURSOR DFREE.CUR
+SAL_RESID_POINTER_DRAW_CONNECT CURSOR DCONNECT.CUR
+SAL_RESID_POINTER_DRAW_TEXT CURSOR DTEXT.CUR
+SAL_RESID_POINTER_DRAW_CAPTION CURSOR DCAPT.CUR
+SAL_RESID_POINTER_CHART CURSOR CHART.CUR
+SAL_RESID_POINTER_DETECTIVE CURSOR DETECTIV.CUR
+SAL_RESID_POINTER_PIVOT_COL CURSOR PIVOTCOL.CUR
+SAL_RESID_POINTER_PIVOT_ROW CURSOR PIVOTROW.CUR
+SAL_RESID_POINTER_PIVOT_FIELD CURSOR PIVOTFLD.CUR
+SAL_RESID_POINTER_CHAIN CURSOR CHAIN.CUR
+SAL_RESID_POINTER_CHAIN_NOTALLOWED CURSOR CHAINNOT.CUR
+SAL_RESID_POINTER_TIMEEVENT_MOVE CURSOR TIMEMOVE.CUR
+SAL_RESID_POINTER_TIMEEVENT_SIZE CURSOR TIMESIZE.CUR
+SAL_RESID_POINTER_AUTOSCROLL_N CURSOR ASN.CUR
+SAL_RESID_POINTER_AUTOSCROLL_S CURSOR ASS.CUR
+SAL_RESID_POINTER_AUTOSCROLL_W CURSOR ASW.CUR
+SAL_RESID_POINTER_AUTOSCROLL_E CURSOR ASE.CUR
+SAL_RESID_POINTER_AUTOSCROLL_NW CURSOR ASNW.CUR
+SAL_RESID_POINTER_AUTOSCROLL_NE CURSOR ASNE.CUR
+SAL_RESID_POINTER_AUTOSCROLL_SW CURSOR ASSW.CUR
+SAL_RESID_POINTER_AUTOSCROLL_SE CURSOR ASSE.CUR
+SAL_RESID_POINTER_AUTOSCROLL_NS CURSOR ASNS.CUR
+SAL_RESID_POINTER_AUTOSCROLL_WE CURSOR ASWE.CUR
+SAL_RESID_POINTER_AUTOSCROLL_NSWE CURSOR ASNSWE.CUR
+SAL_RESID_POINTER_AIRBRUSH CURSOR AIRBRUSH.CUR
+
+SAL_RESID_BITMAP_50 BITMAP 50.BMP
+
+SAL_RESID_ICON_DEFAULT ICON SD.ICO
diff --git a/vcl/win/source/src/sd.ico b/vcl/win/source/src/sd.ico
new file mode 100644
index 000000000000..b2a0a07a67c3
--- /dev/null
+++ b/vcl/win/source/src/sd.ico
Binary files differ
diff --git a/vcl/win/source/src/timemove.cur b/vcl/win/source/src/timemove.cur
new file mode 100755
index 000000000000..319b6edc5774
--- /dev/null
+++ b/vcl/win/source/src/timemove.cur
Binary files differ
diff --git a/vcl/win/source/src/timesize.cur b/vcl/win/source/src/timesize.cur
new file mode 100755
index 000000000000..1ec23de05b71
--- /dev/null
+++ b/vcl/win/source/src/timesize.cur
Binary files differ
diff --git a/vcl/win/source/src/vshear.cur b/vcl/win/source/src/vshear.cur
new file mode 100644
index 000000000000..a4bbf7e8eb00
--- /dev/null
+++ b/vcl/win/source/src/vshear.cur
Binary files differ
diff --git a/vcl/win/source/src/vsize.cur b/vcl/win/source/src/vsize.cur
new file mode 100644
index 000000000000..76449be89d0a
--- /dev/null
+++ b/vcl/win/source/src/vsize.cur
Binary files differ
diff --git a/vcl/win/source/src/vsizebar.cur b/vcl/win/source/src/vsizebar.cur
new file mode 100644
index 000000000000..a87811cb474d
--- /dev/null
+++ b/vcl/win/source/src/vsizebar.cur
Binary files differ
diff --git a/vcl/win/source/src/vsplit.cur b/vcl/win/source/src/vsplit.cur
new file mode 100644
index 000000000000..a4260808fadc
--- /dev/null
+++ b/vcl/win/source/src/vsplit.cur
Binary files differ
diff --git a/vcl/win/source/window/MAKEFILE.MK b/vcl/win/source/window/MAKEFILE.MK
new file mode 100644
index 000000000000..c370e52b2bb9
--- /dev/null
+++ b/vcl/win/source/window/MAKEFILE.MK
@@ -0,0 +1,38 @@
+#*************************************************************************
+#*
+#* $Workfile: makefile. $
+#*
+#* Ersterstellung TH 01.04.97
+#* Letzte Aenderung $Author: hr $ $Date: 2000-09-18 17:05:50 $
+#* $Revision: 1.1.1.1 $
+#*
+#* $Logfile: T:/sv2/win/source/window/makefile.__v $
+#*
+#* Copyright (c) 1990 - 1998, STAR DIVISION
+#*
+#*************************************************************************
+
+PRJ=..$/..$/..
+
+PRJNAME=vcl
+TARGET=salwin
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : svpre.mk
+.INCLUDE : settings.mk
+.INCLUDE : sv.mk
+
+# --- Files --------------------------------------------------------
+
+SLOFILES= $(SLO)$/salframe.obj \
+ $(SLO)$/salobj.obj
+
+.IF "$(UPDATER)"=="YES"
+OBJFILES= $(OBJ)$/salframe.obj \
+ $(OBJ)$/salobj.obj
+.ENDIF
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
diff --git a/vcl/win/source/window/salframe.cxx b/vcl/win/source/window/salframe.cxx
new file mode 100644
index 000000000000..48d964af3ab6
--- /dev/null
+++ b/vcl/win/source/window/salframe.cxx
@@ -0,0 +1,3901 @@
+/*************************************************************************
+ *
+ * $RCSfile: salframe.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:50 $
+ *
+ * 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 <string.h>
+#include <limits.h>
+
+#ifdef DBG_UTIL
+#include <stdio.h>
+#endif
+
+#ifndef _SVWIN_HXX
+#include <tools/svwin.h>
+#endif
+
+#define _SV_SALFRAME_CXX
+
+#ifndef _DEBUG_HXX
+#include <tools/debug.hxx>
+#endif
+
+#define private public
+#ifndef _SV_WINCOMP_HXX
+#include <wincomp.hxx>
+#endif
+#ifndef _SV_SALIDS_HRC
+#include <salids.hrc>
+#endif
+#ifndef _SV_SYSDATA_HXX
+#include <sysdata.hxx>
+#endif
+#ifndef _SV_SALDATA_HXX
+#include <saldata.hxx>
+#endif
+#ifndef _SV_SALINST_HXX
+#include <salinst.hxx>
+#endif
+#ifndef _SV_SALGDI_HXX
+#include <salgdi.hxx>
+#endif
+#ifndef _SV_SALSYS_HXX
+#include <salsys.hxx>
+#endif
+#ifndef _SV_SALFRAME_HXX
+#include <salframe.hxx>
+#endif
+#ifndef _SV_SALVD_HXX
+#include <salvd.hxx>
+#endif
+
+#ifndef _SV_TIMER_HXX
+#include <timer.hxx>
+#endif
+#ifndef _SV_SETTINGS_HXX
+#include <settings.hxx>
+#endif
+#ifndef _SV_KEYCOES_HXX
+#include <keycodes.hxx>
+#endif
+
+// =======================================================================
+
+// Wegen Fehler in Windows-Headerfiles
+#ifndef IMN_OPENCANDIDATE
+#define IMN_OPENCANDIDATE 0x0005
+#endif
+#ifndef IMN_CLOSECANDIDATE
+#define IMN_CLOSECANDIDATE 0x0004
+#endif
+
+// =======================================================================
+
+static void ImplSaveFrameState( SalFrame* pFrame )
+{
+ // Position, Groesse und Status fuer GetWindowState() merken
+ if ( !pFrame->maFrameData.mbFullScreen )
+ {
+ BOOL bVisible = (GetWindowStyle( pFrame->maFrameData.mhWnd ) & WS_VISIBLE) != 0;
+ if ( IsIconic( pFrame->maFrameData.mhWnd ) )
+ {
+ pFrame->maFrameData.maState.mnState |= SAL_FRAMESTATE_MINIMIZED;
+ if ( bVisible )
+ pFrame->maFrameData.mnShowState = SW_SHOWMAXIMIZED;
+ }
+ else if ( IsZoomed( pFrame->maFrameData.mhWnd ) )
+ {
+ pFrame->maFrameData.maState.mnState &= ~SAL_FRAMESTATE_MINIMIZED;
+ pFrame->maFrameData.maState.mnState |= SAL_FRAMESTATE_MAXIMIZED;
+ if ( bVisible )
+ pFrame->maFrameData.mnShowState = SW_SHOWMAXIMIZED;
+ pFrame->maFrameData.mbRestoreMaximize = TRUE;
+ }
+ else
+ {
+ RECT aRect;
+ GetWindowRect( pFrame->maFrameData.mhWnd, &aRect );
+ pFrame->maFrameData.maState.mnState &= ~(SAL_FRAMESTATE_MINIMIZED | SAL_FRAMESTATE_MAXIMIZED);
+ pFrame->maFrameData.maState.mnX = aRect.left;
+ pFrame->maFrameData.maState.mnY = aRect.top;
+ pFrame->maFrameData.maState.mnWidth = aRect.right-aRect.left;
+ pFrame->maFrameData.maState.mnHeight = aRect.bottom-aRect.top;
+ if ( bVisible )
+ pFrame->maFrameData.mnShowState = SW_SHOWNORMAL;
+ pFrame->maFrameData.mbRestoreMaximize = FALSE;
+ }
+ }
+}
+
+// =======================================================================
+
+SalFrame* ImplSalCreateFrame( SalInstance* pInst,
+ HWND hWndParent, ULONG nSalFrameStyle )
+{
+ SalFrame* pFrame = new SalFrame;
+ HWND hWnd;
+ DWORD nSysStyle = 0;
+ DWORD nExSysStyle = 0;
+ BOOL bSaveBits = FALSE;
+
+ // determine creation data
+ if ( nSalFrameStyle & SAL_FRAME_STYLE_CHILD )
+ nSysStyle |= WS_CHILD;
+ else if ( nSalFrameStyle & SAL_FRAME_STYLE_DEFAULT )
+ {
+ pFrame->maFrameData.mbCaption = TRUE;
+ nSysStyle |= WS_OVERLAPPED;
+#if ( WINVER >= 0x0400 )
+ nExSysStyle |= WS_EX_APPWINDOW;
+#endif
+ }
+ else
+ nSysStyle |= WS_POPUP;
+ if ( nSalFrameStyle & SAL_FRAME_STYLE_SIZEABLE )
+ {
+ pFrame->maFrameData.mbSizeBorder = TRUE;
+ nSysStyle |= WS_THICKFRAME | WS_SYSMENU;
+ }
+ else if ( nSalFrameStyle & SAL_FRAME_STYLE_BORDER )
+ {
+ pFrame->maFrameData.mbBorder = TRUE;
+ nSysStyle |= WS_BORDER;
+ }
+ if ( nSalFrameStyle & SAL_FRAME_STYLE_MOVEABLE )
+ {
+ pFrame->maFrameData.mbCaption = TRUE;
+ nSysStyle |= WS_CAPTION | WS_SYSMENU;
+ }
+#if ( WINVER >= 0x0400 )
+ else
+ nExSysStyle |= WS_EX_TOOLWINDOW;
+#endif
+ if ( nSalFrameStyle & SAL_FRAME_STYLE_MINABLE )
+ nSysStyle |= WS_MINIMIZEBOX | WS_SYSMENU;
+ if ( nSalFrameStyle & SAL_FRAME_STYLE_MAXABLE )
+ nSysStyle |= WS_MAXIMIZEBOX | WS_SYSMENU;
+
+ // init frame data
+ pFrame->maFrameData.mnStyle = nSalFrameStyle;
+
+ // determine show style
+ if ( nSalFrameStyle & SAL_FRAME_STYLE_DEFAULT )
+ {
+ SalData* pSalData = GetSalData();
+ pFrame->maFrameData.mnShowState = pSalData->mnCmdShow;
+ if ( (pFrame->maFrameData.mnShowState != SW_SHOWMINIMIZED) &&
+ (pFrame->maFrameData.mnShowState != SW_MINIMIZE) &&
+ (pFrame->maFrameData.mnShowState != SW_SHOWMINNOACTIVE) )
+ {
+ if ( (pFrame->maFrameData.mnShowState == SW_SHOWMAXIMIZED) ||
+ (pFrame->maFrameData.mnShowState == SW_MAXIMIZE) )
+ pFrame->maFrameData.mbOverwriteState = FALSE;
+ pFrame->maFrameData.mnShowState = SW_SHOWMAXIMIZED;
+ }
+ else
+ pFrame->maFrameData.mbOverwriteState = FALSE;
+ }
+ else
+ pFrame->maFrameData.mnShowState = SW_SHOWNORMAL;
+
+ // create frame
+ if ( aSalShlData.mbWNT )
+ {
+ LPCWSTR pClassName;
+ if ( bSaveBits )
+ pClassName = SAL_FRAME_CLASSNAME_SBW;
+ else
+ pClassName = SAL_FRAME_CLASSNAMEW;
+ hWnd = CreateWindowExW( nExSysStyle, pClassName, L"", nSysStyle,
+ CW_USEDEFAULT, 0, CW_USEDEFAULT, 0,
+ hWndParent, 0, pInst->maInstData.mhInst, (void*)pFrame );
+ }
+ else
+ {
+ LPCSTR pClassName;
+ if ( bSaveBits )
+ pClassName = SAL_FRAME_CLASSNAME_SBA;
+ else
+ pClassName = SAL_FRAME_CLASSNAMEA;
+ hWnd = CreateWindowExA( nExSysStyle, pClassName, "", nSysStyle,
+ CW_USEDEFAULT, 0, CW_USEDEFAULT, 0,
+ hWndParent, 0, pInst->maInstData.mhInst, (void*)pFrame );
+ }
+ if ( !hWnd )
+ {
+ delete pFrame;
+ return NULL;
+ }
+
+ // disable close
+ if ( !(nSalFrameStyle & SAL_FRAME_STYLE_CLOSEABLE) )
+ {
+ HMENU hSysMenu = GetSystemMenu( hWnd, FALSE );
+ if ( hSysMenu )
+ EnableMenuItem( hSysMenu, SC_CLOSE, MF_BYCOMMAND | MF_DISABLED | MF_GRAYED );
+ }
+
+ // reset input context
+ pFrame->maFrameData.mhDefIMEContext = ImmAssociateContext( hWnd, 0 );
+
+ // determine output size and state
+ RECT aRect;
+ GetClientRect( hWnd, &aRect );
+ pFrame->maFrameData.mnWidth = aRect.right;
+ pFrame->maFrameData.mnHeight = aRect.bottom;
+ ImplSaveFrameState( pFrame );
+ pFrame->maFrameData.mbDefPos = TRUE;
+
+ // CreateHDC in the main thread
+ pFrame->ReleaseGraphics( pFrame->GetGraphics() );
+
+ return pFrame;
+}
+
+// =======================================================================
+
+// Uebersetzungstabelle von System-Keycodes in StarView-Keycodes
+#define KEY_TAB_SIZE 146
+
+static USHORT aImplTranslateKeyTab[KEY_TAB_SIZE] =
+{
+ // StarView-Code System-Code Index
+ 0, // 0
+ 0, // VK_LBUTTON 1
+ 0, // VK_RBUTTON 2
+ 0, // VK_CANCEL 3
+ 0, // VK_MBUTTON 4
+ 0, // 5
+ 0, // 6
+ 0, // 7
+ KEY_BACKSPACE, // VK_BACK 8
+ KEY_TAB, // VK_TAB 9
+ 0, // 10
+ 0, // 11
+ 0, // VK_CLEAR 12
+ KEY_RETURN, // VK_RETURN 13
+ 0, // 14
+ 0, // 15
+ 0, // VK_SHIFT 16
+ 0, // VK_CONTROL 17
+ 0, // VK_MENU 18
+ 0, // VK_PAUSE 19
+ 0, // VK_CAPITAL 20
+ 0, // 21
+ 0, // 22
+ 0, // 23
+ 0, // 24
+ 0, // 25
+ 0, // 26
+ KEY_ESCAPE, // VK_ESCAPE 27
+ 0, // 28
+ 0, // 29
+ 0, // 30
+ 0, // 31
+ KEY_SPACE, // VK_SPACE 32
+ KEY_PAGEUP, // VK_PRIOR 33
+ KEY_PAGEDOWN, // VK_NEXT 34
+ KEY_END, // VK_END 35
+ KEY_HOME, // VK_HOME 36
+ KEY_LEFT, // VK_LEFT 37
+ KEY_UP, // VK_UP 38
+ KEY_RIGHT, // VK_RIGHT 39
+ KEY_DOWN, // VK_DOWN 40
+ 0, // VK_SELECT 41
+ 0, // VK_PRINT 42
+ 0, // VK_EXECUTE 43
+ 0, // VK_SNAPSHOT 44
+ KEY_INSERT, // VK_INSERT 45
+ KEY_DELETE, // VK_DELETE 46
+ KEY_HELP, // VK_HELP 47
+ KEY_0, // 48
+ KEY_1, // 49
+ KEY_2, // 50
+ KEY_3, // 51
+ KEY_4, // 52
+ KEY_5, // 53
+ KEY_6, // 54
+ KEY_7, // 55
+ KEY_8, // 56
+ KEY_9, // 57
+ 0, // 58
+ 0, // 59
+ 0, // 60
+ 0, // 61
+ 0, // 62
+ 0, // 63
+ 0, // 64
+ KEY_A, // 65
+ KEY_B, // 66
+ KEY_C, // 67
+ KEY_D, // 68
+ KEY_E, // 69
+ KEY_F, // 70
+ KEY_G, // 71
+ KEY_H, // 72
+ KEY_I, // 73
+ KEY_J, // 74
+ KEY_K, // 75
+ KEY_L, // 76
+ KEY_M, // 77
+ KEY_N, // 78
+ KEY_O, // 79
+ KEY_P, // 80
+ KEY_Q, // 81
+ KEY_R, // 82
+ KEY_S, // 83
+ KEY_T, // 84
+ KEY_U, // 85
+ KEY_V, // 86
+ KEY_W, // 87
+ KEY_X, // 88
+ KEY_Y, // 89
+ KEY_Z, // 90
+ 0, // VK_LWIN 91
+ 0, // VK_RWIN 92
+ KEY_CONTEXTMENU, // VK_APPS 93
+ 0, // 94
+ 0, // 95
+ KEY_0, // VK_NUMPAD0 96
+ KEY_1, // VK_NUMPAD1 97
+ KEY_2, // VK_NUMPAD2 98
+ KEY_3, // VK_NUMPAD3 99
+ KEY_4, // VK_NUMPAD4 100
+ KEY_5, // VK_NUMPAD5 101
+ KEY_6, // VK_NUMPAD6 102
+ KEY_7, // VK_NUMPAD7 103
+ KEY_8, // VK_NUMPAD8 104
+ KEY_9, // VK_NUMPAD9 105
+ KEY_MULTIPLY, // VK_MULTIPLY 106
+ KEY_ADD, // VK_ADD 107
+ KEY_COMMA, // VK_SEPARATOR 108
+ KEY_SUBTRACT, // VK_SUBTRACT 109
+ KEY_POINT, // VK_DECIMAL 110
+ KEY_DIVIDE, // VK_DIVIDE 111
+ KEY_F1, // VK_F1 112
+ KEY_F2, // VK_F2 113
+ KEY_F3, // VK_F3 114
+ KEY_F4, // VK_F4 115
+ KEY_F5, // VK_F5 116
+ KEY_F6, // VK_F6 117
+ KEY_F7, // VK_F7 118
+ KEY_F8, // VK_F8 119
+ KEY_F9, // VK_F9 120
+ KEY_F10, // VK_F10 121
+ KEY_F11, // VK_F11 122
+ KEY_F12, // VK_F12 123
+ KEY_F13, // VK_F13 124
+ KEY_F14, // VK_F14 125
+ KEY_F15, // VK_F15 126
+ KEY_F16, // VK_F16 127
+ KEY_F17, // VK_F17 128
+ KEY_F18, // VK_F18 129
+ KEY_F19, // VK_F19 130
+ KEY_F20, // VK_F20 131
+ KEY_F21, // VK_F21 132
+ KEY_F22, // VK_F22 133
+ KEY_F23, // VK_F23 134
+ KEY_F24, // VK_F24 135
+ 0, // 136
+ 0, // 137
+ 0, // 138
+ 0, // 139
+ 0, // 140
+ 0, // 141
+ 0, // 142
+ 0, // 143
+ 0, // NUMLOCK 144
+ 0 // SCROLLLOCK 145
+};
+
+// =======================================================================
+
+long ImplSalCallbackDummy( void*, SalFrame*, USHORT, const void* )
+{
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+static UINT ImplSalGetWheelScrollLines()
+{
+ UINT nScrLines = 0;
+ HWND hWndMsWheel = WIN_FindWindow( MSH_WHEELMODULE_CLASS, MSH_WHEELMODULE_TITLE );
+ if ( hWndMsWheel )
+ {
+ UINT nGetScrollLinesMsgId = RegisterWindowMessage( MSH_SCROLL_LINES );
+ nScrLines = (UINT)ImplSendMessage( hWndMsWheel, nGetScrollLinesMsgId, 0, 0 );
+ }
+
+ if ( !nScrLines )
+ nScrLines = SystemParametersInfo( SPI_GETWHEELSCROLLLINES, 0, &nScrLines, 0 );
+
+ if ( !nScrLines )
+ nScrLines = 3;
+
+ return nScrLines;
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplSalCalcFullScreenSize( const SalFrame* pFrame,
+ int& rX, int& rY, int& rDX, int& rDY )
+{
+ // set window to screen size
+ int nFrameX;
+ int nFrameY;
+ int nCaptionY;
+ int nScreenDX;
+ int nScreenDY;
+
+ if ( pFrame->maFrameData.mbSizeBorder )
+ {
+ nFrameX = GetSystemMetrics( SM_CXFRAME );
+ nFrameY = GetSystemMetrics( SM_CYFRAME );
+ }
+ else if ( pFrame->maFrameData.mbBorder )
+ {
+ nFrameX = GetSystemMetrics( SM_CXBORDER );
+ nFrameY = GetSystemMetrics( SM_CYBORDER );
+ }
+ else
+ {
+ nFrameX = 0;
+ nFrameY = 0;
+ }
+ if ( pFrame->maFrameData.mbCaption )
+ nCaptionY = GetSystemMetrics( SM_CYCAPTION );
+ else
+ nCaptionY = 0;
+
+ nScreenDX = GetSystemMetrics( SM_CXSCREEN );
+ nScreenDY = GetSystemMetrics( SM_CYSCREEN );
+
+ rX = -nFrameX;
+ rY = -(nFrameY+nCaptionY);
+ rDX = nScreenDX+(nFrameX*2);
+ rDY = nScreenDY+(nFrameY*2)+nCaptionY;
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplSalFrameFullScreenPos( SalFrame* pFrame, BOOL bAlways = FALSE )
+{
+ if ( bAlways || !IsIconic( pFrame->maFrameData.mhWnd ) )
+ {
+ // set window to screen size
+ int nX;
+ int nY;
+ int nWidth;
+ int nHeight;
+ ImplSalCalcFullScreenSize( pFrame, nX, nY, nWidth, nHeight );
+ SetWindowPos( pFrame->maFrameData.mhWnd, 0,
+ nX, nY, nWidth, nHeight,
+ SWP_NOZORDER | SWP_NOACTIVATE );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+SalFrame::SalFrame()
+{
+ SalData* pSalData = GetSalData();
+
+ maFrameData.mhWnd = 0;
+ maFrameData.mhCursor = LoadCursor( 0, IDC_ARROW );
+ maFrameData.mhDefIMEContext = 0;
+ maFrameData.mpGraphics = NULL;
+ maFrameData.mpInst = NULL;
+ maFrameData.mpProc = ImplSalCallbackDummy;
+ maFrameData.mnInputLang = 0;
+ maFrameData.mnInputCodePage = 0;
+ maFrameData.mbGraphics = FALSE;
+ maFrameData.mbCaption = FALSE;
+ maFrameData.mbBorder = FALSE;
+ maFrameData.mbSizeBorder = FALSE;
+ maFrameData.mbFullScreen = FALSE;
+ maFrameData.mbPresentation = FALSE;
+ maFrameData.mbInShow = FALSE;
+ maFrameData.mbRestoreMaximize = FALSE;
+ maFrameData.mbInMoveMsg = FALSE;
+ maFrameData.mbInSizeMsg = FALSE;
+ maFrameData.mbFullScreenToolWin = FALSE;
+ maFrameData.mbDefPos = TRUE;
+ maFrameData.mbOverwriteState = TRUE;
+ maFrameData.mbIME = FALSE;
+ maFrameData.mbHandleIME = FALSE;
+ maFrameData.mbSpezIME = FALSE;
+ maFrameData.mbAtCursorIME = FALSE;
+ maFrameData.mbCompositionMode = FALSE;
+ maFrameData.mbCandidateMode = FALSE;
+ memset( &maFrameData.maState, 0, sizeof( SalFrameState ) );
+ maFrameData.maSysData.nSize = sizeof( SystemEnvData );
+
+ // Daten ermitteln, wenn erster Frame angelegt wird
+ if ( !pSalData->mpFirstFrame )
+ {
+ if ( !aSalShlData.mnWheelMsgId )
+ aSalShlData.mnWheelMsgId = RegisterWindowMessage( MSH_MOUSEWHEEL );
+ if ( !aSalShlData.mnWheelScrollLines )
+ aSalShlData.mnWheelScrollLines = ImplSalGetWheelScrollLines();
+ }
+
+ // insert frame in framelist
+ maFrameData.mpNextFrame = pSalData->mpFirstFrame;
+ pSalData->mpFirstFrame = this;
+}
+
+// -----------------------------------------------------------------------
+
+SalFrame::~SalFrame()
+{
+ SalData* pSalData = GetSalData();
+
+ // destroy saved DC
+ if ( maFrameData.mpGraphics )
+ {
+ if ( maFrameData.mpGraphics->maGraphicsData.mhDefPal )
+ SelectPalette( maFrameData.mpGraphics->maGraphicsData.mhDC, maFrameData.mpGraphics->maGraphicsData.mhDefPal, TRUE );
+ ImplSalDeInitGraphics( &(maFrameData.mpGraphics->maGraphicsData) );
+ ReleaseDC( maFrameData.mhWnd, maFrameData.mpGraphics->maGraphicsData.mhDC );
+ delete maFrameData.mpGraphics;
+ }
+
+ if ( maFrameData.mhWnd )
+ {
+ // reset mouse leave data
+ if ( pSalData->mhWantLeaveMsg == maFrameData.mhWnd )
+ {
+ pSalData->mhWantLeaveMsg = 0;
+ if ( pSalData->mpMouseLeaveTimer )
+ {
+ delete pSalData->mpMouseLeaveTimer;
+ pSalData->mpMouseLeaveTimer = NULL;
+ }
+ }
+
+ // destroy system frame
+ if ( !DestroyWindow( maFrameData.mhWnd ) )
+ SetWindowPtr( maFrameData.mhWnd, 0 );
+ }
+
+ // remove frame from framelist
+ if ( this == pSalData->mpFirstFrame )
+ pSalData->mpFirstFrame = maFrameData.mpNextFrame;
+ else
+ {
+ SalFrame* pTempFrame = pSalData->mpFirstFrame;
+ while ( pTempFrame->maFrameData.mpNextFrame != this )
+ pTempFrame = pTempFrame->maFrameData.mpNextFrame;
+
+ pTempFrame->maFrameData.mpNextFrame = maFrameData.mpNextFrame;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+SalGraphics* SalFrame::GetGraphics()
+{
+ if ( maFrameData.mbGraphics )
+ return NULL;
+
+ if ( !maFrameData.mpGraphics )
+ {
+ HDC hDC = GetDC( maFrameData.mhWnd );
+ if ( hDC )
+ {
+ SalData* pSalData = GetSalData();
+ maFrameData.mpGraphics = new SalGraphics;
+ maFrameData.mpGraphics->maGraphicsData.mhDC = hDC;
+ maFrameData.mpGraphics->maGraphicsData.mhWnd = maFrameData.mhWnd;
+ maFrameData.mpGraphics->maGraphicsData.mbPrinter = FALSE;
+ maFrameData.mpGraphics->maGraphicsData.mbVirDev = FALSE;
+ maFrameData.mpGraphics->maGraphicsData.mbWindow = TRUE;
+ maFrameData.mpGraphics->maGraphicsData.mbScreen = TRUE;
+ if ( pSalData->mhDitherPal )
+ {
+ maFrameData.mpGraphics->maGraphicsData.mhDefPal = SelectPalette( hDC, pSalData->mhDitherPal, TRUE );
+ RealizePalette( hDC );
+ }
+ ImplSalInitGraphics( &(maFrameData.mpGraphics->maGraphicsData) );
+ maFrameData.mbGraphics = TRUE;
+ }
+ }
+ else
+ maFrameData.mbGraphics = TRUE;
+
+ return maFrameData.mpGraphics;
+}
+
+// -----------------------------------------------------------------------
+
+void SalFrame::ReleaseGraphics( SalGraphics* )
+{
+ maFrameData.mbGraphics = FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL SalFrame::PostEvent( void* pData )
+{
+ return (BOOL)ImplPostMessage( maFrameData.mhWnd, SAL_MSG_USEREVENT, 0, (LPARAM)pData );
+}
+
+// -----------------------------------------------------------------------
+
+void SalFrame::SetTitle( const XubString& rTitle )
+{
+ DBG_ASSERT( sizeof( WCHAR ) == sizeof( xub_Unicode ), "SalFrame::SetTitle(): WCHAR != sal_Unicode" );
+
+ if ( !SetWindowTextW( maFrameData.mhWnd, rTitle.GetBuffer() ) )
+ {
+ ByteString aAnsiTitle = ImplSalGetWinAnsiString( rTitle );
+ SetWindowTextA( maFrameData.mhWnd, aAnsiTitle.GetBuffer() );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void SalFrame::SetIcon( USHORT nIcon )
+{
+// ImplSendMessage( maFrameData.mhWnd, WM_SETICON, FALSE, hSmIcon );
+// ImplSendMessage( maFrameData.mhWnd, WM_SETICON, TRUE, hIcon );
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplSalShow( HWND hWnd, BOOL bVisible )
+{
+ SalFrame* pFrame = GetWindowPtr( hWnd );
+ if ( !pFrame )
+ return;
+
+ if ( bVisible )
+ {
+ pFrame->maFrameData.mbDefPos = FALSE;
+ pFrame->maFrameData.mbOverwriteState = TRUE;
+ pFrame->maFrameData.mbInShow = TRUE;
+ ShowWindow( hWnd, pFrame->maFrameData.mnShowState );
+ // Damit Taskleiste unter W98 auch gleich ausgeblendet wird
+ if ( pFrame->maFrameData.mbPresentation )
+ {
+ HWND hWndParent = ::GetParent( hWnd );
+ if ( hWndParent )
+ SetForegroundWindow( hWndParent );
+ SetForegroundWindow( hWnd );
+ }
+ pFrame->maFrameData.mnShowState = SW_SHOW;
+ pFrame->maFrameData.mbInShow = FALSE;
+ UpdateWindow( hWnd );
+ }
+ else
+ {
+ if ( pFrame->maFrameData.mbFullScreen &&
+ pFrame->maFrameData.mbPresentation &&
+ !::GetParent( hWnd ) )
+ {
+ // Damit im Impress-Player in der Taskleiste nicht durch
+ // einen Windows-Fehler hin- und wieder mal ein leerer
+ // Button stehen bleibt, muessen wir hier die Taskleiste
+ // etwas austricksen. Denn wenn wir im FullScreenMode sind
+ // und das Fenster hiden kommt Windows anscheinend etwas aus
+ // dem tritt und somit minimieren wir das Fenster damit es
+ // nicht flackert
+ ANIMATIONINFO aInfo;
+ aInfo.cbSize = sizeof( aInfo );
+ SystemParametersInfo( SPI_GETANIMATION, 0, &aInfo, 0 );
+ if ( aInfo.iMinAnimate )
+ {
+ int nOldAni = aInfo.iMinAnimate;
+ aInfo.iMinAnimate = 0;
+ SystemParametersInfo( SPI_SETANIMATION, 0, &aInfo, 0 );
+ ShowWindow( pFrame->maFrameData.mhWnd, SW_SHOWMINNOACTIVE );
+ aInfo.iMinAnimate = nOldAni;
+ SystemParametersInfo( SPI_SETANIMATION, 0, &aInfo, 0 );
+ }
+ else
+ ShowWindow( hWnd, SW_SHOWMINNOACTIVE );
+ ShowWindow( hWnd, SW_HIDE );
+ }
+ else
+ ShowWindow( hWnd, SW_HIDE );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void SalFrame::Show( BOOL bVisible )
+{
+ // Send this Message to the window, because this only works
+ // in the thread of the window, which has create this window
+ ImplSendMessage( maFrameData.mhWnd, SAL_MSG_SHOW, bVisible, 0 );
+}
+
+// -----------------------------------------------------------------------
+
+void SalFrame::Enable( BOOL bEnable )
+{
+ EnableWindow( maFrameData.mhWnd, bEnable );
+}
+
+// -----------------------------------------------------------------------
+
+void SalFrame::SetMinClientSize( long nWidth, long nHeight )
+{
+}
+
+// -----------------------------------------------------------------------
+
+void SalFrame::SetClientSize( long nWidth, long nHeight )
+{
+ BOOL bVisible = (GetWindowStyle( maFrameData.mhWnd ) & WS_VISIBLE) != 0;
+ if ( !bVisible )
+ maFrameData.mnShowState = SW_SHOWNORMAL;
+ else
+ {
+ if ( IsIconic( maFrameData.mhWnd ) || IsZoomed( maFrameData.mhWnd ) )
+ ShowWindow( maFrameData.mhWnd, SW_RESTORE );
+ }
+
+ // Fenstergroesse berechnen
+ RECT aWinRect;
+ aWinRect.left = 0;
+ aWinRect.right = (int)nWidth-1;
+ aWinRect.top = 0;
+ aWinRect.bottom = (int)nHeight-1;
+ AdjustWindowRectEx( &aWinRect,
+ GetWindowStyle( maFrameData.mhWnd ),
+ FALSE,
+ GetWindowExStyle( maFrameData.mhWnd ) );
+ nWidth = aWinRect.right - aWinRect.left + 1;
+ nHeight = aWinRect.bottom - aWinRect.top + 1;
+
+ // Position so berechnen, das Fenster zentiert auf dem Desktop
+ // angezeigt wird
+ int nX;
+ int nY;
+ int nScreenX;
+ int nScreenY;
+ int nScreenWidth;
+ int nScreenHeight;
+
+#if ( WINVER >= 0x0400 )
+ W40IF
+ {
+ RECT aRect;
+ SystemParametersInfo( SPI_GETWORKAREA, 0, &aRect, 0 );
+ nScreenX = aRect.left;
+ nScreenY = aRect.top;
+ nScreenWidth = aRect.right-aRect.left;
+ nScreenHeight = aRect.bottom-aRect.top;
+ }
+ W40ELSE
+#endif
+#ifndef W40ONLY
+ {
+ nScreenX = 0;
+ nScreenY = 0;
+ nScreenWidth = GetSystemMetrics( SM_CXSCREEN );
+ nScreenHeight = GetSystemMetrics( SM_CYSCREEN );
+ }
+#endif
+
+ if ( maFrameData.mbDefPos )
+ {
+ nX = (nScreenWidth-nWidth)/2 + nScreenX;
+ nY = (nScreenHeight-nHeight)/2 + nScreenY;
+ if ( bVisible )
+ maFrameData.mbDefPos = FALSE;
+ }
+ else
+ {
+ RECT aWinRect;
+ GetWindowRect( maFrameData.mhWnd, &aWinRect );
+ nX = aWinRect.left;
+ nY = aWinRect.top;
+ if ( nX+nWidth > nScreenX+nScreenWidth )
+ nX = (nScreenX+nScreenWidth) - nWidth;
+ if ( nY+nHeight > nScreenY+nScreenHeight )
+ nY = (nScreenY+nScreenHeight) - nHeight;
+ if ( nX < nScreenX )
+ nX = nScreenX;
+ if ( nY < nScreenY )
+ nY = nScreenY;
+ }
+
+ SetWindowPos( maFrameData.mhWnd, 0, nX, nY, (int)nWidth, (int)nHeight, SWP_NOZORDER | SWP_NOACTIVATE );
+}
+
+// -----------------------------------------------------------------------
+
+void SalFrame::GetClientSize( long& rWidth, long& rHeight )
+{
+ rWidth = maFrameData.mnWidth;
+ rHeight = maFrameData.mnHeight;
+}
+
+// -----------------------------------------------------------------------
+
+void SalFrame::SetWindowState( const SalFrameState* pState )
+{
+ // Wir testen, ob das Fenster ueberhaupt auf den Bildschirm passt, damit
+ // nicht wenn die Bildschirm-Aufloesung geaendert wurde, das Fenster aus
+ // diesem herausragt
+ int nX;
+ int nY;
+ int nWidth;
+ int nHeight;
+ int nScreenX;
+ int nScreenY;
+ int nScreenWidth;
+ int nScreenHeight;
+
+#if ( WINVER >= 0x0400 )
+ W40IF
+ {
+ RECT aRect;
+ SystemParametersInfo( SPI_GETWORKAREA, 0, &aRect, 0 );
+ nScreenX = aRect.left;
+ nScreenY = aRect.top;
+ nScreenWidth = aRect.right-aRect.left;
+ nScreenHeight = aRect.bottom-aRect.top;
+ }
+ W40ELSE
+#endif
+#ifndef W40ONLY
+ {
+ nScreenX = 0;
+ nScreenY = 0;
+ nScreenWidth = GetSystemMetrics( SM_CXSCREEN );
+ nScreenHeight = GetSystemMetrics( SM_CYSCREEN );
+ }
+#endif
+
+ // Fenster-Position/Groesse in den Bildschirm einpassen
+ nX = (int)pState->mnX;
+ nY = (int)pState->mnY;
+ nWidth = (int)pState->mnWidth;
+ nHeight = (int)pState->mnHeight;
+ if ( nX < nScreenX )
+ nX = nScreenX;
+ if ( nY < nScreenY )
+ nY = nScreenY;
+ if ( nScreenWidth < nWidth )
+ nWidth = nScreenWidth;
+ if ( nScreenHeight < nHeight )
+ nHeight = nScreenHeight;
+
+ // Restore-Position setzen
+ WINDOWPLACEMENT aPlacement;
+ aPlacement.length = sizeof( aPlacement );
+ GetWindowPlacement( maFrameData.mhWnd, &aPlacement );
+
+ // Status setzen
+ BOOL bVisible = (GetWindowStyle( maFrameData.mhWnd ) & WS_VISIBLE) != 0;
+ if ( !bVisible )
+ {
+ aPlacement.showCmd = SW_HIDE;
+
+ if ( maFrameData.mbOverwriteState )
+ {
+ if ( pState->mnState & SAL_FRAMESTATE_MINIMIZED )
+ maFrameData.mnShowState = SW_SHOWMINIMIZED;
+ else if ( pState->mnState & SAL_FRAMESTATE_MAXIMIZED )
+ maFrameData.mnShowState = SW_SHOWMAXIMIZED;
+ else
+ maFrameData.mnShowState = SW_SHOWNORMAL;
+ }
+ }
+ else
+ {
+ if ( pState->mnState & SAL_FRAMESTATE_MINIMIZED )
+ {
+ if ( pState->mnState & SAL_FRAMESTATE_MAXIMIZED )
+ aPlacement.flags |= WPF_RESTORETOMAXIMIZED;
+ aPlacement.showCmd = SW_SHOWMINIMIZED;
+ }
+ else if ( pState->mnState & SAL_FRAMESTATE_MAXIMIZED )
+ aPlacement.showCmd = SW_SHOWMAXIMIZED;
+ else
+ aPlacement.showCmd = SW_RESTORE;
+ }
+
+ // Wenn Fenster nicht minimiert/maximiert ist oder nicht optisch
+ // umgesetzt werden muss, dann SetWindowPos() benutzen, da
+ // SetWindowPlacement() die TaskBar mit einrechnet
+ if ( !IsIconic( maFrameData.mhWnd ) && !IsZoomed( maFrameData.mhWnd ) &&
+ (!bVisible || (aPlacement.showCmd == SW_RESTORE)) )
+ {
+ SetWindowPos( maFrameData.mhWnd, 0,
+ nX, nY, nWidth, nHeight,
+ SWP_NOZORDER | SWP_NOACTIVATE );
+ }
+ else
+ {
+ aPlacement.rcNormalPosition.left = nX-nScreenX;
+ aPlacement.rcNormalPosition.top = nY-nScreenY;
+ aPlacement.rcNormalPosition.right = nX+nWidth-nScreenX;
+ aPlacement.rcNormalPosition.bottom = nY+nHeight-nScreenY;
+ SetWindowPlacement( maFrameData.mhWnd, &aPlacement );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+BOOL SalFrame::GetWindowState( SalFrameState* pState )
+{
+ if ( maFrameData.maState.mnWidth && maFrameData.maState.mnHeight )
+ {
+ *pState = maFrameData.maState;
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+void SalFrame::ShowFullScreen( BOOL bFullScreen )
+{
+ if ( maFrameData.mbFullScreen == bFullScreen )
+ return;
+
+ maFrameData.mbFullScreen = bFullScreen;
+ if ( bFullScreen )
+ {
+#if ( WINVER >= 0x0400 )
+ // Damit Taskleiste von Windows ausgeblendet wird
+ DWORD nExStyle = GetWindowExStyle( maFrameData.mhWnd );
+ if ( nExStyle & WS_EX_TOOLWINDOW )
+ {
+ maFrameData.mbFullScreenToolWin = TRUE;
+ nExStyle &= ~WS_EX_TOOLWINDOW;
+ SetWindowExStyle( maFrameData.mhWnd, nExStyle );
+ }
+#endif
+
+ // save old position
+ GetWindowRect( maFrameData.mhWnd, &maFrameData.maFullScreenRect );
+
+ // save show state
+ maFrameData.mnFullScreenShowState = maFrameData.mnShowState;
+ if ( !(GetWindowStyle( maFrameData.mhWnd ) & WS_VISIBLE) )
+ maFrameData.mnShowState = SW_SHOW;
+
+ // set window to screen size
+ ImplSalFrameFullScreenPos( this, TRUE );
+ }
+ else
+ {
+ // wenn ShowState wieder hergestellt werden muss, hiden wir zuerst
+ // das Fenster, damit es nicht so sehr flackert
+ BOOL bVisible = (GetWindowStyle( maFrameData.mhWnd ) & WS_VISIBLE) != 0;
+ if ( bVisible && (maFrameData.mnShowState != maFrameData.mnFullScreenShowState) )
+ ShowWindow( maFrameData.mhWnd, SW_HIDE );
+
+#if ( WINVER >= 0x0400 )
+ if ( maFrameData.mbFullScreenToolWin )
+ SetWindowExStyle( maFrameData.mhWnd, GetWindowExStyle( maFrameData.mhWnd ) | WS_EX_TOOLWINDOW );
+ maFrameData.mbFullScreenToolWin = FALSE;
+#endif
+
+ SetWindowPos( maFrameData.mhWnd, 0,
+ maFrameData.maFullScreenRect.left,
+ maFrameData.maFullScreenRect.top,
+ maFrameData.maFullScreenRect.right-maFrameData.maFullScreenRect.left,
+ maFrameData.maFullScreenRect.bottom-maFrameData.maFullScreenRect.top,
+ SWP_NOZORDER | SWP_NOACTIVATE );
+
+ // restore show state
+ if ( maFrameData.mnShowState != maFrameData.mnFullScreenShowState )
+ {
+ maFrameData.mnShowState = maFrameData.mnFullScreenShowState;
+ if ( bVisible )
+ {
+ maFrameData.mbInShow = TRUE;
+ ShowWindow( maFrameData.mhWnd, maFrameData.mnShowState );
+ maFrameData.mbInShow = FALSE;
+ UpdateWindow( maFrameData.mhWnd );
+ }
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void SalFrame::StartPresentation( BOOL bStart )
+{
+ if ( maFrameData.mbPresentation == bStart )
+ return;
+
+ maFrameData.mbPresentation = bStart;
+
+ SalData* pSalData = GetSalData();
+ if ( bStart )
+ {
+#if ( WINVER >= 0x0400 )
+ if ( !pSalData->mpSageEnableProc )
+ {
+ if ( pSalData->mnSageStatus != DISABLE_AGENT )
+ {
+ OFSTRUCT aOS;
+ OpenFile( "SAGE.DLL", &aOS, OF_EXIST );
+
+ if ( !aOS.nErrCode )
+ {
+ pSalData->mhSageInst = LoadLibrary( aOS.szPathName );
+ pSalData->mpSageEnableProc = (SysAgt_Enable_PROC)GetProcAddress( pSalData->mhSageInst, "System_Agent_Enable" );
+ }
+ else
+ pSalData->mnSageStatus = DISABLE_AGENT;
+ }
+ }
+
+ if ( pSalData->mpSageEnableProc )
+ {
+ pSalData->mnSageStatus = pSalData->mpSageEnableProc( GET_AGENT_STATUS );
+ if ( pSalData->mnSageStatus == ENABLE_AGENT )
+ pSalData->mpSageEnableProc( DISABLE_AGENT );
+ }
+#endif
+
+ // Bildschirmschoner ausschalten, wenn Praesentation laueft
+ SystemParametersInfo( SPI_GETSCREENSAVEACTIVE, 0,
+ &(pSalData->mbScrSvrEnabled), 0 );
+ if ( pSalData->mbScrSvrEnabled )
+ SystemParametersInfo( SPI_SETSCREENSAVEACTIVE, FALSE, 0, 0 );
+ }
+ else
+ {
+ // Bildschirmschoner wieder einschalten
+ if ( pSalData->mbScrSvrEnabled )
+ SystemParametersInfo( SPI_SETSCREENSAVEACTIVE, pSalData->mbScrSvrEnabled, 0, 0 );
+
+#if ( WINVER >= 0x0400 )
+ // Systemagenten wieder aktivieren
+ if ( pSalData->mnSageStatus == ENABLE_AGENT )
+ pSalData->mpSageEnableProc( pSalData->mnSageStatus );
+#endif
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void SalFrame::SetAlwaysOnTop( BOOL bOnTop )
+{
+ HWND hWnd;
+ if ( bOnTop )
+ hWnd = HWND_TOPMOST;
+ else
+ hWnd = HWND_NOTOPMOST;
+ SetWindowPos( maFrameData.mhWnd, hWnd, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE );
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplSalToTop( HWND hWnd, USHORT nFlags )
+{
+ if ( nFlags & SAL_FRAME_TOTOP_FOREGROUNDTASK )
+ SetForegroundWindow( hWnd );
+ if ( !IsIconic( hWnd ) )
+ {
+ SetFocus( hWnd );
+
+ // Windows behauptet oefters mal, das man den Focus hat, obwohl
+ // man diesen nicht hat. Wenn dies der Fall ist, dann versuchen
+ // wir diesen auch ganz richtig zu bekommen.
+ if ( ::GetFocus() == hWnd )
+ SetForegroundWindow( hWnd );
+ }
+ else
+ {
+ if ( nFlags & SAL_FRAME_TOTOP_RESTOREWHENMIN )
+ {
+ if ( GetWindowPtr( hWnd )->maFrameData.mbRestoreMaximize )
+ ShowWindow( hWnd, SW_MAXIMIZE );
+ else
+ ShowWindow( hWnd, SW_RESTORE );
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void SalFrame::ToTop( USHORT nFlags )
+{
+ // Send this Message to the window, because SetFocus() only work
+ // in the thread of the window, which has create this window
+ ImplSendMessage( maFrameData.mhWnd, SAL_MSG_TOTOP, nFlags, 0 );
+}
+
+// -----------------------------------------------------------------------
+
+void SalFrame::SetPointer( PointerStyle ePointerStyle )
+{
+ struct ImplPtrData
+ {
+ HCURSOR mhCursor;
+ LPCSTR mnSysId;
+ UINT mnOwnId;
+ };
+
+ static ImplPtrData aImplPtrTab[POINTER_COUNT] =
+ {
+ { 0, IDC_ARROW, 0 }, // POINTER_ARROW
+ { 0, 0, SAL_RESID_POINTER_NULL }, // POINTER_NULL
+ { 0, IDC_WAIT, 0 }, // POINTER_WAIT
+ { 0, IDC_IBEAM, 0 }, // POINTER_TEXT
+#if ( WINVER >= 0x0400 )
+ { 0, IDC_HELP, 0 }, // POINTER_HELP
+#else
+ { 0, 0, SAL_RESID_POINTER_HELP }, // POINTER_HELP
+#endif
+ { 0, 0, SAL_RESID_POINTER_CROSS }, // POINTER_CROSS
+ { 0, 0, SAL_RESID_POINTER_MOVE }, // POINTER_MOVE
+ { 0, IDC_SIZENS, 0 }, // POINTER_NSIZE
+ { 0, IDC_SIZENS, 0 }, // POINTER_SSIZE
+ { 0, IDC_SIZEWE, 0 }, // POINTER_WSIZE
+ { 0, IDC_SIZEWE, 0 }, // POINTER_ESIZE
+ { 0, IDC_SIZENWSE, 0 }, // POINTER_NWSIZE
+ { 0, IDC_SIZENESW, 0 }, // POINTER_NESIZE
+ { 0, IDC_SIZENESW, 0 }, // POINTER_SWSIZE
+ { 0, IDC_SIZENWSE, 0 }, // POINTER_SESIZE
+ { 0, IDC_SIZENS, 0 }, // POINTER_WINDOW_NSIZE
+ { 0, IDC_SIZENS, 0 }, // POINTER_WINDOW_SSIZE
+ { 0, IDC_SIZEWE, 0 }, // POINTER_WINDOW_WSIZE
+ { 0, IDC_SIZEWE, 0 }, // POINTER_WINDOW_ESIZE
+ { 0, IDC_SIZENWSE, 0 }, // POINTER_WINDOW_NWSIZE
+ { 0, IDC_SIZENESW, 0 }, // POINTER_WINDOW_NESIZE
+ { 0, IDC_SIZENESW, 0 }, // POINTER_WINDOW_SWSIZE
+ { 0, IDC_SIZENWSE, 0 }, // POINTER_WINDOW_SESIZE
+ { 0, 0, SAL_RESID_POINTER_HSPLIT }, // POINTER_HSPLIT
+ { 0, 0, SAL_RESID_POINTER_VSPLIT }, // POINTER_VSPLIT
+ { 0, 0, SAL_RESID_POINTER_HSIZEBAR }, // POINTER_HSIZEBAR
+ { 0, 0, SAL_RESID_POINTER_VSIZEBAR }, // POINTER_VSIZEBAR
+ { 0, 0, SAL_RESID_POINTER_HAND }, // POINTER_HAND
+ { 0, 0, SAL_RESID_POINTER_REFHAND }, // POINTER_REFHAND
+ { 0, 0, SAL_RESID_POINTER_PEN }, // POINTER_PEN
+ { 0, 0, SAL_RESID_POINTER_MAGNIFY }, // POINTER_MAGNIFY
+ { 0, 0, SAL_RESID_POINTER_FILL }, // POINTER_FILL
+ { 0, 0, SAL_RESID_POINTER_ROTATE }, // POINTER_ROTATE
+ { 0, 0, SAL_RESID_POINTER_HSHEAR }, // POINTER_HSHEAR
+ { 0, 0, SAL_RESID_POINTER_VSHEAR }, // POINTER_VSHEAR
+ { 0, 0, SAL_RESID_POINTER_MIRROR }, // POINTER_MIRROR
+ { 0, 0, SAL_RESID_POINTER_CROOK }, // POINTER_CROOK
+ { 0, 0, SAL_RESID_POINTER_CROP }, // POINTER_CROP
+ { 0, 0, SAL_RESID_POINTER_MOVEPOINT }, // POINTER_MOVEPOINT
+ { 0, 0, SAL_RESID_POINTER_MOVEBEZIERWEIGHT }, // POINTER_MOVEBEZIERWEIGHT
+ { 0, 0, SAL_RESID_POINTER_MOVEDATA }, // POINTER_MOVEDATA
+ { 0, 0, SAL_RESID_POINTER_COPYDATA }, // POINTER_COPYDATA
+ { 0, 0, SAL_RESID_POINTER_LINKDATA }, // POINTER_LINKDATA
+ { 0, 0, SAL_RESID_POINTER_MOVEDATALINK }, // POINTER_MOVEDATALINK
+ { 0, 0, SAL_RESID_POINTER_COPYDATALINK }, // POINTER_COPYDATALINK
+ { 0, 0, SAL_RESID_POINTER_MOVEFILE }, // POINTER_MOVEFILE
+ { 0, 0, SAL_RESID_POINTER_COPYFILE }, // POINTER_COPYFILE
+ { 0, 0, SAL_RESID_POINTER_LINKFILE }, // POINTER_LINKFILE
+ { 0, 0, SAL_RESID_POINTER_MOVEFILELINK }, // POINTER_MOVEFILELINK
+ { 0, 0, SAL_RESID_POINTER_COPYFILELINK }, // POINTER_COPYFILELINK
+ { 0, 0, SAL_RESID_POINTER_MOVEFILES }, // POINTER_MOVEFILES
+ { 0, 0, SAL_RESID_POINTER_COPYFILES }, // POINTER_COPYFILES
+ { 0, 0, SAL_RESID_POINTER_NOTALLOWED }, // POINTER_NOTALLOWED
+ { 0, 0, SAL_RESID_POINTER_DRAW_LINE }, // POINTER_DRAW_LINE
+ { 0, 0, SAL_RESID_POINTER_DRAW_RECT }, // POINTER_DRAW_RECT
+ { 0, 0, SAL_RESID_POINTER_DRAW_POLYGON }, // POINTER_DRAW_POLYGON
+ { 0, 0, SAL_RESID_POINTER_DRAW_BEZIER }, // POINTER_DRAW_BEZIER
+ { 0, 0, SAL_RESID_POINTER_DRAW_ARC }, // POINTER_DRAW_ARC
+ { 0, 0, SAL_RESID_POINTER_DRAW_PIE }, // POINTER_DRAW_PIE
+ { 0, 0, SAL_RESID_POINTER_DRAW_CIRCLECUT }, // POINTER_DRAW_CIRCLECUT
+ { 0, 0, SAL_RESID_POINTER_DRAW_ELLIPSE }, // POINTER_DRAW_ELLIPSE
+ { 0, 0, SAL_RESID_POINTER_DRAW_FREEHAND }, // POINTER_DRAW_FREEHAND
+ { 0, 0, SAL_RESID_POINTER_DRAW_CONNECT }, // POINTER_DRAW_CONNECT
+ { 0, 0, SAL_RESID_POINTER_DRAW_TEXT }, // POINTER_DRAW_TEXT
+ { 0, 0, SAL_RESID_POINTER_DRAW_CAPTION }, // POINTER_DRAW_CAPTION
+ { 0, 0, SAL_RESID_POINTER_CHART }, // POINTER_CHART
+ { 0, 0, SAL_RESID_POINTER_DETECTIVE }, // POINTER_DETECTIVE
+ { 0, 0, SAL_RESID_POINTER_PIVOT_COL }, // POINTER_PIVOT_COL
+ { 0, 0, SAL_RESID_POINTER_PIVOT_ROW }, // POINTER_PIVOT_ROW
+ { 0, 0, SAL_RESID_POINTER_PIVOT_FIELD }, // POINTER_PIVOT_FIELD
+ { 0, 0, SAL_RESID_POINTER_CHAIN }, // POINTER_CHAIN
+ { 0, 0, SAL_RESID_POINTER_CHAIN_NOTALLOWED }, // POINTER_CHAIN_NOTALLOWED
+ { 0, 0, SAL_RESID_POINTER_TIMEEVENT_MOVE }, // POINTER_TIMEEVENT_MOVE
+ { 0, 0, SAL_RESID_POINTER_TIMEEVENT_SIZE }, // POINTER_TIMEEVENT_SIZE
+ { 0, 0, SAL_RESID_POINTER_AUTOSCROLL_N }, // POINTER_AUTOSCROLL_N
+ { 0, 0, SAL_RESID_POINTER_AUTOSCROLL_S }, // POINTER_AUTOSCROLL_S
+ { 0, 0, SAL_RESID_POINTER_AUTOSCROLL_W }, // POINTER_AUTOSCROLL_W
+ { 0, 0, SAL_RESID_POINTER_AUTOSCROLL_E }, // POINTER_AUTOSCROLL_E
+ { 0, 0, SAL_RESID_POINTER_AUTOSCROLL_NW }, // POINTER_AUTOSCROLL_NW
+ { 0, 0, SAL_RESID_POINTER_AUTOSCROLL_NE }, // POINTER_AUTOSCROLL_NE
+ { 0, 0, SAL_RESID_POINTER_AUTOSCROLL_SW }, // POINTER_AUTOSCROLL_SW
+ { 0, 0, SAL_RESID_POINTER_AUTOSCROLL_SE }, // POINTER_AUTOSCROLL_SE
+ { 0, 0, SAL_RESID_POINTER_AUTOSCROLL_NS }, // POINTER_AUTOSCROLL_NS
+ { 0, 0, SAL_RESID_POINTER_AUTOSCROLL_WE }, // POINTER_AUTOSCROLL_WE
+ { 0, 0, SAL_RESID_POINTER_AUTOSCROLL_NSWE }, // POINTER_AUTOSCROLL_NSWE
+ { 0, 0, SAL_RESID_POINTER_AIRBRUSH } // POINTER_AIRBRUSH
+ };
+
+#if POINTER_COUNT != 86
+#error New Pointer must be defined!
+#endif
+
+ // Mousepointer loaded ?
+ if ( !aImplPtrTab[ePointerStyle].mhCursor )
+ {
+ if ( aImplPtrTab[ePointerStyle].mnOwnId )
+ aImplPtrTab[ePointerStyle].mhCursor = ImplLoadSalCursor( aImplPtrTab[ePointerStyle].mnOwnId );
+ else
+ aImplPtrTab[ePointerStyle].mhCursor = LoadCursor( 0, aImplPtrTab[ePointerStyle].mnSysId );
+ }
+
+ // Unterscheidet sich der Mauspointer, dann den neuen setzen
+ if ( maFrameData.mhCursor != aImplPtrTab[ePointerStyle].mhCursor )
+ {
+ maFrameData.mhCursor = aImplPtrTab[ePointerStyle].mhCursor;
+ SetCursor( maFrameData.mhCursor );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void SalFrame::CaptureMouse( BOOL bCapture )
+{
+ // Send this Message to the window, because CaptureMouse() only work
+ // in the thread of the window, which has create this window
+ int nMsg;
+ if ( bCapture )
+ nMsg = SAL_MSG_CAPTUREMOUSE;
+ else
+ nMsg = SAL_MSG_RELEASEMOUSE;
+ ImplSendMessage( maFrameData.mhWnd, nMsg, 0, 0 );
+}
+
+// -----------------------------------------------------------------------
+
+void SalFrame::SetPointerPos( long nX, long nY )
+{
+ POINT aPt;
+ aPt.x = (int)nX;
+ aPt.y = (int)nY;
+ ClientToScreen( maFrameData.mhWnd, &aPt );
+ SetCursorPos( aPt.x, aPt.y );
+}
+
+// -----------------------------------------------------------------------
+
+void SalFrame::Flush()
+{
+ GdiFlush();
+}
+
+// -----------------------------------------------------------------------
+
+void SalFrame::Sync()
+{
+ GdiFlush();
+}
+
+// -----------------------------------------------------------------------
+
+void SalFrame::SetInputContext( SalInputContext* pContext )
+{
+ BOOL bIME = pContext->mnOptions != 0;
+ if ( bIME == maFrameData.mbIME )
+ return;
+
+ maFrameData.mbIME = bIME;
+ if ( !bIME )
+ {
+ ImmAssociateContext( maFrameData.mhWnd, 0 );
+ maFrameData.mbHandleIME = FALSE;
+ }
+ else
+ {
+ if ( maFrameData.mhDefIMEContext )
+ {
+ ImmAssociateContext( maFrameData.mhWnd, maFrameData.mhDefIMEContext );
+ UINT nImeProps = ImmGetProperty( GetKeyboardLayout( 0 ), IGP_PROPERTY );
+ maFrameData.mbSpezIME = (nImeProps & IME_PROP_SPECIAL_UI) != 0;
+ maFrameData.mbAtCursorIME = (nImeProps & IME_PROP_AT_CARET) != 0;
+ maFrameData.mbHandleIME = !maFrameData.mbSpezIME;
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void SalFrame::UpdateExtTextInputArea()
+{
+}
+
+// -----------------------------------------------------------------------
+
+void SalFrame::EndExtTextInput( USHORT nFlags )
+{
+ HWND hWnd = maFrameData.mhWnd;
+ HIMC hIMC = ImmGetContext( hWnd );
+ if ( hIMC )
+ {
+ DWORD nIndex;
+ if ( nFlags & SAL_FRAME_ENDEXTTEXTINPUT_COMPLETE )
+ nIndex = CPS_COMPLETE;
+ else
+ nIndex = CPS_CANCEL;
+
+ ImmNotifyIME( hIMC, NI_COMPOSITIONSTR, nIndex, 0 );
+ ImmReleaseContext( hWnd, hIMC );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplGetKeyNameText( LONG lParam, sal_Unicode* pBuf,
+ UINT& rCount, UINT nMaxSize,
+ const sal_Char* pReplace )
+{
+ DBG_ASSERT( sizeof( WCHAR ) == sizeof( xub_Unicode ), "SalFrame::ImplGetKeyNameTextW(): WCHAR != sal_Unicode" );
+
+ WCHAR aKeyBuf[350];
+ int nKeyLen = 0;
+ if ( lParam )
+ {
+ nKeyLen = GetKeyNameTextW( lParam, aKeyBuf, sizeof( aKeyBuf ) / sizeof( sal_Unicode ) );
+ if ( nKeyLen > 0 )
+ {
+ // Convert name, so that the keyname start with an upper
+ // char and the rest of the word are in lower chars
+ CharLowerBuffW( aKeyBuf, nKeyLen );
+ CharUpperBuffW( aKeyBuf, 1 );
+ WCHAR cTempChar;
+ WCHAR* pKeyBuf = aKeyBuf;
+ while ( (cTempChar = *pKeyBuf) != 0 )
+ {
+ if ( (cTempChar == '+') || (cTempChar == '-') ||
+ (cTempChar == ' ') || (cTempChar == '.') )
+ CharUpperBuffW( pKeyBuf+1, 1 );
+ pKeyBuf++;
+ }
+ }
+ else
+ {
+ sal_Char aAnsiKeyBuf[250];
+ int nAnsiKeyLen = GetKeyNameTextA( lParam, aAnsiKeyBuf, sizeof( aAnsiKeyBuf ) / sizeof( sal_Char ) );
+ if ( nAnsiKeyLen )
+ {
+ // Convert name, so that the keyname start with an upper
+ // char and the rest of the word are in lower chars
+ CharLowerBuffA( aAnsiKeyBuf, nAnsiKeyLen );
+ CharUpperBuffA( aAnsiKeyBuf, 1 );
+ sal_Char cTempChar;
+ sal_Char* pAnsiKeyBuf = aAnsiKeyBuf;
+ while ( (cTempChar = *pAnsiKeyBuf) != 0 )
+ {
+ if ( (cTempChar == '+') || (cTempChar == '-') ||
+ (cTempChar == ' ') || (cTempChar == '.') )
+ CharUpperBuffA( pAnsiKeyBuf+1, 1 );
+ pAnsiKeyBuf++;
+ }
+
+ // Convert to Unicode and copy the data in the Unicode Buffer
+ nKeyLen = MultiByteToWideChar( CP_ACP, MB_PRECOMPOSED, aAnsiKeyBuf, nAnsiKeyLen, aKeyBuf, sizeof( aKeyBuf ) / sizeof( sal_Unicode ) );
+ }
+ }
+ }
+
+ if ( (nKeyLen > 0) || pReplace )
+ {
+ if ( rCount )
+ {
+ pBuf[rCount] = '+';
+ rCount++;
+ }
+
+ if ( nKeyLen )
+ {
+ memcpy( pBuf+rCount, aKeyBuf, nKeyLen*sizeof( sal_Unicode ) );
+ rCount += nKeyLen;
+ }
+ else
+ {
+ while ( *pReplace )
+ {
+ pBuf[rCount] = *pReplace;
+ rCount++;
+ pReplace++;
+ }
+ }
+ }
+ else
+ rCount = 0;
+}
+
+// -----------------------------------------------------------------------
+
+XubString SalFrame::GetKeyName( USHORT nKeyCode )
+{
+ XubString aKeyCode;
+ sal_Unicode aKeyBuf[350];
+ UINT nKeyBufLen = 0;
+ UINT nSysCode;
+
+ if ( nKeyCode & KEY_MOD2 )
+ {
+ nSysCode = MapVirtualKey( VK_MENU, 0 );
+ nSysCode = (nSysCode << 16) | (((ULONG)1) << 25);
+ ImplGetKeyNameText( nSysCode, aKeyBuf, nKeyBufLen,
+ sizeof( aKeyBuf ) / sizeof( sal_Unicode ),
+ "Alt" );
+ }
+
+ if ( nKeyCode & KEY_MOD1 )
+ {
+ nSysCode = MapVirtualKey( VK_CONTROL, 0 );
+ nSysCode = (nSysCode << 16) | (((ULONG)1) << 25);
+ ImplGetKeyNameText( nSysCode, aKeyBuf, nKeyBufLen,
+ sizeof( aKeyBuf ) / sizeof( sal_Unicode ),
+ "Ctrl" );
+ }
+
+ if ( nKeyCode & KEY_SHIFT )
+ {
+ nSysCode = MapVirtualKey( VK_SHIFT, 0 );
+ nSysCode = (nSysCode << 16) | (((ULONG)1) << 25);
+ ImplGetKeyNameText( nSysCode, aKeyBuf, nKeyBufLen,
+ sizeof( aKeyBuf ) / sizeof( sal_Unicode ),
+ "Shift" );
+ }
+
+ USHORT nCode = nKeyCode & 0x0FFF;
+ ULONG nSysCode2 = 0;
+ sal_Char* pReplace = NULL;
+ sal_Unicode cSVCode = 0;
+ sal_Char aFBuf[4];
+ nSysCode = 0;
+
+ if ( (nCode >= KEY_0) && (nCode <= KEY_9) )
+ cSVCode = '0' + (nCode - KEY_0);
+ else if ( (nCode >= KEY_A) && (nCode <= KEY_Z) )
+ cSVCode = 'A' + (nCode - KEY_A);
+ else if ( (nCode >= KEY_F1) && (nCode <= KEY_F26) )
+ {
+ nSysCode = VK_F1 + (nCode - KEY_F1);
+ aFBuf[0] = 'F';
+ if ( (nCode >= KEY_F1) && (nCode <= KEY_F9) )
+ {
+ aFBuf[1] = '1' + (nCode - KEY_F1);
+ aFBuf[2] = 0;
+ }
+ else if ( (nCode >= KEY_F10) && (nCode <= KEY_F19) )
+ {
+ aFBuf[1] = '1';
+ aFBuf[2] = '0' + (nCode - KEY_F10);
+ aFBuf[3] = 0;
+ }
+ else
+ {
+ aFBuf[1] = '2';
+ aFBuf[2] = '0' + (nCode - KEY_F20);
+ aFBuf[3] = 0;
+ }
+ pReplace = aFBuf;
+ }
+ else
+ {
+ switch ( nCode )
+ {
+ case KEY_DOWN:
+ nSysCode = VK_DOWN;
+ nSysCode2 = (((ULONG)1) << 24);
+ pReplace = "Down";
+ break;
+ case KEY_UP:
+ nSysCode = VK_UP;
+ nSysCode2 = (((ULONG)1) << 24);
+ pReplace = "Up";
+ break;
+ case KEY_LEFT:
+ nSysCode = VK_LEFT;
+ nSysCode2 = (((ULONG)1) << 24);
+ pReplace = "Left";
+ break;
+ case KEY_RIGHT:
+ nSysCode = VK_RIGHT;
+ nSysCode2 = (((ULONG)1) << 24);
+ pReplace = "Right";
+ break;
+ case KEY_HOME:
+ nSysCode = VK_HOME;
+ nSysCode2 = (((ULONG)1) << 24);
+ pReplace = "Home";
+ break;
+ case KEY_END:
+ nSysCode = VK_END;
+ nSysCode2 = (((ULONG)1) << 24);
+ pReplace = "End";
+ break;
+ case KEY_PAGEUP:
+ nSysCode = VK_PRIOR;
+ nSysCode2 = (((ULONG)1) << 24);
+ pReplace = "Page Up";
+ break;
+ case KEY_PAGEDOWN:
+ nSysCode = VK_NEXT;
+ nSysCode2 = (((ULONG)1) << 24);
+ pReplace = "Page Down";
+ break;
+ case KEY_RETURN:
+ nSysCode = VK_RETURN;
+ pReplace = "Enter";
+ break;
+ case KEY_ESCAPE:
+ nSysCode = VK_ESCAPE;
+ pReplace = "Escape";
+ break;
+ case KEY_TAB:
+ nSysCode = VK_TAB;
+ pReplace = "Tab";
+ break;
+ case KEY_BACKSPACE:
+ nSysCode = VK_BACK;
+ pReplace = "Backspace";
+ break;
+ case KEY_SPACE:
+ nSysCode = VK_SPACE;
+ pReplace = "Space";
+ break;
+ case KEY_INSERT:
+ nSysCode = VK_INSERT;
+ nSysCode2 = (((ULONG)1) << 24);
+ pReplace = "Insert";
+ break;
+ case KEY_DELETE:
+ nSysCode = VK_DELETE;
+ nSysCode2 = (((ULONG)1) << 24);
+ pReplace = "Delete";
+ break;
+
+ case KEY_ADD:
+ cSVCode = '+';
+ break;
+ case KEY_SUBTRACT:
+ cSVCode = '-';
+ break;
+ case KEY_MULTIPLY:
+ cSVCode = '*';
+ break;
+ case KEY_DIVIDE:
+ cSVCode = '/';
+ break;
+ case KEY_POINT:
+ cSVCode = '.';
+ break;
+ case KEY_COMMA:
+ cSVCode = ',';
+ break;
+ case KEY_LESS:
+ cSVCode = '<';
+ break;
+ case KEY_GREATER:
+ cSVCode = '>';
+ break;
+ case KEY_EQUAL:
+ cSVCode = '=';
+ break;
+ }
+ }
+
+ if ( nSysCode )
+ {
+ nSysCode = MapVirtualKey( (UINT)nSysCode, 0 );
+ if ( nSysCode )
+ nSysCode = (nSysCode << 16) | nSysCode2;
+ ImplGetKeyNameText( nSysCode, aKeyBuf, nKeyBufLen,
+ sizeof( aKeyBuf ) / sizeof( sal_Unicode ),
+ pReplace );
+ }
+ else
+ {
+ if ( cSVCode )
+ {
+ if ( !nKeyBufLen )
+ {
+ aKeyBuf[0] = cSVCode;
+ nKeyBufLen = 1;
+ }
+ else
+ {
+ aKeyBuf[nKeyBufLen] = '+';
+ nKeyBufLen++;
+ aKeyBuf[nKeyBufLen] = cSVCode;
+ nKeyBufLen++;
+ }
+ }
+ }
+
+ if ( nKeyBufLen )
+ aKeyCode.Assign( (const sal_Unicode*)aKeyBuf, nKeyBufLen );
+
+ return aKeyCode;
+}
+
+// -----------------------------------------------------------------------
+
+XubString SalFrame::GetSymbolKeyName( const XubString&, USHORT nKeyCode )
+{
+ return GetKeyName( nKeyCode );
+}
+
+// -----------------------------------------------------------------------
+
+inline Color ImplWinColorToSal( COLORREF nColor )
+{
+ return Color( GetRValue( nColor ), GetGValue( nColor ), GetBValue( nColor ) );
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplSalUpdateStyleFontA( const LOGFONTA& rLogFont, Font& rFont,
+ BOOL bOverwriteSystemCharSet )
+{
+ ImplSalLogFontToFontA( rLogFont, rFont );
+ if ( bOverwriteSystemCharSet && (rFont.GetCharSet() != RTL_TEXTENCODING_SYMBOL) )
+ rFont.SetCharSet( gsl_getSystemTextEncoding() );
+ // Da bei einigen Windows-Einstellungen 6 Punkt eingetragen ist,
+ // obwohl im Dialog 8 Punkt angezeigt werden (da MS Sans Serif
+ // nicht skalierbar ist) vergroessern wir hier das als Hack, da
+ // ansonsten in russisch Symbolunterschriften nicht lesbar sind
+ if ( (rFont.GetName().EqualsIgnoreCaseAscii( "MS Sans Serif" ) ) &&
+ (rFont.GetHeight() < 8) )
+ rFont.SetHeight( 8 );
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplSalUpdateStyleFontW( const LOGFONTW& rLogFont, Font& rFont,
+ BOOL bOverwriteSystemCharSet )
+{
+ ImplSalLogFontToFontW( rLogFont, rFont );
+ if ( bOverwriteSystemCharSet && (rFont.GetCharSet() != RTL_TEXTENCODING_SYMBOL) )
+ rFont.SetCharSet( gsl_getSystemTextEncoding() );
+ // Da bei einigen Windows-Einstellungen 6 Punkt eingetragen ist,
+ // obwohl im Dialog 8 Punkt angezeigt werden (da MS Sans Serif
+ // nicht skalierbar ist) vergroessern wir hier das als Hack, da
+ // ansonsten in russisch Symbolunterschriften nicht lesbar sind
+ if ( (rFont.GetName().EqualsIgnoreCaseAscii( "MS Sans Serif" ) ) &&
+ (rFont.GetHeight() < 8) )
+ rFont.SetHeight( 8 );
+}
+
+// -----------------------------------------------------------------------
+
+static long ImplA2I( const BYTE* pStr )
+{
+ long n = 0;
+ int nSign = 1;
+
+ if ( *pStr == '-' )
+ {
+ nSign = -1;
+ pStr++;
+ }
+
+ while( (*pStr >= 48) && (*pStr <= 57) )
+ {
+ n *= 10;
+ n += ((*pStr) - 48);
+ pStr++;
+ }
+
+ n *= nSign;
+
+ return n;
+}
+
+// -----------------------------------------------------------------------
+
+void SalFrame::UpdateSettings( AllSettings& rSettings )
+{
+ MouseSettings aMouseSettings = rSettings.GetMouseSettings();
+ aMouseSettings.SetDoubleClickTime( GetDoubleClickTime() );
+ aMouseSettings.SetDoubleClickWidth( GetSystemMetrics( SM_CXDOUBLECLK ) );
+ aMouseSettings.SetDoubleClickHeight( GetSystemMetrics( SM_CYDOUBLECLK ) );
+ long nDragWidth = GetSystemMetrics( SM_CXDRAG );
+ long nDragHeight = GetSystemMetrics( SM_CYDRAG );
+ if ( nDragWidth )
+ aMouseSettings.SetStartDragWidth( nDragWidth );
+ if ( nDragHeight )
+ aMouseSettings.SetStartDragHeight( nDragHeight );
+ HKEY hRegKey;
+ if ( RegOpenKey( HKEY_CURRENT_USER,
+ "Control Panel\\Desktop",
+ &hRegKey ) == ERROR_SUCCESS )
+ {
+ BYTE aValueBuf[10];
+ DWORD nValueSize = sizeof( aValueBuf );
+ DWORD nType;
+ if ( RegQueryValueEx( hRegKey, "MenuShowDelay", 0,
+ &nType, aValueBuf, &nValueSize ) == ERROR_SUCCESS )
+ {
+ if ( nType == REG_SZ )
+ aMouseSettings.SetMenuDelay( (ULONG)ImplA2I( aValueBuf ) );
+ }
+
+ RegCloseKey( hRegKey );
+ }
+
+ StyleSettings aStyleSettings = rSettings.GetStyleSettings();
+ BOOL bCompBorder = (aStyleSettings.GetOptions() & (STYLE_OPTION_MACSTYLE | STYLE_OPTION_UNIXSTYLE)) == 0;
+ aStyleSettings.SetScrollBarSize( GetSystemMetrics( SM_CXVSCROLL ) );
+ aStyleSettings.SetSpinSize( GetSystemMetrics( SM_CXVSCROLL ) );
+ aStyleSettings.SetCursorBlinkTime( GetCaretBlinkTime() );
+ if ( bCompBorder )
+ {
+ aStyleSettings.SetFloatTitleHeight( GetSystemMetrics( SM_CYSMCAPTION ) );
+ aStyleSettings.SetTitleHeight( GetSystemMetrics( SM_CYCAPTION ) );
+ aStyleSettings.SetActiveBorderColor( ImplWinColorToSal( GetSysColor( COLOR_ACTIVEBORDER ) ) );
+ aStyleSettings.SetDeactiveBorderColor( ImplWinColorToSal( GetSysColor( COLOR_INACTIVEBORDER ) ) );
+ if ( aSalShlData.mnVersion >= 410 )
+ {
+ aStyleSettings.SetActiveColor2( ImplWinColorToSal( GetSysColor( COLOR_GRADIENTACTIVECAPTION ) ) );
+ aStyleSettings.SetDeactiveColor( ImplWinColorToSal( GetSysColor( COLOR_GRADIENTINACTIVECAPTION ) ) );
+ }
+ aStyleSettings.SetFaceColor( ImplWinColorToSal( GetSysColor( COLOR_3DFACE ) ) );
+ aStyleSettings.SetLightColor( ImplWinColorToSal( GetSysColor( COLOR_3DHILIGHT ) ) );
+ aStyleSettings.SetLightBorderColor( ImplWinColorToSal( GetSysColor( COLOR_3DLIGHT ) ) );
+ aStyleSettings.SetShadowColor( ImplWinColorToSal( GetSysColor( COLOR_3DSHADOW ) ) );
+ aStyleSettings.SetDarkShadowColor( ImplWinColorToSal( GetSysColor( COLOR_3DDKSHADOW ) ) );
+ }
+ aStyleSettings.SetHelpColor( ImplWinColorToSal( GetSysColor( COLOR_INFOBK ) ) );
+ aStyleSettings.SetHelpTextColor( ImplWinColorToSal( GetSysColor( COLOR_INFOTEXT ) ) );
+ aStyleSettings.SetDialogColor( aStyleSettings.GetFaceColor() );
+ aStyleSettings.SetDialogTextColor( aStyleSettings.GetButtonTextColor() );
+ aStyleSettings.SetButtonTextColor( ImplWinColorToSal( GetSysColor( COLOR_BTNTEXT ) ) );
+ aStyleSettings.SetRadioCheckTextColor( ImplWinColorToSal( GetSysColor( COLOR_WINDOWTEXT ) ) );
+ aStyleSettings.SetGroupTextColor( aStyleSettings.GetRadioCheckTextColor() );
+ aStyleSettings.SetLabelTextColor( aStyleSettings.GetRadioCheckTextColor() );
+ aStyleSettings.SetInfoTextColor( aStyleSettings.GetRadioCheckTextColor() );
+ aStyleSettings.SetWindowColor( ImplWinColorToSal( GetSysColor( COLOR_WINDOW ) ) );
+ aStyleSettings.SetWindowTextColor( ImplWinColorToSal( GetSysColor( COLOR_WINDOWTEXT ) ) );
+ aStyleSettings.SetFieldColor( aStyleSettings.GetWindowColor() );
+ aStyleSettings.SetFieldTextColor( aStyleSettings.GetWindowTextColor() );
+ aStyleSettings.SetHighlightColor( ImplWinColorToSal( GetSysColor( COLOR_HIGHLIGHT ) ) );
+ aStyleSettings.SetHighlightTextColor( ImplWinColorToSal( GetSysColor( COLOR_HIGHLIGHTTEXT ) ) );
+ aStyleSettings.SetMenuHighlightColor( aStyleSettings.GetHighlightColor() );
+ aStyleSettings.SetMenuHighlightTextColor( aStyleSettings.GetHighlightTextColor() );
+ if ( bCompBorder )
+ {
+ aStyleSettings.SetMenuColor( ImplWinColorToSal( GetSysColor( COLOR_MENU ) ) );
+ aStyleSettings.SetMenuTextColor( ImplWinColorToSal( GetSysColor( COLOR_MENUTEXT ) ) );
+ aStyleSettings.SetActiveColor( ImplWinColorToSal( GetSysColor( COLOR_ACTIVECAPTION ) ) );
+ aStyleSettings.SetActiveTextColor( ImplWinColorToSal( GetSysColor( COLOR_CAPTIONTEXT ) ) );
+ aStyleSettings.SetDeactiveColor( ImplWinColorToSal( GetSysColor( COLOR_INACTIVECAPTION ) ) );
+ aStyleSettings.SetDeactiveTextColor( ImplWinColorToSal( GetSysColor( COLOR_INACTIVECAPTIONTEXT ) ) );
+ }
+ // Bei hellgrau geben wir die Farbe vor, damit es besser aussieht
+ if ( aStyleSettings.GetFaceColor() == COL_LIGHTGRAY )
+ aStyleSettings.SetCheckedColor( Color( 0xCC, 0xCC, 0xCC ) );
+ else
+ {
+ // Checked-Color berechnen
+ Color aColor1 = aStyleSettings.GetFaceColor();
+ Color aColor2 = aStyleSettings.GetLightColor();
+ BYTE nRed = (BYTE)(((USHORT)aColor1.GetRed() + (USHORT)aColor2.GetRed())/2);
+ BYTE nGreen = (BYTE)(((USHORT)aColor1.GetGreen() + (USHORT)aColor2.GetGreen())/2);
+ BYTE nBlue = (BYTE)(((USHORT)aColor1.GetBlue() + (USHORT)aColor2.GetBlue())/2);
+ aStyleSettings.SetCheckedColor( Color( nRed, nGreen, nBlue ) );
+ }
+
+ // Query Fonts
+ int bOverwriteSystemCharSet = getenv("LC_CHARSET") != 0;
+ Font aMenuFont = aStyleSettings.GetMenuFont();
+ Font aTitleFont = aStyleSettings.GetTitleFont();
+ Font aFloatTitleFont = aStyleSettings.GetFloatTitleFont();
+ Font aHelpFont = aStyleSettings.GetHelpFont();
+ Font aAppFont = aStyleSettings.GetAppFont();
+ Font aIconFont = aStyleSettings.GetIconFont();
+ if ( aSalShlData.mbWNT )
+ {
+ NONCLIENTMETRICSW aNonClientMetrics;
+ aNonClientMetrics.cbSize = sizeof( aNonClientMetrics );
+ if ( SystemParametersInfoW( SPI_GETNONCLIENTMETRICS, sizeof( aNonClientMetrics ), &aNonClientMetrics, 0 ) )
+ {
+ ImplSalUpdateStyleFontW( aNonClientMetrics.lfMenuFont, aMenuFont, bOverwriteSystemCharSet );
+ ImplSalUpdateStyleFontW( aNonClientMetrics.lfCaptionFont, aTitleFont, bOverwriteSystemCharSet );
+ ImplSalUpdateStyleFontW( aNonClientMetrics.lfSmCaptionFont, aFloatTitleFont, bOverwriteSystemCharSet );
+ ImplSalUpdateStyleFontW( aNonClientMetrics.lfStatusFont, aHelpFont, bOverwriteSystemCharSet );
+ ImplSalUpdateStyleFontW( aNonClientMetrics.lfMessageFont, aAppFont, bOverwriteSystemCharSet );
+
+ LOGFONTW aLogFont;
+ if ( SystemParametersInfoW( SPI_GETICONTITLELOGFONT, 0, &aLogFont, 0 ) )
+ ImplSalUpdateStyleFontW( aLogFont, aIconFont, bOverwriteSystemCharSet );
+ }
+ }
+ else
+ {
+ NONCLIENTMETRICSA aNonClientMetrics;
+ aNonClientMetrics.cbSize = sizeof( aNonClientMetrics );
+ if ( SystemParametersInfoA( SPI_GETNONCLIENTMETRICS, sizeof( aNonClientMetrics ), &aNonClientMetrics, 0 ) )
+ {
+ ImplSalUpdateStyleFontA( aNonClientMetrics.lfMenuFont, aMenuFont, bOverwriteSystemCharSet );
+ ImplSalUpdateStyleFontA( aNonClientMetrics.lfCaptionFont, aTitleFont, bOverwriteSystemCharSet );
+ ImplSalUpdateStyleFontA( aNonClientMetrics.lfSmCaptionFont, aFloatTitleFont, bOverwriteSystemCharSet );
+ ImplSalUpdateStyleFontA( aNonClientMetrics.lfStatusFont, aHelpFont, bOverwriteSystemCharSet );
+ ImplSalUpdateStyleFontA( aNonClientMetrics.lfMessageFont, aAppFont, bOverwriteSystemCharSet );
+
+ LOGFONTA aLogFont;
+ if ( SystemParametersInfoA( SPI_GETICONTITLELOGFONT, 0, &aLogFont, 0 ) )
+ ImplSalUpdateStyleFontA( aLogFont, aIconFont, bOverwriteSystemCharSet );
+ }
+ }
+ aStyleSettings.SetMenuFont( aMenuFont );
+ aStyleSettings.SetTitleFont( aTitleFont );
+ aStyleSettings.SetFloatTitleFont( aFloatTitleFont );
+ aStyleSettings.SetHelpFont( aHelpFont );
+ aStyleSettings.SetIconFont( aIconFont );
+ // We prefer Arial in the russian version, because MS Sans Serif
+ // is to wide for the dialogs
+ if ( rSettings.GetInternational().GetLanguage() == LANGUAGE_RUSSIAN )
+ {
+ XubString aFontName = aAppFont.GetName();
+ XubString aFirstName = aFontName.GetToken( 0, ';' );
+ if ( aFirstName.EqualsIgnoreCaseAscii( "MS Sans Serif" ) )
+ {
+ aFontName.InsertAscii( "Arial;", 0 );
+ aAppFont.SetName( aFontName );
+ }
+ }
+ aStyleSettings.SetAppFont( aAppFont );
+ aStyleSettings.SetGroupFont( aAppFont );
+ aStyleSettings.SetLabelFont( aAppFont );
+ aStyleSettings.SetRadioCheckFont( aAppFont );
+ aStyleSettings.SetPushButtonFont( aAppFont );
+ aStyleSettings.SetFieldFont( aAppFont );
+ if ( aAppFont.GetWeight() > WEIGHT_NORMAL )
+ aAppFont.SetWeight( WEIGHT_NORMAL );
+ aStyleSettings.SetInfoFont( aAppFont );
+ aStyleSettings.SetToolFont( aAppFont );
+
+ WIN_BOOL bDragFull;
+ if ( SystemParametersInfo( SPI_GETDRAGFULLWINDOWS, 0, &bDragFull, 0 ) )
+ {
+ ULONG nDragFullOptions = aStyleSettings.GetDragFullOptions();
+ if ( bDragFull )
+ nDragFullOptions |= DRAGFULL_OPTION_WINDOWMOVE | DRAGFULL_OPTION_WINDOWSIZE | DRAGFULL_OPTION_DOCKING | DRAGFULL_OPTION_SPLIT;
+ else
+ nDragFullOptions &= ~(DRAGFULL_OPTION_WINDOWMOVE | DRAGFULL_OPTION_WINDOWSIZE | DRAGFULL_OPTION_DOCKING | DRAGFULL_OPTION_SPLIT);
+ aStyleSettings.SetDragFullOptions( nDragFullOptions );
+ }
+
+ aStyleSettings.SetIconHorzSpace( GetSystemMetrics( SM_CXICONSPACING ) );
+ aStyleSettings.SetIconVertSpace( GetSystemMetrics( SM_CYICONSPACING ) );
+ if ( RegOpenKey( HKEY_CURRENT_USER,
+ "Control Panel\\International\\Calendars\\TwoDigitYearMax",
+ &hRegKey ) == ERROR_SUCCESS )
+ {
+ BYTE aValueBuf[10];
+ DWORD nValue;
+ DWORD nValueSize = sizeof( aValueBuf );
+ DWORD nType;
+ if ( RegQueryValueEx( hRegKey, "1", 0,
+ &nType, aValueBuf, &nValueSize ) == ERROR_SUCCESS )
+ {
+ if ( nType == REG_SZ )
+ {
+ nValue = (ULONG)ImplA2I( aValueBuf );
+ if ( (nValue > 1000) && (nValue < 10000) )
+ {
+ MiscSettings aMiscSettings = rSettings.GetMiscSettings();
+ aMiscSettings.SetTwoDigitYearStart( (USHORT)(nValue-99) );
+ rSettings.SetMiscSettings( aMiscSettings );
+ }
+ }
+ }
+
+ RegCloseKey( hRegKey );
+ }
+
+ rSettings.SetMouseSettings( aMouseSettings );
+ rSettings.SetStyleSettings( aStyleSettings );
+}
+
+// -----------------------------------------------------------------------
+
+const SystemEnvData* SalFrame::GetSystemData() const
+{
+ return &maFrameData.maSysData;
+}
+
+// -----------------------------------------------------------------------
+
+void SalFrame::Beep( SoundType eSoundType )
+{
+ static UINT aImplSoundTab[5] =
+ {
+ 0, // SOUND_DEFAULT
+ MB_ICONASTERISK, // SOUND_INFO
+ MB_ICONEXCLAMATION, // SOUND_WARNING
+ MB_ICONHAND, // SOUND_ERROR
+ MB_ICONQUESTION // SOUND_QUERY
+ };
+
+#if SOUND_COUNT != 5
+#error New Sound must be defined!
+#endif
+
+ MessageBeep( aImplSoundTab[eSoundType] );
+}
+
+// -----------------------------------------------------------------------
+
+void SalFrame::SetCallback( void* pInst, SALFRAMEPROC pProc )
+{
+ maFrameData.mpInst = pInst;
+ if ( pProc )
+ maFrameData.mpProc = pProc;
+ else
+ maFrameData.mpProc = ImplSalCallbackDummy;
+}
+
+// -----------------------------------------------------------------------
+
+static long ImplHandleMouseMsg( HWND hWnd, UINT nMsg,
+ WPARAM wParam, LPARAM lParam )
+{
+ SalFrame* pFrame = GetWindowPtr( hWnd );
+ if ( !pFrame )
+ return 0;
+
+ SalMouseEvent aMouseEvt;
+ long nRet;
+ USHORT nEvent;
+ BOOL bCall = TRUE;
+
+ aMouseEvt.mnX = (short)LOWORD( lParam );
+ aMouseEvt.mnY = (short)HIWORD( lParam );
+ aMouseEvt.mnCode = 0;
+ aMouseEvt.mnTime = GetMessageTime();
+
+ // Wegen (Logitech-)MouseTreiber ueber GetKeyState() gehen, die auf
+ // mittlerer Maustaste Doppelklick simulieren und den KeyStatus nicht
+ // beruecksichtigen
+
+ if ( GetKeyState( VK_LBUTTON ) & 0x8000 )
+ aMouseEvt.mnCode |= MOUSE_LEFT;
+ if ( GetKeyState( VK_MBUTTON ) & 0x8000 )
+ aMouseEvt.mnCode |= MOUSE_MIDDLE;
+ if ( GetKeyState( VK_RBUTTON ) & 0x8000 )
+ aMouseEvt.mnCode |= MOUSE_RIGHT;
+ if ( GetKeyState( VK_SHIFT ) & 0x8000 )
+ aMouseEvt.mnCode |= KEY_SHIFT;
+ if ( GetKeyState( VK_CONTROL ) & 0x8000 )
+ aMouseEvt.mnCode |= KEY_MOD1;
+ if ( GetKeyState( VK_MENU ) & 0x8000 )
+ aMouseEvt.mnCode |= KEY_MOD2;
+
+ switch ( nMsg )
+ {
+ case WM_MOUSEMOVE:
+ {
+ // Da bei Druecken von Modifier-Tasten die MouseEvents
+ // nicht zusammengefast werden (da diese durch KeyEvents
+ // unterbrochen werden), machen wir dieses hier selber
+ if ( aMouseEvt.mnCode & (KEY_SHIFT | KEY_MOD1 | KEY_MOD2) )
+ {
+ MSG aTempMsg;
+ if ( ImplPeekMessage( &aTempMsg, hWnd, WM_MOUSEFIRST, WM_MOUSELAST, PM_NOREMOVE | PM_NOYIELD ) )
+ {
+ if ( (aTempMsg.message == WM_MOUSEMOVE) &&
+ (aTempMsg.wParam == wParam) )
+ return 1;
+ }
+ }
+
+ SalData* pSalData = GetSalData();
+ // Test for MouseLeave
+ if ( pSalData->mhWantLeaveMsg && (pSalData->mhWantLeaveMsg != hWnd) )
+ ImplSendMessage( pSalData->mhWantLeaveMsg, SAL_MSG_MOUSELEAVE, 0, GetMessagePos() );
+ pSalData->mhWantLeaveMsg = hWnd;
+ // Start MouseLeave-Timer
+ if ( !pSalData->mpMouseLeaveTimer )
+ {
+ pSalData->mpMouseLeaveTimer = new AutoTimer;
+ pSalData->mpMouseLeaveTimer->SetTimeout( SAL_MOUSELEAVE_TIMEOUT );
+ pSalData->mpMouseLeaveTimer->Start();
+ // We dont need to set a timeout handler, because we test
+ // for mouseleave in the timeout callback
+ }
+ aMouseEvt.mnButton = 0;
+ nEvent = SALEVENT_MOUSEMOVE;
+ }
+ break;
+
+ case WM_NCMOUSEMOVE:
+ case SAL_MSG_MOUSELEAVE:
+ {
+ SalData* pSalData = GetSalData();
+ if ( pSalData->mhWantLeaveMsg == hWnd )
+ {
+ pSalData->mhWantLeaveMsg = 0;
+ if ( pSalData->mpMouseLeaveTimer )
+ {
+ delete pSalData->mpMouseLeaveTimer;
+ pSalData->mpMouseLeaveTimer = NULL;
+ }
+ // Mouse-Coordinaates are relativ to the screen
+ POINT aPt;
+ aPt.x = (short)LOWORD( lParam );
+ aPt.y = (short)HIWORD( lParam );
+ ScreenToClient( hWnd, &aPt );
+ aMouseEvt.mnX = aPt.x;
+ aMouseEvt.mnY = aPt.y;
+ aMouseEvt.mnButton = 0;
+ nEvent = SALEVENT_MOUSELEAVE;
+ }
+ else
+ bCall = FALSE;
+ }
+ break;
+
+ case WM_LBUTTONDOWN:
+ aMouseEvt.mnButton = MOUSE_LEFT;
+ nEvent = SALEVENT_MOUSEBUTTONDOWN;
+ break;
+
+ case WM_MBUTTONDOWN:
+ aMouseEvt.mnButton = MOUSE_MIDDLE;
+ nEvent = SALEVENT_MOUSEBUTTONDOWN;
+ break;
+
+ case WM_RBUTTONDOWN:
+ aMouseEvt.mnButton = MOUSE_RIGHT;
+ nEvent = SALEVENT_MOUSEBUTTONDOWN;
+ break;
+
+ case WM_LBUTTONUP:
+ aMouseEvt.mnButton = MOUSE_LEFT;
+ nEvent = SALEVENT_MOUSEBUTTONUP;
+ break;
+
+ case WM_MBUTTONUP:
+ aMouseEvt.mnButton = MOUSE_MIDDLE;
+ nEvent = SALEVENT_MOUSEBUTTONUP;
+ break;
+
+ case WM_RBUTTONUP:
+ aMouseEvt.mnButton = MOUSE_RIGHT;
+ nEvent = SALEVENT_MOUSEBUTTONUP;
+ break;
+ }
+
+ if ( bCall )
+ {
+ if ( nEvent == SALEVENT_MOUSEBUTTONDOWN )
+ UpdateWindow( hWnd );
+
+ nRet = pFrame->maFrameData.mpProc( pFrame->maFrameData.mpInst, pFrame,
+ nEvent, &aMouseEvt );
+ if ( nMsg == WM_MOUSEMOVE )
+ SetCursor( pFrame->maFrameData.mhCursor );
+ }
+ else
+ nRet = 0;
+
+ return nRet;
+}
+
+// -----------------------------------------------------------------------
+
+static long ImplHandleMouseActivateMsg( HWND hWnd )
+{
+ SalFrame* pFrame = GetWindowPtr( hWnd );
+ if ( !pFrame )
+ return 0;
+
+ SalMouseActivateEvent aMouseActivateEvt;
+ POINT aPt;
+ GetCursorPos( &aPt );
+ ScreenToClient( hWnd, &aPt );
+ aMouseActivateEvt.mnX = aPt.x;
+ aMouseActivateEvt.mnY = aPt.y;
+ return pFrame->maFrameData.mpProc( pFrame->maFrameData.mpInst, pFrame,
+ SALEVENT_MOUSEACTIVATE, &aMouseActivateEvt );
+}
+
+// -----------------------------------------------------------------------
+
+static long ImplHandleWheelMsg( HWND hWnd, WPARAM wParam, LPARAM lParam )
+{
+ ImplSalYieldMutexAcquireWithWait();
+
+ long nRet = 0;
+ SalFrame* pFrame = GetWindowPtr( hWnd );
+ if ( pFrame )
+ {
+ WORD nWinModCode = LOWORD( wParam );
+ POINT aWinPt;
+ aWinPt.x = (short)LOWORD( lParam );
+ aWinPt.y = (short)HIWORD( lParam );
+ ScreenToClient( hWnd, &aWinPt );
+
+ SalWheelMouseEvent aWheelEvt;
+ aWheelEvt.mnTime = GetMessageTime();
+ aWheelEvt.mnX = aWinPt.x;
+ aWheelEvt.mnY = aWinPt.y;
+ aWheelEvt.mnCode = 0;
+ aWheelEvt.mnDelta = (short)HIWORD( wParam );
+ aWheelEvt.mnNotchDelta = aWheelEvt.mnDelta/WHEEL_DELTA;
+ if ( aSalShlData.mnWheelScrollLines == WHEEL_PAGESCROLL )
+ aWheelEvt.mnScrollLines = SAL_WHEELMOUSE_EVENT_PAGESCROLL;
+ else
+ aWheelEvt.mnScrollLines = aSalShlData.mnWheelScrollLines;
+ aWheelEvt.mbHorz = FALSE;
+
+ if ( nWinModCode & MK_SHIFT )
+ aWheelEvt.mnCode |= KEY_SHIFT;
+ if ( nWinModCode & MK_CONTROL )
+ aWheelEvt.mnCode |= KEY_MOD1;
+ if ( GetKeyState( VK_MENU ) & 0x8000 )
+ aWheelEvt.mnCode |= KEY_MOD2;
+
+ nRet = pFrame->maFrameData.mpProc( pFrame->maFrameData.mpInst, pFrame,
+ SALEVENT_WHEELMOUSE, &aWheelEvt );
+ }
+
+ ImplSalYieldMutexRelease();
+
+ return nRet;
+}
+
+// -----------------------------------------------------------------------
+
+static USHORT ImplSalGetKeyCode( WPARAM wParam )
+{
+ USHORT nKeyCode;
+
+ // convert KeyCode
+ if ( wParam < KEY_TAB_SIZE )
+ nKeyCode = aImplTranslateKeyTab[wParam];
+ else if ( wParam == aSalShlData.mnVKAdd )
+ nKeyCode = KEY_ADD;
+ else if ( wParam == aSalShlData.mnVKSubtract )
+ nKeyCode = KEY_SUBTRACT;
+ else if ( wParam == aSalShlData.mnVKMultiply )
+ nKeyCode = KEY_MULTIPLY;
+ else if ( wParam == aSalShlData.mnVKDivide )
+ nKeyCode = KEY_DIVIDE;
+ else if ( wParam == aSalShlData.mnVKPoint )
+ nKeyCode = KEY_POINT;
+ else if ( wParam == aSalShlData.mnVKComma )
+ nKeyCode = KEY_COMMA;
+ else if ( wParam == aSalShlData.mnVKLess )
+ nKeyCode = KEY_LESS;
+ else if ( wParam == aSalShlData.mnVKGreater )
+ nKeyCode = KEY_GREATER;
+ else if ( wParam == aSalShlData.mnVKEqual )
+ nKeyCode = KEY_EQUAL;
+ else
+ nKeyCode = 0;
+
+ return nKeyCode;
+}
+
+// -----------------------------------------------------------------------
+
+static UINT ImplStrToNum( const sal_Char* pStr )
+{
+ USHORT n = 0;
+
+ // Solange es sich um eine Ziffer handelt, String umwandeln
+ while( (*pStr >= 48) && (*pStr <= 57) )
+ {
+ n *= 10;
+ n += ((*pStr) - 48);
+ pStr++;
+ }
+
+ return n;
+}
+
+// -----------------------------------------------------------------------
+
+static sal_Unicode ImplGetCharCode( SalFrame* pFrame, WPARAM nCharCode )
+{
+ // If we are on Windows NT we use Unicode FrameProcs and so we
+ // get Unicode charcodes directly from Windows
+ if ( aSalShlData.mbWNT )
+ return (sal_Unicode)nCharCode;
+
+ UINT nLang = LOWORD( GetKeyboardLayout( 0 ) );
+ if ( !nLang )
+ {
+ pFrame->maFrameData.mnInputLang = 0;
+ pFrame->maFrameData.mnInputCodePage = GetACP();
+ }
+ else if ( nLang != pFrame->maFrameData.mnInputLang )
+ {
+ pFrame->maFrameData.mnInputLang = nLang;
+ sal_Char aBuf[10];
+ if ( GetLocaleInfoA( MAKELCID( nLang, SORT_DEFAULT ), LOCALE_IDEFAULTANSICODEPAGE,
+ aBuf, sizeof(aBuf) ) > 0 )
+ {
+ pFrame->maFrameData.mnInputCodePage = ImplStrToNum( aBuf );
+ if ( !pFrame->maFrameData.mnInputCodePage )
+ pFrame->maFrameData.mnInputCodePage = GetACP();
+ }
+ else
+ pFrame->maFrameData.mnInputCodePage = GetACP();
+ }
+
+ sal_Char aCharBuf[2];
+ int nCharLen;
+ WCHAR c;
+ if ( nCharCode > 0xFF )
+ {
+ aCharBuf[0] = (sal_Char)(nCharCode>>8);
+ aCharBuf[1] = (sal_Char)nCharCode;
+ nCharLen = 2;
+ }
+ else
+ {
+ aCharBuf[0] = (sal_Char)nCharCode;
+ nCharLen = 1;
+ }
+ if ( ::MultiByteToWideChar( pFrame->maFrameData.mnInputCodePage,
+ MB_PRECOMPOSED,
+ aCharBuf, nCharLen, &c, 1 ) )
+ return (sal_Unicode)c;
+ else
+ return (sal_Unicode)nCharCode;
+}
+
+// -----------------------------------------------------------------------
+
+static long ImplHandleKeyMsg( HWND hWnd, UINT nMsg,
+ WPARAM wParam, LPARAM lParam )
+{
+ static BOOL bIgnoreCharMsg = FALSE;
+ static WPARAM nDeadChar = 0;
+ static WPARAM nLastVKChar = 0;
+ static USHORT nLastChar = 0;
+ USHORT nRepeat = LOWORD( lParam )-1;
+ USHORT nModCode = 0;
+
+ // Key wurde evtl. durch SysChild an uns weitergeleitet und
+ // darf somit dann nicht doppelt verarbeitet werden
+ GetSalData()->mnSalObjWantKeyEvt = 0;
+
+ if ( nMsg == WM_DEADCHAR )
+ {
+ nDeadChar = wParam;
+ return 0;
+ }
+
+ SalFrame* pFrame = GetWindowPtr( hWnd );
+ if ( !pFrame )
+ return 0;
+
+ // Wir restaurieren den Background-Modus bei jeder Texteingabe,
+ // da einige Tools wie RichWin uns diesen hin- und wieder umsetzen
+ if ( pFrame->maFrameData.mpGraphics &&
+ pFrame->maFrameData.mpGraphics->maGraphicsData.mhDC )
+ SetBkMode( pFrame->maFrameData.mpGraphics->maGraphicsData.mhDC, TRANSPARENT );
+
+ // determine modifiers
+ if ( GetKeyState( VK_SHIFT ) & 0x8000 )
+ nModCode |= KEY_SHIFT;
+ if ( GetKeyState( VK_CONTROL ) & 0x8000 )
+ nModCode |= KEY_MOD1;
+ if ( GetKeyState( VK_MENU ) & 0x8000 )
+ {
+ nModCode |= KEY_MOD2;
+ if ( !(nModCode & KEY_MOD1) &&
+ ((nMsg == WM_SYSKEYDOWN) || (nMsg == WM_SYSKEYUP)) )
+ nModCode |= KEY_CONTROLMOD;
+ }
+
+ if ( (nMsg == WM_CHAR) || (nMsg == WM_SYSCHAR) )
+ {
+ nDeadChar = 0;
+
+ if ( bIgnoreCharMsg )
+ {
+ bIgnoreCharMsg = FALSE;
+ return 0;
+ }
+
+ // Backspace ignorieren wir als eigenstaendige Taste,
+ // damit wir keine Probleme in Kombination mit einem
+ // DeadKey bekommen
+ if ( wParam == 0x08 ) // BACKSPACE
+ return 0;
+
+ // Hier kommen nur "freifliegende" WM_CHAR Message an, die durch
+ // eintippen einer ALT-NUMPAD Kombination erzeugt wurden
+ SalKeyEvent aKeyEvt;
+
+ if ( (wParam >= '0') && (wParam <= '9') )
+ aKeyEvt.mnCode = KEYGROUP_NUM + wParam - '0';
+ else if ( (wParam >= 'A') && (wParam <= 'Z') )
+ aKeyEvt.mnCode = KEYGROUP_ALPHA + wParam - 'A';
+ else if ( (wParam >= 'a') && (wParam <= 'z') )
+ aKeyEvt.mnCode = KEYGROUP_ALPHA + wParam - 'a';
+ else if ( wParam == 0x0D ) // RETURN
+ aKeyEvt.mnCode = KEY_RETURN;
+ else if ( wParam == 0x1B ) // ESCAPE
+ aKeyEvt.mnCode = KEY_ESCAPE;
+ else if ( wParam == 0x09 ) // TAB
+ aKeyEvt.mnCode = KEY_TAB;
+ else if ( wParam == 0x20 ) // SPACE
+ aKeyEvt.mnCode = KEY_SPACE;
+ else
+ aKeyEvt.mnCode = 0;
+
+ aKeyEvt.mnTime = GetMessageTime();
+ aKeyEvt.mnCode |= nModCode;
+ aKeyEvt.mnCharCode = ImplGetCharCode( pFrame, wParam );
+ aKeyEvt.mnRepeat = nRepeat;
+ nLastChar = 0;
+ nLastVKChar = 0;
+ long nRet = pFrame->maFrameData.mpProc( pFrame->maFrameData.mpInst, pFrame,
+ SALEVENT_KEYINPUT, &aKeyEvt );
+ pFrame->maFrameData.mpProc( pFrame->maFrameData.mpInst, pFrame,
+ SALEVENT_KEYUP, &aKeyEvt );
+ return nRet;
+ }
+ else
+ {
+ // Bei Shift, Control und Menu schicken wir einen KeyModChange-Event
+ if ( (wParam == VK_SHIFT) || (wParam == VK_CONTROL) || (wParam == VK_MENU) )
+ {
+ SalKeyModEvent aModEvt;
+ aModEvt.mnTime = GetMessageTime();
+ aModEvt.mnCode = nModCode;
+ return pFrame->maFrameData.mpProc( pFrame->maFrameData.mpInst, pFrame,
+ SALEVENT_KEYMODCHANGE, &aModEvt );
+ }
+ else
+ {
+ SalKeyEvent aKeyEvt;
+ USHORT nEvent;
+ MSG aCharMsg;
+ WIN_BOOL bCharPeek = FALSE;
+ UINT nCharMsg = WM_CHAR;
+ BOOL bKeyUp = (nMsg == WM_KEYUP) || (nMsg == WM_SYSKEYUP);
+
+ aKeyEvt.mnCode = ImplSalGetKeyCode( wParam );
+ if ( !bKeyUp )
+ {
+ // check for charcode
+ // Mit Hilfe von PeekMessage holen wir uns jetzt die
+ // zugehoerige WM_CHAR Message, wenn vorhanden.
+ // Diese WM_CHAR Message steht immer am Anfang der
+ // Messagequeue. Ausserdem ist sichergestellt, dass immer
+ // nur eine WM_CHAR Message in der Queue steht.
+ bCharPeek = ImplPeekMessage( &aCharMsg, hWnd,
+ WM_CHAR, WM_CHAR, PM_NOREMOVE | PM_NOYIELD );
+ if ( bCharPeek && (nDeadChar == aCharMsg.wParam) )
+ {
+ bCharPeek = FALSE;
+ nDeadChar = 0;
+
+ if ( wParam == VK_BACK )
+ {
+ ImplPeekMessage( &aCharMsg, hWnd,
+ nCharMsg, nCharMsg, PM_REMOVE | PM_NOYIELD );
+ return 0;
+ }
+ }
+ else
+ {
+ if ( !bCharPeek )
+ {
+ bCharPeek = ImplPeekMessage( &aCharMsg, hWnd,
+ WM_SYSCHAR, WM_SYSCHAR, PM_NOREMOVE | PM_NOYIELD );
+ nCharMsg = WM_SYSCHAR;
+ }
+ }
+ if ( bCharPeek )
+ aKeyEvt.mnCharCode = ImplGetCharCode( pFrame, aCharMsg.wParam );
+ else
+ aKeyEvt.mnCharCode = 0;
+
+ nLastChar = aKeyEvt.mnCharCode;
+ nLastVKChar = wParam;
+ }
+ else
+ {
+ if ( wParam == nLastVKChar )
+ {
+ aKeyEvt.mnCharCode = nLastChar;
+ nLastChar = 0;
+ nLastVKChar = 0;
+ }
+ }
+
+ if ( aKeyEvt.mnCode || aKeyEvt.mnCharCode )
+ {
+ if ( bKeyUp )
+ nEvent = SALEVENT_KEYUP;
+ else
+ nEvent = SALEVENT_KEYINPUT;
+
+ aKeyEvt.mnTime = GetMessageTime();
+ aKeyEvt.mnCode |= nModCode;
+ aKeyEvt.mnRepeat = nRepeat;
+ bIgnoreCharMsg = bCharPeek;
+ long nRet = pFrame->maFrameData.mpProc( pFrame->maFrameData.mpInst, pFrame,
+ nEvent, &aKeyEvt );
+ bIgnoreCharMsg = FALSE;
+
+ // char-message, than remove or ignore
+ if ( bCharPeek )
+ {
+ nDeadChar = 0;
+ if ( nRet )
+ {
+ ImplPeekMessage( &aCharMsg, hWnd,
+ nCharMsg, nCharMsg, PM_REMOVE | PM_NOYIELD );
+ }
+ else
+ bIgnoreCharMsg = TRUE;
+ }
+
+ return nRet;
+ }
+ else
+ return 0;
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+long ImplHandleSalObjKeyMsg( HWND hWnd, UINT nMsg,
+ WPARAM wParam, LPARAM lParam )
+{
+ if ( (nMsg == WM_KEYDOWN) || (nMsg == WM_KEYUP) )
+ {
+ SalFrame* pFrame = GetWindowPtr( hWnd );
+ if ( !pFrame )
+ return 0;
+
+ USHORT nRepeat = LOWORD( lParam )-1;
+ USHORT nModCode = 0;
+
+ // determine modifiers
+ if ( GetKeyState( VK_SHIFT ) & 0x8000 )
+ nModCode |= KEY_SHIFT;
+ if ( GetKeyState( VK_CONTROL ) & 0x8000 )
+ nModCode |= KEY_MOD1;
+ if ( GetKeyState( VK_MENU ) & 0x8000 )
+ {
+ nModCode |= KEY_MOD2;
+ if ( !(nModCode & KEY_MOD1) )
+ nModCode |= KEY_CONTROLMOD;
+ }
+
+ if ( (wParam != VK_SHIFT) && (wParam != VK_CONTROL) && (wParam != VK_MENU) )
+ {
+ SalKeyEvent aKeyEvt;
+ USHORT nEvent;
+ BOOL bKeyUp = (nMsg == WM_KEYUP) || (nMsg == WM_SYSKEYUP);
+
+ // convert KeyCode
+ aKeyEvt.mnCode = ImplSalGetKeyCode( wParam );
+ aKeyEvt.mnCharCode = 0;
+
+ if ( aKeyEvt.mnCode )
+ {
+ if ( bKeyUp )
+ nEvent = SALEVENT_KEYUP;
+ else
+ nEvent = SALEVENT_KEYINPUT;
+
+ aKeyEvt.mnTime = GetMessageTime();
+ aKeyEvt.mnCode |= nModCode;
+ aKeyEvt.mnRepeat = nRepeat;
+ long nRet = pFrame->maFrameData.mpProc( pFrame->maFrameData.mpInst, pFrame,
+ nEvent, &aKeyEvt );
+ return nRet;
+ }
+ else
+ return 0;
+ }
+ }
+
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+long ImplHandleSalObjSysCharMsg( HWND hWnd, WPARAM wParam, LPARAM lParam )
+{
+ SalFrame* pFrame = GetWindowPtr( hWnd );
+ if ( !pFrame )
+ return 0;
+
+ USHORT nRepeat = LOWORD( lParam )-1;
+ USHORT nModCode = 0;
+ USHORT cKeyCode = (USHORT)wParam;
+
+ // determine modifiers
+ if ( GetKeyState( VK_SHIFT ) & 0x8000 )
+ nModCode |= KEY_SHIFT;
+ if ( GetKeyState( VK_CONTROL ) & 0x8000 )
+ nModCode |= KEY_MOD1;
+ nModCode |= KEY_MOD2;
+ if ( !(nModCode & KEY_MOD1) )
+ nModCode |= KEY_CONTROLMOD;
+
+ // KeyEvent zusammenbauen
+ SalKeyEvent aKeyEvt;
+ aKeyEvt.mnTime = GetMessageTime();
+ if ( (cKeyCode >= 48) && (cKeyCode <= 57) )
+ aKeyEvt.mnCode = KEY_0+(cKeyCode-48);
+ else if ( (cKeyCode >= 65) && (cKeyCode <= 90) )
+ aKeyEvt.mnCode = KEY_A+(cKeyCode-65);
+ else if ( (cKeyCode >= 97) && (cKeyCode <= 122) )
+ aKeyEvt.mnCode = KEY_A+(cKeyCode-97);
+ else
+ aKeyEvt.mnCode = 0;
+ aKeyEvt.mnCode |= nModCode;
+ aKeyEvt.mnCharCode = ImplGetCharCode( pFrame, cKeyCode );
+ aKeyEvt.mnRepeat = nRepeat;
+ long nRet = pFrame->maFrameData.mpProc( pFrame->maFrameData.mpInst, pFrame,
+ SALEVENT_KEYINPUT, &aKeyEvt );
+ pFrame->maFrameData.mpProc( pFrame->maFrameData.mpInst, pFrame,
+ SALEVENT_KEYUP, &aKeyEvt );
+ return nRet;
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplHandlePaintMsg( HWND hWnd )
+{
+ // Clip-Region muss zurueckgesetzt werden, da wir sonst kein
+ // ordentliches Bounding-Rectangle bekommen
+ if ( ImplSalYieldMutexTryToAcquire() )
+ {
+ SalFrame* pFrame = GetWindowPtr( hWnd );
+ if ( pFrame && pFrame->maFrameData.mpGraphics )
+ {
+ if ( pFrame->maFrameData.mpGraphics->maGraphicsData.mhRegion )
+ SelectClipRgn( pFrame->maFrameData.mpGraphics->maGraphicsData.mhDC, 0 );
+ }
+ ImplSalYieldMutexRelease();
+ }
+
+ // Laut Window-Doku soll man erst abfragen, ob ueberhaupt eine
+ // Paint-Region anliegt
+ if ( !GetUpdateRect( hWnd, NULL, FALSE ) )
+ return;
+
+ // BeginPaint
+ PAINTSTRUCT aPs;
+ BeginPaint( hWnd, &aPs );
+
+ // Paint
+ if ( ImplSalYieldMutexTryToAcquire() )
+ {
+ SalFrame* pFrame = GetWindowPtr( hWnd );
+ if ( pFrame )
+ {
+ // ClipRegion wieder herstellen
+ if ( pFrame->maFrameData.mpGraphics )
+ {
+ if ( pFrame->maFrameData.mpGraphics->maGraphicsData.mhRegion )
+ {
+ SelectClipRgn( pFrame->maFrameData.mpGraphics->maGraphicsData.mhDC,
+ pFrame->maFrameData.mpGraphics->maGraphicsData.mhRegion );
+ }
+ }
+
+ SalPaintEvent aPEvt;
+ aPEvt.mnBoundX = aPs.rcPaint.left;
+ aPEvt.mnBoundY = aPs.rcPaint.top;
+ aPEvt.mnBoundWidth = aPs.rcPaint.right-aPs.rcPaint.left;
+ aPEvt.mnBoundHeight = aPs.rcPaint.bottom-aPs.rcPaint.top;
+ pFrame->maFrameData.mpProc( pFrame->maFrameData.mpInst, pFrame,
+ SALEVENT_PAINT, &aPEvt );
+ }
+
+ ImplSalYieldMutexRelease();
+ }
+ else
+ {
+ RECT* pRect = new RECT;
+ *pRect = aPs.rcPaint;
+ ImplPostMessage( hWnd, SAL_MSG_POSTPAINT, (WPARAM)pRect, 0 );
+ }
+
+ // EndPaint
+ EndPaint( hWnd, &aPs );
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplHandlePaintMsg2( HWND hWnd, RECT* pRect )
+{
+ // Paint
+ if ( ImplSalYieldMutexTryToAcquire() )
+ {
+ SalFrame* pFrame = GetWindowPtr( hWnd );
+ if ( pFrame )
+ {
+ SalPaintEvent aPEvt;
+ aPEvt.mnBoundX = pRect->left;
+ aPEvt.mnBoundY = pRect->top;
+ aPEvt.mnBoundWidth = pRect->right-pRect->left;
+ aPEvt.mnBoundHeight = pRect->bottom-pRect->top;
+ pFrame->maFrameData.mpProc( pFrame->maFrameData.mpInst, pFrame,
+ SALEVENT_PAINT, &aPEvt );
+ }
+ ImplSalYieldMutexRelease();
+ delete pRect;
+ }
+ else
+ ImplPostMessage( hWnd, SAL_MSG_POSTPAINT, (WPARAM)pRect, 0 );
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplHandleMoveMsg( HWND hWnd )
+{
+ if ( ImplSalYieldMutexTryToAcquire() )
+ {
+ SalFrame* pFrame = GetWindowPtr( hWnd );
+ if ( pFrame )
+ {
+ if ( GetWindowStyle( hWnd ) & WS_VISIBLE )
+ pFrame->maFrameData.mbDefPos = FALSE;
+
+ // Gegen moegliche Rekursionen sichern
+ if ( !pFrame->maFrameData.mbInMoveMsg )
+ {
+ // Fenster im FullScreenModus wieder einpassen
+ pFrame->maFrameData.mbInMoveMsg = TRUE;
+ if ( pFrame->maFrameData.mbFullScreen )
+ ImplSalFrameFullScreenPos( pFrame );
+ pFrame->maFrameData.mbInMoveMsg = FALSE;
+ }
+
+ // Status merken
+ ImplSaveFrameState( pFrame );
+ }
+
+ ImplSalYieldMutexRelease();
+ }
+ else
+ ImplPostMessage( hWnd, SAL_MSG_POSTMOVE, 0, 0 );
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplCallSizeHdl( HWND hWnd )
+{
+ // Da Windows diese Messages auch senden kann, muss hier auch die
+ // Solar-Semaphore beruecksichtigt werden
+ if ( ImplSalYieldMutexTryToAcquire() )
+ {
+ SalFrame* pFrame = GetWindowPtr( hWnd );
+ if ( pFrame )
+ {
+ pFrame->maFrameData.mpProc( pFrame->maFrameData.mpInst, pFrame,
+ SALEVENT_RESIZE, 0 );
+ // Um doppelte Paints von VCL und SAL zu vermeiden
+ if ( IsWindowVisible( hWnd ) && !pFrame->maFrameData.mbInShow )
+ UpdateWindow( hWnd );
+ }
+
+ ImplSalYieldMutexRelease();
+ }
+ else
+ ImplPostMessage( hWnd, SAL_MSG_POSTCALLSIZE, 0, 0 );
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplHandleSizeMsg( HWND hWnd, WPARAM wParam, LPARAM lParam )
+{
+ if ( (wParam != SIZE_MAXSHOW) && (wParam != SIZE_MAXHIDE) )
+ {
+ SalFrame* pFrame = GetWindowPtr( hWnd );
+ if ( pFrame )
+ {
+ pFrame->maFrameData.mnWidth = (int)LOWORD(lParam);
+ pFrame->maFrameData.mnHeight = (int)HIWORD(lParam);
+ // Status merken
+ ImplSaveFrameState( pFrame );
+ // Call Hdl
+ ImplCallSizeHdl( hWnd );
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplHandleFocusMsg( HWND hWnd )
+{
+ if ( ImplSalYieldMutexTryToAcquire() )
+ {
+ SalFrame* pFrame = GetWindowPtr( hWnd );
+ if ( pFrame )
+ {
+ // Query the actual status
+ if ( ::GetFocus() == hWnd )
+ {
+ if ( IsWindowVisible( hWnd ) && !pFrame->maFrameData.mbInShow )
+ UpdateWindow( hWnd );
+ pFrame->maFrameData.mpProc( pFrame->maFrameData.mpInst, pFrame,
+ SALEVENT_GETFOCUS, 0 );
+ }
+ else
+ {
+ pFrame->maFrameData.mpProc( pFrame->maFrameData.mpInst, pFrame,
+ SALEVENT_LOSEFOCUS, 0 );
+ }
+ }
+
+ ImplSalYieldMutexRelease();
+ }
+ else
+ ImplPostMessage( hWnd, SAL_MSG_POSTFOCUS, 0, 0 );
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplHandleCloseMsg( HWND hWnd )
+{
+ if ( ImplSalYieldMutexTryToAcquire() )
+ {
+ SalFrame* pFrame = GetWindowPtr( hWnd );
+ if ( pFrame )
+ {
+ pFrame->maFrameData.mpProc( pFrame->maFrameData.mpInst, pFrame,
+ SALEVENT_CLOSE, 0 );
+ }
+
+ ImplSalYieldMutexRelease();
+ }
+ else
+ ImplPostMessage( hWnd, WM_CLOSE, 0, 0 );
+}
+
+// -----------------------------------------------------------------------
+
+static long ImplHandleShutDownMsg( HWND hWnd )
+{
+ ImplSalYieldMutexAcquireWithWait();
+ long nRet = 0;
+ SalFrame* pFrame = GetWindowPtr( hWnd );
+ if ( pFrame )
+ {
+ nRet = pFrame->maFrameData.mpProc( pFrame->maFrameData.mpInst, pFrame,
+ SALEVENT_SHUTDOWN, 0 );
+ }
+ ImplSalYieldMutexRelease();
+ return nRet;
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplHandleSettingsChangeMsg( HWND hWnd, UINT nMsg,
+ WPARAM wParam, LPARAM lParam )
+{
+ USHORT nSalEvent = SALEVENT_SETTINGSCHANGED;
+
+ if ( nMsg == WM_DEVMODECHANGE )
+ nSalEvent = SALEVENT_PRINTERCHANGED;
+#ifdef WM_DISPLAYCHANGE
+ else if ( nMsg == WM_DISPLAYCHANGE )
+ nSalEvent = SALEVENT_DISPLAYCHANGED;
+#endif
+ else if ( nMsg == WM_FONTCHANGE )
+ nSalEvent = SALEVENT_FONTCHANGED;
+ else if ( nMsg == WM_TIMECHANGE )
+ nSalEvent = SALEVENT_DATETIMECHANGED;
+ else if ( nMsg == WM_WININICHANGE )
+ {
+ if ( lParam )
+ {
+ if ( aSalShlData.mbWNT )
+ {
+ if ( ImplSalWICompareAscii( (const wchar_t*)lParam, "devices" ) == 0 )
+ nSalEvent = SALEVENT_PRINTERCHANGED;
+ }
+ else
+ {
+ if ( stricmp( (const char*)lParam, "devices" ) == 0 )
+ nSalEvent = SALEVENT_PRINTERCHANGED;
+ }
+ }
+ }
+
+#ifdef WM_SETTINGCHANGE
+ if ( nMsg == WM_SETTINGCHANGE )
+ {
+ if ( wParam == SPI_SETWHEELSCROLLLINES )
+ aSalShlData.mnWheelScrollLines = ImplSalGetWheelScrollLines();
+ }
+#endif
+
+ if ( WM_SYSCOLORCHANGE == nMsg && GetSalData()->mhDitherPal )
+ ImplUpdateSysColorEntries();
+
+ ImplSalYieldMutexAcquireWithWait();
+
+ SalFrame* pFrame = GetWindowPtr( hWnd );
+ if ( pFrame )
+ {
+ if ( (nMsg == WM_DISPLAYCHANGE) || (nMsg == WM_WININICHANGE) )
+ {
+ if ( pFrame->maFrameData.mbFullScreen )
+ ImplSalFrameFullScreenPos( pFrame );
+ }
+
+ pFrame->maFrameData.mpProc( pFrame->maFrameData.mpInst, pFrame,
+ nSalEvent, 0 );
+ }
+
+ ImplSalYieldMutexRelease();
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplHandleUserEvent( HWND hWnd, LPARAM lParam )
+{
+ ImplSalYieldMutexAcquireWithWait();
+ SalFrame* pFrame = GetWindowPtr( hWnd );
+ if ( pFrame )
+ {
+ pFrame->maFrameData.mpProc( pFrame->maFrameData.mpInst, pFrame,
+ SALEVENT_USEREVENT, (void*)lParam );
+ }
+ ImplSalYieldMutexRelease();
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplHandleForcePalette( HWND hWnd )
+{
+ SalData* pSalData = GetSalData();
+ HPALETTE hPal = pSalData->mhDitherPal;
+ if ( hPal )
+ {
+ if ( !ImplSalYieldMutexTryToAcquire() )
+ {
+ ImplPostMessage( hWnd, SAL_MSG_FORCEPALETTE, 0, 0 );
+ return;
+ }
+
+ SalFrame* pFrame = GetWindowPtr( hWnd );
+ if ( pFrame && pFrame->maFrameData.mpGraphics )
+ {
+ SalGraphics* pGraphics = pFrame->maFrameData.mpGraphics;
+ if ( pGraphics && pGraphics->maGraphicsData.mhDefPal )
+ {
+ SelectPalette( pGraphics->maGraphicsData.mhDC, hPal, FALSE );
+ if ( RealizePalette( pGraphics->maGraphicsData.mhDC ) )
+ {
+ InvalidateRect( hWnd, NULL, FALSE );
+ UpdateWindow( hWnd );
+ pFrame->maFrameData.mpProc( pFrame->maFrameData.mpInst, pFrame,
+ SALEVENT_DISPLAYCHANGED, 0 );
+ }
+ }
+ }
+
+ ImplSalYieldMutexRelease();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+static LRESULT ImplHandlePalette( BOOL bFrame, HWND hWnd, UINT nMsg,
+ WPARAM wParam, LPARAM lParam, int& rDef )
+{
+ SalData* pSalData = GetSalData();
+ HPALETTE hPal = pSalData->mhDitherPal;
+ if ( !hPal )
+ return 0;
+
+ rDef = FALSE;
+ if ( pSalData->mbInPalChange )
+ return 0;
+
+ if ( (nMsg == WM_PALETTECHANGED) || (nMsg == SAL_MSG_POSTPALCHANGED) )
+ {
+ if ( (HWND)wParam == hWnd )
+ return 0;
+ }
+
+ BOOL bReleaseMutex = FALSE;
+ if ( (nMsg == WM_QUERYNEWPALETTE) || (nMsg == WM_PALETTECHANGED) )
+ {
+ // Da Windows diese Messages auch sendet, muss hier auch die
+ // Solar-Semaphore beruecksichtigt werden
+ if ( ImplSalYieldMutexTryToAcquire() )
+ bReleaseMutex = TRUE;
+ else if ( nMsg == WM_QUERYNEWPALETTE )
+ ImplPostMessage( hWnd, SAL_MSG_POSTQUERYNEWPAL, wParam, lParam );
+ else /* ( nMsg == WM_PALETTECHANGED ) */
+ ImplPostMessage( hWnd, SAL_MSG_POSTPALCHANGED, wParam, lParam );
+ }
+
+ SalVirtualDevice* pTempVD;
+ SalFrame* pTempFrame;
+ SalGraphics* pGraphics;
+ HDC hDC;
+ HPALETTE hOldPal;
+ UINT nCols;
+ BOOL bStdDC;
+ BOOL bUpdate;
+
+ pSalData->mbInPalChange = TRUE;
+
+ // Alle Paletten in VirDevs und Frames zuruecksetzen
+ pTempVD = pSalData->mpFirstVD;
+ while ( pTempVD )
+ {
+ pGraphics = pTempVD->maVirDevData.mpGraphics;
+ if ( pGraphics->maGraphicsData.mhDefPal )
+ {
+ SelectPalette( pGraphics->maGraphicsData.mhDC,
+ pGraphics->maGraphicsData.mhDefPal,
+ TRUE );
+ }
+ pTempVD = pTempVD->maVirDevData.mpNext;
+ }
+ pTempFrame = pSalData->mpFirstFrame;
+ while ( pTempFrame )
+ {
+ pGraphics = pTempFrame->maFrameData.mpGraphics;
+ if ( pGraphics && pGraphics->maGraphicsData.mhDefPal )
+ {
+ SelectPalette( pGraphics->maGraphicsData.mhDC,
+ pGraphics->maGraphicsData.mhDefPal,
+ TRUE );
+ }
+ pTempFrame = pTempFrame->maFrameData.mpNextFrame;
+ }
+
+ // Palette neu realizen
+ SalFrame* pFrame = NULL;
+ if ( bFrame )
+ pFrame = GetWindowPtr( hWnd );
+ if ( pFrame && pFrame->maFrameData.mpGraphics )
+ {
+ hDC = pFrame->maFrameData.mpGraphics->maGraphicsData.mhDC;
+ bStdDC = TRUE;
+ }
+ else
+ {
+ hDC = GetDC( hWnd );
+ bStdDC = FALSE;
+ }
+ UnrealizeObject( hPal );
+ hOldPal = SelectPalette( hDC, hPal, TRUE );
+ nCols = RealizePalette( hDC );
+ bUpdate = nCols != 0;
+ if ( !bStdDC )
+ {
+ SelectPalette( hDC, hOldPal, TRUE );
+ ReleaseDC( hWnd, hDC );
+ }
+
+ // Alle Paletten in VirDevs und Frames neu setzen
+ pTempVD = pSalData->mpFirstVD;
+ while ( pTempVD )
+ {
+ pGraphics = pTempVD->maVirDevData.mpGraphics;
+ if ( pGraphics->maGraphicsData.mhDefPal )
+ {
+ SelectPalette( pGraphics->maGraphicsData.mhDC, hPal, TRUE );
+ RealizePalette( pGraphics->maGraphicsData.mhDC );
+ }
+ pTempVD = pTempVD->maVirDevData.mpNext;
+ }
+ pTempFrame = pSalData->mpFirstFrame;
+ while ( pTempFrame )
+ {
+ if ( pTempFrame != pFrame )
+ {
+ pGraphics = pTempFrame->maFrameData.mpGraphics;
+ if ( pGraphics && pGraphics->maGraphicsData.mhDefPal )
+ {
+ SelectPalette( pGraphics->maGraphicsData.mhDC, hPal, TRUE );
+ if ( RealizePalette( pGraphics->maGraphicsData.mhDC ) )
+ bUpdate = TRUE;
+ }
+ }
+ pTempFrame = pTempFrame->maFrameData.mpNextFrame;
+ }
+
+ // Wenn sich Farben geaendert haben, dann die Fenster updaten
+ if ( bUpdate )
+ {
+ pTempFrame = pSalData->mpFirstFrame;
+ while ( pTempFrame )
+ {
+ pGraphics = pTempFrame->maFrameData.mpGraphics;
+ if ( pGraphics && pGraphics->maGraphicsData.mhDefPal )
+ {
+ InvalidateRect( pTempFrame->maFrameData.mhWnd, NULL, FALSE );
+ UpdateWindow( pTempFrame->maFrameData.mhWnd );
+ pTempFrame->maFrameData.mpProc( pTempFrame->maFrameData.mpInst, pTempFrame,
+ SALEVENT_DISPLAYCHANGED, 0 );
+ }
+ pTempFrame = pTempFrame->maFrameData.mpNextFrame;
+ }
+ }
+
+ pSalData->mbInPalChange = FALSE;
+
+ if ( bReleaseMutex )
+ ImplSalYieldMutexRelease();
+
+ if ( nMsg == WM_PALETTECHANGED )
+ return 0;
+ else
+ return nCols;
+}
+
+// -----------------------------------------------------------------------
+
+static int ImplHandleMinMax( HWND hWnd, LPARAM lParam )
+{
+ int bRet = FALSE;
+
+ if ( ImplSalYieldMutexTryToAcquire() )
+ {
+ SalFrame* pFrame = GetWindowPtr( hWnd );
+ if ( pFrame )
+ {
+ if ( pFrame->maFrameData.mbFullScreen )
+ {
+ MINMAXINFO* pMinMax = (MINMAXINFO*)lParam;
+ int nX;
+ int nY;
+ int nDX;
+ int nDY;
+ ImplSalCalcFullScreenSize( pFrame, nX, nY, nDX, nDY );
+
+ if ( pMinMax->ptMaxPosition.x > nX )
+ pMinMax->ptMaxPosition.x = nX;
+ if ( pMinMax->ptMaxPosition.y > nY )
+ pMinMax->ptMaxPosition.y = nY;
+
+ if ( pMinMax->ptMaxSize.x < nDX )
+ pMinMax->ptMaxSize.x = nDX;
+ if ( pMinMax->ptMaxSize.y < nDY )
+ pMinMax->ptMaxSize.y = nDY;
+ if ( pMinMax->ptMaxTrackSize.x < nDX )
+ pMinMax->ptMaxTrackSize.x = nDX;
+ if ( pMinMax->ptMaxTrackSize.y < nDY )
+ pMinMax->ptMaxTrackSize.y = nDY;
+
+ pMinMax->ptMinTrackSize.x = nDX;
+ pMinMax->ptMinTrackSize.y = nDY;
+
+ bRet = TRUE;
+ }
+ }
+
+ ImplSalYieldMutexRelease();
+ }
+
+ return bRet;
+}
+
+// -----------------------------------------------------------------------
+
+static int ImplHandleSysCommand( HWND hWnd, WPARAM wParam, LPARAM lParam )
+{
+ SalFrame* pFrame = GetWindowPtr( hWnd );
+ if ( !pFrame )
+ return 0;
+
+ WPARAM nCommand = wParam & 0xFFF0;
+
+ if ( pFrame->maFrameData.mbFullScreen )
+ {
+ WIN_BOOL bMaximize = IsZoomed( pFrame->maFrameData.mhWnd );
+ WIN_BOOL bMinimize = IsIconic( pFrame->maFrameData.mhWnd );
+ if ( (nCommand == SC_SIZE) ||
+ (!bMinimize && (nCommand == SC_MOVE)) ||
+ (!bMaximize && (nCommand == SC_MAXIMIZE)) ||
+ (bMaximize && (nCommand == SC_RESTORE)) )
+ {
+ MessageBeep( 0 );
+ return TRUE;
+ }
+ }
+
+ if ( nCommand == SC_KEYMENU )
+ {
+ // Hier verarbeiten wir nur KeyMenu-Events fuer Alt um
+ // den MenuBar zu aktivieren, oder wenn ein SysChild-Fenster
+ // den Focus hat, da diese Alt+Tasten-Kombinationen nur
+ // ueber diesen Event verarbeitet werden
+ if ( !LOWORD( lParam ) )
+ {
+ // Nur ausloesen, wenn keine weitere Taste gedrueckt ist. Im
+ // Gegensatz zur Doku wird in der X-Koordinaate der CharCode
+ // geliefert, der zusaetzlich gedrueckt ist
+ // Also 32 fuer Space, 99 fuer c, 100 fuer d, ...
+ // Da dies nicht dokumentiert ist, fragen wir vorsichtshalber
+ // auch den Status der Space-Taste ab
+ if ( GetKeyState( VK_SPACE ) & 0x8000 )
+ return 0;
+
+ // Damit nicht bei Alt+Maustaste auch der MenuBar aktiviert wird
+ if ( (GetKeyState( VK_LBUTTON ) & 0x8000) ||
+ (GetKeyState( VK_RBUTTON ) & 0x8000) ||
+ (GetKeyState( VK_MBUTTON ) & 0x8000) )
+ return 1;
+
+ SalKeyEvent aKeyEvt;
+ aKeyEvt.mnTime = GetMessageTime();
+ aKeyEvt.mnCode = KEY_MENU;
+ aKeyEvt.mnCharCode = 0;
+ aKeyEvt.mnRepeat = 0;
+ long nRet = pFrame->maFrameData.mpProc( pFrame->maFrameData.mpInst, pFrame,
+ SALEVENT_KEYINPUT, &aKeyEvt );
+ pFrame->maFrameData.mpProc( pFrame->maFrameData.mpInst, pFrame,
+ SALEVENT_KEYUP, &aKeyEvt );
+ return (nRet != 0);
+ }
+ else
+ {
+ // Testen, ob ein SysChild den Focus hat
+ HWND hFocusWnd = ::GetFocus();
+ if ( hFocusWnd && ImplFindSalObject( hFocusWnd ) )
+ {
+ char cKeyCode = (char)(unsigned char)LOWORD( lParam );
+ // LowerCase
+ if ( (cKeyCode >= 65) && (cKeyCode <= 90) )
+ cKeyCode += 32;
+ // Wir nehmen nur 0-9 und A-Z, alle anderen Tasten muessen durch
+ // den Hook vom SalObj verarbeitet werden
+ if ( ((cKeyCode >= 48) && (cKeyCode <= 57)) ||
+ ((cKeyCode >= 97) && (cKeyCode <= 122)) )
+ {
+ USHORT nModCode = 0;
+ if ( GetKeyState( VK_SHIFT ) & 0x8000 )
+ nModCode |= KEY_SHIFT;
+ if ( GetKeyState( VK_CONTROL ) & 0x8000 )
+ nModCode |= KEY_MOD1;
+ nModCode |= KEY_MOD2;
+ if ( !(nModCode & KEY_MOD1) )
+ nModCode |= KEY_CONTROLMOD;
+
+ SalKeyEvent aKeyEvt;
+ aKeyEvt.mnTime = GetMessageTime();
+ if ( (cKeyCode >= 48) && (cKeyCode <= 57) )
+ aKeyEvt.mnCode = KEY_0+(cKeyCode-48);
+ else
+ aKeyEvt.mnCode = KEY_A+(cKeyCode-97);
+ aKeyEvt.mnCode |= nModCode;
+ aKeyEvt.mnCharCode = cKeyCode;
+ aKeyEvt.mnRepeat = 0;
+ long nRet = pFrame->maFrameData.mpProc( pFrame->maFrameData.mpInst, pFrame,
+ SALEVENT_KEYINPUT, &aKeyEvt );
+ pFrame->maFrameData.mpProc( pFrame->maFrameData.mpInst, pFrame,
+ SALEVENT_KEYUP, &aKeyEvt );
+ return (nRet != 0);
+ }
+ }
+ }
+ }
+
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplHandleInputLangChange( HWND hWnd, WPARAM wParam, LPARAM lParam )
+{
+ ImplSalYieldMutexAcquireWithWait();
+
+ // Feststellen, ob wir IME unterstuetzen
+ SalFrame* pFrame = GetWindowPtr( hWnd );
+ if ( pFrame && pFrame->maFrameData.mbIME && pFrame->maFrameData.mhDefIMEContext )
+ {
+ HWND hWnd = pFrame->maFrameData.mhWnd;
+ HKL hKL = (HKL)lParam;
+ UINT nImeProps = ImmGetProperty( hKL, IGP_PROPERTY );
+
+ pFrame->maFrameData.mbSpezIME = (nImeProps & IME_PROP_SPECIAL_UI) != 0;
+ pFrame->maFrameData.mbAtCursorIME = (nImeProps & IME_PROP_AT_CARET) != 0;
+ pFrame->maFrameData.mbHandleIME = !pFrame->maFrameData.mbSpezIME;
+ }
+
+ ImplSalYieldMutexRelease();
+}
+
+// -----------------------------------------------------------------------
+
+static BOOL ImplHandleIMEStartComposition( HWND hWnd )
+{
+ BOOL bDef = TRUE;
+
+ ImplSalYieldMutexAcquireWithWait();
+
+ SalFrame* pFrame = GetWindowPtr( hWnd );
+ if ( pFrame )
+ {
+ if ( pFrame->maFrameData.mbHandleIME )
+ {
+ HIMC hIMC = ImmGetContext( hWnd );
+ if ( hIMC )
+ {
+ // Cursor-Position ermitteln und aus der die Default-Position fuer
+ // das Composition-Fenster berechnen
+ SalCursorPosEvent aCursorPosEvt;
+ pFrame->maFrameData.mpProc( pFrame->maFrameData.mpInst, pFrame,
+ SALEVENT_CURSORPOS, (void*)&aCursorPosEvt );
+ COMPOSITIONFORM aForm;
+ memset( &aForm, 0, sizeof( aForm ) );
+ if ( !aCursorPosEvt.mnWidth || !aCursorPosEvt.mnHeight )
+ aForm.dwStyle |= CFS_DEFAULT;
+ else
+ {
+ aForm.dwStyle |= CFS_POINT;
+ aForm.ptCurrentPos.x = aCursorPosEvt.mnX;
+ aForm.ptCurrentPos.y = aCursorPosEvt.mnY;
+ }
+ ImmSetCompositionWindow( hIMC, &aForm );
+
+ // Den InputContect-Font ermitteln und diesem dem Composition-Fenster
+ // bekannt machen
+
+ ImmReleaseContext( hWnd, hIMC );
+ }
+
+ pFrame->maFrameData.mbCompositionMode = TRUE;
+ pFrame->maFrameData.mpProc( pFrame->maFrameData.mpInst, pFrame,
+ SALEVENT_STARTEXTTEXTINPUT, (void*)NULL );
+ if ( pFrame->maFrameData.mbAtCursorIME )
+ bDef = FALSE;
+ }
+ }
+
+ ImplSalYieldMutexRelease();
+
+ return bDef;
+}
+
+// -----------------------------------------------------------------------
+
+static BOOL ImplHandleIMEComposition( HWND hWnd, LPARAM lParam )
+{
+ BOOL bDef = TRUE;
+ if ( lParam & (GCS_RESULTSTR | GCS_COMPSTR | GCS_COMPATTR | GCS_CURSORPOS) )
+ {
+ ImplSalYieldMutexAcquireWithWait();
+
+ SalFrame* pFrame = GetWindowPtr( hWnd );
+ if ( pFrame && pFrame->maFrameData.mbHandleIME &&
+ (pFrame->maFrameData.mbCompositionMode || !(lParam & GCS_RESULTSTR)) )
+ {
+ HIMC hIMC = ImmGetContext( hWnd );
+ if ( hIMC )
+ {
+ SalExtTextInputEvent aEvt;
+ aEvt.mnTime = GetMessageTime();
+ aEvt.mpTextAttr = NULL;
+ aEvt.mnCursorPos = 0;
+ aEvt.mnDeltaStart = 0;
+ aEvt.mbOnlyCursor = FALSE;
+ aEvt.mbCursorVisible = !pFrame->maFrameData.mbCandidateMode;
+
+ LONG nTextLen;
+ xub_Unicode* pTextBuf = NULL;
+ LONG nAttrLen;
+ WIN_BYTE* pAttrBuf = NULL;
+ BOOL bLastCursor = FALSE;
+ if ( lParam & GCS_RESULTSTR )
+ {
+ nTextLen = ImmGetCompositionStringW( hIMC, GCS_RESULTSTR, 0, 0 ) / sizeof( WCHAR );
+ if ( nTextLen >= 0 )
+ {
+ pTextBuf = new xub_Unicode[nTextLen];
+ ImmGetCompositionStringW( hIMC, GCS_RESULTSTR, pTextBuf, nTextLen*sizeof( WCHAR ) );
+ }
+
+ bLastCursor = TRUE;
+ aEvt.mbCursorVisible = TRUE;
+ bDef = FALSE;
+ }
+ else if ( pFrame->maFrameData.mbAtCursorIME )
+ {
+ bDef = FALSE;
+ if ( lParam & (GCS_COMPSTR | GCS_COMPATTR | GCS_CURSORPOS) )
+ {
+ nTextLen = ImmGetCompositionStringW( hIMC, GCS_COMPSTR, 0, 0 ) / sizeof( WCHAR );
+ if ( nTextLen >= 0 )
+ {
+ pTextBuf = new xub_Unicode[nTextLen];
+ ImmGetCompositionStringW( hIMC, GCS_COMPSTR, pTextBuf, nTextLen*sizeof( WCHAR ) );
+ }
+
+ nAttrLen = ImmGetCompositionStringW( hIMC, GCS_COMPATTR, 0, 0 );
+ if ( nAttrLen >= 0 )
+ {
+ pAttrBuf = new WIN_BYTE[nAttrLen];
+ ImmGetCompositionStringW( hIMC, GCS_COMPATTR, pAttrBuf, nAttrLen );
+ }
+
+ aEvt.mnCursorPos = LOWORD( ImmGetCompositionStringW( hIMC, GCS_CURSORPOS, 0, 0 ) );
+ aEvt.mnDeltaStart = LOWORD( ImmGetCompositionStringW( hIMC, GCS_DELTASTART, 0, 0 ) );
+
+ if ( lParam == GCS_CURSORPOS )
+ aEvt.mbOnlyCursor = TRUE;
+ }
+ }
+
+ USHORT* pSalAttrAry = NULL;
+ if ( pTextBuf )
+ {
+ aEvt.maText = XubString( pTextBuf, (USHORT)nTextLen );
+ delete pTextBuf;
+ if ( pAttrBuf )
+ {
+ xub_StrLen nTextLen = aEvt.maText.Len();
+ if ( nTextLen )
+ {
+ pSalAttrAry = new USHORT[nTextLen];
+ memset( pSalAttrAry, 0, nTextLen*sizeof( USHORT ) );
+ for ( xub_StrLen i = 0; (i < nTextLen) && (i < nAttrLen); i++ )
+ {
+ WIN_BYTE nWinAttr = pAttrBuf[i];
+ USHORT nSalAttr;
+ if ( nWinAttr == ATTR_TARGET_CONVERTED )
+ {
+ nSalAttr = SAL_EXTTEXTINPUT_ATTR_TARGETCONVERTED | SAL_EXTTEXTINPUT_ATTR_UNDERLINE | SAL_EXTTEXTINPUT_ATTR_HIGHLIGHT;
+ aEvt.mbCursorVisible = FALSE;
+ }
+ else if ( nWinAttr == ATTR_CONVERTED )
+ nSalAttr = SAL_EXTTEXTINPUT_ATTR_CONVERTED | SAL_EXTTEXTINPUT_ATTR_DASHDOTUNDERLINE;
+ else if ( nWinAttr == ATTR_TARGET_NOTCONVERTED )
+ nSalAttr = SAL_EXTTEXTINPUT_ATTR_TARGETNOTCONVERTED | SAL_EXTTEXTINPUT_ATTR_DOTTEDUNDERLINE;
+ else if ( nWinAttr == ATTR_INPUT_ERROR )
+ nSalAttr = SAL_EXTTEXTINPUT_ATTR_INPUTERROR | SAL_EXTTEXTINPUT_ATTR_REDTEXT | SAL_EXTTEXTINPUT_ATTR_DOTTEDUNDERLINE;
+ else /* ( nWinAttr == ATTR_INPUT ) */
+ nSalAttr = SAL_EXTTEXTINPUT_ATTR_INPUT | SAL_EXTTEXTINPUT_ATTR_DOTTEDUNDERLINE;
+ pSalAttrAry[i] = nSalAttr;
+ }
+ aEvt.mpTextAttr = pSalAttrAry;
+ }
+ delete pAttrBuf;
+ }
+ if ( bLastCursor )
+ aEvt.mnCursorPos = aEvt.maText.Len();
+ }
+
+ ImmReleaseContext( hWnd, hIMC );
+
+ // Handler rufen und wenn wir ein Attribute-Array haben, danach
+ // wieder zerstoeren
+ if ( !bDef )
+ {
+ pFrame->maFrameData.mpProc( pFrame->maFrameData.mpInst, pFrame,
+ SALEVENT_EXTTEXTINPUT, (void*)&aEvt );
+ }
+ if ( pSalAttrAry )
+ delete pSalAttrAry;
+ }
+
+ ImplSalYieldMutexRelease();
+ }
+ }
+
+ return bDef;
+}
+
+// -----------------------------------------------------------------------
+
+static BOOL ImplHandleIMEEndComposition( HWND hWnd )
+{
+ BOOL bDef = TRUE;
+
+ ImplSalYieldMutexAcquireWithWait();
+
+ SalFrame* pFrame = GetWindowPtr( hWnd );
+ if ( pFrame && pFrame->maFrameData.mbHandleIME )
+ {
+ // Wir restaurieren den Background-Modus bei jeder Texteingabe,
+ // da einige Tools wie RichWin uns diesen hin- und wieder umsetzen
+ if ( pFrame->maFrameData.mpGraphics &&
+ pFrame->maFrameData.mpGraphics->maGraphicsData.mhDC )
+ SetBkMode( pFrame->maFrameData.mpGraphics->maGraphicsData.mhDC, TRANSPARENT );
+
+ pFrame->maFrameData.mbCompositionMode = FALSE;
+ pFrame->maFrameData.mpProc( pFrame->maFrameData.mpInst, pFrame,
+ SALEVENT_ENDEXTTEXTINPUT, (void*)NULL );
+ if ( pFrame->maFrameData.mbAtCursorIME )
+ bDef = FALSE;
+ }
+
+ ImplSalYieldMutexRelease();
+
+ return bDef;
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplHandleIMENotify( HWND hWnd, WPARAM wParam )
+{
+ if ( wParam == (WPARAM)IMN_OPENCANDIDATE )
+ {
+ ImplSalYieldMutexAcquireWithWait();
+
+ SalFrame* pFrame = GetWindowPtr( hWnd );
+ if ( pFrame && pFrame->maFrameData.mbHandleIME &&
+ pFrame->maFrameData.mbAtCursorIME )
+ {
+ // Wir wollen den Cursor hiden
+ pFrame->maFrameData.mbCandidateMode = TRUE;
+ ImplHandleIMEComposition( hWnd, GCS_CURSORPOS );
+
+ HWND hWnd = pFrame->maFrameData.mhWnd;
+ HIMC hIMC = ImmGetContext( hWnd );
+ if ( hIMC )
+ {
+ LONG nBufLen = ImmGetCompositionStringW( hIMC, GCS_COMPSTR, 0, 0 );
+ if ( nBufLen >= 1 )
+ {
+ USHORT nCursorPos = LOWORD( ImmGetCompositionStringW( hIMC, GCS_CURSORPOS, 0, 0 ) );
+ SalExtTextInputPosEvent aEvt;
+ aEvt.mnTime = GetMessageTime();
+ aEvt.mnFirstPos = nCursorPos;
+ aEvt.mnChars = nBufLen/sizeof(sal_Unicode) - nCursorPos;
+ aEvt.mpPosAry = new SalExtCharPos[aEvt.mnChars];
+ memset( aEvt.mpPosAry, 0, aEvt.mnChars*sizeof(SalExtCharPos) );
+
+ pFrame->maFrameData.mpProc( pFrame->maFrameData.mpInst, pFrame,
+ SALEVENT_EXTTEXTINPUTPOS, (void*)&aEvt );
+
+ long nMinLeft = aEvt.mpPosAry[0].mnX;
+ long nMinTop = aEvt.mpPosAry[0].mnY;
+ long nMaxBottom = aEvt.mpPosAry[0].mnY+aEvt.mpPosAry[0].mnHeight;
+ long nMaxRight = nMinLeft;
+ USHORT i = 0;
+ while ( i < aEvt.mnChars )
+ {
+ // Solange wir uns auf der gleichen Zeile bewegen,
+ // ermitteln wir die Rechteck-Grenzen
+ if ( !aEvt.mpPosAry[i].mnHeight ||
+ (aEvt.mpPosAry[i].mnY < nMaxBottom-1) )
+ {
+ if ( aEvt.mpPosAry[i].mnX < nMinLeft )
+ nMinLeft = aEvt.mpPosAry[i].mnX;
+ if ( aEvt.mpPosAry[i].mnX+aEvt.mpPosAry[0].mnWidth > nMaxRight )
+ nMaxRight = aEvt.mpPosAry[i].mnX+aEvt.mpPosAry[0].mnWidth;
+ if ( aEvt.mpPosAry[i].mnY < nMinTop )
+ nMinTop = aEvt.mpPosAry[i].mnY;
+ i++;
+ }
+ else
+ break;
+ }
+
+ CANDIDATEFORM aForm;
+ aForm.dwIndex = 0;
+ aForm.dwStyle = CFS_EXCLUDE;
+ aForm.ptCurrentPos.x = aEvt.mpPosAry[0].mnX;
+ aForm.ptCurrentPos.y = nMaxBottom+1;
+ aForm.rcArea.left = nMinLeft;
+ aForm.rcArea.top = nMinTop;
+ aForm.rcArea.right = nMaxRight+1;
+ aForm.rcArea.bottom = nMaxBottom+1;
+ ImmSetCandidateWindow( hIMC, &aForm );
+
+ delete aEvt.mpPosAry;
+ }
+
+ ImmReleaseContext( hWnd, hIMC );
+ }
+ }
+
+ ImplSalYieldMutexRelease();
+ }
+ else if ( wParam == (WPARAM)IMN_CLOSECANDIDATE )
+ {
+ ImplSalYieldMutexAcquireWithWait();
+ SalFrame* pFrame = GetWindowPtr( hWnd );
+ if ( pFrame )
+ pFrame->maFrameData.mbCandidateMode = FALSE;
+ ImplSalYieldMutexRelease();
+ }
+}
+
+
+// -----------------------------------------------------------------------
+
+void SalTestMouseLeave()
+{
+ SalData* pSalData = GetSalData();
+
+ if ( pSalData->mhWantLeaveMsg && !::GetCapture() )
+ {
+ POINT aPt;
+ GetCursorPos( &aPt );
+ if ( pSalData->mhWantLeaveMsg != WindowFromPoint( aPt ) )
+ ImplSendMessage( pSalData->mhWantLeaveMsg, SAL_MSG_MOUSELEAVE, 0, MAKELPARAM( aPt.x, aPt.y ) );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+static int ImplSalWheelMousePos( HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam ,
+ LRESULT& rResult )
+{
+ POINT aPt;
+ POINT aScreenPt;
+ aScreenPt.x = (short)LOWORD( lParam );
+ aScreenPt.y = (short)HIWORD( lParam );
+ // Child-Fenster suchen, welches an der entsprechenden
+ // Position liegt
+ HWND hChildWnd;
+ HWND hWheelWnd = hWnd;
+ do
+ {
+ hChildWnd = hWheelWnd;
+ aPt = aScreenPt;
+ ScreenToClient( hChildWnd, &aPt );
+ hWheelWnd = ChildWindowFromPointEx( hChildWnd, aPt, CWP_SKIPINVISIBLE | CWP_SKIPTRANSPARENT );
+ }
+ while ( hWheelWnd && (hWheelWnd != hChildWnd) );
+ if ( hWheelWnd && (hWheelWnd != hWnd) &&
+ (hWheelWnd != ::GetFocus()) && IsWindowEnabled( hWheelWnd ) )
+ {
+ rResult = ImplSendMessage( hWheelWnd, nMsg, wParam, lParam );
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+// -----------------------------------------------------------------------
+
+LRESULT CALLBACK SalFrameWndProc( HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam, int& rDef )
+{
+ LRESULT nRet = 0;
+ static int bInWheelMsg = FALSE;
+
+ // By WM_CRETAE we connect the frame with the window handle
+ if ( nMsg == WM_CREATE )
+ {
+ // Window-Instanz am Windowhandle speichern
+ // Can also be used for the W-Version, because the struct
+ // to access lpCreateParams is the same structure
+ CREATESTRUCTA* pStruct = (CREATESTRUCTA*)lParam;
+ SalFrame* pFrame = (SalFrame*)pStruct->lpCreateParams;
+ SetWindowPtr( hWnd, pFrame );
+ // HWND schon hier setzen, da schon auf den Instanzdaten
+ // gearbeitet werden kann, wenn Messages waehrend
+ // CreateWindow() gesendet werden
+ pFrame->maFrameData.mhWnd = hWnd;
+ pFrame->maFrameData.maSysData.hWnd = hWnd;
+ return 0;
+ }
+
+ switch( nMsg )
+ {
+ case WM_MOUSEMOVE:
+ case WM_LBUTTONDOWN:
+ case WM_MBUTTONDOWN:
+ case WM_RBUTTONDOWN:
+ case WM_LBUTTONUP:
+ case WM_MBUTTONUP:
+ case WM_RBUTTONUP:
+ case WM_NCMOUSEMOVE:
+ case SAL_MSG_MOUSELEAVE:
+ ImplSalYieldMutexAcquireWithWait();
+ rDef = !ImplHandleMouseMsg( hWnd, nMsg, wParam, lParam );
+ ImplSalYieldMutexRelease();
+ break;
+
+ case WM_MOUSEACTIVATE:
+ if ( LOWORD( lParam ) == HTCLIENT )
+ {
+ ImplSalYieldMutexAcquireWithWait();
+ nRet = ImplHandleMouseActivateMsg( hWnd );
+ ImplSalYieldMutexRelease();
+ if ( nRet )
+ {
+ nRet = MA_NOACTIVATE;
+ rDef = FALSE;
+ }
+ }
+ break;
+
+ case WM_KEYDOWN:
+ case WM_KEYUP:
+ case WM_DEADCHAR:
+ case WM_CHAR:
+ case WM_SYSKEYDOWN:
+ case WM_SYSKEYUP:
+ case WM_SYSCHAR:
+ ImplSalYieldMutexAcquireWithWait();
+ rDef = !ImplHandleKeyMsg( hWnd, nMsg, wParam, lParam );
+ ImplSalYieldMutexRelease();
+ break;
+
+ case WM_MOUSEWHEEL:
+ // Gegen Rekursion absichern, falls wir vom IE oder dem externen
+ // Fenster die Message wieder zurueckbekommen
+ if ( !bInWheelMsg )
+ {
+ bInWheelMsg++;
+ rDef = !ImplHandleWheelMsg( hWnd, wParam, lParam );
+ // Wenn wir die Message nicht ausgewertet haben, schauen wir
+ // noch einmal nach, ob dort ein geplugtes Fenster steht,
+ // welches wir dann benachrichtigen
+ if ( rDef )
+ rDef = ImplSalWheelMousePos( hWnd, nMsg, wParam, lParam, nRet );
+ bInWheelMsg--;
+ }
+ break;
+
+ case WM_SYSCOMMAND:
+ ImplSalYieldMutexAcquireWithWait();
+ nRet = ImplHandleSysCommand( hWnd, wParam, lParam );
+ ImplSalYieldMutexRelease();
+ if ( nRet )
+ rDef = FALSE;
+ break;
+
+ case WM_MOVE:
+ case SAL_MSG_POSTMOVE:
+ ImplHandleMoveMsg( hWnd );
+ rDef = FALSE;
+ break;
+ case WM_SIZE:
+ ImplHandleSizeMsg( hWnd, wParam, lParam );
+ rDef = FALSE;
+ break;
+ case SAL_MSG_POSTCALLSIZE:
+ ImplCallSizeHdl( hWnd );
+ rDef = FALSE;
+ break;
+
+ case WM_GETMINMAXINFO:
+ if ( ImplHandleMinMax( hWnd, lParam ) )
+ rDef = FALSE;
+ break;
+
+ case WM_ERASEBKGND:
+ nRet = 1;
+ rDef = FALSE;
+ break;
+ case WM_PAINT:
+ ImplHandlePaintMsg( hWnd );
+ rDef = FALSE;
+ break;
+ case SAL_MSG_POSTPAINT:
+ ImplHandlePaintMsg2( hWnd, (RECT*)wParam );
+ rDef = FALSE;
+ break;
+
+ case SAL_MSG_FORCEPALETTE:
+ ImplHandleForcePalette( hWnd );
+ rDef = FALSE;
+ break;
+
+ case WM_QUERYNEWPALETTE:
+ case SAL_MSG_POSTQUERYNEWPAL:
+ nRet = ImplHandlePalette( TRUE, hWnd, nMsg, wParam, lParam, rDef );
+ break;
+
+ case WM_ACTIVATE:
+ // Wenn wir aktiviert werden, dann wollen wir auch unsere
+ // Palette setzen. Wir machen dieses in Activate,
+ // damit andere externe Child-Fenster auch unsere Palette
+ // ueberschreiben koennen. So wird unsere jedenfalls nur einmal
+ // gesetzt und nicht immer rekursiv, da an allen anderen Stellen
+ // diese nur als Background-Palette gesetzt wird
+ if ( LOWORD( wParam ) != WA_INACTIVE )
+ ImplSendMessage( hWnd, SAL_MSG_FORCEPALETTE, 0, 0 );
+ break;
+
+ case WM_SETFOCUS:
+ case WM_KILLFOCUS:
+ case SAL_MSG_POSTFOCUS:
+ ImplHandleFocusMsg( hWnd );
+ rDef = FALSE;
+ break;
+
+ case WM_CLOSE:
+ ImplHandleCloseMsg( hWnd );
+ rDef = FALSE;
+ break;
+
+ case WM_QUERYENDSESSION:
+ nRet = !ImplHandleShutDownMsg( hWnd );
+ rDef = FALSE;
+ break;
+
+#ifdef WM_DISPLAYCHANGE
+ case WM_DISPLAYCHANGE:
+#endif
+#ifdef WM_SETTINGCHANGE
+ case WM_SETTINGCHANGE:
+#else
+ case WM_WININICHANGE:
+#endif
+ case WM_DEVMODECHANGE:
+ case WM_FONTCHANGE:
+ case WM_SYSCOLORCHANGE:
+ case WM_TIMECHANGE:
+ ImplHandleSettingsChangeMsg( hWnd, nMsg, wParam, lParam );
+ break;
+
+ case SAL_MSG_USEREVENT:
+ ImplHandleUserEvent( hWnd, lParam );
+ rDef = FALSE;
+ break;
+
+ case SAL_MSG_CAPTUREMOUSE:
+ SetCapture( hWnd );
+ rDef = FALSE;
+ break;
+ case SAL_MSG_RELEASEMOUSE:
+ if ( ::GetCapture() == hWnd )
+ ReleaseCapture();
+ rDef = FALSE;
+ break;
+ case SAL_MSG_TOTOP:
+ ImplSalToTop( hWnd, (USHORT)wParam );
+ rDef = FALSE;
+ break;
+ case SAL_MSG_SHOW:
+ ImplSalShow( hWnd, (BOOL)wParam );
+ rDef = FALSE;
+ break;
+
+ case WM_INPUTLANGCHANGE:
+ ImplHandleInputLangChange( hWnd, wParam, lParam );
+ break;
+
+ case WM_IME_STARTCOMPOSITION:
+ rDef = ImplHandleIMEStartComposition( hWnd );
+ break;
+
+ case WM_IME_COMPOSITION:
+ rDef = ImplHandleIMEComposition( hWnd, lParam );
+ break;
+
+ case WM_IME_ENDCOMPOSITION:
+ rDef = ImplHandleIMEEndComposition( hWnd );
+ break;
+
+ case WM_IME_NOTIFY:
+ ImplHandleIMENotify( hWnd, wParam );
+ break;
+ }
+
+ // WheelMouse-Message abfangen
+ if ( rDef && (nMsg == aSalShlData.mnWheelMsgId) && aSalShlData.mnWheelMsgId )
+ {
+ // Gegen Rekursion absichern, falls wir vom IE oder dem externen
+ // Fenster die Message wieder zurueckbekommen
+ if ( !bInWheelMsg )
+ {
+ bInWheelMsg++;
+ // Zuerst wollen wir die Message dispatchen und dann darf auch
+ // das SystemWindow drankommen
+ WORD nKeyState = 0;
+ if ( GetKeyState( VK_SHIFT ) & 0x8000 )
+ nKeyState |= MK_SHIFT;
+ if ( GetKeyState( VK_CONTROL ) & 0x8000 )
+ nKeyState |= MK_CONTROL;
+ // Mutex handling is inside from this call
+ rDef = !ImplHandleWheelMsg( hWnd, MAKEWPARAM( nKeyState, (WORD)wParam ), lParam );
+ if ( rDef )
+ {
+ HWND hWheelWnd = ::GetFocus();
+ if ( hWheelWnd && (hWheelWnd != hWnd) )
+ {
+ nRet = ImplSendMessage( hWheelWnd, nMsg, wParam, lParam );
+ rDef = FALSE;
+ }
+ else
+ rDef = ImplSalWheelMousePos( hWnd, nMsg, wParam, lParam, nRet );
+ }
+ bInWheelMsg--;
+ }
+ }
+
+ return nRet;
+}
+
+LRESULT CALLBACK SalFrameWndProcA( HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam )
+{
+ int bDef = TRUE;
+ LRESULT nRet = SalFrameWndProc( hWnd, nMsg, wParam, lParam, bDef );
+ if ( bDef )
+ nRet = DefWindowProcA( hWnd, nMsg, wParam, lParam );
+ return nRet;
+}
+
+LRESULT CALLBACK SalFrameWndProcW( HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam )
+{
+ int bDef = TRUE;
+ LRESULT nRet = SalFrameWndProc( hWnd, nMsg, wParam, lParam, bDef );
+ if ( bDef )
+ nRet = DefWindowProcW( hWnd, nMsg, wParam, lParam );
+ return nRet;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL ImplHandleGlobalMsg( HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam, LRESULT& rlResult )
+{
+ // Hier verarbeiten wir alle Messages, die fuer alle Frame-Fenster gelten,
+ // damit diese nur einmal verarbeitet werden
+ // Must work for Unicode and none Unicode
+ if ( (nMsg == WM_PALETTECHANGED) || (nMsg == SAL_MSG_POSTPALCHANGED) )
+ {
+ int bDef = TRUE;
+ rlResult = ImplHandlePalette( FALSE, hWnd, nMsg, wParam, lParam, bDef );
+ return (bDef != 0);
+ }
+ else
+ return FALSE;
+}
diff --git a/vcl/win/source/window/salobj.cxx b/vcl/win/source/window/salobj.cxx
new file mode 100644
index 000000000000..39b233de05e6
--- /dev/null
+++ b/vcl/win/source/window/salobj.cxx
@@ -0,0 +1,873 @@
+/*************************************************************************
+ *
+ * $RCSfile: salobj.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:05:50 $
+ *
+ * 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 <string.h>
+
+#ifndef _SVWIN_HXX
+#include <tools/svwin.h>
+#endif
+
+#define _SV_SALOBJ_CXX
+
+#ifndef _SV_WINCOMP_HXX
+#include <wincomp.hxx>
+#endif
+#ifndef _SV_SALDATA_HXX
+#include <saldata.hxx>
+#endif
+#ifndef _SV_SALINST_HXX
+#include <salinst.hxx>
+#endif
+#ifndef _SV_SALFRAME_HXX
+#include <salframe.hxx>
+#endif
+#ifndef _SV_SALOBJ_HXX
+#include <salobj.hxx>
+#endif
+
+#ifndef _DEBUG_HXX
+#include <tools/debug.hxx>
+#endif
+
+// =======================================================================
+
+static BOOL ImplIsSysWindowOrChild( HWND hWndParent, HWND hWndChild )
+{
+ if ( hWndParent == hWndChild )
+ return TRUE;
+
+ HWND hTempWnd = ::GetParent( hWndChild );
+ while ( hTempWnd )
+ {
+ // Ab nicht Child-Fenstern hoeren wir auf zu suchen
+ if ( !(GetWindowStyle( hTempWnd ) & WS_CHILD) )
+ return FALSE;
+ if ( hTempWnd == hWndParent )
+ return TRUE;
+ hTempWnd = ::GetParent( hTempWnd );
+ }
+
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+SalObject* ImplFindSalObject( HWND hWndChild )
+{
+ SalData* pSalData = GetSalData();
+ SalObject* pObject = pSalData->mpFirstObject;
+ while ( pObject )
+ {
+ if ( ImplIsSysWindowOrChild( pObject->maObjectData.mhWndChild, hWndChild ) )
+ return pObject;
+
+ pObject = pObject->maObjectData.mpNextObject;
+ }
+
+ return NULL;
+}
+
+// -----------------------------------------------------------------------
+
+SalFrame* ImplFindSalObjectFrame( HWND hWnd )
+{
+ SalFrame* pFrame = NULL;
+ SalObject* pObject = ImplFindSalObject( hWnd );
+ if ( pObject )
+ {
+ // Dazugehoerenden Frame suchen
+ HWND hWnd = ::GetParent( pObject->maObjectData.mhWnd );
+ pFrame = GetSalData()->mpFirstFrame;
+ while ( pFrame )
+ {
+ if ( pFrame->maFrameData.mhWnd == hWnd )
+ break;
+
+ pFrame = pFrame->maFrameData.mpNextFrame;
+ }
+ }
+
+ return pFrame;
+}
+
+// -----------------------------------------------------------------------
+
+LRESULT CALLBACK SalSysMsgProc( int nCode, WPARAM wParam, LPARAM lParam )
+{
+ // Used for Unicode and none Unicode
+ SalData* pSalData = GetSalData();
+
+ if ( (nCode >= 0) && lParam )
+ {
+ CWPSTRUCT* pData = (CWPSTRUCT*)lParam;
+ if ( (pData->message != WM_KEYDOWN) &&
+ (pData->message != WM_KEYUP) )
+ pSalData->mnSalObjWantKeyEvt = 0;
+
+ // Testen, ob wir Daten fuer ein SalObject-Fenster behandeln
+ // muessen
+ SalObject* pObject;
+ if ( pData->message == WM_SETFOCUS )
+ {
+ pObject = ImplFindSalObject( pData->hwnd );
+ if ( pObject )
+ {
+ pObject->maObjectData.mhLastFocusWnd = pData->hwnd;
+ if ( ImplSalYieldMutexTryToAcquire() )
+ {
+ pObject->maObjectData.mpProc( pObject->maObjectData.mpInst, pObject,
+ SALOBJ_EVENT_GETFOCUS, 0 );
+ ImplSalYieldMutexRelease();
+ }
+ else
+ ImplPostMessage( pObject->maObjectData.mhWnd, SALOBJ_MSG_POSTFOCUS, 0, 0 );
+ }
+ }
+ else if ( pData->message == WM_KILLFOCUS )
+ {
+ pObject = ImplFindSalObject( pData->hwnd );
+ if ( pObject && !ImplFindSalObject( (HWND)pData->wParam ) )
+ {
+ // LoseFocus nur rufen, wenn wirklich kein ChildFenster
+ // den Focus bekommt
+ if ( !pData->wParam || !ImplFindSalObject( (HWND)pData->wParam ) )
+ {
+ if ( ImplSalYieldMutexTryToAcquire() )
+ {
+ pObject->maObjectData.mpProc( pObject->maObjectData.mpInst, pObject,
+ SALOBJ_EVENT_LOSEFOCUS, 0 );
+ ImplSalYieldMutexRelease();
+ }
+ else
+ ImplPostMessage( pObject->maObjectData.mhWnd, SALOBJ_MSG_POSTFOCUS, 0, 0 );
+ }
+ else
+ pObject->maObjectData.mhLastFocusWnd = (HWND)pData->wParam;
+ }
+ }
+ }
+
+ return CallNextHookEx( pSalData->mhSalObjMsgHook, nCode, wParam, lParam );
+}
+
+// -----------------------------------------------------------------------
+
+BOOL ImplSalPreDispatchMsg( MSG* pMsg )
+{
+ // Used for Unicode and none Unicode
+ SalData* pSalData = GetSalData();
+ SalObject* pObject;
+
+ if ( (pMsg->message == WM_LBUTTONDOWN) ||
+ (pMsg->message == WM_RBUTTONDOWN) ||
+ (pMsg->message == WM_MBUTTONDOWN) )
+ {
+ ImplSalYieldMutexAcquireWithWait();
+ pObject = ImplFindSalObject( pMsg->hwnd );
+ if ( pObject )
+ ImplPostMessage( pObject->maObjectData.mhWnd, SALOBJ_MSG_TOTOP, 0, 0 );
+ ImplSalYieldMutexRelease();
+ }
+
+ if ( (pMsg->message == WM_KEYDOWN) ||
+ (pMsg->message == WM_KEYUP) )
+ {
+ // KeyEvents wollen wir nach Moeglichkeit auch abarbeiten,
+ // wenn das Control diese nicht selber auswertet
+ // SysKeys werden als WM_SYSCOMMAND verarbeitet
+ // Char-Events verarbeiten wir nicht, da wir nur
+ // Accelerator relevante Keys verarbeiten wollen
+ BOOL bWantedKeyCode = FALSE;
+ // A-Z, 0-9 nur in Verbindung mit Control-Taste
+ if ( ((pMsg->wParam >= 65) && (pMsg->wParam <= 90)) ||
+ ((pMsg->wParam >= 48) && (pMsg->wParam <= 57)) )
+ {
+ if ( GetKeyState( VK_CONTROL ) & 0x8000 )
+ bWantedKeyCode = TRUE;
+ }
+ else if ( ((pMsg->wParam >= VK_F1) && (pMsg->wParam <= VK_F24)) ||
+ ((pMsg->wParam >= VK_SPACE) && (pMsg->wParam <= VK_HELP)) ||
+ (pMsg->wParam == VK_BACK) || (pMsg->wParam == VK_TAB) ||
+ (pMsg->wParam == VK_CLEAR) || (pMsg->wParam == VK_RETURN) ||
+ (pMsg->wParam == VK_ESCAPE) )
+ bWantedKeyCode = TRUE;
+ if ( bWantedKeyCode )
+ {
+ ImplSalYieldMutexAcquireWithWait();
+ pObject = ImplFindSalObject( pMsg->hwnd );
+ if ( pObject )
+ pSalData->mnSalObjWantKeyEvt = pMsg->wParam;
+ ImplSalYieldMutexRelease();
+ }
+ }
+ // Hier WM_SYSCHAR abfangen, um mit Alt+Taste evtl. Menu zu aktivieren
+ else if ( pMsg->message == WM_SYSCHAR )
+ {
+ pSalData->mnSalObjWantKeyEvt = 0;
+
+ USHORT nKeyCode = LOWORD( pMsg->wParam );
+ // Nur 0-9 und A-Z
+ if ( ((nKeyCode >= 48) && (nKeyCode <= 57)) ||
+ ((nKeyCode >= 65) && (nKeyCode <= 90)) ||
+ ((nKeyCode >= 97) && (nKeyCode <= 122)) )
+ {
+ BOOL bRet = FALSE;
+ ImplSalYieldMutexAcquireWithWait();
+ pObject = ImplFindSalObject( pMsg->hwnd );
+ if ( pObject )
+ {
+ if ( pMsg->hwnd == ::GetFocus() )
+ {
+ SalFrame* pFrame = ImplFindSalObjectFrame( pMsg->hwnd );
+ if ( pFrame )
+ {
+ if ( ImplHandleSalObjSysCharMsg( pFrame->maFrameData.mhWnd, pMsg->wParam, pMsg->lParam ) )
+ bRet = TRUE;
+ }
+ }
+ }
+ ImplSalYieldMutexRelease();
+ if ( bRet )
+ return TRUE;
+ }
+ }
+ else
+ pSalData->mnSalObjWantKeyEvt = 0;
+
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+void ImplSalPostDispatchMsg( MSG* pMsg, LRESULT /* nDispatchResult */ )
+{
+ // Used for Unicode and none Unicode
+ SalData* pSalData = GetSalData();
+ SalFrame* pFrame;
+
+ if ( (pMsg->message == WM_KEYDOWN) || (pMsg->message == WM_KEYUP) )
+ {
+ if ( pSalData->mnSalObjWantKeyEvt == pMsg->wParam )
+ {
+ pSalData->mnSalObjWantKeyEvt = 0;
+ if ( pMsg->hwnd == ::GetFocus() )
+ {
+ ImplSalYieldMutexAcquireWithWait();
+ pFrame = ImplFindSalObjectFrame( pMsg->hwnd );
+ if ( pFrame )
+ ImplHandleSalObjKeyMsg( pFrame->maFrameData.mhWnd, pMsg->message, pMsg->wParam, pMsg->lParam );
+ ImplSalYieldMutexRelease();
+ }
+ }
+ }
+
+ pSalData->mnSalObjWantKeyEvt = 0;
+}
+
+// =======================================================================
+
+LRESULT CALLBACK SalSysObjWndProc( HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam, int& rDef )
+{
+ SalObject* pSysObj;
+ LRESULT nRet = 0;
+
+ switch( nMsg )
+ {
+ case WM_ERASEBKGND:
+ nRet = 1;
+ rDef = FALSE;
+ break;
+ case WM_PAINT:
+ {
+ PAINTSTRUCT aPs;
+ BeginPaint( hWnd, &aPs );
+ EndPaint( hWnd, &aPs );
+ rDef = FALSE;
+ }
+ break;
+
+ case WM_PARENTNOTIFY:
+ {
+ UINT nNotifyMsg = LOWORD( wParam );
+ if ( (nNotifyMsg == WM_LBUTTONDOWN) ||
+ (nNotifyMsg == WM_RBUTTONDOWN) ||
+ (nNotifyMsg == WM_MBUTTONDOWN) )
+ {
+ ImplSalYieldMutexAcquireWithWait();
+ pSysObj = GetSalObjWindowPtr( hWnd );
+ if ( pSysObj )
+ pSysObj->maObjectData.mpProc( pSysObj->maObjectData.mpInst, pSysObj, SALOBJ_EVENT_TOTOP, 0 );
+ ImplSalYieldMutexRelease();
+ }
+ }
+ break;
+
+ case WM_MOUSEACTIVATE:
+ ImplPostMessage( hWnd, SALOBJ_MSG_TOTOP, 0, 0 );
+ break;
+
+ case SALOBJ_MSG_TOTOP:
+ if ( ImplSalYieldMutexTryToAcquire() )
+ {
+ pSysObj = GetSalObjWindowPtr( hWnd );
+ pSysObj->maObjectData.mpProc( pSysObj->maObjectData.mpInst, pSysObj,
+ SALOBJ_EVENT_TOTOP, 0 );
+ ImplSalYieldMutexRelease();
+ rDef = FALSE;
+ }
+ else
+ ImplPostMessage( hWnd, SALOBJ_MSG_TOTOP, 0, 0 );
+ break;
+
+ case SALOBJ_MSG_POSTFOCUS:
+ if ( ImplSalYieldMutexTryToAcquire() )
+ {
+ pSysObj = GetSalObjWindowPtr( hWnd );
+ HWND hFocusWnd = ::GetFocus();
+ USHORT nEvent;
+ if ( hFocusWnd && ImplIsSysWindowOrChild( hWnd, hFocusWnd ) )
+ nEvent = SALOBJ_EVENT_GETFOCUS;
+ else
+ nEvent = SALOBJ_EVENT_LOSEFOCUS;
+ pSysObj->maObjectData.mpProc( pSysObj->maObjectData.mpInst, pSysObj,
+ nEvent, 0 );
+ ImplSalYieldMutexRelease();
+ }
+ else
+ ImplPostMessage( hWnd, SALOBJ_MSG_POSTFOCUS, 0, 0 );
+ rDef = FALSE;
+ break;
+
+ case WM_SIZE:
+ {
+ HWND hWndChild = GetWindow( hWnd, GW_CHILD );
+ if ( hWndChild )
+ {
+ SetWindowPos( hWndChild,
+ 0, 0, 0, (int)LOWORD( lParam ), (int)HIWORD( lParam ),
+ SWP_NOZORDER | SWP_NOACTIVATE );
+ }
+ }
+ rDef = FALSE;
+ break;
+
+ case WM_CREATE:
+ {
+ // Window-Instanz am Windowhandle speichern
+ // Can also be used for the W-Version, because the struct
+ // to access lpCreateParams is the same structure
+ CREATESTRUCTA* pStruct = (CREATESTRUCTA*)lParam;
+ pSysObj = (SalObject*)pStruct->lpCreateParams;
+ SetSalObjWindowPtr( hWnd, pSysObj );
+ // HWND schon hier setzen, da schon auf den Instanzdaten
+ // gearbeitet werden kann, wenn Messages waehrend
+ // CreateWindow() gesendet werden
+ pSysObj->maObjectData.mhWnd = hWnd;
+ rDef = FALSE;
+ }
+ break;
+ }
+
+ return nRet;
+}
+
+LRESULT CALLBACK SalSysObjWndProcA( HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam )
+{
+ int bDef = TRUE;
+ LRESULT nRet = SalSysObjWndProc( hWnd, nMsg, wParam, lParam, bDef );
+ if ( bDef )
+ nRet = DefWindowProcA( hWnd, nMsg, wParam, lParam );
+ return nRet;
+}
+
+LRESULT CALLBACK SalSysObjWndProcW( HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam )
+{
+ int bDef = TRUE;
+ LRESULT nRet = SalSysObjWndProc( hWnd, nMsg, wParam, lParam, bDef );
+ if ( bDef )
+ nRet = DefWindowProcW( hWnd, nMsg, wParam, lParam );
+ return nRet;
+}
+
+// -----------------------------------------------------------------------
+
+LRESULT CALLBACK SalSysObjChildWndProc( HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam, int& rDef )
+{
+ LRESULT nRet = 0;
+
+ switch( nMsg )
+ {
+ // Wegen PlugIn's loeschen wir erstmal den Hintergrund
+/*
+ case WM_ERASEBKGND:
+ nRet = 1;
+ rDef = FALSE;
+ break;
+*/
+ case WM_PAINT:
+ {
+ PAINTSTRUCT aPs;
+ BeginPaint( hWnd, &aPs );
+ EndPaint( hWnd, &aPs );
+ rDef = FALSE;
+ }
+ break;
+ }
+
+ return nRet;
+}
+
+LRESULT CALLBACK SalSysObjChildWndProcA( HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam )
+{
+ int bDef = TRUE;
+ LRESULT nRet = SalSysObjChildWndProc( hWnd, nMsg, wParam, lParam, bDef );
+ if ( bDef )
+ nRet = DefWindowProcA( hWnd, nMsg, wParam, lParam );
+ return nRet;
+}
+
+LRESULT CALLBACK SalSysObjChildWndProcW( HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam )
+{
+ int bDef = TRUE;
+ LRESULT nRet = SalSysObjChildWndProc( hWnd, nMsg, wParam, lParam, bDef );
+ if ( bDef )
+ nRet = DefWindowProcW( hWnd, nMsg, wParam, lParam );
+ return nRet;
+}
+
+// =======================================================================
+
+SalObject* ImplSalCreateObject( SalInstance* pInst, SalFrame* pParent )
+{
+ SalData* pSalData = GetSalData();
+
+ // Hook installieren, wenn es das erste SalObject ist
+ if ( !pSalData->mpFirstObject )
+ {
+ if ( aSalShlData.mbWNT )
+ {
+ pSalData->mhSalObjMsgHook = SetWindowsHookExW( WH_CALLWNDPROC,
+ SalSysMsgProc,
+ pSalData->mhInst,
+ pSalData->mnAppThreadId );
+ }
+ else
+ {
+ pSalData->mhSalObjMsgHook = SetWindowsHookExA( WH_CALLWNDPROC,
+ SalSysMsgProc,
+ pSalData->mhInst,
+ pSalData->mnAppThreadId );
+ }
+ }
+
+ if ( !pSalData->mbObjClassInit )
+ {
+ if ( aSalShlData.mbWNT )
+ {
+ WNDCLASSEXW aWndClassEx;
+ aWndClassEx.cbSize = sizeof( aWndClassEx );
+ aWndClassEx.style = 0;
+ aWndClassEx.lpfnWndProc = SalSysObjWndProcW;
+ aWndClassEx.cbClsExtra = 0;
+ aWndClassEx.cbWndExtra = SAL_OBJECT_WNDEXTRA;
+ aWndClassEx.hInstance = pSalData->mhInst;
+ aWndClassEx.hIcon = 0;
+ aWndClassEx.hIconSm = 0;
+ aWndClassEx.hCursor = LoadCursor( 0, IDC_ARROW );
+ aWndClassEx.hbrBackground = 0;
+ aWndClassEx.lpszMenuName = 0;
+ aWndClassEx.lpszClassName = SAL_OBJECT_CLASSNAMEW;
+ if ( RegisterClassExW( &aWndClassEx ) )
+ {
+ // Wegen PlugIn's loeschen wir erstmal den Hintergrund
+ aWndClassEx.cbWndExtra = 0;
+ aWndClassEx.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
+ aWndClassEx.lpfnWndProc = SalSysObjChildWndProcW;
+ aWndClassEx.lpszClassName = SAL_OBJECT_CHILDCLASSNAMEW;
+ if ( RegisterClassExW( &aWndClassEx ) )
+ pSalData->mbObjClassInit = TRUE;
+ }
+ }
+ else
+ {
+ WNDCLASSEXA aWndClassEx;
+ aWndClassEx.cbSize = sizeof( aWndClassEx );
+ aWndClassEx.style = 0;
+ aWndClassEx.lpfnWndProc = SalSysObjWndProcA;
+ aWndClassEx.cbClsExtra = 0;
+ aWndClassEx.cbWndExtra = SAL_OBJECT_WNDEXTRA;
+ aWndClassEx.hInstance = pSalData->mhInst;
+ aWndClassEx.hIcon = 0;
+ aWndClassEx.hIconSm = 0;
+ aWndClassEx.hCursor = LoadCursor( 0, IDC_ARROW );
+ aWndClassEx.hbrBackground = 0;
+ aWndClassEx.lpszMenuName = 0;
+ aWndClassEx.lpszClassName = SAL_OBJECT_CLASSNAMEA;
+ if ( RegisterClassExA( &aWndClassEx ) )
+ {
+ // Wegen PlugIn's loeschen wir erstmal den Hintergrund
+ aWndClassEx.cbWndExtra = 0;
+ aWndClassEx.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
+ aWndClassEx.lpfnWndProc = SalSysObjChildWndProcA;
+ aWndClassEx.lpszClassName = SAL_OBJECT_CHILDCLASSNAMEA;
+ if ( RegisterClassExA( &aWndClassEx ) )
+ pSalData->mbObjClassInit = TRUE;
+ }
+ }
+ }
+
+ if ( pSalData->mbObjClassInit )
+ {
+ SalObject* pObject = new SalObject;
+ HWND hWnd;
+ HWND hWndChild = 0;
+ if ( aSalShlData.mbWNT )
+ {
+ hWnd = CreateWindowExW( 0, SAL_OBJECT_CLASSNAMEW, L"",
+ WS_CHILD, 0, 0, 0, 0,
+ pParent->maFrameData.mhWnd, 0,
+ pInst->maInstData.mhInst, (void*)pObject );
+ if ( hWnd )
+ {
+ hWndChild = CreateWindowExW( 0, SAL_OBJECT_CHILDCLASSNAMEW, L"",
+ WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_VISIBLE,
+ 0, 0, 0, 0,
+ hWnd, 0,
+ pInst->maInstData.mhInst, NULL );
+ }
+ }
+ else
+ {
+ hWnd = CreateWindowExA( 0, SAL_OBJECT_CLASSNAMEA, "",
+ WS_CHILD, 0, 0, 0, 0,
+ pParent->maFrameData.mhWnd, 0,
+ pInst->maInstData.mhInst, (void*)pObject );
+ if ( hWnd )
+ {
+ hWndChild = CreateWindowExA( 0, SAL_OBJECT_CHILDCLASSNAMEA, "",
+ WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_VISIBLE,
+ 0, 0, 0, 0,
+ hWnd, 0,
+ pInst->maInstData.mhInst, NULL );
+ }
+ }
+ if ( !hWndChild )
+ {
+ delete pObject;
+ return NULL;
+ }
+
+ if ( hWnd )
+ {
+ pObject->maObjectData.mhWnd = hWnd;
+ pObject->maObjectData.mhWndChild = hWndChild;
+ pObject->maObjectData.maSysData.hWnd = hWndChild;
+ return pObject;
+ }
+ }
+
+ return NULL;
+}
+
+// =======================================================================
+
+long ImplSalObjCallbackDummy( void*, SalObject*, USHORT, const void* )
+{
+ return 0;
+}
+
+// =======================================================================
+
+SalObject::SalObject()
+{
+ SalData* pSalData = GetSalData();
+
+ maObjectData.mhWnd = 0;
+ maObjectData.mhWndChild = 0;
+ maObjectData.mhLastFocusWnd = 0;
+ maObjectData.maSysData.nSize = sizeof( SystemEnvData );
+ maObjectData.mpInst = NULL;
+ maObjectData.mpProc = ImplSalObjCallbackDummy;
+ maObjectData.mpStdClipRgnData = NULL;
+
+ // Insert object in objectlist
+ maObjectData.mpNextObject = pSalData->mpFirstObject;
+ pSalData->mpFirstObject = this;
+}
+
+// -----------------------------------------------------------------------
+
+SalObject::~SalObject()
+{
+ SalData* pSalData = GetSalData();
+
+ // remove frame from framelist
+ if ( this == pSalData->mpFirstObject )
+ {
+ pSalData->mpFirstObject = maObjectData.mpNextObject;
+
+ // Wenn letztes SalObject, dann Hook wieder entfernen
+ if ( !pSalData->mpFirstObject )
+ UnhookWindowsHookEx( pSalData->mhSalObjMsgHook );
+ }
+ else
+ {
+ SalObject* pTempObject = pSalData->mpFirstObject;
+ while ( pTempObject->maObjectData.mpNextObject != this )
+ pTempObject = pTempObject->maObjectData.mpNextObject;
+
+ pTempObject->maObjectData.mpNextObject = maObjectData.mpNextObject;
+ }
+
+ // Cache-Daten zerstoeren
+ if ( maObjectData.mpStdClipRgnData )
+ delete maObjectData.mpStdClipRgnData;
+
+ HWND hWndParent = ::GetParent( maObjectData.mhWnd );
+
+ if ( maObjectData.mhWndChild )
+ DestroyWindow( maObjectData.mhWndChild );
+ if ( maObjectData.mhWnd )
+ DestroyWindow( maObjectData.mhWnd );
+
+ // Palette wieder zuruecksetzen, wenn kein externes Child-Fenster
+ // mehr vorhanden ist, da diese unsere Palette ueberschrieben haben
+ // koennen
+ if ( hWndParent &&
+ ::GetActiveWindow() == hWndParent &&
+ !GetWindow( hWndParent, GW_CHILD ) )
+ ImplSendMessage( hWndParent, SAL_MSG_FORCEPALETTE, 0, 0 );
+}
+
+// -----------------------------------------------------------------------
+
+void SalObject::ResetClipRegion()
+{
+ SetWindowRgn( maObjectData.mhWnd, 0, TRUE );
+}
+
+// -----------------------------------------------------------------------
+
+USHORT SalObject::GetClipRegionType()
+{
+ return SAL_OBJECT_CLIP_INCLUDERECTS;
+}
+
+// -----------------------------------------------------------------------
+
+void SalObject::BeginSetClipRegion( ULONG nRectCount )
+{
+ ULONG nRectBufSize = sizeof(RECT)*nRectCount;
+ if ( nRectCount < SAL_CLIPRECT_COUNT )
+ {
+ if ( !maObjectData.mpStdClipRgnData )
+ maObjectData.mpStdClipRgnData = (RGNDATA*)new BYTE[sizeof(RGNDATA)-1+(SAL_CLIPRECT_COUNT*sizeof(RECT))];
+ maObjectData.mpClipRgnData = maObjectData.mpStdClipRgnData;
+ }
+ else
+ maObjectData.mpClipRgnData = (RGNDATA*)new BYTE[sizeof(RGNDATA)-1+nRectBufSize];
+ maObjectData.mpClipRgnData->rdh.dwSize = sizeof( RGNDATAHEADER );
+ maObjectData.mpClipRgnData->rdh.iType = RDH_RECTANGLES;
+ maObjectData.mpClipRgnData->rdh.nCount = nRectCount;
+ maObjectData.mpClipRgnData->rdh.nRgnSize = nRectBufSize;
+ SetRectEmpty( &(maObjectData.mpClipRgnData->rdh.rcBound) );
+ maObjectData.mpNextClipRect = (RECT*)(&(maObjectData.mpClipRgnData->Buffer));
+ maObjectData.mbFirstClipRect = TRUE;
+}
+
+// -----------------------------------------------------------------------
+
+void SalObject::UnionClipRegion( long nX, long nY, long nWidth, long nHeight )
+{
+ RECT* pRect = maObjectData.mpNextClipRect;
+ RECT* pBoundRect = &(maObjectData.mpClipRgnData->rdh.rcBound);
+ long nRight = nX + nWidth;
+ long nBottom = nY + nHeight;
+
+ if ( maObjectData.mbFirstClipRect )
+ {
+ pBoundRect->left = nX;
+ pBoundRect->top = nY;
+ pBoundRect->right = nRight;
+ pBoundRect->bottom = nBottom;
+ maObjectData.mbFirstClipRect = FALSE;
+ }
+ else
+ {
+ if ( nX < pBoundRect->left )
+ pBoundRect->left = (int)nX;
+
+ if ( nY < pBoundRect->top )
+ pBoundRect->top = (int)nY;
+
+ if ( nRight > pBoundRect->right )
+ pBoundRect->right = (int)nRight;
+
+ if ( nBottom > pBoundRect->bottom )
+ pBoundRect->bottom = (int)nBottom;
+ }
+
+ pRect->left = (int)nX;
+ pRect->top = (int)nY;
+ pRect->right = (int)nRight;
+ pRect->bottom = (int)nBottom;
+ maObjectData.mpNextClipRect++;
+}
+
+// -----------------------------------------------------------------------
+
+void SalObject::EndSetClipRegion()
+{
+ HRGN hRegion;
+
+ // Aus den Region-Daten muessen wir jetzt eine ClipRegion erzeugen
+ if ( maObjectData.mpClipRgnData->rdh.nCount == 1 )
+ {
+ RECT* pRect = &(maObjectData.mpClipRgnData->rdh.rcBound);
+ hRegion = CreateRectRgn( pRect->left, pRect->top,
+ pRect->right, pRect->bottom );
+ }
+ else
+ {
+ ULONG nSize = maObjectData.mpClipRgnData->rdh.nRgnSize+sizeof(RGNDATAHEADER);
+ hRegion = ExtCreateRegion( NULL, nSize, maObjectData.mpClipRgnData );
+ if ( maObjectData.mpClipRgnData != maObjectData.mpStdClipRgnData )
+ delete maObjectData.mpClipRgnData;
+ }
+
+ DBG_ASSERT( hRegion, "SalObject::EndSetClipRegion() - Can't create ClipRegion" );
+ SetWindowRgn( maObjectData.mhWnd, hRegion, TRUE );
+}
+
+// -----------------------------------------------------------------------
+
+void SalObject::SetPosSize( long nX, long nY, long nWidth, long nHeight )
+{
+ ULONG nStyle = 0;
+ BOOL bVisible = (GetWindowStyle( maObjectData.mhWnd ) & WS_VISIBLE) != 0;
+ if ( bVisible )
+ {
+ ShowWindow( maObjectData.mhWnd, SW_HIDE );
+ nStyle |= SWP_SHOWWINDOW;
+ }
+ SetWindowPos( maObjectData.mhWnd, 0,
+ (int)nX, (int)nY, (int)nWidth, (int)nHeight,
+ SWP_NOZORDER | SWP_NOACTIVATE | nStyle );
+}
+
+// -----------------------------------------------------------------------
+
+void SalObject::Show( BOOL bVisible )
+{
+ if ( bVisible )
+ ShowWindow( maObjectData.mhWnd, SW_SHOWNORMAL );
+ else
+ ShowWindow( maObjectData.mhWnd, SW_HIDE );
+}
+
+// -----------------------------------------------------------------------
+
+void SalObject::Enable( BOOL bEnable )
+{
+ EnableWindow( maObjectData.mhWnd, bEnable );
+}
+
+// -----------------------------------------------------------------------
+
+void SalObject::GrabFocus()
+{
+ if ( maObjectData.mhLastFocusWnd &&
+ IsWindow( maObjectData.mhLastFocusWnd ) &&
+ ImplIsSysWindowOrChild( maObjectData.mhWndChild, maObjectData.mhLastFocusWnd ) )
+ ::SetFocus( maObjectData.mhLastFocusWnd );
+ else
+ ::SetFocus( maObjectData.mhWndChild );
+}
+
+// -----------------------------------------------------------------------
+
+void SalObject::SetBackground()
+{
+}
+
+// -----------------------------------------------------------------------
+
+void SalObject::SetBackground( SalColor nSalColor )
+{
+}
+
+// -----------------------------------------------------------------------
+
+const SystemEnvData* SalObject::GetSystemData() const
+{
+ return &maObjectData.maSysData;
+}
+
+// -----------------------------------------------------------------------
+
+void SalObject::SetCallback( void* pInst, SALOBJECTPROC pProc )
+{
+ maObjectData.mpInst = pInst;
+ if ( pProc )
+ maObjectData.mpProc = pProc;
+ else
+ maObjectData.mpProc = ImplSalObjCallbackDummy;
+}