Moved a bunch of functions out of libwine/kernel/gdi into USER.

This commit is contained in:
Alexandre Julliard 2000-08-04 04:21:02 +00:00
parent b0efe28f6c
commit 93652e1a68
18 changed files with 1588 additions and 1550 deletions

View file

@ -25,13 +25,13 @@ import ntdll.dll
7 register VxDCall6(long) VxDCall
8 register VxDCall7(long) VxDCall
9 register VxDCall8(long) VxDCall
10 stdcall k32CharToOemA(str str) CharToOemA
11 stdcall k32CharToOemBuffA(str str long) CharToOemBuffA
12 stdcall k32OemToCharA(ptr ptr) OemToCharA
13 stdcall k32OemToCharBuffA(ptr ptr long) OemToCharBuffA
14 stdcall k32LoadStringA(long long ptr long) LoadStringA
15 varargs k32wsprintfA(str str) wsprintfA
16 stdcall k32wvsprintfA(ptr str ptr) wvsprintfA
10 forward k32CharToOemA user32.CharToOemA
11 forward k32CharToOemBuffA user32.CharToOemBuffA
12 forward k32OemToCharA user32.OemToCharA
13 forward k32OemToCharBuffA user32.OemToCharBuffA
14 forward k32LoadStringA user32.LoadStringA
15 forward k32wsprintfA user32.wsprintfA
16 forward k32wvsprintfA user32.wvsprintfA
17 register CommonUnimpStub() CommonUnimpStub
18 stdcall GetProcessDword(long long) GetProcessDword
19 stub ThunkTheTemplateHandle

View file

@ -6,17 +6,22 @@ MODULE = user32
SOVERSION = 1.0
WRCEXTRA = -w16 -m
ALTNAMES = user keyboard ddeml display mouse
IMPORTS = gdi32
IMPORTS = gdi32 kernel32
C_SRCS = \
bidi16.c \
cache.c \
ddeml.c \
display.c \
exticon.c \
lstr.c \
misc.c \
mouse.c \
network.c \
user_main.c \
thunk.c
resource.c \
text.c \
thunk.c \
user_main.c
RC_SRCS = \
disp.rc \

201
dlls/user/lstr.c Normal file
View 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
View 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
View 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
View 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;
}

View file

@ -7,7 +7,6 @@ MODULE = graphics
C_SRCS = \
bitblt.c \
cache.c \
dispdib.c \
driver.c \
env.c \

View file

