Welcome rdesktop!

svn path=/trunk/; revision=22620
This commit is contained in:
Michele Cicciotti
2006-06-26 00:00:00 +00:00
parent fb2aaa54a0
commit 01f3e24360
129 changed files with 46039 additions and 0 deletions
@@ -0,0 +1,346 @@
This software is released under the GNU General Public License
(reproduced below) with the additional exemption that compiling,
linking, and/or using OpenSSL together with this software is
allowed.
---
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
675 Mass Ave, Cambridge, MA 02139, USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Library General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
Appendix: How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) 19yy <name of author>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) 19yy name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Library General
Public License instead of this License.
@@ -0,0 +1,158 @@
#
# rdesktop: A Remote Desktop Protocol client
# Makefile.in
# Copyright (C) Matthew Chapman 1999-2005
#
prefix = @prefix@
exec_prefix = @exec_prefix@
bindir = @bindir@
mandir = @mandir@
datadir = @datadir@
VERSION = @PACKAGE_VERSION@
KEYMAP_PATH = $(datadir)/rdesktop/keymaps/
CC = @CC@
INSTALL = @INSTALL@
CFLAGS = @CFLAGS@ @X_CFLAGS@ @DEFS@ -DKEYMAP_PATH=\"$(KEYMAP_PATH)\"
LDFLAGS = @LDFLAGS@ @LIBS@ @X_LIBS@ @X_EXTRA_LIBS@
STRIP = @STRIP@
TARGETS = rdesktop @RDP2VNCTARGET@
VNCINC = @VNCINC@
LDVNC = @LDVNC@
VNCLINK = @VNCLINK@
SOUNDOBJ = @SOUNDOBJ@
RDPOBJ = tcp.o iso.o mcs.o secure.o licence.o rdp.o orders.o bitmap.o cache.o rdp5.o channels.o rdpdr.o serial.o printer.o disk.o parallel.o printercache.o mppc.o pstcache.o lspci.o seamless.o
X11OBJ = rdesktop.o xwin.o xkeymap.o ewmhints.o xclip.o cliprdr.o
VNCOBJ = vnc/rdp2vnc.o vnc/vnc.o vnc/xkeymap.o vnc/x11stubs.o
.PHONY: all
all: $(TARGETS)
rdesktop: $(X11OBJ) $(SOUNDOBJ) $(RDPOBJ)
$(CC) $(CFLAGS) -o rdesktop $(X11OBJ) $(SOUNDOBJ) $(RDPOBJ) $(LDFLAGS) -lX11
rdp2vnc: $(VNCOBJ) $(SOUNDOBJ) $(RDPOBJ)
$(VNCLINK) $(CFLAGS) -o rdp2vnc $(VNCOBJ) $(SOUNDOBJ) $(RDPOBJ) $(LDFLAGS) $(LDVNC)
vnc/rdp2vnc.o: rdesktop.c
$(CC) $(CFLAGS) $(VNCINC) -DRDP2VNC -o vnc/rdp2vnc.o -c rdesktop.c
vnc/vnc.o: vnc/vnc.c
$(CC) $(CFLAGS) $(VNCINC) -DRDP2VNC -o vnc/vnc.o -c vnc/vnc.c
vnc/xkeymap.o: xkeymap.c
$(CC) $(CFLAGS) $(VNCINC) -DRDP2VNC -o vnc/xkeymap.o -c xkeymap.c
vnc/x11stubs.o: vnc/x11stubs.c
$(CC) $(CFLAGS) $(VNCINC) -o vnc/x11stubs.o -c vnc/x11stubs.c
.PHONY: install
install: installbin installkeymaps installman
.PHONY: installbin
installbin: rdesktop
mkdir -p $(DESTDIR)$(bindir)
$(INSTALL) rdesktop $(DESTDIR)$(bindir)
$(STRIP) $(DESTDIR)$(bindir)/rdesktop
chmod 755 $(DESTDIR)$(bindir)/rdesktop
.PHONY: installman
installman: doc/rdesktop.1
mkdir -p $(DESTDIR)$(mandir)/man1
cp doc/rdesktop.1 $(DESTDIR)$(mandir)/man1
chmod 644 $(DESTDIR)$(mandir)/man1/rdesktop.1
.PHONY: installkeymaps
installkeymaps:
mkdir -p $(DESTDIR)$(KEYMAP_PATH)
# Prevent copying the CVS directory
cp keymaps/?? keymaps/??-?? $(DESTDIR)$(KEYMAP_PATH)
cp keymaps/common $(DESTDIR)$(KEYMAP_PATH)
cp keymaps/modifiers $(DESTDIR)$(KEYMAP_PATH)
chmod 644 $(DESTDIR)$(KEYMAP_PATH)/*
.PHONY: proto
proto:
cat proto.head > proto.h
cproto -DMAKE_PROTO \
bitmap.c cache.c channels.c cliprdr.c disk.c mppc.c ewmhints.c \
iso.c licence.c mcs.c orders.c parallel.c printer.c printercache.c \
pstcache.c rdesktop.c rdp5.c rdp.c rdpdr.c rdpsnd.c rdpsnd_oss.c \
secure.c serial.c tcp.c xclip.c xkeymap.c xwin.c lspci.c seamless.c >> proto.h
cat proto.tail >> proto.h
.PHONY: clean
clean:
rm -f *.o *~ vnc/*.o vnc/*~ rdesktop rdp2vnc
.PHONY: distclean
distclean: clean
rm -rf autom4te.cache config.log config.status Makefile
.PHONY: dist
dist: rdesktop-$(VERSION).tar.gz
rdesktop-$(VERSION).tar.gz: Makefile configure
mkdir -p /tmp/rdesktop-make-dist-dir
ln -sf `pwd` /tmp/rdesktop-make-dist-dir/rdesktop-$(VERSION)
(cd /tmp/rdesktop-make-dist-dir; \
tar zcvf rdesktop-$(VERSION)/rdesktop-$(VERSION).tar.gz \
rdesktop-$(VERSION)/COPYING \
rdesktop-$(VERSION)/README \
rdesktop-$(VERSION)/configure \
rdesktop-$(VERSION)/configure.ac \
rdesktop-$(VERSION)/config.sub \
rdesktop-$(VERSION)/config.guess \
rdesktop-$(VERSION)/bootstrap \
rdesktop-$(VERSION)/install-sh \
rdesktop-$(VERSION)/Makefile.in \
rdesktop-$(VERSION)/rdesktop.spec \
rdesktop-$(VERSION)/*.c \
rdesktop-$(VERSION)/*.h \
rdesktop-$(VERSION)/proto.head \
rdesktop-$(VERSION)/proto.tail \
rdesktop-$(VERSION)/keymaps/?? \
rdesktop-$(VERSION)/keymaps/??-?? \
rdesktop-$(VERSION)/keymaps/common \
rdesktop-$(VERSION)/keymaps/modifiers \
rdesktop-$(VERSION)/keymaps/convert-map \
rdesktop-$(VERSION)/doc/HACKING \
rdesktop-$(VERSION)/doc/AUTHORS \
rdesktop-$(VERSION)/doc/TODO \
rdesktop-$(VERSION)/doc/ChangeLog \
rdesktop-$(VERSION)/doc/keymapping.txt \
rdesktop-$(VERSION)/doc/keymap-names.txt \
rdesktop-$(VERSION)/doc/ipv6.txt \
rdesktop-$(VERSION)/doc/licensing.txt \
rdesktop-$(VERSION)/doc/patches.txt \
rdesktop-$(VERSION)/doc/redirection.txt \
rdesktop-$(VERSION)/doc/rdesktop.1 )
rm -rf /tmp/rdesktop-make-dist-dir
.PHONY: dist-noversion
dist-noversion: rdesktop.tar.gz
rdesktop.tar.gz: rdesktop-$(VERSION).tar.gz
mkdir -p /tmp/rdesktop-make-dist-dir
tar zxvf $< -C /tmp/rdesktop-make-dist-dir
mv /tmp/rdesktop-make-dist-dir/rdesktop-$(VERSION) /tmp/rdesktop-make-dist-dir/rdesktop
ls /tmp/rdesktop-make-dist-dir/rdesktop
tar zcvf $@ -C /tmp/rdesktop-make-dist-dir rdesktop
rm -rf /tmp/rdesktop-make-dist-dir
Makefile: Makefile.in configure
./config.status
configure: configure.ac
./bootstrap
.SUFFIXES:
.SUFFIXES: .c .o
.c.o:
$(CC) $(CFLAGS) -o $@ -c $<
@@ -0,0 +1,32 @@
===========================================
rdesktop: A Remote Desktop Protocol client.
===========================================
rdesktop is a client for Microsoft Windows NT Terminal Server, Windows 2000
Terminal Services, Windows 2003 Terminal Services/Remote Desktop, Windows XP
Remote Desktop, and possibly other Terminal Services products.
rdesktop currently implements the RDP version 4 and 5 protocols.
Installation
------------
rdesktop uses a typical GNU-style build procedure:
% ./configure [options]
% make
% make install
where documentation for [options] can be found by running "./configure --help".
Usually no options are necessary. The default is to install under /usr/local,
this can be changed with --prefix=directory.
Invocation
----------
% rdesktop [options] server
where server is the name of the Terminal Services machine. Note: if you
receive "Connection refused", this probably means that the server does not have
Terminal Services enabled, or there is a firewall blocking access.
The rdesktop manual page lists the possible options ("man rdesktop").
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,3 @@
#!/bin/sh
rm -rf autom4te.cache
autoreconf -i
@@ -0,0 +1,432 @@
/* -*- c-basic-offset: 8 -*-
rdesktop: A Remote Desktop Protocol client.
Cache routines
Copyright (C) Matthew Chapman 1999-2005
Copyright (C) Jeroen Meijer 2005
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "rdesktop.h"
/* BITMAP CACHE */
extern int g_pstcache_fd[];
#define NUM_ELEMENTS(array) (sizeof(array) / sizeof(array[0]))
#define IS_PERSISTENT(id) (g_pstcache_fd[id] > 0)
#define TO_TOP -1
#define NOT_SET -1
#define IS_SET(idx) (idx >= 0)
/*
* TODO: Test for optimal value of BUMP_COUNT. TO_TOP gives lowest cpu utilisation but using
* a positive value will hopefully result in less frequently used bitmaps having a greater chance
* of being evicted from the cache, and therby reducing the need to load bitmaps from disk.
* (Jeroen)
*/
#define BUMP_COUNT 40
struct bmpcache_entry
{
HBITMAP bitmap;
sint16 previous;
sint16 next;
};
static struct bmpcache_entry g_bmpcache[3][0xa00];
static HBITMAP g_volatile_bc[3];
static int g_bmpcache_lru[3] = { NOT_SET, NOT_SET, NOT_SET };
static int g_bmpcache_mru[3] = { NOT_SET, NOT_SET, NOT_SET };
static int g_bmpcache_count[3];
/* Setup the bitmap cache lru/mru linked list */
void
cache_rebuild_bmpcache_linked_list(uint8 id, sint16 * idx, int count)
{
int n = count, c = 0;
sint16 n_idx;
/* find top, skip evicted bitmaps */
while (--n >= 0 && g_bmpcache[id][idx[n]].bitmap == NULL);
if (n < 0)
{
g_bmpcache_mru[id] = g_bmpcache_lru[id] = NOT_SET;
return;
}
g_bmpcache_mru[id] = idx[n];
g_bmpcache[id][idx[n]].next = NOT_SET;
n_idx = idx[n];
c++;
/* link list */
while (n >= 0)
{
/* skip evicted bitmaps */
while (--n >= 0 && g_bmpcache[id][idx[n]].bitmap == NULL);
if (n < 0)
break;
g_bmpcache[id][n_idx].previous = idx[n];
g_bmpcache[id][idx[n]].next = n_idx;
n_idx = idx[n];
c++;
}
g_bmpcache[id][n_idx].previous = NOT_SET;
g_bmpcache_lru[id] = n_idx;
if (c != g_bmpcache_count[id])
{
error("Oops. %d in bitmap cache linked list, %d in ui cache...\n", c,
g_bmpcache_count[id]);
exit(1);
}
}
/* Move a bitmap to a new position in the linked list. */
void
cache_bump_bitmap(uint8 id, uint16 idx, int bump)
{
int p_idx, n_idx, n;
if (!IS_PERSISTENT(id))
return;
if (g_bmpcache_mru[id] == idx)
return;
DEBUG_RDP5(("bump bitmap: id=%d, idx=%d, bump=%d\n", id, idx, bump));
n_idx = g_bmpcache[id][idx].next;
p_idx = g_bmpcache[id][idx].previous;
if (IS_SET(n_idx))
{
/* remove */
--g_bmpcache_count[id];
if (IS_SET(p_idx))
g_bmpcache[id][p_idx].next = n_idx;
else
g_bmpcache_lru[id] = n_idx;
if (IS_SET(n_idx))
g_bmpcache[id][n_idx].previous = p_idx;
else
g_bmpcache_mru[id] = p_idx;
}
else
{
p_idx = NOT_SET;
n_idx = g_bmpcache_lru[id];
}
if (bump >= 0)
{
for (n = 0; n < bump && IS_SET(n_idx); n++)
{
p_idx = n_idx;
n_idx = g_bmpcache[id][p_idx].next;
}
}
else
{
p_idx = g_bmpcache_mru[id];
n_idx = NOT_SET;
}
/* insert */
++g_bmpcache_count[id];
g_bmpcache[id][idx].previous = p_idx;
g_bmpcache[id][idx].next = n_idx;
if (p_idx >= 0)
g_bmpcache[id][p_idx].next = idx;
else
g_bmpcache_lru[id] = idx;
if (n_idx >= 0)
g_bmpcache[id][n_idx].previous = idx;
else
g_bmpcache_mru[id] = idx;
}
/* Evict the least-recently used bitmap from the cache */
void
cache_evict_bitmap(uint8 id)
{
uint16 idx;
int n_idx;
if (!IS_PERSISTENT(id))
return;
idx = g_bmpcache_lru[id];
n_idx = g_bmpcache[id][idx].next;
DEBUG_RDP5(("evict bitmap: id=%d idx=%d n_idx=%d bmp=0x%x\n", id, idx, n_idx,
g_bmpcache[id][idx].bitmap));
ui_destroy_bitmap(g_bmpcache[id][idx].bitmap);
--g_bmpcache_count[id];
g_bmpcache[id][idx].bitmap = 0;
g_bmpcache_lru[id] = n_idx;
g_bmpcache[id][n_idx].previous = NOT_SET;
pstcache_touch_bitmap(id, idx, 0);
}
/* Retrieve a bitmap from the cache */
HBITMAP
cache_get_bitmap(uint8 id, uint16 idx)
{
if ((id < NUM_ELEMENTS(g_bmpcache)) && (idx < NUM_ELEMENTS(g_bmpcache[0])))
{
if (g_bmpcache[id][idx].bitmap || pstcache_load_bitmap(id, idx))
{
if (IS_PERSISTENT(id))
cache_bump_bitmap(id, idx, BUMP_COUNT);
return g_bmpcache[id][idx].bitmap;
}
}
else if ((id < NUM_ELEMENTS(g_volatile_bc)) && (idx == 0x7fff))
{
return g_volatile_bc[id];
}
error("get bitmap %d:%d\n", id, idx);
return NULL;
}
/* Store a bitmap in the cache */
void
cache_put_bitmap(uint8 id, uint16 idx, HBITMAP bitmap)
{
HBITMAP old;
if ((id < NUM_ELEMENTS(g_bmpcache)) && (idx < NUM_ELEMENTS(g_bmpcache[0])))
{
old = g_bmpcache[id][idx].bitmap;
if (old != NULL)
ui_destroy_bitmap(old);
g_bmpcache[id][idx].bitmap = bitmap;
if (IS_PERSISTENT(id))
{
if (old == NULL)
g_bmpcache[id][idx].previous = g_bmpcache[id][idx].next = NOT_SET;
cache_bump_bitmap(id, idx, TO_TOP);
if (g_bmpcache_count[id] > BMPCACHE2_C2_CELLS)
cache_evict_bitmap(id);
}
}
else if ((id < NUM_ELEMENTS(g_volatile_bc)) && (idx == 0x7fff))
{
old = g_volatile_bc[id];
if (old != NULL)
ui_destroy_bitmap(old);
g_volatile_bc[id] = bitmap;
}
else
{
error("put bitmap %d:%d\n", id, idx);
}
}
/* Updates the persistent bitmap cache MRU information on exit */
void
cache_save_state(void)
{
uint32 id = 0, t = 0;
int idx;
for (id = 0; id < NUM_ELEMENTS(g_bmpcache); id++)
if (IS_PERSISTENT(id))
{
DEBUG_RDP5(("Saving cache state for bitmap cache %d...", id));
idx = g_bmpcache_lru[id];
while (idx >= 0)
{
pstcache_touch_bitmap(id, idx, ++t);
idx = g_bmpcache[id][idx].next;
}
DEBUG_RDP5((" %d stamps written.\n", t));
}
}
/* FONT CACHE */
static FONTGLYPH g_fontcache[12][256];
/* Retrieve a glyph from the font cache */
FONTGLYPH *
cache_get_font(uint8 font, uint16 character)
{
FONTGLYPH *glyph;
if ((font < NUM_ELEMENTS(g_fontcache)) && (character < NUM_ELEMENTS(g_fontcache[0])))
{
glyph = &g_fontcache[font][character];
if (glyph->pixmap != NULL)
return glyph;
}
error("get font %d:%d\n", font, character);
return NULL;
}
/* Store a glyph in the font cache */
void
cache_put_font(uint8 font, uint16 character, uint16 offset,
uint16 baseline, uint16 width, uint16 height, HGLYPH pixmap)
{
FONTGLYPH *glyph;
if ((font < NUM_ELEMENTS(g_fontcache)) && (character < NUM_ELEMENTS(g_fontcache[0])))
{
glyph = &g_fontcache[font][character];
if (glyph->pixmap != NULL)
ui_destroy_glyph(glyph->pixmap);
glyph->offset = offset;
glyph->baseline = baseline;
glyph->width = width;
glyph->height = height;
glyph->pixmap = pixmap;
}
else
{
error("put font %d:%d\n", font, character);
}
}
/* TEXT CACHE */
static DATABLOB g_textcache[256];
/* Retrieve a text item from the cache */
DATABLOB *
cache_get_text(uint8 cache_id)
{
DATABLOB *text;
text = &g_textcache[cache_id];
return text;
}
/* Store a text item in the cache */
void
cache_put_text(uint8 cache_id, void *data, int length)
{
DATABLOB *text;
text = &g_textcache[cache_id];
if (text->data != NULL)
xfree(text->data);
text->data = xmalloc(length);
text->size = length;
memcpy(text->data, data, length);
}
/* DESKTOP CACHE */
static uint8 g_deskcache[0x38400 * 4];
/* Retrieve desktop data from the cache */
uint8 *
cache_get_desktop(uint32 offset, int cx, int cy, int bytes_per_pixel)
{
int length = cx * cy * bytes_per_pixel;
if (offset > sizeof(g_deskcache))
offset = 0;
if ((offset + length) <= sizeof(g_deskcache))
{
return &g_deskcache[offset];
}
error("get desktop %d:%d\n", offset, length);
return NULL;
}
/* Store desktop data in the cache */
void
cache_put_desktop(uint32 offset, int cx, int cy, int scanline, int bytes_per_pixel, uint8 * data)
{
int length = cx * cy * bytes_per_pixel;
if (offset > sizeof(g_deskcache))
offset = 0;
if ((offset + length) <= sizeof(g_deskcache))
{
cx *= bytes_per_pixel;
while (cy--)
{
memcpy(&g_deskcache[offset], data, cx);
data += scanline;
offset += cx;
}
}
else
{
error("put desktop %d:%d\n", offset, length);
}
}
/* CURSOR CACHE */
static HCURSOR g_cursorcache[0x20];
/* Retrieve cursor from cache */
HCURSOR
cache_get_cursor(uint16 cache_idx)
{
HCURSOR cursor;
if (cache_idx < NUM_ELEMENTS(g_cursorcache))
{
cursor = g_cursorcache[cache_idx];
if (cursor != NULL)
return cursor;
}
error("get cursor %d\n", cache_idx);
return NULL;
}
/* Store cursor in cache */
void
cache_put_cursor(uint16 cache_idx, HCURSOR cursor)
{
HCURSOR old;
if (cache_idx < NUM_ELEMENTS(g_cursorcache))
{
old = g_cursorcache[cache_idx];
if (old != NULL)
ui_destroy_cursor(old);
g_cursorcache[cache_idx] = cursor;
}
else
{
error("put cursor %d\n", cache_idx);
}
}
@@ -0,0 +1,181 @@
/* -*- c-basic-offset: 8 -*-
rdesktop: A Remote Desktop Protocol client.
Protocol services - Virtual channels
Copyright (C) Erik Forsberg <[email protected]> 2003
Copyright (C) Matthew Chapman 2003-2005
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "rdesktop.h"
#define MAX_CHANNELS 6
#define CHANNEL_CHUNK_LENGTH 1600
#define CHANNEL_FLAG_FIRST 0x01
#define CHANNEL_FLAG_LAST 0x02
#define CHANNEL_FLAG_SHOW_PROTOCOL 0x10
extern BOOL g_use_rdp5;
extern BOOL g_encryption;
VCHANNEL g_channels[MAX_CHANNELS];
unsigned int g_num_channels;
/* FIXME: We should use the information in TAG_SRV_CHANNELS to map RDP5
channels to MCS channels.
The format of TAG_SRV_CHANNELS seems to be
global_channel_no (uint16le)
number_of_other_channels (uint16le)
..followed by uint16les for the other channels.
*/
VCHANNEL *
channel_register(char *name, uint32 flags, void (*callback) (STREAM))
{
VCHANNEL *channel;
if (!g_use_rdp5)
return NULL;
if (g_num_channels >= MAX_CHANNELS)
{
error("Channel table full, increase MAX_CHANNELS\n");
return NULL;
}
channel = &g_channels[g_num_channels];
channel->mcs_id = MCS_GLOBAL_CHANNEL + 1 + g_num_channels;
strncpy(channel->name, name, 8);
channel->flags = flags;
channel->process = callback;
g_num_channels++;
return channel;
}
STREAM
channel_init(VCHANNEL * channel, uint32 length)
{
STREAM s;
s = sec_init(g_encryption ? SEC_ENCRYPT : 0, length + 8);
s_push_layer(s, channel_hdr, 8);
return s;
}
void
channel_send(STREAM s, VCHANNEL * channel)
{
uint32 length, flags;
uint32 thislength, remaining;
uint8 *data;
/* first fragment sent in-place */
s_pop_layer(s, channel_hdr);
length = s->end - s->p - 8;
DEBUG_CHANNEL(("channel_send, length = %d\n", length));
thislength = MIN(length, CHANNEL_CHUNK_LENGTH);
/* Note: In the original clipboard implementation, this number was
1592, not 1600. However, I don't remember the reason and 1600 seems
to work so.. This applies only to *this* length, not the length of
continuation or ending packets. */
remaining = length - thislength;
flags = (remaining == 0) ? CHANNEL_FLAG_FIRST | CHANNEL_FLAG_LAST : CHANNEL_FLAG_FIRST;
if (channel->flags & CHANNEL_OPTION_SHOW_PROTOCOL)
flags |= CHANNEL_FLAG_SHOW_PROTOCOL;
out_uint32_le(s, length);
out_uint32_le(s, flags);
data = s->end = s->p + thislength;
DEBUG_CHANNEL(("Sending %d bytes with FLAG_FIRST\n", thislength));
sec_send_to_channel(s, g_encryption ? SEC_ENCRYPT : 0, channel->mcs_id);
/* subsequent segments copied (otherwise would have to generate headers backwards) */
while (remaining > 0)
{
thislength = MIN(remaining, CHANNEL_CHUNK_LENGTH);
remaining -= thislength;
flags = (remaining == 0) ? CHANNEL_FLAG_LAST : 0;
if (channel->flags & CHANNEL_OPTION_SHOW_PROTOCOL)
flags |= CHANNEL_FLAG_SHOW_PROTOCOL;
DEBUG_CHANNEL(("Sending %d bytes with flags %d\n", thislength, flags));
s = sec_init(g_encryption ? SEC_ENCRYPT : 0, thislength + 8);
out_uint32_le(s, length);
out_uint32_le(s, flags);
out_uint8p(s, data, thislength);
s_mark_end(s);
sec_send_to_channel(s, g_encryption ? SEC_ENCRYPT : 0, channel->mcs_id);
data += thislength;
}
}
void
channel_process(STREAM s, uint16 mcs_channel)
{
uint32 length, flags;
uint32 thislength;
VCHANNEL *channel = NULL;
unsigned int i;
STREAM in;
for (i = 0; i < g_num_channels; i++)
{
channel = &g_channels[i];
if (channel->mcs_id == mcs_channel)
break;
}
if (i >= g_num_channels)
return;
in_uint32_le(s, length);
in_uint32_le(s, flags);
if ((flags & CHANNEL_FLAG_FIRST) && (flags & CHANNEL_FLAG_LAST))
{
/* single fragment - pass straight up */
channel->process(s);
}
else
{
/* add fragment to defragmentation buffer */
in = &channel->in;
if (flags & CHANNEL_FLAG_FIRST)
{
if (length > in->size)
{
in->data = (uint8 *) xrealloc(in->data, length);
in->size = length;
}
in->p = in->data;
}
thislength = MIN(s->end - s->p, in->data + in->size - in->p);
memcpy(in->p, s->p, thislength);
in->p += thislength;
if (flags & CHANNEL_FLAG_LAST)
{
in->end = in->p;
in->p = in->data;
channel->process(in);
}
}
}
@@ -0,0 +1,187 @@
/* -*- c-basic-offset: 8 -*-
rdesktop: A Remote Desktop Protocol client.
Protocol services - Clipboard functions
Copyright (C) Erik Forsberg <[email protected]> 2003
Copyright (C) Matthew Chapman 2003
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "rdesktop.h"
#define CLIPRDR_CONNECT 1
#define CLIPRDR_FORMAT_ANNOUNCE 2
#define CLIPRDR_FORMAT_ACK 3
#define CLIPRDR_DATA_REQUEST 4
#define CLIPRDR_DATA_RESPONSE 5
#define CLIPRDR_REQUEST 0
#define CLIPRDR_RESPONSE 1
#define CLIPRDR_ERROR 2
static VCHANNEL *cliprdr_channel;
static uint8 *last_formats = NULL;
static uint32 last_formats_length = 0;
static void
cliprdr_send_packet(uint16 type, uint16 status, uint8 * data, uint32 length)
{
STREAM s;
DEBUG_CLIPBOARD(("CLIPRDR send: type=%d, status=%d, length=%d\n", type, status, length));
s = channel_init(cliprdr_channel, length + 12);
out_uint16_le(s, type);
out_uint16_le(s, status);
out_uint32_le(s, length);
out_uint8p(s, data, length);
out_uint32(s, 0); /* pad? */
s_mark_end(s);
channel_send(s, cliprdr_channel);
}
/* Helper which announces our readiness to supply clipboard data
in a single format (such as CF_TEXT) to the RDP side.
To announce more than one format at a time, use
cliprdr_send_native_format_announce.
*/
void
cliprdr_send_simple_native_format_announce(uint32 format)
{
uint8 buffer[36];
DEBUG_CLIPBOARD(("cliprdr_send_simple_native_format_announce\n"));
buf_out_uint32(buffer, format);
memset(buffer + 4, 0, sizeof(buffer) - 4); /* description */
cliprdr_send_native_format_announce(buffer, sizeof(buffer));
}
/* Announces our readiness to supply clipboard data in multiple
formats, each denoted by a 36-byte format descriptor of
[ uint32 format + 32-byte description ].
*/
void
cliprdr_send_native_format_announce(uint8 * formats_data, uint32 formats_data_length)
{
DEBUG_CLIPBOARD(("cliprdr_send_native_format_announce\n"));
cliprdr_send_packet(CLIPRDR_FORMAT_ANNOUNCE, CLIPRDR_REQUEST, formats_data,
formats_data_length);
if (formats_data != last_formats)
{
if (last_formats)
xfree(last_formats);
last_formats = xmalloc(formats_data_length);
memcpy(last_formats, formats_data, formats_data_length);
last_formats_length = formats_data_length;
}
}
void
cliprdr_send_data_request(uint32 format)
{
uint8 buffer[4];
DEBUG_CLIPBOARD(("cliprdr_send_data_request\n"));
buf_out_uint32(buffer, format);
cliprdr_send_packet(CLIPRDR_DATA_REQUEST, CLIPRDR_REQUEST, buffer, sizeof(buffer));
}
void
cliprdr_send_data(uint8 * data, uint32 length)
{
DEBUG_CLIPBOARD(("cliprdr_send_data\n"));
cliprdr_send_packet(CLIPRDR_DATA_RESPONSE, CLIPRDR_RESPONSE, data, length);
}
static void
cliprdr_process(STREAM s)
{
uint16 type, status;
uint32 length, format;
uint8 *data;
in_uint16_le(s, type);
in_uint16_le(s, status);
in_uint32_le(s, length);
data = s->p;
DEBUG_CLIPBOARD(("CLIPRDR recv: type=%d, status=%d, length=%d\n", type, status, length));
if (status == CLIPRDR_ERROR)
{
switch (type)
{
case CLIPRDR_FORMAT_ACK:
/* FIXME: We seem to get this when we send an announce while the server is
still processing a paste. Try sending another announce. */
cliprdr_send_native_format_announce(last_formats,
last_formats_length);
break;
case CLIPRDR_DATA_RESPONSE:
ui_clip_request_failed();
break;
default:
DEBUG_CLIPBOARD(("CLIPRDR error (type=%d)\n", type));
}
return;
}
switch (type)
{
case CLIPRDR_CONNECT:
ui_clip_sync();
break;
case CLIPRDR_FORMAT_ANNOUNCE:
ui_clip_format_announce(data, length);
cliprdr_send_packet(CLIPRDR_FORMAT_ACK, CLIPRDR_RESPONSE, NULL, 0);
return;
case CLIPRDR_FORMAT_ACK:
break;
case CLIPRDR_DATA_REQUEST:
in_uint32_le(s, format);
ui_clip_request_data(format);
break;
case CLIPRDR_DATA_RESPONSE:
ui_clip_handle_data(data, length);
break;
case 7: /* TODO: W2K3 SP1 sends this on connect with a value of 1 */
break;
default:
unimpl("CLIPRDR packet type %d\n", type);
}
}
void
cliprdr_set_mode(const char *optarg)
{
ui_clip_set_mode(optarg);
}
BOOL
cliprdr_init(void)
{
cliprdr_channel =
channel_register("cliprdr",
CHANNEL_OPTION_INITIALIZED | CHANNEL_OPTION_ENCRYPT_RDP |
CHANNEL_OPTION_COMPRESS_RDP | CHANNEL_OPTION_SHOW_PROTOCOL,
cliprdr_process);
return (cliprdr_channel != NULL);
}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,727 @@
AC_INIT(rdesktop, 1.4.1)
AC_CONFIG_SRCDIR([rdesktop.c])
AC_PROG_CC
if test "$GCC" = yes; then
CFLAGS="$CFLAGS -Wall"
fi
AC_PROG_INSTALL
AC_LANG_C
AC_HEADER_STDC
AC_C_BIGENDIAN([AC_DEFINE(B_ENDIAN)], [AC_DEFINE(L_ENDIAN)])
AC_PATH_XTRA
AC_SEARCH_LIBS(socket, socket)
AC_SEARCH_LIBS(inet_aton, resolv)
AC_CHECK_HEADER(sys/select.h, AC_DEFINE(HAVE_SYS_SELECT_H))
AC_CHECK_HEADER(sys/modem.h, AC_DEFINE(HAVE_SYS_MODEM_H))
AC_CHECK_HEADER(sys/filio.h, AC_DEFINE(HAVE_SYS_FILIO_H))
AC_CHECK_HEADER(sys/strtio.h, AC_DEFINE(HAVE_SYS_STRTIO_H))
AC_CHECK_HEADER(locale.h, AC_DEFINE(HAVE_LOCALE_H))
AC_CHECK_HEADER(langinfo.h, AC_DEFINE(HAVE_LANGINFO_H))
AC_CHECK_TOOL(STRIP, strip, :)
rpath=""
#
# OpenSSL detection borrowed from stunnel
#
checkssldir() { :
if test -f "$1/include/openssl/ssl.h"; then
ssldir="$1"
return 0
fi
return 1
}
AC_MSG_CHECKING([for OpenSSL directory])
AC_ARG_WITH(openssl,
[ --with-openssl=DIR look for OpenSSL at DIR/include, DIR/lib],
[
dnl Check the specified location only
checkssldir "$withval"
],
[
dnl Search default locations of OpenSSL library
for maindir in /usr/local /usr/lib /usr/pkg /usr /var/ssl /opt; do
for dir in $maindir $maindir/openssl $maindir/ssl; do
checkssldir $dir && break 2
done
done
]
)
if test -z "$ssldir"; then
AC_MSG_RESULT([Not found])
echo
echo "Couldn't find your OpenSSL library installation dir"
echo "Use --with-openssl option to fix this problem"
echo
exit 1
fi
AC_MSG_RESULT([$ssldir])
AC_SUBST(ssldir)
AC_DEFINE_UNQUOTED(ssldir, "$ssldir")
dnl Add OpenSSL includes and libraries
CFLAGS="$CFLAGS -I$ssldir/include"
AC_ARG_ENABLE(static-openssl,
[ --enable-static-openssl link OpenSSL statically],
[
LIBS="$LIBS $ssldir/lib/libcrypto.a"
],
[
LIBS="$LIBS -L$ssldir/lib -lcrypto"
rpath="$rpath:$ssldir/lib"
])
#
# Alignment
#
AC_MSG_CHECKING([if architecture needs alignment])
AC_TRY_RUN([
#include <stdlib.h>
#include <signal.h>
int main(int argc, char **argv)
{
unsigned char test[8] = { 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88 };
signal(SIGBUS, exit);
signal(SIGABRT, exit);
signal(SIGSEGV, exit);
if (*((unsigned int *)(test + 1)) != 0x55443322 && *((unsigned int *)(test + 1)) != 0x22334455) {
return 1;
}
return 0;
}],
[AC_MSG_RESULT(no)],
[AC_MSG_RESULT(yes)
AC_DEFINE(NEED_ALIGN)],
[AC_MSG_RESULT(assuming yes)
AC_DEFINE(NEED_ALIGN)])
#
# EGD
#
AC_ARG_WITH(egd-socket,
[ --with-egd-socket=PATH look for Entropy Gathering Daemon socket at PATH],
[EGD_SOCKET="$withval"],
[EGD_SOCKET="/var/run/egd-pool"]
)
AC_DEFINE_UNQUOTED(EGD_SOCKET, "$EGD_SOCKET")
#
# rdp2vnc
#
vncserverconfig=libvncserver-config
AC_ARG_WITH(libvncserver-config,
[ --with-libvncserver-config=CMD use CMD as libvncserver-config],
[vncserverconfig="$withval"]
)
AC_ARG_WITH(libvncserver,
[ --with-libvncserver make rdp2vnc],
[
VNCINC=`$vncserverconfig --cflags`
AC_SUBST(VNCINC)
LDVNC=`$vncserverconfig --libs`
AC_SUBST(LDVNC)
VNCLINK=`$vncserverconfig --link`
AC_SUBST(VNCLINK)
RDP2VNCTARGET="rdp2vnc"
AC_SUBST(RDP2VNCTARGET)
]
)
#
# sound
#
AC_ARG_WITH(libao,
[ --with-libao=DIR look for libao at DIR/include, DIR/lib],
[
CFLAGS="$CFLAGS -I$withval/include"
CPPFLAGS="$CPPFLAGS -I$withval/include"
LIBS="$LIBS -L$withval/lib"
rpath="$rpath:$withval/lib"
]
)
sound="yes"
AC_ARG_WITH(sound,
[ --with-sound select sound system ("oss", "sgi", "sun" or "libao") ],
[
sound="$withval"
])
if test "$sound" = yes; then
AC_CHECK_HEADER(ao/ao.h, [sound=libao])
AC_CHECK_HEADER(sys/soundcard.h, [sound=oss])
AC_CHECK_HEADER(dmedia/audio.h, [sound=sgi])
AC_CHECK_HEADER(sys/audioio.h, [sound=sun])
fi
if test "$sound" = no; then
break
elif test "$sound" = oss; then
SOUNDOBJ="rdpsnd.o rdpsnd_oss.o"
AC_DEFINE(WITH_RDPSND)
elif test "$sound" = sgi; then
SOUNDOBJ="rdpsnd.o rdpsnd_sgi.o"
LDFLAGS="$LDFLAGS -laudio"
AC_DEFINE(WITH_RDPSND)
elif test "$sound" = sun; then
SOUNDOBJ="rdpsnd.o rdpsnd_sun.o"
AC_DEFINE(WITH_RDPSND)
elif test "$sound" = libao; then
SOUNDOBJ="rdpsnd.o rdpsnd_libao.o"
LDFLAGS="$LDFLAGS -lao"
AC_DEFINE(WITH_RDPSND)
else
AC_MSG_WARN([sound support disabled])
AC_MSG_WARN([Currently supported systems are Open Sound System (oss), SGI AL (sgi), Sun/BSD (sun) and libao])
fi
AC_SUBST(SOUNDOBJ)
#
# dirfd
#
dnl Find out how to get the file descriptor associated with an open DIR*.
dnl From Jim Meyering
AC_DEFUN([UTILS_FUNC_DIRFD],
[
AC_HEADER_DIRENT
dirfd_headers='
#if HAVE_DIRENT_H
# include <dirent.h>
#else /* not HAVE_DIRENT_H */
# define dirent direct
# if HAVE_SYS_NDIR_H
# include <sys/ndir.h>
# endif /* HAVE_SYS_NDIR_H */
# if HAVE_SYS_DIR_H
# include <sys/dir.h>
# endif /* HAVE_SYS_DIR_H */
# if HAVE_NDIR_H
# include <ndir.h>
# endif /* HAVE_NDIR_H */
#endif /* HAVE_DIRENT_H */
'
AC_CHECK_FUNCS(dirfd)
AC_CHECK_DECLS([dirfd], , , $dirfd_headers)
AC_CACHE_CHECK([whether dirfd is a macro],
jm_cv_func_dirfd_macro,
[AC_EGREP_CPP([dirent_header_defines_dirfd], [$dirfd_headers
#ifdef dirfd
dirent_header_defines_dirfd
#endif],
jm_cv_func_dirfd_macro=yes,
jm_cv_func_dirfd_macro=no)])
# Use the replacement only if we have no function, macro,
# or declaration with that name.
if test $ac_cv_func_dirfd,$ac_cv_have_decl_dirfd,$jm_cv_func_dirfd_macro \
= no,no,no; then
AC_REPLACE_FUNCS([dirfd])
AC_CACHE_CHECK(
[how to get the file descriptor associated with an open DIR*],
gl_cv_sys_dir_fd_member_name,
[
dirfd_save_CFLAGS=$CFLAGS
for ac_expr in d_fd dd_fd; do
CFLAGS="$CFLAGS -DDIR_FD_MEMBER_NAME=$ac_expr"
AC_TRY_COMPILE(
[$dirfd_headers
],
[DIR *dir_p = opendir("."); (void) dir_p->DIR_FD_MEMBER_NAME;],
dir_fd_found=yes
)
CFLAGS=$dirfd_save_CFLAGS
test "$dir_fd_found" = yes && break
done
test "$dir_fd_found" = yes || ac_expr=no_such_member
gl_cv_sys_dir_fd_member_name=$ac_expr
]
)
if test $gl_cv_sys_dir_fd_member_name != no_such_member; then
AC_DEFINE_UNQUOTED(DIR_FD_MEMBER_NAME,
$gl_cv_sys_dir_fd_member_name,
[the name of the file descriptor member of DIR])
fi
AH_VERBATIM(DIR_TO_FD,
[#ifdef DIR_FD_MEMBER_NAME
# define DIR_TO_FD(Dir_p) ((Dir_p)->DIR_FD_MEMBER_NAME)
#else
# define DIR_TO_FD(Dir_p) -1
#endif
]
)
fi
])
UTILS_FUNC_DIRFD
#
# iconv
#
dnl This macros shamelessly stolen from
dnl http://gcc.gnu.org/ml/gcc-bugs/2001-06/msg01398.html.
dnl Written by Bruno Haible.
AC_DEFUN([UTILS_FUNC_ICONV],
[
dnl Some systems have iconv in libc, some have it in libiconv (OSF/1 and
dnl those with the standalone portable GNU libiconv installed).
AC_ARG_WITH([libiconv-prefix],
[ --with-libiconv-prefix=DIR search for libiconv in DIR/include and DIR/lib], [
for dir in `echo "$withval" | tr : ' '`; do
if test -d $dir/include; then CPPFLAGS="$CPPFLAGS -I$dir/include"; fi
if test -d $dir/lib; then LDFLAGS="$LDFLAGS -L$dir/lib"; fi
done
])
AC_CHECK_HEADER(iconv.h, AC_DEFINE(HAVE_ICONV_H))
AC_CACHE_CHECK(for iconv, am_cv_func_iconv, [
am_cv_func_iconv="no, consider installing GNU libiconv"
am_cv_lib_iconv=no
AC_TRY_LINK([#include <stdlib.h>
#include <iconv.h>],
[iconv_t cd = iconv_open("","");
iconv(cd,NULL,NULL,NULL,NULL);
iconv_close(cd);],
am_cv_func_iconv=yes)
if test "$am_cv_func_iconv" != yes; then
am_save_LIBS="$LIBS"
LIBS="$LIBS -liconv"
AC_TRY_LINK([#include <stdlib.h>
#include <iconv.h>],
[iconv_t cd = iconv_open("","");
iconv(cd,NULL,NULL,NULL,NULL);
iconv_close(cd);],
am_cv_lib_iconv=yes
am_cv_func_iconv=yes)
LIBS="$am_save_LIBS"
fi
])
if test "$am_cv_func_iconv" = yes; then
AC_DEFINE(HAVE_ICONV, 1, [Define if you have the iconv() function.])
AC_MSG_CHECKING([for iconv declaration])
AC_CACHE_VAL(am_cv_proto_iconv, [
AC_TRY_COMPILE([
#include <stdlib.h>
#include <iconv.h>
extern
#ifdef __cplusplus
"C"
#endif
#if defined(__STDC__) || defined(__cplusplus)
size_t iconv (iconv_t cd, char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft);
#else
size_t iconv();
#endif
], [], am_cv_proto_iconv_arg1="", am_cv_proto_iconv_arg1="const")
am_cv_proto_iconv="extern size_t iconv (iconv_t cd, $am_cv_proto_iconv_arg1 char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft);"])
am_cv_proto_iconv=`echo "[$]am_cv_proto_iconv" | tr -s ' ' | sed -e 's/( /(/'`
AC_MSG_RESULT([$]{ac_t:-
}[$]am_cv_proto_iconv)
AC_DEFINE_UNQUOTED(ICONV_CONST, $am_cv_proto_iconv_arg1,
[Define as const if the declaration of iconv() needs const.])
fi
LIBICONV=
if test "$am_cv_lib_iconv" = yes; then
LIBICONV="-liconv"
fi
AC_SUBST(LIBICONV)
])
UTILS_FUNC_ICONV
LIBS="$LIBS $LIBICONV"
#
# socklen_t
# from curl
dnl Check for socklen_t: historically on BSD it is an int, and in
dnl POSIX 1g it is a type of its own, but some platforms use different
dnl types for the argument to getsockopt, getpeername, etc. So we
dnl have to test to find something that will work.
AC_DEFUN([TYPE_SOCKLEN_T],
[
AC_CHECK_TYPE([socklen_t], ,[
AC_MSG_CHECKING([for socklen_t equivalent])
AC_CACHE_VAL([socklen_t_equiv],
[
# Systems have either "struct sockaddr *" or
# "void *" as the second argument to getpeername
socklen_t_equiv=
for arg2 in "struct sockaddr" void; do
for t in int size_t unsigned long "unsigned long"; do
AC_TRY_COMPILE([
#include <sys/types.h>
#include <sys/socket.h>
int getpeername (int, $arg2 *, $t *);
],[
$t len;
getpeername(0,0,&len);
],[
socklen_t_equiv="$t"
break
])
done
done
if test "x$socklen_t_equiv" = x; then
AC_MSG_ERROR([Cannot find a type to use in place of socklen_t])
fi
])
AC_MSG_RESULT($socklen_t_equiv)
AC_DEFINE_UNQUOTED(socklen_t, $socklen_t_equiv,
[type to use in place of socklen_t if not defined])],
[#include <sys/types.h>
#include <sys/socket.h>])
])
TYPE_SOCKLEN_T
#
# statfs stuff
#
AC_CHECK_HEADERS(sys/vfs.h)
AC_CHECK_HEADERS(sys/statvfs.h)
AC_CHECK_HEADERS(sys/statfs.h)
AC_CHECK_HEADERS(sys/param.h)
mount_includes="\
$ac_includes_default
#if HAVE_SYS_PARAM_H
# include <sys/param.h>
#endif
"
AC_CHECK_HEADERS(sys/mount.h,,,[$mount_includes])
#################################################
# these tests are taken from the GNU fileutils package
AC_CHECKING(how to get filesystem space usage)
space=no
# Test for statvfs64.
if test $space = no; then
# SVR4
AC_CACHE_CHECK([statvfs64 function (SVR4)], fu_cv_sys_stat_statvfs64,
[AC_TRY_RUN([
#if defined(HAVE_UNISTD_H)
#include <unistd.h>
#endif
#include <sys/types.h>
#include <sys/statvfs.h>
main ()
{
struct statvfs64 fsd;
exit (statvfs64 (".", &fsd));
}],
fu_cv_sys_stat_statvfs64=yes,
fu_cv_sys_stat_statvfs64=no,
fu_cv_sys_stat_statvfs64=cross)])
if test $fu_cv_sys_stat_statvfs64 = yes; then
space=yes
AC_DEFINE(STAT_STATVFS64,1,[Whether statvfs64() is available])
fi
fi
# Perform only the link test since it seems there are no variants of the
# statvfs function. This check is more than just AC_CHECK_FUNCS(statvfs)
# because that got a false positive on SCO OSR5. Adding the declaration
# of a `struct statvfs' causes this test to fail (as it should) on such
# systems. That system is reported to work fine with STAT_STATFS4 which
# is what it gets when this test fails.
if test $space = no; then
# SVR4
AC_CACHE_CHECK([statvfs function (SVR4)], fu_cv_sys_stat_statvfs,
[AC_TRY_LINK([#include <sys/types.h>
#include <sys/statvfs.h>],
[struct statvfs fsd; statvfs (0, &fsd);],
fu_cv_sys_stat_statvfs=yes,
fu_cv_sys_stat_statvfs=no)])
if test $fu_cv_sys_stat_statvfs = yes; then
space=yes
AC_DEFINE(STAT_STATVFS,1,[Whether statvfs() is available])
fi
fi
if test $space = no; then
# DEC Alpha running OSF/1
AC_MSG_CHECKING([for 3-argument statfs function (DEC OSF/1)])
AC_CACHE_VAL(fu_cv_sys_stat_statfs3_osf1,
[AC_TRY_RUN([
#include <sys/param.h>
#include <sys/types.h>
#include <sys/mount.h>
main ()
{
struct statfs fsd;
fsd.f_fsize = 0;
exit (statfs (".", &fsd, sizeof (struct statfs)));
}],
fu_cv_sys_stat_statfs3_osf1=yes,
fu_cv_sys_stat_statfs3_osf1=no,
fu_cv_sys_stat_statfs3_osf1=no)])
#C_MSG_RESULT($fu_cv_sys_stat_statfs3_osf1)
if test $fu_cv_sys_stat_statfs3_osf1 = yes; then
space=yes
AC_DEFINE(STAT_STATFS3_OSF1,1,[Whether statfs requires 3 arguments])
fi
fi
if test $space = no; then
# AIX
AC_MSG_CHECKING([for two-argument statfs with statfs.bsize dnl
member (AIX, 4.3BSD)])
AC_CACHE_VAL(fu_cv_sys_stat_statfs2_bsize,
[AC_TRY_RUN([
#ifdef HAVE_SYS_PARAM_H
#include <sys/param.h>
#endif
#ifdef HAVE_SYS_MOUNT_H
#include <sys/mount.h>
#endif
#ifdef HAVE_SYS_VFS_H
#include <sys/vfs.h>
#endif
main ()
{
struct statfs fsd;
fsd.f_bsize = 0;
exit (statfs (".", &fsd));
}],
fu_cv_sys_stat_statfs2_bsize=yes,
fu_cv_sys_stat_statfs2_bsize=no,
fu_cv_sys_stat_statfs2_bsize=no)])
AC_MSG_RESULT($fu_cv_sys_stat_statfs2_bsize)
if test $fu_cv_sys_stat_statfs2_bsize = yes; then
space=yes
AC_DEFINE(STAT_STATFS2_BSIZE,1,[Whether statfs requires two arguments and struct statfs has bsize property])
fi
fi
if test $space = no; then
# SVR3
AC_MSG_CHECKING([for four-argument statfs (AIX-3.2.5, SVR3)])
AC_CACHE_VAL(fu_cv_sys_stat_statfs4,
[AC_TRY_RUN([#include <sys/types.h>
#include <sys/statfs.h>
main ()
{
struct statfs fsd;
exit (statfs (".", &fsd, sizeof fsd, 0));
}],
fu_cv_sys_stat_statfs4=yes,
fu_cv_sys_stat_statfs4=no,
fu_cv_sys_stat_statfs4=no)])
AC_MSG_RESULT($fu_cv_sys_stat_statfs4)
if test $fu_cv_sys_stat_statfs4 = yes; then
space=yes
AC_DEFINE(STAT_STATFS4,1,[Whether statfs requires 4 arguments])
fi
fi
if test $space = no; then
# 4.4BSD and NetBSD
AC_MSG_CHECKING([for two-argument statfs with statfs.fsize dnl
member (4.4BSD and NetBSD)])
AC_CACHE_VAL(fu_cv_sys_stat_statfs2_fsize,
[AC_TRY_RUN([#include <sys/types.h>
#ifdef HAVE_SYS_PARAM_H
#include <sys/param.h>
#endif
#ifdef HAVE_SYS_MOUNT_H
#include <sys/mount.h>
#endif
main ()
{
struct statfs fsd;
fsd.f_fsize = 0;
exit (statfs (".", &fsd));
}],
fu_cv_sys_stat_statfs2_fsize=yes,
fu_cv_sys_stat_statfs2_fsize=no,
fu_cv_sys_stat_statfs2_fsize=no)])
AC_MSG_RESULT($fu_cv_sys_stat_statfs2_fsize)
if test $fu_cv_sys_stat_statfs2_fsize = yes; then
space=yes
AC_DEFINE(STAT_STATFS2_FSIZE,1,[Whether statfs requires 2 arguments and struct statfs has fsize])
fi
fi
if test $space = no; then
# Ultrix
AC_MSG_CHECKING([for two-argument statfs with struct fs_data (Ultrix)])
AC_CACHE_VAL(fu_cv_sys_stat_fs_data,
[AC_TRY_RUN([#include <sys/types.h>
#ifdef HAVE_SYS_PARAM_H
#include <sys/param.h>
#endif
#ifdef HAVE_SYS_MOUNT_H
#include <sys/mount.h>
#endif
#ifdef HAVE_SYS_FS_TYPES_H
#include <sys/fs_types.h>
#endif
main ()
{
struct fs_data fsd;
/* Ultrix's statfs returns 1 for success,
0 for not mounted, -1 for failure. */
exit (statfs (".", &fsd) != 1);
}],
fu_cv_sys_stat_fs_data=yes,
fu_cv_sys_stat_fs_data=no,
fu_cv_sys_stat_fs_data=no)])
AC_MSG_RESULT($fu_cv_sys_stat_fs_data)
if test $fu_cv_sys_stat_fs_data = yes; then
space=yes
AC_DEFINE(STAT_STATFS2_FS_DATA,1,[Whether statfs requires 2 arguments and struct fs_data is available])
fi
fi
statxfs_includes="\
$ac_includes_default
#if HAVE_SYS_STATVFS_H
# include <sys/statvfs.h>
#endif
#if HAVE_SYS_VFS_H
# include <sys/vfs.h>
#endif
#if !HAVE_SYS_STATVFS_H && !HAVE_SYS_VFS_H
# if HAVE_SYS_MOUNT_H && HAVE_SYS_PARAM_H
/* NetBSD 1.5.2 needs these, for the declaration of struct statfs. */
# include <sys/param.h>
# include <sys/mount.h>
# elif HAVE_NETINET_IN_H && HAVE_NFS_NFS_CLNT_H && HAVE_NFS_VFS_H
/* Ultrix 4.4 needs these for the declaration of struct statfs. */
# include <netinet/in.h>
# include <nfs/nfs_clnt.h>
# include <nfs/vfs.h>
# endif
#endif
"
AC_CHECK_MEMBERS([struct statfs.f_namemax],,,[$statxfs_includes])
AC_CHECK_MEMBERS([struct statvfs.f_namemax],,,[$statxfs_includes])
AC_CHECK_MEMBERS([struct statfs.f_namelen],,,[$statxfs_includes])
AC_CHECK_MEMBERS([struct statvfs.f_namelen],,,[$statxfs_includes])
#
# Large file support
#
AC_SYS_LARGEFILE
#
# mntent
#
AC_CHECK_HEADER(mntent.h, AC_DEFINE(HAVE_MNTENT_H))
AC_CHECK_FUNCS(setmntent)
#
# IPv6
#
AC_ARG_WITH(ipv6,
[ --with-ipv6 enable IPv6-support],
[
if test $withval != "no";
then
AC_DEFINE(IPv6,1)
fi
])
#
# debugging
#
AC_ARG_WITH(debug,
[ --with-debug enable protocol debugging output],
[
if test $withval != "no";
then
AC_DEFINE(WITH_DEBUG,1)
fi
])
AC_ARG_WITH(debug-kbd,
[ --with-debug-kbd enable debugging of keyboard handling],
[
if test $withval != "no";
then
AC_DEFINE(WITH_DEBUG_KBD,1)
fi
])
AC_ARG_WITH(debug-rdp5,
[ --with-debug-rdp5 enable debugging of RDP5 code],
[
if test $withval != "no";
then
AC_DEFINE(WITH_DEBUG_RDP5,1)
fi
])
AC_ARG_WITH(debug-clipboard,
[ --with-debug-clipboard enable debugging of clipboard code],
[
if test $withval != "no";
then
AC_DEFINE(WITH_DEBUG_CLIPBOARD,1)
fi
])
AC_ARG_WITH(debug-channel,
[ --with-debug-channel enable debugging of virtual channel code],
[
if test $withval != "no";
then
AC_DEFINE(WITH_DEBUG_CHANNEL,1)
fi
])
#
# target-specific stuff
#
# strip leading colon from rpath
rpath=`echo $rpath |sed 's/^://'`
AC_CANONICAL_HOST
case "$host" in
*-*-solaris*)
LDFLAGS="$LDFLAGS -R$rpath"
;;
*-dec-osf*)
LDFLAGS="$LDFLAGS -Wl,-rpath,$rpath"
;;
*-*-hpux*)
CFLAGS="$CFLAGS -D_XOPEN_SOURCE_EXTENDED"
;;
*-*-irix6.5*)
LIBS="$LIBS -L$ssldir/lib32 -lcrypto"
CFLAGS="$CFLAGS -D__SGI_IRIX__"
;;
esac
AC_OUTPUT(Makefile)
dnl Local Variables:
dnl comment-start: "dnl "
dnl comment-end: ""
dnl comment-start-skip: "\\bdnl\\b\\s *"
dnl compile-command: "autoconf"
dnl End:
@@ -0,0 +1,427 @@
/*
rdesktop: A Remote Desktop Protocol client.
Miscellaneous protocol constants
Copyright (C) Matthew Chapman 1999-2005
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* TCP port for Remote Desktop Protocol */
#define TCP_PORT_RDP 3389
#define DEFAULT_CODEPAGE "UTF-8"
#define WINDOWS_CODEPAGE "UTF-16LE"
/* ISO PDU codes */
enum ISO_PDU_CODE
{
ISO_PDU_CR = 0xE0, /* Connection Request */
ISO_PDU_CC = 0xD0, /* Connection Confirm */
ISO_PDU_DR = 0x80, /* Disconnect Request */
ISO_PDU_DT = 0xF0, /* Data */
ISO_PDU_ER = 0x70 /* Error */
};
/* MCS PDU codes */
enum MCS_PDU_TYPE
{
MCS_EDRQ = 1, /* Erect Domain Request */
MCS_DPUM = 8, /* Disconnect Provider Ultimatum */
MCS_AURQ = 10, /* Attach User Request */
MCS_AUCF = 11, /* Attach User Confirm */
MCS_CJRQ = 14, /* Channel Join Request */
MCS_CJCF = 15, /* Channel Join Confirm */
MCS_SDRQ = 25, /* Send Data Request */
MCS_SDIN = 26 /* Send Data Indication */
};
#define MCS_CONNECT_INITIAL 0x7f65
#define MCS_CONNECT_RESPONSE 0x7f66
#define BER_TAG_BOOLEAN 1
#define BER_TAG_INTEGER 2
#define BER_TAG_OCTET_STRING 4
#define BER_TAG_RESULT 10
#define MCS_TAG_DOMAIN_PARAMS 0x30
#define MCS_GLOBAL_CHANNEL 1003
#define MCS_USERCHANNEL_BASE 1001
/* RDP secure transport constants */
#define SEC_RANDOM_SIZE 32
#define SEC_MODULUS_SIZE 64
#define SEC_MAX_MODULUS_SIZE 256
#define SEC_PADDING_SIZE 8
#define SEC_EXPONENT_SIZE 4
#define SEC_CLIENT_RANDOM 0x0001
#define SEC_ENCRYPT 0x0008
#define SEC_LOGON_INFO 0x0040
#define SEC_LICENCE_NEG 0x0080
#define SEC_REDIRECT_ENCRYPT 0x0C00
#define SEC_TAG_SRV_INFO 0x0c01
#define SEC_TAG_SRV_CRYPT 0x0c02
#define SEC_TAG_SRV_CHANNELS 0x0c03
#define SEC_TAG_CLI_INFO 0xc001
#define SEC_TAG_CLI_CRYPT 0xc002
#define SEC_TAG_CLI_CHANNELS 0xc003
#define SEC_TAG_CLI_4 0xc004
#define SEC_TAG_PUBKEY 0x0006
#define SEC_TAG_KEYSIG 0x0008
#define SEC_RSA_MAGIC 0x31415352 /* RSA1 */
/* RDP licensing constants */
#define LICENCE_TOKEN_SIZE 10
#define LICENCE_HWID_SIZE 20
#define LICENCE_SIGNATURE_SIZE 16
#define LICENCE_TAG_DEMAND 0x01
#define LICENCE_TAG_AUTHREQ 0x02
#define LICENCE_TAG_ISSUE 0x03
#define LICENCE_TAG_REISSUE 0x04
#define LICENCE_TAG_PRESENT 0x12
#define LICENCE_TAG_REQUEST 0x13
#define LICENCE_TAG_AUTHRESP 0x15
#define LICENCE_TAG_RESULT 0xff
#define LICENCE_TAG_USER 0x000f
#define LICENCE_TAG_HOST 0x0010
/* RDP PDU codes */
enum RDP_PDU_TYPE
{
RDP_PDU_DEMAND_ACTIVE = 1,
RDP_PDU_CONFIRM_ACTIVE = 3,
RDP_PDU_REDIRECT = 4, /* MS Server 2003 Session Redirect */
RDP_PDU_DEACTIVATE = 6,
RDP_PDU_DATA = 7
};
enum RDP_DATA_PDU_TYPE
{
RDP_DATA_PDU_UPDATE = 2,
RDP_DATA_PDU_CONTROL = 20,
RDP_DATA_PDU_POINTER = 27,
RDP_DATA_PDU_INPUT = 28,
RDP_DATA_PDU_SYNCHRONISE = 31,
RDP_DATA_PDU_BELL = 34,
RDP_DATA_PDU_CLIENT_WINDOW_STATUS = 35,
RDP_DATA_PDU_LOGON = 38,
RDP_DATA_PDU_FONT2 = 39,
RDP_DATA_PDU_KEYBOARD_INDICATORS = 41,
RDP_DATA_PDU_DISCONNECT = 47
};
enum RDP_CONTROL_PDU_TYPE
{
RDP_CTL_REQUEST_CONTROL = 1,
RDP_CTL_GRANT_CONTROL = 2,
RDP_CTL_DETACH = 3,
RDP_CTL_COOPERATE = 4
};
enum RDP_UPDATE_PDU_TYPE
{
RDP_UPDATE_ORDERS = 0,
RDP_UPDATE_BITMAP = 1,
RDP_UPDATE_PALETTE = 2,
RDP_UPDATE_SYNCHRONIZE = 3
};
enum RDP_POINTER_PDU_TYPE
{
RDP_POINTER_SYSTEM = 1,
RDP_POINTER_MOVE = 3,
RDP_POINTER_COLOR = 6,
RDP_POINTER_CACHED = 7
};
enum RDP_SYSTEM_POINTER_TYPE
{
RDP_NULL_POINTER = 0,
RDP_DEFAULT_POINTER = 0x7F00
};
enum RDP_INPUT_DEVICE
{
RDP_INPUT_SYNCHRONIZE = 0,
RDP_INPUT_CODEPOINT = 1,
RDP_INPUT_VIRTKEY = 2,
RDP_INPUT_SCANCODE = 4,
RDP_INPUT_MOUSE = 0x8001
};
/* Device flags */
#define KBD_FLAG_RIGHT 0x0001
#define KBD_FLAG_EXT 0x0100
#define KBD_FLAG_QUIET 0x1000
#define KBD_FLAG_DOWN 0x4000
#define KBD_FLAG_UP 0x8000
/* These are for synchronization; not for keystrokes */
#define KBD_FLAG_SCROLL 0x0001
#define KBD_FLAG_NUMLOCK 0x0002
#define KBD_FLAG_CAPITAL 0x0004
/* See T.128 */
#define RDP_KEYPRESS 0
#define RDP_KEYRELEASE (KBD_FLAG_DOWN | KBD_FLAG_UP)
#define MOUSE_FLAG_MOVE 0x0800
#define MOUSE_FLAG_BUTTON1 0x1000
#define MOUSE_FLAG_BUTTON2 0x2000
#define MOUSE_FLAG_BUTTON3 0x4000
#define MOUSE_FLAG_BUTTON4 0x0280
#define MOUSE_FLAG_BUTTON5 0x0380
#define MOUSE_FLAG_DOWN 0x8000
/* Raster operation masks */
#define ROP2_S(rop3) (rop3 & 0xf)
#define ROP2_P(rop3) ((rop3 & 0x3) | ((rop3 & 0x30) >> 2))
#define ROP2_COPY 0xc
#define ROP2_XOR 0x6
#define ROP2_AND 0x8
#define ROP2_NXOR 0x9
#define ROP2_OR 0xe
#define MIX_TRANSPARENT 0
#define MIX_OPAQUE 1
#define TEXT2_VERTICAL 0x04
#define TEXT2_IMPLICIT_X 0x20
#define ALTERNATE 1
#define WINDING 2
/* RDP bitmap cache (version 2) constants */
#define BMPCACHE2_C0_CELLS 0x78
#define BMPCACHE2_C1_CELLS 0x78
#define BMPCACHE2_C2_CELLS 0x150
#define BMPCACHE2_NUM_PSTCELLS 0x9f6
#define PDU_FLAG_FIRST 0x01
#define PDU_FLAG_LAST 0x02
/* RDP capabilities */
#define RDP_CAPSET_GENERAL 1 /* Maps to generalCapabilitySet in T.128 page 138 */
#define RDP_CAPLEN_GENERAL 0x18
#define OS_MAJOR_TYPE_UNIX 4
#define OS_MINOR_TYPE_XSERVER 7
#define RDP_CAPSET_BITMAP 2
#define RDP_CAPLEN_BITMAP 0x1C
#define RDP_CAPSET_ORDER 3
#define RDP_CAPLEN_ORDER 0x58
#define ORDER_CAP_NEGOTIATE 2
#define ORDER_CAP_NOSUPPORT 4
#define RDP_CAPSET_BMPCACHE 4
#define RDP_CAPLEN_BMPCACHE 0x28
#define RDP_CAPSET_CONTROL 5
#define RDP_CAPLEN_CONTROL 0x0C
#define RDP_CAPSET_ACTIVATE 7
#define RDP_CAPLEN_ACTIVATE 0x0C
#define RDP_CAPSET_POINTER 8
#define RDP_CAPLEN_POINTER 0x08
#define RDP_CAPSET_SHARE 9
#define RDP_CAPLEN_SHARE 0x08
#define RDP_CAPSET_COLCACHE 10
#define RDP_CAPLEN_COLCACHE 0x08
#define RDP_CAPSET_BMPCACHE2 19
#define RDP_CAPLEN_BMPCACHE2 0x28
#define BMPCACHE2_FLAG_PERSIST ((uint32)1<<31)
#define RDP_SOURCE "MSTSC"
/* Logon flags */
#define RDP_LOGON_AUTO 0x0008
#define RDP_LOGON_NORMAL 0x0033
#define RDP_LOGON_COMPRESSION 0x0080 /* mppc compression with 8kB histroy buffer */
#define RDP_LOGON_BLOB 0x0100
#define RDP_LOGON_COMPRESSION2 0x0200 /* rdp5 mppc compression with 64kB history buffer */
#define RDP_LOGON_LEAVE_AUDIO 0x2000
#define RDP5_DISABLE_NOTHING 0x00
#define RDP5_NO_WALLPAPER 0x01
#define RDP5_NO_FULLWINDOWDRAG 0x02
#define RDP5_NO_MENUANIMATIONS 0x04
#define RDP5_NO_THEMING 0x08
#define RDP5_NO_CURSOR_SHADOW 0x20
#define RDP5_NO_CURSORSETTINGS 0x40 /* disables cursor blinking */
/* compression types */
#define RDP_MPPC_BIG 0x01
#define RDP_MPPC_COMPRESSED 0x20
#define RDP_MPPC_RESET 0x40
#define RDP_MPPC_FLUSH 0x80
#define RDP_MPPC_DICT_SIZE 65536
#define RDP5_COMPRESSED 0x80
/* Keymap flags */
#define MapRightShiftMask (1<<0)
#define MapLeftShiftMask (1<<1)
#define MapShiftMask (MapRightShiftMask | MapLeftShiftMask)
#define MapRightAltMask (1<<2)
#define MapLeftAltMask (1<<3)
#define MapAltGrMask MapRightAltMask
#define MapRightCtrlMask (1<<4)
#define MapLeftCtrlMask (1<<5)
#define MapCtrlMask (MapRightCtrlMask | MapLeftCtrlMask)
#define MapRightWinMask (1<<6)
#define MapLeftWinMask (1<<7)
#define MapWinMask (MapRightWinMask | MapLeftWinMask)
#define MapNumLockMask (1<<8)
#define MapCapsLockMask (1<<9)
#define MapLocalStateMask (1<<10)
#define MapInhibitMask (1<<11)
#define MASK_ADD_BITS(var, mask) (var |= mask)
#define MASK_REMOVE_BITS(var, mask) (var &= ~mask)
#define MASK_HAS_BITS(var, mask) ((var & mask)>0)
#define MASK_CHANGE_BIT(var, mask, active) (var = ((var & ~mask) | (active ? mask : 0)))
/* Clipboard constants, "borrowed" from GCC system headers in
the w32 cross compiler */
#define CF_TEXT 1
#define CF_BITMAP 2
#define CF_METAFILEPICT 3
#define CF_SYLK 4
#define CF_DIF 5
#define CF_TIFF 6
#define CF_OEMTEXT 7
#define CF_DIB 8
#define CF_PALETTE 9
#define CF_PENDATA 10
#define CF_RIFF 11
#define CF_WAVE 12
#define CF_UNICODETEXT 13
#define CF_ENHMETAFILE 14
#define CF_HDROP 15
#define CF_LOCALE 16
#define CF_MAX 17
#define CF_OWNERDISPLAY 128
#define CF_DSPTEXT 129
#define CF_DSPBITMAP 130
#define CF_DSPMETAFILEPICT 131
#define CF_DSPENHMETAFILE 142
#define CF_PRIVATEFIRST 512
#define CF_PRIVATELAST 767
#define CF_GDIOBJFIRST 768
#define CF_GDIOBJLAST 1023
/* Sound format constants */
#define WAVE_FORMAT_PCM 1
#define WAVE_FORMAT_ADPCM 2
#define WAVE_FORMAT_ALAW 6
#define WAVE_FORMAT_MULAW 7
/* Virtual channel options */
#define CHANNEL_OPTION_INITIALIZED 0x80000000
#define CHANNEL_OPTION_ENCRYPT_RDP 0x40000000
#define CHANNEL_OPTION_COMPRESS_RDP 0x00800000
#define CHANNEL_OPTION_SHOW_PROTOCOL 0x00200000
/* NT status codes for RDPDR */
#define STATUS_SUCCESS 0x00000000
#define STATUS_NOT_IMPLEMENTED 0x00000001
#define STATUS_PENDING 0x00000103
#define STATUS_NO_MORE_FILES 0x80000006
#define STATUS_DEVICE_PAPER_EMPTY 0x8000000e
#define STATUS_DEVICE_POWERED_OFF 0x8000000f
#define STATUS_DEVICE_OFF_LINE 0x80000010
#define STATUS_DEVICE_BUSY 0x80000011
#define STATUS_INVALID_HANDLE 0xc0000008
#define STATUS_INVALID_PARAMETER 0xc000000d
#define STATUS_NO_SUCH_FILE 0xc000000f
#define STATUS_INVALID_DEVICE_REQUEST 0xc0000010
#define STATUS_ACCESS_DENIED 0xc0000022
#define STATUS_OBJECT_NAME_COLLISION 0xc0000035
#define STATUS_DISK_FULL 0xc000007f
#define STATUS_FILE_IS_A_DIRECTORY 0xc00000ba
#define STATUS_NOT_SUPPORTED 0xc00000bb
#define STATUS_TIMEOUT 0xc0000102
#define STATUS_NOTIFY_ENUM_DIR 0xc000010c
#define STATUS_CANCELLED 0xc0000120
/* RDPDR constants */
#define RDPDR_MAX_DEVICES 0x10
#define DEVICE_TYPE_SERIAL 0x01
#define DEVICE_TYPE_PARALLEL 0x02
#define DEVICE_TYPE_PRINTER 0x04
#define DEVICE_TYPE_DISK 0x08
#define DEVICE_TYPE_SCARD 0x20
#define FILE_DIRECTORY_FILE 0x00000001
#define FILE_NON_DIRECTORY_FILE 0x00000040
#define FILE_COMPLETE_IF_OPLOCKED 0x00000100
#define FILE_DELETE_ON_CLOSE 0x00001000
#define FILE_OPEN_FOR_FREE_SPACE_QUERY 0x00800000
/* RDP5 disconnect PDU */
#define exDiscReasonNoInfo 0x0000
#define exDiscReasonAPIInitiatedDisconnect 0x0001
#define exDiscReasonAPIInitiatedLogoff 0x0002
#define exDiscReasonServerIdleTimeout 0x0003
#define exDiscReasonServerLogonTimeout 0x0004
#define exDiscReasonReplacedByOtherConnection 0x0005
#define exDiscReasonOutOfMemory 0x0006
#define exDiscReasonServerDeniedConnection 0x0007
#define exDiscReasonServerDeniedConnectionFips 0x0008
#define exDiscReasonLicenseInternal 0x0100
#define exDiscReasonLicenseNoLicenseServer 0x0101
#define exDiscReasonLicenseNoLicense 0x0102
#define exDiscReasonLicenseErrClientMsg 0x0103
#define exDiscReasonLicenseHwidDoesntMatchLicense 0x0104
#define exDiscReasonLicenseErrClientLicense 0x0105
#define exDiscReasonLicenseCantFinishProtocol 0x0106
#define exDiscReasonLicenseClientEndedProtocol 0x0107
#define exDiscReasonLicenseErrClientEncryption 0x0108
#define exDiscReasonLicenseCantUpgradeLicense 0x0109
#define exDiscReasonLicenseNoRemoteConnections 0x010a
/* SeamlessRDP constants */
#define SEAMLESSRDP_NOTYETMAPPED -1
#define SEAMLESSRDP_NORMAL 0
#define SEAMLESSRDP_MINIMIZED 1
#define SEAMLESSRDP_MAXIMIZED 2
#define SEAMLESSRDP_POSITION_TIMER 200000
#define SEAMLESSRDP_CREATE_MODAL 0x0001
#define SEAMLESSRDP_HELLO_RECONNECT 0x0001
#define SEAMLESSRDP_HELLO_HIDDEN 0x0002
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,141 @@
/*
rdesktop: A Remote Desktop Protocol client.
Disk Redirection definitions
Copyright (C) Jeroen Meijer 2003
Copyright (C) Peter Astrand 2004
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#define FILE_ATTRIBUTE_READONLY 0x00000001
#define FILE_ATTRIBUTE_HIDDEN 0x00000002
#define FILE_ATTRIBUTE_SYSTEM 0x00000004
#define FILE_ATTRIBUTE_DIRECTORY 0x00000010
#define FILE_ATTRIBUTE_ARCHIVE 0x00000020
#define FILE_ATTRIBUTE_DEVICE 0x00000040
#define FILE_ATTRIBUTE_UNKNOWNXXX0 0x00000060 /* ??? ACTION i.e. 0x860 == compress this file ? */
#define FILE_ATTRIBUTE_NORMAL 0x00000080
#define FILE_ATTRIBUTE_TEMPORARY 0x00000100
#define FILE_ATTRIBUTE_SPARSE_FILE 0x00000200
#define FILE_ATTRIBUTE_REPARSE_POINT 0x00000400
#define FILE_ATTRIBUTE_COMPRESSED 0x00000800
#define FILE_ATTRIBUTE_OFFLINE 0x00001000
#define FILE_ATTRIBUTE_NOT_CONTENT_INDEXED 0x00002000
#define FILE_ATTRIBUTE_ENCRYPTED 0x00004000
#define FILE_FLAG_OPEN_NO_RECALL 0x00100000
#define FILE_FLAG_OPEN_REPARSE_POINT 0x00200000
#define FILE_FLAG_POSIX_SEMANTICS 0x01000000
#define FILE_FLAG_BACKUP_SEMANTICS 0x02000000 /* sometimes used to create a directory */
#define FILE_FLAG_DELETE_ON_CLOSE 0x04000000
#define FILE_FLAG_SEQUENTIAL_SCAN 0x08000000
#define FILE_FLAG_RANDOM_ACCESS 0x10000000
#define FILE_FLAG_NO_BUFFERING 0x20000000
#define FILE_FLAG_OVERLAPPED 0x40000000
#define FILE_FLAG_WRITE_THROUGH 0x80000000
#define FILE_SHARE_READ 0x01
#define FILE_SHARE_WRITE 0x02
#define FILE_SHARE_DELETE 0x04
#define FILE_BASIC_INFORMATION 0x04
#define FILE_STANDARD_INFORMATION 0x05
#define FS_CASE_SENSITIVE 0x00000001
#define FS_CASE_IS_PRESERVED 0x00000002
#define FS_UNICODE_STORED_ON_DISK 0x00000004
#define FS_PERSISTENT_ACLS 0x00000008
#define FS_FILE_COMPRESSION 0x00000010
#define FS_VOLUME_QUOTAS 0x00000020
#define FS_SUPPORTS_SPARSE_FILES 0x00000040
#define FS_SUPPORTS_REPARSE_POINTS 0x00000080
#define FS_SUPPORTS_REMOTE_STORAGE 0X00000100
#define FS_VOL_IS_COMPRESSED 0x00008000
#define FILE_READ_ONLY_VOLUME 0x00080000
#define OPEN_EXISTING 1
#define CREATE_NEW 2
#define OPEN_ALWAYS 3
#define TRUNCATE_EXISTING 4
#define CREATE_ALWAYS 5
#define GENERIC_READ 0x80000000
#define GENERIC_WRITE 0x40000000
#define GENERIC_EXECUTE 0x20000000
#define GENERIC_ALL 0x10000000
#define ERROR_FILE_NOT_FOUND 2L
#define ERROR_ALREADY_EXISTS 183L
#define MAX_OPEN_FILES 0x100
typedef enum _FILE_INFORMATION_CLASS
{
FileDirectoryInformation = 1,
FileFullDirectoryInformation,
FileBothDirectoryInformation,
FileBasicInformation,
FileStandardInformation,
FileInternalInformation,
FileEaInformation,
FileAccessInformation,
FileNameInformation,
FileRenameInformation,
FileLinkInformation,
FileNamesInformation,
FileDispositionInformation,
FilePositionInformation,
FileFullEaInformation,
FileModeInformation,
FileAlignmentInformation,
FileAllInformation,
FileAllocationInformation,
FileEndOfFileInformation,
FileAlternateNameInformation,
FileStreamInformation,
FilePipeInformation,
FilePipeLocalInformation,
FilePipeRemoteInformation,
FileMailslotQueryInformation,
FileMailslotSetInformation,
FileCompressionInformation,
FileCopyOnWriteInformation,
FileCompletionInformation,
FileMoveClusterInformation,
FileOleClassIdInformation,
FileOleStateBitsInformation,
FileNetworkOpenInformation,
FileObjectIdInformation,
FileOleAllInformation,
FileOleDirectoryInformation,
FileContentIndexInformation,
FileInheritContentIndexInformation,
FileOleInformation,
FileMaximumInformation
} FILE_INFORMATION_CLASS, *PFILE_INFORMATION_CLASS;
typedef enum _FSINFOCLASS
{
FileFsVolumeInformation = 1,
FileFsLabelInformation,
FileFsSizeInformation,
FileFsDeviceInformation,
FileFsAttributeInformation,
FileFsControlInformation,
FileFsFullSizeInformation,
FileFsObjectIdInformation,
FileFsDriverPathInformation,
FileFsMaximumInformation
} FS_INFORMATION_CLASS, *PFS_INFORMATION_CLASS;
@@ -0,0 +1,14 @@
This is an attempt at a list of people who have made significant
contributions to the code. If you have been unintentionally omitted
please let one of the team members know.
Matt Chapman <[email protected]>
Peter Kallden <[email protected]>
Hugo Trippaers <[email protected]>
Jay Sorg <[email protected]>
Peter Åstrand <[email protected]>
Michal Mihalik <[email protected]>
Norbert Federa <[email protected]>
Erik Forsberg <[email protected]>
Michael Gernoth <[email protected]>
Jeroen Meijer <[email protected]>
@@ -0,0 +1,86 @@
rdesktop (1.?.?)
* SeamlessRDP - seamless windows support
* Keymap fixes
* Fix connection issues with Windows XP RTM
* Keyboard handling improvements and fixes
* SGI/Irix sound-driver fixes
* Support for clipboard INCR protocol
* Session Directory support (patch from Brian Chapeau <[email protected]>)
* Support for long filenames on redirected drives
* XOR ellipse drawing fix
* Clipboard unicode support (Ilya Konstantinov)
* Refactoring of color depth code (Ilya Konstantinov)
rdesktop (1.4.1)
* persistent bitmap cache optimisations
* support for more RDP-orders (ellipse, polygon)
* libao sound-driver (for Mac OSX and others)
* Unicode support for transmitted strings/filenames
* Added korean keymap
* Xembed fixes to work with krdc correctly
* Portability fixes
* Support for RDP-compression (all bpps)
* process RDP recv queue if send queue is full (Debian bug #246461)
* SGI/Irix sound-driver fixes
-- Michael Gernoth <[email protected]> Sun, 8 May 2005 19:55:35 +0200 (CEST)
rdesktop (1.4.0)
* Basic disk-, parallel-, printer- and serial-redirection
* Fix timezone-redirection
* Backing-store fixes
* Fix client-IP sent to TS
* XEmbed support for embedding rdesktop in other applications (KRDC)
* Support for setting the RDP5 experience
* Keyboard and keymap fixes
* Performance improvements
* Report disconnect-reason
* Support for RDP-compression (currently only for 8bpp)
* Support for persistent bitmap caching
* Sound-driver for SGI/Irix
-- Michael Gernoth <[email protected]> Sun, 6 Mar 2005 22:09:55 +0100 (CET)
rdesktop (1.3.1)
* Crypto fixes for RDP5
* Keyboard and keymap fixes
* some endianess fixes for high color
* portability enhancements
-- Matthew Chapman <[email protected]> Tue, 21 Jan 2004 20:34
rdesktop (1.3.0)
* RDP5
* 15, 16 and 24 bit color depths
* Basic clipboard redirection
* Sound
* IPv6
* Attaching to console on Windows 2003
-- Peter Astrand <[email protected]> Wed, 29 Oct 2003 16:40:58 +0100 (CET)
rdesktop (1.2.0)
* new - more portable - key mapping code
* support for "high" (128-bit) encryption
* toggling out of full-screen mode with Ctrl-Alt-Enter
* a few extra options including host:port syntax
* many, many bug fixes and optimisations
-- Matthew Chapman <[email protected]> Thu, 30 Jan 2003 04:29
rdesktop (1.1.0)
* solves arith.c licensing issue by taking big number routines from
OpenSSL
* keyboard support not merged from unified patches yet
* still no manpage
-- Matthew Chapman <[email protected]> Mon, 17 Sep 2001 23:14:28 +1000 (AEST)
rdesktop (1.0.0)
* initial release
-- Matthew Chapman <[email protected]>
@@ -0,0 +1,28 @@
Code style / indentation
------------------------
The file indent-all.sh contains information about the current code
style. Run this script before commits.
Variable argument macros
------------------------
Variable argument macros are non-portable in general, and should be
avoided. Either use a second set of parentheses like DEBUG, or create
a variable argument function like error.
Structure
---------
The core protocol stack should be system-independent (i.e. ANSI C
only) so that it is easy to port. This currently applies to the
following files:
bitmap.c licence.c orders.c rdp.c rdp5.c cache.c iso.c mcs.c
secure.c mppc.c channels.c
rdesktop.c
RDP resources
-------------
http://dev.remotenetworktechnology.com/refdata.htm
@@ -0,0 +1,89 @@
* Clipboard:
* Support other data types than plain text.
* Conversion between different character sets.
* Drive Redirection:
* Real support for file locking
* Handle reconnections correctly.
* Various deficiencies; see FIXMEs in source code.
* Serial Port Redirection:
* More testing needed.
* Printer Redirection:
* More testing needed.
* Keymapping:
* Sound redirection
* Use timestamps in audio packets.
* Add resampling to supported samplerates of audio-hardware.
* Lower CPU-usage with an audio thread.
* Smartcard redirection
* Merge patches currently implementing sc-redirection.
* Miscellaneous
* Clean up header files. The current "proto.h" and "xproto.h" is far
from optimal.
* Go through the many trackers (bugs/patches/RFEs) at SourceForge.
* More fancy homepage.
* Enhance documentation. Write a FAQ.
* SeamlessRDP mode
* Add a client to server message for starting additional
applications.
* Support cmd.exe.
* Support for Input Contexts.
* Enhanced support for WM_DELETE_WINDOW: Instead of terminating
rdesktop, close the window on the server side.
* Systray support.
* Support for transferring the application taskbar icon.
* Better support for non-EWMH window managers.
* Support for non-rectangular windows.
* The focus handling of menus is a bit crude.
* Support for sending focus information from client to server.
* Implement something similiar to explhook.dll - support for running
explorer.exe in non-shell mode.
* Better compatibility with Task Manager.
* XINERAMA support.
* When enumerating windows, make sure to send info about windows
that are transient for other windows after the referred window.
@@ -0,0 +1,29 @@
IPv6 support in rdesktop
========================
The IPv6 support was developed by Mike Dawson <[email protected]>:
Attached is a patch to tcp.c to enable IPv6 support. Build with
'IPv6' defined to enable it. It's so far only been tested on
Linux 2.4.21 connecting to Windows XP SP1.
Since terminal services doesn't seem to bind to the ipv6 interface
on XP I had to run 'netsh interface portproxy add v6tov4
listenport=3389 connectport=3389' from the windows command prompt
to get it to work.
rdesktop now supports numeric IPv6 addresses:
It checks for two or more colons in an address to decide what it's
dealing with so you can now do:
rdesktop 2001:1:2:3::4
without it getting confused with an ipv4:port specification. I've
also followed the square bracket convention used by browsers
(http://www.ietf.org/rfc/rfc2732.txt) so if you want to specify a
non-standard port with an ipv6 address you can use the format:
rdesktop [2001:1:2:3::4]:3390
@@ -0,0 +1,124 @@
0x0436 af Afrikaans
0x041C sq Albanian
0x0001 ar Arabic
0x0401 ar-sa Arabic (Saudi Arabia)
0x0801 ar-iq Arabic (Iraq)
0x0C01 ar-eg Arabic (Egypt)
0x1001 ar-ly Arabic (Libya)
0x1401 ar-dz Arabic (Algeria)
0x1801 ar-ma Arabic (Morocco)
0x1C01 ar-tn Arabic (Tunisia)
0x2001 ar-om Arabic (Oman)
0x2401 ar-ye Arabic (Yemen)
0x2801 ar-sy Arabic (Syria)
0x2C01 ar-jo Arabic (Jordan)
0x3001 ar-lb Arabic (Lebanon)
0x3401 ar-kw Arabic (Kuwait)
0x3801 ar-ae Arabic (U.A.E.)
0x3C01 ar-bh Arabic (Bahrain)
0x4001 ar-qa Arabic (Qatar)
0x042D eu Basque
0x0402 bg Bulgarian
0x0423 be Belarusian
0x0403 ca Catalan
0x0004 zh Chinese
0x0404 zh-tw Chinese (Taiwan)
0x0804 zh-cn Chinese (China)
0x0C04 zh-hk Chinese (Hong Kong SAR)
0x1004 zh-sg Chinese (Singapore)
0x041A hr Croatian
0x0405 cs Czech
0x0406 da Danish
0x0413 nl Dutch (Netherlands)
0x0813 nl-be Dutch (Belgium)
0x0009 en English
0x0409 en-us English (United States)
0x0809 en-gb English (United Kingdom)
0x0C09 en-au English (Australia)
0x1009 en-ca English (Canada)
0x1409 en-nz English (New Zealand)
0x1809 en-ie English (Ireland)
0x1C09 en-za English (South Africa)
0x2009 en-jm English (Jamaica)
0x2809 en-bz English (Belize)
0x2C09 en-tt English (Trinidad)
0x0425 et Estonian
0x0438 fo Faeroese
0x0429 fa Farsi
0x040B fi Finnish
0x040C fr French (France)
0x080C fr-be French (Belgium)
0x0C0C fr-ca French (Canada)
0x100C fr-ch French (Switzerland)
0x140C fr-lu French (Luxembourg)
0x043C gd Gaelic
0x0407 de German (Germany)
0x0807 de-ch German (Switzerland)
0x0C07 de-at German (Austria)
0x1007 de-lu German (Luxembourg)
0x1407 de-li German (Liechtenstein)
0x0408 el Greek
0x040D he Hebrew
0x0439 hi Hindi
0x040E hu Hungarian
0x040F is Icelandic
0x0421 in Indonesian
0x0410 it Italian (Italy)
0x0810 it-ch Italian (Switzerland)
0x0411 ja Japanese
0x0412 ko Korean
0x0426 lv Latvian
0x0427 lt Lithuanian
0x042F mk FYRO Macedonian
0x043E ms Malay (Malaysia)
0x043A mt Maltese
0x0414 no Norwegian (Bokmal)
0x0814 no Norwegian (Nynorsk)
0x0415 pl Polish
0x0416 pt-br Portuguese (Brazil)
0x0816 pt Portuguese (Portugal)
0x0417 rm Rhaeto-Romanic
0x0418 ro Romanian
0x0818 ro-mo Romanian (Moldova)
0x0419 ru Russian
0x0819 ru-mo Russian (Moldova)
0x0C1A sr Serbian (Cyrillic)
0x081A sr Serbian (Latin)
0x041B sk Slovak
0x0424 sl Slovenian
0x042E sb Sorbian
0x040A es Spanish (Traditional Sort)
0x080A es-mx Spanish (Mexico)
0x0C0A es Spanish (International Sort)
0x100A es-gt Spanish (Guatemala)
0x140A es-cr Spanish (Costa Rica)
0x180A es-pa Spanish (Panama)
0x1C0A es-do Spanish (Dominican Republic)
0x200A es-ve Spanish (Venezuela)
0x240A es-co Spanish (Colombia)
0x280A es-pe Spanish (Peru)
0x2C0A es-ar Spanish (Argentina)
0x300A es-ec Spanish (Ecuador)
0x340A es-cl Spanish (Chile)
0x380A es-uy Spanish (Uruguay)
0x3C0A es-py Spanish (Paraguay)
0x400A es-bo Spanish (Bolivia)
0x440A es-sv Spanish (El Salvador)
0x480A es-hn Spanish (Honduras)
0x4C0A es-ni Spanish (Nicaragua)
0x500A es-pr Spanish (Puerto Rico)
0x0430 sx Sutu
0x041D sv Swedish
0x081D sv-fi Swedish (Finland)
0x041E th Thai
0x0431 ts Tsonga
0x0432 tn Tswana
0x041F tr Turkish
0x0422 uk Ukrainian
0x0420 ur Urdu
0x042A vi Vietnamese
0x0434 xh Xhosa
0x043D ji Yiddish
0x0435 zu Zulu
@@ -0,0 +1,243 @@
Keyboard mapping
================
This release of rdesktop uses a new, portable keyboard mapping
implementation. It should hopefully work on all X11 systems. This new
implementation only looks at X11 keysyms: Not on (nonportable)
keycodes or modifier status. This means that rdesktop will obey your
local keyboard configuration. For example, if you have swapped
CapsLock and Control, rdesktop will use this mapping.
XKB is currently not used. It seems like a good idea to me, but since
some X servers (like Xvnc) does not support XKB, we still need to use
the plain old interface as well, at least.
There are still some small problems.
* CapsLock: CapsLock changes are never sent to the RDP
server. rdesktop does not know which keys that are modified by
CapsLock and which are not. So, the CapsLock indicator in Wordpad
etc will always be off.
Composing/Multi_key is supported. For more information, see:
MIT: $SRC/xc/nls/X11/locale/Compose/iso8859-1
XFree86: /usr/X11R6/lib/X11/locale/*/Compose
Solaris' Openwin: /usr/openwin/include/X11/Suncompose.h
/usr/openwin/lib/locale/*/Compose
Irix6: compose(5)
Keymap files
============
The names of the keymaps follows RFC1766.
(You can find a translation from Windows keyboard layout numbers to
keymap names by looking at
HKEY_LOCAL_MACHINE\SOFTWARE\Classes\MIME\Database\RFC1766 in the
registry.)
Contents of keymap files
========================
The keymaps are line based. There are four different types of lines:
1) include lines
Syntax:
include <another-map-file>
Example:
include common
2) map lines
Syntax:
map <hex-number>
Example:
map 0x41d
Map-lines specifies how the remote RDP server should interpret the
sent scancodes.
3) Translation lines
Syntax:
<keysym-name> <scancode> [flags..]
Example:
onehalf 0x29 shift
The scancode can be found in scancodes.h. Note: The scancode value for
extended keys can be calculated by OR:ing with 0x80. Example: The
Delete key have the scancode sequence 0xe0, 0x52. You can get the
scancode value to put into the map file by running:
python -c "print hex(0x80 | 0x52)"
If flags are "altgr", "shift", the scancode sent for this keysym will
be prefixed with AltGr, or Shift.
If flags includes "addupper", a translation for this keysyms uppercase
name will be added as well, in addition to the non-uppercase
name. Example:
x 2d addupper
...will add an translation for "X" automatically, just like if you
would specify:
X 2d shift
If flags include "localstate", the modifier to send will be determined
by the local modifier state.
If flags is "inhibit", nothing will be sent to the server.
If flags is "numlock", rdesktop will make sure that the remote NumLock
state is on before generating the key event. Otherwise, it will make
sure NumLock is off.
4) enable_compose
If any line starts with the keyword "enable_compose", rdesktop will
enable local Compose/Multi_key handling. Enabling this will often make
it impossible to compose characters with dead keys (on the remote
side). This is because when local compose support is enabled, dead
keys will not be sent to the remote side.
5) sequence lines
Syntax:
sequence <event-keysym-name> <keysym-name1> <keysym-name2> ...
Examples:
sequence eacute dead_acute e
sequence F12 f o o at e x a m p l e period c o m
Sequence lines allows you to specify that multiple scancodes should be
sent to the RDP server, in response to one X11 keyboard event. Note:
The sequence is sent at the X11 KeyPress event. Nothing is sent at
KeyRelease.
6) keyboard_type lines
Syntax:
keyboard_type <hex-number>
keyboard_type lines specifies the keyboard type. Default value is 0x4
(en-us 101/104 keys keyboard).
7) keyboard_subtype lines
Syntax:
keyboard_subtype <hex-number>
keyboard_subtype lines specifies the keyboard subtype. Default value
is 0x0 (en-us 101/104 keys keyboard).
8) keyboard_functionkeys lines
Syntax:
keyboard_functionkeys <hex-number>
keyboard_functionkeys specifies the number of keyboard function
keys. Default value is 0xc (12, for standard 101/104 keys keyboard).
Suggested X11 keysym mapping on PCs
===================================
Unfortunately, there is no standard for which keysyms a given key
should generate. If you have a PC-keyboard with Windows keys, I suggest this mapping:
Keyboard keys:
CtrlLeft WinLeft AltLeft Space AltGr WinRight Menu CtrlRight
...should generate keysyms:
Control_L Super_L Alt_L space Mode_switch Super_R Menu Control_R
Additionally:
Shift-Alt should produce Meta_L
Shift-AltGr should produce Multi_Key.
Use a modifier-map like this:
shift Shift_L (0x32), Shift_R (0x3e)
lock Caps_Lock (0x25)
control Control_L (0x42), Control_R (0x6d)
mod1 Alt_L (0x40)
mod2 Num_Lock (0x4d)
mod3 Mode_switch (0x71)
mod4 Super_L (0x73), Super_R (0x74)
mod5 Scroll_Lock (0x4e)
Updating / writing keymap files
===============================
When writing new or updating keymap files, please use comments and
blanks, to increase readability. The "sv" keymap is a good template.
When you need to add a translation to a keymap file, do:
1. Get the "key number" for this key, by looking at keynums.png.
2. Take a look at scancodes.h, and look for
SCANCODE_KEY_<my-key-number>. The scancode value is at the end of
the line. If the line contains (SCANCODE_EXTENDED | 0xsomething),
then you should OR 0x80 to this value. For example, you can do:
python -c "print hex(0x80 | 0xsomething)"
3. Put the scancode (from step 2) and keysym name (found in the
error message) into the keymap file.
Special keys
============
* The combination Ctrl-Alt-Enter toggles between fullscreen and
non-fullscreen mode.
* Meta, Hyper and Super are treated as windows keys. RDP4 does not
support the windows keys though, so if you are running RDP4, these
keys will translate to Ctrl-Esc.
Links
=====
http://www.win.tue.nl/~aeb/linux/kbd/scancodes.html
Test cases
==========
When changing the keyboard code, make sure all these tests in Notepad
works:
1. Ctrl+f should bring up Find dialog, with CapsLock both on and off.
2. Ctrl+Shift+arrows should mark text, with CapsLock both on and off.
3. Test a sequence, like egrave.
4. Test a char generated with AltGr, such as @ on a swedish keyboard.
5. Test Ctrl-Alt-Delete.
6. Ctrl-Alt-Enter should toggle fullscreen.
7. Test NumLock synchronization using the -N option. Excel is able to
indicate the current NumLock state. Verify that the status is
updated correctly on reconnects.
8. Test the Windows keys, standalone as well as in combination with,
say, E.
9. Make sure the system menu (via Alt-space) cannot be accessed in
single app mode.
10. Make sure keymaps can be loaded from ~/.rdesktop/keymaps,
KEYMAP_PATH, $CWD/keymaps, and from an absolute path.
Binary file not shown.

After

Width:  |  Height:  |  Size: 9.0 KiB

@@ -0,0 +1,56 @@
To be able to connect to Microsoft Windows 2000 Terminal Services (and
probably later versions), you'll need to deal with licensing. This is
complicated. This file is supposed to contain some information about
how rdesktop works with Microsofts license systems.
There's a lot of information on the MS web site, for example,
http://support.microsoft.com/default.aspx?scid=kb;EN-US;287687.
From the rdesktop mailing list:
Peter Åstrand <[email protected]>, 2003-02-06
> We are running rdesktop 1.2 on machine A and connects to a Windows 2000
> Server (machine B). The W2K machine has 5 real licenses installed ("Windows
> 2000 Terminal Services Client Access License", "Open" type). This can be
> verifier by using "Terminal Services Licensing". The problem is that all
> issued licenses have an expire-date. The expire date for the license issued
> to A was reached today, and no more connections could be made until we
> changed the client name (by using -n).
>
> We also have another similiar systems, with Linux machine C and W2K server
> D. This server has 200 licenses installed of the type "Select". On this
> server, the issued licenses seems to be permanent: The expire date is set
> to "-", and we have no problem with this system.
>
> The question of course is why the first system issues license with
> expiration date, while the second system issues permanent licenses.
Darryn Capes-Davis, 2003-02-07
> I have been through the problems and can tell you what is going
> on. The main difference of Machine B (Server 1) and Machine D (Server
> 2) is that from what I see Machine B has Service Pack 3 installed and
> Machine D does not. You see in Service Pack 3 there was a change made
> to TS Licencing in that Microsoft introduced a licence recovery
> mechanism. To cut to the point (I don't know the details) rdesktop 1.2
> with SAVE_LICENCE defined works fine. In the new lic method the
> terminal server expects a valid licence to be presented to renew
> it. Otherwise it just expires it - and a day later you will see it
> actually gone (it does housekeeping once a day)! So if SAVE_LICENCE
> code is not enabled then it just expires and you can't use the licence
> until it cleans it away - and this is where a little gotcha is - if
> you move from using an rdesktop without SAVE_LICENCE to one with
> SAVE_LICENCE then it still won't recover an 'expired' licence. You
> have to wait for the daily housekeeping to clean it up - this really
> had me going for half a day or so! This is exactly what happened to
> you.
>
> The Server pre Spk 3 has the old model where licences never expire. To
> recover a licence that you never wanted to use again you have to call
> the Microsoft Clearing House. That's why they introduced the new
> method. And if you upgrade a Pre Spk3 server to Spk3 then the licences
> granted still stay with the old method - only new licences granted
> will use the new expiry method.
@@ -0,0 +1,39 @@
Protocol overview
=================
The lspci virtual channel makes it possible for the remote RDP server
to enumerate the local PCI devices. The protocol on this channel is
text based and line oriented: One single line per request or
response. UNIX-style LF line breaks are used. The maximum line length
is 1023, newline included.
rdesktop acts as a server, with only one request:
LSPCI
The response is several lines with this syntax:
<class>,<vendor>,<device>,<subvendor>,<subdevice>,<revision>,<progif>
After the last line, a line with a single dot is sent.
Example:
0300,102b,0525,102b,0338,04,00
0401,8086,24d5,1028,0174,02,8f
.
Usage
=====
To enable to lspci virtual channel, run rdesktop with "-r lspci".
References
==========
http://www.microsoft.com/msj/1099/terminal/terminal.aspx
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/termserv/termserv/terminal_services_virtual_channels.asp
@@ -0,0 +1,340 @@
This file documents some of all patches for rdesktop, floating around
the net, and how they are related to the current (CVS) version of
rdesktop. Things left to do are marked with TBD (To Be Done).
URL:
http://bibl4.oru.se/projects/rdesktop/patch19/patches/Makefile.diff
Description:
Makefile changes which makes it possible to compile rdesktop on SunOS
and OSF1.
Status:
Applied (slightly modified)
URL:
http://bibl4.oru.se/projects/rdesktop/patch19/patches/assar_19-7-2.hostlen.patch
Description:
Fix for hostnames longer than 30 chars.
Status:
Applied (revision 1.11 of secure.c)
URL:
http://bibl4.oru.se/projects/rdesktop/patch19/patches/backingstore+privatecolormap-for-19-3-9.patch
Description:
This adds support for 1) Private color maps (useful for 8 bpp mode)
and 2) backingstore selection.
Status:
1) is not needed anymore; rdesktop automatically uses Private color
map in 8 bpp mode. 2) is, as far as I understand, also not
need. rdesktop automatically uses a software backing store if the
Xserver does not provide one.
URL:
http://bibl4.oru.se/projects/rdesktop/patch19/patches/ben_xwin.c.diff
Description:
Fixes for CapsLock and NumLock.
Status:
Not needed anymore, with the new keyboard mapping implementation.
URL:
http://bibl4.oru.se/projects/rdesktop/patch19/patches/ctrl1nohang.diff
Description:
Fixes problem with ctrl1 hangs.
Status:
Not needed anymore, with the new keyboard mapping implementation.
URL:
http://bibl4.oru.se/projects/rdesktop/patch19/patches/downkeypatch.diff
Description:
Seems to keep track of the remote modifier status.
Status:
Not needed anymore, with the new keyboard mapping implementation.
URL:
http://bibl4.oru.se/projects/rdesktop/patch19/patches/fasttext2+nobackpixmap.patch
Description:
(From http://mail.rdesktop.org/archive/2001/msg00218.html):
1) Added --no-backpixmap option to disable the ugly double drawing in
xwin.c (I have a very robust backing storage in my X, so I don't need
it ;)
2) More optimizations to text draw (previous fast-text patch was
included in 192-3-6-2). In text drawing with solid background the
glyphs are drawn with stippled fill instead of XCopyPlane (runs faster
on my S3Trio64 with XFree 3.3.6, please test it on other
configurations to validate this). The WinTach not show any improvement
with this change, it seems to use all transparent background text
draws, but with a old PC Magazine Winbench (3.1) doing the scroll text
test the speed gain is significative.
3) My Previous patch to disable backing storage in fullscreen
Status:
1) is not relevant any more, since rdesktop only uses backing store if
the Xserver does not provide backing store.
Need to examine if 2) and 3) are still useful. TBD.
URL:
http://bibl4.oru.se/projects/rdesktop/patch19/patches/francisco_fix_patblt.html
Description:
The colors in patterns drawn with "pattern blt" order was inverted (fg
& bg). (See the background of the yellow help banners)
Status:
Applied (in revision 1.29, 2002/07/14)
URL:
http://bibl4.oru.se/projects/rdesktop/patch19/patches/frank_1linerfix.html
Description:
ui_create_glyph was not called with ipattern.
Status:
Applied (in revision 1.29, 2002/07/14).
URL:
http://bibl4.oru.se/projects/rdesktop/patch19/patches/frank_fasttext.patch.txt
Description:
Some kind of performence improvements.
Status:
From what I can tell, this patch is no longer necessary.
URL:
http://bibl4.oru.se/projects/rdesktop/patch19/patches/hostname-patch
Description:
(From http://mail.rdesktop.org/archive/2001/msg00163.html):
rdesktop uses gethostname to figure out the hostname, but gethostname
under linux returns an error when the hostname is longer than the
buffer. This hack gives gethostname a 64 char buffer and then strips
the first 16 chars or upto the first '.' and puts the result in
hostname[16].
Status:
Applied in version 1.10 of rdesktop.c.
URL:
http://bibl4.oru.se/projects/rdesktop/patch19/patches/hove-19-7-2endian.diff
Description:
Includes a program for testing endianness.
Status:
rdesktop determines endianness at runtime. This patch is not needed
anymore.
URL:
http://bibl4.oru.se/projects/rdesktop/patch19/patches/mmihalik_19-7-3-keyfix-4.patch
Description:
Some kind of new alternative keyboard mapping imlementation.
Status:
Not needed anymore, with the new keyboard mapping implementation.
URL:
http://bibl4.oru.se/projects/rdesktop/patch19/patches/norbert_fullscreen.patch
Description:
Fullscreen mode.
Status:
Applied.
URL:
http://bibl4.oru.se/projects/rdesktop/patch19/patches/norbert_percent.txt
Description:
Makes is possible to specify RDP geometry based a percent value of the
current desktop size.
Status:
Not applied. I don't think many people will need this.
URL:
http://bibl4.oru.se/projects/rdesktop/patch19/patches/norbert_rdp_tcp_port.diff
Description:
Command line tcp port argument.
Status:
Applied.
URL:
http://bibl4.oru.se/projects/rdesktop/patch19/patches/patch19-7-2.xyPos.emptyPassword.patch
Description:
This patch adds:
1) Support for empty passwords
2) Support for asking for password interactively
3) Support for +<xoff>+<yoff> geometry.
Status:
1) and 2) can be solved by the -P parameter; patch not needed.
Functionality for 3) is currently missing.
URL:
http://bibl4.oru.se/projects/rdesktop/patch19/patches/rdesktop-1.0.0-19-7-1-mmihalik-3.diff
Description:
Defines DO_GLYPH() etc.
Status:
As far as I understand, this patch is applied.
URL:
http://bibl4.oru.se/projects/rdesktop/patch19/patches/rdesktop-1.0.0-mmihalik-1.diff
Description:
Misc drawing changes.
Status:
As far as I understand, this patch is applied.
URL:
http://bibl4.oru.se/projects/rdesktop/patch19/patches/rdesktop-1.0.0-pl19-7-2-mmihalik-1.diff
Description:
Some kind of new alternative keyboard mapping implementation.
Status:
Not needed anymore, with the new keyboard mapping implementation.
URL:
http://bibl4.oru.se/projects/rdesktop/patch19/patches/rdesktop-gmp.patch
Description:
Use GMP for RSA crypto.
Status:
Not needed since rdesktop now use OpenSSL for all of the crypto.
URL:
http://bibl4.oru.se/projects/rdesktop/patch19/patches/rdesktop-new_kb.patch
Description:
Modifies one of the old keyboard mapping implementations in some way.
Status:
Not needed anymore, with the new keyboard mapping implementation.
URL:
http://bibl4.oru.se/projects/rdesktop/patch19/patches/rdesktop-openssl.patch
Description:
Support for linking rdesktop with OpenSSL.
Status:
Not needed anymore, rdesktop can optionally use system
OpenSSL.
URL:
http://bibl4.oru.se/projects/rdesktop/patch19/patches/rdesktop.vncviewer_patch
Description:
Hack for making the old (broken) keyboard mapping implementation work
with the VNC Xserver.
Status:
Not needed anymore, with the new keyboard mapping implementation.
URL:
http://bibl4.oru.se/projects/rdesktop/patch19/patches/rdesktop_keymap.patch
Description:
Some kind of new alternative keyboard mapping implementation.
Status:
Not needed anymore, with the new keyboard mapping implementation.
URL:
http://bibl4.oru.se/projects/rdesktop/patch19/patches/rdp-srvr-19-6-6.diff
Description:
Basic RDP server.
Status:
Not applied.
URL:
http://bibl4.oru.se/projects/rdesktop/patch19/patches/scroll-to-death-patch.txt
Description:
Fixes scroll-to-death problem in Excel and other applications.
Status:
Not needed; fixed in another way in recent versions of rdesktop.
URL:
http://bibl4.oru.se/projects/rdesktop/patch19/patches/spark-manpage-patch-19.4
Description:
Adds a manual page.
Status:
Not needed; rdesktop contains a manual page now.
URL:
http://bibl4.oru.se/projects/rdesktop/patch19/patches/spark-manpage-patch-19.4-1
Description:
Adds a manual page.
Status:
Not needed; rdesktop contains a manual page now.
URL:
http://bibl4.oru.se/projects/rdesktop/patch19/patches/spark_xinerama-patch2
Description:
Adds XINERAMA support to rdesktop.
Status:
Not applied yet. TBD.
URL:
http://bibl4.oru.se/projects/rdesktop/patch19/patches/svenni_dis_wmkeybnds.patch
Description:
Commandline flag to disable keyboard grabbing.
Status:
Applied.
URL:
http://bibl4.oru.se/projects/rdesktop/patch19/patches/svenni_disable_bs_in_x-tiny-patch
Description:
Disables backing store for TinyX.
Status:
As far as I understand, this patch is not need any longer.
URL:
http://bibl4.oru.se/projects/rdesktop/patch19/patches/vincent_19-7-2.license.patch
Description:
TBD
Status:
Not yet examined.
URL:
http://bibl4.oru.se/projects/rdesktop/patch19/patches/vincent_19-7-2.secure.patch
Description:
Fixes a problem during the connection to a French NT4 TSE (a French
NT4 TSE doesn't use encryptation).
Status:
Applied.
URL:
http://bibl4.oru.se/projects/rdesktop/patch19/patches/vincent_19-7-3_excel.patch
Description:
Makes matrixes appear better, such as those found in Excel/toad etc.
Status:
Applied.
URL:
http://bibl4.oru.se/projects/rdesktop/patch19/patches/vincent_8bpp.patch
Description:
Support a 8bpp display (256 colours).
Status:
An enhanced version is included in rdesktop; this patch is not needed any more.
URL:
http://bibl4.oru.se/projects/rdesktop/patch19/patches/vpypatch.txt
Description:
Various changes for one of the old keyboard stuff.
Status:
Not needed anymore, with the new keyboard mapping implementation.
@@ -0,0 +1,217 @@
.TH rdesktop 1 "November 2005"
.SH NAME
.I rdesktop
\- Remote Desktop Protocol client
.SH SYNOPSIS
.B rdesktop [options] server[:port]
.br
.SH DESCRIPTION
.I rdesktop
is a client for Remote Desktop Protocol (RDP), used in a number of Microsoft
products including Windows NT Terminal Server, Windows 2000 Server, Windows XP
and Windows 2003 Server.
.SH OPTIONS
.TP
.BR "-u <username>"
Username for authentication on the server.
.TP
.BR "-d <domain>"
Domain for authentication.
.TP
.BR "-s <shell>"
Startup shell for the user - starts a specific application instead of Explorer.
.TP
.BR "-c <directory>"
The initial working directory for the user. Often used in combination with -s
to set up a fixed login environment.
.TP
.BR "-p <password>"
The password to authenticate with. Note that this may have no effect if
"Always prompt for password" is enabled on the server. WARNING: if you specify
a password on the command line it may be visible to other users when they use
tools like ps. Use -p - to make rdesktop request a password at startup (from
standard input).
.TP
.BR "-n <hostname>"
Client hostname. Normally rdesktop automatically obtains the hostname of the
client.
.TP
.BR "-k <keyboard-map>"
Keyboard layout to emulate. This requires a corresponding keymap file to be
installed. The standard keymaps provided with rdesktop follow the RFC1766
naming scheme: a language code followed by a country code if necessary - e.g.
en-us, en-gb, de, fr, sv, etc.
The default keyboard map depends on the current locale (LC_* and LANG
environment variables). If the current locale is unknown, the default
keyboard map is en-us (a US English keyboard).
The keyboard maps are file names, which means that they are case
sensitive. The standard keymaps are all in lowercase.
The keyboard maps are searched relative to the directories
$HOME/.rdesktop/keymaps, KEYMAP_PATH (specified at build time), and
$CWD/keymaps, in this order. The keyboard-map argument can also be an
absolute filename.
The special value `none' can be used instead of a keyboard map.
In this case, rdesktop will guess the scancodes from the X11 event key
codes using an internal mapping method. This method only supports the
basic alphanumeric keys and may not work properly on all platforms
so its use is discouraged.
.TP
.BR "-g <geometry>"
Desktop geometry (WxH). If geometry is the special word "workarea", the geometry
will be fetched from the extended window manager hints property _NET_WORKAREA, from
the root window. The geometry can also be specified as a percentage of the whole
screen, e.g. "-g 80%".
.TP
.BR "-f"
Enable fullscreen mode. This overrides the window manager and causes the
rdesktop window to fully cover the current screen. Fullscreen mode can be
toggled at any time using Ctrl-Alt-Enter.
.TP
.BR "-b"
Force the server to send screen updates as bitmaps rather than using
higher-level drawing operations.
.TP
.BR "-A"
Enable SeamlessRDP. In this mode, rdesktop creates a X11 window for
each window on the server side. This mode requires the SeamlessRDP
server side component. When using this option, you should specify a
startup shell which launches the desired application through
SeamlessRDP. Example: rdesktop -A -s 'seamlessrdpshell notepad'.
.TP
.BR "-B"
Use the BackingStore of the Xserver instead of the integrated one in
rdesktop.
.TP
.BR "-e"
Disable encryption. This option is only needed (and will only work) if you
have a French version of NT TSE.
.TP
.BR "-E"
Disable encryption from client to server. This sends an encrypted login packet,
but everything after this is unencrypted (including interactive logins).
.TP
.BR "-m"
Do not send mouse motion events. This saves bandwidth, although some Windows
applications may rely on receiving mouse motion.
.TP
.BR "-C"
Use private colourmap. This will improve colour accuracy on an 8-bit display,
but rdesktop will appear in false colour when not focused.
.TP
.BR "-D"
Hide window manager decorations, by using MWM hints.
.TP
.BR "-K"
Do not override window manager key bindings. By default rdesktop attempts
to grab all keyboard input when it is in focus.
.TP
.BR "-S <button size>"
Enable single application mode. This option can be used when running a
single, maximized application (via -s). When the minimize button of
the windows application is pressed, the rdesktop window is minimized
instead of the remote application. The maximize/restore button is
disabled. For this to work, you must specify the correct button
size, in pixels. The special word "standard" means 18 pixels.
.TP
.BR "-T <title>"
Sets the window title.
.TP
.BR "-N"
Enable numlock syncronization between the Xserver and the remote RDP
session. This is useful with applications that looks at the numlock
state, but might cause problems with some Xservers like Xvnc.
.TP
.BR "-X <windowid>"
Embed rdesktop-window in another window. The windowid is expected to
be decimal or hexadecimal (prefixed by 0x).
.TP
.BR "-a <bpp>"
Sets the colour depth for the connection (8, 15, 16 or 24).
More than 8 bpp are only supported when connecting to Windows XP
(up to 16 bpp) or newer. Note that the colour depth may also be
limited by the server configuration. The default value is the depth
of the root window.
.TP
.BR "-z"
Enable compression of the RDP datastream.
.TP
.BR "-x <experience>"
Changes default bandwidth performance behaviour for RDP5. By default only
theming is enabled, and all other options are disabled (corresponding
to modem (56 Kbps)). Setting experience to b[roadband] enables menu
animations and full window dragging. Setting experience to l[an] will
also enable the desktop wallpaper. Setting experience to m[odem]
disables all (including themes). Experience can also be a hexidecimal
number containing the flags.
.TP
.BR "-P"
Enable caching of bitmaps to disk (persistent bitmap caching). This generally
improves performance (especially on low bandwidth connections) and reduces
network traffic at the cost of slightly longer startup and some disk space.
(10MB for 8-bit colour, 20MB for 15/16-bit colour and 30MB for 24-bit colour
sessions)
.TP
.BR "-r <device>"
Enable redirection of the specified device on the client, such
that it appears on the server. Note that the allowed
redirections may be restricted by the server configuration.
Following devices are currently supported:
.TP
.BR "-r comport:<comport>=<device>,..."
Redirects serial devices on your client to the
server. Note that if you need to change any settings on the serial device(s),
do so with an appropriate tool before starting rdesktop. In most
OSes you would use stty. Bidirectional/Read support requires Windows XP or newer.
In Windows 2000 it will create a port, but it's not seamless, most
shell programs will not work with it.
.TP
.BR "-r disk:<sharename>=<path>,..."
Redirects a path to the share \\\\tsclient\\<sharename> on the server
(requires Windows XP or newer). The share name is limited to 8
characters.
.TP
.BR "-r lptport:<lptport>=<device>,..."
Redirects parallel devices on your client to the server.
Bidirectional/Read support requires Windows XP or newer. In Windows 2000
it will create a port, but it's not seamless, most shell programs will not work with
it.
.TP
.BR "-r printer:<printername>[=<driver>],..."
Redirects a printer queue on the client to the server. The <printername>
is the name of the queue in your local system. <driver> defaults to a
simple PS-driver unless you specify one. Keep in mind that you need a
100% match in the server environment, or the driver will fail. The first
printer on the command line will be set as your default printer.
.TP
.BR "-r sound:[local|off|remote]"
Redirects sound generated on the server to the client. "remote" only has
any effect when you connect to the console with the -0 option. (Requires
Windows XP or newer).
.TP
.BR "-r lspci"
Activates the lspci channel, which allows the server to enumerate the
clients PCI devices. See the file lspci-channel.txt in the
documentation for more information.
.TP
.BR "-0"
Attach to the console of the server (requires Windows Server 2003
or newer).
.TP
.BR "-4"
Use RDP version 4.
.TP
.BR "-5"
Use RDP version 5 (default).
.PP
.SH LINKS
Main website of rdesktop
.br
\fIhttp://www.rdesktop.org/
.LP
.PP
@@ -0,0 +1,74 @@
Syntax for configuring RDP redirection modules
==============================================
General
-------
All redirection is configured using the -r option. The general syntax
is:
-r <module>:<string>
<module> is the name of the redirection module. The following names
are valid: disk, printer, lptport, comport, clipboard, sound.
<string> is interpreted by each redirection module.
The redirection modules are described below.
disk mapping
-------------
Multiple mappings possible: yes
Default: no disk redirected
Syntax: -r disk:<sharename>=<path>
Example: -r disk:home=/home/johndoe
printer mapping
---------------
Multiple mappings possible: yes
Default: no printers redirected
Syntax: -r printer:<printername>
Example: -r printer:mydeskjet
LPT port mapping
----------------
Multiple mappings possible: yes
Default: no LPT ports redirected
Syntax: -r lptport:<lptport>=<device>
Example: -r lptport:LPT1=/dev/lp0
COM port mapping
----------------
Multiple mappings possible: yes
Default: no COM ports redirected
Syntax: -r comport:<comport>=<device>
Example: -r comport:COM1=/dev/ttyS0
clipboard mapping
-----------------
Multiple mappings possible: no
Default: yes
Syntax: -r clipboard:[yes|no]
Example: -r clipboard:no
sound mapping
-------------
Multiple mappings possible: no
Default: off
Syntax: -r sound:[local|off|remote]
"local" means "Bring to this computer"
"off" means "Do not play"
"remote" means "Leave at remote computer"
Example: -r sound:remote
@@ -0,0 +1,284 @@
TODO
----
* Command for executing new programs.
* Commands for changing z order and focus.
* Command for transferring icon.
* Think about protocol version management
* Try to assure that messages aren't repeated or are sent for hidden windows.
Overview
========
The protocol is a line based protocol following this simple syntax:
OPERATION,SERIAL[,ARG1[,ARG2,[...]]]
Each operation will have an increasing serial number. The initial value is
implementation defined.
The goal is to have a generic protocol that can be used for other display
systems (e.g. VNC) as well.
One line may not exceed 1024 bytes, including newline.
The protocol has no concept of hidden or unmapped windows. A window does not
exist unless it is visible. Note that a minimized window is an exception to
this rule.
The protocol has no way of indicating failure, meaning that all commands are
expected to succeed. If a command fails, the receiving end must send a
corresponding command back, indicating the actual state.
Data types
==========
Window ID are written in hex, like 0x4321.
Window positions can be negative. This happens when a window is moved
outside the desktop.
All integers fit inside 32 bits.
Strings are sent in UTF-8 and do not contain any characters less than 0x20 or
the character , (comma).
Server to Client Operations
===========================
CREATE
------
Allocate structures for a new window.
Syntax:
CREATE,<SERIAL>,<ID>,<GRPID>,<PARENT>,<FLAGS>
Indicates that a window has appeared on the server. If PARENT is non-zero then
the new window is a child of that window (it's transient for it). The special
value 0xFFFFFFFF for PARENT means that the window is a popup window without a
parent. It's commonly used for splash screens, tool tips and context menus.
The group id identifies a set of windows that belong together. It is currently
only used for modal windows and DESTROYGRP.
Flags:
0x0001 : Create a window that's modal with regard to the other windows
in the same group.
Note that very little information is included in this message. Things like
title and state will come in subsequent messages. This message should only
be used to allocate data structures for the new window.
DESTROY
-------
Remove a window.
Syntax:
DESTROY,<SERIAL>,<ID>,<FLAGS>
Remove the window and deallocate all associated structures.
DESTROYGRP
----------
Destroy an entire group of windows.
Syntax:
DESTROYGRP,<SERIAL>,<GRPID>,<FLAGS>
Every window that belongs to the group GRPID should be destroyed as if they
each got a DESTROY message.
POSITION
--------
Move and/or resize a window.
Syntax:
POSITION,<SERIAL>,<ID>,<X>,<Y>,<WIDTH>,<HEIGHT>,<FLAGS>
If the window isn't visible yet (because a
STATE hasn't been set or because it's minimized), you must store the position
and size. A new POSITION is not guaranteed to be sent when the window changes
state.
TITLE
-----
Sets a window title.
Syntax:
TITLE,<SERIAL>,<ID>,<TITLE>,<FLAGS>
The text is guaranteed to be stripped of control characters (< 0x20).
Note that this has the same requirement as POSITION, that the title needs to
be stored for newly created windows until a STATE is sent. It is however not
guaranteed that a TITLE will be sent before the first STATE.
ZCHANGE
-------
The window moved in z order.
Syntax:
ZCHANGE,<SERIAL>,<ID>,<BEHIND>,<FLAGS>
The window with the id ID is behind the window with the id BEHIND. If
BEHIND is 0, then this window should be brought to the front.
STATE
-----
Changes the window's state and/or title.
Syntax:
STATE,<SERIAL>,<ID>,<STATE>,<FLAGS>
State can have one of three values:
0 : "Normal" window.
1 : Minimized.
2 : Maximized.
The initial STATE for a window will always be preceeded by one CREATE and one
POSITION. Optionally, a TITLE may also be sent before the first STATE.
DEBUG
-----
Debug output from the server component.
Syntax:
DEBUG,<SERIAL>,<STRING>
Used for debugging.
SYNCBEGIN
---------
Indicates that a synchronisation has begun.
Syntax:
SYNCBEGIN,<SERIAL>,<FLAGS>
Sent when the server starts a synchronisation. The client should flush all
information at this point.
SYNCEND
-------
Indicates that a synchronisation is complete.
Syntac:
SYNCEND,<SERIAL>,<FLAGS>
Sent when the last message that is part of the synchronisation has been sent.
This may be followed by duplicate messages and/or messages referring invalid
windows that were queued up during the synchronisation.
HELLO
-----
Initial message sent by server.
Syntax:
HELLO,<SERIAL>,<FLAGS>
The server starts each connection by sending this message. Normally the client
will react by sending a SYNC back to the server.
Flags:
0x0001 : This is a reconnect to an existing session.
0x0002 : The desktop is currently hidden (see HIDE).
ACK
---
Acknowledgement of a request to manipulate a window.
Syntax:
ACK,<SERIAL>,<ACKSERIAL>
Whenever one of the commands POSITION, ZCHANGE, STATE or FOCUS is executed on
the server, the server will send an ACK back to the client. The purpose of this
is to inform the client of when the operation was actually performed, allowing
high latencies in the channel.
HIDE
----
The desktop has become hidden on the server.
Syntax:
HIDE,<SERIAL>,<FLAGS>
This message is sent when the desktop on the server is obscured by something
that cannot be tracked. The client should remove all windows and display the
entire desktop, allowing the user to handle whatever is blocking the view.
Note that updates to windows will still be sent as the windows still exist on
the server, they are merely not visible.
UNHIDE
------
The desktop has been restored on the server.
Syntax:
UNHIDE,<SERIAL>,<FLAGS>
This message is sent some time after a HIDE, indicating that the windowed view
has been restored. If the client has dropped all information about windows then
it can send a SYNC to re-enumerate them.
Client to Server Operations
===========================
SYNC
----
Request a synchronisation of window information.
Syntax:
SYNC,<SERIAL>,<FLAGS>
For each window, the server will send CREATE, POSITION and STATE, in that
order, just as if the window was created. Note that a TITLE may also,
optionally, be sent before the STATE.
POSITION
--------
Identical to the command sent from server to client.
TITLE
-----
Identical to the command sent from server to client.
ZCHANGE
-------
Identical to the command sent from server to client.
STATE
-----
Identical to the command sent from server to client.
FOCUS
-----
Sets which window has input focus.
Syntax:
FOCUS,<SERIAL>,<ID>,<FLAGS>
Changes which window that will recieve the keyboard events. Note that this
might cause the window to change z order.
@@ -0,0 +1,464 @@
/* -*- c-basic-offset: 8 -*-
rdesktop: A Remote Desktop Protocol client.
Support functions for Extended Window Manager Hints,
http://www.freedesktop.org/wiki/Standards_2fwm_2dspec
Copyright (C) Peter Astrand <[email protected]> 2005
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <X11/Xlib.h>
#include <X11/Xatom.h>
#include <X11/Xutil.h>
#include "rdesktop.h"
#define _NET_WM_STATE_REMOVE 0 /* remove/unset property */
#define _NET_WM_STATE_ADD 1 /* add/set property */
#define _NET_WM_STATE_TOGGLE 2 /* toggle property */
extern Display *g_display;
static Atom g_net_wm_state_maximized_vert_atom, g_net_wm_state_maximized_horz_atom,
g_net_wm_state_hidden_atom, g_net_wm_name_atom, g_utf8_string_atom,
g_net_wm_state_skip_taskbar_atom, g_net_wm_state_skip_pager_atom, g_net_wm_state_modal_atom;
Atom g_net_wm_state_atom, g_net_wm_desktop_atom;
/*
Get window property value (32 bit format)
Returns zero on success, -1 on error
*/
static int
get_property_value(Window wnd, char *propname, long max_length,
unsigned long *nitems_return, unsigned char **prop_return, int nowarn)
{
int result;
Atom property;
Atom actual_type_return;
int actual_format_return;
unsigned long bytes_after_return;
property = XInternAtom(g_display, propname, True);
if (property == None)
{
fprintf(stderr, "Atom %s does not exist\n", propname);
return (-1);
}
result = XGetWindowProperty(g_display, wnd, property, 0, /* long_offset */
max_length, /* long_length */
False, /* delete */
AnyPropertyType, /* req_type */
&actual_type_return,
&actual_format_return,
nitems_return, &bytes_after_return, prop_return);
if (result != Success)
{
fprintf(stderr, "XGetWindowProperty failed\n");
return (-1);
}
if (actual_type_return == None || actual_format_return == 0)
{
if (!nowarn)
fprintf(stderr, "Window is missing property %s\n", propname);
return (-1);
}
if (bytes_after_return)
{
fprintf(stderr, "%s is too big for me\n", propname);
return (-1);
}
if (actual_format_return != 32)
{
fprintf(stderr, "%s has bad format\n", propname);
return (-1);
}
return (0);
}
/*
Get current desktop number
Returns -1 on error
*/
static int
get_current_desktop(void)
{
unsigned long nitems_return;
unsigned char *prop_return;
int current_desktop;
if (get_property_value
(DefaultRootWindow(g_display), "_NET_CURRENT_DESKTOP", 1, &nitems_return,
&prop_return, 0) < 0)
return (-1);
if (nitems_return != 1)
{
fprintf(stderr, "_NET_CURRENT_DESKTOP has bad length\n");
return (-1);
}
current_desktop = *prop_return;
XFree(prop_return);
return current_desktop;
}
/*
Get workarea geometry
Returns zero on success, -1 on error
*/
int
get_current_workarea(uint32 * x, uint32 * y, uint32 * width, uint32 * height)
{
int current_desktop;
unsigned long nitems_return;
unsigned char *prop_return;
uint32 *return_words;
const uint32 net_workarea_x_offset = 0;
const uint32 net_workarea_y_offset = 1;
const uint32 net_workarea_width_offset = 2;
const uint32 net_workarea_height_offset = 3;
const uint32 max_prop_length = 32 * 4; /* Max 32 desktops */
if (get_property_value
(DefaultRootWindow(g_display), "_NET_WORKAREA", max_prop_length, &nitems_return,
&prop_return, 0) < 0)
return (-1);
if (nitems_return % 4)
{
fprintf(stderr, "_NET_WORKAREA has odd length\n");
return (-1);
}
current_desktop = get_current_desktop();
if (current_desktop < 0)
return -1;
return_words = (uint32 *) prop_return;
*x = return_words[current_desktop * 4 + net_workarea_x_offset];
*y = return_words[current_desktop * 4 + net_workarea_y_offset];
*width = return_words[current_desktop * 4 + net_workarea_width_offset];
*height = return_words[current_desktop * 4 + net_workarea_height_offset];
XFree(prop_return);
return (0);
}
void
ewmh_init()
{
/* FIXME: Use XInternAtoms */
g_net_wm_state_maximized_vert_atom =
XInternAtom(g_display, "_NET_WM_STATE_MAXIMIZED_VERT", False);
g_net_wm_state_maximized_horz_atom =
XInternAtom(g_display, "_NET_WM_STATE_MAXIMIZED_HORZ", False);
g_net_wm_state_hidden_atom = XInternAtom(g_display, "_NET_WM_STATE_HIDDEN", False);
g_net_wm_state_skip_taskbar_atom =
XInternAtom(g_display, "_NET_WM_STATE_SKIP_TASKBAR", False);
g_net_wm_state_skip_pager_atom = XInternAtom(g_display, "_NET_WM_STATE_SKIP_PAGER", False);
g_net_wm_state_modal_atom = XInternAtom(g_display, "_NET_WM_STATE_MODAL", False);
g_net_wm_state_atom = XInternAtom(g_display, "_NET_WM_STATE", False);
g_net_wm_desktop_atom = XInternAtom(g_display, "_NET_WM_DESKTOP", False);
g_net_wm_name_atom = XInternAtom(g_display, "_NET_WM_NAME", False);
g_utf8_string_atom = XInternAtom(g_display, "UTF8_STRING", False);
}
/*
Get the window state: normal/minimized/maximized.
*/
#ifndef MAKE_PROTO
int
ewmh_get_window_state(Window w)
{
unsigned long nitems_return;
unsigned char *prop_return;
uint32 *return_words;
unsigned long item;
BOOL maximized_vert, maximized_horz, hidden;
maximized_vert = maximized_horz = hidden = False;
if (get_property_value(w, "_NET_WM_STATE", 64, &nitems_return, &prop_return, 0) < 0)
return SEAMLESSRDP_NORMAL;
return_words = (uint32 *) prop_return;
for (item = 0; item < nitems_return; item++)
{
if (return_words[item] == g_net_wm_state_maximized_vert_atom)
maximized_vert = True;
if (return_words[item] == g_net_wm_state_maximized_horz_atom)
maximized_horz = True;
if (return_words[item] == g_net_wm_state_hidden_atom)
hidden = True;
}
XFree(prop_return);
if (maximized_vert && maximized_horz)
return SEAMLESSRDP_MAXIMIZED;
else if (hidden)
return SEAMLESSRDP_MINIMIZED;
else
return SEAMLESSRDP_NORMAL;
}
static int
ewmh_modify_state(Window wnd, int add, Atom atom1, Atom atom2)
{
Status status;
XEvent xevent;
int result;
unsigned long nitems;
unsigned char *props;
uint32 state = WithdrawnState;
/* The spec states that the window manager must respect any
_NET_WM_STATE attributes on a withdrawn window. In order words, we
modify the attributes directly for withdrawn windows and ask the WM
to do it for active windows. */
result = get_property_value(wnd, "WM_STATE", 64, &nitems, &props, 1);
if ((result >= 0) && nitems)
{
state = *(uint32 *) props;
XFree(props);
}
if (state == WithdrawnState)
{
if (add)
{
Atom atoms[2];
atoms[0] = atom1;
nitems = 1;
if (atom2)
{
atoms[1] = atom2;
nitems = 2;
}
XChangeProperty(g_display, wnd, g_net_wm_state_atom, XA_ATOM,
32, PropModeAppend, (unsigned char *) atoms, nitems);
}
else
{
Atom *atoms;
int i;
if (get_property_value(wnd, "_NET_WM_STATE", 64, &nitems, &props, 1) < 0)
return 0;
atoms = (Atom *) props;
for (i = 0; i < nitems; i++)
{
if ((atoms[i] == atom1) || (atom2 && (atoms[i] == atom2)))
{
if (i != (nitems - 1))
memmove(&atoms[i], &atoms[i + 1],
sizeof(Atom) * (nitems - i - 1));
nitems--;
i--;
}
}
XChangeProperty(g_display, wnd, g_net_wm_state_atom, XA_ATOM,
32, PropModeReplace, (unsigned char *) atoms, nitems);
XFree(props);
}
return 0;
}
xevent.type = ClientMessage;
xevent.xclient.window = wnd;
xevent.xclient.message_type = g_net_wm_state_atom;
xevent.xclient.format = 32;
if (add)
xevent.xclient.data.l[0] = _NET_WM_STATE_ADD;
else
xevent.xclient.data.l[0] = _NET_WM_STATE_REMOVE;
xevent.xclient.data.l[1] = atom1;
xevent.xclient.data.l[2] = atom2;
xevent.xclient.data.l[3] = 0;
xevent.xclient.data.l[4] = 0;
status = XSendEvent(g_display, DefaultRootWindow(g_display), False,
SubstructureNotifyMask | SubstructureRedirectMask, &xevent);
if (!status)
return -1;
return 0;
}
/*
Set the window state: normal/minimized/maximized.
Returns -1 on failure.
*/
int
ewmh_change_state(Window wnd, int state)
{
/*
* Deal with the max atoms
*/
if (state == SEAMLESSRDP_MAXIMIZED)
{
if (ewmh_modify_state
(wnd, 1, g_net_wm_state_maximized_vert_atom,
g_net_wm_state_maximized_horz_atom) < 0)
return -1;
}
else
{
if (ewmh_modify_state
(wnd, 0, g_net_wm_state_maximized_vert_atom,
g_net_wm_state_maximized_horz_atom) < 0)
return -1;
}
return 0;
}
int
ewmh_get_window_desktop(Window wnd)
{
unsigned long nitems_return;
unsigned char *prop_return;
int desktop;
if (get_property_value(wnd, "_NET_WM_DESKTOP", 1, &nitems_return, &prop_return, 0) < 0)
return (-1);
if (nitems_return != 1)
{
fprintf(stderr, "_NET_WM_DESKTOP has bad length\n");
return (-1);
}
desktop = *prop_return;
XFree(prop_return);
return desktop;
}
int
ewmh_move_to_desktop(Window wnd, unsigned int desktop)
{
Status status;
XEvent xevent;
xevent.type = ClientMessage;
xevent.xclient.window = wnd;
xevent.xclient.message_type = g_net_wm_desktop_atom;
xevent.xclient.format = 32;
xevent.xclient.data.l[0] = desktop;
xevent.xclient.data.l[1] = 0;
xevent.xclient.data.l[2] = 0;
xevent.xclient.data.l[3] = 0;
xevent.xclient.data.l[4] = 0;
status = XSendEvent(g_display, DefaultRootWindow(g_display), False,
SubstructureNotifyMask | SubstructureRedirectMask, &xevent);
if (!status)
return -1;
return 0;
}
void
ewmh_set_wm_name(Window wnd, const char *title)
{
int len;
len = strlen(title);
XChangeProperty(g_display, wnd, g_net_wm_name_atom, g_utf8_string_atom,
8, PropModeReplace, (unsigned char *) title, len);
}
int
ewmh_set_window_popup(Window wnd)
{
if (ewmh_modify_state
(wnd, 1, g_net_wm_state_skip_taskbar_atom, g_net_wm_state_skip_pager_atom) < 0)
return -1;
return 0;
}
int
ewmh_set_window_modal(Window wnd)
{
if (ewmh_modify_state(wnd, 1, g_net_wm_state_modal_atom, 0) < 0)
return -1;
return 0;
}
#endif /* MAKE_PROTO */
#if 0
/* FIXME: _NET_MOVERESIZE_WINDOW is for pagers, not for
applications. We should implement _NET_WM_MOVERESIZE instead */
int
ewmh_net_moveresize_window(Window wnd, int x, int y, int width, int height)
{
Status status;
XEvent xevent;
Atom moveresize;
moveresize = XInternAtom(g_display, "_NET_MOVERESIZE_WINDOW", False);
if (!moveresize)
{
return -1;
}
xevent.type = ClientMessage;
xevent.xclient.window = wnd;
xevent.xclient.message_type = moveresize;
xevent.xclient.format = 32;
xevent.xclient.data.l[0] = StaticGravity | (1 << 8) | (1 << 9) | (1 << 10) | (1 << 11);
xevent.xclient.data.l[1] = x;
xevent.xclient.data.l[2] = y;
xevent.xclient.data.l[3] = width;
xevent.xclient.data.l[4] = height;
status = XSendEvent(g_display, DefaultRootWindow(g_display), False,
SubstructureNotifyMask | SubstructureRedirectMask, &xevent);
if (!status)
return -1;
return 0;
}
#endif
@@ -0,0 +1,3 @@
#!/bin/sh
indent -bli0 -i8 -cli8 -npcs -l100 *.h *.c vnc/*.h vnc/*.c
@@ -0,0 +1,251 @@
#!/bin/sh
#
# install - install a program, script, or datafile
# This comes from X11R5 (mit/util/scripts/install.sh).
#
# Copyright 1991 by the Massachusetts Institute of Technology
#
# Permission to use, copy, modify, distribute, and sell this software and its
# documentation for any purpose is hereby granted without fee, provided that
# the above copyright notice appear in all copies and that both that
# copyright notice and this permission notice appear in supporting
# documentation, and that the name of M.I.T. not be used in advertising or
# publicity pertaining to distribution of the software without specific,
# written prior permission. M.I.T. makes no representations about the
# suitability of this software for any purpose. It is provided "as is"
# without express or implied warranty.
#
# Calling this script install-sh is preferred over install.sh, to prevent
# `make' implicit rules from creating a file called install from it
# when there is no Makefile.
#
# This script is compatible with the BSD install script, but was written
# from scratch. It can only install one file at a time, a restriction
# shared with many OS's install programs.
# set DOITPROG to echo to test this script
# Don't use :- since 4.3BSD and earlier shells don't like it.
doit="${DOITPROG-}"
# put in absolute paths if you don't have them in your path; or use env. vars.
mvprog="${MVPROG-mv}"
cpprog="${CPPROG-cp}"
chmodprog="${CHMODPROG-chmod}"
chownprog="${CHOWNPROG-chown}"
chgrpprog="${CHGRPPROG-chgrp}"
stripprog="${STRIPPROG-strip}"
rmprog="${RMPROG-rm}"
mkdirprog="${MKDIRPROG-mkdir}"
transformbasename=""
transform_arg=""
instcmd="$mvprog"
chmodcmd="$chmodprog 0755"
chowncmd=""
chgrpcmd=""
stripcmd=""
rmcmd="$rmprog -f"
mvcmd="$mvprog"
src=""
dst=""
dir_arg=""
while [ x"$1" != x ]; do
case $1 in
-c) instcmd="$cpprog"
shift
continue;;
-d) dir_arg=true
shift
continue;;
-m) chmodcmd="$chmodprog $2"
shift
shift
continue;;
-o) chowncmd="$chownprog $2"
shift
shift
continue;;
-g) chgrpcmd="$chgrpprog $2"
shift
shift
continue;;
-s) stripcmd="$stripprog"
shift
continue;;
-t=*) transformarg=`echo $1 | sed 's/-t=//'`
shift
continue;;
-b=*) transformbasename=`echo $1 | sed 's/-b=//'`
shift
continue;;
*) if [ x"$src" = x ]
then
src=$1
else
# this colon is to work around a 386BSD /bin/sh bug
:
dst=$1
fi
shift
continue;;
esac
done
if [ x"$src" = x ]
then
echo "install: no input file specified"
exit 1
else
:
fi
if [ x"$dir_arg" != x ]; then
dst=$src
src=""
if [ -d $dst ]; then
instcmd=:
chmodcmd=""
else
instcmd=$mkdirprog
fi
else
# Waiting for this to be detected by the "$instcmd $src $dsttmp" command
# might cause directories to be created, which would be especially bad
# if $src (and thus $dsttmp) contains '*'.
if [ -f "$src" ] || [ -d "$src" ]
then
:
else
echo "install: $src does not exist"
exit 1
fi
if [ x"$dst" = x ]
then
echo "install: no destination specified"
exit 1
else
:
fi
# If destination is a directory, append the input filename; if your system
# does not like double slashes in filenames, you may need to add some logic
if [ -d $dst ]
then
dst="$dst"/`basename $src`
else
:
fi
fi
## this sed command emulates the dirname command
dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
# Make sure that the destination directory exists.
# this part is taken from Noah Friedman's mkinstalldirs script
# Skip lots of stat calls in the usual case.
if [ ! -d "$dstdir" ]; then
defaultIFS='
'
IFS="${IFS-${defaultIFS}}"
oIFS="${IFS}"
# Some sh's can't handle IFS=/ for some reason.
IFS='%'
set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'`
IFS="${oIFS}"
pathcomp=''
while [ $# -ne 0 ] ; do
pathcomp="${pathcomp}${1}"
shift
if [ ! -d "${pathcomp}" ] ;
then
$mkdirprog "${pathcomp}"
else
:
fi
pathcomp="${pathcomp}/"
done
fi
if [ x"$dir_arg" != x ]
then
$doit $instcmd $dst &&
if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else : ; fi &&
if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else : ; fi &&
if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else : ; fi &&
if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else : ; fi
else
# If we're going to rename the final executable, determine the name now.
if [ x"$transformarg" = x ]
then
dstfile=`basename $dst`
else
dstfile=`basename $dst $transformbasename |
sed $transformarg`$transformbasename
fi
# don't allow the sed command to completely eliminate the filename
if [ x"$dstfile" = x ]
then
dstfile=`basename $dst`
else
:
fi
# Make a temp file name in the proper directory.
dsttmp=$dstdir/#inst.$$#
# Move or copy the file name to the temp name
$doit $instcmd $src $dsttmp &&
trap "rm -f ${dsttmp}" 0 &&
# and set any options; do chmod last to preserve setuid bits
# If any of these fail, we abort the whole thing. If we want to
# ignore errors from any of these, just make sure not to ignore
# errors from the above "$doit $instcmd $src $dsttmp" command.
if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else :;fi &&
if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else :;fi &&
if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else :;fi &&
if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else :;fi &&
# Now rename the file to the real destination.
$doit $rmcmd -f $dstdir/$dstfile &&
$doit $mvcmd $dsttmp $dstdir/$dstfile
fi &&
exit 0
@@ -0,0 +1,231 @@
/* -*- c-basic-offset: 8 -*-
rdesktop: A Remote Desktop Protocol client.
Protocol services - ISO layer
Copyright (C) Matthew Chapman 1999-2005
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "rdesktop.h"
/* Send a self-contained ISO PDU */
static void
iso_send_msg(uint8 code)
{
STREAM s;
s = tcp_init(11);
out_uint8(s, 3); /* version */
out_uint8(s, 0); /* reserved */
out_uint16_be(s, 11); /* length */
out_uint8(s, 6); /* hdrlen */
out_uint8(s, code);
out_uint16(s, 0); /* dst_ref */
out_uint16(s, 0); /* src_ref */
out_uint8(s, 0); /* class */
s_mark_end(s);
tcp_send(s);
}
static void
iso_send_connection_request(char *username)
{
STREAM s;
int length = 30 + strlen(username);
s = tcp_init(length);
out_uint8(s, 3); /* version */
out_uint8(s, 0); /* reserved */
out_uint16_be(s, length); /* length */
out_uint8(s, length - 5); /* hdrlen */
out_uint8(s, ISO_PDU_CR);
out_uint16(s, 0); /* dst_ref */
out_uint16(s, 0); /* src_ref */
out_uint8(s, 0); /* class */
out_uint8p(s, "Cookie: mstshash=", strlen("Cookie: mstshash="));
out_uint8p(s, username, strlen(username));
out_uint8(s, 0x0d); /* Unknown */
out_uint8(s, 0x0a); /* Unknown */
s_mark_end(s);
tcp_send(s);
}
/* Receive a message on the ISO layer, return code */
static STREAM
iso_recv_msg(uint8 * code, uint8 * rdpver)
{
STREAM s;
uint16 length;
uint8 version;
s = tcp_recv(NULL, 4);
if (s == NULL)
return NULL;
in_uint8(s, version);
if (rdpver != NULL)
*rdpver = version;
if (version == 3)
{
in_uint8s(s, 1); /* pad */
in_uint16_be(s, length);
}
else
{
in_uint8(s, length);
if (length & 0x80)
{
length &= ~0x80;
next_be(s, length);
}
}
s = tcp_recv(s, length - 4);
if (s == NULL)
return NULL;
if (version != 3)
return s;
in_uint8s(s, 1); /* hdrlen */
in_uint8(s, *code);
if (*code == ISO_PDU_DT)
{
in_uint8s(s, 1); /* eot */
return s;
}
in_uint8s(s, 5); /* dst_ref, src_ref, class */
return s;
}
/* Initialise ISO transport data packet */
STREAM
iso_init(int length)
{
STREAM s;
s = tcp_init(length + 7);
s_push_layer(s, iso_hdr, 7);
return s;
}
/* Send an ISO data PDU */
void
iso_send(STREAM s)
{
uint16 length;
s_pop_layer(s, iso_hdr);
length = s->end - s->p;
out_uint8(s, 3); /* version */
out_uint8(s, 0); /* reserved */
out_uint16_be(s, length);
out_uint8(s, 2); /* hdrlen */
out_uint8(s, ISO_PDU_DT); /* code */
out_uint8(s, 0x80); /* eot */
tcp_send(s);
}
/* Receive ISO transport data packet */
STREAM
iso_recv(uint8 * rdpver)
{
STREAM s;
uint8 code = 0;
s = iso_recv_msg(&code, rdpver);
if (s == NULL)
return NULL;
if (rdpver != NULL)
if (*rdpver != 3)
return s;
if (code != ISO_PDU_DT)
{
error("expected DT, got 0x%x\n", code);
return NULL;
}
return s;
}
/* Establish a connection up to the ISO layer */
BOOL
iso_connect(char *server, char *username)
{
uint8 code = 0;
if (!tcp_connect(server))
return False;
iso_send_connection_request(username);
if (iso_recv_msg(&code, NULL) == NULL)
return False;
if (code != ISO_PDU_CC)
{
error("expected CC, got 0x%x\n", code);
tcp_disconnect();
return False;
}
return True;
}
/* Establish a reconnection up to the ISO layer */
BOOL
iso_reconnect(char *server)
{
uint8 code = 0;
if (!tcp_connect(server))
return False;
iso_send_msg(ISO_PDU_CR);
if (iso_recv_msg(&code, NULL) == NULL)
return False;
if (code != ISO_PDU_CC)
{
error("expected CC, got 0x%x\n", code);
tcp_disconnect();
return False;
}
return True;
}
/* Disconnect from the ISO layer */
void
iso_disconnect(void)
{
iso_send_msg(ISO_PDU_DR);
tcp_disconnect();
}
/* reset the state to support reconnecting */
void
iso_reset_state(void)
{
tcp_reset_state();
}
@@ -0,0 +1,98 @@
# generated from XKB map ar
include common
map 0x401
exclam 0x02 shift
at 0x03 shift
numbersign 0x04 shift
dollar 0x05 shift
percent 0x06 shift
asciicircum 0x07 shift
ampersand 0x08 shift
asterisk 0x09 shift
parenleft 0x0a shift
parenright 0x0b shift
minus 0x0c
underscore 0x0c shift
equal 0x0d
plus 0x0d shift
Arabic_dad 0x10 altgr
Arabic_fatha 0x10 shift altgr
Arabic_sad 0x11 altgr
Arabic_fathatan 0x11 shift altgr
Arabic_theh 0x12 altgr
Arabic_damma 0x12 shift altgr
Arabic_qaf 0x13 altgr
Arabic_dammatan 0x13 shift altgr
Arabic_feh 0x14 altgr
UFEF9 0x14 shift altgr
Arabic_ghain 0x15 altgr
Arabic_hamzaunderalef 0x15 shift altgr
Arabic_ain 0x16 altgr
grave 0x16 shift altgr
Arabic_ha 0x17 altgr
division 0x17 shift altgr
Arabic_khah 0x18 altgr
multiply 0x18 shift altgr
Arabic_hah 0x19 altgr
Arabic_semicolon 0x19 shift altgr
bracketleft 0x1a
braceleft 0x1a shift
Arabic_jeem 0x1a altgr
bracketright 0x1b
braceright 0x1b shift
Arabic_dal 0x1b altgr
Arabic_sheen 0x1e altgr
backslash 0x1e shift altgr
Arabic_seen 0x1f altgr
Arabic_yeh 0x20 altgr
bracketleft 0x20 shift altgr
Arabic_beh 0x21 altgr
bracketright 0x21 shift altgr
Arabic_lam 0x22 altgr
UFEF7 0x22 shift altgr
Arabic_alef 0x23 altgr
Arabic_hamzaonalef 0x23 shift altgr
Arabic_teh 0x24 altgr
Arabic_tatweel 0x24 shift altgr
Arabic_noon 0x25 altgr
Arabic_comma 0x25 shift altgr
Arabic_meem 0x26 altgr
slash 0x26 shift altgr
semicolon 0x27
colon 0x27 shift
Arabic_kaf 0x27 altgr
apostrophe 0x28
quotedbl 0x28 shift
Arabic_tah 0x28 altgr
grave 0x29
asciitilde 0x29 shift
Arabic_thal 0x29 altgr
Arabic_shadda 0x29 shift altgr
backslash 0x2b
bar 0x2b shift
less 0x2b altgr
greater 0x2b shift altgr
Arabic_hamzaonyeh 0x2c altgr
asciitilde 0x2c shift altgr
Arabic_hamza 0x2d altgr
Arabic_sukun 0x2d shift altgr
Arabic_hamzaonwaw 0x2e altgr
Arabic_kasra 0x2e shift altgr
Arabic_ra 0x2f altgr
Arabic_kasratan 0x2f shift altgr
UFEFB 0x30 altgr
UFEF5 0x30 shift altgr
Arabic_alefmaksura 0x31 altgr
Arabic_maddaonalef 0x31 shift altgr
Arabic_tehmarbuta 0x32 altgr
apostrophe 0x32 shift altgr
comma 0x33
less 0x33 shift
Arabic_waw 0x33 altgr
period 0x34
greater 0x34 shift
Arabic_zain 0x34 altgr
slash 0x35
question 0x35 shift
Arabic_zah 0x35 altgr
Arabic_question_mark 0x35 shift altgr
@@ -0,0 +1,229 @@
include modifiers
#
# Top row
#
1 0x2
2 0x3
3 0x4
4 0x5
5 0x6
6 0x7
7 0x8
8 0x9
9 0xa
0 0xb
BackSpace 0xe
#
# QWERTY first row
#
Tab 0xf localstate
ISO_Left_Tab 0xf shift
q 0x10 addupper
w 0x11 addupper
e 0x12 addupper
sequence egrave dead_grave e
sequence Egrave dead_grave E
sequence eacute dead_acute e
sequence Eacute dead_acute E
sequence ecircumflex dead_circumflex e
sequence Ecircumflex dead_circumflex E
sequence ediaeresis dead_diaeresis e
sequence Ediaeresis dead_diaeresis E
r 0x13 addupper
t 0x14 addupper
y 0x15 addupper
sequence ygrave dead_grave y
sequence Ygrave dead_grave Y
sequence yacute dead_acute y
sequence Yacute dead_acute Y
sequence ycircumflex dead_circumflex y
sequence Ycircumflex dead_circumflex Y
sequence ydiaeresis dead_diaeresis y
sequence Ydiaeresis dead_diaeresis Y
u 0x16 addupper
sequence ugrave dead_grave u
sequence Ugrave dead_grave U
sequence uacute dead_acute u
sequence Uacute dead_acute U
sequence ucircumflex dead_circumflex u
sequence Ucircumflex dead_circumflex U
sequence udiaeresis dead_diaeresis u
sequence Udiaeresis dead_diaeresis U
i 0x17 addupper
sequence igrave dead_grave i
sequence Igrave dead_grave I
sequence iacute dead_acute i
sequence Iacute dead_acute I
sequence icircumflex dead_circumflex i
sequence Icircumflex dead_circumflex I
sequence idiaeresis dead_diaeresis i
sequence Idiaeresis dead_diaeresis I
o 0x18 addupper
sequence ograve dead_grave o
sequence Ograve dead_grave O
sequence oacute dead_acute o
sequence Oacute dead_acute O
sequence ocircumflex dead_circumflex o
sequence Ocircumflex dead_circumflex O
sequence odiaeresis dead_diaeresis o
sequence Odiaeresis dead_diaeresis O
sequence otilde dead_tilde o
sequence Otilde dead_tilde O
p 0x19 addupper
#
# QWERTY second row
#
a 0x1e addupper
sequence agrave dead_grave a
sequence Agrave dead_grave A
sequence aacute dead_acute a
sequence Aacute dead_acute A
sequence acircumflex dead_circumflex a
sequence Acircumflex dead_circumflex A
sequence adiaeresis dead_diaeresis a
sequence Adiaeresis dead_diaeresis A
sequence aring dead_abovering a
sequence Aring dead_abovering A
sequence atilde dead_tilde a
sequence Atilde dead_tilde A
s 0x1f addupper
d 0x20 addupper
f 0x21 addupper
g 0x22 addupper
h 0x23 addupper
j 0x24 addupper
k 0x25 addupper
l 0x26 addupper
Return 0x1c localstate
#
# QWERTY third row
#
z 0x2c addupper
x 0x2d addupper
c 0x2e addupper
sequence ccedilla dead_cedilla c
sequence Ccedilla dead_cedilla C
v 0x2f addupper
b 0x30 addupper
n 0x31 addupper
sequence ntilde dead_tilde n
sequence Ntilde dead_tilde N
m 0x32 addupper
space 0x39 localstate
less 0x56
greater 0x56 shift
bar 0x56 altgr
brokenbar 0x56 shift altgr
#
# Translations for some other dead keys
#
sequence asciitilde dead_tilde space
sequence diaeresis dead_diaeresis space
sequence asciicircum dead_circumflex space
sequence apostrophe dead_acute space
sequence grave dead_grave space
sequence acute dead_acute space
#
# Esc and Function keys
#
Escape 0x1 localstate
F1 0x3b localstate
F2 0x3c localstate
F3 0x3d localstate
F4 0x3e localstate
F5 0x3f localstate
F6 0x40 localstate
F7 0x41 localstate
F8 0x42 localstate
F9 0x43 localstate
F10 0x44 localstate
F11 0x57 localstate
SunF36 0x57 localstate
F12 0x58 localstate
SunF37 0x58 localstate
# Printscreen, Scrollock and Pause
# Printscreen really requires four scancodes (0xe0, 0x2a, 0xe0, 0x37),
# but (0xe0, 0x37) seems to work.
Print 0xb7 localstate
Sys_Req 0xb7 localstate
Execute 0xb7 localstate
F22 0xb7 localstate
Scroll_Lock 0x46
F23 0x46
#
# Insert - PgDown
#
Insert 0xd2 localstate
Delete 0xd3 localstate
Home 0xc7 localstate
End 0xcf localstate
Page_Up 0xc9 localstate
Page_Down 0xd1 localstate
#
# Arrow keys
#
Left 0xcb localstate
Up 0xc8 localstate
Down 0xd0 localstate
Right 0xcd localstate
#
# Numpad
#
Num_Lock 0x45
KP_Divide 0xb5 localstate
KP_Multiply 0x37 localstate
KP_Subtract 0x4a localstate
KP_Add 0x4e localstate
KP_Enter 0x9c localstate
KP_Decimal 0x53 numlock
KP_Separator 0x53 numlock
KP_Delete 0x53
KP_0 0x52 numlock
KP_Insert 0x52 localstate
KP_1 0x4f numlock
KP_End 0x4f localstate
KP_2 0x50 numlock
KP_Down 0x50 localstate
KP_3 0x51 numlock
KP_Next 0x51 localstate
KP_4 0x4b numlock
KP_Left 0x4b localstate
KP_5 0x4c numlock
KP_Begin 0x4c localstate
KP_6 0x4d numlock
KP_Right 0x4d localstate
KP_7 0x47 numlock
KP_Home 0x47 localstate
KP_8 0x48 numlock
KP_Up 0x48 localstate
KP_9 0x49 numlock
KP_Prior 0x49 localstate
#
# Inhibited keys
#
Caps_Lock 0x0 inhibit
Multi_key 0x0 inhibit
@@ -0,0 +1,63 @@
#!/usr/bin/env python2
# -*-Python-*-
#
#
# Copyright (C) 2001 Peter Åstrand <[email protected]>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; version 2 of the License.
#
# This program 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 General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
import sys
def main():
f = open(sys.argv[1])
while 1:
line = f.readline()
if not line: break
if line.startswith("#") or line.startswith("include"):
print line,
continue
fields = line.split()
if line.startswith("map"):
print "map 0x%s" % fields[1]
continue
scancode = fields[0]
for pos in range(1, len(fields)):
keysym = fields[pos]
if pos == 1:
modifiers = ""
elif pos == 2:
modifiers = "shift"
elif pos == 3:
modifiers = "altgr"
elif pos == 4:
modifiers = "shift altgr"
else:
raise("Invalid line: %s" % line)
print "%s 0x%s %s" % (keysym, scancode, modifiers)
if __name__ == "__main__":
if len(sys.argv) < 2:
print "Convert old-style keymaps to new style"
print "Usage: %s <old-style-keymap>" % sys.argv[0]
sys.exit(1)
else:
main()
@@ -0,0 +1,87 @@
# Czech keymap
include common
map 0x405
# AltGr
ISO_Level3_Shift 0xb8
#
# Top row
#
# `
grave 0x29
asciitilde 0x29 shift
# 1
exclam 0x2 shift
# 2
at 0x3 shift
ecaron 0x3 altgr
# 3
numbersign 0x4 shift
# 4
dollar 0x5 shift
# 5
percent 0x6 shift
# 6
asciicircum 0x7 shift
# 7
ampersand 0x8 shift
# 8
asterisk 0x9 shift
# 9
parenleft 0xa shift
# 0
parenright 0xb shift
# -
minus 0xc
underscore 0xc shift
# =
equal 0xd
plus 0xd shift
#
# QWERTZ first row
#
# q
q 0x10 altgr
# e
e 0x12 altgr
# [
bracketleft 0x1a
braceleft 0x1a shift
# ]
bracketright 0x1b
braceright 0x1b shift
#
# QWERTZ second row
#
# ;
semicolon 0x27
# ;
colon 0x27 shift
# '
apostrophe 0x28
# '
quotedbl 0x28 shift
#
# QWERTZ third row
#
# v
v 0x2f altgr
# ,
comma 0x33
less 0x33 shift
# .
period 0x34
greater 0x34 shift
# /
slash 0x35
question 0x35 shift
@@ -0,0 +1,120 @@
# generated from XKB map dk
include common
map 0x406
exclam 0x02 shift
exclamdown 0x02 altgr
onesuperior 0x02 shift altgr
quotedbl 0x03 shift
at 0x03 altgr
twosuperior 0x03 shift altgr
numbersign 0x04 shift
sterling 0x04 altgr
threesuperior 0x04 shift altgr
currency 0x05 shift
dollar 0x05 altgr
onequarter 0x05 shift altgr
percent 0x06 shift
onehalf 0x06 altgr
cent 0x06 shift altgr
ampersand 0x07 shift
yen 0x07 altgr
fiveeighths 0x07 shift altgr
slash 0x08 shift
braceleft 0x08 altgr
division 0x08 shift altgr
parenleft 0x09 shift
bracketleft 0x09 altgr
guillemotleft 0x09 shift altgr
parenright 0x0a shift
bracketright 0x0a altgr
guillemotright 0x0a shift altgr
equal 0x0b shift
braceright 0x0b altgr
degree 0x0b shift altgr
plus 0x0c
question 0x0c shift
plusminus 0x0c altgr
questiondown 0x0c shift altgr
dead_acute 0x0d
dead_grave 0x0d shift
bar 0x0d altgr
brokenbar 0x0d shift altgr
Greek_OMEGA 0x10 shift altgr
lstroke 0x11 altgr
Lstroke 0x11 shift altgr
EuroSign 0x12 altgr
cent 0x12 shift altgr
registered 0x13 altgr
thorn 0x14 altgr
THORN 0x14 shift altgr
leftarrow 0x15 altgr
yen 0x15 shift altgr
downarrow 0x16 altgr
uparrow 0x16 shift altgr
rightarrow 0x17 altgr
idotless 0x17 shift altgr
oe 0x18 altgr
OE 0x18 shift altgr
thorn 0x19 altgr
THORN 0x19 shift altgr
aring 0x1a
Aring 0x1a shift
dead_diaeresis 0x1a altgr
dead_abovering 0x1a shift altgr
dead_diaeresis 0x1b
dead_circumflex 0x1b shift
dead_tilde 0x1b altgr
dead_caron 0x1b shift altgr
ordfeminine 0x1e altgr
masculine 0x1e shift altgr
ssharp 0x1f altgr
section 0x1f shift altgr
eth 0x20 altgr
ETH 0x20 shift altgr
dstroke 0x21 altgr
ordfeminine 0x21 shift altgr
eng 0x22 altgr
ENG 0x22 shift altgr
hstroke 0x23 altgr
Hstroke 0x23 shift altgr
kra 0x25 altgr
lstroke 0x26 altgr
Lstroke 0x26 shift altgr
ae 0x27
AE 0x27 shift
oslash 0x28
Ooblique 0x28 shift
dead_caron 0x28 shift altgr
onehalf 0x29
section 0x29 shift
threequarters 0x29 altgr
paragraph 0x29 shift altgr
apostrophe 0x2b
asterisk 0x2b shift
dead_doubleacute 0x2b altgr
multiply 0x2b shift altgr
guillemotleft 0x2c altgr
guillemotright 0x2d altgr
copyright 0x2e altgr
leftdoublequotemark 0x2f altgr
grave 0x2f shift altgr
rightdoublequotemark 0x30 altgr
mu 0x32 altgr
masculine 0x32 shift altgr
comma 0x33
semicolon 0x33 shift
dead_cedilla 0x33 altgr
dead_ogonek 0x33 shift altgr
period 0x34
colon 0x34 shift
periodcentered 0x34 altgr
dead_abovedot 0x34 shift altgr
minus 0x35
underscore 0x35 shift
hyphen 0x35 altgr
macron 0x35 shift altgr
nobreakspace 0x39 altgr
less 0x56
greater 0x56 shift
backslash 0x56 altgr
notsign 0x56 shift altgr
@@ -0,0 +1,114 @@
# generated from XKB map de
include common
map 0x407
exclam 0x02 shift
onesuperior 0x02 altgr
exclamdown 0x02 shift altgr
quotedbl 0x03 shift
twosuperior 0x03 altgr
oneeighth 0x03 shift altgr
section 0x04 shift
threesuperior 0x04 altgr
sterling 0x04 shift altgr
dollar 0x05 shift
onequarter 0x05 altgr
currency 0x05 shift altgr
percent 0x06 shift
onehalf 0x06 altgr
threeeighths 0x06 shift altgr
ampersand 0x07 shift
threequarters 0x07 altgr
fiveeighths 0x07 shift altgr
slash 0x08 shift
braceleft 0x08 altgr
seveneighths 0x08 shift altgr
parenleft 0x09 shift
bracketleft 0x09 altgr
trademark 0x09 shift altgr
parenright 0x0a shift
bracketright 0x0a altgr
plusminus 0x0a shift altgr
equal 0x0b shift
braceright 0x0b altgr
ssharp 0x0c
question 0x0c shift
backslash 0x0c altgr
questiondown 0x0c shift altgr
acute 0x0d
dead_acute 0x0d
grave 0x0d shift
dead_grave 0x0d shift
dead_cedilla 0x0d altgr
dead_ogonek 0x0d shift altgr
at 0x10 altgr
Greek_OMEGA 0x10 shift altgr
EuroSign 0x12 altgr
paragraph 0x13 altgr
registered 0x13 shift altgr
tslash 0x14 altgr
Tslash 0x14 shift altgr
z 0x15 addupper
leftarrow 0x15 altgr
yen 0x15 shift altgr
downarrow 0x16 altgr
uparrow 0x16 shift altgr
rightarrow 0x17 altgr
idotless 0x17 shift altgr
oslash 0x18 altgr
Ooblique 0x18 shift altgr
thorn 0x19 altgr
THORN 0x19 shift altgr
udiaeresis 0x1a
Udiaeresis 0x1a shift
dead_diaeresis 0x1a altgr
dead_abovering 0x1a shift altgr
plus 0x1b
asterisk 0x1b shift
asciitilde 0x1b altgr
dead_tilde 0x1b altgr
dead_macron 0x1b shift altgr
ae 0x1e altgr
AE 0x1e shift altgr
eth 0x20 altgr
ETH 0x20 shift altgr
dstroke 0x21 altgr
ordfeminine 0x21 shift altgr
eng 0x22 altgr
ENG 0x22 shift altgr
hstroke 0x23 altgr
Hstroke 0x23 shift altgr
kra 0x25 altgr
odiaeresis 0x27
Odiaeresis 0x27 shift
dead_doubleacute 0x27 altgr
adiaeresis 0x28
Adiaeresis 0x28 shift
dead_caron 0x28 shift altgr
asciicircum 0x29
dead_circumflex 0x29
degree 0x29 shift
notsign 0x29 altgr
numbersign 0x2b
apostrophe 0x2b shift
dead_breve 0x2b shift altgr
y 0x2c addupper
guillemotleft 0x2c altgr
guillemotright 0x2d altgr
cent 0x2e altgr
copyright 0x2e shift altgr
leftdoublequotemark 0x2f altgr
rightdoublequotemark 0x30 altgr
mu 0x32 altgr
masculine 0x32 shift altgr
comma 0x33
semicolon 0x33 shift
horizconnector 0x33 altgr
multiply 0x33 shift altgr
period 0x34
colon 0x34 shift
periodcentered 0x34 altgr
division 0x34 shift altgr
minus 0x35
underscore 0x35 shift
dead_belowdot 0x35 altgr
dead_abovedot 0x35 shift altgr
@@ -0,0 +1,169 @@
# rdesktop Swiss-German (de-ch) keymap file
# 2003-06-03 by [email protected]
#
include common
map 0x00000807
#
# Scan Code 1
section 0x29
degree 0x29 shift
notsign 0x29 altgr inhibit
#
# Scan Code 2
plus 0x2 shift
brokenbar 0x02 altgr
#
# Scan Code 3
quotedbl 0x03 shift
at 0x03 altgr
#
# Scan Code 4
asterisk 0x04 shift
numbersign 0x04 altgr
#
# Scan Code 5
ccedilla 0x05 shift
onequarter 0x05 altgr inhibit
#
# Scan Code 6
percent 0x06 shift
onehalf 0x06 altgr inhibit
#
# Scan Code 7
ampersand 0x07 shift
notsign 0x07 altgr
#
# Scan Code 8
slash 0x08 shift
bar 0x08 altgr
#
# Scan Code 9
parenleft 0x09 shift
cent 0x09 altgr
#
# Scan Code 10
parenright 0x0a shift
#
# Scan Code 11
equal 0x0b shift
braceright 0x0b altgr inhibit
#
# Scan Code 12
apostrophe 0x0c
question 0x0c shift
dead_acute 0x0c altgr
#
# Scan Code 13
dead_circumflex 0x0d
dead_grave 0x0d shift
dead_tilde 0x0d altgr
#
# Scan Code 19
EuroSign 0x12 altgr
#
# Scan Code 22
z 0x15 addupper
#
# Scan Code 27
udiaeresis 0x1a
egrave 0x1a shift
bracketleft 0x1a altgr
#
# Scan Code 28
dead_diaeresis 0x1b
exclam 0x1b shift
bracketright 0x1b altgr
#
# Scan Code 40
odiaeresis 0x27
eacute 0x27 shift
#
# Scan Code 41
adiaeresis 0x28
agrave 0x28 shift
braceleft 0x28 altgr
#
# Scan Code 42 (only on international keyboards)
dollar 0x2b
sterling 0x2b shift
braceright 0x2b altgr
#
# Scan Code 45 (only on international keyboards)
backslash 0x56 altgr
#
# Scan Code 46
y 0x2c addupper
#
# Scan Code 53
comma 0x33
semicolon 0x33 shift
#
# Scan Code 54
period 0x34
colon 0x34 shift
#
# Scan Code 55
minus 0x35
underscore 0x35 shift
#
# Suppress Windows unsupported AltGr keys
#
# Scan Code 17
paragraph 0x10 altgr inhibit
#
# Scan Code 21
tslash 0x14 altgr inhibit
#
# Scan Code 22
leftarrow 0x15 altgr inhibit
#
# Scan Code 23
downarrow 0x16 altgr inhibit
#
# Scan Code 24
rightarrow 0x17 altgr inhibit
#
# Scan Code 25
oslash 0x18 altgr inhibit
#
# Scan Code 26
thorn 0x19 altgr inhibit
#
# Scan Code 31
ae 0x1e altgr inhibit
#
# Scan Code 32
ssharp 0x1f altgr inhibit
#
# Scan Code 33
eth 0x20 altgr inhibit
#
# Scan Code 34
dstroke 0x21 altgr inhibit
#
# Scan Code 35
eng 0x22 altgr inhibit
#
# Scan Code 36
hstroke 0x23 altgr inhibit
#
# Scan Code 38
kra 0x25 altgr inhibit
#
# Scan Code 39
lstroke 0x26 altgr inhibit
#
# Scan Code 46
guillemotleft 0x2c altgr inhibit
#
# Scan Code 47
guillemotright 0x2d altgr inhibit
#
# Scan Code 49
leftdoublequotemark 0x2f altgr inhibit
#
# Scan Code 50
rightdoublequotemark 0x30 altgr inhibit
#
# Scan Code 52
mu 0x32 altgr inhibit
@@ -0,0 +1,216 @@
# American Dvorak
map 0x10409
# Note: we are not including the common section
include modifiers
#
# Top row
#
1 0x2
2 0x3
3 0x4
4 0x5
5 0x6
6 0x7
7 0x8
8 0x9
9 0xa
0 0xb
BackSpace 0xe
#
# QWERTY first row
# QWERTY:
# q w e r t y u i o p
# Dvorak:
# ' , . p y f g c r l
Tab 0xf localstate
ISO_Left_Tab 0xf shift
q 0x2d addupper
w 0x33 addupper
e 0x20 addupper
r 0x18 addupper
t 0x25 addupper
y 0x14 addupper
u 0x21 addupper
i 0x22 addupper
o 0x1f addupper
p 0x13 addupper
#
# QWERTY second row
# QUERTY:
# a s d f g h j k l
# Dvorak:
# a o e u i d h t n
a 0x1e addupper
s 0x27 addupper
d 0x23 addupper
f 0x15 addupper
g 0x16 addupper
h 0x24 addupper
j 0x2e addupper
k 0x2f addupper
l 0x19 addupper
Return 0x1c localstate
#
# QWERTY third row
# QUERTY:
# z x c v b n m
# Dvorak:
# ; q j k x b m
z 0x35 addupper
x 0x30 addupper
c 0x17 addupper
v 0x34 addupper
b 0x31 addupper
n 0x26 addupper
m 0x32 addupper
space 0x39 localstate
less 0x56
greater 0x56 shift
bar 0x56 altgr
brokenbar 0x56 shift altgr
#
# Esc and Function keys
#
Escape 0x1 localstate
F1 0x3b localstate
F2 0x3c localstate
F3 0x3d localstate
F4 0x3e localstate
F5 0x3f localstate
F6 0x40 localstate
F7 0x41 localstate
F8 0x42 localstate
F9 0x43 localstate
F10 0x44 localstate
F11 0x57 localstate
SunF36 0x57 localstate
F12 0x58 localstate
SunF37 0x58 localstate
# Printscreen, Scrollock and Pause
# Printscreen really requires four scancodes (0xe0, 0x2a, 0xe0, 0x37),
# but (0xe0, 0x37) seems to work.
Print 0xb7 localstate
Sys_Req 0xb7 localstate
Execute 0xb7 localstate
F22 0xb7 localstate
Scroll_Lock 0x46
F23 0x46
#
# Insert - PgDown
#
Insert 0xd2 localstate
Delete 0xd3 localstate
Home 0xc7 localstate
End 0xcf localstate
Page_Up 0xc9 localstate
Page_Down 0xd1 localstate
#
# Arrow keys
#
Left 0xcb localstate
Up 0xc8 localstate
Down 0xd0 localstate
Right 0xcd localstate
#
# Numpad
#
Num_Lock 0x45
KP_Divide 0xb5
KP_Multiply 0x37
KP_Subtract 0x4a
KP_Add 0x4e
KP_Enter 0x9c
KP_Decimal 0x53 numlock
KP_Separator 0x53 numlock
KP_Delete 0x53
KP_0 0x52 numlock
KP_Insert 0x52
KP_1 0x4f numlock
KP_End 0x4f
KP_2 0x50 numlock
KP_Down 0x50
KP_3 0x51 numlock
KP_Next 0x51
KP_4 0x4b numlock
KP_Left 0x4b
KP_5 0x4c numlock
KP_Begin 0x4c
KP_6 0x4d numlock
KP_Right 0x4d
KP_7 0x47 numlock
KP_Home 0x47
KP_8 0x48 numlock
KP_Up 0x48
KP_9 0x49 numlock
KP_Prior 0x49
#
# Inhibited keys
#
Caps_Lock 0x0 inhibit
Multi_key 0x0 inhibit
exclam 0x02 shift
at 0x03 shift
numbersign 0x04 shift
dollar 0x05 shift
percent 0x06 shift
asciicircum 0x07 shift
ampersand 0x08 shift
asterisk 0x09 shift
parenleft 0x0a shift
parenright 0x0b shift
minus 0x28
underscore 0x28 shift
equal 0x1b
plus 0x1b shift
bracketleft 0x0c
braceleft 0x0c shift
bracketright 0x0d
braceright 0x0d shift
semicolon 0x2c
colon 0x2c shift
apostrophe 0x10
quotedbl 0x10 shift
grave 0x29
asciitilde 0x29 shift
backslash 0x2b
bar 0x2b shift
comma 0x11
less 0x11 shift
period 0x12
greater 0x12 shift
slash 0x1a
question 0x1a shift
@@ -0,0 +1,119 @@
# generated from XKB map gb
include common
map 0x809
exclam 0x02 shift
onesuperior 0x02 altgr
exclamdown 0x02 shift altgr
quotedbl 0x03 shift
twosuperior 0x03 altgr
oneeighth 0x03 shift altgr
sterling 0x04 shift
threesuperior 0x04 altgr
dollar 0x05 shift
EuroSign 0x05 altgr
percent 0x06 shift
onehalf 0x06 altgr
threeeighths 0x06 shift altgr
asciicircum 0x07 shift
threequarters 0x07 altgr
fiveeighths 0x07 shift altgr
ampersand 0x08 shift
braceleft 0x08 altgr
seveneighths 0x08 shift altgr
asterisk 0x09 shift
bracketleft 0x09 altgr
trademark 0x09 shift altgr
parenleft 0x0a shift
bracketright 0x0a altgr
plusminus 0x0a shift altgr
parenright 0x0b shift
braceright 0x0b altgr
degree 0x0b shift altgr
minus 0x0c
underscore 0x0c shift
backslash 0x0c altgr
questiondown 0x0c shift altgr
equal 0x0d
plus 0x0d shift
dead_cedilla 0x0d altgr
dead_ogonek 0x0d shift altgr
at 0x10 altgr
Greek_OMEGA 0x10 shift altgr
lstroke 0x11 altgr
Lstroke 0x11 shift altgr
paragraph 0x13 altgr
registered 0x13 shift altgr
tslash 0x14 altgr
Tslash 0x14 shift altgr
leftarrow 0x15 altgr
yen 0x15 shift altgr
downarrow 0x16 altgr
uparrow 0x16 shift altgr
rightarrow 0x17 altgr
idotless 0x17 shift altgr
oslash 0x18 altgr
Ooblique 0x18 shift altgr
thorn 0x19 altgr
THORN 0x19 shift altgr
bracketleft 0x1a
braceleft 0x1a shift
dead_diaeresis 0x1a altgr
dead_abovering 0x1a shift altgr
bracketright 0x1b
braceright 0x1b shift
dead_tilde 0x1b altgr
dead_macron 0x1b shift altgr
ae 0x1e altgr
AE 0x1e shift altgr
ssharp 0x1f altgr
section 0x1f shift altgr
eth 0x20 altgr
ETH 0x20 shift altgr
dstroke 0x21 altgr
ordfeminine 0x21 shift altgr
eng 0x22 altgr
ENG 0x22 shift altgr
hstroke 0x23 altgr
Hstroke 0x23 shift altgr
kra 0x25 altgr
lstroke 0x26 altgr
Lstroke 0x26 shift altgr
semicolon 0x27
colon 0x27 shift
dead_acute 0x27 altgr
dead_doubleacute 0x27 shift altgr
apostrophe 0x28
at 0x28 shift
dead_circumflex 0x28 altgr
dead_caron 0x28 shift altgr
grave 0x29
notsign 0x29 shift
bar 0x29 altgr
numbersign 0x2b
asciitilde 0x2b shift
dead_grave 0x2b altgr
dead_breve 0x2b shift altgr
guillemotleft 0x2c altgr
less 0x2c shift altgr
guillemotright 0x2d altgr
greater 0x2d shift altgr
cent 0x2e altgr
copyright 0x2e shift altgr
leftdoublequotemark 0x2f altgr
rightdoublequotemark 0x30 altgr
mu 0x32 altgr
masculine 0x32 shift altgr
comma 0x33
less 0x33 shift
horizconnector 0x33 altgr
multiply 0x33 shift altgr
period 0x34
greater 0x34 shift
periodcentered 0x34 altgr
division 0x34 shift altgr
slash 0x35
question 0x35 shift
dead_belowdot 0x35 altgr
dead_abovedot 0x35 shift altgr
backslash 0x56
bar 0x56 shift
@@ -0,0 +1,35 @@
# generated from XKB map us
include common
map 0x409
exclam 0x02 shift
at 0x03 shift
numbersign 0x04 shift
dollar 0x05 shift
percent 0x06 shift
asciicircum 0x07 shift
ampersand 0x08 shift
asterisk 0x09 shift
parenleft 0x0a shift
parenright 0x0b shift
minus 0x0c
underscore 0x0c shift
equal 0x0d
plus 0x0d shift
bracketleft 0x1a
braceleft 0x1a shift
bracketright 0x1b
braceright 0x1b shift
semicolon 0x27
colon 0x27 shift
apostrophe 0x28
quotedbl 0x28 shift
grave 0x29
asciitilde 0x29 shift
backslash 0x2b
bar 0x2b shift
comma 0x33
less 0x33 shift
period 0x34
greater 0x34 shift
slash 0x35
question 0x35 shift
@@ -0,0 +1,105 @@
# generated from XKB map es
include common
map 0x40a
exclam 0x02 shift
bar 0x02 altgr
quotedbl 0x03 shift
at 0x03 altgr
oneeighth 0x03 shift altgr
periodcentered 0x04 shift
numbersign 0x04 altgr
sterling 0x04 shift altgr
dollar 0x05 shift
asciitilde 0x05 altgr
percent 0x06 shift
onehalf 0x06 altgr
threeeighths 0x06 shift altgr
ampersand 0x07 shift
notsign 0x07 altgr
fiveeighths 0x07 shift altgr
slash 0x08 shift
seveneighths 0x08 shift altgr
parenleft 0x09 shift
trademark 0x09 shift altgr
parenright 0x0a shift
plusminus 0x0a shift altgr
equal 0x0b shift
degree 0x0b shift altgr
apostrophe 0x0c
question 0x0c shift
exclamdown 0x0d
questiondown 0x0d shift
Greek_OMEGA 0x10 shift altgr
lstroke 0x11 altgr
Lstroke 0x11 shift altgr
EuroSign 0x12 altgr
paragraph 0x13 altgr
registered 0x13 shift altgr
tslash 0x14 altgr
Tslash 0x14 shift altgr
leftarrow 0x15 altgr
yen 0x15 shift altgr
downarrow 0x16 altgr
uparrow 0x16 shift altgr
rightarrow 0x17 altgr
idotless 0x17 shift altgr
oslash 0x18 altgr
Ooblique 0x18 shift altgr
thorn 0x19 altgr
THORN 0x19 shift altgr
dead_grave 0x1a
dead_circumflex 0x1a shift
bracketleft 0x1a altgr
dead_abovering 0x1a shift altgr
plus 0x1b
asterisk 0x1b shift
bracketright 0x1b altgr
dead_macron 0x1b shift altgr
ae 0x1e altgr
AE 0x1e shift altgr
ssharp 0x1f altgr
section 0x1f shift altgr
eth 0x20 altgr
ETH 0x20 shift altgr
dstroke 0x21 altgr
eng 0x22 altgr
ENG 0x22 shift altgr
hstroke 0x23 altgr
Hstroke 0x23 shift altgr
kra 0x25 altgr
lstroke 0x26 altgr
Lstroke 0x26 shift altgr
ntilde 0x27
Ntilde 0x27 shift
dead_doubleacute 0x27 shift altgr
dead_acute 0x28
dead_diaeresis 0x28 shift
braceleft 0x28 altgr
masculine 0x29
ordfeminine 0x29 shift
backslash 0x29 altgr
ccedilla 0x2b
Ccedilla 0x2b shift
braceright 0x2b altgr
dead_breve 0x2b shift altgr
guillemotleft 0x2c altgr
less 0x56
greater 0x56 shift
guillemotright 0x2d altgr
cent 0x2e altgr
copyright 0x2e shift altgr
leftdoublequotemark 0x2f altgr
grave 0x2f shift altgr
rightdoublequotemark 0x30 altgr
mu 0x32 altgr
comma 0x33
semicolon 0x33 shift
horizconnector 0x33 altgr
multiply 0x33 shift altgr
period 0x34
colon 0x34 shift
division 0x34 shift altgr
minus 0x35
underscore 0x35 shift
dead_belowdot 0x35 altgr
dead_abovedot 0x35 shift altgr
@@ -0,0 +1,86 @@
map 0x00000425
include common
#
# Top row
#
dead_caron 0x29
dead_tilde 0x29 shift
# 1
exclam 0x2 shift
# 2
quotedbl 0x3 shift
at 0x3 altgr
# 3
numbersign 0x4 shift
sterling 0x4 altgr
# 4
currency 0x5 shift
dollar 0x5 altgr
# 5
percent 0x6 shift
# 6
ampersand 0x7 shift
# 7
slash 0x8 shift
braceleft 0x8 altgr
# 8
parenleft 0x9 shift
bracketleft 0x9 altgr
# 9
parenright 0xa shift
bracketright 0xa altgr
# 0
equal 0xb shift
braceright 0xb altgr
plus 0xc
question 0xc shift
backslash 0xc altgr
acute 0xd
dead_acute 0xd
grave 0xd shift
dead_grave 0xd shift
#
# QWERTY first row
#
EuroSign 0x12 altgr
udiaeresis 0x1a
Udiaeresis 0x1a shift
otilde 0x1b
Otilde 0x1b shift
section 0x1b altgr
#
# QWERTY second row
#
scaron 0x1f altgr
Scaron 0x1f altgr shift
odiaeresis 0x27
Odiaeresis 0x27 shift
adiaeresis 0x28
Adiaeresis 0x28 shift
asciicircum 0x28 altgr
apostrophe 0x2b
asterisk 0x2b shift
onehalf 0x2b altgr
#
# QWERTY third row
#
less 0x56
greater 0x56 shift
bar 0x56 altgr
zcaron 0x2c altgr
Zcaron 0x2c altgr shift
comma 0x33
semicolon 0x33 shift
period 0x34
colon 0x34 shift
minus 0x35
underscore 0x35 shift
@@ -0,0 +1,122 @@
# Finnish keyboard layout
# Originally generated from XKB map se_FI (wrong!), modified afterwards.
include common
map 0x40b
exclam 0x02 shift
exclamdown 0x02 altgr
onesuperior 0x02 shift altgr
quotedbl 0x03 shift
at 0x03 altgr
twosuperior 0x03 shift altgr
numbersign 0x04 shift
sterling 0x04 altgr
threesuperior 0x04 shift altgr
currency 0x05 shift
dollar 0x05 altgr
onequarter 0x05 shift altgr
percent 0x06 shift
onehalf 0x06 altgr
cent 0x06 shift altgr
ampersand 0x07 shift
yen 0x07 altgr
fiveeighths 0x07 shift altgr
slash 0x08 shift
braceleft 0x08 altgr
division 0x08 shift altgr
parenleft 0x09 shift
bracketleft 0x09 altgr
guillemotleft 0x09 shift altgr
parenright 0x0a shift
bracketright 0x0a altgr
guillemotright 0x0a shift altgr
equal 0x0b shift
braceright 0x0b altgr
degree 0x0b shift altgr
plus 0x0c
question 0x0c shift
backslash 0x0c altgr
questiondown 0x0c shift altgr
dead_acute 0x0d
dead_grave 0x0d shift
plusminus 0x0d altgr
notsign 0x0d shift altgr
Greek_OMEGA 0x10 shift altgr
lstroke 0x11 altgr
Lstroke 0x11 shift altgr
EuroSign 0x12 altgr
cent 0x12 shift altgr
registered 0x13 altgr
thorn 0x14 altgr
THORN 0x14 shift altgr
leftarrow 0x15 altgr
yen 0x15 shift altgr
downarrow 0x16 altgr
uparrow 0x16 shift altgr
rightarrow 0x17 altgr
idotless 0x17 shift altgr
oe 0x18 altgr
OE 0x18 shift altgr
thorn 0x19 altgr
THORN 0x19 shift altgr
aring 0x1a
Aring 0x1a shift
dead_diaeresis 0x1a altgr
dead_abovering 0x1a shift altgr
dead_diaeresis 0x1b
dead_circumflex 0x1b shift
dead_tilde 0x1b altgr
dead_caron 0x1b shift altgr
ordfeminine 0x1e altgr
masculine 0x1e shift altgr
ssharp 0x1f altgr
section 0x1f shift altgr
eth 0x20 altgr
ETH 0x20 shift altgr
dstroke 0x21 altgr
ordfeminine 0x21 shift altgr
eng 0x22 altgr
ENG 0x22 shift altgr
hstroke 0x23 altgr
Hstroke 0x23 shift altgr
kra 0x25 altgr
lstroke 0x26 altgr
Lstroke 0x26 shift altgr
odiaeresis 0x27
Odiaeresis 0x27 shift
oslash 0x27 altgr
Ooblique 0x27 shift altgr
adiaeresis 0x28
Adiaeresis 0x28 shift
ae 0x28 altgr
AE 0x28 shift altgr
section 0x29
onehalf 0x29 shift
paragraph 0x29 altgr
threequarters 0x29 shift altgr
apostrophe 0x2b
asterisk 0x2b shift
acute 0x2b altgr
multiply 0x2b shift altgr
guillemotleft 0x2c altgr
guillemotright 0x2d altgr
copyright 0x2e altgr
leftdoublequotemark 0x2f altgr
grave 0x2f shift altgr
rightdoublequotemark 0x30 altgr
mu 0x32 altgr
masculine 0x32 shift altgr
comma 0x33
semicolon 0x33 shift
dead_cedilla 0x33 altgr
dead_ogonek 0x33 shift altgr
period 0x34
colon 0x34 shift
periodcentered 0x34 altgr
dead_abovedot 0x34 shift altgr
minus 0x35
underscore 0x35 shift
hyphen 0x35 altgr
macron 0x35 shift altgr
nobreakspace 0x39 altgr
@@ -0,0 +1,77 @@
map 0x438
include common
#
# Top row
#
onehalf 0x29
section 0x29 shift
# 1
exclam 0x2 shift
# 2
quotedbl 0x3 shift
at 0x3 altgr
# 3
numbersign 0x4 shift
sterling 0x4 altgr
# 4
currency 0x5 shift
dollar 0x5 altgr
# 5
percent 0x6 shift
# 6
ampersand 0x7 shift
# 7
slash 0x8 shift
braceleft 0x8 altgr
# 8
parenleft 0x9 shift
bracketleft 0x9 altgr
# 9
parenright 0xa shift
bracketright 0xa altgr
# 0
equal 0xb shift
braceright 0xb altgr
plus 0xc
question 0xc shift
plusminus 0xc altgr
bar 0xd altgr
dead_acute 0xd
#
# QWERTY first row
#
EuroSign 0x12 altgr
aring 0x1a
Aring 0x1a shift
eth 0x1b addupper
asciitilde 0x1b altgr
#
# QWERTY second row
#
ae 0x27 addupper
oslash 0x28
Ooblique 0x28 shift
apostrophe 0x2b
asterisk 0x2b shift
#
# QWERTY third row
#
less 0x56
greater 0x56 shift
backslash 0x56 altgr
comma 0x33
semicolon 0x33 shift
period 0x34
colon 0x34 shift
minus 0x35
underscore 0x35 shift
@@ -0,0 +1,181 @@
include common
map 0x40c
#
# Top row
#
twosuperior 0x29
notsign 0x29 altgr
ampersand 0x02
1 0x02 shift
onesuperior 0x02 altgr
exclamdown 0x02 shift altgr
eacute 0x03
2 0x03 shift
asciitilde 0x03 altgr
oneeighth 0x03 shift altgr
quotedbl 0x04
3 0x04 shift
numbersign 0x04 altgr
apostrophe 0x05
4 0x05 shift
braceleft 0x05 altgr
parenleft 0x06
5 0x06 shift
bracketleft 0x06 altgr
threeeighths 0x06 shift altgr
minus 0x07
6 0x07 shift
bar 0x07 altgr
fiveeighths 0x07 shift altgr
egrave 0x08
7 0x08 shift
grave 0x08 altgr
seveneighths 0x08 shift altgr
underscore 0x09
8 0x09 shift
backslash 0x09 altgr
trademark 0x09 shift altgr
ccedilla 0x0a
9 0x0a shift
asciicircum 0x0a altgr
plusminus 0x0a shift altgr
agrave 0x0b
0 0x0b shift
at 0x0b altgr
parenright 0x0c
degree 0x0c shift
bracketright 0x0c altgr
questiondown 0x0c shift altgr
equal 0x0d
plus 0x0d shift
braceright 0x0d altgr
dead_ogonek 0x0d shift altgr
#
# AZERTY first row
#
a 0x10 addupper
ae 0x10 altgr
AE 0x10 shift altgr
z 0x11 addupper
guillemotleft 0x11 altgr
EuroSign 0x12 altgr
paragraph 0x13 altgr
registered 0x13 shift altgr
tslash 0x14 altgr
Tslash 0x14 shift altgr
leftarrow 0x15 altgr
yen 0x15 shift altgr
downarrow 0x16 altgr
uparrow 0x16 shift altgr
rightarrow 0x17 altgr
idotless 0x17 shift altgr
oslash 0x18 altgr
Ooblique 0x18 shift altgr
thorn 0x19 altgr
THORN 0x19 shift altgr
dead_circumflex 0x1a
dead_diaeresis 0x1a shift
dead_abovering 0x1a shift altgr
dollar 0x1b
sterling 0x1b shift
currency 0x1b altgr
dead_macron 0x1b shift altgr
#
# AZERTY second row
#
q 0x1e addupper
Greek_OMEGA 0x1e shift altgr
ssharp 0x1f altgr
eth 0x20 altgr
ETH 0x20 shift altgr
dstroke 0x21 altgr
ordfeminine 0x21 shift altgr
eng 0x22 altgr
ENG 0x22 shift altgr
hstroke 0x23 altgr
Hstroke 0x23 shift altgr
kra 0x25 altgr
lstroke 0x26 altgr
Lstroke 0x26 shift altgr
m 0x27 addupper
masculine 0x27 shift altgr
ugrave 0x28
percent 0x28 shift
dead_caron 0x28 shift altgr
asterisk 0x2b
mu 0x2b shift
dead_grave 0x2b altgr
dead_breve 0x2b shift altgr
#
# AZERTY third row
#
less 0x56
greater 0x56 shift
w 0x2c addupper
guillemotright 0x2d altgr
cent 0x2e altgr
copyright 0x2e shift altgr
leftdoublequotemark 0x2f altgr
rightdoublequotemark 0x30 altgr
comma 0x32
question 0x32 shift
dead_acute 0x32 altgr
dead_doubleacute 0x32 shift altgr
semicolon 0x33
period 0x33 shift
horizconnector 0x33 altgr
multiply 0x33 shift altgr
colon 0x34
slash 0x34 shift
periodcentered 0x34 altgr
division 0x34 shift altgr
exclam 0x35
section 0x35 shift
dead_belowdot 0x35 altgr
dead_abovedot 0x35 shift altgr
@@ -0,0 +1,135 @@
# generated from XKB map be
include common
map 0x80c
ampersand 0x02
1 0x02 shift
bar 0x02 altgr
exclamdown 0x02 shift altgr
eacute 0x03
2 0x03 shift
at 0x03 altgr
oneeighth 0x03 shift altgr
quotedbl 0x04
3 0x04 shift
numbersign 0x04 altgr
sterling 0x04 shift altgr
apostrophe 0x05
4 0x05 shift
onequarter 0x05 altgr
dollar 0x05 shift altgr
parenleft 0x06
5 0x06 shift
onehalf 0x06 altgr
threeeighths 0x06 shift altgr
section 0x07
6 0x07 shift
asciicircum 0x07 altgr
fiveeighths 0x07 shift altgr
egrave 0x08
7 0x08 shift
braceleft 0x08 altgr
seveneighths 0x08 shift altgr
exclam 0x09
8 0x09 shift
bracketleft 0x09 altgr
trademark 0x09 shift altgr
ccedilla 0x0a
9 0x0a shift
braceleft 0x0a altgr
plusminus 0x0a shift altgr
agrave 0x0b
0 0x0b shift
braceright 0x0b altgr
degree 0x0b shift altgr
parenright 0x0c
degree 0x0c shift
backslash 0x0c altgr
questiondown 0x0c shift altgr
minus 0x0d
underscore 0x0d shift
dead_cedilla 0x0d altgr
dead_ogonek 0x0d shift altgr
a 0x10 addupper
Greek_OMEGA 0x10 shift altgr
z 0x11 addupper
lstroke 0x11 altgr
Lstroke 0x11 shift altgr
EuroSign 0x12 altgr
cent 0x12 shift altgr
paragraph 0x13 altgr
registered 0x13 shift altgr
tslash 0x14 altgr
Tslash 0x14 shift altgr
leftarrow 0x15 altgr
yen 0x15 shift altgr
downarrow 0x16 altgr
uparrow 0x16 shift altgr
rightarrow 0x17 altgr
idotless 0x17 shift altgr
oslash 0x18 altgr
Ooblique 0x18 shift altgr
thorn 0x19 altgr
THORN 0x19 shift altgr
dead_circumflex 0x1a
dead_diaeresis 0x1a shift
bracketleft 0x1a altgr
dead_abovering 0x1a shift altgr
dollar 0x1b
asterisk 0x1b shift
bracketright 0x1b altgr
dead_macron 0x1b shift altgr
q 0x1e addupper
ae 0x1e altgr
AE 0x1e shift altgr
ssharp 0x1f altgr
eth 0x20 altgr
ETH 0x20 shift altgr
dstroke 0x21 altgr
ordfeminine 0x21 shift altgr
eng 0x22 altgr
ENG 0x22 shift altgr
hstroke 0x23 altgr
Hstroke 0x23 shift altgr
kra 0x25 altgr
lstroke 0x26 altgr
Lstroke 0x26 shift altgr
m 0x27 addupper
dead_acute 0x27 altgr
dead_doubleacute 0x27 shift altgr
ugrave 0x28
percent 0x28 shift
dead_acute 0x28 altgr
dead_caron 0x28 shift altgr
twosuperior 0x29
threesuperior 0x29 shift
notsign 0x29 altgr
mu 0x2b
sterling 0x2b shift
dead_grave 0x2b altgr
dead_breve 0x2b shift altgr
w 0x2c addupper
guillemotleft 0x2c altgr
guillemotright 0x2d altgr
cent 0x2e altgr
copyright 0x2e shift altgr
leftdoublequotemark 0x2f altgr
grave 0x2f shift altgr
rightdoublequotemark 0x30 altgr
comma 0x32
question 0x32 shift
dead_cedilla 0x32 altgr
masculine 0x32 shift altgr
semicolon 0x33
period 0x33 shift
horizconnector 0x33 altgr
multiply 0x33 shift altgr
colon 0x34
slash 0x34 shift
periodcentered 0x34 altgr
division 0x34 shift altgr
equal 0x35
plus 0x35 shift
dead_tilde 0x35 altgr
dead_abovedot 0x35 shift altgr
backslash 0x56 altgr
@@ -0,0 +1,50 @@
# Canadian French
# By Simon Germain
include common
map 0xc0c
backslash 0x29 altgr
plusminus 0x2 altgr
at 0x3 altgr
sterling 0x4 altgr
cent 0x5 altgr
currency 0x6 altgr
notsign 0x7 altgr
bar 0x29 shift
twosuperior 0x9 altgr
threesuperior 0xa altgr
onequarter 0xb altgr
onehalf 0xc altgr
threequarters 0xd altgr
section 0x18 altgr
paragraph 0x19 altgr
bracketleft 0x1a altgr
bracketright 0x1b altgr
asciitilde 0x27 altgr
braceleft 0x28 altgr
braceright 0x2b altgr
less 0x2b
greater 0x2b shift
guillemotleft 0x56
guillemotright 0x56 shift
degree 0x56 altgr
mu 0x32 altgr
eacute 0x35
dead_acute 0x35 altgr
dead_grave 0x28
dead_circumflex 0x1a
dead_circumflex 0x1a shift
dead_cedilla 0x1b
dead_diaeresis 0x1b shift
exclam 0x2 shift
quotedbl 0x3 shift
slash 0x4 shift
dollar 0x5 shift
percent 0x6 shift
question 0x7 shift
ampersand 0x8 shift
asterisk 0x9 shift
parenleft 0xa shift
parenright 0xb shift
underscore 0xc shift
plus 0xd shift
@@ -0,0 +1,169 @@
# rdesktop suisse-french keymap file
#
#map 0x00000807
map 0x0000100C
include common
#
# Scan Code 1
section 0x29
degree 0x29 shift
notsign 0x29 altgr inhibit
#
# Scan Code 2
plus 0x2 shift
brokenbar 0x02 altgr
#
# Scan Code 3
quotedbl 0x03 shift
at 0x03 altgr
#
# Scan Code 4
asterisk 0x04 shift
numbersign 0x04 altgr
#
# Scan Code 5
ccedilla 0x05 shift
onequarter 0x05 altgr inhibit
#
# Scan Code 6
percent 0x06 shift
onehalf 0x06 altgr inhibit
#
# Scan Code 7
ampersand 0x07 shift
notsign 0x07 altgr
#
# Scan Code 8
slash 0x08 shift
bar 0x08 altgr
#
# Scan Code 9
parenleft 0x09 shift
cent 0x09 altgr
#
# Scan Code 10
parenright 0x0a shift
#
# Scan Code 11
equal 0x0b shift
braceright 0x0b altgr inhibit
#
# Scan Code 12
apostrophe 0x0c
question 0x0c shift
dead_acute 0x0c altgr
#
# Scan Code 13
dead_circumflex 0x0d
dead_grave 0x0d shift
dead_tilde 0x0d altgr
#
# Scan Code 19
EuroSign 0x12 altgr
#
# Scan Code 22
z 0x15 addupper
#
# Scan Code 27
udiaeresis 0x1a shift
egrave 0x1a
bracketleft 0x1a altgr
#
# Scan Code 28
dead_diaeresis 0x1b
exclam 0x1b shift
bracketright 0x1b altgr
#
# Scan Code 40
odiaeresis 0x27 shift
eacute 0x27
#
# Scan Code 41
adiaeresis 0x28 shift
agrave 0x28
braceleft 0x28 altgr
#
# Scan Code 42 (only on international keyboards)
dollar 0x2b
sterling 0x2b shift
braceright 0x2b altgr
#
# Scan Code 45 (only on international keyboards)
backslash 0x56 altgr
#
# Scan Code 46
y 0x2c addupper
#
# Scan Code 53
comma 0x33
semicolon 0x33 shift
#
# Scan Code 54
period 0x34
colon 0x34 shift
#
# Scan Code 55
minus 0x35
underscore 0x35 shift
#
# Suppress Windows unsupported AltGr keys
#
# Scan Code 17
paragraph 0x10 altgr inhibit
#
# Scan Code 21
tslash 0x14 altgr inhibit
#
# Scan Code 22
leftarrow 0x15 altgr inhibit
#
# Scan Code 23
downarrow 0x16 altgr inhibit
#
# Scan Code 24
rightarrow 0x17 altgr inhibit
#
# Scan Code 25
oslash 0x18 altgr inhibit
#
# Scan Code 26
thorn 0x19 altgr inhibit
#
# Scan Code 31
ae 0x1e altgr inhibit
#
# Scan Code 32
ssharp 0x1f altgr inhibit
#
# Scan Code 33
eth 0x20 altgr inhibit
#
# Scan Code 34
dstroke 0x21 altgr inhibit
#
# Scan Code 35
eng 0x22 altgr inhibit
#
# Scan Code 36
hstroke 0x23 altgr inhibit
#
# Scan Code 38
kra 0x25 altgr inhibit
#
# Scan Code 39
lstroke 0x26 altgr inhibit
#
# Scan Code 46
guillemotleft 0x2c altgr inhibit
#
# Scan Code 47
guillemotright 0x2d altgr inhibit
#
# Scan Code 49
leftdoublequotemark 0x2f altgr inhibit
#
# Scan Code 50
rightdoublequotemark 0x30 altgr inhibit
#
# Scan Code 52
mu 0x32 altgr inhibit
@@ -0,0 +1,91 @@
# Generated by Shlomil
# Please send your comments and corrections to <[email protected]>
include common
map 0x040D
#
# Top row
#
slash 0x10 altgr
apostrophe 0x11 altgr
hebrew_qoph 0x12 altgr
hebrew_resh 0x13 altgr
hebrew_aleph 0x14 altgr
hebrew_tet 0x15 altgr
hebrew_waw 0x16 altgr
hebrew_finalnun 0x17 altgr
hebrew_finalmem 0x18 altgr
hebrew_pe 0x19 altgr
#
# Second row
#
hebrew_shin 0x1e altgr
hebrew_dalet 0x1f altgr
hebrew_gimel 0x20 altgr
hebrew_kaph 0x21 altgr
hebrew_ayin 0x22 altgr
hebrew_yod 0x23 altgr
hebrew_chet 0x24 altgr
hebrew_lamed 0x25 altgr
hebrew_finalkaph 0x26 altgr
hebrew_finalpe 0x27 altgr
comma 0x28 altgr
#
# Third row
#
hebrew_zain 0x2c altgr
hebrew_samech 0x2d altgr
hebrew_bet 0x2e altgr
hebrew_he 0x2f altgr
hebrew_nun 0x30 altgr
hebrew_mem 0x31 altgr
hebrew_zade 0x32 altgr
hebrew_taw 0x33 altgr
hebrew_finalzade 0x34 altgr
period 0x35 altgr
#
# en-us
#
exclam 0x02 shift
at 0x03 shift
numbersign 0x04 shift
dollar 0x05 shift
percent 0x06 shift
asciicircum 0x07 shift
ampersand 0x08 shift
asterisk 0x09 shift
parenleft 0x0a shift
parenright 0x0b shift
minus 0x0c
underscore 0x0c shift
equal 0x0d
plus 0x0d shift
bracketleft 0x1a
braceleft 0x1a shift
bracketright 0x1b
braceright 0x1b shift
semicolon 0x27
colon 0x27 shift
apostrophe 0x28
quotedbl 0x28 shift
grave 0x29
asciitilde 0x29 shift
backslash 0x2b
bar 0x2b shift
comma 0x33
less 0x33 shift
period 0x34
greater 0x34 shift
slash 0x35
question 0x35 shift
@@ -0,0 +1,125 @@
# generated from XKB map hr
include common
map 0x41a
exclam 0x02 shift
asciitilde 0x02 altgr
dead_tilde 0x02 shift altgr
quotedbl 0x03 shift
dead_caron 0x03 altgr
caron 0x03 shift altgr
numbersign 0x04 shift
asciicircum 0x04 altgr
dead_circumflex 0x04 shift altgr
dollar 0x05 shift
dead_breve 0x05 altgr
breve 0x05 shift altgr
percent 0x06 shift
degree 0x06 altgr
dead_abovering 0x06 shift altgr
ampersand 0x07 shift
dead_ogonek 0x07 altgr
ogonek 0x07 shift altgr
slash 0x08 shift
grave 0x08 altgr
dead_grave 0x08 shift altgr
parenleft 0x09 shift
dead_abovedot 0x09 altgr
abovedot 0x09 shift altgr
parenright 0x0a shift
dead_acute 0x0a altgr
apostrophe 0x0a shift altgr
equal 0x0b shift
dead_doubleacute 0x0b altgr
doubleacute 0x0b shift altgr
apostrophe 0x0c
question 0x0c shift
dead_diaeresis 0x0c altgr
diaeresis 0x0c shift altgr
plus 0x0d
asterisk 0x0d shift
dead_cedilla 0x0d altgr
cedilla 0x0d shift altgr
backslash 0x10 altgr
Greek_OMEGA 0x10 shift altgr
bar 0x11 altgr
Lstroke 0x11 shift altgr
EuroSign 0x12 altgr
paragraph 0x13 altgr
registered 0x13 shift altgr
tslash 0x14 altgr
Tslash 0x14 shift altgr
z 0x15 addupper
leftarrow 0x15 altgr
yen 0x15 shift altgr
downarrow 0x16 altgr
uparrow 0x16 shift altgr
rightarrow 0x17 altgr
idotless 0x17 shift altgr
oslash 0x18 altgr
Ooblique 0x18 shift altgr
thorn 0x19 altgr
THORN 0x19 shift altgr
scaron 0x1a
Scaron 0x1a shift
division 0x1a altgr
dead_abovering 0x1a shift altgr
dstroke 0x1b
Dstroke 0x1b shift
multiply 0x1b altgr
dead_macron 0x1b shift altgr
ae 0x1e altgr
AE 0x1e shift altgr
ssharp 0x1f altgr
section 0x1f shift altgr
eth 0x20 altgr
ETH 0x20 shift altgr
bracketleft 0x21 altgr
ordfeminine 0x21 shift altgr
bracketright 0x22 altgr
ENG 0x22 shift altgr
hstroke 0x23 altgr
Hstroke 0x23 shift altgr
lstroke 0x25 altgr
ampersand 0x25 shift altgr
Lstroke 0x26 altgr
ccaron 0x27
Ccaron 0x27 shift
dead_acute 0x27 altgr
dead_doubleacute 0x27 shift altgr
cacute 0x28
Cacute 0x28 shift
ssharp 0x28 altgr
dead_caron 0x28 shift altgr
dead_cedilla 0x29
dead_diaeresis 0x29 shift
notsign 0x29 altgr
zcaron 0x2b
Zcaron 0x2b shift
currency 0x2b altgr
dead_breve 0x2b shift altgr
y 0x2c addupper
guillemotleft 0x2c altgr
less 0x2c shift altgr
guillemotright 0x2d altgr
greater 0x2d shift altgr
cent 0x2e altgr
copyright 0x2e shift altgr
at 0x2f altgr
grave 0x2f shift altgr
braceleft 0x30 altgr
apostrophe 0x30 shift altgr
braceright 0x31 altgr
section 0x32 altgr
masculine 0x32 shift altgr
comma 0x33
semicolon 0x33 shift
horizconnector 0x33 altgr
multiply 0x33 shift altgr
period 0x34
colon 0x34 shift
periodcentered 0x34 altgr
division 0x34 shift altgr
minus 0x35
underscore 0x35 shift
dead_belowdot 0x35 altgr
dead_abovedot 0x35 shift altgr
@@ -0,0 +1,115 @@
# Hungarian keyboard layout (QWERTZ)
# Created by: The NeverGone <[email protected]>
include common
map 0x40e
# AltGr keys:
notsign 0x29 altgr
asciitilde 0x02 altgr
caron 0x03 altgr
asciicircum 0x04 altgr
breve 0x05 altgr
degree 0x06 altgr
ogonek 0x07 altgr
grave 0x08 altgr
abovedot 0x09 altgr
acute 0x0a altgr
doubleacute 0x0b altgr
diaeresis 0x0c altgr
cedilla 0x0d altgr
backslash 0x10 altgr
bar 0x11 altgr
EuroSign 0x12 altgr
Iacute 0x17 altgr
division 0x1a altgr
multiply 0x1b altgr
dstroke 0x1f altgr
Dstroke 0x20 altgr
bracketleft 0x21 altgr
bracketright 0x22 altgr
iacute 0x24 altgr
lstroke 0x25 altgr
Lstroke 0x26 altgr
dollar 0x27 altgr
ssharp 0x28 altgr
currency 0x2b altgr
less 0x56 altgr
greater 0x2c altgr
numbersign 0x2d altgr
ampersand 0x2e altgr
at 0x2f altgr
braceleft 0x30 altgr
braceright 0x31 altgr
semicolon 0x33 altgr
asterisk 0x35 altgr
# Shift keys:
section 0x29 shift
apostrophe 0x02 shift
quotedbl 0x03 shift
plus 0x04 shift
exclam 0x05 shift
percent 0x06 shift
slash 0x07 shift
equal 0x08 shift
parenleft 0x09 shift
parenright 0x0a shift
Odiaeresis 0x0b shift
Udiaeresis 0x0c shift
Oacute 0x0d shift
Z 0x15 shift
Odoubleacute 0x1a shift
Uacute 0x1b shift
Eacute 0x27 shift
Aacute 0x28 shift
Udoubleacute 0x2b shift
Y 0x2c shift
question 0x33 shift
colon 0x34 shift
underscore 0x35 shift
F13 0x3b shift
F14 0x3c shift
F15 0x3d shift
F16 0x3e shift
F17 0x3f shift
F18 0x40 shift
F19 0x41 shift
F20 0x42 shift
F21 0x43 shift
F22 0x44 shift
F23 0x57 shift
F24 0x58 shift
# Ctrl keys:
F25 0x3b ctrl
F26 0x3c ctrl
F27 0x3d ctrl
F28 0x3e ctrl
F29 0x3f ctrl
F30 0x40 ctrl
F31 0x41 ctrl
F32 0x42 ctrl
F33 0x43 ctrl
F34 0x44 ctrl
F35 0x57 ctrl
#NoSymbol 0x58 ctrl
0 0x29
odiaeresis 0x0b
udiaeresis 0x0c
oacute 0x0d
z 0x15
odoubleacute 0x1a
uacute 0x1b
eacute 0x27
aacute 0x28
udoubleacute 0x2b
y 0x2c
comma 0x33
period 0x34
minus 0x35
@@ -0,0 +1,140 @@
# 2004-03-16 Halldór Guðmundsson and Morten Lange
# Keyboard definition file for the Icelandic keyboard
# to be used in rdesktop 1.3.x ( See rdesktop.org)
# generated from XKB map de, and changed manually
# Location for example /usr/local/share/rdesktop/keymaps/is
include common
map 0x40f
exclam 0x02 shift
onesuperior 0x02 altgr
exclamdown 0x02 shift altgr
quotedbl 0x03 shift
twosuperior 0x03 altgr
oneeighth 0x03 shift altgr
#section 0x04 shift
numbersign 0x04 shift
threesuperior 0x04 altgr
sterling 0x04 shift altgr
dollar 0x05 shift
onequarter 0x05 altgr
currency 0x05 shift altgr
percent 0x06 shift
onehalf 0x06 altgr
threeeighths 0x06 shift altgr
ampersand 0x07 shift
threequarters 0x07 altgr
fiveeighths 0x07 shift altgr
slash 0x08 shift
braceleft 0x08 altgr
seveneighths 0x08 shift altgr
parenleft 0x09 shift
bracketleft 0x09 altgr
trademark 0x09 shift altgr
parenright 0x0a shift
bracketright 0x0a altgr
plusminus 0x0a shift altgr
equal 0x0b shift
braceright 0x0b altgr
#ssharp 0x0c
odiaeresis 0x0c
#question 0x0c shift
Odiaeresis 0x0c shift
backslash 0x0c altgr
questiondown 0x0c shift altgr
#acute 0x0d
minus 0x0d
#dead_acute 0x0d
#grave 0x0d shift
#dead_grave 0x0d shift
underscore 0x0d shift
dead_cedilla 0x0d altgr
dead_ogonek 0x0d shift altgr
at 0x10 altgr
Greek_OMEGA 0x10 shift altgr
EuroSign 0x12 altgr
paragraph 0x13 altgr
registered 0x13 shift altgr
tslash 0x14 altgr
Tslash 0x14 shift altgr
#z 0x15 addupper
leftarrow 0x15 altgr
yen 0x15 shift altgr
downarrow 0x16 altgr
uparrow 0x16 shift altgr
rightarrow 0x17 altgr
idotless 0x17 shift altgr
oslash 0x18 altgr
Ooblique 0x18 shift altgr
#thorn 0x19 altgr
#THORN 0x19 shift altgr
#udiaeresis 0x1a
#Udiaeresis 0x1a shift
#dead_diaeresis 0x1a altgr
#dead_abovering 0x1a shift altgr
eth 0x1a
ETH 0x1a shift
apostrophe 0x1b
question 0x1b shift
#plus 0x1b
#asterisk 0x1b shift
asciitilde 0x1b altgr
#grave 0x1b altgr
#dead_tilde 0x1b altgr
#dead_macron 0x1b shift altgr
#ae 0x1e altgr
#AE 0x1e shift altgr
#eth 0x20 altgr
#eth 0x20
#ETH 0x20 shift altgr
#ETH 0x20 shift
dstroke 0x21 altgr
ordfeminine 0x21 shift altgr
eng 0x22 altgr
ENG 0x22 shift altgr
hstroke 0x23 altgr
Hstroke 0x23 shift altgr
kra 0x25 altgr
#adiaeresis 0x27
#Adiaeresis 0x27 shift
ae 0x27
AE 0x27 shift
dead_doubleacute 0x27 altgr
#adiaeresis 0x28
#Adiaeresis 0x28 shift
#dead_caron 0x28 shift altgr
#asciicircum 0x29
acute 0x28
dead_acute 0x28
#dead_circumflex 0x29
#degree 0x29 shift
#notsign 0x29 altgr
plus 0x2b
asterisk 0x2b shift
grave 0x2b altgr
#numbersign 0x2b
#apostrophe 0x2b shift
#dead_breve 0x2b shift altgr
#y 0x2c addupper
guillemotleft 0x2c altgr
guillemotright 0x2d altgr
cent 0x2e altgr
copyright 0x2e shift altgr
leftdoublequotemark 0x2f altgr
rightdoublequotemark 0x30 altgr
mu 0x32 altgr
masculine 0x32 shift altgr
comma 0x33
semicolon 0x33 shift
horizconnector 0x33 altgr
multiply 0x33 shift altgr
period 0x34
colon 0x34 shift
periodcentered 0x34 altgr
division 0x34 shift altgr
#minus 0x35
#underscore 0x35 shift
thorn 0x35
THORN 0x35 shift
dead_belowdot 0x35 altgr
dead_abovedot 0x35 shift altgr
@@ -0,0 +1,115 @@
# generated from XKB map it
include common
map 0x410
exclam 0x02 shift
onesuperior 0x02 altgr
exclamdown 0x02 shift altgr
quotedbl 0x03 shift
twosuperior 0x03 altgr
oneeighth 0x03 shift altgr
sterling 0x04 shift
threesuperior 0x04 altgr
dollar 0x05 shift
onequarter 0x05 altgr
percent 0x06 shift
onehalf 0x06 altgr
threeeighths 0x06 shift altgr
ampersand 0x07 shift
threequarters 0x07 altgr
fiveeighths 0x07 shift altgr
slash 0x08 shift
braceleft 0x08 altgr
seveneighths 0x08 shift altgr
parenleft 0x09 shift
trademark 0x09 shift altgr
parenright 0x0a shift
plusminus 0x0a shift altgr
equal 0x0b shift
braceright 0x0b altgr
degree 0x0b shift altgr
apostrophe 0x0c
question 0x0c shift
grave 0x0c altgr
questiondown 0x0c shift altgr
igrave 0x0d
asciicircum 0x0d shift
asciitilde 0x0d altgr
dead_ogonek 0x0d shift altgr
at 0x10 altgr
Greek_OMEGA 0x10 shift altgr
lstroke 0x11 altgr
Lstroke 0x11 shift altgr
EuroSign 0x12 altgr
cent 0x12 shift altgr
paragraph 0x13 altgr
registered 0x13 shift altgr
tslash 0x14 altgr
Tslash 0x14 shift altgr
leftarrow 0x15 altgr
yen 0x15 shift altgr
downarrow 0x16 altgr
uparrow 0x16 shift altgr
rightarrow 0x17 altgr
idotless 0x17 shift altgr
oslash 0x18 altgr
Ooblique 0x18 shift altgr
thorn 0x19 altgr
THORN 0x19 shift altgr
egrave 0x1a
eacute 0x1a shift
bracketleft 0x1a altgr
dead_abovering 0x1a shift altgr
plus 0x1b
asterisk 0x1b shift
bracketright 0x1b altgr
dead_macron 0x1b shift altgr
ae 0x1e altgr
AE 0x1e shift altgr
ssharp 0x1f altgr
section 0x1f shift altgr
eth 0x20 altgr
ETH 0x20 shift altgr
dstroke 0x21 altgr
ordfeminine 0x21 shift altgr
eng 0x22 altgr
ENG 0x22 shift altgr
hstroke 0x23 altgr
Hstroke 0x23 shift altgr
kra 0x25 altgr
lstroke 0x26 altgr
Lstroke 0x26 shift altgr
ograve 0x27
ccedilla 0x27 shift
at 0x27 altgr
dead_doubleacute 0x27 shift altgr
agrave 0x28
degree 0x28 shift
numbersign 0x28 altgr
backslash 0x29
bar 0x29 shift
notsign 0x29 altgr
ugrave 0x2b
section 0x2b shift
dead_grave 0x2b altgr
dead_breve 0x2b shift altgr
guillemotleft 0x2c altgr
guillemotright 0x2d altgr
cent 0x2e altgr
copyright 0x2e shift altgr
leftdoublequotemark 0x2f altgr
grave 0x2f shift altgr
rightdoublequotemark 0x30 altgr
mu 0x32 altgr
masculine 0x32 shift altgr
comma 0x33
semicolon 0x33 shift
horizconnector 0x33 altgr
multiply 0x33 shift altgr
period 0x34
colon 0x34 shift
periodcentered 0x34 altgr
division 0x34 shift altgr
minus 0x35
underscore 0x35 shift
dead_belowdot 0x35 altgr
dead_abovedot 0x35 shift altgr
@@ -0,0 +1,107 @@
# generated from XKB map jp106
include common
map 0xe0010411
keyboard_type 0x7
keyboard_subtype 0x2
keyboard_functionkeys 0xc
exclam 0x02 shift
kana_NU 0x02 altgr
quotedbl 0x03 shift
kana_FU 0x03 altgr
numbersign 0x04 shift
kana_A 0x04 altgr
kana_a 0x04 shift altgr
dollar 0x05 shift
kana_U 0x05 altgr
kana_u 0x05 shift altgr
percent 0x06 shift
kana_E 0x06 altgr
kana_e 0x06 shift altgr
ampersand 0x07 shift
kana_O 0x07 altgr
kana_o 0x07 shift altgr
apostrophe 0x08 shift
kana_YA 0x08 altgr
kana_ya 0x08 shift altgr
parenleft 0x09 shift
kana_YU 0x09 altgr
kana_yu 0x09 shift altgr
parenright 0x0a shift
kana_YO 0x0a altgr
kana_yo 0x0a shift altgr
asciitilde 0x0b shift
kana_WA 0x0b altgr
kana_WO 0x0b shift altgr
minus 0x0c
equal 0x0c shift
kana_HO 0x0c altgr
asciicircum 0x0d
asciitilde 0x0d shift
kana_HE 0x0d altgr
kana_TA 0x10 altgr
kana_TE 0x11 altgr
kana_I 0x12 altgr
kana_i 0x12 shift altgr
kana_SU 0x13 altgr
kana_KA 0x14 altgr
kana_N 0x15 altgr
kana_NA 0x16 altgr
kana_NI 0x17 altgr
kana_RA 0x18 altgr
kana_SE 0x19 altgr
at 0x1a
grave 0x1a shift
voicedsound 0x1a altgr
bracketleft 0x1b
braceleft 0x1b shift
semivoicedsound 0x1b altgr
kana_openingbracket 0x1b shift altgr
kana_CHI 0x1e altgr
kana_TO 0x1f altgr
kana_SHI 0x20 altgr
kana_HA 0x21 altgr
kana_KI 0x22 altgr
kana_KU 0x23 altgr
kana_MA 0x24 altgr
kana_NO 0x25 altgr
kana_RI 0x26 altgr
semicolon 0x27
plus 0x27 shift
kana_RE 0x27 altgr
colon 0x28
asterisk 0x28 shift
kana_KE 0x28 altgr
Zenkaku_Hankaku 0x29
bracketright 0x2b
braceright 0x2b shift
kana_MU 0x2b altgr
kana_closingbracket 0x2b shift altgr
kana_TSU 0x2c altgr
kana_tsu 0x2c shift altgr
kana_SA 0x2d altgr
kana_SO 0x2e altgr
kana_HI 0x2f altgr
kana_KO 0x30 altgr
kana_MI 0x31 altgr
kana_MO 0x32 altgr
comma 0x33
less 0x33 shift
kana_NE 0x33 altgr
kana_comma 0x33 shift altgr
period 0x34
greater 0x34 shift
kana_RU 0x34 altgr
kana_fullstop 0x34 shift altgr
slash 0x35
question 0x35 shift
kana_ME 0x35 altgr
kana_conjunctive 0x35 shift altgr
Eisu_toggle 0x3a shift
Execute 0x54 shift
Kanji 0x70
backslash 0x73
bar 0x7d shift
underscore 0x73 shift
Henkan_Mode 0x79
Katakana 0x70
Muhenkan 0x7b
@@ -0,0 +1,37 @@
# generated from XKB map ko
include common
map 0xe0010412
exclam 0x02 shift
at 0x03 shift
numbersign 0x04 shift
dollar 0x05 shift
percent 0x06 shift
asciicircum 0x07 shift
ampersand 0x08 shift
asterisk 0x09 shift
parenleft 0x0a shift
parenright 0x0b shift
minus 0x0c
underscore 0x0c shift
equal 0x0d
plus 0x0d shift
bracketleft 0x1a
braceleft 0x1a shift
bracketright 0x1b
braceright 0x1b shift
semicolon 0x27
colon 0x27 shift
apostrophe 0x28
quotedbl 0x28 shift
grave 0x29
asciitilde 0x29 shift
backslash 0x2b
bar 0x2b shift
comma 0x33
less 0x33 shift
period 0x34
greater 0x34 shift
slash 0x35
question 0x35 shift
Hangul 0xf2
Hangul_Hanja 0xf1
@@ -0,0 +1,57 @@
# generated from XKB map lt
include common
map 0x427
exclam 0x02 shift
aogonek 0x02 altgr
Aogonek 0x02 shift altgr
at 0x03 shift
ccaron 0x03 altgr
Ccaron 0x03 shift altgr
numbersign 0x04 shift
eogonek 0x04 altgr
Eogonek 0x04 shift altgr
dollar 0x05 shift
eabovedot 0x05 altgr
Eabovedot 0x05 shift altgr
percent 0x06 shift
iogonek 0x06 altgr
Iogonek 0x06 shift altgr
asciicircum 0x07 shift
scaron 0x07 altgr
Scaron 0x07 shift altgr
ampersand 0x08 shift
uogonek 0x08 altgr
Uogonek 0x08 shift altgr
asterisk 0x09 shift
umacron 0x09 altgr
Umacron 0x09 shift altgr
parenleft 0x0a shift
doublelowquotemark 0x0a altgr
parenright 0x0b shift
leftdoublequotemark 0x0b altgr
minus 0x0c
underscore 0x0c shift
equal 0x0d
plus 0x0d shift
zcaron 0x0d altgr
Zcaron 0x0d shift altgr
bracketleft 0x1a
braceleft 0x1a shift
bracketright 0x1b
braceright 0x1b shift
semicolon 0x27
colon 0x27 shift
apostrophe 0x28
quotedbl 0x28 shift
grave 0x29
asciitilde 0x29 shift
backslash 0x2b
bar 0x2b shift
comma 0x33
less 0x33 shift
period 0x34
greater 0x34 shift
slash 0x35
question 0x35 shift
endash 0x56
EuroSign 0x56 shift
@@ -0,0 +1,128 @@
# generated from XKB map lv
include common
map 0x426
exclam 0x02 shift
onesuperior 0x02 altgr
exclamdown 0x02 shift altgr
at 0x03 shift
twosuperior 0x03 altgr
oneeighth 0x03 shift altgr
numbersign 0x04 shift
threesuperior 0x04 altgr
sterling 0x04 shift altgr
dollar 0x05 shift
EuroSign 0x05 altgr
cent 0x05 shift altgr
percent 0x06 shift
onehalf 0x06 altgr
threeeighths 0x06 shift altgr
asciicircum 0x07 shift
threequarters 0x07 altgr
fiveeighths 0x07 shift altgr
ampersand 0x08 shift
braceleft 0x08 altgr
seveneighths 0x08 shift altgr
asterisk 0x09 shift
bracketleft 0x09 altgr
trademark 0x09 shift altgr
parenleft 0x0a shift
bracketright 0x0a altgr
plusminus 0x0a shift altgr
parenright 0x0b shift
braceright 0x0b altgr
degree 0x0b shift altgr
minus 0x0c
underscore 0x0c shift
backslash 0x0c altgr
questiondown 0x0c shift altgr
equal 0x0d
plus 0x0d shift
dead_cedilla 0x0d altgr
dead_ogonek 0x0d shift altgr
at 0x10 altgr
Greek_OMEGA 0x10 shift altgr
lstroke 0x11 altgr
Lstroke 0x11 shift altgr
emacron 0x12 altgr
Emacron 0x12 shift altgr
rcedilla 0x13 altgr
Rcedilla 0x13 shift altgr
tslash 0x14 altgr
Tslash 0x14 shift altgr
leftarrow 0x15 altgr
yen 0x15 shift altgr
umacron 0x16 altgr
Umacron 0x16 shift altgr
imacron 0x17 altgr
Imacron 0x17 shift altgr
omacron 0x18 altgr
Omacron 0x18 shift altgr
thorn 0x19 altgr
THORN 0x19 shift altgr
bracketleft 0x1a
braceleft 0x1a shift
dead_diaeresis 0x1a altgr
dead_abovering 0x1a shift altgr
bracketright 0x1b
braceright 0x1b shift
dead_tilde 0x1b altgr
dead_macron 0x1b shift altgr
ISO_Next_Group 0x1c shift
amacron 0x1e altgr
Amacron 0x1e shift altgr
scaron 0x1f altgr
Scaron 0x1f shift altgr
eth 0x20 altgr
ETH 0x20 shift altgr
dstroke 0x21 altgr
ordfeminine 0x21 shift altgr
gcedilla 0x22 altgr
Gcedilla 0x22 shift altgr
hstroke 0x23 altgr
Hstroke 0x23 shift altgr
kcedilla 0x25 altgr
Kcedilla 0x25 shift altgr
lcedilla 0x26 altgr
Lcedilla 0x26 shift altgr
semicolon 0x27
colon 0x27 shift
dead_acute 0x27 altgr
dead_doubleacute 0x27 shift altgr
apostrophe 0x28
quotedbl 0x28 shift
leftdoublequotemark 0x28 altgr
doublelowquotemark 0x28 shift altgr
grave 0x29
asciitilde 0x29 shift
notsign 0x29 altgr
backslash 0x2b
bar 0x2b shift
dead_grave 0x2b altgr
dead_breve 0x2b shift altgr
zcaron 0x2c altgr
Zcaron 0x2c shift altgr
guillemotright 0x2d altgr
greater 0x2d shift altgr
ccaron 0x2e altgr
Ccaron 0x2e shift altgr
leftdoublequotemark 0x2f altgr
grave 0x2f shift altgr
rightdoublequotemark 0x30 altgr
apostrophe 0x30 shift altgr
ncedilla 0x31 altgr
Ncedilla 0x31 shift altgr
mu 0x32 altgr
masculine 0x32 shift altgr
comma 0x33
less 0x33 shift
horizconnector 0x33 altgr
multiply 0x33 shift altgr
period 0x34
greater 0x34 shift
periodcentered 0x34 altgr
division 0x34 shift altgr
slash 0x35
question 0x35 shift
dead_belowdot 0x35 altgr
dead_abovedot 0x35 shift altgr
nobreakspace 0x39 altgr
@@ -0,0 +1,101 @@
# generated from XKB map mk
include common
map 0x42f
exclam 0x02 shift
at 0x03 shift
doublelowquotemark 0x03 shift altgr
numbersign 0x04 shift
leftdoublequotemark 0x04 shift altgr
dollar 0x05 shift
percent 0x06 shift
asciicircum 0x07 shift
ampersand 0x08 shift
asterisk 0x09 shift
parenleft 0x0a shift
parenright 0x0b shift
minus 0x0c
underscore 0x0c shift
equal 0x0d
plus 0x0d shift
Cyrillic_lje 0x10 altgr
Cyrillic_LJE 0x10 shift altgr
Cyrillic_nje 0x11 altgr
Cyrillic_NJE 0x11 shift altgr
Cyrillic_ie 0x12 altgr
Cyrillic_IE 0x12 shift altgr
Cyrillic_er 0x13 altgr
Cyrillic_ER 0x13 shift altgr
Cyrillic_te 0x14 altgr
Cyrillic_TE 0x14 shift altgr
Macedonia_dse 0x15 altgr
Macedonia_DSE 0x15 shift altgr
Cyrillic_u 0x16 altgr
Cyrillic_U 0x16 shift altgr
Cyrillic_i 0x17 altgr
Cyrillic_I 0x17 shift altgr
Cyrillic_o 0x18 altgr
Cyrillic_O 0x18 shift altgr
Cyrillic_pe 0x19 altgr
Cyrillic_PE 0x19 shift altgr
bracketleft 0x1a
braceleft 0x1a shift
Cyrillic_sha 0x1a altgr
Cyrillic_SHA 0x1a shift altgr
bracketright 0x1b
braceright 0x1b shift
Macedonia_gje 0x1b altgr
Macedonia_GJE 0x1b shift altgr
Cyrillic_a 0x1e altgr
Cyrillic_A 0x1e shift altgr
Cyrillic_es 0x1f altgr
Cyrillic_ES 0x1f shift altgr
Cyrillic_de 0x20 altgr
Cyrillic_DE 0x20 shift altgr
Cyrillic_ef 0x21 altgr
Cyrillic_EF 0x21 shift altgr
Cyrillic_ghe 0x22 altgr
Cyrillic_GHE 0x22 shift altgr
Cyrillic_ha 0x23 altgr
Cyrillic_HA 0x23 shift altgr
Cyrillic_je 0x24 altgr
Cyrillic_JE 0x24 shift altgr
Cyrillic_ka 0x25 altgr
Cyrillic_KA 0x25 shift altgr
Cyrillic_el 0x26 altgr
Cyrillic_EL 0x26 shift altgr
semicolon 0x27
colon 0x27 shift
Cyrillic_che 0x27 altgr
Cyrillic_CHE 0x27 shift altgr
apostrophe 0x28
quotedbl 0x28 shift
Macedonia_kje 0x28 altgr
Macedonia_KJE 0x28 shift altgr
grave 0x29
asciitilde 0x29 shift
backslash 0x2b
bar 0x2b shift
Cyrillic_zhe 0x2b altgr
Cyrillic_ZHE 0x2b shift altgr
Cyrillic_ze 0x2c altgr
Cyrillic_ZE 0x2c shift altgr
Cyrillic_dzhe 0x2d altgr
Cyrillic_DZHE 0x2d shift altgr
Cyrillic_tse 0x2e altgr
Cyrillic_TSE 0x2e shift altgr
Cyrillic_ve 0x2f altgr
Cyrillic_VE 0x2f shift altgr
Cyrillic_be 0x30 altgr
Cyrillic_BE 0x30 shift altgr
Cyrillic_en 0x31 altgr
Cyrillic_EN 0x31 shift altgr
Cyrillic_em 0x32 altgr
Cyrillic_EM 0x32 shift altgr
comma 0x33
less 0x33 shift
semicolon 0x33 shift altgr
period 0x34
greater 0x34 shift
colon 0x34 shift altgr
slash 0x35
question 0x35 shift
@@ -0,0 +1,18 @@
Shift_R 0x36
Shift_L 0x2a
Alt_R 0xb8
Mode_switch 0xb8
ISO_Level3_Shift 0xb8
Alt_L 0x38
Control_R 0x9d
Control_L 0x1d
# Translate Meta, Super and Hyper to Windows keys.
# This is hardcoded. See documentation for details.
# Translate Menu to the Windows Application key.
# This one does not work either.
Menu 0xdd
@@ -0,0 +1,60 @@
# Dutch (Netherlands)
include common
map 0x413
exclam 0x02 shift
onesuperior 0x02 altgr
quotebl 0x03 shift
twosuperior 0x03 altgr
numbersign 0x04 shift
threesuperior 0x04 altgr
dollar 0x05 shift
onequarter 0x05 altgr
percent 0x06 shift
onehalf 0x06 altgr
ampersand 0x07 shift
threequarters 0x07 altgr
underscore 0x08 shift
sterling 0x08 altgr
parenleft 0x09 shift
braceleft 0x09 altgr
parenright 0x0a shift
braceright 0x0a altgr
apostrophe 0x0b shift
slash 0x0c
question 0x0c shift
backslash 0x0c altgr
degree 0x0d
dead_tilde 0x0d shift
dead_cedilla 0x0d altgr
EuroSign 0x12 altgr
paragraph 0x13 altgr
dead_diaeresis 0x1a
dead_circumflex 0x1a shift
asterisk 0x1b
bar 0x1b shift
ssharp 0x1f altgr
plus 0x27
plusminus 0x27 shift
dead_acute 0x28
dead_grave 0x28 shift
at 0x29
section 0x29 shift
notsign 0x29 altgr
less 0x2b
greater 0x2b shift
guillemotleft 0x2c altgr
guillemotright 0x2d altgr
copyright 0x2e altgr
mu 0x32 altgr
comma 0x33
semicolon 0x33 shift
period 0x34
colon 0x34 shift
periodcentered 0x34 altgr
hyphen 0x35
equal 0x35 shift
bracketright 0x56
bracketleft 0x56 shift
brokenbar 0x56 altgr
@@ -0,0 +1,142 @@
# Dutch (Belgium)
map 0x813
include common
ampersand 0x02
1 0x02 shift
bar 0x02 altgr
exclamdown 0x02 shift altgr
eacute 0x03
2 0x03 shift
at 0x03 altgr
oneeighth 0x03 shift altgr
quotedbl 0x04
3 0x04 shift
numbersign 0x04 altgr
sterling 0x04 shift altgr
apostrophe 0x05
4 0x05 shift
onequarter 0x05 altgr
dollar 0x05 shift altgr
parenleft 0x06
5 0x06 shift
onehalf 0x06 altgr
threeeighths 0x06 shift altgr
section 0x07
6 0x07 shift
asciicircum 0x07 altgr
fiveeighths 0x07 shift altgr
egrave 0x08
7 0x08 shift
braceleft 0x08 altgr
seveneighths 0x08 shift altgr
exclam 0x09
8 0x09 shift
bracketleft 0x09 altgr
trademark 0x09 shift altgr
ccedilla 0x0a
9 0x0a shift
braceleft 0x0a altgr
plusminus 0x0a shift altgr
agrave 0x0b
0 0x0b shift
braceright 0x0b altgr
degree 0x0b shift altgr
parenright 0x0c
degree 0x0c shift
backslash 0x0c altgr
questiondown 0x0c shift altgr
minus 0x0d
underscore 0x0d shift
dead_cedilla 0x0d altgr
dead_ogonek 0x0d shift altgr
a 0x10 addupper
# at 0x10 altgr
Greek_OMEGA 0x10 shift altgr
z 0x11 addupper
lstroke 0x11 altgr
Lstroke 0x11 shift altgr
EuroSign 0x12 altgr
cent 0x12 shift altgr
paragraph 0x13 altgr
registered 0x13 shift altgr
tslash 0x14 altgr
Tslash 0x14 shift altgr
leftarrow 0x15 altgr
yen 0x15 shift altgr
downarrow 0x16 altgr
uparrow 0x16 shift altgr
rightarrow 0x17 altgr
idotless 0x17 shift altgr
oslash 0x18 altgr
Ooblique 0x18 shift altgr
thorn 0x19 altgr
THORN 0x19 shift altgr
dead_circumflex 0x1a
dead_diaeresis 0x1a shift
bracketleft 0x1a altgr
dead_abovering 0x1a shift altgr
dollar 0x1b
asterisk 0x1b shift
bracketright 0x1b altgr
dead_macron 0x1b shift altgr
q 0x1e addupper
ae 0x1e altgr
AE 0x1e shift altgr
ssharp 0x1f altgr
section 0x1f shift altgr
eth 0x20 altgr
ETH 0x20 shift altgr
dstroke 0x21 altgr
ordfeminine 0x21 shift altgr
eng 0x22 altgr
ENG 0x22 shift altgr
hstroke 0x23 altgr
Hstroke 0x23 shift altgr
kra 0x25 altgr
# ampersand 0x25 shift altgr
lstroke 0x26 altgr
Lstroke 0x26 shift altgr
m 0x27 addupper
dead_acute 0x27 altgr
dead_doubleacute 0x27 shift altgr
ugrave 0x28
percent 0x28 shift
dead_acute 0x28 altgr
dead_caron 0x28 shift altgr
twosuperior 0x29
threesuperior 0x29 shift
notsign 0x29 altgr
mu 0x2b
sterling 0x2b shift
dead_grave 0x2b altgr
dead_breve 0x2b shift altgr
w 0x2c addupper
guillemotleft 0x2c altgr
less 0x2c shift altgr
guillemotright 0x2d altgr
greater 0x2d shift altgr
cent 0x2e altgr
copyright 0x2e shift altgr
leftdoublequotemark 0x2f altgr
grave 0x2f shift altgr
rightdoublequotemark 0x30 altgr
# apostrophe 0x30 shift altgr
comma 0x32
question 0x32 shift
dead_cedilla 0x32 altgr
masculine 0x32 shift altgr
semicolon 0x33
period 0x33 shift
horizconnector 0x33 altgr
multiply 0x33 shift altgr
colon 0x34
slash 0x34 shift
periodcentered 0x34 altgr
division 0x34 shift altgr
equal 0x35
plus 0x35 shift
dead_tilde 0x35 altgr
dead_abovedot 0x35 shift altgr
backslash 0x56 altgr
less 0x56
greater 0x56 shift
@@ -0,0 +1,119 @@
# generated from XKB map no
include common
map 0x414
exclam 0x02 shift
exclamdown 0x02 altgr
onesuperior 0x02 shift altgr
quotedbl 0x03 shift
at 0x03 altgr
twosuperior 0x03 shift altgr
numbersign 0x04 shift
sterling 0x04 altgr
threesuperior 0x04 shift altgr
currency 0x05 shift
dollar 0x05 altgr
onequarter 0x05 shift altgr
percent 0x06 shift
onehalf 0x06 altgr
cent 0x06 shift altgr
ampersand 0x07 shift
yen 0x07 altgr
fiveeighths 0x07 shift altgr
slash 0x08 shift
braceleft 0x08 altgr
division 0x08 shift altgr
parenleft 0x09 shift
bracketleft 0x09 altgr
guillemotleft 0x09 shift altgr
parenright 0x0a shift
bracketright 0x0a altgr
guillemotright 0x0a shift altgr
equal 0x0b shift
braceright 0x0b altgr
degree 0x0b shift altgr
plus 0x0c
question 0x0c shift
plusminus 0x0c altgr
questiondown 0x0c shift altgr
backslash 0x0d
dead_grave 0x0d shift
dead_acute 0x0d altgr
notsign 0x0d shift altgr
Greek_OMEGA 0x10 shift altgr
lstroke 0x11 altgr
Lstroke 0x11 shift altgr
EuroSign 0x12 altgr
cent 0x12 shift altgr
registered 0x13 altgr
thorn 0x14 altgr
THORN 0x14 shift altgr
leftarrow 0x15 altgr
yen 0x15 shift altgr
downarrow 0x16 altgr
uparrow 0x16 shift altgr
rightarrow 0x17 altgr
idotless 0x17 shift altgr
oe 0x18 altgr
OE 0x18 shift altgr
thorn 0x19 altgr
THORN 0x19 shift altgr
aring 0x1a
Aring 0x1a shift
dead_diaeresis 0x1a altgr
dead_abovering 0x1a shift altgr
dead_diaeresis 0x1b
dead_circumflex 0x1b shift
asciicircum 0x01b shift
dead_tilde 0x1b altgr
asciitilde 0x1b altgr
dead_caron 0x1b shift altgr
ordfeminine 0x1e altgr
masculine 0x1e shift altgr
ssharp 0x1f altgr
section 0x1f shift altgr
eth 0x20 altgr
ETH 0x20 shift altgr
dstroke 0x21 altgr
ordfeminine 0x21 shift altgr
eng 0x22 altgr
ENG 0x22 shift altgr
hstroke 0x23 altgr
Hstroke 0x23 shift altgr
kra 0x25 altgr
lstroke 0x26 altgr
Lstroke 0x26 shift altgr
oslash 0x27
Ooblique 0x27 shift
dead_doubleacute 0x27 shift altgr
ae 0x28
AE 0x28 shift
dead_caron 0x28 shift altgr
bar 0x29
section 0x29 shift
brokenbar 0x29 altgr
paragraph 0x29 shift altgr
apostrophe 0x2b
asterisk 0x2b shift
multiply 0x2b shift altgr
guillemotleft 0x2c altgr
guillemotright 0x2d altgr
copyright 0x2e altgr
leftdoublequotemark 0x2f altgr
rightdoublequotemark 0x30 altgr
mu 0x32 altgr
masculine 0x32 shift altgr
comma 0x33
semicolon 0x33 shift
dead_cedilla 0x33 altgr
dead_ogonek 0x33 shift altgr
period 0x34
colon 0x34 shift
periodcentered 0x34 altgr
dead_abovedot 0x34 shift altgr
minus 0x35
underscore 0x35 shift
hyphen 0x35 altgr
macron 0x35 shift altgr
nobreakspace 0x39 altgr
onehalf 0x56 altgr
threequarters 0x56 shift altgr
@@ -0,0 +1,122 @@
# generated from XKB map pl
include common
map 0x415
exclam 0x02 shift
onesuperior 0x02 altgr
exclamdown 0x02 shift altgr
at 0x03 shift
twosuperior 0x03 altgr
oneeighth 0x03 shift altgr
numbersign 0x04 shift
threesuperior 0x04 altgr
sterling 0x04 shift altgr
dollar 0x05 shift
onequarter 0x05 altgr
percent 0x06 shift
onehalf 0x06 altgr
threeeighths 0x06 shift altgr
asciicircum 0x07 shift
threequarters 0x07 altgr
fiveeighths 0x07 shift altgr
ampersand 0x08 shift
braceleft 0x08 altgr
seveneighths 0x08 shift altgr
asterisk 0x09 shift
bracketleft 0x09 altgr
trademark 0x09 shift altgr
parenleft 0x0a shift
bracketright 0x0a altgr
plusminus 0x0a shift altgr
parenright 0x0b shift
braceright 0x0b altgr
degree 0x0b shift altgr
minus 0x0c
underscore 0x0c shift
backslash 0x0c altgr
questiondown 0x0c shift altgr
equal 0x0d
plus 0x0d shift
dead_cedilla 0x0d altgr
dead_ogonek 0x0d shift altgr
Greek_OMEGA 0x10 shift altgr
lstroke 0x11 altgr
Lstroke 0x11 shift altgr
eogonek 0x12 altgr
Eogonek 0x12 shift altgr
paragraph 0x13 altgr
registered 0x13 shift altgr
tslash 0x14 altgr
Tslash 0x14 shift altgr
leftarrow 0x15 altgr
yen 0x15 shift altgr
EuroSign 0x16 altgr
uparrow 0x16 shift altgr
rightarrow 0x17 altgr
idotless 0x17 shift altgr
oacute 0x18 altgr
Oacute 0x18 shift altgr
thorn 0x19 altgr
THORN 0x19 shift altgr
bracketleft 0x1a
braceleft 0x1a shift
dead_diaeresis 0x1a altgr
dead_abovering 0x1a shift altgr
bracketright 0x1b
braceright 0x1b shift
dead_tilde 0x1b altgr
dead_macron 0x1b shift altgr
aogonek 0x1e altgr
Aogonek 0x1e shift altgr
sacute 0x1f altgr
Sacute 0x1f shift altgr
eth 0x20 altgr
ETH 0x20 shift altgr
dstroke 0x21 altgr
ordfeminine 0x21 shift altgr
eng 0x22 altgr
ENG 0x22 shift altgr
hstroke 0x23 altgr
Hstroke 0x23 shift altgr
kra 0x25 altgr
lstroke 0x26 altgr
Lstroke 0x26 shift altgr
semicolon 0x27
colon 0x27 shift
dead_acute 0x27 altgr
dead_doubleacute 0x27 shift altgr
apostrophe 0x28
quotedbl 0x28 shift
dead_circumflex 0x28 altgr
dead_caron 0x28 shift altgr
grave 0x29
asciitilde 0x29 shift
notsign 0x29 altgr
backslash 0x2b
bar 0x2b shift
dead_grave 0x2b altgr
dead_breve 0x2b shift altgr
zabovedot 0x2c altgr
Zabovedot 0x2c shift altgr
zacute 0x2d altgr
Zacute 0x2d shift altgr
cacute 0x2e altgr
Cacute 0x2e shift altgr
leftdoublequotemark 0x2f altgr
grave 0x2f shift altgr
rightdoublequotemark 0x30 altgr
nacute 0x31 altgr
Nacute 0x31 shift altgr
mu 0x32 altgr
masculine 0x32 shift altgr
comma 0x33
less 0x33 shift
horizconnector 0x33 altgr
multiply 0x33 shift altgr
period 0x34
greater 0x34 shift
periodcentered 0x34 altgr
division 0x34 shift altgr
slash 0x35
question 0x35 shift
dead_belowdot 0x35 altgr
dead_abovedot 0x35 shift altgr
@@ -0,0 +1,113 @@
# generated from XKB map pt
include common
map 0x816
exclam 0x02 shift
onesuperior 0x02 altgr
exclamdown 0x02 shift altgr
quotedbl 0x03 shift
at 0x03 altgr
oneeighth 0x03 shift altgr
numbersign 0x04 shift
sterling 0x04 altgr
dollar 0x05 shift
section 0x05 altgr
percent 0x06 shift
onehalf 0x06 altgr
threeeighths 0x06 shift altgr
ampersand 0x07 shift
threequarters 0x07 altgr
fiveeighths 0x07 shift altgr
slash 0x08 shift
braceleft 0x08 altgr
seveneighths 0x08 shift altgr
parenleft 0x09 shift
bracketleft 0x09 altgr
trademark 0x09 shift altgr
parenright 0x0a shift
bracketright 0x0a altgr
plusminus 0x0a shift altgr
equal 0x0b shift
braceright 0x0b altgr
degree 0x0b shift altgr
apostrophe 0x0c
question 0x0c shift
backslash 0x0c altgr
questiondown 0x0c shift altgr
guillemotleft 0x0d
guillemotright 0x0d shift
dead_cedilla 0x0d altgr
dead_ogonek 0x0d shift altgr
Greek_OMEGA 0x10 shift altgr
lstroke 0x11 altgr
Lstroke 0x11 shift altgr
EuroSign 0x12 altgr
cent 0x12 shift altgr
paragraph 0x13 altgr
registered 0x13 shift altgr
tslash 0x14 altgr
Tslash 0x14 shift altgr
leftarrow 0x15 altgr
yen 0x15 shift altgr
downarrow 0x16 altgr
uparrow 0x16 shift altgr
rightarrow 0x17 altgr
idotless 0x17 shift altgr
oslash 0x18 altgr
Ooblique 0x18 shift altgr
thorn 0x19 altgr
THORN 0x19 shift altgr
plus 0x1a
asterisk 0x1a shift
dead_diaeresis 0x1a altgr
dead_abovering 0x1a shift altgr
dead_acute 0x1b
dead_grave 0x1b shift
dead_tilde 0x1b altgr
dead_macron 0x1b shift altgr
ae 0x1e altgr
AE 0x1e shift altgr
ssharp 0x1f altgr
eth 0x20 altgr
ETH 0x20 shift altgr
dstroke 0x21 altgr
ordfeminine 0x21 shift altgr
eng 0x22 altgr
ENG 0x22 shift altgr
hstroke 0x23 altgr
Hstroke 0x23 shift altgr
kra 0x25 altgr
lstroke 0x26 altgr
Lstroke 0x26 shift altgr
ccedilla 0x27
Ccedilla 0x27 shift
dead_doubleacute 0x27 shift altgr
masculine 0x28
ordfeminine 0x28 shift
dead_circumflex 0x28 altgr
dead_caron 0x28 shift altgr
backslash 0x29
bar 0x29 shift
notsign 0x29 altgr
dead_tilde 0x2b
dead_circumflex 0x2b shift
dead_breve 0x2b shift altgr
less 0x56
greater 0x56 shift
cent 0x2e altgr
copyright 0x2e shift altgr
leftdoublequotemark 0x2f altgr
grave 0x2f shift altgr
rightdoublequotemark 0x30 altgr
mu 0x32 altgr
comma 0x33
semicolon 0x33 shift
horizconnector 0x33 altgr
multiply 0x33 shift altgr
period 0x34
colon 0x34 shift
periodcentered 0x34 altgr
division 0x34 shift altgr
minus 0x35
underscore 0x35 shift
dead_belowdot 0x35 altgr
dead_abovedot 0x35 shift altgr
@@ -0,0 +1,69 @@
# generated from XKB map br
include common
map 0x416
exclam 0x02 shift
onesuperior 0x02 altgr
exclamdown 0x02 shift altgr
at 0x03 shift
twosuperior 0x03 altgr
onehalf 0x03 shift altgr
numbersign 0x04 shift
threesuperior 0x04 altgr
threequarters 0x04 shift altgr
dollar 0x05 shift
sterling 0x05 altgr
onequarter 0x05 shift altgr
percent 0x06 shift
cent 0x06 altgr
dead_diaeresis 0x07 shift
notsign 0x07 altgr
diaeresis 0x07 shift altgr
ampersand 0x08 shift
braceleft 0x08 altgr
asterisk 0x09 shift
bracketleft 0x09 altgr
parenleft 0x0a shift
bracketright 0x0a altgr
parenright 0x0b shift
braceright 0x0b altgr
minus 0x0c
underscore 0x0c shift
backslash 0x0c altgr
equal 0x0d
plus 0x0d shift
section 0x0d altgr
EuroSign 0x12 altgr
registered 0x13 altgr
dead_acute 0x1a
dead_grave 0x1a shift
acute 0x1a altgr
grave 0x1a shift altgr
bracketleft 0x1b
braceleft 0x1b shift
ordfeminine 0x1b altgr
ccedilla 0x27
Ccedilla 0x27 shift
dead_tilde 0x28
dead_circumflex 0x28 shift
asciitilde 0x28 altgr
asciicircum 0x28 shift altgr
apostrophe 0x29
quotedbl 0x29 shift
bracketright 0x2b
braceright 0x2b shift
masculine 0x2b altgr
copyright 0x2e altgr
mu 0x32 altgr
comma 0x33
less 0x33 shift
period 0x34
greater 0x34 shift
semicolon 0x35
colon 0x35 shift
comma 0x53 numlock
backslash 0x56
bar 0x56 shift
slash 0x73
question 0x73 shift
degree 0x73 altgr
KP_Decimal 0x34
@@ -0,0 +1,109 @@
# generated from XKB map ru
include common
map 0x419
exclam 0x02 shift
at 0x03 shift
quotedbl 0x03 shift altgr
numbersign 0x04 shift
dollar 0x05 shift
asterisk 0x05 shift altgr
percent 0x06 shift
colon 0x06 shift altgr
asciicircum 0x07 shift
comma 0x07 shift altgr
ampersand 0x08 shift
period 0x08 shift altgr
asterisk 0x09 shift
semicolon 0x09 shift altgr
parenleft 0x0a shift
parenright 0x0b shift
minus 0x0c
underscore 0x0c shift
equal 0x0d
plus 0x0d shift
Cyrillic_shorti 0x10 altgr
Cyrillic_SHORTI 0x10 shift altgr
Cyrillic_tse 0x11 altgr
Cyrillic_TSE 0x11 shift altgr
Cyrillic_u 0x12 altgr
Cyrillic_U 0x12 shift altgr
Cyrillic_ka 0x13 altgr
Cyrillic_KA 0x13 shift altgr
Cyrillic_ie 0x14 altgr
Cyrillic_IE 0x14 shift altgr
Cyrillic_en 0x15 altgr
Cyrillic_EN 0x15 shift altgr
Cyrillic_ghe 0x16 altgr
Cyrillic_GHE 0x16 shift altgr
Cyrillic_sha 0x17 altgr
Cyrillic_SHA 0x17 shift altgr
Cyrillic_shcha 0x18 altgr
Cyrillic_SHCHA 0x18 shift altgr
Cyrillic_ze 0x19 altgr
Cyrillic_ZE 0x19 shift altgr
bracketleft 0x1a
braceleft 0x1a shift
Cyrillic_ha 0x1a altgr
Cyrillic_HA 0x1a shift altgr
bracketright 0x1b
braceright 0x1b shift
Cyrillic_hardsign 0x1b altgr
Cyrillic_HARDSIGN 0x1b shift altgr
Cyrillic_ef 0x1e altgr
Cyrillic_EF 0x1e shift altgr
Cyrillic_yeru 0x1f altgr
Cyrillic_YERU 0x1f shift altgr
Cyrillic_ve 0x20 altgr
Cyrillic_VE 0x20 shift altgr
Cyrillic_a 0x21 altgr
Cyrillic_A 0x21 shift altgr
Cyrillic_pe 0x22 altgr
Cyrillic_PE 0x22 shift altgr
Cyrillic_er 0x23 altgr
Cyrillic_ER 0x23 shift altgr
Cyrillic_o 0x24 altgr
Cyrillic_O 0x24 shift altgr
Cyrillic_el 0x25 altgr
Cyrillic_EL 0x25 shift altgr
Cyrillic_de 0x26 altgr
Cyrillic_DE 0x26 shift altgr
semicolon 0x27
colon 0x27 shift
Cyrillic_zhe 0x27 altgr
Cyrillic_ZHE 0x27 shift altgr
apostrophe 0x28
quotedbl 0x28 shift
Cyrillic_e 0x28 altgr
Cyrillic_E 0x28 shift altgr
grave 0x29
asciitilde 0x29 shift
Cyrillic_io 0x29 altgr
Cyrillic_IO 0x29 shift altgr
backslash 0x2b
bar 0x2b shift
Cyrillic_ya 0x2c altgr
Cyrillic_YA 0x2c shift altgr
Cyrillic_che 0x2d altgr
Cyrillic_CHE 0x2d shift altgr
Cyrillic_es 0x2e altgr
Cyrillic_ES 0x2e shift altgr
Cyrillic_em 0x2f altgr
Cyrillic_EM 0x2f shift altgr
Cyrillic_i 0x30 altgr
Cyrillic_I 0x30 shift altgr
Cyrillic_te 0x31 altgr
Cyrillic_TE 0x31 shift altgr
Cyrillic_softsign 0x32 altgr
Cyrillic_SOFTSIGN 0x32 shift altgr
comma 0x33
less 0x33 shift
Cyrillic_be 0x33 altgr
Cyrillic_BE 0x33 shift altgr
period 0x34
greater 0x34 shift
Cyrillic_yu 0x34 altgr
Cyrillic_YU 0x34 shift altgr
slash 0x35
question 0x35 shift
slash 0x56 altgr
bar 0x56 shift altgr
@@ -0,0 +1,110 @@
# generated from XKB map sl
include common
map 0x424
exclam 0x02 shift
asciitilde 0x02 altgr
dead_tilde 0x02 shift altgr
quotedbl 0x03 shift
dead_caron 0x03 altgr
caron 0x03 shift altgr
numbersign 0x04 shift
asciicircum 0x04 altgr
dead_circumflex 0x04 shift altgr
dollar 0x05 shift
dead_breve 0x05 altgr
breve 0x05 shift altgr
percent 0x06 shift
degree 0x06 altgr
dead_abovering 0x06 shift altgr
ampersand 0x07 shift
dead_ogonek 0x07 altgr
ogonek 0x07 shift altgr
slash 0x08 shift
grave 0x08 altgr
dead_grave 0x08 shift altgr
parenleft 0x09 shift
dead_abovedot 0x09 altgr
abovedot 0x09 shift altgr
parenright 0x0a shift
dead_acute 0x0a altgr
equal 0x0b shift
dead_doubleacute 0x0b altgr
doubleacute 0x0b shift altgr
apostrophe 0x0c
question 0x0c shift
dead_diaeresis 0x0c altgr
diaeresis 0x0c shift altgr
plus 0x0d
asterisk 0x0d shift
dead_cedilla 0x0d altgr
cedilla 0x0d shift altgr
backslash 0x10 altgr
Greek_OMEGA 0x10 shift altgr
bar 0x11 altgr
Lstroke 0x11 shift altgr
EuroSign 0x12 altgr
paragraph 0x13 altgr
registered 0x13 shift altgr
tslash 0x14 altgr
Tslash 0x14 shift altgr
z 0x15 addupper
leftarrow 0x15 altgr
yen 0x15 shift altgr
downarrow 0x16 altgr
uparrow 0x16 shift altgr
rightarrow 0x17 altgr
idotless 0x17 shift altgr
oslash 0x18 altgr
Ooblique 0x18 shift altgr
thorn 0x19 altgr
THORN 0x19 shift altgr
scaron 0x1a
Scaron 0x1a shift
division 0x1a altgr
dstroke 0x1b
Dstroke 0x1b shift
multiply 0x1b altgr
dead_macron 0x1b shift altgr
ae 0x1e altgr
AE 0x1e shift altgr
ssharp 0x1f altgr
section 0x1f shift altgr
eth 0x20 altgr
ETH 0x20 shift altgr
bracketleft 0x21 altgr
ordfeminine 0x21 shift altgr
bracketright 0x22 altgr
ENG 0x22 shift altgr
hstroke 0x23 altgr
Hstroke 0x23 shift altgr
lstroke 0x25 altgr
Lstroke 0x26 altgr
ccaron 0x27
Ccaron 0x27 shift
cacute 0x28
Cacute 0x28 shift
ssharp 0x28 altgr
dead_cedilla 0x29
notsign 0x29 altgr
zcaron 0x2b
Zcaron 0x2b shift
currency 0x2b altgr
y 0x2c addupper
guillemotleft 0x2c altgr
guillemotright 0x2d altgr
cent 0x2e altgr
copyright 0x2e shift altgr
at 0x2f altgr
braceleft 0x30 altgr
braceright 0x31 altgr
section 0x32 altgr
masculine 0x32 shift altgr
comma 0x33
semicolon 0x33 shift
horizconnector 0x33 altgr
period 0x34
colon 0x34 shift
periodcentered 0x34 altgr
minus 0x35
underscore 0x35 shift
dead_belowdot 0x35 altgr
@@ -0,0 +1,80 @@
map 0x0000041d
include common
#
# Top row
#
section 0x29
onehalf 0x29 shift
# 1
exclam 0x2 shift
# 2
quotedbl 0x3 shift
at 0x3 altgr
# 3
numbersign 0x4 shift
sterling 0x4 altgr
# 4
currency 0x5 shift
dollar 0x5 altgr
# 5
percent 0x6 shift
# 6
ampersand 0x7 shift
# 7
slash 0x8 shift
braceleft 0x8 altgr
# 8
parenleft 0x9 shift
bracketleft 0x9 altgr
# 9
parenright 0xa shift
bracketright 0xa altgr
# 0
equal 0xb shift
braceright 0xb altgr
plus 0xc
question 0xc shift
backslash 0xc altgr
dead_acute 0xd
dead_grave 0xd shift
#
# QWERTY first row
#
EuroSign 0x12 altgr
aring 0x1a
Aring 0x1a shift
dead_diaeresis 0x1b
dead_circumflex 0x1b shift
dead_tilde 0x1b altgr
#
# QWERTY second row
#
odiaeresis 0x27
Odiaeresis 0x27 shift
adiaeresis 0x28
Adiaeresis 0x28 shift
apostrophe 0x2b
asterisk 0x2b shift
#
# QWERTY third row
#
less 0x56
greater 0x56 shift
bar 0x56 altgr
mu 0x32 altgr
comma 0x33
semicolon 0x33 shift
period 0x34
colon 0x34 shift
minus 0x35
underscore 0x35 shift
@@ -0,0 +1,131 @@
# generated from XKB map th
include common
map 0x41e
exclam 0x02 shift
Thai_lakkhangyao 0x02 altgr
plus 0x02 shift altgr
at 0x03 shift
slash 0x03 altgr
Thai_leknung 0x03 shift altgr
numbersign 0x04 shift
minus 0x04 altgr
Thai_leksong 0x04 shift altgr
dollar 0x05 shift
Thai_phosamphao 0x05 altgr
Thai_leksam 0x05 shift altgr
percent 0x06 shift
Thai_thothung 0x06 altgr
Thai_leksi 0x06 shift altgr
asciicircum 0x07 shift
Thai_sarau 0x07 altgr
Thai_sarauu 0x07 shift altgr
ampersand 0x08 shift
Thai_saraue 0x08 altgr
Thai_baht 0x08 shift altgr
asterisk 0x09 shift
Thai_khokhwai 0x09 altgr
Thai_lekha 0x09 shift altgr
parenleft 0x0a shift
Thai_totao 0x0a altgr
Thai_lekhok 0x0a shift altgr
parenright 0x0b shift
Thai_chochan 0x0b altgr
Thai_lekchet 0x0b shift altgr
minus 0x0c
underscore 0x0c shift
Thai_khokhai 0x0c altgr
Thai_lekpaet 0x0c shift altgr
equal 0x0d
plus 0x0d shift
Thai_chochang 0x0d altgr
Thai_lekkao 0x0d shift altgr
Thai_maiyamok 0x10 altgr
Thai_leksun 0x10 shift altgr
Thai_saraaimaimalai 0x11 altgr
quotedbl 0x11 shift altgr
Thai_saraam 0x12 altgr
Thai_dochada 0x12 shift altgr
Thai_phophan 0x13 altgr
Thai_thonangmontho 0x13 shift altgr
Thai_saraa 0x14 altgr
Thai_thothong 0x14 shift altgr
Thai_maihanakat 0x15 altgr
Thai_nikhahit 0x15 shift altgr
Thai_saraii 0x16 altgr
Thai_maitri 0x16 shift altgr
Thai_rorua 0x17 altgr
Thai_nonen 0x17 shift altgr
Thai_nonu 0x18 altgr
Thai_paiyannoi 0x18 shift altgr
Thai_yoyak 0x19 altgr
Thai_yoying 0x19 shift altgr
bracketleft 0x1a
braceleft 0x1a shift
Thai_bobaimai 0x1a altgr
Thai_thothan 0x1a shift altgr
bracketright 0x1b
braceright 0x1b shift
Thai_loling 0x1b altgr
comma 0x1b shift altgr
Thai_fofan 0x1e altgr
Thai_ru 0x1e shift altgr
Thai_hohip 0x1f altgr
Thai_khorakhang 0x1f shift altgr
Thai_kokai 0x20 altgr
Thai_topatak 0x20 shift altgr
Thai_dodek 0x21 altgr
Thai_sarao 0x21 shift altgr
Thai_sarae 0x22 altgr
Thai_chochoe 0x22 shift altgr
Thai_maitho 0x23 altgr
Thai_maitaikhu 0x23 shift altgr
Thai_maiek 0x24 altgr
Thai_maichattawa 0x24 shift altgr
Thai_saraaa 0x25 altgr
Thai_sorusi 0x25 shift altgr
Thai_sosua 0x26 altgr
Thai_sosala 0x26 shift altgr
semicolon 0x27
colon 0x27 shift
Thai_wowaen 0x27 altgr
Thai_soso 0x27 shift altgr
apostrophe 0x28
quotedbl 0x28 shift
Thai_ngongu 0x28 altgr
period 0x28 shift altgr
grave 0x29
asciitilde 0x29 shift
underscore 0x29 altgr
percent 0x29 shift altgr
ISO_First_Group 0x2a shift
backslash 0x2b
bar 0x2b shift
Thai_khokhuat 0x2b altgr
Thai_khokhon 0x2b shift altgr
Thai_phophung 0x2c altgr
parenleft 0x2c shift altgr
Thai_popla 0x2d altgr
parenright 0x2d shift altgr
Thai_saraae 0x2e altgr
Thai_choching 0x2e shift altgr
Thai_oang 0x2f altgr
Thai_honokhuk 0x2f shift altgr
Thai_sarai 0x30 altgr
Thai_phinthu 0x30 shift altgr
Thai_sarauee 0x31 altgr
Thai_thanthakhat 0x31 shift altgr
Thai_thothahan 0x32 altgr
question 0x32 shift altgr
comma 0x33
less 0x33 shift
Thai_moma 0x33 altgr
Thai_thophuthao 0x33 shift altgr
period 0x34
greater 0x34 shift
Thai_saraaimaimuan 0x34 altgr
Thai_lochula 0x34 shift altgr
slash 0x35
question 0x35 shift
Thai_fofa 0x35 altgr
Thai_lu 0x35 shift altgr
ISO_Last_Group 0x36 shift
@@ -0,0 +1,139 @@
# rdesktop Turkish Q Keyboard Layout
#
# Modified by Umit Oztosun <[email protected]> 20040328
#
# Modified from the original mapping file provided with rdesktop 1.3.1.
# This version works correctly with the right X settings.
include common
map 0x41f
# First row
quotedbl 0x29
eacute 0x29 shift
backslash 0x29 altgr
exclam 0x02 shift
onesuperior 0x02 altgr
exclamdown 0x02 shift altgr
apostrophe 0x03 shift
sterling 0x03 altgr
twosuperior 0x03 shift altgr
dead_circumflex 0x04 shift
numbersign 0x04 altgr
threesuperior 0x04 shift altgr
plus 0x05 shift
dollar 0x05 altgr
onequarter 0x05 shift altgr
percent 0x06 shift
onehalf 0x06 altgr
threeeighths 0x06 shift altgr
ampersand 0x07 shift
threequarters 0x07 altgr
slash 0x08 shift
braceleft 0x08 altgr
parenleft 0x09 shift
bracketleft 0x09 altgr
parenright 0x0a shift
bracketright 0x0a altgr
plusminus 0x0a shift altgr
equal 0x0b shift
braceright 0x0b altgr
degree 0x0b shift altgr
asterisk 0x0c
question 0x0c shift
backslash 0x0c altgr
questiondown 0x0c shift altgr
minus 0x0d
underscore 0x0d shift
division 0x0d altgr
at 0x10 altgr
EuroSign 0x12 altgr
trademark 0x14 altgr
ucircumflex 0x16 altgr
Ucircumflex 0x16 shift altgr
idotless 0x17
I 0x17 shift
icircumflex 0x17 altgr
Icircumflex 0x17 altgr shift
ocircumflex 0x18 altgr
Ocircumflex 0x18 shift altgr
gbreve 0x1a
Gbreve 0x1a shift
udiaeresis 0x1b
Udiaeresis 0x1b shift
asciitilde 0x1b altgr
dead_macron 0x1b shift altgr
comma 0x2b
semicolon 0x2b shift
grave 0x2b altgr
dead_grave 0x2b altgr shift
# Second row
acircumflex 0x1e altgr
Acircumflex 0x1e shift altgr
section 0x1f altgr
ordfeminine 0x21 altgr
scedilla 0x27
Scedilla 0x27 shift
acute 0x27 altgr
dead_acute 0x27 shift altgr
i 0x28
Iabovedot 0x28 shift
apostrophe 0x28 altgr
dead_caron 0x28 shift altgr
less 0x56
greater 0x56 shift
bar 0x56 altgr
brokenbar 0x56 shift altgr
cent 0x2e altgr
copyright 0x2e shift altgr
leftdoublequotemark 0x2f altgr
rightdoublequotemark 0x30 altgr
mu 0x32 altgr
masculine 0x32 shift altgr
odiaeresis 0x33
Odiaeresis 0x33 shift
multiply 0x33 altgr
ccedilla 0x34
Ccedilla 0x34 shift
periodcentered 0x34 altgr
division 0x34 shift altgr
period 0x35
colon 0x35 shift
dead_abovedot 0x35 altgr
dead_abovedot 0x35 shift altgr
@@ -0,0 +1,325 @@
/* -*- c-basic-offset: 8 -*-
rdesktop: A Remote Desktop Protocol client.
RDP licensing negotiation
Copyright (C) Matthew Chapman 1999-2005
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "rdesktop.h"
#include <openssl/rc4.h>
extern char g_username[64];
extern char g_hostname[16];
static uint8 g_licence_key[16];
static uint8 g_licence_sign_key[16];
BOOL g_licence_issued = False;
/* Generate a session key and RC4 keys, given client and server randoms */
static void
licence_generate_keys(uint8 * client_random, uint8 * server_random, uint8 * pre_master_secret)
{
uint8 master_secret[48];
uint8 key_block[48];
/* Generate master secret and then key material */
sec_hash_48(master_secret, pre_master_secret, client_random, server_random, 'A');
sec_hash_48(key_block, master_secret, server_random, client_random, 'A');
/* Store first 16 bytes of session key as MAC secret */
memcpy(g_licence_sign_key, key_block, 16);
/* Generate RC4 key from next 16 bytes */
sec_hash_16(g_licence_key, &key_block[16], client_random, server_random);
}
static void
licence_generate_hwid(uint8 * hwid)
{
buf_out_uint32(hwid, 2);
strncpy((char *) (hwid + 4), g_hostname, LICENCE_HWID_SIZE - 4);
}
/* Present an existing licence to the server */
static void
licence_present(uint8 * client_random, uint8 * rsa_data,
uint8 * licence_data, int licence_size, uint8 * hwid, uint8 * signature)
{
uint32 sec_flags = SEC_LICENCE_NEG;
uint16 length =
16 + SEC_RANDOM_SIZE + SEC_MODULUS_SIZE + SEC_PADDING_SIZE +
licence_size + LICENCE_HWID_SIZE + LICENCE_SIGNATURE_SIZE;
STREAM s;
s = sec_init(sec_flags, length + 4);
out_uint8(s, LICENCE_TAG_PRESENT);
out_uint8(s, 2); /* version */
out_uint16_le(s, length);
out_uint32_le(s, 1);
out_uint16(s, 0);
out_uint16_le(s, 0x0201);
out_uint8p(s, client_random, SEC_RANDOM_SIZE);
out_uint16(s, 0);
out_uint16_le(s, (SEC_MODULUS_SIZE + SEC_PADDING_SIZE));
out_uint8p(s, rsa_data, SEC_MODULUS_SIZE);
out_uint8s(s, SEC_PADDING_SIZE);
out_uint16_le(s, 1);
out_uint16_le(s, licence_size);
out_uint8p(s, licence_data, licence_size);
out_uint16_le(s, 1);
out_uint16_le(s, LICENCE_HWID_SIZE);
out_uint8p(s, hwid, LICENCE_HWID_SIZE);
out_uint8p(s, signature, LICENCE_SIGNATURE_SIZE);
s_mark_end(s);
sec_send(s, sec_flags);
}
/* Send a licence request packet */
static void
licence_send_request(uint8 * client_random, uint8 * rsa_data, char *user, char *host)
{
uint32 sec_flags = SEC_LICENCE_NEG;
uint16 userlen = strlen(user) + 1;
uint16 hostlen = strlen(host) + 1;
uint16 length = 128 + userlen + hostlen;
STREAM s;
s = sec_init(sec_flags, length + 2);
out_uint8(s, LICENCE_TAG_REQUEST);
out_uint8(s, 2); /* version */
out_uint16_le(s, length);
out_uint32_le(s, 1);
out_uint16(s, 0);
out_uint16_le(s, 0xff01);
out_uint8p(s, client_random, SEC_RANDOM_SIZE);
out_uint16(s, 0);
out_uint16_le(s, (SEC_MODULUS_SIZE + SEC_PADDING_SIZE));
out_uint8p(s, rsa_data, SEC_MODULUS_SIZE);
out_uint8s(s, SEC_PADDING_SIZE);
out_uint16_le(s, LICENCE_TAG_USER);
out_uint16_le(s, userlen);
out_uint8p(s, user, userlen);
out_uint16_le(s, LICENCE_TAG_HOST);
out_uint16_le(s, hostlen);
out_uint8p(s, host, hostlen);
s_mark_end(s);
sec_send(s, sec_flags);
}
/* Process a licence demand packet */
static void
licence_process_demand(STREAM s)
{
uint8 null_data[SEC_MODULUS_SIZE];
uint8 *server_random;
uint8 signature[LICENCE_SIGNATURE_SIZE];
uint8 hwid[LICENCE_HWID_SIZE];
uint8 *licence_data;
int licence_size;
RC4_KEY crypt_key;
/* Retrieve the server random from the incoming packet */
in_uint8p(s, server_random, SEC_RANDOM_SIZE);
/* We currently use null client keys. This is a bit naughty but, hey,
the security of licence negotiation isn't exactly paramount. */
memset(null_data, 0, sizeof(null_data));
licence_generate_keys(null_data, server_random, null_data);
licence_size = load_licence(&licence_data);
if (licence_size > 0)
{
/* Generate a signature for the HWID buffer */
licence_generate_hwid(hwid);
sec_sign(signature, 16, g_licence_sign_key, 16, hwid, sizeof(hwid));
/* Now encrypt the HWID */
RC4_set_key(&crypt_key, 16, g_licence_key);
RC4(&crypt_key, sizeof(hwid), hwid, hwid);
licence_present(null_data, null_data, licence_data, licence_size, hwid, signature);
xfree(licence_data);
return;
}
licence_send_request(null_data, null_data, g_username, g_hostname);
}
/* Send an authentication response packet */
static void
licence_send_authresp(uint8 * token, uint8 * crypt_hwid, uint8 * signature)
{
uint32 sec_flags = SEC_LICENCE_NEG;
uint16 length = 58;
STREAM s;
s = sec_init(sec_flags, length + 2);
out_uint8(s, LICENCE_TAG_AUTHRESP);
out_uint8(s, 2); /* version */
out_uint16_le(s, length);
out_uint16_le(s, 1);
out_uint16_le(s, LICENCE_TOKEN_SIZE);
out_uint8p(s, token, LICENCE_TOKEN_SIZE);
out_uint16_le(s, 1);
out_uint16_le(s, LICENCE_HWID_SIZE);
out_uint8p(s, crypt_hwid, LICENCE_HWID_SIZE);
out_uint8p(s, signature, LICENCE_SIGNATURE_SIZE);
s_mark_end(s);
sec_send(s, sec_flags);
}
/* Parse an authentication request packet */
static BOOL
licence_parse_authreq(STREAM s, uint8 ** token, uint8 ** signature)
{
uint16 tokenlen;
in_uint8s(s, 6); /* unknown: f8 3d 15 00 04 f6 */
in_uint16_le(s, tokenlen);
if (tokenlen != LICENCE_TOKEN_SIZE)
{
error("token len %d\n", tokenlen);
return False;
}
in_uint8p(s, *token, tokenlen);
in_uint8p(s, *signature, LICENCE_SIGNATURE_SIZE);
return s_check_end(s);
}
/* Process an authentication request packet */
static void
licence_process_authreq(STREAM s)
{
uint8 *in_token, *in_sig;
uint8 out_token[LICENCE_TOKEN_SIZE], decrypt_token[LICENCE_TOKEN_SIZE];
uint8 hwid[LICENCE_HWID_SIZE], crypt_hwid[LICENCE_HWID_SIZE];
uint8 sealed_buffer[LICENCE_TOKEN_SIZE + LICENCE_HWID_SIZE];
uint8 out_sig[LICENCE_SIGNATURE_SIZE];
RC4_KEY crypt_key;
/* Parse incoming packet and save the encrypted token */
licence_parse_authreq(s, &in_token, &in_sig);
memcpy(out_token, in_token, LICENCE_TOKEN_SIZE);
/* Decrypt the token. It should read TEST in Unicode. */
RC4_set_key(&crypt_key, 16, g_licence_key);
RC4(&crypt_key, LICENCE_TOKEN_SIZE, in_token, decrypt_token);
/* Generate a signature for a buffer of token and HWID */
licence_generate_hwid(hwid);
memcpy(sealed_buffer, decrypt_token, LICENCE_TOKEN_SIZE);
memcpy(sealed_buffer + LICENCE_TOKEN_SIZE, hwid, LICENCE_HWID_SIZE);
sec_sign(out_sig, 16, g_licence_sign_key, 16, sealed_buffer, sizeof(sealed_buffer));
/* Now encrypt the HWID */
RC4_set_key(&crypt_key, 16, g_licence_key);
RC4(&crypt_key, LICENCE_HWID_SIZE, hwid, crypt_hwid);
licence_send_authresp(out_token, crypt_hwid, out_sig);
}
/* Process an licence issue packet */
static void
licence_process_issue(STREAM s)
{
RC4_KEY crypt_key;
uint32 length;
uint16 check;
int i;
in_uint8s(s, 2); /* 3d 45 - unknown */
in_uint16_le(s, length);
if (!s_check_rem(s, length))
return;
RC4_set_key(&crypt_key, 16, g_licence_key);
RC4(&crypt_key, length, s->p, s->p);
in_uint16(s, check);
if (check != 0)
return;
g_licence_issued = True;
in_uint8s(s, 2); /* pad */
/* advance to fourth string */
length = 0;
for (i = 0; i < 4; i++)
{
in_uint8s(s, length);
in_uint32_le(s, length);
if (!s_check_rem(s, length))
return;
}
g_licence_issued = True;
save_licence(s->p, length);
}
/* Process a licence packet */
void
licence_process(STREAM s)
{
uint8 tag;
in_uint8(s, tag);
in_uint8s(s, 3); /* version, length */
switch (tag)
{
case LICENCE_TAG_DEMAND:
licence_process_demand(s);
break;
case LICENCE_TAG_AUTHREQ:
licence_process_authreq(s);
break;
case LICENCE_TAG_ISSUE:
licence_process_issue(s);
break;
case LICENCE_TAG_REISSUE:
case LICENCE_TAG_RESULT:
break;
default:
unimpl("licence tag 0x%x\n", tag);
}
}
@@ -0,0 +1,177 @@
/* -*- c-basic-offset: 8 -*-
+ rdesktop: A Remote Desktop Protocol client.
+ Support for the Matrox "lspci" channel
+ Copyright (C) 2005 Matrox Graphics Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
#include "rdesktop.h"
#include <sys/types.h>
#include <unistd.h>
static VCHANNEL *lspci_channel;
typedef struct _pci_device
{
uint16 klass;
uint16 vendor;
uint16 device;
uint16 subvendor;
uint16 subdevice;
uint8 revision;
uint8 progif;
} pci_device;
static pci_device current_device;
static void lspci_send(const char *output);
/* Handle one line of output from the lspci subprocess */
static BOOL
handle_child_line(const char *line, void *data)
{
const char *val;
char buf[1024];
if (str_startswith(line, "Class:"))
{
val = line + sizeof("Class:");
/* Skip whitespace and second Class: occurance */
val += strspn(val, " \t") + sizeof("Class");
current_device.klass = strtol(val, NULL, 16);
}
else if (str_startswith(line, "Vendor:"))
{
val = line + sizeof("Vendor:");
current_device.vendor = strtol(val, NULL, 16);
}
else if (str_startswith(line, "Device:"))
{
val = line + sizeof("Device:");
/* Sigh, there are *two* lines tagged as Device:. We
are not interested in the domain/bus/slot/func */
if (!strchr(val, ':'))
current_device.device = strtol(val, NULL, 16);
}
else if (str_startswith(line, "SVendor:"))
{
val = line + sizeof("SVendor:");
current_device.subvendor = strtol(val, NULL, 16);
}
else if (str_startswith(line, "SDevice:"))
{
val = line + sizeof("SDevice:");
current_device.subdevice = strtol(val, NULL, 16);
}
else if (str_startswith(line, "Rev:"))
{
val = line + sizeof("Rev:");
current_device.revision = strtol(val, NULL, 16);
}
else if (str_startswith(line, "ProgIf:"))
{
val = line + sizeof("ProgIf:");
current_device.progif = strtol(val, NULL, 16);
}
else if (strspn(line, " \t") == strlen(line))
{
/* Blank line. Send collected information over channel */
snprintf(buf, sizeof(buf), "%04x,%04x,%04x,%04x,%04x,%02x,%02x\n",
current_device.klass, current_device.vendor,
current_device.device, current_device.subvendor,
current_device.subdevice, current_device.revision, current_device.progif);
lspci_send(buf);
memset(&current_device, 0, sizeof(current_device));
}
else
{
warning("lspci: Unrecoqnized line '%s'\n", line);
}
return True;
}
/* Process one line of input from virtual channel */
static BOOL
lspci_process_line(const char *line, void *data)
{
char *lspci_command[5] = { "lspci", "-m", "-n", "-v", NULL };
if (!strcmp(line, "LSPCI"))
{
memset(&current_device, 0, sizeof(current_device));
subprocess(lspci_command, handle_child_line, NULL);
/* Send single dot to indicate end of enumeration */
lspci_send(".\n");
}
else
{
error("lspci protocol error: Invalid line '%s'\n", line);
}
return True;
}
/* Process new data from the virtual channel */
static void
lspci_process(STREAM s)
{
unsigned int pkglen;
static char *rest = NULL;
char *buf;
pkglen = s->end - s->p;
/* str_handle_lines requires null terminated strings */
buf = xmalloc(pkglen + 1);
STRNCPY(buf, (char *) s->p, pkglen + 1);
#if 0
printf("lspci recv:\n");
hexdump(s->p, pkglen);
#endif
str_handle_lines(buf, &rest, lspci_process_line, NULL);
xfree(buf);
}
/* Initialize this module: Register the lspci channel */
BOOL
lspci_init(void)
{
lspci_channel =
channel_register("lspci", CHANNEL_OPTION_INITIALIZED | CHANNEL_OPTION_ENCRYPT_RDP,
lspci_process);
return (lspci_channel != NULL);
}
/* Send data to channel */
static void
lspci_send(const char *output)
{
STREAM s;
size_t len;
len = strlen(output);
s = channel_init(lspci_channel, len);
out_uint8p(s, output, len) s_mark_end(s);
#if 0
printf("lspci send:\n");
hexdump(s->channel_hdr + 8, s->end - s->channel_hdr - 8);
#endif
channel_send(s, lspci_channel);
}
@@ -0,0 +1,469 @@
/* -*- c-basic-offset: 8 -*-
rdesktop: A Remote Desktop Protocol client.
Protocol services - Multipoint Communications Service
Copyright (C) Matthew Chapman 1999-2005
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "rdesktop.h"
uint16 g_mcs_userid;
extern VCHANNEL g_channels[];
extern unsigned int g_num_channels;
/* Parse an ASN.1 BER header */
static BOOL
ber_parse_header(STREAM s, int tagval, int *length)
{
int tag, len;
if (tagval > 0xff)
{
in_uint16_be(s, tag);
}
else
{
in_uint8(s, tag)}
if (tag != tagval)
{
error("expected tag %d, got %d\n", tagval, tag);
return False;
}
in_uint8(s, len);
if (len & 0x80)
{
len &= ~0x80;
*length = 0;
while (len--)
next_be(s, *length);
}
else
*length = len;
return s_check(s);
}
/* Output an ASN.1 BER header */
static void
ber_out_header(STREAM s, int tagval, int length)
{
if (tagval > 0xff)
{
out_uint16_be(s, tagval);
}
else
{
out_uint8(s, tagval);
}
if (length >= 0x80)
{
out_uint8(s, 0x82);
out_uint16_be(s, length);
}
else
out_uint8(s, length);
}
/* Output an ASN.1 BER integer */
static void
ber_out_integer(STREAM s, int value)
{
ber_out_header(s, BER_TAG_INTEGER, 2);
out_uint16_be(s, value);
}
/* Output a DOMAIN_PARAMS structure (ASN.1 BER) */
static void
mcs_out_domain_params(STREAM s, int max_channels, int max_users, int max_tokens, int max_pdusize)
{
ber_out_header(s, MCS_TAG_DOMAIN_PARAMS, 32);
ber_out_integer(s, max_channels);
ber_out_integer(s, max_users);
ber_out_integer(s, max_tokens);
ber_out_integer(s, 1); /* num_priorities */
ber_out_integer(s, 0); /* min_throughput */
ber_out_integer(s, 1); /* max_height */
ber_out_integer(s, max_pdusize);
ber_out_integer(s, 2); /* ver_protocol */
}
/* Parse a DOMAIN_PARAMS structure (ASN.1 BER) */
static BOOL
mcs_parse_domain_params(STREAM s)
{
int length;
ber_parse_header(s, MCS_TAG_DOMAIN_PARAMS, &length);
in_uint8s(s, length);
return s_check(s);
}
/* Send an MCS_CONNECT_INITIAL message (ASN.1 BER) */
static void
mcs_send_connect_initial(STREAM mcs_data)
{
int datalen = mcs_data->end - mcs_data->data;
int length = 9 + 3 * 34 + 4 + datalen;
STREAM s;
s = iso_init(length + 5);
ber_out_header(s, MCS_CONNECT_INITIAL, length);
ber_out_header(s, BER_TAG_OCTET_STRING, 1); /* calling domain */
out_uint8(s, 1);
ber_out_header(s, BER_TAG_OCTET_STRING, 1); /* called domain */
out_uint8(s, 1);
ber_out_header(s, BER_TAG_BOOLEAN, 1);
out_uint8(s, 0xff); /* upward flag */
mcs_out_domain_params(s, 34, 2, 0, 0xffff); /* target params */
mcs_out_domain_params(s, 1, 1, 1, 0x420); /* min params */
mcs_out_domain_params(s, 0xffff, 0xfc17, 0xffff, 0xffff); /* max params */
ber_out_header(s, BER_TAG_OCTET_STRING, datalen);
out_uint8p(s, mcs_data->data, datalen);
s_mark_end(s);
iso_send(s);
}
/* Expect a MCS_CONNECT_RESPONSE message (ASN.1 BER) */
static BOOL
mcs_recv_connect_response(STREAM mcs_data)
{
uint8 result;
int length;
STREAM s;
s = iso_recv(NULL);
if (s == NULL)
return False;
ber_parse_header(s, MCS_CONNECT_RESPONSE, &length);
ber_parse_header(s, BER_TAG_RESULT, &length);
in_uint8(s, result);
if (result != 0)
{
error("MCS connect: %d\n", result);
return False;
}
ber_parse_header(s, BER_TAG_INTEGER, &length);
in_uint8s(s, length); /* connect id */
mcs_parse_domain_params(s);
ber_parse_header(s, BER_TAG_OCTET_STRING, &length);
sec_process_mcs_data(s);
/*
if (length > mcs_data->size)
{
error("MCS data length %d, expected %d\n", length,
mcs_data->size);
length = mcs_data->size;
}
in_uint8a(s, mcs_data->data, length);
mcs_data->p = mcs_data->data;
mcs_data->end = mcs_data->data + length;
*/
return s_check_end(s);
}
/* Send an EDrq message (ASN.1 PER) */
static void
mcs_send_edrq(void)
{
STREAM s;
s = iso_init(5);
out_uint8(s, (MCS_EDRQ << 2));
out_uint16_be(s, 1); /* height */
out_uint16_be(s, 1); /* interval */
s_mark_end(s);
iso_send(s);
}
/* Send an AUrq message (ASN.1 PER) */
static void
mcs_send_aurq(void)
{
STREAM s;
s = iso_init(1);
out_uint8(s, (MCS_AURQ << 2));
s_mark_end(s);
iso_send(s);
}
/* Expect a AUcf message (ASN.1 PER) */
static BOOL
mcs_recv_aucf(uint16 * mcs_userid)
{
uint8 opcode, result;
STREAM s;
s = iso_recv(NULL);
if (s == NULL)
return False;
in_uint8(s, opcode);
if ((opcode >> 2) != MCS_AUCF)
{
error("expected AUcf, got %d\n", opcode);
return False;
}
in_uint8(s, result);
if (result != 0)
{
error("AUrq: %d\n", result);
return False;
}
if (opcode & 2)
in_uint16_be(s, *mcs_userid);
return s_check_end(s);
}
/* Send a CJrq message (ASN.1 PER) */
static void
mcs_send_cjrq(uint16 chanid)
{
STREAM s;
DEBUG_RDP5(("Sending CJRQ for channel #%d\n", chanid));
s = iso_init(5);
out_uint8(s, (MCS_CJRQ << 2));
out_uint16_be(s, g_mcs_userid);
out_uint16_be(s, chanid);
s_mark_end(s);
iso_send(s);
}
/* Expect a CJcf message (ASN.1 PER) */
static BOOL
mcs_recv_cjcf(void)
{
uint8 opcode, result;
STREAM s;
s = iso_recv(NULL);
if (s == NULL)
return False;
in_uint8(s, opcode);
if ((opcode >> 2) != MCS_CJCF)
{
error("expected CJcf, got %d\n", opcode);
return False;
}
in_uint8(s, result);
if (result != 0)
{
error("CJrq: %d\n", result);
return False;
}
in_uint8s(s, 4); /* mcs_userid, req_chanid */
if (opcode & 2)
in_uint8s(s, 2); /* join_chanid */
return s_check_end(s);
}
/* Initialise an MCS transport data packet */
STREAM
mcs_init(int length)
{
STREAM s;
s = iso_init(length + 8);
s_push_layer(s, mcs_hdr, 8);
return s;
}
/* Send an MCS transport data packet to a specific channel */
void
mcs_send_to_channel(STREAM s, uint16 channel)
{
uint16 length;
s_pop_layer(s, mcs_hdr);
length = s->end - s->p - 8;
length |= 0x8000;
out_uint8(s, (MCS_SDRQ << 2));
out_uint16_be(s, g_mcs_userid);
out_uint16_be(s, channel);
out_uint8(s, 0x70); /* flags */
out_uint16_be(s, length);
iso_send(s);
}
/* Send an MCS transport data packet to the global channel */
void
mcs_send(STREAM s)
{
mcs_send_to_channel(s, MCS_GLOBAL_CHANNEL);
}
/* Receive an MCS transport data packet */
STREAM
mcs_recv(uint16 * channel, uint8 * rdpver)
{
uint8 opcode, appid, length;
STREAM s;
s = iso_recv(rdpver);
if (s == NULL)
return NULL;
if (rdpver != NULL)
if (*rdpver != 3)
return s;
in_uint8(s, opcode);
appid = opcode >> 2;
if (appid != MCS_SDIN)
{
if (appid != MCS_DPUM)
{
error("expected data, got %d\n", opcode);
}
return NULL;
}
in_uint8s(s, 2); /* userid */
in_uint16_be(s, *channel);
in_uint8s(s, 1); /* flags */
in_uint8(s, length);
if (length & 0x80)
in_uint8s(s, 1); /* second byte of length */
return s;
}
/* Establish a connection up to the MCS layer */
BOOL
mcs_connect(char *server, STREAM mcs_data, char *username)
{
unsigned int i;
if (!iso_connect(server, username))
return False;
mcs_send_connect_initial(mcs_data);
if (!mcs_recv_connect_response(mcs_data))
goto error;
mcs_send_edrq();
mcs_send_aurq();
if (!mcs_recv_aucf(&g_mcs_userid))
goto error;
mcs_send_cjrq(g_mcs_userid + MCS_USERCHANNEL_BASE);
if (!mcs_recv_cjcf())
goto error;
mcs_send_cjrq(MCS_GLOBAL_CHANNEL);
if (!mcs_recv_cjcf())
goto error;
for (i = 0; i < g_num_channels; i++)
{
mcs_send_cjrq(g_channels[i].mcs_id);
if (!mcs_recv_cjcf())
goto error;
}
return True;
error:
iso_disconnect();
return False;
}
/* Establish a connection up to the MCS layer */
BOOL
mcs_reconnect(char *server, STREAM mcs_data)
{
unsigned int i;
if (!iso_reconnect(server))
return False;
mcs_send_connect_initial(mcs_data);
if (!mcs_recv_connect_response(mcs_data))
goto error;
mcs_send_edrq();
mcs_send_aurq();
if (!mcs_recv_aucf(&g_mcs_userid))
goto error;
mcs_send_cjrq(g_mcs_userid + MCS_USERCHANNEL_BASE);
if (!mcs_recv_cjcf())
goto error;
mcs_send_cjrq(MCS_GLOBAL_CHANNEL);
if (!mcs_recv_cjcf())
goto error;
for (i = 0; i < g_num_channels; i++)
{
mcs_send_cjrq(g_channels[i].mcs_id);
if (!mcs_recv_cjcf())
goto error;
}
return True;
error:
iso_disconnect();
return False;
}
/* Disconnect from the MCS layer */
void
mcs_disconnect(void)
{
iso_disconnect();
}
/* reset the state of the mcs layer */
void
mcs_reset_state(void)
{
g_mcs_userid = 0;
iso_reset_state();
}
@@ -0,0 +1,380 @@
/* -*- c-basic-offset: 8 -*-
rdesktop: A Remote Desktop Protocol client.
Protocol services - RDP decompression
Copyright (C) Matthew Chapman 1999-2005
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <stdio.h>
#include <string.h>
#include "rdesktop.h"
/* mppc decompression */
/* http://www.faqs.org/rfcs/rfc2118.html */
/* Contacts: */
/* hifn contact mentioned in the faq is */
/* Robert Friend rfriend at hifn dot com */
/* if you have questions regarding MPPC */
/* our contact is */
/* Guus Dhaeze GDhaeze at hifn dot com */
/* Licensing: */
/* decompression is alright as long as we */
/* don't compress data */
/* Algorithm: */
/* as the rfc states the algorithm seems to */
/* be LZ77 with a sliding buffer */
/* that is empty at init. */
/* the algorithm is called LZS and is */
/* patented for another couple of years. */
/* more information is available in */
/* http://www.ietf.org/ietf/IPR/hifn-ipr-draft-friend-tls-lzs-compression.txt */
RDPCOMP g_mppc_dict;
int
mppc_expand(uint8 * data, uint32 clen, uint8 ctype, uint32 * roff, uint32 * rlen)
{
int k, walker_len = 0, walker;
uint32 i = 0;
int next_offset, match_off;
int match_len;
int old_offset, match_bits;
BOOL big = ctype & RDP_MPPC_BIG ? True : False;
uint8 *dict = g_mppc_dict.hist;
if ((ctype & RDP_MPPC_COMPRESSED) == 0)
{
*roff = 0;
*rlen = clen;
return 0;
}
if ((ctype & RDP_MPPC_RESET) != 0)
{
g_mppc_dict.roff = 0;
}
if ((ctype & RDP_MPPC_FLUSH) != 0)
{
memset(dict, 0, RDP_MPPC_DICT_SIZE);
g_mppc_dict.roff = 0;
}
*roff = 0;
*rlen = 0;
walker = g_mppc_dict.roff;
next_offset = walker;
old_offset = next_offset;
*roff = old_offset;
if (clen == 0)
return 0;
clen += i;
do
{
if (walker_len == 0)
{
if (i >= clen)
break;
walker = data[i++] << 24;
walker_len = 8;
}
if (walker >= 0)
{
if (walker_len < 8)
{
if (i >= clen)
{
if (walker != 0)
return -1;
break;
}
walker |= (data[i++] & 0xff) << (24 - walker_len);
walker_len += 8;
}
if (next_offset >= RDP_MPPC_DICT_SIZE)
return -1;
dict[next_offset++] = (((uint32) walker) >> ((uint32) 24));
walker <<= 8;
walker_len -= 8;
continue;
}
walker <<= 1;
/* fetch next 8-bits */
if (--walker_len == 0)
{
if (i >= clen)
return -1;
walker = data[i++] << 24;
walker_len = 8;
}
/* literal decoding */
if (walker >= 0)
{
if (walker_len < 8)
{
if (i >= clen)
return -1;
walker |= (data[i++] & 0xff) << (24 - walker_len);
walker_len += 8;
}
if (next_offset >= RDP_MPPC_DICT_SIZE)
return -1;
dict[next_offset++] = (uint8) (walker >> 24 | 0x80);
walker <<= 8;
walker_len -= 8;
continue;
}
/* decode offset */
/* length pair */
walker <<= 1;
if (--walker_len < (big ? 3 : 2))
{
if (i >= clen)
return -1;
walker |= (data[i++] & 0xff) << (24 - walker_len);
walker_len += 8;
}
if (big)
{
/* offset decoding where offset len is:
-63: 11111 followed by the lower 6 bits of the value
64-319: 11110 followed by the lower 8 bits of the value ( value - 64 )
320-2367: 1110 followed by lower 11 bits of the value ( value - 320 )
2368-65535: 110 followed by lower 16 bits of the value ( value - 2368 )
*/
switch (((uint32) walker) >> ((uint32) 29))
{
case 7: /* - 63 */
for (; walker_len < 9; walker_len += 8)
{
if (i >= clen)
return -1;
walker |= (data[i++] & 0xff) << (24 - walker_len);
}
walker <<= 3;
match_off = ((uint32) walker) >> ((uint32) 26);
walker <<= 6;
walker_len -= 9;
break;
case 6: /* 64 - 319 */
for (; walker_len < 11; walker_len += 8)
{
if (i >= clen)
return -1;
walker |= (data[i++] & 0xff) << (24 - walker_len);
}
walker <<= 3;
match_off = (((uint32) walker) >> ((uint32) 24)) + 64;
walker <<= 8;
walker_len -= 11;
break;
case 5:
case 4: /* 320 - 2367 */
for (; walker_len < 13; walker_len += 8)
{
if (i >= clen)
return -1;
walker |= (data[i++] & 0xff) << (24 - walker_len);
}
walker <<= 2;
match_off = (((uint32) walker) >> ((uint32) 21)) + 320;
walker <<= 11;
walker_len -= 13;
break;
default: /* 2368 - 65535 */
for (; walker_len < 17; walker_len += 8)
{
if (i >= clen)
return -1;
walker |= (data[i++] & 0xff) << (24 - walker_len);
}
walker <<= 1;
match_off = (((uint32) walker) >> ((uint32) 16)) + 2368;
walker <<= 16;
walker_len -= 17;
break;
}
}
else
{
/* offset decoding where offset len is:
-63: 1111 followed by the lower 6 bits of the value
64-319: 1110 followed by the lower 8 bits of the value ( value - 64 )
320-8191: 110 followed by the lower 13 bits of the value ( value - 320 )
*/
switch (((uint32) walker) >> ((uint32) 30))
{
case 3: /* - 63 */
if (walker_len < 8)
{
if (i >= clen)
return -1;
walker |= (data[i++] & 0xff) << (24 - walker_len);
walker_len += 8;
}
walker <<= 2;
match_off = ((uint32) walker) >> ((uint32) 26);
walker <<= 6;
walker_len -= 8;
break;
case 2: /* 64 - 319 */
for (; walker_len < 10; walker_len += 8)
{
if (i >= clen)
return -1;
walker |= (data[i++] & 0xff) << (24 - walker_len);
}
walker <<= 2;
match_off = (((uint32) walker) >> ((uint32) 24)) + 64;
walker <<= 8;
walker_len -= 10;
break;
default: /* 320 - 8191 */
for (; walker_len < 14; walker_len += 8)
{
if (i >= clen)
return -1;
walker |= (data[i++] & 0xff) << (24 - walker_len);
}
match_off = (walker >> 18) + 320;
walker <<= 14;
walker_len -= 14;
break;
}
}
if (walker_len == 0)
{
if (i >= clen)
return -1;
walker = data[i++] << 24;
walker_len = 8;
}
/* decode length of match */
match_len = 0;
if (walker >= 0)
{ /* special case - length of 3 is in bit 0 */
match_len = 3;
walker <<= 1;
walker_len--;
}
else
{
/* this is how it works len of:
4-7: 10 followed by 2 bits of the value
8-15: 110 followed by 3 bits of the value
16-31: 1110 followed by 4 bits of the value
32-63: .... and so forth
64-127:
128-255:
256-511:
512-1023:
1024-2047:
2048-4095:
4096-8191:
i.e. 4097 is encoded as: 111111111110 000000000001
meaning 4096 + 1...
*/
match_bits = big ? 14 : 11; /* 11 or 14 bits of value at most */
do
{
walker <<= 1;
if (--walker_len == 0)
{
if (i >= clen)
return -1;
walker = data[i++] << 24;
walker_len = 8;
}
if (walker >= 0)
break;
if (--match_bits == 0)
{
return -1;
}
}
while (1);
match_len = (big ? 16 : 13) - match_bits;
walker <<= 1;
if (--walker_len < match_len)
{
for (; walker_len < match_len; walker_len += 8)
{
if (i >= clen)
{
return -1;
}
walker |= (data[i++] & 0xff) << (24 - walker_len);
}
}
match_bits = match_len;
match_len =
((walker >> (32 - match_bits)) & (~(-1 << match_bits))) | (1 <<
match_bits);
walker <<= match_bits;
walker_len -= match_bits;
}
if (next_offset + match_len >= RDP_MPPC_DICT_SIZE)
{
return -1;
}
/* memory areas can overlap - meaning we can't use memXXX functions */
k = (next_offset - match_off) & (big ? 65535 : 8191);
do
{
dict[next_offset++] = dict[k++];
}
while (--match_len != 0);
}
while (1);
/* store history offset */
g_mppc_dict.roff = next_offset;
*roff = old_offset;
*rlen = next_offset - old_offset;
return 0;
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,368 @@
/*
rdesktop: A Remote Desktop Protocol client.
RDP order processing
Copyright (C) Matthew Chapman 1999-2005
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#define RDP_ORDER_STANDARD 0x01
#define RDP_ORDER_SECONDARY 0x02
#define RDP_ORDER_BOUNDS 0x04
#define RDP_ORDER_CHANGE 0x08
#define RDP_ORDER_DELTA 0x10
#define RDP_ORDER_LASTBOUNDS 0x20
#define RDP_ORDER_SMALL 0x40
#define RDP_ORDER_TINY 0x80
enum RDP_ORDER_TYPE
{
RDP_ORDER_DESTBLT = 0,
RDP_ORDER_PATBLT = 1,
RDP_ORDER_SCREENBLT = 2,
RDP_ORDER_LINE = 9,
RDP_ORDER_RECT = 10,
RDP_ORDER_DESKSAVE = 11,
RDP_ORDER_MEMBLT = 13,
RDP_ORDER_TRIBLT = 14,
RDP_ORDER_POLYGON = 20,
RDP_ORDER_POLYGON2 = 21,
RDP_ORDER_POLYLINE = 22,
RDP_ORDER_ELLIPSE = 25,
RDP_ORDER_ELLIPSE2 = 26,
RDP_ORDER_TEXT2 = 27
};
enum RDP_SECONDARY_ORDER_TYPE
{
RDP_ORDER_RAW_BMPCACHE = 0,
RDP_ORDER_COLCACHE = 1,
RDP_ORDER_BMPCACHE = 2,
RDP_ORDER_FONTCACHE = 3,
RDP_ORDER_RAW_BMPCACHE2 = 4,
RDP_ORDER_BMPCACHE2 = 5,
RDP_ORDER_BRUSHCACHE = 7
};
typedef struct _DESTBLT_ORDER
{
sint16 x;
sint16 y;
sint16 cx;
sint16 cy;
uint8 opcode;
}
DESTBLT_ORDER;
typedef struct _PATBLT_ORDER
{
sint16 x;
sint16 y;
sint16 cx;
sint16 cy;
uint8 opcode;
uint32 bgcolour;
uint32 fgcolour;
BRUSH brush;
}
PATBLT_ORDER;
typedef struct _SCREENBLT_ORDER
{
sint16 x;
sint16 y;
sint16 cx;
sint16 cy;
uint8 opcode;
sint16 srcx;
sint16 srcy;
}
SCREENBLT_ORDER;
typedef struct _LINE_ORDER
{
uint16 mixmode;
sint16 startx;
sint16 starty;
sint16 endx;
sint16 endy;
uint32 bgcolour;
uint8 opcode;
PEN pen;
}
LINE_ORDER;
typedef struct _RECT_ORDER
{
sint16 x;
sint16 y;
sint16 cx;
sint16 cy;
uint32 colour;
}
RECT_ORDER;
typedef struct _DESKSAVE_ORDER
{
uint32 offset;
sint16 left;
sint16 top;
sint16 right;
sint16 bottom;
uint8 action;
}
DESKSAVE_ORDER;
typedef struct _TRIBLT_ORDER
{
uint8 colour_table;
uint8 cache_id;
sint16 x;
sint16 y;
sint16 cx;
sint16 cy;
uint8 opcode;
sint16 srcx;
sint16 srcy;
uint32 bgcolour;
uint32 fgcolour;
BRUSH brush;
uint16 cache_idx;
uint16 unknown;
}
TRIBLT_ORDER;
typedef struct _MEMBLT_ORDER
{
uint8 colour_table;
uint8 cache_id;
sint16 x;
sint16 y;
sint16 cx;
sint16 cy;
uint8 opcode;
sint16 srcx;
sint16 srcy;
uint16 cache_idx;
}
MEMBLT_ORDER;
#define MAX_DATA 256
typedef struct _POLYGON_ORDER
{
sint16 x;
sint16 y;
uint8 opcode;
uint8 fillmode;
uint32 fgcolour;
uint8 npoints;
uint8 datasize;
uint8 data[MAX_DATA];
}
POLYGON_ORDER;
typedef struct _POLYGON2_ORDER
{
sint16 x;
sint16 y;
uint8 opcode;
uint8 fillmode;
uint32 bgcolour;
uint32 fgcolour;
BRUSH brush;
uint8 npoints;
uint8 datasize;
uint8 data[MAX_DATA];
}
POLYGON2_ORDER;
typedef struct _POLYLINE_ORDER
{
sint16 x;
sint16 y;
uint8 opcode;
uint32 fgcolour;
uint8 lines;
uint8 datasize;
uint8 data[MAX_DATA];
}
POLYLINE_ORDER;
typedef struct _ELLIPSE_ORDER
{
sint16 left;
sint16 top;
sint16 right;
sint16 bottom;
uint8 opcode;
uint8 fillmode;
uint32 fgcolour;
}
ELLIPSE_ORDER;
typedef struct _ELLIPSE2_ORDER
{
sint16 left;
sint16 top;
sint16 right;
sint16 bottom;
uint8 opcode;
uint8 fillmode;
BRUSH brush;
uint32 bgcolour;
uint32 fgcolour;
}
ELLIPSE2_ORDER;
#define MAX_TEXT 256
typedef struct _TEXT2_ORDER
{
uint8 font;
uint8 flags;
uint8 opcode;
uint8 mixmode;
uint32 bgcolour;
uint32 fgcolour;
sint16 clipleft;
sint16 cliptop;
sint16 clipright;
sint16 clipbottom;
sint16 boxleft;
sint16 boxtop;
sint16 boxright;
sint16 boxbottom;
BRUSH brush;
sint16 x;
sint16 y;
uint8 length;
uint8 text[MAX_TEXT];
}
TEXT2_ORDER;
typedef struct _RDP_ORDER_STATE
{
uint8 order_type;
BOUNDS bounds;
DESTBLT_ORDER destblt;
PATBLT_ORDER patblt;
SCREENBLT_ORDER screenblt;
LINE_ORDER line;
RECT_ORDER rect;
DESKSAVE_ORDER desksave;
MEMBLT_ORDER memblt;
TRIBLT_ORDER triblt;
POLYGON_ORDER polygon;
POLYGON2_ORDER polygon2;
POLYLINE_ORDER polyline;
ELLIPSE_ORDER ellipse;
ELLIPSE2_ORDER ellipse2;
TEXT2_ORDER text2;
}
RDP_ORDER_STATE;
typedef struct _RDP_RAW_BMPCACHE_ORDER
{
uint8 cache_id;
uint8 pad1;
uint8 width;
uint8 height;
uint8 bpp;
uint16 bufsize;
uint16 cache_idx;
uint8 *data;
}
RDP_RAW_BMPCACHE_ORDER;
typedef struct _RDP_BMPCACHE_ORDER
{
uint8 cache_id;
uint8 pad1;
uint8 width;
uint8 height;
uint8 bpp;
uint16 bufsize;
uint16 cache_idx;
uint16 pad2;
uint16 size;
uint16 row_size;
uint16 final_size;
uint8 *data;
}
RDP_BMPCACHE_ORDER;
/* RDP_BMPCACHE2_ORDER */
#define ID_MASK 0x0007
#define MODE_MASK 0x0038
#define SQUARE 0x0080
#define PERSIST 0x0100
#define FLAG_51_UNKNOWN 0x0800
#define MODE_SHIFT 3
#define LONG_FORMAT 0x80
#define BUFSIZE_MASK 0x3FFF /* or 0x1FFF? */
#define MAX_GLYPH 32
typedef struct _RDP_FONT_GLYPH
{
uint16 character;
uint16 unknown;
uint16 baseline;
uint16 width;
uint16 height;
uint8 data[MAX_GLYPH];
}
RDP_FONT_GLYPH;
#define MAX_GLYPHS 256
typedef struct _RDP_FONTCACHE_ORDER
{
uint8 font;
uint8 nglyphs;
RDP_FONT_GLYPH glyphs[MAX_GLYPHS];
}
RDP_FONTCACHE_ORDER;
typedef struct _RDP_COLCACHE_ORDER
{
uint8 cache_id;
COLOURMAP map;
}
RDP_COLCACHE_ORDER;
@@ -0,0 +1,190 @@
/* -*- c-basic-offset: 8 -*-
rdesktop: A Remote Desktop Protocol client.
Copyright (C) Matthew Chapman 1999-2005
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#define MAX_PARALLEL_DEVICES 1
#define FILE_DEVICE_PARALLEL 0x22
#define IOCTL_PAR_QUERY_RAW_DEVICE_ID 0x0c
#include "rdesktop.h"
#include <unistd.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <errno.h>
#if defined(__linux__)
#include <linux/lp.h>
#endif
extern RDPDR_DEVICE g_rdpdr_device[];
/* Enumeration of devices from rdesktop.c */
/* returns numer of units found and initialized. */
/* optarg looks like ':LPT1=/dev/lp0' */
/* when it arrives to this function. */
int
parallel_enum_devices(uint32 * id, char *optarg)
{
PARALLEL_DEVICE *ppar_info;
char *pos = optarg;
char *pos2;
int count = 0;
/* skip the first colon */
optarg++;
while ((pos = next_arg(optarg, ',')) && *id < RDPDR_MAX_DEVICES)
{
ppar_info = (PARALLEL_DEVICE *) xmalloc(sizeof(PARALLEL_DEVICE));
pos2 = next_arg(optarg, '=');
strcpy(g_rdpdr_device[*id].name, optarg);
toupper_str(g_rdpdr_device[*id].name);
g_rdpdr_device[*id].local_path = xmalloc(strlen(pos2) + 1);
strcpy(g_rdpdr_device[*id].local_path, pos2);
printf("PARALLEL %s to %s\n", optarg, pos2);
/* set device type */
g_rdpdr_device[*id].device_type = DEVICE_TYPE_PARALLEL;
g_rdpdr_device[*id].pdevice_data = (void *) ppar_info;
g_rdpdr_device[*id].handle = 0;
count++;
(*id)++;
optarg = pos;
}
return count;
}
static NTSTATUS
parallel_create(uint32 device_id, uint32 access, uint32 share_mode, uint32 disposition,
uint32 flags, char *filename, NTHANDLE * handle)
{
int parallel_fd;
parallel_fd = open(g_rdpdr_device[device_id].local_path, O_RDWR);
if (parallel_fd == -1)
{
perror("open");
return STATUS_ACCESS_DENIED;
}
/* all read and writes should be non blocking */
if (fcntl(parallel_fd, F_SETFL, O_NONBLOCK) == -1)
perror("fcntl");
#if defined(LPABORT)
/* Retry on errors */
ioctl(parallel_fd, LPABORT, (int) 1);
#endif
g_rdpdr_device[device_id].handle = parallel_fd;
*handle = parallel_fd;
return STATUS_SUCCESS;
}
static NTSTATUS
parallel_close(NTHANDLE handle)
{
int i = get_device_index(handle);
if (i >= 0)
g_rdpdr_device[i].handle = 0;
close(handle);
return STATUS_SUCCESS;
}
static NTSTATUS
parallel_read(NTHANDLE handle, uint8 * data, uint32 length, uint32 offset, uint32 * result)
{
*result = read(handle, data, length);
return STATUS_SUCCESS;
}
static NTSTATUS
parallel_write(NTHANDLE handle, uint8 * data, uint32 length, uint32 offset, uint32 * result)
{
int rc = STATUS_SUCCESS;
int n = write(handle, data, length);
if (n < 0)
{
#if defined(LPGETSTATUS)
int status;
#endif
*result = 0;
switch (errno)
{
case EAGAIN:
rc = STATUS_DEVICE_OFF_LINE;
case ENOSPC:
rc = STATUS_DEVICE_PAPER_EMPTY;
case EIO:
rc = STATUS_DEVICE_OFF_LINE;
default:
rc = STATUS_DEVICE_POWERED_OFF;
}
#if defined(LPGETSTATUS)
if (ioctl(handle, LPGETSTATUS, &status) == 0)
{
/* coming soon: take care for the printer status */
printf("parallel_write: status = %d, errno = %d\n", status, errno);
}
#endif
}
*result = n;
return rc;
}
static NTSTATUS
parallel_device_control(NTHANDLE handle, uint32 request, STREAM in, STREAM out)
{
if ((request >> 16) != FILE_DEVICE_PARALLEL)
return STATUS_INVALID_PARAMETER;
/* extract operation */
request >>= 2;
request &= 0xfff;
printf("PARALLEL IOCTL %d: ", request);
switch (request)
{
case IOCTL_PAR_QUERY_RAW_DEVICE_ID:
default:
printf("\n");
unimpl("UNKNOWN IOCTL %d\n", request);
}
return STATUS_SUCCESS;
}
DEVICE_FNS parallel_fns = {
parallel_create,
parallel_close,
parallel_read,
parallel_write,
parallel_device_control
};
@@ -0,0 +1,95 @@
/*
rdesktop: A Remote Desktop Protocol client.
Parsing primitives
Copyright (C) Matthew Chapman 1999-2005
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* Parser state */
typedef struct stream
{
unsigned char *p;
unsigned char *end;
unsigned char *data;
unsigned int size;
/* Offsets of various headers */
unsigned char *iso_hdr;
unsigned char *mcs_hdr;
unsigned char *sec_hdr;
unsigned char *rdp_hdr;
unsigned char *channel_hdr;
}
*STREAM;
#define s_push_layer(s,h,n) { (s)->h = (s)->p; (s)->p += n; }
#define s_pop_layer(s,h) (s)->p = (s)->h;
#define s_mark_end(s) (s)->end = (s)->p;
#define s_check(s) ((s)->p <= (s)->end)
#define s_check_rem(s,n) ((s)->p + n <= (s)->end)
#define s_check_end(s) ((s)->p == (s)->end)
#if defined(L_ENDIAN) && !defined(NEED_ALIGN)
#define in_uint16_le(s,v) { v = *(uint16 *)((s)->p); (s)->p += 2; }
#define in_uint32_le(s,v) { v = *(uint32 *)((s)->p); (s)->p += 4; }
#define out_uint16_le(s,v) { *(uint16 *)((s)->p) = v; (s)->p += 2; }
#define out_uint32_le(s,v) { *(uint32 *)((s)->p) = v; (s)->p += 4; }
#else
#define in_uint16_le(s,v) { v = *((s)->p++); v += *((s)->p++) << 8; }
#define in_uint32_le(s,v) { in_uint16_le(s,v) \
v += *((s)->p++) << 16; v += *((s)->p++) << 24; }
#define out_uint16_le(s,v) { *((s)->p++) = (v) & 0xff; *((s)->p++) = ((v) >> 8) & 0xff; }
#define out_uint32_le(s,v) { out_uint16_le(s, (v) & 0xffff); out_uint16_le(s, ((v) >> 16) & 0xffff); }
#endif
#if defined(B_ENDIAN) && !defined(NEED_ALIGN)
#define in_uint16_be(s,v) { v = *(uint16 *)((s)->p); (s)->p += 2; }
#define in_uint32_be(s,v) { v = *(uint32 *)((s)->p); (s)->p += 4; }
#define out_uint16_be(s,v) { *(uint16 *)((s)->p) = v; (s)->p += 2; }
#define out_uint32_be(s,v) { *(uint32 *)((s)->p) = v; (s)->p += 4; }
#define B_ENDIAN_PREFERRED
#define in_uint16(s,v) in_uint16_be(s,v)
#define in_uint32(s,v) in_uint32_be(s,v)
#define out_uint16(s,v) out_uint16_be(s,v)
#define out_uint32(s,v) out_uint32_be(s,v)
#else
#define in_uint16_be(s,v) { v = *((s)->p++); next_be(s,v); }
#define in_uint32_be(s,v) { in_uint16_be(s,v); next_be(s,v); next_be(s,v); }
#define out_uint16_be(s,v) { *((s)->p++) = ((v) >> 8) & 0xff; *((s)->p++) = (v) & 0xff; }
#define out_uint32_be(s,v) { out_uint16_be(s, ((v) >> 16) & 0xffff); out_uint16_be(s, (v) & 0xffff); }
#endif
#ifndef B_ENDIAN_PREFERRED
#define in_uint16(s,v) in_uint16_le(s,v)
#define in_uint32(s,v) in_uint32_le(s,v)
#define out_uint16(s,v) out_uint16_le(s,v)
#define out_uint32(s,v) out_uint32_le(s,v)
#endif
#define in_uint8(s,v) v = *((s)->p++);
#define in_uint8p(s,v,n) { v = (s)->p; (s)->p += n; }
#define in_uint8a(s,v,n) { memcpy(v,(s)->p,n); (s)->p += n; }
#define in_uint8s(s,n) (s)->p += n;
#define out_uint8(s,v) *((s)->p++) = v;
#define out_uint8p(s,v,n) { memcpy((s)->p,v,n); (s)->p += n; }
#define out_uint8a(s,v,n) out_uint8p(s,v,n);
#define out_uint8s(s,n) { memset((s)->p,0,n); (s)->p += n; }
#define next_be(s,v) v = ((v) << 8) + *((s)->p++);
@@ -0,0 +1,164 @@
/* -*- c-basic-offset: 8 -*-
rdesktop: A Remote Desktop Protocol client.
Copyright (C) Matthew Chapman 1999-2005
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "rdesktop.h"
extern RDPDR_DEVICE g_rdpdr_device[];
static PRINTER *
get_printer_data(NTHANDLE handle)
{
int index;
for (index = 0; index < RDPDR_MAX_DEVICES; index++)
{
if (handle == g_rdpdr_device[index].handle)
return (PRINTER *) g_rdpdr_device[index].pdevice_data;
}
return NULL;
}
int
printer_enum_devices(uint32 * id, char *optarg)
{
PRINTER *pprinter_data;
char *pos = optarg;
char *pos2;
int count = 0;
int already = 0;
/* we need to know how many printers we've already set up
supplied from other -r flags than this one. */
while (count < *id)
{
if (g_rdpdr_device[count].device_type == DEVICE_TYPE_PRINTER)
already++;
count++;
}
count = 0;
if (*optarg == ':')
optarg++;
while ((pos = next_arg(optarg, ',')) && *id < RDPDR_MAX_DEVICES)
{
pprinter_data = (PRINTER *) xmalloc(sizeof(PRINTER));
strcpy(g_rdpdr_device[*id].name, "PRN");
strcat(g_rdpdr_device[*id].name, l_to_a(already + count + 1, 10));
/* first printer is set as default printer */
if ((already + count) == 0)
pprinter_data->default_printer = True;
else
pprinter_data->default_printer = False;
pos2 = next_arg(optarg, '=');
if (*optarg == (char) 0x00)
pprinter_data->printer = "mydeskjet"; /* set default */
else
{
pprinter_data->printer = xmalloc(strlen(optarg) + 1);
strcpy(pprinter_data->printer, optarg);
}
if (!pos2 || (*pos2 == (char) 0x00))
pprinter_data->driver = "HP Color LaserJet 8500 PS"; /* no printer driver supplied set default */
else
{
pprinter_data->driver = xmalloc(strlen(pos2) + 1);
strcpy(pprinter_data->driver, pos2);
}
printf("PRINTER %s to %s driver %s\n", g_rdpdr_device[*id].name,
pprinter_data->printer, pprinter_data->driver);
g_rdpdr_device[*id].device_type = DEVICE_TYPE_PRINTER;
g_rdpdr_device[*id].pdevice_data = (void *) pprinter_data;
count++;
(*id)++;
optarg = pos;
}
return count;
}
static NTSTATUS
printer_create(uint32 device_id, uint32 access, uint32 share_mode, uint32 disposition, uint32 flags,
char *filename, NTHANDLE * handle)
{
char cmd[256];
PRINTER *pprinter_data;
pprinter_data = (PRINTER *) g_rdpdr_device[device_id].pdevice_data;
/* default printer name use default printer queue as well in unix */
if (pprinter_data->printer == "mydeskjet")
{
pprinter_data->printer_fp = popen("lpr", "w");
}
else
{
sprintf(cmd, "lpr -P %s", pprinter_data->printer);
pprinter_data->printer_fp = popen(cmd, "w");
}
g_rdpdr_device[device_id].handle = fileno(pprinter_data->printer_fp);
*handle = g_rdpdr_device[device_id].handle;
return STATUS_SUCCESS;
}
static NTSTATUS
printer_close(NTHANDLE handle)
{
int i = get_device_index(handle);
if (i >= 0)
{
PRINTER *pprinter_data = g_rdpdr_device[i].pdevice_data;
if (pprinter_data)
pclose(pprinter_data->printer_fp);
g_rdpdr_device[i].handle = 0;
}
return STATUS_SUCCESS;
}
static NTSTATUS
printer_write(NTHANDLE handle, uint8 * data, uint32 length, uint32 offset, uint32 * result)
{
PRINTER *pprinter_data;
pprinter_data = get_printer_data(handle);
*result = length * fwrite(data, length, 1, pprinter_data->printer_fp);
if (ferror(pprinter_data->printer_fp))
{
*result = 0;
return STATUS_INVALID_HANDLE;
}
return STATUS_SUCCESS;
}
DEVICE_FNS printer_fns = {
printer_create,
printer_close,
NULL, /* read */
printer_write,
NULL /* device_control */
};
@@ -0,0 +1,299 @@
/* -*- c-basic-offset: 8 -*-
* rdesktop: A Remote Desktop Protocol client.
* Entrypoint and utility functions
* Copyright (C) Matthew Chapman 1999-2005
* Copyright (C) Jeroen Meijer 2003
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* According to the W2K RDP Printer Redirection WhitePaper, a data
* blob is sent to the client after the configuration of the printer
* is changed at the server.
*
* This data blob is saved to the registry. The client returns this
* data blob in a new session with the printer announce data.
* The data is not interpreted by the client.
*/
#include <sys/stat.h>
#include <sys/types.h>
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include "rdesktop.h"
static BOOL
printercache_mkdir(char *base, char *printer)
{
char *path;
path = (char *) xmalloc(strlen(base) + sizeof("/.rdesktop/rdpdr/") + strlen(printer) + 1);
sprintf(path, "%s/.rdesktop", base);
if ((mkdir(path, 0700) == -1) && errno != EEXIST)
{
perror(path);
xfree(path);
return False;
}
strcat(path, "/rdpdr");
if ((mkdir(path, 0700) == -1) && errno != EEXIST)
{
perror(path);
xfree(path);
return False;
}
strcat(path, "/");
strcat(path, printer);
if ((mkdir(path, 0700) == -1) && errno != EEXIST)
{
perror(path);
xfree(path);
return False;
}
xfree(path);
return True;
}
static BOOL
printercache_unlink_blob(char *printer)
{
char *path;
char *home;
if (printer == NULL)
return False;
home = getenv("HOME");
if (home == NULL)
return False;
path = (char *) xmalloc(strlen(home) + sizeof("/.rdesktop/rdpdr/") + strlen(printer) +
sizeof("/AutoPrinterCacheData") + 1);
sprintf(path, "%s/.rdesktop/rdpdr/%s/AutoPrinterCacheData", home, printer);
if (unlink(path) < 0)
{
xfree(path);
return False;
}
sprintf(path, "%s/.rdesktop/rdpdr/%s", home, printer);
if (rmdir(path) < 0)
{
xfree(path);
return False;
}
xfree(path);
return True;
}
static BOOL
printercache_rename_blob(char *printer, char *new_printer)
{
char *printer_path;
char *new_printer_path;
int printer_maxlen;
char *home;
if (printer == NULL)
return False;
home = getenv("HOME");
if (home == NULL)
return False;
printer_maxlen =
(strlen(printer) >
strlen(new_printer) ? strlen(printer) : strlen(new_printer)) + strlen(home) +
sizeof("/.rdesktop/rdpdr/") + 1;
printer_path = (char *) xmalloc(printer_maxlen);
new_printer_path = (char *) xmalloc(printer_maxlen);
sprintf(printer_path, "%s/.rdesktop/rdpdr/%s", home, printer);
sprintf(new_printer_path, "%s/.rdesktop/rdpdr/%s", home, new_printer);
printf("%s,%s\n", printer_path, new_printer_path);
if (rename(printer_path, new_printer_path) < 0)
{
xfree(printer_path);
xfree(new_printer_path);
return False;
}
xfree(printer_path);
xfree(new_printer_path);
return True;
}
int
printercache_load_blob(char *printer_name, uint8 ** data)
{
char *home, *path;
struct stat st;
int fd, length;
if (printer_name == NULL)
return 0;
*data = NULL;
home = getenv("HOME");
if (home == NULL)
return 0;
path = (char *) xmalloc(strlen(home) + sizeof("/.rdesktop/rdpdr/") + strlen(printer_name) +
sizeof("/AutoPrinterCacheData") + 1);
sprintf(path, "%s/.rdesktop/rdpdr/%s/AutoPrinterCacheData", home, printer_name);
fd = open(path, O_RDONLY);
if (fd == -1)
{
xfree(path);
return 0;
}
if (fstat(fd, &st))
{
xfree(path);
return 0;
}
*data = (uint8 *) xmalloc(st.st_size);
length = read(fd, *data, st.st_size);
close(fd);
xfree(path);
return length;
}
static void
printercache_save_blob(char *printer_name, uint8 * data, uint32 length)
{
char *home, *path;
int fd;
if (printer_name == NULL)
return;
home = getenv("HOME");
if (home == NULL)
return;
if (!printercache_mkdir(home, printer_name))
return;
path = (char *) xmalloc(strlen(home) + sizeof("/.rdesktop/rdpdr/") + strlen(printer_name) +
sizeof("/AutoPrinterCacheData") + 1);
sprintf(path, "%s/.rdesktop/rdpdr/%s/AutoPrinterCacheData", home, printer_name);
fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, 0600);
if (fd == -1)
{
perror(path);
xfree(path);
return;
}
if (write(fd, data, length) != length)
{
perror(path);
unlink(path);
}
close(fd);
xfree(path);
}
void
printercache_process(STREAM s)
{
uint32 type, printer_length, driver_length, printer_unicode_length, blob_length;
char device_name[9], printer[256], driver[256];
in_uint32_le(s, type);
switch (type)
{
case 4: /* rename item */
in_uint8(s, printer_length);
in_uint8s(s, 0x3); /* padding */
in_uint8(s, driver_length);
in_uint8s(s, 0x3); /* padding */
/* NOTE - 'driver' doesn't contain driver, it contains the new printer name */
rdp_in_unistr(s, printer, printer_length);
rdp_in_unistr(s, driver, driver_length);
printercache_rename_blob(printer, driver);
break;
case 3: /* delete item */
in_uint8(s, printer_unicode_length);
in_uint8s(s, 0x3); /* padding */
printer_length = rdp_in_unistr(s, printer, printer_unicode_length);
printercache_unlink_blob(printer);
break;
case 2: /* save printer data */
in_uint32_le(s, printer_unicode_length);
in_uint32_le(s, blob_length);
if (printer_unicode_length < 2 * 255)
{
rdp_in_unistr(s, printer, printer_unicode_length);
printercache_save_blob(printer, s->p, blob_length);
}
break;
case 1: /* save device data */
in_uint8a(s, device_name, 5); /* get LPTx/COMx name */
/* need to fetch this data so that we can get the length of the packet to store. */
in_uint8s(s, 0x2); /* ??? */
in_uint8s(s, 0x2) /* pad?? */
in_uint32_be(s, driver_length);
in_uint32_be(s, printer_length);
in_uint8s(s, 0x7) /* pad?? */
/* next is driver in unicode */
/* next is printer in unicode */
/* TODO: figure out how to use this information when reconnecting */
/* actually - all we need to store is the driver and printer */
/* and figure out what the first word is. */
/* rewind stream so that we can save this blob */
/* length is driver_length + printer_length + 19 */
/* rewind stream */
s->p = s->p - 19;
printercache_save_blob(device_name, s->p,
driver_length + printer_length + 19);
break;
default:
unimpl("RDPDR Printer Cache Packet Type: %d\n", type);
break;
}
}
@@ -0,0 +1,312 @@
/* -*- c-basic-offset: 8 -*-
rdesktop: A Remote Desktop Protocol client.
Copyright (C) Matthew Chapman 1999-2005
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef RDESKTOP_PROTO_H
#define RDESKTOP_PROTO_H
/* *INDENT-OFF* */
#ifdef __cplusplus
extern "C" {
#endif
/* *INDENT-ON* */
/* bitmap.c */
BOOL bitmap_decompress(uint8 * output, int width, int height, uint8 * input, int size, int Bpp);
/* cache.c */
void cache_rebuild_bmpcache_linked_list(uint8 id, sint16 * idx, int count);
void cache_bump_bitmap(uint8 id, uint16 idx, int bump);
void cache_evict_bitmap(uint8 id);
HBITMAP cache_get_bitmap(uint8 id, uint16 idx);
void cache_put_bitmap(uint8 id, uint16 idx, HBITMAP bitmap);
void cache_save_state(void);
FONTGLYPH *cache_get_font(uint8 font, uint16 character);
void cache_put_font(uint8 font, uint16 character, uint16 offset, uint16 baseline, uint16 width,
uint16 height, HGLYPH pixmap);
DATABLOB *cache_get_text(uint8 cache_id);
void cache_put_text(uint8 cache_id, void *data, int length);
uint8 *cache_get_desktop(uint32 offset, int cx, int cy, int bytes_per_pixel);
void cache_put_desktop(uint32 offset, int cx, int cy, int scanline, int bytes_per_pixel,
uint8 * data);
HCURSOR cache_get_cursor(uint16 cache_idx);
void cache_put_cursor(uint16 cache_idx, HCURSOR cursor);
/* channels.c */
VCHANNEL *channel_register(char *name, uint32 flags, void (*callback) (STREAM));
STREAM channel_init(VCHANNEL * channel, uint32 length);
void channel_send(STREAM s, VCHANNEL * channel);
void channel_process(STREAM s, uint16 mcs_channel);
/* cliprdr.c */
void cliprdr_send_simple_native_format_announce(uint32 format);
void cliprdr_send_native_format_announce(uint8 * formats_data, uint32 formats_data_length);
void cliprdr_send_data_request(uint32 format);
void cliprdr_send_data(uint8 * data, uint32 length);
void cliprdr_set_mode(const char *optarg);
BOOL cliprdr_init(void);
/* disk.c */
int disk_enum_devices(uint32 * id, char *optarg);
NTSTATUS disk_query_information(NTHANDLE handle, uint32 info_class, STREAM out);
NTSTATUS disk_set_information(NTHANDLE handle, uint32 info_class, STREAM in, STREAM out);
NTSTATUS disk_check_notify(NTHANDLE handle);
NTSTATUS disk_create_notify(NTHANDLE handle, uint32 info_class);
NTSTATUS disk_query_volume_information(NTHANDLE handle, uint32 info_class, STREAM out);
NTSTATUS disk_query_directory(NTHANDLE handle, uint32 info_class, char *pattern, STREAM out);
/* mppc.c */
int mppc_expand(uint8 * data, uint32 clen, uint8 ctype, uint32 * roff, uint32 * rlen);
/* ewmhints.c */
int get_current_workarea(uint32 * x, uint32 * y, uint32 * width, uint32 * height);
void ewmh_init(void);
/* iso.c */
STREAM iso_init(int length);
void iso_send(STREAM s);
STREAM iso_recv(uint8 * rdpver);
BOOL iso_connect(char *server, char *username);
BOOL iso_reconnect(char *server);
void iso_disconnect(void);
void iso_reset_state(void);
/* licence.c */
void licence_process(STREAM s);
/* mcs.c */
STREAM mcs_init(int length);
void mcs_send_to_channel(STREAM s, uint16 channel);
void mcs_send(STREAM s);
STREAM mcs_recv(uint16 * channel, uint8 * rdpver);
BOOL mcs_connect(char *server, STREAM mcs_data, char *username);
BOOL mcs_reconnect(char *server, STREAM mcs_data);
void mcs_disconnect(void);
void mcs_reset_state(void);
/* orders.c */
void process_orders(STREAM s, uint16 num_orders);
void reset_order_state(void);
/* parallel.c */
int parallel_enum_devices(uint32 * id, char *optarg);
/* printer.c */
int printer_enum_devices(uint32 * id, char *optarg);
/* printercache.c */
int printercache_load_blob(char *printer_name, uint8 ** data);
void printercache_process(STREAM s);
/* pstcache.c */
void pstcache_touch_bitmap(uint8 cache_id, uint16 cache_idx, uint32 stamp);
BOOL pstcache_load_bitmap(uint8 cache_id, uint16 cache_idx);
BOOL pstcache_save_bitmap(uint8 cache_id, uint16 cache_idx, uint8 * key, uint8 width, uint8 height,
uint16 length, uint8 * data);
int pstcache_enumerate(uint8 id, HASH_KEY * keylist);
BOOL pstcache_init(uint8 cache_id);
/* rdesktop.c */
int main(int argc, char *argv[]);
void generate_random(uint8 * random);
void *xmalloc(int size);
char *xstrdup(const char *s);
void *xrealloc(void *oldmem, int size);
void xfree(void *mem);
void error(char *format, ...);
void warning(char *format, ...);
void unimpl(char *format, ...);
void hexdump(unsigned char *p, unsigned int len);
char *next_arg(char *src, char needle);
void toupper_str(char *p);
BOOL str_startswith(const char *s, const char *prefix);
BOOL str_handle_lines(const char *input, char **rest, str_handle_lines_t linehandler, void *data);
BOOL subprocess(char *const argv[], str_handle_lines_t linehandler, void *data);
char *l_to_a(long N, int base);
int load_licence(unsigned char **data);
void save_licence(unsigned char *data, int length);
BOOL rd_pstcache_mkdir(void);
int rd_open_file(char *filename);
void rd_close_file(int fd);
int rd_read_file(int fd, void *ptr, int len);
int rd_write_file(int fd, void *ptr, int len);
int rd_lseek_file(int fd, int offset);
BOOL rd_lock_file(int fd, int start, int len);
/* rdp5.c */
void rdp5_process(STREAM s);
/* rdp.c */
void rdp_out_unistr(STREAM s, char *string, int len);
int rdp_in_unistr(STREAM s, char *string, int uni_len);
void rdp_send_input(uint32 time, uint16 message_type, uint16 device_flags, uint16 param1,
uint16 param2);
void rdp_send_client_window_status(int status);
void process_colour_pointer_pdu(STREAM s);
void process_cached_pointer_pdu(STREAM s);
void process_system_pointer_pdu(STREAM s);
void process_bitmap_updates(STREAM s);
void process_palette(STREAM s);
void process_disconnect_pdu(STREAM s, uint32 * ext_disc_reason);
void rdp_main_loop(BOOL * deactivated, uint32 * ext_disc_reason);
BOOL rdp_loop(BOOL * deactivated, uint32 * ext_disc_reason);
BOOL rdp_connect(char *server, uint32 flags, char *domain, char *password, char *command,
char *directory);
BOOL rdp_reconnect(char *server, uint32 flags, char *domain, char *password, char *command,
char *directory, char *cookie);
void rdp_reset_state(void);
void rdp_disconnect(void);
/* rdpdr.c */
int get_device_index(NTHANDLE handle);
void convert_to_unix_filename(char *filename);
BOOL rdpdr_init(void);
void rdpdr_add_fds(int *n, fd_set * rfds, fd_set * wfds, struct timeval *tv, BOOL * timeout);
struct async_iorequest *rdpdr_remove_iorequest(struct async_iorequest *prev,
struct async_iorequest *iorq);
void rdpdr_check_fds(fd_set * rfds, fd_set * wfds, BOOL timed_out);
BOOL rdpdr_abort_io(uint32 fd, uint32 major, NTSTATUS status);
/* rdpsnd.c */
void rdpsnd_send_completion(uint16 tick, uint8 packet_index);
BOOL rdpsnd_init(void);
/* rdpsnd_oss.c */
BOOL wave_out_open(void);
void wave_out_close(void);
BOOL wave_out_format_supported(WAVEFORMATEX * pwfx);
BOOL wave_out_set_format(WAVEFORMATEX * pwfx);
void wave_out_volume(uint16 left, uint16 right);
void wave_out_write(STREAM s, uint16 tick, uint8 index);
void wave_out_play(void);
/* secure.c */
void sec_hash_48(uint8 * out, uint8 * in, uint8 * salt1, uint8 * salt2, uint8 salt);
void sec_hash_16(uint8 * out, uint8 * in, uint8 * salt1, uint8 * salt2);
void buf_out_uint32(uint8 * buffer, uint32 value);
void sec_sign(uint8 * signature, int siglen, uint8 * session_key, int keylen, uint8 * data,
int datalen);
void sec_decrypt(uint8 * data, int length);
STREAM sec_init(uint32 flags, int maxlen);
void sec_send_to_channel(STREAM s, uint32 flags, uint16 channel);
void sec_send(STREAM s, uint32 flags);
void sec_process_mcs_data(STREAM s);
STREAM sec_recv(uint8 * rdpver);
BOOL sec_connect(char *server, char *username);
BOOL sec_reconnect(char *server);
void sec_disconnect(void);
void sec_reset_state(void);
/* serial.c */
int serial_enum_devices(uint32 * id, char *optarg);
BOOL serial_get_event(NTHANDLE handle, uint32 * result);
BOOL serial_get_timeout(NTHANDLE handle, uint32 length, uint32 * timeout, uint32 * itv_timeout);
/* tcp.c */
STREAM tcp_init(uint32 maxlen);
void tcp_send(STREAM s);
STREAM tcp_recv(STREAM s, uint32 length);
BOOL tcp_connect(char *server);
void tcp_disconnect(void);
char *tcp_get_address(void);
void tcp_reset_state(void);
/* xclip.c */
void ui_clip_format_announce(uint8 * data, uint32 length);
void ui_clip_handle_data(uint8 * data, uint32 length);
void ui_clip_request_failed(void);
void ui_clip_request_data(uint32 format);
void ui_clip_sync(void);
void ui_clip_set_mode(const char *optarg);
void xclip_init(void);
void xclip_deinit(void);
/* xkeymap.c */
BOOL xkeymap_from_locale(const char *locale);
FILE *xkeymap_open(const char *filename);
void xkeymap_init(void);
BOOL handle_special_keys(uint32 keysym, unsigned int state, uint32 ev_time, BOOL pressed);
key_translation xkeymap_translate_key(uint32 keysym, unsigned int keycode, unsigned int state);
void xkeymap_send_keys(uint32 keysym, unsigned int keycode, unsigned int state, uint32 ev_time,
BOOL pressed, uint8 nesting);
uint16 xkeymap_translate_button(unsigned int button);
char *get_ksname(uint32 keysym);
void save_remote_modifiers(uint8 scancode);
void restore_remote_modifiers(uint32 ev_time, uint8 scancode);
void ensure_remote_modifiers(uint32 ev_time, key_translation tr);
unsigned int read_keyboard_state(void);
uint16 ui_get_numlock_state(unsigned int state);
void reset_modifier_keys(void);
void rdp_send_scancode(uint32 time, uint16 flags, uint8 scancode);
/* xwin.c */
BOOL get_key_state(unsigned int state, uint32 keysym);
BOOL ui_init(void);
void ui_deinit(void);
BOOL ui_create_window(void);
void ui_resize_window(void);
void ui_destroy_window(void);
void xwin_toggle_fullscreen(void);
int ui_select(int rdp_socket);
void ui_move_pointer(int x, int y);
HBITMAP ui_create_bitmap(int width, int height, uint8 * data);
void ui_paint_bitmap(int x, int y, int cx, int cy, int width, int height, uint8 * data);
void ui_destroy_bitmap(HBITMAP bmp);
HGLYPH ui_create_glyph(int width, int height, uint8 * data);
void ui_destroy_glyph(HGLYPH glyph);
HCURSOR ui_create_cursor(unsigned int x, unsigned int y, int width, int height, uint8 * andmask,
uint8 * xormask);
void ui_set_cursor(HCURSOR cursor);
void ui_destroy_cursor(HCURSOR cursor);
void ui_set_null_cursor(void);
HCOLOURMAP ui_create_colourmap(COLOURMAP * colours);
void ui_destroy_colourmap(HCOLOURMAP map);
void ui_set_colourmap(HCOLOURMAP map);
void ui_set_clip(int x, int y, int cx, int cy);
void ui_reset_clip(void);
void ui_bell(void);
void ui_destblt(uint8 opcode, int x, int y, int cx, int cy);
void ui_patblt(uint8 opcode, int x, int y, int cx, int cy, BRUSH * brush, int bgcolour,
int fgcolour);
void ui_screenblt(uint8 opcode, int x, int y, int cx, int cy, int srcx, int srcy);
void ui_memblt(uint8 opcode, int x, int y, int cx, int cy, HBITMAP src, int srcx, int srcy);
void ui_triblt(uint8 opcode, int x, int y, int cx, int cy, HBITMAP src, int srcx, int srcy,
BRUSH * brush, int bgcolour, int fgcolour);
void ui_line(uint8 opcode, int startx, int starty, int endx, int endy, PEN * pen);
void ui_rect(int x, int y, int cx, int cy, int colour);
void ui_polygon(uint8 opcode, uint8 fillmode, POINT * point, int npoints, BRUSH * brush,
int bgcolour, int fgcolour);
void ui_polyline(uint8 opcode, POINT * points, int npoints, PEN * pen);
void ui_ellipse(uint8 opcode, uint8 fillmode, int x, int y, int cx, int cy, BRUSH * brush,
int bgcolour, int fgcolour);
void ui_draw_glyph(int mixmode, int x, int y, int cx, int cy, HGLYPH glyph, int srcx, int srcy,
int bgcolour, int fgcolour);
void ui_draw_text(uint8 font, uint8 flags, uint8 opcode, int mixmode, int x, int y, int clipx,
int clipy, int clipcx, int clipcy, int boxx, int boxy, int boxcx, int boxcy,
BRUSH * brush, int bgcolour, int fgcolour, uint8 * text, uint8 length);
void ui_desktop_save(uint32 offset, int x, int y, int cx, int cy);
void ui_desktop_restore(uint32 offset, int x, int y, int cx, int cy);
void ui_begin_update(void);
void ui_end_update(void);
void ui_seamless_begin(BOOL hidden);
void ui_seamless_hide_desktop(void);
void ui_seamless_unhide_desktop(void);
void ui_seamless_toggle(void);
void ui_seamless_create_window(unsigned long id, unsigned long group, unsigned long parent,
unsigned long flags);
void ui_seamless_destroy_window(unsigned long id, unsigned long flags);
void ui_seamless_destroy_group(unsigned long id, unsigned long flags);
void ui_seamless_move_window(unsigned long id, int x, int y, int width, int height,
unsigned long flags);
void ui_seamless_restack_window(unsigned long id, unsigned long behind, unsigned long flags);
void ui_seamless_settitle(unsigned long id, const char *title, unsigned long flags);
void ui_seamless_setstate(unsigned long id, unsigned int state, unsigned long flags);
void ui_seamless_syncbegin(unsigned long flags);
void ui_seamless_ack(unsigned int serial);
/* lspci.c */
BOOL lspci_init(void);
/* seamless.c */
BOOL seamless_init(void);
unsigned int seamless_send_sync(void);
unsigned int seamless_send_state(unsigned long id, unsigned int state, unsigned long flags);
unsigned int seamless_send_position(unsigned long id, int x, int y, int width, int height,
unsigned long flags);
void seamless_select_timeout(struct timeval *tv);
unsigned int seamless_send_zchange(unsigned long id, unsigned long below, unsigned long flags);
unsigned int seamless_send_focus(unsigned long id, unsigned long flags);
/* *INDENT-OFF* */
#ifdef __cplusplus
}
#endif
/* *INDENT-ON* */
#endif
@@ -0,0 +1,27 @@
/* -*- c-basic-offset: 8 -*-
rdesktop: A Remote Desktop Protocol client.
Copyright (C) Matthew Chapman 1999-2005
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef RDESKTOP_PROTO_H
#define RDESKTOP_PROTO_H
/* *INDENT-OFF* */
#ifdef __cplusplus
extern "C" {
#endif
/* *INDENT-ON* */
@@ -0,0 +1,8 @@
/* *INDENT-OFF* */
#ifdef __cplusplus
}
#endif
/* *INDENT-ON* */
#endif
@@ -0,0 +1,200 @@
/* -*- c-basic-offset: 8 -*-
rdesktop: A Remote Desktop Protocol client.
Persistent Bitmap Cache routines
Copyright (C) Jeroen Meijer 2004-2005
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "rdesktop.h"
#define MAX_CELL_SIZE 0x1000 /* pixels */
#define IS_PERSISTENT(id) (id < 8 && g_pstcache_fd[id] > 0)
extern int g_server_depth;
extern BOOL g_bitmap_cache;
extern BOOL g_bitmap_cache_persist_enable;
extern BOOL g_bitmap_cache_precache;
int g_pstcache_fd[8];
int g_pstcache_Bpp;
BOOL g_pstcache_enumerated = False;
uint8 zero_key[] = { 0, 0, 0, 0, 0, 0, 0, 0 };
/* Update mru stamp/index for a bitmap */
void
pstcache_touch_bitmap(uint8 cache_id, uint16 cache_idx, uint32 stamp)
{
int fd;
if (!IS_PERSISTENT(cache_id) || cache_idx >= BMPCACHE2_NUM_PSTCELLS)
return;
fd = g_pstcache_fd[cache_id];
rd_lseek_file(fd, 12 + cache_idx * (g_pstcache_Bpp * MAX_CELL_SIZE + sizeof(CELLHEADER)));
rd_write_file(fd, &stamp, sizeof(stamp));
}
/* Load a bitmap from the persistent cache */
BOOL
pstcache_load_bitmap(uint8 cache_id, uint16 cache_idx)
{
uint8 *celldata;
int fd;
CELLHEADER cellhdr;
HBITMAP bitmap;
if (!g_bitmap_cache_persist_enable)
return False;
if (!IS_PERSISTENT(cache_id) || cache_idx >= BMPCACHE2_NUM_PSTCELLS)
return False;
fd = g_pstcache_fd[cache_id];
rd_lseek_file(fd, cache_idx * (g_pstcache_Bpp * MAX_CELL_SIZE + sizeof(CELLHEADER)));
rd_read_file(fd, &cellhdr, sizeof(CELLHEADER));
celldata = (uint8 *) xmalloc(cellhdr.length);
rd_read_file(fd, celldata, cellhdr.length);
bitmap = ui_create_bitmap(cellhdr.width, cellhdr.height, celldata);
DEBUG(("Load bitmap from disk: id=%d, idx=%d, bmp=0x%x)\n", cache_id, cache_idx, bitmap));
cache_put_bitmap(cache_id, cache_idx, bitmap);
xfree(celldata);
return True;
}
/* Store a bitmap in the persistent cache */
BOOL
pstcache_save_bitmap(uint8 cache_id, uint16 cache_idx, uint8 * key,
uint8 width, uint8 height, uint16 length, uint8 * data)
{
int fd;
CELLHEADER cellhdr;
if (!IS_PERSISTENT(cache_id) || cache_idx >= BMPCACHE2_NUM_PSTCELLS)
return False;
memcpy(cellhdr.key, key, sizeof(HASH_KEY));
cellhdr.width = width;
cellhdr.height = height;
cellhdr.length = length;
cellhdr.stamp = 0;
fd = g_pstcache_fd[cache_id];
rd_lseek_file(fd, cache_idx * (g_pstcache_Bpp * MAX_CELL_SIZE + sizeof(CELLHEADER)));
rd_write_file(fd, &cellhdr, sizeof(CELLHEADER));
rd_write_file(fd, data, length);
return True;
}
/* List the bitmap keys from the persistent cache file */
int
pstcache_enumerate(uint8 id, HASH_KEY * keylist)
{
int fd, n;
uint16 idx;
sint16 mru_idx[0xa00];
uint32 mru_stamp[0xa00];
CELLHEADER cellhdr;
if (!(g_bitmap_cache && g_bitmap_cache_persist_enable && IS_PERSISTENT(id)))
return 0;
/* The server disconnects if the bitmap cache content is sent more than once */
if (g_pstcache_enumerated)
return 0;
DEBUG_RDP5(("Persistent bitmap cache enumeration... "));
for (idx = 0; idx < BMPCACHE2_NUM_PSTCELLS; idx++)
{
fd = g_pstcache_fd[id];
rd_lseek_file(fd, idx * (g_pstcache_Bpp * MAX_CELL_SIZE + sizeof(CELLHEADER)));
if (rd_read_file(fd, &cellhdr, sizeof(CELLHEADER)) <= 0)
break;
if (memcmp(cellhdr.key, zero_key, sizeof(HASH_KEY)) != 0)
{
memcpy(keylist[idx], cellhdr.key, sizeof(HASH_KEY));
/* Pre-cache (not possible for 8 bit colour depth cause it needs a colourmap) */
if (g_bitmap_cache_precache && cellhdr.stamp && g_server_depth > 8)
pstcache_load_bitmap(id, idx);
/* Sort by stamp */
for (n = idx; n > 0 && cellhdr.stamp < mru_stamp[n - 1]; n--)
{
mru_idx[n] = mru_idx[n - 1];
mru_stamp[n] = mru_stamp[n - 1];
}
mru_idx[n] = idx;
mru_stamp[n] = cellhdr.stamp;
}
else
{
break;
}
}
DEBUG_RDP5(("%d cached bitmaps.\n", idx));
cache_rebuild_bmpcache_linked_list(id, mru_idx, idx);
g_pstcache_enumerated = True;
return idx;
}
/* initialise the persistent bitmap cache */
BOOL
pstcache_init(uint8 cache_id)
{
int fd;
char filename[256];
if (g_pstcache_enumerated)
return True;
g_pstcache_fd[cache_id] = 0;
if (!(g_bitmap_cache && g_bitmap_cache_persist_enable))
return False;
if (!rd_pstcache_mkdir())
{
DEBUG(("failed to get/make cache directory!\n"));
return False;
}
g_pstcache_Bpp = (g_server_depth + 7) / 8;
sprintf(filename, "cache/pstcache_%d_%d", cache_id, g_pstcache_Bpp);
DEBUG(("persistent bitmap cache file: %s\n", filename));
fd = rd_open_file(filename);
if (fd == -1)
return False;
if (!rd_lock_file(fd, 0, 0))
{
warning("Persistent bitmap caching is disabled. (The file is already in use)\n");
rd_close_file(fd);
return False;
}
g_pstcache_fd[cache_id] = fd;
return True;
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,119 @@
/*
rdesktop: A Remote Desktop Protocol client.
Master include file
Copyright (C) Matthew Chapman 1999-2005
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <dirent.h>
#include <sys/time.h>
#ifdef HAVE_SYS_SELECT_H
#include <sys/select.h>
#else
#include <sys/types.h>
#include <unistd.h>
#endif
#include <limits.h> /* PATH_MAX */
#define VERSION "1.4.1"
#ifdef WITH_DEBUG
#define DEBUG(args) printf args;
#else
#define DEBUG(args)
#endif
#ifdef WITH_DEBUG_KBD
#define DEBUG_KBD(args) printf args;
#else
#define DEBUG_KBD(args)
#endif
#ifdef WITH_DEBUG_RDP5
#define DEBUG_RDP5(args) printf args;
#else
#define DEBUG_RDP5(args)
#endif
#ifdef WITH_DEBUG_CLIPBOARD
#define DEBUG_CLIPBOARD(args) printf args;
#else
#define DEBUG_CLIPBOARD(args)
#endif
#ifdef WITH_DEBUG_CHANNEL
#define DEBUG_CHANNEL(args) printf args;
#else
#define DEBUG_CHANNEL(args)
#endif
#define STRNCPY(dst,src,n) { strncpy(dst,src,n-1); dst[n-1] = 0; }
#ifndef MIN
#define MIN(x,y) (((x) < (y)) ? (x) : (y))
#endif
#ifndef MAX
#define MAX(x,y) (((x) > (y)) ? (x) : (y))
#endif
/* timeval macros */
#ifndef timerisset
#define timerisset(tvp)\
((tvp)->tv_sec || (tvp)->tv_usec)
#endif
#ifndef timercmp
#define timercmp(tvp, uvp, cmp)\
((tvp)->tv_sec cmp (uvp)->tv_sec ||\
(tvp)->tv_sec == (uvp)->tv_sec &&\
(tvp)->tv_usec cmp (uvp)->tv_usec)
#endif
#ifndef timerclear
#define timerclear(tvp)\
((tvp)->tv_sec = (tvp)->tv_usec = 0)
#endif
/* If configure does not define the endianess, try
to find it out */
#if !defined(L_ENDIAN) && !defined(B_ENDIAN)
#if __BYTE_ORDER == __LITTLE_ENDIAN
#define L_ENDIAN
#elif __BYTE_ORDER == __BIG_ENDIAN
#define B_ENDIAN
#else
#error Unknown endianness. Edit rdesktop.h.
#endif
#endif /* B_ENDIAN, L_ENDIAN from configure */
/* No need for alignment on x86 and amd64 */
#if !defined(NEED_ALIGN)
#if !(defined(__x86__) || defined(__x86_64__) || \
defined(__AMD64__) || defined(_M_IX86) || \
defined(__i386__))
#define NEED_ALIGN
#endif
#endif
#include "parse.h"
#include "constants.h"
#include "types.h"
#ifndef MAKE_PROTO
#include "proto.h"
#endif
@@ -0,0 +1,40 @@
Summary: Remote Desktop Protocol client
Name: rdesktop
Version: 1.4.1
Release: 1
Copyright: GPL; see COPYING
Group: Applications/Communications
Source: rdesktop-%{version}.tar.gz
BuildRoot: %{_tmppath}/%{name}-buildroot
Packager: Peter Åstrand <[email protected]>
%description
rdesktop is a client for Remote Desktop Protocol (RDP), used in a number of
Microsoft products including Windows NT Terminal Server, Windows 2000 Server,
Windows XP and Windows 2003 Server.
%prep
rm -rf $RPM_BUILD_ROOT
%setup
%build
./configure --prefix=%{_prefix} --bindir=%{_bindir} --mandir=%{_mandir}
make
%install
make install DESTDIR=$RPM_BUILD_ROOT
%files
%defattr(-,root,root)
%doc COPYING doc/AUTHORS doc/keymapping.txt doc/keymap-names.txt doc/ipv6.txt doc/ChangeLog
%{_bindir}/rdesktop
%{_mandir}/man1/rdesktop.1*
%{_datadir}/rdesktop/keymaps
%post
%postun
%clean
rm -rf $RPM_BUILD_ROOT
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,121 @@
/* -*- c-basic-offset: 8 -*-
rdesktop: A Remote Desktop Protocol client.
Protocol services - RDP5 short form PDU processing
Copyright (C) Matthew Chapman 1999-2005
Copyright (C) Erik Forsberg 2003
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "rdesktop.h"
extern uint8 *g_next_packet;
extern RDPCOMP g_mppc_dict;
void
rdp5_process(STREAM s)
{
uint16 length, count, x, y;
uint8 type, ctype;
uint8 *next;
uint32 roff, rlen;
struct stream *ns = &(g_mppc_dict.ns);
struct stream *ts;
#if 0
printf("RDP5 data:\n");
hexdump(s->p, s->end - s->p);
#endif
ui_begin_update();
while (s->p < s->end)
{
in_uint8(s, type);
if (type & RDP5_COMPRESSED)
{
in_uint8(s, ctype);
in_uint16_le(s, length);
type ^= RDP5_COMPRESSED;
}
else
{
ctype = 0;
in_uint16_le(s, length);
}
g_next_packet = next = s->p + length;
if (ctype & RDP_MPPC_COMPRESSED)
{
if (mppc_expand(s->p, length, ctype, &roff, &rlen) == -1)
error("error while decompressing packet\n");
/* allocate memory and copy the uncompressed data into the temporary stream */
ns->data = (uint8 *) xrealloc(ns->data, rlen);
memcpy((ns->data), (unsigned char *) (g_mppc_dict.hist + roff), rlen);
ns->size = rlen;
ns->end = (ns->data + ns->size);
ns->p = ns->data;
ns->rdp_hdr = ns->p;
ts = ns;
}
else
ts = s;
switch (type)
{
case 0: /* update orders */
in_uint16_le(ts, count);
process_orders(ts, count);
break;
case 1: /* update bitmap */
in_uint8s(ts, 2); /* part length */
process_bitmap_updates(ts);
break;
case 2: /* update palette */
in_uint8s(ts, 2); /* uint16 = 2 */
process_palette(ts);
break;
case 3: /* update synchronize */
break;
case 5: /* null pointer */
ui_set_null_cursor();
break;
case 6: /* default pointer */
break;
case 8: /* pointer position */
in_uint16_le(ts, x);
in_uint16_le(ts, y);
if (s_check(ts))
ui_move_pointer(x, y);
break;
case 9: /* color pointer */
process_colour_pointer_pdu(ts);
break;
case 10: /* cached pointer */
process_cached_pointer_pdu(ts);
break;
default:
unimpl("RDP5 opcode %d\n", type);
}
s->p = next;
}
ui_end_update();
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,264 @@
/* -*- c-basic-offset: 8 -*-
rdesktop: A Remote Desktop Protocol client.
Sound Channel Process Functions
Copyright (C) Matthew Chapman 2003
Copyright (C) GuoJunBo [email protected] 2003
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "rdesktop.h"
#define RDPSND_CLOSE 1
#define RDPSND_WRITE 2
#define RDPSND_SET_VOLUME 3
#define RDPSND_UNKNOWN4 4
#define RDPSND_COMPLETION 5
#define RDPSND_SERVERTICK 6
#define RDPSND_NEGOTIATE 7
#define MAX_FORMATS 10
static VCHANNEL *rdpsnd_channel;
static BOOL device_open;
static WAVEFORMATEX formats[MAX_FORMATS];
static unsigned int format_count;
static unsigned int current_format;
static STREAM
rdpsnd_init_packet(uint16 type, uint16 size)
{
STREAM s;
s = channel_init(rdpsnd_channel, size + 4);
out_uint16_le(s, type);
out_uint16_le(s, size);
return s;
}
static void
rdpsnd_send(STREAM s)
{
#ifdef RDPSND_DEBUG
printf("RDPSND send:\n");
hexdump(s->channel_hdr + 8, s->end - s->channel_hdr - 8);
#endif
channel_send(s, rdpsnd_channel);
}
void
rdpsnd_send_completion(uint16 tick, uint8 packet_index)
{
STREAM s;
s = rdpsnd_init_packet(RDPSND_COMPLETION, 4);
out_uint16_le(s, tick + 50);
out_uint8(s, packet_index);
out_uint8(s, 0);
s_mark_end(s);
rdpsnd_send(s);
}
static void
rdpsnd_process_negotiate(STREAM in)
{
unsigned int in_format_count, i;
WAVEFORMATEX *format;
STREAM out;
BOOL device_available = False;
int readcnt;
int discardcnt;
in_uint8s(in, 14); /* flags, volume, pitch, UDP port */
in_uint16_le(in, in_format_count);
in_uint8s(in, 4); /* pad, status, pad */
if (wave_out_open())
{
wave_out_close();
device_available = True;
}
format_count = 0;
if (s_check_rem(in, 18 * in_format_count))
{
for (i = 0; i < in_format_count; i++)
{
format = &formats[format_count];
in_uint16_le(in, format->wFormatTag);
in_uint16_le(in, format->nChannels);
in_uint32_le(in, format->nSamplesPerSec);
in_uint32_le(in, format->nAvgBytesPerSec);
in_uint16_le(in, format->nBlockAlign);
in_uint16_le(in, format->wBitsPerSample);
in_uint16_le(in, format->cbSize);
/* read in the buffer of unknown use */
readcnt = format->cbSize;
discardcnt = 0;
if (format->cbSize > MAX_CBSIZE)
{
fprintf(stderr, "cbSize too large for buffer: %d\n",
format->cbSize);
readcnt = MAX_CBSIZE;
discardcnt = format->cbSize - MAX_CBSIZE;
}
in_uint8a(in, format->cb, readcnt);
in_uint8s(in, discardcnt);
if (device_available && wave_out_format_supported(format))
{
format_count++;
if (format_count == MAX_FORMATS)
break;
}
}
}
out = rdpsnd_init_packet(RDPSND_NEGOTIATE | 0x200, 20 + 18 * format_count);
out_uint32_le(out, 3); /* flags */
out_uint32(out, 0xffffffff); /* volume */
out_uint32(out, 0); /* pitch */
out_uint16(out, 0); /* UDP port */
out_uint16_le(out, format_count);
out_uint8(out, 0x95); /* pad? */
out_uint16_le(out, 2); /* status */
out_uint8(out, 0x77); /* pad? */
for (i = 0; i < format_count; i++)
{
format = &formats[i];
out_uint16_le(out, format->wFormatTag);
out_uint16_le(out, format->nChannels);
out_uint32_le(out, format->nSamplesPerSec);
out_uint32_le(out, format->nAvgBytesPerSec);
out_uint16_le(out, format->nBlockAlign);
out_uint16_le(out, format->wBitsPerSample);
out_uint16(out, 0); /* cbSize */
}
s_mark_end(out);
rdpsnd_send(out);
}
static void
rdpsnd_process_servertick(STREAM in)
{
uint16 tick1, tick2;
STREAM out;
/* in_uint8s(in, 4); unknown */
in_uint16_le(in, tick1);
in_uint16_le(in, tick2);
out = rdpsnd_init_packet(RDPSND_SERVERTICK | 0x2300, 4);
out_uint16_le(out, tick1);
out_uint16_le(out, tick2);
s_mark_end(out);
rdpsnd_send(out);
}
static void
rdpsnd_process(STREAM s)
{
uint8 type;
uint16 datalen;
uint32 volume;
static uint16 tick, format;
static uint8 packet_index;
static BOOL awaiting_data_packet;
#ifdef RDPSND_DEBUG
printf("RDPSND recv:\n");
hexdump(s->p, s->end - s->p);
#endif
if (awaiting_data_packet)
{
if (format >= MAX_FORMATS)
{
error("RDPSND: Invalid format index\n");
return;
}
if (!device_open || (format != current_format))
{
if (!device_open && !wave_out_open())
{
rdpsnd_send_completion(tick, packet_index);
return;
}
if (!wave_out_set_format(&formats[format]))
{
rdpsnd_send_completion(tick, packet_index);
wave_out_close();
device_open = False;
return;
}
device_open = True;
current_format = format;
}
wave_out_write(s, tick, packet_index);
awaiting_data_packet = False;
return;
}
in_uint8(s, type);
in_uint8s(s, 1); /* unknown? */
in_uint16_le(s, datalen);
switch (type)
{
case RDPSND_WRITE:
in_uint16_le(s, tick);
in_uint16_le(s, format);
in_uint8(s, packet_index);
awaiting_data_packet = True;
break;
case RDPSND_CLOSE:
wave_out_close();
device_open = False;
break;
case RDPSND_NEGOTIATE:
rdpsnd_process_negotiate(s);
break;
case RDPSND_SERVERTICK:
rdpsnd_process_servertick(s);
break;
case RDPSND_SET_VOLUME:
in_uint32(s, volume);
if (device_open)
{
wave_out_volume((volume & 0xffff), (volume & 0xffff0000) >> 16);
}
break;
default:
unimpl("RDPSND packet type %d\n", type);
break;
}
}
BOOL
rdpsnd_init(void)
{
rdpsnd_channel =
channel_register("rdpsnd", CHANNEL_OPTION_INITIALIZED | CHANNEL_OPTION_ENCRYPT_RDP,
rdpsnd_process);
return (rdpsnd_channel != NULL);
}
@@ -0,0 +1,273 @@
/* -*- c-basic-offset: 8 -*-
rdesktop: A Remote Desktop Protocol client.
Sound Channel Process Functions - libao-driver
Copyright (C) Matthew Chapman 2003
Copyright (C) GuoJunBo [email protected] 2003
Copyright (C) Michael Gernoth [email protected] 2005
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "rdesktop.h"
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <ao/ao.h>
#include <sys/time.h>
#define MAX_QUEUE 10
#define WAVEOUTBUF 16
int g_dsp_fd;
ao_device *o_device = NULL;
int default_driver;
int g_samplerate;
int g_channels;
BOOL g_dsp_busy = False;
static BOOL g_reopened;
static short g_samplewidth;
static struct audio_packet
{
struct stream s;
uint16 tick;
uint8 index;
} packet_queue[MAX_QUEUE];
static unsigned int queue_hi, queue_lo;
BOOL
wave_out_open(void)
{
ao_sample_format format;
ao_initialize();
default_driver = ao_default_driver_id();
format.bits = 16;
format.channels = 2;
g_channels = 2;
format.rate = 44100;
g_samplerate = 44100;
format.byte_format = AO_FMT_LITTLE;
o_device = ao_open_live(default_driver, &format, NULL);
if (o_device == NULL)
{
return False;
}
g_dsp_fd = 0;
queue_lo = queue_hi = 0;
g_reopened = True;
return True;
}
void
wave_out_close(void)
{
/* Ack all remaining packets */
while (queue_lo != queue_hi)
{
rdpsnd_send_completion(packet_queue[queue_lo].tick, packet_queue[queue_lo].index);
free(packet_queue[queue_lo].s.data);
queue_lo = (queue_lo + 1) % MAX_QUEUE;
}
if (o_device != NULL)
ao_close(o_device);
ao_shutdown();
}
BOOL
wave_out_format_supported(WAVEFORMATEX * pwfx)
{
if (pwfx->wFormatTag != WAVE_FORMAT_PCM)
return False;
if ((pwfx->nChannels != 1) && (pwfx->nChannels != 2))
return False;
if ((pwfx->wBitsPerSample != 8) && (pwfx->wBitsPerSample != 16))
return False;
/* The only common denominator between libao output drivers is a sample-rate of
44100, we need to upsample 22050 to it */
if ((pwfx->nSamplesPerSec != 44100) && (pwfx->nSamplesPerSec != 22050))
return False;
return True;
}
BOOL
wave_out_set_format(WAVEFORMATEX * pwfx)
{
ao_sample_format format;
format.bits = pwfx->wBitsPerSample;
format.channels = pwfx->nChannels;
g_channels = pwfx->nChannels;
format.rate = 44100;
g_samplerate = pwfx->nSamplesPerSec;
format.byte_format = AO_FMT_LITTLE;
g_samplewidth = pwfx->wBitsPerSample / 8;
if (o_device != NULL)
ao_close(o_device);
o_device = ao_open_live(default_driver, &format, NULL);
if (o_device == NULL)
{
return False;
}
g_reopened = True;
return True;
}
void
wave_out_volume(uint16 left, uint16 right)
{
warning("volume changes not supported with libao-output\n");
}
void
wave_out_write(STREAM s, uint16 tick, uint8 index)
{
struct audio_packet *packet = &packet_queue[queue_hi];
unsigned int next_hi = (queue_hi + 1) % MAX_QUEUE;
if (next_hi == queue_lo)
{
error("No space to queue audio packet\n");
return;
}
queue_hi = next_hi;
packet->s = *s;
packet->tick = tick;
packet->index = index;
packet->s.p += 4;
/* we steal the data buffer from s, give it a new one */
s->data = malloc(s->size);
if (!g_dsp_busy)
wave_out_play();
}
void
wave_out_play(void)
{
struct audio_packet *packet;
STREAM out;
char outbuf[WAVEOUTBUF];
int offset, len, i;
static long prev_s, prev_us;
unsigned int duration;
struct timeval tv;
int next_tick;
if (g_reopened)
{
g_reopened = False;
gettimeofday(&tv, NULL);
prev_s = tv.tv_sec;
prev_us = tv.tv_usec;
}
if (queue_lo == queue_hi)
{
g_dsp_busy = 0;
return;
}
packet = &packet_queue[queue_lo];
out = &packet->s;
if (((queue_lo + 1) % MAX_QUEUE) != queue_hi)
{
next_tick = packet_queue[(queue_lo + 1) % MAX_QUEUE].tick;
}
else
{
next_tick = (packet->tick + 65535) % 65536;
}
len = 0;
if (g_samplerate == 22050)
{
/* Resample to 44100 */
for (i = 0; (i < ((WAVEOUTBUF / 4) * (3 - g_samplewidth))) && (out->p < out->end);
i++)
{
/* On a stereo-channel we must make sure that left and right
does not get mixed up, so we need to expand the sample-
data with channels in mind: 1234 -> 12123434
If we have a mono-channel, we can expand the data by simply
doubling the sample-data: 1234 -> 11223344 */
if (g_channels == 2)
offset = ((i * 2) - (i & 1)) * g_samplewidth;
else
offset = (i * 2) * g_samplewidth;
memcpy(&outbuf[offset], out->p, g_samplewidth);
memcpy(&outbuf[g_channels * g_samplewidth + offset], out->p, g_samplewidth);
out->p += g_samplewidth;
len += 2 * g_samplewidth;
}
}
else
{
len = (WAVEOUTBUF > (out->end - out->p)) ? (out->end - out->p) : WAVEOUTBUF;
memcpy(outbuf, out->p, len);
out->p += len;
}
ao_play(o_device, outbuf, len);
gettimeofday(&tv, NULL);
duration = ((tv.tv_sec - prev_s) * 1000000 + (tv.tv_usec - prev_us)) / 1000;
if (packet->tick > next_tick)
next_tick += 65536;
if ((out->p == out->end) || duration > next_tick - packet->tick + 500)
{
prev_s = tv.tv_sec;
prev_us = tv.tv_usec;
if (abs((next_tick - packet->tick) - duration) > 20)
{
DEBUG(("duration: %d, calc: %d, ", duration, next_tick - packet->tick));
DEBUG(("last: %d, is: %d, should: %d\n", packet->tick,
(packet->tick + duration) % 65536, next_tick % 65536));
}
/* Until all drivers are using the windows sound-ticks, we need to
substract the 50 ticks added later by rdpsnd.c */
rdpsnd_send_completion(((packet->tick + duration) % 65536) - 50, packet->index);
free(out->data);
queue_lo = (queue_lo + 1) % MAX_QUEUE;
}
g_dsp_busy = 1;
return;
}
@@ -0,0 +1,319 @@
/* -*- c-basic-offset: 8 -*-
rdesktop: A Remote Desktop Protocol client.
Sound Channel Process Functions - Open Sound System
Copyright (C) Matthew Chapman 2003
Copyright (C) GuoJunBo [email protected] 2003
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/*
This is a workaround for Esound bug 312665.
FIXME: Remove this when Esound is fixed.
*/
#ifdef _FILE_OFFSET_BITS
#undef _FILE_OFFSET_BITS
#endif
#include "rdesktop.h"
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/time.h>
#include <sys/ioctl.h>
#include <sys/soundcard.h>
#define MAX_QUEUE 10
int g_dsp_fd;
BOOL g_dsp_busy = False;
static int g_snd_rate;
static short g_samplewidth;
static BOOL g_driver_broken = False;
static struct audio_packet
{
struct stream s;
uint16 tick;
uint8 index;
} packet_queue[MAX_QUEUE];
static unsigned int queue_hi, queue_lo;
BOOL
wave_out_open(void)
{
char *dsp_dev = getenv("AUDIODEV");
if (dsp_dev == NULL)
{
dsp_dev = xstrdup("/dev/dsp");
}
if ((g_dsp_fd = open(dsp_dev, O_WRONLY | O_NONBLOCK)) == -1)
{
perror(dsp_dev);
return False;
}
/* Non-blocking so that user interface is responsive */
fcntl(g_dsp_fd, F_SETFL, fcntl(g_dsp_fd, F_GETFL) | O_NONBLOCK);
return True;
}
void
wave_out_close(void)
{
close(g_dsp_fd);
}
BOOL
wave_out_format_supported(WAVEFORMATEX * pwfx)
{
if (pwfx->wFormatTag != WAVE_FORMAT_PCM)
return False;
if ((pwfx->nChannels != 1) && (pwfx->nChannels != 2))
return False;
if ((pwfx->wBitsPerSample != 8) && (pwfx->wBitsPerSample != 16))
return False;
return True;
}
BOOL
wave_out_set_format(WAVEFORMATEX * pwfx)
{
int stereo, format, fragments;
ioctl(g_dsp_fd, SNDCTL_DSP_RESET, NULL);
ioctl(g_dsp_fd, SNDCTL_DSP_SYNC, NULL);
if (pwfx->wBitsPerSample == 8)
format = AFMT_U8;
else if (pwfx->wBitsPerSample == 16)
format = AFMT_S16_LE;
g_samplewidth = pwfx->wBitsPerSample / 8;
if (ioctl(g_dsp_fd, SNDCTL_DSP_SETFMT, &format) == -1)
{
perror("SNDCTL_DSP_SETFMT");
close(g_dsp_fd);
return False;
}
if (pwfx->nChannels == 2)
{
stereo = 1;
g_samplewidth *= 2;
}
else
{
stereo = 0;
}
if (ioctl(g_dsp_fd, SNDCTL_DSP_STEREO, &stereo) == -1)
{
perror("SNDCTL_DSP_CHANNELS");
close(g_dsp_fd);
return False;
}
g_snd_rate = pwfx->nSamplesPerSec;
if (ioctl(g_dsp_fd, SNDCTL_DSP_SPEED, &g_snd_rate) == -1)
{
perror("SNDCTL_DSP_SPEED");
close(g_dsp_fd);
return False;
}
/* try to get 7 fragments of 2^12 bytes size */
fragments = (7 << 16) + 12;
ioctl(g_dsp_fd, SNDCTL_DSP_SETFRAGMENT, &fragments);
if (!g_driver_broken)
{
audio_buf_info info;
memset(&info, 0, sizeof(info));
if (ioctl(g_dsp_fd, SNDCTL_DSP_GETOSPACE, &info) == -1)
{
perror("SNDCTL_DSP_GETOSPACE");
close(g_dsp_fd);
return False;
}
if (info.fragments == 0 || info.fragstotal == 0 || info.fragsize == 0)
{
fprintf(stderr,
"Broken OSS-driver detected: fragments: %d, fragstotal: %d, fragsize: %d\n",
info.fragments, info.fragstotal, info.fragsize);
g_driver_broken = True;
}
}
return True;
}
void
wave_out_volume(uint16 left, uint16 right)
{
static BOOL use_dev_mixer = False;
uint32 volume;
int fd_mix = -1;
volume = left / (65536 / 100);
volume |= right / (65536 / 100) << 8;
if (use_dev_mixer)
{
if ((fd_mix = open("/dev/mixer", O_RDWR | O_NONBLOCK)) == -1)
{
perror("open /dev/mixer");
return;
}
if (ioctl(fd_mix, MIXER_WRITE(SOUND_MIXER_PCM), &volume) == -1)
{
perror("MIXER_WRITE(SOUND_MIXER_PCM)");
return;
}
close(fd_mix);
}
if (ioctl(g_dsp_fd, MIXER_WRITE(SOUND_MIXER_PCM), &volume) == -1)
{
perror("MIXER_WRITE(SOUND_MIXER_PCM)");
use_dev_mixer = True;
return;
}
}
void
wave_out_write(STREAM s, uint16 tick, uint8 index)
{
struct audio_packet *packet = &packet_queue[queue_hi];
unsigned int next_hi = (queue_hi + 1) % MAX_QUEUE;
if (next_hi == queue_lo)
{
error("No space to queue audio packet\n");
return;
}
queue_hi = next_hi;
packet->s = *s;
packet->tick = tick;
packet->index = index;
packet->s.p += 4;
/* we steal the data buffer from s, give it a new one */
s->data = (uint8 *) malloc(s->size);
if (!g_dsp_busy)
wave_out_play();
}
void
wave_out_play(void)
{
struct audio_packet *packet;
ssize_t len;
STREAM out;
static long startedat_us;
static long startedat_s;
static BOOL started = False;
struct timeval tv;
audio_buf_info info;
while (1)
{
if (queue_lo == queue_hi)
{
g_dsp_busy = 0;
return;
}
packet = &packet_queue[queue_lo];
out = &packet->s;
if (!started)
{
gettimeofday(&tv, NULL);
startedat_us = tv.tv_usec;
startedat_s = tv.tv_sec;
started = True;
}
len = out->end - out->p;
if (!g_driver_broken)
{
memset(&info, 0, sizeof(info));
if (ioctl(g_dsp_fd, SNDCTL_DSP_GETOSPACE, &info) == -1)
{
perror("SNDCTL_DSP_GETOSPACE");
return;
}
if (info.fragments == 0)
{
g_dsp_busy = 1;
return;
}
if (info.fragments * info.fragsize < len
&& info.fragments * info.fragsize > 0)
{
len = info.fragments * info.fragsize;
}
}
len = write(g_dsp_fd, out->p, len);
if (len == -1)
{
if (errno != EWOULDBLOCK)
perror("write audio");
g_dsp_busy = 1;
return;
}
out->p += len;
if (out->p == out->end)
{
long long duration;
long elapsed;
gettimeofday(&tv, NULL);
duration = (out->size * (1000000 / (g_samplewidth * g_snd_rate)));
elapsed = (tv.tv_sec - startedat_s) * 1000000 + (tv.tv_usec - startedat_us);
if (elapsed >= (duration * 85) / 100)
{
rdpsnd_send_completion(packet->tick, packet->index);
free(out->data);
queue_lo = (queue_lo + 1) % MAX_QUEUE;
started = False;
}
else
{
g_dsp_busy = 1;
return;
}
}
}
}
@@ -0,0 +1,340 @@
/* -*- c-basic-offset: 8 -*-
rdesktop: A Remote Desktop Protocol client.
Sound Channel Process Functions - SGI/IRIX
Copyright (C) Matthew Chapman 2003
Copyright (C) GuoJunBo [email protected] 2003
Copyright (C) Jeremy Meng [email protected] 2004, 2005
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "rdesktop.h"
#include <errno.h>
#include <dmedia/audio.h>
/* #define IRIX_DEBUG 1 */
#define IRIX_MAX_VOL 65535
#define MAX_QUEUE 10
int g_dsp_fd;
ALconfig audioconfig;
ALport output_port;
BOOL g_dsp_busy = False;
static BOOL g_swapaudio;
static int g_snd_rate;
static BOOL g_swapaudio;
static int width = AL_SAMPLE_16;
double min_volume, max_volume, volume_range;
int resource, maxFillable;
int combinedFrameSize;
static struct audio_packet
{
struct stream s;
uint16 tick;
uint8 index;
} packet_queue[MAX_QUEUE];
static unsigned int queue_hi, queue_lo;
BOOL
wave_out_open(void)
{
ALparamInfo pinfo;
#if (defined(IRIX_DEBUG))
fprintf(stderr, "wave_out_open: begin\n");
#endif
if (alGetParamInfo(AL_DEFAULT_OUTPUT, AL_GAIN, &pinfo) < 0)
{
fprintf(stderr, "wave_out_open: alGetParamInfo failed: %s\n",
alGetErrorString(oserror()));
}
min_volume = alFixedToDouble(pinfo.min.ll);
max_volume = alFixedToDouble(pinfo.max.ll);
volume_range = (max_volume - min_volume);
#if (defined(IRIX_DEBUG))
fprintf(stderr, "wave_out_open: minvol = %lf, maxvol= %lf, range = %lf.\n",
min_volume, max_volume, volume_range);
#endif
queue_lo = queue_hi = 0;
audioconfig = alNewConfig();
if (audioconfig == (ALconfig) 0)
{
fprintf(stderr, "wave_out_open: alNewConfig failed: %s\n",
alGetErrorString(oserror()));
return False;
}
output_port = alOpenPort("rdpsnd", "w", 0);
if (output_port == (ALport) 0)
{
fprintf(stderr, "wave_out_open: alOpenPort failed: %s\n",
alGetErrorString(oserror()));
return False;
}
#if (defined(IRIX_DEBUG))
fprintf(stderr, "wave_out_open: returning\n");
#endif
return True;
}
void
wave_out_close(void)
{
/* Ack all remaining packets */
#if (defined(IRIX_DEBUG))
fprintf(stderr, "wave_out_close: begin\n");
#endif
while (queue_lo != queue_hi)
{
rdpsnd_send_completion(packet_queue[queue_lo].tick, packet_queue[queue_lo].index);
free(packet_queue[queue_lo].s.data);
queue_lo = (queue_lo + 1) % MAX_QUEUE;
}
alDiscardFrames(output_port, 0);
alClosePort(output_port);
alFreeConfig(audioconfig);
#if (defined(IRIX_DEBUG))
fprintf(stderr, "wave_out_close: returning\n");
#endif
}
BOOL
wave_out_format_supported(WAVEFORMATEX * pwfx)
{
if (pwfx->wFormatTag != WAVE_FORMAT_PCM)
return False;
if ((pwfx->nChannels != 1) && (pwfx->nChannels != 2))
return False;
if ((pwfx->wBitsPerSample != 8) && (pwfx->wBitsPerSample != 16))
return False;
return True;
}
BOOL
wave_out_set_format(WAVEFORMATEX * pwfx)
{
int channels;
int frameSize, channelCount;
ALpv params;
#if (defined(IRIX_DEBUG))
fprintf(stderr, "wave_out_set_format: init...\n");
#endif
g_swapaudio = False;
if (pwfx->wBitsPerSample == 8)
width = AL_SAMPLE_8;
else if (pwfx->wBitsPerSample == 16)
{
width = AL_SAMPLE_16;
/* Do we need to swap the 16bit values? (Are we BigEndian) */
#if (defined(B_ENDIAN))
g_swapaudio = 1;
#else
g_swapaudio = 0;
#endif
}
/* Limited support to configure an opened audio port in IRIX. The
number of channels is a static setting and can not be changed after
a port is opened. So if the number of channels remains the same, we
can configure other settings; otherwise we have to reopen the audio
port, using same config. */
channels = pwfx->nChannels;
g_snd_rate = pwfx->nSamplesPerSec;
alSetSampFmt(audioconfig, AL_SAMPFMT_TWOSCOMP);
alSetWidth(audioconfig, width);
if (channels != alGetChannels(audioconfig))
{
alClosePort(output_port);
alSetChannels(audioconfig, channels);
output_port = alOpenPort("rdpsnd", "w", audioconfig);
if (output_port == (ALport) 0)
{
fprintf(stderr, "wave_out_set_format: alOpenPort failed: %s\n",
alGetErrorString(oserror()));
return False;
}
}
resource = alGetResource(output_port);
maxFillable = alGetFillable(output_port);
channelCount = alGetChannels(audioconfig);
frameSize = alGetWidth(audioconfig);
if (frameSize == 0 || channelCount == 0)
{
fprintf(stderr, "wave_out_set_format: bad frameSize or channelCount\n");
return False;
}
combinedFrameSize = frameSize * channelCount;
params.param = AL_RATE;
params.value.ll = (long long) g_snd_rate << 32;
if (alSetParams(resource, &params, 1) < 0)
{
fprintf(stderr, "wave_set_format: alSetParams failed: %s\n",
alGetErrorString(oserror()));
return False;
}
if (params.sizeOut < 0)
{
fprintf(stderr, "wave_set_format: invalid rate %d\n", g_snd_rate);
return False;
}
#if (defined(IRIX_DEBUG))
fprintf(stderr, "wave_out_set_format: returning...\n");
#endif
return True;
}
void
wave_out_volume(uint16 left, uint16 right)
{
double gainleft, gainright;
ALpv pv[1];
ALfixed gain[8];
#if (defined(IRIX_DEBUG))
fprintf(stderr, "wave_out_volume: begin\n");
fprintf(stderr, "left='%d', right='%d'\n", left, right);
#endif
gainleft = (double) left / IRIX_MAX_VOL;
gainright = (double) right / IRIX_MAX_VOL;
gain[0] = alDoubleToFixed(min_volume + gainleft * volume_range);
gain[1] = alDoubleToFixed(min_volume + gainright * volume_range);
pv[0].param = AL_GAIN;
pv[0].value.ptr = gain;
pv[0].sizeIn = 8;
if (alSetParams(AL_DEFAULT_OUTPUT, pv, 1) < 0)
{
fprintf(stderr, "wave_out_volume: alSetParams failed: %s\n",
alGetErrorString(oserror()));
return;
}
#if (defined(IRIX_DEBUG))
fprintf(stderr, "wave_out_volume: returning\n");
#endif
}
void
wave_out_write(STREAM s, uint16 tick, uint8 index)
{
struct audio_packet *packet = &packet_queue[queue_hi];
unsigned int next_hi = (queue_hi + 1) % MAX_QUEUE;
if (next_hi == queue_lo)
{
fprintf(stderr, "No space to queue audio packet\n");
return;
}
queue_hi = next_hi;
packet->s = *s;
packet->tick = tick;
packet->index = index;
packet->s.p += 4;
/* we steal the data buffer from s, give it a new one */
s->data = malloc(s->size);
if (!g_dsp_busy)
wave_out_play();
}
void
wave_out_play(void)
{
struct audio_packet *packet;
ssize_t len;
unsigned int i;
uint8 swap;
STREAM out;
static BOOL swapped = False;
int gf;
while (1)
{
if (queue_lo == queue_hi)
{
g_dsp_busy = False;
return;
}
packet = &packet_queue[queue_lo];
out = &packet->s;
/* Swap the current packet, but only once */
if (g_swapaudio && !swapped)
{
for (i = 0; i < out->end - out->p; i += 2)
{
swap = *(out->p + i);
*(out->p + i) = *(out->p + i + 1);
*(out->p + i + 1) = swap;
}
swapped = True;
}
len = out->end - out->p;
alWriteFrames(output_port, out->p, len / combinedFrameSize);
out->p += len;
if (out->p == out->end)
{
gf = alGetFilled(output_port);
if (gf < (4 * maxFillable / 10))
{
rdpsnd_send_completion(packet->tick, packet->index);
free(out->data);
queue_lo = (queue_lo + 1) % MAX_QUEUE;
swapped = False;
}
else
{
#if (defined(IRIX_DEBUG))
/* fprintf(stderr,"Busy playing...\n"); */
#endif
g_dsp_busy = True;
usleep(10);
return;
}
}
}
}
@@ -0,0 +1,313 @@
/* -*- c-basic-offset: 8 -*-
rdesktop: A Remote Desktop Protocol client.
Sound Channel Process Functions - Sun
Copyright (C) Matthew Chapman 2003
Copyright (C) GuoJunBo [email protected] 2003
Copyright (C) Michael Gernoth [email protected] 2003
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "rdesktop.h"
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/ioctl.h>
#include <sys/audioio.h>
#if (defined(sun) && (defined(__svr4__) || defined(__SVR4)))
#include <stropts.h>
#endif
#define MAX_QUEUE 10
int g_dsp_fd;
BOOL g_dsp_busy = False;
static BOOL g_reopened;
static BOOL g_swapaudio;
static short g_samplewidth;
static struct audio_packet
{
struct stream s;
uint16 tick;
uint8 index;
} packet_queue[MAX_QUEUE];
static unsigned int queue_hi, queue_lo;
BOOL
wave_out_open(void)
{
char *dsp_dev = getenv("AUDIODEV");
if (dsp_dev == NULL)
{
dsp_dev = xstrdup("/dev/audio");
}
if ((g_dsp_fd = open(dsp_dev, O_WRONLY | O_NONBLOCK)) == -1)
{
perror(dsp_dev);
return False;
}
/* Non-blocking so that user interface is responsive */
fcntl(g_dsp_fd, F_SETFL, fcntl(g_dsp_fd, F_GETFL) | O_NONBLOCK);
queue_lo = queue_hi = 0;
g_reopened = True;
return True;
}
void
wave_out_close(void)
{
/* Ack all remaining packets */
while (queue_lo != queue_hi)
{
rdpsnd_send_completion(packet_queue[queue_lo].tick, packet_queue[queue_lo].index);
free(packet_queue[queue_lo].s.data);
queue_lo = (queue_lo + 1) % MAX_QUEUE;
}
#if defined I_FLUSH && defined FLUSHW
/* Flush the audiobuffer */
ioctl(g_dsp_fd, I_FLUSH, FLUSHW);
#endif
#if defined AUDIO_FLUSH
ioctl(g_dsp_fd, AUDIO_FLUSH, NULL);
#endif
close(g_dsp_fd);
}
BOOL
wave_out_format_supported(WAVEFORMATEX * pwfx)
{
if (pwfx->wFormatTag != WAVE_FORMAT_PCM)
return False;
if ((pwfx->nChannels != 1) && (pwfx->nChannels != 2))
return False;
if ((pwfx->wBitsPerSample != 8) && (pwfx->wBitsPerSample != 16))
return False;
return True;
}
BOOL
wave_out_set_format(WAVEFORMATEX * pwfx)
{
audio_info_t info;
ioctl(g_dsp_fd, AUDIO_DRAIN, 0);
g_swapaudio = False;
AUDIO_INITINFO(&info);
if (pwfx->wBitsPerSample == 8)
{
info.play.encoding = AUDIO_ENCODING_LINEAR8;
}
else if (pwfx->wBitsPerSample == 16)
{
info.play.encoding = AUDIO_ENCODING_LINEAR;
/* Do we need to swap the 16bit values? (Are we BigEndian) */
#ifdef B_ENDIAN
g_swapaudio = 1;
#else
g_swapaudio = 0;
#endif
}
g_samplewidth = pwfx->wBitsPerSample / 8;
if (pwfx->nChannels == 1)
{
info.play.channels = 1;
}
else if (pwfx->nChannels == 2)
{
info.play.channels = 2;
g_samplewidth *= 2;
}
info.play.sample_rate = pwfx->nSamplesPerSec;
info.play.precision = pwfx->wBitsPerSample;
info.play.samples = 0;
info.play.eof = 0;
info.play.error = 0;
g_reopened = True;
if (ioctl(g_dsp_fd, AUDIO_SETINFO, &info) == -1)
{
perror("AUDIO_SETINFO");
close(g_dsp_fd);
return False;
}
return True;
}
void
wave_out_volume(uint16 left, uint16 right)
{
audio_info_t info;
uint balance;
uint volume;
AUDIO_INITINFO(&info);
volume = (left > right) ? left : right;
if (volume / AUDIO_MID_BALANCE != 0)
{
balance =
AUDIO_MID_BALANCE - (left / (volume / AUDIO_MID_BALANCE)) +
(right / (volume / AUDIO_MID_BALANCE));
}
else
{
balance = AUDIO_MID_BALANCE;
}
info.play.gain = volume / (65536 / AUDIO_MAX_GAIN);
info.play.balance = balance;
if (ioctl(g_dsp_fd, AUDIO_SETINFO, &info) == -1)
{
perror("AUDIO_SETINFO");
return;
}
}
void
wave_out_write(STREAM s, uint16 tick, uint8 index)
{
struct audio_packet *packet = &packet_queue[queue_hi];
unsigned int next_hi = (queue_hi + 1) % MAX_QUEUE;
if (next_hi == queue_lo)
{
error("No space to queue audio packet\n");
return;
}
queue_hi = next_hi;
packet->s = *s;
packet->tick = tick;
packet->index = index;
packet->s.p += 4;
/* we steal the data buffer from s, give it a new one */
s->data = malloc(s->size);
if (!g_dsp_busy)
wave_out_play();
}
void
wave_out_play(void)
{
struct audio_packet *packet;
audio_info_t info;
ssize_t len;
unsigned int i;
uint8 swap;
STREAM out;
static BOOL swapped = False;
static BOOL sentcompletion = True;
static uint32 samplecnt = 0;
static uint32 numsamples;
while (1)
{
if (g_reopened)
{
/* Device was just (re)openend */
samplecnt = 0;
swapped = False;
sentcompletion = True;
g_reopened = False;
}
if (queue_lo == queue_hi)
{
g_dsp_busy = 0;
return;
}
packet = &packet_queue[queue_lo];
out = &packet->s;
/* Swap the current packet, but only once */
if (g_swapaudio && !swapped)
{
for (i = 0; i < out->end - out->p; i += 2)
{
swap = *(out->p + i);
*(out->p + i) = *(out->p + i + 1);
*(out->p + i + 1) = swap;
}
swapped = True;
}
if (sentcompletion)
{
sentcompletion = False;
numsamples = (out->end - out->p) / g_samplewidth;
}
len = 0;
if (out->end != out->p)
{
len = write(g_dsp_fd, out->p, out->end - out->p);
if (len == -1)
{
if (errno != EWOULDBLOCK)
perror("write audio");
g_dsp_busy = 1;
return;
}
}
out->p += len;
if (out->p == out->end)
{
if (ioctl(g_dsp_fd, AUDIO_GETINFO, &info) == -1)
{
perror("AUDIO_GETINFO");
return;
}
/* Ack the packet, if we have played at least 70% */
if (info.play.samples >= samplecnt + ((numsamples * 7) / 10))
{
samplecnt += numsamples;
rdpsnd_send_completion(packet->tick, packet->index);
free(out->data);
queue_lo = (queue_lo + 1) % MAX_QUEUE;
swapped = False;
sentcompletion = True;
}
else
{
g_dsp_busy = 1;
return;
}
}
}
}
@@ -0,0 +1,376 @@
/* Two defines for every scancode:
One called SCANCODE_KEY_<num>, where <num> is the key location number.
One called SCANCODE_CHAR_<char-on-us-kbd>, where <char-on-us-kbd> is the
unshifted character on a US 101/102 keyboard. See the Microsoft
document "Keyboard Scan Code Specification" for more information.
Up keys normally have scancode values +0x80.
0x0: Avoid
0x1- 0x59: Normal
0x60, 0x61: Avoid, since the up key would be 0xe1, 0xe1
0x61 - 0x79: Normal
0xfa - : keyboard drivers interpret these as responses from the 8042 chip
We use bit 7 to indicate 0xe0 prefix instead of two-byte sequence (0xe0, something). Eq.,
0xe 0x38 is defined as (0x80 | 0x38)
*/
/* FIXME:
Special keys like Numeric / are very complicated and emits many scancodes.
*/
#define SCANCODE_EXTENDED 0x80
#define SCANCODE_KEY_1 0x29
#define SCANCODE_CHAR_GRAVE 0x29
#define SCANCODE_KEY_2 0x2
#define SCANCODE_CHAR_1 SCANCODE_KEY_2
#define SCANCODE_KEY_3 0x3
#define SCANCODE_CHAR_2 SCANCODE_KEY_3
#define SCANCODE_KEY_4 0x4
#define SCANCODE_CHAR_3 SCANCODE_KEY_4
#define SCANCODE_KEY_5 0x5
#define SCANCODE_CHAR_4 SCANCODE_KEY_5
#define SCANCODE_KEY_6 0x6
#define SCANCODE_CHAR_5 SCANCODE_KEY_6
#define SCANCODE_KEY_7 0x7
#define SCANCODE_CHAR_6 SCANCODE_KEY_7
#define SCANCODE_KEY_8 0x8
#define SCANCODE_CHAR_7 SCANCODE_KEY_8
#define SCANCODE_KEY_9 0x9
#define SCANCODE_CHAR_8 SCANCODE_KEY_9
#define SCANCODE_KEY_10 0xa
#define SCANCODE_CHAR_9 SCANCODE_KEY_10
#define SCANCODE_KEY_11 0xb
#define SCANCODE_CHAR_0 SCANCODE_KEY_11
#define SCANCODE_KEY_12 0xc
#define SCANCODE_CHAR_MINUS SCANCODE_KEY_12
#define SCANCODE_KEY_13 0xd
#define SCANCODE_CHAR_EQUAL SCANCODE_KEY_13
/* Key 14 does not exist */
#define SCANCODE_KEY_15 0xe
#define SCANCODE_CHAR_BACKSPACE SCANCODE_KEY_15
#define SCANCODE_KEY_16 0xf
#define SCANCODE_CHAR_TAB SCANCODE_KEY_16
#define SCANCODE_KEY_17 0x10
#define SCANCODE_CHAR_Q SCANCODE_KEY_17
#define SCANCODE_KEY_18 0x11
#define SCANCODE_CHAR_W SCANCODE_KEY_18
#define SCANCODE_KEY_19 0x12
#define SCANCODE_CHAR_E SCANCODE_KEY_19
#define SCANCODE_KEY_20 0x13
#define SCANCODE_CHAR_R SCANCODE_KEY_20
#define SCANCODE_KEY_21 0x14
#define SCANCODE_CHAR_T SCANCODE_KEY_21
#define SCANCODE_KEY_22 0x15
#define SCANCODE_CHAR_Y SCANCODE_KEY_22
#define SCANCODE_KEY_23 0x16
#define SCANCODE_CHAR_U SCANCODE_KEY_23
#define SCANCODE_KEY_24 0x17
#define SCANCODE_CHAR_I SCANCODE_KEY_24
#define SCANCODE_KEY_25 0x18
#define SCANCODE_CHAR_O SCANCODE_KEY_25
#define SCANCODE_KEY_26 0x19
#define SCANCODE_CHAR_P SCANCODE_KEY_26
#define SCANCODE_KEY_27 0x1a
#define SCANCODE_CHAR_BRACKETLEFT SCANCODE_KEY_27
#define SCANCODE_KEY_28 0x1b
#define SCANCODE_CHAR_BRACKETRIGHT SCANCODE_KEY_28
/* Only on US keyboard */
#define SCANCODE_KEY_29 0x2b
#define SCANCODE_CHAR_BACKSLASH SCANCODE_KEY_29
#define SCANCODE_KEY_30 0x3a
#define SCANCODE_CHAR_CAPSLOCK SCANCODE_KEY_30
#define SCANCODE_KEY_31 0x1e
#define SCANCODE_CHAR_A SCANCODE_KEY_31
#define SCANCODE_KEY_32 0x1f
#define SCANCODE_CHAR_S SCANCODE_KEY_32
#define SCANCODE_KEY_33 0x20
#define SCANCODE_CHAR_D SCANCODE_KEY_33
#define SCANCODE_KEY_34 0x21
#define SCANCODE_CHAR_F SCANCODE_KEY_34
#define SCANCODE_KEY_35 0x22
#define SCANCODE_CHAR_G SCANCODE_KEY_35
#define SCANCODE_KEY_36 0x23
#define SCANCODE_CHAR_H SCANCODE_KEY_36
#define SCANCODE_KEY_37 0x24
#define SCANCODE_CHAR_J SCANCODE_KEY_37
#define SCANCODE_KEY_38 0x25
#define SCANCODE_CHAR_K SCANCODE_KEY_38
#define SCANCODE_KEY_39 0x26
#define SCANCODE_CHAR_L SCANCODE_KEY_39
#define SCANCODE_KEY_40 0x27
#define SCANCODE_CHAR_SEMICOLON SCANCODE_KEY_40
#define SCANCODE_KEY_41 0x28
#define SCANCODE_CHAR_APOSTROPHE SCANCODE_KEY_41
/* Only on international keyboard */
#define SCANCODE_KEY_42 0x2b
#define SCANCODE_KEY_43 0x1c
#define SCANCODE_CHAR_ENTER SCANCODE_KEY_43
#define SCANCODE_KEY_44 0x2a
#define SCANCODE_CHAR_LSHIFT SCANCODE_KEY_44
/* Only on international keyboard */
#define SCANCODE_KEY_45 0x56
#define SCANCODE_KEY_46 0x2c
#define SCANCODE_CHAR_Z SCANCODE_KEY_46
#define SCANCODE_KEY_47 0x2d
#define SCANCODE_CHAR_X SCANCODE_KEY_47
#define SCANCODE_KEY_48 0x2e
#define SCANCODE_CHAR_C SCANCODE_KEY_48
#define SCANCODE_KEY_49 0x2f
#define SCANCODE_CHAR_V SCANCODE_KEY_49
#define SCANCODE_KEY_50 0x30
#define SCANCODE_CHAR_B SCANCODE_KEY_50
#define SCANCODE_KEY_51 0x31
#define SCANCODE_CHAR_N SCANCODE_KEY_51
#define SCANCODE_KEY_52 0x32
#define SCANCODE_CHAR_M SCANCODE_KEY_52
#define SCANCODE_KEY_53 0x33
#define SCANCODE_CHAR_COMMA SCANCODE_KEY_53
#define SCANCODE_KEY_54 0x34
#define SCANCODE_CHAR_DOT SCANCODE_KEY_54
#define SCANCODE_KEY_55 0x35
#define SCANCODE_CHAR_SLASH SCANCODE_KEY_55
/* Only on Brazilian and some Far East keyboards */
#define SCANCODE_KEY_56 0x73
#define SCANCODE_KEY_57 0x36
#define SCANCODE_CHAR_RSHIFT SCANCODE_KEY_57
#define SCANCODE_KEY_58 0x1d
#define SCANCODE_CHAR_LCTRL SCANCODE_KEY_58
/* Key 59 does not exist */
#define SCANCODE_KEY_60 0x38
#define SCANCODE_CHAR_LALT SCANCODE_KEY_60
#define SCANCODE_KEY_61 0x39
#define SCANCODE_CHAR_SPACE SCANCODE_KEY_61
#define SCANCODE_KEY_62 (SCANCODE_EXTENDED | 0x38)
#define SCANCODE_CHAR_RALT SCANCODE_KEY_62
/* Key 63 does not exist */
#define SCANCODE_KEY_64 (SCANCODE_EXTENDED | 0x1d)
#define SCANCODE_CHAR_RCTRL SCANCODE_KEY_64
/* Key 65 - 74 does not exist */
#define SCANCODE_KEY_75 (SCANCODE_EXTENDED | 0x52)
#define SCANCODE_CHAR_INSERT SCANCODE_KEY_75
#define SCANCODE_KEY_76 (SCANCODE_EXTENDED | 0x53)
#define SCANCODE_CHAR_DELETE SCANCODE_KEY_76
/* Key 77 - 78 does not exist */
#define SCANCODE_KEY_79 (SCANCODE_EXTENDED | 0x4b)
#define SCANCODE_CHAR_LARROW SCANCODE_KEY_79
#define SCANCODE_KEY_80 (SCANCODE_EXTENDED | 0x47)
#define SCANCODE_CHAR_HOME SCANCODE_KEY_80
#define SCANCODE_KEY_81 (SCANCODE_EXTENDED | 0x4f)
#define SCANCODE_CHAR_END SCANCODE_KEY_81
/* Key 82 does not exist */
#define SCANCODE_KEY_83 (SCANCODE_EXTENDED | 0x48)
#define SCANCODE_CHAR_UPARROW SCANCODE_KEY_83
#define SCANCODE_KEY_84 (SCANCODE_EXTENDED | 0x50)
#define SCANCODE_CHAR_DNARROW SCANCODE_KEY_84
#define SCANCODE_KEY_85 (SCANCODE_EXTENDED | 0x49)
#define SCANCODE_CHAR_PAGEUP SCANCODE_KEY_85
#define SCANCODE_KEY_86 (SCANCODE_EXTENDED | 0x51)
#define SCANCODE_CHAR_PAGEDOWN SCANCODE_KEY_86
/* Key 87 - 88 does not exist */
#define SCANCODE_KEY_89 (SCANCODE_EXTENDED | 0x4d)
#define SCANCODE_CHAR_RARROW SCANCODE_KEY_89
#define SCANCODE_KEY_90 0x45
#define SCANCODE_CHAR_NUMLOCK SCANCODE_KEY_90
#define SCANCODE_KEY_91 0x47
#define SCANCODE_CHAR_NUMERIC7 SCANCODE_KEY_91
#define SCANCODE_KEY_92 0x4b
#define SCANCODE_CHAR_NUMERIC4 SCANCODE_KEY_92
#define SCANCODE_KEY_93 0x4f
#define SCANCODE_CHAR_NUMERIC1 SCANCODE_KEY_93
/* Key 94 does not exist */
#define SCANCODE_KEY_95 (SCANCODE_EXTENDED | 0x35)
#define SCANCODE_CHAR_NUMERICSLASH SCANCODE_KEY_95
#define SCANCODE_KEY_96 0x48
#define SCANCODE_CHAR_NUMERIC8 SCANCODE_KEY_96
#define SCANCODE_KEY_97 0x4c
#define SCANCODE_CHAR_NUMERIC5 SCANCODE_KEY_97
#define SCANCODE_KEY_98 0x50
#define SCANCODE_CHAR_NUMERIC2 SCANCODE_KEY_98
#define SCANCODE_KEY_99 0x52
#define SCANCODE_CHAR_NUMERIC0 SCANCODE_KEY_99
#define SCANCODE_KEY_100 0x37
#define SCANCODE_CHAR_NUMERICSTAR SCANCODE_KEY_100
#define SCANCODE_KEY_101 0x49
#define SCANCODE_CHAR_NUMERIC9 SCANCODE_KEY_101
#define SCANCODE_KEY_102 0x4d
#define SCANCODE_CHAR_NUMERIC6 SCANCODE_KEY_102
#define SCANCODE_KEY_103 0x51
#define SCANCODE_CHAR_NUMERIC3 SCANCODE_KEY_103
#define SCANCODE_KEY_104 0x53
#define SCANCODE_CHAR_NUMERICDOT SCANCODE_KEY_104
#define SCANCODE_KEY_105 0x4a
#define SCANCODE_CHAR_NUMERICMINUS SCANCODE_KEY_105
#define SCANCODE_KEY_106 0x4e
#define SCANCODE_CHAR_NUMERICPLUS SCANCODE_KEY_106
/* Only on Brazilian and some Far East keyboards */
#define SCANCODE_KEY_107 0x
#define SCANCODE_KEY_108 (SCANCODE_EXTENDED | 0x1c)
#define SCANCODE_CHAR_NUMERICENTER SCANCODE_KEY_108
/* Key 109 does not exist */
#define SCANCODE_KEY_110 0x1
#define SCANCODE_CHAR_ESC SCANCODE_KEY_110
/* Key 111 does not exist */
#define SCANCODE_KEY_112 0x3b
#define SCANCODE_CHAR_F1 SCANCODE_KEY_112
#define SCANCODE_KEY_113 0x3c
#define SCANCODE_CHAR_F2 SCANCODE_KEY_113
#define SCANCODE_KEY_114 0x3d
#define SCANCODE_CHAR_F3 SCANCODE_KEY_114
#define SCANCODE_KEY_115 0x3e
#define SCANCODE_CHAR_F4 SCANCODE_KEY_115
#define SCANCODE_KEY_116 0x3f
#define SCANCODE_CHAR_F5 SCANCODE_KEY_116
#define SCANCODE_KEY_117 0x40
#define SCANCODE_CHAR_F6 SCANCODE_KEY_117
#define SCANCODE_KEY_118 0x41
#define SCANCODE_CHAR_F7 SCANCODE_KEY_118
#define SCANCODE_KEY_119 0x42
#define SCANCODE_CHAR_F8 SCANCODE_KEY_119
#define SCANCODE_KEY_120 0x43
#define SCANCODE_CHAR_F9 SCANCODE_KEY_120
#define SCANCODE_KEY_121 0x44
#define SCANCODE_CHAR_F10 SCANCODE_KEY_121
#define SCANCODE_KEY_122 0x57
#define SCANCODE_CHAR_F11 SCANCODE_KEY_122
#define SCANCODE_KEY_123 0x58
#define SCANCODE_CHAR_F12 SCANCODE_KEY_123
/* Key 124: The Print Screen sequence is complicated, and
hardcoded in xkeymap.c */
#define SCANCODE_KEY_125 0x46
#define SCANCODE_CHAR_SCROLLLOCK SCANCODE_KEY_125
/* Key 126: The Pause and Break sequences is complicated, and
hardcoded in xkeymap.c */
/*
The keys below does not have any key location number
*/
#define SCANCODE_CHAR_LWIN (SCANCODE_EXTENDED | 0x5b)
#define SCANCODE_CHAR_RWIN (SCANCODE_EXTENDED | 0x5c)
#define SCANCODE_CHAR_APPLICATION (SCANCODE_EXTENDED | 0x5d)
#define SCANCODE_CHAR_ACPIPOWER (SCANCODE_EXTENDED | 0x5e)
#define SCANCODE_CHAR_ACPISLEEP (SCANCODE_EXTENDED | 0x5f)
#define SCANCODE_CHAR_ACPIWAKE (SCANCODE_EXTENDED | 0x63)
@@ -0,0 +1,453 @@
/* -*- c-basic-offset: 8 -*-
rdesktop: A Remote Desktop Protocol client.
Seamless Windows support
Copyright (C) Peter Astrand <[email protected]> 2005-2006
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "rdesktop.h"
#include <stdarg.h>
#include <assert.h>
/* #define WITH_DEBUG_SEAMLESS */
#ifdef WITH_DEBUG_SEAMLESS
#define DEBUG_SEAMLESS(args) printf args;
#else
#define DEBUG_SEAMLESS(args)
#endif
extern BOOL g_seamless_rdp;
static VCHANNEL *seamless_channel;
static unsigned int seamless_serial;
static char *
seamless_get_token(char **s)
{
char *comma, *head;
head = *s;
if (!head)
return NULL;
comma = strchr(head, ',');
if (comma)
{
*comma = '\0';
*s = comma + 1;
}
else
{
*s = NULL;
}
return head;
}
static BOOL
seamless_process_line(const char *line, void *data)
{
char *p, *l;
char *tok1, *tok2, *tok3, *tok4, *tok5, *tok6, *tok7, *tok8;
unsigned long id, flags;
char *endptr;
l = xstrdup(line);
p = l;
DEBUG_SEAMLESS(("seamlessrdp got:%s\n", p));
tok1 = seamless_get_token(&p);
tok2 = seamless_get_token(&p);
tok3 = seamless_get_token(&p);
tok4 = seamless_get_token(&p);
tok5 = seamless_get_token(&p);
tok6 = seamless_get_token(&p);
tok7 = seamless_get_token(&p);
tok8 = seamless_get_token(&p);
if (!strcmp("CREATE", tok1))
{
unsigned long group, parent;
if (!tok6)
return False;
id = strtoul(tok3, &endptr, 0);
if (*endptr)
return False;
group = strtoul(tok4, &endptr, 0);
if (*endptr)
return False;
parent = strtoul(tok5, &endptr, 0);
if (*endptr)
return False;
flags = strtoul(tok6, &endptr, 0);
if (*endptr)
return False;
ui_seamless_create_window(id, group, parent, flags);
}
else if (!strcmp("DESTROY", tok1))
{
if (!tok4)
return False;
id = strtoul(tok3, &endptr, 0);
if (*endptr)
return False;
flags = strtoul(tok4, &endptr, 0);
if (*endptr)
return False;
ui_seamless_destroy_window(id, flags);
}
else if (!strcmp("DESTROYGRP", tok1))
{
if (!tok4)
return False;
id = strtoul(tok3, &endptr, 0);
if (*endptr)
return False;
flags = strtoul(tok4, &endptr, 0);
if (*endptr)
return False;
ui_seamless_destroy_group(id, flags);
}
else if (!strcmp("SETICON", tok1))
{
unimpl("SeamlessRDP SETICON1\n");
}
else if (!strcmp("POSITION", tok1))
{
int x, y, width, height;
if (!tok8)
return False;
id = strtoul(tok3, &endptr, 0);
if (*endptr)
return False;
x = strtol(tok4, &endptr, 0);
if (*endptr)
return False;
y = strtol(tok5, &endptr, 0);
if (*endptr)
return False;
width = strtol(tok6, &endptr, 0);
if (*endptr)
return False;
height = strtol(tok7, &endptr, 0);
if (*endptr)
return False;
flags = strtoul(tok8, &endptr, 0);
if (*endptr)
return False;
ui_seamless_move_window(id, x, y, width, height, flags);
}
else if (!strcmp("ZCHANGE", tok1))
{
unsigned long behind;
id = strtoul(tok3, &endptr, 0);
if (*endptr)
return False;
behind = strtoul(tok4, &endptr, 0);
if (*endptr)
return False;
flags = strtoul(tok5, &endptr, 0);
if (*endptr)
return False;
ui_seamless_restack_window(id, behind, flags);
}
else if (!strcmp("TITLE", tok1))
{
if (!tok5)
return False;
id = strtoul(tok3, &endptr, 0);
if (*endptr)
return False;
flags = strtoul(tok5, &endptr, 0);
if (*endptr)
return False;
ui_seamless_settitle(id, tok4, flags);
}
else if (!strcmp("STATE", tok1))
{
unsigned int state;
if (!tok5)
return False;
id = strtoul(tok3, &endptr, 0);
if (*endptr)
return False;
state = strtoul(tok4, &endptr, 0);
if (*endptr)
return False;
flags = strtoul(tok5, &endptr, 0);
if (*endptr)
return False;
ui_seamless_setstate(id, state, flags);
}
else if (!strcmp("DEBUG", tok1))
{
DEBUG_SEAMLESS(("SeamlessRDP:%s\n", line));
}
else if (!strcmp("SYNCBEGIN", tok1))
{
if (!tok3)
return False;
flags = strtoul(tok3, &endptr, 0);
if (*endptr)
return False;
ui_seamless_syncbegin(flags);
}
else if (!strcmp("SYNCEND", tok1))
{
if (!tok3)
return False;
flags = strtoul(tok3, &endptr, 0);
if (*endptr)
return False;
/* do nothing, currently */
}
else if (!strcmp("HELLO", tok1))
{
if (!tok3)
return False;
flags = strtoul(tok3, &endptr, 0);
if (*endptr)
return False;
ui_seamless_begin(!!(flags & SEAMLESSRDP_HELLO_HIDDEN));
}
else if (!strcmp("ACK", tok1))
{
unsigned int serial;
serial = strtoul(tok3, &endptr, 0);
if (*endptr)
return False;
ui_seamless_ack(serial);
}
else if (!strcmp("HIDE", tok1))
{
if (!tok3)
return False;
flags = strtoul(tok3, &endptr, 0);
if (*endptr)
return False;
ui_seamless_hide_desktop();
}
else if (!strcmp("UNHIDE", tok1))
{
if (!tok3)
return False;
flags = strtoul(tok3, &endptr, 0);
if (*endptr)
return False;
ui_seamless_unhide_desktop();
}
xfree(l);
return True;
}
static BOOL
seamless_line_handler(const char *line, void *data)
{
if (!seamless_process_line(line, data))
{
warning("SeamlessRDP: Invalid request:%s\n", line);
}
return True;
}
static void
seamless_process(STREAM s)
{
unsigned int pkglen;
static char *rest = NULL;
char *buf;
pkglen = s->end - s->p;
/* str_handle_lines requires null terminated strings */
buf = xmalloc(pkglen + 1);
STRNCPY(buf, (char *) s->p, pkglen + 1);
#if 0
printf("seamless recv:\n");
hexdump(s->p, pkglen);
#endif
str_handle_lines(buf, &rest, seamless_line_handler, NULL);
xfree(buf);
}
BOOL
seamless_init(void)
{
if (!g_seamless_rdp)
return False;
seamless_serial = 0;
seamless_channel =
channel_register("seamrdp", CHANNEL_OPTION_INITIALIZED | CHANNEL_OPTION_ENCRYPT_RDP,
seamless_process);
return (seamless_channel != NULL);
}
static unsigned int
seamless_send(const char *command, const char *format, ...)
{
STREAM s;
size_t len;
va_list argp;
char buf[1025];
len = snprintf(buf, sizeof(buf) - 1, "%s,%u,", command, seamless_serial);
assert(len < (sizeof(buf) - 1));
va_start(argp, format);
len += vsnprintf(buf + len, sizeof(buf) - len - 1, format, argp);
va_end(argp);
assert(len < (sizeof(buf) - 1));
buf[len] = '\n';
buf[len + 1] = '\0';
len++;
s = channel_init(seamless_channel, len);
out_uint8p(s, buf, len) s_mark_end(s);
DEBUG_SEAMLESS(("SeamlessRDP sending:%s", buf));
#if 0
printf("seamless send:\n");
hexdump(s->channel_hdr + 8, s->end - s->channel_hdr - 8);
#endif
channel_send(s, seamless_channel);
return seamless_serial++;
}
unsigned int
seamless_send_sync()
{
if (!g_seamless_rdp)
return (unsigned int) -1;
return seamless_send("SYNC", "");
}
unsigned int
seamless_send_state(unsigned long id, unsigned int state, unsigned long flags)
{
if (!g_seamless_rdp)
return (unsigned int) -1;
return seamless_send("STATE", "0x%08lx,0x%x,0x%lx", id, state, flags);
}
unsigned int
seamless_send_position(unsigned long id, int x, int y, int width, int height, unsigned long flags)
{
return seamless_send("POSITION", "0x%08lx,%d,%d,%d,%d,0x%lx", id, x, y, width, height,
flags);
}
/* Update select timeout */
void
seamless_select_timeout(struct timeval *tv)
{
struct timeval ourtimeout = { 0, SEAMLESSRDP_POSITION_TIMER };
if (g_seamless_rdp)
{
if (timercmp(&ourtimeout, tv, <))
{
tv->tv_sec = ourtimeout.tv_sec;
tv->tv_usec = ourtimeout.tv_usec;
}
}
}
unsigned int
seamless_send_zchange(unsigned long id, unsigned long below, unsigned long flags)
{
if (!g_seamless_rdp)
return (unsigned int) -1;
return seamless_send("ZCHANGE", "0x%08lx,0x%08lx,0x%lx", id, below, flags);
}
unsigned int
seamless_send_focus(unsigned long id, unsigned long flags)
{
if (!g_seamless_rdp)
return (unsigned int) -1;
return seamless_send("FOCUS", "0x%08lx,0x%lx", id, flags);
}
@@ -0,0 +1,19 @@
/*
rdesktop: A Remote Desktop Protocol client.
Seamless Windows support
Copyright (C) Peter Astrand <[email protected]> 2005-2006
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/

Some files were not shown because too many files have changed in this diff Show More