Changes for OS/2. Patch provided by Eric Olson (eric.olson@sympatico.ca)

git-svn-id: svn://10.0.0.236/trunk@37283 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
mcafee%netscape.com
1999-06-28 23:39:35 +00:00
parent c0945c19ad
commit fcfe8cdbcc
112 changed files with 21111 additions and 0 deletions

View File

@@ -0,0 +1,416 @@
/*
* The contents of this file are subject to the Mozilla Public 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.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
* License for the specific language governing rights and limitations
* under the License.
*
* The Original Code is the Mozilla OS/2 libraries.
*
* The Initial Developer of the Original Code is John Fairhurst,
* <john_fairhurst@iname.com>. Portions created by John Fairhurst are
* Copyright (C) 1999 John Fairhurst. All Rights Reserved.
*
* Contributor(s):
*
*/
#define INCL_DOSDEVIOCTL // for keyboard layout
#include "nsWidgetDefs.h"
#include "nsHashtable.h"
#include "resid.h"
#include <stdio.h>
#include <stdlib.h>
// Module-level data & utility functions:
// * unicode keycode & string conversion
// * atom management
// * printing bits & pieces (though not really any more)
#include "nsIFontRetrieverService.h"
#include "nsDragService.h"
#include "nsAppShell.h"
#include <unidef.h>
#define WARPZILLA_PRESPARAM "PP_WARPZILLA"
static void GetKeyboardName( char *buff);
nsWidgetModuleData::nsWidgetModuleData()
{}
// This is called when the first appshell is created.
void nsWidgetModuleData::Init( nsIAppShell *aPrimaevalAppShell)
{
if( 0 != hModResources) return;
char buffer[CCHMAXPATH];
APIRET rc;
rc = DosLoadModule( buffer, CCHMAXPATH, "WDGTRES", &hModResources);
if( rc)
{
printf( "Widget failed to load resource DLL. rc = %d, cause = %s\n",
(int)rc, buffer);
hModResources = 0;
}
szScreen.cx = WinQuerySysValue( HWND_DESKTOP, SV_CXSCREEN);
szScreen.cy = WinQuerySysValue( HWND_DESKTOP, SV_CYSCREEN);
bMouseSwitched = WinQuerySysValue( HWND_DESKTOP, SV_SWAPBUTTON);
// Magic number -- height of normal text fields in pixels.
// Both combobox and (atm) nsBrowserWindow depend on this.
lHtEntryfield = 26;
rc = WinLoadString( 0/*hab*/, hModResources, ID_STR_FONT, 256, buffer);
if( !rc) strcpy( buffer, "8.Helv");
pszFontNameSize = strdup( buffer);
hptrSelect = hptrFrameIcon = 0;
// Work out if the system is DBCS
COUNTRYCODE cc = { 0 };
DosQueryDBCSEnv( CCHMAXPATH, &cc, buffer);
bIsDBCS = buffer[0] || buffer[1];
ppMozilla = GetAtom( WARPZILLA_PRESPARAM);
fontService = nsnull;
dragService = new nsDragService;
NS_ADDREF(dragService);
// keep a ref beyond the client app so we shut ourselves down properly.
appshell = aPrimaevalAppShell;
NS_ADDREF(appshell);
converter = 0;
supplantConverter = FALSE;
// create unicode keyboard object
char kbdname[8];
UniChar unikbdname[8];
GetKeyboardName( kbdname);
for( int i = 0; i < 8; i++)
unikbdname[i] = kbdname[i];
if( UniCreateKeyboard( &hKeyboard, unikbdname, 0) != ULS_SUCCESS)
hKeyboard = 0;
#ifdef DEBUG
else
printf( "Widget library loaded keyboard table for %s\n", kbdname);
#endif
#if 0
mWindows = nsnull;
#endif
}
nsWidgetModuleData::~nsWidgetModuleData()
{
if( hKeyboard)
UniDestroyKeyboard( hKeyboard);
if( converter)
UniFreeUconvObject( converter);
NS_IF_RELEASE(dragService);
NS_IF_RELEASE(fontService);
PRInt32 cAtoms = atoms.Count();
HATOMTBL systbl = WinQuerySystemAtomTable();
for( PRInt32 i = 0; i < cAtoms; i++)
WinDeleteAtom( systbl, (ATOM) atoms.ElementAt(i));
if( hptrSelect)
WinDestroyPointer( hptrSelect);
if( hptrFrameIcon)
WinDestroyPointer( hptrFrameIcon);
if( hModResources)
DosFreeModule( hModResources);
free( pszFontNameSize);
#if 0
delete mWindows;
#endif
// finally shut down the appshell. No more PM.
// (hope that gfxos2 has gone first!)
NS_IF_RELEASE(appshell);
}
HPOINTER nsWidgetModuleData::GetPointer( nsCursor aCursor)
{
if( aCursor != eCursor_hyperlink)
printf( "\n*** Need to implement cursor type %d (see widget/os2/nsModule.cpp)\n\n", (int) aCursor);
// Use an array and indices here when we have all the pointers in place.
if( !hptrSelect)
hptrSelect = WinLoadPointer( HWND_DESKTOP,
hModResources, ID_PTR_SELECTURL);
return hptrSelect;
}
HPOINTER nsWidgetModuleData::GetFrameIcon()
{
if( !hptrFrameIcon)
hptrFrameIcon = WinLoadPointer( HWND_DESKTOP,
hModResources, ID_ICO_FRAME);
return hptrFrameIcon;
}
// Conversion from unicode to appropriate codepage
char *nsWidgetModuleData::ConvertFromUcs( const PRUnichar *pText,
char *szBuffer, ULONG ulSize)
{
if( supplantConverter)
{
// We couldn't create a converter for some reason, so do this 'by hand'.
// Note this algorithm is fine for most of most western charsets, but
// fails dismally for various glyphs, baltic, points east...
ULONG ulCount = 0;
char *szSave = szBuffer;
while( *pText && ulCount < ulSize - 1) // (one for terminator)
{
*szBuffer = (char) *pText;
szBuffer++;
pText++;
ulCount++;
}
// terminate string
*szBuffer = '\0';
return szSave;
}
if( !converter)
{
// Create a converter from unicode to a codepage which PM can display.
UniChar codepage[20];
int unirc = UniMapCpToUcsCp( 0, codepage, 20);
if( unirc == ULS_SUCCESS)
{
unirc = UniCreateUconvObject( codepage, &converter);
// XXX do we need to set substitution options here?
#ifdef DEBUG
if( unirc == ULS_SUCCESS)
{
printf( "Widget library created unicode converter for cp %s\n",
ConvertFromUcs( (PRUnichar *) codepage));
}
#endif
}
if( unirc != ULS_SUCCESS)
{
supplantConverter = TRUE;
printf( "Couldn't create widget unicode converter.\n");
return ConvertFromUcs( pText, szBuffer, ulSize);
}
}
// Have converter, now get it to work...
UniChar *ucsString = (UniChar*) pText;
size_t ucsLen = UniStrlen( ucsString) + 1;
size_t cplen = ulSize;
size_t cSubs = 0;
char *tmp = szBuffer; // function alters the out pointer
int unirc = UniUconvFromUcs( converter, &ucsString, &ucsLen,
(void**) &tmp, &cplen, &cSubs);
if( unirc == UCONV_E2BIG) // k3w1
{
// terminate output string (truncating)
*(szBuffer + ulSize - 1) = '\0';
}
else if( unirc != ULS_SUCCESS)
{
printf( "UniUconvFromUcs failed, rc %X\n", unirc);
supplantConverter = TRUE;
szBuffer = ConvertFromUcs( pText, szBuffer, ulSize);
supplantConverter = FALSE;
}
return szBuffer;
}
char *nsWidgetModuleData::ConvertFromUcs( const nsString &aString,
char *szBuffer, ULONG ulSize)
{
char *szRet = 0;
const PRUnichar *pUnicode = aString.GetUnicode();
if( pUnicode)
szRet = ConvertFromUcs( pUnicode, szBuffer, ulSize);
else
szRet = aString.ToCString( szBuffer, ulSize);
return szRet;
}
const char *nsWidgetModuleData::ConvertFromUcs( const PRUnichar *pText)
{
// This is probably okay; longer strings will be truncated but istr there's
// a PM limit on things like windowtext
// (which these routines are usually used for)
static char buffer[1024]; // XXX (multithread)
*buffer = '\0';
return ConvertFromUcs( pText, buffer, 1024);
}
const char *nsWidgetModuleData::ConvertFromUcs( const nsString &aString)
{
const char *szRet = 0;
const PRUnichar *pUnicode = aString.GetUnicode();
if( pUnicode)
szRet = ConvertFromUcs( pUnicode);
else
szRet = aString.GetBuffer(); // hrm.
return szRet;
}
// Wrapper around UniTranslateKey to deal with shift-state etc.
int nsWidgetModuleData::TranslateKey( VSCAN scan, UniChar *pChar, VDKEY *vdkey)
{
int unirc = 1;
// bail if we've not got a keyboard
if( !hKeyboard) return unirc;
// XXX Right, this seems madly wrong, but I'm not sure what else to do.
// We need to work out the 'effective shift state' before calling
// UniTranslateKey(). This is derived from the state of the keyboard
// and the current scancode. Unfortunately, the only way I can find
// the current state of the various keys is by doing this on each
// keypress!
//
// XXX Anything else to test? Layers? Or are they just deadkey applications?
// Are deadkeys meant to go in here?
ULONG sstate = 0;
if( WinIsKeyDown(VK_SHIFT)) sstate |= KBD_SHIFT;
if( WinIsKeyDown(VK_CTRL)) sstate |= KBD_CTRL;
// if( WinIsKeyDown(VK_ALT)) sstate |= KBD_ALT;
// if( WinIsKeyDown(VK_ALTGRAF)) sstate |= KBD_ALTGR;
#define TOGGLED(vk) (WinGetKeyState(HWND_DESKTOP,vk) & 1)
if( TOGGLED(VK_CAPSLOCK)) sstate |= KBD_CAPSLOCK;
if( TOGGLED(VK_NUMLOCK)) sstate |= KBD_NUMLOCK;
if( TOGGLED(VK_SCRLLOCK)) sstate |= KBD_SCROLLLOCK;
USHIFTSTATE uss = { sstate, 0, 0 };
unirc = UniUpdateShiftState( hKeyboard, &uss, scan, 0);
if( unirc == ULS_SUCCESS)
{
BYTE bBiosScancode;
unirc = UniTranslateKey( hKeyboard,
uss.Effective,
scan,
pChar,
vdkey,
&bBiosScancode);
}
return unirc;
}
static void GetKeyboardName( char *buff)
{
HFILE hKeyboard = 0;
ULONG ulAction;
strcpy( buff, "UK");
if( !DosOpen( "KBD$", &hKeyboard, &ulAction, 0, FILE_NORMAL, FILE_OPEN,
OPEN_ACCESS_READONLY | OPEN_SHARE_DENYWRITE, NULL))
{
ULONG ulDataLen;
#pragma pack(2)
struct { USHORT usLength; USHORT usCp; CHAR ach[8];} kcp;
#pragma pack()
kcp.usLength = ulDataLen = sizeof kcp;
if( !DosDevIOCtl( hKeyboard, IOCTL_KEYBOARD, KBD_QUERYKBDCODEPAGESUPPORT,
0, 0, 0,
&kcp, ulDataLen, &ulDataLen))
strcpy( buff, kcp.ach);
DosClose( hKeyboard);
}
}
ATOM nsWidgetModuleData::GetAtom( const char *atomname)
{
ATOM atom = WinAddAtom( WinQuerySystemAtomTable(), atomname);
atoms.AppendElement( (void*) atom);
return atom;
}
ATOM nsWidgetModuleData::GetAtom( const nsString &atomname)
{
return GetAtom( ConvertFromUcs( atomname));
}
// Printing stuff -- need to be able to generate a window of a given
// flavour and then do stuff to it in nsWindow::Paint()
#if 0
class nsWndClassKey : public nsHashKey
{
PCSZ pszClassname;
public:
nsWndClassKey( PCSZ pszName) : pszClassname( pszName)
{}
PRUint32 HashValue() const
{ return (PRUint32) pszClassname; }
PRBool Equals( const nsHashKey *aKey) const
{ return HashValue() == aKey->HashValue(); }
nsHashKey *Clone() const
{ return new nsWndClassKey( pszClassname); }
};
// Get a window to render its state
HWND nsWidgetModuleData::GetWindowForPrinting( PCSZ pszClass, ULONG ulStyle)
{
if( mWindows == nsnull)
mWindows = new nsHashtable;
nsWndClassKey aKey( pszClass);
if( mWindows->Get( &aKey) == nsnull)
{
HWND hwnd = WinCreateWindow( HWND_DESKTOP, pszClass, "", ulStyle,
0, -4096, 0, 0, HWND_DESKTOP,
HWND_TOP, 0, 0, 0);
NS_ASSERTION( hwnd, "WinCreateWindow for printing failed");
mWindows->Put( &aKey, (void*) hwnd);
}
return (HWND) mWindows->Get( &aKey);
}
#endif
nsWidgetModuleData gModuleData;