@ -31,7 +31,6 @@
#include "winnls.h"
DEFAULT_DEBUG_CHANNEL(resource);
DECLARE_DEBUG_CHANNEL(accel);
#define HRSRC_MAP_BLOCKSIZE 16
@ -571,399 +570,6 @@ DWORD WINAPI SizeofResource( HINSTANCE hModule, HRSRC hRsrc )
/**********************************************************************
* LoadAccelerators16 [USER.177]
*/
HACCEL16 WINAPI LoadAccelerators16(HINSTANCE16 instance, SEGPTR lpTableName)
{
HRSRC16 hRsrc;
if (HIWORD(lpTableName))
TRACE_(accel)("%04x '%s'\n",
instance, (char *)PTR_SEG_TO_LIN( lpTableName ) );
else
TRACE_(accel)("%04x %04x\n",
instance, LOWORD(lpTableName) );
if (!(hRsrc = FindResource16( instance, lpTableName, RT_ACCELERATOR16 ))) {
WARN_(accel)("couldn't find accelerator table resource\n");
return 0;
}
TRACE_(accel)("returning HACCEL 0x%x\n", hRsrc);
return LoadResource16(instance,hRsrc);
}
/**********************************************************************
* LoadAcceleratorsW [USER.177]
* The image layout seems to look like this (not 100% sure):
* 00: BYTE type type of accelerator
* 01: BYTE pad (to WORD boundary)
* 02: WORD event
* 04: WORD IDval
* 06: WORD pad (to DWORD boundary)
*/
HACCEL WINAPI LoadAcceleratorsW(HINSTANCE instance,LPCWSTR lpTableName)
{
HRSRC hRsrc;
HACCEL hMem,hRetval=0;
DWORD size;
if (HIWORD(lpTableName))
TRACE_(accel)("%p '%s'\n",
(LPVOID)instance, (char *)( lpTableName ) );
else
TRACE_(accel)("%p 0x%04x\n",
(LPVOID)instance, LOWORD(lpTableName) );
if (!(hRsrc = FindResourceW( instance, lpTableName, RT_ACCELERATORW )))
{
WARN_(accel)("couldn't find accelerator table resource\n");
} else {
hMem = LoadResource( instance, hRsrc );
size = SizeofResource( instance, hRsrc );
if(size>=sizeof(PE_ACCEL))
{
LPPE_ACCEL accel_table = (LPPE_ACCEL) hMem;
LPACCEL16 accel16;
int i,nrofaccells = size/sizeof(PE_ACCEL);
hRetval = GlobalAlloc16(0,sizeof(ACCEL16)*nrofaccells);
accel16 = (LPACCEL16)GlobalLock16(hRetval);
for (i=0;i<nrofaccells;i++) {
accel16[i].fVirt = accel_table[i].fVirt;
accel16[i].key = accel_table[i].key;
accel16[i].cmd = accel_table[i].cmd;
}
accel16[i-1].fVirt |= 0x80;
}
}
TRACE_(accel)("returning HACCEL 0x%x\n", hRsrc);
return hRetval;
}
/***********************************************************************
* LoadAcceleratorsA
*/
HACCEL WINAPI LoadAcceleratorsA(HINSTANCE instance,LPCSTR lpTableName)
{
LPWSTR uni;
HACCEL result;
if (HIWORD(lpTableName))
uni = HEAP_strdupAtoW( GetProcessHeap(), 0, lpTableName );
else
uni = (LPWSTR)lpTableName;
result = LoadAcceleratorsW(instance,uni);
if (HIWORD(uni)) HeapFree( GetProcessHeap(), 0, uni);
return result;
}
/**********************************************************************
* CopyAcceleratorTableA (USER32.58)
*/
INT WINAPI CopyAcceleratorTableA(HACCEL src, LPACCEL dst, INT entries)
{
return CopyAcceleratorTableW(src, dst, entries);
}
/**********************************************************************
* CopyAcceleratorTableW (USER32.59)
*
* By mortene@pvv.org 980321
*/
INT WINAPI CopyAcceleratorTableW(HACCEL src, LPACCEL dst,
INT entries)
{
int i,xsize;
LPACCEL16 accel = (LPACCEL16)GlobalLock16(src);
BOOL done = FALSE;
/* Do parameter checking to avoid the explosions and the screaming
as far as possible. */
if((dst && (entries < 1)) || (src == (HACCEL)NULL) || !accel) {
WARN_(accel)("Application sent invalid parameters (%p %p %d).\n",
(LPVOID)src, (LPVOID)dst, entries);
return 0;
}
xsize = GlobalSize16(src)/sizeof(ACCEL16);
if (xsize>entries) entries=xsize;
i=0;
while(!done) {
/* Spit out some debugging information. */
TRACE_(accel)("accel %d: type 0x%02x, event '%c', IDval 0x%04x.\n",
i, accel[i].fVirt, accel[i].key, accel[i].cmd);
/* Copy data to the destination structure array (if dst == NULL,
we're just supposed to count the number of entries). */
if(dst) {
dst[i].fVirt = accel[i].fVirt;
dst[i].key = accel[i].key;
dst[i].cmd = accel[i].cmd;
/* Check if we've reached the end of the application supplied
accelerator table. */
if(i+1 == entries) {
/* Turn off the high order bit, just in case. */
dst[i].fVirt &= 0x7f;
done = TRUE;
}
}
/* The highest order bit seems to mark the end of the accelerator
resource table, but not always. Use GlobalSize() check too. */
if((accel[i].fVirt & 0x80) != 0) done = TRUE;
i++;
}
return i;
}
/*********************************************************************
* CreateAcceleratorTableA (USER32.64)
*
* By mortene@pvv.org 980321
*/
HACCEL WINAPI CreateAcceleratorTableA(LPACCEL lpaccel, INT cEntries)
{
HACCEL hAccel;
LPACCEL16 accel;
int i;
/* Do parameter checking just in case someone's trying to be
funny. */
if(cEntries < 1) {
WARN_(accel)("Application sent invalid parameters (%p %d).\n",
lpaccel, cEntries);
SetLastError(ERROR_INVALID_PARAMETER);
return (HACCEL)NULL;
}
FIXME_(accel)("should check that the accelerator descriptions are valid,"
" return NULL and SetLastError() if not.\n");
/* Allocate memory and copy the table. */
hAccel = GlobalAlloc16(0,cEntries*sizeof(ACCEL16));
TRACE_(accel)("handle %x\n", hAccel);
if(!hAccel) {
ERR_(accel)("Out of memory.\n");
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
return (HACCEL)NULL;
}
accel = GlobalLock16(hAccel);
for (i=0;i<cEntries;i++) {
accel[i].fVirt = lpaccel[i].fVirt;
accel[i].key = lpaccel[i].key;
accel[i].cmd = lpaccel[i].cmd;
}
/* Set the end-of-table terminator. */
accel[cEntries-1].fVirt |= 0x80;
TRACE_(accel)("Allocated accelerator handle %x\n", hAccel);
return hAccel;
}
/*********************************************************************
* CreateAcceleratorTableW (USER32.64)
*
*
*/
HACCEL WINAPI CreateAcceleratorTableW(LPACCEL lpaccel, INT cEntries)
{
HACCEL hAccel;
LPACCEL16 accel;
int i;
char ckey;
/* Do parameter checking just in case someone's trying to be
funny. */
if(cEntries < 1) {
WARN_(accel)("Application sent invalid parameters (%p %d).\n",
lpaccel, cEntries);
SetLastError(ERROR_INVALID_PARAMETER);
return (HACCEL)NULL;
}
FIXME_(accel)("should check that the accelerator descriptions are valid,"
" return NULL and SetLastError() if not.\n");
/* Allocate memory and copy the table. */
hAccel = GlobalAlloc16(0,cEntries*sizeof(ACCEL16));
TRACE_(accel)("handle %x\n", hAccel);
if(!hAccel) {
ERR_(accel)("Out of memory.\n");
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
return (HACCEL)NULL;
}
accel = GlobalLock16(hAccel);
for (i=0;i<cEntries;i++) {
accel[i].fVirt = lpaccel[i].fVirt;
if( !(accel[i].fVirt & FVIRTKEY) ) {
ckey = (char) lpaccel[i].key;
if(!MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, &ckey, 1, &accel[i].key, 1))
WARN_(accel)("Error converting ASCII accelerator table to Unicode");
}
else
accel[i].key = lpaccel[i].key;
accel[i].cmd = lpaccel[i].cmd;
}
/* Set the end-of-table terminator. */
accel[cEntries-1].fVirt |= 0x80;
TRACE_(accel)("Allocated accelerator handle %x\n", hAccel);
return hAccel;
}
/******************************************************************************
* DestroyAcceleratorTable [USER32.130]
* Destroys an accelerator table
*
* NOTES
* By mortene@pvv.org 980321
*
* PARAMS
* handle [I] Handle to accelerator table
*
* RETURNS STD
*/
BOOL WINAPI DestroyAcceleratorTable( HACCEL handle )
{
return !GlobalFree16(handle);
}
/**********************************************************************
* LoadString16
*/
INT16 WINAPI LoadString16( HINSTANCE16 instance, UINT16 resource_id,
LPSTR buffer, INT16 buflen )
{
HGLOBAL16 hmem;
HRSRC16 hrsrc;
unsigned char *p;
int string_num;
int i;
TRACE("inst=%04x id=%04x buff=%08x len=%d\n",
instance, resource_id, (int) buffer, buflen);
hrsrc = FindResource16( instance, (SEGPTR)((resource_id>>4)+1), RT_STRING16 );
if (!hrsrc) return 0;
hmem = LoadResource16( instance, hrsrc );
if (!hmem) return 0;
p = LockResource16(hmem);
string_num = resource_id & 0x000f;
for (i = 0; i < string_num; i++)
p += *p + 1;
TRACE("strlen = %d\n", (int)*p );
if (buffer == NULL) return *p;
i = min(buflen - 1, *p);
if (i > 0) {
memcpy(buffer, p + 1, i);
buffer[i] = '\0';
} else {
if (buflen > 1) {
buffer[0] = '\0';
return 0;
}
WARN("Dont know why caller give buflen=%d *p=%d trying to obtain string '%s'\n", buflen, *p, p + 1);
}
FreeResource16( hmem );
TRACE("'%s' loaded !\n", buffer);
return i;
}
/**********************************************************************
* LoadStringW (USER32.376)
*/
INT WINAPI LoadStringW( HINSTANCE instance, UINT resource_id,
LPWSTR buffer, INT buflen )
{
HGLOBAL hmem;
HRSRC hrsrc;
WCHAR *p;
int string_num;
int i;
if (HIWORD(resource_id)==0xFFFF) /* netscape 3 passes this */
resource_id = (UINT)(-((INT)resource_id));
TRACE("instance = %04x, id = %04x, buffer = %08x, "
"length = %d\n", instance, (int)resource_id, (int) buffer, buflen);
/* Use bits 4 - 19 (incremented by 1) as resourceid, mask out
* 20 - 31. */
hrsrc = FindResourceW( instance, (LPCWSTR)(((resource_id>>4)&0xffff)+1),
RT_STRINGW );
if (!hrsrc) return 0;
hmem = LoadResource( instance, hrsrc );
if (!hmem) return 0;
p = LockResource(hmem);
string_num = resource_id & 0x000f;
for (i = 0; i < string_num; i++)
p += *p + 1;
TRACE("strlen = %d\n", (int)*p );
if (buffer == NULL) return *p;
i = min(buflen - 1, *p);
if (i > 0) {
memcpy(buffer, p + 1, i * sizeof (WCHAR));
buffer[i] = (WCHAR) 0;
} else {
if (buflen > 1) {
buffer[0] = (WCHAR) 0;
return 0;
}
#if 0
WARN("Dont know why caller give buflen=%d *p=%d trying to obtain string '%s'\n", buflen, *p, p + 1);
#endif
}
TRACE("%s loaded !\n", debugstr_w(buffer));
return i;
}
/**********************************************************************
* LoadStringA (USER32.375)
*/
INT WINAPI LoadStringA( HINSTANCE instance, UINT resource_id,
LPSTR buffer, INT buflen )
{
INT retval;
LPWSTR wbuf;
TRACE("instance = %04x, id = %04x, buffer = %08x, "
"length = %d\n", instance, (int)resource_id, (int) buffer, buflen);
if(buffer == NULL) /* asked size of string */
return LoadStringW(instance, resource_id, NULL, 0);
wbuf = HeapAlloc(GetProcessHeap(), 0, buflen * sizeof(WCHAR));
if(!wbuf)
return 0;
retval = LoadStringW(instance, resource_id, wbuf, buflen);
if(retval != 0)
{
retval = WideCharToMultiByte(CP_ACP, 0, wbuf, retval, buffer, buflen - 1, NULL, NULL);
buffer[retval] = 0;
TRACE("%s loaded !\n", debugstr_a(buffer));
}
HeapFree( GetProcessHeap(), 0, wbuf );
return retval;
}
/**********************************************************************
* EnumResourceTypesA (KERNEL32.90)
*/

