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
|
7 register VxDCall6(long) VxDCall
|
||||||
8 register VxDCall7(long) VxDCall
|
8 register VxDCall7(long) VxDCall
|
||||||
9 register VxDCall8(long) VxDCall
|
9 register VxDCall8(long) VxDCall
|
||||||
10 stdcall k32CharToOemA(str str) CharToOemA
|
10 forward k32CharToOemA user32.CharToOemA
|
||||||
11 stdcall k32CharToOemBuffA(str str long) CharToOemBuffA
|
11 forward k32CharToOemBuffA user32.CharToOemBuffA
|
||||||
12 stdcall k32OemToCharA(ptr ptr) OemToCharA
|
12 forward k32OemToCharA user32.OemToCharA
|
||||||
13 stdcall k32OemToCharBuffA(ptr ptr long) OemToCharBuffA
|
13 forward k32OemToCharBuffA user32.OemToCharBuffA
|
||||||
14 stdcall k32LoadStringA(long long ptr long) LoadStringA
|
14 forward k32LoadStringA user32.LoadStringA
|
||||||
15 varargs k32wsprintfA(str str) wsprintfA
|
15 forward k32wsprintfA user32.wsprintfA
|
||||||
16 stdcall k32wvsprintfA(ptr str ptr) wvsprintfA
|
16 forward k32wvsprintfA user32.wvsprintfA
|
||||||
17 register CommonUnimpStub() CommonUnimpStub
|
17 register CommonUnimpStub() CommonUnimpStub
|
||||||
18 stdcall GetProcessDword(long long) GetProcessDword
|
18 stdcall GetProcessDword(long long) GetProcessDword
|
||||||
19 stub ThunkTheTemplateHandle
|
19 stub ThunkTheTemplateHandle
|
||||||
|
@ -6,17 +6,22 @@ MODULE = user32
|
|||||||
SOVERSION = 1.0
|
SOVERSION = 1.0
|
||||||
WRCEXTRA = -w16 -m
|
WRCEXTRA = -w16 -m
|
||||||
ALTNAMES = user keyboard ddeml display mouse
|
ALTNAMES = user keyboard ddeml display mouse
|
||||||
IMPORTS = gdi32
|
IMPORTS = gdi32 kernel32
|
||||||
|
|
||||||
C_SRCS = \
|
C_SRCS = \
|
||||||
bidi16.c \
|
bidi16.c \
|
||||||
|
cache.c \
|
||||||
ddeml.c \
|
ddeml.c \
|
||||||
display.c \
|
display.c \
|
||||||
exticon.c \
|
exticon.c \
|
||||||
|
lstr.c \
|
||||||
|
misc.c \
|
||||||
mouse.c \
|
mouse.c \
|
||||||
network.c \
|
network.c \
|
||||||
user_main.c \
|
resource.c \
|
||||||
thunk.c
|
text.c \
|
||||||
|
thunk.c \
|
||||||
|
user_main.c
|
||||||
|
|
||||||
RC_SRCS = \
|
RC_SRCS = \
|
||||||
disp.rc \
|
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 = \
|
C_SRCS = \
|
||||||
bitblt.c \
|
bitblt.c \
|
||||||
cache.c \
|
|
||||||
dispdib.c \
|
dispdib.c \
|
||||||
driver.c \
|
driver.c \
|
||||||
env.c \
|
env.c \
|
||||||
|
@ -31,7 +31,6 @@
|
|||||||
#include "winnls.h"
|
#include "winnls.h"
|
||||||
|
|
||||||
DEFAULT_DEBUG_CHANNEL(resource);
|
DEFAULT_DEBUG_CHANNEL(resource);
|
||||||
DECLARE_DEBUG_CHANNEL(accel);
|
|
||||||
|
|
||||||
#define HRSRC_MAP_BLOCKSIZE 16
|
#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)
|
* EnumResourceTypesA (KERNEL32.90)
|
||||||
*/
|
*/
|
||||||
|
180
misc/lstr.c
180
misc/lstr.c
@ -30,11 +30,8 @@
|
|||||||
#include "wine/winuser16.h"
|
#include "wine/winuser16.h"
|
||||||
#include "wine/unicode.h"
|
#include "wine/unicode.h"
|
||||||
#include "winnls.h"
|
#include "winnls.h"
|
||||||
#include "task.h"
|
|
||||||
#include "heap.h"
|
#include "heap.h"
|
||||||
#include "ldt.h"
|
#include "ldt.h"
|
||||||
#include "stackframe.h"
|
|
||||||
#include "module.h"
|
|
||||||
#include "debugtools.h"
|
#include "debugtools.h"
|
||||||
|
|
||||||
DEFAULT_DEBUG_CHANNEL(resource);
|
DEFAULT_DEBUG_CHANNEL(resource);
|
||||||
@ -462,180 +459,3 @@ BOOL WINAPI IsCharUpperW(WCHAR x)
|
|||||||
{
|
{
|
||||||
return iswupper(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
|
* 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
|
* 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 "gdi.h"
|
||||||
#include "heap.h"
|
#include "heap.h"
|
||||||
#include "debugtools.h"
|
#include "debugtools.h"
|
||||||
#include "cache.h"
|
|
||||||
#include "winnls.h"
|
#include "winnls.h"
|
||||||
|
|
||||||
DEFAULT_DEBUG_CHANNEL(text);
|
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)
|
* 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
|
* GetTextCharset [GDI32.226] Gets character set for font in DC
|
||||||
*
|
*
|
||||||
|
@ -28,8 +28,6 @@
|
|||||||
#include "stackframe.h"
|
#include "stackframe.h"
|
||||||
#include "builtin16.h"
|
#include "builtin16.h"
|
||||||
#include "debugtools.h"
|
#include "debugtools.h"
|
||||||
#include "queue.h"
|
|
||||||
#include "hook.h"
|
|
||||||
#include "winnls.h"
|
#include "winnls.h"
|
||||||
|
|
||||||
DEFAULT_DEBUG_CHANNEL(thread);
|
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.
|
* 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]
|
* VWin32_BoostThreadGroup [KERNEL.535]
|
||||||
*/
|
*/
|
||||||
|
@ -14,7 +14,6 @@ C_SRCS = \
|
|||||||
init.c \
|
init.c \
|
||||||
kernel32.c \
|
kernel32.c \
|
||||||
newfns.c \
|
newfns.c \
|
||||||
ordinals.c \
|
|
||||||
process.c \
|
process.c \
|
||||||
struct32.c \
|
struct32.c \
|
||||||
time.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]
|
* SetComputerNameA [KERNEL32.621]
|
||||||
*/
|
*/
|
||||||
@ -310,44 +260,6 @@ BOOL WINAPI EnumPortsA(LPSTR name,DWORD level,LPBYTE ports,DWORD bufsize,LPDWORD
|
|||||||
return FALSE;
|
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
|
* CreateIoCompletionPort
|
||||||
*/
|
*/
|
||||||
@ -358,52 +270,3 @@ DWORD dwNumberOfConcurrentThreads)
|
|||||||
FIXME("(%04x, %04x, %08lx, %08lx): stub.\n", hFileHandle, hExistingCompletionPort, dwCompletionKey, dwNumberOfConcurrentThreads);
|
FIXME("(%04x, %04x, %08lx, %08lx): stub.\n", hFileHandle, hExistingCompletionPort, dwCompletionKey, dwNumberOfConcurrentThreads);
|
||||||
return (HANDLE)NULL;
|
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 <assert.h>
|
||||||
#include "windef.h"
|
#include "windef.h"
|
||||||
#include "wingdi.h"
|
#include "wingdi.h"
|
||||||
|
#include "winerror.h"
|
||||||
#include "wine/winbase16.h"
|
#include "wine/winbase16.h"
|
||||||
#include "wine/winuser16.h"
|
#include "wine/winuser16.h"
|
||||||
#include "miscemu.h"
|
#include "miscemu.h"
|
||||||
@ -1660,3 +1661,88 @@ LONG WINAPI GetMessageExtraInfo(void)
|
|||||||
|
|
||||||
return ret;
|
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 = (DC *)GDI_GetObjPtr(hDC, DC_MAGIC)) )
|
||||||
{
|
{
|
||||||
if (dc->w.hVisRgn) {
|
if (dc->w.hVisRgn) {
|
||||||
wnd->pDriver->pSurfaceCopy(wnd,dc,dx,dy,&rc,bUpdate);
|
wnd->pDriver->pSurfaceCopy(wnd,hDC,dx,dy,&rc,bUpdate);
|
||||||
|
|
||||||
if( bUpdate )
|
if( bUpdate )
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user