Moved a bunch of functions out of libwine/kernel/gdi into USER.
This commit is contained in:
parent
b0efe28f6c
commit
93652e1a68
@ -25,13 +25,13 @@ import ntdll.dll
|
||||
7 register VxDCall6(long) VxDCall
|
||||
8 register VxDCall7(long) VxDCall
|
||||
9 register VxDCall8(long) VxDCall
|
||||
10 stdcall k32CharToOemA(str str) CharToOemA
|
||||
11 stdcall k32CharToOemBuffA(str str long) CharToOemBuffA
|
||||
12 stdcall k32OemToCharA(ptr ptr) OemToCharA
|
||||
13 stdcall k32OemToCharBuffA(ptr ptr long) OemToCharBuffA
|
||||
14 stdcall k32LoadStringA(long long ptr long) LoadStringA
|
||||
15 varargs k32wsprintfA(str str) wsprintfA
|
||||
16 stdcall k32wvsprintfA(ptr str ptr) wvsprintfA
|
||||
10 forward k32CharToOemA user32.CharToOemA
|
||||
11 forward k32CharToOemBuffA user32.CharToOemBuffA
|
||||
12 forward k32OemToCharA user32.OemToCharA
|
||||
13 forward k32OemToCharBuffA user32.OemToCharBuffA
|
||||
14 forward k32LoadStringA user32.LoadStringA
|
||||
15 forward k32wsprintfA user32.wsprintfA
|
||||
16 forward k32wvsprintfA user32.wvsprintfA
|
||||
17 register CommonUnimpStub() CommonUnimpStub
|
||||
18 stdcall GetProcessDword(long long) GetProcessDword
|
||||
19 stub ThunkTheTemplateHandle
|
||||
|
@ -6,17 +6,22 @@ MODULE = user32
|
||||
SOVERSION = 1.0
|
||||
WRCEXTRA = -w16 -m
|
||||
ALTNAMES = user keyboard ddeml display mouse
|
||||
IMPORTS = gdi32
|
||||
IMPORTS = gdi32 kernel32
|
||||
|
||||
C_SRCS = \
|
||||
bidi16.c \
|
||||
cache.c \
|
||||
ddeml.c \
|
||||
display.c \
|
||||
exticon.c \
|
||||
lstr.c \
|
||||
misc.c \
|
||||
mouse.c \
|
||||
network.c \
|
||||
user_main.c \
|
||||
thunk.c
|
||||
resource.c \
|
||||
text.c \
|
||||
thunk.c \
|
||||
user_main.c
|
||||
|
||||
RC_SRCS = \
|
||||
disp.rc \
|
||||
|
201
dlls/user/lstr.c
Normal file
201
dlls/user/lstr.c
Normal file
@ -0,0 +1,201 @@
|
||||
/*
|
||||
* String functions
|
||||
*
|
||||
* Copyright 1993 Yngvi Sigurjonsson (yngvi@hafro.is)
|
||||
* Copyright 1996 Marcus Meissner
|
||||
*/
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "wine/winbase16.h"
|
||||
#include "wine/winuser16.h"
|
||||
|
||||
#include "heap.h"
|
||||
#include "ldt.h"
|
||||
#include "debugtools.h"
|
||||
|
||||
DEFAULT_DEBUG_CHANNEL(resource);
|
||||
|
||||
/***********************************************************************
|
||||
* FormatMessage16 (USER.606)
|
||||
*/
|
||||
DWORD WINAPI FormatMessage16(
|
||||
DWORD dwFlags,
|
||||
SEGPTR lpSource, /*not always a valid pointer*/
|
||||
WORD dwMessageId,
|
||||
WORD dwLanguageId,
|
||||
LPSTR lpBuffer, /* *((HLOCAL16*)) for FORMAT_MESSAGE_ALLOCATE_BUFFER*/
|
||||
WORD nSize,
|
||||
LPDWORD args /* va_list *args */
|
||||
) {
|
||||
#ifdef __i386__
|
||||
/* This implementation is completely dependant on the format of the va_list on x86 CPUs */
|
||||
LPSTR target,t;
|
||||
DWORD talloced;
|
||||
LPSTR from,f;
|
||||
DWORD width = dwFlags & FORMAT_MESSAGE_MAX_WIDTH_MASK;
|
||||
BOOL eos = FALSE;
|
||||
LPSTR allocstring = NULL;
|
||||
|
||||
TRACE("(0x%lx,%lx,%d,0x%x,%p,%d,%p)\n",
|
||||
dwFlags,lpSource,dwMessageId,dwLanguageId,lpBuffer,nSize,args);
|
||||
if ((dwFlags & FORMAT_MESSAGE_FROM_SYSTEM)
|
||||
&& (dwFlags & FORMAT_MESSAGE_FROM_HMODULE)) return 0;
|
||||
if ((dwFlags & FORMAT_MESSAGE_FROM_STRING)
|
||||
&&((dwFlags & FORMAT_MESSAGE_FROM_SYSTEM)
|
||||
|| (dwFlags & FORMAT_MESSAGE_FROM_HMODULE))) return 0;
|
||||
|
||||
if (width && width != FORMAT_MESSAGE_MAX_WIDTH_MASK)
|
||||
FIXME("line wrapping (%lu) not supported.\n", width);
|
||||
from = NULL;
|
||||
if (dwFlags & FORMAT_MESSAGE_FROM_STRING)
|
||||
from = HEAP_strdupA( GetProcessHeap(), 0, PTR_SEG_TO_LIN(lpSource));
|
||||
if (dwFlags & FORMAT_MESSAGE_FROM_SYSTEM) {
|
||||
from = HeapAlloc( GetProcessHeap(),0,200 );
|
||||
sprintf(from,"Systemmessage, messageid = 0x%08x\n",dwMessageId);
|
||||
}
|
||||
if (dwFlags & FORMAT_MESSAGE_FROM_HMODULE) {
|
||||
INT16 bufsize;
|
||||
HINSTANCE16 hinst16 = ((HMODULE)lpSource & 0xffff);
|
||||
|
||||
dwMessageId &= 0xFFFF;
|
||||
bufsize=LoadString16(hinst16,dwMessageId,NULL,0);
|
||||
if (bufsize) {
|
||||
from = HeapAlloc( GetProcessHeap(), 0, bufsize +1);
|
||||
LoadString16(hinst16,dwMessageId,from,bufsize+1);
|
||||
}
|
||||
}
|
||||
target = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, 100);
|
||||
t = target;
|
||||
talloced= 100;
|
||||
|
||||
#define ADD_TO_T(c) \
|
||||
*t++=c;\
|
||||
if (t-target == talloced) {\
|
||||
target = (char*)HeapReAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,target,talloced*2);\
|
||||
t = target+talloced;\
|
||||
talloced*=2;\
|
||||
}
|
||||
|
||||
if (from) {
|
||||
f=from;
|
||||
while (*f && !eos) {
|
||||
if (*f=='%') {
|
||||
int insertnr;
|
||||
char *fmtstr,*x,*lastf;
|
||||
DWORD *argliststart;
|
||||
|
||||
fmtstr = NULL;
|
||||
lastf = f;
|
||||
f++;
|
||||
if (!*f) {
|
||||
ADD_TO_T('%');
|
||||
continue;
|
||||
}
|
||||
switch (*f) {
|
||||
case '1':case '2':case '3':case '4':case '5':
|
||||
case '6':case '7':case '8':case '9':
|
||||
insertnr=*f-'0';
|
||||
switch (f[1]) {
|
||||
case '0':case '1':case '2':case '3':
|
||||
case '4':case '5':case '6':case '7':
|
||||
case '8':case '9':
|
||||
f++;
|
||||
insertnr=insertnr*10+*f-'0';
|
||||
f++;
|
||||
break;
|
||||
default:
|
||||
f++;
|
||||
break;
|
||||
}
|
||||
if (*f=='!') {
|
||||
f++;
|
||||
if (NULL!=(x=strchr(f,'!'))) {
|
||||
*x='\0';
|
||||
fmtstr=HeapAlloc(GetProcessHeap(),0,strlen(f)+2);
|
||||
sprintf(fmtstr,"%%%s",f);
|
||||
f=x+1;
|
||||
} else {
|
||||
fmtstr=HeapAlloc(GetProcessHeap(),0,strlen(f)+2);
|
||||
sprintf(fmtstr,"%%%s",f);
|
||||
f+=strlen(f); /*at \0*/
|
||||
}
|
||||
} else
|
||||
if(!args)
|
||||
break;
|
||||
else
|
||||
fmtstr=HEAP_strdupA(GetProcessHeap(),0,"%s");
|
||||
if (args) {
|
||||
int sz;
|
||||
LPSTR b = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sz = 100);
|
||||
|
||||
argliststart=args+insertnr-1;
|
||||
|
||||
/* CMF - This makes a BIG assumption about va_list */
|
||||
while (vsnprintf(b, sz, fmtstr, (va_list) argliststart) < 0) {
|
||||
b = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, b, sz += 100);
|
||||
}
|
||||
for (x=b; *x; x++) ADD_TO_T(*x);
|
||||
} else {
|
||||
/* NULL args - copy formatstr
|
||||
* (probably wrong)
|
||||
*/
|
||||
while ((lastf<f)&&(*lastf)) {
|
||||
ADD_TO_T(*lastf++);
|
||||
}
|
||||
}
|
||||
HeapFree(GetProcessHeap(),0,fmtstr);
|
||||
break;
|
||||
case '0': /* Just stop processing format string */
|
||||
eos = TRUE;
|
||||
f++;
|
||||
break;
|
||||
case 'n': /* 16 bit version just outputs 'n' */
|
||||
default:
|
||||
ADD_TO_T(*f++);
|
||||
break;
|
||||
}
|
||||
} else { /* '\n' or '\r' gets mapped to "\r\n" */
|
||||
if(*f == '\n' || *f == '\r') {
|
||||
if (width == 0) {
|
||||
ADD_TO_T('\r');
|
||||
ADD_TO_T('\n');
|
||||
if(*f++ == '\r' && *f == '\n')
|
||||
f++;
|
||||
}
|
||||
} else {
|
||||
ADD_TO_T(*f++);
|
||||
}
|
||||
}
|
||||
}
|
||||
*t='\0';
|
||||
}
|
||||
talloced = strlen(target)+1;
|
||||
if (nSize && talloced<nSize) {
|
||||
target = (char*)HeapReAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,target,nSize);
|
||||
}
|
||||
TRACE("-- %s\n",debugstr_a(target));
|
||||
if (dwFlags & FORMAT_MESSAGE_ALLOCATE_BUFFER) {
|
||||
/* nSize is the MINIMUM size */
|
||||
HLOCAL16 h = LocalAlloc16(LPTR,talloced);
|
||||
SEGPTR ptr = LocalLock16(h);
|
||||
allocstring = PTR_SEG_TO_LIN( ptr );
|
||||
memcpy( allocstring,target,talloced);
|
||||
LocalUnlock16( h );
|
||||
*((HLOCAL16*)lpBuffer) = h;
|
||||
} else
|
||||
lstrcpynA(lpBuffer,target,nSize);
|
||||
HeapFree(GetProcessHeap(),0,target);
|
||||
if (from) HeapFree(GetProcessHeap(),0,from);
|
||||
return (dwFlags & FORMAT_MESSAGE_ALLOCATE_BUFFER) ?
|
||||
strlen(allocstring):
|
||||
strlen(lpBuffer);
|
||||
#else
|
||||
return 0;
|
||||
#endif /* __i386__ */
|
||||
}
|
||||
#undef ADD_TO_T
|
209
dlls/user/misc.c
Normal file
209
dlls/user/misc.c
Normal file
@ -0,0 +1,209 @@
|
||||
/*
|
||||
* Misc USER functions
|
||||
*
|
||||
* Copyright 1995 Thomas Sandford
|
||||
* Copyright 1997 Marcus Meissner
|
||||
*/
|
||||
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "wingdi.h"
|
||||
#include "winuser.h"
|
||||
#include "winerror.h"
|
||||
|
||||
#include "debugtools.h"
|
||||
|
||||
DEFAULT_DEBUG_CHANNEL(win);
|
||||
|
||||
/**********************************************************************
|
||||
* SetLastErrorEx [USER32.485] Sets the last-error code.
|
||||
*
|
||||
* RETURNS
|
||||
* None.
|
||||
*/
|
||||
void WINAPI SetLastErrorEx(
|
||||
DWORD error, /* [in] Per-thread error code */
|
||||
DWORD type) /* [in] Error type */
|
||||
{
|
||||
TRACE("(0x%08lx, 0x%08lx)\n", error,type);
|
||||
switch(type) {
|
||||
case 0:
|
||||
break;
|
||||
case SLE_ERROR:
|
||||
case SLE_MINORERROR:
|
||||
case SLE_WARNING:
|
||||
/* Fall through for now */
|
||||
default:
|
||||
FIXME("(error=%08lx, type=%08lx): Unhandled type\n", error,type);
|
||||
break;
|
||||
}
|
||||
SetLastError( error );
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* GetProcessWindowStation [USER32.280] Returns handle of window station
|
||||
*
|
||||
* NOTES
|
||||
* Docs say the return value is HWINSTA
|
||||
*
|
||||
* RETURNS
|
||||
* Success: Handle to window station associated with calling process
|
||||
* Failure: NULL
|
||||
*/
|
||||
DWORD WINAPI GetProcessWindowStation(void)
|
||||
{
|
||||
FIXME("(void): stub\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* GetThreadDesktop [USER32.295] Returns handle to desktop
|
||||
*
|
||||
* NOTES
|
||||
* Docs say the return value is HDESK
|
||||
*
|
||||
* PARAMS
|
||||
* dwThreadId [I] Thread identifier
|
||||
*
|
||||
* RETURNS
|
||||
* Success: Handle to desktop associated with specified thread
|
||||
* Failure: NULL
|
||||
*/
|
||||
DWORD WINAPI GetThreadDesktop( DWORD dwThreadId )
|
||||
{
|
||||
FIXME("(%lx): stub\n",dwThreadId);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* SetDebugErrorLevel [USER32.475]
|
||||
* Sets the minimum error level for generating debugging events
|
||||
*
|
||||
* PARAMS
|
||||
* dwLevel [I] Debugging error level
|
||||
*/
|
||||
VOID WINAPI SetDebugErrorLevel( DWORD dwLevel )
|
||||
{
|
||||
FIXME("(%ld): stub\n", dwLevel);
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* GetProcessDefaultLayout [USER32.802]
|
||||
*
|
||||
* Gets the default layout for parentless windows.
|
||||
* Right now, just returns 0 (left-to-right).
|
||||
*
|
||||
* RETURNS
|
||||
* Success: Nonzero
|
||||
* Failure: Zero
|
||||
*
|
||||
* BUGS
|
||||
* No RTL
|
||||
*/
|
||||
BOOL WINAPI GetProcessDefaultLayout( DWORD *pdwDefaultLayout )
|
||||
{
|
||||
if ( !pdwDefaultLayout ) {
|
||||
SetLastError( ERROR_INVALID_PARAMETER );
|
||||
return FALSE;
|
||||
}
|
||||
FIXME( "( %p ): No BiDi\n", pdwDefaultLayout );
|
||||
*pdwDefaultLayout = 0;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* SetProcessDefaultLayout [USER32.803]
|
||||
*
|
||||
* Sets the default layout for parentless windows.
|
||||
* Right now, only accepts 0 (left-to-right).
|
||||
*
|
||||
* RETURNS
|
||||
* Success: Nonzero
|
||||
* Failure: Zero
|
||||
*
|
||||
* BUGS
|
||||
* No RTL
|
||||
*/
|
||||
BOOL WINAPI SetProcessDefaultLayout( DWORD dwDefaultLayout )
|
||||
{
|
||||
if ( dwDefaultLayout == 0 )
|
||||
return TRUE;
|
||||
FIXME( "( %08lx ): No BiDi\n", dwDefaultLayout );
|
||||
SetLastError( ERROR_CALL_NOT_IMPLEMENTED );
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* OpenDesktopA [USER32.408]
|
||||
*
|
||||
* NOTES
|
||||
* Return type should be HDESK
|
||||
*
|
||||
* Not supported on Win9x - returns NULL and calls SetLastError.
|
||||
*/
|
||||
HANDLE WINAPI OpenDesktopA( LPCSTR lpszDesktop, DWORD dwFlags,
|
||||
BOOL fInherit, DWORD dwDesiredAccess )
|
||||
{
|
||||
FIXME("(%s,%lx,%i,%lx): stub\n",debugstr_a(lpszDesktop),dwFlags,
|
||||
fInherit,dwDesiredAccess);
|
||||
|
||||
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* SetUserObjectInformationA (USER32.512)
|
||||
*/
|
||||
BOOL WINAPI SetUserObjectInformationA( HANDLE hObj, INT nIndex,
|
||||
LPVOID pvInfo, DWORD nLength )
|
||||
{
|
||||
FIXME("(%x,%d,%p,%lx): stub\n",hObj,nIndex,pvInfo,nLength);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* SetThreadDesktop (USER32.510)
|
||||
*/
|
||||
BOOL WINAPI SetThreadDesktop( HANDLE hDesktop )
|
||||
{
|
||||
FIXME("(%x): stub\n",hDesktop);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* RegisterShellHookWindow [USER32.459]
|
||||
*/
|
||||
HRESULT WINAPI RegisterShellHookWindow ( DWORD u )
|
||||
{
|
||||
FIXME("0x%08lx stub\n",u);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* DeregisterShellHookWindow [USER32.132]
|
||||
*/
|
||||
HRESULT WINAPI DeregisterShellHookWindow ( DWORD u )
|
||||
{
|
||||
FIXME("0x%08lx stub\n",u);
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* RegisterTaskList [USER23.436]
|
||||
*/
|
||||
DWORD WINAPI RegisterTaskList (DWORD x)
|
||||
{
|
||||
FIXME("0x%08lx\n",x);
|
||||
return TRUE;
|
||||
}
|
413
dlls/user/resource.c
Normal file
413
dlls/user/resource.c
Normal file
@ -0,0 +1,413 @@
|
||||
/*
|
||||
* USER resource functions
|
||||
*
|
||||
* Copyright 1993 Robert J. Amstadt
|
||||
* Copyright 1995 Alexandre Julliard
|
||||
*/
|
||||
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "winerror.h"
|
||||
#include "winnls.h"
|
||||
#include "wine/winbase16.h"
|
||||
#include "wine/winuser16.h"
|
||||
|
||||
#include "heap.h"
|
||||
#include "ldt.h"
|
||||
#include "debugtools.h"
|
||||
|
||||
DEFAULT_DEBUG_CHANNEL(resource);
|
||||
DECLARE_DEBUG_CHANNEL(accel);
|
||||
|
||||
/**********************************************************************
|
||||
* LoadAccelerators16 [USER.177]
|
||||
*/
|
||||
HACCEL16 WINAPI LoadAccelerators16(HINSTANCE16 instance, SEGPTR lpTableName)
|
||||
{
|
||||
HRSRC16 hRsrc;
|
||||
|
||||
if (HIWORD(lpTableName))
|
||||
TRACE_(accel)("%04x '%s'\n",
|
||||
instance, (char *)PTR_SEG_TO_LIN( lpTableName ) );
|
||||
else
|
||||
TRACE_(accel)("%04x %04x\n",
|
||||
instance, LOWORD(lpTableName) );
|
||||
|
||||
if (!(hRsrc = FindResource16( instance, lpTableName, RT_ACCELERATOR16 ))) {
|
||||
WARN_(accel)("couldn't find accelerator table resource\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
TRACE_(accel)("returning HACCEL 0x%x\n", hRsrc);
|
||||
return LoadResource16(instance,hRsrc);
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
* LoadAcceleratorsW (USER32.356)
|
||||
* The image layout seems to look like this (not 100% sure):
|
||||
* 00: BYTE type type of accelerator
|
||||
* 01: BYTE pad (to WORD boundary)
|
||||
* 02: WORD event
|
||||
* 04: WORD IDval
|
||||
* 06: WORD pad (to DWORD boundary)
|
||||
*/
|
||||
HACCEL WINAPI LoadAcceleratorsW(HINSTANCE instance,LPCWSTR lpTableName)
|
||||
{
|
||||
HRSRC hRsrc;
|
||||
HACCEL hMem,hRetval=0;
|
||||
DWORD size;
|
||||
|
||||
if (HIWORD(lpTableName))
|
||||
TRACE_(accel)("%p '%s'\n",
|
||||
(LPVOID)instance, (char *)( lpTableName ) );
|
||||
else
|
||||
TRACE_(accel)("%p 0x%04x\n",
|
||||
(LPVOID)instance, LOWORD(lpTableName) );
|
||||
|
||||
if (!(hRsrc = FindResourceW( instance, lpTableName, RT_ACCELERATORW )))
|
||||
{
|
||||
WARN_(accel)("couldn't find accelerator table resource\n");
|
||||
} else {
|
||||
hMem = LoadResource( instance, hRsrc );
|
||||
size = SizeofResource( instance, hRsrc );
|
||||
if(size>=sizeof(PE_ACCEL))
|
||||
{
|
||||
LPPE_ACCEL accel_table = (LPPE_ACCEL) hMem;
|
||||
LPACCEL16 accel16;
|
||||
int i,nrofaccells = size/sizeof(PE_ACCEL);
|
||||
|
||||
hRetval = GlobalAlloc16(0,sizeof(ACCEL16)*nrofaccells);
|
||||
accel16 = (LPACCEL16)GlobalLock16(hRetval);
|
||||
for (i=0;i<nrofaccells;i++) {
|
||||
accel16[i].fVirt = accel_table[i].fVirt;
|
||||
accel16[i].key = accel_table[i].key;
|
||||
accel16[i].cmd = accel_table[i].cmd;
|
||||
}
|
||||
accel16[i-1].fVirt |= 0x80;
|
||||
}
|
||||
}
|
||||
TRACE_(accel)("returning HACCEL 0x%x\n", hRsrc);
|
||||
return hRetval;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* LoadAcceleratorsA (USER32.355)
|
||||
*/
|
||||
HACCEL WINAPI LoadAcceleratorsA(HINSTANCE instance,LPCSTR lpTableName)
|
||||
{
|
||||
LPWSTR uni;
|
||||
HACCEL result;
|
||||
if (HIWORD(lpTableName))
|
||||
uni = HEAP_strdupAtoW( GetProcessHeap(), 0, lpTableName );
|
||||
else
|
||||
uni = (LPWSTR)lpTableName;
|
||||
result = LoadAcceleratorsW(instance,uni);
|
||||
if (HIWORD(uni)) HeapFree( GetProcessHeap(), 0, uni);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
* CopyAcceleratorTableA (USER32.58)
|
||||
*/
|
||||
INT WINAPI CopyAcceleratorTableA(HACCEL src, LPACCEL dst, INT entries)
|
||||
{
|
||||
return CopyAcceleratorTableW(src, dst, entries);
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
* CopyAcceleratorTableW (USER32.59)
|
||||
*
|
||||
* By mortene@pvv.org 980321
|
||||
*/
|
||||
INT WINAPI CopyAcceleratorTableW(HACCEL src, LPACCEL dst,
|
||||
INT entries)
|
||||
{
|
||||
int i,xsize;
|
||||
LPACCEL16 accel = (LPACCEL16)GlobalLock16(src);
|
||||
BOOL done = FALSE;
|
||||
|
||||
/* Do parameter checking to avoid the explosions and the screaming
|
||||
as far as possible. */
|
||||
if((dst && (entries < 1)) || (src == (HACCEL)NULL) || !accel) {
|
||||
WARN_(accel)("Application sent invalid parameters (%p %p %d).\n",
|
||||
(LPVOID)src, (LPVOID)dst, entries);
|
||||
return 0;
|
||||
}
|
||||
xsize = GlobalSize16(src)/sizeof(ACCEL16);
|
||||
if (xsize>entries) entries=xsize;
|
||||
|
||||
i=0;
|
||||
while(!done) {
|
||||
/* Spit out some debugging information. */
|
||||
TRACE_(accel)("accel %d: type 0x%02x, event '%c', IDval 0x%04x.\n",
|
||||
i, accel[i].fVirt, accel[i].key, accel[i].cmd);
|
||||
|
||||
/* Copy data to the destination structure array (if dst == NULL,
|
||||
we're just supposed to count the number of entries). */
|
||||
if(dst) {
|
||||
dst[i].fVirt = accel[i].fVirt;
|
||||
dst[i].key = accel[i].key;
|
||||
dst[i].cmd = accel[i].cmd;
|
||||
|
||||
/* Check if we've reached the end of the application supplied
|
||||
accelerator table. */
|
||||
if(i+1 == entries) {
|
||||
/* Turn off the high order bit, just in case. */
|
||||
dst[i].fVirt &= 0x7f;
|
||||
done = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
/* The highest order bit seems to mark the end of the accelerator
|
||||
resource table, but not always. Use GlobalSize() check too. */
|
||||
if((accel[i].fVirt & 0x80) != 0) done = TRUE;
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* CreateAcceleratorTableA (USER32.64)
|
||||
*
|
||||
* By mortene@pvv.org 980321
|
||||
*/
|
||||
HACCEL WINAPI CreateAcceleratorTableA(LPACCEL lpaccel, INT cEntries)
|
||||
{
|
||||
HACCEL hAccel;
|
||||
LPACCEL16 accel;
|
||||
int i;
|
||||
|
||||
/* Do parameter checking just in case someone's trying to be
|
||||
funny. */
|
||||
if(cEntries < 1) {
|
||||
WARN_(accel)("Application sent invalid parameters (%p %d).\n",
|
||||
lpaccel, cEntries);
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return (HACCEL)NULL;
|
||||
}
|
||||
FIXME_(accel)("should check that the accelerator descriptions are valid,"
|
||||
" return NULL and SetLastError() if not.\n");
|
||||
|
||||
|
||||
/* Allocate memory and copy the table. */
|
||||
hAccel = GlobalAlloc16(0,cEntries*sizeof(ACCEL16));
|
||||
|
||||
TRACE_(accel)("handle %x\n", hAccel);
|
||||
if(!hAccel) {
|
||||
ERR_(accel)("Out of memory.\n");
|
||||
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
|
||||
return (HACCEL)NULL;
|
||||
}
|
||||
accel = GlobalLock16(hAccel);
|
||||
for (i=0;i<cEntries;i++) {
|
||||
accel[i].fVirt = lpaccel[i].fVirt;
|
||||
accel[i].key = lpaccel[i].key;
|
||||
accel[i].cmd = lpaccel[i].cmd;
|
||||
}
|
||||
/* Set the end-of-table terminator. */
|
||||
accel[cEntries-1].fVirt |= 0x80;
|
||||
|
||||
TRACE_(accel)("Allocated accelerator handle %x\n", hAccel);
|
||||
return hAccel;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* CreateAcceleratorTableW (USER32.64)
|
||||
*
|
||||
*
|
||||
*/
|
||||
HACCEL WINAPI CreateAcceleratorTableW(LPACCEL lpaccel, INT cEntries)
|
||||
{
|
||||
HACCEL hAccel;
|
||||
LPACCEL16 accel;
|
||||
int i;
|
||||
char ckey;
|
||||
|
||||
/* Do parameter checking just in case someone's trying to be
|
||||
funny. */
|
||||
if(cEntries < 1) {
|
||||
WARN_(accel)("Application sent invalid parameters (%p %d).\n",
|
||||
lpaccel, cEntries);
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return (HACCEL)NULL;
|
||||
}
|
||||
FIXME_(accel)("should check that the accelerator descriptions are valid,"
|
||||
" return NULL and SetLastError() if not.\n");
|
||||
|
||||
|
||||
/* Allocate memory and copy the table. */
|
||||
hAccel = GlobalAlloc16(0,cEntries*sizeof(ACCEL16));
|
||||
|
||||
TRACE_(accel)("handle %x\n", hAccel);
|
||||
if(!hAccel) {
|
||||
ERR_(accel)("Out of memory.\n");
|
||||
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
|
||||
return (HACCEL)NULL;
|
||||
}
|
||||
accel = GlobalLock16(hAccel);
|
||||
|
||||
|
||||
for (i=0;i<cEntries;i++) {
|
||||
accel[i].fVirt = lpaccel[i].fVirt;
|
||||
if( !(accel[i].fVirt & FVIRTKEY) ) {
|
||||
ckey = (char) lpaccel[i].key;
|
||||
if(!MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, &ckey, 1, &accel[i].key, 1))
|
||||
WARN_(accel)("Error converting ASCII accelerator table to Unicode");
|
||||
}
|
||||
else
|
||||
accel[i].key = lpaccel[i].key;
|
||||
accel[i].cmd = lpaccel[i].cmd;
|
||||
}
|
||||
|
||||
/* Set the end-of-table terminator. */
|
||||
accel[cEntries-1].fVirt |= 0x80;
|
||||
|
||||
TRACE_(accel)("Allocated accelerator handle %x\n", hAccel);
|
||||
return hAccel;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* DestroyAcceleratorTable [USER32.130]
|
||||
* Destroys an accelerator table
|
||||
*
|
||||
* NOTES
|
||||
* By mortene@pvv.org 980321
|
||||
*
|
||||
* PARAMS
|
||||
* handle [I] Handle to accelerator table
|
||||
*
|
||||
* RETURNS STD
|
||||
*/
|
||||
BOOL WINAPI DestroyAcceleratorTable( HACCEL handle )
|
||||
{
|
||||
return !GlobalFree16(handle);
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
* LoadString16 (USER.176)
|
||||
*/
|
||||
INT16 WINAPI LoadString16( HINSTANCE16 instance, UINT16 resource_id,
|
||||
LPSTR buffer, INT16 buflen )
|
||||
{
|
||||
HGLOBAL16 hmem;
|
||||
HRSRC16 hrsrc;
|
||||
unsigned char *p;
|
||||
int string_num;
|
||||
int i;
|
||||
|
||||
TRACE("inst=%04x id=%04x buff=%08x len=%d\n",
|
||||
instance, resource_id, (int) buffer, buflen);
|
||||
|
||||
hrsrc = FindResource16( instance, (SEGPTR)((resource_id>>4)+1), RT_STRING16 );
|
||||
if (!hrsrc) return 0;
|
||||
hmem = LoadResource16( instance, hrsrc );
|
||||
if (!hmem) return 0;
|
||||
|
||||
p = LockResource16(hmem);
|
||||
string_num = resource_id & 0x000f;
|
||||
for (i = 0; i < string_num; i++)
|
||||
p += *p + 1;
|
||||
|
||||
TRACE("strlen = %d\n", (int)*p );
|
||||
|
||||
if (buffer == NULL) return *p;
|
||||
i = min(buflen - 1, *p);
|
||||
if (i > 0) {
|
||||
memcpy(buffer, p + 1, i);
|
||||
buffer[i] = '\0';
|
||||
} else {
|
||||
if (buflen > 1) {
|
||||
buffer[0] = '\0';
|
||||
return 0;
|
||||
}
|
||||
WARN("Dont know why caller give buflen=%d *p=%d trying to obtain string '%s'\n", buflen, *p, p + 1);
|
||||
}
|
||||
FreeResource16( hmem );
|
||||
|
||||
TRACE("'%s' loaded !\n", buffer);
|
||||
return i;
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
* LoadStringW (USER32.376)
|
||||
*/
|
||||
INT WINAPI LoadStringW( HINSTANCE instance, UINT resource_id,
|
||||
LPWSTR buffer, INT buflen )
|
||||
{
|
||||
HGLOBAL hmem;
|
||||
HRSRC hrsrc;
|
||||
WCHAR *p;
|
||||
int string_num;
|
||||
int i;
|
||||
|
||||
if (HIWORD(resource_id)==0xFFFF) /* netscape 3 passes this */
|
||||
resource_id = (UINT)(-((INT)resource_id));
|
||||
TRACE("instance = %04x, id = %04x, buffer = %08x, "
|
||||
"length = %d\n", instance, (int)resource_id, (int) buffer, buflen);
|
||||
|
||||
/* Use bits 4 - 19 (incremented by 1) as resourceid, mask out
|
||||
* 20 - 31. */
|
||||
hrsrc = FindResourceW( instance, (LPCWSTR)(((resource_id>>4)&0xffff)+1),
|
||||
RT_STRINGW );
|
||||
if (!hrsrc) return 0;
|
||||
hmem = LoadResource( instance, hrsrc );
|
||||
if (!hmem) return 0;
|
||||
|
||||
p = LockResource(hmem);
|
||||
string_num = resource_id & 0x000f;
|
||||
for (i = 0; i < string_num; i++)
|
||||
p += *p + 1;
|
||||
|
||||
TRACE("strlen = %d\n", (int)*p );
|
||||
|
||||
if (buffer == NULL) return *p;
|
||||
i = min(buflen - 1, *p);
|
||||
if (i > 0) {
|
||||
memcpy(buffer, p + 1, i * sizeof (WCHAR));
|
||||
buffer[i] = (WCHAR) 0;
|
||||
} else {
|
||||
if (buflen > 1) {
|
||||
buffer[0] = (WCHAR) 0;
|
||||
return 0;
|
||||
}
|
||||
#if 0
|
||||
WARN("Dont know why caller give buflen=%d *p=%d trying to obtain string '%s'\n", buflen, *p, p + 1);
|
||||
#endif
|
||||
}
|
||||
|
||||
TRACE("%s loaded !\n", debugstr_w(buffer));
|
||||
return i;
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
* LoadStringA (USER32.375)
|
||||
*/
|
||||
INT WINAPI LoadStringA( HINSTANCE instance, UINT resource_id,
|
||||
LPSTR buffer, INT buflen )
|
||||
{
|
||||
INT retval;
|
||||
LPWSTR wbuf;
|
||||
|
||||
TRACE("instance = %04x, id = %04x, buffer = %08x, "
|
||||
"length = %d\n", instance, (int)resource_id, (int) buffer, buflen);
|
||||
|
||||
if(buffer == NULL) /* asked size of string */
|
||||
return LoadStringW(instance, resource_id, NULL, 0);
|
||||
|
||||
wbuf = HeapAlloc(GetProcessHeap(), 0, buflen * sizeof(WCHAR));
|
||||
if(!wbuf)
|
||||
return 0;
|
||||
|
||||
retval = LoadStringW(instance, resource_id, wbuf, buflen);
|
||||
if(retval != 0)
|
||||
{
|
||||
retval = WideCharToMultiByte(CP_ACP, 0, wbuf, retval, buffer, buflen - 1, NULL, NULL);
|
||||
buffer[retval] = 0;
|
||||
TRACE("%s loaded !\n", debugstr_a(buffer));
|
||||
}
|
||||
HeapFree( GetProcessHeap(), 0, wbuf );
|
||||
|
||||
return retval;
|
||||
}
|
663
dlls/user/text.c
Normal file
663
dlls/user/text.c
Normal file
@ -0,0 +1,663 @@
|
||||
/*
|
||||
* USER text functions
|
||||
*
|
||||
* Copyright 1993, 1994 Alexandre Julliard
|
||||
*
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "windef.h"
|
||||
#include "wingdi.h"
|
||||
#include "wine/winuser16.h"
|
||||
#include "winbase.h"
|
||||
#include "winerror.h"
|
||||
#include "winnls.h"
|
||||
#include "cache.h"
|
||||
#include "ldt.h"
|
||||
#include "debugtools.h"
|
||||
|
||||
DEFAULT_DEBUG_CHANNEL(text);
|
||||
|
||||
#define TAB 9
|
||||
#define LF 10
|
||||
#define CR 13
|
||||
#define SPACE 32
|
||||
#define PREFIX 38
|
||||
|
||||
#define SWAP_INT(a,b) { int t = a; a = b; b = t; }
|
||||
|
||||
static int tabstop = 8;
|
||||
static int tabwidth;
|
||||
static int spacewidth;
|
||||
static int prefix_offset;
|
||||
|
||||
static const char *TEXT_NextLine( HDC hdc, const char *str, int *count,
|
||||
char *dest, int *len, int width, WORD format)
|
||||
{
|
||||
/* Return next line of text from a string.
|
||||
*
|
||||
* hdc - handle to DC.
|
||||
* str - string to parse into lines.
|
||||
* count - length of str.
|
||||
* dest - destination in which to return line.
|
||||
* len - length of resultant line in dest in chars.
|
||||
* width - maximum width of line in pixels.
|
||||
* format - format type passed to DrawText.
|
||||
*
|
||||
* Returns pointer to next char in str after end of the line
|
||||
* or NULL if end of str reached.
|
||||
*/
|
||||
|
||||
int i = 0, j = 0, k;
|
||||
int plen = 0;
|
||||
int numspaces;
|
||||
SIZE size;
|
||||
int lasttab = 0;
|
||||
int wb_i = 0, wb_j = 0, wb_count = 0;
|
||||
|
||||
while (*count)
|
||||
{
|
||||
switch (str[i])
|
||||
{
|
||||
case CR:
|
||||
case LF:
|
||||
if (!(format & DT_SINGLELINE))
|
||||
{
|
||||
if ((*count > 1) && (str[i] == CR) && (str[i+1] == LF))
|
||||
{
|
||||
(*count)--;
|
||||
i++;
|
||||
}
|
||||
i++;
|
||||
*len = j;
|
||||
(*count)--;
|
||||
return (&str[i]);
|
||||
}
|
||||
dest[j++] = str[i++];
|
||||
if (!(format & DT_NOCLIP) || !(format & DT_NOPREFIX) ||
|
||||
(format & DT_WORDBREAK))
|
||||
{
|
||||
if (!GetTextExtentPointA(hdc, &dest[j-1], 1, &size))
|
||||
return NULL;
|
||||
plen += size.cx;
|
||||
}
|
||||
break;
|
||||
|
||||
case PREFIX:
|
||||
if (!(format & DT_NOPREFIX) && *count > 1)
|
||||
{
|
||||
if (str[++i] == PREFIX)
|
||||
(*count)--;
|
||||
else {
|
||||
prefix_offset = j;
|
||||
break;
|
||||
}
|
||||
}
|
||||
dest[j++] = str[i++];
|
||||
if (!(format & DT_NOCLIP) || !(format & DT_NOPREFIX) ||
|
||||
(format & DT_WORDBREAK))
|
||||
{
|
||||
if (!GetTextExtentPointA(hdc, &dest[j-1], 1, &size))
|
||||
return NULL;
|
||||
plen += size.cx;
|
||||
}
|
||||
break;
|
||||
|
||||
case TAB:
|
||||
if (format & DT_EXPANDTABS)
|
||||
{
|
||||
wb_i = ++i;
|
||||
wb_j = j;
|
||||
wb_count = *count;
|
||||
|
||||
if (!GetTextExtentPointA(hdc, &dest[lasttab], j - lasttab, &size))
|
||||
return NULL;
|
||||
|
||||
numspaces = (tabwidth - size.cx) / spacewidth;
|
||||
for (k = 0; k < numspaces; k++)
|
||||
dest[j++] = SPACE;
|
||||
plen += tabwidth - size.cx;
|
||||
lasttab = wb_j + numspaces;
|
||||
}
|
||||
else
|
||||
{
|
||||
dest[j++] = str[i++];
|
||||
if (!(format & DT_NOCLIP) || !(format & DT_NOPREFIX) ||
|
||||
(format & DT_WORDBREAK))
|
||||
{
|
||||
if (!GetTextExtentPointA(hdc, &dest[j-1], 1, &size))
|
||||
return NULL;
|
||||
plen += size.cx;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case SPACE:
|
||||
dest[j++] = str[i++];
|
||||
if (!(format & DT_NOCLIP) || !(format & DT_NOPREFIX) ||
|
||||
(format & DT_WORDBREAK))
|
||||
{
|
||||
wb_i = i;
|
||||
wb_j = j - 1;
|
||||
wb_count = *count;
|
||||
if (!GetTextExtentPointA(hdc, &dest[j-1], 1, &size))
|
||||
return NULL;
|
||||
plen += size.cx;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
dest[j++] = str[i++];
|
||||
if (!(format & DT_NOCLIP) || !(format & DT_NOPREFIX) ||
|
||||
(format & DT_WORDBREAK))
|
||||
{
|
||||
if (!GetTextExtentPointA(hdc, &dest[j-1], 1, &size))
|
||||
return NULL;
|
||||
plen += size.cx;
|
||||
}
|
||||
}
|
||||
|
||||
(*count)--;
|
||||
if (!(format & DT_NOCLIP) || (format & DT_WORDBREAK))
|
||||
{
|
||||
if (plen > width)
|
||||
{
|
||||
if (format & DT_WORDBREAK)
|
||||
{
|
||||
if (wb_j)
|
||||
{
|
||||
*len = wb_j;
|
||||
*count = wb_count - 1;
|
||||
return (&str[wb_i]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
*len = j;
|
||||
return (&str[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*len = j;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* DrawText16 (USER.85)
|
||||
*/
|
||||
INT16 WINAPI DrawText16( HDC16 hdc, LPCSTR str, INT16 count, LPRECT16 rect, UINT16 flags )
|
||||
{
|
||||
INT16 ret;
|
||||
|
||||
if (rect)
|
||||
{
|
||||
RECT rect32;
|
||||
CONV_RECT16TO32( rect, &rect32 );
|
||||
ret = DrawTextA( hdc, str, count, &rect32, flags );
|
||||
CONV_RECT32TO16( &rect32, rect );
|
||||
}
|
||||
else ret = DrawTextA( hdc, str, count, NULL, flags);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* DrawTextA (USER32.164)
|
||||
*/
|
||||
INT WINAPI DrawTextA( HDC hdc, LPCSTR str, INT i_count, LPRECT rect, UINT flags )
|
||||
{
|
||||
SIZE size;
|
||||
const char *strPtr;
|
||||
static char line[1024];
|
||||
int len, lh, count=i_count;
|
||||
int prefix_x = 0;
|
||||
int prefix_end = 0;
|
||||
TEXTMETRICA tm;
|
||||
int x = rect->left, y = rect->top;
|
||||
int width = rect->right - rect->left;
|
||||
int max_width = 0;
|
||||
|
||||
TRACE("%s, %d , [(%d,%d),(%d,%d)]\n",
|
||||
debugstr_an (str, count), count,
|
||||
rect->left, rect->top, rect->right, rect->bottom);
|
||||
|
||||
if (!str) return 0;
|
||||
if (count == -1) count = strlen(str);
|
||||
strPtr = str;
|
||||
|
||||
GetTextMetricsA(hdc, &tm);
|
||||
if (flags & DT_EXTERNALLEADING)
|
||||
lh = tm.tmHeight + tm.tmExternalLeading;
|
||||
else
|
||||
lh = tm.tmHeight;
|
||||
|
||||
if (flags & DT_TABSTOP)
|
||||
tabstop = flags >> 8;
|
||||
|
||||
if (flags & DT_EXPANDTABS)
|
||||
{
|
||||
GetTextExtentPointA(hdc, " ", 1, &size);
|
||||
spacewidth = size.cx;
|
||||
GetTextExtentPointA(hdc, "o", 1, &size);
|
||||
tabwidth = size.cx * tabstop;
|
||||
}
|
||||
|
||||
if (flags & DT_CALCRECT) flags |= DT_NOCLIP;
|
||||
|
||||
do
|
||||
{
|
||||
prefix_offset = -1;
|
||||
strPtr = TEXT_NextLine(hdc, strPtr, &count, line, &len, width, flags);
|
||||
|
||||
if (prefix_offset != -1)
|
||||
{
|
||||
GetTextExtentPointA(hdc, line, prefix_offset, &size);
|
||||
prefix_x = size.cx;
|
||||
GetTextExtentPointA(hdc, line, prefix_offset + 1, &size);
|
||||
prefix_end = size.cx - 1;
|
||||
}
|
||||
|
||||
if (!GetTextExtentPointA(hdc, line, len, &size)) return 0;
|
||||
if (flags & DT_CENTER) x = (rect->left + rect->right -
|
||||
size.cx) / 2;
|
||||
else if (flags & DT_RIGHT) x = rect->right - size.cx;
|
||||
|
||||
if (flags & DT_SINGLELINE)
|
||||
{
|
||||
if (flags & DT_VCENTER) y = rect->top +
|
||||
(rect->bottom - rect->top) / 2 - size.cy / 2;
|
||||
else if (flags & DT_BOTTOM) y = rect->bottom - size.cy;
|
||||
}
|
||||
if (!(flags & DT_CALCRECT))
|
||||
{
|
||||
if (!ExtTextOutA(hdc, x, y, (flags & DT_NOCLIP) ? 0 : ETO_CLIPPED,
|
||||
rect, line, len, NULL )) return 0;
|
||||
if (prefix_offset != -1)
|
||||
{
|
||||
HPEN hpen = CreatePen( PS_SOLID, 1, GetTextColor(hdc) );
|
||||
HPEN oldPen = SelectObject( hdc, hpen );
|
||||
MoveToEx(hdc, x + prefix_x, y + tm.tmAscent + 1, NULL );
|
||||
LineTo(hdc, x + prefix_end + 1, y + tm.tmAscent + 1 );
|
||||
SelectObject( hdc, oldPen );
|
||||
DeleteObject( hpen );
|
||||
}
|
||||
}
|
||||
else if (size.cx > max_width)
|
||||
max_width = size.cx;
|
||||
|
||||
y += lh;
|
||||
if (strPtr)
|
||||
{
|
||||
if (!(flags & DT_NOCLIP))
|
||||
{
|
||||
if (y > rect->bottom - lh)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
while (strPtr);
|
||||
if (flags & DT_CALCRECT)
|
||||
{
|
||||
rect->right = rect->left + max_width;
|
||||
rect->bottom = y;
|
||||
}
|
||||
return y - rect->top;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* DrawTextW (USER32.167)
|
||||
*/
|
||||
INT WINAPI DrawTextW( HDC hdc, LPCWSTR str, INT count,
|
||||
LPRECT rect, UINT flags )
|
||||
{
|
||||
LPSTR p;
|
||||
INT acount;
|
||||
INT ret;
|
||||
UINT codepage = CP_ACP; /* FIXME: get codepage of font charset */
|
||||
|
||||
acount = WideCharToMultiByte(codepage,0,str,count,NULL,0,NULL,NULL);
|
||||
p = HeapAlloc( GetProcessHeap(), 0, acount );
|
||||
acount = WideCharToMultiByte(codepage,0,str,count,p,acount,NULL,NULL);
|
||||
if (count == -1) acount = -1;
|
||||
ret = DrawTextA( hdc, p, acount, rect, flags );
|
||||
|
||||
HeapFree( GetProcessHeap(), 0, p );
|
||||
return ret;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* DrawTextExA (USER32.165)
|
||||
*/
|
||||
INT WINAPI DrawTextExA( HDC hdc, LPCSTR str, INT count,
|
||||
LPRECT rect, UINT flags, LPDRAWTEXTPARAMS dtp )
|
||||
{
|
||||
TRACE("(%d,'%s',%d,%p,0x%08x,%p)\n",hdc,str,count,rect,flags,dtp);
|
||||
if(dtp) {
|
||||
FIXME("Ignores params:%d,%d,%d,%d\n",dtp->cbSize,
|
||||
dtp->iTabLength,dtp->iLeftMargin,dtp->iRightMargin);
|
||||
}
|
||||
return DrawTextA(hdc,str,count,rect,flags);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* DrawTextExW (USER32.166)
|
||||
*/
|
||||
INT WINAPI DrawTextExW( HDC hdc, LPCWSTR str, INT count,
|
||||
LPRECT rect, UINT flags, LPDRAWTEXTPARAMS dtp )
|
||||
{
|
||||
TRACE("(%d,%p,%d,%p,0x%08x,%p)\n",hdc,str,count,rect,flags,dtp);
|
||||
FIXME("ignores extended functionality\n");
|
||||
return DrawTextW(hdc,str,count,rect,flags);
|
||||
}
|
||||
/***********************************************************************
|
||||
* TEXT_GrayString
|
||||
*
|
||||
* FIXME: The call to 16-bit code only works because the wine GDI is a 16-bit
|
||||
* heap and we can guarantee that the handles fit in an INT16. We have to
|
||||
* rethink the strategy once the migration to NT handles is complete.
|
||||
* We are going to get a lot of code-duplication once this migration is
|
||||
* completed...
|
||||
*
|
||||
*/
|
||||
static BOOL TEXT_GrayString(HDC hdc, HBRUSH hb, GRAYSTRINGPROC fn, LPARAM lp, INT len,
|
||||
INT x, INT y, INT cx, INT cy, BOOL unicode, BOOL _32bit)
|
||||
{
|
||||
HBITMAP hbm, hbmsave;
|
||||
HBRUSH hbsave;
|
||||
HFONT hfsave;
|
||||
HDC memdc = CreateCompatibleDC(hdc);
|
||||
int slen = len;
|
||||
BOOL retval = TRUE;
|
||||
COLORREF fg, bg;
|
||||
|
||||
if(!hdc) return FALSE;
|
||||
|
||||
if(len == 0)
|
||||
{
|
||||
if(unicode)
|
||||
slen = lstrlenW((LPCWSTR)lp);
|
||||
else if(_32bit)
|
||||
slen = lstrlenA((LPCSTR)lp);
|
||||
else
|
||||
slen = lstrlenA((LPCSTR)PTR_SEG_TO_LIN(lp));
|
||||
}
|
||||
|
||||
if((cx == 0 || cy == 0) && slen != -1)
|
||||
{
|
||||
SIZE s;
|
||||
if(unicode)
|
||||
GetTextExtentPoint32W(hdc, (LPCWSTR)lp, slen, &s);
|
||||
else if(_32bit)
|
||||
GetTextExtentPoint32A(hdc, (LPCSTR)lp, slen, &s);
|
||||
else
|
||||
GetTextExtentPoint32A(hdc, (LPCSTR)PTR_SEG_TO_LIN(lp), slen, &s);
|
||||
if(cx == 0) cx = s.cx;
|
||||
if(cy == 0) cy = s.cy;
|
||||
}
|
||||
|
||||
hbm = CreateBitmap(cx, cy, 1, 1, NULL);
|
||||
hbmsave = (HBITMAP)SelectObject(memdc, hbm);
|
||||
hbsave = SelectObject( memdc, GetStockObject(BLACK_BRUSH) );
|
||||
PatBlt( memdc, 0, 0, cx, cy, PATCOPY );
|
||||
SelectObject( memdc, hbsave );
|
||||
SetTextColor(memdc, RGB(255, 255, 255));
|
||||
SetBkColor(memdc, RGB(0, 0, 0));
|
||||
hfsave = (HFONT)SelectObject(memdc, GetCurrentObject(hdc, OBJ_FONT));
|
||||
|
||||
if(fn)
|
||||
if(_32bit)
|
||||
retval = fn(memdc, lp, slen);
|
||||
else
|
||||
retval = (BOOL)((BOOL16)((GRAYSTRINGPROC16)fn)((HDC16)memdc, lp, (INT16)slen));
|
||||
else
|
||||
if(unicode)
|
||||
TextOutW(memdc, 0, 0, (LPCWSTR)lp, slen);
|
||||
else if(_32bit)
|
||||
TextOutA(memdc, 0, 0, (LPCSTR)lp, slen);
|
||||
else
|
||||
TextOutA(memdc, 0, 0, (LPCSTR)PTR_SEG_TO_LIN(lp), slen);
|
||||
|
||||
SelectObject(memdc, hfsave);
|
||||
|
||||
/*
|
||||
* Windows doc says that the bitmap isn't grayed when len == -1 and
|
||||
* the callback function returns FALSE. However, testing this on
|
||||
* win95 showed otherwise...
|
||||
*/
|
||||
#ifdef GRAYSTRING_USING_DOCUMENTED_BEHAVIOUR
|
||||
if(retval || len != -1)
|
||||
#endif
|
||||
{
|
||||
hbsave = (HBRUSH)SelectObject(memdc, CACHE_GetPattern55AABrush());
|
||||
PatBlt(memdc, 0, 0, cx, cy, 0x000A0329);
|
||||
SelectObject(memdc, hbsave);
|
||||
}
|
||||
|
||||
if(hb) hbsave = (HBRUSH)SelectObject(hdc, hb);
|
||||
fg = SetTextColor(hdc, RGB(0, 0, 0));
|
||||
bg = SetBkColor(hdc, RGB(255, 255, 255));
|
||||
BitBlt(hdc, x, y, cx, cy, memdc, 0, 0, 0x00E20746);
|
||||
SetTextColor(hdc, fg);
|
||||
SetBkColor(hdc, bg);
|
||||
if(hb) SelectObject(hdc, hbsave);
|
||||
|
||||
SelectObject(memdc, hbmsave);
|
||||
DeleteObject(hbm);
|
||||
DeleteDC(memdc);
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* GrayString16 (USER.185)
|
||||
*/
|
||||
BOOL16 WINAPI GrayString16( HDC16 hdc, HBRUSH16 hbr, GRAYSTRINGPROC16 gsprc,
|
||||
LPARAM lParam, INT16 cch, INT16 x, INT16 y,
|
||||
INT16 cx, INT16 cy )
|
||||
{
|
||||
return TEXT_GrayString(hdc, hbr, (GRAYSTRINGPROC)gsprc, lParam, cch, x, y, cx, cy, FALSE, FALSE);
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* GrayStringA (USER32.315)
|
||||
*/
|
||||
BOOL WINAPI GrayStringA( HDC hdc, HBRUSH hbr, GRAYSTRINGPROC gsprc,
|
||||
LPARAM lParam, INT cch, INT x, INT y,
|
||||
INT cx, INT cy )
|
||||
{
|
||||
return TEXT_GrayString(hdc, hbr, gsprc, lParam, cch, x, y, cx, cy, FALSE, TRUE);
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* GrayStringW (USER32.316)
|
||||
*/
|
||||
BOOL WINAPI GrayStringW( HDC hdc, HBRUSH hbr, GRAYSTRINGPROC gsprc,
|
||||
LPARAM lParam, INT cch, INT x, INT y,
|
||||
INT cx, INT cy )
|
||||
{
|
||||
return TEXT_GrayString(hdc, hbr, gsprc, lParam, cch, x, y, cx, cy, TRUE, TRUE);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* TEXT_TabbedTextOut
|
||||
*
|
||||
* Helper function for TabbedTextOut() and GetTabbedTextExtent().
|
||||
* Note: this doesn't work too well for text-alignment modes other
|
||||
* than TA_LEFT|TA_TOP. But we want bug-for-bug compatibility :-)
|
||||
*/
|
||||
static LONG TEXT_TabbedTextOut( HDC hdc, INT x, INT y, LPCSTR lpstr,
|
||||
INT count, INT cTabStops, const INT16 *lpTabPos16,
|
||||
const INT *lpTabPos32, INT nTabOrg,
|
||||
BOOL fDisplayText )
|
||||
{
|
||||
INT defWidth;
|
||||
SIZE extent;
|
||||
int i, tabPos = x;
|
||||
int start = x;
|
||||
|
||||
extent.cx = 0;
|
||||
extent.cy = 0;
|
||||
|
||||
if (cTabStops == 1)
|
||||
{
|
||||
defWidth = lpTabPos32 ? *lpTabPos32 : *lpTabPos16;
|
||||
cTabStops = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
TEXTMETRICA tm;
|
||||
GetTextMetricsA( hdc, &tm );
|
||||
defWidth = 8 * tm.tmAveCharWidth;
|
||||
}
|
||||
|
||||
while (count > 0)
|
||||
{
|
||||
for (i = 0; i < count; i++)
|
||||
if (lpstr[i] == '\t') break;
|
||||
GetTextExtentPointA( hdc, lpstr, i, &extent );
|
||||
if (lpTabPos32)
|
||||
{
|
||||
while ((cTabStops > 0) &&
|
||||
(nTabOrg + *lpTabPos32 <= x + extent.cx))
|
||||
{
|
||||
lpTabPos32++;
|
||||
cTabStops--;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
while ((cTabStops > 0) &&
|
||||
(nTabOrg + *lpTabPos16 <= x + extent.cx))
|
||||
{
|
||||
lpTabPos16++;
|
||||
cTabStops--;
|
||||
}
|
||||
}
|
||||
if (i == count)
|
||||
tabPos = x + extent.cx;
|
||||
else if (cTabStops > 0)
|
||||
tabPos = nTabOrg + (lpTabPos32 ? *lpTabPos32 : *lpTabPos16);
|
||||
else
|
||||
tabPos = nTabOrg + ((x + extent.cx - nTabOrg) / defWidth + 1) * defWidth;
|
||||
if (fDisplayText)
|
||||
{
|
||||
RECT r;
|
||||
r.left = x;
|
||||
r.top = y;
|
||||
r.right = tabPos;
|
||||
r.bottom = y + extent.cy;
|
||||
ExtTextOutA( hdc, x, y,
|
||||
GetBkMode(hdc) == OPAQUE ? ETO_OPAQUE : 0,
|
||||
&r, lpstr, i, NULL );
|
||||
}
|
||||
x = tabPos;
|
||||
count -= i+1;
|
||||
lpstr += i+1;
|
||||
}
|
||||
return MAKELONG(tabPos - start, extent.cy);
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* TabbedTextOut16 (USER.196)
|
||||
*/
|
||||
LONG WINAPI TabbedTextOut16( HDC16 hdc, INT16 x, INT16 y, LPCSTR lpstr,
|
||||
INT16 count, INT16 cTabStops,
|
||||
const INT16 *lpTabPos, INT16 nTabOrg )
|
||||
{
|
||||
TRACE("%04x %d,%d '%.*s' %d\n",
|
||||
hdc, x, y, count, lpstr, count );
|
||||
return TEXT_TabbedTextOut( hdc, x, y, lpstr, count, cTabStops,
|
||||
lpTabPos, NULL, nTabOrg, TRUE );
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* TabbedTextOutA (USER32.542)
|
||||
*/
|
||||
LONG WINAPI TabbedTextOutA( HDC hdc, INT x, INT y, LPCSTR lpstr,
|
||||
INT count, INT cTabStops,
|
||||
const INT *lpTabPos, INT nTabOrg )
|
||||
{
|
||||
TRACE("%04x %d,%d '%.*s' %d\n",
|
||||
hdc, x, y, count, lpstr, count );
|
||||
return TEXT_TabbedTextOut( hdc, x, y, lpstr, count, cTabStops,
|
||||
NULL, lpTabPos, nTabOrg, TRUE );
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* TabbedTextOutW (USER32.543)
|
||||
*/
|
||||
LONG WINAPI TabbedTextOutW( HDC hdc, INT x, INT y, LPCWSTR str,
|
||||
INT count, INT cTabStops,
|
||||
const INT *lpTabPos, INT nTabOrg )
|
||||
{
|
||||
LONG ret;
|
||||
LPSTR p;
|
||||
INT acount;
|
||||
UINT codepage = CP_ACP; /* FIXME: get codepage of font charset */
|
||||
|
||||
acount = WideCharToMultiByte(codepage,0,str,count,NULL,0,NULL,NULL);
|
||||
p = HeapAlloc( GetProcessHeap(), 0, acount );
|
||||
if(p == NULL) return 0; /* FIXME: is this the correct return on failure */
|
||||
acount = WideCharToMultiByte(codepage,0,str,count,p,acount,NULL,NULL);
|
||||
ret = TabbedTextOutA( hdc, x, y, p, acount, cTabStops,
|
||||
lpTabPos, nTabOrg );
|
||||
HeapFree( GetProcessHeap(), 0, p );
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* GetTabbedTextExtent16 (USER.197)
|
||||
*/
|
||||
DWORD WINAPI GetTabbedTextExtent16( HDC16 hdc, LPCSTR lpstr, INT16 count,
|
||||
INT16 cTabStops, const INT16 *lpTabPos )
|
||||
{
|
||||
TRACE("%04x '%.*s' %d\n",
|
||||
hdc, count, lpstr, count );
|
||||
return TEXT_TabbedTextOut( hdc, 0, 0, lpstr, count, cTabStops,
|
||||
lpTabPos, NULL, 0, FALSE );
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* GetTabbedTextExtentA (USER32.293)
|
||||
*/
|
||||
DWORD WINAPI GetTabbedTextExtentA( HDC hdc, LPCSTR lpstr, INT count,
|
||||
INT cTabStops, const INT *lpTabPos )
|
||||
{
|
||||
TRACE("%04x '%.*s' %d\n",
|
||||
hdc, count, lpstr, count );
|
||||
return TEXT_TabbedTextOut( hdc, 0, 0, lpstr, count, cTabStops,
|
||||
NULL, lpTabPos, 0, FALSE );
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* GetTabbedTextExtentW (USER32.294)
|
||||
*/
|
||||
DWORD WINAPI GetTabbedTextExtentW( HDC hdc, LPCWSTR lpstr, INT count,
|
||||
INT cTabStops, const INT *lpTabPos )
|
||||
{
|
||||
LONG ret;
|
||||
LPSTR p;
|
||||
INT acount;
|
||||
UINT codepage = CP_ACP; /* FIXME: get codepage of font charset */
|
||||
|
||||
acount = WideCharToMultiByte(codepage,0,lpstr,count,NULL,0,NULL,NULL);
|
||||
p = HeapAlloc( GetProcessHeap(), 0, acount );
|
||||
if(p == NULL) return 0; /* FIXME: is this the correct failure value? */
|
||||
acount = WideCharToMultiByte(codepage,0,lpstr,count,p,acount,NULL,NULL);
|
||||
ret = GetTabbedTextExtentA( hdc, p, acount, cTabStops, lpTabPos );
|
||||
HeapFree( GetProcessHeap(), 0, p );
|
||||
return ret;
|
||||
}
|
@ -7,7 +7,6 @@ MODULE = graphics
|
||||
|
||||
C_SRCS = \
|
||||
bitblt.c \
|
||||
cache.c \
|
||||
dispdib.c \
|
||||
driver.c \
|
||||
env.c \
|
||||
|
@ -31,7 +31,6 @@
|
||||
#include "winnls.h"
|
||||
|
||||
DEFAULT_DEBUG_CHANNEL(resource);
|
||||
DECLARE_DEBUG_CHANNEL(accel);
|
||||
|
||||
#define HRSRC_MAP_BLOCKSIZE 16
|
||||
|
||||
@ -571,399 +570,6 @@ DWORD WINAPI SizeofResource( HINSTANCE hModule, HRSRC hRsrc )
|
||||
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
* LoadAccelerators16 [USER.177]
|
||||
*/
|
||||
HACCEL16 WINAPI LoadAccelerators16(HINSTANCE16 instance, SEGPTR lpTableName)
|
||||
{
|
||||
HRSRC16 hRsrc;
|
||||
|
||||
if (HIWORD(lpTableName))
|
||||
TRACE_(accel)("%04x '%s'\n",
|
||||
instance, (char *)PTR_SEG_TO_LIN( lpTableName ) );
|
||||
else
|
||||
TRACE_(accel)("%04x %04x\n",
|
||||
instance, LOWORD(lpTableName) );
|
||||
|
||||
if (!(hRsrc = FindResource16( instance, lpTableName, RT_ACCELERATOR16 ))) {
|
||||
WARN_(accel)("couldn't find accelerator table resource\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
TRACE_(accel)("returning HACCEL 0x%x\n", hRsrc);
|
||||
return LoadResource16(instance,hRsrc);
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
* LoadAcceleratorsW [USER.177]
|
||||
* The image layout seems to look like this (not 100% sure):
|
||||
* 00: BYTE type type of accelerator
|
||||
* 01: BYTE pad (to WORD boundary)
|
||||
* 02: WORD event
|
||||
* 04: WORD IDval
|
||||
* 06: WORD pad (to DWORD boundary)
|
||||
*/
|
||||
HACCEL WINAPI LoadAcceleratorsW(HINSTANCE instance,LPCWSTR lpTableName)
|
||||
{
|
||||
HRSRC hRsrc;
|
||||
HACCEL hMem,hRetval=0;
|
||||
DWORD size;
|
||||
|
||||
if (HIWORD(lpTableName))
|
||||
TRACE_(accel)("%p '%s'\n",
|
||||
(LPVOID)instance, (char *)( lpTableName ) );
|
||||
else
|
||||
TRACE_(accel)("%p 0x%04x\n",
|
||||
(LPVOID)instance, LOWORD(lpTableName) );
|
||||
|
||||
if (!(hRsrc = FindResourceW( instance, lpTableName, RT_ACCELERATORW )))
|
||||
{
|
||||
WARN_(accel)("couldn't find accelerator table resource\n");
|
||||
} else {
|
||||
hMem = LoadResource( instance, hRsrc );
|
||||
size = SizeofResource( instance, hRsrc );
|
||||
if(size>=sizeof(PE_ACCEL))
|
||||
{
|
||||
LPPE_ACCEL accel_table = (LPPE_ACCEL) hMem;
|
||||
LPACCEL16 accel16;
|
||||
int i,nrofaccells = size/sizeof(PE_ACCEL);
|
||||
|
||||
hRetval = GlobalAlloc16(0,sizeof(ACCEL16)*nrofaccells);
|
||||
accel16 = (LPACCEL16)GlobalLock16(hRetval);
|
||||
for (i=0;i<nrofaccells;i++) {
|
||||
accel16[i].fVirt = accel_table[i].fVirt;
|
||||
accel16[i].key = accel_table[i].key;
|
||||
accel16[i].cmd = accel_table[i].cmd;
|
||||
}
|
||||
accel16[i-1].fVirt |= 0x80;
|
||||
}
|
||||
}
|
||||
TRACE_(accel)("returning HACCEL 0x%x\n", hRsrc);
|
||||
return hRetval;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* LoadAcceleratorsA
|
||||
*/
|
||||
HACCEL WINAPI LoadAcceleratorsA(HINSTANCE instance,LPCSTR lpTableName)
|
||||
{
|
||||
LPWSTR uni;
|
||||
HACCEL result;
|
||||
if (HIWORD(lpTableName))
|
||||
uni = HEAP_strdupAtoW( GetProcessHeap(), 0, lpTableName );
|
||||
else
|
||||
uni = (LPWSTR)lpTableName;
|
||||
result = LoadAcceleratorsW(instance,uni);
|
||||
if (HIWORD(uni)) HeapFree( GetProcessHeap(), 0, uni);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
* CopyAcceleratorTableA (USER32.58)
|
||||
*/
|
||||
INT WINAPI CopyAcceleratorTableA(HACCEL src, LPACCEL dst, INT entries)
|
||||
{
|
||||
return CopyAcceleratorTableW(src, dst, entries);
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
* CopyAcceleratorTableW (USER32.59)
|
||||
*
|
||||
* By mortene@pvv.org 980321
|
||||
*/
|
||||
INT WINAPI CopyAcceleratorTableW(HACCEL src, LPACCEL dst,
|
||||
INT entries)
|
||||
{
|
||||
int i,xsize;
|
||||
LPACCEL16 accel = (LPACCEL16)GlobalLock16(src);
|
||||
BOOL done = FALSE;
|
||||
|
||||
/* Do parameter checking to avoid the explosions and the screaming
|
||||
as far as possible. */
|
||||
if((dst && (entries < 1)) || (src == (HACCEL)NULL) || !accel) {
|
||||
WARN_(accel)("Application sent invalid parameters (%p %p %d).\n",
|
||||
(LPVOID)src, (LPVOID)dst, entries);
|
||||
return 0;
|
||||
}
|
||||
xsize = GlobalSize16(src)/sizeof(ACCEL16);
|
||||
if (xsize>entries) entries=xsize;
|
||||
|
||||
i=0;
|
||||
while(!done) {
|
||||
/* Spit out some debugging information. */
|
||||
TRACE_(accel)("accel %d: type 0x%02x, event '%c', IDval 0x%04x.\n",
|
||||
i, accel[i].fVirt, accel[i].key, accel[i].cmd);
|
||||
|
||||
/* Copy data to the destination structure array (if dst == NULL,
|
||||
we're just supposed to count the number of entries). */
|
||||
if(dst) {
|
||||
dst[i].fVirt = accel[i].fVirt;
|
||||
dst[i].key = accel[i].key;
|
||||
dst[i].cmd = accel[i].cmd;
|
||||
|
||||
/* Check if we've reached the end of the application supplied
|
||||
accelerator table. */
|
||||
if(i+1 == entries) {
|
||||
/* Turn off the high order bit, just in case. */
|
||||
dst[i].fVirt &= 0x7f;
|
||||
done = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
/* The highest order bit seems to mark the end of the accelerator
|
||||
resource table, but not always. Use GlobalSize() check too. */
|
||||
if((accel[i].fVirt & 0x80) != 0) done = TRUE;
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* CreateAcceleratorTableA (USER32.64)
|
||||
*
|
||||
* By mortene@pvv.org 980321
|
||||
*/
|
||||
HACCEL WINAPI CreateAcceleratorTableA(LPACCEL lpaccel, INT cEntries)
|
||||
{
|
||||
HACCEL hAccel;
|
||||
LPACCEL16 accel;
|
||||
int i;
|
||||
|
||||
/* Do parameter checking just in case someone's trying to be
|
||||
funny. */
|
||||
if(cEntries < 1) {
|
||||
WARN_(accel)("Application sent invalid parameters (%p %d).\n",
|
||||
lpaccel, cEntries);
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return (HACCEL)NULL;
|
||||
}
|
||||
FIXME_(accel)("should check that the accelerator descriptions are valid,"
|
||||
" return NULL and SetLastError() if not.\n");
|
||||
|
||||
|
||||
/* Allocate memory and copy the table. */
|
||||
hAccel = GlobalAlloc16(0,cEntries*sizeof(ACCEL16));
|
||||
|
||||
TRACE_(accel)("handle %x\n", hAccel);
|
||||
if(!hAccel) {
|
||||
ERR_(accel)("Out of memory.\n");
|
||||
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
|
||||
return (HACCEL)NULL;
|
||||
}
|
||||
accel = GlobalLock16(hAccel);
|
||||
for (i=0;i<cEntries;i++) {
|
||||
accel[i].fVirt = lpaccel[i].fVirt;
|
||||
accel[i].key = lpaccel[i].key;
|
||||
accel[i].cmd = lpaccel[i].cmd;
|
||||
}
|
||||
/* Set the end-of-table terminator. */
|
||||
accel[cEntries-1].fVirt |= 0x80;
|
||||
|
||||
TRACE_(accel)("Allocated accelerator handle %x\n", hAccel);
|
||||
return hAccel;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* CreateAcceleratorTableW (USER32.64)
|
||||
*
|
||||
*
|
||||
*/
|
||||
HACCEL WINAPI CreateAcceleratorTableW(LPACCEL lpaccel, INT cEntries)
|
||||
{
|
||||
HACCEL hAccel;
|
||||
LPACCEL16 accel;
|
||||
int i;
|
||||
char ckey;
|
||||
|
||||
/* Do parameter checking just in case someone's trying to be
|
||||
funny. */
|
||||
if(cEntries < 1) {
|
||||
WARN_(accel)("Application sent invalid parameters (%p %d).\n",
|
||||
lpaccel, cEntries);
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return (HACCEL)NULL;
|
||||
}
|
||||
FIXME_(accel)("should check that the accelerator descriptions are valid,"
|
||||
" return NULL and SetLastError() if not.\n");
|
||||
|
||||
|
||||
/* Allocate memory and copy the table. */
|
||||
hAccel = GlobalAlloc16(0,cEntries*sizeof(ACCEL16));
|
||||
|
||||
TRACE_(accel)("handle %x\n", hAccel);
|
||||
if(!hAccel) {
|
||||
ERR_(accel)("Out of memory.\n");
|
||||
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
|
||||
return (HACCEL)NULL;
|
||||
}
|
||||
accel = GlobalLock16(hAccel);
|
||||
|
||||
|
||||
for (i=0;i<cEntries;i++) {
|
||||
accel[i].fVirt = lpaccel[i].fVirt;
|
||||
if( !(accel[i].fVirt & FVIRTKEY) ) {
|
||||
ckey = (char) lpaccel[i].key;
|
||||
if(!MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, &ckey, 1, &accel[i].key, 1))
|
||||
WARN_(accel)("Error converting ASCII accelerator table to Unicode");
|
||||
}
|
||||
else
|
||||
accel[i].key = lpaccel[i].key;
|
||||
accel[i].cmd = lpaccel[i].cmd;
|
||||
}
|
||||
|
||||
/* Set the end-of-table terminator. */
|
||||
accel[cEntries-1].fVirt |= 0x80;
|
||||
|
||||
TRACE_(accel)("Allocated accelerator handle %x\n", hAccel);
|
||||
return hAccel;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* DestroyAcceleratorTable [USER32.130]
|
||||
* Destroys an accelerator table
|
||||
*
|
||||
* NOTES
|
||||
* By mortene@pvv.org 980321
|
||||
*
|
||||
* PARAMS
|
||||
* handle [I] Handle to accelerator table
|
||||
*
|
||||
* RETURNS STD
|
||||
*/
|
||||
BOOL WINAPI DestroyAcceleratorTable( HACCEL handle )
|
||||
{
|
||||
return !GlobalFree16(handle);
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
* LoadString16
|
||||
*/
|
||||
INT16 WINAPI LoadString16( HINSTANCE16 instance, UINT16 resource_id,
|
||||
LPSTR buffer, INT16 buflen )
|
||||
{
|
||||
HGLOBAL16 hmem;
|
||||
HRSRC16 hrsrc;
|
||||
unsigned char *p;
|
||||
int string_num;
|
||||
int i;
|
||||
|
||||
TRACE("inst=%04x id=%04x buff=%08x len=%d\n",
|
||||
instance, resource_id, (int) buffer, buflen);
|
||||
|
||||
hrsrc = FindResource16( instance, (SEGPTR)((resource_id>>4)+1), RT_STRING16 );
|
||||
if (!hrsrc) return 0;
|
||||
hmem = LoadResource16( instance, hrsrc );
|
||||
if (!hmem) return 0;
|
||||
|
||||
p = LockResource16(hmem);
|
||||
string_num = resource_id & 0x000f;
|
||||
for (i = 0; i < string_num; i++)
|
||||
p += *p + 1;
|
||||
|
||||
TRACE("strlen = %d\n", (int)*p );
|
||||
|
||||
if (buffer == NULL) return *p;
|
||||
i = min(buflen - 1, *p);
|
||||
if (i > 0) {
|
||||
memcpy(buffer, p + 1, i);
|
||||
buffer[i] = '\0';
|
||||
} else {
|
||||
if (buflen > 1) {
|
||||
buffer[0] = '\0';
|
||||
return 0;
|
||||
}
|
||||
WARN("Dont know why caller give buflen=%d *p=%d trying to obtain string '%s'\n", buflen, *p, p + 1);
|
||||
}
|
||||
FreeResource16( hmem );
|
||||
|
||||
TRACE("'%s' loaded !\n", buffer);
|
||||
return i;
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
* LoadStringW (USER32.376)
|
||||
*/
|
||||
INT WINAPI LoadStringW( HINSTANCE instance, UINT resource_id,
|
||||
LPWSTR buffer, INT buflen )
|
||||
{
|
||||
HGLOBAL hmem;
|
||||
HRSRC hrsrc;
|
||||
WCHAR *p;
|
||||
int string_num;
|
||||
int i;
|
||||
|
||||
if (HIWORD(resource_id)==0xFFFF) /* netscape 3 passes this */
|
||||
resource_id = (UINT)(-((INT)resource_id));
|
||||
TRACE("instance = %04x, id = %04x, buffer = %08x, "
|
||||
"length = %d\n", instance, (int)resource_id, (int) buffer, buflen);
|
||||
|
||||
/* Use bits 4 - 19 (incremented by 1) as resourceid, mask out
|
||||
* 20 - 31. */
|
||||
hrsrc = FindResourceW( instance, (LPCWSTR)(((resource_id>>4)&0xffff)+1),
|
||||
RT_STRINGW );
|
||||
if (!hrsrc) return 0;
|
||||
hmem = LoadResource( instance, hrsrc );
|
||||
if (!hmem) return 0;
|
||||
|
||||
p = LockResource(hmem);
|
||||
string_num = resource_id & 0x000f;
|
||||
for (i = 0; i < string_num; i++)
|
||||
p += *p + 1;
|
||||
|
||||
TRACE("strlen = %d\n", (int)*p );
|
||||
|
||||
if (buffer == NULL) return *p;
|
||||
i = min(buflen - 1, *p);
|
||||
if (i > 0) {
|
||||
memcpy(buffer, p + 1, i * sizeof (WCHAR));
|
||||
buffer[i] = (WCHAR) 0;
|
||||
} else {
|
||||
if (buflen > 1) {
|
||||
buffer[0] = (WCHAR) 0;
|
||||
return 0;
|
||||
}
|
||||
#if 0
|
||||
WARN("Dont know why caller give buflen=%d *p=%d trying to obtain string '%s'\n", buflen, *p, p + 1);
|
||||
#endif
|
||||
}
|
||||
|
||||
TRACE("%s loaded !\n", debugstr_w(buffer));
|
||||
return i;
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
* LoadStringA (USER32.375)
|
||||
*/
|
||||
INT WINAPI LoadStringA( HINSTANCE instance, UINT resource_id,
|
||||
LPSTR buffer, INT buflen )
|
||||
{
|
||||
INT retval;
|
||||
LPWSTR wbuf;
|
||||
|
||||
TRACE("instance = %04x, id = %04x, buffer = %08x, "
|
||||
"length = %d\n", instance, (int)resource_id, (int) buffer, buflen);
|
||||
|
||||
if(buffer == NULL) /* asked size of string */
|
||||
return LoadStringW(instance, resource_id, NULL, 0);
|
||||
|
||||
wbuf = HeapAlloc(GetProcessHeap(), 0, buflen * sizeof(WCHAR));
|
||||
if(!wbuf)
|
||||
return 0;
|
||||
|
||||
retval = LoadStringW(instance, resource_id, wbuf, buflen);
|
||||
if(retval != 0)
|
||||
{
|
||||
retval = WideCharToMultiByte(CP_ACP, 0, wbuf, retval, buffer, buflen - 1, NULL, NULL);
|
||||
buffer[retval] = 0;
|
||||
TRACE("%s loaded !\n", debugstr_a(buffer));
|
||||
}
|
||||
HeapFree( GetProcessHeap(), 0, wbuf );
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
* EnumResourceTypesA (KERNEL32.90)
|
||||
*/
|
||||
|
180
misc/lstr.c
180
misc/lstr.c
@ -30,11 +30,8 @@
|
||||
#include "wine/winuser16.h"
|
||||
#include "wine/unicode.h"
|
||||
#include "winnls.h"
|
||||
#include "task.h"
|
||||
#include "heap.h"
|
||||
#include "ldt.h"
|
||||
#include "stackframe.h"
|
||||
#include "module.h"
|
||||
#include "debugtools.h"
|
||||
|
||||
DEFAULT_DEBUG_CHANNEL(resource);
|
||||
@ -462,180 +459,3 @@ BOOL WINAPI IsCharUpperW(WCHAR x)
|
||||
{
|
||||
return iswupper(x);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* FormatMessage16 (USER.606)
|
||||
*/
|
||||
DWORD WINAPI FormatMessage16(
|
||||
DWORD dwFlags,
|
||||
SEGPTR lpSource, /*not always a valid pointer*/
|
||||
WORD dwMessageId,
|
||||
WORD dwLanguageId,
|
||||
LPSTR lpBuffer, /* *((HLOCAL16*)) for FORMAT_MESSAGE_ALLOCATE_BUFFER*/
|
||||
WORD nSize,
|
||||
LPDWORD args /* va_list *args */
|
||||
) {
|
||||
#ifdef __i386__
|
||||
/* This implementation is completely dependant on the format of the va_list on x86 CPUs */
|
||||
LPSTR target,t;
|
||||
DWORD talloced;
|
||||
LPSTR from,f;
|
||||
DWORD width = dwFlags & FORMAT_MESSAGE_MAX_WIDTH_MASK;
|
||||
BOOL eos = FALSE;
|
||||
LPSTR allocstring = NULL;
|
||||
|
||||
TRACE("(0x%lx,%lx,%d,0x%x,%p,%d,%p)\n",
|
||||
dwFlags,lpSource,dwMessageId,dwLanguageId,lpBuffer,nSize,args);
|
||||
if ((dwFlags & FORMAT_MESSAGE_FROM_SYSTEM)
|
||||
&& (dwFlags & FORMAT_MESSAGE_FROM_HMODULE)) return 0;
|
||||
if ((dwFlags & FORMAT_MESSAGE_FROM_STRING)
|
||||
&&((dwFlags & FORMAT_MESSAGE_FROM_SYSTEM)
|
||||
|| (dwFlags & FORMAT_MESSAGE_FROM_HMODULE))) return 0;
|
||||
|
||||
if (width && width != FORMAT_MESSAGE_MAX_WIDTH_MASK)
|
||||
FIXME("line wrapping (%lu) not supported.\n", width);
|
||||
from = NULL;
|
||||
if (dwFlags & FORMAT_MESSAGE_FROM_STRING)
|
||||
from = HEAP_strdupA( GetProcessHeap(), 0, PTR_SEG_TO_LIN(lpSource));
|
||||
if (dwFlags & FORMAT_MESSAGE_FROM_SYSTEM) {
|
||||
from = HeapAlloc( GetProcessHeap(),0,200 );
|
||||
sprintf(from,"Systemmessage, messageid = 0x%08x\n",dwMessageId);
|
||||
}
|
||||
if (dwFlags & FORMAT_MESSAGE_FROM_HMODULE) {
|
||||
INT16 bufsize;
|
||||
HINSTANCE16 hinst16 = ((HMODULE)lpSource & 0xffff);
|
||||
|
||||
dwMessageId &= 0xFFFF;
|
||||
bufsize=LoadString16(hinst16,dwMessageId,NULL,0);
|
||||
if (bufsize) {
|
||||
from = HeapAlloc( GetProcessHeap(), 0, bufsize +1);
|
||||
LoadString16(hinst16,dwMessageId,from,bufsize+1);
|
||||
}
|
||||
}
|
||||
target = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, 100);
|
||||
t = target;
|
||||
talloced= 100;
|
||||
|
||||
#define ADD_TO_T(c) \
|
||||
*t++=c;\
|
||||
if (t-target == talloced) {\
|
||||
target = (char*)HeapReAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,target,talloced*2);\
|
||||
t = target+talloced;\
|
||||
talloced*=2;\
|
||||
}
|
||||
|
||||
if (from) {
|
||||
f=from;
|
||||
while (*f && !eos) {
|
||||
if (*f=='%') {
|
||||
int insertnr;
|
||||
char *fmtstr,*x,*lastf;
|
||||
DWORD *argliststart;
|
||||
|
||||
fmtstr = NULL;
|
||||
lastf = f;
|
||||
f++;
|
||||
if (!*f) {
|
||||
ADD_TO_T('%');
|
||||
continue;
|
||||
}
|
||||
switch (*f) {
|
||||
case '1':case '2':case '3':case '4':case '5':
|
||||
case '6':case '7':case '8':case '9':
|
||||
insertnr=*f-'0';
|
||||
switch (f[1]) {
|
||||
case '0':case '1':case '2':case '3':
|
||||
case '4':case '5':case '6':case '7':
|
||||
case '8':case '9':
|
||||
f++;
|
||||
insertnr=insertnr*10+*f-'0';
|
||||
f++;
|
||||
break;
|
||||
default:
|
||||
f++;
|
||||
break;
|
||||
}
|
||||
if (*f=='!') {
|
||||
f++;
|
||||
if (NULL!=(x=strchr(f,'!'))) {
|
||||
*x='\0';
|
||||
fmtstr=HeapAlloc(GetProcessHeap(),0,strlen(f)+2);
|
||||
sprintf(fmtstr,"%%%s",f);
|
||||
f=x+1;
|
||||
} else {
|
||||
fmtstr=HeapAlloc(GetProcessHeap(),0,strlen(f)+2);
|
||||
sprintf(fmtstr,"%%%s",f);
|
||||
f+=strlen(f); /*at \0*/
|
||||
}
|
||||
} else
|
||||
if(!args)
|
||||
break;
|
||||
else
|
||||
fmtstr=HEAP_strdupA(GetProcessHeap(),0,"%s");
|
||||
if (args) {
|
||||
int sz;
|
||||
LPSTR b = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sz = 100);
|
||||
|
||||
argliststart=args+insertnr-1;
|
||||
|
||||
/* CMF - This makes a BIG assumption about va_list */
|
||||
while (vsnprintf(b, sz, fmtstr, (va_list) argliststart) < 0) {
|
||||
b = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, b, sz += 100);
|
||||
}
|
||||
for (x=b; *x; x++) ADD_TO_T(*x);
|
||||
} else {
|
||||
/* NULL args - copy formatstr
|
||||
* (probably wrong)
|
||||
*/
|
||||
while ((lastf<f)&&(*lastf)) {
|
||||
ADD_TO_T(*lastf++);
|
||||
}
|
||||
}
|
||||
HeapFree(GetProcessHeap(),0,fmtstr);
|
||||
break;
|
||||
case '0': /* Just stop processing format string */
|
||||
eos = TRUE;
|
||||
f++;
|
||||
break;
|
||||
case 'n': /* 16 bit version just outputs 'n' */
|
||||
default:
|
||||
ADD_TO_T(*f++);
|
||||
break;
|
||||
}
|
||||
} else { /* '\n' or '\r' gets mapped to "\r\n" */
|
||||
if(*f == '\n' || *f == '\r') {
|
||||
if (width == 0) {
|
||||
ADD_TO_T('\r');
|
||||
ADD_TO_T('\n');
|
||||
if(*f++ == '\r' && *f == '\n')
|
||||
f++;
|
||||
}
|
||||
} else {
|
||||
ADD_TO_T(*f++);
|
||||
}
|
||||
}
|
||||
}
|
||||
*t='\0';
|
||||
}
|
||||
talloced = strlen(target)+1;
|
||||
if (nSize && talloced<nSize) {
|
||||
target = (char*)HeapReAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,target,nSize);
|
||||
}
|
||||
TRACE("-- %s\n",debugstr_a(target));
|
||||
if (dwFlags & FORMAT_MESSAGE_ALLOCATE_BUFFER) {
|
||||
/* nSize is the MINIMUM size */
|
||||
*((HLOCAL16*)lpBuffer)= LocalAlloc16(LPTR,talloced);
|
||||
allocstring=PTR_SEG_OFF_TO_LIN(CURRENT_DS,*((HLOCAL16*)lpBuffer));
|
||||
memcpy( allocstring,target,talloced);
|
||||
} else
|
||||
lstrcpynA(lpBuffer,target,nSize);
|
||||
HeapFree(GetProcessHeap(),0,target);
|
||||
if (from) HeapFree(GetProcessHeap(),0,from);
|
||||
return (dwFlags & FORMAT_MESSAGE_ALLOCATE_BUFFER) ?
|
||||
strlen(allocstring):
|
||||
strlen(lpBuffer);
|
||||
#else
|
||||
return 0;
|
||||
#endif /* __i386__ */
|
||||
}
|
||||
#undef ADD_TO_T
|
||||
|
@ -745,16 +745,6 @@ BOOL16 WINAPI IsDCCurrentPalette16(HDC16 hDC)
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* SelectPalette16 (USER.282)
|
||||
*/
|
||||
HPALETTE16 WINAPI SelectPalette16( HDC16 hDC, HPALETTE16 hPal,
|
||||
BOOL16 bForceBackground )
|
||||
{
|
||||
return SelectPalette( hDC, hPal, bForceBackground );
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* SelectPalette [GDI32.300] Selects logical palette into DC
|
||||
*
|
||||
@ -783,15 +773,6 @@ HPALETTE WINAPI SelectPalette(
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* RealizePalette16 (USER.283)
|
||||
*/
|
||||
UINT16 WINAPI RealizePalette16( HDC16 hDC )
|
||||
{
|
||||
return RealizePalette( hDC );
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* RealizePalette [GDI32.280] Maps palette entries to system palette
|
||||
*
|
||||
|
645
objects/text.c
645
objects/text.c
@ -16,347 +16,10 @@
|
||||
#include "gdi.h"
|
||||
#include "heap.h"
|
||||
#include "debugtools.h"
|
||||
#include "cache.h"
|
||||
#include "winnls.h"
|
||||
|
||||
DEFAULT_DEBUG_CHANNEL(text);
|
||||
|
||||
#define TAB 9
|
||||
#define LF 10
|
||||
#define CR 13
|
||||
#define SPACE 32
|
||||
#define PREFIX 38
|
||||
|
||||
#define SWAP_INT(a,b) { int t = a; a = b; b = t; }
|
||||
|
||||
static int tabstop = 8;
|
||||
static int tabwidth;
|
||||
static int spacewidth;
|
||||
static int prefix_offset;
|
||||
|
||||
static const char *TEXT_NextLine( HDC16 hdc, const char *str, int *count,
|
||||
char *dest, int *len, int width, WORD format)
|
||||
{
|
||||
/* Return next line of text from a string.
|
||||
*
|
||||
* hdc - handle to DC.
|
||||
* str - string to parse into lines.
|
||||
* count - length of str.
|
||||
* dest - destination in which to return line.
|
||||
* len - length of resultant line in dest in chars.
|
||||
* width - maximum width of line in pixels.
|
||||
* format - format type passed to DrawText.
|
||||
*
|
||||
* Returns pointer to next char in str after end of the line
|
||||
* or NULL if end of str reached.
|
||||
*/
|
||||
|
||||
int i = 0, j = 0, k;
|
||||
int plen = 0;
|
||||
int numspaces;
|
||||
SIZE16 size;
|
||||
int lasttab = 0;
|
||||
int wb_i = 0, wb_j = 0, wb_count = 0;
|
||||
|
||||
while (*count)
|
||||
{
|
||||
switch (str[i])
|
||||
{
|
||||
case CR:
|
||||
case LF:
|
||||
if (!(format & DT_SINGLELINE))
|
||||
{
|
||||
if ((*count > 1) && (str[i] == CR) && (str[i+1] == LF))
|
||||
{
|
||||
(*count)--;
|
||||
i++;
|
||||
}
|
||||
i++;
|
||||
*len = j;
|
||||
(*count)--;
|
||||
return (&str[i]);
|
||||
}
|
||||
dest[j++] = str[i++];
|
||||
if (!(format & DT_NOCLIP) || !(format & DT_NOPREFIX) ||
|
||||
(format & DT_WORDBREAK))
|
||||
{
|
||||
if (!GetTextExtentPoint16(hdc, &dest[j-1], 1, &size))
|
||||
return NULL;
|
||||
plen += size.cx;
|
||||
}
|
||||
break;
|
||||
|
||||
case PREFIX:
|
||||
if (!(format & DT_NOPREFIX) && *count > 1)
|
||||
{
|
||||
if (str[++i] == PREFIX)
|
||||
(*count)--;
|
||||
else {
|
||||
prefix_offset = j;
|
||||
break;
|
||||
}
|
||||
}
|
||||
dest[j++] = str[i++];
|
||||
if (!(format & DT_NOCLIP) || !(format & DT_NOPREFIX) ||
|
||||
(format & DT_WORDBREAK))
|
||||
{
|
||||
if (!GetTextExtentPoint16(hdc, &dest[j-1], 1, &size))
|
||||
return NULL;
|
||||
plen += size.cx;
|
||||
}
|
||||
break;
|
||||
|
||||
case TAB:
|
||||
if (format & DT_EXPANDTABS)
|
||||
{
|
||||
wb_i = ++i;
|
||||
wb_j = j;
|
||||
wb_count = *count;
|
||||
|
||||
if (!GetTextExtentPoint16(hdc, &dest[lasttab], j - lasttab,
|
||||
&size))
|
||||
return NULL;
|
||||
|
||||
numspaces = (tabwidth - size.cx) / spacewidth;
|
||||
for (k = 0; k < numspaces; k++)
|
||||
dest[j++] = SPACE;
|
||||
plen += tabwidth - size.cx;
|
||||
lasttab = wb_j + numspaces;
|
||||
}
|
||||
else
|
||||
{
|
||||
dest[j++] = str[i++];
|
||||
if (!(format & DT_NOCLIP) || !(format & DT_NOPREFIX) ||
|
||||
(format & DT_WORDBREAK))
|
||||
{
|
||||
if (!GetTextExtentPoint16(hdc, &dest[j-1], 1, &size))
|
||||
return NULL;
|
||||
plen += size.cx;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case SPACE:
|
||||
dest[j++] = str[i++];
|
||||
if (!(format & DT_NOCLIP) || !(format & DT_NOPREFIX) ||
|
||||
(format & DT_WORDBREAK))
|
||||
{
|
||||
wb_i = i;
|
||||
wb_j = j - 1;
|
||||
wb_count = *count;
|
||||
if (!GetTextExtentPoint16(hdc, &dest[j-1], 1, &size))
|
||||
return NULL;
|
||||
plen += size.cx;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
dest[j++] = str[i++];
|
||||
if (!(format & DT_NOCLIP) || !(format & DT_NOPREFIX) ||
|
||||
(format & DT_WORDBREAK))
|
||||
{
|
||||
if (!GetTextExtentPoint16(hdc, &dest[j-1], 1, &size))
|
||||
return NULL;
|
||||
plen += size.cx;
|
||||
}
|
||||
}
|
||||
|
||||
(*count)--;
|
||||
if (!(format & DT_NOCLIP) || (format & DT_WORDBREAK))
|
||||
{
|
||||
if (plen > width)
|
||||
{
|
||||
if (format & DT_WORDBREAK)
|
||||
{
|
||||
if (wb_j)
|
||||
{
|
||||
*len = wb_j;
|
||||
*count = wb_count - 1;
|
||||
return (&str[wb_i]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
*len = j;
|
||||
return (&str[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*len = j;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* DrawText16 (USER.85)
|
||||
*/
|
||||
INT16 WINAPI DrawText16( HDC16 hdc, LPCSTR str, INT16 i_count,
|
||||
LPRECT16 rect, UINT16 flags )
|
||||
{
|
||||
SIZE16 size;
|
||||
const char *strPtr;
|
||||
static char line[1024];
|
||||
int len, lh, count=i_count;
|
||||
int prefix_x = 0;
|
||||
int prefix_end = 0;
|
||||
TEXTMETRIC16 tm;
|
||||
int x = rect->left, y = rect->top;
|
||||
int width = rect->right - rect->left;
|
||||
int max_width = 0;
|
||||
|
||||
TRACE("%s, %d , [(%d,%d),(%d,%d)]\n",
|
||||
debugstr_an (str, count), count,
|
||||
rect->left, rect->top, rect->right, rect->bottom);
|
||||
|
||||
if (!str) return 0;
|
||||
if (count == -1) count = strlen(str);
|
||||
strPtr = str;
|
||||
|
||||
GetTextMetrics16(hdc, &tm);
|
||||
if (flags & DT_EXTERNALLEADING)
|
||||
lh = tm.tmHeight + tm.tmExternalLeading;
|
||||
else
|
||||
lh = tm.tmHeight;
|
||||
|
||||
if (flags & DT_TABSTOP)
|
||||
tabstop = flags >> 8;
|
||||
|
||||
if (flags & DT_EXPANDTABS)
|
||||
{
|
||||
GetTextExtentPoint16(hdc, " ", 1, &size);
|
||||
spacewidth = size.cx;
|
||||
GetTextExtentPoint16(hdc, "o", 1, &size);
|
||||
tabwidth = size.cx * tabstop;
|
||||
}
|
||||
|
||||
if (flags & DT_CALCRECT) flags |= DT_NOCLIP;
|
||||
|
||||
do
|
||||
{
|
||||
prefix_offset = -1;
|
||||
strPtr = TEXT_NextLine(hdc, strPtr, &count, line, &len, width, flags);
|
||||
|
||||
if (prefix_offset != -1)
|
||||
{
|
||||
GetTextExtentPoint16(hdc, line, prefix_offset, &size);
|
||||
prefix_x = size.cx;
|
||||
GetTextExtentPoint16(hdc, line, prefix_offset + 1, &size);
|
||||
prefix_end = size.cx - 1;
|
||||
}
|
||||
|
||||
if (!GetTextExtentPoint16(hdc, line, len, &size)) return 0;
|
||||
if (flags & DT_CENTER) x = (rect->left + rect->right -
|
||||
size.cx) / 2;
|
||||
else if (flags & DT_RIGHT) x = rect->right - size.cx;
|
||||
|
||||
if (flags & DT_SINGLELINE)
|
||||
{
|
||||
if (flags & DT_VCENTER) y = rect->top +
|
||||
(rect->bottom - rect->top) / 2 - size.cy / 2;
|
||||
else if (flags & DT_BOTTOM) y = rect->bottom - size.cy;
|
||||
}
|
||||
if (!(flags & DT_CALCRECT))
|
||||
{
|
||||
if (!ExtTextOut16(hdc, x, y, (flags & DT_NOCLIP) ? 0 : ETO_CLIPPED,
|
||||
rect, line, len, NULL )) return 0;
|
||||
if (prefix_offset != -1)
|
||||
{
|
||||
HPEN hpen = CreatePen( PS_SOLID, 1, GetTextColor(hdc) );
|
||||
HPEN oldPen = SelectObject( hdc, hpen );
|
||||
MoveTo16(hdc, x + prefix_x, y + tm.tmAscent + 1 );
|
||||
LineTo(hdc, x + prefix_end + 1, y + tm.tmAscent + 1 );
|
||||
SelectObject( hdc, oldPen );
|
||||
DeleteObject( hpen );
|
||||
}
|
||||
}
|
||||
else if (size.cx > max_width)
|
||||
max_width = size.cx;
|
||||
|
||||
y += lh;
|
||||
if (strPtr)
|
||||
{
|
||||
if (!(flags & DT_NOCLIP))
|
||||
{
|
||||
if (y > rect->bottom - lh)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
while (strPtr);
|
||||
if (flags & DT_CALCRECT)
|
||||
{
|
||||
rect->right = rect->left + max_width;
|
||||
rect->bottom = y;
|
||||
}
|
||||
return y - rect->top;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* DrawTextA (USER32.164)
|
||||
*/
|
||||
INT WINAPI DrawTextA( HDC hdc, LPCSTR str, INT count,
|
||||
LPRECT rect, UINT flags )
|
||||
{
|
||||
RECT16 rect16;
|
||||
INT16 ret;
|
||||
|
||||
if (!rect)
|
||||
return DrawText16( (HDC16)hdc, str, (INT16)count, NULL, (UINT16)flags);
|
||||
CONV_RECT32TO16( rect, &rect16 );
|
||||
ret = DrawText16( (HDC16)hdc, str, (INT16)count, &rect16, (UINT16)flags );
|
||||
CONV_RECT16TO32( &rect16, rect );
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* DrawTextW (USER32.167)
|
||||
*/
|
||||
INT WINAPI DrawTextW( HDC hdc, LPCWSTR str, INT count,
|
||||
LPRECT rect, UINT flags )
|
||||
{
|
||||
LPSTR p;
|
||||
INT acount;
|
||||
INT ret;
|
||||
UINT codepage = CP_ACP; /* FIXME: get codepage of font charset */
|
||||
|
||||
acount = WideCharToMultiByte(codepage,0,str,count,NULL,0,NULL,NULL);
|
||||
p = HeapAlloc( GetProcessHeap(), 0, acount );
|
||||
acount = WideCharToMultiByte(codepage,0,str,count,p,acount,NULL,NULL);
|
||||
if (count == -1) acount = -1;
|
||||
ret = DrawTextA( hdc, p, acount, rect, flags );
|
||||
|
||||
HeapFree( GetProcessHeap(), 0, p );
|
||||
return ret;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* DrawTextExA (USER32.165)
|
||||
*/
|
||||
INT WINAPI DrawTextExA( HDC hdc, LPCSTR str, INT count,
|
||||
LPRECT rect, UINT flags, LPDRAWTEXTPARAMS dtp )
|
||||
{
|
||||
TRACE("(%d,'%s',%d,%p,0x%08x,%p)\n",hdc,str,count,rect,flags,dtp);
|
||||
if(dtp) {
|
||||
FIXME("Ignores params:%d,%d,%d,%d\n",dtp->cbSize,
|
||||
dtp->iTabLength,dtp->iLeftMargin,dtp->iRightMargin);
|
||||
}
|
||||
return DrawTextA(hdc,str,count,rect,flags);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* DrawTextExW (USER32.166)
|
||||
*/
|
||||
INT WINAPI DrawTextExW( HDC hdc, LPCWSTR str, INT count,
|
||||
LPRECT rect, UINT flags, LPDRAWTEXTPARAMS dtp )
|
||||
{
|
||||
TRACE("(%d,%p,%d,%p,0x%08x,%p)\n",hdc,str,count,rect,flags,dtp);
|
||||
FIXME("ignores extended functionality\n");
|
||||
return DrawTextW(hdc,str,count,rect,flags);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* ExtTextOut16 (GDI.351)
|
||||
@ -462,314 +125,6 @@ BOOL WINAPI TextOutW(HDC hdc, INT x, INT y, LPCWSTR str, INT count)
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* TEXT_GrayString
|
||||
*
|
||||
* FIXME: The call to 16-bit code only works because the wine GDI is a 16-bit
|
||||
* heap and we can guarantee that the handles fit in an INT16. We have to
|
||||
* rethink the strategy once the migration to NT handles is complete.
|
||||
* We are going to get a lot of code-duplication once this migration is
|
||||
* completed...
|
||||
*
|
||||
*/
|
||||
static BOOL TEXT_GrayString(HDC hdc, HBRUSH hb,
|
||||
GRAYSTRINGPROC fn, LPARAM lp, INT len,
|
||||
INT x, INT y, INT cx, INT cy,
|
||||
BOOL unicode, BOOL _32bit)
|
||||
{
|
||||
HBITMAP hbm, hbmsave;
|
||||
HBRUSH hbsave;
|
||||
HFONT hfsave;
|
||||
HDC memdc = CreateCompatibleDC(hdc);
|
||||
int slen = len;
|
||||
BOOL retval = TRUE;
|
||||
COLORREF fg, bg;
|
||||
|
||||
if(!hdc) return FALSE;
|
||||
|
||||
if(len == 0)
|
||||
{
|
||||
if(unicode)
|
||||
slen = lstrlenW((LPCWSTR)lp);
|
||||
else if(_32bit)
|
||||
slen = lstrlenA((LPCSTR)lp);
|
||||
else
|
||||
slen = lstrlenA((LPCSTR)PTR_SEG_TO_LIN(lp));
|
||||
}
|
||||
|
||||
if((cx == 0 || cy == 0) && slen != -1)
|
||||
{
|
||||
SIZE s;
|
||||
if(unicode)
|
||||
GetTextExtentPoint32W(hdc, (LPCWSTR)lp, slen, &s);
|
||||
else if(_32bit)
|
||||
GetTextExtentPoint32A(hdc, (LPCSTR)lp, slen, &s);
|
||||
else
|
||||
GetTextExtentPoint32A(hdc, (LPCSTR)PTR_SEG_TO_LIN(lp), slen, &s);
|
||||
if(cx == 0) cx = s.cx;
|
||||
if(cy == 0) cy = s.cy;
|
||||
}
|
||||
|
||||
hbm = CreateBitmap(cx, cy, 1, 1, NULL);
|
||||
hbmsave = (HBITMAP)SelectObject(memdc, hbm);
|
||||
hbsave = SelectObject( memdc, GetStockObject(BLACK_BRUSH) );
|
||||
PatBlt( memdc, 0, 0, cx, cy, PATCOPY );
|
||||
SelectObject( memdc, hbsave );
|
||||
SetTextColor(memdc, RGB(255, 255, 255));
|
||||
SetBkColor(memdc, RGB(0, 0, 0));
|
||||
hfsave = (HFONT)SelectObject(memdc, GetCurrentObject(hdc, OBJ_FONT));
|
||||
|
||||
if(fn)
|
||||
if(_32bit)
|
||||
retval = fn(memdc, lp, slen);
|
||||
else
|
||||
retval = (BOOL)((BOOL16)((GRAYSTRINGPROC16)fn)((HDC16)memdc, lp, (INT16)slen));
|
||||
else
|
||||
if(unicode)
|
||||
TextOutW(memdc, 0, 0, (LPCWSTR)lp, slen);
|
||||
else if(_32bit)
|
||||
TextOutA(memdc, 0, 0, (LPCSTR)lp, slen);
|
||||
else
|
||||
TextOutA(memdc, 0, 0, (LPCSTR)PTR_SEG_TO_LIN(lp), slen);
|
||||
|
||||
SelectObject(memdc, hfsave);
|
||||
|
||||
/*
|
||||
* Windows doc says that the bitmap isn't grayed when len == -1 and
|
||||
* the callback function returns FALSE. However, testing this on
|
||||
* win95 showed otherwise...
|
||||
*/
|
||||
#ifdef GRAYSTRING_USING_DOCUMENTED_BEHAVIOUR
|
||||
if(retval || len != -1)
|
||||
#endif
|
||||
{
|
||||
hbsave = (HBRUSH)SelectObject(memdc, CACHE_GetPattern55AABrush());
|
||||
PatBlt(memdc, 0, 0, cx, cy, 0x000A0329);
|
||||
SelectObject(memdc, hbsave);
|
||||
}
|
||||
|
||||
if(hb) hbsave = (HBRUSH)SelectObject(hdc, hb);
|
||||
fg = SetTextColor(hdc, RGB(0, 0, 0));
|
||||
bg = SetBkColor(hdc, RGB(255, 255, 255));
|
||||
BitBlt(hdc, x, y, cx, cy, memdc, 0, 0, 0x00E20746);
|
||||
SetTextColor(hdc, fg);
|
||||
SetBkColor(hdc, bg);
|
||||
if(hb) SelectObject(hdc, hbsave);
|
||||
|
||||
SelectObject(memdc, hbmsave);
|
||||
DeleteObject(hbm);
|
||||
DeleteDC(memdc);
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* GrayString16 (USER.185)
|
||||
*/
|
||||
BOOL16 WINAPI GrayString16( HDC16 hdc, HBRUSH16 hbr, GRAYSTRINGPROC16 gsprc,
|
||||
LPARAM lParam, INT16 cch, INT16 x, INT16 y,
|
||||
INT16 cx, INT16 cy )
|
||||
{
|
||||
return TEXT_GrayString(hdc, hbr, (GRAYSTRINGPROC)gsprc, lParam, cch, x, y, cx, cy, FALSE, FALSE);
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* GrayStringA (USER32.315)
|
||||
*/
|
||||
BOOL WINAPI GrayStringA( HDC hdc, HBRUSH hbr, GRAYSTRINGPROC gsprc,
|
||||
LPARAM lParam, INT cch, INT x, INT y,
|
||||
INT cx, INT cy )
|
||||
{
|
||||
return TEXT_GrayString(hdc, hbr, gsprc, lParam, cch, x, y, cx, cy, FALSE, TRUE);
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* GrayStringW (USER32.316)
|
||||
*/
|
||||
BOOL WINAPI GrayStringW( HDC hdc, HBRUSH hbr, GRAYSTRINGPROC gsprc,
|
||||
LPARAM lParam, INT cch, INT x, INT y,
|
||||
INT cx, INT cy )
|
||||
{
|
||||
return TEXT_GrayString(hdc, hbr, gsprc, lParam, cch, x, y, cx, cy, TRUE, TRUE);
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* TEXT_TabbedTextOut
|
||||
*
|
||||
* Helper function for TabbedTextOut() and GetTabbedTextExtent().
|
||||
* Note: this doesn't work too well for text-alignment modes other
|
||||
* than TA_LEFT|TA_TOP. But we want bug-for-bug compatibility :-)
|
||||
*/
|
||||
LONG TEXT_TabbedTextOut( HDC hdc, INT x, INT y, LPCSTR lpstr,
|
||||
INT count, INT cTabStops, const INT16 *lpTabPos16,
|
||||
const INT *lpTabPos32, INT nTabOrg,
|
||||
BOOL fDisplayText )
|
||||
{
|
||||
INT defWidth;
|
||||
DWORD extent = 0;
|
||||
int i, tabPos = x;
|
||||
int start = x;
|
||||
|
||||
if (cTabStops == 1)
|
||||
{
|
||||
defWidth = lpTabPos32 ? *lpTabPos32 : *lpTabPos16;
|
||||
cTabStops = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
TEXTMETRIC16 tm;
|
||||
GetTextMetrics16( hdc, &tm );
|
||||
defWidth = 8 * tm.tmAveCharWidth;
|
||||
}
|
||||
|
||||
while (count > 0)
|
||||
{
|
||||
for (i = 0; i < count; i++)
|
||||
if (lpstr[i] == '\t') break;
|
||||
extent = GetTextExtent16( hdc, lpstr, i );
|
||||
if (lpTabPos32)
|
||||
{
|
||||
while ((cTabStops > 0) &&
|
||||
(nTabOrg + *lpTabPos32 <= x + LOWORD(extent)))
|
||||
{
|
||||
lpTabPos32++;
|
||||
cTabStops--;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
while ((cTabStops > 0) &&
|
||||
(nTabOrg + *lpTabPos16 <= x + LOWORD(extent)))
|
||||
{
|
||||
lpTabPos16++;
|
||||
cTabStops--;
|
||||
}
|
||||
}
|
||||
if (i == count)
|
||||
tabPos = x + LOWORD(extent);
|
||||
else if (cTabStops > 0)
|
||||
tabPos = nTabOrg + (lpTabPos32 ? *lpTabPos32 : *lpTabPos16);
|
||||
else
|
||||
tabPos = nTabOrg + ((x + LOWORD(extent) - nTabOrg) / defWidth + 1) * defWidth;
|
||||
if (fDisplayText)
|
||||
{
|
||||
RECT r;
|
||||
r.left = x;
|
||||
r.top = y;
|
||||
r.right = tabPos;
|
||||
r.bottom = y + HIWORD(extent);
|
||||
ExtTextOutA( hdc, x, y,
|
||||
GetBkMode(hdc) == OPAQUE ? ETO_OPAQUE : 0,
|
||||
&r, lpstr, i, NULL );
|
||||
}
|
||||
x = tabPos;
|
||||
count -= i+1;
|
||||
lpstr += i+1;
|
||||
}
|
||||
return MAKELONG(tabPos - start, HIWORD(extent));
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* TabbedTextOut16 (USER.196)
|
||||
*/
|
||||
LONG WINAPI TabbedTextOut16( HDC16 hdc, INT16 x, INT16 y, LPCSTR lpstr,
|
||||
INT16 count, INT16 cTabStops,
|
||||
const INT16 *lpTabPos, INT16 nTabOrg )
|
||||
{
|
||||
TRACE("%04x %d,%d '%.*s' %d\n",
|
||||
hdc, x, y, count, lpstr, count );
|
||||
return TEXT_TabbedTextOut( hdc, x, y, lpstr, count, cTabStops,
|
||||
lpTabPos, NULL, nTabOrg, TRUE );
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* TabbedTextOutA (USER32.542)
|
||||
*/
|
||||
LONG WINAPI TabbedTextOutA( HDC hdc, INT x, INT y, LPCSTR lpstr,
|
||||
INT count, INT cTabStops,
|
||||
const INT *lpTabPos, INT nTabOrg )
|
||||
{
|
||||
TRACE("%04x %d,%d '%.*s' %d\n",
|
||||
hdc, x, y, count, lpstr, count );
|
||||
return TEXT_TabbedTextOut( hdc, x, y, lpstr, count, cTabStops,
|
||||
NULL, lpTabPos, nTabOrg, TRUE );
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* TabbedTextOutW (USER32.543)
|
||||
*/
|
||||
LONG WINAPI TabbedTextOutW( HDC hdc, INT x, INT y, LPCWSTR str,
|
||||
INT count, INT cTabStops,
|
||||
const INT *lpTabPos, INT nTabOrg )
|
||||
{
|
||||
LONG ret;
|
||||
LPSTR p;
|
||||
INT acount;
|
||||
UINT codepage = CP_ACP; /* FIXME: get codepage of font charset */
|
||||
|
||||
acount = WideCharToMultiByte(codepage,0,str,count,NULL,0,NULL,NULL);
|
||||
p = HeapAlloc( GetProcessHeap(), 0, acount );
|
||||
if(p == NULL) return 0; /* FIXME: is this the correct return on failure */
|
||||
acount = WideCharToMultiByte(codepage,0,str,count,p,acount,NULL,NULL);
|
||||
ret = TabbedTextOutA( hdc, x, y, p, acount, cTabStops,
|
||||
lpTabPos, nTabOrg );
|
||||
HeapFree( GetProcessHeap(), 0, p );
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* GetTabbedTextExtent16 (USER.197)
|
||||
*/
|
||||
DWORD WINAPI GetTabbedTextExtent16( HDC16 hdc, LPCSTR lpstr, INT16 count,
|
||||
INT16 cTabStops, const INT16 *lpTabPos )
|
||||
{
|
||||
TRACE("%04x '%.*s' %d\n",
|
||||
hdc, count, lpstr, count );
|
||||
return TEXT_TabbedTextOut( hdc, 0, 0, lpstr, count, cTabStops,
|
||||
lpTabPos, NULL, 0, FALSE );
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* GetTabbedTextExtentA (USER32.293)
|
||||
*/
|
||||
DWORD WINAPI GetTabbedTextExtentA( HDC hdc, LPCSTR lpstr, INT count,
|
||||
INT cTabStops, const INT *lpTabPos )
|
||||
{
|
||||
TRACE("%04x '%.*s' %d\n",
|
||||
hdc, count, lpstr, count );
|
||||
return TEXT_TabbedTextOut( hdc, 0, 0, lpstr, count, cTabStops,
|
||||
NULL, lpTabPos, 0, FALSE );
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* GetTabbedTextExtentW (USER32.294)
|
||||
*/
|
||||
DWORD WINAPI GetTabbedTextExtentW( HDC hdc, LPCWSTR lpstr, INT count,
|
||||
INT cTabStops, const INT *lpTabPos )
|
||||
{
|
||||
LONG ret;
|
||||
LPSTR p;
|
||||
INT acount;
|
||||
UINT codepage = CP_ACP; /* FIXME: get codepage of font charset */
|
||||
|
||||
acount = WideCharToMultiByte(codepage,0,lpstr,count,NULL,0,NULL,NULL);
|
||||
p = HeapAlloc( GetProcessHeap(), 0, acount );
|
||||
if(p == NULL) return 0; /* FIXME: is this the correct failure value? */
|
||||
acount = WideCharToMultiByte(codepage,0,lpstr,count,p,acount,NULL,NULL);
|
||||
ret = GetTabbedTextExtentA( hdc, p, acount, cTabStops, lpTabPos );
|
||||
HeapFree( GetProcessHeap(), 0, p );
|
||||
return ret;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* GetTextCharset [GDI32.226] Gets character set for font in DC
|
||||
*
|
||||
|
@ -28,8 +28,6 @@
|
||||
#include "stackframe.h"
|
||||
#include "builtin16.h"
|
||||
#include "debugtools.h"
|
||||
#include "queue.h"
|
||||
#include "hook.h"
|
||||
#include "winnls.h"
|
||||
|
||||
DEFAULT_DEBUG_CHANNEL(thread);
|
||||
@ -359,32 +357,6 @@ void WINAPI ExitThread( DWORD code ) /* [in] Exit code for this thread */
|
||||
}
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
* SetLastErrorEx [USER32.485] Sets the last-error code.
|
||||
*
|
||||
* RETURNS
|
||||
* None.
|
||||
*/
|
||||
void WINAPI SetLastErrorEx(
|
||||
DWORD error, /* [in] Per-thread error code */
|
||||
DWORD type) /* [in] Error type */
|
||||
{
|
||||
TRACE("(0x%08lx, 0x%08lx)\n", error,type);
|
||||
switch(type) {
|
||||
case 0:
|
||||
break;
|
||||
case SLE_ERROR:
|
||||
case SLE_MINORERROR:
|
||||
case SLE_WARNING:
|
||||
/* Fall through for now */
|
||||
default:
|
||||
FIXME("(error=%08lx, type=%08lx): Unhandled type\n", error,type);
|
||||
break;
|
||||
}
|
||||
SetLastError( error );
|
||||
}
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
* TlsAlloc [KERNEL32.530] Allocates a TLS index.
|
||||
*
|
||||
@ -747,95 +719,6 @@ BOOL WINAPI GetThreadTimes(
|
||||
}
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
* AttachThreadInput [KERNEL32.8] Attaches input of 1 thread to other
|
||||
*
|
||||
* Attaches the input processing mechanism of one thread to that of
|
||||
* another thread.
|
||||
*
|
||||
* RETURNS
|
||||
* Success: TRUE
|
||||
* Failure: FALSE
|
||||
*
|
||||
* TODO:
|
||||
* 1. Reset the Key State (currenly per thread key state is not maintained)
|
||||
*/
|
||||
BOOL WINAPI AttachThreadInput(
|
||||
DWORD idAttach, /* [in] Thread to attach */
|
||||
DWORD idAttachTo, /* [in] Thread to attach to */
|
||||
BOOL fAttach) /* [in] Attach or detach */
|
||||
{
|
||||
#if 0 /* FIXME: cannot call USER functions here */
|
||||
MESSAGEQUEUE *pSrcMsgQ = 0, *pTgtMsgQ = 0;
|
||||
BOOL16 bRet = 0;
|
||||
|
||||
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||
|
||||
/* A thread cannot attach to itself */
|
||||
if ( idAttach == idAttachTo )
|
||||
goto CLEANUP;
|
||||
|
||||
/* According to the docs this method should fail if a
|
||||
* "Journal record" hook is installed. (attaches all input queues together)
|
||||
*/
|
||||
if ( HOOK_IsHooked( WH_JOURNALRECORD ) )
|
||||
goto CLEANUP;
|
||||
|
||||
/* Retrieve message queues corresponding to the thread id's */
|
||||
pTgtMsgQ = (MESSAGEQUEUE *)QUEUE_Lock( GetThreadQueue16( idAttach ) );
|
||||
pSrcMsgQ = (MESSAGEQUEUE *)QUEUE_Lock( GetThreadQueue16( idAttachTo ) );
|
||||
|
||||
/* Ensure we have message queues and that Src and Tgt threads
|
||||
* are not system threads.
|
||||
*/
|
||||
if ( !pSrcMsgQ || !pTgtMsgQ || !pSrcMsgQ->pQData || !pTgtMsgQ->pQData )
|
||||
goto CLEANUP;
|
||||
|
||||
if (fAttach) /* Attach threads */
|
||||
{
|
||||
/* Only attach if currently detached */
|
||||
if ( pTgtMsgQ->pQData != pSrcMsgQ->pQData )
|
||||
{
|
||||
/* First release the target threads perQData */
|
||||
PERQDATA_Release( pTgtMsgQ->pQData );
|
||||
|
||||
/* Share a reference to the source threads perQDATA */
|
||||
PERQDATA_Addref( pSrcMsgQ->pQData );
|
||||
pTgtMsgQ->pQData = pSrcMsgQ->pQData;
|
||||
}
|
||||
}
|
||||
else /* Detach threads */
|
||||
{
|
||||
/* Only detach if currently attached */
|
||||
if ( pTgtMsgQ->pQData == pSrcMsgQ->pQData )
|
||||
{
|
||||
/* First release the target threads perQData */
|
||||
PERQDATA_Release( pTgtMsgQ->pQData );
|
||||
|
||||
/* Give the target thread its own private perQDATA once more */
|
||||
pTgtMsgQ->pQData = PERQDATA_CreateInstance();
|
||||
}
|
||||
}
|
||||
|
||||
/* TODO: Reset the Key State */
|
||||
|
||||
bRet = 1; /* Success */
|
||||
|
||||
CLEANUP:
|
||||
|
||||
/* Unlock the queues before returning */
|
||||
if ( pSrcMsgQ )
|
||||
QUEUE_Unlock( pSrcMsgQ );
|
||||
if ( pTgtMsgQ )
|
||||
QUEUE_Unlock( pTgtMsgQ );
|
||||
|
||||
return bRet;
|
||||
#endif
|
||||
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||
FIXME( "broken for now\n" );
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
* VWin32_BoostThreadGroup [KERNEL.535]
|
||||
*/
|
||||
|
@ -14,7 +14,6 @@ C_SRCS = \
|
||||
init.c \
|
||||
kernel32.c \
|
||||
newfns.c \
|
||||
ordinals.c \
|
||||
process.c \
|
||||
struct32.c \
|
||||
time.c
|
||||
|
137
win32/newfns.c
137
win32/newfns.c
@ -226,56 +226,6 @@ DWORD WINAPI GetCompressedFileSizeW(
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* GetProcessWindowStation [USER32.280] Returns handle of window station
|
||||
*
|
||||
* NOTES
|
||||
* Docs say the return value is HWINSTA
|
||||
*
|
||||
* RETURNS
|
||||
* Success: Handle to window station associated with calling process
|
||||
* Failure: NULL
|
||||
*/
|
||||
DWORD WINAPI GetProcessWindowStation(void)
|
||||
{
|
||||
FIXME("(void): stub\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* GetThreadDesktop [USER32.295] Returns handle to desktop
|
||||
*
|
||||
* NOTES
|
||||
* Docs say the return value is HDESK
|
||||
*
|
||||
* PARAMS
|
||||
* dwThreadId [I] Thread identifier
|
||||
*
|
||||
* RETURNS
|
||||
* Success: Handle to desktop associated with specified thread
|
||||
* Failure: NULL
|
||||
*/
|
||||
DWORD WINAPI GetThreadDesktop( DWORD dwThreadId )
|
||||
{
|
||||
FIXME("(%lx): stub\n",dwThreadId);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* SetDebugErrorLevel [USER32.475]
|
||||
* Sets the minimum error level for generating debugging events
|
||||
*
|
||||
* PARAMS
|
||||
* dwLevel [I] Debugging error level
|
||||
*/
|
||||
VOID WINAPI SetDebugErrorLevel( DWORD dwLevel )
|
||||
{
|
||||
FIXME("(%ld): stub\n", dwLevel);
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* SetComputerNameA [KERNEL32.621]
|
||||
*/
|
||||
@ -310,44 +260,6 @@ BOOL WINAPI EnumPortsA(LPSTR name,DWORD level,LPBYTE ports,DWORD bufsize,LPDWORD
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* OpenDesktopA [USER32.408]
|
||||
*
|
||||
* NOTES
|
||||
* Return type should be HDESK
|
||||
*
|
||||
* Not supported on Win9x - returns NULL and calls SetLastError.
|
||||
*/
|
||||
HANDLE WINAPI OpenDesktopA( LPCSTR lpszDesktop, DWORD dwFlags,
|
||||
BOOL fInherit, DWORD dwDesiredAccess )
|
||||
{
|
||||
FIXME("(%s,%lx,%i,%lx): stub\n",debugstr_a(lpszDesktop),dwFlags,
|
||||
fInherit,dwDesiredAccess);
|
||||
|
||||
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* SetUserObjectInformationA
|
||||
*/
|
||||
BOOL WINAPI SetUserObjectInformationA( HANDLE hObj, INT nIndex,
|
||||
LPVOID pvInfo, DWORD nLength )
|
||||
{
|
||||
FIXME("(%x,%d,%p,%lx): stub\n",hObj,nIndex,pvInfo,nLength);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* SetThreadDesktop
|
||||
*/
|
||||
BOOL WINAPI SetThreadDesktop( HANDLE hDesktop )
|
||||
{
|
||||
FIXME("(%x): stub\n",hDesktop);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* CreateIoCompletionPort
|
||||
*/
|
||||
@ -358,52 +270,3 @@ DWORD dwNumberOfConcurrentThreads)
|
||||
FIXME("(%04x, %04x, %08lx, %08lx): stub.\n", hFileHandle, hExistingCompletionPort, dwCompletionKey, dwNumberOfConcurrentThreads);
|
||||
return (HANDLE)NULL;
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* GetProcessDefaultLayout [USER32.802]
|
||||
*
|
||||
* Gets the default layout for parentless windows.
|
||||
* Right now, just returns 0 (left-to-right).
|
||||
*
|
||||
* RETURNS
|
||||
* Success: Nonzero
|
||||
* Failure: Zero
|
||||
*
|
||||
* BUGS
|
||||
* No RTL
|
||||
*/
|
||||
BOOL WINAPI GetProcessDefaultLayout( DWORD *pdwDefaultLayout )
|
||||
{
|
||||
if ( !pdwDefaultLayout ) {
|
||||
SetLastError( ERROR_INVALID_PARAMETER );
|
||||
return FALSE;
|
||||
}
|
||||
FIXME( "( %p ): No BiDi\n", pdwDefaultLayout );
|
||||
*pdwDefaultLayout = 0;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* SetProcessDefaultLayout [USER32.803]
|
||||
*
|
||||
* Sets the default layout for parentless windows.
|
||||
* Right now, only accepts 0 (left-to-right).
|
||||
*
|
||||
* RETURNS
|
||||
* Success: Nonzero
|
||||
* Failure: Zero
|
||||
*
|
||||
* BUGS
|
||||
* No RTL
|
||||
*/
|
||||
BOOL WINAPI SetProcessDefaultLayout( DWORD dwDefaultLayout )
|
||||
{
|
||||
if ( dwDefaultLayout == 0 )
|
||||
return TRUE;
|
||||
FIXME( "( %08lx ): No BiDi\n", dwDefaultLayout );
|
||||
SetLastError( ERROR_CALL_NOT_IMPLEMENTED );
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
@ -1,45 +0,0 @@
|
||||
/*
|
||||
* Win32 ordinal only exported functions that can't be stuffed somehwere else.
|
||||
*
|
||||
* Copyright 1997 Marcus Meissner
|
||||
*/
|
||||
|
||||
#include "thread.h"
|
||||
#include "winerror.h"
|
||||
#include "heap.h"
|
||||
#include "selectors.h"
|
||||
#include "miscemu.h"
|
||||
#include "winnt.h"
|
||||
#include "process.h"
|
||||
#include "module.h"
|
||||
#include "task.h"
|
||||
#include "callback.h"
|
||||
#include "stackframe.h"
|
||||
#include "debugtools.h"
|
||||
|
||||
DECLARE_DEBUG_CHANNEL(win);
|
||||
|
||||
/***********************************************************************
|
||||
* RegisterShellHookWindow [USER32.459]
|
||||
*/
|
||||
HRESULT WINAPI RegisterShellHookWindow ( DWORD u )
|
||||
{ FIXME_(win)("0x%08lx stub\n",u);
|
||||
return 0;
|
||||
|
||||
}
|
||||
/***********************************************************************
|
||||
* DeregisterShellHookWindow [USER32.132]
|
||||
*/
|
||||
HRESULT WINAPI DeregisterShellHookWindow ( DWORD u )
|
||||
{ FIXME_(win)("0x%08lx stub\n",u);
|
||||
return 0;
|
||||
|
||||
}
|
||||
/***********************************************************************
|
||||
* RegisterTaskList [USER23.436]
|
||||
*/
|
||||
DWORD WINAPI RegisterTaskList (DWORD x)
|
||||
{ FIXME_(win)("0x%08lx\n",x);
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include <assert.h>
|
||||
#include "windef.h"
|
||||
#include "wingdi.h"
|
||||
#include "winerror.h"
|
||||
#include "wine/winbase16.h"
|
||||
#include "wine/winuser16.h"
|
||||
#include "miscemu.h"
|
||||
@ -1660,3 +1661,88 @@ LONG WINAPI GetMessageExtraInfo(void)
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
* AttachThreadInput [USER32.8] Attaches input of 1 thread to other
|
||||
*
|
||||
* Attaches the input processing mechanism of one thread to that of
|
||||
* another thread.
|
||||
*
|
||||
* RETURNS
|
||||
* Success: TRUE
|
||||
* Failure: FALSE
|
||||
*
|
||||
* TODO:
|
||||
* 1. Reset the Key State (currenly per thread key state is not maintained)
|
||||
*/
|
||||
BOOL WINAPI AttachThreadInput(
|
||||
DWORD idAttach, /* [in] Thread to attach */
|
||||
DWORD idAttachTo, /* [in] Thread to attach to */
|
||||
BOOL fAttach) /* [in] Attach or detach */
|
||||
{
|
||||
MESSAGEQUEUE *pSrcMsgQ = 0, *pTgtMsgQ = 0;
|
||||
BOOL16 bRet = 0;
|
||||
|
||||
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||
|
||||
/* A thread cannot attach to itself */
|
||||
if ( idAttach == idAttachTo )
|
||||
goto CLEANUP;
|
||||
|
||||
/* According to the docs this method should fail if a
|
||||
* "Journal record" hook is installed. (attaches all input queues together)
|
||||
*/
|
||||
if ( HOOK_IsHooked( WH_JOURNALRECORD ) )
|
||||
goto CLEANUP;
|
||||
|
||||
/* Retrieve message queues corresponding to the thread id's */
|
||||
pTgtMsgQ = (MESSAGEQUEUE *)QUEUE_Lock( GetThreadQueue16( idAttach ) );
|
||||
pSrcMsgQ = (MESSAGEQUEUE *)QUEUE_Lock( GetThreadQueue16( idAttachTo ) );
|
||||
|
||||
/* Ensure we have message queues and that Src and Tgt threads
|
||||
* are not system threads.
|
||||
*/
|
||||
if ( !pSrcMsgQ || !pTgtMsgQ || !pSrcMsgQ->pQData || !pTgtMsgQ->pQData )
|
||||
goto CLEANUP;
|
||||
|
||||
if (fAttach) /* Attach threads */
|
||||
{
|
||||
/* Only attach if currently detached */
|
||||
if ( pTgtMsgQ->pQData != pSrcMsgQ->pQData )
|
||||
{
|
||||
/* First release the target threads perQData */
|
||||
PERQDATA_Release( pTgtMsgQ->pQData );
|
||||
|
||||
/* Share a reference to the source threads perQDATA */
|
||||
PERQDATA_Addref( pSrcMsgQ->pQData );
|
||||
pTgtMsgQ->pQData = pSrcMsgQ->pQData;
|
||||
}
|
||||
}
|
||||
else /* Detach threads */
|
||||
{
|
||||
/* Only detach if currently attached */
|
||||
if ( pTgtMsgQ->pQData == pSrcMsgQ->pQData )
|
||||
{
|
||||
/* First release the target threads perQData */
|
||||
PERQDATA_Release( pTgtMsgQ->pQData );
|
||||
|
||||
/* Give the target thread its own private perQDATA once more */
|
||||
pTgtMsgQ->pQData = PERQDATA_CreateInstance();
|
||||
}
|
||||
}
|
||||
|
||||
/* TODO: Reset the Key State */
|
||||
|
||||
bRet = 1; /* Success */
|
||||
|
||||
CLEANUP:
|
||||
|
||||
/* Unlock the queues before returning */
|
||||
if ( pSrcMsgQ )
|
||||
QUEUE_Unlock( pSrcMsgQ );
|
||||
if ( pTgtMsgQ )
|
||||
QUEUE_Unlock( pTgtMsgQ );
|
||||
|
||||
return bRet;
|
||||
}
|
||||
|
@ -279,7 +279,7 @@ rc.left, rc.top, rc.right, rc.bottom, (UINT16)flags );
|
||||
if( (dc = (DC *)GDI_GetObjPtr(hDC, DC_MAGIC)) )
|
||||
{
|
||||
if (dc->w.hVisRgn) {
|
||||
wnd->pDriver->pSurfaceCopy(wnd,dc,dx,dy,&rc,bUpdate);
|
||||
wnd->pDriver->pSurfaceCopy(wnd,hDC,dx,dy,&rc,bUpdate);
|
||||
|
||||
if( bUpdate )
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user