View file

@ -30,11 +30,8 @@
#include "wine/winuser16.h"
#include "wine/unicode.h"
#include "winnls.h"
#include "task.h"
#include "heap.h"
#include "ldt.h"
#include "stackframe.h"
#include "module.h"
#include "debugtools.h"
DEFAULT_DEBUG_CHANNEL(resource);
@ -462,180 +459,3 @@ BOOL WINAPI IsCharUpperW(WCHAR x)
{
return iswupper(x);
}
/***********************************************************************
* FormatMessage16 (USER.606)
*/
DWORD WINAPI FormatMessage16(
DWORD dwFlags,
SEGPTR lpSource, /*not always a valid pointer*/
WORD dwMessageId,
WORD dwLanguageId,
LPSTR lpBuffer, /* *((HLOCAL16*)) for FORMAT_MESSAGE_ALLOCATE_BUFFER*/
WORD nSize,
LPDWORD args /* va_list *args */
) {
#ifdef __i386__
/* This implementation is completely dependant on the format of the va_list on x86 CPUs */
LPSTR target,t;
DWORD talloced;
LPSTR from,f;
DWORD width = dwFlags & FORMAT_MESSAGE_MAX_WIDTH_MASK;
BOOL eos = FALSE;
LPSTR allocstring = NULL;
TRACE("(0x%lx,%lx,%d,0x%x,%p,%d,%p)\n",
dwFlags,lpSource,dwMessageId,dwLanguageId,lpBuffer,nSize,args);
if ((dwFlags & FORMAT_MESSAGE_FROM_SYSTEM)
&& (dwFlags & FORMAT_MESSAGE_FROM_HMODULE)) return 0;
if ((dwFlags & FORMAT_MESSAGE_FROM_STRING)
&&((dwFlags & FORMAT_MESSAGE_FROM_SYSTEM)
|| (dwFlags & FORMAT_MESSAGE_FROM_HMODULE))) return 0;
if (width && width != FORMAT_MESSAGE_MAX_WIDTH_MASK)
FIXME("line wrapping (%lu) not supported.\n", width);
from = NULL;
if (dwFlags & FORMAT_MESSAGE_FROM_STRING)
from = HEAP_strdupA( GetProcessHeap(), 0, PTR_SEG_TO_LIN(lpSource));
if (dwFlags & FORMAT_MESSAGE_FROM_SYSTEM) {
from = HeapAlloc( GetProcessHeap(),0,200 );
sprintf(from,"Systemmessage, messageid = 0x%08x\n",dwMessageId);
}
if (dwFlags & FORMAT_MESSAGE_FROM_HMODULE) {
INT16 bufsize;
HINSTANCE16 hinst16 = ((HMODULE)lpSource & 0xffff);
dwMessageId &= 0xFFFF;
bufsize=LoadString16(hinst16,dwMessageId,NULL,0);
if (bufsize) {
from = HeapAlloc( GetProcessHeap(), 0, bufsize +1);
LoadString16(hinst16,dwMessageId,from,bufsize+1);
}
}
target = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, 100);
t = target;
talloced= 100;
#define ADD_TO_T(c) \
*t++=c;\
if (t-target == talloced) {\
target = (char*)HeapReAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,target,talloced*2);\
t = target+talloced;\
talloced*=2;\
}
if (from) {
f=from;
while (*f && !eos) {
if (*f=='%') {
int insertnr;
char *fmtstr,*x,*lastf;
DWORD *argliststart;
fmtstr = NULL;
lastf = f;
f++;
if (!*f) {
ADD_TO_T('%');
continue;
}
switch (*f) {
case '1':case '2':case '3':case '4':case '5':
case '6':case '7':case '8':case '9':
insertnr=*f-'0';
switch (f[1]) {
case '0':case '1':case '2':case '3':
case '4':case '5':case '6':case '7':
case '8':case '9':
f++;
insertnr=insertnr*10+*f-'0';
f++;
break;
default:
f++;
break;
}
if (*f=='!') {
f++;
if (NULL!=(x=strchr(f,'!'))) {
*x='\0';
fmtstr=HeapAlloc(GetProcessHeap(),0,strlen(f)+2);
sprintf(fmtstr,"%%%s",f);
f=x+1;
} else {
fmtstr=HeapAlloc(GetProcessHeap(),0,strlen(f)+2);
sprintf(fmtstr,"%%%s",f);
f+=strlen(f); /*at \0*/
}
} else
if(!args)
break;
else
fmtstr=HEAP_strdupA(GetProcessHeap(),0,"%s");
if (args) {
int sz;
LPSTR b = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sz = 100);
argliststart=args+insertnr-1;
/* CMF - This makes a BIG assumption about va_list */
while (vsnprintf(b, sz, fmtstr, (va_list) argliststart) < 0) {
b = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, b, sz += 100);
}
for (x=b; *x; x++) ADD_TO_T(*x);
} else {
/* NULL args - copy formatstr
* (probably wrong)
*/
while ((lastf<f)&&(*lastf)) {
ADD_TO_T(*lastf++);
}
}
HeapFree(GetProcessHeap(),0,fmtstr);
break;
case '0': /* Just stop processing format string */
eos = TRUE;
f++;
break;
case 'n': /* 16 bit version just outputs 'n' */
default:
ADD_TO_T(*f++);
break;
}
} else { /* '\n' or '\r' gets mapped to "\r\n" */
if(*f == '\n' || *f == '\r') {
if (width == 0) {
ADD_TO_T('\r');
ADD_TO_T('\n');
if(*f++ == '\r' && *f == '\n')
f++;
}
} else {
ADD_TO_T(*f++);
}
}
}
*t='\0';
}
talloced = strlen(target)+1;
if (nSize && talloced<nSize) {
target = (char*)HeapReAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,target,nSize);
}
TRACE("-- %s\n",debugstr_a(target));
if (dwFlags & FORMAT_MESSAGE_ALLOCATE_BUFFER) {
/* nSize is the MINIMUM size */
*((HLOCAL16*)lpBuffer)= LocalAlloc16(LPTR,talloced);
allocstring=PTR_SEG_OFF_TO_LIN(CURRENT_DS,*((HLOCAL16*)lpBuffer));
memcpy( allocstring,target,talloced);
} else
lstrcpynA(lpBuffer,target,nSize);
HeapFree(GetProcessHeap(),0,target);
if (from) HeapFree(GetProcessHeap(),0,from);
return (dwFlags & FORMAT_MESSAGE_ALLOCATE_BUFFER) ?
strlen(allocstring):
strlen(lpBuffer);
#else
return 0;
#endif /* __i386__ */
}
#undef ADD_TO_T

