Wine-Devel
By thread
wine-devel@list.winehq.org
By month
Messages by month
- ----- 2026 -----
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 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
January 2004
- 129 participants
- 1019 messages
Re: Broken Mandrake packages
by Mike Hearn
On Thu, 2004-01-08 at 20:59, Ivan Leo Murray-Smith wrote:
> > Could whoever is responsible for these packages please double check the
> > specfiles?
> Never heard of such a problem, all RPMs are tested on both mdk 9.2 and 9.1, on 2
> different computers, and I've never noticed any lib problem. /usr/lib/wine is
> added to ld.so.conf during post, and after that ldconfig is run. I am NOT
> responsible for the RPMS shipped by Mandrakesoft.
Hmm, OK. I don't know which this person was using. Why is /usr/lib/wine
even added to ld.so.conf though, surely that isn't necessary? Only
libwine needs to be in the linker path.
Jan. 8, 2004
Re: Broken Mandrake packages
by Ivan Leo Murray-Smith
> Could whoever is responsible for these packages please double check the
> specfiles?
Never heard of such a problem, all RPMs are tested on both mdk 9.2 and 9.1, on 2
different computers, and I've never noticed any lib problem. /usr/lib/wine is
added to ld.so.conf during post, and after that ldconfig is run. I am NOT
responsible for the RPMS shipped by Mandrakesoft.
Ivan.
Jan. 8, 2004
Re: Wine troubles on Diskless workstations.....
by Eric Pouech
Alex Stewart a écrit :
> Hi,
> Below is a thread I started in the wine-users list but so far
> no seems to know the answer. I've tried their suggestions but
> they dont work. I think its a simple question (maybe not I dont
> really know thats why I have the question)
> How does wine store the path to its libraries? Simply put I changed
> the prefix var in the wineinstall script to point to a different "root"
> path for a diskless client system. The path is the root folder that
> gets made into a compressed tar.gz for the ram disk. Anyway
> as you would think/probobly guessed when I run wine on the client
> the path to the libs are not correct, they still point to the path on the
> server instead of the true root (/lib/wine)..... Thanx a bunch in advance!
ever tried to point env var WINEDLLPATH to your dir ?
A+
Jan. 8, 2004
Re: deadlock on some X environments (was: reading relay log)
by Alexandre Julliard
Ferenc Wagner <wferi(a)afavant.elte.hu> writes:
> Making progress. The thing does not depend on time or
> weather, but instead on the terminal I'm using. Different X
> extensions, color depth, whatever. On --debugmsg +all logs
Probably yet another Xlib locking bug, try commenting out the
XInitThreads call in x11drv_main.c to see if it makes a
difference. What X version are you running?
--
Alexandre Julliard
julliard(a)winehq.com
Jan. 8, 2004
Re: Wine troubles on Diskless workstations.....
by Vincent Béron
Le jeu 08/01/2004 à 15:15, Alex Stewart a écrit :
> Hi,
> Below is a thread I started in the wine-users list but so far
> no seems to know the answer. I've tried their suggestions but
> they dont work. I think its a simple question (maybe not I dont
> really know thats why I have the question)
> How does wine store the path to its libraries? Simply put I changed
> the prefix var in the wineinstall script to point to a different "root"
> path for a diskless client system. The path is the root folder that
> gets made into a compressed tar.gz for the ram disk. Anyway
> as you would think/probobly guessed when I run wine on the client
> the path to the libs are not correct, they still point to the path on
> the
> server instead of the true root (/lib/wine)..... Thanx a bunch in
> advance!
./configure --prefix=/opt/whereever/it/ll/go
make
make prefix=/some/place/to/be/packaged install
Basically, it's the same process as building an RPM (install somewhere,
grab everything over there in a "fake" root and package it).
Hope this helps...
Vincent
Jan. 8, 2004
Re: deadlock on some X environments (was: reading relay log)
by Ferenc Wagner
Ferenc Wagner <wferi(a)afavant.elte.hu> writes:
> For me it seems XCreateDC does not return (the one I quoted
> from the Wine source). I mean, sometimes. Because the same
> program works now... I did not even recompile it, honest.
> I am going mad. Yesterday night it was 100% reproducible.
Making progress. The thing does not depend on time or
weather, but instead on the terminal I'm using. Different X
extensions, color depth, whatever. On --debugmsg +all logs
$ diff -u run_head.log lock_async.log
[...]
+0009:trace:opengl:X11DRV_OpenGL_Init GLX is up and running error_base = 77
[...]
-0009:trace:x11settings:X11DRV_Settings_AddOneMode initialized mode 0: 1024x768x16 @0 Hz (NoRes)
+0009:trace:x11settings:X11DRV_Settings_AddOneMode initialized mode 0: 1024x768x32 @0 Hz (NoRes)
[...]
+0009:trace:xrender:X11DRV_XRender_Init Xrender is up and running error_base = 179
[...]
-0009:trace:xrender:X11DRV_XRender_Init Xrender is not available on your XServer, client side rendering with the core protocol instead.
[...]
-0009:Ret x11drv.GetDeviceCaps() retval=00000010 ret=40899a22
+0009:Ret x11drv.GetDeviceCaps() retval=00000018 ret=40899a22
[...]
-0009:trace:x11drv:X11DRV_CreateBitmap (0x68) 36x18 16 bpp
+0009:trace:x11drv:X11DRV_CreateBitmap (0x68) 36x18 24 bpp
[...]
Does it ring the bell for anybody? It's getting far too
deep for me... The whole logs are available at
http://afavant.elte.hu/~wferi/wine/{run_head,lock_async}.log
Feri.
Jan. 8, 2004
Wine troubles on Diskless workstations.....
by Alex Stewart
Hi,
Below is a thread I started in the wine-users list but so far
no seems to know the answer. I've tried their suggestions but
they dont work. I think its a simple question (maybe not I dont
really know thats why I have the question)
How does wine store the path to its libraries? Simply put I changed
the prefix var in the wineinstall script to point to a different "root"
path for a diskless client system. The path is the root folder that
gets made into a compressed tar.gz for the ram disk. Anyway
as you would think/probobly guessed when I run wine on the client
the path to the libs are not correct, they still point to the path on
the
server instead of the true root (/lib/wine)..... Thanx a bunch in
advance!
-Alex
PS- If I didnt explain to well above the drawn out thread of what Im
doing
and why is below....Thanx for your time!
> Then perhaps you should build wine with the prefix that the clients
> will
> be using. You may need to create a chroot'ed environment that emulates
> what the clients will be using.
The problem with that is the Diskless clients are "Thin" ie they have a
minimal
system and thus no rpm management or a compiler (no gcc).
> This is, of course, the problem you're actually having. You're pointing
> the install directory to a directory that doesn't exist for the
> clients.
>
Right. If I did point it to the correct path it would install on the
server's
local lib folder which the clients have no access to. If I rebuild wine
(now that it has installed in the client root system) with the correct
path would
all I need to do is snag the new binaries from the bin folder of the
server
and put them in the bin of the client root? Sorry I keep asking this but
WHERE is this path stored? Because its not in ./wine/config I cant
seem
to find it anywhere. I ask because if I do rebuild and its not
hardcoded in
the binary and it aint in ./wine/config then the problem will persist
because
I dont know where to change it back!
On Jan 7, 2004, at 11:21 PM, Rob Hughes wrote:
> On Wed, 2004-01-07 at 20:18, Alex Stewart wrote:
>
>> it looks for its libs at :
>> /opt/pxes-0.7/stock/dist/lib/wine/ntdll.dll.so Which makes since.
>> The
>> directory "dist"
>> is the distribution level of the root fs. So when it gets compressed
>> the nodes think dist is root ie the libraries
>> are in the file system there just not in
>> opt/pxes-0.7/stock/dist/lib/wine/ntdll.dll.so they are in fact in
>> /lib
>> at the root of the ramdisk.......So my question is where is this path
>
>
> Then perhaps you should build wine with the prefix that the clients
> will
> be using. You may need to create a chroot'ed environment that emulates
> what the clients will be using.
>
> This is, of course, the problem you're actually having. You're pointing
> the install directory to a directory that doesn't exist for the
> clients.
>
> _______________________________________________
> wine-users mailing list
> wine-users(a)winehq.com
> http://www.winehq.com/mailman/listinfo/wine-users
>
Jan. 8, 2004
bogus patch to bind() dlls/winsock/socket.c (request removal)
by Jeremy Shaw
As a result of this patch (which is currently applied in cvs head):
http://www.winehq.com/hypermail/wine-patches/2002/12/0009.html
WS_bind() currently does this before every call to bind():
WS_setsockopt( s, WS_SOL_SOCKET, WS_SO_REUSEADDR, (char*)&on, sizeof(on) );
Basically, it sets SO_REUSEADDR for every call to WS_bind().
I can't imagine this is the correct thing to do. According to MSDN,
bind() should fail unless the program has explicitly set SO_REUSEADDR.
See Error code WSAEADDRINUSE at:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winsock/wi…
I found that this patch causes major problems with the xten sipphone
client. The xten client does not explicitly set SO_REUSEADDR and
depends on bind() failing if it tries to bind to the same local
address/port twice.
When the sipphone client needs a socket, it starts at port 8000, and
calls bind() on successive ports until bind() returns success. So
normally, if the program is already using port 8000, then bind() will
fail and will try port 8001. However, with the above patch in place,
bind() always works. So then the sipphone client will be using port
8000 twice, which the program is not designed to handle.
If I remove the call to WS_setsockopt(), the xten sipphone client works
correctly.
I am proposing that the portion of the patch applied to WS_bind() be
removed unless someone has a convincing arguement that the patch is
actually valid.
Jeremy Shaw.
Jan. 8, 2004
Re: Wineconf update, RFC re remote participation
by Eric Pouech
Dimitrie O. Paun a écrit :
> On Wed, 7 Jan 2004, Eric Pouech wrote:
>
>
>>One of the things which improved was to have a couple of folks present
>>chatting on IRC at the same time (even, if it was not satisfactory to
>>break in and ask questions)
>
>
> Telephone conversations are quite cheap nowadays (from Europe, they
> cost are <$3/h!), what about a big conference call. You can break in,
> ask questions, etc... That will work quite nicely with any sort of
> telecast from the conference, me thinks.
>
Of course audio conf would be great. It this doesn't work out, telecast
of the conf + someone watching an IRC channel would be ok.
A+
Jan. 8, 2004
Re: Will DCOM98 be pulled?
by Alexandre Julliard
Mike Hearn <mike(a)theoretic.com> writes:
> The other alternative is to have the generated files in CVS. That way we
> only deal with the bootstrapping issue once. We already have quite a few
> generated files in CVS because that makes our lives easier (think build
> system etc) - would it be acceptable to do the same here Alexandre?
As a temporary hack maybe, but not as the proper solution. widl must
be able to generate typelibs by itself without depending on the OLE
dlls. Duplicating a bit of code if necessary is not a big deal.
--
Alexandre Julliard
julliard(a)winehq.com
Jan. 8, 2004
Re: winearts patch
by Jeremy Shaw
At Wed, 7 Jan 2004 15:54:50 -0500,
<chmorgan(a)charter.net> wrote:
>
> > > (4b) wodPlayer_FeedDSP()
> > >
> > > In the while loop, I could not figure out the purpose of 'availInQ >
> > > SPACE_THRESHOLD', so I changed it to 'availInQ'. In reality, the
> > > SPACE_THRESHOLD check could probably be left in, I am not sure what
> > > the purpose was in the first place.
> > Dunno either. Reading Chris response, we need this on OSS (because
> > sounds is processed by fragments of fixed size). I don't know how arts
> > behaves here... Thrashing it altogether could also work.
>
> It would seem to reduce the number of calls to arts if we waited for a minimum amount of data, not sure if the input size of each chunk of input data is large enough to make this check pointless or if it won't hurt performace making the additional calls, just wanted to point it out. The issue with OSS appears to be that for some drivers the fragment prior to the last one isn't played if the last fragment isn't complete, line 1398 of wineoss/audio.c, I'd be inclined to think this isn't something to worry about with arts.
Based on that comment in wineoss/audio.c, I would say we don't need to
carry over the SPACE_THRESHOLD check to winearts.
As for performance and the number of calls to winearts, in the patch I
sent there are two cases that can happen:
(1) we run out of wave headers
This should only happen if we are in danger of a buffer underrun. In
this case we probably want to write wave headers as soon as we get
them so the buffer does not get empty.
(2) we run out of space in the arts buffer (but have plenty of wave
headers left to write)
This is the normal case, in which case we sleep however long it will
take to play BUFFER_REFILL_THRESHOLD packets. This is how we prevent
arts from being overly aggressive at refilling the arts buffer.
Jeremy Shaw.
Jan. 8, 2004
Re: winearts patch
by Jeremy Shaw
At Wed, 07 Jan 2004 21:22:33 +0100,
Eric Pouech wrote:
>
> Jeremy Shaw a écrit :
> > Hello,
> >
> > This message is largely for Chris Morgan's review, but I thought I
> > should open it to any interested parties.
> >
> > I have added wave-in support for arts. I also fixed some bugs in the
> > waveout code, and made some "improvements". This code seems to work
> > really well for me. If no one sees any problems I will submit the
> > patch to the patches mailing list.
> >
> > Here is a brief description of the changes I made:
> >
> > (1) In ARTS_CloseDevice() (now named ARTS_CloseWaveOutDevice()) and
> > wodPlayer_NotifyWait()
> >
> > I added 'wwo->sound_buffer = 0' after the HeapFree(). Without it,
> > HeapFree() was being called twice on the same buffer, and would crash
> > the second time.
> Well, I think the bug isn't here but rather in wodPlayer_WriteMaxFrags.
> If the buffer is too small:
> - we shouldn't destroy the current buffer (and hopefully create a new
> one) but realloc the buffer...
> - moreover, destroying the buffer without setting the sound_buffer field
> to NULL is calling for dangling pointers...
I am submitting a patch to do a HeapRealloc() instead of
HeapFree()/HeapAlloc(). It also assigns pointers to NULL after a
HeapFree().
> > (2) ARTS_AddRingMessage()
> >
> > Added the same fix I submitted earlier for wineoss in regards to ring
> > buffer resizing.
> >
> > (3) wodPlayer_WriteMaxFrags()
> >
> > DWORD *bytes, points to the number of bytes the winearts driver thinks
> > it should be able to write. However, arts sometimes lies, and says it
> > has (for example) 512 bytes available, but when you call arts_write()
> > it returns zero bytes written.
> >
> > In that case, I update *bytes to point to 0, otherwise
> > wodPlayer_WriteMaxFrags() will keep being called in vain.
> correct. It should even be done as soon as we write less bytes than
> expected (content of *byte at upon entry of wodPlayer_WriteMaxFrags)
>
Ok, in WriteMaxFrags() I changed:
*bytes -= written;
to
if (written < toWrite)
*bytes = 0;
else
*bytes -= written;
> > (4a) wodPlayer_FeedDSP()
> >
> > The old code had the following checks:
> >
> > /* input queue empty and output buffer with no space */
> > if (!wwo->lpPlayPtr && availInQ) {
> > TRACE("Run out of wavehdr:s... flushing\n");
> > wwo->dwPlayedTotal = wwo->dwWrittenTotal;
> > return INFINITE;
> > }
> >
> > if(!availInQ)
> > {
> > TRACE("no more room, no need to try to feed\n");
> > return wodPlayer_DSPWait(wwo);
> > }
> >
> > I could not understand the purpose of the '&& availInQ' in the first
> > check. It seems that if we are out of wavehdrs, then it does not
> > matter if there is space in the availInQ or not, because we don't have
> > anything to write. So I removed the && availInQ part.
> The purpose of the test is to try to always keep the input queue full:
> - therefore if we no longer have wave headers to feed the queue with, and
> >
> > Looking at it now, I realize that maybe I need to add 'if (!availInQ)'
> > before 'wwo->dwPlayedTotal = wwo->dwWrittenTotal'?
>
> IMO, the wwo->dwPlayedTotal = wwo->dwWrittenTotal is wrong in all cases.
> If we have no data to write, just way for some new headers to arrive.
Yeah, I looked at it closer after I read the email, and decided to
remove the line altogether. There is already a call to
wodUpdatePlayedTotal() that should take care of updating
wwo->dwPlayedTotal.
> > (4b) wodPlayer_FeedDSP()
> >
> > In the while loop, I could not figure out the purpose of 'availInQ >
> > SPACE_THRESHOLD', so I changed it to 'availInQ'. In reality, the
> > SPACE_THRESHOLD check could probably be left in, I am not sure what
> > the purpose was in the first place.
> Dunno either. Reading Chris response, we need this on OSS (because
> sounds is processed by fragments of fixed size). I don't know how arts
> behaves here... Thrashing it altogether could also work.
I think arts is fine without it...
Jeremy Shaw.
Jan. 8, 2004
Re: Wineconf update, RFC re remote participation
by Brian Vincent (C)
> p.s. If someone out there is thinking: of course you could do that,
> if would be trivial if you just did 'X', please feel free to share X
> with me. Otherwise, we'll have to investigate the open pbx project
> and the possibility of getting some Quicknet cards...
I have an 8 port conference bridge we can use. Unfortunately
I can't provide toll free access. It will be long distance from
MN too because I can't bring the PBX.
If there's going to be more than 8 callers, I have another bridge
available that will accomodate 32. I prefer not to use that one
though.
The neat solution would be to use the asterisk.org software to set
up a PBX with a SIP stack. Then international folks could just use
the Internet to participate. I've never used Asterisk though, so
it's hard to say how much work would be involved setting that up.
Is there a local LUG that would be willing to set something like
that up? I imagine there's some geek in MN with all the equipment
in his closet.
-brian
Jan. 8, 2004
Re: reading relay log
by Dimitrie O. Paun
On Thu, 8 Jan 2004, Ferenc Wagner wrote:
> Or maybe all the above is the result of my misconceptions.
> Please correct me if it sounds silly; winetest is my first
> Windows program, after all...
Feri, I haven't had a chance to look at the code. All I know
is that it's better to not mix GUI stuff with threads, especially
when it's not necessary. I prefer to keep things simple, this
way more people can participate. But of course, I comment without
even seeing the code, so please take this with a huge grain of salt.
--
Dimi.
Jan. 8, 2004
Broken Mandrake packages
by Mike Hearn
Hi,
I don't know who maintains the mandrake packages, but it appears that they
incorrectly install libwine.so.1 into /usr/lib/wine instead of /usr/lib,
and therefore all Wine apps fail to start with an unresolved import
failure.
Could whoever is responsible for these packages please double check the
specfiles?
thanks -mike
Jan. 8, 2004
Re: More on "no keyboard events in ddraw application"
by Oleg Prokhorov
Hello Robert,
Thursday, January 8, 2004, 1:27:23 PM, you wrote:
RG> I had the same problem as Oleg Prokhorov (no keyboard input in
RG> fullscreen games) and following patch fixed it
RG> (just a single line in Randr and XVid drivers). I do not know if
RG> something gets broken by it; I have tested it with Railroad Tycoon II
RG> demo.
It didn't help in my case and makes things even worse, after screen
init application doesn't proceed further at all.
--
Best regards,
Oleg mailto:xolegpro(a)rbcmail.ru
Jan. 8, 2004
Re: Will DCOM98 be pulled?
by Mike Hearn
On Thu, 2004-01-08 at 16:41, Nyef wrote:
> However you slice it, though, if you use the ICreateTypeLib interfaces
> you're going to get bitten with a circular dependancy, if only because
> of the wtypes.h thing. And if you use an external library you're going
> to want to use it in oleaut32.dll as well just to avoid the code
> duplication. And that external library is going to want to duplicate
> the same parts from wtypes.h for VARENUM and such.
>
> I hate to say it, but I think the best option might be to use an
> external winelib app to create the typelibs or to build a second copy
> of widl as a winelib app once winelib is available.
The other alternative is to have the generated files in CVS. That way we
only deal with the bootstrapping issue once. We already have quite a few
generated files in CVS because that makes our lives easier (think build
system etc) - would it be acceptable to do the same here Alexandre?
Jan. 8, 2004
Re: Will DCOM98 be pulled?
by Nyef
On Thu, Jan 08, 2004 at 02:11:28PM +0100, Ove Kaaven wrote:
> tor, 08.01.2004 kl. 12.52 skrev Mike Hearn:
> > On Wed, 2004-01-07 at 23:39, Ove Kaaven wrote:
> > > Well, I've done about as much as I dared do without knowing exactly what
> > > plans you have. After all, widl can *not* link to oleaut32 since widl is
> > > not a Winelib app (and wasn't meant to be since someday we may want widl
> > > to generate some of the .c and .h files used by Wine DLLs such as
> > > oleaut32 at build time, instead of putting the generated files into
> > > CVS). My original plan was to use stdio to write typelibs straight from
> > > widl, not to use ICreateTypeLib.
> >
> > OK, I thought I'd CC this to Alexander so he realises this, I must admit
> > I had just assumed widl was a winelib app like all the others.
>
> Huh? None of the other programs in tools/ are Winelib either AFAIK.
>
> > To be honest, as we might one day have to implement ICreateTypeLib
> > anyway (and i think Alexander mentioned he wanted these for his own
> > project anyway), it seems like a lot of extra work to do this once in
> > widl and again in oleaut32. Is being able take generated files out of
> > CVS really that big a gain? We already ship quite a few (wineserver,
> > build system, idl->h) and it doesn't really cause problems.
>
> I'm just saying that wasn't what it was supposed to be. But nothing a
> little rewriting can't change if we don't care about circular
> dependencies I guess, though the common typelib library (which Robert
> Shearman mentioned) would also be a solution.
Well, here's what I've got for ideas:
We could build widl twice, the second time as a winelib app.
We could set widl up to use an external winelib app to actually create
the type libraries when needed.
We could move the implementation of the type library creation out to a
separate library.
We could have some way of conditionally-compiling the typelib creation
code so that it could be run without using any services other than libc
or whatever.
However you slice it, though, if you use the ICreateTypeLib interfaces
you're going to get bitten with a circular dependancy, if only because
of the wtypes.h thing. And if you use an external library you're going
to want to use it in oleaut32.dll as well just to avoid the code
duplication. And that external library is going to want to duplicate
the same parts from wtypes.h for VARENUM and such.
I hate to say it, but I think the best option might be to use an
external winelib app to create the typelibs or to build a second copy
of widl as a winelib app once winelib is available.
-- Alastair Bridgewater
Jan. 8, 2004
Re: reading relay log
by Ferenc Wagner
"Dimitrie O. Paun" <dpaun(a)rogers.com> writes:
> On January 8, 2004 06:49 am, Ferenc Wagner wrote:
>
>> I would be glad to drop it, but how can I keep serving
>> messages while running the tests? Sorry for being dumb.
>
> I haven't looked at the source lately, but aren't you
> running the programs in a different process? If so, why
> are they blocking winetest?
I wanted to make the gui as unintrusive as I could. This
means that the original program stayed intact apart from the
status reporting functions inserted here and there which
send messages to the gui. The only synchronization I need
is not starting the tests until the gui is created, which is
achieved by an Event object. The picture could be changed
of course (it is somewhat inside-out now), but that would
require splitting up the original code into separate
callbacks. Not something I'm particularly fond of. The
present code is still a little bit verbose, I could use
DialogBox instead of CreateDialog and an explicit message
loop, which are relics of the hard beginnings.
Or maybe all the above is the result of my misconceptions.
Please correct me if it sounds silly; winetest is my first
Windows program, after all...
Feri.
Jan. 8, 2004
Re: www.winehq.org down?
by Jeremy Newman
According to the logs, the was a delay in restating httpd after the log
rotation process. One of the child pids took a bit to close. This caused
the server to be down for about 20 minutes.
On Thu, 2004-01-08 at 07:35, Francois Gouget wrote:
> On Thu, 8 Jan 2004, Michael Stefaniuc wrote:
>
> > Hello,
> >
> > is the www.winehq.org website down? The host is pingable and port 80 is
> > open but i get no data after the initial tcp connect.
>
> I believe it had trouble earlier today but it should work now.
--
Jeremy Newman <jnewman(a)codeweavers.com>
CodeWeavers, Inc.
Jan. 8, 2004
Re: dll name length (was: Windows dll replacement with Linux library)
by Dimitrie O. Paun
On January 6, 2004 10:04 pm, Dan Timis wrote:
> I finally figured out what my problem was. If the name of the library
> is "USBUtils" it works, if it is "USBDeviceUtils" it doesn't. Actually
> the max length I can use is 11 characters. That is probably 15
> characters including ".dll"
>
> In my config file all filesystems are "win95" The version is "nt40"
>
> Is there any way to configure wine to support longer names?
Eric is right, I've run into the same problem (with visual-mingw)
some time ago. He fixed it way back in Sep, 2004, with this patch:
http://www.winehq.org/hypermail/wine-patches/2003/09/0174.html
If you can't update to something newer, this patch is trivial
to backport in your tree. Please let us know if it helped.
--
Dimi.
Jan. 8, 2004
Re: reading relay log
by Dimitrie O. Paun
On January 8, 2004 06:49 am, Ferenc Wagner wrote:
> I would be glad to drop it, but how can I keep serving
> messages while running the tests? Sorry for being dumb.
I haven't looked at the source lately, but aren't you
running the programs in a different process? If so,
why are they blocking winetest?
--
Dimi.
Jan. 8, 2004
wintab work
by Aric Stewart
Sorry all, This is way way way _way_ overdue. But it is really the first
time i have had a chance to really take some time and review the changes
Alexandre gave me, retest everything and put together a patch against
the tip.
I did some quick testing and it appears that this will work.
I have broken it into 2 patches
wine_wintab.diff is all the wintab work except for the x11drv stuff
wine_x11_wintab.diff is the changes to x11drv. the reason for this is
because i still have the ime patch that i submitted earlier in my wine
tree so i had to had edit that x11 patch to try to make it not dependent
on the xim stuff being already applied. This make there a chance that
there are bits that may not apply cleanly, and if you are committing
both of my patches (xim and this) then they wont apply cleanly without a
bit of fudging.
I am also giving you 2 test applications i used for wintab testing.
SYSPRESS.EXE and TILTTEST.EXE These applications helped alot on testing
things. They where found on the wacom developers site, i think i still
have the source kicking around somewhere.
Changelog: Enables Tablet support with both Tilt and Pressure
-aric
Index: dlls/wintab32/Makefile.in
===================================================================
RCS file: /home/wine/wine/dlls/wintab32/Makefile.in,v
retrieving revision 1.3
diff -u -w -r1.3 Makefile.in
--- dlls/wintab32/Makefile.in 11 Oct 2003 01:09:16 -0000 1.3
+++ dlls/wintab32/Makefile.in 8 Jan 2004 14:57:45 -0000
@@ -3,14 +3,15 @@
SRCDIR = @srcdir@
VPATH = @srcdir@
MODULE = wintab32.dll
-IMPORTS = kernel32
+IMPORTS = kernel32 user32
ALTNAMES = wintab.dll
SPEC_SRCS16 = $(ALTNAMES:.dll=.spec)
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.2
diff -u -w -r1.2 context.c
--- dlls/wintab32/context.c 5 Sep 2003 23:08:26 -0000 1.2
+++ dlls/wintab32/context.c 8 Jan 2004 14:57:46 -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,29 +20,340 @@
*/
#include "config.h"
-
+#include <stdio.h>
+#include <stdlib.h>
#include <stdarg.h>
#include "windef.h"
-#include "winbase.h"
#include "winerror.h"
+#include "winbase.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
+ */
+
+BOOL gLoaded= FALSE;
+
+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;
+ pLoadTabletInfo(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);
+ if (gLoaded == FALSE)
+ LoadTablet();
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-
- return 0;
+ return pWTInfoA( wCategory, nIndex, lpOutput );
}
/***********************************************************************
@@ -61,11 +373,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);
+
+ 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;
}
/***********************************************************************
@@ -85,9 +424,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;
}
@@ -97,23 +459,74 @@
*/
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;
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+ TRACE("(%p, %d, %p)\n", hCtx, cMaxPkts, lpPkts);
+ if (!hCtx || !lpPkts) return 0;
+
+ 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);
+
+ TRACE("Copied %i packets\n",limit);
+
+ return limit;
+}
+
/***********************************************************************
* WTPacket (WINTAB32.24)
*/
BOOL WINAPI WTPacket(HCTX hCtx, UINT wSerial, LPVOID lpPkt)
{
- FIXME("(%p, %d, %p): stub\n", hCtx, wSerial, lpPkt);
+ int rc = 0;
+ LPOPENCONTEXT context;
+ LPWTPACKET wtp;
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+ TRACE("(%p, %d, %p)\n", hCtx, wSerial, lpPkt);
- return FALSE;
+ if (!hCtx) return 0;
+
+ 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);
+
+ TRACE("Returning %i\n",rc+1);
+ return rc+1;
}
/***********************************************************************
@@ -121,11 +534,16 @@
*/
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;
+ if (!hCtx) return 0;
+
+ context = TABLET_FindOpenContext(hCtx);
+ context->enabled = fEnable;
+
+ return TRUE;
}
/***********************************************************************
@@ -135,9 +553,7 @@
{
FIXME("(%p, %u): stub\n", hCtx, fToTop);
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-
- return FALSE;
+ return TRUE;
}
/***********************************************************************
@@ -157,11 +573,17 @@
*/
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);
- return FALSE;
+ if (!hCtx) return 0;
+
+ context = TABLET_FindOpenContext(hCtx);
+
+ memcpy(lpLogCtx,&context->context,sizeof(LOGCONTEXTA));
+
+ return TRUE;
}
/***********************************************************************
@@ -253,49 +675,166 @@
*/
int WINAPI WTPacketsPeek(HCTX hCtx, int cMaxPkts, LPVOID lpPkts)
{
- FIXME("(%p, %d, %p): stub\n", hCtx, cMaxPkts, lpPkts);
+ int limit;
+ LPOPENCONTEXT context;
+ LPVOID ptr = lpPkts;
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+ TRACE("(%p, %d, %p)\n", hCtx, cMaxPkts, lpPkts);
+
+ if (!hCtx || !lpPkts) return 0;
+
+ 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;
+}
+
/***********************************************************************
* WTDataGet (WINTAB32.81)
*/
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);
+ if (!hCtx) return 0;
+ context = TABLET_FindOpenContext(hCtx);
+
+ 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;
+}
+
/***********************************************************************
* WTDataPeek (WINTAB32.82)
*/
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);
+ if (!hCtx) return 0;
+
+ context = TABLET_FindOpenContext(hCtx);
+
+ 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;
+}
+
/***********************************************************************
* WTQueuePacketsEx (WINTAB32.200)
*/
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);
+
+ if (!hCtx) return 0;
+
+ 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;
}
@@ -305,11 +844,13 @@
*/
int WINAPI WTQueueSizeGet(HCTX hCtx)
{
- FIXME("(%p): stub\n", hCtx);
+ LPOPENCONTEXT context;
+ TRACE("(%p)\n", hCtx);
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+ if (!hCtx) return 0;
- return 0;
+ context = TABLET_FindOpenContext(hCtx);
+ return context->QueueSize;
}
/***********************************************************************
@@ -317,9 +858,20 @@
*/
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;
+ if (!hCtx) 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;
}
--- /dev/null Thu Aug 30 15:30:55 2001
+++ dlls/wintab32/wintab32.c Thu Jan 8 08:47:13 2004
@@ -0,0 +1,155 @@
+/*
+ * 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 <stdarg.h>
+
+#include "windef.h"
+#include "winbase.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;
+
+UINT (*pWTInfoA)(UINT wCategory, UINT nIndex, LPVOID lpOutput) = NULL;
+
+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");
+ pWTInfoA = (void *)GetProcAddress(hx11drv, "WTInfoA");
+ 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 Thu Jan 8 08:47:13 2004
@@ -0,0 +1,163 @@
+/*
+ * 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_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(HWND hwnddefault);
+
+typedef int X11_GetCurrentPacket(LPWTPACKET packet);
+
+typedef int X11_AttachEventQueueToTablet(HWND hOwner);
+
+X11_LoadTabletInfo *pLoadTabletInfo;
+X11_AttachEventQueueToTablet *pAttachEventQueueToTablet;
+X11_GetCurrentPacket *pGetCurrentPacket;
+
+extern UINT (*pWTInfoA)(UINT wCategory, UINT nIndex, LPVOID lpOutput);
Index: include/wintab.h
===================================================================
RCS file: /home/wine/wine/include/wintab.h,v
retrieving revision 1.1
diff -u -w -r1.1 wintab.h
--- include/wintab.h 17 Dec 2002 01:49:16 -0000 1.1
+++ include/wintab.h 8 Jan 2004 14:59:11 -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
Index: dlls/x11drv/Makefile.in
===================================================================
RCS file: /home/wine/wine/dlls/x11drv/Makefile.in,v
retrieving revision 1.38
diff -u -w -r1.38 Makefile.in
--- dlls/x11drv/Makefile.in 5 Dec 2003 00:20:28 -0000 1.38
+++ dlls/x11drv/Makefile.in 8 Jan 2004 14:59:54 -0000
@@ -34,10 +34,12 @@
text.c \
window.c \
winpos.c \
+ wintab.c \
x11ddraw.c \
x11drv_main.c \
xdnd.c \
Index: dlls/x11drv/event.c
===================================================================
RCS file: /home/wine/wine/dlls/x11drv/event.c,v
retrieving revision 1.30
diff -u -w -r1.30 event.c
--- dlls/x11drv/event.c 5 Dec 2003 04:45:50 -0000 1.30
+++ dlls/x11drv/event.c 8 Jan 2004 14:59:54 -0000
@@ -275,8 +277,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 extension 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)
{
RCS file: /home/wine/wine/dlls/x11drv/x11drv.spec,v
retrieving revision 1.50
diff -u -w -r1.50 x11drv.spec
--- dlls/x11drv/x11drv.spec 26 Nov 2003 22:03:34 -0000 1.50
+++ dlls/x11drv/x11drv.spec 8 Jan 2004 14:59:57 -0000
@@ -114,3 +114,12 @@
# X11 locks
@ cdecl -norelay wine_tsx11_lock()
@ cdecl -norelay wine_tsx11_unlock()
+
+# WinTab32
+@ cdecl LoadTabletInfo(long) X11DRV_LoadTabletInfo
+@ cdecl AttachEventQueueToTablet(long) X11DRV_AttachEventQueueToTablet
+@ cdecl GetCurrentPacket(ptr) X11DRV_GetCurrentPacket
+@ cdecl WTInfoA(long long ptr) X11DRV_WTInfoA
Index: dlls/x11drv/x11drv_main.c
===================================================================
RCS file: /home/wine/wine/dlls/x11drv/x11drv_main.c,v
retrieving revision 1.83
diff -u -w -r1.83 x11drv_main.c
--- dlls/x11drv/x11drv_main.c 5 Dec 2003 00:11:48 -0000 1.83
+++ dlls/x11drv/x11drv_main.c 8 Jan 2004 14:59:57 -0000
@@ -62,7 +62,10 @@
#include "xrandr.h"
#include "dga2.h"
#include "wine/server.h"
+#include "wine/unicode.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(x11drv);
--- /dev/null Thu Aug 30 15:30:55 2001
+++ dlls/x11drv/wintab.c Thu Jan 8 08:47:17 2004
@@ -0,0 +1,1134 @@
+/*
+ * 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 "wine/port.h"
+
+#include <stdlib.h>
+#include <X11/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"
+
+WINE_DEFAULT_DEBUG_CHANNEL(wintab32);
+WINE_DECLARE_DEBUG_CHANNEL(event);
+
+
+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_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 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;
+
+
+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};
+
+#define CURSORMAX 10
+
+static LOGCONTEXTA gSysContext;
+static WTI_DEVICES_INFO gSysDevice;
+static WTI_CURSORS_INFO gSysCursor[CURSORMAX];
+static INT gNumCursors;
+
+
+/* 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;
+}
+
+void X11DRV_LoadTabletInfo(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;
+ }
+
+ hwndTabletDefault = hwnddefault;
+
+ /* Do base initializaion */
+ strcpy(gSysContext.lcName, "Wine Tablet Context");
+ strcpy(gSysDevice.NAME,"Wine Tablet Device");
+
+ gSysContext.lcOptions = CXO_SYSTEM | CXO_MESSAGES | CXO_CSRMESSAGES;
+ gSysContext.lcLocks = CXL_INSIZE | CXL_INASPECT | CXL_MARGIN |
+ CXL_SENSITIVITY | CXL_SYSOUT;
+
+ gSysContext.lcMsgBase= WT_DEFBASE;
+ gSysContext.lcDevice = 0;
+ gSysContext.lcPktData =
+ PK_CONTEXT | PK_STATUS | PK_SERIAL_NUMBER| PK_TIME | PK_CURSOR |
+ PK_BUTTONS | PK_X | PK_Y | PK_NORMAL_PRESSURE | PK_ORIENTATION;
+ gSysContext.lcMoveMask=
+ PK_BUTTONS | PK_X | PK_Y | PK_NORMAL_PRESSURE | PK_ORIENTATION;
+ gSysContext.lcStatus = CXS_ONTOP;
+ gSysContext.lcPktRate = 100;
+ gSysContext.lcBtnDnMask = 0xffffffff;
+ gSysContext.lcBtnUpMask = 0xffffffff;
+ gSysContext.lcSensX = 65536;
+ gSysContext.lcSensY = 65536;
+ gSysContext.lcSensX = 65536;
+ gSysContext.lcSensZ = 65536;
+ gSysContext.lcSysSensX= 65536;
+ gSysContext.lcSysSensY= 65536;
+
+ /* Device Defaults */
+ gSysDevice.HARDWARE = HWC_HARDPROX|HWC_PHYSID_CURSORS;
+ gSysDevice.FIRSTCSR= 0;
+ gSysDevice.PKTRATE = 100;
+ gSysDevice.PKTDATA =
+ PK_CONTEXT | PK_STATUS | PK_SERIAL_NUMBER| PK_TIME | PK_CURSOR |
+ PK_BUTTONS | PK_X | PK_Y | PK_NORMAL_PRESSURE | PK_ORIENTATION;
+ strcpy(gSysDevice.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;
+ }
+ 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 Extension Device\n");
+ cursor_target++;
+ target = &devices[loop];
+ cursor = &gSysCursor[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 */
+ gSysDevice.X.axMin = Axis->min_value;
+ gSysDevice.X.axMax= Axis->max_value;
+ gSysDevice.X.axUnits = 1;
+ gSysDevice.X.axResolution = Axis->resolution;
+ gSysContext.lcInOrgX = Axis->min_value;
+ gSysContext.lcSysOrgX = Axis->min_value;
+ gSysContext.lcInExtX = Axis->max_value;
+ gSysContext.lcSysExtX = Axis->max_value;
+ Axis++;
+ }
+ if (Val->num_axes>=2)
+ {
+ /* Axis 2 is Y */
+ gSysDevice.Y.axMin = Axis->min_value;
+ gSysDevice.Y.axMax= Axis->max_value;
+ gSysDevice.Y.axUnits = 1;
+ gSysDevice.Y.axResolution = Axis->resolution;
+ gSysContext.lcInOrgY = Axis->min_value;
+ gSysContext.lcSysOrgY = Axis->min_value;
+ gSysContext.lcInExtY = Axis->max_value;
+ gSysContext.lcSysExtY = Axis->max_value;
+ Axis++;
+ }
+ if (Val->num_axes>=3)
+ {
+ /* Axis 3 is Normal Pressure */
+ gSysDevice.NPRESSURE.axMin = Axis->min_value;
+ gSysDevice.NPRESSURE.axMax= Axis->max_value;
+ gSysDevice.NPRESSURE.axUnits = 1;
+ gSysDevice.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)))
+ {
+ gSysDevice.ORIENTATION[0].axMin = 0;
+ gSysDevice.ORIENTATION[0].axMax = 3600;
+ gSysDevice.ORIENTATION[0].axUnits = 1;
+ gSysDevice.ORIENTATION[0].axResolution =
+ 235929600;
+ gSysDevice.ORIENTATION[1].axMin = -1000;
+ gSysDevice.ORIENTATION[1].axMax = 1000;
+ gSysDevice.ORIENTATION[1].axUnits = 1;
+ gSysDevice.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();
+ gSysDevice.NCSRTYPES = cursor_target+1;
+ gNumCursors = 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)("Received tablet motion event (%p)\n",hwnd);
+ TRACE("Received 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];
+ 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)("Received tablet button event\n");
+ TRACE("Received 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)("Received tablet key press event\n");
+ FIXME("Received tablet key press event\n");
+ }
+ else if (event->type == key_release_type)
+ {
+ TRACE_(event)("Received tablet key release event\n");
+ FIXME("Received tablet key release event\n");
+ }
+ else if ((event->type == proximity_in_type) ||
+ (event->type == proximity_out_type))
+ {
+ TRACE_(event)("Received tablet proximity event\n");
+ TRACE("Received 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)
+{
+ 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, gNumCursors);
+
+ devices = pXListInputDevices(data->display, &num_devices);
+
+ for (cur_loop=0; cur_loop < gNumCursors; cur_loop++)
+ {
+ int event_number=0;
+
+ for (loop=0; loop < num_devices; loop ++)
+ if (strcmp(devices[loop].name,gSysCursor[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;
+}
+
+
+int static inline CopyTabletData(LPVOID target, LPVOID src, INT size)
+{
+ memcpy(target,src,size);
+ return(size);
+}
+
+/***********************************************************************
+ * X11DRV_WTInfoA (X11DRV.@)
+ */
+UINT X11DRV_WTInfoA(UINT wCategory, UINT nIndex, LPVOID lpOutput)
+{
+ int rc = 0;
+ LPWTI_CURSORS_INFO tgtcursor;
+ TRACE("(%u, %u, %p)\n", wCategory, nIndex, lpOutput);
+
+ switch(wCategory)
+ {
+ case 0:
+ /* return largest necessary 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:
+ 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;
+}
Jan. 8, 2004
Re: Wineconf update, RFC re remote participation
by Jeremy White
> I remember getting all sorts of spam about very cheap conference calling.
> It can't be that expensive, we just set up a US number, the caller
> pays the long distance charges (which are very small right now)...
Well, we've had a tentative offer from someone to use their conference
services; I'll see if that pans out.
However, conference calling services (one of which we use
regularly) are ostensibly 'cheap', but their prices scale
by the multiple of number of connections and length of time.
48 hours times many callers would shatter my budget.
Now, if you *own* the conference box (which is easy to do; you
can buy 'em for a few K or build them easily), then you only have
fixed costs, and can afford something like this easily. I
believe that's the case in the service I've been offered.
Cheers,
Jeremy
Jan. 8, 2004
Re: www.winehq.org down?
by Francois Gouget
On Thu, 8 Jan 2004, Michael Stefaniuc wrote:
> Hello,
>
> is the www.winehq.org website down? The host is pingable and port 80 is
> open but i get no data after the initial tcp connect.
I believe it had trouble earlier today but it should work now.
--
Francois Gouget fgouget(a)free.fr http://fgouget.free.fr/
La terre est une b\xEAta...
Jan. 8, 2004