Wine-devel
Threads by month
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2005 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2004 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2003 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2002 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2001 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
April 2003
- 120 participants
- 314 discussions
shorthair_kai(a)yahoo.com.cn wrote:
> I try to compile wine in mingw, is it possible?
> Can the compiled wine run in mingw?
What are you trying to do? We really can't advise you until
we understand why you're trying to build wine in mingw.
Please tell us a story about why you decided to try this,
and what you hope to get out of it.
> What I need?
> I installed the following package on my win2000:
> MinGW-2.0.0-3.exe
> MSYS-1.0.8.exe
> msysDTK-1.0.1.exe
> gdb-5.2.1.1-1.exe
> is it enough?
>
> But when I try, i got the following error:
> configure: error: no suitable bison/yacc found. Please
> install the 'bison' package.
> Where can I get the package?
Since I have no idea what you're trying to really do, and I've never
compiled Wine under MinGW or Cygwin, take this advice with a grain of salt:
You may be happier building under cygwin, which comes with bison.
MinGW is like a fork of cygwin.
Only difference is you'll need the --mno-cygwin option to the gcc commandline
to avoid linking with cygwin.dll.
- Dan
- Dan
--
Dan Kegel
http://www.kegel.com
http://counter.li.org/cgi-bin/runscript/display-person.cgi?user=78045
1
0
2 questions...
1. Is there any macro to dump out a hex dump of memory, eg.
TRACE_DUMP("Memory", pMem, numBytes);
If not, can I add one (inline in debug.h?)
2. When debugging using winedbg, is there any way to view the contents of a
lot of memory in one go (eg. hex dump of 256 bytes)?
Jason
4
4
Since the Slash Dot pice on Wine the server is dead
half the day....
Why not get the site on a new server
I know what you are going to say:
"Have you got one?"
:)
How about wine.sf.net?
You already have a project open on source forge is it
that difficult to move the site to their server?
I THINK they can handle the load
I assume there is some reason it has not been done but
if there is not any meager issue I think it will be
done at least for now (till the users stop coming :) )
What do you think?
Hatky.
__________________________________________________
Do you Yahoo!?
The New Yahoo! Search - Faster. Easier. Bingo
http://search.yahoo.com
3
3
Folks,
Mozilla officially builds on MinGW:
http://www.mozilla.org/build/win32.html#ss2.2
Bug #134113 tracking this effort was closed:
http://bugzilla.mozilla.org/show_bug.cgi?id=134113
Unfortunately, the new windres I was working on did
not make it in time for this release, so a bunch of
ugly hacks had to be checked in to work around various
problems, but hopefully we'll be able to remove them
in a few weeks, when the next binutils package is released.
We can now start looking into the real Winelib port. :)
--
Dimi.
1
0
hi,
am a newbee and in need of help about wine, following
are my querries. using wine20030408 on linux rhl 8.0
1. wine-devel doc says that the code for service
thread should be in scheduler/services.c, I could not
locate the file in my source code.
2. scheduler/pthread.c baffled me. It seems a pthread
implementation using windows code. The header says.
/*
* pthread emulation for re-entrant libcs
*
* We can't use pthreads directly, so why not let
libcs
* that want pthreads use Wine's own threading
*/
Why cannot we use pthreads directly ?
3. I get a SIGBUS and repeated SIGSEGV, keeps coming,
while running wine under gdb, this segv or sigbus is
not normally visible, I mean running without gdb.
This must be affecting the performance severly ?
How can i know which thread is causing this ?
gdb version is 5.2.1-4
4. The stack trace of sisegv looks like .....
for SIGBUS
#0 0x4207be77 in memset () from /lib/i686/libc.so.6
#1 0x00000010 in ?? ()
#2 0x400c4bf8 in NtAllocateVirtualMemory
(process=0xffffffff, ret=0x40722854,
addr=0x41920000, size_ptr=0x40722858, type=4096,
protect=64)
at virtual.c:1045
#3 0x400b6b57 in HEAP_FindFreeBlock (heap=0x418f0000,
size=65040,
ppSubHeap=0x40722884) at heap.c:340
#4 0x400b74a5 in RtlAllocateHeap (heap=0x418f0000,
flags=3, size=65040)
at heap.c:1102
#5 0x004014f6 in ?? ()
==========================================
FOR SIGSEGV
#0 RtlImageNtHeader (hModule=0x0) at loader.c:1242
#1 0x400ba560 in RtlImageDirectoryEntryToData
(module=0x0, image=1, dir=0,
size=0x40722650) at loader.c:1270
#2 0x400b97c7 in LdrGetProcedureAddress (module=0x0,
name=0x4072267c, ord=0,
address=0x40722678) at loader.c:754
#3 0x4007c8f9 in GetProcAddress (hModule=0x0,
function=0xac46c4 "IID_ITextServices") at
../../loader/module.c:1053
#4 0x0046b5ed in ?? ()
#5 0x006074d7 in ?? ()
#6 0x00467708 in ?? ()
#7 0x00469e99 in ?? ()
#8 0x00607865 in ?? ()
#9 0x004671ae in ?? ()
#10 0x004610f1 in ?? ()
#11 0x00466ffa in ?? ()
#12 0x00466fa5 in ?? ()
#13 0x00463e07 in ?? ()
#14 0x0040b610 in ?? ()
#15 0x00463c22 in ?? ()
#16 0x00431979 in ?? ()
#17 0x00462662 in ?? ()
#18 0x00463a94 in ?? ()
#19 0x00463a0d in ?? ()
#20 0x004631b2 in ?? ()
----------------------------------------
Please help me to know what are these functions ?? ()
tia
-kks
__________________________________________________
Do you Yahoo!?
The New Yahoo! Search - Faster. Easier. Bingo
http://search.yahoo.com
2
1
Thanks, I already have some code in the form of libegg, but I suspect
Chris' code might be clearer.
Chris - if you have any tips or could send me that code, it'd be good.
Just remember that if you start getting it to work with Wine, please
drop me a line.
On Fri, 2003-04-25 at 04:09, Mike McCormack wrote:
> Hi Mike,
>
> Now is a good time to mention to you that Chris Hoff did some work on
> getting XEmbed to work with Wine. As far as I know, he had a standalone
> program that could put something in the gnome toolbar, but no Wine code.
>
> You might want to write him an email to see how far he got with it.
>
> Mike
>
> Mike Hearn wrote:
>
> > I don't really have any, I'm much happier now that the policy has been
> > made clear. It seems fine to me. No promised on xembed though ;)
>
--
Mike Hearn <m.hearn(a)signal.qinetiq.com>
QinetiQ - Malvern Technology Center
1
0
Changelog:
Adds wintab32 support using XInput. Merged from CrossOver Office.
I am including this on the wine-devel list because there was discussion
and comment about it there.
-aric
Index: dlls/wintab32/Makefile.in
===================================================================
RCS file: /home/wine/wine/dlls/wintab32/Makefile.in,v
retrieving revision 1.2
diff -u -r1.2 Makefile.in
--- dlls/wintab32/Makefile.in 23 Mar 2003 20:00:02 -0000 1.2
+++ dlls/wintab32/Makefile.in 23 Apr 2003 13:55:27 -0000
@@ -3,7 +3,7 @@
SRCDIR = @srcdir@
VPATH = @srcdir@
MODULE = wintab32.dll
-IMPORTS = kernel32
+IMPORTS = kernel32 user32
ALTNAMES = wintab.dll
LDDLLFLAGS = @LDDLLFLAGS@
@@ -13,7 +13,8 @@
C_SRCS = \
context.c \
- manager.c
+ manager.c \
+ wintab32.c
C_SRCS16 = \
wintab16.c
Index: dlls/wintab32/context.c
===================================================================
RCS file: /home/wine/wine/dlls/wintab32/context.c,v
retrieving revision 1.1
diff -u -r1.1 context.c
--- dlls/wintab32/context.c 17 Dec 2002 01:49:16 -0000 1.1
+++ dlls/wintab32/context.c 23 Apr 2003 13:55:27 -0000
@@ -2,6 +2,7 @@
* Tablet Context
*
* Copyright 2002 Patrik Stridvall
+ * Copyright 2003 Codeweavers, Aric Stewart
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -19,27 +20,737 @@
*/
#include "config.h"
+#include <stdio.h>
+#include <stdlib.h>
-#include "windef.h"
#include "winbase.h"
+#include "windef.h"
#include "winerror.h"
+#include "winuser.h"
+#include "user.h"
#include "wintab.h"
+#include "wintab_internal.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(wintab32);
+/*
+ * Documentation found at
+ * http://www.csl.sony.co.jp/projects/ar/restricted/wintabl.html
+ */
+
+#define CURSORMAX 10
+
+BOOL gLoaded= FALSE;
+LOGCONTEXTA gSysContext;
+WTI_CURSORS_INFO gSysCursor[CURSORMAX];
+WTI_DEVICES_INFO gSysDevice;
+INT gNumCursors;
+
+LPOPENCONTEXT gOpenContexts = NULL;
+INT gContextCount = 0;
+HCTX gTopContext = (HCTX)0xc00;
+
+extern HWND hwndDefault;
+extern CRITICAL_SECTION csTablet;
+
+char* DUMPBITS(int x, char* buf)
+{
+ strcpy(buf,"{");
+ if (x&PK_CONTEXT) strcat(buf,"PK_CONTEXT ");
+ if (x&PK_STATUS) strcat(buf, "PK_STATUS ");
+ if (x&PK_TIME) strcat(buf, "PK_TIME ");
+ if (x&PK_CHANGED) strcat(buf, "PK_CHANGED ");
+ if (x&PK_SERIAL_NUMBER) strcat(buf, "PK_SERIAL_NUMBER ");
+ if (x&PK_CURSOR) strcat(buf, "PK_CURSOR ");
+ if (x&PK_BUTTONS) strcat(buf, "PK_BUTTONS ");
+ if (x&PK_X) strcat(buf, "PK_X ");
+ if (x&PK_Y) strcat(buf, "PK_Y ");
+ if (x&PK_Z) strcat(buf, "PK_Z ");
+ if (x&PK_NORMAL_PRESSURE) strcat(buf, "PK_NORMAL_PRESSURE ");
+ if (x&PK_TANGENT_PRESSURE) strcat(buf, "PK_TANGENT_PRESSURE ");
+ if (x&PK_ORIENTATION) strcat(buf, "PK_ORIENTATION ");
+ if (x&PK_ROTATION) strcat(buf, "PK_ROTATION ");
+ strcat(buf, "}");
+ return buf;
+}
+
+static inline void DUMPPACKET(WTPACKET packet)
+{
+ TRACE("pkContext: 0x%x pkStatus: 0x%x pkTime : 0x%x pkChanged: 0x%x pkSerialNumber: 0x%x pkCursor : %i pkButtons: %x pkX: %li pkY: %li pkZ: %li pkNormalPressure: %i pkTangentPressure: %i pkOrientation: (%i,%i,%i) pkRotation: (%i,%i,%i)\n"
+,(UINT)packet.pkContext,
+ (UINT)packet.pkStatus,
+ (UINT)packet.pkTime,
+ (UINT)packet.pkChanged,
+ packet.pkSerialNumber,
+ packet.pkCursor,
+ (UINT)packet.pkButtons,
+ packet.pkX,
+ packet.pkY,
+ packet.pkZ,
+ packet.pkNormalPressure,
+ packet.pkTangentPressure,
+ packet.pkOrientation.orAzimuth,
+ packet.pkOrientation.orAltitude, packet.pkOrientation.orTwist,
+ packet.pkRotation.roPitch,
+ packet.pkRotation.roRoll, packet.pkRotation.roYaw);
+}
+
+static inline void DUMPCONTEXT(LOGCONTEXTA lc)
+{
+ CHAR mmsg[4000];
+ CHAR bits[100];
+ CHAR bits1[100];
+ CHAR bits2[100];
+
+ sprintf(mmsg,"%s, %x, %x, %x, %x, %x, %x, %x%s, %x%s, %x%s, %x, %x, %i, %i, %i, %li ,%li, %li, %li, %li, %li,%li, %li, %li, %li, %li, %li, %i, %i, %i, %i, %i %li %li\n",
+ debugstr_a(lc.lcName), lc.lcOptions, lc.lcStatus, lc.lcLocks, lc.lcMsgBase,
+lc.lcDevice, lc.lcPktRate, (UINT)lc.lcPktData, DUMPBITS(lc.lcPktData,bits),
+(UINT)lc.lcPktMode, DUMPBITS(lc.lcPktMode,bits1), (UINT)lc.lcMoveMask,
+DUMPBITS(lc.lcMoveMask,bits2), (INT)lc.lcBtnDnMask, (INT)lc.lcBtnUpMask,
+(INT)lc.lcInOrgX, (INT)lc.lcInOrgY, (INT)lc.lcInOrgZ, lc.lcInExtX, lc.lcInExtY,
+lc.lcInExtZ, lc.lcOutOrgX, lc.lcOutOrgY, lc.lcOutOrgZ, lc.lcOutExtX,
+lc.lcOutExtY, lc.lcOutExtZ, lc.lcSensX, lc.lcSensY, lc.lcSensZ, lc.lcSysMode,
+lc.lcSysOrgX, lc.lcSysOrgY, lc.lcSysExtX, lc.lcSysExtY, lc.lcSysSensX,
+lc.lcSysSensY);
+ TRACE("context: %s",mmsg);
+}
+
+
+/* Find an open context given the handle */
+LPOPENCONTEXT TABLET_FindOpenContext(HCTX hCtx)
+{
+ LPOPENCONTEXT ptr = gOpenContexts;
+ while (ptr)
+ {
+ if (ptr->handle == hCtx) return ptr;
+ ptr = ptr->next;
+ }
+ return NULL;
+}
+
+static void LoadTablet()
+{
+ TRACE("Initilizing the tablet to hwnd 0x%x\n",(INT)hwndDefault);
+ gLoaded= TRUE;
+ memset(&gSysContext,0,sizeof(LOGCONTEXTA));
+ memset(&gSysDevice,0,sizeof(WTI_DEVICES_INFO));
+ memset(gSysCursor,0,sizeof(WTI_CURSORS_INFO)*gNumCursors);
+ gNumCursors = pLoadTabletInfo(&gSysContext, &gSysDevice, gSysCursor,
+ CURSORMAX, hwndDefault);
+}
+
+int TABLET_PostTabletMessage(LPOPENCONTEXT newcontext, UINT msg, WPARAM wParam,
+ LPARAM lParam, BOOL send_always)
+{
+ if ((send_always) || (newcontext->context.lcOptions & CXO_MESSAGES))
+ {
+ TRACE("Posting message %x to %x\n",msg, (UINT)newcontext->hwndOwner);
+ return PostMessageA(newcontext->hwndOwner, msg, wParam, lParam);
+ }
+ return 0;
+}
+
+static inline DWORD ScaleForContext(DWORD In, DWORD InOrg, DWORD InExt, DWORD
+ OutOrg, DWORD OutExt)
+{
+ if (((InExt > 0 )&&(OutExt > 0)) || ((InExt<0) && (OutExt < 0)))
+ return ((In - InOrg) * abs(OutExt) / abs(InExt)) + OutOrg;
+ else
+ return ((abs(InExt) - (In - InOrg))*abs(OutExt) / abs(InExt)) + OutOrg;
+}
+
+LPOPENCONTEXT FindOpenContext(HWND hwnd)
+{
+ LPOPENCONTEXT ptr=NULL;
+ ptr = gOpenContexts;
+ while (ptr)
+ {
+ TRACE("Trying Context %lx (%x %x)\n",(LONG)ptr->handle,(INT)hwnd,
+ (INT)ptr->hwndOwner);
+
+ if (ptr->hwndOwner == hwnd)
+ return ptr;
+ }
+ return NULL;
+}
+
+LPOPENCONTEXT AddPacketToContextQueue(LPWTPACKET packet, HWND hwnd)
+{
+ LPOPENCONTEXT ptr=NULL;
+
+ EnterCriticalSection(&csTablet);
+
+ ptr = gOpenContexts;
+ while (ptr)
+ {
+ TRACE("Trying Queue %lx (%x %x)\n",(LONG)ptr->handle,(INT)hwnd,
+ (INT)ptr->hwndOwner);
+
+ if (ptr->hwndOwner == hwnd)
+ {
+ int tgt;
+ if (!ptr->enabled)
+ {
+ ptr = ptr->next;
+ continue;
+ }
+
+ tgt = ptr->PacketsQueued;
+
+ packet->pkContext = ptr->handle;
+
+ /* translate packet data to the context */
+
+ /* Scale as per documentation */
+ packet->pkY = ScaleForContext(packet->pkY, ptr->context.lcInOrgY,
+ ptr->context.lcInExtY, ptr->context.lcOutOrgY,
+ ptr->context.lcOutExtY);
+
+ packet->pkX = ScaleForContext(packet->pkX, ptr->context.lcInOrgX,
+ ptr->context.lcInExtX, ptr->context.lcOutOrgX,
+ ptr->context.lcOutExtX);
+
+ /* flip the Y axis */
+ if (ptr->context.lcOutExtY > 0)
+ packet->pkY = ptr->context.lcOutExtY - packet->pkY;
+
+ DUMPPACKET(*packet);
+
+ if (tgt + 1 == ptr->QueueSize)
+ {
+ TRACE("Queue Overflow %p\n",ptr->handle);
+ packet->pkStatus = TPS_QUEUE_ERR;
+ }
+ else
+ {
+ TRACE("Placed in queue %p index %i\n",ptr->handle,tgt);
+ memcpy(&ptr->PacketQueue[tgt], packet, sizeof
+ (WTPACKET));
+ ptr->PacketsQueued++;
+
+ if (ptr->ActiveCursor != packet->pkCursor)
+ {
+ ptr->ActiveCursor = packet->pkCursor;
+ if (ptr->context.lcOptions & CXO_CSRMESSAGES)
+ TABLET_PostTabletMessage(ptr, WT_CSRCHANGE,
+ (WPARAM)packet->pkSerialNumber, (LPARAM)ptr->handle,
+ FALSE);
+ }
+ }
+ break;
+ }
+ ptr = ptr->next;
+ }
+ LeaveCriticalSection(&csTablet);
+ TRACE("Done (%p)\n",ptr);
+ return ptr;
+}
+
+int static inline CopyTabletData(LPVOID target, LPVOID src, INT size)
+{
+ memcpy(target,src,size);
+ return(size);
+}
+
+static INT TABLET_FindPacket(LPOPENCONTEXT context, UINT wSerial,
+ LPWTPACKET *pkt)
+{
+ int loop;
+ int index = -1;
+ for (loop = 0; loop < context->PacketsQueued; loop++)
+ if (context->PacketQueue[loop].pkSerialNumber == wSerial)
+ {
+ index = loop;
+ *pkt = &context->PacketQueue[loop];
+ break;
+ }
+
+ TRACE("%i .. %i\n",context->PacketsQueued,index);
+
+ return index;
+}
+
+
+static LPVOID TABLET_CopyPacketData(LPOPENCONTEXT context, LPVOID lpPkt,
+ LPWTPACKET wtp)
+{
+ LPBYTE ptr;
+ CHAR bits[100];
+
+ ptr = lpPkt;
+ TRACE("Packet Bits %s\n",DUMPBITS(context->context.lcPktData,bits));
+
+ if (context->context.lcPktData & PK_CONTEXT)
+ ptr+=CopyTabletData(ptr,&wtp->pkContext,sizeof(HCTX));
+ if (context->context.lcPktData & PK_STATUS)
+ ptr+=CopyTabletData(ptr,&wtp->pkStatus,sizeof(UINT));
+ if (context->context.lcPktData & PK_TIME)
+ ptr+=CopyTabletData(ptr,&wtp->pkTime,sizeof(LONG));
+ if (context->context.lcPktData & PK_CHANGED)
+ ptr+=CopyTabletData(ptr,&wtp->pkChanged,sizeof(WTPKT));
+ if (context->context.lcPktData & PK_SERIAL_NUMBER)
+ ptr+=CopyTabletData(ptr,&wtp->pkChanged,sizeof(UINT));
+ if (context->context.lcPktData & PK_CURSOR)
+ ptr+=CopyTabletData(ptr,&wtp->pkCursor,sizeof(UINT));
+ if (context->context.lcPktData & PK_BUTTONS)
+ ptr+=CopyTabletData(ptr,&wtp->pkButtons,sizeof(DWORD));
+ if (context->context.lcPktData & PK_X)
+ ptr+=CopyTabletData(ptr,&wtp->pkX,sizeof(DWORD));
+ if (context->context.lcPktData & PK_Y)
+ ptr+=CopyTabletData(ptr,&wtp->pkY,sizeof(DWORD));
+ if (context->context.lcPktData & PK_Z)
+ ptr+=CopyTabletData(ptr,&wtp->pkZ,sizeof(DWORD));
+ if (context->context.lcPktData & PK_NORMAL_PRESSURE)
+ ptr+=CopyTabletData(ptr,&wtp->pkNormalPressure,sizeof(UINT));
+ if (context->context.lcPktData & PK_TANGENT_PRESSURE)
+ ptr+=CopyTabletData(ptr,&wtp->pkTangentPressure,sizeof(UINT));
+ if (context->context.lcPktData & PK_ORIENTATION)
+ ptr+=CopyTabletData(ptr,&wtp->pkOrientation,sizeof(ORIENTATION));
+ if (context->context.lcPktData & PK_ROTATION)
+ ptr+=CopyTabletData(ptr,&wtp->pkRotation,sizeof(ROTATION));
+
+ //TRACE("Copied %i bytes\n",(INT)ptr - (INT)lpPkt);
+ return ptr;
+}
+
+static VOID TABLET_BlankPacketData(LPOPENCONTEXT context, LPVOID lpPkt, INT n)
+{
+ int rc = 0;
+
+ if (context->context.lcPktData & PK_CONTEXT)
+ rc +=sizeof(HCTX);
+ if (context->context.lcPktData & PK_STATUS)
+ rc +=sizeof(UINT);
+ if (context->context.lcPktData & PK_TIME)
+ rc += sizeof(LONG);
+ if (context->context.lcPktData & PK_CHANGED)
+ rc += sizeof(WTPKT);
+ if (context->context.lcPktData & PK_SERIAL_NUMBER)
+ rc += sizeof(UINT);
+ if (context->context.lcPktData & PK_CURSOR)
+ rc += sizeof(UINT);
+ if (context->context.lcPktData & PK_BUTTONS)
+ rc += sizeof(DWORD);
+ if (context->context.lcPktData & PK_X)
+ rc += sizeof(DWORD);
+ if (context->context.lcPktData & PK_Y)
+ rc += sizeof(DWORD);
+ if (context->context.lcPktData & PK_Z)
+ rc += sizeof(DWORD);
+ if (context->context.lcPktData & PK_NORMAL_PRESSURE)
+ rc += sizeof(UINT);
+ if (context->context.lcPktData & PK_TANGENT_PRESSURE)
+ rc += sizeof(UINT);
+ if (context->context.lcPktData & PK_ORIENTATION)
+ rc += sizeof(ORIENTATION);
+ if (context->context.lcPktData & PK_ROTATION)
+ rc += sizeof(ROTATION);
+
+ rc *= n;
+ memset(lpPkt,0,rc);
+}
+
+
/***********************************************************************
* WTInfoA (WINTAB32.20)
*/
UINT WINAPI WTInfoA(UINT wCategory, UINT nIndex, LPVOID lpOutput)
{
- FIXME("(%u, %u, %p): stub\n", wCategory, nIndex, lpOutput);
-
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-
- return 0;
+ int rc = 0;
+ LPWTI_CURSORS_INFO tgtcursor;
+ TRACE("(%u, %u, %p)\n", wCategory, nIndex, lpOutput);
+
+ if (gLoaded == FALSE)
+ LoadTablet();
+ switch(wCategory)
+ {
+ case 0:
+ /* return largest nessecary buffer */
+ TRACE("%i cursors\n",gNumCursors);
+ if (gNumCursors>0)
+ {
+ FIXME("Return proper size\n");
+ return 200;
+ }
+ else
+ return 0;
+ break;
+ case WTI_INTERFACE:
+ switch (nIndex)
+ {
+ WORD version;
+ case IFC_WINTABID:
+ strcpy(lpOutput,"Wine Wintab 1.1");
+ rc = 16;
+ break;
+ case IFC_SPECVERSION:
+ version = (0x01) | (0x01 << 8);
+ rc = CopyTabletData(lpOutput, &version,sizeof(WORD));
+ break;
+ case IFC_IMPLVERSION:
+ version = (0x00) | (0x01 << 8);
+ rc = CopyTabletData(lpOutput, &version,sizeof(WORD));
+ break;
+ default:
+ FIXME("WTI_INTERFACE unhandled index %i\n",nIndex);
+ rc = 0;
+
+ }
+ case WTI_DEFSYSCTX:
+ case WTI_DDCTXS:
+ case WTI_DEFCONTEXT:
+ DUMPCONTEXT(gSysContext);
+ switch (nIndex)
+ {
+ case 0:
+ memcpy(lpOutput, &gSysContext,
+ sizeof(LOGCONTEXTA));
+ rc = sizeof(LOGCONTEXTA);
+ break;
+ case CTX_NAME:
+ rc = CopyTabletData(lpOutput, &gSysContext.lcName,
+ strlen(gSysContext.lcName)+1);
+ break;
+ case CTX_OPTIONS:
+ rc = CopyTabletData(lpOutput, &gSysContext.lcOptions,
+ sizeof(UINT));
+ break;
+ case CTX_STATUS:
+ rc = CopyTabletData(lpOutput, &gSysContext.lcStatus,
+ sizeof(UINT));
+ break;
+ case CTX_LOCKS:
+ rc= CopyTabletData (lpOutput, &gSysContext.lcLocks,
+ sizeof(UINT));
+ break;
+ case CTX_MSGBASE:
+ rc = CopyTabletData(lpOutput, &gSysContext.lcMsgBase,
+ sizeof(UINT));
+ break;
+ case CTX_DEVICE:
+ rc = CopyTabletData(lpOutput, &gSysContext.lcDevice,
+ sizeof(UINT));
+ break;
+ case CTX_PKTRATE:
+ rc = CopyTabletData(lpOutput, &gSysContext.lcPktRate,
+ sizeof(UINT));
+ break;
+ case CTX_PKTMODE:
+ rc = CopyTabletData(lpOutput, &gSysContext.lcPktMode,
+ sizeof(WTPKT));
+ break;
+ case CTX_MOVEMASK:
+ rc = CopyTabletData(lpOutput, &gSysContext.lcMoveMask,
+ sizeof(WTPKT));
+ break;
+ case CTX_BTNDNMASK:
+ rc = CopyTabletData(lpOutput, &gSysContext.lcBtnDnMask,
+ sizeof(DWORD));
+ break;
+ case CTX_BTNUPMASK:
+ rc = CopyTabletData(lpOutput, &gSysContext.lcBtnUpMask,
+ sizeof(DWORD));
+ break;
+ case CTX_INORGX:
+ rc = CopyTabletData(lpOutput, &gSysContext.lcInOrgX,
+ sizeof(LONG));
+ break;
+ case CTX_INORGY:
+ rc = CopyTabletData(lpOutput, &gSysContext.lcInOrgY,
+ sizeof(LONG));
+ break;
+ case CTX_INORGZ:
+ rc = CopyTabletData(lpOutput, &gSysContext.lcInOrgZ,
+ sizeof(LONG));
+ break;
+ case CTX_INEXTX:
+ rc = CopyTabletData(lpOutput, &gSysContext.lcInExtX,
+ sizeof(LONG));
+ break;
+ case CTX_INEXTY:
+ rc = CopyTabletData(lpOutput, &gSysContext.lcInExtY,
+ sizeof(LONG));
+ break;
+ case CTX_INEXTZ:
+ rc = CopyTabletData(lpOutput, &gSysContext.lcInExtZ,
+ sizeof(LONG));
+ break;
+ case CTX_OUTORGX:
+ rc = CopyTabletData(lpOutput, &gSysContext.lcOutOrgX,
+ sizeof(LONG));
+ break;
+ case CTX_OUTORGY:
+ rc = CopyTabletData(lpOutput, &gSysContext.lcOutOrgY,
+ sizeof(LONG));
+ break;
+ case CTX_OUTORGZ:
+ rc = CopyTabletData(lpOutput, &gSysContext.lcOutOrgZ,
+ sizeof(LONG));
+ break;
+ case CTX_OUTEXTX:
+ rc = CopyTabletData(lpOutput, &gSysContext.lcOutExtX,
+ sizeof(LONG));
+ break;
+ case CTX_OUTEXTY:
+ rc = CopyTabletData(lpOutput, &gSysContext.lcOutExtY,
+ sizeof(LONG));
+ break;
+ case CTX_OUTEXTZ:
+ rc = CopyTabletData(lpOutput, &gSysContext.lcOutExtZ,
+ sizeof(LONG));
+ break;
+ case CTX_SENSX:
+ rc = CopyTabletData(lpOutput, &gSysContext.lcSensX,
+ sizeof(LONG));
+ break;
+ case CTX_SENSY:
+ rc = CopyTabletData(lpOutput, &gSysContext.lcSensY,
+ sizeof(LONG));
+ break;
+ case CTX_SENSZ:
+ rc = CopyTabletData(lpOutput, &gSysContext.lcSensZ,
+ sizeof(LONG));
+ break;
+ case CTX_SYSMODE:
+ rc = CopyTabletData(lpOutput, &gSysContext.lcSysMode,
+ sizeof(LONG));
+ break;
+ case CTX_SYSORGX:
+ rc = CopyTabletData(lpOutput, &gSysContext.lcSysOrgX,
+ sizeof(LONG));
+ break;
+ case CTX_SYSORGY:
+ rc = CopyTabletData(lpOutput, &gSysContext.lcSysOrgY,
+ sizeof(LONG));
+ break;
+ case CTX_SYSEXTX:
+ rc = CopyTabletData(lpOutput, &gSysContext.lcSysExtX,
+ sizeof(LONG));
+ break;
+ case CTX_SYSEXTY:
+ rc = CopyTabletData(lpOutput, &gSysContext.lcSysExtY,
+ sizeof(LONG));
+ break;
+ case CTX_SYSSENSX:
+ rc = CopyTabletData(lpOutput, &gSysContext.lcSysSensX,
+ sizeof(LONG));
+ break;
+ case CTX_SYSSENSY:
+ rc = CopyTabletData(lpOutput, &gSysContext.lcSysSensY,
+ sizeof(LONG));
+ break;
+ default:
+ FIXME("WTI_DEFSYSCTX unhandled index %i\n",nIndex);
+ rc = 0;
+ }
+ break;
+ case WTI_CURSORS:
+ case WTI_CURSORS+1:
+ case WTI_CURSORS+2:
+ case WTI_CURSORS+3:
+ case WTI_CURSORS+4:
+ case WTI_CURSORS+5:
+ case WTI_CURSORS+6:
+ case WTI_CURSORS+7:
+ case WTI_CURSORS+8:
+ case WTI_CURSORS+9:
+ case WTI_CURSORS+10:
+ tgtcursor = &gSysCursor[wCategory - WTI_CURSORS];
+ switch (nIndex)
+ {
+ case CSR_NAME:
+ rc = CopyTabletData(lpOutput, &tgtcursor->NAME,
+ strlen(tgtcursor->NAME)+1);
+ break;
+ case CSR_ACTIVE:
+ rc = CopyTabletData(lpOutput,&tgtcursor->ACTIVE,
+ sizeof(BOOL));
+ break;
+ case CSR_PKTDATA:
+ rc = CopyTabletData(lpOutput,&tgtcursor->PKTDATA,
+ sizeof(WTPKT));
+ break;
+ case CSR_BUTTONS:
+ rc = CopyTabletData(lpOutput,&tgtcursor->BUTTONS,
+ sizeof(BYTE));
+ break;
+ case CSR_BUTTONBITS:
+ rc = CopyTabletData(lpOutput,&tgtcursor->BUTTONBITS,
+ sizeof(BYTE));
+ break;
+ case CSR_BTNNAMES:
+ FIXME("Button Names not returned correctly\n");
+ rc = CopyTabletData(lpOutput,&tgtcursor->BTNNAMES,
+ strlen(tgtcursor->BTNNAMES)+1);
+ break;
+ case CSR_BUTTONMAP:
+ rc = CopyTabletData(lpOutput,&tgtcursor->BUTTONMAP,
+ sizeof(BYTE)*32);
+ break;
+ case CSR_SYSBTNMAP:
+ rc = CopyTabletData(lpOutput,&tgtcursor->SYSBTNMAP,
+ sizeof(BYTE)*32);
+ break;
+ case CSR_NPBTNMARKS:
+ memcpy(lpOutput,&tgtcursor->NPBTNMARKS,sizeof(UINT)*2);
+ rc = sizeof(UINT)*2;
+ break;
+ case CSR_NPBUTTON:
+ rc = CopyTabletData(lpOutput,&tgtcursor->NPBUTTON,
+ sizeof(BYTE));
+ break;
+ case CSR_NPRESPONSE:
+ FIXME("Not returning CSR_NPRESPONSE correctly\n");
+ rc = 0;
+ break;
+ case CSR_TPBUTTON:
+ rc = CopyTabletData(lpOutput,&tgtcursor->TPBUTTON,
+ sizeof(BYTE));
+ break;
+ case CSR_TPBTNMARKS:
+ memcpy(lpOutput,&tgtcursor->TPBTNMARKS,sizeof(UINT)*2);
+ rc = sizeof(UINT)*2;
+ break;
+ case CSR_TPRESPONSE:
+ FIXME("Not returning CSR_TPRESPONSE correctly\n");
+ rc = 0;
+ break;
+ case CSR_PHYSID:
+ {
+ DWORD id;
+ rc = CopyTabletData(&id,&tgtcursor->PHYSID,
+ sizeof(DWORD));
+ id += (wCategory - WTI_CURSORS);
+ memcpy(lpOutput,&id,sizeof(DWORD));
+ }
+ break;
+ case CSR_MODE:
+ rc = CopyTabletData(lpOutput,&tgtcursor->MODE,sizeof(UINT));
+ break;
+ case CSR_MINPKTDATA:
+ rc = CopyTabletData(lpOutput,&tgtcursor->MINPKTDATA,
+ sizeof(UINT));
+ break;
+ case CSR_MINBUTTONS:
+ rc = CopyTabletData(lpOutput,&tgtcursor->MINBUTTONS,
+ sizeof(UINT));
+ break;
+ case CSR_CAPABILITIES:
+ rc = CopyTabletData(lpOutput,&tgtcursor->CAPABILITIES,
+ sizeof(UINT));
+ break;
+ case CSR_TYPE:
+ rc = CopyTabletData(lpOutput,&tgtcursor->TYPE,
+ sizeof(UINT));
+ break;
+ default:
+ FIXME("WTI_CURSORS unhandled index %i\n",nIndex);
+ rc = 0;
+ }
+ break;
+ case WTI_DEVICES:
+ switch (nIndex)
+ {
+ case DVC_NAME:
+ rc = CopyTabletData(lpOutput,gSysDevice.NAME,
+ strlen(gSysDevice.NAME)+1);
+ break;
+ case DVC_HARDWARE:
+ rc = CopyTabletData(lpOutput,&gSysDevice.HARDWARE,
+ sizeof(UINT));
+ break;
+ case DVC_NCSRTYPES:
+ rc = CopyTabletData(lpOutput,&gSysDevice.NCSRTYPES,
+ sizeof(UINT));
+ break;
+ case DVC_FIRSTCSR:
+ rc = CopyTabletData(lpOutput,&gSysDevice.FIRSTCSR,
+ sizeof(UINT));
+ break;
+ case DVC_PKTRATE:
+ rc = CopyTabletData(lpOutput,&gSysDevice.PKTRATE,
+ sizeof(UINT));
+ break;
+ case DVC_PKTDATA:
+ rc = CopyTabletData(lpOutput,&gSysDevice.PKTDATA,
+ sizeof(WTPKT));
+ break;
+ case DVC_PKTMODE:
+ rc = CopyTabletData(lpOutput,&gSysDevice.PKTMODE,
+ sizeof(WTPKT));
+ break;
+ case DVC_CSRDATA:
+ rc = CopyTabletData(lpOutput,&gSysDevice.CSRDATA,
+ sizeof(WTPKT));
+ break;
+ case DVC_XMARGIN:
+ rc = CopyTabletData(lpOutput,&gSysDevice.XMARGIN,
+ sizeof(INT));
+ break;
+ case DVC_YMARGIN:
+ rc = CopyTabletData(lpOutput,&gSysDevice.YMARGIN,
+ sizeof(INT));
+ break;
+ case DVC_ZMARGIN:
+ rc = 0; /* unsupported */
+ /*
+ rc = CopyTabletData(lpOutput,&gSysDevice.ZMARGIN,
+ sizeof(INT));
+ */
+ break;
+ case DVC_X:
+ rc = CopyTabletData(lpOutput,&gSysDevice.X,
+ sizeof(AXIS));
+ break;
+ case DVC_Y:
+ rc = CopyTabletData(lpOutput,&gSysDevice.Y,
+ sizeof(AXIS));
+ break;
+ case DVC_Z:
+ rc = 0; /* unsupported */
+ /*
+ rc = CopyTabletData(lpOutput,&gSysDevice.Z,
+ sizeof(AXIS));
+ */
+ break;
+ case DVC_NPRESSURE:
+ rc = CopyTabletData(lpOutput,&gSysDevice.NPRESSURE,
+ sizeof(AXIS));
+ break;
+ case DVC_TPRESSURE:
+ rc = 0; /* unsupported */
+ /*
+ rc = CopyTabletData(lpOutput,&gSysDevice.TPRESSURE,
+ sizeof(AXIS));
+ */
+ break;
+ case DVC_ORIENTATION:
+ memcpy(lpOutput,&gSysDevice.ORIENTATION,sizeof(AXIS)*3);
+ rc = sizeof(AXIS)*3;
+ break;
+ case DVC_ROTATION:
+ rc = 0; /* unsupported */
+ /*
+ memcpy(lpOutput,&gSysDevice.ROTATION,sizeof(AXIS)*3);
+ rc = sizeof(AXIS)*3;
+ */
+ break;
+ case DVC_PNPID:
+ rc = CopyTabletData(lpOutput,gSysDevice.PNPID,
+ strlen(gSysDevice.PNPID)+1);
+ break;
+ default:
+ FIXME("WTI_DEVICES unhandled index %i\n",nIndex);
+ rc = 0;
+ }
+ break;
+ default:
+ FIXME("Unhandled Category %i\n",wCategory);
+ }
+ return rc;
}
/***********************************************************************
@@ -59,11 +770,38 @@
*/
HCTX WINAPI WTOpenA(HWND hWnd, LPLOGCONTEXTA lpLogCtx, BOOL fEnable)
{
- FIXME("(%p, %p, %u): stub\n", hWnd, lpLogCtx, fEnable);
+ LPOPENCONTEXT newcontext;
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+ TRACE("(%p, %p, %u)\n", hWnd, lpLogCtx, fEnable);
+ DUMPCONTEXT(*lpLogCtx);
- return NULL;
+ newcontext = HeapAlloc(GetProcessHeap(), 0 , sizeof(OPENCONTEXT));
+ memcpy(&(newcontext->context),lpLogCtx,sizeof(LOGCONTEXTA));
+ newcontext->hwndOwner = hWnd;
+ newcontext->enabled = fEnable;
+ newcontext->ActiveCursor = -1;
+ newcontext->QueueSize = 10;
+ newcontext->PacketsQueued = 0;
+ newcontext->PacketQueue=HeapAlloc(GetProcessHeap(),0,sizeof(WTPACKET)*10);
+ newcontext->handle = gTopContext++;
+ newcontext->next = gOpenContexts;
+
+ EnterCriticalSection(&csTablet);
+ gOpenContexts = newcontext;
+ LeaveCriticalSection(&csTablet);
+
+ pAttachEventQueueToTablet(hWnd, gSysCursor, gNumCursors);
+
+ TABLET_PostTabletMessage(newcontext, WT_CTXOPEN, (WPARAM)newcontext->handle,
+ newcontext->context.lcStatus, TRUE);
+
+ newcontext->context.lcStatus = CXS_ONTOP;
+
+ TABLET_PostTabletMessage(newcontext, WT_CTXOVERLAP,
+ (WPARAM)newcontext->handle,
+ newcontext->context.lcStatus, TRUE);
+
+ return newcontext->handle;
}
/***********************************************************************
@@ -83,9 +821,32 @@
*/
BOOL WINAPI WTClose(HCTX hCtx)
{
- FIXME("(%p): stub\n", hCtx);
+ LPOPENCONTEXT context,ptr;
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+ TRACE("(%p)\n", hCtx);
+
+ ptr = context = gOpenContexts;
+
+ while ((context->handle != hCtx) && (context))
+ {
+ ptr = context;
+ context = context->next;
+ }
+ if (!context)
+ return TRUE;
+
+ EnterCriticalSection(&csTablet);
+ if (context == gOpenContexts)
+ gOpenContexts = context->next;
+ else
+ ptr->next = context->next;
+ LeaveCriticalSection(&csTablet);
+
+ TABLET_PostTabletMessage(context, WT_CTXCLOSE, (WPARAM)context->handle,
+ context->context.lcStatus,TRUE);
+
+ HeapFree(GetProcessHeap(),0,context->PacketQueue);
+ HeapFree(GetProcessHeap(),0,context);
return TRUE;
}
@@ -95,11 +856,36 @@
*/
int WINAPI WTPacketsGet(HCTX hCtx, int cMaxPkts, LPVOID lpPkts)
{
- FIXME("(%p, %d, %p): stub\n", hCtx, cMaxPkts, lpPkts);
+ int limit;
+ LPOPENCONTEXT context;
+ LPVOID ptr = lpPkts;
+
+ TRACE("(%p, %d, %p)\n", hCtx, cMaxPkts, lpPkts);
+
+ context = TABLET_FindOpenContext(hCtx);
+ TABLET_BlankPacketData(context,lpPkts,cMaxPkts);
+
+ EnterCriticalSection(&csTablet);
+ if (context->PacketsQueued == 0)
+ {
+ LeaveCriticalSection(&csTablet);
+ return 0;
+ }
+
+ for(limit = 0; limit < cMaxPkts && limit < context->PacketsQueued; limit++)
+ ptr=TABLET_CopyPacketData(context ,ptr, &context->PacketQueue[limit]);
+
+ if (limit < context->PacketsQueued)
+ {
+ memcpy(context->PacketQueue, &context->PacketQueue[limit],
+ (context->QueueSize - (limit))*sizeof(WTPACKET));
+ }
+ context->PacketsQueued -= limit;
+ LeaveCriticalSection(&csTablet);
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+ TRACE("Copied %i packets\n",limit);
- return 0;
+ return limit;
}
/***********************************************************************
@@ -107,11 +893,33 @@
*/
BOOL WINAPI WTPacket(HCTX hCtx, UINT wSerial, LPVOID lpPkt)
{
- FIXME("(%p, %d, %p): stub\n", hCtx, wSerial, lpPkt);
-
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+ int rc = 0;
+ LPOPENCONTEXT context;
+ LPWTPACKET wtp;
+
+ TRACE("(%p, %d, %p)\n", hCtx, wSerial, lpPkt);
+
+ context = TABLET_FindOpenContext(hCtx);
+
+ EnterCriticalSection(&csTablet);
+ rc = TABLET_FindPacket(context ,wSerial, &wtp);
+
+ if (rc >= 0)
+ {
+ if (lpPkt)
+ TABLET_CopyPacketData(context ,lpPkt, wtp);
+
+ if ((rc+1) < context->QueueSize)
+ {
+ memcpy(context->PacketQueue, &context->PacketQueue[rc+1],
+ (context->QueueSize - (rc+1))*sizeof(WTPACKET));
+ }
+ context->PacketsQueued -= (rc+1);
+ }
+ LeaveCriticalSection(&csTablet);
- return FALSE;
+ TRACE("Returning %i\n",rc+1);
+ return rc+1;
}
/***********************************************************************
@@ -119,11 +927,14 @@
*/
BOOL WINAPI WTEnable(HCTX hCtx, BOOL fEnable)
{
- FIXME("(%p, %u): stub\n", hCtx, fEnable);
+ LPOPENCONTEXT context;
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+ TRACE("(%p, %u)\n", hCtx, fEnable);
- return FALSE;
+ context = TABLET_FindOpenContext(hCtx);
+ context->enabled = fEnable;
+
+ return TRUE;
}
/***********************************************************************
@@ -133,9 +944,7 @@
{
FIXME("(%p, %u): stub\n", hCtx, fToTop);
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-
- return FALSE;
+ return TRUE;
}
/***********************************************************************
@@ -155,11 +964,14 @@
*/
BOOL WINAPI WTGetA(HCTX hCtx, LPLOGCONTEXTA lpLogCtx)
{
- FIXME("(%p, %p): stub\n", hCtx, lpLogCtx);
+ LPOPENCONTEXT context;
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+ TRACE("(%p, %p)\n", hCtx, lpLogCtx);
+ context = TABLET_FindOpenContext(hCtx);
- return FALSE;
+ memcpy(lpLogCtx,&context->context,sizeof(LOGCONTEXTA));
+
+ return TRUE;
}
/***********************************************************************
@@ -251,11 +1063,27 @@
*/
int WINAPI WTPacketsPeek(HCTX hCtx, int cMaxPkts, LPVOID lpPkts)
{
- FIXME("(%p, %d, %p): stub\n", hCtx, cMaxPkts, lpPkts);
-
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-
- return 0;
+ int limit;
+ LPOPENCONTEXT context;
+ LPVOID ptr = lpPkts;
+
+ TRACE("(%p, %d, %p)\n", hCtx, cMaxPkts, lpPkts);
+
+ context = TABLET_FindOpenContext(hCtx);
+
+ EnterCriticalSection(&csTablet);
+ if (context->PacketsQueued == 0)
+ {
+ LeaveCriticalSection(&csTablet);
+ return 0;
+ }
+
+ for (limit = 0; limit < cMaxPkts && limit < context->PacketsQueued; limit++)
+ ptr = TABLET_CopyPacketData(context ,ptr, &context->PacketQueue[limit]);
+
+ LeaveCriticalSection(&csTablet);
+ TRACE("Copied %i packets\n",limit);
+ return limit;
}
/***********************************************************************
@@ -264,12 +1092,53 @@
int WINAPI WTDataGet(HCTX hCtx, UINT wBegin, UINT wEnd,
int cMaxPkts, LPVOID lpPkts, LPINT lpNPkts)
{
- FIXME("(%p, %u, %u, %d, %p, %p): stub\n",
+ LPOPENCONTEXT context;
+ LPVOID ptr = lpPkts;
+ UINT bgn = 0;
+ UINT end = 0;
+ UINT num = 0;
+
+ TRACE("(%p, %u, %u, %d, %p, %p)\n",
hCtx, wBegin, wEnd, cMaxPkts, lpPkts, lpNPkts);
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+ context = TABLET_FindOpenContext(hCtx);
- return 0;
+ EnterCriticalSection(&csTablet);
+ if (context->PacketsQueued == 0)
+ {
+ LeaveCriticalSection(&csTablet);
+ return 0;
+ }
+
+ while (bgn < context->PacketsQueued &&
+ context->PacketQueue[bgn].pkSerialNumber != wBegin)
+ bgn++;
+
+ end = bgn;
+ while (end < context->PacketsQueued &&
+ context->PacketQueue[end].pkSerialNumber != wEnd)
+ end++;
+
+ if (bgn == end == context->PacketsQueued)
+ {
+ LeaveCriticalSection(&csTablet);
+ return 0;
+ }
+
+ for (num = bgn; num <= end; num++)
+ ptr = TABLET_CopyPacketData(context ,ptr, &context->PacketQueue[end]);
+
+ /* remove read packets */
+ if ((end+1) < context->PacketsQueued)
+ memcpy( &context->PacketQueue[bgn], &context->PacketQueue[end+1],
+ (context->PacketsQueued - ((end-bgn)+1)) * sizeof (WTPACKET));
+
+ context->PacketsQueued -= ((end-bgn)+1);
+ *lpNPkts = ((end-bgn)+1);
+
+ LeaveCriticalSection(&csTablet);
+ TRACE("Copied %i packets\n",*lpNPkts);
+ return (end - bgn)+1;
}
/***********************************************************************
@@ -278,12 +1147,48 @@
int WINAPI WTDataPeek(HCTX hCtx, UINT wBegin, UINT wEnd,
int cMaxPkts, LPVOID lpPkts, LPINT lpNPkts)
{
- FIXME("(%p, %u, %u, %d, %p, %p): stub\n",
+ LPOPENCONTEXT context;
+ LPVOID ptr = lpPkts;
+ UINT bgn = 0;
+ UINT end = 0;
+ UINT num = 0;
+
+ TRACE("(%p, %u, %u, %d, %p, %p)\n",
hCtx, wBegin, wEnd, cMaxPkts, lpPkts, lpNPkts);
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+ context = TABLET_FindOpenContext(hCtx);
- return 0;
+ EnterCriticalSection(&csTablet);
+ if (context->PacketsQueued == 0)
+ {
+ LeaveCriticalSection(&csTablet);
+ return 0;
+ }
+
+ while (bgn < context->PacketsQueued &&
+ context->PacketQueue[bgn].pkSerialNumber != wBegin)
+ bgn++;
+
+ end = bgn;
+ while (end < context->PacketsQueued &&
+ context->PacketQueue[end].pkSerialNumber != wEnd)
+ end++;
+
+ if (bgn == context->PacketsQueued || end == context->PacketsQueued)
+ {
+ TRACE("%i %i %i \n", bgn, end, context->PacketsQueued);
+ LeaveCriticalSection(&csTablet);
+ return 0;
+ }
+
+ for (num = bgn; num <= end; num++)
+ ptr = TABLET_CopyPacketData(context ,ptr, &context->PacketQueue[end]);
+
+ *lpNPkts = ((end-bgn)+1);
+ LeaveCriticalSection(&csTablet);
+
+ TRACE("Copied %i packets\n",*lpNPkts);
+ return (end - bgn)+1;
}
/***********************************************************************
@@ -291,9 +1196,24 @@
*/
BOOL WINAPI WTQueuePacketsEx(HCTX hCtx, UINT *lpOld, UINT *lpNew)
{
- FIXME("(%p, %p, %p): stub\n", hCtx, lpOld, lpNew);
+ LPOPENCONTEXT context;
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+ TRACE("(%p, %p, %p)\n", hCtx, lpOld, lpNew);
+ context = TABLET_FindOpenContext(hCtx);
+
+ EnterCriticalSection(&csTablet);
+ if (context->PacketsQueued)
+ {
+ *lpOld = context->PacketQueue[0].pkSerialNumber;
+ *lpNew = context->PacketQueue[context->PacketsQueued-1].pkSerialNumber;
+ }
+ else
+ {
+ TRACE("No packets\n");
+ LeaveCriticalSection(&csTablet);
+ return FALSE;
+ }
+ LeaveCriticalSection(&csTablet);
return TRUE;
}
@@ -303,11 +1223,11 @@
*/
int WINAPI WTQueueSizeGet(HCTX hCtx)
{
- FIXME("(%p): stub\n", hCtx);
+ LPOPENCONTEXT context;
+ TRACE("(%p)\n", hCtx);
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-
- return 0;
+ context = TABLET_FindOpenContext(hCtx);
+ return context->QueueSize;
}
/***********************************************************************
@@ -315,9 +1235,18 @@
*/
BOOL WINAPI WTQueueSizeSet(HCTX hCtx, int nPkts)
{
- FIXME("(%p, %d): stub\n", hCtx, nPkts);
+ LPOPENCONTEXT context;
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+ TRACE("(%p, %d)\n", hCtx, nPkts);
- return 0;
+ context = TABLET_FindOpenContext(hCtx);
+
+ EnterCriticalSection(&csTablet);
+ context->PacketQueue = HeapReAlloc(GetProcessHeap(), 0,
+ context->PacketQueue, sizeof(WTPACKET)*nPkts);
+
+ context->QueueSize = nPkts;
+ LeaveCriticalSection(&csTablet);
+
+ return nPkts;
}
Index: dlls/x11drv/Makefile.in
===================================================================
RCS file: /home/wine/wine/dlls/x11drv/Makefile.in,v
retrieving revision 1.30
diff -u -r1.30 Makefile.in
--- dlls/x11drv/Makefile.in 31 Oct 2002 02:38:20 -0000 1.30
+++ dlls/x11drv/Makefile.in 23 Apr 2003 13:55:27 -0000
@@ -38,7 +38,8 @@
x11ddraw.c \
x11drv_main.c \
xrender.c \
- xvidmode.c
+ xvidmode.c \
+ wintab.c
PROGRAMS = wineclipsrv
Index: dlls/x11drv/event.c
===================================================================
RCS file: /home/wine/wine/dlls/x11drv/event.c,v
retrieving revision 1.18
diff -u -r1.18 event.c
--- dlls/x11drv/event.c 23 Jan 2003 01:29:58 -0000 1.18
+++ dlls/x11drv/event.c 23 Apr 2003 13:55:28 -0000
@@ -275,8 +275,18 @@
WARN( "Got event %s for unknown Window %08lx\n",
event_names[event->type], event->xany.window );
else
- TRACE("Got event %s for hwnd %p\n",
- event_names[event->type], hWnd );
+ if (event->type <= MappingNotify)
+ TRACE("Got event %s for hwnd/window %p/%lx, GetFocus()=%p\n",
+ event_names[event->type], hWnd, event->xany.window, GetFocus() );
+ else
+ TRACE("Got extention event for hwnd/window %p/%lx, GetFocus()=%p\n",
+ hWnd, event->xany.window, GetFocus() );
+
+ if (X11DRV_ProcessTabletEvent(hWnd, event))
+ {
+ TRACE("Return: filtered by tablet\n");
+ return;
+ }
switch(event->type)
{
Index: dlls/x11drv/x11drv.spec
===================================================================
RCS file: /home/wine/wine/dlls/x11drv/x11drv.spec,v
retrieving revision 1.45
diff -u -r1.45 x11drv.spec
--- dlls/x11drv/x11drv.spec 22 Apr 2003 00:15:48 -0000 1.45
+++ dlls/x11drv/x11drv.spec 23 Apr 2003 13:55:28 -0000
@@ -104,3 +104,8 @@
# X11 locks
@ cdecl -norelay wine_tsx11_lock()
@ cdecl -norelay wine_tsx11_unlock()
+
+# WinTab32
+@ cdecl LoadTabletInfo(ptr ptr ptr long ptr) X11DRV_LoadTabletInfo
+@ cdecl AttachEventQueueToTablet(ptr ptr long) X11DRV_AttachEventQueueToTablet
+@ cdecl GetCurrentPacket(ptr) X11DRV_GetCurrentPacket
Index: include/wintab.h
===================================================================
RCS file: /home/wine/wine/include/wintab.h,v
retrieving revision 1.1
diff -u -r1.1 wintab.h
--- include/wintab.h 17 Dec 2002 01:49:16 -0000 1.1
+++ include/wintab.h 23 Apr 2003 13:55:28 -0000
@@ -328,7 +328,9 @@
#define CSR_MINPKTDATA 17 /* 1.1 */
#define CSR_MINBUTTONS 18 /* 1.1 */
#define CSR_CAPABILITIES 19 /* 1.1 */
-#define CSR_MAX 19
+/* from http://www.wacomeng.com/devsupport/ibmpc/wacomwindevfaq.html */
+#define CSR_TYPE 20
+#define CSR_MAX 20
#endif
--- /dev/null Thu Aug 30 15:30:55 2001
+++ dlls/wintab32/wintab32.c Wed Apr 23 08:22:37 2003
@@ -0,0 +1,150 @@
+/*
+ * WinTab32 library
+ *
+ * Copyright 2003 Codeweavers, Aric Stewart
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "winbase.h"
+#include "windef.h"
+#include "wingdi.h"
+#include "winuser.h"
+#include "winerror.h"
+#include "wintab.h"
+#include "wintab_internal.h"
+#include "wine/debug.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(wintab32);
+
+HWND hwndDefault = (HWND)NULL;
+static HANDLE hTabletInst;
+static const WCHAR
+WC_TABLETCLASSNAME[] = {'W','i','n','e','T','a','b','l','e','t','C','l','a','s','s',0};
+CRITICAL_SECTION csTablet;
+
+static LRESULT WINAPI TABLET_WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam,
+ LPARAM lParam);
+
+static VOID TABLET_Register()
+{
+ WNDCLASSW wndClass;
+ ZeroMemory(&wndClass, sizeof(WNDCLASSW));
+ wndClass.style = CS_GLOBALCLASS;
+ wndClass.lpfnWndProc = (WNDPROC) TABLET_WindowProc;
+ wndClass.cbClsExtra = 0;
+ wndClass.cbWndExtra = 0;
+ wndClass.hCursor = (HCURSOR)NULL;
+ wndClass.hbrBackground = (HBRUSH)(COLOR_WINDOW +1);
+ wndClass.lpszClassName = WC_TABLETCLASSNAME;
+ RegisterClassW(&wndClass);
+}
+
+static VOID TABLET_Unregister()
+{
+ UnregisterClassW(WC_TABLETCLASSNAME, (HINSTANCE)NULL);
+}
+
+BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpReserved)
+{
+ static const WCHAR name[] = {'T','a','b','l','e','t',0};
+ static HMODULE hx11drv = NULL;
+
+ TRACE("%p, %lx, %p\n",hInstDLL,fdwReason,lpReserved);
+ switch (fdwReason)
+ {
+ case DLL_PROCESS_ATTACH:
+ TRACE("Initialization\n");
+ InitializeCriticalSection(&csTablet);
+ hx11drv = LoadLibraryA("x11drv.dll");
+ if (hx11drv)
+ {
+ pLoadTabletInfo = (X11_LoadTabletInfo*)GetProcAddress(hx11drv,
+ "LoadTabletInfo");
+ pAttachEventQueueToTablet = (X11_AttachEventQueueToTablet*)
+ GetProcAddress(hx11drv, "AttachEventQueueToTablet");
+ pGetCurrentPacket = (X11_GetCurrentPacket*)
+ GetProcAddress(hx11drv, "GetCurrentPacket");
+ TABLET_Register();
+ hTabletInst = hInstDLL;
+ hwndDefault = CreateWindowW(WC_TABLETCLASSNAME, name,
+ WS_POPUPWINDOW,0,0,0,0,0,0,hTabletInst,0);
+ }
+ else
+ return FALSE;
+ break;
+ case DLL_PROCESS_DETACH:
+ TRACE("Detaching\n");
+ if (hx11drv)
+ {
+ FreeLibrary(hx11drv);
+ if (hwndDefault)
+ {
+ DestroyWindow(hwndDefault);
+ hwndDefault = 0;
+ }
+ TABLET_Unregister();
+ }
+ DeleteCriticalSection(&csTablet);
+ break;
+ }
+ return TRUE;
+}
+
+
+/*
+ * The window proc for the default TABLET window
+ */
+static LRESULT WINAPI TABLET_WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam,
+ LPARAM lParam)
+{
+ TRACE("Incomming Message 0x%x (0x%08x, 0x%08x)\n", uMsg, (UINT)wParam,
+ (UINT)lParam);
+
+ switch(uMsg)
+ {
+ case WM_NCCREATE:
+ return TRUE;
+
+ case WT_PACKET:
+ {
+ WTPACKET packet;
+ LPOPENCONTEXT handler;
+ pGetCurrentPacket(&packet);
+ handler = AddPacketToContextQueue(&packet,(HWND)lParam);
+ if (handler)
+ TABLET_PostTabletMessage(handler, WT_PACKET,
+ (WPARAM)packet.pkSerialNumber,
+ (LPARAM)handler->handle, FALSE);
+ break;
+ }
+ case WT_PROXIMITY:
+ {
+ LPOPENCONTEXT handler;
+ LPARAM prox;
+ handler = FindOpenContext((HWND)lParam);
+ if (handler)
+ {
+ prox = wParam | 0x1 << 16;
+ TABLET_PostTabletMessage(handler, WT_PROXIMITY,
+ (WPARAM)handler->handle, (LPARAM)prox,
+ TRUE);
+ }
+ break;
+ }
+ }
+ return 0;
+}
+
--- /dev/null Thu Aug 30 15:30:55 2001
+++ dlls/wintab32/wintab_internal.h Wed Apr 23 08:26:57 2003
@@ -0,0 +1,329 @@
+/*
+ * Tablet header
+ *
+ * Copyright 2003 Codeweavers (Aric Stewart)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+typedef struct tagWTI_INTERFACE_INFO {
+ CHAR WINTABID[1024];
+ /* a copy of the null-terminated tablet hardware identification string
+ * in the user buffer. This string should include make, model, and
+ * revision information in user-readable format.
+ */
+ WORD SPECVERSION;
+ /* the specification version number. The high-order byte contains the
+ * major version number; the low-order byte contains the minor version
+ * number.
+ */
+ WORD IMPLVERSION;
+ /* the implementation version number. The high-order byte contains the
+ * major version number; the low-order byte contains the minor version
+ * number.
+ */
+ UINT NDEVICES;
+ /* the number of devices supported. */
+ UINT NCURSORS;
+ /* the total number of cursor types supported. */
+ UINT NCONTEXTS;
+ /* the number of contexts supported. */
+ UINT CTXOPTIONS;
+ /* flags indicating which context options are supported */
+ UINT CTXSAVESIZE;
+ /* the size of the save information returned from WTSave.*/
+ UINT NEXTENSIONS;
+ /* the number of extension data items supported.*/
+ UINT NMANAGERS;
+ /* the number of manager handles supported.*/
+ }WTI_INTERFACE_INFO, *LPWTI_INTERFACE_INFO;
+
+typedef struct tagWTI_STATUS_INFO{
+ UINT CONTEXTS;
+ /* the number of contexts currently open.*/
+ UINT SYSCTXS;
+ /* the number of system contexts currently open.*/
+ UINT PKTRATE;
+ /* the maximum packet report rate currently being received by any
+ * context, in Hertz.
+ */
+ WTPKT PKTDATA;
+ /* a mask indicating which packet data items are requested by at
+ * least one context.
+ */
+ UINT MANAGERS;
+ /* the number of manager handles currently open.*/
+ BOOL SYSTEM;
+ /* a non-zero value if system pointing is available to the whole
+ * screen; zero otherwise.
+ */
+ DWORD BUTTONUSE;
+ /* a button mask indicating the logical buttons whose events are
+ * requested by at least one context.
+ */
+ DWORD SYSBTNUSE;
+ /* a button mask indicating which logical buttons are assigned a system
+ * button function by the current cursor's system button map.
+ */
+} WTI_STATUS_INFO, *LPWTI_STATUS_INFO;
+
+
+typedef struct tagWTI_DEVICES_INFO
+{
+ CHAR NAME[256];
+ /* a displayable null- terminated string describing the device,
+ * manufacturer, and revision level.
+ */
+ UINT HARDWARE;
+ /* flags indicating hardware and driver capabilities, as defined
+ * below:
+ HWC_INTEGRATED:
+ Indicates that the display and digitizer share the same surface.
+ HWC_TOUCH
+ Indicates that the cursor must be in physical contact with the
+ device to report position.
+ HWC_HARDPROX
+ Indicates that device can generate events when the cursor is
+ entering and leaving the physical detection range.
+ HWC_PHYSID_CURSORS
+ Indicates that device can uniquely identify the active cursor in
+ hardware.
+ */
+ UINT NCSRTYPES;
+ /* the number of supported cursor types.*/
+ UINT FIRSTCSR;
+ /* the first cursor type number for the device. */
+ UINT PKTRATE;
+ /* the maximum packet report rate in Hertz. */
+ WTPKT PKTDATA;
+ /* a bit mask indicating which packet data items are always available.*/
+ WTPKT PKTMODE;
+ /* a bit mask indicating which packet data items are physically
+ * relative, i.e., items for which the hardware can only report change,
+ * not absolute measurement.
+ */
+ WTPKT CSRDATA;
+ /* a bit mask indicating which packet data items are only available when
+ * certain cursors are connected. The individual cursor descriptions
+ * must be consulted to determine which cursors return which data.
+ */
+ INT XMARGIN;
+ INT YMARGIN;
+ INT ZMARGIN;
+ /* the size of tablet context margins in tablet native coordinates, in
+ * the x, y, and z directions, respectively.
+ */
+ AXIS X;
+ AXIS Y;
+ AXIS Z;
+ /* the tablet's range and resolution capabilities, in the x, y, and z
+ * axes, respectively.
+ */
+ AXIS NPRESSURE;
+ AXIS TPRESSURE;
+ /* the tablet's range and resolution capabilities, for the normal and
+ * tangential pressure inputs, respectively.
+ */
+ AXIS ORIENTATION[3];
+ /* a 3-element array describing the tablet's orientation range and
+ * resolution capabilities.
+ */
+ AXIS ROTATION[3];
+ /* a 3-element array describing the tablet's rotation range and
+ * resolution capabilities.
+ */
+ CHAR PNPID[256];
+ /* a null-terminated string containing the devices Plug and Play ID.*/
+} WTI_DEVICES_INFO, *LPWTI_DEVICES_INFO;
+
+typedef struct tagWTI_CURSORS_INFO
+{
+ CHAR NAME[256];
+ /* a displayable zero-terminated string containing the name of the
+ * cursor.
+ */
+ BOOL ACTIVE;
+ /* whether the cursor is currently connected. */
+ WTPKT PKTDATA;
+ /* a bit mask indicating the packet data items supported when this
+ * cursor is connected.
+ */
+ BYTE BUTTONS;
+ /* the number of buttons on this cursor. */
+ BYTE BUTTONBITS;
+ /* the number of bits of raw button data returned by the hardware.*/
+ CHAR BTNNAMES[1024]; /* FIXME: make this dynamic */
+ /* a list of zero-terminated strings containing the names of the
+ * cursor's buttons. The number of names in the list is the same as the
+ * number of buttons on the cursor. The names are separated by a single
+ * zero character; the list is terminated by two zero characters.
+ */
+ BYTE BUTTONMAP[32];
+ /* a 32 byte array of logical button numbers, one for each physical
+ * button.
+ */
+ BYTE SYSBTNMAP[32];
+ /* a 32 byte array of button action codes, one for each logical
+ * button.
+ */
+ BYTE NPBUTTON;
+ /* the physical button number of the button that is controlled by normal
+ * pressure.
+ */
+ UINT NPBTNMARKS[2];
+ /* an array of two UINTs, specifying the button marks for the normal
+ * pressure button. The first UINT contains the release mark; the second
+ * contains the press mark.
+ */
+ UINT *NPRESPONSE;
+ /* an array of UINTs describing the pressure response curve for normal
+ * pressure.
+ */
+ BYTE TPBUTTON;
+ /* the physical button number of the button that is controlled by
+ * tangential pressure.
+ */
+ UINT TPBTNMARKS[2];
+ /* an array of two UINTs, specifying the button marks for the tangential
+ * pressure button. The first UINT contains the release mark; the second
+ * contains the press mark.
+ */
+ UINT *TPRESPONSE;
+ /* an array of UINTs describing the pressure response curve for
+ * tangential pressure.
+ */
+ DWORD PHYSID;
+ /* a manufacturer-specific physical identifier for the cursor. This
+ * value will distinguish the physical cursor from others on the same
+ * device. This physical identifier allows applications to bind
+ * functions to specific physical cursors, even if category numbers
+ * change and multiple, otherwise identical, physical cursors are
+ * present.
+ */
+ UINT MODE;
+ /* the cursor mode number of this cursor type, if this cursor type has
+ * the CRC_MULTIMODE capability.
+ */
+ UINT MINPKTDATA;
+ /* the minimum set of data available from a physical cursor in this
+ * cursor type, if this cursor type has the CRC_AGGREGATE capability.
+ */
+ UINT MINBUTTONS;
+ /* the minimum number of buttons of physical cursors in the cursor type,
+ * if this cursor type has the CRC_AGGREGATE capability.
+ */
+ UINT CAPABILITIES;
+ /* flags indicating cursor capabilities, as defined below:
+ CRC_MULTIMODE
+ Indicates this cursor type describes one of several modes of a
+ single physical cursor. Consecutive cursor type categories
+ describe the modes; the CSR_MODE data item gives the mode number
+ of each cursor type.
+ CRC_AGGREGATE
+ Indicates this cursor type describes several physical cursors
+ that cannot be distinguished by software.
+ CRC_INVERT
+ Indicates this cursor type describes the physical cursor in its
+ inverted orientation; the previous consecutive cursor type
+ category describes the normal orientation.
+ */
+ UINT TYPE;
+ /* Manufacturer Unique id for the item type */
+} WTI_CURSORS_INFO, *LPWTI_CURSORS_INFO;
+
+
+typedef struct tagWTI_EXTENSIONS_INFO
+{
+ CHAR NAME[256];
+ /* a unique, null-terminated string describing the extension.*/
+ UINT TAG;
+ /* a unique identifier for the extension. */
+ WTPKT MASK;
+ /* a mask that can be bitwise OR'ed with WTPKT-type variables to select
+ * the extension.
+ */
+ UINT SIZE[2];
+ /* an array of two UINTs specifying the extension's size within a packet
+ * (in bytes). The first is for absolute mode; the second is for
+ * relative mode.
+ */
+ AXIS *AXES;
+ /* an array of axis descriptions, as needed for the extension. */
+ BYTE *DEFAULT;
+ /* the current global default data, as needed for the extension. This
+ * data is modified via the WTMgrExt function.
+ */
+ BYTE *DEFCONTEXT;
+ BYTE *DEFSYSCTX;
+ /* the current default context-specific data, as needed for the
+ * extension. The indices identify the digitizing- and system-context
+ * defaults, respectively.
+ */
+ BYTE *CURSORS;
+ /* Is the first of one or more consecutive indices, one per cursor type.
+ * Each returns the current default cursor-specific data, as need for
+ * the extension. This data is modified via the WTMgrCsrExt function.
+ */
+} WTI_EXTENSIONS_INFO, *LPWTI_EXTENSIONS_INFO;
+
+typedef struct tagWTPACKET {
+ HCTX pkContext;
+ UINT pkStatus;
+ LONG pkTime;
+ WTPKT pkChanged;
+ UINT pkSerialNumber;
+ UINT pkCursor;
+ DWORD pkButtons;
+ DWORD pkX;
+ DWORD pkY;
+ DWORD pkZ;
+ UINT pkNormalPressure;
+ UINT pkTangentPressure;
+ ORIENTATION pkOrientation;
+ ROTATION pkRotation; /* 1.1 */
+} WTPACKET, *LPWTPACKET;
+
+typedef struct tagOPENCONTEXT
+{
+ HCTX handle;
+ LOGCONTEXTA context;
+ HWND hwndOwner;
+ BOOL enabled;
+ INT ActiveCursor;
+ INT QueueSize;
+ INT PacketsQueued;
+ LPWTPACKET PacketQueue;
+ struct tagOPENCONTEXT *next;
+} OPENCONTEXT, *LPOPENCONTEXT;
+
+LPOPENCONTEXT TABLET_FindOpenContext(HCTX hCtx);
+int TABLET_PostTabletMessage(LPOPENCONTEXT newcontext, UINT msg, WPARAM wParam,
+ LPARAM lParam, BOOL send_always);
+LPOPENCONTEXT AddPacketToContextQueue(LPWTPACKET packet, HWND hwnd);
+LPOPENCONTEXT FindOpenContext(HWND hwnd);
+
+/* X11drv functions */
+typedef int X11_LoadTabletInfo(LPLOGCONTEXTA context, LPWTI_DEVICES_INFO
+ device, LPWTI_CURSORS_INFO cursor_list, int
+ num_cursors, HWND hwnddefault);
+
+typedef int X11_GetCurrentPacket(LPWTPACKET packet);
+
+typedef int X11_AttachEventQueueToTablet(HWND hOwner, LPWTI_CURSORS_INFO
+ cursor_list, int num_cursors);
+
+X11_LoadTabletInfo *pLoadTabletInfo;
+X11_AttachEventQueueToTablet *pAttachEventQueueToTablet;
+X11_GetCurrentPacket *pGetCurrentPacket;
--- /dev/null Thu Aug 30 15:30:55 2001
+++ dlls/x11drv/wintab.c Wed Apr 23 08:27:47 2003
@@ -0,0 +1,551 @@
+/*
+ * X11 tablet driver
+ *
+ * Copyright 2003 Codeweavers (Aric Stewart)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "config.h"
+
+#include "ts_xlib.h"
+#include <X11/extensions/XInput.h>
+#include <X11/extensions/XI.h>
+
+#include "windef.h"
+#include "x11drv.h"
+#include "wine/debug.h"
+#include "wintab.h"
+#include <dlfcn.h>
+#include "../wintab32/wintab_internal.h"
+#include <stdlib.h>
+
+WINE_DEFAULT_DEBUG_CHANNEL(wintab32);
+WINE_DECLARE_DEBUG_CHANNEL(event);
+
+static int motion_type = -1;
+static int button_press_type = -1;
+static int button_release_type = -1;
+static int key_press_type = -1;
+static int key_release_type = -1;
+static int proximity_in_type = -1;
+static int proximity_out_type = -1;
+
+HWND hwndTabletDefault = (HWND)NULL;
+WTPACKET gMsgPacket;
+static DWORD gSerial = 0;
+static INT button_state[10] = {0,0,0,0,0,0,0,0,0,0};
+
+
+/* XInput stuff */
+static void *xinput_handle;
+
+#define MAKE_FUNCPTR(f) static typeof(f) * p##f;
+MAKE_FUNCPTR(XListInputDevices)
+MAKE_FUNCPTR(XOpenDevice)
+MAKE_FUNCPTR(XQueryDeviceState)
+MAKE_FUNCPTR(XGetDeviceButtonMapping)
+MAKE_FUNCPTR(XCloseDevice)
+MAKE_FUNCPTR(XSelectExtensionEvent)
+MAKE_FUNCPTR(XFreeDeviceState)
+#undef MAKE_FUNCPTR
+
+INT X11DRV_XInput_Init(void)
+{
+ xinput_handle = wine_dlopen("libXi.so", RTLD_NOW, NULL, 0);
+ if (xinput_handle)
+ {
+#define LOAD_FUNCPTR(f) if((p##f = wine_dlsym(xinput_handle, #f, NULL, 0)) == NULL) goto sym_not_found;
+ LOAD_FUNCPTR(XListInputDevices)
+ LOAD_FUNCPTR(XOpenDevice)
+ LOAD_FUNCPTR(XGetDeviceButtonMapping)
+ LOAD_FUNCPTR(XCloseDevice)
+ LOAD_FUNCPTR(XSelectExtensionEvent)
+ LOAD_FUNCPTR(XQueryDeviceState)
+ LOAD_FUNCPTR(XFreeDeviceState)
+#undef LOAD_FUNCPTR
+ return 1;
+ }
+sym_not_found:
+ return 0;
+}
+
+int X11DRV_LoadTabletInfo(LPLOGCONTEXTA context, LPWTI_DEVICES_INFO device,
+ LPWTI_CURSORS_INFO cursor_list, int num_cursors, HWND
+ hwnddefault)
+{
+ struct x11drv_thread_data *data = x11drv_thread_data();
+ int num_devices;
+ int loop;
+ int cursor_target;
+ XDeviceInfo *devices;
+ XDeviceInfo *target = NULL;
+ BOOL axis_read_complete= FALSE;
+
+ XAnyClassPtr any;
+ XButtonInfoPtr Button;
+ XValuatorInfoPtr Val;
+ XAxisInfoPtr Axis;
+
+ XDevice *opendevice;
+
+ if (!X11DRV_XInput_Init())
+ {
+ ERR("Unable to initialized the XInput library.\n");
+ return 0;
+ }
+
+ hwndTabletDefault = hwnddefault;
+
+ /* Do base initializaion */
+ strcpy(context->lcName, "Wine Tablet Context");
+ strcpy(device->NAME,"Wine Tablet Device");
+
+ context->lcOptions = CXO_SYSTEM | CXO_MESSAGES | CXO_CSRMESSAGES;
+ context->lcLocks = CXL_INSIZE | CXL_INASPECT | CXL_MARGIN |
+ CXL_SENSITIVITY | CXL_SYSOUT;
+
+ context->lcMsgBase= WT_DEFBASE;
+ context->lcDevice = 0;
+ context->lcPktData =
+ PK_CONTEXT | PK_STATUS | PK_SERIAL_NUMBER| PK_TIME | PK_CURSOR |
+ PK_BUTTONS | PK_X | PK_Y | PK_NORMAL_PRESSURE | PK_ORIENTATION;
+ context->lcMoveMask=
+ PK_BUTTONS | PK_X | PK_Y | PK_NORMAL_PRESSURE | PK_ORIENTATION;
+ context->lcStatus = CXS_ONTOP;
+ context->lcPktRate = 100;
+ context->lcBtnDnMask = 0xffffffff;
+ context->lcBtnUpMask = 0xffffffff;
+ context->lcSensX = 65536;
+ context->lcSensY = 65536;
+ context->lcSensX = 65536;
+ context->lcSensZ = 65536;
+ context->lcSysSensX= 65536;
+ context->lcSysSensY= 65536;
+
+ /* Device Defaults */
+ device->HARDWARE = HWC_HARDPROX|HWC_PHYSID_CURSORS;
+ device->FIRSTCSR= 0;
+ device->PKTRATE = 100;
+ device->PKTDATA =
+ PK_CONTEXT | PK_STATUS | PK_SERIAL_NUMBER| PK_TIME | PK_CURSOR |
+ PK_BUTTONS | PK_X | PK_Y | PK_NORMAL_PRESSURE | PK_ORIENTATION;
+ strcpy(device->PNPID,"non-pluginplay");
+
+ wine_tsx11_lock();
+
+ cursor_target = -1;
+ devices = pXListInputDevices(data->display, &num_devices);
+ if (!devices)
+ {
+ WARN("XInput Extenstions reported as not avalable\n");
+ wine_tsx11_unlock();
+ return 0;
+ }
+ for (loop=0; loop < num_devices; loop++)
+ {
+ int class_loop;
+
+ TRACE("Trying device %i(%s)\n",loop,devices[loop].name);
+ if (devices[loop].use == IsXExtensionDevice)
+ {
+ LPWTI_CURSORS_INFO cursor;
+
+ TRACE("Is Extention Device\n");
+ cursor_target++;
+ target = &devices[loop];
+ cursor = &cursor_list[cursor_target];
+
+ opendevice = pXOpenDevice(data->display,target->id);
+ if (opendevice)
+ {
+ unsigned char map[32];
+ int i;
+ int shft = 0;
+
+ pXGetDeviceButtonMapping(data->display, opendevice, map, 32);
+
+ for (i=0; i< cursor->BUTTONS; i++,shft++)
+ {
+ cursor->BUTTONMAP[i] = map[i];
+ cursor->SYSBTNMAP[i] = (1<<shft);
+ }
+ pXCloseDevice(data->display, opendevice);
+ }
+ else
+ {
+ WARN("Unable to open device %s\n",target->name);
+ cursor_target --;
+ continue;
+ }
+
+ strcpy(cursor->NAME,target->name);
+
+ cursor->ACTIVE = 1;
+ cursor->PKTDATA = PK_TIME | PK_CURSOR | PK_BUTTONS | PK_X | PK_Y |
+ PK_NORMAL_PRESSURE | PK_TANGENT_PRESSURE |
+ PK_ORIENTATION;
+
+ cursor->PHYSID = cursor_target;
+ cursor->NPBUTTON = 1;
+ cursor->NPBTNMARKS[0] = 0 ;
+ cursor->NPBTNMARKS[1] = 1 ;
+ cursor->CAPABILITIES = 1;
+ if (strcasecmp(cursor->NAME,"stylus")==0)
+ cursor->TYPE = 0x4825;
+ if (strcasecmp(cursor->NAME,"eraser")==0)
+ cursor->TYPE = 0xc85a;
+
+
+ any = (XAnyClassPtr) (target->inputclassinfo);
+
+ for (class_loop = 0; class_loop < target->num_classes; class_loop++)
+ {
+ switch (any->class)
+ {
+ case ValuatorClass:
+ if (!axis_read_complete)
+ {
+ Val = (XValuatorInfoPtr) any;
+ Axis = (XAxisInfoPtr) ((char *) Val + sizeof
+ (XValuatorInfo));
+
+ if (Val->num_axes>=1)
+ {
+ /* Axis 1 is X */
+ device->X.axMin = Axis->min_value;
+ device->X.axMax= Axis->max_value;
+ device->X.axUnits = 1;
+ device->X.axResolution = Axis->resolution;
+ context->lcInOrgX = Axis->min_value;
+ context->lcSysOrgX = Axis->min_value;
+ context->lcInExtX = Axis->max_value;
+ context->lcSysExtX = Axis->max_value;
+ Axis++;
+ }
+ if (Val->num_axes>=2)
+ {
+ /* Axis 2 is Y */
+ device->Y.axMin = Axis->min_value;
+ device->Y.axMax= Axis->max_value;
+ device->Y.axUnits = 1;
+ device->Y.axResolution = Axis->resolution;
+ context->lcInOrgY = Axis->min_value;
+ context->lcSysOrgY = Axis->min_value;
+ context->lcInExtY = Axis->max_value;
+ context->lcSysExtY = Axis->max_value;
+ Axis++;
+ }
+ if (Val->num_axes>=3)
+ {
+ /* Axis 3 is Normal Pressure */
+ device->NPRESSURE.axMin = Axis->min_value;
+ device->NPRESSURE.axMax= Axis->max_value;
+ device->NPRESSURE.axUnits = 1;
+ device->NPRESSURE.axResolution =
+ Axis->resolution;
+ Axis++;
+ }
+ if (Val->num_axes >= 5)
+ {
+ /* Axis 4 and 5 are X and Y tilt */
+ XAxisInfoPtr XAxis = Axis;
+ Axis++;
+ if (max (abs(Axis->max_value),
+ abs(XAxis->max_value)))
+ {
+ device->ORIENTATION[0].axMin = 0;
+ device->ORIENTATION[0].axMax = 3600;
+ device->ORIENTATION[0].axUnits = 1;
+ device->ORIENTATION[0].axResolution =
+ 235929600;
+ device->ORIENTATION[1].axMin = -1000;
+ device->ORIENTATION[1].axMax = 1000;
+ device->ORIENTATION[1].axUnits = 1;
+ device->ORIENTATION[1].axResolution =
+ 235929600;
+ Axis++;
+ }
+ }
+ axis_read_complete = TRUE;
+ }
+ break;
+ case ButtonClass:
+ {
+ CHAR *ptr = cursor->BTNNAMES;
+ int i;
+
+ Button = (XButtonInfoPtr) any;
+ cursor->BUTTONS = Button->num_buttons;
+ for (i = 0; i < cursor->BUTTONS; i++)
+ {
+ strcpy(ptr,cursor->NAME);
+ ptr+=8;
+ }
+ }
+ break;
+ }
+ any = (XAnyClassPtr) ((char*) any + any->length);
+ }
+ }
+ }
+ wine_tsx11_unlock();
+ device->NCSRTYPES = cursor_target+1;
+ return cursor_target+1;
+}
+
+static int figure_deg(int x, int y)
+{
+ int rc;
+
+ if (y != 0)
+ {
+ rc = (int) 10 * (atan( (FLOAT)abs(y) / (FLOAT)abs(x)) / (3.1415 / 180));
+ if (y>0)
+ {
+ if (x>0)
+ rc += 900;
+ else
+ rc = 2700 - rc;
+ }
+ else
+ {
+ if (x>0)
+ rc = 900 - rc;
+ else
+ rc += 2700;
+ }
+ }
+ else
+ {
+ if (x >= 0)
+ rc = 900;
+ else
+ rc = 2700;
+ }
+
+ return rc;
+}
+
+static int get_button_state(int deviceid)
+{
+ return button_state[deviceid];
+}
+
+static void set_button_state(XID deviceid)
+{
+ struct x11drv_thread_data *data = x11drv_thread_data();
+ XDevice *device;
+ XDeviceState *state;
+ XInputClass *class;
+ int loop;
+ int rc = 0;
+
+ wine_tsx11_lock();
+ device = pXOpenDevice(data->display,deviceid);
+ state = pXQueryDeviceState(data->display,device);
+
+ if (state)
+ {
+ class = state->data;
+ for (loop = 0; loop < state->num_classes; loop++)
+ {
+ if (class->class == ButtonClass)
+ {
+ int loop2;
+ XButtonState *button_state = (XButtonState*)class;
+ for (loop2 = 1; loop2 <= button_state->num_buttons; loop2++)
+ {
+ if (button_state->buttons[loop2 / 8] & (1 << (loop2 % 8)))
+ {
+ rc |= (1<<(loop2-1));
+ }
+ }
+ }
+ class = (XInputClass *) ((char *) class + class->length);
+ }
+ }
+ pXFreeDeviceState(state);
+ wine_tsx11_unlock();
+ button_state[deviceid] = rc;
+}
+
+int X11DRV_ProcessTabletEvent(HWND hwnd, XEvent *event)
+{
+ memset(&gMsgPacket,0,sizeof(WTPACKET));
+
+ if(event->type == motion_type)
+ {
+ XDeviceMotionEvent *motion = (XDeviceMotionEvent *)event;
+
+ TRACE_(event)("Recieved tablet motion event (%p)\n",hwnd);
+ TRACE("Recieved tablet motion event (%p)\n",hwnd);
+ gMsgPacket.pkTime = motion->time;
+ gMsgPacket.pkSerialNumber = gSerial++;
+ gMsgPacket.pkCursor = motion->deviceid;
+ gMsgPacket.pkX = motion->axis_data[0];
+ gMsgPacket.pkY = motion->axis_data[1];
+ gMsgPacket.pkOrientation.orAzimuth =
+ figure_deg(motion->axis_data[3],motion->axis_data[4]);
+ gMsgPacket.pkOrientation.orAltitude = 1000 - 15 * max
+ (abs(motion->axis_data[3]),abs(motion->axis_data[4]));
+ gMsgPacket.pkNormalPressure = motion->axis_data[2];
+
+ if (!gMsgPacket.pkNormalPressure)
+ button_state[motion->deviceid] &= ~(1);
+ else
+ button_state[motion->deviceid] |= 1;
+
+ gMsgPacket.pkButtons = get_button_state(motion->deviceid);
+ SendMessageW(hwndTabletDefault,WT_PACKET,0,(LPARAM)hwnd);
+ }
+ else if ((event->type == button_press_type)||(event->type ==
+ button_release_type))
+ {
+ XDeviceButtonEvent *button = (XDeviceButtonEvent *) event;
+
+ TRACE_(event)("Recieved tablet button event\n");
+ TRACE("Recieved tablet button %s event\n", (event->type ==
+ button_press_type)?"press":"release");
+
+ set_button_state(button->deviceid);
+ }
+ else if (event->type == key_press_type)
+ {
+ TRACE_(event)("Recieved tablet key press event\n");
+ FIXME("Recieved tablet key press event\n");
+ }
+ else if (event->type == key_release_type)
+ {
+ TRACE_(event)("Recieved tablet key release event\n");
+ FIXME("Recieved tablet key release event\n");
+ }
+ else if ((event->type == proximity_in_type) ||
+ (event->type == proximity_out_type))
+ {
+ TRACE_(event)("Recieved tablet proximity event\n");
+ TRACE("Recieved tablet proximity event\n");
+ gMsgPacket.pkStatus = (event->type==proximity_out_type)?TPS_PROXIMITY:0;
+ SendMessageW(hwndTabletDefault, WT_PROXIMITY,
+ (event->type==proximity_out_type)?0:1, (LPARAM)hwnd);
+ }
+ else
+ return 0;
+
+ return 1;
+}
+
+int X11DRV_AttachEventQueueToTablet(HWND hOwner, LPWTI_CURSORS_INFO cursor_list,
+ int num_cursors)
+{
+ struct x11drv_thread_data *data = x11drv_thread_data();
+ int num_devices;
+ int loop;
+ int cur_loop;
+ XDeviceInfo *devices;
+ XDeviceInfo *target = NULL;
+ XDevice *the_device;
+ XInputClassInfo *ip;
+ XEventClass event_list[7];
+ Window win;
+ WND *wndPtr;
+
+ wine_tsx11_lock();
+
+ wndPtr = WIN_GetPtr(hOwner);
+ win = ((struct x11drv_win_data*)wndPtr->pDriverData)->whole_window;
+
+ TRACE("Creating context for window 0x%x (%lx) %i cursors\n",(INT)hOwner,
+ win, num_cursors);
+
+ devices = pXListInputDevices(data->display, &num_devices);
+
+ for (cur_loop=0; cur_loop < num_cursors; cur_loop++)
+ {
+ int event_number=0;
+
+ for (loop=0; loop < num_devices; loop ++)
+ if (strcmp(devices[loop].name,cursor_list[cur_loop].NAME)==0)
+ target = &devices[loop];
+
+ TRACE("Opening cursor %i id %i\n",cur_loop,(INT)target->id);
+
+ the_device = pXOpenDevice(data->display, target->id);
+
+ if (!the_device)
+ {
+ WARN("Unable to Open device\n");
+ continue;
+ }
+
+ if (the_device->num_classes > 0)
+ {
+ for (ip = the_device->classes, loop=0; loop < target->num_classes;
+ ip++, loop++)
+ {
+ switch(ip->input_class)
+ {
+ case KeyClass:
+ DeviceKeyPress(the_device, key_press_type,
+ event_list[event_number]);
+ event_number++;
+ DeviceKeyRelease(the_device, key_release_type,
+ event_list[event_number]);
+ event_number++;
+ break;
+ case ButtonClass:
+ DeviceButtonPress(the_device, button_press_type,
+ event_list[event_number]);
+ event_number++;
+ DeviceButtonRelease(the_device, button_release_type,
+ event_list[event_number]);
+ event_number++;
+ break;
+ case ValuatorClass:
+ DeviceMotionNotify(the_device, motion_type,
+ event_list[event_number]);
+ event_number++;
+ ProximityIn(the_device, proximity_in_type,
+ event_list[event_number]);
+ event_number++;
+ ProximityOut(the_device, proximity_out_type,
+ event_list[event_number]);
+ event_number++;
+ break;
+ default:
+ ERR("unknown class\n");
+ break;
+ }
+ }
+ if (pXSelectExtensionEvent(data->display, win, event_list,
+ event_number))
+ {
+ ERR( "error selecting extended events\n");
+ goto end;
+ }
+ }
+ }
+
+end:
+ WIN_ReleasePtr(wndPtr);
+ wine_tsx11_unlock();
+ return 0;
+}
+
+int X11DRV_GetCurrentPacket(LPWTPACKET *packet)
+{
+ memcpy(packet,&gMsgPacket,sizeof(WTPACKET));
+ return 1;
+}
6
6
I've just had this problem:
A program had crashed and wing-dbg has been initiated, when I pressed
CTRL+C it went back to the console. however then like mad "wine-dbg>"
kept appearing over and over until I exited the console.
Like "winedbg> winedbg> winedbg> winedbg> winedbg> winedbg> winedbg>
winedbg> winedbg> winedbg> winedbg> winedbg> winedbg> winedbg> winedbg>
winedbg> winedbg> winedbg> winedbg> winedbg> winedbg> winedbg> winedbg>
winedbg> winedbg> winedbg> winedbg> winedbg> winedbg> winedbg> winedbg>
winedbg> winedbg> winedbg> winedbg> winedbg> winedbg> winedbg> winedbg>
winedbg> winedbg> winedbg> winedbg> winedbg> winedbg> winedbg> winedbg>
winedbg> winedbg> winedbg> winedbg> winedbg> winedbg> winedbg> winedbg>
winedbg> winedbg> winedbg> winedbg> winedbg> winedbg> winedbg> winedbg>
winedbg> winedbg> winedbg> winedbg> winedbg> winedbg> winedbg> winedbg>
winedbg> winedbg> winedbg> winedbg> winedbg> winedbg> winedbg>"
Over and over and over (and over... and over...... and over..... etc)
Any ideas why this is?
Oh, and on an unrelated note, I noticed that Opera 5 runs well in wine -
do the newer versions run just as well?
3
2
> If you run for example edonkey 0.26+, you can see that it crashes as
> soon as you enter the preference dialog box.
do u talk about edonkey or emule ? Anyway, this path fixes a crash bug in emule 0.27c :)
3
2
24 Apr '03
> executive summary: "please obscure the email addresses in the
> winehq mailing list archives, I'm drowning in spam"!
FWIW, Zack Brown and I began obscuring all the email address
in the Wine Traffic / Kernel Traffic newsletters a while ago.
They used to be embedded in the XML, HTML and various pages
referenced on the site. However, any email sent to wine-devel
before mid October will show up in the mailing list stats
in the XML pages on both WineHQ and Wine Traffic (Zack's site).
---------------
Brian Vincent
Copper Mountain Telecom
vincentb(a)coppercolorado.com
3
2