View file

@ -745,16 +745,6 @@ BOOL16 WINAPI IsDCCurrentPalette16(HDC16 hDC)
}
/***********************************************************************
* SelectPalette16 (USER.282)
*/
HPALETTE16 WINAPI SelectPalette16( HDC16 hDC, HPALETTE16 hPal,
BOOL16 bForceBackground )
{
return SelectPalette( hDC, hPal, bForceBackground );
}
/***********************************************************************
* SelectPalette [GDI32.300] Selects logical palette into DC
*
@ -783,15 +773,6 @@ HPALETTE WINAPI SelectPalette(
}
/***********************************************************************
* RealizePalette16 (USER.283)
*/
UINT16 WINAPI RealizePalette16( HDC16 hDC )
{
return RealizePalette( hDC );
}
/***********************************************************************
* RealizePalette [GDI32.280] Maps palette entries to system palette
*

View file

@ -16,347 +16,10 @@
#include "gdi.h"
#include "heap.h"
#include "debugtools.h"
#include "cache.h"
#include "winnls.h"
DEFAULT_DEBUG_CHANNEL(text);
#define TAB 9
#define LF 10
#define CR 13
#define SPACE 32
#define PREFIX 38
#define SWAP_INT(a,b) { int t = a; a = b; b = t; }
static int tabstop = 8;
static int tabwidth;
static int spacewidth;
static int prefix_offset;
static const char *TEXT_NextLine( HDC16 hdc, const char *str, int *count,
char *dest, int *len, int width, WORD format)
{
/* Return next line of text from a string.
*
* hdc - handle to DC.
* str - string to parse into lines.
* count - length of str.
* dest - destination in which to return line.
* len - length of resultant line in dest in chars.
* width - maximum width of line in pixels.
* format - format type passed to DrawText.
*
* Returns pointer to next char in str after end of the line
* or NULL if end of str reached.
*/
int i = 0, j = 0, k;
int plen = 0;
int numspaces;
SIZE16 size;
int lasttab = 0;
int wb_i = 0, wb_j = 0, wb_count = 0;
while (*count)
{
switch (str[i])
{
case CR:
case LF:
if (!(format & DT_SINGLELINE))
{
if ((*count > 1) && (str[i] == CR) && (str[i+1] == LF))
{
(*count)--;
i++;
}
i++;
*len = j;
(*count)--;
return (&str[i]);
}
dest[j++] = str[i++];
if (!(format & DT_NOCLIP) || !(format & DT_NOPREFIX) ||
(format & DT_WORDBREAK))
{
if (!GetTextExtentPoint16(hdc, &dest[j-1], 1, &size))
return NULL;
plen += size.cx;
}
break;
case PREFIX:
if (!(format & DT_NOPREFIX) && *count > 1)
{
if (str[++i] == PREFIX)
(*count)--;
else {
prefix_offset = j;
break;
}
}
dest[j++] = str[i++];
if (!(format & DT_NOCLIP) || !(format & DT_NOPREFIX) ||
(format & DT_WORDBREAK))
{
if (!GetTextExtentPoint16(hdc, &dest[j-1], 1, &size))
return NULL;
plen += size.cx;
}
break;
case TAB:
if (format & DT_EXPANDTABS)
{
wb_i = ++i;
wb_j = j;
wb_count = *count;
if (!GetTextExtentPoint16(hdc, &dest[lasttab], j - lasttab,
&size))
return NULL;
numspaces = (tabwidth - size.cx) / spacewidth;
for (k = 0; k < numspaces; k++)
dest[j++] = SPACE;
plen += tabwidth - size.cx;
lasttab = wb_j + numspaces;
}
else
{
dest[j++] = str[i++];
if (!(format & DT_NOCLIP) || !(format & DT_NOPREFIX) ||
(format & DT_WORDBREAK))
{
if (!GetTextExtentPoint16(hdc, &dest[j-1], 1, &size))
return NULL;
plen += size.cx;
}
}
break;
case SPACE:
dest[j++] = str[i++];
if (!(format & DT_NOCLIP) || !(format & DT_NOPREFIX) ||
(format & DT_WORDBREAK))
{
wb_i = i;
wb_j = j - 1;
wb_count = *count;
if (!GetTextExtentPoint16(hdc, &dest[j-1], 1, &size))
return NULL;
plen += size.cx;
}
break;
default:
dest[j++] = str[i++];
if (!(format & DT_NOCLIP) || !(format & DT_NOPREFIX) ||
(format & DT_WORDBREAK))
{
if (!GetTextExtentPoint16(hdc, &dest[j-1], 1, &size))
return NULL;
plen += size.cx;
}
}
(*count)--;
if (!(format & DT_NOCLIP) || (format & DT_WORDBREAK))
{
if (plen > width)
{
if (format & DT_WORDBREAK)
{
if (wb_j)
{
*len = wb_j;
*count = wb_count - 1;
return (&str[wb_i]);
}
}
else
{
*len = j;
return (&str[i]);
}
}
}
}
*len = j;
return NULL;
}
/***********************************************************************
* DrawText16 (USER.85)
*/
INT16 WINAPI DrawText16( HDC16 hdc, LPCSTR str, INT16 i_count,
LPRECT16 rect, UINT16 flags )
{
SIZE16 size;
const char *strPtr;
static char line[1024];
int len, lh, count=i_count;
int prefix_x = 0;
int prefix_end = 0;
TEXTMETRIC16 tm;
int x = rect->left, y = rect->top;
int width = rect->right - rect->left;
int max_width = 0;
TRACE("%s, %d , [(%d,%d),(%d,%d)]\n",
debugstr_an (str, count), count,
rect->left, rect->top, rect->right, rect->bottom);
if (!str) return 0;
if (count == -1) count = strlen(str);
strPtr = str;
GetTextMetrics16(hdc, &tm);
if (flags & DT_EXTERNALLEADING)
lh = tm.tmHeight + tm.tmExternalLeading;
else
lh = tm.tmHeight;
if (flags & DT_TABSTOP)
tabstop = flags >> 8;
if (flags & DT_EXPANDTABS)
{
GetTextExtentPoint16(hdc, " ", 1, &size);
spacewidth = size.cx;
GetTextExtentPoint16(hdc, "o", 1, &size);
tabwidth = size.cx * tabstop;
}
if (flags & DT_CALCRECT) flags |= DT_NOCLIP;
do
{
prefix_offset = -1;
strPtr = TEXT_NextLine(hdc, strPtr, &count, line, &len, width, flags);
if (prefix_offset != -1)
{
GetTextExtentPoint16(hdc, line, prefix_offset, &size);
prefix_x = size.cx;
GetTextExtentPoint16(hdc, line, prefix_offset + 1, &size);
prefix_end = size.cx - 1;
}
if (!GetTextExtentPoint16(hdc, line, len, &size)) return 0;
if (flags & DT_CENTER) x = (rect->left + rect->right -
size.cx) / 2;
else if (flags & DT_RIGHT) x = rect->right - size.cx;
if (flags & DT_SINGLELINE)
{
if (flags & DT_VCENTER) y = rect->top +
(rect->bottom - rect->top) / 2 - size.cy / 2;
else if (flags & DT_BOTTOM) y = rect->bottom - size.cy;
}
if (!(flags & DT_CALCRECT))
{
if (!ExtTextOut16(hdc, x, y, (flags & DT_NOCLIP) ? 0 : ETO_CLIPPED,
rect, line, len, NULL )) return 0;
if (prefix_offset != -1)
{
HPEN hpen = CreatePen( PS_SOLID, 1, GetTextColor(hdc) );
HPEN oldPen = SelectObject( hdc, hpen );
MoveTo16(hdc, x + prefix_x, y + tm.tmAscent + 1 );
LineTo(hdc, x + prefix_end + 1, y + tm.tmAscent + 1 );
SelectObject( hdc, oldPen );
DeleteObject( hpen );
}
}
else if (size.cx > max_width)
max_width = size.cx;
y += lh;
if (strPtr)
{
if (!(flags & DT_NOCLIP))
{
if (y > rect->bottom - lh)
break;
}
}
}
while (strPtr);
if (flags & DT_CALCRECT)
{
rect->right = rect->left + max_width;
rect->bottom = y;
}
return y - rect->top;
}
/***********************************************************************
* DrawTextA (USER32.164)
*/
INT WINAPI DrawTextA( HDC hdc, LPCSTR str, INT count,
LPRECT rect, UINT flags )
{
RECT16 rect16;
INT16 ret;
if (!rect)
return DrawText16( (HDC16)hdc, str, (INT16)count, NULL, (UINT16)flags);
CONV_RECT32TO16( rect, &rect16 );
ret = DrawText16( (HDC16)hdc, str, (INT16)count, &rect16, (UINT16)flags );
CONV_RECT16TO32( &rect16, rect );
return ret;
}
/***********************************************************************
* DrawTextW (USER32.167)
*/
INT WINAPI DrawTextW( HDC hdc, LPCWSTR str, INT count,
LPRECT rect, UINT flags )
{
LPSTR p;
INT acount;
INT ret;
UINT codepage = CP_ACP; /* FIXME: get codepage of font charset */
acount = WideCharToMultiByte(codepage,0,str,count,NULL,0,NULL,NULL);
p = HeapAlloc( GetProcessHeap(), 0, acount );
acount = WideCharToMultiByte(codepage,0,str,count,p,acount,NULL,NULL);
if (count == -1) acount = -1;
ret = DrawTextA( hdc, p, acount, rect, flags );
HeapFree( GetProcessHeap(), 0, p );
return ret;
}
/***********************************************************************
* DrawTextExA (USER32.165)
*/
INT WINAPI DrawTextExA( HDC hdc, LPCSTR str, INT count,
LPRECT rect, UINT flags, LPDRAWTEXTPARAMS dtp )
{
TRACE("(%d,'%s',%d,%p,0x%08x,%p)\n",hdc,str,count,rect,flags,dtp);
if(dtp) {
FIXME("Ignores params:%d,%d,%d,%d\n",dtp->cbSize,
dtp->iTabLength,dtp->iLeftMargin,dtp->iRightMargin);
}
return DrawTextA(hdc,str,count,rect,flags);
}
/***********************************************************************
* DrawTextExW (USER32.166)
*/
INT WINAPI DrawTextExW( HDC hdc, LPCWSTR str, INT count,
LPRECT rect, UINT flags, LPDRAWTEXTPARAMS dtp )
{
TRACE("(%d,%p,%d,%p,0x%08x,%p)\n",hdc,str,count,rect,flags,dtp);
FIXME("ignores extended functionality\n");
return DrawTextW(hdc,str,count,rect,flags);
}
/***********************************************************************
* ExtTextOut16 (GDI.351)
@ -462,314 +125,6 @@ BOOL WINAPI TextOutW(HDC hdc, INT x, INT y, LPCWSTR str, INT count)
}
/***********************************************************************
* TEXT_GrayString
*
* FIXME: The call to 16-bit code only works because the wine GDI is a 16-bit
* heap and we can guarantee that the handles fit in an INT16. We have to
* rethink the strategy once the migration to NT handles is complete.
* We are going to get a lot of code-duplication once this migration is
* completed...
*
*/
static BOOL TEXT_GrayString(HDC hdc, HBRUSH hb,
GRAYSTRINGPROC fn, LPARAM lp, INT len,
INT x, INT y, INT cx, INT cy,
BOOL unicode, BOOL _32bit)
{
HBITMAP hbm, hbmsave;
HBRUSH hbsave;
HFONT hfsave;
HDC memdc = CreateCompatibleDC(hdc);
int slen = len;
BOOL retval = TRUE;
COLORREF fg, bg;
if(!hdc) return FALSE;
if(len == 0)
{
if(unicode)
slen = lstrlenW((LPCWSTR)lp);
else if(_32bit)
slen = lstrlenA((LPCSTR)lp);
else
slen = lstrlenA((LPCSTR)PTR_SEG_TO_LIN(lp));
}
if((cx == 0 || cy == 0) && slen != -1)
{
SIZE s;
if(unicode)
GetTextExtentPoint32W(hdc, (LPCWSTR)lp, slen, &s);
else if(_32bit)
GetTextExtentPoint32A(hdc, (LPCSTR)lp, slen, &s);
else
GetTextExtentPoint32A(hdc, (LPCSTR)PTR_SEG_TO_LIN(lp), slen, &s);
if(cx == 0) cx = s.cx;
if(cy == 0) cy = s.cy;
}
hbm = CreateBitmap(cx, cy, 1, 1, NULL);
hbmsave = (HBITMAP)SelectObject(memdc, hbm);
hbsave = SelectObject( memdc, GetStockObject(BLACK_BRUSH) );
PatBlt( memdc, 0, 0, cx, cy, PATCOPY );
SelectObject( memdc, hbsave );
SetTextColor(memdc, RGB(255, 255, 255));
SetBkColor(memdc, RGB(0, 0, 0));
hfsave = (HFONT)SelectObject(memdc, GetCurrentObject(hdc, OBJ_FONT));
if(fn)
if(_32bit)
retval = fn(memdc, lp, slen);
else
retval = (BOOL)((BOOL16)((GRAYSTRINGPROC16)fn)((HDC16)memdc, lp, (INT16)slen));
else
if(unicode)
TextOutW(memdc, 0, 0, (LPCWSTR)lp, slen);
else if(_32bit)
TextOutA(memdc, 0, 0, (LPCSTR)lp, slen);
else
TextOutA(memdc, 0, 0, (LPCSTR)PTR_SEG_TO_LIN(lp), slen);
SelectObject(memdc, hfsave);
/*
* Windows doc says that the bitmap isn't grayed when len == -1 and
* the callback function returns FALSE. However, testing this on
* win95 showed otherwise...
*/
#ifdef GRAYSTRING_USING_DOCUMENTED_BEHAVIOUR
if(retval || len != -1)
#endif
{
hbsave = (HBRUSH)SelectObject(memdc, CACHE_GetPattern55AABrush());
PatBlt(memdc, 0, 0, cx, cy, 0x000A0329);
SelectObject(memdc, hbsave);
}
if(hb) hbsave = (HBRUSH)SelectObject(hdc, hb);
fg = SetTextColor(hdc, RGB(0, 0, 0));
bg = SetBkColor(hdc, RGB(255, 255, 255));
BitBlt(hdc, x, y, cx, cy, memdc, 0, 0, 0x00E20746);
SetTextColor(hdc, fg);
SetBkColor(hdc, bg);
if(hb) SelectObject(hdc, hbsave);
SelectObject(memdc, hbmsave);
DeleteObject(hbm);
DeleteDC(memdc);
return retval;
}
/***********************************************************************
* GrayString16 (USER.185)
*/
BOOL16 WINAPI GrayString16( HDC16 hdc, HBRUSH16 hbr, GRAYSTRINGPROC16 gsprc,
LPARAM lParam, INT16 cch, INT16 x, INT16 y,
INT16 cx, INT16 cy )
{
return TEXT_GrayString(hdc, hbr, (GRAYSTRINGPROC)gsprc, lParam, cch, x, y, cx, cy, FALSE, FALSE);
}
/***********************************************************************
* GrayStringA (USER32.315)
*/
BOOL WINAPI GrayStringA( HDC hdc, HBRUSH hbr, GRAYSTRINGPROC gsprc,
LPARAM lParam, INT cch, INT x, INT y,
INT cx, INT cy )
{
return TEXT_GrayString(hdc, hbr, gsprc, lParam, cch, x, y, cx, cy, FALSE, TRUE);
}
/***********************************************************************
* GrayStringW (USER32.316)
*/
BOOL WINAPI GrayStringW( HDC hdc, HBRUSH hbr, GRAYSTRINGPROC gsprc,
LPARAM lParam, INT cch, INT x, INT y,
INT cx, INT cy )
{
return TEXT_GrayString(hdc, hbr, gsprc, lParam, cch, x, y, cx, cy, TRUE, TRUE);
}
/***********************************************************************
* TEXT_TabbedTextOut
*
* Helper function for TabbedTextOut() and GetTabbedTextExtent().
* Note: this doesn't work too well for text-alignment modes other
* than TA_LEFT|TA_TOP. But we want bug-for-bug compatibility :-)
*/
LONG TEXT_TabbedTextOut( HDC hdc, INT x, INT y, LPCSTR lpstr,
INT count, INT cTabStops, const INT16 *lpTabPos16,
const INT *lpTabPos32, INT nTabOrg,
BOOL fDisplayText )
{
INT defWidth;
DWORD extent = 0;
int i, tabPos = x;
int start = x;
if (cTabStops == 1)
{
defWidth = lpTabPos32 ? *lpTabPos32 : *lpTabPos16;
cTabStops = 0;
}
else
{
TEXTMETRIC16 tm;
GetTextMetrics16( hdc, &tm );
defWidth = 8 * tm.tmAveCharWidth;
}
while (count > 0)
{
for (i = 0; i < count; i++)
if (lpstr[i] == '\t') break;
extent = GetTextExtent16( hdc, lpstr, i );
if (lpTabPos32)
{
while ((cTabStops > 0) &&
(nTabOrg + *lpTabPos32 <= x + LOWORD(extent)))
{
lpTabPos32++;
cTabStops--;
}
}
else
{
while ((cTabStops > 0) &&
(nTabOrg + *lpTabPos16 <= x + LOWORD(extent)))
{
lpTabPos16++;
cTabStops--;
}
}
if (i == count)
tabPos = x + LOWORD(extent);
else if (cTabStops > 0)
tabPos = nTabOrg + (lpTabPos32 ? *lpTabPos32 : *lpTabPos16);
else
tabPos = nTabOrg + ((x + LOWORD(extent) - nTabOrg) / defWidth + 1) * defWidth;
if (fDisplayText)
{
RECT r;
r.left = x;
r.top = y;
r.right = tabPos;
r.bottom = y + HIWORD(extent);
ExtTextOutA( hdc, x, y,
GetBkMode(hdc) == OPAQUE ? ETO_OPAQUE : 0,
&r, lpstr, i, NULL );
}
x = tabPos;
count -= i+1;
lpstr += i+1;
}
return MAKELONG(tabPos - start, HIWORD(extent));
}
/***********************************************************************
* TabbedTextOut16 (USER.196)
*/
LONG WINAPI TabbedTextOut16( HDC16 hdc, INT16 x, INT16 y, LPCSTR lpstr,
INT16 count, INT16 cTabStops,
const INT16 *lpTabPos, INT16 nTabOrg )
{
TRACE("%04x %d,%d '%.*s' %d\n",
hdc, x, y, count, lpstr, count );
return TEXT_TabbedTextOut( hdc, x, y, lpstr, count, cTabStops,
lpTabPos, NULL, nTabOrg, TRUE );
}
/***********************************************************************
* TabbedTextOutA (USER32.542)
*/
LONG WINAPI TabbedTextOutA( HDC hdc, INT x, INT y, LPCSTR lpstr,
INT count, INT cTabStops,
const INT *lpTabPos, INT nTabOrg )
{
TRACE("%04x %d,%d '%.*s' %d\n",
hdc, x, y, count, lpstr, count );
return TEXT_TabbedTextOut( hdc, x, y, lpstr, count, cTabStops,
NULL, lpTabPos, nTabOrg, TRUE );
}
/***********************************************************************
* TabbedTextOutW (USER32.543)
*/
LONG WINAPI TabbedTextOutW( HDC hdc, INT x, INT y, LPCWSTR str,
INT count, INT cTabStops,
const INT *lpTabPos, INT nTabOrg )
{
LONG ret;
LPSTR p;
INT acount;
UINT codepage = CP_ACP; /* FIXME: get codepage of font charset */
acount = WideCharToMultiByte(codepage,0,str,count,NULL,0,NULL,NULL);
p = HeapAlloc( GetProcessHeap(), 0, acount );
if(p == NULL) return 0; /* FIXME: is this the correct return on failure */
acount = WideCharToMultiByte(codepage,0,str,count,p,acount,NULL,NULL);
ret = TabbedTextOutA( hdc, x, y, p, acount, cTabStops,
lpTabPos, nTabOrg );
HeapFree( GetProcessHeap(), 0, p );
return ret;
}
/***********************************************************************
* GetTabbedTextExtent16 (USER.197)
*/
DWORD WINAPI GetTabbedTextExtent16( HDC16 hdc, LPCSTR lpstr, INT16 count,
INT16 cTabStops, const INT16 *lpTabPos )
{
TRACE("%04x '%.*s' %d\n",
hdc, count, lpstr, count );
return TEXT_TabbedTextOut( hdc, 0, 0, lpstr, count, cTabStops,
lpTabPos, NULL, 0, FALSE );
}
/***********************************************************************
* GetTabbedTextExtentA (USER32.293)
*/
DWORD WINAPI GetTabbedTextExtentA( HDC hdc, LPCSTR lpstr, INT count,
INT cTabStops, const INT *lpTabPos )
{
TRACE("%04x '%.*s' %d\n",
hdc, count, lpstr, count );
return TEXT_TabbedTextOut( hdc, 0, 0, lpstr, count, cTabStops,
NULL, lpTabPos, 0, FALSE );
}
/***********************************************************************
* GetTabbedTextExtentW (USER32.294)
*/
DWORD WINAPI GetTabbedTextExtentW( HDC hdc, LPCWSTR lpstr, INT count,
INT cTabStops, const INT *lpTabPos )
{
LONG ret;
LPSTR p;
INT acount;
UINT codepage = CP_ACP; /* FIXME: get codepage of font charset */
acount = WideCharToMultiByte(codepage,0,lpstr,count,NULL,0,NULL,NULL);
p = HeapAlloc( GetProcessHeap(), 0, acount );
if(p == NULL) return 0; /* FIXME: is this the correct failure value? */
acount = WideCharToMultiByte(codepage,0,lpstr,count,p,acount,NULL,NULL);
ret = GetTabbedTextExtentA( hdc, p, acount, cTabStops, lpTabPos );
HeapFree( GetProcessHeap(), 0, p );
return ret;
}
/***********************************************************************
* GetTextCharset [GDI32.226] Gets character set for font in DC
*

View file

@ -28,8 +28,6 @@
#include "stackframe.h"
#include "builtin16.h"
#include "debugtools.h"
#include "queue.h"
#include "hook.h"
#include "winnls.h"
DEFAULT_DEBUG_CHANNEL(thread);
@ -359,32 +357,6 @@ void WINAPI ExitThread( DWORD code ) /* [in] Exit code for this thread */
}
/**********************************************************************
* SetLastErrorEx [USER32.485] Sets the last-error code.
*
* RETURNS
* None.
*/
void WINAPI SetLastErrorEx(
DWORD error, /* [in] Per-thread error code */
DWORD type) /* [in] Error type */
{
TRACE("(0x%08lx, 0x%08lx)\n", error,type);
switch(type) {
case 0:
break;
case SLE_ERROR:
case SLE_MINORERROR:
case SLE_WARNING:
/* Fall through for now */
default:
FIXME("(error=%08lx, type=%08lx): Unhandled type\n", error,type);
break;
}
SetLastError( error );
}
/**********************************************************************
* TlsAlloc [KERNEL32.530] Allocates a TLS index.
*
@ -747,95 +719,6 @@ BOOL WINAPI GetThreadTimes(
}
/**********************************************************************
* AttachThreadInput [KERNEL32.8] Attaches input of 1 thread to other
*
* Attaches the input processing mechanism of one thread to that of
* another thread.
*
* RETURNS
* Success: TRUE
* Failure: FALSE
*
* TODO:
* 1. Reset the Key State (currenly per thread key state is not maintained)
*/
BOOL WINAPI AttachThreadInput(
DWORD idAttach, /* [in] Thread to attach */
DWORD idAttachTo, /* [in] Thread to attach to */
BOOL fAttach) /* [in] Attach or detach */
{
#if 0 /* FIXME: cannot call USER functions here */
MESSAGEQUEUE *pSrcMsgQ = 0, *pTgtMsgQ = 0;
BOOL16 bRet = 0;
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
/* A thread cannot attach to itself */
if ( idAttach == idAttachTo )
goto CLEANUP;
/* According to the docs this method should fail if a
* "Journal record" hook is installed. (attaches all input queues together)
*/
if ( HOOK_IsHooked( WH_JOURNALRECORD ) )
goto CLEANUP;
/* Retrieve message queues corresponding to the thread id's */
pTgtMsgQ = (MESSAGEQUEUE *)QUEUE_Lock( GetThreadQueue16( idAttach ) );
pSrcMsgQ = (MESSAGEQUEUE *)QUEUE_Lock( GetThreadQueue16( idAttachTo ) );
/* Ensure we have message queues and that Src and Tgt threads
* are not system threads.
*/
if ( !pSrcMsgQ || !pTgtMsgQ || !pSrcMsgQ->pQData || !pTgtMsgQ->pQData )
goto CLEANUP;
if (fAttach) /* Attach threads */
{
/* Only attach if currently detached */
if ( pTgtMsgQ->pQData != pSrcMsgQ->pQData )
{
/* First release the target threads perQData */
PERQDATA_Release( pTgtMsgQ->pQData );
/* Share a reference to the source threads perQDATA */
PERQDATA_Addref( pSrcMsgQ->pQData );
pTgtMsgQ->pQData = pSrcMsgQ->pQData;
}
}
else /* Detach threads */
{
/* Only detach if currently attached */
if ( pTgtMsgQ->pQData == pSrcMsgQ->pQData )
{
/* First release the target threads perQData */
PERQDATA_Release( pTgtMsgQ->pQData );
/* Give the target thread its own private perQDATA once more */
pTgtMsgQ->pQData = PERQDATA_CreateInstance();
}
}
/* TODO: Reset the Key State */
bRet = 1; /* Success */
CLEANUP:
/* Unlock the queues before returning */
if ( pSrcMsgQ )
QUEUE_Unlock( pSrcMsgQ );
if ( pTgtMsgQ )
QUEUE_Unlock( pTgtMsgQ );
return bRet;
#endif
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
FIXME( "broken for now\n" );
return FALSE;
}
/**********************************************************************
* VWin32_BoostThreadGroup [KERNEL.535]
*/

View file

@ -14,7 +14,6 @@ C_SRCS = \
init.c \
kernel32.c \
newfns.c \
ordinals.c \
process.c \
struct32.c \
time.c

View file

@ -226,56 +226,6 @@ DWORD WINAPI GetCompressedFileSizeW(
}
/******************************************************************************
* GetProcessWindowStation [USER32.280] Returns handle of window station
*
* NOTES
* Docs say the return value is HWINSTA
*
* RETURNS
* Success: Handle to window station associated with calling process
* Failure: NULL
*/
DWORD WINAPI GetProcessWindowStation(void)
{
FIXME("(void): stub\n");
return 1;
}
/******************************************************************************
* GetThreadDesktop [USER32.295] Returns handle to desktop
*
* NOTES
* Docs say the return value is HDESK
*
* PARAMS
* dwThreadId [I] Thread identifier
*
* RETURNS
* Success: Handle to desktop associated with specified thread
* Failure: NULL
*/
DWORD WINAPI GetThreadDesktop( DWORD dwThreadId )
{
FIXME("(%lx): stub\n",dwThreadId);
return 1;
}
/******************************************************************************
* SetDebugErrorLevel [USER32.475]
* Sets the minimum error level for generating debugging events
*
* PARAMS
* dwLevel [I] Debugging error level
*/
VOID WINAPI SetDebugErrorLevel( DWORD dwLevel )
{
FIXME("(%ld): stub\n", dwLevel);
}
/******************************************************************************
* SetComputerNameA [KERNEL32.621]
*/
@ -310,44 +260,6 @@ BOOL WINAPI EnumPortsA(LPSTR name,DWORD level,LPBYTE ports,DWORD bufsize,LPDWORD
return FALSE;
}
/******************************************************************************
* OpenDesktopA [USER32.408]
*
* NOTES
* Return type should be HDESK
*
* Not supported on Win9x - returns NULL and calls SetLastError.
*/
HANDLE WINAPI OpenDesktopA( LPCSTR lpszDesktop, DWORD dwFlags,
BOOL fInherit, DWORD dwDesiredAccess )
{
FIXME("(%s,%lx,%i,%lx): stub\n",debugstr_a(lpszDesktop),dwFlags,
fInherit,dwDesiredAccess);
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return 0;
}
/******************************************************************************
* SetUserObjectInformationA
*/
BOOL WINAPI SetUserObjectInformationA( HANDLE hObj, INT nIndex,
LPVOID pvInfo, DWORD nLength )
{
FIXME("(%x,%d,%p,%lx): stub\n",hObj,nIndex,pvInfo,nLength);
return TRUE;
}
/******************************************************************************
* SetThreadDesktop
*/
BOOL WINAPI SetThreadDesktop( HANDLE hDesktop )
{
FIXME("(%x): stub\n",hDesktop);
return TRUE;
}
/******************************************************************************
* CreateIoCompletionPort
*/
@ -358,52 +270,3 @@ DWORD dwNumberOfConcurrentThreads)
FIXME("(%04x, %04x, %08lx, %08lx): stub.\n", hFileHandle, hExistingCompletionPort, dwCompletionKey, dwNumberOfConcurrentThreads);
return (HANDLE)NULL;
}
/******************************************************************************
* GetProcessDefaultLayout [USER32.802]
*
* Gets the default layout for parentless windows.
* Right now, just returns 0 (left-to-right).
*
* RETURNS
* Success: Nonzero
* Failure: Zero
*
* BUGS
* No RTL
*/
BOOL WINAPI GetProcessDefaultLayout( DWORD *pdwDefaultLayout )
{
if ( !pdwDefaultLayout ) {
SetLastError( ERROR_INVALID_PARAMETER );
return FALSE;
}
FIXME( "( %p ): No BiDi\n", pdwDefaultLayout );
*pdwDefaultLayout = 0;
return TRUE;
}
/******************************************************************************
* SetProcessDefaultLayout [USER32.803]
*
* Sets the default layout for parentless windows.
* Right now, only accepts 0 (left-to-right).
*
* RETURNS
* Success: Nonzero
* Failure: Zero
*
* BUGS
* No RTL
*/
BOOL WINAPI SetProcessDefaultLayout( DWORD dwDefaultLayout )
{
if ( dwDefaultLayout == 0 )
return TRUE;
FIXME( "( %08lx ): No BiDi\n", dwDefaultLayout );
SetLastError( ERROR_CALL_NOT_IMPLEMENTED );
return FALSE;
}

View file

@ -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;
}

View file

@ -8,6 +8,7 @@
#include <assert.h>
#include "windef.h"
#include "wingdi.h"
#include "winerror.h"
#include "wine/winbase16.h"
#include "wine/winuser16.h"
#include "miscemu.h"
@ -1660,3 +1661,88 @@ LONG WINAPI GetMessageExtraInfo(void)
return ret;
}
/**********************************************************************
* AttachThreadInput [USER32.8] Attaches input of 1 thread to other
*
* Attaches the input processing mechanism of one thread to that of
* another thread.
*
* RETURNS
* Success: TRUE
* Failure: FALSE
*
* TODO:
* 1. Reset the Key State (currenly per thread key state is not maintained)
*/
BOOL WINAPI AttachThreadInput(
DWORD idAttach, /* [in] Thread to attach */
DWORD idAttachTo, /* [in] Thread to attach to */
BOOL fAttach) /* [in] Attach or detach */
{
MESSAGEQUEUE *pSrcMsgQ = 0, *pTgtMsgQ = 0;
BOOL16 bRet = 0;
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
/* A thread cannot attach to itself */
if ( idAttach == idAttachTo )
goto CLEANUP;
/* According to the docs this method should fail if a
* "Journal record" hook is installed. (attaches all input queues together)
*/
if ( HOOK_IsHooked( WH_JOURNALRECORD ) )
goto CLEANUP;
/* Retrieve message queues corresponding to the thread id's */
pTgtMsgQ = (MESSAGEQUEUE *)QUEUE_Lock( GetThreadQueue16( idAttach ) );
pSrcMsgQ = (MESSAGEQUEUE *)QUEUE_Lock( GetThreadQueue16( idAttachTo ) );
/* Ensure we have message queues and that Src and Tgt threads
* are not system threads.
*/
if ( !pSrcMsgQ || !pTgtMsgQ || !pSrcMsgQ->pQData || !pTgtMsgQ->pQData )
goto CLEANUP;
if (fAttach) /* Attach threads */
{
/* Only attach if currently detached */
if ( pTgtMsgQ->pQData != pSrcMsgQ->pQData )
{
/* First release the target threads perQData */
PERQDATA_Release( pTgtMsgQ->pQData );
/* Share a reference to the source threads perQDATA */
PERQDATA_Addref( pSrcMsgQ->pQData );
pTgtMsgQ->pQData = pSrcMsgQ->pQData;
}
}
else /* Detach threads */
{
/* Only detach if currently attached */
if ( pTgtMsgQ->pQData == pSrcMsgQ->pQData )
{
/* First release the target threads perQData */
PERQDATA_Release( pTgtMsgQ->pQData );
/* Give the target thread its own private perQDATA once more */
pTgtMsgQ->pQData = PERQDATA_CreateInstance();
}
}
/* TODO: Reset the Key State */
bRet = 1; /* Success */
CLEANUP:
/* Unlock the queues before returning */
if ( pSrcMsgQ )
QUEUE_Unlock( pSrcMsgQ );
if ( pTgtMsgQ )
QUEUE_Unlock( pTgtMsgQ );
return bRet;
}

View file

@ -279,7 +279,7 @@ rc.left, rc.top, rc.right, rc.bottom, (UINT16)flags );
if( (dc = (DC *)GDI_GetObjPtr(hDC, DC_MAGIC)) )
{
if (dc->w.hVisRgn) {
wnd->pDriver->pSurfaceCopy(wnd,dc,dx,dy,&rc,bUpdate);
wnd->pDriver->pSurfaceCopy(wnd,hDC,dx,dy,&rc,bUpdate);
if( bUpdate )
{